From ccea2f3305a091938d0f679bd21520ef4b402e43 Mon Sep 17 00:00:00 2001 From: lllyasviel Date: Sat, 27 Jan 2024 10:34:31 -0800 Subject: [PATCH] upload a cn --- .../sd_forge_controlnet/.gitignore | 185 +++ .../sd_forge_controlnet/LICENSE | 674 ++++++++ .../sd_forge_controlnet/README.md | 243 +++ .../annotator/anime_face_segment/LICENSE | 21 + .../annotator/anime_face_segment/__init__.py | 172 ++ .../annotator/annotator_path.py | 22 + .../annotator/binary/__init__.py | 14 + .../annotator/canny/__init__.py | 5 + .../annotator/clipvision/__init__.py | 133 ++ .../clipvision/clip_vision_h_uc.data | Bin 0 -> 658694 bytes .../clipvision/clip_vision_vith_uc.data | Bin 0 -> 66319 bytes .../annotator/color/__init__.py | 20 + .../annotator/densepose/__init__.py | 57 + .../annotator/densepose/densepose.py | 347 ++++ .../annotator/depth_anything.py | 79 + .../annotator/hed/__init__.py | 98 ++ .../annotator/keypose/__init__.py | 212 +++ .../keypose/faster_rcnn_r50_fpn_coco.py | 182 +++ .../keypose/hrnet_w48_coco_256x192.py | 169 ++ .../annotator/lama/__init__.py | 58 + .../annotator/lama/config.yaml | 157 ++ .../annotator/lama/saicinpainting/__init__.py | 0 .../lama/saicinpainting/training/__init__.py | 0 .../saicinpainting/training/data/__init__.py | 0 .../saicinpainting/training/data/masks.py | 332 ++++ .../training/losses/__init__.py | 0 .../training/losses/adversarial.py | 177 ++ .../training/losses/constants.py | 152 ++ .../training/losses/distance_weighting.py | 126 ++ .../training/losses/feature_matching.py | 33 + .../training/losses/perceptual.py | 113 ++ .../training/losses/segmentation.py | 43 + .../training/losses/style_loss.py | 155 ++ .../training/modules/__init__.py | 31 + .../saicinpainting/training/modules/base.py | 80 + .../training/modules/depthwise_sep_conv.py | 17 + .../training/modules/fake_fakes.py | 47 + .../saicinpainting/training/modules/ffc.py | 485 ++++++ .../training/modules/multidilated_conv.py | 98 ++ .../training/modules/multiscale.py | 244 +++ .../training/modules/pix2pixhd.py | 669 ++++++++ .../training/modules/spatial_transform.py | 49 + .../training/modules/squeeze_excitation.py | 20 + .../training/trainers/__init__.py | 29 + .../saicinpainting/training/trainers/base.py | 293 ++++ .../training/trainers/default.py | 175 ++ .../training/visualizers/__init__.py | 15 + .../training/visualizers/base.py | 73 + .../training/visualizers/colors.py | 76 + .../training/visualizers/directory.py | 36 + .../training/visualizers/noop.py | 9 + .../annotator/lama/saicinpainting/utils.py | 174 ++ .../annotator/leres/__init__.py | 113 ++ .../annotator/leres/leres/LICENSE | 23 + .../annotator/leres/leres/Resnet.py | 199 +++ .../annotator/leres/leres/Resnext_torch.py | 237 +++ .../annotator/leres/leres/depthmap.py | 546 +++++++ .../leres/leres/multi_depth_model_woauxi.py | 34 + .../annotator/leres/leres/net_tools.py | 54 + .../annotator/leres/leres/network_auxi.py | 417 +++++ .../annotator/leres/pix2pix/LICENSE | 19 + .../leres/pix2pix/models/__init__.py | 67 + .../leres/pix2pix/models/base_model.py | 241 +++ .../leres/pix2pix/models/base_model_hg.py | 58 + .../leres/pix2pix/models/networks.py | 623 +++++++ .../pix2pix/models/pix2pix4depth_model.py | 155 ++ .../leres/pix2pix/options/__init__.py | 1 + .../leres/pix2pix/options/base_options.py | 156 ++ .../leres/pix2pix/options/test_options.py | 22 + .../annotator/leres/pix2pix/util/__init__.py | 1 + .../annotator/leres/pix2pix/util/get_data.py | 110 ++ .../leres/pix2pix/util/guidedfilter.py | 47 + .../annotator/leres/pix2pix/util/html.py | 86 + .../leres/pix2pix/util/image_pool.py | 54 + .../annotator/leres/pix2pix/util/util.py | 105 ++ .../leres/pix2pix/util/visualizer.py | 166 ++ .../annotator/lineart/LICENSE | 21 + .../annotator/lineart/__init__.py | 133 ++ .../annotator/lineart_anime/LICENSE | 21 + .../annotator/lineart_anime/__init__.py | 161 ++ .../annotator/manga_line/LICENSE | 21 + .../annotator/manga_line/__init__.py | 248 +++ .../annotator/mediapipe_face/__init__.py | 5 + .../mediapipe_face/mediapipe_face_common.py | 155 ++ .../annotator/midas/LICENSE | 21 + .../annotator/midas/__init__.py | 49 + .../annotator/midas/api.py | 181 ++ .../annotator/midas/midas/__init__.py | 0 .../annotator/midas/midas/base_model.py | 16 + .../annotator/midas/midas/blocks.py | 342 ++++ .../annotator/midas/midas/dpt_depth.py | 109 ++ .../annotator/midas/midas/midas_net.py | 76 + .../annotator/midas/midas/midas_net_custom.py | 128 ++ .../annotator/midas/midas/transforms.py | 234 +++ .../annotator/midas/midas/vit.py | 491 ++++++ .../annotator/midas/utils.py | 189 +++ .../annotator/mlsd/LICENSE | 201 +++ .../annotator/mlsd/__init__.py | 49 + .../annotator/mlsd/models/mbv2_mlsd_large.py | 292 ++++ .../annotator/mlsd/models/mbv2_mlsd_tiny.py | 275 ++++ .../annotator/mlsd/utils.py | 581 +++++++ .../annotator/mmpkg/mmcv/__init__.py | 15 + .../mmpkg/mmcv/arraymisc/__init__.py | 4 + .../mmpkg/mmcv/arraymisc/quantization.py | 55 + .../annotator/mmpkg/mmcv/cnn/__init__.py | 41 + .../annotator/mmpkg/mmcv/cnn/alexnet.py | 61 + .../mmpkg/mmcv/cnn/bricks/__init__.py | 35 + .../mmpkg/mmcv/cnn/bricks/activation.py | 92 ++ .../mmpkg/mmcv/cnn/bricks/context_block.py | 125 ++ .../annotator/mmpkg/mmcv/cnn/bricks/conv.py | 44 + .../cnn/bricks/conv2d_adaptive_padding.py | 62 + .../mmpkg/mmcv/cnn/bricks/conv_module.py | 206 +++ .../mmpkg/mmcv/cnn/bricks/conv_ws.py | 148 ++ .../bricks/depthwise_separable_conv_module.py | 96 ++ .../annotator/mmpkg/mmcv/cnn/bricks/drop.py | 65 + .../mmcv/cnn/bricks/generalized_attention.py | 412 +++++ .../mmpkg/mmcv/cnn/bricks/hsigmoid.py | 34 + .../annotator/mmpkg/mmcv/cnn/bricks/hswish.py | 29 + .../mmpkg/mmcv/cnn/bricks/non_local.py | 306 ++++ .../annotator/mmpkg/mmcv/cnn/bricks/norm.py | 144 ++ .../mmpkg/mmcv/cnn/bricks/padding.py | 36 + .../annotator/mmpkg/mmcv/cnn/bricks/plugin.py | 88 + .../mmpkg/mmcv/cnn/bricks/registry.py | 16 + .../annotator/mmpkg/mmcv/cnn/bricks/scale.py | 21 + .../annotator/mmpkg/mmcv/cnn/bricks/swish.py | 25 + .../mmpkg/mmcv/cnn/bricks/transformer.py | 595 +++++++ .../mmpkg/mmcv/cnn/bricks/upsample.py | 84 + .../mmpkg/mmcv/cnn/bricks/wrappers.py | 180 ++ .../annotator/mmpkg/mmcv/cnn/builder.py | 30 + .../annotator/mmpkg/mmcv/cnn/resnet.py | 316 ++++ .../mmpkg/mmcv/cnn/utils/__init__.py | 19 + .../mmpkg/mmcv/cnn/utils/flops_counter.py | 599 +++++++ .../mmpkg/mmcv/cnn/utils/fuse_conv_bn.py | 59 + .../annotator/mmpkg/mmcv/cnn/utils/sync_bn.py | 59 + .../mmpkg/mmcv/cnn/utils/weight_init.py | 684 ++++++++ .../annotator/mmpkg/mmcv/cnn/vgg.py | 175 ++ .../annotator/mmpkg/mmcv/engine/__init__.py | 8 + .../annotator/mmpkg/mmcv/engine/test.py | 202 +++ .../annotator/mmpkg/mmcv/fileio/__init__.py | 11 + .../mmpkg/mmcv/fileio/file_client.py | 1148 +++++++++++++ .../mmpkg/mmcv/fileio/handlers/__init__.py | 7 + .../mmpkg/mmcv/fileio/handlers/base.py | 30 + .../mmcv/fileio/handlers/json_handler.py | 36 + .../mmcv/fileio/handlers/pickle_handler.py | 28 + .../mmcv/fileio/handlers/yaml_handler.py | 24 + .../annotator/mmpkg/mmcv/fileio/io.py | 151 ++ .../annotator/mmpkg/mmcv/fileio/parse.py | 97 ++ .../annotator/mmpkg/mmcv/image/__init__.py | 28 + .../annotator/mmpkg/mmcv/image/colorspace.py | 306 ++++ .../annotator/mmpkg/mmcv/image/geometric.py | 728 +++++++++ .../annotator/mmpkg/mmcv/image/io.py | 258 +++ .../annotator/mmpkg/mmcv/image/misc.py | 44 + .../annotator/mmpkg/mmcv/image/photometric.py | 428 +++++ .../mmpkg/mmcv/model_zoo/deprecated.json | 6 + .../annotator/mmpkg/mmcv/model_zoo/mmcls.json | 31 + .../mmpkg/mmcv/model_zoo/open_mmlab.json | 50 + .../annotator/mmpkg/mmcv/ops/__init__.py | 81 + .../mmpkg/mmcv/ops/assign_score_withk.py | 123 ++ .../annotator/mmpkg/mmcv/ops/ball_query.py | 55 + .../annotator/mmpkg/mmcv/ops/bbox.py | 72 + .../annotator/mmpkg/mmcv/ops/border_align.py | 109 ++ .../mmpkg/mmcv/ops/box_iou_rotated.py | 45 + .../annotator/mmpkg/mmcv/ops/carafe.py | 287 ++++ .../annotator/mmpkg/mmcv/ops/cc_attention.py | 83 + .../mmpkg/mmcv/ops/contour_expand.py | 49 + .../annotator/mmpkg/mmcv/ops/corner_pool.py | 161 ++ .../annotator/mmpkg/mmcv/ops/correlation.py | 196 +++ .../annotator/mmpkg/mmcv/ops/deform_conv.py | 405 +++++ .../mmpkg/mmcv/ops/deform_roi_pool.py | 204 +++ .../mmpkg/mmcv/ops/deprecated_wrappers.py | 43 + .../annotator/mmpkg/mmcv/ops/focal_loss.py | 212 +++ .../mmpkg/mmcv/ops/furthest_point_sample.py | 83 + .../mmpkg/mmcv/ops/fused_bias_leakyrelu.py | 268 +++ .../annotator/mmpkg/mmcv/ops/gather_points.py | 57 + .../annotator/mmpkg/mmcv/ops/group_points.py | 224 +++ .../annotator/mmpkg/mmcv/ops/info.py | 36 + .../annotator/mmpkg/mmcv/ops/iou3d.py | 85 + .../annotator/mmpkg/mmcv/ops/knn.py | 77 + .../annotator/mmpkg/mmcv/ops/masked_conv.py | 111 ++ .../annotator/mmpkg/mmcv/ops/merge_cells.py | 149 ++ .../mmpkg/mmcv/ops/modulated_deform_conv.py | 282 ++++ .../mmpkg/mmcv/ops/multi_scale_deform_attn.py | 358 ++++ .../annotator/mmpkg/mmcv/ops/nms.py | 417 +++++ .../annotator/mmpkg/mmcv/ops/pixel_group.py | 75 + .../annotator/mmpkg/mmcv/ops/point_sample.py | 336 ++++ .../mmpkg/mmcv/ops/points_in_boxes.py | 133 ++ .../mmpkg/mmcv/ops/points_sampler.py | 177 ++ .../annotator/mmpkg/mmcv/ops/psa_mask.py | 92 ++ .../annotator/mmpkg/mmcv/ops/roi_align.py | 223 +++ .../mmpkg/mmcv/ops/roi_align_rotated.py | 177 ++ .../annotator/mmpkg/mmcv/ops/roi_pool.py | 86 + .../mmpkg/mmcv/ops/roiaware_pool3d.py | 114 ++ .../mmpkg/mmcv/ops/roipoint_pool3d.py | 77 + .../annotator/mmpkg/mmcv/ops/saconv.py | 145 ++ .../mmpkg/mmcv/ops/scatter_points.py | 135 ++ .../annotator/mmpkg/mmcv/ops/sync_bn.py | 279 ++++ .../mmpkg/mmcv/ops/three_interpolate.py | 68 + .../annotator/mmpkg/mmcv/ops/three_nn.py | 51 + .../annotator/mmpkg/mmcv/ops/tin_shift.py | 68 + .../annotator/mmpkg/mmcv/ops/upfirdn2d.py | 330 ++++ .../annotator/mmpkg/mmcv/ops/voxelize.py | 132 ++ .../annotator/mmpkg/mmcv/parallel/__init__.py | 13 + .../mmpkg/mmcv/parallel/_functions.py | 79 + .../annotator/mmpkg/mmcv/parallel/collate.py | 84 + .../mmpkg/mmcv/parallel/data_container.py | 89 + .../mmpkg/mmcv/parallel/data_parallel.py | 89 + .../mmpkg/mmcv/parallel/distributed.py | 112 ++ .../mmcv/parallel/distributed_deprecated.py | 70 + .../annotator/mmpkg/mmcv/parallel/registry.py | 8 + .../mmpkg/mmcv/parallel/scatter_gather.py | 59 + .../annotator/mmpkg/mmcv/parallel/utils.py | 20 + .../annotator/mmpkg/mmcv/runner/__init__.py | 47 + .../mmpkg/mmcv/runner/base_module.py | 195 +++ .../mmpkg/mmcv/runner/base_runner.py | 542 ++++++ .../annotator/mmpkg/mmcv/runner/builder.py | 24 + .../annotator/mmpkg/mmcv/runner/checkpoint.py | 707 ++++++++ .../mmpkg/mmcv/runner/default_constructor.py | 44 + .../annotator/mmpkg/mmcv/runner/dist_utils.py | 164 ++ .../mmpkg/mmcv/runner/epoch_based_runner.py | 187 +++ .../annotator/mmpkg/mmcv/runner/fp16_utils.py | 410 +++++ .../mmpkg/mmcv/runner/hooks/__init__.py | 29 + .../mmpkg/mmcv/runner/hooks/checkpoint.py | 167 ++ .../mmpkg/mmcv/runner/hooks/closure.py | 11 + .../annotator/mmpkg/mmcv/runner/hooks/ema.py | 89 + .../mmpkg/mmcv/runner/hooks/evaluation.py | 509 ++++++ .../annotator/mmpkg/mmcv/runner/hooks/hook.py | 92 ++ .../mmpkg/mmcv/runner/hooks/iter_timer.py | 18 + .../mmcv/runner/hooks/logger/__init__.py | 15 + .../mmpkg/mmcv/runner/hooks/logger/base.py | 166 ++ .../mmpkg/mmcv/runner/hooks/logger/dvclive.py | 58 + .../mmpkg/mmcv/runner/hooks/logger/mlflow.py | 78 + .../mmpkg/mmcv/runner/hooks/logger/neptune.py | 82 + .../mmpkg/mmcv/runner/hooks/logger/pavi.py | 117 ++ .../mmcv/runner/hooks/logger/tensorboard.py | 57 + .../mmpkg/mmcv/runner/hooks/logger/text.py | 256 +++ .../mmpkg/mmcv/runner/hooks/logger/wandb.py | 56 + .../mmpkg/mmcv/runner/hooks/lr_updater.py | 670 ++++++++ .../mmpkg/mmcv/runner/hooks/memory.py | 25 + .../mmcv/runner/hooks/momentum_updater.py | 493 ++++++ .../mmpkg/mmcv/runner/hooks/optimizer.py | 508 ++++++ .../mmpkg/mmcv/runner/hooks/profiler.py | 180 ++ .../mmpkg/mmcv/runner/hooks/sampler_seed.py | 20 + .../mmpkg/mmcv/runner/hooks/sync_buffer.py | 22 + .../mmpkg/mmcv/runner/iter_based_runner.py | 273 ++++ .../annotator/mmpkg/mmcv/runner/log_buffer.py | 41 + .../mmpkg/mmcv/runner/optimizer/__init__.py | 9 + .../mmpkg/mmcv/runner/optimizer/builder.py | 44 + .../runner/optimizer/default_constructor.py | 249 +++ .../annotator/mmpkg/mmcv/runner/priority.py | 60 + .../annotator/mmpkg/mmcv/runner/utils.py | 93 ++ .../annotator/mmpkg/mmcv/utils/__init__.py | 69 + .../annotator/mmpkg/mmcv/utils/config.py | 688 ++++++++ .../annotator/mmpkg/mmcv/utils/env.py | 95 ++ .../annotator/mmpkg/mmcv/utils/ext_loader.py | 71 + .../annotator/mmpkg/mmcv/utils/logging.py | 110 ++ .../annotator/mmpkg/mmcv/utils/misc.py | 377 +++++ .../annotator/mmpkg/mmcv/utils/parrots_jit.py | 41 + .../mmpkg/mmcv/utils/parrots_wrapper.py | 107 ++ .../annotator/mmpkg/mmcv/utils/path.py | 101 ++ .../annotator/mmpkg/mmcv/utils/progressbar.py | 208 +++ .../annotator/mmpkg/mmcv/utils/registry.py | 315 ++++ .../annotator/mmpkg/mmcv/utils/testing.py | 140 ++ .../annotator/mmpkg/mmcv/utils/timer.py | 118 ++ .../annotator/mmpkg/mmcv/utils/trace.py | 23 + .../mmpkg/mmcv/utils/version_utils.py | 90 + .../annotator/mmpkg/mmcv/version.py | 35 + .../annotator/mmpkg/mmcv/video/__init__.py | 11 + .../annotator/mmpkg/mmcv/video/io.py | 318 ++++ .../annotator/mmpkg/mmcv/video/optflow.py | 254 +++ .../annotator/mmpkg/mmcv/video/processing.py | 160 ++ .../mmpkg/mmcv/visualization/__init__.py | 9 + .../mmpkg/mmcv/visualization/color.py | 51 + .../mmpkg/mmcv/visualization/image.py | 152 ++ .../mmpkg/mmcv/visualization/optflow.py | 112 ++ .../annotator/mmpkg/mmseg/apis/__init__.py | 9 + .../annotator/mmpkg/mmseg/apis/inference.py | 138 ++ .../annotator/mmpkg/mmseg/apis/test.py | 238 +++ .../annotator/mmpkg/mmseg/apis/train.py | 116 ++ .../annotator/mmpkg/mmseg/core/__init__.py | 3 + .../mmpkg/mmseg/core/evaluation/__init__.py | 8 + .../mmseg/core/evaluation/class_names.py | 152 ++ .../mmpkg/mmseg/core/evaluation/eval_hooks.py | 109 ++ .../mmpkg/mmseg/core/evaluation/metrics.py | 326 ++++ .../mmpkg/mmseg/core/seg/__init__.py | 4 + .../annotator/mmpkg/mmseg/core/seg/builder.py | 8 + .../mmpkg/mmseg/core/seg/sampler/__init__.py | 4 + .../core/seg/sampler/base_pixel_sampler.py | 12 + .../core/seg/sampler/ohem_pixel_sampler.py | 76 + .../mmpkg/mmseg/core/utils/__init__.py | 3 + .../annotator/mmpkg/mmseg/core/utils/misc.py | 17 + .../mmpkg/mmseg/datasets/__init__.py | 19 + .../annotator/mmpkg/mmseg/datasets/ade.py | 84 + .../annotator/mmpkg/mmseg/datasets/builder.py | 169 ++ .../mmpkg/mmseg/datasets/chase_db1.py | 27 + .../mmpkg/mmseg/datasets/cityscapes.py | 217 +++ .../annotator/mmpkg/mmseg/datasets/custom.py | 403 +++++ .../mmpkg/mmseg/datasets/dataset_wrappers.py | 50 + .../annotator/mmpkg/mmseg/datasets/drive.py | 27 + .../annotator/mmpkg/mmseg/datasets/hrf.py | 27 + .../mmpkg/mmseg/datasets/pascal_context.py | 103 ++ .../mmseg/datasets/pipelines/__init__.py | 16 + .../mmpkg/mmseg/datasets/pipelines/compose.py | 51 + .../mmseg/datasets/pipelines/formating.py | 288 ++++ .../mmpkg/mmseg/datasets/pipelines/loading.py | 153 ++ .../mmseg/datasets/pipelines/test_time_aug.py | 133 ++ .../mmseg/datasets/pipelines/transforms.py | 889 ++++++++++ .../annotator/mmpkg/mmseg/datasets/stare.py | 27 + .../annotator/mmpkg/mmseg/datasets/voc.py | 29 + .../annotator/mmpkg/mmseg/models/__init__.py | 12 + .../mmpkg/mmseg/models/backbones/__init__.py | 16 + .../mmpkg/mmseg/models/backbones/cgnet.py | 367 +++++ .../mmpkg/mmseg/models/backbones/fast_scnn.py | 375 +++++ .../mmpkg/mmseg/models/backbones/hrnet.py | 555 +++++++ .../mmseg/models/backbones/mobilenet_v2.py | 180 ++ .../mmseg/models/backbones/mobilenet_v3.py | 255 +++ .../mmpkg/mmseg/models/backbones/resnest.py | 314 ++++ .../mmpkg/mmseg/models/backbones/resnet.py | 688 ++++++++ .../mmpkg/mmseg/models/backbones/resnext.py | 145 ++ .../mmpkg/mmseg/models/backbones/unet.py | 429 +++++ .../mmpkg/mmseg/models/backbones/vit.py | 459 ++++++ .../annotator/mmpkg/mmseg/models/builder.py | 46 + .../mmseg/models/decode_heads/__init__.py | 28 + .../mmseg/models/decode_heads/ann_head.py | 245 +++ .../mmseg/models/decode_heads/apc_head.py | 158 ++ .../mmseg/models/decode_heads/aspp_head.py | 107 ++ .../decode_heads/cascade_decode_head.py | 57 + .../mmseg/models/decode_heads/cc_head.py | 45 + .../mmseg/models/decode_heads/da_head.py | 178 ++ .../mmseg/models/decode_heads/decode_head.py | 234 +++ .../mmseg/models/decode_heads/dm_head.py | 140 ++ .../mmseg/models/decode_heads/dnl_head.py | 131 ++ .../mmseg/models/decode_heads/ema_head.py | 168 ++ .../mmseg/models/decode_heads/enc_head.py | 187 +++ .../mmseg/models/decode_heads/fcn_head.py | 81 + .../mmseg/models/decode_heads/fpn_head.py | 68 + .../mmseg/models/decode_heads/gc_head.py | 47 + .../mmseg/models/decode_heads/lraspp_head.py | 90 + .../mmseg/models/decode_heads/nl_head.py | 49 + .../mmseg/models/decode_heads/ocr_head.py | 127 ++ .../mmseg/models/decode_heads/point_head.py | 354 ++++ .../mmseg/models/decode_heads/psa_head.py | 199 +++ .../mmseg/models/decode_heads/psp_head.py | 101 ++ .../models/decode_heads/sep_aspp_head.py | 101 ++ .../mmseg/models/decode_heads/sep_fcn_head.py | 51 + .../mmseg/models/decode_heads/uper_head.py | 126 ++ .../mmpkg/mmseg/models/losses/__init__.py | 12 + .../mmpkg/mmseg/models/losses/accuracy.py | 78 + .../mmseg/models/losses/cross_entropy_loss.py | 198 +++ .../mmpkg/mmseg/models/losses/dice_loss.py | 119 ++ .../mmpkg/mmseg/models/losses/lovasz_loss.py | 303 ++++ .../mmpkg/mmseg/models/losses/utils.py | 121 ++ .../mmpkg/mmseg/models/necks/__init__.py | 4 + .../annotator/mmpkg/mmseg/models/necks/fpn.py | 212 +++ .../mmseg/models/necks/multilevel_neck.py | 70 + .../mmpkg/mmseg/models/segmentors/__init__.py | 5 + .../mmpkg/mmseg/models/segmentors/base.py | 273 ++++ .../segmentors/cascade_encoder_decoder.py | 98 ++ .../models/segmentors/encoder_decoder.py | 298 ++++ .../mmpkg/mmseg/models/utils/__init__.py | 13 + .../mmpkg/mmseg/models/utils/drop.py | 31 + .../mmseg/models/utils/inverted_residual.py | 208 +++ .../mmseg/models/utils/make_divisible.py | 27 + .../mmpkg/mmseg/models/utils/res_layer.py | 94 ++ .../mmpkg/mmseg/models/utils/se_layer.py | 57 + .../models/utils/self_attention_block.py | 159 ++ .../mmpkg/mmseg/models/utils/up_conv_block.py | 101 ++ .../mmpkg/mmseg/models/utils/weight_init.py | 62 + .../annotator/mmpkg/mmseg/ops/__init__.py | 4 + .../annotator/mmpkg/mmseg/ops/encoding.py | 74 + .../annotator/mmpkg/mmseg/ops/wrappers.py | 50 + .../annotator/mmpkg/mmseg/utils/__init__.py | 4 + .../mmpkg/mmseg/utils/collect_env.py | 17 + .../annotator/mmpkg/mmseg/utils/logger.py | 27 + .../annotator/normalbae/LICENSE | 21 + .../annotator/normalbae/__init__.py | 81 + .../annotator/normalbae/models/NNET.py | 22 + .../annotator/normalbae/models/baseline.py | 85 + .../normalbae/models/submodules/decoder.py | 202 +++ .../submodules/efficientnet_repo/.gitignore | 109 ++ .../submodules/efficientnet_repo/BENCHMARK.md | 555 +++++++ .../submodules/efficientnet_repo/LICENSE | 201 +++ .../submodules/efficientnet_repo/README.md | 323 ++++ .../efficientnet_repo/caffe2_benchmark.py | 65 + .../efficientnet_repo/caffe2_validate.py | 138 ++ .../efficientnet_repo/geffnet/__init__.py | 5 + .../geffnet/activations/__init__.py | 137 ++ .../geffnet/activations/activations.py | 102 ++ .../geffnet/activations/activations_jit.py | 79 + .../geffnet/activations/activations_me.py | 174 ++ .../efficientnet_repo/geffnet/config.py | 123 ++ .../geffnet/conv2d_layers.py | 304 ++++ .../geffnet/efficientnet_builder.py | 683 ++++++++ .../geffnet/gen_efficientnet.py | 1450 +++++++++++++++++ .../efficientnet_repo/geffnet/helpers.py | 71 + .../efficientnet_repo/geffnet/mobilenetv3.py | 364 +++++ .../geffnet/model_factory.py | 27 + .../efficientnet_repo/geffnet/version.py | 1 + .../submodules/efficientnet_repo/hubconf.py | 84 + .../efficientnet_repo/onnx_export.py | 120 ++ .../efficientnet_repo/onnx_optimize.py | 84 + .../efficientnet_repo/onnx_to_caffe.py | 27 + .../efficientnet_repo/onnx_validate.py | 112 ++ .../efficientnet_repo/requirements.txt | 2 + .../submodules/efficientnet_repo/setup.py | 47 + .../submodules/efficientnet_repo/utils.py | 52 + .../submodules/efficientnet_repo/validate.py | 166 ++ .../normalbae/models/submodules/encoder.py | 34 + .../normalbae/models/submodules/submodules.py | 140 ++ .../annotator/oneformer/LICENSE | 21 + .../annotator/oneformer/__init__.py | 45 + .../annotator/oneformer/api.py | 39 + .../Base-ADE20K-UnifiedSegmentation.yaml | 68 + .../ade20k/oneformer_R50_bs16_160k.yaml | 58 + ...former_swin_large_IN21k_384_bs16_160k.yaml | 40 + .../coco/Base-COCO-UnifiedSegmentation.yaml | 54 + .../configs/coco/oneformer_R50_bs16_50ep.yaml | 59 + ...ormer_swin_large_IN21k_384_bs16_100ep.yaml | 25 + .../oneformer/detectron2/__init__.py | 10 + .../detectron2/checkpoint/__init__.py | 10 + .../detectron2/checkpoint/c2_model_loading.py | 412 +++++ .../detectron2/checkpoint/catalog.py | 115 ++ .../checkpoint/detection_checkpoint.py | 145 ++ .../oneformer/detectron2/config/__init__.py | 24 + .../oneformer/detectron2/config/compat.py | 229 +++ .../oneformer/detectron2/config/config.py | 265 +++ .../oneformer/detectron2/config/defaults.py | 650 ++++++++ .../detectron2/config/instantiate.py | 88 + .../oneformer/detectron2/config/lazy.py | 435 +++++ .../oneformer/detectron2/data/__init__.py | 19 + .../oneformer/detectron2/data/benchmark.py | 225 +++ .../oneformer/detectron2/data/build.py | 556 +++++++ .../oneformer/detectron2/data/catalog.py | 236 +++ .../oneformer/detectron2/data/common.py | 301 ++++ .../detectron2/data/dataset_mapper.py | 191 +++ .../detectron2/data/datasets/README.md | 9 + .../detectron2/data/datasets/__init__.py | 9 + .../detectron2/data/datasets/builtin.py | 259 +++ .../detectron2/data/datasets/builtin_meta.py | 350 ++++ .../detectron2/data/datasets/cityscapes.py | 329 ++++ .../data/datasets/cityscapes_panoptic.py | 187 +++ .../detectron2/data/datasets/coco.py | 539 ++++++ .../detectron2/data/datasets/coco_panoptic.py | 228 +++ .../detectron2/data/datasets/lvis.py | 241 +++ .../data/datasets/lvis_v0_5_categories.py | 13 + .../data/datasets/lvis_v1_categories.py | 16 + .../datasets/lvis_v1_category_image_count.py | 20 + .../detectron2/data/datasets/pascal_voc.py | 82 + .../detectron2/data/datasets/register_coco.py | 3 + .../detectron2/data/detection_utils.py | 659 ++++++++ .../detectron2/data/samplers/__init__.py | 17 + .../data/samplers/distributed_sampler.py | 278 ++++ .../data/samplers/grouped_batch_sampler.py | 47 + .../detectron2/data/transforms/__init__.py | 14 + .../data/transforms/augmentation.py | 380 +++++ .../data/transforms/augmentation_impl.py | 736 +++++++++ .../detectron2/data/transforms/transform.py | 351 ++++ .../oneformer/detectron2/engine/__init__.py | 12 + .../oneformer/detectron2/engine/defaults.py | 715 ++++++++ .../oneformer/detectron2/engine/hooks.py | 690 ++++++++ .../oneformer/detectron2/engine/launch.py | 123 ++ .../oneformer/detectron2/engine/train_loop.py | 469 ++++++ .../detectron2/evaluation/__init__.py | 12 + .../evaluation/cityscapes_evaluation.py | 197 +++ .../detectron2/evaluation/coco_evaluation.py | 722 ++++++++ .../detectron2/evaluation/evaluator.py | 224 +++ .../detectron2/evaluation/fast_eval_api.py | 121 ++ .../detectron2/evaluation/lvis_evaluation.py | 380 +++++ .../evaluation/panoptic_evaluation.py | 199 +++ .../evaluation/pascal_voc_evaluation.py | 300 ++++ .../evaluation/rotated_coco_evaluation.py | 207 +++ .../evaluation/sem_seg_evaluation.py | 265 +++ .../detectron2/evaluation/testing.py | 85 + .../oneformer/detectron2/export/README.md | 15 + .../oneformer/detectron2/export/__init__.py | 30 + .../oneformer/detectron2/export/api.py | 230 +++ .../oneformer/detectron2/export/c10.py | 557 +++++++ .../detectron2/export/caffe2_export.py | 203 +++ .../detectron2/export/caffe2_inference.py | 161 ++ .../detectron2/export/caffe2_modeling.py | 419 +++++ .../detectron2/export/caffe2_patch.py | 152 ++ .../oneformer/detectron2/export/flatten.py | 330 ++++ .../oneformer/detectron2/export/shared.py | 1039 ++++++++++++ .../detectron2/export/torchscript.py | 132 ++ .../detectron2/export/torchscript_patch.py | 406 +++++ .../oneformer/detectron2/layers/__init__.py | 26 + .../oneformer/detectron2/layers/aspp.py | 144 ++ .../oneformer/detectron2/layers/batch_norm.py | 300 ++++ .../oneformer/detectron2/layers/blocks.py | 111 ++ .../detectron2/layers/csrc/README.md | 7 + .../csrc/ROIAlignRotated/ROIAlignRotated.h | 115 ++ .../ROIAlignRotated/ROIAlignRotated_cpu.cpp | 522 ++++++ .../ROIAlignRotated/ROIAlignRotated_cuda.cu | 443 +++++ .../csrc/box_iou_rotated/box_iou_rotated.h | 35 + .../box_iou_rotated/box_iou_rotated_cpu.cpp | 39 + .../box_iou_rotated/box_iou_rotated_cuda.cu | 130 ++ .../box_iou_rotated/box_iou_rotated_utils.h | 370 +++++ .../layers/csrc/cocoeval/cocoeval.cpp | 507 ++++++ .../layers/csrc/cocoeval/cocoeval.h | 88 + .../detectron2/layers/csrc/cuda_version.cu | 26 + .../layers/csrc/deformable/deform_conv.h | 377 +++++ .../csrc/deformable/deform_conv_cuda.cu | 1223 ++++++++++++++ .../deformable/deform_conv_cuda_kernel.cu | 1288 +++++++++++++++ .../layers/csrc/nms_rotated/nms_rotated.h | 39 + .../csrc/nms_rotated/nms_rotated_cpu.cpp | 75 + .../csrc/nms_rotated/nms_rotated_cuda.cu | 145 ++ .../detectron2/layers/csrc/vision.cpp | 117 ++ .../detectron2/layers/deform_conv.py | 514 ++++++ .../oneformer/detectron2/layers/losses.py | 133 ++ .../oneformer/detectron2/layers/mask_ops.py | 275 ++++ .../oneformer/detectron2/layers/nms.py | 144 ++ .../oneformer/detectron2/layers/roi_align.py | 74 + .../detectron2/layers/roi_align_rotated.py | 100 ++ .../detectron2/layers/rotated_boxes.py | 21 + .../oneformer/detectron2/layers/shape_spec.py | 18 + .../oneformer/detectron2/layers/wrappers.py | 162 ++ .../detectron2/model_zoo/__init__.py | 10 + .../detectron2/model_zoo/model_zoo.py | 213 +++ .../oneformer/detectron2/modeling/__init__.py | 64 + .../detectron2/modeling/anchor_generator.py | 386 +++++ .../detectron2/modeling/backbone/__init__.py | 20 + .../detectron2/modeling/backbone/backbone.py | 74 + .../detectron2/modeling/backbone/build.py | 33 + .../detectron2/modeling/backbone/fpn.py | 268 +++ .../detectron2/modeling/backbone/mvit.py | 448 +++++ .../detectron2/modeling/backbone/regnet.py | 452 +++++ .../detectron2/modeling/backbone/resnet.py | 694 ++++++++ .../detectron2/modeling/backbone/swin.py | 695 ++++++++ .../detectron2/modeling/backbone/utils.py | 186 +++ .../detectron2/modeling/backbone/vit.py | 524 ++++++ .../detectron2/modeling/box_regression.py | 369 +++++ .../oneformer/detectron2/modeling/matcher.py | 127 ++ .../detectron2/modeling/meta_arch/__init__.py | 16 + .../detectron2/modeling/meta_arch/build.py | 24 + .../modeling/meta_arch/dense_detector.py | 294 ++++ .../detectron2/modeling/meta_arch/fcos.py | 328 ++++ .../modeling/meta_arch/panoptic_fpn.py | 269 +++ .../detectron2/modeling/meta_arch/rcnn.py | 341 ++++ .../modeling/meta_arch/retinanet.py | 439 +++++ .../modeling/meta_arch/semantic_seg.py | 267 +++ .../detectron2/modeling/mmdet_wrapper.py | 273 ++++ .../oneformer/detectron2/modeling/poolers.py | 263 +++ .../detectron2/modeling/postprocessing.py | 100 ++ .../modeling/proposal_generator/__init__.py | 5 + .../modeling/proposal_generator/build.py | 24 + .../proposal_generator/proposal_utils.py | 205 +++ .../modeling/proposal_generator/rpn.py | 533 ++++++ .../modeling/proposal_generator/rrpn.py | 209 +++ .../detectron2/modeling/roi_heads/__init__.py | 29 + .../detectron2/modeling/roi_heads/box_head.py | 118 ++ .../modeling/roi_heads/cascade_rcnn.py | 299 ++++ .../modeling/roi_heads/fast_rcnn.py | 569 +++++++ .../modeling/roi_heads/keypoint_head.py | 272 ++++ .../modeling/roi_heads/mask_head.py | 298 ++++ .../modeling/roi_heads/roi_heads.py | 877 ++++++++++ .../modeling/roi_heads/rotated_fast_rcnn.py | 271 +++ .../oneformer/detectron2/modeling/sampling.py | 54 + .../modeling/test_time_augmentation.py | 307 ++++ .../oneformer/detectron2/projects/README.md | 2 + .../oneformer/detectron2/projects/__init__.py | 34 + .../detectron2/projects/deeplab/__init__.py | 5 + .../projects/deeplab/build_solver.py | 27 + .../detectron2/projects/deeplab/config.py | 28 + .../detectron2/projects/deeplab/loss.py | 40 + .../projects/deeplab/lr_scheduler.py | 62 + .../detectron2/projects/deeplab/resnet.py | 158 ++ .../projects/deeplab/semantic_seg.py | 348 ++++ .../oneformer/detectron2/solver/__init__.py | 11 + .../oneformer/detectron2/solver/build.py | 310 ++++ .../detectron2/solver/lr_scheduler.py | 246 +++ .../detectron2/structures/__init__.py | 17 + .../oneformer/detectron2/structures/boxes.py | 425 +++++ .../detectron2/structures/image_list.py | 129 ++ .../detectron2/structures/instances.py | 194 +++ .../detectron2/structures/keypoints.py | 235 +++ .../oneformer/detectron2/structures/masks.py | 534 ++++++ .../detectron2/structures/rotated_boxes.py | 505 ++++++ .../oneformer/detectron2/tracking/__init__.py | 15 + .../detectron2/tracking/base_tracker.py | 64 + .../detectron2/tracking/bbox_iou_tracker.py | 276 ++++ .../detectron2/tracking/hungarian_tracker.py | 171 ++ ...iou_weighted_hungarian_bbox_iou_tracker.py | 102 ++ .../oneformer/detectron2/tracking/utils.py | 40 + .../vanilla_hungarian_bbox_iou_tracker.py | 129 ++ .../oneformer/detectron2/utils/README.md | 5 + .../oneformer/detectron2/utils/__init__.py | 1 + .../oneformer/detectron2/utils/analysis.py | 188 +++ .../oneformer/detectron2/utils/collect_env.py | 246 +++ .../oneformer/detectron2/utils/colormap.py | 158 ++ .../oneformer/detectron2/utils/comm.py | 238 +++ .../oneformer/detectron2/utils/develop.py | 59 + .../oneformer/detectron2/utils/env.py | 170 ++ .../oneformer/detectron2/utils/events.py | 534 ++++++ .../oneformer/detectron2/utils/file_io.py | 39 + .../oneformer/detectron2/utils/logger.py | 237 +++ .../oneformer/detectron2/utils/memory.py | 84 + .../oneformer/detectron2/utils/registry.py | 60 + .../oneformer/detectron2/utils/serialize.py | 32 + .../oneformer/detectron2/utils/testing.py | 478 ++++++ .../oneformer/detectron2/utils/tracing.py | 71 + .../detectron2/utils/video_visualizer.py | 287 ++++ .../oneformer/detectron2/utils/visualizer.py | 1267 ++++++++++++++ .../annotator/oneformer/oneformer/__init__.py | 9 + .../annotator/oneformer/oneformer/config.py | 239 +++ .../oneformer/oneformer/data/__init__.py | 2 + .../data/bpe_simple_vocab_16e6.txt.gz | Bin 0 -> 1356917 bytes .../oneformer/oneformer/data/build.py | 117 ++ .../data/dataset_mappers/__init__.py | 1 + ...oco_unified_new_baseline_dataset_mapper.py | 341 ++++ .../data/dataset_mappers/dataset_mapper.py | 203 +++ .../oneformer_unified_dataset_mapper.py | 375 +++++ .../oneformer/data/datasets/__init__.py | 7 + .../data/datasets/register_ade20k_instance.py | 56 + .../data/datasets/register_ade20k_panoptic.py | 394 +++++ .../datasets/register_cityscapes_panoptic.py | 199 +++ .../register_coco_panoptic2instance.py | 44 + .../register_coco_panoptic_annos_semseg.py | 367 +++++ .../oneformer/oneformer/data/tokenizer.py | 192 +++ .../oneformer/oneformer/demo/colormap.py | 170 ++ .../oneformer/oneformer/demo/defaults.py | 77 + .../oneformer/oneformer/demo/predictor.py | 190 +++ .../oneformer/oneformer/demo/visualizer.py | 1350 +++++++++++++++ .../oneformer/evaluation/__init__.py | 3 + .../evaluation/cityscapes_evaluation.py | 201 +++ .../oneformer/evaluation/coco_evaluator.py | 563 +++++++ .../evaluation/detection_coco_evaluator.py | 723 ++++++++ .../oneformer/evaluation/evaluator.py | 228 +++ .../evaluation/instance_evaluation.py | 110 ++ .../oneformer/oneformer/modeling/__init__.py | 5 + .../oneformer/modeling/backbone/__init__.py | 1 + .../oneformer/modeling/backbone/dinat.py | 324 ++++ .../oneformer/modeling/backbone/swin.py | 771 +++++++++ .../oneformer/oneformer/modeling/matcher.py | 212 +++ .../oneformer/modeling/meta_arch/__init__.py | 1 + .../modeling/meta_arch/oneformer_head.py | 135 ++ .../modeling/pixel_decoder/__init__.py | 1 + .../oneformer/modeling/pixel_decoder/fpn.py | 312 ++++ .../modeling/pixel_decoder/msdeformattn.py | 358 ++++ .../pixel_decoder/ops/functions/__init__.py | 13 + .../ops/functions/ms_deform_attn_func.py | 77 + .../modeling/pixel_decoder/ops/make.sh | 13 + .../pixel_decoder/ops/modules/__init__.py | 12 + .../ops/modules/ms_deform_attn.py | 120 ++ .../modeling/pixel_decoder/ops/setup.py | 78 + .../ops/src/cpu/ms_deform_attn_cpu.cpp | 46 + .../ops/src/cpu/ms_deform_attn_cpu.h | 38 + .../ops/src/cuda/ms_deform_attn_cuda.cu | 158 ++ .../ops/src/cuda/ms_deform_attn_cuda.h | 35 + .../ops/src/cuda/ms_deform_im2col_cuda.cuh | 1332 +++++++++++++++ .../pixel_decoder/ops/src/ms_deform_attn.h | 67 + .../modeling/pixel_decoder/ops/src/vision.cpp | 21 + .../modeling/pixel_decoder/ops/test.py | 92 ++ .../modeling/transformer_decoder/__init__.py | 2 + .../oneformer_transformer_decoder.py | 528 ++++++ .../transformer_decoder/position_encoding.py | 67 + .../transformer_decoder/text_transformer.py | 257 +++ .../transformer_decoder/transformer.py | 376 +++++ .../oneformer/oneformer/oneformer_model.py | 470 ++++++ .../oneformer/oneformer/utils/__init__.py | 2 + .../oneformer/oneformer/utils/box_ops.py | 133 ++ .../oneformer/oneformer/utils/events.py | 120 ++ .../oneformer/oneformer/utils/misc.py | 197 +++ .../oneformer/oneformer/utils/pos_embed.py | 122 ++ .../oneformer/pycocotools/__init__.py | 1 + .../annotator/oneformer/pycocotools/coco.py | 444 +++++ .../oneformer/pycocotools/cocoeval.py | 534 ++++++ .../annotator/oneformer/pycocotools/mask.py | 107 ++ .../annotator/openpose/LICENSE | 108 ++ .../annotator/openpose/__init__.py | 463 ++++++ .../annotator/openpose/animalpose.py | 131 ++ .../annotator/openpose/body.py | 258 +++ .../annotator/openpose/cv_ox_det.py | 128 ++ .../annotator/openpose/cv_ox_pose.py | 364 +++++ .../annotator/openpose/face.py | 362 ++++ .../annotator/openpose/hand.py | 94 ++ .../annotator/openpose/model.py | 218 +++ .../annotator/openpose/types.py | 31 + .../annotator/openpose/util.py | 411 +++++ .../annotator/openpose/wholebody.py | 100 ++ .../annotator/pidinet/LICENSE | 21 + .../annotator/pidinet/__init__.py | 51 + .../annotator/pidinet/model.py | 654 ++++++++ .../annotator/shuffle/__init__.py | 18 + .../annotator/teed/Fmish.py | 17 + .../annotator/teed/Fsmish.py | 20 + .../annotator/teed/LICENSE.txt | 21 + .../annotator/teed/Xmish.py | 43 + .../annotator/teed/Xsmish.py | 43 + .../annotator/teed/__init__.py | 55 + .../sd_forge_controlnet/annotator/teed/ted.py | 296 ++++ .../annotator/uniformer/LICENSE | 203 +++ .../annotator/uniformer/__init__.py | 56 + .../configs/_base_/datasets/ade20k.py | 54 + .../configs/_base_/datasets/chase_db1.py | 59 + .../configs/_base_/datasets/cityscapes.py | 54 + .../_base_/datasets/cityscapes_769x769.py | 35 + .../configs/_base_/datasets/drive.py | 59 + .../uniformer/configs/_base_/datasets/hrf.py | 59 + .../configs/_base_/datasets/pascal_context.py | 60 + .../_base_/datasets/pascal_context_59.py | 60 + .../configs/_base_/datasets/pascal_voc12.py | 57 + .../_base_/datasets/pascal_voc12_aug.py | 9 + .../configs/_base_/datasets/stare.py | 59 + .../configs/_base_/default_runtime.py | 14 + .../configs/_base_/models/ann_r50-d8.py | 46 + .../configs/_base_/models/apcnet_r50-d8.py | 44 + .../configs/_base_/models/ccnet_r50-d8.py | 44 + .../uniformer/configs/_base_/models/cgnet.py | 35 + .../configs/_base_/models/danet_r50-d8.py | 44 + .../configs/_base_/models/deeplabv3_r50-d8.py | 44 + .../_base_/models/deeplabv3_unet_s5-d16.py | 50 + .../_base_/models/deeplabv3plus_r50-d8.py | 46 + .../configs/_base_/models/dmnet_r50-d8.py | 44 + .../configs/_base_/models/dnl_r50-d8.py | 46 + .../configs/_base_/models/emanet_r50-d8.py | 47 + .../configs/_base_/models/encnet_r50-d8.py | 48 + .../configs/_base_/models/fast_scnn.py | 57 + .../configs/_base_/models/fcn_hr18.py | 52 + .../configs/_base_/models/fcn_r50-d8.py | 45 + .../configs/_base_/models/fcn_unet_s5-d16.py | 51 + .../configs/_base_/models/fpn_r50.py | 36 + .../configs/_base_/models/fpn_uniformer.py | 35 + .../configs/_base_/models/gcnet_r50-d8.py | 46 + .../configs/_base_/models/lraspp_m-v3-d8.py | 25 + .../configs/_base_/models/nonlocal_r50-d8.py | 46 + .../configs/_base_/models/ocrnet_hr18.py | 68 + .../configs/_base_/models/ocrnet_r50-d8.py | 47 + .../configs/_base_/models/pointrend_r50.py | 56 + .../configs/_base_/models/psanet_r50-d8.py | 49 + .../configs/_base_/models/pspnet_r50-d8.py | 44 + .../_base_/models/pspnet_unet_s5-d16.py | 50 + .../configs/_base_/models/upernet_r50.py | 44 + .../_base_/models/upernet_uniformer.py | 43 + .../configs/_base_/schedules/schedule_160k.py | 9 + .../configs/_base_/schedules/schedule_20k.py | 9 + .../configs/_base_/schedules/schedule_40k.py | 9 + .../configs/_base_/schedules/schedule_80k.py | 9 + .../annotator/uniformer/inference.py | 144 ++ .../uniformer/mmcv_custom/__init__.py | 5 + .../uniformer/mmcv_custom/checkpoint.py | 508 ++++++ .../annotator/uniformer/uniformer.py | 426 +++++ .../uniformer/upernet_global_small.py | 44 + .../sd_forge_controlnet/annotator/util.py | 79 + .../sd_forge_controlnet/annotator/zoe/LICENSE | 21 + .../annotator/zoe/__init__.py | 59 + .../annotator/zoe/zoedepth/models/__init__.py | 24 + .../zoedepth/models/base_models/__init__.py | 24 + .../zoe/zoedepth/models/base_models/midas.py | 379 +++++ .../models/base_models/midas_repo/.gitignore | 110 ++ .../models/base_models/midas_repo/Dockerfile | 29 + .../models/base_models/midas_repo/LICENSE | 21 + .../models/base_models/midas_repo/README.md | 259 +++ .../base_models/midas_repo/environment.yaml | 16 + .../models/base_models/midas_repo/hubconf.py | 435 +++++ .../base_models/midas_repo/input/.placeholder | 0 .../midas_repo/midas/backbones/beit.py | 198 +++ .../midas_repo/midas/backbones/levit.py | 106 ++ .../midas_repo/midas/backbones/next_vit.py | 39 + .../midas_repo/midas/backbones/swin.py | 13 + .../midas_repo/midas/backbones/swin2.py | 34 + .../midas_repo/midas/backbones/swin_common.py | 52 + .../midas_repo/midas/backbones/utils.py | 249 +++ .../midas_repo/midas/backbones/vit.py | 221 +++ .../midas_repo/midas/base_model.py | 16 + .../base_models/midas_repo/midas/blocks.py | 439 +++++ .../base_models/midas_repo/midas/dpt_depth.py | 166 ++ .../base_models/midas_repo/midas/midas_net.py | 76 + .../midas_repo/midas/midas_net_custom.py | 128 ++ .../midas_repo/midas/model_loader.py | 242 +++ .../midas_repo/midas/transforms.py | 234 +++ .../midas_repo/output/.placeholder | 0 .../models/base_models/midas_repo/ros/LICENSE | 21 + .../base_models/midas_repo/ros/README.md | 131 ++ .../ros/additions/do_catkin_make.sh | 5 + .../midas_repo/ros/additions/downloads.sh | 5 + .../install_ros_melodic_ubuntu_17_18.sh | 34 + .../additions/install_ros_noetic_ubuntu_20.sh | 33 + .../ros/additions/make_package_cpp.sh | 16 + .../midas_repo/ros/launch_midas_cpp.sh | 2 + .../midas_repo/ros/midas_cpp/CMakeLists.txt | 189 +++ .../ros/midas_cpp/launch/midas_cpp.launch | 19 + .../launch/midas_talker_listener.launch | 23 + .../midas_repo/ros/midas_cpp/package.xml | 77 + .../ros/midas_cpp/scripts/listener.py | 61 + .../midas_cpp/scripts/listener_original.py | 61 + .../ros/midas_cpp/scripts/talker.py | 53 + .../midas_repo/ros/midas_cpp/src/main.cpp | 285 ++++ .../ros/run_talker_listener_test.sh | 16 + .../models/base_models/midas_repo/run.py | 277 ++++ .../base_models/midas_repo/tf/README.md | 147 ++ .../midas_repo/tf/input/.placeholder | 0 .../midas_repo/tf/make_onnx_model.py | 112 ++ .../midas_repo/tf/output/.placeholder | 0 .../base_models/midas_repo/tf/run_onnx.py | 119 ++ .../base_models/midas_repo/tf/run_pb.py | 135 ++ .../base_models/midas_repo/tf/transforms.py | 234 +++ .../models/base_models/midas_repo/tf/utils.py | 82 + .../models/base_models/midas_repo/utils.py | 199 +++ .../midas_repo/weights/.placeholder | 0 .../annotator/zoe/zoedepth/models/builder.py | 51 + .../zoe/zoedepth/models/depth_model.py | 152 ++ .../zoe/zoedepth/models/layers/attractor.py | 208 +++ .../zoe/zoedepth/models/layers/dist_layers.py | 121 ++ .../models/layers/localbins_layers.py | 169 ++ .../models/layers/patch_transformer.py | 91 ++ .../annotator/zoe/zoedepth/models/model_io.py | 92 ++ .../zoe/zoedepth/models/zoedepth/__init__.py | 31 + .../models/zoedepth/config_zoedepth.json | 58 + .../zoedepth/config_zoedepth_kitti.json | 22 + .../zoedepth/models/zoedepth/zoedepth_v1.py | 250 +++ .../zoedepth/models/zoedepth_nk/__init__.py | 31 + .../zoedepth_nk/config_zoedepth_nk.json | 67 + .../models/zoedepth_nk/zoedepth_nk_v1.py | 333 ++++ .../annotator/zoe/zoedepth/utils/__init__.py | 24 + .../annotator/zoe/zoedepth/utils/arg_utils.py | 33 + .../annotator/zoe/zoedepth/utils/config.py | 437 +++++ .../zoe/zoedepth/utils/easydict/__init__.py | 158 ++ .../annotator/zoe/zoedepth/utils/geometry.py | 98 ++ .../annotator/zoe/zoedepth/utils/misc.py | 368 +++++ .../api_advanced_weighting.py | 119 ++ .../stock_mountain.png | Bin 0 -> 106568 bytes .../sd_forge_controlnet/example/chatgpt.py | 676 ++++++++ .../example/inpaint_example/1girl.png | Bin 0 -> 493039 bytes .../example/inpaint_example/api_inpaint.py | 174 ++ .../example/inpaint_example/mask.png | Bin 0 -> 244 bytes .../example/txt2img_example/api_txt2img.py | 77 + .../txt2img_example/stock_mountain.png | Bin 0 -> 106568 bytes .../example/visual_chatgpt.ipynb | 60 + .../sd_forge_controlnet/extract_controlnet.py | 27 + .../extract_controlnet_diff.py | 91 ++ .../sd_forge_controlnet/install.py | 145 ++ .../internal_controlnet/external_code.py | 515 ++++++ .../javascript/active_units.js | 311 ++++ .../sd_forge_controlnet/javascript/canvas.js | 17 + .../sd_forge_controlnet/javascript/modal.js | 33 + .../javascript/openpose_editor.js | 152 ++ .../javascript/photopea.js | 435 +++++ .../models/put_controlnet_models_here.txt | 1 + .../sd_forge_controlnet/patch_version.py | 53 + .../sd_forge_controlnet/preload.py | 39 + .../sd_forge_controlnet/requirements.txt | 5 + .../sd_forge_controlnet/samples/an-gen.png | Bin 0 -> 129751 bytes .../sd_forge_controlnet/samples/an-pose.png | Bin 0 -> 3113 bytes .../sd_forge_controlnet/samples/an-source.jpg | Bin 0 -> 18734 bytes .../sd_forge_controlnet/samples/bal-gen.png | Bin 0 -> 90193 bytes .../samples/bal-source.png | Bin 0 -> 8553 bytes .../sd_forge_controlnet/samples/cm1.png | Bin 0 -> 192982 bytes .../sd_forge_controlnet/samples/cm2.png | Bin 0 -> 396024 bytes .../sd_forge_controlnet/samples/cm3.png | Bin 0 -> 384236 bytes .../sd_forge_controlnet/samples/cm4.png | Bin 0 -> 416352 bytes .../sd_forge_controlnet/samples/dog_rel.jpg | Bin 0 -> 48778 bytes .../sd_forge_controlnet/samples/dog_rel.png | Bin 0 -> 462986 bytes .../sd_forge_controlnet/samples/evt_gen.png | Bin 0 -> 179979 bytes .../sd_forge_controlnet/samples/evt_hed.png | Bin 0 -> 140507 bytes .../samples/evt_source.jpg | Bin 0 -> 145909 bytes .../samples/mahiro-out.png | Bin 0 -> 415672 bytes .../samples/mahiro_canny.png | Bin 0 -> 9585 bytes .../samples/mahiro_input.png | Bin 0 -> 60201 bytes .../sd_forge_controlnet/samples/ref.png | Bin 0 -> 620406 bytes .../sd_forge_controlnet/samples/sk-b-dep.png | Bin 0 -> 121145 bytes .../sd_forge_controlnet/samples/sk-b-out.png | Bin 0 -> 576953 bytes .../sd_forge_controlnet/samples/sk-b-src.png | Bin 0 -> 561584 bytes .../sd_forge_controlnet/scripts/adapter.py | 373 +++++ .../sd_forge_controlnet/scripts/api.py | 197 +++ .../scripts/batch_hijack.py | 210 +++ .../sd_forge_controlnet/scripts/cldm.py | 322 ++++ .../scripts/controlmodel_ipadapter.py | 614 +++++++ .../sd_forge_controlnet/scripts/controlnet.py | 1283 +++++++++++++++ .../scripts/controlnet_diffusers.py | 95 ++ .../scripts/controlnet_lllite.py | 220 +++ .../scripts/controlnet_lora.py | 191 +++ .../scripts/controlnet_model_guess.py | 261 +++ .../controlnet_ui/controlnet_ui_group.py | 1412 ++++++++++++++++ .../scripts/controlnet_ui/modal.py | 38 + .../scripts/controlnet_ui/openpose_editor.py | 154 ++ .../scripts/controlnet_ui/photopea.py | 182 +++ .../scripts/controlnet_ui/preset.py | 319 ++++ .../scripts/controlnet_ui/tool_button.py | 12 + .../scripts/controlnet_version.py | 10 + .../sd_forge_controlnet/scripts/enums.py | 115 ++ .../scripts/external_code.py | 1 + .../scripts/global_state.py | 355 ++++ .../sd_forge_controlnet/scripts/hook.py | 1014 ++++++++++++ .../sd_forge_controlnet/scripts/infotext.py | 135 ++ .../sd_forge_controlnet/scripts/logging.py | 41 + .../sd_forge_controlnet/scripts/lvminthin.py | 88 + .../scripts/movie2movie.py | 176 ++ .../sd_forge_controlnet/scripts/processor.py | 1245 ++++++++++++++ .../sd_forge_controlnet/scripts/utils.py | 180 ++ .../scripts/xyz_grid_support.py | 449 +++++ .../sd_forge_controlnet/style.css | 182 +++ .../sd_forge_controlnet/tests/README.md | 47 + .../openpose_tests/body_test.py | 50 + .../openpose_tests/detection_test.py | 109 ++ .../openpose_tests/json_encode_test.py | 83 + .../openpose_e2e_test_disabled.py | 115 ++ .../tests/cn_script/__init__.py | 0 .../tests/cn_script/batch_hijack_test.py | 337 ++++ .../tests/cn_script/cn_script_test.py | 184 +++ .../tests/cn_script/global_state_test.py | 67 + .../tests/cn_script/infotext_test.py | 34 + .../tests/cn_script/utils_test.py | 75 + .../tests/external_code_api/__init__.py | 0 .../external_code_api/external_code_test.py | 170 ++ .../importlib_reload_test.py | 24 + .../external_code_api/script_args_test.py | 34 + .../tests/images/1girl.png | Bin 0 -> 493039 bytes .../tests/images/expected_ski_output.png | Bin 0 -> 4792 bytes .../images/expected_woman_all_output.png | Bin 0 -> 13675 bytes .../images/expected_woman_dw_all_output.png | Bin 0 -> 15282 bytes .../images/expected_woman_face_output.png | Bin 0 -> 4426 bytes .../images/expected_woman_hand_output.png | Bin 0 -> 6039 bytes .../tests/images/living_room.webp | Bin 0 -> 79796 bytes .../sd_forge_controlnet/tests/images/mask.png | Bin 0 -> 244 bytes .../tests/images/mask_small.png | Bin 0 -> 226 bytes .../tests/images/portrait/1.webp | Bin 0 -> 20481 bytes .../tests/images/portrait/2.jpg | Bin 0 -> 37869 bytes .../tests/images/portrait/3.jpeg | Bin 0 -> 22485 bytes .../tests/images/portrait/4.jpg | Bin 0 -> 6600 bytes .../tests/images/portrait/5.jpg | Bin 0 -> 206595 bytes .../tests/images/portrait/6.jpg | Bin 0 -> 15098 bytes .../sd_forge_controlnet/tests/images/ski.jpg | Bin 0 -> 141529 bytes .../tests/images/woman.jpeg | Bin 0 -> 44572 bytes .../sd_forge_controlnet/tests/utils.py | 67 + .../tests/web_api/__init__.py | 0 .../tests/web_api/animal_pose.json | 60 + .../tests/web_api/control_types_test.py | 24 + .../tests/web_api/detect_test.py | 47 + .../tests/web_api/full_coverage/README.md | 3 + .../tests/web_api/full_coverage/__init__.py | 0 .../tests/web_api/full_coverage/depth_test.py | 66 + .../web_api/full_coverage/inpaint_test.py | 219 +++ .../web_api/full_coverage/ipadapter_test.py | 169 ++ .../tests/web_api/full_coverage/template.py | 265 +++ .../tests/web_api/img2img_test.py | 99 ++ .../tests/web_api/pose.json | 194 +++ .../tests/web_api/render_openpose_json.py | 51 + .../tests/web_api/txt2img_test.py | 286 ++++ .../sd_forge_controlnet/web_tests/README.md | 15 + .../web_tests/images/ski.jpg | Bin 0 -> 141529 bytes .../sd_forge_controlnet/web_tests/main.py | 393 +++++ 940 files changed, 150956 insertions(+) create mode 100644 extensions-builtin/sd_forge_controlnet/.gitignore create mode 100644 extensions-builtin/sd_forge_controlnet/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/README.md create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/anime_face_segment/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/anime_face_segment/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/annotator_path.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/binary/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/canny/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/clipvision/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/clipvision/clip_vision_h_uc.data create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/clipvision/clip_vision_vith_uc.data create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/color/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/densepose/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/densepose/densepose.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/depth_anything.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/hed/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/keypose/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/keypose/faster_rcnn_r50_fpn_coco.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/keypose/hrnet_w48_coco_256x192.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/config.yaml create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/data/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/data/masks.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/adversarial.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/constants.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/distance_weighting.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/feature_matching.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/perceptual.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/segmentation.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/style_loss.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/base.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/depthwise_sep_conv.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/fake_fakes.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/ffc.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/multidilated_conv.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/multiscale.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/pix2pixhd.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/spatial_transform.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/squeeze_excitation.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/trainers/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/trainers/base.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/trainers/default.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/base.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/colors.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/directory.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/noop.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/leres/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/leres/Resnet.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/leres/Resnext_torch.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/leres/depthmap.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/leres/multi_depth_model_woauxi.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/leres/net_tools.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/leres/network_auxi.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/base_model.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/base_model_hg.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/networks.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/pix2pix4depth_model.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/options/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/options/base_options.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/options/test_options.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/get_data.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/guidedfilter.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/html.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/image_pool.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/util.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/visualizer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lineart/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lineart/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lineart_anime/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/lineart_anime/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/manga_line/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/manga_line/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mediapipe_face/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mediapipe_face/mediapipe_face_common.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/midas/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/midas/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/midas/api.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/midas/midas/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/midas/midas/base_model.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/midas/midas/blocks.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/midas/midas/dpt_depth.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/midas/midas/midas_net.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/midas/midas/midas_net_custom.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/midas/midas/transforms.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/midas/midas/vit.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/midas/utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mlsd/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mlsd/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mlsd/models/mbv2_mlsd_large.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mlsd/models/mbv2_mlsd_tiny.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mlsd/utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/arraymisc/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/arraymisc/quantization.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/alexnet.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/activation.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/context_block.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/conv.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/conv2d_adaptive_padding.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/conv_module.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/conv_ws.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/depthwise_separable_conv_module.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/drop.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/generalized_attention.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/hsigmoid.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/hswish.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/non_local.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/norm.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/padding.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/plugin.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/registry.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/scale.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/swish.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/transformer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/upsample.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/wrappers.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/builder.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/resnet.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/flops_counter.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/fuse_conv_bn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/sync_bn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/weight_init.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/vgg.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/engine/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/engine/test.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/file_client.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/base.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/json_handler.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/pickle_handler.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/yaml_handler.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/io.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/parse.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/colorspace.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/geometric.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/io.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/misc.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/photometric.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/model_zoo/deprecated.json create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/model_zoo/mmcls.json create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/model_zoo/open_mmlab.json create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/assign_score_withk.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/ball_query.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/bbox.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/border_align.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/box_iou_rotated.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/carafe.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/cc_attention.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/contour_expand.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/corner_pool.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/correlation.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/deform_conv.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/deform_roi_pool.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/deprecated_wrappers.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/focal_loss.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/furthest_point_sample.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/fused_bias_leakyrelu.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/gather_points.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/group_points.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/info.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/iou3d.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/knn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/masked_conv.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/merge_cells.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/modulated_deform_conv.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/multi_scale_deform_attn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/nms.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/pixel_group.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/point_sample.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/points_in_boxes.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/points_sampler.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/psa_mask.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roi_align.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roi_align_rotated.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roi_pool.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roiaware_pool3d.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roipoint_pool3d.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/saconv.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/scatter_points.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/sync_bn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/three_interpolate.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/three_nn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/tin_shift.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/upfirdn2d.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/voxelize.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/_functions.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/collate.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/data_container.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/data_parallel.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/distributed.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/distributed_deprecated.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/registry.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/scatter_gather.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/base_module.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/base_runner.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/builder.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/checkpoint.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/default_constructor.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/dist_utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/epoch_based_runner.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/fp16_utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/checkpoint.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/closure.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/ema.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/evaluation.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/hook.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/iter_timer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/base.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/dvclive.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/mlflow.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/neptune.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/pavi.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/tensorboard.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/text.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/wandb.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/lr_updater.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/memory.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/momentum_updater.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/optimizer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/profiler.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/sampler_seed.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/sync_buffer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/iter_based_runner.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/log_buffer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/optimizer/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/optimizer/builder.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/optimizer/default_constructor.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/priority.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/config.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/env.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/ext_loader.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/logging.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/misc.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/parrots_jit.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/parrots_wrapper.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/path.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/progressbar.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/registry.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/testing.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/timer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/trace.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/version_utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/version.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/video/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/video/io.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/video/optflow.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/video/processing.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/visualization/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/visualization/color.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/visualization/image.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/visualization/optflow.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/apis/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/apis/inference.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/apis/test.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/apis/train.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/evaluation/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/evaluation/class_names.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/evaluation/eval_hooks.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/evaluation/metrics.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/builder.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/sampler/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/sampler/base_pixel_sampler.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/sampler/ohem_pixel_sampler.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/utils/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/utils/misc.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/ade.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/builder.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/chase_db1.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/cityscapes.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/custom.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/dataset_wrappers.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/drive.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/hrf.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pascal_context.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/compose.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/formating.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/loading.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/test_time_aug.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/transforms.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/stare.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/voc.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/cgnet.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/fast_scnn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/hrnet.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/mobilenet_v2.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/mobilenet_v3.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/resnest.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/resnet.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/resnext.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/unet.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/vit.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/builder.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/ann_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/apc_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/aspp_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/cascade_decode_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/cc_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/da_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/decode_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/dm_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/dnl_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/ema_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/enc_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/fcn_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/fpn_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/gc_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/lraspp_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/nl_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/ocr_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/point_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/psa_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/psp_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/sep_aspp_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/sep_fcn_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/uper_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/accuracy.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/cross_entropy_loss.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/dice_loss.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/lovasz_loss.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/necks/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/necks/fpn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/necks/multilevel_neck.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/segmentors/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/segmentors/base.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/segmentors/cascade_encoder_decoder.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/segmentors/encoder_decoder.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/drop.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/inverted_residual.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/make_divisible.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/res_layer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/se_layer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/self_attention_block.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/up_conv_block.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/weight_init.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/ops/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/ops/encoding.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/ops/wrappers.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/utils/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/utils/collect_env.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/utils/logger.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/NNET.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/baseline.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/decoder.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/.gitignore create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/BENCHMARK.md create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/README.md create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/caffe2_benchmark.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/caffe2_validate.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/activations/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/activations/activations.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/activations/activations_jit.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/activations/activations_me.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/config.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/conv2d_layers.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/efficientnet_builder.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/gen_efficientnet.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/helpers.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/mobilenetv3.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/model_factory.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/version.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/hubconf.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/onnx_export.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/onnx_optimize.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/onnx_to_caffe.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/onnx_validate.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/requirements.txt create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/setup.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/validate.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/encoder.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/submodules.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/api.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/ade20k/Base-ADE20K-UnifiedSegmentation.yaml create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/ade20k/oneformer_R50_bs16_160k.yaml create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/ade20k/oneformer_swin_large_IN21k_384_bs16_160k.yaml create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/coco/Base-COCO-UnifiedSegmentation.yaml create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/coco/oneformer_R50_bs16_50ep.yaml create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/coco/oneformer_swin_large_IN21k_384_bs16_100ep.yaml create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/checkpoint/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/checkpoint/c2_model_loading.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/checkpoint/catalog.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/checkpoint/detection_checkpoint.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/compat.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/config.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/defaults.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/instantiate.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/lazy.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/benchmark.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/build.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/catalog.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/common.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/dataset_mapper.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/README.md create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/builtin.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/builtin_meta.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/cityscapes.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/cityscapes_panoptic.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/coco.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/coco_panoptic.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/lvis.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/lvis_v0_5_categories.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/lvis_v1_categories.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/lvis_v1_category_image_count.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/pascal_voc.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/register_coco.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/detection_utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/samplers/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/samplers/distributed_sampler.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/samplers/grouped_batch_sampler.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/transforms/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/transforms/augmentation.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/transforms/augmentation_impl.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/transforms/transform.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/defaults.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/hooks.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/launch.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/train_loop.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/cityscapes_evaluation.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/coco_evaluation.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/evaluator.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/fast_eval_api.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/lvis_evaluation.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/panoptic_evaluation.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/pascal_voc_evaluation.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/rotated_coco_evaluation.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/sem_seg_evaluation.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/testing.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/README.md create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/api.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/c10.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/caffe2_export.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/caffe2_inference.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/caffe2_modeling.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/caffe2_patch.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/flatten.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/shared.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/torchscript.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/torchscript_patch.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/aspp.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/batch_norm.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/blocks.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/README.md create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/ROIAlignRotated/ROIAlignRotated.h create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/ROIAlignRotated/ROIAlignRotated_cpu.cpp create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/ROIAlignRotated/ROIAlignRotated_cuda.cu create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/box_iou_rotated/box_iou_rotated.h create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/box_iou_rotated/box_iou_rotated_cpu.cpp create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/box_iou_rotated/box_iou_rotated_cuda.cu create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/box_iou_rotated/box_iou_rotated_utils.h create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/cocoeval/cocoeval.cpp create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/cocoeval/cocoeval.h create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/cuda_version.cu create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/deformable/deform_conv.h create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/deformable/deform_conv_cuda.cu create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/deformable/deform_conv_cuda_kernel.cu create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/nms_rotated/nms_rotated.h create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/nms_rotated/nms_rotated_cpu.cpp create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/nms_rotated/nms_rotated_cuda.cu create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/vision.cpp create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/deform_conv.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/losses.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/mask_ops.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/nms.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/roi_align.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/roi_align_rotated.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/rotated_boxes.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/shape_spec.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/wrappers.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/model_zoo/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/model_zoo/model_zoo.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/anchor_generator.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/backbone.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/build.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/fpn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/mvit.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/regnet.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/resnet.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/swin.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/vit.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/box_regression.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/matcher.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/build.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/dense_detector.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/fcos.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/panoptic_fpn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/rcnn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/retinanet.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/semantic_seg.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/mmdet_wrapper.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/poolers.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/postprocessing.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/build.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/proposal_utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/rpn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/rrpn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/box_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/cascade_rcnn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/fast_rcnn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/keypoint_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/mask_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/roi_heads.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/rotated_fast_rcnn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/sampling.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/test_time_augmentation.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/README.md create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/build_solver.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/config.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/loss.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/lr_scheduler.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/resnet.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/semantic_seg.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/solver/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/solver/build.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/solver/lr_scheduler.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/boxes.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/image_list.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/instances.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/keypoints.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/masks.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/rotated_boxes.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/base_tracker.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/bbox_iou_tracker.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/hungarian_tracker.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/iou_weighted_hungarian_bbox_iou_tracker.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/vanilla_hungarian_bbox_iou_tracker.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/README.md create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/analysis.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/collect_env.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/colormap.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/comm.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/develop.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/env.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/events.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/file_io.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/logger.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/memory.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/registry.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/serialize.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/testing.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/tracing.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/video_visualizer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/visualizer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/config.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/bpe_simple_vocab_16e6.txt.gz create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/build.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/dataset_mappers/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/dataset_mappers/coco_unified_new_baseline_dataset_mapper.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/dataset_mappers/dataset_mapper.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/dataset_mappers/oneformer_unified_dataset_mapper.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_ade20k_instance.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_ade20k_panoptic.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_cityscapes_panoptic.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_coco_panoptic2instance.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_coco_panoptic_annos_semseg.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/tokenizer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/demo/colormap.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/demo/defaults.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/demo/predictor.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/demo/visualizer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/cityscapes_evaluation.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/coco_evaluator.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/detection_coco_evaluator.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/evaluator.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/instance_evaluation.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/backbone/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/backbone/dinat.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/backbone/swin.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/matcher.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/meta_arch/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/meta_arch/oneformer_head.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/fpn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/msdeformattn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/functions/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/functions/ms_deform_attn_func.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/make.sh create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/modules/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/modules/ms_deform_attn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/setup.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cpu/ms_deform_attn_cpu.cpp create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cpu/ms_deform_attn_cpu.h create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cuda/ms_deform_attn_cuda.cu create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cuda/ms_deform_attn_cuda.h create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cuda/ms_deform_im2col_cuda.cuh create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/ms_deform_attn.h create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/vision.cpp create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/test.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/oneformer_transformer_decoder.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/position_encoding.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/text_transformer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/transformer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/oneformer_model.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/box_ops.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/events.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/misc.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/pos_embed.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/pycocotools/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/pycocotools/coco.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/pycocotools/cocoeval.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/oneformer/pycocotools/mask.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/openpose/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/openpose/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/openpose/animalpose.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/openpose/body.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/openpose/cv_ox_det.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/openpose/cv_ox_pose.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/openpose/face.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/openpose/hand.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/openpose/model.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/openpose/types.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/openpose/util.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/openpose/wholebody.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/pidinet/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/pidinet/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/pidinet/model.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/shuffle/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/teed/Fmish.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/teed/Fsmish.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/teed/LICENSE.txt create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/teed/Xmish.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/teed/Xsmish.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/teed/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/teed/ted.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/ade20k.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/chase_db1.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/cityscapes.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/cityscapes_769x769.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/drive.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/hrf.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/pascal_context.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/pascal_context_59.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/pascal_voc12.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/pascal_voc12_aug.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/stare.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/default_runtime.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/ann_r50-d8.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/apcnet_r50-d8.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/ccnet_r50-d8.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/cgnet.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/danet_r50-d8.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/deeplabv3_r50-d8.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/deeplabv3_unet_s5-d16.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/deeplabv3plus_r50-d8.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/dmnet_r50-d8.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/dnl_r50-d8.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/emanet_r50-d8.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/encnet_r50-d8.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fast_scnn.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fcn_hr18.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fcn_r50-d8.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fcn_unet_s5-d16.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fpn_r50.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fpn_uniformer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/gcnet_r50-d8.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/lraspp_m-v3-d8.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/nonlocal_r50-d8.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/ocrnet_hr18.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/ocrnet_r50-d8.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/pointrend_r50.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/psanet_r50-d8.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/pspnet_r50-d8.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/pspnet_unet_s5-d16.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/upernet_r50.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/upernet_uniformer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/schedules/schedule_160k.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/schedules/schedule_20k.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/schedules/schedule_40k.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/schedules/schedule_80k.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/inference.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/mmcv_custom/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/mmcv_custom/checkpoint.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/uniformer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/uniformer/upernet_global_small.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/util.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/.gitignore create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/Dockerfile create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/README.md create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/environment.yaml create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/hubconf.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/input/.placeholder create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/beit.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/levit.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/next_vit.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/swin.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/swin2.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/swin_common.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/vit.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/base_model.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/blocks.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/dpt_depth.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/midas_net.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/midas_net_custom.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/model_loader.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/transforms.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/output/.placeholder create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/LICENSE create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/README.md create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/do_catkin_make.sh create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/downloads.sh create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/install_ros_melodic_ubuntu_17_18.sh create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/install_ros_noetic_ubuntu_20.sh create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/make_package_cpp.sh create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/launch_midas_cpp.sh create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/CMakeLists.txt create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/launch/midas_cpp.launch create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/launch/midas_talker_listener.launch create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/package.xml create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/scripts/listener.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/scripts/listener_original.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/scripts/talker.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/src/main.cpp create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/run_talker_listener_test.sh create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/run.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/README.md create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/input/.placeholder create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/make_onnx_model.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/output/.placeholder create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/run_onnx.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/run_pb.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/transforms.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/weights/.placeholder create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/builder.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/depth_model.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/layers/attractor.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/layers/dist_layers.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/layers/localbins_layers.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/layers/patch_transformer.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/model_io.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth/config_zoedepth.json create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth/config_zoedepth_kitti.json create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth/zoedepth_v1.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth_nk/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth_nk/config_zoedepth_nk.json create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth_nk/zoedepth_nk_v1.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/arg_utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/config.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/easydict/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/geometry.py create mode 100644 extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/misc.py create mode 100644 extensions-builtin/sd_forge_controlnet/example/advanced_weighting_example/api_advanced_weighting.py create mode 100644 extensions-builtin/sd_forge_controlnet/example/advanced_weighting_example/stock_mountain.png create mode 100644 extensions-builtin/sd_forge_controlnet/example/chatgpt.py create mode 100644 extensions-builtin/sd_forge_controlnet/example/inpaint_example/1girl.png create mode 100644 extensions-builtin/sd_forge_controlnet/example/inpaint_example/api_inpaint.py create mode 100644 extensions-builtin/sd_forge_controlnet/example/inpaint_example/mask.png create mode 100644 extensions-builtin/sd_forge_controlnet/example/txt2img_example/api_txt2img.py create mode 100644 extensions-builtin/sd_forge_controlnet/example/txt2img_example/stock_mountain.png create mode 100644 extensions-builtin/sd_forge_controlnet/example/visual_chatgpt.ipynb create mode 100644 extensions-builtin/sd_forge_controlnet/extract_controlnet.py create mode 100644 extensions-builtin/sd_forge_controlnet/extract_controlnet_diff.py create mode 100644 extensions-builtin/sd_forge_controlnet/install.py create mode 100644 extensions-builtin/sd_forge_controlnet/internal_controlnet/external_code.py create mode 100644 extensions-builtin/sd_forge_controlnet/javascript/active_units.js create mode 100644 extensions-builtin/sd_forge_controlnet/javascript/canvas.js create mode 100644 extensions-builtin/sd_forge_controlnet/javascript/modal.js create mode 100644 extensions-builtin/sd_forge_controlnet/javascript/openpose_editor.js create mode 100644 extensions-builtin/sd_forge_controlnet/javascript/photopea.js create mode 100644 extensions-builtin/sd_forge_controlnet/models/put_controlnet_models_here.txt create mode 100644 extensions-builtin/sd_forge_controlnet/patch_version.py create mode 100644 extensions-builtin/sd_forge_controlnet/preload.py create mode 100644 extensions-builtin/sd_forge_controlnet/requirements.txt create mode 100644 extensions-builtin/sd_forge_controlnet/samples/an-gen.png create mode 100644 extensions-builtin/sd_forge_controlnet/samples/an-pose.png create mode 100644 extensions-builtin/sd_forge_controlnet/samples/an-source.jpg create mode 100644 extensions-builtin/sd_forge_controlnet/samples/bal-gen.png create mode 100644 extensions-builtin/sd_forge_controlnet/samples/bal-source.png create mode 100644 extensions-builtin/sd_forge_controlnet/samples/cm1.png create mode 100644 extensions-builtin/sd_forge_controlnet/samples/cm2.png create mode 100644 extensions-builtin/sd_forge_controlnet/samples/cm3.png create mode 100644 extensions-builtin/sd_forge_controlnet/samples/cm4.png create mode 100644 extensions-builtin/sd_forge_controlnet/samples/dog_rel.jpg create mode 100644 extensions-builtin/sd_forge_controlnet/samples/dog_rel.png create mode 100644 extensions-builtin/sd_forge_controlnet/samples/evt_gen.png create mode 100644 extensions-builtin/sd_forge_controlnet/samples/evt_hed.png create mode 100644 extensions-builtin/sd_forge_controlnet/samples/evt_source.jpg create mode 100644 extensions-builtin/sd_forge_controlnet/samples/mahiro-out.png create mode 100644 extensions-builtin/sd_forge_controlnet/samples/mahiro_canny.png create mode 100644 extensions-builtin/sd_forge_controlnet/samples/mahiro_input.png create mode 100644 extensions-builtin/sd_forge_controlnet/samples/ref.png create mode 100644 extensions-builtin/sd_forge_controlnet/samples/sk-b-dep.png create mode 100644 extensions-builtin/sd_forge_controlnet/samples/sk-b-out.png create mode 100644 extensions-builtin/sd_forge_controlnet/samples/sk-b-src.png create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/adapter.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/api.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/batch_hijack.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/cldm.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/controlmodel_ipadapter.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/controlnet.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/controlnet_diffusers.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/controlnet_lllite.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/controlnet_lora.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/controlnet_model_guess.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/controlnet_ui_group.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/modal.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/openpose_editor.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/photopea.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/preset.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/tool_button.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/controlnet_version.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/enums.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/external_code.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/global_state.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/hook.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/infotext.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/logging.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/lvminthin.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/movie2movie.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/processor.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/scripts/xyz_grid_support.py create mode 100644 extensions-builtin/sd_forge_controlnet/style.css create mode 100644 extensions-builtin/sd_forge_controlnet/tests/README.md create mode 100644 extensions-builtin/sd_forge_controlnet/tests/annotator_tests/openpose_tests/body_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/annotator_tests/openpose_tests/detection_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/annotator_tests/openpose_tests/json_encode_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/annotator_tests/openpose_tests/openpose_e2e_test_disabled.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/cn_script/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/cn_script/batch_hijack_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/cn_script/cn_script_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/cn_script/global_state_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/cn_script/infotext_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/cn_script/utils_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/external_code_api/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/external_code_api/external_code_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/external_code_api/importlib_reload_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/external_code_api/script_args_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/images/1girl.png create mode 100644 extensions-builtin/sd_forge_controlnet/tests/images/expected_ski_output.png create mode 100644 extensions-builtin/sd_forge_controlnet/tests/images/expected_woman_all_output.png create mode 100644 extensions-builtin/sd_forge_controlnet/tests/images/expected_woman_dw_all_output.png create mode 100644 extensions-builtin/sd_forge_controlnet/tests/images/expected_woman_face_output.png create mode 100644 extensions-builtin/sd_forge_controlnet/tests/images/expected_woman_hand_output.png create mode 100644 extensions-builtin/sd_forge_controlnet/tests/images/living_room.webp create mode 100644 extensions-builtin/sd_forge_controlnet/tests/images/mask.png create mode 100644 extensions-builtin/sd_forge_controlnet/tests/images/mask_small.png create mode 100644 extensions-builtin/sd_forge_controlnet/tests/images/portrait/1.webp create mode 100644 extensions-builtin/sd_forge_controlnet/tests/images/portrait/2.jpg create mode 100644 extensions-builtin/sd_forge_controlnet/tests/images/portrait/3.jpeg create mode 100644 extensions-builtin/sd_forge_controlnet/tests/images/portrait/4.jpg create mode 100644 extensions-builtin/sd_forge_controlnet/tests/images/portrait/5.jpg create mode 100644 extensions-builtin/sd_forge_controlnet/tests/images/portrait/6.jpg create mode 100644 extensions-builtin/sd_forge_controlnet/tests/images/ski.jpg create mode 100644 extensions-builtin/sd_forge_controlnet/tests/images/woman.jpeg create mode 100644 extensions-builtin/sd_forge_controlnet/tests/utils.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/web_api/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/web_api/animal_pose.json create mode 100644 extensions-builtin/sd_forge_controlnet/tests/web_api/control_types_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/web_api/detect_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/README.md create mode 100644 extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/__init__.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/depth_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/inpaint_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/ipadapter_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/template.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/web_api/img2img_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/web_api/pose.json create mode 100644 extensions-builtin/sd_forge_controlnet/tests/web_api/render_openpose_json.py create mode 100644 extensions-builtin/sd_forge_controlnet/tests/web_api/txt2img_test.py create mode 100644 extensions-builtin/sd_forge_controlnet/web_tests/README.md create mode 100644 extensions-builtin/sd_forge_controlnet/web_tests/images/ski.jpg create mode 100644 extensions-builtin/sd_forge_controlnet/web_tests/main.py diff --git a/extensions-builtin/sd_forge_controlnet/.gitignore b/extensions-builtin/sd_forge_controlnet/.gitignore new file mode 100644 index 00000000..60d06e51 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/.gitignore @@ -0,0 +1,185 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea +*.pt +*.pth +*.ckpt +*.bin +*.safetensors + +# Editor setting metadata +.idea/ +.vscode/ +detected_maps/ +annotator/downloads/ + +# test results and expectations +web_tests/results/ +web_tests/expectations/ +tests/web_api/full_coverage/results/ +tests/web_api/full_coverage/expectations/ + +*_diff.png + +# Presets +presets/ + +# Ignore existing dir of hand refiner if exists. +annotator/hand_refiner_portable \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/LICENSE b/extensions-builtin/sd_forge_controlnet/LICENSE new file mode 100644 index 00000000..f288702d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/extensions-builtin/sd_forge_controlnet/README.md b/extensions-builtin/sd_forge_controlnet/README.md new file mode 100644 index 00000000..38460eca --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/README.md @@ -0,0 +1,243 @@ +# ControlNet for Stable Diffusion WebUI + +The WebUI extension for ControlNet and other injection-based SD controls. + +![image](https://github.com/Mikubill/sd-webui-controlnet/assets/20929282/51172d20-606b-4b9f-aba5-db2f2417cb0b) + +This extension is for AUTOMATIC1111's [Stable Diffusion web UI](https://github.com/AUTOMATIC1111/stable-diffusion-webui), allows the Web UI to add [ControlNet](https://github.com/lllyasviel/ControlNet) to the original Stable Diffusion model to generate images. The addition is on-the-fly, the merging is not required. + +# Installation + +1. Open "Extensions" tab. +2. Open "Install from URL" tab in the tab. +3. Enter `https://github.com/Mikubill/sd-webui-controlnet.git` to "URL for extension's git repository". +4. Press "Install" button. +5. Wait for 5 seconds, and you will see the message "Installed into stable-diffusion-webui\extensions\sd-webui-controlnet. Use Installed tab to restart". +6. Go to "Installed" tab, click "Check for updates", and then click "Apply and restart UI". (The next time you can also use these buttons to update ControlNet.) +7. Completely restart A1111 webui including your terminal. (If you do not know what is a "terminal", you can reboot your computer to achieve the same effect.) +8. Download models (see below). +9. After you put models in the correct folder, you may need to refresh to see the models. The refresh button is right to your "Model" dropdown. + +# Download Models + +Right now all the 14 models of ControlNet 1.1 are in the beta test. + +Download the models from ControlNet 1.1: https://huggingface.co/lllyasviel/ControlNet-v1-1/tree/main + +You need to download model files ending with ".pth" . + +Put models in your "stable-diffusion-webui\extensions\sd-webui-controlnet\models". You only need to download "pth" files. + +Do not right-click the filenames in HuggingFace website to download. Some users right-clicked those HuggingFace HTML websites and saved those HTML pages as PTH/YAML files. They are not downloading correct files. Instead, please click the small download arrow “↓” icon in HuggingFace to download. + +# Download Models for SDXL + +See instructions [here](https://github.com/Mikubill/sd-webui-controlnet/discussions/2039). + +# Features in ControlNet 1.1 + +### Perfect Support for All ControlNet 1.0/1.1 and T2I Adapter Models. + +Now we have perfect support all available models and preprocessors, including perfect support for T2I style adapter and ControlNet 1.1 Shuffle. (Make sure that your YAML file names and model file names are same, see also YAML files in "stable-diffusion-webui\extensions\sd-webui-controlnet\models".) + +### Perfect Support for A1111 High-Res. Fix + +Now if you turn on High-Res Fix in A1111, each controlnet will output two different control images: a small one and a large one. The small one is for your basic generating, and the big one is for your High-Res Fix generating. The two control images are computed by a smart algorithm called "super high-quality control image resampling". This is turned on by default, and you do not need to change any setting. + +### Perfect Support for All A1111 Img2Img or Inpaint Settings and All Mask Types + +Now ControlNet is extensively tested with A1111's different types of masks, including "Inpaint masked"/"Inpaint not masked", and "Whole picture"/"Only masked", and "Only masked padding"&"Mask blur". The resizing perfectly matches A1111's "Just resize"/"Crop and resize"/"Resize and fill". This means you can use ControlNet in nearly everywhere in your A1111 UI without difficulty! + +### The New "Pixel-Perfect" Mode + +Now if you turn on pixel-perfect mode, you do not need to set preprocessor (annotator) resolutions manually. The ControlNet will automatically compute the best annotator resolution for you so that each pixel perfectly matches Stable Diffusion. + +### User-Friendly GUI and Preprocessor Preview + +We reorganized some previously confusing UI like "canvas width/height for new canvas" and it is in the 📝 button now. Now the preview GUI is controlled by the "allow preview" option and the trigger button 💥. The preview image size is better than before, and you do not need to scroll up and down - your a1111 GUI will not be messed up anymore! + +### Support for Almost All Upscaling Scripts + +Now ControlNet 1.1 can support almost all Upscaling/Tile methods. ControlNet 1.1 support the script "Ultimate SD upscale" and almost all other tile-based extensions. Please do not confuse ["Ultimate SD upscale"](https://github.com/Coyote-A/ultimate-upscale-for-automatic1111) with "SD upscale" - they are different scripts. Note that the most recommended upscaling method is ["Tiled VAE/Diffusion"](https://github.com/pkuliyi2015/multidiffusion-upscaler-for-automatic1111) but we test as many methods/extensions as possible. Note that "SD upscale" is supported since 1.1.117, and if you use it, you need to leave all ControlNet images as blank (We do not recommend "SD upscale" since it is somewhat buggy and cannot be maintained - use the "Ultimate SD upscale" instead). + +### More Control Modes (previously called Guess Mode) + +We have fixed many bugs in previous 1.0’s Guess Mode and now it is called Control Mode + +![image](https://user-images.githubusercontent.com/19834515/236641759-6c44ddf6-c7ad-4bda-92be-e90a52911d75.png) + +Now you can control which aspect is more important (your prompt or your ControlNet): + +* "Balanced": ControlNet on both sides of CFG scale, same as turning off "Guess Mode" in ControlNet 1.0 + +* "My prompt is more important": ControlNet on both sides of CFG scale, with progressively reduced SD U-Net injections (layer_weight*=0.825**I, where 0<=I <13, and the 13 means ControlNet injected SD 13 times). In this way, you can make sure that your prompts are perfectly displayed in your generated images. + +* "ControlNet is more important": ControlNet only on the Conditional Side of CFG scale (the cond in A1111's batch-cond-uncond). This means the ControlNet will be X times stronger if your cfg-scale is X. For example, if your cfg-scale is 7, then ControlNet is 7 times stronger. Note that here the X times stronger is different from "Control Weights" since your weights are not modified. This "stronger" effect usually has less artifact and give ControlNet more room to guess what is missing from your prompts (and in the previous 1.0, it is called "Guess Mode"). + + + + + + + + + + + + + + +
Input (depth+canny+hed)"Balanced""My prompt is more important""ControlNet is more important"
+ +### Reference-Only Control + +Now we have a `reference-only` preprocessor that does not require any control models. It can guide the diffusion directly using images as references. + +(Prompt "a dog running on grassland, best quality, ...") + +![image](samples/ref.png) + +This method is similar to inpaint-based reference but it does not make your image disordered. + +Many professional A1111 users know a trick to diffuse image with references by inpaint. For example, if you have a 512x512 image of a dog, and want to generate another 512x512 image with the same dog, some users will connect the 512x512 dog image and a 512x512 blank image into a 1024x512 image, send to inpaint, and mask out the blank 512x512 part to diffuse a dog with similar appearance. However, that method is usually not very satisfying since images are connected and many distortions will appear. + +This `reference-only` ControlNet can directly link the attention layers of your SD to any independent images, so that your SD will read arbitrary images for reference. You need at least ControlNet 1.1.153 to use it. + +To use, just select `reference-only` as preprocessor and put an image. Your SD will just use the image as reference. + +*Note that this method is as "non-opinioned" as possible. It only contains very basic connection codes, without any personal preferences, to connect the attention layers with your reference images. However, even if we tried best to not include any opinioned codes, we still need to write some subjective implementations to deal with weighting, cfg-scale, etc - tech report is on the way.* + +More examples [here](https://github.com/Mikubill/sd-webui-controlnet/discussions/1236). + +# Technical Documents + +See also the documents of ControlNet 1.1: + +https://github.com/lllyasviel/ControlNet-v1-1-nightly#model-specification + +# Default Setting + +This is my setting. If you run into any problem, you can use this setting as a sanity check + +![image](https://user-images.githubusercontent.com/19834515/235620638-17937171-8ac1-45bc-a3cb-3aebf605b4ef.png) + +# Use Previous Models + +### Use ControlNet 1.0 Models + +https://huggingface.co/lllyasviel/ControlNet/tree/main/models + +You can still use all previous models in the previous ControlNet 1.0. Now, the previous "depth" is now called "depth_midas", the previous "normal" is called "normal_midas", the previous "hed" is called "softedge_hed". And starting from 1.1, all line maps, edge maps, lineart maps, boundary maps will have black background and white lines. + +### Use T2I-Adapter Models + +(From TencentARC/T2I-Adapter) + +To use T2I-Adapter models: + +1. Download files from https://huggingface.co/TencentARC/T2I-Adapter/tree/main/models +2. Put them in "stable-diffusion-webui\extensions\sd-webui-controlnet\models". +3. Make sure that the file names of pth files and yaml files are consistent. + +*Note that "CoAdapter" is not implemented yet.* + +# Gallery + +The below results are from ControlNet 1.0. + +| Source | Input | Output | +|:-------------------------:|:-------------------------:|:-------------------------:| +| (no preprocessor) | | | +| (no preprocessor) | | | +| | | | +| | | | +| | | | +| | | | + +The below examples are from T2I-Adapter. + +From `t2iadapter_color_sd14v1.pth` : + +| Source | Input | Output | +|:-------------------------:|:-------------------------:|:-------------------------:| +| | | | + +From `t2iadapter_style_sd14v1.pth` : + +| Source | Input | Output | +|:-------------------------:|:-------------------------:|:-------------------------:| +| | (clip, non-image) | | + +# Minimum Requirements + +* (Windows) (NVIDIA: Ampere) 4gb - with `--xformers` enabled, and `Low VRAM` mode ticked in the UI, goes up to 768x832 + +# Multi-ControlNet + +This option allows multiple ControlNet inputs for a single generation. To enable this option, change `Multi ControlNet: Max models amount (requires restart)` in the settings. Note that you will need to restart the WebUI for changes to take effect. + + + + + + + + + + + + +
Source ASource BOutput
+ +# Control Weight/Start/End + +Weight is the weight of the controlnet "influence". It's analogous to prompt attention/emphasis. E.g. (myprompt: 1.2). Technically, it's the factor by which to multiply the ControlNet outputs before merging them with original SD Unet. + +Guidance Start/End is the percentage of total steps the controlnet applies (guidance strength = guidance end). It's analogous to prompt editing/shifting. E.g. \[myprompt::0.8\] (It applies from the beginning until 80% of total steps) + +# Batch Mode + +Put any unit into batch mode to activate batch mode for all units. Specify a batch directory for each unit, or use the new textbox in the img2img batch tab as a fallback. Although the textbox is located in the img2img batch tab, you can use it to generate images in the txt2img tab as well. + +Note that this feature is only available in the gradio user interface. Call the APIs as many times as you want for custom batch scheduling. + +# API and Script Access + +This extension can accept txt2img or img2img tasks via API or external extension call. Note that you may need to enable `Allow other scripts to control this extension` in settings for external calls. + +To use the API: start WebUI with argument `--api` and go to `http://webui-address/docs` for documents or checkout [examples](https://github.com/Mikubill/sd-webui-controlnet/blob/main/example/txt2img_example/api_txt2img.py). + +To use external call: Checkout [Wiki](https://github.com/Mikubill/sd-webui-controlnet/wiki/API) + +# Command Line Arguments + +This extension adds these command line arguments to the webui: + +``` + --controlnet-dir ADD a controlnet models directory + --controlnet-annotator-models-path SET the directory for annotator models + --no-half-controlnet load controlnet models in full precision + --controlnet-preprocessor-cache-size Cache size for controlnet preprocessor results + --controlnet-loglevel Log level for the controlnet extension + --controlnet-tracemalloc Enable malloc memory tracing +``` + +# MacOS Support + +Tested with pytorch nightly: https://github.com/Mikubill/sd-webui-controlnet/pull/143#issuecomment-1435058285 + +To use this extension with mps and normal pytorch, currently you may need to start WebUI with `--no-half`. + +# Archive of Deprecated Versions + +The previous version (sd-webui-controlnet 1.0) is archived in + +https://github.com/lllyasviel/webui-controlnet-v1-archived + +Using this version is not a temporary stop of updates. You will stop all updates forever. + +Please consider this version if you work with professional studios that requires 100% reproducing of all previous results pixel by pixel. + +# Thanks + +This implementation is inspired by kohya-ss/sd-webui-additional-networks diff --git a/extensions-builtin/sd_forge_controlnet/annotator/anime_face_segment/LICENSE b/extensions-builtin/sd_forge_controlnet/annotator/anime_face_segment/LICENSE new file mode 100644 index 00000000..9bad0545 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/anime_face_segment/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Miaomiao Li + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/extensions-builtin/sd_forge_controlnet/annotator/anime_face_segment/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/anime_face_segment/__init__.py new file mode 100644 index 00000000..466feca1 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/anime_face_segment/__init__.py @@ -0,0 +1,172 @@ +import os +import torch +import torch.nn as nn +import torch.nn.functional as F +from PIL import Image +import fnmatch +import cv2 + +import sys + +import numpy as np +from modules import devices +from einops import rearrange +from annotator.annotator_path import models_path + +import torchvision +from torchvision.models import MobileNet_V2_Weights +from torchvision import transforms + +COLOR_BACKGROUND = (255,255,0) +COLOR_HAIR = (0,0,255) +COLOR_EYE = (255,0,0) +COLOR_MOUTH = (255,255,255) +COLOR_FACE = (0,255,0) +COLOR_SKIN = (0,255,255) +COLOR_CLOTHES = (255,0,255) +PALETTE = [COLOR_BACKGROUND,COLOR_HAIR,COLOR_EYE,COLOR_MOUTH,COLOR_FACE,COLOR_SKIN,COLOR_CLOTHES] + +class UNet(nn.Module): + def __init__(self): + super(UNet, self).__init__() + self.NUM_SEG_CLASSES = 7 # Background, hair, face, eye, mouth, skin, clothes + + mobilenet_v2 = torchvision.models.mobilenet_v2(weights=MobileNet_V2_Weights.IMAGENET1K_V1) + mob_blocks = mobilenet_v2.features + + # Encoder + self.en_block0 = nn.Sequential( # in_ch=3 out_ch=16 + mob_blocks[0], + mob_blocks[1] + ) + self.en_block1 = nn.Sequential( # in_ch=16 out_ch=24 + mob_blocks[2], + mob_blocks[3], + ) + self.en_block2 = nn.Sequential( # in_ch=24 out_ch=32 + mob_blocks[4], + mob_blocks[5], + mob_blocks[6], + ) + self.en_block3 = nn.Sequential( # in_ch=32 out_ch=96 + mob_blocks[7], + mob_blocks[8], + mob_blocks[9], + mob_blocks[10], + mob_blocks[11], + mob_blocks[12], + mob_blocks[13], + ) + self.en_block4 = nn.Sequential( # in_ch=96 out_ch=160 + mob_blocks[14], + mob_blocks[15], + mob_blocks[16], + ) + + # Decoder + self.de_block4 = nn.Sequential( # in_ch=160 out_ch=96 + nn.UpsamplingNearest2d(scale_factor=2), + nn.Conv2d(160, 96, kernel_size=3, padding=1), + nn.InstanceNorm2d(96), + nn.LeakyReLU(0.1), + nn.Dropout(p=0.2) + ) + self.de_block3 = nn.Sequential( # in_ch=96x2 out_ch=32 + nn.UpsamplingNearest2d(scale_factor=2), + nn.Conv2d(96*2, 32, kernel_size=3, padding=1), + nn.InstanceNorm2d(32), + nn.LeakyReLU(0.1), + nn.Dropout(p=0.2) + ) + self.de_block2 = nn.Sequential( # in_ch=32x2 out_ch=24 + nn.UpsamplingNearest2d(scale_factor=2), + nn.Conv2d(32*2, 24, kernel_size=3, padding=1), + nn.InstanceNorm2d(24), + nn.LeakyReLU(0.1), + nn.Dropout(p=0.2) + ) + self.de_block1 = nn.Sequential( # in_ch=24x2 out_ch=16 + nn.UpsamplingNearest2d(scale_factor=2), + nn.Conv2d(24*2, 16, kernel_size=3, padding=1), + nn.InstanceNorm2d(16), + nn.LeakyReLU(0.1), + nn.Dropout(p=0.2) + ) + + self.de_block0 = nn.Sequential( # in_ch=16x2 out_ch=7 + nn.UpsamplingNearest2d(scale_factor=2), + nn.Conv2d(16*2, self.NUM_SEG_CLASSES, kernel_size=3, padding=1), + nn.Softmax2d() + ) + + def forward(self, x): + e0 = self.en_block0(x) + e1 = self.en_block1(e0) + e2 = self.en_block2(e1) + e3 = self.en_block3(e2) + e4 = self.en_block4(e3) + + d4 = self.de_block4(e4) + d4 = F.interpolate(d4, size=e3.size()[2:], mode='bilinear', align_corners=True) + c4 = torch.cat((d4,e3),1) + + d3 = self.de_block3(c4) + d3 = F.interpolate(d3, size=e2.size()[2:], mode='bilinear', align_corners=True) + c3 = torch.cat((d3,e2),1) + + d2 = self.de_block2(c3) + d2 = F.interpolate(d2, size=e1.size()[2:], mode='bilinear', align_corners=True) + c2 =torch.cat((d2,e1),1) + + d1 = self.de_block1(c2) + d1 = F.interpolate(d1, size=e0.size()[2:], mode='bilinear', align_corners=True) + c1 = torch.cat((d1,e0),1) + y = self.de_block0(c1) + + return y + + +class AnimeFaceSegment: + + model_dir = os.path.join(models_path, "anime_face_segment") + + def __init__(self): + self.model = None + self.device = devices.get_device_for("controlnet") + + def load_model(self): + remote_model_path = "https://huggingface.co/bdsqlsz/qinglong_controlnet-lllite/resolve/main/Annotators/UNet.pth" + modelpath = os.path.join(self.model_dir, "UNet.pth") + if not os.path.exists(modelpath): + from basicsr.utils.download_util import load_file_from_url + load_file_from_url(remote_model_path, model_dir=self.model_dir) + net = UNet() + ckpt = torch.load(modelpath, map_location=self.device) + for key in list(ckpt.keys()): + if 'module.' in key: + ckpt[key.replace('module.', '')] = ckpt[key] + del ckpt[key] + net.load_state_dict(ckpt) + net.eval() + self.model = net.to(self.device) + + def unload_model(self): + if self.model is not None: + self.model.cpu() + + def __call__(self, input_image): + + if self.model is None: + self.load_model() + self.model.to(self.device) + transform = transforms.Compose([ + transforms.Resize(512,interpolation=transforms.InterpolationMode.BICUBIC), + transforms.ToTensor(),]) + img = Image.fromarray(input_image) + with torch.no_grad(): + img = transform(img).unsqueeze(dim=0).to(self.device) + seg = self.model(img).squeeze(dim=0) + seg = seg.cpu().detach().numpy() + img = rearrange(seg,'h w c -> w c h') + img = [[PALETTE[np.argmax(val)] for val in buf]for buf in img] + return np.array(img).astype(np.uint8) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/annotator_path.py b/extensions-builtin/sd_forge_controlnet/annotator/annotator_path.py new file mode 100644 index 00000000..ba168e19 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/annotator_path.py @@ -0,0 +1,22 @@ +import os +from modules import shared + +models_path = shared.opts.data.get('control_net_modules_path', None) +if not models_path: + models_path = getattr(shared.cmd_opts, 'controlnet_annotator_models_path', None) +if not models_path: + models_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'downloads') + +if not os.path.isabs(models_path): + models_path = os.path.join(shared.data_path, models_path) + +clip_vision_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'clip_vision') +# clip vision is always inside controlnet "extensions\sd-webui-controlnet" +# and any problem can be solved by removing controlnet and reinstall + +models_path = os.path.realpath(models_path) +os.makedirs(models_path, exist_ok=True) +print(f'ControlNet preprocessor location: {models_path}') +# Make sure that the default location is inside controlnet "extensions\sd-webui-controlnet" +# so that any problem can be solved by removing controlnet and reinstall +# if users do not change configs on their own (otherwise users will know what is wrong) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/binary/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/binary/__init__.py new file mode 100644 index 00000000..2d13ad69 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/binary/__init__.py @@ -0,0 +1,14 @@ +import cv2 + + +def apply_binary(img, bin_threshold): + img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) + + if bin_threshold == 0 or bin_threshold == 255: + # Otsu's threshold + otsu_threshold, img_bin = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) + print("Otsu threshold:", otsu_threshold) + else: + _, img_bin = cv2.threshold(img_gray, bin_threshold, 255, cv2.THRESH_BINARY_INV) + + return cv2.cvtColor(img_bin, cv2.COLOR_GRAY2RGB) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/canny/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/canny/__init__.py new file mode 100644 index 00000000..ace98583 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/canny/__init__.py @@ -0,0 +1,5 @@ +import cv2 + + +def apply_canny(img, low_threshold, high_threshold): + return cv2.Canny(img, low_threshold, high_threshold) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/clipvision/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/clipvision/__init__.py new file mode 100644 index 00000000..0a9b1cea --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/clipvision/__init__.py @@ -0,0 +1,133 @@ +import os +import cv2 +import torch + +from modules import devices +from modules.modelloader import load_file_from_url +from annotator.annotator_path import models_path +from transformers import CLIPVisionModelWithProjection, CLIPVisionConfig, CLIPImageProcessor + + +config_clip_g = { + "attention_dropout": 0.0, + "dropout": 0.0, + "hidden_act": "gelu", + "hidden_size": 1664, + "image_size": 224, + "initializer_factor": 1.0, + "initializer_range": 0.02, + "intermediate_size": 8192, + "layer_norm_eps": 1e-05, + "model_type": "clip_vision_model", + "num_attention_heads": 16, + "num_channels": 3, + "num_hidden_layers": 48, + "patch_size": 14, + "projection_dim": 1280, + "torch_dtype": "float32" +} + +config_clip_h = { + "attention_dropout": 0.0, + "dropout": 0.0, + "hidden_act": "gelu", + "hidden_size": 1280, + "image_size": 224, + "initializer_factor": 1.0, + "initializer_range": 0.02, + "intermediate_size": 5120, + "layer_norm_eps": 1e-05, + "model_type": "clip_vision_model", + "num_attention_heads": 16, + "num_channels": 3, + "num_hidden_layers": 32, + "patch_size": 14, + "projection_dim": 1024, + "torch_dtype": "float32" +} + +config_clip_vitl = { + "attention_dropout": 0.0, + "dropout": 0.0, + "hidden_act": "quick_gelu", + "hidden_size": 1024, + "image_size": 224, + "initializer_factor": 1.0, + "initializer_range": 0.02, + "intermediate_size": 4096, + "layer_norm_eps": 1e-05, + "model_type": "clip_vision_model", + "num_attention_heads": 16, + "num_channels": 3, + "num_hidden_layers": 24, + "patch_size": 14, + "projection_dim": 768, + "torch_dtype": "float32" +} + +configs = { + 'clip_g': config_clip_g, + 'clip_h': config_clip_h, + 'clip_vitl': config_clip_vitl, +} + +downloads = { + 'clip_vitl': 'https://huggingface.co/openai/clip-vit-large-patch14/resolve/main/pytorch_model.bin', + 'clip_g': 'https://huggingface.co/lllyasviel/Annotators/resolve/main/clip_g.pth', + 'clip_h': 'https://huggingface.co/h94/IP-Adapter/resolve/main/models/image_encoder/pytorch_model.bin' +} + + +clip_vision_h_uc = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'clip_vision_h_uc.data') +clip_vision_h_uc = torch.load(clip_vision_h_uc, map_location=torch.device('cuda' if torch.cuda.is_available() else 'cpu'))['uc'] + +clip_vision_vith_uc = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'clip_vision_vith_uc.data') +clip_vision_vith_uc = torch.load(clip_vision_vith_uc, map_location=torch.device('cuda' if torch.cuda.is_available() else 'cpu'))['uc'] + + +class ClipVisionDetector: + def __init__(self, config, low_vram: bool): + assert config in downloads + self.download_link = downloads[config] + self.model_path = os.path.join(models_path, 'clip_vision') + self.file_name = config + '.pth' + self.config = configs[config] + self.device = ( + torch.device("cpu") if low_vram else + devices.get_device_for("controlnet") + ) + os.makedirs(self.model_path, exist_ok=True) + file_path = os.path.join(self.model_path, self.file_name) + if not os.path.exists(file_path): + load_file_from_url(url=self.download_link, model_dir=self.model_path, file_name=self.file_name) + config = CLIPVisionConfig(**self.config) + + self.model = CLIPVisionModelWithProjection(config) + self.processor = CLIPImageProcessor(crop_size=224, + do_center_crop=True, + do_convert_rgb=True, + do_normalize=True, + do_resize=True, + image_mean=[0.48145466, 0.4578275, 0.40821073], + image_std=[0.26862954, 0.26130258, 0.27577711], + resample=3, + size=224) + sd = torch.load(file_path, map_location=self.device) + self.model.load_state_dict(sd, strict=False) + del sd + self.model.to(self.device) + self.model.eval() + + def unload_model(self): + if self.model is not None: + self.model.to('meta') + + def __call__(self, input_image): + with torch.no_grad(): + input_image = cv2.resize(input_image, (224, 224), interpolation=cv2.INTER_AREA) + feat = self.processor(images=input_image, return_tensors="pt") + feat['pixel_values'] = feat['pixel_values'].to(self.device) + result = self.model(**feat, output_hidden_states=True) + result['hidden_states'] = [v.to(self.device) for v in result['hidden_states']] + result = {k: v.to(self.device) if isinstance(v, torch.Tensor) else v for k, v in result.items()} + return result diff --git a/extensions-builtin/sd_forge_controlnet/annotator/clipvision/clip_vision_h_uc.data b/extensions-builtin/sd_forge_controlnet/annotator/clipvision/clip_vision_h_uc.data new file mode 100644 index 0000000000000000000000000000000000000000..70c4a7bc9aeef7445c3974e2618c4a78745d3c9d GIT binary patch literal 658694 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 i|51Oz?i^MoJ! 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

)j|=WD-7Z%gHbSJEr_AblHGmdzFBgxk@j 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

FlY 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%0DsZIY!~7!X~K%Tb#^)viU#3 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 z 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%0A|F7fvQOLDQFPf3 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

Rp5@H-63rPkl?5M!`%e$q5M^(XmdeOwiW zW|vmGE5kKAE-6r%tM7^P*A;VW?H%bOf752qV_m&Nekhx1rnkn;8dzEqK*B_d-#M6ZDSLGYoS|B_wYx z;8qDgjM$9w=+*E(m<;?*#~}F*HokA6GJ8#P8hQJbp5HLNQa82*-V-YJ31gLJ9|0%h zRiOII(ra?Kp_vLeiR#UI!YdU&>FNQaLbj(RL|l@xzfarcd)=DcitVn^s?da)fpv9D z-kT*9%k-#H(Dv>L3yRd5v$kw7>_9~)zV|gDP0ltw5sG5kHk8G767T3$bJ&jBjYjhOVX_haPixS{t7!8AbP@HJL;7 zHp~Zm_Z;ZTn{25kI=$3X%^VjXT8-z7IcegUdyxVmi-~GyK2PeD1`xu zANiQ=scEboc{_|N(-Q{a8U20T)~(f&*M;PXT2=}bnNdP)seRanvOg#sK}TH5+5oma zV}p2h2=0t6&`qN1gGzI1XnyDv32g-H#iM^)XUZ}rAh7cV2OrK9NTex}1o_U;pxTv~ zX(8oN!&8{yIEjfMJi~qmU5FN78#~D)GkTJfcVsIjoh@Klp>+JY=>mQIiTugyzepYn zs<_;hEUia!wufxF1Pop*xcCiItw+o-b+Diucv{aFop7yiP9muS*#3sAv+}tUrWRLK zAAk{dy2wvKhx{>Uybybd3I$l92n!*_v)aQ5j)LZ%pd)o0NOTnIs7u;1NYaBBmOJdK z`Vm#pdZ6@X(@6o;#>#3U3=pkKg8+k^P>^)42!%xE3t5e{=DJfYIvgR7C*=k8a=fzL zcgq6RkFh>DO_S5evFG@jXM1Q>hh=MV>$=(bg8^F7wL|fDl3syShE8~4EP(1~h)*{nIa?-oZ!oLHcn;dteez#>mamw2iVcu7F zjYA^L{wD@`Ta@pRO?yBLXJJWK=I01jLRr5TZu^{2pVJ?t!8%7@h$cRT{U zam{L;$u823CJ}1q*%hLHB0J*`;pOFcq8pZ5Q3zc7oC*Y2A0r%tDk{WrrxRi z&)MkK>H3(B$FGt*Dg46TK0GyV(D9AsvRgk^UhLcgIR}F{Lk3FG`MY2`&kxm}O8>H3 zJIpkfhs)GKf~70v_^Ruyt-4Hy8Urj)F|lEYJa2jC5K*_95M4H3CP-hGthQt{juU?X z(!2chu1bA+xL~47%9E&A}X7G(Zc`0J100`ih;joyJdE%as0)*NPP5(T>q z_>iQ>M(S{?@%lu{Gk`qR7S@VeNbz#{R}R63Pg(n*ke9xhP3gIOc7q8RZnJ(V0H$}z4Zph8FW zUu$-B8{~YkC%9OSnHQq-z=RQq%lTvD5rOU7Yx z#CK3))3?_+c_2jwqb(@1cMhu?>g14`-MVj>&C9{63f_fp89i{(X;+;j7H=uZMSV*2 ziR759OctG4pouip8BeQGNzUgHlfcs{qq>xBB*HrJ-hD4`yA(Bb_C8m)^Qp>;p=xhv zOf|{!$@E9zzh36vp7NxMI+JVcHBiXXkvu1+$lk7v4Z=GgLTs+5D$6Sno_zrAcMFUR zHy5p|4_QKe%(9M?`}jfpVSs2MtswMma<<*6?UauFj~bH&y{&FcM%|=2sUDLzGmLqnMtVw3Dq0=gsb&`o>=(y=xewJ;4od-D85QjI-U$sgp;F!WO7vF_0is9k_CfWyU{x{UW?r(Kx6l(&`Fu13Va5S?!}g6-j8YeAAsE znskD(i32vmENDX~_Zmr^84-<2WS8fPy^?GBP@GnfG; zfeSjNQqGiRo}Rzg_(N~|bWxAd=)gn*qBuxlf5Y^eRgm#DY_jZjGwf{CYR3|=k( zg7yqSxr>8txlLn}VYRoQ!5ah4GyMiWne-x&*Kl&Vgw{J@Sn`@HfXdZDuEhM@35~^m zy-Ga|J!wd8+e;jw-$yO*4er|Ypt#9hO-|&9QgJH2JrLk_!v{@yovOf=}!c8j=$zU`%fffS9ijzJq+BEVX zc?uU5gEtl_`*9cv&n>D|P^|2vNC+P@ppg`DyugdhAv#hAu=_FVnB5p#hlNpjJ&J@> zmWG{i)56hm_8=?(@4{)cp{8sfDly%u2 z5&ByaK#j5YJR^=%2+GxX?{H2~uvL0vtt*t&r%?}jfp@$0J4jHM*){Kay*FEmm=h+m zLh>sii(~c8*Pp(ALeT+G*Knqsz%v-p*CZb{nCfhkoU@Y0VSu(#_7!3qKCj&5^}kp& z9FNpd4nw>6YqHZ5GO2ODAh#?tH4_Ita_&~5lD{2^{E#MG7Gj9M{w0*d)?@UMha9S? zN(%xDRcq7$Eq@>WJ_(T?5*IAtLN~i+?-b!@cOoZ-c$V8^0*2ABlT9G64U&sM^=|bf-TUj~5;%M`(7aB12 zaiP*=!WOjQzNkGP(0mU!6zY1&Z37HSAld3B4X{pKTW}%zTG2W3iqXw7@eAZZ5+48h zPbyi7dRCTJc~dcQd2gn04-Ewt*C>&L>JQkOkgDb-Z=2r&`3&&*ZooAqwF3W|K59}D zQ>D31)!n=F1I-)SINrdcxK6A`w7Y{B!)vHjjTn{!>KExU zU%D(_y(PbhHECN>gqi*p=+ zBWZa)vzJOv!J9=%@3O|_#GcYN#*Q)z{TI&(WO=S>QUV!5Z$JPYrA*JzWRK=uMFEzT zPYd3xa@`9hJ$Dwx)9JNxoWy3iUmj%;Dfv+Vf~`wKwB5xDT0 zr!;^K2x93QkOo2z6!!=}NqZVYClN+R377~ZwRroQ=A9@FG6ue& zx>7aC`l1B{9Kwm{kEXE>cI;%EzP_G{CqmNTi<-9ahi`v*``FQV{&P70CheouD%W8_ zNK{ceB}K%Si)6ke3~brOsM5S^@+g3E4Pk*g6kl3v80gF@#Z9ZJD1eVepEPWkD*D6X_+3 z48$&UDk7&-2J1C5al9#b%sWCYTwaZ91QW|reM<@eDhld&M@WSy$4r~|)>^!U+&A0O zDn+zZ4eb#X5l0?*^w7pf?35A*Z@zRQV3b?rv*EMw_6brSuynxX9}X4UaO*(;hdBPm z-XjqiJ;d~Rs~We%zIrSntWkTrRY^}XnF&xz!9xDMoJZ-G#E|wu{i>rpMRKXMtYeEB z@V<<$1TFi!WNV6oQ39Qlll$6pFnKo6(5M{`ti#T*^H5tAJNO`909~J^hScFqw6ZEV zxVhn?oMC$=*cYHIqz9y496GQ}TtJ%4>okVI(BHiNYr3v*wV@Zx(D>yKIr%X{!Z4su zYv4(C-#EHF6YN-&fGTBK6BuD-UB>iM8^|(KiSx<^eBn(hZC}$Ca_Ew4Af}@W+b1<1 z$1_(@2UZu4S+pPUcyPwmrv^bW$kwti>dN+VvY3JoJ&Y%|_$)Olb0UbnFoD%}`|04m zcC`_*Z$w3_T#>a|A(BM*i<-6sYQvH)0B+^5#8hf{U=0l^5^p^wNm4|Gr!ZJ6d;wzB zvM55zsSEat^yJ5o3BAgQBP{{;W(gSTxKLQezO>9TTU^SM>;VUT!WMO_Idp_Hi8H*_ zm&953Hb4I;B$7a~n1GImwczfk*v1{}iO=?m9Ks^E*UvY(UL#Bb;W$9$bm-Uzme1Ui zfVtMFdwA&>ysAqN-R{Mls=GCha z8D)(pjZcA59&FufObTx~!_uCuAIXk~*JQ4CDqQo4I_4 z)~)D!GzMW(h=d{}0>H)@YYZMlx_VIRqO)^xz7BMx==VyiX~RC;{JlH{Lx90wES8Rv zSAFpUlaI7>&Kx46rT)}hDqerb2&)t;BUT|UOoPQ2Xzc)x#gxvd;^0Sis&fQEfC$vCPpq2y1Ym?Mhy4W1m}S5fmD&@r zq|$~fzi5jmAU?z(d!mb1r;5mFZvHY2>UD6VE$>w&)LI9FH;Rs+>m=`nSlGw`^{Nz8 zj=ar5IU~uNZjp**?@rag&gM$0DBu1P_(LiPz6gI~H*xe?&}==+P|R>IOzTCv{r9dm zlefe2UHH+t4d!Zjhr)voP{?bz3P5hylYKCwYMnMvkYZ6!05%AKt@lQ26Sl&BU_a}M z@N~Hn=wGS{@`Eo(cB53(wo+R4;6|9{viykyMDnt%}^P~aN?k{UY3(urAA$jbM7-z0VrnEW0TZ>M9w<9 z2KgVt>o4qCht}{2Kuq44K1n!Mc|VITA*P?CJWoHgz?M<_NSAi)GQoYKi{b)gqG6JBt0iIlF@-1G|I zu!X=nngU6@qcABNXot0FVQ0OB@9Dy0nN^mnLnxYjI;R6*7;NT9Q6BIYc;7Xi?2&ECSG|6AMizlYZ^;3wUoUz!G`DO z%6=%B%NiY(F1Pb4Bsq2syZn!CaoeKfTg#lG`bpyXBUdYB;kXGuOUtCrAR-Xvg3R#fvI4SOw0OQGehVUDte0xa8Z6xubVbqzU zsl;dbiyfu!uCYTEgl$DTefXA-Vn{v6@`ifhsH_Z02VPfS2hwoTaA!*016J^cN84KML|I>fLR1p3=t`1D$zBcspg>NH(m05FK{iz%1knL1Yf~ z_whiAlx4Fk)$v`3H-;Sci#$7Ugt8s2>96! z8Y>h(MmXQMh>m~>u*w%1e$mXEU87h^adsnByA-f;jD+643a_6ggJ#$(+JOQPDxXR( z1+BeA2@wOK4BOnV@cR28X|2Fx6%bJ)k$7_ncMNT;i5u0Z zgndecCi%Xrll~^?i(^PkD|=}DvYjQNe^yDL%Q4y6*+{X6y?m#5ZW-1K2E!C`?p&PP zCHT+p?azEaHesui)8&}SFFKdu+a9~{0n4ay@`?$eLF>*M6SbmFY3;5l;z|@oe}yCi zh&5UH*dWUFGXy$Lur)Xo03wN&{{?E-k_^jw{6YBozZxy}013q&nsPXEz5*KA%CJ?C zU?NpdpNL^$RNN^^&v7(ei}OPZga~Y~_w| z4ViJ42mJdg?`$CpT)FdZ(MRBk-=WRVo7E##H)!J;7WM9@0bgObpP!Sw_+%;QmbABA zcs>t-mM$MSDs)HYz)khbE+87wR}SUN@{ax%Uem_d$6BREY~@y2y=8%E4t4mX=2YOt zEX#Rgtpo~%=LNXSiH|*GRUR-QFrO(cC4H!&!l(qVX-11ZV?U=`31>}*>_34-n?5Cm z)k-dTFBIS_7Ufp6KPsii8FZmH`ukumYS<(3#%PPq$g($1THPOxfgfQa~DlSZz3+S@P<=fe;_($@u7Ud9*6$NmYc&pinO$g&Gdo_lqU2?~5mGw#T$P-bT zm~F+2>Mt$w1Owj-$e9G2>$}+;v=q70)Hi^c)Ltlx=PhmJN&a^n+bV) z1w-=w@SUt}BcDoX7H$F+=?l@EmvadD!XqKz0a~*gMdC7Y)>J{?Zt<+KoF<2KMl6N2 z;Im5!TB;cO^B=TmS#e|{2~>9{x}VVe2XZC0K%}OWEMkTOV&O&zgT$!TDMjc8F32=w zrQP#1W{!J8NLgevozx_O*SqiP%^^&XzuY`;1FQkHGDZ%!OT>UHcWQru_4Nf5-hLY1 zet7|MdcUlDj|A8~$Q9psg>J2T9*qE!Ow>jKMwHhJGbhZIdvl&nCyv2vXR>p$ZPVt7F13JS>$x2$2YugA#t>M@rpu+5y z^GhPd!c%;PiamrAFmtl(aYW8w+-gcpEPyG6LVMy=m*{%bEunF3#!_A1YUHJV2(QVf zebI>n!B@8al71%uA|qZ15;A)qVRo+~DWO*YA%TcQB3An&ze^;r-$)>^*}X!AFLN6g zG_)D8l|m1UHiD=`Ad4(R_b}Yb1DIGF14i)NX=0%cZ5A>iKcRB zba6mkPfKM9iTl0Qw!Ac(wI3ywunCq@#%+FHgF#%n&~>4O`+3^)6`KF{1Ak3VcJHt2 zrY_srBoPdGr!)fT!K%;|Y~WNB)Mb&1Ts4t7Lm_`_K*QRl7}PSldeT#$+Sf>AkjF@B zv=JqQe(;%0f&&t7eNX_1R~I!T5&^hHy3=LxK&bqu59*K9y?a;mM>T(v^W$`U$W>DI z8Ki@ zB&u2McB}G$tiMn@!w;1QCO?+j$6W{TQXRvJ zg&P7iYC>$}-9ryas#}y+X}j6022$AP>V2*1wG(x!*hfvCWSVa@uIC*64M-jI9P}j+ zvjQbW?RxvPtxXtr0-3ZOXh|h@wQw zl-6Wol~Arip=E~4Pyv`SGbba3`@V_9`K1MF*wtDNh5||tzu~B9pfgX7(CedGKhtY< zIkjC-ILr=$>3WCWs8P-ql7xvVn0&Ci$p}0>0F_zFaM3ral zx2$pew8fr>rl4wy^ewAxpcqs@L=K!W^e;?w%-chHa&4nV!9s0 zWyvZjIUnw_bR|KN6ne+YLBq-0ITFJRiMA0CgjW4V)+1y$a{K$v)|UEsuu&sH=Gjx@ z3Od4z+Kh9O^!2B2e+jRtp`3hH4tb^bx?%V9(6*2L1~eRdV@JqBKoA@T62qWVYpMDr zG<0=?HtT9hmP_U;qPSJLFh1k*AESd`(WN!XJ4ssY86bgI-o^rm=Z4Yt;076chb$X1 z(@2;yYH|YR&%Xi+`hlqv;75c)YcJ_gY|gDd6zgZPa2nkx5hnL3zrnfzmIX(xQfZQfhf^o(} z)+w>0w?%5x?H~vYO$ABmFgUlBgsG?ekyh$2@G=GNzS$wWlHQ_kxejPEYm>r&oBo{` z7pHIj7$xc>!Vc7>b$5wLz#3Lz9ov)ms|g8#jUut>t^!U=GrsN zjwMnfK`+Km?S9G?Tp>@0TIL5aWD?;KUgVgr*n3)1!?6YueYX$`w4!$|f$@rtNhl{Y zhfnI@TC*~CDQslHWc6ukWgV6!fgn{RFMdb9XdJL=YPbSxH3DJ#;09$5V@=`&vf-)9 zjBhnNv`>l#f`YI-*R%=;uuV5hi3x4oZTtsw6*h|~qQ}PHa*{ZmRq6v~K*es&ABi(B z>LhGCXu=+6>aj+=?#``VR@egI=!;gUK6RuNq`IE>`FG(T{}H{q#$iROk#8S6!KRV) z1z8umKiu#G+RB#splU7mt0^g6udd8h@2aK^62|PEroRiRSNoXYoI^7lB)Fbku61;e z=mkI#v)bNKDH{Bc(z<<(tXX~6Y^ZDG!mT^W%If?LlaXgt7eHCN*wT1`D58R9Ot9!0 zT!~&n85JK;JEqrj4O80hk2XxV%M3R(UylQEflr~d(;b<|%%DG_b$ThoVEyl^ItzG2 z6`#h?vW0uNIwz+O@os7nC@5mOtk&s~Y$K!2)&X7(bY2=Etuuf_m&ED}!kx?nP!3FY zxI52|-Ovz~Gch=21R|TkakC+LjUbav>m&#rq(f6}W+TL-z~IGivrzb!Yu)Hr9;!!a zm$g1rgx-O?{(VvU9y7d+Cdf+oO6_~N7di&@rrdDOle!GVXr>8|rIduiC27)Dtu^(m61FJc*QP- zeZpKLy-%vjiYB)@Lf+K%M9+GVYq8+*V62GhAECA300K?ZjqY24q7#zYDRUfx{yFkX zaVbmLr%kfNZ2< z=sea`1Odadr-FE8jbU&-nP~6T3Hp^pXR=_n9Q*x_ho-t?cIzrx;)&{?;f@pDK7RYT zjv{cPc76|#f0vUn?I0}sXIm4fj!>mrIRbdOZ`yLgN?@T?Xa~%Nd!v3y4o>gdjS1Pv zQwwH^EMjlSzb%=Bkz-t}^^XpiO@gp6(*sB$OCC}~RG-%09AcKTQx*y^6bfTVpFA3{ z8?GUfq?l-XZ$Y-byw|$dM$u13OLZ7Q3SjcDr$GL@x8J)XNxCbLwomM&rEWa_%twf% z4%RL83AJB3oNX~w+qZv}eg`mq&Pzi2oQ70>sY3huU8M|#F3JcbKjvAMO zy}TtJH%mJk9mK;MqD!Z!SE)Kw4M!(T-WI;rYCCD?XH=b{sbk>;55rZCEWlW6T4bnU z)aaWtWH{MCzPJLWYiIyxyc*nH-n;-OLgclUVifoK904OVWV;KB{MSM4+|4#b>crREJxKl(%?Rg>gI=E`-5`Oji zm)Ads^h;v6y!{qKu%Cq2KPC$cHZoL1lV|O`FYsr+z!aIwVXl)lig&hqm};i4`CqS} zhqr|GdO@0(+zcJyk!NcswMGE#n8WLl-e0~QzWr@;8phoJnAAKnJeHh(ly$E&AX8DC zRhERVxOdDEsCbiXleN~CB0yF=rOV~;n&ExJp5GNc469A|9$_Olnu>UUpTAjhb=Z3u zCT-&b8}?)@X<{@$n=(P`yM}(~Bn>lTv;5wpW?F{|CdG)rZQd6m$Y$hqR;?(ho5J3FQ8)=B1+) zRnPIq)4&w?mYy}<;x(r>x|iq(aVTHjatr!73r>Qal`9-!QOcZH+GZg$HA2OA%x2TKKY9e{`^b*MZu^!g7t_D@RLri&MwAN}Kym-}G z)P1*eT;!^V3Uk0JW(|8_*x}A&X{o46icbv6sgNA7AgIY*-3sl=ZnnFgk?z<#1Gf>h zRKpKI6{xS#pM#_*22?(u!YrBOHI+oRl`kvX+7P3a@K8)1In-QXzY$hdWN)qI(1xT=IT1FH~bN9H;Tb@BfU%H~Aqwnr6xJjVi4p&z-tYK$y1}%Mcl@OUbF|iyrM~ zW1N!0B07R;G5>p@1xwGN$e}G}xzmu2NksMiS>6n4r}W7&r=fDjL&31MGZjMD$dOcZ zXD$6!SD)(`s15aB5p(8I1gL^IJ$PQC%cI>PNcFN+VF%@XpinVhQ-$EYx4U4i!3?;Tq2>~w8N(Y;wq`zX~`Um>zs<>_$~X5vC2DeLxz zDk*F7HM=Wj!0fxM^RThal(Q>lqUq8xjX!EYft#~n^$I(N(YuN@-I^*);*fA^Eqh9O z|0PID@d)IIZMABLxjusPryGZQHVfP{vuf~53{W#qd#`<`C9YWeyFb#Zg>=Yi?|^AP zEtq#3=)e%=$t3}-1ld6Be4pp{S4fxCK$YH|Xafwt_s}qTlT&mbW|}xiW`wu^<6%zc zT>u`2n0~62%Q3&7g)57RsRTN#J|-<{RQ@BIK9A1okole86O21H2bbXj!s;rtlDfL` zcQU(7KbAyW0UINwIK{U21OO)$g$M$&z2Iq;t8$;HN+oHv-=P?6FrB2jFW+j=pMzYK0cSz@g^TeZ)Yg9Ow8c&Zho@v4+#a5VtDqjE98u=Jg}d~3Vm$k@>C#*u3@e>nvAW=X(1V6 zd)et-xoYo?K9df`I#+a{OKXMH~|2dq0!;`Pv2RlHi&YD%XVW_&xSwovCZRGP@PDX}l z*`+*51-P3FjvEYP?a&@E=VSE`yr#3pfYnuTYX8FhMv_8y=3VlfVvaZ)ON!!U-GFI^ z&=PI4Zgs5=n-bEyxy=S-7}r}!aObLZOI@2?ZA&1)?=otQ(#&Qq!ag@`>RbU0R&qicIH3v|_6RFXT`_*q=x%7JU`o*lKkpL)#Bxiuh+Y_mxU z=!GpfJ>``FUU~c$_rCrpynTjzE#A0bJ5tM_u65%Ce^WI^&j}vcKnAgB!7By8jCK&qYoB7>&UrfN5a2z*S)m0B$a|st9|}H22!?lZlrR*$MS8 zS=(!LjqP0xZ@p4$Iw-f|@=8^$u;gaLK;U7Ic&}x}U>r@h;F_y2W&M;pQPzYUsDVsJ z77R)R>M|T?k8INu%qsZjcF1Kfy+}~$f$(C{`*xf<{t&ROB9j=(@6A3XN0B?=q_L`? z2B}RlD7Fk+%*@=K0`$OfwG$vZf;mQ3U#1h?(}7gwyf~U!PKpy!qiiQnUNB5U!MelQ20M zct)NQ28RG%o!MqUrLfS8pjn;Z+n>?s9Znj*O*`TaR&@;&JjDQ{sx+*wqvoYT@AXkq zvgJj^R;{c}3e)J|@!CUt&}3DX?@LYdnHC8Uvpz(+E{AOVdmZw0ZU#QukfPM`Cn`J| z3>x5f*a|~7X#5L+&mHR{)o_)?oPqIl{BEuxL9YWEF=0#R2{SCYKZ z&he}SWd0k>sjSnYJ@l0+(&C`9>y*{Qp65DY2^^PRKQorWaZwhSf<`1}K#5^gN7#(z z{4;o4cY6hWn38A{!|5pT$%c9uZ+!`^N}NngFS5JA;cAf}J=t18-^`K^xsqkJe>Bfh z&pqeiQ4MZWx_6kJ+20!usGEMU6Bk;lrlsRGD*%%0#D%>&n~4A6KLiuF-=(s-JlErd z9*WHyVKcU#zzlnyteO{1sp>mtif2V(N0{1=4e=^3!Ar01gz*_TwgMB>Q#Z&hWO+1Y z9I$&BmtEFNAt6e>pmnnu~QTkji+LLExOOd;89d2D?` z=-!U?UZUoiNGfmY+Nt>%`d~m~aXngPNaHvBBUS#3?l%TpXQvV+XcMqEDQnjjQN59p zga(UUe!c87Wt)^ZH6~anKT|^fQ9ANTmJc3+jvijHVdh$mcjZ3ySR%t5!-otofA8-5 zxw-pNc|QSawg=#Vu(~9aSV~-|6j>_zXb<^FKxgLUc+zn=)KPgGz8Y1IeLh!~A~c^J zY(O_IjJLn&3LQ%1r6pUKaK0`>yL4JB*+^wp3oig5pbOvkI+JMQMVmG#?w~KkfoBu$ z)KF9<5(5X)5LuPw)BmsI9o17DJJ3nB#oF)ic{m_wH9-=8Jb9U-<%O*JAmgc28D9&G z(-Xo>p8?fB3qG!e)OOauLbTGn%-C?ZV6ux4{EFanPm3JH)(Vj2s21)UbT>ItEH&o& z)cEU9Uw`7}9gwZE(28FgSTjIL~-t1LIs6CRpxu52)_>ExCZOlFsj9|bhSq(sRFc78p%C3NRAnZ@}&JZ zOl~={S31(Y!X`6NitHf)J#C&FJc!K2R2%#`*+PcHsY$&l7;K&7IBb9{8nfQZt`666 zb%rD)>?941+L}_yN20EQw8etuO1oa!g`VBkLEe(m@7*6vw$3_3y4D4dFmsA)yiqW+ z>S~x0ZI8~;D&~u7h#!NY041)b);>+%(6LYBqPsB!7QmWyM;jKe>HhCAgSK%-TAywK|k_*vFH+3DD>_@I@qK zOQenR{|6WwMuiUEa`Oef_FWEw8(iVi`bG+8cL9(UA%sfphi!(fS)BA7A=Q~-w{NO5 zq`LOqDUZ^wkgFya{VsXztqUFfP#5QYVf)=rE39wi z7?7cpnYBV`jtcx6n+Xx0+6}Sie8w;Gd*R>z@U)P^+y773yERFYTxVkM`70cx*@~b< z@Ex)h^*`2Dw77UiMrGVOE}0c66OACaZ!#J8ZMkol3kJXp1~a&0FaXS|YW|nbcl>ega1rAV!BU+Dknr`hD- ze^wg~Yn(oZ=Vx;?n+`TPLzt-kj~Bw(hEU=`+x3T)yE~+X9HMURn>KT7Xn7C7+v7K_BJ=Wl;f@ zS8Q|iel7w`wvWU7GdA)v5atV}Ezm9*J#uOL-OgwQ4;F0k*SJcI|1hYoAZuZ3et>k7 z)Kyk9-r5+R*b1MotT&Pk@~PlV=1~JdVE3=$EEzl7WRDtmHo#b({KAV|i zfI-Kp*OT&FveTy`rOt;T_C>8oEHrOb9$&z~%V5E>4|E6HLARmOKsV-aQd@5Izx$FQ%EJSt#P$y}tZLNR$r|?hzWcNcy zLpwwvo{H%-e%pXcB@sD!nRaI>7jWv8+xBFKY`Dm;bVaglI@41J0l!C|n~JdArcQ@u zxE1O-{js)FKz>gM{#p%u(%3JTlAnfeet>xi8taZtD=AfcNuQf14^z`Da)A1Jq$6HQ zGtPP5{mv#Xx}BdLe6Z5D6>u60^QK3Z{<{OOYh8!?ICq#&oHy8eqGMMkL}Zz5xlHqq zJ>VH*MDT#Dfq)!>WUkJASc)qBM|=^;Ee>I)ln9nf2ELE!eqL~NA*Hx0^)cANYM;8* z%-be#mq7IyatNcZqu!bFv>i|bi(J&X z^?kRPghwCdO*YaPQidpjMmytn(f}SW|7FLTQu9BUuNAh@v=i9#U<2KW;k_6eaANKD z){E@{OfVr^!APO@HsAt=_YH-ABd2xBuwZ#E=l)PwK*1(G@4g2l)tu-ku=L4l8rT_l z4xP@JCoonxH_YUuGQdT4dFx_qSBD0nP?T)tJw+rm1-rN+Jr1UXd?m~d$mc>5<`xDK zXO-n!**{fiHdKh&IaXC%>qz75Gm8`Go6iS-mEVVChZR*qqtTAJH~WnE9+FdcTAy-I z%r-OvFnVP|hcp(&)|vf$B*rZjLKD1gF{bDuc?S@{1Jp2dWRO-i=6+X5XhokzToF3c zt$|Ihq6Hvu&hh*P7_{}a81H z3@vEObLu$`$#knAIiwgj>YkKbAkzeMew{*5a0X4!|7^EsV zA-9TXEL5y9D_OM}{e~TqHBu}1Zc17^;Gg7}FrJ#d2QGKb&vb|sf~hEEqJlV!_dS8@ zv!kM6QZ;U&K0zn++Ol_%)m3_^!JQ$)&6Y$d3m|>>pRFlxg}|Q)xcW1{rdJ!G7%4#z zBX~n>?#K}B)%NU6Bf0uOGhQTHFJEWOh5vB;-cE^m%{kp_{4XRKSNZs`4;WTRMPC(= zDd`s`<=G%G-*?CqkewD?P75697LqwWAA`et9|)9?*IF)FSk++Ebuj7v%H^6~KYsZF z*0B4=!#?S+bECur+JaCbWl)hb%2rU#C+bbe8l_pFWI}|5_{{p{Pr*n?tCZga$biP` zXBK-0>N_NLD1lE1n3r$a?fjbUSKORk;_o7L8%FrBAU|CJ12U#&#mEDl|44xwS>;FE zLK#)x1Cnb}7%BnS?u3f(QTB1`&>6FJ-SuG@TNY3%n3I)GqV~6HyfBA)@~s_eum6sj z*uTI13`A*Q4{TF|)osOq*Dq*DM$6$Ai52@Pd7)y8H|JBpdfhdSl==w?Wp)xZ-?*^@ zaLX2Biv-Oo{tc<)x@9F<2?;wyCDVn1htR^N5+l3YiCh6BAjD16BHRxTPsE0W=2eh(LDwU7wgG-*NerEPa zP+^Cxlvm4M13u5%Dhs9xPOrp?VQcpZ)4yCm0jQQ$v?DshwkLHx{zO8##RsHn5Q|5} zk8WnK3Zb)9n|)T-k?_?jE|7zCQ`kio)-#VUvHC7h5v=D?)nrY+2;I(lA0(-^BOJ}Z zq-`Ug68Hl4{`x z@BvpzAXkdiOhOWgu-xyFLEMV!;u7pRKW*>(LIb7VI$BhUU#WfNAd$WNWVJ7pPf^1o zaj^UV0(@?JcXM>U6di+&%?_{JXQX}iPBZcohrT9 zjoN)VZ`ON}`zt|ubeUYZ5!ojH&*ryeVe*Uj$Bif4?h%QXGDv=g7ijg!Sn zuc={bC-;x=#j>nGxoshmBX#P`3pW&gPOf zqjM}tl_y#dAs-d3#k^7;ck5HgpSgwdNKc*%_o37vupKI zCL*M!)AyI~E3e$oBJcnJH**7?w$q;Usz8&) zJ#>{QWM_vYM^-dXXfQZZLCyQn-%N{EeN?<91Fe0nV3Lu-OInWjh7V@h7PLWf(tDSR zUYjP&OS&3Kz`!!UEa`EC&}*k|xXcCe(w3_$viUr)s{kOoBwi&(FqC&MarKJiv#Qo-NOBQcCH=p(jjAtbSImNyDx1&l{5i>8sU7S& zjcatm2HH!29Y(h;icDRvI+15})hianPR}{Hsl!M3Ozev!G4eS|9vx~P&dsna){?D9 zcNmf*?Uoy4H<-c248sSd2$SLRiSQ(#KMBPF`JzI(wytFuIl^oRqCJCSnkD^|F{kha zpF7vV-hi)Pjnze!Au1RpF{<|%aXfexub;ep0z(u){M79od*8P z3|&YcFt?g8LNw5^LwZ;2{3 zl!Y2W7-qei1HC5IyX}1)&0m}0hxJvpt?Gkq1Q7-DLZx}(nnn-LGK>pbCd>5*M*>6= z)HiA^-5i?Vt2T-grnEL-4_sF9c*_k~&;!YIZhRJg-hkd~Jz?A4ZD`pMh`)~KP8+1u zAG%?52a7~V=v!Kt&2;6a^RVf4L0C5)gciDnNtwu(JC7YyXo1-|OP*z05->EI4XAmd z2>>9TSwSz=?Twh`Y9vB$SG_2k+^H&xgI~3eJ*9dK4hLhFig&0Am z?`k>tvVpSG{Ujt~(p|X);Th*X4A219?OITMSKV+)dy2tB%cCr^bVIv1eTzmPkrjUk z{DxoC?TrO4hpCP#47o?QRBptkL1Vi~I(^#F@;X%gney2H$zmtUFP@S^6@KT`zEIV> zb8$lx4Z2)q=c}$%dCHS^=}ICnAWs%~8sWs5BQ!*4=L9b>+qysx6(D!2->H)WpIT~X z#A_(Zk@}Z%qK_*8Y@l95y9pOcpfuVN|5Xc7G*D)ti07z{;=d(Es^s4@j zq0m*1(a~FLRYG0NsT#M={ma)lhRRXG(%LSrl8rN;3E$>x34Q?>c}o>VxCXjhb)Hhp zz>3*9wjQjsNsxm!LF6>3+)3WJfiz6nW`OpZwm7=^Wd`miu_{rko>6s`Wi@siCNpJv@)y32+{+OWb|dwJl6G*m#vA zhxHP$yrhSyF@Pnl5NQUpD@DW=2E=w?Z6wbbROjUvI#SXxO15$zo}jm$evs@yj_{i; zs!?r)llCzH;^{0>@d!UJA&cVr18u`gk}W3zKyKkNd6&y6qXWx{ANnPC#s}f;ixZM; zt9gbUa!*vuf_AT@3k{WUlD>rdAgE!f(=g9)`8mY`U3d=Zq34A<9+U)nYF%6~sgy_8 z`^1RaHUDII8d*}#V=RX28NuNq^&^9`;(Crd{Tv=?KT(_>a!OQ_km8}jD7rb;ie5(7`+%*5#F3c* z6ZGP$%cfNJ!PxF-@!4ByZ;t5gZ+@8G_`lH-;Q z_>lSQ6%*UWCRQ*>(34O})KV^k2r>xXY2hPRJ& za>TTGJ3~D|b$Byl`??zmI6M^;;);^#anqIXGh>bpOmwR*L`G)+>B}$ES4b{AWHoh# zJBnd0$0Oh>XZ?-GDSC=X-ff<8r`oRa+i3Z_Y<;hkPEvU*HKm}o72M0x3qDCqE#+gb zHqHm@po4sN>zrM5e?5B)RnLg&q~Zgp>;7b~v$}{BTDT7`A>PeTRISvSe;_*b6E*OYJAPOq{+K{=+e1ee(mZUg$wNxOu_V z?7FusH-JZ=l%}KFhEfbqlIfXxKE-6Kg705|2Y(YFt&l8Re9gOI7IGip?b@yE9`Kq8770(J)x7$e$ z3cVygv|xl+m&C)4DBDprRkTWWr%8mg&RU~&l(Q2#KLvHh#6(OB`O~+bLwn=1w?Eh% za+0fM!;bKOZE7BU!#lZrqLXg$T8?xgM3?>(luvsCTCz=jnBVlM;GFY?WtOFK5V+-h z$O140SuPT@Riu(>;imrYQIbK76_G)kQ_%{0Wx`J7F`fyr2xt4p+TxcFP}D#eo2Egv zhvsAl=8^dxaYbJmH_j6^2u90eEQ72Z>to9f$5_X1%cw?Ddmvc`L#vEr`vn}E@0)Wh zaj0YKLAFX8RW8&h7rbS-1^}z2PdNJxO7aJ{8}z`o{&b~)rz+B0c|Sgf@p)tvpQyAe zkxJFIxd~(8?4erWFHN#)PUiqR%O`61*g&ud@uFInXlUNi9k!UR0RRe#vI9CdplgP0 z@o}+4@=2{niDjE49qEY))l>8fIkWAXPZ@0`&%GUFNP*6Q;K-Z=y;is|P@OD-qK2f* zegt{K2tPn>w%*Z@sKCXgo_B{cTkg5lOPc<43iJ2l?97RA?A19^i-TGvg1N6@T{L12 z@+GTtWNB#6Fo}>-0P+BY_y;$#P*qGXnKv1e78p4Skx*F0A}o7Q zMZp7}@R#B3rwljpG{%mSU0b(8Dd2!@Nd`B|MrD@4y%3H$SJ^%j5v~eZlIQiOmtTjY z+zNEs7SCnb1aBq%WSp5s2$wnuP?gzza5Qt+P=OE&s$`MS)U4KkA2Ladk=@?~`GYkT zW*s+KDp6G!@Y@`bhj6^H?;;vuTgJK}I2mjmABgSWqMOr218e;^#s+I-=W zW|wuVRcY4rlp2rA^n_P)&4KaEs1FZ)g=$cu=r~5=Z4^ZH&5jfJ1u5 zn+RcdvEQEJ=uisMO-|XpYfCWaHKIc0=0_=1N&!}dTUty1NBHjF=e_VHPZ_!S9{AA; zJLpS7&CGgcs75)%d}3O9;b`1${9pK>e{4{(cJY!3W`fU2yvl37S>COoB%@iU*j08} z!u$e%Xs>TEw1uWObHpOs#9G9D`TFEQ%8y?@4BxW{bx;Kc)CcMOwI5jLswMI`!t#?MiibX5;#YH;am& z;<5brbo0&|_|X%TV50*FVDG4^xaqRm9CIZ}1U3M4%k9cMKr*}`wZkZ7uOe%z=HQMA z6SnYQg}?uMTcEi&uHl$D_kse4;}OgUW+G`c89+C6w&Utr$PpmrCwhao%;t_D+t(7h z9?tZo$aHVn;#m9RI4BciD0D9Q&1=<>U)!WYr>Qy-^K@%oAolnNnRe?dJqhY zasjGaibpfG<}b%{$J!=xu-4l6tl9M3;K81w&Ju0w6dQ~lQ+oEd1{+efcWU%*y&GHh zk~9_)W3NQcT_rEIgX%0f4K#L0x+p7)@mOdUE)e~kLVuWRrA#nZjWJ)3~4{dft+*&o$bz$o#1j z(%7Q9K-em}X5hBN!QFNSSfZ4g?OQwqcL9T^y$-Q^KLE=(MDJgfPBT0tk6)2q`IYVO ztyjE)fwcPIN^9GUDU9MO0PL1`Q|%0E4uO0xD-%p9hzqh0RUFleCD#4;<%9RqNGW<9 znz^h=OYNXOrz0{Ii;@R+55;3cZ3%&{nc#p@wn8JfS?XDEmg4CSBNFGdyl0CfNxCPb zK&#g5z@l5+0X%X$I%9!mW&IH4QX-AF&{)pdrmuilk7RNPLlycs2izEt{~SBmZT=PS z_pg#T>_Vbdf+nNfqns4#zkDOEi6k?-OGyU~>0rt6Wv>C}fb$V1q`Op`Qis}eI20O% z=R`VQ9Q~sK@bX7=H)}uT=?N4r#y=a%0KGpT|IJ!Yt!`6AY2_`DLOTVfJ*cuWT^vn=fcj@0TW8q8ASiI z@`Ie=Q6lM%_7R|TuDS;efj*vA%F@!8Six}Fn$H)A=u1Fjb?ic0nHJ)D&k-UHV;K2NUxJVj_pxN1+NUm@l< zL!cJcRqYAbmArd4i5uiZ7u5{6Hv#8^8mv-Zf-dA*e-Q*so@e4W#VMYIE%Y)_!sa%&rMEl++It0wP_U}0&7Dmp{N)=OAX3&OafT6bHoW>XxX>lF0NAHasS7z%tu zd%DUhwxHZX8nPfoJtQw~1;tZ-DL4xfX2*igach41E*k0|K!cY=TWUkw5TRQq5 z7C-$d_JRI=vkQ=I3dB2jio@imYkl}j6duT=c6v#UHte$FpU|?nbB2bd<$g+DS`hNK z9v&fozB&q?bt;T!Z*;ApzHfnU36-*mFtvr(UFR54wUtqiFx&5RiY^t6ZfBcv`DQD0 z3hOjU5nx^KSzVQ$@?ZsB5reToBG_QkpRtt)~_*3eFB&dlqP0}6-|Ibd#C zo}x|%K|8M(JO-Cz2hD}8`Qn;&#!BmRy#CwEpI-m#+s|MBExe>g>;ucmt;;2=xN~Pd zQC4Xg8-xyM!eo7~*iVVI2N#z36cd>;z1xb`t8I|`MeSh>7boR!1#zd|vB}e7u%kf^ zkUo?%wY10uL#q%kmvYAVES1VuL0=snv$E zpCMwNK7(pBVki0xYJr!~j9it1*2EhD?%O-%0p!`FWw%U)9Z`)7WSs$ewSEiXMzWZ! zPWVUp1?ykLK*LWcD|Fz949()PR;30~9^pZ4uxC&j2RL%5;CezvPDZ%F#VMN|I-ItPs$`RQ?;RGi#UK*-{F z%q!1Wp21m_ktqVINW^ioFtx}sNrD-*{99_UoHw|LsosFQP@w6aF1&_~Ii%O@;Xh#Q zfR=`VEnwSyxf=#1^nH<^6$@K;(~;$Y#T;vxbugCJ5CvY3JWWhFaZp$hF@$5aeIatH za6E@ZXTWPDhxATw3yTjGI&=gxaBV|^^GPAK)4dEOl^v{q^MC$d#Axe4z>Iv;+;VNJ+5C=S8 z>eJrQZSn$Ow;q%P9_#P}2;QQV6VBvBqLe%Ww`X~V=s!4CsGua6dVx9QS!*oI<(Do- zdAG~x!}0~yVo56|$Q@cz*mNU6Qzea_26j5psh>v;8W@31lT*9qJTO6<$2y1?Z9TGw ziB?tNfR$QRCS8UTdId1lS;0B-4c4m59u<4nTwN7|mgesf*Pwjsp8{{Df?rm96}K!4 zr~;Smz|uqI2JBocoP~|{aElc;b{Wy6q$8?Ll(77vAYh@us{#}PYyNI-OT4kglXT?0 zI~E#SegllDz*UJ5V{nhRR)>6ObW)^Hkxx#I8P)BzBC-dfW8_cNPpNU`jljRWe3X6< z#~%*U*E?4tBx+1(cFa=iaF~M%Wq&(GN8i>@8Q!*q>!_o+iKt3U)=a`w?zlBFk|GkM z5dhWz&_dnZSa23)%51D>h>w!CP`ERhK&gC`voA+g^9Lum*7l3-vN|+IvYr@nu5O;- zaPu0cFUdXka0h^;l=^X@V-f^=EV0w=WYOc@rp|cGr749WCk_)jFiEck z3Tzo>L^WjPKa~RCiPF=&2e07$j-X(-9AZq2fjaPrmAqqY&j0@N7EotloVceN+9NC&5pM(Ty$eEy_drQ6DUm|Uu8 zNt+OMD?P?~a2Z>i>Xk~0GRn0hp={KN&M^Z}@v*;J=Mvk-uPtyh(M zMnmARx;|m0aAMd;z&5LLIhgeD?>NpV_TR~~OEZo1Owo%eBn{_{-Q4p4P8E0eJx6Dc z3FaC+Oti?(=56xYN{;9lvwgMF!f?tZ5H=aw5};3Ae8z0V#(*2lPpr3CD-r?ITKc2_ z@6%I47CN}MD6cA8sB@UZ2yPNFFQvR%LA>#h2ek;*MP&*@06cg>lZ=17(+OD&Cvyd2 z`+AKj>1b*1j7+ zBA91(E;p7WS3FR`?y;dy>^W37@FfPmSm*BG+6JC^LC}t{)l9w7s1v1h>)8D)=JmEf z>XB*JO`GTG?!balwvq26H{^&u2YhdWD(T?pWh0pWh4=d5s#bJ%G-*`HMMqNCfHbt+ zCc7$hG_t(}Dj2qPwY;<2t{^5h)Bsk8LcRTrzB5%;7{-w{HrcgV#fE@rwXzKe!WpJk zo2@UY6z$dAsg+{797CFB%H~MZjsOu@C@HxM3GpINSY43mX@;|0P#9xm!~*j zzBEHsrzJpR9F)9xwEP5~kx7*Lj^1o@%OeIOC_}H2I!rp4&T5*mJ7dD^Ik-vZ7a$zX zMDAW;W2M^=QjP618#0>VG{wv%FSmPktp}C1{jI6iz5dtm_EU7*AgUpCjuhF*70WyTKAJ`N?4c3g(p=me|}HBtSTB{B<;aLvSvI1+F~uZSl2p|n)CB^ zJuXDKneBM!&1ku9;(iF>s)aAd#p=LHVE4+6;bskU78i%bN@R(If&drIDYaw?)K^fj zBeej+#Sgys6=s}$xZE=kAUEo#RzahZPCVqyQ{t6@qQG6X^0QL?YFX+8Pm{3cmN*q*pTBy3$6G;elU23ojqMeS$(adjp~U#1J^3 zdYB42{DJhy)1w1JhKa=<8aHuKr9h-tAV%CB0e&m`DZt=5duywaQIT+YGkkzk^=GH` z+4NM3l_%SM2~W_Jdq3doq>rLAP&Y{m+O8++{@BQWqp6aW+fhYOA9pQrLk>}#ax0bW z2{asCY=3~YA9R=@rftojCls-JR`^uGbG!zI1!BBKSU>@jBFbZc{KykXHc8E-3j;Q0*AK0&dE4^s zf5(qKKmy~`vl(=S{)g?;>!5Jt&1q^QRiXpsHj+Ul62JwH*hWUW=&iL)h390!vz5XD zjhJz0{4A1GC1#xM>&H-L{0R^6g7c8xV$swBgkU0S5DFW}z(rcA4~w%s$sKkuob`vD z^@>R;o2NUZz`Xe1Y1C3ul-?pg9rW?bb+Kd>wjp>l$kl9%L& zq^x~qA5)Sgsmlr9gU>;>pu9N{MH1AM6&2+&s;LTe*77_6B4`~nNABK*9U^*1bt_Q^ z<7{wCF%27S30xuhC8-ND?od;|r75=DlR9(G4u|N$TjP<}aSxd$6o-~3*wv+l{1b7` z9c9qure9*3yxGSbE95dZErAV~O7>d@6=B^qvmO29+%kn)qvwMnPE zz;H9*MOjqJ3UJ2$fWGbB6VNV#{$Pa}2#c#6ydarn)x=VLv}0#ID2b}L!j@U1JZ^ZC znqo22=qiv*S-GpO`bt}a@y>r<46+rj#WY%rvrfdgP~KhEvr5jsp7rzv*L0didGIGFl03ehp_%}?JyFAslkdi{UG%ddf#ydfcx z=fIBB!0CpfhP&fE?7if@M%V8<0}DilX&mg<<*F&8(bCorZbPO0b!v^LWq`xS2Obv? z`I!6FaZ`Q$isI1)m{}{OjF3F6c6XvYQdP#F|0rCn&}N~m?isPi;^KHvh>^Y43}bGz zV3Ieq3jvOxXxW{0U2sJ2*-o29RvVbhtJNxCEl{`^0KINJ;Lkpl!1nURDPdO?MMBJ? zMB7TTaJdtNLJtza+8P@6{I4KNT-mn8;93rj2`Qj`juHd*BnD}rx^UCAr*pWfAGC3% zp&tZ34Am$TgE)OiSr}hIzrswPBrR=KUwLp+zq(>tg0tSTD`6kI#KD(z`WgK6m9@Y^VBR^Qk{x0G zv9ilEJV1y_SGiz<2z_bqfrhel#vrJdPPo}%%t89*JtARq^n$yXsa8P?hcV`-1k=h+ z^!<$#Ph}NY+PJa0B%2EauBl9zDi2?jh>ID$vLj`(RR^Og%Gum81#$Yg?D^HH9vO8B z&6$n@Aq|Og*ki?zH6h>>AWM|XssJ7%qt0v~J|(aA6jjibKh+oZ*d_d!Gb8p|RQ=p} zw2ZdsRNd4PcjR0q0|A|s2E*s{`P4^-P2(i(p^$THNg~C_O2ET#Sd?Fcm!IiR&$}r3$1#QSvBEkiFO)>Szg5=SjWI^t0;wF>oU&maf_LNFJuF}2qnjD7}nFGSHs(N zlMC_d&XSaP_vR+Am>%xPKFxVk?_FC`GY9t%7-!hU066KFrUs`OIL%&UD6Z@fR2N_1 zWq1OHT+vLr(6hbjj-*`WHEFr7`ooq*tFUQ$X;c_%q23#khX5P*dmsycnfjy_O9odk zT8d5Y4;r1LkD~@i61&Yd4rCO{>4-~x94M&RxdQ2uFwkEXlQs1pwF$3^AaCy@S*$3# z>XJ|2U*-eW&NMTmd_dgj&}v?N21ysia>jy45(Pz4W2_i>iyktUr3-Z`U<2e%d$$ek z56cnZYRxXZiq~$oEw8)%=Z(q|rJaB&3EGKLEf=eTLV3hsTrniOg^Wznf}!dxxGcz1 z4I?l}V)*PkQnf(R?Hy+{aI@N0XHWdBIsbrY4RDAzy5+(pAfY$$z(me&XMvU8dqoYc zZKkIVNN;CKDN6Qn+d3(lo$o65YFl)mJrkS1u97SS{I_)Mo&{Bx|8XxHt6fv+ae@o3=#$b@{!PZ z;^V3k;v>?v?N)fSL(1hD;jXI2K*|(knSh(y!OrdmWfPikNuFp*SE@m2yQMq;@?W6` z@b+8Pe%vjcTYOBj$gy=h0YKfO_H?E1B-D6PaYzira-f&Ot)-s)5|26X^{i5Fr8gi zw?UuG(0Hh*A&|-Y1O-};LnQ*m%LAm{_@3y4nRkXoE0IvOCNB| zh7yWz1(QkAx-RC^utdvD$}g#X!6A_2ZkANn&fJ@nJIS-V=Ip9-kQ`|G6hB`JCH`fb z$#HhOOI23&47IvS8rmt))J1TxO2^!7?p4+8a=M4Rd3moRfCc<}iRlKWQZb>8D-b)C zzTBBu){J>8HEepDwurNpS@lfy}Y$+Zi0aA;9d zVYSU!r@YN(1=`L}kM@JN-@kkn(wFp(BXXGZnxV)Ay&MjY!uev>ta?g_W@U6>q)?)j zhjV-7ZGhw5nH{e!$s^d}NZoDzpc4%@-lH)GDB^+BjC(=K#NB+u(?7<90jUs*e0k`= z&Q5?*IoRk~PL^F33$tQ5>tUh-h^Q(rH0T?|#k()hq0$#^Hn6;>5&rHDP2K!-pTbh9 zBtq#-sM=`T9T@Cp{Z)lRM9+oQumOX&fjP&(5jc>Z^;mf-Z6#&J9bN#oeO<5X!$P{h~9+eYV0q?%?6@eTMFQ1=u37tFc69}e* zzL*p_A-F%sXO7XJZDZ%Ry0DS<>DeZF_&1=hM|hdqwo!#ZK$i@ec9YBJS)@v;>5bLe zc%TKMq{eaxNxcuLn8(AyhKm)b^!&@$&|yF)#&Mc=N(16VA~>kJ;1Sq$OQ5CaBsxjG z90?YeI~BwPc3-16o*ap>uNSFJR1r1?lm^swwyTaZYl>=O?NhVimGw#=^3mLW~m|`;o$_%P#jJ+>>4EGC zj#E4s8Wqij07XE$zlL)q*!#Wfu)O}e#2&kWqcf0`lWw{L%Z`y=1x)s4$5WkZQjV=) zuGMC5gTNlyHYgRxMT#W3(4I;QM!tp9fs)Hwv=WEjsb&(Pl;bv3Enu?!VU9NJgf6Wv zl7ajOoIkJH;1`I}IZuYVvC6{{Is{y{<*NB;7j`%z%>YVy&8UJ@PHs}6PA4Q{R@IUp zJXX~<9f^g5+?t0Xu%SEw^IJkPs zw1BJBHuAcqnu9q=tU`Za7!6iZZjT4sXFBb;jb7G# z*-9;|E-*2$?G(Wwb&VaEl5n!)53?^5SS$btrBf#AcKmL`v!fA{Mcjo2yaaYzVA;c4 z1!~>f)^F{17Dl;Ht+S0A-&q}&8w zBpa4VghTIoQ}Ah_v9-^(L&*lLqXGpmjZwBJohf3kvIp%Wj}m1ouBX?ZORn^m#4>fW z6Hc$V#e-^FUt9omD2sBl<*syZOPZgY{vpv?B_IZJ%7BI^t3wh{<3^+PCZQ7Q$&sOV zaw!y;dLzxWR2B$IyUI|`C$zDPyJLbd``YDj22#j2ajni>1>|CH#7rD08Y)h6WiPJH zTvEVT=Tp5M=^PJ#ujEZ8Ssy?GHrm6O?I5nPM3ROiI8GKWkSkeJOucIe+&Jq`wstQd z>mL{c)=3_)LT%?oG|to0zyO)MsfUy>B`J0?zTyfB6*bx5iszynQAw*=2(>#*$~(op zV8HQIY@yjs%~+$sx4_{P{p}RDfC!(ojbqt81O!H$E1w|w__6JPIoNJ9 z0P2I4!5Z!tD1A9#rY!->TZtHpP`Ozgp>uI6|9uHJYV4o|m#I9k&78+FnVQTXyG!b0 z;$Q055#{5;<+2JF=(U*kC3;9`hfBKM$lVwzZGifpdMFU8BQ2{x$WmXy_P)B5^|hU^ z=g$S_8=S}TXcdJ{o?fro z{_e|&iAd2JCS^jP>Iw0z4I-{QC1@m3b4^E1IQmKq1n`7W5ZJgwy|AqDt(p_7&)hNI z4bEi2)@3X5s!N%~2MBpo?Md^C+FgNJacZ6UZYya0S)f0#DCY8n)~6gS@DW%~s>z*J zWdZ&HF2Tr=*nvuD+zBh%mP~sqb>?$=`@QKHQYQMR?lhI&8A^1ll91ouICn!cU$2ka zxN;>{Cyj8tPj@k(Cm(elBE{yqxs?8_Xl8XBw0#L6!XsM%QHEu7*Hesyfz&{oZ5Y|Y z?J}Q30wz9?4FV;kfYN#A9ZY@`D!CF=6T#1}B}ura%j#WNtXG*#?!5CThw^gL9lxut zOj#J0V}Wqha41R9Qkl}YP!4;zrPKIBM?GngLJ+1h8q>=c{2KU;9Z9mQ41|0c;k%If zWcR^z{1=_J^#g3bf=cn$|z zxI9UTE-dX8HB=6FQ^PW+e#U5?521H zkxkdW137L~S72H~sSE}hwC!l%%!(c^Nl4=o-Nh{VH7aIRku(QUK3J2c$qY(d80E?q zadkad&Ba00w_PvtPj8>Ue){&~WRdbGb0|}ycTaa}V18>!$mpqqBuNS)#i*@3lqJhq zS^`}AHZ(($2`eYF#n}6xt>NhBqFT=?Rj0s$ zlpM?s9K`8aOf77<+FmE!cD9AH6N=G%UP1dAH6cXOH+s*!KRCNyK*7Gins^H?Sp~ZG z&+OohVSDxihG6h_TRS*{b!ekviQq$T=|S!%cfelRaRW=)bNik)wgk}szpvrje_$6$ z%?s6VtfWvRJmHK>Np}eRIc>qhz>hsyc}nWwM=?7EC~p&F;$0bO-46O#%cPx2-7I#< z0>g853_Q+5husa~Ol%cY6fN+|6RMa(!aLTVaiS8}6y_?`GjoU;tPY32-y`$>8GN>o z#+R_i=}j=y-T*(9jrzm4xXDZP|>j49$tQ%q-mV!xN6&7;+CD)5^2s+ z;=F3#5u@@^RX58_v6}CiDYy4N|z0^bnYHHf2j(vt{fS7fXD%MTfEsBmNj# zGL&-!d)Ct})GRTAz}UMAJdl{gL~5$%#vlt6DkMNy$+2}R1LT^ogAu<=NR_nS zIF-W08c*Q%Uvk~NYwrk(n(RZ&x@m15K5a*?#su8Z!i39aI}Hvxb<&+Va)G`4Zd3^4 zDdz*VZIBpMs5tgP#iG({qf)k>dMPV3slFM1CsK8`Zr{_st!Da}Rs{+PHI;8kPk;UJ z?c-qJsb{7@cc3Zn$oOT^MsypGKvAv0=h!xuj$M_)NhxTF3jHyFNeo~Gao1bQDJsA$ zml%l^koCFgm%&nTz&EYbqWYD>lg4g4DLp&A(D&$Jl6nQb>JmMXZv~eq%&6)OBNm+A zu2U^X8BWq}x)dd42#ZQ`$)n>a=m4kG9V!@z0d>V51#^Zk(^S@ zv%*d+BFlBbd6#k_aKKcSf41_)sJcflYU9~G4(e2tRy5R%io2Pls?b>a7O@e^ltdz; z(v`>5$69W`{NTo>-wA((0HqCKrul1#&jqVMn3-|8!&632dqygkG%o4cr$aRx9y|xo z1_mjkZRac5*J==y5|9o_d;j&*mp_EJPe5W?7ft;L>ezZDzQNgRO;eQj zYmoUKbR;}aoWua2ajGm>>aLO>;Es2DP8I}0Uu&q7-^{&9C zE~%HejtA2aIgKE!%8|n!3PS88NK9CWk{TiBK@%oDh}tHX15B}23xiK+l{4de8k33! z-vg|Rd5|! zrHwGVx-XhL%VyJ8d9a9Xsn2j$0!7hLx3H5ne@tZL*ik)-Uw}UFo}Ly^ssn;fq)UXn zojuGY+t2l*gA1Bb>4${QK|zX+8e@p^<~c|%koA#!w6YDi4BA=r3|v0-6rF?9wT;SA z(O&@kfAE@t7tKYyBn}WOx^Qx%RjZxm>SQ)2jB|!sGeejlEK>yvDG!px!-ozR-w;;T z5?k2}-tJd$qlLt?wRC!$b=6~P%rS>zv0Om>reM(gQrTM(HGj?9Jhk3qsd^(a?M015 z?kZ7&s%CfZ8?Ur&1Z|15f-Kc5$9V&RewWWhBuEQ6%R9pR%0l!E^zt;e#2?+*!z$Je zJsTW|_E}+J+>_ zN+29hDh`T%gB!Wj0Ppd9lJ!-R#ElQmYN}{FN1EXVxfB)%@H}zOO}jdMXT^e%3|}5k zNFCDseg~Btj;Ze9PKJ-7c>ti`6R*%YvQ}+}nSJ!!C@Sj54>r}wQ~o^b)452Zr_hTZ z(Qc}&2D{5illo^s#d@icpsp@~*e}*k1#GL%&DV^B01e9`+kc|zw*{qhxAkR9h9MEo^C&yL^dYT+DQ$hGX0}b9BGt9qPNB~UPB_7ojViSH zcqogkBqdpL?9{2u^U+{}#OVlG=R^!)>vc~=N<}sG+}f?r?Yo1EyGjQ#ub3&!RU}sc z4A45sm0cj8a=2T1UbGHclhd=7L$~dx+|JI^}SOj{t4zh=)Qy`_{^W#t6C@(Y~n;NTRD688JJhM0^3#+4+=gGWNJA zMIaWmmSNqz$W2oZINPWa_$c;z<0M#~wcCPdGPh@oUP_**xBbhXRSqa}IFHu-jxZqK z*du&KOSEh49>D<2UK${$krX<0NWOD85+PY2>%tM#vh~lH_%ISGSSY>YKsAY5zI%#y zUv$_4>4VkN)ge3x*YkOuK9ZjVbFf5Kp9E(xVUH953yYz#m>5vh17ghoHbdN_wbW1zvrHi3!-|GiraLYVK1l~*@!MJ1)JHpYLdR#oN|C&Q3jG(=}=^7F}e?BVMy%?QA0yKI7#YsZ;KYGVuokx_FOZ> zaL9s$DCq{t!Jfu4KrPkPBhr(F@>jZj@wti-&KJ~l!w$~5MR}AsK)c@#!NU7m$kNv6 zM{(!M!+I1Op5rWu4{Tly5UNJ(I#d2{lK-7{H~(1BY~Q-mGFwMTwld&dC-wUVwhtzn zQbr(!fk=!*DY?`&ad_GN=mVRq)y3`J3KRrbPPAH@aM0Y)Kmvxo#|rvLF`csnmU?V* zZP^3+;ikD!-4HE%QYgYACk*ln9DI5>^aZFpY})@VJ8qHiIVZt(~@=cE<&S;$vwlc-v3a+i!;v-J{n`traZlqyiJI;|Pz98*fq<%*5H~!#Z6Spp?%bJi}OSDv#aeO%rb6TZZU-b@Ey4EbiXQ3 zd?DOkk1zzSy%`S@(({4XO{ExAb`S>zqy)1OS4soqO*X(p0WXO4733P8Gh1-E${u&^ zk;{naMl_y0AIn;XuRWVTk~z*N@~t`~B-D5V)|x$_H8f0==p`aYi@ZO_Bn;eB1o&ENkm*0i&8v-;mKEnWs zM$uB+I;v&_PW75}1vNwndFWpRFFiN}OF$#!7&ICOKh+u5hysx0%2*dmrix2AsDgYU zOUS-S36Ek1W+OK(kZn$MQP+3|=+VN5vIdF%?fNV#SV~O};y$WN2`s8Dxy_O+E%_7$ z1T9wbFR};$+Flh?>E-U7Y0~QE*!HE8&Yj$d4>*iuJu`2pc5PQlny>~nh^EPSMGWn8 z>xDTm&F$POfFIGJ+f3gKp01db&>LXvG7=`xwx?kO3!NBCJ!S88rxl(!bu9tJ(SH~8 z`-;W?C6qp_o!BzKWZ3%I3|?3&~NlUuI^sa*2l@8HCx z7^4*Uq2VX`oA4ja_(M_#3*gGFt@v&zJtC3Dz(}0>DUb&0k|D^dPle^8MB-yr{X$9` zbXc$U`~a(pIuLFb$GCyb;FPJ0lFX5~$x>jo3EhhRlo$(7YS%kG@yu1;qh*4$|o*{RN=h=J_{7a#+MmK_nlRz^@8z&t^8joJ!s@{p_xTg@dl9N`u6%|oSvm1NNcD!wec zvJfmg-m*!P)Q&ELAAA_NQv@I-y)fdjR~(cF2fgt^B}*uSAD_X*mDm z{-s2pL%SHXV(nM7gC{u4x+Cn5cGN=5<6G9_Qq(mj14?#&)wDd6P~X;E=`E4=a++~p zRyMuek=J!pC4|a>^=PKVyFei@p_wh$LV%3Et9=V!M0UBa5)|80187O)B<%($h#I+| zxrE7d%zgmr$fP9WFHE{PVJ5}{y$*5+DA@_nadjoOzPVg5d2@Oyszx?+V=Z}ALWvY~ z2-V0NNGYE+3mkFS18;HTxiGgkj73Pyet@xfCYAKT)s9g1eR=2-$;Yu^HE6)>>bl|(#Tg5rtlqFE%EMKni3X)T!lzL*~r4N+G9um?%3406!{*^*CS9 z_J{kmPO?s?+W%6|H1Cildo#W?z-yd#zx^>BO`BAJ$YRv0OeZj}yF>O!G=qHOFAwcK zN9y;IF&#dL)P6N49qFyJttC=_pjA~4>tHgW92&PQTGYqJU@q z!XnY}s4BQOkIb1{`4#XRFxluNv4K^Ms&Z*CR7kNKh}i7H3Y!W{Qq@_kH1l>T%T&zk z^aSLHyaWg)7i}&$Ua?X?T3daRW@MWq&Da9Gk6;EAyuzzc;7JU6&KLfX)av}kPCcon zB}27KPy?lbr{?0PCWfO+LG`q2@DQ#I%wo;>d;re$cYO^SX1h7icn)~!^iY@y9=#He|a zJYd%avIg*mL%cA@JIwz_z?Q7tBZ&{Z(w8-L`Bi}jRyQ;wPJ%I^*qY5i5ddvGL$;O~ zkdMn#lu|EhYQ-8p5+!d9lXvfz*%3BR!HJ901bjfl3RdyD^jOASpH&s-skq43Sb-KL z#ml9wTrW!U*o(ST2AcOSQn1F;4xztv)T0?jSCi$AF6HGkkj|ou}DzR3o6|sR16DmmBf3OsCmbc_8qf>u=R?B_tbqqJif+Jcq@f?``2J33HnZf>>ff<>1ogE|Yf zULz|uaOZGk<~2s;HRvA0e}0Ip=SN%X)|171&QmW!ze+*t_>kP>xj z$qMS*Zp>ZNI-*B^A%H@;2Ji^6<`QQ9vs{%OZp}f-=KJBh-?5Of9ds_HEhzxjP$J&- z8w;&FTf^&?3KSkTuRn#z+s2!`j-|Sxqt8_sRZ9h1tS5?vnv?y<*rV*jJ>2vB0ZC-m zptjZj{qKhF$}jyM?E}j|RBqt6{9f{rAKB*hsnXbX2Rc!m3k2hS*@NmF!8#Wcl#Oj` z^$P{ht{qB&*0PrGh5s#u%gYWCOFNOE8pD29sT4vVFts|$lrn-`Mb+?j!q-S#iySX# zr>5^^g9B&kx>M%K^mi86r2Yf^J^gfn6ucs(R<{+?^Oo=N6d`z^G-GuDUhmG`>?hT) zYTYnQ*WC^)^wHe_H@u5$`bInGtO*L=?m)@(} zendN;dr9JEln6+qZ9hWet8#8ZS2*aTR6-#YFdl0p2m!M`YjV$>t8+{})@L z=z`9pp_LZ*5}1pppuzFI*r=M#W>zn$%Ok2XvXmjP^=g4Hh7zTFXv*`VT4u`0*LGru z4;;Lu*p4Z|ACn!cBQLn4{t(`NchY_{Cc+gzYL`v2r-Z6K0S;f#Xe@mi`+w_a@|9AP~J{(sPi`G>km2QQ9UQw?FzT1;8-B@9}?0Nrl}aFO3ZI;blafq z*J0|A-n9U*NtI3P&fuuxwEfvtksoXlpxBn|Z_YXTyRAjNbC(d>mp+7pSIw1`_JFN5 zLA}$2NGe4qrRS!C5e`CnLY-_GRNA>H-Q!pm%j7Nc>M=#XKj?{|FMjw}1g)aC=?! zBDGJPZbwpU=L{M1->Hq%2tgcGw>Ec0gv_F3AWEbMwyFq9*hp(&u_PJiXS5O3nhe_= zpf~vOh^a!y-C~=fgCB>l8j>F@&kUN-`2-M3vsiYo} z4G5JTi<5d9-iqAhi|S}debS!3V-RS{pG)eXVT5nE+-UxZ{2kk{#RX3arYsLTjHTx7 zxtg>g(7LtrIAyOLC_k8OMrcMFzXY37F0#m0%4$up{w-RAP%9uNC1oW-hkcGZXKxF- z_@Ll)?Ttfx&&mL;y|i=)UHk*l4f5NF2PE~ADJRW_6<3}t`$LTfQzY_(N*6KnLS_@3 zpQrCO;yjIcZ}e(Tp=1E8Y--xj02F+bKGRn;^Ggf#)3={Xj*c&HKYRV`?GM&10o~Qa zVb*{qa(!B6G@*fp?ICqCZL)p3Bzh^IXSXiBWCU;r-{hD6^L_Nt2-dXhbWB2SEhp1* zSN4Ns@_Tl?XiDG><&0hr&X-V&$ed3CofP$Jl}+|^T5;Kii@Xu?t+J0iox3chR)CV} zp>W^Bj$i5JFKDu?n5nDw#B%3E4oHaR^aPDbY8o^;Osa~mz|!ED5GaPoPRNJvD{j61 z>o-4;(CTk>cVx{1aI%4rfK3k<>HS3r$QVj5y5}vk{hN-wpra7%qSP_QxC$zXEm0 zzL5vFxQpeC$6`TIjxQLtT}@`BoHtd=Ho&c_KiHsT1xUYAbEEX}Hw@3VIR^F;r-Jgu?M*6jm@p4L z>Ufn@Apjhk%Ys(HlV%VM5O`OXSCjg}Z-xRJ z9w1mV!wgcaDigxuyOi9Yy!|}=9*#foZ$EzdI*lR|zI0pBBYaR_7A`rE$#O(v%aEY9 zb&Kk)vkFpvAu{mR2U?qZWYqDjez^Hg%^5m$Z@U^fH;_JD!H~mF4{8l(OIx>O70SXt zYWKID4+FyFH1LrqH1ST={xT%N7 zX_b`V9-~7imIidyaA=~Hyxjm7I<9qliq2j^-_athq$p$ZJwx0{f3}V1;7(3(I!~*t)0s@o196Zo zO@omqAC{X1_Hvy3|3y6xs>JDLn32^Rr>v5jI!5}#yJAI5ZD%=ftSnN5fYgfivL!|r z+@33DkQJWi1fI#Ref$OrJ5v()N)IBGBN-<_y`yA1H7rC`D;zinIW3`v<$PqtZ$XXQ zxls_GY7qu4a$n-JMp`0|N=O(r^L|DTydK@MLDUxGxs_PxILy!DcmS;D2NWJy3ZHj+>7i~x`T_90zZ{4Pg?dnB5icn&vZ z3^>KWZLsg?5Yb+{2&_J$6O(%7J328K{Xkn@uq@m05r8XNTZ#)ykiXl@p`*bfT&;rA z%^D6mV*Pq6=j$Zpe95^&(IL5X`c9NJc{xxvrBeOoU)1^4;Is)R+o+Qqn59m{fCC!u z0O~M5DCJJ4kNDT&uT#|jWqA3eZH^`^(3(MCi%eAYCnVt5ABJd%I}ZlC4%@3y?P1~7G4z^H`1 zXOj?ep$AsG*Y7Q4SK*E72226~;5{PP$Ms>Q}`z0yN-AZYVS)x#;vh zm1W)KQF;%o@H1-*?`8jp<9!xu=6&z z6?yms6<50)*?tlvD5ILF@9Ta-u989#^f=q>z>N(GSiW5#435CEk*w{ajdrwbveO)7 z)NN@=jA(0!$1Uq-tD#n#0^9AgFSG*KZE`jvhRfDg3M+YPXV>tLXzbXAsN|+RS(HMn z8vIn?sOOd{f-5-$3GI&x$Q>j$5f3XB`01G>%P@s?%daL+6#pi#Na)5z;Av>EQtzIMZ^EJOp(+TKDH{9@v>o%?dkkmph8 zm}riv{kLFT^a+aTfQ5i$I+0Z&iHS+5x3Xr&nNor1%qmu!Kg#xS zbSX3wFM$gFX}0t!l;h+kZk)?6S4f0s&Gr!{oQ;m$R3C2D-`jj0zk2(W6Om8()t+jk zb*Hi~T%vTsa5nNfnAKvrwhh#rCCdmZoa8Qk1kK5_lpU^CK9uVp@WSH+tgP3fWif)t zoz{n3lgAi zENaKTLA7#LSTyGlNCaU=2w5zO5L=7>V}_ouHIbS|Hh9-9nz6I_Q!5Tu83D}P$-uEl z3$qSBwAE)VUC%gOy!Dkl^+=~$imM)qcFy*wQV4@V^pBF! zpt&I@hojpI3^TAn-BJUWou#99xV|7d1v1^9}i&{0sR;0T9LIgfy;p=df#Xah{=x;Wx7`HaPN; ztyFXv2U&=KssOt|7+~~R@QRU=Giq?Xa9A>HZs8wILdligAPCq17?Us}aNvQIK&eyF zRjHoPoJntf#WeH;H&0m?cQ*Le0$0uf(yTER?_U>P5{`ZS;Wt0@0dW9jS2Bcjt;_*5 z*GcTWnV<+sO7_f_>SEDs%s-my)KqGBk3t=^t5dZG3I`0!=Kk8ZmeMnl?o2SZcT7~z z%3?X^)CHY!m03JpL9n!>w<$to1f<6ztQoHk$1LW4N8h6=*vim{{X1X=4nfNliBc(= zAbOY)d<3Y{83I}n(|_b7^9WO>jAWxCikjLxBBs+0i=@d;Iv6`b*C7d??yuUCr`x15 z36A+Z1Fp-QH15bDsmOX$jSirChML>6ra*ywP}zMGZ>{W{rfFE%Hl$G5Rz-Gi9TR{G zV$uU5*L4QRvi26>c!lYT99{3-#$Ubtg85ST_8-^>f&-5|3*emya|BxM%0ZjT5^@a5 zj;0O@BvZFUeRae6YnJdvUo=dU?k;>dqv9TB5uvP33K~aDx&Xz5=2uLOM_5^Lwo#Nd zIH!;H!8IVq*jG{>Ey}vN6*!l(a2rrAi?;3PiKs9H)gah139G>5-;%qJFcnC1roWs_ z0F)W--3vfuq~3^~H)MyF$nQEXuphu_8kJa_RzQnGtpc}RiL@1QfNIWtYdcTFX4&R| z^0iH6-6!M+1lUS~r8WzJE93R2__Twzf=nRZpV0Mcsn2;EuBdcPN%2N;xLA?cq5aa1 z2=fQtFWqNJ|97~MS?q+GWCM@G3jDt|Yx4%s*PQue`Z_>|uL}>0ICN_E>z#fbOg8>g z7^%gk3EeCKb0i~hO=?>NZI`rzUQqX}-0Vj``I*9zlPc|zKN`**bePdLd@9g&fr@P5 zs?|y(!u((X>t!1xjUO{6TBo5*85>|$WgVS%DV!{3=DwbuE1+>Yk`w}e8FY`3(mo!L zaZsprv7D}uj+r^)Z?^8Bf{3ec2R+7A-J{hvI1`gR%1cl}6m_b>Q-?4NOi95Tn_=)c zT$NTGhdj(Mh4%M611rz3@3BEPZfqNa@G#6s$_e@$R(pSvgbgDDN!dxcgfCJ0u3!%c zP1EjFu3&!H1Bd)}ry^sNI!^8Mg;bJvp_HBbPDiUwGQxQ*ADCm`X2UejI-KZ1>s(Sv z!09TtL)wKVKq@s)Z=cht5>7CL3fwDaxlArdCP79Cc}=7&IE%b^wFNctr4h z3TzCc$wmJwPHm7oT8&ykE&_$vK}@KU8!KDW6;112>#7K`14<`o3D36-0j1b*(khR5j7 z0+Sq)X}Uc66pL?K>U>kN2keI`2Lmq1@H}iY+z=B?%he_56>5xP$@>{<$wuuzN5|uz zLtmM2MAEp3#0b@LzPM2&8jx+_&049ND1~rWG#h>RW~dRC>E_KKWl^T1f`%y0WMbq@ zgT0!!NRaidPFdPZ9Briy?Vv$0YH)l&NlsqujJ#XJrZo7qy$0QCs}`0+wBzp;{pfN+l?Su`Hp{Xt=JLo=Qw z&njyf{gz+#Zy!Klu#{i5xFZ@8xu#pNFTmK_5myK1RTqjC zP6%{EN|$=H97?zP?6PmkcfJ$;;UCgJ?I^>s#6e{{EG-z_8S@g`><-_64 z?mU?8{G{x5^kB0Y5@C}-NrJ(aNDm}`kz@`%nH`<=Si^Zj(`R1&R6oC`l|)IRb~$=a zfji+!1`_t5Ky*&fnSwVl^;MS<3K4CQsbWiX2<8-5u-n&F-o(~A+B#?S2lgJ9jq$qM zcYw!pD->p#>FB9hfJ_oFE_Q7p*0u1H^z>L>)bg@$5#9>Z1k`Nhc+Xfv01s{8w_#pU zNDz4fFw}}`fEDa8mMuX)La<3>9S*T}pGpYW29y~@+>8uBmsY*E;b&M8Wzw(}4Tl&z zoiO1iX1SE0wfmEo?7K^9-)u-rG$JK%b6-?w2XPaQC4?AGI{-mMCit1y6`1-UVSjS{ z7)*U3yCu7t*~l5{^@-bVuOH$?bxekuTAor>8?MUGaX{6!vkI7ur|aFy(gtDEO;6Of z5fh_}R1`2>0IlbKQgxtJEmtba)tHeqkC8Q*oTs?e#(NUwv!xR$LRBtt3TCLQ)pf{G0IlFE1Z{H?R1gzI~`~QzRv|kyQz+_v_#d2w#+BrD9bS|zJ@0-rW zQ?V##LC&N~Rj-t@qJP;^s#oflG@VRsCC*sEOjx2Ud3;t2vn5AOS}9peVF9<&Nro=g z#h39R?p8TI9?!!(`WQAGsInaaqKYWf<11*M_;2W784*OCq9JMz%m)4_t$lHNWlrvGEcCYlc>aj*f4;A&z^XH zvkwV=x}?b#hviDqHr2Vu4*6Nhda_)n6zAZ4o>XK%MKDJGgUcPwyT}ZTt|AF-&QRd^9KcV^d_6z*} z^0V;z(aTpaU+E7&dHv+&589Ob@a=PSXWl-;_uu?L|K!KExbA71C>WGbu*PLt4_jggqT7%e>-T=e(~}X^1(iP`+0c#^XsQTIe+~2 z)9{anhjn9LKqAzWO}{3NSW%CgY;~)}ekM-bR7KTVQE>_MT!|Aw7i*9#jIr_mrR&Xl zWJ#_w!T0zTMt0A%rdy)k386LrV;T^AvGDK=cQ?PjL}cU)8Ui^_^Dt1qNpE7Y7Lrxs zE*4p&ia_41|25}3cD`eNOFaeD&E?+A@NhRfc9w7XN&d*}XSBSsO#u%4(l_ zOgl^#IzF&spWJK$NvB;IP6il9Sw~0voTsQBpnhVsrk#!KHGc+~qbE72wZo#EI^v$P zU8F68XQt$vBzM-JHpGamd5JV=QX2+?*bOEfl6=p-u z43KQLu3FP5Kv!9PLjM%p=4+JaOCw;3krvxVmTy*Stq^tn=$jwD{W|{{@`t>S6z=(f z+QHTo36EdJYgx3Pu}bFAb%>g)g(s|I5nNVS$wd zPFQ`mwX1j|gRezF2UZi68`QYHMb$@*4GhNom@5gorV{|R+Lv6^-LR`IFgxFH9MUU{ zD#^2q2ep{L{LAo{f0_B$%Fql)Y8aSH>nu@0GL9UFo*+FS_ic8ejPMw&QB?2TfYZLB zMp`eC`Uwa-hW&-7vCHTHR;*h3swJM;o!4E>)1-RYSzK%3K0(3F&ckz3)z`{Tu~uy# ztf7j(D{?rHjD);+zBa6}iqDLE775u;k}A4j5*+gE*o;0dfnAdA0uW*ESP2jAg|nSq z1DkGbuP|^(*{rP&`wZQQgV0}SUvB+PAMGB$Kob0I%q&c6fCgw2>Usp1-8$$(*bwZw&E5&Vu>O9LLyvE|HI}7Wou~*m( zHFadetpy^u(y|7I2T;Uz3{MUGhlM4n*H(DEt6g^0eIV!lTX=MT^!BwGJ<0VDq#>D} zran^}Dc;7 zyKhi>x5^GA5Gw!SM;bEf(FpH#=1NHisFv(xysfTR1Zcq&X z>Y`d6$c}mO^2gzac}^N$fNk0EV-oiDap+h4MXt#L5NC*xbQgu4ya zMo=fqU{X;})u43IO!mT!lL%y;aKPQz_JB^IWLwR_O1lBY)CK8K0+HgVehEyJ&4&J` zS+PP+Bhz_-%u6t@3p{2C=PrSaAZ#qnIoz#zg&w_+0$?~??b%=1mT7}FzC;#J6xGUhEgCyH2g?iUUa3wLwI_O&-?7o~ zh;;@D#>zI?-Pa^Y3{2?)1+3cb>?srZ+3RPZqocz8`RPU!04z^)8J?lT{e~cD6Ii)xmIOb+(Iq$JQ8eI` zHOlL`=3rQrE?n!Yb1EljcrYGe^9G8!`6p0CKOg~dVP9rMZC3eQUA6(~XQ6*0Zo?^U z6Tn~Ao(Dl~9cWn>n%OopbO~5h#M~xe+wgx0|0O?ADAE;?okf`sh{I~CJOZQ#P91u> zE(aGX=o4(o1mpi(_-}dV{~=gzZ*kyLHW7bj?@)>uQ{o0Z2Wr_%)mOd!f)R%Za-BRngtZnd0aMvskLY0@N7k zYZ7W5Y{?9vh?Z}B7#oGv8`SHT9vH+)&d?r?^zo{eGd`dmpr^>$B3804WLcs)LzWF3 zC#2nW7M@*jey46`C^|=K^d<><*HHH5?ceh4t0D$JslltM-;_lJImYBBJjrbXY9`+Z zh?=?5w`#l>ALCt}Fb|SVn`???;b8aal0(*EK}iAxB?J0(hQ`y9EhDJ06VV5C##yVy z@`Oo4#htl&{SISN8YhO)Uq-_T0ckdf)$|oII5Lyoz zvMAL+{tYmX!((^zGdWoa%ov@}DW!WBHXIUcGHVNhmj|N8a`gQBO?dr-b$af}FJ$Q< zhki;2Bgl++0M_iJ_R8|vKsrOu%onf{)ibKm(Oq_xrSQZaU}f8Os(|lUkBsd4i9Dq( z99?|oRSG8T{5iErbNc)MN6XeH%+1;d!kff#<5lax-znj$@anc}^@8cl{vqc5H>dai z6bz035?%UcFWC*$&gKa2kIynOQ@pUh%hdfmJkV#6oeSp$%4eWmH04_Y6Hs`F+H%10 zGfSeO|3bYGK^I3Gg;Hg~z@&)80>uBAoTMv+@Y9e9w;I%>ZY<<-`6$zy- zR!wPA&Rn=xvICp^LbJET36&EzE>;3bMfRTAYVp~way=WwH!QA7@@5_EvCt$@)$cx( zsq4@TvG5}@_F{t_sl&g=aP!e6-#Q9vLx#A0WYI*9|iXpxIST{*6vE|NH`ULY>%9GC8) zdL3?4FvugEv_r=piIiLYc-X3ceET`!=;7Pn$nURmsfYkzK%c*R)t4j}0PtQBnUHR= zy(PEl5tSR|;;ah$#YJ-1R1k(~$+93%`>Kij>4`)^vJAY3WEmO|ofHypv$XP;Op^$g8@P^4vaE5sHmV~R+0K6yl3&P#mDDrk~jFA=< zf&#G9f~Z4f+B2q7&7Wnm2R!bY7GU+BChP zdGb8buIr`O?qS~lGg8^fwLMoy_peYzPaBQ6-(`zytAoR4m0u6=o=xa0XTQo(jh=T$ z0?Pu6*fuq&>ws0K(M7XE6^ZOkw4JSh03Kh?*=>gc$rb$4H7*V!Um*Krqg{C8R(zgx zM3lRVjtGf$yO&0Qxg%`=iDRK-G2~NaTi8>t`*p+(a<3-jv0xrp{s7R7MKEt{J)u8l zqs<;IAsCzn04r@FZR95_7sUCqRuQTot?j#>`14f@R^ms`1R6tN)Fzns@Sqfd5*+OF z>H{Pv@)|XsVBd6cgs3r1KIg~q?Qa;?KCAhG20d~m!uP;~H&hS$HjC9l^$g(6sh8wm z{8VSFKHg}(oN!1NIUP8N-|T|m2@HNg#;3KN$Q8}LpC7ubhFlj9Rrb!4lCtDO*c zo$AZ8>cLx#CG>9ID(v>fK?ohvSVI3{c6yM;s^n}rRjOUGaVV#Wk5ufEUEU?~O<P;X6RgGV zX;*LW_y7Vt+faJSFkJWq;584HSj)Y{00T1eH=hCS95c2GGyu=T(6ew|b{laa0L+re z)9LCGfnXtP+T8H zHdJekxfKS!@r4?m4`2b{tYb68aR#D`V2pDGS&YFYof}|%r;-k*bk&@dvIuHYCz}sm zJAEMg)Z(+`BU&jaMHUQox?fx>^h@is6#oah!75a4mkb*%m4ABs^!-1+{zgtQWE0?y zlc&qk2|R5br2Z5q$RS9~OzuL~!Z;a62$!#;9MK2jEUUppopfwPR^GDU4^YfFY75s0w$*Zu@+)BFD?y#DfZCvsw6K`*P5O?fhy zzadIR-d|dZT)G6DMwj{nM%XUrGX*-9j18XfkQy@0pu6Slt2{JQKf*8+(=KhdE=5cs zS9I^c_~r)yxcuz(U%&Zb{?7lvTKpexAD?99o7xMgFx2lkROG5Gkq-LwQ(@?ilBI#k zA?1~`BnS9GuyN6cXUX(${gTv0OWo0p_cEa`G^6`035hWue}PK;UQ<^45(>^cBXxu(rYtG8F91=AKChOgwdZ+37b!G_?YwfZfq~_EAx#bmCY#ov z3unlItU*W=Xvsap=&Hvv&~A=hGFc z30I@K%0-$-F*?NezPU(dHBBl8>K!ClQ|Mfw)l|5ZLUE9|F{C3r_$$a9+9%56LFS}k zUEQU@nuA%kSN&_%ppPitpH^MKmh7yQN zYW?~3_aX0P+sgOq-~k17Ckzu2upn?ETi}Kl04;b>-*m|AUZW%jnf3@x0!aoeHEUoT zbhfjpN9G=SX5O7;VQs=alX?#ZX=nqX0-0{PF->fnRv#;E@01x?bw18}3~ z35Y2rcr`A=nlRI>+yZom8kr^Wdt=qBvY{l8DCV^oKp7#XKXk}?7-T^3INT{)>Yf7) zu&d7JtaaXN3tpa1OFdfCS1_mJb(T|QL7`=PZq<;&lR{OeWlzIgXSLV4R#Ns!LB?bO z!ZRuveN>F@2@^qdkfnR;3&CrtUf}sBxwy8=7jH6+Ak=Y;t)!7?>lnl?g}27zJ;}F( z;FF4o1@&ZW$x5he8c|Ccz$_rhA79Ev4Q%0T==IU%h35~3Mmz=LRC0p|D9~eME@c?} zZ+?((AU3Y;k?xKP-p&eQ2hpcgB@I#`UDZo%o$cg}Q&E?LKzmIMAXy^dp33Gm`hRjS z>L<9N!FJD*H8e%$nF6$EnSH&;_QVX)lW{6{sa&;1%pZZ~d&f)o{nt==TCWc@ zVlPt4p|t@XhzS-t&ndXy6N=uK-X&1LJWV^h4n90mE0z(BL|1*qjM4!h8)^%QW7H*Y zIN^|^ECM+o#mYI{4Zgq5oWB%~11ei*oB_33kvVjS4+8O7QXVGR*rO~AV>g1Ha0dH= z8O08I)&b0jb(>Cw81()Nh}C=zCgW_m5)>~Wcp=ZHA_ltjn%Z~<`Y^hWFFa&kcxSvZ zv+5-Bq#!S=H&yrL9!>Z`6#-qa${?!1Dbt1etJfd#BfTSkR5tFf-ag{Tz)vhpQL_=+ zan%d*ZZ}1c_Q9FdUU&x<-eEaxA&9!_I?N?1FdWS(M)*-*yDGA1 zTc-j($CAZ=1gb*J-{ih4tDYG`BODRme_+AS|jb9Aonw%4hLI^ zy5E|F^PkAB_n$y=Q2P{eCT(a{=6&AP+dIy=23)IUgV#hoSK0atnKwXyQ5)pkJJ=D5 zo-04agPqg^OG>21rQ$#L1pk9Xe^bFD3xE1N0UZNvZtMvhnW_=3z1at~@j>0QZbuXD zflEs_j}DFEAqrs>=p0B7vgWJfK^s(}3hdp3&4qv%pf8@BH!2e{#pEEdhZ9jRe8!Mn z=MWxM9U37Jwwhvhfb{%2yndDiLDesH>j6wB-w2!~DS0u7y)cYuTNS9xRdIn!sb@fl zfE?U2s-8(c#_^~R3|f_i3hcANygKThyuUh(M6iHXL#jx0=)hXrdY7NJ9g!gTH11N= zg0qm@G-{FJt-AyYl||z#&{yaMKLH)SxCUbb2Phin){3;~c3fH7v}Puj_<=FUoc$8) z#$!UWo|K0=%Xa7p?p;s~48&|lu=7m05}m28GqF|498ggaK*U)xW;Y+EBX57?$MEfM z=)bx_DStVsL$=%>ygwDlZ&|kED|;j=+H0-7c+_`!RdFraP`b zJPbZ8?+F?ir0ChLg8(t{=F~4s?DjlA;A4Rt@(btKfM?jbU91GEGnP@uF~f`X4c95g zVhcOTk;4HAQWqbz^wYT?wxvjkWZg^pz(O~eww;*1R#IreIMy=nibw}3ZN3bzzeVqL zWIZud4rP)J5=S4$Jk|r?O^!DRgys`X9hPNBWTol64BEgMXi?E!8IXU1fc(Yj#=+Pw z&#ua+&31T^ONHt--%ya`dQj)xHy&ESwy|p0I^%CNfXvTHEy=j`dpZ|rT?Vk_H@c51 zF+}ZHWR0OhYenv)Bo($B!n3)TV+veAxK>OS@q~@cR-gx^$i%lQPEOG!$}bY<>{@ML z?hzerc`F2>p*Tyck3oUYlfa&ReNU(}x2hvowTFH>G~Le@$FxiBZ}qIs4m5$eWJW{p z2r(SaO`!0=yvad*lqs8~x=S9V98F=g)M6yH* zMgsoaXE|(k%LxQSkJs6^XoNs{6NiR9993FI-$&;{6#GCvVee5LGu#hOp{!JHm}Sp- zClgRE-t)~281r-?1`%hkf1xt-bvOe>D2zM4(aM+g8^F}9GNSpwi994^y8(G4) z3gJVmsn;2w9p)G+$e?k7& zFCIRnx~r%OJo%*Luxf9GhUYjdM{-l;e_7DmWv~Y?F+gqa(6LF26xSA$`pInIdcLOm z0;ngO1&tS{Ap%&TbE^eVFe(ZH9EF;(2-V(EY3-gDNOjifK{}H9?zN)oWLd%ks_W>W z#@+??BnY8x2r05^g*)%8-2*l(hH$efZ3TZF0_EiiS@gjTw}((6w#j<&QEhy;N3{|M zeDw-3LfbhoI6Q2dyUl@aS#z%H&Gl%Dv|ezB^4zaE)84XY-9$bJM_MC9a^s91j;%D+ zY5w%6M7CZ5elhq}?;_&>B(WhiIp}t*AXWiD4)oV0pM?1ld#{KtD*o>`b>uX(-WC31 zM}KyEDMA0&RFwGj>(}|a(5!m>4lSf|rD^x>zB$PrX)oT<_Xh?W86* zx4wNr1e@K(IYC&Xr%^dQ0r7UWLzjegJERxvq`ERj?jZWkmh7){JeUediE_Pgt!x{? z1G9p%^GmAZxb~ZBzottq&wO>vK?|Y6pfC|u`>I{tT#yUmG?7Ynwb;F-XN6g?PD616 z72W4DPNwMxG9E*>cBz$k z#zcH6rs0UJcdn`@Hj?@!z1tHHl&&~^V6F=-rbzunA9(yyzkHDu_foN$i#A+@CR-gd zby$wYSX5XmPXrW0Mp+SCC~WT(e{?0GVu0kk!trZEZ`LN6V(Prbk#xsVSz`^i-}G|0+X(iRZ5a+^53X1 z#^M#x`nA`}+OvoDg3wClg9J;5K=kXnd!Kdz=sLe7{IR)78Bj7g%?^D@epX0T!fT`M zse@v`yI&cI?BBw-zX4tvit1BNoz&`H4i!v~&{VB-P-Frz3V=STVTdG$jZQc%g8lII zt3X&1mUy!Dt=`T;U)+QY63T@Y6Z%Z9OY1M37bT}T$52I$eT*9*F~T*cXQ*k$$G zp(5szoivpi7TT5lG`xK!hxMa0N|p!^lB^Y-a&TV{n0bx+8uwAziOb}Q8nBgp;H-r9 z7|+d)_7Yb&bngHPVQ7eor1oaE(s`u*Wl2>9;z<-4`}VoSXegOkYiB|LLo#eDuCtdI zhr0A&E=wi8MM-%R-R0yYutteI%4~5j8)`b}mLnyqYCvknhnzhR zRkgKlSsFZ_-Ih4QFVPMal?)jn{%FDMx;#P=L6&ciiD)y7K+9^-DwN}9L}+UmVIp37 zN8lcS=CWeEYL8#VDq6S%CZ3eVZV#@0vV5C9u!WHj2p+2H`Bvx z{nhw9YeMc5tkAZn?|taKDzMN$CGWZ_g}!gCF`t#+S$Sd;i0w|9w`$f$4|;ZldVog*C8GpHlA?cvM~*y zP;4c-P!#0s{1T|W*0NWuAq2#~LmMPHnN=Uo5{>nthB%84hO>3g>yP;{eEShuI@U6SJB%7)^YR0P3K{ zWOP1-DHITx95zGMJCS+aAu}3=JZI#u;5+|S3N`2)Oo88 z8qky425-*dY!=TiGahP?w_+_^_}mi(sFE`7iv-lF$_!bq`A@+_Ss;i?*HWqQ_oV?j z)iV3q>vD&ruM!VR&%OX;8h9p(k$$?OqNZ2S`Z+(*fH6&sDRQ`7afpMseIW?a@5^e&4+ba0}fIS2@%PZDPxuNjGG?v>r`)j?s)VY|0e^i`lp^OH~a z&Tz79hQrw}MX2?7&h{j#=As6Sa!OpxN<~&R>s)~J5E>JsMreC>4xt5*pJ7C~*I}!m z7j(y#qeYJb8DX+3n{a{8%Yo7L0psBXa`5>@A1Xq&ST8~nS<3{Z3|MP|fIw{;R0E_Z zV?b$v)p)Qm`Niv(fuEexGq6HzPs@8s!8HoR5{||h74)dl`vc>qS0}pFv8%# z3oJWpS%S@g$4%@HbpNbcw}>>S3?^N(X=2Y|UyZg$QEh?JtM}*{+-%@5l-Ubp4XOK> zYF1tVuSk3_v~WJ*UduC2v**34b#j#ii`~u{^MrlQGO`%u_%axG7#$XG2M7-^OBhq_ zfDs8jn5Y)}K#(Xp)p}AA$pQ!kXcxT-N4DH)sy4FuFcAhSqe2rFBF3(m@^`7gLDepa zR0y0lgs>99nujZ)2#c!u!&#mQ0;m&CR%Pmd*GpbidH@2n=$5i*#A>3G18}xBL5Nm* zzAz3*>T_MKsdnp;QrIC65qX|ez!Lh}Qrl@8W^_l)an~=fJ&?fF6M4jGHz6F7;JrwG zXpJ9<)M)h{M$^9zCi*xp@OM*Tx4cI|Cc=7J{hVCUNEzJ~Lmd{q8#|-qzMiJbfDukn zRges9I$hzaKy0}V|0Fy|mAQ-tqpDfFR!}kzqR!mdI#O2Ob0F0_OvQMQ`ZI~ zJZ^ObOyD(mSZ;v0{<;vGkHezO&N`z$4S4KWYG6K@u}}vxg4g&K6EWH!0;hsO|| z)hL_k!Hj5eP@}w{gNr zqx$D$^2?LDa~E9g-E(f8)D>b~WhZ}D`*{0V;3t5>W$hfT5ZDddIm(BP%t9QBO z*dm=8#nh#c9K4vFt6)JK7CG0`7%us~NRc3M3KXkyzFyEe=|-gX0kpd?_!dV=DqAvbBxoEZk61%qA5ifeh`W!E7Qj|B^7yTb&9Fk_ybB z&`x60bZl*l;4CX)wQp3d2_MBa{u#ZoDn?JAc9Qe-Kk0;ju8oYGb?F}f4z z0QC%V>=eY@t^hK{3X@H&z_S0OQs(C2hI=h>9NFMgW zPO)U^BULff!?{tPKDASJ{gfVbG6R*W9r9yB7-Xr2n_zX!C$Are*Pr4|{yx0@?zBUx zp!YT}#P^*jDY>Y7gQ9~&03e#4?r`5z9%6uUqDyljhl+q3*tNHn4t#Fx+JMFEHkgWK zw-%{3y7Nnh=|JQfsv;VjylFC}Ipb|C!6pilrH_ z>2lw*0~J}o_N1Ts3)&?dYHp6?&G3FUEs!KQ99$FPEW@b=Q9!kTySv80+W$LJ6WeYi zZO>iETfp8r5WSLzL44*&ooT>+4;-U1O{tMifLy|DG4`ko)kfzB2 z-QXzns>FaID6t8L_uvSTa+ryIDyJe0(U~l7OmMj@W z7-e6oJ2h6)aQ?uwqCbzZ& zCAO{YX2D@RpwOkJIlEHRMbXmGZ-hj&NWtp-xK8kV~x~S_lp5%Q2-hkkxOPG{`5X7XT>Pcz$GB zZhkWwK#!T=iF=*4FZ`*e+4DC-_^l?)sbpCyj~%O~yDmR+LidKGKpuNZMJKeGaap)pnL8HUP;f zL%H{sqD0?)T2qaVE47=eokT{}VyD4Vra!DIwq^?)ayfA-L&4g*_~&r3rFoG@OIM{A z*9?E`JV+j^5uqfXmlMic-YR1A*GvI_Ogu&GIW7};fbF2;&X{ocO;gd@%a*+zy^vi@r7T!eF{1%9{T%#2r%=O zBx*iP1a)KJu#n_midPL3`E{P_^sKSm`XZA0x2JtJ6<2ly%o0|Xq4B0K=?<7*{v34! zn=$=)Q}1dHo!TVXCVZ&Cua#4x_qf=PI&pjeA`_J-w)=2N2XY%vinY%%_$fltZCP~A zrn35H_b_gE7&bk?fzUAx#r^8O>uONDH*|*bOCPJp2ddZ89a-p5nP{O-9I05g>_r?4 zSOA;QLxYc|HYp$B7UF>5?HSP|p9T=tTS-#rq{jXsh*&yVK=(KXt8rFW>?=Mb#$4n-JHL?Eust-Ok4F`temcW# zVl)6(uPI@Pv)7T4va+@Q(L*_}FJ86I$~?1aKdo-&*uc^0yxiQcpG zntP`m0?ijvsJ{Of`SAOEZL+lpm7B}t4>_?x!qp9)pb)J1fs0y!!kvncNkZX5g#)SM zvR5n{(R+arS8_)2Iw~|Xf8GQaOO_=0L8-n89v%s*Q&$f=z~n7tdQu6S1;7{F&=QH2 zcqdO+o*WQYZWOwCX$@?;#co*x*33?tC604{XaW?dR97u3suh5G*me5VcZk5eW5&|*;-1+nO#uSOM0gB3Bgldd2W5l~;8E;k_w88A zeXZ4oM&gQAFIOgf14f>LYIaD!FJo4h6m?c|>!OTn6F^64umJd+O=dgi-egidHJN zjW}Oaw{_@j=S4g$m*3J!K|ZmNybSF^>0gXXa7Qi-X6SXs19Bv(;G6+yWD!THhWi&r zKAyB^^i^x?mrIDLm&d8l2a4#zN7ivyb8FoCjltjbex`@J3MqXXTqz}lj;x5Vz1MB5 z)}Y6Cej})YapLm8E#^7^4j12`8emayN+nYR*jnur=<=|t>njf|Ditq~XW>RpDA!50 zz>La1T>`89!L=}PdB^19Ea84{8vlE!^XU;03f3Orm?5`t2&-x$NQKY3lqDsbEnI5L zu&+)4GJ$#mZ_U*rE$GV|R@K<67W6EyUAxCnqgb;XC5O}Zz8C(&4nj*dkss`X=Uh4{ zrbv2?p0xLu-v8fkKMs_<9A(eK7bL5K;66QbS}nJa-DCg&B{Zs1v}7KcDC$svN>Vlo zI()&8;oINH%Ud}RHYwdQkE1(`itKT#NIs0}?C@1^_MOl)9H!N(#s3Rj!8j6P{9Q|I00EB<{?f<*j?)Y=SPmn z0Bxn)aW+2`DGcxRfhls47X`AG@&|N&TvZ>`j=ih^GM_MhMG(8f^~!)iI@qxw4+miC(T(Bav2kr<;{Wf8K0z%hHs4pqqLGmD3Bfn1q2r2kX+-@a!dT~gvxQK*uLzRsZ}_1AEfG$s;bba!G@c%)Mo zHz23yekq5l?8_F~AldB04|<6tJMm*RJTwZ4k&{n*I3O~ONyCt-M9Q9!6y5bmkUckv zpG)cj6+OG$!L4l3k`Kdf9C4Th9lgmUP441JwJ7W-TNG?u=ub%=gX|Z!Ch+5mezvb9 z2Kwfy+FNSMm(9-&5B0^pFXFW;klW{Np#udBIq8}SkVwQ7XP;yX zDbZ!&?|)WVvFcReZ5(zn_0E3v`p2BAfQI%5LIqwTwYX4i?XV$kc!x*AzF_r<@hpWd ziL8sBH?&zqEgc;48gTn2GG)NUYd=seYc!QeXd@EV2HBeY1Ap^3;cx!NLhrT`y{SOQ ze3P^@Tj1)m_UodFf6C__r7RraqkU;O&i7G?r=3?Ja*(9uv`Uz{JPg&EfeH+<3ok3} zKHIFMs;Z@=qX<{uska9ia!U)98wlvTf~my9@lNZ?6~}JbL=r(0)bvelO64k#YL&+- zFEeC+Do6k?jG zL_(*yESk}%scNOdf_BqaSgcVrX^EHuyW8PXIrDAY2UP%9m9v5EnM~!ac!RDAx3u#T zXQYj!FUZIq(cm_hOzq683P?Fg@~D8(03QxAgktLKn^|NMBnwL%VYf>lfjX63s#CUm z0e5IS)ihc4qXQiP_#bf3?WjQ-;3$YCt!pPy?GHtQ=Y2bCPao}iIs5LpouK9Bnk9kx z8=92kj3OI3^}`g(O1B>7jj)&JeQz{eb!63G9?BysyK`BB3#>ZjV`sDupO^ zj2iVIVQ(vD1w7Y{hv%1fkUp0h?|1J%58wR#>6Q>Og4V9f{)Z9#MBm;o22TFmD!t1{s#W`TF;gf?gswX{F=3=$Wo$9^e9kX4uoP{_F z{iI4`Y#*vf?TRpRyxM%Q-XFz5rbY+0J$>gp-wEIQp5$j+xCWXffD3+1<7#t0mb) zQKx-3Qvm+x?a$#ggS`M`eCA1R4QkVCkpOa4+I4T}%sAUi%Q?wuDD)Iyl+lFU{Ysni zu2CMMp^AZ+oH1}G^Xdspm^VAByC5-({bjEJ&0|^oQXSeHzkK_Y_=F#$#nA>W=}w?K z_G`;Nh3Yt!WjiYPtmvC}8jU8XId>O#6iz-mSY0T0-d|okO_dC+>C19OjW+fqqo~_i ze4bUAosHWluZg`V%V+~qk?@yU6}BdTtK{v8wvIgCa?TFPtXqBBx%t$_~>^4o36 zg1fG=S|Lj#RrL-sjD&|Gaj-&c23Qp5slkYi)7vgF(6muG&WBEU^S~^g+(>%ny#En2 z3N&C>wQTU{$W(1{LDpw#RP3z?jMdl$9H3!jtri|OTfu@b0a{xk5KjP_)sd~eI+xS< zp0tQrm26TAM1kcrZRw>{HM9j<3F~MoNOEn!pRk>k zjdtzY@OQl`AXJ@tk#cKA6xPud8*2JgRcbi*{v$xTvhuX-A8mML$%O}_C>1In+XYnq1Q)^OT^)`@=A#_3cjM#Vw_E@z&Lg9d5tLFj)x?^Wn&(GnR`t2EkDu*yJWCLy6 zqiWX`J`{3ocO^TjyWRSwWVQRIRyg@@wiM#oO~EljB6fRLF$_!eC)q(Y>ke6X_p8)Y z5*$ZOt?XsX}Sv`!@6&~s5~xiSyB4;l_s^%FT<+=Jo-7h;_)qa;u{}g zG$$m}rLufs427dD4jnl21RelQ0_)YaOs4gY<`Y817mCW5qMVOVXV^J!-eqrlHiZpr zv)pXtb*Ub_sQ?mkG%3~obxIy9Z=k(Z76$fkVfqC=I2%QPhj8CsqZ&1%nYu+QkuDJm zm!SOZoEw}|rHX}4`;Yc3nv1;U)n|8g`T$MyJN7bvXFbdf9z#+L98H>5xe9q4L?!h) zY~s;+)s9GYXPzVnV%zc@YBBkVgFNIjF9v8Ol$_jVO+F4(uZ|7>3n+;=pVv+29fV>k z3hwk2HI=rb4gMsHWJ()nur+v;tQ9y!$Ywg-1D&ZB3;{OA^vR{+G0xN^kmDB8v>78s z&@_xxUC&QBUiV~hTi7737haEoIS=oKq0-<;OtWP=gJ!TEq z9ZUdi?;55AstCZ90C*|y1uU}S9NE8st#2pC`=7!h>t7)>v9T4`uPXUM)A!OM0X@r4 zR;lDDX_C@4wy<^^DpxE|g+i_FKz5r)_1@grjr>LUph5lu^v1)&Xk+dRurx6vYs?kV z6j)+K_N|;@u`g1Odjlc1%~8oXzp4-PGS5p?TD%Ddp~7|j%k!WdoMwRf$Spl2A3Tau z(`Ph~rPgw>vLbg39jSa0^30xh#A1cI61J`vbn3DdcIkKOuBdbq4kL_1$|ee`XuB<1o{S>MQ9<(-3K1{ zUT9bV0MYSIf}Kjx4jb#OhG|YMQFC<1Xa6p`6{eynpA+PHBl=jLDHt^<)SsR zsHU?d^J!eQvor)7sB5%ImFmc<70kwCoQ7I}!%=O=Gvw;TIXaIR~0 z2UOV-^#y!(`;Gfh&Kg;McLn{sWLCR`Cscp6&;4tS2lh;EN-^3)V^wa1qS6}Or5+%% zyyRd{aZ1R}7XCD#Q_m7+SGtNI!1pc&@Pb3v5T}464D6#q&2VwIT|_K)@KrzS_4im6 z8Rwc`CplJr09PH}H1Owg5mfc5x};80Mb-RqU!t~RpYItxyB=}XSt_#%T-)0Nm-{3K z7J>Dl9!|>U!~hLJGo7{PbuH5Fn0iFzqR9F~4+?h4Npd)lP)LT803czVxZ9=9uFOur zkQY_6nu8C#F{7~U(##cm&cdE6=tJuXrea_PTlj!Y)x$Fi*T?!UN_s2m(ekaPC)zjK z;nLwGnNk6%b;w|c;>T#=8d?c^wic8F%f}FsD^(SR(_i-RlB4GIK=Cb!?aH zkb%p1g)NWj5dcB3-O+R;t_35$Nre{c#H0C0UKv4bsfH%YHrtt{^JDgWC1E4yvgHm1E1w0RfxF*VMW#HyK*dF&sMblb=N%3Vct+0Zy`?5c zCIwSUly2(KQrh!RuX#jq>(?FImGf3myU|-&Rcz5xp*GwNis?GG9UEFoF0|!DL z*a?%~NJc5ZwV+X>Q?C+9F4tnbvpoZ+^_j{CT;vT9OTuW^W*KhKqom7cAH z?|g^jHmFv!1H6J?{UZt9+p5YQ9jt0>$vhV2h)RYvW#{KdsUq)TeB}AW3N-YGY%)JuOUsS@NI5OXXV#umB3GXtJJf<0G_m{JQk+Ib2Cf3^PP)fgs=Z?J7He@3eKZ z0<4Zy8aK7ummQBVGH>hBI(wYKxW5SAwZ&A>lsdkqWXIR1XGr+Gt4Z(=So8pQJ8370sq!G})u}*0k`a&lLv35ee=(*;g`nma$g0lp@ z#H49~X5#V`KU2SD%8SVDy#+4>*Fc@822wVsIu|_~)d^{V1J{|;mIpf$_b`Yxb$r>! z+G@Gj?|hQYbnS^oU6B}g$Md3gr0iX*C_D`uXufk#p#CXS=z_a*#vGN7_iFT{&b=-h z1;w9>A_s5YB|vNXaZ*pXe2w5)!OU!u+M{|RbO0#Fm4?b7aL~M`(=?h^)jg^skf`7a zjkA|Y4~k|kZYWGeGCWjO%(|bSzWo_2>W^Q)lKrCIb(VypqLqw63SO$~sc##4chM46 zNmFc8sIpqjud&NX&}@T48BkNhw7sZ~Qg|azL*(fJe(i_YH6lVziRim@)jE=y8^E?DvQtMI?u;k>cs30n}jOFyvaeTp2Y^{wsI|x-k9kQz3d;U4OI=kk^%H1L z;MDhCrZr2C{NKrD5^)+$gczCLfA;#>+mB(L{rYn(h2OvZ{{3ff zUmA7tPKoq&40KLklt){{DP>7F+M*%`dqm6U0lAS~V(g;g56p$1AW0cP@9r^L$vzMU z>(M2@sFvWUCflAt*PG72Ol9)Z{|R7I|Je(edKQ51kd|CQ3fhwPH`Y6P^RdEyOn_;j zny@#d)C?f>JBOZ7_8U^~EW%|&sftN386K%)k zQ)o@u7?iH1r@a2O?nMLyB>ViRo&iAv-1L^zG8hReoFd$^RHfDWs9`rJ7jaj)ETRb; zYfNkUWt>cH_g;NaG=*J-po{H&hw&2ovmIiIqy(q-8cYPinr20dS)%j=@CCNSPN?dw zY5<9o00a>|*cy0aM4r^s4yrX9B|Us);EC5rG7qv=Ua4~CV=&Gpd{x+wa@K;*Nbbr4 z$^aN&oOZzf$4b=hL38`6s8pSo9tyFWBc(3#s@iVEK-DUmx^fAz4T4npfupx3zklIu z3x*$VmM%$N{_eXyLQw83>7}(^c2#%=;OqqhdnN9Mn9am{J9pAu)uRc181}L#BiG$hc`G?N4iGOE}# zgj<*!wg40Yq$NSy>jHW<8mb%W|8pYh-wJfg=c1Z1_)!d~J5i@OrKBhA2=224J5+Em zwyXvmh~y_MMRX-Xw#NGs(4DUR-ggxY8Y*}3c$Q*l@XDcu(Rj=fLb3b6eFIeITK3nY z4wG4$59kuvT9|euuokT`1j=j-yMi53yK+2Q&sL7%eM9T^f*foi!m@{KKA$*qr+VR` zD#!X1drhFEWP=M_Lqk}VmsiK)LgI%l+&+8@{43u)S4h1aX{vdIOGL&23{(qIkOpCL zhOSWYPEl?%7bhOrS@P?d#vRxy=pb>yZnA`6%W7Xt4#yw8=kaxiVo^n_uU>i4pnjID@009>uH^^;gfg_bVqKijO0~>-JNsm(PkP2{dewg+-ByKf~7)Wt- zB31FrKo`yT|MK=n>O?;8rJ&<#lFRML6D( z>NcuHV}7ZqkFIHasta0-Etw~@1Sd4Wdv86}ioq_u0_+#4Rm__Yv{A*HK%5`8nEvKM zE|c=zed9?D3-S$KG>1iZ8ptOpbQ`7SH-cww#_htF7npsZA+bDyI-~)`+6VD-6{%7qjgEzm!#ge zf|O_q8UgZ>k|Us1cd9ii`CtlKlj#*$biOHiN@@KJWc zCF#nWw@pCvS@DBbq~gpuzFsQ1?cN2$pw#Y#I#ii@8)!D}a0Spp z?MA-IQA88OilBU)Ej76tkWD!k2kpW!r4tHrrRdtzlw1kI5er6LigYJk8kOwn!M4Dv zLozr#V5c)()M8#$n-3?%Z^CP?!{2}M`iJoP+Z^?FXD^$qmF+pKCRV1sg14;}hIvQ+ zB&s9wGN~yONN41>4}mi%2G?uvw34fw4GM|o`uV`m189S_M)cd#S&sU1QDy^n@Urks zX)gPf3Qw8#CUqBEI@OTXYBp{Rpm~s2rtx%_Fl^#eS7!Tn!hT@^Kor-8O}g>?I0&go z_yLN9Z#ONyy!C3(@~Ucl014%16Eus%tP%hydJY7mP#u7PoyX{^QCYh7fS;HFJb;3| z+X`Ybi7hopP##f9wP>n1zv66>(Uy~%&S>`#6KW~QfXG%bKa#Fq{n%9oepNr6EZoDA z@QRrxaxI(F;yCx;3^7jG$d}%A-XN=K1%BTFJ9D4ZsN5O7XB2%d`Nig4M&n7TO!ygM ztfOg|8p>mxUNWKLAeOIV#$qXk)(s87|lwiTwLI(O3yI2W!}jv@D!Ir3%_=QLMS=je1+pA)`~ z%IjIk4VprO0WvXJM8lF5sy5dbEfW&7;#);Af$!4oakI{ZJcFG9)W%r9|4{vCb2U8l z8oa?#@2a(we+m4+Fjra7}!f>W|IBOf=1;%6mjgfy1Oz-U592m{huL|^YM3b+QFzlsc%R2Y7Qvb(Fof7+^* zE$&s7t$5}R7%p9-Vgi9mfmGbsyPDurrPP!injEB2>-FH zx?hCXKcmK%e}0Z1ge)w2qkVu9aml1+m)(GH>&)X3>Y`Db z9EL+0YZ#TuB3|g2^+#)U@2*LDRrZJkdpS?Fzvlh#&eP8TNkF#06*XhAGt)F~jD7Za z0oy9=1BBv9=zv@ak0oV!LEy_OP{;>Szz+IR&`EIgC9o4V{2mTM<#jHR^G`|Y=7w-n zU+Ho`yIY(@pa-yG>*)isx%?X%{YG$TEeK&q1KY+;NupSj*GUl=j9D1ZBw(RhG9J<9 zkVM8=RU`A;C9wEkytRb(&PvrQIF1b`748ixK5a*17>!r31_!)=Zl#nX!%%g*l3?w! z7aLl|=W`m4pi37KzGpAo{M&YDyVTS!hZglBkFU9c*blsCUI$TK2IB3?3Uj#(EPjFlP#YcAO?Gel@S2MY8-4FfQ1a=#i3fWtwfuB>6| zd;j6|5-jIK4c0o8LJBp9SVP;vbnmb~rZQ3oDi|l!1D+@ykZy9cn|LYKOuqkDv>nj= zMOpzoo3_voJ#aLFjRDj~Y#%k3v)k9p@;1=kIS||+l`j#|I(Z>xW-ShgY79gRzk2Y+ zKVZ~C0*KV(hIfNN4C4m2qz$-v3Y>k$EBojyn@KA2z~&YP27MW;SL(dr#AQfC{r2?! zA74Lv|Bt~iNb5EbV6=|v^qB_lZc2eChg2aNp(~PyoV$Z@&u$GjK$h5Tz6o#az`2nd z$#K=cynP7~x%=#zCJKX9+>Bx zRb>>G#CLZngNmt6AMs8H_YSGpRDs;PoS(9En5`muaT#ZgrPEVrW}U{yBQ*?jwUXe~ zvP8~)=dwy~l^6T(!`sgtH=kd1MkjWwntiBBU-@c9@U;*fE=do{iU`brbKVy2gu@v| zB$Alf0&XfW6${`}?qe-)eTG7+JK$jmcHt0P;UX3Q;4BPS^w5t5JbZ^-MmFb>oTYcX zlY)tDReQc6VHa+mAbXX3j=@8IToNUUo^4LHQfJ~gHLgJ*8^i8ty2Me-JC(@Q@4bZT z8IVUkO1VZ9ALMGEU?;=n*YQ*mTBoA}9#c+dS2;|m{z65m#fpYLF>0mo+y{8Ruz&*G>8M=$vd##Kn25hz#kf(2rvv;o8~ zbpKox1oS?7GAN2UTpsP>Ax=&xPlPp=Y^N1?={R{6w4ej%i)M?Z`G*mVqbscQ7iZ1v z{Ny&X>rNLDcs%u@hm!=zlGA|`d{Dmm&D+n(D)~5n_a9z=2ffzc%m2Ryw%)`-E>Q8k zR173{wIw&%wO-z&#G#8*j)H;rvuuVPLq0TVm^E^a^ULzpufp4J^81$piFJLx`x?>R zEDJ62EmDXJEEynZ9Sx71&&Ggg?2VG#YNQ$uCHFNm*)AF5mM<6>)j6JYj%*_i^`UO* zcam1lCuLo1==2P#^5_U?Xi3Yxf5HnI&u7-?zGGzu+c>i!xJnyYnnq45#U zZ=_2gkg7)gDHE62gUZ7QgxRg4&L%KO?xnF#IGa~u?WK^yz`>w1i^@R4Rqw$IoM4vP zln!W`GEaaBA?%;qbW*QXr~pna6!#=i-0CPb1rHPi@cV$%1t;xMSdOLvUJsMvUkcEU&|84n3S_MjD`0a7Z=vb zO&TyQM{0}7I|O=u88Ud-hJkXrl&-+0IemVMP_5On)k)$uShwhgcwc*^mJ$xwYo9=!Atux?t@&Q{e0^$W=mICwK zrfDzD*hcXncEBwVcPuW7N}{3R$B*AWdHWKgbgw@O`r%^)LBayJeN<%=Vyd=7nsKS# z?ZKguig`>vO2IMW#~h5pvA4~aBzLCbsX5osb$Yl?7~UpNjS2#xb2^ksKYjgIN{Iea z(vh>QhFHofiA83EnQlQ1`0`hMcp4*6;di9V7y)wjtB3O%vv!fB*c-b8WAL(Sf=AM} z(}xe{@CLVATXb@DCIlD42E4K^aYHQLSpn^RgmL()O@=tE1Xf_w;fYX%!2^IKeb^yn zfg2`U&g{5WKJL~4dTNXkv0d87x09&1&+^i8IP505P_4Y_k*FXf9(LNs`M|ca!|IzK zD9gedyLY;Rf)&bdqN(jND3$VP?AJq~p+}I-cK~1wmcm!IkRa0z@|4R}Xez)C11z+* z3UIsAEkW&~GdlMw*Gl6cNs<8u^nfw$KoHumpF(n_S64%=G-{QkQTgdbfw3?-|hw-8dov4$kG-EE}YzF3ItA z^I~1)ta~LE^I5`9?R55**tyEisPS1ANJF_JQ%bi|f%4i?iHApJ3m({IiViO|3X7LA z_fZ5hn{J9>3{aUa;_wwRE_ml9Op%!_4V43#E2_AkD>r(4vYlq!dRtj(dW_!7lLSx; zn@fKKOwZaHn2lPEJ;NvFc9i*RZBp>mkE4|F@+TUA#eC%q*F9Ak@wX=#oHJpeN{Jbc zu@N8*JfckRIp=Sez|pa!!f1Q4IF!VFKdB4XU^!`>kq-HH{ng+7UHH4dD*O0f>0qh2 zr5ypRSa+^jRGZBW@IvKQE_7?}-K0$}OJ@r?%HDK1lI}i>KSy;waCJ}EvoD+pLmxt3 zT<&ZBdcW5DsxYoV>*>9g>~||5*7dS)1*tHjPaZc%GYx*lX+Yj*k3|Ys$eZ^hxn_|b zv_A5$c~tk{=>B`JE&Y6fFnyAT56fN~?J1IoJr6~a=m-FujZMyG^T|tU7paaw+Yzt~n zE!+ImyqR@^I1{1XQVVGHnhsj{%4~l7Jr_JMAX%{*(=tgzoWZT;jBNvBZZrmc6Cu7? zJA8K`1So+4Q`lC(;b;x8&K1z{73&fynl|g!d9V^v~Fm8C48HnvEJuuRgnB%#l zL@t+G0WXt9xi)W-h6CjwpI0F@s|4zu&6+h+2-Pm^#R zj!Z;);T-f7nuF0e_Jj}K3gj1M+^J{N%z4L>kSWc$4|+n zbl{1zLX*vZz>uLvSan>V%k+0rvtW8;;PVJd?l6Fl%Ny?psA}X7{GV@WL*WW|JkjbG z0iFjELO#t(=a``Af(LkyDog!nVYJcsZOdUKSjDz$lKlR zIZg5;ugD1O@C=WK9axgqLfWr2pPd#Mn>;SaU3FM7^|Iw*_f1_jw3PGc(?UEzrX3e3 zq~Zo5NF{{8m5#vkbzf)nyICM(RoN=-TUjM!%BekhUKE1^=ptVq7$lAm8659@@UHP1 zv-1-BE%PAx-){AfF`ZlzP1mR5gAd+-5=Iir;Dxv-fM_CkKvBbntK2l612-2KR!SV@ z2vC;5k`6K>t6-_~60R$PZ9|pHiHdJJ@{@ndfb^2`e6R7Y zB3|xJ=sw`e&MikS1Q8$WLBLD0SyyPLbS|yd(qpm0$Sm9sG5ZeYic|hD56`_1HTz9H z2ZjnA^f9nnoTz#xY>#>eB!M?2K}G9_Ts|CZA5hK_Lf@tx-QT*hv2t!D$aZC`QqBU+ z&8>$Z|G9PT?!Y5Sif|&l*nt7YBa?}>I>+sCsG#9wdm1ELmOQ{ts9v6#!3DLSwb-Bp z$ghPCndpe;2M;{g>nFkFM60WvM7I0{d_Sxag@tBENSHTi6a~sl8n0(TDFTOuwIHN&Sg4XAv9-e z{wi6dwume}e}bfdAE0eK@T$;LhEkC>842FXRhI=WkcQ>RL#w%A9;)i07_8UHB(i=U z-fS)wy$`e3QkJrlyT;+BDPndMP3}At8FJ3yZg3PA^ZkDKi*K8qu+R4A9D06w`oHuq zUagAMQ3n}LnUAx07K4uYIqrdj#&ZSVY?~@I4~!)21}x~^E3+y+j_8vDsiO_oQ&?T2 z!K@l9CssFf^ICV+pmpzFc+K;Hj8My|Q%ifnE3$=vkA5+d1nhh^N{@!T6f27VZoT5% z)ra5~7{miwbgOdyCDj?#8JTPh9FR$t%%FGQyc1wqK<>|kJSeKjptr*JvFLS3#d|%y z|5c z_cU0|_nq&A|CG-TZUfi_66*Mgh}#QYtkedt~5G^#o?6$ zu;fgOi6Uj(zf$O~Z0z;LIB;=&<|TRS9jHlz)$RwU9dvxm;{$y=c2Q(?8W|3ND@jnu zafKJA6?$O0Y|j22Wlbx3w`Z@is#ln3u&y-hFev>fktR57h(F~7jZ%-6bEzY4REL&Zc0b;@2 z4`|+yw+q-?OZb%B+MDcnWRf<9kiR}c$BQ@2*I?uZC!i&K)k|jV-qpj=01AlJr9xqV zRCC^Kq?6X{AG^C@ab5B4NIn;?Wm(%3lkg?Y|D7)B z;5U825n}bjJ#1>%rej)Kx>S$s$|qNjJ#6Pj4c9|tqT0)2#ND7sV6DCN9Ojk}H{$|< zd%YjK|M7;9S>iiJbX&RC_1=W0$AGzU$vRC*3^6tAY=faEwHE&OC}q|O9v&=8)V3Hx zQg(6$;D1l|%^o$Rwc@6|Oy?v`EeQJ9oK&`HF@5=2IbZqn zA^5EGA?XXq$#xVzIA&I@QJi|6jXtmE@JMuy$%uK)PXYO3uHE`s2s z0jbv0P3Drk2ybw{8u>*c!i!3ma}Ft4e6&j8?s9!NWz50DzpgJPMW?MzYmcGP=vqG$ z&?JP6kNjP|HUO3~iKJ^qs|95KopOU+F?y9>!$Wsbv|#JcHrp22rrkr5^T+PTRwx>3 zJvkzY32wX_ds$_d0woj)Gc7NGa*YUKn?YU4#uq$wEdvz>VW~U_Zhy6jw z%-Tr`9MbdwVh&JBDpHw5;vX8~DW@L=5u=o#AafSk# zO{y~y6fJh*exJj>O2P?xTIF0Csbmxm+i#o8g=Ipt_XD$$5k`mPRLVZG9Il(#)Wnha zq7!6WfM?mn4eEE8`(U_|%Sbq`^==ENjk!ufffRHPu09Z(nX9jw$arhY)%?eeX{6@& zRm06T$r{><9_$6Uv`7#wWLI`KSZcDWseYdA2?o?p*4vf`?dZ+afCSmlr+8l+Yk*4A zE)Vihk>Ix7TUC#72GEl`V~MwHKQg1(wFSNhi=-U}QfEjJb_4uAw$}yk^lCe<+;E7VK0v zp3^les%Dx^K==Sm=d0$0o1DK=5I2NmK$7ojkrK3H+Sq_q11A&=et6Hr-OeW%Tr5zJ znJ5w)?g@laB+XhqaFsXi9HvQUpeDSE>}Z?X-u({)kisEJR+O6w`K?8`kgjMF8IBAl z2w^_Wdqk2a>vMqmSB@$X*}*B>Vbg#kIrkL?3E=5L3_LAf!C>&d@oYPT@7+m-IF2fMXp#@!?4@LsY6`33Xns{KBW!-B!U}3~ z1#O?%VfTg(KM)LFKXJV=B**)N_9^nI()xhMs`{jvRvdzQoK(D&#o`by)`;3M%buY8 zyTGn9&X-`=WXUc{@YmuK0~W1B=$NP!oQ6Ep;p#4_`y^!?D3yLqGjsDbRkOEs6?|et zZQ#J*%CWRpU5P z6Gi3F*0s2$AX}EhGdNTu^v{w=HW>LvZUJ;gOoaKPx36Bm3i(6+Grvc7{+gu%Eoy&b zo>+BhXf-kD;4r}HjpRUQ%UTw7C~oDI2nf9OXqH9NH8R?TUZm?qHCHTjNm}Q!XG_#! z9pON_k#kc`X;)JG5HSVfnPaShFOmTA%@1v1XepmFNQmo6GNk>JPAelTY0|t8W!OGR z2KWN0ExW7{HNi>oZk99p#05&-JwMA&RLz!($`LxRSk6)=0Lx}cXs>4VowBDb)YNv^ zNg$+~nZ(O?dtx`vG7%KJ%=O=Y^v&N>f(*@6NwGE+K)*Bh2xpF}eQ-4*{Yggs=m7L( z2GvOZ+qh&tlT=AX7A#VAX!dbch1$}Z_aG=fVor?TzJPQoSe5Wp0~_VuudSu-1hK^n06c1(a`tK`?nYB#(mNX}C_e9<#yo~=1!?=!6Pq7!Ub&?~XU z`4rrzPqLoCGGa=N@lxxEBM@(w$&HDI-ip?$_p#HV@3NxHd1h_4N<8R2zMidNj?k5* zx~#gMy!u6OT4)rYcEA)BUI5CgP~e-eL)OF8;d_CzU=&iRqt8{MHHzp7%?vW#U4TjF z=^T~EMNPJ1tH!$MH9NeKsc*Ft3cp?>p(S!>YKFvEs*bS^&8c5ygUc2>U4rWyK{m;u zc}YU=nJqMpnUsu233A0daUUDZLuDZW1vIXpmfhG84iL7;&mhBxA*eA$W?{GW9zIgk|+t1&B{`T41 zM?t>$myD$N90p;ktOVRMlPFDmC-h(w_-yF8T6qWLv3&p_3lJqVAw3C3ni6t&lQxjgqBr zTaP-he*zhW$Yv#r2M+F@?X#=G{9W;&_ib-vg|BFU`MJFwJm4&ehguR4#1-TdH*VZ; zb$9HkLbn4z{xUyZUC=ET>!COZNujBnB|e+* zWM+~P88=&_NwY;3IGS=UQnsAYQqTeqAi!NsSi0(kGv#W>VAE0*unIo#*n0i=^-C`& z4$|HqAMJ8+qSSTKzLO*=aS8(UG+F#(bB)2ZCm-$$;&zA5^}+sNcS9Zl$5kl!&|0iq zrB0Fx2r?GE7Nk9~qcX(ot zCqBoGrnM})o+@2v2N}~C%jqwf%$_wZCt`pV7@V@6V5GrF@3JbHoyCC1b zMaHr_qgsXbl^hN@sulixgIYJ*Gu&h_$^oEvf@shH5{l&d(5Hs71f!sd_Iyh9o=^EP zzc+<)XsI>#ksY`7u4FfRsvBbnX87Rj(8n#@o0H079JzF|sBT8Cc8!jvk~HJt#HM=D z0iZ%_KQJi%>_aIrG{+3olTRo+3u+{~#!A#<=G3cdAa4wZ{(yC&fpc*Mk*NY+Q5G(F z#ML0F1`Ri54b;1OGFP}U)DBYfa%M?O^=*?@*-SlUVHPcsA%f4DN{>lLSJR-r2Lg^g zuO{1x7`B<^5~{D?(Um1V{#@s}z0t z#Skyollq~t2!hIE58U&G_QvxJdD+$pl5*dGNoj*@1yje8mprGm)y&(V(V{JRc8pb^ zI^TCtoFw-{YV0SS&ORcz48&7%+CbaGcOC)N!+=&_j?`vUMf;tAP0l zKE)Kd9Oa0U*RRwlAwQQf;(htEr)b5KI89N7fj`*p_1*ZZv~=|4DfL zS`Jh<%K{{{<75`ZpZ#=gIdLk|1&WLw(Li<(F7A0z?d0hc$N5t5V{$C9F)=9v#L@Z95EXc`%s%?s6xwCi zB&#uIKTyj$FmEUR1}f#XK@VZ#+3v*bpc!M{gqS>9!2`g0kD$#?IJ!izd<@zxWNHJM z*V7baTLK$I zB0>zE-Ka|`x3{}aQ@t*f^AF?xE-D6rg2NL!Ud*$kG`pk;NG&hFY(mhW$0ccBbJ-#1 zHJ}53pBM_{Y~28VfD^I<>Tz@()*@z;79zeEzWZHn=Q>L_qzKKzemzhm zXL-kCS*VaeN5&1U)fHJAejO7V74TEFE!#?RGV8%9aTQs7nHE7v$NCqNynHU_%Uu_B zry5{X&>s)3ViGJN9c@7ak?X(_h`XH~z`A+Yf+##iL|DZ>NcgO^A>d;-xuYb+yQbFm z|B?14OV%XUdEov&g+pyEg6bx<*I?9p&?H(6ej_4pOcleu8Mz{XrPwlYNA5s?g{ndo zh@rp&0Tc>mnThx6^Bq6m@%SNO(+!FB-~5Nn7~K6#-;gwmrda}XSL>-2pE1c8Y2r4w zIx#Y{bMV`|ImO&hgDF8zb?%&Q&!JUamkbczbgEKR=ClrdW^(zUM8-j%%DC8P^^0Nc z0*PZ;Qxhj!O-p+?)R_~y7@n>w7o{=2dedq13`+A5sDhtg1MfCY-NQ^l4>>I*3s&rm z{RYG|T{5&79XoZOoT?;+0Ky0xmQuPjg<8&JPqW)26hI%~$cUTzl452VpHEi7K*Cb3 ztS(|p`AEx7e#KvzuKX%JR7^i7f1;9%6~nY!YZsL}m5{S(#I(5{{YX!y>rN@iT8UsO zeWWJ%s=y>nZ>7L39H0O{#lDboytckLup9ETZQ`SR>X3lD_C8&t6bgL)T!F6(lac?m z8|8v>*xnGfV?RTYZaR$|>!hshWdho3CPXFYR)69sw@eG0?z)9$XC2by^-|w$PN)5I zW*NhDNFBk^%>XS^IR_lS40{ys%bmc5C7Q@PHYcRhi0;~H_`R>8vF?=`n@(dE^g(9* zP**uS1E##K$81Ets_He9Q8{8y#=Q~(3XU9XjwQ!gMD5~Kb*L%~ z`RE=Z>6T9yaISKMRvj8l(=q||iVBg-0dAWUH}PZKCpc;hT{XL}?Kc>=GR4vcFl+kxA??vw(7+s5Wlfd^`rteyi&`AQ-jE>WAdw2_CQ zHP^ZN2H49fZY@WEB{qpBylm5|>jKnvMxAnIw#FEPbDt@P48;N6$*4tcoW7gTF=vW) zT*|w!;aPm*5eGuGli%TjWusn5TU}}F5f%2(q&A_Z>osJ*(~$!->7t9CCsIExb#icD z94v0sJc)GA&~L7F@aT1r;`)7T*%nC!j8XvD3hJo_L8q*+Qw-z^?D7;^8$X~{gPyQf z-7xm;w7j{fW%cC=mpNT+;eiUfU7$vI(gTR$32I4>H!oD(iU-_J!~d-xk!n)BShoJ7 zPyxT(8HUiBe9OyI7Qe?=vY)xaK2`|zz>y-60ci(wydTq*)3X9EjNNYi@uI0T@ERhCV8G&_jz)sb@1J7 zZ#{=+IiFP-X&UBfb#BNMhT+gW;$%93slNdnB6J1_FW8n2#1%S4^_)X)>}9V-a@f$` z0d2J~hV03U1;q&eA9&wEPn2C{(qV%nU7+l8Y-sDQG>#^H6L;r}>2?>-)gVPtK+5q_lfaPlE z!RUaso!KZdmavwS0m?$aOW&1ujhLf-f3B9L5nR{uCO|9gx#YzRQE2(hm7j}93(d)m2*Dn;! zih<+zUVmksd_9Ekq-CNNzjN9ND8osGTOLrOt?#Rf+ZL25QHu$wp%)r?GB4b?zA@#e z_@NYZsG`wrcVm z@!1ZF9sVd#T399H1JRaTx317+A2;N=l;ZHZ?9r{u|Lgbf^Vh%+-1JQ(=~rGEIry~O;NTFL@KE$AY1PkF@1&R z#=zqTnjq7TUMXC@ZT74JSFQpHk}1)Pt0F!)flG2Tb}7gpkqqvo@>G2wwM2=Ow=CBp z|ECp$I|c!{AX!$Ev1t`$?$p%JIx}*_8Awes*e;ay1~toaII_7KZOn)3wOAy$cL-2s3e+M zZ)TLF`M8|?1-2+>w(Fx$*-?1dqpDciJzxsmu){OYFx;{4*e!cazs%aD&?cC2X5jRW zwz=mpa(S{4d|0)#6N4o%rO_vhQz?5pZN@najl?SjWyvc8ToGZkpa|0GkWZ3p4|)yH zDh6Q>5U8|kapIcFw^XV)$9=Ge8^Md94Na%nUIF(V^OY^U)%B3v)i4j{$I@ZRfG(0? z^%Vdmv{UZQ+>D30A?h1|$0R8OF6ZpYbBRe?5!H`tc&naPQU(4U@}N(H{O3m(?Hv+V zjcF?zXFE>WCwc-YhccU&B!9!V&%^KkT0x29sC**os#fjjYCit`EI=SWK-Ypq$rb|| zTQ~){QL?oT%e1(5Oideeq+g0F;*cd>FD6`K-(Wf^z7%2-ThKo}q_? zd#7+=7!}5@^xDBz9aMD6nKp^q+Qnu&x2c4J5HGh)P`)@XeLq$A2R!8Q8 zT{id-Wc{dz^v2!WaI8j$RmaLb=uq~Beh!ZZC2bUVm|cSuw49z@I^p~+Ucos`%SMq4 z`3O=jMlJwl2Tyfyd}Vo)H4oB3U868C=H(a5|yt65rFmn`$?GeW>Ft;%9)5slGlt{>F z05xt|5)p{>o~`{A>$|IqbQbKJ1xp7*VySuFd0S)&KOK_)Z4Z)BIyI21FHI}eY3BpZ zYY)+P2^oBNbL<+e8%WK?X=*Vwpjn@>+DxIBFp}Oc3HAXJX8jp z64^IyO{sd#MXgq4>D~|MD{MH?2$%iIS)O4BjsCJ7n8~|f?wy*O6CUZ}$-@HXib>Lw z(w+);zG}5ru}7WMx#dWb1!Pl#WWz}N?=?@jp$0FE}e~}>%{VBC9VK|Kt2uz>JOhTNZJeE+I&Ou3cD>&(<8X$ppbG4HVP>0)8x7#=C^?gZ}RiciV!Y=aPV~ zj`o1p(wN_2uV$`FRB-we=ID-!mSm}xb3DR!hnYU=uwDmdF-zCV7QjA?*&qT=)V;yT z253-ugR+k&)Tr#h!J{Fp7MMv&onN=?B0yD|OdwPX7c-8}C-zUn>-V{Sz5rnB$L~M9 zynX!sP5Axa*x4z$c|R4_Bi}P(98+cWy|70xD)E`a8Z>fz28Q7l$@g`wsg&IX`(kxB zPHTZqP1(sSvy#3TZ*o|}K!mv6hb+d85>}9dju&LM#gU9B_DoWS!RS4B1_>=j*q$@G zfj}ZJ4IELxW0fu7V56T06K{JQegH}4xD*ex6w#6&T}7^!MCu7Oon%$NY^(4p^>If-qNv9)TAq8) z#Hm~*aWcq(#C@w%0OykYye) zqwsRbT00O`Yn>Y9mC>uQ=0#DG>6NJlF)>hze7%x|*M!w*M18EA+?$Ux)-F}P)u&5| zSUA5dcD(?DkwSH`@}PLM6ZBc0UHS+djgTi_ll#`Mvm|{4xIjhCS|Z@WRLBA45rlN^ z@YtE#Q0KX(fo}k)o;algbsAyW_**zO4}bhMs6HF>b@hM9iWctVk&HZ?rU>%DvIA7O zuWs7(I~*rphu6=LJACv0BPYY>FYF!(LWdA9KNTv`XOZb~*2U_Ec`;+}#AZe2b)_&v z3A~;_8g^8DvIkBN)Jxp`MdD`GtK;zT8b)v({U@>G+B7G1N2@NTfsB>?71<3 zHoennE!_9mZ=4ST)`G?rMi%q++=ok_}Oyh4#?w@I!AL zRn%Yy9U7sQY({H6HQ-!9?R;UBhc|@O%xThZZ+*=A_VC0;lS5g+j2%YMshA{<+S*GO z*Tbujnrc$Bp`)H_yWva08aBzIT`=yhc@wxlf92*e#P#tUsH_cT4BXiE%yklR1Y$$fd2OE*1+ z2WF>?K7%ajv_BfPcW{C+v_)($OTOlK)*a(`Y&nwH6{-o^Z&tfk1)~686rYQ(H?>*R z_ICOWxOM00Lhm`2>a$Ix0ijV0@Ms*S+#IZr5$-!lPmMYqkT@`8{r`OZipGg>Q2gfY z@817OvnV*T*n&q=w{ZTHeu`yvuv9VuxfY2~B2rHW1c2!q{{#Kw7ZYaN_I0KGkes~E zFI}NZF>rhUM%Ok;rVzE^KpbeXDZ|t%xi}{BkL33a2o4DmSJ6 z`%Jy$@Kdk%E67P(F`j?-pXCABuLMD+$t)(scZ-Z_^l1A9KF^} zVl;Qji)tyHZAMX}tLm##)e!wTexYIv@BjM0{x|%wKhVsgBIFz~BfyZy*m3Du+ z_!50b`n||%XVvoXz@ic|*~?&cp-;*6AbkSiJBjKIqYI@A<1&?Qiv9M<>%YAIOL+U? z`_Ckwo1rIj&~ZieB+~|qO=|D6(Q@OoK*xMghE6}a!JvW*-3_XMqlBBfm5FLty-<~3 z)!5S;RGZC94P;@4n!SB4N$*#0pF{NHH)!Omw0%zdC&~2@bYV;~OsBl&F!K+NDsw=8 zQAnVi%m-%Cxq+4G-$YJFt#o0xBr!z0{*vjnA4$~fh-E9gsGNItTOuo|1Px^ZuN&CH zog~G-AgfJ^V%GF`t%a(~J=BIKoEO(X0Q&{3U?>7dNLKAc+0`f}AqIT{xl1|>gv<9;iHrmiE|0FvRq)bl^!7aGnW=t;!;b=awqOL4keh@*1rRtkG;GpS=h9w zj%{w06nr6HX249k++AAHeNU50ozWDEVJsWF@as|JgK9#Q5`I zAAZDF|68|&IfXMuGlaF@%7-7zum57F_NFIC&+VL&^}3@i+&U`^&@I3qKtS2m6=TDe z2rgns#vSyWMdjixhc4Bdw8ZJwLt_2?=NI|08jB6g7_M2a(Mly&n&=w16P~W z_Ro-}l?I5nW5T%1&XQfj-P+`m!8O@Ro&IfT$51kO$K1Ek-ZeW{oYZPNW!BANDjMiY zSvWbelg?N#;YG?q6(dYnq^>`Hib1;FG0@AZvZbltWA9QPUMXpl3q#>t9|1Cbi9JOe z6UPu>PM1@tW1ktVIy3_aw2V+2x=Kj3U{@(@5uG?IFC1+>?t>zstzw7lZG!96Ns!UY zkqX3u@dC@UjVayLWovbH1AMtyvkpT4oOy=4M4)z`bf;}Y-=Y`H@H2OlH+2Nxdyiuk zTDgAs4RiL9uR>YsduiIsf42Vxez^SkAN();;cr|FwyS%T@^ma6_KK}?J7OoV9N z2<00f2lbZ=M1F`)ZMC1y>1B9Qq|pS+Iq=vBl3ex%qwDTPYD4;$*3Lfyi$qd%iRx3+ zGS>CQO8^Hf{ru0~KU2Y0SU&g6I}xx=`eQZD);gk<+fMP+%g1hCxcugp+{|ImLWocM zP=aX07_V{zPK}VV2E{bc(t!#CQe`-nQI@om(Kero7GcUNX%x%t5N@mkJ+)z_(F$xJPok|3Tp8~uy(=M=qN z7z?9Oi9po?Cie<_x+%AlP@mEZ;P*K)R_%OC^3;3$58{*m@K#A$a@f7>om z&(ar#=X7nDhf7p-L_6*b70{o(UJ-b_V8dA)q3zIN^qOwuz=G?XF9|1{Wz6}tJ>Wad zwbNsi3OL0@V9QtPnpEmRlTG|!mkfzys#@b@Sj$V)obuEd8 z0BEAha>jP{-8%g{_AsB6fX(@dT08J(ODbp0nv{-)*RK`u`T9e}+$1khmJ{+8fn0Vy zY00dplZ&Z9$A|atY^EGCe>g<%H*`N>WhHocm zXaL8UkJY(316>|#WKECByVffy(|JyXF zWU?`-Y3;-et#AqbMblur!?#`LUZy zcRFYsVMA_p?o|z%Z2ovysTQ^m8}GYye5)Sw&cAxP8sBzITGj(>y^x-4uW=h77 z*HGF#1yszDw_`*T214NOnK0c`z0H35nQ!uXL7ARKKVl#Wg*qw!Yysv5uu<{Klm#1-Pd9qGO z$3FygIV`RwN7xt2(S)KEcq|Z|1CUOIs$8c^ZK*ot^{NUvj)aV~PvyI@<)zlQK3M1m z;8$)P`IU2z)0>F5{Uoz}k4mAn4wL)|ej-d_peE4`UXcT_YELz}Xz(i-AP=Bq-MX@{ zReVGLjia}2ULRmIBp8ikue%>V>VtKu4%FfbV)wIpEJ|0y`X|DwbQ3!@a($@I2Ad}n z`i!m;3YmG?Ne4PfgaBDUroR)6Xg!fbdXwZgE5OOak_hFclM~0qy^yEI>u0Kz83{4 zOKMeAl7Z&5=_v48TAu$l|LCLoiuRbIM3Ns%e23d~OU~*i+&NJPP*sQt9ZLgY5LGhj z@M%|at$d_od~m-*NnFwCk)luauumCV)p~7ILW6lN52bnL)a^x|QwJar*S>?N4_f)~ zMwqENcEyqX(&1GsJg|*F?OX=c5eFt}guZ3r%yfC`V8|E`1?8BnYLwU1G7R&4QWauR zdX<~OaTE!xsSlRx7^YgN1Tcb)5HJ)CC@y>J7vc3A3o5QOJ40R;JX&V>Sg(MGtT48A ztjkbo0@of{WXjZO3OSxzM_9+j)x3%wp!MVOjNz;u63}LY6AsSmw(t%k50PO9pvz_` z@By=d)&b*S7WqkWB@e=I0Q+eQ27IT&ncgG-^CLYzc9T@b9sQT0p;=qKBc$1@d&bbw z=@km#vnAE+@IJOzSF2&0bNeJNe?Xt_qnujqaFyi5(s2X3&~+v0cnfaVp5cTbadgzN ziR0ZTGf0x)YSuf;LN#eAGNU~Niss4(QiVSyRrpi>nh*E)FBp4h^oY%;Vu@;b4Va*c z2?8Jl;LS^?Cb+Z+X^Zs#LW>O5)+!vPS4(tOY`T|&E8a4XMTOy+wygJLtQ(Vg8Jij- zG^&W~0*Sog7m`f5ut*v)$pbg*?poC--#!NM;7gckIq_rNQ^8K~=@bap!9Ck}VL?rX z5^b>#Vo&%IbQMiVh)VWmC^8KiTvxJzzh1?*VgC9S#H;e%W= zeMHi&xi`Z@2AfKPlu+5WDrybKd9HwI-zZ1#0PW9{S!~2XPg*UA|0m_?UxnZQ^*QmZ z-IpZw)?If`R>LqmEpRL{MG&-CtNyxRPHHV^e@MQY{VC807)?2;nQfMyNa9`>s zFU!~8>bRCF6LP+}$o{w{6>Mfr9nf%`dajUt;>9T@hH8PB<#s;5>6UQ6piM`7W60dx zIzr~vXI1EN)B2}?$v{4_3qBn=QfN}VgJ#;fA2{%KsOB%YN?DgzPl*MXOeS$x^&>)@)bVmpbyR2nqRGBjQ8l*g)ZAeQ!&V3o&Vx4}f|S`s z18e#N6#pq@arX$@ESkVV4a~mnJ{V_N)hx2Ig480UxPt(S7XIw?^QmO3ygzHtcCLlh zD62YM_XZlIb|TrO(!l6kh(EyA4ii*NvIS?y<;bo$tjrE}d0Ur*O zQR_20fRM@4LVieVoemW#Mg9=o?Npob14M>mAa0n6our_km&kLW-Y8m|l1xvOHkHR| z5o7@O@`G?*R1m?G-==R9Ky5_N!hwQ00x*(XD-#Z0iCf4<^q1kd+(KgZ}E8T1tS$n9ks0uWwP-*V+=%l5CRvxYC`WzpOdw01j?@e+ssdPu{|BpDY zhlH^V++UKp4yQT`Af-`)p0`p|1iruEdNP$@iwczXEF1!H_F$fUR*$X#F>rBXYBS)Z zo=IGRKZfO`OxV3^;61C;JW(+&+H& z8vhM)cFGYd7iV%}J4Vp?Q6|iGBdc_Gn*o#FPmlD*MXpJM{8Y>|GAa44qOv(oIQG%(jDlRC6Hs;8y zb&Jxpp+hhLYYmf_f5iCmo)4~2M)&9JlEKrDlzeA*Hu zFqP`?R1Ce^h1vKXO!YA>m0tz}YpUkY`@dRvRWi88wrPahbc7fwHeTmrk)92>D=9YM zlVNbo;1{80+o7ZpP}88hDvndh78_)9Bc4fZ{IBBufi0 zR(6qpcd(NqyOpigWlnc0XJrc#uPCqCA0Z0=M`0)D4U%_s{84kYs6A3JjCNmBf1-$_ z^v*CQ*H&e2pWY?yv_y8ohS*03#e5Wor`D8DQ~^CjU(9<6YaFH(cmfu{12f1zcc^aD zTA}DN@eY{Am}U^kG|1owt-?$_RV(y>|E7qF$$4lfcL2zog38?FMKWb5B+%ariN(HT z6rsEuEB>L;5A|aAKIYH`(AAXcraM;-n1oN{H!lWZ242k+!sLDJmz$(3Rti=M?*xg! z#h(5LRRng$+pZ5=-V@9N&@^eI%PWIaEjg<(mXHI&uZ$CFcO69VyP;Qq!Zab3lS-&B z=B_@~K?TJSljd?BS|x%I{LEOre(&{5Duiy6`Zp_(l&2GJDQ0~;)#y|6o$97kjp+&k zRjnd2K88@-G(4giPjEYDqp;mxM-y`br^wQ2zdW!#cs+n6P=Q{}V7nLffwiVSMu{CC zqU7XmhSoVkA6wr3dXv;kMoyOFkcO*)!u8}mKbXVi1vlq`5H!sVhYFKj+fu~~!?OfA80%uLqRKm9 z5abkBvZBZ66D0%`+YhNB@rfKI1(fO6?Scuq93Gf?D0;F{qX*lbz10&Ly_G@IGp7I;=veL2LaoiQGid}# z)Xc40Ir7AoLT_3n99|}gFD^Ivf*EDHlD))y1O4gSW!}+k>s&S+1K22KoNUn|+hfW( zDKR~hdSKp#qVx1XS|4EO^u_SEk~I;bsLxNAxcY?+l%3yo1}(+3wM^yVFl@qNLQ>ZX zN;u`l-M?-Q=|W8;NfNR%d)aOBM5Y}EPJ)uGffF`&47PBvZ17`V9Jn@3mp>1GnJ#}) z%rLOGc003_g6b#8%5O~im-OC2RAgd5s%mw5u2eZwm5Km?I3-Tn2^OEjNoM{h;r(-9 z^S*-N((6CIe-j|$1`RjZVm5?-r(K}7tY%F>b+PSwQf`pC4h7}f-GDi|5h@qhPlad9u7)9a`!D8SP-06{Ou!uV zvc22UTl+I>;>mtcF;8U9Jk#WTxSBxMfb+W|`pl%%bvWdeW7h8_*W55Iq&xMyc03*G z+-H4i^vFB`X_Q{VK-WVe+}`AVcEPDsRGUqcO3MEAw2NqT8U73JN0Q{aI1mf$$n9&b z#1(E6N%VyfmU}A#@kC)Sj7U1HOTg+>!N!&#PznT~Uil)Ts!`OP`EL-8MQE$a$S5@e zN>+KkbX=b0Km<9EsNpM$Evf)@ZU-m7i2!R2+C-XX5WNA^kTG=a#Ec8j@<>$i7tHrAwyVM1n~kVsw{l??S>ge6L)uQz4(Q8*ZmJ>jF>5SlyM73OyAt}ob9 zGZNcdCP86*5bslu&b*8L-a^&eh18*mavstb9qB_=EKXeLs8Rg(MUbTckym+dK6aT@ z$7ht2M6Pw(Q^NBU+EQyUHHHLMo)r53GyFw9CVov0+pjHUS}=1pz38J->E`rAMyZ62 zBqnLvoNny)&{E4Q!j+LqeUBepJy`Pws#eA!Lf-}Ge{YA+|@Cru1IG(&BeB{90; zJbD&X!#kaeFcwCJNJ)lavksCv3|L0+1ROPmv$bDX0+KGfgmz(f=orBEMOFxPbKtUN zDHe)7tvZfXO{x^cXp3A{C@QC95mQ69xg(u?(~Twt*SahDeSzu|A#l@dI}7k$iBd|R zmC#sC%yHB~#dR`2e*G-zWWpBkVqC<{wmF+WVV4;GT4QjP|y zyO*}=>0yIPbxZn@bSp`saTZapVKd&I%ZS{e5o2eg9GO5mZ>~Vq%58&%x!P22Z68PYxu+8 z(0`yKr|`jGXzMmr=uN)qh(uDO+u{#OY_aJ{(wUUidqq#xq)<;4$ycye{QmpbuZiIC z;+i1O@ZTLh5xJ{tkcR3!*ay=GCImY%2o<4eGv6>doXV9mydO{?k9!xgK3bKptglPt(^I zLL{d>L#;<35KOBhJlh*qlX&RxRTj_yg-&HDs#1C7diS(qYvRe!TM0MrcL1jz>u4v7 zo;_iid+$=B`|7#b;2y$HcmZo_dGaS=Am62)MAuLBk_Cm2#(g!nhr|#cb49g@wruBy z$4{u=&4>L*vYk@-FbgItRJfq$mM(M;I~7G*D;6Lh;Euztx{dmpKqTmf@i0@McW$?< z=`EYcn7%hB6o+<^BjUPT#pOSSWN`P;j!!zY_Bn7aJ!NITDwGfERR-Fn0KDr{b-*%` zZd*S4bnL-07$6D|7}d761-^4LS)wN#FBWck_g_uJu#==swM)FE%XY8DdQRP*08Aw0 zAheQ=%AHy2{6kb0$ zZHlu-!Ovg6@;?dhKeh7*1$9L$E2XDeta%t7a;QMpu$r*Lwj$(gbaJ#c5*_DqxMY8^ zt7cIi?V!HnJH1Oy1x5k+q-yKneaG4LKx7wV$lcMmv_;F_&nw_YHYxF~9Sp#Qb*Z`} z_m}s*0tgP3IgJ^Du#qXcsSmXpToy}4J4g}OI*xQe#Vt93jc@kQ?)GG!;-#srvr^-z z+F9aC@NiZej40J{DgUV)351vzZa#SIfynNFHg%gEn4roZ)fqCiH9L6Hz>6xCFf8q1 zw*i4jIzfRegxb~e6-gzzmp9qAheoBL#K!KYEjzK6veAn}9-4&-2s$jW>bsffj}Gm4 zumj+Fn4bT}L$Fp{jzrD77L`rBJkCP?@H&^rjU#U*3SCa=t7pCF>H;ReO!n+s)flxU z(1GE#GI6uio|4fMOpefcLiR`823F3mRoNcs4^?%~od*ttqtMmkQ%!C+r9mK^Z!gIL_j@U7-6_v8l6Ywniu4MNYOi#mN45l+S-UQ$AIk^yeuE?VFk^q}PqPtP%FKUFOof=zjPiV^DkTLPR8>M=5G;_JY=@V0HN>=po26Q)1Vp4KAK7e9O zmU&t>75XOd3kvDSA(pTySzBygKzfQ;k-Fjd9x zhS#6UT0SOZ+ga#Db8k~3E{-+8A=>TVA!T~1_$NK8XkxQ75w60+TIRi?V$$a_u)cwA z35s4&AF2~Ls9BL!>G1! zm9*Veh=L7w&>6DqxUD#lvR7-; zAP1Z;4^8<(>y0}UNt{|gVupXJ>0`QAVAWi#ipa!Ubi91m!+D}+qovkXpv_h**&q%# zfmkTW3UIVkt8O2&!@AmF^btO(gATeTZp3UqGG3J?N=#Ct0&_mo2GMPh)QQ1ZtzNg> zseb)L$@Gd<`xLO5I~y`<4gX*^OXW0`Dgq|#a;ix901w)Z>5jT3F`Hdhdv>>yLI+!3 zLfx}07d%qyS?{&qg)Fn+;xvndo-lfndPH+k$SeQ z+{P+h44o~${q6AWZ-bi$kZ*R*-Do`rKN~_kC-3#)@lZ3hTI3*5$3`Mk0cMyU(fcXW z&ce{panSknsRFw?-V{b#xz1ACz)@V?Z*4hQOHatuOO(ntbOUYxD$TP$20Ti>8}|L1 zHpqr49^S*lPlv3DtLi2Vd6lw$mbwqRVsUoOmek{6mR2cw1thxyGeBbP+Q3$A8iM@( zZ;bQ$A8dcOM;M=NedA_L`=tms$M!_bRv2P>^z`g;R-o-lIb3YAiI>~CQ={@rAdGo6 z0jPF$!vQ|JAUf(fOD$kbq1|A0_mKTGhsHD3P91kUhPG{VV0fdnessRzP+uv>o;ZK6 zh84@LYM&4`7(q?m8J-8JXCK}65*PPc8TMpWN%eKf4Yo&mMvy*Bi}62%|HP-p@FJ@g z5_FOJ0P;j^kzEgt%T%91YMF|<->qUQqxW~C?TQ!7y;dHOz&gjiBFXF_sr>_^A>(#! z2%UAGne#@D|Y>ly_o+1Zr8VaG4jTnjh+U{^Io~wiq#aAkzm=5PqG43gPh;)23h0@p#RR<6c9|-^wh?Izr!fzJ+)GX> zfOo&bx?X}j(1y1FHCMve>Uht&LWP`VmVfQq3vy?Ygq9Oe*Fx$KsX3)|EZ~z|wH5as zO<(^}{rx^huK6o`brkM&1I(2hDrr%El|{X5y`p+KQ&qN(ic~V}gx$bz|9d09w;zEP z45K#CxHlpMH*M0W6bA>+3mmMtaz+a5gJL?Nc~AJ!2s@_L7JZzZYEAf*u_sTxK zCyl;qbh=JA0{Tbd7}=v$T-{4g9?kvqV8i>bF<-v>mRne(F0pY6=nQc^$wY6gT)eAy zLt|M#0e}<9iMm#S7J@+%=7p_22%(&&-oJkT4aZrj)hl_$_aRxoO>)5QJmHH(knJJS zZ*K^IkmZ88ez$?VE_VyPBW5aBq;+WleH*gjzc8=}%5nQ}xld4v>#kdyBsbEtQt1!5 zQ?95M0#M+muIug=MhHMh;fd{Z4X|#{2G|cdoD0I_yg$`r{6Sy^o=QMm%3|5gRLf)D z71fsxjULA%vb~E33ftd%QB` zm&zf~T@g3rRLIuc5!BNFMdP{16}l?+DMoz)SE(!b1Hp%o<$a0G z$p)oHZY3G;ZilVpPb#Jj--H{Bk9!hnv_nYN?oEy#NZA*I3Aw(soGkT74u1QXHO@o%j(pWUCUih#QD%K(8ILO6djl0d77kV5^pcfOdF8*YA_Je|Y~P zI)7hi#h_6MX6@|1$&t&|h1caJ<5HXiSHLu?c$$xs{K={*zdR&IsnF!;m*`LQ>X7Sp zZZJrmc4fzYw5ykfB>*_ox|IX@HS>|zh$Ok-%wq<3n_wd>CMZO(2lvQIS_dZ?n3Z>& zHUW-knY5(*C)tt*QpV7d_>2hdE*?Yjo1_Znj+ItL49H-SG)7q4E$&-|85jag>0bt> z$&xmLJ0S-SCmE5Wp5o;t<5`)*d<}fay7^S>a00fhL0L%>^qzOA(J}U6`M%_KP4ftc z?e!}WZs42%iOE?O_SK@G_0->dbP6O{{bex&+e)>?==i|kqfL(mu#Ju3m43fxb_l{1 zTL+b87;90R%a=4)| zqR@`IMMy3o4x*jf z)a7(wxuTAr%4xbeHL{dPXMi}>RML;np(pZi(H`apUX-%53;_f?6qr{wk%zVhIg)Rc zN)UYhkF*16g%k_`3~nlD%M8}7ev0+1D=CkXBkvN+-QLxwd}*IvlC8?5rs5I>d)L%9 z2lzZ7gse|GXJ)iQ($j*%j<0;ce%LdXm>>7--KIS2RaG^#X2wXR*yZwF!o3C)vM(;M zX`P@JnNCgzh|~u8+Ta^E^wRR2oChM zM0#4Gxid>*B$=Q!+B7kcm)TwhHVP#~2Iw6}RY)f&w@bpOZQ;D8riHg@Q77n_OC5u! zkf$;5BAEstEsThzz2Dz|2i5*pREkm38w5g$1DCw=*;ImXVJ%--|&`qf@O3Vc2P1ad9Ay+bpdFfwUL}eTUuW~^n8XHNVJnNxuo#S;nDe| z0f@qn%@(kznd?I0t6`41s9cjBvCxaPqeeZqKg5M=qrzITtt5AL@GQD%<3toVM6`7B zpBxeGMJtQ$0vapoR1EJZWHbUWWfq#q=D zU`Dml|D&2TD)WgVK$TFzR&y4|<@F^A`-MVzELSbuQbZ-P>|&-K43Q?17>{zgp$^Rr z$g#8*ikFu>feR=#-NPl6J{Aa&9Oecq+bTZ3BPo+)2^awjaSQ_h+s&>n@Pdn#79w-lj*%()g&jO#Q)gY zVJTZmel$ALte*Q_bIco1J;?#xl#C_?0<&S-bT{YKHAZDT_y>! z*LYDA(LLi>qrb5Bn00PR`%d6Nvs=(rg#>8cUKQbqAV_qNmk&12SNxTm=d1juU%q}~ z@JJ;6*A6QY1l2|kW7`jdCariq>qcu}Kxlm#KBA6E#%aIPkOPh8%{XD0V-Q0c2O5pM z|0;d@*YIu%i#xS=Bt^eD#Y92~RG-<7fs^<3N}uP@Sz3j@5jYCu*;VwJTBbBTACjrM zBI3|F{6oNJ`8~M%F{kDlM8#>I| z4lu*oolPbaKz1_IY1x;+ov|@$tVhi11N&}~ z9kG>~`AMk^syPz}+hdXxhoSnaN^g5p=4?Td?8zZA4NmVib6w$;WGh|W$8Zsl8Pwk8 zlDz=mzIgvsF#>g_gWD)SbC&E!mc& zR4#SZ0Z#GENC$2ETQ{!B`aL~`en&v4Bum$9r6dUh)5ko^dH*uJ|1kA<{yx0^3dJrv z0HB%>2&gA@IuiEOCSqG7;frJ+Uzy$yG54P$6_H^mKVRgGva?^ZSsGY+`doqnYv(Oy zAjJk#(Jw6-R511sDQ~kDVVaA*_h=WMveA$HTVNX0C5O$KtkPFEY`xU6hbCt*s@x&T zzx+?f-Hn^MVn)Atdo;CZ@&NKco5?=QY1zX-Jy0usf~FRbN0GeAVPCx7yeS2U{=|iP zxu$gs{7mbhMS?b1KFV__r^EfT-adW*0eYneJW?2aMsJ<0&%upI7lRqCw;&mt1s+G; zt_PH;VAVpO#6tZI<7Movi_GEjKL7Up3&$*ET#qCqCt&l5(-x|s+)eDpnE#I&6 z_EZFK9NnZPd0|#zpIkm%HQ6dC%oC6p+J(%H(6I2skEO)dkO)a*bpgV+Qt4}}nV~~q zD+4-CoT3eSPImPL?x|o}SgTa3vkWQiJ}?M?I4XwjdzR)cRr#NA_^EdsVA)Z`8c>lF z7F(W_<`!F<2!On8b&zXK{X++omnGa>i>f6HN6v9Wh?Vxv28aL|m_IgI0qrS5exh|h zmGT28x<(E{w$J9dfE}75zN;`OgMuAS zW)ftMKy42IkV?5Ut=$=DjuFJ*^o$_SNyr%b$y+4MK00Q+QgdNhE;t8Ok(w%%ae*Sc z{E4+>S74;Bm!dpa>c4&e_uqa0IlT$<=kUk=fI+2kUC{M_LW(Pms=VE}`R&2QwM)Z12xm?ppPua28>Y5u3 z-!tzkxMCT$ag#b-wHbjHBJ4t2=`h{A=9U6gnta&tP{(8wd{ozL?E|E*!)&K?)Gmp& z@Y+d*^khj`bgrPq1<645Hk@i~8(Mi_Kvmr6S0tCPX+PUL^jS6x4nDHOEgnsIW`-Ga zOOi8m^&l0T&Mc{mEz3Zxb-p!JFvkLk>|IA8=pZ6iNp><&`dj%&pu$3rt55>GSz_Eh zrmV&8gWtr4Hq;S%o(Rb=FNcaKGX&uc?AI%CR)sytBEh%NQ6ZA(d#OG9Xp0RAPqc5b z9@`NrFIX3lYAJxbx~j~g;&lboxXO#F5jBo`dg{Dc)rOTWqGN{Z!M*%a!|a*jrP@k` z0*D;C)CqX;=`834a-CBDceb7Hpa}GwX~X8yx!c;ZcC!r~*?gummpkwV)_G~t**uaB z1o?W9!iBxYi>kJk;)TrFYfg+tN6B(GOSkm%=j($-s0r&tTx^t6-}x*&8EW;KcxXW)a}8u=svp zQ^h||4HRptd{+tqd;fB3*Zc@XH?;4wUAyA?p{o0g7OjQKDyp~8k{L2hw<#*9z}%}p zH7AOpR3%c@P!%^VCZ)1g*2#@w7ijca(`1%-x^!5U*z?!k-ZP}XxvgXA=&0(H%`mxn>@wZBbPf ziEo31D8M!=qi{-CwT*B+S-M15YXo<(oK}A$m8w**vHz#x-=)jQLqC9zCBwV(^#kzL zbJhYNTs<`xa2o8Q-aeO``ReWS-~Tnx`#*mF<@=ZN-yfKqK4iD^7FZ!c2=U)7xgA;6 z186O`0q|yWdA$6wyWQkHcBU(HJ5HuMN#nB4mS~cy;CVKD7Zsa=I_1dPDBV(@I#(q! z)$3_g25?ilunxesYI1<_fTo4#d??lvfE#Ugn@wbqi@r$Y0rHPz^Y;Z~oh0Jme@Vq4 z1)Mb#n+f6tBdpw2Z_w@v9J`TP%1&f?32_GAdsBf{yLJq3?Ko9wnRQE9pZFdU!JO9Ity?KMSwYC=|Q?~;G*$TOQi_1`4r)R_+FY&I6+ZU)Gu{F6XOcDRmOjJ`?|L0)B z#B%aln*s{OCu!pupYn+|^~W%G-Y*&?rM;fW-8bcvBsj-)*$o^B8jn1xieD+P4k~)3 zA4tGYUXn*oM{&K^Pe2R%{PicVU#H*spOgdF7MK;oTW?EfI(Z&q&NfrisV=r6CCxkn zv6O@L2C8r`d5UBO4Yc;|leGbG3bczQL;B7TIzkBlyrt~*?An`Ty#4W9czzFv367?+2xSVktjZMSSl;_ z$YxEFQ5m^x4n4}XIc}#aeJs>UlAa#W;(X-Uy*ApX>qYhLAya^JQu0U+k=cb+benCAh1pdgoai|>2--EhWG44FI&bJPFdM-NP;aEJK#klKN7~P zHXz-r0NF=~1)R!{b(eY%x|cSnXu@pOOiXB8V6Xk*V%o>4m|6%!*)CoF3$)|pkvyi{ zBL%4oW`QqGH{8QKC)1m0x>??|QRyNLn(#1RykGwmZu@Xim3kXjp#I!-^n)j#frRSn zk~2*$bkS6^wFu30YcEDcmZ7V}n(qL#hQc^Zz`#HOm@O8Ko%aho_{P%;H~x0-`XCtk z;&8~Jfv+2}!2;w}VLw(Hgrk@L^fu}WLpqIN$;v3B9+Xhy;uvHOt95OkLeZpq!U4s3 z2~d*#q}@&J5&CXcOFJ*`p$y#RWcE$HBUOtqfxI)=S*40HZ5z*Evdfe+%nLn8^mwCS znA&hnO^n+JFrP(%Q++#>uxF!#g^%O@P2;7!Kwc~3!3U?Q1?wy}_?QsZ$reK>GZnt43g`fw- zM$!fk5puq5j3*$UxgL@v^cFYvR`cET1r&lzMPcup&s3|%F#CR>3b`7R6i25qp!1Pb zVSt`kNDMfhC?HR%ax>{So&cXo8%82>UAyGc5EkQhy?q`aF@HJIBXfo6M^s0>pbT%d z=_4kr(+N6Z699Y?JqBj6GR;zR;ZN*R31lnwmQYO)8?gxlrG&!gH^yVYi?y8PSlC$@y;v3|sl6{`q{ zb;z4$o4a%9;52VZ&?WiZdnX5$wsqtzB#lgmq9&$o(OIu0ZgEiwUPrg-T%adysV9B3 z=x3LFGPKk$`D^&Y-?*%*(4S49_KG7vh)@=l9IpxS0AJ8WY9om+j^9(A|Exn+XpR$l zR|&?3v^}z7*0=EJ0s3l0utz*oB*smijciA4W!k7y9v9~%qnbJ{5Kc#KYh4SiFg!r0 zzU*|q?caU~soqEY;IiuMj9l?aMlaM{i=2=+_55<{! zCL#ZZ(z8*2nZ@;uI{YOy7N}WnK~w|1T<$oI60#SzAejyQ_JX9_G(k-MbAH%h5=ZibL|YA#QQ~?^{YCmse-FFZ?1_cb8hWmuC;6R zP`X@A+d(*p&114^OG2 zvi7>p-N`Z>K(CQFyZKNcbXN;o^$t4vLV}p$N`Oeqkp|>wHYcu96#jdQt8br%_s={* zlm}*SF_|YLH;~K;umGyM!=pN0VGm8BJfw+$na7!I5Z@nzn@Zh~f24GPFzU6Df2pWZoF!aSQs`AsU$LIJ zWDoX1Eu*-ABx(jv?*J;$e!Y1-BAv9VzNx*=0#g!WK&3~Et9Of zgji9hC3`;)40Y^S@3Y$pS_%huuD~;tc%-r6kpb?{O-^Y)MYfi&WZylUZ#7qW{~?kB%eU!r*KbuVPb+|B`^oKXr^4F$ zw(=0ca=zR!A2!Y^8b}6Etd*2&$3s|47zfzv1gy-}b70Z(CH{*^g1T^HEBxyH2f86% zKemO7zNC%I;=|8nU^=*UF|pH!?s30ZaBL^V59-`acNGzUW;NXwla49hgCcPykoU~U z)*?KPxG3DL=sj?Q@}L%dFCBNdDpN^NLUY9yt~$X}d=FB_6}@?&F0X>27fjJtnm=v3 zCV+%v0yzuKvj){g`W;=o3!IeLH;*$~tk(1#R^p@O=7-K+OK5k59ZAvwQnN_mGZB9H z!(Z)66_vj85k7(x-fE zBcL0KB+Tan$14n_fF811M@a$oG}Vm!$Eh6!kTqJ|m$x5-S+f;wa*bJ|n^jH7kL1Tc zO$1ZB206wC+s>3j>L^T6<0C0#T_Jf$%LFt{vRZ{gq)tRQb>Z1L2wnJk6t3_w>0z7H zW7q65-#R)PB%aJvSzNGqlzX7{YX<=j7=czNy~`)e6AH%8VY*w_4IRXKeR%ED>{J(R z(8gHk^`&OFRL{j&8e0jmzxY~tgZ}^tlfO6H4yjlhLlNqr+->Xi++N$s zrC14|f#6lLX_knOfFGU+zj41qDW_3P8Y0ed>XkN{ICmc)j{=*W$!*4uX_fc0FZShr zBYd3T;&3Yt+)7@MV8GA3^Wl2 z!ZB4T63^rkVSxw}%s~w%Y-^RhW!BJ3g!ugsoUKBKTuH<`*SMTlpTR7uUX;V3l$As9 zFPlR4qbc`>Yg$83aRddT+&4dhN3Jil$sn$rZOhoKmPgc#ZpVl?nf~c)-@bDliyB5o zFnzP#46Xh}%`GF6cYC0}PR4O zgdMmV`pXL&Mka6Ijb5FEXg_~+3BWJV&Y{Dfa*+x3SB08V-pO&Ks|2yiloz@l*s_HM z3Cg0!;UfY0cFg2r^vU89yANRZV|Lt~7+2evbQJ7eO^cd~(xzT5C-*hqtgSJfj}@xy zUHc$DoVU@&~4lCG{_$53inD#ypsyH5Q+OxtBzP@1jZ*hjGio9V5T(zN`VHT zip<+iS%Pa*CF93bR(xg>iHTOdNe!`BGa@|L!46eLw}|DmXKqE3d08bYIJu}B)Rm>5 z;nc;byAgIbDcu-4!j>C=d`D1nmi{YRS^NNi*`HJ-d&3K6&Wq&haF%fSGQ9s20`{+8 zf9<3mSj?n-fyxBh?-D`o9%@llIJPBx1Rer)fRg!A+WFlmOF>0_IvT!1L!L#;)5O{x z{zCE&CrGXUR6wi0+X(NmmNrj>w9`!zJm`1dRps(l&~UnC1(rW4O_PXEw2yHq0K96?TpxjAz$7 zq@-;2146B2go^lO*S%R_Ol$A)3fokP+t)Cd4*&+UGXbv9?cE8#AWtLp6uyQYowZm- zcQkq0v+T(eo^S>hjG#yH*e>?wB$;a9s~-@B^@GdX=kK4xQ1grT-@X3g@}j0^12C7+ z2efj!3$fDah@>T`8M~7?$7AHC1nXk*38)&i*ujo8ty3(g%Zw=J-gc5CK5{c4u|k^G z+Q5)dI_Mm0>(X@)#J7FFz&{WfmYzkT}zc6=sM{_*>df=U#|n>RAV3c^TL${&FDl>R;_*OjeZ$kzqu&rL}TDGRfI7} z(J4P*vjyPV_G{K~USW~qb0`h@+P*QhYK(5JEf#ToDY4C!xXPSWM51-Qsv$GjBCAJ9 zG`i{ltfjI3+DjzE_ zbay)*7j%23p1a_oSf2|Dy}5Is1iF@K(F`GvL<7CDTm+_7s+$H|yTuX{DrfhW3p`D0 zp1aUh1pbWN3W-3Rr)|{2m{G#!j>Z6!-K=C{fc*3vZhSQc0J)+~)9$t_)Qj?hMk{Fh zTWe3RSyYh96}&phcojd>-PxJks9|wLx+s*BO6V{|Le3#lPk#Yara7>vAP->gJ|=Z} zTNn}#<<3*q4jve3%)m>_*|MQFmCPT-HOHATtj?ucH{Mk0Cj5IVq87p2 z4e!6S@TcwCjpVmZ^}CVjXSEEuIctQVMcY#?J?Wp0mzHQ(r0`2zaX=AHT6$9fDaZTA z>1(LU!U6hb-x(lHRd%u#CPs-88|(^h`q!WK0ZdJn z^UZ|Q!;8vN711&f8Lf_Jl%(sH8cg=hUx4T0roro#I6V0b6qOKsW|ll71nAVx5H+=x zUD$c}blW&tLqKUc_Ug(_R>E;ciD8saeL#6Ted{cyAt!0cluk*iWZZ30ZSS*i=5FTGE760RVv3jw+m?_$>1GyBB+5(f#~B&0u}e}J|@dt4?a7m zZ|hzr|AdRhc-cjcHrg^hZADe4_H&kg?N4Fy*oP{KtvCQh7LwFP)iIJSpv&pWJqDf% zU|1FLT2h4!14FMR5-yNbHJ!kBI@5Xor50cRcrL+g%wtm?U^#57>U`!j$X(*oepe|t zj%A5UPGlzAjI#Y8gw3bbbQ!?c6h=Icl=v}P;C0-@24^~Gy|X;t|OD>4+f zWjYU1baPrapy}%~p+@Q+v+{;;T5_j{*C%%XoV90Jd$lIb0D1(6u*yM8%_>nKRFaCrPidwO+zFOrMRPE;sf$W!Z()#Radwe0fsM3t`* z^$gG>@%i#C`(H@E*bf^{K9z8jx^y^x+|MsO+oxex^>SIg#ZC<%5L%G4_KC@ocIrb5 zX4^hD=(drbtg4Xi8xUr6^tx?_vePtsQ&kf7xj3y(-aCkT68l?EzA?)8nRz)F6jQao z;>wvEWV4v=t*VtXx5Whtz0)({BQI5c=q;VNUi)-iiv@al6wsg9M2*ETpg%JSgWO^#AoMvD|VGlfSV2-@=6=cH&D*# zs+U_cK>)}z;g~pZ5?9&w1YVOuF$f>xNdwZ zdMXk_*4q>)8@ytpPR|KU zH9xJ4RDy>=nN;n564Ec}*kHBl7+ODi`{=tdR2bqi)l)S?_MFcCswwOUf3H74QT z5Qsf#nyyJLYL0Gb4Btfz$1n&cD`|)|gmYrrxcxMsWn=r}D(N2@RDTHRs1)?zaugL= z_ozHdJO`jAhGSC61O6k)d1ChJH3Wt+NMJuR)>^C&99O-|k0n*LgV_E8Orp$5_*(OsP#2{p~@E{pe2EXODKBrO9ep_V6+t2gI7m zOeN@HBXtIudd$$5^GaX!#@Ov>YP?pG`_$TTah%Vn&SnzlI+EXIIRNwKK7VBdq(DRP z)v;lrHc>`-BrmLC0FZ9d^jnHa(2^dPHqL6h2X|#CPIjkxY7J?%Y0fl1K-M-@V_McT zxJaLXq=2%!(RfO?g37+w)IP^Wh;@)jbedF;vN$Clx=-$LF`~z@TyF3rXf8MC@=(=b znE=%o71%X;rU3~9{Ut@EGo%%vnXc~&Cv^4-XfK%Q!?=N~L(atJJkkMfGL2*;*S)4m zbOhZbj~ewEw&rgGSQrlr*s4hyLL^@g ztn@#k*{g)IeP*j3;Q~VgR!S!a@KUwBZRH+XLfDE=o6s@tMSI?(aHAol__)fIiOqiONV!Py7I??-{D?NDOW3FkLG zcw<(|nX!Hba+5~MNABE>Lt|+_+Nf<|UZ!%=EjQ$t4cRbv$6IRQ^RuA%!_WCUpGuCJ z_Dy3A8?>>e_0lI(H#V@^>0Eve;NlbSpaAu_excQ+&X7~T_Fk9 zphX#!X;ej)%PMJItyWMoAS&`wqBkwCFsNd?hM`2lcZuG*)M(ga>Gmbic=eTAuStO- z{HYxn)*W17C#}Qyg`+L04a~B48c#&=WGPu#d*La;H>q8Db!4~WR2%%fQ31Vp#C#RT8M6A%S=~!kK;A#>n0h8u_NfTRQ4beh#I_}d3 zTBe&MtHnWPkwF=f z4W6hQu61V!NHOBnT}G`lr)#<$loTq46{MYEDm!TAqPGu~UF)|E#SPxhmhQUP zOkZTF2R(b-_eyF*sQ)oqlpQk08t93g4h`tvnBaV@4kibc`JpBu#O`c91T`q@Ct$j`5U#h`UKuNO8!K);kCP1N z<ycufGlHmlU|@e2qN_2W^yb zuu0k`&7%M|o*`|>;pwX4%Rn6%c^|Fj!$J!#C&}NMng>RRUOGaOXIHHIZo@ffoybF> zyc61$+9w zac@1P0o+Se^o#Cz%}A%X1D`0ZAa+|ySH zr3M{1$lROc7S6}E-~_ZhWcft(W%TQq0_0PkNhM|2W!bre22B8XobVyYMdp1pVT_hs zKa=Y|O)?fFMNo4oSIZ8-eVhGYg{ko64sf@fn{7QNxzSxcDC}2a1gK@H+&}73@G}z< zQ(~tT1kr^O+}CXL*g6f98pheCQ-$$F0A2=Hk^4f@L&PvM3cusC1xv)G8XX`Dmr{jS z%yI8J#me1>HXRGvmB$8WgP6Fu+#Ok@OIeVT>#&76;$Z zOqrXNIycF!=MxnG4KOUp-<@%E)O3|OcBLbRD8vORI~7Hua)w0z_{yML%0sMB0DxLM zp(e8v5_|>rpR*)`ovjBXec{Qacx?;yI%u{U;~9DK<(MSDlE2t$eQb3r=wLP&Uj+(l zms@Q42ZmxycqWyW1fr^wVrV5c|CVB$oW)NwbeFTc$E*_DY5f7#s{9bEoJ^}~OS?-oA7Ef}S%@5+?`(*z^=qKG;cw-v`P=mNzC7_(0Sczy#fG!%O#}@XZVpIV zN&Zst;X(&0mOR?ck5J!bst@%go*0Gd9@?1Q3sp*x}F|EMCyAE560^?!=@Gc6TMU zw4}uM;TR1UwLl6zaL!#7s)1m!0JJYyh*D?TJVhu+qegRCw}-1;{0Fa}gx5%B-IBcN z7G1YY$ccy5(A#JhzXO>lV5N(8@k-m;Na6`O4Np(9R8Z63xv|womI?pp%{hp+m?ERp z!+B_#&Zs*x7b*ZWRRUvZ(OdHr#^uUwJ+`=;I!8}R#wvl*np^5G7B4TEM&hIO`(*Ku zCfrs?dN#FWhNwB7x1D8*Epc#{oMlQ#w8Q4@$FIK(uYb9`{b_jpUBq?8SB~}`N`r{? zZKD-OnrcN4%$St#PSk2DwI-1>Bjrw#HuhB&tvRlg?29l7jtOPqa_2q+*(ooyH&oI- z=)mEbQ#=4Z7R-z*7lf1Q1}SZEqPNc2D7IWT)$WKFT|3BR0-|8*>e z|J6tck4Edk=(IbeDf?D4=IFsNmd@RV7qFeJor?#c$?|A$=8XW4yR0*G6(l*6ax8Jw z^1X!NOT1SQ^plDcaA+J^6^;BFoo2hjR8)nK(#qZ(+Sy4aZK8SdFvT9C_c-PHN62Or zZ}!$qrnN3z+!GVKYC5UJ^O+{hI?g2`WRD{pm#0L!1#;JG+&f}o0U2kg<%84Q?@#+8 zp`=3BbYqn2Gp&rGycN`~fW3$hNv`cl7Im$Q5GVqh^imtt zlLTsXdLP6U;_OXX_SDG*!D`L+>;dbc9R+y0Y1%-lRxCK5J2F zGppF@`{m`aklV4l*Ez}`d2({$1NRH?$~b*5nuP{5IdAkyrInO2Lprc2rj>7bRYOqZ%d- zrE0yl8&n#!tXSY~f!Uno)aRB?T>&#KX+U|mHb>cFp8<+jNICXfMwCJ|>z$~MF5H{l zl{TfsZu`?@E}AvTz5`=0!R96vBw657gXegeTi{(RM$gJ~@lB0s$L0k35$cI8Fr!@Y z7@ODL%`9L!NA`NACoiH6ZJ%+l7l0IlF+pg;Y1=PFf`y%4Dmfc}il$soU_bx#PJF0U|7ns!J7H zwjet}%pTUiMMHthMo}Spc49LCvSr}UA>$w%e!k^NTNxu;gFFXg)1wLU{f}Nhh(Qfg zkqaRH8SgMc1o8g1a8o%cd8_4wp2Vd%)Qfp>xr<_nlEI|W0Vq^>_Mb1nITMhjvqFG< z%gp+iQV^bJwF(Wkw;DwoS*Wai8>fWcRhG5bx7X8<(;f{?65!FhP&)^9C5e+S+5ZeS zRRU8hM~k@sM<`c@oCRREaGJS)E zBE%URYJlAA`z&&ZLNl$ojWO0;V59@W++Gr8>T1J*jqfUA(c*I6455b3_B!z8 z0{iit4H0P|VX?0U7*35-1Y|mGy$bH_#kLm)Dr|sBq0GJm3dhAT)H6dH$-C1E==yqlVP>mcp4FS}5qTN_&QAF)?te{U{zK&mm zsRfvdkb$9KmVCAL-sYyRn(>q|ZpRf(Rk4 z{+Rg4*(C#EioLwR$^ zHH;q)I9JW-CoX5GvO@ImsAg9QLqNArlDyi04Rk0M`WtNPc3>Ra!|7;0(kO{-gk=to z=x#!fLmMmhf>Fzk-Y6;5?kUAqByzglX>*SIwbvXP`+MaOSiG&1^(BmHFVC!ZMx}%k z7O=|MYRM3BG z)mBhaG?aDFd0Xyli`ng{?ZciFGZk$)vQei%H`U94;ASh!#qqarx?ZTO=|(%iCT#XP zuPuZmP_cB)WQIQXK8+oBB$blaY)jyv4E`7B3(Yh2+glYYnJq(NAl=kXxsd1}kElyR z6_M}X5a3fJh`*e$MJ7j!)U)|cX1?+)dgCZ=2VF8ibj6a5z!dAZsvUBuIZReLehWAc zVgQg%LD~(-VhR1tn?17*7wiGZZv*7N1QHFMi3htjH!Lq}XOw%V`?=V2@7{twQah*f zq(<-;{_NuyI^`UCuo9{GOkZnscvckf>T*BvO~OTI**rPhvL^t;YR#VF4#Q;>L|;h7 zI+~dsAumuxU$E#jmDTh={?*T*5*(0BU3YsD>eT9FxefWJK`AoFgbqGGt8*SF@}K~i z+c$qp0Cd1R;-bbV9Qx`28`LLXXK^x+S5!1xt3s<83f;?kGaoA10Y&nDsMLnR@@Uyk z`59)vLojV&e`+Bww2)wiW#9X2g9kS-t6VJ@|W;Wwx=U9h=3Y26Ty6r&TnuykaUnl^;%wzm%3l4M#A7naIoOwjS3#CRCsUBoA)6%np z))Q=XGq?)i=uux=L(-J(Hl4H}3UxK3-pmKDe}R9Meu?o$@&_Ykg}qcA#w$!O3Jf3z zA2IbRNp7MJXbl#J$x~ZnO*KG$3iOxo^2O!t{}o<-YLSRIA9-sSjjwy;=r#;Mbr?_F zpGFA*UP$6fY>?X> z#fkAIzUa({`B#8+BtduzPVRBh`W)Sqc%x8`8ZXbg1hRtR1+W(j4rIzy z#XFc2bP?PDQjT$wIWc%yvK?(hNuoefekNUaR6s~>Q%^EAuqp}RwM_hV}@8a zSH$-!X)4?&w|tfa5^WgC-yD-ERV#^7ruc_Sb;2lNPs>}A&x})OosvL-ljKCT4p>$6 z*&Ez?$TA6T7kjNRBww>DQ#WN7`yi{1&pC#Da*ovM3#`2O9nQry5 z^4r)y{vvjZqcGZ&{4d}i@Ja&k;lb#1*jX!UYoNHm65K@!`avf59`AUk1u%d$c`mOE zuS%g%8Wb0z#SquFRTNRRoJ#mxE!W+>$1r}XO zU3Hp?+mX|L36s~>839A4TKwKP?OO^e^dLl+(|kc+o`-rK+H7d_coPs z2U(Zf&bY~e3@L$z8>xX=vahGI(x{Po<+2<3SMe>LjwiIjm&_a2ZdRlHa+7CK1()r? zf3?oxA^{ESyHKeC#hSyM<6I01~VJE=Ug}-`@ary0suOCVn z(2{qfns^jo>o33n$QjYXy;yCaJ@QHEkxju8EY%m{loGqf$^^-+jw)N!D9V8Tw${ed z>69JWB>*K=Y%Y~xp^qgveJV2sla5M_Tg)?C)*^-(`uX3V@o9emUc^3J(A$D$6oOjG z>~BPW@&r>x)x=g`C-FxvskY2x(8j8<{Q`^g0?os!$xY}(f7`Fv?2r$t=qp+61%emZ zCMTIY>p}ZNYG%-Ftg-~?A!><1SEWHwOCJ9-1ZUaI0nt#ok+$!ez*M|$uc|7**B^|5 zSh>STj&RLSNAbPQKmuBjmgJNIf@+82)Ix??4~aD{nU&nX;<*B2Nh0JuW5=_AMs;FMYQnaTj#sS(@MLg;GgDxEu|yo#?=t`@#Omj#`*xbomQVt*e*!=%Eh7?A)~f|UrozA$jv9(Kxw zVpJe;uOc0m*RsbAPW+fyI@wjxf~CuH=>q+Ips98QaDV@!iz+OhJlNy?qIR|-@E)%H zWd~e)F$q%^yCal5Oz13HlX6^2Sdu()_)}CIN&zqC8f-hHP9@@RY?`aNz$~S4M#D)| zl3m6jFDSCqwTCSG5*>6MXe2KPstDQA=6Piy6NZgal^I_6SeVVV3bb$aImKU|%Q+F( z&0|_1Skm?-24>FqYeTYbM>A@4VYMbW!5fBfrhITnC9G$MDfmrol7~_;VCVzJ-#DTy z31Pi+mC9>b@j1c_|W*Rgp9d05q&A_ylm{z*LdLO&vl3nH}kHF0M z=I^bZ*?&bZh+F36BYqA15bs5f!7{M@rhKTb=fL$I*fw5JERD1hL6#*2d7nLJY~a+? zRfCal8Dtwa(|u&)x`if|sbXKE3cI6+6^8rZFT!`p1{#SJU7&sf*!E9M_V_k6(7dQQ z(!GHdWt($cl3kW>MI3anuM3pqKj*9&Ic*4SvKD@q|N8}^eZW{s-CgA;g`tMfza{-V$pzxJQm9 zz8S`v5|$k`(u7sfELQzPdSG<&^yW&Gt8A{dPOUvzdtF;yqIn79=)t68lA}oujuSMi z9pOc=q}B~azftYAmP&^H=}|+2FnCCYrghZvd6j4c*pYi>+M27^qHQ>|!63;+qg%u& zivT5H0<1zL1<24&9w`G7Oa)SbzOkvManKIM05ufiG%AC5uP+pzO!*f0SCR z{>^1ZJLn@|T8ehV60r_*$jz^Eharm*_3Av_VSWRP9sR-oZ2t@V0KtmBbwE;*G+I$a zoV07DZajB71~|>5R*JtAQ#^N6E5b0MmkNg}xm`%+_LsMxzyAF7i?^Ri=rYvb2G>;f zMzEJ;8Mu|;I-k_PS8WQ}!&kMEhUq&FD>5JzSqP7U4l8x?7qw-2qHWQ;C&zZI zwB^NCf)uR)NVU=S+fceQ;qfqbu@g{^?@LslbVdZYJK54{Omq^mtZmg(k<@Qi*!8$M z)oG*d*4+nPz?}mXgC%TE5!&83#&Tf^sBY?$?Av_rpw76$+Mpf@nfYN*U5*c69c0U3 zMbZRF5;VaU@KsvI|49W(2)5ByyMo)Cr@S(HZfVLM(S%9HSXQl8CO9O^GE=8gjjUJDcQ%E&uJph%q^bXlexM4R|jmWaHH zPzbG!PU-od!t1Xts^dYw@f9ixk?3F2|FaElrBJI#OM!zrZ(u5;tLI>dm*@RSeE#TT zTN;}*4Hf@L`GB6KA6has4N0c1(qbvENC4dFyWY5MSiNYGxUv%|X{jVYlY=;AALXFh zWWin3W=eR#OJ&(tPQDfX2BT>xR%U7FUmv3`a*P1Z697DzDyj)5>to;^{Y-~}B(T5n zUzwNzh2dM|;2{Bn4TK@D+BG0`*I?7Y5-cuJ%y_L#2E>fB?+pSkoN%OQ1Rq>8(^A7J zj%@-88ap9Zbb5?~1V<55;f|Txe}DZ#lFea8KT)oDalU$mmYR0HXjePqm`^9~6o)zN zrtg|txRxL0Po@|SGDD3~b#DP~-7rc*w^{Z(0Y+G|vl<53Wh;6)2Dk@d4{_8{tBzDs zOvn1l=%=`sv(hSZ;3^mElDj6gJ$YzCU%P|*Q!XVeLti2VN-C0 z&f*D}p%U+RACbK$_B}w}#KwiHSc>N>S(8ICH=77t`zS$d*pDk4G{qsM*bex|7!L-p zXNDuu7=X)iOlmM{lZqz%`IJ5I8_D2t)SxkYSEak{hf~DjdfJum93D&i%H9otDE7Gz8`0+zX=m~Sonz!|6nsFQ-zHX~~URA7$1abaHIhdN~M+%mZ^Q z=#{D$DAdUvfbp>O6za2f+L6c5v^fxk_Kha~yBo$V*^SR+#^EdfxZJ8$0(Ei@2mF06 zFINbYv59d7NF5a*D-lgb`it_A3~kh_Q4{-LXl7ID4IJF~82?)S`>)l%!`q*~eDnG_ zy4tVb;-4>HT=sRQwF%DEooPPWMsm_j6UmgLT0f0>feP*5Ndgvt<>Ap)Q4{%iZTEmQ z^@G>nyJ{eDcF>0{N$-X`8QO5Y!--D81C-}2)AoA|pF=N+;vlbW#@44UPFSh@3W?K1 z8n{iTvUYk$mG3G`5MV&>A!Fs*vQom!!MX)m!Z(qKImu#LM&U6;7NZH1Ov}>6{(=(+RhXAIkaed`U+QaGc4_IQl-U_ur8l*}G4>IjC%yc>jmA^Zp3GPWhJK826)ItI2vgIin zG9&z;TVxm-h}OoG-6@+ux^mkA<;j6)GK~UsEY!2TZ|#sQkm{+D1BOy!2FKG%ScVl@ ze1SiC{V0&DoT$pJ%92>$s7<2>+2+uNv)!e*PsAGZvMoOV8B{NOqxYsfDyy!*Dd?lH z0}ED3;Nx?EXuq6thGUj!a0RkVpJ{S4eI!2^C2b9DiH?qKBfy&N%32>)O6Cwd#cg=r zLF*d)-OjrzqeAQe;Vo`iITQe;w^t78l@)UNK|Qz}9a}`5&ny7(#F8iRjw_24Qq~XI zWhGKZtf?Y_blf=gS!GKH2hWCPS3uWO^8A7LYG;cOb*_X)|1 zt>Ae*BAs+gv(I|(6*VzeRtmPGa-k<{$~FfQn5RRk#~J@E+8)mhLpC8;;5*M1lCwq5 zMpX>`AjB^bxWnw=ky#AiQzLOxh2phYXut#6-;sE)B^!n)HxTbZb{O=VY)@2}8_;QB zj(9f191-N8IAElBd@HCIYRhio>RPB0ya(=R8;5?xxoEU}SX>GXBW1Qxzb^#%v{X!a#27vFr;G7)|r zpdOmIUAIY2Ly3ND+}#u?ZZEyu3-@6Fp}|F4+Zz6&uI(&$V8aUVj?*O@+bddXThFL6 z-s~3Hss=b#d{QpUuBARYfW1Hwcq*rHblKfh04jK{dWoD8i$E$q44rCM+C;CZqDbq1 zu+5JNRJLLK!{{d$d9z!yBmN3?a_biqxR%bDwF$|Y!!W~N*35~ijwvbYzXZl~x1*CS zQ|!HCcY%HPjOc$K26gt7906&wIeJxAF`d(IbSIVKV1y8u$MB-~TTBvwrxm z!Td-L0Dg%eZMB5AM)?L@kQzp?xd6rfcEguqi!yv+wTWL1OpQ;6l;T^0aCJCdK0h6C za_-$G7hfz+le0Xxq7(Dd4O)W)4tEg6Gt?Yf7<3qs6U&_r=6-h%V^~&0;odL~5E#QB zT(cyO0zZLqD@d6x+f}yfYzI7sp6DsWU$f8ZM&^wkEj!)swE~W%Y^7RhduKe)5ODe755vFLAN?=kANA`q1o15!lYKsoDx2mO zkx9iL-70&HfGe|%RCgYm&Mz(NEwoc<2D!0zZLoapM&wNEc0D4{W-b)kZeVBiYl6J; z$PHBh>{B89wW_qZq`8%i0-jop%NhHXGNrH2b^MKdTAhu1cH#Rkj3hC z`c-le-ou;3hkR0$M;Js7Mfr&j<{!d;k^f!L@?75DNIS~Smty?m={5Y#zz!r7oGq6_&H57GJR;30RRCrWfto@V$K~-Ud zi6J9DNRe!@fzzFo8KZC$=DGF+au@}bWCuvDv_W{3@XyFW z?PX#ML-HYbGZ0lckBPZb=_D%C?BUtu@sx!=OHD!rupW72Ns2bqzc6?vl(RsYYiAlP z`KYrdx4T`QE6}8`^F^|PjjS#v@>;H zORRp{rWWB^yz_VEE!(Sdf!lG)It(iQ5i#QtbMyAImoLNXHy7pDz%ANc_{>dg)5hYY zgf$=r*Cvv6>&w!>qVh5`3JeNp9?&$4x3#S*43xtKtqD1E>sC3y6+~BivSl&1)!d0Q zgk{or6=gov8cz)*e68s~1gZ#e#i-V;TqLxpWvv{+CAr3^hLX^dLlah$6^I&BQDQ2r z59^`B_N7-zWlMvhm>)&R9Wqq}ugJrbB3tX|T(CHwDtE|#HbBjt0?Y3qhOM&t4Nu)a zzWj-E15KL^WE73$F-!Qv%g6D>U;@5nRTt>_sM6dvNT3~3?@Dze<|b%|b{bl9PxpsR zmVQs0$D7J~SHA2gpi7tCo1ja=5*Cy~hmO+RMp%etQP2khIhY&Zp@z1E+yJVwyA%w4 z+iueVz~WL_pGU58ze~94cDG)rD)%IE`p z|Kms#{XlY)0<9s~%{aqy*fp?T+6dyelM7HLoU*NPnWA33T2xhzgM0hw_y3{_%WBLR zH`%cRZ3m;s9WqZCb<5v+*v7;T>x_^wtMGpxMV65dP%8yoKKZ#k3OM*lxICl?oe_cz zMOf}Cr)672a{dW|`&yl1uI1V@eMFC0urQes=WFSt(jt0=E-o;t=yDAd`Wzjsn)SKr zBNMNN4Pbq>$DK269Gpdi2Rf{{`ku;Gz~INXtWZm+(aC+8$VoLUKH7$km6T7tGjBjR zS3H>=sBX&m2oL;^7y9lf4SrRY(Je5|5Gmj z_^2=kD{+vA!79GO0)XvhKq$q znU<~P?73R5?w3*#$#WyDSXM7g_d;r3JD9EH}Aj#gr59JFZH#PiS$C2=S91lWB>fASVG4 zvL7n%N1D;9O+d93$9d`i&@t3Z0itwheC65FR3h3O?83zn1KOFNt z>vX9#_@w48ZL~R);tLWE4iqin`exA)LpW_AFqI9J=1p!LkoC1xA&N}{$<+d69dxJw z0~CxdQHhndzTbWlUVeRf9BeIVQDiS73d!0&+tvIxTJ6=LKgN;sdE`%}&OL1!)KbjsqbSX9QhDKE!tHs6|rves|!d*^;4bJ!V%nw^tttZ_u2)bs9T@|tf>UW!*v>| z6%D+GkFNm1k)k%-T2~u&BAgJ7aPWVGb$W-?r zv+>ZaLUnXi+gEjY%Uer~t0%d&MMY}el)Y%!VF@LvK5Z2E0y>3rIEjeQ@ymj__FBy< z)&o^qD0L}31Dx)={k7K?Q{h}9;^c^s4}u*m`@>qX@Q#r>&X$U#S`q~0U3vMe%7YRF z3uCZP44_%Qt*Deyk+2qGbX_Djzv=AKv!KhSY2ZP#MCpFir{P+6;#8T*z zryAF8l@t{s2%B+yQ~MO#ap=3X=J}H+O57pae%JIzlF|yuZ_Czz*QY9(D(BPc6prit zK@}r(k>f{|2Drm7NU7~0Tgj18bhh)dLw!Dc76iR9+5ktB0|zITkDwQm)aGGdC82HD zW$PW`SvkU-Mah;jla~XqFUaOBE!<;CvszWTK(!ur*Sf}Nqt8fM0e?dxudG#1YUD4t zw@_^{7fpM)d*XC<>ZB)C81m=clXGT`II0)3CF!NYF9~!%fT6IA1)#Sr31F`+s!-LW zf^Xay9Pky^*&Z|QF0^FF_RxT{QwtbxZgJ$o5of{E5n`kj)e);ziZxdO1x9g3{ia?l zZX%cg`KqEE#JTowUQ_UeR0YM$(v0#>B9!?n-i z;(D9ffD?#-9N(3C7q=L^W!Ct(fD!D?dnT%!E;2Ol!ROc)}x(qr-Z~ zSYZST4?t?dN&lWAD%>`&$mcwWjEc<&c#9Zq$OBz)P)t1r%aT$A7&%2$@TLVL% zwQ$IZ`a(NgY*RU#(z9V8DjiU+)lFRZuzvyrSE@xh;5!QN)T#y^R}oA)pK-jm>}Fzj zZ4Uj_1T?obS4w)tzeMVL%bWnYlFaFmMqfP!tQjA>_Kj4qGt1*F{y>8^Wzx_WYL)0n&ZM!*bOw=p8 zn$DLkQ)U(Uv4cet%_!$E?>#aidzgbd87g34V*w*ehI7SC4%6d;6NHBn{>vT+a9oq+ zD|>AREo_6ZLQN=a#3`Y{k^rL#owTwty>5v4=ujbY1+Q?`k-M;&LpCU3bzzEE!sEym zjjWknRep%6l#d+UJ|hX$Ny$RKLaT@@FhV7RBK>8aI>|E9tO7GzRXIY4(@ zLei5OQh77CQIi*lP@`Xu2)wiE(KBFJltW1=XgTM#lJikU+(|xrhZ>?HV z7iNhBr8U8^3^%?B8o6k)&Jw7T1-h>UI&CW_fN&no(#13M!S1<4*=vysQ#AXC)V6LD zMMBR$+5VCZ+1qL%q_VfvFVg1Kbjfxvxo(=W1KejecVJlA2!7Vq45r{xRA`bb(Tbp_ zd6}dF(|M>5+Tr-sOdMYDjX4Nto+^o%iSU9YiH=|I-&Mv*G+ZS{4N`=}r-m?)S(o&R zXVR`wQOi!jJ8DN|zvk1Ut<-+Pg0{hh#(1RfY|}| zwlEF@p*Eu{z)nGlk+)psbu^EoadQ(R#65Xc}J<0L}??*)fccwc#!$XWTa@yZq`ViX|dfEw8rMQ=5 z7@O%cu%|u1_l}!SLF@BraZ0BB889Ed@E(YL+DP@uAo>7d?!8SrsA`7CO1VC&LrB@A zt&kj*<-4PV5@!h`C4}>EE$&`w1DcOHsrmTw00cl1O2}a1Y02x?&K`*@siz8Tje;cU z7OpxMbyd0xX=Su+`}3YpgLz@7UDTz$>bcuwF+-IwpkZZOt3v~gQj$49Wz2pLH%SI) z&BB0GEwGNv<^>_7I2AYFy?%Jsh53pNX!)SCoz+|Gq?koCbA+YOj_`yZtiwKvB3K#> zG2&aMnbtZs&QSOW9X2(AXgO#`ki>$eE`Tc~APSD!(CIFiiyW%!UbUC{pynWOMW}W; zzM0V~Viu7-1vw3dBj7q*$p9W`d;%ZX6L^-_NZwMo+AI+%Y#??EwkQuzWOp|iKx*m3 z+gTrlGx;4O148I*l{AF*<8Fsd3snW=_>fywT5AQhgPd_|b&I^6xFm$#X`N9tNn_c2Pe%S;pg~0zMPn47ebKb7L27GRI}F4bbTfYer}(iPh@Ka%)*XBD{*%R>BF12MB>9m=1?gX6Nlx6{tJ@GOuH|M{#Sc;i*`8;^fJxp zc0yp<-i zfwE}~z)g6KWPjNTbg_d4W6D`EJK8Do4&u}-2cQ*hvO0Ej3w+wYCu0N9~C z)BU0?Ar24IKskcRRF=DX&Vre-*ijn_nnAW5Jln37f{9T`W=^(tj{V#JSIwof@o62KEeZ5leh-yGqRQ@ky4%^S5f$y8t#dlX}uQRTvF{ zJn8>H72L@ynX1^7uGs$>Ea|9U;Gmc(x7`W=H%ftE`nY&|d&EUOICWid2vmS`W2~KK zcS{8s3cI5$P-a_4*f^ZpWQn!V<)z5U_vGX)&KNVUW(g)A*rUW~e&P;NbEuMMocGSq zPQnI0kRP2iozZSs-53$mHgLH0%mgRCpf89yL=+X&z;NMmf``&-5vh(KO`cRWcTAn^ z-hna=Uh5!1x4;u-m#Z(=>X20kBPwI^*2XA^-{7z?+df4}(9A+@4iF^Mn50zT{lgZ3 ztv$7CFnXM%WWc(#b7FGCp-55C3qkm+Z=eI}(*ORw8<8^FEdr_yao1; z%tPG4lRCQvAhp_v!tbMonttxkSjh}HWg+TWHG?y=FRj_tzal$O+2ewgrfVCaRR*+v z!tr;hwiU37ENP?`;21YfPbidKRqi^m^~cNRz=v8h;-q$Ou;_(AU6Bl!nSgT3f^mVv z%6fB`5eRjH6HoJJ$W<%^0Q3-)O6hcNvPbb96m9vQ37nOXAMvZ9aKHbt?T5%6y*$ns z?p=Z6uvc<-2S63=g#ZZC*$E(tz)eY1@gd58bOaTPweLZhNHm;M67&6yJyr!J$VmcK zW-{0%3jq|)0!t=kit>~Va+2xBwj-p4(ikf?tVs0ZmWkb~aBD7+Vq_Oe=RiqhzkT^U zy#4(9|Ks&H>H}0VCGQo(<1WLCM94Uzg*2x<;32DggFc#2SUknd!QL^Z2v_b-$a`{5Fj`lM-X83o(AAG-}~l9XfuzhF0cYC zz`07BQ0LGIXsy>g1DJAjmNa6nc|lD<+!>Jy+Kz)Sg{QCW0MKEj0BVaI{gK2V5ELzD zpuBgN8fA%X>4=ehjG||aJBZ~wWnKO*YH`Ih?%08X2qZb*p`f#Jr)lRIoSs=b28|#Z)cwac*+1G zW6}?qqNw!q4bL_`tDS}XI zVF*lBvOAOJ)tdazNFM?hA}(8}nyE{pZr}JVPE@*tLmlU^<8y+ZvK)1Ca;L_OT;#Kj z1pyRkl_yqJkg{F{ z(!;~>I^Yyo`X_~lnneF6iEKgo*%8-7py%^|BLa3?49F>|vg1ocrRP3(SWduFqJorljdn`nsQ|kLuv;US#pJ4Hc?*t{PniJabz3)_m(}fR zdtr?dW=Nf+s3?_OEjc6=OiEc#a*YysCDJTbl4$Fh1xbZE&|3?#6{7>2Z5XkOh?~KL#@( z#oK?y02pVApFnHoT02W+t|5*Q#cUX(btz%#0XOR294@-umCllT=RywxsWvcA$q7Wx zam&3dis{Oh!>U6t*Yc7z*r#+^5}_>_h7trlx$U`@oRaW%yc{xJLC%}xK~2uzud8uV zmr4tXPeCh$iSp2+i$><)_s2(ehb;_du+)>pnViK4_r%L@H9t&gor<$vX2N=8iAXS! z$}%HFevn`}0zq$q9FVU!yA9`Vk^Qa8;)`NlH>z1Q8HCL*70%VGyWBxe8ucT$ab7`v z_q4`;Ch-G3Gfgg_`Q$7B<@Xz=2IZDKwkLHYB+5t!fh-ZBWYR)8O&* zL3N4K&k|4pL_^m&fm(GK5v0ag`Wn zKa~Ifrm0NNnFA0$u=xxQsvCD)guS@l`R2GjV$4~PyJoNzc%nO6&l;n*-0h_m^5$? zEp?DfrM=5?^86|S-3`L?vxQ!e606Y)A#Cqid-#T;ZB8D!_bMqbs+11p0zs8pFDe@m z%4N40jlSCC1-6PD`9u-}^Mh9&%ALKSLPa_F+i!A9lCoXeHZ%ZjVrXWVo)R7|0Im?X zqTUYb=*LbaxQX#Y20Xxl!JnDlz^H6>c9PVpZ1${(7hahGpx9q+@xga!+FSyIa%HE) z5z18ytm9TgJ2`~_UD`$o@8efXVLD`@scIrCcS|$V2omZ zPGOdVr>|B1!6rWs#bv~Yn?eVa@XC@C>eBU{=YAg?t^wtQ2dfW=fZFC8W))NKaMJGz zA|%%1w&!4}R=9W#+Ro0cAT+IBjjSjTgRG`+)#||R>>4)Z2}xBk0_mU~1v{5s{}NvR z2vACAmhd1N6Eu@2vLw`6dRiBCv%Be`A1cugL0VqznEb5d4Wesu2Ob)SHP}x2FP^p~ z>QsR|!zI!wqdtmcWus#kd)PtBF^1{`Mksa`jbQ&)PRN{l(EnI0&9GEw#wVv#e}Pg_ z74P^E2> zLKCuwAetny~mcsUpdWk@{%$m|-bT}cS`m)_*|TpaYIgM+6gM@I$vbWPp?`k)0heG77C zSF8#7te7tXX;%w|{l_8rp&I~zJjCIL5r-2Kv zqzL0l9~HWm60`eq&!6Np%MXkkb||!6ch=wQblpzV>fvy+liOYb9BIw01b434td|c1 zS|?BiK}$7hhyoUCXg*Ad_MSaaS?5hODjFmPp+Q<*+L=zDz;dXDE`Q~0H=6^!RE=sS zm?b#?6;}XlHEPy2bRN26Xb7e+XB(O{YjUzOA+C|iU*Rl#8jZFJ>z{=l{5{2PDyL3A={AMKmdac>KFyoxGVWH%CeTDOy{sZ@OJ%L zOz`aEGTm^I(DSzS2NH68IC5D#rKgtQpuu56NmHp#G>F$GZV zvLl46EoSBJ135t9$9Smy1f9ubF;w0#)~M|E%J3Lf-?Is7Q0D^-Ia@scRn<%jTp5%# zJA1K;Gx{W|zkFyHUvwPesTVZ|rKmU&DB~^c0H;Ov+4^V)F!h=J!iVcTh>b2itVsOAy zoMh3VHw{_^BgGYl9<2Dz0=U)5U}u50D+QC8CTkOt^DS5fITE4SAx`SZ0x973?NU>6 zx!OZ_!LrbvL5t=_d%}!j%J%%8ee-W#zKIJn0*hY0xIBg48t}688=j#CI!2&Y*I+kU zxrWtb@1(+%bEP&OY6%}UmEnlE7gIUUG4tp219G%yfv_*b%XeS^mx%{sf_i@(Zzxdo<@J z1zHXu4q)IZ)dg9NiS(o2qG=1aG*=YKeQ+d8qcoN5REW;;3Z$kiajsHmOA4QO>+KcEX zDY1{aG5XgqA(KOqj6YntxdX{z;4O(wl9CbvO0EA=$r>j%?OK&PwmAip`k|;*G>B7s zV7aW50dQ~(uFZivc@SNvHwn1~n+C{6K~JmlpJX7wsE~lN@p6>WmVG=>>F}t9(fYCz zHnA^s>)i$L%2jUd$zC0LIs~1S zDz*lbpRskgPNCJ5mszo$Ruc`a8B_cXP% z^X&&Op9jvL_xX!lREJyOzF185EGWoSK#&Q`0hrGN9>XO`isQ5*y&F zNT6B^%2ET77Qz`+f}bs3SPTHji5f#Y|CwR!Ij8y=fwdBD~rRh+}+));# z_p`l+|IMV~|1*!-Q>`ndjU1Ub63V2ig(?BG!mECo6Ce=&!s{iLcqiBk@Ff;q`;eQ$ z_5}0fDgxXZRnlr&GIg&llxF*03YemDf>Q|)PZK+-LyUH|jZgY|wq_q>*Tk-`{DIwQ zjZ?0DcIzG4S0A{oRhx=9rnzN|^`-?_ss@#E7CZU6CH%u;pj7w&d4~fd#s`caz zdhyU&M5v{7zB-<#zO z5l&%iD$^b$-kLmLTQqNf{`w)PQZTRjL}G%%c=pjx26@xYIh%Y|1*<)ZfMyZ~$%F$- z3`$G++1Xg>IEt(pC#sb%WweRQFhy9Vy(Z?SXK}RgkXRe>+!8zGe zs&iHJ8iEW-g>WAorGx7lgoay^vu0TucI1ZA(xYbgZh@-xTdV+(slrHJD_fHRQ7m`7 z3ykKl3f|~}_4;XuUm&5+*hDMxBCJ;ogewwLi)+sXed;5 zSF5ZiflC}Ne;fWmzXPJWg+49BO7$mi_GD&g5r9+*6>?=RGwL5((TmA{c1HZR2`#TWeEG>j2vO!Wd zw5|OlpXD_{gd82J$$*+SbpSGGKhvptLgUplt2U zo^z@G))R#8An@R=j_k=XFB16e+TZ@`%g=xSiQ{(FY0IIF<+z*&Izx~4*?D4UTXN2{ z4~o_#$)1`SYgH`JAIWGBJXd&_sk|8E-o19{RZwx|83|RWL@z3%t2S|~`?6KZx>Yer zmd$~|!G(LZ((UapUcL@5pU3-<6e~){TU>7e`jGHqqJP?W9;sUdw?|2Nh(I~yDVjDQ znwz0B0yW?tayAu3B8zwXGs}XjX&KQkE|-$K!p}f_BuV{{n^2bYO0cgS@iZL;hu?d8u-}7lp*{FI5LrK3*KDuW z^ysrehy3Zd{B?N!ReZ2bl7(5p8Q)mCH!xAdApPMvo8?ydbO62MvOY+EsNe_GyB>DK z4g&~@5eL~YNZ;K^dP&pjED{Ns?nOiwSdjK1K4sJ#T_$B*2x+jOY!&1ISL%5kL#$WTdBduT}DV%P_r66Xy!m?qn}=?Pbb1R_#h*qNtKMo#G4 z+s|MB9KQci{Jjr=;Fl1OHd{~7tYvsyBs$dr2e<_6e>5wb5%DZe31wkkkyb_QPKI4Qy_LWB@&5aiahYFxKP%ZHb6!RA1BwY*i!YnnCWeTJ@ssWXl{T z0)mJfess!w1oj1yxmc7{GeV46^xG#n^rolFW3)NdBPv|lXB;?oBF-uwz+o011C^w9 zFLosW7&1p!l4ZUfIxIEZBgZVE|s^jdV2Ki3OW!9E*F_9(Zg4@oKlQTgP85hvt zO$!dIiwb}6W8ZM>fcGj9X&tcO;4gYo;{k2shukZrs~tR0`f|s}?R1FbIplXcKfNKr za9MVoBXT0KkrB|&p%%of#l+5uOV>u$(q+8%;2y#U$#&i()wzkbOUXTGJ22i6E*bwo zgjE(6?UX03JvmI#M5L&oZ*mvL*KvDT@umilaX8 zQsN(b3Vr)zFG@4enUaZ*VA^4K#fc^A#fst|Elz}65*g8p<>XV6O}Ep=&|z2V7}Z;} z2za!mp{g^*ab7aia6gkG++A2U?WA8KTdo3iieAfIkoVgj8JD$e=ThPh>nvI0t>V^u z*}ew(jfnZSk;OKrAzEJ zp}M;3#cHYlFxZD1(pflqK9g~X7S0M140@ZGV>6059ZZst8>gITr`R)Ei87eb08et4 z)wrgyzH)1fEJAHK!)sxv_Gb4~tb@pryuB{FU~p?-DRT<$9hRVpD zem@H|qF@&s_v)hM-8-r;vU=tz8b!nhkZdLLAv}ohl|KQo_)}DO-@pmtE)o=`Ibvym zWFKrIG)~I{wv;#mOfzNJtlgl7&<)$lK6~y|K;&X5i)-uM@z@r$fao4PwvyW%naK&r z@b-Va{5F^$n%V?$Xw<6uP<2uINlzIT^tgKln-Laux64olD&?u>b5}(GuU%$dKz1rQ z5bUrP<>fq|C5?bU1IvF*o7Tu?Qp*ekw}KjqL5<-lKmnq+Io837=8E^RXrvaeqq0`C-0T8CgNvxIy7ikkzDWkS24tb!WjSERfjrKN{uZgMeGbQXaU*!i z-O#UwC?-YEYDL9j3`4v+PB|8QS@0z72Z5@|u|8Y&+IpyuoIW|5c34?1ZBh6ftsgngoz~!N*rlI4X!AUl{Zg3R)LgIa_P@L_LN{{MZ;A> z{~rTE3fWjB6@#+6Wp|51r7A|M9UhIkv|C(K`{y2p!qz^N(WCT8!g{(d%nS&4q6I8n z@N97a8X-*y8a0!?G~o##wW*5}8KfpACWkHt2bq0aR7%>wq3><*?B*n-g51vk82%o} znU7vRw~R^o@JXt>JjH597a2DfOb=4i5MmaJ$K(8JR1KrbWLx`<*Db35t3sotBqH;F z1gw(Y5jiH+Xne}mBHFYzB^;4kN;NFCr924d%xNReWiOY4B?cJ7;Jfw;O1Be6@&*u8 zCo<}A#1T_bO$*X#IYsU7s&Pwwnp9lhEh3l7QIt6p0_D1CCs+D_5hwWQb=-#pXWns$ zXPhbZoN7yr28OG$UQ4cW5bK@^u7F`~=uf6vQcUJH?}Ok*>Oqv1az=WGhpCo$qsSXs zrM_pbT1Am^w{J?@XB5c~IoqTpai)B}#H!0HJ=LkRSUVyP!r@J|n>o*xqnnZd^Bmn` zY;k3qcK+>bp85j^Q&Ptt+YaQS_W*j5M4zBZ*U_52*H+3_YhA`4B>i4hfN!`7pd|5Y z-bT{;t>Rk*e-{4^Xw z1x3@1$6@QbZ-ndQb}=vpl=6g`Wu?So6xNcxqv;z{N21%DYd1YI|kyUNv(q_ccs?%r%&@iYq1WmmCNq8k+vVi#yhx(Wv zm}ib86{VkT!Ah~)i8rr?z?wXvfIroT#`OQSxexw1y#Ip>gc0QM=;U(kjJ^@~iN2kU zTk#UWq_d@6#Y3E;c~$9vwUWa|m@U_5lJJ+|w$C2uz;&1P;=rumO%cN++?{D9*nD&VJc+- z&ksRnY&&Q#8Q+>Zv*U_1!=fLX+}j0=EkL$T=}(ubee1Y!u|Ukify&V}y)6{;Y4zR? z+MG4@m+TQ}<+)0vmxQ2Y(@EA*(Q1YvSF%Ac##j+*TM(SLcslVgEp0Mp?&_~ZsKrgC zDzKKHC+E^mJcvjN$3wyH_dnX&7N zkVMlY4=(S1whY1f6i~WKf`M_+tK}`1S)L^mAnn_> z8wNB5${UOhc9x&=hmyX>rmR>CywQ5h>2&v2&5XP#Si;?qnStORDJ9X5yGp&oguZH> zz+E1zJntu~;o#BBgGohsmh7Fl@)f@_uEgHVldKC9ebcl6-G*AO*)_N&w6z?PzIPr& zl%4taivB9f*-9a3Hqi||{mVeCgsE}0+@n_*bM7Ks*}sI3djwG?E@N}ioH*yNfqy$R z7Y+;>FDs-ShyZTYEpsF45(0gMs4WTWKdFBN)yaW)nh64KDO>=kp$fdyL=xYcsa7?P zS&NdVloQ1s@!s(wbmFkj*v=f|K{w9_gQ~y^Cs12TK=s~Pt;6-O;)AojrGobH-fLZf zOSJ8?A&q2(2ZOl{9u6xYqVTb0PDphwQW6C%D=a%6B+Xaog~^uLu-TsyU`mz zAm&ibRW;I;kP4!j)tFM3+-XxJ(cubsmx@$aGeZGNvrczzEg6gzCjhGPo1VybFW>Sj zQL#3D`fo2^zx{72!t?)x*Plx*J>gf`G-pZ!dbO)#DvVjCmpD6c{m_h_!$V3MT3Ixx zUTpak4$qLXdVgoQvL<0&NU>17N~(XGVX6OSJxVZ^10~dy?#XJ`O`vy6E{UTZt=a*{ zm`~Dsw-<#(>lFY(HZ$NI12n_PX*`CM6`>O6Vff&p$XDnkT^U)bfvU*1mMgW6U>`L} zyTSRxTp%HVjtVx%jL02Wr6MZ7*i&V8)W9DrWeMWk}dfV zBO38>$zr6*6c?Diqs=3Ek_{s7p+Aw`C}#5r$|(iu`W^M>3Ovt{#LT1l90~ckrIOf^(hmifD+Hf#da}E_Dd5=S55CKiImQJWnWsyX0>C3Mk2DuwDYs&Y5(J~i#Y?YQoGyqv7bdnk|t&j6`kz`(fS)CjqN z-KmdYuZ7expbM~?`_BfMT&sIzrPJqX&03cv>X^HAZuXApYX;?hpg^U@nOnSJsSZqT z4eXnB(u7)S&IhF2$RCAio~44o7_is6j@~_ihnEX6@1aJc&Q`*(QNnW4QSH{qClwjC zGg%IXD)1R}YHA->dao^QiA?0{pof)ASkaoj$!ag62^T;q&@JYP355(JfP5^;&dbk1 zqtmGAq7|S`Vv^btuet7OF=yLCxgf46zGOE!cQ(n&u1PhVn`?~0VK{8h0xv?>(Fnef zno?f@<(_JZy;KdnO5!|3u1Mp2hH79X7ilAvkC`PIttE?s*KXq7n#@0W8c~{iOvb8! zXOEI&sMG<1A*FAA>OE2y1|WAZnQE!q`X)u zx?&ku;AOUuP}p`!Xqn8Kd-tztrA#BADB2ex3CC#w zys+JBU=P(Z+PR<6yDTROwv%3y(=?G>I-kjXW2zH^&lM(eCCXbRlcT~?&I2>1Q zl<0Fn8HZOTc3=x$*rrH5`fNxgP@}``@6-@L8~Hy&Nk7Lv+FVv{d^ZM4Nu4ycTlElQ z7Z@766CXtt`W?8teZ;-0K7%6vO`3jfRi@Buw26Cf0)1g@h=dv{MZxf~HxpdDC>J(v zvgsXAFBhgm7dLl>$KRKVw0Zp<9J*e9s{i~*u{U4o&p$96&d*=IdHr1Z7vJKaFJFYW zKYRJv>xc21w;#Ry{`L27fA;!2%L*dmE)D8XJ(Za+Fb=9GZP>ckalD}^7+t-Sw2bZI zPSvUGnM#>Bq5Lkq9KozA-oIo`s0-RVkC{n<)-(mcOm${d>kSls`5SL}#pePp*B^r_ z!o{{5=mG|p!68Uq1OySIrV1w+&nYobmIh3*jEU!dPvW}!0j9NQZ*(w19N~g~6ES>WM zSaMGE-cuvxEULA$y}w+NjaA~Yl*->p!a=2ds5xTTDj#wU_L=OwdLr^0 zRZaup$sQn4gAc1uK;2$xtlN;Nl9O|d=?x1buvL<3UkoGY?%K7_Y9DMUXIY38c~qFH zMZE+bp2i6ZlGbd9I`7Voi{uH3L*`vn)L1v%_GzZod9`{|!9mB4Z3+Osg0#|-l_kFb zl9%mjFA#9kWtta^Ra@0GQhe;DwKPoZeE!mcNE3%emm^IC&_e<1?a^Q{)(f?&?y%}O z8L??6E6GLLhTLWOT8?2rYhXSASznlu6Cen&Lp08fgWcvUu^+&w>d{qyS=RQNo7 zV}})#276b3?K4L<01;R9S|XW>ImkGRwi#|2xM0ur2ti^#h^FZgWhqxGDS(e)ko?Qi z2F5wu+o?}$7H3BMgn?9s84$*d9E9YOeaZS&?RaA2azK|^RO*BO`t?`V%eMFMHDAcr zQmETgeN4}C-PUJ%XxCKbuWp$GVxdQQQpv`c#`YfVKx=p1I2aLDfiDhvW%J0&_!6#eIRP z%oSsmm7w8j)~Vv)8a$)y-V`ylQQA1CXx39ITkKKHm~^P6xmtdDTm}-y=FyX;d{&k% ztlfK+US#sv-cPEgH#pd4{XmS*CJRP#1*~#Qp!VF-Jg9a1PCIwzWsR{vP6oKdK zGK87uVPJmS54R_X8OH~reeH|0x(2PBT}xspP;(i49Ihc{8#Qh$9_^uo(#^O!(dMe^ z4ICoEryYPo*hsp3z+^K}D5S00?JV67_YNV^c#+^8R$enP*8eW(qq1%EV+ zre);dG*-C@^EZHi)=cQ3+A){M48)e_6Kv|5iJj~YFVabV*(2)!#aSUF2}C%R5zs2J zgbhm#6%`(~{f>uIGm>v^t4AH>p(-CL!H4eIg$_{F4=p74M$iV&HqI-$zjxoT~0J>kU_P=F9(e@ zyUiqqHY1;~Qg%ush7RE9e76XYt6%{9PI{(5*kF(BX5W>o_Q&I&&*X(rIsWyV%iB-G z>z|S8g*&=o0C7LN2vG-ZH)7RVm~?MVZIPz~$Im+C?Kt5y0V0}HiF>;wML*R~hWFb% zSKA3v_=6vWAN(MG3V##dIy_CR@ws#Sul;FjddX=EVZyD!!4vKoVkyesfO-c#t%krK zxgLAkSAbOPxIcU@k&kN3%cz3V@p|Up}+OYUH6E$(nFM8{T!-a|pWu1uS97u0YFl zh+HW=Jzn4B3vyL;eTh32$&s@P_?gnc0tPznA)%#UhIyT`vZR8=2obSs#%R$i;*?H7M45l=H)fyPz#s0@UWMoqK0`9#;6o& z5z!@XP0<^6!_|7qZ@zo|j$gz3Kj2sW(?>=bUtpS63Jv4jf*XcnLFFkGJY{AD{`(+D z&Kc_}RS$%0&Lz}8MOJdHRMs?RDxp&Zu*tNwcYDOarrS5EjXw&M|Gi1tLU9@!#-ztQ z7X3Sx_43>yN(sC+6Ug1QSBfP8P?RZa1B(w{Ka}eDe~OD{QQypLo9t|b6iqnfOI9Qj z5!BoBoVAD~1|a5gP@;P5IFdQYYO(2{%nB5ZJ(ti}N*)GOy1*quZ}wXC$y4GQ^-4L9 z%L9)MfDy?}#i&b>u^`sjy*XtmIuX?b2HOk&HCMu~fs`C5^tVFpY@l_lQd#T<$DLV$ zWTxmV6&Xo_sBbJckaI_#ih(ncdA;MPe$9H+mLwcQ@HJKHEb*O-q0}K+22fhV^!4T)s&!wkM0%)Y0R5)wXk7_|`D#sF3jjSN z0Vf7yR7_$D6&E$_G2zso>d)hBkA(v0+EyLuc+$tT>ui!pD2V{#uxl#Zv1^c5wiC`c z$a(};Y@RC8LgCvjE6tdONTKW*X`g3dsW)y4nqx_GaCRJDdS3_5nP5Ood?)ISoU#LG z+qtzdsu4NO?l~5^qDej}khehv=@`&Km58m|6bkEiFDU&+@W3zXWoSWE9ts8xdQ`;|<) z)Hw;2`W#%F7`{`WHYtdGT~XLh`vpUQFz<3vPlm=is9qOyvpiYxO5UHq2?b3uD7?N?UqN2`NqtYr^Ho(LIufEWOJQ9lmU$8i z6><9wz((=snYUV%h!AK{tsb>@1h`_9DmD{DnL#XSSsLiz!dQ?}vg%BUMuR+t8&~%> z^|a59%)#&fCH$>^yN_3e8DAhHYQ-9K4dcfN7iiIcI8J^aO@aq!&zJ~v(iuB#!3d{! zlr7F1$2ig8uABDynjMp$6)sAF(7Sc6{;FVA=X93tfo=!ji^^YFHDs&}d*~XjB?OLR z03qIvrRT6qt^P=wTfppTiDy~Mv_M7Ka+(UxT9P_k9F*AD=is6VFXn!?eq8eX!#T$CR~C-t8k&eC4RD)kRU4m=fJ8ZKPeIV?coJ zw*t1(pbZ;xI9W#IQnC-h%{KBLu$a7^W)#hX(=Pf-XD9mYe+d8hkN>Ejen@sz9N}x{ z*UC+}7v>J-E+@wVKdf>AD403yrX+RyTp_4C9uYnZj!#wND0J~o#xu6|t`U^v_z;EV z*KEf3&M}Tn5C?;!4V*E3_Ra=6AyGEQdn09X)+qXe+=rZ_Ov$Srl|=Y`%f_xrspbkY zK~X7@%(X;ky!DCN1;bP(_kl{0K4``j^a!KAn6qbV5RzOQQ2mh@@1T${GmDaw5KE1K z#9~+1coLn^zR5X5S5u3)B|rWC$FJXnx1YX#`1&e`B~l^S?( zWk!SwNhqCPDJhW+ktV?4xEY$4!@Nn;CBiL`~JsTPgq!eoKT$D&kBAe7uA}LC$0`eyRm)E!U`c}kc^@A-yyeIFF z8N=Rdui+a&TtkV5hNvn{w9)O4pD-k2#eXNyb5>s>Gu27v=S#q)tU7081#7@U8kTh) znphp%9U#1N0hf~BydcEh;YMMn%!BD6zJpW(Kl+iS9V--sZKMLeLOifM;Om-@DzZ&k zi(q6z?7DsqE?=vfjT1`sSC9udZ>Wbd}0+IOJtYeNj-pho;Bkt zi%5-z2_>xIcET{RME0uW#EBL{@-CL$Ml9LD2n+}*M$UjU`EXa_Qy`AJLnqrNRpaa$ zU)7A%?fWE72u#5OMEN+JVbzMUn|(e3>HGZr?mo3Z;yRp8x_r<9g7xv+Hy`|7{;lx- z5t}%X zR-<9;8l8M035tQ|hTX74jw(M*a)qUA ztixHkjFTQEYwIp83oIr^Wm(x$zoCf&mJmp105w3$zbg^+i`y?DSWS!CsW$WYU?)+Q zu`Jt_0IWniLsccU8#;vHf!4A4YE=f61hHr-PnKjk*^hwgk7o5<jwMS?IVZ= z0B`mSh~0*FXzSR)VT($ORZ@R|62n{dLxJFO4sbUBxFkGP{o4-u&{bW-I_aWnu_k%x8%x#13OWy{@qi@i$?dB?RQStV zPAAPT7H1~OJW(OT-6^@=Oucdfgy|>rFrf24UWrlvl%Staa)kNl?d$ORYqXW5imy5F zl{jlH?xZfTcJ#G${gp`QU2wxdQs?ldv)FtKX;o~iTnmN^p1GBCQn;#Ph!h$0`ll1@ zYUweQA>e%`<3kOUnR1~ft4^>6^f<;*EkfA=N8P%RQ9Gn115}OK6)@aVQ;^oB5{clJ zY$4?bT}a6W40_Eg{hl54x1{@|rRI&_N05sob-PE2CEI0{Ur3_UrJjl3sZ#wS&eq~G z1z8GgnL(E0gtG#b&Wq}8@s>JTWmY+Z*kscZV1pHj1m21Sf6JRBXwQe^HH1nlZxKKw z*V66I9h++;0f%`RfYuztLhjn9KwUVv1l!>1dMjEnaoDqI@CQcIFF;+v3e!2Ey10*r8q9owo=%#FqC!Kw+AHpR3? zqHpZiHrgrOLnN70?Y;(Hh87B#DHyP^iz=y9W6))Q=FQdSONe*EG^x#+;+RPQ{Bu(C zTnV4aN17cPb9fr(%1M?*XgI$?yP{zSPLiYt5X+uRY}Zm{l};-W1^JFAo^Kg_D=CoX z4XLJyzm8G>(5?{ptY)s=Dn?F1s8901S;NB6JYeU}JXOBHc#p$NUKN#~LS-RH4Tt(#1u( zY!RNT8^ln%kge#lKd@7?9`NS8=l-xPh{qAQWVORj!ZpCRSzZn|?^GY|di~a*?O-80 zTn$QmOX0pTJcX7;7*YXB(juRLoV!IN%};aO&8OFwl&~Dn0?+`Iw^qUdC3WavsFWX_ zK5JJNNe(ONl>0l6vi9qVj^)656}2O_G216)`fN>nQ!ytR(@9Nj16%p#gJz?{)>9z> zCNcQ8Ovau@hq+xtkz`w|KcA0*@3ogO3%q}9)__1j5nb?)N96rYmks_<`{IvlQdJLRi~W!z9k~7CEg(=;4CfR zOIW}U>O5bJTp0+1bLxbtvVzg6(+w$kzR5U%V8eOs zqymP!&N}UIkaRTYssD(a2n=Wp$XkMwK!FaA#Eci)Bi^vMr7Ej98s5FmBD?G&ptWF! zz0Q*2!^z92OQ`l~D&IW#AXihqm?3Zpr||U_pd(<{E&Ya9I$UPX5wQV zsULLfyZXc%Vos7P)!a5c1UbcX8mi^50rWDr^2jY#&)W(~G*y-A_m}rSd;K=NX5`lY zZUA=J@o-^6pvq3TU@A-&Bhm45y8o1R7_m3-k%bZiJlN$ul+J+bhb+Y9I?z4z2s-3f zvcPNuCKVU(L^iQTZ6Z7y2pukABc6xweI)&%Ku@4%vO#Y_SeVH-K{JceNcRojOM>s+ zFb1nyZrd<;tp~a0j_51^2NKevK8yHqTS>KN^HX`>**#t=1KgqQ474naHfq6EHYNPs z?ePI$;zKG3nfr)+PIo`mX4T5Z_y>(+x)gL+))d8r=k$)`2C%q%Nn4fCL~aRpy&{Wf z<(*#I)Ahu2&CUllQV0UgT)M4 z6(871T?gCROApAHqVi^)Lq|x-s9d)E9tS*9h;`$x_ahg#W6p(ksvECLP{Cn;DT*?; zZKViwK0Snc(*-6s-&}S#U3s9+YYtmXl!jNjx=KdmoVE3&>5~vi4n6?JOyyQE2}BF8 zt?$%?EOXa0Q!(-bK-a!zqo)bpNNG~nB!GN6I5I@aD4m_euXXJzL@IfZp9Ksm_lt_> z4)(Cy9%o zUj`bDCHP_oH)&C39aM;Bhun;%Pif@jr~ThhH%brV(0=r;GbTj4M67EUpASKkDqdN? zl;dz`8#m7CwgS!c{2bcs8aHc*F5wV?r;aYP^GsAC2>Ojyp&ns<0j_xn4+SQZdxe8C zK^z*0tyPmTi^e@5q%gdsloduBr+o%9U(mFU#0Uu1m1;k|q-%CoJz*C_UxjLgu+T>; z9rjWOX#|jcBgx5j3zECv25)DpVawX${)X!83kc|p!-uMtEr3ZPW~h&bG%~u{%Oi-a z!+FE7m7sXp{WeO3L&+m={n|SiOp!EfG>l}47F$)dM;p@BRHaaE!Fsd?-J=YJrFno4 zu9UD^_DWrOACwu!r(=wxO5g6L3JC!Huk0X6SC`Tqh@miJg`tEtE3MTc4NY=eomchc zvmLLx;aXsG`5oQ`8^p^p_RJs>vl3y-Q=O;MuyQAhQz7J^qy{=_!Sp!umIy09&{j$v zgJ87Ez7&`>>q)XlLNI&)mU)|e1A!dJdF28P0Juw#!;*kbT7ws0D6=kG?80>$*C8{j<5pR8*|E<|#J)^N?(dxmIWCQloVZ1m_uxX8;p=yP4=XnvG zR#JX7z*cJ)qm^S?ZVP4`Gc|au_np>_B>nov!FLT6Lp1bE`w>%&(xoRqfBSuS{gq-h zueHG<&`p@x_s3uwacIE|?4qM{;9ZBd12%%EdF`gTon$?`U6@*M*U0Z45M#2538x-l z0+HYZYE#F4;^K_MYf>P=5SfkD%3o^^?0=QH;S}qr7hi&?24hJ8f@)0I{zoQHl#&&_ zzu>Ro`@fM7AMi=>{!XuNsT&nl$m>z+9rs6?)X%|Ir89PQ#C*S;Q0*=DcSF`7fUBs> zt(OYypG8%mE73ORnvO`MXvc?dch+rjIGW@JCS@U;s08(_qsLKqF4?b|mau@mj^1v# zy7Y zAc$a6n42(~?27QDcNLriIYI7;T_rpN2nH9)M+HxKKi1=ada_IvmdVy$tv7y~yKFAi@R&|ecxiSgV{ni`hca4jF!iTUpzi|&|-x2f6 z+5n4`gXDx)lEPq9Q91ik)|?rZCMr*~XMyf3&Rq5YfkWGfADRy@PT(giB!+B*V2`-) zrl~t9_>67Nn4Pa{n!(&dNtslH(Jpa<)}uYbyl_$SE_zk-advg!Nu5v;FyOSG(u`x% z)yV2L!o1u(9LQC=N!{J)Bq5SGW)}eXqP6_J-!UBBn1#lxL?_DB16nl_=^#5Os@^z7 z3}p$;P>Ph`HaSNfBdw_WB96sSwR z()z0gOKh99pjEpbI|gRxtI8^>&9k@QU@7ByJ_1g5^ub9YpA7g6YUlS+&m=h*d$-mJ zPxfPZ-O--)DKUYkZmQ4;G=RFn?(JIH!G#iha^VIAfpXG8+RLg zRHTNPze2acy=|o(WBq)Rc2bnPT!HO8ry9<9vQu=r{dJt-Xg$L1&?g<3k4i0!7Ro6~ zY%|WB{R2{45fv^a$qmj}#thK1PwbCxhEX7rs*hBo*WI;QB4&jM9z$J2W8JQIA2ZB4_6P zA9PGZ?z$m<6@{#6`L!F_d#o_~H0_$swfQ@DxP%zRmX-D)T*>)uTRT2V>MQUAs2JR+ z7g|pOOCS8<1ym*R3ph%ouaw&s6wD6AEL8EWs>vVu>6+niWWn?u{t0`Hu8Bdbgz zi4JB}f@Lfur7p=yte}#|?g|UfO(nE_``2vZUqi`(RP9>#^9F4{m($WYrD`@FNVgW2 zVtoe6ZcBmb+f#c;Rx?cvUO~!`8qI4MYoC+v5ps(wX zu?Iy_cKU{-^rA^7t20L z#|?xxYhIvh$AKlcU9?8YTkq$uzkK^Ty#Ms=tMC3gi>2Ahh7T^V6Gm}?p_U~fHL7BD z(w6l5OKEesr^$DOzdQh#adP4RZTyQPw z8qGi8hvCoiq<+VIc(ae8#j=rq1!&Ecx}DWQ%k9T|s?RoQow_}7y-d2cy@}FGtrheR z%-ZeewnzsRzsisBhE$Ll#ycrZtYeFeP7}I={tSmGdAZ~hX%iRI?ZJ@x5+yLGI^_Fc zN(z$&(wN4%sX-z>(7>=Xx9u0McJ2WwxXKokGH*%tDkWR2c&KGb)jmkAXKMu~5W|+Y zZ=Ud`YXUsfUud%6A-2ov3f$ ze)?e_QA&nG`q2)(8GY+Jk<)CLk8t+nJH{M#jqmJ!LZO9RRQuQob_QjpEXC1~ep{uFx&NH~n;JRB#$$yLt?)&VmO zpuhr?sW1&Y~e8iL9aS zT$7L|4M>dVX#Kw&TdH^)SAu#}ucL8(>8(DA>$J|nXn7ziklFgWb*A^m50LNW4Zbs` z`hu+H(6MZwKvC`Lr7167cK4^@Eh7-tf`^tI^2i9Ry*TV{cicC9&=MfOZwSp=+*RT8b?IXi}W**ND_^E!{kWkDYGWTQl$zfKipCfMX*e3q93C7RbF3B)XvpENW^R61@`M|D7D(ND2)& zKfC()KqAsEg{Yt3s)~sZ)Nj~WAVP>?fJ+@aX<$|dL%P2QjNaK{7iTG5q%J zGg~M3T7`y{)M-yY&w&C*Lmy6tq~wtowG(maS`--U;)q)72QgG=CD+IvB>IB_wqLHh zK`5}A826PrU(@0O1uCN&s&`vsfQ%Qe%UsH#luCl0@__k(0*@VLF;aNsFV%b~KZLG+ zM(j?Wrn`?TPY)U;e3p-qsKW)$Dep+)Yy;5;WPo!Ji8?^HQ7&2%bCrB1{^};nG~O=h zU6@xYOLT!lS0oHc9Yl$y?LZGw_Zx7qt)$T(HgFG78}R*SZ$G0t*jCa`1CEbyWwVTN z+SDT0ln&sx7+1OA2i1Ujt$AhFgbAowgSB5ViP@fPk5*1N!nZE=;qp?;B{elWGLO1~ zajYgTu0n=})@my33tHTV=6ihJMRSiY;}j{sEXNfBdvnn3&Ek zeVE|d7ua<|yGP+3upyJB7)w`$8w;nV74YCr{pIETKSDGAAKyN|yo8;M zCK~l+Xw=nn+pJ5q$eBv7KzKidCu?b4tu`2|9W%OJk|xxbK<)sZwA6>iiw@|?FIUf` z(hV+=_UyWIHXAL}&-GlMa-;-)UhyTPUQnSkqAuL$@msP$)*`zxgT|$N%HVt#V50dN|WOLBeURwsZbqz2^aMu(M>YlXnU!ix{U@> zH96oRnolgv6T7xLM>z4(zj*yR@I#hJR`hLd(vFaSvTGXk{0712MpTGa?2cK3^#k?u zZi!&aG^jTnB=@MC)$z#oVgoP_|8a{f^=-*{IS9n8gnO1Cw54F?r;P=VqF z+kXsXvQ*j)xHOv@vJD4lA+JN*EzKA)?mm94c)%9b<1v-({#j?Bl z50ZTOCTP6F$AU=!JZ`PMtBnw)KvW4NUOAeNHtY=^!y}9D>K+zD*Mm*T^GQX9Ez}T* zqWAH2c>7bnIGCLAf^_T}3zcxxGvm-dy<^NY;F|Eua0+j-sAfmCO8VGGtzP=X!}l6( z@>_xAG`s6!gwkd$34^Os%s9p3`Pv&rF)GRIqC%z?0_6xcLhd+2oWh>HtU6=3D)2Aa z$W#(IOM$^zPCO*do}=Np(=@6D1W1wfxki)_kQb%6aCJPCMDvnTo_JAM5RVwsG^|bl z0<^ce%i%1=@r$KD+i;i=6R31{dzJ%4EkOqAQif(z-`@Q4cR6fAn(y8-sx=2P!fnM zVP~{;3bjQ_oScP&TErem87Gh&ZP$>^|69h)x1V12t>5|Q%eqP4>C9^dt^^e1tX;W)HkeEd_nSxMq5EHiQ}6QX7P^DDC8hq zThbZhMAVX6*yL>1(OA!rqmNwj>T{&S3*u}$0Nii&rOKp!EJWrFJc*UQ>Vq2fOx`ht z+9{4JMa3wGUhGySF69UKAHxrS_(T2lAHt7+oMSqI%aSf=4O~%h#tXdQAFjV98Cq~! zGrIqCeVLXWWHk(zBsS2}5gG|LtF4@5osfXw#0Hb+Wme!6JfANp~vn$9Txs z^txpSrocDw0tP66prgPsa|BF%bRaD(Oq!N&3*vRI5(ox)Q~JB?`f(($Lgmx$wk3D<2TqCZe4xTS6 zp3N+Sk%B;grBy8M$|>t`tT0`Tc>5=`10|}+hS*IDbAdT`SF5SVVVP4Is=Sv6+Pl>L z+++ss;#WVQ9cI$capuemgS1FYPm5h;@k@*4$XOOt>~zA=ao1Sw0rkzR3#Z=G0`G5J z?m#C%h~9a(cHL2SsK%zH6uo4qiU`eLrY7{%Um1I6V4^YTmHU(YrG_VV*toZvh(pa{ z1qiaxz=DE-wy_Ona4gyiQuDF`ZDVq5QNk3B#F=d6dr?gVqV;p5M1>|I&o_wV)zu-} z2X~5XqJBXM(0Z9V%=g_Ox?iPGf*3Qf*Q{JR-6axKMtdVq68?xLNFBOYy=@rir9wE- z39l0YJSwfU(*@#7mnJ-|t?>F=KVr_Zx&t(9XE!_Ux2MpuBLtUXc-l7p1aIo1V@k*9 zy5caqNdna;cavzj$~catRo7JqqlCS|9^8$NB}lYt3$q+Ri~@QnYGnO5wXA>f`kVY~ zFuwa8c~{A&hmGln&^Dtiq4DCP4LiOtOfIjaPr?RA4sYV&!s52VAd9eePcI?f*gI%| zHBR1y-xTgrqN#+s`=ZRK0y5{Y{v!7k1$sH}%+-JO-+58rO0oE7`S_W#>SK=dBc)Jg zofnL9X2K4@^i<@3!8Y7&^u}Vlp**pC4w)=Hr$DG=T{4o5i~g-2&842mm-y^JfH(}g zs98~Bu$9I8CY52ZgCq2v?6U|u5W=7itS!^2H9gIr;jcwQxc8q!vEYyP`Sn-f^>b|% zfV}r1kt&bWAX{TOTdmE$(qcQ{Pk9xWnuuCxF9IbfAKD*1H7KFyW2gOX_Dman@CQNM zs_G1wog9dc@4P|Z;C@1b-~Mv!Z^sO0=qi-0Lq7&J2&~9;||2YTJxey7MF_> zyt9u)-uK?rR~nX-1(L`O%G9+itX2Yr&fX*d0XBqAmO6qt&j*O;D?;mbeyt{Mx?Lr2 zRjZgHwk__4oHf!aMXgH@1tOLZZ^E2F`z0BC7O0^jp`K9k*Ip@H@ft6=yEVaL! z|0J{9noEwX=x2CPSvE*1P=gX=lsj8i6Bs;6_V0Rd(j+QwFiT?un|L0}vtTRK6y+{W zasqzr29IKRVYa`;#)4cM%pOmY9K~`zg7}Kh3q_^>M`7L%W4zLr5|> z4=3-EKGP`yL8v+Q0w5_b+5o|ZW;~I}=djaAt!xqBphlbyyHPbTkR4aZTY6S0>CQ=_ zlCWk&r~G9Z998>48!+odmyVBrXaHBUUyW%NMeFJ$;I+g8bR1vo?@*CifL$Dn-H+>8 zUinFJ4@?ERZd4x+)ceB$>;*DzB2*@BYlbX*peOokgEIdyeE&D{_4k||-ZK`;%MrL| z&Hw_dLJEcyl22_0x07UFa)l05wVC$6PbbdvSssz$7%+JDt;(F$k`XVbjB7n~YO9*> zNGWQWBfzc>6w<3KkpEE@wEW6m%;1d$i4r$xP;q%;7*n~*4^|};b`&$@NR~H9@V;0w zFilcxcU=j8u_xQ3=qf zz4;Y_BQcv2r_n6P3E;a;&UIVl@{)362}N8YX9X2E4K2|lxuV^^I8f&b(55#Q>*o@1 zdG8a{m}sbjEmeDf^Er&@ixD~!o1N=$?j-CLQ@1O5Jf6oZV}Q%#q%rkGT4uf`I@lLL z;Ya~S43l~&=8u@qC!QZ)hPN*-pbxVLAOT6Xo*eUcib=M!l)Zx;9?R7p3GAzrx*;6W zU$DtMdflMQe~-`cq5ijOy}I!EteRR^6(S(#8gyJ6LLfg|T(wLmDz)4eOw{ZdO1_of z?6w^2p#8{)u19l!86r-+N#f@(0s|;Kt8%IVz)L?x5@`nv6wzmt{{>Sic}nX^%`Fim z(O?cluqlS}M8LAC3;H{af`;m8{F7Fze!H6luN;snWas zr2nJpdb7*w)kAZa>dYWnCAHTSlAL^)I^IlM>Ua!thMHU&9Gz6aBZD0$&p8%3&~yL{ znV@<`4RrVf>t72`V}2*HqHN|t(i4Qm@5Eqr_`4bz@3Q7QU<66PPElB81~=NndRpAyzS>MiKJeG$Po=v2y@g$gy4K(h6^l3M zrFqv37B1|(-yH5z$?1DfPi)bYJHS2FfwI@=BX6*YJt3%ts%*9CF+h0|-T6G7jMFbN(9m z!Qx0$7>;_M%#16!x1eko+#2D5%Z6D+{s>8ql})oA{=R@TB&%4iW?_R%wSzfEmB=0L zbX!icfi|}HpT_$LofC?S_mZJ3Sz3EHWt+J`*=p%*ghS8y;QH$IpL56KmzS+qt5Irj zgZ<|D@goEE?T9;RK7n1wCfR~9Pz^wa1=^%zXDzJx=H@vIAwfw$3%VGyx`RDmg$rQ8 zUG|ay-Qp~(JhJ80j_@V(yMZ%mz7W;wUHv#i_4!2Q-oZO{GrZ%lhpfjWE6Hdr5>CLw zWjkFd3Xr|K8iW(=bMPT=Bc!>P8+++5kUcy|zb&8>Q{>nO|3;70 znS>(S27pU4nOm+3*)@eLIfF@%suBQUl5A9xEX(4rPFfu0>YiQ0nq+x1FPAEGRS)=u zbQB4S)=ibA@XhO2)SuJk5BFg^i$(~XxeThxBfzI{EFBW?1cE%~*iHkxN=|Kf8ITs! zuu**bG%?p!rd=KOvHEJ!6Kj!_>=`PjlG0o8=OaQ{mKNA$xkAg0NIPAaO`6$2g607~ zx)TFt`15Gce&_{||JARDc5z==4hH9<^kN4(dJ0Jm+13^+6#1Y!8^XlGRI&DiN_ zFxX77M-FOBwg^x8?vX!0F0CimPJPAlXV^tb-Ex|RBA;B*PP60@XU)8$dU0mH!ZbQ< z3;WO;8vn9~)NG2vtetk!+$DgbcZpQ8RvpxEQgL_)_b`wXEN%lxaF8lw<(=&bRM%^i z!*vh)ZewVqf7wICt~4khY2mY#B#w|l$ygW4odg0rp+V`uSh)o@OzBK6f}uMzA!I8c*cAQk#TDzFNJ8dfl> zS7`psVExV&*@jT8S;7FOBGrC^nI$6hla5UdT_sEANfOI+4M$5_c5(b(<6jxds_2v3 zl9I9pV_OG(JTwRmnsh81Nhs((eWsz7@ zGE`w!#xO2FfZP8`c4aS{8row-r!{f*C~)0WSoJ6^NapKDN9LkXQ5p z#!Qj7`mRvPVi=#ZiVW9@vCQgJ0_J{WCzu4V;t=4J6%U4#?5|WgT5Hi>Re3v@P!jjT zO3oTizBx~`r%AV+GMXf^9lA=rJaBb@S=fVC&aa7JVk|4G`r7k^V=EE~<%16rUMvU5 zYYr}00X+mml*+Oi0G+ANxpVaM8)(ko=5nZne9s|DxNLYQ2kropA>#lw{MDTZp*$I# zF#%1nJGFrN0|nHh;T+|kw}kviUe4ZFpSp*9n;WdH%PzZU=K$3OI|-fw(O8&x^;F|( zD2xSVz|)ZO>S(=9*=Prn1g&lim+6y+rn)t6CHaK&Ldh;0STHm-2vCn3=Y70tXC*=T zY^`r$V3Qu()1`P-VJ7me0)`ACwmsAldaCPzycz1c>gq#02$nG2htmZ`?h>DP<%pym zRp7}YGx!5DL73P8n5?MZi+0dWmNyoaDt=kc@B*D7DxpL2mb&mtP4wZ831VQeZV<1w znN{qvAS`hVFjIlrn8#Cj^ppne>w{u=RYH?dN=6-C$N_zgANqM$H5^xlJJ5IRj7f?N znPB;Qs2208Pcy6-DPJ35OOOUb*JrjASYuxE>u8HB_ zf6h@kD$D;vQMs~Cjy}dnd)&Z%ra#yqXN**6KE{P!U%pCJD9uYL0pxSJCW(68hh~>a zq8v}1*-|xf%TyU1ijz3N-V+Sr9Vw5kg;IzX;7_BpO2S{^~mwS=~-0EzAIk0M2 zM<-dWwR3)FSWj|uWy0h^+~7IfZF&sYp19q@e9ywlpiDLMc7zBj7|3n`=RE=z$c!Cs z;otoYnQl=8^s!9kIv&|0+3Z#lpW z%y?xv;)Ek`>;VxWUR=GT#>ODp0V+SwB3y5aNPpMr0TnD zx|5bK{4C{fmjwnkQjXeAm)pD}-O)OLhkTw&*)3s!L9`sYuw8QOjY~mvI;!;o3TTV* zMd2dk)I5&VU%`NecDXtaqmt;*VmM)dF8QG~kuGM1_T67!?&DfRGV4x&Q?Fer!=olS z6CB|*LyGDisX8^oEY8o?49n-_UO_~O3QhMKMm!1%&A*cgA4p&t^%ggNzno@=`X!qW z7>yFkyxBA!P_Fag8G(?zZk@M0BP)l07k==AAKH7ta_%l`Z%kZCN+9Ey<-$}K$Lf?@ z;9(=%?GTNZ1e6aM$)|k+oWhTYC2D_Psf7O6}6k-h&+U2kQ- zU)6>hgSJy?)5wp18V5-+idiSkb{VinOpg5PHusiYvxNnTmV;W1so6Vlrgfw5DKDN{ zs@sxI2}SO8T%wt>nQ>XZ+Ur%RdPEAyCh3B@588#I#EyM=_PbVr>-gZbXu!nQ0w8v& zonpg&qy__|U}11_bPmxI=%~y;tV(wr4}h+`u_e8bPOGR;hx*Z_eCFBlt)q(@3 zg(PCd0Fj%wuoSEC7G)hCHmvHuR1fUFeMKzc*B(Cr*Uz+m5CG;=%_Hxx1$N9uv!AJW zs*?DOe7&rC14wFFF9EyJlG`%kQr^X8O&v+}tY`lrCG?-)zShDsy#ITfZ2edC3IAX| z^gAppca=r69BM5g234{9q?$JV;GqBn01xZr9t5pa0t{89%wk*XJZ&{t{gW;`smzYF z1O_@h5p&$zW@lxqJ9}Pu@+io*?nC>|&iD>gwK-0!3zOAwQR5+`t;3+SXd;6TOf{x3 zv9~tS5T;6>Aw**>fT^84C&wyVw=HTIn%7I+O_*ooEyc0>oz-c*E_*O7jC#V9jB02V zZhp@k?GtbJi}3bydkc`ngIf1!3?!xC*6U@WECSGEwo4>B(H0~QKGEv41bMy@2}_lU zEs*Sajqvoy7Y9}cp-S~h)C%zJ!DU%W)C4ylLgum`14es~YM@GOF=QHtPOI`X))CUm zBtwP;N1>b<8$P3wIuOtk@(=T@36PkQ@52?*qy4a>ldEJf>O9=SeZQogmVscn6fF0< zO=U(FnFX`O(|Igts$nQWj^sRn&tDPs8PL zR{KGnhT#)t3yOHm(8aQqjdnV()JTZw9^_KOp&f)-FrDlxc@_s;a_rUpBXJhZ4gkbI zq`JWAI>p02eZ5On_e_0<$g^3l1rF*qaolFjcOw&OIfDJ?gN_xAMf)O&G+O}BcAx8T zX2`72BA1nO(bX|~buQtjUrq{D;Do0|mNE8OrPMG_hY&M|5>*_7J{Z;6AC7R$cN=cj zi=6DuZboWJYA$2xz}ogm5ir}R#`&Vi7m&1+)9CQkWFs)hR&oTH>WyM7lE>UIYOWCt z@3vqe9ft(Mlh)NT97#7y70+D!4--8Q8kO;6#)_IRdb6hlh1SwlV4vm)sye|94~!ew zK7@!0^ztdPBP*&8w~<>?mYtm$k^r|CGy|D3Pw7RG^!X;BC$n`5Dml+@p5n`k@*dKi zx|47hu&xe@40i-r6lt9!6(t#|9RL1v5Y26({_)#q;q|8qBXO}uI#H4&o9>plOEh>P zTpA1K;oGxSy;l=MniW1uZ(t-f3xsi9GPD9+aUOV-)(kPS)S1%2(u3AVXf|**lPUF! zosExOevriX)!mrT4wps9mIg2o3XTDOYh>H14oqW0+Oxelq5x}Xu*&63q0!njOjVdl zt3@TLR_DCqt;id)VBKffnZ(9vRKc10DsQDXMsEuxRrgkCfSYl3eMC0ryj~#>;RYLW zw8PzqYqK9S7~t68C14Of@+{Rx)dlb8b^M?asHT3W{OecYm7sG>DdJ!#X^`941Gu@X3!WY0-#v5CsS;6Q7M%!$r1uhWNv}HKQXjn9fM&PVSh!CO*bn%g>h2S zfY6WX1iTWQj?t{FrpHJ#XfocksIiTCgNG_e|M}f-I;XJyt(;2oKMUUEX~}~{B?&+y zAFi?0-DfQho4g}U8uIUy>Wtx>?v)Mo8Gmh|>Vca7@DMND-wa6KK03x;{(v>@E^BCm zNv#E|UHSSjJ&^S9uu6nCiy{HR$sUR@93xC%DZv7`#qEk#z`*CT#6gz+icVrRGQu_> zkXUiOVPhl?1&`hvGTxSEOc0?10QtyKUwVcw7`R{%7-QUP>=zqic zi~Ohm`1VOwB-xy+pNEP7T}n;_1wSt^#%WC_1}Fd%o}S&*)bU9te!Jg5qa!j`uv5bV z#X8oEdBu}eM%sC%d#<{-IPWuqLGq5psMXUQ`AZN60@~S*qEu|>rY4Hd8`2+qP`qGU z-_dUvZX8sjXsbL=B#v;BwQoo%K)`oQE)=%m{9Jk-VoWG$o7!;_K(Ut{hGeIB39FVS zX>wOr+Vr?btEM3b@1`Z*IkQbSBS=V!SVO-ZMmO@HA!)XF&?E#}VuW=$aaf$>A7K;A zA?4N-dxqkc)Y{tvE*~JL)y`Xqr8ba+s43l^ubo8PCng1`Qko;))C5WwTZu^ppH873 zwf0z0<8(aeDym%NS_`bU1VR6U%y770az!4ctsK^>or+jIr`1fl)_Gf)*U9tPY+|e3 z%(SN5jlkI74laep3@XNfA9%>8j9USHm^7ReIwT>~VJl0Ywl0od1ePvmb2}WxSz(uP za+{(?BJF7^SES0p*HmZlwm=R^poiy`0Ho4=OqFAARO`Yrlx5tJ68S)KroNgQoVgkp zB%ZNl`aJq;qfcm|O3pSiZcu9CUD9q_g+)}yoz>qd5}oRzGimoWjFK@S=N>z4o7E=? zeRv?nrS=XGGH4Vzk$X0b*b&dBRhI8!k?fiGkO}u}yu4V!KOtG$S z7^^^{(3?DPl0s-bkht0N%k}_J?Qof8KGn(rxmogsV|<9!1)%Ju#zHTsG%EfT(l_G3)nlpM1ciXff`?Ih1H#<+Ox*bmrtbqFp^Dms1OFwFxE^ z)R<}}1-by_w=CfR0y)7Ri>k9g2dO_X(fNR}>27Fh$-WD~C)C#lh$TX$p0=iOE`T0$ zs8!S8IU7ze6ZKH18H*Bl9~@Yr)Zb~j8@1)mzHyQBOROqqA*_$I8dSkeYVmauXCwYh z>OG4az8^rHMb6&Q05(XXZ}sI+XqUG+K)9God7~tm_2oXM=ggPK?|vO#zr3tl4MB4l zgV4Gj){@pfIINX)5M?*eNgBYY0C1=z0?@3(7}nMn<2;NUVYg?=+otR$39vPtzD#tD zTx96tNxi*zV-D-ij!`H)59>L7grd^MJw(p>$0k*Ruj*%j z9Fo_4nuJlQ(viUCa*K6qhd1n1^4-;e&TpK^ET*X#yTh?>TJVk!9Z2L4_9x(d93nD3 z9eqHi^hUKZLG1p}aJ$I{z8NAcTd<*Mv7-Sw!Ww4_vTD*5uVvuL9E(=9qHl8TijY~R zk>hrsrn1kf-0$jCf=|9%C#WFhPpWckPkfLw%NQRRNkaA=4OdBr4(-0pJ&M%K^K$E= zx7eRH_z+){htyV1G<*Ym@RR6ehol{ z15F=+%}gHehMF<}=@>r)lD8_T)xsS*hO>7^|Ml(n2f^IGIDfX-SKey4)-I%DK5^aR zrSvqk%)cYgU8*`%5KoT#(Pj^I?Nxx=Lxw6x^1uP!wZ2RQ<-p-d8FHnY&9CULB~thR zfFDp^(AQVeRg*-PAOJg&3NkH86YT_GEosT{ewWj;ww~aB2>&s^D_JzO_nO&A&Cs3un;WAF=zrzLi&1>f5Lv-f00QGaXUZf;nfFTgJiIUBC z(OSEGEGA3bj!l@%BdTY|!!`vv^0M4o7dDV*X-2F)L{pOv{SU7~S3=F6Qhi*#S6;-M zyta`_#Q;e$3((4r3-}M{OWLd!xP4i6`yP_nJZ$Wq%{4kA?xrvU24N|W)HpkAW-9W= zkO!-3a9(1Y7Q`)hBe|7b4<6rIcqUk{TOP$#;tQP%p>GSczi-49vk)^ngNi^ThBqHF zISdV0&qw5aaSSpbL=^F_Z=OXy$!3tK0jWwqM;kq!K?(zTk)We;E46__oW%w#QSFOt za&>_$HK6JPK-#<$E&kT ze-!@Hf67|}@Me=5U=Ms7Dnfsm{pT433X1zh;ocvhVSBZmg{3W`IBUv-M2d;6RFyLe zr>tCnj(N4qaxttN)Kyo@?Bs7o@S(W>dz|nEyK_?15TVtgUx|LeXkW^%CO@lgZZpc^%pNQl8IB4$rYx|bSOc5I#f_|JkVQ|#zAj@tz;%MOA#8PrXwIa5erA(38E z&osJqPf&15z|67+vXR=L?mZL-Dz??s)`kdO=m%8@ z1FV;_15m>uLQ99}Z1NxnrAO7{1~->uE1M9==Trnab9w>%fyu(xAN1=n;{V3Z9q6B& z96=$LWzCVcjwq*iKCgKv}l*(|QzKgX9l6wHuzo^pKq(tCHk~+8qhd zy`g~#{EonS7@}!(NdkNi%m^B2*+)rUlw7R#8=$dAsE)FQAsbS~{ZHvIfDiH6pTg_U z!s}<3=Vz03KxaY%JKR@%Xt+%A5b0W!3C_K2Xn!P4(3YoMkG#_D5Rx3&y+}x>zy!l1 zb32hXEKlI*=uxR4Dyiogy_Zbvw!8=WLu-OTFWWLG8f_6ki~XV`SzkD&$jGL*+~_08 zCVRMa%zSo9krfX^vjNm*2yO2}*{TyXm-dPtBG>i}J5&!E2eR~vr@(1NO$VJpJD03n z5-Uj+x;#>MaMkGI`fgJK^fDgcVMWO~ZS4RdjK;yYhc()?LcZQ&6qwxhXkR?d+EH=RlC$n$Z-yC> za%%Hq-)6TR1h6C8KUB4#&e2xGU_GW@5l0-PB$aBJqibs(N&; zVfVQ($0`R)ZIEW&)RVHsDR+pe?lqP5;G7NY?sT+N1`yYPb^rq$DtLCZ0Tyq=;oOtT z4^v`80A!J7--z6 zy4Iytz00c;G9Z}iwU?x!i}uwe7I^2vNsy3HYHIkO<(pGUO^X0tK%u`XFZi*ShuLx5 zVa6dDTDwVA#bangVbJm94KL`mz8H=Hv(dQtQ1>2nw2M{Wc;9%FcQ;LrizD3L)}(3L znzZ}-e|Y^=4$ANT7FiJ(zL7-MH6cXOq;=Iqw!sL%{S8uhe!eW=UgqE?(URip^3ZlQ z^l?A~MjvBG`>fR1!G?P~peOi3vbqkg>pW7cR96xU97WfFun72%tU(xH=O->pMgA{a zuq0k|)h2TO42j_-v55rV#!J*q`FD~S z|9KYse#lEPu7jKwvKrU=IdHtU9@5kxUSXJ|L~}ODr5seZi&53jZFNlzmY$RcNV;0< ztc`%LuqGNER|%pCRF0a;>cbmQc7aNhEl_8&6YO!-8H8%j4w`m`6bS4nG({h-&cB+X zREq#KLkO~zhz8l`aX$KqP!%2y*&Wpg8xmxN=CME~qzt}Zv-d&$HKrCz8^jIVGC*pM z9hRVO3H&V%H@Gm9Bi1qXy+TB^q6l?b(EeWl-=jbmn9iG$7`f>stYa|FomY(=v%iQ2 zvQ;AQKY_;f7Z-K=dHbbWejL;PxTqrAfaMFVXw@3NV7Qw~1T2gA3p8T-)ioIE0l0F^ zJ0rbIDoqC+n2kDIwS^2d0;34yQZGvm{;sDDr5pGfYX6I>&OLfNBtF6*8?D63n%+^3 z%<#t1Ae0>cp)xks5?w-t`)fRci;CqlatK^wW;kx&l;M?ufwxIfSL&X!9y;oh4&E<6nND zhW9Pi@T{8t^!0b)^>=nJa7c%ifnvT^M+}WH^GH@RwE%iqzq%aP%x>oSvxL$9$2ihb zm#t$kLZp*8KHw;L;qixYXycv;5;M2z;H%a{BPmy74g8`Ah2*ku7a@t{$3OmY__G}K z{>Sj6(@FmNW%!@+mw)s6hw$SZ7qh$?MF@Hq5*(}Q0POW@n#dt;IDBSXS?xG6IXS#) z{&>0Ct2`@tTdAjPTC)Gt#RqM46}Um`O(j4)zN2E21Nhq6%pKpxM;!n1`g5=N^1Yy6 zjBqxp!@|H)3pnw`Gmo3YW+g^lZr<*YADR`#?8_&6oULZBr2L`vSvc178v4nsKDa<@ z9Ipp)sazTW_U^UQlT^zNG#=AuN6>0)Ft2W4j>ic`Zd*E6iI`Q`$RPPD{>J7gd_f^B ze^K8l_^MgHQ^Ovt?6#bG?|Udq6Ww_@;1<$eUjB|Vdeo8$QLh0LZb(*I*dL3hj8Y~r zco^@l0yqHRoC!d|3(X!P*EB=~pmh(uDU+(dX|ki`diX$HwKZ>fdG(<#U4@~Cyy}@a zyDB_^!8fxJj^0el0A14MM-ahsKjbdS@XS1CL};Gdnj4^2g+fQTOH!d9wOUUXSm}-E z&tlQP0IN)asJZ21t37&b{N)E z$Waa!Bak%_ zf6ZUR_kV-G=D+>PcYi}?1)zfnyMx+zds&9$?Oxb2;ZVWuyv`${k*jvPnA05D^*~6E ze(+>jz)`Zmp0X11#yLSN(NSc_PaERo46Q2R$4mtELyiPL%w5s1P6x!>AH#V@e*DRA zcq+dC=)1oPufNKl|MvA$8+bi{p|W?27HYE6TgA+VLmg(tJydLzX}7^L2b_P+xI!?d zfCC~y5a??#rd#UKANYw$3ToAVh&gbRHSWflg>7g7pB-N={Bj1KN-aYWD|O7`7?D2p{gwtnu*n zsT^{{41A=IFwj%9V@Oi_iZ4bA2vnjRio;T#By{vJCDzJutRN#}tDq;%9HNry9*jTl zP&Hev(xulciBn}(smv8>c>BV1Pkwt@o~Ztz{Dv9enWTIw=L01*NJjBa_?U#P_Ri2R#{jRVgCBys1r(8L)Nl8#bYT*oVY18$>`X8e@M#{yRJEQoX;+ zZLg8%3--UQMg=F?XPEZLWg_2KHS*CT02?Ejw}g{qmv?-~FUZSrSE`Oi9f}ezlSBGd znLvuB22KHNfa!@SB~za&ng_=1SvJAbW^Ih?$V9N3y{ar%V(#-4(eA*!Cl@%csvSCg zSN}Pj&Cc`s`{~UrJwNoDiKGmknoS@ie zg40sTmEd%-%)5>qOe<};S$Dwb&9LF#To|R$_ESe_TmzCctFIz%Jto8}wOb_4_Bm{* zB<$oB&NV9E9+u%f5>2;5q_lmN;f*Vn2k^wTHz6DvUr5nTp(hx)+F=RFYK-3C&!I3n z!=%>gqijI9Srt%fDVK?&bDS-_r()?iEvdH&$LL`0$c(j@TokPg3@(=&i-Ct6pa#$E z;HP6N1GL;jGpx#x_Yx{t4k3=27{-=5$nMH2IY=c^<~)W2Z3&ElD`a{?fI;j{iW$k$ zjmv_uQhc&yvm1h8-XR+|E?#s4&rBL%QeRf*XWRgbbp7Dof=!l#qf4_K*f1iI*9J|= z!aFvY9nsPaE^1o0MTBJLknts)sTm>OU|5#-0A%npWNn)!U?oZlG@-Slo&fYNL9WWh z0Pr9?1-)jwJn5f94KXSS)h)fw+Yx+;pqguTm_)$v939-FyC{F-37%Qa$y638v6cXzk}6SPw-dk!4J7I8ZWg(u@Q zUO6g$#CGCuA=5D^Gh$r52!_<5r>)xFmRvyY$U$tNkpsb5smuu>(l`VL5iUYS`6ScQ%n!|I99V4I}%`WGV&>_G<81@Hkk6g&R(lM|Y`Or~X$u zT<#8~;SGU_=x_PaH3yZl^a~Ea8jj#$?zx#;Se&Rq9*+j8iopCt7A4YfE--l>5V*4N zDJglcNJu;lpldof9jG9)izZ1%mSt#NuzS?O9#eNoehL`I4ktM#wP_*~H4}D@sa@e+ z#9w^(w{Ks)|Am~2zkC1b>&I{3y#E+9raWZY;Vw5^p7Fe_2(2?av+Z=W>t1LGp=i5v z>NKlUGwA6`)2tac;J4~RHam60y3Hl)yL8vQGT&z6xc~4_?m-Z94e4<|57;Gv%=@r$ znKNiX(N+M%JYcO0m5;DJh(R68u|`>k+W8!Z%LZixMN!Z6a-%!I)YWo?H!2v|!Qcnv zIhQs7s_c@GhC|GHIpIM|MCgVeTOTs0Xn&O@qU?tixpf06DAcLMTj2-gH<#1uUwr6I zbo!0U%i%Y%*9({89pcGYt#emV6z$=u}=bq#+V&r1HI9yJK6CUOdEQJ2RMD*{%>!)^e=u!*_>u}4!l9RwTS#X!f`x_RDhx@t;E$pjY5eeUO)@IibpHoyRpf(q5fheH+6o zyRV<+Ny@)>6Sh}k z&~^`EoRqR5_ffuKZ~Gka1lcjD)>0}PU|7y@XI6uTt|B28PV9OY@P(7n(NGBa*c&!f zmO5%xQ^1hNvDE0VLGsDkwrI?_@i3qZvZ1;lJ4Gcu;qxAo6@ z3G^5=#Ot=*@5yWV50Hn(NJa9BH$xBeZqAVB)*F;{EUW zM!rX;`^I2VDogPCuNDhCw=zciwQ2HShQItvZWT4+o%vOu#+eFDqQigSEV97t zBkq6#DAemv^OtR28PyF{;W!^dPL#(d_K%e{r z-^!=4a5l&@Dz$3Kad!fO+}s)*3z^xWmNRdqr-s1F2jSf#Dy2i-YtfmXY1p*SkRpI;i+!CWyFHNE{npD5NWB&%veIl6qlht& zK8h-U7dpfqR>p^G9ZL0HhoGb64OVQ0y4ek$9A5u$dH>n#muO3T{`R>w*2STMQ4A|J$-CT9!*O((a*ktCQ4fD^;Izl8ZtMJl7B$BCJQrw#1eSurQl}zSsb9 zWj-c3o6ste?@7$V5ZxeGrDkm)0|N?u;+LBoN0R4_yMDrlgWUywFsNy?R&EZ|2c{fm z8B-mce-+}D1Uk1`ImwQ@=P0U5_)L~44iHu=SP?IbG*EHhgTy6Uk&JIyAt?8_vO2A!UGkbc zJ3HcpveM{9iF-%?7sGVh>~cYhBd!7V@rl$Tl@4Qwl5G`?0Jh0fS}*Mik&$X#$$114 zZ>PDArV)1bN**5kv4&!o-MLF$Ss6JZ4k|zGqJn4!*iKcy^Y8v9uY}Q8%bI6O5MEjE zKRbOfh<6xzIir;do+JZe#s1A$m|TbZsU(g9AmC~)D@=43B;NM(Wm*K65@S$QPc$hATMU4HiZo68G_ERPyAS^(JLgQX6hUP-w@6eoV*iZ0{zlIbC# zqXPld#wIia#*=_Fyw%qiXCKSIZESu&wjgZf2m;&flOEJf*(VY#vsM-WP{f*akehP8 zxd{moTmj@8UuX}-0QZcQ$GrK%M_Eh5Ur1cv$V9hA422fIdT>b<;vFr_pg!qBi30 zi(w-rJPo-G262QOW5L9hCkYKA*D%r{Tz*tP4{u+C#T{a_bo#!yoYN#rhxr+*adK86 zzV`$nnj}fDLNP@W6Mi-DMYMhGsx=NlQIqnCwWH``c zhId?cG}qWFMEwC)@nwdW2>zqsP9M6#s+)dT65tMj>Kd{DOMDS*#gO>q#7S0lV= z5SS02W0rI}51ycJR>6latS*iO=G~;3q1Pof*us(*bF5s!oFocmemM_K6 zUOx%h>1JE0{J2bDLpiJsjz|o{8NOscaAYe18Y}T~ThV10tcJdga`sc%t7Io!nIJTl zdzSxK#NR+j?*jFW{?zZNx7_*9UqnJ=fK|RZRCkC)I?7{6%t+wA{Ka2{zxa#1w!We3 z;2q3!U#Z&!52e*ukdOJ)m;l?{-sqs@Wj$*amAUn;J~^mNg=DR{ALW!&9~u4fi2_Lq zAQ^Eek^&tE1%yW1XxVqwSM0sk#MzPkm^E6v??FX+m5}DUd?0*bLh^sqN!~4!kqXaRJE9sogq00-W0-$Nj5vY>jP;*#kOCkV4b`OV`%?gh3J8my}`3x!wOoF~v!1hj61izK@?>eXZc!V!y zI`)^cJOul3D&oi+7tA<-^L-*K4vKA%HJhnuyB}Ta2lNO4uaxAnbP!~gXy(wat`MZO zn`!T-f$oBBDA_jN;YTwuRZwt9b^cD*s3hzhcHpM5&<+jOC8|%E9|!cHk}Q(oNq4Om zNBJ?Z1heft5jk_1Mj}eoK#g4`$VR)6&Mh5|xf+TlPI0dB03p=!B#lJ6fm&-b^t1pt zKBZ^2006_UX-ygF%4L7pNhwZgT=0+#Ge&l7!QnqO-f>+M z>Iu<~gM9iTr(%<9i2^VN3;3#RZjDV$vO9v-gB$VHl`7_&bWPMr=V7^}sRjhFE=v&> z46wrFrp#{MS9j{>B(=WmxJ&AlhFoV;>#|FhPAIi$))oi%cO@}m z>uo-)Vp3p1+GB_6H5t%@cKf@q7K*dnklbz-_;G=1xw9+V$=A>xa8LOTg=E&4HO-rW)#X6Q zu9lK$eG%UNbb>j{@nbUE8KgLh0(^L#yh|Mbo=LWL2z{iXqxW=U2Z#6^!Q4I3swXYt7uRH z=!mGb&Fy4ie!$5%MqJ4G28gr8dO?iDF56HwGPUeMoy)c2+qZ!qa%%9#fG%N#y(L+= z64SSn@q^lTpf^(n2tGNB6#aJh_<>n-s!Wt~8jl~6Y(;zy2L94q^#z4n$31|+=D7Knn#EQ2Xy`U_>Aw8YoESCeH7eA#n>trvl zb$N;RWC$>$Gk<)9*^gfTXfyWzfv05WmfMix3#E1u7NF==*@mawQmgQlkJ(UDK>Qgf z17n$J18!t-s+xJoiMg9Wps6y3G5JllXO}DK&;?Kbil2Xxy`!Kcc z`MnRn2S92P!8Gy(`mj7A3Uz~*BWO*FqxB!kNu#>Ny2Hgae^lWN@2tprRNzk{djgRK z6Ki=l_Lrs=^m6STyDsIT6En${c&meRn{_&7B%FLgHV=(l-Ok)Ii*2vo!3f(-X-!Nt z2h5o6a$hem)@s}ovd1lv9n-+-Qp2GrG>qAAD1+p0@?B;1Nd~Lt-+9H!X~jGc61JU(Ea*cF?14g7 zX3cn1*>~*v$?rnO(^G;PrPiZPv<{rd8^AR-Le0WR*Ukm@5+qgq5Q1cqqi<9)xpZ|b z*v1n`2k$Sg#uDHMIfrZdxGMZ&Wx}Rj8H!5vw-{ZTtx;qz#twrd=FkoG$kM6FCOgY7 zvfAPiN4}+4^ z0!|pN!g_kc+eOk2%n7>W^DpeRbvFqGIT%lv=1-8K?jtJcj&4$*kvpmmg0PUO1w+#6 zUl_|^t3R3Bt`f8cN{qtyzPiAzcfoiVh2c&~q+f?W&p%mGppVoIRW-PB0D`0IK{LlR`zwOxtvs;L9nyH@8_@$t#`BD3|e^YI={HhU$yrfet$o*EcF9 zpJHl}U<9bw{>Sk8OP-7Wf@N$;iiFcR5nG~qY0s%Yl`Rn4O^`?O_AZ4S-oBFkkV3LC zL6?r>%BSiOdLt;Vb@lqC9FOt;=p5+*45KRJpn=0Syg?_~Wv&kE?kd%A?}rmKgAQXq zY_Cf-D=)D^_4iblhUEjlygr(*&`jt&evT{bSAYKYhxebp{mXZM9o~QZ`tj?Zlx_Vb z{`>mN_dk36_Vru+{PXvpzW)C0zv-WT0WS92=lJ~HU+eFDayrcKBj*xQdN{cZu#dPN zqMCzyTtd`|v13;A+#EZUhM}#N?P#$cF`0vKe)Lm9y&I8?qL84P%#}-w{qT$02J=IXg@a{MPv3Dnm95 zyR528ZG!D=xPe+~dsQK|wzO1JK-+aW%1eU2TYnv_cfu&RZ!p+lQ|p0D&g!U#+X&@1 z(xkb=DvMqvplonOZ71%@Zh^>IENgFQ;N0L)c94gapg?AA+Fq4UB9#;YV%(T8ZnJB( zJS!U($(Ott2%z00S6XliaKHc(Fm%DGPg*Y^il{8?3wHsIKM3YRg6?fG*Xz;fRTwZO_FbJk$4a}GgK@12u#!?zIURpS$pERI zq@=C)+QVe-=-D(ll9B|pm)BQvq7|q9Q&qEtedw%@ySIActT3&7E&mRg=+CGt2#}kk zs3+s7R_UenWdohpOK9_6w(3M>VEa1z_n-!FHS8N;OV)Jhnqm#_$W8{065{8qd=oql z$kgPcl$UA1oEj;rnu5LmrJRr-h4-I-_gAl<8;_cj8Zh0P#z|_;hT8stYH(0|9cc9c z#$_d4q2K+8)X7Gh}UYGHzK9aJS4z0F_N{{gs zuMjSSb*v64INVjN(QuhM=1*)}wWW@L309j) zH%U6G#3yQO%AQn#o}MS&ZR?M&)D5UlTa5{d+3v9oBLvePgTsM5Fp1?Il@(=`=Mj31 zJ$noua7Md2JeuX$fR)b@tJ8YR$oW!jJ&diQ<2@$evW%h62eJO8)~4<~NuGLjorDfh z+BBO)?-a_znY>VO!gM)Jkt);q$Ohlku9!v+h?U6KLU!b+x?ndCYvy2LA%!dp^}2S8 zI^d%)T<;bVSg`-|#|4r8h)0+x?w6Rec-m&{G3=wY4M)jAp4m~5KvFpBsggYlVGp`S zaQlL~T`yLmKOL>&7MMSJdP>d?HYtK8PFFk=P>Hhi6`-C>>QHK_Kca*8UR?J-q5*d` z*n}0dpZ$02JH8BWKZi}_Ey5@iV&naG8fi!(O2F;ZL)Y3xZzm+FuozWVZ{jiCY%}t; z!%+>s>LoA^az1pt+a6IJH&&ABQf8}Mq;(IXnx-s7#PtWi&>O+OP+(@^qLV@5EaIUj z6pK9o4RC%2pR&6D^s*lS7%Af3*@_M|+ueA1IhkHGU&DRurt++$5=nxYKX65=EId;hQD2S511f6G?8%mzWK`W@6*5_>g!10C4@yjnFmSM^-^ux2xN)m0^y60_KNbkf zH&B7#ybcW_6N!i%XdqxdBbREx8(d{w84(+TKDKRuA~;TDEd2aP&BC55J4@V*zV0zt z0RE>zFFOC&5p_ioDr;DnLtPNk3%_SdX)hGDRz#aZ7OWGfUNhhAKQu zL1e0aTlfW*RZ5Y9*EF}g6cGId(mgg{im32sR<=WEDJ57xOB|gD$pY%7JUm9xmCK*p ziK0+gXugL=wHB@Ru+8=B4?E)z9S)5)L*0V)#a2CgI9M%gb<9ftgnAvS{Fj+yb#g$M5kGfq`Vx71KU*y$kt}hglCn^&Imw~ zE%f)$QGyhSAi9||E25X9FpwuT2C4&r99IaX&QCld$;c6Qc&gRpUB}tAUoq#1K9QES zQ*r-v3AH`ghOGDP)5)SlV6;t%!rexlbG?Jxr?W64d!z7KUCmojS@%=qg>N>c{o3^j zBoupLvI_h-W*j5r{TKP(x?A&OcCW%mkN9@)Q@#qEUTTiv?Uwyf%#I{Of6b$3RqR;f z3!8x>n85pPEwB}eS$>YFkRpx~pyYdbO2Z{nIyEh|0QwSxt4jgC1(4Am3mu|ap_raq=DS8Z1g7{?}S(R;=^ zM95AiH>A50`=3_t1G7!yX|SmQKzA*3P6UM)I2Y$fCP!l4OM5qEa(!|N!_iCZ)eSiHD}25#>hT#JdRa@C%uV65vQLn6FnP-(YU3}GZ4 zHtcqktzEmO-k*g(`?C^7|MBeyoXz}P76Y8`erb&;c)sif7?@#~Kyta%{jTbrwkW(6 z1g{PBG1l4TD8bi;E>=(CE>85RbS*)#Qg?QHC#%V(`EavvW>PErgyM~Ga+!C{VfP&e zBCQTIV!i#t=Vaq&GWKi!gk9;5sr*$^4D2#57iHw3BOzJ;1XDTF2EiCDzmhU?q{AN! z1;~R0>Hf%5DjRenZpjLD$U!rLV|Gh3Px-ia2p(3iw(Y9kVHSQKK$W;q(*c5Mkl$Qb z6jN_iXtzeSd=^4Q(GtH5P^xA{dV{d$cqzp8-ixKSc3K3cbMh$wu68;pDH3lkVBRnLkoCrv|Q6~$|Ad19+_3$d!jHukc0AOHTEFt-;hw>1M0qQQQvhNX`A6+ZCYaV;C&b zR|XfkP-JOq#t+!J*eMpsvNN>KEOm=}n`VVX*lm$hh|9F=*?LmdQ8_4EAjx4n7ijpa zCg|*)RhS*ZbD8QS6|!fwjBi~~N*w69q-E z3wX@3o38lz-fqL@a!^?p8C}vnE}yk#l#$xY^HJ+diAVao70*vZr9qaTM5&vV02?yz zEX@`rz5&IT3L+T&I+j*QIOJ162f2dGXSllU3u<-Z^ki3J0A-n-tZj*-a*IJJf`K-) zCT7SJ9QJv2LIIqXy&uAdBda6NLvGEw{DFLv`+_|GkdHFWcfX4?jRB~&?Hr)NkB9CH zB$8(k#7U?6*hACu$^&>**{Xq)4+y6#pQV)~(z>v?(N)#&3M4BzK$@UZLL{F`QG|`zM{D*QLSV5~pm-J2?84r{)F+E~*#=c(cut@pIcS+DkQrg6JRD|M7oaX_ z=+(BNkfs9|>5!m6!;3z87DWHx(G-i+2CN&n)W#*>Fu0u!l7l5mjc@fELU}3?q{fte z@iSsH)eCtkSr^RDP~CDOi=OB1TAC}`fs&vPKs6u8QzF_wOF#4ycWmFOnTy2|bc;?< z-Kzv+iQ*Jq(tO8#CA1U-KdW-t8r}J}9CG2^(GEmmt~UUWR035^5aCF{My4eBd+bT& z#(0S23HW|M#6=z}@~o?uJ~!z4^6;Z#Tv`Dpq$YoZrUQcrRfMZv?Z9!^+kOVs-!ra5 zP8HVS$t4`Jf2>`KA{Fxk>0e*LsFmEJ-+YGGhaw7fM}}*mN_KDVV-8Y2KCICLFJo&{ zVT7(G$C4Xt0JUWwH;dc@G()WveU|b5s{^sr&1xjD>dw3sDDwKE?jFCknX_ZMt?g+9GsN)e3hmrME zmldM+q*CGjkMxZ!qM-<~K;GisOHE!4fcii_2_-S*PSi)+G~xaqDN5iIYL8`dB?pUT zFqp)F^t`McW-%VvR&bsn1LYV5*>s zgYLG`C4yNKO%=&rD5g!wmAGtp znyy8X9hkexVNixGIMfRg=%=d-mNo_?SWUAP^P(r%GY^xsk5J*0JNzi|x93^DE3$7> zFjrAgixP3S@US_{aC|)0Qvy4n7_mEWo6hsEj)!j5S3?hCqTQZK>J^}EynB=y*ebCJ zR#kGIbZc@%UVA?If5+d$*T10M$~|)BA)T|n^ek^iPBs=}Q%Rx5WM_fTAz=Hgo|VAj zT;V;u(%@sG1X}w*VvO2PTaZt&8(-XV)`)gQdZB1}u0c~{@*Vg6- z0y;^ELDmM+v8=$GHziDD5utLlmHXHz=cP<~5OyNzU0|9@%!96~qmO&A#DTpxR5+mW zQv#IUEe2N2T*KV4<0+BQKAnm?(?j>gAy@DNgrZUD`2TtM8;jSLls%Bu8;Ix#*1rS? zrK->&S!mUPq4S`|0nf`qM(>omRJtOnY$PA|s7o!=Da0yYfYPm)DrA>8BM%{_TL8h( zT=my5BxkK9wAR#w95souPKq*~0e!)QH7}`~rUgAJ z)~>g5M($vEa(zhHSGjK7ior*BbXqq z#wii5j@NMORm8I&+3ZI{h0IytN9aJMTo_w&0FqJovg*}bOD+U`9!M~j*(TJU>^1;? z^>Kj+qFqQ2x*YmXhAW%HHd-`Eute#Atg0=vs?a82xulWTnMPh9<%1lfKup!-GrXd7 z2Q1KV9|;a_{Z6+w%t%yll_D2EfBP4TT$r<9_f&J9M=Dya$D|T({k?QF(KKKKR|^e` zE|a=M=QlmsG9Tb8MdNO4RF{5MH5Cd5x0uDvSLkW&=dL-Vt2ynu#z%ykNIaU3ls81C z#$^d%APv(4ww@X^)eVt_0{QJ{S|+Ou{3J2x1NC^3ZnJ-lPw-SC?qGc884x43jFuin zRo0>34%P~4SKvUfLETc;{c?M*?b8asTd1oGV0AXV>9|tb>qmKr^q9w7Y>#{`>r}q6 zWW|;ztNl260u>e8t!w)Swr~G{e!R2!9zlgX@}~#%%dP{wU2u(>v(_dCQ6qevnX;&h zI9Rk^uR>~}A^jCmZ%rx~1zU4po|5|mo9}Z5FnI{eK~+6)HvtgdK{pBxcbESZzIm}V z`LCI1^Uw0@@7}-b?e(U477Vw_nxX?(A`H5Cs`laLo#`^? z%DO5j#^(Lf%YUJl$o_0(PsoBGj%d}z#zqsma_(4h?cEVON#<_hONp_#@1|7^{>_63 zA*f-#eV-0fnD=em7uhwFTBB!ClC9IBjYV+_ES7iV`MHAIUJi_Hqv=VASXvN8O} zt+Gmqp&d#2SVmG(g%1fs8vElv`PzTs>t9fzRJMe!3a>k5Lk$Q$N0xNv0AIam=0|a* z#@x_8=nbk*c0}T!jnT7>1RthVr7F|PK?cmvdDz};DqSb#H8;hZ7lpgUXa{X<0Cxvf$ai3gge3%nz0d49r#r1kK`7PTPt z<77XtD4}HsTRH2?D^LQ;ciw;f$G?Vu?+;jX ze8Cv-2Rj~t|E~Khi)w{~QbHB52AAD|ID22G^LQP}0yt833yK7HR?rL(vCL|{u+kZ+ zpQl=yXz6c}RwC_8hmR&L=o!&$FAYc;?}Qkh_#*x{a`NfB46)IV{|frb&X1Yu;^d|( z-C^IH_)|tha_@J0l271#B~5w&La|ugaqlIDAG|Hesr0SFdVFs@Egy%1oO`06WNR=p`y zV1kd9&SY!r?p;B||L0vkqlTH1(t;(a$U57=a5$qfqtyOQn@+m;i<}gVRu|*UM+Ux+ zg4=JG8+tbe9IBf@dVo4TZh6AgnUhTwt0y!j-O5&7hgGSbdqINL%&iTs+u?3iJU#yU zuft#GvQ7Tk0mYA$t)^N&l|#yenN~gtu$cKG2QSQPNkdla-knNxGvvj3Yx1X$3QB<- z=20|zz$wknk6GtUGuQD+cFOyAFOpW+pc?{&IHgQMlvB~?NtbiaXu(`tTI2!kKSk{j z&^`f44ouHjXQ0gR3r&k0s=Wb5<>JuF%-2(6l)bXhly7+Tru0<}#4H-&jDg4m$klS6 zRoKwoLBCN%z73T8ov*(A{U2a#&bUV%@n%;a)yUBC1+|`A^piU7~ z@gVODg)5`Mbfn%au$s+l6`au8M9lfg&27(a(J9q0@TTuh-C{K1=7H&Z$`Z!c z8by9R9O`|DVkrE`WB)w=qzA}qV zIPQ=JiRIZ>6jMA--c;G@1Ac(^s6m*zanf>o25Z0GP%?rn?+(f@b9kAz3t(y617Nw? zA#bas;_k9Wc36#_I`SM{VNV2!f&BOWCVV6BL9P%syMAk-bk%=sX&L&ywn)g`Kv#Hr zO73|Nr=i}m*m0r#EybtU+63xS$XmPJ5F!d`(ke zUT~(Z%eps%yb2`T6E68@B;I3p!}>V;qJ+X++A+G8bqfz;E=%noW6Cd)%ceh1$gwc? z$O+Lzc9h|9H`krghEWBi{Up48a8idBIeF0)awC%~9$-#AI_@B8L*PanCUj{Nn{Z8p zBb^C-tY>`0fbRs&K4+V#6us1vNXtK~Ix!$9H|`#lM+r|#A9=_g0jCe%dQaFoKsP{g zG*_CM;Ch;0FM|Sy8o6Ot7g1X@N%EVur2_!kr^Rz*Ss8p)OeoZzLw?>(ww*)GpsZuv zC-cW0CAL{w0te-W zQ6iZ=t)O<29C|36t%$N2Zo`-$@VUKXHEXsIl zen$q#4LPW>BLwo9?|_}3$P!VceSQs01PJ9$8k`mFFlBE8Wq0M%RWkoPm$D}iS^RXR zZ{3mG+PdWGfw_t8MPeH3PU@T)@_JlepcPwOm0G~~465|;&nKmiUuTUE`3+5@--P#n zvMZm`D`>XS4Lgxrv@J!&x95QA)RTY4^E z`$E1&-+KFTAS0l$mf4ICeln%pxIk8DTRTkSE~)2N-@d4KX2v_(vt4F(?#3oOKJr*a z*RvnAhhq)f7s_g2$|q}>cj06mthV%ZEVvpybZx>X+s?@X4&cicctHIDe#DXnq7k+d zVci39^`FVMXacwDLyz#DMqQ6cfRr4>*{p3)0Z~+ z9?h>YQ#P_zw6nLhzR7iGulA~jzQl4*riQL|E#R2RLsokq)wj?Oh^lNJPwHmLtVh^E zLD8cM0r|bG-dmL4oJ1yPp}Bp^ZNt`*l8r6C0nFSTDrmz~`Af3|`q@}>TVw8P?HeZ8;rnHUoNw~17Nj#C= zRiQO2*EiLaHA`s5SbGdUr0d0D)OpYS6MO;)@%X81DtvFyX;roYctbyfHI|QViwkVi zc4J+J^YAo4U;6_HD?265o_)cH38GH(2xd3H^FI=(1uh@LVowcIrEN6 zsv(eLM*$$AUnAOQt1RFKqm^cdDd0T$sZFUj~QYDHa8)g%A`!Je|Z z3)TiUuuLC!z2CHE)ftSvOaK=ldf0_dh`x5-0Ums(7dgDmRm1j41<90 zYO_UB^3fFWo=MeNuD!=4n0^A}fO&w`f?JP`Vhn~)-+uf3s<*(y#snyoD}bOb=~=z% zpnr7k7&^qW3d^VpgGDLiOGVQMWPQx4ala-Yz7tbD6s;U*%i0P%QAbq@CwC(Bh9uuC z`O0%frzpNs3M>LE$3EJYJyUt5lj;&vu_$cYb*}6{Q6%(M7qM$6(7NN_&wYheliK=fu}2r-Pab zg_us6B+*hQB4?iVLMI%3ED0gjD>Tv-Cg%0D+{l&4Elf+RUJ>DPlT<0vI!uxp-LitG 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

nj;X-C@gua07)qPBmS6kxKbsrp_1VbHQ%kr&^ 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�J#6HekB- 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%0DQu49$GwTP{0?>4l_B{}_v8!N|W%zC&9> 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

brXZX@VYhc!=SFxwhp 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 z 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

B0o?DtF!VT!YjrDC^S2?RV?P>**rUM?tSk)et zMFAb(!zQv+s5=>il;$rbcShA_T?iz1b7B)$XCoFoujmv@X$Ba%-@E$Px9V>d;4in*8ShS{{H>n=>D-AUVp_` zeMY6X@Zn4NijQ7DXTy63W5Dju9UWD3D}vq|@>^x%=LSfh#@Zpln)@Ej4O4(iD{)wN z*eTaP@;SP7;lbNqw#(Bk%z1B3Eh#j;W@X*7 zx(*M5e?j@vVF6f6MmBEOH;!Y|(EYC)!Kx#WH$%!xVs5zvP z1|iYeC6R^Vcvl;@im16!(b^a$Tet%lzKBkGpSgr(>X~gy48^PzAqqO>z?4mkK`{}w zx;%1r;7@T3t580(6jW6jZ-r;n?$U81Qv3zXlt*j5ELE%HoChqEGe)BeoQqOmyy@Wd zJH#8TgzZQ$K@%z8db!*D>RJ0H=MIkGN-8gDO zN(y*~DHIy?$W98*MU|e}Ff6z5r<8TNs2R^%m+z9TN=KiZh-BvcfnjLytHZ4r&plBP z!0Owx(nNQ)Y;?2=2~sWH(m4zVnhiSG8zgNoGlsWFv^C%i>4pUjQQ+`>6*z}!%@0g` z#49{C2KlXq8+ws@-Ws8!t3ZL1AFCGRdD7;0f@?QG#u{RcHuTL-s=k?(_<*+!hiN?2 zNMSNzI|o*$8Y!Ka74QeBjl!PLIV>tYnz!Y4T2AG5JtQp4wkT9-06q!eICT|V70@+4 ze9cFkLiQ4i3)+y4Y@i=Gklg~!W2XkrNTgI@lzxyHfzfybV{kAVUbex_$*pdMu?^*7J z`?pS}v<;GqWzDNx&yAqfps5Z!ge`0}X$_=)(f!$BMw)k7Ucc%Xu2I+@M}s@Y=nW;a zBqzIdH*`!k3nmbNTH!3=jzUGXKL^_d71bzT=0a8A^1=QVC}9Mh(HWX2_6x3^(i$Z* zr!ld0T7Q@{&1{9md5PHv1_7R!4}@t0hkpfPvhWLm+wS(mJxbJ3+I59&D$_3 z^0n(%CmieCzm-Ii5N~A*GZB@Grp~HInb{N%MIFf>feM3zjqXAH5p6Hr@7zM=nY0N+ zP68wxp1NOC58@atW;-d9!bYvysSC_erxqrRu+BDo@}&K_i~G>_KEFv1cF}YQX{aU` zBqYlbnK(22ACVR5%fYbSdiWrJ7rylsIGmi%$Btski<*) zBqm2$^<|o=Fay8%RY#C^b3$pRAw&*9*J3%fDmk}UGS+tT7f;Zmgql~gK~T^`lj^Oq3PAOuVkdNikrmgrN+*vtmg~cqdKVsr7Npd3;bL~_ zkkOEg)`~C;d)93Lzm!+H%zWs)EzeoW!n}-m-T<^M;9qHT&7@*2L9~&Snnf!n%hODh z35q~J(~3Yi6%agFPK6ISkDjFt){bMpdi&H#9RS3B8(x2hp5#~I?PsXleiPpR?b~Ok zhx{+#AN|P}bY>*|os3g^-y{W%WMgXIM!Ozrg@;0RCSqpAm@=5CS+GSWtA~!;I(L3! zz}rEp;$Az;IRr@>arTi6){L_3v?~ddlG6(Q7Af*D0gxDFP9+?AG4WA~m9FSk`%Drd zeE7AZZAZW=>I4Ik^dAc8E!W8PQem!gRr!Y$d}0mDN-;GL1|!T?*vc%CcS$HgX9La2 zzH89DlZP3)oqfl)w*+`R6$3>T*uE}geJ~Q3t%gf0piw5E!pwg7n(JtgNC zUNaQ6_hnty+Kbe&XRt~x$+DhHE$NbZiKD3mMK4=_)hJQEOdUj>LvvEU*f5`LL?chz zd6gx&cAV!zBA%SM$?;YoJKO=rbA=OFCOi92QGJwkUe|C)f0h1OFn%)l%{e)5|6Dwx zw>8fadbX}tzL6bJuEZP<9YU>8Y*nqJp81BtC6Y-QG-6kc6;vWp@1b=;xWyP%1Vv|Z z$3u(AZLo#udP&f#avXMqkY~_%(m`tGAB>)w^KB@FpeDKS=5Hn)`Rz3Wy?HJ2*C& z=b>>wvn>XzBwLMN&yc?T8;z!>m9<@(Cvc7PU{stztnlcl)BOt$R4H1aSZpwJz!+ zZcVN1aSorO6@CpaJq+?5i1H|LSc`%AFTqWbk>uHLmreh!XQvdQodtNN-13Oh9rrg30guaTauB&pFxUruv!lji1GsJ zz>U$hp^Vrb+>QY%YR(rljD@Zb=XQPQFh#==Fz9-;(JEls!ENtUrgJo5?X%ojttx0YM#D(GYFihy*HaqBlW)6JRZ5Kjmazqb+2INQA1@ddOM8kEPY>vL9jbcx7Aln1E%sp{Y~jpfai zbYP+?7n@;ZGLSlJ(|Ej=d>mAGP!&HI&OtE~IYPyJTqQI)?@E}7+>3)=F)ELp zg!%_4K~|R`5q2Y3IQ1Q%ow9^m2L0-b4PsZ-0el2K{sVSAqzOGoDU?>#rV~6)!2Ibd zOwy$6J4rDq1*a6G3x-gq{~Z3ypXP}A<=c0#WBBy-cdx&VMw#_E|O23I((kB-|+ zf-vh+Q4-thE$u|KksEn`R>g!Nu#%5ynyw@?hMjP?j$CF3%-e`*7W2JEbpy}f1$0@! zx9T_t8x)9nI&VFjB4@cVtPqw>M<+_`Qh&(2GlX}>4nSggSi)B8lI^bSyul9ko+~r- z-||MG$k$}}D%6$(3d=yO1=gAB8Aw%UGze=;;O~d%7EculySrP9%Niv&3<1Ovd`#3x zN45l4ARD&eF_cigusD+%N63_D-Pg5>XTog7j&=ZeD4yE(Ay7v7W`*J)$xVzt=vb>> zD}&CO1^D`>bwzIXkreq2-3qJxAi=nz`*U>rJ&_*P3jB&>JEP(Kh7+t`y&60b;Eul!|DHQP4R0Bp4~#}0f!%j7W~73H zB_8{KN*t?Bx3Jl{Q$aK6uQJ#`31_Pt3bBlC@rI=eqPVo(%mHK@j)~S5mc#DH7JA?& zj^>n9aV*u)JfygCdKRX9OuMGx3UjAbz64sMwM zkD44IwLfzwOfF3wh6qHM7+;9>9NI*N`~YqCl*b}gUL$ZyF*IlY^ACES5*&t1t^(5D z*~Wtoloaa`6@N?fDu{#2nV$$(gl|N_D7mf~br0}o--p}4n5okbJCi-S14E}^nwIzu zlu+!A_Ugh+$eV;w=RN2)^Wmp=m5*a}SE2CjSxIyOL^|iuVS%+JF}q{BjuChU zeNOUVbx;FHi1_Xp;#O@b*n(?uIZnCNfKnOc7q?Db)<;{ngdTtWViV6AQ?dY}EQRRUS)Ziw`{b8~v zZz<9@53}P251NaANIfPiyd?%z53ID>iXm6Bh=-HyUIudi8a^MxNDqq9r}!08TdS@% zmFOV68gnbIyr`z+|1>^;i=ej%q?%IM!2?BHf*?mKfIJ@d`y|D_*;bt!D23wrTtPt2 zLUm- zWc3+nX$+1fk~622WOhQ-23P z=^V^h%E=(Wj+uONL|J5Zhpv{Xo*s^E%T``s+RYHRV!<&f3JHnfdZ0q)4?vy^fGPNl z$47)1LL5lRlD(#tfG82?sZ5hXG7%#vl_zol+iq#Ywq(-eY1aIrv4?1GZozWjIS!$H zXPY&8dN?DIf@`QWp(N+x@aj%YVw$?zs-QpcdX6nATE_^yo8a~|ffK}$-y#vnPRgXi zZf}XA2J}6-dCdC95Fi#2J6%AU0`3gzpcrkH(6$W1hS|NQ8n#v+$mb34{oecNie{^n zqsW?BRzic~3^tA`Y|8^BU(u+&Q)(MV8}7rXEc6DHG@LXksVJ=7L0lR9s~+%Fq#(T% zSs|$r>?Z&AlF8(khLU12Om!4wzb#A0F=2m{RsdJs8P619&TaYqKqt;tSEeW_QE@*& zDN<=-tesn>jh(U!NM6yI=rgSs6lu_~z6A6&QLGdQZW?a4GbIyX;s+*#>$^)#JkWo* z_xesXyji9-60Paat^z_Pu>-4EIt%s3yh3-naZ@SLLh+-s1WaXJpYa5`cDKVa7PL@R zf1zUVqo}6ZqWdTjNSP;p$=DA{ge6D3!LPNS>zU;NlhdE-tHA-$Y9&>)j;IafZ&$0! zbb@?SZQx}m5Txrv3^WH!OlO{|;;PraWF2f=&S^Q+T!NE3E2tR`7#?=&L7}Zr3yc&< zFK5I^7-eu!m`Z@UYd=pV%&$R>wdi+k*UrUW%L3yPB5zA@r8%R3a%ZO|?Os*^Cg~o2 z14Isr+Uh>=U^eP?*WvEi!>>(kD~$_uoD}dBH-78j4cie!)eJGA! zYQ}821huT_9sy=E>(q&Lhj{C=!Fpcj!?F+Hvv@@)50FM6@655^yTB=)Jo*J{EOkoM z$(6EVlQ#*s8QQQfs~UJO+zH(zUqUG%NUn*mh0Ea}ut?e9NNeoCXc~|a=Hm+-L9%wZ zcU@3?7*ccIref=t00Balm!Lw;(BSE?nYZNb*a%LX{4GjRsf!AWwu$W?#GbRta|7XD zVM%oByC;T}2AA;!uW-3q9i{Lma5%bFdE9^ zL53U>Sd*#kH$ubvEFf&>0ZplqZW1{6EGn*txH^C>YjL{VgKD~PF}b8*l9(4rg4PH| z>8i7|<)oakPHQ?V@7lDgL>psI&S2$1E?DUG7?Ct{!B($Y+9EO2Ugq88Z(2xzLCUY$ zRG3T_fcXSB82RaTv(ScmW+vARPJ?iiZ90^5`b44P5XC-oZk3;rgVy*%Q2ggWC?*+`RrmQkp=$O<`#YD3oHggWM;v zBT(a1&KQ_gH;nZg`j$vkkd>x#=Caftm?U4-t6_fD<-u$w98B~D1!U5C1eit-c2HZE zzfKLy4&G5)&qAYfwMigcHfx2=YM0q7jah1>v*D9uPvTm7GAEuuNGse+0V>nZQN9Pd zg9DF!m+b9%n1wrz>Q^W@p!e&ZrD~serxmR1Bj#8HP>8&@2~-!0?UxifwgGV35><>x zS-i3GP&;FZ*$`~EeaWTw+{5c;rQ0@C-H0pnWik38Tm_OEw)`&~rVnsy{9pn-Xp^uc z%L^0z1a)d##VcGlkDS0vswyYCMEx-=gNW(;=yJIuDX-x(ptl8t+aW97N4TQR?g<3h zG9=R$jISLQj2NCE>fLzVQM9fknCV{tvoM1mNgul^_apPTyo$rXEgqU%#a(KaQ0y#C z&Wh9C7L0(891H~;2HG7On6Q7O&G|g14}41$1WBuemgx94l%=J8D!5S{-8_velxPA} z3;Kf8wnBg4fNM9}_*yu*0^+J6BHahcfS}i@M_DsCx&Ex0m&G}*J8B%2)q$~7IQY+~ zZU!Z50l>||B~VQX{J3dCl#r;iW)TiM%TT*T>4F5s z3eYJ;^)=8lw;yPOt5Cw4ezGhCdb#x+&0;hzif#0|Be-1vhN2R^XYQAKuZ-5h*GjO3 zEvnqzph#WEECkIEo~utvrLoy&@s8NsF_RY+*;i z7*|%>Fq8SjntSGLQGVMiO++^XABD}pbC#1^(m7d3X?Qhiz< zAc9zcT8z}TBA4!z3pw%tRInu|B{~MK3A!(M7rqjyvB23j;g74T4Pm)QgfLmApk`co zNJGof!q<2-V|5tC^%8)`ybvs449z+60M4AX73l}MRG}uMV&ApbDq9lmwi$)WHJzk# z&esB{FUU^0HJm!j&fVk5Svx8`cjhakuz?2~N-K>Y(Q zJ(8!!1IkVV*-IhG=#?!f7(d>*UR?rOFL}X+l;=K}VH7$C*%yGPQq7}nX-CDYsU|g< zw8vJ|)x71Kw*~ZHa<9d$qe&7J^H$kNZIqENh-V2ttmE0@QZS1&QR!LGF)`yiU0V7z@ zk^&1asuYrxRA{0l;0`ymCu}8}u=S|~iC$5>`KZF_7&}Ty0AIYNSE~FW+dy*iQ0YJD zU0{X*E@O+Pmpn6Qca>5Bt&&W}VPX%i*ucht)$x_y)LWI2WUKn)<<+o&Bo8Hvk>|8- zl?NUWoO+7BmehThb^p))H2j5r^FM{3{KXMmo@@i2>AObm{gS%D-?MajLhU_+_QLy5 z-~Po=@>(7JMvEjK`Rnld>FFVlX=Mztho{{8hVc%?yzWTM@(G1BTb)1sO%7O^v#-etz(-z2~UkbHNZ>4TYzG4EFB1?F7)p&AqoR(cJ-qYYA z4N8AtIQDdMdQ5H#91;2%2ANBMhBFHenLSs!zJJx9I0!7zn$vaI5C5j^KM3T>N_&V-Cg zJjE5`$1<&j_0*)&csMf(e65~D7Fe1u1Yye(4=+t<3Z3&ZX}Ur9j4%bjXwdx3x<&&p zpn1`cgmPb_BVTKIACUY$cv8^BKY>qnNv79_WQkX?Rt_~6X8@zms#2&3@>!YLM4tf0 zLP;SIxFsU9KOp&uoITDt+6Ws&g9s=Ty0<7Iw~tx4>1M^u77=B2xuOn!X(Y7DgCh4k z+NF6PH%-UUzpP993E=6yKqXPqva7_5Bw1Y8~*uu#s7?!(Lcp1|J(5Tv8xx!+WjP4 zvp)h23RSS-aqQ7*_AV=tEO4f`e20e5z=9l@;1}BplRCeq6Ao7 zw6B8)mhqaP9$Oc~(5cn8PKB5c?Z5J0`YiGmqLE{5Mq~_t|;W`GSxP~$%!YE#UhJL zp?~m0(vDM1W*C zTUcod#FXurhNvE2Tc~sdizUfK=BLUA$(D^WCaCr1MG}UjRv#w}f7cVpFc&E!WZkz_ zf0s*mLx5f*q+G8qtEPOO-rcHGe!8RYk!dqz+BiVlQ0#)s&6ri(0ZU_tBzK+ab~Akg zhiWVE43pl4PM-klS zb=M>rC;B^i&&@clP>eBdkgCDf9dCyVFi|HAvaIU_jOT8JfTR$`I4077aQCCcNeuzs z9g&<}V5NMNW}&+$&P<~|c@1azO}8~igqwRP zFi4`>v=9!*5ITP+u5#}kGMSiwKrqRopMol5ap*3@ti@&Fuo$nMI&!9mrPK(Kj@wqb zcMF$=wwB`Vt|@WNeJ9&-%15@L!+gY$HnB0ejA%nI8=3^@XIfMYL)U1?lSQzDpawrr zHf_oGf(6Y29rJ)o;a9@QQfJ_dkk;5ioig$Xk|o6y9UL5oj-of#dMh=!7hI`bqVd+r z{XiikPFjKgM%@4{5=Vrq;A5e>e)g)+tm@_2KpeTuJy>26bn+UvcR??)If|tiUDXJm z6dF!!x?Q2~l!FpVHX^+P^>m=yd8Q)LyA45XWBi*WSzoP&!N?X|qazG9aBws=4-7R| zVx@}`C+|r+sZj;PNj{;tA$Oei|<|EOZ|Pn1(VCV!)WHn zY;GH!g&-JFqGF&j@-1)$zA1ZAH#f|T4pew-jGPqSZHd%iXElP>`=GXZ#SUFQsn8no7)n4yb4bIJt=} zPz7x!JYiKHa}l!W9N^Gbf#w7f-@_UO<_pJO7cO1#I4!VBYDOv`#bTUP7yXJ^)aV_) z=+OWo!GJjM-74!L0xk|T@QsyWfs9@Cb7!xy=Gk&`IH?pRWp~%j48Ea;y2vSCT30-} zM$*mZWBs1C1Ina?VP>)j_i!BM$ZF<@4o=`VY9GlOPo)gNB5G1NRD!p13&Lg z;8eV(%IfTR?#E6pF4pFPO&K&%wF6G^+&jT3xhQ<5PJ*(Ce|iE8ZmRS<#>n=UB!X+` z*`>*%M{@V{_k!(3q%wIEnrBJ5y&$2YmLKH3$O4;r;N)m!wgX2|D}3gCdoAwV8AFVQ zc$4DN0{V4_akYizZC-D3L)zpBnnabldSBhz^Qtx(Q6l(M8MXit_D@Qh;O7kmI9Wk5 zGl&90wVUML8@rS+TgV~!B{)9|L&VN#)#~T{LLqo$niY4NFzibDt-?kt?-5NtV$d-{ zru&NAAp==i#uG(&zeUKFtFsdIIv@hlfF4K}?)VG_&so61XlSyU8Rt^j-s1_Q-5}=n zoND6zDrn=rBayOwcAm@44At3(-vO)|HuyKZPzr!NHKeesH=B?|8 zfnwnmD`1Q=4k6s&k=0 z1dKaX4#VtAOEDt!jp##A{sox6qDd#P6_Tsd%e{6?&^T=^R1WA=NF{E8)XLYd-+sog zIV4+&`=Qd{kL5rzvR$J2Cjn9Y{|UzVdL+3pl=R-AaA9$52RHN1?fHn+vH=&V`<312 z9Lrl6ZEMMk5yCtw(wX<99+r%YcjdhewR@`s61r~*0o-89w=RKBMPfGG0~N@{y?(2% z96YajtImtts{(|2#|(Spfn#`#GCEh$K#-3PcLxnkQ-FtoiLnjMdVDQ7F@ggNXKQN} z?rNJRDWj5@S-UKgruCl2FM}-SHc*qa^{`yUM7hz}Jxw}}i`_M}TW+gPhh;0wa8>JY zd{R+bly(6)0(lWLxU5viU)2F*g`5cRShby3D5rK<61+fxcdFVkk`7%BlRWJfumS2k zV2ba^s-MsVTU^hhnbp$rS@&4S>+&Gl>my`Tq=sW5FX!|$Rl$k3le)?j+ni27AaE9f z-_cR6H=V760!0m!2{$&q$A{wa^Y$HzYuoj{S=g4`XW~5uuVfDR_H4&P-JoGZ;m{f= za1KNVLMuHHSy*b`2JsC^d3t(b51l@^2m%BV!U9*3E9?Y2?{=tEliXcXXC>VizKhoL zK!m)yv_{ha_EwZyw7~cqaidqNZ$7P=E@p@dQ2ZXmd|wjFKSbtkkx;xWkS^Syn%MF$ zVm4^3FIj*dC*{gX(1q@kaiwW=+Q}83pmZg_!`3gr0XtdT_h%-UE%C}t-fVLSZoANI zprYr^DO9$VLbLJ0K!en+-&A75SRDWjTDS2GI&|+&X39h%lmte@5^bzUDG&IABg7hN zhW5*9kblWThWKtTWd%@z^jlE{w!8@>)|GQTw15VBnH5bD*u1RJ1&KsQpq+{#f~lri z*eeEvt8@l(5Wb=&U$LQU2hLOEe#k$e)v3Gl8M(CK{r#o%BN1E&CmDhL-urs!i@xG_rA3cv1c$ z{0IH|lYga1_%(%gzcx3p_g{v$Z>4aAsl;i|NE{~RU>;A*V($G@Dt7Objz|m#sEwO# zpUd)}VHdqbmDEYvVxT?R}h?3?nS0Y2Iq=1i?p?0PP(RJsHEmMEiK%VE)C-euIJpp*JOS8YYf zQckYbL@eP3V#Zn=EGcC+ng&$bB|w3wWDx;!7y$@6+wYMQ%}+aex(=PGhO%ssD!gne zhDXU;IX(G3&f${R@poJ2O{!e)$wwnQO~T$N_f=9(JcMq$aNazq0NW1pm>dRnpLglF z4<2bY>cbE%o)XY1HuA$*M%IM=N~L#rl%S|X563V5aHFZxpx$m4DpsCH^lT&4SXk7R zoxBIwraSsip7`_xE(3j|7hpj0I02$TyaLQ*&VvVY!0S;cnq|zpV zF{ko2CX7HF+l}8#HEcgC!4ySUG0_0DFC-m5#GR0Nrj6W(E3yYG6s~Q;%6CmSI%`4$ zK8`FH;Y+d+ha&Gq$?7WMn-5jtv74Lb0)j*eIgpURh*yQ3+iL znFf7b>IS8f0~S$qIFVrP)G``w(w*bgL8z7Widwsh!LBziZLlI*yjswswe6Cew?w5^ zsik=cY6`L_T62EfF%L+t;xt}#@?@b)K8to=JoiCwvhyuT0^sFUplSe@D%}GiRuak1 z&VeesIvhS-#SB45x=TwPGRjKxZab!n&7Go_{XVNHS%0R8PQN|Cld)i{IAHrEz5Ee4 zbaAirfY7UI<_R(eU~X7Y0tEs?52(8}>C|JQUNjtIUC}}7Bmf~}P~RR;hA+VV%FXT1 zJ9IDbIWT@<$*n<%67}$bTArAq@=oto{Di$A{&8%8r}j~K3*R%AJ0*HIhI6mI-w4(V zFw;jRnp4x+0=^^lC{_-mY4yyweNpNie>TEY9l$Qk9iV zoqHD{pDuO@E_c>`K&~(#%zMI&_Nh~V-eXdfBY=hsKnIGR;)DsdHMJB{>%2j6^3H%0 zO<%lfGjbdJNge?GvQVW#EH(2&^Y04nx$&9*E47reFaa22*)^1q+c5fWuOK`}BqRPq zW~(^5imE!)#w%q9AT?N}8{$(5yuSQ0&gORDuknZvLEX!+;eetjH$QXl?xKJv@gp9XID>t6rCekV5a z(Vs(_!z8M{c>8Ji;je(T{35*m_O!b+_FX-3Mz#HdQbE)56hd?3Dz~hMyLeRv%al*R zHkUvuS_5V4(M-%7!yJheO>dbV#(m&_J;l7T^KDtjkbfZn!rdJ1x4rMQUZC55=yWwj~x%-jRzAs;MERjc;c+7s?L?kms0#LL_Pok9#yKC}QSe9W%!) zf=q&PjYU(6)eNuEgYTSiCTo3eByvA^Lw)LE6_1h^e#;w#w1_B&^(&x5a5E($ENO?7 z^t4fy2DblFFrkt$DX?@z?!I|VI~LxS8l-Sd@iYLSgm%q6^&G|z13Ok|@L3Hf6(1^f z$y(WU1Z~Vo=R*O3?4j7y^tc#l1SU^+p&lV=t%#Dzrk6m%b_8QXiZNO%PnPeZ2V03!{J$rt4k(26z#}_aHdd{vd$jgmqTvX6M zICV?5%{>Avym`28W7N}j;mQ$Y9+e%%Vwa5qMZ>fH$U>CAARXZ5~IB|9X28oWtfuTzVbmk~40g%a0 ze1W9cNY$1IS!Ii^^8=P*g9XHcnwfEUQ20G=QD^}qra z$e0c|*?6e;Vp@F4bWz4p)i0cPRknbcOhnil(TE->m5r8=@dWS-$m#?)VSqOn3^`IJ zL4rFp%nHPBO5K3Z5FYYsvkEKg0`D|!#JBixQ^UvSQmN%a47!GIA3qbJzj*zZ!139q zuV20W;r-|G6W?U$%U6o&|Cjt-v?_o3uVfN`AAlD9NMaE4W0lAsii<=a5}v251m@T> zwWh4;C3w$TAj5{q!AWhF!yVv*{M{Cz1b)>7kLH&4F<8DM49{c_DAvH@8}$2NqdXT^ zwCHkJo5H%;wcarB#W>CzoGqx-E2Kf!cAH&IQuTn4JANqc%LhYw(&l$*kpgXM`cBG9 ztlkTUJ(%R@1B(FXwyThBnj zhC4HNkh`(TIjbTq*bFXKI^kyLsv^(-6xU~GBz2MY@-tw*WML7Lvz-Ew%E>l(Hpn#h z&XKg(C5ZtuHlL45Ihxmm)VmQd3Q&j098ct!g7XcaWG{a^!!`!AyNEx5$jys(KA#Gw zK~;SykumRwv?OTMM_*F@7WlnYXj^4Sz(jNaRt4<1g>@oyRiZaQaRU+08k<8XtuHEB zc%%$)Q0FzlOM+6(k{1SBq!6IwQfx0qm9D7KV$re;+x2vnkYsQdectT@UqB12yNV>b z@rH3p?Tb4As>jp^01eX%>uNOo>_vzpQg06Oj^cAAx$l$)-b&?`Q1vN=M`wL$*@iPT zA*LAtVK5WeuSTO?uuqx#KHYWEQqM_tFH@${f*xX(>073L}yB7jHO=eMk(0 zR|(ON?%8evylM(RArXnxs(`(MwF`BACXuHCR`Gz5OMq+Q(R~8bBjonx=ncq9^}7yR z<+hOQ$&$KCbv4t(sD~4xz87FH%n+@URfda9rNn#^>Lu8{fS6~IF{v$lT%Q*V$RWtv znVD_FSf)E?C1GkNLJVc2pG*A6YgO^>%5Y5HfVRQNBQT*A6F=b1Zm`+tCyRZUE3*JCDo7RSlsF zB3W7I!iHLFE&9h#82J;!fe#Ez8z#%B&{BWOC=99XY*YsdmjO8>_;fW@bvKykr2#NX zr5H^%F`P!=rgY{2Q$Vc0?RZLAp3)?bsNpyyxp;VUQvweV8?uB=FyJgMb3QWS(I7}KA| zf#-BAh;kqHGoIyxm?8NNrKEJK*Cc~wF04&tH&nd~MPY@8N#&Ylfi0@(JWp;~rwI&I z1Add2dw73EB{58%XS*Muo4-NX)Ot%GHCj;*I-{&qChh^!T5q+ncCdZZT$+!c17~YV z5~A)fJA;%)M74G~UEnHz2}2LKN1^=-u)^)?m=z^8KtgWifARQ1?VYS`74G!^{z zE0p%Ue3RJ9?u5!v5Xi3R7Zt8rJP^@DK|Pw+lWEk4ipY)hVo9BW=X0P!GIs7|otcP` zI2R>OL4vJW)x)dI&9>qM6=$dr7~mu6d@b{R&aH|d05URV-$u9 z1b^tF1Bq`eZgy-@4R~ff*zcx3TUAlR9#iHq)=-qSa0jQ3g=i7f!S+e(0?^d9xFu>! z4G}72oB*i(>aq}8g20zI)mH(a9}@f&p>SyCDG7r35vd1@x`5LxWPEZ-Ujl){$c6-f z_!`)iMx>+%%D0q{_hP{cjpbotjEitg(LRDsgDrwB-j3Ad9oSAFC?UY+-j?IqK{Bia z%47t$YFE%n>fJCpp#f&KWDgw%$j)%}hYTBgmpw|DSdubQT;#Xd--iatnDC$%hgr&B z{$==+BSij+V>b_xx)a{M`>~4FS8oPck&S%x%h&G$yrr#R)YtzR<18ZT`;UM4YYGgf zO)imjbpaB!`(b}ZS;~z=0)IwWs=GY*oyl}pU!yxa1^06>{y=VoqGw=j(D?ND-J=VW z-BCrmI=~$S{;O=13*MZ zy2B67zOBpAIKPE?J#FO?U@@NlfRAC<^A%;R_!Z<`Om|R#b=tS+sj)vPh4@Aj89db_ zFJfbHTuhxI+uU*&B$E^8hgs2HcBso-Um2ez$A(#&PM*LuUsuJ=;jrqCID@?iW<-Tc zL{5<7NTVOSPZ>I1G#p#BkM$&y6^R0q8;z=Iu%Qbk5EiF8^a6wBpr9U1tdKF%lWlTeOr)bAlU)7O4I%Y?$8IYD9SqSA%L-T zmBT7}q_^J628M+r%U&|ijYZyOTf9zY<-_gW9S6xm6-MdU}Q~`u>=vNzL$Cpo`nPu zVV)Og@G?97pvV&vi)R=P0zFOMz+B{{5D?4NSce!2E6{Sa>`oFQsp>&2*urh0+!h$Q zW*I8C@!|{unoUDZW9isn%!;{o+=3l!VNF|fdi*^qn*8MmR9{lq@yoYA99Mt$_7Q*9 z=mP2k{fPyn{+JJeqeUf-eBtO(?dSetaLo#Im01Rh`4Smm!fdE*4YNI4*1ywtaro#^hFwU!v zFYGf%op&Z0RGz~P(0>=A2QjH(8Cj|mowqH=#e02AZpP{HoD|~foO@7hC<3g%0b{mq z?iA6wxK(EjP=2#@Jw>_jl_f%=I%e6WtO*mBuWJC?Wt8&KJ zT>*T*1Mrm}@U}azp`d1|>?9X3rRX!X*dil6vU{7-sO!^P|6v+zDte{rc)Ll|;-BZF{N~m>C zrwYR84v4Ih`+`X%P|Z|~rR4ZLZ-nQ8GzQ{><0-0IWhU(S46S`P`KuHSXn(On@(CG7 zt)J#@;z+kbQAEBaTnz>%l7k<{w~RN1mxbNuC0u z!yIdh*Z>I$INcL0($IkVGB}ihnb;YVNGfJMSx(P&qra0i(i9fMlHl>RxC1CNdI_<| z$O$5*08J`W&i(~JOeB|#K$_$$4sI}*$k*XNJ)ORO7IohL)zYAqxijw=*W0d$GD`1`s85oB# zE{Kzw4H8YcVNz|!HKH(i7eL|dFm%ah63}LT2Lf&MzV5=1Di3S2htTMHsoOvneHqv) zTi|QXHTjg;=92OvVY!wMV$_1gOB( zf}OG{O!04R<4ZLKw=;9Rtkt1D*@lH`?`Xt~azELFBcAc5o3s3*@UQ=X zq2Y$C9Z}8$=2r}ro5Tb3jRW-EfTHY9{rzYifXUX7F4O}fXT2uG^JscA*L2m}$VoBy z;~oaD5;HlBQBi=rQZLyG%l-zmh$TtBz~>M**rdC=c~%ZBAdQC89G6Wh@~V6O+j23U zJ0Bdwp&c%Y#wtc;H!kR3uE#L5ReU|4IOx|W?aQzk1_?%@O=LO5N)2X5>KfP2F`2Zv zOc#H)MMg=8;emzW1VpQ)GmX?9+4CY==xNkyivhc;=~cEpTp$nu>j{gkO>MRw&Uh3{ zPV+L|I6m7rI95Vjnp$%^O}5Ek2(-u8GWQ;Q$~uP0$e)D*8cca46UJaY>!j{P>t7eg^OSmN;bA)>mfybjty~{+C97ws{(jDhSPBZ zbE3BAK8L5)FR}K+JE$>yPty ze)RT<{QuJ+fBej4UmmWA{Bl50QV%4utodV$x({K!YaJ*xUn>V!lnz5C>iI`?SBWx< zw=g;DG2pA@$*b*m-|EJcKM^7N(|QYw#=^eFfI$yiK;2h(ruM{BXrqlJJ#{#t#ECpG z=bCEC>yDXapJ>+!ZHQ;rG2n*P4IrN{N9=Uc9b0vlr=mI_?OS>zQ! zvB>h6H^T2173Pzyvh5v&iGCFPHg9TlZjr2>Fjz*Elk5HF_~<#px=HqTL=Z9=B=#_- z_4S|@n)gT}zbTX>Wchc{X-2#fl%X7sEoisEx6RJcSR$M;ZS;D;#N zfNW!g?gg5M$!iJ3BiZ}cvUI@>l;aZZFfOZau*qE1ZTCz?w2SPb>P=kq)aHbhCfbN7 z)NT@^yfe{FbGJj_VNq|>L*hggN8vPL!KHKHKGY8p2N;Mn+AOkxJ|bDq05WnCB*BKO zrkN7}5Ze^Abl|lOMQM4QIc!GG!2g9m@Dd$y1I3foH@`;BaXfUbDVN-K0o`zlf7VDz z>?alBsOWKDR~cy|fw-Me5OxNA|E=iT4@5k}_ab*w0_TMmzGC zQn>wD{`|(&I!$>jlg1y(ySb24epvMBJ1g3D_3^SX6`m%*KQKt#@~Z1oI$_EQ7a6ur z*QA15t2e{p4XraxICQRkpucnr9>0ne6E>oHB2eM%YjlV1UTf7)QVMIBXk-V@Ti{_Gjmx)Hcp`d7zg=osl~Og!D`EAx1P9DtI9>0utbr?y zDPDsuX7%Qi1RjbD>C{0HrS4B%Aw>@KfGjr8RHkZGrR-k2t@Yr`uZ84{NlN5s`tai` zx{@AfW!3Mp22Q!!l05W~7d~7~mt}<>BO%#v{gsb*bkEI{t3(6E=j40vz*bY z@2LZZ$=WVo8_c8H+R>P@QP6m`kX(aOT@YtlPikG_K$Llfb*j9EbPnT^v$3e+v#`Pe z8n%r`?blFwbBKq6ajZawnd7Zv1f7W&2X^Yo|K`irUx(*D=JB21zJ0;3fd~1!KYjZ* z(Bj^I`u0ny;ZE;=DD~lNGluv747JXW-hTe}(dhwp;F32|*m&YUo6yO&x+-I2?4(lD z20cq}6H;L^aLcwf{eFVpYf>$z*+MV`!xWdfQ@=|Uj272blOoRCr#CoO%W`I0bAi+y zAcL|;T3|+YO>HlLe!YvObc9sWKYeYogr-F{Aipz7K(-UdWD=0FD7l3EfOy@bO4M15 zoPfBo$F+chvVsst-PhsH z!-8DhY*3JGz;^Atno!}^2i_k}X(Sq!eYo$HRAd+*lOSHBTj*#Hc=T`x2N(OJb5YDF z4$2-BiZNw)G`@ zhLG|R)f=~DXn-knQy&UjNwar99f65oWw&6}HD2(@-0~h1`x`tJ2!0&YGK*p+A%X>P zl{-7-q~*T^HVXChKZn10jxfJxE%tk>0pBpX$ajME0JFxVwCtM`de4&o^P*(l(+MkeRL*}%KZl^Mp$dN- zNW(R6p29nfAd*uQ1=1wF`nyqvcDaUag8eiM!cj&r&V{p2aNeK4ekR@DX0F2#;z+9BY~^-K#)?bCE|NHMbMEGhm%T2Cy^cNBCv$K~M@cC5(I|9fE7g7e&~xz3J4iaKuvo*s zV5{&(JM0gBMgtZ$r+62209mC_n}=)(=@UM5IoQ~g8}ed(&sIuE1#G&?K!cC%kgRKt zft+jzmCEgI2j2nS^)s!lU$B?k@#2z~3YvF$#Lm|dq-8x=d-EZm7SkcsaF(b4q}niyv0&)f81EpkmP#A9 zxk`blR#a{2|e(OH?85AQAuoS8h?T%ns)XUd@M&_xWAYG0{+mm zzxkW+y(7B1h}V~I|MqnC^*8()ct9(nzvQps^|$`>uOGvT?%$!Ye+Pl@Ymd%vf5e~R z&CTh48xEtoPu_lx*!{7|i#?#yYP5k}ZD@=eFgvUtJqBCcgto9c>C7CMqc5ez{H63wMjD%|)!mxp;UCBLwuQ)(#%SdV6xMa_sQSw0L+ zVJ@gDpvnel*Uw4EmpLTKGhKCu0@jo!c?bzb>6Na1P-a!{(uv(ShtGh!-9J&^$Fr0l zxt*BL>$`5%P%cA_M@Xdv-@bB`$HM&+{2NL_=;K|RMYU|dI`>0A#*GHbYbVtohkw}X zENWbl7`X1pbzo+5RWrPN*dEI4*SePX7gX|-gSUZ0u&W0V#Y{pg=K@m&SbPup)#WVm z9J%pdS-!WxN>R8@Qk-i<2?h-C;+yy4tGdDaOLrnJFtDLb=ytfmL4n?`%JO-)atpWV z!8tjKMM5SJ9C_zOo^edCRz#D;PF=2pxThoe%f|zpEja!Hv+j^Cma2gk9QD=6YQO{9 z57%5}wW=YyV|8#G#+-Wv7H=vfPpWEsP}F26)%)!-$8|X0885P@ohrINnbs9R4O`^6 zNdbSZ=lQU#t7V6d7TI*Ol%`DP=3Guy zueAX)9;7yja^0fX@e=0NwMv;_uTds;92-eOyNM7vP=yG&FR~#>#WS=|w%tz-tbYl~ zj1xYOkgh&y8*vmCiOCj&W-ab42w`Bs(Y>Vp3Sf|rY2(BQDVKzs7mGXU__K1g#pc8xm;w9z>I68yC=90sZ9#Sujugy(*ays;JYTdUlokMHYBOW3Ugiy6#94LYu1v z2BpL@ZtKw=OmYM45C|q~mM*oLL8vYJQd%Pb4m!1~nZ%nmrFN;b23`ryLIX1(M-BPM zuF115xbmv77jciEctR_xTTZh>H1RO!kN4dM%RSPWF*HMa(&Ej0Wq(`6ca4+{2s=eX zVDxGq$#@UTT`Hf5LJ@89&Ut4u`&l60*hI^f42CXKV}^}J3(Aa^mvW&>g37ptSna@j zOnh%Bs;_lc1nG|)Yyd-|W8D+#1;eN2D0$==q`+iqL4KQE@#^Ny_Pz$A1PzrFyt1 zwq}z&vC1Byz55IIC-)XRA+<3QoW2wY|^1E8Q^rG7)EuV z%MoN-_G1@=Qm2~V(OM*5zYY zREx5q+kTGD$1Go-^djBT<_kg_fByPqc>5iXzmQmWdY~l99sz9a zz?;?Zhw_oVvm*%KaX1A$!PO2INF3_~3(!MLL2lrhjL@v;OkHxDoo~O%T{*+$*UArN zno&Cj2!7eqt!c4#$IDVPu$R?gV(18B&$2ldHdm{KkdF9qrouWx1yxSRq6VciUcF=T z`%WF5hs40Uq{C+5LX+C1Q;;|V+k`RaQon>Lc`q&_D^yN|Ds6ICACJVtt>sbEbc{eN zl*Mw)fxcq}uQ-!LR^_%FYHo?WlQCVpZ^4(wVhKuX?U^DxA=i(heGKocUeTDbx{3#& z8?wph3WQgGus%Q%*5|~H4l>BoLj{j=B>Vxc^>WPvGefIm*uTSHm2EXdagQ&i@9&3L5F9%VavL8NA< z098sBo&D0*Y&Ew~K@hgy-qJN|%` zP)fD-uTbT4$O23`|jMsHS$_mg7ixk{mI8V7DSMN)nq3 z`^yD1kEkxWNWj?UG{<&>x&ZlRswZlP0d%xEY*(KF#Bn2dM>g>R$!f=88R8zCRWU(r zYiLGpjfa~L!_L!%Z+|_4)bHMYr5KH8`QzWXSg{HGTi5LuuRle|k{^eKz;hq(zrX%U z>1;m&ZvRJy_U&ovO%?)B?+5@L8Jf{kd+j zaE667DU8giZ9621>+xnrQtP;C2hV~UB);nC8;`nSyM|WLZ`ea@>(IH^4CWe^eu2@J z>w%yzWKHDd9yXBA#?=|0NSn}tO%(b^SuJZpvK*T+p|G1FH^-_kE#L%GcWjZpy`qr= z)KiCeMNx;xo#1{fM!7!=WhvqRnOvp|1pGO6CH!qD@-x>JoWD5p0zass2L8JZS{YL4 z$#zLpqHOv%2T?#TB^wXRYfOTw5yb1}jO+JxayC-jCfiwG;u__+gJ3 z4_LY>8d#@rq#hNSRchS^6Y}m6ww1kCH5(lw)UCjgaOT4Rb8%A-8=^CF2kIpb*fVlu zMCuFG;U`QhsxWWa!1IcG9rSnW^>n>s)aJ;1Ele$@UXdd?K#*GdD$ju~2Add=``5vd zMNsUQ78O_ZsJ5^uwXGIUh&aF?oq*o$oZHr_5=tTkEDQtfW!z{c&N>;p=NS~6j4s;W z0&GgOV1x^Nh67p*18tJ?7s(pcmceKJaF|hol10B6!#hSo3`Z?2Vxb%2Kimne1Y!F! zemGm2tej*p1h9T@{Wa$ya?jW&Wryi{T$<-u^o z8uhrhvb(H`|B?w11p-2}JfdD?fv0TpS+bolBP>C%kPHD~*DJU%luvW2Ze5>G^y|br zE$fS+{3>k&E6{!#q2GvR`e-Qs*`+cH;G%%)M}A@Ij`B|c$y2{%IzqlEfg2(-E~+&* zNE-iyQCO>EFGk5q6~EvkAfY-(H%!Ksc6KFZ@C2|qYr4hA>1N?0xCJ%TxYTHl0W-`> z^j4mCn2v1;mFz&%(_TJr`wK8bgOfp(We|zHkX;Baq3D_B4dL(p;UB_3{QVIZzj^z0 zFjH~LhA`Tx=w4?%&U-w%1&{-=t@PG?C~Jd~mRiS1l5e$Zhe9GED^$@ke1qbLGn-d9 z*O7EBcjbs&pcF?1ZAe^Ff2uoWmKXU{ej?9U+zb$l`QeswnDvE%qeH(5%k#Uj3Rkcm{AW0$=e7KwGTn&OMK4VHM_ zR1(t88kQefzW-2Xl*KH+agb0wOw0;qfNw`ev)f4DmDp#XbqyGiWp$1J#b5+PBp6k)r!z2XiS{qD+zl&yV7vS`1hYizG6*S=> zZtTt-NU0WRSAfiVZGT=jn$F=Vn~5EPjj=@EDy^RKf(>Fv-MB~~Zc-%?VQ0j3PBs?e zWTACzmZJu{J{x9&mdz+zJ5uHn5tI6!Md?<#y0PIbLcDb!5V9pb4Mg5Iu=Qhs0ui-S zr)9H6;kB0VK1{?=Y?xU^22H57`7xEE0Pao{%tE)&1g^j}^eRrt(#^JelnmPlS*&i7 z$Eza_0gfl##AA63An#=!qjj%X3xiDViY!s+q?Cfz{fuhtE}vShlpIQ~)zq1(10UFG zhcU=JQBD;o{e>G*m70U*EQQyoRyJg^L6%NRAP6Q)`O{$5H+mBf;*ns6$gXu?6uy6t z502L6;ItbFtJov*aW`W)wGA6BI??)^CH9_WFP-C=y-&z8P=qpOhHfFLI$8ogQ!O(0 zVWD|LINV6%4*yR z(RU)D&Yf9Hf~Z}^MJ1)J7?jOofS5T8e5enw5Al8bFMQvE*E4wjZ^QRbR4bwXTX+Uz zc$9nn>FbaAHSi#R_tV!ugx8;-8vJ8;{mb*;`{CG2x@On>MJDVBsGZyU$}u6V$mLB7o>uBk=RDd?ee z#n+)$JR0qELent#NpyGXvjMz|TkQkGRx%Cp2%0fvt-xNlIA^R~0fC&1&8DC^z#tE; z$s6+GSU_eHLXlJQs?~A8*BJsaTC;XbHb%Vxy<*7`l-^$~j9%~}7*w&nsmLgYdxJbW zE&?Yt`Dj?5cAuczkxuOv?==*4Tr{(ljXhg|SlI0SwL?4)Ye?33_!#P( zK#g*o&>0Opoi|1=)3f6i_%}qpV27y-Uw{^Ce~M?|SLM1*5vvWO0}hK6$$*{eThqbcy?yS16^&O5y%aM! zF65v3=vTnuBzI=q}v*D0FgkYd(3KaUIT#wv~V$UiYs0r2bzF{#YD zC9=ng$*xoX`W`g5w#bT^bET5bngKIbj^HxbF?zeZyx7|jN3YvZ7`kQ$>=LT`XY1nk z=@y>mK)rm>J`|N@0T64wo-o&$quTT+?qRp)Z-Qr2>2~L?w*@`_TZhoPwz8`-Gr1xT z(9_^*!as^4wb*k7XlCG@yW+;JJVxu0-|)%dRr2PVM?KAfFPj7Nq!_Gy;GC;lh^Qqx z=yYTIv_h48U@-kZPs{@8{2GZIX;-hMuVZ6xy&W^Bv9U;gF_qDkUG-D z^EQ^>F$G8ew{oU9=quow^ar0@>GmIr;GVmJ_LfRB#*WrUhJ|Q{B z9`EeG3PDP@Ups}up#yUI9#diUdn7&K$;JTqNcXWVHU+~u+z0Am28S<@`AHz1tISEO zRWq!p)tY>z#4ai^)t9#NH5(%XiM^10-gaZ9N)jcJcCa?DoJ?IvPFYVhOHlgYlfAa& z3zm4p!5lam$r}JYMIXX`1op3(=1Pbi6ogad`|=+{mQwkTdiK5Vg}?v75l8>W+rLw~ zzJ2!kX|RKD@>liB3vh4!m$zSsPX5daE|0vc?eU$IUHP-!75%fEUP`rYl+14@K=z)V zbk^@uJv`_Ir0@eN^zW_p?C)W-K0dg^JBm*YppuCXZgvG0!D*HM0{+Mm47&VByp&Ku z%nclTPpjgckHGhCL-%yUU{$8)19DfTZbFw*ciQVre= z)T5iu5D}Kp#d-1$9Q7AFu1DU2fqo!8WP?Uz3>e8)safbWHl$r`Ai-Lw1GP_PbaKL2 zl*c(dk({)k3@_`qb_!nY(@DEVt`wwd;Ozb97n&`eA(~|gms)yBJjHm^)sg!eQ$7U_ zava%*xs=jym&cKNcoZv2}|8d;-wmk4{jYP8Mn?Z zC8o6fQ{%M+oKk|v;}B0OlWzL6-O>VD*|PkLdBdE$n5j#QIfQ*Qg^r|AImu&t#mo)U zy>4Xp5$F;d=qb2A>GW-u_ue>(OtzU0nGlnhI7^&&)ev+h2(W}oc0L@p2?^n(wl|1& z+{b;|@$LHON#gMfUj5?j7rE8=3H(bx5PkeKy#AO_luurNA6`F!V)9SJ+fUVW##PDX zb4sQKa!+cxM*0^dcMcCy%w1RSBR;|bSHD3zgL?$v*S69CYIoNfsWKPFYWY~Kc2(oV zrP*AJcdI1u<-K{Xi|q2mQ-w%BkqlSW)pqEvEJIkIF779D4wcEYtwc+&TH~_eh<`m& zOk{xs;!Q(pgaSWzXbi1}?6KoF15|5Rz9AH>@KJ<7GMazEVvsV;RzNEyksd60S)g*@ zJHKoN!@w3M!0j$f(y4AM>zZtVjn=*^E=fq6RIA^oeQ?Jk^*gGWqU8m1jou;J-yGzf zH_-2iU2a zRHzR1PN)t33Hzmm8L1Rl^&}O-(WzdM6y-9q;62}9@L@aD8PJrJ-{Lu`b>Uf=c4wQ? zSwAx$k4H`^)l70?IQmKwC3`7eR+qy9`P<7IpaZE}fPUIU4$p)BAv=OC_JP1_Sa)o2n>ZXjA)Wn%?WSS^YBT@ZHH4wAUvB>QN zB1J$|H{8E&!VGq3?X{rXSeTp8?ZEqVl^=PaZAPy>Mdfynw26x93T4}xgq4}@i)dV; zu7O)2e-UOr>?ylZe{P1=ujke-+Z^Fyz4iRdGv~ayk zB+DY!s!YvI5-G3ASwJ+>_3I#w3bUCuQ&HVT1~Xy|W=Ijhilj^kl-24d%}IHYFmWoS z2w9HTC{O3zv5^Qd78&jtWU`^PbHEoQj6s)mR_RDIi<8rxw{?WJXh;Inm& zgK7|kd={r>JWm_w(l}gifusF(@v{-H{OEx%)pLxNP;=AV(OzqmG%N92P-TN60rMs) zS9ZpwNNK<+!SN&aGN(>0R9vk|cC8%U>}-_C*eS^=hZJP{_KwhFyQsaf$v~4JYU-!KADU}t;^TqdG)Rctvkfunc%rf>^2ift9H9m=u%y(5Yt*Q0SrW!o1^$qP>#N=Z;bm_s4P4{SQ|3m(riOV7&lAFk|nW*1FUADp-vDj(W%D=D%e$&HHMm~X(T>{nnTO$-ab)9`rs<_4UjS`S)FtPBOkIGT{$ z)KjAVq48YI8iq^iDZ-7UaP9n+JB);hl~&oj0&EFHIApbg-lV=DD;NaNaCk|3OlCtBM2EQy51i)5m1gbjKPx?~5_dZvmOgg>H7 zX;p#tdT}VQOC9u$*g>B!ouEL6p;QC1H=|GmEYsm{6E2eCvmH$A2eq?)eq8mQz-xj%dT8HGRoVz807Z~k4;53Tj&XaARc`pdVk!mD|Z{sN@9uipOx z5%CYI1peznLr!s{LSpf8h0uRezv)~!V(d0 z?-mJ3^p-6&?2+X3xjUbI*&<=v3WiE$Dbd3XH(_>htm<$!K>|He zKSXNI5|wJ$CU=pV(!EmUuxGvHr2Xi)SvwFh(vTtNehW3B01!*AbP_qm>kV8fYLOU~ zGLf*C&ju`slhh+}$6J?~8281uZ?F*LX@}sOox8sDs7a^<(}o10VS~pd>3kAUt#HQP z_)d`^T~)Ch4nu_GAGBu0bDvPNV6mdz+?4;CnW11OA zQ|3o)lB_{ODDwo6@4y_}A#zfOjoQQV^kU=1V9G=$H(4ScKRf8D0ioL#7h?o$I`+(u zkisG#G<%ux`B|j};C7^TRs90+xam%feLP$->tR;(MYuvMnw)~3udmwWX&kNjSD~;_ z|HDQ7;3V5y5m6~XY$78o8MakD^#@O=l4ni=u=Qr_5{AP$;wcAOa*3IRBh1-u`X~M8 zVNzMEYXte(lCVd~K$d+#gM$n@_(O+c?9r+BLj~9DINW{mBOkcxjzHl%U&1DFj}_4uF6<(UGZkJf1;(<;eV5D_)IwE@C26Q*K-Z) zmvC3og)0NA{)-~-WsO3xwMcun(0Nm}YNhT6)!FV21e}1*EIWrAC}j(+&KAf5(Htfpz7oXb35%+sx^Vt;ti1GWHa z=3r-#nCuLvF|=Wl7$9Z7?2c3nmN5Il*auqgtMjqsreyzG0_iI-NjF+$4z6S@VF27` z>s$AVWXXpLW+1FZjj{%3c=S+ubR{Jn(BR(j*2#P2V=Q|TD3?yVy>1v?T%ieRw6_EW zx|+w5X{d^p1VAh4fa{7K!P{4ag=&AssDgg(yO7j*?I4NUxpyx4CAGxCO6Ftuy-xd3 zoMQtSbB$Eak8nq;I)eO_G7$m)Z}4X9DoWLr1IKQFI3_x7j;h8TdRp+xu=C;)T3}Mx zNi70-u|sH4KC@1JXs#r^Ayds!E0e5putMfy6`ec|Qss?-*wu5C{mO#a1XOa6!U_#f z4y2TiKnjEWUaLfv#%&bs?iP00W>z}?u)bY1Y^8Or!mjzt4 z7yU7hKYsn0N-n;*;2?>Ivl9{T1ofW6_%PNHEfel_b@G|8^}4MVuW zR8@IBSZ~MHu;uA3YZpnF2K+(%(~3+x9)~c;hF+}v9SO?(POU>JI}R5*lLmlea&*Kv zwv?Le>I7-bYDZYH*clqlZoep@U42_=~@TK^LE zDTNnhVQ_lehBz`Zk6z#oZ>k@_4mNu&UnLW;w!w@kXgOfSPVieC+#wxRKg;29u&K&J~s7y%b%8q>3a#6500TctS0xVcm72+wf#Hu12!z3N!2v;y`sACaiO54)+uwt{!ajBH4F ztcGS-c`9q~@nC^Am=_JIG?WBc(F@c<9LeK7K)y~g2ipS&B`FcF4}GjtzpL{3z)-6# zOgljrHb*uX6pY@*y`pHgnA&B%3W{b zELK`jX%rAr$4$bU`YqLt{D&nW{JCa}m#8N_ z5Ve~sSM{+SyCa}s^B5S&RH({lU7HI!m5>a9;^PKi^8z=s@vi4lVia-@;Z$US4NU7B z@d!mrbtEa^N8FAN?oc6*llCB;N9_Y0Nos+5wfs;C*GU3Ve?0h6MZN5}amO`9xsMl6 zq~#%DQ}Gji4d1@N*5N1o`rJbN;_Vmz-q-N|_XBJ~eoeUF*MN)sOhQ^#`Ty~g%KxDz z{Bbay5_EA(laJjo@W?yT)A2YWFs^HMr z-5s+IQ7oUG0RsZaM|M+_PtwFLAr5%}0Bdb)$A&2}D*4eV+0fOzcfA8O&gR#F4$Qc! zvD%XWJf=FZ@S%gxG^c7Sfi#sHlqMgjf)S=8{hnj2sjK0jv$!_aR3kY=mxWYp9UZUQ z@EfpMI&LGN#VZF;;4~hXa)rW~Z&JbwSc>+l#%q#5`XJbDRLi9KgbXdd(;-=@Wi4UJ z2o&q4q%R$RcXBA(JFPNQheXm}%9;)Gl+G~uEU!@tpzKhPg92W~kB_K8@}_L~Agauq z4_WWNTL1wY(+YUZ;36XOxI^!u};#{=@4H8Yq;z=9Z@Jm&0|p4@?ndoEADV9pCv$e)FnOu&cHeBu{C=b%zPm$UrKqBL%>7s&J{R{Yor=ue1v*(w@pCh zw>}De38|c6xgpF;RG;cUP@)Qf!43nT}4g8O9ABQJcHqvXEsFkVYB_-_5?aDcHHRPoL zLqNR0(7wPn043p8m4v-uSfrdsd$Q9m+yU!r9B2UbF8Yg=N`@qQ0x;ZN>z51Ddknd< zi}FdO(|ZGio(ka%axQm8)Afyre_#mEh}?|s?`Uys?W8Oa2gy2hpx-7kzZCt z1uJ___kAV1x zl|0M#Y%C4fL=RMAA<1PVDP^r;WOyg)XstP>UZFWhD5H*P2u)aX1@6qwHKHpM&6qR7 zQ&|Nq;AQRoz7o~e;!u8-n9WpR)>v{h!_A6AyIGCf-FI-Aphb}?52#R{7~DT;!H$zV zWDJ~fo}O%j0X%6tE1}@_4kL5M&Kp~Ny+Yzn^Hw0)le&pg`iYJsbAqMpx}4??4(!Pr zdq60%0xN?t2(prWSYJGD0%cEu^9kza5=XBb`b9V^$X4viRWbE>DmooGY&xFZm-QMc zH=SbYWeG|Iv_hbZ1K<&5n`|3{RI0+7Y+&OYr&XIUD*>PGNz-MUh-9OY2D*t|{`-w;rc=#Je#rlgL&@~4OsF$tSwSHK z^Obk+tfU1vAKK6iia-SgTF-!_ZYT6hIaI6X`S`txmo0f*6mtYv5-Yi*w&59N_|N6b zdZ%@nWa9K2#Y1BHqzJusG_IC^)@L;lt|_VfBxq7~lX6Jbr>quq4}fmZe5@)7b#gy| zDI0hNc?hdf)Eri8j^22Lq9-slX>&kGRIj<6!50a3?N$Q7(qC(WvA_=QBb$m@e`g_* zw1CRXe5i64#gis-qmCQ2les|8HXjG$ki@M(i|hkc%y@0(pUb1PSly_kQM7J_`U64^ zfBo&RM~wU`JhR8XeES2ZSk4do0|1SmzWv$eS}@|;iKE;Dtwc)z^gbhlhKM(6Dj~fO$A1HyE zk7ppFQSmDywKC*`bw8UIJqyXN=}f2Vnu4Q1RDr2DP5T|qyzlB55NgPAKSq@ zlN-&6tWLnL5%iJuk-S`#kJ~4Ps3c*^;_8mG>$&PX%YR9w@)}50Ee%@i)a8JKt1>i* zH+cz)JmBeCwr7=AzHz_o6)W%50xe&9s1@6{1OL*~-$5fkN*UTF0NY4Z>mkZW=!yIy zLLgrtt&}(bzNBzTO9$~t?37;eBMU}r%<*|MHe?rDz?eG8v#>`JfFfKZ}ld_dtq(^?o-P2&fXSG_|R{JBekOe(z45F4@rs zO%L=oo4}}^zx+N9uH*F%)rW;8EyzcKC=g(VAp8%~+bQaNq)MZp^R+;Nuey22AzYssA4Pm^K!q(DU8k=t5HIIpce;Yw36gHG!p_Lv1$^ZP>ZS9uthq# zsTQEXT{=4!9s=r4kIruN7LPO=(m14z0|v6#bV~KiXFzPqmTd!{x!o$Ly^IVa5Ve{O z^Um?r{jiirM0kQMK)c8GKZvT0C+zK# zcf)4T2kf~ODPq7z$}Zcj+UR1FP*ChZbwQP+iMA#>5P5YwS1Z`&GP?2_Tt0@r0D<>l#NF|L*|>3*jPcOhJkhL zt(&+}lI|=If!v@|M)#o6wvsajx}KYkoYTt=!NGij!KIX0vh=CUD4SrjfoOmg#;ySH zx~LU)2?f)3s$Zgai4}ktaQpr4*BHJM9$P~j(tfl|vdXx*RS6F*n~fWMz}1zlz9x?3 zP>pXRA&L=#3O;;m)glvsFzS|K8rqE?APeQ`k}|b-%LA`CB`t$p;$|nH0Je5)mqM)+sb>5fJuD0tJX!b_%zN|&~do#gr}T|H5`bWZ$~hkvA1C_FmR!lE`rsJ&3BUWbl%)U1>HWX{ z^@rj8zrOzF^azDEQdO^4O9TtLea73#QE>j`z3rwcsmqBi^t%q{?XKMGt{qj8s^;Vp zJ&XdLknpR~Yq!m!X&z7>qj_ZeQh(e|+w&)*Jh#OeS~?+Nk5vf{M7h*T%6Hr(CnvJY zr0p8K%wK_>Thla$$qK{`I)EsTfmfdqQWxR?l;<5;lP_6^Pz~V1B+2$Ngxx}|+&IZz z>FlmfP?9ViHk(V0$r$v9c>!!w^#9r3Rhf;hl&B2?m1+9J>1Np=*uZ2Rrrl%Gp5GB8 zG*nBP;lssS)QJgC!!0goh(f0dQWeYsr+8RrKuIL_nm6BZ0wY<}r54)dmQt*^thXs) zix_GJbx0lQbrw3Uk^`)IAbB->SiI{RTVzzDLlj0-5rm^aNeO}>l2)K{QYsqD$pO;j z6#)To6Q|9c>i2scSGkwN5G!QI*o0M*n39U1rZ(PEyDC=HYAd)|HK*&yZirI47c)D) zD%PQ+GNS4=)92!f8Pt#-G@;Y^drl=>_i?`Y07Y#R@q;l@&^3V|eaM_kuQUvLl&I`F_!TfkOW z=k9H27ZyneV;Y2mqGRt%Dktr+co$19)a4dvxjiV93#59~pU+2jw&k`%|eZO zbyY9kTyUN9Ektvch@YF5ceJS3AgIP*IB(}Ou`QC9?E%R)=ao@K2`P^P5jH&4y_?3# zvzsyUv};XrY&5~?}9#86SvkcXWB2Yyal88>?C;P#8dB476^F( zr8E-9bGXH_qZ(EzR4sXdJeNf98tiUh1O}45fnM4Uo&c&+NZE!*Vdrc92v)N4#@baG z#t0=0^yYGSR6?=bvk_GAHBsyl{1q$9C3J04W8)KXEtR@+i7l`X+71rm5jFS*=BY>L zTE#=-QIlW0YAJl0FRQjP%C{8h!P_R#KL!+|SCLo>eAV!7XEbQJouO?(&vGc}xaWY}pe**}&4(HeR7m^1LGTyGMf)Li#IG4@Is`J`Nq$SoPnmUZ%2 zpO4{?bVKyUzMM|7^N=~AX(8vCsxY<9)&eUa1T(5>jCE*l#tbRu-Cu5zdZ4+i&x;mL z>uP=l)O1`txm&6yGGifSeHq?uZ1{rY<(5BjMzod>j%ZtSyY3Eej`Jw*ev#dz=nwHs zS;YOW;94mHVDeC#hE42uFe0m33gPRAetfZ&(!wxE<=Pp}E6S3$ZTkIB-aZL$-{9-V z5-jCRf~ow8!6;5LhzL-A>uc<8hkS?dEjx1e=H=@^~=R#MmjnPKge z%&nMrJ%D_~iXdaZ5t#3KdbmM3aQrm(DccWd_IKHY0Y~F-QEKrUMh>i8vz8#OJ5>Y* zvdMM4;zh@+_ne`@!!S*P*CIhoTPf{<7`iGleEDF|2PnwZ2ca0XojFombfjRMQQb@{hxUDf57vWK5^i}S!G42VrFQctzD)S1L&DO0T}kVUbBV_E zq81AUZ{Y|9PQyTgKq^61-sEKSu|a)4F>f4Q?t197&yP@hV{C;5Ogf-iLtMHegdxJl z5e4xrc791#1_W0&b>3NOM9~l*KB62ZS8s#648;boX?z4i8u1xG)4O?BBR#f}gd)*F`>nz5*ZKg{hI88tFq9V1~|667x)05!gzS zKuH+fEjmE-kmeo`%|sq*Cs5rhT>1=HKK86-TaGt*Sn2rLU>!GG@3Q`=g{bVH&>h$* zD^3>WKMwkBIsp%(y0x4_0=47~2MGcBmFRWl%A?}0w2R$A-UUJKe#mZ0 zv{PcwsE+9#qe@w^vNzLEsMyNZy%P$o6iJx}E8Eozdv!pWGKz8+Ssv{=eQ35-xDvU9 zjjl$<$$wJ{=L-*%IOG^22t`=FU&!5wPqSvY`JldCwO6><1F0iH^5*9mCLdS{7~0yk zDllpR*e<^UPf$(94jOYaC@%?=<)Ln=)CuBapKBlILN0+K#&|>}r$--80(M7I4dioe z)GO;akuZ6NW)~`R`6C=T^WTT>$$vR~=W_e=@2IfpFNX)B0JTbnf4NAOI5XJkW@$Y z+L`xgoe+U5&qQ-n#S*d3es+Df?Ov|(N{(_85^1wh3zjZhLbaWrV>`FwQENDt*pZaE zp>Qkskwxa|yNC0Nm@hA;cpa5DmVkdV<9o zM$aawmgQdE170?N3k2Z!J&)tZjJr3TG&7bB4w^(M{LVdfd^CZH|W?7t3rG1wT~k0040uYt>X}sjXe( zO%O78fuh*);B;uO;!(7O3fP=xeDcoew0|z)TC$^4r`8WSYd~qszB@KS`BK(_Sbsb_ zY|AS-lhbzyq}#*PVgW0(xI8rpGKliNM}n7NB2{ysE_tglaDZ~N1=}=~kdqA^^fu_+ zk3RQ?#B5z>P%*v(A)eGXDxP~lUC#FEfG933z^FvGthtjCZLGr9Q4a39W)|`zAmV6y z&1gB2SgEy;B^n^#tgQw;EyWvT6Huzp;dn=np_~BqQlYZUR?wMU2#hAAYJN} zb;_Enl*nT(c0l5woei_@i4Rc$>3G1M7_w1MEO({oTo2qvp;2}5Bn9PinlzP}*TXRv z5T!Hb#y9&%i@33AQK*zuPa<6bwSZBLf51@PB$Cef{F@_A%f4mf<^gpOWZ}>iC}tg^ zSYXBDGNZrda4Q%e(?AFxDZHnnZmqNW@<9Np&M^^&p^`&(CFPf(Twn!PmYVxcMY$th z|319_#LvFV68G&7uU~+cs=@=m4X>Y`w5|QG;q`YpfD@U7p5Z$l!i4}t#l?d76=KRa zpb+x=dXc@woki8{ZzKjwo(uzONt$Tx6}6-&PyEuN#;TCw(|bhgT)%j>i%L5|0=!Ny zsvI}a7g0f|mNF>a!J&>T0C7@-OXi*fOF)-?QKT)MOy&*OawkRW15ft z5PIe$C@hfA)>+eVkj55yLLph)xoJEqc37|a{2jw>xYKXFTeQuZy`8iSs8_)c{Pi4 zi3J5CHjJBMUnC0U$y!?|pipH&t z8;ThP;ohg0eB+MlUkZku?3chIxL8pA z92`{DbtLdXBFBBS>d-Fa?vCsu7!X^i!*Gz*ZoFOrTC)wLxY&wExhrd|rc4~{3_Q*O z-2;sksaK_x`8I4L&PXcjO72Q_zDtW_gtq$RQQbjMkgWOYx^VCawP2S`KFF@j~oL}+~b?)IVW(l?ZI%T&|1-=5xo65hW0K+^5&{1ZP4Z(pDQ{UpdAKRG=h z4IK-FD1GG?uPWES2FsLi?v{4+}PHVY+iZe z9O{CqCwuzY8%+@L?$F>|)17tWJ`^CHS&-O9kYD5rXFzI$I27rms0qoV5WH%|vC0wD z?ZHT}us3XU^jcI2jDV(2YA%aXNi+JY4P= zguyN5fPYHyXk~4}&9|}BD|#&WKyfJN)stTw_%qNJMD26G-kCo2DtiN|L#q}gz99de zIj_DZ6*@8Ys12y$44v46p2HZM*7b)bNbXXpH7cP!2f;MxCRabXB3^3DvZE4U5G|o2 zX9XdY0-u~fTG{4X7*MvV&JV!@#>E}^ge9IWVC1{cQL{f&6@4wXYH4&>HHBycTnrmr zIakhrw2)7ucf$_=x2Y7TF|;D$BkMpY_RHdEuLdLb-A+D7{+d>8Qwh)3fJY{Qd0W$bp#YMTkMtKv=eXwVk#i`sTtfR-n>qwNRS zK21980P+PlF19YU5(~%8*!AVPG<;o2qMK;UHoK}hPL&1@5?<0buZrn|%Q0;%bh-f(jCLqa$Bx=WxAK_Xyy14aLsmijQ z*esUS3A^>Nt6F<-r0n864=kg*XFjobCvTNJz8^UK^$UyBZ-06F?He%5I5@rkg(=y6 zN}r592AkKuP*W6!1`5i&%f5WJuqx>mJ9Rghj_K?+c{f0UWv%)unAKjTo>Tpy!>sU- z(MP<}-@djphYf6aRJDL?q8?)eRjju-Y%V+5Q|Y85mb`=d0JiR7;vUYMD=H1zm{Ruw zi0AF}6A6zAAU%1RB*is{2dOU{9l6$Mf-&gQrn6qNmd(Rr1HaVuI^AzY)Q7!CCUO1u3BLzI}mT zkDvbP^~-04*Duw0{qwg^-u|MDn?Hs3pTB-kLcPlCHliz(o0B>L*P~jBI&-$kZnODp-Kc0U z5mM@ryP1<>_+ki37$V6^gg9VT+w5TgT(7u56 zJp7TbBd7+vU1&BhG-|if5dJ5NN|Vnl_%_$YzF<|_{kQ-PvGTYII{{0D?C3dAcQb&O zp3!w9&|H-l zoERDrd9Big96dR*^5LW6=^R>BC9npdhXzOzOx0IXcdGgpT-g_3+;X#phWX$MNV>%; zba5n~aj#RzRaXb3w~ekYMCujlr_Dh}D5)C#(>X*KJ>!%ORG$_UJ%n|4#muTrj!GpU zkz1dDaSEVihxLPgZN&UK0Aj=Q@FHQbIzyu-@8=lsa7;LE1tis_0%#q=gDl>5kqG%r z0(DWTvG}S674^0hA2b?C=Z%Sav=#sE2U3^){eL*(*B@R#rsUAGlI`m!-!ixV#p`dw z+s|QM|MpWdN&i#+7WBtIRa(qXpCrj&e|&muPA1z^6Yl|CwjDyE%-&!`pa(CZa1?JX zN&dXi1@m67PgoO)d=m&-oc`M1UsD2J)>_&XgBs-RVEiBKNtbzYmoG2leMd9qB}!{lX#+X{Qw&d z0*$#%O>TJr|G+vV`@2pwI92I!x_J>&fkUw;)=w=6saJO>5zSw*%DlJdKWRhXD(_dcG? z+)}X0|9PD((<$lt7w&^3IHCA$b~;k`~0 zpIfMJNLk-N8P2OENba%kiinm5ic-|U0W*D7CWzx>9FZ@zYVDi@&?dLiVi8(~4GAit zk$O*?kVi}Atjb(LN^U2PL3w%`IQo+}crnz=yG^~eR<7E*R7F);Xa|N!Dig!>;zO!7 z70w_Fyi(QUeAw#TOcpu;x9S&A9~SI-B_xz}m)czwwJ&ckuAF5hFSV0NKj7giRc&-k zjpUUO7g;!%M0MoG9^e`U|51nxt#YrpuV$(#3rYOvTCb`h4* zD#{8J%ClhO6B6yvG;|cN{Mt$Oq?H|SbWOW6BPdjUWi!7?NZ+i=fxchat~%T7#&;X2 zF#5`v#1;w7)oVvoQ1T8i#Dx}GBdcGwl&Y!>fgtVxwjx3!a2vg5Ef6%+D=ASYHtJZ{ zJEwDfNA)xFwn|vhM$rb0BFA;A}_^`*`{nB%jqA(KmMbBpAa2J-mfWtn_WMC zM-O5fcYgl%OPCpd{`RNWFW_tSZ#wi;nfU*2mH6=fr?0<*zy!P}Kl-2l%%+q%+&^UZ zEzvTsPy2RLN=qEC&|fs$@Ewc8LbxnmL*Qz``sA*rMe8Duyo*HO7a5baO_-1FCZ(2j zWo4DyU&ZROtq{Z|t5}1H32vc%XYqE_Q6mt&OPjq*)+{(?0k~%JzN$XtT`4;6HXY#S z>!52?$$J0mh^n+xrd9;;srRO^!c-5h%&NoaRGFA8U$2l!wNT!|c06k6;gey9W2y#}@SyMi;3JF0U+*Y~twmI^F zjAnNoM6@G~BnTy9P~7*bprr%{HS-D;vd#YeOS1Iz(haQL zF9k+s#4}ywWjsEhaa|%@AwXS)VuoXc>V_2tptQl&=po9BF@YNH0wOs)^@VAwHLs7O z-~#+{1s1xj%^B7-1QUTIZKivkTJS%Z9LPug;>kg?qso0K*@^Q})fWrAJB`$IGewuQ z0$#nAY9jFZ>@9=vx+eYmRxhizq~#HSl|_jJJM)ji|CZ9AutRACTQrg$i8MlBwzsP%8i6?~Yjf4dt4?d42Mj{6m1XOV*qC zg@^99zr6iXJHH6+KY8|W{>c**_a`4}E&Wld?!Wbu@b)oqwi360^!9m<$`At~XC}^- zN*&4rpCu20wLWRLPQf%*AEQ%@cA*4VSevYDzX4<$Z9g-3QAtG21{lNMq12`H3W8=9 zllS)0nq(Pb|4+BBe&*22H$a8~1h?)LUbL&~V6yOahew|Kt=t1aYnh*VVHXLDpJ5zq zvu7`ujAF4U*=ecFUM=L@S=BE?(w->#ypy8ffspNho^ucqC3;(!-wcd~_XFlNuh1Cu z_!bwHfVju2`|-_HE%^|P)EU~~CZKpo>O{aF%bEalq`J_%tj+-KgKc&gGN7EYQJvm} zDL*0;YNZl>)eEilAl(nxcUH`{OOjS>R>|jhstieoCN-UAuJoRs4sPeC==l{+)S5b*cJ#5fZ%{m^+ct}+1Q{%Pw|GK+x25KW=tOH z4y7V{>~Eo^xGEku4OxU=HTa*PO9T3WcgtEbdI+J%4Z-_P_WYCj@2(#DS2Fzjg39FlR_=-UIzK>ZwP2Xdp-V_;l{5mA&vlL}1#a)M zQ#$_Ht&%CYD6~n9j*P>V952xRzl6P6uPoP5Im$pagxlDZAJVZilRRemX54iX2EVu=(bY68wZ{9j(*+Ur{p zmsLU&;LV80GvtY3ujw1&j!&!M@?{Bh-Hl3`s#~0Zky5vi_EdC^MZ+^l-r7m2ZtUGq zcYQxY=cG7mQ=f{E;b-QB?x2f{oa52TFg?Qgl$4qVx~R(lBuR=A2Cz#!CAr2eEug9q z^|Na~DRW3x;DYVyG)ax>G*}%RTUAs};G$NH!7#;i+RFl77ijtl*!Bbj5G40p>k%GfCGJ%-xTU)l%&-p`6{?gBeA^?vSR6y8 zVBjL{!&)pj^2DApwa}s;_&c^$cvImDZ}8(d6|&4MQt>HIt%9aoDk$M@ulBn@+XF7B zJXGod>wRqHaQC~D84yXqr>ebFF(XwYYAu_s!N2CVvT`J#oMZl60`Mu4A4S~wG+BGc``Y925y7|BkV^D>7B585eU71Lp z8k)Ea7_N?>gQwDge^t9E1{KXL0z<0ZB)duqs^oS+q+|dDiNoMUay5y;C~-ZC(Ite@ zo^ohzITkKSRCd|0#omz=Rt+Vf63O5QWGw)PBPtbZk(8=d$u6t+jkxU zDOTl?#EYC=mw*`6aT~(Jt3>8@S4omb{&6bcvS+PlBrsQiXx)BXDNyJec%UnZdRI6T zWgDQO;J#28g*|!gjq$YA?CRxpVV@HMhr4*Ngi6}E9X$cnwpbIx8 z;B`M)G?YrBJ8i1l=e)ReRtE)?iR6XGaAi)q!jbdbQMs_a;S$?}1gJNlI%F%t5z8NG zg#&KTg8nw!Sw-GpX!>zaf7EqFATRp90ysIb@&kJoJ_v-M8Nu9Us* zQZ0WI2&22pK`?oCpo^XPcinpau7cQg(3F z7^VdS>gsUH<+{LwD-rrrP3rDxlOtt#g6EXd!=N zP219K7PK~X*{U*TKge#4BzCxEaY(3;eX>`;~K1K`D_L|CUdowH4J3dTK>|) zirFH(w~us76c@|$)e?YRB}zWQ0j=D~2VglnO~CB4r;NDH0v3&_k(T1fV?9y^=M$fg{RTZ}^m!y8 z1LaD6|64m}O-u&yI1!4s%>a&IhOQ!PHaG z8g87>15eeRw63c98K;0lNSn?>q~Q=~*=2Qi`O1TJT1{DBj@z<+z( zATM#YaEz)-tybla)*f(#E8Kw!t8R8V*Xy@%ZAK_5g28EY>>h?Rz`OPydX)*>c$GfdhwdW1!0bAP`VGU{w!%fZ+B^#od$VwdyU1g#NLE$N5eL{K!)QSb^E;Z<) zunrDO_f7?KeOHJZciOU9zwN3nV)9b3S85@gLuY&Is6jCo%AFun zXu=4tg_gx2xyta|Mwd@Szv844Kyow4`Hz_BNTQhE?i_j{^*Sqh_1&_74jbzqh5z~V zZ^DoDztg`CZ+~)-TYCMLb_QR(e6=6_>hJyDuNSd>*)A zqD|0j3g7(|!~2)v<=eas8K+lc-71Y_pQqkY3PToz4Qxmo;byoiHqN5_pyJgMCoCx3 zv@JNFHp$rXmD*}*B5!56i_y|L1d&+Q%rl@{O}M!1BHD8nks*~>lK%sgmxW&SHlYxO z3IaG4Kco3ZZbzwX`Is%EN@PHwVnZ3Rbm|grxBa3bNcI~VTYq=#mEyKB7rsh1L*@@; zk|HtHpesnKYc+n^^y(37g}Dk930lP7hs-zVM|5mV*Si7=`W;e{ zuxA}7S-4ZToZbULnM~dSdcF-rDA=q3;i=%5Sk5n9IV4VFDA)QN7%-|n`wvhHMb;3^ zWn3FMjHj`b<)b2Gb$Ad7I3NN`8p0;KBxtZdS!Y()N$SM7F2vb_v2kSK&eUY;TVnM~hIYj&IKwF+&+Y73#{EUu{m9+vETe*zG^iD( zSTRB=VHzi>QvhGmp@3Xz@CxlQySng^lUPTuS0wEgwjc7#9i0ukWw{Z6v|v(kMHEX! zaSiJRKt(Zj>aJvGfUTSJ#=&L+T27cfdaH5d#?I53tl zsKIi_$^CgY+gMbBvX0c4ewDV4*AYvUd>sh9vzmBudb}z1K$5ug9EQy0)z-&Bp5xpO zgTuj)r?zw<1W>JzGRAe4vkt&+9gvi$R9;VNCfq}7Sw6^eeJqC=OSM7#kStx$fUFs$ zl2Of8pQ;PQ5G$O^y2b;|S$x&(!v0mGj~}Ef@H2=IFVl3e2aMGhVFv~UAdnd~ zKPJB|U_hWv9$ERQav^8S=JXi#gvqegI$Wl5suI~T^P%nf>SQ?j{zX|sxPxto@G}*V z>-QutWr&ikgd1tXxl>PuT>-UHOr?&`L!pEQ{6q zUkc5}YNU4`=G7ZFDKZgn2PF4~>=D5d zz5F_0sBA}dq^6@1@B4|<({z*VYF)O>VDco6?F zv!Tbl+##D^8&&#PrcURu_61PFTELQHeTtNm0xW99Zso;Vgm)bdR`u_>M*DjfZEU*I zAaa5=c)DOYE{h7mCtRo{BAy3hJ2AXf#PB_ow!mI-Z-`2g4S>r9oe_*w2 zb6efn`Z_?8GwyB;5D8~0ab<|Pv{Vea$P>G*Bmsjf9A|1fw747k(Z#CdL9Z!>Mb{#t zy!X(N-3g~i~k?Ws&p<6IsJ@FbbDECuufMjEJE$ytEA+zuiiUBuiSw6A1DJ&8F| zj+lAi7@oX@s1DlFmFX&zd?o2Xe1=zXj_ zyDMb~v@eoGv*cQ25~#ocu*egX+KP>y19p|paAC!*;Peig+6zYHVjNo46gO39a8Fsh zqgY*1M+%2KI7)Nq@d65z{a7^`IS3Shc!aK`A-3Ej$Gzo8Ne?%)kbojr&0!p{tO}`zLWVMDtki@I z(msckf~yX)@Swc&f>M^iE*aP~j}e3Ndf5^NG0!$<$ic4BLrSZ%5%Qtybn)xa^(|RYXd!OVV{lQ9vxRxy=(C*B_kJ&3SIw5#FOcD*ftP& zp?TD8a+e`UNA5p0uJ}XJ!9NU5ZE$=oM8;jqOTz3lJx*B{(ypr{viD&_#8k+*gEo)5rQA+ za!XE9IRUvvZ(_4}sggw~J*9eX4M_sZG017LOnF;3ta&x?lruzANJ?L*uql!DDP>V*E*$6wO?&l*BjBJ7U0Ur3@a9(9wcyX7uPiCb1J-Z^?#cI95!`A2EN@C4gJ{ij zb(IqG!AL8KDoKX}-TMHLdYD$j<5!nZ(l!Hq6pn6F&+CksvQm|&N^++tiG8<_t#Ixo<6TO6 z$}4A=bJiJl#W1KvVHc_7u_*@L{oHl#i|H4av2swyyLx35oVRWV=PKrURkq1vKL7^; z_J&dAI&2GhA?=6Nfsd$b%#3PQn5dG=jkKaCZM$ERKe)ws(4;CbonUV?>vJeTUzQG5 ztULAzd?v{NX_2dekg8k7gCw*?}$~tzMsL|pC6793U(wWzkKlW{$F|x-#?JQ>!a^}8eZPd-n$>D6R-L0 z%J%!{9m|VZ*+1mJ@X-G(Bug%9D8G9vH_zR0;}CF%3!l0~X0C7!!K1p?ZIimPGGkdc zMOS!7cHV%?M$Ekh3A-d7OATQ8)Y|qvA4sJ*wRKJGqvE(F9a|qtLJmZFK?Gs};_I@j zMs|6weC|AELYb1@J`p8T&wN;Q-=xY1(cCzc7^x8$1Fgx%en=;)8`cSXM;S=2$t6oq zd~6g9NlyyYpjzaDK|uG&VOmwV>_(ACYa&Z&!2N0ASW@#1;3!tNrCQu_QVf}p{MRT_ z6b)?!WwSvmv3?At#yL9x`THj-J!_Mobh~afI$)ALNl`cw;e{xJx_%1%YDV^JnkM@> z>cwVN*YHeXmO;@+z1G^y|NC)4>#0&-iF0Jufm*oY&{!6!N?wE_@w^!O`L&oQx`H7je@ZS>(pO?9mdY zuFhy}#%9Og!KPec^l+x2mHpkYI7JOipgr5oAJWhFObHC8e2> zV7#lF6?!FYr}Jj(_Ezc^nC^*iG(1||qNrTe?7s{++0aNL;Xv;=Ys=uEkycemfi3wd zAJCe{f~osZBHJbvU@qgr3cXjQL!Lq(yD zzo89=<{qnu1deuPc2VlW#qZu)^VInAIW}(`Bza&}DAi*gp0!JcT|m({-T45yKf; zw*shvUH%y|9;|>@Z4f&?E6wLE^j`axrFqwHGe*o`Qr2EJqr=7@2=oLuv(Q$v8!2GOd6Nt0vah}B zbI7|6!J6UP1_2s^tO0ep+nU~oy9p<$U+vIV6;(0;C)%dUdEBU=F-qsvK%z1=Byx7) zskF#D!7ns#%bmNe&wyyb-?k^s;TmTt{i6iiodkZBJJgUH@i~BUI|5p`Q8 zK0u))Zer!r1=XH|8r00lSeY2*>m+elmRZcaEwH9x7m`m;;{;qoLZdloPs-kiGxX2^ z&~k_p;y#OF2*BO? z(DH6M%U#)kd~oy-2B&O{bSVx}grz%0P-NYLc7vS|Uet;eA|Tt*DG4mPwE#Paw(TPQD(E0IhsPYh;QuK#e~OTN2WT~zW)C!m{V ziXIuj3VMLv%t^9*>&QS1uS$ZVvgHI;+SO4>YmYTw!YU)VWP(x}YRnE!`og1ilT4^Y zlRFFt8)cNw6|qZrbG2oA$p&r~PTTIfvq)tx?Anvf`ivn8V zV?}~7cu^6O#aDSYtp#0qvaRLsd7MwPLKM%jI$P$dpykw@1~j<=onfmPnu`Ot zsQq?SDwJ4^IjMW~9nhLmrnmJyo%+V_JawT17iriTGav!?8-UNV2^urfI+NO3)Nbr? zZ6aYz=p-{=zQ}E1)nnWDk3844+9z|6W=?tcad50bt%z(`(8cQ5)RE8EsKW)(E!ua6cKI$+*R*hO*v#3C znju?`A-T}ZhcGN4Sy&#WWjs`#J+nz=FqNls)hj-fW<~d4v~j6GmHKI9vW)G!Q>9H32Rus0*h+;5R+jU!6PD;3D zHjWy1XssUuL21ale>pOM-kf@!0a8#JV3(*+_dV!^Ku=9l#Rm&Yz%f^Jstc9uV#zrp z1*U9ByRRD&>P)hTjX)nPhCT!j3U|0?_&`R{vS@Asw^Y2oZQNAT1a z;pI1Z@3ZfIg8A*IufKf#Bp-S6`sVdF|McIGU-H-dEWCaN?$9s7>o=!oaO~tmpDh{! zq7P|b}(<=Dv*$hL%Y^A>Xmm%t$M_WfW`$A){mw2qo?c z!-od4_x1=uY*iu}BW!AbK#0%A3qr^TMk@|i?J4s!sLN~W2oLtba$Ew99?qeZNUWJj z?mlnMO;Tw$>VU*&NI7x<4c4XUSArmpVGFwf6MCBRuum{ZZBoUq*wpr|;yvWjw~8dv&mV)=-n>Mpz8gMUIVx_k@Ez3G$f>~vYN4b9eRsZeWrLR zv$%??^8wNFqpgt?#%e%n7uSR)(Jp23({&lltxmfuZ!4gM_<1DHs8`O9IU~7_v#fgf zMII3W@JnSwtskpnQrTDowDd(WHYl}g+0T(S=Gkt21 zdNtw7lKFxad4ItV_*2} zSwRK{#*)h5eo9%E45+T;nK_>M*3eo8DAOJD2h1^cKA`zPG(z``m}3Z3T2QJ~(a-`V zz#BwONdkNKQn$RKtxO10iKGcU1l#LI%wi;8cW3%l71?Y@5)`HX#1e2Rz@!;(Q{a5N z7#rMa@`zdN`9vvCktb;#9djYb!8&u_W-;s)Z?da zB0*RddI2pPF& z#UCDE&^p$ZiuN217SsRkUxpw4@Q1qj`pG*eXW8Y(_h0v~`aHaRe5Cq(`tob#>wNg~ zZFv1K3rc^Q3*?V2D9>_zWl^zy!2>fsIWLv5*Peo1_&X}H$Z0OTOlBwebnWiI3J^LV z%{80T36A0QiJIj{l9J8>C7#~MbJ?bVA+T4bc<2|8-S;6lx_!;9P1~NRu_3=&S5*tw zx@w$s>Jg+`Jb+A4*{wQ#;!3@OY)9DYitapp37^{F!5Uoi_SQ{@2>s6epTjc0d<0xi zKG6{d-N^@^$SH#%lPvXwI?FkhGiOzA6Yqn9Pvov*Xio6VH9<`TP+Qj&sYTG%aP(0J zaI1iDRK;c#V6V`>_bVpFU(s4EIyXtD10|#R3S=A7qd1vxNP2H`_S-BA69nzx9Nd~f zvE=&TO zoH2YbwZA@Wczso6aMjO}7?8)mxw~|cYqi7RFHi+jI(*A04e!rBX>7(dFW4Q)C~VSy zb)4)qyG=`U5vUo=TNe4UFwBVFh+3wT)1dJp$rgh(=9le8qL4(J&Ai1djxSr^w;sNc z4&)JsDtzQ25oQvrpSc=Ne^w!HomLzS%@EKvmRQb=cf;S^E#TZ?_^+@Oj%jBMA4f#- zRA~ZkKd;1UHYn9OAILUznFzXuZ3qDA&@^{p<*dGiK6vDm?$9u!OTfaiHf z>Y+wX#5`Au_b&U`uq8bxc&I*?f2eBHAHDn`uuy*g^-Zuy4JV~_w2A72x(2G22}%ev z!n=eomB!3_$S3Bb0o$#;=x8Z*#U=j;I2gJCvee;4=#2ok4XUKmLJK2O_-gAAV(*l; zUsuIU5M~tz2~|KLm$Y!uKtY2f*oYQHLc=nvultpubgRfUWEJUV z&Spt21cRtC#K|tBN^35ZZjdlUrz3d2T7;Apc!S-qs(-jkB9PSbgkAS$bo72aCN*m~ z^w8wMv}fh&@<3#k{1kIkib&8lB?^&ctZH1=H8Z9Mo@y8#p4pGSjdB9XGpg&|?ID$F zk7&=uT!tG*!#6CmL`h3X&-Jhbpou092oh5Vf<`_7YMyHPSV-LootbhwF67$|t~>{f zv=zHq?Au~&I?Nh?l0NwSqJJ?AV9a7610wojnb=SQIc8xI-;NB--Dvtzf($?a74-mn zlynYmm27i%o-Jfhq;@*>Wi6Qy)409}M9}v8_!Od+)_~|^3p;ZAg%I=nwfZjYke_aY zJc$LF4iJ701v{A1FIkNGFdF-oNn8YFkEE>^*gBjgAD^@-|VbqZPX)FSq* zR$Jr6cIA=iwdh_Vy&mxq*;0o@imQP=1B7JkD>W^)wEEmqHyRMHMcsS7Jp`ZE{OHXy zoe1irLtlCXo~7Erl>qD>a+}FmG8tk8Nj0|Vl6JnRYYu2k8h3F3sjy+VWs_8}T5V`o z0f10NsX2+^?&Z44LYJ2B?av%rgY~8fg+hSsAba`cjA56f12CFS^DRqF9LSLw(gNv*eNe#s-$4S+V1Ebc~9ML^nMrN)2 zG9TQ>l?g^%;H5fIb|Ee<5uBNBW5+TJcp8G8;rD%ab?cT~CMbPNt}$~p_(Av~nML2& zRQJ1|<`Dby@BTWxddSX!jbP_unIb!O|3 z6!{6r?u2`DsEAvZNU<@C2f|ctBIby43F?H_bU#+DyJf(V!9i3|gpjO6E;}p>3)2Gt z3m5)N0|PE301-N2d#YKYi#Z?l@N3RnlL?kM>uWFC{nydEMH zMAY<|yO%X1(FIMb4{J4n@MTzGPVG$b$aM*ol7&=EO_BBa9W>8dNHiCk*k8f+ir|y& z5onpbtqb46J-Xm#vDM>(o*W-zx!f=ql#IZ~vQQ_t4fup6 z?{eM>Cckwt;nKCBVUUgMEQp}YYX_|v`xRPJcdIESPuHIExHu3A%Q$7i&yfZwK*!9Z z)Oa_*(qZSNg&g!$&pzWV$&0X$YVZ9zjLJR$5g%TEqO z*8^nbed##dBFR+;Mx>M>A9+ovYf7^flLHN%YG1wnem{BuF8vcE(_cn5 z!SeS&p#AdoSI5@y$3PT+p;KPWZr}dw<*Q)tJ)z{tLF6getX<2~g=VaGU|}rW!OG^L zRN5PvcPK>Vgf-kjrbT4&)b9~+Vxw{0R0?iYQN?5fIP8IdcTz>i1GWfWH8&M{M697J z0&onh-7tEF_=Y5O?HTR6xF65P35qv@;)=z%Rlo+u=q@35Ul^INR3K{Mf>U zlFRLF^XophlY-rk87d@_I#Ru7IZ2i~0~6f)VAQ3A;q+&*;Jt94EEvKm({28eYHZ6N zej`!GS-sigubypUJB`X?;&K5L&j|YqhSOz*pAohoe>CZO#bg*>L*q!k4qP3r6Dz+M z@J`8a?1_d+-_nny)ePf4?rhiQfoMrt;{mx*)y8KFs&`CbCx$o>Y@>06`|)}A>6Oo| z9aS(~b~z464`I6BvXX?3lbrjFBUIG0L_hWDUMQ*3zFE#VtrDQ)Qbudnf}tDR6Ogx= z?~nn;Zlxo4c`Ok|wX4ATE`cCoUcB0wMK4(6B%t}8yk=*jdM7>NZ;F`N$|v7-6l=`l zIC{c@U&-g&3$O&vssTVS#xPBBM*>$MJor)uXz=Rgmz;mto=})cMKY?m&}=qqG8c6H ztkqVDuDK9qU?qloCGAuflvNTb`z({8Ly-JNL(Pn{tgrW6sGil5!&;nZgizx`wYyIU zY8|JY>8aFi&Pr$8=xvm0gZ|J8iRGGF6s;xzZn+Er7Z+B9Q9)T!IvE;?P?kJtn?SyU z-O&wqY@}MmMmZ{}${^?M;Su1wM3=pT)Kod{w>uopB=@^<8u}nN5W(e0k{z>p1T>|T zmODx!%=Dmu1`~f1j144U`qA4@PjCP3_2+N@zt_*h z+rOs<^4|vgegB7q#ovY3-<_T};7{^;^$hXA{Fgt2$NfrVqDX|W@t2(~--p~>65~JtLyXF=s61Cms8BOm(RI`3B zo45c46MYW05wT2weiBp_wGlL)At|N4OY->K#xh#x8x9lC__yILj=84@x?G7ruZjK*B1R1#71R(UTx0rvDvaSNcP*wr1~Qw8R9%VGdxfQ~KXpdE{TM(3`9 zKrIeBKy5F!W>3%>9~ZE{o+!wPwW^Y0m%}qj-_Hkun6avWgBwC~f zYX;rlJ6MRNYdrg1(Z>Zu9H$Qn3bHw3$)kT4peE`NEL3Pf{z7a~3+Kd&07! z)nJ@$XmsS?DJg|BpHw=-i(*-kDViz^UMpog0?|%NMJ2a@9h6Y~I_U_Q&GJ6u$69>e z<^qazkkn8eWVBR`Hzb)ErajIGk}sIYgC6pB4ZLpZA_^>}{nRs)`4VCSbKF@##qQfw z>bh>?j*Z_JDt@3NwCQH0gOd3m?7nsHsQKI*C0JP7{tkYuZMlyAJ+9aGorPG19_1ga zcO@Uzd(&=$o3caIwbu3nHQuE7*|jh>cw#K6V4Aqe<3|^?_3m1*D$Y30dFE<89o4*; z{Q*_bvRp5nullE4Q`tzRRzK*hPzM_|K^$@*ZW--p8@8_Fk(0W-w*igEJ&2P)Qoy3F zjI9D{0$qlzhd?ze)z-1?3I$-x=nlXdd)Lh)3{rA;Z4H@lJGW!o9ZWSO2ZLc! z4zFsl3~pKXn7Q~9@Q5{0`kA1up58?}e^38S_;=9LJ>s{U>V)z$+d z8FKyDx5fx;IdyvTkcb(7l%{3G61-O@JTqsY$0)Ei10K8D7^l=Z04~ z2b+b`+0QE+k>nB^TJZ`B;v^AuF^}@o1<9K)lR!>bDTs*L6V7zTy6X5u$v7o5+FiUA zIEXa+oTQcK?WSsv|z{f2Yu zQNjbGU`04?04n6C3G!WFx7+?zvRz1KF*c9*Tb?XVFUaO7b}X0V0m}nG%$f&{j*>di zTPvwbkQxSb&=l$90L1pG7CFPgv$nzpyCte~&A}y2 zh>-xUqWF!lnZRp_B!6>jZ>b?iXW}nVW771@I@XfwKPc!wq=>a}86;v`79jU+a-iaJ z1#ivBJ4jdXcOGcBk$}!c733L_$2(9};l5+5;2K-I$-oetp$pN=wUM&Pp~D-xa8?8- zsl!3|(FIkRx|dNNtHR!ew2!Js()=iP6I60a$*c{uOo2@cv?+Am-VhJ)9p{jEg{15n zTmgAPlvFJz&j~UzYGI8&#f9m_6mHc$(5&of zLKqorD0>C(DdsDBl{;#(;stPI{ylQhJ5~5uEJcv=d<3S(mBl5E_yxesupdQN4CdZa-|CKFz=vDFUD1>{)H+UorXoXeQdl$ZB#LtbyvM9_n0Qt zxi`Ld=`e4;(Fa(a2P7UVL)HetUHc@#z@jQjfUua<6Wri(=KvyM5@85HdiMSqa?|A8 zpaF%*qjv~#XjdouNCmNrG!M9gBp7g90qd>mplT{Hxk9OVHe{H}ZK#f+{17VON{o(Y zuzS%K+egpPqq1%J{VYE#;DRKrhL*EdON>NPQ57CeNukuaa#r^Xz!{_KErEDq^StjR zC({^I=0eyIi1Dg&4HnrK z(8}Z0m%FGMOcw2Rl9g|OABX>4U;o$eum86_lz;vD2fhYw?C<_sV!yqH?;rRlij=NE zi5~sWz(rO{G82MtUw@JR4ac4QFTdu^%SR!<{OCvfu{Ur3pYZyAP9`LuLR$z6Xg;@~ z@aA*$6sGQUmpcgtoi3rJB`k`OydOFfAGo0o#B5uqNKvZy^>*5p5q((F!J+mcHz_TR zufRKAmwRLcT{n;{;i&2HYn3u!4X$R7NiQkI@|9My0FDQO#*V5k9AXXFbeT*$dD$+z zzyd1xSqclnq%XMpNIPy1{A3*gYV*quWCbIR*%ff?b9VT*=WXCxq4$^fdPy?!7KkAY zPl9A3D|De$DlQ+v%s-ygaMmE+X+-?76D_Gj5!$Oa^uwdo4ggBWX3Wid&*B#hQ!98# z_AM207HCVuM1zR6-9b#Eh`L)GxJo*|F_xpz= z9uU@29pFxKj?KK|`!O3Y*a^iFOM~*hozaXn@*gxr(2aJ#Oq|5k^=Of@l;g5NyK9yk zFtO*Jq|V&kV|z(F+0IWmz5|HhaEhE2*jMQ=-H*ij(6gmY|bXv1y;%dKnSqTa;~ z_z8(So0~4m&5q(W@2C;Q4An}_o2)MY;Ho45#$xUQ+XZ2Ar3n<3q^w`!^K+<>0GfQJ z-26nnX&c`JtmRX1z@EVObtNwO6E)eI$Um0cZX^N?fR=}(3+oEL(TYxbG2R`9Stpe8 zHW;ZD6|i%f_y|FI63Uay&O?HzXiR6gL#V|Z?jYW&Cs z!@z38z-a3*E2q6>vB|Z$wtKNXP(DOXVuNw0%SZ3b?yMd?-Ur6j+OV|^hx=8MTXw85E$trYJM{%UA>x#Mnk-^pA3(6nZA@fzuOj%iy(_=u zxw^N|Iat7EGtPNg#YI*{#XZ`7EA{sGUc>*gzx^wkHvH=KQ+wS_hhIMU?yn3c_VOnU zw=b?e`42C@Qe&k5B0tZN(`dGF>hwULO6qPTo(Iw(=78hDFj!K=d#Z88d)2v;bF(Xa zl+UCVhd!qv5(N)9K=nw4VB1xTaCXnPnuM|~6jqljn%cBlbz;5E@J$L1R#_JyT#EjP z1C&MI8g?2@$v0UQsRN9WEnw)Oy9Vrn@_2R^kB7mBg+z3I~=KUpPAceGd>ypSdmGL(P8HRNeFgp zXDCp>VgUXvmPHNCP6LDL+HKrUa0k#hYQYjNJPgQvSwpg|6`&gD>p0Z|I;XdTo4CRClV8<8~t*mxeM-gok(OfV}P$#vTv9 zM4pT5RTcDZQj$Ud6Ws%@~SG#~E)S@M-8Kexm7SFqlEsof&%Al<65Ekulf<)A!?QXPq1Y8@Z|s={}yBMcSh##S~$J_oJZcUJf(MCQDq=}-keujPZVu%SsEOK6y~&ld zT022Mi)4#!V3Tkiak5*JFD>E3>h&A0SMDWjYk}lWu$A@ z#toCk4Rl-3o1NXfwCm;s3<thjM)H9%7g0+ zRNldBy@xVL>A@j6Pq_EA0*qJ~Pe|!#jeqdvS_bduky~xeEeL+fGUlI4b-AtR&_=uS za4>2Hx<6seO_6i3DxS4!ws;JEkE7oC1n@NG`E06phw5d@Hr)iRL0S*DfT?{+axo$2 zrg5@Fb9ovbhaNH%H6?{OL)A-Gs``X3ppJIg-yLU^a|uGndA|xnVJW~Zo`&_Nn%Dz} z=yE&78n01@*gPDP;dX~I%4%V11w-V}M@nwRU*#Pvr?PO{jngZV3q$g8Q557T#k1Vd z9SBOZ7r@%_+e#O>2BBrAJu8WgmQOH-YS-s0N9z!WEbIfqeOTqpFw~Od;29mRm4YMk z+0T38002zuXf_z?S>_-=z#91)N5bL>;kAX;NF+-+$^AcDd45$>F9=^-(gyT~r0H;k z#-?sb$ve|=4iYLMOK!fJ>&B^`*?Ay%u3O)BU<}tE#+{mB-zr9EXs$<)mZka%mPUkVK4Q7NZzz? zL_RDEhj!f%FoHN0S4d#&_iSO-NfbbDm5P8k2(E)2qdPpJld5jYiE4bM%Iy2!R)!~L z5vzf>U@YaHE|NANNMqTZsV)YSXX_XgFiye05gtRsN>q({Mp0T@kuFvZVoby_`wh+Z zppAA}jBk_#M^*o4HMFx3Beeerem`V~ugg|r(6UuD}&R2MST6?0Fd$DynYM$l8;`#lz;#5 z@>TxMH?Mzw{fG>*H?M!>j=b~oS$O@^ajgG0FMoRbH{s<=%;ss330TYH^zh!^LkD)J zr(%2x?hA#49)LP{Cf>n6Rc|PHrkE5YmGH@tf8FcpZ9oCFk7(Ad=R*VWX=;|h2gjP` zn6}`dPV;?aEs2ADyPWA9f;^y>tO0;+1GJ-f{&e30Lb1$XLxq&C@{xlMUXHL1oVSp z9o({U9g(TN{poixO&vL7E2ed#6=jt)76GE#_hZ4~srOKYzvQGzZf z{2EoCiVM2rwcNBsvbWU`r@(nD=xO1Z-;XCW z*qhC~ffZXS_4TC%p{yK9u|BFKRPd|8^}|0RFX!+;LtJj%#T)1vYWpb<%iEgNxl*;Ll?A;AfA|&`@T4g=-b2NPLaaR% z>w>W-8lsXAocEp%BB;qZ6rIw1-3kQKy?6@l4q-!Km9K;H9Qk3uwuS{Y#6IM=AsE7Y zfVH#Q#*D2idR;fRx+grP?zuRk+>m(p9H6=6U~?2L*HgBMhkLG^5g(Dp?m0sl(N0?u zou<@|Q5OG!gUhJ%_q-|hNAn&x&y=9Sf`X4;0`wal;rnCxFUbF=A5cy^^R<8A_46KR zfA2i(KZfrgV3kdZ+w0eS&EGGPH@tj>*Wc;u8;Qi9?BUmUG9d1o42b(YfA9YtUbD^P z^Dz^AMx4qw=>uLFG;WZ3%EsF&H*_Ef0OS5Zqkb>9?@Cm#r5P_z+9?`e4F+#iDt{i!W#WD+S2xW=)SlR&G0$+5|u68q{xr4$}t-P#@;K_8D^JtV8b)4Q))E^_Y2wb^uL$e>c=MOHoOtG)8c$bePIm3+_Mp>oWcVzp@8Wa+k)mW?5@uvLxc{R*P zoh@b=&bl@C)wu7bhOo2?HQQ@y#DK{u_sn7?YmX4C-Jx!g8|wsE6am}N`5~K=c9Ycz zjeUoV4X*7{;VN@Got3gfR5X?zgT9q_CzEAr!RoPWo5L>dp^p#4S)+C)8|YN4ws44* zLe;1~^(0?wQY9r|)(0?3^1xw_r?{cKh@8iQHL-gH4r>F=+H#{?Jg6+FUObb11yDcB%I zim=I+Zz%|32a(3*y^WoywS}+DURpJ?oIp3TQE$MofY+p|ih!D!r<=tKh(kustyaLF zgX5-wSL)lxBT_qZ*t@cTdqwL74{;bcoCSaXq=G&NS2e(!nD{I@AmBD+17Y+>w3Do@ z#PBbW2XuJ((%xEmObJCo#lmheM736K%MH;_BrqpUaR`r+1RuuTY%6CSi{;(6@(@uh z-raL;DId7P7WDw6AQXG69-(eGADV_@5qi~HUNp=hZk_rg*#+?Jaa z$H2`-RLHC_kSy(F2UKx|m1bWU$O^U~>@9EIZiA>Tqnf7Ct6z+YTYA3& zKi7}df$ePZY|OsujC}G(5kj7~(*y#QExkZ@m%x+f9_#7Hxm zQ-6`-CDBJlqG?u9Jy26+HIRZaR_|!(x>Uu2QvaT1)$fLK&BHm-b?MrOj3Z%;W6bHS;6f@rG0<#KrK!|gHI>SulT*6##aq3cbiB=DU zq{g-bjC$Rm4{EHGKbGnm42ow~SCAB>`4gteojV(MxnV3b`1 z0*fulSq0u{@rRuIrVa+3o5ex$quU53c9@B*ksvVjWidY}T7?!p7J6(PoFL>`s$s2q!M?XmBG$E%~#15?1ffJ(0LTAg{!{ zg0saZK&S2TMS|oG;j&m47F2E!_agCUniPIyrx#&vXxLrAUTw{2@Nu6Eh%_F`@>M6e z6LTF*00T{k;K8QRSgz;OMD@okqqxe4@J=M|fnM8_c&0-Ib6iV;6?*j8fk(*d-L#(G z(~CR_vQ)Q2ZcPG-X1F4KDoGXEtEH?`;w9bE_Ea)7mB@~gbs#jOjAY1~VMxM&1(2M} z8l&~lCgs!EKCDZRWZrqK$2*HOrG6qWNDNj!6PqECBT)|FM=lR@hv~)u0RwwQZ!6}X z$7;3WBE$jOT9eavrDCI8@|@8Tm5w(}&9Zf(FYYD>9m~l)x8C)Zy>gp&qW{#XUAsC2 zuB`5qn{$a!+3HjV*If$=pkB`E{ABvd@=+mVB?)CWT5U7Pm6%O1LDIR0Q)`EG1N_-K z%LDLsWouJ}p`iZ}PC%3lHcu_xJ-HtTmDdVv4E2)oP_%hj7C5wd9E0~n$os|+C?@-{17^bU=^1_fOnen!ZB}0$f z8k$i4qOYzLhyjw04|Nx{F{5OtQI$Xy$l@39gmWXVE>t!i{ApszKqd`b>fCj_j$Sn*2UQ)`O?b7IAguFPX zm&#~I^Ml}F;J>Nd<(Ui;?`Zvn^DO!Aksh3$gZ!HHOpipleZVV`o3{hS(psYn=%J@H zDbFoIFj2>Zev#|{35O0yMC1Qh}_ zERINm8!uXyz(8Bj1-44N;8uHrv@7@U8HFV96C89(T0LO=3RO>a3rtFXofo&|h4#oh zzJN$PVN2*<@@15|<$+Re@HQ+U?JS(pO08=jMn=V97Ip1lBN)%Ww@KmE0>s^O{5aPK zd{cy1GF(69fqh7sIq#uABBh?3=>}}M1uRhtu0%y#Dg#%eNoA`~ifXU%Y($VgtUPzkC{Ae~GT-pI(2vcO`u%f7MT3J~q>$ zhf*$a7h8P^=-E|YjBEPzga&O#Z(CKY2=`RUjkODKgh^tu+*QN@-+Ej!mAJs)TWrqzJ z?d@Y#wMlz3CPONj1171Y`7YiOQ%TB_qmE9wEG$SQBOV?m?3{1eYh~f%lGfeI_Y!z2 zTio9_gYM$nh@my8)=U#zL_!>p3sP*$4)<%(tAlYL?m|_#*#&NzQR2RP?&5Y=vG0^M z?RR8vygguIQ#UZuo#YnEP`KE+A8#C#gUZo;1JMGLyujZgPdfOwxlNYNq)qmZMg!CCInhY6PESu0j!N35qOiT>?!G!jcH5Z?LJ5b?|t zSe1Pa7e-E5q~`G*e=W@A=jsy1j;VnZw7rDg!WlJKq|AG6a-v+aH?=UfWYQ=o)^ z0L$O-L}KoFJ(ZiRzIdE-5R(eW&F&;9>uR*Oc1Q3nZbT>@xMy$4A{>p~7NERE7wXfl)_a%l4(JdN8oV4#lL|?w1K1tb-(UoBbuC7A<&`1qoW(*ixOP<4VJoAN!g2&rz~8E;`@xRCj*3o&B&%F- z2IH(~$Wck0`$F<{Hyc2&nB)sIx*zBc-^lAlW7BIcNNZZnB|&`7L(7cVdHdPxpI^R$ zWAC3|{*ZU%jn7_wo4@84uOEfik56wuk^=izL0-PW=pqF(XMZmyGj`>g-%bhH{ z&TU?fAhThe#ce6WHtnNvxHL1BlC)jK!S-MYJoz*e51DlvF)VhQUA?Nd4YwhS z?db_hVB@3#zl)&5dim<|pgm|KJ6H$Tj#wP1OBO}TJ@j(-`qlC^d5~e4Ou&v5t&`;B z7L|3J#Y?7scx>Vh?7_$;s#~lpc^?QK%j>QZBuc4I*f~%Oz;Z;S^#iekXR9PGZ~yCe zf1MvL2u@$aMxS0Z`&~Bb8fSEq4c;?0RCbes7aTat3KqG&(gL|^6jJ$MEJG_fLT^>> zf~3#%tLIcpzoN*5d29QuYeXH_3AAtvd%bao18dxA$|ThOe%r z87dSR?S!A9?Xiq!a#6DwmB-dT4u|%-RIYNzUfZdJHBk=y#Swt#X*tej@NJM3Us`du(7UE|_NURT&OrLT= zT>&`49YBT59W(G1?3nWzBETFFf)Mi*4moOp&w)%O8rr!Sw=NKuQD7)x>8-@RL2=N< zSmUp-tT_{7yI81tG}eTIuwTeZug;Oxu$Y%hHYkdMh^hj7nhLX0M}oU5#$>ht`U$^0KKy)f8s~=3zcX6%=ik*7~IJ97cP;44O~m9mx?a zZb$j^+uBE$vTLJF`L&f5!r%S$FTDnCuw?$0uMV^QXW+K~Y}5M-`UZYM!y@c_92l@a zhkNfYU|;m>@b>Rs--nM;e&=srK9T>w#?epY|Icvb=d?M(hWQE>l4CTm>{~gEe3tV= zhoj90+t`e|kj-P1rOxEEl1hWHZT3+3NyF{v>>fo89c*vm2)tVW%Pm}ucLv&fbA;gB z;e!mpCs)h67qV=sk_HAe4C_16SBJq1TpOwU4)B899axFEUsB&p)i0B3-sm(El zFW3!92YwTEs<$xdj2O3_+>f%Ew*n(so)(u8uJYbERLr(#XB1jiQoXa|y@8}|C9guP zK->kiHNo^(o=j7ln$Swf6WX}SQfxC?xMSPcS>pV-Sa}YUgQZmdO^~17jOCTw7*(`* zZ)3v?awt*7Efdft6||w3u?I;PYqXJapzJ_KsQ!N7c-o#oV>v&NC^V6bn47>*ziiEx zu8%-;K_41K>J^$=vYMyIa>9tMp$K57o_H4SOFlGEmeo%+wL5WFt_)?PAM&}?KQLV6 zZ?(ui0>S4yl%K_nIj{wBMTJ0+$u(SLF^BiB-sEYC&f0CF1o3{i#?8;Lq-$>RtKCZa z_Cj0*{!O^YPi^7U;|43tB-LW;_5Fh^+-B^F{%F8Nmhw-{{|JG?G9Y;+d*4wOi4oKr zlBm(NS71!ull56DGaC7#rB$}FAt$7QCPd^+=ZvcF0m2QKAf>5F0~ZwPaj`D(Id!Pm z-mUCsB?WWHZPmSG7*f>(h_K7TWGl~Srv%9wCZ#rF$|=QM?s#cFM+Zk%j|IjM<2*OC z4TNTx`#wQ_R_f>z%KZ)K;-IMDBWJLJi_$p3K3>j@%3TjTe7u}tY?}@W%Pz05Du<`avJ$&eI$SUZz8Im?U z1F|EfkL1TzOe2lOG8rX(2xH+Bym;1jC%fur*j+;}?i8yHO@(~8Qr)#kp6w5Q$Pu16c59FCR#O{~@%r zK6&}(<+pD?{qC>G#{KLCpy9mz{_C5UU$I4h*vZZNPmaxdhZG}^_`BDS@f(QDzW{e1!&*(H>*MvY}n&X}cY^q~%?4UMg*j`BpSJ%q3!ddV<~3 z2qWS|2=Q|w`N#slJiI1lg<1M$As;Nr8<1aj3dt?agl+^I@37`@ssvnGUCL`Y%Y$Kq zaPuVO09=-^^Z5k)rhS@HyX~&3DUTQDeZWYzj#-_96o#KdYhxsQY8v51m9$)60aBrU z1`N?rT{q*zHq?aC9pgFl?bv|I22e+r4<+2@a=@n1j~(bRY}(*-SmB_PX35AnxR#}C zGuce3o?FOR+1O-=r3>j|{7^mA8)9_n>IEW8AYK;8>`Zt%hgR@{aM>P)7rKn`D%JHc zS~aAAtR}4olzsaQ`i&84+XvO5TUE0v)1y>hCbC=M+6sq6r_PKpe~l7A(MV{O%j{)0 z;x^sJYAA;0t$Ez0u!~7coSnw|tdf?MrvzC#ZEw{`iLM=~W?Xl%j4*!hKT2i*?$@T< zPNJ=Y0-f_-?W*cEhF{8zclW3a09-hu1_j-f3(sBlG?UyQ@8@PZ0AjObfv0SHLODyh zi{~^MT@KBZaamv#HBynR8Z!*O($pp&l3ynYZ52`Rqr1WAtv0=Duu-G3Sx^&Lw;k&O zo9E%-m@gGZGZk_)2wVj#n6kkxdFcQ$Xa+9cEry|D+;a_WmjLS3-n^rr{Qq5Y;|BO( zBdd|b?Hdpd5BCiy(Q7W-aU;W4^{F4+Q%fFivJZG90f2J$&ov#XgM~J745+T)8vq6D zK~S``#Ae6Z6ma()8R*p#zK{(}n{H7J6}Ju;v=J(B;0>`k4*Xf(>^fpoqwpil1^Z{O ze|-JNAR+l%9(n)u{qXun#LDMqM$Idr)ly)e?oaXoO=<6b$5K>NJ|o;ohXpF#r{C(E ziuxHM_9r|BOqFk75OAz~iz-@Yac8T{cTsK56K#PX(3t@!Thd93nzzUhJFd!(I+wQJ z%(8TtfL$)4kpO#A3J*m&)pDcR*CR@D8)h(M*8(YcTJ9)wypydlRZ2BB#y44)4$fcz zTx2}w0pYx+78G}vj$7a%yqgziqV2nO6AEy1GLh`J9d6j%`hx4(hJPy$))4Yq7^+eI zUq<#}vjMWCEqReukaU_yvUkg4R}RKfR+U3}*B%9S-Btfu)`!iGYMUacYomp9jQNcw zg0r;3gaS2%4SuKXi~@is3sM{~$nHE`K>VO!6Y z&g`irGlb0I-TDpTU-huioY>6zlcLvAYG{9tLrXnNNf|JtzwZ89eTzdi zmbJW}8u*L#s?*1&JjA)+yCJJa)f!m{E>I&B!RT$6MFs+wJ2hlpA_Y3mY0=Shnq@~G zfU}t*Nc9@-j=AmP4eI>xW}Yic6)nk-2!9i^xUd6Be&r4~rNWq#NyNje^Eb6mzH z;litf^S~qplbO>cozGf5RqO%KeR4TS*Q>&N*a&`ugL1U;wox;cnV2?6phAzum9~R`uvL5E5~~hJ|qk@%q3`Jo_7J0bVhnD%d`Q>LB7LTz*Yh7f{NmiB0Tn)^*}IN zzDo9{dS=1hLY`n(x=a6{I7p?nF*8G%IhmjXp-+OgC9~<(;9TpqE4f zS*n`BrwSGNCOwt62N1V+YZ1k-r|?9bjt(=>MAlZ9C6w|`lewX}*xoq2hrl3RFya8{ z0y7KMDzN-S9{6q_awNr0Yahdzj%6GrNhZ`?P6S3CBdkk1W>3)h(#JfcCyv+(Xon$G zS@%J!7H>^Jn49y7G9#Ps*%3V-l%jzOX3*qT%744aHdakpYz!n6pE)4_8aZzveQ9Z- zdDS_r1l;m}1c>{GWRfb@3>h1#5_6<4lV0ZG?xqREEjIpS-_pQCkf}t6N z#8-o!=+Hf#a);B)46q8%q4cC84)7_cu+>WtnDPjICD&k8)ej^M=g8FHT~7%NcL8_l zp$$i-lZ1I4r6bg$?^wOe^jzoj*MbgUDr#Gom;5`y$vXT%jCWnbNfI#JTHy1sa$f4pfCF}T$hdL zR28(P`+T}=1qfkLuK9!J7ZYjoM*MP!9YiIfZ?ckt84=ffNrGWO z>6kp-WA{D*fZ^6v+PGB}rLuj;Gp}xOZYh_kJeQ%C2VS<%;L^Hq4(to~i{D+a?`ltbnFh$ZrGimPDk>%`1t3J#N(l7HK2hGBz~mm`f-T zT50H&WHojS$VNUoRf70N0ejb;h@%Q5b>t%mwRrUR0EhHOrMhkRn2VQP#DaB(i#P|< zrMfjN7zFJmkqx^2eTlDk9vO)FBX=PEZO!C$q)?&bH8M`)4BLo7lBj1>=;S^g1d4Qy&af&plTL1zp(av0%eIJt z5jv_IV7gfOzbS2Mw1$K1Y8R|`nd}8K;gbT7u0RqDYb)haDJPKT#z;65oBV@fYpGfv zdoYVycx7aN&3FM9h9tRjm<{!*9_d}QoH<5w>dt#1*)q4Y-QK+Z`Q?NB@BYqjUOxOw zui?M<1$^Cq+Q%>75Ik^j+kkym#s>Z=y#4g$ccxSF_OsXD1kMTmTX@Oryyv6OyVTm_ z?n5i-g*_rDDs26F3eDP^ofcX=5S*mXg`zbZ@RUxLZ%KWYW7J&-u}M`#T%Zby-z&R} zko^P>6TS=amX3I1U;`}&}U-E+DleNn4sOCkVvr_|2^Gj}iU)G~8m8X}14qia zlnx{bLg;KW#@z%?9rZ*Z4W$T#2QwxW8e5J{4p~D8LPS2sdeRtqQF|Y3X(S}+qi>fI z_bze1xoo&BO}hG9vH>W8H5TO8D2Z>9k5t{rVVV>bfv`rNIPxHNG-NT7AGu1Md`n)- zXfr5Tv;Ywg$V%#ymEj4geco%@PO4fYc@oh!*C}h*#?5m6_Qi3~vR!wEWw(ix->vfz z3*19vDwF7lpdsQo4*3Z1^+<199d=^pIZkyA`+#nYj_kk>?NJthEqp3 z;0`K$6e-rY1g_AED~ zmpRQiNmUcF*=9ZxyYs=bwcc8Y+o30IgPFO*_yvM3##2z8wamgrW8{3$F(1({!qEa$ zqWog-IK|JOnOcQmAG{?%)mh;PI*<2k{3(kS0bS>b%zOoaI$1#$x)E|{6aH!K#9@}Q znQmzjY>7epLkb;0quAWI!l;#UX*xS(36~E6`bGQ$1lX!%UZE)qjFPz!iU#P0B|>^i zesx{2MKR4(|a( zn1}kmmjAyA?+o-Y@(*wS-iT_?cMUCFvS!0F@l@W+Fx@RucW_e7*`LnxfdXr#IE#Z#U#h#u-~Bi(gaX%nb^foa%zYih#2sn(^Kmm|7)<^a0=B1 ze16#ZgjfjSbLjmR!0#nocV4gu2@(AxoGZFTkMQc5N7k%4n4R71N>x%cJ9T2R>}T#v z-_Xz+JT9+lM0(~?ve&NKgNZ##n9Ki9*PAU%Z(V1C z_xTjtj_$55m#qhIMVBANu>tG^kco*HG7mC36lKeG(U*1Sin=LNA}LZ7C6TlSN-`r3 zkKU`-xAyuL@=)bp;(vfV`R9OPujw09+3a*t$H&woa^2IMqtq@DYHCmI5+kJX9&@yF z0&+vc*rPMU9yeh@q@M)oYto{hHkV^?n?aZu6;{J&|H2u&O;WvlBTFLtC2$Wm%r}NQ zNnvLC1lP<1B%lG`Ip`(K1wTi*dULeF8Q|oV7MhTx1i{qYHrw+GB0yspBXm{<_-_Qa z#M%IowQUtBKjl7Ucb1S>$=*SzJB6U`7ISRYQJMLfg&}H0f&XWC^D)?dt;D5ACeZTr=BhnK56clU&C2sX#SoD_e07L>b1q zJ{kyM3_F)049?>l0-eFe!7GlUhp{r?k9ij~hfGafpN@W!l%(Nw2B-O{;4SAS+~lt$3TB`t{}-f zHN-J3W2)eSHGju`!}lz<-QMGCBM0P^;q}Y#{~o(vy?sHz!_SXLzXV;-Hu9sNzy1U{ z#?R$>*+JwX^{7uH9+HodBe0jxV+u$kUi0#Chq7oom}+;akVw3OU*jL-bmTF$%i<{(gk4=nyGRJONVjRpOOkzkfMX79y5*=f<1bCERJhuGSr>TxR$MW zZYS!@3K=!%f~eQe1bxY>d>`eyNGB*gQXgFINPu1sM=q4_oNlNwCQ%81;`nx!=$*Im zde8v3z6e}{=27KK28sbl;&;>UOyFVLDGJ!04*N3HzZgVMTR%ahtVD@VSFc%{${R5Y za;{YZBkzt#DSSr?oPp)_d}yRAW{S$BP~4hN^5Nkt$R5hD1-D)s)a~51^%An@z?;IH zC?q^%-f~=#7&=JuO`O6FC?s1ehS*?*&fB4{q%L1b=p#l!&lq&)Fr6e>5ZXf4>7d zJ{%5eTBJHJXD?AwoPAsxPiR&mw0rHz)XY!R>0MR}>iS4UtS+%s|T>Bbe3H=q#8k+s@96oup{H{~DbBN#6algk5a zi(ZURivTERI|f$*;36qh4UG5;_y61#jV|Fcy((4!A5yilY0XNKy}01J(3CtLi$K8 zJ(l*cwM{cx8hzRw+aKx!MhLyMb#)#gaD-s|(+6|&7A0_`J--OFQrEB?dr)>*f$_(M zyAXy_j!2s@Hq5&i8CVCVOlRQg#v8}?Xl%8;gUVdRJhf^rafd3PCSF2JHS^}zsWC2&5} zCsR`EJ<^LXZt4#MNo2k$hV>H(jM~V8{U#C?67`3yR!?l9+%n5DbEg|izy^B*Dn-R< z*x;a&g9SUBJ=#KoHD0co|MFjGk(sSGtd%btr|&*_`*C>vS^h0xfv=y!Bts(We}DV% zyZ5(cc4!-P;IqBplrV#q|TH2uwroyWkq}K!Nb0G!U+eJ49!(s zAs$X7UpoOO$l)iDQucf)gdvq?J6>6UFLbc=8k=XbOqbh+L3M2xOA=(KY!+2^+1S=z z6u^9v3w$HGZ6Ip*HaP^(i_@Jg^{eWOcv>7D@0vgRiM}t;qL6OU*4-F$V0=hLV5u+=Y zwSzNN?>He7?vd4DmUaA!u*?V!h~Z4jcQ64Hz&_7lmpU_UN83?O!I}V9W8elMs|HLy zJVuS+6-I_~iP*Y%MzLh|emg@2&>4b~{`9Q9&QSUzuMZ;)5yzo$&fpWC}Ck&L#}O-+~cXdN5w9&edDAN zz`ib$eISPuWP^LqYt2Cfas$=wNeyjUeq^u;D));nM@-$|y)ET?K-tv;4C>gwHl4BT zgp!(iu#pXggmBPm%fKkA-b6^fp2qnb8Rx3Men0ec&`q*!eYv$~IxvHonViH`Ns4nP8zBl|n_B0*N92mmyLR&JIXba)_Pm><#Hpad#F!V-~xAROo) z+g0f_w*9+G^6QtR8vwQ=%yk=7^>FMELp!i08*rXtP?|72AlybC*(0rFbmtV?m<+ZRK5J$sIb=zSXiO zKf28-h`qD3u2N0#*nUdYvhlX8UnZ}-p>lbD&B4aCXX3S8b&icW*7|@n&Xp?cci7nF zO=$RpqhGu#Qw}Tf;*%r{p|-Ue;nL)mB289|*Nr7Y9bQMXB(|^V5!i`THv@nPF_&er z9(6dq#&ZmJK7`h5K~@5SP2tG?t-$(*V!7o5*^n?AX&OV4PQf?EY?l1+F^Bxecy{XC+@JV=62 zOI&zRwNfI7&(7u2y`mzokUf@9o}D_&3(obK+CaU6DKCtNOSiiD>W?&BS*`0uVCx*P zPo@)^_u~s_2?K+?ynR$e0|LJH__b^|$-cI9P542DoR{Td1-+bl8w&UPd3?#r`BVe% zpF30iC?R9h62Ky~>er13$scU|7x3Xm?T-3@o&l(`pIx%iLXZ2Y50`i?EPd`KpiAD3 zwMP}dIwrrMZbHZtF0#y2x~TJ9IBt%|j6iL%i2zKy&aDhBbH&-dGQP`#8w{PoAb-`x zvXQctGJBmjL$Po}zZl-x;Zhx7K318HTquO>D?Fd3TyhCX;ULR8O|O>*X<0;<9TM|s zT1h&cpN-D1ZFL0hhh>+)sEvM>OhZa&Qftppg|vh}y+n1ee7cPikTj7fgWLveFod@I zHic(7wT1MS%`!3GZ}|hx`|S zYh79$OAnoG6yQY*|7`gi!JOT4iIT>}2PX)Eb*0?%r(zk*);fnU0B>D1O5vQDcSkgq z{9`&-4=P_tG@DCH0L^e^j6$yJb$a%Swr92L(Uh)?Gi1RD@wFgx;|JldpNQ>Wy_uop zSC}Y6t^Lcl&qCffefR0xhpHNjK=qXh$w{2rfvbx>2x}TYWdllsk_y}@_IXcaIo)Hh zV(hkc@cpx(GRL5>a|=}y(wgd+9gk;Kc3~tN@`{^yUbDl&2^QgK$4Z{rxp&AtNwT$^ z)?4PMo-(MMH_STr4ol7UOLN8e0t7pdz?+AdY);bQY0Kt=XVmhSxJ&L=bG+QC&Nem@ zq={G1z+_=q5V4`!>}A7!FPkRNlbQrlw1RTkdlXJ*^Gz@V;Jp(X{sy(XBW%vNumUV08 zfLojToMo#c1`B5ZEde+y!kkSTs7{%?6HG&{Ttxp9(jH*|(8rx# zT-jV&PWxHjIp@qhM3+dX2h6L|Nw+&u)>2z62PYkN)0Dmo2K3EGsoOeuy2yJU6HQfdfMy)Fn3GbugSUC*Qj#ASIXJclLfgx z1+QvB4y(60--T!cbNqw>scj7vRueXRDpKolOR97E z=AnJ~5F5?r<(L~7OFq3w_&(KruwiJO(6(o2sZ}%8l}f>Q&rdrenFLoMx{0);G`KTW zwW0NTHZ&MK%eBPb6_`-9`h{vYo)s;w7}JJrA&W5(8dhN(f0a{5FX*gW-1=f8m**H* zOhFoH-3}%0QtJAXGGQJb3e|xu`8`?UQq5k`faWZdeRm0D3wt3z{5X}Q#PC!uS~-=D z+5(za^10UG=u)Psmaes}!?X`xXCAUK7`U#a1c5HwA@ra9V4*_|cSi@Zs}Z!?m$8zR zHG83?T^(G!uJYg?Av$DZSs%e+OhF?`)gG4nf-6Ft6$OOvb3jCt1{`jOXnTA-m}tlB zy+B-K4(7y%wR5parpo#G_Ne-|yndYb^hG#R_Q$??{f445`4#^y|K^|ZTwv1v z*?emsDLHxkC6wn5&~k}Oqbx1=_S&MM(K~RwEuM13n^OKyunU3f$2hn(8JgT{Lxl*$ z_a)Ul^)X zp@Kfo(1KG_s?h~ua%o$&uz7ZuXL%8{G0G>)%5iA{;X{5=HfSuv!Gr^Cbv8p);P$=hgvn9jHPE+@2Z!lkl{2h%fkSBkoFzbR)#0GrjbNm4 zd#D}vjSNd73>POT%2`6usavRR>QvV&^iCZgSKm9YSynX*PuqiGN~^@SE6AHjqOMRw z&sP}CHGMh1Hc`EsZ3n|)!&!qf-KvT#gSN`z#d;(V8{FO;iBYrBN%MT@KehuX*Soqs zS6*kfy&@wzl%y?su0f(8ddsTIK-^WM74yJ;@~q;@tYy(*I~0?#8}?1d!zKdOgyoJA zvDKounkquX=C~CwX86Ov(*VW0c-F>qWyPZ;MT#WNI~~5OsoU0C%7DRTW9CS4>ssz~ z3+r;5hw<3V*jCxBWySYg^$a@dv*P@qDiCFK_@|23%>X&14QKhdCFBxK<>&eske1+q@2t*2UoSD7_MSMtnr-5Cg?pcl0-n!Cs1u3lYcW% zOQ0!ANvcoq`WkhftIwlA7zZjJR4}%5vUWCsk-P%DpKE%u2$k$=n`=6{s`FdlKZ*R} z5!|lTQ@=n0gZhAYM*{6`S&k&TN83I>6s8SI@;eZ3ZjB9#8XayoiFzu99L*=4z@i1} zp-44U9xrTJgL8R?TOkyioOF&dAN3syYPnoYm>0_Jv>`RQZ6e8LAd*q1x662nHQtKf z33}jT&%TH~Haiwc%2TO7|5X&ESn_) zJ(c@WA@!yLlOKYV{vwBldW#r1nT{8b=LC-#Gre@6xe_jH3mgX{smBY@aFZk#>dj}Z z;~{MlgC#q+Gyw!4P)>lePlG#vB5dAO0)wtH zI!l^arjUOX;HS&-z+RIJeZJgrx+m~<#5Ebko8bBJaLlGOyF z^zsQ8?h_y zSW*$^E%k>t0x(@0`x82&_lBzV!*~nP)TOE!MpexT4xM39QP`_TrmBH|nT?*6jvkaN zVGjVgW}$X{vRJGz#p>8slD)E_SQx%#+^w*ept&2%LUkh~!n(_;+Lz+OqMU4_l`+{% z#ilM%6$)+Dte2dF&MWX(Sxo;HHP#NO=;~0g8PGebyU6Oe$`2^|1d19;SOo`fW8EKT z0P$2q@W6?6262O|Tx%WjLjpc`SX|>;1uahM1JUv}kSw?HSw2b$*6{0sOU+(r!rT&? znwh42=+w!_*%ht*IQ_t6;>=P-hrIZcLnnUq`!}nRWrIJD-+se7`5oo^o7d07(@T8u z`YqMyzRi#R^zFy5Uju6P_A&l`{WxzUe*c6e{D*(~(c70+ivO)W^!EGLkL)38)X2ws z{p|E;@ogvK4B?R#B^p!yeWAxl*68V3hC@`^HcKo@c^hQUL?rE@7aDP!`jl&N4C8edO< zj3U!x@L8H|T^)9<#@~lkREB@si=+W2pwU6COKM>})+eWosUvmZ&^g6Cva@s;J@>LD zY#h>yCybmAr*qI32uv$^A?0)L@l5R&|nun(Cz>fALmtqP|@i3?D(1!AEC%SDwT+>hU5hQX~$Q&+ONtLXv zFm?y2tGNa$-UF%mPMbhOO7gw};EEO<8s#6&bXC2feyiJlKwH7O_wAvBQ-c%5#04Gr zCpGdq^oE(mY=kd)-V|JYhRE5-c0Mxi!G-6Cqcf9U%ERIqQ@z=EOqnf^HxF(=P7^wM zwN$kg3=-CIQA^<20&?2~h1+6Br2^;~EQpOk79p`~v3`b(SLMbl<(zK7n?AMq<;d8D zR${=zVUH{ufc#Oinq7WyA*n{&!z+&(>NF8lR82c7A}9 zR|7Ci>%6B`q(3J8)T0>o&LJo__`l?%K3OmU6iIL#)ZPO$mUjMLDlnTb0D&!u*}xr1;EBeb z!^S7crH9+P-k_Jo(R{22RVJDm#@RliI9`E~wOIWi{2tn7r~$`2s%o{Kujv4{0<=fu zSYmS1=@ouvK<6w2<-4UB*HIZ8?9PM!EQL12ymI_i->r*ngAy+(rEJlc_@de$R*^r# zXpIOc(rO>-2&t;g#@0G!;3_ubt#$`_E5C}_bd6WnmKfKr+mSnpBq1cMZlMQ10324443B7ON;8M>Tm^m0Xa5F3$1Ec( zVFpN@HdPFh%(83|>$Z2w?GSF4>VL4~S1Rouo)o1N>PJgK3Du1Hg_@w1G;5pDVxtBs zkcKwpPAY!oS1#6A)TsSfX{p*!TV2v!b5q0Yj>(73YJd66ar*T2rwm+XRPxE&mw~h7 zPozeDvw-&T+aDdx{G-=jKk5`}OkZaEK9APbiFatXPo{ReE3Ek?81*8Pb;4m0s$H?D zt{n4|OuDQcCxA{4LCTvP>qMn{zVQ8>{(#^n;}!vXzqs=5ko{pmM}Y>9G-`5`_Y@4_r1FEE9?>1#5u;bY&tWd`~4_ z=+vnr>X;9_Xm^MZjh-I*#*6M=YDUkF|$*y_=B6E~nIE0To#k ziWoGlWDRd?cC$E`!{K|;agrrS4H$P=lJ;OsO7W;i#i!Hr)OdQ2vjek|nRhrKs)1rA zpv+q5HrA>@n?nP@Pl*y*aN>mE5w#w#N_(}+PqJFM;_kKsYd(t==*oMR15xQP*!?4+ z1%9u9*8_l6qo=!!BY#=zs&n}4T>xW~zoou!XO)Y;!df?Rl+%J%CW)52je)A+C@#f9 z&*LOn*qRQLab>?t;DR=cB)e>TLX-Rf?$Qjk5FcbWY7r-Y_ZHDs%}3<+=~xhAe4JvV z{3c$*P27{ok2Vm-l`Az(S3(6Kdpg$ITs;QX5Dk@r&(z+|Blx&U$GXe2D46Q@yEZvm zm`Wwis$V&r-Ow*1wI)g0Z9XP)F}r(Dn%YAJPNjbA6zLcPGfIkj!I;P*S`UsETD7Hlr#bkmGih|S-#oH1F6VF3SN(wh;V4z5s+ii8K*QUbiIYjOd*@=gfcy=l2(P~sMB(=I^rKE^Z zo~X)id@Q;t*&KzP-RE$QhyMr8w0BSSevp&_cI>e0>(j`mXo7iq>CDap#j^o8xj1)UYDcgP|r3xqR>!_J_HE;DbPIcZVsBVJIm z%VzAs`@N>sak26Zk!IR^qOE#hlhIo>2Tnps}QoO-4%CYI$jxNy`!-moS!6%973_ zmFbgnR-Ugqj0^GrX3=>IhYVz{4Hr10m+9$|+P$4}Mdm1B10+;PLBHJUotfyX_vx&#-z<190kAS8j-$fBUT&91Rs$pxr3 z;E^NKpbB7 zhV&r^0T9TNINwK!6uf9}T5(+1@s$*brXb+Jhcp3VHIsx2kIY02^$mRi`3b9gIomK9 zvtYb=V@T?tp)xPASeDG&5w52OnyGyb-Fa%u&aH0K_fy#l1XnLBtPgGav23b(16BPa z8Z4`7_Ahi9#D3^|M^#OLnBqJ)^awjs(lWb*aM^;|1+oEX);qo`2D`zbq~v4P=BU-B zPEJJEqE6m=0<+gAv+vlgAxoOb_65T~ownNQDdofn;Bk(^v-rKjqnZnCgskxv?>IUwYqZihyv| zEPb}*vcTS`q?1*z3U2PmQ!$Iq@hrEpSG#cem4(>aL1$>x7&Z#HnH3p*-tF`PKc$wv z@>FWO4?@0fss)#ygTW_xd3X4fR4zE7GfPbS>CT}E@pxdIDcvrqQ#`khWTuYxQ(vb7 z8=PIg3N7t_JOcl^nL1{lItsCraxW5k%*a-bJv!$ccb47ZZmqf-Knq)k7+`!CwFbx7 zwmU@}Jb|Cp5d@0Ys9>n&rRgAd(2fFeD(ZXCEx>+RcaTn^l5qj|oK+F77Es}o)FvlV zwF{g(6J7~>ka8O;)zhw2YIRv$QyUFVQkuh!!*4}@;cYA_0CT-L0dM&{l^wD_2v}If zXbgUb0ixUk@8Na_$5Xj(PEi}6 zKC}EA`xEfj5#J@)e~;bdQUA&C<7aO_fBi}L?sIwMYp8d89Nx^P!)&(IUK@H~->M!M zI^>`DRBa!(TdK!Z;dc2E+~*!=_oUic=XBa*Ru76^*uDgt0l#GOn_GjaC>|H+d)pI| zjB{&ogu-QH$@@&Hc-6o9+P1N(*Imc-CveYgE z(v#yNm=l#eY*fSs5r9oQY9L8Lkqti)j*n?BUjwcQ7*igPAkTMdChfRp=KFKhDVt4@ z}g@0K05i?~Rk12wBoJ zHi1kcDZOBJN=Z!YQhj1*C8$b${vz#+LJ zz(sb#b#uD)1?eHY#z7mNPc2%_2NY|zk%iua#b8nlm^SJ3XklkTHfy=AE@3SrWEBTg1^D3M(~R*7s)K^YApFX zSoo;4YQqNf@FoHbR>zkx%og-Y`WG2BS}WWcO*j4E!3j%5fc& zhOO$OMy={(ZBwe2!jx2CMJLo*B=qo%R%ee>E>oB~WdHEjpS=CJknb>F$khBVX2GsCJIiJiE(B`L0#M1U#_ij9~$OmXLPaC?Y5_ctvp5S37A#Qb4 znUSriFA0|B=xSlI2n0sam zRgN8|;0sN_r?JHRQldOzVWm?bGR>`A{Q1wa&lYR+6&>{caA(m3?JAi zLM}}Tb&u~l^ZkxBSiTy7PLa(Fqz|M>_9KKpBx_jRjUF>cx%f8Hz!hXCTy&f z*m=ctt+PY|6!PIIgTOL6TSa{ZOyvpGU6?}1Wy4I24L=?D%Wc@yM!dO23I!FA-ofEUs@)!vk$Vbcb|a4gGZc9oWYCQ>%10 zmAl_f*g?p9CyoY;83OfqI#Z?(B(9Fm>}gL8?gpl$KuOP(3)Du14XCmk03_{D_6})v z;pVFSGx#!k2jKX|bZuR(bHr3(Lc!GfSt?cR#@qeywTBc}EOa|>y5@-14lCdmtFz^Mjdu0kA*z*7-0#t>L9Ycxx{u_H^ojrOvUaUYK zTgXMn^bwWz6$q))lK<|RXwhaBQg0U_jrs6hEbhZLfN{K0Nosh8(UdKs0sj9O2kNiFGhgeM zufGo8H}w4C^-BhB3(lXtejVQaEo-5Dt+cDxe*u~5*Ka@m^S{Ht_Y3q3J_@ftL9gI< z5Jy3;;1@Zt=Ng3Kd*p;Sk%U) zm=F6ceBcaflm5UKB!7ksYI2is3C^LhzCcCV^afIfkLy9VRlIj;arwn=#bxh~=zP}! zs0CZdxKwUR3+Ol0cL?o+$$+d3i-vHv_+9B%TS>BTK5S2}9+i(%b~SqWWrC)-Tw~V9 z*ZhvF3r1;aYSI7K8J3f=X80!^v0t(q{kt}>bkGBlEBhP*rDki`hML3LHtQg(_-3IaE+~thFm2m!78yft_CjilzW~QFc@Q z>2jSZe%pn5(=d6q5Q(mB!wEdTyu;<>Y8xUh7)P&PWA)uXz5Xg(0c|zu?G1(sM~!Zo zIS?M+jnDLDn8C-B3RAcxQnQuUgM8AA$_ATlN*{Z0K;StTi8;GSoXk-*gm8w zq)JwoOBe2hjN{T`Kpzh2f}~=DmJ6gwVoyE?sDKaoYyfcbW;)}vqYEdc?bPuKuOvI2 zocN?hrq?|)nb^0-3_KnY5>?5QAhtK`p%DDSiEl1h`&_aTuC{#bG@-72~}HBOibt+EH$j_8}g(K1|=xGJ=+(8)I~E zxyE8+5ms)`I7(o>1?9b2m{o%-R~C)hbk~z_n3O_|q;l|EAEB2r&O&N=6w< zInz_6SRml~kXEXYVddKm8-8@fxnff8fr)y?tR5_}_>3yL`qsuiucd zmBTIWZK*^p&)Zc^+@^Fdq07L)`^ZL@I#NMo!y@Bt?6koxZN@>WuK$Ej*TtH{2U6d?Kz#h`pay>Ocz5m?$FB?qv zEoymFPt-t)3~e4k{%B15Suw{| zDqK!#LUNqneJVrGx%o_sxhYQShge>-0JhZp0|drSgWN^a3{8+hR}ST#C1Sua`@Wv~ zH5^6Xj3BtF2Nal|(avI@pg=KU&S3kM<{#RK4r*?RqJNvc$V9O{Q_~PrFU0A%u{|AH zl8(a)?P@s$R_9=_TPj^i!PafLvaINUFRsvy;eMbLJZj#jkR8qho5R8&`gXOMh{jby zv%6HxuFrf8{Ui|*hac-$4w&*W?xRJeOH^g?7yIz4kDF%eKua}==5af~a}Rf1+xu9& zB7m+{W9_bEoRg4yg+(}b5oeZ@di!}xdT?98CY((_OnsY!mAJJEkl1Dw4iATn_+~aH zpKEyP18Q@Ju61XC#uo3r5d-5yJUG{|ZPSY@1Ps2pKM zK*22#IW*Lbzar#i2z1#+#Dt&yiflx==1$wMrg~HG!Z&j!s4AM}l zc~eQ?I3&vk)|MBgk(b<+-*EVB?B8dtEs)iogP6owh$A~D4FQ~}vRaKR;3gFg--yF+ zA}ZNen>y|b1@M@yfJJn3nD~&CpIqJ>#(EYMp%=xX6U&z=|s<>P$e$5E>?d#X__vf#_gRkNr-^`@(AQcCYV!4S z*gX;Ka|fkMR#sV9cb7@Qu|TH@UCy5E^t)E}c{9A2cvhMfToE8(!;AP9)|`(?c6vqE z$qvUh`^}xLAfUbmYei2Y*A1PoC#9(j+g4RLDryZxi$OqZb@>dX1EXgFn})-6K~n$T z*+~)u{l39*wmS zmIf_}yZwwe)}X*ikSmIb96cbQY9|>SwY*dm&tefYx_LQH^9Z~MlO@@8bCO9V-ty)+ zuZW&H$(1w5;jI*!n}?~;u{}GPbRzeWf=}TtrC{hA%w*-(IgJmS?u~cI)JVZOS|pO- zaSgW2Lgl{oW-Y)t{b?-K{B+oX0;NpGJ24EDi!u`n=QywxgLO9Gc)A_|%SV;qt6rY+c6G)P=8aZShjhiPGCm_(L(uJZK?GGyOEbo$?6tI zC5m1FB^%3Ab`;pIcT>&Q)+ywnDT-YNlImJC5qO4A-ij(5jfSgjxZ}~tfY zU9)^_D21h}gM)9&_oUb)gg79|+cTo(29>*9)V5A2u#ARG7l@lv=JG6;TfWzI+Nx>7 zlf;W+LF4XnFtGrn1YYpzegtC)u>bn(miz@QEIuf~{k*dq5#R9Htq~>MyStuG9KLFNSI|97PkPHHM4v zhVLi>Pm5e;wP!-vrbZ(I_me8IGd$C@Zh`$+o3!pcpO!N;U)QoZdtE4%m^>X#)6HDj zVT&=YpbF|P)E=M`Jtxg_v&|ILGEiZ;b_Tr~r#-yb&6a1O8U8E*4_74>6DBoFQRQif zNCGqsbd{Y~B}FBpeo91@I&R$7VN-(;`6LP;Vva61xpAl9*|(jvCg?S;O_s6tJ50#> z4Y0bD+#?uonJTJHK`|>lOkWzzbEzzQAlxisrAtfSmp=PzStJ`E_M;+8tt(Zun2*KY z3r5Maf$ni33x!T4x+6ts(XKvl+)8S-WERv@1KawwY3J|5VVc%OSU^}L1O__UIQuGB zW4`zPBH+Nlc%m!+K=!)oPSb2Du1GH=yfCRQ%T(`=AKW-E1u zYsttJQ)MJ)k7dC;E}EVKx*8A)234y=Pu2PJRpWy5kc?_1rfO7gCTi2nL#QC%*QNK z8`rmpY|yLBlfiX1DGWL~?G;cJst5?$V1|pzPaPpSA}G`Yvz9Ut96F93AuoweOXXEy z)?^07c_-tEGR;?hNLhNqQ8squ;m4QYL&gL|8$}>ppj`1aSNyO!i{#VevcaqY&Hma_ zNI>B7#qb}(|8+#7Z{B|L@BIwlf4~Y!7&TZ$nP2Dgw?8<^_tV!OhqphTzWeFxhvD^S zC?MtMzvQSC&r{qa zE7@RIIII}bX3?l~yf2Uz?P=?Dkt!rH$d87~Vk5xn31ZA!f+Ph6e^og#8!e3h*^n*V zdYyr{p3*Svz6a;O1dCZtM4*3B`Mm&dD9LH%XDF$!EGcgxA%K;nV*SYM9VP#jnxca9 zDT0DM+_kW53;Rg}&;dxsXiLJw0!oA3a_V{1tJY*hM-}8@SPx1Z+n}0J(Bc=~WpwQu z^{V6!MurQtG!!)J)%KiVnL^FQ>HrTxUM8eP(yzR&o2YU~Edpm_olPK8MWza3Lh-dQ zn^G2${97~d-Dcc=n8bL00C^>r|`he&G9pr+Ld zx*42!)4NezueQSO$k%M#lEc|ce6ql$ryANidAH^G0>FO)EW4CNMc-e>XmOT_ajZuD z?*-iCB29%&^saNdYqZ#(CXnzovUq=m>ZqJup4_Vn`@s88yNx@>jIsh_jV3ndV8dV4 zjC`OGk~V^Y(0MXIxWuxQvT>US!b&gULQpSG(^{yIetty#7A!uZA(t!!4rA^K+HQSR z*G3|iLqq^cHu%kKHhVx;x{0be8NhQ^$d5guGNlZOun&`40PaVeu1XE2`51Aku!5Fs zXnSIs!|1od^mU}beR|0p0mdlBj7>AgacQ97FI%eFzWoHH0*k2C?pl?VvR-GbiBjuM zDw^t=V&?pNym$rfQ+uFqfg?~YW(bGbz%qhq>GUKdoGW#iWw{u%Q7e~h1@KpiqKu@V zHJrJW#!r3$W{P+7PU(oih1L=&yRj)qr*QuD`OoG|Ni;mulUNJzJ6mr?X@I2zx_J@9WuiR^|Zuf z_F=#~QP=E_roST`bIefYj!br8Xa=h)z-MYDMn+;Ztkn-XqFj?LG)KYkcZM85yDfjO z<8iwWZ`xcz{O*z)O>QVXM-S$Fw3eJp?$~SR&4LXh4Jh*-(r7rt&cgs`o}atxS#7`4KM)ifrSJEUnT6`cjO*1OV|y~DU{L+j|ytlf+OEg8T}`4_oo z*cM){6trDZxoL|%XzFRPJ=E>ZVLTX8_8y3pn87fh@!HWtGc>JX%Zs*qO|=0iB)9AL zDMZCC@%k~&m^6mMEXh>Rsv>d^ZCgrApkAeXR(rT4$aY1M0nm!&jcv9G7C+l!sN0{^ zH6-j$2^yH4Z60WeDfJMY>)OZG$NZUcdF&1C2$Z(0h2zUv12CjPt<5|gE{ebgorWF6 znW6Ufv0PY}F~91dBXV|-(_Ky1Wdpg3GTJKdoPZD}0ZGjmI#Q1tB&?Pq$mKk=PC{mX zsc-j#wbKsj9G7=W9HvB}E!Ad{oF;?RsauJZpLxeMc=e5_LFUgO%khv0PbIUBGh{Fp z_fu#rtxz`wN&0#ZI9JuJx=Y1#g>}M}a@Oi)`#cImHt}$fQX+LqZjc6w4wtq!t0y@` zSVgBv`9kZdT{`Mwn>q;4a|TyZffGra>q|3dRj*g`|N=O95!>qqP9P>mLd35YZjO3op^3zT*2Zfca|9pKGn z!_gnt6YUzN@W2SJV02C(96(*Nrv2~>c)otp(@U6)^@B`9qTG}4deWlA#Yd*LioqQX zWw*qdl)O8xP$v5rsR@#yv9gDjm1m-Gn9r9Pq$;K2uD2%*J;^t8KrlFixg0n8zTnb>#%i^`9ljz2~!KH^DDHMsNKR6k8OA^){*%SjvE&&oDM=gMUm_(Jdl1K%b+&D;t(jzfH8 zQzl3WDEGm73`ME6og`VK7yC)SFVYpcO67;FtZYi}f%e{#vUF?^#BEW}dqSc@?SQ6P z)>*U!*5R;Y8sHHFA07u|$PL(+lCJ?^nU4$=1Ivp|$2xr>mGD$_?2(SrB<>*7{Z0bmM06GfW)fGq< z$YJXCxKTP+8N*lss68?yV7Zpf#$}^cPh%tZblz8qvSX@^72q_$NR=H=g=WbUB#{V3 z3j|haJmBmg+Ktpw=*JC362dGgKT=6gV|VH=@=qTs&M9Rgdh&hG28CL#b4PBr-Mjm7 zm1_rLu(o?edFIUrtnEeH9pJex4+2N$`Jgnl(9)^WB%g=TJTi#`6^gXN8V$I`u1pNh zcC%lSE=;p4M?W6V{*tmTm284Sz6%EBehNMwkTA}P?mZFeQL9xLlrhyV z0n-pG=~R6e#i~^@wW?UoR`t|RNGxn8J{$-LJGkXQEUi0h7_%sQ&XQqyyS=3d zwCbIZtge?MKPwzKKa$jVg~T>^SLr>b#N>?&=%dbM3}XDKb|MT{i$fRaaw7PNxptknm= zxp$FY^a8m`sCZaG$<7AmYDw1PvIv*lK&=pYFNOiIj=IVo!rzIgt& zz%wwS-$Ug>ByrAChO>4fDhr%Q93TPV`tcFuXkxh5)-mJo!O9E{LP7s!G72f5h=t=k#Tw5geI=M3u-hPp{eiz=pwypsPN49Z1^UK$d0yk*9 zjLE=|16G_1@{0Aq0EdOatVE_Q8F*gDyL@#Je^-3ZWeh->?RxK~xN!t0{@AfJ7g`+fIM z06Q&2YU7WBXDp$EB32VX4#Sh$lpJsbq0{(sfXBwny@f+#wB*nS4-gN0(H(cFfS&48 zjnVIiXFz|K&tGsDkKQcW2pZPdF@Sr9iGh?g4LWOo+;E2D5&4jZfbvL%&7AOH4^BLR~VB7X| zQP(8HUZ)0nP1cdn#x?$aCZ#|(&~DatyyGIhUlWy*)a|)IOt)Nt&Q%Z$+tkGIY51NL zo?smVi9@TR#4uI3w0-NR2>QpNah#Z39=8NKlS4u45li{0ZilFfR|7F&mBBFT@T5q0 z2Ir(*p5W_e%(UBdN;la4L>Iq@o*F?^X^3FH`FKNe{;4@sF99lH_e;ukY7l|NRCH3d z4={RE9+N~r)abX7geK5j38W1xBDLPv*07h-fo*v+(Ugr6#@q3Zw*5IQ?im6_RK|FW zHwL0P$_Vv4|6Zkjm38Ev;>K{3NvMSv8_RI4uM#Gofm$xy#c@l~st7&2jB!^d53mYy zfXDD-lU$Ob*Yf?P_y(0Xw!l%#f@lanAgEA^bC^D)Y#L*`U}8D+6F5#&a*N$av2E}j ztirCaM%Y_Q(tM@7%MZZ!`SA6_BaVJ^h;)8-Jo@$PXC~75Y{vM@w|`|j|MRy`0{KWE zzx@#$-;dvZOSHBW-r<$pqd)!Q+lPPtclh&%?D-PPzX& zzYMS6zEcqUgeqdcl>dGw|H&uHJAc%F^N5n6Ys@Ep@-BsejR!#DKEx5A00Neqtzd}P zNZ%|$P+txA3WOaafb}?2HdR2^4fcb{0{XDSN5S)noAwUr1i2j!RIBQZJN5!{lUZAx z{eY>G+Et~&%F<&uvi@Q_ihh-^^Bw}KeYqG+mIfBeE_QDspfKr3hm40haX<&x2%Qcq#dJictxJbomQ8`WF zg;fs@%?7z)*6^hx&S4rD8LF?~pm?2T(af-K$T(i9)n+Z);=xg4FZpjI~ z3rsB*m}^J|YB+V+Q^-Sd^`)+fHkC}TYyw~j}$Z6w;2zeQA`r3 zhK*&0E$5*CcPn_oJ`{+2*0lp9N>=0h)ia7i;~6kMEY1Dat*sW14&j54R4YF_2#`|Y zTm{Ib0Ez<>8Q|3)hdf4~bUeqM3W0{x1;|m`=DHT)$tD_Ok@(`xqCSSpW{{B{>^I2( zGhVgZd$slk_v`E?6Ib+PrTDv!3R5(f$QBowbFLJe-jZ&tdof)`Uj13jyvx}1-X7{u z#`OdzBI}T(0xOZEx-D=hbf=W`byL(qkvJ?s25C+I?V{BD7Q=uYbMP>EKmhcvT2v&= z06Awgnj|7?D_~JsQkJo2_(8083!YV-V^>M9846Q}BvE=%aKzF1S2aSnb)ICUlhx@Y z1(Vq#`W)Ob57Id7!cg35WV4Sq($j#W?cf)yZ*?ocU}y_zwz zgHdV=Z}mD~2{8!8gBvZ5BWs6pluSb|)>;x2J_4%lQabowJN)>t7-CV2sB9H#OxaP@ z`qZCY32&;QYAcuM-lSA9*gq^A1LSB<#hN?s?`~EQxJ;R$==#7cJwE_~a^0TSgAI*7 zLw5e)KCVlb_!`fN00Yo&ux?NY1TFsr;2uV@R(k^^hF!}j`mj-^K0@gopqS&yl4Puu z2I+9!*`ge;jhqX666|v#eKBNBsi1=*m#_W01Yy(bIiyPvWy?3o-@zC9FLR3WgCB(N z;}Q7tNJah-Ob^R&1izyb*VoJtzIN%be}a|dj(Pn+yGZybz)WDZFg!DF+%PP5YOe$V zqp8S}CQJHbRQ{GTTGzIFvRDJFRxxF#?DtC6ABcg6k^8bCAQBp8Kbs!Qq!#H>Y1S355hVFJFeXn%4;fz_JH|LfN3K><|#U1>9T$UZlYqe;5DA*=`Z%A;fxG!AUt3w z!=3V41!hxZ51{pOxA3vmMCZ!=H%@5S94+zhe)Re;+`|-`w@N?iv^Rp9WYsm~j2Se? z5GU5rYJ|)k<#lBusGD^#Vdzt-O?V2a_9gJe$#S(mqV|&G^kB(7z`jO)qUH;J3nGISP)lf}JbELBz*|$|D zYo)>asaJKK8kgdT;a9ap!CjP>GDY+ydD2+{e*%YIeV}7DbWzz!GN+S@GF(7h zoGiu8rjSq+pCcT9BTTfL)K+%_gS4B3D-_;jL&X|E>iQH8S2)>4)#n&|32Vuli7+xP z=T<_y3ZuoVvCKlzN(IvF)2O|To+!gzS&ZX2K^4VQclC#`c0Wu}+5MADtHxl02l6IkVB@k7D@~5e*KtjhEKxlFR~cP zC*iO2Lm$eUfA~Fe`2TwS2|5(`k&FKa##dH-KLR=|yQ(GGEiTo8oj<4@Y4m~!X5|m5 zfcDEvc(GzX8$i`jO1TxRvq=ZE$9pD*~M7oUEF{k`d;Bi z?Geo4QRi{Cu52zhf$k#5dJusm<{8^rCEDrW%Jv!amV^duoU@VxQVza&6Q?7sX=2m5 zA18oKGy3=N_mtO|*c)i2^a`7|IlZC35SzWIz`bok7Nr|E>W51~Z2TxG=ZD|~0BF1_ zprf$l9WZ&>cj-gSiiVYTIQ0cG%|UH#sXlOj1! z@s!;pB}7ORS<$8klRXjz&{1j#aPx$jz8v-*Jn~%AvFSR*85N-9^61M$vnEIIU5=YB@ZfOERcm?!ih=$qbRrUcUCDOwHnF$?YuxupoTnW zi|@6al>Udl0h{r&6R=YMM2*9Qu#{D=W9fmmyw#;}1{rAJ3E!A|3kl|8wtR;_Ij+lIp9nXqNZ`Ox;N*A^7;hZ@gt={;Lt3#kiPHo+$Cz?ZC za}dyBtzEqm2Ci_*KsWPUQIFvqFhKy%%H4fofi3IpnJsxVI;u3ei{q0h7Rukh{Ojj% z{0n0BKRO=$^7TVbzpZWl(d#$iz`cD0lP$pCKI9`me*3*X^7eDa+MkBEZ*)G6*ODJ^ zpQ54u(}0e;GP)~Ud-p`lm25R5$Z!HB1umSOwRpyXhR&@ojz56~wmxjiH62+k5I6FGG*C{qo z?Tr@RYZ{1KlO^nIaTpd@;NDa)(?ZY8JBLzALz83nqM(mEIID%nwz-wtT{5>2flFhF zJ*b-|ubV!)QY<(qGfL{Mf-1H}yez9b-=jm*pq@yHD>DqqM31fZ7MAnD5{+-Xz8)T9=F zmu%a@WKS7$23yAfaKW&`QXDu~7}QABV#e)M4f9OkSOtpqGa#x0!b(=dp#GJ7(vVa; zM81`+Y#5=(3mX}l^Ifl~l;v6?C8$cxhRf6OrR5yYiuT@yvhD2bVh`+`422I5XRE8C zF)h^5W%7T}_rPr)zFX?9>n`sSw_gaL3o|J1D*lO!-s1ESsEpQ=beIR}IyZgtvd&Fo zlP7~7U!GEKUJ^$a$i|5R|77-=J5C|(QVJb`L-5?7sLCL6+^<|I?Al5oui3%IN-=V> zFNqC!2g3;h>w#GA*amNCOXfSBV)1}>i)94`v^{Qi_+ydvg=NW%dB~{`|KEQT{vM8* zfA{QR{mt7){~I$c*Wr|nj?H&A~^o5P_@ zhUA(QkQF1gTfv7(7 z0eOFkZwS9mlgb9!Y(T2zY#3Kqpjk!yP_t83F-yPVkqvM#i$Q*7+>Cg?O<8juP_Llrls3+Wh9FL2J?2I}Mj?6RC= zCNa|cJ9f%h^gXn$skw?t{3uVQl2c9*T&ibo(IPm_XGrYGiJ)9}1v3X|mFD9yM`)7D zEiB)ok;BG%WrBqa^AV&xim5CeBR?a#8P$V(W@BT*tn1KU97poRB%o!GRJ-_iQ78RX zJ5v8oSN3=UMyh1s9$FPBt-LAI@4N(bZVhnSi(7G;LrDw7+(5r=%{TgZu{~dWRowgj!YB^3BdBk1C$2a2XWj533&pL}6@^FAx~pzCd)VWgjkw`* zWsmgQ*&)vjzDV*qYe%#@C|BG8cf`tX=xwDPF`nTaohG!a&ojgN+UOLyrqEfaZ4Ik# zODHa;B(njtvtS-P5N}^8!RJ(sRj79f+=u5x)t1nw?*mT*uBT|cwaByqKz5fMl~qGB zsx!Pc?|O1x5Smwf;1Z*NBPI`6#aLJOz`Nyb2zsvyRF#F)df~WB0k6z5r^J$}!iN%-!c|Ma8NL(Zk6YaS}HTc0F>vJuE5G*T<=5ZR0&&=iD z{T?VZ)8V3@i8b#C2!OW?1{88&@1TGK4P%h;3k>k`rYsRQIJg~%zb)J*51dO-7$dZ& zH94FQ;cB&#y0%9tEDNIqQ~CUI|7%n&x{;dO>SD*r7hW)qF>BITfy#V<&^pXOEWC&B z{^{+<^5dmFWkpJh!)VlmrqHwrw>mtj`%#^#R+iCP(#nghv@}BPAg4oqJ}IdJSf&CRU8^pZRR4t^&E00I zA8eY6IudMikl3dFbMkWPKslp5ZFTbqpjFu)I)co+AnS2qrRgt z@C6xRZ<`?b=S}!3%E6Y9EFa4}q|}P4y+LtxaeqzBhk*c~O0Kd7rfv6WlaU9=}b6_@C)Rhfmw(b~XOv%}>& zQ@eeprtM~rlWfyNib8HG6&T}dLbu;gL>07)G5>})xv{k_)_9lWk!KU$S;l?hWosox zsYF3Z+F=7J?dwupM=++GP-^NggJg>8z}@$^K6ReAeXZBl2w<@Vk1;t7I%Eq$SEsA-bpXY z?Z3-~099OM=uEn9?Jz1n(#9QfTPmo*llYqwW{r=a!U-L;UNFHti2t`NA(l_4T$<>+ z*=+X^2H7S}ho#Czp; zD9AUodN2dHi}d8&+V`AU8@xI_9g@;SMm(Q8mHy4pb~^Gd)1Hhwo#1a)S?ye>im} z#Di$Kv_`H`AYOhcSsNcGS(+Feqne25Q1RAsulgPe!6 z1pE93YogidfiW6 z%w4GfbDNCHbvsbnL^70ixsEs1dDpOI+rmQ(;xek{M2TRfOGOSi$b813eV3`rdu-Zx zL9U~)2_BF(Yk)$@)x;0liU>t$bVCW=LKINyb7nRbTWgkL4OTjPYgrMyQo4E6OP&4@}85KRjO0{7efKLSy0D^W=9lqW^1NB;^H>?SQ* zLh3G=E$~c;j@y$9N2Ln*kS#SbPo)r5s6DD=HlK#(7KgMWuy4$|K~aY|a^8tMa2z$b z-ghcOK=$M)E5}~tpkjp>X$x7YR70YmQ-8>=mz~K@4iX-Kh3*0|Qjj`q$OAxs0szMa z4d8CXPJN^XuFYj(dj{~qEiztFHRR1jOLdiH* z;KpAWh`0V^AR4y;j%uoIn;1jQTUDu!8(zwkRl<`TkUsJk-}@8v@8>Z53wDi7t4%|$ zgx`-|VXOG3|4N0oA4A#OY&brIeU$q;{fxFA4{)`$h@CSmYEd0~7@bB{^<>R|PhmGd z% zbw$LK@5TmlNE>QdMe;V3GC?tKu$LJuRBpYv(_*DbCQ9kFQi81tWvV>#hgOcEWS-Dl zJ0rVfKWL5$?^zpoEL*$ogKhM41)!NNMbIh%%mIb)0?qMpRW(_KXvwMqI<(trPC&9a z7E9I%n4{)2hZ#d-1$G&Fn>?#}kzF`IFk3H6g`3LF3MEVrdy~u<(*2AunjHvX#Bpbk zm-~Afsp-@M=%-~d{B=o1T2VCt4M>&Ly`Q8uGom%BYxSx2A$9kT2GdEBj}QrPk>xZO zr1Tqv77j4hC8Aa4JAf2ek9Aq%A*-zw1W@8ONG<7z+5m!K5n8TQxmwQbFTWp`%8k<~ z+}vq_xwQ_Vd3P$7lpEOZCkk;r&vVA4Q_--Vj=4J8{_@HNgEr`e3f-vVlQxXCyhoT9P5SL&6I4xQJ$-|3}hrG%uk7{U$UzDw5`VxE_PZgx@C~u_@WqCz=hE%W%#7f&Ig`XM!zxA1*)Bln zip}oER;mMd!PqKyMyX-7)GV`3hhjJ&rT9{WLZ#W0-m;K~+jZ41%=xM;2Rou~1te4# zPe{Wmz$|p1F?MElSu8^beFv;n_Sv95R(TPNXG)NKxB=rF8`R8XN&@0+ePM_S5^4n< z2FRUQ1Xf2*MBm5A$WcHEfId_buP67(xDo~~S4$HaK0gSPh1UTtXJG++c~(ip`50iJ zKaMV$(?sJLKJ}})UC`{}xk~-;dsXV&S8t#Gdq2bXA2|NiuVB;o^hy9R%x zb~TP#;lctOadyV&oNkyBYwZ**igZa70Rb@CwMpb7!!&hubNl7GTishz33vgsqRXYO zN~ClX)jCwYIM9?>-3+W=TWUG}56)5NTWFm%H7v6DkfN|uu5Ggb^;EKH0Ld{zI3Xr7 z(~cR2Ja*IEm>@p z6JW9-^X||d$coVQWP+8R+?mk1wXk{#x3dLNXf|2oZN?;b!$CIR0QP3sYN+8(einm(08=m;2^$EKD$Cwx$}2HX-fbrs~ivAC)d>J2AP9 z@x{O@l&yw^$3P-*d$aBkkVM;jYSFr!pKhV7Km=nP$>4X@P!t9CYV z3$2{3k5b$(k-US};r-2cSKSxhWeq$@CL~*KxzxyF0I4xAe&yJ&5Bn5gKeVO#VU2d1 zHLBwkwI@)SRmeEPMnEdm8sa25832YFddg|#{C9-g)~c9NBo3kQdj&I!p_Vk^8je_` zI$Y(bxdHq_5&a}5=Wow}eC4D9l&q&07vP6=h?J!iBWoq?F5HW~gbFgOt-Rr0j(U>3 zRjuRd=&CQ6m`@tBKnJnMnvE3C636urn}EIuTz^)v%#JwuGb+&>WrEUh&4oib;Nyn~2Nj~!Q!f)B~hz?qC zkP4!+E);gHqAxk>iA4j5c3MwS+oKs!^n?G6ZRPL6+gHclZ^GM`R2_T$?0wb!f99us z5?()qht?-%Kk_ta&X&th$-@6f-txW_JE_P@@gL78t!CFa5nYXQ!a7`Tv#`3b2!Qni z$D215s!d96UYgTQF0mZP<&Zp-#%#Ffu||W{@XPJ0ooR?Y+XJvPu$eT1d2K)0~ zk-Hf{XQ?!{+3RP-5j!o|Nej*Imc5h9hRWp_U#b_#3icx%urx|)hrr29tC#Qtck^CY z?tIP+N*{Lyy|;IV)<_clP>~7CBrtBl%(-l!O<}yE76XKg;IRi(2MzKdmUjaYw1y|? zZS@*DB*7$YY7b7GPK?KG;xM_AuK?o*>w(KHprs8IL|X--k$nUq%o5l3=0oBYXkPE7 zOOYq{qb^glF_ZK(J5$>+n!oveT)r&y#Z{V7}lu0}e-3@(tBmILmu& zgl)?ah}TSeR&Jd=EH9vP-d#8sCmlNk$#<`^+UCXf+V-%sJlqPP8d6fS{t8K1qX=L2 z`HHA40fM(UatGYigHDlCp~KIji*}!6@^IblW$Igshzt&KXtu&z>d?j;)Y0os1+p-8 zQp!v2;@3(&s&xW8>5>geM6+4*IaG$sN@ICQ)SWj>*JI(DFXwIp>Tqz9>scLdyu6p% z)Q!DvOjNbv&s$Y+Hh3!g@a(NsjSJ{s_U+_&$O6|t#cRi4YlhJ{H3-NR5CXyB$N>|2 zV8B!%8kGsWCh(o+WqOP3mU%4c03H^n&2$DCm%N{4t zlNh6sjXI#*-715;^~}+Au|3?9d4_IShZ1}Rh(C+8@+cPQ)!P$6-a5!i5Cn(ZvI~4K zx@s)khtOPAwWJZ_kBc(Gg$_OLp8l0`c#CdFsa_tVP-sxgnqwNDOV}2gy{LW>fzlWg z@^K*hBB4AQ+B<5K^y<82uPmi(XiHx_;l0QawiIG_u%q7n3HCFGZ3>3~NdM$WyKy#)@tqW2qEtO&rGz|cw8-Hx4uF(O5LY1s1SmE|Y$zoHvrt>HVPLQV)TVL*qa)3cOwKI?&E-0M zoUToD2`!-dKoo_Z*ue}7?gDEhu2J=;ZJGca!qVJXuA)#^?;hxu?(*hi>DJaWrd>AC zM;*aJzYKGpY0T*L6dq%-fnXIw3&OI^!#;OZ+NmL>EEW*06253jc%Un2;)XjeYj zP^z~H+ZoB_1G@PqDSZ-g)e1?~IoZ+As?e;6!wTAwJpf9Rx{H<8HYkD90`Q!X9CQKL zgLT2@;pcNoxzuJA?&|KU7jCSm#CErix}Vy!vV<;@2EABx#vMhE7SjwJiPXybgf2nx zn|if*+rl{J&bCy?dzkQ-CA#vP|DUvX>zU@d&cyEfS8T->iIExmK0yHgkMY>3!|tl; zI_RlTR~ zI_!0N4u$o*A=Cxr^b(32<1yTAWT}Ek3&ud~8zItCKeR&?ZE+f;tx@VYe{% z>Yaa}e5Kc~m9O+_Q*YR;+MV~5Jh$$E$_AyqvbOFn317O4_OS)hwZH6xf^ilL#85%( zR~2qZ9%6#W;(1CE!VNhL(AamObH3XjE*BqG*^|*Ibqw%cwDw z)`oR6=g~)uD&l$6+Y^nF6f1`E-V!1eHp$krWtgPK+({H+i_wU3^bkXyYc`h{ar;P0 zg}>K_RptAz6itP12c<1yF8;Z(Q>RYtXdu1-1jbMUhTI2$e& z_I0>q%k#U`8bsNyM^Ql6+(o6Ps0)Gyk`?BoEa~X6R)>Y6iipaye2VCMzoMSMha~S^ z7XDzS>>lkzuijB1Ihv5mHXIkLh@rB`&qqLEh3K{CIU0& zri|r~5Ot4>3F7aJ*G&ms)iX$Ig!cAH#RHHY$Q)Skoxy(N{V{5PFA4nYYR@fque=so z=OQ|R@t(fb>DiP0ox!WT#gLku2OSqzA}+?h^D}8Er#YbgDLd zL(**ALN*kROIDYCRCyW-rybBE2zG7r(HTf$wI@oS<^mKxM!W$52?8Y5pjMuavz8DJ z2^Qd+Z69-^&iPqa&8KeTn>eXae>k4q7*B)piRdS|ABcXOs@%*teg-bOK#t_WFdD8{*q0v@`BDe)g!f2tPcoX zP|(#S{6%SAFp92#>#HOzPsHlU^JPJ&lG|*2=jN{Dsa+FpKkY~G8KjJ;lnz93^duOU zyP8UT34UW=m0Mbn)^ODkB|6#}{nMpjfX#3-uR>k)ai z8`Fp*N)*$HH7<;M0P6;)Mkg*7mU9cIP*$wDgL$)|R>Sp0UM-S{A0#MLYF7XA% zmz(~8G@!~VNDz;qLM*7KLUu}yN7Ui%TUmnV+jU0+0*nf!f5pLcO7VQz@6=I?{FNH6 zCX%~%;l4;7G@MKnbBt$Pk44iUds6dwmSV_N>RQ&M-mr)ui2?jmkCP(c6Y{;zu9r+7 z#*$)YW!Ry$0+=Jx|4Fa0_Ybb{$3sS*4ZAFa0FW#kFcesDY;z1G?`5#4BYitRYrg$e z_#gF^JTU_APQ>hQ-adJkoA&X)kqv$JuYToINx6O=!%yD2a|C0`eY6qyILf z7yZgJP^aqw-37XesUVA?2sC9OC`$GMgB`T|#*>|~1TZN-?uuU21KWTf1#oCXnB%d6 zUtjmBh6}6PU$2h>7gVxI%TSd5Gj{gX5w$5$1riYQhyrSc{W$u>c+$t!xJkQL*)BCO!yXBD#) zsH6hl3r7AUb()qe)23EK;6lg$hrQQXIw;>Pb51k=&*DN8{uDTAZng>OfDiiBrZ-KTz4_`0(Qwx7uQ||3F$Hg zI--NAR!6p(VFb+-Wb!6C*wt5Ly(4ct^azG*vZO-6>IbfCkox>GEJdJCNpU>?LuaG8 zp=n!qA=+{yy8(lauCei##J|c;xU2(_V&t=`?x!bskjk9X0qw?n3m*uA7Qj~9yGa11 z*vm@Uz<$JdfrX($yR0jLylHb$8H{x(h=v*BEUywg02xHx&m2Q;DoF@RH$zcntKJLT zc&pXBl%Xt)aA_9|M|82F)4Htu$a4n6fq_lSMW+rAGd_jo9u*9e*Sb2(R3q8}1|hGY z`&&l`i&qfw(tlyvj*Q|Ou9C*WguRB&8k(l0)4iNZcEuT}p>|JlokKp5LIh6Iu5cRh zON7bC^Y~ITC$;t3o42y&(p@$Vh(~TF52ea$myu;&I*z5p0Jk9@U^5;uawkb!Uq+XL z0qiPmW<3kJ67jlb6AQQ*3lnON+BpKjQ6dE@P=XJHYk~hkcgHLlWu|Q) z|K-;@4G!-=Cp6$0GV7A5I)4MSpv0h!@!vlEzYE|0nC2y_fC~9=_dq{MqkjJSZTO3G zOgAk4XK!Cnr{xcnCI5~`-1wXdE}z=#N9i{KF!*6IQ29ktMAe8dFX`X(UGKkr{rYK0 zFAVwR_`vFKyIsdYmim`S!A|DT15SLK&0-$1c0Db$2Otehx->Mk#P6-2PS7#fI;fh> z36!;tpbA^{s*Q%pLpu7U7F-{hTW~HqRdeJ#)zfg(nsjp_nG^ z5yTnVq#-+0NC8?;+i)e71-@n^Z{|Zx6bn4TC3p&s(g)!`DBI3@0zld%@Sa*= zje@*JLj#bpTusSuns;r*AQEA35=rT1y@F!o!seJK!;9ZUf40!xW4F7(Q3k zduqJz)T_w5MdYWfi!~!Pl#PdV9tk>_T^prGDyRX2AsI6m^;&i`LMwsX(G6-DWDyzp z#5GX=rrQ>Eg&^PnIL?Lg5M9XY^x34azaqdw7Gku|+bX93fOrQ0wg9LT0}6tGeWz5+ zhop3?E>F678wcPB3_2i@xpL}!vq~Xq&NhwQcNSPT#66bmI(D`A3g{Co+F8wm0+0Y6 zr}&!qRmz9E z9c)Acy)9Jlbic&1M32IvsPd^8AEgkK$93yY4&hsW#Rm_EuA{0Lg~c*iMfp$OmQcoB z2?ZC4Ea?bV1rqB^7zueqg$9Sb8NQcdzp8Z1l`(do+%pskOD`67%N=8g+opz+_Vqps zcmlJ+QN~5*L?3y;Kn$Liw~5*wo58U ztT=p2rD(2?#z3_|2yI|rV9ZMO9#y{k7PaQz2rZPmWUAwd`L5CjP~)`QEeGOdRA027 zMxiUj0U^qjcCmmiKkyC3qytOSB|}U6u+x_0a0AvX9xhf&>ogrZ9jlRB(CvpTrrf>j zSiwDgc9gtQiIixr>Hz6jTOR^(H@QHv{LsS$Gc|q$o%5#69Efz=sze z^bWpL!rs44OYn}vw{M?P;Kn865{Vuf?BS0;#(?Bk;q9jv$z#3<|6afJj9GY*`n4w4 z0IlQqHc1yR(7fCX@$uM$H@_Yc2*Mo6bVmr?BN9f4y127z146-^QNk6vx?{6|PoNFh z6N!F%geoN{>n4RDHBzyLQonWFAzX0F21zXzG^gwf(7?2DhPs^1E~<)MH55;~*-N1I zrUZYvVmISXE&HsggYA@#-dCuEFHx!EU~Bp^qt(s!Ub67ih3t}Do?@I8** z$X0+vH7@z^bfu81xI^Ir#cBD~ltLe|FwB?v9;had*@Yq;m&rcR+)K29KTTvzmP$_jQoLFkGnOT!sxeYjKP>IHkX-0}JX$KSme9D0y zrE*g2EkOT3S^83^>Z=)(U_DBHO1Z5FAxNpYpM~T$ zXZxUabMV&38f}EMjiGbriG!-#C2U{=Ktkot=JFRRki*<+t&8Z;TG`s6>w74|WqN4_ z-z((_p{#0`A@)i2Z5C#VVyxMrZJQFK2?G9FoeJ9YLaM@iyxBG$u2crJK?OV|Fy)?S zfb0khqT|-Th2?Q+6gtGA5QZcV8ltEOeA@>a-`3b~(kGezOxWj(p(NHf0@KuKJZa=K5yj zK!PJM$zmed>%b4X7`i&FvxO)aLfk4)3v_}z@t3Pv34~c_zPJfzn^M4DHniI>{6x? z7fCY;43Ee$gkqnpRn3^p(MLtEY>WG<0?INg&~e-x!uSlN6`&bQH&wJ&>|5lQmWTCu z?X3!2P^~W|O-oiNt)~${Pxd}~h^VdZ))>gP8gN?8<6lwbdRif#pOO$+Pb9)IPP^TpbXe&@l6YKfZVt8kW*D9G{~7Z zrCZ*kBNf>A1U*k}%Sx3uM;mwDC*uF$E#;deBd+lIsn8r>7f1esx%_A@X^4qBo+TEd zl(~~UBn5C#-WF;rMG(kPSYGF`$K$$4wWDZ&l5>5ukti0eqf&_JkYhI{k0^&E05)TP zLu%wYN?sOcKKfV&+?fO|d?KQis<&U3pkp!;<2MW#(q>$AU@dk1?JS%FN7dGT;RGD+ z>@&(q#k{yiz$~=9C=oqQjHEDrh&KzJQtqK`XWyQ!u!vZj0x?xi?%q#$q&b+Ld|;)Q!+k=n*~S=q7Q`|xI|3yDivP8=`gj+&;hP3KN*w(&7nI4H|x#i z-o~LtG~|QUXHPX#Ho2P&meDSt-egKN;j^yV>5aa$l>Y|VP}bj;KLd?h*JGDooK?W< zh1sX}=t27gU#<~r^HBxm<&80J0`I!G)k_CZL)CO>r0*C*_TE@8>cf^Bv^WpS$m6qP z(;_t(Urs3NGAYn1srHGQZ&jDbf+<9ztT1eqoWgDRYHHl2_h*}FTgbMV8sA3kOqjY{ z(}!kW>?+>0rFH>wvA@*&1C8Y}yPzBou);V-`PN>lV~eY^(==Qo=3MQV!mpc>32F3I zL1!i>DjPa7F11mqC#eO-R3u_xKJfrxN1Qo8W|gD>6h#rja*I4l9l{>voh4}t9LJX% zA7prdvDZXUe}_=%{p~s~9EER_B&0eLuNw0b&s<+#etkH(~%B>W=^K>T>Tat z`8le#;(_spAuAbqD(=-azBBKma_!6nDOcb@?It8}t8w>EP`8Z)jX66DXE^r|8@NcS zVc#LO)HQG}2Eh_M8zqZjIa_y@)73C4poh(1knP{|ttr``BTLs8$}aytW-zFmWlh>aGQZ1grA+Jw+4;c7Y!9`^x z3g67}eGgaTzE54St$vln@oq6$sdK3AQvB^v)!dt<(8b%H5hN8%(V?X@v6(^_ZfH0w ze16_x4TKr@6;5B_#&8H;pUrEQ?Rp)%7Fu8BNhMXo9>?OLw{i?nDTTe*SD>L%$#wPc z=#CVNJV6kc<6hqbh96h;iSl->mi&>&~lJ+b44ML{Z3 zmnJoFQOk>D_03aR)x*x?__lsYyxnRXo*A{|K>H1F=z<#$DqIaq3J@ zW*lUf0a{0XGg@YevtLov9g_Jf3hig7)8c_4ZK$@RwXLJK(fh-oyHUXf5OuaLl>U~j z+yVJ*W9zk*GiM-m6*aMo0Q-cYX*XAAmHeq>Zg)c;+SKY4M(6YE8NTZhM2UE^O|vr3wosmg?j5%Xn!HXJ;TI+4F)N70E8(k>xCO6~h}q9x_1 z{J{*aKBclrT}lTbE)uI&DeRyE1FgqIdZ3)cRhFaV?rD|fO9U&Oku4L7z=zo@mtgUJptQWC z0rJrn^*CVI?*dCrAfzR+DpE&Gmi6Ldo@#&qMw0y|l^)_49PrCQUo)oJFguwhjpDBV zl&h33E7U;+=50q-wHw1b{nwInF#aeDm<+dvWKu6FQ?X-mZ3Y12lmmI?qoo2l5ROP& zvH@ojPQW*#lx4ZfE}!UqS>ZM+fBBc;FE2kLt?nPs@%xJ(7ix%ZRxBvfJZIlh3~lfhJTJ@9@yxt8}k zYz15W3$R?SXQRqf#92cnc#yQ9LsA>CepyD*bS*F*Y>C6QK-Hqx$X_a-<7t0V?sNH& zXPr*8ClCE}xzpC8x?b1IoO0sf0s#p48X|9vyq(n$=1T3lB_?xL+pP{Y4RB3?tV8Aj zwufw9BlI!t&mxv&gkn#R!5N1W5-;$Bn+n2oD!n8!dS~wl~ zPPEw$VEt;;K2lgG7V79}zeG;%h|sYgEp!B8Ijf`-z_V>m1N>{}-zE#0{c?KkbYGxL~(Ptga=G29jfv|-C;D_2Rw!Dq}klQ;D0y%pJK(9cux?ZW5w8H{_mNwMIrc*o+n1vg~lti6R6 z&sBZV^jp#L-G~W0sqI zNahs}{I$YChz(}pz5F^i4;^U1*<7iJ+?3fn?lJXNqK~!Y*$z=Y2%(YwvG0(5X)D zZ3}KDO-9t43T)6EwvW+L-dhQ zQH0XWz*Q)pqyaRw4_EN4Q&RSzTav=raI`pS1m*}eGCE7`u! zcFMo^_=OyY1HF=*#4o7}$Bsc4U(}`0l7$xPwN=)_{fxkCU{7WnUe-utce)Bv1<_8@Db3wK2;Ge?}4;kg#ZC0hWHsB$R}*pe@iv zfbFcpgVIt9!7M}B&8jl8YsvjSD7#v}YpFLF^a65A3ZSeIut5ckUp4w| zgtH|6uWiffpz`NotjTSLbvW=R{Vb7)48o?=DQV4i`jVA33}X@|!roKh6cW^uUDB3# z$Ha|k%9XxUY9fxN<5p0qcEgmWwI%|F*oeF%GY3pkiOZkSKsHG|NhCr`mvFhL1Pl&n zyEX1Bo&-UdIh4TdE8RdoxJo%0gnxj*{z8QxoHJ{BNI_Ae%fWlz;tgIS}Rr%F}`nv=*mE)j5a!3hBc$F6vwk~^+`W)&=Y-AjbS z5|y5|ceN>H92*C`oj07e6zFa$e zfT6rV>!3`cE64o4%XCBnWeY+Lk(+r1CT9-K61fXt_EuZ}uaG1|+k(aTBJU8=MzZ)2 zt%%kNc!!V#KU>F1E<2W%g%^zuQRJz}A+maM@4$GYi6CP%1Lp&n{4cA^5cU(qKqw6b z{7u&L8?juCBQ(TXrU^6 zi;w6k>$0Cc;zG#_Ng2I>%kJ)ivvx?;oj#e(s?sRqJRh9MHr~PJAB-2<2d>m*#n;&EAaJaY{r-a z{QGaer$_8pZ+`5%*WX*W<$p+r{_geb@Bc2m{*&%KgCRK7b!klcgA1!dq$W|xY+{6^yfI**hzH}R!LFre9YDj8d+&` zZgOaur5)VlRC8a)GoEyXzP)?0H;eo~wGcS@U7_FM$TqZ6C^ETh>htDGen2Q>1owgJ zD6wX;I~L??WJB8pK_R#VCAv-~TLgFO>7`3n3C6=wA032mA$U4P9BX#U*emvuH0K{jsg4W<@h9WFP3PMW4tMQpe z^OMxr)~K4KifL`8Kf=R~Lr|~^a%JsNrd#-I-K#=FT65V+UNl8u0(C0l)&WU z*pd3zR+8&RUk;#z&;(~M2-v$)79$Dw!$C(+-aKLNjC-KoD%qaA?3T=Z@nYX+=#s43 zWk6rhgY@|D(FG#prM!llh3lC;c|`6_@pc}op`h1W2%HsN>fx3-d{Xx(l7BAXcPY`R zIz?CHOJHb_q=o|rJHMz8Q85k9(6`#72IUB;y=}T+xg4xq%2Ce~JDj6`Wdwe83X$h6 z!^{C`A+Zk_dPj5;kRDQYf4~JvoBaeFmF1&YW!N2%Jhr)HHT7~*W&ip!Ej@*xk3;7pQ#+a#K7;*b0v}^?Klu_Z;ehzA&1t7&WHzAZ5N8w`Nco zlgJiEyJ_xF4N9>MUAh!;z}f{Z4dOQ7;xr(`$79|Ij5(|7Myj8yMllPDb?kTeQt%t< zh*DT?dhf3*#K7?h*n@1t__(YJl1xXTy0fx!pH+m}{y-*0rYS(c64{h{wj35_)XG)+ zL-cG}*vnmA6o@@i9m@Fvm_V7H7E)AkPcjFIQWJV<2llRKmm9;1kS}BQL>N>BFgp$h z5-yi&^J!rUZt<=SKkL(}FS!H?TdAZZsC^!=u)YKmob|RU^3JP2SsEyA*c3_WDV&ywf!i88U*Y6k=iy@!qd3}{106)rPSX|HFzAI z)&v6$h*qt{5UOdRPK?rlQ@USgm2$Ku8uHYD2UlZ`D%cj%YQP-j9%Vyc!-I`5xcN!M zvTwt9QT{Ch=I-o9R4BQAGhePdG7(n(a|0Pdfb?_P1YoU|ux41|{cWSvbb+a^T2(_y7-%JDsLF@LeCAGNec%=x zbCYBejx1RAA?c72o(M`D=tDX`v|~yc@~jhez&$$E9w7L!)1urp2-M06Eiu;Np`~{Z z2B&FDrFl9x>&qpVdl18wNA#_z+M{J|+J>NS(D5Jl194W8Wner>{DlG)Px#^-Ub9fD zN9K?xtwf0l*@nh8#0W8xK*W}J z<(B6`f9(%`Yqk0GEGwP&rSlBJnxJjnQ;|jW=A>kOw{|~XIo2>?LKP5z?az;2Pi8@% z{qb+ZY1HxA>vw!*9dF{ppGs~2Rl-C<7wAK3CjRv8{nvj!Cq~3nJQZJ-He;tkeb&Kz zW^Ksa_~|L(a4QkXi*yUfBVMcB?!s&R7~zdVx1Wau64NQhig$R?@>q7|?4ky8FK(*jTGC_);s_@Y`68FeZdDEQ35iF@26SpepSwX(;Wocfv0AdE z&KsXrNN*rYN$zyWGiFx>E?BL&XlsNiR&XVQSOP46SdOcIggi1QD+9tZv>ir?MCj7+ z@fRG*0T+<={fNUieYq&N1ol-B}nYhfdf#sl$g{O#LfE-^1#7r#p6n^E~aXCzmLg#2);vd(k1QabLw=$ zwkbGrR6-G8%$HXCK5K33cMDNP>M*yU6!~VP(*W+@v zlX%I2m2A^1V3A%vNasr0RVsFp(#kcAmL**=)}1^f7SKlpz8x$($*rYuCBpy%%++oJ z2nA~ewwz`ma!`GCEbX|e3>^~y_dB>MCqg1gT!Jm?QV^vQJ|g{Q9F=FNqv&pVSENwo zJ%B-F8UbuXqS*!r@2R;3>G8--?fWCvI|30-Y=p$%WSr$`gBK z{~mX#9j7#TU`}xI%Feo8mPAQAzf^>TNwDL@^%JxLPpCjB2Qp(QSdwIlzx?mRpB~}< z^&^!u{^i?m-ah;OlOPfPJ9Ik!IlTVr^8NoN8AN(pkY_{9WE~9k7cValTy&T2LBi#2 z+(#@UruBPTq8?ezYzXq}=vhcYj6w3{9#v4I%q&}z{U8?wPWJHB>=-Dejtz%nuJVjq z?u;;$gl3+_%z4g^RT)?z^TSR?xKIot6%lvh#3y!*S+Pw=%>zL{1N5#%$nAH?W$UyN zYOKP&9HN{N2_M;khg0`*)Fb)Mz?)hw7FPjND;u}~Ia+I(q`ugDsm7Ijh?Joqh z=!C>PsTv0mhpgc-hFb<&#v*Bb%g7Bs0usGuE&4CB>6z2BS4FR(`2z?6=432BL74z? z+AawMJWFnos4#3ZdZ6`kx5$cT;-kw@%bRSfhElmbM(zV%Sk>>yY%cvH*ct2LqT@(C zkUu50**qA-DZLKzk%Bc%Rh;~>e%4?!9~`GjlUj!er`&n%q5mv z@vcG_WDZIxZ?nFn=I>4Y=%Z6O(P06Vo442yksB%g_vU^GbhmOJHw?S5N>AIx94a#w zzm4s|!i4#stb4bJQ3^qc7%(li*-i3CB!b$w-<^z_C2S>3{*t(zRQ8JXN?$92YW;_U zD33hwu$_U>5BV-9Wq(XQjS}t zikuwSE4&K^FP=hUg>90 z9Cle~w~7`6lHF>Me8+hHL~BD*XwcoXe+6=;My>^%hp{nGoFHN=@8l9%7~OHMmnG8C5OZGDz0{wnBW?1~%lf7_9?}UUJKleE~=s*nMeFy9#x4_54N>TuY1q z*rjxl%1brwc^DdN<1U*lg8BG>zP3gAH9~VIZ3F1H7+DLL$gy>@MhCbvbr>NZQ~@dg zPlR+N^2U@@Z3B1RJmAx@Y*+Icus7#Eb2AFHyCoJu(tD6PA1)WC`94ts=)*%h(ajAb zFt9FMT*j#zcM2TLKnPAhAb3g`zZ0w29ZCt3^}sA&@;ID=&1vWfphn7HrTEVr zF69md5Vo|2mLFTuDw!;KDGr+3FapsJJe;eDspY_B$S8W*&#QdHegYzlSd?2UMb(Gk zqUMNHMCq}lEfnuvl}2|EBNW0{)D!@cPe!ukmV70Lr^^Md)p$n(z!H>BCoeXENHvse z5=5-gZk-?@R?bs(vaOOMfbB<3PuRokvIlf%4xb?@11OCUo`yo0UE#ik@cUy!|7UO& z!e(weSa}!lC7OfF7t9#?ZY8CJV6tsAiw({YHlP40eWRw;Edzn2W0`n^y%c1HAvjJ{ zgEH>!u0DgQZ0b1z>iz=bVOWl9uA)p&SxS6Y4*AZqu#GsqqKfDQzJ+MpzQ51&JLau8vXweqgc)jQUi5m;F|r3f!a zEGN=XoedQeted(OmMa;NV1`}^NtXHtZQ|hEc#HgQ6`4avr&CcvOs*X!n#(Q35mTOr zLOTue<;@nuY&$H6RbFkhGDz<6>d;5P9Zr5E7{=OG7$7QK$42Evnb&K_01bn1r)pq# zSTkhF{l2;64R!e|Y;cynO}W#Xr6MKDiJ4?(+T5U;i<@C1Bw9AH06{`dRq?=Widr{o-AU z=C{;CHem*6HhgNi0h)iSFRVMPYH_QW%!CvkZHxty30gD-se5f1dB7#Ftea$h+_;hO zL!S0`(gsx+d3r{0H-NvyeR*i^`t;ci4?<*-Rg&6!g}LPtEpX#l_?89QwqSVg&Zihl zMHRG)62Be^yC5CUjTv&efZVee~MiMW+$~?LfXKx zeOBa6K2K>=egiQh75V2OGJ4B9Z~UCggxHQrppccbW20E z^ChaOwl!h^s6BwhvWpQD;Tnfsk^-k+JjMCww_H z&vJ4kVyQ+%Q%5%gt+j?`^+pKbF&H^Sh%6pz#z0;Aw(}%{+zF}>F~P+F&^aRKI&f~5 zU;`w8}7@IdhODGa0CaN6#Z+9Gwm%nM0%E z9zN1QeKRSHVy(_bNj3Ph6qc*kkOwL97xiZxJtk!1h{MsGyD#>YV^0SX_~ zE_Ey+$w0o@`YuVne72Tn4D5Q8E7dT{dFzjWSb~0FDZqGWmX-+tR2};zA;yqde!HgO0 z7*ez$5VaEFFMo6&e0z|@)jR>9IB1jrdB=F?hn9B^Y>b7^rBIECcIpS9$N?*Yw8_Y_Db z!mxrAlT4k@DaftCkLb1Z!OA$cyL zbu9OAYq=X%Q!wv~t7==Tw$dVTa%1o;Y9P-cJ`jB7UW%5@l1@0D>v`XAXI%y?(=F>FUyk6}QZy%sy8$X*-bb}TFVLL6ZzoiJR z4g|?J1Rj{sM2RPuKD4SxH9N9iDtlmAT7PzKvE4(bbrmcI41|dDLquXTBaR(1eGQCg zB0C}~{gk!}PEWx{$R3K>8~d8vta@~f!MafeWa=Tr?MV0~``u>fGokKJ!_RO{>-D>~ z#M7MRwF47-8rD?vo@3(NW+!E)!7)Y{aL6sFyfecbj_RQ_9NhzjDcZKmDiG`daVA&I zyxv3My%&7Yo()dzDYWu^&{sHG*_d5eVjsa3aLHgDW;@ghVg%hKX%mh2W~OanhwdU| z04|`D7*#=WCmoCr3b!Sk;eUn^gk%hGrFHF6Ss)I%CrB+|MfawHEDk-~28lB&%WI-p z!LcA6NeO7FC`5B5N)3qR07Jlv;2tm90Xb6HGWl=lcCm*Ny$A&Fxf=<=K$zn}c$sLm{rDf2| zyDgaPT;700M%U)d^uQagi%=@xPt2WcgIfjb94J&2&Qns zx$IqUmJCu3oWtRR&>b4!6CFzrA+^2sEn*A-Yr2-rtewaHaQ$``>{ly zsLd>){HyRk>FePNothC}du!qU>udP``wM=cGxd&e#Fykue#wc(r>|dx*Uv8BeEPlM@M5x7L%i0vYKc zWQDTx3b`uo;(os@kQYvA%eE|ygw{Kl@a5LdZkjqTM$w)#i_g``eNttG23y=1+X;H2r}frm*Q1-BGjEZUa#21+JGwDB#MCen?k6c6Qwp-d3ba`ak0_VdWD(?TwD=eB#Y$FY z*v?|~g$|Z0Nv`o^OVugguZT%JvbT^YpSsd%1lSZ!d6czn-Dpj2X$xl0NRF+~)v6Wn z?gEq$a?d(YX`l{3re&AyEGTYU4hvL!YqwDX7zC)9%dE~BX)9|+~(Shsbl2{n&Kx!tzjqinm3X?c&m^G;TS}ysOJ3Ga3-%D(+!Hfp{BmpYjRqk{1zXls4JHIAbeVoff!Y zd2nt(5gw8sg_E)eP#F)&g&??>kGrdqNVY9$%?kDEY1!dHm1^qrMLa)KQ@Cn|4rcJN zZ8uK_usL!1Y6AU^g#&a+YvMnlJ3AAugn1XTS4)Mq!}b)TvOdS%mv(1lP+I6qa!>fi z4027NXi+v{MwC>uZdsV(jd`0|SxR!XL1{G|>XUO0_tGE;gI>~P1C`LSge=KcA$_MUO)6X&DQ{q{uJJipS=C-?Hk)mI{`bA&%m+rXE1;I z1hkV+^f&E0EqeAW)cfV-B+K%scUe?t7DNw}Mp$wQtSI+P-GIq=ott<_0D~7;SsH(r zdUyuJj^K+%6~=I5xxywyTSu3kl@eo;n_#jFv31IkyKK2szb4)QiQPCDLmsV6wLl~Z zZ=J(riBcUYHKp6vS>kxD$W(w0=3O^2!lg?^>?bJ@6psom?m;(oD^wkuzAFSe$IEhe z*agVFDnQ)Kr_sl{m5GPc%r4UjvCHUC4#;%T0eV>u!pPKcRMS*Twkgck;HmN~D<+az z{-R(O2ZBhQzF(|;6_Q?U`jWawJiKirk4kV84%EU)YlaObbl`0h17Z?uC2>T5iPN01 z4})QPXLY&Qmy1^Z#ECTF$haU4K1a-LGQ4a9ysaLO%n;y`clBGR)^`ph$-|L_Wvlh)vW3E6{GEZTFC#1rQpMF>F-+t}-Z?25Ns_mG##~YF23zfZeEA11ddX8=N9hW6aqH4v z(ISNck)$K*n(pNIq8KH4~5=xr`MfZ@8MW?x-8zP{= zkl|if?~+OT+_?mnLH?2@A~1}y*$%$d8c%?Vf`{V0`x4N2&ri@wF*GRdKP)E_)zbmF zaw(7_{qq!LRlbqRY?GaWtX%$x%3Z6*HWurRK+sOde4HGiaopMOMN&5Nq!o!7U`-T> zj~UjDU!8|RCz>%lp<4HyL@NwZ@XkR2J<7on`Sb%5NK~Ej8Dyd4Y-qs)K959mU|7@+ zqhmiZmoLllL9g;jnWpAw=l41@vZUZawOv#wv;OPBTgqEXVk{Exrj^+RJnq$F95XVc z5NVA;cc#)A=Bp5eK&oC3TVZ^(>;3$8<&#(hvT$)2RnB3LC4 z?L`GN!;gNXM_gg^+qVz(fbD!1k~q|H>|c;q4_nHVeSBnSkk2mPzyHS{zrFwe{@?I# zeIfn+pZxL120MHn$=JRffMQt1rxW-RR?=GL9*Lz~M!lSS%m@|jIv4qP$O$PZ%(*BY zot*;+b=DcvuzM!y4LCY0)r2-6wk2(|1s*h3hTpBF-O5%sIwI`BRMhsJ1Bju^nP8NV6w7HAD{LWas^LgGbuYD{0Z&j`^V|Gh|(*WfzF zY8h!^1$tL#K=itFD%pazMaz~Wxl#aEK&ZdbfOKG0T`xBoSv44PC#YGKjf@ve@fSm3 zFOzzFq;0GqlA@sIcZ6#L%0$|%(GG&Y1=E|(@!E?9Wr-^dcOePj`r@HWx5JE9i!3fs z|JF9XvQ}|EBny#s1#w3TxFz`;>yH3?%V9TIIg)9rhvhEstCe4XZSW`*M?z@~_5T}I zG<;4Ho3hkBpUE}5r(5JWY(e6{1v2Y4G6ST~IzWX=Y0)i_kv8FnVQ^OH`<+(be!NN9f2Sf=fgZrjoI>iPtFmuV_h2;3<`004 z+`a*Pb%AMNBw416r;HQ~nUlP&%4MJ^x+oEX;8#_ruml49ALy=FLn!S)*j?wlMz@l^m_d0Z@+u1{yr6QWTsZht$_cfov4%NLQ)Wkn3Lj0=B8ES>Xd50eu|tG+&CGO<`Xu=aVu9z z8!T^_8!jv;k->(!M8MCjx3ST5SIMabH7`L&B{Q|T15k%&Qn__>t)8%Uq48rG1RlOP zyZ2hs(3YDu*;F?Q0$me~Qt||-|8AI)Fd^vpU~4miZW>8m*S3RuZfJMLl7J1D#I_}6 z!_1BP+RFLbio^8^s(GFF0OS(L8#H=T4xQNXk{=8$tiU}zvYNS6bfp_tH_79M?$>#P z0my=mACJU9k=|ShHu1W3m%KPv4S<|569)@*$n5FJ?t#E{tiMM~{KyK1Dys!qBEMVCWN?Uq6{=A{7}l|lU*H{+k#C(jJWXT#`)}WxF~^VI72ZlykvG%H{tcxg zQh(tC0yovi^6=w${aN^T-1+A1w`VlzuQ@pR2Y7${!`qiBas!cJeS}-69iXD7Q8|O| z12zf}CbEDAV;nh=M5UkvaKDHLhU6}^F6+X0O&Fg?W3`DvO?C;q*}D)*S%}soOmE{7 zSalTimX=k0FNjsZqvC2@;R;UB3^MbN#{fLK|b55Gm5DA0tu=15YB@fPz;B}7C*9DtJEeM zF=(D;aSyE*8*(T=E0~1q8M< zh}Es}auS=_?uXgkxS<^|8X~S)KZmkM-AE@Yrk=`5&*&2(jb3-NB4R;lB-e!tH zrTRl&m)77{NTj^q10CmjyVQ&7{aE0WTmXfaTptS^XyqQGi0cc|h_ns)$VYY_Qh+YA z?pmg2*G(m%u19~VhTE5cF90=h9Y(N4(Wd1L=NCm>qT@4#(3bM zuS8Co4QCvqVm2?umWB=~(n@&`)eI(Ds#LiLHw3`GBQ-F-?=sUa;heWY6F%jV8fpWFzmIR8D6T8J+b2 z1B-&yV{keBA){P8Dx;7`M!u@wI%oJB8>i2W6S z78;*__?0i-KC#!I+VB8g7OFGx_Uph6|Nhqx-hN@P2__*MX+!|HsuDn6zW^-ar*9wN z=K+WKQg=Q>)FKU*0kkPjVYVO4;h&wY{ zE>?wRe}krsgzadZ0Xzp9{kub-34k6_5LRV`=!$4D8<%Y3cmSeT6q}atG@{r8B%&O9 z5<}R!AGX<*B(_k`zM1FDmy^T<<`40*VALg7TVbT5F0e3oVK-@MUCz0lVInC%#ARZs zAvR&}thsg;}S zJB@zdYE*~CCbipPYEALX;L1_cJl@iHdvF&Eaw*0MV-x%$wmYY82cAlM_O{ASD&j!3 zCpJp8VovBx%O9j#=;@}4Ndq_B*wQ=w&Dt}aXzv$o{#sE2izFR`*lvRs$xgDSgcD#> z3)_(ewd7_M@o&7#3$Sw5NP&Rd_D*`Kx|M)sZt})CQ-Hn`eYIz6zV|byMg6z}hkhkN zw;xlV!gdBs=qWS}^N+Mur25|xuF#a~i_;yXCV*(4IGv-04(5a7h79oI>~>L~0whF; z?fRuIySs7{bWOhhUyUEGU3^;m!kM}u&AZLe7B)m_(4MxzCnS}SWt7MYIotH~tbtc2 zjq?^)K%CdjP9xx>Bd`{^WM%_l6u5TYd}@Y-ZF0r5CfTc`9Fso+Cgi#r9vlfzgFwJB zlBR09Rc~__@{QNq?V;3kqM}9q)GDqyfqFfPKKT{J$9?wIVBkTmrPY~e@OX! zk+;@duWSLl1WHyYE}+{LO@UE8-|RK(3iS}Sf+D_5V4Fw~F7Ssf<#@S{&{`uTAfn+Q z58TioFOiik_AX6Z?wzuum=GYRms3a;8CY|Awj`esc@92v<2eTA1S4--JY@DJ3OSW` zg;lO$2iyP(`Wb-*;1u)`_71f{GxHgmYtT#f_^K{M+I=LPa)i*SMgL09Ag}_fc9POT zG`q85oQclK^N>@|dP8xIVdG1c0Fm3MJ2c1yo6$ahgM~eP&ylo50GqKuK`zU z*p*?aCT!a}<^&nb!5bK1`N+NiU<7K%cu8(I;5#uBkZ{6kWdUAdf@Tz}eAsR?sMk#f z_n~*&0CgPtEr#0Q09Sb@T}$TM5_{Z=g@nl5k^!{lfy-0`n0s&nt1cys_wz8o->D&0 z1h<`sl9XBS$%?ZbCg!t7k(}G38C^nVhc;L6o`tLfFb{ylF-ZX0+iINmHU*-k?ND%} z53M5~@Q<_nU2nR>`PTi3CgnO%QX6Jha#4J@Lj~ZVMpcj)ZrXpq1OxL%{eo0dm?ac7 zRI6gQUB+Bn==L{;31liW)5Of+21KO&5fzby*;TYoIdTH)R6s$@94SChE-yWr&om_i zioq>BIUo-b&WrpT5%@d$4>P-F$>P4`%NJ6$Tmju0{)~YY769x)rHx? znsUPqmkydMsD=C-gnHVai*$nx(hI z;Ovr^2a<|+(GzY1Y-;=W(iA71D0%)unxPaB4z>W#+pb~gY21|H`jIEU=5MiJ@J;$_XV@sF05Z6`xCN z+}{wsO7Sd>2@tB=eUFe!f#;Xa7cgZbO|?PUwz!@_nI@W3W=UnKV8F9ZMGP(r2jIe? zTvCiGwd+!s08b7y`6>VjP)Q-kT*Vh%-HuitlB#%7J>HZ39P*LPo*xtpz+GN#4~*3l z$pp^df!GFE%3V8#2Xp)GwasDuUWnXdJf_?qpE?}weX0ULW^0nUmH;sUjj$-wcyLjX z3^-f5Ok@jisP>GZWmY72GAtoHrU2B7a!9@N1)gk2vA@==Iw`C#?@8^LqU$x)@)-{SIA>uV25Uki}1t zFc~uQKgq}VyVu`C{0a(KU&w#IlmEW5?PNQ;k6Sy8k2F2FN62F7ag)5NRX-c44H~=i zhG83<<*JS?Ilgz#w>DJp5MOwUt~+##sJp%$gbFZb^#-f#w=^%XmN? zCyY@we{2(AZ`Za~XOfg(Y*oGow@ZC=E1L^`JDYKrEi&F_I8HAq}EzRo6?n#hQE>m3u4!SXLQ(`#Jyw z3P7Gpt34$1oQ%znBs8K60#(j2(JNI|5R_u#%Es3Hl*XG%_c4nd0cKj^!lk-+!voBX zLD{#NtoG4*_`?+~o=nXMJWm3%zcT%xA2A*rDuqzanZ zIvFSkws+H7h-2kRgaTt$=f)OjU#stCCm9iH1C_tl7@*G4o}-jwG4@cgvgZd3zj2mw zl3+lbt3zB>Ex0;&?=x6-lP4MRc+mo4#jWS%v!iDBkam!K= zfI9vW^whi4f~)ZW(m~?N8|`w5Lf0|Zi0+?RDfHJibDK0>w{UA*67)J_Mse6|VIjc; z)(%{QD@j}<5DuK3tgFh)T0BoYxIoHjyvGhJ7}TI_GNztfCGLF7NH)^&n_;j?le$z| zrV+I`A;Ts@ab0pKiRw0`izP-<+7YuFRPw*6;pVNWQMQk9@-a^x@2#2FiFtCgyrDmOe#fq@b)V6G5H*D5IFM&A#I z5aesFs|AFR+=S>2K_TcMYeGjPGAEJChq}Ukot!)Cwcx>lkOoRDVk%>JW?dpvEDC05 z3iL^&49V_3s>~j6sj|Q>fAp>zpjk=9eHr#pU~7y!}C~yDb8LjClMRzy`YY3ATQAdF~xm@At)sXgdtC zW+-R`vrhrf!9LKVM(<7vDHpPs4lAYy27hcsjMnXdn&h_B?I9>>(04fNK^w7SuR^Yt z1VS4JRD|FM~KPf*$Lb?W7r_cKE`CKa>iBz$jt0P zjA|WkV**eW*Sp1NP)`gwH(p&`Vvv+TIf9*!DZm+1WoT8b7!LPwDeAO!N332Z=UNdG z+=qy@taJbrNG{>hlIRGhZ4CG@KD5UI`D=nuaICFbv~bh9sDda0ZOXzmL6zGy=}^qE zXx%P5&cKy~6OvX@u<(WfJWm!1$oEE`iAh&oIgp)8kUdlU}$e7EJt;s1-eIQNYhXo3Le?^Jy7vjK?rlz3W?&f7IC(4pb~L!gHX2etHU_`{;HQ4V~T%L+krk8yJDRt;JW z#`_MU%9WU_Ia`ABD~kIt6wAjvN6&U7;y(buZ9j|RT5ewnb81mF5?PRhhhPki@q^s( zm>)RSLN%i@)Yypk?EXKMp`=|*SAQDHLr@`^A6>G(R7g)c*yr}JLVN-3m_r&1g^X(; z%WZornLAShx;cq{})8;e~#Gs zPLzH9JpAy$h4I%^9ieydJN@@_9rM5aR(C#1Ur68c{@eSnABI0quYaz`p3h(~2q|{u z3@j4On7-`2q(*kG9{b?z^Hc>(X7x~VH2o^%MD&Qihc70q;a&Xsj$Q*d0j`}ccLl;o zvX?wv?vi2~BoKN4DG&lffJkFIa_Jdwp!4dp1QmUC-9|W_OEJA>1LCCwJ*XL{uQhVf zXRokTqp=4O^upc!)~ofCS&%6iTp3$0ZmjkLYnIOD>9HlGV&I4EY`n z$OdhQX|Pa|A|T&>O_kdO1yQ-=k$?tJwB|-~6kxQVu1C{O+~Vl-TUvsI1ZsKaiAf$P z+%{6dzsV}dbr)I*$MYd{9rZfCSW2jN5>G~o9g8`xvrlK=xp zjm1Yg-8Lxi?TWS44gu;cr?{vkm1u#SK2`Lcv+#zYefj|p6?Sb}hN){09bP2~A)|TiH)s_v_)IkTdVmWyrVKzQZG`grm#dKr5 z%ZdP)oy60OC3iL-LSq$BFOo}09;-S~>NOYnRcKI_@|;4%LESBKdnbu3P?Ba1TMG2r zt(_nNQ%et6QO->dpBBRr4vl^wbg}M>x8ko?rUZ8^K`dyO@dTVwL4$RCvD+DQr|Gb! zl)H5z48zeAm>@W9$J zAaUehZ7kS$e_Ir*aEieB=F^cpffqb$P)PHlJw?kHmNm)hcmlEVVaa9Tkbi1dNqS1U zTV*q4p|=jAtMvs+hryY{8T9Se!%-sZY0;ZV)oHU)1#54rNiLAfV@>Sezx5jaYu|uC z{cSLW|K9`+*YDfTf8((lJo*)ta%au8m(W{o`qP(OCt{FmUJWX$z`zZ! z^MlYgvppbnMb@BAAb}4r`M4rbLmz<82TFe?$|@?*6m1fBlAnl?UgS`PzWY|Bl%;Ai z5uev#R*`!PAXMFWK}L?{IvtejIb`j!GjOY4P9wJ|ksEa*x72We-s)=^)EKs;*)Yn-1>MbtFuq17(J*yn zFrUujcey3qPPOW=QuQtxeGTg!!*;Zjr3~ngu|HBCEZ}~#;{a|Wp2q|glC$rVq zgY^T3QWY@Qi)wOOy%S+dmr0&2&k{*Jc&w-lfXdV6<;|i%J7WITB!`v}$$<^JAtwg` zsZHeFxd{Zl`(SjK8K16{0A$ELR818(Av>nv|E|%RmNz>j^Z{LNdYV5>lFQH{q6jvu zgYMCuNTQ7C-2`_XqVzzubqe0ROF|~8k2y?Zs4bUHLb&9&9Ywry=#PNx#l05ZmT~nj z19h^HCD2rdqf0K8%!CFw;0?RH0D>Ek5R``dO19Hd*;tC0t%shRTBYtgS^Tng?s#da z3vkuuI+*$0Avu&y@U>QM-ZyXWpC;1({=f3S@WTU~dH;?Syx;5Z`To@J?Os|Z45*rTXj5&2Y62e(DhSy2?t8dF=oZ!v)?h)|kCLqck&J9# z@+{S~UVPkP=9#9Ae;j`7ek z!KjDSd~_zg89pn)$*BWoo(98)@iIeuLSnL-D5h`Gfw5J-8&+N@@KHliV*h@m##3iQ z8>vz>k+Yx-jAIuG3Y4$B7_{%+?0}$~h~tQ1Bh#|cwNnP@@*ER)E%iw(``N&Me$#of9fF=P-v+0n;K`Cjy zo@&$)^5x84RFI2^wBUmM%?So0h{eWR*SJs*x zA8!|Cl`F^N3cDb>1G4Po}TT;hGk zG}n9e8)T2IA*$$DBw$e?I;`A-;}epd(*mW#CG%1rx`)gX(i|IrRClTdzT5`c5Z=*T zk7|gj%Vs0=(C+3lYO+J&G&q4QjZ+Vo{y+fBsu`*pJpyfLrDM=HaM7WbGD8vycW!rB z`Yl~3C9blrhj}a~R`6ci28^)|QM96i$gAZoNvjZ2h2c;$$CH7#?QH}pj3NR`p*G`8 zAO^#*z)*@@@f=EX;QXXX!MR%?nJT#i_-lN>c|vg$s0WynBn%j6QeX%v?orGnNkVcB zARwfUgt9&1e7o>~n$Dz6C?2M?0MhZNF8mS8P#sw@D=C*O(l6#((fN2c zSwLQ?-~9lZl}s^NQPke(irHv7Pm(vhTV8KPzH+HtA7CveLp*R16g-EXqPB~5z4lk6^T zfQ^7HZ#saIzNZytY2_Z3h_BXKy5W<*rBF(d+|0VETRDAn-8}B{jAPN4^XQU*u%fPXxZ|yZW2)tnc$qY@0PYb9ixuBW z9Xu}00G+1A3-_i)OI_-(JNu=BRBp4ymL3MRoUm_Cxhk!a0XkR$q~`iUFAzfK)ay0+ zF$mo>SDrno@~vHqjy!<^4MNSOFH|LXS9~4ndsS3ErujEcg}^g8D1x|=w}pKGXjIwX zmIufHcX-M`0k=*(MqTM%=pyXq!!jV?knMnxesgKxgCh^8*D65>a{xZp;1ODqpk8D0 zB-;3(l{eY}S6A5yy-Dg*nk3+mqHob04Mp?<%J|-fCX=NZat~8@K;GTFzt~Q;p8CK^ z0Nj~+=vPz@29O`KRpYd1R7#h;9&q|64X-mOWp0c+5FW6Bqb|Hh`m3D|_8V-_6|RR} z?X}xLps-W|;48^JuF%EO$=W-4#!TMg749i1xZeX44#?+OY7itXgw^0LoZMJGL*HLY zz>p;omI4=bMzKkFe`#>bcu65iK!FUsVRwNxpk;(0JK(a1+JIW0UnS}n;UG{z4}gA6 z1)%+9y=Rk>DNS*>#vB$z!FXr@<4ztV8tF_;DzJ%(fZDEUgSt36Q&2yKboEJfIqRom zh+pUgId^mUe1<^Qpu-n8ftJ$h8BdN5K;?{t<0DUylK_H^9RQr=K;5PNek3~)vR3Z8 zlQ#wQWPH)gn><3FP;wHE8Rkm9`@8UzYdp>_ML37#Qz?n##tDS-a?`eg^CBP$fbMTd zdv>@+9I6CsKQ2?9M5s_q6FLUj1u_Qat;3u`Zl;V1Nw|6dChQLfcx1psyLj<5B`*CT zQ#d%{8KyJM0_f7fdL`?U=aa+HrS!L+3Nk^Kj~O0F2X}q{!P`HBx%lDRZz&t_!Q0Q@ zKL7rsx8MBne+lW!=db?c^*3q#B)(g3d7@#y|4DfL!{s^3na2#lgvhWsvpu@Ys<_EA zWZY5Q3Em1;KmwR42e%s9L~(IB3V1ghG6mq0u1yjf9H~%p*M~A~0pjF{juCK&C3 zqTL)tBn4H$B;$(asUj#ksTF6S01}==D|u1@t-^ zqHda|zJ^osBw2570EId!eoG++#U>vJKz4d2TTd3BHS1^=30{BS49E)>Qx!*)#IKQX zzeC@HHr$BQuxW||CNWlngI^fWhQD#p+RPjEk}a56707dvMoR#F?34{Efi!{5gzHp* zpPU>c&TP02rAJ1=OB{o7lKfTf17R*}xi#2#X!mvs#M{m@_z_Cw$qorOJn3(vBdb(X zwqq2=G=GT>W6QTHJS~)s;J({~lEXSpp0q~REh-q~om^NvCc z*ypx~A%JT?*M+nTJ(Fz1tHl98vp zqbdLunREGak-rS>DT|XyHSg`S*At!W8yEroYlX0X^)HUyuiif3Yxv;-zNYW~@a?C8 ztg@fIej7mC2m9<#Ea>*ZjI3%~-sJbsJvJJj5(Tw!NS>cDZ#3}HUSa$4$PTdAg6Rvz>Q?2lQdf2jw=v@7unbb>FST=K$hgeJ zxeq%yzZV6y%<|go5MQ&;ys01b}}piO^aw17^&=M;ngsQlb{k z)3_P3jLwV_;#MQl%SRa@At8Cv;GQ|w4@xfaETV9CD4;vdcK$(?R3)O9XHGyeL?}n zo;B<#-6a)^5MUS1CCLEY?~575Xnr?s^!A)Wj9DLLY=nUrkTVs zxiD4Zr##KZ<(aL4LBx7{#p2HC3jNwc;=S8O)ii~2CO zt&zge^rvppjc&no9uV0N?z_%9K)D8_&yS*z_2Chk^uRAVf~A6OsJb)*?>c3r<){d~ zcdg4SOqN`ivKqS*byAh(X;A@c|AofO>JojqHXy|s(BT?Oqesv`;Ur6lCx9tSs(Ukam_S1#7cEqI;u>EFv_S4gudP*8x6bx*xViLM ziMAC6I8f}OoNS2}t?Th=-^bpXqWC2P;uIcBtTxmE*F-hT6NSlhb0A<;jDME0azHrG zAugGYBb@f9fqb93+H{X7P|8V7-V)p^(6yz5tQ{c1O6V?l~#JzkQ;_yArj=#6GN33k0JKTQuqlO-t2H}CPOlT-pgnY^d6mM zwrA#f_t@Vtdee0M5YA~Zv(auhg{&Tuu3(|S#9V4g027hX7=V4D{iHn1PX`{rQDr{# za5cGG7}XVu==1N1OFGn_Ce=EXR98n4U7~`euPVaAT9&}MtJA5}Jf>iQ?s%)94()L7 zoyPeQ`1Tr@+|hnb*12=*s*p1*aL}}u@?9lhA;8xiZ(d5yvP6t8=FtXm%0UkcLGSYj zg;jnyH$Abb%=Ll|4 z3FJtU!ZDc~$locKWdhuY0bUmUa=fBi#pt9kqFQ1vGGsr;OJ9W^aa+wofK-DZ2W<1w z_Y_hngw927_M!4m4@;skWbsjVlj1lE3sG)^ZKG@vB~U3wc? z7TE+Eibg6t-Au#=H!=-KDlq3)!rP#aPs8LP zWd~YN54I*&IGuS`v{GX~&InXlOAAH5%R1M%Uor}B_wdn)w+ryT6zD6WBc37qwCkxv z(cuF9i%QmHm&lhDv#@}^$+hXALo;wTt3J`L6<%g4%}B4m)dCuOLj2kUsFZXmWDI@Xd1nKB)C;74b?%V7J=pdf*~Q%Z=JK2ib?sG7U+ zpo?dnI;!$1%D3w^8d4{hVv#~KXizyG4r96zO*pNeoUowpbfo7> z!mH&4ljQvD0!Zqcev=wX(HU@19G3S1!0uWyIUxfDZpsa8^3nzZmOFgSB;sqnp1=Cl zS)1>70eX8$wC~en1pfZ(m*G#3o%h4vq@ABg>S3$NbM!^vi9}HTMPX=7sVBzyhLHn1 zGGx?-F{WVCcz$0k=po^CVc#Z_fb$_3Os_}E|6PV5Chz2T^6lmRfDCY5VaoT@HJpkjUC8Ggc%d!&;$Jr}b0+a3>NF|9zfi1bq>T3yLQK6i< zjL*q;=qP(I*YDU3Nf3TuzpwuFSRE!vbA)zj?~f}c`B^z0*uNH3%(Y}(mF#bqs5LLO zmpX~<&zaRUs^N@v+3S56f#;z9&Rn2{Af?slEqPm*ry#cgR6u46U}HPlaCT5>%S*pi z)ggS}gI6}gQb00r4&65x4)>$W<0h276xzdIA20QO#Zh6c8Z_3_mS$gC;7rVz( zBo$%D(TN}*K*v7vgE&Hw0I~|G!qgb5HujY)`P?}izO!WCNIh|CvN?#Px?3b8c5l9y z*SB(g3;3H-*lq^@4OH!+3YEw;eS-`4DR;B%81=e{^j!XZst*s9j_(8bW&9lPhp2_* zD0|`$-z!Tj)n&(_1vfQ(!0hm7^xaNPKTHOvv1aQ6J)3+eX|cKqkZvzI1YC2dUDv{h zfivRY(QxaU=%I zyDMAwtDDh`P{0PqhP8{~BXaG0rh-~$tNnp= zGH~v6h}Dd{MM1PZsSGD+h2g6tgof6znD;hF?O*{kO`)<@>b+DUIeFVdUcYx8_|EKS zNbxU0v9>h-b_>~LA^(9}8ydRif^{Lkd2ttA41S#6b%Ts!^5_glZgmjSrryb*K<@Du zdBkKAfrflhgkn5`Bj~st(PFlvDD9f=?ZpAv6V|Q!NQY#``8np zcU56DYT*KI+(AzPk;F-SlIuN>6Veh5i#OU|y0mkW&*g+F1o3syR+@$*gF{?e04pxY ztMWO#4P^z(K0J1tudWNK<_d2l=N>O=I+a|rJM+47duxjhT8&nH!gQo9P0a0Eko#Pubt z5B2~`4FPMUSP$fs4u&;;)vX|u2g1T`d>|>w8clf@L#K|9hDQD^rQ$;fHAlz@^FZt3 z0-WffIbJ#qtGkmyW4fw^qMg)1iboE=(6hF8EWx0W|9EV}t^Xl>|G(;i;S0VAC$#-< zT(LH1D}VS-w(_w&^6rC;-(axuqv93w1xrs~v1pPD=GiANA5Mw|+P9Xp?}UIp(O?3q zigL`)!KRkaMmuDwc&74{J3rBRmxz?t+cv4C#xb4Mc7kzp8Zd>X<6*5~9jbpX+t<)} zs=9$vYPrU4i(6`=-Zo>X>KJhE0M5xZuQrwH@6D6~;m2OuDs`-RkYj8im1czyV5!0e zy)$E&E?cQUw*$BDbh{NjU}h7kBeP6RXM?=W=h`&UopI6cI}igC1o*&I<}c_Ww}$q{ zvQafx(yk3$zA&ziJ&cIacBr$z zy}6P)V`0DWqb=-%O%wKmDm`slWfChmZK{K*_5E-^yU|RO&b9M#hhU`7619*rSDAeo zP=>q}A<5`>6u1ZZVafHm1L4QA3eZVN5K=ex^Px;y;J1Cz_g?3>I$2@rAhA*v!+QvT z9x217e`o?ut^$0IkT?AZqeJE7W{N77pCrmHuFt1pZ%@|b_w5b~6f!ICxS#R|e5cFL zUH6lG2>UaG7epU5-o|?hA9$AEpfM`(r*@|5E!2`uwuiN1n^mXUK_VCoaJbUc0awCx zaC@AxSIZoFFg06uk188!m;vBawa=DM0eL*I1GsS+df>kj0so_=PBpSLY@#|b+VNax z5vO<|YybfoeEc4R#bYy7=H7D1<=2a zKQXWa@F_PWxcPV9Ly+b(a6#%NS*D#IuqV)m0!=?k2_Gd0+oDLd%8A%FMm6?@Os9r% zN!ft|+-CLsn>a)yPoEzr#3MsA&y6~vB6oFsNho#LX^~#??%jV(E~;7(Y>V##b!5^E z{NKXH#Js66Fo8!E%Ifpbtb!FrydH4DS#CaqKtL0}+fIhb)d=eInHf+Wx=a=1C0?Mv zdHixfj}CrYB{^#QAh7=uE{T&Dc_VV$TAu+N&kSx29N(7mDhx+3Z$vAi4v~*U_J4E% zq^PXuXi#?X<;4H*B_xRR)v0!v+IKndXPk4i&NS4o@+ zbsPfqD>GxzKHp3ilx$d)SnQ$D-iv4GZ6+>>q76sJ?IgP?N&R-njpje|P%)}}7#x`; z`73(sKKs}foh!(Ve@W?ZGz=H(Sim}{1f_ItvsIr6-$?Y+anmLQpH~Imj5@KNJ z5vwwhbzI;pzC% z;yn)%#*4(ALVZWAeIZ-Oh+W*E{824ea7){{)KPU?^qaQ9Ex(Z8wCzMX4yrJ;0-yk* zXAkk-?le~ITkpd300h|)M05auw5+BCTE54OGy-^)W2c;BFQmWESgFO?+WKr@1t)Vj z4A%kZptR3P|KKha6(r@QMrW~jZvl|-o(JA?cWT7l#&W?82+Kb?T$t93KGSk3@SN53Ev$6Y}3q%%Ksex>VwGt zXBoih+4rA+_tE!1zJDF)iSx<(C-0v_0r->R!&!zV0;EO!)7w`_4&ajW&*(FJjXuM# z=$G?(u!A2$6)4S;AGn<$bbv0*WcM*NCce23f#!h=fJYK+A_e;83dM^BUghJ-hxMXB z$rdd+#(lXrWQTTY=TqH&Nb05Pua!~#UfyfCQO zIx#T+efG z;8T6-W+_ji*RBMh!HJndpb>!r*0a7M+Z?g!4rB&Yn5j54f;7*!1(R4;9P(b*+4de9 z@)FCepP_{8khD^dux;6q_NxZR%t$c_ zKLWYz+?mwo(q=N?doL~p0-aJRSE^(dK5Cbbh6(-NVrd|l`oyn zI$8`#?A2o5j*jWZE1Xj`7MXc!Nl|A7OT1E5t(KpPIwvF^f#vSUI*8C2pt@9{e%pU3|y38DQV)&6Hue=7=9A)A3zF5 zwg*rw$#z*t!4OdjgbHO6wsZ~GbTB=Dh6T>GoH4&}6d!Qti>GHOLDht8^- zQIB%7CcJ%JeEU;Lnf~;5`O(iMsrp&?_D65Oc>7&`iT4hoCxjx*_H*-OFIlo|{Goyh-e&TJw}p&HjTko%kH4?|hLhL(Z@Bcx(o z?ofWM6x^>i7g?b=R4QhJ@m`M=ewi|qjqT1=rIOoW+9Nz@@?&TsY!x*LTmwzvl6tgk zRj8<^yoHzH)WU$23-OQWBu|^%^Y*l6>(+f=y3kJs?Pw4IAeAHwTRzya=Ao2u_mN7< z*T-@3Oa@1@d`>_huzd5PqJ0_IPJM?jv)j)$(2Q#`MYDg^+CP3$&kBz=qCgORG| zsFJ(h<-jt`F&M@MuDgP{E^0o>ELMzUI#9gnvb-hSlcn4(tMg56Fre^6W|-j6Cq<2m zD082hTI3eAu~S-!llx(20QoCsLv@V_n`B5e=O>cfaK(;;+EUxe9k?!&Wg;16SnX3p zPkojYs8SKol?|AMvfsmNP(vS^{frM*nDQ4;QWn}GLzI9Wi}g7emVd4z>SM94D9 zrTb`Wvp18Z_(hKqdWZFCNmV<@i^_wH&G;*6jW1MWl4G=T46V~2S~Y!qt?~IEeoXR1 znA)O1^DYPyXcQCdHw7kn_u2}bb zLO)A#6BVehpf^v*h`azwO)#qgih#LG5At$zmYlpQVp;o%`5ZdQ4q(2v zDC{KHK%A2Z-(F9WjYooh0W)#}M?_D7dokXp{PJ7-q{1S^L1ja*c&|;nZMN1@?#F2H z#)P0n+7BFzOBhTcLy<{~c3+y1) z6RH6XH_rJad9C)0)7Vrol!Fy1cE$tmCgt%eFSIBe&qVC9jI!_rgoA^R#o>WPGr z-7CgYwMMN|(qTwtJC8)^wN+(h@LvW7^7>FT+-8Vm$W39Vb$ignQ5l!81Co@bF5Ib>`owufpT8rxdn+)Yi1OoL4StiwCf-IMEq~ha$(b)c9 z^!R(>zds_n+7X{&oc~Uv8E+$Vd zkbzI^jC9)y0@qxCGeZgnFxZwxAkVolkwZl^YCf?BpTf>fXb2^h+m<2|*tXd&K~QqX z^N%Dre^gA6%!LnwrRzYu8M1MbACNrH`uGz}aw;Hq9V#<*Ckcv+RW+^Bf8F7@-Q)+F@KQw;OgSWuq&cPq)Dwk_1t&)@^~KFz>0P^vx4NGDS^RlpJeP7gUe7dj_9blz(h^ zG+x<3s@n&o^_o$EEmAU92d!4!=MQkoO!G~1qbOSKr}v@iv(#xbjm z!pt&1(u|c_SG9#L>C-jkBTM2rLfT0}GOJF@`;$!Pfal~x z*;#?@!NJjvk?4)kxRP#%q#vN#(YlFf=z?w4^ao8goqAqa&m$A29!7G8S?wn6#}VGz z^#F&tI2Tf@ZE48Qk=LvG9N09vLu=)G@?ZGg_fBlte|!7UfAlr{zkLI{7TI+VMYD%`|mJdlP_;S zFTVY6;q5n)q=mL-*0L*O*Dxjkxr=w+ z{bX#>q(nm}6i5(K!>ZhwF7zb*tTlCIKs%ci>GPl=q6kpO@MijhSV2EQ;K;+gY?pG5>7Q zjM+L`zoz*Rx0anc^-QyJTxR7u?a=-JpTfE-Tc;_|D>1aeosFOc0x>o+GA9WJH`&2a zDNC3KTj!Fh72VE?>Rqyk7IGlmeuotUT%;)LO!e{`>5o?Ax=7;s^dYW-Rg{_8<5mYIuo>Kz$zlA zmV%r>@kTAL@?oi6{f$y}_c2g}0s&}I9;p>+_a+8QEHGC(yi#DWUeT1{uA{sI#|0zH zo|s=m9&+_=BedM(;g4|xkWg;18z48s75PpKH%Yh-?};|sH;yy&o0WnTtvYIw7A83k zG%Nl6!-q=J5deIXduTzH#z1-)Jzx)7PO37yDzbwd>fhb5GXZk0@VaP+ zJHRrEyPIdCZ57^1d{Z9mbltdX65_KROv0ukR~TXCNid9}ue~XS8!2nl5&m-H6H#75 zPZ{ip7Ncbsv(|R4$#_-@xRxCx17hu`LvNs(aL9+1S#SP|Y0Pj~nPD~q9Jw>0ODTB| zscT4<9oTxPa+-c;Ho>agy%Jf96FAD;o5Z}Nvj9IVlhb{XQ5;e>09iK)asY}}l}(Zi z;F38X=-wm(pLKyK*!7{q_2~g)ynxeU2l?kdfB!vLFrUAFMa|4VYqWe#0PDvRyFUs4 zT|W8yx8DZB7$kI0Mg`yTcC0t@Je#i=gI4$0L(Z!Yi7gjO0ji!htJo**ny8+x)NXmS z!`|tX(<6O%NS8cXjK*#Mcqoi1726s?=|j->@E;`uwtaC!zfJBmDhqCy1+nD~CWEzw zSM-I}R$}#5qJEIjY;iwt-jwxJH83pgbu2mgc>*W5Qm%` z`&kGA*4~KZ`6{`geUcZI3{#Cnf>rxIv=xhF)h&@L1j~SI(FSh~_tTuSbV|+ga_R>>6zfblaDp?n#F%__XYmHqd2Ho*XFvH79w1xRtw_ z?~u`^qS&|`9^q7JiqWy(wI zvZ&a77^h3;ZIcQqsO)*ka(PKQup!Dm4(3pY)o3hGdph_i2hX|esG_9QU&BEb5>(~k zLsx7bfXRh^c<-QGNHbE3dl{*!ct<0kVqyVn<(x$*)*#Gd>wn|6A>VF{9E#qHtj?XB zVqH>){lQHG<6wnp3(A)i&uw&t=oU!u!+%Wb$LC(4fOtSf^l<20ZXwlv=B$w>fr`q# zN>`gJh|WOtB${|gK+=XK#I`NX=pB};l5&@>ox+7#!ljkZ@B>?oAyixjxnUKYl9skf z|F+p`NfKy-B2^l-N2PY)3$5G7)_Fed}h8 z%o8&BHK6n(nj=@m+YhAu$h~OIh-z2VL*;D~Wy?}56mZl2#ZEfOQW2I%&uE~G$1MmB zT%p@0&uM^lx@6(dc8xxGid)?v3+%}yLffPTXS9+^u~U2=JvsDTUxhyqC90m2q%g88+zs&it*p?;qd(<=daV|LpA-;oC3XK7ap7e)g01Pr~~j zKg@9q{QJ+6&k$d7nkfAn&VCo(t()=pZ@&)k{l12>&CTRJtohw$ZPI7U`|K&%DW$_q zqEx#SvTfTpz{Nck4_RLMdTxu3a#xoQYY$W+Myc>Vg4@d>M@sDhOmDp4c(KEXL^>)u)UTE&0fR z#kaOLl8{?`LjAl7O`^{zERrN&nvqS|Z-KW}4FF64AFB9BmagPSJrl%f21nJ&K2Vl+ zjPIcRh2*xF@;kxrZOJs?+6oPML+lYqnnVhi4zrdPg3OopL{UB*#EWsseYv(iK)+Tu zLs>Ri93So~R8h0ff<48WBMN9iMpkHzM*l7eBgAL+V|`@5y=uu1z^$}>phmh%vCcdR zhng8Y93C)5g`VoVD~N}EpsL1B=YZQ*Cyz(Non77*;k z)al7pe}yh>J39aEs++hS2Kt=J0+O_?<_xN%#PkJCzWlx=;SGR-=My#2!;R<&`%9?o z)z+_4gckKKZ(4Ecv_Tmlq;_%jRagy;^DrL$E6JNKaAWpy(%_UC1@(l1tfsLZ=YxI; zrnFCcYTV_f^iW5-*g&+^T_UTk1a@FsiPgmvXWWLB@IFU(9Vj{ zcjRrWCZm1^7-miIEp!%%uUV1Kx_GPF*#ch!o%M9UY@soC(oGplsCd=Aw`SUz(rl@F zjKMXgOJ$tUa1__hT18;}D|LB>6)qK0f=i-;X$Vm56V01G-XL?*YO5GcDElUibfU%I zSks$Oj;ww81NraFLHg$XWA<-sECXGVw|_oykfG2t7W?M7NU0PzbX+RSLm;rZCW#K# zX=%gl#0*|2uBej8u+f#$7jjmuTZ48;`Qs}C!ZVcl=K*g?JPc9}+Oa~UPaU#{TBhnD z~oYdLX?JB<05g2=vBMiU@hAie6?*@)7MXrdhCW8^z+Gw>8aXqNW@%1TDuKlw~Zu7UQ^4R_4F;Gg=1XrR%!z1+MhfbTHHldi!sYiVW+kRFur`XP>nXC9gmV5TG-ZH z?aI*6w1k18_BH`A$dgmy1o|lEeggBFcr^o4sBGtlWsA3a6NeF`W;;!?7VMj%(#F@# z0z1~?9inC6o}dOIg}I}M&LwsjDlAjB|JBD5Jmw5}^0H#aInJ`c7&JkmmcK)hcCcC` zohuNxjk#8*2U>A<+^ga@%~jOGaztMaP?3_Cz6P>^)0)uUKvm{o9P%rJ36*SzlU=z*UC~Xi54R-!C)YIfs-cOw8TJG$bT$*`p4qIs;u_T)SMxQ^AW*h#! zUcEQ6Nxejf>w3Z;#|3^=>@r66qZ{~UF}ad#;gy!Eh!t{E?vmNsPYw;yKBlKfg;!K%xj72vcNJA!Zkl8@-uYFE;|9Won!KFwA5$yE6{t0A*{ zftG6Jnr$&GXQ{%akd5EQByeD>)4)wx;k2?Dw`Z8TY~-UMC}7Z%{aIAOWMi8{yZ$R$ z8V4_@LGg~hTU#>$!q3@=L<$NNdng3FJ(1$#aBQR*)+2aIaRWv%jCmeoSGf=f#tqgh zF!_+fheeSK2CC?_+#=&dL3*@gA zVVfO`+;l}gMeq$SK6TmMrfN9rGWj|@wk0O++A!jFdS#cAPSTN=;27v1+$B-QnTnBR>9xB zM*Vt?+9}^UOYkI*t4(OV10%YpiQ4GiCiEWbk_k#_V(ItjAQ)2g{?IHG}cblbJng~fEfUR8BMu4}tT1t?T^ z&6702libE07-y-Y`o8#ulH1z)57|vxlD_K(m%&-X{wssaRojcm&MXO#ViXt*_#&l9 zp)|09yf&6B7H&c9g=Y{0Q8g2KkjGZrqvYsA$w7k{`7h~yG*ZBq13_bf{Xk~a z!tEU%;?PKkK4*@-fL6(8xVmQQc(sNc^o#JIY@3e)e80w8U=eWA;;+6R{?dS)U%Y?y z_Qkhf{ONDse}o_0aD{oP#ph)iU^1)x{j%13nFS5H{Ia5c*IoBkU(t z`G(Io+C}EQ*6rvGNR3Exss#KJ=%xuT6pkDwHC<7u#jf12NsQjGvsKI z9i7dLOj*%yI2=O8tS z4r|?i1-E6oqC=qwF3sI72U)Q?4`82mBOIeXqb=TboMw!*?KtXiz5vVUkP(R`u?!7> zqbr!|NR@NjVRLQ8In^pP_f$YBP?Y0B6w-tjHZJm`)=kJrkyC01t<*2 zDMK-YW1J~XlT$OMa36{+5N6m7xJ?Y`9l%E3G(iTnSPWD95lO>CJt`^9rWav)+QAS@ z^?6;xZIgY}QVqFn<1-w_uJFP=VFuLT)$Lb?TFs>w%8dCV$^*8C>P+mB7~&)-@?+Zh z;p`Y7Lk|zR04S-u!^sU!uQ`Y;M9wR^Ks{F#zFO7p+;O8dF{)@g$W^yrcbB@0?sWIe zxa^`g$L=wtHQTAQ!!7%~&JK!{|s|BYe!{9IE^99L$2P^QAy69@vf0v)l#cjBGtaLBfoXJ!t88N;ASh) z8k(B~D2(n8gRl+L5*5V&v&$lO7Q(O_!qAvi=pWh$P{mlnFy$iyM>Y_=2>Er5yLPr# z>V%gaQy8(;vmPlIjmXieugKz%TKsZR8`Stf`EQS+*9WXzGysNz9##(M6o5Qii=xEv z)BSoNPdX|v6XF#VNpHq^N$WAkloGG<994DRKHAu8Ri{gp63M49Ow*RCJE%b!c6IJS zL{kn|!H^TpX*wqvgoFTCKl&XAch(L&)k$PBR_cqZCN23TV{GuDL93dmy%}Fa4vKF- zd;3&D44=Gz_NTwi^ow6JllcAHuMe*kKfyC!zkhN(<0t3i{5t@Y_)*AT)PMc$@n4p0ppL=g5_K6SOS_hNj1r2%uHQZvmoIKfbkRX;Y%lB|f zFsT5hyeN=n`_@&=Q-<>J?1EPQ*zHogS|$JqkJn;>?-znyesDthv$;~ofcYZRfeFco zj}3ZNwdS|>KxFn7?E8}>^KuZ-FtEr5?ZJUROVXC8y=d%KP@RByDGDHo%c^4K6@$cX zN$}cbl%qQ^|5xgzON~2kxQMuF&U2qPZS8o6a)O?iwdd!!LkDu%3E$N|`w96BL$kw@ zrOnU-1ERpGeIesk@hE_k&P*<$pNs`?=lfJ~*LIb!HJStVAbQ>-mm{d_;c53QVEhP| z`J`^$X9U_Aagi?)2w&}yS#9?$6v$~-I)zTA3vLYR-dHo88%7Cr;MJ-KT%=g%AQ=Tl z>^8;%%XSHm%1$J{Zd9;T@nuT2LsYWgSB%dU0g?5T$;9b_h=H@;>dr8aQ{~!^<4F?2 z;1A2u@#%ppM(ZeEkC_a_RBh4pQ1^Bx>At!`m5p$`Ve}N1f7~j!|O==@-BOd4qR4!X1h`CbgDT%&s^KX1}b}J~81yodi2q z8p}&yjXENA5QFwG`UuRzIM{l>wGha+<4YI%)ipm_@Bub9K%Pn=w9&?}WC1S%PF6ZjZ4%2%FSh>Q^o{qAcS`Qci6iUCwKY{)Y zAthHxP$@#+WrqNHs7V|F8fRl3gFZ_f9vxMYFK7kwN%j9xoA>;Ht9D)5mjK`pgk3S! zFyj|^lGhD#Az3Sz;)04j8;U2{@$fb{E>Yzih{$W**o-(DTHEmfF=hK9B|~V`vU1@F zV@5DBBh>R#icgf}`f)LY;krEb*=CMu56UW?2AFPU9I|>KKsog^^>GJhwbq+Cyee&sA5$iIf6R?+z8NZPJa(K#=y9OqeA(3P#1 z+|2bwjX{g$gm5v8u1a=vUm~cxaKc4=GA8XajH5}x;*u#JzgcpaVfbrzsUbF{3ZU=e*N|%c+NtvB!f~hVe}$Pl=-J(b@*fPCYiRDh3H_+%2in&J!tnuAC?a{lv>{nh8B z+W`4_Rdif>Z2{QBvaTNO;Y`y3Yw9G*bytrE^RJsX?ZLb()LNE+B|&d-ArWo+py1^s zMv9x!u!-tnyKIE1wrJJd-55x@aN8wotVtp7j(MuA$FxrAo5)t|>7>~x{E6&5>hp@j zb##XUQY(o+g*rw~$OPB+a-d2wV|k_PP2_&KOr7c!7V1v{!EW|(AQOjw%T!>P4vz#l zby>v*pzs~cnnvypNYhg`MMu8&XS4#52y6ML?3R!-x=`GF$&S7RfdqGCkc4fANlR^` zG-%8^#}^fEnO-A-MR|^dHeoRXcu(ohIhZCP`v2#_`>X5nxQ~5@);qHhSpy(R_969D8HwQ1bYEG z3+dR4C1T1{wvA+H775$)=HQR8t+mal2k2kRO5x3|t=xdKY^T6}xPdYl+va*iJi+mM`B& zpky(HI?qGyG1HCj*x%^k*UKk_3t^y9EGCMWEbtW~qPZO<&#I^=k%@+zJM}G-0!^$h zRJDg>OpA8wvOpVlR!4JlglKdrF3~9&_K=ko|p+pMG z%14ZQ*&Dn7$#+%`HsJW_kv8bAYWu|pFqNQy+g`!8T@KKEf>EDZ*}MH7v{8=k>IF{m zC-*$~qbp`t&(n)+5%Yx1s(R*^k@^y~&*@|n@pcb(H64FsF& z%sWKkcm7?>g9s9VK0Q(edj?%0nCn4E1k;+UcXy8J0@GHud}CJ6j%9JQN4~)j=XZe= zlh59Ng>2z7iRhoACGzv|{)gfTHFLKh8(wXg1Cu3-j`FeRu*zTv35%d8Fn2x4K4uKNauZ%9 zfFJ;_q-G4`vzMKzbyfltUlah*WE1-%GBUcVjan#g))N6A%;1?7Dx!ylJ_s||;o^h$ z#XbL)<1UbTVbyqOqe$wdt3#GIhvZR=H*$QEcW>wrxKdj*%c>Neju4P-NDM8;2}%tX zicG>|y@ac&M2zd&gBh_OsjfgQ-wS$`F_|%>zSQ|>qwpiaxVrh^b3II;b|bxzemGf)-}%{C~}0Z zk}tQ{jy3?r$EZRQP^55$&a=rs*ydHeegMXBc?nqnsyjZ?BL!-8Cl)~p=|O1-7%@p+ z(5{bwTv#!0mIp~-uBZW_X`;0n+kV=#sLE$eApIcrs;vYq5{lC_sPJEGJvMOflOkR1 zLyp*RKe$xalb(OZCu(Meiv7{je5I~~`>;$KVMJF{)I=$E@cpUO4}4^O9$kRrqTC)k zbcbLdTOrrLS=1%w+0?qoU1Y%m`x11?vCl&b9(#4`p|qAzU&0*u*zXA;K}#I*w zL8xk2HexO-jR#ccluNuQ*QUC&yoLIOm7^*aff-3fl!1Z_Tp2=z#qN=8fi9IO5PSN& z1GcTW0HFL75a72-7S&duP{Rj8okt0vhhW6=h*n{!cS$=-;cr$OaaJq^Kg1_DjRM{zdq~NgdlwO#hW|fuBh<`qSSbD*fT@ zQv($+HvK-l|K30Z)Yr6X_n+Q=6W+hX*H0lIfiL-)w;zXZ|4)fvx@F}E_6(*7y+eIf zYEZX>@K(MBvZO*c*-d0PqK;v#A27dC;?i~Y6FEM_ZXbxgAb67!iIdqYuk9Z6^2@fc zwU|EBHUy(#M-{k{&pON1eg;bBWg#bPR4OzRCZ9S50R5pHUm5@K00utmJz0YtegyWn zkXPOzt9cFA>k;Bq#ZEi?Xq2Fnuh|-=u?YlZhLllqMMntC9AeAzmpBeOnzI+t^<)fH zqKun}NF1~^xu93rBClZtl&qr3ZU4LB!j?u=i8*dandeA#&LkVX>-;Xsok-9$Y8QM3 zm(k@KweXQQb`T37KtI=ovXSubm44YXHVU~vXgo3m&i~T_eaH4>Ups5U5Y|JOQym4b z8wUsDR0o*tS0Q}O78FQ5>8)g@;Oi(aO2pr-}m;%l$ z10fnk(mYrLUP#Uor_h*CkpSz{jKKT%M|`$+_E1U8dm#DQOKNTCV<)=K5Faqy=14#m z_6uaX@gZ2OmJfsV<1n~;7YNz$cEn(SGkB&WeE{}kt-%0(b^Y&jPP>wTfJ`&1{^& z#wK~753FSiO-dJ4m;tUc;Y=Oy7)r3;!XeSbNGX|nOZ(qxJGQ`^|yEz2Y$hxQWC!!v+;G!)xv z2(Jc@;98P8mOqxfn5bLx+EV;oDxRkxX^W5u_%H8q9iv6&Qe!J_qYaB??MnA zWe0dxV=fVEudJXXjbQ1KUrSA8WmvqOXLXrOP8oq%Ctw#AFt-wx)3WGz9#l-o0y2mc z)poM_UK4B-w;ZACI4{IaVI4`_K%icmJag_IjL9gjJthHgS+bF$p2;2H|4l-esB@g< zRDD3B8WzDs;HA`qLU3&Vuo&Ne$>D-il%fw@H0RU4Mn zStad3R#nk3eZMvyKar`$wd_AMxR4renh^*fnm5VIroTlZPeHPqUSp>ug}0L#Sdve% zOa0T%hE?wk3u9AwaA%dBBw5wH3p@>HB5e#AF>n$}Bj2g9#YpVtTqh#*onZ z-eKwm!=;k~<^WI{E9PKw_r0njWdI#?a0<0NA=phy`6Xh1zl~%NBy_(x3hmQ@O@cK1 zE5kC9WOK|zZ;iIq2PGOK0;Gb)U6N@77|uLEc{5@DjK3 zBOCN#uxhy&Z!?-`-MvlZ+N0w@Gf}wSTAl@iiZ~Z7_HYK#p5k?_(sZG&miH3bqv4th z2z}4;^-jKI6IP4xTCxL^?|fdVUmu`#=FRX5w_NU*Fwq#UXsG7X2CcySwyuDQE#wQq zp=!>5Kq8d!@hW{e1(A>Ikh1B;y=))1dncsY=Bmsna6>jg2Q zjupR$AzKwu6Du^Hqf{fuy2k|MZ%MX?07>uiZctpd6rn^56liG|U`FLW-f1cY9G(19 zC&`vXmtJVtm1|LzLfyS;K4#9<5Aw zyg`dfTg2K0X+Kk|Ef9Ci55<*V}TJ_ot~ zmkQB)`#1a>-hYL7{-a>Tp+k zd`}foxZ3i2#`dy>X95Dzf1gx!R)pt)h2;TIU)0`hwHmnQflofUjQ09aL5vTbgwTqn zin`QavMk#>b7DycrURwCs<8^;@T-c;_yl*=Y)MOURSz5|21BjV10}=Z8wwzT#OsqV z5qyZPZ~deKbL1>ryVxJ(7fHP(Ob`i0ug&*X^mfDNz? zeD`jN_OfnedA?1-7l@ww^HK&Wzq)+v-Ijj6oxLawDi3`#9As4F<7y^gJPB8zok9F$QKrJ5w#I-u%Z-T5zT!GTR zr;{_e)wMqN_NTXSBei`F!` zwCyO#=A$sUOPMV79+9gVt5J%7n+;cC;*>bIP6NaUA{U(+pm)0}I^Ov)XbMBWbXn4t zd0-5w;Or^aHWfA$1n2j1C)$C4+p%T zb18sITlZ$_F@x+Oe<`;=2EP~LghN?plrM4%*OL2?PIm!Jtz*|}> z7;7nX>8_XB45?CwdfGB2sM=8qPLiJv{odusf3V1KAJz(L+f4KYfIH-wEme!c%kG@T zx_vOO)9#^}T_gzl7;G=8b307eU@bb|LxvQ|u`C1RQsXmB?!&2=2iF`JQDPe(0S$iO zBcf?X=0{s3?SuP+4uPZPRy&lELD~bAtW)>1SRg#($c=JTQRyq~-OB!{Wx>R(YLpZo zYT+(-55A$?=tOLnS<(9;8--_0JGxU+FmyiVL>uF-L-B=OH_RvGdU#b>s<=ZZUt9E+ z7YRYH{Dsg(B^nNDA8ar~*HKwCN%F8QxP3hKpGOPwgWNzB8_7^3dFa2gCt*G=mm6QE zlT}7o=@=^S`Xo`Ko_9Q!s3D=hgEy!WQLR;?k{eSa3%%k4HnWe4R?LSbSZQq6m?y=r z*aP{u@>K zNUh2EEanvct7He`i~=B2*Smq?{fGw2HsjvG2)D9L2nOxO$A*;{lOUvLPG&$ZJ<<0G z`bPtX&QwWokqGtl;vt6Jlkyx`;Z4xrFQ&1E=#I__dKNE}PEHbxKfCaZbn^n$;8t6z zFku1ZLvT{8J5tK;G!O!S!Vfdy0-&}SQWf-teE2#%s~Do@Cr4gUE5d>%TXH$q_>mld zzUsE-UPAY62S&h?Cx`A(+Rs+jk{x8%8xHg}CAZ@n8dp2S5U_2G0G1(PQH=vf=67)h z@Xo_JdQNv`L|AJ?-cSl3b>owGeU&VbJH`4USz^}u9uQsHvtOtDf~_xZ?JKM38>+~T z0Oxj<&7|c*1yxXLS|~?BtHGs{v(T7f_hswPjX+S4M~w3~EIkecW}u)flr^J7phd$8 zbA)+4=#PriY<*IE-GWqe_9w3}rpia^|47N}tEzPyhWD!IL`kF!Fmsi74ei3JxXQBF zhP&i%Pfks*#4{Bj+f*uA2u07a+YVe92DiP*Zd`O;<9dbK;o^zn;|u+D5M;r9Z8M4& zHT{~$Ly`j|-CAx(E!wOFmsHQV0JM?&O{RM>4^hQSxz+Bi$2)cUu)iXk4KfnDf03#& z!5Gv?Tq>!~A?Wbix&z&(##;|J6~(vROz2Rqa8JjlI(jPww~Hm()s9#txvlXYG4`jn zvt%LjxH{y2#k9)&4**QL?eb$an`mf9k7=kI?EFthsf?T_L8i{jh=>+Q$i{=?fZ!?*uv-}&}UP-Ua9ir1F1 zV9yz&26ydxCiqcehM7;xN}|J(d^Vev4*;hu9;16nKH9PKULvSgCs^?VeJqD-J`&n8 zb*pWXjPbVM-`$Z(OAuBi5>qf#7uGbuEnamq)v#xw$Y(>uUvhy#00r9uj-3OXr>y;<^zpfv zo89V+Iqr~NnH+Jj0hWqyr&8wL^N^V=f1>T1kQ-%8+8AWf%FP5#i1sfvDW^~E=Yx#7LAX4e@ z64>~5*p3S;mD(yFihn0G2c}tSO=~Nlvzy?1^^hc|l&DyCtz+5ed4%m2WLiz8QLesC zbD+po+HgoqDL@%vIbK{_$fdAVb1j4Ky#O^%3Dm=3Kj`}x74u$O$S#JvCM8Zn1IK#h zGznf;m-up4D2B;0)00c+O*a-}9^Ts$!S9XZn^Jltof9X}?~7VzEoOp+z0h8Cz2P#P z+&<(15Eq#z*Q#R(yT6pC!*r#ds!%Wa0wGZX!;cPIxr26r2^aDo<}Lv8&RcaS}8 z?l!f z)syKP(bSiH>Il1*kc{;6>9M+@Kkm(WCF0d=wQjOA#eq#K6bELpr40^@ z4o{~N67!K9U>am;5HM$wx^*4pm>?Y}$v<--kUby)IimfZUl`^%Nh+oG1m%=fv3d_> zRTOOGq-Pwk>s2Q)z)6zx0v)H*IB5dX3gcbFi43N|Ca>kuB3jCAN>paNtFP&4%U1|V z(rzggeunlAIVyC1RvbaeCbLOn`!tcuJk3flZ5 zdk=i&@1b_(95_vbx%sp*13fDR)Vw@9QOtdi%K#S zsQH27Ky!^d_6Z{ABri{p_?_+T$mPA}4F-W+V45SFRH&on4*Z3_YR#wjK)bqvYbr z8i8PjL>=$VY#q$LIFGO)+6N*U%vwmdKs{|Okq6MYax+|tv^q3U5A|PbX24_(BCUN~ ziquP)k5p{t?gGv~YaA%lc@M-^e!CpWNSe0biUyrreBbmS6D_~_$z%h_4;Bp7xb)+c zUD=$eg>oO`JkDXV0Wy}oQaV=V4LW!G05({qNiH+k4)U$_khKaeQP{NeU`c}9Mwgl7 zb)*SsB1%qTU5HX;;;N4A8Nj08nx65q`5|}=;(Z;k9eFw^g(=dt6B&ndIME;BSVvY; ze-@)JRfavsaF}D!{adzfNoMioKorMCZuLvJqybjG`Jp*0D=>kRf)1&|6fjsBh6MFZ z=o-_`R+gfI0XVLTxA4>~LqaGhB&B}5He@uQ%G*C5XD6V_mlQSlJY-b^P(pqd{`9}7 zGgh|e{sfSekKcd)uHW-VQbzzm`4kY8_upr2r%&=@pJZ6dSNdJM4g&z@`aqjvr=^Fa z8}c!v9X%BYsnD`>fpQTBXFi~Nw1?pKsb)1$_MIi*+{wh-yGsr(-*N*k?{- z#mr*CAot#I+efyS-E8SZrIt2_h&OIn3Rr?FOMFQy6^ul~J{=;~SY16N>Mvxbm6yfT^)ev|DyY<3JY!6%^ z?3!&J1Nndn*HAX+dcz*~*SIqIYcP7`f$@580H1fqt6 ztQ}XcfVdjCrd1vp``l<*aFU}6$0a?V21q!x;Z`V}a4P`3wUs4dueS_jR>JJjAio_=!b|k&o;NI2jIH<)cM$mRw&UP@h7ruvF`s zbBzt$=6r;D@2r5o-9yHV6_P?sX*es6q3lSsppe7}2v&D))t9wII+>vJAZyt?H$h=c zg=tO>7v!^kC$F&#-AQBm5gyB-&Hw@*dmaFb+Hhw*0X3#9_QfB90FP5rdXSSh_BiBS z+c%-_O<@XUb5GPqT%=^YSz3cljT2M(7&`e8+i8{g;z(4<-4RLc1cJ5l1+>;aHTH_p za}T3CT%h}wIs#ImM|)7!nA&@;WM*u9dqm#w<0@tPdGhI$VEl!~@ z^y9XdZJSz;R|SdWgE(ZXWb3Ot{Zn$3)REfHYrL5*0fNEfcu`+J6FgFqpAT8iIdEZYH0_418mxjn`U!%DE zOkGy>!tf~z%v7yGdPRH9 zI~QRsCErj|F`=bs(b;$fZ8aDgEU_$YJL8II6+c9;i_X)BI^CcUFJB>btF9U# zDCnCh9q^(3AWT>;Fq-X(Y6@5OHD>fVc~VuFCzAjx;kDfC`oJgx=qN{wE~gZ>#B>A_ z&Lyz7OhEu0FG0*PAV(7(M0GApmQ5sG{sBc zGz&Bt+_r#EuLVR-CuS|VSMdJFv%mIlpk4IsXYc>=_N(yikKTX!_9f%=?-7+xd>I7g zU)Upm#fLtA`}o`c?fr-0Z=h`W8wF(mogx1>Ud#XS_OJ5)-v{|8Gi%^1b)%!DSpnN7 z__AY5Xh!yg(HjSSb#^xIGu$f+#?XS69rhV_U@Ud6)H1v(NrY6BKt}!AQpXsow5ije zx<(ePI=UOdc(JlxZbGPwBO;THy2-EG7*v6a1oUQcd1h5|2)-jJl7cZ907{}KkhTB} zfl_EWoFK80OG0n83nZN*bxaqCyEOI$@)e1kMgfs+pjTstXt0PmU6E;{8b^EVFkqwN zf*edEt&$;3joTVU`o-?SX~G0iWln~-C={~Ba5 z9 zq+C5mV$xL=kOHyVm|H5H(}%TvYVX(}B$7bXkR>qGTLu>F9k>XT(c8x?a#pB~8+t{# z6Cc%|FMpH4-Q*KA^4fjGObueK1}A8xVyDeT2+qEe4V7=(lMRqw6ZJ12u(g@l0|FPD{`zri++c! zj{PJv2Crpnv140>_d*|Dr3ikSbTM39M$f+0H9j`v|0u6Xu5Lox9jaO^aX4e&pO9L%GEVOnV)1^f-SOniJR7ir^2{(a5UG3qD|w4UK9KTVE=Lz@sW;yX|-gZl{1UV9l;ksz+BzF{6DX?+{if zw+A2&fCm0(BOw+tGDq+QbeAKA8RpQy$u)LU;GuBnP)LP+#uw=j1nyQV=MJIrd2@*# zGXAm2!aRDnKsKpnqiY3xC$H)xIRk$1j0W4s1i?(j<5PEre7uEM*P@tkw^*eKTuty} zcO1!H0M3!^lOo zw{Q=^H!HL7)6vxoS77y+_)2;p|62e8m@F$mq2=PjZScaqQ%(0}%>u-mq~b&>*{-y$}C-eo0e{btz&KE&;6p?g-kpX3}sq*{v|Cvs_C zk%{1n=HlFL?~f!~$O*wbLJ+NWfrMu~B6aY;Jlx$tB7=tkXmD*#HKgq_Ui;4$!IX zx-4Enn=WI0+A%CUWubGD0E0hRz8-=W!$HRwA^#nYkkX?kQUf+;iib)bOk`8^BOFRm z^c(!WZ$j0P+EM$o9=r~@J0ZmXi9Jvm0H$+*Q3q8COT@YnBD8K%3F!z*KS>6ckD|86 zsCWT^AV9m!NjeLe6GMrsBsHXDnz_w!zlXcj_~04f61!?+ z0Jz?cpv#znM+@P>*(*P!F$jZ)3R+HOAZmkrXDwP)-qfcgXFObCR6)uyzY?tnoeD{g z1JwyP<7;vaLIjfvU|c)OmS53VTD|<98ZEd@6-zUd!_fSKsUYdNxU&}|h2&FTltq`n zTxMFu!GbdHGN!3=(OcKD$ZSiS4~Nz*#ero8RJ&7`1k;qJ$F!24@-6dv035QFB)0z= z*(h&JME3CsuY>1N*H;~|Ar<@*W+MVsH@OTYW<>e4(LRWpQ`NHr5EGCg^kAU!7yFWK@ID8&8HnKu%Td)SDL|yplG2-Y>5GCuR^Im z;3e5lB()IR$k&wLR>~LXWAJL13Wl+0zrZ0440^YsKv!*?K)8_mJIW`~7qQH9b2O#Y$BdK1|~^4ouU`$c&B4ZeN}rHNPQ z;pQm*8peCJm;}(#ByRTJ$hyy4C@+lBfce`k`OL!3?%xE6Iojs9)a`X(yq0BmVZOg9 z%1qJI14H6Nb^J+AlCaUX*7KgA3N;=|{#OFzvf9H5MX_ox`8w~QJl0FGRvDED%Co6U z#FmzbS7Dj?4b2Jvy1Y0x-a8e`^t5$+PpTu_kC;)zPHDQndUtV5#QsJh4ME6cu zMyJR^&L1iSk~ejvFT7yMs{zl^KS=O-fWTIw)h4WEIDrF#YLu)fpCF-j>()i3aotEV zN)(>xEgkxUnW46f#oU(2NFEq*QR)HwBI-cM_e|Z$9zyFLao%^g!1Pgw*J2uRZN^ip zU3R|a8QJNcx`U`O)d#?Hg34=f1djS@mLu*j6JVHKTy~tGlIe>0Cd$yT4dea!8q{q@ z)HxV{7?R2WyuyYF)Z9VslArR@(RP>Be=1xt&NnFs#L0gKLBguc9*Y-ipLWzxOsp`h zU&3RQv}vQ&5)gqFa?^_Wqw6kUsG_bd7JucM0~s`5x5EKI_IcOz*Etn;#vYhZH+zzN zV&QjHd5%cv-v&2_LMNpi+^5^5KpIzbM2xkZ0BA-7_RS!Bx$M_n34)Y#M9XN)TK-gI zj-jo|RFEr>I2F1<^(r61B|xe@Ik;TFII%`W4Lv2*Z3tJJEuc4nc0q8Bup3)zQr-=xyltM>$A=15KXnjZ5PL{IvAuK%@?dJF_0T5= zC|IJui(i32a@W?wBtII$Kzmedm#&v5>0NL(Jh6*Cl&c4clEq>9m)m z;uSUeTDrU%RMkl)06ZA-0jTm3J?k;+GC&8f(HoSBz^s-R2)1nHKm!31txBPE%cJ4Y z?ND{BBxM(58X3Ryj2p{79gm^XOWF(Im<-2v(r)AxLa0EqHdAO(z@ZdSKEI#gxkWVM zhyWd^-d~QZTa=XJp!}!Osdy$XojUiJgp;}REU%l~DHh{Oc!M!3v%a48xp{(EJ<9~!~mk$#D;q5D&{YwGkFdMsLevrbRiXE#?!jRp>FY0%thfi6g z+H9cHQQP%-7Ej_7#G;GGL-uu(!Bh>khbJ9*)F7#LgTR>|3RP8Lu%z0lK=@RZloul< zVb*QALsxGdgR?pt%zqXMo5)k*swjGL8`2>;yvC10yF2+(y#p3-qwIlnh`oV39biHz z*#-phVM-nF6XY!@jCZ!e8X{8bS|B4oj1=UCm%x9ae1f6bnNVyH-apucHg33bbl(C< zl)7Tx>an|EB9R7;1{6zx4Z5-%;Q>ND$&ZR3T-*eF8mHXmef4s^Jq>iGi_k9LIkDa zqB=D2e(`!mZ~CBJV*dn%&l|`+z}f?58+`zZufQN@o2+-l_bN-kpklIXR|*xguH=2h zw7a3IbD#_qfPMGk)JVZ4!9}C!zCa&`BuU3LPo}Pz#$L25nH<n26>{+1kmHAyrpaS)$Uay z`MW6*Z*q=1t*MoGT2NZY(}#s75ez=}%T2kz0P}l|F|ME42DZb?=d3 zT|2HFpavJ-*rhVtEY=Ucb(C${wc1FW8iE89D$+&0B^+v6!r%4D{y_PNP-~nd^T))X z1kuUr3q?`Fk7AkBt&WV=h#h>M#GF7=fMnMq)|<{?4)^Is zOEdd5Rn@gU21#^XEWv{6itqm*eE%>0og6{Zf;>YwMgRAYNpJj^@%=a9{kO$_7{t81 zoD5B&ti;4i*3+g76l;k-QZR&Wm*No#n^a*XSy3kBDPk^3mHH-HVVhtyNh$aC=7Bxdj z;Q*^n%Z`=jnvYOn8W)A~9SH-ZFLx*@WOK%7uYtxwjj+ zmF(}g3bL@4eo~rAm7rt|-%;lsAo9_Ky5v4M!H^c0SI=M(P5n#xM7Ay0xoYj4kESpe znLT=m#@1G9%IJwnSYDHhat*gYp#*Ra7b-&rYm4>S80si_p~a3h zkQfFKx2L5jQlXhS)RwLox+-2m@>TAPx0o5foDHa^N>FtcavRe@bCeI5l)?>nNt&J4 zI73zj?aiaQ)b+Y`2M};RfPiw5S^)Lx@Z6ba48i(6ux6HA-A*vu)`$S)m#a`+;BV6w zkfWn+1f-o_c;^Dz02HF75m@WEyUc|mQxc$i%bEc71*5R69;74zLO6Pp)X=la_L_84 zPJN)rQYhy(T{u99pwnspKxzsr>9ui3B?1^sklX>7631*h?wPOvI08T>#~lTje`Hv8 zGAPFkPE#?}uAoq<%Vej>I~W?v2Md3?sKWbLWB{&0m)7T~u>>wJo<$ zFO~ZQlpX-t43~h0U1f`kDnr?Fd>@`Ok0eIHIRUnN4(nH6WLieuTGau~C#}-mo)WVc z#i`jZtizbRdWWAnW3#!neGr)cEI=R6{ye<@2;xeL>HGZsEBZ=&_WntD`z-?XH^BSr zm;7&j{vY3e1dv})BjbN~`&F^4Bu%a$WusY^Fm85+0XT4qbcEa`vy^<=6o+2Aa|nKc z3$GLst2M1K1IrN~d~1AG&ynT5ly7&RXgyR4YbaF00=8cH$1wTd!S!CKsx%^TzzA?M zO!qn?;6px)Lp)Ve+9V0UL=I+?oa&=?KV%D_x|TBqmy1-7b(bZG62N;Z$1J;-Ja8*k zdT%N;*JsOVS<#ns5WpHA8Uv{}fP{3FCA-i_0;U;q6LQ|XbfAhu8PZaQdl>K!auxNI z>R@OoG0%D+@{r1}%{lb|U|D&Ck{#k}nJ5vv=rng$bfHdBn3JeMIws(Bn2Kd=R93_7 z9q~SAyVA?y5IXPpxVn?pHDskJPXPiUg{mO+9dqYkA_iL3@;><0GxFq~V^_II*bqC< zJ|tA_OiZA0qhI2|W`>Vrcx{ZF018AFhm4LZXn+`G9s-)W?J+R8#ENvNE}Sudw(LiU zVOc1gWK+7xzx^c)rR5Ma;9-+VpQwzagjG&G)IpNm$1Y0vUbAiTLOTsez06D>n5vH9 zvK515Lz3PtV5sHPVU$XZFv|AZzkmB-7-?H50eU@#&I3en$X zA66Lf(#4uc{BcZ{HR=Q11z!$venBS%kGYp?M)p{&Tri!q_*#Mc6JCo@l;7*iR zNbqa8#Ee_X=>i5c%u-;+M0;U4;t|XV_TlXK1Q-WP=7YSW8;L|j*Si5~5MU_8zaAM<~R?B(QXs)496iy*Z4&0Q-HfmH;uUm2*E7N zXfGcg&Z(Wnlyb08OAx z;Uk-@wsaqkLgxw4J+J9AJe%U7a{Ku&z?8=*ge!o;#kMqEsNHXLTkL*^a@L^ck?}C! zO4v6s+j92yI=1MFrz2T`Octb|mr9b97bn}Tx(=9eJPG9mWkD@Hh(|=Dv!{^K1x!Wi z2f*OMxDe|#jq?@z?#OaZ{W0U9v*tuk3?*C5hb0C~@OUzT3NkW-nSw3jMV+Ml^>pCr zH(6mJw@FS`(eu$y2Af}XCY1`p^h@#=HB1~@0wW&C80}at2pyjwj=+6<0p*ZM#KYj7 z5@n^@#%!`W)G1YTACqJ`Qk3O^ppdtR1vv~TH^=DMz% z_pdlK0$4H(d9DDFe@GIeUR_mPk5jBi_pKfTaFk&N$;?0|kx7cCNRd?ZpiNOSaC!B= zve!O)?W*rHgbboM->s^9c^}^8sr?1@J#a&+`*>iuy3z5t9qXV2PBnxxQtohESIe`ee^Eu>$DUGB$hg61Tp?_N`h)z3 zeIydR%2wWlI@0z4mKf&n2!XUsV#?Y}ky7RCi&D}62@?^?4~hyjP_Sb^C6jV_%J{1lkdM3f zl5#4_V_is5o|#)46hKZ?Q@}pJ?&v&?;pyLaN?^|8%P|#!z^{%@pFk>;Ko96DRA7PH zA-dp#O^yVbjxJ<=nqng8bA>0;CObzQ&)uDdK{Kq>Il^v^Es2P5v?29 zyfh~iLKq`=<_pNPWRHBnaYMWI)=Zx#ho(;i%!JpEFW9hcy7>ZS zfzN>-3nou9cc@1U`%`1X+_Lb|vbFKZdhAAZOW;xj$`2o5Sd9o#g5OHw6yyjaEuOTF z)nn)iD8}4sHCl*uwH|^B0F%LjQ`ZQ19j^=k1EcaVTWVp{eDZv3Di2v*W$l6e)>uZlvt zDxmQkaZ7-D0SDx^P=6*=|D4W7w<(L7LTsR72%IlRc$ux3XS$Rb-b?b!hFn%|0Ri-C zlp9y+5_PohqWUnAl7V36YC2?~){D?$xNzPs6rK}?=$N}Lg91{e3qn znUyhr+sL2j!p-;*;7nrCw#@RI4n2`3W2Y+S45sEx*U+XnpMq?-X+U)=+ut=B(2%FX zu)zkLK3V6riT6PNg6m62H|ue)g1iI@OXow3)zjMmdKa`s9wjodL1*@skYLF`SEM$j z9}y(rrjdUD7cg^adjSXGmQ4Z-rt(TGpqAU0>rJIK8n&5cgw|3R+8Is8Fy@TSmKVCj z#+3W0w8UUxLq^BZxG&X2WS~AWp3I*kTzzuS_Z*MNIwd|FLg-?f2k5)x#-Mm{#!P|b zL~<%UNNG3^C>zvp@m*synBWG@5jcdBrGHKq9{j8Bg6R^H2NAt&t2W%XX71#$(*~iZ zTA1UgB1lYuv%;w{1=<0pIIZOOn|9t!r{>mo&SwB3O|Q9E*xLp7a!9gOJ}ib_RI0?o z=Lq}B=mB z2lv()obAtSgI9%x0|H$G1?JdfC52ddxE0=1W@F@mF!-;--`U5% zOw@=UgdhEF+Ot1H5U3?xz-;li$#e0yyz-B4zYBkvPX2o!P2#7opI}v@r^9o@%fTWG z4hr&nrd#W&PL-7(3oc6CpnVDlc^-p*6LfGUs-n%Qt!dlwP#6LR#;E(5`DaOGNJxr3 z59|y8h29-tA7M)08L6a)YUQqQI3nyq_6)m!73oUJ35z>{E`8NbQa&2MfZ~9?2lZ%3k>c`8u!$ki^rB&) z=^Us*a4<1G!an=phK`N8sgKS)UosuMXN*Wi4Z{BGVuT_Fnr1gG^6gt?QaZItMe6x^ zjcgR~@o2zVXNv<>Wbg+hq|Hn`Te7GqSlvf0=SairmJ%-v* zor&>P&vYYy2-blaMLxnx-bY+fWWytH=aoDWDLt+WTuZI6*-lYHpr&n12&F6cWJ zz9|iUc~E6Bp%=ip@{~4FI}UV!o#bVfeV?>cc+9i|$2wCpXAMca%A5nFpEfq0$|d2v7g0w$o`4!IRujkE{;+bgTi|n;DPXtFb{i zz3P(~5jg_>*4ca+PezHu-f3L+80N!K5-f`aD>Y))D{Z2?cu4+W78mMaUA8mntYGFP z;d44K1V%a(14BzgKb~}ws-bdyZl|>mfC2!`E1G_jpU`bp(e!T5(RmaI?*&!v3AAJq zh(?tj3Zh>95={G=p*T#3YG}fgm<~+T)|49E6f9Sw)0=9<$I3Ls9h|?7&e5TUzs0eA zH*~yxY9(?wSe{n_>_5h{ZT754WVUpweV&6^pOuT9nc4O#KF!$*5CjsK$QY3 z8$B(MOI=dRQfY%lHk*7yn`C919-T;5as}pk4-yK<$=)GiCOl1TkKEhAD_;7~a1?k;iW- z^7!rX-+e_v$XBKi`HI4jU%q|x`o;I3zkU4nEslfvMt%SJ>n8#7kDtAM8(x3*P8%e3 zOZKhz*1-c-LUCu;qraZ|9cUmJxIr>-dVG~;g87Qdj`Xvs-?0eL5zu41Hk!8)Rkg9G zA$5`!5SG&F{cbQMMU%%XoFrKpri2S)jyO$yRSr;V$)szzRp?S!UW^>|7|CdIP(EuW zX8Ht_Z14Ft%2A(Il4Dwep)8vl9Xj#I5pU6s8E)<*v%qJAed0xS9Zpm#41=1B#(cp7 zm%!k`H2`E9S$$^3_cWhEF~y_^O{o~`X5R=1vT}!Z{ak^~X}QD>j_Afy%G#vxP@oJklM?hlNZ}mYHMm3VR9U;1jLptfVVHi{JOfYnOeBnnkSz&g6AH6y5HKrvVzp+G zXKrF_3lf)IMSw*5V`Y(EElX4G1XOD7K?ZZsw$?hv`tQi6>O#D;R|B54VC!s1V-02o za%03FUOKe`F?@T}gHB`U(`K~~QxmaX4>YHOjZ8X3p0gdbVDe_GdhthCEQXPW4*3iz z_Y&MZ7eoiTUIAuTDZX>%Mp zsB%Up9vfNNFXutOW=@TDXMx}?qK$w(j3}}#7zkbSQ+HB_EVPua;dgHYl4?}9r}ZG5 zHq}jDJ{#7^8$7L)nih1dY9JY@RdCHZyT-hYM2%YISbape7QW;Z1q!MU9|5`XYKw<3 zn#cw#V|f86C>^bJe1&E-?Zi-<#EqnnaV=4^+Zl+){Y9q;%XF#Ac1&7|^-|9AUX<*$ zWTqZ4#zsU?q&+M!aeeVgiVtFx!>GZ4ejWsbv~mD?wTe#{4la6lZpwS5iQb{3KNE6S zNHHulEwnm~S~49v%kSY?3pu>Y-1TXjkwAE8KVQ_2e?0L-1!6II6K#B(TX-V4JQYv1 zi$*WX%RsngVYhCS=V3@Jdxj=cV+e*{gUJlyhDAy17Qa+8L#f8KiDOE#ED2@dc2VG| zCu1i&h{~D3^qEXkx&PABcRYMZkx^auOgGrf^KUa~E?^F=H9vT52{5ZZpWk_afSS&LVv*wL{HAZ50q#xp6;z)r$ywXV~x}0F167?j#GwN zdIh#g-Vjf%*--dLDT>%W-egV3Kk1i~TNeTH^tf2SaiRm|eE15jur`o#6g)%fQRb-0 zWGN*JJ(G0UWT_i+WtRg4?ZIV`tEnTdNNXZ_HG^+lB$*WRP;1LcsUD6<&y-!q4QW9) zd1}4xlG_(JnM@Ew+p=RJFQ$@2GPq7uIFx3m#uX2#`y2t_LYZiq@)yiV#v58zO4oM28+jBgkD z1+)cx-DoY5{uk_Hy4bi;LCj%}@6s!zd2?Nfc+!m(v4ty%cS$Jjhh z7|Wsr$^lrIW#&p5K^Dr~ony}V#+=9#;6wmDphQ6G6jh+1-rD3FAq!=XWCVG;4o0@r z|I<}onwqH~vd!mVdGKZHG$!RyfpxiOvi3dP?_tfL$gwTuw%xG?na1T7cTAX|yN}*V zgW%%P?W=9&&|BCemxdR%^8j)8)^CP<8QZqtXuIEA-P%5~FCA|%V47|3m+#L$f3pb| znl<#dCM5(M?#hGz8mqa{!N8Ppg-c=2cLcGn>T=g}H7 zuH*9r>1f@@O*UsKc9C)k>iLJ(r>w*MVSDkYVLFh8Li(02BJ*V^hHaj$jx-1Lm3iGS z!C7GFwPT;ic&5gBR=`!Ky-iC*fxWd;H_-;oI2n-YK%Ves%jEx@#mS^>&9ANwMw41p zJ9i87zij8Hav0HEut3msVh{3mK$r>veMNKtp-b=Knh}w`YW}==P*tlHSvsy{A6!$w z6_g#OQrZ98-m1C2^F$vT(6{3RLO@jTatj1bO;bC=5$ zSwBfy0&jP)%6?WxP&$UPW^~C>)=!XQSN)nzq%z38;2zPkS#}Gz{Bp}*ltg>4XbjQI z%b_sOzNXN=ui8+nNVEnaG`UEB@WBV+ua2$!TdCOL;_&w6**p3@YNmbsBRQMjy)PX7 z4FSQoZzs_3tGD0i)z?qnKJ}}wACuqd`j-Fw`ppkx>(bWy94Vj9~gw*}Kt08S`SR)FIWXKyKNh&<-R zMZhk`@)<>|f7J;pRg0-S=YhYhaiwold5utjqcRIYI+KYLXV%9(sn zStIc#YRuo79JYpR#z-HBu#i}vglNnu*B^&T61==L3NVxxTJm8usY8TSVsp-i@z?olHYf<2fW!nvqF%vHd{20&J+ zO6zpW4zex;(eS12uqN~Q@8JHWN4M=Je>Z)y;!;fw$_B!t4Y=Qq*HbGfkwE;<^_cJD zLfr%?QteD0p&=Z2XcT}nkw2R(HL$y0+tnxc0))b0(><%5XM0FxM&|D}nka#oU$B># zocvKVC}u-7(7Y%weuc&bBYiM?PC?*;lj!UXg^4QU-ak*Ll^{8zj^;-Yxh5h&9~-8t zjw+sr6_;D~NfIf{uW7x3$Eu81%rQ2Y8@DrAV{k+%;O9zraCFHx>SlV%Y%5u)YNWW% zf}LQuHYA}InOfDj4GKx@%MlqEqIT-jg+>ZiXx{`G^$+9+)!C8!VQJ$kD0X!LD9nAv zwuvB1D9}e{VW48;_`S?p6$4pMWC5w)eMh9$1rU=zO7K4+QJ+|*xZ-j=fT}$CNo)8w zxEk3)eazNl9?r(fyhboXWUGs`BGw8Z+|_K?zpO&ux!ZGtHQHWs->+c9saDw54$F}y z?lQyt;6vx&>>m5F#(d>&*C8)!WL~%?CEC-iUf%n=Sx|D#A{%p^U_&`KGBhm zIg4pP2r!qO=~!-_Sf1_(^wlFBR|^=X%NJC=yS0c^rHPtqma;HiYLRWld64D+E6i}9 zt|_MM0)hbH*h*uONVs`~JZDJyr~yf!y~uA^Ru-F1mCv|A;4|b9^e|C)QxR?M@h|H= z(At^K&H@kx;zf8XGR{Qq1H*icvJv_O<8(%UsD7l7Y9~!Z@=F;LN)cFJ8F7Z1Wt^Z# zDgVboCo)T!Q?6NeI&}h!IE2aqRSWVIc}pmq2?tIZ^(FT)eJt)_n@aC+#QeG~#gQ+7q@wZ? zF)=aVDNn6UWI)MNE9-QY8z>o3_vyIEPQ%U6mRuBg9x}PD+~TW8i4DpZr%IJqIfK9< z$B07#A7YM=YRg%tZidr$IWiV8Mw(-+8Jq$exp^`|YgL~!9DDqDOoFJX@8J9NNPjJU zUk_PSl?=^9!H=l~^^_U8+=$!)zk*YJoMS9_<-O95MUUpc^L?b0Va&KMzD*p^ARp`m z8eePZVCHEs#-axZaCUHv4}C$B{$f{!TV*!y2-?!DV77Te)TD4yG6dGta-TPB0c%DH z5Q_jCW&qYbhU+Kupt=vmC5h(xuoc87F|H@k$+buRuH&O?0l_A3wre&X)^I9wK}e3@ zd)13PjdOkigHZYS)LAN;KJ0@Ahl9JlR4;No!zW-RK$Ly5EYYE^2?Gz$ z>AK72QTtcP^Jyky)zhi9)e=1|T>CbHHb4{gX(L)Rw&fKFux0ll`G?xlt$iBWwIw@n zI*Nef37=u4UrEW*uxlfm;{hO`A9RmH%Mm{$M<5c;EjrLZQiMUd5{c*snYUf?YO?>N zt&_$Q^mWbenX?v$=V1%6Gnhm}NQaoIt49ooa%T)BRkm0(( zC1lhPaw)Ft`^x_C*5ICSVjrt*H;>A=UDRY= zQI3HC^fe7JXUF99sT<4OMVRRU*JaqhOffg zmvA=!G`xLw*>|f|cd4H*kJ(#x1`CwaLHPx#O!0f4u^Dr(;IoifdAKc5 zOql9)gKkXzYx|G38Qk2#hVa{@oIO4WKvXt2s;;Sz1Ik@Zw(2H(COnZlrkc;P0YiSY z(+^gzM6Dosn%xmLUXvY;4iX-GR_++@9M;d6EO|Ev_Kj$FuP43H8e14+by7_a2)JxG zky5*~1-L=>4&nx|0aQjjDsc&c3YibF1l{)E|F_p)!T)4E(hinKdtLQj^nsAd+Lo!p zvri5SjEF|LLTwIQhCtq4ox#0~^1@&{xqvbMAb?nDA(8CAJd}N@w6zWIApsktPmVyJic@h`6X9YVdggXzX(<=Yl>k&@#cvYdrhi8ID@02Z>MXQOYAbD53d zJb9ep6)QKKGFz_lFrC{KI$a61hoh=S=#i4rWnI6hZCV*+0bH3?qPI30I>UC+cDiu@ zM%hT}mXYp8CKXt58DU7R`Gqz?8mmWoNRCL9VGg&rH28SE3<>im8jhii71<*YG#YN0 z5uIf$eqQQQAkez%i5-(OIe=#Zb%Z;Jgwe?|DyMyD2Aj`Ype$Pi8~Kj}{~TsB&0&=) zB}-31`w$*i2z40q*~{x;OQrrb%V9Yv&pA7f3O}TXn6lpdW>5`}N~xB2aQB-Fv{_qm zo#c7-=FX0CfG44%)<+(1 za7(VXRJ98_`+{21Sv(z&aHwMQXBBV^BgMlmr0vXNUFz6WDyijpF8}O^Y?IqWKuqCO zQ^hj)Tf84MLyzJCrX!@0Qw19gYh4LgdYGyRf$11wp~3~JW!>D)AD)@X4mh3ajK_mi zFsxl8gvRR11=NITyy3*FtS&&Ag0J9d5{kBf3K(~SwOw9dwLIYEuE6$|Z(`G}G8kv0 zd{_}F@1uVAlhto2_&aln0=oHib8t)1-ox4jKB}ws%j^-xr+cia7b+gipo)D%NC{FV z+=8+c-u!e`KbpHmEE;Xdz{82L4?sY&=d{dF0T}T$MD8Fb2p^#-Ve_6LC^49N10szA zZ*8Q;=4!qm3D0xTb&Yc|FJ#2>ZI$7FcSdUihbBz4*Z`R^DWoe}4I>7_4j*cB(#^{u z{3l)+oCYqh1L>^pYVmjWzrX{%`hgCbU;~n9s=rh<4NORXf5eLa+fRM`{$T2#-@c(K z$sf*O$i+%MGNHjX@q4x66L-m=aNq$5c-|nv`-+8%S#e;!QY1@7Yk+EQ~WtdQVeN<_RQEW zSzuxihFJkbSloUCS{6N$TF}zmFW`O8Sx1nAtV`89dmXinML4Y0?NXLl@7C?ekMXyf znIXUO#7bM+X~IgY0t^EjNeqIl2Y0$t@@%usvT}k=8Ag*Xm<}i_y2FieRZrqY9_ES{ zq-Zo^J~9v2BeY>zkyfR~YzU9BYv&laWrEGS!4r@xpRWJWWx>g`bVtURDVJ|33p=^G z)j5Gmb6lkW<@5^KriW1)S{~qGXqF2+*ucVt<3)l#=prH>aZcP4>u{)=iP?cLrlBiQ zx`3(46Jvc1-?3|Bgi4^Z`gX4JRE6dT%$VaC5wdqospPAzK`Y=B>yvw+C`eh76FIK{ zeE@laWV1|A2DdEhvGY9u-8$kV1(>^p@uxky1Dap{0H{6iL z7$1o*1p#M$aIT;QRvXHuo$R6QnjsKasvdfXtPO%GA?fZ(&aE5IZ-wN>dOC0rv#%)B)RTnV6h#zILK`2T z9Qi7|@J{+lqPx6)Olr&*Z{NVo?3Zs}P(t(bw_m>g47RS{ynb{^R%icku_UZ8*+(9QM!$U|;4Da`2!a)-l1I)Wp(frvW-@_Nq21vtarBVS$ncX2?U6T6>qRY^WU*6(;T4;0Lga0k4pDrCsZw(S~YRM&(VLXIpTr0HGxa zk#vDoD{dvzBCT}Q;qZYU#+DB5nvptJ>L7An1eZI~muMh@IlVw8IA?Ci00rfT0dZk; zyt|A6caPY zm*AnWmAud$r!m-2z^o&OMt+qxIg|AA98V9(SqV8>UG+8cHHH!}BOaousYg>c+S8t# z(7;%ew|S;J8u}K~qC)=4+T;nF#CKkB)eD)Os=R4nPA`riVy9rUd!z+mjQfbBhz~cq zrH{%>kTv^I)xu4T@BpgZ@x)ykt7tqG4|4@b!LmS0C)7>`Uvg-_;Um~E@-PM3r$c$; z?1vyeLjKM3%czF#2|~D))u7D&ewLqOhrQ2E1}FWbkR&U+|3%i8JT-D}44%`Y<)T^NHjxta+=7Wv zn5SN)GVO)~C^+@+%&moo2>(`1K%f%1U5e_k?=7oDiKm+$+^W+gFCn?q#9Jcw zGHYja+eTwM7J}&;DWBG0(s#QWa$3d4SzfwHJL%?{f<6_)XrYX19sP{xxZA^!#|O0M z*}k}0%BEA>$3>mg~moPij&)nN;93z~^=9W_6QlonBp~q5hJLa~6r64Fl%~|iQ zbMm)dwL6+J&}?w*?o-FXq44xq60E{utau5O@gCUT1*b`S*8y*;7VesPNBij66 zJ3@11a`!&P5Qv-r==*a`k-uj!mQNRTw16s*osLNmR-SkzkXwBJ(?9*xfPes$7R=g5 zNW-UewJm}Lh(f*Qgb+1$UL15UuF_rdZKah8^j2Umlf1lSSqEw60(?xI>w`M0j|Y>`eQ=M`^ob^h2ORmKmeE2>H>a~L-wFGAYZ0c@!lLP`*q3WU)j*+olhZt;nI8CZ-D)hXI# zU615Qo!*=?U=U4k^>~=tvts%U&FUxVvFLGsXb4R1j zp7?{6M?yhyyC^^yNw95{SZu=;L7cWn$42V9Jzli6FK7{CKwHHdeGILSP?gb*0~=_p zU2faSHY{)Y)Sj%|N2xnuNQU3eG&$;qq55?+$DA1|KlZvGEddDH=!S+Ima4-pT5Bgp zw#%88;s|VqW?rWju+rC#)&-I!+bretyRox0B?B?RC(n>-!1TTJ25gCT4wG2)@vgKP zFwqefBL{g?|pJsPSnw0FnY6*!CW)l|#ym0yL-+~QIQ zsE|@#Zq#R_-$ew8-1aqD!*`U|Fy6>^6&9s^=T499EIBdAq7IrQBfc?0Xlu_upX4Ph zl1w%uDPilg5=urr(lIr$eB^B=u^^!7!N4)olt_h+Tqin=}CJ3^=ce>rJKRIwLU2d!XRk z7M@zZ>VkaMv7mWqt$Qf>4p6dcHlpp6qp|0(Ro-F}%Bq7(I`jxu0XeEBUsGxURvW40 z0SkYO*ZeTgoO)3qDoe^}qs^vq!^w)YVr=uW2P$lqt;By}*SCC7H)L=gu5jqUEV6FV zIgqV|d#Qe74*sywPFqEhY2L{Mupg~q>f0bW|ejfGK4!Rnpv#6Tebc}ao-KbMh znmIX{wZI?yM0h;xz;Y7cOWH@G3Uve}4G2jtte9T}@2S^~aTs3I;X*F3hN$i;@hJo| zAap>!F~umMda<$^t9~_*p@~|d=9ED#TY0kRD@ydR2O4yiO8N!0Nq$KSf(0rksCb-~ za5Uxx2CZ&js;)Gplu|_#)y%`bt^v=YooQJfMlcn;5(fInvqlvqLDs1`>uFYsm?Geg zA(So#*-DMb?VlVZXc`Pw0xz`Vj-VZRB=2$z=xzULGJFe*y@h#IqRV^=63#QZDG>U6{w&MZ6+_oyicq8*OhetbJUakStDc55_(EsYMhEJ}kPc-L z7bsuKqQ_9z5p-L-QQ>TwX7=e6cBZll%*ycSP4dZch@?bp=mxpbxH3WnrnXMGe+Zh@bEU+8l2Ud0{YsYex z2L;`RyvpZDr@|FhoY8zxH4Bz-0PXooqne1InmCUqC&I)Tw#KW5(!s;q^t_li5?)wG zZq1NQ*K+`|s??&gh!!Nu-!_=D0xUXpa+hx<-%~9m-B4k9$kM(iA#Yy6fiMjF!i;KJ z*MQ6Th%B>vcP&%1hZ@>mwDy|}+3oB#xb^lTIJAR%s@c&XZKXJ9UyCee8|eLZb`KdH zR8iGlp*|@B%z~L#k12Gk?F95U27yiX+$l=}#q!)Bb21v~T&EN3v5?K#4)=nSQef6p zrDN&>8&l8^(n(mZX{DKvB-!ewYtRF(qa4Mfi2$KN>y%Dx8P+l=yrqTA6>VRoTrisk z$dc@VH)E!5jj|oeqHMrvbTg&_ZBgxTmQF?JWZ}$-0@g-qab#9yEXCz-&24Hf1#DCy zk9F&PC+Otf$*lv2KM*ugBP_~`e4VRZ4pQP_#(h~{(?TtzJscx#7^<@+x;)6Tcob-A`8NaJCxaO-Ub#8Bh zm0gH29nnW?#JtLAB{=b@xD}j2Yh1{FLG2ul1@TEGnO4y4>Qdo9ld##F@WIrUSv@~&8#x&Qn{T_T8v`kvG>lqSPX&q}{FW*OYA4J?1@?Oc8 z!deg7(ICH9*0gzel9M2(z&Wu%RW+_uc!au;e<+0nL!Hf#xd=BKBP81cveVVEWpuZX zc2RWzra;bD(HX;$E-k0tlAJSGj@f%JFAoAHX3{EQS3YHnpCWogAdvtD(5utcehVh3 zL}0x}whkTvkNb*&Z!h@yQZ$(~Rc_h#+ESP*s3Vi|NH_V(@WX1Fno)blrc!OYE?E>G zY;t**US0%l+(DbPhDeq!c~ao82}JJFh{DV}hb=UAE5YFiBU?o*pj=ja8ku`|^Du^T zv=&IBAe@m4Ad{o8p}=iZu$=*R;L`7hCk%4o&N31Y&qWxD8u?!O?S+nsJ-U-Sf0De| zlN*R*9-(wW`=k3vrJU6M@*S>-X+Adf9_F3h?pBmtT%QBw5&^D)p*!rx0j~4+B&K-x!m`(R(I$RM_R^9gD;O zy9Ij%)E=@uP;l#hS`f&S5RNFJlW9tmI#{S}$yRRUJ`;cwp9Eb!iZ=TpiMnaM6y)@z zqqxR4v3dFKkj)8K4`l-g$U?vCcbKd|n*owBgt5yuIebG$L^i|VcZ@o{rlTRtTPgR! z`^iQan_kf!NiDqe6-9I~P;PeT*%|(3flug;AA{5~Zn?&*X^06gGAk~n1gC4r)o^b! zxbU`WV@iRR5|vQjj%^u%vb&IjS9JAHA;uu9#XKCofbv#W0WW9aE8$aWZd3^ zkv|Tpx8P=y-?{1AVy%-as2^p|>P5|l1eo%Rv7=OHgtg7;rdr6qD$ugr+ZD}qhv5K$ z8E;ycJXQotM-dOT>?r?(lg7|$Pn_Ld*q|E7QRT5L$NwSx2ufGI_!pcRy-$aDN96j= zpZgg8Ute(1(A#e?H~Pcd|4HBT^Ve@e(vf`k`ir0+K2M+d-*W!;M})!2-DD5c6Luh; z&nd7}UMneR^z5-8VMmX+KLaDdY={(L;7uR=q!L^JdevUT%r(^USm1}?wN?s=5zUnj zY)?e&l&!KJ7?Qm{9oz^onJR=eE4x$ncZ9+rm&jtR(^m;%fJab@hH+o!wegH%?RUTc zLy+mP!{xyKOV}`7TZGA19xR0Kzjc5t3}0V1xDMn#c3(DSYZJu)k8nnl`3P&7jyq?O z{Xq@lO0qrU2KyD>v`YlBVuN7hTG1>C{ur`|p^b<}XFSqvTPy%_{|_A5Y`K~&wXkKE zI@oQ`s?wi&spcpzTuyCRZ4f~ zZV;U~5CZ?t+KL~-W{I?k-G?aC7V6qXB=Tp=zp`+;_gMxnc)W*4+Q`(zWzw<1LUyOM zfHY-A_AbB|Fo`!xSVp-w%tr&3;nan|Mm-(Y;c*OTjt~=c$l(|Rt|TG?mgp*wd4g@Z z=``e(82zZLoCyiJJ!>zikt*)xcQUC*c^9%8ZiFS(L%rNFd>~%eF2tXUK7E8wcZ*$jD6 zhnX3s2e3o5QWpbspf_<8U3RXg6ztWm) zIp*718PfV4k94*o)E1TsD6_K8$2dhB9_gJb8jZNrwbqx~qDe8P;9K4+RcT)hd|)cX ztT$*_hqiRLj#3T6(+M06$|#HDPBClAUoFSt9~oE|K-P7E>*}T+s12EcD-Y8_HP3^K zvGP#%0x`h8D`3Fq%`w$n-E2Jp)2K=-hsN_Q_>dn=mZpVWSII>dv&fLWGaSw|SIrKa zR$deQ3Sk@3Dzx`1%Qpl~uy2#gZU{Ks*KeQO z>5qS)2k&cHet%s38pM}$@Hqg@r^v9Ck3ZLdmrve)8*J+I1RL+78CDwpFi$gUxgA`f z^!UEWU8)T!M5XB!HTY@^o&L}a{!mlhBW67&%ehClVY;^v-9ysj&zr`C^ftt~Yi#So zXFb?5(~+9*TH|C^&c)y-!&Di#A(KVEr2!)K*~s9&+77529&9rh>vMqu1@el)#fGF#-J$0#LxXfSUtCiL%q! z=a;Qv(pD-IGwF(!MFv^W5H8&F5gr;IuBS9lusos6vP(gJw}EoiBo=22XvVmOb4yHV zPzkOx`E1CdJT^G!#nV$Y>q@p!%?iWB`pB!pqA0Jo)PvKqL+h5VXJ|gm3@x7MB@g9m zh!^u3MR~~)PQ+V~j%Xmmoy4d6c(?uyYW=V(buY-@{4G;r)R@Ox9wU_3t?Xwlm{(8`R&-Du!eD-Xtv3DAj-N(Pb2c?>jey=`Zm#l9!6=_< z*hARToSnZ_F;Mjvcq#Oxz$7cOTO)Y4bf(JSk3eH48&$2m;d; zWYif$1@2~WoViq>WYhU0L6-*h^J{!C`~rW3j|NKQ7J$P@_!4d#Em(EKK^F)cF(#9+{3#NC(bY)*)L?BQ&sZU1ZXrS2b!_-Sdf-+Msu` z(Q-?IVhp&H$S$yqQ!Wn-^Az7{Ze3SvH5OE{SXZF7fyr17)kE*WysPJfXv<}YM)Gtk zDCiw3lsN`BP@^Ht!;Q?ssTJdLl)1>tHUq!aThy|pv1^b`$%=F=PBsHsBDWQ2*+63* zPj4T0|y6o7q1kx*GcL1Gcwwiww{{0X2;4i}W|J9f%AAI2Ggdg>~yVbwvZ1&yz zACIp-zJ(*6Ur_b(9aS&K*S~)Hr@s&X*2W}#{+DmReEm8kx$pO%zx^x!yU*S}4{txe zBoF;F*XB3$4*40P^X$9)52$Var?GIs*w z#1EQgIxm5P>~s+&y=vs;K6`o(DbV5zbR2@Li1`6pMwNzU7}CJJPPQv}s}?Fe-z*U} z8K=I#nmI`H9)Q|W&&RPTmtJAL!!`cNKMu5$}9czj&fu9a1;y9wyr0x{y zYPR>R+tv(L*|flyLd5%KNu0C9E8WlX#G!88=wnSAV>&@sOg9NnI9;Y-b4R%3n~@=` z?m3%SdN>rBY5LN&h=Op!aB4CYhtj8!oqTGm;!qOH@`ik$(d+u<$|n3$$#QQ{4uF)C zH{|NbE1LCwp>n!7LWkW3OQpkuyQWPSH9NYhV{5;V!Y1#<^=fT5xml3T0~l8$!eUAC z9<0aQ&Sld|V^>!)rYnKN$~lKB2w}(&rRpp(U6)11kR8}V0A*}Nfmk!QxxH)$;^V2( z$o;cuTU%c%ZoT`xW1MNP^CXp}MHRQ5TXH3-GSp-SB#}L8GrFlTJ?fN*?yz^GA>R~8 z-4;OuGbtfTlC{E}+SYu1J{Srw-@@HM!)#*CO9+E#yN1*8fz@mK)+~`c5`eRS` zSt-i_>l&(xcKjii0g<~XaV~@Gb@L__89YP@PLpApyBf`@|YdsOE7trlSZ|qFgniO+RK{8-ox4FOVb+$Vs zzJdl^?UyTJEd?D87+7deaKaj}v9(q8pa7Trg|FarqZyUXP$evM+DCPljxaLnL4Jns z3Vr}-(yhid7{dd#u-t>kA}MceCjfy==&cBx?g22$V`pcO!?&Fr)H+Gu&P$4b$O(!* zr#Qo>$7Y8W1|4JTAx6+(0a<1qT09Mq8R#dlS0&V9c}|iT9sEpxy7=+K)XTyHRkpGMGdyX$o^xF+wY|{ z>?p-c&^6<Ilj#}*J9cO%Xh?M#GvVlQEo^6a?hSzaZUIJ?;>(s3^2QJ$SgNH>{}E$ z9YCm)O|mT8%QU?+rI_ML8ZE!vn%NsLl@p9gDvFO)j3)1!0h7mJ28;zJ5%=tLTIDt( ziD=d&-x>))AY_}Lifnj>c{L}f+9i0b%=9Tq%8;=_2Mh*4Qg+G>NPjlj;s!yp zIf*Vkh&?A`S$U>BT%bp4t4pKDK*cn$!`vc!DEfd7U8#+dCV9Hj%VRbs7(drrrD@6X znqJyH8&M!+p=JN_i68GkBWW|(! zuEnK(*wd$``P4+A<(k7WaA{D6nH5`u;jo$NH?VLyuvIM^aA~u-x^kFRXNwY~VT0dT z0EC8FfTj2A}$0d#Tvck&c87FeG$ucQE>4N6bhi=*`|H1p5?`8gK|23t|Qk z8|Dbi&}#S3+DwocwWIRNO01fsMQ?=`c|6Mn#dgFAtC~4pH=+ZL8auw&vkeU#RC(Sa zzj+^HPlgd5&GukmKLtWaF?d(cKybt?MQ9US; ztxONk0vixS8S>(hzAbw(#0>;C#ks|_ha+((8DqrW_Ad=hHlbPG7JCqoQYc=?dg}X> z=@SQQ4dhuRpq4|p(g#`?$z1JCMe_-s9ZCq=j%b8zcK3ZHG1D=BRYyW{d_f?@sE3m= z&|HmgkeI;Mhm!J^35$8OxjG^dfASN<0q3^NpF2JSh2Ov5RXTanenuCT&t8oT^u^mh zg}2{*uTwPnR^NXf-ae+l{Il@(HKu7_1qjU1RQlcj|G(kSeL{bx0Jc0m-n()VY;oHw zIzVB?O@_32+^NgTKrF&CdZi=_#;fQd&@66bKGZ$rBa(EUG?_*5Y5sg0q!@<>3)C3x zDHjQ08Yct5byJU)RZx}jpJ%P1PloKt@FZl9Bj8yPOMy-m){oxJYiEr>nJ)qwWT{Qp zj_mW)R04a=pMh1%Dv(aj1Q1nfowhih;WqMv}`9*1Gi{T$c5f9??B^HHhv{z(}TVD%q4)no;HK6^>A)q~X hSpdDrox+^4cgglrz7rRzDPZO0{{oPT@#kp3FaTBF64n3! literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/build.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/build.py new file mode 100644 index 00000000..26116445 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/build.py @@ -0,0 +1,117 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from typing import Any, Callable, Dict, List, Optional, Union +import torch.utils.data as torchdata + +from annotator.oneformer.detectron2.config import configurable + + +from annotator.oneformer.detectron2.data.common import DatasetFromList, MapDataset +from annotator.oneformer.detectron2.data.dataset_mapper import DatasetMapper +from annotator.oneformer.detectron2.data.samplers import ( + InferenceSampler, +) +from annotator.oneformer.detectron2.data.build import ( + get_detection_dataset_dicts, + trivial_batch_collator +) +""" +This file contains the default logic to build a dataloader for training or testing. +""" + +__all__ = [ + "build_detection_test_loader", +] + + +def _test_loader_from_config(cfg, dataset_name, mapper=None): + """ + Uses the given `dataset_name` argument (instead of the names in cfg), because the + standard practice is to evaluate each test set individually (not combining them). + """ + if isinstance(dataset_name, str): + dataset_name = [dataset_name] + + dataset = get_detection_dataset_dicts( + dataset_name, + filter_empty=False, + proposal_files=[ + cfg.DATASETS.PROPOSAL_FILES_TEST[list(cfg.DATASETS.TEST).index(x)] for x in dataset_name + ] + if cfg.MODEL.LOAD_PROPOSALS + else None, + ) + if mapper is None: + mapper = DatasetMapper(cfg, False) + return { + "dataset": dataset, + "mapper": mapper, + "num_workers": cfg.DATALOADER.NUM_WORKERS, + "sampler": InferenceSampler(len(dataset)) + if not isinstance(dataset, torchdata.IterableDataset) + else None, + } + + +@configurable(from_config=_test_loader_from_config) +def build_detection_test_loader( + dataset: Union[List[Any], torchdata.Dataset], + *, + mapper: Callable[[Dict[str, Any]], Any], + sampler: Optional[torchdata.Sampler] = None, + batch_size: int = 1, + num_workers: int = 0, + collate_fn: Optional[Callable[[List[Any]], Any]] = None, +) -> torchdata.DataLoader: + """ + Similar to `build_detection_train_loader`, with default batch size = 1, + and sampler = :class:`InferenceSampler`. This sampler coordinates all workers + to produce the exact set of all samples. + + Args: + dataset: a list of dataset dicts, + or a pytorch dataset (either map-style or iterable). They can be obtained + by using :func:`DatasetCatalog.get` or :func:`get_detection_dataset_dicts`. + mapper: a callable which takes a sample (dict) from dataset + and returns the format to be consumed by the model. + When using cfg, the default choice is ``DatasetMapper(cfg, is_train=False)``. + sampler: a sampler that produces + indices to be applied on ``dataset``. Default to :class:`InferenceSampler`, + which splits the dataset across all workers. Sampler must be None + if `dataset` is iterable. + batch_size: the batch size of the data loader to be created. + Default to 1 image per worker since this is the standard when reporting + inference time in papers. + num_workers: number of parallel data loading workers + collate_fn: same as the argument of `torch.utils.data.DataLoader`. + Defaults to do no collation and return a list of data. + + Returns: + DataLoader: a torch DataLoader, that loads the given detection + dataset, with test-time transformation and batching. + + Examples: + :: + data_loader = build_detection_test_loader( + DatasetRegistry.get("my_test"), + mapper=DatasetMapper(...)) + + # or, instantiate with a CfgNode: + data_loader = build_detection_test_loader(cfg, "my_test") + """ + if isinstance(dataset, list): + dataset = DatasetFromList(dataset, copy=False) + if mapper is not None: + dataset = MapDataset(dataset, mapper) + if isinstance(dataset, torchdata.IterableDataset): + assert sampler is None, "sampler must be None if dataset is IterableDataset" + else: + if sampler is None: + sampler = InferenceSampler(len(dataset)) + return torchdata.DataLoader( + dataset, + batch_size=batch_size, + sampler=sampler, + drop_last=False, + num_workers=num_workers, + collate_fn=trivial_batch_collator if collate_fn is None else collate_fn, + ) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/dataset_mappers/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/dataset_mappers/__init__.py new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/dataset_mappers/__init__.py @@ -0,0 +1 @@ + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/dataset_mappers/coco_unified_new_baseline_dataset_mapper.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/dataset_mappers/coco_unified_new_baseline_dataset_mapper.py new file mode 100644 index 00000000..25a460bf --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/dataset_mappers/coco_unified_new_baseline_dataset_mapper.py @@ -0,0 +1,341 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/Mask2Former/blob/main/mask2former/data/dataset_mappers/coco_panoptic_new_baseline_dataset_mapper.py +# Modified by Jitesh Jain (https://github.com/praeclarumjj3) +# ------------------------------------------------------------------------------ + +import copy +import logging + +import numpy as np +import torch + +from annotator.oneformer.detectron2.data import MetadataCatalog +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.data import detection_utils as utils +from annotator.oneformer.detectron2.data import transforms as T +from annotator.oneformer.detectron2.structures import BitMasks, Instances +from annotator.oneformer.oneformer.utils.box_ops import masks_to_boxes +from annotator.oneformer.oneformer.data.tokenizer import SimpleTokenizer, Tokenize + +__all__ = ["COCOUnifiedNewBaselineDatasetMapper"] + + +def build_transform_gen(cfg, is_train): + """ + Create a list of default :class:`Augmentation` from config. + Now it includes resizing and flipping. + Returns: + list[Augmentation] + """ + assert is_train, "Only support training augmentation" + image_size = cfg.INPUT.IMAGE_SIZE + min_scale = cfg.INPUT.MIN_SCALE + max_scale = cfg.INPUT.MAX_SCALE + + augmentation = [] + + if cfg.INPUT.RANDOM_FLIP != "none": + augmentation.append( + T.RandomFlip( + horizontal=cfg.INPUT.RANDOM_FLIP == "horizontal", + vertical=cfg.INPUT.RANDOM_FLIP == "vertical", + ) + ) + + augmentation.extend([ + T.ResizeScale( + min_scale=min_scale, max_scale=max_scale, target_height=image_size, target_width=image_size + ), + T.FixedSizeCrop(crop_size=(image_size, image_size)), + ]) + + return augmentation + + +# This is specifically designed for the COCO dataset. +class COCOUnifiedNewBaselineDatasetMapper: + """ + A callable which takes a dataset dict in Detectron2 Dataset format, + and map it into a format used by OneFormer. + + This dataset mapper applies the same transformation as DETR for COCO panoptic segmentation. + + The callable currently does the following: + + 1. Read the image from "file_name" + 2. Applies geometric transforms to the image and annotation + 3. Find and applies suitable cropping to the image and annotation + 4. Prepare image and annotation to Tensors + """ + + @configurable + def __init__( + self, + is_train=True, + *, + num_queries, + tfm_gens, + meta, + image_format, + max_seq_len, + task_seq_len, + semantic_prob, + instance_prob, + ): + """ + NOTE: this interface is experimental. + Args: + is_train: for training or inference + augmentations: a list of augmentations or deterministic transforms to apply + crop_gen: crop augmentation + tfm_gens: data augmentation + image_format: an image format supported by :func:`detection_utils.read_image`. + """ + self.tfm_gens = tfm_gens + logging.getLogger(__name__).info( + "[COCOUnifiedNewBaselineDatasetMapper] Full TransformGens used in training: {}".format( + str(self.tfm_gens) + ) + ) + + self.img_format = image_format + self.is_train = is_train + self.meta = meta + self.ignore_label = self.meta.ignore_label + self.num_queries = num_queries + + self.things = [] + for k,v in self.meta.thing_dataset_id_to_contiguous_id.items(): + self.things.append(v) + self.class_names = self.meta.stuff_classes + self.text_tokenizer = Tokenize(SimpleTokenizer(), max_seq_len=max_seq_len) + self.task_tokenizer = Tokenize(SimpleTokenizer(), max_seq_len=task_seq_len) + self.semantic_prob = semantic_prob + self.instance_prob = instance_prob + + @classmethod + def from_config(cls, cfg, is_train=True): + # Build augmentation + tfm_gens = build_transform_gen(cfg, is_train) + dataset_names = cfg.DATASETS.TRAIN + meta = MetadataCatalog.get(dataset_names[0]) + + ret = { + "is_train": is_train, + "meta": meta, + "tfm_gens": tfm_gens, + "image_format": cfg.INPUT.FORMAT, + "num_queries": cfg.MODEL.ONE_FORMER.NUM_OBJECT_QUERIES - cfg.MODEL.TEXT_ENCODER.N_CTX, + "task_seq_len": cfg.INPUT.TASK_SEQ_LEN, + "max_seq_len": cfg.INPUT.MAX_SEQ_LEN, + "semantic_prob": cfg.INPUT.TASK_PROB.SEMANTIC, + "instance_prob": cfg.INPUT.TASK_PROB.INSTANCE, + } + return ret + + def _get_semantic_dict(self, pan_seg_gt, image_shape, segments_info, num_class_obj): + instances = Instances(image_shape) + + classes = [] + texts = ["a semantic photo"] * self.num_queries + masks = [] + label = np.ones_like(pan_seg_gt) * self.ignore_label + + for segment_info in segments_info: + class_id = segment_info["category_id"] + if not segment_info["iscrowd"]: + mask = pan_seg_gt == segment_info["id"] + if not np.all(mask == False): + if class_id not in classes: + cls_name = self.class_names[class_id] + classes.append(class_id) + masks.append(mask) + num_class_obj[cls_name] += 1 + else: + idx = classes.index(class_id) + masks[idx] += mask + masks[idx] = np.clip(masks[idx], 0, 1).astype(np.bool) + label[mask] = class_id + + num = 0 + for i, cls_name in enumerate(self.class_names): + if num_class_obj[cls_name] > 0: + for _ in range(num_class_obj[cls_name]): + if num >= len(texts): + break + texts[num] = f"a photo with a {cls_name}" + num += 1 + + classes = np.array(classes) + instances.gt_classes = torch.tensor(classes, dtype=torch.int64) + if len(masks) == 0: + # Some image does not have annotation (all ignored) + instances.gt_masks = torch.zeros((0, pan_seg_gt.shape[-2], pan_seg_gt.shape[-1])) + instances.gt_bboxes = torch.zeros((0, 4)) + else: + masks = BitMasks( + torch.stack([torch.from_numpy(np.ascontiguousarray(x.copy())) for x in masks]) + ) + instances.gt_masks = masks.tensor + # Placeholder bounding boxes for stuff regions. Note that these are not used during training. + instances.gt_bboxes = torch.stack([torch.tensor([0., 0., 1., 1.])] * instances.gt_masks.shape[0]) + return instances, texts, label + + def _get_instance_dict(self, pan_seg_gt, image_shape, segments_info, num_class_obj): + instances = Instances(image_shape) + + classes = [] + texts = ["an instance photo"] * self.num_queries + masks = [] + label = np.ones_like(pan_seg_gt) * self.ignore_label + + for segment_info in segments_info: + class_id = segment_info["category_id"] + if class_id in self.things: + if not segment_info["iscrowd"]: + mask = pan_seg_gt == segment_info["id"] + if not np.all(mask == False): + cls_name = self.class_names[class_id] + classes.append(class_id) + masks.append(mask) + num_class_obj[cls_name] += 1 + label[mask] = class_id + + num = 0 + for i, cls_name in enumerate(self.class_names): + if num_class_obj[cls_name] > 0: + for _ in range(num_class_obj[cls_name]): + if num >= len(texts): + break + texts[num] = f"a photo with a {cls_name}" + num += 1 + + classes = np.array(classes) + instances.gt_classes = torch.tensor(classes, dtype=torch.int64) + if len(masks) == 0: + # Some image does not have annotation (all ignored) + instances.gt_masks = torch.zeros((0, pan_seg_gt.shape[-2], pan_seg_gt.shape[-1])) + instances.gt_bboxes = torch.zeros((0, 4)) + else: + masks = BitMasks( + torch.stack([torch.from_numpy(np.ascontiguousarray(x.copy())) for x in masks]) + ) + instances.gt_masks = masks.tensor + instances.gt_bboxes = masks_to_boxes(instances.gt_masks) + return instances, texts, label + + def _get_panoptic_dict(self, pan_seg_gt, image_shape, segments_info, num_class_obj): + instances = Instances(image_shape) + + classes = [] + texts = ["a panoptic photo"] * self.num_queries + masks = [] + label = np.ones_like(pan_seg_gt) * self.ignore_label + + for segment_info in segments_info: + class_id = segment_info["category_id"] + if not segment_info["iscrowd"]: + mask = pan_seg_gt == segment_info["id"] + if not np.all(mask == False): + cls_name = self.class_names[class_id] + classes.append(class_id) + masks.append(mask) + num_class_obj[cls_name] += 1 + label[mask] = class_id + + num = 0 + for i, cls_name in enumerate(self.class_names): + if num_class_obj[cls_name] > 0: + for _ in range(num_class_obj[cls_name]): + if num >= len(texts): + break + texts[num] = f"a photo with a {cls_name}" + num += 1 + + classes = np.array(classes) + instances.gt_classes = torch.tensor(classes, dtype=torch.int64) + if len(masks) == 0: + # Some image does not have annotation (all ignored) + instances.gt_masks = torch.zeros((0, pan_seg_gt.shape[-2], pan_seg_gt.shape[-1])) + instances.gt_bboxes = torch.zeros((0, 4)) + else: + masks = BitMasks( + torch.stack([torch.from_numpy(np.ascontiguousarray(x.copy())) for x in masks]) + ) + instances.gt_masks = masks.tensor + instances.gt_bboxes = masks_to_boxes(instances.gt_masks) + for i in range(instances.gt_classes.shape[0]): + # Placeholder bounding boxes for stuff regions. Note that these are not used during training. + if instances.gt_classes[i].item() not in self.things: + instances.gt_bboxes[i] = torch.tensor([0., 0., 1., 1.]) + return instances, texts, label + + def __call__(self, dataset_dict): + """ + Args: + dataset_dict (dict): Metadata of one image, in Detectron2 Dataset format. + + Returns: + dict: a format that builtin models in detectron2 accept + """ + dataset_dict = copy.deepcopy(dataset_dict) # it will be modified by code below + image = utils.read_image(dataset_dict["file_name"], format=self.img_format) + utils.check_image_size(dataset_dict, image) + + image, transforms = T.apply_transform_gens(self.tfm_gens, image) + image_shape = image.shape[:2] # h, w + + # Pytorch's dataloader is efficient on torch.Tensor due to shared-memory, + # but not efficient on large generic data structures due to the use of pickle & mp.Queue. + # Therefore it's important to use torch.Tensor. + dataset_dict["image"] = torch.as_tensor(np.ascontiguousarray(image.transpose(2, 0, 1))) + + if not self.is_train: + # USER: Modify this if you want to keep them for some reason. + dataset_dict.pop("annotations", None) + return dataset_dict + + # semantic segmentation + if "sem_seg_file_name" in dataset_dict: + # PyTorch transformation not implemented for uint16, so converting it to double first + sem_seg_gt = utils.read_image(dataset_dict.pop("sem_seg_file_name")).astype("double") + sem_seg_gt = transforms.apply_segmentation(sem_seg_gt) + else: + sem_seg_gt = None + + if "pan_seg_file_name" in dataset_dict: + pan_seg_gt = utils.read_image(dataset_dict.pop("pan_seg_file_name"), "RGB") + segments_info = dataset_dict["segments_info"] + + # apply the same transformation to panoptic segmentation + pan_seg_gt = transforms.apply_segmentation(pan_seg_gt) + + from panopticapi.utils import rgb2id + pan_seg_gt = rgb2id(pan_seg_gt) + + prob_task = np.random.uniform(0,1.) + + num_class_obj = {} + + for name in self.class_names: + num_class_obj[name] = 0 + + if prob_task < self.semantic_prob: + task = "The task is semantic" + instances, text, sem_seg = self._get_semantic_dict(pan_seg_gt, image_shape, segments_info, num_class_obj) + elif prob_task < self.instance_prob: + task = "The task is instance" + instances, text, sem_seg = self._get_instance_dict(pan_seg_gt, image_shape, segments_info, num_class_obj) + else: + task = "The task is panoptic" + instances, text, sem_seg = self._get_panoptic_dict(pan_seg_gt, image_shape, segments_info, num_class_obj) + + + dataset_dict["sem_seg"] = torch.from_numpy(sem_seg).long() + dataset_dict["instances"] = instances + dataset_dict["orig_shape"] = image_shape + dataset_dict["task"] = task + dataset_dict["text"] = text + dataset_dict["thing_ids"] = self.things + + return dataset_dict diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/dataset_mappers/dataset_mapper.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/dataset_mappers/dataset_mapper.py new file mode 100644 index 00000000..710c81be --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/dataset_mappers/dataset_mapper.py @@ -0,0 +1,203 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/detectron2/blob/main/detectron2/data/dataset_mapper.py +# Modified by Jitesh Jain (https://github.com/praeclarumjj3) +# ------------------------------------------------------------------------------ + +import copy +import logging +import numpy as np +from typing import List, Optional, Union +import torch + +from annotator.oneformer.detectron2.config import configurable + +from annotator.oneformer.detectron2.data import detection_utils as utils +from annotator.oneformer.detectron2.data import transforms as T +from annotator.oneformer.oneformer.data.tokenizer import SimpleTokenizer, Tokenize + +__all__ = ["DatasetMapper"] + + +class DatasetMapper: + """ + A callable which takes a dataset dict in Detectron2 Dataset format, + and map it into a format used by the model. + + This is the default callable to be used to map your dataset dict into training data. + You may need to follow it to implement your own one for customized logic, + such as a different way to read or transform images. + See :doc:`/tutorials/data_loading` for details. + + The callable currently does the following: + + 1. Read the image from "file_name" + 2. Applies cropping/geometric transforms to the image and annotations + 3. Prepare data and annotations to Tensor and :class:`Instances` + """ + + @configurable + def __init__( + self, + is_train: bool, + *, + augmentations: List[Union[T.Augmentation, T.Transform]], + image_format: str, + task_seq_len: int, + task: str = "panoptic", + use_instance_mask: bool = False, + use_keypoint: bool = False, + instance_mask_format: str = "polygon", + keypoint_hflip_indices: Optional[np.ndarray] = None, + precomputed_proposal_topk: Optional[int] = None, + recompute_boxes: bool = False, + ): + """ + NOTE: this interface is experimental. + + Args: + is_train: whether it's used in training or inference + augmentations: a list of augmentations or deterministic transforms to apply + image_format: an image format supported by :func:`detection_utils.read_image`. + use_instance_mask: whether to process instance segmentation annotations, if available + use_keypoint: whether to process keypoint annotations if available + instance_mask_format: one of "polygon" or "bitmask". Process instance segmentation + masks into this format. + keypoint_hflip_indices: see :func:`detection_utils.create_keypoint_hflip_indices` + precomputed_proposal_topk: if given, will load pre-computed + proposals from dataset_dict and keep the top k proposals for each image. + recompute_boxes: whether to overwrite bounding box annotations + by computing tight bounding boxes from instance mask annotations. + """ + if recompute_boxes: + assert use_instance_mask, "recompute_boxes requires instance masks" + # fmt: off + self.is_train = is_train + self.augmentations = T.AugmentationList(augmentations) + self.image_format = image_format + self.use_instance_mask = use_instance_mask + self.instance_mask_format = instance_mask_format + self.use_keypoint = use_keypoint + self.keypoint_hflip_indices = keypoint_hflip_indices + self.proposal_topk = precomputed_proposal_topk + self.recompute_boxes = recompute_boxes + self.task_tokenizer = Tokenize(SimpleTokenizer(), max_seq_len=task_seq_len) + self.task = task + assert self.task in ["panoptic", "semantic", "instance"] + + # fmt: on + logger = logging.getLogger(__name__) + mode = "training" if is_train else "inference" + logger.info(f"[DatasetMapper] Augmentations used in {mode}: {augmentations}") + + @classmethod + def from_config(cls, cfg, is_train: bool = True): + augs = utils.build_augmentation(cfg, is_train) + if cfg.INPUT.CROP.ENABLED and is_train: + augs.insert(0, T.RandomCrop(cfg.INPUT.CROP.TYPE, cfg.INPUT.CROP.SIZE)) + recompute_boxes = cfg.MODEL.MASK_ON + else: + recompute_boxes = False + + ret = { + "is_train": is_train, + "augmentations": augs, + "image_format": cfg.INPUT.FORMAT, + "use_instance_mask": cfg.MODEL.MASK_ON, + "instance_mask_format": cfg.INPUT.MASK_FORMAT, + "use_keypoint": cfg.MODEL.KEYPOINT_ON, + "task_seq_len": cfg.INPUT.TASK_SEQ_LEN, + "recompute_boxes": recompute_boxes, + "task": cfg.MODEL.TEST.TASK, + } + + if cfg.MODEL.KEYPOINT_ON: + ret["keypoint_hflip_indices"] = utils.create_keypoint_hflip_indices(cfg.DATASETS.TRAIN) + + if cfg.MODEL.LOAD_PROPOSALS: + ret["precomputed_proposal_topk"] = ( + cfg.DATASETS.PRECOMPUTED_PROPOSAL_TOPK_TRAIN + if is_train + else cfg.DATASETS.PRECOMPUTED_PROPOSAL_TOPK_TEST + ) + return ret + + def _transform_annotations(self, dataset_dict, transforms, image_shape): + # USER: Modify this if you want to keep them for some reason. + for anno in dataset_dict["annotations"]: + if not self.use_instance_mask: + anno.pop("segmentation", None) + if not self.use_keypoint: + anno.pop("keypoints", None) + + # USER: Implement additional transformations if you have other types of data + annos = [ + utils.transform_instance_annotations( + obj, transforms, image_shape, keypoint_hflip_indices=self.keypoint_hflip_indices + ) + for obj in dataset_dict.pop("annotations") + if obj.get("iscrowd", 0) == 0 + ] + instances = utils.annotations_to_instances( + annos, image_shape, mask_format=self.instance_mask_format + ) + + # After transforms such as cropping are applied, the bounding box may no longer + # tightly bound the object. As an example, imagine a triangle object + # [(0,0), (2,0), (0,2)] cropped by a box [(1,0),(2,2)] (XYXY format). The tight + # bounding box of the cropped triangle should be [(1,0),(2,1)], which is not equal to + # the intersection of original bounding box and the cropping box. + if self.recompute_boxes: + instances.gt_boxes = instances.gt_masks.get_bounding_boxes() + dataset_dict["instances"] = utils.filter_empty_instances(instances) + + def __call__(self, dataset_dict): + """ + Args: + dataset_dict (dict): Metadata of one image, in Detectron2 Dataset format. + + Returns: + dict: a format that builtin models in detectron2 accept + """ + dataset_dict = copy.deepcopy(dataset_dict) # it will be modified by code below + # USER: Write your own image loading if it's not from a file + image = utils.read_image(dataset_dict["file_name"], format=self.image_format) + utils.check_image_size(dataset_dict, image) + + task = f"The task is {self.task}" + dataset_dict["task"] = task + + # USER: Remove if you don't do semantic/panoptic segmentation. + if "sem_seg_file_name" in dataset_dict: + sem_seg_gt = utils.read_image(dataset_dict.pop("sem_seg_file_name"), "L").squeeze(2) + else: + sem_seg_gt = None + + aug_input = T.AugInput(image, sem_seg=sem_seg_gt) + transforms = self.augmentations(aug_input) + image, sem_seg_gt = aug_input.image, aug_input.sem_seg + + image_shape = image.shape[:2] # h, w + # Pytorch's dataloader is efficient on torch.Tensor due to shared-memory, + # but not efficient on large generic data structures due to the use of pickle & mp.Queue. + # Therefore it's important to use torch.Tensor. + dataset_dict["image"] = torch.as_tensor(np.ascontiguousarray(image.transpose(2, 0, 1))) + if sem_seg_gt is not None: + dataset_dict["sem_seg"] = torch.as_tensor(sem_seg_gt.astype("long")) + + # USER: Remove if you don't use pre-computed proposals. + # Most users would not need this feature. + if self.proposal_topk is not None: + utils.transform_proposals( + dataset_dict, image_shape, transforms, proposal_topk=self.proposal_topk + ) + + if not self.is_train: + # USER: Modify this if you want to keep them for some reason. + dataset_dict.pop("annotations", None) + dataset_dict.pop("sem_seg_file_name", None) + return dataset_dict + + if "annotations" in dataset_dict: + self._transform_annotations(dataset_dict, transforms, image_shape) + + return dataset_dict \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/dataset_mappers/oneformer_unified_dataset_mapper.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/dataset_mappers/oneformer_unified_dataset_mapper.py new file mode 100644 index 00000000..e5dadbc2 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/dataset_mappers/oneformer_unified_dataset_mapper.py @@ -0,0 +1,375 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/Mask2Former/blob/main/mask2former/data/dataset_mappers/mask_former_panoptic_dataset_mapper.py +# Modified by Jitesh Jain (https://github.com/praeclarumjj3) +# ------------------------------------------------------------------------------ + +import copy +import logging +import os + +import numpy as np +import torch +from torch.nn import functional as F + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.data import detection_utils as utils +from annotator.oneformer.detectron2.data import transforms as T +from annotator.oneformer.detectron2.structures import BitMasks, Instances +from annotator.oneformer.detectron2.data import MetadataCatalog +from annotator.oneformer.detectron2.projects.point_rend import ColorAugSSDTransform +from annotator.oneformer.oneformer.utils.box_ops import masks_to_boxes +from annotator.oneformer.oneformer.data.tokenizer import SimpleTokenizer, Tokenize + +__all__ = ["OneFormerUnifiedDatasetMapper"] + + +class OneFormerUnifiedDatasetMapper: + """ + A callable which takes a dataset dict in Detectron2 Dataset format, + and map it into a format used by OneFormer for universal segmentation. + + The callable currently does the following: + + 1. Read the image from "file_name" + 2. Applies geometric transforms to the image and annotation + 3. Find and applies suitable cropping to the image and annotation + 4. Prepare image and annotation to Tensors + """ + + @configurable + def __init__( + self, + is_train=True, + *, + name, + num_queries, + meta, + augmentations, + image_format, + ignore_label, + size_divisibility, + task_seq_len, + max_seq_len, + semantic_prob, + instance_prob, + ): + """ + NOTE: this interface is experimental. + Args: + is_train: for training or inference + augmentations: a list of augmentations or deterministic transforms to apply + image_format: an image format supported by :func:`detection_utils.read_image`. + ignore_label: the label that is ignored to evaluation + size_divisibility: pad image size to be divisible by this value + """ + self.is_train = is_train + self.meta = meta + self.name = name + self.tfm_gens = augmentations + self.img_format = image_format + self.ignore_label = ignore_label + self.size_divisibility = size_divisibility + self.num_queries = num_queries + + logger = logging.getLogger(__name__) + mode = "training" if is_train else "inference" + logger.info(f"[{self.__class__.__name__}] Augmentations used in {mode}: {augmentations}") + + self.things = [] + for k,v in self.meta.thing_dataset_id_to_contiguous_id.items(): + self.things.append(v) + self.class_names = self.meta.stuff_classes + self.text_tokenizer = Tokenize(SimpleTokenizer(), max_seq_len=max_seq_len) + self.task_tokenizer = Tokenize(SimpleTokenizer(), max_seq_len=task_seq_len) + self.semantic_prob = semantic_prob + self.instance_prob = instance_prob + + @classmethod + def from_config(cls, cfg, is_train=True): + # Build augmentation + augs = [ + T.ResizeShortestEdge( + cfg.INPUT.MIN_SIZE_TRAIN, + cfg.INPUT.MAX_SIZE_TRAIN, + cfg.INPUT.MIN_SIZE_TRAIN_SAMPLING, + ) + ] + if cfg.INPUT.CROP.ENABLED: + augs.append( + T.RandomCrop_CategoryAreaConstraint( + cfg.INPUT.CROP.TYPE, + cfg.INPUT.CROP.SIZE, + cfg.INPUT.CROP.SINGLE_CATEGORY_MAX_AREA, + cfg.MODEL.SEM_SEG_HEAD.IGNORE_VALUE, + ) + ) + if cfg.INPUT.COLOR_AUG_SSD: + augs.append(ColorAugSSDTransform(img_format=cfg.INPUT.FORMAT)) + augs.append(T.RandomFlip()) + + # Assume always applies to the training set. + dataset_names = cfg.DATASETS.TRAIN + meta = MetadataCatalog.get(dataset_names[0]) + ignore_label = meta.ignore_label + + ret = { + "is_train": is_train, + "meta": meta, + "name": dataset_names[0], + "num_queries": cfg.MODEL.ONE_FORMER.NUM_OBJECT_QUERIES - cfg.MODEL.TEXT_ENCODER.N_CTX, + "task_seq_len": cfg.INPUT.TASK_SEQ_LEN, + "max_seq_len": cfg.INPUT.MAX_SEQ_LEN, + "augmentations": augs, + "image_format": cfg.INPUT.FORMAT, + "ignore_label": ignore_label, + "size_divisibility": cfg.INPUT.SIZE_DIVISIBILITY, + "semantic_prob": cfg.INPUT.TASK_PROB.SEMANTIC, + "instance_prob": cfg.INPUT.TASK_PROB.INSTANCE, + } + return ret + + def _get_semantic_dict(self, pan_seg_gt, image_shape, segments_info, num_class_obj): + pan_seg_gt = pan_seg_gt.numpy() + instances = Instances(image_shape) + + classes = [] + texts = ["a semantic photo"] * self.num_queries + masks = [] + label = np.ones_like(pan_seg_gt) * self.ignore_label + + for segment_info in segments_info: + class_id = segment_info["category_id"] + if not segment_info["iscrowd"]: + mask = pan_seg_gt == segment_info["id"] + if not np.all(mask == False): + if class_id not in classes: + cls_name = self.class_names[class_id] + classes.append(class_id) + masks.append(mask) + num_class_obj[cls_name] += 1 + else: + idx = classes.index(class_id) + masks[idx] += mask + masks[idx] = np.clip(masks[idx], 0, 1).astype(np.bool) + label[mask] = class_id + + num = 0 + for i, cls_name in enumerate(self.class_names): + if num_class_obj[cls_name] > 0: + for _ in range(num_class_obj[cls_name]): + if num >= len(texts): + break + texts[num] = f"a photo with a {cls_name}" + num += 1 + + classes = np.array(classes) + instances.gt_classes = torch.tensor(classes, dtype=torch.int64) + if len(masks) == 0: + # Some image does not have annotation (all ignored) + instances.gt_masks = torch.zeros((0, pan_seg_gt.shape[-2], pan_seg_gt.shape[-1])) + instances.gt_bboxes = torch.zeros((0, 4)) + else: + masks = BitMasks( + torch.stack([torch.from_numpy(np.ascontiguousarray(x.copy())) for x in masks]) + ) + instances.gt_masks = masks.tensor + # Placeholder bounding boxes for stuff regions. Note that these are not used during training. + instances.gt_bboxes = torch.stack([torch.tensor([0., 0., 1., 1.])] * instances.gt_masks.shape[0]) + return instances, texts, label + + def _get_instance_dict(self, pan_seg_gt, image_shape, segments_info, num_class_obj): + pan_seg_gt = pan_seg_gt.numpy() + instances = Instances(image_shape) + + classes = [] + texts = ["an instance photo"] * self.num_queries + masks = [] + label = np.ones_like(pan_seg_gt) * self.ignore_label + + for segment_info in segments_info: + class_id = segment_info["category_id"] + if class_id in self.things: + if not segment_info["iscrowd"]: + mask = pan_seg_gt == segment_info["id"] + if not np.all(mask == False): + cls_name = self.class_names[class_id] + classes.append(class_id) + masks.append(mask) + num_class_obj[cls_name] += 1 + label[mask] = class_id + + num = 0 + for i, cls_name in enumerate(self.class_names): + if num_class_obj[cls_name] > 0: + for _ in range(num_class_obj[cls_name]): + if num >= len(texts): + break + texts[num] = f"a photo with a {cls_name}" + num += 1 + + classes = np.array(classes) + instances.gt_classes = torch.tensor(classes, dtype=torch.int64) + if len(masks) == 0: + # Some image does not have annotation (all ignored) + instances.gt_masks = torch.zeros((0, pan_seg_gt.shape[-2], pan_seg_gt.shape[-1])) + instances.gt_bboxes = torch.zeros((0, 4)) + else: + masks = BitMasks( + torch.stack([torch.from_numpy(np.ascontiguousarray(x.copy())) for x in masks]) + ) + instances.gt_masks = masks.tensor + instances.gt_bboxes = masks_to_boxes(instances.gt_masks) + return instances, texts, label + + def _get_panoptic_dict(self, pan_seg_gt, image_shape, segments_info, num_class_obj): + pan_seg_gt = pan_seg_gt.numpy() + instances = Instances(image_shape) + + classes = [] + texts = ["a panoptic photo"] * self.num_queries + masks = [] + label = np.ones_like(pan_seg_gt) * self.ignore_label + + for segment_info in segments_info: + class_id = segment_info["category_id"] + if not segment_info["iscrowd"]: + mask = pan_seg_gt == segment_info["id"] + if not np.all(mask == False): + cls_name = self.class_names[class_id] + classes.append(class_id) + masks.append(mask) + num_class_obj[cls_name] += 1 + label[mask] = class_id + + num = 0 + for i, cls_name in enumerate(self.class_names): + if num_class_obj[cls_name] > 0: + for _ in range(num_class_obj[cls_name]): + if num >= len(texts): + break + texts[num] = f"a photo with a {cls_name}" + num += 1 + + classes = np.array(classes) + instances.gt_classes = torch.tensor(classes, dtype=torch.int64) + if len(masks) == 0: + # Some image does not have annotation (all ignored) + instances.gt_masks = torch.zeros((0, pan_seg_gt.shape[-2], pan_seg_gt.shape[-1])) + instances.gt_bboxes = torch.zeros((0, 4)) + else: + masks = BitMasks( + torch.stack([torch.from_numpy(np.ascontiguousarray(x.copy())) for x in masks]) + ) + instances.gt_masks = masks.tensor + instances.gt_bboxes = masks_to_boxes(instances.gt_masks) + for i in range(instances.gt_classes.shape[0]): + # Placeholder bounding boxes for stuff regions. Note that these are not used during training. + if instances.gt_classes[i].item() not in self.things: + instances.gt_bboxes[i] = torch.tensor([0., 0., 1., 1.]) + return instances, texts, label + + def __call__(self, dataset_dict): + """ + Args: + dataset_dict (dict): Metadata of one image, in Detectron2 Dataset format. + + Returns: + dict: a format that builtin models in detectron2 accept + """ + assert self.is_train, "OneFormerUnifiedDatasetMapper should only be used for training!" + + dataset_dict = copy.deepcopy(dataset_dict) # it will be modified by code below + image = utils.read_image(dataset_dict["file_name"], format=self.img_format) + utils.check_image_size(dataset_dict, image) + + # semantic segmentation + if "sem_seg_file_name" in dataset_dict: + # PyTorch transformation not implemented for uint16, so converting it to double first + sem_seg_gt = utils.read_image(dataset_dict.pop("sem_seg_file_name")).astype("double") + else: + sem_seg_gt = None + + # panoptic segmentation + if "pan_seg_file_name" in dataset_dict: + pan_seg_gt = utils.read_image(dataset_dict.pop("pan_seg_file_name"), "RGB") + segments_info = dataset_dict["segments_info"] + else: + pan_seg_gt = None + segments_info = None + + if pan_seg_gt is None: + raise ValueError( + "Cannot find 'pan_seg_file_name' for panoptic segmentation dataset {}.".format( + dataset_dict["file_name"] + ) + ) + + aug_input = T.AugInput(image, sem_seg=sem_seg_gt) + aug_input, transforms = T.apply_transform_gens(self.tfm_gens, aug_input) + image = aug_input.image + if sem_seg_gt is not None: + sem_seg_gt = aug_input.sem_seg + + # apply the same transformation to panoptic segmentation + pan_seg_gt = transforms.apply_segmentation(pan_seg_gt) + + from panopticapi.utils import rgb2id + + pan_seg_gt = rgb2id(pan_seg_gt) + + # Pad image and segmentation label here! + image = torch.as_tensor(np.ascontiguousarray(image.transpose(2, 0, 1))) + if sem_seg_gt is not None: + sem_seg_gt = torch.as_tensor(sem_seg_gt.astype("long")) + pan_seg_gt = torch.as_tensor(pan_seg_gt.astype("long")) + + if self.size_divisibility > 0: + image_size = (image.shape[-2], image.shape[-1]) + padding_size = [ + 0, + self.size_divisibility - image_size[1], + 0, + self.size_divisibility - image_size[0], + ] + image = F.pad(image, padding_size, value=128).contiguous() + if sem_seg_gt is not None: + sem_seg_gt = F.pad(sem_seg_gt, padding_size, value=self.ignore_label).contiguous() + pan_seg_gt = F.pad( + pan_seg_gt, padding_size, value=0 + ).contiguous() # 0 is the VOID panoptic label + + image_shape = (image.shape[-2], image.shape[-1]) # h, w + + # Pytorch's dataloader is efficient on torch.Tensor due to shared-memory, + # but not efficient on large generic data structures due to the use of pickle & mp.Queue. + # Therefore it's important to use torch.Tensor. + dataset_dict["image"] = image + + if "annotations" in dataset_dict: + raise ValueError("Pemantic segmentation dataset should not have 'annotations'.") + + prob_task = np.random.uniform(0,1.) + + num_class_obj = {} + + for name in self.class_names: + num_class_obj[name] = 0 + + if prob_task < self.semantic_prob: + task = "The task is semantic" + instances, text, sem_seg = self._get_semantic_dict(pan_seg_gt, image_shape, segments_info, num_class_obj) + elif prob_task < self.instance_prob: + task = "The task is instance" + instances, text, sem_seg = self._get_instance_dict(pan_seg_gt, image_shape, segments_info, num_class_obj) + else: + task = "The task is panoptic" + instances, text, sem_seg = self._get_panoptic_dict(pan_seg_gt, image_shape, segments_info, num_class_obj) + + dataset_dict["sem_seg"] = torch.from_numpy(sem_seg).long() + dataset_dict["instances"] = instances + dataset_dict["orig_shape"] = image_shape + dataset_dict["task"] = task + dataset_dict["text"] = text + dataset_dict["thing_ids"] = self.things + + return dataset_dict diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/__init__.py new file mode 100644 index 00000000..59ce3071 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/__init__.py @@ -0,0 +1,7 @@ +from . import ( + register_ade20k_panoptic, + register_cityscapes_panoptic, + register_coco_panoptic_annos_semseg, + register_ade20k_instance, + register_coco_panoptic2instance, +) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_ade20k_instance.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_ade20k_instance.py new file mode 100644 index 00000000..e32d2b0b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_ade20k_instance.py @@ -0,0 +1,56 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/Mask2Former/blob/main/mask2former/data/datasets/register_ade20k_instance.py +# ------------------------------------------------------------------------------ + +import json +import logging +import numpy as np +import os +from PIL import Image + +from annotator.oneformer.detectron2.data import DatasetCatalog, MetadataCatalog +from annotator.oneformer.detectron2.data.datasets.coco import load_coco_json, register_coco_instances +from annotator.oneformer.detectron2.utils.file_io import PathManager + +ADE_CATEGORIES = [{'id': 7, 'name': 'bed'}, {'id': 8, 'name': 'windowpane'}, {'id': 10, 'name': 'cabinet'}, {'id': 12, 'name': 'person'}, {'id': 14, 'name': 'door'}, {'id': 15, 'name': 'table'}, {'id': 18, 'name': 'curtain'}, {'id': 19, 'name': 'chair'}, {'id': 20, 'name': 'car'}, {'id': 22, 'name': 'painting'}, {'id': 23, 'name': 'sofa'}, {'id': 24, 'name': 'shelf'}, {'id': 27, 'name': 'mirror'}, {'id': 30, 'name': 'armchair'}, {'id': 31, 'name': 'seat'}, {'id': 32, 'name': 'fence'}, {'id': 33, 'name': 'desk'}, {'id': 35, 'name': 'wardrobe'}, {'id': 36, 'name': 'lamp'}, {'id': 37, 'name': 'bathtub'}, {'id': 38, 'name': 'railing'}, {'id': 39, 'name': 'cushion'}, {'id': 41, 'name': 'box'}, {'id': 42, 'name': 'column'}, {'id': 43, 'name': 'signboard'}, {'id': 44, 'name': 'chest of drawers'}, {'id': 45, 'name': 'counter'}, {'id': 47, 'name': 'sink'}, {'id': 49, 'name': 'fireplace'}, {'id': 50, 'name': 'refrigerator'}, {'id': 53, 'name': 'stairs'}, {'id': 55, 'name': 'case'}, {'id': 56, 'name': 'pool table'}, {'id': 57, 'name': 'pillow'}, {'id': 58, 'name': 'screen door'}, {'id': 62, 'name': 'bookcase'}, {'id': 64, 'name': 'coffee table'}, {'id': 65, 'name': 'toilet'}, {'id': 66, 'name': 'flower'}, {'id': 67, 'name': 'book'}, {'id': 69, 'name': 'bench'}, {'id': 70, 'name': 'countertop'}, {'id': 71, 'name': 'stove'}, {'id': 72, 'name': 'palm'}, {'id': 73, 'name': 'kitchen island'}, {'id': 74, 'name': 'computer'}, {'id': 75, 'name': 'swivel chair'}, {'id': 76, 'name': 'boat'}, {'id': 78, 'name': 'arcade machine'}, {'id': 80, 'name': 'bus'}, {'id': 81, 'name': 'towel'}, {'id': 82, 'name': 'light'}, {'id': 83, 'name': 'truck'}, {'id': 85, 'name': 'chandelier'}, {'id': 86, 'name': 'awning'}, {'id': 87, 'name': 'streetlight'}, {'id': 88, 'name': 'booth'}, {'id': 89, 'name': 'television receiver'}, {'id': 90, 'name': 'airplane'}, {'id': 92, 'name': 'apparel'}, {'id': 93, 'name': 'pole'}, {'id': 95, 'name': 'bannister'}, {'id': 97, 'name': 'ottoman'}, {'id': 98, 'name': 'bottle'}, {'id': 102, 'name': 'van'}, {'id': 103, 'name': 'ship'}, {'id': 104, 'name': 'fountain'}, {'id': 107, 'name': 'washer'}, {'id': 108, 'name': 'plaything'}, {'id': 110, 'name': 'stool'}, {'id': 111, 'name': 'barrel'}, {'id': 112, 'name': 'basket'}, {'id': 115, 'name': 'bag'}, {'id': 116, 'name': 'minibike'}, {'id': 118, 'name': 'oven'}, {'id': 119, 'name': 'ball'}, {'id': 120, 'name': 'food'}, {'id': 121, 'name': 'step'}, {'id': 123, 'name': 'trade name'}, {'id': 124, 'name': 'microwave'}, {'id': 125, 'name': 'pot'}, {'id': 126, 'name': 'animal'}, {'id': 127, 'name': 'bicycle'}, {'id': 129, 'name': 'dishwasher'}, {'id': 130, 'name': 'screen'}, {'id': 132, 'name': 'sculpture'}, {'id': 133, 'name': 'hood'}, {'id': 134, 'name': 'sconce'}, {'id': 135, 'name': 'vase'}, {'id': 136, 'name': 'traffic light'}, {'id': 137, 'name': 'tray'}, {'id': 138, 'name': 'ashcan'}, {'id': 139, 'name': 'fan'}, {'id': 142, 'name': 'plate'}, {'id': 143, 'name': 'monitor'}, {'id': 144, 'name': 'bulletin board'}, {'id': 146, 'name': 'radiator'}, {'id': 147, 'name': 'glass'}, {'id': 148, 'name': 'clock'}, {'id': 149, 'name': 'flag'}] + + +_PREDEFINED_SPLITS = { + # point annotations without masks + "ade20k_instance_train": ( + "ADEChallengeData2016/images/training", + "ADEChallengeData2016/ade20k_instance_train.json", + ), + "ade20k_instance_val": ( + "ADEChallengeData2016/images/validation", + "ADEChallengeData2016/ade20k_instance_val.json", + ), +} + + +def _get_ade_instances_meta(): + thing_ids = [k["id"] for k in ADE_CATEGORIES] + assert len(thing_ids) == 100, len(thing_ids) + # Mapping from the incontiguous ADE category id to an id in [0, 99] + thing_dataset_id_to_contiguous_id = {k: i for i, k in enumerate(thing_ids)} + thing_classes = [k["name"] for k in ADE_CATEGORIES] + ret = { + "thing_dataset_id_to_contiguous_id": thing_dataset_id_to_contiguous_id, + "thing_classes": thing_classes, + } + return ret + + +def register_all_ade20k_instance(root): + for key, (image_root, json_file) in _PREDEFINED_SPLITS.items(): + # Assume pre-defined datasets live in `./datasets`. + register_coco_instances( + key, + _get_ade_instances_meta(), + os.path.join(root, json_file) if "://" not in json_file else json_file, + os.path.join(root, image_root), + ) + + +_root = os.getenv("DETECTRON2_DATASETS", "datasets") +register_all_ade20k_instance(_root) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_ade20k_panoptic.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_ade20k_panoptic.py new file mode 100644 index 00000000..05094a61 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_ade20k_panoptic.py @@ -0,0 +1,394 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/Mask2Former/blob/main/mask2former/data/datasets/register_ade20k_panoptic.py +# Modified by Jitesh Jain (https://github.com/praeclarumjj3) +# ------------------------------------------------------------------------------ + +import json +import os + +from annotator.oneformer.detectron2.data import DatasetCatalog, MetadataCatalog +from annotator.oneformer.detectron2.utils.file_io import PathManager + +ADE20K_150_CATEGORIES = [ + {"color": [120, 120, 120], "id": 0, "isthing": 0, "name": "wall"}, + {"color": [180, 120, 120], "id": 1, "isthing": 0, "name": "building"}, + {"color": [6, 230, 230], "id": 2, "isthing": 0, "name": "sky"}, + {"color": [80, 50, 50], "id": 3, "isthing": 0, "name": "floor"}, + {"color": [4, 200, 3], "id": 4, "isthing": 0, "name": "tree"}, + {"color": [120, 120, 80], "id": 5, "isthing": 0, "name": "ceiling"}, + {"color": [140, 140, 140], "id": 6, "isthing": 0, "name": "road, route"}, + {"color": [204, 5, 255], "id": 7, "isthing": 1, "name": "bed"}, + {"color": [230, 230, 230], "id": 8, "isthing": 1, "name": "window "}, + {"color": [4, 250, 7], "id": 9, "isthing": 0, "name": "grass"}, + {"color": [224, 5, 255], "id": 10, "isthing": 1, "name": "cabinet"}, + {"color": [235, 255, 7], "id": 11, "isthing": 0, "name": "sidewalk, pavement"}, + {"color": [150, 5, 61], "id": 12, "isthing": 1, "name": "person"}, + {"color": [120, 120, 70], "id": 13, "isthing": 0, "name": "earth, ground"}, + {"color": [8, 255, 51], "id": 14, "isthing": 1, "name": "door"}, + {"color": [255, 6, 82], "id": 15, "isthing": 1, "name": "table"}, + {"color": [143, 255, 140], "id": 16, "isthing": 0, "name": "mountain, mount"}, + {"color": [204, 255, 4], "id": 17, "isthing": 0, "name": "plant"}, + {"color": [255, 51, 7], "id": 18, "isthing": 1, "name": "curtain"}, + {"color": [204, 70, 3], "id": 19, "isthing": 1, "name": "chair"}, + {"color": [0, 102, 200], "id": 20, "isthing": 1, "name": "car"}, + {"color": [61, 230, 250], "id": 21, "isthing": 0, "name": "water"}, + {"color": [255, 6, 51], "id": 22, "isthing": 1, "name": "painting, picture"}, + {"color": [11, 102, 255], "id": 23, "isthing": 1, "name": "sofa"}, + {"color": [255, 7, 71], "id": 24, "isthing": 1, "name": "shelf"}, + {"color": [255, 9, 224], "id": 25, "isthing": 0, "name": "house"}, + {"color": [9, 7, 230], "id": 26, "isthing": 0, "name": "sea"}, + {"color": [220, 220, 220], "id": 27, "isthing": 1, "name": "mirror"}, + {"color": [255, 9, 92], "id": 28, "isthing": 0, "name": "rug"}, + {"color": [112, 9, 255], "id": 29, "isthing": 0, "name": "field"}, + {"color": [8, 255, 214], "id": 30, "isthing": 1, "name": "armchair"}, + {"color": [7, 255, 224], "id": 31, "isthing": 1, "name": "seat"}, + {"color": [255, 184, 6], "id": 32, "isthing": 1, "name": "fence"}, + {"color": [10, 255, 71], "id": 33, "isthing": 1, "name": "desk"}, + {"color": [255, 41, 10], "id": 34, "isthing": 0, "name": "rock, stone"}, + {"color": [7, 255, 255], "id": 35, "isthing": 1, "name": "wardrobe, closet, press"}, + {"color": [224, 255, 8], "id": 36, "isthing": 1, "name": "lamp"}, + {"color": [102, 8, 255], "id": 37, "isthing": 1, "name": "tub"}, + {"color": [255, 61, 6], "id": 38, "isthing": 1, "name": "rail"}, + {"color": [255, 194, 7], "id": 39, "isthing": 1, "name": "cushion"}, + {"color": [255, 122, 8], "id": 40, "isthing": 0, "name": "base, pedestal, stand"}, + {"color": [0, 255, 20], "id": 41, "isthing": 1, "name": "box"}, + {"color": [255, 8, 41], "id": 42, "isthing": 1, "name": "column, pillar"}, + {"color": [255, 5, 153], "id": 43, "isthing": 1, "name": "signboard, sign"}, + { + "color": [6, 51, 255], + "id": 44, + "isthing": 1, + "name": "chest of drawers, chest, bureau, dresser", + }, + {"color": [235, 12, 255], "id": 45, "isthing": 1, "name": "counter"}, + {"color": [160, 150, 20], "id": 46, "isthing": 0, "name": "sand"}, + {"color": [0, 163, 255], "id": 47, "isthing": 1, "name": "sink"}, + {"color": [140, 140, 140], "id": 48, "isthing": 0, "name": "skyscraper"}, + {"color": [250, 10, 15], "id": 49, "isthing": 1, "name": "fireplace"}, + {"color": [20, 255, 0], "id": 50, "isthing": 1, "name": "refrigerator, icebox"}, + {"color": [31, 255, 0], "id": 51, "isthing": 0, "name": "grandstand, covered stand"}, + {"color": [255, 31, 0], "id": 52, "isthing": 0, "name": "path"}, + {"color": [255, 224, 0], "id": 53, "isthing": 1, "name": "stairs"}, + {"color": [153, 255, 0], "id": 54, "isthing": 0, "name": "runway"}, + {"color": [0, 0, 255], "id": 55, "isthing": 1, "name": "case, display case, showcase, vitrine"}, + { + "color": [255, 71, 0], + "id": 56, + "isthing": 1, + "name": "pool table, billiard table, snooker table", + }, + {"color": [0, 235, 255], "id": 57, "isthing": 1, "name": "pillow"}, + {"color": [0, 173, 255], "id": 58, "isthing": 1, "name": "screen door, screen"}, + {"color": [31, 0, 255], "id": 59, "isthing": 0, "name": "stairway, staircase"}, + {"color": [11, 200, 200], "id": 60, "isthing": 0, "name": "river"}, + {"color": [255, 82, 0], "id": 61, "isthing": 0, "name": "bridge, span"}, + {"color": [0, 255, 245], "id": 62, "isthing": 1, "name": "bookcase"}, + {"color": [0, 61, 255], "id": 63, "isthing": 0, "name": "blind, screen"}, + {"color": [0, 255, 112], "id": 64, "isthing": 1, "name": "coffee table"}, + { + "color": [0, 255, 133], + "id": 65, + "isthing": 1, + "name": "toilet, can, commode, crapper, pot, potty, stool, throne", + }, + {"color": [255, 0, 0], "id": 66, "isthing": 1, "name": "flower"}, + {"color": [255, 163, 0], "id": 67, "isthing": 1, "name": "book"}, + {"color": [255, 102, 0], "id": 68, "isthing": 0, "name": "hill"}, + {"color": [194, 255, 0], "id": 69, "isthing": 1, "name": "bench"}, + {"color": [0, 143, 255], "id": 70, "isthing": 1, "name": "countertop"}, + {"color": [51, 255, 0], "id": 71, "isthing": 1, "name": "stove"}, + {"color": [0, 82, 255], "id": 72, "isthing": 1, "name": "palm, palm tree"}, + {"color": [0, 255, 41], "id": 73, "isthing": 1, "name": "kitchen island"}, + {"color": [0, 255, 173], "id": 74, "isthing": 1, "name": "computer"}, + {"color": [10, 0, 255], "id": 75, "isthing": 1, "name": "swivel chair"}, + {"color": [173, 255, 0], "id": 76, "isthing": 1, "name": "boat"}, + {"color": [0, 255, 153], "id": 77, "isthing": 0, "name": "bar"}, + {"color": [255, 92, 0], "id": 78, "isthing": 1, "name": "arcade machine"}, + {"color": [255, 0, 255], "id": 79, "isthing": 0, "name": "hovel, hut, hutch, shack, shanty"}, + {"color": [255, 0, 245], "id": 80, "isthing": 1, "name": "bus"}, + {"color": [255, 0, 102], "id": 81, "isthing": 1, "name": "towel"}, + {"color": [255, 173, 0], "id": 82, "isthing": 1, "name": "light"}, + {"color": [255, 0, 20], "id": 83, "isthing": 1, "name": "truck"}, + {"color": [255, 184, 184], "id": 84, "isthing": 0, "name": "tower"}, + {"color": [0, 31, 255], "id": 85, "isthing": 1, "name": "chandelier"}, + {"color": [0, 255, 61], "id": 86, "isthing": 1, "name": "awning, sunshade, sunblind"}, + {"color": [0, 71, 255], "id": 87, "isthing": 1, "name": "street lamp"}, + {"color": [255, 0, 204], "id": 88, "isthing": 1, "name": "booth"}, + {"color": [0, 255, 194], "id": 89, "isthing": 1, "name": "tv"}, + {"color": [0, 255, 82], "id": 90, "isthing": 1, "name": "plane"}, + {"color": [0, 10, 255], "id": 91, "isthing": 0, "name": "dirt track"}, + {"color": [0, 112, 255], "id": 92, "isthing": 1, "name": "clothes"}, + {"color": [51, 0, 255], "id": 93, "isthing": 1, "name": "pole"}, + {"color": [0, 194, 255], "id": 94, "isthing": 0, "name": "land, ground, soil"}, + { + "color": [0, 122, 255], + "id": 95, + "isthing": 1, + "name": "bannister, banister, balustrade, balusters, handrail", + }, + { + "color": [0, 255, 163], + "id": 96, + "isthing": 0, + "name": "escalator, moving staircase, moving stairway", + }, + { + "color": [255, 153, 0], + "id": 97, + "isthing": 1, + "name": "ottoman, pouf, pouffe, puff, hassock", + }, + {"color": [0, 255, 10], "id": 98, "isthing": 1, "name": "bottle"}, + {"color": [255, 112, 0], "id": 99, "isthing": 0, "name": "buffet, counter, sideboard"}, + { + "color": [143, 255, 0], + "id": 100, + "isthing": 0, + "name": "poster, posting, placard, notice, bill, card", + }, + {"color": [82, 0, 255], "id": 101, "isthing": 0, "name": "stage"}, + {"color": [163, 255, 0], "id": 102, "isthing": 1, "name": "van"}, + {"color": [255, 235, 0], "id": 103, "isthing": 1, "name": "ship"}, + {"color": [8, 184, 170], "id": 104, "isthing": 1, "name": "fountain"}, + { + "color": [133, 0, 255], + "id": 105, + "isthing": 0, + "name": "conveyer belt, conveyor belt, conveyer, conveyor, transporter", + }, + {"color": [0, 255, 92], "id": 106, "isthing": 0, "name": "canopy"}, + { + "color": [184, 0, 255], + "id": 107, + "isthing": 1, + "name": "washer, automatic washer, washing machine", + }, + {"color": [255, 0, 31], "id": 108, "isthing": 1, "name": "plaything, toy"}, + {"color": [0, 184, 255], "id": 109, "isthing": 0, "name": "pool"}, + {"color": [0, 214, 255], "id": 110, "isthing": 1, "name": "stool"}, + {"color": [255, 0, 112], "id": 111, "isthing": 1, "name": "barrel, cask"}, + {"color": [92, 255, 0], "id": 112, "isthing": 1, "name": "basket, handbasket"}, + {"color": [0, 224, 255], "id": 113, "isthing": 0, "name": "falls"}, + {"color": [112, 224, 255], "id": 114, "isthing": 0, "name": "tent"}, + {"color": [70, 184, 160], "id": 115, "isthing": 1, "name": "bag"}, + {"color": [163, 0, 255], "id": 116, "isthing": 1, "name": "minibike, motorbike"}, + {"color": [153, 0, 255], "id": 117, "isthing": 0, "name": "cradle"}, + {"color": [71, 255, 0], "id": 118, "isthing": 1, "name": "oven"}, + {"color": [255, 0, 163], "id": 119, "isthing": 1, "name": "ball"}, + {"color": [255, 204, 0], "id": 120, "isthing": 1, "name": "food, solid food"}, + {"color": [255, 0, 143], "id": 121, "isthing": 1, "name": "step, stair"}, + {"color": [0, 255, 235], "id": 122, "isthing": 0, "name": "tank, storage tank"}, + {"color": [133, 255, 0], "id": 123, "isthing": 1, "name": "trade name"}, + {"color": [255, 0, 235], "id": 124, "isthing": 1, "name": "microwave"}, + {"color": [245, 0, 255], "id": 125, "isthing": 1, "name": "pot"}, + {"color": [255, 0, 122], "id": 126, "isthing": 1, "name": "animal"}, + {"color": [255, 245, 0], "id": 127, "isthing": 1, "name": "bicycle"}, + {"color": [10, 190, 212], "id": 128, "isthing": 0, "name": "lake"}, + {"color": [214, 255, 0], "id": 129, "isthing": 1, "name": "dishwasher"}, + {"color": [0, 204, 255], "id": 130, "isthing": 1, "name": "screen"}, + {"color": [20, 0, 255], "id": 131, "isthing": 0, "name": "blanket, cover"}, + {"color": [255, 255, 0], "id": 132, "isthing": 1, "name": "sculpture"}, + {"color": [0, 153, 255], "id": 133, "isthing": 1, "name": "hood, exhaust hood"}, + {"color": [0, 41, 255], "id": 134, "isthing": 1, "name": "sconce"}, + {"color": [0, 255, 204], "id": 135, "isthing": 1, "name": "vase"}, + {"color": [41, 0, 255], "id": 136, "isthing": 1, "name": "traffic light"}, + {"color": [41, 255, 0], "id": 137, "isthing": 1, "name": "tray"}, + {"color": [173, 0, 255], "id": 138, "isthing": 1, "name": "trash can"}, + {"color": [0, 245, 255], "id": 139, "isthing": 1, "name": "fan"}, + {"color": [71, 0, 255], "id": 140, "isthing": 0, "name": "pier"}, + {"color": [122, 0, 255], "id": 141, "isthing": 0, "name": "crt screen"}, + {"color": [0, 255, 184], "id": 142, "isthing": 1, "name": "plate"}, + {"color": [0, 92, 255], "id": 143, "isthing": 1, "name": "monitor"}, + {"color": [184, 255, 0], "id": 144, "isthing": 1, "name": "bulletin board"}, + {"color": [0, 133, 255], "id": 145, "isthing": 0, "name": "shower"}, + {"color": [255, 214, 0], "id": 146, "isthing": 1, "name": "radiator"}, + {"color": [25, 194, 194], "id": 147, "isthing": 1, "name": "glass, drinking glass"}, + {"color": [102, 255, 0], "id": 148, "isthing": 1, "name": "clock"}, + {"color": [92, 0, 255], "id": 149, "isthing": 1, "name": "flag"}, +] + +ADE20k_COLORS = [k["color"] for k in ADE20K_150_CATEGORIES] + +MetadataCatalog.get("ade20k_sem_seg_train").set( + stuff_colors=ADE20k_COLORS[:], +) + +MetadataCatalog.get("ade20k_sem_seg_val").set( + stuff_colors=ADE20k_COLORS[:], +) + + +def load_ade20k_panoptic_json(json_file, image_dir, gt_dir, semseg_dir, meta): + """ + Args: + image_dir (str): path to the raw dataset. e.g., "~/coco/train2017". + gt_dir (str): path to the raw annotations. e.g., "~/coco/panoptic_train2017". + json_file (str): path to the json file. e.g., "~/coco/annotations/panoptic_train2017.json". + Returns: + list[dict]: a list of dicts in Detectron2 standard format. (See + `Using Custom Datasets `_ ) + """ + + def _convert_category_id(segment_info, meta): + if segment_info["category_id"] in meta["thing_dataset_id_to_contiguous_id"]: + segment_info["category_id"] = meta["thing_dataset_id_to_contiguous_id"][ + segment_info["category_id"] + ] + segment_info["isthing"] = True + else: + segment_info["category_id"] = meta["stuff_dataset_id_to_contiguous_id"][ + segment_info["category_id"] + ] + segment_info["isthing"] = False + return segment_info + + with PathManager.open(json_file) as f: + json_info = json.load(f) + + ret = [] + for ann in json_info["annotations"]: + image_id = ann["image_id"] + # TODO: currently we assume image and label has the same filename but + # different extension, and images have extension ".jpg" for COCO. Need + # to make image extension a user-provided argument if we extend this + # function to support other COCO-like datasets. + image_file = os.path.join(image_dir, os.path.splitext(ann["file_name"])[0] + ".jpg") + label_file = os.path.join(gt_dir, ann["file_name"]) + sem_label_file = os.path.join(semseg_dir, ann["file_name"]) + segments_info = [_convert_category_id(x, meta) for x in ann["segments_info"]] + ret.append( + { + "file_name": image_file, + "image_id": image_id, + "pan_seg_file_name": label_file, + "sem_seg_file_name": sem_label_file, + "segments_info": segments_info, + } + ) + assert len(ret), f"No images found in {image_dir}!" + assert PathManager.isfile(ret[0]["file_name"]), ret[0]["file_name"] + assert PathManager.isfile(ret[0]["pan_seg_file_name"]), ret[0]["pan_seg_file_name"] + assert PathManager.isfile(ret[0]["sem_seg_file_name"]), ret[0]["sem_seg_file_name"] + return ret + + +def register_ade20k_panoptic( + name, metadata, image_root, panoptic_root, semantic_root, panoptic_json, instances_json=None, +): + """ + Register a "standard" version of ADE20k panoptic segmentation dataset named `name`. + The dictionaries in this registered dataset follows detectron2's standard format. + Hence it's called "standard". + Args: + name (str): the name that identifies a dataset, + e.g. "ade20k_panoptic_train" + metadata (dict): extra metadata associated with this dataset. + image_root (str): directory which contains all the images + panoptic_root (str): directory which contains panoptic annotation images in COCO format + panoptic_json (str): path to the json panoptic annotation file in COCO format + sem_seg_root (none): not used, to be consistent with + `register_coco_panoptic_separated`. + instances_json (str): path to the json instance annotation file + """ + panoptic_name = name + DatasetCatalog.register( + panoptic_name, + lambda: load_ade20k_panoptic_json( + panoptic_json, image_root, panoptic_root, semantic_root, metadata + ), + ) + MetadataCatalog.get(panoptic_name).set( + panoptic_root=panoptic_root, + image_root=image_root, + panoptic_json=panoptic_json, + json_file=instances_json, + evaluator_type="ade20k_panoptic_seg", + ignore_label=255, + label_divisor=1000, + **metadata, + ) + + +_PREDEFINED_SPLITS_ADE20K_PANOPTIC = { + "ade20k_panoptic_train": ( + "ADEChallengeData2016/images/training", + "ADEChallengeData2016/ade20k_panoptic_train", + "ADEChallengeData2016/ade20k_panoptic_train.json", + "ADEChallengeData2016/annotations_detectron2/training", + "ADEChallengeData2016/ade20k_instance_train.json", + ), + "ade20k_panoptic_val": ( + "ADEChallengeData2016/images/validation", + "ADEChallengeData2016/ade20k_panoptic_val", + "ADEChallengeData2016/ade20k_panoptic_val.json", + "ADEChallengeData2016/annotations_detectron2/validation", + "ADEChallengeData2016/ade20k_instance_val.json", + ), +} + + +def get_metadata(): + meta = {} + # The following metadata maps contiguous id from [0, #thing categories + + # #stuff categories) to their names and colors. We have to replica of the + # same name and color under "thing_*" and "stuff_*" because the current + # visualization function in D2 handles thing and class classes differently + # due to some heuristic used in Panoptic FPN. We keep the same naming to + # enable reusing existing visualization functions. + thing_classes = [k["name"] for k in ADE20K_150_CATEGORIES if k["isthing"] == 1] + thing_colors = [k["color"] for k in ADE20K_150_CATEGORIES if k["isthing"] == 1] + stuff_classes = [k["name"] for k in ADE20K_150_CATEGORIES] + stuff_colors = [k["color"] for k in ADE20K_150_CATEGORIES] + + meta["thing_classes"] = thing_classes + meta["thing_colors"] = thing_colors + meta["stuff_classes"] = stuff_classes + meta["stuff_colors"] = stuff_colors + + # Convert category id for training: + # category id: like semantic segmentation, it is the class id for each + # pixel. Since there are some classes not used in evaluation, the category + # id is not always contiguous and thus we have two set of category ids: + # - original category id: category id in the original dataset, mainly + # used for evaluation. + # - contiguous category id: [0, #classes), in order to train the linear + # softmax classifier. + thing_dataset_id_to_contiguous_id = {} + stuff_dataset_id_to_contiguous_id = {} + + for i, cat in enumerate(ADE20K_150_CATEGORIES): + if cat["isthing"]: + thing_dataset_id_to_contiguous_id[cat["id"]] = i + # else: + # stuff_dataset_id_to_contiguous_id[cat["id"]] = i + + # in order to use sem_seg evaluator + stuff_dataset_id_to_contiguous_id[cat["id"]] = i + + meta["thing_dataset_id_to_contiguous_id"] = thing_dataset_id_to_contiguous_id + meta["stuff_dataset_id_to_contiguous_id"] = stuff_dataset_id_to_contiguous_id + + return meta + + +def register_all_ade20k_panoptic(root): + metadata = get_metadata() + for ( + prefix, + (image_root, panoptic_root, panoptic_json, semantic_root, instance_json), + ) in _PREDEFINED_SPLITS_ADE20K_PANOPTIC.items(): + # The "standard" version of COCO panoptic segmentation dataset, + # e.g. used by Panoptic-DeepLab + register_ade20k_panoptic( + prefix, + metadata, + os.path.join(root, image_root), + os.path.join(root, panoptic_root), + os.path.join(root, semantic_root), + os.path.join(root, panoptic_json), + os.path.join(root, instance_json), + ) + + +_root = os.getenv("DETECTRON2_DATASETS", "datasets") +register_all_ade20k_panoptic(_root) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_cityscapes_panoptic.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_cityscapes_panoptic.py new file mode 100644 index 00000000..5f2c2a69 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_cityscapes_panoptic.py @@ -0,0 +1,199 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/detectron2/blob/main/detectron2/data/datasets/cityscapes_panoptic.py +# Modified by Jitesh Jain (https://github.com/praeclarumjj3) +# ------------------------------------------------------------------------------ + +import json +import logging +import os + +from annotator.oneformer.detectron2.data import DatasetCatalog, MetadataCatalog +from annotator.oneformer.detectron2.data.datasets.builtin_meta import CITYSCAPES_CATEGORIES +from annotator.oneformer.detectron2.utils.file_io import PathManager + +""" +This file contains functions to register the Cityscapes panoptic dataset to the DatasetCatalog. +""" + + +logger = logging.getLogger(__name__) + + +def get_cityscapes_panoptic_files(image_dir, gt_dir, json_info): + files = [] + # scan through the directory + cities = PathManager.ls(image_dir) + logger.info(f"{len(cities)} cities found in '{image_dir}'.") + image_dict = {} + for city in cities: + city_img_dir = os.path.join(image_dir, city) + for basename in PathManager.ls(city_img_dir): + image_file = os.path.join(city_img_dir, basename) + + suffix = "_leftImg8bit.png" + assert basename.endswith(suffix), basename + basename = os.path.basename(basename)[: -len(suffix)] + + image_dict[basename] = image_file + + for ann in json_info["annotations"]: + image_file = image_dict.get(ann["image_id"], None) + assert image_file is not None, "No image {} found for annotation {}".format( + ann["image_id"], ann["file_name"] + ) + label_file = os.path.join(gt_dir, ann["file_name"]) + segments_info = ann["segments_info"] + files.append((image_file, label_file, segments_info)) + + assert len(files), "No images found in {}".format(image_dir) + assert PathManager.isfile(files[0][0]), files[0][0] + assert PathManager.isfile(files[0][1]), files[0][1] + return files + + +def load_cityscapes_panoptic(image_dir, gt_dir, gt_json, meta): + """ + Args: + image_dir (str): path to the raw dataset. e.g., "~/cityscapes/leftImg8bit/train". + gt_dir (str): path to the raw annotations. e.g., + "~/cityscapes/gtFine/cityscapes_panoptic_train". + gt_json (str): path to the json file. e.g., + "~/cityscapes/gtFine/cityscapes_panoptic_train.json". + meta (dict): dictionary containing "thing_dataset_id_to_contiguous_id" + and "stuff_dataset_id_to_contiguous_id" to map category ids to + contiguous ids for training. + + Returns: + list[dict]: a list of dicts in Detectron2 standard format. (See + `Using Custom Datasets `_ ) + """ + + def _convert_category_id(segment_info, meta): + if segment_info["category_id"] in meta["thing_dataset_id_to_contiguous_id"]: + segment_info["category_id"] = meta["thing_dataset_id_to_contiguous_id"][ + segment_info["category_id"] + ] + else: + segment_info["category_id"] = meta["stuff_dataset_id_to_contiguous_id"][ + segment_info["category_id"] + ] + return segment_info + + assert os.path.exists( + gt_json + ), "Please run `python cityscapesscripts/preparation/createPanopticImgs.py` to generate label files." # noqa + + + with open(gt_json) as f: + json_info = json.load(f) + + files = get_cityscapes_panoptic_files(image_dir, gt_dir, json_info) + ret = [] + for image_file, label_file, segments_info in files: + sem_label_file = ( + image_file.replace("leftImg8bit", "gtFine").split(".")[0] + "_labelTrainIds.png" + ) + segments_info = [_convert_category_id(x, meta) for x in segments_info] + ret.append( + { + "file_name": image_file, + "image_id": "_".join( + os.path.splitext(os.path.basename(image_file))[0].split("_")[:3] + ), + "sem_seg_file_name": sem_label_file, + "pan_seg_file_name": label_file, + "segments_info": segments_info, + } + ) + assert len(ret), f"No images found in {image_dir}!" + assert PathManager.isfile( + ret[0]["sem_seg_file_name"] + ), "Please generate labelTrainIds.png with cityscapesscripts/preparation/createTrainIdLabelImgs.py" # noqa + assert PathManager.isfile( + ret[0]["pan_seg_file_name"] + ), "Please generate panoptic annotation with python cityscapesscripts/preparation/createPanopticImgs.py" # noqa + return ret + + +_RAW_CITYSCAPES_PANOPTIC_SPLITS = { + "cityscapes_fine_panoptic_train": ( + "cityscapes/leftImg8bit/train", + "cityscapes/gtFine/cityscapes_panoptic_train", + "cityscapes/gtFine/cityscapes_panoptic_train.json", + ), + "cityscapes_fine_panoptic_val": ( + "cityscapes/leftImg8bit/val", + "cityscapes/gtFine/cityscapes_panoptic_val", + "cityscapes/gtFine/cityscapes_panoptic_val.json", + ), + # "cityscapes_fine_panoptic_test": not supported yet +} + + +def register_all_cityscapes_panoptic(root): + meta = {} + # The following metadata maps contiguous id from [0, #thing categories + + # #stuff categories) to their names and colors. We have to replica of the + # same name and color under "thing_*" and "stuff_*" because the current + # visualization function in D2 handles thing and class classes differently + # due to some heuristic used in Panoptic FPN. We keep the same naming to + # enable reusing existing visualization functions. + thing_classes = [k["name"] for k in CITYSCAPES_CATEGORIES] + thing_colors = [k["color"] for k in CITYSCAPES_CATEGORIES] + stuff_classes = [k["name"] for k in CITYSCAPES_CATEGORIES] + stuff_colors = [k["color"] for k in CITYSCAPES_CATEGORIES] + + meta["thing_classes"] = thing_classes + meta["thing_colors"] = thing_colors + meta["stuff_classes"] = stuff_classes + meta["stuff_colors"] = stuff_colors + + # There are three types of ids in cityscapes panoptic segmentation: + # (1) category id: like semantic segmentation, it is the class id for each + # pixel. Since there are some classes not used in evaluation, the category + # id is not always contiguous and thus we have two set of category ids: + # - original category id: category id in the original dataset, mainly + # used for evaluation. + # - contiguous category id: [0, #classes), in order to train the classifier + # (2) instance id: this id is used to differentiate different instances from + # the same category. For "stuff" classes, the instance id is always 0; for + # "thing" classes, the instance id starts from 1 and 0 is reserved for + # ignored instances (e.g. crowd annotation). + # (3) panoptic id: this is the compact id that encode both category and + # instance id by: category_id * 1000 + instance_id. + thing_dataset_id_to_contiguous_id = {} + stuff_dataset_id_to_contiguous_id = {} + + for k in CITYSCAPES_CATEGORIES: + if k["isthing"] == 1: + thing_dataset_id_to_contiguous_id[k["id"]] = k["trainId"] + else: + stuff_dataset_id_to_contiguous_id[k["id"]] = k["trainId"] + + meta["thing_dataset_id_to_contiguous_id"] = thing_dataset_id_to_contiguous_id + meta["stuff_dataset_id_to_contiguous_id"] = stuff_dataset_id_to_contiguous_id + + for key, (image_dir, gt_dir, gt_json) in _RAW_CITYSCAPES_PANOPTIC_SPLITS.items(): + image_dir = os.path.join(root, image_dir) + gt_dir = os.path.join(root, gt_dir) + gt_json = os.path.join(root, gt_json) + + if key in DatasetCatalog.list(): + DatasetCatalog.remove(key) + + DatasetCatalog.register( + key, lambda x=image_dir, y=gt_dir, z=gt_json: load_cityscapes_panoptic(x, y, z, meta) + ) + MetadataCatalog.get(key).set( + panoptic_root=gt_dir, + image_root=image_dir, + panoptic_json=gt_json, + gt_dir=gt_dir.replace("cityscapes_panoptic_", ""), + evaluator_type="cityscapes_panoptic_seg", + ignore_label=255, + label_divisor=1000, + **meta, + ) + +_root = os.getenv("DETECTRON2_DATASETS", "datasets") +register_all_cityscapes_panoptic(_root) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_coco_panoptic2instance.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_coco_panoptic2instance.py new file mode 100644 index 00000000..511c5b66 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_coco_panoptic2instance.py @@ -0,0 +1,44 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/detectron2/blob/main/detectron2/data/datasets/builtin.py +# Modified by Jitesh Jain (https://github.com/praeclarumjj3) +# ------------------------------------------------------------------------------ + + +""" +This file registers pre-defined datasets at hard-coded paths, and their metadata. + +We hard-code metadata for common datasets. This will enable: +1. Consistency check when loading the datasets +2. Use models on these standard datasets directly and run demos, + without having to download the dataset annotations + +We hard-code some paths to the dataset that's assumed to +exist in "./datasets/". + +Users SHOULD NOT use this file to create new dataset / metadata for new dataset. +To add new dataset, refer to the tutorial "docs/DATASETS.md". +""" + +import os +from annotator.oneformer.detectron2.data.datasets.builtin_meta import _get_builtin_metadata +from annotator.oneformer.detectron2.data.datasets.coco import register_coco_instances + + +_PREDEFINED_SPLITS_COCO = { + "coco_2017_val_panoptic2instance": ("coco/val2017", "coco/annotations/panoptic2instances_val2017.json"), +} + + +def register_panoptic2instances_coco(root): + for key, (image_root, json_file) in _PREDEFINED_SPLITS_COCO.items(): + # Assume pre-defined datasets live in `./datasets`. + register_coco_instances( + key, + _get_builtin_metadata("coco"), + os.path.join(root, json_file) if "://" not in json_file else json_file, + os.path.join(root, image_root), + ) + + +_root = os.path.expanduser(os.getenv("DETECTRON2_DATASETS", "datasets")) +register_panoptic2instances_coco(_root) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_coco_panoptic_annos_semseg.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_coco_panoptic_annos_semseg.py new file mode 100644 index 00000000..170daf3e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/datasets/register_coco_panoptic_annos_semseg.py @@ -0,0 +1,367 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/Mask2Former/blob/main/mask2former/data/datasets/register_coco_panoptic_annos_semseg.py +# Modified by Jitesh Jain (https://github.com/praeclarumjj3) +# ------------------------------------------------------------------------------ + +import json +import os + +from annotator.oneformer.detectron2.data import DatasetCatalog, MetadataCatalog +from annotator.oneformer.detectron2.data.datasets import load_sem_seg +from annotator.oneformer.detectron2.data.datasets.builtin_meta import COCO_CATEGORIES +from annotator.oneformer.detectron2.utils.file_io import PathManager +import contextlib +import logging +import io +from fvcore.common.timer import Timer +import annotator.oneformer.pycocotools.mask as mask_util +from annotator.oneformer.detectron2.structures import BoxMode + + +logger = logging.getLogger(__name__) + + +_PREDEFINED_SPLITS_COCO_PANOPTIC = { + "coco_2017_train_panoptic": ( + # This is the original panoptic annotation directory + "coco/panoptic_train2017", + "coco/annotations/panoptic_train2017.json", + # This directory contains semantic annotations that are + # converted from panoptic annotations. + # It is used by PanopticFPN. + # You can use the script at detectron2/datasets/prepare_panoptic_fpn.py + # to create these directories. + "coco/panoptic_semseg_train2017", + ), + "coco_2017_val_panoptic": ( + "coco/panoptic_val2017", + "coco/annotations/panoptic_val2017.json", + "coco/panoptic_semseg_val2017", + ), +} + +def load_coco_instance_json(json_file, image_root, dataset_name=None): + from annotator.oneformer.pycocotools.coco import COCO + + timer = Timer() + json_file = PathManager.get_local_path(json_file) + with contextlib.redirect_stdout(io.StringIO()): + coco_api = COCO(json_file) + if timer.seconds() > 1: + logger.info("Loading {} takes {:.2f} seconds.".format(json_file, timer.seconds())) + + id_map = None + if dataset_name is not None: + meta = MetadataCatalog.get(dataset_name) + cat_ids = sorted(coco_api.getCatIds()) + cats = coco_api.loadCats(cat_ids) + # The categories in a custom json file may not be sorted. + thing_classes = [c["name"] for c in sorted(cats, key=lambda x: x["id"])] + meta.thing_classes = thing_classes + + # In COCO, certain category ids are artificially removed, + # and by convention they are always ignored. + # We deal with COCO's id issue and translate + # the category ids to contiguous ids in [0, 80). + + # It works by looking at the "categories" field in the json, therefore + # if users' own json also have incontiguous ids, we'll + # apply this mapping as well but print a warning. + if not (min(cat_ids) == 1 and max(cat_ids) == len(cat_ids)): + if "coco" not in dataset_name: + logger.warning( + """ +Category ids in annotations are not in [1, #categories]! We'll apply a mapping for you. +""" + ) + id_map = {v: i for i, v in enumerate(cat_ids)} + meta.thing_dataset_id_to_contiguous_id = id_map + + # sort indices for reproducible results + img_ids = sorted(coco_api.imgs.keys()) + # imgs is a list of dicts, each looks something like: + # {'license': 4, + # 'url': 'http://farm6.staticflickr.com/5454/9413846304_881d5e5c3b_z.jpg', + # 'file_name': 'COCO_val2014_000000001268.jpg', + # 'height': 427, + # 'width': 640, + # 'date_captured': '2013-11-17 05:57:24', + # 'id': 1268} + imgs = coco_api.loadImgs(img_ids) + # anns is a list[list[dict]], where each dict is an annotation + # record for an object. The inner list enumerates the objects in an image + # and the outer list enumerates over images. Example of anns[0]: + # [{'segmentation': [[192.81, + # 247.09, + # ... + # 219.03, + # 249.06]], + # 'area': 1035.749, + # 'iscrowd': 0, + # 'image_id': 1268, + # 'bbox': [192.81, 224.8, 74.73, 33.43], + # 'category_id': 16, + # 'id': 42986}, + # ...] + anns = [coco_api.imgToAnns[img_id] for img_id in img_ids] + total_num_valid_anns = sum([len(x) for x in anns]) + total_num_anns = len(coco_api.anns) + if total_num_valid_anns < total_num_anns: + logger.warning( + f"{json_file} contains {total_num_anns} annotations, but only " + f"{total_num_valid_anns} of them match to images in the file." + ) + + if "minival" not in json_file: + # The popular valminusminival & minival annotations for COCO2014 contain this bug. + # However the ratio of buggy annotations there is tiny and does not affect accuracy. + # Therefore we explicitly white-list them. + ann_ids = [ann["id"] for anns_per_image in anns for ann in anns_per_image] + assert len(set(ann_ids)) == len(ann_ids), "Annotation ids in '{}' are not unique!".format( + json_file + ) + + imgs_anns = list(zip(imgs, anns)) + logger.info("Loaded {} images in COCO format from {}".format(len(imgs_anns), json_file)) + + dataset_dicts = {} + + ann_keys = ["iscrowd", "bbox", "keypoints", "category_id"] + + num_instances_without_valid_segmentation = 0 + + for (img_dict, anno_dict_list) in imgs_anns: + record = {} + record["file_name"] = os.path.join(image_root, img_dict["file_name"]) + record["height"] = img_dict["height"] + record["width"] = img_dict["width"] + image_id = record["image_id"] = img_dict["id"] + + objs = [] + for anno in anno_dict_list: + # Check that the image_id in this annotation is the same as + # the image_id we're looking at. + # This fails only when the data parsing logic or the annotation file is buggy. + + # The original COCO valminusminival2014 & minival2014 annotation files + # actually contains bugs that, together with certain ways of using COCO API, + # can trigger this assertion. + assert anno["image_id"] == image_id + + assert anno.get("ignore", 0) == 0, '"ignore" in COCO json file is not supported.' + + obj = {key: anno[key] for key in ann_keys if key in anno} + if "bbox" in obj and len(obj["bbox"]) == 0: + raise ValueError( + f"One annotation of image {image_id} contains empty 'bbox' value! " + "This json does not have valid COCO format." + ) + + segm = anno.get("segmentation", None) + if segm: # either list[list[float]] or dict(RLE) + if isinstance(segm, dict): + if isinstance(segm["counts"], list): + # convert to compressed RLE + segm = mask_util.frPyObjects(segm, *segm["size"]) + else: + # filter out invalid polygons (< 3 points) + segm = [poly for poly in segm if len(poly) % 2 == 0 and len(poly) >= 6] + if len(segm) == 0: + num_instances_without_valid_segmentation += 1 + continue # ignore this instance + obj["segmentation"] = segm + + keypts = anno.get("keypoints", None) + if keypts: # list[int] + for idx, v in enumerate(keypts): + if idx % 3 != 2: + # COCO's segmentation coordinates are floating points in [0, H or W], + # but keypoint coordinates are integers in [0, H-1 or W-1] + # Therefore we assume the coordinates are "pixel indices" and + # add 0.5 to convert to floating point coordinates. + keypts[idx] = v + 0.5 + obj["keypoints"] = keypts + + obj["bbox_mode"] = BoxMode.XYWH_ABS + if id_map: + annotation_category_id = obj["category_id"] + try: + obj["category_id"] = id_map[annotation_category_id] + except KeyError as e: + raise KeyError( + f"Encountered category_id={annotation_category_id} " + "but this id does not exist in 'categories' of the json file." + ) from e + objs.append(obj) + record["annotations"] = objs + dataset_dicts[image_id] = record + + if num_instances_without_valid_segmentation > 0: + logger.warning( + "Filtered out {} instances without valid segmentation. ".format( + num_instances_without_valid_segmentation + ) + + "There might be issues in your dataset generation process. Please " + "check https://detectron2.readthedocs.io/en/latest/tutorials/datasets.html carefully" + ) + return dataset_dicts + +def get_metadata(): + meta = {} + # The following metadata maps contiguous id from [0, #thing categories + + # #stuff categories) to their names and colors. We have to replica of the + # same name and color under "thing_*" and "stuff_*" because the current + # visualization function in D2 handles thing and class classes differently + # due to some heuristic used in Panoptic FPN. We keep the same naming to + # enable reusing existing visualization functions. + thing_classes = [k["name"] for k in COCO_CATEGORIES if k["isthing"] == 1] + thing_colors = [k["color"] for k in COCO_CATEGORIES if k["isthing"] == 1] + stuff_classes = [k["name"] for k in COCO_CATEGORIES] + stuff_colors = [k["color"] for k in COCO_CATEGORIES] + + meta["thing_classes"] = thing_classes + meta["thing_colors"] = thing_colors + meta["stuff_classes"] = stuff_classes + meta["stuff_colors"] = stuff_colors + + # Convert category id for training: + # category id: like semantic segmentation, it is the class id for each + # pixel. Since there are some classes not used in evaluation, the category + # id is not always contiguous and thus we have two set of category ids: + # - original category id: category id in the original dataset, mainly + # used for evaluation. + # - contiguous category id: [0, #classes), in order to train the linear + # softmax classifier. + thing_dataset_id_to_contiguous_id = {} + stuff_dataset_id_to_contiguous_id = {} + + for i, cat in enumerate(COCO_CATEGORIES): + if cat["isthing"]: + thing_dataset_id_to_contiguous_id[cat["id"]] = i + # else: + # stuff_dataset_id_to_contiguous_id[cat["id"]] = i + + # in order to use sem_seg evaluator + stuff_dataset_id_to_contiguous_id[cat["id"]] = i + + meta["thing_dataset_id_to_contiguous_id"] = thing_dataset_id_to_contiguous_id + meta["stuff_dataset_id_to_contiguous_id"] = stuff_dataset_id_to_contiguous_id + + return meta + + +def load_coco_panoptic_json(json_file, instances_json, instances_name, image_dir, gt_dir, semseg_dir, meta): + """ + Args: + image_dir (str): path to the raw dataset. e.g., "~/coco/train2017". + gt_dir (str): path to the raw annotations. e.g., "~/coco/panoptic_train2017". + json_file (str): path to the json file. e.g., "~/coco/annotations/panoptic_train2017.json". + Returns: + list[dict]: a list of dicts in Detectron2 standard format. (See + `Using Custom Datasets `_ ) + """ + + def _convert_category_id(segment_info, meta): + if segment_info["category_id"] in meta["thing_dataset_id_to_contiguous_id"]: + segment_info["category_id"] = meta["thing_dataset_id_to_contiguous_id"][ + segment_info["category_id"] + ] + segment_info["isthing"] = True + else: + segment_info["category_id"] = meta["stuff_dataset_id_to_contiguous_id"][ + segment_info["category_id"] + ] + segment_info["isthing"] = False + return segment_info + + with PathManager.open(json_file) as f: + json_info = json.load(f) + + instance_data_dicts = load_coco_instance_json(instances_json, image_dir.replace("panoptic_", ""), instances_name) + + ret = [] + for ann in json_info["annotations"]: + image_id = int(ann["image_id"]) + # TODO: currently we assume image and label has the same filename but + # different extension, and images have extension ".jpg" for COCO. Need + # to make image extension a user-provided argument if we extend this + # function to support other COCO-like datasets. + image_file = os.path.join(image_dir, os.path.splitext(ann["file_name"])[0] + ".jpg") + label_file = os.path.join(gt_dir, ann["file_name"]) + sem_label_file = os.path.join(semseg_dir, ann["file_name"]) + segments_info = [_convert_category_id(x, meta) for x in ann["segments_info"]] + ret.append( + { + "file_name": image_file, + "image_id": image_id, + "pan_seg_file_name": label_file, + "sem_seg_file_name": sem_label_file, + "segments_info": segments_info, + "annotations": instance_data_dicts[image_id]["annotations"], + } + ) + assert len(ret), f"No images found in {image_dir}!" + assert PathManager.isfile(ret[0]["file_name"]), ret[0]["file_name"] + assert PathManager.isfile(ret[0]["pan_seg_file_name"]), ret[0]["pan_seg_file_name"] + assert PathManager.isfile(ret[0]["sem_seg_file_name"]), ret[0]["sem_seg_file_name"] + return ret + + +def register_coco_panoptic_annos_sem_seg( + name, metadata, image_root, panoptic_root, panoptic_json, sem_seg_root, instances_json, instances_name, +): + panoptic_name = name + delattr(MetadataCatalog.get(panoptic_name), "thing_classes") + delattr(MetadataCatalog.get(panoptic_name), "thing_colors") + MetadataCatalog.get(panoptic_name).set( + thing_classes=metadata["thing_classes"], + thing_colors=metadata["thing_colors"], + # thing_dataset_id_to_contiguous_id=metadata["thing_dataset_id_to_contiguous_id"], + ) + + # the name is "coco_2017_train_panoptic_with_sem_seg" and "coco_2017_val_panoptic_with_sem_seg" + semantic_name = name + "_with_sem_seg" + DatasetCatalog.register( + semantic_name, + lambda: load_coco_panoptic_json(panoptic_json, instances_json, instances_name, image_root, panoptic_root, sem_seg_root, metadata), + ) + MetadataCatalog.get(semantic_name).set( + sem_seg_root=sem_seg_root, + panoptic_root=panoptic_root, + image_root=image_root, + panoptic_json=panoptic_json, + json_file=instances_json, + evaluator_type="coco_panoptic_seg", + ignore_label=255, + label_divisor=1000, + **metadata, + ) + + +def register_all_coco_panoptic_annos_sem_seg(root): + for ( + prefix, + (panoptic_root, panoptic_json, semantic_root), + ) in _PREDEFINED_SPLITS_COCO_PANOPTIC.items(): + + prefix_instances = prefix[: -len("_panoptic")] + instances_meta = MetadataCatalog.get(prefix_instances) + image_root, instances_json = instances_meta.image_root, instances_meta.json_file + + if 'val' in instances_json: + instances_json = instances_json.replace('instances_', 'panoptic2instances_') + + register_coco_panoptic_annos_sem_seg( + prefix, + get_metadata(), + image_root, + os.path.join(root, panoptic_root), + os.path.join(root, panoptic_json), + os.path.join(root, semantic_root), + instances_json, + prefix_instances, + ) + + +_root = os.getenv("DETECTRON2_DATASETS", "datasets") +register_all_coco_panoptic_annos_sem_seg(_root) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/tokenizer.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/tokenizer.py new file mode 100644 index 00000000..05d4c29c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/tokenizer.py @@ -0,0 +1,192 @@ +# ------------------------------------------------------------------------- +# MIT License +# +# Copyright (c) 2021 OpenAI +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# Modified by Jiarui Xu +# ------------------------------------------------------------------------- + +import gzip +import html +import os +from functools import lru_cache + +import ftfy +import regex as re +import torch + + +@lru_cache() +def default_bpe(): + return os.path.join(os.path.dirname(os.path.abspath(__file__)), 'bpe_simple_vocab_16e6.txt.gz') + +@lru_cache() +def bytes_to_unicode(): + """Returns list of utf-8 byte and a corresponding list of unicode strings. + + The reversible bpe codes work on unicode strings. This means you need a large # of unicode characters in your vocab + if you want to avoid UNKs. When you're at something like a 10B token dataset you end up needing around 5K for decent + coverage. This is a significant percentage of your normal, say, 32K bpe vocab. To avoid that, we want lookup tables + between utf-8 bytes and unicode strings. And avoids mapping to whitespace/control characters the bpe code barfs on. + """ + bs = list(range(ord('!'), ord('~') + 1)) + list(range(ord('¡'), ord('¬') + 1)) + list(range(ord('®'), ord('ÿ') + 1)) + cs = bs[:] + n = 0 + for b in range(2**8): + if b not in bs: + bs.append(b) + cs.append(2**8 + n) + n += 1 + cs = [chr(n) for n in cs] + return dict(zip(bs, cs)) + + +def get_pairs(word): + """Return set of symbol pairs in a word. + + Word is represented as tuple of symbols (symbols being variable-length strings). + """ + pairs = set() + prev_char = word[0] + for char in word[1:]: + pairs.add((prev_char, char)) + prev_char = char + return pairs + + +def basic_clean(text): + text = ftfy.fix_text(text) + text = html.unescape(html.unescape(text)) + return text.strip() + + +def whitespace_clean(text): + text = re.sub(r'\s+', ' ', text) + text = text.strip() + return text + +class Tokenize: + + def __init__(self, tokenizer, max_seq_len=77, truncate=True): + self.tokenizer = tokenizer + self.max_seq_len = max_seq_len + self.truncate = truncate + + def __call__(self, texts): + expanded_dim = False + if isinstance(texts, str): + texts = [texts] + expanded_dim = True + + sot_token = self.tokenizer.encoder['<|startoftext|>'] + eot_token = self.tokenizer.encoder['<|endoftext|>'] + all_tokens = [[sot_token] + self.tokenizer.encode(text) + [eot_token] for text in texts] + result = torch.zeros(len(all_tokens), self.max_seq_len, dtype=torch.long) + + for i, tokens in enumerate(all_tokens): + if len(tokens) > self.max_seq_len: + if self.truncate: + tokens = tokens[:self.max_seq_len] + tokens[-1] = eot_token + else: + raise RuntimeError(f'Input {texts[i]} is too long for context length {self.max_seq_len}') + result[i, :len(tokens)] = torch.tensor(tokens) + + if expanded_dim: + return result[0] + + return result + + +class SimpleTokenizer(object): + + def __init__(self, bpe_path: str = default_bpe()): + self.byte_encoder = bytes_to_unicode() + self.byte_decoder = {v: k for k, v in self.byte_encoder.items()} + merges = gzip.open(bpe_path).read().decode('utf-8').split('\n') + merges = merges[1:49152 - 256 - 2 + 1] + merges = [tuple(merge.split()) for merge in merges] + vocab = list(bytes_to_unicode().values()) + vocab = vocab + [v + '' for v in vocab] + for merge in merges: + vocab.append(''.join(merge)) + vocab.extend(['<|startoftext|>', '<|endoftext|>']) + self.encoder = dict(zip(vocab, range(len(vocab)))) + self.decoder = {v: k for k, v in self.encoder.items()} + self.bpe_ranks = dict(zip(merges, range(len(merges)))) + self.cache = {'<|startoftext|>': '<|startoftext|>', '<|endoftext|>': '<|endoftext|>'} + self.pat = re.compile( + r"""<\|startoftext\|>|<\|endoftext\|>|'s|'t|'re|'ve|'m|'ll|'d|[\p{L}]+|[\p{N}]|[^\s\p{L}\p{N}]+""", + re.IGNORECASE) + + def bpe(self, token): + if token in self.cache: + return self.cache[token] + word = tuple(token[:-1]) + (token[-1] + '', ) + pairs = get_pairs(word) + + if not pairs: + return token + '' + + while True: + bigram = min(pairs, key=lambda pair: self.bpe_ranks.get(pair, float('inf'))) + if bigram not in self.bpe_ranks: + break + first, second = bigram + new_word = [] + i = 0 + while i < len(word): + try: + j = word.index(first, i) + new_word.extend(word[i:j]) + i = j + except: # noqa: E722 + new_word.extend(word[i:]) + break + + if word[i] == first and i < len(word) - 1 and word[i + 1] == second: + new_word.append(first + second) + i += 2 + else: + new_word.append(word[i]) + i += 1 + new_word = tuple(new_word) + word = new_word + if len(word) == 1: + break + else: + pairs = get_pairs(word) + word = ' '.join(word) + self.cache[token] = word + return word + + def encode(self, text): + bpe_tokens = [] + text = whitespace_clean(basic_clean(text)).lower() + for token in re.findall(self.pat, text): + token = ''.join(self.byte_encoder[b] for b in token.encode('utf-8')) + bpe_tokens.extend(self.encoder[bpe_token] for bpe_token in self.bpe(token).split(' ')) + return bpe_tokens + + def decode(self, tokens): + text = ''.join([self.decoder[token] for token in tokens]) + text = bytearray([self.byte_decoder[c] for c in text]).decode('utf-8', errors='replace').replace('', ' ') + return text \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/demo/colormap.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/demo/colormap.py new file mode 100644 index 00000000..3eff9a46 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/demo/colormap.py @@ -0,0 +1,170 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +""" +An awesome colormap for really neat visualizations. +Copied from Detectron, and removed gray colors. +""" + +import numpy as np +import random +random.seed(0) + +__all__ = ["colormap", "random_color", "random_colors"] + +# fmt: off +# RGB: +# _COLORS = np.array( +# [ +# 0.000, 0.447, 0.741, +# 0.850, 0.325, 0.098, +# 0.929, 0.694, 0.125, +# 0.494, 0.184, 0.556, +# 0.466, 0.674, 0.188, +# 0.301, 0.745, 0.933, +# 0.635, 0.078, 0.184, +# 0.300, 0.300, 0.300, +# 0.600, 0.600, 0.600, +# 1.000, 0.000, 0.000, +# 1.000, 0.500, 0.000, +# 0.749, 0.749, 0.000, +# 0.000, 1.000, 0.000, +# 0.000, 0.000, 1.000, +# 0.667, 0.000, 1.000, +# 0.333, 0.333, 0.000, +# 0.333, 0.667, 0.000, +# 0.333, 1.000, 0.000, +# 0.667, 0.333, 0.000, +# 0.667, 0.667, 0.000, +# 0.667, 1.000, 0.000, +# 1.000, 0.333, 0.000, +# 1.000, 0.667, 0.000, +# 1.000, 1.000, 0.000, +# 0.000, 0.333, 0.500, +# 0.000, 0.667, 0.500, +# 0.000, 1.000, 0.500, +# 0.333, 0.000, 0.500, +# 0.333, 0.333, 0.500, +# 0.333, 0.667, 0.500, +# 0.333, 1.000, 0.500, +# 0.667, 0.000, 0.500, +# 0.667, 0.333, 0.500, +# 0.667, 0.667, 0.500, +# 0.667, 1.000, 0.500, +# 1.000, 0.000, 0.500, +# 1.000, 0.333, 0.500, +# 1.000, 0.667, 0.500, +# 1.000, 1.000, 0.500, +# 0.000, 0.333, 1.000, +# 0.000, 0.667, 1.000, +# 0.000, 1.000, 1.000, +# 0.333, 0.000, 1.000, +# 0.333, 0.333, 1.000, +# 0.333, 0.667, 1.000, +# 0.333, 1.000, 1.000, +# 0.667, 0.000, 1.000, +# 0.667, 0.333, 1.000, +# 0.667, 0.667, 1.000, +# 0.667, 1.000, 1.000, +# 1.000, 0.000, 1.000, +# 1.000, 0.333, 1.000, +# 1.000, 0.667, 1.000, +# 0.333, 0.000, 0.000, +# 0.500, 0.000, 0.000, +# 0.667, 0.000, 0.000, +# 0.833, 0.000, 0.000, +# 1.000, 0.000, 0.000, +# 0.000, 0.167, 0.000, +# 0.000, 0.333, 0.000, +# 0.000, 0.500, 0.000, +# 0.000, 0.667, 0.000, +# 0.000, 0.833, 0.000, +# 0.000, 1.000, 0.000, +# 0.000, 0.000, 0.167, +# 0.000, 0.000, 0.333, +# 0.000, 0.000, 0.500, +# 0.000, 0.000, 0.667, +# 0.000, 0.000, 0.833, +# 0.000, 0.000, 1.000, +# 0.000, 0.000, 0.000, +# 0.143, 0.143, 0.143, +# 0.857, 0.857, 0.857, +# 1.000, 1.000, 1.000 +# ] +# ).astype(np.float32).reshape(-1, 3) +# fmt: on + +_COLORS = [] + + +def gen_color(): + color = tuple(np.round(np.random.choice(range(256), size=3)/255, 3)) + if color not in _COLORS and np.mean(color) != 0.0: + _COLORS.append(color) + else: + gen_color() + + +for _ in range(300): + gen_color() + + +def colormap(rgb=False, maximum=255): + """ + Args: + rgb (bool): whether to return RGB colors or BGR colors. + maximum (int): either 255 or 1 + Returns: + ndarray: a float32 array of Nx3 colors, in range [0, 255] or [0, 1] + """ + assert maximum in [255, 1], maximum + c = _COLORS * maximum + if not rgb: + c = c[:, ::-1] + return c + + +def random_color(rgb=False, maximum=255): + """ + Args: + rgb (bool): whether to return RGB colors or BGR colors. + maximum (int): either 255 or 1 + Returns: + ndarray: a vector of 3 numbers + """ + idx = np.random.randint(0, len(_COLORS)) + ret = _COLORS[idx] * maximum + if not rgb: + ret = ret[::-1] + return ret + + +def random_colors(N, rgb=False, maximum=255): + """ + Args: + N (int): number of unique colors needed + rgb (bool): whether to return RGB colors or BGR colors. + maximum (int): either 255 or 1 + Returns: + ndarray: a list of random_color + """ + indices = random.sample(range(len(_COLORS)), N) + ret = [_COLORS[i] * maximum for i in indices] + if not rgb: + ret = [x[::-1] for x in ret] + return ret + + +if __name__ == "__main__": + import cv2 + + size = 100 + H, W = 10, 10 + canvas = np.random.rand(H * size, W * size, 3).astype("float32") + for h in range(H): + for w in range(W): + idx = h * W + w + if idx >= len(_COLORS): + break + canvas[h * size : (h + 1) * size, w * size : (w + 1) * size] = _COLORS[idx] + cv2.imshow("a", canvas) + cv2.waitKey(0) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/demo/defaults.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/demo/defaults.py new file mode 100644 index 00000000..ba991299 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/demo/defaults.py @@ -0,0 +1,77 @@ +import torch +import annotator.oneformer.detectron2.data.transforms as T +from annotator.oneformer.detectron2.checkpoint import DetectionCheckpointer +from annotator.oneformer.detectron2.data import ( + MetadataCatalog, +) +from annotator.oneformer.detectron2.modeling import build_model + + +__all__ = [ + "DefaultPredictor", +] + + +class DefaultPredictor: + """ + Create a simple end-to-end predictor with the given config that runs on + single device for a single input image. + Compared to using the model directly, this class does the following additions: + 1. Load checkpoint from `cfg.MODEL.WEIGHTS`. + 2. Always take BGR image as the input and apply conversion defined by `cfg.INPUT.FORMAT`. + 3. Apply resizing defined by `cfg.INPUT.{MIN,MAX}_SIZE_TEST`. + 4. Take one input image and produce a single output, instead of a batch. + This is meant for simple demo purposes, so it does the above steps automatically. + This is not meant for benchmarks or running complicated inference logic. + If you'd like to do anything more complicated, please refer to its source code as + examples to build and use the model manually. + Attributes: + metadata (Metadata): the metadata of the underlying dataset, obtained from + cfg.DATASETS.TEST. + Examples: + :: + pred = DefaultPredictor(cfg) + inputs = cv2.imread("input.jpg") + outputs = pred(inputs) + """ + + def __init__(self, cfg): + self.cfg = cfg.clone() # cfg can be modified by model + self.model = build_model(self.cfg) + self.model.eval() + if len(cfg.DATASETS.TEST): + self.metadata = MetadataCatalog.get(cfg.DATASETS.TEST[0]) + + checkpointer = DetectionCheckpointer(self.model) + checkpointer.load(cfg.MODEL.WEIGHTS) + + self.aug = T.ResizeShortestEdge( + [cfg.INPUT.MIN_SIZE_TEST, cfg.INPUT.MIN_SIZE_TEST], cfg.INPUT.MAX_SIZE_TEST + ) + + self.input_format = cfg.INPUT.FORMAT + assert self.input_format in ["RGB", "BGR"], self.input_format + + def __call__(self, original_image, task): + """ + Args: + original_image (np.ndarray): an image of shape (H, W, C) (in BGR order). + Returns: + predictions (dict): + the output of the model for one image only. + See :doc:`/tutorials/models` for details about the format. + """ + with torch.no_grad(): # https://github.com/sphinx-doc/sphinx/issues/4258 + # Apply pre-processing to image. + if self.input_format == "RGB": + # whether the model expects BGR inputs or RGB + original_image = original_image[:, :, ::-1] + height, width = original_image.shape[:2] + image = self.aug.get_transform(original_image).apply_image(original_image) + image = torch.as_tensor(image.astype("float32").transpose(2, 0, 1)) + + task = f"The task is {task}" + + inputs = {"image": image, "height": height, "width": width, "task": task} + predictions = self.model([inputs])[0] + return predictions \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/demo/predictor.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/demo/predictor.py new file mode 100644 index 00000000..4b2de6c7 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/demo/predictor.py @@ -0,0 +1,190 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# Copied from: https://github.com/facebookresearch/detectron2/blob/master/demo/predictor.py +import atexit +import bisect +import multiprocessing as mp +from collections import deque + +import cv2 +import torch + +from annotator.oneformer.detectron2.data import MetadataCatalog +from defaults import DefaultPredictor +from annotator.oneformer.detectron2.utils.video_visualizer import VideoVisualizer +from visualizer import ColorMode, Visualizer + + +class VisualizationDemo(object): + def __init__(self, cfg, instance_mode=ColorMode.IMAGE, parallel=False): + """ + Args: + cfg (CfgNode): + instance_mode (ColorMode): + parallel (bool): whether to run the model in different processes from visualization. + Useful since the visualization logic can be slow. + """ + self.metadata = MetadataCatalog.get( + cfg.DATASETS.TEST[0] if len(cfg.DATASETS.TEST) else "__unused" + ) + if 'cityscapes_fine_sem_seg_val' in cfg.DATASETS.TEST[0]: + from cityscapesscripts.helpers.labels import labels + stuff_colors = [k.color for k in labels if k.trainId != 255] + self.metadata = self.metadata.set(stuff_colors=stuff_colors) + self.cpu_device = torch.device("cpu") + self.instance_mode = instance_mode + + self.parallel = parallel + if parallel: + num_gpu = torch.cuda.device_count() + self.predictor = AsyncPredictor(cfg, num_gpus=num_gpu) + else: + self.predictor = DefaultPredictor(cfg) + + def run_on_image(self, image, task, sem_gt, pan_gt, ins_gt, box_gt): + """ + Args: + image (np.ndarray): an image of shape (H, W, C) (in BGR order). + This is the format used by OpenCV. + Returns: + predictions (dict): the output of the model. + vis_output (VisImage): the visualized image output. + """ + vis_output = None + # Convert image from OpenCV BGR format to Matplotlib RGB format. + image = image[:, :, ::-1] + vis_output = {} + + if task == 'panoptic': + visualizer = Visualizer(image, metadata=self.metadata, instance_mode=0) + predictions = self.predictor(image, "panoptic") + panoptic_seg, segments_info = predictions["panoptic_seg"] + vis_output['panoptic'] = visualizer.draw_panoptic_seg_predictions( + panoptic_seg.to(self.cpu_device), segments_info, alpha=1 + ) + + # visualizer = Visualizer(image, metadata=self.metadata, instance_mode=0) + # vis_output['pan_gt'] = visualizer.draw_panoptic_seg( + # pan_gt[0].to(self.cpu_device), pan_gt[1], alpha=1 + # ) + + if task == 'panoptic' or task == 'semantic': + visualizer = Visualizer(image, metadata=self.metadata, instance_mode=1) + predictions = self.predictor(image, "semantic") + vis_output['semantic'] = visualizer.draw_sem_seg( + predictions["sem_seg"].argmax(dim=0).to(self.cpu_device), alpha=1 + ) + + # visualizer = Visualizer(image, metadata=self.metadata, instance_mode=1) + # vis_output['gt_sem'] = visualizer.draw_sem_seg( + # sem_gt.to(self.cpu_device), alpha=1 + # ) + + if task == 'panoptic' or task == 'instance': + visualizer = Visualizer(image, metadata=self.metadata, instance_mode=2) + predictions = self.predictor(image, "instance") + instances = predictions["instances"].to(self.cpu_device) + vis_output['instance'] = visualizer.draw_instance_predictions(predictions=instances, alpha=1) + + if 'boxes' in predictions: + boxes, labels, scores = predictions["boxes"] + visualizer = Visualizer(image, False, metadata=self.metadata, instance_mode=0) + vis_output['boxes'] = visualizer.draw_box_predictions( + boxes.to(self.cpu_device), labels.to(self.cpu_device), scores.to(self.cpu_device)) + + + # visualizer = Visualizer(image, metadata=self.metadata, instance_mode=2) + # vis_output['ins_gt'] = visualizer.draw_instance_predictions(predictions=ins_gt.to(self.cpu_device), alpha=1) + # vis_output['input'] = visualizer.get_image(image) + + return predictions, vis_output + + +class AsyncPredictor: + """ + A predictor that runs the model asynchronously, possibly on >1 GPUs. + Because rendering the visualization takes considerably amount of time, + this helps improve throughput a little bit when rendering videos. + """ + + class _StopToken: + pass + + class _PredictWorker(mp.Process): + def __init__(self, cfg, task_queue, result_queue): + self.cfg = cfg + self.task_queue = task_queue + self.result_queue = result_queue + super().__init__() + + def run(self): + predictor = DefaultPredictor(self.cfg) + + while True: + task = self.task_queue.get() + if isinstance(task, AsyncPredictor._StopToken): + break + idx, data = task + result = predictor(data) + self.result_queue.put((idx, result)) + + def __init__(self, cfg, num_gpus: int = 1): + """ + Args: + cfg (CfgNode): + num_gpus (int): if 0, will run on CPU + """ + num_workers = max(num_gpus, 1) + self.task_queue = mp.Queue(maxsize=num_workers * 3) + self.result_queue = mp.Queue(maxsize=num_workers * 3) + self.procs = [] + for gpuid in range(max(num_gpus, 1)): + cfg = cfg.clone() + cfg.defrost() + cfg.MODEL.DEVICE = "cuda:{}".format(gpuid) if num_gpus > 0 else "cpu" + self.procs.append( + AsyncPredictor._PredictWorker(cfg, self.task_queue, self.result_queue) + ) + + self.put_idx = 0 + self.get_idx = 0 + self.result_rank = [] + self.result_data = [] + + for p in self.procs: + p.start() + atexit.register(self.shutdown) + + def put(self, image): + self.put_idx += 1 + self.task_queue.put((self.put_idx, image)) + + def get(self): + self.get_idx += 1 # the index needed for this request + if len(self.result_rank) and self.result_rank[0] == self.get_idx: + res = self.result_data[0] + del self.result_data[0], self.result_rank[0] + return res + + while True: + # make sure the results are returned in the correct order + idx, res = self.result_queue.get() + if idx == self.get_idx: + return res + insert = bisect.bisect(self.result_rank, idx) + self.result_rank.insert(insert, idx) + self.result_data.insert(insert, res) + + def __len__(self): + return self.put_idx - self.get_idx + + def __call__(self, image): + self.put(image) + return self.get() + + def shutdown(self): + for _ in self.procs: + self.task_queue.put(AsyncPredictor._StopToken()) + + @property + def default_buffer_size(self): + return len(self.procs) * 5 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/demo/visualizer.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/demo/visualizer.py new file mode 100644 index 00000000..91246d2f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/demo/visualizer.py @@ -0,0 +1,1350 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import colorsys +import logging +import math +import numpy as np +from enum import Enum, unique +import cv2 +import matplotlib as mpl +import matplotlib.colors as mplc +import matplotlib.figure as mplfigure +import annotator.oneformer.pycocotools.mask as mask_util +import torch +from matplotlib.backends.backend_agg import FigureCanvasAgg +from PIL import Image + +from annotator.oneformer.detectron2.data import MetadataCatalog +from annotator.oneformer.detectron2.structures import BitMasks, Boxes, BoxMode, Keypoints, PolygonMasks, RotatedBoxes +from annotator.oneformer.detectron2.utils.file_io import PathManager +import random +random.seed(0) +from .colormap import random_color, _COLORS +logger = logging.getLogger(__name__) + +__all__ = ["ColorMode", "VisImage", "Visualizer"] + + +_SMALL_OBJECT_AREA_THRESH = 1000 +_LARGE_MASK_AREA_THRESH = 120000 +_OFF_WHITE = (1.0, 1.0, 1.0) +_BLACK = (0, 0, 0) +_RED = (1.0, 0, 0) + +_KEYPOINT_THRESHOLD = 0.05 + + +def instance_color(rgb=False, idx=1, maximum=255): + """ + Args: + rgb (bool): whether to return RGB colors or BGR colors. + maximum (int): either 255 or 1 + Returns: + ndarray: a vector of 3 numbers + """ + ret = _COLORS[idx] * maximum + if not rgb: + ret = ret[::-1] + return ret + +@unique +class ColorMode(Enum): + """ + Enum of different color modes to use for instance visualizations. + """ + + IMAGE = 0 + """ + Picks a random color for every instance and overlay segmentations with low opacity. + """ + SEGMENTATION = 1 + """ + Let instances of the same category have similar colors + (from metadata.thing_colors), and overlay them with + high opacity. This provides more attention on the quality of segmentation. + """ + IMAGE_BW = 2 + """ + Same as IMAGE, but convert all areas without masks to gray-scale. + Only available for drawing per-instance mask predictions. + """ + + +class GenericMask: + """ + Attribute: + polygons (list[ndarray]): list[ndarray]: polygons for this mask. + Each ndarray has format [x, y, x, y, ...] + mask (ndarray): a binary mask + """ + + def __init__(self, mask_or_polygons, height, width): + self._mask = self._polygons = self._has_holes = None + self.height = height + self.width = width + + m = mask_or_polygons + if isinstance(m, dict): + # RLEs + assert "counts" in m and "size" in m + if isinstance(m["counts"], list): # uncompressed RLEs + h, w = m["size"] + assert h == height and w == width + m = mask_util.frPyObjects(m, h, w) + self._mask = mask_util.decode(m)[:, :] + return + + if isinstance(m, list): # list[ndarray] + self._polygons = [np.asarray(x).reshape(-1) for x in m] + return + + if isinstance(m, np.ndarray): # assumed to be a binary mask + assert m.shape[1] != 2, m.shape + assert m.shape == ( + height, + width, + ), f"mask shape: {m.shape}, target dims: {height}, {width}" + self._mask = m.astype("uint8") + return + + raise ValueError("GenericMask cannot handle object {} of type '{}'".format(m, type(m))) + + @property + def mask(self): + if self._mask is None: + self._mask = self.polygons_to_mask(self._polygons) + return self._mask + + @property + def polygons(self): + if self._polygons is None: + self._polygons, self._has_holes = self.mask_to_polygons(self._mask) + return self._polygons + + @property + def has_holes(self): + if self._has_holes is None: + if self._mask is not None: + self._polygons, self._has_holes = self.mask_to_polygons(self._mask) + else: + self._has_holes = False # if original format is polygon, does not have holes + return self._has_holes + + def mask_to_polygons(self, mask): + # cv2.RETR_CCOMP flag retrieves all the contours and arranges them to a 2-level + # hierarchy. External contours (boundary) of the object are placed in hierarchy-1. + # Internal contours (holes) are placed in hierarchy-2. + # cv2.CHAIN_APPROX_NONE flag gets vertices of polygons from contours. + mask = np.ascontiguousarray(mask) # some versions of cv2 does not support incontiguous arr + res = cv2.findContours(mask.astype("uint8"), cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE) + hierarchy = res[-1] + if hierarchy is None: # empty mask + return [], False + has_holes = (hierarchy.reshape(-1, 4)[:, 3] >= 0).sum() > 0 + res = res[-2] + res = [x.flatten() for x in res] + # These coordinates from OpenCV are integers in range [0, W-1 or H-1]. + # We add 0.5 to turn them into real-value coordinate space. A better solution + # would be to first +0.5 and then dilate the returned polygon by 0.5. + res = [x + 0.5 for x in res if len(x) >= 6] + return res, has_holes + + def polygons_to_mask(self, polygons): + rle = mask_util.frPyObjects(polygons, self.height, self.width) + rle = mask_util.merge(rle) + return mask_util.decode(rle)[:, :] + + def area(self): + return self.mask.sum() + + def bbox(self): + p = mask_util.frPyObjects(self.polygons, self.height, self.width) + p = mask_util.merge(p) + bbox = mask_util.toBbox(p) + bbox[2] += bbox[0] + bbox[3] += bbox[1] + return bbox + + +class _PanopticPrediction: + """ + Unify different panoptic annotation/prediction formats + """ + + def __init__(self, panoptic_seg, segments_info, metadata=None): + if segments_info is None: + assert metadata is not None + # If "segments_info" is None, we assume "panoptic_img" is a + # H*W int32 image storing the panoptic_id in the format of + # category_id * label_divisor + instance_id. We reserve -1 for + # VOID label. + label_divisor = metadata.label_divisor + segments_info = [] + for panoptic_label in np.unique(panoptic_seg.numpy()): + if panoptic_label == -1: + # VOID region. + continue + pred_class = panoptic_label // label_divisor + isthing = pred_class in metadata.thing_dataset_id_to_contiguous_id.values() + segments_info.append( + { + "id": int(panoptic_label), + "category_id": int(pred_class), + "isthing": bool(isthing), + } + ) + del metadata + + self._seg = panoptic_seg + + self._sinfo = {s["id"]: s for s in segments_info} # seg id -> seg info + segment_ids, areas = torch.unique(panoptic_seg, sorted=True, return_counts=True) + areas = areas.numpy() + sorted_idxs = np.argsort(-areas) + self._seg_ids, self._seg_areas = segment_ids[sorted_idxs], areas[sorted_idxs] + self._seg_ids = self._seg_ids.tolist() + for sid, area in zip(self._seg_ids, self._seg_areas): + if sid in self._sinfo: + self._sinfo[sid]["area"] = float(area) + + def non_empty_mask(self): + """ + Returns: + (H, W) array, a mask for all pixels that have a prediction + """ + empty_ids = [] + for id in self._seg_ids: + if id not in self._sinfo: + empty_ids.append(id) + if len(empty_ids) == 0: + return np.zeros(self._seg.shape, dtype=np.uint8) + assert ( + len(empty_ids) == 1 + ), ">1 ids corresponds to no labels. This is currently not supported" + return (self._seg != empty_ids[0]).numpy().astype(np.bool) + + def semantic_masks(self): + for sid in self._seg_ids: + sinfo = self._sinfo.get(sid) + if sinfo is None or sinfo["isthing"]: + # Some pixels (e.g. id 0 in PanopticFPN) have no instance or semantic predictions. + continue + yield (self._seg == sid).numpy().astype(np.bool), sinfo + + def instance_masks(self): + for sid in self._seg_ids: + sinfo = self._sinfo.get(sid) + if sinfo is None or not sinfo["isthing"]: + continue + mask = (self._seg == sid).numpy().astype(np.bool) + if mask.sum() > 0: + yield mask, sinfo + + +def _create_text_labels(classes, scores, class_names, is_crowd=None): + """ + Args: + classes (list[int] or None): + scores (list[float] or None): + class_names (list[str] or None): + is_crowd (list[bool] or None): + Returns: + list[str] or None + """ + labels = None + if classes is not None: + if class_names is not None and len(class_names) > 0: + labels = [class_names[i] for i in classes] + else: + labels = [str(i) for i in classes] + if scores is not None: + if labels is None: + labels = ["{:.0f}%".format(s * 100) for s in scores] + else: + labels = ["{} {:.0f}%".format(l, s * 100) for l, s in zip(labels, scores)] + if labels is not None and is_crowd is not None: + labels = [l + ("|crowd" if crowd else "") for l, crowd in zip(labels, is_crowd)] + return labels + + +class VisImage: + def __init__(self, img, scale=1.0): + """ + Args: + img (ndarray): an RGB image of shape (H, W, 3) in range [0, 255]. + scale (float): scale the input image + """ + self.img = img + self.scale = scale + self.width, self.height = img.shape[1], img.shape[0] + self._setup_figure(img) + + def _setup_figure(self, img): + """ + Args: + Same as in :meth:`__init__()`. + Returns: + fig (matplotlib.pyplot.figure): top level container for all the image plot elements. + ax (matplotlib.pyplot.Axes): contains figure elements and sets the coordinate system. + """ + fig = mplfigure.Figure(frameon=False) + self.dpi = fig.get_dpi() + # add a small 1e-2 to avoid precision lost due to matplotlib's truncation + # (https://github.com/matplotlib/matplotlib/issues/15363) + fig.set_size_inches( + (self.width * self.scale + 1e-2) / self.dpi, + (self.height * self.scale + 1e-2) / self.dpi, + ) + self.canvas = FigureCanvasAgg(fig) + # self.canvas = mpl.backends.backend_cairo.FigureCanvasCairo(fig) + ax = fig.add_axes([0.0, 0.0, 1.0, 1.0]) + ax.axis("off") + self.fig = fig + self.ax = ax + self.reset_image(img) + + def reset_image(self, img): + """ + Args: + img: same as in __init__ + """ + img = img.astype("uint8") + self.ax.imshow(img, extent=(0, self.width, self.height, 0), interpolation="nearest") + + def save(self, filepath): + """ + Args: + filepath (str): a string that contains the absolute path, including the file name, where + the visualized image will be saved. + """ + self.fig.savefig(filepath) + + def get_image(self): + """ + Returns: + ndarray: + the visualized image of shape (H, W, 3) (RGB) in uint8 type. + The shape is scaled w.r.t the input image using the given `scale` argument. + """ + canvas = self.canvas + s, (width, height) = canvas.print_to_buffer() + # buf = io.BytesIO() # works for cairo backend + # canvas.print_rgba(buf) + # width, height = self.width, self.height + # s = buf.getvalue() + + buffer = np.frombuffer(s, dtype="uint8") + + img_rgba = buffer.reshape(height, width, 4) + rgb, alpha = np.split(img_rgba, [3], axis=2) + return rgb.astype("uint8") + + +class Visualizer: + """ + Visualizer that draws data about detection/segmentation on images. + It contains methods like `draw_{text,box,circle,line,binary_mask,polygon}` + that draw primitive objects to images, as well as high-level wrappers like + `draw_{instance_predictions,sem_seg,panoptic_seg_predictions,dataset_dict}` + that draw composite data in some pre-defined style. + Note that the exact visualization style for the high-level wrappers are subject to change. + Style such as color, opacity, label contents, visibility of labels, or even the visibility + of objects themselves (e.g. when the object is too small) may change according + to different heuristics, as long as the results still look visually reasonable. + To obtain a consistent style, you can implement custom drawing functions with the + abovementioned primitive methods instead. If you need more customized visualization + styles, you can process the data yourself following their format documented in + tutorials (:doc:`/tutorials/models`, :doc:`/tutorials/datasets`). This class does not + intend to satisfy everyone's preference on drawing styles. + This visualizer focuses on high rendering quality rather than performance. It is not + designed to be used for real-time applications. + """ + + # TODO implement a fast, rasterized version using OpenCV + + def __init__(self, img_rgb, is_img=True, metadata=None, scale=1.0, instance_mode=ColorMode.IMAGE): + """ + Args: + img_rgb: a numpy array of shape (H, W, C), where H and W correspond to + the height and width of the image respectively. C is the number of + color channels. The image is required to be in RGB format since that + is a requirement of the Matplotlib library. The image is also expected + to be in the range [0, 255]. + metadata (Metadata): dataset metadata (e.g. class names and colors) + instance_mode (ColorMode): defines one of the pre-defined style for drawing + instances on an image. + """ + if is_img: + self.img = np.asarray(img_rgb).clip(0, 255).astype(np.uint8) + else: + self.img = np.zeros_like(img_rgb).clip(0, 255).astype(np.uint8) + 255 + if metadata is None: + metadata = MetadataCatalog.get("__nonexist__") + self.metadata = metadata + self.output = VisImage(self.img, scale=scale) + self.cpu_device = torch.device("cpu") + + # too small texts are useless, therefore clamp to 9 + self._default_font_size = max( + np.sqrt(self.output.height * self.output.width) // 90, 10 // scale + ) + self._instance_mode = instance_mode + self.keypoint_threshold = _KEYPOINT_THRESHOLD + + def get_image(self, img): + img = np.asarray(img).clip(0, 255).astype(np.uint8) + return VisImage(img, scale=1.0) + + def draw_box_predictions( + self, + boxes=None, + labels=None, + scores=None, + assigned_colors=None + ): + """ + Args: + boxes (Boxes, RotatedBoxes or ndarray): either a :class:`Boxes`, + or an Nx4 numpy array of XYXY_ABS format for the N objects in a single image, + or a :class:`RotatedBoxes`, + or an Nx5 numpy array of (x_center, y_center, width, height, angle_degrees) format + for the N objects in a single image, + labels (list[str]): the text to be displayed for each instance. + assigned_colors (list[matplotlib.colors]): a list of colors, where each color + corresponds to each mask or box in the image. Refer to 'matplotlib.colors' + for full list of formats that the colors are accepted in. + Returns: + output (VisImage): image object with visualizations. + """ + num_instances = 0 + boxes = self._convert_boxes(boxes) + classes = labels.tolist() + scores = scores.tolist() + labels = _create_text_labels(classes, scores, self.metadata.get("stuff_classes", None)) + num_instances = len(boxes) + assert len(labels) == num_instances + if assigned_colors is None: + # assigned_colors = [random_color(rgb=True, maximum=1) for _ in range(num_instances)] + assigned_colors = [instance_color(rgb=True, idx=i, maximum=1) for i in range(num_instances)] + if num_instances == 0: + return self.output + + # Display in largest to smallest order to reduce occlusion. + areas = None + areas = np.prod(boxes[:, 2:] - boxes[:, :2], axis=1) + + if areas is not None: + sorted_idxs = np.argsort(-areas).tolist() + # Re-order overlapped instances in descending order. + boxes = boxes[sorted_idxs] if boxes is not None else None + labels = [labels[k] for k in sorted_idxs] if labels is not None else None + assigned_colors = [assigned_colors[idx] for idx in sorted_idxs] + + for i in range(num_instances): + color = assigned_colors[i] + if boxes is not None: + self.draw_box(boxes[i], edge_color=color) + + if labels is not None: + # first get a box + if boxes is not None: + x0, y0, x1, y1 = boxes[i] + text_pos = (x0, y0) # if drawing boxes, put text on the box corner. + horiz_align = "left" + else: + continue # drawing the box confidence for keypoints isn't very useful. + # for small objects, draw text at the side to avoid occlusion + instance_area = (y1 - y0) * (x1 - x0) + if ( + instance_area < _SMALL_OBJECT_AREA_THRESH * self.output.scale + or y1 - y0 < 40 * self.output.scale + ): + if y1 >= self.output.height - 5: + text_pos = (x1, y0) + else: + text_pos = (x0, y1) + + height_ratio = (y1 - y0) / np.sqrt(self.output.height * self.output.width) + lighter_color = self._change_color_brightness(color, brightness_factor=0.7) + font_size = ( + np.clip((height_ratio - 0.02) / 0.08 + 1, 1.2, 2) + * 0.5 + * self._default_font_size + ) + self.draw_text( + labels[i], + text_pos, + color=lighter_color, + horizontal_alignment=horiz_align, + font_size=font_size, + ) + + return self.output + + + def draw_instance_predictions(self, predictions, alpha=0.8, is_text=True): + """ + Draw instance-level prediction results on an image. + Args: + predictions (Instances): the output of an instance detection/segmentation + model. Following fields will be used to draw: + "pred_boxes", "pred_classes", "scores", "pred_masks" (or "pred_masks_rle"). + Returns: + output (VisImage): image object with visualizations. + """ + boxes = predictions.pred_boxes if predictions.has("pred_boxes") else None + scores = predictions.scores if predictions.has("scores") else None + classes = predictions.pred_classes.tolist() if predictions.has("pred_classes") else None + labels = _create_text_labels(classes, scores, self.metadata.get("stuff_classes", None)) + keypoints = predictions.pred_keypoints if predictions.has("pred_keypoints") else None + + if predictions.has("pred_masks"): + masks = np.asarray(predictions.pred_masks) + masks = [GenericMask(x, self.output.height, self.output.width) for x in masks] + else: + masks = None + + if self._instance_mode == ColorMode.SEGMENTATION and self.metadata.get("stuff_colors"): + # colors = [ + # self._jitter([x / 255 for x in self.metadata.thing_colors[c]]) for c in classes + # ] + colors = [ + instance_color(rgb=True, idx=c, maximum=1) for c in classes + ] + else: + colors = None + + if self._instance_mode == ColorMode.IMAGE_BW: + self.output.reset_image( + self._create_grayscale_image( + (predictions.pred_masks.any(dim=0) > 0).numpy() + if predictions.has("pred_masks") + else None + ) + ) + + self.overlay_instances( + masks=masks, + boxes=boxes, + labels=labels, + keypoints=keypoints, + assigned_colors=colors, + alpha=alpha, + is_text=is_text, + ) + return self.output + + def draw_sem_seg(self, sem_seg, area_threshold=None, alpha=0.8, is_text=True, edge_color=_OFF_WHITE): + """ + Draw semantic segmentation predictions/labels. + Args: + sem_seg (Tensor or ndarray): the segmentation of shape (H, W). + Each value is the integer label of the pixel. + area_threshold (int): segments with less than `area_threshold` are not drawn. + alpha (float): the larger it is, the more opaque the segmentations are. + Returns: + output (VisImage): image object with visualizations. + """ + if isinstance(sem_seg, torch.Tensor): + sem_seg = sem_seg.numpy() + labels, areas = np.unique(sem_seg, return_counts=True) + sorted_idxs = np.argsort(-areas).tolist() + labels = labels[sorted_idxs] + for label in filter(lambda l: l < len(self.metadata.stuff_classes), labels): + try: + mask_color = [x / 255 for x in self.metadata.stuff_colors[label]] + except (AttributeError, IndexError): + mask_color = None + + binary_mask = (sem_seg == label).astype(np.uint8) + text = self.metadata.stuff_classes[label] + self.draw_binary_mask( + binary_mask, + color=mask_color, + edge_color=edge_color, + text=text, + alpha=alpha, + area_threshold=area_threshold, + is_text=is_text, + ) + return self.output + + def draw_panoptic_seg(self, panoptic_seg, segments_info, area_threshold=None, alpha=0.7, is_text=True,): + """ + Draw panoptic prediction annotations or results. + Args: + panoptic_seg (Tensor): of shape (height, width) where the values are ids for each + segment. + segments_info (list[dict] or None): Describe each segment in `panoptic_seg`. + If it is a ``list[dict]``, each dict contains keys "id", "category_id". + If None, category id of each pixel is computed by + ``pixel // metadata.label_divisor``. + area_threshold (int): stuff segments with less than `area_threshold` are not drawn. + Returns: + output (VisImage): image object with visualizations. + """ + pred = _PanopticPrediction(panoptic_seg, segments_info, self.metadata) + + if self._instance_mode == ColorMode.IMAGE_BW: + self.output.reset_image(self._create_grayscale_image(pred.non_empty_mask())) + + # draw mask for all semantic segments first i.e. "stuff" + for mask, sinfo in pred.semantic_masks(): + category_idx = sinfo["category_id"] + try: + mask_color = [x / 255 for x in self.metadata.stuff_colors[category_idx]] + except AttributeError: + mask_color = None + + text = self.metadata.stuff_classes[category_idx] + self.draw_binary_mask( + mask, + color=mask_color, + edge_color=_OFF_WHITE, + text=text, + alpha=alpha, + area_threshold=area_threshold, + is_text=is_text, + ) + + # draw mask for all instances second + all_instances = list(pred.instance_masks()) + if len(all_instances) == 0: + return self.output + masks, sinfo = list(zip(*all_instances)) + category_ids = [x["category_id"] for x in sinfo] + + try: + scores = [x["score"] for x in sinfo] + except KeyError: + scores = None + labels = _create_text_labels( + category_ids, scores, self.metadata.stuff_classes, [x.get("iscrowd", 0) for x in sinfo] + ) + + try: + colors = [ + self._jitter([x / 255 for x in self.metadata.stuff_colors[c]]) for c in category_ids + ] + except AttributeError: + colors = None + self.overlay_instances(masks=masks, labels=labels, assigned_colors=colors, alpha=alpha, is_text=is_text) + + return self.output + + draw_panoptic_seg_predictions = draw_panoptic_seg # backward compatibility + + def draw_dataset_dict(self, dic): + """ + Draw annotations/segmentaions in Detectron2 Dataset format. + Args: + dic (dict): annotation/segmentation data of one image, in Detectron2 Dataset format. + Returns: + output (VisImage): image object with visualizations. + """ + annos = dic.get("annotations", None) + if annos: + if "segmentation" in annos[0]: + masks = [x["segmentation"] for x in annos] + else: + masks = None + if "keypoints" in annos[0]: + keypts = [x["keypoints"] for x in annos] + keypts = np.array(keypts).reshape(len(annos), -1, 3) + else: + keypts = None + + boxes = [ + BoxMode.convert(x["bbox"], x["bbox_mode"], BoxMode.XYXY_ABS) + if len(x["bbox"]) == 4 + else x["bbox"] + for x in annos + ] + + colors = None + category_ids = [x["category_id"] for x in annos] + if self._instance_mode == ColorMode.SEGMENTATION and self.metadata.get("stuff_colors"): + colors = [ + self._jitter([x / 255 for x in self.metadata.stuff_colors[c]]) + for c in category_ids + ] + names = self.metadata.get("stuff_classes", None) + labels = _create_text_labels( + category_ids, + scores=None, + class_names=names, + is_crowd=[x.get("iscrowd", 0) for x in annos], + ) + self.overlay_instances( + labels=labels, boxes=boxes, masks=masks, keypoints=keypts, assigned_colors=colors + ) + + sem_seg = dic.get("sem_seg", None) + if sem_seg is None and "sem_seg_file_name" in dic: + with PathManager.open(dic["sem_seg_file_name"], "rb") as f: + sem_seg = Image.open(f) + sem_seg = np.asarray(sem_seg, dtype="uint8") + if sem_seg is not None: + self.draw_sem_seg(sem_seg, area_threshold=0, alpha=0.5) + + pan_seg = dic.get("pan_seg", None) + # if pan_seg is None and "pan_seg_file_name" in dic: + # with PathManager.open(dic["pan_seg_file_name"], "rb") as f: + # pan_seg = Image.open(f) + # pan_seg = np.asarray(pan_seg) + # from panopticapi.utils import rgb2id + # + # pan_seg = rgb2id(pan_seg) + if pan_seg is not None: + segments_info = dic["segments_info"] + pan_seg = torch.tensor(pan_seg) + self.draw_panoptic_seg(pan_seg, segments_info, area_threshold=0, alpha=0.5) + return self.output + + def overlay_instances( + self, + *, + boxes=None, + labels=None, + masks=None, + keypoints=None, + assigned_colors=None, + alpha=0.5, + is_text=True, + ): + """ + Args: + boxes (Boxes, RotatedBoxes or ndarray): either a :class:`Boxes`, + or an Nx4 numpy array of XYXY_ABS format for the N objects in a single image, + or a :class:`RotatedBoxes`, + or an Nx5 numpy array of (x_center, y_center, width, height, angle_degrees) format + for the N objects in a single image, + labels (list[str]): the text to be displayed for each instance. + masks (masks-like object): Supported types are: + * :class:`detectron2.structures.PolygonMasks`, + :class:`detectron2.structures.BitMasks`. + * list[list[ndarray]]: contains the segmentation masks for all objects in one image. + The first level of the list corresponds to individual instances. The second + level to all the polygon that compose the instance, and the third level + to the polygon coordinates. The third level should have the format of + [x0, y0, x1, y1, ..., xn, yn] (n >= 3). + * list[ndarray]: each ndarray is a binary mask of shape (H, W). + * list[dict]: each dict is a COCO-style RLE. + keypoints (Keypoint or array like): an array-like object of shape (N, K, 3), + where the N is the number of instances and K is the number of keypoints. + The last dimension corresponds to (x, y, visibility or score). + assigned_colors (list[matplotlib.colors]): a list of colors, where each color + corresponds to each mask or box in the image. Refer to 'matplotlib.colors' + for full list of formats that the colors are accepted in. + Returns: + output (VisImage): image object with visualizations. + """ + num_instances = 0 + if boxes is not None: + boxes = self._convert_boxes(boxes) + num_instances = len(boxes) + if masks is not None: + masks = self._convert_masks(masks) + if num_instances: + assert len(masks) == num_instances + else: + num_instances = len(masks) + if keypoints is not None: + if num_instances: + assert len(keypoints) == num_instances + else: + num_instances = len(keypoints) + keypoints = self._convert_keypoints(keypoints) + if labels is not None: + assert len(labels) == num_instances + if assigned_colors is None: + # assigned_colors = [random_color(rgb=True, maximum=1) for _ in range(num_instances)] + assigned_colors = [instance_color(rgb=True, idx=i, maximum=1) for i in range(num_instances)] + if num_instances == 0: + return self.output + if boxes is not None and boxes.shape[1] == 5: + return self.overlay_rotated_instances( + boxes=boxes, labels=labels, assigned_colors=assigned_colors + ) + + # Display in largest to smallest order to reduce occlusion. + areas = None + if boxes is not None: + areas = np.prod(boxes[:, 2:] - boxes[:, :2], axis=1) + elif masks is not None: + areas = np.asarray([x.area() for x in masks]) + + if areas is not None: + sorted_idxs = np.argsort(-areas).tolist() + # Re-order overlapped instances in descending order. + boxes = boxes[sorted_idxs] if boxes is not None else None + labels = [labels[k] for k in sorted_idxs] if labels is not None else None + masks = [masks[idx] for idx in sorted_idxs] if masks is not None else None + assigned_colors = [assigned_colors[idx] for idx in sorted_idxs] + keypoints = keypoints[sorted_idxs] if keypoints is not None else None + + for i in range(num_instances): + color = assigned_colors[i] + if boxes is not None: + self.draw_box(boxes[i], edge_color=color) + + if masks is not None: + for segment in masks[i].polygons: + self.draw_polygon(segment.reshape(-1, 2), color, alpha=alpha) + + if labels is not None: + # first get a box + if boxes is not None: + x0, y0, x1, y1 = boxes[i] + text_pos = (x0, y0) # if drawing boxes, put text on the box corner. + horiz_align = "left" + elif masks is not None: + # skip small mask without polygon + if len(masks[i].polygons) == 0: + continue + + x0, y0, x1, y1 = masks[i].bbox() + + # draw text in the center (defined by median) when box is not drawn + # median is less sensitive to outliers. + text_pos = np.median(masks[i].mask.nonzero(), axis=1)[::-1] + horiz_align = "center" + else: + continue # drawing the box confidence for keypoints isn't very useful. + # for small objects, draw text at the side to avoid occlusion + instance_area = (y1 - y0) * (x1 - x0) + if ( + instance_area < _SMALL_OBJECT_AREA_THRESH * self.output.scale + or y1 - y0 < 40 * self.output.scale + ): + if y1 >= self.output.height - 5: + text_pos = (x1, y0) + else: + text_pos = (x0, y1) + + height_ratio = (y1 - y0) / np.sqrt(self.output.height * self.output.width) + lighter_color = self._change_color_brightness(color, brightness_factor=0.7) + font_size = ( + np.clip((height_ratio - 0.02) / 0.08 + 1, 1.2, 2) + * 0.5 + * self._default_font_size + ) + if is_text: + self.draw_text( + labels[i], + text_pos, + color=lighter_color, + horizontal_alignment=horiz_align, + font_size=font_size, + ) + + # draw keypoints + if keypoints is not None: + for keypoints_per_instance in keypoints: + self.draw_and_connect_keypoints(keypoints_per_instance) + + return self.output + + def overlay_rotated_instances(self, boxes=None, labels=None, assigned_colors=None): + """ + Args: + boxes (ndarray): an Nx5 numpy array of + (x_center, y_center, width, height, angle_degrees) format + for the N objects in a single image. + labels (list[str]): the text to be displayed for each instance. + assigned_colors (list[matplotlib.colors]): a list of colors, where each color + corresponds to each mask or box in the image. Refer to 'matplotlib.colors' + for full list of formats that the colors are accepted in. + Returns: + output (VisImage): image object with visualizations. + """ + num_instances = len(boxes) + + if assigned_colors is None: + # assigned_colors = [random_color(rgb=True, maximum=1) for _ in range(num_instances)] + assigned_colors = [instance_color(rgb=True, idx=i, maximum=1) for i in range(num_instances)] + if num_instances == 0: + return self.output + + # Display in largest to smallest order to reduce occlusion. + if boxes is not None: + areas = boxes[:, 2] * boxes[:, 3] + + sorted_idxs = np.argsort(-areas).tolist() + # Re-order overlapped instances in descending order. + boxes = boxes[sorted_idxs] + labels = [labels[k] for k in sorted_idxs] if labels is not None else None + colors = [assigned_colors[idx] for idx in sorted_idxs] + + for i in range(num_instances): + self.draw_rotated_box_with_label( + boxes[i], edge_color=colors[i], label=labels[i] if labels is not None else None + ) + + return self.output + + def draw_and_connect_keypoints(self, keypoints): + """ + Draws keypoints of an instance and follows the rules for keypoint connections + to draw lines between appropriate keypoints. This follows color heuristics for + line color. + Args: + keypoints (Tensor): a tensor of shape (K, 3), where K is the number of keypoints + and the last dimension corresponds to (x, y, probability). + Returns: + output (VisImage): image object with visualizations. + """ + visible = {} + keypoint_names = self.metadata.get("keypoint_names") + for idx, keypoint in enumerate(keypoints): + + # draw keypoint + x, y, prob = keypoint + if prob > self.keypoint_threshold: + self.draw_circle((x, y), color=_RED) + if keypoint_names: + keypoint_name = keypoint_names[idx] + visible[keypoint_name] = (x, y) + + if self.metadata.get("keypoint_connection_rules"): + for kp0, kp1, color in self.metadata.keypoint_connection_rules: + if kp0 in visible and kp1 in visible: + x0, y0 = visible[kp0] + x1, y1 = visible[kp1] + color = tuple(x / 255.0 for x in color) + self.draw_line([x0, x1], [y0, y1], color=color) + + # draw lines from nose to mid-shoulder and mid-shoulder to mid-hip + # Note that this strategy is specific to person keypoints. + # For other keypoints, it should just do nothing + try: + ls_x, ls_y = visible["left_shoulder"] + rs_x, rs_y = visible["right_shoulder"] + mid_shoulder_x, mid_shoulder_y = (ls_x + rs_x) / 2, (ls_y + rs_y) / 2 + except KeyError: + pass + else: + # draw line from nose to mid-shoulder + nose_x, nose_y = visible.get("nose", (None, None)) + if nose_x is not None: + self.draw_line([nose_x, mid_shoulder_x], [nose_y, mid_shoulder_y], color=_RED) + + try: + # draw line from mid-shoulder to mid-hip + lh_x, lh_y = visible["left_hip"] + rh_x, rh_y = visible["right_hip"] + except KeyError: + pass + else: + mid_hip_x, mid_hip_y = (lh_x + rh_x) / 2, (lh_y + rh_y) / 2 + self.draw_line([mid_hip_x, mid_shoulder_x], [mid_hip_y, mid_shoulder_y], color=_RED) + return self.output + + """ + Primitive drawing functions: + """ + + def draw_text( + self, + text, + position, + *, + font_size=None, + color="g", + horizontal_alignment="center", + rotation=0, + ): + """ + Args: + text (str): class label + position (tuple): a tuple of the x and y coordinates to place text on image. + font_size (int, optional): font of the text. If not provided, a font size + proportional to the image width is calculated and used. + color: color of the text. Refer to `matplotlib.colors` for full list + of formats that are accepted. + horizontal_alignment (str): see `matplotlib.text.Text` + rotation: rotation angle in degrees CCW + Returns: + output (VisImage): image object with text drawn. + """ + if not font_size: + font_size = self._default_font_size + + # since the text background is dark, we don't want the text to be dark + color = np.maximum(list(mplc.to_rgb(color)), 0.2) + color[np.argmax(color)] = max(0.8, np.max(color)) + + x, y = position + self.output.ax.text( + x, + y, + text, + size=font_size * self.output.scale, + family="sans-serif", + bbox={"facecolor": "black", "alpha": 0.8, "pad": 0.7, "edgecolor": "none"}, + verticalalignment="top", + horizontalalignment=horizontal_alignment, + color=color, + zorder=10, + rotation=rotation, + ) + return self.output + + def draw_box(self, box_coord, alpha=1.0, edge_color="g", line_style="-"): + """ + Args: + box_coord (tuple): a tuple containing x0, y0, x1, y1 coordinates, where x0 and y0 + are the coordinates of the image's top left corner. x1 and y1 are the + coordinates of the image's bottom right corner. + alpha (float): blending efficient. Smaller values lead to more transparent masks. + edge_color: color of the outline of the box. Refer to `matplotlib.colors` + for full list of formats that are accepted. + line_style (string): the string to use to create the outline of the boxes. + Returns: + output (VisImage): image object with box drawn. + """ + x0, y0, x1, y1 = box_coord + width = x1 - x0 + height = y1 - y0 + + linewidth = 2 + + self.output.ax.add_patch( + mpl.patches.Rectangle( + (x0, y0), + width, + height, + fill=False, + edgecolor=edge_color, + linewidth=linewidth * self.output.scale, + alpha=alpha, + linestyle=line_style, + ) + ) + return self.output + + def draw_rotated_box_with_label( + self, rotated_box, alpha=0.5, edge_color="g", line_style="-", label=None + ): + """ + Draw a rotated box with label on its top-left corner. + Args: + rotated_box (tuple): a tuple containing (cnt_x, cnt_y, w, h, angle), + where cnt_x and cnt_y are the center coordinates of the box. + w and h are the width and height of the box. angle represents how + many degrees the box is rotated CCW with regard to the 0-degree box. + alpha (float): blending efficient. Smaller values lead to more transparent masks. + edge_color: color of the outline of the box. Refer to `matplotlib.colors` + for full list of formats that are accepted. + line_style (string): the string to use to create the outline of the boxes. + label (string): label for rotated box. It will not be rendered when set to None. + Returns: + output (VisImage): image object with box drawn. + """ + cnt_x, cnt_y, w, h, angle = rotated_box + area = w * h + # use thinner lines when the box is small + linewidth = self._default_font_size / ( + 6 if area < _SMALL_OBJECT_AREA_THRESH * self.output.scale else 3 + ) + + theta = angle * math.pi / 180.0 + c = math.cos(theta) + s = math.sin(theta) + rect = [(-w / 2, h / 2), (-w / 2, -h / 2), (w / 2, -h / 2), (w / 2, h / 2)] + # x: left->right ; y: top->down + rotated_rect = [(s * yy + c * xx + cnt_x, c * yy - s * xx + cnt_y) for (xx, yy) in rect] + for k in range(4): + j = (k + 1) % 4 + self.draw_line( + [rotated_rect[k][0], rotated_rect[j][0]], + [rotated_rect[k][1], rotated_rect[j][1]], + color=edge_color, + linestyle="--" if k == 1 else line_style, + linewidth=linewidth, + ) + + if label is not None: + text_pos = rotated_rect[1] # topleft corner + + height_ratio = h / np.sqrt(self.output.height * self.output.width) + label_color = self._change_color_brightness(edge_color, brightness_factor=0.7) + font_size = ( + np.clip((height_ratio - 0.02) / 0.08 + 1, 1.2, 2) * 0.5 * self._default_font_size + ) + self.draw_text(label, text_pos, color=label_color, font_size=font_size, rotation=angle) + + return self.output + + def draw_circle(self, circle_coord, color, radius=3): + """ + Args: + circle_coord (list(int) or tuple(int)): contains the x and y coordinates + of the center of the circle. + color: color of the polygon. Refer to `matplotlib.colors` for a full list of + formats that are accepted. + radius (int): radius of the circle. + Returns: + output (VisImage): image object with box drawn. + """ + x, y = circle_coord + self.output.ax.add_patch( + mpl.patches.Circle(circle_coord, radius=radius, fill=True, color=color) + ) + return self.output + + def draw_line(self, x_data, y_data, color, linestyle="-", linewidth=None): + """ + Args: + x_data (list[int]): a list containing x values of all the points being drawn. + Length of list should match the length of y_data. + y_data (list[int]): a list containing y values of all the points being drawn. + Length of list should match the length of x_data. + color: color of the line. Refer to `matplotlib.colors` for a full list of + formats that are accepted. + linestyle: style of the line. Refer to `matplotlib.lines.Line2D` + for a full list of formats that are accepted. + linewidth (float or None): width of the line. When it's None, + a default value will be computed and used. + Returns: + output (VisImage): image object with line drawn. + """ + if linewidth is None: + linewidth = self._default_font_size / 3 + linewidth = max(linewidth, 1) + self.output.ax.add_line( + mpl.lines.Line2D( + x_data, + y_data, + linewidth=linewidth * self.output.scale, + color=color, + linestyle=linestyle, + ) + ) + return self.output + + def draw_binary_mask( + self, binary_mask, color=None, *, edge_color=None, text=None, alpha=0.5, area_threshold=10, is_text=True, + ): + """ + Args: + binary_mask (ndarray): numpy array of shape (H, W), where H is the image height and + W is the image width. Each value in the array is either a 0 or 1 value of uint8 + type. + color: color of the mask. Refer to `matplotlib.colors` for a full list of + formats that are accepted. If None, will pick a random color. + edge_color: color of the polygon edges. Refer to `matplotlib.colors` for a + full list of formats that are accepted. + text (str): if None, will be drawn on the object + alpha (float): blending efficient. Smaller values lead to more transparent masks. + area_threshold (float): a connected component smaller than this area will not be shown. + Returns: + output (VisImage): image object with mask drawn. + """ + if color is None: + color = random_color(rgb=True, maximum=1) + color = mplc.to_rgb(color) + + has_valid_segment = False + binary_mask = binary_mask.astype("uint8") # opencv needs uint8 + mask = GenericMask(binary_mask, self.output.height, self.output.width) + shape2d = (binary_mask.shape[0], binary_mask.shape[1]) + + if not mask.has_holes: + # draw polygons for regular masks + for segment in mask.polygons: + # area = mask_util.area(mask_util.frPyObjects([segment], shape2d[0], shape2d[1])) + # if area < (area_threshold or 0): + # continue + has_valid_segment = True + segment = segment.reshape(-1, 2) + self.draw_polygon(segment, color=color, edge_color=edge_color, alpha=alpha) + else: + # TODO: Use Path/PathPatch to draw vector graphics: + # https://stackoverflow.com/questions/8919719/how-to-plot-a-complex-polygon + rgba = np.zeros(shape2d + (4,), dtype="float32") + rgba[:, :, :3] = color + rgba[:, :, 3] = (mask.mask == 1).astype("float32") * alpha + has_valid_segment = True + self.output.ax.imshow(rgba, extent=(0, self.output.width, self.output.height, 0)) + + if is_text: + if text is not None and has_valid_segment: + lighter_color = self._change_color_brightness(color, brightness_factor=0.7) + self._draw_text_in_mask(binary_mask, text, lighter_color) + return self.output + + def draw_soft_mask(self, soft_mask, color=None, *, text=None, alpha=0.5): + """ + Args: + soft_mask (ndarray): float array of shape (H, W), each value in [0, 1]. + color: color of the mask. Refer to `matplotlib.colors` for a full list of + formats that are accepted. If None, will pick a random color. + text (str): if None, will be drawn on the object + alpha (float): blending efficient. Smaller values lead to more transparent masks. + Returns: + output (VisImage): image object with mask drawn. + """ + if color is None: + color = random_color(rgb=True, maximum=1) + color = mplc.to_rgb(color) + + shape2d = (soft_mask.shape[0], soft_mask.shape[1]) + rgba = np.zeros(shape2d + (4,), dtype="float32") + rgba[:, :, :3] = color + rgba[:, :, 3] = soft_mask * alpha + self.output.ax.imshow(rgba, extent=(0, self.output.width, self.output.height, 0)) + + if text is not None: + lighter_color = self._change_color_brightness(color, brightness_factor=0.7) + binary_mask = (soft_mask > 0.5).astype("uint8") + # self._draw_text_in_mask(binary_mask, text, lighter_color) + return self.output + + def draw_polygon(self, segment, color, edge_color=None, alpha=0.5): + """ + Args: + segment: numpy array of shape Nx2, containing all the points in the polygon. + color: color of the polygon. Refer to `matplotlib.colors` for a full list of + formats that are accepted. + edge_color: color of the polygon edges. Refer to `matplotlib.colors` for a + full list of formats that are accepted. If not provided, a darker shade + of the polygon color will be used instead. + alpha (float): blending efficient. Smaller values lead to more transparent masks. + Returns: + output (VisImage): image object with polygon drawn. + """ + if edge_color is None: + # make edge color darker than the polygon color + if alpha > 0.8: + edge_color = self._change_color_brightness(color, brightness_factor=-0.7) + else: + edge_color = color + edge_color = mplc.to_rgb(edge_color) + (1,) + + polygon = mpl.patches.Polygon( + segment, + fill=True, + facecolor=mplc.to_rgb(color) + (alpha,), + edgecolor=edge_color, + linewidth=max(self._default_font_size // 15 * self.output.scale, 1), + ) + self.output.ax.add_patch(polygon) + return self.output + + """ + Internal methods: + """ + + def _jitter(self, color): + """ + Randomly modifies given color to produce a slightly different color than the color given. + Args: + color (tuple[double]): a tuple of 3 elements, containing the RGB values of the color + picked. The values in the list are in the [0.0, 1.0] range. + Returns: + jittered_color (tuple[double]): a tuple of 3 elements, containing the RGB values of the + color after being jittered. The values in the list are in the [0.0, 1.0] range. + """ + color = mplc.to_rgb(color) + vec = np.random.rand(3) + # better to do it in another color space + vec = vec / np.linalg.norm(vec) * 0.5 + res = np.clip(vec + color, 0, 1) + return tuple(res) + + def _create_grayscale_image(self, mask=None): + """ + Create a grayscale version of the original image. + The colors in masked area, if given, will be kept. + """ + img_bw = self.img.astype("f4").mean(axis=2) + img_bw = np.stack([img_bw] * 3, axis=2) + if mask is not None: + img_bw[mask] = self.img[mask] + return img_bw + + def _change_color_brightness(self, color, brightness_factor): + """ + Depending on the brightness_factor, gives a lighter or darker color i.e. a color with + less or more saturation than the original color. + Args: + color: color of the polygon. Refer to `matplotlib.colors` for a full list of + formats that are accepted. + brightness_factor (float): a value in [-1.0, 1.0] range. A lightness factor of + 0 will correspond to no change, a factor in [-1.0, 0) range will result in + a darker color and a factor in (0, 1.0] range will result in a lighter color. + Returns: + modified_color (tuple[double]): a tuple containing the RGB values of the + modified color. Each value in the tuple is in the [0.0, 1.0] range. + """ + assert brightness_factor >= -1.0 and brightness_factor <= 1.0 + color = mplc.to_rgb(color) + polygon_color = colorsys.rgb_to_hls(*mplc.to_rgb(color)) + modified_lightness = polygon_color[1] + (brightness_factor * polygon_color[1]) + modified_lightness = 0.0 if modified_lightness < 0.0 else modified_lightness + modified_lightness = 1.0 if modified_lightness > 1.0 else modified_lightness + modified_color = colorsys.hls_to_rgb(polygon_color[0], modified_lightness, polygon_color[2]) + return modified_color + + def _convert_boxes(self, boxes): + """ + Convert different format of boxes to an NxB array, where B = 4 or 5 is the box dimension. + """ + if isinstance(boxes, Boxes) or isinstance(boxes, RotatedBoxes): + return boxes.tensor.detach().numpy() + else: + return np.asarray(boxes) + + def _convert_masks(self, masks_or_polygons): + """ + Convert different format of masks or polygons to a tuple of masks and polygons. + Returns: + list[GenericMask]: + """ + + m = masks_or_polygons + if isinstance(m, PolygonMasks): + m = m.polygons + if isinstance(m, BitMasks): + m = m.tensor.numpy() + if isinstance(m, torch.Tensor): + m = m.numpy() + ret = [] + for x in m: + if isinstance(x, GenericMask): + ret.append(x) + else: + ret.append(GenericMask(x, self.output.height, self.output.width)) + return ret + + def _draw_text_in_mask(self, binary_mask, text, color): + """ + Find proper places to draw text given a binary mask. + """ + # TODO sometimes drawn on wrong objects. the heuristics here can improve. + _num_cc, cc_labels, stats, centroids = cv2.connectedComponentsWithStats(binary_mask, 8) + if stats[1:, -1].size == 0: + return + largest_component_id = np.argmax(stats[1:, -1]) + 1 + + # draw text on the largest component, as well as other very large components. + for cid in range(1, _num_cc): + if cid == largest_component_id or stats[cid, -1] > _LARGE_MASK_AREA_THRESH: + # median is more stable than centroid + # center = centroids[largest_component_id] + center = np.median((cc_labels == cid).nonzero(), axis=1)[::-1] + self.draw_text(text, center, color=color) + + def _convert_keypoints(self, keypoints): + if isinstance(keypoints, Keypoints): + keypoints = keypoints.tensor + keypoints = np.asarray(keypoints) + return keypoints + + def get_output(self): + """ + Returns: + output (VisImage): the image output containing the visualizations added + to the image. + """ + return self.output \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/__init__.py new file mode 100644 index 00000000..49f62369 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/__init__.py @@ -0,0 +1,3 @@ +from .detection_coco_evaluator import * +from .coco_evaluator import * +from .cityscapes_evaluation import CityscapesInstanceEvaluator \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/cityscapes_evaluation.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/cityscapes_evaluation.py new file mode 100644 index 00000000..19b1cb77 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/cityscapes_evaluation.py @@ -0,0 +1,201 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/detectron2/blob/main/detectron2/evaluation/cityscapes_evaluation.py +# Modified by Jitesh Jain (https://github.com/praeclarumjj3) +# ------------------------------------------------------------------------------ + +import glob +import logging +import numpy as np +import os +import tempfile +from collections import OrderedDict +import torch +from PIL import Image + +from annotator.oneformer.detectron2.data import MetadataCatalog +from annotator.oneformer.detectron2.utils import comm +from annotator.oneformer.detectron2.utils.file_io import PathManager + +from .evaluator import DatasetEvaluator + + +class CityscapesEvaluator(DatasetEvaluator): + """ + Base class for evaluation using cityscapes API. + """ + + def __init__(self, dataset_name): + """ + Args: + dataset_name (str): the name of the dataset. + It must have the following metadata associated with it: + "thing_classes", "gt_dir". + """ + self._metadata = MetadataCatalog.get(dataset_name) + self._cpu_device = torch.device("cpu") + self._logger = logging.getLogger(__name__) + + def reset(self): + self._working_dir = tempfile.TemporaryDirectory(prefix="cityscapes_eval_") + self._temp_dir = self._working_dir.name + # All workers will write to the same results directory + # TODO this does not work in distributed training + assert ( + comm.get_local_size() == comm.get_world_size() + ), "CityscapesEvaluator currently do not work with multiple machines." + self._temp_dir = comm.all_gather(self._temp_dir)[0] + if self._temp_dir != self._working_dir.name: + self._working_dir.cleanup() + self._logger.info( + "Writing cityscapes results to temporary directory {} ...".format(self._temp_dir) + ) + + +class CityscapesInstanceEvaluator(CityscapesEvaluator): + """ + Evaluate instance segmentation results on cityscapes dataset using cityscapes API. + + Note: + * It does not work in multi-machine distributed training. + * It contains a synchronization, therefore has to be used on all ranks. + * Only the main process runs evaluation. + """ + + def process(self, inputs, outputs): + from cityscapesscripts.helpers.labels import name2label + + for input, output in zip(inputs, outputs): + file_name = input["file_name"] + basename = os.path.splitext(os.path.basename(file_name))[0] + pred_txt = os.path.join(self._temp_dir, basename + "_pred.txt") + + if "instances" in output: + output = output["instances"].to(self._cpu_device) + num_instances = len(output) + with open(pred_txt, "w") as fout: + for i in range(num_instances): + pred_class = output.pred_classes[i] + classes = self._metadata.stuff_classes[pred_class] + class_id = name2label[classes].id + score = output.scores[i] + mask = output.pred_masks[i].numpy().astype("uint8") + png_filename = os.path.join( + self._temp_dir, basename + "_{}_{}.png".format(i, classes) + ) + + Image.fromarray(mask * 255).save(png_filename) + fout.write( + "{} {} {}\n".format(os.path.basename(png_filename), class_id, score) + ) + else: + # Cityscapes requires a prediction file for every ground truth image. + with open(pred_txt, "w") as fout: + pass + + def evaluate(self): + """ + Returns: + dict: has a key "segm", whose value is a dict of "AP" and "AP50". + """ + comm.synchronize() + if comm.get_rank() > 0: + return + import cityscapesscripts.evaluation.evalInstanceLevelSemanticLabeling as cityscapes_eval + + self._logger.info("Evaluating results under {} ...".format(self._temp_dir)) + + # set some global states in cityscapes evaluation API, before evaluating + cityscapes_eval.args.predictionPath = os.path.abspath(self._temp_dir) + cityscapes_eval.args.predictionWalk = None + cityscapes_eval.args.JSONOutput = False + cityscapes_eval.args.colorized = False + cityscapes_eval.args.gtInstancesFile = os.path.join(self._temp_dir, "gtInstances.json") + + # These lines are adopted from + # https://github.com/mcordts/cityscapesScripts/blob/master/cityscapesscripts/evaluation/evalInstanceLevelSemanticLabeling.py # noqa + gt_dir = PathManager.get_local_path(self._metadata.gt_dir) + groundTruthImgList = glob.glob(os.path.join(gt_dir, "*", "*_gtFine_instanceIds.png")) + assert len( + groundTruthImgList + ), "Cannot find any ground truth images to use for evaluation. Searched for: {}".format( + cityscapes_eval.args.groundTruthSearch + ) + predictionImgList = [] + for gt in groundTruthImgList: + predictionImgList.append(cityscapes_eval.getPrediction(gt, cityscapes_eval.args)) + results = cityscapes_eval.evaluateImgLists( + predictionImgList, groundTruthImgList, cityscapes_eval.args + )["averages"] + + ret = OrderedDict() + ret["segm"] = {"AP": results["allAp"] * 100, "AP50": results["allAp50%"] * 100} + self._working_dir.cleanup() + return ret + + +class CityscapesSemSegEvaluator(CityscapesEvaluator): + """ + Evaluate semantic segmentation results on cityscapes dataset using cityscapes API. + + Note: + * It does not work in multi-machine distributed training. + * It contains a synchronization, therefore has to be used on all ranks. + * Only the main process runs evaluation. + """ + + def process(self, inputs, outputs): + from cityscapesscripts.helpers.labels import trainId2label + + for input, output in zip(inputs, outputs): + file_name = input["file_name"] + basename = os.path.splitext(os.path.basename(file_name))[0] + pred_filename = os.path.join(self._temp_dir, basename + "_pred.png") + + output = output["sem_seg"].argmax(dim=0).to(self._cpu_device).numpy() + pred = 255 * np.ones(output.shape, dtype=np.uint8) + for train_id, label in trainId2label.items(): + if label.ignoreInEval: + continue + pred[output == train_id] = label.id + Image.fromarray(pred).save(pred_filename) + + def evaluate(self): + comm.synchronize() + if comm.get_rank() > 0: + return + # Load the Cityscapes eval script *after* setting the required env var, + # since the script reads CITYSCAPES_DATASET into global variables at load time. + import cityscapesscripts.evaluation.evalPixelLevelSemanticLabeling as cityscapes_eval + + self._logger.info("Evaluating results under {} ...".format(self._temp_dir)) + + # set some global states in cityscapes evaluation API, before evaluating + cityscapes_eval.args.predictionPath = os.path.abspath(self._temp_dir) + cityscapes_eval.args.predictionWalk = None + cityscapes_eval.args.JSONOutput = False + cityscapes_eval.args.colorized = False + + # These lines are adopted from + # https://github.com/mcordts/cityscapesScripts/blob/master/cityscapesscripts/evaluation/evalPixelLevelSemanticLabeling.py # noqa + gt_dir = PathManager.get_local_path(self._metadata.gt_dir) + groundTruthImgList = glob.glob(os.path.join(gt_dir, "*", "*_gtFine_labelIds.png")) + assert len( + groundTruthImgList + ), "Cannot find any ground truth images to use for evaluation. Searched for: {}".format( + cityscapes_eval.args.groundTruthSearch + ) + predictionImgList = [] + for gt in groundTruthImgList: + predictionImgList.append(cityscapes_eval.getPrediction(cityscapes_eval.args, gt)) + results = cityscapes_eval.evaluateImgLists( + predictionImgList, groundTruthImgList, cityscapes_eval.args + ) + ret = OrderedDict() + ret["sem_seg"] = { + "IoU": 100.0 * results["averageScoreClasses"], + "iIoU": 100.0 * results["averageScoreInstClasses"], + "IoU_sup": 100.0 * results["averageScoreCategories"], + "iIoU_sup": 100.0 * results["averageScoreInstCategories"], + } + self._working_dir.cleanup() + return ret diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/coco_evaluator.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/coco_evaluator.py new file mode 100644 index 00000000..c26107ee --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/coco_evaluator.py @@ -0,0 +1,563 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/detectron2/blob/main/detectron2/evaluation/coco_evaluation.py +# Modified by Jitesh Jain (https://github.com/praeclarumjj3) +# ------------------------------------------------------------------------------ + +import contextlib +import copy +import io +import itertools +import json +import logging +import numpy as np +import os +import pickle +from collections import OrderedDict +import annotator.oneformer.pycocotools.mask as mask_util +import torch +from annotator.oneformer.pycocotools.coco import COCO +from annotator.oneformer.pycocotools.cocoeval import COCOeval +from tabulate import tabulate + +import annotator.oneformer.detectron2.utils.comm as comm +from annotator.oneformer.detectron2.config import CfgNode +from annotator.oneformer.detectron2.data import MetadataCatalog +from annotator.oneformer.detectron2.data.datasets.coco import convert_to_coco_json +from annotator.oneformer.detectron2.structures import Boxes, BoxMode, pairwise_iou +from annotator.oneformer.detectron2.utils.file_io import PathManager +from annotator.oneformer.detectron2.utils.logger import create_small_table + +from .evaluator import DatasetEvaluator + +try: + from annotator.oneformer.detectron2.evaluation.fast_eval_api import COCOeval_opt +except ImportError: + COCOeval_opt = COCOeval + + +class COCOEvaluator(DatasetEvaluator): + """ + Evaluate AP for instance detection/segmentation, AP + for keypoint detection outputs using COCO's metrics. + See http://cocodataset.org/#detection-eval and + http://cocodataset.org/#keypoints-eval to understand its metrics. + The metrics range from 0 to 100 (instead of 0 to 1), where a -1 or NaN means + the metric cannot be computed (e.g. due to no predictions made). + + In addition to COCO, this evaluator is able to support any bounding box detection, + instance segmentation, or keypoint detection dataset. + """ + + def __init__( + self, + dataset_name, + tasks=None, + distributed=True, + output_dir=None, + *, + max_dets_per_image=None, + use_fast_impl=True, + kpt_oks_sigmas=(), + allow_cached_coco=True, + ): + """ + Args: + dataset_name (str): name of the dataset to be evaluated. + It must have either the following corresponding metadata: + + "json_file": the path to the COCO format annotation + + Or it must be in detectron2's standard dataset format + so it can be converted to COCO format automatically. + tasks (tuple[str]): tasks that can be evaluated under the given + configuration. A task is one of "bbox", "segm", "keypoints". + By default, will infer this automatically from predictions. + distributed (True): if True, will collect results from all ranks and run evaluation + in the main process. + Otherwise, will only evaluate the results in the current process. + output_dir (str): optional, an output directory to dump all + results predicted on the dataset. The dump contains two files: + + 1. "instances_predictions.pth" a file that can be loaded with `torch.load` and + contains all the results in the format they are produced by the model. + 2. "coco_instances_results.json" a json file in COCO's result format. + max_dets_per_image (int): limit on the maximum number of detections per image. + By default in COCO, this limit is to 100, but this can be customized + to be greater, as is needed in evaluation metrics AP fixed and AP pool + (see https://arxiv.org/pdf/2102.01066.pdf) + This doesn't affect keypoint evaluation. + use_fast_impl (bool): use a fast but **unofficial** implementation to compute AP. + Although the results should be very close to the official implementation in COCO + API, it is still recommended to compute results with the official API for use in + papers. The faster implementation also uses more RAM. + kpt_oks_sigmas (list[float]): The sigmas used to calculate keypoint OKS. + See http://cocodataset.org/#keypoints-eval + When empty, it will use the defaults in COCO. + Otherwise it should be the same length as ROI_KEYPOINT_HEAD.NUM_KEYPOINTS. + allow_cached_coco (bool): Whether to use cached coco json from previous validation + runs. You should set this to False if you need to use different validation data. + Defaults to True. + """ + self._logger = logging.getLogger(__name__) + self._distributed = distributed + self._output_dir = output_dir + + if use_fast_impl and (COCOeval_opt is COCOeval): + self._logger.info("Fast COCO eval is not built. Falling back to official COCO eval.") + use_fast_impl = False + self._use_fast_impl = use_fast_impl + + # COCOeval requires the limit on the number of detections per image (maxDets) to be a list + # with at least 3 elements. The default maxDets in COCOeval is [1, 10, 100], in which the + # 3rd element (100) is used as the limit on the number of detections per image when + # evaluating AP. COCOEvaluator expects an integer for max_dets_per_image, so for COCOeval, + # we reformat max_dets_per_image into [1, 10, max_dets_per_image], based on the defaults. + if max_dets_per_image is None: + max_dets_per_image = [1, 10, 100] + else: + max_dets_per_image = [1, 10, max_dets_per_image] + self._max_dets_per_image = max_dets_per_image + + if tasks is not None and isinstance(tasks, CfgNode): + kpt_oks_sigmas = ( + tasks.TEST.KEYPOINT_OKS_SIGMAS if not kpt_oks_sigmas else kpt_oks_sigmas + ) + self._logger.warn( + "COCO Evaluator instantiated using config, this is deprecated behavior." + " Please pass in explicit arguments instead." + ) + self._tasks = None # Infering it from predictions should be better + else: + self._tasks = tasks + + self._cpu_device = torch.device("cpu") + + self._metadata = MetadataCatalog.get(dataset_name) + if not hasattr(self._metadata, "json_file"): + if output_dir is None: + raise ValueError( + "output_dir must be provided to COCOEvaluator " + "for datasets not in COCO format." + ) + self._logger.info(f"Trying to convert '{dataset_name}' to COCO format ...") + + cache_path = os.path.join(output_dir, f"{dataset_name}_coco_format.json") + self._metadata.json_file = cache_path + convert_to_coco_json(dataset_name, cache_path, allow_cached=allow_cached_coco) + + json_file = PathManager.get_local_path(self._metadata.json_file) + with contextlib.redirect_stdout(io.StringIO()): + self._coco_api = COCO(json_file) + + # Test set json files do not contain annotations (evaluation must be + # performed using the COCO evaluation server). + self._do_evaluation = "annotations" in self._coco_api.dataset + if self._do_evaluation: + self._kpt_oks_sigmas = kpt_oks_sigmas + + def reset(self): + self._predictions = [] + + def process(self, inputs, outputs): + """ + Args: + inputs: the inputs to a COCO model (e.g., GeneralizedRCNN). + It is a list of dict. Each dict corresponds to an image and + contains keys like "height", "width", "file_name", "image_id". + outputs: the outputs of a COCO model. It is a list of dicts with key + "instances" that contains :class:`Instances`. + """ + for input, output in zip(inputs, outputs): + prediction = {"image_id": input["image_id"]} + + if "instances" in output: + instances = output["instances"].to(self._cpu_device) + prediction["instances"] = instances_to_coco_json(instances, input["image_id"]) + if len(prediction) > 1: + self._predictions.append(prediction) + + def evaluate(self, img_ids=None): + """ + Args: + img_ids: a list of image IDs to evaluate on. Default to None for the whole dataset + """ + if self._distributed: + comm.synchronize() + predictions = comm.gather(self._predictions, dst=0) + predictions = list(itertools.chain(*predictions)) + + if not comm.is_main_process(): + return {} + else: + predictions = self._predictions + + if len(predictions) == 0: + self._logger.warning("[COCOEvaluator] Did not receive valid predictions.") + return {} + + if self._output_dir: + PathManager.mkdirs(self._output_dir) + file_path = os.path.join(self._output_dir, "instances_predictions.pth") + with PathManager.open(file_path, "wb") as f: + torch.save(predictions, f) + + self._results = OrderedDict() + if "instances" in predictions[0]: + self._eval_predictions(predictions, img_ids=img_ids) + # Copy so the caller can do whatever with results + return copy.deepcopy(self._results) + + def _tasks_from_predictions(self, predictions): + """ + Get COCO API "tasks" (i.e. iou_type) from COCO-format predictions. + """ + for pred in predictions: + if "segmentation" in pred: + tasks = {"segm"} + if "keypoints" in pred: + tasks.add("keypoints") + return sorted(tasks) + + def _eval_predictions(self, predictions, img_ids=None): + """ + Evaluate predictions. Fill self._results with the metrics of the tasks. + """ + self._logger.info("Preparing results for COCO format ...") + coco_results = list(itertools.chain(*[x["instances"] for x in predictions])) + tasks = self._tasks or self._tasks_from_predictions(coco_results) + + # unmap the category ids for COCO + if hasattr(self._metadata, "thing_dataset_id_to_contiguous_id"): + dataset_id_to_contiguous_id = self._metadata.thing_dataset_id_to_contiguous_id + all_contiguous_ids = list(dataset_id_to_contiguous_id.values()) + num_classes = len(all_contiguous_ids) + assert min(all_contiguous_ids) == 0 and max(all_contiguous_ids) == num_classes - 1 + + reverse_id_mapping = {v: k for k, v in dataset_id_to_contiguous_id.items()} + for result in coco_results: + category_id = result["category_id"] + assert category_id < num_classes, ( + f"A prediction has class={category_id}, " + f"but the dataset only has {num_classes} classes and " + f"predicted class id should be in [0, {num_classes - 1}]." + ) + result["category_id"] = reverse_id_mapping[category_id] + + if self._output_dir: + file_path = os.path.join(self._output_dir, "coco_instances_results.json") + self._logger.info("Saving results to {}".format(file_path)) + with PathManager.open(file_path, "w") as f: + f.write(json.dumps(coco_results)) + f.flush() + + if not self._do_evaluation: + self._logger.info("Annotations are not available for evaluation.") + return + + self._logger.info( + "Evaluating predictions with {} COCO API...".format( + "unofficial" if self._use_fast_impl else "official" + ) + ) + for task in sorted(tasks): + assert task in {"segm", "keypoints"}, f"Got unknown task: {task}!" + coco_eval = ( + _evaluate_predictions_on_coco( + self._coco_api, + coco_results, + task, + kpt_oks_sigmas=self._kpt_oks_sigmas, + use_fast_impl=self._use_fast_impl, + img_ids=img_ids, + max_dets_per_image=self._max_dets_per_image, + ) + if len(coco_results) > 0 + else None # cocoapi does not handle empty results very well + ) + + res = self._derive_coco_results( + coco_eval, task, class_names=self._metadata.get("thing_classes") + ) + self._results[task] = res + + def _derive_coco_results(self, coco_eval, iou_type, class_names=None): + """ + Derive the desired score numbers from summarized COCOeval. + + Args: + coco_eval (None or COCOEval): None represents no predictions from model. + iou_type (str): + class_names (None or list[str]): if provided, will use it to predict + per-category AP. + + Returns: + a dict of {metric name: score} + """ + + metrics = { + "segm": ["AP", "AP50", "AP75", "APs", "APm", "APl"], + "keypoints": ["AP", "AP50", "AP75", "APm", "APl"], + }[iou_type] + + if coco_eval is None: + self._logger.warn("No predictions from the model!") + return {metric: float("nan") for metric in metrics} + + # the standard metrics + results = { + metric: float(coco_eval.stats[idx] * 100 if coco_eval.stats[idx] >= 0 else "nan") + for idx, metric in enumerate(metrics) + } + self._logger.info( + "Evaluation results for {}: \n".format(iou_type) + create_small_table(results) + ) + if not np.isfinite(sum(results.values())): + self._logger.info("Some metrics cannot be computed and is shown as NaN.") + + if class_names is None or len(class_names) <= 1: + return results + # Compute per-category AP + # from https://github.com/facebookresearch/Detectron/blob/a6a835f5b8208c45d0dce217ce9bbda915f44df7/detectron/datasets/json_dataset_evaluator.py#L222-L252 # noqa + precisions = coco_eval.eval["precision"] + # precision has dims (iou, recall, cls, area range, max dets) + assert len(class_names) == precisions.shape[2] + + results_per_category = [] + for idx, name in enumerate(class_names): + # area range index 0: all area ranges + # max dets index -1: typically 100 per image + precision = precisions[:, :, idx, 0, -1] + precision = precision[precision > -1] + ap = np.mean(precision) if precision.size else float("nan") + results_per_category.append(("{}".format(name), float(ap * 100))) + + # tabulate it + N_COLS = min(6, len(results_per_category) * 2) + results_flatten = list(itertools.chain(*results_per_category)) + results_2d = itertools.zip_longest(*[results_flatten[i::N_COLS] for i in range(N_COLS)]) + table = tabulate( + results_2d, + tablefmt="pipe", + floatfmt=".3f", + headers=["category", "AP"] * (N_COLS // 2), + numalign="left", + ) + self._logger.info("Per-category {} AP: \n".format(iou_type) + table) + + results.update({"AP-" + name: ap for name, ap in results_per_category}) + return results + + +def instances_to_coco_json(instances, img_id): + """ + Dump an "Instances" object to a COCO-format json that's used for evaluation. + + Args: + instances (Instances): + img_id (int): the image id + + Returns: + list[dict]: list of json annotations in COCO format. + """ + num_instance = len(instances) + if num_instance == 0: + return [] + + scores = instances.scores.tolist() + classes = instances.pred_classes.tolist() + + has_mask = instances.has("pred_masks") + if has_mask: + # use RLE to encode the masks, because they are too large and takes memory + # since this evaluator stores outputs of the entire dataset + rles = [ + mask_util.encode(np.array(mask[:, :, None], order="F", dtype="uint8"))[0] + for mask in instances.pred_masks + ] + for rle in rles: + # "counts" is an array encoded by mask_util as a byte-stream. Python3's + # json writer which always produces strings cannot serialize a bytestream + # unless you decode it. Thankfully, utf-8 works out (which is also what + # the annotator.oneformer.pycocotools/_mask.pyx does). + rle["counts"] = rle["counts"].decode("utf-8") + + has_keypoints = instances.has("pred_keypoints") + if has_keypoints: + keypoints = instances.pred_keypoints + + results = [] + for k in range(num_instance): + result = { + "image_id": img_id, + "category_id": classes[k], + "score": scores[k], + } + if has_mask: + result["segmentation"] = rles[k] + if has_keypoints: + # In COCO annotations, + # keypoints coordinates are pixel indices. + # However our predictions are floating point coordinates. + # Therefore we subtract 0.5 to be consistent with the annotation format. + # This is the inverse of data loading logic in `datasets/coco.py`. + keypoints[k][:, :2] -= 0.5 + result["keypoints"] = keypoints[k].flatten().tolist() + results.append(result) + return results + +def _evaluate_predictions_on_coco( + coco_gt, + coco_results, + iou_type, + kpt_oks_sigmas=None, + use_fast_impl=True, + img_ids=None, + max_dets_per_image=None, +): + """ + Evaluate the coco results using COCOEval API. + """ + assert len(coco_results) > 0 + + if iou_type == "segm": + coco_results = copy.deepcopy(coco_results) + # When evaluating mask AP, if the results contain bbox, cocoapi will + # use the box area as the area of the instance, instead of the mask area. + # This leads to a different definition of small/medium/large. + # We remove the bbox field to let mask AP use mask area. + for c in coco_results: + c.pop("bbox", None) + + coco_dt = coco_gt.loadRes(coco_results) + coco_eval = (COCOeval_opt if use_fast_impl else COCOeval)(coco_gt, coco_dt, iou_type) + # For COCO, the default max_dets_per_image is [1, 10, 100]. + if max_dets_per_image is None: + max_dets_per_image = [1, 10, 100] # Default from COCOEval + else: + assert ( + len(max_dets_per_image) >= 3 + ), "COCOeval requires maxDets (and max_dets_per_image) to have length at least 3" + # In the case that user supplies a custom input for max_dets_per_image, + # apply COCOevalMaxDets to evaluate AP with the custom input. + if max_dets_per_image[2] != 100: + coco_eval = COCOevalMaxDets(coco_gt, coco_dt, iou_type) + if iou_type != "keypoints": + coco_eval.params.maxDets = max_dets_per_image + + if img_ids is not None: + coco_eval.params.imgIds = img_ids + + if iou_type == "keypoints": + # Use the COCO default keypoint OKS sigmas unless overrides are specified + if kpt_oks_sigmas: + assert hasattr(coco_eval.params, "kpt_oks_sigmas"), "annotator.oneformer.pycocotools is too old!" + coco_eval.params.kpt_oks_sigmas = np.array(kpt_oks_sigmas) + # COCOAPI requires every detection and every gt to have keypoints, so + # we just take the first entry from both + num_keypoints_dt = len(coco_results[0]["keypoints"]) // 3 + num_keypoints_gt = len(next(iter(coco_gt.anns.values()))["keypoints"]) // 3 + num_keypoints_oks = len(coco_eval.params.kpt_oks_sigmas) + assert num_keypoints_oks == num_keypoints_dt == num_keypoints_gt, ( + f"[COCOEvaluator] Prediction contain {num_keypoints_dt} keypoints. " + f"Ground truth contains {num_keypoints_gt} keypoints. " + f"The length of cfg.TEST.KEYPOINT_OKS_SIGMAS is {num_keypoints_oks}. " + "They have to agree with each other. For meaning of OKS, please refer to " + "http://cocodataset.org/#keypoints-eval." + ) + + coco_eval.evaluate() + coco_eval.accumulate() + coco_eval.summarize() + + return coco_eval + + +class COCOevalMaxDets(COCOeval): + """ + Modified version of COCOeval for evaluating AP with a custom + maxDets (by default for COCO, maxDets is 100) + """ + + def summarize(self): + """ + Compute and display summary metrics for evaluation results given + a custom value for max_dets_per_image + """ + + def _summarize(ap=1, iouThr=None, areaRng="all", maxDets=100): + p = self.params + iStr = " {:<18} {} @[ IoU={:<9} | area={:>6s} | maxDets={:>3d} ] = {:0.3f}" + titleStr = "Average Precision" if ap == 1 else "Average Recall" + typeStr = "(AP)" if ap == 1 else "(AR)" + iouStr = ( + "{:0.2f}:{:0.2f}".format(p.iouThrs[0], p.iouThrs[-1]) + if iouThr is None + else "{:0.2f}".format(iouThr) + ) + + aind = [i for i, aRng in enumerate(p.areaRngLbl) if aRng == areaRng] + mind = [i for i, mDet in enumerate(p.maxDets) if mDet == maxDets] + if ap == 1: + # dimension of precision: [TxRxKxAxM] + s = self.eval["precision"] + # IoU + if iouThr is not None: + t = np.where(iouThr == p.iouThrs)[0] + s = s[t] + s = s[:, :, :, aind, mind] + else: + # dimension of recall: [TxKxAxM] + s = self.eval["recall"] + if iouThr is not None: + t = np.where(iouThr == p.iouThrs)[0] + s = s[t] + s = s[:, :, aind, mind] + if len(s[s > -1]) == 0: + mean_s = -1 + else: + mean_s = np.mean(s[s > -1]) + print(iStr.format(titleStr, typeStr, iouStr, areaRng, maxDets, mean_s)) + return mean_s + + def _summarizeDets(): + stats = np.zeros((12,)) + # Evaluate AP using the custom limit on maximum detections per image + stats[0] = _summarize(1, maxDets=self.params.maxDets[2]) + stats[1] = _summarize(1, iouThr=0.5, maxDets=self.params.maxDets[2]) + stats[2] = _summarize(1, iouThr=0.75, maxDets=self.params.maxDets[2]) + stats[3] = _summarize(1, areaRng="small", maxDets=self.params.maxDets[2]) + stats[4] = _summarize(1, areaRng="medium", maxDets=self.params.maxDets[2]) + stats[5] = _summarize(1, areaRng="large", maxDets=self.params.maxDets[2]) + stats[6] = _summarize(0, maxDets=self.params.maxDets[0]) + stats[7] = _summarize(0, maxDets=self.params.maxDets[1]) + stats[8] = _summarize(0, maxDets=self.params.maxDets[2]) + stats[9] = _summarize(0, areaRng="small", maxDets=self.params.maxDets[2]) + stats[10] = _summarize(0, areaRng="medium", maxDets=self.params.maxDets[2]) + stats[11] = _summarize(0, areaRng="large", maxDets=self.params.maxDets[2]) + return stats + + def _summarizeKps(): + stats = np.zeros((10,)) + stats[0] = _summarize(1, maxDets=20) + stats[1] = _summarize(1, maxDets=20, iouThr=0.5) + stats[2] = _summarize(1, maxDets=20, iouThr=0.75) + stats[3] = _summarize(1, maxDets=20, areaRng="medium") + stats[4] = _summarize(1, maxDets=20, areaRng="large") + stats[5] = _summarize(0, maxDets=20) + stats[6] = _summarize(0, maxDets=20, iouThr=0.5) + stats[7] = _summarize(0, maxDets=20, iouThr=0.75) + stats[8] = _summarize(0, maxDets=20, areaRng="medium") + stats[9] = _summarize(0, maxDets=20, areaRng="large") + return stats + + if not self.eval: + raise Exception("Please run accumulate() first") + iouType = self.params.iouType + if iouType == "segm": + summarize = _summarizeDets + elif iouType == "keypoints": + summarize = _summarizeKps + self.stats = summarize() + + def __str__(self): + self.summarize() \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/detection_coco_evaluator.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/detection_coco_evaluator.py new file mode 100644 index 00000000..8ea65b7f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/detection_coco_evaluator.py @@ -0,0 +1,723 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/detectron2/blob/main/detectron2/evaluation/coco_evaluation.py +# Modified by Jitesh Jain (https://github.com/praeclarumjj3) +# ------------------------------------------------------------------------------ + +import contextlib +import copy +import io +import itertools +import json +import logging +import numpy as np +import os +import pickle +from collections import OrderedDict +import annotator.oneformer.pycocotools.mask as mask_util +import torch +from annotator.oneformer.pycocotools.coco import COCO +from annotator.oneformer.pycocotools.cocoeval import COCOeval +from tabulate import tabulate + +import annotator.oneformer.detectron2.utils.comm as comm +from annotator.oneformer.detectron2.config import CfgNode +from annotator.oneformer.detectron2.data import MetadataCatalog +from annotator.oneformer.detectron2.data.datasets.coco import convert_to_coco_json +from annotator.oneformer.detectron2.structures import Boxes, BoxMode, pairwise_iou +from annotator.oneformer.detectron2.utils.file_io import PathManager +from annotator.oneformer.detectron2.utils.logger import create_small_table + +from .evaluator import DatasetEvaluator + +try: + from annotator.oneformer.detectron2.evaluation.fast_eval_api import COCOeval_opt +except ImportError: + COCOeval_opt = COCOeval + + +class DetectionCOCOEvaluator(DatasetEvaluator): + """ + Evaluate AR for object proposals, AP for instance detection/segmentation, AP + for keypoint detection outputs using COCO's metrics. + See http://cocodataset.org/#detection-eval and + http://cocodataset.org/#keypoints-eval to understand its metrics. + The metrics range from 0 to 100 (instead of 0 to 1), where a -1 or NaN means + the metric cannot be computed (e.g. due to no predictions made). + + In addition to COCO, this evaluator is able to support any bounding box detection, + instance segmentation, or keypoint detection dataset. + """ + + def __init__( + self, + dataset_name, + tasks=None, + distributed=True, + output_dir=None, + *, + max_dets_per_image=None, + use_fast_impl=True, + kpt_oks_sigmas=(), + allow_cached_coco=True, + ): + """ + Args: + dataset_name (str): name of the dataset to be evaluated. + It must have either the following corresponding metadata: + + "json_file": the path to the COCO format annotation + + Or it must be in detectron2's standard dataset format + so it can be converted to COCO format automatically. + tasks (tuple[str]): tasks that can be evaluated under the given + configuration. A task is one of "bbox", "segm", "keypoints". + By default, will infer this automatically from predictions. + distributed (True): if True, will collect results from all ranks and run evaluation + in the main process. + Otherwise, will only evaluate the results in the current process. + output_dir (str): optional, an output directory to dump all + results predicted on the dataset. The dump contains two files: + + 1. "instances_predictions.pth" a file that can be loaded with `torch.load` and + contains all the results in the format they are produced by the model. + 2. "coco_instances_results.json" a json file in COCO's result format. + max_dets_per_image (int): limit on the maximum number of detections per image. + By default in COCO, this limit is to 100, but this can be customized + to be greater, as is needed in evaluation metrics AP fixed and AP pool + (see https://arxiv.org/pdf/2102.01066.pdf) + This doesn't affect keypoint evaluation. + use_fast_impl (bool): use a fast but **unofficial** implementation to compute AP. + Although the results should be very close to the official implementation in COCO + API, it is still recommended to compute results with the official API for use in + papers. The faster implementation also uses more RAM. + kpt_oks_sigmas (list[float]): The sigmas used to calculate keypoint OKS. + See http://cocodataset.org/#keypoints-eval + When empty, it will use the defaults in COCO. + Otherwise it should be the same length as ROI_KEYPOINT_HEAD.NUM_KEYPOINTS. + allow_cached_coco (bool): Whether to use cached coco json from previous validation + runs. You should set this to False if you need to use different validation data. + Defaults to True. + """ + self._logger = logging.getLogger(__name__) + self._distributed = distributed + self._output_dir = output_dir + + if use_fast_impl and (COCOeval_opt is COCOeval): + self._logger.info("Fast COCO eval is not built. Falling back to official COCO eval.") + use_fast_impl = False + self._use_fast_impl = use_fast_impl + + # COCOeval requires the limit on the number of detections per image (maxDets) to be a list + # with at least 3 elements. The default maxDets in COCOeval is [1, 10, 100], in which the + # 3rd element (100) is used as the limit on the number of detections per image when + # evaluating AP. COCOEvaluator expects an integer for max_dets_per_image, so for COCOeval, + # we reformat max_dets_per_image into [1, 10, max_dets_per_image], based on the defaults. + if max_dets_per_image is None: + max_dets_per_image = [1, 10, 100] + else: + max_dets_per_image = [1, 10, max_dets_per_image] + self._max_dets_per_image = max_dets_per_image + + if tasks is not None and isinstance(tasks, CfgNode): + kpt_oks_sigmas = ( + tasks.TEST.KEYPOINT_OKS_SIGMAS if not kpt_oks_sigmas else kpt_oks_sigmas + ) + self._logger.warn( + "COCO Evaluator instantiated using config, this is deprecated behavior." + " Please pass in explicit arguments instead." + ) + self._tasks = None # Infering it from predictions should be better + else: + self._tasks = tasks + + self._cpu_device = torch.device("cpu") + + self._metadata = MetadataCatalog.get(dataset_name) + if not hasattr(self._metadata, "json_file"): + if output_dir is None: + raise ValueError( + "output_dir must be provided to COCOEvaluator " + "for datasets not in COCO format." + ) + self._logger.info(f"Trying to convert '{dataset_name}' to COCO format ...") + + cache_path = os.path.join(output_dir, f"{dataset_name}_coco_format.json") + self._metadata.json_file = cache_path + convert_to_coco_json(dataset_name, cache_path, allow_cached=allow_cached_coco) + + json_file = PathManager.get_local_path(self._metadata.json_file) + with contextlib.redirect_stdout(io.StringIO()): + self._coco_api = COCO(json_file) + + # Test set json files do not contain annotations (evaluation must be + # performed using the COCO evaluation server). + self._do_evaluation = "annotations" in self._coco_api.dataset + if self._do_evaluation: + self._kpt_oks_sigmas = kpt_oks_sigmas + + def reset(self): + self._predictions = [] + + def process(self, inputs, outputs): + """ + Args: + inputs: the inputs to a COCO model (e.g., GeneralizedRCNN). + It is a list of dict. Each dict corresponds to an image and + contains keys like "height", "width", "file_name", "image_id". + outputs: the outputs of a COCO model. It is a list of dicts with key + "box_instances" that contains :class:`Instances`. + """ + for input, output in zip(inputs, outputs): + prediction = {"image_id": input["image_id"]} + + if "box_instances" in output: + instances = output["box_instances"].to(self._cpu_device) + prediction["box_instances"] = instances_to_coco_json(instances, input["image_id"]) + if "proposals" in output: + prediction["proposals"] = output["proposals"].to(self._cpu_device) + if len(prediction) > 1: + self._predictions.append(prediction) + + def evaluate(self, img_ids=None): + """ + Args: + img_ids: a list of image IDs to evaluate on. Default to None for the whole dataset + """ + if self._distributed: + comm.synchronize() + predictions = comm.gather(self._predictions, dst=0) + predictions = list(itertools.chain(*predictions)) + + if not comm.is_main_process(): + return {} + else: + predictions = self._predictions + + if len(predictions) == 0: + self._logger.warning("[COCOEvaluator] Did not receive valid predictions.") + return {} + + if self._output_dir: + PathManager.mkdirs(self._output_dir) + file_path = os.path.join(self._output_dir, "instances_predictions.pth") + with PathManager.open(file_path, "wb") as f: + torch.save(predictions, f) + + self._results = OrderedDict() + if "proposals" in predictions[0]: + self._eval_box_proposals(predictions) + if "box_instances" in predictions[0]: + self._eval_predictions(predictions, img_ids=img_ids) + # Copy so the caller can do whatever with results + return copy.deepcopy(self._results) + + def _tasks_from_predictions(self, predictions): + """ + Get COCO API "tasks" (i.e. iou_type) from COCO-format predictions. + """ + tasks = {"bbox"} + for pred in predictions: + if "keypoints" in pred: + tasks.add("keypoints") + return sorted(tasks) + + def _eval_predictions(self, predictions, img_ids=None): + """ + Evaluate predictions. Fill self._results with the metrics of the tasks. + """ + self._logger.info("Preparing results for COCO format ...") + coco_results = list(itertools.chain(*[x["box_instances"] for x in predictions])) + tasks = self._tasks or self._tasks_from_predictions(coco_results) + + # unmap the category ids for COCO + if hasattr(self._metadata, "thing_dataset_id_to_contiguous_id"): + dataset_id_to_contiguous_id = self._metadata.thing_dataset_id_to_contiguous_id + all_contiguous_ids = list(dataset_id_to_contiguous_id.values()) + num_classes = len(all_contiguous_ids) + assert min(all_contiguous_ids) == 0 and max(all_contiguous_ids) == num_classes - 1 + + reverse_id_mapping = {v: k for k, v in dataset_id_to_contiguous_id.items()} + for result in coco_results: + category_id = result["category_id"] + assert category_id < num_classes, ( + f"A prediction has class={category_id}, " + f"but the dataset only has {num_classes} classes and " + f"predicted class id should be in [0, {num_classes - 1}]." + ) + result["category_id"] = reverse_id_mapping[category_id] + + if self._output_dir: + file_path = os.path.join(self._output_dir, "coco_instances_results.json") + self._logger.info("Saving results to {}".format(file_path)) + with PathManager.open(file_path, "w") as f: + f.write(json.dumps(coco_results)) + f.flush() + + if not self._do_evaluation: + self._logger.info("Annotations are not available for evaluation.") + return + + self._logger.info( + "Evaluating predictions with {} COCO API...".format( + "unofficial" if self._use_fast_impl else "official" + ) + ) + for task in sorted(tasks): + assert task in {"bbox", "keypoints"}, f"Got unknown task: {task}!" + coco_eval = ( + _evaluate_predictions_on_coco( + self._coco_api, + coco_results, + task, + kpt_oks_sigmas=self._kpt_oks_sigmas, + use_fast_impl=self._use_fast_impl, + img_ids=img_ids, + max_dets_per_image=self._max_dets_per_image, + ) + if len(coco_results) > 0 + else None # cocoapi does not handle empty results very well + ) + + res = self._derive_coco_results( + coco_eval, task, class_names=self._metadata.get("thing_classes") + ) + self._results[task] = res + + def _eval_box_proposals(self, predictions): + """ + Evaluate the box proposals in predictions. + Fill self._results with the metrics for "box_proposals" task. + """ + if self._output_dir: + # Saving generated box proposals to file. + # Predicted box_proposals are in XYXY_ABS mode. + bbox_mode = BoxMode.XYXY_ABS.value + ids, boxes, objectness_logits = [], [], [] + for prediction in predictions: + ids.append(prediction["image_id"]) + boxes.append(prediction["proposals"].proposal_boxes.tensor.numpy()) + objectness_logits.append(prediction["proposals"].objectness_logits.numpy()) + + proposal_data = { + "boxes": boxes, + "objectness_logits": objectness_logits, + "ids": ids, + "bbox_mode": bbox_mode, + } + with PathManager.open(os.path.join(self._output_dir, "box_proposals.pkl"), "wb") as f: + pickle.dump(proposal_data, f) + + if not self._do_evaluation: + self._logger.info("Annotations are not available for evaluation.") + return + + self._logger.info("Evaluating bbox proposals ...") + res = {} + areas = {"all": "", "small": "s", "medium": "m", "large": "l"} + for limit in [100, 1000]: + for area, suffix in areas.items(): + stats = _evaluate_box_proposals(predictions, self._coco_api, area=area, limit=limit) + key = "AR{}@{:d}".format(suffix, limit) + res[key] = float(stats["ar"].item() * 100) + self._logger.info("Proposal metrics: \n" + create_small_table(res)) + self._results["box_proposals"] = res + + def _derive_coco_results(self, coco_eval, iou_type, class_names=None): + """ + Derive the desired score numbers from summarized COCOeval. + + Args: + coco_eval (None or COCOEval): None represents no predictions from model. + iou_type (str): + class_names (None or list[str]): if provided, will use it to predict + per-category AP. + + Returns: + a dict of {metric name: score} + """ + + metrics = { + "bbox": ["AP", "AP50", "AP75", "APs", "APm", "APl"], + "keypoints": ["AP", "AP50", "AP75", "APm", "APl"], + }[iou_type] + + if coco_eval is None: + self._logger.warn("No predictions from the model!") + return {metric: float("nan") for metric in metrics} + + # the standard metrics + results = { + metric: float(coco_eval.stats[idx] * 100 if coco_eval.stats[idx] >= 0 else "nan") + for idx, metric in enumerate(metrics) + } + self._logger.info( + "Evaluation results for {}: \n".format(iou_type) + create_small_table(results) + ) + if not np.isfinite(sum(results.values())): + self._logger.info("Some metrics cannot be computed and is shown as NaN.") + + if class_names is None or len(class_names) <= 1: + return results + # Compute per-category AP + # from https://github.com/facebookresearch/Detectron/blob/a6a835f5b8208c45d0dce217ce9bbda915f44df7/detectron/datasets/json_dataset_evaluator.py#L222-L252 # noqa + precisions = coco_eval.eval["precision"] + # precision has dims (iou, recall, cls, area range, max dets) + assert len(class_names) == precisions.shape[2] + + results_per_category = [] + for idx, name in enumerate(class_names): + # area range index 0: all area ranges + # max dets index -1: typically 100 per image + precision = precisions[:, :, idx, 0, -1] + precision = precision[precision > -1] + ap = np.mean(precision) if precision.size else float("nan") + results_per_category.append(("{}".format(name), float(ap * 100))) + + # tabulate it + N_COLS = min(6, len(results_per_category) * 2) + results_flatten = list(itertools.chain(*results_per_category)) + results_2d = itertools.zip_longest(*[results_flatten[i::N_COLS] for i in range(N_COLS)]) + table = tabulate( + results_2d, + tablefmt="pipe", + floatfmt=".3f", + headers=["category", "AP"] * (N_COLS // 2), + numalign="left", + ) + self._logger.info("Per-category {} AP: \n".format(iou_type) + table) + + results.update({"AP-" + name: ap for name, ap in results_per_category}) + return results + + +def instances_to_coco_json(instances, img_id): + """ + Dump an "Instances" object to a COCO-format json that's used for evaluation. + + Args: + instances (Instances): + img_id (int): the image id + + Returns: + list[dict]: list of json annotations in COCO format. + """ + num_instance = len(instances) + if num_instance == 0: + return [] + + boxes = instances.pred_boxes.tensor.numpy() + boxes = BoxMode.convert(boxes, BoxMode.XYXY_ABS, BoxMode.XYWH_ABS) + boxes = boxes.tolist() + scores = instances.scores.tolist() + classes = instances.pred_classes.tolist() + + has_mask = instances.has("pred_masks") + if has_mask: + # use RLE to encode the masks, because they are too large and takes memory + # since this evaluator stores outputs of the entire dataset + rles = [ + mask_util.encode(np.array(mask[:, :, None], order="F", dtype="uint8"))[0] + for mask in instances.pred_masks + ] + for rle in rles: + # "counts" is an array encoded by mask_util as a byte-stream. Python3's + # json writer which always produces strings cannot serialize a bytestream + # unless you decode it. Thankfully, utf-8 works out (which is also what + # the annotator.oneformer.pycocotools/_mask.pyx does). + rle["counts"] = rle["counts"].decode("utf-8") + + has_keypoints = instances.has("pred_keypoints") + if has_keypoints: + keypoints = instances.pred_keypoints + + results = [] + for k in range(num_instance): + result = { + "image_id": img_id, + "category_id": classes[k], + "bbox": boxes[k], + "score": scores[k], + } + if has_mask: + result["segmentation"] = rles[k] + if has_keypoints: + # In COCO annotations, + # keypoints coordinates are pixel indices. + # However our predictions are floating point coordinates. + # Therefore we subtract 0.5 to be consistent with the annotation format. + # This is the inverse of data loading logic in `datasets/coco.py`. + keypoints[k][:, :2] -= 0.5 + result["keypoints"] = keypoints[k].flatten().tolist() + results.append(result) + return results + + +# inspired from Detectron: +# https://github.com/facebookresearch/Detectron/blob/a6a835f5b8208c45d0dce217ce9bbda915f44df7/detectron/datasets/json_dataset_evaluator.py#L255 # noqa +def _evaluate_box_proposals(dataset_predictions, coco_api, thresholds=None, area="all", limit=None): + """ + Evaluate detection proposal recall metrics. This function is a much + faster alternative to the official COCO API recall evaluation code. However, + it produces slightly different results. + """ + # Record max overlap value for each gt box + # Return vector of overlap values + areas = { + "all": 0, + "small": 1, + "medium": 2, + "large": 3, + "96-128": 4, + "128-256": 5, + "256-512": 6, + "512-inf": 7, + } + area_ranges = [ + [0**2, 1e5**2], # all + [0**2, 32**2], # small + [32**2, 96**2], # medium + [96**2, 1e5**2], # large + [96**2, 128**2], # 96-128 + [128**2, 256**2], # 128-256 + [256**2, 512**2], # 256-512 + [512**2, 1e5**2], + ] # 512-inf + assert area in areas, "Unknown area range: {}".format(area) + area_range = area_ranges[areas[area]] + gt_overlaps = [] + num_pos = 0 + + for prediction_dict in dataset_predictions: + predictions = prediction_dict["proposals"] + + # sort predictions in descending order + # TODO maybe remove this and make it explicit in the documentation + inds = predictions.objectness_logits.sort(descending=True)[1] + predictions = predictions[inds] + + ann_ids = coco_api.getAnnIds(imgIds=prediction_dict["image_id"]) + anno = coco_api.loadAnns(ann_ids) + gt_boxes = [ + BoxMode.convert(obj["bbox"], BoxMode.XYWH_ABS, BoxMode.XYXY_ABS) + for obj in anno + if obj["iscrowd"] == 0 + ] + gt_boxes = torch.as_tensor(gt_boxes).reshape(-1, 4) # guard against no boxes + gt_boxes = Boxes(gt_boxes) + gt_areas = torch.as_tensor([obj["area"] for obj in anno if obj["iscrowd"] == 0]) + + if len(gt_boxes) == 0 or len(predictions) == 0: + continue + + valid_gt_inds = (gt_areas >= area_range[0]) & (gt_areas <= area_range[1]) + gt_boxes = gt_boxes[valid_gt_inds] + + num_pos += len(gt_boxes) + + if len(gt_boxes) == 0: + continue + + if limit is not None and len(predictions) > limit: + predictions = predictions[:limit] + + overlaps = pairwise_iou(predictions.proposal_boxes, gt_boxes) + + _gt_overlaps = torch.zeros(len(gt_boxes)) + for j in range(min(len(predictions), len(gt_boxes))): + # find which proposal box maximally covers each gt box + # and get the iou amount of coverage for each gt box + max_overlaps, argmax_overlaps = overlaps.max(dim=0) + + # find which gt box is 'best' covered (i.e. 'best' = most iou) + gt_ovr, gt_ind = max_overlaps.max(dim=0) + assert gt_ovr >= 0 + # find the proposal box that covers the best covered gt box + box_ind = argmax_overlaps[gt_ind] + # record the iou coverage of this gt box + _gt_overlaps[j] = overlaps[box_ind, gt_ind] + assert _gt_overlaps[j] == gt_ovr + # mark the proposal box and the gt box as used + overlaps[box_ind, :] = -1 + overlaps[:, gt_ind] = -1 + + # append recorded iou coverage level + gt_overlaps.append(_gt_overlaps) + gt_overlaps = ( + torch.cat(gt_overlaps, dim=0) if len(gt_overlaps) else torch.zeros(0, dtype=torch.float32) + ) + gt_overlaps, _ = torch.sort(gt_overlaps) + + if thresholds is None: + step = 0.05 + thresholds = torch.arange(0.5, 0.95 + 1e-5, step, dtype=torch.float32) + recalls = torch.zeros_like(thresholds) + # compute recall for each iou threshold + for i, t in enumerate(thresholds): + recalls[i] = (gt_overlaps >= t).float().sum() / float(num_pos) + # ar = 2 * np.trapz(recalls, thresholds) + ar = recalls.mean() + return { + "ar": ar, + "recalls": recalls, + "thresholds": thresholds, + "gt_overlaps": gt_overlaps, + "num_pos": num_pos, + } + + +def _evaluate_predictions_on_coco( + coco_gt, + coco_results, + iou_type, + kpt_oks_sigmas=None, + use_fast_impl=True, + img_ids=None, + max_dets_per_image=None, +): + """ + Evaluate the coco results using COCOEval API. + """ + assert len(coco_results) > 0 + + if iou_type == "segm": + coco_results = copy.deepcopy(coco_results) + # When evaluating mask AP, if the results contain bbox, cocoapi will + # use the box area as the area of the instance, instead of the mask area. + # This leads to a different definition of small/medium/large. + # We remove the bbox field to let mask AP use mask area. + for c in coco_results: + c.pop("bbox", None) + + coco_dt = coco_gt.loadRes(coco_results) + coco_eval = (COCOeval_opt if use_fast_impl else COCOeval)(coco_gt, coco_dt, iou_type) + # For COCO, the default max_dets_per_image is [1, 10, 100]. + if max_dets_per_image is None: + max_dets_per_image = [1, 10, 100] # Default from COCOEval + else: + assert ( + len(max_dets_per_image) >= 3 + ), "COCOeval requires maxDets (and max_dets_per_image) to have length at least 3" + # In the case that user supplies a custom input for max_dets_per_image, + # apply COCOevalMaxDets to evaluate AP with the custom input. + if max_dets_per_image[2] != 100: + coco_eval = COCOevalMaxDets(coco_gt, coco_dt, iou_type) + if iou_type != "keypoints": + coco_eval.params.maxDets = max_dets_per_image + + if img_ids is not None: + coco_eval.params.imgIds = img_ids + + if iou_type == "keypoints": + # Use the COCO default keypoint OKS sigmas unless overrides are specified + if kpt_oks_sigmas: + assert hasattr(coco_eval.params, "kpt_oks_sigmas"), "annotator.oneformer.pycocotools is too old!" + coco_eval.params.kpt_oks_sigmas = np.array(kpt_oks_sigmas) + # COCOAPI requires every detection and every gt to have keypoints, so + # we just take the first entry from both + num_keypoints_dt = len(coco_results[0]["keypoints"]) // 3 + num_keypoints_gt = len(next(iter(coco_gt.anns.values()))["keypoints"]) // 3 + num_keypoints_oks = len(coco_eval.params.kpt_oks_sigmas) + assert num_keypoints_oks == num_keypoints_dt == num_keypoints_gt, ( + f"[COCOEvaluator] Prediction contain {num_keypoints_dt} keypoints. " + f"Ground truth contains {num_keypoints_gt} keypoints. " + f"The length of cfg.TEST.KEYPOINT_OKS_SIGMAS is {num_keypoints_oks}. " + "They have to agree with each other. For meaning of OKS, please refer to " + "http://cocodataset.org/#keypoints-eval." + ) + + coco_eval.evaluate() + coco_eval.accumulate() + coco_eval.summarize() + + return coco_eval + + +class COCOevalMaxDets(COCOeval): + """ + Modified version of COCOeval for evaluating AP with a custom + maxDets (by default for COCO, maxDets is 100) + """ + + def summarize(self): + """ + Compute and display summary metrics for evaluation results given + a custom value for max_dets_per_image + """ + + def _summarize(ap=1, iouThr=None, areaRng="all", maxDets=100): + p = self.params + iStr = " {:<18} {} @[ IoU={:<9} | area={:>6s} | maxDets={:>3d} ] = {:0.3f}" + titleStr = "Average Precision" if ap == 1 else "Average Recall" + typeStr = "(AP)" if ap == 1 else "(AR)" + iouStr = ( + "{:0.2f}:{:0.2f}".format(p.iouThrs[0], p.iouThrs[-1]) + if iouThr is None + else "{:0.2f}".format(iouThr) + ) + + aind = [i for i, aRng in enumerate(p.areaRngLbl) if aRng == areaRng] + mind = [i for i, mDet in enumerate(p.maxDets) if mDet == maxDets] + if ap == 1: + # dimension of precision: [TxRxKxAxM] + s = self.eval["precision"] + # IoU + if iouThr is not None: + t = np.where(iouThr == p.iouThrs)[0] + s = s[t] + s = s[:, :, :, aind, mind] + else: + # dimension of recall: [TxKxAxM] + s = self.eval["recall"] + if iouThr is not None: + t = np.where(iouThr == p.iouThrs)[0] + s = s[t] + s = s[:, :, aind, mind] + if len(s[s > -1]) == 0: + mean_s = -1 + else: + mean_s = np.mean(s[s > -1]) + print(iStr.format(titleStr, typeStr, iouStr, areaRng, maxDets, mean_s)) + return mean_s + + def _summarizeDets(): + stats = np.zeros((12,)) + # Evaluate AP using the custom limit on maximum detections per image + stats[0] = _summarize(1, maxDets=self.params.maxDets[2]) + stats[1] = _summarize(1, iouThr=0.5, maxDets=self.params.maxDets[2]) + stats[2] = _summarize(1, iouThr=0.75, maxDets=self.params.maxDets[2]) + stats[3] = _summarize(1, areaRng="small", maxDets=self.params.maxDets[2]) + stats[4] = _summarize(1, areaRng="medium", maxDets=self.params.maxDets[2]) + stats[5] = _summarize(1, areaRng="large", maxDets=self.params.maxDets[2]) + stats[6] = _summarize(0, maxDets=self.params.maxDets[0]) + stats[7] = _summarize(0, maxDets=self.params.maxDets[1]) + stats[8] = _summarize(0, maxDets=self.params.maxDets[2]) + stats[9] = _summarize(0, areaRng="small", maxDets=self.params.maxDets[2]) + stats[10] = _summarize(0, areaRng="medium", maxDets=self.params.maxDets[2]) + stats[11] = _summarize(0, areaRng="large", maxDets=self.params.maxDets[2]) + return stats + + def _summarizeKps(): + stats = np.zeros((10,)) + stats[0] = _summarize(1, maxDets=20) + stats[1] = _summarize(1, maxDets=20, iouThr=0.5) + stats[2] = _summarize(1, maxDets=20, iouThr=0.75) + stats[3] = _summarize(1, maxDets=20, areaRng="medium") + stats[4] = _summarize(1, maxDets=20, areaRng="large") + stats[5] = _summarize(0, maxDets=20) + stats[6] = _summarize(0, maxDets=20, iouThr=0.5) + stats[7] = _summarize(0, maxDets=20, iouThr=0.75) + stats[8] = _summarize(0, maxDets=20, areaRng="medium") + stats[9] = _summarize(0, maxDets=20, areaRng="large") + return stats + + if not self.eval: + raise Exception("Please run accumulate() first") + iouType = self.params.iouType + if iouType == "segm" or iouType == "bbox": + summarize = _summarizeDets + elif iouType == "keypoints": + summarize = _summarizeKps + self.stats = summarize() + + def __str__(self): + self.summarize() \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/evaluator.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/evaluator.py new file mode 100644 index 00000000..2c85d90e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/evaluator.py @@ -0,0 +1,228 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/detectron2/blob/main/detectron2/evaluation/evaluator.py +# Modified by Jitesh Jain (https://github.com/praeclarumjj3) +# ------------------------------------------------------------------------------ + +import datetime +import logging +import time +from collections import OrderedDict, abc +from contextlib import ExitStack, contextmanager +from typing import List, Union +import torch +from torch import nn + +from annotator.oneformer.detectron2.utils.comm import get_world_size, is_main_process +from annotator.oneformer.detectron2.utils.logger import log_every_n_seconds + + +class DatasetEvaluator: + """ + Base class for a dataset evaluator. + + The function :func:`inference_on_dataset` runs the model over + all samples in the dataset, and have a DatasetEvaluator to process the inputs/outputs. + + This class will accumulate information of the inputs/outputs (by :meth:`process`), + and produce evaluation results in the end (by :meth:`evaluate`). + """ + + def reset(self): + """ + Preparation for a new round of evaluation. + Should be called before starting a round of evaluation. + """ + pass + + def process(self, inputs, outputs): + """ + Process the pair of inputs and outputs. + If they contain batches, the pairs can be consumed one-by-one using `zip`: + + .. code-block:: python + + for input_, output in zip(inputs, outputs): + # do evaluation on single input/output pair + ... + + Args: + inputs (list): the inputs that's used to call the model. + outputs (list): the return value of `model(inputs)` + """ + pass + + def evaluate(self): + """ + Evaluate/summarize the performance, after processing all input/output pairs. + + Returns: + dict: + A new evaluator class can return a dict of arbitrary format + as long as the user can process the results. + In our train_net.py, we expect the following format: + + * key: the name of the task (e.g., bbox) + * value: a dict of {metric name: score}, e.g.: {"AP50": 80} + """ + pass + + +class DatasetEvaluators(DatasetEvaluator): + """ + Wrapper class to combine multiple :class:`DatasetEvaluator` instances. + + This class dispatches every evaluation call to + all of its :class:`DatasetEvaluator`. + """ + + def __init__(self, evaluators): + """ + Args: + evaluators (list): the evaluators to combine. + """ + super().__init__() + self._evaluators = evaluators + + def reset(self): + for evaluator in self._evaluators: + evaluator.reset() + + def process(self, inputs, outputs): + for evaluator in self._evaluators: + evaluator.process(inputs, outputs) + + def evaluate(self): + results = OrderedDict() + for evaluator in self._evaluators: + result = evaluator.evaluate() + if is_main_process() and result is not None: + for k, v in result.items(): + assert ( + k not in results + ), "Different evaluators produce results with the same key {}".format(k) + results[k] = v + return results + + +def inference_on_dataset( + model, data_loader, evaluator: Union[DatasetEvaluator, List[DatasetEvaluator], None] +): + """ + Run model on the data_loader and evaluate the metrics with evaluator. + Also benchmark the inference speed of `model.__call__` accurately. + The model will be used in eval mode. + + Args: + model (callable): a callable which takes an object from + `data_loader` and returns some outputs. + + If it's an nn.Module, it will be temporarily set to `eval` mode. + If you wish to evaluate a model in `training` mode instead, you can + wrap the given model and override its behavior of `.eval()` and `.train()`. + data_loader: an iterable object with a length. + The elements it generates will be the inputs to the model. + evaluator: the evaluator(s) to run. Use `None` if you only want to benchmark, + but don't want to do any evaluation. + + Returns: + The return value of `evaluator.evaluate()` + """ + num_devices = get_world_size() + logger = logging.getLogger(__name__) + logger.info("Start inference on {} batches".format(len(data_loader))) + + total = len(data_loader) # inference data loader must have a fixed length + if evaluator is None: + # create a no-op evaluator + evaluator = DatasetEvaluators([]) + if isinstance(evaluator, abc.MutableSequence): + evaluator = DatasetEvaluators(evaluator) + evaluator.reset() + + num_warmup = min(5, total - 1) + start_time = time.perf_counter() + total_data_time = 0 + total_compute_time = 0 + total_eval_time = 0 + with ExitStack() as stack: + if isinstance(model, nn.Module): + stack.enter_context(inference_context(model)) + stack.enter_context(torch.no_grad()) + + start_data_time = time.perf_counter() + for idx, inputs in enumerate(data_loader): + total_data_time += time.perf_counter() - start_data_time + if idx == num_warmup: + start_time = time.perf_counter() + total_data_time = 0 + total_compute_time = 0 + total_eval_time = 0 + + start_compute_time = time.perf_counter() + outputs = model(inputs) + if torch.cuda.is_available(): + torch.cuda.synchronize() + total_compute_time += time.perf_counter() - start_compute_time + + start_eval_time = time.perf_counter() + evaluator.process(inputs, outputs) + total_eval_time += time.perf_counter() - start_eval_time + + iters_after_start = idx + 1 - num_warmup * int(idx >= num_warmup) + data_seconds_per_iter = total_data_time / iters_after_start + compute_seconds_per_iter = total_compute_time / iters_after_start + eval_seconds_per_iter = total_eval_time / iters_after_start + total_seconds_per_iter = (time.perf_counter() - start_time) / iters_after_start + if idx >= num_warmup * 2 or compute_seconds_per_iter > 5: + eta = datetime.timedelta(seconds=int(total_seconds_per_iter * (total - idx - 1))) + log_every_n_seconds( + logging.INFO, + ( + f"Inference done {idx + 1}/{total}. " + f"Dataloading: {data_seconds_per_iter:.4f} s/iter. " + f"Inference: {compute_seconds_per_iter:.4f} s/iter. " + f"Eval: {eval_seconds_per_iter:.4f} s/iter. " + f"Total: {total_seconds_per_iter:.4f} s/iter. " + f"ETA={eta}" + ), + n=5, + ) + start_data_time = time.perf_counter() + + # Measure the time only for this worker (before the synchronization barrier) + total_time = time.perf_counter() - start_time + total_time_str = str(datetime.timedelta(seconds=total_time)) + # NOTE this format is parsed by grep + logger.info( + "Total inference time: {} ({:.6f} s / iter per device, on {} devices)".format( + total_time_str, total_time / (total - num_warmup), num_devices + ) + ) + total_compute_time_str = str(datetime.timedelta(seconds=int(total_compute_time))) + logger.info( + "Total inference pure compute time: {} ({:.6f} s / iter per device, on {} devices)".format( + total_compute_time_str, total_compute_time / (total - num_warmup), num_devices + ) + ) + + results = evaluator.evaluate() + # An evaluator may return None when not in main process. + # Replace it by an empty dict instead to make it easier for downstream code to handle + if results is None: + results = {} + return results + + +@contextmanager +def inference_context(model): + """ + A context where the model is temporarily changed to eval mode, + and restored to previous mode afterwards. + + Args: + model: a torch Module + """ + training_mode = model.training + model.eval() + yield + model.train(training_mode) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/instance_evaluation.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/instance_evaluation.py new file mode 100644 index 00000000..12ce1d72 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/evaluation/instance_evaluation.py @@ -0,0 +1,110 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/Mask2Former/blob/main/mask2former/evaluation/instance_evaluation.py +# ------------------------------------------------------------------------------ + +import contextlib +import copy +import io +import itertools +import json +import logging +import numpy as np +import os +import pickle +from collections import OrderedDict +import annotator.oneformer.pycocotools.mask as mask_util +import torch +from annotator.oneformer.pycocotools.coco import COCO +from annotator.oneformer.pycocotools.cocoeval import COCOeval +from tabulate import tabulate + +import annotator.oneformer.detectron2.utils.comm as comm +from annotator.oneformer.detectron2.config import CfgNode +from annotator.oneformer.detectron2.data import MetadataCatalog +from annotator.oneformer.detectron2.data.datasets.coco import convert_to_coco_json +from annotator.oneformer.detectron2.evaluation.coco_evaluation import COCOEvaluator, _evaluate_predictions_on_coco +from annotator.oneformer.detectron2.evaluation.fast_eval_api import COCOeval_opt +from annotator.oneformer.detectron2.structures import Boxes, BoxMode, pairwise_iou +from annotator.oneformer.detectron2.utils.file_io import PathManager +from annotator.oneformer.detectron2.utils.logger import create_small_table + + +# modified from COCOEvaluator for instance segmetnat +class InstanceSegEvaluator(COCOEvaluator): + """ + Evaluate AR for object proposals, AP for instance detection/segmentation, AP + for keypoint detection outputs using COCO's metrics. + See http://cocodataset.org/#detection-eval and + http://cocodataset.org/#keypoints-eval to understand its metrics. + The metrics range from 0 to 100 (instead of 0 to 1), where a -1 or NaN means + the metric cannot be computed (e.g. due to no predictions made). + + In addition to COCO, this evaluator is able to support any bounding box detection, + instance segmentation, or keypoint detection dataset. + """ + + def _eval_predictions(self, predictions, img_ids=None): + """ + Evaluate predictions. Fill self._results with the metrics of the tasks. + """ + self._logger.info("Preparing results for COCO format ...") + coco_results = list(itertools.chain(*[x["instances"] for x in predictions])) + tasks = self._tasks or self._tasks_from_predictions(coco_results) + + # unmap the category ids for COCO + if hasattr(self._metadata, "thing_dataset_id_to_contiguous_id"): + dataset_id_to_contiguous_id = self._metadata.thing_dataset_id_to_contiguous_id + # all_contiguous_ids = list(dataset_id_to_contiguous_id.values()) + # num_classes = len(all_contiguous_ids) + # assert min(all_contiguous_ids) == 0 and max(all_contiguous_ids) == num_classes - 1 + + reverse_id_mapping = {v: k for k, v in dataset_id_to_contiguous_id.items()} + for result in coco_results: + category_id = result["category_id"] + # assert category_id < num_classes, ( + # f"A prediction has class={category_id}, " + # f"but the dataset only has {num_classes} classes and " + # f"predicted class id should be in [0, {num_classes - 1}]." + # ) + assert category_id in reverse_id_mapping, ( + f"A prediction has class={category_id}, " + f"but the dataset only has class ids in {dataset_id_to_contiguous_id}." + ) + result["category_id"] = reverse_id_mapping[category_id] + + if self._output_dir: + file_path = os.path.join(self._output_dir, "coco_instances_results.json") + self._logger.info("Saving results to {}".format(file_path)) + with PathManager.open(file_path, "w") as f: + f.write(json.dumps(coco_results)) + f.flush() + + if not self._do_evaluation: + self._logger.info("Annotations are not available for evaluation.") + return + + self._logger.info( + "Evaluating predictions with {} COCO API...".format( + "unofficial" if self._use_fast_impl else "official" + ) + ) + for task in sorted(tasks): + assert task in {"bbox", "segm", "keypoints"}, f"Got unknown task: {task}!" + coco_eval = ( + _evaluate_predictions_on_coco( + self._coco_api, + coco_results, + task, + kpt_oks_sigmas=self._kpt_oks_sigmas, + use_fast_impl=self._use_fast_impl, + img_ids=img_ids, + max_dets_per_image=self._max_dets_per_image, + ) + if len(coco_results) > 0 + else None # cocoapi does not handle empty results very well + ) + + res = self._derive_coco_results( + coco_eval, task, class_names=self._metadata.get("thing_classes") + ) + self._results[task] = res diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/__init__.py new file mode 100644 index 00000000..4e133836 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/__init__.py @@ -0,0 +1,5 @@ +from .backbone.swin import D2SwinTransformer +from .backbone.dinat import D2DiNAT +from .pixel_decoder.fpn import BasePixelDecoder +from .pixel_decoder.msdeformattn import MSDeformAttnPixelDecoder +from .meta_arch.oneformer_head import OneFormerHead diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/backbone/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/backbone/__init__.py new file mode 100644 index 00000000..9020c2df --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/backbone/__init__.py @@ -0,0 +1 @@ +# Copyright (c) Facebook, Inc. and its affiliates. diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/backbone/dinat.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/backbone/dinat.py new file mode 100644 index 00000000..17027574 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/backbone/dinat.py @@ -0,0 +1,324 @@ +# -------------------------------------------------------- +# Neighborhood Attention Transformer +# Licensed under The MIT License +# Written by Ali Hassani +# -------------------------------------------------------- + +# Modified by Jitesh Jain + +import torch +import torch.nn as nn +from timm.models.layers import DropPath +from annotator.oneformer.detectron2.modeling import BACKBONE_REGISTRY, Backbone, ShapeSpec + +class NeighborhoodAttention(nn.Module): + """ + Neighborhood Attention 2D Module + """ + + def __init__( + self, + dim, + num_heads, + kernel_size, + dilation=1, + bias=True, + qkv_bias=True, + qk_scale=None, + attn_drop=0.0, + proj_drop=0.0, + ): + super().__init__() + + + def forward(self, x): + + return x + + def extra_repr(self) -> str: + return ( + f"head_dim={self.head_dim}, num_heads={self.num_heads}, " + + f"kernel_size={self.kernel_size}, dilation={self.dilation}, " + + f"rel_pos_bias={self.rpb is not None}" + ) + +class ConvTokenizer(nn.Module): + def __init__(self, in_chans=3, embed_dim=96, norm_layer=None): + super().__init__() + self.proj = nn.Sequential( + nn.Conv2d(in_chans, embed_dim // 2, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1)), + nn.Conv2d(embed_dim // 2, embed_dim, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1)), + ) + if norm_layer is not None: + self.norm = norm_layer(embed_dim) + else: + self.norm = None + + def forward(self, x): + x = self.proj(x).permute(0, 2, 3, 1) + if self.norm is not None: + x = self.norm(x) + return x + + +class ConvDownsampler(nn.Module): + def __init__(self, dim, norm_layer=nn.LayerNorm): + super().__init__() + self.reduction = nn.Conv2d(dim, 2 * dim, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False) + self.norm = norm_layer(2 * dim) + + def forward(self, x): + x = self.reduction(x.permute(0, 3, 1, 2)).permute(0, 2, 3, 1) + x = self.norm(x) + return x + + +class Mlp(nn.Module): + def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.): + super().__init__() + out_features = out_features or in_features + hidden_features = hidden_features or in_features + self.fc1 = nn.Linear(in_features, hidden_features) + self.act = act_layer() + self.fc2 = nn.Linear(hidden_features, out_features) + self.drop = nn.Dropout(drop) + + def forward(self, x): + x = self.fc1(x) + x = self.act(x) + x = self.drop(x) + x = self.fc2(x) + x = self.drop(x) + return x + + +class NATLayer(nn.Module): + def __init__(self, dim, num_heads, kernel_size=7, dilation=None, + mlp_ratio=4., qkv_bias=True, qk_scale=None, drop=0., attn_drop=0., drop_path=0., + act_layer=nn.GELU, norm_layer=nn.LayerNorm, layer_scale=None): + super().__init__() + self.dim = dim + self.num_heads = num_heads + self.mlp_ratio = mlp_ratio + + self.norm1 = norm_layer(dim) + self.attn = NeighborhoodAttention( + dim, kernel_size=kernel_size, dilation=dilation, num_heads=num_heads, + qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop) + + self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity() + self.norm2 = norm_layer(dim) + self.mlp = Mlp(in_features=dim, hidden_features=int(dim * mlp_ratio), act_layer=act_layer, drop=drop) + self.layer_scale = False + if layer_scale is not None and type(layer_scale) in [int, float]: + self.layer_scale = True + self.gamma1 = nn.Parameter(layer_scale * torch.ones(dim), requires_grad=True) + self.gamma2 = nn.Parameter(layer_scale * torch.ones(dim), requires_grad=True) + + def forward(self, x): + if not self.layer_scale: + shortcut = x + x = self.norm1(x) + x = self.attn(x) + x = shortcut + self.drop_path(x) + x = x + self.drop_path(self.mlp(self.norm2(x))) + return x + shortcut = x + x = self.norm1(x) + x = self.attn(x) + x = shortcut + self.drop_path(self.gamma1 * x) + x = x + self.drop_path(self.gamma2 * self.mlp(self.norm2(x))) + return x + + + +class NATBlock(nn.Module): + def __init__(self, dim, depth, num_heads, kernel_size, dilations=None, + downsample=True, + mlp_ratio=4., qkv_bias=True, qk_scale=None, drop=0., attn_drop=0., + drop_path=0., norm_layer=nn.LayerNorm, layer_scale=None): + super().__init__() + self.dim = dim + self.depth = depth + + self.blocks = nn.ModuleList([ + NATLayer(dim=dim, + num_heads=num_heads, + kernel_size=kernel_size, + dilation=None if dilations is None else dilations[i], + mlp_ratio=mlp_ratio, + qkv_bias=qkv_bias, qk_scale=qk_scale, + drop=drop, attn_drop=attn_drop, + drop_path=drop_path[i] if isinstance(drop_path, list) else drop_path, + norm_layer=norm_layer, + layer_scale=layer_scale) + for i in range(depth)]) + + self.downsample = None if not downsample else ConvDownsampler(dim=dim, norm_layer=norm_layer) + + def forward(self, x): + for blk in self.blocks: + x = blk(x) + if self.downsample is None: + return x, x + return self.downsample(x), x + + +class DiNAT(nn.Module): + def __init__(self, + embed_dim, + mlp_ratio, + depths, + num_heads, + drop_path_rate=0.2, + in_chans=3, + kernel_size=7, + dilations=None, + out_indices=(0, 1, 2, 3), + qkv_bias=True, + qk_scale=None, + drop_rate=0., + attn_drop_rate=0., + norm_layer=nn.LayerNorm, + frozen_stages=-1, + layer_scale=None, + **kwargs): + super().__init__() + self.num_levels = len(depths) + self.embed_dim = embed_dim + self.num_features = [int(embed_dim * 2 ** i) for i in range(self.num_levels)] + self.mlp_ratio = mlp_ratio + + self.patch_embed = ConvTokenizer(in_chans=in_chans, embed_dim=embed_dim, norm_layer=norm_layer) + + self.pos_drop = nn.Dropout(p=drop_rate) + + dpr = [x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))] + self.levels = nn.ModuleList() + for i in range(self.num_levels): + level = NATBlock(dim=int(embed_dim * 2 ** i), + depth=depths[i], + num_heads=num_heads[i], + kernel_size=kernel_size, + dilations=None if dilations is None else dilations[i], + mlp_ratio=self.mlp_ratio, + qkv_bias=qkv_bias, qk_scale=qk_scale, + drop=drop_rate, attn_drop=attn_drop_rate, + drop_path=dpr[sum(depths[:i]):sum(depths[:i + 1])], + norm_layer=norm_layer, + downsample=(i < self.num_levels - 1), + layer_scale=layer_scale) + self.levels.append(level) + + # add a norm layer for each output + self.out_indices = out_indices + for i_layer in self.out_indices: + layer = norm_layer(self.num_features[i_layer]) + layer_name = f'norm{i_layer}' + self.add_module(layer_name, layer) + + self.frozen_stages = frozen_stages + + def _freeze_stages(self): + if self.frozen_stages >= 0: + self.patch_embed.eval() + for param in self.patch_embed.parameters(): + param.requires_grad = False + + if self.frozen_stages >= 2: + for i in range(0, self.frozen_stages - 1): + m = self.network[i] + m.eval() + for param in m.parameters(): + param.requires_grad = False + + def train(self, mode=True): + super(DiNAT, self).train(mode) + self._freeze_stages() + + def forward_embeddings(self, x): + x = self.patch_embed(x) + return x + + def forward_tokens(self, x): + outs = {} + for idx, level in enumerate(self.levels): + x, xo = level(x) + if idx in self.out_indices: + norm_layer = getattr(self, f'norm{idx}') + x_out = norm_layer(xo) + outs["res{}".format(idx + 2)] = x_out.permute(0, 3, 1, 2).contiguous() + return outs + + def forward(self, x): + x = self.forward_embeddings(x) + return self.forward_tokens(x) + + +@BACKBONE_REGISTRY.register() +class D2DiNAT(DiNAT, Backbone): + def __init__(self, cfg, input_shape): + + embed_dim = cfg.MODEL.DiNAT.EMBED_DIM + mlp_ratio = cfg.MODEL.DiNAT.MLP_RATIO + depths = cfg.MODEL.DiNAT.DEPTHS + num_heads = cfg.MODEL.DiNAT.NUM_HEADS + drop_path_rate = cfg.MODEL.DiNAT.DROP_PATH_RATE + kernel_size = cfg.MODEL.DiNAT.KERNEL_SIZE + out_indices = cfg.MODEL.DiNAT.OUT_INDICES + dilations = cfg.MODEL.DiNAT.DILATIONS + + super().__init__( + embed_dim=embed_dim, + mlp_ratio=mlp_ratio, + depths=depths, + num_heads=num_heads, + drop_path_rate=drop_path_rate, + kernel_size=kernel_size, + out_indices=out_indices, + dilations=dilations, + ) + + self._out_features = cfg.MODEL.DiNAT.OUT_FEATURES + + self._out_feature_strides = { + "res2": 4, + "res3": 8, + "res4": 16, + "res5": 32, + } + self._out_feature_channels = { + "res2": self.num_features[0], + "res3": self.num_features[1], + "res4": self.num_features[2], + "res5": self.num_features[3], + } + + def forward(self, x): + """ + Args: + x: Tensor of shape (N,C,H,W). H, W must be a multiple of ``self.size_divisibility``. + Returns: + dict[str->Tensor]: names and the corresponding features + """ + assert ( + x.dim() == 4 + ), f"DiNAT takes an input of shape (N, C, H, W). Got {x.shape} instead!" + outputs = {} + y = super().forward(x) + for k in y.keys(): + if k in self._out_features: + outputs[k] = y[k] + return outputs + + def output_shape(self): + return { + name: ShapeSpec( + channels=self._out_feature_channels[name], stride=self._out_feature_strides[name] + ) + for name in self._out_features + } + + @property + def size_divisibility(self): + return 32 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/backbone/swin.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/backbone/swin.py new file mode 100644 index 00000000..2380cde5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/backbone/swin.py @@ -0,0 +1,771 @@ +# -------------------------------------------------------- +# Swin Transformer +# Copyright (c) 2021 Microsoft +# Licensed under The MIT License [see LICENSE for details] +# Written by Ze Liu, Yutong Lin, Yixuan Wei +# -------------------------------------------------------- + +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/Mask2Former +# ------------------------------------------------------------------------------ + +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.checkpoint as checkpoint +from timm.models.layers import DropPath, to_2tuple, trunc_normal_ + +from annotator.oneformer.detectron2.modeling import BACKBONE_REGISTRY, Backbone, ShapeSpec + + +class Mlp(nn.Module): + """Multilayer perceptron.""" + + def __init__( + self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.0 + ): + super().__init__() + out_features = out_features or in_features + hidden_features = hidden_features or in_features + self.fc1 = nn.Linear(in_features, hidden_features) + self.act = act_layer() + self.fc2 = nn.Linear(hidden_features, out_features) + self.drop = nn.Dropout(drop) + + def forward(self, x): + x = self.fc1(x) + x = self.act(x) + x = self.drop(x) + x = self.fc2(x) + x = self.drop(x) + return x + + +def window_partition(x, window_size): + """ + Args: + x: (B, H, W, C) + window_size (int): window size + Returns: + windows: (num_windows*B, window_size, window_size, C) + """ + B, H, W, C = x.shape + x = x.view(B, H // window_size, window_size, W // window_size, window_size, C) + windows = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(-1, window_size, window_size, C) + return windows + + +def window_reverse(windows, window_size, H, W): + """ + Args: + windows: (num_windows*B, window_size, window_size, C) + window_size (int): Window size + H (int): Height of image + W (int): Width of image + Returns: + x: (B, H, W, C) + """ + B = int(windows.shape[0] / (H * W / window_size / window_size)) + x = windows.view(B, H // window_size, W // window_size, window_size, window_size, -1) + x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, H, W, -1) + return x + + +class WindowAttention(nn.Module): + """Window based multi-head self attention (W-MSA) module with relative position bias. + It supports both of shifted and non-shifted window. + Args: + dim (int): Number of input channels. + window_size (tuple[int]): The height and width of the window. + num_heads (int): Number of attention heads. + qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True + qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set + attn_drop (float, optional): Dropout ratio of attention weight. Default: 0.0 + proj_drop (float, optional): Dropout ratio of output. Default: 0.0 + """ + + def __init__( + self, + dim, + window_size, + num_heads, + qkv_bias=True, + qk_scale=None, + attn_drop=0.0, + proj_drop=0.0, + ): + + super().__init__() + self.dim = dim + self.window_size = window_size # Wh, Ww + self.num_heads = num_heads + head_dim = dim // num_heads + self.scale = qk_scale or head_dim ** -0.5 + + # define a parameter table of relative position bias + self.relative_position_bias_table = nn.Parameter( + torch.zeros((2 * window_size[0] - 1) * (2 * window_size[1] - 1), num_heads) + ) # 2*Wh-1 * 2*Ww-1, nH + + # get pair-wise relative position index for each token inside the window + coords_h = torch.arange(self.window_size[0]) + coords_w = torch.arange(self.window_size[1]) + coords = torch.stack(torch.meshgrid([coords_h, coords_w])) # 2, Wh, Ww + coords_flatten = torch.flatten(coords, 1) # 2, Wh*Ww + relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] # 2, Wh*Ww, Wh*Ww + relative_coords = relative_coords.permute(1, 2, 0).contiguous() # Wh*Ww, Wh*Ww, 2 + relative_coords[:, :, 0] += self.window_size[0] - 1 # shift to start from 0 + relative_coords[:, :, 1] += self.window_size[1] - 1 + relative_coords[:, :, 0] *= 2 * self.window_size[1] - 1 + relative_position_index = relative_coords.sum(-1) # Wh*Ww, Wh*Ww + self.register_buffer("relative_position_index", relative_position_index) + + self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias) + self.attn_drop = nn.Dropout(attn_drop) + self.proj = nn.Linear(dim, dim) + self.proj_drop = nn.Dropout(proj_drop) + + trunc_normal_(self.relative_position_bias_table, std=0.02) + self.softmax = nn.Softmax(dim=-1) + + def forward(self, x, mask=None): + """Forward function. + Args: + x: input features with shape of (num_windows*B, N, C) + mask: (0/-inf) mask with shape of (num_windows, Wh*Ww, Wh*Ww) or None + """ + B_, N, C = x.shape + qkv = ( + self.qkv(x) + .reshape(B_, N, 3, self.num_heads, C // self.num_heads) + .permute(2, 0, 3, 1, 4) + ) + q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple) + + q = q * self.scale + attn = q @ k.transpose(-2, -1) + + relative_position_bias = self.relative_position_bias_table[ + self.relative_position_index.view(-1) + ].view( + self.window_size[0] * self.window_size[1], self.window_size[0] * self.window_size[1], -1 + ) # Wh*Ww,Wh*Ww,nH + relative_position_bias = relative_position_bias.permute( + 2, 0, 1 + ).contiguous() # nH, Wh*Ww, Wh*Ww + attn = attn + relative_position_bias.unsqueeze(0) + + if mask is not None: + nW = mask.shape[0] + attn = attn.view(B_ // nW, nW, self.num_heads, N, N) + mask.unsqueeze(1).unsqueeze(0) + attn = attn.view(-1, self.num_heads, N, N) + attn = self.softmax(attn) + else: + attn = self.softmax(attn) + + attn = self.attn_drop(attn) + + x = (attn @ v).transpose(1, 2).reshape(B_, N, C) + x = self.proj(x) + x = self.proj_drop(x) + return x + + +class SwinTransformerBlock(nn.Module): + """Swin Transformer Block. + Args: + dim (int): Number of input channels. + num_heads (int): Number of attention heads. + window_size (int): Window size. + shift_size (int): Shift size for SW-MSA. + mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. + qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True + qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set. + drop (float, optional): Dropout rate. Default: 0.0 + attn_drop (float, optional): Attention dropout rate. Default: 0.0 + drop_path (float, optional): Stochastic depth rate. Default: 0.0 + act_layer (nn.Module, optional): Activation layer. Default: nn.GELU + norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm + """ + + def __init__( + self, + dim, + num_heads, + window_size=7, + shift_size=0, + mlp_ratio=4.0, + qkv_bias=True, + qk_scale=None, + drop=0.0, + attn_drop=0.0, + drop_path=0.0, + act_layer=nn.GELU, + norm_layer=nn.LayerNorm, + ): + super().__init__() + self.dim = dim + self.num_heads = num_heads + self.window_size = window_size + self.shift_size = shift_size + self.mlp_ratio = mlp_ratio + assert 0 <= self.shift_size < self.window_size, "shift_size must in 0-window_size" + + self.norm1 = norm_layer(dim) + self.attn = WindowAttention( + dim, + window_size=to_2tuple(self.window_size), + num_heads=num_heads, + qkv_bias=qkv_bias, + qk_scale=qk_scale, + attn_drop=attn_drop, + proj_drop=drop, + ) + + self.drop_path = DropPath(drop_path) if drop_path > 0.0 else nn.Identity() + self.norm2 = norm_layer(dim) + mlp_hidden_dim = int(dim * mlp_ratio) + self.mlp = Mlp( + in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop + ) + + self.H = None + self.W = None + + def forward(self, x, mask_matrix): + """Forward function. + Args: + x: Input feature, tensor size (B, H*W, C). + H, W: Spatial resolution of the input feature. + mask_matrix: Attention mask for cyclic shift. + """ + B, L, C = x.shape + H, W = self.H, self.W + assert L == H * W, "input feature has wrong size" + + shortcut = x + x = self.norm1(x) + x = x.view(B, H, W, C) + + # pad feature maps to multiples of window size + pad_l = pad_t = 0 + pad_r = (self.window_size - W % self.window_size) % self.window_size + pad_b = (self.window_size - H % self.window_size) % self.window_size + x = F.pad(x, (0, 0, pad_l, pad_r, pad_t, pad_b)) + _, Hp, Wp, _ = x.shape + + # cyclic shift + if self.shift_size > 0: + shifted_x = torch.roll(x, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2)) + attn_mask = mask_matrix + else: + shifted_x = x + attn_mask = None + + # partition windows + x_windows = window_partition( + shifted_x, self.window_size + ) # nW*B, window_size, window_size, C + x_windows = x_windows.view( + -1, self.window_size * self.window_size, C + ) # nW*B, window_size*window_size, C + + # W-MSA/SW-MSA + attn_windows = self.attn(x_windows, mask=attn_mask) # nW*B, window_size*window_size, C + + # merge windows + attn_windows = attn_windows.view(-1, self.window_size, self.window_size, C) + shifted_x = window_reverse(attn_windows, self.window_size, Hp, Wp) # B H' W' C + + # reverse cyclic shift + if self.shift_size > 0: + x = torch.roll(shifted_x, shifts=(self.shift_size, self.shift_size), dims=(1, 2)) + else: + x = shifted_x + + if pad_r > 0 or pad_b > 0: + x = x[:, :H, :W, :].contiguous() + + x = x.view(B, H * W, C) + + # FFN + x = shortcut + self.drop_path(x) + x = x + self.drop_path(self.mlp(self.norm2(x))) + + return x + + +class PatchMerging(nn.Module): + """Patch Merging Layer + Args: + dim (int): Number of input channels. + norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm + """ + + def __init__(self, dim, norm_layer=nn.LayerNorm): + super().__init__() + self.dim = dim + self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False) + self.norm = norm_layer(4 * dim) + + def forward(self, x, H, W): + """Forward function. + Args: + x: Input feature, tensor size (B, H*W, C). + H, W: Spatial resolution of the input feature. + """ + B, L, C = x.shape + assert L == H * W, "input feature has wrong size" + + x = x.view(B, H, W, C) + + # padding + pad_input = (H % 2 == 1) or (W % 2 == 1) + if pad_input: + x = F.pad(x, (0, 0, 0, W % 2, 0, H % 2)) + + x0 = x[:, 0::2, 0::2, :] # B H/2 W/2 C + x1 = x[:, 1::2, 0::2, :] # B H/2 W/2 C + x2 = x[:, 0::2, 1::2, :] # B H/2 W/2 C + x3 = x[:, 1::2, 1::2, :] # B H/2 W/2 C + x = torch.cat([x0, x1, x2, x3], -1) # B H/2 W/2 4*C + x = x.view(B, -1, 4 * C) # B H/2*W/2 4*C + + x = self.norm(x) + x = self.reduction(x) + + return x + + +class BasicLayer(nn.Module): + """A basic Swin Transformer layer for one stage. + Args: + dim (int): Number of feature channels + depth (int): Depths of this stage. + num_heads (int): Number of attention head. + window_size (int): Local window size. Default: 7. + mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. Default: 4. + qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True + qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set. + drop (float, optional): Dropout rate. Default: 0.0 + attn_drop (float, optional): Attention dropout rate. Default: 0.0 + drop_path (float | tuple[float], optional): Stochastic depth rate. Default: 0.0 + norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm + downsample (nn.Module | None, optional): Downsample layer at the end of the layer. Default: None + use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False. + """ + + def __init__( + self, + dim, + depth, + num_heads, + window_size=7, + mlp_ratio=4.0, + qkv_bias=True, + qk_scale=None, + drop=0.0, + attn_drop=0.0, + drop_path=0.0, + norm_layer=nn.LayerNorm, + downsample=None, + use_checkpoint=False, + ): + super().__init__() + self.window_size = window_size + self.shift_size = window_size // 2 + self.depth = depth + self.use_checkpoint = use_checkpoint + + # build blocks + self.blocks = nn.ModuleList( + [ + SwinTransformerBlock( + dim=dim, + num_heads=num_heads, + window_size=window_size, + shift_size=0 if (i % 2 == 0) else window_size // 2, + mlp_ratio=mlp_ratio, + qkv_bias=qkv_bias, + qk_scale=qk_scale, + drop=drop, + attn_drop=attn_drop, + drop_path=drop_path[i] if isinstance(drop_path, list) else drop_path, + norm_layer=norm_layer, + ) + for i in range(depth) + ] + ) + + # patch merging layer + if downsample is not None: + self.downsample = downsample(dim=dim, norm_layer=norm_layer) + else: + self.downsample = None + + def forward(self, x, H, W): + """Forward function. + Args: + x: Input feature, tensor size (B, H*W, C). + H, W: Spatial resolution of the input feature. + """ + + # calculate attention mask for SW-MSA + Hp = int(np.ceil(H / self.window_size)) * self.window_size + Wp = int(np.ceil(W / self.window_size)) * self.window_size + img_mask = torch.zeros((1, Hp, Wp, 1), device=x.device) # 1 Hp Wp 1 + h_slices = ( + slice(0, -self.window_size), + slice(-self.window_size, -self.shift_size), + slice(-self.shift_size, None), + ) + w_slices = ( + slice(0, -self.window_size), + slice(-self.window_size, -self.shift_size), + slice(-self.shift_size, None), + ) + cnt = 0 + for h in h_slices: + for w in w_slices: + img_mask[:, h, w, :] = cnt + cnt += 1 + + mask_windows = window_partition( + img_mask, self.window_size + ) # nW, window_size, window_size, 1 + mask_windows = mask_windows.view(-1, self.window_size * self.window_size) + attn_mask = mask_windows.unsqueeze(1) - mask_windows.unsqueeze(2) + attn_mask = attn_mask.masked_fill(attn_mask != 0, float(-100.0)).masked_fill( + attn_mask == 0, float(0.0) + ) + + for blk in self.blocks: + blk.H, blk.W = H, W + if self.use_checkpoint: + x = checkpoint.checkpoint(blk, x, attn_mask) + else: + x = blk(x, attn_mask) + if self.downsample is not None: + x_down = self.downsample(x, H, W) + Wh, Ww = (H + 1) // 2, (W + 1) // 2 + return x, H, W, x_down, Wh, Ww + else: + return x, H, W, x, H, W + + +class PatchEmbed(nn.Module): + """Image to Patch Embedding + Args: + patch_size (int): Patch token size. Default: 4. + in_chans (int): Number of input image channels. Default: 3. + embed_dim (int): Number of linear projection output channels. Default: 96. + norm_layer (nn.Module, optional): Normalization layer. Default: None + """ + + def __init__(self, patch_size=4, in_chans=3, embed_dim=96, norm_layer=None): + super().__init__() + patch_size = to_2tuple(patch_size) + self.patch_size = patch_size + + self.in_chans = in_chans + self.embed_dim = embed_dim + + self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size) + if norm_layer is not None: + self.norm = norm_layer(embed_dim) + else: + self.norm = None + + def forward(self, x): + """Forward function.""" + # padding + _, _, H, W = x.size() + if W % self.patch_size[1] != 0: + x = F.pad(x, (0, self.patch_size[1] - W % self.patch_size[1])) + if H % self.patch_size[0] != 0: + x = F.pad(x, (0, 0, 0, self.patch_size[0] - H % self.patch_size[0])) + + x = self.proj(x) # B C Wh Ww + if self.norm is not None: + Wh, Ww = x.size(2), x.size(3) + x = x.flatten(2).transpose(1, 2) + x = self.norm(x) + x = x.transpose(1, 2).view(-1, self.embed_dim, Wh, Ww) + + return x + + +class SwinTransformer(nn.Module): + """Swin Transformer backbone. + A PyTorch impl of : `Swin Transformer: Hierarchical Vision Transformer using Shifted Windows` - + https://arxiv.org/pdf/2103.14030 + Args: + pretrain_img_size (int): Input image size for training the pretrained model, + used in absolute postion embedding. Default 224. + patch_size (int | tuple(int)): Patch size. Default: 4. + in_chans (int): Number of input image channels. Default: 3. + embed_dim (int): Number of linear projection output channels. Default: 96. + depths (tuple[int]): Depths of each Swin Transformer stage. + num_heads (tuple[int]): Number of attention head of each stage. + window_size (int): Window size. Default: 7. + mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. Default: 4. + qkv_bias (bool): If True, add a learnable bias to query, key, value. Default: True + qk_scale (float): Override default qk scale of head_dim ** -0.5 if set. + drop_rate (float): Dropout rate. + attn_drop_rate (float): Attention dropout rate. Default: 0. + drop_path_rate (float): Stochastic depth rate. Default: 0.2. + norm_layer (nn.Module): Normalization layer. Default: nn.LayerNorm. + ape (bool): If True, add absolute position embedding to the patch embedding. Default: False. + patch_norm (bool): If True, add normalization after patch embedding. Default: True. + out_indices (Sequence[int]): Output from which stages. + frozen_stages (int): Stages to be frozen (stop grad and set eval mode). + -1 means not freezing any parameters. + use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False. + """ + + def __init__( + self, + pretrain_img_size=224, + patch_size=4, + in_chans=3, + embed_dim=96, + depths=[2, 2, 6, 2], + num_heads=[3, 6, 12, 24], + window_size=7, + mlp_ratio=4.0, + qkv_bias=True, + qk_scale=None, + drop_rate=0.0, + attn_drop_rate=0.0, + drop_path_rate=0.2, + norm_layer=nn.LayerNorm, + ape=False, + patch_norm=True, + out_indices=(0, 1, 2, 3), + frozen_stages=-1, + use_checkpoint=False, + ): + super().__init__() + + self.pretrain_img_size = pretrain_img_size + self.num_layers = len(depths) + self.embed_dim = embed_dim + self.ape = ape + self.patch_norm = patch_norm + self.out_indices = out_indices + self.frozen_stages = frozen_stages + + # split image into non-overlapping patches + self.patch_embed = PatchEmbed( + patch_size=patch_size, + in_chans=in_chans, + embed_dim=embed_dim, + norm_layer=norm_layer if self.patch_norm else None, + ) + + # absolute position embedding + if self.ape: + pretrain_img_size = to_2tuple(pretrain_img_size) + patch_size = to_2tuple(patch_size) + patches_resolution = [ + pretrain_img_size[0] // patch_size[0], + pretrain_img_size[1] // patch_size[1], + ] + + self.absolute_pos_embed = nn.Parameter( + torch.zeros(1, embed_dim, patches_resolution[0], patches_resolution[1]) + ) + trunc_normal_(self.absolute_pos_embed, std=0.02) + + self.pos_drop = nn.Dropout(p=drop_rate) + + # stochastic depth + dpr = [ + x.item() for x in torch.linspace(0, drop_path_rate, sum(depths)) + ] # stochastic depth decay rule + + # build layers + self.layers = nn.ModuleList() + for i_layer in range(self.num_layers): + layer = BasicLayer( + dim=int(embed_dim * 2 ** i_layer), + depth=depths[i_layer], + num_heads=num_heads[i_layer], + window_size=window_size, + mlp_ratio=mlp_ratio, + qkv_bias=qkv_bias, + qk_scale=qk_scale, + drop=drop_rate, + attn_drop=attn_drop_rate, + drop_path=dpr[sum(depths[:i_layer]) : sum(depths[: i_layer + 1])], + norm_layer=norm_layer, + downsample=PatchMerging if (i_layer < self.num_layers - 1) else None, + use_checkpoint=use_checkpoint, + ) + self.layers.append(layer) + + num_features = [int(embed_dim * 2 ** i) for i in range(self.num_layers)] + self.num_features = num_features + + # add a norm layer for each output + for i_layer in out_indices: + layer = norm_layer(num_features[i_layer]) + layer_name = f"norm{i_layer}" + self.add_module(layer_name, layer) + + self._freeze_stages() + + def _freeze_stages(self): + if self.frozen_stages >= 0: + self.patch_embed.eval() + for param in self.patch_embed.parameters(): + param.requires_grad = False + + if self.frozen_stages >= 1 and self.ape: + self.absolute_pos_embed.requires_grad = False + + if self.frozen_stages >= 2: + self.pos_drop.eval() + for i in range(0, self.frozen_stages - 1): + m = self.layers[i] + m.eval() + for param in m.parameters(): + param.requires_grad = False + + def init_weights(self, pretrained=None): + """Initialize the weights in backbone. + Args: + pretrained (str, optional): Path to pre-trained weights. + Defaults to None. + """ + + def _init_weights(m): + if isinstance(m, nn.Linear): + trunc_normal_(m.weight, std=0.02) + if isinstance(m, nn.Linear) and m.bias is not None: + nn.init.constant_(m.bias, 0) + elif isinstance(m, nn.LayerNorm): + nn.init.constant_(m.bias, 0) + nn.init.constant_(m.weight, 1.0) + + def forward(self, x): + """Forward function.""" + x = self.patch_embed(x) + + Wh, Ww = x.size(2), x.size(3) + if self.ape: + # interpolate the position embedding to the corresponding size + absolute_pos_embed = F.interpolate( + self.absolute_pos_embed, size=(Wh, Ww), mode="bicubic" + ) + x = (x + absolute_pos_embed).flatten(2).transpose(1, 2) # B Wh*Ww C + else: + x = x.flatten(2).transpose(1, 2) + x = self.pos_drop(x) + + outs = {} + for i in range(self.num_layers): + layer = self.layers[i] + x_out, H, W, x, Wh, Ww = layer(x, Wh, Ww) + + if i in self.out_indices: + norm_layer = getattr(self, f"norm{i}") + x_out = norm_layer(x_out) + + out = x_out.view(-1, H, W, self.num_features[i]).permute(0, 3, 1, 2).contiguous() + outs["res{}".format(i + 2)] = out + + return outs + + def train(self, mode=True): + """Convert the model into training mode while keep layers freezed.""" + super(SwinTransformer, self).train(mode) + self._freeze_stages() + + +@BACKBONE_REGISTRY.register() +class D2SwinTransformer(SwinTransformer, Backbone): + def __init__(self, cfg, input_shape): + + pretrain_img_size = cfg.MODEL.SWIN.PRETRAIN_IMG_SIZE + patch_size = cfg.MODEL.SWIN.PATCH_SIZE + in_chans = 3 + embed_dim = cfg.MODEL.SWIN.EMBED_DIM + depths = cfg.MODEL.SWIN.DEPTHS + num_heads = cfg.MODEL.SWIN.NUM_HEADS + window_size = cfg.MODEL.SWIN.WINDOW_SIZE + mlp_ratio = cfg.MODEL.SWIN.MLP_RATIO + qkv_bias = cfg.MODEL.SWIN.QKV_BIAS + qk_scale = cfg.MODEL.SWIN.QK_SCALE + drop_rate = cfg.MODEL.SWIN.DROP_RATE + attn_drop_rate = cfg.MODEL.SWIN.ATTN_DROP_RATE + drop_path_rate = cfg.MODEL.SWIN.DROP_PATH_RATE + norm_layer = nn.LayerNorm + ape = cfg.MODEL.SWIN.APE + patch_norm = cfg.MODEL.SWIN.PATCH_NORM + use_checkpoint = cfg.MODEL.SWIN.USE_CHECKPOINT + + super().__init__( + pretrain_img_size, + patch_size, + in_chans, + embed_dim, + depths, + num_heads, + window_size, + mlp_ratio, + qkv_bias, + qk_scale, + drop_rate, + attn_drop_rate, + drop_path_rate, + norm_layer, + ape, + patch_norm, + use_checkpoint=use_checkpoint, + ) + + self._out_features = cfg.MODEL.SWIN.OUT_FEATURES + + self._out_feature_strides = { + "res2": 4, + "res3": 8, + "res4": 16, + "res5": 32, + } + self._out_feature_channels = { + "res2": self.num_features[0], + "res3": self.num_features[1], + "res4": self.num_features[2], + "res5": self.num_features[3], + } + + def forward(self, x): + """ + Args: + x: Tensor of shape (N,C,H,W). H, W must be a multiple of ``self.size_divisibility``. + Returns: + dict[str->Tensor]: names and the corresponding features + """ + assert ( + x.dim() == 4 + ), f"SwinTransformer takes an input of shape (N, C, H, W). Got {x.shape} instead!" + outputs = {} + y = super().forward(x) + for k in y.keys(): + if k in self._out_features: + outputs[k] = y[k] + return outputs + + def output_shape(self): + return { + name: ShapeSpec( + channels=self._out_feature_channels[name], stride=self._out_feature_strides[name] + ) + for name in self._out_features + } + + @property + def size_divisibility(self): + return 32 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/matcher.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/matcher.py new file mode 100644 index 00000000..4dba337a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/matcher.py @@ -0,0 +1,212 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/Mask2Former/blob/main/mask2former/modeling/matcher.py +# Modified by Jitesh Jain (https://github.com/praeclarumjj3) +# ------------------------------------------------------------------------------ + +""" +Modules to compute the matching cost and solve the corresponding LSAP. +""" +import torch +import torch.nn.functional as F +from scipy.optimize import linear_sum_assignment +from torch import nn +from torch.cuda.amp import autocast +import numpy as np + +# from annotator.oneformer.detectron2.projects.point_rend.point_features import point_sample + + +def linear_sum_assignment_with_nan(cost_matrix): + cost_matrix = np.asarray(cost_matrix) + nan = np.isnan(cost_matrix).any() + nan_all = np.isnan(cost_matrix).all() + empty = cost_matrix.size == 0 + + if not empty: + if nan_all: + print('Matrix contains all NaN values!') + elif nan: + print('Matrix contains NaN values!') + + if nan_all: + cost_matrix = np.empty(shape=(0, 0)) + elif nan: + cost_matrix[np.isnan(cost_matrix)] = 100 + + return linear_sum_assignment(cost_matrix) + +def batch_dice_loss(inputs: torch.Tensor, targets: torch.Tensor): + """ + Compute the DICE loss, similar to generalized IOU for masks + Args: + inputs: A float tensor of arbitrary shape. + The predictions for each example. + targets: A float tensor with the same shape as inputs. Stores the binary + classification label for each element in inputs + (0 for the negative class and 1 for the positive class). + """ + inputs = inputs.sigmoid() + inputs = inputs.flatten(1) + numerator = 2 * torch.einsum("nc,mc->nm", inputs, targets) + denominator = inputs.sum(-1)[:, None] + targets.sum(-1)[None, :] + loss = 1 - (numerator + 1) / (denominator + 1) + return loss + + +batch_dice_loss_jit = torch.jit.script( + batch_dice_loss +) # type: torch.jit.ScriptModule + + +def batch_sigmoid_ce_loss(inputs: torch.Tensor, targets: torch.Tensor): + """ + Args: + inputs: A float tensor of arbitrary shape. + The predictions for each example. + targets: A float tensor with the same shape as inputs. Stores the binary + classification label for each element in inputs + (0 for the negative class and 1 for the positive class). + Returns: + Loss tensor + """ + hw = inputs.shape[1] + + pos = F.binary_cross_entropy_with_logits( + inputs, torch.ones_like(inputs), reduction="none" + ) + neg = F.binary_cross_entropy_with_logits( + inputs, torch.zeros_like(inputs), reduction="none" + ) + + loss = torch.einsum("nc,mc->nm", pos, targets) + torch.einsum( + "nc,mc->nm", neg, (1 - targets) + ) + + return loss / hw + + +batch_sigmoid_ce_loss_jit = torch.jit.script( + batch_sigmoid_ce_loss +) # type: torch.jit.ScriptModule + + +class HungarianMatcher(nn.Module): + """This class computes an assignment between the targets and the predictions of the network + + For efficiency reasons, the targets don't include the no_object. Because of this, in general, + there are more predictions than targets. In this case, we do a 1-to-1 matching of the best predictions, + while the others are un-matched (and thus treated as non-objects). + """ + + def __init__(self, cost_class: float = 1, cost_mask: float = 1, + cost_dice: float = 1, num_points: int = 0): + """Creates the matcher + + Params: + cost_class: This is the relative weight of the classification error in the matching cost + cost_mask: This is the relative weight of the focal loss of the binary mask in the matching cost + cost_dice: This is the relative weight of the dice loss of the binary mask in the matching cost + """ + super().__init__() + self.cost_class = cost_class + self.cost_mask = cost_mask + self.cost_dice = cost_dice + + assert cost_class != 0 or cost_mask != 0 or cost_dice != 0, "all costs cant be 0" + + self.num_points = num_points + + @torch.no_grad() + def memory_efficient_forward(self, outputs, targets): + """More memory-friendly matching""" + bs, num_queries = outputs["pred_logits"].shape[:2] + + indices = [] + + # Iterate through batch size + for b in range(bs): + out_prob = outputs["pred_logits"][b].softmax(-1) # [num_queries, num_classes] + tgt_ids = targets[b]["labels"] + + # Compute the classification cost. Contrary to the loss, we don't use the NLL, + # but approximate it in 1 - proba[target class]. + # The 1 is a constant that doesn't change the matching, it can be ommitted. + cost_class = -out_prob[:, tgt_ids] + + out_mask = outputs["pred_masks"][b] # [num_queries, H_pred, W_pred] + # gt masks are already padded when preparing target + tgt_mask = targets[b]["masks"].to(out_mask) + + out_mask = out_mask[:, None] + tgt_mask = tgt_mask[:, None] + # all masks share the same set of points for efficient matching! + point_coords = torch.rand(1, self.num_points, 2, device=out_mask.device) + # get gt labels + tgt_mask = point_sample( + tgt_mask, + point_coords.repeat(tgt_mask.shape[0], 1, 1), + align_corners=False, + ).squeeze(1) + + out_mask = point_sample( + out_mask, + point_coords.repeat(out_mask.shape[0], 1, 1), + align_corners=False, + ).squeeze(1) + + with autocast(enabled=False): + out_mask = out_mask.float() + tgt_mask = tgt_mask.float() + # Compute the focal loss between masks + cost_mask = batch_sigmoid_ce_loss_jit(out_mask, tgt_mask) + # Compute the dice loss betwen masks + cost_dice = batch_dice_loss(out_mask, tgt_mask) + + # Final cost matrix + C = ( + self.cost_mask * cost_mask + + self.cost_class * cost_class + + self.cost_dice * cost_dice + ) + C = C.reshape(num_queries, -1).cpu() + + indices.append(linear_sum_assignment_with_nan(C)) + + return [ + (torch.as_tensor(i, dtype=torch.int64), torch.as_tensor(j, dtype=torch.int64)) + for i, j in indices + ] + + @torch.no_grad() + def forward(self, outputs, targets): + """Performs the matching + + Params: + outputs: This is a dict that contains at least these entries: + "pred_logits": Tensor of dim [batch_size, num_queries, num_classes] with the classification logits + "pred_masks": Tensor of dim [batch_size, num_queries, H_pred, W_pred] with the predicted masks + + targets: This is a list of targets (len(targets) = batch_size), where each target is a dict containing: + "labels": Tensor of dim [num_target_boxes] (where num_target_boxes is the number of ground-truth + objects in the target) containing the class labels + "masks": Tensor of dim [num_target_boxes, H_gt, W_gt] containing the target masks + + Returns: + A list of size batch_size, containing tuples of (index_i, index_j) where: + - index_i is the indices of the selected predictions (in order) + - index_j is the indices of the corresponding selected targets (in order) + For each batch element, it holds: + len(index_i) = len(index_j) = min(num_queries, num_target_boxes) + """ + + return self.memory_efficient_forward(outputs, targets) + + def __repr__(self, _repr_indent=4): + head = "Matcher " + self.__class__.__name__ + body = [ + "cost_class: {}".format(self.cost_class), + "cost_mask: {}".format(self.cost_mask), + "cost_dice: {}".format(self.cost_dice), + ] + lines = [head] + [" " * _repr_indent + line for line in body] + return "\n".join(lines) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/meta_arch/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/meta_arch/__init__.py new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/meta_arch/__init__.py @@ -0,0 +1 @@ + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/meta_arch/oneformer_head.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/meta_arch/oneformer_head.py new file mode 100644 index 00000000..f8f8eb11 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/meta_arch/oneformer_head.py @@ -0,0 +1,135 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/Mask2Former/blob/main/mask2former/modeling/meta_arch/mask_former_head.py +# Modified by Jitesh Jain (https://github.com/praeclarumjj3) +# ------------------------------------------------------------------------------ + +import logging +from copy import deepcopy +from typing import Callable, Dict, List, Optional, Tuple, Union + +import fvcore.nn.weight_init as weight_init +from torch import nn +from torch.nn import functional as F + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.layers import Conv2d, ShapeSpec, get_norm +from annotator.oneformer.detectron2.modeling import SEM_SEG_HEADS_REGISTRY +from ..pixel_decoder.fpn import build_pixel_decoder +from ..transformer_decoder.oneformer_transformer_decoder import build_transformer_decoder + +@SEM_SEG_HEADS_REGISTRY.register() +class OneFormerHead(nn.Module): + + _version = 2 + + def _load_from_state_dict( + self, state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs + ): + version = local_metadata.get("version", None) + if version is None or version < 2: + # Do not warn if train from scratch + scratch = True + logger = logging.getLogger(__name__) + for k in list(state_dict.keys()): + newk = k + if "sem_seg_head" in k and not k.startswith(prefix + "predictor"): + newk = k.replace(prefix, prefix + "pixel_decoder.") + # logger.debug(f"{k} ==> {newk}") + if newk != k: + state_dict[newk] = state_dict[k] + del state_dict[k] + scratch = False + + if not scratch: + logger.warning( + f"Weight format of {self.__class__.__name__} have changed! " + "Please upgrade your models. Applying automatic conversion now ..." + ) + + @configurable + def __init__( + self, + input_shape: Dict[str, ShapeSpec], + *, + num_classes: int, + pixel_decoder: nn.Module, + loss_weight: float = 1.0, + ignore_value: int = -1, + # extra parameters + transformer_predictor: nn.Module, + transformer_in_feature: str, + ): + """ + NOTE: this interface is experimental. + Args: + input_shape: shapes (channels and stride) of the input features + num_classes: number of classes to predict + pixel_decoder: the pixel decoder module + loss_weight: loss weight + ignore_value: category id to be ignored during training. + transformer_predictor: the transformer decoder that makes prediction + transformer_in_feature: input feature name to the transformer_predictor + """ + super().__init__() + input_shape = sorted(input_shape.items(), key=lambda x: x[1].stride) + self.in_features = [k for k, v in input_shape] + feature_strides = [v.stride for k, v in input_shape] + feature_channels = [v.channels for k, v in input_shape] + + self.ignore_value = ignore_value + self.common_stride = 4 + self.loss_weight = loss_weight + + self.pixel_decoder = pixel_decoder + self.predictor = transformer_predictor + self.transformer_in_feature = transformer_in_feature + + self.num_classes = num_classes + + @classmethod + def from_config(cls, cfg, input_shape: Dict[str, ShapeSpec]): + # figure out in_channels to transformer predictor + if cfg.MODEL.ONE_FORMER.TRANSFORMER_IN_FEATURE == "transformer_encoder": + transformer_predictor_in_channels = cfg.MODEL.SEM_SEG_HEAD.CONVS_DIM + elif cfg.MODEL.ONE_FORMER.TRANSFORMER_IN_FEATURE == "pixel_embedding": + transformer_predictor_in_channels = cfg.MODEL.SEM_SEG_HEAD.MASK_DIM + elif cfg.MODEL.ONE_FORMER.TRANSFORMER_IN_FEATURE == "multi_scale_pixel_decoder": + transformer_predictor_in_channels = cfg.MODEL.SEM_SEG_HEAD.CONVS_DIM + else: + transformer_predictor_in_channels = input_shape[cfg.MODEL.ONE_FORMER.TRANSFORMER_IN_FEATURE].channels + + return { + "input_shape": { + k: v for k, v in input_shape.items() if k in cfg.MODEL.SEM_SEG_HEAD.IN_FEATURES + }, + "ignore_value": cfg.MODEL.SEM_SEG_HEAD.IGNORE_VALUE, + "num_classes": cfg.MODEL.SEM_SEG_HEAD.NUM_CLASSES, + "pixel_decoder": build_pixel_decoder(cfg, input_shape), + "loss_weight": cfg.MODEL.SEM_SEG_HEAD.LOSS_WEIGHT, + "transformer_in_feature": cfg.MODEL.ONE_FORMER.TRANSFORMER_IN_FEATURE, + "transformer_predictor": build_transformer_decoder( + cfg, + transformer_predictor_in_channels, + mask_classification=True, + ), + } + + def forward(self, features, tasks, mask=None): + return self.layers(features, tasks, mask) + + def layers(self, features, tasks, mask=None): + mask_features, transformer_encoder_features, multi_scale_features, _, _ = self.pixel_decoder.forward_features(features) + + if self.transformer_in_feature == "multi_scale_pixel_decoder": + predictions = self.predictor(multi_scale_features, mask_features, tasks, mask) + else: + if self.transformer_in_feature == "transformer_encoder": + assert ( + transformer_encoder_features is not None + ), "Please use the TransformerEncoderPixelDecoder." + predictions = self.predictor(transformer_encoder_features, mask_features, mask) + elif self.transformer_in_feature == "pixel_embedding": + predictions = self.predictor(mask_features, mask_features, mask) + else: + predictions = self.predictor(features[self.transformer_in_feature], mask_features, mask) + return predictions diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/__init__.py new file mode 100644 index 00000000..9020c2df --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/__init__.py @@ -0,0 +1 @@ +# Copyright (c) Facebook, Inc. and its affiliates. diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/fpn.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/fpn.py new file mode 100644 index 00000000..0f724775 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/fpn.py @@ -0,0 +1,312 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import logging +import numpy as np +from typing import Callable, Dict, List, Optional, Tuple, Union + +import fvcore.nn.weight_init as weight_init +import torch +from torch import nn +from torch.nn import functional as F +from torch.nn.init import xavier_uniform_, constant_, uniform_, normal_ +from torch.cuda.amp import autocast + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.layers import Conv2d, DeformConv, ShapeSpec, get_norm +from annotator.oneformer.detectron2.modeling import SEM_SEG_HEADS_REGISTRY + +from ..transformer_decoder.position_encoding import PositionEmbeddingSine +from ..transformer_decoder.transformer import TransformerEncoder, TransformerEncoderLayer, _get_clones, _get_activation_fn + + +def build_pixel_decoder(cfg, input_shape): + """ + Build a pixel decoder from `cfg.MODEL.MASK_FORMER.PIXEL_DECODER_NAME`. + """ + name = cfg.MODEL.SEM_SEG_HEAD.PIXEL_DECODER_NAME + model = SEM_SEG_HEADS_REGISTRY.get(name)(cfg, input_shape) + forward_features = getattr(model, "forward_features", None) + if not callable(forward_features): + raise ValueError( + "Only SEM_SEG_HEADS with forward_features method can be used as pixel decoder. " + f"Please implement forward_features for {name} to only return mask features." + ) + return model + + +# This is a modified FPN decoder. +@SEM_SEG_HEADS_REGISTRY.register() +class BasePixelDecoder(nn.Module): + @configurable + def __init__( + self, + input_shape: Dict[str, ShapeSpec], + *, + conv_dim: int, + mask_dim: int, + norm: Optional[Union[str, Callable]] = None, + ): + """ + NOTE: this interface is experimental. + Args: + input_shape: shapes (channels and stride) of the input features + conv_dims: number of output channels for the intermediate conv layers. + mask_dim: number of output channels for the final conv layer. + norm (str or callable): normalization for all conv layers + """ + super().__init__() + + input_shape = sorted(input_shape.items(), key=lambda x: x[1].stride) + self.in_features = [k for k, v in input_shape] # starting from "res2" to "res5" + feature_channels = [v.channels for k, v in input_shape] + + lateral_convs = [] + output_convs = [] + + use_bias = norm == "" + for idx, in_channels in enumerate(feature_channels): + if idx == len(self.in_features) - 1: + output_norm = get_norm(norm, conv_dim) + output_conv = Conv2d( + in_channels, + conv_dim, + kernel_size=3, + stride=1, + padding=1, + bias=use_bias, + norm=output_norm, + activation=F.relu, + ) + weight_init.c2_xavier_fill(output_conv) + self.add_module("layer_{}".format(idx + 1), output_conv) + + lateral_convs.append(None) + output_convs.append(output_conv) + else: + lateral_norm = get_norm(norm, conv_dim) + output_norm = get_norm(norm, conv_dim) + + lateral_conv = Conv2d( + in_channels, conv_dim, kernel_size=1, bias=use_bias, norm=lateral_norm + ) + output_conv = Conv2d( + conv_dim, + conv_dim, + kernel_size=3, + stride=1, + padding=1, + bias=use_bias, + norm=output_norm, + activation=F.relu, + ) + weight_init.c2_xavier_fill(lateral_conv) + weight_init.c2_xavier_fill(output_conv) + self.add_module("adapter_{}".format(idx + 1), lateral_conv) + self.add_module("layer_{}".format(idx + 1), output_conv) + + lateral_convs.append(lateral_conv) + output_convs.append(output_conv) + # Place convs into top-down order (from low to high resolution) + # to make the top-down computation in forward clearer. + self.lateral_convs = lateral_convs[::-1] + self.output_convs = output_convs[::-1] + + self.mask_dim = mask_dim + self.mask_features = Conv2d( + conv_dim, + mask_dim, + kernel_size=3, + stride=1, + padding=1, + ) + weight_init.c2_xavier_fill(self.mask_features) + + self.oneformer_num_feature_levels = 3 # always use 3 scales + + @classmethod + def from_config(cls, cfg, input_shape: Dict[str, ShapeSpec]): + ret = {} + ret["input_shape"] = { + k: v for k, v in input_shape.items() if k in cfg.MODEL.SEM_SEG_HEAD.IN_FEATURES + } + ret["conv_dim"] = cfg.MODEL.SEM_SEG_HEAD.CONVS_DIM + ret["mask_dim"] = cfg.MODEL.SEM_SEG_HEAD.MASK_DIM + ret["norm"] = cfg.MODEL.SEM_SEG_HEAD.NORM + return ret + + def forward_features(self, features): + multi_scale_features = [] + num_cur_levels = 0 + # Reverse feature maps into top-down order (from low to high resolution) + for idx, f in enumerate(self.in_features[::-1]): + x = features[f] + lateral_conv = self.lateral_convs[idx] + output_conv = self.output_convs[idx] + if lateral_conv is None: + y = output_conv(x) + else: + cur_fpn = lateral_conv(x) + # Following FPN implementation, we use nearest upsampling here + y = cur_fpn + F.interpolate(y, size=cur_fpn.shape[-2:], mode="nearest") + y = output_conv(y) + if num_cur_levels < self.oneformer_num_feature_levels: + multi_scale_features.append(y) + num_cur_levels += 1 + return self.mask_features(y), None, multi_scale_features + + def forward(self, features, targets=None): + logger = logging.getLogger(__name__) + logger.warning("Calling forward() may cause unpredicted behavior of PixelDecoder module.") + return self.forward_features(features) + + +class TransformerEncoderOnly(nn.Module): + def __init__( + self, + d_model=512, + nhead=8, + num_encoder_layers=6, + dim_feedforward=2048, + dropout=0.1, + activation="relu", + normalize_before=False, + ): + super().__init__() + + encoder_layer = TransformerEncoderLayer( + d_model, nhead, dim_feedforward, dropout, activation, normalize_before + ) + encoder_norm = nn.LayerNorm(d_model) if normalize_before else None + self.encoder = TransformerEncoder(encoder_layer, num_encoder_layers, encoder_norm) + + self._reset_parameters() + + self.d_model = d_model + self.nhead = nhead + + def _reset_parameters(self): + for p in self.parameters(): + if p.dim() > 1: + nn.init.xavier_uniform_(p) + + def forward(self, src, mask, pos_embed): + # flatten NxCxHxW to HWxNxC + bs, c, h, w = src.shape + src = src.flatten(2).permute(2, 0, 1) + pos_embed = pos_embed.flatten(2).permute(2, 0, 1) + if mask is not None: + mask = mask.flatten(1) + + memory = self.encoder(src, src_key_padding_mask=mask, pos=pos_embed) + return memory.permute(1, 2, 0).view(bs, c, h, w) + + +# This is a modified FPN decoder with extra Transformer encoder that processes the lowest-resolution feature map. +@SEM_SEG_HEADS_REGISTRY.register() +class TransformerEncoderPixelDecoder(BasePixelDecoder): + @configurable + def __init__( + self, + input_shape: Dict[str, ShapeSpec], + *, + transformer_dropout: float, + transformer_nheads: int, + transformer_dim_feedforward: int, + transformer_enc_layers: int, + transformer_pre_norm: bool, + conv_dim: int, + mask_dim: int, + norm: Optional[Union[str, Callable]] = None, + ): + """ + NOTE: this interface is experimental. + Args: + input_shape: shapes (channels and stride) of the input features + transformer_dropout: dropout probability in transformer + transformer_nheads: number of heads in transformer + transformer_dim_feedforward: dimension of feedforward network + transformer_enc_layers: number of transformer encoder layers + transformer_pre_norm: whether to use pre-layernorm or not + conv_dims: number of output channels for the intermediate conv layers. + mask_dim: number of output channels for the final conv layer. + norm (str or callable): normalization for all conv layers + """ + super().__init__(input_shape, conv_dim=conv_dim, mask_dim=mask_dim, norm=norm) + + input_shape = sorted(input_shape.items(), key=lambda x: x[1].stride) + self.in_features = [k for k, v in input_shape] # starting from "res2" to "res5" + feature_strides = [v.stride for k, v in input_shape] + feature_channels = [v.channels for k, v in input_shape] + + in_channels = feature_channels[len(self.in_features) - 1] + self.input_proj = Conv2d(in_channels, conv_dim, kernel_size=1) + weight_init.c2_xavier_fill(self.input_proj) + self.transformer = TransformerEncoderOnly( + d_model=conv_dim, + dropout=transformer_dropout, + nhead=transformer_nheads, + dim_feedforward=transformer_dim_feedforward, + num_encoder_layers=transformer_enc_layers, + normalize_before=transformer_pre_norm, + ) + N_steps = conv_dim // 2 + self.pe_layer = PositionEmbeddingSine(N_steps, normalize=True) + + # update layer + use_bias = norm == "" + output_norm = get_norm(norm, conv_dim) + output_conv = Conv2d( + conv_dim, + conv_dim, + kernel_size=3, + stride=1, + padding=1, + bias=use_bias, + norm=output_norm, + activation=F.relu, + ) + weight_init.c2_xavier_fill(output_conv) + delattr(self, "layer_{}".format(len(self.in_features))) + self.add_module("layer_{}".format(len(self.in_features)), output_conv) + self.output_convs[0] = output_conv + + @classmethod + def from_config(cls, cfg, input_shape: Dict[str, ShapeSpec]): + ret = super().from_config(cfg, input_shape) + ret["transformer_dropout"] = cfg.MODEL.MASK_FORMER.DROPOUT + ret["transformer_nheads"] = cfg.MODEL.MASK_FORMER.NHEADS + ret["transformer_dim_feedforward"] = cfg.MODEL.MASK_FORMER.DIM_FEEDFORWARD + ret[ + "transformer_enc_layers" + ] = cfg.MODEL.SEM_SEG_HEAD.TRANSFORMER_ENC_LAYERS # a separate config + ret["transformer_pre_norm"] = cfg.MODEL.MASK_FORMER.PRE_NORM + return ret + + def forward_features(self, features): + multi_scale_features = [] + num_cur_levels = 0 + # Reverse feature maps into top-down order (from low to high resolution) + for idx, f in enumerate(self.in_features[::-1]): + x = features[f] + lateral_conv = self.lateral_convs[idx] + output_conv = self.output_convs[idx] + if lateral_conv is None: + transformer = self.input_proj(x) + pos = self.pe_layer(x) + transformer = self.transformer(transformer, None, pos) + y = output_conv(transformer) + # save intermediate feature as input to Transformer decoder + transformer_encoder_features = transformer + else: + cur_fpn = lateral_conv(x) + # Following FPN implementation, we use nearest upsampling here + y = cur_fpn + F.interpolate(y, size=cur_fpn.shape[-2:], mode="nearest") + y = output_conv(y) + if num_cur_levels < self.oneformer_num_feature_levels: + multi_scale_features.append(y) + num_cur_levels += 1 + return self.mask_features(y), transformer_encoder_features, multi_scale_features + + def forward(self, features, targets=None): + logger = logging.getLogger(__name__) + logger.warning("Calling forward() may cause unpredicted behavior of PixelDecoder module.") + return self.forward_features(features) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/msdeformattn.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/msdeformattn.py new file mode 100644 index 00000000..007051d7 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/msdeformattn.py @@ -0,0 +1,358 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import logging +import numpy as np +from typing import Callable, Dict, List, Optional, Tuple, Union + +import fvcore.nn.weight_init as weight_init +import torch +from torch import nn +from torch.nn import functional as F +from torch.nn.init import xavier_uniform_, constant_, uniform_, normal_ +from torch.cuda.amp import autocast + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.layers import Conv2d, ShapeSpec, get_norm +from annotator.oneformer.detectron2.modeling import SEM_SEG_HEADS_REGISTRY + +from ..transformer_decoder.position_encoding import PositionEmbeddingSine +from ..transformer_decoder.transformer import _get_clones, _get_activation_fn +from .ops.modules import MSDeformAttn + + +# MSDeformAttn Transformer encoder in deformable detr +class MSDeformAttnTransformerEncoderOnly(nn.Module): + def __init__(self, d_model=256, nhead=8, + num_encoder_layers=6, dim_feedforward=1024, dropout=0.1, + activation="relu", + num_feature_levels=4, enc_n_points=4, + ): + super().__init__() + + self.d_model = d_model + self.nhead = nhead + + encoder_layer = MSDeformAttnTransformerEncoderLayer(d_model, dim_feedforward, + dropout, activation, + num_feature_levels, nhead, enc_n_points) + self.encoder = MSDeformAttnTransformerEncoder(encoder_layer, num_encoder_layers) + + self.level_embed = nn.Parameter(torch.Tensor(num_feature_levels, d_model)) + + self._reset_parameters() + + def _reset_parameters(self): + for p in self.parameters(): + if p.dim() > 1: + nn.init.xavier_uniform_(p) + for m in self.modules(): + if isinstance(m, MSDeformAttn): + m._reset_parameters() + normal_(self.level_embed) + + def get_valid_ratio(self, mask): + _, H, W = mask.shape + valid_H = torch.sum(~mask[:, :, 0], 1) + valid_W = torch.sum(~mask[:, 0, :], 1) + valid_ratio_h = valid_H.float() / H + valid_ratio_w = valid_W.float() / W + valid_ratio = torch.stack([valid_ratio_w, valid_ratio_h], -1) + return valid_ratio + + def forward(self, srcs, pos_embeds): + masks = [torch.zeros((x.size(0), x.size(2), x.size(3)), device=x.device, dtype=torch.bool) for x in srcs] + # prepare input for encoder + src_flatten = [] + mask_flatten = [] + lvl_pos_embed_flatten = [] + spatial_shapes = [] + for lvl, (src, mask, pos_embed) in enumerate(zip(srcs, masks, pos_embeds)): + bs, c, h, w = src.shape + spatial_shape = (h, w) + spatial_shapes.append(spatial_shape) + src = src.flatten(2).transpose(1, 2) + mask = mask.flatten(1) + pos_embed = pos_embed.flatten(2).transpose(1, 2) + lvl_pos_embed = pos_embed + self.level_embed[lvl].view(1, 1, -1) + lvl_pos_embed_flatten.append(lvl_pos_embed) + src_flatten.append(src) + mask_flatten.append(mask) + src_flatten = torch.cat(src_flatten, 1) + mask_flatten = torch.cat(mask_flatten, 1) + lvl_pos_embed_flatten = torch.cat(lvl_pos_embed_flatten, 1) + spatial_shapes = torch.as_tensor(spatial_shapes, dtype=torch.long, device=src_flatten.device) + level_start_index = torch.cat((spatial_shapes.new_zeros((1, )), spatial_shapes.prod(1).cumsum(0)[:-1])) + valid_ratios = torch.stack([self.get_valid_ratio(m) for m in masks], 1) + + # encoder + memory = self.encoder(src_flatten, spatial_shapes, level_start_index, valid_ratios, lvl_pos_embed_flatten, mask_flatten) + + return memory, spatial_shapes, level_start_index, valid_ratios + + +class MSDeformAttnTransformerEncoderLayer(nn.Module): + def __init__(self, + d_model=256, d_ffn=1024, + dropout=0.1, activation="relu", + n_levels=4, n_heads=8, n_points=4): + super().__init__() + + # self attention + self.self_attn = MSDeformAttn(d_model, n_levels, n_heads, n_points) + self.dropout1 = nn.Dropout(dropout) + self.norm1 = nn.LayerNorm(d_model) + + # ffn + self.linear1 = nn.Linear(d_model, d_ffn) + self.activation = _get_activation_fn(activation) + self.dropout2 = nn.Dropout(dropout) + self.linear2 = nn.Linear(d_ffn, d_model) + self.dropout3 = nn.Dropout(dropout) + self.norm2 = nn.LayerNorm(d_model) + + @staticmethod + def with_pos_embed(tensor, pos): + return tensor if pos is None else tensor + pos + + def forward_ffn(self, src): + src2 = self.linear2(self.dropout2(self.activation(self.linear1(src)))) + src = src + self.dropout3(src2) + src = self.norm2(src) + return src + + def forward(self, src, pos, reference_points, spatial_shapes, level_start_index, padding_mask=None): + # self attention + src2 = self.self_attn(self.with_pos_embed(src, pos), reference_points, src, spatial_shapes, level_start_index, padding_mask) + src = src + self.dropout1(src2) + src = self.norm1(src) + + # ffn + src = self.forward_ffn(src) + + return src + + +class MSDeformAttnTransformerEncoder(nn.Module): + def __init__(self, encoder_layer, num_layers): + super().__init__() + self.layers = _get_clones(encoder_layer, num_layers) + self.num_layers = num_layers + + @staticmethod + def get_reference_points(spatial_shapes, valid_ratios, device): + reference_points_list = [] + for lvl, (H_, W_) in enumerate(spatial_shapes): + + ref_y, ref_x = torch.meshgrid(torch.linspace(0.5, H_ - 0.5, H_, dtype=torch.float32, device=device), + torch.linspace(0.5, W_ - 0.5, W_, dtype=torch.float32, device=device)) + ref_y = ref_y.reshape(-1)[None] / (valid_ratios[:, None, lvl, 1] * H_) + ref_x = ref_x.reshape(-1)[None] / (valid_ratios[:, None, lvl, 0] * W_) + ref = torch.stack((ref_x, ref_y), -1) + reference_points_list.append(ref) + reference_points = torch.cat(reference_points_list, 1) + reference_points = reference_points[:, :, None] * valid_ratios[:, None] + return reference_points + + def forward(self, src, spatial_shapes, level_start_index, valid_ratios, pos=None, padding_mask=None): + output = src + reference_points = self.get_reference_points(spatial_shapes, valid_ratios, device=src.device) + for _, layer in enumerate(self.layers): + output = layer(output, pos, reference_points, spatial_shapes, level_start_index, padding_mask) + + return output + + +@SEM_SEG_HEADS_REGISTRY.register() +class MSDeformAttnPixelDecoder(nn.Module): + @configurable + def __init__( + self, + input_shape: Dict[str, ShapeSpec], + *, + transformer_dropout: float, + transformer_nheads: int, + transformer_dim_feedforward: int, + transformer_enc_layers: int, + conv_dim: int, + mask_dim: int, + norm: Optional[Union[str, Callable]] = None, + # deformable transformer encoder args + transformer_in_features: List[str], + common_stride: int, + ): + """ + NOTE: this interface is experimental. + Args: + input_shape: shapes (channels and stride) of the input features + transformer_dropout: dropout probability in transformer + transformer_nheads: number of heads in transformer + transformer_dim_feedforward: dimension of feedforward network + transformer_enc_layers: number of transformer encoder layers + conv_dims: number of output channels for the intermediate conv layers. + mask_dim: number of output channels for the final conv layer. + norm (str or callable): normalization for all conv layers + """ + super().__init__() + transformer_input_shape = { + k: v for k, v in input_shape.items() if k in transformer_in_features + } + + # this is the input shape of pixel decoder + input_shape = sorted(input_shape.items(), key=lambda x: x[1].stride) + self.in_features = [k for k, v in input_shape] # starting from "res2" to "res5" + self.feature_strides = [v.stride for k, v in input_shape] + self.feature_channels = [v.channels for k, v in input_shape] + + # this is the input shape of transformer encoder (could use less features than pixel decoder + transformer_input_shape = sorted(transformer_input_shape.items(), key=lambda x: x[1].stride) + self.transformer_in_features = [k for k, v in transformer_input_shape] # starting from "res2" to "res5" + transformer_in_channels = [v.channels for k, v in transformer_input_shape] + self.transformer_feature_strides = [v.stride for k, v in transformer_input_shape] # to decide extra FPN layers + + self.transformer_num_feature_levels = len(self.transformer_in_features) + if self.transformer_num_feature_levels > 1: + input_proj_list = [] + # from low resolution to high resolution (res5 -> res2) + for in_channels in transformer_in_channels[::-1]: + input_proj_list.append(nn.Sequential( + nn.Conv2d(in_channels, conv_dim, kernel_size=1), + nn.GroupNorm(32, conv_dim), + )) + self.input_proj = nn.ModuleList(input_proj_list) + else: + self.input_proj = nn.ModuleList([ + nn.Sequential( + nn.Conv2d(transformer_in_channels[-1], conv_dim, kernel_size=1), + nn.GroupNorm(32, conv_dim), + )]) + + for proj in self.input_proj: + nn.init.xavier_uniform_(proj[0].weight, gain=1) + nn.init.constant_(proj[0].bias, 0) + + self.transformer = MSDeformAttnTransformerEncoderOnly( + d_model=conv_dim, + dropout=transformer_dropout, + nhead=transformer_nheads, + dim_feedforward=transformer_dim_feedforward, + num_encoder_layers=transformer_enc_layers, + num_feature_levels=self.transformer_num_feature_levels, + ) + N_steps = conv_dim // 2 + self.pe_layer = PositionEmbeddingSine(N_steps, normalize=True) + + self.mask_dim = mask_dim + # use 1x1 conv instead + self.mask_features = Conv2d( + conv_dim, + mask_dim, + kernel_size=1, + stride=1, + padding=0, + ) + weight_init.c2_xavier_fill(self.mask_features) + + self.oneformer_num_feature_levels = 3 # always use 3 scales + self.common_stride = common_stride + + # extra fpn levels + stride = min(self.transformer_feature_strides) + self.num_fpn_levels = int(np.log2(stride) - np.log2(self.common_stride)) + + lateral_convs = [] + output_convs = [] + + use_bias = norm == "" + for idx, in_channels in enumerate(self.feature_channels[:self.num_fpn_levels]): + lateral_norm = get_norm(norm, conv_dim) + output_norm = get_norm(norm, conv_dim) + + lateral_conv = Conv2d( + in_channels, conv_dim, kernel_size=1, bias=use_bias, norm=lateral_norm + ) + output_conv = Conv2d( + conv_dim, + conv_dim, + kernel_size=3, + stride=1, + padding=1, + bias=use_bias, + norm=output_norm, + activation=F.relu, + ) + weight_init.c2_xavier_fill(lateral_conv) + weight_init.c2_xavier_fill(output_conv) + self.add_module("adapter_{}".format(idx + 1), lateral_conv) + self.add_module("layer_{}".format(idx + 1), output_conv) + + lateral_convs.append(lateral_conv) + output_convs.append(output_conv) + # Place convs into top-down order (from low to high resolution) + # to make the top-down computation in forward clearer. + self.lateral_convs = lateral_convs[::-1] + self.output_convs = output_convs[::-1] + + @classmethod + def from_config(cls, cfg, input_shape: Dict[str, ShapeSpec]): + ret = {} + ret["input_shape"] = { + k: v for k, v in input_shape.items() if k in cfg.MODEL.SEM_SEG_HEAD.IN_FEATURES + } + ret["conv_dim"] = cfg.MODEL.SEM_SEG_HEAD.CONVS_DIM + ret["mask_dim"] = cfg.MODEL.SEM_SEG_HEAD.MASK_DIM + ret["norm"] = cfg.MODEL.SEM_SEG_HEAD.NORM + ret["transformer_dropout"] = cfg.MODEL.ONE_FORMER.DROPOUT + ret["transformer_nheads"] = cfg.MODEL.ONE_FORMER.NHEADS + # ret["transformer_dim_feedforward"] = cfg.MODEL.ONE_FORMER.DIM_FEEDFORWARD + ret["transformer_dim_feedforward"] = 1024 # use 1024 for deformable transformer encoder + ret[ + "transformer_enc_layers" + ] = cfg.MODEL.SEM_SEG_HEAD.TRANSFORMER_ENC_LAYERS # a separate config + ret["transformer_in_features"] = cfg.MODEL.SEM_SEG_HEAD.DEFORMABLE_TRANSFORMER_ENCODER_IN_FEATURES + ret["common_stride"] = cfg.MODEL.SEM_SEG_HEAD.COMMON_STRIDE + return ret + + @autocast(enabled=False) + def forward_features(self, features): + srcs = [] + pos = [] + # Reverse feature maps into top-down order (from low to high resolution) + for idx, f in enumerate(self.transformer_in_features[::-1]): + x = features[f].float() # deformable detr does not support half precision + srcs.append(self.input_proj[idx](x)) + pos.append(self.pe_layer(x)) + + y, spatial_shapes, level_start_index, valid_ratios = self.transformer(srcs, pos) + bs = y.shape[0] + + split_size_or_sections = [None] * self.transformer_num_feature_levels + for i in range(self.transformer_num_feature_levels): + if i < self.transformer_num_feature_levels - 1: + split_size_or_sections[i] = level_start_index[i + 1] - level_start_index[i] + else: + split_size_or_sections[i] = y.shape[1] - level_start_index[i] + y = torch.split(y, split_size_or_sections, dim=1) + + out = [] + multi_scale_features = [] + num_cur_levels = 0 + for i, z in enumerate(y): + out.append(z.transpose(1, 2).view(bs, -1, spatial_shapes[i][0], spatial_shapes[i][1])) + + # append `out` with extra FPN levels + # Reverse feature maps into top-down order (from low to high resolution) + for idx, f in enumerate(self.in_features[:self.num_fpn_levels][::-1]): + x = features[f].float() + lateral_conv = self.lateral_convs[idx] + output_conv = self.output_convs[idx] + cur_fpn = lateral_conv(x) + # Following FPN implementation, we use nearest upsampling here + y = cur_fpn + F.interpolate(out[-1], size=cur_fpn.shape[-2:], mode="bilinear", align_corners=False) + y = output_conv(y) + out.append(y) + + for o in out: + if num_cur_levels < self.oneformer_num_feature_levels: + multi_scale_features.append(o) + num_cur_levels += 1 + + return self.mask_features(out[-1]), out[0], multi_scale_features, spatial_shapes, level_start_index diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/functions/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/functions/__init__.py new file mode 100644 index 00000000..2b06b5ac --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/functions/__init__.py @@ -0,0 +1,13 @@ +# ------------------------------------------------------------------------------------------------ +# Deformable DETR +# Copyright (c) 2020 SenseTime. All Rights Reserved. +# Licensed under the Apache License, Version 2.0 [see LICENSE for details] +# ------------------------------------------------------------------------------------------------ +# Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +# ------------------------------------------------------------------------------------------------ + +# Copyright (c) Facebook, Inc. and its affiliates. +# Modified by Bowen Cheng from https://github.com/fundamentalvision/Deformable-DETR + +from .ms_deform_attn_func import MSDeformAttnFunction + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/functions/ms_deform_attn_func.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/functions/ms_deform_attn_func.py new file mode 100644 index 00000000..e074eb69 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/functions/ms_deform_attn_func.py @@ -0,0 +1,77 @@ +# ------------------------------------------------------------------------------------------------ +# Deformable DETR +# Copyright (c) 2020 SenseTime. All Rights Reserved. +# Licensed under the Apache License, Version 2.0 [see LICENSE for details] +# ------------------------------------------------------------------------------------------------ +# Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +# ------------------------------------------------------------------------------------------------ + +# Copyright (c) Facebook, Inc. and its affiliates. +# Modified by Bowen Cheng from https://github.com/fundamentalvision/Deformable-DETR + + +from __future__ import absolute_import +from __future__ import print_function +from __future__ import division + +import torch +import torch.nn.functional as F +from torch.autograd import Function +from torch.autograd.function import once_differentiable + +# if torch.cuda.is_available(): +# try: +# import MultiScaleDeformableAttention as MSDA +# except ModuleNotFoundError as e: +# info_string = ( +# "\n\nPlease compile MultiScaleDeformableAttention CUDA op with the following commands:\n" +# "\t`cd oneformer/modeling/pixel_decoder/ops`\n" +# "\t`sh make.sh`\n" +# ) +# raise ModuleNotFoundError(info_string) +# else: +# MultiScaleDeformableAttention = None + + + +class MSDeformAttnFunction(Function): + @staticmethod + def forward(ctx, value, value_spatial_shapes, value_level_start_index, sampling_locations, attention_weights, im2col_step): + # ctx.im2col_step = im2col_step + output = ms_deform_attn_core_pytorch( + value, value_spatial_shapes, sampling_locations, attention_weights) + # ctx.save_for_backward(value, value_spatial_shapes, value_level_start_index, sampling_locations, attention_weights) + return output + + # @staticmethod + # @once_differentiable + # def backward(ctx, grad_output): + # value, value_spatial_shapes, value_level_start_index, sampling_locations, attention_weights = ctx.saved_tensors + # grad_value, grad_sampling_loc, grad_attn_weight = \ + # MSDA.ms_deform_attn_backward( + # value, value_spatial_shapes, value_level_start_index, sampling_locations, attention_weights, grad_output, ctx.im2col_step) + # + # return grad_value, None, None, grad_sampling_loc, grad_attn_weight, None + + +def ms_deform_attn_core_pytorch(value, value_spatial_shapes, sampling_locations, attention_weights): + # for debug and test only, + # need to use cuda version instead + N_, S_, M_, D_ = value.shape + _, Lq_, M_, L_, P_, _ = sampling_locations.shape + value_list = value.split([H_ * W_ for H_, W_ in value_spatial_shapes], dim=1) + sampling_grids = 2 * sampling_locations - 1 + sampling_value_list = [] + for lid_, (H_, W_) in enumerate(value_spatial_shapes): + # N_, H_*W_, M_, D_ -> N_, H_*W_, M_*D_ -> N_, M_*D_, H_*W_ -> N_*M_, D_, H_, W_ + value_l_ = value_list[lid_].flatten(2).transpose(1, 2).reshape(N_*M_, D_, H_, W_) + # N_, Lq_, M_, P_, 2 -> N_, M_, Lq_, P_, 2 -> N_*M_, Lq_, P_, 2 + sampling_grid_l_ = sampling_grids[:, :, :, lid_].transpose(1, 2).flatten(0, 1) + # N_*M_, D_, Lq_, P_ + sampling_value_l_ = F.grid_sample(value_l_, sampling_grid_l_, + mode='bilinear', padding_mode='zeros', align_corners=False) + sampling_value_list.append(sampling_value_l_) + # (N_, Lq_, M_, L_, P_) -> (N_, M_, Lq_, L_, P_) -> (N_, M_, 1, Lq_, L_*P_) + attention_weights = attention_weights.transpose(1, 2).reshape(N_*M_, 1, Lq_, L_*P_) + output = (torch.stack(sampling_value_list, dim=-2).flatten(-2) * attention_weights).sum(-1).view(N_, M_*D_, Lq_) + return output.transpose(1, 2).contiguous() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/make.sh b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/make.sh new file mode 100644 index 00000000..ca5c0b46 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/make.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# ------------------------------------------------------------------------------------------------ +# Deformable DETR +# Copyright (c) 2020 SenseTime. All Rights Reserved. +# Licensed under the Apache License, Version 2.0 [see LICENSE for details] +# ------------------------------------------------------------------------------------------------ +# Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +# ------------------------------------------------------------------------------------------------ + +# Copyright (c) Facebook, Inc. and its affiliates. +# Modified by Bowen Cheng from https://github.com/fundamentalvision/Deformable-DETR + +FORCE_CUDA=1 python setup.py build install diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/modules/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/modules/__init__.py new file mode 100644 index 00000000..6fdbf033 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/modules/__init__.py @@ -0,0 +1,12 @@ +# ------------------------------------------------------------------------------------------------ +# Deformable DETR +# Copyright (c) 2020 SenseTime. All Rights Reserved. +# Licensed under the Apache License, Version 2.0 [see LICENSE for details] +# ------------------------------------------------------------------------------------------------ +# Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +# ------------------------------------------------------------------------------------------------ + +# Copyright (c) Facebook, Inc. and its affiliates. +# Modified by Bowen Cheng from https://github.com/fundamentalvision/Deformable-DETR + +from .ms_deform_attn import MSDeformAttn diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/modules/ms_deform_attn.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/modules/ms_deform_attn.py new file mode 100644 index 00000000..5bc471d2 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/modules/ms_deform_attn.py @@ -0,0 +1,120 @@ +# ------------------------------------------------------------------------------------------------ +# Deformable DETR +# Copyright (c) 2020 SenseTime. All Rights Reserved. +# Licensed under the Apache License, Version 2.0 [see LICENSE for details] +# ------------------------------------------------------------------------------------------------ +# Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +# ------------------------------------------------------------------------------------------------ + +# Copyright (c) Facebook, Inc. and its affiliates. +# Modified by Bowen Cheng from https://github.com/fundamentalvision/Deformable-DETR + +from __future__ import absolute_import +from __future__ import print_function +from __future__ import division + +import warnings +import math + +import torch +from torch import nn +import torch.nn.functional as F +from torch.nn.init import xavier_uniform_, constant_ + +MSDeformAttnFunction = None +from ..functions.ms_deform_attn_func import ms_deform_attn_core_pytorch + + +def _is_power_of_2(n): + if (not isinstance(n, int)) or (n < 0): + raise ValueError("invalid input for _is_power_of_2: {} (type: {})".format(n, type(n))) + return (n & (n-1) == 0) and n != 0 + + +class MSDeformAttn(nn.Module): + def __init__(self, d_model=256, n_levels=4, n_heads=8, n_points=4): + """ + Multi-Scale Deformable Attention Module + :param d_model hidden dimension + :param n_levels number of feature levels + :param n_heads number of attention heads + :param n_points number of sampling points per attention head per feature level + """ + super().__init__() + if d_model % n_heads != 0: + raise ValueError('d_model must be divisible by n_heads, but got {} and {}'.format(d_model, n_heads)) + _d_per_head = d_model // n_heads + # you'd better set _d_per_head to a power of 2 which is more efficient in our CUDA implementation + if not _is_power_of_2(_d_per_head): + warnings.warn("You'd better set d_model in MSDeformAttn to make the dimension of each attention head a power of 2 " + "which is more efficient in our CUDA implementation.") + + self.im2col_step = 128 + + self.d_model = d_model + self.n_levels = n_levels + self.n_heads = n_heads + self.n_points = n_points + + self.sampling_offsets = nn.Linear(d_model, n_heads * n_levels * n_points * 2) + self.attention_weights = nn.Linear(d_model, n_heads * n_levels * n_points) + self.value_proj = nn.Linear(d_model, d_model) + self.output_proj = nn.Linear(d_model, d_model) + + self._reset_parameters() + + def _reset_parameters(self): + constant_(self.sampling_offsets.weight.data, 0.) + thetas = torch.arange(self.n_heads, dtype=torch.float32) * (2.0 * math.pi / self.n_heads) + grid_init = torch.stack([thetas.cos(), thetas.sin()], -1) + grid_init = (grid_init / grid_init.abs().max(-1, keepdim=True)[0]).view(self.n_heads, 1, 1, 2).repeat(1, self.n_levels, self.n_points, 1) + for i in range(self.n_points): + grid_init[:, :, i, :] *= i + 1 + with torch.no_grad(): + self.sampling_offsets.bias = nn.Parameter(grid_init.view(-1)) + constant_(self.attention_weights.weight.data, 0.) + constant_(self.attention_weights.bias.data, 0.) + xavier_uniform_(self.value_proj.weight.data) + constant_(self.value_proj.bias.data, 0.) + xavier_uniform_(self.output_proj.weight.data) + constant_(self.output_proj.bias.data, 0.) + + def forward(self, query, reference_points, input_flatten, input_spatial_shapes, input_level_start_index, input_padding_mask=None): + """ + :param query (N, Length_{query}, C) + :param reference_points (N, Length_{query}, n_levels, 2), range in [0, 1], top-left (0,0), bottom-right (1, 1), including padding area + or (N, Length_{query}, n_levels, 4), add additional (w, h) to form reference boxes + :param input_flatten (N, \sum_{l=0}^{L-1} H_l \cdot W_l, C) + :param input_spatial_shapes (n_levels, 2), [(H_0, W_0), (H_1, W_1), ..., (H_{L-1}, W_{L-1})] + :param input_level_start_index (n_levels, ), [0, H_0*W_0, H_0*W_0+H_1*W_1, H_0*W_0+H_1*W_1+H_2*W_2, ..., H_0*W_0+H_1*W_1+...+H_{L-1}*W_{L-1}] + :param input_padding_mask (N, \sum_{l=0}^{L-1} H_l \cdot W_l), True for padding elements, False for non-padding elements + :return output (N, Length_{query}, C) + """ + N, Len_q, _ = query.shape + N, Len_in, _ = input_flatten.shape + assert (input_spatial_shapes[:, 0] * input_spatial_shapes[:, 1]).sum() == Len_in + + value = self.value_proj(input_flatten) + if input_padding_mask is not None: + value = value.masked_fill(input_padding_mask[..., None], float(0)) + value = value.view(N, Len_in, self.n_heads, self.d_model // self.n_heads) + sampling_offsets = self.sampling_offsets(query).view(N, Len_q, self.n_heads, self.n_levels, self.n_points, 2) + attention_weights = self.attention_weights(query).view(N, Len_q, self.n_heads, self.n_levels * self.n_points) + attention_weights = F.softmax(attention_weights, -1).view(N, Len_q, self.n_heads, self.n_levels, self.n_points) + # N, Len_q, n_heads, n_levels, n_points, 2 + if reference_points.shape[-1] == 2: + offset_normalizer = torch.stack([input_spatial_shapes[..., 1], input_spatial_shapes[..., 0]], -1) + sampling_locations = reference_points[:, :, None, :, None, :] \ + + sampling_offsets / offset_normalizer[None, None, None, :, None, :] + elif reference_points.shape[-1] == 4: + sampling_locations = reference_points[:, :, None, :, None, :2] \ + + sampling_offsets / self.n_points * reference_points[:, :, None, :, None, 2:] * 0.5 + else: + raise ValueError( + 'Last dim of reference_points must be 2 or 4, but get {} instead.'.format(reference_points.shape[-1])) + # try: + output = ms_deform_attn_core_pytorch(value, input_spatial_shapes, sampling_locations, attention_weights) + # # For FLOPs calculation only + # output = ms_deform_attn_core_pytorch(value, input_spatial_shapes, sampling_locations, attention_weights) + output = self.output_proj(output) + return output \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/setup.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/setup.py new file mode 100644 index 00000000..3b57ad31 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/setup.py @@ -0,0 +1,78 @@ +# ------------------------------------------------------------------------------------------------ +# Deformable DETR +# Copyright (c) 2020 SenseTime. All Rights Reserved. +# Licensed under the Apache License, Version 2.0 [see LICENSE for details] +# ------------------------------------------------------------------------------------------------ +# Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +# ------------------------------------------------------------------------------------------------ + +# Copyright (c) Facebook, Inc. and its affiliates. +# Modified by Bowen Cheng from https://github.com/fundamentalvision/Deformable-DETR + +import os +import glob + +import torch + +from torch.utils.cpp_extension import CUDA_HOME +from torch.utils.cpp_extension import CppExtension +from torch.utils.cpp_extension import CUDAExtension + +from setuptools import find_packages +from setuptools import setup + +requirements = ["torch", "torchvision"] + +def get_extensions(): + this_dir = os.path.dirname(os.path.abspath(__file__)) + extensions_dir = os.path.join(this_dir, "src") + + main_file = glob.glob(os.path.join(extensions_dir, "*.cpp")) + source_cpu = glob.glob(os.path.join(extensions_dir, "cpu", "*.cpp")) + source_cuda = glob.glob(os.path.join(extensions_dir, "cuda", "*.cu")) + + sources = main_file + source_cpu + extension = CppExtension + extra_compile_args = {"cxx": []} + define_macros = [] + + # Force cuda since torch ask for a device, not if cuda is in fact available. + if (os.environ.get('FORCE_CUDA') or torch.cuda.is_available()) and CUDA_HOME is not None: + extension = CUDAExtension + sources += source_cuda + define_macros += [("WITH_CUDA", None)] + extra_compile_args["nvcc"] = [ + "-DCUDA_HAS_FP16=1", + "-D__CUDA_NO_HALF_OPERATORS__", + "-D__CUDA_NO_HALF_CONVERSIONS__", + "-D__CUDA_NO_HALF2_OPERATORS__", + ] + else: + if CUDA_HOME is None: + raise NotImplementedError('CUDA_HOME is None. Please set environment variable CUDA_HOME.') + else: + raise NotImplementedError('No CUDA runtime is found. Please set FORCE_CUDA=1 or test it by running torch.cuda.is_available().') + + sources = [os.path.join(extensions_dir, s) for s in sources] + include_dirs = [extensions_dir] + ext_modules = [ + extension( + "MultiScaleDeformableAttention", + sources, + include_dirs=include_dirs, + define_macros=define_macros, + extra_compile_args=extra_compile_args, + ) + ] + return ext_modules + +setup( + name="MultiScaleDeformableAttention", + version="1.0", + author="Weijie Su", + url="https://github.com/fundamentalvision/Deformable-DETR", + description="PyTorch Wrapper for CUDA Functions of Multi-Scale Deformable Attention", + packages=find_packages(exclude=("configs", "tests",)), + ext_modules=get_extensions(), + cmdclass={"build_ext": torch.utils.cpp_extension.BuildExtension}, +) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cpu/ms_deform_attn_cpu.cpp b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cpu/ms_deform_attn_cpu.cpp new file mode 100644 index 00000000..48757e2b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cpu/ms_deform_attn_cpu.cpp @@ -0,0 +1,46 @@ +/*! +************************************************************************************************** +* Deformable DETR +* Copyright (c) 2020 SenseTime. All Rights Reserved. +* Licensed under the Apache License, Version 2.0 [see LICENSE for details] +************************************************************************************************** +* Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +************************************************************************************************** +*/ + +/*! +* Copyright (c) Facebook, Inc. and its affiliates. +* Modified by Bowen Cheng from https://github.com/fundamentalvision/Deformable-DETR +*/ + +#include + +#include +#include + + +at::Tensor +ms_deform_attn_cpu_forward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const int im2col_step) +{ + AT_ERROR("Not implement on cpu"); +} + +std::vector +ms_deform_attn_cpu_backward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const at::Tensor &grad_output, + const int im2col_step) +{ + AT_ERROR("Not implement on cpu"); +} + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cpu/ms_deform_attn_cpu.h b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cpu/ms_deform_attn_cpu.h new file mode 100644 index 00000000..51bb27e9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cpu/ms_deform_attn_cpu.h @@ -0,0 +1,38 @@ +/*! +************************************************************************************************** +* Deformable DETR +* Copyright (c) 2020 SenseTime. All Rights Reserved. +* Licensed under the Apache License, Version 2.0 [see LICENSE for details] +************************************************************************************************** +* Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +************************************************************************************************** +*/ + +/*! +* Copyright (c) Facebook, Inc. and its affiliates. +* Modified by Bowen Cheng from https://github.com/fundamentalvision/Deformable-DETR +*/ + +#pragma once +#include + +at::Tensor +ms_deform_attn_cpu_forward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const int im2col_step); + +std::vector +ms_deform_attn_cpu_backward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const at::Tensor &grad_output, + const int im2col_step); + + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cuda/ms_deform_attn_cuda.cu b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cuda/ms_deform_attn_cuda.cu new file mode 100644 index 00000000..0c465dab --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cuda/ms_deform_attn_cuda.cu @@ -0,0 +1,158 @@ +/*! +************************************************************************************************** +* Deformable DETR +* Copyright (c) 2020 SenseTime. All Rights Reserved. +* Licensed under the Apache License, Version 2.0 [see LICENSE for details] +************************************************************************************************** +* Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +************************************************************************************************** +*/ + +/*! +* Copyright (c) Facebook, Inc. and its affiliates. +* Modified by Bowen Cheng from https://github.com/fundamentalvision/Deformable-DETR +*/ + +#include +#include "cuda/ms_deform_im2col_cuda.cuh" + +#include +#include +#include +#include + + +at::Tensor ms_deform_attn_cuda_forward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const int im2col_step) +{ + AT_ASSERTM(value.is_contiguous(), "value tensor has to be contiguous"); + AT_ASSERTM(spatial_shapes.is_contiguous(), "spatial_shapes tensor has to be contiguous"); + AT_ASSERTM(level_start_index.is_contiguous(), "level_start_index tensor has to be contiguous"); + AT_ASSERTM(sampling_loc.is_contiguous(), "sampling_loc tensor has to be contiguous"); + AT_ASSERTM(attn_weight.is_contiguous(), "attn_weight tensor has to be contiguous"); + + AT_ASSERTM(value.type().is_cuda(), "value must be a CUDA tensor"); + AT_ASSERTM(spatial_shapes.type().is_cuda(), "spatial_shapes must be a CUDA tensor"); + AT_ASSERTM(level_start_index.type().is_cuda(), "level_start_index must be a CUDA tensor"); + AT_ASSERTM(sampling_loc.type().is_cuda(), "sampling_loc must be a CUDA tensor"); + AT_ASSERTM(attn_weight.type().is_cuda(), "attn_weight must be a CUDA tensor"); + + const int batch = value.size(0); + const int spatial_size = value.size(1); + const int num_heads = value.size(2); + const int channels = value.size(3); + + const int num_levels = spatial_shapes.size(0); + + const int num_query = sampling_loc.size(1); + const int num_point = sampling_loc.size(4); + + const int im2col_step_ = std::min(batch, im2col_step); + + AT_ASSERTM(batch % im2col_step_ == 0, "batch(%d) must divide im2col_step(%d)", batch, im2col_step_); + + auto output = at::zeros({batch, num_query, num_heads, channels}, value.options()); + + const int batch_n = im2col_step_; + auto output_n = output.view({batch/im2col_step_, batch_n, num_query, num_heads, channels}); + auto per_value_size = spatial_size * num_heads * channels; + auto per_sample_loc_size = num_query * num_heads * num_levels * num_point * 2; + auto per_attn_weight_size = num_query * num_heads * num_levels * num_point; + for (int n = 0; n < batch/im2col_step_; ++n) + { + auto columns = output_n.select(0, n); + AT_DISPATCH_FLOATING_TYPES(value.type(), "ms_deform_attn_forward_cuda", ([&] { + ms_deformable_im2col_cuda(at::cuda::getCurrentCUDAStream(), + value.data() + n * im2col_step_ * per_value_size, + spatial_shapes.data(), + level_start_index.data(), + sampling_loc.data() + n * im2col_step_ * per_sample_loc_size, + attn_weight.data() + n * im2col_step_ * per_attn_weight_size, + batch_n, spatial_size, num_heads, channels, num_levels, num_query, num_point, + columns.data()); + + })); + } + + output = output.view({batch, num_query, num_heads*channels}); + + return output; +} + + +std::vector ms_deform_attn_cuda_backward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const at::Tensor &grad_output, + const int im2col_step) +{ + + AT_ASSERTM(value.is_contiguous(), "value tensor has to be contiguous"); + AT_ASSERTM(spatial_shapes.is_contiguous(), "spatial_shapes tensor has to be contiguous"); + AT_ASSERTM(level_start_index.is_contiguous(), "level_start_index tensor has to be contiguous"); + AT_ASSERTM(sampling_loc.is_contiguous(), "sampling_loc tensor has to be contiguous"); + AT_ASSERTM(attn_weight.is_contiguous(), "attn_weight tensor has to be contiguous"); + AT_ASSERTM(grad_output.is_contiguous(), "grad_output tensor has to be contiguous"); + + AT_ASSERTM(value.type().is_cuda(), "value must be a CUDA tensor"); + AT_ASSERTM(spatial_shapes.type().is_cuda(), "spatial_shapes must be a CUDA tensor"); + AT_ASSERTM(level_start_index.type().is_cuda(), "level_start_index must be a CUDA tensor"); + AT_ASSERTM(sampling_loc.type().is_cuda(), "sampling_loc must be a CUDA tensor"); + AT_ASSERTM(attn_weight.type().is_cuda(), "attn_weight must be a CUDA tensor"); + AT_ASSERTM(grad_output.type().is_cuda(), "grad_output must be a CUDA tensor"); + + const int batch = value.size(0); + const int spatial_size = value.size(1); + const int num_heads = value.size(2); + const int channels = value.size(3); + + const int num_levels = spatial_shapes.size(0); + + const int num_query = sampling_loc.size(1); + const int num_point = sampling_loc.size(4); + + const int im2col_step_ = std::min(batch, im2col_step); + + AT_ASSERTM(batch % im2col_step_ == 0, "batch(%d) must divide im2col_step(%d)", batch, im2col_step_); + + auto grad_value = at::zeros_like(value); + auto grad_sampling_loc = at::zeros_like(sampling_loc); + auto grad_attn_weight = at::zeros_like(attn_weight); + + const int batch_n = im2col_step_; + auto per_value_size = spatial_size * num_heads * channels; + auto per_sample_loc_size = num_query * num_heads * num_levels * num_point * 2; + auto per_attn_weight_size = num_query * num_heads * num_levels * num_point; + auto grad_output_n = grad_output.view({batch/im2col_step_, batch_n, num_query, num_heads, channels}); + + for (int n = 0; n < batch/im2col_step_; ++n) + { + auto grad_output_g = grad_output_n.select(0, n); + AT_DISPATCH_FLOATING_TYPES(value.type(), "ms_deform_attn_backward_cuda", ([&] { + ms_deformable_col2im_cuda(at::cuda::getCurrentCUDAStream(), + grad_output_g.data(), + value.data() + n * im2col_step_ * per_value_size, + spatial_shapes.data(), + level_start_index.data(), + sampling_loc.data() + n * im2col_step_ * per_sample_loc_size, + attn_weight.data() + n * im2col_step_ * per_attn_weight_size, + batch_n, spatial_size, num_heads, channels, num_levels, num_query, num_point, + grad_value.data() + n * im2col_step_ * per_value_size, + grad_sampling_loc.data() + n * im2col_step_ * per_sample_loc_size, + grad_attn_weight.data() + n * im2col_step_ * per_attn_weight_size); + + })); + } + + return { + grad_value, grad_sampling_loc, grad_attn_weight + }; +} \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cuda/ms_deform_attn_cuda.h b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cuda/ms_deform_attn_cuda.h new file mode 100644 index 00000000..4f0658e8 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cuda/ms_deform_attn_cuda.h @@ -0,0 +1,35 @@ +/*! +************************************************************************************************** +* Deformable DETR +* Copyright (c) 2020 SenseTime. All Rights Reserved. +* Licensed under the Apache License, Version 2.0 [see LICENSE for details] +************************************************************************************************** +* Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +************************************************************************************************** +*/ + +/*! +* Copyright (c) Facebook, Inc. and its affiliates. +* Modified by Bowen Cheng from https://github.com/fundamentalvision/Deformable-DETR +*/ + +#pragma once +#include + +at::Tensor ms_deform_attn_cuda_forward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const int im2col_step); + +std::vector ms_deform_attn_cuda_backward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const at::Tensor &grad_output, + const int im2col_step); + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cuda/ms_deform_im2col_cuda.cuh b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cuda/ms_deform_im2col_cuda.cuh new file mode 100644 index 00000000..c04e0d4a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/cuda/ms_deform_im2col_cuda.cuh @@ -0,0 +1,1332 @@ +/*! +************************************************************************** +* Deformable DETR +* Copyright (c) 2020 SenseTime. All Rights Reserved. +* Licensed under the Apache License, Version 2.0 [see LICENSE for details] +************************************************************************** +* Modified from DCN (https://github.com/msracver/Deformable-ConvNets) +* Copyright (c) 2018 Microsoft +************************************************************************** +*/ + +/*! +* Copyright (c) Facebook, Inc. and its affiliates. +* Modified by Bowen Cheng from https://github.com/fundamentalvision/Deformable-DETR +*/ + +#include +#include +#include + +#include +#include + +#include + +#define CUDA_KERNEL_LOOP(i, n) \ + for (int i = blockIdx.x * blockDim.x + threadIdx.x; \ + i < (n); \ + i += blockDim.x * gridDim.x) + +const int CUDA_NUM_THREADS = 1024; +inline int GET_BLOCKS(const int N, const int num_threads) +{ + return (N + num_threads - 1) / num_threads; +} + + +template +__device__ scalar_t ms_deform_attn_im2col_bilinear(const scalar_t* &bottom_data, + const int &height, const int &width, const int &nheads, const int &channels, + const scalar_t &h, const scalar_t &w, const int &m, const int &c) +{ + const int h_low = floor(h); + const int w_low = floor(w); + const int h_high = h_low + 1; + const int w_high = w_low + 1; + + const scalar_t lh = h - h_low; + const scalar_t lw = w - w_low; + const scalar_t hh = 1 - lh, hw = 1 - lw; + + const int w_stride = nheads * channels; + const int h_stride = width * w_stride; + const int h_low_ptr_offset = h_low * h_stride; + const int h_high_ptr_offset = h_low_ptr_offset + h_stride; + const int w_low_ptr_offset = w_low * w_stride; + const int w_high_ptr_offset = w_low_ptr_offset + w_stride; + const int base_ptr = m * channels + c; + + scalar_t v1 = 0; + if (h_low >= 0 && w_low >= 0) + { + const int ptr1 = h_low_ptr_offset + w_low_ptr_offset + base_ptr; + v1 = bottom_data[ptr1]; + } + scalar_t v2 = 0; + if (h_low >= 0 && w_high <= width - 1) + { + const int ptr2 = h_low_ptr_offset + w_high_ptr_offset + base_ptr; + v2 = bottom_data[ptr2]; + } + scalar_t v3 = 0; + if (h_high <= height - 1 && w_low >= 0) + { + const int ptr3 = h_high_ptr_offset + w_low_ptr_offset + base_ptr; + v3 = bottom_data[ptr3]; + } + scalar_t v4 = 0; + if (h_high <= height - 1 && w_high <= width - 1) + { + const int ptr4 = h_high_ptr_offset + w_high_ptr_offset + base_ptr; + v4 = bottom_data[ptr4]; + } + + const scalar_t w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw; + + const scalar_t val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4); + return val; +} + + +template +__device__ void ms_deform_attn_col2im_bilinear(const scalar_t* &bottom_data, + const int &height, const int &width, const int &nheads, const int &channels, + const scalar_t &h, const scalar_t &w, const int &m, const int &c, + const scalar_t &top_grad, + const scalar_t &attn_weight, + scalar_t* &grad_value, + scalar_t* grad_sampling_loc, + scalar_t* grad_attn_weight) +{ + const int h_low = floor(h); + const int w_low = floor(w); + const int h_high = h_low + 1; + const int w_high = w_low + 1; + + const scalar_t lh = h - h_low; + const scalar_t lw = w - w_low; + const scalar_t hh = 1 - lh, hw = 1 - lw; + + const int w_stride = nheads * channels; + const int h_stride = width * w_stride; + const int h_low_ptr_offset = h_low * h_stride; + const int h_high_ptr_offset = h_low_ptr_offset + h_stride; + const int w_low_ptr_offset = w_low * w_stride; + const int w_high_ptr_offset = w_low_ptr_offset + w_stride; + const int base_ptr = m * channels + c; + + const scalar_t w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw; + const scalar_t top_grad_value = top_grad * attn_weight; + scalar_t grad_h_weight = 0, grad_w_weight = 0; + + scalar_t v1 = 0; + if (h_low >= 0 && w_low >= 0) + { + const int ptr1 = h_low_ptr_offset + w_low_ptr_offset + base_ptr; + v1 = bottom_data[ptr1]; + grad_h_weight -= hw * v1; + grad_w_weight -= hh * v1; + atomicAdd(grad_value+ptr1, w1*top_grad_value); + } + scalar_t v2 = 0; + if (h_low >= 0 && w_high <= width - 1) + { + const int ptr2 = h_low_ptr_offset + w_high_ptr_offset + base_ptr; + v2 = bottom_data[ptr2]; + grad_h_weight -= lw * v2; + grad_w_weight += hh * v2; + atomicAdd(grad_value+ptr2, w2*top_grad_value); + } + scalar_t v3 = 0; + if (h_high <= height - 1 && w_low >= 0) + { + const int ptr3 = h_high_ptr_offset + w_low_ptr_offset + base_ptr; + v3 = bottom_data[ptr3]; + grad_h_weight += hw * v3; + grad_w_weight -= lh * v3; + atomicAdd(grad_value+ptr3, w3*top_grad_value); + } + scalar_t v4 = 0; + if (h_high <= height - 1 && w_high <= width - 1) + { + const int ptr4 = h_high_ptr_offset + w_high_ptr_offset + base_ptr; + v4 = bottom_data[ptr4]; + grad_h_weight += lw * v4; + grad_w_weight += lh * v4; + atomicAdd(grad_value+ptr4, w4*top_grad_value); + } + + const scalar_t val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4); + *grad_attn_weight = top_grad * val; + *grad_sampling_loc = width * grad_w_weight * top_grad_value; + *(grad_sampling_loc + 1) = height * grad_h_weight * top_grad_value; +} + + +template +__device__ void ms_deform_attn_col2im_bilinear_gm(const scalar_t* &bottom_data, + const int &height, const int &width, const int &nheads, const int &channels, + const scalar_t &h, const scalar_t &w, const int &m, const int &c, + const scalar_t &top_grad, + const scalar_t &attn_weight, + scalar_t* &grad_value, + scalar_t* grad_sampling_loc, + scalar_t* grad_attn_weight) +{ + const int h_low = floor(h); + const int w_low = floor(w); + const int h_high = h_low + 1; + const int w_high = w_low + 1; + + const scalar_t lh = h - h_low; + const scalar_t lw = w - w_low; + const scalar_t hh = 1 - lh, hw = 1 - lw; + + const int w_stride = nheads * channels; + const int h_stride = width * w_stride; + const int h_low_ptr_offset = h_low * h_stride; + const int h_high_ptr_offset = h_low_ptr_offset + h_stride; + const int w_low_ptr_offset = w_low * w_stride; + const int w_high_ptr_offset = w_low_ptr_offset + w_stride; + const int base_ptr = m * channels + c; + + const scalar_t w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw; + const scalar_t top_grad_value = top_grad * attn_weight; + scalar_t grad_h_weight = 0, grad_w_weight = 0; + + scalar_t v1 = 0; + if (h_low >= 0 && w_low >= 0) + { + const int ptr1 = h_low_ptr_offset + w_low_ptr_offset + base_ptr; + v1 = bottom_data[ptr1]; + grad_h_weight -= hw * v1; + grad_w_weight -= hh * v1; + atomicAdd(grad_value+ptr1, w1*top_grad_value); + } + scalar_t v2 = 0; + if (h_low >= 0 && w_high <= width - 1) + { + const int ptr2 = h_low_ptr_offset + w_high_ptr_offset + base_ptr; + v2 = bottom_data[ptr2]; + grad_h_weight -= lw * v2; + grad_w_weight += hh * v2; + atomicAdd(grad_value+ptr2, w2*top_grad_value); + } + scalar_t v3 = 0; + if (h_high <= height - 1 && w_low >= 0) + { + const int ptr3 = h_high_ptr_offset + w_low_ptr_offset + base_ptr; + v3 = bottom_data[ptr3]; + grad_h_weight += hw * v3; + grad_w_weight -= lh * v3; + atomicAdd(grad_value+ptr3, w3*top_grad_value); + } + scalar_t v4 = 0; + if (h_high <= height - 1 && w_high <= width - 1) + { + const int ptr4 = h_high_ptr_offset + w_high_ptr_offset + base_ptr; + v4 = bottom_data[ptr4]; + grad_h_weight += lw * v4; + grad_w_weight += lh * v4; + atomicAdd(grad_value+ptr4, w4*top_grad_value); + } + + const scalar_t val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4); + atomicAdd(grad_attn_weight, top_grad * val); + atomicAdd(grad_sampling_loc, width * grad_w_weight * top_grad_value); + atomicAdd(grad_sampling_loc + 1, height * grad_h_weight * top_grad_value); +} + + +template +__global__ void ms_deformable_im2col_gpu_kernel(const int n, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *data_col) +{ + CUDA_KERNEL_LOOP(index, n) + { + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + scalar_t *data_col_ptr = data_col + index; + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + scalar_t col = 0; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const scalar_t *data_value_ptr = data_value + (data_value_ptr_init_offset + level_start_id * qid_stride); + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + col += ms_deform_attn_im2col_bilinear(data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col) * weight; + } + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + } + } + *data_col_ptr = col; + } +} + +template +__global__ void ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + __shared__ scalar_t cache_grad_sampling_loc[blockSize * 2]; + __shared__ scalar_t cache_grad_attn_weight[blockSize]; + unsigned int tid = threadIdx.x; + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + *(cache_grad_sampling_loc+(threadIdx.x << 1)) = 0; + *(cache_grad_sampling_loc+((threadIdx.x << 1) + 1)) = 0; + *(cache_grad_attn_weight+threadIdx.x)=0; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + cache_grad_sampling_loc+(threadIdx.x << 1), cache_grad_attn_weight+threadIdx.x); + } + + __syncthreads(); + if (tid == 0) + { + scalar_t _grad_w=cache_grad_sampling_loc[0], _grad_h=cache_grad_sampling_loc[1], _grad_a=cache_grad_attn_weight[0]; + int sid=2; + for (unsigned int tid = 1; tid < blockSize; ++tid) + { + _grad_w += cache_grad_sampling_loc[sid]; + _grad_h += cache_grad_sampling_loc[sid + 1]; + _grad_a += cache_grad_attn_weight[tid]; + sid += 2; + } + + + *grad_sampling_loc = _grad_w; + *(grad_sampling_loc + 1) = _grad_h; + *grad_attn_weight = _grad_a; + } + __syncthreads(); + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + + +template +__global__ void ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + __shared__ scalar_t cache_grad_sampling_loc[blockSize * 2]; + __shared__ scalar_t cache_grad_attn_weight[blockSize]; + unsigned int tid = threadIdx.x; + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + *(cache_grad_sampling_loc+(threadIdx.x << 1)) = 0; + *(cache_grad_sampling_loc+((threadIdx.x << 1) + 1)) = 0; + *(cache_grad_attn_weight+threadIdx.x)=0; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + cache_grad_sampling_loc+(threadIdx.x << 1), cache_grad_attn_weight+threadIdx.x); + } + + __syncthreads(); + + for (unsigned int s=blockSize/2; s>0; s>>=1) + { + if (tid < s) { + const unsigned int xid1 = tid << 1; + const unsigned int xid2 = (tid + s) << 1; + cache_grad_attn_weight[tid] += cache_grad_attn_weight[tid + s]; + cache_grad_sampling_loc[xid1] += cache_grad_sampling_loc[xid2]; + cache_grad_sampling_loc[xid1 + 1] += cache_grad_sampling_loc[xid2 + 1]; + } + __syncthreads(); + } + + if (tid == 0) + { + *grad_sampling_loc = cache_grad_sampling_loc[0]; + *(grad_sampling_loc + 1) = cache_grad_sampling_loc[1]; + *grad_attn_weight = cache_grad_attn_weight[0]; + } + __syncthreads(); + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + + +template +__global__ void ms_deformable_col2im_gpu_kernel_shm_reduce_v1(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + extern __shared__ int _s[]; + scalar_t* cache_grad_sampling_loc = (scalar_t*)_s; + scalar_t* cache_grad_attn_weight = cache_grad_sampling_loc + 2 * blockDim.x; + unsigned int tid = threadIdx.x; + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + *(cache_grad_sampling_loc+(threadIdx.x << 1)) = 0; + *(cache_grad_sampling_loc+((threadIdx.x << 1) + 1)) = 0; + *(cache_grad_attn_weight+threadIdx.x)=0; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + cache_grad_sampling_loc+(threadIdx.x << 1), cache_grad_attn_weight+threadIdx.x); + } + + __syncthreads(); + if (tid == 0) + { + scalar_t _grad_w=cache_grad_sampling_loc[0], _grad_h=cache_grad_sampling_loc[1], _grad_a=cache_grad_attn_weight[0]; + int sid=2; + for (unsigned int tid = 1; tid < blockDim.x; ++tid) + { + _grad_w += cache_grad_sampling_loc[sid]; + _grad_h += cache_grad_sampling_loc[sid + 1]; + _grad_a += cache_grad_attn_weight[tid]; + sid += 2; + } + + + *grad_sampling_loc = _grad_w; + *(grad_sampling_loc + 1) = _grad_h; + *grad_attn_weight = _grad_a; + } + __syncthreads(); + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + +template +__global__ void ms_deformable_col2im_gpu_kernel_shm_reduce_v2(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + extern __shared__ int _s[]; + scalar_t* cache_grad_sampling_loc = (scalar_t*)_s; + scalar_t* cache_grad_attn_weight = cache_grad_sampling_loc + 2 * blockDim.x; + unsigned int tid = threadIdx.x; + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + *(cache_grad_sampling_loc+(threadIdx.x << 1)) = 0; + *(cache_grad_sampling_loc+((threadIdx.x << 1) + 1)) = 0; + *(cache_grad_attn_weight+threadIdx.x)=0; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + cache_grad_sampling_loc+(threadIdx.x << 1), cache_grad_attn_weight+threadIdx.x); + } + + __syncthreads(); + + for (unsigned int s=blockDim.x/2, spre=blockDim.x; s>0; s>>=1, spre>>=1) + { + if (tid < s) { + const unsigned int xid1 = tid << 1; + const unsigned int xid2 = (tid + s) << 1; + cache_grad_attn_weight[tid] += cache_grad_attn_weight[tid + s]; + cache_grad_sampling_loc[xid1] += cache_grad_sampling_loc[xid2]; + cache_grad_sampling_loc[xid1 + 1] += cache_grad_sampling_loc[xid2 + 1]; + if (tid + (s << 1) < spre) + { + cache_grad_attn_weight[tid] += cache_grad_attn_weight[tid + (s << 1)]; + cache_grad_sampling_loc[xid1] += cache_grad_sampling_loc[xid2 + (s << 1)]; + cache_grad_sampling_loc[xid1 + 1] += cache_grad_sampling_loc[xid2 + 1 + (s << 1)]; + } + } + __syncthreads(); + } + + if (tid == 0) + { + *grad_sampling_loc = cache_grad_sampling_loc[0]; + *(grad_sampling_loc + 1) = cache_grad_sampling_loc[1]; + *grad_attn_weight = cache_grad_attn_weight[0]; + } + __syncthreads(); + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + +template +__global__ void ms_deformable_col2im_gpu_kernel_shm_reduce_v2_multi_blocks(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + extern __shared__ int _s[]; + scalar_t* cache_grad_sampling_loc = (scalar_t*)_s; + scalar_t* cache_grad_attn_weight = cache_grad_sampling_loc + 2 * blockDim.x; + unsigned int tid = threadIdx.x; + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + *(cache_grad_sampling_loc+(threadIdx.x << 1)) = 0; + *(cache_grad_sampling_loc+((threadIdx.x << 1) + 1)) = 0; + *(cache_grad_attn_weight+threadIdx.x)=0; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + cache_grad_sampling_loc+(threadIdx.x << 1), cache_grad_attn_weight+threadIdx.x); + } + + __syncthreads(); + + for (unsigned int s=blockDim.x/2, spre=blockDim.x; s>0; s>>=1, spre>>=1) + { + if (tid < s) { + const unsigned int xid1 = tid << 1; + const unsigned int xid2 = (tid + s) << 1; + cache_grad_attn_weight[tid] += cache_grad_attn_weight[tid + s]; + cache_grad_sampling_loc[xid1] += cache_grad_sampling_loc[xid2]; + cache_grad_sampling_loc[xid1 + 1] += cache_grad_sampling_loc[xid2 + 1]; + if (tid + (s << 1) < spre) + { + cache_grad_attn_weight[tid] += cache_grad_attn_weight[tid + (s << 1)]; + cache_grad_sampling_loc[xid1] += cache_grad_sampling_loc[xid2 + (s << 1)]; + cache_grad_sampling_loc[xid1 + 1] += cache_grad_sampling_loc[xid2 + 1 + (s << 1)]; + } + } + __syncthreads(); + } + + if (tid == 0) + { + atomicAdd(grad_sampling_loc, cache_grad_sampling_loc[0]); + atomicAdd(grad_sampling_loc + 1, cache_grad_sampling_loc[1]); + atomicAdd(grad_attn_weight, cache_grad_attn_weight[0]); + } + __syncthreads(); + + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + + +template +__global__ void ms_deformable_col2im_gpu_kernel_gm(const int n, + const scalar_t *grad_col, + const scalar_t *data_value, + const int64_t *data_spatial_shapes, + const int64_t *data_level_start_index, + const scalar_t *data_sampling_loc, + const scalar_t *data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t *grad_value, + scalar_t *grad_sampling_loc, + scalar_t *grad_attn_weight) +{ + CUDA_KERNEL_LOOP(index, n) + { + int _temp = index; + const int c_col = _temp % channels; + _temp /= channels; + const int sampling_index = _temp; + const int m_col = _temp % num_heads; + _temp /= num_heads; + const int q_col = _temp % num_query; + _temp /= num_query; + const int b_col = _temp; + + const scalar_t top_grad = grad_col[index]; + + int data_weight_ptr = sampling_index * num_levels * num_point; + int data_loc_w_ptr = data_weight_ptr << 1; + const int grad_sampling_ptr = data_weight_ptr; + grad_sampling_loc += grad_sampling_ptr << 1; + grad_attn_weight += grad_sampling_ptr; + const int grad_weight_stride = 1; + const int grad_loc_stride = 2; + const int qid_stride = num_heads * channels; + const int data_value_ptr_init_offset = b_col * spatial_size * qid_stride; + + for (int l_col=0; l_col < num_levels; ++l_col) + { + const int level_start_id = data_level_start_index[l_col]; + const int spatial_h_ptr = l_col << 1; + const int spatial_h = data_spatial_shapes[spatial_h_ptr]; + const int spatial_w = data_spatial_shapes[spatial_h_ptr + 1]; + const int value_ptr_offset = data_value_ptr_init_offset + level_start_id * qid_stride; + const scalar_t *data_value_ptr = data_value + value_ptr_offset; + scalar_t *grad_value_ptr = grad_value + value_ptr_offset; + + for (int p_col=0; p_col < num_point; ++p_col) + { + const scalar_t loc_w = data_sampling_loc[data_loc_w_ptr]; + const scalar_t loc_h = data_sampling_loc[data_loc_w_ptr + 1]; + const scalar_t weight = data_attn_weight[data_weight_ptr]; + + const scalar_t h_im = loc_h * spatial_h - 0.5; + const scalar_t w_im = loc_w * spatial_w - 0.5; + if (h_im > -1 && w_im > -1 && h_im < spatial_h && w_im < spatial_w) + { + ms_deform_attn_col2im_bilinear_gm( + data_value_ptr, spatial_h, spatial_w, num_heads, channels, h_im, w_im, m_col, c_col, + top_grad, weight, grad_value_ptr, + grad_sampling_loc, grad_attn_weight); + } + data_weight_ptr += 1; + data_loc_w_ptr += 2; + grad_attn_weight += grad_weight_stride; + grad_sampling_loc += grad_loc_stride; + } + } + } +} + + +template +void ms_deformable_im2col_cuda(cudaStream_t stream, + const scalar_t* data_value, + const int64_t* data_spatial_shapes, + const int64_t* data_level_start_index, + const scalar_t* data_sampling_loc, + const scalar_t* data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t* data_col) +{ + const int num_kernels = batch_size * num_query * num_heads * channels; + const int num_actual_kernels = batch_size * num_query * num_heads * channels; + const int num_threads = CUDA_NUM_THREADS; + ms_deformable_im2col_gpu_kernel + <<>>( + num_kernels, data_value, data_spatial_shapes, data_level_start_index, data_sampling_loc, data_attn_weight, + batch_size, spatial_size, num_heads, channels, num_levels, num_query, num_point, data_col); + + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) + { + printf("error in ms_deformable_im2col_cuda: %s\n", cudaGetErrorString(err)); + } + +} + +template +void ms_deformable_col2im_cuda(cudaStream_t stream, + const scalar_t* grad_col, + const scalar_t* data_value, + const int64_t * data_spatial_shapes, + const int64_t * data_level_start_index, + const scalar_t * data_sampling_loc, + const scalar_t * data_attn_weight, + const int batch_size, + const int spatial_size, + const int num_heads, + const int channels, + const int num_levels, + const int num_query, + const int num_point, + scalar_t* grad_value, + scalar_t* grad_sampling_loc, + scalar_t* grad_attn_weight) +{ + const int num_threads = (channels > CUDA_NUM_THREADS)?CUDA_NUM_THREADS:channels; + const int num_kernels = batch_size * num_query * num_heads * channels; + const int num_actual_kernels = batch_size * num_query * num_heads * channels; + if (channels > 1024) + { + if ((channels & 1023) == 0) + { + ms_deformable_col2im_gpu_kernel_shm_reduce_v2_multi_blocks + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + } + else + { + ms_deformable_col2im_gpu_kernel_gm + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + } + } + else{ + switch(channels) + { + case 1: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 2: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 4: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 8: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 16: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 32: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 64: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 128: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 256: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 512: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + case 1024: + ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + break; + default: + if (channels < 64) + { + ms_deformable_col2im_gpu_kernel_shm_reduce_v1 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + } + else + { + ms_deformable_col2im_gpu_kernel_shm_reduce_v2 + <<>>( + num_kernels, + grad_col, + data_value, + data_spatial_shapes, + data_level_start_index, + data_sampling_loc, + data_attn_weight, + batch_size, + spatial_size, + num_heads, + channels, + num_levels, + num_query, + num_point, + grad_value, + grad_sampling_loc, + grad_attn_weight); + } + } + } + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) + { + printf("error in ms_deformable_col2im_cuda: %s\n", cudaGetErrorString(err)); + } + +} \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/ms_deform_attn.h b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/ms_deform_attn.h new file mode 100644 index 00000000..2f80a1b2 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/ms_deform_attn.h @@ -0,0 +1,67 @@ +/*! +************************************************************************************************** +* Deformable DETR +* Copyright (c) 2020 SenseTime. All Rights Reserved. +* Licensed under the Apache License, Version 2.0 [see LICENSE for details] +************************************************************************************************** +* Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +************************************************************************************************** +*/ + +/*! +* Copyright (c) Facebook, Inc. and its affiliates. +* Modified by Bowen Cheng from https://github.com/fundamentalvision/Deformable-DETR +*/ + +#pragma once + +#include "cpu/ms_deform_attn_cpu.h" + +#ifdef WITH_CUDA +#include "cuda/ms_deform_attn_cuda.h" +#endif + + +at::Tensor +ms_deform_attn_forward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const int im2col_step) +{ + if (value.type().is_cuda()) + { +#ifdef WITH_CUDA + return ms_deform_attn_cuda_forward( + value, spatial_shapes, level_start_index, sampling_loc, attn_weight, im2col_step); +#else + AT_ERROR("Not compiled with GPU support"); +#endif + } + AT_ERROR("Not implemented on the CPU"); +} + +std::vector +ms_deform_attn_backward( + const at::Tensor &value, + const at::Tensor &spatial_shapes, + const at::Tensor &level_start_index, + const at::Tensor &sampling_loc, + const at::Tensor &attn_weight, + const at::Tensor &grad_output, + const int im2col_step) +{ + if (value.type().is_cuda()) + { +#ifdef WITH_CUDA + return ms_deform_attn_cuda_backward( + value, spatial_shapes, level_start_index, sampling_loc, attn_weight, grad_output, im2col_step); +#else + AT_ERROR("Not compiled with GPU support"); +#endif + } + AT_ERROR("Not implemented on the CPU"); +} + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/vision.cpp b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/vision.cpp new file mode 100644 index 00000000..4a08821e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/src/vision.cpp @@ -0,0 +1,21 @@ +/*! +************************************************************************************************** +* Deformable DETR +* Copyright (c) 2020 SenseTime. All Rights Reserved. +* Licensed under the Apache License, Version 2.0 [see LICENSE for details] +************************************************************************************************** +* Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +************************************************************************************************** +*/ + +/*! +* Copyright (c) Facebook, Inc. and its affiliates. +* Modified by Bowen Cheng from https://github.com/fundamentalvision/Deformable-DETR +*/ + +#include "ms_deform_attn.h" + +PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) { + m.def("ms_deform_attn_forward", &ms_deform_attn_forward, "ms_deform_attn_forward"); + m.def("ms_deform_attn_backward", &ms_deform_attn_backward, "ms_deform_attn_backward"); +} diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/test.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/test.py new file mode 100644 index 00000000..6e1b5454 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/pixel_decoder/ops/test.py @@ -0,0 +1,92 @@ +# ------------------------------------------------------------------------------------------------ +# Deformable DETR +# Copyright (c) 2020 SenseTime. All Rights Reserved. +# Licensed under the Apache License, Version 2.0 [see LICENSE for details] +# ------------------------------------------------------------------------------------------------ +# Modified from https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/tree/pytorch_1.0.0 +# ------------------------------------------------------------------------------------------------ + +# Copyright (c) Facebook, Inc. and its affiliates. +# Modified by Bowen Cheng from https://github.com/fundamentalvision/Deformable-DETR + +from __future__ import absolute_import +from __future__ import print_function +from __future__ import division + +import time +import torch +import torch.nn as nn +from torch.autograd import gradcheck + +from functions.ms_deform_attn_func import MSDeformAttnFunction, ms_deform_attn_core_pytorch + + +N, M, D = 1, 2, 2 +Lq, L, P = 2, 2, 2 +shapes = torch.as_tensor([(6, 4), (3, 2)], dtype=torch.long).cuda() +level_start_index = torch.cat((shapes.new_zeros((1, )), shapes.prod(1).cumsum(0)[:-1])) +S = sum([(H*W).item() for H, W in shapes]) + + +torch.manual_seed(3) + + +@torch.no_grad() +def check_forward_equal_with_pytorch_double(): + value = torch.rand(N, S, M, D).cuda() * 0.01 + sampling_locations = torch.rand(N, Lq, M, L, P, 2).cuda() + attention_weights = torch.rand(N, Lq, M, L, P).cuda() + 1e-5 + attention_weights /= attention_weights.sum(-1, keepdim=True).sum(-2, keepdim=True) + im2col_step = 2 + output_pytorch = ms_deform_attn_core_pytorch(value.double(), shapes, sampling_locations.double(), attention_weights.double()).detach().cpu() + output_cuda = MSDeformAttnFunction.apply(value.double(), shapes, level_start_index, sampling_locations.double(), attention_weights.double(), im2col_step).detach().cpu() + fwdok = torch.allclose(output_cuda, output_pytorch) + max_abs_err = (output_cuda - output_pytorch).abs().max() + max_rel_err = ((output_cuda - output_pytorch).abs() / output_pytorch.abs()).max() + + print(f'* {fwdok} check_forward_equal_with_pytorch_double: max_abs_err {max_abs_err:.2e} max_rel_err {max_rel_err:.2e}') + + +@torch.no_grad() +def check_forward_equal_with_pytorch_float(): + value = torch.rand(N, S, M, D).cuda() * 0.01 + sampling_locations = torch.rand(N, Lq, M, L, P, 2).cuda() + attention_weights = torch.rand(N, Lq, M, L, P).cuda() + 1e-5 + attention_weights /= attention_weights.sum(-1, keepdim=True).sum(-2, keepdim=True) + im2col_step = 2 + output_pytorch = ms_deform_attn_core_pytorch(value, shapes, sampling_locations, attention_weights).detach().cpu() + output_cuda = MSDeformAttnFunction.apply(value, shapes, level_start_index, sampling_locations, attention_weights, im2col_step).detach().cpu() + fwdok = torch.allclose(output_cuda, output_pytorch, rtol=1e-2, atol=1e-3) + max_abs_err = (output_cuda - output_pytorch).abs().max() + max_rel_err = ((output_cuda - output_pytorch).abs() / output_pytorch.abs()).max() + + print(f'* {fwdok} check_forward_equal_with_pytorch_float: max_abs_err {max_abs_err:.2e} max_rel_err {max_rel_err:.2e}') + + +def check_gradient_numerical(channels=4, grad_value=True, grad_sampling_loc=True, grad_attn_weight=True): + + value = torch.rand(N, S, M, channels).cuda() * 0.01 + sampling_locations = torch.rand(N, Lq, M, L, P, 2).cuda() + attention_weights = torch.rand(N, Lq, M, L, P).cuda() + 1e-5 + attention_weights /= attention_weights.sum(-1, keepdim=True).sum(-2, keepdim=True) + im2col_step = 2 + func = MSDeformAttnFunction.apply + + value.requires_grad = grad_value + sampling_locations.requires_grad = grad_sampling_loc + attention_weights.requires_grad = grad_attn_weight + + gradok = gradcheck(func, (value.double(), shapes, level_start_index, sampling_locations.double(), attention_weights.double(), im2col_step)) + + print(f'* {gradok} check_gradient_numerical(D={channels})') + + +if __name__ == '__main__': + check_forward_equal_with_pytorch_double() + check_forward_equal_with_pytorch_float() + + for channels in [30, 32, 64, 71, 1025, 2048, 3096]: + check_gradient_numerical(channels, True, True, True) + + + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/__init__.py new file mode 100644 index 00000000..b84bd4ec --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from .oneformer_transformer_decoder import ContrastiveMultiScaleMaskedTransformerDecoder \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/oneformer_transformer_decoder.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/oneformer_transformer_decoder.py new file mode 100644 index 00000000..2887c771 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/oneformer_transformer_decoder.py @@ -0,0 +1,528 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/Mask2Former/blob/main/mask2former/modeling/transformer_decoder/mask2former_transformer_decoder.py +# Modified by Jitesh Jain (https://github.com/praeclarumjj3) +# ------------------------------------------------------------------------------ + +import logging +import fvcore.nn.weight_init as weight_init +from typing import Optional +import torch +from torch import nn, Tensor +from torch.nn import functional as F + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.layers import Conv2d + +from .position_encoding import PositionEmbeddingSine +from .transformer import Transformer + +from annotator.oneformer.detectron2.utils.registry import Registry + + +TRANSFORMER_DECODER_REGISTRY = Registry("TRANSFORMER_MODULE") +TRANSFORMER_DECODER_REGISTRY.__doc__ = """ +Registry for transformer module in OneFormer. +""" + + +def build_transformer_decoder(cfg, in_channels, mask_classification=True): + """ + Build a instance embedding branch from `cfg.MODEL.INS_EMBED_HEAD.NAME`. + """ + name = cfg.MODEL.ONE_FORMER.TRANSFORMER_DECODER_NAME + return TRANSFORMER_DECODER_REGISTRY.get(name)(cfg, in_channels, mask_classification) + + +class SelfAttentionLayer(nn.Module): + + def __init__(self, d_model, nhead, dropout=0.0, + activation="relu", normalize_before=False): + super().__init__() + self.self_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout) + + self.norm = nn.LayerNorm(d_model) + self.dropout = nn.Dropout(dropout) + + self.activation = _get_activation_fn(activation) + self.normalize_before = normalize_before + + self._reset_parameters() + + def _reset_parameters(self): + for p in self.parameters(): + if p.dim() > 1: + nn.init.xavier_uniform_(p) + + def with_pos_embed(self, tensor, pos: Optional[Tensor]): + return tensor if pos is None else tensor + pos + + def forward_post(self, tgt, + tgt_mask: Optional[Tensor] = None, + tgt_key_padding_mask: Optional[Tensor] = None, + query_pos: Optional[Tensor] = None): + q = k = self.with_pos_embed(tgt, query_pos) + tgt2 = self.self_attn(q, k, value=tgt, attn_mask=tgt_mask, + key_padding_mask=tgt_key_padding_mask)[0] + tgt = tgt + self.dropout(tgt2) + tgt = self.norm(tgt) + + return tgt + + def forward_pre(self, tgt, + tgt_mask: Optional[Tensor] = None, + tgt_key_padding_mask: Optional[Tensor] = None, + query_pos: Optional[Tensor] = None): + tgt2 = self.norm(tgt) + q = k = self.with_pos_embed(tgt2, query_pos) + tgt2 = self.self_attn(q, k, value=tgt2, attn_mask=tgt_mask, + key_padding_mask=tgt_key_padding_mask)[0] + tgt = tgt + self.dropout(tgt2) + + return tgt + + def forward(self, tgt, + tgt_mask: Optional[Tensor] = None, + tgt_key_padding_mask: Optional[Tensor] = None, + query_pos: Optional[Tensor] = None): + if self.normalize_before: + return self.forward_pre(tgt, tgt_mask, + tgt_key_padding_mask, query_pos) + return self.forward_post(tgt, tgt_mask, + tgt_key_padding_mask, query_pos) + + +class CrossAttentionLayer(nn.Module): + + def __init__(self, d_model, nhead, dropout=0.0, + activation="relu", normalize_before=False): + super().__init__() + self.multihead_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout) + + self.norm = nn.LayerNorm(d_model) + self.dropout = nn.Dropout(dropout) + + self.activation = _get_activation_fn(activation) + self.normalize_before = normalize_before + + self._reset_parameters() + + def _reset_parameters(self): + for p in self.parameters(): + if p.dim() > 1: + nn.init.xavier_uniform_(p) + + def with_pos_embed(self, tensor, pos: Optional[Tensor]): + return tensor if pos is None else tensor + pos + + def forward_post(self, tgt, memory, + memory_mask: Optional[Tensor] = None, + memory_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None, + query_pos: Optional[Tensor] = None): + tgt2 = self.multihead_attn(query=self.with_pos_embed(tgt, query_pos), + key=self.with_pos_embed(memory, pos), + value=memory, attn_mask=memory_mask, + key_padding_mask=memory_key_padding_mask)[0] + tgt = tgt + self.dropout(tgt2) + tgt = self.norm(tgt) + + return tgt + + def forward_pre(self, tgt, memory, + memory_mask: Optional[Tensor] = None, + memory_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None, + query_pos: Optional[Tensor] = None): + tgt2 = self.norm(tgt) + tgt2 = self.multihead_attn(query=self.with_pos_embed(tgt2, query_pos), + key=self.with_pos_embed(memory, pos), + value=memory, attn_mask=memory_mask, + key_padding_mask=memory_key_padding_mask)[0] + tgt = tgt + self.dropout(tgt2) + + return tgt + + def forward(self, tgt, memory, + memory_mask: Optional[Tensor] = None, + memory_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None, + query_pos: Optional[Tensor] = None): + if self.normalize_before: + return self.forward_pre(tgt, memory, memory_mask, + memory_key_padding_mask, pos, query_pos) + return self.forward_post(tgt, memory, memory_mask, + memory_key_padding_mask, pos, query_pos) + + +class FFNLayer(nn.Module): + + def __init__(self, d_model, dim_feedforward=2048, dropout=0.0, + activation="relu", normalize_before=False): + super().__init__() + # Implementation of Feedforward model + self.linear1 = nn.Linear(d_model, dim_feedforward) + self.dropout = nn.Dropout(dropout) + self.linear2 = nn.Linear(dim_feedforward, d_model) + + self.norm = nn.LayerNorm(d_model) + + self.activation = _get_activation_fn(activation) + self.normalize_before = normalize_before + + self._reset_parameters() + + def _reset_parameters(self): + for p in self.parameters(): + if p.dim() > 1: + nn.init.xavier_uniform_(p) + + def with_pos_embed(self, tensor, pos: Optional[Tensor]): + return tensor if pos is None else tensor + pos + + def forward_post(self, tgt): + tgt2 = self.linear2(self.dropout(self.activation(self.linear1(tgt)))) + tgt = tgt + self.dropout(tgt2) + tgt = self.norm(tgt) + return tgt + + def forward_pre(self, tgt): + tgt2 = self.norm(tgt) + tgt2 = self.linear2(self.dropout(self.activation(self.linear1(tgt2)))) + tgt = tgt + self.dropout(tgt2) + return tgt + + def forward(self, tgt): + if self.normalize_before: + return self.forward_pre(tgt) + return self.forward_post(tgt) + + +def _get_activation_fn(activation): + """Return an activation function given a string""" + if activation == "relu": + return F.relu + if activation == "gelu": + return F.gelu + if activation == "glu": + return F.glu + raise RuntimeError(F"activation should be relu/gelu, not {activation}.") + + +class MLP(nn.Module): + """ Very simple multi-layer perceptron (also called FFN)""" + + def __init__(self, input_dim, hidden_dim, output_dim, num_layers): + super().__init__() + self.num_layers = num_layers + h = [hidden_dim] * (num_layers - 1) + self.layers = nn.ModuleList(nn.Linear(n, k) for n, k in zip([input_dim] + h, h + [output_dim])) + + def forward(self, x): + for i, layer in enumerate(self.layers): + x = F.relu(layer(x)) if i < self.num_layers - 1 else layer(x) + return x + + +@TRANSFORMER_DECODER_REGISTRY.register() +class ContrastiveMultiScaleMaskedTransformerDecoder(nn.Module): + + _version = 2 + + def _load_from_state_dict( + self, state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs + ): + version = local_metadata.get("version", None) + if version is None or version < 2: + # Do not warn if train from scratch + scratch = True + logger = logging.getLogger(__name__) + for k in list(state_dict.keys()): + newk = k + if "static_query" in k: + newk = k.replace("static_query", "query_feat") + if newk != k: + state_dict[newk] = state_dict[k] + del state_dict[k] + scratch = False + + if not scratch: + logger.warning( + f"Weight format of {self.__class__.__name__} have changed! " + "Please upgrade your models. Applying automatic conversion now ..." + ) + + @configurable + def __init__( + self, + in_channels, + mask_classification=True, + *, + num_classes: int, + hidden_dim: int, + num_queries: int, + nheads: int, + dropout: float, + dim_feedforward: int, + enc_layers: int, + is_train: bool, + dec_layers: int, + class_dec_layers: int, + pre_norm: bool, + mask_dim: int, + enforce_input_project: bool, + use_task_norm: bool, + ): + """ + NOTE: this interface is experimental. + Args: + in_channels: channels of the input features + mask_classification: whether to add mask classifier or not + num_classes: number of classes + hidden_dim: Transformer feature dimension + num_queries: number of queries + nheads: number of heads + dim_feedforward: feature dimension in feedforward network + enc_layers: number of Transformer encoder layers + dec_layers: number of Transformer decoder layers + pre_norm: whether to use pre-LayerNorm or not + mask_dim: mask feature dimension + enforce_input_project: add input project 1x1 conv even if input + channels and hidden dim is identical + """ + super().__init__() + + assert mask_classification, "Only support mask classification model" + self.mask_classification = mask_classification + self.is_train = is_train + self.use_task_norm = use_task_norm + + # positional encoding + N_steps = hidden_dim // 2 + self.pe_layer = PositionEmbeddingSine(N_steps, normalize=True) + + self.class_transformer = Transformer( + d_model=hidden_dim, + dropout=dropout, + nhead=nheads, + dim_feedforward=dim_feedforward, + num_encoder_layers=enc_layers, + num_decoder_layers=class_dec_layers, + normalize_before=pre_norm, + return_intermediate_dec=False, + ) + + # define Transformer decoder here + self.num_heads = nheads + self.num_layers = dec_layers + self.transformer_self_attention_layers = nn.ModuleList() + self.transformer_cross_attention_layers = nn.ModuleList() + self.transformer_ffn_layers = nn.ModuleList() + + for _ in range(self.num_layers): + self.transformer_self_attention_layers.append( + SelfAttentionLayer( + d_model=hidden_dim, + nhead=nheads, + dropout=0.0, + normalize_before=pre_norm, + ) + ) + + self.transformer_cross_attention_layers.append( + CrossAttentionLayer( + d_model=hidden_dim, + nhead=nheads, + dropout=0.0, + normalize_before=pre_norm, + ) + ) + + self.transformer_ffn_layers.append( + FFNLayer( + d_model=hidden_dim, + dim_feedforward=dim_feedforward, + dropout=0.0, + normalize_before=pre_norm, + ) + ) + + self.decoder_norm = nn.LayerNorm(hidden_dim) + + self.num_queries = num_queries + # learnable query p.e. + self.query_embed = nn.Embedding(num_queries, hidden_dim) + + # level embedding (we always use 3 scales) + self.num_feature_levels = 3 + self.level_embed = nn.Embedding(self.num_feature_levels, hidden_dim) + self.input_proj = nn.ModuleList() + for _ in range(self.num_feature_levels): + if in_channels != hidden_dim or enforce_input_project: + self.input_proj.append(Conv2d(in_channels, hidden_dim, kernel_size=1)) + weight_init.c2_xavier_fill(self.input_proj[-1]) + else: + self.input_proj.append(nn.Sequential()) + + self.class_input_proj = Conv2d(in_channels, hidden_dim, kernel_size=1) + weight_init.c2_xavier_fill(self.class_input_proj) + + # output FFNs + if self.mask_classification: + self.class_embed = nn.Linear(hidden_dim, num_classes + 1) + self.mask_embed = MLP(hidden_dim, hidden_dim, mask_dim, 3) + + @classmethod + def from_config(cls, cfg, in_channels, mask_classification): + ret = {} + ret["in_channels"] = in_channels + ret["mask_classification"] = mask_classification + + ret["num_classes"] = cfg.MODEL.SEM_SEG_HEAD.NUM_CLASSES + ret["hidden_dim"] = cfg.MODEL.ONE_FORMER.HIDDEN_DIM + ret["num_queries"] = cfg.MODEL.ONE_FORMER.NUM_OBJECT_QUERIES + # Transformer parameters: + ret["nheads"] = cfg.MODEL.ONE_FORMER.NHEADS + ret["dim_feedforward"] = cfg.MODEL.ONE_FORMER.DIM_FEEDFORWARD + + # NOTE: because we add learnable query features which requires supervision, + # we add minus 1 to decoder layers to be consistent with our loss + # implementation: that is, number of auxiliary losses is always + # equal to number of decoder layers. With learnable query features, the number of + # auxiliary losses equals number of decoders plus 1. + assert cfg.MODEL.ONE_FORMER.DEC_LAYERS >= 1 + ret["dec_layers"] = cfg.MODEL.ONE_FORMER.DEC_LAYERS - 1 + ret["class_dec_layers"] = cfg.MODEL.ONE_FORMER.CLASS_DEC_LAYERS + ret["enc_layers"] = cfg.MODEL.ONE_FORMER.ENC_LAYERS + ret["dropout"] = cfg.MODEL.ONE_FORMER.DROPOUT + ret["pre_norm"] = cfg.MODEL.ONE_FORMER.PRE_NORM + ret["enforce_input_project"] = cfg.MODEL.ONE_FORMER.ENFORCE_INPUT_PROJ + ret["is_train"] = cfg.MODEL.IS_TRAIN + ret["mask_dim"] = cfg.MODEL.SEM_SEG_HEAD.MASK_DIM + ret["use_task_norm"] = cfg.MODEL.ONE_FORMER.USE_TASK_NORM + + return ret + + def forward(self, x, mask_features, tasks, mask = None): + # x is a list of multi-scale feature + assert len(x) == self.num_feature_levels + src = [] + pos = [] + size_list = [] + + # disable mask, it does not affect performance + del mask + + for i in range(self.num_feature_levels): + size_list.append(x[i].shape[-2:]) + pos.append(self.pe_layer(x[i], None).flatten(2)) + src.append(self.input_proj[i](x[i]).flatten(2) + self.level_embed.weight[i][None, :, None]) + + # flatten NxCxHxW to HWxNxC + pos[-1] = pos[-1].permute(2, 0, 1) + src[-1] = src[-1].permute(2, 0, 1) + + _, bs, _ = src[0].shape + + # QxNxC + query_embed = self.query_embed.weight.unsqueeze(1).repeat(1, bs, 1) + tasks = tasks.unsqueeze(0) + if self.use_task_norm: + tasks = self.decoder_norm(tasks) + + feats = self.pe_layer(mask_features, None) + + out_t, _ = self.class_transformer(feats, None, + self.query_embed.weight[:-1], + self.class_input_proj(mask_features), + tasks if self.use_task_norm else None) + out_t = out_t[0].permute(1, 0, 2) + + out = torch.cat([out_t, tasks], dim=0) + + output = out.clone() + + predictions_class = [] + predictions_mask = [] + + # prediction heads on learnable query features + outputs_class, outputs_mask, attn_mask = self.forward_prediction_heads(output, mask_features, attn_mask_target_size=size_list[0], i=0) + predictions_class.append(outputs_class) + predictions_mask.append(outputs_mask) + + for i in range(self.num_layers): + level_index = i % self.num_feature_levels + attn_mask[torch.where(attn_mask.sum(-1) == attn_mask.shape[-1])] = False + # attention: cross-attention first + output = self.transformer_cross_attention_layers[i]( + output, src[level_index], + memory_mask=attn_mask, + memory_key_padding_mask=None, # here we do not apply masking on padded region + pos=pos[level_index], query_pos=query_embed + ) + + output = self.transformer_self_attention_layers[i]( + output, tgt_mask=None, + tgt_key_padding_mask=None, + query_pos=query_embed + ) + + # FFN + output = self.transformer_ffn_layers[i]( + output + ) + + outputs_class, outputs_mask, attn_mask = self.forward_prediction_heads(output, mask_features, attn_mask_target_size=size_list[(i + 1) % self.num_feature_levels], i=i+1) + predictions_class.append(outputs_class) + predictions_mask.append(outputs_mask) + + assert len(predictions_class) == self.num_layers + 1 + if self.is_train: + query_class = out.permute(1, 0, 2) + else: + query_class = None + out = { + 'contrastive_logits': query_class, + 'pred_logits': predictions_class[-1], + 'pred_masks': predictions_mask[-1], + 'aux_outputs': self._set_aux_loss( + predictions_class if self.mask_classification else None, + predictions_mask, + ) + } + + return out + + def forward_prediction_heads(self, output, mask_features, attn_mask_target_size, i): + decoder_output = self.decoder_norm(output) + decoder_output = decoder_output.transpose(0, 1) + outputs_class = self.class_embed(decoder_output) + mask_embed = self.mask_embed(decoder_output) + outputs_mask = torch.einsum("bqc,bchw->bqhw", mask_embed, mask_features) + + # NOTE: prediction is of higher-resolution + # [B, Q, H, W] -> [B, Q, H*W] -> [B, h, Q, H*W] -> [B*h, Q, HW] + attn_mask = F.interpolate(outputs_mask, size=attn_mask_target_size, mode="bilinear", align_corners=False) + + # save_attn_masks(attn_mask.sigmoid() < 0.5, fname=f'demo/maps/{i}_pre_bool') + + # must use bool type + # If a BoolTensor is provided, positions with ``True`` are not allowed to attend while ``False`` values will be unchanged. + attn_mask = (attn_mask.sigmoid().flatten(2).unsqueeze(1).repeat(1, self.num_heads, 1, 1).flatten(0, 1) < 0.5).bool() + attn_mask = attn_mask.detach() + + return outputs_class, outputs_mask, attn_mask + + @torch.jit.unused + def _set_aux_loss(self, outputs_class, outputs_seg_masks): + # this is a workaround to make torchscript happy, as torchscript + # doesn't support dictionary with non-homogeneous values, such + # as a dict having both a Tensor and a list. + if self.mask_classification: + aux_list = [ + {"pred_logits": a, "pred_masks": b} + for a, b in zip(outputs_class[:-1], outputs_seg_masks[:-1]) + ] + else: + aux_list = [{"pred_masks": b} for b, in outputs_seg_masks[:-1]] + + return aux_list \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/position_encoding.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/position_encoding.py new file mode 100644 index 00000000..051984d9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/position_encoding.py @@ -0,0 +1,67 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/Mask2Former/blob/main/mask2former/modeling/transformer_decoder/position_encoding.py +# Modified by Jitesh Jain (https://github.com/praeclarumjj3) +# ------------------------------------------------------------------------------ + +""" +Various positional encodings for the transformer. +""" +import math + +import torch +from torch import nn + + +class PositionEmbeddingSine(nn.Module): + """ + This is a more standard version of the position embedding, very similar to the one + used by the Attention is all you need paper, generalized to work on images. + """ + + def __init__(self, num_pos_feats=64, temperature=10000, normalize=False, scale=None): + super().__init__() + self.num_pos_feats = num_pos_feats + self.temperature = temperature + self.normalize = normalize + if scale is not None and normalize is False: + raise ValueError("normalize should be True if scale is passed") + if scale is None: + scale = 2 * math.pi + self.scale = scale + + def forward(self, x, mask=None): + if mask is None: + mask = torch.zeros((x.size(0), x.size(2), x.size(3)), device=x.device, dtype=torch.bool) + not_mask = ~mask + y_embed = not_mask.cumsum(1, dtype=torch.float32) + x_embed = not_mask.cumsum(2, dtype=torch.float32) + if self.normalize: + eps = 1e-6 + y_embed = y_embed / (y_embed[:, -1:, :] + eps) * self.scale + x_embed = x_embed / (x_embed[:, :, -1:] + eps) * self.scale + + dim_t = torch.arange(self.num_pos_feats, dtype=torch.float32, device=x.device) + dim_t = self.temperature ** (2 * (dim_t // 2) / self.num_pos_feats) + + pos_x = x_embed[:, :, :, None] / dim_t + pos_y = y_embed[:, :, :, None] / dim_t + pos_x = torch.stack( + (pos_x[:, :, :, 0::2].sin(), pos_x[:, :, :, 1::2].cos()), dim=4 + ).flatten(3) + pos_y = torch.stack( + (pos_y[:, :, :, 0::2].sin(), pos_y[:, :, :, 1::2].cos()), dim=4 + ).flatten(3) + pos = torch.cat((pos_y, pos_x), dim=3).permute(0, 3, 1, 2) + return pos + + def __repr__(self, _repr_indent=4): + head = "Positional encoding " + self.__class__.__name__ + body = [ + "num_pos_feats: {}".format(self.num_pos_feats), + "temperature: {}".format(self.temperature), + "normalize: {}".format(self.normalize), + "scale: {}".format(self.scale), + ] + # _repr_indent = 4 + lines = [head] + [" " * _repr_indent + line for line in body] + return "\n".join(lines) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/text_transformer.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/text_transformer.py new file mode 100644 index 00000000..d0b72920 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/text_transformer.py @@ -0,0 +1,257 @@ +# ------------------------------------------------------------------------- +# MIT License +# +# Copyright (c) 2021 OpenAI +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ------------------------------------------------------------------------- + +import torch +import torch.utils.checkpoint as checkpoint +from torch import nn +from collections import OrderedDict +from timm.models.layers import trunc_normal_ + +class Attention(nn.Module): + def __init__(self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0., proj_drop=0.): + super().__init__() + self.num_heads = num_heads + head_dim = dim // num_heads + # NOTE scale factor was wrong in my original version, can set manually to be compat with prev weights + self.scale = qk_scale or head_dim ** -0.5 + + self.q_proj = nn.Linear(dim, dim, bias=qkv_bias) + self.k_proj = nn.Linear(dim, dim, bias=qkv_bias) + self.v_proj = nn.Linear(dim, dim, bias=qkv_bias) + + + self.attn_drop = nn.Dropout(attn_drop) + self.proj = nn.Linear(dim, dim) + self.proj_drop = nn.Dropout(proj_drop) + + def forward(self, q, k, v): + B, N, C = q.shape + assert k.shape == v.shape + B, M, C = k.shape + q = self.q_proj(q).reshape(B, N, self.num_heads, C // self.num_heads) + k = self.k_proj(k).reshape(B, M, self.num_heads, C // self.num_heads) + v = self.v_proj(v).reshape(B, M, self.num_heads, C // self.num_heads) + + attn = torch.einsum('bnkc,bmkc->bknm', q, k) * self.scale + + attn = attn.softmax(dim=-1) + + x = torch.einsum('bknm,bmkc->bnkc', attn, v).reshape(B, N, C) + + x = self.proj(x) + x = self.proj_drop(x) + return x + +class TransformerDecoderLayer(nn.Module): + def __init__( + self, + d_model, + nhead, + dropout=0.1, + ): + super().__init__() + self.self_attn = Attention(d_model, nhead, proj_drop=dropout) + self.cross_attn = Attention(d_model, nhead, proj_drop=dropout) + + self.norm1 = nn.LayerNorm(d_model) + self.norm2 = nn.LayerNorm(d_model) + self.norm3 = nn.LayerNorm(d_model) + self.dropout = nn.Dropout(dropout) + + self.mlp = nn.Sequential( + nn.Linear(d_model, d_model * 4), + nn.GELU(), + nn.Dropout(dropout), + nn.Linear(d_model * 4, d_model) + ) + + def forward(self, x, mem): + q = k = v = self.norm1(x) + x = x + self.self_attn(q, k, v) + q = self.norm2(x) + x = x + self.cross_attn(q, mem, mem) + x = x + self.dropout(self.mlp(self.norm3(x))) + return x + + +class ContextDecoder(nn.Module): + def __init__(self, + transformer_width=256, + transformer_heads=4, + transformer_layers=6, + visual_dim=1024, + dropout=0.1, + **kwargs): + super().__init__() + + self.memory_proj = nn.Sequential( + nn.LayerNorm(visual_dim), + nn.Linear(visual_dim, transformer_width), + nn.LayerNorm(transformer_width), + ) + + self.text_proj = nn.Sequential( + nn.LayerNorm(visual_dim), + nn.Linear(visual_dim, transformer_width), + ) + + self.decoder = nn.ModuleList([ + TransformerDecoderLayer(transformer_width, transformer_heads, dropout) for _ in range(transformer_layers) + ]) + + self.out_proj = nn.Sequential( + nn.LayerNorm(transformer_width), + nn.Linear(transformer_width, visual_dim) + ) + + self.apply(self._init_weights) + + def _init_weights(self, m): + if isinstance(m, nn.Linear): + trunc_normal_(m.weight, std=.02) + if isinstance(m, nn.Linear) and m.bias is not None: + nn.init.constant_(m.bias, 0) + elif isinstance(m, nn.LayerNorm): + nn.init.constant_(m.bias, 0) + nn.init.constant_(m.weight, 1.0) + + + def forward(self, text, visual): + B, N, C = visual.shape + visual = self.memory_proj(visual) + x = self.text_proj(text) + + for layer in self.decoder: + x = layer(x, visual) + + return self.out_proj(x) + + +class QuickGELU(nn.Module): + + def forward(self, x: torch.Tensor): + return x * torch.sigmoid(1.702 * x) + + +class ResidualAttentionBlock(nn.Module): + + def __init__(self, d_model: int, n_head: int, attn_mask: torch.Tensor = None): + super().__init__() + + self.attn = nn.MultiheadAttention(d_model, n_head) + self.ln_1 = nn.LayerNorm(d_model) + self.mlp = nn.Sequential( + OrderedDict([('c_fc', nn.Linear(d_model, d_model * 4)), ('gelu', QuickGELU()), + ('c_proj', nn.Linear(d_model * 4, d_model))])) + self.ln_2 = nn.LayerNorm(d_model) + self.attn_mask = attn_mask + + def attention(self, x: torch.Tensor, key_padding_mask: torch.Tensor): + self.attn_mask = self.attn_mask.to(dtype=x.dtype, device=x.device) if self.attn_mask is not None else None + return self.attn(x, x, x, need_weights=False, attn_mask=self.attn_mask, key_padding_mask=key_padding_mask)[0] + + def forward(self, x: torch.Tensor, key_padding_mask=None): + x = x + self.attention(self.ln_1(x), key_padding_mask=key_padding_mask) + x = x + self.mlp(self.ln_2(x)) + return x + +class Transformer(nn.Module): + + def __init__(self, width: int, layers: int, heads: int, attn_mask: torch.Tensor = None, use_checkpoint=False): + super().__init__() + self.width = width + self.layers = layers + self.resblocks = nn.Sequential(*[ResidualAttentionBlock(width, heads, attn_mask) for _ in range(layers)]) + proj_std = (self.width**-0.5) * ((2 * self.layers)**-0.5) + attn_std = self.width**-0.5 + fc_std = (2 * self.width)**-0.5 + for block in self.resblocks: + nn.init.normal_(block.attn.in_proj_weight, std=attn_std) + nn.init.normal_(block.attn.out_proj.weight, std=proj_std) + nn.init.normal_(block.mlp.c_fc.weight, std=fc_std) + nn.init.normal_(block.mlp.c_proj.weight, std=proj_std) + + self.use_checkpoint = use_checkpoint + + def forward(self, x: torch.Tensor): + for resblock in self.resblocks: + if self.use_checkpoint: + x = checkpoint.checkpoint(resblock, x) + else: + x = resblock(x) + return x + + +class TextTransformer(nn.Module): + + def __init__( + self, + context_length: int, + width: int, + layers: int, + vocab_size, + use_checkpoint=False, + ): + + super().__init__() + heads = width // 64 + self.context_length = context_length + self.width = width + self.transformer = Transformer( + width=width, + layers=layers, + heads=heads, + attn_mask=self.build_attention_mask(), + use_checkpoint=use_checkpoint) + + self.positional_embedding = nn.Parameter(torch.empty(self.context_length, width)) + self.ln_final = nn.LayerNorm(width) + self.token_embedding = nn.Embedding(vocab_size, width) + nn.init.normal_(self.token_embedding.weight, std=0.02) + + # initialization + nn.init.normal_(self.positional_embedding, std=0.01) + + def build_attention_mask(self): + # lazily create causal attention mask, with full attention between the vision tokens + # pytorch uses additive attention mask; fill with -inf + mask = torch.empty(self.context_length, self.context_length) + mask.fill_(float('-inf')) + mask.triu_(1) # zero out the lower diagonal + return mask + + def forward(self, text): + x = self.token_embedding(text) + x = x + self.positional_embedding + x = x.permute(1, 0, 2) # NLD -> LND + x = self.transformer(x) + x = x.permute(1, 0, 2) # LND -> NLD + x = self.ln_final(x) + + # x.shape = [batch_size, n_ctx, transformer.width] + # take features from the eot embedding (eot_token is the highest number in each sequence) + x = x[torch.arange(x.shape[0]), text.argmax(dim=-1)] + + return x \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/transformer.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/transformer.py new file mode 100644 index 00000000..cd075256 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/modeling/transformer_decoder/transformer.py @@ -0,0 +1,376 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/Mask2Former/blob/main/mask2former/modeling/transformer_decoder/transformer.py +# Modified by Jitesh Jain (https://github.com/praeclarumjj3) +# ------------------------------------------------------------------------------ + +""" +Transformer class. + +Copy-paste from torch.nn.Transformer with modifications: + * positional encodings are passed in MHattention + * extra LN at the end of encoder is removed + * decoder returns a stack of activations from all decoding layers +""" +import copy +from typing import List, Optional + +import torch +import torch.nn.functional as F +from torch import Tensor, nn + + +class Transformer(nn.Module): + def __init__( + self, + d_model=512, + nhead=8, + num_encoder_layers=6, + num_decoder_layers=6, + dim_feedforward=2048, + dropout=0.1, + activation="relu", + normalize_before=False, + return_intermediate_dec=False, + ): + super().__init__() + + encoder_layer = TransformerEncoderLayer( + d_model, nhead, dim_feedforward, dropout, activation, normalize_before + ) + encoder_norm = nn.LayerNorm(d_model) if normalize_before else None + self.encoder = TransformerEncoder(encoder_layer, num_encoder_layers, encoder_norm) + + decoder_layer = TransformerDecoderLayer( + d_model, nhead, dim_feedforward, dropout, activation, normalize_before + ) + decoder_norm = nn.LayerNorm(d_model) + self.decoder = TransformerDecoder( + decoder_layer, + num_decoder_layers, + decoder_norm, + return_intermediate=return_intermediate_dec, + ) + + self._reset_parameters() + + self.d_model = d_model + self.nhead = nhead + + def _reset_parameters(self): + for p in self.parameters(): + if p.dim() > 1: + nn.init.xavier_uniform_(p) + + def forward(self, src, mask, query_embed, pos_embed, task_token=None): + # flatten NxCxHxW to HWxNxC + bs, c, h, w = src.shape + src = src.flatten(2).permute(2, 0, 1) + pos_embed = pos_embed.flatten(2).permute(2, 0, 1) + query_embed = query_embed.unsqueeze(1).repeat(1, bs, 1) + if mask is not None: + mask = mask.flatten(1) + + if task_token is None: + tgt = torch.zeros_like(query_embed) + else: + tgt = task_token.repeat(query_embed.shape[0], 1, 1) + + memory = self.encoder(src, src_key_padding_mask=mask, pos=pos_embed) + hs = self.decoder( + tgt, memory, memory_key_padding_mask=mask, pos=pos_embed, query_pos=query_embed + ) + return hs.transpose(1, 2), memory.permute(1, 2, 0).view(bs, c, h, w) + + +class TransformerEncoder(nn.Module): + def __init__(self, encoder_layer, num_layers, norm=None): + super().__init__() + self.layers = _get_clones(encoder_layer, num_layers) + self.num_layers = num_layers + self.norm = norm + + def forward( + self, + src, + mask: Optional[Tensor] = None, + src_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None, + ): + output = src + + for layer in self.layers: + output = layer( + output, src_mask=mask, src_key_padding_mask=src_key_padding_mask, pos=pos + ) + + if self.norm is not None: + output = self.norm(output) + + return output + + +class TransformerDecoder(nn.Module): + def __init__(self, decoder_layer, num_layers, norm=None, return_intermediate=False): + super().__init__() + self.layers = _get_clones(decoder_layer, num_layers) + self.num_layers = num_layers + self.norm = norm + self.return_intermediate = return_intermediate + + def forward( + self, + tgt, + memory, + tgt_mask: Optional[Tensor] = None, + memory_mask: Optional[Tensor] = None, + tgt_key_padding_mask: Optional[Tensor] = None, + memory_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None, + query_pos: Optional[Tensor] = None, + ): + output = tgt + + intermediate = [] + + for layer in self.layers: + output = layer( + output, + memory, + tgt_mask=tgt_mask, + memory_mask=memory_mask, + tgt_key_padding_mask=tgt_key_padding_mask, + memory_key_padding_mask=memory_key_padding_mask, + pos=pos, + query_pos=query_pos, + ) + if self.return_intermediate: + intermediate.append(self.norm(output)) + + if self.norm is not None: + output = self.norm(output) + if self.return_intermediate: + intermediate.pop() + intermediate.append(output) + + if self.return_intermediate: + return torch.stack(intermediate) + + return output.unsqueeze(0) + + +class TransformerEncoderLayer(nn.Module): + def __init__( + self, + d_model, + nhead, + dim_feedforward=2048, + dropout=0.1, + activation="relu", + normalize_before=False, + ): + super().__init__() + self.self_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout) + # Implementation of Feedforward model + self.linear1 = nn.Linear(d_model, dim_feedforward) + self.dropout = nn.Dropout(dropout) + self.linear2 = nn.Linear(dim_feedforward, d_model) + + self.norm1 = nn.LayerNorm(d_model) + self.norm2 = nn.LayerNorm(d_model) + self.dropout1 = nn.Dropout(dropout) + self.dropout2 = nn.Dropout(dropout) + + self.activation = _get_activation_fn(activation) + self.normalize_before = normalize_before + + def with_pos_embed(self, tensor, pos: Optional[Tensor]): + return tensor if pos is None else tensor + pos + + def forward_post( + self, + src, + src_mask: Optional[Tensor] = None, + src_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None, + ): + q = k = self.with_pos_embed(src, pos) + src2 = self.self_attn( + q, k, value=src, attn_mask=src_mask, key_padding_mask=src_key_padding_mask + )[0] + src = src + self.dropout1(src2) + src = self.norm1(src) + src2 = self.linear2(self.dropout(self.activation(self.linear1(src)))) + src = src + self.dropout2(src2) + src = self.norm2(src) + return src + + def forward_pre( + self, + src, + src_mask: Optional[Tensor] = None, + src_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None, + ): + src2 = self.norm1(src) + q = k = self.with_pos_embed(src2, pos) + src2 = self.self_attn( + q, k, value=src2, attn_mask=src_mask, key_padding_mask=src_key_padding_mask + )[0] + src = src + self.dropout1(src2) + src2 = self.norm2(src) + src2 = self.linear2(self.dropout(self.activation(self.linear1(src2)))) + src = src + self.dropout2(src2) + return src + + def forward( + self, + src, + src_mask: Optional[Tensor] = None, + src_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None, + ): + if self.normalize_before: + return self.forward_pre(src, src_mask, src_key_padding_mask, pos) + return self.forward_post(src, src_mask, src_key_padding_mask, pos) + + +class TransformerDecoderLayer(nn.Module): + def __init__( + self, + d_model, + nhead, + dim_feedforward=2048, + dropout=0.1, + activation="relu", + normalize_before=False, + ): + super().__init__() + self.self_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout) + self.multihead_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout) + # Implementation of Feedforward model + self.linear1 = nn.Linear(d_model, dim_feedforward) + self.dropout = nn.Dropout(dropout) + self.linear2 = nn.Linear(dim_feedforward, d_model) + + self.norm1 = nn.LayerNorm(d_model) + self.norm2 = nn.LayerNorm(d_model) + self.norm3 = nn.LayerNorm(d_model) + self.dropout1 = nn.Dropout(dropout) + self.dropout2 = nn.Dropout(dropout) + self.dropout3 = nn.Dropout(dropout) + + self.activation = _get_activation_fn(activation) + self.normalize_before = normalize_before + + def with_pos_embed(self, tensor, pos: Optional[Tensor]): + return tensor if pos is None else tensor + pos + + def forward_post( + self, + tgt, + memory, + tgt_mask: Optional[Tensor] = None, + memory_mask: Optional[Tensor] = None, + tgt_key_padding_mask: Optional[Tensor] = None, + memory_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None, + query_pos: Optional[Tensor] = None, + ): + q = k = self.with_pos_embed(tgt, query_pos) + tgt2 = self.self_attn( + q, k, value=tgt, attn_mask=tgt_mask, key_padding_mask=tgt_key_padding_mask + )[0] + tgt = tgt + self.dropout1(tgt2) + tgt = self.norm1(tgt) + tgt2 = self.multihead_attn( + query=self.with_pos_embed(tgt, query_pos), + key=self.with_pos_embed(memory, pos), + value=memory, + attn_mask=memory_mask, + key_padding_mask=memory_key_padding_mask, + )[0] + tgt = tgt + self.dropout2(tgt2) + tgt = self.norm2(tgt) + tgt2 = self.linear2(self.dropout(self.activation(self.linear1(tgt)))) + tgt = tgt + self.dropout3(tgt2) + tgt = self.norm3(tgt) + return tgt + + def forward_pre( + self, + tgt, + memory, + tgt_mask: Optional[Tensor] = None, + memory_mask: Optional[Tensor] = None, + tgt_key_padding_mask: Optional[Tensor] = None, + memory_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None, + query_pos: Optional[Tensor] = None, + ): + tgt2 = self.norm1(tgt) + q = k = self.with_pos_embed(tgt2, query_pos) + tgt2 = self.self_attn( + q, k, value=tgt2, attn_mask=tgt_mask, key_padding_mask=tgt_key_padding_mask + )[0] + tgt = tgt + self.dropout1(tgt2) + tgt2 = self.norm2(tgt) + tgt2 = self.multihead_attn( + query=self.with_pos_embed(tgt2, query_pos), + key=self.with_pos_embed(memory, pos), + value=memory, + attn_mask=memory_mask, + key_padding_mask=memory_key_padding_mask, + )[0] + tgt = tgt + self.dropout2(tgt2) + tgt2 = self.norm3(tgt) + tgt2 = self.linear2(self.dropout(self.activation(self.linear1(tgt2)))) + tgt = tgt + self.dropout3(tgt2) + return tgt + + def forward( + self, + tgt, + memory, + tgt_mask: Optional[Tensor] = None, + memory_mask: Optional[Tensor] = None, + tgt_key_padding_mask: Optional[Tensor] = None, + memory_key_padding_mask: Optional[Tensor] = None, + pos: Optional[Tensor] = None, + query_pos: Optional[Tensor] = None, + ): + if self.normalize_before: + return self.forward_pre( + tgt, + memory, + tgt_mask, + memory_mask, + tgt_key_padding_mask, + memory_key_padding_mask, + pos, + query_pos, + ) + return self.forward_post( + tgt, + memory, + tgt_mask, + memory_mask, + tgt_key_padding_mask, + memory_key_padding_mask, + pos, + query_pos, + ) + + +def _get_clones(module, N): + return nn.ModuleList([copy.deepcopy(module) for i in range(N)]) + + +def _get_activation_fn(activation): + """Return an activation function given a string""" + if activation == "relu": + return F.relu + if activation == "gelu": + return F.gelu + if activation == "glu": + return F.glu + raise RuntimeError(f"activation should be relu/gelu, not {activation}.") diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/oneformer_model.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/oneformer_model.py new file mode 100644 index 00000000..8bb18a85 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/oneformer_model.py @@ -0,0 +1,470 @@ +# ------------------------------------------------------------------------------ +# Reference: https://github.com/facebookresearch/Mask2Former/blob/main/mask2former/maskformer_model.py +# Modified by Jitesh Jain (https://github.com/praeclarumjj3) +# ------------------------------------------------------------------------------ + +from typing import Tuple + +import torch +from torch import nn +from torch.nn import functional as F + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.data import MetadataCatalog +from annotator.oneformer.detectron2.modeling import META_ARCH_REGISTRY, build_backbone, build_sem_seg_head +from annotator.oneformer.detectron2.modeling.backbone import Backbone +from annotator.oneformer.detectron2.modeling.postprocessing import sem_seg_postprocess +from annotator.oneformer.detectron2.structures import Boxes, ImageList, Instances, BitMasks +from annotator.oneformer.detectron2.utils.memory import retry_if_cuda_oom + +from .modeling.matcher import HungarianMatcher +from einops import rearrange +from .modeling.transformer_decoder.text_transformer import TextTransformer +from .modeling.transformer_decoder.oneformer_transformer_decoder import MLP +from annotator.oneformer.oneformer.data.tokenizer import SimpleTokenizer, Tokenize + +@META_ARCH_REGISTRY.register() +class OneFormer(nn.Module): + """ + Main class for mask classification semantic segmentation architectures. + """ + + @configurable + def __init__( + self, + *, + backbone: Backbone, + sem_seg_head: nn.Module, + task_mlp: nn.Module, + text_encoder: nn.Module, + text_projector: nn.Module, + prompt_ctx: nn.Embedding, + num_queries: int, + object_mask_threshold: float, + overlap_threshold: float, + metadata, + size_divisibility: int, + sem_seg_postprocess_before_inference: bool, + pixel_mean: Tuple[float], + pixel_std: Tuple[float], + # inference + semantic_on: bool, + panoptic_on: bool, + instance_on: bool, + detection_on: bool, + test_topk_per_image: int, + task_seq_len: int, + max_seq_len: int, + is_demo: bool, + ): + """ + Args: + backbone: a backbone module, must follow detectron2's backbone interface + sem_seg_head: a module that predicts semantic segmentation from backbone features + criterion: a module that defines the loss + num_queries: int, number of queries + object_mask_threshold: float, threshold to filter query based on classification score + for panoptic segmentation inference + overlap_threshold: overlap threshold used in general inference for panoptic segmentation + metadata: dataset meta, get `thing` and `stuff` category names for panoptic + segmentation inference + size_divisibility: Some backbones require the input height and width to be divisible by a + specific integer. We can use this to override such requirement. + sem_seg_postprocess_before_inference: whether to resize the prediction back + to original input size before semantic segmentation inference or after. + For high-resolution dataset like Mapillary, resizing predictions before + inference will cause OOM error. + pixel_mean, pixel_std: list or tuple with #channels element, representing + the per-channel mean and std to be used to normalize the input image + semantic_on: bool, whether to output semantic segmentation prediction + instance_on: bool, whether to output instance segmentation prediction + panoptic_on: bool, whether to output panoptic segmentation prediction + test_topk_per_image: int, instance segmentation parameter, keep topk instances per image + """ + super().__init__() + self.backbone = backbone + self.sem_seg_head = sem_seg_head + self.task_mlp = task_mlp + self.text_encoder = text_encoder + self.text_projector = text_projector + self.prompt_ctx = prompt_ctx + self.num_queries = num_queries + self.overlap_threshold = overlap_threshold + self.object_mask_threshold = object_mask_threshold + self.metadata = metadata + if size_divisibility < 0: + # use backbone size_divisibility if not set + size_divisibility = self.backbone.size_divisibility + self.size_divisibility = size_divisibility + self.sem_seg_postprocess_before_inference = sem_seg_postprocess_before_inference + self.register_buffer("pixel_mean", torch.Tensor(pixel_mean).view(-1, 1, 1), False) + self.register_buffer("pixel_std", torch.Tensor(pixel_std).view(-1, 1, 1), False) + + # additional args + self.semantic_on = semantic_on + self.instance_on = instance_on + self.panoptic_on = panoptic_on + self.detection_on = detection_on + self.test_topk_per_image = test_topk_per_image + + self.text_tokenizer = Tokenize(SimpleTokenizer(), max_seq_len=max_seq_len) + self.task_tokenizer = Tokenize(SimpleTokenizer(), max_seq_len=task_seq_len) + self.is_demo = is_demo + + self.thing_indices = [k for k in self.metadata.thing_dataset_id_to_contiguous_id.keys()] + + if not self.semantic_on: + assert self.sem_seg_postprocess_before_inference + + @classmethod + def from_config(cls, cfg): + backbone = build_backbone(cfg) + sem_seg_head = build_sem_seg_head(cfg, backbone.output_shape()) + + if cfg.MODEL.IS_TRAIN: + text_encoder = TextTransformer(context_length=cfg.MODEL.TEXT_ENCODER.CONTEXT_LENGTH, + width=cfg.MODEL.TEXT_ENCODER.WIDTH, + layers=cfg.MODEL.TEXT_ENCODER.NUM_LAYERS, + vocab_size=cfg.MODEL.TEXT_ENCODER.VOCAB_SIZE) + text_projector = MLP(text_encoder.width, cfg.MODEL.ONE_FORMER.HIDDEN_DIM, + cfg.MODEL.ONE_FORMER.HIDDEN_DIM, cfg.MODEL.TEXT_ENCODER.PROJ_NUM_LAYERS) + if cfg.MODEL.TEXT_ENCODER.N_CTX > 0: + prompt_ctx = nn.Embedding(cfg.MODEL.TEXT_ENCODER.N_CTX, cfg.MODEL.TEXT_ENCODER.WIDTH) + else: + prompt_ctx = None + else: + text_encoder = None + text_projector = None + prompt_ctx = None + + task_mlp = MLP(cfg.INPUT.TASK_SEQ_LEN, cfg.MODEL.ONE_FORMER.HIDDEN_DIM, + cfg.MODEL.ONE_FORMER.HIDDEN_DIM, 2) + + # Loss parameters: + deep_supervision = cfg.MODEL.ONE_FORMER.DEEP_SUPERVISION + no_object_weight = cfg.MODEL.ONE_FORMER.NO_OBJECT_WEIGHT + + # loss weights + class_weight = cfg.MODEL.ONE_FORMER.CLASS_WEIGHT + dice_weight = cfg.MODEL.ONE_FORMER.DICE_WEIGHT + mask_weight = cfg.MODEL.ONE_FORMER.MASK_WEIGHT + contrastive_weight = cfg.MODEL.ONE_FORMER.CONTRASTIVE_WEIGHT + + # building criterion + matcher = HungarianMatcher( + cost_class=class_weight, + cost_mask=mask_weight, + cost_dice=dice_weight, + num_points=cfg.MODEL.ONE_FORMER.TRAIN_NUM_POINTS, + ) + + weight_dict = {"loss_ce": class_weight, "loss_mask": mask_weight, + "loss_dice": dice_weight, "loss_contrastive": contrastive_weight} + + + if deep_supervision: + dec_layers = cfg.MODEL.ONE_FORMER.DEC_LAYERS + aux_weight_dict = {} + for i in range(dec_layers - 1): + aux_weight_dict.update({k + f"_{i}": v for k, v in weight_dict.items()}) + weight_dict.update(aux_weight_dict) + + losses = ["labels", "masks", "contrastive"] + + return { + "backbone": backbone, + "sem_seg_head": sem_seg_head, + "task_mlp": task_mlp, + "prompt_ctx": prompt_ctx, + "text_encoder": text_encoder, + "text_projector": text_projector, + "num_queries": cfg.MODEL.ONE_FORMER.NUM_OBJECT_QUERIES, + "object_mask_threshold": cfg.MODEL.TEST.OBJECT_MASK_THRESHOLD, + "overlap_threshold": cfg.MODEL.TEST.OVERLAP_THRESHOLD, + "metadata": MetadataCatalog.get(cfg.DATASETS.TRAIN[0]), + "size_divisibility": cfg.MODEL.ONE_FORMER.SIZE_DIVISIBILITY, + "sem_seg_postprocess_before_inference": ( + cfg.MODEL.TEST.SEM_SEG_POSTPROCESSING_BEFORE_INFERENCE + or cfg.MODEL.TEST.PANOPTIC_ON + or cfg.MODEL.TEST.INSTANCE_ON + ), + "pixel_mean": cfg.MODEL.PIXEL_MEAN, + "pixel_std": cfg.MODEL.PIXEL_STD, + # inference + "semantic_on": cfg.MODEL.TEST.SEMANTIC_ON, + "instance_on": cfg.MODEL.TEST.INSTANCE_ON, + "panoptic_on": cfg.MODEL.TEST.PANOPTIC_ON, + "detection_on": cfg.MODEL.TEST.DETECTION_ON, + "test_topk_per_image": cfg.TEST.DETECTIONS_PER_IMAGE, + "task_seq_len": cfg.INPUT.TASK_SEQ_LEN, + "max_seq_len": cfg.INPUT.MAX_SEQ_LEN, + "is_demo": cfg.MODEL.IS_DEMO, + } + + @property + def device(self): + return self.pixel_mean.device + + def encode_text(self, text): + assert text.ndim in [2, 3], text.ndim + b = text.shape[0] + squeeze_dim = False + num_text = 1 + if text.ndim == 3: + num_text = text.shape[1] + text = rearrange(text, 'b n l -> (b n) l', n=num_text) + squeeze_dim = True + + # [B, C] + x = self.text_encoder(text) + + text_x = self.text_projector(x) + + if squeeze_dim: + text_x = rearrange(text_x, '(b n) c -> b n c', n=num_text) + if self.prompt_ctx is not None: + text_ctx = self.prompt_ctx.weight.unsqueeze(0).repeat(text_x.shape[0], 1, 1) + text_x = torch.cat([text_x, text_ctx], dim=1) + + return {"texts": text_x} + + def forward(self, batched_inputs): + """ + Args: + batched_inputs: a list, batched outputs of :class:`DatasetMapper`. + Each item in the list contains the inputs for one image. + For now, each item in the list is a dict that contains: + * "image": Tensor, image in (C, H, W) format. + * "instances": per-region ground truth + * Other information that's included in the original dicts, such as: + "height", "width" (int): the output resolution of the model (may be different + from input resolution), used in inference. + Returns: + list[dict]: + each dict has the results for one image. The dict contains the following keys: + * "sem_seg": + A Tensor that represents the + per-pixel segmentation prediced by the head. + The prediction has shape KxHxW that represents the logits of + each class for each pixel. + * "panoptic_seg": + A tuple that represent panoptic output + panoptic_seg (Tensor): of shape (height, width) where the values are ids for each segment. + segments_info (list[dict]): Describe each segment in `panoptic_seg`. + Each dict contains keys "id", "category_id", "isthing". + """ + images = [x["image"].to(self.device) for x in batched_inputs] + images = [(x - self.pixel_mean) / self.pixel_std for x in images] + images = ImageList.from_tensors(images, self.size_divisibility) + + tasks = torch.cat([self.task_tokenizer(x["task"]).to(self.device).unsqueeze(0) for x in batched_inputs], dim=0) + tasks = self.task_mlp(tasks.float()) + + features = self.backbone(images.tensor) + outputs = self.sem_seg_head(features, tasks) + + if self.training: + texts = torch.cat([self.text_tokenizer(x["text"]).to(self.device).unsqueeze(0) for x in batched_inputs], dim=0) + texts_x = self.encode_text(texts) + + outputs = {**outputs, **texts_x} + + # mask classification target + if "instances" in batched_inputs[0]: + gt_instances = [x["instances"].to(self.device) for x in batched_inputs] + targets = self.prepare_targets(gt_instances, images) + else: + targets = None + + # bipartite matching-based loss + losses = self.criterion(outputs, targets) + + for k in list(losses.keys()): + if k in self.criterion.weight_dict: + losses[k] *= self.criterion.weight_dict[k] + else: + # remove this loss if not specified in `weight_dict` + losses.pop(k) + return losses + else: + mask_cls_results = outputs["pred_logits"] + mask_pred_results = outputs["pred_masks"] + # upsample masks + mask_pred_results = F.interpolate( + mask_pred_results, + size=(images.tensor.shape[-2], images.tensor.shape[-1]), + mode="bilinear", + align_corners=False, + ) + + del outputs + + processed_results = [] + for i, data in enumerate(zip( + mask_cls_results, mask_pred_results, batched_inputs, images.image_sizes + )): + mask_cls_result, mask_pred_result, input_per_image, image_size = data + height = input_per_image.get("height", image_size[0]) + width = input_per_image.get("width", image_size[1]) + processed_results.append({}) + + if self.sem_seg_postprocess_before_inference: + mask_pred_result = retry_if_cuda_oom(sem_seg_postprocess)( + mask_pred_result, image_size, height, width + ) + mask_cls_result = mask_cls_result.to(mask_pred_result) + + # semantic segmentation inference + if self.semantic_on: + r = retry_if_cuda_oom(self.semantic_inference)(mask_cls_result, mask_pred_result) + if not self.sem_seg_postprocess_before_inference: + r = retry_if_cuda_oom(sem_seg_postprocess)(r, image_size, height, width) + processed_results[-1]["sem_seg"] = r + + # panoptic segmentation inference + if self.panoptic_on: + panoptic_r = retry_if_cuda_oom(self.panoptic_inference)(mask_cls_result, mask_pred_result) + processed_results[-1]["panoptic_seg"] = panoptic_r + + # instance segmentation inference + if self.instance_on: + instance_r = retry_if_cuda_oom(self.instance_inference)(mask_cls_result, mask_pred_result) + processed_results[-1]["instances"] = instance_r + + if self.detection_on: + bbox_r = retry_if_cuda_oom(self.instance_inference)(mask_cls_result, mask_pred_result) + processed_results[-1]["box_instances"] = bbox_r + + return processed_results + + def prepare_targets(self, targets, images): + h_pad, w_pad = images.tensor.shape[-2:] + new_targets = [] + for targets_per_image in targets: + # pad gt + gt_masks = targets_per_image.gt_masks + padded_masks = torch.zeros((gt_masks.shape[0], h_pad, w_pad), dtype=gt_masks.dtype, device=gt_masks.device) + padded_masks[:, : gt_masks.shape[1], : gt_masks.shape[2]] = gt_masks + new_targets.append( + { + "labels": targets_per_image.gt_classes, + "masks": padded_masks, + } + ) + return new_targets + + def semantic_inference(self, mask_cls, mask_pred): + mask_cls = F.softmax(mask_cls, dim=-1)[..., :-1] + mask_pred = mask_pred.sigmoid() + semseg = torch.einsum("qc,qhw->chw", mask_cls, mask_pred) + return semseg + + def panoptic_inference(self, mask_cls, mask_pred): + scores, labels = F.softmax(mask_cls, dim=-1).max(-1) + mask_pred = mask_pred.sigmoid() + + keep = labels.ne(self.sem_seg_head.num_classes) & (scores > self.object_mask_threshold) + cur_scores = scores[keep] + cur_classes = labels[keep] + cur_masks = mask_pred[keep] + cur_mask_cls = mask_cls[keep] + cur_mask_cls = cur_mask_cls[:, :-1] + + cur_prob_masks = cur_scores.view(-1, 1, 1) * cur_masks + + h, w = cur_masks.shape[-2:] + panoptic_seg = torch.zeros((h, w), dtype=torch.int32, device=cur_masks.device) + segments_info = [] + + current_segment_id = 0 + + if cur_masks.shape[0] == 0: + # We didn't detect any mask :( + return panoptic_seg, segments_info + else: + # take argmax + cur_mask_ids = cur_prob_masks.argmax(0) + stuff_memory_list = {} + for k in range(cur_classes.shape[0]): + pred_class = cur_classes[k].item() + isthing = pred_class in self.metadata.thing_dataset_id_to_contiguous_id.values() + mask_area = (cur_mask_ids == k).sum().item() + original_area = (cur_masks[k] >= 0.5).sum().item() + mask = (cur_mask_ids == k) & (cur_masks[k] >= 0.5) + + if mask_area > 0 and original_area > 0 and mask.sum().item() > 0: + if mask_area / original_area < self.overlap_threshold: + continue + + # merge stuff regions + if not isthing: + if int(pred_class) in stuff_memory_list.keys(): + panoptic_seg[mask] = stuff_memory_list[int(pred_class)] + continue + else: + stuff_memory_list[int(pred_class)] = current_segment_id + 1 + + current_segment_id += 1 + panoptic_seg[mask] = current_segment_id + + segments_info.append( + { + "id": current_segment_id, + "isthing": bool(isthing), + "category_id": int(pred_class), + } + ) + + return panoptic_seg, segments_info + + def instance_inference(self, mask_cls, mask_pred): + # mask_pred is already processed to have the same shape as original input + image_size = mask_pred.shape[-2:] + + # [Q, K] + scores = F.softmax(mask_cls, dim=-1)[:, :-1] + labels = torch.arange(self.sem_seg_head.num_classes, device=self.device).unsqueeze(0).repeat(self.num_queries, 1).flatten(0, 1) + + # scores_per_image, topk_indices = scores.flatten(0, 1).topk(self.num_queries, sorted=False) + scores_per_image, topk_indices = scores.flatten(0, 1).topk(self.test_topk_per_image, sorted=False) + labels_per_image = labels[topk_indices] + + topk_indices = topk_indices // self.sem_seg_head.num_classes + # mask_pred = mask_pred.unsqueeze(1).repeat(1, self.sem_seg_head.num_classes, 1).flatten(0, 1) + mask_pred = mask_pred[topk_indices] + + # Only consider scores with confidence over [self.object_mask_threshold] for demo + if self.is_demo: + keep = scores_per_image > self.object_mask_threshold + scores_per_image = scores_per_image[keep] + labels_per_image = labels_per_image[keep] + mask_pred = mask_pred[keep] + + # if this is panoptic segmentation, we only keep the "thing" classes + if self.panoptic_on: + keep = torch.zeros_like(scores_per_image).bool() + for i, lab in enumerate(labels_per_image): + keep[i] = lab in self.metadata.thing_dataset_id_to_contiguous_id.values() + + scores_per_image = scores_per_image[keep] + labels_per_image = labels_per_image[keep] + mask_pred = mask_pred[keep] + + if 'ade20k' in self.metadata.name: + for i in range(labels_per_image.shape[0]): + labels_per_image[i] = self.thing_indices.index(labels_per_image[i].item()) + + result = Instances(image_size) + # mask (before sigmoid) + result.pred_masks = (mask_pred > 0).float() + if self.detection_on: + # Uncomment the following to get boxes from masks (this is slow) + result.pred_boxes = BitMasks(mask_pred > 0).get_bounding_boxes() + else: + result.pred_boxes = Boxes(torch.zeros(mask_pred.size(0), 4)) + + # calculate average mask prob + mask_scores_per_image = (mask_pred.sigmoid().flatten(1) * result.pred_masks.flatten(1)).sum(1) / (result.pred_masks.flatten(1).sum(1) + 1e-6) + result.scores = scores_per_image * mask_scores_per_image + result.pred_classes = labels_per_image + return result \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/__init__.py new file mode 100644 index 00000000..130d3011 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from .events import setup_wandb, WandbWriter \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/box_ops.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/box_ops.py new file mode 100644 index 00000000..a2b62ad9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/box_ops.py @@ -0,0 +1,133 @@ +# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved +""" +Utilities for bounding box manipulation and GIoU. +""" +import torch, os +from torchvision.ops.boxes import box_area + + +def box_cxcywh_to_xyxy(x): + x_c, y_c, w, h = x.unbind(-1) + b = [(x_c - 0.5 * w), (y_c - 0.5 * h), + (x_c + 0.5 * w), (y_c + 0.5 * h)] + return torch.stack(b, dim=-1) + + +def box_xyxy_to_cxcywh(x): + x0, y0, x1, y1 = x.unbind(-1) + b = [(x0 + x1) / 2, (y0 + y1) / 2, + (x1 - x0), (y1 - y0)] + return torch.stack(b, dim=-1) + + +# modified from torchvision to also return the union +def box_iou(boxes1, boxes2): + area1 = box_area(boxes1) + area2 = box_area(boxes2) + + # import ipdb; ipdb.set_trace() + lt = torch.max(boxes1[:, None, :2], boxes2[:, :2]) # [N,M,2] + rb = torch.min(boxes1[:, None, 2:], boxes2[:, 2:]) # [N,M,2] + + wh = (rb - lt).clamp(min=0) # [N,M,2] + inter = wh[:, :, 0] * wh[:, :, 1] # [N,M] + + union = area1[:, None] + area2 - inter + + iou = inter / (union + 1e-6) + return iou, union + + +def generalized_box_iou(boxes1, boxes2): + """ + Generalized IoU from https://giou.stanford.edu/ + The boxes should be in [x0, y0, x1, y1] format + Returns a [N, M] pairwise matrix, where N = len(boxes1) + and M = len(boxes2) + """ + # degenerate boxes gives inf / nan results + # so do an early check + assert (boxes1[:, 2:] >= boxes1[:, :2]).all() + assert (boxes2[:, 2:] >= boxes2[:, :2]).all() + # except: + # import ipdb; ipdb.set_trace() + iou, union = box_iou(boxes1, boxes2) + + lt = torch.min(boxes1[:, None, :2], boxes2[:, :2]) + rb = torch.max(boxes1[:, None, 2:], boxes2[:, 2:]) + + wh = (rb - lt).clamp(min=0) # [N,M,2] + area = wh[:, :, 0] * wh[:, :, 1] + + return iou - (area - union) / (area + 1e-6) + + + +# modified from torchvision to also return the union +def box_iou_pairwise(boxes1, boxes2): + area1 = box_area(boxes1) + area2 = box_area(boxes2) + + lt = torch.max(boxes1[:, :2], boxes2[:, :2]) # [N,2] + rb = torch.min(boxes1[:, 2:], boxes2[:, 2:]) # [N,2] + + wh = (rb - lt).clamp(min=0) # [N,2] + inter = wh[:, 0] * wh[:, 1] # [N] + + union = area1 + area2 - inter + + iou = inter / union + return iou, union + + +def generalized_box_iou_pairwise(boxes1, boxes2): + """ + Generalized IoU from https://giou.stanford.edu/ + Input: + - boxes1, boxes2: N,4 + Output: + - giou: N, 4 + """ + # degenerate boxes gives inf / nan results + # so do an early check + assert (boxes1[:, 2:] >= boxes1[:, :2]).all() + assert (boxes2[:, 2:] >= boxes2[:, :2]).all() + assert boxes1.shape == boxes2.shape + iou, union = box_iou_pairwise(boxes1, boxes2) # N, 4 + + lt = torch.min(boxes1[:, :2], boxes2[:, :2]) + rb = torch.max(boxes1[:, 2:], boxes2[:, 2:]) + + wh = (rb - lt).clamp(min=0) # [N,2] + area = wh[:, 0] * wh[:, 1] + + return iou - (area - union) / area + +def masks_to_boxes(masks): + """Compute the bounding boxes around the provided masks + The masks should be in format [N, H, W] where N is the number of masks, (H, W) are the spatial dimensions. + Returns a [N, 4] tensors, with the boxes in xyxy format + """ + if masks.numel() == 0: + return torch.zeros((0, 4), device=masks.device) + + h, w = masks.shape[-2:] + + y = torch.arange(0, h, dtype=torch.float) + x = torch.arange(0, w, dtype=torch.float) + y, x = torch.meshgrid(y, x) + + x_mask = (masks * x.unsqueeze(0)) + x_max = x_mask.flatten(1).max(-1)[0] + x_min = x_mask.masked_fill(~(masks.bool()), 1e8).flatten(1).min(-1)[0] + + y_mask = (masks * y.unsqueeze(0)) + y_max = y_mask.flatten(1).max(-1)[0] + y_min = y_mask.masked_fill(~(masks.bool()), 1e8).flatten(1).min(-1)[0] + + return torch.stack([x_min, y_min, x_max, y_max], 1) + +if __name__ == '__main__': + x = torch.rand(5, 4) + y = torch.rand(3, 4) + iou, union = box_iou(x, y) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/events.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/events.py new file mode 100644 index 00000000..3c81e8f6 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/events.py @@ -0,0 +1,120 @@ +import os +import wandb +from annotator.oneformer.detectron2.utils import comm +from annotator.oneformer.detectron2.utils.events import EventWriter, get_event_storage + + +def setup_wandb(cfg, args): + if comm.is_main_process(): + init_args = { + k.lower(): v + for k, v in cfg.WANDB.items() + if isinstance(k, str) and k not in ["config"] + } + # only include most related part to avoid too big table + # TODO: add configurable params to select which part of `cfg` should be saved in config + if "config_exclude_keys" in init_args: + init_args["config"] = cfg + init_args["config"]["cfg_file"] = args.config_file + else: + init_args["config"] = { + "model": cfg.MODEL, + "solver": cfg.SOLVER, + "cfg_file": args.config_file, + } + if ("name" not in init_args) or (init_args["name"] is None): + init_args["name"] = os.path.basename(args.config_file) + else: + init_args["name"] = init_args["name"] + '_' + os.path.basename(args.config_file) + wandb.init(**init_args) + + +class BaseRule(object): + def __call__(self, target): + return target + + +class IsIn(BaseRule): + def __init__(self, keyword: str): + self.keyword = keyword + + def __call__(self, target): + return self.keyword in target + + +class Prefix(BaseRule): + def __init__(self, keyword: str): + self.keyword = keyword + + def __call__(self, target): + return "/".join([self.keyword, target]) + + +class WandbWriter(EventWriter): + """ + Write all scalars to a tensorboard file. + """ + + def __init__(self): + """ + Args: + log_dir (str): the directory to save the output events + kwargs: other arguments passed to `torch.utils.tensorboard.SummaryWriter(...)` + """ + self._last_write = -1 + self._group_rules = [ + (IsIn("/"), BaseRule()), + (IsIn("loss"), Prefix("train")), + ] + + def write(self): + + storage = get_event_storage() + + def _group_name(scalar_name): + for (rule, op) in self._group_rules: + if rule(scalar_name): + return op(scalar_name) + return scalar_name + + stats = { + _group_name(name): scalars[0] + for name, scalars in storage.latest().items() + if scalars[1] > self._last_write + } + if len(stats) > 0: + self._last_write = max([v[1] for k, v in storage.latest().items()]) + + # storage.put_{image,histogram} is only meant to be used by + # tensorboard writer. So we access its internal fields directly from here. + if len(storage._vis_data) >= 1: + stats["image"] = [ + wandb.Image(img, caption=img_name) + for img_name, img, step_num in storage._vis_data + ] + # Storage stores all image data and rely on this writer to clear them. + # As a result it assumes only one writer will use its image data. + # An alternative design is to let storage store limited recent + # data (e.g. only the most recent image) that all writers can access. + # In that case a writer may not see all image data if its period is long. + storage.clear_images() + + if len(storage._histograms) >= 1: + + def create_bar(tag, bucket_limits, bucket_counts, **kwargs): + data = [ + [label, val] for (label, val) in zip(bucket_limits, bucket_counts) + ] + table = wandb.Table(data=data, columns=["label", "value"]) + return wandb.plot.bar(table, "label", "value", title=tag) + + stats["hist"] = [create_bar(**params) for params in storage._histograms] + + storage.clear_histograms() + + if len(stats) == 0: + return + wandb.log(stats, step=storage.iter) + + def close(self): + wandb.finish() \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/misc.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/misc.py new file mode 100644 index 00000000..f2bca773 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/misc.py @@ -0,0 +1,197 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# Modified by Bowen Cheng from https://github.com/facebookresearch/detr/blob/master/util/misc.py +""" +Misc functions, including distributed helpers. + +Mostly copy-paste from torchvision references. +""" +from typing import List, Optional + +import torch +import torch.distributed as dist +import torchvision +from torch import Tensor +import warnings +import torch.nn.functional as F +import math + +def inverse_sigmoid(x, eps=1e-3): + x = x.clamp(min=0, max=1) + x1 = x.clamp(min=eps) + x2 = (1 - x).clamp(min=eps) + return torch.log(x1/x2) + +def _no_grad_trunc_normal_(tensor, mean, std, a, b): + # Cut & paste from PyTorch official master until it's in a few official releases - RW + # Method based on https://people.sc.fsu.edu/~jburkardt/presentations/truncated_normal.pdf + def norm_cdf(x): + # Computes standard normal cumulative distribution function + return (1. + math.erf(x / math.sqrt(2.))) / 2. + + if (mean < a - 2 * std) or (mean > b + 2 * std): + warnings.warn("mean is more than 2 std from [a, b] in nn.init.trunc_normal_. " + "The distribution of values may be incorrect.", + stacklevel=2) + + with torch.no_grad(): + # Values are generated by using a truncated uniform distribution and + # then using the inverse CDF for the normal distribution. + # Get upper and lower cdf values + l = norm_cdf((a - mean) / std) + u = norm_cdf((b - mean) / std) + + # Uniformly fill tensor with values from [l, u], then translate to + # [2l-1, 2u-1]. + tensor.uniform_(2 * l - 1, 2 * u - 1) + + # Use inverse cdf transform for normal distribution to get truncated + # standard normal + tensor.erfinv_() + + # Transform to proper mean, std + tensor.mul_(std * math.sqrt(2.)) + tensor.add_(mean) + + # Clamp to ensure it's in the proper range + tensor.clamp_(min=a, max=b) + return tensor + +def trunc_normal_(tensor, mean=0., std=1., a=-2., b=2.): + # type: (Tensor, float, float, float, float) -> Tensor + r"""Fills the input Tensor with values drawn from a truncated + normal distribution. The values are effectively drawn from the + normal distribution :math:`\mathcal{N}(\text{mean}, \text{std}^2)` + with values outside :math:`[a, b]` redrawn until they are within + the bounds. The method used for generating the random values works + best when :math:`a \leq \text{mean} \leq b`. + Args: + tensor: an n-dimensional `torch.Tensor` + mean: the mean of the normal distribution + std: the standard deviation of the normal distribution + a: the minimum cutoff value + b: the maximum cutoff value + Examples: + >>> w = torch.empty(3, 5) + >>> nn.init.trunc_normal_(w) + """ + return _no_grad_trunc_normal_(tensor, mean, std, a, b) + +def resize(input, + size=None, + scale_factor=None, + mode='nearest', + align_corners=None, + warning=True): + if warning: + if size is not None and align_corners: + input_h, input_w = tuple(int(x) for x in input.shape[2:]) + output_h, output_w = tuple(int(x) for x in size) + if output_h > input_h or output_w > output_h: + if ((output_h > 1 and output_w > 1 and input_h > 1 + and input_w > 1) and (output_h - 1) % (input_h - 1) + and (output_w - 1) % (input_w - 1)): + warnings.warn( + f'When align_corners={align_corners}, ' + 'the output would more aligned if ' + f'input size {(input_h, input_w)} is `x+1` and ' + f'out size {(output_h, output_w)} is `nx+1`') + if isinstance(size, torch.Size): + size = tuple(int(x) for x in size) + return F.interpolate(input, size, scale_factor, mode, align_corners) + +def _max_by_axis(the_list): + # type: (List[List[int]]) -> List[int] + maxes = the_list[0] + for sublist in the_list[1:]: + for index, item in enumerate(sublist): + maxes[index] = max(maxes[index], item) + return maxes + + +class NestedTensor(object): + def __init__(self, tensors, mask: Optional[Tensor]): + self.tensors = tensors + self.mask = mask + + def to(self, device): + # type: (Device) -> NestedTensor # noqa + cast_tensor = self.tensors.to(device) + mask = self.mask + if mask is not None: + assert mask is not None + cast_mask = mask.to(device) + else: + cast_mask = None + return NestedTensor(cast_tensor, cast_mask) + + def decompose(self): + return self.tensors, self.mask + + def __repr__(self): + return str(self.tensors) + + +def nested_tensor_from_tensor_list(tensor_list: List[Tensor]): + # TODO make this more general + if tensor_list[0].ndim == 3: + if torchvision._is_tracing(): + # nested_tensor_from_tensor_list() does not export well to ONNX + # call _onnx_nested_tensor_from_tensor_list() instead + return _onnx_nested_tensor_from_tensor_list(tensor_list) + + # TODO make it support different-sized images + max_size = _max_by_axis([list(img.shape) for img in tensor_list]) + # min_size = tuple(min(s) for s in zip(*[img.shape for img in tensor_list])) + batch_shape = [len(tensor_list)] + max_size + b, c, h, w = batch_shape + dtype = tensor_list[0].dtype + device = tensor_list[0].device + tensor = torch.zeros(batch_shape, dtype=dtype, device=device) + mask = torch.ones((b, h, w), dtype=torch.bool, device=device) + for img, pad_img, m in zip(tensor_list, tensor, mask): + pad_img[: img.shape[0], : img.shape[1], : img.shape[2]].copy_(img) + m[: img.shape[1], : img.shape[2]] = False + else: + raise ValueError("not supported") + return NestedTensor(tensor, mask) + + +# _onnx_nested_tensor_from_tensor_list() is an implementation of +# nested_tensor_from_tensor_list() that is supported by ONNX tracing. +@torch.jit.unused +def _onnx_nested_tensor_from_tensor_list(tensor_list: List[Tensor]) -> NestedTensor: + max_size = [] + for i in range(tensor_list[0].dim()): + max_size_i = torch.max( + torch.stack([img.shape[i] for img in tensor_list]).to(torch.float32) + ).to(torch.int64) + max_size.append(max_size_i) + max_size = tuple(max_size) + + # work around for + # pad_img[: img.shape[0], : img.shape[1], : img.shape[2]].copy_(img) + # m[: img.shape[1], :img.shape[2]] = False + # which is not yet supported in onnx + padded_imgs = [] + padded_masks = [] + for img in tensor_list: + padding = [(s1 - s2) for s1, s2 in zip(max_size, tuple(img.shape))] + padded_img = torch.nn.functional.pad(img, (0, padding[2], 0, padding[1], 0, padding[0])) + padded_imgs.append(padded_img) + + m = torch.zeros_like(img[0], dtype=torch.int, device=img.device) + padded_mask = torch.nn.functional.pad(m, (0, padding[2], 0, padding[1]), "constant", 1) + padded_masks.append(padded_mask.to(torch.bool)) + + tensor = torch.stack(padded_imgs) + mask = torch.stack(padded_masks) + + return NestedTensor(tensor, mask=mask) + + +def is_dist_avail_and_initialized(): + if not dist.is_available(): + return False + if not dist.is_initialized(): + return False + return True diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/pos_embed.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/pos_embed.py new file mode 100644 index 00000000..aa11d60d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/utils/pos_embed.py @@ -0,0 +1,122 @@ +# -------------------------------------------------------- +# Position embedding utils +# -------------------------------------------------------- + +from typing import Tuple + +import numpy as np +import torch + + +# -------------------------------------------------------- +# 2D sine-cosine position embedding +# References: +# Transformer: https://github.com/tensorflow/models/blob/master/official/nlp/transformer/model_utils.py +# MoCo v3: https://github.com/facebookresearch/moco-v3 +# -------------------------------------------------------- +def get_2d_sincos_pos_embed(embed_dim, grid_size, cls_token=False): + """ + grid_size: int of the grid height and width + return: + pos_embed: [grid_size*grid_size, embed_dim] or [1+grid_size*grid_size, embed_dim] (w/ or w/o cls_token) + """ + grid_h = np.arange(grid_size, dtype=np.float32) + grid_w = np.arange(grid_size, dtype=np.float32) + grid = np.meshgrid(grid_w, grid_h) # here w goes first + grid = np.stack(grid, axis=0) + + grid = grid.reshape([2, 1, grid_size, grid_size]) + pos_embed = get_2d_sincos_pos_embed_from_grid(embed_dim, grid) + if cls_token: + pos_embed = np.concatenate([np.zeros([1, embed_dim]), pos_embed], axis=0) + return pos_embed + + +def get_2d_sincos_pos_embed_from_grid(embed_dim, grid): + assert embed_dim % 2 == 0 + + # use half of dimensions to encode grid_h + emb_h = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[0]) # (H*W, D/2) + emb_w = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[1]) # (H*W, D/2) + + emb = np.concatenate([emb_h, emb_w], axis=1) # (H*W, D) + return emb + + +def get_1d_sincos_pos_embed_from_grid(embed_dim, pos): + """ + embed_dim: output dimension for each position + pos: a list of positions to be encoded: size (M,) + out: (M, D) + """ + assert embed_dim % 2 == 0 + omega = np.arange(embed_dim // 2, dtype=np.float) + omega /= embed_dim / 2.0 + omega = 1.0 / 10000 ** omega # (D/2,) + + pos = pos.reshape(-1) # (M,) + out = np.einsum("m,d->md", pos, omega) # (M, D/2), outer product + + emb_sin = np.sin(out) # (M, D/2) + emb_cos = np.cos(out) # (M, D/2) + + emb = np.concatenate([emb_sin, emb_cos], axis=1) # (M, D) + return emb + + +# -------------------------------------------------------- +# Interpolate position embeddings for high-resolution +# References: +# DeiT: https://github.com/facebookresearch/deit +# -------------------------------------------------------- +def interpolate_pos_embed(model, checkpoint_model, pos_embed_key): + if pos_embed_key in checkpoint_model: + pos_embed_checkpoint = checkpoint_model[pos_embed_key] + embedding_size = pos_embed_checkpoint.shape[-1] + num_patches = model.num_patches + if pos_embed_key.startswith("decoder"): + num_extra_tokens = model.decoder_pos_embed.shape[-2] - num_patches + else: + num_extra_tokens = model.pos_embed.shape[-2] - num_patches + # height (== width) for the checkpoint position embedding + orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5) + # height (== width) for the new position embedding + new_size = int(num_patches ** 0.5) + # class_token and dist_token are kept unchanged + if orig_size != new_size: + print( + "Position interpolate from %dx%d to %dx%d" + % (orig_size, orig_size, new_size, new_size) + ) + extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens] + # only the position tokens are interpolated + pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:] + pos_tokens = pos_tokens.reshape( + -1, orig_size, orig_size, embedding_size + ).permute(0, 3, 1, 2) + pos_tokens = torch.nn.functional.interpolate( + pos_tokens, + size=(new_size, new_size), + mode="bicubic", + align_corners=False, + ) + pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2) + new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1) + checkpoint_model[pos_embed_key] = new_pos_embed + + +def interpolate_pos_embed_online( + pos_embed, orig_size: Tuple[int], new_size: Tuple[int], num_extra_tokens: int +): + extra_tokens = pos_embed[:, :num_extra_tokens] + pos_tokens = pos_embed[:, num_extra_tokens:] + embedding_size = pos_tokens.shape[-1] + pos_tokens = pos_tokens.reshape( + -1, orig_size[0], orig_size[1], embedding_size + ).permute(0, 3, 1, 2) + pos_tokens = torch.nn.functional.interpolate( + pos_tokens, size=new_size, mode="bicubic", align_corners=False, + ) + pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2) + new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1) + return new_pos_embed diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/pycocotools/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/pycocotools/__init__.py new file mode 100644 index 00000000..3f7d85bb --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/pycocotools/__init__.py @@ -0,0 +1 @@ +__author__ = 'tylin' diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/pycocotools/coco.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/pycocotools/coco.py new file mode 100644 index 00000000..1ecb6c1b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/pycocotools/coco.py @@ -0,0 +1,444 @@ +__author__ = 'tylin' +__version__ = '2.0' +# Interface for accessing the Microsoft COCO dataset. + +# Microsoft COCO is a large image dataset designed for object detection, +# segmentation, and caption generation. annotator.oneformer.pycocotools is a Python API that +# assists in loading, parsing and visualizing the annotations in COCO. +# Please visit http://mscoco.org/ for more information on COCO, including +# for the data, paper, and tutorials. The exact format of the annotations +# is also described on the COCO website. For example usage of the annotator.oneformer.pycocotools +# please see annotator.oneformer.pycocotools_demo.ipynb. In addition to this API, please download both +# the COCO images and annotations in order to run the demo. + +# An alternative to using the API is to load the annotations directly +# into Python dictionary +# Using the API provides additional utility functions. Note that this API +# supports both *instance* and *caption* annotations. In the case of +# captions not all functions are defined (e.g. categories are undefined). + +# The following API functions are defined: +# COCO - COCO api class that loads COCO annotation file and prepare data structures. +# decodeMask - Decode binary mask M encoded via run-length encoding. +# encodeMask - Encode binary mask M using run-length encoding. +# getAnnIds - Get ann ids that satisfy given filter conditions. +# getCatIds - Get cat ids that satisfy given filter conditions. +# getImgIds - Get img ids that satisfy given filter conditions. +# loadAnns - Load anns with the specified ids. +# loadCats - Load cats with the specified ids. +# loadImgs - Load imgs with the specified ids. +# annToMask - Convert segmentation in an annotation to binary mask. +# showAnns - Display the specified annotations. +# loadRes - Load algorithm results and create API for accessing them. +# download - Download COCO images from mscoco.org server. +# Throughout the API "ann"=annotation, "cat"=category, and "img"=image. +# Help on each functions can be accessed by: "help COCO>function". + +# See also COCO>decodeMask, +# COCO>encodeMask, COCO>getAnnIds, COCO>getCatIds, +# COCO>getImgIds, COCO>loadAnns, COCO>loadCats, +# COCO>loadImgs, COCO>annToMask, COCO>showAnns + +# Microsoft COCO Toolbox. version 2.0 +# Data, paper, and tutorials available at: http://mscoco.org/ +# Code written by Piotr Dollar and Tsung-Yi Lin, 2014. +# Licensed under the Simplified BSD License [see bsd.txt] + +import json +import time +import numpy as np +import copy +import itertools +from . import mask as maskUtils +import os +from collections import defaultdict +import sys +PYTHON_VERSION = sys.version_info[0] +if PYTHON_VERSION == 2: + from urllib import urlretrieve +elif PYTHON_VERSION == 3: + from urllib.request import urlretrieve + + +def _isArrayLike(obj): + return hasattr(obj, '__iter__') and hasattr(obj, '__len__') + + +class COCO: + def __init__(self, annotation_file=None): + """ + Constructor of Microsoft COCO helper class for reading and visualizing annotations. + :param annotation_file (str): location of annotation file + :param image_folder (str): location to the folder that hosts images. + :return: + """ + # load dataset + self.dataset,self.anns,self.cats,self.imgs = dict(),dict(),dict(),dict() + self.imgToAnns, self.catToImgs = defaultdict(list), defaultdict(list) + if not annotation_file == None: + print('loading annotations into memory...') + tic = time.time() + with open(annotation_file, 'r') as f: + dataset = json.load(f) + assert type(dataset)==dict, 'annotation file format {} not supported'.format(type(dataset)) + print('Done (t={:0.2f}s)'.format(time.time()- tic)) + self.dataset = dataset + self.createIndex() + + def createIndex(self): + # create index + print('creating index...') + anns, cats, imgs = {}, {}, {} + imgToAnns,catToImgs = defaultdict(list),defaultdict(list) + if 'annotations' in self.dataset: + for ann in self.dataset['annotations']: + imgToAnns[ann['image_id']].append(ann) + anns[ann['id']] = ann + + if 'images' in self.dataset: + for img in self.dataset['images']: + imgs[img['id']] = img + + if 'categories' in self.dataset: + for cat in self.dataset['categories']: + cats[cat['id']] = cat + + if 'annotations' in self.dataset and 'categories' in self.dataset: + for ann in self.dataset['annotations']: + catToImgs[ann['category_id']].append(ann['image_id']) + + print('index created!') + + # create class members + self.anns = anns + self.imgToAnns = imgToAnns + self.catToImgs = catToImgs + self.imgs = imgs + self.cats = cats + + def info(self): + """ + Print information about the annotation file. + :return: + """ + for key, value in self.dataset['info'].items(): + print('{}: {}'.format(key, value)) + + def getAnnIds(self, imgIds=[], catIds=[], areaRng=[], iscrowd=None): + """ + Get ann ids that satisfy given filter conditions. default skips that filter + :param imgIds (int array) : get anns for given imgs + catIds (int array) : get anns for given cats + areaRng (float array) : get anns for given area range (e.g. [0 inf]) + iscrowd (boolean) : get anns for given crowd label (False or True) + :return: ids (int array) : integer array of ann ids + """ + imgIds = imgIds if _isArrayLike(imgIds) else [imgIds] + catIds = catIds if _isArrayLike(catIds) else [catIds] + + if len(imgIds) == len(catIds) == len(areaRng) == 0: + anns = self.dataset['annotations'] + else: + if not len(imgIds) == 0: + lists = [self.imgToAnns[imgId] for imgId in imgIds if imgId in self.imgToAnns] + anns = list(itertools.chain.from_iterable(lists)) + else: + anns = self.dataset['annotations'] + anns = anns if len(catIds) == 0 else [ann for ann in anns if ann['category_id'] in catIds] + anns = anns if len(areaRng) == 0 else [ann for ann in anns if ann['area'] > areaRng[0] and ann['area'] < areaRng[1]] + if not iscrowd == None: + ids = [ann['id'] for ann in anns if ann['iscrowd'] == iscrowd] + else: + ids = [ann['id'] for ann in anns] + return ids + + def getCatIds(self, catNms=[], supNms=[], catIds=[]): + """ + filtering parameters. default skips that filter. + :param catNms (str array) : get cats for given cat names + :param supNms (str array) : get cats for given supercategory names + :param catIds (int array) : get cats for given cat ids + :return: ids (int array) : integer array of cat ids + """ + catNms = catNms if _isArrayLike(catNms) else [catNms] + supNms = supNms if _isArrayLike(supNms) else [supNms] + catIds = catIds if _isArrayLike(catIds) else [catIds] + + if len(catNms) == len(supNms) == len(catIds) == 0: + cats = self.dataset['categories'] + else: + cats = self.dataset['categories'] + cats = cats if len(catNms) == 0 else [cat for cat in cats if cat['name'] in catNms] + cats = cats if len(supNms) == 0 else [cat for cat in cats if cat['supercategory'] in supNms] + cats = cats if len(catIds) == 0 else [cat for cat in cats if cat['id'] in catIds] + ids = [cat['id'] for cat in cats] + return ids + + def getImgIds(self, imgIds=[], catIds=[]): + ''' + Get img ids that satisfy given filter conditions. + :param imgIds (int array) : get imgs for given ids + :param catIds (int array) : get imgs with all given cats + :return: ids (int array) : integer array of img ids + ''' + imgIds = imgIds if _isArrayLike(imgIds) else [imgIds] + catIds = catIds if _isArrayLike(catIds) else [catIds] + + if len(imgIds) == len(catIds) == 0: + ids = self.imgs.keys() + else: + ids = set(imgIds) + for i, catId in enumerate(catIds): + if i == 0 and len(ids) == 0: + ids = set(self.catToImgs[catId]) + else: + ids &= set(self.catToImgs[catId]) + return list(ids) + + def loadAnns(self, ids=[]): + """ + Load anns with the specified ids. + :param ids (int array) : integer ids specifying anns + :return: anns (object array) : loaded ann objects + """ + if _isArrayLike(ids): + return [self.anns[id] for id in ids] + elif type(ids) == int: + return [self.anns[ids]] + + def loadCats(self, ids=[]): + """ + Load cats with the specified ids. + :param ids (int array) : integer ids specifying cats + :return: cats (object array) : loaded cat objects + """ + if _isArrayLike(ids): + return [self.cats[id] for id in ids] + elif type(ids) == int: + return [self.cats[ids]] + + def loadImgs(self, ids=[]): + """ + Load anns with the specified ids. + :param ids (int array) : integer ids specifying img + :return: imgs (object array) : loaded img objects + """ + if _isArrayLike(ids): + return [self.imgs[id] for id in ids] + elif type(ids) == int: + return [self.imgs[ids]] + + def showAnns(self, anns, draw_bbox=False): + """ + Display the specified annotations. + :param anns (array of object): annotations to display + :return: None + """ + if len(anns) == 0: + return 0 + if 'segmentation' in anns[0] or 'keypoints' in anns[0]: + datasetType = 'instances' + elif 'caption' in anns[0]: + datasetType = 'captions' + else: + raise Exception('datasetType not supported') + if datasetType == 'instances': + import matplotlib.pyplot as plt + from matplotlib.collections import PatchCollection + from matplotlib.patches import Polygon + + ax = plt.gca() + ax.set_autoscale_on(False) + polygons = [] + color = [] + for ann in anns: + c = (np.random.random((1, 3))*0.6+0.4).tolist()[0] + if 'segmentation' in ann: + if type(ann['segmentation']) == list: + # polygon + for seg in ann['segmentation']: + poly = np.array(seg).reshape((int(len(seg)/2), 2)) + polygons.append(Polygon(poly)) + color.append(c) + else: + # mask + t = self.imgs[ann['image_id']] + if type(ann['segmentation']['counts']) == list: + rle = maskUtils.frPyObjects([ann['segmentation']], t['height'], t['width']) + else: + rle = [ann['segmentation']] + m = maskUtils.decode(rle) + img = np.ones( (m.shape[0], m.shape[1], 3) ) + if ann['iscrowd'] == 1: + color_mask = np.array([2.0,166.0,101.0])/255 + if ann['iscrowd'] == 0: + color_mask = np.random.random((1, 3)).tolist()[0] + for i in range(3): + img[:,:,i] = color_mask[i] + ax.imshow(np.dstack( (img, m*0.5) )) + if 'keypoints' in ann and type(ann['keypoints']) == list: + # turn skeleton into zero-based index + sks = np.array(self.loadCats(ann['category_id'])[0]['skeleton'])-1 + kp = np.array(ann['keypoints']) + x = kp[0::3] + y = kp[1::3] + v = kp[2::3] + for sk in sks: + if np.all(v[sk]>0): + plt.plot(x[sk],y[sk], linewidth=3, color=c) + plt.plot(x[v>0], y[v>0],'o',markersize=8, markerfacecolor=c, markeredgecolor='k',markeredgewidth=2) + plt.plot(x[v>1], y[v>1],'o',markersize=8, markerfacecolor=c, markeredgecolor=c, markeredgewidth=2) + + if draw_bbox: + [bbox_x, bbox_y, bbox_w, bbox_h] = ann['bbox'] + poly = [[bbox_x, bbox_y], [bbox_x, bbox_y+bbox_h], [bbox_x+bbox_w, bbox_y+bbox_h], [bbox_x+bbox_w, bbox_y]] + np_poly = np.array(poly).reshape((4,2)) + polygons.append(Polygon(np_poly)) + color.append(c) + + p = PatchCollection(polygons, facecolor=color, linewidths=0, alpha=0.4) + ax.add_collection(p) + p = PatchCollection(polygons, facecolor='none', edgecolors=color, linewidths=2) + ax.add_collection(p) + elif datasetType == 'captions': + for ann in anns: + print(ann['caption']) + + def loadRes(self, resFile): + """ + Load result file and return a result api object. + :param resFile (str) : file name of result file + :return: res (obj) : result api object + """ + res = COCO() + res.dataset['images'] = [img for img in self.dataset['images']] + + print('Loading and preparing results...') + tic = time.time() + if type(resFile) == str or (PYTHON_VERSION == 2 and type(resFile) == unicode): + with open(resFile) as f: + anns = json.load(f) + elif type(resFile) == np.ndarray: + anns = self.loadNumpyAnnotations(resFile) + else: + anns = resFile + assert type(anns) == list, 'results in not an array of objects' + annsImgIds = [ann['image_id'] for ann in anns] + assert set(annsImgIds) == (set(annsImgIds) & set(self.getImgIds())), \ + 'Results do not correspond to current coco set' + if 'caption' in anns[0]: + imgIds = set([img['id'] for img in res.dataset['images']]) & set([ann['image_id'] for ann in anns]) + res.dataset['images'] = [img for img in res.dataset['images'] if img['id'] in imgIds] + for id, ann in enumerate(anns): + ann['id'] = id+1 + elif 'bbox' in anns[0] and not anns[0]['bbox'] == []: + res.dataset['categories'] = copy.deepcopy(self.dataset['categories']) + for id, ann in enumerate(anns): + bb = ann['bbox'] + x1, x2, y1, y2 = [bb[0], bb[0]+bb[2], bb[1], bb[1]+bb[3]] + if not 'segmentation' in ann: + ann['segmentation'] = [[x1, y1, x1, y2, x2, y2, x2, y1]] + ann['area'] = bb[2]*bb[3] + ann['id'] = id+1 + ann['iscrowd'] = 0 + elif 'segmentation' in anns[0]: + res.dataset['categories'] = copy.deepcopy(self.dataset['categories']) + for id, ann in enumerate(anns): + # now only support compressed RLE format as segmentation results + ann['area'] = maskUtils.area(ann['segmentation']) + if not 'bbox' in ann: + ann['bbox'] = maskUtils.toBbox(ann['segmentation']) + ann['id'] = id+1 + ann['iscrowd'] = 0 + elif 'keypoints' in anns[0]: + res.dataset['categories'] = copy.deepcopy(self.dataset['categories']) + for id, ann in enumerate(anns): + s = ann['keypoints'] + x = s[0::3] + y = s[1::3] + x0,x1,y0,y1 = np.min(x), np.max(x), np.min(y), np.max(y) + ann['area'] = (x1-x0)*(y1-y0) + ann['id'] = id + 1 + ann['bbox'] = [x0,y0,x1-x0,y1-y0] + print('DONE (t={:0.2f}s)'.format(time.time()- tic)) + + res.dataset['annotations'] = anns + res.createIndex() + return res + + def download(self, tarDir = None, imgIds = [] ): + ''' + Download COCO images from mscoco.org server. + :param tarDir (str): COCO results directory name + imgIds (list): images to be downloaded + :return: + ''' + if tarDir is None: + print('Please specify target directory') + return -1 + if len(imgIds) == 0: + imgs = self.imgs.values() + else: + imgs = self.loadImgs(imgIds) + N = len(imgs) + if not os.path.exists(tarDir): + os.makedirs(tarDir) + for i, img in enumerate(imgs): + tic = time.time() + fname = os.path.join(tarDir, img['file_name']) + if not os.path.exists(fname): + urlretrieve(img['coco_url'], fname) + print('downloaded {}/{} images (t={:0.1f}s)'.format(i, N, time.time()- tic)) + + def loadNumpyAnnotations(self, data): + """ + Convert result data from a numpy array [Nx7] where each row contains {imageID,x1,y1,w,h,score,class} + :param data (numpy.ndarray) + :return: annotations (python nested list) + """ + print('Converting ndarray to lists...') + assert(type(data) == np.ndarray) + print(data.shape) + assert(data.shape[1] == 7) + N = data.shape[0] + ann = [] + for i in range(N): + if i % 1000000 == 0: + print('{}/{}'.format(i,N)) + ann += [{ + 'image_id' : int(data[i, 0]), + 'bbox' : [ data[i, 1], data[i, 2], data[i, 3], data[i, 4] ], + 'score' : data[i, 5], + 'category_id': int(data[i, 6]), + }] + return ann + + def annToRLE(self, ann): + """ + Convert annotation which can be polygons, uncompressed RLE to RLE. + :return: binary mask (numpy 2D array) + """ + t = self.imgs[ann['image_id']] + h, w = t['height'], t['width'] + segm = ann['segmentation'] + if type(segm) == list: + # polygon -- a single object might consist of multiple parts + # we merge all parts into one mask rle code + rles = maskUtils.frPyObjects(segm, h, w) + rle = maskUtils.merge(rles) + elif type(segm['counts']) == list: + # uncompressed RLE + rle = maskUtils.frPyObjects(segm, h, w) + else: + # rle + rle = ann['segmentation'] + return rle + + def annToMask(self, ann): + """ + Convert annotation which can be polygons, uncompressed RLE, or RLE to binary mask. + :return: binary mask (numpy 2D array) + """ + rle = self.annToRLE(ann) + m = maskUtils.decode(rle) + return m diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/pycocotools/cocoeval.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/pycocotools/cocoeval.py new file mode 100644 index 00000000..89c251e1 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/pycocotools/cocoeval.py @@ -0,0 +1,534 @@ +__author__ = 'tsungyi' + +import numpy as np +import datetime +import time +from collections import defaultdict +from . import mask as maskUtils +import copy + +class COCOeval: + # Interface for evaluating detection on the Microsoft COCO dataset. + # + # The usage for CocoEval is as follows: + # cocoGt=..., cocoDt=... # load dataset and results + # E = CocoEval(cocoGt,cocoDt); # initialize CocoEval object + # E.params.recThrs = ...; # set parameters as desired + # E.evaluate(); # run per image evaluation + # E.accumulate(); # accumulate per image results + # E.summarize(); # display summary metrics of results + # For example usage see evalDemo.m and http://mscoco.org/. + # + # The evaluation parameters are as follows (defaults in brackets): + # imgIds - [all] N img ids to use for evaluation + # catIds - [all] K cat ids to use for evaluation + # iouThrs - [.5:.05:.95] T=10 IoU thresholds for evaluation + # recThrs - [0:.01:1] R=101 recall thresholds for evaluation + # areaRng - [...] A=4 object area ranges for evaluation + # maxDets - [1 10 100] M=3 thresholds on max detections per image + # iouType - ['segm'] set iouType to 'segm', 'bbox' or 'keypoints' + # iouType replaced the now DEPRECATED useSegm parameter. + # useCats - [1] if true use category labels for evaluation + # Note: if useCats=0 category labels are ignored as in proposal scoring. + # Note: multiple areaRngs [Ax2] and maxDets [Mx1] can be specified. + # + # evaluate(): evaluates detections on every image and every category and + # concats the results into the "evalImgs" with fields: + # dtIds - [1xD] id for each of the D detections (dt) + # gtIds - [1xG] id for each of the G ground truths (gt) + # dtMatches - [TxD] matching gt id at each IoU or 0 + # gtMatches - [TxG] matching dt id at each IoU or 0 + # dtScores - [1xD] confidence of each dt + # gtIgnore - [1xG] ignore flag for each gt + # dtIgnore - [TxD] ignore flag for each dt at each IoU + # + # accumulate(): accumulates the per-image, per-category evaluation + # results in "evalImgs" into the dictionary "eval" with fields: + # params - parameters used for evaluation + # date - date evaluation was performed + # counts - [T,R,K,A,M] parameter dimensions (see above) + # precision - [TxRxKxAxM] precision for every evaluation setting + # recall - [TxKxAxM] max recall for every evaluation setting + # Note: precision and recall==-1 for settings with no gt objects. + # + # See also coco, mask, pycocoDemo, pycocoEvalDemo + # + # Microsoft COCO Toolbox. version 2.0 + # Data, paper, and tutorials available at: http://mscoco.org/ + # Code written by Piotr Dollar and Tsung-Yi Lin, 2015. + # Licensed under the Simplified BSD License [see coco/license.txt] + def __init__(self, cocoGt=None, cocoDt=None, iouType='segm'): + ''' + Initialize CocoEval using coco APIs for gt and dt + :param cocoGt: coco object with ground truth annotations + :param cocoDt: coco object with detection results + :return: None + ''' + if not iouType: + print('iouType not specified. use default iouType segm') + self.cocoGt = cocoGt # ground truth COCO API + self.cocoDt = cocoDt # detections COCO API + self.evalImgs = defaultdict(list) # per-image per-category evaluation results [KxAxI] elements + self.eval = {} # accumulated evaluation results + self._gts = defaultdict(list) # gt for evaluation + self._dts = defaultdict(list) # dt for evaluation + self.params = Params(iouType=iouType) # parameters + self._paramsEval = {} # parameters for evaluation + self.stats = [] # result summarization + self.ious = {} # ious between all gts and dts + if not cocoGt is None: + self.params.imgIds = sorted(cocoGt.getImgIds()) + self.params.catIds = sorted(cocoGt.getCatIds()) + + + def _prepare(self): + ''' + Prepare ._gts and ._dts for evaluation based on params + :return: None + ''' + def _toMask(anns, coco): + # modify ann['segmentation'] by reference + for ann in anns: + rle = coco.annToRLE(ann) + ann['segmentation'] = rle + p = self.params + if p.useCats: + gts=self.cocoGt.loadAnns(self.cocoGt.getAnnIds(imgIds=p.imgIds, catIds=p.catIds)) + dts=self.cocoDt.loadAnns(self.cocoDt.getAnnIds(imgIds=p.imgIds, catIds=p.catIds)) + else: + gts=self.cocoGt.loadAnns(self.cocoGt.getAnnIds(imgIds=p.imgIds)) + dts=self.cocoDt.loadAnns(self.cocoDt.getAnnIds(imgIds=p.imgIds)) + + # convert ground truth to mask if iouType == 'segm' + if p.iouType == 'segm': + _toMask(gts, self.cocoGt) + _toMask(dts, self.cocoDt) + # set ignore flag + for gt in gts: + gt['ignore'] = gt['ignore'] if 'ignore' in gt else 0 + gt['ignore'] = 'iscrowd' in gt and gt['iscrowd'] + if p.iouType == 'keypoints': + gt['ignore'] = (gt['num_keypoints'] == 0) or gt['ignore'] + self._gts = defaultdict(list) # gt for evaluation + self._dts = defaultdict(list) # dt for evaluation + for gt in gts: + self._gts[gt['image_id'], gt['category_id']].append(gt) + for dt in dts: + self._dts[dt['image_id'], dt['category_id']].append(dt) + self.evalImgs = defaultdict(list) # per-image per-category evaluation results + self.eval = {} # accumulated evaluation results + + def evaluate(self): + ''' + Run per image evaluation on given images and store results (a list of dict) in self.evalImgs + :return: None + ''' + tic = time.time() + print('Running per image evaluation...') + p = self.params + # add backward compatibility if useSegm is specified in params + if not p.useSegm is None: + p.iouType = 'segm' if p.useSegm == 1 else 'bbox' + print('useSegm (deprecated) is not None. Running {} evaluation'.format(p.iouType)) + print('Evaluate annotation type *{}*'.format(p.iouType)) + p.imgIds = list(np.unique(p.imgIds)) + if p.useCats: + p.catIds = list(np.unique(p.catIds)) + p.maxDets = sorted(p.maxDets) + self.params=p + + self._prepare() + # loop through images, area range, max detection number + catIds = p.catIds if p.useCats else [-1] + + if p.iouType == 'segm' or p.iouType == 'bbox': + computeIoU = self.computeIoU + elif p.iouType == 'keypoints': + computeIoU = self.computeOks + self.ious = {(imgId, catId): computeIoU(imgId, catId) \ + for imgId in p.imgIds + for catId in catIds} + + evaluateImg = self.evaluateImg + maxDet = p.maxDets[-1] + self.evalImgs = [evaluateImg(imgId, catId, areaRng, maxDet) + for catId in catIds + for areaRng in p.areaRng + for imgId in p.imgIds + ] + self._paramsEval = copy.deepcopy(self.params) + toc = time.time() + print('DONE (t={:0.2f}s).'.format(toc-tic)) + + def computeIoU(self, imgId, catId): + p = self.params + if p.useCats: + gt = self._gts[imgId,catId] + dt = self._dts[imgId,catId] + else: + gt = [_ for cId in p.catIds for _ in self._gts[imgId,cId]] + dt = [_ for cId in p.catIds for _ in self._dts[imgId,cId]] + if len(gt) == 0 and len(dt) ==0: + return [] + inds = np.argsort([-d['score'] for d in dt], kind='mergesort') + dt = [dt[i] for i in inds] + if len(dt) > p.maxDets[-1]: + dt=dt[0:p.maxDets[-1]] + + if p.iouType == 'segm': + g = [g['segmentation'] for g in gt] + d = [d['segmentation'] for d in dt] + elif p.iouType == 'bbox': + g = [g['bbox'] for g in gt] + d = [d['bbox'] for d in dt] + else: + raise Exception('unknown iouType for iou computation') + + # compute iou between each dt and gt region + iscrowd = [int(o['iscrowd']) for o in gt] + ious = maskUtils.iou(d,g,iscrowd) + return ious + + def computeOks(self, imgId, catId): + p = self.params + # dimention here should be Nxm + gts = self._gts[imgId, catId] + dts = self._dts[imgId, catId] + inds = np.argsort([-d['score'] for d in dts], kind='mergesort') + dts = [dts[i] for i in inds] + if len(dts) > p.maxDets[-1]: + dts = dts[0:p.maxDets[-1]] + # if len(gts) == 0 and len(dts) == 0: + if len(gts) == 0 or len(dts) == 0: + return [] + ious = np.zeros((len(dts), len(gts))) + sigmas = p.kpt_oks_sigmas + vars = (sigmas * 2)**2 + k = len(sigmas) + # compute oks between each detection and ground truth object + for j, gt in enumerate(gts): + # create bounds for ignore regions(double the gt bbox) + g = np.array(gt['keypoints']) + xg = g[0::3]; yg = g[1::3]; vg = g[2::3] + k1 = np.count_nonzero(vg > 0) + bb = gt['bbox'] + x0 = bb[0] - bb[2]; x1 = bb[0] + bb[2] * 2 + y0 = bb[1] - bb[3]; y1 = bb[1] + bb[3] * 2 + for i, dt in enumerate(dts): + d = np.array(dt['keypoints']) + xd = d[0::3]; yd = d[1::3] + if k1>0: + # measure the per-keypoint distance if keypoints visible + dx = xd - xg + dy = yd - yg + else: + # measure minimum distance to keypoints in (x0,y0) & (x1,y1) + z = np.zeros((k)) + dx = np.max((z, x0-xd),axis=0)+np.max((z, xd-x1),axis=0) + dy = np.max((z, y0-yd),axis=0)+np.max((z, yd-y1),axis=0) + e = (dx**2 + dy**2) / vars / (gt['area']+np.spacing(1)) / 2 + if k1 > 0: + e=e[vg > 0] + ious[i, j] = np.sum(np.exp(-e)) / e.shape[0] + return ious + + def evaluateImg(self, imgId, catId, aRng, maxDet): + ''' + perform evaluation for single category and image + :return: dict (single image results) + ''' + p = self.params + if p.useCats: + gt = self._gts[imgId,catId] + dt = self._dts[imgId,catId] + else: + gt = [_ for cId in p.catIds for _ in self._gts[imgId,cId]] + dt = [_ for cId in p.catIds for _ in self._dts[imgId,cId]] + if len(gt) == 0 and len(dt) ==0: + return None + + for g in gt: + if g['ignore'] or (g['area']aRng[1]): + g['_ignore'] = 1 + else: + g['_ignore'] = 0 + + # sort dt highest score first, sort gt ignore last + gtind = np.argsort([g['_ignore'] for g in gt], kind='mergesort') + gt = [gt[i] for i in gtind] + dtind = np.argsort([-d['score'] for d in dt], kind='mergesort') + dt = [dt[i] for i in dtind[0:maxDet]] + iscrowd = [int(o['iscrowd']) for o in gt] + # load computed ious + ious = self.ious[imgId, catId][:, gtind] if len(self.ious[imgId, catId]) > 0 else self.ious[imgId, catId] + + T = len(p.iouThrs) + G = len(gt) + D = len(dt) + gtm = np.zeros((T,G)) + dtm = np.zeros((T,D)) + gtIg = np.array([g['_ignore'] for g in gt]) + dtIg = np.zeros((T,D)) + if not len(ious)==0: + for tind, t in enumerate(p.iouThrs): + for dind, d in enumerate(dt): + # information about best match so far (m=-1 -> unmatched) + iou = min([t,1-1e-10]) + m = -1 + for gind, g in enumerate(gt): + # if this gt already matched, and not a crowd, continue + if gtm[tind,gind]>0 and not iscrowd[gind]: + continue + # if dt matched to reg gt, and on ignore gt, stop + if m>-1 and gtIg[m]==0 and gtIg[gind]==1: + break + # continue to next gt unless better match made + if ious[dind,gind] < iou: + continue + # if match successful and best so far, store appropriately + iou=ious[dind,gind] + m=gind + # if match made store id of match for both dt and gt + if m ==-1: + continue + dtIg[tind,dind] = gtIg[m] + dtm[tind,dind] = gt[m]['id'] + gtm[tind,m] = d['id'] + # set unmatched detections outside of area range to ignore + a = np.array([d['area']aRng[1] for d in dt]).reshape((1, len(dt))) + dtIg = np.logical_or(dtIg, np.logical_and(dtm==0, np.repeat(a,T,0))) + # store results for given image and category + return { + 'image_id': imgId, + 'category_id': catId, + 'aRng': aRng, + 'maxDet': maxDet, + 'dtIds': [d['id'] for d in dt], + 'gtIds': [g['id'] for g in gt], + 'dtMatches': dtm, + 'gtMatches': gtm, + 'dtScores': [d['score'] for d in dt], + 'gtIgnore': gtIg, + 'dtIgnore': dtIg, + } + + def accumulate(self, p = None): + ''' + Accumulate per image evaluation results and store the result in self.eval + :param p: input params for evaluation + :return: None + ''' + print('Accumulating evaluation results...') + tic = time.time() + if not self.evalImgs: + print('Please run evaluate() first') + # allows input customized parameters + if p is None: + p = self.params + p.catIds = p.catIds if p.useCats == 1 else [-1] + T = len(p.iouThrs) + R = len(p.recThrs) + K = len(p.catIds) if p.useCats else 1 + A = len(p.areaRng) + M = len(p.maxDets) + precision = -np.ones((T,R,K,A,M)) # -1 for the precision of absent categories + recall = -np.ones((T,K,A,M)) + scores = -np.ones((T,R,K,A,M)) + + # create dictionary for future indexing + _pe = self._paramsEval + catIds = _pe.catIds if _pe.useCats else [-1] + setK = set(catIds) + setA = set(map(tuple, _pe.areaRng)) + setM = set(_pe.maxDets) + setI = set(_pe.imgIds) + # get inds to evaluate + k_list = [n for n, k in enumerate(p.catIds) if k in setK] + m_list = [m for n, m in enumerate(p.maxDets) if m in setM] + a_list = [n for n, a in enumerate(map(lambda x: tuple(x), p.areaRng)) if a in setA] + i_list = [n for n, i in enumerate(p.imgIds) if i in setI] + I0 = len(_pe.imgIds) + A0 = len(_pe.areaRng) + # retrieve E at each category, area range, and max number of detections + for k, k0 in enumerate(k_list): + Nk = k0*A0*I0 + for a, a0 in enumerate(a_list): + Na = a0*I0 + for m, maxDet in enumerate(m_list): + E = [self.evalImgs[Nk + Na + i] for i in i_list] + E = [e for e in E if not e is None] + if len(E) == 0: + continue + dtScores = np.concatenate([e['dtScores'][0:maxDet] for e in E]) + + # different sorting method generates slightly different results. + # mergesort is used to be consistent as Matlab implementation. + inds = np.argsort(-dtScores, kind='mergesort') + dtScoresSorted = dtScores[inds] + + dtm = np.concatenate([e['dtMatches'][:,0:maxDet] for e in E], axis=1)[:,inds] + dtIg = np.concatenate([e['dtIgnore'][:,0:maxDet] for e in E], axis=1)[:,inds] + gtIg = np.concatenate([e['gtIgnore'] for e in E]) + npig = np.count_nonzero(gtIg==0 ) + if npig == 0: + continue + tps = np.logical_and( dtm, np.logical_not(dtIg) ) + fps = np.logical_and(np.logical_not(dtm), np.logical_not(dtIg) ) + + tp_sum = np.cumsum(tps, axis=1).astype(dtype=float) + fp_sum = np.cumsum(fps, axis=1).astype(dtype=float) + for t, (tp, fp) in enumerate(zip(tp_sum, fp_sum)): + tp = np.array(tp) + fp = np.array(fp) + nd = len(tp) + rc = tp / npig + pr = tp / (fp+tp+np.spacing(1)) + q = np.zeros((R,)) + ss = np.zeros((R,)) + + if nd: + recall[t,k,a,m] = rc[-1] + else: + recall[t,k,a,m] = 0 + + # numpy is slow without cython optimization for accessing elements + # use python array gets significant speed improvement + pr = pr.tolist(); q = q.tolist() + + for i in range(nd-1, 0, -1): + if pr[i] > pr[i-1]: + pr[i-1] = pr[i] + + inds = np.searchsorted(rc, p.recThrs, side='left') + try: + for ri, pi in enumerate(inds): + q[ri] = pr[pi] + ss[ri] = dtScoresSorted[pi] + except: + pass + precision[t,:,k,a,m] = np.array(q) + scores[t,:,k,a,m] = np.array(ss) + self.eval = { + 'params': p, + 'counts': [T, R, K, A, M], + 'date': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), + 'precision': precision, + 'recall': recall, + 'scores': scores, + } + toc = time.time() + print('DONE (t={:0.2f}s).'.format( toc-tic)) + + def summarize(self): + ''' + Compute and display summary metrics for evaluation results. + Note this functin can *only* be applied on the default parameter setting + ''' + def _summarize( ap=1, iouThr=None, areaRng='all', maxDets=100 ): + p = self.params + iStr = ' {:<18} {} @[ IoU={:<9} | area={:>6s} | maxDets={:>3d} ] = {:0.3f}' + titleStr = 'Average Precision' if ap == 1 else 'Average Recall' + typeStr = '(AP)' if ap==1 else '(AR)' + iouStr = '{:0.2f}:{:0.2f}'.format(p.iouThrs[0], p.iouThrs[-1]) \ + if iouThr is None else '{:0.2f}'.format(iouThr) + + aind = [i for i, aRng in enumerate(p.areaRngLbl) if aRng == areaRng] + mind = [i for i, mDet in enumerate(p.maxDets) if mDet == maxDets] + if ap == 1: + # dimension of precision: [TxRxKxAxM] + s = self.eval['precision'] + # IoU + if iouThr is not None: + t = np.where(iouThr == p.iouThrs)[0] + s = s[t] + s = s[:,:,:,aind,mind] + else: + # dimension of recall: [TxKxAxM] + s = self.eval['recall'] + if iouThr is not None: + t = np.where(iouThr == p.iouThrs)[0] + s = s[t] + s = s[:,:,aind,mind] + if len(s[s>-1])==0: + mean_s = -1 + else: + mean_s = np.mean(s[s>-1]) + print(iStr.format(titleStr, typeStr, iouStr, areaRng, maxDets, mean_s)) + return mean_s + def _summarizeDets(): + stats = np.zeros((12,)) + stats[0] = _summarize(1) + stats[1] = _summarize(1, iouThr=.5, maxDets=self.params.maxDets[2]) + stats[2] = _summarize(1, iouThr=.75, maxDets=self.params.maxDets[2]) + stats[3] = _summarize(1, areaRng='small', maxDets=self.params.maxDets[2]) + stats[4] = _summarize(1, areaRng='medium', maxDets=self.params.maxDets[2]) + stats[5] = _summarize(1, areaRng='large', maxDets=self.params.maxDets[2]) + stats[6] = _summarize(0, maxDets=self.params.maxDets[0]) + stats[7] = _summarize(0, maxDets=self.params.maxDets[1]) + stats[8] = _summarize(0, maxDets=self.params.maxDets[2]) + stats[9] = _summarize(0, areaRng='small', maxDets=self.params.maxDets[2]) + stats[10] = _summarize(0, areaRng='medium', maxDets=self.params.maxDets[2]) + stats[11] = _summarize(0, areaRng='large', maxDets=self.params.maxDets[2]) + return stats + def _summarizeKps(): + stats = np.zeros((10,)) + stats[0] = _summarize(1, maxDets=20) + stats[1] = _summarize(1, maxDets=20, iouThr=.5) + stats[2] = _summarize(1, maxDets=20, iouThr=.75) + stats[3] = _summarize(1, maxDets=20, areaRng='medium') + stats[4] = _summarize(1, maxDets=20, areaRng='large') + stats[5] = _summarize(0, maxDets=20) + stats[6] = _summarize(0, maxDets=20, iouThr=.5) + stats[7] = _summarize(0, maxDets=20, iouThr=.75) + stats[8] = _summarize(0, maxDets=20, areaRng='medium') + stats[9] = _summarize(0, maxDets=20, areaRng='large') + return stats + if not self.eval: + raise Exception('Please run accumulate() first') + iouType = self.params.iouType + if iouType == 'segm' or iouType == 'bbox': + summarize = _summarizeDets + elif iouType == 'keypoints': + summarize = _summarizeKps + self.stats = summarize() + + def __str__(self): + self.summarize() + +class Params: + ''' + Params for coco evaluation api + ''' + def setDetParams(self): + self.imgIds = [] + self.catIds = [] + # np.arange causes trouble. the data point on arange is slightly larger than the true value + self.iouThrs = np.linspace(.5, 0.95, int(np.round((0.95 - .5) / .05)) + 1, endpoint=True) + self.recThrs = np.linspace(.0, 1.00, int(np.round((1.00 - .0) / .01)) + 1, endpoint=True) + self.maxDets = [1, 10, 100] + self.areaRng = [[0 ** 2, 1e5 ** 2], [0 ** 2, 32 ** 2], [32 ** 2, 96 ** 2], [96 ** 2, 1e5 ** 2]] + self.areaRngLbl = ['all', 'small', 'medium', 'large'] + self.useCats = 1 + + def setKpParams(self): + self.imgIds = [] + self.catIds = [] + # np.arange causes trouble. the data point on arange is slightly larger than the true value + self.iouThrs = np.linspace(.5, 0.95, int(np.round((0.95 - .5) / .05)) + 1, endpoint=True) + self.recThrs = np.linspace(.0, 1.00, int(np.round((1.00 - .0) / .01)) + 1, endpoint=True) + self.maxDets = [20] + self.areaRng = [[0 ** 2, 1e5 ** 2], [32 ** 2, 96 ** 2], [96 ** 2, 1e5 ** 2]] + self.areaRngLbl = ['all', 'medium', 'large'] + self.useCats = 1 + self.kpt_oks_sigmas = np.array([.26, .25, .25, .35, .35, .79, .79, .72, .72, .62,.62, 1.07, 1.07, .87, .87, .89, .89])/10.0 + + def __init__(self, iouType='segm'): + if iouType == 'segm' or iouType == 'bbox': + self.setDetParams() + elif iouType == 'keypoints': + self.setKpParams() + else: + raise Exception('iouType not supported') + self.iouType = iouType + # useSegm is deprecated + self.useSegm = None diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/pycocotools/mask.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/pycocotools/mask.py new file mode 100644 index 00000000..85a5643a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/pycocotools/mask.py @@ -0,0 +1,107 @@ +__author__ = 'tsungyi' + +# import annotator.oneformer.pycocotools._mask as _mask + +# Interface for manipulating masks stored in RLE format. +# +# RLE is a simple yet efficient format for storing binary masks. RLE +# first divides a vector (or vectorized image) into a series of piecewise +# constant regions and then for each piece simply stores the length of +# that piece. For example, given M=[0 0 1 1 1 0 1] the RLE counts would +# be [2 3 1 1], or for M=[1 1 1 1 1 1 0] the counts would be [0 6 1] +# (note that the odd counts are always the numbers of zeros). Instead of +# storing the counts directly, additional compression is achieved with a +# variable bitrate representation based on a common scheme called LEB128. +# +# Compression is greatest given large piecewise constant regions. +# Specifically, the size of the RLE is proportional to the number of +# *boundaries* in M (or for an image the number of boundaries in the y +# direction). Assuming fairly simple shapes, the RLE representation is +# O(sqrt(n)) where n is number of pixels in the object. Hence space usage +# is substantially lower, especially for large simple objects (large n). +# +# Many common operations on masks can be computed directly using the RLE +# (without need for decoding). This includes computations such as area, +# union, intersection, etc. All of these operations are linear in the +# size of the RLE, in other words they are O(sqrt(n)) where n is the area +# of the object. Computing these operations on the original mask is O(n). +# Thus, using the RLE can result in substantial computational savings. +# +# The following API functions are defined: +# encode - Encode binary masks using RLE. +# decode - Decode binary masks encoded via RLE. +# merge - Compute union or intersection of encoded masks. +# iou - Compute intersection over union between masks. +# area - Compute area of encoded masks. +# toBbox - Get bounding boxes surrounding encoded masks. +# frPyObjects - Convert polygon, bbox, and uncompressed RLE to encoded RLE mask. +# +# Usage: +# Rs = encode( masks ) +# masks = decode( Rs ) +# R = merge( Rs, intersect=false ) +# o = iou( dt, gt, iscrowd ) +# a = area( Rs ) +# bbs = toBbox( Rs ) +# Rs = frPyObjects( [pyObjects], h, w ) +# +# In the API the following formats are used: +# Rs - [dict] Run-length encoding of binary masks +# R - dict Run-length encoding of binary mask +# masks - [hxwxn] Binary mask(s) (must have type np.ndarray(dtype=uint8) in column-major order) +# iscrowd - [nx1] list of np.ndarray. 1 indicates corresponding gt image has crowd region to ignore +# bbs - [nx4] Bounding box(es) stored as [x y w h] +# poly - Polygon stored as [[x1 y1 x2 y2...],[x1 y1 ...],...] (2D list) +# dt,gt - May be either bounding boxes or encoded masks +# Both poly and bbs are 0-indexed (bbox=[0 0 1 1] encloses first pixel). +# +# Finally, a note about the intersection over union (iou) computation. +# The standard iou of a ground truth (gt) and detected (dt) object is +# iou(gt,dt) = area(intersect(gt,dt)) / area(union(gt,dt)) +# For "crowd" regions, we use a modified criteria. If a gt object is +# marked as "iscrowd", we allow a dt to match any subregion of the gt. +# Choosing gt' in the crowd gt that best matches the dt can be done using +# gt'=intersect(dt,gt). Since by definition union(gt',dt)=dt, computing +# iou(gt,dt,iscrowd) = iou(gt',dt) = area(intersect(gt,dt)) / area(dt) +# For crowd gt regions we use this modified criteria above for the iou. +# +# To compile run "python setup.py build_ext --inplace" +# Please do not contact us for help with compiling. +# +# Microsoft COCO Toolbox. version 2.0 +# Data, paper, and tutorials available at: http://mscoco.org/ +# Code written by Piotr Dollar and Tsung-Yi Lin, 2015. +# Licensed under the Simplified BSD License [see coco/license.txt] + +# iou = _mask.iou +# merge = _mask.merge +# frPyObjects = _mask.frPyObjects + +def encode(bimask): + pass + # if len(bimask.shape) == 3: + # return _mask.encode(bimask) + # elif len(bimask.shape) == 2: + # h, w = bimask.shape + # return _mask.encode(bimask.reshape((h, w, 1), order='F'))[0] + +def decode(rleObjs): + pass + # if type(rleObjs) == list: + # return _mask.decode(rleObjs) + # else: + # return _mask.decode([rleObjs])[:,:,0] + +def area(rleObjs): + pass + # if type(rleObjs) == list: + # return _mask.area(rleObjs) + # else: + # return _mask.area([rleObjs])[0] + +def toBbox(rleObjs): + pass + # if type(rleObjs) == list: + # return _mask.toBbox(rleObjs) + # else: + # return _mask.toBbox([rleObjs])[0] \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/openpose/LICENSE b/extensions-builtin/sd_forge_controlnet/annotator/openpose/LICENSE new file mode 100644 index 00000000..6f60b76d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/openpose/LICENSE @@ -0,0 +1,108 @@ +OPENPOSE: MULTIPERSON KEYPOINT DETECTION +SOFTWARE LICENSE AGREEMENT +ACADEMIC OR NON-PROFIT ORGANIZATION NONCOMMERCIAL RESEARCH USE ONLY + +BY USING OR DOWNLOADING THE SOFTWARE, YOU ARE AGREEING TO THE TERMS OF THIS LICENSE AGREEMENT. IF YOU DO NOT AGREE WITH THESE TERMS, YOU MAY NOT USE OR DOWNLOAD THE SOFTWARE. + +This is a license agreement ("Agreement") between your academic institution or non-profit organization or self (called "Licensee" or "You" in this Agreement) and Carnegie Mellon University (called "Licensor" in this Agreement). All rights not specifically granted to you in this Agreement are reserved for Licensor. + +RESERVATION OF OWNERSHIP AND GRANT OF LICENSE: +Licensor retains exclusive ownership of any copy of the Software (as defined below) licensed under this Agreement and hereby grants to Licensee a personal, non-exclusive, +non-transferable license to use the Software for noncommercial research purposes, without the right to sublicense, pursuant to the terms and conditions of this Agreement. As used in this Agreement, the term "Software" means (i) the actual copy of all or any portion of code for program routines made accessible to Licensee by Licensor pursuant to this Agreement, inclusive of backups, updates, and/or merged copies permitted hereunder or subsequently supplied by Licensor, including all or any file structures, programming instructions, user interfaces and screen formats and sequences as well as any and all documentation and instructions related to it, and (ii) all or any derivatives and/or modifications created or made by You to any of the items specified in (i). + +CONFIDENTIALITY: Licensee acknowledges that the Software is proprietary to Licensor, and as such, Licensee agrees to receive all such materials in confidence and use the Software only in accordance with the terms of this Agreement. Licensee agrees to use reasonable effort to protect the Software from unauthorized use, reproduction, distribution, or publication. + +COPYRIGHT: The Software is owned by Licensor and is protected by United +States copyright laws and applicable international treaties and/or conventions. + +PERMITTED USES: The Software may be used for your own noncommercial internal research purposes. You understand and agree that Licensor is not obligated to implement any suggestions and/or feedback you might provide regarding the Software, but to the extent Licensor does so, you are not entitled to any compensation related thereto. + +DERIVATIVES: You may create derivatives of or make modifications to the Software, however, You agree that all and any such derivatives and modifications will be owned by Licensor and become a part of the Software licensed to You under this Agreement. You may only use such derivatives and modifications for your own noncommercial internal research purposes, and you may not otherwise use, distribute or copy such derivatives and modifications in violation of this Agreement. + +BACKUPS: If Licensee is an organization, it may make that number of copies of the Software necessary for internal noncommercial use at a single site within its organization provided that all information appearing in or on the original labels, including the copyright and trademark notices are copied onto the labels of the copies. + +USES NOT PERMITTED: You may not distribute, copy or use the Software except as explicitly permitted herein. Licensee has not been granted any trademark license as part of this Agreement and may not use the name or mark “OpenPose", "Carnegie Mellon" or any renditions thereof without the prior written permission of Licensor. + +You may not sell, rent, lease, sublicense, lend, time-share or transfer, in whole or in part, or provide third parties access to prior or present versions (or any parts thereof) of the Software. + +ASSIGNMENT: You may not assign this Agreement or your rights hereunder without the prior written consent of Licensor. Any attempted assignment without such consent shall be null and void. + +TERM: The term of the license granted by this Agreement is from Licensee's acceptance of this Agreement by downloading the Software or by using the Software until terminated as provided below. + +The Agreement automatically terminates without notice if you fail to comply with any provision of this Agreement. Licensee may terminate this Agreement by ceasing using the Software. Upon any termination of this Agreement, Licensee will delete any and all copies of the Software. You agree that all provisions which operate to protect the proprietary rights of Licensor shall remain in force should breach occur and that the obligation of confidentiality described in this Agreement is binding in perpetuity and, as such, survives the term of the Agreement. + +FEE: Provided Licensee abides completely by the terms and conditions of this Agreement, there is no fee due to Licensor for Licensee's use of the Software in accordance with this Agreement. + +DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. LICENSEE BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE AND RELATED MATERIALS. + +SUPPORT AND MAINTENANCE: No Software support or training by the Licensor is provided as part of this Agreement. + +EXCLUSIVE REMEDY AND LIMITATION OF LIABILITY: To the maximum extent permitted under applicable law, Licensor shall not be liable for direct, indirect, special, incidental, or consequential damages or lost profits related to Licensee's use of and/or inability to use the Software, even if Licensor is advised of the possibility of such damage. + +EXPORT REGULATION: Licensee agrees to comply with any and all applicable +U.S. export control laws, regulations, and/or other laws related to embargoes and sanction programs administered by the Office of Foreign Assets Control. + +SEVERABILITY: If any provision(s) of this Agreement shall be held to be invalid, illegal, or unenforceable by a court or other tribunal of competent jurisdiction, the validity, legality and enforceability of the remaining provisions shall not in any way be affected or impaired thereby. + +NO IMPLIED WAIVERS: No failure or delay by Licensor in enforcing any right or remedy under this Agreement shall be construed as a waiver of any future or other exercise of such right or remedy by Licensor. + +GOVERNING LAW: This Agreement shall be construed and enforced in accordance with the laws of the Commonwealth of Pennsylvania without reference to conflict of laws principles. You consent to the personal jurisdiction of the courts of this County and waive their rights to venue outside of Allegheny County, Pennsylvania. + +ENTIRE AGREEMENT AND AMENDMENTS: This Agreement constitutes the sole and entire agreement between Licensee and Licensor as to the matter set forth herein and supersedes any previous agreements, understandings, and arrangements between the parties relating hereto. + + + +************************************************************************ + +THIRD-PARTY SOFTWARE NOTICES AND INFORMATION + +This project incorporates material from the project(s) listed below (collectively, "Third Party Code"). This Third Party Code is licensed to you under their original license terms set forth below. We reserves all other rights not expressly granted, whether by implication, estoppel or otherwise. + +1. Caffe, version 1.0.0, (https://github.com/BVLC/caffe/) + +COPYRIGHT + +All contributions by the University of California: +Copyright (c) 2014-2017 The Regents of the University of California (Regents) +All rights reserved. + +All other contributions: +Copyright (c) 2014-2017, the respective contributors +All rights reserved. + +Caffe uses a shared copyright model: each contributor holds copyright over +their contributions to Caffe. The project versioning records all such +contribution and copyright details. If a contributor wants to further mark +their specific copyright on a particular contribution, they should indicate +their copyright solely in the commit message of the change when it is +committed. + +LICENSE + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +CONTRIBUTION AGREEMENT + +By contributing to the BVLC/caffe repository through pull-request, comment, +or otherwise, the contributor releases their content to the +license and copyright terms herein. + +************END OF THIRD-PARTY SOFTWARE NOTICES AND INFORMATION********** \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/openpose/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/openpose/__init__.py new file mode 100644 index 00000000..e13f7536 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/openpose/__init__.py @@ -0,0 +1,463 @@ +# Openpose +# Original from CMU https://github.com/CMU-Perceptual-Computing-Lab/openpose +# 2nd Edited by https://github.com/Hzzone/pytorch-openpose +# 3rd Edited by ControlNet +# 4th Edited by ControlNet (added face and correct hands) +# 5th Edited by ControlNet (Improved JSON serialization/deserialization, and lots of bug fixs) +# This preprocessor is licensed by CMU for non-commercial use only. + + +import os + +os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" + +import torch +import numpy as np +from . import util +from .body import Body, BodyResult, Keypoint +from .hand import Hand +from .face import Face +from .types import HandResult, FaceResult, HumanPoseResult, AnimalPoseResult +from modules import devices +from annotator.annotator_path import models_path +from .animalpose import draw_animalposes + +from typing import Tuple, List, Callable, Union, Optional + +body_model_path = ( + "https://huggingface.co/lllyasviel/Annotators/resolve/main/body_pose_model.pth" +) +hand_model_path = ( + "https://huggingface.co/lllyasviel/Annotators/resolve/main/hand_pose_model.pth" +) +face_model_path = ( + "https://huggingface.co/lllyasviel/Annotators/resolve/main/facenet.pth" +) + +remote_onnx_det = "https://huggingface.co/yzd-v/DWPose/resolve/main/yolox_l.onnx" +remote_onnx_pose = ( + "https://huggingface.co/yzd-v/DWPose/resolve/main/dw-ll_ucoco_384.onnx" +) + +animal_onnx_pose = "https://huggingface.co/bdsqlsz/qinglong_controlnet-lllite/resolve/main/Annotators/rtmpose-m_simcc-ap10k_pt-aic-coco_210e-256x256-7a041aa1_20230206.onnx" + + +def draw_poses( + poses: List[HumanPoseResult], H, W, draw_body=True, draw_hand=True, draw_face=True +): + """ + Draw the detected poses on an empty canvas. + + Args: + poses (List[HumanPoseResult]): A list of HumanPoseResult objects containing the detected poses. + H (int): The height of the canvas. + W (int): The width of the canvas. + draw_body (bool, optional): Whether to draw body keypoints. Defaults to True. + draw_hand (bool, optional): Whether to draw hand keypoints. Defaults to True. + draw_face (bool, optional): Whether to draw face keypoints. Defaults to True. + + Returns: + numpy.ndarray: A 3D numpy array representing the canvas with the drawn poses. + """ + canvas = np.zeros(shape=(H, W, 3), dtype=np.uint8) + + for pose in poses: + if draw_body: + canvas = util.draw_bodypose(canvas, pose.body.keypoints) + + if draw_hand: + canvas = util.draw_handpose(canvas, pose.left_hand) + canvas = util.draw_handpose(canvas, pose.right_hand) + + if draw_face: + canvas = util.draw_facepose(canvas, pose.face) + + return canvas + + +def decode_json_as_poses( + pose_json: dict, +) -> Tuple[List[HumanPoseResult], List[AnimalPoseResult], int, int]: + """Decode the json_string complying with the openpose JSON output format + to poses that controlnet recognizes. + https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/doc/02_output.md + + Args: + json_string: The json string to decode. + + Returns: + human_poses + animal_poses + canvas_height + canvas_width + """ + height = pose_json["canvas_height"] + width = pose_json["canvas_width"] + + def chunks(lst, n): + """Yield successive n-sized chunks from lst.""" + for i in range(0, len(lst), n): + yield lst[i : i + n] + + def decompress_keypoints( + numbers: Optional[List[float]], + ) -> Optional[List[Optional[Keypoint]]]: + if not numbers: + return None + + assert len(numbers) % 3 == 0 + + def create_keypoint(x, y, c): + if c < 1.0: + return None + keypoint = Keypoint(x, y) + return keypoint + + return [create_keypoint(x, y, c) for x, y, c in chunks(numbers, n=3)] + + return ( + [ + HumanPoseResult( + body=BodyResult( + keypoints=decompress_keypoints(pose.get("pose_keypoints_2d")) + ), + left_hand=decompress_keypoints(pose.get("hand_left_keypoints_2d")), + right_hand=decompress_keypoints(pose.get("hand_right_keypoints_2d")), + face=decompress_keypoints(pose.get("face_keypoints_2d")), + ) + for pose in pose_json.get("people", []) + ], + [decompress_keypoints(pose) for pose in pose_json.get("animals", [])], + height, + width, + ) + + +def encode_poses_as_json( + poses: List[HumanPoseResult], + animals: List[AnimalPoseResult], + canvas_height: int, + canvas_width: int, +) -> dict: + """Encode the pose as a JSON compatible dict following openpose JSON output format: + https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/doc/02_output.md + """ + + def compress_keypoints( + keypoints: Union[List[Keypoint], None] + ) -> Union[List[float], None]: + if not keypoints: + return None + + return [ + value + for keypoint in keypoints + for value in ( + [float(keypoint.x), float(keypoint.y), 1.0] + if keypoint is not None + else [0.0, 0.0, 0.0] + ) + ] + + return { + "people": [ + { + "pose_keypoints_2d": compress_keypoints(pose.body.keypoints), + "face_keypoints_2d": compress_keypoints(pose.face), + "hand_left_keypoints_2d": compress_keypoints(pose.left_hand), + "hand_right_keypoints_2d": compress_keypoints(pose.right_hand), + } + for pose in poses + ], + "animals": [compress_keypoints(animal) for animal in animals], + "canvas_height": canvas_height, + "canvas_width": canvas_width, + } + + +class OpenposeDetector: + """ + A class for detecting human poses in images using the Openpose model. + + Attributes: + model_dir (str): Path to the directory where the pose models are stored. + """ + + model_dir = os.path.join(models_path, "openpose") + + def __init__(self): + self.device = devices.get_device_for("controlnet") + self.body_estimation = None + self.hand_estimation = None + self.face_estimation = None + + self.dw_pose_estimation = None + self.animal_pose_estimation = None + + def load_model(self): + """ + Load the Openpose body, hand, and face models. + """ + body_modelpath = os.path.join(self.model_dir, "body_pose_model.pth") + hand_modelpath = os.path.join(self.model_dir, "hand_pose_model.pth") + face_modelpath = os.path.join(self.model_dir, "facenet.pth") + + if not os.path.exists(body_modelpath): + from basicsr.utils.download_util import load_file_from_url + + load_file_from_url(body_model_path, model_dir=self.model_dir) + + if not os.path.exists(hand_modelpath): + from basicsr.utils.download_util import load_file_from_url + + load_file_from_url(hand_model_path, model_dir=self.model_dir) + + if not os.path.exists(face_modelpath): + from basicsr.utils.download_util import load_file_from_url + + load_file_from_url(face_model_path, model_dir=self.model_dir) + + self.body_estimation = Body(body_modelpath) + self.hand_estimation = Hand(hand_modelpath) + self.face_estimation = Face(face_modelpath) + + def load_dw_model(self): + from .wholebody import Wholebody # DW Pose + + def load_model(filename: str, remote_url: str): + local_path = os.path.join(self.model_dir, filename) + if not os.path.exists(local_path): + from basicsr.utils.download_util import load_file_from_url + + load_file_from_url(remote_url, model_dir=self.model_dir) + return local_path + + onnx_det = load_model("yolox_l.onnx", remote_onnx_det) + onnx_pose = load_model("dw-ll_ucoco_384.onnx", remote_onnx_pose) + self.dw_pose_estimation = Wholebody(onnx_det, onnx_pose) + + def load_animalpose_model(self): + from .animalpose import AnimalPose # Animalpose + + def load_model(filename: str, remote_url: str): + """ + Load the model from the specified filename and remote URL if it doesn't exist locally. + + Args: + filename (str): The filename of the model. + remote_url (str): The remote URL of the model. + """ + local_path = os.path.join(self.model_dir, filename) + if not os.path.exists(local_path): + from basicsr.utils.download_util import load_file_from_url + + load_file_from_url(remote_url, model_dir=self.model_dir) + return local_path + + onnx_det = load_model("yolox_l.onnx", remote_onnx_det) + onnx_pose = load_model( + "rtmpose-m_simcc-ap10k_pt-aic-coco_210e-256x256-7a041aa1_20230206.onnx", + animal_onnx_pose, + ) + self.animal_pose_estimation = AnimalPose(onnx_det, onnx_pose) + + def unload_model(self): + """ + Unload the Openpose models by moving them to the CPU. + Note: DW Pose models always run on CPU, so no need to `unload` them. + """ + if self.body_estimation is not None: + self.body_estimation.model.to("cpu") + self.hand_estimation.model.to("cpu") + self.face_estimation.model.to("cpu") + + def detect_hands( + self, body: BodyResult, oriImg + ) -> Tuple[Union[HandResult, None], Union[HandResult, None]]: + left_hand = None + right_hand = None + H, W, _ = oriImg.shape + for x, y, w, is_left in util.handDetect(body, oriImg): + peaks = self.hand_estimation(oriImg[y : y + w, x : x + w, :]).astype( + np.float32 + ) + if peaks.ndim == 2 and peaks.shape[1] == 2: + peaks[:, 0] = np.where(peaks[:, 0] < 1e-6, -1, peaks[:, 0] + x) / float( + W + ) + peaks[:, 1] = np.where(peaks[:, 1] < 1e-6, -1, peaks[:, 1] + y) / float( + H + ) + + hand_result = [Keypoint(x=peak[0], y=peak[1]) for peak in peaks] + + if is_left: + left_hand = hand_result + else: + right_hand = hand_result + + return left_hand, right_hand + + def detect_face(self, body: BodyResult, oriImg) -> Union[FaceResult, None]: + face = util.faceDetect(body, oriImg) + if face is None: + return None + + x, y, w = face + H, W, _ = oriImg.shape + heatmaps = self.face_estimation(oriImg[y : y + w, x : x + w, :]) + peaks = self.face_estimation.compute_peaks_from_heatmaps(heatmaps).astype( + np.float32 + ) + if peaks.ndim == 2 and peaks.shape[1] == 2: + peaks[:, 0] = np.where(peaks[:, 0] < 1e-6, -1, peaks[:, 0] + x) / float(W) + peaks[:, 1] = np.where(peaks[:, 1] < 1e-6, -1, peaks[:, 1] + y) / float(H) + return [Keypoint(x=peak[0], y=peak[1]) for peak in peaks] + + return None + + def detect_poses( + self, oriImg, include_hand=False, include_face=False + ) -> List[HumanPoseResult]: + """ + Detect poses in the given image. + Args: + oriImg (numpy.ndarray): The input image for pose detection. + include_hand (bool, optional): Whether to include hand detection. Defaults to False. + include_face (bool, optional): Whether to include face detection. Defaults to False. + + Returns: + List[HumanPoseResult]: A list of HumanPoseResult objects containing the detected poses. + """ + if self.body_estimation is None: + self.load_model() + + self.body_estimation.model.to(self.device) + self.hand_estimation.model.to(self.device) + self.face_estimation.model.to(self.device) + + self.body_estimation.cn_device = self.device + self.hand_estimation.cn_device = self.device + self.face_estimation.cn_device = self.device + + oriImg = oriImg[:, :, ::-1].copy() + H, W, C = oriImg.shape + with torch.no_grad(): + candidate, subset = self.body_estimation(oriImg) + bodies = self.body_estimation.format_body_result(candidate, subset) + + results = [] + for body in bodies: + left_hand, right_hand, face = (None,) * 3 + if include_hand: + left_hand, right_hand = self.detect_hands(body, oriImg) + if include_face: + face = self.detect_face(body, oriImg) + + results.append( + HumanPoseResult( + BodyResult( + keypoints=[ + Keypoint( + x=keypoint.x / float(W), y=keypoint.y / float(H) + ) + if keypoint is not None + else None + for keypoint in body.keypoints + ], + total_score=body.total_score, + total_parts=body.total_parts, + ), + left_hand, + right_hand, + face, + ) + ) + + return results + + def detect_poses_dw(self, oriImg) -> List[HumanPoseResult]: + """ + Detect poses in the given image using DW Pose: + https://github.com/IDEA-Research/DWPose + + Args: + oriImg (numpy.ndarray): The input image for pose detection. + + Returns: + List[HumanPoseResult]: A list of HumanPoseResult objects containing the detected poses. + """ + from .wholebody import Wholebody # DW Pose + + self.load_dw_model() + + with torch.no_grad(): + keypoints_info = self.dw_pose_estimation(oriImg.copy()) + return Wholebody.format_result(keypoints_info) + + def detect_poses_animal(self, oriImg) -> List[AnimalPoseResult]: + """ + Detect poses in the given image using RTMPose AP10k model: + https://github.com/abehonest/ControlNet_AnimalPose + + Args: + oriImg (numpy.ndarray): The input image for pose detection. + + Returns: + A list of AnimalPoseResult objects containing the detected animal poses. + """ + + self.load_animalpose_model() + + with torch.no_grad(): + return self.animal_pose_estimation(oriImg.copy()) + + def __call__( + self, + oriImg, + include_body=True, + include_hand=False, + include_face=False, + use_dw_pose=False, + use_animal_pose=False, + json_pose_callback: Callable[[str], None] = None, + ): + """ + Detect and draw poses in the given image. + + Args: + oriImg (numpy.ndarray): The input image for pose detection and drawing. + include_body (bool, optional): Whether to include body keypoints. Defaults to True. + include_hand (bool, optional): Whether to include hand keypoints. Defaults to False. + include_face (bool, optional): Whether to include face keypoints. Defaults to False. + use_dw_pose (bool, optional): Whether to use DW pose detection algorithm. Defaults to False. + json_pose_callback (Callable, optional): A callback that accepts the pose JSON string. + + Returns: + numpy.ndarray: The image with detected and drawn poses. + """ + H, W, _ = oriImg.shape + animals = [] + poses = [] + if use_animal_pose: + animals = self.detect_poses_animal(oriImg) + elif use_dw_pose: + poses = self.detect_poses_dw(oriImg) + else: + poses = self.detect_poses(oriImg, include_hand, include_face) + + if json_pose_callback: + json_pose_callback(encode_poses_as_json(poses, animals, H, W)) + + if poses: + assert len(animals) == 0 + return draw_poses( + poses, + H, + W, + draw_body=include_body, + draw_hand=include_hand, + draw_face=include_face, + ) + else: + return draw_animalposes(animals, H, W) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/openpose/animalpose.py b/extensions-builtin/sd_forge_controlnet/annotator/openpose/animalpose.py new file mode 100644 index 00000000..46fec4a4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/openpose/animalpose.py @@ -0,0 +1,131 @@ +import cv2 +import numpy as np +from typing import List + +from .cv_ox_det import inference_detector +from .cv_ox_pose import inference_pose + +from .types import AnimalPoseResult, Keypoint + + +def draw_animalposes(animals: List[List[Keypoint]], H: int, W: int) -> np.ndarray: + canvas = np.zeros(shape=(H, W, 3), dtype=np.uint8) + for animal_pose in animals: + canvas = draw_animalpose(canvas, animal_pose) + return canvas + + +def draw_animalpose(canvas: np.ndarray, keypoints: List[Keypoint]) -> np.ndarray: + # order of the keypoints for AP10k and a standardized list of colors for limbs + keypointPairsList = [ + (1, 2), + (2, 3), + (1, 3), + (3, 4), + (4, 9), + (9, 10), + (10, 11), + (4, 6), + (6, 7), + (7, 8), + (4, 5), + (5, 15), + (15, 16), + (16, 17), + (5, 12), + (12, 13), + (13, 14), + ] + colorsList = [ + (255, 255, 255), + (100, 255, 100), + (150, 255, 255), + (100, 50, 255), + (50, 150, 200), + (0, 255, 255), + (0, 150, 0), + (0, 0, 255), + (0, 0, 150), + (255, 50, 255), + (255, 0, 255), + (255, 0, 0), + (150, 0, 0), + (255, 255, 100), + (0, 150, 0), + (255, 255, 0), + (150, 150, 150), + ] # 16 colors needed + + for ind, (i, j) in enumerate(keypointPairsList): + p1 = keypoints[i - 1] + p2 = keypoints[j - 1] + + if p1 is not None and p2 is not None: + cv2.line( + canvas, + (int(p1.x), int(p1.y)), + (int(p2.x), int(p2.y)), + colorsList[ind], + 5, + ) + return canvas + + +class AnimalPose: + def __init__( + self, + onnx_det: str, + onnx_pose: str, + ): + self.onnx_det = onnx_det + self.onnx_pose = onnx_pose + self.model_input_size = (256, 256) + + # Always loads to CPU to avoid building OpenCV. + device = 'cpu' + backend = cv2.dnn.DNN_BACKEND_OPENCV if device == 'cpu' else cv2.dnn.DNN_BACKEND_CUDA + # You need to manually build OpenCV through cmake to work with your GPU. + providers = cv2.dnn.DNN_TARGET_CPU if device == 'cpu' else cv2.dnn.DNN_TARGET_CUDA + + self.session_det = cv2.dnn.readNetFromONNX(onnx_det) + self.session_det.setPreferableBackend(backend) + self.session_det.setPreferableTarget(providers) + + self.session_pose = cv2.dnn.readNetFromONNX(onnx_pose) + self.session_pose.setPreferableBackend(backend) + self.session_pose.setPreferableTarget(providers) + + def __call__(self, oriImg) -> List[AnimalPoseResult]: + detect_classes = list( + range(14, 23 + 1) + ) # https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/datasets/coco.yaml + + det_result = inference_detector( + self.session_det, + oriImg, + detect_classes=detect_classes, + ) + + if (det_result is None) or (det_result.shape[0] == 0): + return [] + + keypoint_sets, scores = inference_pose( + self.session_pose, + det_result, + oriImg, + self.model_input_size, + ) + + animals = [] + for idx, keypoints in enumerate(keypoint_sets): + score = scores[idx, ..., None] + score[score > 1.0] = 1.0 + score[score < 0.0] = 0.0 + animals.append( + [ + Keypoint(x, y, c) + for x, y, c in np.concatenate((keypoints, score), axis=-1).tolist() + ] + ) + + return animals diff --git a/extensions-builtin/sd_forge_controlnet/annotator/openpose/body.py b/extensions-builtin/sd_forge_controlnet/annotator/openpose/body.py new file mode 100644 index 00000000..d3ec1cb9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/openpose/body.py @@ -0,0 +1,258 @@ +import cv2 +import numpy as np +import math +import time +from scipy.ndimage import gaussian_filter +import matplotlib.pyplot as plt +import matplotlib +import torch +from torchvision import transforms +from typing import NamedTuple, List, Union + +from . import util +from .model import bodypose_model +from .types import Keypoint, BodyResult + +class Body(object): + def __init__(self, model_path): + self.model = bodypose_model() + model_dict = util.transfer(self.model, torch.load(model_path)) + self.model.load_state_dict(model_dict) + self.model.eval() + + def __call__(self, oriImg): + # scale_search = [0.5, 1.0, 1.5, 2.0] + scale_search = [0.5] + boxsize = 368 + stride = 8 + padValue = 128 + thre1 = 0.1 + thre2 = 0.05 + multiplier = [x * boxsize / oriImg.shape[0] for x in scale_search] + heatmap_avg = np.zeros((oriImg.shape[0], oriImg.shape[1], 19)) + paf_avg = np.zeros((oriImg.shape[0], oriImg.shape[1], 38)) + + for m in range(len(multiplier)): + scale = multiplier[m] + imageToTest = util.smart_resize_k(oriImg, fx=scale, fy=scale) + imageToTest_padded, pad = util.padRightDownCorner(imageToTest, stride, padValue) + im = np.transpose(np.float32(imageToTest_padded[:, :, :, np.newaxis]), (3, 2, 0, 1)) / 256 - 0.5 + im = np.ascontiguousarray(im) + + data = torch.from_numpy(im).float() + if torch.cuda.is_available(): + data = data.cuda() + # data = data.permute([2, 0, 1]).unsqueeze(0).float() + with torch.no_grad(): + data = data.to(self.cn_device) + Mconv7_stage6_L1, Mconv7_stage6_L2 = self.model(data) + Mconv7_stage6_L1 = Mconv7_stage6_L1.cpu().numpy() + Mconv7_stage6_L2 = Mconv7_stage6_L2.cpu().numpy() + + # extract outputs, resize, and remove padding + # heatmap = np.transpose(np.squeeze(net.blobs[output_blobs.keys()[1]].data), (1, 2, 0)) # output 1 is heatmaps + heatmap = np.transpose(np.squeeze(Mconv7_stage6_L2), (1, 2, 0)) # output 1 is heatmaps + heatmap = util.smart_resize_k(heatmap, fx=stride, fy=stride) + heatmap = heatmap[:imageToTest_padded.shape[0] - pad[2], :imageToTest_padded.shape[1] - pad[3], :] + heatmap = util.smart_resize(heatmap, (oriImg.shape[0], oriImg.shape[1])) + + # paf = np.transpose(np.squeeze(net.blobs[output_blobs.keys()[0]].data), (1, 2, 0)) # output 0 is PAFs + paf = np.transpose(np.squeeze(Mconv7_stage6_L1), (1, 2, 0)) # output 0 is PAFs + paf = util.smart_resize_k(paf, fx=stride, fy=stride) + paf = paf[:imageToTest_padded.shape[0] - pad[2], :imageToTest_padded.shape[1] - pad[3], :] + paf = util.smart_resize(paf, (oriImg.shape[0], oriImg.shape[1])) + + heatmap_avg += heatmap_avg + heatmap / len(multiplier) + paf_avg += + paf / len(multiplier) + + all_peaks = [] + peak_counter = 0 + + for part in range(18): + map_ori = heatmap_avg[:, :, part] + one_heatmap = gaussian_filter(map_ori, sigma=3) + + map_left = np.zeros(one_heatmap.shape) + map_left[1:, :] = one_heatmap[:-1, :] + map_right = np.zeros(one_heatmap.shape) + map_right[:-1, :] = one_heatmap[1:, :] + map_up = np.zeros(one_heatmap.shape) + map_up[:, 1:] = one_heatmap[:, :-1] + map_down = np.zeros(one_heatmap.shape) + map_down[:, :-1] = one_heatmap[:, 1:] + + peaks_binary = np.logical_and.reduce( + (one_heatmap >= map_left, one_heatmap >= map_right, one_heatmap >= map_up, one_heatmap >= map_down, one_heatmap > thre1)) + peaks = list(zip(np.nonzero(peaks_binary)[1], np.nonzero(peaks_binary)[0])) # note reverse + peaks_with_score = [x + (map_ori[x[1], x[0]],) for x in peaks] + peak_id = range(peak_counter, peak_counter + len(peaks)) + peaks_with_score_and_id = [peaks_with_score[i] + (peak_id[i],) for i in range(len(peak_id))] + + all_peaks.append(peaks_with_score_and_id) + peak_counter += len(peaks) + + # find connection in the specified sequence, center 29 is in the position 15 + limbSeq = [[2, 3], [2, 6], [3, 4], [4, 5], [6, 7], [7, 8], [2, 9], [9, 10], \ + [10, 11], [2, 12], [12, 13], [13, 14], [2, 1], [1, 15], [15, 17], \ + [1, 16], [16, 18], [3, 17], [6, 18]] + # the middle joints heatmap correpondence + mapIdx = [[31, 32], [39, 40], [33, 34], [35, 36], [41, 42], [43, 44], [19, 20], [21, 22], \ + [23, 24], [25, 26], [27, 28], [29, 30], [47, 48], [49, 50], [53, 54], [51, 52], \ + [55, 56], [37, 38], [45, 46]] + + connection_all = [] + special_k = [] + mid_num = 10 + + for k in range(len(mapIdx)): + score_mid = paf_avg[:, :, [x - 19 for x in mapIdx[k]]] + candA = all_peaks[limbSeq[k][0] - 1] + candB = all_peaks[limbSeq[k][1] - 1] + nA = len(candA) + nB = len(candB) + indexA, indexB = limbSeq[k] + if (nA != 0 and nB != 0): + connection_candidate = [] + for i in range(nA): + for j in range(nB): + vec = np.subtract(candB[j][:2], candA[i][:2]) + norm = math.sqrt(vec[0] * vec[0] + vec[1] * vec[1]) + norm = max(0.001, norm) + vec = np.divide(vec, norm) + + startend = list(zip(np.linspace(candA[i][0], candB[j][0], num=mid_num), \ + np.linspace(candA[i][1], candB[j][1], num=mid_num))) + + vec_x = np.array([score_mid[int(round(startend[I][1])), int(round(startend[I][0])), 0] \ + for I in range(len(startend))]) + vec_y = np.array([score_mid[int(round(startend[I][1])), int(round(startend[I][0])), 1] \ + for I in range(len(startend))]) + + score_midpts = np.multiply(vec_x, vec[0]) + np.multiply(vec_y, vec[1]) + score_with_dist_prior = sum(score_midpts) / len(score_midpts) + min( + 0.5 * oriImg.shape[0] / norm - 1, 0) + criterion1 = len(np.nonzero(score_midpts > thre2)[0]) > 0.8 * len(score_midpts) + criterion2 = score_with_dist_prior > 0 + if criterion1 and criterion2: + connection_candidate.append( + [i, j, score_with_dist_prior, score_with_dist_prior + candA[i][2] + candB[j][2]]) + + connection_candidate = sorted(connection_candidate, key=lambda x: x[2], reverse=True) + connection = np.zeros((0, 5)) + for c in range(len(connection_candidate)): + i, j, s = connection_candidate[c][0:3] + if (i not in connection[:, 3] and j not in connection[:, 4]): + connection = np.vstack([connection, [candA[i][3], candB[j][3], s, i, j]]) + if (len(connection) >= min(nA, nB)): + break + + connection_all.append(connection) + else: + special_k.append(k) + connection_all.append([]) + + # last number in each row is the total parts number of that person + # the second last number in each row is the score of the overall configuration + subset = -1 * np.ones((0, 20)) + candidate = np.array([item for sublist in all_peaks for item in sublist]) + + for k in range(len(mapIdx)): + if k not in special_k: + partAs = connection_all[k][:, 0] + partBs = connection_all[k][:, 1] + indexA, indexB = np.array(limbSeq[k]) - 1 + + for i in range(len(connection_all[k])): # = 1:size(temp,1) + found = 0 + subset_idx = [-1, -1] + for j in range(len(subset)): # 1:size(subset,1): + if subset[j][indexA] == partAs[i] or subset[j][indexB] == partBs[i]: + subset_idx[found] = j + found += 1 + + if found == 1: + j = subset_idx[0] + if subset[j][indexB] != partBs[i]: + subset[j][indexB] = partBs[i] + subset[j][-1] += 1 + subset[j][-2] += candidate[partBs[i].astype(int), 2] + connection_all[k][i][2] + elif found == 2: # if found 2 and disjoint, merge them + j1, j2 = subset_idx + membership = ((subset[j1] >= 0).astype(int) + (subset[j2] >= 0).astype(int))[:-2] + if len(np.nonzero(membership == 2)[0]) == 0: # merge + subset[j1][:-2] += (subset[j2][:-2] + 1) + subset[j1][-2:] += subset[j2][-2:] + subset[j1][-2] += connection_all[k][i][2] + subset = np.delete(subset, j2, 0) + else: # as like found == 1 + subset[j1][indexB] = partBs[i] + subset[j1][-1] += 1 + subset[j1][-2] += candidate[partBs[i].astype(int), 2] + connection_all[k][i][2] + + # if find no partA in the subset, create a new subset + elif not found and k < 17: + row = -1 * np.ones(20) + row[indexA] = partAs[i] + row[indexB] = partBs[i] + row[-1] = 2 + row[-2] = sum(candidate[connection_all[k][i, :2].astype(int), 2]) + connection_all[k][i][2] + subset = np.vstack([subset, row]) + # delete some rows of subset which has few parts occur + deleteIdx = [] + for i in range(len(subset)): + if subset[i][-1] < 4 or subset[i][-2] / subset[i][-1] < 0.4: + deleteIdx.append(i) + subset = np.delete(subset, deleteIdx, axis=0) + + # subset: n*20 array, 0-17 is the index in candidate, 18 is the total score, 19 is the total parts + # candidate: x, y, score, id + return candidate, subset + + @staticmethod + def format_body_result(candidate: np.ndarray, subset: np.ndarray) -> List[BodyResult]: + """ + Format the body results from the candidate and subset arrays into a list of BodyResult objects. + + Args: + candidate (np.ndarray): An array of candidates containing the x, y coordinates, score, and id + for each body part. + subset (np.ndarray): An array of subsets containing indices to the candidate array for each + person detected. The last two columns of each row hold the total score and total parts + of the person. + + Returns: + List[BodyResult]: A list of BodyResult objects, where each object represents a person with + detected keypoints, total score, and total parts. + """ + return [ + BodyResult( + keypoints=[ + Keypoint( + x=candidate[candidate_index][0], + y=candidate[candidate_index][1], + score=candidate[candidate_index][2], + id=candidate[candidate_index][3] + ) if candidate_index != -1 else None + for candidate_index in person[:18].astype(int) + ], + total_score=person[18], + total_parts=person[19] + ) + for person in subset + ] + + +if __name__ == "__main__": + body_estimation = Body('../model/body_pose_model.pth') + + test_image = '../images/ski.jpg' + oriImg = cv2.imread(test_image) # B,G,R order + candidate, subset = body_estimation(oriImg) + bodies = body_estimation.format_body_result(candidate, subset) + + canvas = oriImg + for body in bodies: + canvas = util.draw_bodypose(canvas, body) + + plt.imshow(canvas[:, :, [2, 1, 0]]) + plt.show() \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/openpose/cv_ox_det.py b/extensions-builtin/sd_forge_controlnet/annotator/openpose/cv_ox_det.py new file mode 100644 index 00000000..0c210a53 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/openpose/cv_ox_det.py @@ -0,0 +1,128 @@ +import cv2 +import numpy as np + +def nms(boxes, scores, nms_thr): + """Single class NMS implemented in Numpy.""" + x1 = boxes[:, 0] + y1 = boxes[:, 1] + x2 = boxes[:, 2] + y2 = boxes[:, 3] + + areas = (x2 - x1 + 1) * (y2 - y1 + 1) + order = scores.argsort()[::-1] + + keep = [] + while order.size > 0: + i = order[0] + keep.append(i) + xx1 = np.maximum(x1[i], x1[order[1:]]) + yy1 = np.maximum(y1[i], y1[order[1:]]) + xx2 = np.minimum(x2[i], x2[order[1:]]) + yy2 = np.minimum(y2[i], y2[order[1:]]) + + w = np.maximum(0.0, xx2 - xx1 + 1) + h = np.maximum(0.0, yy2 - yy1 + 1) + inter = w * h + ovr = inter / (areas[i] + areas[order[1:]] - inter) + + inds = np.where(ovr <= nms_thr)[0] + order = order[inds + 1] + + return keep + +def multiclass_nms(boxes, scores, nms_thr, score_thr): + """Multiclass NMS implemented in Numpy. Class-aware version.""" + final_dets = [] + num_classes = scores.shape[1] + for cls_ind in range(num_classes): + cls_scores = scores[:, cls_ind] + valid_score_mask = cls_scores > score_thr + if valid_score_mask.sum() == 0: + continue + else: + valid_scores = cls_scores[valid_score_mask] + valid_boxes = boxes[valid_score_mask] + keep = nms(valid_boxes, valid_scores, nms_thr) + if len(keep) > 0: + cls_inds = np.ones((len(keep), 1)) * cls_ind + dets = np.concatenate( + [valid_boxes[keep], valid_scores[keep, None], cls_inds], 1 + ) + final_dets.append(dets) + if len(final_dets) == 0: + return None + return np.concatenate(final_dets, 0) + +def demo_postprocess(outputs, img_size, p6=False): + grids = [] + expanded_strides = [] + strides = [8, 16, 32] if not p6 else [8, 16, 32, 64] + + hsizes = [img_size[0] // stride for stride in strides] + wsizes = [img_size[1] // stride for stride in strides] + + for hsize, wsize, stride in zip(hsizes, wsizes, strides): + xv, yv = np.meshgrid(np.arange(wsize), np.arange(hsize)) + grid = np.stack((xv, yv), 2).reshape(1, -1, 2) + grids.append(grid) + shape = grid.shape[:2] + expanded_strides.append(np.full((*shape, 1), stride)) + + grids = np.concatenate(grids, 1) + expanded_strides = np.concatenate(expanded_strides, 1) + outputs[..., :2] = (outputs[..., :2] + grids) * expanded_strides + outputs[..., 2:4] = np.exp(outputs[..., 2:4]) * expanded_strides + + return outputs + +def preprocess(img, input_size, swap=(2, 0, 1)): + if len(img.shape) == 3: + padded_img = np.ones((input_size[0], input_size[1], 3), dtype=np.uint8) * 114 + else: + padded_img = np.ones(input_size, dtype=np.uint8) * 114 + + r = min(input_size[0] / img.shape[0], input_size[1] / img.shape[1]) + resized_img = cv2.resize( + img, + (int(img.shape[1] * r), int(img.shape[0] * r)), + interpolation=cv2.INTER_LINEAR, + ).astype(np.uint8) + padded_img[: int(img.shape[0] * r), : int(img.shape[1] * r)] = resized_img + + padded_img = padded_img.transpose(swap) + padded_img = np.ascontiguousarray(padded_img, dtype=np.float32) + return padded_img, r + +def inference_detector(session, oriImg, detect_classes=[0]): + input_shape = (640,640) + img, ratio = preprocess(oriImg, input_shape) + + input = img[None, :, :, :] + if "InferenceSession" in type(session).__name__: + input_name = session.get_inputs()[0].name + output = session.run(None, {input_name: input}) + else: + outNames = session.getUnconnectedOutLayersNames() + session.setInput(input) + output = session.forward(outNames) + + predictions = demo_postprocess(output[0], input_shape)[0] + + boxes = predictions[:, :4] + scores = predictions[:, 4:5] * predictions[:, 5:] + + boxes_xyxy = np.ones_like(boxes) + boxes_xyxy[:, 0] = boxes[:, 0] - boxes[:, 2]/2. + boxes_xyxy[:, 1] = boxes[:, 1] - boxes[:, 3]/2. + boxes_xyxy[:, 2] = boxes[:, 0] + boxes[:, 2]/2. + boxes_xyxy[:, 3] = boxes[:, 1] + boxes[:, 3]/2. + boxes_xyxy /= ratio + dets = multiclass_nms(boxes_xyxy, scores, nms_thr=0.45, score_thr=0.1) + if dets is None: + return None + final_boxes, final_scores, final_cls_inds = dets[:, :4], dets[:, 4], dets[:, 5] + isscore = final_scores>0.3 + iscat = np.isin(final_cls_inds, detect_classes) + isbbox = [ i and j for (i, j) in zip(isscore, iscat)] + final_boxes = final_boxes[isbbox] + return final_boxes diff --git a/extensions-builtin/sd_forge_controlnet/annotator/openpose/cv_ox_pose.py b/extensions-builtin/sd_forge_controlnet/annotator/openpose/cv_ox_pose.py new file mode 100644 index 00000000..529404ca --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/openpose/cv_ox_pose.py @@ -0,0 +1,364 @@ +from typing import List, Tuple + +import cv2 +import numpy as np + +def preprocess( + img: np.ndarray, out_bbox, input_size: Tuple[int, int] = (192, 256) +) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: + """Do preprocessing for DWPose model inference. + + Args: + img (np.ndarray): Input image in shape. + input_size (tuple): Input image size in shape (w, h). + + Returns: + tuple: + - resized_img (np.ndarray): Preprocessed image. + - center (np.ndarray): Center of image. + - scale (np.ndarray): Scale of image. + """ + # get shape of image + img_shape = img.shape[:2] + out_img, out_center, out_scale = [], [], [] + if len(out_bbox) == 0: + out_bbox = [[0, 0, img_shape[1], img_shape[0]]] + for i in range(len(out_bbox)): + x0 = out_bbox[i][0] + y0 = out_bbox[i][1] + x1 = out_bbox[i][2] + y1 = out_bbox[i][3] + bbox = np.array([x0, y0, x1, y1]) + + # get center and scale + center, scale = bbox_xyxy2cs(bbox, padding=1.25) + + # do affine transformation + resized_img, scale = top_down_affine(input_size, scale, center, img) + + # normalize image + mean = np.array([123.675, 116.28, 103.53]) + std = np.array([58.395, 57.12, 57.375]) + resized_img = (resized_img - mean) / std + + out_img.append(resized_img) + out_center.append(center) + out_scale.append(scale) + + return out_img, out_center, out_scale + + +def inference(sess, img): + """Inference DWPose model. + + Args: + sess : ONNXRuntime session. + img : Input image in shape. + + Returns: + outputs : Output of DWPose model. + """ + all_out = [] + # build input + input = np.stack(img, axis=0).transpose(0, 3, 1, 2) + input = input.astype(np.float32) + if "InferenceSession" in type(sess).__name__: + input_name = sess.get_inputs()[0].name + all_outputs = sess.run(None, {input_name: input}) + for batch_idx in range(len(all_outputs[0])): + outputs = [all_outputs[i][batch_idx:batch_idx+1,...] for i in range(len(all_outputs))] + all_out.append(outputs) + return all_out + + for i in range(len(img)): + + input = img[i].transpose(2, 0, 1) + input = input[None, :, :, :] + + outNames = sess.getUnconnectedOutLayersNames() + sess.setInput(input) + outputs = sess.forward(outNames) + all_out.append(outputs) + + return all_out + + +def postprocess(outputs: List[np.ndarray], + model_input_size: Tuple[int, int], + center: Tuple[int, int], + scale: Tuple[int, int], + simcc_split_ratio: float = 2.0 + ) -> Tuple[np.ndarray, np.ndarray]: + """Postprocess for DWPose model output. + + Args: + outputs (np.ndarray): Output of RTMPose model. + model_input_size (tuple): RTMPose model Input image size. + center (tuple): Center of bbox in shape (x, y). + scale (tuple): Scale of bbox in shape (w, h). + simcc_split_ratio (float): Split ratio of simcc. + + Returns: + tuple: + - keypoints (np.ndarray): Rescaled keypoints. + - scores (np.ndarray): Model predict scores. + """ + all_key = [] + all_score = [] + for i in range(len(outputs)): + # use simcc to decode + simcc_x, simcc_y = outputs[i] + keypoints, scores = decode(simcc_x, simcc_y, simcc_split_ratio) + + # rescale keypoints + keypoints = keypoints / model_input_size * scale[i] + center[i] - scale[i] / 2 + all_key.append(keypoints[0]) + all_score.append(scores[0]) + + return np.array(all_key), np.array(all_score) + + +def bbox_xyxy2cs(bbox: np.ndarray, + padding: float = 1.) -> Tuple[np.ndarray, np.ndarray]: + """Transform the bbox format from (x,y,w,h) into (center, scale) + + Args: + bbox (ndarray): Bounding box(es) in shape (4,) or (n, 4), formatted + as (left, top, right, bottom) + padding (float): BBox padding factor that will be multilied to scale. + Default: 1.0 + + Returns: + tuple: A tuple containing center and scale. + - np.ndarray[float32]: Center (x, y) of the bbox in shape (2,) or + (n, 2) + - np.ndarray[float32]: Scale (w, h) of the bbox in shape (2,) or + (n, 2) + """ + # convert single bbox from (4, ) to (1, 4) + dim = bbox.ndim + if dim == 1: + bbox = bbox[None, :] + + # get bbox center and scale + x1, y1, x2, y2 = np.hsplit(bbox, [1, 2, 3]) + center = np.hstack([x1 + x2, y1 + y2]) * 0.5 + scale = np.hstack([x2 - x1, y2 - y1]) * padding + + if dim == 1: + center = center[0] + scale = scale[0] + + return center, scale + + +def _fix_aspect_ratio(bbox_scale: np.ndarray, + aspect_ratio: float) -> np.ndarray: + """Extend the scale to match the given aspect ratio. + + Args: + scale (np.ndarray): The image scale (w, h) in shape (2, ) + aspect_ratio (float): The ratio of ``w/h`` + + Returns: + np.ndarray: The reshaped image scale in (2, ) + """ + w, h = np.hsplit(bbox_scale, [1]) + bbox_scale = np.where(w > h * aspect_ratio, + np.hstack([w, w / aspect_ratio]), + np.hstack([h * aspect_ratio, h])) + return bbox_scale + + +def _rotate_point(pt: np.ndarray, angle_rad: float) -> np.ndarray: + """Rotate a point by an angle. + + Args: + pt (np.ndarray): 2D point coordinates (x, y) in shape (2, ) + angle_rad (float): rotation angle in radian + + Returns: + np.ndarray: Rotated point in shape (2, ) + """ + sn, cs = np.sin(angle_rad), np.cos(angle_rad) + rot_mat = np.array([[cs, -sn], [sn, cs]]) + return rot_mat @ pt + + +def _get_3rd_point(a: np.ndarray, b: np.ndarray) -> np.ndarray: + """To calculate the affine matrix, three pairs of points are required. This + function is used to get the 3rd point, given 2D points a & b. + + The 3rd point is defined by rotating vector `a - b` by 90 degrees + anticlockwise, using b as the rotation center. + + Args: + a (np.ndarray): The 1st point (x,y) in shape (2, ) + b (np.ndarray): The 2nd point (x,y) in shape (2, ) + + Returns: + np.ndarray: The 3rd point. + """ + direction = a - b + c = b + np.r_[-direction[1], direction[0]] + return c + + +def get_warp_matrix(center: np.ndarray, + scale: np.ndarray, + rot: float, + output_size: Tuple[int, int], + shift: Tuple[float, float] = (0., 0.), + inv: bool = False) -> np.ndarray: + """Calculate the affine transformation matrix that can warp the bbox area + in the input image to the output size. + + Args: + center (np.ndarray[2, ]): Center of the bounding box (x, y). + scale (np.ndarray[2, ]): Scale of the bounding box + wrt [width, height]. + rot (float): Rotation angle (degree). + output_size (np.ndarray[2, ] | list(2,)): Size of the + destination heatmaps. + shift (0-100%): Shift translation ratio wrt the width/height. + Default (0., 0.). + inv (bool): Option to inverse the affine transform direction. + (inv=False: src->dst or inv=True: dst->src) + + Returns: + np.ndarray: A 2x3 transformation matrix + """ + shift = np.array(shift) + src_w = scale[0] + dst_w = output_size[0] + dst_h = output_size[1] + + # compute transformation matrix + rot_rad = np.deg2rad(rot) + src_dir = _rotate_point(np.array([0., src_w * -0.5]), rot_rad) + dst_dir = np.array([0., dst_w * -0.5]) + + # get four corners of the src rectangle in the original image + src = np.zeros((3, 2), dtype=np.float32) + src[0, :] = center + scale * shift + src[1, :] = center + src_dir + scale * shift + src[2, :] = _get_3rd_point(src[0, :], src[1, :]) + + # get four corners of the dst rectangle in the input image + dst = np.zeros((3, 2), dtype=np.float32) + dst[0, :] = [dst_w * 0.5, dst_h * 0.5] + dst[1, :] = np.array([dst_w * 0.5, dst_h * 0.5]) + dst_dir + dst[2, :] = _get_3rd_point(dst[0, :], dst[1, :]) + + if inv: + warp_mat = cv2.getAffineTransform(np.float32(dst), np.float32(src)) + else: + warp_mat = cv2.getAffineTransform(np.float32(src), np.float32(dst)) + + return warp_mat + + +def top_down_affine(input_size: dict, bbox_scale: dict, bbox_center: dict, + img: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: + """Get the bbox image as the model input by affine transform. + + Args: + input_size (dict): The input size of the model. + bbox_scale (dict): The bbox scale of the img. + bbox_center (dict): The bbox center of the img. + img (np.ndarray): The original image. + + Returns: + tuple: A tuple containing center and scale. + - np.ndarray[float32]: img after affine transform. + - np.ndarray[float32]: bbox scale after affine transform. + """ + w, h = input_size + warp_size = (int(w), int(h)) + + # reshape bbox to fixed aspect ratio + bbox_scale = _fix_aspect_ratio(bbox_scale, aspect_ratio=w / h) + + # get the affine matrix + center = bbox_center + scale = bbox_scale + rot = 0 + warp_mat = get_warp_matrix(center, scale, rot, output_size=(w, h)) + + # do affine transform + img = cv2.warpAffine(img, warp_mat, warp_size, flags=cv2.INTER_LINEAR) + + return img, bbox_scale + + +def get_simcc_maximum(simcc_x: np.ndarray, + simcc_y: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: + """Get maximum response location and value from simcc representations. + + Note: + instance number: N + num_keypoints: K + heatmap height: H + heatmap width: W + + Args: + simcc_x (np.ndarray): x-axis SimCC in shape (K, Wx) or (N, K, Wx) + simcc_y (np.ndarray): y-axis SimCC in shape (K, Wy) or (N, K, Wy) + + Returns: + tuple: + - locs (np.ndarray): locations of maximum heatmap responses in shape + (K, 2) or (N, K, 2) + - vals (np.ndarray): values of maximum heatmap responses in shape + (K,) or (N, K) + """ + N, K, Wx = simcc_x.shape + simcc_x = simcc_x.reshape(N * K, -1) + simcc_y = simcc_y.reshape(N * K, -1) + + # get maximum value locations + x_locs = np.argmax(simcc_x, axis=1) + y_locs = np.argmax(simcc_y, axis=1) + locs = np.stack((x_locs, y_locs), axis=-1).astype(np.float32) + max_val_x = np.amax(simcc_x, axis=1) + max_val_y = np.amax(simcc_y, axis=1) + + # get maximum value across x and y axis + mask = max_val_x > max_val_y + max_val_x[mask] = max_val_y[mask] + vals = max_val_x + locs[vals <= 0.] = -1 + + # reshape + locs = locs.reshape(N, K, 2) + vals = vals.reshape(N, K) + + return locs, vals + + +def decode(simcc_x: np.ndarray, simcc_y: np.ndarray, + simcc_split_ratio) -> Tuple[np.ndarray, np.ndarray]: + """Modulate simcc distribution with Gaussian. + + Args: + simcc_x (np.ndarray[K, Wx]): model predicted simcc in x. + simcc_y (np.ndarray[K, Wy]): model predicted simcc in y. + simcc_split_ratio (int): The split ratio of simcc. + + Returns: + tuple: A tuple containing center and scale. + - np.ndarray[float32]: keypoints in shape (K, 2) or (n, K, 2) + - np.ndarray[float32]: scores in shape (K,) or (n, K) + """ + keypoints, scores = get_simcc_maximum(simcc_x, simcc_y) + keypoints /= simcc_split_ratio + + return keypoints, scores + + +def inference_pose(session, out_bbox, oriImg, model_input_size: Tuple[int, int]= (288, 384) ): + resized_img, center, scale = preprocess(oriImg, out_bbox, model_input_size) + outputs = inference(session, resized_img) + keypoints, scores = postprocess(outputs, model_input_size, center, scale) + + return keypoints, scores \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/openpose/face.py b/extensions-builtin/sd_forge_controlnet/annotator/openpose/face.py new file mode 100644 index 00000000..f3c46d77 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/openpose/face.py @@ -0,0 +1,362 @@ +import logging +import numpy as np +from torchvision.transforms import ToTensor, ToPILImage +import torch +import torch.nn.functional as F +import cv2 + +from . import util +from torch.nn import Conv2d, Module, ReLU, MaxPool2d, init + + +class FaceNet(Module): + """Model the cascading heatmaps. """ + def __init__(self): + super(FaceNet, self).__init__() + # cnn to make feature map + self.relu = ReLU() + self.max_pooling_2d = MaxPool2d(kernel_size=2, stride=2) + self.conv1_1 = Conv2d(in_channels=3, out_channels=64, + kernel_size=3, stride=1, padding=1) + self.conv1_2 = Conv2d( + in_channels=64, out_channels=64, kernel_size=3, stride=1, + padding=1) + self.conv2_1 = Conv2d( + in_channels=64, out_channels=128, kernel_size=3, stride=1, + padding=1) + self.conv2_2 = Conv2d( + in_channels=128, out_channels=128, kernel_size=3, stride=1, + padding=1) + self.conv3_1 = Conv2d( + in_channels=128, out_channels=256, kernel_size=3, stride=1, + padding=1) + self.conv3_2 = Conv2d( + in_channels=256, out_channels=256, kernel_size=3, stride=1, + padding=1) + self.conv3_3 = Conv2d( + in_channels=256, out_channels=256, kernel_size=3, stride=1, + padding=1) + self.conv3_4 = Conv2d( + in_channels=256, out_channels=256, kernel_size=3, stride=1, + padding=1) + self.conv4_1 = Conv2d( + in_channels=256, out_channels=512, kernel_size=3, stride=1, + padding=1) + self.conv4_2 = Conv2d( + in_channels=512, out_channels=512, kernel_size=3, stride=1, + padding=1) + self.conv4_3 = Conv2d( + in_channels=512, out_channels=512, kernel_size=3, stride=1, + padding=1) + self.conv4_4 = Conv2d( + in_channels=512, out_channels=512, kernel_size=3, stride=1, + padding=1) + self.conv5_1 = Conv2d( + in_channels=512, out_channels=512, kernel_size=3, stride=1, + padding=1) + self.conv5_2 = Conv2d( + in_channels=512, out_channels=512, kernel_size=3, stride=1, + padding=1) + self.conv5_3_CPM = Conv2d( + in_channels=512, out_channels=128, kernel_size=3, stride=1, + padding=1) + + # stage1 + self.conv6_1_CPM = Conv2d( + in_channels=128, out_channels=512, kernel_size=1, stride=1, + padding=0) + self.conv6_2_CPM = Conv2d( + in_channels=512, out_channels=71, kernel_size=1, stride=1, + padding=0) + + # stage2 + self.Mconv1_stage2 = Conv2d( + in_channels=199, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv2_stage2 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv3_stage2 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv4_stage2 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv5_stage2 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv6_stage2 = Conv2d( + in_channels=128, out_channels=128, kernel_size=1, stride=1, + padding=0) + self.Mconv7_stage2 = Conv2d( + in_channels=128, out_channels=71, kernel_size=1, stride=1, + padding=0) + + # stage3 + self.Mconv1_stage3 = Conv2d( + in_channels=199, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv2_stage3 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv3_stage3 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv4_stage3 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv5_stage3 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv6_stage3 = Conv2d( + in_channels=128, out_channels=128, kernel_size=1, stride=1, + padding=0) + self.Mconv7_stage3 = Conv2d( + in_channels=128, out_channels=71, kernel_size=1, stride=1, + padding=0) + + # stage4 + self.Mconv1_stage4 = Conv2d( + in_channels=199, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv2_stage4 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv3_stage4 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv4_stage4 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv5_stage4 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv6_stage4 = Conv2d( + in_channels=128, out_channels=128, kernel_size=1, stride=1, + padding=0) + self.Mconv7_stage4 = Conv2d( + in_channels=128, out_channels=71, kernel_size=1, stride=1, + padding=0) + + # stage5 + self.Mconv1_stage5 = Conv2d( + in_channels=199, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv2_stage5 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv3_stage5 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv4_stage5 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv5_stage5 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv6_stage5 = Conv2d( + in_channels=128, out_channels=128, kernel_size=1, stride=1, + padding=0) + self.Mconv7_stage5 = Conv2d( + in_channels=128, out_channels=71, kernel_size=1, stride=1, + padding=0) + + # stage6 + self.Mconv1_stage6 = Conv2d( + in_channels=199, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv2_stage6 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv3_stage6 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv4_stage6 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv5_stage6 = Conv2d( + in_channels=128, out_channels=128, kernel_size=7, stride=1, + padding=3) + self.Mconv6_stage6 = Conv2d( + in_channels=128, out_channels=128, kernel_size=1, stride=1, + padding=0) + self.Mconv7_stage6 = Conv2d( + in_channels=128, out_channels=71, kernel_size=1, stride=1, + padding=0) + + for m in self.modules(): + if isinstance(m, Conv2d): + init.constant_(m.bias, 0) + + def forward(self, x): + """Return a list of heatmaps.""" + heatmaps = [] + + h = self.relu(self.conv1_1(x)) + h = self.relu(self.conv1_2(h)) + h = self.max_pooling_2d(h) + h = self.relu(self.conv2_1(h)) + h = self.relu(self.conv2_2(h)) + h = self.max_pooling_2d(h) + h = self.relu(self.conv3_1(h)) + h = self.relu(self.conv3_2(h)) + h = self.relu(self.conv3_3(h)) + h = self.relu(self.conv3_4(h)) + h = self.max_pooling_2d(h) + h = self.relu(self.conv4_1(h)) + h = self.relu(self.conv4_2(h)) + h = self.relu(self.conv4_3(h)) + h = self.relu(self.conv4_4(h)) + h = self.relu(self.conv5_1(h)) + h = self.relu(self.conv5_2(h)) + h = self.relu(self.conv5_3_CPM(h)) + feature_map = h + + # stage1 + h = self.relu(self.conv6_1_CPM(h)) + h = self.conv6_2_CPM(h) + heatmaps.append(h) + + # stage2 + h = torch.cat([h, feature_map], dim=1) # channel concat + h = self.relu(self.Mconv1_stage2(h)) + h = self.relu(self.Mconv2_stage2(h)) + h = self.relu(self.Mconv3_stage2(h)) + h = self.relu(self.Mconv4_stage2(h)) + h = self.relu(self.Mconv5_stage2(h)) + h = self.relu(self.Mconv6_stage2(h)) + h = self.Mconv7_stage2(h) + heatmaps.append(h) + + # stage3 + h = torch.cat([h, feature_map], dim=1) # channel concat + h = self.relu(self.Mconv1_stage3(h)) + h = self.relu(self.Mconv2_stage3(h)) + h = self.relu(self.Mconv3_stage3(h)) + h = self.relu(self.Mconv4_stage3(h)) + h = self.relu(self.Mconv5_stage3(h)) + h = self.relu(self.Mconv6_stage3(h)) + h = self.Mconv7_stage3(h) + heatmaps.append(h) + + # stage4 + h = torch.cat([h, feature_map], dim=1) # channel concat + h = self.relu(self.Mconv1_stage4(h)) + h = self.relu(self.Mconv2_stage4(h)) + h = self.relu(self.Mconv3_stage4(h)) + h = self.relu(self.Mconv4_stage4(h)) + h = self.relu(self.Mconv5_stage4(h)) + h = self.relu(self.Mconv6_stage4(h)) + h = self.Mconv7_stage4(h) + heatmaps.append(h) + + # stage5 + h = torch.cat([h, feature_map], dim=1) # channel concat + h = self.relu(self.Mconv1_stage5(h)) + h = self.relu(self.Mconv2_stage5(h)) + h = self.relu(self.Mconv3_stage5(h)) + h = self.relu(self.Mconv4_stage5(h)) + h = self.relu(self.Mconv5_stage5(h)) + h = self.relu(self.Mconv6_stage5(h)) + h = self.Mconv7_stage5(h) + heatmaps.append(h) + + # stage6 + h = torch.cat([h, feature_map], dim=1) # channel concat + h = self.relu(self.Mconv1_stage6(h)) + h = self.relu(self.Mconv2_stage6(h)) + h = self.relu(self.Mconv3_stage6(h)) + h = self.relu(self.Mconv4_stage6(h)) + h = self.relu(self.Mconv5_stage6(h)) + h = self.relu(self.Mconv6_stage6(h)) + h = self.Mconv7_stage6(h) + heatmaps.append(h) + + return heatmaps + + +LOG = logging.getLogger(__name__) +TOTEN = ToTensor() +TOPIL = ToPILImage() + + +params = { + 'gaussian_sigma': 2.5, + 'inference_img_size': 736, # 368, 736, 1312 + 'heatmap_peak_thresh': 0.1, + 'crop_scale': 1.5, + 'line_indices': [ + [0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], + [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], + [13, 14], [14, 15], [15, 16], + [17, 18], [18, 19], [19, 20], [20, 21], + [22, 23], [23, 24], [24, 25], [25, 26], + [27, 28], [28, 29], [29, 30], + [31, 32], [32, 33], [33, 34], [34, 35], + [36, 37], [37, 38], [38, 39], [39, 40], [40, 41], [41, 36], + [42, 43], [43, 44], [44, 45], [45, 46], [46, 47], [47, 42], + [48, 49], [49, 50], [50, 51], [51, 52], [52, 53], [53, 54], + [54, 55], [55, 56], [56, 57], [57, 58], [58, 59], [59, 48], + [60, 61], [61, 62], [62, 63], [63, 64], [64, 65], [65, 66], + [66, 67], [67, 60] + ], +} + + +class Face(object): + """ + The OpenPose face landmark detector model. + + Args: + inference_size: set the size of the inference image size, suggested: + 368, 736, 1312, default 736 + gaussian_sigma: blur the heatmaps, default 2.5 + heatmap_peak_thresh: return landmark if over threshold, default 0.1 + + """ + def __init__(self, face_model_path, + inference_size=None, + gaussian_sigma=None, + heatmap_peak_thresh=None): + self.inference_size = inference_size or params["inference_img_size"] + self.sigma = gaussian_sigma or params['gaussian_sigma'] + self.threshold = heatmap_peak_thresh or params["heatmap_peak_thresh"] + self.model = FaceNet() + self.model.load_state_dict(torch.load(face_model_path)) + # if torch.cuda.is_available(): + # self.model = self.model.cuda() + # print('cuda') + self.model.eval() + + def __call__(self, face_img): + H, W, C = face_img.shape + + w_size = 384 + x_data = torch.from_numpy(util.smart_resize(face_img, (w_size, w_size))).permute([2, 0, 1]) / 256.0 - 0.5 + + x_data = x_data.to(self.cn_device) + + with torch.no_grad(): + hs = self.model(x_data[None, ...]) + heatmaps = F.interpolate( + hs[-1], + (H, W), + mode='bilinear', align_corners=True).cpu().numpy()[0] + return heatmaps + + def compute_peaks_from_heatmaps(self, heatmaps): + all_peaks = [] + for part in range(heatmaps.shape[0]): + map_ori = heatmaps[part].copy() + binary = np.ascontiguousarray(map_ori > 0.05, dtype=np.uint8) + + if np.sum(binary) == 0: + continue + + positions = np.where(binary > 0.5) + intensities = map_ori[positions] + mi = np.argmax(intensities) + y, x = positions[0][mi], positions[1][mi] + all_peaks.append([x, y]) + + return np.array(all_peaks) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/openpose/hand.py b/extensions-builtin/sd_forge_controlnet/annotator/openpose/hand.py new file mode 100644 index 00000000..03a218d0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/openpose/hand.py @@ -0,0 +1,94 @@ +import cv2 +import json +import numpy as np +import math +import time +from scipy.ndimage import gaussian_filter +import matplotlib.pyplot as plt +import matplotlib +import torch +from skimage.measure import label + +from .model import handpose_model +from . import util + +class Hand(object): + def __init__(self, model_path): + self.model = handpose_model() + # if torch.cuda.is_available(): + # self.model = self.model.cuda() + # print('cuda') + model_dict = util.transfer(self.model, torch.load(model_path)) + self.model.load_state_dict(model_dict) + self.model.eval() + + def __call__(self, oriImgRaw): + scale_search = [0.5, 1.0, 1.5, 2.0] + # scale_search = [0.5] + boxsize = 368 + stride = 8 + padValue = 128 + thre = 0.05 + multiplier = [x * boxsize for x in scale_search] + + wsize = 128 + heatmap_avg = np.zeros((wsize, wsize, 22)) + + Hr, Wr, Cr = oriImgRaw.shape + + oriImg = cv2.GaussianBlur(oriImgRaw, (0, 0), 0.8) + + for m in range(len(multiplier)): + scale = multiplier[m] + imageToTest = util.smart_resize(oriImg, (scale, scale)) + + imageToTest_padded, pad = util.padRightDownCorner(imageToTest, stride, padValue) + im = np.transpose(np.float32(imageToTest_padded[:, :, :, np.newaxis]), (3, 2, 0, 1)) / 256 - 0.5 + im = np.ascontiguousarray(im) + + data = torch.from_numpy(im).float() + if torch.cuda.is_available(): + data = data.cuda() + + with torch.no_grad(): + data = data.to(self.cn_device) + output = self.model(data).cpu().numpy() + + # extract outputs, resize, and remove padding + heatmap = np.transpose(np.squeeze(output), (1, 2, 0)) # output 1 is heatmaps + heatmap = util.smart_resize_k(heatmap, fx=stride, fy=stride) + heatmap = heatmap[:imageToTest_padded.shape[0] - pad[2], :imageToTest_padded.shape[1] - pad[3], :] + heatmap = util.smart_resize(heatmap, (wsize, wsize)) + + heatmap_avg += heatmap / len(multiplier) + + all_peaks = [] + for part in range(21): + map_ori = heatmap_avg[:, :, part] + one_heatmap = gaussian_filter(map_ori, sigma=3) + binary = np.ascontiguousarray(one_heatmap > thre, dtype=np.uint8) + + if np.sum(binary) == 0: + all_peaks.append([0, 0]) + continue + label_img, label_numbers = label(binary, return_num=True, connectivity=binary.ndim) + max_index = np.argmax([np.sum(map_ori[label_img == i]) for i in range(1, label_numbers + 1)]) + 1 + label_img[label_img != max_index] = 0 + map_ori[label_img == 0] = 0 + + y, x = util.npmax(map_ori) + y = int(float(y) * float(Hr) / float(wsize)) + x = int(float(x) * float(Wr) / float(wsize)) + all_peaks.append([x, y]) + return np.array(all_peaks) + +if __name__ == "__main__": + hand_estimation = Hand('../model/hand_pose_model.pth') + + # test_image = '../images/hand.jpg' + test_image = '../images/hand.jpg' + oriImg = cv2.imread(test_image) # B,G,R order + peaks = hand_estimation(oriImg) + canvas = util.draw_handpose(oriImg, peaks, True) + cv2.imshow('', canvas) + cv2.waitKey(0) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/openpose/model.py b/extensions-builtin/sd_forge_controlnet/annotator/openpose/model.py new file mode 100644 index 00000000..72dc79ad --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/openpose/model.py @@ -0,0 +1,218 @@ +import torch +from collections import OrderedDict + +import torch +import torch.nn as nn + +def make_layers(block, no_relu_layers): + layers = [] + for layer_name, v in block.items(): + if 'pool' in layer_name: + layer = nn.MaxPool2d(kernel_size=v[0], stride=v[1], + padding=v[2]) + layers.append((layer_name, layer)) + else: + conv2d = nn.Conv2d(in_channels=v[0], out_channels=v[1], + kernel_size=v[2], stride=v[3], + padding=v[4]) + layers.append((layer_name, conv2d)) + if layer_name not in no_relu_layers: + layers.append(('relu_'+layer_name, nn.ReLU(inplace=True))) + + return nn.Sequential(OrderedDict(layers)) + +class bodypose_model(nn.Module): + def __init__(self): + super(bodypose_model, self).__init__() + + # these layers have no relu layer + no_relu_layers = ['conv5_5_CPM_L1', 'conv5_5_CPM_L2', 'Mconv7_stage2_L1',\ + 'Mconv7_stage2_L2', 'Mconv7_stage3_L1', 'Mconv7_stage3_L2',\ + 'Mconv7_stage4_L1', 'Mconv7_stage4_L2', 'Mconv7_stage5_L1',\ + 'Mconv7_stage5_L2', 'Mconv7_stage6_L1', 'Mconv7_stage6_L1'] + blocks = {} + block0 = OrderedDict([ + ('conv1_1', [3, 64, 3, 1, 1]), + ('conv1_2', [64, 64, 3, 1, 1]), + ('pool1_stage1', [2, 2, 0]), + ('conv2_1', [64, 128, 3, 1, 1]), + ('conv2_2', [128, 128, 3, 1, 1]), + ('pool2_stage1', [2, 2, 0]), + ('conv3_1', [128, 256, 3, 1, 1]), + ('conv3_2', [256, 256, 3, 1, 1]), + ('conv3_3', [256, 256, 3, 1, 1]), + ('conv3_4', [256, 256, 3, 1, 1]), + ('pool3_stage1', [2, 2, 0]), + ('conv4_1', [256, 512, 3, 1, 1]), + ('conv4_2', [512, 512, 3, 1, 1]), + ('conv4_3_CPM', [512, 256, 3, 1, 1]), + ('conv4_4_CPM', [256, 128, 3, 1, 1]) + ]) + + + # Stage 1 + block1_1 = OrderedDict([ + ('conv5_1_CPM_L1', [128, 128, 3, 1, 1]), + ('conv5_2_CPM_L1', [128, 128, 3, 1, 1]), + ('conv5_3_CPM_L1', [128, 128, 3, 1, 1]), + ('conv5_4_CPM_L1', [128, 512, 1, 1, 0]), + ('conv5_5_CPM_L1', [512, 38, 1, 1, 0]) + ]) + + block1_2 = OrderedDict([ + ('conv5_1_CPM_L2', [128, 128, 3, 1, 1]), + ('conv5_2_CPM_L2', [128, 128, 3, 1, 1]), + ('conv5_3_CPM_L2', [128, 128, 3, 1, 1]), + ('conv5_4_CPM_L2', [128, 512, 1, 1, 0]), + ('conv5_5_CPM_L2', [512, 19, 1, 1, 0]) + ]) + blocks['block1_1'] = block1_1 + blocks['block1_2'] = block1_2 + + self.model0 = make_layers(block0, no_relu_layers) + + # Stages 2 - 6 + for i in range(2, 7): + blocks['block%d_1' % i] = OrderedDict([ + ('Mconv1_stage%d_L1' % i, [185, 128, 7, 1, 3]), + ('Mconv2_stage%d_L1' % i, [128, 128, 7, 1, 3]), + ('Mconv3_stage%d_L1' % i, [128, 128, 7, 1, 3]), + ('Mconv4_stage%d_L1' % i, [128, 128, 7, 1, 3]), + ('Mconv5_stage%d_L1' % i, [128, 128, 7, 1, 3]), + ('Mconv6_stage%d_L1' % i, [128, 128, 1, 1, 0]), + ('Mconv7_stage%d_L1' % i, [128, 38, 1, 1, 0]) + ]) + + blocks['block%d_2' % i] = OrderedDict([ + ('Mconv1_stage%d_L2' % i, [185, 128, 7, 1, 3]), + ('Mconv2_stage%d_L2' % i, [128, 128, 7, 1, 3]), + ('Mconv3_stage%d_L2' % i, [128, 128, 7, 1, 3]), + ('Mconv4_stage%d_L2' % i, [128, 128, 7, 1, 3]), + ('Mconv5_stage%d_L2' % i, [128, 128, 7, 1, 3]), + ('Mconv6_stage%d_L2' % i, [128, 128, 1, 1, 0]), + ('Mconv7_stage%d_L2' % i, [128, 19, 1, 1, 0]) + ]) + + for k in blocks.keys(): + blocks[k] = make_layers(blocks[k], no_relu_layers) + + self.model1_1 = blocks['block1_1'] + self.model2_1 = blocks['block2_1'] + self.model3_1 = blocks['block3_1'] + self.model4_1 = blocks['block4_1'] + self.model5_1 = blocks['block5_1'] + self.model6_1 = blocks['block6_1'] + + self.model1_2 = blocks['block1_2'] + self.model2_2 = blocks['block2_2'] + self.model3_2 = blocks['block3_2'] + self.model4_2 = blocks['block4_2'] + self.model5_2 = blocks['block5_2'] + self.model6_2 = blocks['block6_2'] + + + def forward(self, x): + + out1 = self.model0(x) + + out1_1 = self.model1_1(out1) + out1_2 = self.model1_2(out1) + out2 = torch.cat([out1_1, out1_2, out1], 1) + + out2_1 = self.model2_1(out2) + out2_2 = self.model2_2(out2) + out3 = torch.cat([out2_1, out2_2, out1], 1) + + out3_1 = self.model3_1(out3) + out3_2 = self.model3_2(out3) + out4 = torch.cat([out3_1, out3_2, out1], 1) + + out4_1 = self.model4_1(out4) + out4_2 = self.model4_2(out4) + out5 = torch.cat([out4_1, out4_2, out1], 1) + + out5_1 = self.model5_1(out5) + out5_2 = self.model5_2(out5) + out6 = torch.cat([out5_1, out5_2, out1], 1) + + out6_1 = self.model6_1(out6) + out6_2 = self.model6_2(out6) + + return out6_1, out6_2 + +class handpose_model(nn.Module): + def __init__(self): + super(handpose_model, self).__init__() + + # these layers have no relu layer + no_relu_layers = ['conv6_2_CPM', 'Mconv7_stage2', 'Mconv7_stage3',\ + 'Mconv7_stage4', 'Mconv7_stage5', 'Mconv7_stage6'] + # stage 1 + block1_0 = OrderedDict([ + ('conv1_1', [3, 64, 3, 1, 1]), + ('conv1_2', [64, 64, 3, 1, 1]), + ('pool1_stage1', [2, 2, 0]), + ('conv2_1', [64, 128, 3, 1, 1]), + ('conv2_2', [128, 128, 3, 1, 1]), + ('pool2_stage1', [2, 2, 0]), + ('conv3_1', [128, 256, 3, 1, 1]), + ('conv3_2', [256, 256, 3, 1, 1]), + ('conv3_3', [256, 256, 3, 1, 1]), + ('conv3_4', [256, 256, 3, 1, 1]), + ('pool3_stage1', [2, 2, 0]), + ('conv4_1', [256, 512, 3, 1, 1]), + ('conv4_2', [512, 512, 3, 1, 1]), + ('conv4_3', [512, 512, 3, 1, 1]), + ('conv4_4', [512, 512, 3, 1, 1]), + ('conv5_1', [512, 512, 3, 1, 1]), + ('conv5_2', [512, 512, 3, 1, 1]), + ('conv5_3_CPM', [512, 128, 3, 1, 1]) + ]) + + block1_1 = OrderedDict([ + ('conv6_1_CPM', [128, 512, 1, 1, 0]), + ('conv6_2_CPM', [512, 22, 1, 1, 0]) + ]) + + blocks = {} + blocks['block1_0'] = block1_0 + blocks['block1_1'] = block1_1 + + # stage 2-6 + for i in range(2, 7): + blocks['block%d' % i] = OrderedDict([ + ('Mconv1_stage%d' % i, [150, 128, 7, 1, 3]), + ('Mconv2_stage%d' % i, [128, 128, 7, 1, 3]), + ('Mconv3_stage%d' % i, [128, 128, 7, 1, 3]), + ('Mconv4_stage%d' % i, [128, 128, 7, 1, 3]), + ('Mconv5_stage%d' % i, [128, 128, 7, 1, 3]), + ('Mconv6_stage%d' % i, [128, 128, 1, 1, 0]), + ('Mconv7_stage%d' % i, [128, 22, 1, 1, 0]) + ]) + + for k in blocks.keys(): + blocks[k] = make_layers(blocks[k], no_relu_layers) + + self.model1_0 = blocks['block1_0'] + self.model1_1 = blocks['block1_1'] + self.model2 = blocks['block2'] + self.model3 = blocks['block3'] + self.model4 = blocks['block4'] + self.model5 = blocks['block5'] + self.model6 = blocks['block6'] + + def forward(self, x): + out1_0 = self.model1_0(x) + out1_1 = self.model1_1(out1_0) + concat_stage2 = torch.cat([out1_1, out1_0], 1) + out_stage2 = self.model2(concat_stage2) + concat_stage3 = torch.cat([out_stage2, out1_0], 1) + out_stage3 = self.model3(concat_stage3) + concat_stage4 = torch.cat([out_stage3, out1_0], 1) + out_stage4 = self.model4(concat_stage4) + concat_stage5 = torch.cat([out_stage4, out1_0], 1) + out_stage5 = self.model5(concat_stage5) + concat_stage6 = torch.cat([out_stage5, out1_0], 1) + out_stage6 = self.model6(concat_stage6) + return out_stage6 + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/openpose/types.py b/extensions-builtin/sd_forge_controlnet/annotator/openpose/types.py new file mode 100644 index 00000000..3136612f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/openpose/types.py @@ -0,0 +1,31 @@ +from typing import NamedTuple, List, Optional, Union + + +class Keypoint(NamedTuple): + x: float + y: float + score: float = 1.0 + id: int = -1 + + +class BodyResult(NamedTuple): + # Note: Using `Optional` instead of `|` operator as the ladder is a Python + # 3.10 feature. + # Annotator code should be Python 3.8 Compatible, as controlnet repo uses + # Python 3.8 environment. + # https://github.com/lllyasviel/ControlNet/blob/d3284fcd0972c510635a4f5abe2eeb71dc0de524/environment.yaml#L6 + keypoints: List[Optional[Keypoint]] + total_score: float = 0.0 + total_parts: int = 0 + + +HandResult = List[Keypoint] +FaceResult = List[Keypoint] +AnimalPoseResult = List[Keypoint] + + +class HumanPoseResult(NamedTuple): + body: BodyResult + left_hand: Optional[HandResult] + right_hand: Optional[HandResult] + face: Optional[FaceResult] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/openpose/util.py b/extensions-builtin/sd_forge_controlnet/annotator/openpose/util.py new file mode 100644 index 00000000..00a88084 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/openpose/util.py @@ -0,0 +1,411 @@ +import math +import numpy as np +import matplotlib +import cv2 +from typing import List, Tuple, Union, Optional + +from .body import BodyResult, Keypoint + +eps = 0.01 + + +def smart_resize(x, s): + Ht, Wt = s + if x.ndim == 2: + Ho, Wo = x.shape + Co = 1 + else: + Ho, Wo, Co = x.shape + if Co == 3 or Co == 1: + k = float(Ht + Wt) / float(Ho + Wo) + return cv2.resize(x, (int(Wt), int(Ht)), interpolation=cv2.INTER_AREA if k < 1 else cv2.INTER_LANCZOS4) + else: + return np.stack([smart_resize(x[:, :, i], s) for i in range(Co)], axis=2) + + +def smart_resize_k(x, fx, fy): + if x.ndim == 2: + Ho, Wo = x.shape + Co = 1 + else: + Ho, Wo, Co = x.shape + Ht, Wt = Ho * fy, Wo * fx + if Co == 3 or Co == 1: + k = float(Ht + Wt) / float(Ho + Wo) + return cv2.resize(x, (int(Wt), int(Ht)), interpolation=cv2.INTER_AREA if k < 1 else cv2.INTER_LANCZOS4) + else: + return np.stack([smart_resize_k(x[:, :, i], fx, fy) for i in range(Co)], axis=2) + + +def padRightDownCorner(img, stride, padValue): + h = img.shape[0] + w = img.shape[1] + + pad = 4 * [None] + pad[0] = 0 # up + pad[1] = 0 # left + pad[2] = 0 if (h % stride == 0) else stride - (h % stride) # down + pad[3] = 0 if (w % stride == 0) else stride - (w % stride) # right + + img_padded = img + pad_up = np.tile(img_padded[0:1, :, :]*0 + padValue, (pad[0], 1, 1)) + img_padded = np.concatenate((pad_up, img_padded), axis=0) + pad_left = np.tile(img_padded[:, 0:1, :]*0 + padValue, (1, pad[1], 1)) + img_padded = np.concatenate((pad_left, img_padded), axis=1) + pad_down = np.tile(img_padded[-2:-1, :, :]*0 + padValue, (pad[2], 1, 1)) + img_padded = np.concatenate((img_padded, pad_down), axis=0) + pad_right = np.tile(img_padded[:, -2:-1, :]*0 + padValue, (1, pad[3], 1)) + img_padded = np.concatenate((img_padded, pad_right), axis=1) + + return img_padded, pad + + +def transfer(model, model_weights): + transfered_model_weights = {} + for weights_name in model.state_dict().keys(): + transfered_model_weights[weights_name] = model_weights['.'.join(weights_name.split('.')[1:])] + return transfered_model_weights + + +def is_normalized(keypoints: List[Optional[Keypoint]]) -> bool: + point_normalized = [ + 0 <= abs(k.x) <= 1 and 0 <= abs(k.y) <= 1 + for k in keypoints + if k is not None + ] + if not point_normalized: + return False + return all(point_normalized) + + +def draw_bodypose(canvas: np.ndarray, keypoints: List[Keypoint]) -> np.ndarray: + """ + Draw keypoints and limbs representing body pose on a given canvas. + + Args: + canvas (np.ndarray): A 3D numpy array representing the canvas (image) on which to draw the body pose. + keypoints (List[Keypoint]): A list of Keypoint objects representing the body keypoints to be drawn. + + Returns: + np.ndarray: A 3D numpy array representing the modified canvas with the drawn body pose. + + Note: + The function expects the x and y coordinates of the keypoints to be normalized between 0 and 1. + """ + if not is_normalized(keypoints): + H, W = 1.0, 1.0 + else: + H, W, _ = canvas.shape + + stickwidth = 4 + + limbSeq = [ + [2, 3], [2, 6], [3, 4], [4, 5], + [6, 7], [7, 8], [2, 9], [9, 10], + [10, 11], [2, 12], [12, 13], [13, 14], + [2, 1], [1, 15], [15, 17], [1, 16], + [16, 18], + ] + + colors = [[255, 0, 0], [255, 85, 0], [255, 170, 0], [255, 255, 0], [170, 255, 0], [85, 255, 0], [0, 255, 0], \ + [0, 255, 85], [0, 255, 170], [0, 255, 255], [0, 170, 255], [0, 85, 255], [0, 0, 255], [85, 0, 255], \ + [170, 0, 255], [255, 0, 255], [255, 0, 170], [255, 0, 85]] + + for (k1_index, k2_index), color in zip(limbSeq, colors): + keypoint1 = keypoints[k1_index - 1] + keypoint2 = keypoints[k2_index - 1] + + if keypoint1 is None or keypoint2 is None: + continue + + Y = np.array([keypoint1.x, keypoint2.x]) * float(W) + X = np.array([keypoint1.y, keypoint2.y]) * float(H) + mX = np.mean(X) + mY = np.mean(Y) + length = ((X[0] - X[1]) ** 2 + (Y[0] - Y[1]) ** 2) ** 0.5 + angle = math.degrees(math.atan2(X[0] - X[1], Y[0] - Y[1])) + polygon = cv2.ellipse2Poly((int(mY), int(mX)), (int(length / 2), stickwidth), int(angle), 0, 360, 1) + cv2.fillConvexPoly(canvas, polygon, [int(float(c) * 0.6) for c in color]) + + for keypoint, color in zip(keypoints, colors): + if keypoint is None: + continue + + x, y = keypoint.x, keypoint.y + x = int(x * W) + y = int(y * H) + cv2.circle(canvas, (int(x), int(y)), 4, color, thickness=-1) + + return canvas + + +def draw_handpose(canvas: np.ndarray, keypoints: Union[List[Keypoint], None]) -> np.ndarray: + """ + Draw keypoints and connections representing hand pose on a given canvas. + + Args: + canvas (np.ndarray): A 3D numpy array representing the canvas (image) on which to draw the hand pose. + keypoints (List[Keypoint]| None): A list of Keypoint objects representing the hand keypoints to be drawn + or None if no keypoints are present. + + Returns: + np.ndarray: A 3D numpy array representing the modified canvas with the drawn hand pose. + + Note: + The function expects the x and y coordinates of the keypoints to be normalized between 0 and 1. + """ + if not keypoints: + return canvas + + if not is_normalized(keypoints): + H, W = 1.0, 1.0 + else: + H, W, _ = canvas.shape + + edges = [[0, 1], [1, 2], [2, 3], [3, 4], [0, 5], [5, 6], [6, 7], [7, 8], [0, 9], [9, 10], \ + [10, 11], [11, 12], [0, 13], [13, 14], [14, 15], [15, 16], [0, 17], [17, 18], [18, 19], [19, 20]] + + for ie, (e1, e2) in enumerate(edges): + k1 = keypoints[e1] + k2 = keypoints[e2] + if k1 is None or k2 is None: + continue + + x1 = int(k1.x * W) + y1 = int(k1.y * H) + x2 = int(k2.x * W) + y2 = int(k2.y * H) + if x1 > eps and y1 > eps and x2 > eps and y2 > eps: + cv2.line(canvas, (x1, y1), (x2, y2), matplotlib.colors.hsv_to_rgb([ie / float(len(edges)), 1.0, 1.0]) * 255, thickness=2) + + for keypoint in keypoints: + if keypoint is None: + continue + + x, y = keypoint.x, keypoint.y + x = int(x * W) + y = int(y * H) + if x > eps and y > eps: + cv2.circle(canvas, (x, y), 4, (0, 0, 255), thickness=-1) + return canvas + + +def draw_facepose(canvas: np.ndarray, keypoints: Union[List[Keypoint], None]) -> np.ndarray: + """ + Draw keypoints representing face pose on a given canvas. + + Args: + canvas (np.ndarray): A 3D numpy array representing the canvas (image) on which to draw the face pose. + keypoints (List[Keypoint]| None): A list of Keypoint objects representing the face keypoints to be drawn + or None if no keypoints are present. + + Returns: + np.ndarray: A 3D numpy array representing the modified canvas with the drawn face pose. + + Note: + The function expects the x and y coordinates of the keypoints to be normalized between 0 and 1. + """ + if not keypoints: + return canvas + + if not is_normalized(keypoints): + H, W = 1.0, 1.0 + else: + H, W, _ = canvas.shape + + for keypoint in keypoints: + if keypoint is None: + continue + + x, y = keypoint.x, keypoint.y + x = int(x * W) + y = int(y * H) + if x > eps and y > eps: + cv2.circle(canvas, (x, y), 3, (255, 255, 255), thickness=-1) + return canvas + + +# detect hand according to body pose keypoints +# please refer to https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/src/openpose/hand/handDetector.cpp +def handDetect(body: BodyResult, oriImg) -> List[Tuple[int, int, int, bool]]: + """ + Detect hands in the input body pose keypoints and calculate the bounding box for each hand. + + Args: + body (BodyResult): A BodyResult object containing the detected body pose keypoints. + oriImg (numpy.ndarray): A 3D numpy array representing the original input image. + + Returns: + List[Tuple[int, int, int, bool]]: A list of tuples, each containing the coordinates (x, y) of the top-left + corner of the bounding box, the width (height) of the bounding box, and + a boolean flag indicating whether the hand is a left hand (True) or a + right hand (False). + + Notes: + - The width and height of the bounding boxes are equal since the network requires squared input. + - The minimum bounding box size is 20 pixels. + """ + ratioWristElbow = 0.33 + detect_result = [] + image_height, image_width = oriImg.shape[0:2] + + keypoints = body.keypoints + # right hand: wrist 4, elbow 3, shoulder 2 + # left hand: wrist 7, elbow 6, shoulder 5 + left_shoulder = keypoints[5] + left_elbow = keypoints[6] + left_wrist = keypoints[7] + right_shoulder = keypoints[2] + right_elbow = keypoints[3] + right_wrist = keypoints[4] + + # if any of three not detected + has_left = all(keypoint is not None for keypoint in (left_shoulder, left_elbow, left_wrist)) + has_right = all(keypoint is not None for keypoint in (right_shoulder, right_elbow, right_wrist)) + if not (has_left or has_right): + return [] + + hands = [] + #left hand + if has_left: + hands.append([ + left_shoulder.x, left_shoulder.y, + left_elbow.x, left_elbow.y, + left_wrist.x, left_wrist.y, + True + ]) + # right hand + if has_right: + hands.append([ + right_shoulder.x, right_shoulder.y, + right_elbow.x, right_elbow.y, + right_wrist.x, right_wrist.y, + False + ]) + + for x1, y1, x2, y2, x3, y3, is_left in hands: + # pos_hand = pos_wrist + ratio * (pos_wrist - pos_elbox) = (1 + ratio) * pos_wrist - ratio * pos_elbox + # handRectangle.x = posePtr[wrist*3] + ratioWristElbow * (posePtr[wrist*3] - posePtr[elbow*3]); + # handRectangle.y = posePtr[wrist*3+1] + ratioWristElbow * (posePtr[wrist*3+1] - posePtr[elbow*3+1]); + # const auto distanceWristElbow = getDistance(poseKeypoints, person, wrist, elbow); + # const auto distanceElbowShoulder = getDistance(poseKeypoints, person, elbow, shoulder); + # handRectangle.width = 1.5f * fastMax(distanceWristElbow, 0.9f * distanceElbowShoulder); + x = x3 + ratioWristElbow * (x3 - x2) + y = y3 + ratioWristElbow * (y3 - y2) + distanceWristElbow = math.sqrt((x3 - x2) ** 2 + (y3 - y2) ** 2) + distanceElbowShoulder = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) + width = 1.5 * max(distanceWristElbow, 0.9 * distanceElbowShoulder) + # x-y refers to the center --> offset to topLeft point + # handRectangle.x -= handRectangle.width / 2.f; + # handRectangle.y -= handRectangle.height / 2.f; + x -= width / 2 + y -= width / 2 # width = height + # overflow the image + if x < 0: x = 0 + if y < 0: y = 0 + width1 = width + width2 = width + if x + width > image_width: width1 = image_width - x + if y + width > image_height: width2 = image_height - y + width = min(width1, width2) + # the max hand box value is 20 pixels + if width >= 20: + detect_result.append((int(x), int(y), int(width), is_left)) + + ''' + return value: [[x, y, w, True if left hand else False]]. + width=height since the network require squared input. + x, y is the coordinate of top left + ''' + return detect_result + + +# Written by Lvmin +def faceDetect(body: BodyResult, oriImg) -> Union[Tuple[int, int, int], None]: + """ + Detect the face in the input body pose keypoints and calculate the bounding box for the face. + + Args: + body (BodyResult): A BodyResult object containing the detected body pose keypoints. + oriImg (numpy.ndarray): A 3D numpy array representing the original input image. + + Returns: + Tuple[int, int, int] | None: A tuple containing the coordinates (x, y) of the top-left corner of the + bounding box and the width (height) of the bounding box, or None if the + face is not detected or the bounding box width is less than 20 pixels. + + Notes: + - The width and height of the bounding box are equal. + - The minimum bounding box size is 20 pixels. + """ + # left right eye ear 14 15 16 17 + image_height, image_width = oriImg.shape[0:2] + + keypoints = body.keypoints + head = keypoints[0] + left_eye = keypoints[14] + right_eye = keypoints[15] + left_ear = keypoints[16] + right_ear = keypoints[17] + + if head is None or all(keypoint is None for keypoint in (left_eye, right_eye, left_ear, right_ear)): + return None + + width = 0.0 + x0, y0 = head.x, head.y + + if left_eye is not None: + x1, y1 = left_eye.x, left_eye.y + d = max(abs(x0 - x1), abs(y0 - y1)) + width = max(width, d * 3.0) + + if right_eye is not None: + x1, y1 = right_eye.x, right_eye.y + d = max(abs(x0 - x1), abs(y0 - y1)) + width = max(width, d * 3.0) + + if left_ear is not None: + x1, y1 = left_ear.x, left_ear.y + d = max(abs(x0 - x1), abs(y0 - y1)) + width = max(width, d * 1.5) + + if right_ear is not None: + x1, y1 = right_ear.x, right_ear.y + d = max(abs(x0 - x1), abs(y0 - y1)) + width = max(width, d * 1.5) + + x, y = x0, y0 + + x -= width + y -= width + + if x < 0: + x = 0 + + if y < 0: + y = 0 + + width1 = width * 2 + width2 = width * 2 + + if x + width > image_width: + width1 = image_width - x + + if y + width > image_height: + width2 = image_height - y + + width = min(width1, width2) + + if width >= 20: + return int(x), int(y), int(width) + else: + return None + + +# get max index of 2d array +def npmax(array): + arrayindex = array.argmax(1) + arrayvalue = array.max(1) + i = arrayvalue.argmax() + j = arrayindex[i] + return i, j \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/openpose/wholebody.py b/extensions-builtin/sd_forge_controlnet/annotator/openpose/wholebody.py new file mode 100644 index 00000000..37bf1178 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/openpose/wholebody.py @@ -0,0 +1,100 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import cv2 +import numpy as np + +from .cv_ox_det import inference_detector +from .cv_ox_pose import inference_pose + +from typing import List, Optional +from .types import HumanPoseResult, BodyResult, Keypoint + + +class Wholebody: + def __init__(self, onnx_det: str, onnx_pose: str): + # Always loads to CPU to avoid building OpenCV. + device = 'cpu' + backend = cv2.dnn.DNN_BACKEND_OPENCV if device == 'cpu' else cv2.dnn.DNN_BACKEND_CUDA + # You need to manually build OpenCV through cmake to work with your GPU. + providers = cv2.dnn.DNN_TARGET_CPU if device == 'cpu' else cv2.dnn.DNN_TARGET_CUDA + + self.session_det = cv2.dnn.readNetFromONNX(onnx_det) + self.session_det.setPreferableBackend(backend) + self.session_det.setPreferableTarget(providers) + + self.session_pose = cv2.dnn.readNetFromONNX(onnx_pose) + self.session_pose.setPreferableBackend(backend) + self.session_pose.setPreferableTarget(providers) + + def __call__(self, oriImg) -> Optional[np.ndarray]: + det_result = inference_detector(self.session_det, oriImg) + if det_result is None: + return None + + keypoints, scores = inference_pose(self.session_pose, det_result, oriImg) + + keypoints_info = np.concatenate( + (keypoints, scores[..., None]), axis=-1) + # compute neck joint + neck = np.mean(keypoints_info[:, [5, 6]], axis=1) + # neck score when visualizing pred + neck[:, 2:4] = np.logical_and( + keypoints_info[:, 5, 2:4] > 0.3, + keypoints_info[:, 6, 2:4] > 0.3).astype(int) + new_keypoints_info = np.insert( + keypoints_info, 17, neck, axis=1) + mmpose_idx = [ + 17, 6, 8, 10, 7, 9, 12, 14, 16, 13, 15, 2, 1, 4, 3 + ] + openpose_idx = [ + 1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17 + ] + new_keypoints_info[:, openpose_idx] = \ + new_keypoints_info[:, mmpose_idx] + keypoints_info = new_keypoints_info + + return keypoints_info + + @staticmethod + def format_result(keypoints_info: Optional[np.ndarray]) -> List[HumanPoseResult]: + def format_keypoint_part( + part: np.ndarray, + ) -> Optional[List[Optional[Keypoint]]]: + keypoints = [ + Keypoint(x, y, score, i) if score >= 0.3 else None + for i, (x, y, score) in enumerate(part) + ] + return ( + None if all(keypoint is None for keypoint in keypoints) else keypoints + ) + + def total_score(keypoints: Optional[List[Optional[Keypoint]]]) -> float: + return ( + sum(keypoint.score for keypoint in keypoints if keypoint is not None) + if keypoints is not None + else 0.0 + ) + + pose_results = [] + if keypoints_info is None: + return pose_results + + for instance in keypoints_info: + body_keypoints = format_keypoint_part(instance[:18]) or ([None] * 18) + left_hand = format_keypoint_part(instance[92:113]) + right_hand = format_keypoint_part(instance[113:134]) + face = format_keypoint_part(instance[24:92]) + + # Openpose face consists of 70 points in total, while DWPose only + # provides 68 points. Padding the last 2 points. + if face is not None: + # left eye + face.append(body_keypoints[14]) + # right eye + face.append(body_keypoints[15]) + + body = BodyResult( + body_keypoints, total_score(body_keypoints), len(body_keypoints) + ) + pose_results.append(HumanPoseResult(body, left_hand, right_hand, face)) + + return pose_results diff --git a/extensions-builtin/sd_forge_controlnet/annotator/pidinet/LICENSE b/extensions-builtin/sd_forge_controlnet/annotator/pidinet/LICENSE new file mode 100644 index 00000000..913b6cf9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/pidinet/LICENSE @@ -0,0 +1,21 @@ +It is just for research purpose, and commercial use should be contacted with authors first. + +Copyright (c) 2021 Zhuo Su + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/pidinet/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/pidinet/__init__.py new file mode 100644 index 00000000..7a3f6c10 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/pidinet/__init__.py @@ -0,0 +1,51 @@ +import os +import torch +import numpy as np +from einops import rearrange +from annotator.pidinet.model import pidinet +from annotator.util import safe_step +from modules import devices +from annotator.annotator_path import models_path +from scripts.utils import load_state_dict + +netNetwork = None +remote_model_path = "https://huggingface.co/lllyasviel/Annotators/resolve/main/table5_pidinet.pth" +modeldir = os.path.join(models_path, "pidinet") +old_modeldir = os.path.dirname(os.path.realpath(__file__)) + +def apply_pidinet(input_image, is_safe=False, apply_fliter=False): + global netNetwork + if netNetwork is None: + modelpath = os.path.join(modeldir, "table5_pidinet.pth") + old_modelpath = os.path.join(old_modeldir, "table5_pidinet.pth") + if os.path.exists(old_modelpath): + modelpath = old_modelpath + elif not os.path.exists(modelpath): + from basicsr.utils.download_util import load_file_from_url + load_file_from_url(remote_model_path, model_dir=modeldir) + netNetwork = pidinet() + ckp = load_state_dict(modelpath) + netNetwork.load_state_dict({k.replace('module.',''):v for k, v in ckp.items()}) + + netNetwork = netNetwork.to(devices.get_device_for("controlnet")) + netNetwork.eval() + assert input_image.ndim == 3 + input_image = input_image[:, :, ::-1].copy() + with torch.no_grad(): + image_pidi = torch.from_numpy(input_image).float().to(devices.get_device_for("controlnet")) + image_pidi = image_pidi / 255.0 + image_pidi = rearrange(image_pidi, 'h w c -> 1 c h w') + edge = netNetwork(image_pidi)[-1] + edge = edge.cpu().numpy() + if apply_fliter: + edge = edge > 0.5 + if is_safe: + edge = safe_step(edge) + edge = (edge * 255.0).clip(0, 255).astype(np.uint8) + + return edge[0][0] + +def unload_pid_model(): + global netNetwork + if netNetwork is not None: + netNetwork.cpu() \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/pidinet/model.py b/extensions-builtin/sd_forge_controlnet/annotator/pidinet/model.py new file mode 100644 index 00000000..c778b89c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/pidinet/model.py @@ -0,0 +1,654 @@ +""" +Author: Zhuo Su, Wenzhe Liu +Date: Feb 18, 2021 +""" + +import math + +import cv2 +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F +from modules import devices +from basicsr.utils import img2tensor + +nets = { + 'baseline': { + 'layer0': 'cv', + 'layer1': 'cv', + 'layer2': 'cv', + 'layer3': 'cv', + 'layer4': 'cv', + 'layer5': 'cv', + 'layer6': 'cv', + 'layer7': 'cv', + 'layer8': 'cv', + 'layer9': 'cv', + 'layer10': 'cv', + 'layer11': 'cv', + 'layer12': 'cv', + 'layer13': 'cv', + 'layer14': 'cv', + 'layer15': 'cv', + }, + 'c-v15': { + 'layer0': 'cd', + 'layer1': 'cv', + 'layer2': 'cv', + 'layer3': 'cv', + 'layer4': 'cv', + 'layer5': 'cv', + 'layer6': 'cv', + 'layer7': 'cv', + 'layer8': 'cv', + 'layer9': 'cv', + 'layer10': 'cv', + 'layer11': 'cv', + 'layer12': 'cv', + 'layer13': 'cv', + 'layer14': 'cv', + 'layer15': 'cv', + }, + 'a-v15': { + 'layer0': 'ad', + 'layer1': 'cv', + 'layer2': 'cv', + 'layer3': 'cv', + 'layer4': 'cv', + 'layer5': 'cv', + 'layer6': 'cv', + 'layer7': 'cv', + 'layer8': 'cv', + 'layer9': 'cv', + 'layer10': 'cv', + 'layer11': 'cv', + 'layer12': 'cv', + 'layer13': 'cv', + 'layer14': 'cv', + 'layer15': 'cv', + }, + 'r-v15': { + 'layer0': 'rd', + 'layer1': 'cv', + 'layer2': 'cv', + 'layer3': 'cv', + 'layer4': 'cv', + 'layer5': 'cv', + 'layer6': 'cv', + 'layer7': 'cv', + 'layer8': 'cv', + 'layer9': 'cv', + 'layer10': 'cv', + 'layer11': 'cv', + 'layer12': 'cv', + 'layer13': 'cv', + 'layer14': 'cv', + 'layer15': 'cv', + }, + 'cvvv4': { + 'layer0': 'cd', + 'layer1': 'cv', + 'layer2': 'cv', + 'layer3': 'cv', + 'layer4': 'cd', + 'layer5': 'cv', + 'layer6': 'cv', + 'layer7': 'cv', + 'layer8': 'cd', + 'layer9': 'cv', + 'layer10': 'cv', + 'layer11': 'cv', + 'layer12': 'cd', + 'layer13': 'cv', + 'layer14': 'cv', + 'layer15': 'cv', + }, + 'avvv4': { + 'layer0': 'ad', + 'layer1': 'cv', + 'layer2': 'cv', + 'layer3': 'cv', + 'layer4': 'ad', + 'layer5': 'cv', + 'layer6': 'cv', + 'layer7': 'cv', + 'layer8': 'ad', + 'layer9': 'cv', + 'layer10': 'cv', + 'layer11': 'cv', + 'layer12': 'ad', + 'layer13': 'cv', + 'layer14': 'cv', + 'layer15': 'cv', + }, + 'rvvv4': { + 'layer0': 'rd', + 'layer1': 'cv', + 'layer2': 'cv', + 'layer3': 'cv', + 'layer4': 'rd', + 'layer5': 'cv', + 'layer6': 'cv', + 'layer7': 'cv', + 'layer8': 'rd', + 'layer9': 'cv', + 'layer10': 'cv', + 'layer11': 'cv', + 'layer12': 'rd', + 'layer13': 'cv', + 'layer14': 'cv', + 'layer15': 'cv', + }, + 'cccv4': { + 'layer0': 'cd', + 'layer1': 'cd', + 'layer2': 'cd', + 'layer3': 'cv', + 'layer4': 'cd', + 'layer5': 'cd', + 'layer6': 'cd', + 'layer7': 'cv', + 'layer8': 'cd', + 'layer9': 'cd', + 'layer10': 'cd', + 'layer11': 'cv', + 'layer12': 'cd', + 'layer13': 'cd', + 'layer14': 'cd', + 'layer15': 'cv', + }, + 'aaav4': { + 'layer0': 'ad', + 'layer1': 'ad', + 'layer2': 'ad', + 'layer3': 'cv', + 'layer4': 'ad', + 'layer5': 'ad', + 'layer6': 'ad', + 'layer7': 'cv', + 'layer8': 'ad', + 'layer9': 'ad', + 'layer10': 'ad', + 'layer11': 'cv', + 'layer12': 'ad', + 'layer13': 'ad', + 'layer14': 'ad', + 'layer15': 'cv', + }, + 'rrrv4': { + 'layer0': 'rd', + 'layer1': 'rd', + 'layer2': 'rd', + 'layer3': 'cv', + 'layer4': 'rd', + 'layer5': 'rd', + 'layer6': 'rd', + 'layer7': 'cv', + 'layer8': 'rd', + 'layer9': 'rd', + 'layer10': 'rd', + 'layer11': 'cv', + 'layer12': 'rd', + 'layer13': 'rd', + 'layer14': 'rd', + 'layer15': 'cv', + }, + 'c16': { + 'layer0': 'cd', + 'layer1': 'cd', + 'layer2': 'cd', + 'layer3': 'cd', + 'layer4': 'cd', + 'layer5': 'cd', + 'layer6': 'cd', + 'layer7': 'cd', + 'layer8': 'cd', + 'layer9': 'cd', + 'layer10': 'cd', + 'layer11': 'cd', + 'layer12': 'cd', + 'layer13': 'cd', + 'layer14': 'cd', + 'layer15': 'cd', + }, + 'a16': { + 'layer0': 'ad', + 'layer1': 'ad', + 'layer2': 'ad', + 'layer3': 'ad', + 'layer4': 'ad', + 'layer5': 'ad', + 'layer6': 'ad', + 'layer7': 'ad', + 'layer8': 'ad', + 'layer9': 'ad', + 'layer10': 'ad', + 'layer11': 'ad', + 'layer12': 'ad', + 'layer13': 'ad', + 'layer14': 'ad', + 'layer15': 'ad', + }, + 'r16': { + 'layer0': 'rd', + 'layer1': 'rd', + 'layer2': 'rd', + 'layer3': 'rd', + 'layer4': 'rd', + 'layer5': 'rd', + 'layer6': 'rd', + 'layer7': 'rd', + 'layer8': 'rd', + 'layer9': 'rd', + 'layer10': 'rd', + 'layer11': 'rd', + 'layer12': 'rd', + 'layer13': 'rd', + 'layer14': 'rd', + 'layer15': 'rd', + }, + 'carv4': { + 'layer0': 'cd', + 'layer1': 'ad', + 'layer2': 'rd', + 'layer3': 'cv', + 'layer4': 'cd', + 'layer5': 'ad', + 'layer6': 'rd', + 'layer7': 'cv', + 'layer8': 'cd', + 'layer9': 'ad', + 'layer10': 'rd', + 'layer11': 'cv', + 'layer12': 'cd', + 'layer13': 'ad', + 'layer14': 'rd', + 'layer15': 'cv', + }, + } + +def createConvFunc(op_type): + assert op_type in ['cv', 'cd', 'ad', 'rd'], 'unknown op type: %s' % str(op_type) + if op_type == 'cv': + return F.conv2d + + if op_type == 'cd': + def func(x, weights, bias=None, stride=1, padding=0, dilation=1, groups=1): + assert dilation in [1, 2], 'dilation for cd_conv should be in 1 or 2' + assert weights.size(2) == 3 and weights.size(3) == 3, 'kernel size for cd_conv should be 3x3' + assert padding == dilation, 'padding for cd_conv set wrong' + + weights_c = weights.sum(dim=[2, 3], keepdim=True) + yc = F.conv2d(x, weights_c, stride=stride, padding=0, groups=groups) + y = F.conv2d(x, weights, bias, stride=stride, padding=padding, dilation=dilation, groups=groups) + return y - yc + return func + elif op_type == 'ad': + def func(x, weights, bias=None, stride=1, padding=0, dilation=1, groups=1): + assert dilation in [1, 2], 'dilation for ad_conv should be in 1 or 2' + assert weights.size(2) == 3 and weights.size(3) == 3, 'kernel size for ad_conv should be 3x3' + assert padding == dilation, 'padding for ad_conv set wrong' + + shape = weights.shape + weights = weights.view(shape[0], shape[1], -1) + weights_conv = (weights - weights[:, :, [3, 0, 1, 6, 4, 2, 7, 8, 5]]).view(shape) # clock-wise + y = F.conv2d(x, weights_conv, bias, stride=stride, padding=padding, dilation=dilation, groups=groups) + return y + return func + elif op_type == 'rd': + def func(x, weights, bias=None, stride=1, padding=0, dilation=1, groups=1): + assert dilation in [1, 2], 'dilation for rd_conv should be in 1 or 2' + assert weights.size(2) == 3 and weights.size(3) == 3, 'kernel size for rd_conv should be 3x3' + padding = 2 * dilation + + shape = weights.shape + if weights.is_cuda: + buffer = torch.cuda.FloatTensor(shape[0], shape[1], 5 * 5).fill_(0).to(devices.get_device_for("controlnet")) + else: + buffer = torch.zeros(shape[0], shape[1], 5 * 5).to(devices.get_device_for("controlnet")) + weights = weights.view(shape[0], shape[1], -1) + buffer[:, :, [0, 2, 4, 10, 14, 20, 22, 24]] = weights[:, :, 1:] + buffer[:, :, [6, 7, 8, 11, 13, 16, 17, 18]] = -weights[:, :, 1:] + buffer[:, :, 12] = 0 + buffer = buffer.view(shape[0], shape[1], 5, 5) + y = F.conv2d(x, buffer, bias, stride=stride, padding=padding, dilation=dilation, groups=groups) + return y + return func + else: + print('impossible to be here unless you force that') + return None + +class Conv2d(nn.Module): + def __init__(self, pdc, in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=False): + super(Conv2d, self).__init__() + if in_channels % groups != 0: + raise ValueError('in_channels must be divisible by groups') + if out_channels % groups != 0: + raise ValueError('out_channels must be divisible by groups') + self.in_channels = in_channels + self.out_channels = out_channels + self.kernel_size = kernel_size + self.stride = stride + self.padding = padding + self.dilation = dilation + self.groups = groups + self.weight = nn.Parameter(torch.Tensor(out_channels, in_channels // groups, kernel_size, kernel_size)) + if bias: + self.bias = nn.Parameter(torch.Tensor(out_channels)) + else: + self.register_parameter('bias', None) + self.reset_parameters() + self.pdc = pdc + + def reset_parameters(self): + nn.init.kaiming_uniform_(self.weight, a=math.sqrt(5)) + if self.bias is not None: + fan_in, _ = nn.init._calculate_fan_in_and_fan_out(self.weight) + bound = 1 / math.sqrt(fan_in) + nn.init.uniform_(self.bias, -bound, bound) + + def forward(self, input): + + return self.pdc(input, self.weight, self.bias, self.stride, self.padding, self.dilation, self.groups) + +class CSAM(nn.Module): + """ + Compact Spatial Attention Module + """ + def __init__(self, channels): + super(CSAM, self).__init__() + + mid_channels = 4 + self.relu1 = nn.ReLU() + self.conv1 = nn.Conv2d(channels, mid_channels, kernel_size=1, padding=0) + self.conv2 = nn.Conv2d(mid_channels, 1, kernel_size=3, padding=1, bias=False) + self.sigmoid = nn.Sigmoid() + nn.init.constant_(self.conv1.bias, 0) + + def forward(self, x): + y = self.relu1(x) + y = self.conv1(y) + y = self.conv2(y) + y = self.sigmoid(y) + + return x * y + +class CDCM(nn.Module): + """ + Compact Dilation Convolution based Module + """ + def __init__(self, in_channels, out_channels): + super(CDCM, self).__init__() + + self.relu1 = nn.ReLU() + self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=1, padding=0) + self.conv2_1 = nn.Conv2d(out_channels, out_channels, kernel_size=3, dilation=5, padding=5, bias=False) + self.conv2_2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, dilation=7, padding=7, bias=False) + self.conv2_3 = nn.Conv2d(out_channels, out_channels, kernel_size=3, dilation=9, padding=9, bias=False) + self.conv2_4 = nn.Conv2d(out_channels, out_channels, kernel_size=3, dilation=11, padding=11, bias=False) + nn.init.constant_(self.conv1.bias, 0) + + def forward(self, x): + x = self.relu1(x) + x = self.conv1(x) + x1 = self.conv2_1(x) + x2 = self.conv2_2(x) + x3 = self.conv2_3(x) + x4 = self.conv2_4(x) + return x1 + x2 + x3 + x4 + + +class MapReduce(nn.Module): + """ + Reduce feature maps into a single edge map + """ + def __init__(self, channels): + super(MapReduce, self).__init__() + self.conv = nn.Conv2d(channels, 1, kernel_size=1, padding=0) + nn.init.constant_(self.conv.bias, 0) + + def forward(self, x): + return self.conv(x) + + +class PDCBlock(nn.Module): + def __init__(self, pdc, inplane, ouplane, stride=1): + super(PDCBlock, self).__init__() + self.stride=stride + + self.stride=stride + if self.stride > 1: + self.pool = nn.MaxPool2d(kernel_size=2, stride=2) + self.shortcut = nn.Conv2d(inplane, ouplane, kernel_size=1, padding=0) + self.conv1 = Conv2d(pdc, inplane, inplane, kernel_size=3, padding=1, groups=inplane, bias=False) + self.relu2 = nn.ReLU() + self.conv2 = nn.Conv2d(inplane, ouplane, kernel_size=1, padding=0, bias=False) + + def forward(self, x): + if self.stride > 1: + x = self.pool(x) + y = self.conv1(x) + y = self.relu2(y) + y = self.conv2(y) + if self.stride > 1: + x = self.shortcut(x) + y = y + x + return y + +class PDCBlock_converted(nn.Module): + """ + CPDC, APDC can be converted to vanilla 3x3 convolution + RPDC can be converted to vanilla 5x5 convolution + """ + def __init__(self, pdc, inplane, ouplane, stride=1): + super(PDCBlock_converted, self).__init__() + self.stride=stride + + if self.stride > 1: + self.pool = nn.MaxPool2d(kernel_size=2, stride=2) + self.shortcut = nn.Conv2d(inplane, ouplane, kernel_size=1, padding=0) + if pdc == 'rd': + self.conv1 = nn.Conv2d(inplane, inplane, kernel_size=5, padding=2, groups=inplane, bias=False) + else: + self.conv1 = nn.Conv2d(inplane, inplane, kernel_size=3, padding=1, groups=inplane, bias=False) + self.relu2 = nn.ReLU() + self.conv2 = nn.Conv2d(inplane, ouplane, kernel_size=1, padding=0, bias=False) + + def forward(self, x): + if self.stride > 1: + x = self.pool(x) + y = self.conv1(x) + y = self.relu2(y) + y = self.conv2(y) + if self.stride > 1: + x = self.shortcut(x) + y = y + x + return y + +class PiDiNet(nn.Module): + def __init__(self, inplane, pdcs, dil=None, sa=False, convert=False): + super(PiDiNet, self).__init__() + self.sa = sa + if dil is not None: + assert isinstance(dil, int), 'dil should be an int' + self.dil = dil + + self.fuseplanes = [] + + self.inplane = inplane + if convert: + if pdcs[0] == 'rd': + init_kernel_size = 5 + init_padding = 2 + else: + init_kernel_size = 3 + init_padding = 1 + self.init_block = nn.Conv2d(3, self.inplane, + kernel_size=init_kernel_size, padding=init_padding, bias=False) + block_class = PDCBlock_converted + else: + self.init_block = Conv2d(pdcs[0], 3, self.inplane, kernel_size=3, padding=1) + block_class = PDCBlock + + self.block1_1 = block_class(pdcs[1], self.inplane, self.inplane) + self.block1_2 = block_class(pdcs[2], self.inplane, self.inplane) + self.block1_3 = block_class(pdcs[3], self.inplane, self.inplane) + self.fuseplanes.append(self.inplane) # C + + inplane = self.inplane + self.inplane = self.inplane * 2 + self.block2_1 = block_class(pdcs[4], inplane, self.inplane, stride=2) + self.block2_2 = block_class(pdcs[5], self.inplane, self.inplane) + self.block2_3 = block_class(pdcs[6], self.inplane, self.inplane) + self.block2_4 = block_class(pdcs[7], self.inplane, self.inplane) + self.fuseplanes.append(self.inplane) # 2C + + inplane = self.inplane + self.inplane = self.inplane * 2 + self.block3_1 = block_class(pdcs[8], inplane, self.inplane, stride=2) + self.block3_2 = block_class(pdcs[9], self.inplane, self.inplane) + self.block3_3 = block_class(pdcs[10], self.inplane, self.inplane) + self.block3_4 = block_class(pdcs[11], self.inplane, self.inplane) + self.fuseplanes.append(self.inplane) # 4C + + self.block4_1 = block_class(pdcs[12], self.inplane, self.inplane, stride=2) + self.block4_2 = block_class(pdcs[13], self.inplane, self.inplane) + self.block4_3 = block_class(pdcs[14], self.inplane, self.inplane) + self.block4_4 = block_class(pdcs[15], self.inplane, self.inplane) + self.fuseplanes.append(self.inplane) # 4C + + self.conv_reduces = nn.ModuleList() + if self.sa and self.dil is not None: + self.attentions = nn.ModuleList() + self.dilations = nn.ModuleList() + for i in range(4): + self.dilations.append(CDCM(self.fuseplanes[i], self.dil)) + self.attentions.append(CSAM(self.dil)) + self.conv_reduces.append(MapReduce(self.dil)) + elif self.sa: + self.attentions = nn.ModuleList() + for i in range(4): + self.attentions.append(CSAM(self.fuseplanes[i])) + self.conv_reduces.append(MapReduce(self.fuseplanes[i])) + elif self.dil is not None: + self.dilations = nn.ModuleList() + for i in range(4): + self.dilations.append(CDCM(self.fuseplanes[i], self.dil)) + self.conv_reduces.append(MapReduce(self.dil)) + else: + for i in range(4): + self.conv_reduces.append(MapReduce(self.fuseplanes[i])) + + self.classifier = nn.Conv2d(4, 1, kernel_size=1) # has bias + nn.init.constant_(self.classifier.weight, 0.25) + nn.init.constant_(self.classifier.bias, 0) + + # print('initialization done') + + def get_weights(self): + conv_weights = [] + bn_weights = [] + relu_weights = [] + for pname, p in self.named_parameters(): + if 'bn' in pname: + bn_weights.append(p) + elif 'relu' in pname: + relu_weights.append(p) + else: + conv_weights.append(p) + + return conv_weights, bn_weights, relu_weights + + def forward(self, x): + H, W = x.size()[2:] + + x = self.init_block(x) + + x1 = self.block1_1(x) + x1 = self.block1_2(x1) + x1 = self.block1_3(x1) + + x2 = self.block2_1(x1) + x2 = self.block2_2(x2) + x2 = self.block2_3(x2) + x2 = self.block2_4(x2) + + x3 = self.block3_1(x2) + x3 = self.block3_2(x3) + x3 = self.block3_3(x3) + x3 = self.block3_4(x3) + + x4 = self.block4_1(x3) + x4 = self.block4_2(x4) + x4 = self.block4_3(x4) + x4 = self.block4_4(x4) + + x_fuses = [] + if self.sa and self.dil is not None: + for i, xi in enumerate([x1, x2, x3, x4]): + x_fuses.append(self.attentions[i](self.dilations[i](xi))) + elif self.sa: + for i, xi in enumerate([x1, x2, x3, x4]): + x_fuses.append(self.attentions[i](xi)) + elif self.dil is not None: + for i, xi in enumerate([x1, x2, x3, x4]): + x_fuses.append(self.dilations[i](xi)) + else: + x_fuses = [x1, x2, x3, x4] + + e1 = self.conv_reduces[0](x_fuses[0]) + e1 = F.interpolate(e1, (H, W), mode="bilinear", align_corners=False) + + e2 = self.conv_reduces[1](x_fuses[1]) + e2 = F.interpolate(e2, (H, W), mode="bilinear", align_corners=False) + + e3 = self.conv_reduces[2](x_fuses[2]) + e3 = F.interpolate(e3, (H, W), mode="bilinear", align_corners=False) + + e4 = self.conv_reduces[3](x_fuses[3]) + e4 = F.interpolate(e4, (H, W), mode="bilinear", align_corners=False) + + outputs = [e1, e2, e3, e4] + + output = self.classifier(torch.cat(outputs, dim=1)) + #if not self.training: + # return torch.sigmoid(output) + + outputs.append(output) + outputs = [torch.sigmoid(r) for r in outputs] + return outputs + +def config_model(model): + model_options = list(nets.keys()) + assert model in model_options, \ + 'unrecognized model, please choose from %s' % str(model_options) + + # print(str(nets[model])) + + pdcs = [] + for i in range(16): + layer_name = 'layer%d' % i + op = nets[model][layer_name] + pdcs.append(createConvFunc(op)) + + return pdcs + +def pidinet(): + pdcs = config_model('carv4') + dil = 24 #if args.dil else None + return PiDiNet(60, pdcs, dil=dil, sa=True) + + +if __name__ == '__main__': + model = pidinet() + ckp = torch.load('table5_pidinet.pth')['state_dict'] + model.load_state_dict({k.replace('module.',''):v for k, v in ckp.items()}) + im = cv2.imread('examples/test_my/cat_v4.png') + im = img2tensor(im).unsqueeze(0)/255. + res = model(im)[-1] + res = res>0.5 + res = res.float() + res = (res[0,0].cpu().data.numpy()*255.).astype(np.uint8) + print(res.shape) + cv2.imwrite('edge.png', res) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/shuffle/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/shuffle/__init__.py new file mode 100644 index 00000000..92bf1182 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/shuffle/__init__.py @@ -0,0 +1,18 @@ +import cv2 +import numpy as np +from annotator.util import make_noise_disk + + +class ContentShuffleDetector: + def __call__(self, img, h=None, w=None, f=None): + H, W, C = img.shape + if h is None: + h = H + if w is None: + w = W + if f is None: + f = 256 + x = make_noise_disk(h, w, 1, f) * float(W - 1) + y = make_noise_disk(h, w, 1, f) * float(H - 1) + flow = np.concatenate([x, y], axis=2).astype(np.float32) + return cv2.remap(img, flow, None, cv2.INTER_LINEAR) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/teed/Fmish.py b/extensions-builtin/sd_forge_controlnet/annotator/teed/Fmish.py new file mode 100644 index 00000000..40c867a2 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/teed/Fmish.py @@ -0,0 +1,17 @@ +""" +Script provides functional interface for Mish activation function. +""" + +# import pytorch +import torch +import torch.nn.functional as F + + +@torch.jit.script +def mish(input): + """ + Applies the mish function element-wise: + mish(x) = x * tanh(softplus(x)) = x * tanh(ln(1 + exp(x))) + See additional documentation for mish class. + """ + return input * torch.tanh(F.softplus(input)) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/teed/Fsmish.py b/extensions-builtin/sd_forge_controlnet/annotator/teed/Fsmish.py new file mode 100644 index 00000000..eb8c55ca --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/teed/Fsmish.py @@ -0,0 +1,20 @@ +""" +Script based on: +Wang, Xueliang, Honge Ren, and Achuan Wang. + "Smish: A Novel Activation Function for Deep Learning Methods. + " Electronics 11.4 (2022): 540. +""" + +# import pytorch +import torch +import torch.nn.functional as F + + +@torch.jit.script +def smish(input): + """ + Applies the mish function element-wise: + mish(x) = x * tanh(softplus(x)) = x * tanh(ln(1 + exp(sigmoid(x)))) + See additional documentation for mish class. + """ + return input * torch.tanh(torch.log(1+torch.sigmoid(input))) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/teed/LICENSE.txt b/extensions-builtin/sd_forge_controlnet/annotator/teed/LICENSE.txt new file mode 100644 index 00000000..4a99ffdd --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/teed/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Xavier Soria Poma + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/extensions-builtin/sd_forge_controlnet/annotator/teed/Xmish.py b/extensions-builtin/sd_forge_controlnet/annotator/teed/Xmish.py new file mode 100644 index 00000000..15e84ed9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/teed/Xmish.py @@ -0,0 +1,43 @@ +""" +Applies the mish function element-wise: +mish(x) = x * tanh(softplus(x)) = x * tanh(ln(1 + exp(x))) +""" + +# import pytorch +import torch +import torch.nn.functional as F +from torch import nn + +# import activation functions +from .Fmish import mish + + +class Mish(nn.Module): + """ + Applies the mish function element-wise: + mish(x) = x * tanh(softplus(x)) = x * tanh(ln(1 + exp(x))) + Shape: + - Input: (N, *) where * means, any number of additional + dimensions + - Output: (N, *), same shape as the input + Examples: + >>> m = Mish() + >>> input = torch.randn(2) + >>> output = m(input) + Reference: https://pytorch.org/docs/stable/generated/torch.nn.Mish.html + """ + + def __init__(self): + """ + Init method. + """ + super().__init__() + + def forward(self, input): + """ + Forward pass of the function. + """ + if torch.__version__ >= "1.9": + return F.mish(input) + else: + return mish(input) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/teed/Xsmish.py b/extensions-builtin/sd_forge_controlnet/annotator/teed/Xsmish.py new file mode 100644 index 00000000..df75bee4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/teed/Xsmish.py @@ -0,0 +1,43 @@ +""" +Script based on: +Wang, Xueliang, Honge Ren, and Achuan Wang. + "Smish: A Novel Activation Function for Deep Learning Methods. + " Electronics 11.4 (2022): 540. +smish(x) = x * tanh(softplus(x)) = x * tanh(ln(1 + sigmoid(x))) +""" + +# import pytorch +import torch +import torch.nn.functional as F +from torch import nn + +# import activation functions +from .Fsmish import smish + + +class Smish(nn.Module): + """ + Applies the mish function element-wise: + mish(x) = x * tanh(softplus(x)) = x * tanh(ln(1 + exp(x))) + Shape: + - Input: (N, *) where * means, any number of additional + dimensions + - Output: (N, *), same shape as the input + Examples: + >>> m = Mish() + >>> input = torch.randn(2) + >>> output = m(input) + Reference: https://pytorch.org/docs/stable/generated/torch.nn.Mish.html + """ + + def __init__(self): + """ + Init method. + """ + super().__init__() + + def forward(self, input): + """ + Forward pass of the function. + """ + return smish(input) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/teed/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/teed/__init__.py new file mode 100644 index 00000000..47517043 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/teed/__init__.py @@ -0,0 +1,55 @@ +""" +Hello, welcome on board, +""" +from __future__ import print_function + +import os +import cv2 +import numpy as np + +import torch + +from annotator.teed.ted import TED # TEED architecture +from einops import rearrange +from modules import devices +from annotator.util import load_model,safe_step +from annotator.annotator_path import models_path + +class TEEDDector: + """https://github.com/xavysp/TEED""" + + model_dir = os.path.join(models_path, "TEED") + + def __init__(self): + self.device = devices.get_device_for("controlnet") + self.model = TED().to(self.device).eval() + remote_url = os.environ.get( + "CONTROLNET_TEED_MODEL_URL", + "https://huggingface.co/bdsqlsz/qinglong_controlnet-lllite/resolve/main/Annotators/7_model.pth", + ) + model_path = load_model( + "7_model.pth", remote_url=remote_url, model_dir=self.model_dir + ) + self.model.load_state_dict(torch.load(model_path)) + + def unload_model(self): + if self.model is not None: + self.model.cpu() + + def __call__(self, image: np.ndarray, safe_steps: int = 2) -> np.ndarray: + + self.model.to(self.device) + + H, W, _ = image.shape + with torch.no_grad(): + image_teed = torch.from_numpy(image.copy()).float().to(self.device) + image_teed = rearrange(image_teed, 'h w c -> 1 c h w') + edges = self.model(image_teed) + edges = [e.detach().cpu().numpy().astype(np.float32)[0, 0] for e in edges] + edges = [cv2.resize(e, (W, H), interpolation=cv2.INTER_LINEAR) for e in edges] + edges = np.stack(edges, axis=2) + edge = 1 / (1 + np.exp(-np.mean(edges, axis=2).astype(np.float64))) + if safe_steps != 0: + edge = safe_step(edge, safe_steps) + edge = (edge * 255.0).clip(0, 255).astype(np.uint8) + return edge \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/teed/ted.py b/extensions-builtin/sd_forge_controlnet/annotator/teed/ted.py new file mode 100644 index 00000000..ff347d5a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/teed/ted.py @@ -0,0 +1,296 @@ +# TEED: is a Tiny but Efficient Edge Detection, it comes from the LDC-B3 +# with a Slightly modification +# LDC parameters: +# 155665 +# TED > 58K + +import torch +import torch.nn as nn +import torch.nn.functional as F + +from .Fsmish import smish as Fsmish +from .Xsmish import Smish + + +def weight_init(m): + if isinstance(m, (nn.Conv2d,)): + torch.nn.init.xavier_normal_(m.weight, gain=1.0) + + if m.bias is not None: + torch.nn.init.zeros_(m.bias) + + # for fusion layer + if isinstance(m, (nn.ConvTranspose2d,)): + torch.nn.init.xavier_normal_(m.weight, gain=1.0) + if m.bias is not None: + torch.nn.init.zeros_(m.bias) + +class CoFusion(nn.Module): + # from LDC + + def __init__(self, in_ch, out_ch): + super(CoFusion, self).__init__() + self.conv1 = nn.Conv2d(in_ch, 32, kernel_size=3, + stride=1, padding=1) # before 64 + self.conv3= nn.Conv2d(32, out_ch, kernel_size=3, + stride=1, padding=1)# before 64 instead of 32 + self.relu = nn.ReLU() + self.norm_layer1 = nn.GroupNorm(4, 32) # before 64 + + def forward(self, x): + # fusecat = torch.cat(x, dim=1) + attn = self.relu(self.norm_layer1(self.conv1(x))) + attn = F.softmax(self.conv3(attn), dim=1) + return ((x * attn).sum(1)).unsqueeze(1) + + +class CoFusion2(nn.Module): + # TEDv14-3 + def __init__(self, in_ch, out_ch): + super(CoFusion2, self).__init__() + self.conv1 = nn.Conv2d(in_ch, 32, kernel_size=3, + stride=1, padding=1) # before 64 + # self.conv2 = nn.Conv2d(32, 32, kernel_size=3, + # stride=1, padding=1)# before 64 + self.conv3 = nn.Conv2d(32, out_ch, kernel_size=3, + stride=1, padding=1)# before 64 instead of 32 + self.smish= Smish()#nn.ReLU(inplace=True) + + + def forward(self, x): + # fusecat = torch.cat(x, dim=1) + attn = self.conv1(self.smish(x)) + attn = self.conv3(self.smish(attn)) # before , )dim=1) + + # return ((fusecat * attn).sum(1)).unsqueeze(1) + return ((x * attn).sum(1)).unsqueeze(1) + +class DoubleFusion(nn.Module): + # TED fusion before the final edge map prediction + def __init__(self, in_ch, out_ch): + super(DoubleFusion, self).__init__() + self.DWconv1 = nn.Conv2d(in_ch, in_ch*8, kernel_size=3, + stride=1, padding=1, groups=in_ch) # before 64 + self.PSconv1 = nn.PixelShuffle(1) + + self.DWconv2 = nn.Conv2d(24, 24*1, kernel_size=3, + stride=1, padding=1,groups=24)# before 64 instead of 32 + + self.AF= Smish()#XAF() #nn.Tanh()# XAF() # # Smish()# + + + def forward(self, x): + # fusecat = torch.cat(x, dim=1) + attn = self.PSconv1(self.DWconv1(self.AF(x))) # #TEED best res TEDv14 [8, 32, 352, 352] + + attn2 = self.PSconv1(self.DWconv2(self.AF(attn))) # #TEED best res TEDv14[8, 3, 352, 352] + + return Fsmish(((attn2 +attn).sum(1)).unsqueeze(1)) #TED best res + +class _DenseLayer(nn.Sequential): + def __init__(self, input_features, out_features): + super(_DenseLayer, self).__init__() + + self.add_module('conv1', nn.Conv2d(input_features, out_features, + kernel_size=3, stride=1, padding=2, bias=True)), + self.add_module('smish1', Smish()), + self.add_module('conv2', nn.Conv2d(out_features, out_features, + kernel_size=3, stride=1, bias=True)) + def forward(self, x): + x1, x2 = x + + new_features = super(_DenseLayer, self).forward(Fsmish(x1)) # F.relu() + + return 0.5 * (new_features + x2), x2 + + +class _DenseBlock(nn.Sequential): + def __init__(self, num_layers, input_features, out_features): + super(_DenseBlock, self).__init__() + for i in range(num_layers): + layer = _DenseLayer(input_features, out_features) + self.add_module('denselayer%d' % (i + 1), layer) + input_features = out_features + + +class UpConvBlock(nn.Module): + def __init__(self, in_features, up_scale): + super(UpConvBlock, self).__init__() + self.up_factor = 2 + self.constant_features = 16 + + layers = self.make_deconv_layers(in_features, up_scale) + assert layers is not None, layers + self.features = nn.Sequential(*layers) + + def make_deconv_layers(self, in_features, up_scale): + layers = [] + all_pads=[0,0,1,3,7] + for i in range(up_scale): + kernel_size = 2 ** up_scale + pad = all_pads[up_scale] # kernel_size-1 + out_features = self.compute_out_features(i, up_scale) + layers.append(nn.Conv2d(in_features, out_features, 1)) + layers.append(Smish()) + layers.append(nn.ConvTranspose2d( + out_features, out_features, kernel_size, stride=2, padding=pad)) + in_features = out_features + return layers + + def compute_out_features(self, idx, up_scale): + return 1 if idx == up_scale - 1 else self.constant_features + + def forward(self, x): + return self.features(x) + + +class SingleConvBlock(nn.Module): + def __init__(self, in_features, out_features, stride, use_ac=False): + super(SingleConvBlock, self).__init__() + # self.use_bn = use_bs + self.use_ac=use_ac + self.conv = nn.Conv2d(in_features, out_features, 1, stride=stride, + bias=True) + if self.use_ac: + self.smish = Smish() + + def forward(self, x): + x = self.conv(x) + if self.use_ac: + return self.smish(x) + else: + return x + +class DoubleConvBlock(nn.Module): + def __init__(self, in_features, mid_features, + out_features=None, + stride=1, + use_act=True): + super(DoubleConvBlock, self).__init__() + + self.use_act = use_act + if out_features is None: + out_features = mid_features + self.conv1 = nn.Conv2d(in_features, mid_features, + 3, padding=1, stride=stride) + self.conv2 = nn.Conv2d(mid_features, out_features, 3, padding=1) + self.smish= Smish()#nn.ReLU(inplace=True) + + def forward(self, x): + x = self.conv1(x) + x = self.smish(x) + x = self.conv2(x) + if self.use_act: + x = self.smish(x) + return x + + +class TED(nn.Module): + """ Definition of Tiny and Efficient Edge Detector + model + """ + + def __init__(self): + super(TED, self).__init__() + self.block_1 = DoubleConvBlock(3, 16, 16, stride=2,) + self.block_2 = DoubleConvBlock(16, 32, use_act=False) + self.dblock_3 = _DenseBlock(1, 32, 48) # [32,48,100,100] before (2, 32, 64) + + self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) + + # skip1 connection, see fig. 2 + self.side_1 = SingleConvBlock(16, 32, 2) + + # skip2 connection, see fig. 2 + self.pre_dense_3 = SingleConvBlock(32, 48, 1) # before (32, 64, 1) + + # USNet + self.up_block_1 = UpConvBlock(16, 1) + self.up_block_2 = UpConvBlock(32, 1) + self.up_block_3 = UpConvBlock(48, 2) # (32, 64, 1) + + self.block_cat = DoubleFusion(3,3) # TEED: DoubleFusion + + self.apply(weight_init) + + def slice(self, tensor, slice_shape): + t_shape = tensor.shape + img_h, img_w = slice_shape + if img_w!=t_shape[-1] or img_h!=t_shape[2]: + new_tensor = F.interpolate( + tensor, size=(img_h, img_w), mode='bicubic',align_corners=False) + + else: + new_tensor=tensor + # tensor[..., :height, :width] + return new_tensor + def resize_input(self,tensor): + t_shape = tensor.shape + if t_shape[2] % 8 != 0 or t_shape[3] % 8 != 0: + img_w= ((t_shape[3]// 8) + 1) * 8 + img_h = ((t_shape[2] // 8) + 1) * 8 + new_tensor = F.interpolate( + tensor, size=(img_h, img_w), mode='bicubic', align_corners=False) + else: + new_tensor = tensor + return new_tensor + + def crop_bdcn(data1, h, w, crop_h, crop_w): + # Based on BDCN Implementation @ https://github.com/pkuCactus/BDCN + _, _, h1, w1 = data1.size() + assert (h <= h1 and w <= w1) + data = data1[:, :, crop_h:crop_h + h, crop_w:crop_w + w] + return data + + + def forward(self, x, single_test=False): + assert x.ndim == 4, x.shape + # supose the image size is 352x352 + + # Block 1 + block_1 = self.block_1(x) # [8,16,176,176] + block_1_side = self.side_1(block_1) # 16 [8,32,88,88] + + # Block 2 + block_2 = self.block_2(block_1) # 32 # [8,32,176,176] + block_2_down = self.maxpool(block_2) # [8,32,88,88] + block_2_add = block_2_down + block_1_side # [8,32,88,88] + + # Block 3 + block_3_pre_dense = self.pre_dense_3(block_2_down) # [8,64,88,88] block 3 L connection + block_3, _ = self.dblock_3([block_2_add, block_3_pre_dense]) # [8,64,88,88] + + # upsampling blocks + out_1 = self.up_block_1(block_1) + out_2 = self.up_block_2(block_2) + out_3 = self.up_block_3(block_3) + + results = [out_1, out_2, out_3] + + # concatenate multiscale outputs + block_cat = torch.cat(results, dim=1) # Bx6xHxW + block_cat = self.block_cat(block_cat) # Bx1xHxW DoubleFusion + + results.append(block_cat) + return results + + +if __name__ == '__main__': + batch_size = 8 + img_height = 352 + img_width = 352 + + # device = "cuda" if torch.cuda.is_available() else "cpu" + device = "cpu" + input = torch.rand(batch_size, 3, img_height, img_width).to(device) + # target = torch.rand(batch_size, 1, img_height, img_width).to(device) + print(f"input shape: {input.shape}") + model = TED().to(device) + output = model(input) + print(f"output shapes: {[t.shape for t in output]}") + + # for i in range(20000): + # print(i) + # output = model(input) + # loss = nn.MSELoss()(output[-1], target) + # loss.backward() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/LICENSE b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/LICENSE new file mode 100644 index 00000000..c38dc639 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/LICENSE @@ -0,0 +1,203 @@ +Copyright 2022 SenseTime X-Lab. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2022 SenseTime X-Lab. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/__init__.py new file mode 100644 index 00000000..ad862ed7 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/__init__.py @@ -0,0 +1,56 @@ +import os +from annotator.annotator_path import models_path +from modules import devices +from annotator.uniformer.inference import init_segmentor, inference_segmentor, show_result_pyplot + +try: + from mmseg.core.evaluation import get_palette +except ImportError: + from annotator.mmpkg.mmseg.core.evaluation import get_palette + +modeldir = os.path.join(models_path, "uniformer") +checkpoint_file = "https://huggingface.co/lllyasviel/ControlNet/resolve/main/annotator/ckpts/upernet_global_small.pth" +config_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "upernet_global_small.py") +old_modeldir = os.path.dirname(os.path.realpath(__file__)) +model = None + +def unload_uniformer_model(): + global model + if model is not None: + model = model.cpu() + +def apply_uniformer(img): + global model + if model is None: + modelpath = os.path.join(modeldir, "upernet_global_small.pth") + old_modelpath = os.path.join(old_modeldir, "upernet_global_small.pth") + if os.path.exists(old_modelpath): + modelpath = old_modelpath + elif not os.path.exists(modelpath): + from basicsr.utils.download_util import load_file_from_url + load_file_from_url(checkpoint_file, model_dir=modeldir) + + model = init_segmentor(config_file, modelpath, device=devices.get_device_for("controlnet")) + model = model.to(devices.get_device_for("controlnet")) + + if devices.get_device_for("controlnet").type == 'mps': + # adaptive_avg_pool2d can fail on MPS, workaround with CPU + import torch.nn.functional + + orig_adaptive_avg_pool2d = torch.nn.functional.adaptive_avg_pool2d + def cpu_if_exception(input, *args, **kwargs): + try: + return orig_adaptive_avg_pool2d(input, *args, **kwargs) + except: + return orig_adaptive_avg_pool2d(input.cpu(), *args, **kwargs).to(input.device) + + try: + torch.nn.functional.adaptive_avg_pool2d = cpu_if_exception + result = inference_segmentor(model, img) + finally: + torch.nn.functional.adaptive_avg_pool2d = orig_adaptive_avg_pool2d + else: + result = inference_segmentor(model, img) + + res_img = show_result_pyplot(model, img, result, get_palette('ade'), opacity=1) + return res_img diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/ade20k.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/ade20k.py new file mode 100644 index 00000000..efc8b4bb --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/ade20k.py @@ -0,0 +1,54 @@ +# dataset settings +dataset_type = 'ADE20KDataset' +data_root = 'data/ade/ADEChallengeData2016' +img_norm_cfg = dict( + mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) +crop_size = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations', reduce_zero_label=True), + dict(type='Resize', img_scale=(2048, 512), ratio_range=(0.5, 2.0)), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='Normalize', **img_norm_cfg), + dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255), + dict(type='DefaultFormatBundle'), + dict(type='Collect', keys=['img', 'gt_semantic_seg']), +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict( + type='MultiScaleFlipAug', + img_scale=(2048, 512), + # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75], + flip=False, + transforms=[ + dict(type='Resize', keep_ratio=True), + dict(type='RandomFlip'), + dict(type='Normalize', **img_norm_cfg), + dict(type='ImageToTensor', keys=['img']), + dict(type='Collect', keys=['img']), + ]) +] +data = dict( + samples_per_gpu=4, + workers_per_gpu=4, + train=dict( + type=dataset_type, + data_root=data_root, + img_dir='images/training', + ann_dir='annotations/training', + pipeline=train_pipeline), + val=dict( + type=dataset_type, + data_root=data_root, + img_dir='images/validation', + ann_dir='annotations/validation', + pipeline=test_pipeline), + test=dict( + type=dataset_type, + data_root=data_root, + img_dir='images/validation', + ann_dir='annotations/validation', + pipeline=test_pipeline)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/chase_db1.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/chase_db1.py new file mode 100644 index 00000000..298594ea --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/chase_db1.py @@ -0,0 +1,59 @@ +# dataset settings +dataset_type = 'ChaseDB1Dataset' +data_root = 'data/CHASE_DB1' +img_norm_cfg = dict( + mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) +img_scale = (960, 999) +crop_size = (128, 128) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', img_scale=img_scale, ratio_range=(0.5, 2.0)), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='Normalize', **img_norm_cfg), + dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255), + dict(type='DefaultFormatBundle'), + dict(type='Collect', keys=['img', 'gt_semantic_seg']) +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict( + type='MultiScaleFlipAug', + img_scale=img_scale, + # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0], + flip=False, + transforms=[ + dict(type='Resize', keep_ratio=True), + dict(type='RandomFlip'), + dict(type='Normalize', **img_norm_cfg), + dict(type='ImageToTensor', keys=['img']), + dict(type='Collect', keys=['img']) + ]) +] + +data = dict( + samples_per_gpu=4, + workers_per_gpu=4, + train=dict( + type='RepeatDataset', + times=40000, + dataset=dict( + type=dataset_type, + data_root=data_root, + img_dir='images/training', + ann_dir='annotations/training', + pipeline=train_pipeline)), + val=dict( + type=dataset_type, + data_root=data_root, + img_dir='images/validation', + ann_dir='annotations/validation', + pipeline=test_pipeline), + test=dict( + type=dataset_type, + data_root=data_root, + img_dir='images/validation', + ann_dir='annotations/validation', + pipeline=test_pipeline)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/cityscapes.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/cityscapes.py new file mode 100644 index 00000000..f21867c6 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/cityscapes.py @@ -0,0 +1,54 @@ +# dataset settings +dataset_type = 'CityscapesDataset' +data_root = 'data/cityscapes/' +img_norm_cfg = dict( + mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) +crop_size = (512, 1024) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', img_scale=(2048, 1024), ratio_range=(0.5, 2.0)), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='Normalize', **img_norm_cfg), + dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255), + dict(type='DefaultFormatBundle'), + dict(type='Collect', keys=['img', 'gt_semantic_seg']), +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict( + type='MultiScaleFlipAug', + img_scale=(2048, 1024), + # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75], + flip=False, + transforms=[ + dict(type='Resize', keep_ratio=True), + dict(type='RandomFlip'), + dict(type='Normalize', **img_norm_cfg), + dict(type='ImageToTensor', keys=['img']), + dict(type='Collect', keys=['img']), + ]) +] +data = dict( + samples_per_gpu=2, + workers_per_gpu=2, + train=dict( + type=dataset_type, + data_root=data_root, + img_dir='leftImg8bit/train', + ann_dir='gtFine/train', + pipeline=train_pipeline), + val=dict( + type=dataset_type, + data_root=data_root, + img_dir='leftImg8bit/val', + ann_dir='gtFine/val', + pipeline=test_pipeline), + test=dict( + type=dataset_type, + data_root=data_root, + img_dir='leftImg8bit/val', + ann_dir='gtFine/val', + pipeline=test_pipeline)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/cityscapes_769x769.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/cityscapes_769x769.py new file mode 100644 index 00000000..336c7b25 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/cityscapes_769x769.py @@ -0,0 +1,35 @@ +_base_ = './cityscapes.py' +img_norm_cfg = dict( + mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) +crop_size = (769, 769) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', img_scale=(2049, 1025), ratio_range=(0.5, 2.0)), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='Normalize', **img_norm_cfg), + dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255), + dict(type='DefaultFormatBundle'), + dict(type='Collect', keys=['img', 'gt_semantic_seg']), +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict( + type='MultiScaleFlipAug', + img_scale=(2049, 1025), + # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75], + flip=False, + transforms=[ + dict(type='Resize', keep_ratio=True), + dict(type='RandomFlip'), + dict(type='Normalize', **img_norm_cfg), + dict(type='ImageToTensor', keys=['img']), + dict(type='Collect', keys=['img']), + ]) +] +data = dict( + train=dict(pipeline=train_pipeline), + val=dict(pipeline=test_pipeline), + test=dict(pipeline=test_pipeline)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/drive.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/drive.py new file mode 100644 index 00000000..06e8ff60 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/drive.py @@ -0,0 +1,59 @@ +# dataset settings +dataset_type = 'DRIVEDataset' +data_root = 'data/DRIVE' +img_norm_cfg = dict( + mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) +img_scale = (584, 565) +crop_size = (64, 64) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', img_scale=img_scale, ratio_range=(0.5, 2.0)), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='Normalize', **img_norm_cfg), + dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255), + dict(type='DefaultFormatBundle'), + dict(type='Collect', keys=['img', 'gt_semantic_seg']) +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict( + type='MultiScaleFlipAug', + img_scale=img_scale, + # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0], + flip=False, + transforms=[ + dict(type='Resize', keep_ratio=True), + dict(type='RandomFlip'), + dict(type='Normalize', **img_norm_cfg), + dict(type='ImageToTensor', keys=['img']), + dict(type='Collect', keys=['img']) + ]) +] + +data = dict( + samples_per_gpu=4, + workers_per_gpu=4, + train=dict( + type='RepeatDataset', + times=40000, + dataset=dict( + type=dataset_type, + data_root=data_root, + img_dir='images/training', + ann_dir='annotations/training', + pipeline=train_pipeline)), + val=dict( + type=dataset_type, + data_root=data_root, + img_dir='images/validation', + ann_dir='annotations/validation', + pipeline=test_pipeline), + test=dict( + type=dataset_type, + data_root=data_root, + img_dir='images/validation', + ann_dir='annotations/validation', + pipeline=test_pipeline)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/hrf.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/hrf.py new file mode 100644 index 00000000..242d790e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/hrf.py @@ -0,0 +1,59 @@ +# dataset settings +dataset_type = 'HRFDataset' +data_root = 'data/HRF' +img_norm_cfg = dict( + mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) +img_scale = (2336, 3504) +crop_size = (256, 256) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', img_scale=img_scale, ratio_range=(0.5, 2.0)), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='Normalize', **img_norm_cfg), + dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255), + dict(type='DefaultFormatBundle'), + dict(type='Collect', keys=['img', 'gt_semantic_seg']) +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict( + type='MultiScaleFlipAug', + img_scale=img_scale, + # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0], + flip=False, + transforms=[ + dict(type='Resize', keep_ratio=True), + dict(type='RandomFlip'), + dict(type='Normalize', **img_norm_cfg), + dict(type='ImageToTensor', keys=['img']), + dict(type='Collect', keys=['img']) + ]) +] + +data = dict( + samples_per_gpu=4, + workers_per_gpu=4, + train=dict( + type='RepeatDataset', + times=40000, + dataset=dict( + type=dataset_type, + data_root=data_root, + img_dir='images/training', + ann_dir='annotations/training', + pipeline=train_pipeline)), + val=dict( + type=dataset_type, + data_root=data_root, + img_dir='images/validation', + ann_dir='annotations/validation', + pipeline=test_pipeline), + test=dict( + type=dataset_type, + data_root=data_root, + img_dir='images/validation', + ann_dir='annotations/validation', + pipeline=test_pipeline)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/pascal_context.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/pascal_context.py new file mode 100644 index 00000000..ff65bad1 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/pascal_context.py @@ -0,0 +1,60 @@ +# dataset settings +dataset_type = 'PascalContextDataset' +data_root = 'data/VOCdevkit/VOC2010/' +img_norm_cfg = dict( + mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) + +img_scale = (520, 520) +crop_size = (480, 480) + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', img_scale=img_scale, ratio_range=(0.5, 2.0)), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='Normalize', **img_norm_cfg), + dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255), + dict(type='DefaultFormatBundle'), + dict(type='Collect', keys=['img', 'gt_semantic_seg']), +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict( + type='MultiScaleFlipAug', + img_scale=img_scale, + # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75], + flip=False, + transforms=[ + dict(type='Resize', keep_ratio=True), + dict(type='RandomFlip'), + dict(type='Normalize', **img_norm_cfg), + dict(type='ImageToTensor', keys=['img']), + dict(type='Collect', keys=['img']), + ]) +] +data = dict( + samples_per_gpu=4, + workers_per_gpu=4, + train=dict( + type=dataset_type, + data_root=data_root, + img_dir='JPEGImages', + ann_dir='SegmentationClassContext', + split='ImageSets/SegmentationContext/train.txt', + pipeline=train_pipeline), + val=dict( + type=dataset_type, + data_root=data_root, + img_dir='JPEGImages', + ann_dir='SegmentationClassContext', + split='ImageSets/SegmentationContext/val.txt', + pipeline=test_pipeline), + test=dict( + type=dataset_type, + data_root=data_root, + img_dir='JPEGImages', + ann_dir='SegmentationClassContext', + split='ImageSets/SegmentationContext/val.txt', + pipeline=test_pipeline)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/pascal_context_59.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/pascal_context_59.py new file mode 100644 index 00000000..37585aba --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/pascal_context_59.py @@ -0,0 +1,60 @@ +# dataset settings +dataset_type = 'PascalContextDataset59' +data_root = 'data/VOCdevkit/VOC2010/' +img_norm_cfg = dict( + mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) + +img_scale = (520, 520) +crop_size = (480, 480) + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations', reduce_zero_label=True), + dict(type='Resize', img_scale=img_scale, ratio_range=(0.5, 2.0)), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='Normalize', **img_norm_cfg), + dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255), + dict(type='DefaultFormatBundle'), + dict(type='Collect', keys=['img', 'gt_semantic_seg']), +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict( + type='MultiScaleFlipAug', + img_scale=img_scale, + # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75], + flip=False, + transforms=[ + dict(type='Resize', keep_ratio=True), + dict(type='RandomFlip'), + dict(type='Normalize', **img_norm_cfg), + dict(type='ImageToTensor', keys=['img']), + dict(type='Collect', keys=['img']), + ]) +] +data = dict( + samples_per_gpu=4, + workers_per_gpu=4, + train=dict( + type=dataset_type, + data_root=data_root, + img_dir='JPEGImages', + ann_dir='SegmentationClassContext', + split='ImageSets/SegmentationContext/train.txt', + pipeline=train_pipeline), + val=dict( + type=dataset_type, + data_root=data_root, + img_dir='JPEGImages', + ann_dir='SegmentationClassContext', + split='ImageSets/SegmentationContext/val.txt', + pipeline=test_pipeline), + test=dict( + type=dataset_type, + data_root=data_root, + img_dir='JPEGImages', + ann_dir='SegmentationClassContext', + split='ImageSets/SegmentationContext/val.txt', + pipeline=test_pipeline)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/pascal_voc12.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/pascal_voc12.py new file mode 100644 index 00000000..ba1d42d0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/pascal_voc12.py @@ -0,0 +1,57 @@ +# dataset settings +dataset_type = 'PascalVOCDataset' +data_root = 'data/VOCdevkit/VOC2012' +img_norm_cfg = dict( + mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) +crop_size = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', img_scale=(2048, 512), ratio_range=(0.5, 2.0)), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='Normalize', **img_norm_cfg), + dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255), + dict(type='DefaultFormatBundle'), + dict(type='Collect', keys=['img', 'gt_semantic_seg']), +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict( + type='MultiScaleFlipAug', + img_scale=(2048, 512), + # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75], + flip=False, + transforms=[ + dict(type='Resize', keep_ratio=True), + dict(type='RandomFlip'), + dict(type='Normalize', **img_norm_cfg), + dict(type='ImageToTensor', keys=['img']), + dict(type='Collect', keys=['img']), + ]) +] +data = dict( + samples_per_gpu=4, + workers_per_gpu=4, + train=dict( + type=dataset_type, + data_root=data_root, + img_dir='JPEGImages', + ann_dir='SegmentationClass', + split='ImageSets/Segmentation/train.txt', + pipeline=train_pipeline), + val=dict( + type=dataset_type, + data_root=data_root, + img_dir='JPEGImages', + ann_dir='SegmentationClass', + split='ImageSets/Segmentation/val.txt', + pipeline=test_pipeline), + test=dict( + type=dataset_type, + data_root=data_root, + img_dir='JPEGImages', + ann_dir='SegmentationClass', + split='ImageSets/Segmentation/val.txt', + pipeline=test_pipeline)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/pascal_voc12_aug.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/pascal_voc12_aug.py new file mode 100644 index 00000000..3f23b671 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/pascal_voc12_aug.py @@ -0,0 +1,9 @@ +_base_ = './pascal_voc12.py' +# dataset settings +data = dict( + train=dict( + ann_dir=['SegmentationClass', 'SegmentationClassAug'], + split=[ + 'ImageSets/Segmentation/train.txt', + 'ImageSets/Segmentation/aug.txt' + ])) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/stare.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/stare.py new file mode 100644 index 00000000..3f71b254 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/datasets/stare.py @@ -0,0 +1,59 @@ +# dataset settings +dataset_type = 'STAREDataset' +data_root = 'data/STARE' +img_norm_cfg = dict( + mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) +img_scale = (605, 700) +crop_size = (128, 128) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', img_scale=img_scale, ratio_range=(0.5, 2.0)), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='Normalize', **img_norm_cfg), + dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255), + dict(type='DefaultFormatBundle'), + dict(type='Collect', keys=['img', 'gt_semantic_seg']) +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict( + type='MultiScaleFlipAug', + img_scale=img_scale, + # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0], + flip=False, + transforms=[ + dict(type='Resize', keep_ratio=True), + dict(type='RandomFlip'), + dict(type='Normalize', **img_norm_cfg), + dict(type='ImageToTensor', keys=['img']), + dict(type='Collect', keys=['img']) + ]) +] + +data = dict( + samples_per_gpu=4, + workers_per_gpu=4, + train=dict( + type='RepeatDataset', + times=40000, + dataset=dict( + type=dataset_type, + data_root=data_root, + img_dir='images/training', + ann_dir='annotations/training', + pipeline=train_pipeline)), + val=dict( + type=dataset_type, + data_root=data_root, + img_dir='images/validation', + ann_dir='annotations/validation', + pipeline=test_pipeline), + test=dict( + type=dataset_type, + data_root=data_root, + img_dir='images/validation', + ann_dir='annotations/validation', + pipeline=test_pipeline)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/default_runtime.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/default_runtime.py new file mode 100644 index 00000000..b564cc4e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/default_runtime.py @@ -0,0 +1,14 @@ +# yapf:disable +log_config = dict( + interval=50, + hooks=[ + dict(type='TextLoggerHook', by_epoch=False), + # dict(type='TensorboardLoggerHook') + ]) +# yapf:enable +dist_params = dict(backend='nccl') +log_level = 'INFO' +load_from = None +resume_from = None +workflow = [('train', 1)] +cudnn_benchmark = True diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/ann_r50-d8.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/ann_r50-d8.py new file mode 100644 index 00000000..a2cb6538 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/ann_r50-d8.py @@ -0,0 +1,46 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 2, 4), + strides=(1, 2, 1, 1), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + decode_head=dict( + type='ANNHead', + in_channels=[1024, 2048], + in_index=[2, 3], + channels=512, + project_channels=256, + query_scales=(1, ), + key_pool_scales=(1, 3, 6, 8), + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=1024, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/apcnet_r50-d8.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/apcnet_r50-d8.py new file mode 100644 index 00000000..c8f5316c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/apcnet_r50-d8.py @@ -0,0 +1,44 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 2, 4), + strides=(1, 2, 1, 1), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + decode_head=dict( + type='APCHead', + in_channels=2048, + in_index=3, + channels=512, + pool_scales=(1, 2, 3, 6), + dropout_ratio=0.1, + num_classes=19, + norm_cfg=dict(type='SyncBN', requires_grad=True), + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=1024, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/ccnet_r50-d8.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/ccnet_r50-d8.py new file mode 100644 index 00000000..794148f5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/ccnet_r50-d8.py @@ -0,0 +1,44 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 2, 4), + strides=(1, 2, 1, 1), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + decode_head=dict( + type='CCHead', + in_channels=2048, + in_index=3, + channels=512, + recurrence=2, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=1024, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/cgnet.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/cgnet.py new file mode 100644 index 00000000..eff8d945 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/cgnet.py @@ -0,0 +1,35 @@ +# model settings +norm_cfg = dict(type='SyncBN', eps=1e-03, requires_grad=True) +model = dict( + type='EncoderDecoder', + backbone=dict( + type='CGNet', + norm_cfg=norm_cfg, + in_channels=3, + num_channels=(32, 64, 128), + num_blocks=(3, 21), + dilations=(2, 4), + reductions=(8, 16)), + decode_head=dict( + type='FCNHead', + in_channels=256, + in_index=2, + channels=256, + num_convs=0, + concat_input=False, + dropout_ratio=0, + num_classes=19, + norm_cfg=norm_cfg, + loss_decode=dict( + type='CrossEntropyLoss', + use_sigmoid=False, + loss_weight=1.0, + class_weight=[ + 2.5959933, 6.7415504, 3.5354059, 9.8663225, 9.690899, 9.369352, + 10.289121, 9.953208, 4.3097677, 9.490387, 7.674431, 9.396905, + 10.347791, 6.3927646, 10.226669, 10.241062, 10.280587, + 10.396974, 10.055647 + ])), + # model training and testing settings + train_cfg=dict(sampler=None), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/danet_r50-d8.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/danet_r50-d8.py new file mode 100644 index 00000000..2c934939 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/danet_r50-d8.py @@ -0,0 +1,44 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 2, 4), + strides=(1, 2, 1, 1), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + decode_head=dict( + type='DAHead', + in_channels=2048, + in_index=3, + channels=512, + pam_channels=64, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=1024, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/deeplabv3_r50-d8.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/deeplabv3_r50-d8.py new file mode 100644 index 00000000..d7a43bee --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/deeplabv3_r50-d8.py @@ -0,0 +1,44 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 2, 4), + strides=(1, 2, 1, 1), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + decode_head=dict( + type='ASPPHead', + in_channels=2048, + in_index=3, + channels=512, + dilations=(1, 12, 24, 36), + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=1024, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/deeplabv3_unet_s5-d16.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/deeplabv3_unet_s5-d16.py new file mode 100644 index 00000000..0cd26299 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/deeplabv3_unet_s5-d16.py @@ -0,0 +1,50 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained=None, + backbone=dict( + type='UNet', + in_channels=3, + base_channels=64, + num_stages=5, + strides=(1, 1, 1, 1, 1), + enc_num_convs=(2, 2, 2, 2, 2), + dec_num_convs=(2, 2, 2, 2), + downsamples=(True, True, True, True), + enc_dilations=(1, 1, 1, 1, 1), + dec_dilations=(1, 1, 1, 1), + with_cp=False, + conv_cfg=None, + norm_cfg=norm_cfg, + act_cfg=dict(type='ReLU'), + upsample_cfg=dict(type='InterpConv'), + norm_eval=False), + decode_head=dict( + type='ASPPHead', + in_channels=64, + in_index=4, + channels=16, + dilations=(1, 12, 24, 36), + dropout_ratio=0.1, + num_classes=2, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=128, + in_index=3, + channels=64, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=2, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='slide', crop_size=256, stride=170)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/deeplabv3plus_r50-d8.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/deeplabv3plus_r50-d8.py new file mode 100644 index 00000000..050e39e0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/deeplabv3plus_r50-d8.py @@ -0,0 +1,46 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 2, 4), + strides=(1, 2, 1, 1), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + decode_head=dict( + type='DepthwiseSeparableASPPHead', + in_channels=2048, + in_index=3, + channels=512, + dilations=(1, 12, 24, 36), + c1_in_channels=256, + c1_channels=48, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=1024, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/dmnet_r50-d8.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/dmnet_r50-d8.py new file mode 100644 index 00000000..d22ba526 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/dmnet_r50-d8.py @@ -0,0 +1,44 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 2, 4), + strides=(1, 2, 1, 1), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + decode_head=dict( + type='DMHead', + in_channels=2048, + in_index=3, + channels=512, + filter_sizes=(1, 3, 5, 7), + dropout_ratio=0.1, + num_classes=19, + norm_cfg=dict(type='SyncBN', requires_grad=True), + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=1024, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/dnl_r50-d8.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/dnl_r50-d8.py new file mode 100644 index 00000000..edb4c174 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/dnl_r50-d8.py @@ -0,0 +1,46 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 2, 4), + strides=(1, 2, 1, 1), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + decode_head=dict( + type='DNLHead', + in_channels=2048, + in_index=3, + channels=512, + dropout_ratio=0.1, + reduction=2, + use_scale=True, + mode='embedded_gaussian', + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=1024, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/emanet_r50-d8.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/emanet_r50-d8.py new file mode 100644 index 00000000..26adcd43 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/emanet_r50-d8.py @@ -0,0 +1,47 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 2, 4), + strides=(1, 2, 1, 1), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + decode_head=dict( + type='EMAHead', + in_channels=2048, + in_index=3, + channels=256, + ema_channels=512, + num_bases=64, + num_stages=3, + momentum=0.1, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=1024, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/encnet_r50-d8.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/encnet_r50-d8.py new file mode 100644 index 00000000..be777123 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/encnet_r50-d8.py @@ -0,0 +1,48 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 2, 4), + strides=(1, 2, 1, 1), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + decode_head=dict( + type='EncHead', + in_channels=[512, 1024, 2048], + in_index=(1, 2, 3), + channels=512, + num_codes=32, + use_se_loss=True, + add_lateral=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0), + loss_se_decode=dict( + type='CrossEntropyLoss', use_sigmoid=True, loss_weight=0.2)), + auxiliary_head=dict( + type='FCNHead', + in_channels=1024, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fast_scnn.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fast_scnn.py new file mode 100644 index 00000000..32fdeb65 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fast_scnn.py @@ -0,0 +1,57 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True, momentum=0.01) +model = dict( + type='EncoderDecoder', + backbone=dict( + type='FastSCNN', + downsample_dw_channels=(32, 48), + global_in_channels=64, + global_block_channels=(64, 96, 128), + global_block_strides=(2, 2, 1), + global_out_channels=128, + higher_in_channels=64, + lower_in_channels=128, + fusion_out_channels=128, + out_indices=(0, 1, 2), + norm_cfg=norm_cfg, + align_corners=False), + decode_head=dict( + type='DepthwiseSeparableFCNHead', + in_channels=128, + channels=128, + concat_input=False, + num_classes=19, + in_index=-1, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=True, loss_weight=0.4)), + auxiliary_head=[ + dict( + type='FCNHead', + in_channels=128, + channels=32, + num_convs=1, + num_classes=19, + in_index=-2, + norm_cfg=norm_cfg, + concat_input=False, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=True, loss_weight=0.4)), + dict( + type='FCNHead', + in_channels=64, + channels=32, + num_convs=1, + num_classes=19, + in_index=-3, + norm_cfg=norm_cfg, + concat_input=False, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=True, loss_weight=0.4)), + ], + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fcn_hr18.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fcn_hr18.py new file mode 100644 index 00000000..c3e299bc --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fcn_hr18.py @@ -0,0 +1,52 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://msra/hrnetv2_w18', + backbone=dict( + type='HRNet', + norm_cfg=norm_cfg, + norm_eval=False, + extra=dict( + stage1=dict( + num_modules=1, + num_branches=1, + block='BOTTLENECK', + num_blocks=(4, ), + num_channels=(64, )), + stage2=dict( + num_modules=1, + num_branches=2, + block='BASIC', + num_blocks=(4, 4), + num_channels=(18, 36)), + stage3=dict( + num_modules=4, + num_branches=3, + block='BASIC', + num_blocks=(4, 4, 4), + num_channels=(18, 36, 72)), + stage4=dict( + num_modules=3, + num_branches=4, + block='BASIC', + num_blocks=(4, 4, 4, 4), + num_channels=(18, 36, 72, 144)))), + decode_head=dict( + type='FCNHead', + in_channels=[18, 36, 72, 144], + in_index=(0, 1, 2, 3), + channels=sum([18, 36, 72, 144]), + input_transform='resize_concat', + kernel_size=1, + num_convs=1, + concat_input=False, + dropout_ratio=-1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fcn_r50-d8.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fcn_r50-d8.py new file mode 100644 index 00000000..5e98f6cc --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fcn_r50-d8.py @@ -0,0 +1,45 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 2, 4), + strides=(1, 2, 1, 1), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + decode_head=dict( + type='FCNHead', + in_channels=2048, + in_index=3, + channels=512, + num_convs=2, + concat_input=True, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=1024, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fcn_unet_s5-d16.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fcn_unet_s5-d16.py new file mode 100644 index 00000000..a33e7972 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fcn_unet_s5-d16.py @@ -0,0 +1,51 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained=None, + backbone=dict( + type='UNet', + in_channels=3, + base_channels=64, + num_stages=5, + strides=(1, 1, 1, 1, 1), + enc_num_convs=(2, 2, 2, 2, 2), + dec_num_convs=(2, 2, 2, 2), + downsamples=(True, True, True, True), + enc_dilations=(1, 1, 1, 1, 1), + dec_dilations=(1, 1, 1, 1), + with_cp=False, + conv_cfg=None, + norm_cfg=norm_cfg, + act_cfg=dict(type='ReLU'), + upsample_cfg=dict(type='InterpConv'), + norm_eval=False), + decode_head=dict( + type='FCNHead', + in_channels=64, + in_index=4, + channels=64, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=2, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=128, + in_index=3, + channels=64, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=2, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='slide', crop_size=256, stride=170)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fpn_r50.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fpn_r50.py new file mode 100644 index 00000000..86ab327d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fpn_r50.py @@ -0,0 +1,36 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 1, 1), + strides=(1, 2, 2, 2), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + neck=dict( + type='FPN', + in_channels=[256, 512, 1024, 2048], + out_channels=256, + num_outs=4), + decode_head=dict( + type='FPNHead', + in_channels=[256, 256, 256, 256], + in_index=[0, 1, 2, 3], + feature_strides=[4, 8, 16, 32], + channels=128, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fpn_uniformer.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fpn_uniformer.py new file mode 100644 index 00000000..8aae98c5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/fpn_uniformer.py @@ -0,0 +1,35 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + backbone=dict( + type='UniFormer', + embed_dim=[64, 128, 320, 512], + layers=[3, 4, 8, 3], + head_dim=64, + mlp_ratio=4., + qkv_bias=True, + drop_rate=0., + attn_drop_rate=0., + drop_path_rate=0.1), + neck=dict( + type='FPN', + in_channels=[64, 128, 320, 512], + out_channels=256, + num_outs=4), + decode_head=dict( + type='FPNHead', + in_channels=[256, 256, 256, 256], + in_index=[0, 1, 2, 3], + feature_strides=[4, 8, 16, 32], + channels=128, + dropout_ratio=0.1, + num_classes=150, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole') +) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/gcnet_r50-d8.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/gcnet_r50-d8.py new file mode 100644 index 00000000..3d2ad69f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/gcnet_r50-d8.py @@ -0,0 +1,46 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 2, 4), + strides=(1, 2, 1, 1), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + decode_head=dict( + type='GCHead', + in_channels=2048, + in_index=3, + channels=512, + ratio=1 / 4., + pooling_type='att', + fusion_types=('channel_add', ), + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=1024, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/lraspp_m-v3-d8.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/lraspp_m-v3-d8.py new file mode 100644 index 00000000..93258242 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/lraspp_m-v3-d8.py @@ -0,0 +1,25 @@ +# model settings +norm_cfg = dict(type='SyncBN', eps=0.001, requires_grad=True) +model = dict( + type='EncoderDecoder', + backbone=dict( + type='MobileNetV3', + arch='large', + out_indices=(1, 3, 16), + norm_cfg=norm_cfg), + decode_head=dict( + type='LRASPPHead', + in_channels=(16, 24, 960), + in_index=(0, 1, 2), + channels=128, + input_transform='multiple_select', + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + act_cfg=dict(type='ReLU'), + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/nonlocal_r50-d8.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/nonlocal_r50-d8.py new file mode 100644 index 00000000..5674a398 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/nonlocal_r50-d8.py @@ -0,0 +1,46 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 2, 4), + strides=(1, 2, 1, 1), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + decode_head=dict( + type='NLHead', + in_channels=2048, + in_index=3, + channels=512, + dropout_ratio=0.1, + reduction=2, + use_scale=True, + mode='embedded_gaussian', + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=1024, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/ocrnet_hr18.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/ocrnet_hr18.py new file mode 100644 index 00000000..c60f62a7 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/ocrnet_hr18.py @@ -0,0 +1,68 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='CascadeEncoderDecoder', + num_stages=2, + pretrained='open-mmlab://msra/hrnetv2_w18', + backbone=dict( + type='HRNet', + norm_cfg=norm_cfg, + norm_eval=False, + extra=dict( + stage1=dict( + num_modules=1, + num_branches=1, + block='BOTTLENECK', + num_blocks=(4, ), + num_channels=(64, )), + stage2=dict( + num_modules=1, + num_branches=2, + block='BASIC', + num_blocks=(4, 4), + num_channels=(18, 36)), + stage3=dict( + num_modules=4, + num_branches=3, + block='BASIC', + num_blocks=(4, 4, 4), + num_channels=(18, 36, 72)), + stage4=dict( + num_modules=3, + num_branches=4, + block='BASIC', + num_blocks=(4, 4, 4, 4), + num_channels=(18, 36, 72, 144)))), + decode_head=[ + dict( + type='FCNHead', + in_channels=[18, 36, 72, 144], + channels=sum([18, 36, 72, 144]), + in_index=(0, 1, 2, 3), + input_transform='resize_concat', + kernel_size=1, + num_convs=1, + concat_input=False, + dropout_ratio=-1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + dict( + type='OCRHead', + in_channels=[18, 36, 72, 144], + in_index=(0, 1, 2, 3), + input_transform='resize_concat', + channels=512, + ocr_channels=256, + dropout_ratio=-1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + ], + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/ocrnet_r50-d8.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/ocrnet_r50-d8.py new file mode 100644 index 00000000..615aa3ff --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/ocrnet_r50-d8.py @@ -0,0 +1,47 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='CascadeEncoderDecoder', + num_stages=2, + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 2, 4), + strides=(1, 2, 1, 1), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + decode_head=[ + dict( + type='FCNHead', + in_channels=1024, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + dict( + type='OCRHead', + in_channels=2048, + in_index=3, + channels=512, + ocr_channels=256, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)) + ], + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/pointrend_r50.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/pointrend_r50.py new file mode 100644 index 00000000..9d323dbf --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/pointrend_r50.py @@ -0,0 +1,56 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='CascadeEncoderDecoder', + num_stages=2, + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 1, 1), + strides=(1, 2, 2, 2), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + neck=dict( + type='FPN', + in_channels=[256, 512, 1024, 2048], + out_channels=256, + num_outs=4), + decode_head=[ + dict( + type='FPNHead', + in_channels=[256, 256, 256, 256], + in_index=[0, 1, 2, 3], + feature_strides=[4, 8, 16, 32], + channels=128, + dropout_ratio=-1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + dict( + type='PointHead', + in_channels=[256], + in_index=[0], + channels=256, + num_fcs=3, + coarse_pred_each_layer=True, + dropout_ratio=-1, + num_classes=19, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)) + ], + # model training and testing settings + train_cfg=dict( + num_points=2048, oversample_ratio=3, importance_sample_ratio=0.75), + test_cfg=dict( + mode='whole', + subdivision_steps=2, + subdivision_num_points=8196, + scale_factor=2)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/psanet_r50-d8.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/psanet_r50-d8.py new file mode 100644 index 00000000..689513fa --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/psanet_r50-d8.py @@ -0,0 +1,49 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 2, 4), + strides=(1, 2, 1, 1), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + decode_head=dict( + type='PSAHead', + in_channels=2048, + in_index=3, + channels=512, + mask_size=(97, 97), + psa_type='bi-direction', + compact=False, + shrink_factor=2, + normalization_factor=1.0, + psa_softmax=True, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=1024, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/pspnet_r50-d8.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/pspnet_r50-d8.py new file mode 100644 index 00000000..f451e08a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/pspnet_r50-d8.py @@ -0,0 +1,44 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 2, 4), + strides=(1, 2, 1, 1), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + decode_head=dict( + type='PSPHead', + in_channels=2048, + in_index=3, + channels=512, + pool_scales=(1, 2, 3, 6), + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=1024, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/pspnet_unet_s5-d16.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/pspnet_unet_s5-d16.py new file mode 100644 index 00000000..fcff9ec4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/pspnet_unet_s5-d16.py @@ -0,0 +1,50 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained=None, + backbone=dict( + type='UNet', + in_channels=3, + base_channels=64, + num_stages=5, + strides=(1, 1, 1, 1, 1), + enc_num_convs=(2, 2, 2, 2, 2), + dec_num_convs=(2, 2, 2, 2), + downsamples=(True, True, True, True), + enc_dilations=(1, 1, 1, 1, 1), + dec_dilations=(1, 1, 1, 1), + with_cp=False, + conv_cfg=None, + norm_cfg=norm_cfg, + act_cfg=dict(type='ReLU'), + upsample_cfg=dict(type='InterpConv'), + norm_eval=False), + decode_head=dict( + type='PSPHead', + in_channels=64, + in_index=4, + channels=16, + pool_scales=(1, 2, 3, 6), + dropout_ratio=0.1, + num_classes=2, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=128, + in_index=3, + channels=64, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=2, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='slide', crop_size=256, stride=170)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/upernet_r50.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/upernet_r50.py new file mode 100644 index 00000000..10974962 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/upernet_r50.py @@ -0,0 +1,44 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='ResNetV1c', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + dilations=(1, 1, 1, 1), + strides=(1, 2, 2, 2), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True), + decode_head=dict( + type='UPerHead', + in_channels=[256, 512, 1024, 2048], + in_index=[0, 1, 2, 3], + pool_scales=(1, 2, 3, 6), + channels=512, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=1024, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/upernet_uniformer.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/upernet_uniformer.py new file mode 100644 index 00000000..41aa4db8 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/models/upernet_uniformer.py @@ -0,0 +1,43 @@ +# model settings +norm_cfg = dict(type='BN', requires_grad=True) +model = dict( + type='EncoderDecoder', + pretrained=None, + backbone=dict( + type='UniFormer', + embed_dim=[64, 128, 320, 512], + layers=[3, 4, 8, 3], + head_dim=64, + mlp_ratio=4., + qkv_bias=True, + drop_rate=0., + attn_drop_rate=0., + drop_path_rate=0.1), + decode_head=dict( + type='UPerHead', + in_channels=[64, 128, 320, 512], + in_index=[0, 1, 2, 3], + pool_scales=(1, 2, 3, 6), + channels=512, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=320, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=19, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/schedules/schedule_160k.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/schedules/schedule_160k.py new file mode 100644 index 00000000..52603890 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/schedules/schedule_160k.py @@ -0,0 +1,9 @@ +# optimizer +optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005) +optimizer_config = dict() +# learning policy +lr_config = dict(policy='poly', power=0.9, min_lr=1e-4, by_epoch=False) +# runtime settings +runner = dict(type='IterBasedRunner', max_iters=160000) +checkpoint_config = dict(by_epoch=False, interval=16000) +evaluation = dict(interval=16000, metric='mIoU') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/schedules/schedule_20k.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/schedules/schedule_20k.py new file mode 100644 index 00000000..bf780a1b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/schedules/schedule_20k.py @@ -0,0 +1,9 @@ +# optimizer +optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005) +optimizer_config = dict() +# learning policy +lr_config = dict(policy='poly', power=0.9, min_lr=1e-4, by_epoch=False) +# runtime settings +runner = dict(type='IterBasedRunner', max_iters=20000) +checkpoint_config = dict(by_epoch=False, interval=2000) +evaluation = dict(interval=2000, metric='mIoU') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/schedules/schedule_40k.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/schedules/schedule_40k.py new file mode 100644 index 00000000..cdbf841a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/schedules/schedule_40k.py @@ -0,0 +1,9 @@ +# optimizer +optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005) +optimizer_config = dict() +# learning policy +lr_config = dict(policy='poly', power=0.9, min_lr=1e-4, by_epoch=False) +# runtime settings +runner = dict(type='IterBasedRunner', max_iters=40000) +checkpoint_config = dict(by_epoch=False, interval=4000) +evaluation = dict(interval=4000, metric='mIoU') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/schedules/schedule_80k.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/schedules/schedule_80k.py new file mode 100644 index 00000000..c190cee6 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/configs/_base_/schedules/schedule_80k.py @@ -0,0 +1,9 @@ +# optimizer +optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005) +optimizer_config = dict() +# learning policy +lr_config = dict(policy='poly', power=0.9, min_lr=1e-4, by_epoch=False) +# runtime settings +runner = dict(type='IterBasedRunner', max_iters=80000) +checkpoint_config = dict(by_epoch=False, interval=8000) +evaluation = dict(interval=8000, metric='mIoU') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/inference.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/inference.py new file mode 100644 index 00000000..667d3e7e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/inference.py @@ -0,0 +1,144 @@ + +import torch + +try: + import mmcv as mmcv + from mmcv.parallel import collate, scatter + from mmcv.runner import load_checkpoint + from mmseg.datasets.pipelines import Compose + from mmseg.models import build_segmentor +except ImportError: + import annotator.mmpkg.mmcv as mmcv + from annotator.mmpkg.mmcv.parallel import collate, scatter + from annotator.mmpkg.mmcv.runner import load_checkpoint + from annotator.mmpkg.mmseg.datasets.pipelines import Compose + from annotator.mmpkg.mmseg.models import build_segmentor + +def init_segmentor(config, checkpoint=None, device='cuda:0'): + """Initialize a segmentor from config file. + + Args: + config (str or :obj:`mmcv.Config`): Config file path or the config + object. + checkpoint (str, optional): Checkpoint path. If left as None, the model + will not load any weights. + device (str, optional) CPU/CUDA device option. Default 'cuda:0'. + Use 'cpu' for loading model on CPU. + Returns: + nn.Module: The constructed segmentor. + """ + if isinstance(config, str): + config = mmcv.Config.fromfile(config) + elif not isinstance(config, mmcv.Config): + raise TypeError('config must be a filename or Config object, ' + 'but got {}'.format(type(config))) + config.model.pretrained = None + config.model.train_cfg = None + model = build_segmentor(config.model, test_cfg=config.get('test_cfg')) + if checkpoint is not None: + checkpoint = load_checkpoint(model, checkpoint, map_location='cpu') + model.CLASSES = checkpoint['meta']['CLASSES'] + model.PALETTE = checkpoint['meta']['PALETTE'] + model.cfg = config # save the config in the model for convenience + model.to(device) + model.eval() + return model + + +class LoadImage: + """A simple pipeline to load image.""" + + def __call__(self, results): + """Call function to load images into results. + + Args: + results (dict): A result dict contains the file name + of the image to be read. + + Returns: + dict: ``results`` will be returned containing loaded image. + """ + + if isinstance(results['img'], str): + results['filename'] = results['img'] + results['ori_filename'] = results['img'] + else: + results['filename'] = None + results['ori_filename'] = None + img = mmcv.imread(results['img']) + results['img'] = img + results['img_shape'] = img.shape + results['ori_shape'] = img.shape + return results + + +def inference_segmentor(model, img): + """Inference image(s) with the segmentor. + + Args: + model (nn.Module): The loaded segmentor. + imgs (str/ndarray or list[str/ndarray]): Either image files or loaded + images. + + Returns: + (list[Tensor]): The segmentation result. + """ + cfg = model.cfg + device = next(model.parameters()).device # model device + # build the data pipeline + test_pipeline = [LoadImage()] + cfg.data.test.pipeline[1:] + test_pipeline = Compose(test_pipeline) + # prepare data + data = dict(img=img) + data = test_pipeline(data) + data = collate([data], samples_per_gpu=1) + if next(model.parameters()).is_cuda: + # scatter to specified GPU + data = scatter(data, [device])[0] + else: + data['img_metas'] = [i.data[0] for i in data['img_metas']] + + data['img'] = [x.to(device) for x in data['img']] + + # forward the model + with torch.no_grad(): + result = model(return_loss=False, rescale=True, **data) + return result + + +def show_result_pyplot(model, + img, + result, + palette=None, + fig_size=(15, 10), + opacity=0.5, + title='', + block=True): + """Visualize the segmentation results on the image. + + Args: + model (nn.Module): The loaded segmentor. + img (str or np.ndarray): Image filename or loaded image. + result (list): The segmentation result. + palette (list[list[int]]] | None): The palette of segmentation + map. If None is given, random palette will be generated. + Default: None + fig_size (tuple): Figure size of the pyplot figure. + opacity(float): Opacity of painted segmentation map. + Default 0.5. + Must be in (0, 1] range. + title (str): The title of pyplot figure. + Default is ''. + block (bool): Whether to block the pyplot figure. + Default is True. + """ + if hasattr(model, 'module'): + model = model.module + img = model.show_result( + img, result, palette=palette, show=False, opacity=opacity) + # plt.figure(figsize=fig_size) + # plt.imshow(mmcv.bgr2rgb(img)) + # plt.title(title) + # plt.tight_layout() + # plt.show(block=block) + return mmcv.bgr2rgb(img) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/mmcv_custom/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/mmcv_custom/__init__.py new file mode 100644 index 00000000..4b958738 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/mmcv_custom/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + +from .checkpoint import load_checkpoint + +__all__ = ['load_checkpoint'] \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/mmcv_custom/checkpoint.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/mmcv_custom/checkpoint.py new file mode 100644 index 00000000..48c1b16b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/mmcv_custom/checkpoint.py @@ -0,0 +1,508 @@ +# Copyright (c) Open-MMLab. All rights reserved. +import io +import os +import os.path as osp +import pkgutil +import time +import warnings +from collections import OrderedDict +from importlib import import_module +from tempfile import TemporaryDirectory + +import torch +import torchvision +from torch.optim import Optimizer +from torch.utils import model_zoo +from torch.nn import functional as F + +try: + import mmcv as mmcv + from mmcv.fileio import FileClient + from mmcv.fileio import load as load_file + from mmcv.parallel import is_module_wrapper + from mmcv.utils import mkdir_or_exist + from mmcv.runner import get_dist_info +except ImportError: + import annotator.mmpkg.mmcv as mmcv + from annotator.mmpkg.mmcv.fileio import FileClient + from annotator.mmpkg.mmcv.fileio import load as load_file + from annotator.mmpkg.mmcv.parallel import is_module_wrapper + from annotator.mmpkg.mmcv.utils import mkdir_or_exist + from annotator.mmpkg.mmcv.runner import get_dist_info + +ENV_MMCV_HOME = 'MMCV_HOME' +ENV_XDG_CACHE_HOME = 'XDG_CACHE_HOME' +DEFAULT_CACHE_DIR = '~/.cache' + + +def _get_mmcv_home(): + mmcv_home = os.path.expanduser( + os.getenv( + ENV_MMCV_HOME, + os.path.join( + os.getenv(ENV_XDG_CACHE_HOME, DEFAULT_CACHE_DIR), 'mmcv'))) + + mkdir_or_exist(mmcv_home) + return mmcv_home + + +def load_state_dict(module, state_dict, strict=False, logger=None): + """Load state_dict to a module. + + This method is modified from :meth:`torch.nn.Module.load_state_dict`. + Default value for ``strict`` is set to ``False`` and the message for + param mismatch will be shown even if strict is False. + + Args: + module (Module): Module that receives the state_dict. + state_dict (OrderedDict): Weights. + strict (bool): whether to strictly enforce that the keys + in :attr:`state_dict` match the keys returned by this module's + :meth:`~torch.nn.Module.state_dict` function. Default: ``False``. + logger (:obj:`logging.Logger`, optional): Logger to log the error + message. If not specified, print function will be used. + """ + unexpected_keys = [] + all_missing_keys = [] + err_msg = [] + + metadata = getattr(state_dict, '_metadata', None) + state_dict = state_dict.copy() + if metadata is not None: + state_dict._metadata = metadata + + # use _load_from_state_dict to enable checkpoint version control + def load(module, prefix=''): + # recursively check parallel module in case that the model has a + # complicated structure, e.g., nn.Module(nn.Module(DDP)) + if is_module_wrapper(module): + module = module.module + local_metadata = {} if metadata is None else metadata.get( + prefix[:-1], {}) + module._load_from_state_dict(state_dict, prefix, local_metadata, True, + all_missing_keys, unexpected_keys, + err_msg) + for name, child in module._modules.items(): + if child is not None: + load(child, prefix + name + '.') + + load(module) + load = None # break load->load reference cycle + + # ignore "num_batches_tracked" of BN layers + missing_keys = [ + key for key in all_missing_keys if 'num_batches_tracked' not in key + ] + + if unexpected_keys: + err_msg.append('unexpected key in source ' + f'state_dict: {", ".join(unexpected_keys)}\n') + if missing_keys: + err_msg.append( + f'missing keys in source state_dict: {", ".join(missing_keys)}\n') + + rank, _ = get_dist_info() + if len(err_msg) > 0 and rank == 0: + err_msg.insert( + 0, 'The model and loaded state dict do not match exactly\n') + err_msg = '\n'.join(err_msg) + if strict: + raise RuntimeError(err_msg) + elif logger is not None: + logger.warning(err_msg) + else: + print(err_msg) + + +def load_url_dist(url, model_dir=None): + """In distributed setting, this function only download checkpoint at local + rank 0.""" + rank, world_size = get_dist_info() + rank = int(os.environ.get('LOCAL_RANK', rank)) + if rank == 0: + checkpoint = model_zoo.load_url(url, model_dir=model_dir) + if world_size > 1: + torch.distributed.barrier() + if rank > 0: + checkpoint = model_zoo.load_url(url, model_dir=model_dir) + return checkpoint + + +def load_pavimodel_dist(model_path, map_location=None): + """In distributed setting, this function only download checkpoint at local + rank 0.""" + try: + from pavi import modelcloud + except ImportError: + raise ImportError( + 'Please install pavi to load checkpoint from modelcloud.') + rank, world_size = get_dist_info() + rank = int(os.environ.get('LOCAL_RANK', rank)) + if rank == 0: + model = modelcloud.get(model_path) + with TemporaryDirectory() as tmp_dir: + downloaded_file = osp.join(tmp_dir, model.name) + model.download(downloaded_file) + checkpoint = torch.load(downloaded_file, map_location=map_location) + if world_size > 1: + torch.distributed.barrier() + if rank > 0: + model = modelcloud.get(model_path) + with TemporaryDirectory() as tmp_dir: + downloaded_file = osp.join(tmp_dir, model.name) + model.download(downloaded_file) + checkpoint = torch.load( + downloaded_file, map_location=map_location) + return checkpoint + + +def load_fileclient_dist(filename, backend, map_location): + """In distributed setting, this function only download checkpoint at local + rank 0.""" + rank, world_size = get_dist_info() + rank = int(os.environ.get('LOCAL_RANK', rank)) + allowed_backends = ['ceph'] + if backend not in allowed_backends: + raise ValueError(f'Load from Backend {backend} is not supported.') + if rank == 0: + fileclient = FileClient(backend=backend) + buffer = io.BytesIO(fileclient.get(filename)) + checkpoint = torch.load(buffer, map_location=map_location) + if world_size > 1: + torch.distributed.barrier() + if rank > 0: + fileclient = FileClient(backend=backend) + buffer = io.BytesIO(fileclient.get(filename)) + checkpoint = torch.load(buffer, map_location=map_location) + return checkpoint + + +def get_torchvision_models(): + model_urls = dict() + for _, name, ispkg in pkgutil.walk_packages(torchvision.models.__path__): + if ispkg: + continue + _zoo = import_module(f'torchvision.models.{name}') + if hasattr(_zoo, 'model_urls'): + _urls = getattr(_zoo, 'model_urls') + model_urls.update(_urls) + return model_urls + + +def get_external_models(): + mmcv_home = _get_mmcv_home() + default_json_path = osp.join(mmcv.__path__[0], 'model_zoo/open_mmlab.json') + default_urls = load_file(default_json_path) + assert isinstance(default_urls, dict) + external_json_path = osp.join(mmcv_home, 'open_mmlab.json') + if osp.exists(external_json_path): + external_urls = load_file(external_json_path) + assert isinstance(external_urls, dict) + default_urls.update(external_urls) + + return default_urls + + +def get_mmcls_models(): + mmcls_json_path = osp.join(mmcv.__path__[0], 'model_zoo/mmcls.json') + mmcls_urls = load_file(mmcls_json_path) + + return mmcls_urls + + +def get_deprecated_model_names(): + deprecate_json_path = osp.join(mmcv.__path__[0], + 'model_zoo/deprecated.json') + deprecate_urls = load_file(deprecate_json_path) + assert isinstance(deprecate_urls, dict) + + return deprecate_urls + + +def _process_mmcls_checkpoint(checkpoint): + state_dict = checkpoint['state_dict'] + new_state_dict = OrderedDict() + for k, v in state_dict.items(): + if k.startswith('backbone.'): + new_state_dict[k[9:]] = v + new_checkpoint = dict(state_dict=new_state_dict) + + return new_checkpoint + + +def _load_checkpoint(filename, map_location=None): + """Load checkpoint from somewhere (modelzoo, file, url). + + Args: + filename (str): Accept local filepath, URL, ``torchvision://xxx``, + ``open-mmlab://xxx``. Please refer to ``docs/model_zoo.md`` for + details. + map_location (str | None): Same as :func:`torch.load`. Default: None. + + Returns: + dict | OrderedDict: The loaded checkpoint. It can be either an + OrderedDict storing model weights or a dict containing other + information, which depends on the checkpoint. + """ + if filename.startswith('modelzoo://'): + warnings.warn('The URL scheme of "modelzoo://" is deprecated, please ' + 'use "torchvision://" instead') + model_urls = get_torchvision_models() + model_name = filename[11:] + checkpoint = load_url_dist(model_urls[model_name]) + elif filename.startswith('torchvision://'): + model_urls = get_torchvision_models() + model_name = filename[14:] + checkpoint = load_url_dist(model_urls[model_name]) + elif filename.startswith('open-mmlab://'): + model_urls = get_external_models() + model_name = filename[13:] + deprecated_urls = get_deprecated_model_names() + if model_name in deprecated_urls: + warnings.warn(f'open-mmlab://{model_name} is deprecated in favor ' + f'of open-mmlab://{deprecated_urls[model_name]}') + model_name = deprecated_urls[model_name] + model_url = model_urls[model_name] + # check if is url + if model_url.startswith(('http://', 'https://')): + checkpoint = load_url_dist(model_url) + else: + filename = osp.join(_get_mmcv_home(), model_url) + if not osp.isfile(filename): + raise IOError(f'{filename} is not a checkpoint file') + checkpoint = torch.load(filename, map_location=map_location) + elif filename.startswith('mmcls://'): + model_urls = get_mmcls_models() + model_name = filename[8:] + checkpoint = load_url_dist(model_urls[model_name]) + checkpoint = _process_mmcls_checkpoint(checkpoint) + elif filename.startswith(('http://', 'https://')): + checkpoint = load_url_dist(filename) + elif filename.startswith('pavi://'): + model_path = filename[7:] + checkpoint = load_pavimodel_dist(model_path, map_location=map_location) + elif filename.startswith('s3://'): + checkpoint = load_fileclient_dist( + filename, backend='ceph', map_location=map_location) + else: + if not osp.isfile(filename): + raise IOError(f'{filename} is not a checkpoint file') + checkpoint = torch.load(filename, map_location=map_location) + return checkpoint + + +def load_checkpoint(model, + filename, + map_location='cpu', + strict=False, + logger=None): + """Load checkpoint from a file or URI. + + Args: + model (Module): Module to load checkpoint. + filename (str): Accept local filepath, URL, ``torchvision://xxx``, + ``open-mmlab://xxx``. Please refer to ``docs/model_zoo.md`` for + details. + map_location (str): Same as :func:`torch.load`. + strict (bool): Whether to allow different params for the model and + checkpoint. + logger (:mod:`logging.Logger` or None): The logger for error message. + + Returns: + dict or OrderedDict: The loaded checkpoint. + """ + checkpoint = _load_checkpoint(filename, map_location) + # OrderedDict is a subclass of dict + if not isinstance(checkpoint, dict): + raise RuntimeError( + f'No state_dict found in checkpoint file {filename}') + # get state_dict from checkpoint + if 'state_dict' in checkpoint: + state_dict = checkpoint['state_dict'] + elif 'model' in checkpoint: + state_dict = checkpoint['model'] + else: + state_dict = checkpoint + # strip prefix of state_dict + if list(state_dict.keys())[0].startswith('module.'): + state_dict = {k[7:]: v for k, v in state_dict.items()} + + # for MoBY, load model of online branch + if sorted(list(state_dict.keys()))[0].startswith('encoder'): + state_dict = {k.replace('encoder.', ''): v for k, v in state_dict.items() if k.startswith('encoder.')} + + # reshape absolute position embedding + if state_dict.get('absolute_pos_embed') is not None: + absolute_pos_embed = state_dict['absolute_pos_embed'] + N1, L, C1 = absolute_pos_embed.size() + N2, C2, H, W = model.absolute_pos_embed.size() + if N1 != N2 or C1 != C2 or L != H*W: + logger.warning("Error in loading absolute_pos_embed, pass") + else: + state_dict['absolute_pos_embed'] = absolute_pos_embed.view(N2, H, W, C2).permute(0, 3, 1, 2) + + # interpolate position bias table if needed + relative_position_bias_table_keys = [k for k in state_dict.keys() if "relative_position_bias_table" in k] + for table_key in relative_position_bias_table_keys: + table_pretrained = state_dict[table_key] + table_current = model.state_dict()[table_key] + L1, nH1 = table_pretrained.size() + L2, nH2 = table_current.size() + if nH1 != nH2: + logger.warning(f"Error in loading {table_key}, pass") + else: + if L1 != L2: + S1 = int(L1 ** 0.5) + S2 = int(L2 ** 0.5) + table_pretrained_resized = F.interpolate( + table_pretrained.permute(1, 0).view(1, nH1, S1, S1), + size=(S2, S2), mode='bicubic') + state_dict[table_key] = table_pretrained_resized.view(nH2, L2).permute(1, 0) + + # load state_dict + load_state_dict(model, state_dict, strict, logger) + return checkpoint + + +def weights_to_cpu(state_dict): + """Copy a model state_dict to cpu. + + Args: + state_dict (OrderedDict): Model weights on GPU. + + Returns: + OrderedDict: Model weights on GPU. + """ + state_dict_cpu = OrderedDict() + for key, val in state_dict.items(): + state_dict_cpu[key] = val.cpu() + return state_dict_cpu + + +def _save_to_state_dict(module, destination, prefix, keep_vars): + """Saves module state to `destination` dictionary. + + This method is modified from :meth:`torch.nn.Module._save_to_state_dict`. + + Args: + module (nn.Module): The module to generate state_dict. + destination (dict): A dict where state will be stored. + prefix (str): The prefix for parameters and buffers used in this + module. + """ + for name, param in module._parameters.items(): + if param is not None: + destination[prefix + name] = param if keep_vars else param.detach() + for name, buf in module._buffers.items(): + # remove check of _non_persistent_buffers_set to allow nn.BatchNorm2d + if buf is not None: + destination[prefix + name] = buf if keep_vars else buf.detach() + + +def get_state_dict(module, destination=None, prefix='', keep_vars=False): + """Returns a dictionary containing a whole state of the module. + + Both parameters and persistent buffers (e.g. running averages) are + included. Keys are corresponding parameter and buffer names. + + This method is modified from :meth:`torch.nn.Module.state_dict` to + recursively check parallel module in case that the model has a complicated + structure, e.g., nn.Module(nn.Module(DDP)). + + Args: + module (nn.Module): The module to generate state_dict. + destination (OrderedDict): Returned dict for the state of the + module. + prefix (str): Prefix of the key. + keep_vars (bool): Whether to keep the variable property of the + parameters. Default: False. + + Returns: + dict: A dictionary containing a whole state of the module. + """ + # recursively check parallel module in case that the model has a + # complicated structure, e.g., nn.Module(nn.Module(DDP)) + if is_module_wrapper(module): + module = module.module + + # below is the same as torch.nn.Module.state_dict() + if destination is None: + destination = OrderedDict() + destination._metadata = OrderedDict() + destination._metadata[prefix[:-1]] = local_metadata = dict( + version=module._version) + _save_to_state_dict(module, destination, prefix, keep_vars) + for name, child in module._modules.items(): + if child is not None: + get_state_dict( + child, destination, prefix + name + '.', keep_vars=keep_vars) + for hook in module._state_dict_hooks.values(): + hook_result = hook(module, destination, prefix, local_metadata) + if hook_result is not None: + destination = hook_result + return destination + + +def save_checkpoint(model, filename, optimizer=None, meta=None): + """Save checkpoint to file. + + The checkpoint will have 3 fields: ``meta``, ``state_dict`` and + ``optimizer``. By default ``meta`` will contain version and time info. + + Args: + model (Module): Module whose params are to be saved. + filename (str): Checkpoint filename. + optimizer (:obj:`Optimizer`, optional): Optimizer to be saved. + meta (dict, optional): Metadata to be saved in checkpoint. + """ + if meta is None: + meta = {} + elif not isinstance(meta, dict): + raise TypeError(f'meta must be a dict or None, but got {type(meta)}') + meta.update(mmcv_version=mmcv.__version__, time=time.asctime()) + + if is_module_wrapper(model): + model = model.module + + if hasattr(model, 'CLASSES') and model.CLASSES is not None: + # save class name to the meta + meta.update(CLASSES=model.CLASSES) + + checkpoint = { + 'meta': meta, + 'state_dict': weights_to_cpu(get_state_dict(model)) + } + # save optimizer state dict in the checkpoint + if isinstance(optimizer, Optimizer): + checkpoint['optimizer'] = optimizer.state_dict() + elif isinstance(optimizer, dict): + checkpoint['optimizer'] = {} + for name, optim in optimizer.items(): + checkpoint['optimizer'][name] = optim.state_dict() + + if filename.startswith('pavi://'): + try: + from pavi import modelcloud + from pavi.exception import NodeNotFoundError + except ImportError: + raise ImportError( + 'Please install pavi to load checkpoint from modelcloud.') + model_path = filename[7:] + root = modelcloud.Folder() + model_dir, model_name = osp.split(model_path) + try: + model = modelcloud.get(model_dir) + except NodeNotFoundError: + model = root.create_training_model(model_dir) + with TemporaryDirectory() as tmp_dir: + checkpoint_file = osp.join(tmp_dir, model_name) + with open(checkpoint_file, 'wb') as f: + torch.save(checkpoint, f) + f.flush() + model.create_file(checkpoint_file, name=model_name) + else: + mmcv.mkdir_or_exist(osp.dirname(filename)) + # immediately flush buffer + with open(filename, 'wb') as f: + torch.save(checkpoint, f) + f.flush() \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/uniformer.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/uniformer.py new file mode 100644 index 00000000..f5726fbe --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/uniformer.py @@ -0,0 +1,426 @@ +# -------------------------------------------------------- +# UniFormer +# Copyright (c) 2022 SenseTime X-Lab +# Licensed under The MIT License [see LICENSE for details] +# Written by Kunchang Li +# -------------------------------------------------------- + + +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.checkpoint as checkpoint + +from functools import partial +from collections import OrderedDict +from timm.models.layers import DropPath, to_2tuple, trunc_normal_ + +try: + from mmseg.utils import get_root_logger + from mmseg.models.builder import BACKBONES +except ImportError: + from annotator.mmpkg.mmseg.utils import get_root_logger + from annotator.mmpkg.mmseg.models.builder import BACKBONES + +from annotator.uniformer.mmcv_custom import load_checkpoint + + +class Mlp(nn.Module): + def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.): + super().__init__() + out_features = out_features or in_features + hidden_features = hidden_features or in_features + self.fc1 = nn.Linear(in_features, hidden_features) + self.act = act_layer() + self.fc2 = nn.Linear(hidden_features, out_features) + self.drop = nn.Dropout(drop) + + def forward(self, x): + x = self.fc1(x) + x = self.act(x) + x = self.drop(x) + x = self.fc2(x) + x = self.drop(x) + return x + + +class CMlp(nn.Module): + def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.): + super().__init__() + out_features = out_features or in_features + hidden_features = hidden_features or in_features + self.fc1 = nn.Conv2d(in_features, hidden_features, 1) + self.act = act_layer() + self.fc2 = nn.Conv2d(hidden_features, out_features, 1) + self.drop = nn.Dropout(drop) + + def forward(self, x): + x = self.fc1(x) + x = self.act(x) + x = self.drop(x) + x = self.fc2(x) + x = self.drop(x) + return x + + +class CBlock(nn.Module): + def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0., attn_drop=0., + drop_path=0., act_layer=nn.GELU, norm_layer=nn.LayerNorm): + super().__init__() + self.pos_embed = nn.Conv2d(dim, dim, 3, padding=1, groups=dim) + self.norm1 = nn.BatchNorm2d(dim) + self.conv1 = nn.Conv2d(dim, dim, 1) + self.conv2 = nn.Conv2d(dim, dim, 1) + self.attn = nn.Conv2d(dim, dim, 5, padding=2, groups=dim) + # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here + self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity() + self.norm2 = nn.BatchNorm2d(dim) + mlp_hidden_dim = int(dim * mlp_ratio) + self.mlp = CMlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop) + + def forward(self, x): + x = x + self.pos_embed(x) + x = x + self.drop_path(self.conv2(self.attn(self.conv1(self.norm1(x))))) + x = x + self.drop_path(self.mlp(self.norm2(x))) + return x + + +class Attention(nn.Module): + def __init__(self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0., proj_drop=0.): + super().__init__() + self.num_heads = num_heads + head_dim = dim // num_heads + # NOTE scale factor was wrong in my original version, can set manually to be compat with prev weights + self.scale = qk_scale or head_dim ** -0.5 + + self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias) + self.attn_drop = nn.Dropout(attn_drop) + self.proj = nn.Linear(dim, dim) + self.proj_drop = nn.Dropout(proj_drop) + + def forward(self, x): + B, N, C = x.shape + qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4) + q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple) + + attn = (q @ k.transpose(-2, -1)) * self.scale + attn = attn.softmax(dim=-1) + attn = self.attn_drop(attn) + + x = (attn @ v).transpose(1, 2).reshape(B, N, C) + x = self.proj(x) + x = self.proj_drop(x) + return x + + +class SABlock(nn.Module): + def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0., attn_drop=0., + drop_path=0., act_layer=nn.GELU, norm_layer=nn.LayerNorm): + super().__init__() + self.pos_embed = nn.Conv2d(dim, dim, 3, padding=1, groups=dim) + self.norm1 = norm_layer(dim) + self.attn = Attention( + dim, + num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, + attn_drop=attn_drop, proj_drop=drop) + # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here + self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity() + self.norm2 = norm_layer(dim) + mlp_hidden_dim = int(dim * mlp_ratio) + self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop) + + def forward(self, x): + x = x + self.pos_embed(x) + B, N, H, W = x.shape + x = x.flatten(2).transpose(1, 2) + x = x + self.drop_path(self.attn(self.norm1(x))) + x = x + self.drop_path(self.mlp(self.norm2(x))) + x = x.transpose(1, 2).reshape(B, N, H, W) + return x + + +def window_partition(x, window_size): + """ + Args: + x: (B, H, W, C) + window_size (int): window size + Returns: + windows: (num_windows*B, window_size, window_size, C) + """ + B, H, W, C = x.shape + x = x.view(B, H // window_size, window_size, W // window_size, window_size, C) + windows = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(-1, window_size, window_size, C) + return windows + + +def window_reverse(windows, window_size, H, W): + """ + Args: + windows: (num_windows*B, window_size, window_size, C) + window_size (int): Window size + H (int): Height of image + W (int): Width of image + Returns: + x: (B, H, W, C) + """ + B = int(windows.shape[0] / (H * W / window_size / window_size)) + x = windows.view(B, H // window_size, W // window_size, window_size, window_size, -1) + x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, H, W, -1) + return x + + +class SABlock_Windows(nn.Module): + def __init__(self, dim, num_heads, window_size=14, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0., attn_drop=0., + drop_path=0., act_layer=nn.GELU, norm_layer=nn.LayerNorm): + super().__init__() + self.window_size=window_size + self.pos_embed = nn.Conv2d(dim, dim, 3, padding=1, groups=dim) + self.norm1 = norm_layer(dim) + self.attn = Attention( + dim, + num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, + attn_drop=attn_drop, proj_drop=drop) + # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here + self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity() + self.norm2 = norm_layer(dim) + mlp_hidden_dim = int(dim * mlp_ratio) + self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop) + + def forward(self, x): + x = x + self.pos_embed(x) + x = x.permute(0, 2, 3, 1) + B, H, W, C = x.shape + shortcut = x + x = self.norm1(x) + + pad_l = pad_t = 0 + pad_r = (self.window_size - W % self.window_size) % self.window_size + pad_b = (self.window_size - H % self.window_size) % self.window_size + x = F.pad(x, (0, 0, pad_l, pad_r, pad_t, pad_b)) + _, Hp, Wp, _ = x.shape + + x_windows = window_partition(x, self.window_size) # nW*B, window_size, window_size, C + x_windows = x_windows.view(-1, self.window_size * self.window_size, C) # nW*B, window_size*window_size, C + + # W-MSA/SW-MSA + attn_windows = self.attn(x_windows) # nW*B, window_size*window_size, C + + # merge windows + attn_windows = attn_windows.view(-1, self.window_size, self.window_size, C) + x = window_reverse(attn_windows, self.window_size, Hp, Wp) # B H' W' C + + # reverse cyclic shift + if pad_r > 0 or pad_b > 0: + x = x[:, :H, :W, :].contiguous() + + x = shortcut + self.drop_path(x) + x = x + self.drop_path(self.mlp(self.norm2(x))) + x = x.permute(0, 3, 1, 2).reshape(B, C, H, W) + return x + + +class PatchEmbed(nn.Module): + """ Image to Patch Embedding + """ + def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768): + super().__init__() + img_size = to_2tuple(img_size) + patch_size = to_2tuple(patch_size) + num_patches = (img_size[1] // patch_size[1]) * (img_size[0] // patch_size[0]) + self.img_size = img_size + self.patch_size = patch_size + self.num_patches = num_patches + self.norm = nn.LayerNorm(embed_dim) + self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size) + + def forward(self, x): + B, _, H, W = x.shape + x = self.proj(x) + B, _, H, W = x.shape + x = x.flatten(2).transpose(1, 2) + x = self.norm(x) + x = x.reshape(B, H, W, -1).permute(0, 3, 1, 2).contiguous() + return x + + +@BACKBONES.register_module() +class UniFormer(nn.Module): + """ Vision Transformer + A PyTorch impl of : `An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale` - + https://arxiv.org/abs/2010.11929 + """ + def __init__(self, layers=[3, 4, 8, 3], img_size=224, in_chans=3, num_classes=80, embed_dim=[64, 128, 320, 512], + head_dim=64, mlp_ratio=4., qkv_bias=True, qk_scale=None, representation_size=None, + drop_rate=0., attn_drop_rate=0., drop_path_rate=0., norm_layer=partial(nn.LayerNorm, eps=1e-6), + pretrained_path=None, use_checkpoint=False, checkpoint_num=[0, 0, 0, 0], + windows=False, hybrid=False, window_size=14): + """ + Args: + layer (list): number of block in each layer + img_size (int, tuple): input image size + in_chans (int): number of input channels + num_classes (int): number of classes for classification head + embed_dim (int): embedding dimension + head_dim (int): dimension of attention heads + mlp_ratio (int): ratio of mlp hidden dim to embedding dim + qkv_bias (bool): enable bias for qkv if True + qk_scale (float): override default qk scale of head_dim ** -0.5 if set + representation_size (Optional[int]): enable and set representation layer (pre-logits) to this value if set + drop_rate (float): dropout rate + attn_drop_rate (float): attention dropout rate + drop_path_rate (float): stochastic depth rate + norm_layer (nn.Module): normalization layer + pretrained_path (str): path of pretrained model + use_checkpoint (bool): whether use checkpoint + checkpoint_num (list): index for using checkpoint in every stage + windows (bool): whether use window MHRA + hybrid (bool): whether use hybrid MHRA + window_size (int): size of window (>14) + """ + super().__init__() + self.num_classes = num_classes + self.use_checkpoint = use_checkpoint + self.checkpoint_num = checkpoint_num + self.windows = windows + print(f'Use Checkpoint: {self.use_checkpoint}') + print(f'Checkpoint Number: {self.checkpoint_num}') + self.num_features = self.embed_dim = embed_dim # num_features for consistency with other models + norm_layer = norm_layer or partial(nn.LayerNorm, eps=1e-6) + + self.patch_embed1 = PatchEmbed( + img_size=img_size, patch_size=4, in_chans=in_chans, embed_dim=embed_dim[0]) + self.patch_embed2 = PatchEmbed( + img_size=img_size // 4, patch_size=2, in_chans=embed_dim[0], embed_dim=embed_dim[1]) + self.patch_embed3 = PatchEmbed( + img_size=img_size // 8, patch_size=2, in_chans=embed_dim[1], embed_dim=embed_dim[2]) + self.patch_embed4 = PatchEmbed( + img_size=img_size // 16, patch_size=2, in_chans=embed_dim[2], embed_dim=embed_dim[3]) + + self.pos_drop = nn.Dropout(p=drop_rate) + dpr = [x.item() for x in torch.linspace(0, drop_path_rate, sum(layers))] # stochastic depth decay rule + num_heads = [dim // head_dim for dim in embed_dim] + self.blocks1 = nn.ModuleList([ + CBlock( + dim=embed_dim[0], num_heads=num_heads[0], mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale, + drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i], norm_layer=norm_layer) + for i in range(layers[0])]) + self.norm1=norm_layer(embed_dim[0]) + self.blocks2 = nn.ModuleList([ + CBlock( + dim=embed_dim[1], num_heads=num_heads[1], mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale, + drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i+layers[0]], norm_layer=norm_layer) + for i in range(layers[1])]) + self.norm2 = norm_layer(embed_dim[1]) + if self.windows: + print('Use local window for all blocks in stage3') + self.blocks3 = nn.ModuleList([ + SABlock_Windows( + dim=embed_dim[2], num_heads=num_heads[2], window_size=window_size, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale, + drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i+layers[0]+layers[1]], norm_layer=norm_layer) + for i in range(layers[2])]) + elif hybrid: + print('Use hybrid window for blocks in stage3') + block3 = [] + for i in range(layers[2]): + if (i + 1) % 4 == 0: + block3.append(SABlock( + dim=embed_dim[2], num_heads=num_heads[2], mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale, + drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i+layers[0]+layers[1]], norm_layer=norm_layer)) + else: + block3.append(SABlock_Windows( + dim=embed_dim[2], num_heads=num_heads[2], window_size=window_size, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale, + drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i+layers[0]+layers[1]], norm_layer=norm_layer)) + self.blocks3 = nn.ModuleList(block3) + else: + print('Use global window for all blocks in stage3') + self.blocks3 = nn.ModuleList([ + SABlock( + dim=embed_dim[2], num_heads=num_heads[2], mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale, + drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i+layers[0]+layers[1]], norm_layer=norm_layer) + for i in range(layers[2])]) + self.norm3 = norm_layer(embed_dim[2]) + self.blocks4 = nn.ModuleList([ + SABlock( + dim=embed_dim[3], num_heads=num_heads[3], mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale, + drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i+layers[0]+layers[1]+layers[2]], norm_layer=norm_layer) + for i in range(layers[3])]) + self.norm4 = norm_layer(embed_dim[3]) + + # Representation layer + if representation_size: + self.num_features = representation_size + self.pre_logits = nn.Sequential(OrderedDict([ + ('fc', nn.Linear(embed_dim, representation_size)), + ('act', nn.Tanh()) + ])) + else: + self.pre_logits = nn.Identity() + + self.apply(self._init_weights) + self.init_weights(pretrained=pretrained_path) + + def init_weights(self, pretrained): + if isinstance(pretrained, str): + logger = get_root_logger() + load_checkpoint(self, pretrained, map_location='cpu', strict=False, logger=logger) + print(f'Load pretrained model from {pretrained}') + def _init_weights(self, m): + if isinstance(m, nn.Linear): + trunc_normal_(m.weight, std=.02) + if isinstance(m, nn.Linear) and m.bias is not None: + nn.init.constant_(m.bias, 0) + elif isinstance(m, nn.LayerNorm): + nn.init.constant_(m.bias, 0) + nn.init.constant_(m.weight, 1.0) + + @torch.jit.ignore + def no_weight_decay(self): + return {'pos_embed', 'cls_token'} + + def get_classifier(self): + return self.head + + def reset_classifier(self, num_classes, global_pool=''): + self.num_classes = num_classes + self.head = nn.Linear(self.embed_dim, num_classes) if num_classes > 0 else nn.Identity() + + def forward_features(self, x): + out = [] + x = self.patch_embed1(x) + x = self.pos_drop(x) + for i, blk in enumerate(self.blocks1): + if self.use_checkpoint and i < self.checkpoint_num[0]: + x = checkpoint.checkpoint(blk, x) + else: + x = blk(x) + x_out = self.norm1(x.permute(0, 2, 3, 1)) + out.append(x_out.permute(0, 3, 1, 2).contiguous()) + x = self.patch_embed2(x) + for i, blk in enumerate(self.blocks2): + if self.use_checkpoint and i < self.checkpoint_num[1]: + x = checkpoint.checkpoint(blk, x) + else: + x = blk(x) + x_out = self.norm2(x.permute(0, 2, 3, 1)) + out.append(x_out.permute(0, 3, 1, 2).contiguous()) + x = self.patch_embed3(x) + for i, blk in enumerate(self.blocks3): + if self.use_checkpoint and i < self.checkpoint_num[2]: + x = checkpoint.checkpoint(blk, x) + else: + x = blk(x) + x_out = self.norm3(x.permute(0, 2, 3, 1)) + out.append(x_out.permute(0, 3, 1, 2).contiguous()) + x = self.patch_embed4(x) + for i, blk in enumerate(self.blocks4): + if self.use_checkpoint and i < self.checkpoint_num[3]: + x = checkpoint.checkpoint(blk, x) + else: + x = blk(x) + x_out = self.norm4(x.permute(0, 2, 3, 1)) + out.append(x_out.permute(0, 3, 1, 2).contiguous()) + return tuple(out) + + def forward(self, x): + x = self.forward_features(x) + return x diff --git a/extensions-builtin/sd_forge_controlnet/annotator/uniformer/upernet_global_small.py b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/upernet_global_small.py new file mode 100644 index 00000000..16b14768 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/uniformer/upernet_global_small.py @@ -0,0 +1,44 @@ +_base_ = [ + 'configs/_base_/models/upernet_uniformer.py', + 'configs/_base_/datasets/ade20k.py', + 'configs/_base_/default_runtime.py', + 'configs/_base_/schedules/schedule_160k.py' +] + +custom_imports = dict( + imports=['annotator.uniformer.uniformer'], + allow_failed_imports=False +) + +model = dict( + backbone=dict( + type='UniFormer', + embed_dim=[64, 128, 320, 512], + layers=[3, 4, 8, 3], + head_dim=64, + drop_path_rate=0.25, + windows=False, + hybrid=False + ), + decode_head=dict( + in_channels=[64, 128, 320, 512], + num_classes=150 + ), + auxiliary_head=dict( + in_channels=320, + num_classes=150 + )) + +# AdamW optimizer, no weight decay for position embedding & layer norm in backbone +optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01, + paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.), + 'relative_position_bias_table': dict(decay_mult=0.), + 'norm': dict(decay_mult=0.)})) + +lr_config = dict(_delete_=True, policy='poly', + warmup='linear', + warmup_iters=1500, + warmup_ratio=1e-6, + power=1.0, min_lr=0.0, by_epoch=False) + +data=dict(samples_per_gpu=2) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/util.py b/extensions-builtin/sd_forge_controlnet/annotator/util.py new file mode 100644 index 00000000..7e773045 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/util.py @@ -0,0 +1,79 @@ +import numpy as np +import cv2 +import os + + +def load_model(filename: str, remote_url: str, model_dir: str) -> str: + """ + Load the model from the specified filename and remote URL if it doesn't exist locally. + + Args: + filename (str): The filename of the model. + remote_url (str): The remote URL of the model. + """ + local_path = os.path.join(model_dir, filename) + if not os.path.exists(local_path): + from basicsr.utils.download_util import load_file_from_url + + load_file_from_url(remote_url, model_dir=model_dir) + return local_path + + +def HWC3(x): + assert x.dtype == np.uint8 + if x.ndim == 2: + x = x[:, :, None] + assert x.ndim == 3 + H, W, C = x.shape + assert C == 1 or C == 3 or C == 4 + if C == 3: + return x + if C == 1: + return np.concatenate([x, x, x], axis=2) + if C == 4: + color = x[:, :, 0:3].astype(np.float32) + alpha = x[:, :, 3:4].astype(np.float32) / 255.0 + y = color * alpha + 255.0 * (1.0 - alpha) + y = y.clip(0, 255).astype(np.uint8) + return y + + +def make_noise_disk(H, W, C, F): + noise = np.random.uniform(low=0, high=1, size=((H // F) + 2, (W // F) + 2, C)) + noise = cv2.resize(noise, (W + 2 * F, H + 2 * F), interpolation=cv2.INTER_CUBIC) + noise = noise[F: F + H, F: F + W] + noise -= np.min(noise) + noise /= np.max(noise) + if C == 1: + noise = noise[:, :, None] + return noise + + +def nms(x, t, s): + x = cv2.GaussianBlur(x.astype(np.float32), (0, 0), s) + + f1 = np.array([[0, 0, 0], [1, 1, 1], [0, 0, 0]], dtype=np.uint8) + f2 = np.array([[0, 1, 0], [0, 1, 0], [0, 1, 0]], dtype=np.uint8) + f3 = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype=np.uint8) + f4 = np.array([[0, 0, 1], [0, 1, 0], [1, 0, 0]], dtype=np.uint8) + + y = np.zeros_like(x) + + for f in [f1, f2, f3, f4]: + np.putmask(y, cv2.dilate(x, kernel=f) == x, x) + + z = np.zeros_like(y, dtype=np.uint8) + z[y > t] = 255 + return z + + +def min_max_norm(x): + x -= np.min(x) + x /= np.maximum(np.max(x), 1e-5) + return x + + +def safe_step(x, step=2): + y = x.astype(np.float32) * float(step + 1) + y = y.astype(np.int32).astype(np.float32) / float(step) + return y diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/LICENSE b/extensions-builtin/sd_forge_controlnet/annotator/zoe/LICENSE new file mode 100644 index 00000000..7a1e90d0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Intelligent Systems Lab Org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/__init__.py new file mode 100644 index 00000000..49fbf677 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/__init__.py @@ -0,0 +1,59 @@ +import os +import cv2 +import numpy as np +import torch + +from einops import rearrange +from .zoedepth.models.zoedepth.zoedepth_v1 import ZoeDepth +from .zoedepth.utils.config import get_config +from modules import devices +from annotator.annotator_path import models_path + + +class ZoeDetector: + model_dir = os.path.join(models_path, "zoedepth") + + def __init__(self): + self.model = None + self.device = devices.get_device_for("controlnet") + + def load_model(self): + remote_model_path = "https://huggingface.co/lllyasviel/Annotators/resolve/main/ZoeD_M12_N.pt" + modelpath = os.path.join(self.model_dir, "ZoeD_M12_N.pt") + if not os.path.exists(modelpath): + from basicsr.utils.download_util import load_file_from_url + load_file_from_url(remote_model_path, model_dir=self.model_dir) + conf = get_config("zoedepth", "infer") + model = ZoeDepth.build_from_config(conf) + model.load_state_dict(torch.load(modelpath, map_location=model.device)['model']) + model.eval() + self.model = model.to(self.device) + + def unload_model(self): + if self.model is not None: + self.model.cpu() + + def __call__(self, input_image): + if self.model is None: + self.load_model() + self.model.to(self.device) + + assert input_image.ndim == 3 + image_depth = input_image + with torch.no_grad(): + image_depth = torch.from_numpy(image_depth).float().to(self.device) + image_depth = image_depth / 255.0 + image_depth = rearrange(image_depth, 'h w c -> 1 c h w') + depth = self.model.infer(image_depth) + + depth = depth[0, 0].cpu().numpy() + + vmin = np.percentile(depth, 2) + vmax = np.percentile(depth, 85) + + depth -= vmin + depth /= vmax - vmin + depth = 1.0 - depth + depth_image = (depth * 255.0).clip(0, 255).astype(np.uint8) + + return depth_image diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/__init__.py new file mode 100644 index 00000000..5f266879 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/__init__.py @@ -0,0 +1,24 @@ +# MIT License + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/__init__.py new file mode 100644 index 00000000..5f266879 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/__init__.py @@ -0,0 +1,24 @@ +# MIT License + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas.py new file mode 100644 index 00000000..ee660bc9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas.py @@ -0,0 +1,379 @@ +# MIT License +import os + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + +import torch +import torch.nn as nn +import numpy as np +from torchvision.transforms import Normalize + + +def denormalize(x): + """Reverses the imagenet normalization applied to the input. + + Args: + x (torch.Tensor - shape(N,3,H,W)): input tensor + + Returns: + torch.Tensor - shape(N,3,H,W): Denormalized input + """ + mean = torch.Tensor([0.485, 0.456, 0.406]).view(1, 3, 1, 1).to(x.device) + std = torch.Tensor([0.229, 0.224, 0.225]).view(1, 3, 1, 1).to(x.device) + return x * std + mean + +def get_activation(name, bank): + def hook(model, input, output): + bank[name] = output + return hook + + +class Resize(object): + """Resize sample to given size (width, height). + """ + + def __init__( + self, + width, + height, + resize_target=True, + keep_aspect_ratio=False, + ensure_multiple_of=1, + resize_method="lower_bound", + ): + """Init. + Args: + width (int): desired output width + height (int): desired output height + resize_target (bool, optional): + True: Resize the full sample (image, mask, target). + False: Resize image only. + Defaults to True. + keep_aspect_ratio (bool, optional): + True: Keep the aspect ratio of the input sample. + Output sample might not have the given width and height, and + resize behaviour depends on the parameter 'resize_method'. + Defaults to False. + ensure_multiple_of (int, optional): + Output width and height is constrained to be multiple of this parameter. + Defaults to 1. + resize_method (str, optional): + "lower_bound": Output will be at least as large as the given size. + "upper_bound": Output will be at max as large as the given size. (Output size might be smaller than given size.) + "minimal": Scale as least as possible. (Output size might be smaller than given size.) + Defaults to "lower_bound". + """ + print("Params passed to Resize transform:") + print("\twidth: ", width) + print("\theight: ", height) + print("\tresize_target: ", resize_target) + print("\tkeep_aspect_ratio: ", keep_aspect_ratio) + print("\tensure_multiple_of: ", ensure_multiple_of) + print("\tresize_method: ", resize_method) + + self.__width = width + self.__height = height + + self.__keep_aspect_ratio = keep_aspect_ratio + self.__multiple_of = ensure_multiple_of + self.__resize_method = resize_method + + def constrain_to_multiple_of(self, x, min_val=0, max_val=None): + y = (np.round(x / self.__multiple_of) * self.__multiple_of).astype(int) + + if max_val is not None and y > max_val: + y = (np.floor(x / self.__multiple_of) + * self.__multiple_of).astype(int) + + if y < min_val: + y = (np.ceil(x / self.__multiple_of) + * self.__multiple_of).astype(int) + + return y + + def get_size(self, width, height): + # determine new height and width + scale_height = self.__height / height + scale_width = self.__width / width + + if self.__keep_aspect_ratio: + if self.__resize_method == "lower_bound": + # scale such that output size is lower bound + if scale_width > scale_height: + # fit width + scale_height = scale_width + else: + # fit height + scale_width = scale_height + elif self.__resize_method == "upper_bound": + # scale such that output size is upper bound + if scale_width < scale_height: + # fit width + scale_height = scale_width + else: + # fit height + scale_width = scale_height + elif self.__resize_method == "minimal": + # scale as least as possbile + if abs(1 - scale_width) < abs(1 - scale_height): + # fit width + scale_height = scale_width + else: + # fit height + scale_width = scale_height + else: + raise ValueError( + f"resize_method {self.__resize_method} not implemented" + ) + + if self.__resize_method == "lower_bound": + new_height = self.constrain_to_multiple_of( + scale_height * height, min_val=self.__height + ) + new_width = self.constrain_to_multiple_of( + scale_width * width, min_val=self.__width + ) + elif self.__resize_method == "upper_bound": + new_height = self.constrain_to_multiple_of( + scale_height * height, max_val=self.__height + ) + new_width = self.constrain_to_multiple_of( + scale_width * width, max_val=self.__width + ) + elif self.__resize_method == "minimal": + new_height = self.constrain_to_multiple_of(scale_height * height) + new_width = self.constrain_to_multiple_of(scale_width * width) + else: + raise ValueError( + f"resize_method {self.__resize_method} not implemented") + + return (new_width, new_height) + + def __call__(self, x): + width, height = self.get_size(*x.shape[-2:][::-1]) + return nn.functional.interpolate(x, (height, width), mode='bilinear', align_corners=True) + +class PrepForMidas(object): + def __init__(self, resize_mode="minimal", keep_aspect_ratio=True, img_size=384, do_resize=True): + if isinstance(img_size, int): + img_size = (img_size, img_size) + net_h, net_w = img_size + self.normalization = Normalize( + mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) + self.resizer = Resize(net_w, net_h, keep_aspect_ratio=keep_aspect_ratio, ensure_multiple_of=32, resize_method=resize_mode) \ + if do_resize else nn.Identity() + + def __call__(self, x): + return self.normalization(self.resizer(x)) + + +class MidasCore(nn.Module): + def __init__(self, midas, trainable=False, fetch_features=True, layer_names=('out_conv', 'l4_rn', 'r4', 'r3', 'r2', 'r1'), freeze_bn=False, keep_aspect_ratio=True, + img_size=384, **kwargs): + """Midas Base model used for multi-scale feature extraction. + + Args: + midas (torch.nn.Module): Midas model. + trainable (bool, optional): Train midas model. Defaults to False. + fetch_features (bool, optional): Extract multi-scale features. Defaults to True. + layer_names (tuple, optional): Layers used for feature extraction. Order = (head output features, last layer features, ...decoder features). Defaults to ('out_conv', 'l4_rn', 'r4', 'r3', 'r2', 'r1'). + freeze_bn (bool, optional): Freeze BatchNorm. Generally results in better finetuning performance. Defaults to False. + keep_aspect_ratio (bool, optional): Keep the aspect ratio of input images while resizing. Defaults to True. + img_size (int, tuple, optional): Input resolution. Defaults to 384. + """ + super().__init__() + self.core = midas + self.output_channels = None + self.core_out = {} + self.trainable = trainable + self.fetch_features = fetch_features + # midas.scratch.output_conv = nn.Identity() + self.handles = [] + # self.layer_names = ['out_conv','l4_rn', 'r4', 'r3', 'r2', 'r1'] + self.layer_names = layer_names + + self.set_trainable(trainable) + self.set_fetch_features(fetch_features) + + self.prep = PrepForMidas(keep_aspect_ratio=keep_aspect_ratio, + img_size=img_size, do_resize=kwargs.get('do_resize', True)) + + if freeze_bn: + self.freeze_bn() + + def set_trainable(self, trainable): + self.trainable = trainable + if trainable: + self.unfreeze() + else: + self.freeze() + return self + + def set_fetch_features(self, fetch_features): + self.fetch_features = fetch_features + if fetch_features: + if len(self.handles) == 0: + self.attach_hooks(self.core) + else: + self.remove_hooks() + return self + + def freeze(self): + for p in self.parameters(): + p.requires_grad = False + self.trainable = False + return self + + def unfreeze(self): + for p in self.parameters(): + p.requires_grad = True + self.trainable = True + return self + + def freeze_bn(self): + for m in self.modules(): + if isinstance(m, nn.BatchNorm2d): + m.eval() + return self + + def forward(self, x, denorm=False, return_rel_depth=False): + with torch.no_grad(): + if denorm: + x = denormalize(x) + x = self.prep(x) + # print("Shape after prep: ", x.shape) + + with torch.set_grad_enabled(self.trainable): + + # print("Input size to Midascore", x.shape) + rel_depth = self.core(x) + # print("Output from midas shape", rel_depth.shape) + if not self.fetch_features: + return rel_depth + out = [self.core_out[k] for k in self.layer_names] + + if return_rel_depth: + return rel_depth, out + return out + + def get_rel_pos_params(self): + for name, p in self.core.pretrained.named_parameters(): + if "relative_position" in name: + yield p + + def get_enc_params_except_rel_pos(self): + for name, p in self.core.pretrained.named_parameters(): + if "relative_position" not in name: + yield p + + def freeze_encoder(self, freeze_rel_pos=False): + if freeze_rel_pos: + for p in self.core.pretrained.parameters(): + p.requires_grad = False + else: + for p in self.get_enc_params_except_rel_pos(): + p.requires_grad = False + return self + + def attach_hooks(self, midas): + if len(self.handles) > 0: + self.remove_hooks() + if "out_conv" in self.layer_names: + self.handles.append(list(midas.scratch.output_conv.children())[ + 3].register_forward_hook(get_activation("out_conv", self.core_out))) + if "r4" in self.layer_names: + self.handles.append(midas.scratch.refinenet4.register_forward_hook( + get_activation("r4", self.core_out))) + if "r3" in self.layer_names: + self.handles.append(midas.scratch.refinenet3.register_forward_hook( + get_activation("r3", self.core_out))) + if "r2" in self.layer_names: + self.handles.append(midas.scratch.refinenet2.register_forward_hook( + get_activation("r2", self.core_out))) + if "r1" in self.layer_names: + self.handles.append(midas.scratch.refinenet1.register_forward_hook( + get_activation("r1", self.core_out))) + if "l4_rn" in self.layer_names: + self.handles.append(midas.scratch.layer4_rn.register_forward_hook( + get_activation("l4_rn", self.core_out))) + + return self + + def remove_hooks(self): + for h in self.handles: + h.remove() + return self + + def __del__(self): + self.remove_hooks() + + def set_output_channels(self, model_type): + self.output_channels = MIDAS_SETTINGS[model_type] + + @staticmethod + def build(midas_model_type="DPT_BEiT_L_384", train_midas=False, use_pretrained_midas=True, fetch_features=False, freeze_bn=True, force_keep_ar=False, force_reload=False, **kwargs): + if midas_model_type not in MIDAS_SETTINGS: + raise ValueError( + f"Invalid model type: {midas_model_type}. Must be one of {list(MIDAS_SETTINGS.keys())}") + if "img_size" in kwargs: + kwargs = MidasCore.parse_img_size(kwargs) + img_size = kwargs.pop("img_size", [384, 384]) + print("img_size", img_size) + midas_path = os.path.join(os.path.dirname(__file__), 'midas_repo') + midas = torch.hub.load(midas_path, midas_model_type, + pretrained=use_pretrained_midas, force_reload=force_reload, source='local') + kwargs.update({'keep_aspect_ratio': force_keep_ar}) + midas_core = MidasCore(midas, trainable=train_midas, fetch_features=fetch_features, + freeze_bn=freeze_bn, img_size=img_size, **kwargs) + midas_core.set_output_channels(midas_model_type) + return midas_core + + @staticmethod + def build_from_config(config): + return MidasCore.build(**config) + + @staticmethod + def parse_img_size(config): + assert 'img_size' in config + if isinstance(config['img_size'], str): + assert "," in config['img_size'], "img_size should be a string with comma separated img_size=H,W" + config['img_size'] = list(map(int, config['img_size'].split(","))) + assert len( + config['img_size']) == 2, "img_size should be a string with comma separated img_size=H,W" + elif isinstance(config['img_size'], int): + config['img_size'] = [config['img_size'], config['img_size']] + else: + assert isinstance(config['img_size'], list) and len( + config['img_size']) == 2, "img_size should be a list of H,W" + return config + + +nchannels2models = { + tuple([256]*5): ["DPT_BEiT_L_384", "DPT_BEiT_L_512", "DPT_BEiT_B_384", "DPT_SwinV2_L_384", "DPT_SwinV2_B_384", "DPT_SwinV2_T_256", "DPT_Large", "DPT_Hybrid"], + (512, 256, 128, 64, 64): ["MiDaS_small"] +} + +# Model name to number of output channels +MIDAS_SETTINGS = {m: k for k, v in nchannels2models.items() + for m in v + } diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/.gitignore b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/.gitignore new file mode 100644 index 00000000..a13c8002 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/.gitignore @@ -0,0 +1,110 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +*.png +*.pfm +*.jpg +*.jpeg +*.pt \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/Dockerfile b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/Dockerfile new file mode 100644 index 00000000..466bc94b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/Dockerfile @@ -0,0 +1,29 @@ +# enables cuda support in docker +FROM nvidia/cuda:10.2-cudnn7-runtime-ubuntu18.04 + +# install python 3.6, pip and requirements for opencv-python +# (see https://github.com/NVIDIA/nvidia-docker/issues/864) +RUN apt-get update && apt-get -y install \ + python3 \ + python3-pip \ + libsm6 \ + libxext6 \ + libxrender-dev \ + curl \ + && rm -rf /var/lib/apt/lists/* + +# install python dependencies +RUN pip3 install --upgrade pip +RUN pip3 install torch~=1.8 torchvision opencv-python-headless~=3.4 timm + +# copy inference code +WORKDIR /opt/MiDaS +COPY ./midas ./midas +COPY ./*.py ./ + +# download model weights so the docker image can be used offline +RUN cd weights && {curl -OL https://github.com/isl-org/MiDaS/releases/download/v3/dpt_hybrid_384.pt; cd -; } +RUN python3 run.py --model_type dpt_hybrid; exit 0 + +# entrypoint (dont forget to mount input and output directories) +CMD python3 run.py --model_type dpt_hybrid diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/LICENSE b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/LICENSE new file mode 100644 index 00000000..277b5c11 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Intel ISL (Intel Intelligent Systems Lab) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/README.md b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/README.md new file mode 100644 index 00000000..9568ea71 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/README.md @@ -0,0 +1,259 @@ +## Towards Robust Monocular Depth Estimation: Mixing Datasets for Zero-shot Cross-dataset Transfer + +This repository contains code to compute depth from a single image. It accompanies our [paper](https://arxiv.org/abs/1907.01341v3): + +>Towards Robust Monocular Depth Estimation: Mixing Datasets for Zero-shot Cross-dataset Transfer +René Ranftl, Katrin Lasinger, David Hafner, Konrad Schindler, Vladlen Koltun + + +and our [preprint](https://arxiv.org/abs/2103.13413): + +> Vision Transformers for Dense Prediction +> René Ranftl, Alexey Bochkovskiy, Vladlen Koltun + + +MiDaS was trained on up to 12 datasets (ReDWeb, DIML, Movies, MegaDepth, WSVD, TartanAir, HRWSI, ApolloScape, BlendedMVS, IRS, KITTI, NYU Depth V2) with +multi-objective optimization. +The original model that was trained on 5 datasets (`MIX 5` in the paper) can be found [here](https://github.com/isl-org/MiDaS/releases/tag/v2). +The figure below shows an overview of the different MiDaS models; the bubble size scales with number of parameters. + +![](figures/Improvement_vs_FPS.png) + +### Setup + +1) Pick one or more models and download the corresponding weights to the `weights` folder: + +MiDaS 3.1 +- For highest quality: [dpt_beit_large_512](https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_beit_large_512.pt) +- For moderately less quality, but better speed-performance trade-off: [dpt_swin2_large_384](https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_swin2_large_384.pt) +- For embedded devices: [dpt_swin2_tiny_256](https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_swin2_tiny_256.pt), [dpt_levit_224](https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_levit_224.pt) +- For inference on Intel CPUs, OpenVINO may be used for the small legacy model: openvino_midas_v21_small [.xml](https://github.com/isl-org/MiDaS/releases/download/v3_1/openvino_midas_v21_small_256.xml), [.bin](https://github.com/isl-org/MiDaS/releases/download/v3_1/openvino_midas_v21_small_256.bin) + +MiDaS 3.0: Legacy transformer models [dpt_large_384](https://github.com/isl-org/MiDaS/releases/download/v3/dpt_large_384.pt) and [dpt_hybrid_384](https://github.com/isl-org/MiDaS/releases/download/v3/dpt_hybrid_384.pt) + +MiDaS 2.1: Legacy convolutional models [midas_v21_384](https://github.com/isl-org/MiDaS/releases/download/v2_1/midas_v21_384.pt) and [midas_v21_small_256](https://github.com/isl-org/MiDaS/releases/download/v2_1/midas_v21_small_256.pt) + +1) Set up dependencies: + + ```shell + conda env create -f environment.yaml + conda activate midas-py310 + ``` + +#### optional + +For the Next-ViT model, execute + +```shell +git submodule add https://github.com/isl-org/Next-ViT midas/external/next_vit +``` + +For the OpenVINO model, install + +```shell +pip install openvino +``` + +### Usage + +1) Place one or more input images in the folder `input`. + +2) Run the model with + + ```shell + python run.py --model_type --input_path input --output_path output + ``` + where `````` is chosen from [dpt_beit_large_512](#model_type), [dpt_beit_large_384](#model_type), + [dpt_beit_base_384](#model_type), [dpt_swin2_large_384](#model_type), [dpt_swin2_base_384](#model_type), + [dpt_swin2_tiny_256](#model_type), [dpt_swin_large_384](#model_type), [dpt_next_vit_large_384](#model_type), + [dpt_levit_224](#model_type), [dpt_large_384](#model_type), [dpt_hybrid_384](#model_type), + [midas_v21_384](#model_type), [midas_v21_small_256](#model_type), [openvino_midas_v21_small_256](#model_type). + +3) The resulting depth maps are written to the `output` folder. + +#### optional + +1) By default, the inference resizes the height of input images to the size of a model to fit into the encoder. This + size is given by the numbers in the model names of the [accuracy table](#accuracy). Some models do not only support a single + inference height but a range of different heights. Feel free to explore different heights by appending the extra + command line argument `--height`. Unsupported height values will throw an error. Note that using this argument may + decrease the model accuracy. +2) By default, the inference keeps the aspect ratio of input images when feeding them into the encoder if this is + supported by a model (all models except for Swin, Swin2, LeViT). In order to resize to a square resolution, + disregarding the aspect ratio while preserving the height, use the command line argument `--square`. + +#### via Camera + + If you want the input images to be grabbed from the camera and shown in a window, leave the input and output paths + away and choose a model type as shown above: + + ```shell + python run.py --model_type --side + ``` + + The argument `--side` is optional and causes both the input RGB image and the output depth map to be shown + side-by-side for comparison. + +#### via Docker + +1) Make sure you have installed Docker and the + [NVIDIA Docker runtime](https://github.com/NVIDIA/nvidia-docker/wiki/Installation-\(Native-GPU-Support\)). + +2) Build the Docker image: + + ```shell + docker build -t midas . + ``` + +3) Run inference: + + ```shell + docker run --rm --gpus all -v $PWD/input:/opt/MiDaS/input -v $PWD/output:/opt/MiDaS/output -v $PWD/weights:/opt/MiDaS/weights midas + ``` + + This command passes through all of your NVIDIA GPUs to the container, mounts the + `input` and `output` directories and then runs the inference. + +#### via PyTorch Hub + +The pretrained model is also available on [PyTorch Hub](https://pytorch.org/hub/intelisl_midas_v2/) + +#### via TensorFlow or ONNX + +See [README](https://github.com/isl-org/MiDaS/tree/master/tf) in the `tf` subdirectory. + +Currently only supports MiDaS v2.1. + + +#### via Mobile (iOS / Android) + +See [README](https://github.com/isl-org/MiDaS/tree/master/mobile) in the `mobile` subdirectory. + +#### via ROS1 (Robot Operating System) + +See [README](https://github.com/isl-org/MiDaS/tree/master/ros) in the `ros` subdirectory. + +Currently only supports MiDaS v2.1. DPT-based models to be added. + + +### Accuracy + +We provide a **zero-shot error** $\epsilon_d$ which is evaluated for 6 different datasets +(see [paper](https://arxiv.org/abs/1907.01341v3)). **Lower error values are better**. +$\color{green}{\textsf{Overall model quality is represented by the improvement}}$ ([Imp.](#improvement)) with respect to +MiDaS 3.0 DPTL-384. The models are grouped by the height used for inference, whereas the square training resolution is given by +the numbers in the model names. The table also shows the **number of parameters** (in millions) and the +**frames per second** for inference at the training resolution (for GPU RTX 3090): + +| MiDaS Model | DIW
WHDR | Eth3d
AbsRel | Sintel
AbsRel | TUM
δ1 | KITTI
δ1 | NYUv2
δ1 | $\color{green}{\textsf{Imp.}}$
% | Par.
M | FPS
  | +|-----------------------------------------------------------------------------------------------------------------------|-------------------------:|-----------------------------:|------------------------------:|-------------------------:|-------------------------:|-------------------------:|-------------------------------------------------:|----------------------:|--------------------------:| +| **Inference height 512** | | | | | | | | | | +| [v3.1 BEiTL-512](https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_beit_large_512.pt) | 0.1137 | 0.0659 | 0.2366 | **6.13** | 11.56* | **1.86*** | $\color{green}{\textsf{19}}$ | **345** | **5.7** | +| [v3.1 BEiTL-512](https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_beit_large_512.pt)$\tiny{\square}$ | **0.1121** | **0.0614** | **0.2090** | 6.46 | **5.00*** | 1.90* | $\color{green}{\textsf{34}}$ | **345** | **5.7** | +| | | | | | | | | | | +| **Inference height 384** | | | | | | | | | | +| [v3.1 BEiTL-512](https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_beit_large_512.pt) | 0.1245 | 0.0681 | **0.2176** | **6.13** | 6.28* | **2.16*** | $\color{green}{\textsf{28}}$ | 345 | 12 | +| [v3.1 Swin2L-384](https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_swin2_large_384.pt)$\tiny{\square}$ | 0.1106 | 0.0732 | 0.2442 | 8.87 | **5.84*** | 2.92* | $\color{green}{\textsf{22}}$ | 213 | 41 | +| [v3.1 Swin2B-384](https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_swin2_base_384.pt)$\tiny{\square}$ | 0.1095 | 0.0790 | 0.2404 | 8.93 | 5.97* | 3.28* | $\color{green}{\textsf{22}}$ | 102 | 39 | +| [v3.1 SwinL-384](https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_swin_large_384.pt)$\tiny{\square}$ | 0.1126 | 0.0853 | 0.2428 | 8.74 | 6.60* | 3.34* | $\color{green}{\textsf{17}}$ | 213 | 49 | +| [v3.1 BEiTL-384](https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_beit_large_384.pt) | 0.1239 | **0.0667** | 0.2545 | 7.17 | 9.84* | 2.21* | $\color{green}{\textsf{17}}$ | 344 | 13 | +| [v3.1 Next-ViTL-384](https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_next_vit_large_384.pt) | **0.1031** | 0.0954 | 0.2295 | 9.21 | 6.89* | 3.47* | $\color{green}{\textsf{16}}$ | **72** | 30 | +| [v3.1 BEiTB-384](https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_beit_base_384.pt) | 0.1159 | 0.0967 | 0.2901 | 9.88 | 26.60* | 3.91* | $\color{green}{\textsf{-31}}$ | 112 | 31 | +| [v3.0 DPTL-384](https://github.com/isl-org/MiDaS/releases/download/v3/dpt_large_384.pt) | 0.1082 | 0.0888 | 0.2697 | 9.97 | 8.46 | 8.32 | $\color{green}{\textsf{0}}$ | 344 | **61** | +| [v3.0 DPTH-384](https://github.com/isl-org/MiDaS/releases/download/v3/dpt_hybrid_384.pt) | 0.1106 | 0.0934 | 0.2741 | 10.89 | 11.56 | 8.69 | $\color{green}{\textsf{-10}}$ | 123 | 50 | +| [v2.1 Large384](https://github.com/isl-org/MiDaS/releases/download/v2_1/midas_v21_384.pt) | 0.1295 | 0.1155 | 0.3285 | 12.51 | 16.08 | 8.71 | $\color{green}{\textsf{-32}}$ | 105 | 47 | +| | | | | | | | | | | +| **Inference height 256** | | | | | | | | | | +| [v3.1 Swin2T-256](https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_swin2_tiny_256.pt)$\tiny{\square}$ | **0.1211** | **0.1106** | **0.2868** | **13.43** | **10.13*** | **5.55*** | $\color{green}{\textsf{-11}}$ | 42 | 64 | +| [v2.1 Small256](https://github.com/isl-org/MiDaS/releases/download/v2_1/midas_v21_small_256.pt) | 0.1344 | 0.1344 | 0.3370 | 14.53 | 29.27 | 13.43 | $\color{green}{\textsf{-76}}$ | **21** | **90** | +| | | | | | | | | | | +| **Inference height 224** | | | | | | | | | | +| [v3.1 LeViT224](https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_levit_224.pt)$\tiny{\square}$ | **0.1314** | **0.1206** | **0.3148** | **18.21** | **15.27*** | **8.64*** | $\color{green}{\textsf{-40}}$ | **51** | **73** | + +* No zero-shot error, because models are also trained on KITTI and NYU Depth V2\ +$\square$ Validation performed at **square resolution**, either because the transformer encoder backbone of a model +does not support non-square resolutions (Swin, Swin2, LeViT) or for comparison with these models. All other +validations keep the aspect ratio. A difference in resolution limits the comparability of the zero-shot error and the +improvement, because these quantities are averages over the pixels of an image and do not take into account the +advantage of more details due to a higher resolution.\ +Best values per column and same validation height in bold + +#### Improvement + +The improvement in the above table is defined as the relative zero-shot error with respect to MiDaS v3.0 +DPTL-384 and averaging over the datasets. So, if $\epsilon_d$ is the zero-shot error for dataset $d$, then +the $\color{green}{\textsf{improvement}}$ is given by $100(1-(1/6)\sum_d\epsilon_d/\epsilon_{d,\rm{DPT_{L-384}}})$%. + +Note that the improvements of 10% for MiDaS v2.0 → v2.1 and 21% for MiDaS v2.1 → v3.0 are not visible from the +improvement column (Imp.) in the table but would require an evaluation with respect to MiDaS v2.1 Large384 +and v2.0 Large384 respectively instead of v3.0 DPTL-384. + +### Depth map comparison + +Zoom in for better visibility +![](figures/Comparison.png) + +### Speed on Camera Feed + +Test configuration +- Windows 10 +- 11th Gen Intel Core i7-1185G7 3.00GHz +- 16GB RAM +- Camera resolution 640x480 +- openvino_midas_v21_small_256 + +Speed: 22 FPS + +### Changelog + +* [Dec 2022] Released MiDaS v3.1: + - New models based on 5 different types of transformers ([BEiT](https://arxiv.org/pdf/2106.08254.pdf), [Swin2](https://arxiv.org/pdf/2111.09883.pdf), [Swin](https://arxiv.org/pdf/2103.14030.pdf), [Next-ViT](https://arxiv.org/pdf/2207.05501.pdf), [LeViT](https://arxiv.org/pdf/2104.01136.pdf)) + - Training datasets extended from 10 to 12, including also KITTI and NYU Depth V2 using [BTS](https://github.com/cleinc/bts) split + - Best model, BEiTLarge 512, with resolution 512x512, is on average about [28% more accurate](#Accuracy) than MiDaS v3.0 + - Integrated live depth estimation from camera feed +* [Sep 2021] Integrated to [Huggingface Spaces](https://huggingface.co/spaces) with [Gradio](https://github.com/gradio-app/gradio). See [Gradio Web Demo](https://huggingface.co/spaces/akhaliq/DPT-Large). +* [Apr 2021] Released MiDaS v3.0: + - New models based on [Dense Prediction Transformers](https://arxiv.org/abs/2103.13413) are on average [21% more accurate](#Accuracy) than MiDaS v2.1 + - Additional models can be found [here](https://github.com/isl-org/DPT) +* [Nov 2020] Released MiDaS v2.1: + - New model that was trained on 10 datasets and is on average about [10% more accurate](#Accuracy) than [MiDaS v2.0](https://github.com/isl-org/MiDaS/releases/tag/v2) + - New light-weight model that achieves [real-time performance](https://github.com/isl-org/MiDaS/tree/master/mobile) on mobile platforms. + - Sample applications for [iOS](https://github.com/isl-org/MiDaS/tree/master/mobile/ios) and [Android](https://github.com/isl-org/MiDaS/tree/master/mobile/android) + - [ROS package](https://github.com/isl-org/MiDaS/tree/master/ros) for easy deployment on robots +* [Jul 2020] Added TensorFlow and ONNX code. Added [online demo](http://35.202.76.57/). +* [Dec 2019] Released new version of MiDaS - the new model is significantly more accurate and robust +* [Jul 2019] Initial release of MiDaS ([Link](https://github.com/isl-org/MiDaS/releases/tag/v1)) + +### Citation + +Please cite our paper if you use this code or any of the models: +``` +@ARTICLE {Ranftl2022, + author = "Ren\'{e} Ranftl and Katrin Lasinger and David Hafner and Konrad Schindler and Vladlen Koltun", + title = "Towards Robust Monocular Depth Estimation: Mixing Datasets for Zero-Shot Cross-Dataset Transfer", + journal = "IEEE Transactions on Pattern Analysis and Machine Intelligence", + year = "2022", + volume = "44", + number = "3" +} +``` + +If you use a DPT-based model, please also cite: + +``` +@article{Ranftl2021, + author = {Ren\'{e} Ranftl and Alexey Bochkovskiy and Vladlen Koltun}, + title = {Vision Transformers for Dense Prediction}, + journal = {ICCV}, + year = {2021}, +} +``` + +### Acknowledgements + +Our work builds on and uses code from [timm](https://github.com/rwightman/pytorch-image-models) and [Next-ViT](https://github.com/bytedance/Next-ViT). +We'd like to thank the authors for making these libraries available. + +### License + +MIT License diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/environment.yaml b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/environment.yaml new file mode 100644 index 00000000..b9abe569 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/environment.yaml @@ -0,0 +1,16 @@ +name: midas-py310 +channels: + - pytorch + - defaults +dependencies: + - nvidia::cudatoolkit=11.7 + - python=3.10.8 + - pytorch::pytorch=1.13.0 + - torchvision=0.14.0 + - pip=22.3.1 + - numpy=1.23.4 + - pip: + - opencv-python==4.6.0.66 + - imutils==0.5.4 + - timm==0.6.12 + - einops==0.6.0 \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/hubconf.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/hubconf.py new file mode 100644 index 00000000..0d638be5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/hubconf.py @@ -0,0 +1,435 @@ +dependencies = ["torch"] + +import torch + +from midas.dpt_depth import DPTDepthModel +from midas.midas_net import MidasNet +from midas.midas_net_custom import MidasNet_small + +def DPT_BEiT_L_512(pretrained=True, **kwargs): + """ # This docstring shows up in hub.help() + MiDaS DPT_BEiT_L_512 model for monocular depth estimation + pretrained (bool): load pretrained weights into model + """ + + model = DPTDepthModel( + path=None, + backbone="beitl16_512", + non_negative=True, + ) + + if pretrained: + checkpoint = ( + "https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_beit_large_512.pt" + ) + state_dict = torch.hub.load_state_dict_from_url( + checkpoint, map_location=torch.device('cpu'), progress=True, check_hash=True + ) + model.load_state_dict(state_dict) + + return model + +def DPT_BEiT_L_384(pretrained=True, **kwargs): + """ # This docstring shows up in hub.help() + MiDaS DPT_BEiT_L_384 model for monocular depth estimation + pretrained (bool): load pretrained weights into model + """ + + model = DPTDepthModel( + path=None, + backbone="beitl16_384", + non_negative=True, + ) + + if pretrained: + checkpoint = ( + "https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_beit_large_384.pt" + ) + state_dict = torch.hub.load_state_dict_from_url( + checkpoint, map_location=torch.device('cpu'), progress=True, check_hash=True + ) + model.load_state_dict(state_dict) + + return model + +def DPT_BEiT_B_384(pretrained=True, **kwargs): + """ # This docstring shows up in hub.help() + MiDaS DPT_BEiT_B_384 model for monocular depth estimation + pretrained (bool): load pretrained weights into model + """ + + model = DPTDepthModel( + path=None, + backbone="beitb16_384", + non_negative=True, + ) + + if pretrained: + checkpoint = ( + "https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_beit_base_384.pt" + ) + state_dict = torch.hub.load_state_dict_from_url( + checkpoint, map_location=torch.device('cpu'), progress=True, check_hash=True + ) + model.load_state_dict(state_dict) + + return model + +def DPT_SwinV2_L_384(pretrained=True, **kwargs): + """ # This docstring shows up in hub.help() + MiDaS DPT_SwinV2_L_384 model for monocular depth estimation + pretrained (bool): load pretrained weights into model + """ + + model = DPTDepthModel( + path=None, + backbone="swin2l24_384", + non_negative=True, + ) + + if pretrained: + checkpoint = ( + "https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_swin2_large_384.pt" + ) + state_dict = torch.hub.load_state_dict_from_url( + checkpoint, map_location=torch.device('cpu'), progress=True, check_hash=True + ) + model.load_state_dict(state_dict) + + return model + +def DPT_SwinV2_B_384(pretrained=True, **kwargs): + """ # This docstring shows up in hub.help() + MiDaS DPT_SwinV2_B_384 model for monocular depth estimation + pretrained (bool): load pretrained weights into model + """ + + model = DPTDepthModel( + path=None, + backbone="swin2b24_384", + non_negative=True, + ) + + if pretrained: + checkpoint = ( + "https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_swin2_base_384.pt" + ) + state_dict = torch.hub.load_state_dict_from_url( + checkpoint, map_location=torch.device('cpu'), progress=True, check_hash=True + ) + model.load_state_dict(state_dict) + + return model + +def DPT_SwinV2_T_256(pretrained=True, **kwargs): + """ # This docstring shows up in hub.help() + MiDaS DPT_SwinV2_T_256 model for monocular depth estimation + pretrained (bool): load pretrained weights into model + """ + + model = DPTDepthModel( + path=None, + backbone="swin2t16_256", + non_negative=True, + ) + + if pretrained: + checkpoint = ( + "https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_swin2_tiny_256.pt" + ) + state_dict = torch.hub.load_state_dict_from_url( + checkpoint, map_location=torch.device('cpu'), progress=True, check_hash=True + ) + model.load_state_dict(state_dict) + + return model + +def DPT_Swin_L_384(pretrained=True, **kwargs): + """ # This docstring shows up in hub.help() + MiDaS DPT_Swin_L_384 model for monocular depth estimation + pretrained (bool): load pretrained weights into model + """ + + model = DPTDepthModel( + path=None, + backbone="swinl12_384", + non_negative=True, + ) + + if pretrained: + checkpoint = ( + "https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_swin_large_384.pt" + ) + state_dict = torch.hub.load_state_dict_from_url( + checkpoint, map_location=torch.device('cpu'), progress=True, check_hash=True + ) + model.load_state_dict(state_dict) + + return model + +def DPT_Next_ViT_L_384(pretrained=True, **kwargs): + """ # This docstring shows up in hub.help() + MiDaS DPT_Next_ViT_L_384 model for monocular depth estimation + pretrained (bool): load pretrained weights into model + """ + + model = DPTDepthModel( + path=None, + backbone="next_vit_large_6m", + non_negative=True, + ) + + if pretrained: + checkpoint = ( + "https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_next_vit_large_384.pt" + ) + state_dict = torch.hub.load_state_dict_from_url( + checkpoint, map_location=torch.device('cpu'), progress=True, check_hash=True + ) + model.load_state_dict(state_dict) + + return model + +def DPT_LeViT_224(pretrained=True, **kwargs): + """ # This docstring shows up in hub.help() + MiDaS DPT_LeViT_224 model for monocular depth estimation + pretrained (bool): load pretrained weights into model + """ + + model = DPTDepthModel( + path=None, + backbone="levit_384", + non_negative=True, + head_features_1=64, + head_features_2=8, + ) + + if pretrained: + checkpoint = ( + "https://github.com/isl-org/MiDaS/releases/download/v3_1/dpt_levit_224.pt" + ) + state_dict = torch.hub.load_state_dict_from_url( + checkpoint, map_location=torch.device('cpu'), progress=True, check_hash=True + ) + model.load_state_dict(state_dict) + + return model + +def DPT_Large(pretrained=True, **kwargs): + """ # This docstring shows up in hub.help() + MiDaS DPT-Large model for monocular depth estimation + pretrained (bool): load pretrained weights into model + """ + + model = DPTDepthModel( + path=None, + backbone="vitl16_384", + non_negative=True, + ) + + if pretrained: + checkpoint = ( + "https://github.com/isl-org/MiDaS/releases/download/v3/dpt_large_384.pt" + ) + state_dict = torch.hub.load_state_dict_from_url( + checkpoint, map_location=torch.device('cpu'), progress=True, check_hash=True + ) + model.load_state_dict(state_dict) + + return model + +def DPT_Hybrid(pretrained=True, **kwargs): + """ # This docstring shows up in hub.help() + MiDaS DPT-Hybrid model for monocular depth estimation + pretrained (bool): load pretrained weights into model + """ + + model = DPTDepthModel( + path=None, + backbone="vitb_rn50_384", + non_negative=True, + ) + + if pretrained: + checkpoint = ( + "https://github.com/isl-org/MiDaS/releases/download/v3/dpt_hybrid_384.pt" + ) + state_dict = torch.hub.load_state_dict_from_url( + checkpoint, map_location=torch.device('cpu'), progress=True, check_hash=True + ) + model.load_state_dict(state_dict) + + return model + +def MiDaS(pretrained=True, **kwargs): + """ # This docstring shows up in hub.help() + MiDaS v2.1 model for monocular depth estimation + pretrained (bool): load pretrained weights into model + """ + + model = MidasNet() + + if pretrained: + checkpoint = ( + "https://github.com/isl-org/MiDaS/releases/download/v2_1/midas_v21_384.pt" + ) + state_dict = torch.hub.load_state_dict_from_url( + checkpoint, map_location=torch.device('cpu'), progress=True, check_hash=True + ) + model.load_state_dict(state_dict) + + return model + +def MiDaS_small(pretrained=True, **kwargs): + """ # This docstring shows up in hub.help() + MiDaS v2.1 small model for monocular depth estimation on resource-constrained devices + pretrained (bool): load pretrained weights into model + """ + + model = MidasNet_small(None, features=64, backbone="efficientnet_lite3", exportable=True, non_negative=True, blocks={'expand': True}) + + if pretrained: + checkpoint = ( + "https://github.com/isl-org/MiDaS/releases/download/v2_1/midas_v21_small_256.pt" + ) + state_dict = torch.hub.load_state_dict_from_url( + checkpoint, map_location=torch.device('cpu'), progress=True, check_hash=True + ) + model.load_state_dict(state_dict) + + return model + + +def transforms(): + import cv2 + from torchvision.transforms import Compose + from midas.transforms import Resize, NormalizeImage, PrepareForNet + from midas import transforms + + transforms.default_transform = Compose( + [ + lambda img: {"image": img / 255.0}, + Resize( + 384, + 384, + resize_target=None, + keep_aspect_ratio=True, + ensure_multiple_of=32, + resize_method="upper_bound", + image_interpolation_method=cv2.INTER_CUBIC, + ), + NormalizeImage(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), + PrepareForNet(), + lambda sample: torch.from_numpy(sample["image"]).unsqueeze(0), + ] + ) + + transforms.small_transform = Compose( + [ + lambda img: {"image": img / 255.0}, + Resize( + 256, + 256, + resize_target=None, + keep_aspect_ratio=True, + ensure_multiple_of=32, + resize_method="upper_bound", + image_interpolation_method=cv2.INTER_CUBIC, + ), + NormalizeImage(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), + PrepareForNet(), + lambda sample: torch.from_numpy(sample["image"]).unsqueeze(0), + ] + ) + + transforms.dpt_transform = Compose( + [ + lambda img: {"image": img / 255.0}, + Resize( + 384, + 384, + resize_target=None, + keep_aspect_ratio=True, + ensure_multiple_of=32, + resize_method="minimal", + image_interpolation_method=cv2.INTER_CUBIC, + ), + NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]), + PrepareForNet(), + lambda sample: torch.from_numpy(sample["image"]).unsqueeze(0), + ] + ) + + transforms.beit512_transform = Compose( + [ + lambda img: {"image": img / 255.0}, + Resize( + 512, + 512, + resize_target=None, + keep_aspect_ratio=True, + ensure_multiple_of=32, + resize_method="minimal", + image_interpolation_method=cv2.INTER_CUBIC, + ), + NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]), + PrepareForNet(), + lambda sample: torch.from_numpy(sample["image"]).unsqueeze(0), + ] + ) + + transforms.swin384_transform = Compose( + [ + lambda img: {"image": img / 255.0}, + Resize( + 384, + 384, + resize_target=None, + keep_aspect_ratio=False, + ensure_multiple_of=32, + resize_method="minimal", + image_interpolation_method=cv2.INTER_CUBIC, + ), + NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]), + PrepareForNet(), + lambda sample: torch.from_numpy(sample["image"]).unsqueeze(0), + ] + ) + + transforms.swin256_transform = Compose( + [ + lambda img: {"image": img / 255.0}, + Resize( + 256, + 256, + resize_target=None, + keep_aspect_ratio=False, + ensure_multiple_of=32, + resize_method="minimal", + image_interpolation_method=cv2.INTER_CUBIC, + ), + NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]), + PrepareForNet(), + lambda sample: torch.from_numpy(sample["image"]).unsqueeze(0), + ] + ) + + transforms.levit_transform = Compose( + [ + lambda img: {"image": img / 255.0}, + Resize( + 224, + 224, + resize_target=None, + keep_aspect_ratio=False, + ensure_multiple_of=32, + resize_method="minimal", + image_interpolation_method=cv2.INTER_CUBIC, + ), + NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]), + PrepareForNet(), + lambda sample: torch.from_numpy(sample["image"]).unsqueeze(0), + ] + ) + + return transforms diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/input/.placeholder b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/input/.placeholder new file mode 100644 index 00000000..e69de29b diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/beit.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/beit.py new file mode 100644 index 00000000..1a898086 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/beit.py @@ -0,0 +1,198 @@ +import timm +import torch +import types + +import numpy as np +import torch.nn.functional as F + +from .utils import forward_adapted_unflatten, make_backbone_default +from timm.models.beit import gen_relative_position_index +from torch.utils.checkpoint import checkpoint +from typing import Optional + + +def forward_beit(pretrained, x): + return forward_adapted_unflatten(pretrained, x, "forward_features") + + +def patch_embed_forward(self, x): + """ + Modification of timm.models.layers.patch_embed.py: PatchEmbed.forward to support arbitrary window sizes. + """ + x = self.proj(x) + if self.flatten: + x = x.flatten(2).transpose(1, 2) + x = self.norm(x) + return x + + +def _get_rel_pos_bias(self, window_size): + """ + Modification of timm.models.beit.py: Attention._get_rel_pos_bias to support arbitrary window sizes. + """ + old_height = 2 * self.window_size[0] - 1 + old_width = 2 * self.window_size[1] - 1 + + new_height = 2 * window_size[0] - 1 + new_width = 2 * window_size[1] - 1 + + old_relative_position_bias_table = self.relative_position_bias_table + + old_num_relative_distance = self.num_relative_distance + new_num_relative_distance = new_height * new_width + 3 + + old_sub_table = old_relative_position_bias_table[:old_num_relative_distance - 3] + + old_sub_table = old_sub_table.reshape(1, old_width, old_height, -1).permute(0, 3, 1, 2) + new_sub_table = F.interpolate(old_sub_table, size=(new_height, new_width), mode="bilinear") + new_sub_table = new_sub_table.permute(0, 2, 3, 1).reshape(new_num_relative_distance - 3, -1) + + new_relative_position_bias_table = torch.cat( + [new_sub_table, old_relative_position_bias_table[old_num_relative_distance - 3:]]) + + key = str(window_size[1]) + "," + str(window_size[0]) + if key not in self.relative_position_indices.keys(): + self.relative_position_indices[key] = gen_relative_position_index(window_size) + + relative_position_bias = new_relative_position_bias_table[ + self.relative_position_indices[key].view(-1)].view( + window_size[0] * window_size[1] + 1, + window_size[0] * window_size[1] + 1, -1) # Wh*Ww,Wh*Ww,nH + relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous() # nH, Wh*Ww, Wh*Ww + return relative_position_bias.unsqueeze(0) + + +def attention_forward(self, x, resolution, shared_rel_pos_bias: Optional[torch.Tensor] = None): + """ + Modification of timm.models.beit.py: Attention.forward to support arbitrary window sizes. + """ + B, N, C = x.shape + + qkv_bias = torch.cat((self.q_bias, self.k_bias, self.v_bias)) if self.q_bias is not None else None + qkv = F.linear(input=x, weight=self.qkv.weight, bias=qkv_bias) + qkv = qkv.reshape(B, N, 3, self.num_heads, -1).permute(2, 0, 3, 1, 4) + q, k, v = qkv.unbind(0) # make torchscript happy (cannot use tensor as tuple) + + q = q * self.scale + attn = (q @ k.transpose(-2, -1)) + + if self.relative_position_bias_table is not None: + window_size = tuple(np.array(resolution) // 16) + attn = attn + self._get_rel_pos_bias(window_size) + if shared_rel_pos_bias is not None: + attn = attn + shared_rel_pos_bias + + attn = attn.softmax(dim=-1) + attn = self.attn_drop(attn) + + x = (attn @ v).transpose(1, 2).reshape(B, N, -1) + x = self.proj(x) + x = self.proj_drop(x) + return x + + +def block_forward(self, x, resolution, shared_rel_pos_bias: Optional[torch.Tensor] = None): + """ + Modification of timm.models.beit.py: Block.forward to support arbitrary window sizes. + """ + if hasattr(self, 'drop_path1') and not hasattr(self, 'drop_path'): + self.drop_path = self.drop_path1 + if self.gamma_1 is None: + x = x + self.drop_path(self.attn(self.norm1(x), resolution, shared_rel_pos_bias=shared_rel_pos_bias)) + x = x + self.drop_path(self.mlp(self.norm2(x))) + else: + x = x + self.drop_path(self.gamma_1 * self.attn(self.norm1(x), resolution, + shared_rel_pos_bias=shared_rel_pos_bias)) + x = x + self.drop_path(self.gamma_2 * self.mlp(self.norm2(x))) + return x + + +def beit_forward_features(self, x): + """ + Modification of timm.models.beit.py: Beit.forward_features to support arbitrary window sizes. + """ + resolution = x.shape[2:] + + x = self.patch_embed(x) + x = torch.cat((self.cls_token.expand(x.shape[0], -1, -1), x), dim=1) + if self.pos_embed is not None: + x = x + self.pos_embed + x = self.pos_drop(x) + + rel_pos_bias = self.rel_pos_bias() if self.rel_pos_bias is not None else None + for blk in self.blocks: + if self.grad_checkpointing and not torch.jit.is_scripting(): + x = checkpoint(blk, x, shared_rel_pos_bias=rel_pos_bias) + else: + x = blk(x, resolution, shared_rel_pos_bias=rel_pos_bias) + x = self.norm(x) + return x + + +def _make_beit_backbone( + model, + features=[96, 192, 384, 768], + size=[384, 384], + hooks=[0, 4, 8, 11], + vit_features=768, + use_readout="ignore", + start_index=1, + start_index_readout=1, +): + backbone = make_backbone_default(model, features, size, hooks, vit_features, use_readout, start_index, + start_index_readout) + + backbone.model.patch_embed.forward = types.MethodType(patch_embed_forward, backbone.model.patch_embed) + backbone.model.forward_features = types.MethodType(beit_forward_features, backbone.model) + + for block in backbone.model.blocks: + attn = block.attn + attn._get_rel_pos_bias = types.MethodType(_get_rel_pos_bias, attn) + attn.forward = types.MethodType(attention_forward, attn) + attn.relative_position_indices = {} + + block.forward = types.MethodType(block_forward, block) + + return backbone + + +def _make_pretrained_beitl16_512(pretrained, use_readout="ignore", hooks=None): + model = timm.create_model("beit_large_patch16_512", pretrained=pretrained) + + hooks = [5, 11, 17, 23] if hooks is None else hooks + + features = [256, 512, 1024, 1024] + + return _make_beit_backbone( + model, + features=features, + size=[512, 512], + hooks=hooks, + vit_features=1024, + use_readout=use_readout, + ) + + +def _make_pretrained_beitl16_384(pretrained, use_readout="ignore", hooks=None): + model = timm.create_model("beit_large_patch16_384", pretrained=pretrained) + + hooks = [5, 11, 17, 23] if hooks is None else hooks + return _make_beit_backbone( + model, + features=[256, 512, 1024, 1024], + hooks=hooks, + vit_features=1024, + use_readout=use_readout, + ) + + +def _make_pretrained_beitb16_384(pretrained, use_readout="ignore", hooks=None): + model = timm.create_model("beit_base_patch16_384", pretrained=pretrained) + + hooks = [2, 5, 8, 11] if hooks is None else hooks + return _make_beit_backbone( + model, + features=[96, 192, 384, 768], + hooks=hooks, + use_readout=use_readout, + ) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/levit.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/levit.py new file mode 100644 index 00000000..6d023a98 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/levit.py @@ -0,0 +1,106 @@ +import timm +import torch +import torch.nn as nn +import numpy as np + +from .utils import activations, get_activation, Transpose + + +def forward_levit(pretrained, x): + pretrained.model.forward_features(x) + + layer_1 = pretrained.activations["1"] + layer_2 = pretrained.activations["2"] + layer_3 = pretrained.activations["3"] + + layer_1 = pretrained.act_postprocess1(layer_1) + layer_2 = pretrained.act_postprocess2(layer_2) + layer_3 = pretrained.act_postprocess3(layer_3) + + return layer_1, layer_2, layer_3 + + +def _make_levit_backbone( + model, + hooks=[3, 11, 21], + patch_grid=[14, 14] +): + pretrained = nn.Module() + + pretrained.model = model + pretrained.model.blocks[hooks[0]].register_forward_hook(get_activation("1")) + pretrained.model.blocks[hooks[1]].register_forward_hook(get_activation("2")) + pretrained.model.blocks[hooks[2]].register_forward_hook(get_activation("3")) + + pretrained.activations = activations + + patch_grid_size = np.array(patch_grid, dtype=int) + + pretrained.act_postprocess1 = nn.Sequential( + Transpose(1, 2), + nn.Unflatten(2, torch.Size(patch_grid_size.tolist())) + ) + pretrained.act_postprocess2 = nn.Sequential( + Transpose(1, 2), + nn.Unflatten(2, torch.Size((np.ceil(patch_grid_size / 2).astype(int)).tolist())) + ) + pretrained.act_postprocess3 = nn.Sequential( + Transpose(1, 2), + nn.Unflatten(2, torch.Size((np.ceil(patch_grid_size / 4).astype(int)).tolist())) + ) + + return pretrained + + +class ConvTransposeNorm(nn.Sequential): + """ + Modification of + https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/levit.py: ConvNorm + such that ConvTranspose2d is used instead of Conv2d. + """ + + def __init__( + self, in_chs, out_chs, kernel_size=1, stride=1, pad=0, dilation=1, + groups=1, bn_weight_init=1): + super().__init__() + self.add_module('c', + nn.ConvTranspose2d(in_chs, out_chs, kernel_size, stride, pad, dilation, groups, bias=False)) + self.add_module('bn', nn.BatchNorm2d(out_chs)) + + nn.init.constant_(self.bn.weight, bn_weight_init) + + @torch.no_grad() + def fuse(self): + c, bn = self._modules.values() + w = bn.weight / (bn.running_var + bn.eps) ** 0.5 + w = c.weight * w[:, None, None, None] + b = bn.bias - bn.running_mean * bn.weight / (bn.running_var + bn.eps) ** 0.5 + m = nn.ConvTranspose2d( + w.size(1), w.size(0), w.shape[2:], stride=self.c.stride, + padding=self.c.padding, dilation=self.c.dilation, groups=self.c.groups) + m.weight.data.copy_(w) + m.bias.data.copy_(b) + return m + + +def stem_b4_transpose(in_chs, out_chs, activation): + """ + Modification of + https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/levit.py: stem_b16 + such that ConvTranspose2d is used instead of Conv2d and stem is also reduced to the half. + """ + return nn.Sequential( + ConvTransposeNorm(in_chs, out_chs, 3, 2, 1), + activation(), + ConvTransposeNorm(out_chs, out_chs // 2, 3, 2, 1), + activation()) + + +def _make_pretrained_levit_384(pretrained, hooks=None): + model = timm.create_model("levit_384", pretrained=pretrained) + + hooks = [3, 11, 21] if hooks == None else hooks + return _make_levit_backbone( + model, + hooks=hooks + ) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/next_vit.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/next_vit.py new file mode 100644 index 00000000..8afdd8b7 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/next_vit.py @@ -0,0 +1,39 @@ +import timm + +import torch.nn as nn + +from pathlib import Path +from .utils import activations, forward_default, get_activation + +from ..external.next_vit.classification.nextvit import * + + +def forward_next_vit(pretrained, x): + return forward_default(pretrained, x, "forward") + + +def _make_next_vit_backbone( + model, + hooks=[2, 6, 36, 39], +): + pretrained = nn.Module() + + pretrained.model = model + pretrained.model.features[hooks[0]].register_forward_hook(get_activation("1")) + pretrained.model.features[hooks[1]].register_forward_hook(get_activation("2")) + pretrained.model.features[hooks[2]].register_forward_hook(get_activation("3")) + pretrained.model.features[hooks[3]].register_forward_hook(get_activation("4")) + + pretrained.activations = activations + + return pretrained + + +def _make_pretrained_next_vit_large_6m(hooks=None): + model = timm.create_model("nextvit_large") + + hooks = [2, 6, 36, 39] if hooks == None else hooks + return _make_next_vit_backbone( + model, + hooks=hooks, + ) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/swin.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/swin.py new file mode 100644 index 00000000..f8c71367 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/swin.py @@ -0,0 +1,13 @@ +import timm + +from .swin_common import _make_swin_backbone + + +def _make_pretrained_swinl12_384(pretrained, hooks=None): + model = timm.create_model("swin_large_patch4_window12_384", pretrained=pretrained) + + hooks = [1, 1, 17, 1] if hooks == None else hooks + return _make_swin_backbone( + model, + hooks=hooks + ) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/swin2.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/swin2.py new file mode 100644 index 00000000..ce4c8f1d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/swin2.py @@ -0,0 +1,34 @@ +import timm + +from .swin_common import _make_swin_backbone + + +def _make_pretrained_swin2l24_384(pretrained, hooks=None): + model = timm.create_model("swinv2_large_window12to24_192to384_22kft1k", pretrained=pretrained) + + hooks = [1, 1, 17, 1] if hooks == None else hooks + return _make_swin_backbone( + model, + hooks=hooks + ) + + +def _make_pretrained_swin2b24_384(pretrained, hooks=None): + model = timm.create_model("swinv2_base_window12to24_192to384_22kft1k", pretrained=pretrained) + + hooks = [1, 1, 17, 1] if hooks == None else hooks + return _make_swin_backbone( + model, + hooks=hooks + ) + + +def _make_pretrained_swin2t16_256(pretrained, hooks=None): + model = timm.create_model("swinv2_tiny_window16_256", pretrained=pretrained) + + hooks = [1, 1, 5, 1] if hooks == None else hooks + return _make_swin_backbone( + model, + hooks=hooks, + patch_grid=[64, 64] + ) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/swin_common.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/swin_common.py new file mode 100644 index 00000000..94d63d40 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/swin_common.py @@ -0,0 +1,52 @@ +import torch + +import torch.nn as nn +import numpy as np + +from .utils import activations, forward_default, get_activation, Transpose + + +def forward_swin(pretrained, x): + return forward_default(pretrained, x) + + +def _make_swin_backbone( + model, + hooks=[1, 1, 17, 1], + patch_grid=[96, 96] +): + pretrained = nn.Module() + + pretrained.model = model + pretrained.model.layers[0].blocks[hooks[0]].register_forward_hook(get_activation("1")) + pretrained.model.layers[1].blocks[hooks[1]].register_forward_hook(get_activation("2")) + pretrained.model.layers[2].blocks[hooks[2]].register_forward_hook(get_activation("3")) + pretrained.model.layers[3].blocks[hooks[3]].register_forward_hook(get_activation("4")) + + pretrained.activations = activations + + if hasattr(model, "patch_grid"): + used_patch_grid = model.patch_grid + else: + used_patch_grid = patch_grid + + patch_grid_size = np.array(used_patch_grid, dtype=int) + + pretrained.act_postprocess1 = nn.Sequential( + Transpose(1, 2), + nn.Unflatten(2, torch.Size(patch_grid_size.tolist())) + ) + pretrained.act_postprocess2 = nn.Sequential( + Transpose(1, 2), + nn.Unflatten(2, torch.Size((patch_grid_size // 2).tolist())) + ) + pretrained.act_postprocess3 = nn.Sequential( + Transpose(1, 2), + nn.Unflatten(2, torch.Size((patch_grid_size // 4).tolist())) + ) + pretrained.act_postprocess4 = nn.Sequential( + Transpose(1, 2), + nn.Unflatten(2, torch.Size((patch_grid_size // 8).tolist())) + ) + + return pretrained diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/utils.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/utils.py new file mode 100644 index 00000000..0558899d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/utils.py @@ -0,0 +1,249 @@ +import torch + +import torch.nn as nn + + +class Slice(nn.Module): + def __init__(self, start_index=1): + super(Slice, self).__init__() + self.start_index = start_index + + def forward(self, x): + return x[:, self.start_index:] + + +class AddReadout(nn.Module): + def __init__(self, start_index=1): + super(AddReadout, self).__init__() + self.start_index = start_index + + def forward(self, x): + if self.start_index == 2: + readout = (x[:, 0] + x[:, 1]) / 2 + else: + readout = x[:, 0] + return x[:, self.start_index:] + readout.unsqueeze(1) + + +class ProjectReadout(nn.Module): + def __init__(self, in_features, start_index=1): + super(ProjectReadout, self).__init__() + self.start_index = start_index + + self.project = nn.Sequential(nn.Linear(2 * in_features, in_features), nn.GELU()) + + def forward(self, x): + readout = x[:, 0].unsqueeze(1).expand_as(x[:, self.start_index:]) + features = torch.cat((x[:, self.start_index:], readout), -1) + + return self.project(features) + + +class Transpose(nn.Module): + def __init__(self, dim0, dim1): + super(Transpose, self).__init__() + self.dim0 = dim0 + self.dim1 = dim1 + + def forward(self, x): + x = x.transpose(self.dim0, self.dim1) + return x + + +activations = {} + + +def get_activation(name): + def hook(model, input, output): + activations[name] = output + + return hook + + +def forward_default(pretrained, x, function_name="forward_features"): + exec(f"pretrained.model.{function_name}(x)") + + layer_1 = pretrained.activations["1"] + layer_2 = pretrained.activations["2"] + layer_3 = pretrained.activations["3"] + layer_4 = pretrained.activations["4"] + + if hasattr(pretrained, "act_postprocess1"): + layer_1 = pretrained.act_postprocess1(layer_1) + if hasattr(pretrained, "act_postprocess2"): + layer_2 = pretrained.act_postprocess2(layer_2) + if hasattr(pretrained, "act_postprocess3"): + layer_3 = pretrained.act_postprocess3(layer_3) + if hasattr(pretrained, "act_postprocess4"): + layer_4 = pretrained.act_postprocess4(layer_4) + + return layer_1, layer_2, layer_3, layer_4 + + +def forward_adapted_unflatten(pretrained, x, function_name="forward_features"): + b, c, h, w = x.shape + + exec(f"glob = pretrained.model.{function_name}(x)") + + layer_1 = pretrained.activations["1"] + layer_2 = pretrained.activations["2"] + layer_3 = pretrained.activations["3"] + layer_4 = pretrained.activations["4"] + + layer_1 = pretrained.act_postprocess1[0:2](layer_1) + layer_2 = pretrained.act_postprocess2[0:2](layer_2) + layer_3 = pretrained.act_postprocess3[0:2](layer_3) + layer_4 = pretrained.act_postprocess4[0:2](layer_4) + + unflatten = nn.Sequential( + nn.Unflatten( + 2, + torch.Size( + [ + h // pretrained.model.patch_size[1], + w // pretrained.model.patch_size[0], + ] + ), + ) + ) + + if layer_1.ndim == 3: + layer_1 = unflatten(layer_1) + if layer_2.ndim == 3: + layer_2 = unflatten(layer_2) + if layer_3.ndim == 3: + layer_3 = unflatten(layer_3) + if layer_4.ndim == 3: + layer_4 = unflatten(layer_4) + + layer_1 = pretrained.act_postprocess1[3: len(pretrained.act_postprocess1)](layer_1) + layer_2 = pretrained.act_postprocess2[3: len(pretrained.act_postprocess2)](layer_2) + layer_3 = pretrained.act_postprocess3[3: len(pretrained.act_postprocess3)](layer_3) + layer_4 = pretrained.act_postprocess4[3: len(pretrained.act_postprocess4)](layer_4) + + return layer_1, layer_2, layer_3, layer_4 + + +def get_readout_oper(vit_features, features, use_readout, start_index=1): + if use_readout == "ignore": + readout_oper = [Slice(start_index)] * len(features) + elif use_readout == "add": + readout_oper = [AddReadout(start_index)] * len(features) + elif use_readout == "project": + readout_oper = [ + ProjectReadout(vit_features, start_index) for out_feat in features + ] + else: + assert ( + False + ), "wrong operation for readout token, use_readout can be 'ignore', 'add', or 'project'" + + return readout_oper + + +def make_backbone_default( + model, + features=[96, 192, 384, 768], + size=[384, 384], + hooks=[2, 5, 8, 11], + vit_features=768, + use_readout="ignore", + start_index=1, + start_index_readout=1, +): + pretrained = nn.Module() + + pretrained.model = model + pretrained.model.blocks[hooks[0]].register_forward_hook(get_activation("1")) + pretrained.model.blocks[hooks[1]].register_forward_hook(get_activation("2")) + pretrained.model.blocks[hooks[2]].register_forward_hook(get_activation("3")) + pretrained.model.blocks[hooks[3]].register_forward_hook(get_activation("4")) + + pretrained.activations = activations + + readout_oper = get_readout_oper(vit_features, features, use_readout, start_index_readout) + + # 32, 48, 136, 384 + pretrained.act_postprocess1 = nn.Sequential( + readout_oper[0], + Transpose(1, 2), + nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])), + nn.Conv2d( + in_channels=vit_features, + out_channels=features[0], + kernel_size=1, + stride=1, + padding=0, + ), + nn.ConvTranspose2d( + in_channels=features[0], + out_channels=features[0], + kernel_size=4, + stride=4, + padding=0, + bias=True, + dilation=1, + groups=1, + ), + ) + + pretrained.act_postprocess2 = nn.Sequential( + readout_oper[1], + Transpose(1, 2), + nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])), + nn.Conv2d( + in_channels=vit_features, + out_channels=features[1], + kernel_size=1, + stride=1, + padding=0, + ), + nn.ConvTranspose2d( + in_channels=features[1], + out_channels=features[1], + kernel_size=2, + stride=2, + padding=0, + bias=True, + dilation=1, + groups=1, + ), + ) + + pretrained.act_postprocess3 = nn.Sequential( + readout_oper[2], + Transpose(1, 2), + nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])), + nn.Conv2d( + in_channels=vit_features, + out_channels=features[2], + kernel_size=1, + stride=1, + padding=0, + ), + ) + + pretrained.act_postprocess4 = nn.Sequential( + readout_oper[3], + Transpose(1, 2), + nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])), + nn.Conv2d( + in_channels=vit_features, + out_channels=features[3], + kernel_size=1, + stride=1, + padding=0, + ), + nn.Conv2d( + in_channels=features[3], + out_channels=features[3], + kernel_size=3, + stride=2, + padding=1, + ), + ) + + pretrained.model.start_index = start_index + pretrained.model.patch_size = [16, 16] + + return pretrained diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/vit.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/vit.py new file mode 100644 index 00000000..413f9693 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/backbones/vit.py @@ -0,0 +1,221 @@ +import torch +import torch.nn as nn +import timm +import types +import math +import torch.nn.functional as F + +from .utils import (activations, forward_adapted_unflatten, get_activation, get_readout_oper, + make_backbone_default, Transpose) + + +def forward_vit(pretrained, x): + return forward_adapted_unflatten(pretrained, x, "forward_flex") + + +def _resize_pos_embed(self, posemb, gs_h, gs_w): + posemb_tok, posemb_grid = ( + posemb[:, : self.start_index], + posemb[0, self.start_index:], + ) + + gs_old = int(math.sqrt(len(posemb_grid))) + + posemb_grid = posemb_grid.reshape(1, gs_old, gs_old, -1).permute(0, 3, 1, 2) + posemb_grid = F.interpolate(posemb_grid, size=(gs_h, gs_w), mode="bilinear") + posemb_grid = posemb_grid.permute(0, 2, 3, 1).reshape(1, gs_h * gs_w, -1) + + posemb = torch.cat([posemb_tok, posemb_grid], dim=1) + + return posemb + + +def forward_flex(self, x): + b, c, h, w = x.shape + + pos_embed = self._resize_pos_embed( + self.pos_embed, h // self.patch_size[1], w // self.patch_size[0] + ) + + B = x.shape[0] + + if hasattr(self.patch_embed, "backbone"): + x = self.patch_embed.backbone(x) + if isinstance(x, (list, tuple)): + x = x[-1] # last feature if backbone outputs list/tuple of features + + x = self.patch_embed.proj(x).flatten(2).transpose(1, 2) + + if getattr(self, "dist_token", None) is not None: + cls_tokens = self.cls_token.expand( + B, -1, -1 + ) # stole cls_tokens impl from Phil Wang, thanks + dist_token = self.dist_token.expand(B, -1, -1) + x = torch.cat((cls_tokens, dist_token, x), dim=1) + else: + if self.no_embed_class: + x = x + pos_embed + cls_tokens = self.cls_token.expand( + B, -1, -1 + ) # stole cls_tokens impl from Phil Wang, thanks + x = torch.cat((cls_tokens, x), dim=1) + + if not self.no_embed_class: + x = x + pos_embed + x = self.pos_drop(x) + + for blk in self.blocks: + x = blk(x) + + x = self.norm(x) + + return x + + +def _make_vit_b16_backbone( + model, + features=[96, 192, 384, 768], + size=[384, 384], + hooks=[2, 5, 8, 11], + vit_features=768, + use_readout="ignore", + start_index=1, + start_index_readout=1, +): + pretrained = make_backbone_default(model, features, size, hooks, vit_features, use_readout, start_index, + start_index_readout) + + # We inject this function into the VisionTransformer instances so that + # we can use it with interpolated position embeddings without modifying the library source. + pretrained.model.forward_flex = types.MethodType(forward_flex, pretrained.model) + pretrained.model._resize_pos_embed = types.MethodType( + _resize_pos_embed, pretrained.model + ) + + return pretrained + + +def _make_pretrained_vitl16_384(pretrained, use_readout="ignore", hooks=None): + model = timm.create_model("vit_large_patch16_384", pretrained=pretrained) + + hooks = [5, 11, 17, 23] if hooks == None else hooks + return _make_vit_b16_backbone( + model, + features=[256, 512, 1024, 1024], + hooks=hooks, + vit_features=1024, + use_readout=use_readout, + ) + + +def _make_pretrained_vitb16_384(pretrained, use_readout="ignore", hooks=None): + model = timm.create_model("vit_base_patch16_384", pretrained=pretrained) + + hooks = [2, 5, 8, 11] if hooks == None else hooks + return _make_vit_b16_backbone( + model, features=[96, 192, 384, 768], hooks=hooks, use_readout=use_readout + ) + + +def _make_vit_b_rn50_backbone( + model, + features=[256, 512, 768, 768], + size=[384, 384], + hooks=[0, 1, 8, 11], + vit_features=768, + patch_size=[16, 16], + number_stages=2, + use_vit_only=False, + use_readout="ignore", + start_index=1, +): + pretrained = nn.Module() + + pretrained.model = model + + used_number_stages = 0 if use_vit_only else number_stages + for s in range(used_number_stages): + pretrained.model.patch_embed.backbone.stages[s].register_forward_hook( + get_activation(str(s + 1)) + ) + for s in range(used_number_stages, 4): + pretrained.model.blocks[hooks[s]].register_forward_hook(get_activation(str(s + 1))) + + pretrained.activations = activations + + readout_oper = get_readout_oper(vit_features, features, use_readout, start_index) + + for s in range(used_number_stages): + value = nn.Sequential(nn.Identity(), nn.Identity(), nn.Identity()) + exec(f"pretrained.act_postprocess{s + 1}=value") + for s in range(used_number_stages, 4): + if s < number_stages: + final_layer = nn.ConvTranspose2d( + in_channels=features[s], + out_channels=features[s], + kernel_size=4 // (2 ** s), + stride=4 // (2 ** s), + padding=0, + bias=True, + dilation=1, + groups=1, + ) + elif s > number_stages: + final_layer = nn.Conv2d( + in_channels=features[3], + out_channels=features[3], + kernel_size=3, + stride=2, + padding=1, + ) + else: + final_layer = None + + layers = [ + readout_oper[s], + Transpose(1, 2), + nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])), + nn.Conv2d( + in_channels=vit_features, + out_channels=features[s], + kernel_size=1, + stride=1, + padding=0, + ), + ] + if final_layer is not None: + layers.append(final_layer) + + value = nn.Sequential(*layers) + exec(f"pretrained.act_postprocess{s + 1}=value") + + pretrained.model.start_index = start_index + pretrained.model.patch_size = patch_size + + # We inject this function into the VisionTransformer instances so that + # we can use it with interpolated position embeddings without modifying the library source. + pretrained.model.forward_flex = types.MethodType(forward_flex, pretrained.model) + + # We inject this function into the VisionTransformer instances so that + # we can use it with interpolated position embeddings without modifying the library source. + pretrained.model._resize_pos_embed = types.MethodType( + _resize_pos_embed, pretrained.model + ) + + return pretrained + + +def _make_pretrained_vitb_rn50_384( + pretrained, use_readout="ignore", hooks=None, use_vit_only=False +): + model = timm.create_model("vit_base_resnet50_384", pretrained=pretrained) + + hooks = [0, 1, 8, 11] if hooks == None else hooks + return _make_vit_b_rn50_backbone( + model, + features=[256, 512, 768, 768], + size=[384, 384], + hooks=hooks, + use_vit_only=use_vit_only, + use_readout=use_readout, + ) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/base_model.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/base_model.py new file mode 100644 index 00000000..5cf43023 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/base_model.py @@ -0,0 +1,16 @@ +import torch + + +class BaseModel(torch.nn.Module): + def load(self, path): + """Load model from file. + + Args: + path (str): file path + """ + parameters = torch.load(path, map_location=torch.device('cpu')) + + if "optimizer" in parameters: + parameters = parameters["model"] + + self.load_state_dict(parameters) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/blocks.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/blocks.py new file mode 100644 index 00000000..6d87a006 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/blocks.py @@ -0,0 +1,439 @@ +import torch +import torch.nn as nn + +from .backbones.beit import ( + _make_pretrained_beitl16_512, + _make_pretrained_beitl16_384, + _make_pretrained_beitb16_384, + forward_beit, +) +from .backbones.swin_common import ( + forward_swin, +) +from .backbones.swin2 import ( + _make_pretrained_swin2l24_384, + _make_pretrained_swin2b24_384, + _make_pretrained_swin2t16_256, +) +from .backbones.swin import ( + _make_pretrained_swinl12_384, +) +from .backbones.levit import ( + _make_pretrained_levit_384, + forward_levit, +) +from .backbones.vit import ( + _make_pretrained_vitb_rn50_384, + _make_pretrained_vitl16_384, + _make_pretrained_vitb16_384, + forward_vit, +) + +def _make_encoder(backbone, features, use_pretrained, groups=1, expand=False, exportable=True, hooks=None, + use_vit_only=False, use_readout="ignore", in_features=[96, 256, 512, 1024]): + if backbone == "beitl16_512": + pretrained = _make_pretrained_beitl16_512( + use_pretrained, hooks=hooks, use_readout=use_readout + ) + scratch = _make_scratch( + [256, 512, 1024, 1024], features, groups=groups, expand=expand + ) # BEiT_512-L (backbone) + elif backbone == "beitl16_384": + pretrained = _make_pretrained_beitl16_384( + use_pretrained, hooks=hooks, use_readout=use_readout + ) + scratch = _make_scratch( + [256, 512, 1024, 1024], features, groups=groups, expand=expand + ) # BEiT_384-L (backbone) + elif backbone == "beitb16_384": + pretrained = _make_pretrained_beitb16_384( + use_pretrained, hooks=hooks, use_readout=use_readout + ) + scratch = _make_scratch( + [96, 192, 384, 768], features, groups=groups, expand=expand + ) # BEiT_384-B (backbone) + elif backbone == "swin2l24_384": + pretrained = _make_pretrained_swin2l24_384( + use_pretrained, hooks=hooks + ) + scratch = _make_scratch( + [192, 384, 768, 1536], features, groups=groups, expand=expand + ) # Swin2-L/12to24 (backbone) + elif backbone == "swin2b24_384": + pretrained = _make_pretrained_swin2b24_384( + use_pretrained, hooks=hooks + ) + scratch = _make_scratch( + [128, 256, 512, 1024], features, groups=groups, expand=expand + ) # Swin2-B/12to24 (backbone) + elif backbone == "swin2t16_256": + pretrained = _make_pretrained_swin2t16_256( + use_pretrained, hooks=hooks + ) + scratch = _make_scratch( + [96, 192, 384, 768], features, groups=groups, expand=expand + ) # Swin2-T/16 (backbone) + elif backbone == "swinl12_384": + pretrained = _make_pretrained_swinl12_384( + use_pretrained, hooks=hooks + ) + scratch = _make_scratch( + [192, 384, 768, 1536], features, groups=groups, expand=expand + ) # Swin-L/12 (backbone) + elif backbone == "next_vit_large_6m": + from .backbones.next_vit import _make_pretrained_next_vit_large_6m + pretrained = _make_pretrained_next_vit_large_6m(hooks=hooks) + scratch = _make_scratch( + in_features, features, groups=groups, expand=expand + ) # Next-ViT-L on ImageNet-1K-6M (backbone) + elif backbone == "levit_384": + pretrained = _make_pretrained_levit_384( + use_pretrained, hooks=hooks + ) + scratch = _make_scratch( + [384, 512, 768], features, groups=groups, expand=expand + ) # LeViT 384 (backbone) + elif backbone == "vitl16_384": + pretrained = _make_pretrained_vitl16_384( + use_pretrained, hooks=hooks, use_readout=use_readout + ) + scratch = _make_scratch( + [256, 512, 1024, 1024], features, groups=groups, expand=expand + ) # ViT-L/16 - 85.0% Top1 (backbone) + elif backbone == "vitb_rn50_384": + pretrained = _make_pretrained_vitb_rn50_384( + use_pretrained, + hooks=hooks, + use_vit_only=use_vit_only, + use_readout=use_readout, + ) + scratch = _make_scratch( + [256, 512, 768, 768], features, groups=groups, expand=expand + ) # ViT-H/16 - 85.0% Top1 (backbone) + elif backbone == "vitb16_384": + pretrained = _make_pretrained_vitb16_384( + use_pretrained, hooks=hooks, use_readout=use_readout + ) + scratch = _make_scratch( + [96, 192, 384, 768], features, groups=groups, expand=expand + ) # ViT-B/16 - 84.6% Top1 (backbone) + elif backbone == "resnext101_wsl": + pretrained = _make_pretrained_resnext101_wsl(use_pretrained) + scratch = _make_scratch([256, 512, 1024, 2048], features, groups=groups, expand=expand) # efficientnet_lite3 + elif backbone == "efficientnet_lite3": + pretrained = _make_pretrained_efficientnet_lite3(use_pretrained, exportable=exportable) + scratch = _make_scratch([32, 48, 136, 384], features, groups=groups, expand=expand) # efficientnet_lite3 + else: + print(f"Backbone '{backbone}' not implemented") + assert False + + return pretrained, scratch + + +def _make_scratch(in_shape, out_shape, groups=1, expand=False): + scratch = nn.Module() + + out_shape1 = out_shape + out_shape2 = out_shape + out_shape3 = out_shape + if len(in_shape) >= 4: + out_shape4 = out_shape + + if expand: + out_shape1 = out_shape + out_shape2 = out_shape*2 + out_shape3 = out_shape*4 + if len(in_shape) >= 4: + out_shape4 = out_shape*8 + + scratch.layer1_rn = nn.Conv2d( + in_shape[0], out_shape1, kernel_size=3, stride=1, padding=1, bias=False, groups=groups + ) + scratch.layer2_rn = nn.Conv2d( + in_shape[1], out_shape2, kernel_size=3, stride=1, padding=1, bias=False, groups=groups + ) + scratch.layer3_rn = nn.Conv2d( + in_shape[2], out_shape3, kernel_size=3, stride=1, padding=1, bias=False, groups=groups + ) + if len(in_shape) >= 4: + scratch.layer4_rn = nn.Conv2d( + in_shape[3], out_shape4, kernel_size=3, stride=1, padding=1, bias=False, groups=groups + ) + + return scratch + + +def _make_pretrained_efficientnet_lite3(use_pretrained, exportable=False): + efficientnet = torch.hub.load( + "rwightman/gen-efficientnet-pytorch", + "tf_efficientnet_lite3", + pretrained=use_pretrained, + exportable=exportable + ) + return _make_efficientnet_backbone(efficientnet) + + +def _make_efficientnet_backbone(effnet): + pretrained = nn.Module() + + pretrained.layer1 = nn.Sequential( + effnet.conv_stem, effnet.bn1, effnet.act1, *effnet.blocks[0:2] + ) + pretrained.layer2 = nn.Sequential(*effnet.blocks[2:3]) + pretrained.layer3 = nn.Sequential(*effnet.blocks[3:5]) + pretrained.layer4 = nn.Sequential(*effnet.blocks[5:9]) + + return pretrained + + +def _make_resnet_backbone(resnet): + pretrained = nn.Module() + pretrained.layer1 = nn.Sequential( + resnet.conv1, resnet.bn1, resnet.relu, resnet.maxpool, resnet.layer1 + ) + + pretrained.layer2 = resnet.layer2 + pretrained.layer3 = resnet.layer3 + pretrained.layer4 = resnet.layer4 + + return pretrained + + +def _make_pretrained_resnext101_wsl(use_pretrained): + resnet = torch.hub.load("facebookresearch/WSL-Images", "resnext101_32x8d_wsl") + return _make_resnet_backbone(resnet) + + + +class Interpolate(nn.Module): + """Interpolation module. + """ + + def __init__(self, scale_factor, mode, align_corners=False): + """Init. + + Args: + scale_factor (float): scaling + mode (str): interpolation mode + """ + super(Interpolate, self).__init__() + + self.interp = nn.functional.interpolate + self.scale_factor = scale_factor + self.mode = mode + self.align_corners = align_corners + + def forward(self, x): + """Forward pass. + + Args: + x (tensor): input + + Returns: + tensor: interpolated data + """ + + x = self.interp( + x, scale_factor=self.scale_factor, mode=self.mode, align_corners=self.align_corners + ) + + return x + + +class ResidualConvUnit(nn.Module): + """Residual convolution module. + """ + + def __init__(self, features): + """Init. + + Args: + features (int): number of features + """ + super().__init__() + + self.conv1 = nn.Conv2d( + features, features, kernel_size=3, stride=1, padding=1, bias=True + ) + + self.conv2 = nn.Conv2d( + features, features, kernel_size=3, stride=1, padding=1, bias=True + ) + + self.relu = nn.ReLU(inplace=True) + + def forward(self, x): + """Forward pass. + + Args: + x (tensor): input + + Returns: + tensor: output + """ + out = self.relu(x) + out = self.conv1(out) + out = self.relu(out) + out = self.conv2(out) + + return out + x + + +class FeatureFusionBlock(nn.Module): + """Feature fusion block. + """ + + def __init__(self, features): + """Init. + + Args: + features (int): number of features + """ + super(FeatureFusionBlock, self).__init__() + + self.resConfUnit1 = ResidualConvUnit(features) + self.resConfUnit2 = ResidualConvUnit(features) + + def forward(self, *xs): + """Forward pass. + + Returns: + tensor: output + """ + output = xs[0] + + if len(xs) == 2: + output += self.resConfUnit1(xs[1]) + + output = self.resConfUnit2(output) + + output = nn.functional.interpolate( + output, scale_factor=2, mode="bilinear", align_corners=True + ) + + return output + + + + +class ResidualConvUnit_custom(nn.Module): + """Residual convolution module. + """ + + def __init__(self, features, activation, bn): + """Init. + + Args: + features (int): number of features + """ + super().__init__() + + self.bn = bn + + self.groups=1 + + self.conv1 = nn.Conv2d( + features, features, kernel_size=3, stride=1, padding=1, bias=True, groups=self.groups + ) + + self.conv2 = nn.Conv2d( + features, features, kernel_size=3, stride=1, padding=1, bias=True, groups=self.groups + ) + + if self.bn==True: + self.bn1 = nn.BatchNorm2d(features) + self.bn2 = nn.BatchNorm2d(features) + + self.activation = activation + + self.skip_add = nn.quantized.FloatFunctional() + + def forward(self, x): + """Forward pass. + + Args: + x (tensor): input + + Returns: + tensor: output + """ + + out = self.activation(x) + out = self.conv1(out) + if self.bn==True: + out = self.bn1(out) + + out = self.activation(out) + out = self.conv2(out) + if self.bn==True: + out = self.bn2(out) + + if self.groups > 1: + out = self.conv_merge(out) + + return self.skip_add.add(out, x) + + # return out + x + + +class FeatureFusionBlock_custom(nn.Module): + """Feature fusion block. + """ + + def __init__(self, features, activation, deconv=False, bn=False, expand=False, align_corners=True, size=None): + """Init. + + Args: + features (int): number of features + """ + super(FeatureFusionBlock_custom, self).__init__() + + self.deconv = deconv + self.align_corners = align_corners + + self.groups=1 + + self.expand = expand + out_features = features + if self.expand==True: + out_features = features//2 + + self.out_conv = nn.Conv2d(features, out_features, kernel_size=1, stride=1, padding=0, bias=True, groups=1) + + self.resConfUnit1 = ResidualConvUnit_custom(features, activation, bn) + self.resConfUnit2 = ResidualConvUnit_custom(features, activation, bn) + + self.skip_add = nn.quantized.FloatFunctional() + + self.size=size + + def forward(self, *xs, size=None): + """Forward pass. + + Returns: + tensor: output + """ + output = xs[0] + + if len(xs) == 2: + res = self.resConfUnit1(xs[1]) + output = self.skip_add.add(output, res) + # output += res + + output = self.resConfUnit2(output) + + if (size is None) and (self.size is None): + modifier = {"scale_factor": 2} + elif size is None: + modifier = {"size": self.size} + else: + modifier = {"size": size} + + output = nn.functional.interpolate( + output, **modifier, mode="bilinear", align_corners=self.align_corners + ) + + output = self.out_conv(output) + + return output + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/dpt_depth.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/dpt_depth.py new file mode 100644 index 00000000..3129d09c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/dpt_depth.py @@ -0,0 +1,166 @@ +import torch +import torch.nn as nn + +from .base_model import BaseModel +from .blocks import ( + FeatureFusionBlock_custom, + Interpolate, + _make_encoder, + forward_beit, + forward_swin, + forward_levit, + forward_vit, +) +from .backbones.levit import stem_b4_transpose +from timm.models.layers import get_act_layer + + +def _make_fusion_block(features, use_bn, size = None): + return FeatureFusionBlock_custom( + features, + nn.ReLU(False), + deconv=False, + bn=use_bn, + expand=False, + align_corners=True, + size=size, + ) + + +class DPT(BaseModel): + def __init__( + self, + head, + features=256, + backbone="vitb_rn50_384", + readout="project", + channels_last=False, + use_bn=False, + **kwargs + ): + + super(DPT, self).__init__() + + self.channels_last = channels_last + + # For the Swin, Swin 2, LeViT and Next-ViT Transformers, the hierarchical architectures prevent setting the + # hooks freely. Instead, the hooks have to be chosen according to the ranges specified in the comments. + hooks = { + "beitl16_512": [5, 11, 17, 23], + "beitl16_384": [5, 11, 17, 23], + "beitb16_384": [2, 5, 8, 11], + "swin2l24_384": [1, 1, 17, 1], # Allowed ranges: [0, 1], [0, 1], [ 0, 17], [ 0, 1] + "swin2b24_384": [1, 1, 17, 1], # [0, 1], [0, 1], [ 0, 17], [ 0, 1] + "swin2t16_256": [1, 1, 5, 1], # [0, 1], [0, 1], [ 0, 5], [ 0, 1] + "swinl12_384": [1, 1, 17, 1], # [0, 1], [0, 1], [ 0, 17], [ 0, 1] + "next_vit_large_6m": [2, 6, 36, 39], # [0, 2], [3, 6], [ 7, 36], [37, 39] + "levit_384": [3, 11, 21], # [0, 3], [6, 11], [14, 21] + "vitb_rn50_384": [0, 1, 8, 11], + "vitb16_384": [2, 5, 8, 11], + "vitl16_384": [5, 11, 17, 23], + }[backbone] + + if "next_vit" in backbone: + in_features = { + "next_vit_large_6m": [96, 256, 512, 1024], + }[backbone] + else: + in_features = None + + # Instantiate backbone and reassemble blocks + self.pretrained, self.scratch = _make_encoder( + backbone, + features, + False, # Set to true of you want to train from scratch, uses ImageNet weights + groups=1, + expand=False, + exportable=False, + hooks=hooks, + use_readout=readout, + in_features=in_features, + ) + + self.number_layers = len(hooks) if hooks is not None else 4 + size_refinenet3 = None + self.scratch.stem_transpose = None + + if "beit" in backbone: + self.forward_transformer = forward_beit + elif "swin" in backbone: + self.forward_transformer = forward_swin + elif "next_vit" in backbone: + from .backbones.next_vit import forward_next_vit + self.forward_transformer = forward_next_vit + elif "levit" in backbone: + self.forward_transformer = forward_levit + size_refinenet3 = 7 + self.scratch.stem_transpose = stem_b4_transpose(256, 128, get_act_layer("hard_swish")) + else: + self.forward_transformer = forward_vit + + self.scratch.refinenet1 = _make_fusion_block(features, use_bn) + self.scratch.refinenet2 = _make_fusion_block(features, use_bn) + self.scratch.refinenet3 = _make_fusion_block(features, use_bn, size_refinenet3) + if self.number_layers >= 4: + self.scratch.refinenet4 = _make_fusion_block(features, use_bn) + + self.scratch.output_conv = head + + + def forward(self, x): + if self.channels_last == True: + x.contiguous(memory_format=torch.channels_last) + + layers = self.forward_transformer(self.pretrained, x) + if self.number_layers == 3: + layer_1, layer_2, layer_3 = layers + else: + layer_1, layer_2, layer_3, layer_4 = layers + + layer_1_rn = self.scratch.layer1_rn(layer_1) + layer_2_rn = self.scratch.layer2_rn(layer_2) + layer_3_rn = self.scratch.layer3_rn(layer_3) + if self.number_layers >= 4: + layer_4_rn = self.scratch.layer4_rn(layer_4) + + if self.number_layers == 3: + path_3 = self.scratch.refinenet3(layer_3_rn, size=layer_2_rn.shape[2:]) + else: + path_4 = self.scratch.refinenet4(layer_4_rn, size=layer_3_rn.shape[2:]) + path_3 = self.scratch.refinenet3(path_4, layer_3_rn, size=layer_2_rn.shape[2:]) + path_2 = self.scratch.refinenet2(path_3, layer_2_rn, size=layer_1_rn.shape[2:]) + path_1 = self.scratch.refinenet1(path_2, layer_1_rn) + + if self.scratch.stem_transpose is not None: + path_1 = self.scratch.stem_transpose(path_1) + + out = self.scratch.output_conv(path_1) + + return out + + +class DPTDepthModel(DPT): + def __init__(self, path=None, non_negative=True, **kwargs): + features = kwargs["features"] if "features" in kwargs else 256 + head_features_1 = kwargs["head_features_1"] if "head_features_1" in kwargs else features + head_features_2 = kwargs["head_features_2"] if "head_features_2" in kwargs else 32 + kwargs.pop("head_features_1", None) + kwargs.pop("head_features_2", None) + + head = nn.Sequential( + nn.Conv2d(head_features_1, head_features_1 // 2, kernel_size=3, stride=1, padding=1), + Interpolate(scale_factor=2, mode="bilinear", align_corners=True), + nn.Conv2d(head_features_1 // 2, head_features_2, kernel_size=3, stride=1, padding=1), + nn.ReLU(True), + nn.Conv2d(head_features_2, 1, kernel_size=1, stride=1, padding=0), + nn.ReLU(True) if non_negative else nn.Identity(), + nn.Identity(), + ) + + super().__init__(head, **kwargs) + + if path is not None: + self.load(path) + + def forward(self, x): + return super().forward(x).squeeze(dim=1) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/midas_net.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/midas_net.py new file mode 100644 index 00000000..8a954977 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/midas_net.py @@ -0,0 +1,76 @@ +"""MidashNet: Network for monocular depth estimation trained by mixing several datasets. +This file contains code that is adapted from +https://github.com/thomasjpfan/pytorch_refinenet/blob/master/pytorch_refinenet/refinenet/refinenet_4cascade.py +""" +import torch +import torch.nn as nn + +from .base_model import BaseModel +from .blocks import FeatureFusionBlock, Interpolate, _make_encoder + + +class MidasNet(BaseModel): + """Network for monocular depth estimation. + """ + + def __init__(self, path=None, features=256, non_negative=True): + """Init. + + Args: + path (str, optional): Path to saved model. Defaults to None. + features (int, optional): Number of features. Defaults to 256. + backbone (str, optional): Backbone network for encoder. Defaults to resnet50 + """ + print("Loading weights: ", path) + + super(MidasNet, self).__init__() + + use_pretrained = False if path is None else True + + self.pretrained, self.scratch = _make_encoder(backbone="resnext101_wsl", features=features, use_pretrained=use_pretrained) + + self.scratch.refinenet4 = FeatureFusionBlock(features) + self.scratch.refinenet3 = FeatureFusionBlock(features) + self.scratch.refinenet2 = FeatureFusionBlock(features) + self.scratch.refinenet1 = FeatureFusionBlock(features) + + self.scratch.output_conv = nn.Sequential( + nn.Conv2d(features, 128, kernel_size=3, stride=1, padding=1), + Interpolate(scale_factor=2, mode="bilinear"), + nn.Conv2d(128, 32, kernel_size=3, stride=1, padding=1), + nn.ReLU(True), + nn.Conv2d(32, 1, kernel_size=1, stride=1, padding=0), + nn.ReLU(True) if non_negative else nn.Identity(), + ) + + if path: + self.load(path) + + def forward(self, x): + """Forward pass. + + Args: + x (tensor): input data (image) + + Returns: + tensor: depth + """ + + layer_1 = self.pretrained.layer1(x) + layer_2 = self.pretrained.layer2(layer_1) + layer_3 = self.pretrained.layer3(layer_2) + layer_4 = self.pretrained.layer4(layer_3) + + layer_1_rn = self.scratch.layer1_rn(layer_1) + layer_2_rn = self.scratch.layer2_rn(layer_2) + layer_3_rn = self.scratch.layer3_rn(layer_3) + layer_4_rn = self.scratch.layer4_rn(layer_4) + + path_4 = self.scratch.refinenet4(layer_4_rn) + path_3 = self.scratch.refinenet3(path_4, layer_3_rn) + path_2 = self.scratch.refinenet2(path_3, layer_2_rn) + path_1 = self.scratch.refinenet1(path_2, layer_1_rn) + + out = self.scratch.output_conv(path_1) + + return torch.squeeze(out, dim=1) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/midas_net_custom.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/midas_net_custom.py new file mode 100644 index 00000000..50e4acb5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/midas_net_custom.py @@ -0,0 +1,128 @@ +"""MidashNet: Network for monocular depth estimation trained by mixing several datasets. +This file contains code that is adapted from +https://github.com/thomasjpfan/pytorch_refinenet/blob/master/pytorch_refinenet/refinenet/refinenet_4cascade.py +""" +import torch +import torch.nn as nn + +from .base_model import BaseModel +from .blocks import FeatureFusionBlock, FeatureFusionBlock_custom, Interpolate, _make_encoder + + +class MidasNet_small(BaseModel): + """Network for monocular depth estimation. + """ + + def __init__(self, path=None, features=64, backbone="efficientnet_lite3", non_negative=True, exportable=True, channels_last=False, align_corners=True, + blocks={'expand': True}): + """Init. + + Args: + path (str, optional): Path to saved model. Defaults to None. + features (int, optional): Number of features. Defaults to 256. + backbone (str, optional): Backbone network for encoder. Defaults to resnet50 + """ + print("Loading weights: ", path) + + super(MidasNet_small, self).__init__() + + use_pretrained = False if path else True + + self.channels_last = channels_last + self.blocks = blocks + self.backbone = backbone + + self.groups = 1 + + features1=features + features2=features + features3=features + features4=features + self.expand = False + if "expand" in self.blocks and self.blocks['expand'] == True: + self.expand = True + features1=features + features2=features*2 + features3=features*4 + features4=features*8 + + self.pretrained, self.scratch = _make_encoder(self.backbone, features, use_pretrained, groups=self.groups, expand=self.expand, exportable=exportable) + + self.scratch.activation = nn.ReLU(False) + + self.scratch.refinenet4 = FeatureFusionBlock_custom(features4, self.scratch.activation, deconv=False, bn=False, expand=self.expand, align_corners=align_corners) + self.scratch.refinenet3 = FeatureFusionBlock_custom(features3, self.scratch.activation, deconv=False, bn=False, expand=self.expand, align_corners=align_corners) + self.scratch.refinenet2 = FeatureFusionBlock_custom(features2, self.scratch.activation, deconv=False, bn=False, expand=self.expand, align_corners=align_corners) + self.scratch.refinenet1 = FeatureFusionBlock_custom(features1, self.scratch.activation, deconv=False, bn=False, align_corners=align_corners) + + + self.scratch.output_conv = nn.Sequential( + nn.Conv2d(features, features//2, kernel_size=3, stride=1, padding=1, groups=self.groups), + Interpolate(scale_factor=2, mode="bilinear"), + nn.Conv2d(features//2, 32, kernel_size=3, stride=1, padding=1), + self.scratch.activation, + nn.Conv2d(32, 1, kernel_size=1, stride=1, padding=0), + nn.ReLU(True) if non_negative else nn.Identity(), + nn.Identity(), + ) + + if path: + self.load(path) + + + def forward(self, x): + """Forward pass. + + Args: + x (tensor): input data (image) + + Returns: + tensor: depth + """ + if self.channels_last==True: + print("self.channels_last = ", self.channels_last) + x.contiguous(memory_format=torch.channels_last) + + + layer_1 = self.pretrained.layer1(x) + layer_2 = self.pretrained.layer2(layer_1) + layer_3 = self.pretrained.layer3(layer_2) + layer_4 = self.pretrained.layer4(layer_3) + + layer_1_rn = self.scratch.layer1_rn(layer_1) + layer_2_rn = self.scratch.layer2_rn(layer_2) + layer_3_rn = self.scratch.layer3_rn(layer_3) + layer_4_rn = self.scratch.layer4_rn(layer_4) + + + path_4 = self.scratch.refinenet4(layer_4_rn) + path_3 = self.scratch.refinenet3(path_4, layer_3_rn) + path_2 = self.scratch.refinenet2(path_3, layer_2_rn) + path_1 = self.scratch.refinenet1(path_2, layer_1_rn) + + out = self.scratch.output_conv(path_1) + + return torch.squeeze(out, dim=1) + + + +def fuse_model(m): + prev_previous_type = nn.Identity() + prev_previous_name = '' + previous_type = nn.Identity() + previous_name = '' + for name, module in m.named_modules(): + if prev_previous_type == nn.Conv2d and previous_type == nn.BatchNorm2d and type(module) == nn.ReLU: + # print("FUSED ", prev_previous_name, previous_name, name) + torch.quantization.fuse_modules(m, [prev_previous_name, previous_name, name], inplace=True) + elif prev_previous_type == nn.Conv2d and previous_type == nn.BatchNorm2d: + # print("FUSED ", prev_previous_name, previous_name) + torch.quantization.fuse_modules(m, [prev_previous_name, previous_name], inplace=True) + # elif previous_type == nn.Conv2d and type(module) == nn.ReLU: + # print("FUSED ", previous_name, name) + # torch.quantization.fuse_modules(m, [previous_name, name], inplace=True) + + prev_previous_type = previous_type + prev_previous_name = previous_name + previous_type = type(module) + previous_name = name \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/model_loader.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/model_loader.py new file mode 100644 index 00000000..f1cd1f2d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/model_loader.py @@ -0,0 +1,242 @@ +import cv2 +import torch + +from midas.dpt_depth import DPTDepthModel +from midas.midas_net import MidasNet +from midas.midas_net_custom import MidasNet_small +from midas.transforms import Resize, NormalizeImage, PrepareForNet + +from torchvision.transforms import Compose + +default_models = { + "dpt_beit_large_512": "weights/dpt_beit_large_512.pt", + "dpt_beit_large_384": "weights/dpt_beit_large_384.pt", + "dpt_beit_base_384": "weights/dpt_beit_base_384.pt", + "dpt_swin2_large_384": "weights/dpt_swin2_large_384.pt", + "dpt_swin2_base_384": "weights/dpt_swin2_base_384.pt", + "dpt_swin2_tiny_256": "weights/dpt_swin2_tiny_256.pt", + "dpt_swin_large_384": "weights/dpt_swin_large_384.pt", + "dpt_next_vit_large_384": "weights/dpt_next_vit_large_384.pt", + "dpt_levit_224": "weights/dpt_levit_224.pt", + "dpt_large_384": "weights/dpt_large_384.pt", + "dpt_hybrid_384": "weights/dpt_hybrid_384.pt", + "midas_v21_384": "weights/midas_v21_384.pt", + "midas_v21_small_256": "weights/midas_v21_small_256.pt", + "openvino_midas_v21_small_256": "weights/openvino_midas_v21_small_256.xml", +} + + +def load_model(device, model_path, model_type="dpt_large_384", optimize=True, height=None, square=False): + """Load the specified network. + + Args: + device (device): the torch device used + model_path (str): path to saved model + model_type (str): the type of the model to be loaded + optimize (bool): optimize the model to half-integer on CUDA? + height (int): inference encoder image height + square (bool): resize to a square resolution? + + Returns: + The loaded network, the transform which prepares images as input to the network and the dimensions of the + network input + """ + if "openvino" in model_type: + from openvino.runtime import Core + + keep_aspect_ratio = not square + + if model_type == "dpt_beit_large_512": + model = DPTDepthModel( + path=model_path, + backbone="beitl16_512", + non_negative=True, + ) + net_w, net_h = 512, 512 + resize_mode = "minimal" + normalization = NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) + + elif model_type == "dpt_beit_large_384": + model = DPTDepthModel( + path=model_path, + backbone="beitl16_384", + non_negative=True, + ) + net_w, net_h = 384, 384 + resize_mode = "minimal" + normalization = NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) + + elif model_type == "dpt_beit_base_384": + model = DPTDepthModel( + path=model_path, + backbone="beitb16_384", + non_negative=True, + ) + net_w, net_h = 384, 384 + resize_mode = "minimal" + normalization = NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) + + elif model_type == "dpt_swin2_large_384": + model = DPTDepthModel( + path=model_path, + backbone="swin2l24_384", + non_negative=True, + ) + net_w, net_h = 384, 384 + keep_aspect_ratio = False + resize_mode = "minimal" + normalization = NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) + + elif model_type == "dpt_swin2_base_384": + model = DPTDepthModel( + path=model_path, + backbone="swin2b24_384", + non_negative=True, + ) + net_w, net_h = 384, 384 + keep_aspect_ratio = False + resize_mode = "minimal" + normalization = NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) + + elif model_type == "dpt_swin2_tiny_256": + model = DPTDepthModel( + path=model_path, + backbone="swin2t16_256", + non_negative=True, + ) + net_w, net_h = 256, 256 + keep_aspect_ratio = False + resize_mode = "minimal" + normalization = NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) + + elif model_type == "dpt_swin_large_384": + model = DPTDepthModel( + path=model_path, + backbone="swinl12_384", + non_negative=True, + ) + net_w, net_h = 384, 384 + keep_aspect_ratio = False + resize_mode = "minimal" + normalization = NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) + + elif model_type == "dpt_next_vit_large_384": + model = DPTDepthModel( + path=model_path, + backbone="next_vit_large_6m", + non_negative=True, + ) + net_w, net_h = 384, 384 + resize_mode = "minimal" + normalization = NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) + + # We change the notation from dpt_levit_224 (MiDaS notation) to levit_384 (timm notation) here, where the 224 refers + # to the resolution 224x224 used by LeViT and 384 is the first entry of the embed_dim, see _cfg and model_cfgs of + # https://github.com/rwightman/pytorch-image-models/blob/main/timm/models/levit.py + # (commit id: 927f031293a30afb940fff0bee34b85d9c059b0e) + elif model_type == "dpt_levit_224": + model = DPTDepthModel( + path=model_path, + backbone="levit_384", + non_negative=True, + head_features_1=64, + head_features_2=8, + ) + net_w, net_h = 224, 224 + keep_aspect_ratio = False + resize_mode = "minimal" + normalization = NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) + + elif model_type == "dpt_large_384": + model = DPTDepthModel( + path=model_path, + backbone="vitl16_384", + non_negative=True, + ) + net_w, net_h = 384, 384 + resize_mode = "minimal" + normalization = NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) + + elif model_type == "dpt_hybrid_384": + model = DPTDepthModel( + path=model_path, + backbone="vitb_rn50_384", + non_negative=True, + ) + net_w, net_h = 384, 384 + resize_mode = "minimal" + normalization = NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) + + elif model_type == "midas_v21_384": + model = MidasNet(model_path, non_negative=True) + net_w, net_h = 384, 384 + resize_mode = "upper_bound" + normalization = NormalizeImage( + mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225] + ) + + elif model_type == "midas_v21_small_256": + model = MidasNet_small(model_path, features=64, backbone="efficientnet_lite3", exportable=True, + non_negative=True, blocks={'expand': True}) + net_w, net_h = 256, 256 + resize_mode = "upper_bound" + normalization = NormalizeImage( + mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225] + ) + + elif model_type == "openvino_midas_v21_small_256": + ie = Core() + uncompiled_model = ie.read_model(model=model_path) + model = ie.compile_model(uncompiled_model, "CPU") + net_w, net_h = 256, 256 + resize_mode = "upper_bound" + normalization = NormalizeImage( + mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225] + ) + + else: + print(f"model_type '{model_type}' not implemented, use: --model_type large") + assert False + + if not "openvino" in model_type: + print("Model loaded, number of parameters = {:.0f}M".format(sum(p.numel() for p in model.parameters()) / 1e6)) + else: + print("Model loaded, optimized with OpenVINO") + + if "openvino" in model_type: + keep_aspect_ratio = False + + if height is not None: + net_w, net_h = height, height + + transform = Compose( + [ + Resize( + net_w, + net_h, + resize_target=None, + keep_aspect_ratio=keep_aspect_ratio, + ensure_multiple_of=32, + resize_method=resize_mode, + image_interpolation_method=cv2.INTER_CUBIC, + ), + normalization, + PrepareForNet(), + ] + ) + + if not "openvino" in model_type: + model.eval() + + if optimize and (device == torch.device("cuda")): + if not "openvino" in model_type: + model = model.to(memory_format=torch.channels_last) + model = model.half() + else: + print("Error: OpenVINO models are already optimized. No optimization to half-float possible.") + exit() + + if not "openvino" in model_type: + model.to(device) + + return model, transform, net_w, net_h diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/transforms.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/transforms.py new file mode 100644 index 00000000..350cbc11 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/midas/transforms.py @@ -0,0 +1,234 @@ +import numpy as np +import cv2 +import math + + +def apply_min_size(sample, size, image_interpolation_method=cv2.INTER_AREA): + """Rezise the sample to ensure the given size. Keeps aspect ratio. + + Args: + sample (dict): sample + size (tuple): image size + + Returns: + tuple: new size + """ + shape = list(sample["disparity"].shape) + + if shape[0] >= size[0] and shape[1] >= size[1]: + return sample + + scale = [0, 0] + scale[0] = size[0] / shape[0] + scale[1] = size[1] / shape[1] + + scale = max(scale) + + shape[0] = math.ceil(scale * shape[0]) + shape[1] = math.ceil(scale * shape[1]) + + # resize + sample["image"] = cv2.resize( + sample["image"], tuple(shape[::-1]), interpolation=image_interpolation_method + ) + + sample["disparity"] = cv2.resize( + sample["disparity"], tuple(shape[::-1]), interpolation=cv2.INTER_NEAREST + ) + sample["mask"] = cv2.resize( + sample["mask"].astype(np.float32), + tuple(shape[::-1]), + interpolation=cv2.INTER_NEAREST, + ) + sample["mask"] = sample["mask"].astype(bool) + + return tuple(shape) + + +class Resize(object): + """Resize sample to given size (width, height). + """ + + def __init__( + self, + width, + height, + resize_target=True, + keep_aspect_ratio=False, + ensure_multiple_of=1, + resize_method="lower_bound", + image_interpolation_method=cv2.INTER_AREA, + ): + """Init. + + Args: + width (int): desired output width + height (int): desired output height + resize_target (bool, optional): + True: Resize the full sample (image, mask, target). + False: Resize image only. + Defaults to True. + keep_aspect_ratio (bool, optional): + True: Keep the aspect ratio of the input sample. + Output sample might not have the given width and height, and + resize behaviour depends on the parameter 'resize_method'. + Defaults to False. + ensure_multiple_of (int, optional): + Output width and height is constrained to be multiple of this parameter. + Defaults to 1. + resize_method (str, optional): + "lower_bound": Output will be at least as large as the given size. + "upper_bound": Output will be at max as large as the given size. (Output size might be smaller than given size.) + "minimal": Scale as least as possible. (Output size might be smaller than given size.) + Defaults to "lower_bound". + """ + self.__width = width + self.__height = height + + self.__resize_target = resize_target + self.__keep_aspect_ratio = keep_aspect_ratio + self.__multiple_of = ensure_multiple_of + self.__resize_method = resize_method + self.__image_interpolation_method = image_interpolation_method + + def constrain_to_multiple_of(self, x, min_val=0, max_val=None): + y = (np.round(x / self.__multiple_of) * self.__multiple_of).astype(int) + + if max_val is not None and y > max_val: + y = (np.floor(x / self.__multiple_of) * self.__multiple_of).astype(int) + + if y < min_val: + y = (np.ceil(x / self.__multiple_of) * self.__multiple_of).astype(int) + + return y + + def get_size(self, width, height): + # determine new height and width + scale_height = self.__height / height + scale_width = self.__width / width + + if self.__keep_aspect_ratio: + if self.__resize_method == "lower_bound": + # scale such that output size is lower bound + if scale_width > scale_height: + # fit width + scale_height = scale_width + else: + # fit height + scale_width = scale_height + elif self.__resize_method == "upper_bound": + # scale such that output size is upper bound + if scale_width < scale_height: + # fit width + scale_height = scale_width + else: + # fit height + scale_width = scale_height + elif self.__resize_method == "minimal": + # scale as least as possbile + if abs(1 - scale_width) < abs(1 - scale_height): + # fit width + scale_height = scale_width + else: + # fit height + scale_width = scale_height + else: + raise ValueError( + f"resize_method {self.__resize_method} not implemented" + ) + + if self.__resize_method == "lower_bound": + new_height = self.constrain_to_multiple_of( + scale_height * height, min_val=self.__height + ) + new_width = self.constrain_to_multiple_of( + scale_width * width, min_val=self.__width + ) + elif self.__resize_method == "upper_bound": + new_height = self.constrain_to_multiple_of( + scale_height * height, max_val=self.__height + ) + new_width = self.constrain_to_multiple_of( + scale_width * width, max_val=self.__width + ) + elif self.__resize_method == "minimal": + new_height = self.constrain_to_multiple_of(scale_height * height) + new_width = self.constrain_to_multiple_of(scale_width * width) + else: + raise ValueError(f"resize_method {self.__resize_method} not implemented") + + return (new_width, new_height) + + def __call__(self, sample): + width, height = self.get_size( + sample["image"].shape[1], sample["image"].shape[0] + ) + + # resize sample + sample["image"] = cv2.resize( + sample["image"], + (width, height), + interpolation=self.__image_interpolation_method, + ) + + if self.__resize_target: + if "disparity" in sample: + sample["disparity"] = cv2.resize( + sample["disparity"], + (width, height), + interpolation=cv2.INTER_NEAREST, + ) + + if "depth" in sample: + sample["depth"] = cv2.resize( + sample["depth"], (width, height), interpolation=cv2.INTER_NEAREST + ) + + sample["mask"] = cv2.resize( + sample["mask"].astype(np.float32), + (width, height), + interpolation=cv2.INTER_NEAREST, + ) + sample["mask"] = sample["mask"].astype(bool) + + return sample + + +class NormalizeImage(object): + """Normlize image by given mean and std. + """ + + def __init__(self, mean, std): + self.__mean = mean + self.__std = std + + def __call__(self, sample): + sample["image"] = (sample["image"] - self.__mean) / self.__std + + return sample + + +class PrepareForNet(object): + """Prepare sample for usage as network input. + """ + + def __init__(self): + pass + + def __call__(self, sample): + image = np.transpose(sample["image"], (2, 0, 1)) + sample["image"] = np.ascontiguousarray(image).astype(np.float32) + + if "mask" in sample: + sample["mask"] = sample["mask"].astype(np.float32) + sample["mask"] = np.ascontiguousarray(sample["mask"]) + + if "disparity" in sample: + disparity = sample["disparity"].astype(np.float32) + sample["disparity"] = np.ascontiguousarray(disparity) + + if "depth" in sample: + depth = sample["depth"].astype(np.float32) + sample["depth"] = np.ascontiguousarray(depth) + + return sample diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/output/.placeholder b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/output/.placeholder new file mode 100644 index 00000000..e69de29b diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/LICENSE b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/LICENSE new file mode 100644 index 00000000..6606ec02 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Alexey + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/README.md b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/README.md new file mode 100644 index 00000000..1d43c260 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/README.md @@ -0,0 +1,131 @@ +# MiDaS for ROS1 by using LibTorch in C++ + +### Requirements + +- Ubuntu 17.10 / 18.04 / 20.04, Debian Stretch +- ROS Melodic for Ubuntu (17.10 / 18.04) / Debian Stretch, ROS Noetic for Ubuntu 20.04 +- C++11 +- LibTorch >= 1.6 + +## Quick Start with a MiDaS Example + +MiDaS is a neural network to compute depth from a single image. + +* input from `image_topic`: `sensor_msgs/Image` - `RGB8` image with any shape +* output to `midas_topic`: `sensor_msgs/Image` - `TYPE_32FC1` inverse relative depth maps in range [0 - 255] with original size and channels=1 + +### Install Dependecies + +* install ROS Melodic for Ubuntu 17.10 / 18.04: +```bash +wget https://raw.githubusercontent.com/isl-org/MiDaS/master/ros/additions/install_ros_melodic_ubuntu_17_18.sh +./install_ros_melodic_ubuntu_17_18.sh +``` + +or Noetic for Ubuntu 20.04: + +```bash +wget https://raw.githubusercontent.com/isl-org/MiDaS/master/ros/additions/install_ros_noetic_ubuntu_20.sh +./install_ros_noetic_ubuntu_20.sh +``` + + +* install LibTorch 1.7 with CUDA 11.0: + +On **Jetson (ARM)**: +```bash +wget https://nvidia.box.com/shared/static/wa34qwrwtk9njtyarwt5nvo6imenfy26.whl -O torch-1.7.0-cp36-cp36m-linux_aarch64.whl +sudo apt-get install python3-pip libopenblas-base libopenmpi-dev +pip3 install Cython +pip3 install numpy torch-1.7.0-cp36-cp36m-linux_aarch64.whl +``` +Or compile LibTorch from source: https://github.com/pytorch/pytorch#from-source + +On **Linux (x86_64)**: +```bash +cd ~/ +wget https://download.pytorch.org/libtorch/cu110/libtorch-cxx11-abi-shared-with-deps-1.7.0%2Bcu110.zip +unzip libtorch-cxx11-abi-shared-with-deps-1.7.0+cu110.zip +``` + +* create symlink for OpenCV: + +```bash +sudo ln -s /usr/include/opencv4 /usr/include/opencv +``` + +* download and install MiDaS: + +```bash +source ~/.bashrc +cd ~/ +mkdir catkin_ws +cd catkin_ws +git clone https://github.com/isl-org/MiDaS +mkdir src +cp -r MiDaS/ros/* src + +chmod +x src/additions/*.sh +chmod +x src/*.sh +chmod +x src/midas_cpp/scripts/*.py +cp src/additions/do_catkin_make.sh ./do_catkin_make.sh +./do_catkin_make.sh +./src/additions/downloads.sh +``` + +### Usage + +* run only `midas` node: `~/catkin_ws/src/launch_midas_cpp.sh` + +#### Test + +* Test - capture video and show result in the window: + * place any `test.mp4` video file to the directory `~/catkin_ws/src/` + * run `midas` node: `~/catkin_ws/src/launch_midas_cpp.sh` + * run test nodes in another terminal: `cd ~/catkin_ws/src && ./run_talker_listener_test.sh` and wait 30 seconds + + (to use Python 2, run command `sed -i 's/python3/python2/' ~/catkin_ws/src/midas_cpp/scripts/*.py` ) + +## Mobile version of MiDaS - Monocular Depth Estimation + +### Accuracy + +* MiDaS v2 small - ResNet50 default-decoder 384x384 +* MiDaS v2.1 small - EfficientNet-Lite3 small-decoder 256x256 + +**Zero-shot error** (the lower - the better): + +| Model | DIW WHDR | Eth3d AbsRel | Sintel AbsRel | Kitti δ>1.25 | NyuDepthV2 δ>1.25 | TUM δ>1.25 | +|---|---|---|---|---|---|---| +| MiDaS v2 small 384x384 | **0.1248** | 0.1550 | **0.3300** | **21.81** | 15.73 | 17.00 | +| MiDaS v2.1 small 256x256 | 0.1344 | **0.1344** | 0.3370 | 29.27 | **13.43** | **14.53** | +| Relative improvement, % | -8 % | **+13 %** | -2 % | -34 % | **+15 %** | **+15 %** | + +None of Train/Valid/Test subsets of datasets (DIW, Eth3d, Sintel, Kitti, NyuDepthV2, TUM) were not involved in Training or Fine Tuning. + +### Inference speed (FPS) on nVidia GPU + +Inference speed excluding pre and post processing, batch=1, **Frames Per Second** (the higher - the better): + +| Model | Jetson Nano, FPS | RTX 2080Ti, FPS | +|---|---|---| +| MiDaS v2 small 384x384 | 1.6 | 117 | +| MiDaS v2.1 small 256x256 | 8.1 | 232 | +| SpeedUp, X times | **5x** | **2x** | + +### Citation + +This repository contains code to compute depth from a single image. It accompanies our [paper](https://arxiv.org/abs/1907.01341v3): + +>Towards Robust Monocular Depth Estimation: Mixing Datasets for Zero-shot Cross-dataset Transfer +René Ranftl, Katrin Lasinger, David Hafner, Konrad Schindler, Vladlen Koltun + +Please cite our paper if you use this code or any of the models: +``` +@article{Ranftl2020, + author = {Ren\'{e} Ranftl and Katrin Lasinger and David Hafner and Konrad Schindler and Vladlen Koltun}, + title = {Towards Robust Monocular Depth Estimation: Mixing Datasets for Zero-shot Cross-dataset Transfer}, + journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence (TPAMI)}, + year = {2020}, +} +``` diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/do_catkin_make.sh b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/do_catkin_make.sh new file mode 100644 index 00000000..0d416fc0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/do_catkin_make.sh @@ -0,0 +1,5 @@ +mkdir src +catkin_make +source devel/setup.bash +echo $ROS_PACKAGE_PATH +chmod +x ./devel/setup.bash diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/downloads.sh b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/downloads.sh new file mode 100644 index 00000000..9c967d4e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/downloads.sh @@ -0,0 +1,5 @@ +mkdir ~/.ros +wget https://github.com/isl-org/MiDaS/releases/download/v2_1/model-small-traced.pt +cp ./model-small-traced.pt ~/.ros/model-small-traced.pt + + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/install_ros_melodic_ubuntu_17_18.sh b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/install_ros_melodic_ubuntu_17_18.sh new file mode 100644 index 00000000..b8681126 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/install_ros_melodic_ubuntu_17_18.sh @@ -0,0 +1,34 @@ +#@title { display-mode: "code" } + +#from http://wiki.ros.org/indigo/Installation/Ubuntu + +#1.2 Setup sources.list +sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' + +# 1.3 Setup keys +sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 +sudo apt-key adv --keyserver 'hkp://ha.pool.sks-keyservers.net:80' --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116 + +curl -sSL 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xC1CF6E31E6BADE8868B172B4F42ED6FBAB17C654' | sudo apt-key add - + +# 1.4 Installation +sudo apt-get update +sudo apt-get upgrade + +# Desktop-Full Install: +sudo apt-get install ros-melodic-desktop-full + +printf "\nsource /opt/ros/melodic/setup.bash\n" >> ~/.bashrc + +# 1.5 Initialize rosdep +sudo rosdep init +rosdep update + + +# 1.7 Getting rosinstall (python) +sudo apt-get install python-rosinstall +sudo apt-get install python-catkin-tools +sudo apt-get install python-rospy +sudo apt-get install python-rosdep +sudo apt-get install python-roscd +sudo apt-get install python-pip \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/install_ros_noetic_ubuntu_20.sh b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/install_ros_noetic_ubuntu_20.sh new file mode 100644 index 00000000..d73ea1a3 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/install_ros_noetic_ubuntu_20.sh @@ -0,0 +1,33 @@ +#@title { display-mode: "code" } + +#from http://wiki.ros.org/indigo/Installation/Ubuntu + +#1.2 Setup sources.list +sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' + +# 1.3 Setup keys +sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 + +curl -sSL 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xC1CF6E31E6BADE8868B172B4F42ED6FBAB17C654' | sudo apt-key add - + +# 1.4 Installation +sudo apt-get update +sudo apt-get upgrade + +# Desktop-Full Install: +sudo apt-get install ros-noetic-desktop-full + +printf "\nsource /opt/ros/noetic/setup.bash\n" >> ~/.bashrc + +# 1.5 Initialize rosdep +sudo rosdep init +rosdep update + + +# 1.7 Getting rosinstall (python) +sudo apt-get install python3-rosinstall +sudo apt-get install python3-catkin-tools +sudo apt-get install python3-rospy +sudo apt-get install python3-rosdep +sudo apt-get install python3-roscd +sudo apt-get install python3-pip \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/make_package_cpp.sh b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/make_package_cpp.sh new file mode 100644 index 00000000..d0ef6073 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/additions/make_package_cpp.sh @@ -0,0 +1,16 @@ +cd ~/catkin_ws/src +catkin_create_pkg midas_cpp std_msgs roscpp cv_bridge sensor_msgs image_transport +cd ~/catkin_ws +catkin_make + +chmod +x ~/catkin_ws/devel/setup.bash +printf "\nsource ~/catkin_ws/devel/setup.bash" >> ~/.bashrc +source ~/catkin_ws/devel/setup.bash + + +sudo rosdep init +rosdep update +#rospack depends1 midas_cpp +roscd midas_cpp +#cat package.xml +#rospack depends midas_cpp \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/launch_midas_cpp.sh b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/launch_midas_cpp.sh new file mode 100644 index 00000000..5a0d1583 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/launch_midas_cpp.sh @@ -0,0 +1,2 @@ +source ~/catkin_ws/devel/setup.bash +roslaunch midas_cpp midas_cpp.launch model_name:="model-small-traced.pt" input_topic:="image_topic" output_topic:="midas_topic" out_orig_size:="true" \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/CMakeLists.txt b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/CMakeLists.txt new file mode 100644 index 00000000..88534169 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/CMakeLists.txt @@ -0,0 +1,189 @@ +cmake_minimum_required(VERSION 3.0.2) +project(midas_cpp) + +## Compile as C++11, supported in ROS Kinetic and newer +# add_compile_options(-std=c++11) + +## Find catkin macros and libraries +## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) +## is used, also find other catkin packages +find_package(catkin REQUIRED COMPONENTS + cv_bridge + image_transport + roscpp + rospy + sensor_msgs + std_msgs +) + +## System dependencies are found with CMake's conventions +# find_package(Boost REQUIRED COMPONENTS system) + +list(APPEND CMAKE_PREFIX_PATH "~/libtorch") +list(APPEND CMAKE_PREFIX_PATH "/usr/local/lib/python3.6/dist-packages/torch/lib") +list(APPEND CMAKE_PREFIX_PATH "/usr/local/lib/python2.7/dist-packages/torch/lib") + +if(NOT EXISTS "~/libtorch") + if (EXISTS "/usr/local/lib/python3.6/dist-packages/torch") + include_directories(/usr/local/include) + include_directories(/usr/local/lib/python3.6/dist-packages/torch/include/torch/csrc/api/include) + include_directories(/usr/local/lib/python3.6/dist-packages/torch/include) + + link_directories(/usr/local/lib) + link_directories(/usr/local/lib/python3.6/dist-packages/torch/lib) + + set(CMAKE_PREFIX_PATH /usr/local/lib/python3.6/dist-packages/torch) + set(Boost_USE_MULTITHREADED ON) + set(Torch_DIR /usr/local/lib/python3.6/dist-packages/torch) + + elseif (EXISTS "/usr/local/lib/python2.7/dist-packages/torch") + + include_directories(/usr/local/include) + include_directories(/usr/local/lib/python2.7/dist-packages/torch/include/torch/csrc/api/include) + include_directories(/usr/local/lib/python2.7/dist-packages/torch/include) + + link_directories(/usr/local/lib) + link_directories(/usr/local/lib/python2.7/dist-packages/torch/lib) + + set(CMAKE_PREFIX_PATH /usr/local/lib/python2.7/dist-packages/torch) + set(Boost_USE_MULTITHREADED ON) + set(Torch_DIR /usr/local/lib/python2.7/dist-packages/torch) + endif() +endif() + + + +find_package(Torch REQUIRED) +find_package(OpenCV REQUIRED) +include_directories( ${OpenCV_INCLUDE_DIRS} ) + +add_executable(midas_cpp src/main.cpp) +target_link_libraries(midas_cpp "${TORCH_LIBRARIES}" "${OpenCV_LIBS} ${catkin_LIBRARIES}") +set_property(TARGET midas_cpp PROPERTY CXX_STANDARD 14) + + + +################################### +## catkin specific configuration ## +################################### +## The catkin_package macro generates cmake config files for your package +## Declare things to be passed to dependent projects +## INCLUDE_DIRS: uncomment this if your package contains header files +## LIBRARIES: libraries you create in this project that dependent projects also need +## CATKIN_DEPENDS: catkin_packages dependent projects also need +## DEPENDS: system dependencies of this project that dependent projects also need +catkin_package( +# INCLUDE_DIRS include +# LIBRARIES midas_cpp +# CATKIN_DEPENDS cv_bridge image_transport roscpp sensor_msgs std_msgs +# DEPENDS system_lib +) + +########### +## Build ## +########### + +## Specify additional locations of header files +## Your package locations should be listed before other locations +include_directories( +# include + ${catkin_INCLUDE_DIRS} +) + +## Declare a C++ library +# add_library(${PROJECT_NAME} +# src/${PROJECT_NAME}/midas_cpp.cpp +# ) + +## Add cmake target dependencies of the library +## as an example, code may need to be generated before libraries +## either from message generation or dynamic reconfigure +# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) + +## Declare a C++ executable +## With catkin_make all packages are built within a single CMake context +## The recommended prefix ensures that target names across packages don't collide +# add_executable(${PROJECT_NAME}_node src/midas_cpp_node.cpp) + +## Rename C++ executable without prefix +## The above recommended prefix causes long target names, the following renames the +## target back to the shorter version for ease of user use +## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" +# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") + +## Add cmake target dependencies of the executable +## same as for the library above +# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) + +## Specify libraries to link a library or executable target against +# target_link_libraries(${PROJECT_NAME}_node +# ${catkin_LIBRARIES} +# ) + +############# +## Install ## +############# + +# all install targets should use catkin DESTINATION variables +# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html + +## Mark executable scripts (Python etc.) for installation +## in contrast to setup.py, you can choose the destination +# catkin_install_python(PROGRAMS +# scripts/my_python_script +# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark executables for installation +## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html +# install(TARGETS ${PROJECT_NAME}_node +# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark libraries for installation +## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html +# install(TARGETS ${PROJECT_NAME} +# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} +# ) + +## Mark cpp header files for installation +# install(DIRECTORY include/${PROJECT_NAME}/ +# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} +# FILES_MATCHING PATTERN "*.h" +# PATTERN ".svn" EXCLUDE +# ) + +## Mark other files for installation (e.g. launch and bag files, etc.) +# install(FILES +# # myfile1 +# # myfile2 +# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} +# ) + +############# +## Testing ## +############# + +## Add gtest based cpp test target and link libraries +# catkin_add_gtest(${PROJECT_NAME}-test test/test_midas_cpp.cpp) +# if(TARGET ${PROJECT_NAME}-test) +# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) +# endif() + +## Add folders to be run by python nosetests +# catkin_add_nosetests(test) + +install(TARGETS ${PROJECT_NAME} + ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +) + +add_custom_command( + TARGET midas_cpp POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_BINARY_DIR}/midas_cpp + ${CMAKE_SOURCE_DIR}/midas_cpp +) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/launch/midas_cpp.launch b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/launch/midas_cpp.launch new file mode 100644 index 00000000..88e86f42 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/launch/midas_cpp.launch @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/launch/midas_talker_listener.launch b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/launch/midas_talker_listener.launch new file mode 100644 index 00000000..8817a4f4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/launch/midas_talker_listener.launch @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/package.xml b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/package.xml new file mode 100644 index 00000000..9cac90eb --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/package.xml @@ -0,0 +1,77 @@ + + + midas_cpp + 0.1.0 + The midas_cpp package + + Alexey Bochkovskiy + MIT + https://github.com/isl-org/MiDaS/tree/master/ros + + + + + + + TODO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + catkin + cv_bridge + image_transport + roscpp + rospy + sensor_msgs + std_msgs + cv_bridge + image_transport + roscpp + rospy + sensor_msgs + std_msgs + cv_bridge + image_transport + roscpp + rospy + sensor_msgs + std_msgs + + + + + + + + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/scripts/listener.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/scripts/listener.py new file mode 100644 index 00000000..6927ea7a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/scripts/listener.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +from __future__ import print_function + +import roslib +#roslib.load_manifest('my_package') +import sys +import rospy +import cv2 +import numpy as np +from std_msgs.msg import String +from sensor_msgs.msg import Image +from cv_bridge import CvBridge, CvBridgeError + +class video_show: + + def __init__(self): + self.show_output = rospy.get_param('~show_output', True) + self.save_output = rospy.get_param('~save_output', False) + self.output_video_file = rospy.get_param('~output_video_file','result.mp4') + # rospy.loginfo(f"Listener - params: show_output={self.show_output}, save_output={self.save_output}, output_video_file={self.output_video_file}") + + self.bridge = CvBridge() + self.image_sub = rospy.Subscriber("midas_topic", Image, self.callback) + + def callback(self, data): + try: + cv_image = self.bridge.imgmsg_to_cv2(data) + except CvBridgeError as e: + print(e) + return + + if cv_image.size == 0: + return + + rospy.loginfo("Listener: Received new frame") + cv_image = cv_image.astype("uint8") + + if self.show_output==True: + cv2.imshow("video_show", cv_image) + cv2.waitKey(10) + + if self.save_output==True: + if self.video_writer_init==False: + fourcc = cv2.VideoWriter_fourcc(*'XVID') + self.out = cv2.VideoWriter(self.output_video_file, fourcc, 25, (cv_image.shape[1], cv_image.shape[0])) + + self.out.write(cv_image) + + + +def main(args): + rospy.init_node('listener', anonymous=True) + ic = video_show() + try: + rospy.spin() + except KeyboardInterrupt: + print("Shutting down") + cv2.destroyAllWindows() + +if __name__ == '__main__': + main(sys.argv) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/scripts/listener_original.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/scripts/listener_original.py new file mode 100644 index 00000000..20e235f6 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/scripts/listener_original.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +from __future__ import print_function + +import roslib +#roslib.load_manifest('my_package') +import sys +import rospy +import cv2 +import numpy as np +from std_msgs.msg import String +from sensor_msgs.msg import Image +from cv_bridge import CvBridge, CvBridgeError + +class video_show: + + def __init__(self): + self.show_output = rospy.get_param('~show_output', True) + self.save_output = rospy.get_param('~save_output', False) + self.output_video_file = rospy.get_param('~output_video_file','result.mp4') + # rospy.loginfo(f"Listener original - params: show_output={self.show_output}, save_output={self.save_output}, output_video_file={self.output_video_file}") + + self.bridge = CvBridge() + self.image_sub = rospy.Subscriber("image_topic", Image, self.callback) + + def callback(self, data): + try: + cv_image = self.bridge.imgmsg_to_cv2(data) + except CvBridgeError as e: + print(e) + return + + if cv_image.size == 0: + return + + rospy.loginfo("Listener_original: Received new frame") + cv_image = cv_image.astype("uint8") + + if self.show_output==True: + cv2.imshow("video_show_orig", cv_image) + cv2.waitKey(10) + + if self.save_output==True: + if self.video_writer_init==False: + fourcc = cv2.VideoWriter_fourcc(*'XVID') + self.out = cv2.VideoWriter(self.output_video_file, fourcc, 25, (cv_image.shape[1], cv_image.shape[0])) + + self.out.write(cv_image) + + + +def main(args): + rospy.init_node('listener_original', anonymous=True) + ic = video_show() + try: + rospy.spin() + except KeyboardInterrupt: + print("Shutting down") + cv2.destroyAllWindows() + +if __name__ == '__main__': + main(sys.argv) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/scripts/talker.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/scripts/talker.py new file mode 100644 index 00000000..8219cc86 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/scripts/talker.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 + + +import roslib +#roslib.load_manifest('my_package') +import sys +import rospy +import cv2 +from std_msgs.msg import String +from sensor_msgs.msg import Image +from cv_bridge import CvBridge, CvBridgeError + + +def talker(): + rospy.init_node('talker', anonymous=True) + + use_camera = rospy.get_param('~use_camera', False) + input_video_file = rospy.get_param('~input_video_file','test.mp4') + # rospy.loginfo(f"Talker - params: use_camera={use_camera}, input_video_file={input_video_file}") + + # rospy.loginfo("Talker: Trying to open a video stream") + if use_camera == True: + cap = cv2.VideoCapture(0) + else: + cap = cv2.VideoCapture(input_video_file) + + pub = rospy.Publisher('image_topic', Image, queue_size=1) + rate = rospy.Rate(30) # 30hz + bridge = CvBridge() + + while not rospy.is_shutdown(): + ret, cv_image = cap.read() + if ret==False: + print("Talker: Video is over") + rospy.loginfo("Video is over") + return + + try: + image = bridge.cv2_to_imgmsg(cv_image, "bgr8") + except CvBridgeError as e: + rospy.logerr("Talker: cv2image conversion failed: ", e) + print(e) + continue + + rospy.loginfo("Talker: Publishing frame") + pub.publish(image) + rate.sleep() + +if __name__ == '__main__': + try: + talker() + except rospy.ROSInterruptException: + pass diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/src/main.cpp b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/src/main.cpp new file mode 100644 index 00000000..e4fc72c6 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/midas_cpp/src/main.cpp @@ -0,0 +1,285 @@ +#include +#include +#include +#include + +#include + +#include // One-stop header. + +#include +#include +#include +#include + +#include +#include + +// includes for OpenCV >= 3.x +#ifndef CV_VERSION_EPOCH +#include +#include +#include +#endif + +// OpenCV includes for OpenCV 2.x +#ifdef CV_VERSION_EPOCH +#include +#include +#include +#include +#endif + +static const std::string OPENCV_WINDOW = "Image window"; + +class Midas +{ + ros::NodeHandle nh_; + image_transport::ImageTransport it_; + image_transport::Subscriber image_sub_; + image_transport::Publisher image_pub_; + + torch::jit::script::Module module; + torch::Device device; + + auto ToTensor(cv::Mat img, bool show_output = false, bool unsqueeze = false, int unsqueeze_dim = 0) + { + //std::cout << "image shape: " << img.size() << std::endl; + at::Tensor tensor_image = torch::from_blob(img.data, { img.rows, img.cols, 3 }, at::kByte); + + if (unsqueeze) + { + tensor_image.unsqueeze_(unsqueeze_dim); + //std::cout << "tensors new shape: " << tensor_image.sizes() << std::endl; + } + + if (show_output) + { + std::cout << tensor_image.slice(2, 0, 1) << std::endl; + } + //std::cout << "tenor shape: " << tensor_image.sizes() << std::endl; + return tensor_image; + } + + auto ToInput(at::Tensor tensor_image) + { + // Create a vector of inputs. + return std::vector{tensor_image}; + } + + auto ToCvImage(at::Tensor tensor, int cv_type = CV_8UC3) + { + int width = tensor.sizes()[0]; + int height = tensor.sizes()[1]; + try + { + cv::Mat output_mat; + if (cv_type == CV_8UC4 || cv_type == CV_8UC3 || cv_type == CV_8UC2 || cv_type == CV_8UC1) { + cv::Mat cv_image(cv::Size{ height, width }, cv_type, tensor.data_ptr()); + output_mat = cv_image; + } + else if (cv_type == CV_32FC4 || cv_type == CV_32FC3 || cv_type == CV_32FC2 || cv_type == CV_32FC1) { + cv::Mat cv_image(cv::Size{ height, width }, cv_type, tensor.data_ptr()); + output_mat = cv_image; + } + else if (cv_type == CV_64FC4 || cv_type == CV_64FC3 || cv_type == CV_64FC2 || cv_type == CV_64FC1) { + cv::Mat cv_image(cv::Size{ height, width }, cv_type, tensor.data_ptr()); + output_mat = cv_image; + } + + //show_image(output_mat, "converted image from tensor"); + return output_mat.clone(); + } + catch (const c10::Error& e) + { + std::cout << "an error has occured : " << e.msg() << std::endl; + } + return cv::Mat(height, width, CV_8UC3); + } + + std::string input_topic, output_topic, model_name; + bool out_orig_size; + int net_width, net_height; + torch::NoGradGuard guard; + at::Tensor mean, std; + at::Tensor output, tensor; + +public: + Midas() + : nh_(), it_(nh_), device(torch::Device(torch::kCPU)) + { + ros::param::param("~input_topic", input_topic, "image_topic"); + ros::param::param("~output_topic", output_topic, "midas_topic"); + ros::param::param("~model_name", model_name, "model-small-traced.pt"); + ros::param::param("~out_orig_size", out_orig_size, true); + ros::param::param("~net_width", net_width, 256); + ros::param::param("~net_height", net_height, 256); + + std::cout << ", input_topic = " << input_topic << + ", output_topic = " << output_topic << + ", model_name = " << model_name << + ", out_orig_size = " << out_orig_size << + ", net_width = " << net_width << + ", net_height = " << net_height << + std::endl; + + // Subscrive to input video feed and publish output video feed + image_sub_ = it_.subscribe(input_topic, 1, &Midas::imageCb, this); + image_pub_ = it_.advertise(output_topic, 1); + + std::cout << "Try to load torchscript model \n"; + + try { + // Deserialize the ScriptModule from a file using torch::jit::load(). + module = torch::jit::load(model_name); + } + catch (const c10::Error& e) { + std::cerr << "error loading the model\n"; + exit(0); + } + + std::cout << "ok\n"; + + try { + module.eval(); + torch::jit::getProfilingMode() = false; + torch::jit::setGraphExecutorOptimize(true); + + mean = torch::tensor({ 0.485, 0.456, 0.406 }); + std = torch::tensor({ 0.229, 0.224, 0.225 }); + + if (torch::hasCUDA()) { + std::cout << "cuda is available" << std::endl; + at::globalContext().setBenchmarkCuDNN(true); + device = torch::Device(torch::kCUDA); + module.to(device); + mean = mean.to(device); + std = std.to(device); + } + } + catch (const c10::Error& e) + { + std::cerr << " module initialization: " << e.msg() << std::endl; + } + } + + ~Midas() + { + } + + void imageCb(const sensor_msgs::ImageConstPtr& msg) + { + cv_bridge::CvImagePtr cv_ptr; + try + { + // sensor_msgs::Image to cv::Mat + cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::RGB8); + } + catch (cv_bridge::Exception& e) + { + ROS_ERROR("cv_bridge exception: %s", e.what()); + return; + } + + // pre-processing + auto tensor_cpu = ToTensor(cv_ptr->image); // OpenCV-image -> Libtorch-tensor + + try { + tensor = tensor_cpu.to(device); // move to device (CPU or GPU) + + tensor = tensor.toType(c10::kFloat); + tensor = tensor.permute({ 2, 0, 1 }); // HWC -> CHW + tensor = tensor.unsqueeze(0); + tensor = at::upsample_bilinear2d(tensor, { net_height, net_width }, true); // resize + tensor = tensor.squeeze(0); + tensor = tensor.permute({ 1, 2, 0 }); // CHW -> HWC + + tensor = tensor.div(255).sub(mean).div(std); // normalization + tensor = tensor.permute({ 2, 0, 1 }); // HWC -> CHW + tensor.unsqueeze_(0); // CHW -> NCHW + } + catch (const c10::Error& e) + { + std::cerr << " pre-processing exception: " << e.msg() << std::endl; + return; + } + + auto input_to_net = ToInput(tensor); // input to the network + + // inference + output; + try { + output = module.forward(input_to_net).toTensor(); // run inference + } + catch (const c10::Error& e) + { + std::cerr << " module.forward() exception: " << e.msg() << std::endl; + return; + } + + output = output.detach().to(torch::kF32); + + // move to CPU temporary + at::Tensor output_tmp = output; + output_tmp = output_tmp.to(torch::kCPU); + + // normalization + float min_val = std::numeric_limits::max(); + float max_val = std::numeric_limits::min(); + + for (int i = 0; i < net_width * net_height; ++i) { + float val = output_tmp.data_ptr()[i]; + if (min_val > val) min_val = val; + if (max_val < val) max_val = val; + } + float range_val = max_val - min_val; + + output = output.sub(min_val).div(range_val).mul(255.0F).clamp(0, 255).to(torch::kF32); // .to(torch::kU8); + + // resize to the original size if required + if (out_orig_size) { + try { + output = at::upsample_bilinear2d(output.unsqueeze(0), { cv_ptr->image.size().height, cv_ptr->image.size().width }, true); + output = output.squeeze(0); + } + catch (const c10::Error& e) + { + std::cout << " upsample_bilinear2d() exception: " << e.msg() << std::endl; + return; + } + } + output = output.permute({ 1, 2, 0 }).to(torch::kCPU); + + int cv_type = CV_32FC1; // CV_8UC1; + auto cv_img = ToCvImage(output, cv_type); + + sensor_msgs::Image img_msg; + + try { + // cv::Mat -> sensor_msgs::Image + std_msgs::Header header; // empty header + header.seq = 0; // user defined counter + header.stamp = ros::Time::now();// time + //cv_bridge::CvImage img_bridge = cv_bridge::CvImage(header, sensor_msgs::image_encodings::MONO8, cv_img); + cv_bridge::CvImage img_bridge = cv_bridge::CvImage(header, sensor_msgs::image_encodings::TYPE_32FC1, cv_img); + + img_bridge.toImageMsg(img_msg); // cv_bridge -> sensor_msgs::Image + } + catch (cv_bridge::Exception& e) + { + ROS_ERROR("cv_bridge exception: %s", e.what()); + return; + } + + // Output modified video stream + image_pub_.publish(img_msg); + } +}; + +int main(int argc, char** argv) +{ + ros::init(argc, argv, "midas", ros::init_options::AnonymousName); + Midas ic; + ros::spin(); + return 0; +} \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/run_talker_listener_test.sh b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/run_talker_listener_test.sh new file mode 100644 index 00000000..a997c426 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/ros/run_talker_listener_test.sh @@ -0,0 +1,16 @@ +# place any test.mp4 file near with this file + +# roscore +# rosnode kill -a + +source ~/catkin_ws/devel/setup.bash + +roscore & +P1=$! +rosrun midas_cpp talker.py & +P2=$! +rosrun midas_cpp listener_original.py & +P3=$! +rosrun midas_cpp listener.py & +P4=$! +wait $P1 $P2 $P3 $P4 \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/run.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/run.py new file mode 100644 index 00000000..5696ef05 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/run.py @@ -0,0 +1,277 @@ +"""Compute depth maps for images in the input folder. +""" +import os +import glob +import torch +import utils +import cv2 +import argparse +import time + +import numpy as np + +from imutils.video import VideoStream +from midas.model_loader import default_models, load_model + +first_execution = True +def process(device, model, model_type, image, input_size, target_size, optimize, use_camera): + """ + Run the inference and interpolate. + + Args: + device (torch.device): the torch device used + model: the model used for inference + model_type: the type of the model + image: the image fed into the neural network + input_size: the size (width, height) of the neural network input (for OpenVINO) + target_size: the size (width, height) the neural network output is interpolated to + optimize: optimize the model to half-floats on CUDA? + use_camera: is the camera used? + + Returns: + the prediction + """ + global first_execution + + if "openvino" in model_type: + if first_execution or not use_camera: + print(f" Input resized to {input_size[0]}x{input_size[1]} before entering the encoder") + first_execution = False + + sample = [np.reshape(image, (1, 3, *input_size))] + prediction = model(sample)[model.output(0)][0] + prediction = cv2.resize(prediction, dsize=target_size, + interpolation=cv2.INTER_CUBIC) + else: + sample = torch.from_numpy(image).to(device).unsqueeze(0) + + if optimize and device == torch.device("cuda"): + if first_execution: + print(" Optimization to half-floats activated. Use with caution, because models like Swin require\n" + " float precision to work properly and may yield non-finite depth values to some extent for\n" + " half-floats.") + sample = sample.to(memory_format=torch.channels_last) + sample = sample.half() + + if first_execution or not use_camera: + height, width = sample.shape[2:] + print(f" Input resized to {width}x{height} before entering the encoder") + first_execution = False + + prediction = model.forward(sample) + prediction = ( + torch.nn.functional.interpolate( + prediction.unsqueeze(1), + size=target_size[::-1], + mode="bicubic", + align_corners=False, + ) + .squeeze() + .cpu() + .numpy() + ) + + return prediction + + +def create_side_by_side(image, depth, grayscale): + """ + Take an RGB image and depth map and place them side by side. This includes a proper normalization of the depth map + for better visibility. + + Args: + image: the RGB image + depth: the depth map + grayscale: use a grayscale colormap? + + Returns: + the image and depth map place side by side + """ + depth_min = depth.min() + depth_max = depth.max() + normalized_depth = 255 * (depth - depth_min) / (depth_max - depth_min) + normalized_depth *= 3 + + right_side = np.repeat(np.expand_dims(normalized_depth, 2), 3, axis=2) / 3 + if not grayscale: + right_side = cv2.applyColorMap(np.uint8(right_side), cv2.COLORMAP_INFERNO) + + if image is None: + return right_side + else: + return np.concatenate((image, right_side), axis=1) + + +def run(input_path, output_path, model_path, model_type="dpt_beit_large_512", optimize=False, side=False, height=None, + square=False, grayscale=False): + """Run MonoDepthNN to compute depth maps. + + Args: + input_path (str): path to input folder + output_path (str): path to output folder + model_path (str): path to saved model + model_type (str): the model type + optimize (bool): optimize the model to half-floats on CUDA? + side (bool): RGB and depth side by side in output images? + height (int): inference encoder image height + square (bool): resize to a square resolution? + grayscale (bool): use a grayscale colormap? + """ + print("Initialize") + + # select device + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + print("Device: %s" % device) + + model, transform, net_w, net_h = load_model(device, model_path, model_type, optimize, height, square) + + # get input + if input_path is not None: + image_names = glob.glob(os.path.join(input_path, "*")) + num_images = len(image_names) + else: + print("No input path specified. Grabbing images from camera.") + + # create output folder + if output_path is not None: + os.makedirs(output_path, exist_ok=True) + + print("Start processing") + + if input_path is not None: + if output_path is None: + print("Warning: No output path specified. Images will be processed but not shown or stored anywhere.") + for index, image_name in enumerate(image_names): + + print(" Processing {} ({}/{})".format(image_name, index + 1, num_images)) + + # input + original_image_rgb = utils.read_image(image_name) # in [0, 1] + image = transform({"image": original_image_rgb})["image"] + + # compute + with torch.no_grad(): + prediction = process(device, model, model_type, image, (net_w, net_h), original_image_rgb.shape[1::-1], + optimize, False) + + # output + if output_path is not None: + filename = os.path.join( + output_path, os.path.splitext(os.path.basename(image_name))[0] + '-' + model_type + ) + if not side: + utils.write_depth(filename, prediction, grayscale, bits=2) + else: + original_image_bgr = np.flip(original_image_rgb, 2) + content = create_side_by_side(original_image_bgr*255, prediction, grayscale) + cv2.imwrite(filename + ".png", content) + utils.write_pfm(filename + ".pfm", prediction.astype(np.float32)) + + else: + with torch.no_grad(): + fps = 1 + video = VideoStream(0).start() + time_start = time.time() + frame_index = 0 + while True: + frame = video.read() + if frame is not None: + original_image_rgb = np.flip(frame, 2) # in [0, 255] (flip required to get RGB) + image = transform({"image": original_image_rgb/255})["image"] + + prediction = process(device, model, model_type, image, (net_w, net_h), + original_image_rgb.shape[1::-1], optimize, True) + + original_image_bgr = np.flip(original_image_rgb, 2) if side else None + content = create_side_by_side(original_image_bgr, prediction, grayscale) + cv2.imshow('MiDaS Depth Estimation - Press Escape to close window ', content/255) + + if output_path is not None: + filename = os.path.join(output_path, 'Camera' + '-' + model_type + '_' + str(frame_index)) + cv2.imwrite(filename + ".png", content) + + alpha = 0.1 + if time.time()-time_start > 0: + fps = (1 - alpha) * fps + alpha * 1 / (time.time()-time_start) # exponential moving average + time_start = time.time() + print(f"\rFPS: {round(fps,2)}", end="") + + if cv2.waitKey(1) == 27: # Escape key + break + + frame_index += 1 + print() + + print("Finished") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument('-i', '--input_path', + default=None, + help='Folder with input images (if no input path is specified, images are tried to be grabbed ' + 'from camera)' + ) + + parser.add_argument('-o', '--output_path', + default=None, + help='Folder for output images' + ) + + parser.add_argument('-m', '--model_weights', + default=None, + help='Path to the trained weights of model' + ) + + parser.add_argument('-t', '--model_type', + default='dpt_beit_large_512', + help='Model type: ' + 'dpt_beit_large_512, dpt_beit_large_384, dpt_beit_base_384, dpt_swin2_large_384, ' + 'dpt_swin2_base_384, dpt_swin2_tiny_256, dpt_swin_large_384, dpt_next_vit_large_384, ' + 'dpt_levit_224, dpt_large_384, dpt_hybrid_384, midas_v21_384, midas_v21_small_256 or ' + 'openvino_midas_v21_small_256' + ) + + parser.add_argument('-s', '--side', + action='store_true', + help='Output images contain RGB and depth images side by side' + ) + + parser.add_argument('--optimize', dest='optimize', action='store_true', help='Use half-float optimization') + parser.set_defaults(optimize=False) + + parser.add_argument('--height', + type=int, default=None, + help='Preferred height of images feed into the encoder during inference. Note that the ' + 'preferred height may differ from the actual height, because an alignment to multiples of ' + '32 takes place. Many models support only the height chosen during training, which is ' + 'used automatically if this parameter is not set.' + ) + parser.add_argument('--square', + action='store_true', + help='Option to resize images to a square resolution by changing their widths when images are ' + 'fed into the encoder during inference. If this parameter is not set, the aspect ratio of ' + 'images is tried to be preserved if supported by the model.' + ) + parser.add_argument('--grayscale', + action='store_true', + help='Use a grayscale colormap instead of the inferno one. Although the inferno colormap, ' + 'which is used by default, is better for visibility, it does not allow storing 16-bit ' + 'depth values in PNGs but only 8-bit ones due to the precision limitation of this ' + 'colormap.' + ) + + args = parser.parse_args() + + + if args.model_weights is None: + args.model_weights = default_models[args.model_type] + + # set torch options + torch.backends.cudnn.enabled = True + torch.backends.cudnn.benchmark = True + + # compute depth maps + run(args.input_path, args.output_path, args.model_weights, args.model_type, args.optimize, args.side, args.height, + args.square, args.grayscale) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/README.md b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/README.md new file mode 100644 index 00000000..5b5fe0e6 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/README.md @@ -0,0 +1,147 @@ +## Towards Robust Monocular Depth Estimation: Mixing Datasets for Zero-shot Cross-dataset Transfer + +### TensorFlow inference using `.pb` and `.onnx` models + +1. [Run inference on TensorFlow-model by using TensorFlow](#run-inference-on-tensorflow-model-by-using-tensorFlow) + +2. [Run inference on ONNX-model by using TensorFlow](#run-inference-on-onnx-model-by-using-tensorflow) + +3. [Make ONNX model from downloaded Pytorch model file](#make-onnx-model-from-downloaded-pytorch-model-file) + + +### Run inference on TensorFlow-model by using TensorFlow + +1) Download the model weights [model-f6b98070.pb](https://github.com/isl-org/MiDaS/releases/download/v2_1/model-f6b98070.pb) +and [model-small.pb](https://github.com/isl-org/MiDaS/releases/download/v2_1/model-small.pb) and place the +file in the `/tf/` folder. + +2) Set up dependencies: + +```shell +# install OpenCV +pip install --upgrade pip +pip install opencv-python + +# install TensorFlow +pip install -I grpcio tensorflow==2.3.0 tensorflow-addons==0.11.2 numpy==1.18.0 +``` + +#### Usage + +1) Place one or more input images in the folder `tf/input`. + +2) Run the model: + + ```shell + python tf/run_pb.py + ``` + + Or run the small model: + + ```shell + python tf/run_pb.py --model_weights model-small.pb --model_type small + ``` + +3) The resulting inverse depth maps are written to the `tf/output` folder. + + +### Run inference on ONNX-model by using ONNX-Runtime + +1) Download the model weights [model-f6b98070.onnx](https://github.com/isl-org/MiDaS/releases/download/v2_1/model-f6b98070.onnx) +and [model-small.onnx](https://github.com/isl-org/MiDaS/releases/download/v2_1/model-small.onnx) and place the +file in the `/tf/` folder. + +2) Set up dependencies: + +```shell +# install OpenCV +pip install --upgrade pip +pip install opencv-python + +# install ONNX +pip install onnx==1.7.0 + +# install ONNX Runtime +pip install onnxruntime==1.5.2 +``` + +#### Usage + +1) Place one or more input images in the folder `tf/input`. + +2) Run the model: + + ```shell + python tf/run_onnx.py + ``` + + Or run the small model: + + ```shell + python tf/run_onnx.py --model_weights model-small.onnx --model_type small + ``` + +3) The resulting inverse depth maps are written to the `tf/output` folder. + + + +### Make ONNX model from downloaded Pytorch model file + +1) Download the model weights [model-f6b98070.pt](https://github.com/isl-org/MiDaS/releases/download/v2_1/model-f6b98070.pt) and place the +file in the root folder. + +2) Set up dependencies: + +```shell +# install OpenCV +pip install --upgrade pip +pip install opencv-python + +# install PyTorch TorchVision +pip install -I torch==1.7.0 torchvision==0.8.0 + +# install TensorFlow +pip install -I grpcio tensorflow==2.3.0 tensorflow-addons==0.11.2 numpy==1.18.0 + +# install ONNX +pip install onnx==1.7.0 + +# install ONNX-TensorFlow +git clone https://github.com/onnx/onnx-tensorflow.git +cd onnx-tensorflow +git checkout 095b51b88e35c4001d70f15f80f31014b592b81e +pip install -e . +``` + +#### Usage + +1) Run the converter: + + ```shell + python tf/make_onnx_model.py + ``` + +2) The resulting `model-f6b98070.onnx` file is written to the `/tf/` folder. + + +### Requirements + + The code was tested with Python 3.6.9, PyTorch 1.5.1, TensorFlow 2.2.0, TensorFlow-addons 0.8.3, ONNX 1.7.0, ONNX-TensorFlow (GitHub-master-17.07.2020) and OpenCV 4.3.0. + +### Citation + +Please cite our paper if you use this code or any of the models: +``` +@article{Ranftl2019, + author = {Ren\'{e} Ranftl and Katrin Lasinger and David Hafner and Konrad Schindler and Vladlen Koltun}, + title = {Towards Robust Monocular Depth Estimation: Mixing Datasets for Zero-shot Cross-dataset Transfer}, + journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence (TPAMI)}, + year = {2020}, +} +``` + +### License + +MIT License + + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/input/.placeholder b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/input/.placeholder new file mode 100644 index 00000000..e69de29b diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/make_onnx_model.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/make_onnx_model.py new file mode 100644 index 00000000..d14b0e4e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/make_onnx_model.py @@ -0,0 +1,112 @@ +"""Compute depth maps for images in the input folder. +""" +import os +import ntpath +import glob +import torch +import utils +import cv2 +import numpy as np +from torchvision.transforms import Compose, Normalize +from torchvision import transforms + +from shutil import copyfile +import fileinput +import sys +sys.path.append(os.getcwd() + '/..') + +def modify_file(): + modify_filename = '../midas/blocks.py' + copyfile(modify_filename, modify_filename+'.bak') + + with open(modify_filename, 'r') as file : + filedata = file.read() + + filedata = filedata.replace('align_corners=True', 'align_corners=False') + filedata = filedata.replace('import torch.nn as nn', 'import torch.nn as nn\nimport torchvision.models as models') + filedata = filedata.replace('torch.hub.load("facebookresearch/WSL-Images", "resnext101_32x8d_wsl")', 'models.resnext101_32x8d()') + + with open(modify_filename, 'w') as file: + file.write(filedata) + +def restore_file(): + modify_filename = '../midas/blocks.py' + copyfile(modify_filename+'.bak', modify_filename) + +modify_file() + +from midas.midas_net import MidasNet +from midas.transforms import Resize, NormalizeImage, PrepareForNet + +restore_file() + + +class MidasNet_preprocessing(MidasNet): + """Network for monocular depth estimation. + """ + def forward(self, x): + """Forward pass. + + Args: + x (tensor): input data (image) + + Returns: + tensor: depth + """ + + mean = torch.tensor([0.485, 0.456, 0.406]) + std = torch.tensor([0.229, 0.224, 0.225]) + x.sub_(mean[None, :, None, None]).div_(std[None, :, None, None]) + + return MidasNet.forward(self, x) + + +def run(model_path): + """Run MonoDepthNN to compute depth maps. + + Args: + model_path (str): path to saved model + """ + print("initialize") + + # select device + + # load network + #model = MidasNet(model_path, non_negative=True) + model = MidasNet_preprocessing(model_path, non_negative=True) + + model.eval() + + print("start processing") + + # input + img_input = np.zeros((3, 384, 384), np.float32) + + # compute + with torch.no_grad(): + sample = torch.from_numpy(img_input).unsqueeze(0) + prediction = model.forward(sample) + prediction = ( + torch.nn.functional.interpolate( + prediction.unsqueeze(1), + size=img_input.shape[:2], + mode="bicubic", + align_corners=False, + ) + .squeeze() + .cpu() + .numpy() + ) + + torch.onnx.export(model, sample, ntpath.basename(model_path).rsplit('.', 1)[0]+'.onnx', opset_version=9) + + print("finished") + + +if __name__ == "__main__": + # set paths + # MODEL_PATH = "model.pt" + MODEL_PATH = "../model-f6b98070.pt" + + # compute depth maps + run(MODEL_PATH) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/output/.placeholder b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/output/.placeholder new file mode 100644 index 00000000..e69de29b diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/run_onnx.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/run_onnx.py new file mode 100644 index 00000000..7107b999 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/run_onnx.py @@ -0,0 +1,119 @@ +"""Compute depth maps for images in the input folder. +""" +import os +import glob +import utils +import cv2 +import sys +import numpy as np +import argparse + +import onnx +import onnxruntime as rt + +from transforms import Resize, NormalizeImage, PrepareForNet + + +def run(input_path, output_path, model_path, model_type="large"): + """Run MonoDepthNN to compute depth maps. + + Args: + input_path (str): path to input folder + output_path (str): path to output folder + model_path (str): path to saved model + """ + print("initialize") + + # select device + device = "CUDA:0" + #device = "CPU" + print("device: %s" % device) + + # network resolution + if model_type == "large": + net_w, net_h = 384, 384 + elif model_type == "small": + net_w, net_h = 256, 256 + else: + print(f"model_type '{model_type}' not implemented, use: --model_type large") + assert False + + # load network + print("loading model...") + model = rt.InferenceSession(model_path) + input_name = model.get_inputs()[0].name + output_name = model.get_outputs()[0].name + + resize_image = Resize( + net_w, + net_h, + resize_target=None, + keep_aspect_ratio=False, + ensure_multiple_of=32, + resize_method="upper_bound", + image_interpolation_method=cv2.INTER_CUBIC, + ) + + def compose2(f1, f2): + return lambda x: f2(f1(x)) + + transform = compose2(resize_image, PrepareForNet()) + + # get input + img_names = glob.glob(os.path.join(input_path, "*")) + num_images = len(img_names) + + # create output folder + os.makedirs(output_path, exist_ok=True) + + print("start processing") + + for ind, img_name in enumerate(img_names): + + print(" processing {} ({}/{})".format(img_name, ind + 1, num_images)) + + # input + img = utils.read_image(img_name) + img_input = transform({"image": img})["image"] + + # compute + output = model.run([output_name], {input_name: img_input.reshape(1, 3, net_h, net_w).astype(np.float32)})[0] + prediction = np.array(output).reshape(net_h, net_w) + prediction = cv2.resize(prediction, (img.shape[1], img.shape[0]), interpolation=cv2.INTER_CUBIC) + + # output + filename = os.path.join( + output_path, os.path.splitext(os.path.basename(img_name))[0] + ) + utils.write_depth(filename, prediction, bits=2) + + print("finished") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument('-i', '--input_path', + default='input', + help='folder with input images' + ) + + parser.add_argument('-o', '--output_path', + default='output', + help='folder for output images' + ) + + parser.add_argument('-m', '--model_weights', + default='model-f6b98070.onnx', + help='path to the trained weights of model' + ) + + parser.add_argument('-t', '--model_type', + default='large', + help='model type: large or small' + ) + + args = parser.parse_args() + + # compute depth maps + run(args.input_path, args.output_path, args.model_weights, args.model_type) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/run_pb.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/run_pb.py new file mode 100644 index 00000000..e46254f7 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/run_pb.py @@ -0,0 +1,135 @@ +"""Compute depth maps for images in the input folder. +""" +import os +import glob +import utils +import cv2 +import argparse + +import tensorflow as tf + +from transforms import Resize, NormalizeImage, PrepareForNet + +def run(input_path, output_path, model_path, model_type="large"): + """Run MonoDepthNN to compute depth maps. + + Args: + input_path (str): path to input folder + output_path (str): path to output folder + model_path (str): path to saved model + """ + print("initialize") + + # the runtime initialization will not allocate all memory on the device to avoid out of GPU memory + gpus = tf.config.experimental.list_physical_devices('GPU') + if gpus: + try: + for gpu in gpus: + #tf.config.experimental.set_memory_growth(gpu, True) + tf.config.experimental.set_virtual_device_configuration(gpu, + [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=4000)]) + except RuntimeError as e: + print(e) + + # network resolution + if model_type == "large": + net_w, net_h = 384, 384 + elif model_type == "small": + net_w, net_h = 256, 256 + else: + print(f"model_type '{model_type}' not implemented, use: --model_type large") + assert False + + # load network + graph_def = tf.compat.v1.GraphDef() + with tf.io.gfile.GFile(model_path, 'rb') as f: + graph_def.ParseFromString(f.read()) + tf.import_graph_def(graph_def, name='') + + + model_operations = tf.compat.v1.get_default_graph().get_operations() + input_node = '0:0' + output_layer = model_operations[len(model_operations) - 1].name + ':0' + print("Last layer name: ", output_layer) + + resize_image = Resize( + net_w, + net_h, + resize_target=None, + keep_aspect_ratio=False, + ensure_multiple_of=32, + resize_method="upper_bound", + image_interpolation_method=cv2.INTER_CUBIC, + ) + + def compose2(f1, f2): + return lambda x: f2(f1(x)) + + transform = compose2(resize_image, PrepareForNet()) + + # get input + img_names = glob.glob(os.path.join(input_path, "*")) + num_images = len(img_names) + + # create output folder + os.makedirs(output_path, exist_ok=True) + + print("start processing") + + with tf.compat.v1.Session() as sess: + try: + # load images + for ind, img_name in enumerate(img_names): + + print(" processing {} ({}/{})".format(img_name, ind + 1, num_images)) + + # input + img = utils.read_image(img_name) + img_input = transform({"image": img})["image"] + + # compute + prob_tensor = sess.graph.get_tensor_by_name(output_layer) + prediction, = sess.run(prob_tensor, {input_node: [img_input] }) + prediction = prediction.reshape(net_h, net_w) + prediction = cv2.resize(prediction, (img.shape[1], img.shape[0]), interpolation=cv2.INTER_CUBIC) + + # output + filename = os.path.join( + output_path, os.path.splitext(os.path.basename(img_name))[0] + ) + utils.write_depth(filename, prediction, bits=2) + + except KeyError: + print ("Couldn't find input node: ' + input_node + ' or output layer: " + output_layer + ".") + exit(-1) + + print("finished") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument('-i', '--input_path', + default='input', + help='folder with input images' + ) + + parser.add_argument('-o', '--output_path', + default='output', + help='folder for output images' + ) + + parser.add_argument('-m', '--model_weights', + default='model-f6b98070.pb', + help='path to the trained weights of model' + ) + + parser.add_argument('-t', '--model_type', + default='large', + help='model type: large or small' + ) + + args = parser.parse_args() + + # compute depth maps + run(args.input_path, args.output_path, args.model_weights, args.model_type) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/transforms.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/transforms.py new file mode 100644 index 00000000..350cbc11 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/transforms.py @@ -0,0 +1,234 @@ +import numpy as np +import cv2 +import math + + +def apply_min_size(sample, size, image_interpolation_method=cv2.INTER_AREA): + """Rezise the sample to ensure the given size. Keeps aspect ratio. + + Args: + sample (dict): sample + size (tuple): image size + + Returns: + tuple: new size + """ + shape = list(sample["disparity"].shape) + + if shape[0] >= size[0] and shape[1] >= size[1]: + return sample + + scale = [0, 0] + scale[0] = size[0] / shape[0] + scale[1] = size[1] / shape[1] + + scale = max(scale) + + shape[0] = math.ceil(scale * shape[0]) + shape[1] = math.ceil(scale * shape[1]) + + # resize + sample["image"] = cv2.resize( + sample["image"], tuple(shape[::-1]), interpolation=image_interpolation_method + ) + + sample["disparity"] = cv2.resize( + sample["disparity"], tuple(shape[::-1]), interpolation=cv2.INTER_NEAREST + ) + sample["mask"] = cv2.resize( + sample["mask"].astype(np.float32), + tuple(shape[::-1]), + interpolation=cv2.INTER_NEAREST, + ) + sample["mask"] = sample["mask"].astype(bool) + + return tuple(shape) + + +class Resize(object): + """Resize sample to given size (width, height). + """ + + def __init__( + self, + width, + height, + resize_target=True, + keep_aspect_ratio=False, + ensure_multiple_of=1, + resize_method="lower_bound", + image_interpolation_method=cv2.INTER_AREA, + ): + """Init. + + Args: + width (int): desired output width + height (int): desired output height + resize_target (bool, optional): + True: Resize the full sample (image, mask, target). + False: Resize image only. + Defaults to True. + keep_aspect_ratio (bool, optional): + True: Keep the aspect ratio of the input sample. + Output sample might not have the given width and height, and + resize behaviour depends on the parameter 'resize_method'. + Defaults to False. + ensure_multiple_of (int, optional): + Output width and height is constrained to be multiple of this parameter. + Defaults to 1. + resize_method (str, optional): + "lower_bound": Output will be at least as large as the given size. + "upper_bound": Output will be at max as large as the given size. (Output size might be smaller than given size.) + "minimal": Scale as least as possible. (Output size might be smaller than given size.) + Defaults to "lower_bound". + """ + self.__width = width + self.__height = height + + self.__resize_target = resize_target + self.__keep_aspect_ratio = keep_aspect_ratio + self.__multiple_of = ensure_multiple_of + self.__resize_method = resize_method + self.__image_interpolation_method = image_interpolation_method + + def constrain_to_multiple_of(self, x, min_val=0, max_val=None): + y = (np.round(x / self.__multiple_of) * self.__multiple_of).astype(int) + + if max_val is not None and y > max_val: + y = (np.floor(x / self.__multiple_of) * self.__multiple_of).astype(int) + + if y < min_val: + y = (np.ceil(x / self.__multiple_of) * self.__multiple_of).astype(int) + + return y + + def get_size(self, width, height): + # determine new height and width + scale_height = self.__height / height + scale_width = self.__width / width + + if self.__keep_aspect_ratio: + if self.__resize_method == "lower_bound": + # scale such that output size is lower bound + if scale_width > scale_height: + # fit width + scale_height = scale_width + else: + # fit height + scale_width = scale_height + elif self.__resize_method == "upper_bound": + # scale such that output size is upper bound + if scale_width < scale_height: + # fit width + scale_height = scale_width + else: + # fit height + scale_width = scale_height + elif self.__resize_method == "minimal": + # scale as least as possbile + if abs(1 - scale_width) < abs(1 - scale_height): + # fit width + scale_height = scale_width + else: + # fit height + scale_width = scale_height + else: + raise ValueError( + f"resize_method {self.__resize_method} not implemented" + ) + + if self.__resize_method == "lower_bound": + new_height = self.constrain_to_multiple_of( + scale_height * height, min_val=self.__height + ) + new_width = self.constrain_to_multiple_of( + scale_width * width, min_val=self.__width + ) + elif self.__resize_method == "upper_bound": + new_height = self.constrain_to_multiple_of( + scale_height * height, max_val=self.__height + ) + new_width = self.constrain_to_multiple_of( + scale_width * width, max_val=self.__width + ) + elif self.__resize_method == "minimal": + new_height = self.constrain_to_multiple_of(scale_height * height) + new_width = self.constrain_to_multiple_of(scale_width * width) + else: + raise ValueError(f"resize_method {self.__resize_method} not implemented") + + return (new_width, new_height) + + def __call__(self, sample): + width, height = self.get_size( + sample["image"].shape[1], sample["image"].shape[0] + ) + + # resize sample + sample["image"] = cv2.resize( + sample["image"], + (width, height), + interpolation=self.__image_interpolation_method, + ) + + if self.__resize_target: + if "disparity" in sample: + sample["disparity"] = cv2.resize( + sample["disparity"], + (width, height), + interpolation=cv2.INTER_NEAREST, + ) + + if "depth" in sample: + sample["depth"] = cv2.resize( + sample["depth"], (width, height), interpolation=cv2.INTER_NEAREST + ) + + sample["mask"] = cv2.resize( + sample["mask"].astype(np.float32), + (width, height), + interpolation=cv2.INTER_NEAREST, + ) + sample["mask"] = sample["mask"].astype(bool) + + return sample + + +class NormalizeImage(object): + """Normlize image by given mean and std. + """ + + def __init__(self, mean, std): + self.__mean = mean + self.__std = std + + def __call__(self, sample): + sample["image"] = (sample["image"] - self.__mean) / self.__std + + return sample + + +class PrepareForNet(object): + """Prepare sample for usage as network input. + """ + + def __init__(self): + pass + + def __call__(self, sample): + image = np.transpose(sample["image"], (2, 0, 1)) + sample["image"] = np.ascontiguousarray(image).astype(np.float32) + + if "mask" in sample: + sample["mask"] = sample["mask"].astype(np.float32) + sample["mask"] = np.ascontiguousarray(sample["mask"]) + + if "disparity" in sample: + disparity = sample["disparity"].astype(np.float32) + sample["disparity"] = np.ascontiguousarray(disparity) + + if "depth" in sample: + depth = sample["depth"].astype(np.float32) + sample["depth"] = np.ascontiguousarray(depth) + + return sample diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/utils.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/utils.py new file mode 100644 index 00000000..ff9a54bd --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/tf/utils.py @@ -0,0 +1,82 @@ +import numpy as np +import sys +import cv2 + + +def write_pfm(path, image, scale=1): + """Write pfm file. + Args: + path (str): pathto file + image (array): data + scale (int, optional): Scale. Defaults to 1. + """ + + with open(path, "wb") as file: + color = None + + if image.dtype.name != "float32": + raise Exception("Image dtype must be float32.") + + image = np.flipud(image) + + if len(image.shape) == 3 and image.shape[2] == 3: # color image + color = True + elif ( + len(image.shape) == 2 or len(image.shape) == 3 and image.shape[2] == 1 + ): # greyscale + color = False + else: + raise Exception("Image must have H x W x 3, H x W x 1 or H x W dimensions.") + + file.write("PF\n" if color else "Pf\n".encode()) + file.write("%d %d\n".encode() % (image.shape[1], image.shape[0])) + + endian = image.dtype.byteorder + + if endian == "<" or endian == "=" and sys.byteorder == "little": + scale = -scale + + file.write("%f\n".encode() % scale) + + image.tofile(file) + +def read_image(path): + """Read image and output RGB image (0-1). + Args: + path (str): path to file + Returns: + array: RGB image (0-1) + """ + img = cv2.imread(path) + + if img.ndim == 2: + img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) + + img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) / 255.0 + + return img + +def write_depth(path, depth, bits=1): + """Write depth map to pfm and png file. + Args: + path (str): filepath without extension + depth (array): depth + """ + write_pfm(path + ".pfm", depth.astype(np.float32)) + + depth_min = depth.min() + depth_max = depth.max() + + max_val = (2**(8*bits))-1 + + if depth_max - depth_min > np.finfo("float").eps: + out = max_val * (depth - depth_min) / (depth_max - depth_min) + else: + out = 0 + + if bits == 1: + cv2.imwrite(path + ".png", out.astype("uint8")) + elif bits == 2: + cv2.imwrite(path + ".png", out.astype("uint16")) + + return \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/utils.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/utils.py new file mode 100644 index 00000000..7a3976fd --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/utils.py @@ -0,0 +1,199 @@ +"""Utils for monoDepth. +""" +import sys +import re +import numpy as np +import cv2 +import torch + + +def read_pfm(path): + """Read pfm file. + + Args: + path (str): path to file + + Returns: + tuple: (data, scale) + """ + with open(path, "rb") as file: + + color = None + width = None + height = None + scale = None + endian = None + + header = file.readline().rstrip() + if header.decode("ascii") == "PF": + color = True + elif header.decode("ascii") == "Pf": + color = False + else: + raise Exception("Not a PFM file: " + path) + + dim_match = re.match(r"^(\d+)\s(\d+)\s$", file.readline().decode("ascii")) + if dim_match: + width, height = list(map(int, dim_match.groups())) + else: + raise Exception("Malformed PFM header.") + + scale = float(file.readline().decode("ascii").rstrip()) + if scale < 0: + # little-endian + endian = "<" + scale = -scale + else: + # big-endian + endian = ">" + + data = np.fromfile(file, endian + "f") + shape = (height, width, 3) if color else (height, width) + + data = np.reshape(data, shape) + data = np.flipud(data) + + return data, scale + + +def write_pfm(path, image, scale=1): + """Write pfm file. + + Args: + path (str): pathto file + image (array): data + scale (int, optional): Scale. Defaults to 1. + """ + + with open(path, "wb") as file: + color = None + + if image.dtype.name != "float32": + raise Exception("Image dtype must be float32.") + + image = np.flipud(image) + + if len(image.shape) == 3 and image.shape[2] == 3: # color image + color = True + elif ( + len(image.shape) == 2 or len(image.shape) == 3 and image.shape[2] == 1 + ): # greyscale + color = False + else: + raise Exception("Image must have H x W x 3, H x W x 1 or H x W dimensions.") + + file.write("PF\n" if color else "Pf\n".encode()) + file.write("%d %d\n".encode() % (image.shape[1], image.shape[0])) + + endian = image.dtype.byteorder + + if endian == "<" or endian == "=" and sys.byteorder == "little": + scale = -scale + + file.write("%f\n".encode() % scale) + + image.tofile(file) + + +def read_image(path): + """Read image and output RGB image (0-1). + + Args: + path (str): path to file + + Returns: + array: RGB image (0-1) + """ + img = cv2.imread(path) + + if img.ndim == 2: + img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) + + img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) / 255.0 + + return img + + +def resize_image(img): + """Resize image and make it fit for network. + + Args: + img (array): image + + Returns: + tensor: data ready for network + """ + height_orig = img.shape[0] + width_orig = img.shape[1] + + if width_orig > height_orig: + scale = width_orig / 384 + else: + scale = height_orig / 384 + + height = (np.ceil(height_orig / scale / 32) * 32).astype(int) + width = (np.ceil(width_orig / scale / 32) * 32).astype(int) + + img_resized = cv2.resize(img, (width, height), interpolation=cv2.INTER_AREA) + + img_resized = ( + torch.from_numpy(np.transpose(img_resized, (2, 0, 1))).contiguous().float() + ) + img_resized = img_resized.unsqueeze(0) + + return img_resized + + +def resize_depth(depth, width, height): + """Resize depth map and bring to CPU (numpy). + + Args: + depth (tensor): depth + width (int): image width + height (int): image height + + Returns: + array: processed depth + """ + depth = torch.squeeze(depth[0, :, :, :]).to("cpu") + + depth_resized = cv2.resize( + depth.numpy(), (width, height), interpolation=cv2.INTER_CUBIC + ) + + return depth_resized + +def write_depth(path, depth, grayscale, bits=1): + """Write depth map to png file. + + Args: + path (str): filepath without extension + depth (array): depth + grayscale (bool): use a grayscale colormap? + """ + if not grayscale: + bits = 1 + + if not np.isfinite(depth).all(): + depth=np.nan_to_num(depth, nan=0.0, posinf=0.0, neginf=0.0) + print("WARNING: Non-finite depth values present") + + depth_min = depth.min() + depth_max = depth.max() + + max_val = (2**(8*bits))-1 + + if depth_max - depth_min > np.finfo("float").eps: + out = max_val * (depth - depth_min) / (depth_max - depth_min) + else: + out = np.zeros(depth.shape, dtype=depth.dtype) + + if not grayscale: + out = cv2.applyColorMap(np.uint8(out), cv2.COLORMAP_INFERNO) + + if bits == 1: + cv2.imwrite(path + ".png", out.astype("uint8")) + elif bits == 2: + cv2.imwrite(path + ".png", out.astype("uint16")) + + return diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/weights/.placeholder b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/base_models/midas_repo/weights/.placeholder new file mode 100644 index 00000000..e69de29b diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/builder.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/builder.py new file mode 100644 index 00000000..0818311b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/builder.py @@ -0,0 +1,51 @@ +# MIT License + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + +from importlib import import_module +from .depth_model import DepthModel + +def build_model(config) -> DepthModel: + """Builds a model from a config. The model is specified by the model name and version in the config. The model is then constructed using the build_from_config function of the model interface. + This function should be used to construct models for training and evaluation. + + Args: + config (dict): Config dict. Config is constructed in utils/config.py. Each model has its own config file(s) saved in its root model folder. + + Returns: + torch.nn.Module: Model corresponding to name and version as specified in config + """ + module_name = f"zoedepth.models.{config.model}" + try: + module = import_module(module_name) + except ModuleNotFoundError as e: + # print the original error message + print(e) + raise ValueError( + f"Model {config.model} not found. Refer above error for details.") from e + try: + get_version = getattr(module, "get_version") + except AttributeError as e: + raise ValueError( + f"Model {config.model} has no get_version function.") from e + return get_version(config.version_name).build_from_config(config) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/depth_model.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/depth_model.py new file mode 100644 index 00000000..fc421c10 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/depth_model.py @@ -0,0 +1,152 @@ +# MIT License + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F +from torchvision import transforms +import PIL.Image +from PIL import Image +from typing import Union + + +class DepthModel(nn.Module): + def __init__(self): + super().__init__() + self.device = 'cpu' + + def to(self, device) -> nn.Module: + self.device = device + return super().to(device) + + def forward(self, x, *args, **kwargs): + raise NotImplementedError + + def _infer(self, x: torch.Tensor): + """ + Inference interface for the model + Args: + x (torch.Tensor): input tensor of shape (b, c, h, w) + Returns: + torch.Tensor: output tensor of shape (b, 1, h, w) + """ + return self(x)['metric_depth'] + + def _infer_with_pad_aug(self, x: torch.Tensor, pad_input: bool=True, fh: float=3, fw: float=3, upsampling_mode: str='bicubic', padding_mode="reflect", **kwargs) -> torch.Tensor: + """ + Inference interface for the model with padding augmentation + Padding augmentation fixes the boundary artifacts in the output depth map. + Boundary artifacts are sometimes caused by the fact that the model is trained on NYU raw dataset which has a black or white border around the image. + This augmentation pads the input image and crops the prediction back to the original size / view. + + Note: This augmentation is not required for the models trained with 'avoid_boundary'=True. + Args: + x (torch.Tensor): input tensor of shape (b, c, h, w) + pad_input (bool, optional): whether to pad the input or not. Defaults to True. + fh (float, optional): height padding factor. The padding is calculated as sqrt(h/2) * fh. Defaults to 3. + fw (float, optional): width padding factor. The padding is calculated as sqrt(w/2) * fw. Defaults to 3. + upsampling_mode (str, optional): upsampling mode. Defaults to 'bicubic'. + padding_mode (str, optional): padding mode. Defaults to "reflect". + Returns: + torch.Tensor: output tensor of shape (b, 1, h, w) + """ + # assert x is nchw and c = 3 + assert x.dim() == 4, "x must be 4 dimensional, got {}".format(x.dim()) + assert x.shape[1] == 3, "x must have 3 channels, got {}".format(x.shape[1]) + + if pad_input: + assert fh > 0 or fw > 0, "atlease one of fh and fw must be greater than 0" + pad_h = int(np.sqrt(x.shape[2]/2) * fh) + pad_w = int(np.sqrt(x.shape[3]/2) * fw) + padding = [pad_w, pad_w] + if pad_h > 0: + padding += [pad_h, pad_h] + + x = F.pad(x, padding, mode=padding_mode, **kwargs) + out = self._infer(x) + if out.shape[-2:] != x.shape[-2:]: + out = F.interpolate(out, size=(x.shape[2], x.shape[3]), mode=upsampling_mode, align_corners=False) + if pad_input: + # crop to the original size, handling the case where pad_h and pad_w is 0 + if pad_h > 0: + out = out[:, :, pad_h:-pad_h,:] + if pad_w > 0: + out = out[:, :, :, pad_w:-pad_w] + return out + + def infer_with_flip_aug(self, x, pad_input: bool=True, **kwargs) -> torch.Tensor: + """ + Inference interface for the model with horizontal flip augmentation + Horizontal flip augmentation improves the accuracy of the model by averaging the output of the model with and without horizontal flip. + Args: + x (torch.Tensor): input tensor of shape (b, c, h, w) + pad_input (bool, optional): whether to use padding augmentation. Defaults to True. + Returns: + torch.Tensor: output tensor of shape (b, 1, h, w) + """ + # infer with horizontal flip and average + out = self._infer_with_pad_aug(x, pad_input=pad_input, **kwargs) + out_flip = self._infer_with_pad_aug(torch.flip(x, dims=[3]), pad_input=pad_input, **kwargs) + out = (out + torch.flip(out_flip, dims=[3])) / 2 + return out + + def infer(self, x, pad_input: bool=True, with_flip_aug: bool=True, **kwargs) -> torch.Tensor: + """ + Inference interface for the model + Args: + x (torch.Tensor): input tensor of shape (b, c, h, w) + pad_input (bool, optional): whether to use padding augmentation. Defaults to True. + with_flip_aug (bool, optional): whether to use horizontal flip augmentation. Defaults to True. + Returns: + torch.Tensor: output tensor of shape (b, 1, h, w) + """ + if with_flip_aug: + return self.infer_with_flip_aug(x, pad_input=pad_input, **kwargs) + else: + return self._infer_with_pad_aug(x, pad_input=pad_input, **kwargs) + + @torch.no_grad() + def infer_pil(self, pil_img, pad_input: bool=True, with_flip_aug: bool=True, output_type: str="numpy", **kwargs) -> Union[np.ndarray, PIL.Image.Image, torch.Tensor]: + """ + Inference interface for the model for PIL image + Args: + pil_img (PIL.Image.Image): input PIL image + pad_input (bool, optional): whether to use padding augmentation. Defaults to True. + with_flip_aug (bool, optional): whether to use horizontal flip augmentation. Defaults to True. + output_type (str, optional): output type. Supported values are 'numpy', 'pil' and 'tensor'. Defaults to "numpy". + """ + x = transforms.ToTensor()(pil_img).unsqueeze(0).to(self.device) + out_tensor = self.infer(x, pad_input=pad_input, with_flip_aug=with_flip_aug, **kwargs) + if output_type == "numpy": + return out_tensor.squeeze().cpu().numpy() + elif output_type == "pil": + # uint16 is required for depth pil image + out_16bit_numpy = (out_tensor.squeeze().cpu().numpy()*256).astype(np.uint16) + return Image.fromarray(out_16bit_numpy) + elif output_type == "tensor": + return out_tensor.squeeze().cpu() + else: + raise ValueError(f"output_type {output_type} not supported. Supported values are 'numpy', 'pil' and 'tensor'") + \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/layers/attractor.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/layers/attractor.py new file mode 100644 index 00000000..2a8efe64 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/layers/attractor.py @@ -0,0 +1,208 @@ +# MIT License + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + +import torch +import torch.nn as nn + + +@torch.jit.script +def exp_attractor(dx, alpha: float = 300, gamma: int = 2): + """Exponential attractor: dc = exp(-alpha*|dx|^gamma) * dx , where dx = a - c, a = attractor point, c = bin center, dc = shift in bin centermmary for exp_attractor + + Args: + dx (torch.Tensor): The difference tensor dx = Ai - Cj, where Ai is the attractor point and Cj is the bin center. + alpha (float, optional): Proportional Attractor strength. Determines the absolute strength. Lower alpha = greater attraction. Defaults to 300. + gamma (int, optional): Exponential Attractor strength. Determines the "region of influence" and indirectly number of bin centers affected. Lower gamma = farther reach. Defaults to 2. + + Returns: + torch.Tensor : Delta shifts - dc; New bin centers = Old bin centers + dc + """ + return torch.exp(-alpha*(torch.abs(dx)**gamma)) * (dx) + + +@torch.jit.script +def inv_attractor(dx, alpha: float = 300, gamma: int = 2): + """Inverse attractor: dc = dx / (1 + alpha*dx^gamma), where dx = a - c, a = attractor point, c = bin center, dc = shift in bin center + This is the default one according to the accompanying paper. + + Args: + dx (torch.Tensor): The difference tensor dx = Ai - Cj, where Ai is the attractor point and Cj is the bin center. + alpha (float, optional): Proportional Attractor strength. Determines the absolute strength. Lower alpha = greater attraction. Defaults to 300. + gamma (int, optional): Exponential Attractor strength. Determines the "region of influence" and indirectly number of bin centers affected. Lower gamma = farther reach. Defaults to 2. + + Returns: + torch.Tensor: Delta shifts - dc; New bin centers = Old bin centers + dc + """ + return dx.div(1+alpha*dx.pow(gamma)) + + +class AttractorLayer(nn.Module): + def __init__(self, in_features, n_bins, n_attractors=16, mlp_dim=128, min_depth=1e-3, max_depth=10, + alpha=300, gamma=2, kind='sum', attractor_type='exp', memory_efficient=False): + """ + Attractor layer for bin centers. Bin centers are bounded on the interval (min_depth, max_depth) + """ + super().__init__() + + self.n_attractors = n_attractors + self.n_bins = n_bins + self.min_depth = min_depth + self.max_depth = max_depth + self.alpha = alpha + self.gamma = gamma + self.kind = kind + self.attractor_type = attractor_type + self.memory_efficient = memory_efficient + + self._net = nn.Sequential( + nn.Conv2d(in_features, mlp_dim, 1, 1, 0), + nn.ReLU(inplace=True), + nn.Conv2d(mlp_dim, n_attractors*2, 1, 1, 0), # x2 for linear norm + nn.ReLU(inplace=True) + ) + + def forward(self, x, b_prev, prev_b_embedding=None, interpolate=True, is_for_query=False): + """ + Args: + x (torch.Tensor) : feature block; shape - n, c, h, w + b_prev (torch.Tensor) : previous bin centers normed; shape - n, prev_nbins, h, w + + Returns: + tuple(torch.Tensor,torch.Tensor) : new bin centers normed and scaled; shape - n, nbins, h, w + """ + if prev_b_embedding is not None: + if interpolate: + prev_b_embedding = nn.functional.interpolate( + prev_b_embedding, x.shape[-2:], mode='bilinear', align_corners=True) + x = x + prev_b_embedding + + A = self._net(x) + eps = 1e-3 + A = A + eps + n, c, h, w = A.shape + A = A.view(n, self.n_attractors, 2, h, w) + A_normed = A / A.sum(dim=2, keepdim=True) # n, a, 2, h, w + A_normed = A[:, :, 0, ...] # n, na, h, w + + b_prev = nn.functional.interpolate( + b_prev, (h, w), mode='bilinear', align_corners=True) + b_centers = b_prev + + if self.attractor_type == 'exp': + dist = exp_attractor + else: + dist = inv_attractor + + if not self.memory_efficient: + func = {'mean': torch.mean, 'sum': torch.sum}[self.kind] + # .shape N, nbins, h, w + delta_c = func(dist(A_normed.unsqueeze( + 2) - b_centers.unsqueeze(1)), dim=1) + else: + delta_c = torch.zeros_like(b_centers, device=b_centers.device) + for i in range(self.n_attractors): + # .shape N, nbins, h, w + delta_c += dist(A_normed[:, i, ...].unsqueeze(1) - b_centers) + + if self.kind == 'mean': + delta_c = delta_c / self.n_attractors + + b_new_centers = b_centers + delta_c + B_centers = (self.max_depth - self.min_depth) * \ + b_new_centers + self.min_depth + B_centers, _ = torch.sort(B_centers, dim=1) + B_centers = torch.clip(B_centers, self.min_depth, self.max_depth) + return b_new_centers, B_centers + + +class AttractorLayerUnnormed(nn.Module): + def __init__(self, in_features, n_bins, n_attractors=16, mlp_dim=128, min_depth=1e-3, max_depth=10, + alpha=300, gamma=2, kind='sum', attractor_type='exp', memory_efficient=False): + """ + Attractor layer for bin centers. Bin centers are unbounded + """ + super().__init__() + + self.n_attractors = n_attractors + self.n_bins = n_bins + self.min_depth = min_depth + self.max_depth = max_depth + self.alpha = alpha + self.gamma = gamma + self.kind = kind + self.attractor_type = attractor_type + self.memory_efficient = memory_efficient + + self._net = nn.Sequential( + nn.Conv2d(in_features, mlp_dim, 1, 1, 0), + nn.ReLU(inplace=True), + nn.Conv2d(mlp_dim, n_attractors, 1, 1, 0), + nn.Softplus() + ) + + def forward(self, x, b_prev, prev_b_embedding=None, interpolate=True, is_for_query=False): + """ + Args: + x (torch.Tensor) : feature block; shape - n, c, h, w + b_prev (torch.Tensor) : previous bin centers normed; shape - n, prev_nbins, h, w + + Returns: + tuple(torch.Tensor,torch.Tensor) : new bin centers unbounded; shape - n, nbins, h, w. Two outputs just to keep the API consistent with the normed version + """ + if prev_b_embedding is not None: + if interpolate: + prev_b_embedding = nn.functional.interpolate( + prev_b_embedding, x.shape[-2:], mode='bilinear', align_corners=True) + x = x + prev_b_embedding + + A = self._net(x) + n, c, h, w = A.shape + + b_prev = nn.functional.interpolate( + b_prev, (h, w), mode='bilinear', align_corners=True) + b_centers = b_prev + + if self.attractor_type == 'exp': + dist = exp_attractor + else: + dist = inv_attractor + + if not self.memory_efficient: + func = {'mean': torch.mean, 'sum': torch.sum}[self.kind] + # .shape N, nbins, h, w + delta_c = func( + dist(A.unsqueeze(2) - b_centers.unsqueeze(1)), dim=1) + else: + delta_c = torch.zeros_like(b_centers, device=b_centers.device) + for i in range(self.n_attractors): + delta_c += dist(A[:, i, ...].unsqueeze(1) - + b_centers) # .shape N, nbins, h, w + + if self.kind == 'mean': + delta_c = delta_c / self.n_attractors + + b_new_centers = b_centers + delta_c + B_centers = b_new_centers + + return b_new_centers, B_centers diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/layers/dist_layers.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/layers/dist_layers.py new file mode 100644 index 00000000..3208405d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/layers/dist_layers.py @@ -0,0 +1,121 @@ +# MIT License + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + +import torch +import torch.nn as nn + + +def log_binom(n, k, eps=1e-7): + """ log(nCk) using stirling approximation """ + n = n + eps + k = k + eps + return n * torch.log(n) - k * torch.log(k) - (n-k) * torch.log(n-k+eps) + + +class LogBinomial(nn.Module): + def __init__(self, n_classes=256, act=torch.softmax): + """Compute log binomial distribution for n_classes + + Args: + n_classes (int, optional): number of output classes. Defaults to 256. + """ + super().__init__() + self.K = n_classes + self.act = act + self.register_buffer('k_idx', torch.arange( + 0, n_classes).view(1, -1, 1, 1)) + self.register_buffer('K_minus_1', torch.Tensor( + [self.K-1]).view(1, -1, 1, 1)) + + def forward(self, x, t=1., eps=1e-4): + """Compute log binomial distribution for x + + Args: + x (torch.Tensor - NCHW): probabilities + t (float, torch.Tensor - NCHW, optional): Temperature of distribution. Defaults to 1.. + eps (float, optional): Small number for numerical stability. Defaults to 1e-4. + + Returns: + torch.Tensor -NCHW: log binomial distribution logbinomial(p;t) + """ + if x.ndim == 3: + x = x.unsqueeze(1) # make it nchw + + one_minus_x = torch.clamp(1 - x, eps, 1) + x = torch.clamp(x, eps, 1) + y = log_binom(self.K_minus_1, self.k_idx) + self.k_idx * \ + torch.log(x) + (self.K - 1 - self.k_idx) * torch.log(one_minus_x) + return self.act(y/t, dim=1) + + +class ConditionalLogBinomial(nn.Module): + def __init__(self, in_features, condition_dim, n_classes=256, bottleneck_factor=2, p_eps=1e-4, max_temp=50, min_temp=1e-7, act=torch.softmax): + """Conditional Log Binomial distribution + + Args: + in_features (int): number of input channels in main feature + condition_dim (int): number of input channels in condition feature + n_classes (int, optional): Number of classes. Defaults to 256. + bottleneck_factor (int, optional): Hidden dim factor. Defaults to 2. + p_eps (float, optional): small eps value. Defaults to 1e-4. + max_temp (float, optional): Maximum temperature of output distribution. Defaults to 50. + min_temp (float, optional): Minimum temperature of output distribution. Defaults to 1e-7. + """ + super().__init__() + self.p_eps = p_eps + self.max_temp = max_temp + self.min_temp = min_temp + self.log_binomial_transform = LogBinomial(n_classes, act=act) + bottleneck = (in_features + condition_dim) // bottleneck_factor + self.mlp = nn.Sequential( + nn.Conv2d(in_features + condition_dim, bottleneck, + kernel_size=1, stride=1, padding=0), + nn.GELU(), + # 2 for p linear norm, 2 for t linear norm + nn.Conv2d(bottleneck, 2+2, kernel_size=1, stride=1, padding=0), + nn.Softplus() + ) + + def forward(self, x, cond): + """Forward pass + + Args: + x (torch.Tensor - NCHW): Main feature + cond (torch.Tensor - NCHW): condition feature + + Returns: + torch.Tensor: Output log binomial distribution + """ + pt = self.mlp(torch.concat((x, cond), dim=1)) + p, t = pt[:, :2, ...], pt[:, 2:, ...] + + p = p + self.p_eps + p = p[:, 0, ...] / (p[:, 0, ...] + p[:, 1, ...]) + + t = t + self.p_eps + t = t[:, 0, ...] / (t[:, 0, ...] + t[:, 1, ...]) + t = t.unsqueeze(1) + t = (self.max_temp - self.min_temp) * t + self.min_temp + + return self.log_binomial_transform(p, t) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/layers/localbins_layers.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/layers/localbins_layers.py new file mode 100644 index 00000000..f9448160 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/layers/localbins_layers.py @@ -0,0 +1,169 @@ +# MIT License + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + +import torch +import torch.nn as nn + + +class SeedBinRegressor(nn.Module): + def __init__(self, in_features, n_bins=16, mlp_dim=256, min_depth=1e-3, max_depth=10): + """Bin center regressor network. Bin centers are bounded on (min_depth, max_depth) interval. + + Args: + in_features (int): input channels + n_bins (int, optional): Number of bin centers. Defaults to 16. + mlp_dim (int, optional): Hidden dimension. Defaults to 256. + min_depth (float, optional): Min depth value. Defaults to 1e-3. + max_depth (float, optional): Max depth value. Defaults to 10. + """ + super().__init__() + self.version = "1_1" + self.min_depth = min_depth + self.max_depth = max_depth + + self._net = nn.Sequential( + nn.Conv2d(in_features, mlp_dim, 1, 1, 0), + nn.ReLU(inplace=True), + nn.Conv2d(mlp_dim, n_bins, 1, 1, 0), + nn.ReLU(inplace=True) + ) + + def forward(self, x): + """ + Returns tensor of bin_width vectors (centers). One vector b for every pixel + """ + B = self._net(x) + eps = 1e-3 + B = B + eps + B_widths_normed = B / B.sum(dim=1, keepdim=True) + B_widths = (self.max_depth - self.min_depth) * \ + B_widths_normed # .shape NCHW + # pad has the form (left, right, top, bottom, front, back) + B_widths = nn.functional.pad( + B_widths, (0, 0, 0, 0, 1, 0), mode='constant', value=self.min_depth) + B_edges = torch.cumsum(B_widths, dim=1) # .shape NCHW + + B_centers = 0.5 * (B_edges[:, :-1, ...] + B_edges[:, 1:, ...]) + return B_widths_normed, B_centers + + +class SeedBinRegressorUnnormed(nn.Module): + def __init__(self, in_features, n_bins=16, mlp_dim=256, min_depth=1e-3, max_depth=10): + """Bin center regressor network. Bin centers are unbounded + + Args: + in_features (int): input channels + n_bins (int, optional): Number of bin centers. Defaults to 16. + mlp_dim (int, optional): Hidden dimension. Defaults to 256. + min_depth (float, optional): Not used. (for compatibility with SeedBinRegressor) + max_depth (float, optional): Not used. (for compatibility with SeedBinRegressor) + """ + super().__init__() + self.version = "1_1" + self._net = nn.Sequential( + nn.Conv2d(in_features, mlp_dim, 1, 1, 0), + nn.ReLU(inplace=True), + nn.Conv2d(mlp_dim, n_bins, 1, 1, 0), + nn.Softplus() + ) + + def forward(self, x): + """ + Returns tensor of bin_width vectors (centers). One vector b for every pixel + """ + B_centers = self._net(x) + return B_centers, B_centers + + +class Projector(nn.Module): + def __init__(self, in_features, out_features, mlp_dim=128): + """Projector MLP + + Args: + in_features (int): input channels + out_features (int): output channels + mlp_dim (int, optional): hidden dimension. Defaults to 128. + """ + super().__init__() + + self._net = nn.Sequential( + nn.Conv2d(in_features, mlp_dim, 1, 1, 0), + nn.ReLU(inplace=True), + nn.Conv2d(mlp_dim, out_features, 1, 1, 0), + ) + + def forward(self, x): + return self._net(x) + + + +class LinearSplitter(nn.Module): + def __init__(self, in_features, prev_nbins, split_factor=2, mlp_dim=128, min_depth=1e-3, max_depth=10): + super().__init__() + + self.prev_nbins = prev_nbins + self.split_factor = split_factor + self.min_depth = min_depth + self.max_depth = max_depth + + self._net = nn.Sequential( + nn.Conv2d(in_features, mlp_dim, 1, 1, 0), + nn.GELU(), + nn.Conv2d(mlp_dim, prev_nbins * split_factor, 1, 1, 0), + nn.ReLU() + ) + + def forward(self, x, b_prev, prev_b_embedding=None, interpolate=True, is_for_query=False): + """ + x : feature block; shape - n, c, h, w + b_prev : previous bin widths normed; shape - n, prev_nbins, h, w + """ + if prev_b_embedding is not None: + if interpolate: + prev_b_embedding = nn.functional.interpolate(prev_b_embedding, x.shape[-2:], mode='bilinear', align_corners=True) + x = x + prev_b_embedding + S = self._net(x) + eps = 1e-3 + S = S + eps + n, c, h, w = S.shape + S = S.view(n, self.prev_nbins, self.split_factor, h, w) + S_normed = S / S.sum(dim=2, keepdim=True) # fractional splits + + b_prev = nn.functional.interpolate(b_prev, (h,w), mode='bilinear', align_corners=True) + + + b_prev = b_prev / b_prev.sum(dim=1, keepdim=True) # renormalize for gurantees + # print(b_prev.shape, S_normed.shape) + # if is_for_query:(1).expand(-1, b_prev.size(0)//n, -1, -1, -1, -1).flatten(0,1) # TODO ? can replace all this with a single torch.repeat? + b = b_prev.unsqueeze(2) * S_normed + b = b.flatten(1,2) # .shape n, prev_nbins * split_factor, h, w + + # calculate bin centers for loss calculation + B_widths = (self.max_depth - self.min_depth) * b # .shape N, nprev * splitfactor, H, W + # pad has the form (left, right, top, bottom, front, back) + B_widths = nn.functional.pad(B_widths, (0,0,0,0,1,0), mode='constant', value=self.min_depth) + B_edges = torch.cumsum(B_widths, dim=1) # .shape NCHW + + B_centers = 0.5 * (B_edges[:, :-1, ...] + B_edges[:,1:,...]) + return b, B_centers \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/layers/patch_transformer.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/layers/patch_transformer.py new file mode 100644 index 00000000..99d9e51a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/layers/patch_transformer.py @@ -0,0 +1,91 @@ +# MIT License + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + +import torch +import torch.nn as nn + + +class PatchTransformerEncoder(nn.Module): + def __init__(self, in_channels, patch_size=10, embedding_dim=128, num_heads=4, use_class_token=False): + """ViT-like transformer block + + Args: + in_channels (int): Input channels + patch_size (int, optional): patch size. Defaults to 10. + embedding_dim (int, optional): Embedding dimension in transformer model. Defaults to 128. + num_heads (int, optional): number of attention heads. Defaults to 4. + use_class_token (bool, optional): Whether to use extra token at the start for global accumulation (called as "class token"). Defaults to False. + """ + super(PatchTransformerEncoder, self).__init__() + self.use_class_token = use_class_token + encoder_layers = nn.TransformerEncoderLayer( + embedding_dim, num_heads, dim_feedforward=1024) + self.transformer_encoder = nn.TransformerEncoder( + encoder_layers, num_layers=4) # takes shape S,N,E + + self.embedding_convPxP = nn.Conv2d(in_channels, embedding_dim, + kernel_size=patch_size, stride=patch_size, padding=0) + + def positional_encoding_1d(self, sequence_length, batch_size, embedding_dim, device='cpu'): + """Generate positional encodings + + Args: + sequence_length (int): Sequence length + embedding_dim (int): Embedding dimension + + Returns: + torch.Tensor SBE: Positional encodings + """ + position = torch.arange( + 0, sequence_length, dtype=torch.float32, device=device).unsqueeze(1) + index = torch.arange( + 0, embedding_dim, 2, dtype=torch.float32, device=device).unsqueeze(0) + div_term = torch.exp(index * (-torch.log(torch.tensor(10000.0, device=device)) / embedding_dim)) + pos_encoding = position * div_term + pos_encoding = torch.cat([torch.sin(pos_encoding), torch.cos(pos_encoding)], dim=1) + pos_encoding = pos_encoding.unsqueeze(1).repeat(1, batch_size, 1) + return pos_encoding + + + def forward(self, x): + """Forward pass + + Args: + x (torch.Tensor - NCHW): Input feature tensor + + Returns: + torch.Tensor - SNE: Transformer output embeddings. S - sequence length (=HW/patch_size^2), N - batch size, E - embedding dim + """ + embeddings = self.embedding_convPxP(x).flatten( + 2) # .shape = n,c,s = n, embedding_dim, s + if self.use_class_token: + # extra special token at start ? + embeddings = nn.functional.pad(embeddings, (1, 0)) + + # change to S,N,E format required by transformer + embeddings = embeddings.permute(2, 0, 1) + S, N, E = embeddings.shape + embeddings = embeddings + self.positional_encoding_1d(S, N, E, device=embeddings.device) + x = self.transformer_encoder(embeddings) # .shape = S, N, E + return x diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/model_io.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/model_io.py new file mode 100644 index 00000000..78b65796 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/model_io.py @@ -0,0 +1,92 @@ +# MIT License + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + +import torch + +def load_state_dict(model, state_dict): + """Load state_dict into model, handling DataParallel and DistributedDataParallel. Also checks for "model" key in state_dict. + + DataParallel prefixes state_dict keys with 'module.' when saving. + If the model is not a DataParallel model but the state_dict is, then prefixes are removed. + If the model is a DataParallel model but the state_dict is not, then prefixes are added. + """ + state_dict = state_dict.get('model', state_dict) + # if model is a DataParallel model, then state_dict keys are prefixed with 'module.' + + do_prefix = isinstance( + model, (torch.nn.DataParallel, torch.nn.parallel.DistributedDataParallel)) + state = {} + for k, v in state_dict.items(): + if k.startswith('module.') and not do_prefix: + k = k[7:] + + if not k.startswith('module.') and do_prefix: + k = 'module.' + k + + state[k] = v + + model.load_state_dict(state) + print("Loaded successfully") + return model + + +def load_wts(model, checkpoint_path): + ckpt = torch.load(checkpoint_path, map_location='cpu') + return load_state_dict(model, ckpt) + + +def load_state_dict_from_url(model, url, **kwargs): + state_dict = torch.hub.load_state_dict_from_url(url, map_location='cpu', **kwargs) + return load_state_dict(model, state_dict) + + +def load_state_from_resource(model, resource: str): + """Loads weights to the model from a given resource. A resource can be of following types: + 1. URL. Prefixed with "url::" + e.g. url::http(s)://url.resource.com/ckpt.pt + + 2. Local path. Prefixed with "local::" + e.g. local::/path/to/ckpt.pt + + + Args: + model (torch.nn.Module): Model + resource (str): resource string + + Returns: + torch.nn.Module: Model with loaded weights + """ + print(f"Using pretrained resource {resource}") + + if resource.startswith('url::'): + url = resource.split('url::')[1] + return load_state_dict_from_url(model, url, progress=True) + + elif resource.startswith('local::'): + path = resource.split('local::')[1] + return load_wts(model, path) + + else: + raise ValueError("Invalid resource type, only url:: and local:: are supported") + \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth/__init__.py new file mode 100644 index 00000000..cc33f737 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth/__init__.py @@ -0,0 +1,31 @@ +# MIT License + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + +from .zoedepth_v1 import ZoeDepth + +all_versions = { + "v1": ZoeDepth, +} + +get_version = lambda v : all_versions[v] \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth/config_zoedepth.json b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth/config_zoedepth.json new file mode 100644 index 00000000..3112ed78 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth/config_zoedepth.json @@ -0,0 +1,58 @@ +{ + "model": { + "name": "ZoeDepth", + "version_name": "v1", + "n_bins": 64, + "bin_embedding_dim": 128, + "bin_centers_type": "softplus", + "n_attractors":[16, 8, 4, 1], + "attractor_alpha": 1000, + "attractor_gamma": 2, + "attractor_kind" : "mean", + "attractor_type" : "inv", + "midas_model_type" : "DPT_BEiT_L_384", + "min_temp": 0.0212, + "max_temp": 50.0, + "output_distribution": "logbinomial", + "memory_efficient": true, + "inverse_midas": false, + "img_size": [384, 512] + }, + + "train": { + "train_midas": true, + "use_pretrained_midas": true, + "trainer": "zoedepth", + "epochs": 5, + "bs": 16, + "optim_kwargs": {"lr": 0.000161, "wd": 0.01}, + "sched_kwargs": {"div_factor": 1, "final_div_factor": 10000, "pct_start": 0.7, "three_phase":false, "cycle_momentum": true}, + "same_lr": false, + "w_si": 1, + "w_domain": 0.2, + "w_reg": 0, + "w_grad": 0, + "avoid_boundary": false, + "random_crop": false, + "input_width": 640, + "input_height": 480, + "midas_lr_factor": 1, + "encoder_lr_factor":10, + "pos_enc_lr_factor":10, + "freeze_midas_bn": true + + }, + + "infer":{ + "train_midas": false, + "use_pretrained_midas": false, + "pretrained_resource" : null, + "force_keep_ar": true + }, + + "eval":{ + "train_midas": false, + "use_pretrained_midas": false, + "pretrained_resource" : null + } +} \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth/config_zoedepth_kitti.json b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth/config_zoedepth_kitti.json new file mode 100644 index 00000000..b51802aa --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth/config_zoedepth_kitti.json @@ -0,0 +1,22 @@ +{ + "model": { + "bin_centers_type": "normed", + "img_size": [384, 768] + }, + + "train": { + }, + + "infer":{ + "train_midas": false, + "use_pretrained_midas": false, + "pretrained_resource" : "url::https://github.com/isl-org/ZoeDepth/releases/download/v1.0/ZoeD_M12_K.pt", + "force_keep_ar": true + }, + + "eval":{ + "train_midas": false, + "use_pretrained_midas": false, + "pretrained_resource" : "url::https://github.com/isl-org/ZoeDepth/releases/download/v1.0/ZoeD_M12_K.pt" + } +} \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth/zoedepth_v1.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth/zoedepth_v1.py new file mode 100644 index 00000000..bc931b05 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth/zoedepth_v1.py @@ -0,0 +1,250 @@ +# MIT License + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + +import itertools + +import torch +import torch.nn as nn +from ..depth_model import DepthModel +from ..base_models.midas import MidasCore +from ..layers.attractor import AttractorLayer, AttractorLayerUnnormed +from ..layers.dist_layers import ConditionalLogBinomial +from ..layers.localbins_layers import (Projector, SeedBinRegressor, + SeedBinRegressorUnnormed) +from ..model_io import load_state_from_resource + + +class ZoeDepth(DepthModel): + def __init__(self, core, n_bins=64, bin_centers_type="softplus", bin_embedding_dim=128, min_depth=1e-3, max_depth=10, + n_attractors=[16, 8, 4, 1], attractor_alpha=300, attractor_gamma=2, attractor_kind='sum', attractor_type='exp', min_temp=5, max_temp=50, train_midas=True, + midas_lr_factor=10, encoder_lr_factor=10, pos_enc_lr_factor=10, inverse_midas=False, **kwargs): + """ZoeDepth model. This is the version of ZoeDepth that has a single metric head + + Args: + core (models.base_models.midas.MidasCore): The base midas model that is used for extraction of "relative" features + n_bins (int, optional): Number of bin centers. Defaults to 64. + bin_centers_type (str, optional): "normed" or "softplus". Activation type used for bin centers. For "normed" bin centers, linear normalization trick is applied. This results in bounded bin centers. + For "softplus", softplus activation is used and thus are unbounded. Defaults to "softplus". + bin_embedding_dim (int, optional): bin embedding dimension. Defaults to 128. + min_depth (float, optional): Lower bound for normed bin centers. Defaults to 1e-3. + max_depth (float, optional): Upper bound for normed bin centers. Defaults to 10. + n_attractors (List[int], optional): Number of bin attractors at decoder layers. Defaults to [16, 8, 4, 1]. + attractor_alpha (int, optional): Proportional attractor strength. Refer to models.layers.attractor for more details. Defaults to 300. + attractor_gamma (int, optional): Exponential attractor strength. Refer to models.layers.attractor for more details. Defaults to 2. + attractor_kind (str, optional): Attraction aggregation "sum" or "mean". Defaults to 'sum'. + attractor_type (str, optional): Type of attractor to use; "inv" (Inverse attractor) or "exp" (Exponential attractor). Defaults to 'exp'. + min_temp (int, optional): Lower bound for temperature of output probability distribution. Defaults to 5. + max_temp (int, optional): Upper bound for temperature of output probability distribution. Defaults to 50. + train_midas (bool, optional): Whether to train "core", the base midas model. Defaults to True. + midas_lr_factor (int, optional): Learning rate reduction factor for base midas model except its encoder and positional encodings. Defaults to 10. + encoder_lr_factor (int, optional): Learning rate reduction factor for the encoder in midas model. Defaults to 10. + pos_enc_lr_factor (int, optional): Learning rate reduction factor for positional encodings in the base midas model. Defaults to 10. + """ + super().__init__() + + self.core = core + self.max_depth = max_depth + self.min_depth = min_depth + self.min_temp = min_temp + self.bin_centers_type = bin_centers_type + + self.midas_lr_factor = midas_lr_factor + self.encoder_lr_factor = encoder_lr_factor + self.pos_enc_lr_factor = pos_enc_lr_factor + self.train_midas = train_midas + self.inverse_midas = inverse_midas + + if self.encoder_lr_factor <= 0: + self.core.freeze_encoder( + freeze_rel_pos=self.pos_enc_lr_factor <= 0) + + N_MIDAS_OUT = 32 + btlnck_features = self.core.output_channels[0] + num_out_features = self.core.output_channels[1:] + + self.conv2 = nn.Conv2d(btlnck_features, btlnck_features, + kernel_size=1, stride=1, padding=0) # btlnck conv + + if bin_centers_type == "normed": + SeedBinRegressorLayer = SeedBinRegressor + Attractor = AttractorLayer + elif bin_centers_type == "softplus": + SeedBinRegressorLayer = SeedBinRegressorUnnormed + Attractor = AttractorLayerUnnormed + elif bin_centers_type == "hybrid1": + SeedBinRegressorLayer = SeedBinRegressor + Attractor = AttractorLayerUnnormed + elif bin_centers_type == "hybrid2": + SeedBinRegressorLayer = SeedBinRegressorUnnormed + Attractor = AttractorLayer + else: + raise ValueError( + "bin_centers_type should be one of 'normed', 'softplus', 'hybrid1', 'hybrid2'") + + self.seed_bin_regressor = SeedBinRegressorLayer( + btlnck_features, n_bins=n_bins, min_depth=min_depth, max_depth=max_depth) + self.seed_projector = Projector(btlnck_features, bin_embedding_dim) + self.projectors = nn.ModuleList([ + Projector(num_out, bin_embedding_dim) + for num_out in num_out_features + ]) + self.attractors = nn.ModuleList([ + Attractor(bin_embedding_dim, n_bins, n_attractors=n_attractors[i], min_depth=min_depth, max_depth=max_depth, + alpha=attractor_alpha, gamma=attractor_gamma, kind=attractor_kind, attractor_type=attractor_type) + for i in range(len(num_out_features)) + ]) + + last_in = N_MIDAS_OUT + 1 # +1 for relative depth + + # use log binomial instead of softmax + self.conditional_log_binomial = ConditionalLogBinomial( + last_in, bin_embedding_dim, n_classes=n_bins, min_temp=min_temp, max_temp=max_temp) + + def forward(self, x, return_final_centers=False, denorm=False, return_probs=False, **kwargs): + """ + Args: + x (torch.Tensor): Input image tensor of shape (B, C, H, W) + return_final_centers (bool, optional): Whether to return the final bin centers. Defaults to False. + denorm (bool, optional): Whether to denormalize the input image. This reverses ImageNet normalization as midas normalization is different. Defaults to False. + return_probs (bool, optional): Whether to return the output probability distribution. Defaults to False. + + Returns: + dict: Dictionary containing the following keys: + - rel_depth (torch.Tensor): Relative depth map of shape (B, H, W) + - metric_depth (torch.Tensor): Metric depth map of shape (B, 1, H, W) + - bin_centers (torch.Tensor): Bin centers of shape (B, n_bins). Present only if return_final_centers is True + - probs (torch.Tensor): Output probability distribution of shape (B, n_bins, H, W). Present only if return_probs is True + + """ + b, c, h, w = x.shape + # print("input shape ", x.shape) + self.orig_input_width = w + self.orig_input_height = h + rel_depth, out = self.core(x, denorm=denorm, return_rel_depth=True) + # print("output shapes", rel_depth.shape, out.shape) + + outconv_activation = out[0] + btlnck = out[1] + x_blocks = out[2:] + + x_d0 = self.conv2(btlnck) + x = x_d0 + _, seed_b_centers = self.seed_bin_regressor(x) + + if self.bin_centers_type == 'normed' or self.bin_centers_type == 'hybrid2': + b_prev = (seed_b_centers - self.min_depth) / \ + (self.max_depth - self.min_depth) + else: + b_prev = seed_b_centers + + prev_b_embedding = self.seed_projector(x) + + # unroll this loop for better performance + for projector, attractor, x in zip(self.projectors, self.attractors, x_blocks): + b_embedding = projector(x) + b, b_centers = attractor( + b_embedding, b_prev, prev_b_embedding, interpolate=True) + b_prev = b.clone() + prev_b_embedding = b_embedding.clone() + + last = outconv_activation + + if self.inverse_midas: + # invert depth followed by normalization + rel_depth = 1.0 / (rel_depth + 1e-6) + rel_depth = (rel_depth - rel_depth.min()) / \ + (rel_depth.max() - rel_depth.min()) + # concat rel depth with last. First interpolate rel depth to last size + rel_cond = rel_depth.unsqueeze(1) + rel_cond = nn.functional.interpolate( + rel_cond, size=last.shape[2:], mode='bilinear', align_corners=True) + last = torch.cat([last, rel_cond], dim=1) + + b_embedding = nn.functional.interpolate( + b_embedding, last.shape[-2:], mode='bilinear', align_corners=True) + x = self.conditional_log_binomial(last, b_embedding) + + # Now depth value is Sum px * cx , where cx are bin_centers from the last bin tensor + # print(x.shape, b_centers.shape) + b_centers = nn.functional.interpolate( + b_centers, x.shape[-2:], mode='bilinear', align_corners=True) + out = torch.sum(x * b_centers, dim=1, keepdim=True) + + # Structure output dict + output = dict(metric_depth=out) + if return_final_centers or return_probs: + output['bin_centers'] = b_centers + + if return_probs: + output['probs'] = x + + return output + + def get_lr_params(self, lr): + """ + Learning rate configuration for different layers of the model + Args: + lr (float) : Base learning rate + Returns: + list : list of parameters to optimize and their learning rates, in the format required by torch optimizers. + """ + param_conf = [] + if self.train_midas: + if self.encoder_lr_factor > 0: + param_conf.append({'params': self.core.get_enc_params_except_rel_pos( + ), 'lr': lr / self.encoder_lr_factor}) + + if self.pos_enc_lr_factor > 0: + param_conf.append( + {'params': self.core.get_rel_pos_params(), 'lr': lr / self.pos_enc_lr_factor}) + + midas_params = self.core.core.scratch.parameters() + midas_lr_factor = self.midas_lr_factor + param_conf.append( + {'params': midas_params, 'lr': lr / midas_lr_factor}) + + remaining_modules = [] + for name, child in self.named_children(): + if name != 'core': + remaining_modules.append(child) + remaining_params = itertools.chain( + *[child.parameters() for child in remaining_modules]) + + param_conf.append({'params': remaining_params, 'lr': lr}) + + return param_conf + + @staticmethod + def build(midas_model_type="DPT_BEiT_L_384", pretrained_resource=None, use_pretrained_midas=False, train_midas=False, freeze_midas_bn=True, **kwargs): + core = MidasCore.build(midas_model_type=midas_model_type, use_pretrained_midas=use_pretrained_midas, + train_midas=train_midas, fetch_features=True, freeze_bn=freeze_midas_bn, **kwargs) + model = ZoeDepth(core, **kwargs) + if pretrained_resource: + assert isinstance(pretrained_resource, str), "pretrained_resource must be a string" + model = load_state_from_resource(model, pretrained_resource) + return model + + @staticmethod + def build_from_config(config): + return ZoeDepth.build(**config) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth_nk/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth_nk/__init__.py new file mode 100644 index 00000000..513a278b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth_nk/__init__.py @@ -0,0 +1,31 @@ +# MIT License + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + +from .zoedepth_nk_v1 import ZoeDepthNK + +all_versions = { + "v1": ZoeDepthNK, +} + +get_version = lambda v : all_versions[v] \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth_nk/config_zoedepth_nk.json b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth_nk/config_zoedepth_nk.json new file mode 100644 index 00000000..42bab2a3 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth_nk/config_zoedepth_nk.json @@ -0,0 +1,67 @@ +{ + "model": { + "name": "ZoeDepthNK", + "version_name": "v1", + "bin_conf" : [ + { + "name": "nyu", + "n_bins": 64, + "min_depth": 1e-3, + "max_depth": 10.0 + }, + { + "name": "kitti", + "n_bins": 64, + "min_depth": 1e-3, + "max_depth": 80.0 + } + ], + "bin_embedding_dim": 128, + "bin_centers_type": "softplus", + "n_attractors":[16, 8, 4, 1], + "attractor_alpha": 1000, + "attractor_gamma": 2, + "attractor_kind" : "mean", + "attractor_type" : "inv", + "min_temp": 0.0212, + "max_temp": 50.0, + "memory_efficient": true, + "midas_model_type" : "DPT_BEiT_L_384", + "img_size": [384, 512] + }, + + "train": { + "train_midas": true, + "use_pretrained_midas": true, + "trainer": "zoedepth_nk", + "epochs": 5, + "bs": 16, + "optim_kwargs": {"lr": 0.0002512, "wd": 0.01}, + "sched_kwargs": {"div_factor": 1, "final_div_factor": 10000, "pct_start": 0.7, "three_phase":false, "cycle_momentum": true}, + "same_lr": false, + "w_si": 1, + "w_domain": 100, + "avoid_boundary": false, + "random_crop": false, + "input_width": 640, + "input_height": 480, + "w_grad": 0, + "w_reg": 0, + "midas_lr_factor": 10, + "encoder_lr_factor":10, + "pos_enc_lr_factor":10 + }, + + "infer": { + "train_midas": false, + "pretrained_resource": "url::https://github.com/isl-org/ZoeDepth/releases/download/v1.0/ZoeD_M12_NK.pt", + "use_pretrained_midas": false, + "force_keep_ar": true + }, + + "eval": { + "train_midas": false, + "pretrained_resource": "url::https://github.com/isl-org/ZoeDepth/releases/download/v1.0/ZoeD_M12_NK.pt", + "use_pretrained_midas": false + } +} \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth_nk/zoedepth_nk_v1.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth_nk/zoedepth_nk_v1.py new file mode 100644 index 00000000..7368ae80 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/models/zoedepth_nk/zoedepth_nk_v1.py @@ -0,0 +1,333 @@ +# MIT License + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + +import itertools + +import torch +import torch.nn as nn + +from zoedepth.models.depth_model import DepthModel +from zoedepth.models.base_models.midas import MidasCore +from zoedepth.models.layers.attractor import AttractorLayer, AttractorLayerUnnormed +from zoedepth.models.layers.dist_layers import ConditionalLogBinomial +from zoedepth.models.layers.localbins_layers import (Projector, SeedBinRegressor, + SeedBinRegressorUnnormed) +from zoedepth.models.layers.patch_transformer import PatchTransformerEncoder +from zoedepth.models.model_io import load_state_from_resource + + +class ZoeDepthNK(DepthModel): + def __init__(self, core, bin_conf, bin_centers_type="softplus", bin_embedding_dim=128, + n_attractors=[16, 8, 4, 1], attractor_alpha=300, attractor_gamma=2, attractor_kind='sum', attractor_type='exp', + min_temp=5, max_temp=50, + memory_efficient=False, train_midas=True, + is_midas_pretrained=True, midas_lr_factor=1, encoder_lr_factor=10, pos_enc_lr_factor=10, inverse_midas=False, **kwargs): + """ZoeDepthNK model. This is the version of ZoeDepth that has two metric heads and uses a learned router to route to experts. + + Args: + core (models.base_models.midas.MidasCore): The base midas model that is used for extraction of "relative" features + + bin_conf (List[dict]): A list of dictionaries that contain the bin configuration for each metric head. Each dictionary should contain the following keys: + "name" (str, typically same as the dataset name), "n_bins" (int), "min_depth" (float), "max_depth" (float) + + The length of this list determines the number of metric heads. + bin_centers_type (str, optional): "normed" or "softplus". Activation type used for bin centers. For "normed" bin centers, linear normalization trick is applied. This results in bounded bin centers. + For "softplus", softplus activation is used and thus are unbounded. Defaults to "normed". + bin_embedding_dim (int, optional): bin embedding dimension. Defaults to 128. + + n_attractors (List[int], optional): Number of bin attractors at decoder layers. Defaults to [16, 8, 4, 1]. + attractor_alpha (int, optional): Proportional attractor strength. Refer to models.layers.attractor for more details. Defaults to 300. + attractor_gamma (int, optional): Exponential attractor strength. Refer to models.layers.attractor for more details. Defaults to 2. + attractor_kind (str, optional): Attraction aggregation "sum" or "mean". Defaults to 'sum'. + attractor_type (str, optional): Type of attractor to use; "inv" (Inverse attractor) or "exp" (Exponential attractor). Defaults to 'exp'. + + min_temp (int, optional): Lower bound for temperature of output probability distribution. Defaults to 5. + max_temp (int, optional): Upper bound for temperature of output probability distribution. Defaults to 50. + + memory_efficient (bool, optional): Whether to use memory efficient version of attractor layers. Memory efficient version is slower but is recommended incase of multiple metric heads in order save GPU memory. Defaults to False. + + train_midas (bool, optional): Whether to train "core", the base midas model. Defaults to True. + is_midas_pretrained (bool, optional): Is "core" pretrained? Defaults to True. + midas_lr_factor (int, optional): Learning rate reduction factor for base midas model except its encoder and positional encodings. Defaults to 10. + encoder_lr_factor (int, optional): Learning rate reduction factor for the encoder in midas model. Defaults to 10. + pos_enc_lr_factor (int, optional): Learning rate reduction factor for positional encodings in the base midas model. Defaults to 10. + + """ + + super().__init__() + + self.core = core + self.bin_conf = bin_conf + self.min_temp = min_temp + self.max_temp = max_temp + self.memory_efficient = memory_efficient + self.train_midas = train_midas + self.is_midas_pretrained = is_midas_pretrained + self.midas_lr_factor = midas_lr_factor + self.encoder_lr_factor = encoder_lr_factor + self.pos_enc_lr_factor = pos_enc_lr_factor + self.inverse_midas = inverse_midas + + N_MIDAS_OUT = 32 + btlnck_features = self.core.output_channels[0] + num_out_features = self.core.output_channels[1:] + # self.scales = [16, 8, 4, 2] # spatial scale factors + + self.conv2 = nn.Conv2d( + btlnck_features, btlnck_features, kernel_size=1, stride=1, padding=0) + + # Transformer classifier on the bottleneck + self.patch_transformer = PatchTransformerEncoder( + btlnck_features, 1, 128, use_class_token=True) + self.mlp_classifier = nn.Sequential( + nn.Linear(128, 128), + nn.ReLU(), + nn.Linear(128, 2) + ) + + if bin_centers_type == "normed": + SeedBinRegressorLayer = SeedBinRegressor + Attractor = AttractorLayer + elif bin_centers_type == "softplus": + SeedBinRegressorLayer = SeedBinRegressorUnnormed + Attractor = AttractorLayerUnnormed + elif bin_centers_type == "hybrid1": + SeedBinRegressorLayer = SeedBinRegressor + Attractor = AttractorLayerUnnormed + elif bin_centers_type == "hybrid2": + SeedBinRegressorLayer = SeedBinRegressorUnnormed + Attractor = AttractorLayer + else: + raise ValueError( + "bin_centers_type should be one of 'normed', 'softplus', 'hybrid1', 'hybrid2'") + self.bin_centers_type = bin_centers_type + # We have bins for each bin conf. + # Create a map (ModuleDict) of 'name' -> seed_bin_regressor + self.seed_bin_regressors = nn.ModuleDict( + {conf['name']: SeedBinRegressorLayer(btlnck_features, conf["n_bins"], mlp_dim=bin_embedding_dim//2, min_depth=conf["min_depth"], max_depth=conf["max_depth"]) + for conf in bin_conf} + ) + + self.seed_projector = Projector( + btlnck_features, bin_embedding_dim, mlp_dim=bin_embedding_dim//2) + self.projectors = nn.ModuleList([ + Projector(num_out, bin_embedding_dim, mlp_dim=bin_embedding_dim//2) + for num_out in num_out_features + ]) + + # Create a map (ModuleDict) of 'name' -> attractors (ModuleList) + self.attractors = nn.ModuleDict( + {conf['name']: nn.ModuleList([ + Attractor(bin_embedding_dim, n_attractors[i], + mlp_dim=bin_embedding_dim, alpha=attractor_alpha, + gamma=attractor_gamma, kind=attractor_kind, + attractor_type=attractor_type, memory_efficient=memory_efficient, + min_depth=conf["min_depth"], max_depth=conf["max_depth"]) + for i in range(len(n_attractors)) + ]) + for conf in bin_conf} + ) + + last_in = N_MIDAS_OUT + # conditional log binomial for each bin conf + self.conditional_log_binomial = nn.ModuleDict( + {conf['name']: ConditionalLogBinomial(last_in, bin_embedding_dim, conf['n_bins'], bottleneck_factor=4, min_temp=self.min_temp, max_temp=self.max_temp) + for conf in bin_conf} + ) + + def forward(self, x, return_final_centers=False, denorm=False, return_probs=False, **kwargs): + """ + Args: + x (torch.Tensor): Input image tensor of shape (B, C, H, W). Assumes all images are from the same domain. + return_final_centers (bool, optional): Whether to return the final centers of the attractors. Defaults to False. + denorm (bool, optional): Whether to denormalize the input image. Defaults to False. + return_probs (bool, optional): Whether to return the probabilities of the bins. Defaults to False. + + Returns: + dict: Dictionary of outputs with keys: + - "rel_depth": Relative depth map of shape (B, 1, H, W) + - "metric_depth": Metric depth map of shape (B, 1, H, W) + - "domain_logits": Domain logits of shape (B, 2) + - "bin_centers": Bin centers of shape (B, N, H, W). Present only if return_final_centers is True + - "probs": Bin probabilities of shape (B, N, H, W). Present only if return_probs is True + """ + b, c, h, w = x.shape + self.orig_input_width = w + self.orig_input_height = h + rel_depth, out = self.core(x, denorm=denorm, return_rel_depth=True) + + outconv_activation = out[0] + btlnck = out[1] + x_blocks = out[2:] + + x_d0 = self.conv2(btlnck) + x = x_d0 + + # Predict which path to take + embedding = self.patch_transformer(x)[0] # N, E + domain_logits = self.mlp_classifier(embedding) # N, 2 + domain_vote = torch.softmax(domain_logits.sum( + dim=0, keepdim=True), dim=-1) # 1, 2 + + # Get the path + bin_conf_name = ["nyu", "kitti"][torch.argmax( + domain_vote, dim=-1).squeeze().item()] + + try: + conf = [c for c in self.bin_conf if c.name == bin_conf_name][0] + except IndexError: + raise ValueError( + f"bin_conf_name {bin_conf_name} not found in bin_confs") + + min_depth = conf['min_depth'] + max_depth = conf['max_depth'] + + seed_bin_regressor = self.seed_bin_regressors[bin_conf_name] + _, seed_b_centers = seed_bin_regressor(x) + if self.bin_centers_type == 'normed' or self.bin_centers_type == 'hybrid2': + b_prev = (seed_b_centers - min_depth)/(max_depth - min_depth) + else: + b_prev = seed_b_centers + prev_b_embedding = self.seed_projector(x) + + attractors = self.attractors[bin_conf_name] + for projector, attractor, x in zip(self.projectors, attractors, x_blocks): + b_embedding = projector(x) + b, b_centers = attractor( + b_embedding, b_prev, prev_b_embedding, interpolate=True) + b_prev = b + prev_b_embedding = b_embedding + + last = outconv_activation + + b_centers = nn.functional.interpolate( + b_centers, last.shape[-2:], mode='bilinear', align_corners=True) + b_embedding = nn.functional.interpolate( + b_embedding, last.shape[-2:], mode='bilinear', align_corners=True) + + clb = self.conditional_log_binomial[bin_conf_name] + x = clb(last, b_embedding) + + # Now depth value is Sum px * cx , where cx are bin_centers from the last bin tensor + # print(x.shape, b_centers.shape) + # b_centers = nn.functional.interpolate(b_centers, x.shape[-2:], mode='bilinear', align_corners=True) + out = torch.sum(x * b_centers, dim=1, keepdim=True) + + output = dict(domain_logits=domain_logits, metric_depth=out) + if return_final_centers or return_probs: + output['bin_centers'] = b_centers + + if return_probs: + output['probs'] = x + return output + + def get_lr_params(self, lr): + """ + Learning rate configuration for different layers of the model + + Args: + lr (float) : Base learning rate + Returns: + list : list of parameters to optimize and their learning rates, in the format required by torch optimizers. + """ + param_conf = [] + if self.train_midas: + def get_rel_pos_params(): + for name, p in self.core.core.pretrained.named_parameters(): + if "relative_position" in name: + yield p + + def get_enc_params_except_rel_pos(): + for name, p in self.core.core.pretrained.named_parameters(): + if "relative_position" not in name: + yield p + + encoder_params = get_enc_params_except_rel_pos() + rel_pos_params = get_rel_pos_params() + midas_params = self.core.core.scratch.parameters() + midas_lr_factor = self.midas_lr_factor if self.is_midas_pretrained else 1.0 + param_conf.extend([ + {'params': encoder_params, 'lr': lr / self.encoder_lr_factor}, + {'params': rel_pos_params, 'lr': lr / self.pos_enc_lr_factor}, + {'params': midas_params, 'lr': lr / midas_lr_factor} + ]) + + remaining_modules = [] + for name, child in self.named_children(): + if name != 'core': + remaining_modules.append(child) + remaining_params = itertools.chain( + *[child.parameters() for child in remaining_modules]) + param_conf.append({'params': remaining_params, 'lr': lr}) + return param_conf + + def get_conf_parameters(self, conf_name): + """ + Returns parameters of all the ModuleDicts children that are exclusively used for the given bin configuration + """ + params = [] + for name, child in self.named_children(): + if isinstance(child, nn.ModuleDict): + for bin_conf_name, module in child.items(): + if bin_conf_name == conf_name: + params += list(module.parameters()) + return params + + def freeze_conf(self, conf_name): + """ + Freezes all the parameters of all the ModuleDicts children that are exclusively used for the given bin configuration + """ + for p in self.get_conf_parameters(conf_name): + p.requires_grad = False + + def unfreeze_conf(self, conf_name): + """ + Unfreezes all the parameters of all the ModuleDicts children that are exclusively used for the given bin configuration + """ + for p in self.get_conf_parameters(conf_name): + p.requires_grad = True + + def freeze_all_confs(self): + """ + Freezes all the parameters of all the ModuleDicts children + """ + for name, child in self.named_children(): + if isinstance(child, nn.ModuleDict): + for bin_conf_name, module in child.items(): + for p in module.parameters(): + p.requires_grad = False + + @staticmethod + def build(midas_model_type="DPT_BEiT_L_384", pretrained_resource=None, use_pretrained_midas=False, train_midas=False, freeze_midas_bn=True, **kwargs): + core = MidasCore.build(midas_model_type=midas_model_type, use_pretrained_midas=use_pretrained_midas, + train_midas=train_midas, fetch_features=True, freeze_bn=freeze_midas_bn, **kwargs) + model = ZoeDepthNK(core, **kwargs) + if pretrained_resource: + assert isinstance(pretrained_resource, str), "pretrained_resource must be a string" + model = load_state_from_resource(model, pretrained_resource) + return model + + @staticmethod + def build_from_config(config): + return ZoeDepthNK.build(**config) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/__init__.py new file mode 100644 index 00000000..5f266879 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/__init__.py @@ -0,0 +1,24 @@ +# MIT License + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/arg_utils.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/arg_utils.py new file mode 100644 index 00000000..8a3004ec --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/arg_utils.py @@ -0,0 +1,33 @@ + + +def infer_type(x): # hacky way to infer type from string args + if not isinstance(x, str): + return x + + try: + x = int(x) + return x + except ValueError: + pass + + try: + x = float(x) + return x + except ValueError: + pass + + return x + + +def parse_unknown(unknown_args): + clean = [] + for a in unknown_args: + if "=" in a: + k, v = a.split("=") + clean.extend([k, v]) + else: + clean.append(a) + + keys = clean[::2] + values = clean[1::2] + return {k.replace("--", ""): infer_type(v) for k, v in zip(keys, values)} diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/config.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/config.py new file mode 100644 index 00000000..84996564 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/config.py @@ -0,0 +1,437 @@ +# MIT License + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + +import json +import os + +from .easydict import EasyDict as edict +from .arg_utils import infer_type + +import pathlib +import platform + +ROOT = pathlib.Path(__file__).parent.parent.resolve() + +HOME_DIR = os.path.expanduser("~") + +COMMON_CONFIG = { + "save_dir": os.path.expanduser("~/shortcuts/monodepth3_checkpoints"), + "project": "ZoeDepth", + "tags": '', + "notes": "", + "gpu": None, + "root": ".", + "uid": None, + "print_losses": False +} + +DATASETS_CONFIG = { + "kitti": { + "dataset": "kitti", + "min_depth": 0.001, + "max_depth": 80, + "data_path": os.path.join(HOME_DIR, "shortcuts/datasets/kitti/raw"), + "gt_path": os.path.join(HOME_DIR, "shortcuts/datasets/kitti/gts"), + "filenames_file": "./train_test_inputs/kitti_eigen_train_files_with_gt.txt", + "input_height": 352, + "input_width": 1216, # 704 + "data_path_eval": os.path.join(HOME_DIR, "shortcuts/datasets/kitti/raw"), + "gt_path_eval": os.path.join(HOME_DIR, "shortcuts/datasets/kitti/gts"), + "filenames_file_eval": "./train_test_inputs/kitti_eigen_test_files_with_gt.txt", + + "min_depth_eval": 1e-3, + "max_depth_eval": 80, + + "do_random_rotate": True, + "degree": 1.0, + "do_kb_crop": True, + "garg_crop": True, + "eigen_crop": False, + "use_right": False + }, + "kitti_test": { + "dataset": "kitti", + "min_depth": 0.001, + "max_depth": 80, + "data_path": os.path.join(HOME_DIR, "shortcuts/datasets/kitti/raw"), + "gt_path": os.path.join(HOME_DIR, "shortcuts/datasets/kitti/gts"), + "filenames_file": "./train_test_inputs/kitti_eigen_train_files_with_gt.txt", + "input_height": 352, + "input_width": 1216, + "data_path_eval": os.path.join(HOME_DIR, "shortcuts/datasets/kitti/raw"), + "gt_path_eval": os.path.join(HOME_DIR, "shortcuts/datasets/kitti/gts"), + "filenames_file_eval": "./train_test_inputs/kitti_eigen_test_files_with_gt.txt", + + "min_depth_eval": 1e-3, + "max_depth_eval": 80, + + "do_random_rotate": False, + "degree": 1.0, + "do_kb_crop": True, + "garg_crop": True, + "eigen_crop": False, + "use_right": False + }, + "nyu": { + "dataset": "nyu", + "avoid_boundary": False, + "min_depth": 1e-3, # originally 0.1 + "max_depth": 10, + "data_path": os.path.join(HOME_DIR, "shortcuts/datasets/nyu_depth_v2/sync/"), + "gt_path": os.path.join(HOME_DIR, "shortcuts/datasets/nyu_depth_v2/sync/"), + "filenames_file": "./train_test_inputs/nyudepthv2_train_files_with_gt.txt", + "input_height": 480, + "input_width": 640, + "data_path_eval": os.path.join(HOME_DIR, "shortcuts/datasets/nyu_depth_v2/official_splits/test/"), + "gt_path_eval": os.path.join(HOME_DIR, "shortcuts/datasets/nyu_depth_v2/official_splits/test/"), + "filenames_file_eval": "./train_test_inputs/nyudepthv2_test_files_with_gt.txt", + "min_depth_eval": 1e-3, + "max_depth_eval": 10, + "min_depth_diff": -10, + "max_depth_diff": 10, + + "do_random_rotate": True, + "degree": 1.0, + "do_kb_crop": False, + "garg_crop": False, + "eigen_crop": True + }, + "ibims": { + "dataset": "ibims", + "ibims_root": os.path.join(HOME_DIR, "shortcuts/datasets/ibims/ibims1_core_raw/"), + "eigen_crop": True, + "garg_crop": False, + "do_kb_crop": False, + "min_depth_eval": 0, + "max_depth_eval": 10, + "min_depth": 1e-3, + "max_depth": 10 + }, + "sunrgbd": { + "dataset": "sunrgbd", + "sunrgbd_root": os.path.join(HOME_DIR, "shortcuts/datasets/SUNRGBD/test/"), + "eigen_crop": True, + "garg_crop": False, + "do_kb_crop": False, + "min_depth_eval": 0, + "max_depth_eval": 8, + "min_depth": 1e-3, + "max_depth": 10 + }, + "diml_indoor": { + "dataset": "diml_indoor", + "diml_indoor_root": os.path.join(HOME_DIR, "shortcuts/datasets/diml_indoor_test/"), + "eigen_crop": True, + "garg_crop": False, + "do_kb_crop": False, + "min_depth_eval": 0, + "max_depth_eval": 10, + "min_depth": 1e-3, + "max_depth": 10 + }, + "diml_outdoor": { + "dataset": "diml_outdoor", + "diml_outdoor_root": os.path.join(HOME_DIR, "shortcuts/datasets/diml_outdoor_test/"), + "eigen_crop": False, + "garg_crop": True, + "do_kb_crop": False, + "min_depth_eval": 2, + "max_depth_eval": 80, + "min_depth": 1e-3, + "max_depth": 80 + }, + "diode_indoor": { + "dataset": "diode_indoor", + "diode_indoor_root": os.path.join(HOME_DIR, "shortcuts/datasets/diode_indoor/"), + "eigen_crop": True, + "garg_crop": False, + "do_kb_crop": False, + "min_depth_eval": 1e-3, + "max_depth_eval": 10, + "min_depth": 1e-3, + "max_depth": 10 + }, + "diode_outdoor": { + "dataset": "diode_outdoor", + "diode_outdoor_root": os.path.join(HOME_DIR, "shortcuts/datasets/diode_outdoor/"), + "eigen_crop": False, + "garg_crop": True, + "do_kb_crop": False, + "min_depth_eval": 1e-3, + "max_depth_eval": 80, + "min_depth": 1e-3, + "max_depth": 80 + }, + "hypersim_test": { + "dataset": "hypersim_test", + "hypersim_test_root": os.path.join(HOME_DIR, "shortcuts/datasets/hypersim_test/"), + "eigen_crop": True, + "garg_crop": False, + "do_kb_crop": False, + "min_depth_eval": 1e-3, + "max_depth_eval": 80, + "min_depth": 1e-3, + "max_depth": 10 + }, + "vkitti": { + "dataset": "vkitti", + "vkitti_root": os.path.join(HOME_DIR, "shortcuts/datasets/vkitti_test/"), + "eigen_crop": False, + "garg_crop": True, + "do_kb_crop": True, + "min_depth_eval": 1e-3, + "max_depth_eval": 80, + "min_depth": 1e-3, + "max_depth": 80 + }, + "vkitti2": { + "dataset": "vkitti2", + "vkitti2_root": os.path.join(HOME_DIR, "shortcuts/datasets/vkitti2/"), + "eigen_crop": False, + "garg_crop": True, + "do_kb_crop": True, + "min_depth_eval": 1e-3, + "max_depth_eval": 80, + "min_depth": 1e-3, + "max_depth": 80, + }, + "ddad": { + "dataset": "ddad", + "ddad_root": os.path.join(HOME_DIR, "shortcuts/datasets/ddad/ddad_val/"), + "eigen_crop": False, + "garg_crop": True, + "do_kb_crop": True, + "min_depth_eval": 1e-3, + "max_depth_eval": 80, + "min_depth": 1e-3, + "max_depth": 80, + }, +} + +ALL_INDOOR = ["nyu", "ibims", "sunrgbd", "diode_indoor", "hypersim_test"] +ALL_OUTDOOR = ["kitti", "diml_outdoor", "diode_outdoor", "vkitti2", "ddad"] +ALL_EVAL_DATASETS = ALL_INDOOR + ALL_OUTDOOR + +COMMON_TRAINING_CONFIG = { + "dataset": "nyu", + "distributed": True, + "workers": 16, + "clip_grad": 0.1, + "use_shared_dict": False, + "shared_dict": None, + "use_amp": False, + + "aug": True, + "random_crop": False, + "random_translate": False, + "translate_prob": 0.2, + "max_translation": 100, + + "validate_every": 0.25, + "log_images_every": 0.1, + "prefetch": False, +} + + +def flatten(config, except_keys=('bin_conf')): + def recurse(inp): + if isinstance(inp, dict): + for key, value in inp.items(): + if key in except_keys: + yield (key, value) + if isinstance(value, dict): + yield from recurse(value) + else: + yield (key, value) + + return dict(list(recurse(config))) + + +def split_combined_args(kwargs): + """Splits the arguments that are combined with '__' into multiple arguments. + Combined arguments should have equal number of keys and values. + Keys are separated by '__' and Values are separated with ';'. + For example, '__n_bins__lr=256;0.001' + + Args: + kwargs (dict): key-value pairs of arguments where key-value is optionally combined according to the above format. + + Returns: + dict: Parsed dict with the combined arguments split into individual key-value pairs. + """ + new_kwargs = dict(kwargs) + for key, value in kwargs.items(): + if key.startswith("__"): + keys = key.split("__")[1:] + values = value.split(";") + assert len(keys) == len( + values), f"Combined arguments should have equal number of keys and values. Keys are separated by '__' and Values are separated with ';'. For example, '__n_bins__lr=256;0.001. Given (keys,values) is ({keys}, {values})" + for k, v in zip(keys, values): + new_kwargs[k] = v + return new_kwargs + + +def parse_list(config, key, dtype=int): + """Parse a list of values for the key if the value is a string. The values are separated by a comma. + Modifies the config in place. + """ + if key in config: + if isinstance(config[key], str): + config[key] = list(map(dtype, config[key].split(','))) + assert isinstance(config[key], list) and all([isinstance(e, dtype) for e in config[key]] + ), f"{key} should be a list of values dtype {dtype}. Given {config[key]} of type {type(config[key])} with values of type {[type(e) for e in config[key]]}." + + +def get_model_config(model_name, model_version=None): + """Find and parse the .json config file for the model. + + Args: + model_name (str): name of the model. The config file should be named config_{model_name}[_{model_version}].json under the models/{model_name} directory. + model_version (str, optional): Specific config version. If specified config_{model_name}_{model_version}.json is searched for and used. Otherwise config_{model_name}.json is used. Defaults to None. + + Returns: + easydict: the config dictionary for the model. + """ + config_fname = f"config_{model_name}_{model_version}.json" if model_version is not None else f"config_{model_name}.json" + config_file = os.path.join(ROOT, "models", model_name, config_fname) + if not os.path.exists(config_file): + return None + + with open(config_file, "r") as f: + config = edict(json.load(f)) + + # handle dictionary inheritance + # only training config is supported for inheritance + if "inherit" in config.train and config.train.inherit is not None: + inherit_config = get_model_config(config.train["inherit"]).train + for key, value in inherit_config.items(): + if key not in config.train: + config.train[key] = value + return edict(config) + + +def update_model_config(config, mode, model_name, model_version=None, strict=False): + model_config = get_model_config(model_name, model_version) + if model_config is not None: + config = {**config, ** + flatten({**model_config.model, **model_config[mode]})} + elif strict: + raise ValueError(f"Config file for model {model_name} not found.") + return config + + +def check_choices(name, value, choices): + # return # No checks in dev branch + if value not in choices: + raise ValueError(f"{name} {value} not in supported choices {choices}") + + +KEYS_TYPE_BOOL = ["use_amp", "distributed", "use_shared_dict", "same_lr", "aug", "three_phase", + "prefetch", "cycle_momentum"] # Casting is not necessary as their int casted values in config are 0 or 1 + + +def get_config(model_name, mode='train', dataset=None, **overwrite_kwargs): + """Main entry point to get the config for the model. + + Args: + model_name (str): name of the desired model. + mode (str, optional): "train" or "infer". Defaults to 'train'. + dataset (str, optional): If specified, the corresponding dataset configuration is loaded as well. Defaults to None. + + Keyword Args: key-value pairs of arguments to overwrite the default config. + + The order of precedence for overwriting the config is (Higher precedence first): + # 1. overwrite_kwargs + # 2. "config_version": Config file version if specified in overwrite_kwargs. The corresponding config loaded is config_{model_name}_{config_version}.json + # 3. "version_name": Default Model version specific config specified in overwrite_kwargs. The corresponding config loaded is config_{model_name}_{version_name}.json + # 4. common_config: Default config for all models specified in COMMON_CONFIG + + Returns: + easydict: The config dictionary for the model. + """ + + + check_choices("Model", model_name, ["zoedepth", "zoedepth_nk"]) + check_choices("Mode", mode, ["train", "infer", "eval"]) + if mode == "train": + check_choices("Dataset", dataset, ["nyu", "kitti", "mix", None]) + + config = flatten({**COMMON_CONFIG, **COMMON_TRAINING_CONFIG}) + config = update_model_config(config, mode, model_name) + + # update with model version specific config + version_name = overwrite_kwargs.get("version_name", config["version_name"]) + config = update_model_config(config, mode, model_name, version_name) + + # update with config version if specified + config_version = overwrite_kwargs.get("config_version", None) + if config_version is not None: + print("Overwriting config with config_version", config_version) + config = update_model_config(config, mode, model_name, config_version) + + # update with overwrite_kwargs + # Combined args are useful for hyperparameter search + overwrite_kwargs = split_combined_args(overwrite_kwargs) + config = {**config, **overwrite_kwargs} + + # Casting to bool # TODO: Not necessary. Remove and test + for key in KEYS_TYPE_BOOL: + if key in config: + config[key] = bool(config[key]) + + # Model specific post processing of config + parse_list(config, "n_attractors") + + # adjust n_bins for each bin configuration if bin_conf is given and n_bins is passed in overwrite_kwargs + if 'bin_conf' in config and 'n_bins' in overwrite_kwargs: + bin_conf = config['bin_conf'] # list of dicts + n_bins = overwrite_kwargs['n_bins'] + new_bin_conf = [] + for conf in bin_conf: + conf['n_bins'] = n_bins + new_bin_conf.append(conf) + config['bin_conf'] = new_bin_conf + + if mode == "train": + orig_dataset = dataset + if dataset == "mix": + dataset = 'nyu' # Use nyu as default for mix. Dataset config is changed accordingly while loading the dataloader + if dataset is not None: + config['project'] = f"MonoDepth3-{orig_dataset}" # Set project for wandb + + if dataset is not None: + config['dataset'] = dataset + config = {**DATASETS_CONFIG[dataset], **config} + + + config['model'] = model_name + typed_config = {k: infer_type(v) for k, v in config.items()} + # add hostname to config + config['hostname'] = platform.node() + return edict(typed_config) + + +def change_dataset(config, new_dataset): + config.update(DATASETS_CONFIG[new_dataset]) + return config diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/easydict/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/easydict/__init__.py new file mode 100644 index 00000000..15928179 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/easydict/__init__.py @@ -0,0 +1,158 @@ +""" +EasyDict +Copy/pasted from https://github.com/makinacorpus/easydict +Original author: Mathieu Leplatre +""" + +class EasyDict(dict): + """ + Get attributes + + >>> d = EasyDict({'foo':3}) + >>> d['foo'] + 3 + >>> d.foo + 3 + >>> d.bar + Traceback (most recent call last): + ... + AttributeError: 'EasyDict' object has no attribute 'bar' + + Works recursively + + >>> d = EasyDict({'foo':3, 'bar':{'x':1, 'y':2}}) + >>> isinstance(d.bar, dict) + True + >>> d.bar.x + 1 + + Bullet-proof + + >>> EasyDict({}) + {} + >>> EasyDict(d={}) + {} + >>> EasyDict(None) + {} + >>> d = {'a': 1} + >>> EasyDict(**d) + {'a': 1} + >>> EasyDict((('a', 1), ('b', 2))) + {'a': 1, 'b': 2} + + Set attributes + + >>> d = EasyDict() + >>> d.foo = 3 + >>> d.foo + 3 + >>> d.bar = {'prop': 'value'} + >>> d.bar.prop + 'value' + >>> d + {'foo': 3, 'bar': {'prop': 'value'}} + >>> d.bar.prop = 'newer' + >>> d.bar.prop + 'newer' + + + Values extraction + + >>> d = EasyDict({'foo':0, 'bar':[{'x':1, 'y':2}, {'x':3, 'y':4}]}) + >>> isinstance(d.bar, list) + True + >>> from operator import attrgetter + >>> list(map(attrgetter('x'), d.bar)) + [1, 3] + >>> list(map(attrgetter('y'), d.bar)) + [2, 4] + >>> d = EasyDict() + >>> list(d.keys()) + [] + >>> d = EasyDict(foo=3, bar=dict(x=1, y=2)) + >>> d.foo + 3 + >>> d.bar.x + 1 + + Still like a dict though + + >>> o = EasyDict({'clean':True}) + >>> list(o.items()) + [('clean', True)] + + And like a class + + >>> class Flower(EasyDict): + ... power = 1 + ... + >>> f = Flower() + >>> f.power + 1 + >>> f = Flower({'height': 12}) + >>> f.height + 12 + >>> f['power'] + 1 + >>> sorted(f.keys()) + ['height', 'power'] + + update and pop items + >>> d = EasyDict(a=1, b='2') + >>> e = EasyDict(c=3.0, a=9.0) + >>> d.update(e) + >>> d.c + 3.0 + >>> d['c'] + 3.0 + >>> d.get('c') + 3.0 + >>> d.update(a=4, b=4) + >>> d.b + 4 + >>> d.pop('a') + 4 + >>> d.a + Traceback (most recent call last): + ... + AttributeError: 'EasyDict' object has no attribute 'a' + """ + def __init__(self, d=None, **kwargs): + if d is None: + d = {} + else: + d = dict(d) + if kwargs: + d.update(**kwargs) + for k, v in d.items(): + setattr(self, k, v) + # Class attributes + for k in self.__class__.__dict__.keys(): + if not (k.startswith('__') and k.endswith('__')) and not k in ('update', 'pop'): + setattr(self, k, getattr(self, k)) + + def __setattr__(self, name, value): + if isinstance(value, (list, tuple)): + value = [self.__class__(x) + if isinstance(x, dict) else x for x in value] + elif isinstance(value, dict) and not isinstance(value, self.__class__): + value = self.__class__(value) + super(EasyDict, self).__setattr__(name, value) + super(EasyDict, self).__setitem__(name, value) + + __setitem__ = __setattr__ + + def update(self, e=None, **f): + d = e or dict() + d.update(f) + for k in d: + setattr(self, k, d[k]) + + def pop(self, k, d=None): + delattr(self, k) + return super(EasyDict, self).pop(k, d) + + +if __name__ == "__main__": + import doctest + doctest.testmod() \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/geometry.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/geometry.py new file mode 100644 index 00000000..e3da8c75 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/geometry.py @@ -0,0 +1,98 @@ +# MIT License + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + +import numpy as np + +def get_intrinsics(H,W): + """ + Intrinsics for a pinhole camera model. + Assume fov of 55 degrees and central principal point. + """ + f = 0.5 * W / np.tan(0.5 * 55 * np.pi / 180.0) + cx = 0.5 * W + cy = 0.5 * H + return np.array([[f, 0, cx], + [0, f, cy], + [0, 0, 1]]) + +def depth_to_points(depth, R=None, t=None): + + K = get_intrinsics(depth.shape[1], depth.shape[2]) + Kinv = np.linalg.inv(K) + if R is None: + R = np.eye(3) + if t is None: + t = np.zeros(3) + + # M converts from your coordinate to PyTorch3D's coordinate system + M = np.eye(3) + M[0, 0] = -1.0 + M[1, 1] = -1.0 + + height, width = depth.shape[1:3] + + x = np.arange(width) + y = np.arange(height) + coord = np.stack(np.meshgrid(x, y), -1) + coord = np.concatenate((coord, np.ones_like(coord)[:, :, [0]]), -1) # z=1 + coord = coord.astype(np.float32) + # coord = torch.as_tensor(coord, dtype=torch.float32, device=device) + coord = coord[None] # bs, h, w, 3 + + D = depth[:, :, :, None, None] + # print(D.shape, Kinv[None, None, None, ...].shape, coord[:, :, :, :, None].shape ) + pts3D_1 = D * Kinv[None, None, None, ...] @ coord[:, :, :, :, None] + # pts3D_1 live in your coordinate system. Convert them to Py3D's + pts3D_1 = M[None, None, None, ...] @ pts3D_1 + # from reference to targe tviewpoint + pts3D_2 = R[None, None, None, ...] @ pts3D_1 + t[None, None, None, :, None] + # pts3D_2 = pts3D_1 + # depth_2 = pts3D_2[:, :, :, 2, :] # b,1,h,w + return pts3D_2[:, :, :, :3, 0][0] + + +def create_triangles(h, w, mask=None): + """ + Reference: https://github.com/google-research/google-research/blob/e96197de06613f1b027d20328e06d69829fa5a89/infinite_nature/render_utils.py#L68 + Creates mesh triangle indices from a given pixel grid size. + This function is not and need not be differentiable as triangle indices are + fixed. + Args: + h: (int) denoting the height of the image. + w: (int) denoting the width of the image. + Returns: + triangles: 2D numpy array of indices (int) with shape (2(W-1)(H-1) x 3) + """ + x, y = np.meshgrid(range(w - 1), range(h - 1)) + tl = y * w + x + tr = y * w + x + 1 + bl = (y + 1) * w + x + br = (y + 1) * w + x + 1 + triangles = np.array([tl, bl, tr, br, tr, bl]) + triangles = np.transpose(triangles, (1, 2, 0)).reshape( + ((w - 1) * (h - 1) * 2, 3)) + if mask is not None: + mask = mask.reshape(-1) + triangles = triangles[mask[triangles].all(1)] + return triangles diff --git a/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/misc.py b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/misc.py new file mode 100644 index 00000000..4bbe403d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/zoe/zoedepth/utils/misc.py @@ -0,0 +1,368 @@ +# MIT License + +# Copyright (c) 2022 Intelligent Systems Lab Org + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File author: Shariq Farooq Bhat + +"""Miscellaneous utility functions.""" + +from scipy import ndimage + +import base64 +import math +import re +from io import BytesIO + +import matplotlib +import matplotlib.cm +import numpy as np +import requests +import torch +import torch.distributed as dist +import torch.nn +import torch.nn as nn +import torch.utils.data.distributed +from PIL import Image +from torchvision.transforms import ToTensor + + +class RunningAverage: + def __init__(self): + self.avg = 0 + self.count = 0 + + def append(self, value): + self.avg = (value + self.count * self.avg) / (self.count + 1) + self.count += 1 + + def get_value(self): + return self.avg + + +def denormalize(x): + """Reverses the imagenet normalization applied to the input. + + Args: + x (torch.Tensor - shape(N,3,H,W)): input tensor + + Returns: + torch.Tensor - shape(N,3,H,W): Denormalized input + """ + mean = torch.Tensor([0.485, 0.456, 0.406]).view(1, 3, 1, 1).to(x.device) + std = torch.Tensor([0.229, 0.224, 0.225]).view(1, 3, 1, 1).to(x.device) + return x * std + mean + + +class RunningAverageDict: + """A dictionary of running averages.""" + def __init__(self): + self._dict = None + + def update(self, new_dict): + if new_dict is None: + return + + if self._dict is None: + self._dict = dict() + for key, value in new_dict.items(): + self._dict[key] = RunningAverage() + + for key, value in new_dict.items(): + self._dict[key].append(value) + + def get_value(self): + if self._dict is None: + return None + return {key: value.get_value() for key, value in self._dict.items()} + + +def colorize(value, vmin=None, vmax=None, cmap='gray_r', invalid_val=-99, invalid_mask=None, background_color=(128, 128, 128, 255), gamma_corrected=False, value_transform=None): + """Converts a depth map to a color image. + + Args: + value (torch.Tensor, numpy.ndarry): Input depth map. Shape: (H, W) or (1, H, W) or (1, 1, H, W). All singular dimensions are squeezed + vmin (float, optional): vmin-valued entries are mapped to start color of cmap. If None, value.min() is used. Defaults to None. + vmax (float, optional): vmax-valued entries are mapped to end color of cmap. If None, value.max() is used. Defaults to None. + cmap (str, optional): matplotlib colormap to use. Defaults to 'magma_r'. + invalid_val (int, optional): Specifies value of invalid pixels that should be colored as 'background_color'. Defaults to -99. + invalid_mask (numpy.ndarray, optional): Boolean mask for invalid regions. Defaults to None. + background_color (tuple[int], optional): 4-tuple RGB color to give to invalid pixels. Defaults to (128, 128, 128, 255). + gamma_corrected (bool, optional): Apply gamma correction to colored image. Defaults to False. + value_transform (Callable, optional): Apply transform function to valid pixels before coloring. Defaults to None. + + Returns: + numpy.ndarray, dtype - uint8: Colored depth map. Shape: (H, W, 4) + """ + if isinstance(value, torch.Tensor): + value = value.detach().cpu().numpy() + + value = value.squeeze() + if invalid_mask is None: + invalid_mask = value == invalid_val + mask = np.logical_not(invalid_mask) + + # normalize + vmin = np.percentile(value[mask],2) if vmin is None else vmin + vmax = np.percentile(value[mask],85) if vmax is None else vmax + if vmin != vmax: + value = (value - vmin) / (vmax - vmin) # vmin..vmax + else: + # Avoid 0-division + value = value * 0. + + # squeeze last dim if it exists + # grey out the invalid values + + value[invalid_mask] = np.nan + cmapper = matplotlib.cm.get_cmap(cmap) + if value_transform: + value = value_transform(value) + # value = value / value.max() + value = cmapper(value, bytes=True) # (nxmx4) + + # img = value[:, :, :] + img = value[...] + img[invalid_mask] = background_color + + # return img.transpose((2, 0, 1)) + if gamma_corrected: + # gamma correction + img = img / 255 + img = np.power(img, 2.2) + img = img * 255 + img = img.astype(np.uint8) + return img + + +def count_parameters(model, include_all=False): + return sum(p.numel() for p in model.parameters() if p.requires_grad or include_all) + + +def compute_errors(gt, pred): + """Compute metrics for 'pred' compared to 'gt' + + Args: + gt (numpy.ndarray): Ground truth values + pred (numpy.ndarray): Predicted values + + gt.shape should be equal to pred.shape + + Returns: + dict: Dictionary containing the following metrics: + 'a1': Delta1 accuracy: Fraction of pixels that are within a scale factor of 1.25 + 'a2': Delta2 accuracy: Fraction of pixels that are within a scale factor of 1.25^2 + 'a3': Delta3 accuracy: Fraction of pixels that are within a scale factor of 1.25^3 + 'abs_rel': Absolute relative error + 'rmse': Root mean squared error + 'log_10': Absolute log10 error + 'sq_rel': Squared relative error + 'rmse_log': Root mean squared error on the log scale + 'silog': Scale invariant log error + """ + thresh = np.maximum((gt / pred), (pred / gt)) + a1 = (thresh < 1.25).mean() + a2 = (thresh < 1.25 ** 2).mean() + a3 = (thresh < 1.25 ** 3).mean() + + abs_rel = np.mean(np.abs(gt - pred) / gt) + sq_rel = np.mean(((gt - pred) ** 2) / gt) + + rmse = (gt - pred) ** 2 + rmse = np.sqrt(rmse.mean()) + + rmse_log = (np.log(gt) - np.log(pred)) ** 2 + rmse_log = np.sqrt(rmse_log.mean()) + + err = np.log(pred) - np.log(gt) + silog = np.sqrt(np.mean(err ** 2) - np.mean(err) ** 2) * 100 + + log_10 = (np.abs(np.log10(gt) - np.log10(pred))).mean() + return dict(a1=a1, a2=a2, a3=a3, abs_rel=abs_rel, rmse=rmse, log_10=log_10, rmse_log=rmse_log, + silog=silog, sq_rel=sq_rel) + + +def compute_metrics(gt, pred, interpolate=True, garg_crop=False, eigen_crop=True, dataset='nyu', min_depth_eval=0.1, max_depth_eval=10, **kwargs): + """Compute metrics of predicted depth maps. Applies cropping and masking as necessary or specified via arguments. Refer to compute_errors for more details on metrics. + """ + if 'config' in kwargs: + config = kwargs['config'] + garg_crop = config.garg_crop + eigen_crop = config.eigen_crop + min_depth_eval = config.min_depth_eval + max_depth_eval = config.max_depth_eval + + if gt.shape[-2:] != pred.shape[-2:] and interpolate: + pred = nn.functional.interpolate( + pred, gt.shape[-2:], mode='bilinear', align_corners=True) + + pred = pred.squeeze().cpu().numpy() + pred[pred < min_depth_eval] = min_depth_eval + pred[pred > max_depth_eval] = max_depth_eval + pred[np.isinf(pred)] = max_depth_eval + pred[np.isnan(pred)] = min_depth_eval + + gt_depth = gt.squeeze().cpu().numpy() + valid_mask = np.logical_and( + gt_depth > min_depth_eval, gt_depth < max_depth_eval) + + if garg_crop or eigen_crop: + gt_height, gt_width = gt_depth.shape + eval_mask = np.zeros(valid_mask.shape) + + if garg_crop: + eval_mask[int(0.40810811 * gt_height):int(0.99189189 * gt_height), + int(0.03594771 * gt_width):int(0.96405229 * gt_width)] = 1 + + elif eigen_crop: + # print("-"*10, " EIGEN CROP ", "-"*10) + if dataset == 'kitti': + eval_mask[int(0.3324324 * gt_height):int(0.91351351 * gt_height), + int(0.0359477 * gt_width):int(0.96405229 * gt_width)] = 1 + else: + # assert gt_depth.shape == (480, 640), "Error: Eigen crop is currently only valid for (480, 640) images" + eval_mask[45:471, 41:601] = 1 + else: + eval_mask = np.ones(valid_mask.shape) + valid_mask = np.logical_and(valid_mask, eval_mask) + return compute_errors(gt_depth[valid_mask], pred[valid_mask]) + + +#################################### Model uilts ################################################ + + +def parallelize(config, model, find_unused_parameters=True): + + if config.gpu is not None: + torch.cuda.set_device(config.gpu) + model = model.cuda(config.gpu) + + config.multigpu = False + if config.distributed: + # Use DDP + config.multigpu = True + config.rank = config.rank * config.ngpus_per_node + config.gpu + dist.init_process_group(backend=config.dist_backend, init_method=config.dist_url, + world_size=config.world_size, rank=config.rank) + config.batch_size = int(config.batch_size / config.ngpus_per_node) + # config.batch_size = 8 + config.workers = int( + (config.num_workers + config.ngpus_per_node - 1) / config.ngpus_per_node) + print("Device", config.gpu, "Rank", config.rank, "batch size", + config.batch_size, "Workers", config.workers) + torch.cuda.set_device(config.gpu) + model = nn.SyncBatchNorm.convert_sync_batchnorm(model) + model = model.cuda(config.gpu) + model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[config.gpu], output_device=config.gpu, + find_unused_parameters=find_unused_parameters) + + elif config.gpu is None: + # Use DP + config.multigpu = True + model = model.cuda() + model = torch.nn.DataParallel(model) + + return model + + +################################################################################################# + + +##################################################################################################### + + +class colors: + '''Colors class: + Reset all colors with colors.reset + Two subclasses fg for foreground and bg for background. + Use as colors.subclass.colorname. + i.e. colors.fg.red or colors.bg.green + Also, the generic bold, disable, underline, reverse, strikethrough, + and invisible work with the main class + i.e. colors.bold + ''' + reset = '\033[0m' + bold = '\033[01m' + disable = '\033[02m' + underline = '\033[04m' + reverse = '\033[07m' + strikethrough = '\033[09m' + invisible = '\033[08m' + + class fg: + black = '\033[30m' + red = '\033[31m' + green = '\033[32m' + orange = '\033[33m' + blue = '\033[34m' + purple = '\033[35m' + cyan = '\033[36m' + lightgrey = '\033[37m' + darkgrey = '\033[90m' + lightred = '\033[91m' + lightgreen = '\033[92m' + yellow = '\033[93m' + lightblue = '\033[94m' + pink = '\033[95m' + lightcyan = '\033[96m' + + class bg: + black = '\033[40m' + red = '\033[41m' + green = '\033[42m' + orange = '\033[43m' + blue = '\033[44m' + purple = '\033[45m' + cyan = '\033[46m' + lightgrey = '\033[47m' + + +def printc(text, color): + print(f"{color}{text}{colors.reset}") + +############################################ + +def get_image_from_url(url): + response = requests.get(url) + img = Image.open(BytesIO(response.content)).convert("RGB") + return img + +def url_to_torch(url, size=(384, 384)): + img = get_image_from_url(url) + img = img.resize(size, Image.ANTIALIAS) + img = torch.from_numpy(np.asarray(img)).float() + img = img.permute(2, 0, 1) + img.div_(255) + return img + +def pil_to_batched_tensor(img): + return ToTensor()(img).unsqueeze(0) + +def save_raw_16bit(depth, fpath="raw.png"): + if isinstance(depth, torch.Tensor): + depth = depth.squeeze().cpu().numpy() + + assert isinstance(depth, np.ndarray), "Depth must be a torch tensor or numpy array" + assert depth.ndim == 2, "Depth must be 2D" + depth = depth * 256 # scale for 16-bit png + depth = depth.astype(np.uint16) + depth = Image.fromarray(depth) + depth.save(fpath) + print("Saved raw depth to", fpath) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/example/advanced_weighting_example/api_advanced_weighting.py b/extensions-builtin/sd_forge_controlnet/example/advanced_weighting_example/api_advanced_weighting.py new file mode 100644 index 00000000..ba508b7d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/example/advanced_weighting_example/api_advanced_weighting.py @@ -0,0 +1,119 @@ +import io +import cv2 +import base64 +import requests +from PIL import Image + +""" + To use this example make sure you've done the following steps before executing: + 1. Ensure automatic1111 is running in api mode with the controlnet extension. + Use the following command in your terminal to activate: + ./webui.sh --no-half --api + 2. Validate python environment meet package dependencies. + If running in a local repo you'll likely need to pip install cv2, requests and PIL +""" + + +def generate(url: str, payload: dict, file_suffix: str = ""): + response = requests.post(url=url, json=payload).json() + if "images" not in response: + print(response) + else: + for i, base64image in enumerate(response["images"]): + Image.open(io.BytesIO(base64.b64decode(base64image.split(",", 1)[0]))).save( + f"{url.split('/')[-1]}-{i}{file_suffix}.png" + ) + + +def read_image(img_path: str) -> str: + img = cv2.imread(img_path) + _, bytes = cv2.imencode(".png", img) + encoded_image = base64.b64encode(bytes).decode("utf-8") + return encoded_image + + +input_image = read_image("stock_mountain.png") + +txt2img_payload = { + "alwayson_scripts": { + "ControlNet": { + "args": [ + { + "batch_images": "", + "control_mode": "Balanced", + "enabled": True, + "guidance_end": 1, + "guidance_start": 0, + "image": input_image, + "low_vram": False, + "model": "control_v11p_sd15_canny [d14c016b]", + "module": "canny", + "pixel_perfect": False, + "processor_res": -1, + "resize_mode": "Crop and Resize", + "save_detected_map": True, + "threshold_a": -1, + "threshold_b": -1, + "weight": 1, + } + ] + } + }, + "batch_size": 1, + "cfg_scale": 7, + "comments": {}, + "disable_extra_networks": False, + "do_not_save_grid": False, + "do_not_save_samples": False, + "enable_hr": False, + "height": 512, + "width": 768, + "hr_negative_prompt": "", + "hr_prompt": "", + "hr_resize_x": 0, + "hr_resize_y": 0, + "hr_scale": 2, + "hr_second_pass_steps": 0, + "hr_upscaler": "Latent", + "n_iter": 1, + "negative_prompt": "", + "override_settings": {}, + "override_settings_restore_afterwards": True, + "prompt": "(masterpiece: 1.3), (highres: 1.3), best quality, a large avalanche", + "restore_faces": False, + "s_churn": 0.0, + "s_min_uncond": 0, + "s_noise": 1.0, + "s_tmax": None, + "s_tmin": 0.0, + "sampler_name": "DPM++ 2M Karras", + "script_args": [], + "script_name": None, + "seed": 42, + "seed_enable_extras": True, + "seed_resize_from_h": -1, + "seed_resize_from_w": -1, + "steps": 30, + "styles": [], + "subseed": -1, + "subseed_strength": 0, + "tiling": False, +} + + +if __name__ == "__main__": + url = "http://localhost:7860/sdapi/v1/" + for weight_factor in (0.3, 0.5, 0.8): + advanced_weighting = [weight_factor ** float(12 - i) for i in range(13)] + txt2img_payload["alwayson_scripts"]["ControlNet"]["args"][0][ + "advanced_weighting" + ] = advanced_weighting + generate(url + "txt2img", txt2img_payload, file_suffix=f"fac{weight_factor}") + + for linear_start in (0.3, 0.5, 0.8): + step = (1.0 - linear_start) / 12 + advanced_weighting = [linear_start + i * step for i in range(13)] + txt2img_payload["alwayson_scripts"]["ControlNet"]["args"][0][ + "advanced_weighting" + ] = advanced_weighting + generate(url + "txt2img", txt2img_payload, file_suffix=f"linear{linear_start}") diff --git a/extensions-builtin/sd_forge_controlnet/example/advanced_weighting_example/stock_mountain.png b/extensions-builtin/sd_forge_controlnet/example/advanced_weighting_example/stock_mountain.png new file mode 100644 index 0000000000000000000000000000000000000000..4c036e8e281b3641943b4f973132aa19fe0aae0f GIT binary patch literal 106568 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 f8xPqqUfsDh?<= keep_last_n_words: + last_n_tokens = last_n_tokens - len(paragraphs[0].split(' ')) + paragraphs = paragraphs[1:] + return '\n' + '\n'.join(paragraphs) + +def get_new_image_name(org_img_name, func_name="update"): + head_tail = os.path.split(org_img_name) + head = head_tail[0] + tail = head_tail[1] + name_split = tail.split('.')[0].split('_') + this_new_uuid = str(uuid.uuid4())[0:4] + if len(name_split) == 1: + most_org_file_name = name_split[0] + recent_prev_file_name = name_split[0] + new_file_name = '{}_{}_{}_{}.png'.format(this_new_uuid, func_name, recent_prev_file_name, most_org_file_name) + else: + assert len(name_split) == 4 + most_org_file_name = name_split[3] + recent_prev_file_name = name_split[0] + new_file_name = '{}_{}_{}_{}.png'.format(this_new_uuid, func_name, recent_prev_file_name, most_org_file_name) + return os.path.join(head, new_file_name) + +class MaskFormer: + def __init__(self, device): + self.device = device + self.processor = CLIPSegProcessor.from_pretrained("CIDAS/clipseg-rd64-refined") + self.model = CLIPSegForImageSegmentation.from_pretrained("CIDAS/clipseg-rd64-refined").to(device) + + def inference(self, image_path, text): + threshold = 0.5 + min_area = 0.02 + padding = 20 + original_image = Image.open(image_path) + image = original_image.resize((512, 512)) + inputs = self.processor(text=text, images=image, padding="max_length", return_tensors="pt",).to(self.device) + with torch.no_grad(): + outputs = self.model(**inputs) + mask = torch.sigmoid(outputs[0]).squeeze().cpu().numpy() > threshold + area_ratio = len(np.argwhere(mask)) / (mask.shape[0] * mask.shape[1]) + if area_ratio < min_area: + return None + true_indices = np.argwhere(mask) + mask_array = np.zeros_like(mask, dtype=bool) + for idx in true_indices: + padded_slice = tuple(slice(max(0, i - padding), i + padding + 1) for i in idx) + mask_array[padded_slice] = True + visual_mask = (mask_array * 255).astype(np.uint8) + image_mask = Image.fromarray(visual_mask) + return image_mask.resize(image.size) + +# class ImageEditing: +# def __init__(self, device): +# print("Initializing StableDiffusionInpaint to %s" % device) +# self.device = device +# self.mask_former = MaskFormer(device=self.device) +# # self.inpainting = StableDiffusionInpaintPipeline.from_pretrained("runwayml/stable-diffusion-inpainting",).to(device) + +# def remove_part_of_image(self, input): +# image_path, to_be_removed_txt = input.split(",") +# print(f'remove_part_of_image: to_be_removed {to_be_removed_txt}') +# return self.replace_part_of_image(f"{image_path},{to_be_removed_txt},background") + +# def replace_part_of_image(self, input): +# image_path, to_be_replaced_txt, replace_with_txt = input.split(",") +# print(f'replace_part_of_image: replace_with_txt {replace_with_txt}') +# mask_image = self.mask_former.inference(image_path, to_be_replaced_txt) +# buffered = io.BytesIO() +# mask_image.save(buffered, format="JPEG") +# resp = do_webui_request( +# url=ENDPOINT + "/sdapi/v1/img2img", +# init_images=[readImage(image_path)], +# mask=b64encode(buffered.getvalue()).decode("utf-8"), +# prompt=replace_with_txt, +# ) +# image = Image.open(io.BytesIO(base64.b64decode(resp["images"][0]))) +# updated_image_path = get_new_image_name(image_path, func_name="replace-something") +# updated_image.save(updated_image_path) +# return updated_image_path + +# class Pix2Pix: +# def __init__(self, device): +# print("Initializing Pix2Pix to %s" % device) +# self.device = device +# self.pipe = StableDiffusionInstructPix2PixPipeline.from_pretrained("timbrooks/instruct-pix2pix", torch_dtype=torch.float16, safety_checker=None).to(device) +# self.pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(self.pipe.scheduler.config) + +# def inference(self, inputs): +# """Change style of image.""" +# print("===>Starting Pix2Pix Inference") +# image_path, instruct_text = inputs.split(",")[0], ','.join(inputs.split(',')[1:]) +# original_image = Image.open(image_path) +# image = self.pipe(instruct_text,image=original_image,num_inference_steps=40,image_guidance_scale=1.2,).images[0] +# updated_image_path = get_new_image_name(image_path, func_name="pix2pix") +# image.save(updated_image_path) +# return updated_image_path + + +class T2I: + def __init__(self, device): + print("Initializing T2I to %s" % device) + self.device = device + self.text_refine_tokenizer = AutoTokenizer.from_pretrained("Gustavosta/MagicPrompt-Stable-Diffusion") + self.text_refine_model = AutoModelForCausalLM.from_pretrained("Gustavosta/MagicPrompt-Stable-Diffusion") + self.text_refine_gpt2_pipe = pipeline("text-generation", model=self.text_refine_model, tokenizer=self.text_refine_tokenizer, device=self.device) + + def inference(self, text): + image_filename = os.path.join('image', str(uuid.uuid4())[0:8] + ".png") + refined_text = self.text_refine_gpt2_pipe(text)[0]["generated_text"] + print(f'{text} refined to {refined_text}') + resp = do_webui_request( + url=ENDPOINT + "/sdapi/v1/txt2img", + prompt=refined_text, + ) + image = Image.open(io.BytesIO(base64.b64decode(resp["images"][0]))) + image.save(image_filename) + print(f"Processed T2I.run, text: {text}, image_filename: {image_filename}") + return image_filename + + +class ImageCaptioning: + def __init__(self, device): + print("Initializing ImageCaptioning to %s" % device) + self.device = device + self.processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base") + self.model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base").to(self.device) + + def inference(self, image_path): + inputs = self.processor(Image.open(image_path), return_tensors="pt").to(self.device) + out = self.model.generate(**inputs) + captions = self.processor.decode(out[0], skip_special_tokens=True) + return captions + + +class image2canny: + def inference(self, inputs): + print("===>Starting image2canny Inference") + resp = do_webui_request( + url=DETECTAPI, + controlnet_input_images=[readImage(inputs)], + controlnet_module="segmentation", + ) + updated_image_path = get_new_image_name(inputs, func_name="edge") + image.save(updated_image_path) + return updated_image_path + + +class canny2image: + def inference(self, inputs): + print("===>Starting canny2image Inference") + image_path, instruct_text = inputs.split(",")[0], ','.join(inputs.split(',')[1:]) + resp = do_webui_request( + prompt=instruct_text, + controlnet_input_images=[readImage(image_path)], + controlnet_module="none", + controlnet_model=get_model(pattern='^control_canny.*'), + ) + image = Image.open(io.BytesIO(base64.b64decode(resp["images"][0]))) + updated_image_path = get_new_image_name(image_path, func_name="canny2image") + real_image = Image.fromarray(x_samples[0]) + real_image.save(updated_image_path) + return updated_image_path + + +class image2line: + def inference(self, inputs): + print("===>Starting image2hough Inference") + resp = do_webui_request( + url=DETECTAPI, + controlnet_input_images=[readImage(inputs)], + controlnet_module="mlsd", + ) + updated_image_path = get_new_image_name(inputs, func_name="line-of") + image = Image.open(io.BytesIO(base64.b64decode(resp["images"][0]))) + image.save(updated_image_path) + return updated_image_path + + +class line2image: + def inference(self, inputs): + print("===>Starting line2image Inference") + image_path, instruct_text = inputs.split(",")[0], ','.join(inputs.split(',')[1:]) + resp = do_webui_request( + prompt=instruct_text, + controlnet_input_images=[readImage(image_path)], + controlnet_module="none", + controlnet_model=get_model(pattern='^control_mlsd.*'), + ) + image = Image.open(io.BytesIO(base64.b64decode(resp["images"][0]))) + updated_image_path = get_new_image_name(image_path, func_name="line2image") + real_image = Image.fromarray(x_samples[0]) # default the index0 image + real_image.save(updated_image_path) + return updated_image_path + + +class image2hed: + def inference(self, inputs): + print("===>Starting image2hed Inference") + resp = do_webui_request( + url=DETECTAPI, + controlnet_input_images=[readImage(inputs)], + controlnet_module="hed", + ) + image = Image.open(io.BytesIO(base64.b64decode(resp["images"][0]))) + updated_image_path = get_new_image_name(inputs, func_name="hed-boundary") + image.save(updated_image_path) + return updated_image_path + + +class hed2image: + def inference(self, inputs): + print("===>Starting hed2image Inference") + resp = do_webui_request( + prompt=instruct_text, + controlnet_input_images=[readImage(image_path)], + controlnet_module="none", + controlnet_model=get_model(pattern='^control_hed.*'), + ) + image = Image.open(io.BytesIO(base64.b64decode(resp["images"][0]))) + updated_image_path = get_new_image_name(image_path, func_name="hed2image") + real_image = Image.fromarray(x_samples[0]) # default the index0 image + real_image.save(updated_image_path) + return updated_image_path + + +class image2scribble: + def inference(self, inputs): + print("===>Starting image2scribble Inference") + resp = do_webui_request( + url=DETECTAPI, + controlnet_input_images=[readImage(inputs)], + controlnet_module="scribble", + ) + image = Image.open(io.BytesIO(base64.b64decode(resp["images"][0]))) + updated_image_path = get_new_image_name(inputs, func_name="scribble") + image.save(updated_image_path) + return updated_image_path + + +class scribble2image: + def inference(self, inputs): + print("===>Starting seg2image Inference") + image_path, instruct_text = inputs.split(",")[0], ','.join(inputs.split(',')[1:]) + resp = do_webui_request( + prompt=instruct_text, + controlnet_input_images=[readImage(image_path)], + controlnet_module="none", + controlnet_model=get_model(pattern='^control_scribble.*'), + ) + image = Image.open(io.BytesIO(base64.b64decode(resp["images"][0]))) + updated_image_path = get_new_image_name(image_path, func_name="scribble2image") + real_image = Image.fromarray(x_samples[0]) + real_image.save(updated_image_path) + return updated_image_path + + +class image2pose: + def inference(self, inputs): + print("===>Starting image2pose Inference") + resp = do_webui_request( + url=DETECTAPI, + controlnet_input_images=[readImage(inputs)], + controlnet_module="openpose", + ) + image = Image.open(io.BytesIO(base64.b64decode(resp["images"][0]))) + updated_image_path = get_new_image_name(inputs, func_name="human-pose") + image.save(updated_image_path) + return updated_image_path + + +class pose2image: + def inference(self, inputs): + print("===>Starting pose2image Inference") + image_path, instruct_text = inputs.split(",")[0], ','.join(inputs.split(',')[1:]) + resp = do_webui_request( + prompt=instruct_text, + controlnet_input_images=[readImage(image_path)], + controlnet_module="none", + controlnet_model=get_model(pattern='^control_openpose.*'), + ) + image = Image.open(io.BytesIO(base64.b64decode(resp["images"][0]))) + updated_image_path = get_new_image_name(image_path, func_name="pose2image") + real_image = Image.fromarray(x_samples[0]) # default the index0 image + real_image.save(updated_image_path) + return updated_image_path + + +class image2seg: + def inference(self, inputs): + print("===>Starting image2seg Inference") + resp = do_webui_request( + url=DETECTAPI, + controlnet_input_images=[readImage(inputs)], + controlnet_module="segmentation", + ) + image = Image.open(io.BytesIO(base64.b64decode(resp["images"][0]))) + updated_image_path = get_new_image_name(inputs, func_name="segmentation") + image.save(updated_image_path) + return updated_image_path + + +class seg2image: + def inference(self, inputs): + print("===>Starting seg2image Inference") + image_path, instruct_text = inputs.split(",")[0], ','.join(inputs.split(',')[1:]) + resp = do_webui_request( + prompt=instruct_text, + controlnet_input_images=[readImage(image_path)], + controlnet_module="none", + controlnet_model=get_model(pattern='^control_seg.*'), + ) + image = Image.open(io.BytesIO(base64.b64decode(resp["images"][0]))) + updated_image_path = get_new_image_name(image_path, func_name="segment2image") + real_image = Image.fromarray(x_samples[0]) + real_image.save(updated_image_path) + return updated_image_path + + +class image2depth: + def inference(self, inputs): + print("===>Starting image2depth Inference") + resp = do_webui_request( + url=DETECTAPI, + controlnet_input_images=[readImage(inputs)], + controlnet_module="depth", + ) + image = Image.open(io.BytesIO(base64.b64decode(resp["images"][0]))) + updated_image_path = get_new_image_name(inputs, func_name="depth") + image.save(updated_image_path) + return updated_image_path + + +class depth2image: + def inference(self, inputs): + print("===>Starting depth2image Inference") + image_path, instruct_text = inputs.split(",")[0], ','.join(inputs.split(',')[1:]) + resp = do_webui_request( + prompt=instruct_text, + controlnet_input_images=[readImage(image_path)], + controlnet_module="depth", + controlnet_model=get_model(pattern='^control_depth.*'), + ) + image = Image.open(io.BytesIO(base64.b64decode(resp["images"][0]))) + updated_image_path = get_new_image_name(image_path, func_name="depth2image") + real_image = Image.fromarray(x_samples[0]) # default the index0 image + real_image.save(updated_image_path) + return updated_image_path + + +class image2normal: + def inference(self, inputs): + print("===>Starting image2 normal Inference") + resp = do_webui_request( + url=DETECTAPI, + controlnet_input_images=[readImage(inputs)], + controlnet_module="normal", + ) + image = Image.open(io.BytesIO(base64.b64decode(resp["images"][0]))) + updated_image_path = get_new_image_name(inputs, func_name="normal-map") + image.save(updated_image_path) + return updated_image_path + + +class normal2image: + def inference(self, inputs): + print("===>Starting normal2image Inference") + image_path, instruct_text = inputs.split(",")[0], ','.join(inputs.split(',')[1:]) + resp = do_webui_request( + prompt=instruct_text, + controlnet_input_images=[readImage(image_path)], + controlnet_module="normal", + controlnet_model=get_model(pattern='^control_normal.*'), + ) + image = Image.open(io.BytesIO(base64.b64decode(resp["images"][0]))) + updated_image_path = get_new_image_name(image_path, func_name="normal2image") + real_image = Image.fromarray(x_samples[0]) # default the index0 image + real_image.save(updated_image_path) + return updated_image_path + + +class BLIPVQA: + def __init__(self, device): + print("Initializing BLIP VQA to %s" % device) + self.device = device + self.processor = BlipProcessor.from_pretrained("Salesforce/blip-vqa-base") + self.model = BlipForQuestionAnswering.from_pretrained("Salesforce/blip-vqa-base").to(self.device) + + def get_answer_from_question_and_image(self, inputs): + image_path, question = inputs.split(",") + raw_image = Image.open(image_path).convert('RGB') + print(F'BLIPVQA :question :{question}') + inputs = self.processor(raw_image, question, return_tensors="pt").to(self.device) + out = self.model.generate(**inputs) + answer = self.processor.decode(out[0], skip_special_tokens=True) + return answer + + +class ConversationBot: + def __init__(self): + print("Initializing VisualChatGPT") + # self.edit = ImageEditing(device=device) + self.i2t = ImageCaptioning(device=device) + self.t2i = T2I(device=device) + self.image2canny = image2canny() + self.canny2image = canny2image() + self.image2line = image2line() + self.line2image = line2image() + self.image2hed = image2hed() + self.hed2image = hed2image() + self.image2scribble = image2scribble() + self.scribble2image = scribble2image() + self.image2pose = image2pose() + self.pose2image = pose2image() + self.BLIPVQA = BLIPVQA(device=device) + self.image2seg = image2seg() + self.seg2image = seg2image() + self.image2depth = image2depth() + self.depth2image = depth2image() + self.image2normal = image2normal() + self.normal2image = normal2image() + # self.pix2pix = Pix2Pix(device="cuda:3") + self.memory = ConversationBufferMemory(memory_key="chat_history", output_key='output') + self.tools = [ + Tool(name="Get Photo Description", func=self.i2t.inference, + description="useful when you want to know what is inside the photo. receives image_path as input. " + "The input to this tool should be a string, representing the image_path. "), + Tool(name="Generate Image From User Input Text", func=self.t2i.inference, + description="useful when you want to generate an image from a user input text and save it to a file. like: generate an image of an object or something, or generate an image that includes some objects. " + "The input to this tool should be a string, representing the text used to generate image. "), + # Tool(name="Remove Something From The Photo", func=self.edit.remove_part_of_image, + # description="useful when you want to remove and object or something from the photo from its description or location. " + # "The input to this tool should be a comma seperated string of two, representing the image_path and the object need to be removed. "), + # Tool(name="Replace Something From The Photo", func=self.edit.replace_part_of_image, + # description="useful when you want to replace an object from the object description or location with another object from its description. " + # "The input to this tool should be a comma seperated string of three, representing the image_path, the object to be replaced, the object to be replaced with "), + + # Tool(name="Instruct Image Using Text", func=self.pix2pix.inference, + # description="useful when you want to the style of the image to be like the text. like: make it look like a painting. or make it like a robot. " + # "The input to this tool should be a comma seperated string of two, representing the image_path and the text. "), + Tool(name="Answer Question About The Image", func=self.BLIPVQA.get_answer_from_question_and_image, + description="useful when you need an answer for a question based on an image. like: what is the background color of the last image, how many cats in this figure, what is in this figure. " + "The input to this tool should be a comma seperated string of two, representing the image_path and the question"), + Tool(name="Edge Detection On Image", func=self.image2canny.inference, + description="useful when you want to detect the edge of the image. like: detect the edges of this image, or canny detection on image, or peform edge detection on this image, or detect the canny image of this image. " + "The input to this tool should be a string, representing the image_path"), + Tool(name="Generate Image Condition On Canny Image", func=self.canny2image.inference, + description="useful when you want to generate a new real image from both the user desciption and a canny image. like: generate a real image of a object or something from this canny image, or generate a new real image of a object or something from this edge image. " + "The input to this tool should be a comma seperated string of two, representing the image_path and the user description. "), + Tool(name="Line Detection On Image", func=self.image2line.inference, + description="useful when you want to detect the straight line of the image. like: detect the straight lines of this image, or straight line detection on image, or peform straight line detection on this image, or detect the straight line image of this image. " + "The input to this tool should be a string, representing the image_path"), + Tool(name="Generate Image Condition On Line Image", func=self.line2image.inference, + description="useful when you want to generate a new real image from both the user desciption and a straight line image. like: generate a real image of a object or something from this straight line image, or generate a new real image of a object or something from this straight lines. " + "The input to this tool should be a comma seperated string of two, representing the image_path and the user description. "), + Tool(name="Hed Detection On Image", func=self.image2hed.inference, + description="useful when you want to detect the soft hed boundary of the image. like: detect the soft hed boundary of this image, or hed boundary detection on image, or peform hed boundary detection on this image, or detect soft hed boundary image of this image. " + "The input to this tool should be a string, representing the image_path"), + Tool(name="Generate Image Condition On Soft Hed Boundary Image", func=self.hed2image.inference, + description="useful when you want to generate a new real image from both the user desciption and a soft hed boundary image. like: generate a real image of a object or something from this soft hed boundary image, or generate a new real image of a object or something from this hed boundary. " + "The input to this tool should be a comma seperated string of two, representing the image_path and the user description"), + Tool(name="Segmentation On Image", func=self.image2seg.inference, + description="useful when you want to detect segmentations of the image. like: segment this image, or generate segmentations on this image, or peform segmentation on this image. " + "The input to this tool should be a string, representing the image_path"), + Tool(name="Generate Image Condition On Segmentations", func=self.seg2image.inference, + description="useful when you want to generate a new real image from both the user desciption and segmentations. like: generate a real image of a object or something from this segmentation image, or generate a new real image of a object or something from these segmentations. " + "The input to this tool should be a comma seperated string of two, representing the image_path and the user description"), + Tool(name="Predict Depth On Image", func=self.image2depth.inference, + description="useful when you want to detect depth of the image. like: generate the depth from this image, or detect the depth map on this image, or predict the depth for this image. " + "The input to this tool should be a string, representing the image_path"), + Tool(name="Generate Image Condition On Depth", func=self.depth2image.inference, + description="useful when you want to generate a new real image from both the user desciption and depth image. like: generate a real image of a object or something from this depth image, or generate a new real image of a object or something from the depth map. " + "The input to this tool should be a comma seperated string of two, representing the image_path and the user description"), + Tool(name="Predict Normal Map On Image", func=self.image2normal.inference, + description="useful when you want to detect norm map of the image. like: generate normal map from this image, or predict normal map of this image. " + "The input to this tool should be a string, representing the image_path"), + Tool(name="Generate Image Condition On Normal Map", func=self.normal2image.inference, + description="useful when you want to generate a new real image from both the user desciption and normal map. like: generate a real image of a object or something from this normal map, or generate a new real image of a object or something from the normal map. " + "The input to this tool should be a comma seperated string of two, representing the image_path and the user description"), + Tool(name="Sketch Detection On Image", func=self.image2scribble.inference, + description="useful when you want to generate a scribble of the image. like: generate a scribble of this image, or generate a sketch from this image, detect the sketch from this image. " + "The input to this tool should be a string, representing the image_path"), + Tool(name="Generate Image Condition On Sketch Image", func=self.scribble2image.inference, + description="useful when you want to generate a new real image from both the user desciption and a scribble image or a sketch image. " + "The input to this tool should be a comma seperated string of two, representing the image_path and the user description"), + Tool(name="Pose Detection On Image", func=self.image2pose.inference, + description="useful when you want to detect the human pose of the image. like: generate human poses of this image, or generate a pose image from this image. " + "The input to this tool should be a string, representing the image_path"), + Tool(name="Generate Image Condition On Pose Image", func=self.pose2image.inference, + description="useful when you want to generate a new real image from both the user desciption and a human pose image. like: generate a real image of a human from this human pose image, or generate a new real image of a human from this pose. " + "The input to this tool should be a comma seperated string of two, representing the image_path and the user description")] + + def init_langchain(self, openai_api_key): + self.llm = OpenAI(temperature=0, openai_api_key=openai_api_key) + self.agent = initialize_agent( + self.tools, + self.llm, + agent="conversational-react-description", + verbose=True, + memory=self.memory, + return_intermediate_steps=True, + agent_kwargs={'prefix': VISUAL_CHATGPT_PREFIX, 'format_instructions': VISUAL_CHATGPT_FORMAT_INSTRUCTIONS, 'suffix': VISUAL_CHATGPT_SUFFIX} + ) + + def run_text(self, openai_api_key, text, state): + if not hasattr(self, "agent"): + self.init_langchain(openai_api_key) + print("===============Running run_text =============") + print("Inputs:", text, state) + print("======>Previous memory:\n %s" % self.agent.memory) + self.agent.memory.buffer = cut_dialogue_history(self.agent.memory.buffer, keep_last_n_words=500) + res = self.agent({"input": text}) + print("======>Current memory:\n %s" % self.agent.memory) + response = re.sub('(image/\S*png)', lambda m: f'![](/file={m.group(0)})*{m.group(0)}*', res['output']) + state = state + [(text, response)] + print("Outputs:", state) + return state, state + + def run_image(self, openai_api_key, image, state, txt): + if not hasattr(self, "agent"): + self.init_langchain(openai_api_key) + print("===============Running run_image =============") + print("Inputs:", image, state) + print("======>Previous memory:\n %s" % self.agent.memory) + image_filename = os.path.join('image', str(uuid.uuid4())[0:8] + ".png") + print("======>Auto Resize Image...") + img = Image.open(image.name) + width, height = img.size + ratio = min(512 / width, 512 / height) + width_new, height_new = (round(width * ratio), round(height * ratio)) + img = img.resize((width_new, height_new)) + img = img.convert('RGB') + img.save(image_filename, "PNG") + print(f"Resize image form {width}x{height} to {width_new}x{height_new}") + description = self.i2t.inference(image_filename) + Human_prompt = "\nHuman: provide a figure named {}. The description is: {}. This information helps you to understand this image, but you should use tools to finish following tasks, " \ + "rather than directly imagine from my description. If you understand, say \"Received\". \n".format(image_filename, description) + AI_prompt = "Received. " + self.agent.memory.buffer = self.agent.memory.buffer + Human_prompt + 'AI: ' + AI_prompt + print("======>Current memory:\n %s" % self.agent.memory) + state = state + [(f"![](/file={image_filename})*{image_filename}*", AI_prompt)] + print("Outputs:", state) + return state, state, txt + ' ' + image_filename + ' ' + + +if __name__ == '__main__': + os.makedirs("image/", exist_ok=True) + bot = ConversationBot() + with gr.Blocks(css="#chatbot .overflow-y-auto{height:500px}") as demo: + openai_api_key = gr.Textbox(type="password", label="Enter your OpenAI API key here") + chatbot = gr.Chatbot(elem_id="chatbot", label="Visual ChatGPT") + state = gr.State([]) + with gr.Row(): + with gr.Column(scale=0.7): + txt = gr.Textbox(show_label=False, placeholder="Enter text and press enter, or upload an image").style(container=False) + with gr.Column(scale=0.15, min_width=0): + clear = gr.Button("Clear️") + with gr.Column(scale=0.15, min_width=0): + btn = gr.UploadButton("Upload", file_types=["image"]) + + txt.submit(bot.run_text, [openai_api_key, txt, state], [chatbot, state]) + txt.submit(lambda: "", None, txt) + btn.upload(bot.run_image, [openai_api_key, btn, state, txt], [chatbot, state, txt]) + clear.click(bot.memory.clear) + clear.click(lambda: [], None, chatbot) + clear.click(lambda: [], None, state) + + + demo.launch(server_name="0.0.0.0", server_port=7864) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/example/inpaint_example/1girl.png b/extensions-builtin/sd_forge_controlnet/example/inpaint_example/1girl.png new file mode 100644 index 0000000000000000000000000000000000000000..d825e716be9b40ddcce6987fdd8aab7d1e6871a0 GIT binary patch literal 493039 zcmZsCby!=^@^^v;4=!zKa4E%I0|Y6>2~di=ySqcM;;s$uEfgv4Qlu>uE5)I>yT5$z zy+3=N_ph9to%zhp&g?lmvzsVYWjQ=-Dr^7%fcHiorVaq0JUyZUK>z$K*vnHsH7?v_ z-nls$yBOP>yP3PV0z~Z`U5th8OzjQ-c`$S}>XW9tj(U<-2dXRcXzY4dt&$>ikpkEgTwz|JTd&!4Y4wI zFndzU?BwX^V&@Gpb20XG_&4#tu}$pUU0l4Mcub7VAjS^HZjSc<;QU+BKeVU0baHfY zvvzcF{cj<2uP22NJ8OHBf6$*sXAW_D(gop$I9NM5***E^zpZ&P+|}B_5@PIP|G%jJ z0Wi1xUo;DM*QX&{JTX57#S;KO7boAp%yn~ggxDK9c>n+U+#O8q%#B?j=HCBH=|98% zkLmxV{y(s6kbi47v$nK$dm6gM(?mU~`bW(_LMD!8PgCLKZenfv1YqsL2C=j=c6hSU z+}PFI;Xl#E_P_0Qv;N1~4wi;y=H^cS#bM~dWhlV+Aj&&s3y zzbh4DY;0~~!Oz3bX(3=n%LdVU^4?Rh2tz!cT*%J(nn!^9wWXl3F&~!&zo7P@%q{>3 z0K9=o!o70B?zNlDhus;Ym54u&@(-2>Y~YDP6VN1ywk!m)o6ep1&XAowl^-9GTtyDn zTaph34K#CYZV*tAQ@9lAx9qAj@4GpNOoY%m*rGbOpa>QIci4V9n)Gk>(%s)!%B#-% zrAJHS(6EAvpdb)v1rrFD1j78TEd3}+fdE1hFn|!Nyry!(Y0@LRgm9CD6hJ5m1VFj` zMfAPy4$o*ILHM3hKlZ<~08j?vO&-!pI4b_m80`w6X#z+Iw`bxm@qq~mQ3x!=i2$5l zkJFEm%iuk*XARmGQxYh4iMtZG_8>jli9a@OKej4%<3nkxKo*X8|m+U|{0Q}fLUpXYut zWio@g+d|9!e1~o8VxeHEvZf@w50yEZ;9gNN{4*Px@-0K}1nIuipE;!enWXPUQM>4A z2a^U#y^s_EN{wzM=ox?`S~fBK6~NefDyA79k%*&9p_?*IX0DUO6&=>di-!F>%B?!R zaXY(YiLG^`$31ST3g<*I#NApUZ~tJd_T`>o=fjS6XItRzO-a>E>1KL--a(LvXhvrH z{lIaFbMz=;FIcnt6*gzdZ~>Kt(R}dw%Xrc!908JAddVWEJ zxSpH7AM(JiPm2hvjBD(m;~iF__k`L+0Ei6=uO?XaQ16P27Q+bSS!nzfPkZ2tV$Uat z@m@`H7Vn?8Yo##sc2)?OsE`(^-S5SMq6$^TDvU%@O^XJj6qHr4Qj#5_^3#S}7*RPX zI)xyK*ePDpuF^4sBKUAXD5+j_W~LmtUFoG-ISvR}8Hhf!AAsf$#EmXENn6VZfT8|t zmXwMk6wr&-kEp`xkVWL(QV{Zuj~HQ`Nc7N;#W%#+7g{4iy+NJaALUFX;hJE1QlQ|f z?x!H=d^H85{azX(hbne?8aqbGYaC_8srYCUw7z!s=K+7cIJq+mm*?+NEzB3 zX9J7TmmGt4I!Yx*oPr;-Wq?>R;j7Z&nqkAZw8c~NuLS!I%1QM-YpicZrhM9MS}Yd$ zcWZWkyE83bRyLgJcN&ChEV(bk;JMnGydXdoiU9xyNFc%E3JSVZoog4V?Kq07r8W>_ zvoTey&U=mw(uPSg0Sx4&$+?gy$&x1M=YZ;rjfvd6JP(zF+j`4|{?BgDoL`fLyG(fk zmW%c2f_!FbbF@tu36{;I%P?}wm{b8w1+OoL@XIhAX5X8c+F9ad^<)kI`o-}5Yl^bp zVew(>IA8X|$wYPfy$yPtu0hUAF`ekgJWM{m#3&;p^{9z822z z=f6{RXFN+Z%i9MRSpfC4z%mo44qUZ3NYI!aK`Z%X1rfz3!%uX~9c0kQKq0G6O2VVZ zL`8ALth5CfhM?Z8c%7JKr5g_8Fr)D9IQqYnB#tnCnDNRaI3uDF-JkVCTkkgF=m|^t zqKwLm4*iAJ@e!5TfKgP!9Hz35JNaId5X>?+^5aJIlsJ@%txCaX#|jVSg(j@W&0oe0 zz5A*N21EXgeiarko2(dCK&4xX-S-nl6oP{MdGsl|d%Z6P1Yl?_DWi&Ijxe6FT2R{h z{NoUh`@!*{H!vB%nyJA=L}-v0v|bT4I4D;fq#_UMf|;vP_4?27E4^CPV6xEaz;l}S zYC@0tZd`$4AmDDLHjtlmQ`9Ggw|VMswkT_&Xc(DtS8AogI9*;P6Bibi zSW{0Po8ldAHrk7|h+neEqsCw7@(w!p9cu8<&JQ=z1aMx{nbKu-2mBHoZRAuj{IgSK zB({bqHP3p{+-4`cPmUhBg?JzAKB=GgS~)(RLs?miX>flPsbAyQ>TFLp-dci*=8PS- zoND)RD2UlE9Gf$(8lBbe2r5GnCoH2zc9=cl&`v*Pqcv80KrT?D@4Fq|{!F`aJ2pJ$ z60$?u4n12>00a?|g21;W5`lL|XDj3*YnF8_Thk-*1K=OOx-f#FK4uU`_Gptvxkk3# z7S;-6O+`p12mtzWxhfV$`K!uz$K(NMM=9z2e#4>w1z@lG+Uqvy zTvQg%R}~yKINn%bRq)Pdc6x0dy;{myYJ2VPdA82gbblTinr_(Q+$x=bAvz~}()7IxxV#6D!7a*wsJk`ES z``sI58N%SGVNRI=urEJX39m%x+bjo(f(r4@8cs2Ip8xe%5+c0lJFx~II|AO8=!|A8 z21j6_NY?Xq#Z+3;7^V$DsD-r**~t#NyHR~sS znXA3SK;JBKUG3vP zOHy}dYC*yEecC6t)=Jw}9fL9DWeBSiX;R2mlkp0p@E~aN|Aj_|C@S2+x%Q{U%!?P&%>i|-CF-$5jUrXQ)mP*ECKGzc@O*Zhn$q9^UsZ9dtYtYj+$kWCx!8-8kML&%ghB>M1_El)n^k zeDRi}oilUHuU3B(=8xQZ!-dr;cMzR5M1CSOWz9`7+6f>GdBBN2!YRws{x&_14{ z!=mZ(XsgwR=#@;&I$_z;Askp3XE-+i*mYa9UCvrYc_|{b)jxFS#(9WUxhBn&6TH;o z$$fC_Ti&Yv+}UacR8!}aFN;$c7k;;B#0P-5o>UL>F}qSKHst}5)#z~foq1)TG)lSE zl^?Q1nCXultnuyn=+6-mjgIF(9Q9q>mUTUyeY+c`VWwhE{8DuCH zA_mG@LyeX4hXcl)jDe~~%!-@m$DvI5osWx!1dAepUbTj=2~)os@ycUhMd76qvol$} zWoLS)__a)lkEMdjUeeB9XLk5YhL)y2+*}9VZ>B!VSW-1wv|PcNY8kp?tHZ(ZauUKY^3{#yACw z6!y!uv8W0S)YXTcY91^y>0p?%RdW865>yF{^!t3))6e4|v)mksiE(J(5s340Q_ek% zW6)Ky)UI;W>R4#*a35>Q83z|RPJa(L&9*%3l<4$7Ev~)q-d%bS_X>PiUTa$Nf800h zaNR#zF6QWT-aL4XzAK`pNg!o>Fu+${_%%&lV?Y6v%o78ON;AejjV)DrPjLO6B4xyl zoKUKb%Q<{~k#SbpDX5U8w0lsgNH9CKI}t#l`HkppPKsJ7B-Z#%^v)w-549{_lQfo} zEefb(h%FccphAC+MuLu}yc2k1!<(FWsc=Q1W@e1N2DO#_A_~r$;s&6Z(P9%xd_*YV z-XSlE&IW$DOCFd0cotN~O7{kpX6w}Y3nxslZtAV)^sn%!I96sKu#^@wIYB}JOK3uX z|7VsElzNARTrHd;5)gj(b(WT5rRf9XjMqV&-o)$a&!mn+D1{*ZDRid=QArUA-u2s^SL=(nj`t_Wa)%9;Opv_H zZ^J1{=&@Z4pEpcw7=7VmUCN4LTr&OU#?c|MG)88om3380T;UX#MGCt{1sVl zvG^+F>(VAJqMMWZnnQW+o$ja-AI}u7efdxqMl4?=f3o#cYEfz~lu0H-)6V`uMSteD z#68>Gv+-<`T;s5obYO23p;JE|LqSi5xGw?f;RbQ-$;^_Sj~?h}dyd!g-&-uOlkc9J zGzhlq8R*rdX9u)it`jm4q#apDLlj|q(b1$3q z6l-kyc5c)q$cjVoyi-&dFzQW6AHc0qkryQB{6emVe9LCF*qPGCCx~9wrpKNl<6RgT zI;l*wy6+B_JTq2r=hLR`L9gH@y1<%ql1QO408Nh>m`aIx3NA1s5r5vo{JZf-E4bS6 z?>iI&`h=UR!$>&@{cuhkh_Jm3gqvs#JI1bneRRYEpas#eD02xZXoi7hlHSBz5T>Z2 zDTa*oZ6!~QMW@5)Bl`p+<=~o9-L9#4H=!ga%fdu0- z!4AfrBTj2@qy(}fDk{k=Ctkyq1P&NFz4!j5VrzO^^RtIQpzk<)JE~p{H;}~&U=*t^ z!N8xF=m$Hj{~4r4VqwO4iaS~m@4aHnj~k`Eon}hrW{MuC5W@P5piWRX@L^@}Wyk&W zq>99LdU{vifVx^T7ibTCn4~ddZaXjYxf5Tpj}4QEURobU1{j=)m6#Fq=D9uDeg8?$ z?*?=l{*q5-Ak}_U8r>LoYbBu7PE3r4dj}Bsw+AQ6%cTc~0la>V zc73w@8Z2(`_wTO_B6{ONYQvmlLt4=xIJzXM<(o3bamH>nI*y>kSrT_F_wv(W3+~H% zAJlOmAPIVsB@HDFb*+X_17Ngah*R{BsAuh{GT^cbWW~tvc-5|-Z>izyX>vJo^6$z5 zmNS;_ZkX5_qlZKt{XLEy*9BnR_agH6==Z+*x z4>$F4@rO&TfrpbE9t0N#KKC1yGqs;wK*>^#JJ9GX6Tzq-xZLcl6}XHNF3l-CJdB0_ zqK%A112LD;WZa~-XydQt7+k1pvA<^B%e+5Y=S1qhWiwZi1>jhbk=xu^p6E^LukOe| zds0wHvP3B|tT5rEGKoYn44|4YW_cTFl+Psf{gO!^zWITBro23K-NK;h zGZqt&jp#b+n=H$N@Mn1ZA~-^dB&V$)sR2u)B~I)#b6;}ulpwUQ z_%3AcPIQSTgZZ(kjp*N4R=}YQUzc)S2?zox>K-CW3>i?g>e{jZ%MZD!6V^hzes+Y# zenO;7XLOzU5+)W<1#6>gN-2o6W4Oi!;TrXT%S=GTbOrdQu*u%-ckv@aJ#>-`UVJP& zUu4n;f2)k=zcf~EmZQC5!RF$XOl~EUmpl{W+%PKkj?p#5?v3bO##I#N*Odw8jNAW_ z*R4h0rc#d|F;6ednbEv*>%BBshMAIwdMH1JIYtul0?$xhDBsx`jesF*B5{~j>jgzvyh7aenDOI7-FRU(bBu8Ii7U<=HZ z=W#xAw1BO4gb%Y_uuSzrMHM!OpZ8fpIXc|LMIGw9eKXJ$cldr=q;~7~c<$ok`Ejqq zY`w~d4cK~7R4zm z>T?8&V=-)`#-Z==;@hH62xEW3U{)dpz1d7=*+IHqk9Xcg)ih`bg0Cej zow0caXrTqI8{<~;N?NLK=xFHjUUjcYa)tq(ju6z^g;jfFS?K|v`P5!Xp`e|h+RzeG z@|V$qlu3XYSm2PKI1`kF)>d!fISHD_-yhcu%aF3CqGygKx#g~fPNX^#j1H9IuvksC zx|N#UmJ-r)PKw8)21$Ltaex`cSOJ1=Jx-{B?j3b-2|i7c+Xm2!kjDH~(MM2hm#6+r zE455iLPp|A4yD=IQJbJwO=o|R-1o$giSBd+z616UE(U$6mK-Kybz0wavgw<|p0^|> za90PJof}@1uS@D>wAUofQxmTbS@C30P~?#`gcL2Jt$vT`hwZ16`TC;XQb9(bIdwG@ zN=-FRJ>_q6e-tg={nAq!$wfs|FaDGdN`xk60021}=*MLM_-qCL)R&y^BX#V%QJGwt zv7<(+!Ch2;GEdw}E3nydDW$Z8#pdspnGD+=kLOBA&FUEH`9ik*mK^yz_JhK}KRH1V zR+^Y3gvKE{z$&EW$RAZ94eyg?6Z1~gYum=~B|VQy^CiAn{)wuF`Jg3LH6qnR5va60 zOjf4i_c%eVf$z%rV)wzy)P3*5_2PjUfB6su;#0dA6~9NsS!4r_DBhCER_Zi3x33)k z2vP0!7~dbTpAKlS^F92`IMaG6mmV`YGWJxd#@U})*qLa;Ir;#GQ*A$6vg^B?_%bdc z$-Fz9DqzrgdXilmuy1?1aI&|ZT!?vjJLPkDbG|F!s9d5!0w(=o>}X11rMN3kd&Tf2 zGI)C39a6FAtqF)es-S72fBgxhloEtWSDRk6Y=p2O#B&7$>0M6uSWsDM)P8?|UYkvl zm$34UFcG6kO6o&J{Kt1Dt58oh$)CZ3o3{f(glI;@YT22bSRz?7{AKb(hbRC}Nj()M z5QyXs0*6ZB6BL6Hj$US)qR`pTqyoB}M0Bh{1SrS~R*I4ht8f(z`$N-s&Y z=+>%)4AeACfh2?!FD)WK(Qb}H3VlE4uq{Zc+YHwiaOjUAhz5(Egp%rzK1M!XrE|@N zamLV;6C*nrkOe5i7;)F;T?C9(-;(f}>=S~}knhsp$#Sz{2@d`t;faVBvV~Xm_$k%% z%!5a%gJdyH5X9?Pd0gZXQI$Kb9hd&`6$ts!U}v*Q^4xLe1@i=I`Ny*B?ONR4xn~ov zr));!llt-%-`=R+m}bOtW54PTP%JT(cMJHiRjRepwH*;jaTRc+4wjSz1Yu>8rDrd- z-7mI2-mOjE#*_TYNSZA$hG6S%jhVe4z3{3t-4UAqHvYGyDh$`_^Hgjcux{sl)8bX5 zr#+@kik({Od0V5qFM@lk zkvdlH$PZbZzMUGkFNJQHanEywpCjySMdpBLO$O(?F;o3tZM89O>V9n(<&Bj_&eR%o z25j7%FWk4k&`s5}4$UY>w!32gv?m}#o_6ftS?p`YbnL6CM!!*;wrJmrSLV+p*QM3^ zBJ7yHIpR=nkemB;OufausUyXsumg3g*s;H%Lnr2t@RtzBGMan9?cb({WyAKfZ`mRu z^;7-B_Z;FL*<*{{4cQzWs-&r2FUzG%9#Ox)2`nAbEh`OTNn$NnjFIVeyXx<%mB4n zqqon+toGXx(Yx(s+&pT()A`41r3=^?`WMX9LPHcIG^PWu9AX>5F1SCCAwF+f8B~c) zwSjznBvOOkgpuMZDN`{%U<~}@Sp$>Hh%^dY5X9}X_L4}xKTyieAmL{LS6JVc=KQ#~ znk*Y0aWXL>=mj&j%`kYNpoTRG`{6q93Mc#%2TJHXaUl(IM-8$`)-9?s^VM7 z+>^(fs?ksrN-}!Ls^!_-`YJK^sD`}qasYELlz2=yB{Gi*`~=0MY^qDLWhGT_I$RfJ zP@%)9@&dE(!Khv~)NO)Ek0Am)30I@)6J*`9y2BGv3T<;c!?Vk0kR-Pm$X=u`(ciat z9sOE^_?=9c_6dkaDx3lZM8wSQ-(F7%|J(e)oAt@~AFs&KlW0t!bl6b4r`MWCS(dum z{PqVHTYiT3F;>IxpsKY2?MdS?g1<1nRm$j-iJba~vnaqzA*vLw@wAGMt$fs2t$YN5 zwd7Clvt*f8>y{Cv)@>XoUt-~AasRcA``yTT7w$QltNZ}(i{bXSngBBZFtq23c>7*9 zACc;xa_A6l!QwfsK}x@UlH+RiMu6*Aot$BdsQaWCs@aU~bDPZq;byf11L^aMp*~m$ z3@TcsP72%lJ+^a3Va_mCr_Xj1N7wBQyw$$AsCn_n=XhsoR~x@}PnnUF5c*s2@8p3B z`Z01>)AOrcww5S`u8UAT)8@hYu*;-~h%x&o{p*0WHrMPa0$j!lch%XdcmK`b5b40j{BQ{pi_*Vf&woNC7#~Uc;xkv@t4DEEsZhjZ81|A=0syWR5UoI)Fujo& z0wx~RAK8Jokw+)QR4l`ShlsdnX}zY#qk<@qNt9B!K|>$8;u?g`xafP;}#7Z z5`v(?r$0awb%wn*K}Eb!|4K2?r_(x}+E(g@%SDme_v4kJ_rqrDmkM!_25-7__H+F75f>-$+LpE^@66z7X=bvM71U4Gl{KKuQ)|A3TL!31Ik zqlFSe!KyUUc6h{urcf~LQH^D$5Z>=3^To) zF6p>E8PRsoW1vYb1KL_FMycb;5G55+mlP3H%03+mxX^Plc435Lnht;N4yJzHkGq!W z0-Zpi1=HE!r=ys)5cd^8dqan@qU|R9Bh?9MSq)@Tv4Au!09Mczu*>xpI0`jrODKO%Qfl}nUFQ53>3u-5Xb?Ov>@r$N$D3qsyh z;G;yV=%x^YhB;A!h_PhRPWMBSq^%M&%Cwh!H36aUEGqy>w-6yI@Jm>PJOthkMeCRN zPNbUfg{Xe2N`jdggTt5N*Cr<-ssc%0Vg=|c1*?(><=xuc7~J_MX!YR6iUJ0-<@a>y zDhCwti2@vy+MlaL^D6g=Y)Ya*bFY@o2x-)gY$I7(UcA40{UM(>dtG%fojY5_1I9yT z+K8I@C7#u$uhl|2wKkc}DX%?|&uG!_>iKfKLGTw>zWyjeh`l=Q_)F}qNhYSJD+0Ao zDVXkkKROo?=WIwbT4PW|GiNf3iUmAHPx))boEEey8nVp)wzC8342ob9@d!{oH2iE1 zL<3=j`^7^;Frw5n)t+k%MgS3suRMGk#&Lr@*=F5rs`guIw(m_g@^blJNgA6rFZVzw zHO)g$7qC$IvZuW_Wl%P41mdo!O+HJ(H{s8@&Uf8AMGw-y-)uT8hq_pH zRxws|4Sk%kGtML=)I|1GB8P^!#L*}|sq|5pr8u^!`)`gUPhpIw?{8cC`W>i@-yILn z%}pkcjBJ>E2oA$lM zzQFE>sZ<`_u?mx?8o;?fhkY$8_C#&k{S8t#?>xqIM(->}!&x8H1WsXc&Odb{y5B3IyjhY<8r%^UV5%51AW7Vj=_0d5$!#J-p7QN2#9HESni!b z0!EPq&(X4B*RE~Kr)@J_mmoMtO>?zQEp`wJO(k|=JL^vxwA0uv5K47VyqrLp6gF!IDrAh)~Lgm@5fmNaLm3_LmHQHvQNziku*Wsi^1> znhGQkOt9>WMQGO>Chdj}Mti(_+Tnh_c%dd6Ga7t4Y3+i-J-(iZ4q&VriAMac*-yp< zSl3T9lbr#yDG6wlQ(lXJ6KoT@c!K2@O_J)9fe5jROl(J`_vecuhux8N-L%L#0Io>! zU<@SjUagET{sauBzNTEu@btjoY~pVcdKRKq+c)@K`&rJj7fzy;P(d5$o~&YTn!z9# z{cX2c%DXQ*lIYv3F6S$)hn<&`hPmPoC@?8ltbKSRib+w@Zf1EYeAP07?jwaa5;uF|aPyH?OvkiGHjdq&2Kg7>;PDr0sb5m(>X7kdhChQqt{? z{5=cse4wvIS~gY4@Zk*!M`O3BlGJ46#CTX9 z8=f&>1vQi<#M%2aH=k|d2uawFbNs%IAI}pP5)&8hv=T-yv#AgCe^|xQK3o)U3vd^& z#H&wISQ6S@LAvLQTIW5#9q4wMW9Q(n*?oteX=lIR=hEHbOiMJ2tVnm5;$WYT(dZO+ zt>jr^^KZiT3H8kNd~vmSS^a5m!GERo@#1^OSwpQy&EwsqiZ=Pku7HC}p%uFj@Hi(QKilyLxZCrJ~+@^u&Ys*6Q^9#2L08FbGwl&0Q%;i!I6vgCI z2u>hEkAEZ19TYsUhf6C3Jf~gsR)xYWXnS+gN(hcezQofAzR-DtuSx+AWTG;4_z3$% zqoh*_9F+2LDmo&B{K*wM_3xT>iaqTxfD5evXc zPM}dxIc`u?%-bsC^bTI?I^b?$8v?5;f+UPPo_n&i~&#oo%_GahRWJGFy957X;A>E&f}@3%#hB;nj?xTX8d??}Sa+0W`KA{MUH zeyO66pc8V?;MK9?0HA8@DS(f*3RAkie{aMuJQ+9BFB&*BW6q~6<+3B?vVG%!Gks@2 zSTJ0AJUh+Z`57lt-|DF6y&e7vvz5kCz3?{5?0 zRNt#ZKp*+_-0JD}k+{^|)#O;Mku>MflA@2xfnmRm&((Pm((iGhs$o*8QC@gbXbD$= zG&IuX)b7m8uPQ!6+~5`%frh^Zam|LDs1A#1_(;H9zrLsv0!eENx};whNapm)Qv+$Z z{NgqQ>J+H=`pcGO$js`bg>V(gD?1enU5U3WP)yS_*;jsm-;kJrUUm{! z7Ddcr;(xuE)21+FcqKRo$Bhtne4KP{>K{}h#sg~XNaI@KC28LgCsM?TCSvesE5tKPXWnZqR%Js^U=L-W> zj2>+w_Sx>+Cec)jxDbyz4FhjyAFr8Fj|312SM#D`G;N3#!j3Rs@3W^>X6L!jd1|)I zVQLgsU+e6IYFH}rG^7d|t$a0CaXWQ?u^o!hM+f0%4!&F@C>QUN*GsXZfFb1d2+#n( z4D#$gEKXm9jr#dqO{{-=b-sf0j-+DNo5A*HSP=&<}^$v;9RInlWvYe6KpA)XlVL=!#g-U+VA4j@cBO{6@gcnhL5?9-whro zEHA|$mS-Fnyf>y^Y1c{~0zvX?&Zxal5zNFQL`MwP#AlvRrB9vg(5CqyDJ~l20K!b{6Qd?0G zi&mDz&u)bawc<#Uq{C*K!-=tq4okoT6d6aoR_Y^xYC<^)Y#9NR_Ms-^Hc~Jv>Wnap zHs24tj~CA=I}>sy%w!8Y2|1m4hk56BKC>4VzQW7{`^n05E+mLf4QQC3o&Q{pf0o@N zxK^gTwSzX|9k5xwT~5r2qXkY1*GP9P7b(Dc*Khot^ZFUdfdjGM292*Hv`Je;`Oe^{-hk2J(84A_j zzprC)4BX~}c(qPzrt#E&4^0*ec-|kC3NRX$Wlhby(wY@1aHKtu__|?__&}qpNJFg{fiT49& z_T-@9)xODE%k(Afv%`73^ava}la?_;2amBk01jWQyjev{&c0jyf`|8F_4tj)8%>?* z(~CR!@6_WqQJuT>&b#wo0*Sln&g&+}j++fj6>7hWVc+bHjTny33gxCoJSGn;1Q8A$ zZnkw2{Kb$1>>y#C=upguI2wa3g`9@93@{a_u z7QuRPCc@Lk=*+R_mPS*OC`67uV?9pQN96Nr$}H5P{vK{7}oQRY|Ka^<;D`P{UAjWT(X515L z7>f3v*W;W!*%2twHekK*NW|e7Dj_00R`?AeSqv}YfVnB!QNUk-xauzpP^#tC>dq9Z zMoFZqGAQvwJn@B9-a{%B{=6tAinq?xZnkzt9|a_Td-tp4w1AuAF8v^De&$lekd;Fj z|7Adc-{V7Je89zlT<62y?@CX{POq7#oiCKvf1cP|mr^6$h(efj^R5I4kfM<`_n#E7 zZ)ziH0uq_Nh0}AMACPLKlvK_4%RCX!Ho9M1r#m#Hcx>DrEJo(Pd~t8sahxmhaB=wf zuz2twm+#lCLLR8pk>-iZyM0oRMhHGcT2F8sQUt4Lo&||IECfKk}X|G#NH9oGz zI8x@CQB6=U@p=+_V!KA5)ZzLz(rr>mUUcC_C{w-CpDS245e&H$n=GJQ*6vUc-= z0~4|u?~erX?^ZD%-Oh$Fkv)w_WFNAmuB3w7d@PwID_Uvgc3eQIQ}j5dG`8zJ!2P_~ zWwR#tC7Dbdzz!FPLP@Ab2s<(OVI)>Plty!APSMP{7zJpq@jb3-_ig`SU@CORTjt$S zOl<_+Asy!*7jxb52`!*mKzXB?)AxmY^SPVCXo(pdpRD;yVcVsXEfqn%e~uNdij zAz={!mR~ZGtfZy6IvytK)(39hjawdyd0q7=)} zIv+m7)wX?gy=Sy{tA2K_-*k|G7_K0+rL3$w%oVKNspj(V{B6jN29p^UV#k^JQeedN z^w)urVFQtND>BO(U1=^Jk8k%ShB=oDKK_jl+kv++mhmqGE)DOu1v;-WI|Cl8FP}a= z9D%2vapk$EVIT2%74ZqX6a$d zkWoBI=>pAABMR78V}0}hDnpvH)8F+)S^#zK4|-;2fA$%|yL6D)ui(fLsT zyQ9Lsl*URG(44;I3QZ3Q$$HKYmGA6keoKM+j`3?C#j24b-M%IEqN>Lu(KH^fA6g|U zDK*+1*M;pLnOu@9#k|Rxq>Hp!(>w;@lOS3%rgBCH)U+Wq*|Fyi)oZu(yD8Zc1%YSL zN!pTO)1kYKI{&jvwODAV>HsbgdW7_X9*1P7`s|enz0he0 z(krzF=Q}IwRMD4WbW>P+w7PNZXXv`mwy&In>!pGi!=hFGwoX}>43}_{n1U8Ple&gb z!!A>G7%4mJj{jj_D>eOIo*d+0-axXlf;&P69igbk{H&5kbK;$-n4&ofX{e+p9bT;z z^WV3C9a3OF(X9HSUvYrP&+74Mx3Lr%|2wzIhLBjmP*sG|d{nxF0cr9znoKa?v_mwt zzi3bceY@D&BnG^I!2%VcO2W$$LA$8sB&5d!LRr_NODE?_N!{CTat+V&cUANRe&()n1)p{@y?eM0=uuW%Opk(Nca z@$8YwMLxUIeuM7a@Od_P%lAd^+pV9Wj`zp;e!HHX{*U!fQJMTQV8gakWI$!qPCsi8ge#O;Yi%%Pfy5>kJ)earm5rF; z)Cw{$CZEEcwxiq%boSy$)M=u9NjylvWC*@Nq&Zxp_Wt>y$e84kyQolyf$RJi&FN>Z z{5;tBtZ;iQ?4X;Z^vOjDnHG#6T3)VJN0bZNI3ygMh^i2CXSyp!{xq5GNZQ~~%H{FM zo7hOEiWn9&t9nT`dbECgv;Dadch?9+!bj4zvrzhS;dXB6ajiFg5tTrXa-GOd#@zg` zNdKZZDe+&0U$_0Rcn@g*~)zIL^s^}yTjtXiITQMO6U#1e? zAf!PX`KG8hjf|S=;SUt9H-|aS%+b$xJ2+{WZwwF_xH4p{#@&?-7>UB0qzM_RsxpZ~ z=g|?^Be%rDVi5u8w+xT9Pgg;0@i@%`t*?u|Etk7tiVdlZeLpM@%Y|6nLK{;mA2&g?QOP=u zaCKU|1+ z5o$*~%xM>g%GgJcn`mT^+<@n)@)%QsBcqwg!A^d7x3_QjxK$csNk9mE8)H?#>?Qo_ zvNoe#jGGkutTN_c{WIG*Nncjac&#?3XXV1PcW^sg3REjXUTU;$AH{2>ReyOT=4aZD z-QN{#b7W&kO%DI1CVOqdb|2q50ftR~;|xl?LG_uB@tL3C??k*>j?+gTOcun&_QgAz zbo8sf($mWT%ud?LnbKabP(cqkk$K(oyZoJC3`R7pjTmpK02u>%m{pb)^ts@sA(vB5gp6WO#Q z&$c_LIQ5WC)L$vXvPQ3GFX6V5{|}x(VZYC>=t@qs2U8)!4G1HMo6L|3EWx{ znK_r!5mith9E&9Ms;GyMT#%*z2*;|F?wfS5xXl{UUojG`0O3ISczX$7vLyc$sM4XNA8Xsx|eVE$v+wMTX zP#qkBf%$H;{L%G>*%OT>rrryNJ(sPH;iZ_`fm;vpoTU%r1`wm~iEt~X(yxJQNb)!% zAS0wS2uNHVQ^ni#Eb$BJHBA$Hn^lc^e;`kTmpxeKtsw}L!mB>~{Nc}k^pnqj^>({j z5Hp$*$WT$1hgXZkt7g83Wct;zdG^SiJtg0xt?cZ2v2&x?xmiqR##$J^{|P-9B~K_Wt<-g{Y#QxI)^*P|m;=Tr&Hg5JEd^X)gL(+Ub=K~f|Y&j4(wWKxB; zmk$>D{uB54W4GG4=3>2Ct=q0aBwKRG&ol^1SeKO{CJu>x>YVf5g>*e40ub>i0wRir zi7^zuLI71^VnkMOAv4YvMpVR02&n}Is$Ly{DzpKndic@1tFxv3`t|;^^X_VC-?+W= z$$PjqRF$c#$>Hr{dbmD$vN=DJZq3!4i^{DoyepdX%fJ1<|6gDGz2E=lcfR}Z ziw{BZ%H6wt=KugxT4w^&xEm;-F-BB*j(WvuI&y=vyNr3ZhgqG%Z$Xzq0wfGdOH6@5 zP{`-D1Xzsq5#!QUfOK?G%FW0I1p!msBA^gQmqJNNC4wy?F$K0v;zcxxSSo|IrP(i0 zNd^XE>1GWlat27@xF0&Q*?7DdB?^eiD8)kvMhr8we)uoDM-YvIC?RRsX_-)DD3%bP zF*+rgc50$Qq0f{cQU7c^a~dc<2PrVT9;~}2VjXUrjeP23$-Y>2>R=oF^W4}*u897l zNa*m5tr!#xf}`dJr<;sIw(0IsWQkKC?ZS?H84`2eYD)fcx>OSB3DFosOd1d*>@`mn zv|}x%u?fht05r3gt)NBzC}dqL4hp0tlQ(jWE*ifO2SZUYa-2=qeeljFzx?|j9^d~$ zeMd}a7}@e{r@nQ|9$q))RN8LygK*dMHLhvLq?6c==JE_oh{w* zS|6Rr>1DfGZMvov=Uv}{cL<=~dr$-e2yB=P6B-p2M8jwba%%dn?>hmfK;T6+>`pa# zn=m31D1!K)77&@xYl4VMM8q5lY9SLb5E3dVvH?I+Qq{MAv-;?x^?X|Fzhb9GZ|qKd z?~a#!F9-^?wNctv4e{`JRAQ{{o;NoHSDY-P_dbB4^jN9RE4i?|X?>_+U<(EZzHN)C zz4iL5)qMBC+dqHy>t9T7+}*i#+mcm9GKQpc&V@5)5EvO<+pB^p3=sekqt|thLQDnt zju@Krb6lHhzH4T)ott;c>F(w6qyF*?LGAPqnAT#;(xe(;bZ&VSaH-Yf5G%S#Xjttq@Ny7Qg(-uiyL0PgW-uge0DA3y!O|HuFB%fI_Oli94OCtMYfWQ7RaFh~=5 zfex!X6645=^Z7+Etlh-kl8ljjY{U$ySq{+r&Twf`@EWTcg#QtPz{m?x7%IDiYAPd< z1cGoSRnb)MGi>Hk1QgH^NKSbp!?I0uF)q!pS0aov4!iABh7t_x6ce+LxT^pvfDrRG z5wfm6V$G7BCsh>y9u~i1h-2%J?H>&qj>uvNeudK3p=^pO5v3d%q9AgmjoHZq(1B2A z+CGN!0sZ69#CBm0aYPQZ1#KfgCC!7;KLdYeHi#&q64PXptT!}hWS2)+iV$M;Tb3r_ z+|#V!_VC5 zkph@v&h-^L-7~XL?PtcO;A$eO+I0*)A%LBcsfkd1EC$1c4b>Kr4BG-V)EM^$jTc40 z$xc}o^yM$@{odDhZ=;AfWbBkbIQH*n8{MN1uN91}+O^LmL59QLlwFXSd6*6|Z zaK2Y@gjkTavRZALwwq2SJNtXr?v(Xxb@aGfT%a)qY7bN?wC(DhpZx6nj1 zgm`SgAMzri0;&WQf;*5>2z9iYG%kKk%q_1z%~k}W;fa!c5*V`Yp5w0wA>S-LqJ~VH z{FwPXkATC`CLtk(ifowbDWw!?Rn5M|2$K}NsEPGSQl0%oZF6VS2zo^0NsvL8B#7IQ z6aYi{pajdRqn*I{;Wa@gCiyuIWJ;~as8~luE6LXyOzzOifsfjPt&m&AHR3+$A9;O#~*(z-eV8~ zjHwT=PVc-}AKd8r?(F`@&66*n?~I*by~mR)wwiNU+Nw5XiDgA>QCR!dyB1K2**``#JD)4fSKHCHD1>b3GJfH0mK{^H^07r$|jpS69{ zD|-Yqb?HP~-*=}=zdCD9Pqn>tn{(+G{rUn?RXre+F~~(V-vhGM?#{J0zGJumHpE68 zwyTwdx)AC-xB{mPfS|;rNWRa0dOXFNnK!4$C!hS{^3l7^`H{K}st_?mp&ASk^j?Y7 zJCCBGPPBPS7q+zf*USBHPOiU>^ZA8uyR`?RUf>My=z-k0HNA7Yy1852xmK1|Da`IL zH*?sY009i3LG(yuls%Fs@z8b-6hKg&Qpjaw5bsry*mTYV!Ic+ZEN459KmYXd!9BlT z?%aBTi9C=K1yyoh+y)7O$S{l3u4yThI8`p{S>rB%oH`H0C{DVz>wCA}lm}PKoolAv zSsg##96$1Y0aRc~C7_q~{)Zp0&rSj1wXb}sbA4DQl-CX>PBZK?)NzazLj@!nk}yZu zxBU})Y`BR=8jPuKHDJs-DYo!gL7R85-x_`PpxN z`Zs@n`Rs`z03)bURZs7{IJ@-aw1p~3 z-$Q$WWXfWKb_!e|Dj^zUnU~Z33M;d@+$^3Roj-ZJIe*$5Kal?1uP;D*a4l#LAYm7wLiiIefPl4} z@2ac!@7$SPxq($F>P10-!1Zj5<;pNwHePxlu*422BjzJhTTV97xUCep!F{<(+ATKpp_%exM9$2&`y1hK|vQ4<}e@WOTums{q%4%<4Ue7efpz3Nky` zd%?VU_Uy^!(UZ$B?v*=xcD8GXMT`?fzcJ+m7~-l?BqApO1XNoqGiphFCtd4$0RTqu zoAv7GvD>*?%x9Bpcet9Yp552;W9bFBWF`bUKfCz5|M!1cFV|oD{crc;LY!mUryaHf z468XV&M^oo075*SWxNbV1A-_l0f7(S@w>vjm$6tf(UpIF-ZXw!x2X@VKyIkpsGUf+gU)NSGKumc;-yE z(;#W$^9n=)8XPhTHRqn20V6zn&MC+b5hKY-`iU%l%*FvBxga!-pr_C+et&+X&Y5CDlYO2ZQZ+?m zj4g}l9IXXgsH$|WU#~%XF6TvA0vkjHQ6fe%-u1*p#Ogf&tAZCthLJ2-+jQNuz!zVf ztjVmL^vWN9w*K3H?jIiatIdWBzH)bOKA(5X^T!{(_v|;Ok#X(D_ zX6I7!n&K(YuU7Yd`aeDW_~6Ft-`;=qcf4n>O2%;5PDaGcipW%oih6;t-47HI`pc8! z4}N&`@juJvl8iyIaXII*=YyMtfDn!aBqELAj38hvK(}e1eY82gck>N~IP-TBsZ z_i8nrsBe#sFD@3v$ys~R>K}Y{Z(eXvq&0>@5kNz&H5N1!wiT1LsGTQ`^^}N61y<+* z&>|~(#b|fCP7tJ;*VoGz>-qfb>66PRkLttC{Q3*z!8uej^#Z=z6tyvvJ;ZZy9U1G} z-Z@8AMTowQz$$&K;t3VIO?&jPYxe5>tJT3(uIf!aZBC!K#U*$_wkXgn*Z=evf6;E5 zul>Qdjpd|ek37|c)N$0(T8#3|hzll8m8N|LF$9QbyC>IvFb9wqNuu*XP633VXkbpF zA1{%h3B{!tZ4@R&E)zAx-0VO-MKV<3wq48c3WIS{(3Gv7!QOCCWQGE%CDsk3F z1RPx+R~ZE^FOsTxM>|PLsDhZ&4GIuX z85mUq1<2A|+T)O_$R+P7b9{ubWjqe(aI`|`K+Lr$vPZKm%xBn5@eW7{2jfj=38S;i z8NL^N?Lnm<`Ew%|Ljfp_j%qZs7|mb2!njSE+>tQC;Ws8?HeuAmPJ-x_GDHJ|3R{yV zbVEAPEg6NhT*e%KD*%x2ejE667D23lf*wQ=&dyi={0~2V_s2i#Rx2O?LN3bc`mLS2 zFB>yiJ$u+Z`@(lUBAaT5svT4BVpS6xF6*M6fGvOu@m|)Kvbi9hQ8BgCLm&%+fuNEB zCPHHXQN^nYF%uimKqtg?-WaaRs%h-b;bcm)#l_`sJ~}yFcr47`^?9*7Yu4>&KmWz! zw|}sH{3)zY5qd;0go>ETmBezrfix+AdJpIU35W?9ypVL8CtrMe`gH#E@r{?ivvc!? z01}#%e~BvURWKAhiAm15K0ki?>%Y0Y|8oMzY~m1T;1Hpz8;#f^f}~)YB68FUM7<~h z7+^G@etok3_+)eMH}=YlyEk5&U%g|d^JTknEA;nH7wz)9U%hg3uTtkBc=`&V>@FfO zu|ZH33}Nj_34KqY5ei;n+yEI3Ap!<7&jm@Zh=>N~hgZ>*XHOox_44x3y<+#!R+Tsw z@FklP%D!7U^&mjZU`yYtQPi?@t^r{(CaCM`dvOlDlf_xnwPtU>obAkRzRZ(Z^Xz_i zb_Bhk_;B9(Pyg;8*6Yo8|MYvdFy2cp8WZR5STV>e5TdaF9epIP_XxjPxrl2x2pR;G z1b9v8mljp9r$GQtA|D2}0vbJQxj# z8d;!|9MUd>NO*r!uaN0ul-Fb3Y_YsE~ZQyw0|)C~W^^et-ZF zHs@&SG~Gr`NDYPTb7AbSfg}tzI#0zo6JeNkk?su-g_&NA0?m0UU_6P z>!s=S+uk>4_uq9Fr=-ZX=3>T^85L9Hl1yo;%G47@MnT^-etC|*<+3W~SGkw~62!!7 z1Yl5d&Lbc*g-9SVD|k~F%jCV*byXGxE2_7vr~dNzAzi(Vra(~v z(|UAmEAFzIAF{>v!UJ0I;(bqCf}nJs7=ciG5&5U4bxe>`YCKoKUZ z7A_X|oJKoHMA`g=$xl(|iCKg(w+BH&_2)z;2N40lt6<L2{a}gR% zzK}*I%ZrLAZSl{+14z9#AS!B3e~tER>;Y~K#?Xrp6?u&5QosE(Sk*W@p^%2;=z7Y6 zf<*FRe4&u%m7J2$S1IB@fMrUc#niNPYseW!ijdMYlk1tDB&c*uYz$Ly5;e#5FwUDy zD+aqbYG*|7!3_w_N^y_;9n`J4HvVk-9D)FdiWm6gllwpZ>%V#U;cvuyWXokyUAZ~A z^_rbdHfKl8(|g*rWJ=`HmUF77RF-5)Bx7bXvXugDjMsF)}rI0uN# zMnpvnnSkv-b11e*XCFzui2& z=h|}uAJ}lPp@^i38%C%I%P87lLL_94)!Jk14iOlUnN4$f^vRF@;`*0<|H{kXqGBTH zm{Ov|I~DrP>gl_Ge}4ZL3;;?X3KVXNs2Dc@L-YW$kqt>5iVDObRVILQ0f5E#UOgJC&La@3I_DUP3RE!j!z;#^)%nTl>3yiCv%RZS80SSz z#cZW_tj_FN+>mr_zt|udAR<$E*M=Yq6^vX;*MkVV&R?8~cg6fFm3#Fyqhy-1XRkq(m&FQiW3-PLgsJLqs)cV=eA%YtVI}B1SB%3DvCfb z6jlfqjAeH7$f@R4sOhQ^Jd%BnsVjM*1?<6Sq9jSKW2b!l6W9JoMNSYBG6_;zOo}u_ z?IfNAmL5)H$yE*23G+cSkqRj&Mj0X=pA!lgM{|%9Oe0eQfQjeo%snW?^Mc|)Mo=8R zlCPO!57GO|d_FrJ*&afQ!9t4Zj^4_q4w6_FeT2+d5RnZt$9?$8D;O*Gu+=yiJ=SwR z!q6`oY|d8y4I2s|5t^;-5~?5|&ijwvzxR)S{ntmIeX0Ot3RBN#cV4a!Z#ajSUwr7! zo)R)~fyK;JbFw9uHQ54)%xq4kQc;z@yF8O_X>4WZSBu$IAPWEtgvKDV7e`1~aLA7o z5oBT}MrLCW)H#oc^<)=F!1>L^3bmWu-nsVTtEcD7&))v!vtRvW{oq62FGwAcsuu)8 zR1D<;F&gl+-~bR*6yx^mxTJ(Mp28BQv63o?^8f^{Kfm|h&f!awtCOI55+fq1_s*$` zyS)G5#TUOuuyI)$MULDmKrw1K+cji#1$G2!^Hwwj*+PfXy|IWGYO3;rDu@b1;4hBP zE-%gW%EcF2@9yuu_?m1?w}IdL`reI$0>LQ+Wdjr>2o#oRZ(^slX_`*N2YoLeFCyTP zpbUv#1_V^Zc=0O2NKS=7r+a%uW_fYatS=k!(;IiufOer`o;ue7d1PQ~CcC@cYDLDN zigW>op*dhmU{tws`l4|MvTb zR}Y+X$*yEUL9=o9;)BmrZVZbmhxYRPxxalsrlxbIA2Hb!MkOpxS+a0UtL&!-r z_nB_lfB~;H-BBY10mSNN9BvV|H$t|+ps>ZihgB=8)$4=<&4qT}!4@CT$>6D1`9 z5YW!cd+&Vq&;RYOo;~{;U7EAuFdH>yheGcH5NgZIg`que>qzIw1zJh>wBtzB^TQwGtkQgB7 zy5YEQRR!dr&ZvkBvYe`C1f{^W1QbQY5cga3-2AMsCVAA>N;_)`d)pnx#|iC5wol}>u=nilqT4oSbc^Fg>*jQYx~7w(Kik}C;~EqB#!4*5h=L(NGj@-*n6kW z6C;xWR6i|u%WL+c+FYD2AAZL5tlHg2Af-aVqbMRd=h$+&KbO8&KyuESsdOzWfGCv~ z)VUUb6uoG(>CcaKdSI)n+Pe;bEh7;3m*)aP)_(fV`zrd!fA+5ruI@SSVh}KnYMQ)h zCB{GVtkwW9iQp(Iq?3jL z)O3@F9+Og&h!b%dQ^H2XAWaTOn8TqEfPzY@I311}$B?CxDJMWsIr7cIHZTSCDg2P0 zAON1mGk^h*gBUUNt)%L1ir~Eh24^BTAnH{a(IC56G-FUG!Zk#dIHo6r*NrAh4Y?a~ zc4KfaG=ue!20BpSgoyd^GEV=0a{@+I5g`f$0O=5>OnwO|bP$d%j@z6YQ~FTWeEvlP zgsE0w8cIM#8bvKabK-iZ zCR6EJ|Epj8=0|_?KVLk3glvkUC=PDUZ@ zcCOVo?v{I3Z9O-o1##Z{zG*fWXY2FxW^sXiiy)w0eXpuTF*|(io74TnG)<9+y%#1z zBo#Be^BPQcRuA55&mN(w8U;c!mWm12b356ucCVDP9aGJU$pnL$7eEXVIuYOZP3PKm zyIOVY^KN<8tuFj#Et`dOjY<#Ri}Qe<$RM(Jj?j|!0?X;)9rV6gpFREP7blNCyZ`7C4-vIheAa0;uLCR5%CCUjQ2k5 zZc_nc4O*Jwel@Mn9zSYNPoUpSZ{HQ?K`DR}87txmpzj3PRP&i{+g3!n&c}KSgat|8 z1+@a3#`j0KcRIy=#R zbr$Q4&1UIa`&6ClVtswR`{>}jQLj4oK(0hRxVJ&`vm zAYd%ky^YWR;?KZy0U&U=EaJt#f^!{Wj|0btktIxCNAf$yrAi0G9h<5DQeM|q0w>1d zjE{rJ#2gPD)WNW%?#UBnjP2XL#b5+kWFfHCJ!{T}{S07Ov`m8R)``jcP(;&1{d*3h57Jb`m*AR;It@ORMwJ9fNG9y!mO}~K!auOWan)&`Nqrm32EvJSJ6=gZw zE#|vszK6Evq98VjGf}`IR7FICsHnsgOumXLc;B~uv+fs*_36>(^l5u>+$~Ohvl8E{ zcd8&>$qAwYt~Sj{eem+^>dn5>X48K0>krPJJ$rEPYybYwzVgD=nfT62V0UVnrW3kz zqg-v;qf>`u)Q}5oM^RM;W1LzQn8>Jj0#F75^#TIoAtY;=VzPVn=KA8aU0*IA-YfU^ zZ8>pGZ;TpiKv|?GK3q}(|`l@n3`n~_fpX?v(dG9hk3miXgYYH1RK{9I^7K;J^h^qI}d+(eF07HzH zqb?Kub=4t-8uB_!2!JqN{s2TI2_O^i4UNj5L+UB%{N*qH@o$@pb1aH_ z@9Om03&muwxp>;1-Un&f6lAApDlnEzLAK&*!joDMwNpdjR;R9A0a;Vci`i9M%|fOx z8H30`Dqg*c*S@e70`$&VV~7a>Oi?-~-h;J_%)WQE>F>Ngzxl#mIpJUY^21Mm_SW&Q zf7zTrR<|Y;@D5_^PSWC0BrIxM%nr+g+tu#P>fma9<%X>$hOGc9l88btVHZE5I@f#O zgX={+cqnWE)-n+g8aCiD6D(p*4tba}fIuM1Xs3Huru&DnmOWVtL0}}`dr%Fsqlf^i z>pdYb2Zc4Mpy8l-FJzdDs;X){I6S!fg75q0;(U4ZWcBRP`s8W1KJ)DwP(to$I7xVO z`f1-U>-{%p^?`Kj<;CSc{`D^(-+%ny|M$Q9jj!HD1n*Q8daq18pOyQ&#cCz%UO*{` zYea;My+}BAr}aLDJ-s3Tcm*UfU*{7oN&T&zA^#DXg zRThQxohb?+5(VlS*S4f6;s5~Idhepj-nX(mRT8AS+PlKGT$8bc{pF?i4IzK=@y9>> zZ}><5?)wK<_PujqzG{T-P-+_?5J%F1#fP~bW(bIg?|awx4gkR_Q7BBGlEBld59t@r zv#f0rrkS2)R<4@j4LULz@q5WWgh@feqRje!xL*`jvQL3Aex-RSr;-CnSIEEy!FrF% z0b}+XqNqTDW#CAefM@^+67|I-N>MnbCWuR<3P1qfYdQy+5-1HcHDQXTGpb_Rs!BXx zGjL5a(r(gsBLB}hli7`mFqh3p$l=!D+CTsEFM(jTZLzNq040iR0|Um<*L9m{Cm>HR zCFy5?(OBm%_A7>?b0`GUqZgAWRZiv!iei)$V&-n(4%r+Iaz4h2h`0syL+6iBet2iw zF&Y`%^u(C0izo={qG^Bf!(YDj_y6-|wKP>dyK<{KxC4mGXP>*}F{zNP(9Y1-AuolC z!ju(O6(IVi#lCUgtLqt=ik)J5Xv-O}AvA1_h=TNlXbKkbtQJMR7sJeC!aiB=90FTQ zK&T#fX7+RxZ_aMK zR9}Cwnn%w=KnX}ZcrSv`ca94#iUK`$n@ziER29`T6AB;*u~82wD1u>2J28ohh{U*F zfPM{|IuVH(O^}#X5P?KNyaZ7sPJdAG9@HTqF=hUsAR%W{yKtYXVWLuePGTFO! z-M#ka<N-0GsZ@%lUBA{iub$!xq+>;a6xR?awy#fIviKzHUunZYsK~>+20+2!K!4_4s zzBHW$MN^f#H*faMrdgbCPEYJ)X6wqOLJr7)LI~7v8URH$rk<**c+w6;1(=Ae>$)h2 zxZYiyaV0XFay^|~xz!ROQh#v@zDG9q-usvUzV~N;vU|AWoC`^kp-hj24XBWm4NMrK znir9X_ToG5ocDz2C0Nl|qc!tlP=&BNZv;h|sYh{X1T$g7la46#XgOxsjKcLP+EvR0B5WnvZdiyfc?q$fbTC1@5vs%j zN`%qLh}m_Ry37Hb9 z4P(Sks$jAnnJAA2DC}8K^{R@RYRpC(j>$J1VQlKRQ4Bc0mtBBpNRlv_10Cssb4F=0 zazP3R_EI!Q#p4~bL^R$EGk&&l>$ZQMe_`7^Y~_OmKj`v&^-n+e@jE~MQMXwa)7kvy zE7i_^*LKb6W7%8~A)1Qoec(bB7@6$E)-zy>WZim+%?iMK*PCi?%3UlbwwxjmD3M_R zQgNzE%!W!Qn_k6%8YVW@^*w>nsQWwQqVRD2diAZ}xnA9vzx~eV|MZ`Kbn(HvZuQKs zj?r%rG^VnsQvgL|!?UZm=C@whd*SQ#!3{3TNE5t-B;Qb?%{kxq4ix&8b3}%W>s(aa z2t|dMLA^1IMBaO{CLC#v2+rfGQD$Q$oCW47ClARlN$JdLXSQJA~RbodTGmARzUE%~HGGs}guFEt;b5 zdSeSN40Jt^F-YEZXe=U;bAU)_)H`M?>Vp!2eJlRd8RcTa^`tns0R({5U7U*RQQ_W) zACW1(_ov^V@6DWZX^qDHp@hgW5&^Mp3Z!KRsu1gn6GE)y8oY>%AL$FMRpRE8naSu7!

()L~7dt=BLG{z7iaX1NtxI#7vg2W0c>WKpVhv-HVMb#K7 zC6hwfDI6C!p@zeKQW}7WS3<)^ct<;js-Pm?0dT(&GK4J53`Ej{%LiVjY`I+C`tq#6Eo89&8^8MeOoE`n_ zJAd@$Z+z$OPGS1Kbsnm+ymL$XezDkqxadkVq7bU63yK`vjr6_v&aK*RxuMG1>CB^u3RksuJsHzAr(`QCYY!rABhDiel?8g|`!*^O z;@ssaOqC`xE^9l#BBBLgzc>fitA|g2^FASd|KI=XdQv;>qwJv?vRu**sDXDU7(zld zM4lK85|JUIP!$qKq%N*!fgx8gB;Y_=hU!(ttEe&(hf{IWiqf3dmlXn)7*-iv@4PhQ zx|Qg642{j0JqTGTw9KPT&Ozdonf0#+z6DM*@!sr9fRMyb>;ROH%@!`@n8Ss!yo<3ojsD~q&t5I ze#1!WTu>?4a5X#Fx%1lLYu}k1-T_7gQZEz;IG~6JrvM~Tt5K(ZeX;cGg^FQQl0hI+ z1t(w-f`c9kJcPaV=ur?=k;2(g3h@w5L=*_w&PX^)S@A0MARetP=o zL3@4zu2JXY{L!Y{bkp1Q-s@F;{rKdIzx|81kDgxq!S`M{JeUb|jdPRI-nv$QdVlHB zf&u3RLX~3@5J3VYQbj=_22l3id)EM3MG)}n(3XX$cb&2|-dkH(rMfvkSMQ~1JqVSR z^8$6H2q3PQ%)wLFtdZH46W_H;s@{Vka0W+)0>(NtzK1%yVRMCvZj#jQc$ zqhI}+i2m^3{Lyr0(z_nQ5GoMo@K}}vB5%}GAi);KDj-6rR*7MYs$wd56T<~DC>#=a z680&mcoh*Z!B>|UT}^2(X@#f%hH!ASBnSYKl0QPqOcDnozs&%!wM@s($*_Y>6I)E7 zTug>%oEa~onR>>@3AaSb`y!G{5dv{pH_HN!W^fyEdC~Cv0g{s9J@_#&VwnjBAs7ym ziF*3_fVJs95es$5qfej~;|hR?Ly7nlzKuEF~x9t_`ry|NAQU8f`s?k>?8n9Q$0_h z5zyn71x+?K{_0hL@Y&Oozxl6!_t`tYqQcs}EA`|!P(BQn6Eu|oSX0=d z5n?!I5;#=SrosXk5ESn~6hJ6tmpLckdlgnh z8;%$*S)v)y`;aJ#+K>{=>H*G3J_mUHJ?>`??vQIcWTHi9auSQvzG zz_dq2@ZK-au$)0X<8o5&9d;L50Jaxi`$m~Q_~ko<@Q45I`(!w0Xq1ZhJsXc7`9K@3`lMI`a zK;o%O33w1FBsB$XUqK)o*nmV)$x3E$uwVJ`l-P}`h+tH8{F&77>xf zCJu~B++l`uO=mepUoUA|gX59>z+r5%8O|m)zlGyZ{nn_CoX^Mw2=URQ)4%%9e|7)E z_f0h|_ODjEH@xeclP|QnL;wT=v}h}~H6RfhE-EvfA(g7suTG^|BLXp(vwffnh!6;k zWm71C7Y_uiJz4I0hpNnMjR_CrMb!IXzr8r$_lEJ{_O&Z_Z=9bmKmFkkFFyM~`(?j6 z?a!Z)ZU{s?B4AO^>Z`Z+UjFv}3tzF5d6HSuE*J&xl_FsaoBR*~q<3z;Y*!nCa(+0w zdUJnwr(la4hvyev+j#L|dB(L%h(sKCkpkpuRuGG4#qL*7@Bj$FY05~TX^4o@cH;Y@ zEJ4|M7kms6iKPZaBJVRqWWjs!sIji15)&eL@7-D*ktvCoh!wm7qZc$l6Km?)*4HY2 zWx8G;96!5$@8idhKE8kQ;EVS1QrSs&zIpazn!P^Rd)eB9&+ac4|LGTh^l!iM>g&7S z^}TmDuJ5eZ=TFWzL?s&(@nIjG7eyoiMPfqj`(712I7H%tUGJqARq(DsvhlQJq^@bm zRKeO}WJ6lfyv2&ex2X<0g-!}~su`R+ekY1Dxu(hrY{8ORXXzzp&O-kwzA*sZGI0inCua z70m!p051S4;*rAf$ML}0gpQcNJQ=nidYMd~C7xv=DIE@DSU1(z9eYEVsq`SJL?liq zoPjx0WKBsmacBZEV@jq12sR}AKQZZyC?lsVcF8uLLRS3;`mHf0qp56=rYRBz7~;7S zsbIFoDAWl3^GI*$Ut>c6&!PPGTiFR1bzOAI6ac`f649ea&;HB*_*aiU`>?F1_TYw{ z9`x%_(;6W@H76s`@|@n z^gZ-JrR7ld77#%_p(+~=ZYvvB0P%vHNRtRE0&1u!7Z2M=j&4k(Po!Y=@SP>^SNqqC z*%X+2>zpbB6B~e1MTk(CsS`pKATY-6 z&eXMT-KvT@*LD{?n;;?@1Dz*R5IgarY_KS-dUWWzhODt=*=?3_m#^>q;+$%a)zlO< zOn05CodIvyZC1Yb@BREOW6R(B*T2WdkG=oGb z6You~OJwo@5DR|{Ur4qDqROS-vcc z=r~C!Jz#42__0UvDL}7^gpZ${{KbFzs|TNdSWR}z!>e4(-TJ&ge+sTaRYU_oz}8d~ zVhg5VwmjWYE>xsno=M*jp)Cro_kk-BGG#%AyaON(lDSHUgh-5nB_Jb$dPQ(;@4Xbo z1brvcktuCG-@SFy%*)e9#}D87X?uJh+5 zMxhc_h|ppReM>CUtE8w-+tvE~=owe~jX!+jE3e*Q;>EJhTxzJ9l`x4~W%# z#}=h{5dk9RSTQ*lcLlZuI5+Yv5kXz&MgBi@{b!RV*Oev+9&xX`zams>Bt$|G06`KY zsz{dVs_LGe7Bf3NwqrIuHv8N5<4Rjwv$e6AwchP!m!c{XBnYh&2_O>*q>jjlc!m4D z=bZg;g?pfS!xG4hSGZrl;yKUJhG^Z~BSPvTw%yXnF)fjI$?vwbbKstsFQ31#{QUU~ zpFDf@vrle+{_!WLM~^H*;}i-hkyFdU-k|5AzZz3uw6em zUa!E<5K#@{5P@^UrPL7~!~mI?P|bm+qizDhHZIOIMg$?>4VzPBM&}U$aBHII8nkFb zZxngHh#FNCUF)0<>ov1Sav%oWm?%Z}xd+kqu#GEWuf z>O^GvoEIzyApzHkIb-L@N?!@8EI%XuorT9dI2_@23{K58GmGyz!zF$jkH?`-w2D0P zBD(F&Zm7!%R*7P1wvg;j<0hKwlVuYYHQ=l!VABtdx61z&Hd;1Xde(ye#&qw&;m`iV z-+lG@=d=2*iTfruNL?NPG; zBXrKP5nTX{921cOn!*sb9XEuW4qu9|Vy4(1rx|qJa_918^zPBucOQQEhyKpT7S`K) zccFhw5Dmr8_Lfh)bnxsCcdkC~XY=}C06>`Pv_LK{L>LA!Fd~w^?@vyL)1!VnT)Mpb z=l}9$5r53$esMZ23XC@Qz+^zi{m*Kb;wzkUf#vt#r=3ay9vCXF)%Q#2gk

pWa=1zF;xT1+6-|^Y^q4tCjuh^M2V7g=#0oEE^Z9mCp1mgpvD zW-BXMWs_N1NUZNnMOPJCStG-7A)zR#`L;x6g$L$QA<7RFebbG4XQ$%u&cZ)rM z76Hh4A}_(j6hK|qIhR3H0La9mA*rfq)KqswV*nH1wtoLox4VyQk00EB^x6BHuRqbv zqxGXZx>+$J5qIaFKKH_p4xal#v)CiY1f->wSJqV}n;z9bf~YDYogN-<9^Q-L)RBMU z*(aZT`pVz@?6bqi$5)oK=U=>byqSIU`NPANR!3>W~BD!AEf@9Ad^)P|so{i7T2-+Aj-`_F%G z@5(h|uPOjYgr+%vAmvCUN0RpxRqJMuXzNuFwRzVdf&?AJ3^}EnsQ?g*8L3`4hs&M4 za~It+-#NJc(WQ^y|Mc#S+i=>$=Hcq*f9ejtKU-Y9bNlgs{$JkwlYjmFOHVD>4^KXS z;fs$B6@c2-AUeQq2BMF^;G~~zwIy<-7Q~{ckP#qyVofzu(TG8W9BEWFi+vBweBLYea0vZA^5tQgB3dCbx)aLd|irAS#81muRX9uvS)YXNmtf7|e

06;WA!jqHr-~7ja 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%0Dc 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 z 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%0D$0h$wV6B#C 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
hucU_g9Hl^RFHV7~Qm|60SdP~N zc06(I-QD#j?l9;1>Hf>b9I5k98Ey$PKxO4m*X`OT;yh&{cx(03t5&yL9AK<)Qb58; zo0dx#{%7jU^Y(#U%p}|(gxQ;Sp0*!Y$6OYh{L8KjUEsPM#Y7;$iRyx~sV7u3P#kZQ z7BN>%30#851WhTF%WjUj9liFGZ$J4z@_KkQ`Qz5~bwLR10P zl=trJAMd~a!O7mopYENV?LEI-U;gso`SZgEZ#=(u`f|RwR`g}fq7rcV>Bv$IS;`{Q zYbw%YUxE^yyxcXv`btIO$(}hdo0{U5)7ey}iDP3wlLSmS*&w;CEX6+NoteV_vW}XQ zDCzec)G1mAXMH#HfAz)9AAW9MT(o_!bZ)+092~E{{f_&c)BdpCiD9%Hk+rHv3YaSc zdm;dn7}+PIFU5W%pLZ4lVo;eo9y=~mQXJ9~JClymXLb!Gbj?ZynF^L04i!K6HaiT6-2;|J`YIZ5Z=iqP2 zXziyiKwkMz@@rlIVi<;@+X4`(u!rnKhP-qX-{qp z%Ff2uE&@_#h9$Dhs(cC%O>w^Qi`j!s@Y}60ULLM4j^}g^0@TrOW-yPLJKk>&8@Ln~ z6m2L7a^msEWCRP!Nu|_jqK$Ya9WKDAY|zwp)}PU}Y{kwmo6~!bR&C$M7ER9g0O)$# z4oLalobRF#`+~LbPcffz)eY#@(K1jlP}BC0xp1PN!WN+CvB z%n&mSt$I|Q@++2QqT}gTOYi^ysqLpah*#$jZ0JAu>gu0R100K#K*z&Gu4gX_83}!<>D6P@U@}k6f2{3cNv3*H1lr&KKQuC8* z{{>n~v?qpoe7Evu$pIxIwzv%uroJ%M`eSkoyTHzDmCD7-cXgqGy5bqCvV4Z)uN0{0 z#5oQjMx$@q`NnTP>a7!P0e71{8ozGE0R%+M*lk1TdZj2uqp6t+a}iplfMiSxPkx`s z3G?x0Bc~;5jhNj*E`(wi$HIVCZk#^-;l;*mRu7_4<{FZ4>_UIN3vu5AnMe{Ubx-8T@R{V4=`D#ak0;eBlhDM#ScF7_ zP)yV=dLOCx@BHd}_J3}l+utny73dUi_e9>icXYJB z`snoN(e25_(2;gU*xeU&;mVMMwdG1LjRoY{CBH zXS@IJXYs@5O}Fz9oh=sotJOCi%zyvh@YejMl>q=H4NyoYVsfVtAym?tf6aX~;S6z* zj+w$MEMX41NKvJ#Ej*4K=K_NUpf~JHJ7@rmO3CvEr$D2&CX`}*M=_?5#)_s|yg&IHZ|Lu`D60`YFi zY|%f~1bhYznko3y!p$iMqR;JSpn^q<{kD6u?FYArNHd2f2D+}U2vS=ZZFht2`e5n& zdQwdpA8wk4MnPVdYCbgkE@r_fLP`)WO`0i?HHQvDNbFY47tIW#@=kqp`MT8>wV*)( zyNIi9;bsrI=(fX7`Dh;iTcyj0TV%ct; z3#stLNTH;99-5^F_bkOELP%+IMCc&?(G}Y#HhV437j)5yW;d8(UJ)>tlIlnjSFw{< zUqi;gc~rFu`%~)2jp-lvpBgzFxyJ!uy$Aolh6f|9kt7q{&^Hb3 zQ@mZwNYdz(mCp~8hTXBQMIpgT;#kW3lw22d8wS<&y!{O(9w5DYO+0gAVJQ$*=S?I= zGm3h*=N_HKmyo+Mc2${L|M5R8fg^z-*skja+vSrJ7zlF?;$SQt#Zl@v@{#uvf!6*R z$;Q@_+h4aeBm5L`fXa#|b9dxmklldK4c9|2*BiX-e21C1)M;58M33miAPr<#EO&6_ z=rl_yia-Q@`jS$SOZLCT)=&US84g{6SVf_!;YwcU6i5hR7>1HG7c3g=wS(UVCl(b$ zAhl641+9t1k@CJG>U18q?Pk-5NaxeT7& z&*uKYzy>LL6@dbi3GabU=y21)?L;-X4XhZMAxEUG9S%%~(ZBC3nm z=DKS=T|Ix}&Hv}>=~sUh{x5WimUV2s+mrVvTo5K1cn5vgTl{|p{#_Pw2C(92$ zTz~QL#}^l0-GoK=WOZ}3_ww$O`}bcQA70O!Eg4HQHYQ7xczJ= z&&46Ud!O@}DMiF6qLSNGia^pCpj3F1y_D1kF4~-%DX~=ej6S~_x`bOqRdnvzqKEB1 zzS{ifpYyMuwbwT)>gV%Wvu@vhbMaq$J-mOonMt6TIhYCaxtfGP0jh`sJ`LzBl!+1u z*hLPNenu6zQs1SVI~)iVGC)Y#nRL`d{$!s}6k}?mC+#frUQK--E16o}SnCG_r3H5d zJW_2{#>0}mN-1k7H=VfDtVJjh^iOyA$Ae;&Mn(>-Fy}K{xmwn-}+7J*di)| zV7BdtI6#`z_dNpXKmbWmt!q-5==6isdP$i_V@#dXWGyo&FZ!Kk4G;pq*SyxKhixsq z2>PjE=zDv9gRAY**r?LXM6A)Faf4&iM_Dwx)hr_QN*+@S*>K-#23IY3UcVC4m+Er` zOj1+WNjJB&-KwehLlb?hLLs^!Rsdb=u(#Z`SKFQJhc@KnFsNGPaV2AWxSaBSHYx&SV?wDV6%DDf=Sf zmeP%5EgDG?n$fviB}ya6EXk4b;1tj`Y*fxK+=G)ZR*T=g4unKiXDWnkcEfJK!WAz> zfKG8NXlxu7T2l`B`RYCto2L_tt)M{!P(!2}qPWL5*eqV2zV)B|@X7Wsx7}m^JK_OT zk`xtkY>0g8jYf5{;(Ih_1#BMq`l8+c-n+*~dmsGr@cHA1p?i9L*>>CZ`sMue-iy~B zoFD9Myc=MWkGl#L5=)Q-LR2K8EV4#eq+G?>hfh>Eym#N)8KI&oR?c#fvDmWzrONOoLe+Hb9Y~BfBS)b_uzUZ z1B`^T7->;NvkoGki)PBlmSea^sCmi|WQTBNq5vw|vt0>lJ4=1~+`nsf)vsA$akRaLolry}WD-s?|r`%|K#qMmU_ zBO0BzU98{%zs| zq#(=cne*J9COFw&&+iHwaT@J8^<@m&1$%mf-EIMq+ zDLH_GCm|5k)H5U#RZMOQK4u)OhGYqCeW^PfoK6CoWpuCEdBP9182U! z!a!{^n9zK$anGGN&)9Ca(hs%(T=qGIg{vAg^6>zLMrw2!grsx?5@D4>d&$G%i_B(u zG7zmjKiGR#;KR7_z8Ll=rJ?-qydOM$|W&}tm9fr1DuiN7p zntUERYfz%o#+reG%SxOzv9KsyGg0?6`9zaU$4#IYwaznO0p&@#W;1_vV@Gd4K0Ug4 z`s65O7F3l1H`}o7?P#H>6DR2erz)$6i@bVT3$F@&G1`F&_@uP`ccrX^1|=d~j59gw z(OY-#&R_iA4Ss&H`BnH4{S5SCmMF!kbH9be${UjT03(FynS78#b>DvT-r@fGmmeH` z`PpYTmy0gU&#&h<-TM4|b?^1(_fIdE^TDZEZ4sw1W4@_~Y92^ugsMvo4X&g6#Ul~x z-+4`z^HM0IOtmuUnQ{TUs&ERB$8W|Gj}$NEluzP5Dag(28fOdFx4b#Oy86dobU%Ky zytr&5)zEl#CwucBoZxqlx2quNY2GLqvt>UaqqK+!ooW+%1frp~GtT`do3K$gpRgDsYUkv+QPg=C!fxmo z;UKWmkg;Gefz~*r{Ho-GO2rwo7OG5EPM}a5u~k`4K&ZCV(}jDWIz$^HKZiSG)SC@n zUe7~V!%09igZK14suLTUMmNjFrX)n9Fnt-AQHleo)+Ebu(eAW%l_$^pS_}WAur>k! zX~dye>SJ$CEc7k}%p6D+*lNagv-8`bciu#72%@F=d^O^dlA5V#eKz#k55Y{FA6*2& z?30rF$S{9IGMY0-$jyf80osvaWlq7RgYFcKw#LKd`rHa_$X5itumCy9$y);q7fOk6^C z)9HX1iXLTRqG$%P*T_pJ5OTT1`SYG}c=ztZkDtE1O-}+P(G9lgESfmL()4!1``33@T%AJl~TU7Q?r za~B0>grg=4NPz+302G$n)TxKKNOx`XpFiCWw)y&9u2#ivE7I(ljPOiLtyo6BlXApD z2G{K@bt{QC5mA7x>cX?-=IrX~zkIy=)91~zi)Mhcpz7rGc>bez=RdlCbL@JFBpexO z$^AQ_E3}WJi6Hg9&CZ8_n34?G8LZTMq>U4S%kGae&pqWF1jJI+KeUJDCM%7-b`im9SP%N@aLPgdsInx&2jbe6eJ=@{6^jZ`v_cr#?Vp2xwb% zvpxUCS${767&)rU+f>Y9ww9!jFd!1Uei-^e%qi8_6DfvF-bTvs{ul6`W_?b zl#&}B-KByOB^qSy?zHZXpdoI0ei3BTMR&20&30kdph+gdJlH_QX3=Cl+b!CNO0XAX zSeJJ^30(Z6KqN%~)5H`xeNvER^iOsyR52CH-XDZe6`^ki11YIB|E#ft*|ynqs%kEV zK2Vy>#urk9WTu+biJQgXyRNecPOAf$9w4Dj0HupeM#7d)^G)#stJY=fnbKtmtdQ$g!4*wbX%wt#ddA-CqEO%HT=D#R{?@&R z?XP4TqIeTk4mO0a?W37<$!MzxX|e}71s;yvUx5QvdaHb48nBCkjwEy6$22}wB20v6 ztTXxQ`r@elv-j`x^B3JucYo09zNjJ=B$%ws*r^i5xuJ@5eE^{)YQob_8^8Se{o~{P z4?jD2_~qWs^%o&}H}_Aw=IX2Y$@Tfk>gI6Iyabm{TR~MA%Q~sLU}-fybZ*WW@{rIU2m`cN~H^fAh8e&Z3016j~{ogbE$tglbe32RMO}1<&LJU?0#YZnt2Ca-0_` zY?XVCOQDDakw^?C{j|kafge*T8)dOXLRH%)yOw9o6d^`AT9HV#=^|zCQ8{ZCFTi5S zM!#C+aD0U72`0r^$r%Vl)B`>QgNQiYYhJqTQ{%f8_H%OWj0RcwE6QNp4Ph7tQHlto zAvN8X%$G<$CsROL$_z|Gcgs_Zk|vMVRZvex6+*IrD&c(P-&I*bh9N#Oc@ZJI*uT8? z-FEGq3na~yXi|SKIuWery*f%%C^9O}VNf=vzIcSm5uBX!tm&80bLHBZLd9j*sAap< zAi1|a0dW`x-v=%2Yn=DCH}7W{wi2Ufh{3$MYz7mZJ<1R$sy;;DbrP)%r9oYlvP7&% zBRx`ikCBEeyISZ-8K*R7QBpv|X0`s(ElTIpSL}Y-I|8VuQ+VaM zAp$ohU6=@VnwSU-?nQqY!+-Vm;jp;s{(SS_-0DhIiwMC-$LPM+BB&)Su72AN)t6`O)ziP z(p*ou5Wal2d(vP2i07{z^-iO5oaHK6nPemdimj^fPryR8mzUGT2g&hFJi42!n;$>j z{pm~n;zfJYIeI55>x1^aHy1y69k0*KlVXmNC(wefbmdclBSj=*|B{AbDcp(y+tNhD z#)nJ_La$sZR+77f88J|LNu4`O+vNg~Z=3#v1@o>mkKf5*O+|TC&9n6vR!1O{3)WQM zBso6%depu{)8gCPk22cTYQz#ClT-?#KE$4YT03jInfvr6{;o)x(k`#QS(P*j1i{#K z(Lz*+6T~-N4XC>G@c^i@2pUaH zbJ;|BA%%D8NUNnnYIPDi*AH1lL8!-i5$D>g!8IBq;{e~Jpo0k%lWBy30DyY4S+_$N zfHps3wdc3iPzYg~I7p$WNjYwU8eOCfD4-lbpUxp(?wzxT&rgT+-cE+dO&_{o3zx1&ff*Xl zyQXtPuMN?TQ2;@E`#RpVeIZA!8hqw8q(FkY2iad5Kha}U)aPd$1 z0997}8kLHus`D{)1{3+(zlepra4CL)@Hm zOCBa7!=jQjAP}v!=j**^$VEt#tKW_wZ+$~{0o#5bau@0?Y<9aF=WdQxm^DzqQjaHb zzFD-*(wRyg&|`H$SPr5l3!T>CmG`Q0ArPx$$#OodJY$ASTH#rR{~}`spx|VPu$hC` z;rfQ(J^1|R{$OK965>KY*TtbsQqPcG9Qc~ZQqbjNXccQ0{{mESm=%EexymG&1h42I z5vpJ$0F@{vG^hR&!$&v2cysR`{a&;Ev$Ox!1@3u?Ib3)Ja8@rZC^kn%qm~88QbDqh zIHD|$_YT%y`_=yXyR{|~&f9!12C+egM$_37BWZ|9ioJS;6Nri$>7As$)D=`2%%G8`YHQi~ z_F4m8Zo{X2_}L9VdfuL2wSDjDWj1SGKiU7`>+MVLo1poHCH znG36S6@`|}nB+cSNpvTXUd701U&rg*`pF0eUKJEfeL%Ujs&^qU4pisG*?#lclkElk z{& z&BX8d*Bcxvnt+R*kK!*sin66Gp+k`v7GzPZZ~b}N>x9QAkll%&g{v#Qw|aRv=lK=k zDS}9BcX8K|^VCo>_0Dm|drl7{Ul!)4oR1jk;L7$S$T=PrlAN4i3Ni)C91JBWBm@km zUN*sfy!r6Gy?^*G*zm{a|MIom6E%qfaT8xW%}>==pJwk0SY)z`>P!~on{IaWwKq=> z_kaG;(W9?E-E6+-&fCqly}F4%c=!7KgU$Veo%bE`G}Rb^ekDWn(O^-BUUyxyiL-&a zTFTKun6*Pd1mM&Og)s)x2r#Nc@bryFuP*g0Q&A@_4QVyT7>4Ip{fmoXXMB5wdq>+hb#l@CHtG*xxeQU{h)>5$~fK^#V1hm{8X zgc&0+BoZ$NOcWI*1u}EocUUP~fPw)sP`lFgp{D&=Ey!)rlOlUkavrtKmq0{Das*>g zz|{Ol$`1>$D8OUF@D!t(!kAZWd=G9$IfQF*3V#qawncR zXnIM|uyp1;~HnVy2=|N;pc{ zS2>c1s<7D;Pw$(>Na}}*Gbm30ofIsUZcr%RK!SJDLq56s@7;Q{i4=^2T485;LI*grBgo=-|7iXGFOCjB`e^U`Y<0C=|MH`~C(qZPz4Orz z9z6QSQD~ZA7HKfjDWr)4m?3&B=hzF5>Sl9U%)Ek;LgvmA09in$zddCz#5CECPB|#m zi#F0u`?!&Y@M;dwJN|i)-jM%$GK|@aehx>C@E*k5`x5hQ|56KR#Z5|4sKh zCw4Fkj#@;aB=wOjPLfwIa2RQ4&iU6{aE6*gfSDFH-*{mes$bZT8D5r5g*qA^9*ZxQRi zb~6-_%oh_t)HzWZhKM%lDgs340MH;YkMU+Y zC71@pR=vpXOMnzAmQ~AsuUOGrh#YE&rnc`+7wu~TifF`F)lDLB8HabU#LjIXbO!l>keQ zL(>9gzLi-+$;7CGB928R$>jUB<|j;|IM;FY+4Q!@Y$og-+kkgZ@u;8 z{{D?hugMY_pzsPe2Myk$z(hS$nOa|n_EF^fy!So@f(_M}=s8Lw5qPu<4p-%z8QBHB{R8~BRpuBo+KHWj&7 zr>e9=e{G#%qd*)r3n$tDMMbea-TX!E#Jfa@~N`q-)+*t46tOPF<$rxodh@1nP9|`>UJn zYp2)y3wgQeg{?RjLhN=i#x~`jQ?Edxad<;zZn!R3k0`0#0v6H;LRSZEmXBo#Ovq8n z?B+7cqwvu}BSfNl=}kYqc=pzv|Ktyb?VsQL>$~|kEDnau=4sXZaj_E$1?=H7OsDXw+ zI1zEk^<@keM@}u(e*{bQ$r2+#D4dv>SfmBYFbuoU&&R$ySn#!MK z%J0-z5`P1ta9oPYR(Y)pALSq@;W+mXq`wRmVhJd~LEKXaeVoH#1)3y~BVjm>Sdfe^q!Qd%-I z3?@-p+4l3#&aS?G|3CfVmzV!+_do1r-xLPYiMSH87Tbba_cZ>zga=b2m5SVQlsRL( z-?T^HeB;5%-cLVRKYTpjbhF6$mk(E0XGfpC_SLuF{_>ssFArw}#hm0$JKl+9xDt&Z zoI%YJn+PBcyGo&rC0;nSKQkgo*ah4Sa86WO(nYggx)+ztU%xo~tFMkdjCsA&!j=&c)%r69T6w~Ii3X6(Z?V9d+FchUQP5qnC?%s` z9YnE0#g|XfzP$2%{d=ifeN~}E0OveSLW~d*aqITEvzL)?BFW{gi=S zPB;)dMiXjE{^ypPtk)>902Ag*e@jyX3eKDw9ag-QvEbUhvGA`$d%#CNj<_O17l-rf zS;rY%w8%*F0#EfisD##Sosap@L*e6c6r2u870ve3)tY8pq^RwvUwId+BN)|90D)*` zfsz3N462M#H(NbQri~<|@!VhTlzmil4j3%b9Bax@%JK`SL}SwQ1B2zCjgD$G|M_9E zu!^W8GK!#x-mXKCNXeaB(pfNvVdb8!)-PFRp8p#BPvV(uladyM+re4mx-lHz^q{oKKqLpl=yojx=$vFbI7t@i7-oL2~xTk%K<%~+q3MN?71Zzis) zGbr8Sgd*_Xb;FLjy>nL|eh~wsih z(N-CPWI0LNuK6LUB33I4QX7OC)KP+KWY_yoE_QFc@rOV9;_4?i|Gl&I@28_$qjyP? zIa#q$qDz#NK2Tl8lq6SRLA-l!fB)cHAAWl9@kbwAp3M!5-FE%KXGf3EPv3g_)wkaG z@|~lr{bff2Aq^Il)EC;wXrx%A7%3uVmam&;ujIi4X@6qw$VG*D)1YEe_~>l$H;<2g z`S|#9BhhR=!{N%ke@}mKhi@NoCYtA~Sjh%KkOSLtl019;q=*92WXMKbvdt&V7}CcG zs5r0{+f%Gl3@1Wjpme4k(U)UiC?Tm79=#%cEz=7}61%|IGL9Cv7QJeCvL-o)kv=l% zE>-sq<$e?AUXEntD*!bLDngG}zQ)*K`a@B56b)SvPg>jh-ON3{;dfP(EDhWzw@oBZ z2pmF;(IBGY8I$~_?MQRrnBlT}VcJw@EEbCGaD%XK$$xEvO8IdJReDji5OiWeo!B+b4|7(hV>X}Vte zA(AfLda~OSQ!06=fkGTiB;+9gsqP;tsb{It7%fp$MhB?%i`kReavL$80lswuW+}@) zS*#1#;SG_mn=KpLw8OLG^~?1N-l-^r4s08@@ZuBv*C`H9I1SaI)@Jv`txY7jBAwEI zI1N}}B7SA!5RzIkv+*_P!zjlUj1)p7BgaPQyMA-^8;8$-^Wk#t^FQbT@CU3ev#unHp6KFA;~Z-(}( zOMByufBxMs`@g*EF4livbue?HJ_R!+3dk!p8Uap%wygD26Jhzl7Q_#7x0$cL`SzWo z{a^gz@XIeh+=dyryu8}~U~~8B<2OHf{mD1(fBweZi@kOi&6EyN3i!=zVh(3q>c%gs zBAOXeI0^*W>C7QMJF zpVKc2QcDPJ`XNT6Q#bR&%71ko1AQ~5%cNQv0fdHV2q9XG$P*@dqNha~NJprno7}vH zJTihbj0GK4+EF|~{@v7ZgEo`9d;UGALBJSa#PG;y7Q)3fu7{;LA2Gl`AH zS(DB&I_CwHXvyHEl@}KOByy`2#JC?UiDDKcJWTtjiSuk6^f=| zwCN>On8(|~NLbl!{bjnnqAog2v0mi=-xQ9ZYqJ+U?7@pbw@!1m#!&}x)#tUO? z9FM=MF4kToQwNTn_D*J2`#hC%^aTfBTmgSI-aryNzrE4C0KL z3ma1>RpF)Z3LImE5p))On_?r0Tm^ma^yKjG%s=?$;RhdlaDDT+Y-enj7k2Q|4^BRR za_{Xop1gPW)6?bo@qUCp}^%m-{7RkP54l%0#n3 z7xsU2#+B&DtskQD&*@)S6=K}LTS`;B)Z|}psg_iZRYX+03w>u6)zqu3-Q%Z2Cw^9H z=7kuK&>KNxh#Z2&NI;>3#eo7d1B8|{Q{xGVVo0iMs){|S3N2rnb}OaOm58Qs&);7( z4?u;Y4_^-QJVp!=&#ti>mS|}zMncsoXG(=R-?vThj?vOKrV5_4Beh3zmZDc902Z~b zkSd=a9h2fC08i49-%ucqtv40KT4?MjqW#tn5sfR={(^SSgZa(V>l^6Wc|RBff@dRA z$x5a?jj$2UV|2R?G4(o6D_qx2z|xtg^b${E7{`e-xhyNeD2SDg^CZL+oB8Uo^BFl$ z>}atNR$oyK))8TN8~iTK8eXmN#liB^^(?A_s)RaeeKVW#AvL`t6S#;H58o2tbn|M= za=$v1N+$xfhx8<_oh%sv((0l8iHv2hF7+0PeHS!MyW5>Dj?PaG?tgkoGkWC^hFu@} z(5xVaVu0vee1mcrt+|K{m0 ze|GZh;jgyC%YdD_!;9Vm|oyYIqe{#IsELXv4FsSp65u_l3fD;!% zOQ#A21_MMz6Mos5dwRY2@Z;kTK7H_fbH8^@)UEH_yumvs_M>~7Z@s4b%UNokQN&MR z&|C#X!YY&yQJM%B=T!UFb5R*5SWNg@?4|oXQ7j(>Tw&GRTx@=^dj3+0pRqvD-uWX zS0Y}UK6YUU-cyw8_Ni<(`MT(VxNeY(jeQdAN;M8Qcy==nwj>y676lHC#@0oMv_5!^ zMu)<>mq<(mVkME7bnMsW0hDS)De6)ge_}NEbxref<~MY10TYY{(-czp#mgi$yK6!+EuT(hX16|iAa#e2cYku6qQX;>snjq#Hdr=i70WC^?$nur1>DebI|E8117$A;f)oPR@a^(Q=t%WT&8681Z z?>Yb##wn?L#R@?h`fozoX@ z9KSeNZI1VbS!+(CibbfwOKeghf+t@MYEwuL-=Gffb z>wfFO_6KjpJIlGkAsv?^3tr3_a+GF`09cwp0F1JWvN3cNOOZqA)M~~whf9SbXr1i2 zI4jY6Dq-(gnV*WLQ%o*Oia-HZxF8*E*hpm5Efrv_K`6pm4Mh@2shO$?1R8PAEr}@J zrXVzq`1#j7L;MVJEecHH!cO+)@2Z%fiQ#4l&w*Yn-t@TM zEloTTNCy+wuyMgDA#D8Mlt^9HM%F>_>yZd^H|B{OPWzHLT&uRY(*7kuSE@jyx@%CB zzA;skAf+tWsMvMd4QZB)EfU0Ot98nx&RW4aE`5O~o^m}!>6kGJ zsNA~V1ec|2RjXUG#S{lI-+0$`;j_C(yXAa&we5vQayP_Xus~^&<&o52XX$XicYlRA zJ%GarV@OozCPk)1$e6l|mOOzHQ7}H^1coH5rzsg_OnVin-AzAJERT-1U*rFM_Y#ly z|3|7mT2!=!FAo5_TH@;uch zC;OGcu~Nk|jk|!7AxJ6W^nYVAztlDqaVUx55#)>>yJ*R;=j@7+m5N;dcB!B^*N8O3 zFqlMz&S%#%eHi(5fh!$)n9{%LeD4q$f(>B^>}e(#pgm(u$lXj*JMK(8rW8p&0RRYT zH3G2Gohdb7DK3d(fFn}-F)_TLc8!~keAS4Hk@DMx?i(FWIo;32#<`$}*$!~)$mqmq!|d%gAF&t?agAv@-Y4@j?1w@g=50s8ORc=pe^J@YY58dT>CykR6%7da zeA!gn^WxR|r_mG?EK-&to2ta#noyhw&0L2!mIo)lJ$wA-=@*|rdiLbm<>lF?JMVUl z>fjih3^v4F7q^#u@|CGL*M{ZZ`FihszPM`FSMB_2eRRDw_wxDt#lxek=cl{=ba2P6 znZwPgP+ZJxb3A+Uo!2ja?`?bQXw|4kbg)uri@L2KV(E936k5enhBpSi39=(nDMPiG z0!l=P7D*BHYDR^lsnn5)(&R**6vUlZ z+lqcyVlZ3wDQ>BVsBGbFh*WS>66KM15P;*aWHp*57^#YPSpO&9%+(-Hv ze@_;)E@Jl3Wpk&nvwWN=UO)gkN3UtXx8#Fe!WgC7ikUbq@rYSV)Bh1~^TlB}>1+{GbY0B%G#`dw@EzZ9D%G zEkqEfc|s!PiX~xxYKo#m_ch{s;(`x03tzUYA2*I7N^vUAxtYR&xyfx=IjM`61TUoo z>=t2D5l-0+$rTTyiIvoey0Z8Ay)wg-rL}G@Io3r8OF!4l9?>$;wXCMT(d*sialC$Q zrI*jF3sD={4R+JnV1Ah!odK!$B;OFfN7kB0E(F9xf0|c!=_i-+^w&^cJDuuXWhg7f0OQbU=+-1oKy@(mhEaAMgwp= z?ikHN7U{fA(cqFbI|payZ-4dZ?8(#TFE5|(b{9i;!?5kGCkOaQro%8gTpeCs zA~FJT)?Ux%*L~=BJwjYU=5$N63z3CTTnG!<9W5TeefP<4y%*oUf7tj2=9qC#3R_c> z+|t}ZXw6`i0~H8Cc0qR3kaahP57&a@^yEg3l7$XGY>Nw$o-GEE@n2FiIqb!G?hrjU0r5vV$52Ks2UAu+S7V ztta=Z-vTB{3MTE%B~4QkYi0_i##W9GW^a20LyYmfk58g>B5}9n)6Hsd4K*?f)V#yI zjlPNE+^jL@q7-)`NYpDP-Zvk z=+XihnA#7d9ak_FLWx4>x;t1s6QBKkvQd=j;VPx65%7JunaBQj(Y}K)c)K~&zusGX zC0@LGs;FzkH72T5DXV_l=3tugdKHnB#g+Px73z#ShYSi){W?%`zvI3nPd&|pW`!w< z(&AL4#HQXkwe7}#aeDAOpNMT4DKzk=XBW~tXc-V`&?Dg;@Hs?)IDJXUVP-NxQPl~2 zN>&u_Q0|=KvczAH>M{w5a)_gu34$eyWr!WOh^=8cJG_3!|6dl5&p+Dxx1jGv8Gy!8 z1yTXZW72$bak(wRx4v}D05aP@p|OF#cerC?*>=RGzA zsewXOAvA^ z*(ZhBOxLoXDI&9&tbfWrPX!^V3QJWgyu(u1CgvH!)FJ|4${7^XT1xvxg_1f~qZrbh zT1kj+LO>R*SXor&u^TyET&+u?bP7Bzw&s?n9wqjcP)iZ@+m2}b*cAAWpjrw{9Un6< zqCmuX-wQ%aCwpbtJoDQN;7+oiB}N4x(GVh{StMap4L~PC!H)0}wfKvA{;@pH#Ku?9 z$5QE5ae2{HH5eTCoBPZ57&eHw$Y+B+XOM{aa*OM3PK7C9P)H+~yWo>2aKQ-^&zvfM zBrofDEQ2f=m~;{tQwKXWPXa{bgiEQjKmo_2Al7Lu3RQY%Vl;CQM~eW0$?nF*5Ygm@ zRH>q2Z$Iqqon5@VY26~IL^a32*iaKVVIELQFPz8VyKaa^Uz$%$(n$y&|z$A_R zPEl8FACk&rC?J%gj0<Lo_Y9vXlNP0dF!Y>&YnlE3ez>3ax$k=; zZoINGDj$`Zl~vWPRs+>dixDtIFsLySBZf2#5Htf2Gw2COAZ8%cLQSc_Io8fZuoKE{y)vu<6GZawu~nlv2Mb} z&C?J56MX&lFE;HSJl0>;tXjp}kAcADJ(imq6kpP&ZzP*?}`|!c% zfAjk{zxDlxPcHA3C4_aXiY=xArGG=NDe4BzNQfENBuA4}v+E5nd)M)7Fbbf7yMUbl zA|)G^0V6Ub7ZLMSzvZ>HY$fKLd@&_8aRf;1XV87B_g`?~M}cnDR+F9SZhux6;x-Xo zt!oLl8_pIbu$2^`{jp&gKjv&2M?c|!UK+NQ7@~--sjM#Ke)D4H^A$hz#*#&jk;x_D zbV}=Dr7exnfQ6j7ZV`<=Lyl5BJy?FvhOoE;w#08$KSzrwt5YGu&Hc^CF>C~jnI6-x zz#9!%7W?{2Zr2Ohmu*$hbt)Rr74*O)d~y3z{?9T0jii}~ZWcOHa8(@Yq&iSTGf#s}t5jqS)C(ks zf|LbOEJC*r9^C((doSO<`}xnl{Q9pyd;Q|;<+M@~0tn3}Fau#!%FJmivQ=c!n~=Z0 zz)wEd{MnB`xcXZ^xcB7IPEAXy38+ax&`2XnH#bshPhAkD%F}R4dNQQeRG>QFR%lT7 z9#qAo*eOHJJyrHU*HF9J{|eZP@#^bH2f1=I(y)h+q)O>SCk^5I_==RAj}P!r`stCY z1Ax8?sHLcSrNsG{^hZED;qHoyuoY>|DXrVL zalZfF|L1S!|M7#o+-{JVyh zc2-2LxTQ&sd$oqigkA+iDRs7W@M%Vf-isgY!&Bgfk`rDeK7%A^I^N>-_0Bj6r8t}o zxQ!`Ik>AQJRBqnr6A zqh$;j+@MDh(U2!S?WSkCxy`j}1gu6bu(E{SqEV=)<#_*i`nw4qE7Jx3`pNzeF1Oc+ zL3OJVp(+|EQX4|iiFS9TZMe^ckmtV>0*J5xiVPBvT{Az?$t)-5C6ZP=>PQI;U5M8WG(%+OlVSb z4b`c(;c6bD{t<03=!U)wQpIl>mXTJhiEF}|kdw%&k`PvTw7vZP55DvL-}?0@@Bd&s zJ(;t_!UPqRy&+|t@YnnGUp$`v)sKGd_3!@PgAd<*5ExjBK5KEHfJP?6TB2wO z%aS8lCK4rOtO*B}g$4zY_udM1^Cpzl!VtwAWFsim5~$kn8JTx2Z31livrkekz@OUh(f`%)jKm!Js<##qXt5NdbH7HJjZ>g}sQ z6;APRaq+o?Gl789b0}P1NM`fx^>3W)w?gEGuO9CI;L-hO(=H;;z)Vgd%&48@yu6`> zf0Z4nRZYFRs@QCpEfAhk)w zD4WvqF7DPUS6Yi!Yk3J+N>&-#SOk@U1Fa8n{3s89*1C7bb zuZ7ty45v?gd81;QgfYlQWumceyJS7<+pT8L!Hi*LC0bbPbH*60B?CAV^;d8wt^(*2 z>#^Y-S?n>u5GS)uSq&Vr`J!ZiPB}ljlHkUCv&)yu@dKSN zslk%uOa!UrreY{tMM}&WYhw1I1P;u4h5dvokQhLfB&areZLyc52iNo#f9bq7+fJgqY5b5;uhYF@!0bCi7j+5OAY z#s2biSk}D6-9BYICM-es(Eu$}A9WY(ow}VD#M=Q3$+^Nxz-Yos{#BB>jsu}klWLEx zVWFb;*7RkxGXg=7V3fLfcLnukQnuyW-U7QPKmX*#|1!S4eSYyj$YMq2JMU~LfKi@FD?gPrai}QZX zoZJQejZbmwUmbN%;WPjY-kcevg^dNa227LrEfoR@0OM)Fl5DEUmAbl-2$z@3@=5XH2vVNI*Cf+fH?@{*7SDTp!SBocCvLM9cVtOD6WU?ETHZ*zK~v2K&*q30g9Y76E;G%69K!fBWia z*)-Tn-Y&eHw6vmRZDg(yAE<5%1~s!9bGR75F{6P}HqYzyZxc6>QZ_^_DT9i3rM*jg zF#*UdP!SDkAk-`XCIKyFBv=*mG0Xhui;wZY*}r}9#e;uv#G_2AM7L(*QeLsyH)aI{ zvhlcJS!s!uS=MV7IYX&rF8DtqnWbdMgj+k^9PN0WjyJc5+n4L@Vbxjn0eM0`%=!5y z|KU6L|MWM18-MS2K6-rrezb`;0n(s6k!htQKl@`<*%lySH7N}~ojL#-@9#lPo#yIL zDTbKMd(V!N=w~0!K=Vt9T;-BMn}d?PpYSb z^E=h>IEgKT=2ZLdcW75AI@Y5DI@qWWbjRzoDhL5YLXauvl*tHe!rKkLI`Wg+byYw} zGOWpru=PlYiXgAG%^Fp#xD&P3HWkv;VbHkxtIUMwq%*&!_>r2T{GyOZvj4uqt1 zmGM?XSo8Y!fUBE(IZP74HK@pTN;^#=qR2a4W3e*Q6DW0x%|EZ%=32|!d|)vfWkzU1u2)Z!OF>s5|BB>ci+2?`fOQpfd@1-l-4D5 zE1=XVvAyrvqTso=;vX@|J5vnXaPwsUukK&`GK9bowI;i?jyJU|76-@SsL#n^oX$knf2)$~gw9Yy z)CarP__^YYO3^`(hkZ>^-Rtx2Er`{v|NX1aTjD(nUc!0J%0M#_kZzk{u}eZ^*i5v zdif;gOXNK)A`1+j$MrQ?m8Un5q)~Fl$&g&&iJ|%q9s5_i=gDjlnN%h~iN-aw|KI~V zEDvgugOSWHxWhyLF4-=;9mNh})#0{(>Rj6fIE+i+c$&gKKp`D;JXy7bX^06f~DY=k8;>Ppr z{?#V|Fsad7>#)Gm6=0Tqd~^}t5jkZAxXJd)_?iqEe14;c(;h(tvog-2yO3jmh;FBK z8*|kw`ZP+LAMvU37`=K3-vzPb&9dsS(rI3ZJj#SPkQmN%>jMB(#0jcIqNo}fB1FQv zgmooLe~1b#3NqEFPt)b27dOvu!tNnM*;KD!|5`|FLP*R@Tu#X5Hl%2B11MBLRBN(D zf{7%URkK*zm$NiVR@hc<_q$(6uqjcFHnO zc~azH2qJ-2)+&`btl(hOFf>3?%zIg*Q3a$0wXC?UQY2kX+MHFvr#N_N5?<$k<7X{l zP~!=2%+oki&@=KFB07!pqPL&V;WsaLxCSiK6vv!an^Ng-T)_${?*NyyQ&1%dt>6M3 zlDf?xK`R?r)xR{W!17E%K%t2!kloT)9Sc&67S?T6ijJ#ljS_%dWF~`zm739ovt3-h zGyNZ?uMdBA@gGd{y<|sXM%|sEE{BFwoTWtufn~+jA+M`hrrTQ?66iG03^_C9d|1+Q z%4t2_uIqA0w>P)T>1a#{rSD?Ob{+HAQU2)T@BHb1{qNate*c{v_Q)F|0IZecB#{gW zmc@4~Dgkhfim)1T-3rn(hc)EtC>OQ8PjMUuK?pLb#A^5)Fu8b|_vDaaBF;_b;EU0_ zf7M(1szOxK-!-iYIa+3?^5;({9!@lGRy}hqRP~#6`*!!MMcQ}%KDwm( zqmzylNNj-*VgLaE07*naRM42yF&i}q;<^hzyUK?!U6$YkF~~erbhtE zNqIB~RT4xfb4W?jLZfLzfq(=^j{9AD{QjG-U%bxtK9pI+fM7MQB2=i5XpC#poU+I5 z4N+E?PN9avc*s=2VQI$h?aNt2gre&%zSwU+M`;3T6@!#s^_eg=72Mo@d|ZEb3Y&ZK z)zj@C?Y6J-6g1RnSFLNFq^fcAi`DZM&XYh@I`MeAF#kQf+x%&ji}p)3sD4RlprYE^ zQN+rW)i|MYY@#HMwIzHpbFNcToo5RI0AZAnG<+VA_nUYD$w@?L8EdwcVWvW?g8A?; z>6qrOfOHOLp^rX}4n7+QZ`7b~H=)e50{WgE=2T!Ij zagAW8rl3+N<{1?Co23ek2AGvr4W(LNYBi3_SzBCPOj#RtkNIUTwz!Thh_WfUwBm$j z9Q}1WjWbL@lhVNiRB!?D6{mIIqk+UnCETQ;?~ZF6moyhvF;a_V&SZdISHqh0Xna=n zZT@uP7aw%7S%?u=wf7W&szF3j&LIdzFZ7qXyvBT~k_-G;5|(UcCPwBfOiImcTjdcU zL{fpQp{zg}S*q@$`x7?Cn3XAIv?*NNn?8uP1rH*+%JWlxnIS@35Bb&2K2xEYia>7W zJjW!Qf*yBa31SfQ-cS&AN6)4(gXyn!$V)i-jJ3eMI$EcOI`dG4uE*t_gO>7MF){{M zutF{b$;W9uRgR@ii~uS!X?*ADvYB3{)3xZzAemCOYcyy!&8C#e(sVj#UWL{{Pi3Uh zP-p#12w5d748=P`C}JWe6A6*LjbCl%FWQ`xr&0k;vZ=zBK{@>c{DEY=zqAAEE!kVc3Rk~Mp-$?;$fJ~j%&U>rmO4I)y?txkWZ^+ zgK5FpW^1yXNLo5Dy_%QLAI$&N-}ufS|J%QP`|IDoAF<)GWezMUre_A$u^U;M6uCxL zGuh7f?@#Yc%c<1zF6pb4w+3onUtNc{w;Koo1&LF{c1n{P#P(C#hU8nl2z=S5QjExC zDaL8z>8=@UIRN;SI4#KT`~k?h|L6fhMIR$y2&yVVOrmZA6fy-vIGuu}mQOB9SL!sw z{d>50^h%c30-*#zjFJ(uXc8nSRZZfOH026sS_TUZKs(4*B1n!%p(4l1*w;Cc6!my9 zeK}9B>s(kV>MP2j8ImKe5AU7qw_?P8eto(9DduZTCh9wXtD=l5Ju$+9cl_p!4*6#xLSzkvRs{ zfC$Z5){I=p?^1&)N`6d6w@T+u%bk$FTd_;oM?xA>boo-1Q0wQs*`z-`33ni6Re_rd z$9gJIlwBxFK7hqZWJu1OuW?`A`^j%y{Da3=|0_zGKw@peTc{ArxH;ssCUGe0Sf$wG zk_IMeDz@8%%Zu&h{dspeZ}wrD0;H@0%*o!ab_IDJ`LhT6KmPUa{p8>HjoTl7`fw8_ z?VL9vHOcG+d|ohidG^&>?B$ zkh;9qgX<}77V6*VAfjgve8QXX4iSTMH*MYp&3ZOr84*-_fZ=jrhk66Iie`!2Y1ZF6 zX>oRw@t5|L1RxqLCxC`1)7x48nmI$v$dy>laxQ)v$OZ~D61gn2CNctwFa>pv&hONs zk*@f~LD!L2Kr^_CKAaxyr`dQ4xKKHs@Wq;rMyzRh{Wh#N);Y4HYzK~4bliY7iov?gp^I;>vI|_nnH8ka%S6E7Y?_-jE)*jCLkJQ-eg>7NQ4T7 zh)B2bbkMvK+Zq*=2K*ubWw*0O@4kNVi>tIgK>$iWe+damAi|&;A+Zz!(aJXEZBm3+h2(s=@3;=dl;LEDsPULr^DYe`FO9l59dGKZ+pg$+j>rmRC8&(!SsvQfQuiwKsBdFUcb}p{R6n=+N zjwuM@&r>fd?d9tgRU}J@n_HfK8KzISg+JIJuApH_vPMoSAk1Jk1$^J+5%HDOWiz!j zb+i-W%}foZt$fCxw8@)_vb5u(i5P37>FQZb9F4hbxhRb(@;4ViU;;H}P?&{+LOKx$ zr@Y%dee)^)cX;vYs|Wv+{dDh`m!NZ*4gn7zHLB7K zQXI%Tdb3&$DHy{ekENRKN%dPKsES!o_N5?d)16#WmC~-mL2a9$b{yiObtbCpV&jgS z7=4I1r6Yn`i0y*c7No-az57)h?G(irU_D))Y_R7YwRB(jE$UJKaQ6GR{LNWV4Joaq z7EPzq7JqrQoUofRbD}2Z#6`u(m3D)5GBSh`$7Rde7${;U63J5RqBLt3vTLOw8?tzy z2TEQgLnqxo-aV?!vBk{iM|qJa+V*moqi&D+VrpxM;kq6`-v_R zHGB$UA%77>V#qV{tWX8OoGq1QhSb`XP2Z95&@6#kvftt;tVI+a|C6oCr9ww_tS05| ziV!4-1gWd3MNC@MU%r#BMP&}sm3K#jkf(isSLY^5F3O z_y5BmUi}X>eZJR?*s3sv<%L&ob53;uPvbxwc{Yb#r>bCppfT!Z8>WqgXq=d_zKZzl z(e^Jse()!M`?r4jZ~yrCy$|9pnv~oivWtO{*^sT$aw@R0*;9>1JrtI zth4O#TxBCwWGcd0aj6(-XuhPz-r`Z3cy5?1_YfDzO6xX5;HRKOz-?N&J0w>-Ty@YY`N6stwri=h z2*8Ufh0Xprzs3&P+K`I7kb20N?hp~gn1djjQdwP(hUF0QDVtHt5+&c99wwsU!NcX^ zoflVsdC>V$2sy8!5rUvq9w*3VUE{ixje~n83f?w=QfdUt#?_`^5GELqN=`(Sf}mnC zyq)Ifm4$ZsA8CU+pkqAsuUB7NGRj#1@}#|(XBHalS_?U z>$pgh$(qHIq8e@c!#3BoZz`S>CI}Cp*Atz!j4O~mXk1S3Wv^6rKDf za%nLDvEdqJ2-({BRFsH;>>cpmXs9cAcX2BzoL*<)mhap{b)l9fA;T3LU)0X2gD!Pn z^ZIb*Gtv6+XPKvATfw!B(Pc6-L$G0Y7c#&?();hm#RwAnJ779{}B5q+#UORmSfv? zSj~-zx+Cexpec^TKvkoe#9#!J8a1u)v@DjzM6~V~>j2uqe#WB@-+b}&YdbA*8z2G% zvm^pBg#>U)jLRyPy1he#G$>C+6_&F6pcc%u^ce+&IdBsg0*)Jf9p)Dd4fg>4JqO$z z-#g~teYgov^W!QrDZc>K9Dx-Q9p|#1v zaAMVzfpU}aqV@R33ski#o}W_dMTTJA9cW7k*ZHQ#IlP8`G0)$i$72<2%W2Ex~ZcM8NP)tap<+3G6BNN2Ug^C7?hAdE}W|%^)G$kK&wGJl-FI!+% zxgaau39>HbsRncriN|!g%*O}c{l~XoJbDrS!)?gdN4+{_nuIp6Z7_$MHt){jos22v z!|8ZfULEsSOZuw|{N$Yn|MGhu|KdkKx_*3*v#QdhEMP_w#JbA7E?kR(2t;8PJ!BkB z5{j!X|B1oVTs>pjzhn@(E+!NKRb`UWK)ZJRG?tw-KoF|ZQCu^=T@+ZY#c1WFt`+uG zp%q=$sJQ$}C-*%s*d@^ibjS{)%SofmE7oMIoU1z?R=?(~95`k#c|I;Yo4IrA-{fb^ z5L88~F{oujAR!vBV)~P-<=-=|Ndh&M_|?d?9%OeY-bt9Na0A)Is9kjK?Dg$f*;<9D zki=@10%u%4zIQ+1R(M~yH~##TUI0SVWwqzm@wm=9>q-%|?QAL(m3dmr{$G^}sQ^z{ z;dNh$AcN&6>4*){WuDEVjJ~@Dm7dHll#7d_&&C+|mH88f$PmgHKuXKx4f83kN2O(! z63r&t1Rx>EyYC$T^77@)s}DBQ)({~oh@{Z~nF6=AZq`*(25Yt7C}&lSRLKlglhUx! zilr_HI*5o0r}$duxA0Ccpyz=Djy4?*zoq)4NAZhy0clx{ZB24)4QA1&P6R?@ zn5V<`__Gv$5Q8mwO)wRqSF_NXIqP4+6F+Sh$w&I`{BB1$xxn3Sgt2^VAS};L^2yA1U+xOo8kC(6in|c4= zzD=1#3~WygX;!G}a3k{wm@sFo>v}rAJsw{l4!^|dC-3e5@H^l8qaVHZtM7lX1Qn*B z2t<;yHAPu|P7OL60ow{@DFLb;4A+LG44jpGcj0R8I-+m+>Vrpd8xTZ7iRMMhqSK7l zOif1QQK^CUo)!KN#il(gTLi9+KTGo0uTTqo0JwJ@c8Gg6K=nn~B>PMd&)fw(YYqUaI^}f2#z@s^o#Zc$%WAV`%ceA#sQN8eg9BjfxQK&B#~Mb>lm2Mb?cq>+Fo%jY9T0gc(-Pw0`SdINcCJx<0}Upi~Rx1g%T6 z=XdT%w$$#;Y@iNi)Bv>iZmM(^76=q!o#d}X{#(-)Sfw=8Gh)qFR;|_@mzfbCf*)G? zvmkZR9zA6#MZ4NNf)E(8P!yr`Cm4EKRO_RVsKLx&r6m(<-U06I90-ad!x(3Pw3ROE z?k|+$t7@fmpCV*6P|}0lZhd$9Cx3nXZ!CPEq7dhp1>$_OGZj)0Cj}W;Gmh(Wx_x`R z`P|l@J<@;ngHQk255DvH$M@4_yAWn;G-YO1XxR+NECktzZfG0WPB4p2N)sFsZnG=| zSu!4#Ty*xUD_pUf(lq)E*|Ld|0>O7=EOc0|W}!`SxmrVB4K5UAJhP=kZ9)IJeQQ>x z`OTKCzVlTabZwT^{R!NIV7yQHr^;wvsDBXfk9XKnxUi&wuiIJwDN0P-a!JQhO=T~^Rgx_Gjq2)|CjmTD>tf&i!l zl+KC@0VX|erWc`=A+&Tda56c({ry@0#-r)wlg*!RcVA{*ORG19sHkNCVs%$jWpy78 ztO{Bb;TfJmD}yL2L~0D}USnW*yKJJtu~Ew1!AOD2ur@7&(sf;Gu3Ov))^)Vv#Y0_2 z>$zGWiiXYR>*I1W&yOb(IhVbdQ?^r2AiOs(Cz z!%3p-04D%r1e2K2%A#!6&E5LjHv}oAH3XDumRF!xx0GUxD#})isZ0RNkPvgYeDY`0 z^Uo*`rD|#Q&W51{rE^N8WJcA++v%$D$w^~&T>2p`gF)N*EmyC}F>bJTi=11}&8q7qyH%oC|T zF*Q&EQ8po|GC5T0d<#tW3GzD?Xi@;bCw>PE;h?;pTOzpbGw7)->1`>SXDLR<>YC@C z7!W`q*0Y9UEbGPxI{VBI_*K6-mTgSOQ_2X15Z0w8pk>Cz{DL>n!KcZV1VhMcK4s<% ziY+MHT@=70wGCXR5?P9EF&}(aV3w6eLZcDLnQOKs$d->EUOb-c2zes1CjIijX9z~) zYU{Jt@#cC@6*I%kZOl;+L@q*#aTS)mU)yZ9nt?Jwm9uj;c$iiKjiT`(XhcODcPI45 zk@Fds1|5dUsz_KQPFd9I6^%h8Y{I(8x`GtT4S1AcG6(~vr;pR_{b$R1pk-sW+7+wZ zV9K^jOUy~kybE!gbjNEVq?&{^NGhTuh(JJD5UWen>rHr5Ntyvkr--ZNVP5~x{XN*hPgFaA7L7`iA1;P+&c?l4F>2G}$r_I_3wZSDkPt-UypTRTn97ev)OZN-?4 z>pD?MB^fPzZ!Ood2JP*>@w^V|zx8#x>2T$(&!eDPP9h8vHt}XBKci%mlqBmMb2>7w z!VP4BK&UY9CU2mLA(V)KWnaiLIqe~Z1e4{`_cJFzV33E?2M_h$7AxeT00(@Tcmkq; zw>NxowOQ6c6{yUU&cQ?^#Jt}egVv(MVvLPNXiN9qVu9rRod;Ifk)VI-rm(`b8UWMJ zZh}|qSDPexNLl_?4;SGyWhuNWH6W@2F)X*!@jxLgSEp1(SBtL6{mcBpC(jgbkXAB5 zV9W+Hf)a_{vTWAO3R-M@{670sXvm_3C@qN8#IP!%>lChadfg1D0LT!x$So5riA{n@)yvgAz>xr6Kv6Qk@kn|B5?C9Aq z9b@?G3MdK<5-Zs&&Ggg^Q!AdSky@7`4jPZ)t33l9bvRnPBdHD@`-d`2Ia+4eb*^2D z{he3{tKx5c0&9^{a~w`f^Z?MEV0&H;9)n^!)8EMdsNOY>M291jv3`cJon%@T5zff>!ZRC8T~*%688HCEl{jHtfP1~ zfhAYwBES?EOJ5S(IL7)UgaW2CgJfOrO@A8k7U6O20_bF5v5{7u36{y#lG$Iri~r-N z@BhC)`RJ?5ttpvF(^}^%fQl%vE!BWh{JS-oj&@qhl8l$D-9j&~s_ukiBNU&*8^__lh0AV^>B?TRGuD zCZ!lG>9ghZTSrXgVambOsax8U(@Bl?!~UBAZHJNIPY_5sfh^~e&cF{RUfC$u=t z+~Tv>YeA8SLQBR>QfQ=R$yr#o1IhIIwv@v*mYoSp&WR{BgD8_?Ib|9wlcuI|ySevp zyWJ*OyoAX~zd9^eU;s5Ge)(43-cAN`&akxEAOMqMKjo;o)E9TuSv9FsaA1X8(%Nqh z`97)p0myK8zaXp0YAL#b7wz{eX16wf=~)L+PBBN#LW&kjOjLD6JRUV?P6VvBkZg-Z zMJNmp@27k3ygdBnySmQEb2WA*qCsSn^Sq|ISx2>uHaIJ(PFQsfNWM$F0-1nHj&d`H zH$e~LCb#&O8{+!rZ%+Cf@9uu}VE0E;d}U(ZMPEfE)#l$?O5bWf0xyB60e4G?4~jH` z`*y@I6WzDEM!`YZIE_WshSa$aHl?`%H0r|xz%w4T#vFr9uKvMoDZR*4K#QEhFDH9p z@>DdLWr~!n=4#BwNrg0_Dx&f?iGKz?7SmIC7PK5*eJQ^w0c2+7Dk?yz>;p~A(^r6q zMvX02$h9J{$QuDbS)+^UYYTZbTB_z{3m;a&ackYa+InyMS6lg|;Bg~-$^fz08_P_m zWV*-a@5KM-I~V`)NALde#l=bym?S|~sikDKafDdi{xO94(Hy=v$%nx;?DJgnPt9|K~+wL-bC?2~9Bjs~Jp$**>5g?Jvep+4GJOm%@nIGR1 zpJ>P5`JzCe8kbbYO~WQ$PQQ@+JSqaSScYZGWywwvbF0IyQspF+{Oh2;jQ6cVb1ZKkFH zSU0rp(wef0OE*P30;;cd&QuOMjc@yS6yI*;Tzy$Lh|*r^B>09KYOq-?C&BQ3+I)2Eaja8!oUDxzAjE?Q@rSqyQuBqBl7%hJlo zh}Qn!LGSLu{xg^J+#D((;6vba}js7R1*RrLAO_$P1lZ{7fgnWA-> zIZPzQd7UrAP$^YjEkN)B2A_J050IXUGmZl;s{22uSVY)xZPiJ{w^EMc2p9?G| zw^`qs94MJm>IK!+QrdHN!5Ve5%f-Nf_nE94DilXQ7dLR#YCRW`hG;nn; zCH~RiN!W<~flL~ZOuytE>puj>-pQKH_83|A*)6AAk9@1O>m$$z=!OP+6n_5R{#@rJ zdjLg)A{!+MHdCA)Y`&b{zKFXI!MA1^$UrKKTkDpfKw&_Nz(PZ|+ET~Cx3-Gn_LOe}91PuWB!RoGT#f=R%3Ubk_r@8)SqAM>)f zvQ{p*;yFM+9|ekc=MYB;b@-`?s&@g5IDuP1gcgWfOAP(?OK$PuXwg9rtx zLXkD-+YnxhENv|2h$C=3d{6n^5BI-(XZk~lSJc|Ix@=oRz)S>X_mc94bq|wjf(I?3 zxVa^&s~Bu~FWIcXd+gg#ujF>SbDaZ>uCvlj*&U{nXO6jFyP3?&rSM$;&)|^&KnP)( z`LmD_#Z*hL43bzJIonD}=>6jB>1Dlz z071g6^CYt(YF%zREM*XszWZg^YnHe2Lj8r^5>^F~njOdny^))X`448jiEwsSpB9dqeB-7ld72~2Pt4@(1Ael2P zXjiD(K&+^&TdK09#H3LfA8s#a0d)d+!m}maY7oFuvM;an?d=3ef@zRxLJSf_ck?pE zwfb8rwy^{l)iygyAgWugW6x@*duA*)IT`^&HLTrlN!gtP4JR1t4!8x(b!XEZyb9+j zL7ROPLc z4xmPj>ux@%))mOEx1Rph;RV~fwWz5Z6aZpiJoEf#Ls4f^eCtZ~KU1`(rF!?T3o=o-YGlFf@gwk)r@OZo`=2S^vO`7@ zN;WeR2&ikFiY(TZL3Nx Qm5x#6x%LzIjDws7GesEYx&jl#=5K|U93=;vFkKipXl zNBcamWOU)0=5EAOz$K*#frJ=8V}7ObK*cKOF3j0ZiDnXul#|&c;>W8!vG7Z!LUMZ@ zk+N{47R6Ot;`L<)OSX!tHp{{aDawO^P?3mv6NKPm0QKT&;jk(bNxJmOa&y*S}U!XafrmaLMaN?mvnisO@NvOp@B6(P=# zcGGvJ@UGe{gh&&! z)=kH}JlSQagld7!HyzFag`c}bb!+AcK1ErLF-IPfg$D*-}1YP zWoXY*}+x5Surfsv7`Cr6OXRRG@iecxRfkk(Fle zMEZV8^x)H@4|l_aVwz2rvWk=q_(+MQhQmQ};uO0~j2SzjOrlTUJ8d4`99})NC19IE z2v&k9nb&orIio9qoRVQ_cjd=D#3j0^z`Yiv>dYBCF=Ekqxx=aS|2;_j3?tTrJM*0%K z=G+}xRoOrrQ#4ow4nOp1cW6~ZLjeS8GKJ|`IR3TC?@1|EVf7!Y84*Op%pgLVhR4x< zxaMC%1q^PK(G-9kQ*>zqLFAkkiDkKlNCo))RSBxdq*Ez$UaeMu3|A`9kb{iElVN=< zicP3Sq#P zEEH(jgeM!0#BG*C+0tFW5?ea9Wi|XYWp_s%+C7`XHLWbet7R!1=wu_ES!$90X#MM{ ztYc6w(wCn#o6RI*$6mRSz<)*kfuzu+?oL&sPv^F~Zu`BwoB?i!< z`A&g!OLd3zFXM`D`;smsXMR{DlEVs`LB+L#nuhhRmxW7B~Mf;*+n3Ml0^ie z>>*rPF?WkKF|Rdh$(BqqMAXR5yqRQc*a&3h%ajhP0mNzL^DADznP^H82?&#jVl(B- zn1ZIZjE@l8uUiz=NhizqmVLgZXc!fllOLS9&P?w!z}`>>@ZuZL0HhNh=kViu>Q5` zuC~q_!?094T3?9gFz8%s3c?!fb#(5DHU;vwxVyN zTFnpX`{ofUGKI}HZey4rp#WPBZVV1)eI%Prt7(#)&aUUne9$2aM(dj5{6 z^ym)VOaNlYYhKrsGICmy zFkEhS0TCKSj<@+4B*h@Ge08!fuk`j5B?eQIz!;%|ZCH1klZJx(#UPn()y2oLn09eQ z;OqOwbfG`)kmou3^11UlWkp$Kl;BvyOZZ!zTGgpyAfX{LY}N{e08pVO8(G(II>2{J zsJdRoy~O?&w~7xweHpiJbEch6wi-l9B{n%JYfJGji|}5H`Bqh3%}f zZyTUhf}B$t22TBj&&&d9)}X$ixW;54*M{o8Xjy9WP7i#f+I;|~VoH;;1#67^?dChX z@IkbVl#REMz?E3C+!$_67D`S0vSSs8iA@};eJ1YOUmwNB;?kKJQ52q&iqdYns!-`) zSmFb}7@P3)HMh-tNt2O!(>8fcQbqa?9ztNac)!UgTjLMs;HEjYb7bOUp~6zX7es<0 zh^RcczeFGj7z#Hgg-RC<(BC0>v+m8^+uRpO&B6B?iEJcP; z%REct3MC<`mPKHph^<=9x3i{UjJBjTF&izbO_N^6jpl9OHu24hmw~E^l+ug0`RY0> zCV5iJGEE^uX2s>aOmS&ov8hIx4l9)w{)xERhtyD${$Grp zoA}gLMQRKsAP9kTOyWXblr&75)_8j;hRDHc6NU<_MX4V?JU)5y(oQRrq|*v2IT^x= z{qb5m_!Z^)Utu|D2*8MK-C*43pr+J6hKs8WaujY@zVGzKwpN~}Xpwnr! z^F({j8uqn~Kij;S)J2_PyPH1PPVWcqln~8e1{1Ml9J1VGJ)vMmuS0^bH!e4Foh<9^IBw1tk~?sJqmar*-S!L(8)(H3!2gJ8tVobBzuH2NR&x)S}_^b2ED; ztUMvO`t#dm&Jr!1fK<{FC_53AB^;upsL~7(A%NMy!aJ8IDa+X`=UjF);<{kB zz1YSbBxK|TZ?fIaF^KVY&Cjpo<`_*wX==ZTm?%@o`+3n&`Wp&M9kCBr3-UxN(vTML zS@l^i?b71I8jUtYFQeUQqSFJpt|Co4`>YPZtB3%qqMJFZc#jHzln_K14mX-B%`Uzo za1a(y@^o*5_rLSfWMx8LZCOZRR!th0!~S%Nmb<{Q<#N2rF~%ItfDI^M4w5E0&Uzbl zDXNnNZ}Ytv9(=gJ-pCt?iNRm6%v*6$ikkkd5>hos+!q#g>@iW7Vct>X^Dhsk?BvedR-%(CW=?q$9B?HJX z$?wwclUYzVeH$Ix9R>EsssFc}%~FwSEiEmpNY?!(3)dN-8{O`w-6qVXQAF8U1$BC) zHL2=uuGzMBlCn7qlc2b>2SRZa#?EDFjNOT7R=6c`#Y1 zYgxyLvd5XfxdZ=Zk6aqY(HUlakc)DpLPBA~+>sP{kf!CRLtdxA<>`)P95~137tU@d z7%tdG?3_-4ho8+IoTG2~29i0G(mJl^f0H{Wa&TInhOAzp@tt=xh5dcbea|;tLXA)b zD#0dZQxRbZA>N;Uv0{aarOXT`@vPpJzBb6jvWb{Vt`kwrekEm?Q_7Z;nPpRv-L#pf z$vBZ%^DC7#1~uc0LwbE9%Q6#@f}lE0Hb>iUY&#vp5HLzh09fU5+oTvJ=jvVE*|n+m zD~PWNVkgkb`Wv`qqUX5k+_NFOeksy5tj&7SIaN#>3y~nJ)=MFBA!W-jL`pE7ZM~P5Im=+pgrt!yyGaQoYBrmQt(n16l*1I?L_L;f zsvzL{7R?W@}UUorsU2(6!xRZwv?@K%tx#8%NU9c#fP*k2pMQlafvP! znLg%ie!4_<_3EzIKalo^Misd0Zzt5V>b!bEBH+I_j=WA7okA>%>=%WEa0>DjB#J`B z93EpaJ7t#>P#|V1`W?Y{4Otp$kZKvEzsDH?Qqc^UOS4g~EPK9{R@+_q(OGRr zv57m?Sy)p7CAr$|K;{fLiJf zj-FKL$no2xYLuY%H3;gNLn*#tFuP;X~n^`~H{{>`~xMenj6$mU9e@U~B5`<*~xR9&* z7y6r^Fe9yYO12u)y5_*?a(5AeigM*m;#Cw0g5{K+UD@kfJ!NEw03l+dvQh4*(>7*^ z_}-q?T6<&(DWJQ^En1*I)Lr?Q({*X==IjG+9X52Ur2Q~eXp6dkqtJ-e zGM}Q1l0h1x*+QOFZ{z$t#%m3Az;5$Bu1`MM9e3L=O^fZ%;+CH*^uJVXas~Sq#fK4y)!}S>^XM`Mo#|7Rxp!*1rPba&%|M#&L9{4^IYEbU!q9g=bTn+pM-l+VN%lrp>+W z{NWrPYF&73U?LZjgW+IUOjb%RR?n@kRL8?+(Yx8^P&tl)-tKO`^AyTflHmT`+0zox zw*bQzqS9~DjeRwU-+&l*2CYtBo3<({#n`eBa@D~uyv?V$h46p8<0MLs&vBHg4jd1;9lP78KNzt=WpxbeS+l7vB$FcJKqfdXc zN!`>DLQxBI4#A|Bon@*~O($J$*ELaLwx7nGYz+h9jr)gS4pC5 z)Uw}L>b3%7g0Zq@rJyL6$s@%A^b zr~|rvs(@2kuHOWTt?swe2fO$*P*t*$U@{ytPKHC4g_4S+9TFZs5mL=3TW+_5-~K>! zJk$L%ixsOo5mlQfK-ur8wu5N+oA5}eUavuyQP{@uIhSpqiPK0hH*=3O;cQm_4&C3& zFb8|i@dPvl?tgAqXA_mtdN-fZ>Oi`b5BI1Oc_!&RpL2JqKIH<6YCtM2hpEs9ySEqH z7rNbQG^4eBovW^wb-!iXSuzN+(R$q{0MKZ8$tjuTl(PYsyNfw)6DHG~@*AZ|pr!TM zoBaA9%M#L}I$@eLAaBHWx@_lT2+fR0MgJB3K~yKjEG7LgbgC4G?*$&vM@9gzM|Lq9 z;hIy$o%b*oO>3OWz5^WByFa?|EG?Zi!Vxm~H9B#$3+XflIT6sN|TfO(r+lPTt{6Y$chE~BOZSEV7(u% z>Mr#e3h^>IsVzWD?Lp-t*rcTzx8f$x6rjpuBkKFm3A?C$o6GAX3^#V|bDkgDz)+u~ z2Ap_)R?`pn`o$7-ROr`}kw0~RM={k+_%h^|BB7Xa00zs*$HYVl5G#Fppk$8IyJ8>Y zlPW`To=qwJ4F_o$YPXygW6n#mBVa%%mba`fmO}DaBitw=QRZE^*u{%jQv#}IuDV-+ zVZ7SfnR45+fyZF?o25bF{7jJnaMI0o^Zqt|5I9#DfJ7|hLL9R!loiMVlrkYSA5dl0 z-@0oL2g6n*%fpg$kU%Nmt}{HWZhg?-dLu!1>y?sdqBT1FF~00447sLrbkZkq{EYa< zIJQUXsxc&m+9_-k)K7zeqj=Yg3BGaYFoy0S{2!hcu=Isi(GnsA(ae<6vf7%mWy`91xxEOo515l24L8M- z9FFwL`N_7pM^HwvW9jLpQ0%_(YPqYP2qPb%f}THFzdqfL}$J<_^E2VlPk*56qk}$E1oNUQh0hTE!_JD4;T7^Fd5d@ibda;Z5W7vsA zRxYRnZUbeF`i^9ycFNH79-_nGy9cOjbxAM?ph4npdUrQ}91)A$k*jerE?Ev)PLvgz z&y}v(z@lFzyF@rCU%68>>95XU&@ES9jx*#5mXc`dK&=gslQoS+^3TtW=x|2&2ZP8A zIKzJ!Vq(&}-j5EW`Pj3(EQSYh-|1U`RZ-w@?p?o7J*hNn)H3{KUC7<{;*f$nzi%~N zqq1}l5R?enl4#BrG0D^2^ZV1ZD^)!NQAq+bLbMp+CYG6iA~O*tD#pB~-^#-o-E$H5z&oKqQoX@jJDe@A(k#Kr6@(kTjmi|U=jeb zP|Zsgq}h_jG|HJAP}qvK&qW{Jl(nIwHjl-^O6g4Q>v=p`=ThkxA_6#1Nwtua((+GK zxxLoBjF~HcSf6N!Ne=rU?|=AQH`g$Tg`4YTO5Fi{ZX2mFO|5xP1CU4-j~ex?23xMfgk?Dsf+mngV1qJ=|?Rj@$)8 z#E3+$hLiDRSctXm@a4Iw20PD;Q(fV3=AoT$LVr{@Z+@(Z!-?h$%S=%~aYC-olfS4V z?r&Pyb2&MKBr<;9{yTG?ZM24*n6yu%hH7JE*-r9&S*;**0CEmr$~~JMYv&1Td-{6L zNcIhgsf^$_0%zAAALtB;2}CvL3?b7jqWj3iryEOzv26xk8G^t{_a`g6!iY-s)k5Ti z)0$6)oN~5A0e16lH}Al$*p&H}a)iij&R@J;PL#Jday&+z)nEa#nRPqmIi6Ilm|Cq1 zxCDd}%38QX(}h_8DVZkUjtND8Ymbn+=~0gAlz)D&O3JkEP zOq2@eIjNRjb%ausrE2!(Z9E?D02820ENl7%qLlFTy_?5RzFv}1Hz(U>+a8bm zHHB79&{HFV!wMy)c*qMZQNhjTc8*J!kp!pwK-TR$53c5L6ewCng20P^%Buv7MXJ*7 z!Gf2rKwz5g z?KU6IdLgAb1QWSt981=hntCt+=l%T#K0qw>#qP)|)6$YR99&f$nEs@0##q7a5c#pK z3>;i|o8l%dt?c3(K|t{{&8$ibRmLL*_Qx4Te@wW)Y*#~31on^oP_`pHeTQz{$2YHn zIb44fc4w*N8~>fh9i4vr#{5@M;wRFlLN(KhWQjtLpYia_xEM*Ta$Q$ni$H2WPQo&B ziR#MjjCsvRlQm;qbIQyT+RRt^fF6;1 zIXtUMdDPshE$PXG#`QMYt%%663Y*NikTx|QCG;Co+XY!h5g%r4NXCuuW{?0^#eShW zk#3{C!~8tO7iw=HL5k3n#Sz51u(n31egyq{+ zj%G^hLMBStj4W2TLkOT$cx^!~R)&a#NjE#aw}}@~r@ENHyPBHs6_ zdA63!8*bGsx;GpZ4EEqI`WgkK>u?`24-?CkzcHlkyn-Ljl={xU!@Jq=95P&{-NZ@G z!IM>IRm#F3zOX}EDA3E>{{MZ+`P$Fnd9`N?<95z$J8btO}*o1r$ zR}EIZZmHe(Oqbhatbl2COs!md5U4tTRRA12Xf^A-dZpUIDmcx!dksc4^CD&AkD1s&hrOPo~4y}$?0gByX)n_ z^_vH$!(?M63XzGNBnx(1%z9;(jPn#_cX2gEgc*w>uNP1Ed7e+Oy37a__7&c%^qJL~ z?v)-M4HVj$8uX^S4Nz3T+dMs_o<=0>wLJ0wI%K4DBRLGcDf07o%k7*lYQb;LUuGuB` z(?e}?U6oyVpdlAqhYcCfV-v{w~~)x`mV+z87*e zxvZD)87)A(dB66M#iyIVB*?s<-rdbl112p%g2nV7Oio1M{aLMO1^CT^mH{JS#*D(i zwZdJuIdBu)@Yg`$$nY_|oT`ps6;W}nw}-H!SsUzO6S=`cvL%6<7@au+@l6H9j0<`)O4%x2qIX9R{Una3WUo0%%X(REd_h zBTbJjTUe?-5FG2$%W=}?4plkD=Yf#A;Go&GiZjGho$XYKYSU&_6}3VKQ-GivEZn>a zX&L9b)$G!}8wuFDd30}i@7I0?9(dw=?>3Kz@Qx%6bJYyAiqlkA=_e3VkwLeDso@Umj3*4l8Q4_z%5pb0J8n$r=r-F^@W zCE(yFtX4@#N-4Y4iQBE-+lI?YH!49(w*aq&ZfDlO)9;TyqtcGA!Kh%KAM7{pPTU9q z7`bMgGL9L?O8y|%az>uLQ3p4y@Tm1b>0fT1JbULN;&a*2#W0d(%DvXO1uyMos=egd z6#H}CAzPZ5NjsA*HtMWoyGuENayJfOpU7cy`P5=0>nO%vv!P#T3Yf)r2B2SmKgX z1}vpDrIngBU>E0EFS*WQ5~hW?PP7-V^Fn)l;MJ=g<0gwJxZN>IzL-yQT#KfMu0L#U z*k8Azud>{#i4;BZqho(I0jtr3^TKsvx{~^|)m!#)DpjruG?s(I@s2y|V5)MSS4B;q zltSewq9NW~Pbr_nkbcjmG=%9i;gj!vaqr$stjgnQxwUnDc)I=|ogOYHqy+07s-eJp zA7I|#bb88cQDhhOLY7Hk#F}(B+oMa?RW}8Ps}iKu9@A1Y`~Dt|96L5{WdC5f?jWY- zbL&y!PPBb%BHBi9WJQ`0cYSP=HA*YoYP7hk4Wa88Tk(#kb?cEawDq?#n!z$xvm+(3 z6a^I@U^1{ZgY4A&r$%hH`e3h*Cf!3O?_|ee)W2y4q?^SOjT8eVnB&Fe_Ptpzg#syk zevS!;gcBvPbd73rHBLpjo|2$3v+2q}3O0|+X5}0)_>B9N>g4$$eeN1y8*zS})&ZBe z3+a;Pe(#K~@gb1@O}qv4U2AZT*6)1DIMQcPX8CUL`k(VN>d+Kn<(V(VnM3ktsKSaC z2edZv?Vh8wxCU2lH}dhWV{yipy0buMx`iex2qTI+TOv}X!-E3l zJgsp`<+(MOP(;BXx7YD_bRM=R3!5wyuEIn_^5((AeE-ug1uL>F*Xw$Sr>n>7i}x%| z%L+@L86-9vh6xFHcKCQrQ;_XG=H2|p1jnSX?UQ|;<5JvFwcND}d!;-e!AUU=A!m{G z>L<~xGtV@lze6AHZVM>>t&c4`%|y1d&#{&BN%ZB6;~bS(>24aJBda!{4fA?xL)x2l z&jQxJk1J&ZHt{pqO`%xXt+b*(P&uQL@=I%N%SQ z^LAdM(jDVa=)&sxtO84yt5Oc{dR7i?n7(J;1oREW2CDHKX1Ht=UZmv->H^0gW4zp^ z(FeJuZ-mpFrnm}BB|t>gpumLFDI5>o&`FCQ%Pdv{Nl^>X{fv*k_m|u4OQcmS@uY{F z%U7R&e0cH1AUT7c4A@SHiq98(@#ejQm_}aAH*;749P=jS@aWzW!>RRlE`yS-l&zF) zzp4z;_w05wF<=Id!!SnKXBGs4ApP201MAAdnaN?MR0Wfr_6m{7+En9 zyIB$cgUbSYb#RlD7WFo;$D;RCO!1l6OVpN0K((f_Cf;T?KEBKysTw~Ke7clv^W=Pd z8jckB{QB`Zo)m$jW7U1 z;c54x1M=^mfkf2J<@Wvk{H~e;nOKdd6^D$4NGP2iycI*$9CRf>eY9dRtlxBCF@TYv zsISoVyw5nKByU(-rg~yPefy>+5k3xsytEhW_@yg;PbjocnvA+$mmRRRIgUFRWEj!@ z^38FT=@{%Xfy}e??>CIIj1h3ZpMM}g1O8}MzD)7?y#!9!boncT&CaV|r}BK0ayu_U8fp|}2pX8<&5be-x39FbG;M}d zz!!**9>03$-Ct?SI3_MJo#g7~;mhYA9S@r|BNG`gfkxyNpDhpG9PTI0v&zNxMVJ@M z({T-#AwJp!YWD8g1gi58N@)bvNwE5MT^+qz-i_msJ9IFDA#50sN$V@tjv1$PI39G; z8>8hv`=QCM47I1eKCh!dw_|YMUwuF|9f0v{Qw3>7D8s`mAPgF=qkIKOOFtP%r4gs4 zT&=ckC_K07{W<(7F^zYxn!;{fM7&uQ`)Cb5(F{2wSzfapjVozDsBu8GqgHuvSQURy zunSZfW?Wo^hx>4U3L8Zb`WD0uzWC$;zO;oP88z&;?_A992b(~EW?T%5VRh?Y_6BJ& zz}@!C-O(0+<1#Zc=?!PW3y}uPb?2)=ZE4X=pZvRyt-j)r8aTsO>_^_cN&lzXmLBka z(@>xNFoLAU0@v#iXP012|5iNWf9U}7TVPdtlYS?6t8L<%%(e#`_^rXL^Z^HOj<(8k zYse`JK#RLgyxiYpTkAfkWf={uG$Sg_KWT(fU`ET9OGllY@|r9g01dOoFio--?lt5^ zU%Xx4-kxyCxJl{R>*;pgrx>$}s9r{FLf&uIIIXP(SFs3%7UAIk$Xc)5*Nzt}+9usA zT>PIZ3SOco{@w$8@PRACGfqKG$OkzSi#w9veF?-mlZi{MSTIu@cCzd@A?|T!*;s4 zH@yhKat0TDGKV=DGCW2qG!TtmDbfsO@tS8;zPRl#uE~LK^#Ojpmdj>!ww2wj2XyP~ z?EE-pP2}03+2CP1&UVi$-VCz-CZlq92z550)zQ$0d$2cEA{vyeu2Djo^e==<`GfiG zDY#wJ$x0!Rb3jyKi1IsT53{CjsoZ|~K>33aJ)?cDjQ|KU$%%)|lUXWTa4081Ae5%4 zIS{GTlzUG=gh3G}TuDxyO>9iLsGAa)hmZ=T%Sd>9x@i~r1H;wfXL zWT4w8wgGFub9gscg-lNL(Cyb9D?da(gW{f9?#BECsZ@B?b8%?jrnR0c!(jFaK2zt> z-}pK0MG9gVDD~mgvsvmVaX0{7s9iEpfJfh!;{2j+1jNe>eW>YLaOR6#smf!QC0aVX za05~7(lx5m_=JNEqd-)1HS=M=m4_E^LF)lzQyT(gYfBwONFxj|vvkTi(M%X-jZr6V zqCAk0sW(TyIOXFh zZyb*oii>;UaJhYz6p0G6r}vd1d&Z#aq6<+&=>FL_V9m&m4$B?voeQBI+pcp4!m4JE z<9g?-*9mrpP0nVba|cz`3q%->EOOHgPSpYNi`F!LQw3?7+Vx5(5CgX1uat-C;iS}{ zk-}rL;}9U0@iDVFe?YvKtpw)cliY*x#$drUxu(jiyQAmWjL60{=L4{sWs=Y!5+T92 zii1KGt%HAkde(A239{M72N%<$P1pyGQjQ#)YKzmp&QoBL2K?YNZpiqr3nR1g%tz&k>s}v}=(7JPBHghx=@_4?36kIYTvbM|Pe`NcSlvFH-e>a-?MkBsYeuhMzb6V>lwL3# z@90$#CAl-2-F)A5hyEU_#?tOVrzt+VcO!M`eOpt1gmPXs5)_JAeX(qo5@}Fs3<%Uo z?n5t4nB&{y=~c=&9OY!|v$yf;&Al8#7J_!MK@{6=(>x^^TICFL=P-$FMugrCu=UVo zpV?-HIJ!QqXmJ?)hG&bbJaeV(dX>w87Q9qx1OL;2Y3hfO^LCwMD(zGPRRkI!5)QZX zaj|;lkf9!GkxBxM2n>QpPx<6~e-*+(jL12q>Gj*EU;gyRS1+HeoEMAbDsOJzeewLG z#EEvXkB80njpg0V8g`rTU_XJmmdmoBkwRJN+4_o(g2chaIHm)PYLKP51=d$6qsF0d zP1*=|z*N=1jp5*O?}P_6ts429QSg1aMCSN~ z@MYN@Q%ds_3Ir?UCe^|ScPc_N>Vsf^*K%ZkEjC!@Z$03&Qq1Y3mNdZ(PLRweCV`$H8EOhs5M}-3lA^mcem4{826$xB-Bl{%2=3?qR{>H=>Ghj z85gh&=FBCd5>TwmeEP6@=gy|$8+J7xNGQLTDiE^K1ghcP2dAK!%-ZZ; zTh46|QD|A2Xhld;%4^Cwn-Iz{Y1Fid@)(>IIq}7kuGb`|g~yd&eQ|kQFY+u|7$nRA zQ_TDAah{SuiL!vF8vTJJEL}NaLPOnn22wtkjyeQ&XX0~j!Pcjx8KZ{9=+3$Mo+eVo zdK56BT9+uiOpF0PM)lkxqFd5)kd2-b!) ztWK-=JJ+HCL6kA+qIw2`d&1Od6q-pLkV+%gYV_9^%C;xI zQzawaEOaB#jjXJ3ADI7P@bPrP^WHR54` zG2@+kWreRJ8mYBh03eM(boe`fBTu(?v*m^bb!&1s+uzV08r#A_#L+#Zn@aZw{%N%s zJy|#kbJu~gtk+S&FbVFEI({73es&H>>dO8mTMn$)>Kd)us$xRpY0|$U*=XSg3~ttZ z$`;x)lxWx_hL6-fUYRQeStr^Vh!-drn4N{s5EF=)PO{zV!+m(?a`VA{dVe3E&hdWG{e=B)dVFtsf1`VlKsH&8 ziA+Rx%LPD44+<-X*5$Pj+@(8S0XDr{x|+K#B5XR`)>3%BsM+yuAt8!M7#vcFH$Q+2 zkaYM$z?1syhOc&l@~QU;a|LgSorWI8cjxgL8)UId`nP`iO+eRvF!VJjRVwOgzKUb- z_z(9MRf5Z{*h$PbP;fnMQ5{hgaZr;A<0{YQn%ckW@G4@mT4VM2J}7fo*4>=6 zs;T1(@nc9Xp(te9t#MkI$zmr6od}bgo3N%qZ0-sX-NzDQn&bWg@BHA;=ga5WWX%N}#@C;J z@7XUuI8sjJ_3eXKUp>i765DL&yxqTm@^r$(sE@a?;-Ge)VsL7MVpqFfBvGAW($3x)OCSb5dHS!lfr zRjTzD=|Mgn*SU3Y(QdY);W3A6hDOHMTyh=k9vR5+tb_b?`5V7_^i%(O=kHy>Yg?2v zH3!&=!RqC_q3M8?8WSdNy1(Ij8o&~1j_{mTZO_LhXv3LzpI(GU0JLyhU%#%Lx4MSR{B^r~#&mIODzVT;KoTGlLPU zs2Ol|`}pgheERy;y~Ao>zJBuZs}I)<3!B|0ZT8n(bvrdbw;HU4km?QlNN0b z1dR;8IzdTwGg@gAx|c%nvLc0?^$?uxjcQoNaipY00361*-j4mK?wdzRZHA_6X~RP` z24D@+n$2ooZCcsuu`3`daLljfkem`X)0cu*b(P^jQk%$|H7^W6!J8!=r=$e^jWzEw zmMW2r$8;a#2B&IoH#`kxjpL}yk`vaWawFq}s4@nb`pObf??uzZraVz2yK63?vMo&&T^!3zS@{n!w%h6C!0(7m&n$!-o%!(!eunL-qO+ifkwpVKzaAWf07kr>N0_NmbLuoG!O(3|Y<-FYFOoBS?Kx#9Kr+JVFQtQ&V=m zEi&rb=DmQ1%$&51<=m#zC96t&sr{&o3_`y~9Z@$LP00m-P@-_&CWMuOfDphCAjIhq zmeWwXH3(0$Sq)PvMN+)n;-gQ08sfDP#0o{`=Ji+az53-tJK)*#hi`8#ld8$I-yP!a z&0>p6dhbDi7$H*E{Z{fv95#;P+R#)PzJ@@Ceu%><)tCxB$zCBjQG)c!Om_f&Zp--% z@sn@-$U@8v$N8oF@rrR0ps9O*ovLwOA|ak{X02wh60dbYRdm%6hR?l5yx8J1_=Z3b z6$XU{(PPG&WG!;3)`S-4_ayxAluXJ{6H*&l7CEGIn$?#1yOehvCZUfNDJkKU?2zpU zCa=knlF=2Y`c`gkWhm{f#E6vTn0dSMZNdRaF@`zrr%)D)m9J`FN@F6x27<2*z4$}I zu|Jzhs&2Ou5$-KVqc|o_yb6FmS*)j*e?+knnZR&X-&bxg=h(kdL6!e0=1?;vm+TFz zjij3rR)@~Br}GWn>bEg!?qb*slwf$W23MSSp_BbR4d9VYb77TIZ*XdGGib**9V(|- znWn*rmzGfV6!eT;OEQj9-mcSrsqU#ff|TSb%rFN&ez263pER+OI&Q{NNX~3r4su$N zjoA#4?Z%cw(TgAxaR~8svX={ZN_L&{7cVx)n;m1!NkhbSa!dN4i~?a|+{R{^>C>(khVq-jCZ!p<2CcC+)J==DjBM;&i10AOCk ze-49K_rs(=a5&EL=gP7jv#`PiRS6mK^-*#QBMbLMp=*%wxhWvDA_qiXxWHe3Ws3ex-WaNCQ*0CD|!)$yh}!hB!~Vs2f2* zb(3TpEE2R@TIZ&|J+2JX53!c6XhQ4|3hl{JdarAWv=Tabt!d1sXUHrmYb#) z8&%Ol^DdsXgtrN5mZob4t8)@j5t=apiM0_w4Q8dc;~>fG&)>|<$WzI={s}LPtx#bHwa6(T$3}aQI zeiH~wgSr~M)={niuYO01P9y}(`=nt7Cm^awl)x01qttYx2gm+Y6}`0(q>Q!X_~?l} z{_tm_3CLyfrwI-(Kl$oUzIXN2lU39d8rR+BL3k8PPw&Mkf>k-Zi?~!C%z<5J(pz~= zWm)PjKdyPro)*V9+W9&Qola}2)!}FZhCa6gU~<#f^{!u`%k!B<@dJCj$nn^->N*+k z>3{FCUt{y`S==j>4kHF^^k)G#t<_!+AyDEW#AC3-?QK3m zj!XXP`Tq5r3&>QMl}Tk*Y^QW@cZeaQaj;bf+JKyUTd7#fyRTJuj%ufyrSMMhF1)C1 zSPEb5$2AFdqCf=Rd&K#!G3y(9g?u&l!^8P#TP>Z?V7uKqZ4M*_QG>)FlH=)GQ|c1c z-;`(xH)+5I0K&y3KKb;galSPvh2DhXbhvo+m%sVy%cohG&E`38E)J`u3G(#5NK7OM zD{nLO$vQKKaO78HvpjiSDNNrUvO!b~$*ZpI{sFuFl&&*HEe6$);dpr5HeQyli1g@` zZVJS~Si5)ihr$@_Nn9A66k? zP<=0iUtgJ;scWP`9~f=I<8o6Ck$Rm~t!{2)gekJ5#M8<{=Aq^TP`gtD@O4$Sbp%AJ zA*U**AoGNaD0}4w7Hf|*c+n96 zWQi$TtPYY=*8>xk&aD_5s9vK^ViS&O%A5V^=IUfJX<31!SQbsI%_aR-{7mD9i+D@p zqeMWXMw2J+e!abXc60rytt-MrgcZA2S5Mb?VX8o!_Ia9@(;+&JjLMlKN z)dBjR%kG_Dn>FK^;`(WVmVFsT2<@-!Q^z;mWJ{NLw<^7K#JvVtbM_UNpftz4^Vsx} zs}_dsbDqOEafd3^-+0c(ZJkuh;?53$DWIH0-%j>?ksm6Pw{xr$CD7Z2r#)t9WoA_Y zgIvtvw@&;|O|n#>>f_oFdu4yBowGW;O%&Z!l4$stu#6R?Lc~NNqS3udheq{Qgiy;U zDgv}($D%&Pkr7Ouj< z0Vx7Q5~wmRlOC6!>$5NJ-T%=v?dp_iH73I|a(IF}uTaIVI_a)2fCQQ`WHUUvOqZAT z{B=Le1xHAOtdjH9b&gX?mcofs&=Vz*v*-kifq~0)KHOSbuzq$GUOvAdB2%QoXH?D-Gs18Js^q@^XB3JJwjAOf`}rlhmf+1LY;uK6+8|2DJu{X#D|a9 z$M6115=m#$=GY%13>oH7dLaGS1gY;#m^(aG`}AB>Vc{50s}KrNj?w>J9z z^403WukHV6(Bl?=-FM$`Jranho(xw@As?hN{U)Hy_zkh|<&q;P=G5O)+%Q(zb5*Yu z2mYx~PN}aFHhTdYa^jNgka;kkXo+4!(#(<|2qu*&$Q)&(GMAcqQ0oKKc&z~MT&sp^ zn?N`hKfH7wI`hgOb00MzgOX) zgZk6Wy1Bf3V$oh-{pzq>TM3BFd^PwmTMh1=J#^QN@ef5oRkWlh&3L(69zH&L7~{NO z;eib?%iF{0=dTW{r8Q$s%;e2tRGA~9nueUiam6bs1e6#tiEXFT z{rzbQCY@!dvf^UMOk+*X0lw_JB7LvpsHVaaUZamXoBN|@1nGY@5?JbJurS16QI5d^m7P01gpzj0O5G5wt9i_j z$po>&jkH+Gok<;AlD_OK`&|ZljZT_2AH)Gsk4Z{tRA;*^%TCBDGZ^9QYl{Hd^+xe2 zWT??%u*EL^`LBNXumAYpdG_}AWTzWu+GaHgDsglF7wg~ukN)TfKls@n{{9dD;G=iH z+C=;R(e z#fg)uR3%PSu@zfURg}iDt8B$Cr!7~i@*}azwk*Z8W090dilW$)=zBci0k3cGyZ794 z&faUyIllZDW6ZVo1#)q5-)Z(x?Y^R9TdM_X7b~S&Jr31-c#D|xMC4;&7b|v>eb`|_b z{ZQVqMP+w97kTY3!(w6m0?Zt4;!*CZ^dNEnv!af$A)^b}b==Vp4|j z8QH%Ayi44Yh6VJ@rC!&%H|)gE&YGaWjC!)MPfqq3Y$lK1rVG^R!LmwzULcpof0@Q0 zPM+8*T>?+lgB3gg?luxAIVH{Hq2p#GtyYn3>1`Vfjcl~mePEz>4MCs~SMOt9^DAkX z*V$bh`{Apfh3hBjQKzN%YEvOZhJu}7AOe1KS7iZ1MDs5f!$zUD5pp%(`p3_F@}Iu= zXVD(lGuqrtRH#bj#F=d~o<2Bv-|t`j(09J@Bky?IFPuI2;=9h?{NeYOVY{(qOL87u zqk9*Y<%b?vU10OOU)cX2gYPE6((hz8CMfQ!0fi91ZdxK(ncD%<4|uzA($=g}+Ubqm zW*Dr^Dg`t;dp_b)$UTgGI0FCGsGPNt2--=SS=sRWo_Mg?V9)04!mJe)QVZ({+fVw~ zt<%RI$Bk{fKFHi;w;PIzD6{}&I!uSFYV%y4eev|oH*Z)GC=CJ?6_moW8&{{hStHu# z+&^@Xc~}E(L_txpMiZK;r*mltf6|fD>+U2Ym1`ynfl#Fe#CKI(>@xyz*1IYlgghcb zfPPbD_VdYShkRt=UzY}j42sj!Lm8VL|4IO6MW;$k8OjER^g2ww3=st zxdhFmLq&N0MmC~GJs>S5_DBQzpLH#kWN3Bgy(T9aJ+KoCuS$5ie4a0vQBb!3G$Z(k-2qM9IJ9+cXY) zhsj4VIhrHMBtFGXZ1c7C$oji#MlGFh3M z!PF0^8I95ZO$A=#cJe`Na|OOn>D*2|PW}tU-*&yUfMT$AIPNmnk7(w89JUEwv;Xg@foQ-fK`|b0u(K zB|+N3tYWAY<=d~{{wH7hD=+MS(gZrq6%^HxYR$q{5aZA`YBp})CBOc$8~^e9KK6T$ zKUwCjG_VQL&`Wi{hm`V|wJ^o{i0XHcT}`|z6gAIk`B4XwB2vIXpn^E*rn&hDN1?mR z4ErSEIKVls0Mf|Gv`U->S?SENey#p{Ow~eV77{G*s1VH{l*i5wXQ%Dn!v<9mcSH>& z2Gi61$&Kmstm(F(%Apl0QbyH5Hf7imG(0$PZg}OTlUH6p19ng)V1_b4729#Td1F5m zX230|SUAV7p=PcMDq>lZ*0+T0%YS4$GLysOb-?h(i)9S8L~Sf&Jr7VOk7EU3TRb| z$vd8U_S+x)`g31?_vLgx9Z*@Qqn4BH_U5^M`~2*|AfaXv`xk-cag$i1Ug_d#-YkXb z(^zQ&(e0DdVI&$K2~n4#3>C!&Ea;G2dY)v73XUfd z&*0GyVj?-GM>fvG^3FmG6xr%`)GkF&<0ek&vPPv$vtG@1z6l-^wpTV=e0X1f!wNwa zZMp2rqW1(w?saN-4-3&3WIcGKxr(B9Z1UzKlV>QS9=sLleNr5IIhF|qZ@rJE*T4gYxfu#3q(FCJfzfP2T4GTVp?^u zi#Gn@H$U>}XaD?t`yi#FHlw(A;1sQzsmf5SY|3_fc*n_q@@H=RXK#P&=i03&W*Zs? zVhbCbDn^oqi-#C#tr)Vbk`Zgv>`{jG)cOMTxSfBg@Po)QAU`w+&hmB|ng?vt1t!FD zHyrW?=$zv)uu2iJWe{>Sk~KTUYP0givWR1vEP+Br%=E@?f9Ga>_60&$ITF@kGjHV} z!tKpsbGf>P)nT_SDjWwHMTTaz+4ZciPWtT2+pEh{4uypc5S20xh4b0=`h2%98d-5k zfLR$o>Cx+6a3g+y;9B;WUj#<4cPTBN2*BYFzVWu7dgAg1-gH{kWB5R3kiUn_hBSi& z)X)kzh}15h9Y9@De6Z#6edfA*XIU>v^q2Op}~SQ)C7qUC(V<2PPCKfe?!EIE@NSqlIN&`SP}r;5Ooz>pt>6eB*pKt zE-3}e0dC2aHnPYOGs>qk?1liQvK^n-tCv;ZO3X;}+8xFQeK55fqejC_gF+!J<-Mrq zjTfViPU=#SJ(Qgbz62}*&;A>|*w{5e7UV&XwuG&X(Rv%sN-BiH=20l&7@6VpVhwY{ z^~`JIL^g^E)!U1Pp2XV5hf``}HChx;d(?GhlJnp0pR5HYT^6jPA6?4fhw~LhbwqkS zX&BZ*3yOe3BTBWC>7_Sr{?0dk{L8QW#q07;;L57seyps<#$oFpr83%P!1md8E1dr^Drn?e#6puVVs+qB0$H z7;*dNeb^}&DOZwavOS${-o6?O2k5?WK5WKu&<(B0$*5`+;4t$|E6=`u^3p3eW{lXB zR;n4b2t-tHeq(>Kn^nR-3S==y5GK&82y*fnBToTy&sH+BD1hkFy~dNXsp}y0>-XRH z@+)rv{igd4x?Q4I=~uy;izCd8SW`cwAtL71CJ$jGQR&vJhx4TQQro6Bt zc+K}PaP0q0Dd^oFi6fO<*bdikTMHW3YuI0y>%3&4f=n!Cc*TYKZlISeK|tvVv_9ws z%fp2B($$2<{>eE&S>#6mza_W>SPr`P%9HTS2PxNE`IZ3Mj~w+m3r%p@xHn`;u~CFH zjJHvKV4j*}6OKohJ{2`shDaBk%#%vAtm)tso7!Ir6%?haK^t{~>`ksJA5>mcTvWSg zysW&ayg&2JgS~O!y_pZ=x<@ofi@u>~(QTBGAvT#SCy)C_;~EF^U;{^U>B6!6w_EFWd~(SIH6Tq!`u`YwsN zDcR#RZM#y0enQ*xy^eStHwaY9B#5wfr~g6~^Y=;~-~geZiWHzg+-%H|?@4{Zcgb0f z@KJ)B8}rDvi2-Ag>0mm_6F2TD=Qv#@AYoRA;kA=;Jy3>O?u>l%erq?RoQ|qx1P5zv z=1ji)aD3^-vx^5iD}%X>7S%xjY>M4JyBanvj&UdXPyOujk*9$?7Zz?41OgNBdv+SA<2a(uUk9*Q+VM;yJPMA<=*4&mTQ2cyqgZGC>W%T9XvX^~% zCB-AQJ6zaU?*2y>Opidg8!wUKR4o(3k%_>{20-UQdC~Nre&wUT_tMWF+6Orlv@65t zuM2TfQ5{-Cfow&_-RnPn_`iMh`+wo|$y=BWyGyNgrVKe*Vu^xEl*uar9Jhi(ts zqEFsx8_YtQ@Zx~yUpssG`8)Grs~a)TX~vPPVK=s$XIFzSi~w1z#*RoPG{43=3IdoR z-p<>5^Kt3N6~*fq3~5T%XfZTC_RK5qyLj-MXOF*uHpZrk1qaQXCHor2N-hBDl|Mri z1ELej#grZ`W&jKz@02#z4-Cvb+J#h%4IHs8TQM4 z$V9rY)nYz_H!T&PhO3-AHukvH;xWVM3}AGR$SD&%g2bFMsK$zIp#==izOlwOONh zB!p&GL`d~~s}R#%#`fILZ2$I8eB{@MCvNJrgFuwJk`srJyc5aS*5eUN)Kn5d@|!eu z{(~iaFAFmfWP@p6Vs;B38Pot6`mN>wfC3bi4O4FV(k_pLf<}l)A&dKn>TwJ<)g$!i z?^*qku7h3pj^S|;I1*aCC{6F)x;z;4-XsB#1~3$CPqdh6u+&Tb#){v zlk#K5+X;mjnU3??rp>*JcfR=C4^YwKn5<>;Dg55}`^c)mIbrl~EyCh2MwbRb z8jqu;Pd+>rJ2~BJsf6etr0lPTYKU9!15kYAi}C<~(Hg7?O=-o5*WNgP=IOT{Y-`@+ zVH~$Q-x*)qZ68WpnUvr_5z|Efm6Q7@Jzf$od13%q!nT4{=yRDdu;M`7G&4bYIVKTH zgIwfbr}_3!FzJtpZ^a$(rQLkzdEdP~!5Wr;U$+QL1fsuuJ(#FM=Mn&uWh0jH6N7GE zSA3^8S4g4)czK7)b;DIf9NBdvV5<6-K|VNHT}*3CoW~A1wdalE!(*&&lr!?szb4yjNWJqf#PuK+FAG$cP4akX}9 zm(I<1oWE6piWVsHAi$cJf)FzyO~<*~@abos`n!Mdm%sM#pFeD#0H?~OM~ORW)X_xga9sJd3ma9gZ&p;)*c^8c0_jE$R;u`0oC#3iF3j^*}jG7FOKxLdT>}$f+9AYCP zl$dhA>|Iv~-#Qmy(ISB9`K^aH#!ECtaspEHaJoJ0P6%u+?r%iTDtFI5UtWHhQaKa_ zcwMJwU){d+^3B5p?u3O9p@^TmQ{b^1m%H6TQg;`NnG!$~7&NYdKnn#|Yworw+;%%Y zSVT+{BKig`@&t%-+D!GD z8DWk96v%cn4V#&!sv@J#*Tdn`c~6Fa)BN~WMNzgTsT0-nGMt@!$fE1QueU^OYOmBw+xyo6MBzm zYt>q{)+|rwW;}64XSzQLlJstG6o-}WR@3{uXUBPh=AGt@y=|H-QnX&u>H8E{EvYDu`2@jW*WCCdFNfM&frY2r==Ey*tm0srVuRkgra7hn@My_fgCB?m;9T0$2+v!&> z+Le@3A7&m6Ow^)2Y<5$ybMM{=6&Qx{LxQ(dd3l3vU|gK>=y5r)2jJM(T-GYwrEQV( zjMzm?i4h|bI(`Rb(N>yJ0*F#nikN7%4Tc-Tmw)co zfAF!N_)XirT^dZqQzmK7S6SZ`?sEZ6O_9yDSUlLS-kQs^imV2v`fL~Nu=F!S`}~pv z8XzVn)_tFes1VPG_h2jqN)re7>>eS)q8zCeVoISHP)X~p5z&L=2r%rsvFI6A;*hG< zca$uf0apzt!+7g-FTDbXdb*i+o5@Iw(9LK?N`cK%56V_gR1d^wUcK?$i|5l^ZS*{+ z$UrEBDzM$Q-8sKdKd2P$WmjhHTtLC1E^gk}mfakNhaFZmv4^?C{o1rBgpPeuX`^s> z(BARFSKeO?L`9sPiFgv0kbWnhS*qX)Col@gp|gJpy^&ne)iPqGF0v_Y+#bA~u8d-J zxV{*y0!u%|u05gpG_)qQ$=pzi+KkUX`+=9Aem5I+C@2HLaVW~mTPH6KLrYoAB%8R; zn2QiKOUKx_2y2ggE>mD15RTroo}(Mc70nDkQ~It%6k}y$mOw>*LPk24#n0ReS3@~k zrAOcjN5fxF%Rf!}4|{xK;o`*i;IG{Znh?g#Se_sGya>E3O;nf}Du7f@Ci`l-tdSU- zZf>c(yR}R?rX4#tHi8l&l(#4A|j_r1s5(Kiw*ZF zj^3D67MW|vmvwAhNds4#(|_zQAQDDnoh6Q@kuIzG3?;{AQieuszWVLA{pX+kD_^<% zEA#fQ+Qc>xgHpw^7j=vLoeH)>;cjCu{JFRM?T`J$=Pz~AeGX*M5Q<510R#7afvM3{_q$q`@K-K^H!imQ*+!3iNvq}@06;;(rX+=$8%32J? zw2(q`udBy2+yOSW)MtfB59tw=9wu4Dps)FIs$jiIU9~0lZcUoSfN{fVp0(JGvq?n> zb?7_U%!5|*`{Oj!UWamVsWZzU`pkpvXP zcf|rA*b75M(6eCz1)Bj>@j~LpUUG@!=3@P6{v(QD9NTtxP;G$dpkTSWF3qAUID56l zm!5$oF;%fTl+jK`d;Q+yU;f;W>@N-&lo+hBU>J0}8{W8m_M(&q7Q{75Zt+5yec$D{ z?^_q<;CKGVy7tQImH87qLLa)y90!Jb?aIOy)BAR_-^1Ton1i(H&g%RPxh+l-*K{@? znSNzAJ{)Y%h(ge-G%^Y04xq>PmRrNuDWl{znzRT+02?r^EO~K z6sU|4mO;lN+nt;XZm1S5qqePxdPPq5|*H2x|HNXE$>T9!;llRD9O*z0tuqI$|x4U zGp0Id8z5-Vm-iq0&R0JC{!jg5o2e{$4O=b`kp+8!cj@Jl0;5!7$SXlo*D@X*qfAif z!xa?eb~g{BwW?BRED!IOI$^Vo#KM9CE{x=10_z|cHk&3l_&ZPk_;;RrOr&BQZKkM5 z83$}{4)<=KzlON4j9FHJ9;;oV4f%r*-Xt~4G$1+foOJF=M!6RGNus=#vV~NKy;wy$ z+->VsYW>Briv931BI0z6904Rwa;3+6a$vD`(t)BQ-6H8-Su>1aB4RWRh)on-KGjJi z6;PI@hm-Q9OZ&NancJxj3Lt@f!=5}9b%LupG-E062ktb!AhHD&V$!F@KE2o>1Eq(8 zeVN%+Gq+^zxiJ(Yrx?o-D87!^tQmX%vJZu;-zR@uN7IhBd8M(dXFc*2au%VH{_F0< z397v zKl0w^ZGY2X)HR%opWpB=y!w+J-{I|*x@X+OI~w1*O1Y;&XVV&%PzS01X(X035s0azQ#T$BoJ zO=b~_64Dyqe0Vt?-uT?p<8OWC?T2|JU}#X+AqCVgJQ&pO-nhRRn+Bt&K#+H4ka1@Z z0M$57W3iLHjf)TzbteHqbPUK-V=hx>5M4(OI0%K*W_Tb^eDP~P_0}K#!r93Iw$+Go z=1L~o9R-zhrRe5JSVWY;p7P3qj+YAzrEefbZL^t&VV*kf&cUz zGewXi3r9Ugy~ln!V{2=yG?+pKmJSkf@LVE|5U6g(ugT$_jE{*~E`}fbiWkmJFK2AF zj8nl-m`J%Z%pYy#xe{KjtkFGjw)+8n3A%A*7j|^>E6YOWFS@6*B6S_M!^GwH>$R1> z4gM#y3}I@HgcwETIS`UnL zA2EawQu^4%@fng=wE#kLo_MvNFRttTt9o&$SF;_O&4y-ZNvlaLwO&*%i;^6uhu)ij zz<~fJ%n*BU@A{QZIoWN_Z*3kw+dMYNi9#EdRD;5b$e@w=F$Xr!I6z>Tqs;tOoG(GL ziP*=`3F#sM$-)?;s0<3u!;OMFcQI^U^>)rDURit~Wov6eX5Y_-tl?pbXWhF{@{GrH9mJT!agiQF)Ox;Rl zAY?EqSSn42>80rdFMaC=-v1+CK@$CM|wESz}=0SE&s4p)Pm%K1%hM*Pl~f9(FNkEy&?bs&oo z5Nt}hA@!*n&+oQ-lPyD>Q}x!Qx2q#MW_RWFed>h=?7@fy0<=p^J|j})opi5$8F001 z+Ui#e2<2?0e{3QmQ%Ab2rrN|uAN?T3S(e@F@uNq{PR^;Dr6czx(d+1AdrCv7s=H@o z|2*`uOf2;B_;gSpmlfw5*@$PCA)o3%r0L_YH?v!{ zg_~y@72T?I35=CRt|#&!<$5F6<|5;Poj0I|Iuf|oJZJq7=^wHR$_4K9z*F0MM@uU(5kgCn;coDGc?{E-tSx9$db@-JIUqK7MoaRKdAQ5k*54 z9L#3QL=ZILm5Ksmw|0qJ3$*m@T*LyI*k6SUd`v9Z3_7>r^!&Q$OoCG2GHqz!VJb3= ztYV}U9@_cWp8LTGTd@L}DS$yKjLS`3*5!0O+&Q@xRT#p#?l8+vTjRtSy#}pYYe^I$ zVrRI3aPTCB*%29WJ|l*qVE}|sLw$g^f9?xE^#ecjtx_g!n<$`{AZpFae$X#f{;+tuggu==kg6c$(%Qp{I|DqP zqbRhd`fl?33||7y^8l9h!GUc4!F@EfysIVb08HzRR8}qJUonEHtQA4tnp^+yCgRpZfB>e{Mg1A9b&T?7#(0FBYUZXsyR4IBg>iLM9%ANOu^?=YSZMtkzM$*aj z4ZCG`TT7I2XoqV(JspY?lR=DZq!MCH4u^q`LljXok-6<4Dwr#zSDX+g)V$J_H_slP zo*n#F(^WF6(-e}Ri4H7k0yN8`t<1o{vceQU0uO=3VFF(e1nfF?g)R&vfdWwq+AzNG z@RKh+_nY7Mp3k>7D3#KB(s5ZRMtZ?FE6h6y_;E0;g0vhf4jo}!AR3SnCZaMbx4Wqf zZJI~j&`_?g3*EQsA=MBnW#wyDzHfW)h3nn#e&Judy00uVv2nAgTAE=qoIZKu;gdIC zD<&q@vH+C~&5Qfo{Lo2f;t4e3z6Sj>J1lAkkS=|Gf0>xypXTmL5fjNQigEjMPPr3`;EBghCGI z<+F$O&xvlu4>Lrp)yr)SFfl#M;9#lnLIUNy)E}SiE8|FU*H*fZg`_m=XkedccO?Z( zI|YgOW+r>PUB<#;mR0OuBd3>>JR+uR`Ed5I@(qryZesn~!Rt1@GljKR(~m?63OHC3 z9V%sf`nkt`^$UOb`RR|<(=FPCHKmF`%x@`%h>A3k!sz{?G61dZHsy_@MKVM&qnh5I=c|kMviC3;wu()o8LP=8zb`GCIV9SssW!%%40Q^LXvI7K?)3Vb*rY?lOr&A38 zW>`QEGFTNE0BFNtHr%)G`}}7=_T;<1IY`T0=zhTZPxNhaH--Xwe+A(nIM_Ng(mz@P z%R>jeiV3RRjCH$dhy6IJ7>3LHW1FWkl1rjbU=Wba9>{dDufO+8fBA){pQ`14ZGxiO z)D168U{k@1o6Q?gn#_>m+o~$CV5rd~1U+t$4lhI?BHlU3uojP1PBEo76+SI>XA$ez zL|Dg^+%=p9I&{Y&ABm3Ya`dEi(}FZi3w82WXXrcuK15(GLd%=%{^5X5x=v^*g5BDa=l-xaFNvo{(14!nW&f^NcRtl18n9IJN zk{kh?i?ttp6;sl-$_D+zumA8bKm9LWwGVJ0=1QoP?xjei5dE9HE>R65b)&ER-06S# zlRx|`+&qp(7LgR0jCaQoAwq%DpO1RMpo3uHUk3&4CDEU z%-4E7)wyvNIUNR*eU*dQ`)Yzab%Iw6QFO6hZh?cCFwkyzPsN3BvZ=PaA8O#21Q|HSq5CIQHw?LuJM%%S- zzwv$Fc=|opbCn`w5sEbyEygBIMjh{*Uf;N}Hvn28g!;XgEtf_>ks@db_y~ZAN;p5C z;i?^|n1b2GH{^89^AQ>Rz7q+{>!?9`3=2C7xL$xhzUb+leAp5k4?S1_9Q~>J32Cdk z?)6yFYQR3)K9DpST(&HWE*DeAl{$w9xV7QIPCt7s?-enD`XSH$FdtEEa@DxiZ0QA| zp_I25dsk~O7umtoJGrbTCF>8%xLG8oeU!dRZgbV64tbjDNZ2xZwt{UO?;YYr`7W%S zk+Abe)PC6*bU|4xQxNlhT(B?r>fJ(!VvshNV$|BMPyVZ~{MpaF@E5M-?W&j72rcRy zK8S*Vh&UO8l#HOX0-gTEWB<`7KlD#IJT6VC6lp+KbUXUTl~JB-kdTKSX$T|Xz!dFL zDD%M{Ud^vRm|wq~A53;Inm|-7g8S*>FI>bPEp+ul>Ws(5xiUH$NpczX^-Ow%?$3r3 z&@-If=vo8BifSVjCQa%j18oAXS}Rv-&CbtcP*F6)RpX%^E>DNIZHK4U@t=sSLU~k; z7BRt4d%)X{j@)hs+nqLPR4sn1ZZ(dy;};>8?9@cV zXGk6;f&zB{kiAtPnOKbAj}La`2e_()l7u57y{8p{LD`y#`+<}K;+5-nef{g-|JakS zn3)(*A|kdR43bPyqI%D50~PS&AJPI@I%!?`>>eoYS$L6Qu-$eNZH-$QaD7n@2e|>S z{^MF#Z2&1>`PR?9d36`#MXP@FqrueMLliA1+u_E^#V}r(6Mg_RGlQ9mK^jmRv*OsZ zvkCT~Xm3T-XNt9y2HTN-qhw@bG;Ny4$1{ zdcWQgIiBRQY{%Pi^e5C$(io+JE$A<4jkM=06o9Ci=r9kEi!1y8{{H{yEBF7IX+xPV ztCMmH%}5%uZ6sB^N2v!s`HQTNiJ=Y17+*hT?AxpHH{<>p3ET()+B~&kS~?u(bqZwd#QZQKRAuK}Yw_371{< z)pn^SmdlwX<-`nr#%WNH1}e2pkQr*GR};n=H#Wv_hw6j}HZ_#-1dm4)BH0AM#VUmA z^t7=E#JtXYz%Z1v(<-g7QFSor+{&S8tr=8@H~5aE8mL~tko>}JpRmcTv-`JCFBTq_ zCl&+}H!Pa4p@5qClEMkE>B*vxfa_ zjTFJavKh)|7>Y{sLbc`w&67BZA3~U##SoSO&j`Jh4ozuyCk2^RFhY^lo}{d#kdnQ)<$WV zW;QBBn{jt28?o&sl|kFo9$Xz>*qq+fx|J}53%%`Hc4V?5iU^~k*f_Sc^I1%+QU+~` zy_G|i*@_vm?M__K9-`bIAJ&&76#ACC7rWC#&kH8Wp-;`1f`F=tL=&9UP=_1~j13 z%-j(J#7sA(oNe!G|B$>cjRG@HjaSu7s6>HS8LZU;6_M6jt(>ee#G48f#aI+VHOc#r z{j`mbO9cg@kRmK1#ZRMn6La=%0Rma>Gx9Y%X7y`L>5`ZD{wN<^qsb9t;qtDdm!+;O z&pdiu0A(gburk^1N|2UEywWr=GQ9p4#ZWeHoL>Fb1O8CL%`&qd5UJ#3M6pQIQbCj9 zZ9IIe+3%x_WJ}_;Ah5U+pfi~qm+R7MUV%+;surjb7KBKw@a)`p2cPf-)QYk2V*KrI{*m8&`mbG%Kd5>SbKY%bQE;~mpgD4D zF0YL?%JA?{?*6Zz`sgoUcnh0Y@dJF6{?^R>W@J*9X?6MVo7SWr?BRZX<6(W{(5@Ti zrn5Gw5pnHNvtx3!thLi%e{gt~$!J|Z3u0wd zHVQMawS6-J&1^Pqv^10JYNcS1QG|tMwz{A1Pn(OAvSnpP(Norvi-oEXks@(K5g7)w zQO<8p%F?RJ7G^TlvZplD=!CF@8*>Yp90Yw5Ix63C=UyqMC{b6(NTeWz*^D%fBSg?l zT3GSa_*L>e)`UrZ;x&;Y2)dLGpR2~;mvYjYmT36|@*3}c{)-=f_xrv9F*Rk0HkIiw zGj&w_k^TV&F$#o3xFN?Db=l(;CvwbD4nx~+t6nz@)pU6HaATZ`GI?L*AE-FY+rwUo zXg(LgEmtubpo7}x|R<1ySsIebtHPVDM^I$)nSw+ZqMr#WBajr{_M#OkvtC8>3x1oAA4u-DL-5muY+vZed%pBQXf6u z2U#2A<-LoG)J643g#Z6+THl&(9GA7~7C1LuL1kmvHNo)GOPk;R%wPD@gMXo&Jf?ip zn$mNkj+9&>AeZ146(gFo0ptFUKlZ=s79l-L39A-MM=7Dq?R$_cipugi){xEV)H>Ujj8Krt3Ra2dEI_+-MLjeoBB;XgS#&wz~(=eo;!Fv@|qt5ldkah)NSP zqS2aRVrzK>*rmW6@+Ubcg$;_LRD;!42r(Io6hSEpFbdpJi7Mi^6cxcJD2f46;CX-P zFb{+Sz7S7YtyVH}Swrp-vPjn<>9$^^`{d|Q)J=6RM-aIvKneqrEZV*Ij3pA?9Q8*c zUjSxH5-Y=I^R40PE7R~Ppyv2;+e7-fx3+J(DPWZDNHZDBC+hU~DffJJJwCZuy$%zp zHj5HP%pf>nR3xX7AkC{Jms~oRM?SLRv0f|i&-o_HM~25Uf#>Tgo!celO+z9~WlSed zXbR=HVXM2(eeJEk`qh8&!hVKZSi1m53#Ln^TOGc%H?xEHS%O%lZMVZ~f9lqM_{To^ z%hUcTHMLPy!eWbvH_gr)z5=%VDqU}pDG;&|^MMZ^)|W5q{c6`HGfG6ut+KUTr;M99 z+C<4v4-`7bNN8W>Xk2aG-$HjRd!ovhgytKmD|G5>90-xOI|>wWCtKf10f32ouy5l) zkk^gww-%LJt+EL*&pg@E)2BtGk%#$WYSRuo6I%pA79mK?isFkb6=W$ShFd4|Ae*@v zl(P+&`%{)$P1!w&M;P$&AMZ|Z`{vc%TMq%DLM@a{GT;OOO#?}@A+s5?zoPT&|KWRdvc7B#lDoM`7HEm>J&;V^#v3ZNs zcg*uk+j6=vuJst@cuq@=N#>@V)E~LS!FOB%vUqdt?<{f{GtYpL8^K5}bZyCX;%X2e zBB8SE-!gtWx3)svs_%(*Dva;2fHFn z2@&sZ$y#BS$NJKgNk9LKCD%lxxkf}U;?rDVQ~m(Nt|`I10uD!MgWQG=DLL`rV=)(9 zwjkYJ1&EofQv*_21yFJpB`Bq~xf#YHfGUjA8m|uZ;$+w@LD$9JA#pUhQ_l!Ogr;q{ zxod+~!C+DwaM*8+18WJf^-)FV^mVW?bw)%DcW+_;)?RaoH=8;Rri2W7xZWJ5aPb!EDHOqGb~{i&ST#0b zaqpN$(P7-}9uDJGRMN^SG%kq`;e14X+5lSIr4eOveZ(c`sObU?0ANu|QD++!#ZXK} z6#E9GahK1tFex z4)hPB0SL78Cch~rjxCIZc2t5;6pXtLA>C9NlkhCRv3FOMCBGs6_v z;3y#laZTqkMmKa<#F<)cY$h9N>Oosd<2}VEJ=G_#6(Yb(?*;3 zF{~!@ylpgVL#kFFrT}>!SB^f0RH<*h`(P-9UyMnwixn6xT49o=Gz?>u0JS-;eQ-vs z8Yt(jGbM9#aM~3&cgUissT2uiGN?2qAPTGGNGTC;)8V;`554-_yWahQSIrn*SVPvo z3p-Nc0Cx{rM7)t0(?{ux!A@HJTa!`%sI~;Wdi0Jh~&0Qiq5Lt~ATY-!svq34N zvNRS|@ggBrVpbT@1PxYI2Ff7FyY9e#EPL^46U{Qua>RyL3&~?{pF~PlvtA>T?^Caq z>2FHfm5jmjh#m4eUB*IyT?WPD`)=^iWGI{Gw};O+z9Y|EIGwuv|)Idbc z>Sp}F{&3T_mj!W&DI&O%F{fp;Smim=JV-WL@*ghu;aQSOuAT`PmU=>GB$6Cwfw@&u zK>CmRPZ*(^P98hXMhXcE6%?`%QnoDBzVwwJ_~mc>k00od*=CYDdH-fC(RME6nhDtu z2u(Pc(Y71=_Md;}U;oGtzkFzKV}Wc`#p3+vGS*xR>02#cE<>r6*O%?3i|O^*u1%tY zJ|%KrBx<66oX}FJUpE-Q49_A&EthpcTa;Rs^0)51rz!QvcyPxU7p*ZZCP_rUDAj)b zP}0~=Wjl!#^rgyqC&B>~s9@jh=GZV5Yeb>v_C#T|&hxcxnglegfD)bWuLU5T5P?v( zC(sQ!5z1C^xgVk=8WJJ;KE$<(t_Hm;^{Lwrio$xYL4@G=P(;`a5DwYFK)mN1BTwLG z;MrZ!H7yK#5-aKxTLzUQ8X)E>C|1>`h7KDK^YHMZpFPVwmJ3>=nZS?5J55aS>(L)1^oIl9P5weDn(}>(BvhWy#&* z`6sF$T3`5r`$nq;$*_CU4$^M|5pAc#@9f(jQ$1_ud{$`A@t_ccP2_<#Fb_DXvNbDD zsC=lle_DnuBHWne1>bGpLS0wRY$&Wd8SEkE=vBE$KtvFtAqpXsjBIEUNQvc+L|`Xw zYgXvvinPmmwM9TD@$Sf1P@3-A{MzQ%zxvVNc>aGiZ{Df$I_APsT&=9vQOIg*=&GrR zLXR1CqVnp`zw_Vz*r%SpzIX@JFsO(D?#6d}&*=9cnfs1?q{(4lFD|B6uG_teSv5#$ zXedCS*%C+-M73Kte@?^FmOFeWYoK?r>`sWkYLyTPc@lWP&a7}nm+2)!4KSC5$Gk=| z^_45e#i@&tb4Bk2Xa}3NQlPa(Ig-L#U2?YT#=6n5#XU0Y>kzZ-%(bf=M6`f%w&BTG z?NHR)R2~K`Uij}rbOMsn+bLZaN5idK*H4^Z#t|$*xPUG73NWHJs+bPVC1TFXFdC(( z_mP#32wh$M$Ci~^otXrfLUOGl*$*)RORL~aB?f8Awi%y!^P~4(dJE)uV(b%2;K)fa z(AcYCRF@+s3(_RK$`YmpIFg0KShr)_j8-wed2iG9aq0w&{CfdZ51A3ljkc^*FddX9 zyVr(sa`J)o9}yE$QM|!OCIh${7>MkDx}c7vl?lrpCoDSW@h+t}5EFTAc4_UhwJWwu zt5>yN*E+Q}ajuvu4~+-o-t3CDr|p3Wn1Cj1X^%)(6GRMhh3m_R@<%I{^4;;a6I3np7^- zK}X1s)p>wgTzdVzCeqGN0s5qvv6-1!+_BN~xUp7}23o@2 zcK6UfYbC_U)1UCRSgfMsRJQi=>kt0k@BW!zf8lTK&mO0|Zmm$=3$@(j{A2?SY_6aR zz`QTM?O5v1z3Z?4#3%po>f&uC#z6$ZUdd!h>}n+l)(n!?=7ZgT^YHxZ`)97^Hw-iS zX1Yi>n4wt~O*^_4(GpDw89Jw+M2yJ7V+dLB%YVDM?aP;YmG5GRIF2tNe&pr3hg{At z6CiCNyx%h~mL?-DjYdqteT8=N7kyQ|Onw2)*N~A0NvG ziQVFAu>THR9eew91_NEy1%_HtYa7Pm_msh2ukZfCS3mL7Z+%X=*Q4&;(g|Ze&k0YY z3k4{`3R$fjyY-PcCfwIoSqz&Bw4L%~oJGg`7rPmU4FE$K&?umYa?p8I&_?mY0u3NV z$~f@k?4p!e6bljPW3)IR*QL$6G3oM`^IJQTfdaw#^7eKC3b^v$DgmI8AWKsfE22eg z5G^W0X$4x;Pavz>tSn}O=pZ_%Y!E>qZ{DFn1K04jVk60p;s-Hm>Ckm-#Bxq699>+a zB%epgdZcIVM3~z5JwB;(B}6$P)uTY=-cEjR!Vg=|X$GJ7tyc;THZ>|RFx*%)lVSX! zd3vhi#Q|lR)0*D&vB$Uh`6*tjh3Y>=XFW%+)XwM#!eByeW&%~wXm;N}nK@l{?h`-m zD-{RBnSGOt0Eca>s9*o$JO1HU{}=c8vu!IfU4jF=K_?gHBulIYnK^R=7tjXCK{r3Y z{hNQ{W52$i-e)iw2Jz^YVf80KKlIcHD9DEC&>mb&uU)q{iJ6+Mp-a5V7t)ra^AL!t zsw)=}o)lsJKLay_CMkG5B#^OwxRkO7@p%OI%YNzdb>B`Bd3$XNx9`@fFe2ZuSZk4` zH zJ2Mn!<*3S_qN0VWZO}GQN6|ra6t5Zeqs8fU9b+IofxIHaVN4?)5ie%&pyg%06B6%` z?F^um#K=vpF#k3o?3JQb4wXy(BZRX@P7 zEU*B2bfjWgoCq2D0}Gm3Y1^S*U5x+mi$DH_XaAM`@FO~0ayH1|0j4-=9yTQFG}fRP zQ?kKY9d7=__TT#BKmPZx_ut4#A3bzdT3>Tw$GYeN|t-KD;@%E1-#(H3E=a3D7Z;Yu zRr`;^Jgk!|2w|6QghQVOGxzEOiM1N$J$5@t@#BQAUViXvpZ@6WKmCkKD{=czH_I`c zfK<2kB3_j5N8;Qk0N@e*WNslrJ?#Rhj+LdM=yq(oja*-EFRt}2EQJpO85AeF58U_g ztuXT9qG+}$wmZ2(IO2=Qc*10nyvzp#ao}q6xyUN|o~K2(uKj7?!%Rr1t#+F22@3#Z z%gBKM+Mt4BGC+ocQDl&LKv7erY8yod)lp;v9RvmRzS!ZmFuswc7NVnuBc*jk=xeaN zU=&_=R{)|6agw^ zvNo2Wo<5d_E%6ik`rDhKcKi;bCMz2V$*kbYz)K=f&OYXDxf7D>BTHeKPuis?N>-g4 zQ^e>M(W2Tl2w=pNm;!yYo(ig&>b4e>7oKmw^67u+>HS}-yPGmyGzz46$~QVQ9@C6a z(u^?yLTQ7wy*%*={XhQvkN+1ueZuM>Cz9#cw2Rq~P1gB7f@lX`TpnJ#s`rhPsu31R zyn+QCoV5h{i>j#KO@)-~03%xFZ2K-~T(xn`ka8GgUn>B}drk;hy78imPYP|A6K7S? z;~@G4^~6r9W~%4%u+>Pg09`YoKus%Kr4~UEDJt{K+2+P3OR)Kf6tOo~b76O$EJaWU z*zSbH1_HpWQO6_7k=D5HbC1uFO>S(bySMjis)>w=^jL1Is=%gDfJT`q2I-SRw&GdX zn1-_@fVJ!y+u4$2o@TW~gI7IfMTCK6IJCO0BE<{(ZFBbR7k~Wy_kQWltvA`W0wr74 zTtxAjEIXE~i74a9=RUV76^GZ8u}v?(F`X<;^#Wz1`~qRp4w8_D&cX@JizyNkG5oT0v5&SLga0Q~MNkjKcQV2n}8+da%orvVjbt z=@1$>CqH;;H)p=G!Pt49q?5b?cC12bwXgp5`{j>u1F3sz0g5MfV>yyqhVAg@_?aB{ zQWb-->D>>F|Bs*h@c(Of{+8)l~uTo-P7WDW#{O#d}hMY)12r1bK`HptG+qg}yX_1CqBE#HvR4hq)<>b?=#( z&Y>3QOx;Zy$3RB2IHb{YUTaNUuc{F0r*dW<%ub84!3OwkmPN$GW;;}y$FlV&$+5<) zG%PiNBB~H7cs7bUS15|Qu1s1@ae;xH9t6bgv+J|deGj9ixJnWAuGgS6Qx*CJ&Bh*h zcHE6dPkC)utfchFt)G?EFq!PsHBGDkZ|Qu=EZx#pWv&#j(il|bwfTp?{Ny>lw~dgM(hwL<4x*O4 zhgoGEsjg8U?zRtHx&wJv2B*uZ#h{lM6p*3(p1J8+Uo1XBCjL4GFM_hl{Rc6LmwCq6 z{~bVu*8^3>1nhxJ;=*{pw)=B^FxSg=xVHU)mxuabn(oijy{Wy~?80zmGEpX=5zSyx zfX8l>mhp6%?U8=T;j^y@`zwzANaRt&csm+0oZV%$R%+pI@uNo&(iA7-XSVax!Xjkm zVOuvzoU%J3w~Y&2%kS3ne6REuUUx*!W{-E{cIQwcf?+6fe(P$KeNKLnkPZ`lq6_*ZBRqn%)kv4G zfk$2;`Go!guHTfRzc>&p>xmp>i!%b4NHq=(gVwnAf5W8{ ziFD6=v6}H+8p`CQ@Fv41P@z?kD4BqSdV_^k%dS%8rEl>c{r-RNTlFus8>iYXjRQsW zk+Jnduq){b>=O_a(b5ja$KRp9_~+jHf4}qnsMBD@q|nUNJJC`^JdWc8o5BJW!{KUr z_3HYKY6p}iG;3ze`($I^qg*7rBs%vmS`hwx7)*d{Y|UEtl_h-oSfdWjeFqo;fxyhf ze`LH7;V`b^aO}$JQ0cYp1iHM?UlUu`d0a}NzasM}9aShosGp=ZnT;%Bvovr31@IFm zb34>FN3VSxX+%tzD{~b~pejP*WNRWMjZ{C&m6shX6st>;@3;^`8PFcT^KclKLk{t3 zl76HMYy^NYx)h)saIQ-wDQ#0F(o_gBU zP+q+J(9>V|@a;eT?LnG`MuHMOo4WyC3=$(X6&?4Xal=8Tc6y63@iVayKy=eMR8-w< zFbuaK9r8A?@!Qe;x1u(w_%!gy-bi&uh;Ual`I2eAOFtmDQ|6F($4}nKN zU#;N!4M#?y|FHka<3G!{$gS#BTQXi9VjSr>HYt7gN=e>v#^MjBAZe+ zMYk$jsHclH{6G)WOV5#kM@UJ)OW&hTD=kM)9Hlb#((;3HpYZRf@S}8v;wfD^Y!d5oS0AEM>MCp|ub8Oxg zkdwtuNxy<5X1>Y_5KGcnR;uc0ZI4~5-@q68>wR`3OG&`2>}oap{Ab?&55NAeKGZ)g zC)cc(#*HlDHm;ak4$XgMk;o0vRF&ya+mr7cKJ%A9{I{O?!ON*_+tB_7y((lUSc^4eB1z`E`rmj= zzCc!a^LPPPe;#>@f4v+egRio`Ajk@r=Scr8k_8fIt0xcy8ZZL~!4+^(@nFWK@gTL~ zFt>|ozCTS5=K8?eB{`AJ&|LNMNKq()3+pn5SOSpfU1B=i2Lej$O~wS%mViA`*aLS* zixNBH74~c#c=qfK`6bMwUZ zF&B=V#h5EAo_L=GZONe^BGmr-058ERek6=*k>lkCVF3o1Lfd#_zTQ9lrQdn?fA!VB z@y6y)bMvsZY8c^&O0wU+!LYZzHin+zVjhatB6Tu({K*^N`g1?{?>_Otm#?NWNwqSA z6Hv)UG_wZJ$VNX-sk(pj>e)9gzPWF2P)rI<4Nm`KK|=Ul{;emD6jF*5FQ*XcW&Vw= z)!M8F{$#cMQPz%Bby*!n&}B&%5us$yK*#y~yB0u6WLS$8vW_SAoL%;~2=t1SIo)+j z)*~c<31?$7p-5X=%b_TYb+$u`212V(W_Yu?Qs}WDQnV;3yNwJ*JTo3qHSrg8WlrCz zORWHgvyvEZ9*t29w3w9Y4B&tl>xqHb?FavwyVZ+6QD?=5`tcUjSFh7{4 z`*nU`d`L_t6X6$~dCBjpD_7?-At*_X*kv*UIbHsH`;Nr^^xYm&+l~%lSz>jS14`53 z&h8h~Ui2EQJhI~H1eoZ7I(hRl7kdCyniTyo__)cuis*NPyewW!N91_(GCOPq{u%DWi4;!P&?mod_tIZ}%YXmvKm7aG*PE&A>rlyw)__XRR%fyjrmWDp z;^Ml#^6LF(9_(LkvJXdGSs>QbB;(-B5JloI04Q`&^)n9(5g?7#tYy_)CR1`Jat@J| z@zA=#n+OG#t<@*LURrKSR7v!w1Cf&u@jfj??xX_Q7$ z^*Uc4JWCOxO>N&=JECAXewxEast+kr)M`7q(T0KW7Dyf{j6zMW6?q|(t}BgqZeN_9 z%wlOf>5dbVP&F9g_^$Au8gI@d#1xpRPryI!J+u z9u7Pkpc|t?THD-y`pZB2-uHd&iO0Tbb5Sb9k1f*+vYCQ-=ykkbIC`giY5Rs)Mb1&<;x=%13z)LRc#V5%62 zUBPw$Y^GIWHg2Tsi=HaB5CxUt&nN9zR4pc$E+DeWima$t4qvQ)1A-or?P;f#&FTvz zf^73>3aRZ(PhLJd{L(%C707jR9eOxefhxmQvt41_HbX*`)?|EA_>nsO+BkZ2DDDsJ z^aZ_B8{9v}vXLD)xZ3uZ6A{r0q~%@qDz}q?(|OROuN6J4Ni|cHw%N$_)%e?g`2OGe z&VTp8=8s?pnfDMC6j^1vu_#jpv|PTPG6RN%R$<=J$17_QW9FIaFQY_e5tG;Ua@8IP5Z*Z}c2;W^71I zGi>V|BrfL|3W0WLhswIa*gtd;h=BgIglPap#f&FA8-y|ot2a(!?<2Irj_mNl*oVUQ z_^pTAU0#|T{C;!y9Dd{n}3@--=^FRG3f+Ajw6$b&<(gTUX zA`iuvT`L1bFz)K+biDWSZa>}MZeR^mG=UCN5o@6M`Cse>r=*~9GhCmazviCXifF~B z2(TnfSE317Z5CEvJo5EwjydpUj_XZdY{~kms}JJp7yavyuCAXsP(RM;uc?Fy%ur{X z4j91MCS?`QCUen~GHf9mPz@?^JUj;~SdBCRAu?;Ji7|fZ-%7XEp!wy$YyDWPMTTnq zhvGIsTalY5zj*KZPf58$HorD{Z`dBv`9@YKndw< zEP?2$0_fvkoqq5oW}jcc#8LpT@D*A1s%w+3a!6KSro+r}c=6k3zxMeb``UwldEUK8 ztQ<7sWrmHkJ~f=X+W00Xi+b`uFaa(;`5e-X}?;X0HCT`BoCK3uM}^GQOzu3 z^8#fytcbKy9DYd3!|=XWRJ04hf(2k#_6*&}(JMDUX)PqdmX>BXAFyn{W)v6swEW0C zB!!6K(eF$Sx62GQjRrFaIw(|Zs{3ja}|>i zQj2KO9$7Q#zF%LbR0*L8Okf33MyjPX(OXaHXFojt8}I({-?p<_+urnAco6QJ9ctUx zdVM`#PVF$Yt9icKPlvh90#i_pG^+Yp1+vo*jV{$dE}5!ViLam!4|1 zG3%#0aUlGDa|xApm(&jjxIIAvH_XH`{unxrB=J3D8#<6n(YZ-i290W(p3sUN%DK3S z_Po@}hf0C&;d{xyN&>Y?g*Vp_r{#lC1=Xg>u1V{ep%e_tU0^@b##a?0)tox(2r;}Mm38~fN|8GV5g zNZ<(`=N}Rt1y`IZz}RoRg#cx$s56y9BNT(YFn{3d-}(?Yg=LNliY2dxOFPs-Bz~k& z_3Y9Dp@BbrtGd<}Y)(vdR*~_Hhq`<1wbD#rXfXJtZhm;j*WA?a5)!eK-SzJLGP0S1 zT(KCMkEZu*Uj*^^&jN#K4cA#>tiR|p;Ua1MZ$L_y!0)m&(lK{|o@HrPkP7K>(KzXY zrr0YUHhI|GbD~LY+*iAt>x0@J(herGp?ScQ$eb|JYQ-4>EFZl3(3GVFiLPqW6L?tC z3{mpo6H>=PAw*13=A!2}e(|JzRz-!)k)H;@6fn^}=A~~ZkF0D;U zxS+j%yH?bkKyaE6g~+qz4#@hwM-NKi&qKbNtkR%bH(R}TQGW4PKK{#}{u^&@{u0I$ z%oQ9(;(j9bO^0aD?n%zh_c`-&gc2(CFxNXz*3bRa&429&e(cxv46_|3ogp(gH%^AB zaX;CWVQ#XoJWO?-YmF)-gBes*i_vU0Ykmt_$53C7ypU8>WYCrH0fFXL8(Y%jE|#9! z^o{mVq#4~>ENq7v?AFBV$Z`1V5m`Zm09%)#B}o~u#uns!2}>`0e{E714Fdr4Bj;Y^ zc(l8&SSlb{4b>p(aWqmOiZZ}#p4+~;hk(8W->nv1`$OY5%I&6l?2;)np>19Cx;*+z z$lK?K^Yh8As?Q+qa$}@p&7@Ts6j}_#+{9LxuYA|NrI28P(J=$ISqZC7Pp{(j&G~^RrERw zAI`XcE&H0pfwl3vwuf`OXm(9h&kP4kSb4vKE}IML%QEO5s9KqG*TuCxOq-rlTP=(L zVxqKq&dr;*w*SQ-uc=f-Nev}KR8yOqXNEz>T|32ChVe(|`KGDCR1w!5rZcnJr;bA% zwBk!y@5A@}69ZmM;3Iy700kVyblBK1lxM#B*8lV${FUE-VWa24$`)px;Y)*c;WQ=T1sBnBC~?k zQAioGENIGh?3lD3p<#7Z4Sg(RIWcf>$dG11+PKRB0vH0UHeK)fQuNTalh zx`(L@620vKs5RQ~ebwGmTN6o6;{O-+f}+*P``R*3m0^hx6Is-`aDX7{ojU=D(1T<> zo%$i7a?%c0!>|4B+y2h){STkRU**Yd&evuI7&4`dF4}8BN@;f>7NqwLiV37mbGvmm zeg02<|G)9BPkovvyN1I&R%(NpHG|O{tmwy$YMrdkt>a1p5yYZxo@-EV?GR^z=qI2G&38NSrk`TD&QcB_cyG3{cus53|+fU5{{wOb2zJ!<#V-g59>p z2{dzqDc!SS$DT!hFseQA#Qn0dNFxA}7g9uS))N4RG7xcN`I1D4w%APj<;LE!PNIVs z7&mTb2TqTeq{JuyrER44zAi|`mBgZWmo%2CMJP|j1P{lzee>y`oTkyVg=5oY1U;3O zvfp(}dVSYAXT~yAfPjm+l#?pPXy9SQ>-0 z73W^LBO#@VS@_W8!Hh%mEANe%nqANBVQW{00~w(rN#33vy=bkoS#<$sJ*qF9|N3hPca59^hlFXZ%O%yxhe{~chvcR zl+G_%ls*?niiF>k`7{K}yjL5Z!*#`mf(0C4QZ}{Rm|uGB@Sp$cAN%F6|E-JjpTcmk z*{DU_Z$Dz9Yvj)$r3DR#!Q=kU5tOyz#;xJ^Klz^j&AUGS*#n1KtCd-#0<~H7@Lk4R zV8+^P_LdIe%|S$qcNYbtniP>@hqrgmKt5EYltsuG)wtGJn^l@+vH&Y`9g%~GOe`U8 zAnos><+4bve*$@=KJKFmq1jeMu+|3}V9_8o4R|c-Dz%voUk;#0*O+wdQC0S^govNm znwuXq_MnOoQbe?%@i5z=C$v`|z2e2)TcN;XX#<9>#Sw=B_^GCqK}x9$KMI2FFg16a_k%l8^I*7_SO5jMI1 zI6K7m#XK5*XZNWOF^s%-Bt^aJ!+KD%(xsI}3H(|1bKLrgjf|`Q65&gs;EE{ z8fvq>+W^V|Xk0f$MaRu!o4ESyz^dg9-Ve?Y<$_BS-PD^-yt~8_fKtiruzBfx^Y?f9 zl1Kw4T4UaMFmdlw&nT(@XcWR z4Bdn}54$?o&1e7Mo&WD&{%c=)_&?)~cfs~(Dq7SvR_KtEMD`KEN|9UY{bSRl9p?Jj zsO}qH6f6`0|b!b zasTvM1Dj}#)p*q6b0r2|ow5L#f_{^hW&j8AZxYW{qXO|xkUm{@nO`DedA-0wPNUMb z3;xPs3pi$sRO0uE|LGra89s;=2k~4xKr}-&Kwy@MQpKRCZLV#KD%(VRkL{;Iq>u-O zC?KlXZmS=GlhlRy+* zalK@U-X2pzNZcbsa-4VoOxd=@2DCMalP+uFa7|No+pq5vdWlU=o3tGfOblBSVw4%x8ri|yi*Iv0X`NaYXE5=s+vne~3Q^0WJ2AD?Pe_u61?bmXmCC!|>=Bpna+K9?v4kl5E=w*4((a;vn`?9= z9$c}cd;)TFk6yoeV*q8UJuR?v0xugbX3Px~7^>O6&X-s?C2%U}PazwpI>{q^xL z>UNO%K--A7hfeb;4rL42OFy9=eoXLZZ>}x?q|MYDr{#Bl{K>!h_8``AyyJw!9Bw8j>GdoLJUXFw&o zCTJ4H#OotD>2K*Zmmx|X`0|)VWCQcX);BusM>v)#l95+%izNxgN9+i_#z>Mzb{96y zT&@JC*H?j0QFY&7b}dzhw^qJDs$aWS`=EO+y*BurL_92z9D z;mK(mp(4ZX*7@r%on7w>{6d`ZphNYOVQ~hr8EX~P?Pf}-f>3ptRsXQA@*T9W9?Tlw zA&(%;x}t3f1tA)JX22tjgg?J~8=B9_`=0%-?F`{@u>^f1v=5T2{pOOB2;mRcgcO6K z0eitk!&OBSRJ4YDoiEJ}L`|2ougm)Qrmojx6_}Oips<|(cT2$TD4VeC1y|oP0oSZw-*q4?)<qf zjgU6YJUiKc=BMxeTkrkE??O%~vw3?f5^l(&*}02&6kG)9l?8soOU?$@GlpfLpz19>fnTS6L z>(ZTNBr+~TM(p6~`LdQ_zkIw0!50*kNA$Xx)U-X_XbnY39_rMrCi7aE0S`7VP#d@) z3MslfX^waRy8ViUSqy1>JxF`vv5R47&b}zC)n<&`8UPyyim;h9Te=gkS&W}MLnKH- zAM*%+MLoV}7!$&YrUBH6@p;QLI(8Z!uD0j&0Kd$4eZu>%_tVJFo<#_|weOZAz z%5Ka9MP&ZaH7Z|&q&4ZF(<|1|HiN!?SN`D{UmQ4tAhgNQD6~t-8&6X?Y1Z`QLsNZ> zW*QB(apc3L&*eN@mTm5{SQ1QquM_J!?9i5n276 zL^f~D0{muOI7jta3wQPerdNSCW;GteCebis)|8vJOvn2Wf$tWa8j%tWVs0 zsAJk6_Q?sepw3KuW7X?_;t52C%`(f|mt_^)_FW)gJ>j}&w%7Hj+HRFUXP*!mN#wQ4hju({~fc60E2=_*9I2u_T!1N|{s zlkfFyN9S0?{=~q#^{VBUNnesE08YRbW)Nh10WnDkk#rdyMe?S%FeH5@omVB@S&f+? z+r+GRXtC;fAdA&Oi@93y3? z256n;`No~gU;F8|{>>ly_-8~0Kj0bH2?&$QGw~@mg#8pc1<~-YsA^e0SOTXbN+i5=a;IsEAPR=7AvJ!m+ef8R{ zXdK^Pu%^73u<4?ny($*luvmacrCK6#M>AIQICgS2!JtwUb3M#$GOGyx1-WLFPQOu*wzWsSO4d3t&(iq@4~k*h~l&T~;ioChJd(6a}dm<|;N>X@D3NY7gZHzw?cs zysoDvplR>9akTasGV@4-!fzTwki&ksr?)K%3@9@4xUf|!Webf7O3AB1DIe>Tuqn=f{h2-w6KUy99FxZc;LH} zTay@{w4ihS{NiZQ@}U_g6UqEH31S|ucjIs0#&2%%rb-n-E5m&)6Iw1^YLgL$K|f|Z zp;}0X`vKzDRapo69C)r_3}WpTEWx5&(So*t=(ugxcEA36AN@PO`)_^o@UPU9+pGt+ zQDpFID}#W zYX3oG5z-*DF9Ko{`sS`(e;;`eHSL=g^20u$^fi{DcE5{j*~`6H{dbWEjgG>8mAbni zB2Z;fRI4)&o_JsQ?~))xUaZdE`esn>HlkvAKyw+!B4R5daQoKv`Hd+xiMe)tl+mbe zRBu{`ifFtco#}+%<4JRb^Uaj@jG}d?&ugwCa;c`;P6kuA%MA@O2-X8%Z7&HC(xP;T zWCI@7c4r=SgGNC1yz{N+e&*fp`Q7bP-_|w?yi+>Dw_$kY84eOa{Kg|65|cJ|R9!=? z6uWVA+UWJ6O{cfU*IzsTtIjU0kbXMvh-|HvBjyWPsfI9#6mO zbsQn+Dd`N`x0azrpnY74Q~^YED@idcT52hB@4|lR_x|kXU;S^_?ORLR*BOGrIc+e& z6dPHwffVx+%KUTOLt7^r*P-Kl zOAm^75IkN)E()Owqd3yKJZ<9Y=I31(rS@ny{JI`rxK-4pPb@7ng@`K)(M*~N3M~~1 zf^oprq184wR>;=y5jdO; z9V0U%At4X(sUDJX2Sdty80r>fg)F5Z+-J)Prl_FMYNcjg{$SF0%T=}2!u2f z(Na3%5ZRnDK2;W-6_m}!Zr+}sd*e;LJMe|GZ-4FV%^Poj^VuhK>I8&c0;PzL^PGiR&=F@E*3rf z80%~bY=(CC?tR^K(z_-p{uVS7DHsX_n5(6-9$tneFyhzwxtgfBR?O^UiOz z$%bf!NF!91SkFoTydpZgiLL>T2_9i#F>ZPD)>L1-DmSL#?E3PByRZB@uA5esW>)7~ z0FovKv!eT9(}=R1$F~(Zkp*65#eLShaQt69B9;+#Q7E{tIMf6)Pn1wd77qrBYzCYR zgk}n7g@lS@eQ-%lRarnxB0(k+x3>0l2D_DBDS3zpR`O1$!su6Ba9_*WXkfE8sT7ET zB^J8lfpmiPy;moe#M6!5BQo3NAHBiXYi&V1&E+yFrXIo9H*bu;adWu7i6>{=*-uYi z>Dw#rh?xmzn~klY(ICSo4wt`icIyj~fm|mq#G+d#Wfg#2c==+<;`d4;bQ%VoCi%^; zefT%N_^(}*4-Dnfrb-=E^vJThx&@Uvvf3#eebeGBs8AheOPglgeP{h|KJ`O?C!=D1_EkmW_D&5@(VGzwjuPtZ{{YF+ANjL@-tiAsCWzfZz?xnxYP-mN1ncvn zt0iLYgNxxtk&26?8Cr|3<$f?m1Va%er}@w}Qzmf(i0Dzr=-O%M_@PwF$%f-#(ZgAC zg+mWP02);5=FR;Rx2`&DBeOLk(P_O^HgY@2SjdJ$G*4WFcP)5Ar1RuUBGS*b*lI^Y z4-G>bi=9f9%E@?Mbh_R?_u#2v^~g2%>)Rv@#-|ih*tnl<2!bWn)MTa>;ksN zU9O^$8MThzEw5yXL~sOOkwr@A!U1$d>e4I8jInxJjAJckSYdd)h6~?u!{3oYaudSO zUrByKYfcf8NeBvztlnNN4LpFNP-V5bqFOYQ>Ba`Darf;}FD@K67zRJ>8Y7ITx8zya zIG81O&o6J@*vDFA$tL0sMG?{rq>dwsa5BvCtTmNELh^T6){yzNaE5IYp=ec|&lCf3 zRSmTagFOGn-A_OB9_^URbXV2|2(j>JIzR@nY|*F>t65d4tfcAQZa(wc&%XHV4_O3; z!(1^Bsz%WXvw}vTkyc1!ny{62Jz=Bpc@S*^+`pga`fga(<_xx(Cc2Dplz7Z_Il=_arY?|7=le4d%pMUeVeRgBtR!l{z zaq{59WUOs2`iaYjA8eYbc5pp*Ux#I24w4;sLBj`^4Rr1_!IB^-+$jnzM?WhXD?)m z)b-jCWd_YVcQwyNiexOhMDK~%fxa0=>sb*$c*Eoeq+jf{+)30?B{#-ZbmUgM|_;>V{F24Aw*rp>Ro2F-wYp0D#)L%rWt!G|py|NfAiJT0d91`|$wYX1BU@}o zd+U?;Hk*nb-wnqx`<_x-RZ(meO75GO^|%)o;UgC)%T>x4PKG|>+gxR-rOYRry3y7Q zhe^v|^FhAx?H_${|MBInQ)U~Z#hSVnLrU3-3|a;hrRq@UGS4U?R24Ch??Qh>JyPJ-oP`iUO#={$<(m@auL6L|xyjs?lPw)TQgPOZ5)WU@ zLtij&%S{jb%Aj6AC6YWxm`4Xzh?MY`|5(6ygI&)MF=cBu(`w>C%2oUU<`JNV3*np-|=5fdS4>o`QH-7TJ`oh2Yrv3>j2i93IipCKG zUl8vd=9#Z0{1JfHd;Esa?@%D7et!!6A_VN7#DDt9_x*eC{_xWRD641_G>zWr3`sCu zB0m5K>vRcFp&ArYih5LE`)325BrrP`bOtdY(aelAPf$7!V_;aY*cHJ)+O96uM*$;r z85OsJzV|DvUo*$t_BF9fm0CL>0D2V=!YsxLlh6 z&~#Y55NItf3Je8it#WQQFZvWYO!rz{MrN->@T;DOEyuB318nvj5gTZXiXyg-%z97_!sP%8-bJ@#&ePaYvu|em}*v3K;UL8PU zfW7p_$ulp0`0Q{x1TSD(cCK81LZkpzfL36nsz3*=rq>6K17&~#qBfj9bN^%C`p&O> z@cmzOav2gzEcS$MCWQi3sEOb3o1WHMK#=(k6qP&YynAPV{orJC1K5)H8wnjesc%8Y zI1l5YD5Vq8WXj(q+Q;lI#a$i|9e5P}(HAo=-c2#J?9L|0I}?LA&!(c2WIvYRKDvD3 z3a0z4bHMSP?`Y(RB*p~)SoDAo09j};GUY(eOmv10nG7>brP5}UEn$Fw77~_Zv;+9E z6o8-pi*76e0S%@!k);jI@gIp3;8CZ8%>MYJ4N&J`6gIWjuU|Vov(xkGL_dA!^6XGP z&~VaFl(m=?s1m!AJGBx+r=-TdD@XgcB8*fqfthS;;ptbt_QbD!{?9*q_*2-P>ip3B ztW<~2w62-{OF;-WN~{zymno@+I~k3GwYd)OIQ%Dn>Lph_tvjhffxNk8+o5@KZV*T-cr%c`v&X<6}`P9;0VS*;*ffy-Ra zB#H~DJ6dPy(Q#N(`fFviA#1v^7O%A=FHh(`r4Kao@&ORKen8UAH4RFw3TX4c3Tx33 z$ZK4DZB#HSu3@!J)#eagDA`t6>#@eR@LI)KWVdT}AzjOR(8?DQW-`j%$F6Rj?Ex`B zY(;;)cEiw`kl2na+HB@*t8HE8BYlA!Ya%FX5>A4{hlaf*P|(JqZbloy+Bi2=m8*Gp z>DfPd|KdZN^3{P^l_CpDEo_%=eXSKn4_8rvvecP%-^LLrgoqvv^5Az|5V_?EY|*WZ}Nhc=v!^?}wJV&I_<6%@A3 zFl)9|mDRe*Bht2r*`gBi-M@PzSeajlck5;^WH{0uS<=`t&7-wLcH~<*8OX?I51~s4 z&e~i_SWZWcphP8)hJkVS@G?3HTo5+zPxg@6|MKUe9QDb%N38HWL9{Se+uW#Zv>B&R~ZiK zco%>pVQz`>PfQu^c`nB;eRp;@htpz{vp`IZa4lH6uAok|80ES)X=PL=lL2nK3HxcT zz6_O^4b3MYdZ3{{_`nO-uXPe~px2?@sr@8nz~`*V;CGyh%HdWKWx$l7e6;02BqOIX z$vU4Mm;DYC&AMOBnENyx?p{52|F@t1p#0X3_f4?U`|J8+uq7y=$)#nXMb8_7WOuum z7dqR7E`rPM)>mHmiLZaYO5zG#bF6+|+i3Sc;P>Cu z6OW-CpKoVV$C+dnrOz+}Cd~W8F(PZsCb$^})GDhld%fZZT1mQkLq(aWsmN$wa8>EN z@iR&!=6(<^jmK3s20Y#5+ff8b?YXr#Ys?e?D6%PA<_mDTtv))#Ur>pnO64jgT&C_= zXxHf87nj;5+&u)2Lu@!;#L8zw3n>1{7^+9!GXZiz&IEtNa0Qd&6*eG)_)bSuIytV6 zbMJjO-QnShiFR|=wf11w8_#&->i7-oPw?OZJ8L=ijAS|{MFKov=&M-o8eUkgk*Uf+VCqMk>UjLTo z;jP;ub4WJy;s8QH+VU#GSa&%D%5s~2p2b>@4x-j1kM{~XTOOj56jcu@8%98Yerm6y9*n!Czk(m%8EJHK}Wq3@A33ICvXcFbIf!SbTSw zY3ber7)`S%*Q4<7%<}1M5hr01D~DD-2v)cdPig86T-u?}%lk6<}pHUqGR{Q^S}7x-~SgMddo9fD4S)9hB#T# zi@2IVwC-`jko^^@*t4lbx3m!sk3)}wl&R{&CRiPQH`>8U@M`e@DmM=fY%!Q^W8>o& z9|aKwy*F2upN@5jD=t5LLk&Twh;`wav5jiHi>elbHVe09!xc7cpzcPFR4OqIDCN<9 zW{B&0-O9kq1EL&QdUVAq@=(oardf+)S^9BrH#Y3B2`MKzI{+AM-ztu!=+s-bCu2iEV}zi@H9$=wTmxs|Ce6>CLcFa9gCOAVNlAwmzW z0i7}2RmZOph#=WY!>zJWQN0+Gd8-Pu6j)Iltw;grKqr>Te4kKl+8g^}GMaXZ^=vN6iZ`8QC`9jJ!nVlhaskIG{rOX>tZ84ebw# zbob^9boM>^%Rl>`Kl}Q(e2ZPq#R;l*1*VNjb)5-Bl$)A*HZ!bkjclD$9x%b{{?O5A11OeSEaql&WNZ)RzyJdtF-55!AggT*l)*KZl4Hg$x zrl@N$0))i)(zw}r?^3esDzkQ*jE9FLYP}#KQas^ar$6BgTjh)#-RVwuk+G8qW@toT zddG40yB>SaYt@CW(MS>Q>fYtTZf`ctQp7t-^kNyEa$x3t*Y4bRezhair^#CML{`SW zBw^`5^F#9;{G!_|mRG0YwdCwdo{AE~YOiR{0D~s$`<;v3n%}v?RqvX*V}9bR-}}__ zKd5%6!yJc+#?6}6K9O}_9cmesUAkzbIXeOK-j=(4nxqL%vR~O7|KKw}_x87Z zaG7dsz_3oMrp#K9kr&Ek&EUbth69jYyV0k!OMiZmj%~Snc|m0@of8ezbnpR33Nd4a zI-A!CL>SY284%I>(Xd^?w_HD}NK4HQBb(~tvG2nB8C*I-IwRXMynz)+m0B1hNN^Y7 zEkr*h$TG_pnZA^cx~)#{FobG$x9isgN?GviY{E zBTBwGglzDBupBaz>vdRmB^0dr)Ogjk$d7*IoK1TYzPU{b8e`w56WZ-@*k8J@0$7fV zTn;Cpy^fL=`JIc_`!qF?M3+poOy{)b`w3LP(|22cYjBK;Tx-@bd1Q^?7x?pLeVV#W z-VDpEJD2W#r^Ds*?%(>#KRI8W+jQYN2bL+QS+T$ZIjZ8PXn>s2KC`GiF~Ce60Ncg9 zOjq1VYC`LF_KlZ5^5xI}=KFu-9~{tawCdROMNnZPW1cTS)Inyon=d7_;?hJrJNW*5 zzE$e5xc~rxU`a$lRQ$@t@$Q6W=Q9K&dNVV2p`-Q9S*Kgwx4MwEqy1&CmudgvB#!%~ zE6CE&8I&pApfdlGvN=>+bP$Z}Ql(n#mCesa90Z{@V+|7#U_f4FLwWI-W+R^zlpCp&6H2U>3B@3)JaY6VPc5VIl31w%0@>3ToBV_h8qA zCzXTD&L`;3-l-i_S{+0)`Oz0&I*#3sW_y63%T=A=x5R>r)@*<7VN@bm9%?(!%cCg1 z_}ux|p1jfDa5*2Rd6}>6`t@^zIi&77c9*!@Vc)tRapmhFUEA2?2?W8=k|_j3a3PW2 zcJs8GcjoN6bE$cTO`YaXeC-{Nf9InD=YHng5mU5+ur)=yjhiqnK?VVbTj1j@wce+T zxlfJU!D-a8`>t<(KXN%o>6M5WSg4J{Ax25`Q5!MXSH(>NDX8t6-?(+T z+`a3!cWiswWZqkxa?Nh^X$qGZG(x#sbR)w$;pux`I_1UeGNw~jm_#{qGUy;WSzvdM@b1Y^@Jho zxxiuRqN3ACcWUpLzkB!Zedt|(<#lg;jtj+3!>Gs1nN>Iwskw4b5i84@QALromPOru zanv)Hx?B`uf;uB0`b{mKeF-#Fc?{DFH3?u8m7+&Y#%gvq$U4nG$}$bvAK-GJbZsp7 zzy-x88V%m!pW%zwYLDC&s<9EU_J3aaX_(>)K&~8ERZTj*CdN3zO@o0k%!!6Z85qVL zeciYaE&!$pGP%0rxcKG7Yc$ds)tgF#TUdsWV6?MqVoOb#GaNnsC?}qO>Hg1t&Yphy z__~|NS3hw3?Ch@VxQm?&9qs_NZz6T4)1^A%M+CD}8$&l^qa}-swOBNgePW;5GPQ2f z#mu``gmJe!KHc!mNB-FDs|RrA@&m{&ObE<1{PaXsydkmVn1-Cd6NlN=e&?ieuc1xTi377_E#_7 z)pB)*cB9!eF-*G5e820-ptgQ}E8zLp&`~G9ZeBwVtln!Z>`-r;=zn~YHBOZt5R4)* z_e1w-XU9|S4%R$1Nn1f1&d-nxuC_S>UM@7MkvsC356(z#!md#gx|ya3mo9~!(9~VM z5gAb#aE-vo*=%j$CeuAIZLv;n_9qFBE^4_Ds*K*SG#fM=wuJJi;m8@}C>m1INYDH!1+d< z2N0vAdf&O`7|3?qJb;bgx$5tWB6nrpZ*s9b@EJZmCbMmOmXc79C{BqIL zSGv<-Ak9@hwg4Knl*^b(zZRDTCUT@g7Z$OL>}Kp!IpPBy4=z4cFg3svz#imV<2^$q zVBD>0H>$=5z-VAHQo{s_O~!5R2`yEG?jCo240y0-N=L-UjTj-=(YSVe0c5o>5~C0Z z-QkTb=PEN$=-svJbHBZx?rUhN`PDO%k#!Im5TM!48b=mTtghV^nCyPBoIU-*_2b3z z!nOY58=w4v8{fXkMP25+a`ukHq{D;`-RV0ZItb(qWvTy4I72>ba@?9vLYnA@)@|yb zyYSK#Kut|*di>G1ed}8vyEb+C8N3BMPMc_Z3VD)<(Nnl=4O6K`6V>u-0lLZCeD`=b z5If1B`N-Ei^6)?NU2pmN>t6GL;{jT@I|_dkE< zTlblrVb|1&P!4ji+iuY)3P?uMz|zF2!u{`jX{bUBq8F!*TZkL`Ql_QQPSLoBv_NTM%lxjD`cPCX!sK++q`~JOsJ4?5JgCoShRw!>S%GwM&vMgN7MCN!>y; z`3|794%&X|CbN{kzc#-Ei)FAEqP)=@vJboxCC{@w-Qi&4-gd=Mi546S@i6M-(51{ z;?&&%wZt6q$`PH}jHSsaoopt0?D5W9xUuE-97X3?hO>Z-}w;c)G_xt+hDV}H`I zG}|q+`rHWZc8eK(!KH(a>`3A(y~I^42S0ACbGCpo^u6_F4w=F4TwtE9P25e(OTr_6 z@S&^A*PUHEIwtc53g}jVD71VqN^pumz^Yfoz{M#RnSm7~HoIK7T(T{Y)7iCq?BWBT z{ltgv^s}W^ijRo8^)+UkB{SKNa-=)9{K?f&@cia{{~Mp|eyQHu1e=Ifp-KUeIytFFT0brof#;1f%DEO|; zb2*kj1du`_Ceqxj>SOLTTQ$hxb1aSpaQ8kh@=`);yjGi_>}rO~*9rt}gCT$_CR+7; z%x64#UGOB5HWMlWlo&E|6zfJpl9r(!G{}es?X)xs*!!_x`@|o-^Z)aY|Ce8T@|S&g z6Z4gOBd2H*Qgy~GoXHXQ-?073?;6abS|+6>kO0jl;rPOLw}1B|fAp{1_qIC(y>(f{ zIWj{~^W*7q7qdq^6t%)&qcsD$xcbw_{+zoDFv;9jbs0(Bq;Faq=6>-FVyXucGP%KN zKG;T^i;GY4?M*UwHPwTwxhh$WuH;*hQc3Z8>{0dsOK24Kvxu{Pox*SkICjfNxK*R` zMv}Bn1>MNzAR{VAd+)%Cxnp_a?(99IKv7U+q%}3dUCzaITyzz^3&9TbShh{zlyHN! z!>(Wbo~d-P3De*LEphgl+e4p%VC79mOB%J9@; zBg8MHo|~0Z&@f`MZqjryE00Amq0Q5M-+c0Co_+KopXLsCMMYeY(5vItXsn`iml8n_ ztUi>lL|ohH4X=6e`l}W@>@>M{tU^&5VD0Dwr)-SODTkg~gzamiJX5gl`C@&4sIM^4 z8q8i(5Fm3iceSqF$rJC@J#|-ZZ(R@LT3xfIW-^wRrLtz68rsIjBy(=(I-nu}WLG$u zx*r3@uL>XA0ciZ#m_C4O6lG1S*DbW(YrIp5v30IPKh^`+!|dYl*)`u3NFyreAQF4^ zz4~O6W8a=S^6!26gMa(e|I?@Zhq%A;g=#yi&N;}&_(nz+_#OtXv26YuqM)*aqpy^* z2l_!ce*bI!?8iR#SFhi6EQ@m?op9Ef&Pvv{_%DS@<4nvoh#ilyINMzW^vsn%H%A-j zvN!@o^EzPDH|u-Pa^K_QR;*PSzp^wK<8y3&D}8!$kHL_P8D&yQ1yIJmgvy$PqN)`P zsw7xeX=16c0=G}E|H?3)A{dnk@fE79ADdJvc;mFy@4lfn{VHGgTs zm%sd>%iC|8rY;@|@({F17Y*$M%L?)MA*^Z1LeJ6_oS zaPU|dX(A4`@}f4%Wy8-LD2e0ktej(6{ z5Fv))e4f}X6!=+(TIxa@Asb{ZRG~zWYno!L?+95DimC%SmX30avYBUVph4Z2z8v7{ zvl{8mF;96!OgthRIzgmyzf(g`mn@TB;Uvhs*{TPt|ri@Yu|k4=fC=e z4=8({=ef6q7qr4JVk0RlTv)-e1iJO<=0Oj>`O)ddWmrO@krU8%lQ+vO4F^+bRmvIx znp5#PQTX@p;8vv$(vM4vpJU9Khb{9BxY6Z@rJt8#|HGeh0(pj9)Bw{m#9eb#u|NU4 zra%xjf>$Tv!HrQ_UeJq@^o5|G|`Ih?%_;FvBJtxd2~BdQ*bcRDeIlG%2=n< zMazp-av4>ZMz^FIYvr_htg5;uPv_$VI~75Sy=&OpH`BMw=rKpYEVwWSzqNw31UZ+n zl$GEqI13^@22T$_;HYDRH3;5kr(y215DlE8dFY^Z@i_!xKOqhT2uqT-wu7DM4b%Ld zcVFGSzc1{)_hr^oPfwry^n;)K^6Q?tecny`CiUrsOA9=ofUnMfE-?Xya*NDGh5%qD zgHKv^wnUKBJMLUIs5R`ZEfb$&!9TOOe7y7O*eex%td-@@^C7n@2>}c-=P7%oAPip&L$p?Nm7%O) zHh1mk`If7ZsQmWEs=fR*Zo=a4dK`zotyDntq=R7Kj%*-6vkjYX3>7!{L4*Udqq}=# zsiY`l&Ibq>%_s-BD_I=DnvEkV!ArAglN>IKQW`%QE5|j)7jgcC0G_f=MZakhn9v*C zY;xK3^=EJVe}Cgo{>~%+%Jcp%LCb<@>lR@#$Ew?h8Auzj-66W+fYsir^kUgEfG(iV z=yZSK`_KQ~4}b8lo;|oUP?Oi`F7*(driKa~3<{RVoFYcYWN4F&%hCJe7r5IEu|bk~ z%q(gTEQN6t!X_eHYH;Y-5mc>MWKGp``gP?7Xrw`0?RYV2wtvjpq`K6QE1t)vuX`Pf zQw^kxy_+lJ@e$gn39P}+XjzwxH7dx4lNK(}HY1%1YgC+-mqip#&2UsHt*GHCBgu73 zvxLRXor2T_q0y#B0KH3as5@rn!FkHy6*L-p$FT$xtrr}~ zivl`%OpSQs%nW<6l6Q?VWNbEkYGkM+^1YLMqS5yKHZOngk?;O%zy7~^_}O1}d$l=4 zgYC+3UX#=X`&X-1^eyItRwA8X;|SoU2Oz@Kp>yia`|tm^e)I!>^>8lJ0_(<3I9U>} z4PqT^vy!Bm{76|OE*aUH5nQ@|=Pq9Iq+tY;!$A)<7tKGoo|^(IBgqj=T@4MYk3ALUWr#r zkk`f8wzgOeHY=W&h-7?c;Qv~GAK88dhh6VNS3?+8E9(*i%T0x- zt$ri@AC}CU`oTI|cc_^zj=Jl`0=wnT0bl#{`)^;py&X(A1TG)^VP>}7f3yuEoG6gw z*re64wS$pz2S3r~#f}Ti4V|QmcXqG&>{oyK`4?ZU{hT^8qLD)=gWWk8G0a^qVX@;7 zFS~Kp-tgcvuYTQ=%f*Ep2B#Y_twk{D-E8<|g?NJxaPrIP-!Hcs8~u^VsFV)YgX)5T znaKt8rQd*0TdlAfms0FozAw@jihE@PmLll6;SEOZjZ+1`R6{|n=f;1ib8Lv?g5GEE z3ve<9r0N)QIb!CeBeFxu8cIp^4XI355o_Ff3@Rb{&?RG@$(GfP5<~=Sr)jpyo_Y4# z-~NqX{`;T)Uq9P_%xs5Qp1^;rA25_ZR<9MOw1`D4eSuZo=fH~;E@A1m7_T0CU;DQ{ z^uE7(?fy&3Wg+ev6)wT4PM9%qFDi~4^41!<44fty9qLbB;`zna6pSfNaY(7q98GA$ z0K{ApJ+1E+YDit5dlw>kOO3GBy2@B1FdUjRh!Z(K0jv!eC}kJAubJF%hK&AeH9@$|tFr*t{8+ZZFRC&Yg+I=~{pG z(Fec!)t|xsmazd7s(vs0TQ3KVwdkem$1F~i(HIBEx(wke{sZT$piX$5n5M@re)N$q z{SaZ2(=DQMDk&_!+JGgTyf&akG+evZZl3iwyzR;B*Y8XOjU5wwH(8dnYTE#so4X1B zeXroeSNg^%pBNp6#tb%?g)8s|wNUfo*W`O_sI;1wI>8Y`4l%CLJwjKDF@{w(KY=su|IPEzwzTA{hMburq(4BtY3mT?IkT+kMok2A_w9JZp0csq;TD~FQy;$FsCtpbR3<4Ps` zwp7``nf!EX>cUt6h(0`y)IdfyBPf@AanOCa5=bnBg*{Efl1j-WwuXs{n$PXCT-xo9 zZ@h1Q;c48xq=CM;r0Db7)tAM-`pwt=SHJz*XP%w_m&4Eu2Dh}Wx#vQztyT`#7^c26 z?M#rHjE*};Ec4Vbfo+=l5%}8Y-~Zy}d)oOl^s zNWV%LV8?~?9Dkb;nl9QypZmf`pL+H++{Y1V!8R*aUGeD}kJ>N`k--py)7zx`U!@1$ z@WTDCd9L{d4UQc+S&Hw-#HkeN7#g=|{e)>&?YzB$yeBwt!ksKIu#u};BLOf6FfX@y zKNP>!z1J_ijPTlUe9*#13!DOOo4qLoiJauLfxH_NSej`(G`P3HiP;xvMuaDn2iV2e zv<0ohgJ#N`jkd<|jY0`|ap3DU)Dy!h>yY`xb%{5(BG?GJH?dFqerM+2|KtzdCxP2zZ6F>%J0CdrvupnFqu1>2fs#e+iSErAr?c+Po_g|4 zFTQy5K6avewb?-x-Ad6bBAjDUGK8byhUmfRZ33vf^1Gd294BseHh=p&ulo9zer|Vm z9VYoy<0Xwoi~2BI#qdNU4XII$XSJ*w)xc;`hOuN6Ty0(=Ni8#B;)JLCN5A~3_bj9* zh)TE5E6ltxEMXloGK67k2g`^zZg77%KJ>lcIo~}mG!V^rsFJ3_nWtR4nb*q=*9sRl zxF|8+W@Om#a@w#6f6}W8Xxs}#HywLF^L`lEYSrT#T(gd13~5OD&@~CL1P;w9(cN8+ z$o}qW6VeD3gkS$#XPTe_P8@q*dU$N&=GJ9u)~}W7uKR^Wu+n|PbJ8D!}RCoX#OHj<|PJoRx!ig@q+-1^{c30R%`@=MM!vYh#<_5t8Q>E_^ zIiCj~CCAMce(s=YQaZ+uy&xM)!S1|5IQFr`c9gR{S^CNvn*lvIG>`S{*@D zw2Gu%U2>Td*V$y=j_oy{dHA1t{IS<_=PJRk@Nq(p3ej!Q@qjR4>$A=pd)nCz|E_m@ z=XI}shJFP)tzl}l=mVQ4uY{&31%5J*)7R#yx`$^|!)UxetRiuu_+#w}nhW!l&KAG6 zRm9^NCj%%Z);jXMdPP2K3T_>g7!_(F(7=i7X1;qT78-(;HYB=XA!eU@Uj`H$_KTY@ zR@~m!wHblI0WMJ|IIMK9Ol3e9j__eVC#8AiBUswoK>##h-k`zxjdp z|08G?7S);YbgOAGXUocVOB>#;N2dk~A4?QklW~TYr!M)tTkZ|EisYpFNbxejddB&O z@gCzJl?Us-Tvo+KqS06fk51Z&+%_UyN*&2+5aW#16yDghwW282yqLX5u<7%WGjL({ zsbeQh-P=;QAfVn*@kpf~#SV!QGKT9XmT<$qCsI^~vuY-4K{kA^$_Eu<#YV$KjZ0xf zNnM(V$p~RlpM4SGyo*kvfk<3if%24;X03I_;bBx+VYa3e z^2Z)}=&v`bX;PfGpi{LhaB~7)2v5ODCryM2q;?a|9=v_uYo6kB3$$S0%yw%oZw)_i zbMKd{^}1wbN^a-3xgf?7W%Mh`C>Q|b$i%=bsS2+g>U|&M*(Ntmhjq%(gZZ@%Ew15M zr5b|-hupK=xfv|BDsCRZG53nr3{}5)97E`9&$UfJhC^tyQi)7C0GJLC(x~J?-SMEZ zycOBkI`s6Mpl}%_z~Cl_O|xP8`s3%n{fVD{_=R7-I=mUJGxqmJc@ReE9pky+YII6V zZTXW)O03^6@@`yALiEY!j;Z;VKJxZ|^9SGa@%ic+&^5u(*QL@X>8Y`9L6CZcMnYUd z<$D~H!ANsFH}mO*ffk}LI#|pjP!LI0%G_Ix)`0G%C@f%tpjlm}Wj%xZQ0PJcCn<==P3)8sgi5b`+w9VkwP~n!_Kq%bpW>^?GYHp{a>g z@Gg*!OZia%I5k7J-K4vnU-{I#?_B)Q{`#5wJJ?jEB`3@jsA(f1FSl!(NtQJ_<$fCrc-0?xBb@F{)wmcGdSF&AE8ODwb;C$;8;@K-4ceD4c@4kLB5Rv%+*3DH3HSSS#qd( zcTH#dq4gUH$vH1>BQ}}h%g51Xol9@*sm6R`?4*e zdQAkq8kmQCQKY%KrnCnT^Q6b*zY*yl^Q6GkeIWGN%`jxzHBeg1u1rVa zszaT-2J2|xbk@K1jn_W%@K5iqy#bQDaiE>TuBvR&v=NkbHOD*myvthpRTro(%o4sx zlXP3uE{=Y)g|7iSH1Bu${a^m>Ips@1*ZBblZ2KaUv#g32LQ)-9yk)x&_i_UzR>k z=5%KZ|7vq(!LK647#$&!bh%uH(H^l>;UEZKHr=|4fZPCCn>j6yKXL2teflF`dFmIA zXYZmBeHQj+xl5#OI`nRYWE0keWyrn+d4Tvj>7v4lD2WrY2%4n1pWo7NeeB);yYG3| zBYtV%f)*zykJ1G}c?8MJIA+zZaZF=|Hbe;KFluT5&^x|;sk?|B#vZ}+WDToa48_<4 zfpqD@xAnYVq#WS6A(QKTx5~YQA?J=Xl>==Iu1>NfU^WjBToJ6MagtVMpv zp&p6|q_dNYY!Ro*aA~94(;$~oS9&PShU=*--& zgs1=#0Q%yb0H<7M2fXuLzQclUVoy~i2kC;5vE|kxAXq6M0|Z~ZOD#@xG1_j@ZEIit z2sqsrn`}c5%b@u|6A|RJS)sScFA0(1kWW z9qYUasdD>g!0!N@qTD+vGaEvtO*TUtA7&e3g2SxSv|P2%eDU?a@%exLvE`$7?Z6J9 zk-HYjQ zggKPB&NgFGsZox7UbXLIcz9cb%&<4e9RqP=L}H0rSs{ZMsC-9m;aAc*0z^730{S)aJQn2|7RRs$7z$}!{xD9|Yw_8i-J%gs| zP$vwNp@9zT&ffbxT~1S+y4HcoFe$57a>31-wJ8%Ou_R(^cK2?-`(iU1*p;#Tns*$n z3qifP+VSef^yIDUa~S@Cq*m-z$y+Kt3PqLe!~St zYv~~^$!RuV!0-StmU^=!@z>Tctc!zW_w@EPY(S`6irv|-wA;yvW^CrN7xX<}`O;6l z^&MZmzI$ovji&6bS3676WnH%kCs?aHJHo^^HX|Glz5e$5-uuPN-9y~XrQ=ZuHJPYX zv#_1mJ%5aMPEEpzl@KUVCXWsAbe9?67(43nE)EzPFN`l9an1dj+1-J(Rxo_evxXdV zoyU3^QGRo%3K5krDf>=vA{yCOUB1p~L~+*J65Vl}7fmy5w^6G=?C>n?G{$=(gEXl} zB#0fNGq#qm_B$>vTb|0vAcLdrj!=8@+1;;y^5;MI^e^0LZ@0Z;k+YfFdSvv;vZOWR zmQ8DnD;%vD!?0gPhDw{(Tdux`x-M@W|LdRn;J^3QcRcCyf#FLB78|BNWpf0gi!nH~ zf96>uS|!g&2j!E2M035+@#NfGjp(q-CibeQ$}$WZumko*#1f1MGS*c^l#wyYMl?0% zVO#Q|VJB38CN5rKwE(!Ax6EDy?#jgs%{CB=sdmh>Bp-2j<&yi(k+(}Bn1)YDs(3>u0J1;^ZtzB4}f>bo}&x7}p~;y^=0 z6e!uBh2KYJ&EehU4#?=-O^s@kVe#oJpMBS*-gkXJdAH=4h$*hFeQJV{_q*q{77OPb zt9%24)Nzv$=S*0Trl~S(w2MWWNlCp;H0-+Vzxn(RfANd&7Mr7Tm*dtNw?&q!vPSAD z8*ze&T%=z=xAWKGyWaiv`))mBMjx9)PKP@9{@$71qksRqaRG^ zW(O86c}9F7n-Zt7`maC~mOK}A+}&emB^Bb4EfzyGQu(qh^J2T>vHNGf^v3_}H~vQ- zfBJuTcmH-`Q8#gCY!!6Khf?E#s(Y2PSB4)qz+{a=4OO5q*6aWo(mziQEc5H}SAOy* ze)YTF^MpIpD((+3wqCAVs50=y^bSG*s(Yd$=UHP8;yNaBnw*@E?oV7!m&_Pk=HfhE zF^!2xO}=xtDB!e26lp)1`M-jcCw1=Y{A=D~V$+d&70QMV`36S8jHpF%iYd#VF6J+I zmdd`wq5|=fZ$8+qvj%a*JaJcx&fG| z4brIn5G(H@cG8*wh-!ZdaXz_=vZywbAaw5wXK)6)=wdhRno(M6KLo4=?uio)h3H#L z9xtFIYRj%31z)1XEH^zE8C^hvC`K@&2&p0$M+fBCO|gg3 z_UFrYzJBAI5C8nx^_#uBD_Rt7^P&tHT;_tS*hxm8S<94DQMfiir8ePb_$k`WXzDYv?H6mQfw#<%>uDq z+=V(!vBSYQEq3_UOCR~d@BgUVUZyxmqimuO@&?l&1`^y$=G`DO>)(g3XY z6R^V$Pxblc)zzE24jQm#+<8mQRpE}zSmB{!0H)B!s;*yDY5%xGoDjej>!m#8gsg3iE9bbm_9nBXae4lTC%a`pC98?D zTTdK?Yys{`bG7c15(RajkJ&`UXf?SW5fs%V^Zh`HdGtI7n%0(No5ieAQ@KTHG@=;z zxfDWu3p!Q2$Svy>V{ffG9oas!t1W6L%ThMrR1R~+R~{(!&eKbZqwA~0xTvB4!_pV) zZ#l#AzZgV!y1?iFL4j@&$rQUZ`{JAl&?n~%iZmeHTmjnA_6B$!ieUha>`jV=<}kDb zlbuOPG#qwU?S;YAJbwduQWY;()GmKBSKT6wknClG@M|81(VKN8d$Z|-R%&y#*OC7EU8EB2_ z$K9(R`Pxst^BZ4y?VG=eg_MEa2}YObVBoyNHV^4OJY_f8yxZaOF2D1QH@*JGOVpA$ z29UNLMmLxdul#z&_t(h(NFSOyaD3^8mLIrtb!+w}q2UGG@7G@SsId-ZwS=5D;fzmR z`rX_8f%|l=;c^UTH5I3>d(jXvPi;OJdaj0Cm`+hDVU>@;)X*G@V^yddO|jlm$&y_- z_W2x(_io%C6J5U~Tw2AI>Gni$#NZOVqodOr*#dGBab7l>oMzpO&)q)%_-8-#d*AwF zxAkuACU$@=v#5oLi`<~9*;@vnYwYWiZj=6lk5A~t0R|H{I=t_sd3o_Q(|`I?Kk?@u zcf8+_1jN18~87#V5(4sYFWY zZuIzA8Y3Lm^90Jw)&yfNf-Coz6~4)g)|lS-O0j$)ztV=%SjtyJUhUS|huO)Z$CWRboJD!!T zF&Ia_?5_Lanyy~h9e6dhILD~8X=ngd|7sz&k9By@^m)R2ExT#Lay38v+3&l{_wHKv zId(LUCELim;vvb#_J`@jdtMvBx!R^d^$gguc8s`>y_Is>odw<%(Gw%pCew5MeV_UC z$F!WG^;k2D%@oo4W~}8nUsN1hpw*kVdEapRJForJH-75d&%STMPWOxpW8>*PaAN?7 zmrruN!&du`Hv=BecV2b-&KvvX1O4*8lB3_{a^r{j<=;9X)iM zZ;T|)<}s%O8SY8`T(b*nf+0Nn{AYw_07gbAbJkNZkP_Ebx#WttN~J)CP8_|vW@4#r zY@SEW$E`O|i(}~VZk$D9SzNQY7I%+r29d0AgUhCQfgbt#YybMM|FggT&41;2zF%hO z04G|ux~Z9rfPhBm>4f=Im+;;NuYcE-USlgUWC(p}eXn``u4{k(XMg4|J^0XF9qA2f z%AU3($C^Rc|4`=)1NUk5Yg1k}t{#(Hw|9BO`$(Fm{a)lDT&7 zR_x%}yTKyt6n38@@DhDk3e_Qd=Hyu$5kL-}kw#Gvs?H*PnM_kMK#LN;pN1CnIR@Qpus^iNFJUbXm= ziMVaOK$0`ES3%YIYo-4xQm3zb-qb68I+WJB8baU+yPDh8Y$m|jXx0Gl`?H6i{OIG4 zez)xxNx8#!>*+<71gd7Okc`%-$<^(EXCKAi{f%Gw&CmYtU+Ql>oWD4G2HU8z_AeX1 zUiQn$@2h!OUH=4)gh&UL2^YA2T+Y4k`f~7P>Px%2dg$Wn{-ye~RJssyw8Ok>&tCdX z_xpfT8r?%z!%$Zl+{|pq3eyJrq;5hUy9z;$a$rG&8C#i&&Fn_ZV5Lj=4OhakAIT0@ zHX&DGJZuwSi50fY%g3{#ZKT9yk#_(lP3jY@W52w3$$$9i_xz1d{L5c?>7Si<4>Uij z?`cykc`+o`KK5k`P74r{Z3~hQJG9Pmz}$)*RuhE$y-(UN^PRUH{==X7iT~FF58UP* zMbnyw&fNBdH8K)W*WCBBTB5S8@q49#Gdu@E6Mf$zh@+>k@U&;ufLlaJ0oZ!774z=K zXxb|SI$nnfdVT|!g!BS z2^#6DE_FrA)l4LiRLfB6(&w%v2qP?8P(TRAb_l!MBZ!wZ|8ZW6vQs!$dZf8->bGuO ze(!shH#~GXwGPVB!%a!(PBL8lG21Y0lzQj~gHP>jdFeQR{xd&wXL>KNc;6xAh?V3e z$lQ;xA-IE6E@v&~25Qv`RNA1f+nDU}B>}8z=s3_izHOPK;@vBq?Pv{J(3+M>wmi4I z{T<)i1P3WPAr5@_7nse`T}X!HA%A&v40%>*75SSe)HMRwEj8lh9($an*FdG z&x7?dm!K8CY-xHjl#V=?^s=T;QnGWj&A6s8VZ(l&M8e3|-u^RV1^{o?+c zVp{^CMZ5pJvQ~IZsw*-;@I_NI1D*0ifBZM!`p9?w`2L2jmM-pAjvk;d3AM=v7_c^j z**Ab;T=3@8rAO?1-!sIp3gN8>uNQ#V z&=;XY<(n|K07XGf>oZ0O& zJ~C(*U1OZS;PDIIDIBJa;$ES2&X(plb3c>Ya6bk;VyXjKDeXg6%WU1%q5dMGP^J2z z3{q_K?xE zrOTkj01$P{Rg$&2>zHVLn~Y$Z3oi5wym3*)@}nh^tkJ!9?__7_H1y&@K`_(KAUP4O zP_pTBDjz@Vv@EL-h4L`wr1)bSX**1Sn6`Y zUb(@604D1A65js%pZxhZzWwXF-Sb)wd9LOfyYS&w15`Kd`kDC2PyNWpzy8OU-2=uK zyLm}A28A9Mr^#CF2p_n!Ln=by5(alL4znx zTsgY?&OEoVrSU0THpt4C6LQ?2lu2;w$8L{*`@Y}$@<+e&?4P*Wy$O^b0h>mFt|~^u z(iJPtAM;V}EnoA`rIeBm97`r7%{NsK0zs!+KhkeZR}cT-Yya$z{PeHycjCq3lZzQ* zLHRQ*aw`!iqmr`fb_QIK4`7iEGt*G-pndB=H~AA6cxIWx*C`0dq4a~MtR@<}?q})~ zhN2ijm*R|Y+eZmhsl_b2)2iabr;sZW%Ug*^*M@+k3M39K6)_?;t-5s+LoRw}2ZxA7 z#55$hW9iMk!IJRlnUpQ{mu=Qf3&PD3CPNS7Q8HQ1VU1(swkHSIP}8v-{4gB0!6iiq zt_r&Qh(93hsDT~sm<)0*-pv+~UVWHJsz>wiXdi@#vyhNG;%LYr+L_2@uuhoEo9DN` z>!CZ>&wGcX3BB?cHS|1x9b)#vB0*Uvj5N4`)^^9Qe&QXEKmUu<`7$p68bbLNE1*~{ zcbpRgelj+d6yKl7GhX4ZZGLV0c_I@FPAAZsi(WDD+HMv0T6x^4&U&wUEW7C5Y`*H#-D7h$g;~6J_@{Gw z+4R=;Hdq-L?2qEbm};jlH+mi3?99ViyKc?Pbq#DBw$FeDYu?pn-iXThSVk8l3Fd}B*s?Wdz#umebV1)&> zjXZ3DV=Ot?43in!*>Xhx>{o95+VB3UPe1i9-fgdyFTGD_ts0?VsPobewFIf%GJ+X- zkxXV)M63we#p7vBGd|I;7&xxYJ^aN*v%*sI59by-7o?*S1- z1gk$mXej-$Q$m8eYLB902ke_5nf&=99-rwAncKBI3z#JpdG~0+2JPV!;RYup~WDEpg+Ku+5MR z8QX$9b;5}Rj$m8bf38)NC{mL$cdUS@Rm=1>Sy2heP6tO_Kc1@im{JK zf+Uaq^qmr0o39r9-tYYno_XQjHa)X+HZ;tO^9oaLv>p&8M_$S=nLg0nFo~}?WhErQU<26Gg7Hy1-ik$27S6rE+8MPl! zbd^n+4jmrgD|TJFSdquD$0Rq+wK*`*8rvO%kzrnNG5h&pF?7+Get;{316*ZnK&4P& zFbL+*Zl-omJ#+qvPyg_zzx_+M@m?5tC7&7-BGp_I0Ir1(aWj>{QXv))itX2N6jEXs zad;w|zz6||tB!!I&#oK$t51ILO@H=BKJq(@8kVjGWIbL!og4faPb}VHYJH;0d!=4u z1yar(5+?Z0MC+#I@`!IPfVo+bCM?jWAXaYp#_R<~4nqLkVzYE>R4l0zAGzxKE z;?kRA$+|;JmQ*?~)uwVaHsD~{WSX_aKd3hZc9_TvJ89fu8{ViV)Tc3WF!W4Bfw+tI zUJ#oonp2V)+`YRqQU=k54+K&{?Wf+j?%K_`<*;l;wTx{D=xUf>`@qGun?jwkL0OW8 z>BU?0Tk_aj51QEEJy(S0JS>m?qaS|s`JZZs+sCEkK($Lp*la+KgOpb776Fr2+z9r{ zuM?|!ukKWxUw~+cVFqgr5plBQ03H|mRhB3iK!ci1^OJYq`<35+52nctKpe>sXJi{~ z5=_36THpJZzx~$FJ@zp)fpTMGN55nHD;gWt-4ijwm8pli(q{1M6gF8-t@GTzHxPu2 zj=caWHVnpD9h3XHmK(zlO_C=>?T$A0L+?>6xp_#r^Xu?dWS#$VKnRQSo-7d~)l3!= z1`+X5+*Lp{_1(-;h26#gZGDsoH(a`AEzun&oKCG^FJYuIkr@?7CN+5z*qVAjeCf+? z`Y(R{PyX(=|K*q32V!@Ea|eO$Sr1W8Hb%m=iXuj&a+DnmETlEdltV5BJcb1bv8fP1 zZba8?*k3#T_7A`L-+uo`e|N#eqd98)W*b2Cm2{kcgJ z<*IEntXuL72^{y?#x1%2U;z+U^}kEAWXvXyPTDll(HEcHyD~*teJ3RlcGjs5Ax<|s z4XP(eiqHttfB*UXz_mNAg?~gk8OLI|VPT$~t~|A%s!C%EfE$c`n)b_`7nUzR^0P~O z>mrD|j49gC7$d8SI#h_OKSJOS_W;(hp8(UXT3Q3{0tjR89uH0YEDzSzMcdz;6mwx_@-}j~aUi-M;Jp)=a?)HQpyDmGM{5#LT{ldHbkJxU);?5S# zsMuiBe8l6@?A>F7Yv85+PU?>!K@O`%5iIRc6kF>X1V`Wb;(qJw_}d?N`@j934}TVJ z@U8~I+xQBL8`i}@oUg{AJV#AzMPtLncqKPOswZMqqb z!pIuMDFxtaixcpNt;sI9m7@o`ummdN=q@KhusCZ{g1obLV$!%>nVi(|o5)X@88IW@ z1Kjywpm2zaqpgg}_9iRyta^WiS(_Yyi(PWh@|jBD5rR6Jc_$b5=m^x&TUMSDfYHty zfoKie2P)abq68lYyU1Le`~BDNyy~?}+cA?dhBiSR%Mr~C4RI7`9RiWAn}lYDg(RBk zOTYX6Ctm!S-OV`I(n@N$PA#AySB<>}rv&kpT0yKjbX#(LO3@MPUMZf;roME!!?M9) z9^Y+2S;xiE`T~k{Gy;ugn($=*;HN(E;TiirxudyH;3Q7&`|i6P^^#xy!{7g>o_YF5 zG2LC31#JQw7qsPgeIMZ02SliUH+o+u{4fwY?tOdn?eX5`7QS3_orzg@gEd*#mVRBs zy4p&hi8EpD2aj`^PexDzS^9fLL8t(CA>-KCV=epuwLE4nYo}t*Pn=5^8pMc-yFjYE zPohs$8YsbRNQj8bd0AqsON7Joyv7>0iV&LA8{};_FPJ{}wb%Z&-~8p@`qrO$asT0I zx8u^tsj)>2KXGi&6a>~B1U7tBKyLd7Svn`frxAHrfo|T23ICIl-rR+2H~hc-@$de> zy!S(&Vi%VVbA;&9RdN4%q^&l&G+!dqZAEgr8j`a0R1m*GyU64^Ubwn+c(A)dF16r zfCk75@}I);b>4MpcXq(X4hlKVLvuG14RfE5{pcR{E&5Y>luVtsQR+Y9$3p>cqCd#M z=AQjEueo!6zL+_w2AY~L)@Qq#c{LMm5PezE4XqO}Hg1joe=;8x3utAClWS6PQy3`taWCy7VmYF;(M4+R*LttOu2LP7 zXt;8;#dp0Q*4zY69tV|#*RwM>TJA`GFZ5@`dHNds9=WxgO2l!A%(`v@zjcHbfjDp? z7%b_~iHoBj&*rnKlTC0Ho+w|uq*C6j8>XjkPrvi=pZMhCKYyFwtKH7r;f+?!RO0Sl zOcR6K0*T;|0nc)|l37{rC2wgpW#uXj8-VZ_C7-;zuD#~?w|?~d{_o%O-mi6u-eJho zghGYpmxHF|(IF2?J6WAgOJziglN;fXns8{a=J4gJ>sxo*C9GN6C00j=?DZfRE5Z_A zcUAw1(p1G20&vf^ES>&aTPK1nwGDhr(o7Vgn0N>`xoUQ5D2@opXT%|wFIwPj)PO4Z z5xE*N`VLugzY44(eT>o0W9jCq@_&q_Mrp=^n*r@N>c7anv2)v>9G|DyrzbS{=oNHW zk|*3uhq`ldiyD*>p)%23jcULm$@{Fip{<=}#KpuzBU&B~QIXd%#o<07_ThTp+2sTG zUF;7U6`u`&@nV7ZCUkD6rseM0 z;j*<(x^0y`BUV@WJ!Un+7V=`FN(Qf$aII#cWQYLN_l~{QM$o|A1ciovUPt9dEoQz< zM*#~D^Kw3jxf1n6u5#3C@CVRX7~Xq5Lt$ZLt8k z>a;dKSRur)L4)S&1x)%!^#mMh0~Dq!K?f+A1K!}^^alS+AN>Bm`1bcc+83iQY63it z*vrshBJDyi>*AME8k}FiJA=hp0GcrFqBOf)fCZrs!QFMWjVt3Y}G#wa>v=!cI3P!OA1bEAPi(jR(W&3 z@9g;C1D9rH#2e&Tu6Whu)S(%7T@JP~)ed)=Y~tjL?XNG-f9q9WdiZDe=dbGiym-jz zR(m^^Jw?q91i79Zgp3h!^a8qGMP$>dH zXm&|n&DtN2H&pAPqMp|0vT90fB)+l;B$5r-_?HnD8Ww(lgzDx9L_9ZAGN%i?;x9&N zO=TDWgNTcH>FOz?W#*%%NiMS^8=rjs{{P~)e*CX};$QvN|1W{v24C1yGny05;2;PLd=o%{zSmI{&Lb_P#&&)(?Es)xnO?{;K&! zHacHLxL99sjWDnzzzZunTuO>1{>21L&55OPe&#N}J?Fu(Xv!pd;JA^Z9YQ6*HOY4b zHtAna_#W7v3g(Kr`pSxfY@t4q7Y4c+>Z>ZFRwz1{ncBv~Q*E&U)6HHNzsc19jpknB-2-%-(9YsJtp?c&d zhwJpIrPylz9_OHy_=FqnX(+QR%d+V5xXfCHm4LLUxBb${$bLk>g%ITgV^V1YQD}32 z^{bx0@4jP3Y>Z}X!rXP$J^ZNFN?n)oGT6=xZr0d1ef}T(&`bW|{r<9Rf;DN>5}}Hy zSyoVl^^c<(g?hCb^Nt|_%B_|-_PB1;-N>SERPo5hd!x&5>B@#(d}hz=~+d4rci)=C#bd+)n|ip+8@I6=E=yl~rJ zEjJuP`QC$jVq5W$s?`RU&d@Mq!^WhO6`jRK{5xeu5=@-Nu{z|IAVM{Bk05$}2W~hn z%dz+96DW|Fgh{;t-uBDYVgBS}_x)%8_@DdjZ~l+(?%&aPr4CtRG*L%RoGG5MmnBa% zk!KIx+}$vgPSHav_oWRV_Ax&d)dTpizMSa5Vv-wQd-fMT`oq8a#&oW^W36MM7>vYxeU`b9lSObiUd_FGoGCMsKtH4FRJG)|AdUv@tqsk1) zn%a|0+UfYJ*M0X3%av8wJtHU; z2~;kAg-D7)N_Qks9uPFW)-}LV>|yd(*Kh#q>cJHn&rBE;j50pX=odL~F7xOXAZhNnA*Pz!&GR5P-Z(?l)TNE4h$)=1)n z#1?;+E1Dw_utYN_Y}j&SJAh^oa9sN3@pyATIgOk;aMgR;UADGp>|7a4RVKU~35Wb} zm|y+cORG-&F*}-C(~Wa$Q%BFb0~g@o5STjT*zNnJ>C^w!AHBm5@28iRIqj5Zx6 z%voI7LBPvKyjA-J`2sPDbaY_8X}*J&gn}#5GHKWQ9$HP2LaW)&CYlRqHi-1Mw!irPAN+s6`t2{wN9G=FIR~jrH9%OY%k83XmLyk*$P8yzP87)n zsTn2%gsJO^3qIqGb$ng*;jLhm!0mZK%6vj&#Vt=bfnHjigC4QuqedX9GlHE$W%n74 z2698-W>akj-G*fa9c1ilS!r#ljv~8KR3UvG#wsVuPs0Gv)v{Bm)--p{j{@DCWT&jF zB5kW$IuXf|g5gmHoAp8jwCb6T zj|=xOYLRE3zMZ11`|85%I5l4Z(JQd+9ALgfH-$MlUy1#+uV#SOv!Nl#!W5h zt%mFhR|>?FMTUfFE29OH*ka=xBNaR|vk6V0%an){L>vw0RP;$m1GRMQrmfhm^2X}ZeK5hr9+c# zzNUMAuI8qKPl8-CaoKq;WpfIc(Vgavx_){5(c{I7+?_>NM~XVSq{x>GpbT^G^BrD0 zwn;BP+nDQvGeElGl~A?iUT#tU)}_Q2Hl{-8+>gj*jqR8l^$?8@Nil;=`XN+aZ?ZTHC%K2ntg(JVTFtE(PVEujh% zV7Su+gq_;%Hr1wOulDJ$zVkOf|4ZMw`y*;+6BhIx48%BZD89L()s=8$ao`x5(mqB{ zJX$tNMjiw7P;h89l_FYf(?sBf_oiwb&tr7SEVY3P1|0eaxpe$I&Z?&NYxQ(@s$Bb zHf{yAj>09Exkq&h83&v(Lazp((MaoZqmIjb`||G1Gt5^qBdzTY(j7@%*!br0pxQJ? zYTu3zJ$UDEfT*lFj`%{^e!5`<>L|j@OnrhkyLS1=$KU+OOaId0{u_(m1@?(qtWs&I z=|%`~OVt+bO^FjRyC(!xfoHt(>(n}I9IKVtR=rc(T8F!^{UROUvw+Tv(NneJiXp1bvX8s zQrHHN5>^a$H?BW; z(Ps}x6$&ddH6Tb&jU2phC~REAPh=ZRIQY7f1lVXj7o;80OhA|Vx9_&+-K^RnMYC6r z5PyD)V`e3LY7s6e6AEHoM<}vO>|p~3zpi`vSZtE}r%hD`puz^}Jr&{^n-?mCyJnP1 zP*=G{Xpn546{C+;8g&)}EfNyC!+mnF%PO;u8n%Pp1hYIctO|56RNl~DvAEjaUEace}{cgVXBH(h129xS8ReWYADjM5J8Lc187D{7xQepD>cJJYrdbB zup#4y8=Iqy$aueb+=pW9~Z0du~?S-kiqPPw!b#Ncy;yh-}z;nzp=NM z+z%;r+xgbaLh#lS{%uBJHGhC!p%ui51;s1Scsy?n10m6BEz}0`75yt;R|`V87UFWj z^@+4>XkgMJ?X7Fqr8u40UFrzY^z_FF8s=_()tanj{bD{c_qA*WdNPS%@Dm&Thnc(+ zRc3I9`!&MWjx7bTM1ZaL>pj|NZ3^84Si1{6b%{6h{B3p;^zuqhS@f;eq7-7(-On4_iE>h}8DMMl9HE2A}9_myH^i*O+rjEUSf9<&dhdWRAsoWg1s{3nM`VAidI!Dx~r$ zL796b^k@36?E=3dTZ8BJ#8FrV0Lcjk}$gCBkL>Yv%) z&%W%$=rfqXoRtA!h@S9iw{H46ZtPk7I$hS84raHPY+%V_e(sZFi65 z{H5cJYkOD&D7lerbcdatIq7{C6}4-L8%Q<^<{)*K{iU`)+OFTz(qaQZsuX%ye5myQ zhJn`c*SE*6nGNSH9o-LcX=QpatclQ;eyxih(SRXxgzqk3FM&67e3cxQKIKsD>o``S zD`h#*M6CrAs}gZ=Ad=DRfG`GE)rMgLLNo;$P@T*QY0={;p*Gvud^q2|`0e|C;}ieX zBai>{^Yq4PI^yCIheKbRV$fua zqQ<*d{@C5N(5BG#(8%SKQd$vgI#h z1sQ_k$cq9Q6jWt6#sF(CfB+MtM{0#dN=q`w#*_DAz1^|+UfMYfFj^}4sxc)yRlJcqb2VZx0e{GS<{&LtXEm2otpk*$ZjwW;1 zVLw0j_|4z@@}HV+-tT_9V>ji2FB&52QG(`|)bFq@ zZK_5b`SdV+iG^3Rw4LJUQn1qOo-1N{Cn#uH(0vE%8X2}EPCRDUd01dV*LXY1-ZdL9 z(wSKtf zfWGjh*ZjWFo?MoLHRN!hMi4X)->f>X8+PzJ|}VOKC$2sA%pFdF3I5~bBK zXd3}S23$(U7vOXQ;=DtbncGfAi|*-ZB~vtpNb7L6y!wIT?hs4nf+5=K3GNx~%LHTQ zCk#G;4xj(vk#{}cKe9i&>TYH&@LPrS)}wz5RhF0yl^>(Zj9kg?E0uw6@5&>S?SF#vA$T1`={isoUb$=)yBd>iU=&ldEVjhZ9D07pP`U zPC4xSxU<8HPu=*`$A9*--~Llq?R%$o)ZD>cRG6vHur{*MrA`K^H&8hQz|vt^C2ym} zhYtY|9<8mRT$eS7k!jQnsY>Y9I~~{TlOKBffAs$M|3+V$cSK<@BW_xOenIXWhcaz! zBBQ11CODPizUGC8dzh9X8iJ~kQ*+Yk{o5CKb}`$ftY;k$M?^N&L{@U3ghAfq6Wz2P z`KOc-*3*ixf!DZ(*HZbH)GP4%80%nPZdOGV0xJYjhVJE|r5t$XD^X#O)xehxprX7s zbo8RueW!8=IfRd(kcVg0p8?3?0p8iB6&7w*sd8W?6dNFYs*W_MyOIqBa7X;9M8*n) zt_8K_pVlM9o{fl!R*sNIYMmxGFb}+MkfV2RX6kJ61D80=ffFi4y=KkBhTOV&`M?90 zVWbqNOy{zjB#B+J%FGdvn}EaF)sv6k|LM>F^Ji!KS$BoA0{4}&8dPBgN(W6@|4$Ab zaiL_ZlSAQ8h*n9;o)?{rs-Nm8BA6aXN(xP0`PuxZe`7#bGom+24C1G>lbM&d+(1B>u&ULN# zgLH*DkTW=$wh$K`{itcVn%ZGrYs$y-wtE0p&tpYjrRO(lIAta$lT1e-fS97CZ*0Jk z8L~uKAdN70pe_3yu8!wl{QNtA_sjp>^T(gW?#8ZPIRHCE%tGGPfyt^;fkoS~ym|iA zNJ*`sje*;SrCULO5GjZ*P8ltiDsZ&XT+ytz>FB^Me*DM2=im9BANayDTgObJ<(|w_ z-jpQDNz2&O%BDkut|mI3I}Cl zQ<+5)q|A)~M!p5;-j;y>v8E0LHU>y1)q-Drqu~t!w|!M!MTCJ_I80TF$KaoJ=}r{X z2DxrVS-+%VUTs4FjbQ;AfVo)X%qgcs9R?HsO8+3GwDTc zU?+hIGkJAv{jv+Q;mpAbp^q^Q9xO#)-h5qF@FjQAdJ-l}ofsR_%EaX^STI^H8Q1`~ z26Vc-k>1XZX!~cr`Rd>K%tyZR^q;z%eqevNjpL=;REi+ZHdS|bSDtP)7FjrP@7EAf z1^vd%wliHrXKA*o;r`G)DXU3UNm$@?pI*2Bdw=A6{~vFA_a}VWi;E1o#VzQfm2^OQ zNU?JysL5em)+m2z#I;Q#l{@g zV&!K3GFZi?O7cv?l>8qNH%*j7N6Ia_G;WR_8rnIsP{uKx(tjKlo2xo1iC9&70g;s2 ztvqdV!g-JCfm|jwS9*1zQgyJ4-ASY1%)K+Q8fNH?Fy+#+h3=M%CS99m!Gf9Pzyx%Z zpCtlkyQ|kfbmwrE2Xsg#d31SO+#?AL%3Z$5fN3(B_B;Q^!|(XQWB=0OY+8HFV+uZVO`Fv#STa8 zrxbY4k509Gab)$p2YC7#7#4KG~V{6rC&SfB|sZ~eAysh`JGZ!rQ;K$t*&|* z5M|;Al2ZoC4Uo}#r@?8RJD->HPkicKpZ?N6^Su9*ouBXL7qLuiqo-=@Db0*aU%FZK zj(QoflVsYEtS&2zyLpxU4P7Sz9cJms09i*F?CQ3dOT7D*8-MGkfABwe?d!k2%qAXT zG7~N7|z%bUxSc#VpfaXUHB7BvZ5JGZuFMP`LcI0Gs_;LMh&+ED_dnqX{-Im zoH4E`sldP=HNs7ZucAF+Kk`^l=74ja5snq0#j!-;zetPvMD^aKiPhI$^;H7iC4)f+ z+dMqD0a^bK%7F9zeE<2ZrOoo)#AR7T(kLN!;sMM=o>dD4P>D1iffkA7;=2?i#1?%DfhFjmkKV;@(FtJ9k>3|kG=OlebsB8o@a|{ z){OkfB6=|-4uxam2^AOtqoEs2cKz`C|IH6S`TS2` zyZ_GY;V+GZ<1l#KsJ5{(Tj3jOVPk>omkHdG<7IOCGP1txGrjyvr^{29t$KEdTc{3~ zsAYjKYz?%G;1aIhy;ru1v~+a^svqT7AgzIomF`}FW!`+%Ca1&Xh7c(Dyv+%h!@*RD zPzXI*fsINu(;@EE6+{*1tfD&PX}h;27uUl8Y=}T9j)61!l#$4L)ySq4Z7}RceQC&J0gO{c&TT5n z%ieE7i{plaqvM^rXnhCu*w92l*u~4oN-nESbIhY`T?%(FE3E}k)6{8DY=B03RtXG= z3I3W}$D224J9D?&7o6B8`Mzn1(~5R%jn-gjn46YqI`5A?ee3fN|57`DO~-|EzX4V& zz~2PY#&VVJD(zn@S>HfK#xe=4?I$O{yrSZNIic^h9NRAqgoxtcx;Ufr;jwhLrK2T| ztR5Vj@l^3blC*bQX2!wjV18f9?8>OU~@AmJ@kYY%FLg z2qs^bf3Be>!3x-Ib!5!~fKXhQc1)0gt&wCC?#}q;T^+;o2!3`~?Qlv?C{$6zjKWVD z^VV+J9wF3j*0hyQiiiP5#b?~Ig^o*)6%=8`Hp$KTXC&1JB{p{@3l0p-0MrdbHb)>R zHV|eIK82BpC}ezyAj-+5Q$CBtwcAAVrx%!8Gn{}C~{fshlv%j-myTt$jOim(Fw||PR}ry6!EKQ zZDI7~oU=vkMIQ7rVV^wm&m>d*S)Rvya=YTX^8+<+Yo~xSMyE!@OZ< zIy-*uzxdd5^M`NTyzFtnPOQdh@^BMC+s1)UhV2h95NNqtJGL%gVZ&_ zxZ+kVt)txpiVAmOlOD)mC}bvB>`KMfwGAN=q}F}6cvH{QeBj8_;oAjwPj%Vc&%_Bl z-b>LM)Jn^7zRw_@g{rT%ZIHQrp+Mt{@6vo z8%n}5dzaq{!?mf#E8M5px}GpS;|K`9LHXTyN4cqF1dad~tePz)GkXA>g0#c34$9g% zO=isur>#;#NjdRKL zmQPEk`uIYt4cD#1}2Y063 zv)AAD`a5rU@JhZ!p;_nd?7Bbo`2Amg>?f!DZgk#u?y`sYu;k>*1Y3sSDq=&CY@~4| zGXcVh7!M7$0>?dTzc2mJ@d#xRR|e@fw0QW=3hdRcX^ZHUVIRvV_r6* z@#Djjt9km?s?QYXM$C@sTKoFDUjM7_fA8NsOcNIL>|>R!)&jL*fV%aTjx0AQa9e3! zklj7;ZUA8+HwuNy6bIYeOP# zA6^40Koy}tm_`I*D9Y+BSNbnI+NFUWLhNHtLu!VRQjR%6O;F}4(_1tsPC(?C2#}TO zaL9}f^x82YtMcK}$gvGz?rql2BbCxbxW^}4U<=UMx}Z3Sc{oXm5HH~!w0bvfXV`}| zcN)RFA^|hESqqx%vtd$=N&==$3(Cd>R^ljRJdbNm`w{+v;pjR_`zXmL;qE}EGX`jM z_vo)4n#tipH=E6T@q6%i;*geV4EkzA54V945QrxctjPvlj4kOf62 zvX|gy%`+oF6XS@Mh!G||>HyOemoPbE^f`$1r39>gl7QNl>*(IxcTp=D5@8b1%@#v% z1^KLKcem{mA=jjwOHQJcR{^Di4kR~I;B=^h7uK_+9cE?@Z{ zYM5!=roP{i*ioV1H%pIV|51e=*}^fO96;HZ8s!+5HYUOl#}4j+Iciilh$4Q8P2o+L zrH`qC4>bYVYe?Wn6oY!=D%tt(fWCwAR~yBYH^)?ovRXoCaNAZ!fD z$%M9S5CtI=)tzVO?GHZi(4YT-cmCbO4TrinuQL+|la11u!Olsq^;E4vQ5F}DQKm*o zoPYqzS~(0rYXL_4W!HBu`b=-tM`AV3x|f>=t{57IRm+w{9-}G-+sdwL5)4m&W87-V z5jHsnuHzlG|20u0puoul{ljrb?SmNMY4Jh6H{O~S*WmERB5;yJSsv-r#fH` zSEC!2$vlFEL-kj1Y}MgurM%9I(BSQ{HDTD;8h27{wV9jc*ShU_d|nx+!8PRotVX1= zPis7}I}n|sB@#Qc<}$KnuQzg>x+g$r;B=T97kWeQW+u;Eih<{ct2ey*ZsX3qV2h^x zq*tHyC!TGW$IJVn=Pr5i%=yh*vvWCK>Nh|A^OyRbju|@3SoS)zO{@?re&pDMd1F(WZx9LNwLk^}A!?Nkm!aV9b?Oo(zrlZY$s8~~%N zdg4HkLXb_=Vh|}!?j7cejYKq=oXcXD7p|ib+M9bEl6+#cW2R|)2Ju(|UfnX%l1Y)0 zLa5P3g6dOS+@~*n>21IL#b0{j?$2qu-}UFhw~4uNuYYA0?? z_lc7i%e;XPL#j`ii3MjBOComHemZ>hy>I;YKlt|F!oFc<-z^a9Q1tT7PD6-ACE`R$ zqO3GiU3e{W=+HF$%+-&aNpA08ZUk~Xd(rR0Oa7uTbnIqf3}&cNqV{$u#fSi-)O{le z$hBh{^I`!OJyt&7F2uUod1G}~N*D78h=Y}?LcyhMJ*V=7BJWTDN1|CZtqRh?(9;yv zWyXjRc|>em87Cmmh*{O~YK4RBo`Z?w8&>nSMnbuf4-{$3a-4>? z8Z%{dIvp5VgK6B1XTi`nvWJWYJd4t6kng;KfAjJW~lusZ#8$srg zlAc<~=)GUR|L*dWtXEvIV>eBWmK2cQ0_C$2uq z1Gye`2qe-RVJvQDxgn8G-_gn%+dm07w7{lN{jBKuAU!t>`%1Te*&jvs3`}ed(-t&s zu~;e4_`A6iUFxPuaJc)@tve}M>}8=by7IbvJ9fiCXS<`}D0ix%Df=a2D5$8jWj9~w zKA!5Q(e~9I_(>K$Op~m)F5n2C_g6MgASN_=-`$u=! z>j?R^mW}*9kAE5qRAoeEX=>&i>NTFtDiLvJ4@{NL+VDcfbWlRM#j#^bsmX;Z(GFeR>)-yV@A<9S`n!>w1~@w2fK_3aNU#9mmO=v8M$}^)$3{_&OHXaUy$WnFkT^0onbN1! z=nId+VduP2vy0=AlkX_fOioeWE?@u9Q@749 zfrcfEDw@{M4`#|>kS5A-ahdJDV9Dc^}A+j3UIFW zw-9U$r;9F56r0SJ$mLD8fJd2JfYGfr5az&9yll%|zR(ZLwX7+rtuE61< zjzBlkV&+bzVLw@Qgj;2~V4v&r*Rcpf5F2$Kc>AGz{`B_8y1kMWc6xlwTjEl*L~90# zOe;OA)Ge;fNc0xpT~wk;M28@i43-|lYmQhydR}BfG$)@T`;(qgo`)A-r;3HKB$_zN>M3MrdWpL>g6bIRD-L~sqsWo z5MxfC;#UhURgJDBZsUzQPT5_WUp=$iGc1he$WMuRXRlUa9y={Dl3O)ha!^*In7FNy z&h9Czi4CGNG-FH|C`#4MD5_aRXhfc;>EKs+e%Q`15h_a(C5G+5zi)=^#dKQc!UpO}&Cdb~cH= m%5{hDc(rOcwLF41_m_WYhI=JvVh6 str: + img = cv2.imread(img_path) + _, bytes = cv2.imencode(".png", img) + encoded_image = base64.b64encode(bytes).decode("utf-8") + return encoded_image + + +input_image = read_image("1girl.png") +mask_image = read_image("mask.png") + +img2img_payload = { + "batch_size": 1, + "cfg_scale": 7, + "height": 768, + "width": 512, + "n_iter": 1, + "steps": 30, + "sampler_name": "DPM++ 2M Karras", + "prompt": "(masterpiece: 1.3), (highres: 1.3), best quality,", + "negative_prompt": "(worst quality:2), (low quality:2), (normal quality:2), lowres, normal quality, ((monochrome)), ((grayscale)), skin spots, acnes, skin blemishes, age spot, backlight,(ugly:1.331), (duplicate:1.331), (morbid:1.21), (mutilated:1.21), (tranny:1.331), mutated hands, (poorly drawn hands:1.331), blurry, (bad anatomy:1.21), (bad proportions:1.331), extra limbs, (more than 2 nipples:1.331), (missing arms:1.331), (extra legs:1.331), (fused fingers:1.61051), (too many fingers:1.61051), (unclear eyes:1.331), bad hands, missing fingers, extra digit, (futa:1.1), bad body, pubic hair, glans, easynegative,more than 2 tits, ng_deepnegative_v1_75t,(big fee:1),more than 2 feet,incorrect feet", + "seed": 42, + "seed_enable_extras": False, + "seed_resize_from_h": 0, + "seed_resize_from_w": 0, + "subseed": -1, + "subseed_strength": 0, + "override_settings": {}, + "override_settings_restore_afterwards": False, + "do_not_save_grid": False, + "do_not_save_samples": False, + "s_churn": 0, + "s_min_uncond": 0, + "s_noise": 1, + "s_tmax": None, + "s_tmin": 0, + "script_args": [], + "script_name": None, + "styles": [], + "alwayson_scripts": { + "ControlNet": { + "args": [ + { + "control_mode": 0, + "enabled": True, + "guidance_end": 1, + "guidance_start": 0, + "low_vram": False, + "model": "control_v11p_sd15_inpaint [ebff9138]", + "module": "inpaint_only", + "pixel_perfect": True, + "processor_res": 512, + "resize_mode": 1, + "threshold_a": 64, + "threshold_b": 64, + "weight": 1, + } + ] + } + }, + "denoising_strength": 0.75, + "initial_noise_multiplier": 1, + "inpaint_full_res": 0, + "inpaint_full_res_padding": 32, + "inpainting_fill": 1, + "inpainting_mask_invert": 0, + "mask_blur_x": 4, + "mask_blur_y": 4, + "mask_blur": 4, + "resize_mode": 0, + "init_images": [input_image], + "mask": mask_image, +} + +txt2img_payload = { + "alwayson_scripts": { + "ControlNet": { + "args": [ + { + "batch_images": "", + "control_mode": "Balanced", + "enabled": True, + "guidance_end": 1, + "guidance_start": 0, + "image": { + "image": input_image, + "mask": mask_image, + }, + "low_vram": False, + "model": "control_v11p_sd15_inpaint [ebff9138]", + "module": "inpaint_only", + "pixel_perfect": False, + "processor_res": -1, + "resize_mode": "Crop and Resize", + "save_detected_map": True, + "threshold_a": -1, + "threshold_b": -1, + "weight": 1, + } + ] + } + }, + "batch_size": 1, + "cfg_scale": 7, + "comments": {}, + "disable_extra_networks": False, + "do_not_save_grid": False, + "do_not_save_samples": False, + "enable_hr": False, + "height": 768, + "hr_negative_prompt": "", + "hr_prompt": "", + "hr_resize_x": 0, + "hr_resize_y": 0, + "hr_scale": 2, + "hr_second_pass_steps": 0, + "hr_upscaler": "Latent", + "n_iter": 1, + "negative_prompt": "(worst quality:2), (low quality:2), (normal quality:2), lowres, normal quality, ((monochrome)), ((grayscale)), skin spots, acnes, skin blemishes, age spot, backlight,(ugly:1.331), (duplicate:1.331), (morbid:1.21), (mutilated:1.21), (tranny:1.331), mutated hands, (poorly drawn hands:1.331), blurry, (bad anatomy:1.21), (bad proportions:1.331), extra limbs, (more than 2 nipples:1.331), (missing arms:1.331), (extra legs:1.331), (fused fingers:1.61051), (too many fingers:1.61051), (unclear eyes:1.331), bad hands, missing fingers, extra digit, (futa:1.1), bad body, pubic hair, glans, easynegative,more than 2 tits, ng_deepnegative_v1_75t,(big fee:1),more than 2 feet,incorrect feet", + "override_settings": {}, + "override_settings_restore_afterwards": True, + "prompt": "(masterpiece: 1.3), (highres: 1.3), best quality,", + "restore_faces": False, + "s_churn": 0.0, + "s_min_uncond": 0, + "s_noise": 1.0, + "s_tmax": None, + "s_tmin": 0.0, + "sampler_name": "DPM++ 2M Karras", + "script_args": [], + "script_name": None, + "seed": 42, + "seed_enable_extras": True, + "seed_resize_from_h": -1, + "seed_resize_from_w": -1, + "steps": 30, + "styles": [], + "subseed": -1, + "subseed_strength": 0, + "tiling": False, + "width": 512, +} + + +if __name__ == "__main__": + url = "http://localhost:7860/sdapi/v1/" + generate(url + "img2img", img2img_payload) + generate(url + "txt2img", txt2img_payload) diff --git a/extensions-builtin/sd_forge_controlnet/example/inpaint_example/mask.png b/extensions-builtin/sd_forge_controlnet/example/inpaint_example/mask.png new file mode 100644 index 0000000000000000000000000000000000000000..166203af05d94bec271dc3ea34b4ce41135b998f GIT binary patch literal 244 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k85o&?RK`JHULeI-9OUlAc=M!AJ&?m$;1OBO zz`!jG!i)^F=12eq*#dk*T!Hle|NocXoPQU{YWH+;45^s&_KYFW1P?0 zUEdshWBk8t^-pH{hs{4(^e>w`IGVrN{Po${+`;@W54>@hr-#KGLn*#-h^LK(*BdXq zF}1yigUuU1yfLc!-lK-vpUsnHn_}jMsw760GN1H+5PW(IW-)a9H=TrayymxPP z6Zh{pvvdGx`2qm=YyXa;&I16nU;t>I{*UtD{_QW;?(WX~tgK#MUMw~iV3xlX`Y-uE z8vM)he+~bUAIsnT{#AG6k`|Vx9`^3!e=8O2WbfqRO77-t3br6;{+~PX|8v6saO*$( zU{bfRv~aa>e9KDvt(Vz2TD>*5qq&W{jgup}jpP5Sh5sLu{f7^K@t^(r4X}z{0c>Ly z0DT%8fV!9fps|nuC{WIu2I61srih>o{JryZ$d3Nm@89@M|Bvv02q0tMP9fcFtjPaH zOQ>s-gFRe5|MJ^C@i%}05CJp*8z2Bk0V?1fzznbhJb(Zo3P=I+fC``q=mACm7_bH$ z09U{Z@B=;pAwVP$2P6X-KrT=Olmpd3JWxFb>QBi@-Xt4IBVxz$I`GJik52 z;2=;SupkH^$RKDS7$Mjpcp-!#q#zU_)FJdBOdzZv93ea){2)FIO;LWr7(wuqk)(-5l>2N5?A zZ;+6XD3SP()R1hDJ|d+d)gp}`?I1lOVcY@s}$Vxh92%AuO02BK!7Hlxm={y;-Oqd^lxGeYx0OF?Tun?^fFM?j}V zmq0f~4?xdEZ$n>3zr(=7V8c+saKMPdsK6M-IL3s-q{WoNG{+3aEX3@`+{1#xqQa8E z0%Lu~D#9AXI>3g-ro)!Qw#AOb{)#n1NWG*q6AFc!Kzjgp@>v#F-?Wq@U!R6qi(#)Rr`f zw43yV42w*d%!Vw9tcUEB9EV(t+@3s*e1QCtf|x>XMp_T8Y|^x{`X027!i`#+oLTW|-y|Egh{6Z76LE?J*rbogAGHT_xSd zJCt`K?_Ay$yj!4$rRSx$qtB+FVSr@dVz6e&WSC}zWaMVFVa#TnWrAViV{&9FU|MEI zW)@@iWUgf1VZmilWC>zvVfn#I&8p8D&pOQd`kw2({rjT#>ui{8@@zqD?QGZV4D4X` zO!fs16b@;QK#o?9D^5mE3(g$Q6)r3;C9Y7eKCTyT9&T6eYVH#rY914wES_avY+hB~ zDBcl17(Q{nK)z1CM}BU8cm8_*p90JRb^;Xw$AWZ%7J@~BdqR{#rb78b+rs3+Cc=5b z+aeSqrXmF*yP{O0=AtE{M`HA1wqjLcKg8dQyNWl7|B~RB@R#@|2_-2b86i0(g(;;a zl_9kyO(|_9T`7Gj!zJS@^Gy~;RzWsic3F-@4lGwLcPY;!?=L@~fUKaQkfE@v$e`$| z*scVrB(IdHw4qF+?5NzL0;tHTB&uwx(y6+rcBsLssj6kF9jddb`>79WU}+d@RA}65 zifhJdu4}#1^3dwjM$-mqmuvshk<>}h+16#%_17KOBh<6eYt@I-*VZr5zcY|BNH#bC zae+cWONMlY9}Gv02#xHGx{T3`O^q8&U`%vODolQxs+bm--kHgnWtm-qCBUiRGjmb% zB=ZvsA&UfyBTFI61j}P9A*)2I6KfIc6zg*v37ZU?D_dFHT-#rEDt4uIf9!SaYaHMm zOdQ%AF&*t32b@TqJ~+)fGdhPjZ@cijB)eR?D!7)oLAV*ZwYp=!4W=eM-g$iS*zpwh z%=CQl()Mcjfbqfc!-O}3cewYFkF-y*FSIY%x6hBl?~~t-znFi107QUUKwltLU~u5U zN12ahpAbLUeVPn@UTd`XtHS<;SYil)gb$$(QO=K-l>rs1JXHvIRuTbCDz}ryWNYj|rgw+($4AJb} zeA!~%vfZlJI@>1S*4Hl3-qgX;QQAq-nc0QY72A#29o+q=$EWA+oAbBxUaQ`{KI6Xi ze%=0s0kwgtL50DQA?cz1VX@(!5uuUJQU1}kG2XG3aqjWv39gBzNv_GJDekG}X`boU z8NQkJS;5)vIgz>EdCB>q1-XUsMdiiWC9S2EWzh2Wiuua%s{QKKn&;Z{`o|5JjfhS3 z&6F+Tt%C3L-)pwHx4U*EcP4fwM6kJ*nqPoz&~P7O{E z&YaJl&qFRSF0y{S`_cGQ^ykE-?&ZOi>(!s@s2hTt(p%2kzB|>st$T<2=U)*I1P^78 zypO|AI!{N>Uccdfr@hd>w7)96Zv1ih^XJbx5DY*MM6wM#Xv*Dz{SobB?W@`|GmJUJ^%wAG7IV$ z3W5@V#DIXpfcP`;HV6SAprQWGb^c3WAfcdP0SGvF1PI_w@mKy!1-v-{4Fd}Y|7Q(A zhJpYf(V@`abQFzex55sE`o%@`O5D4*M%fBu%d`wPOGc8jMT3272`Eya6FLeC&|%)N zs}#iQIueqZ3*{JgL6}(Z&`P|Y!M?%}4iBpX3+K?*ytSK?!d%XV_OFrM~gF zPHOSaVo^s})M>Wsmh5O*rN3EJxk5%%3l0~VMs@~aJrOYq=Aih-yOP1<0w4?R$2wo_qV8(RN z1SEW#ho)<8@zvoOYt;s1n7y)AbWXA+x0` zdw#RUk)`CK{Lur?q2tZ!A|17&(x|Vb!>r`Adi57-O9y+h4oO`FXLYN;i^rX=W*V~a zN9g)hYxRg-=%V%zG8Fo}Nd8lRp*K$FdOUiWz4tSGp@AaD7q>9%kf%*t=!c)o1?bneEy1O;!-#6>iZic z)B3*6N9=PMcWomiB1#l_mep;Ctad%cR zmf&T>xliqWt~xahb}vx>QlKE(6&H2T*giOQS2f37#6&!FX{)cjv}vc#pJbbmkgcz8 zU?-bYmgz>Jw!mi>bLzz3f4RBNFxeHKsJ@HuWSz2MZsht4f`1e{N@-LRWthgD2VVuw z9^T~KSxG!;)+5YC&OF9&U`SW0KWq}jzCPN76FyQTgoPmqKd|@Sj@n=?#Qgm0WBr84 z(K)4>oJ(Fh^nA3WtNPIVdMX~qD6`U6TQ?N50yB;h?jMCp4mObvsVlQIL%)h-N2=Ie z`&dDfohaw4Ut#Bvw}aC&RJC<&#?D&caE!I2zGyYU6l9Y6K>7{~v-tG1B zFjb24coWMSa_W6*E0NTI@xtdgQBE6Uvk;XLR8E)|C#c* zMuz5mq>V;VGF#)8yy~E3;|{+9zg2|8`Xr%#+1tcVaX(~q$udLRrk$GNE9UO*o(6Hy zo<=H!jmm}$aZl6%9s0ZjZ@(I6I&)vFcU%lNOFr)o*j;X-;&940pY$=df{z@v!4jR- zE1tT~&`MbLpfV>cW+)L4qUx4*WxCw%ylkDvuu@v zxPRdsTWD$}|A*zGgk}>W?O}!NDw}+P`7aU_Jvvp2zOj$elLFW%(p!p9A=jcGJS5f?tQBW?TI*TU*q8rw4w zfdeu3aHT_WCQI(o;|rN}ns1(T()I)KM5XUmtJdV(pL>v=h|uKXp>-?;P!UH2$Tt(^ z!M}vsTH$j-w(}B#xg<5>+tW7AP}d)&Cra>ma&3V_7Y-(vn&ynL4#?swPnz=eJna zcA*b*&cNnDns?DufRdQWlQ4twwprr)TTdO{85F9bzvh+mof=wriRvFk&#wjo*YjME}yJ(q!4!*%8_%d zeZsEl%@18IGYw~QzyObdy+cvml?rf$GI1Z>ieD|BbVsR;$A*Q)Ha>N{PX}|$A#NAn z=6`JsN@|^~po~A!RGXQib%Nx~{({rEv7)8FDV2P>SH9v2!A@#Vd6LWL^w^83{?0OD}!KA4DKp)H&M7r-P+|#z38))an60 z9yRY>)Ye+j>cPa2m|-VbPPEFekG&(mgyf@+W45kQT8D2?X=CQ1R6$zT1rlnmC0oPA zPu|7IT$h^EwtXpGH>0Yho7?lOt;EV1_lGhyEid;cLRUk|xtp9Y z_&G97E+h7N66Ex_%kW1u80HZ|>=$u~1j3JzK?r0O=_jAtX}5ouWww6U)h-09$4${2 z*?Axh*d~@sZ|u%BI>>3@6kF@7x5#z1)={b0AZXvu+q#Knmn%`Q7Dw$pyY^YwOt_EF zr)a)%_GPVyG(LZhY1ss`@RsWv#3GWG+DXAAC}~ESXA+LA4D4N`Ma5?n#%dcskS#c{ zEH0;8j`hhka2eWEB55tH)p8g~6&}~L6x0?Gg0fbaIlUpc)GZ+9z0+mi<{a<&p)DY} zbklkXP5lwnpcB{}WgTh9QsXbx@vw-;My#RO6_{tOH=0g zlgcTnW4<|Jdd4NE4Zx{6gc*%nOMqybB;Hrd&|44#&s=%P1s$%;=1CN3dc9v(Cx8x) zk3=ZvrnoL92r?-j1!|c*23P9%?{(h;?_S|iNmq34Ox8`fOuhjP?Iv8rvY+j{xtYyV zD5jO1(+qN3sN&>!DArh}YH|6RJs?aKXWif+E60AJGBI9{ZoeqSSu)a3#NwosIHK~f zQt~IZi$`o_C`opSNr|DLdG|leM~NHxOX4J`gR^tnTBj6!-uWE;aKzj{Ce%n05?d5KFEe$slG&-5g?HUmW3Fn1HONr4*@VK`tLrt{R;1V9w512(@OiK{$aBpLLdw{u0Zs2hMu z-cZfPv6BtHO_f4ftqfucO~zizSs5lz@^=YM*jS=8U!=$TLefh32v;y{>Tm$2!%mO+ zWR;v4DyxGg68&i$iXFCZw2h2XKHNzqALXZ9o0mPsL`$fA(UY#evXgRibX#M>DJPv_ z$TjU(v>jhJh16mv^&5Q!5>1e;T^whS0a4?q$v~r?sXH#p@~oQKqG`#6Z*jrlWrjRw zW(Iv(YwKxxhE$D~g&l5GfA z%Is#_DCIX7GwibGx-3v*uE6U_CJ4}#$B`!H=kI^zy!a4oV_iNsAI;x7D!B~X9Q1^i zPax{PWsyLq1Jg)>M|(-CZP|#zFLnVe9(swoDNg3GvnZQTgUA*GIWr*{AJt43z1t&c zwG&;e7EST83$=tm`s-B|Qkjf$ofiV-CzHMIT}>W_WbTHuik64_gDl*$Zc~BTSX#;K zGGA_IveP>^loV}2?jp%qelE)T8qe@&aRs^?saPT99m<@g=HoUh)i$LY9)jKq{pRJi zp~XL4M9y69}P2C9`m4iB zBaJkh+#JR}E3^0%HdOOWx*d9s7uaPLD*AA@&3lj#fzBA5M)GY-?icBFk_Wkn%bE{l zR0P0W*<9v}F3M=zB#mxjo~uRSs+h9BF_1|Zc47?&hrktRM{*PO6Y4u z+i|>8X2oABvMF1SFIgGZoM-TMT-it!XRvBt@f_zUf*pNqhb>|~d`U{OF$#FQb%Fs7=;X_ zBZA&a&ozhgk@~{5QO5tVtjMq~yo`E-WFY`6Bri&VG%9;eZ}Da|*IbsiFIx;bMi)5 zLJ7hN;y|8?hIr78+=o7D?-KWgEHL`(-g)ZW62gRh5?_Y8jW&~Ohq1A;@ z;kP?obzm;))9B1t;$;aGvG*oI&|I*%Ncyrgd^PX6BC^*VQ5GpizM5Te+I?6`+D)c% zJk@vc(N1>4sc|qjXicTP%ba1g5mUa1!Y<-W$XbVQqEWqt#uO?Ur8cu>*#7d#4|&ci zj--}*#=(KM8PAhwg@)71B-y$_T&;rsV}n{#r19q&6$uRpPGnKsUIq+ByvEUU+clcH z3hETmUW^d|gjE#Dv5|EIqUaV(&MBysC4^0$WEQjc3d#wCyUt$^>zEIlnJuq#Y;=Qd zCW^MQzu7rjP=hn&isT0Nen=mtjS|6kBsNQpMwru#sk`9NVS$}?9ZHl@zKArgDMrO- z_k3Yb$ERhN9*u6pAF5lV$cq0sB%D7q>MN<3`bBCZnVqzBkK8c;5f*)Ah`JgS-nS|% zuk_=iFHbF8gAZUMSOL%u2UQ=Jov8q09lPmHUM)-bQOkL#GE_sB0&{djf>oJ^n%UzT^@QtC3^JR zAfn#@s9=jiYajyFxtheBx5#Np=1eXRk6}XJn{sgDsR7 zl}aD_T-N?keB3NQ^Id|BDKWLr;U0yfYdjL24F>j8Mr_NaBK-u|KwZKwGTvL_{FS5F z-}b@fZhY`A@&dLS??<2MN7Ch(*F7ie_|{f>Z#+0gHT)t4xD!1Rw9x{50j0#=w4hAv z3WV(mG0vDFl@X*lI&-ZUh4?L+$qOBny*7o!i}PyTlY}sry5B^)*K;wYo+uZS(MVgc z3sKsKJbf)kX92c1`!$`vA5{nMdz?mYb8WfoUO&91DsC?-^5wb3?Bdmkq+WMH9M&xV z0oc0zu^&BtOou+NXP*r==b~+#-dQIF7CdHd8fPsCx9liBsSIA#pFJ5((|K(Nd@r|0 zKHH=E>;k>OXrd*q34_TeCPKdJ=7k_%TtT|1xS&*#+-gnyo9v?mIAN9*`vmdlbrP*8v)M;O-9)!HeSdGf=1{{Hy05An(#4`)uf&FzYRA z1(tOu_Y7c3q|wdSm1NqtxDzQaue<;u0&)<%v(n;0CC$b|BpBC<0hrx^< zouh8Ax*4IDtBv8@mbEP-0Pf&>dHS&tdcK#<4_3Zwqn%S1Z^WP91;3w&$jtw~_P9(x z6U;MSes!Cbym=5J9z5UJs;qJcC#&fC{ajV|7r4GYI`lD?)46dfy&7&xJ`j<7$hpgO zY4}`sH=yr^L84aJzBE6{Xj7_=gG#Do0C%1;#DRDY{jNQY%A$qIXv_ifUP%dAjU)y( zY(EZ%4Jvj5?f2+YPi)tmxb%zhHS9>Ao4ww9>fcTvLDxiW83DEa06g+h8&>yo9dj!S1h9_JdB zPF?n7d$Si8%}8Z54IgH#jP&*fI@zip1*^b-?^%Fo5^1u;bwI~rqTjFE&x7}Z8p`)Q z8N!L%tB18z9xfcNHKd2P!f_8PUgQtcbE8iUV=o4!sja1DV%IOE)=VIk`UlEdY02dr zXMfRUzBS|q`S(~&rUpW8lll)T3vI#Q-5*NlACEZ>d(U>xj0zrqp0LI}{S>n|6E-*= zr&dlgfI5M_B>i?6WQ}T~NYMC2LAsXZg5cW|MmF47B0PFV&_%d(8~(TUR^GVws);)7 z$Jrl#FT;tQfwzBvQM;>}jPDGb4dSCs3oZ3Ov<#RnIiFM(1+`XskYD4^HxRX6ufQWY zO`m54tth|TKk#?nss7G2sB}i%J7U#1dJ^oW@_j;sD)af-8_@GmQ+jSKTC&1+-SL{*_HOeet1?#1$d#vyN2w$>q4um@KSK0mpsCbEly}<1mJKXBLv_2d`X2U=EmK9l6^uW0^r0)DXYTj00qRdR-av+@`(E2a^!n+t`19<8MH@@rJLYevQu2*O8WOV#?{D(WI>!td!&*HQ;#y(ra260d?aP~reGm}nHA}|soOy6a7w%b2b4x}I z*YQF7aq;N+d3@(Nmdq=*@5!@mzF+C{twPGxlb~Ifx6Isz(Xhs?$mC<7$lcb;b~g8M zEMMfwjBxJWBOcSwjbT4;sf@aX`)!;BG4=Z8xmjpP?Tp`@8sQd(Y?(FePLdZc^6g z(Iz(;w^+?t1M2&h8G{m;O&hy?{;Tzc^pW}a4-oRgv31kQw%Cny+ueGU>|~Uhy;k1Y zGMv*g>G8wFG4R+pdEsN`SIPR3v|_mMi-ubv(Z z@-c!dkbpY(docpvqG1@T;JF>XOO07&Ebu}#`eEu!F}T~M>2`$XfTrQrtwX^V;By-* zc(!-Q{e$xGcdn+%htSnmyoGoK(7_8RC2YIGpBJS?NM$*#SFnsDPm6aW@`!x@b|Lo3 z>jtgxL!iQDMG0SzNa_4?J^eNdF zU%?)(-rJTOq1;?b?S`3~lNw{b%Dr2ixt_S3?1%3&{^d6TT}rpz?&smZ*G~fU=%flk zRtE2y+bT)qVit2|j~6+vpZ)-(74SN1IUDeE6d8(@LEY)sZMhuZpK^!zoa}$s{4ym~ zAe$DE_?@w+U$^v{xZ~3qbXy%z?_Qb8xSX@2#;3GQg%K)Seji)j?Widt_!4@I{|DeR z@|!O0xDBvVs1^askJSwLN8A3w{oZWk(fDhNZZUc_!2U2-;woU@t2fw(*MFF@=ELL9 z($B%J?hhp_!xMi1uUCiK+0d246ZR)BAs5mbvvRv>|7JHVP2L2tCu6FA5D4=Y{FpNx9`xjv z=_9Pd^!|d%(RI_F)a~}kAm%nQkj@F?A`Z-XLCw%Iq;Vi+197cOyLzPEnqjJ<8+{fW zd0<}EYZ=oa+uZdau)alBxPx=duG4f#wh>f!KYF`zj?kR)+$WxsCvTshCAh0qjBk@7$Tm< zy*@iKEOLxPG&b*aloG|yPv^XYhsvtbv6$0v6bL+-8bFwr#t5rD3aJ11f2UoP$h1IP8@Z5G1y1O@L6sdao2hhpgoYHz)w!%xS zp7TysLGmz~Jeq8);^+mf9d&=%QJeooMqIhZ>#w3Z*BPRwwRSN6gYbZ*!6`*YxXO#7 zDVKAvI|inQ##XE3n+V?>EJlfFl_Bb9ezGzhWy~YNuhZW%ewZzcT;vlSY9t}m0Be%r~aSUIij8I2BQ*_NP?99C9` z0>=pIC~^M1cl&Tr50FXpH!rxbS(w2zONV$OOn7Zd>;8!0_(h0oRa3*qEcgc?%U4On zT&$L$qdzv8mM7%YF^^u(RYz85;9szXQ|>Qgd*=jhn@XOH19hQ_Lbx%r`+=mUEe*l}5OzzKyK$P? zZ6+Q$yk|nLvE+r!T~|=wUL&H#)jQsARE^CIBBc0=1 zb2WVK-pyyH;d)N{y#B6TEkbfPnx~UepRn45Y!0=N?=whqg|8Z5P%k9=?4h&`XS?*d z3S{q-gK zyJKXUl}ov$y;U{5N`ncG&N?+6G(kQr1Hs;2ApTtT!-S6CHJ~*?i={T-4xR2-&u4+p z^Y2NgtBtx5M5>nW#;5Uq(5Rem-x@Prw|2)UuA|+1&u?u;qDBlRU=ZIP4u&aw&whFw z>(smCi5T;kDpm{E^Cvh7QMzrcRrEDZRgKEB--9ea8tVaN`|syu(zdIY=L>iqRmRcg`Oc1-&`u@8{@jMCUtqmzP6q$i&n32H9`sX!Z4P&z+Ce&n z%WVk${er$3!>|jXzJ8Lu$uz1K!l$r_VY`K9C8a_Vh_rYCI`(2EM*%@`DBtOh;WaL7 z-3D1vLQZe4>jPNQ3~;6prJDsC2B$5JiM2UfUDg6Q*K^!ac-D`2n=eyonq`Dckc3L zfKm^KZ<^axJGK}2m=zphn<+bEYqD178AXGcdI_8IZuaw;%@`f9^!uI=QlnSo`w z+gzT&$$Q&dM~f++2ZCz-NYBU4i|$c##_5C?w?WG`f!EKC3^(!kiYH;>h73M!!y}i9 z{60vKC%)i0?^^-8I9e6_%xd{lp0MxJ>O#E9HR)G;rK}{W%$tt{sZg{floH;@6W;X} zi($z&;}Wjh)gLn_&T}LZ#hGW2f;%IWS+iaFa^ZbsvmM&T`{u&-sRmTIAa2f*!N#KF`cTNLUXiepDA-5lJ?eVVz2O zWrq*da6Fxg@AV&mOOMJZdg1p@NykT2iUNPVZ{7Bf#2rQ@`9Ck32)}IOR)6Qj;6zS!?$BUp9 zGFXV$Z^W0jG`o8jCUp+*?O}6ZpP1O~Y6cTZMx(t=3a%Q5AZaFSiEfhlQFG2BS`b}f z*FWsZYjB_o3znXWwaS&EQ<5lAU>4hqaW~6vWqDv|mvf4b4xyu}IaHRHED~ZmF`Jf77xdBlW)BAg9nKZ{$$SZj+?!l@JPBR!e5DbkwzK%Xa-nX#S)e zWAHaDM?M@yT7w1yMH}0=`?yR4H^Pw8r3G&I0o>%4xnMCy(u{a~aBahsE+`1IS2=(& zF@9(|(`7-9IB96qk>;q6DR>ATN^!We)?2HDRP94hB+V*HuR&cO?bZjiS)mZ#aZ%{xu0}|ELUAwGP9^+9j^M}{i{?wIFd_*80fty9<=2TLU0eH%r)HdiqW+~w5?uy6H_mmZ26Mn08;}3JIWYHc;bw^_4xsrSig=u$E-V_vE z#~Cg^|IRnLHsb6Qwz;dN6ysyd%7ENRxcPyoftxD}T2*b#(srHST63+ zKBX-c@`&p^gDyo-SOR3UjHb}4(r2PMm<+{_TL*%TcoYlNKUQLRjB$7qFf^boz_Cg5 zavsW-Hi}Bk8$)Yz)N3D}6=%|F{aTg~dfqD>1~hy0W!H!-Fk9zC$^HSTFH9==f9f5~ z6~~a6G0yg_7Dl_>w|9GhO}DiPSMH@-umW7IKG3n>{;rX~s`lhqxjcYZeEYmZU*&Q- zg&kT~TrE&cQA%thU@AwCV1W7K7HN%hP@u8yg6rcc_8GxKC?sJK=RjLAn!(bXlRB|2 zDensB#w0W{D@Cninx!nhxEoOQgosi&RjM;CE)PTL8yy+z)NVRE(6GvP=u4bR>UFC! zLFDabIbf=&l&+){iG%A`5;`#wmbO4$QY5*aPVXt$OzK3KNbZYR%*l4d+AJ)Qnl2$u z`DyY?3~x(BMt@!KdAt**WVGvIr~-+83DVJPl9R}t4E*KGayA?I+TWW=lD_w(oCPl$ zN4tA;T^KxXSR#87ekLq{iphCk#rY225R}^O$eQ6}q@xx74erUvI8WRKzT?J2ep0~K zE!A4w^IMeXWtP!iy@Fb{%`kyDb^UylQB$6m{YhzjENy=c7%%>I@Q{;+h0=ihmM$@8 zgF7>=tQzx>hDrZ0R>>txw1|WDz3hgS?%`gXM|s~t!MBeIbP~>X+T_gWHtDO$X=Eui zw?0-%!_~7(6<7f>Kj6%N-*l1jpK^%2eSG65@@d{*`~snxjxXmj?x2`}o|TKrz%&`7 zI3_v_g)Yr~C=t(npw!sHd&?8D=DEWVO^eQKU1{;Pk_FPceV~WCCR_I_wt>u)zq|u2 zzZIH4+?1yQp723o%!Dv0oa%FiS)$XxFhd4!BEHL)eh&r9tYn&aOzU78#r%hl(ooSM`>`nl zU8LeR9!X8SA77Ni(#aSQ4B#}nPWX0gZ#S>!cL8(Ek32*FMbW>Fz5Ovm`?Z?9Id0S4+{KT zzG0)kUOkV*gNT-{Y7Fw&nn?gIO$Q4X63uvTMbTzb3)8{*beqsI;;PT6wh3!PeZpp#4j(#{x(60^cz1hO z=4QBWpZdTvM=AVl{)wOuk?^1BFY2LU+UZs)>N98Qzvxh7MO6@%P5}C~L(FNc9Xzo1 zt@JDPUGc>y2H^7mLh&@&{rYh7Ay%_+HYD+Sf%^N6kZ*n|#Lh!A>k2XRW|;``5;bCjps@FR@z6XxNmi$ zszt8*tFR_Wp7;Cme)uJD`)w-5i6Qi7XX@qQK=Dja5iAYN z_`ylyiDf6P8#*-7Cg`eT{-MfNYF4OtYLpnms^Jro zo{TE5Vd1329SZJ3$8FrxAJ|qU6%{Xd zUa4>Yb@d8JeTDsdfyx`h&A;;f7volYMNP@i>&>UP&+#2^kHk>p=eJ`=&+T7(uRlN) z&RZVF#|(dyy(MJ$=i#@9g_e%TzjFWYU|i5;`?n~+xwICwv;vKO{B&r(`$vL*1l4b0 z_vu*0YxL&k*1FNU;hS?MfAe}sexuYk`k$od@*ht8Ge~_E{_$7t*BzSQ_BYd>>z4n} z{{i|VDr)YN|N8RE{qJ1=MU^j5U4bUsDLp-$BNxfWiz#~4p_o=$KBE@i57dV}i~Fvl zYO(WZ1#dHy09tSFbc`EL(=J!QSk`8k|)wE-NPc1fO07Ii42Nv0CftDuAQ$bm~&K7wn4 z!WcdR{Iw}O5c?yW#pb^5lFGY7#z06tBjrjsO}A)>Q8-*3J$*sSJ2~^Qvic92L%pkW zo+^v1RHQOU;S~LIl_Xo{9QASGsoq{zZFp4SDHe*1)LAwVFD)aPYeU8up=z=#$JOcV zy$Pm#rfE#%HIgz6vD4JuGI8}GnsDScrhd$hO%R^Z$wLZwGn+1Jmf*U~_$+VU>i~nd z2DI`9Dwf)Tj8KSu`KjvBo$&l28INPLw25O^8hqr@{qR2k(|m&56nO$G9#yo9*~C@r z80v~5t;h8s^{g-EN?W0XhXO$?RiJN2=i9o$@8o?wfD(Lhe8=yNOx$k&w(RM(N)qc24|3&U}&Fe+sigexgRfo)OmXs z#_8M55FVeZ`@RWUxbT!QQuv%@h^!~yp82jT%}A6J6V7@|raN0pp~bqnUwRvL@)~;= zhbteh@8{&7oTc%m)k7@AwB=9mu6S5g1D*EfM4dH}p;)L?)yh=D98_UTnK+AJr)D{t zgMAqDE!huxe1loxxO_aYTD)m=az&cq;M~}&`o$D8hIB4AYDNSkmKEoNif`u9<0tTe zX$eK_XtI0=laF$A>Pl3=L{S{SMzvE!ehjzE$Y5OXzRIX&R8CsVL;bvX4XwAyG;ytU zE6o#L^2U6}eu!WkQ@*(=HLT<{E6rux*hL6A20>n&T-`~0?j#w7#Yv3gMsfV)#ewBu zf?x_6#I_vKL1THmuqy?=56Y*{k`F4BQhG$F$Q#^f;{0o^yjOZGqJt=#raV|b%LgTq zccug_C;~ktsgfPBe<;B&$5=AhTy7&U?8lcl$bBY5gvIp!-NDI9*vO92@ZO}Y`EC9| zec-a6U@v!=qBsM-%9o8CW+-51HQi4@1x3MbBJ+v4{-QQ3qr*d$RD88G(T!3B&$q~s zr`5Ny<6G9?(%P)0gR&y8yL?dC0ZZb1@6ac;33W?(C-gpIg!SqQp4mEciwF3O#8{8ps2O*;1&=PDuy zkPxJ%9Cq&(b0&8q{VHRGbIg_sZO1v>#~s!b4hN9SBg;WjR4P@%eFBeA0y{_3lB!~m z_cC&3IrZJ!D3RM%jMo zZ+>qQ%H=5XdDy_jp7-J?y1j&FSNC>VuP}z&>l<0+DS-i$^o>dCXy&ST`kr`Xb+4G` zcZ;}2UGoi7&em_H)FSSOzJ++#|%+-?e9fmRAEBZ`YbS zQ44w9nwyJcYBj+}1cn6YBaFjS)+Xpm=KYb@qvuiz77_D+gbSC9+VP9h$@o`f;QDR& z_h^SZXVAqKw7|U{W!z%}s}pr#K+X3fhm%is#<+??{+q&m0Ad#Ns7X6xzBsCBL-m z!uFxv7LET_j-7cYiEV3))Tm^;nz&DM%##pZlWVVBk^Nqgg%4$Gmatiedhow#MMPQX?JR4%3%Ym1NuTGe*odT8Masm zO%L_^!*plkm(e1mFAaMGqTjb3Qk#>$!EG+WD#bc`{M>rk^|6=mLmw*}AufB3Q*$$a zl75B!PnF0*`!s!VVU64#ruxJ%-XyK-ZitOI>8YH_NE>0HQygMXdHk-0JfT9TTJjEd zx>YzHhQe<+wvMwq1FBt}a~~&L$#UQL^FbE9V!^?kJK+hq9>jNi`#NRqUKS`Gt4xDq z=i{Ss`aj@2UW9f>MTFGZVM5tHN3~8X1xwWyWTKu`C?_r=7qbq$DDcAFCes)->paYj zVts}Et&@igBrRH3*E#w1mz$ko567I4G)VE1RinXLXz1hf{Nc{30YTOjfI&ZidQvXG z@6jHc^a_LdRkVq|oa1`j`Cc~pHZ{wOs2utYxo^9st$UR`?MloQ*&`fB86!r8`9BX5o0~~>UcIqUBKIPUTM;zW9H!c!CG_{pi z=12cs?JH(oLF5KOyP`nzIEGrnxnPO&yGVvBKTUp%G=)Z80`Ky&d&Fz9UI0`mgvCpX zPj~qWVSJ-P^Hi}}&0kty?pz|RHc2w<)9N}9>vRxDf`Wn5T^(RmBdAX#grzfYP}Qa9 zJ@?jg8S){PFR+~kb$JLo<^=g`+bc3 zJ)lN_J@Rw=jIj)@g)IE#Yo_eHYl3%A^H-?VRnPaA)m{3(vX{zPA7(a34%#Zk-3}VA zg?}DYTXhwM7&Em!oU~S#I2AlyW7Sr@MwlRGR^-x8;J?3|-bjbzkP z*zRQ8Ka?MpRp;CIC&DIWklH)-Mm8Ru_YGpbKi}q;FD*WGpQmzklyz9dxcWx=vUYK+ zTI$Pol$Yf+%vxz5O1JjNe=$?0dA53rcr`dRFmkBhuzk9}jkI+Z+O7>hSI%>O_qgUO zlD*^p_-xCYJ-&PH?v?&)=iI<~UrkR<&BNdvaz0>y_hpe=-Q8SpQ32P>2Y?tE6{FzQ zMSU*VwEFze)_Ht*c`zxpZ z_ir@f-tmSb=wJ5ooO2akcWrAFs;fC`ht5$emz9?vKeyde1v_I_p^{=7Uh86h!#HIcdQ3`ouK#8}4Pec+NPn47z#C%0HUScW?AJ}xegau*f~S)`4lR*+vJhr|`Ey&qQdt+?Gk-6o=o!&V zy=g%dgc27N`V~X3O2mVcha`RiHaL%}YF5~^Il4dAGC@Lnt6MND9LI%J@{e&(y*0fj zji+>klS{alVjJHLbww-H1b$|OTa0$jfm zhWkG6tnF9SmBdMbU2jDOXRnrC!&L_GXD5&7-4HYjt?HP+v4N?yvU=(%q%pPOz2+Q) z{U-vY1)zGh;MdLGea{omFRQ!0?|p!`MM&VEyzgSf=SF6CE&Zc8ttwLmgBl4Gf5Qcm zi(bLTMnbT$(TkVxuU;d(eu)4(vE=XI2$SL!7P}}0(C{542gn|qP0SCR3;*GxQ7zRc zhwjPE(=$$SmAty|{|uR4iNJsOTzS^?b1AQYQrh8P0(oS79IQXFEQ-?0kfV<~v zlJ~QzyHB#*WHNzlM$mcw1H%?jd9D?fgT-Lvr!cu$>@obRekz^kYI(7&e3OfTfGX>` zmHd)J@>vQ}t#2r^t91Y(?y1(4a8*}>9cdQer74hkrZ5C&bhM}x9cwJvULL(+Mz!$S z$h<9P;slr%_0g#|ypygfGBQ)xfBCX6QFA$OLN|=8f1H<6|3?dxV>?)leCe2jjxW#p$oE@_Y|G-kMf}T## zb`~jE41qHoneH*2yit>vc8&5!ZFFPy*B&9aI&^Q;a-RU%@G%yF`?afS>mWDKm>BZ2 znaagkbj27{6j}1KcBWegs*GHN1-MVQ5HhsRPCiwVUY5`)Vb3`=RjEz+8?KNSIylB} zZlv*jRMLKOZYOJo9UKF(>I?a%pd_}^9ZBV+wv?Yls$jmT@F<`jf5U;P z`zRQzjDse!T_oxoDtQ>=H5RMH#}z~O^40f14?ec$2h>%3^2J1jD?TN6@jJ3@3wbpM z+>S&(3>vusM~Sc1<2XjR^d>`YL;09wv4^}XZmW8>8aC79S{*qCe>&J@zCGYoJ_D%G z5DT&jhJlhcLUq0QpAP+XD$b_zh+>i`cC`-rW7C>lwWRL9;pqHj z^yV3bKVPvZqCcy*)zQeZ46dnFh64MK`S0H@n)6ZY(Ew9HIvjG}INd64sPkz`PoEIy zJ3Hj>v7*$RClV5`9~&jD>Oh%`1l6Ff?x)XW=Dop`C#K#`Y*)jf-Lo3N&!uali3B$k zHT7=hz@(CbI=PkX`*6G!ke)<=1(d%>?FuKEuEk?;|Cr?fr2FGnn5;$4Bb7=O$k8M@ zCj{SEkm>5C#Z+cJrIzW7&_S=B?1;wFdh{-?(!IbmpPMofl{^&02(+5Xs5vYZkQK;h z(3G;6a8^!DLXO;V#HVCe`|J?*BS2yka5Br{J0zBVv)+>hE8z@{Dpdr5=v;u>P3W;!x5&l{31a)9On?R2B5_V=x@A zGnf_E@xzaJ-r{P@tU^#dgAk&0e^DQIXh!+sgq8G{N!-tJ0;-8HW#VUSK!&v$g@A+{ASo%>&9N3dEL)kIowFVn8p*kF$F_iAFOT8}V^57QLBp)tMlgQORaj6yrU~rnDbHEG@-`x=Dfg zsAWk)-_Eyq_iIk~)_Zr^wo?l_1UPywcVrJy2n3(|XxpkI?e_Hs8F>2T61@Ne0rcT? zMrj8;x7L=LpzuBYNLTS$kuwT8LgoG4+1hXAy}-jBe~(%fQR?aGTZ+i)Qu^_f3{(8m zRb0!S5%|U#O}Au$*@!!IxpJe${ELkXU*VrG4anzf_E);}!jysYqShvsB~dziu119b zX-HJtQhaY;Lr@qdvu@S?!tmCxClF*j) zX5RyLZz6S2t+;SW7bRzb$+szE`xa>sA?Xur1N*558XL0{EyB;@=&?_Vx;$sN0L3MK1Rb& zveMjTO=529tpG=RL0o$?RyneaMx2rmJe7c%h^2?jCF>6(ZMAVyDq{bD;;oFf!!|s)T*)-k?m<6&=t_Fdcv6Klq)j@oEB3nUk}13O6HFii3bRl_|7g+XOTr4Yt6gUn?C)@6C1gG!ll*K&3G{^&7PaB_RJu}; zNa`WW&i8P^W@(`yIgUHd&%Ml#G)n>H4+Q1$cLZUpls93hGPCx|xxAB(CU_Bh$|?Qb z(X3GaiQYtAl~NkU*!83Fa9RtuQYtQ$sM0clhRwq2mdZ%&0~%4@JREJ_QY%Shos{sY z`;>+bwM+wS3Zv@Z}EGI!H*j()d!kx`AMZ{T#4F zOPnnTSU=H|?a5eDPv7A}HF_P95NW7W#{`Rj`ebz*CDU$wpZ z_84#;i0ft9SBZN;lFaUn0{!IqzPbEkfKqQ&BP(;>Sa*4JYWj?|7r@a0%xWG^(P+D< zJToG)ldh<;*R)Bv3H((urNLMNVZEpoR7=7QUz4aSWB|l=ycr2X>Txc79f96Xg;(kd z%`QfvC?4t8%|um7{sF6 zl4|m#*GG?|g;hln=$kOPY#rz1on z@zg6Wo9QaYG>P9#m@7L(@6 zT&mwzM#4%nm$pZ6wu>GqgKt&CJa9bFI+=nkoNyJ}h~gqf8-?nAv>RZNu&|)=4VKay zO?!v#Tv8BAnwhNrWbDX?BxFTC4RYw{I<*>r0xe}#SXB0m<<7147mPxM4}mDV&8Ip?aELqpQ?!)GyV=JpJe zH%XB#x+$@e^?PH>O6aSG_cS}RxeSdA*Zbs>i^Wg_W>Y@efTgMFq*I=@b*e=RYu`|? zaw=sE=orZdnAfHS(d3K}TS}>FV+Z7K%38XrmKfaOa+AK9@fspf&Q<^D1)hlTn5c>g z?jJd=HI~nm#fU#m)gTlK()lJ<`t+J|#m<;$t^-wr=X%Fb-nV2oX^yIXSxhGK$n?v{ zn3P@0o|OYRtKOC|-T0rN>;nhmb%R=&S+BlJk4$sJfd(+LzKMD=lO;+@VF!FGj-qx( z#A*4aH>0RqF;Jz&7~2DxKScypQYXeT`p+j|07#^ec zF06`qEr#tGljHG>Xqs0W#z&QDXJ~IK_3lab7ge^%mk$Og*gNaB;_4+65UHL_9IE6J zLzx>GCqsVZEu5H3J|RQphOnK*JBHK@q`0OYP6O3&cZ^21?p@etyW+=!eXx@kg7gh) zLqapD4_q@59H~+|!nO0_IuNa)Mv_$u(2r#tC*pcTRz^B?Jmh)gRM?!A3bJ`gPFQ<` zIw|Rq2fDUF&8=uC{+nOk^t|+9>W&E55dqj(7ZqNTa?#6p>1sY8opq6YmWv~%2RfO) z>7Ea2UJh|{hpPJonRQ4rbObN^iq^BIsV;)oR=>vJ1?3LjY1MQ49ycykF*0(c#=P~w@n(k_p#%fDNbkuUu8PtP4OK7L2t{4YS z>?W5vEg4~URiUY4DRv$3%|fiSGCr zMNHW#Zfx0!j^KI*^`bBES;d|M!yPOQeOFXHg%JzkT16Fl4a7K1qkTK_9^jqDAxhb) z5}l0HHR`^WTt+9>VcsTFTsi=%f-OVfuC&}aLlfb|Z@9?lqwwWm0hhj9uC}R?G!y-u zN?C#gYGG+%jOdjw$4k68V0j!9YT(&QmszZBpfPgCAn$ZdX)dvMUsa*LzZIyJDA7;b zBYb8@PP=m$AD$JTz6~pe-K5GkHB4yWW|Lnp>iEY&&aJC?nR3cJL89@PScaL}8ZC*M z_5)^;rK?4)l}Ij)B9aLHLsV zQ=U(fGRbewJyNStnl<0pJNhuY5w6lz75FHBOMTOo8`@ZM4%L(fwc^aC=qagf&cr8z z0inIUiqi+ujL&H_yE4v|o`5Jq-k$ABb7T3fV$tW_1MVu?!qU`JFP@TCtjDN8fIUwo zo}w23sv%k#yxL}&VYTGNz0s!N5nU*>5^Y?T^Cag&!@tHf8~<^{5_35+X^+_njMpM^ zhHa~H!Iz&D!pTyv5xDD&joE>)t1!u?wj1t4MuxM#;HN%jaEm0M}K&ieTXvlWiC1I zOkYx}!RVv(Z#W(!X-#&OUIz?)5imeW>TN%gSL!W*mGUlyY4swc6F3Yx3@vqt@u>ZLcE;_orF zS|+iq@9{O8Z#IuO+{6^jMd#l@Y-sa~>eU76vFw1hS= zugZ=srZiMJy+7vTunuC4{jIF6dT}#?V9<>R=Z|#4> zoweL%sL2}6@6cCTOs3ju6Bt~}n_kl_ z*JRIh?D*_KdiW_oiMIYfkF_X)lkstdo$}|1#RpuEkyDD5G8(CBdHNYfG_~PZ>FiYV zbGtscKH}tLCK@VCHEZqUrfC*EjZE^-b+EnQwl4hxvI`jv-Ys@9R`x9Kg?o-TY&RbW zstsmr?=wMCu#56N}dO1A`u2*q9g z67IcG*pnU&y-S{n$;7;%BpC&;hwPPx?6IvC;mxw`cOBGuBS}ZDg(f(w-b8|_$~I^6 zW^zIu*+w~0QUgZ2F9?K zvJ7GS9GT04Nkz`QAg1LlTCSEYq|+SvMmn*3G;-`?z*Lt~=8@)-PeaV$7BQTLfx>68 zVp6D7C$0)eO_!91I=GQM;j>2fZ#YZgnY#I-kKXcc4;&>Lag5T-O2M+G8Y?5xC5O6! z4s$^*(U--e8bw`3l}NvUlrf?sj@YS2n66<#iZT~eBmU2uLyW^&fn}@GjC0yZ0yDe7 zOBuxj>QzkDS=nhO7aaNv%TK12Ho&=HCfLzeTbp5JBuPztx>lR)d<0n_eN~?s0N~(; zA25X-r9;Bt;L(Q3O<(Dd5uu*#KuZS7e!HOTP_D{&8#^k6GeG6jsGV4Hg6>DQ zZds>DC^N=t)w+1iW96MA<5M`{aRu#Jvd z$VezygjUk^Y@LjIYyjEGXs~29%4vs8DJWQ*tIWt#XAo3b7R3^zy<4(2!%zAeqKkh+ zN{|$~H;9{x46J6Cp2?_^>x5^#Rmu$4bh@H#!PLoASc3RCcui8oJg~={Pbl3VF@^!9 zxal;$$O=v5SGzfA)Lfe~=(*L_p2`@}_Cx#vKLo6Vq=avE)syd-%w;ehsaVD*l$jmx zwIC80VERisY!W$>da1v=Ha(9cMK9K$-V-+d*&UNI_>}GIDMvcp8guX%x>J&feuFcY zVM$>s5Y)_npy5KzrJTxtAfK}TRB8-cPhi4;ts%U4^$NC_@b5EHUtm(OivlqW?ce#a zeE{dy{#ilzc=qYv4p$-^cb1@p!hJb|yN`kUNN2f-V%QTDNRzNz0R^J60)?=8LLq}U z@6X~qj6e#03jWwk*d0;qzZdL^%bvg34}lcI9{C&7sIz`(GQl(XQz{tr;hDRBQ^^p)?}{^o(v5SGE*{L2!5{2xC4q{F7P<f!T``!-!$s~VTDrXS#N76qJu+_ZFKa3doBmIdu^v2(qO6XvK zQStGx@WFTq!~6yQy?DR~x1FjXgloRUtsaD;Ks> z`tQoQFAtmQ9mxKJoiJ(L=*B^h@>7=`fZonlSmGaU3IT(Exy(lX(_g`8@gZHPcKzj>PV4*|3}bM6 z`A@_D1OJ-`7Mc1dlnh&y+BW=;pqD|gglC)oQ{rO{JYC*@W3VeIgg*YucE91`{`#%{ zCp!hw!T%`izpDHH3;AOdowWe#A_Y800nfS6*1Pk)YF5s-M1m*JKns*F#c1{!7e2x%_)% zywDiKax}kXkQ-Kk$FB|XHP6VQUR@LGIFI6dx*{)ve@e^dmRnvt`L3`$n;Xt?>4in= z@5Y{wCZ4dT5N-Zfsgm+>FjMryI=1tu7h>^qo{bJ!`zgD23riGj>SI6#2NRT$SbbztuSl6TY+>)+K30a5;V485PiNrHCHV2 z@bWOo@Gz0LkFvdHcOm2}Hwzr4QG|jlgts{wrcMP?OJJL0n1xZ+qMly6n;q$ZdEG17 z5pYDIEJubr@tf|gX!@;x<$yIm%m4&buQ(n6x?uETQ__{$&l-yn6VFddHLxFz1g(L`0cQe^u`m8%?tG@csUE1Y_KHrTL;%Q~Sh#;Y->_18i= z7aHmehO8(P?)vn(o?BCwuEA=Vk61$2yYG+4L0PUOBTAYH+PF29Mq_5$iO~cypOfq& zTmie742Cv*-~lye#3noJVfuP2gB94Tz2-;70TN?BBmVc;F)v2=M=M| z#5WTs{iLw;Y`x31-$jVCtv9iVt!4>&{5pLP>jHdU-LTxcai*VJ{<@>IboF?GU%9cg zXTLJa^vs2R;y!vz&w*HnE`tt8+Qn58+wb1ouew zvr10A0r+=%0=aNq&+>7u6pM&zY{^e^5yg2&%$bBD{I=)`X$O^p=3yFX;&+dI7FlW$A*?<+xsHc8?W`P~a=0(|C!Uz0{jZZ7u!rA1Xe$5Up zNSr5e=|qUnPDmPjl79|P4e#Qs(D##swZSCO9P>H+W6Q_^#io_5#M&Wm()f=W-ETIy zA0wVOf}HW5mGp)~_2&uC#qd0DlwZy#fCZ|gT8qJoyNTrm>HcmvYRoJAJMm)FYwGBw zB-RL&WE5R`a(-fnKMtHLul;UTqlIiSNc|g*CH3^3`Mk~@1tU-3Y@W0CU=-O3>f+-o zAXOJzAwz%$ShJGX`oppzJP#M&3(qL46UeP1y=76o)RJ~OT-IkQwku|t)g9X+c|(kJ z+Zz&@?4y*8j!};0!}hRb6=#%gkJsF)g@O%4gS#nc<+9e04%BUgAH`ilgB2CiUpJ7u zD2aZgmG^Ggk6Joo5V`rjy!>}Z2y49ulgzb9nE|wv9KWWp4N(w(A(aQbQUH`FeY!aQ zoLn;BEAsL;TA&Kt&ApR-^i+f>V^ZoaRJi2V9rzOItw zAAeFbh|%a2R=)hN}SXE zhD%7-*>Ir+VMj^0(I9IPOdeQd)(nGxx^VlJhzl4hUV{F}Z1DAk zf|E>>AWQ5Vn;&*nz>Ek&^pUH1ttK*<=;1m5Ih$#L&$zAC{e8)FD@IZ2W-m@U=IoKt zHF-E&+4&))>LKo$j?XW{okis_;`QJv($=UrXS=ceFLlX>OMOb$%=Ylx!1Am;i1)dg zZM_pWjxsq!ia76h2}{GqhTz8e_~$Ncg8wUHW~NL+=7N&Ni60(FL*2xNdrpxXa2;aD zeTQ|bEyDtk;9qDTrIqCBfXz>zN~Mx%Ibk%kB3gGhHMrn4&NewLb~qm~7jvJ>_E_e} z*pfyfbJTFP&MMP_1P99q@~{8`A&aL}Z^~5-VP_}3=wb4tfW{cESa_x&Ok=oV1KX5P z78?R#U$vdF1vn+M_jo4C2;s0-=PT+F^C+*gn$*x=IHu*&UwDfklNy1P!;nV!{9#hz z&jXQ(idATYfj+M}WKC^k#Jb5B<5kyp*%^8tQP`^u>t0~D%n29T^Jg|14djzp@I)x2 z!8~9e@=1H5HEf`MwX=GCKeG-m8R=qj3V0!1{!7%JWHI0nthC)*VlMAU6q2g?0@!QK z3*X}1V-#at>h6ZlYlP&53ze6M^PkDV4c5h+>2ySVxHEJi3#w7vA5#UCMbS|`#&-f^ z_@>`unkjNwMnaO!1X9$B@E;dI`3tkSrTE&BF3*vKL_&dIvQnSY<)0^0^l86gPgeDu zB?kK);PV8Yiz>SEV#^Zm86&R5qElKf3#fK7rOUO5Ps(P^?Q@{mh#7}g@y{C! z-ccJ#FDKD_xy`W9hu2Bz`;g;wJMu!)gwG;jaT^}R^4C#8CunG<13oFp7qO*NPnTp>ftC=?gIw_D zIW7s4DI;?xOMUQHx`E8OkT`5U$Q5CBJYue$r|A2rcxOc-b(f7Lx5?uV`BDTu;9~F( zl#gjck$FI8vcvEF1+ee(NAZ?1d3WnEA`q5MMCCKlyKeFw<-S?bvi2Rfel`6qn8W2- zl;`9)&CB8MZUv5ux$%($WaPCkh19(g0k@A}V&HMxBkU_E7(v9e@62&$!KBfQg_*D~ zD!_x8;JPg?_rP58tuIvFFD3iaRH8D|JxTO>@^ZHjtIC4W{KBcK;^ts;D$6kkEz~S& z#b@A^%8eNvYGdBeNYY6yE9^)g!suD}!P%CSg#IUJ&LNxN+>WGyrmNwOa$B=EUe66~ zgfb1ft9?M5(U(sS7Tu733wMgXxTbFORuia&2mDd_5v5l$X<*-{=R&1^`1&p(9t!Eb z6x*WIW7;d8#HUedfzTPsa&hHrTz+Bg+_p)b)| zz>3eD0jz~>{2q7MD}yUyQozri2#~UnSSs~7F6J%9z6*u{$OpY4-&aMqO-fKE)ihh_ z!sh{O!_OM@O9^K_7{byi;Ie z$wno`Q#6}IhVD#nYIk4KQ!j1jkJs{G>&@uI+Uky-VasdBbx4}!Bhmuh04beBnhJ}~ zhX>AST3J+!OlVS$n7OJ{RVEK?xA90v6wPE;VTm3(Fd@IgxU67twyu*R)a4 z-W-1(DV!GSi#rz2BT!DY5dU?&68@TN&5aa*^E8htS|=k<`<|(ur$&%=U33;Q7>#la z#S4(iCw~om4nllxi|@J-=lSj_h@|f@EsCpMWBp*YVc1)``JU#0j>sVxaOEnV;O#Fj zZSZwWk!%@r``8%o5j*!<*k7x(2~4ZCQ~q;BN)l`qK*wH)1ab2detmdMf)9w-C@wlN1ew^$PVD18A&a4%*iwIi>7k`m*J%rsUh-(}`A= zf5TCDA80T+9(YJ{zLq~QjFvaG%Ez%`f0NWqWz58vO;Pq^0dfr+5P$qpzPeypmVKW$ znZCQ?hHJZU)kglY#@O7Jb@&mPS8QGcF<8rE2(x1hX^>CyFNB5*fBkJj#D=Z0SL8$X0^?hq9wp!l0Y;vH#*j&e~&o*hq11?xvg=b|Os0>}#6Q+EgG7&U`=vjR@1X z*?nkl%m{H5Uk_lhy!Jp3P1_V%PGy3pMCxE$URW_;nM_xppwf2Ju1)&TXZD`n@>zT^ z9bc_XLG{}-wpCtoveaolL-yOfcTR`M6eX0?=BUydjr*z!mB5*EE7Q@}TuE#C+2 zlBD?4!elZU70P-PHDtCsH&H8vQ!u+V&XLflJS)j-53>lc>P=27zuwuFStwCpsItglG($4g@C+my!V z5^{fAuoP@?Vbl2D_}UXKe@w6muo85%p;~aVV2{IV3!l_nN~3gS$%4=}_;NCmfM!HQ z^rWaSFnujrheNzR=+QsC(zo^+FTu8+jQS+z$ePLM29x1dS6qQ=bj8*qlepE+la;93 zx;(}Ky(?#3GO?y55A8;r%w=T|1v0|0GTPwzb0sP#U48tDyI(OdFAm_d>*t_5wbNdw zObMxX5zzEPv1*za|6IpbY*-Fhft@l*UFR9L^hra1i+bMP(q9)}#|C*r5y|iEr3Yf6 zd602yxseO+GeoA+R&U}l;l^U+N4;Z<%7Ly!2#@uEbj(E0+sKHT#cU(?{TOe}h|1mt zi>;&2KtAsG;!Pxx*8%ke_zSx9To2CbJuI5EK8O?0vU$HT^R#I1fv2#Bc~ObLod6(|()^WPR9C(~4OoVqs2A?6IWvm*$ZPWitgXJwkk58^O zYn0IYHX=CP+Oq5@1>~jiBj+aQ2O_Rq|aaziUgf^kyO5WcJ=)UoMH+qc#q{0mw)tcDy ztmfzPMC6>!;cGf!u8N%}Z@%8#6pRMCoT7?<$rS?*tr93U7!w<-xRaBDs;8 z0o?T2DliS6<;R&Rn^6b=N%Ov^+4NI$(HglHHy!odI`pBi>W!7Tde$})mSHcB5qlX~ zJf_C9bifW<59C)Q4gL6O1zkOByOVWvR_kF08KGdLcQOOs*G_8{`>Jm()4n*j{x= zX$6pCtlTd*t{DFHgjVm(&5&M%*q>7_ruagCaKnTfer4kRRecPq+eX1E+U-zM7enu^ zoe0nJ*^WncY_b$l%4Di1I3FOTMk?O5$DKvPRbZYl7#MCJnG`Ry2q8H?j$M-=2qkd4!)1UL_i1QHKPxzeKW{;5$?wb9~D3SJIZu>zll46J;NFJ21&=FY?DPEnWjtM5RklF~%mKee2d?8wx;u|L|9pO2$C^jK<0 z7m-jKdP@Hb_ljzT(7fphoNKrxENit9;TxZ94RwE|baCO$0HO@nA1E zQ5m-uMiQcqM!sh;S+fCM=JYZg@YXn-d%rAuOps9&SZRO7U-7*KL47Goo0_Y~jog9b zL!JXC_3`_3=#qyycg-?r(r^34Jb-`wRq9z+T)d_c3iSeNA=rF?AfU<@;r-3q=Cw8n z#t~~O#yclx_Aomp(Shyxq?OR4r))@E1&Vvl_3MCl;MyV?uDQIp*)QA_*CH(;`Xub8 zBS%Ezhg^p@tg=s1qf7=hLD5C2!QO%Xo;f340tu8u-_}{dR2YVRlnxxzE}Tu0Iw~Z;xKRx1$c#o0$cVPIi&)auJp1S;>mqX=nZ~(=8BmSO;}JW1Be%Hy@|$)G zyuh+ip$YL$z3*m8wIoIB$^Li&4C89IwB6Z_!j?tfc5EnAV@!E|ZT`*N<%m1KY+A-7 zOCxM3Ubm<OEi-gZxPBl5~|dBIYfDCePox5C}{P$xys5MPl9#hklwO|z)> z8Y=^RyhXEMQB0Ba9z3TUf4J}8=xSdzTp+z#EZjx)DJ;ff0Pc!cIc1X5LjZ0({p_Tj0@8*N)N0*~tB)FGviCR`1 z)8-I95Y1a{LbdH__P@O!gQI!2Bs?!dtvfZcJ9aVCrjak^Pa|h32P-IOks$c(9 zhHtiiQR~TD+!9WP0VZ$GL^L5bWDeDP!!QA^K+<7D1t-w!W>n}$?|9>`V3!hOaq6?L zAJB3PmE@%P-J&_D+3`*iTDoF12nr9Z-jKbyzc*(DbYi&F3+11i(hfED)p_ThXiqET ze>PTk!Yb;C`ms@YM_hl(+d`?0ekm7bZA7qeS;B}Ly{XPL_MUv#!h@vDMqG7LA%^H@ zZS$qWcd08bZSo-E>vJ{v7ANEjyJOJdX1S6uw;)|I{Nna-lC6UXv@{-66@`%%B^64M zvxj%KN@Bz)R+QgL-^xUADrEH7%4TyGXJVb~j20-t;EmGa(@ShNUcwDuBN#iTg>5MM zb%?-RMQo~1fPw4X5oT|lP=AtGg!x8DsgAZ2sMmP@t#0^Hh&!rzUOH=}A{s_Vp`IU) zhDK^v%R&^H9CO&br6u#`&KJc-Hv`fUR98h|>CyA7d@NfnsI{1Z{VjpEn0{l+LgMT$ z$#+MI3GQXYhnr@+iFdr%o;xF|kE+8%mD*Saeuthwa|0;7SN114mG3OS{Fcas^BGSz z^sUQ#l)d!- zV}BfJI}$<@YHNQhgi=Sj5P+En&6XgFhHZCJ5DvRk!lw8ZQa>lTZ*DMCttpx7boDo)@Y{u%v+;(5u zc1Oc+#%G0lV8s<2Q_M?zpJPHh^q=eU0?`+)Q`YHjneKO;fj2FPS-qkf@2w0{dkIcB*-bGb@VIyj{a4by*?TRe;uVo`^U{>AYn0pn_$htKEUGv;6oVW+18mmj{ zLDy4gQgl_8SV#{kW#Knw!)~}e4(;dtwK#dUk#C2s4@D>){OY&xf-Bp5QF|@9pYm21 z+drAAwdUVo5nZ)#vCV0;a89cO{PEIwFo7m6Z(o`zvsAwl^h`7WcXUtGZZva3jj(dd z2jxOP7vO{2STiD@rOGFAe^Pz%z*uwQ=;)))S&3|9)go+8k_39tPGgIc#u!?>ZRA8R znVM&f-LcR;Pku}tV)p%k$i1GYD3Hs~r8AJvjp`FF;mXP{CR{OM=xg}WI6Fz0S=!Tm z9(0o31x?p>BcN89hR6DJQv$7ex+nNoNNOHf9=l!MW7#*<#M`0Z7gst=a;56$Zm*T~&4XtxZG zqaxF~EzDC`1u}d!_9=}O4V}H9?~|0S{gel}#KF)sHP(c8DD(-VLWzu&0;v?94wXF* zL!n{XCM8o}OgYX;Uq+Os1@XO7ST4OTby}WR{>yzZ_>!(5*;Waj3$w|wG^)$gflht% zG4kD)DB7?mqLk7t;cYBqMGPxm?r@B*ppyM$14?Bw{cel;#TL~4s5q`4_&ask9~)(5 zb$2`9^N3%WvYZBQ2_=vjwKr-do&$M{Vu*M?WGH*TT`&t6fvh$^9Ch}-pa0VR8RMH( z&kgoSk3s!3MRX&3A?vCvW~7j; zM~y5i|+ys3RHk zOm&h>QFZ_Xq~3B3v{NK)U76?WBAT+->2BF_PbSdJgzjNJI-knE+zUN{V;uf7INYPb2 z>WK=NlgtiA8fpBzTXs3A>W*1JQt5Cu*!spY>!5yLkBbN@-1m{^CZ$387+rNWjKtIE~KM*Z4LAxy0SS0UH(~TFFZx(Oc;pM z{@cxjvbCS`@{^)ukg5GC^`scSL-NXvXRoY^0qlj7u-uG*kpjYy{K1os-rWmu# z!7U6Nk>d2Rsg94j3x8P)3cMF=;~JN{{oML?BFwgLKAhW^ur1r-bG+Ot$7xjbY&ieH z2-@aS+DqhpW3R$I#z5vv%_&AlPX)i-d<|+lWBy+$ zkwcvre60pAJi8Xqp3EC@Mm2P47wG_U5+Tw&1MqL*ne?&@t_qKT?DIeC{I)ra4In<% zmwuxBL{55+Owj^-(|aGB4arI_Hs*oc1kq#Yli-XNqL*+~iV;MQr-XB&;UkQU$_CG(xb3ugXy%s8sxz&5}hEJ7iDi_2UUtEoG6BhhS zl2kMCah8V+i_R;n5?s6aSkE3$Ez~8Euqcc49SVT~H=8pCF zM0P>E+j=JTl=1a-c(HUTaeVKw(VJ4oTLP4C>Bi{*5x5i$QBC*z2@x51x(Ppt^rNEu zXFx)~g#l7qhzr>)xnZyB$@v|A9_r7esJ#RoA%74;T3B_Lvx-uU(w~&2nyD3fiKE%h zbLHLtZIR@;{P02=t3<7I5G+>(aI){*FviUj!bA!LBByO{1??wLYAehGO*~manm^l0 zzAf62k@j0)Rf&ykUq405XdI_2RYBsST(;tN`6pNoYScX584=bi>R68FHCEj(_Jqk; zS>2GZ6yNM+XPi7r$OdWMGRXVkmS78m+Hs&Z@#(cFK2XV;qcEjDSOBm6Mf?XtV}4R6 zrD;JW(gGj!p2Fm}#yDgIevo<_qxw6(VPQkmc^~@8D>~kOg1E@s2@YXAKKa{7f-p-* z%LSafpos25y6){T=RRoMvH^ug04 z32Crr#94$eD5cxb*gwltWpuQly6`RMp)nV|{gJaHsbX)vg|PpaZB9VOx%LG`QD5{8 zezY?GP3TIzplo4K0@ezL^XQj<5k6g#ybLu-Ie0MVXDLll+kc|p!K9fPec!j#`1XC? zpyIxQLB1?sOaQX~H%nj4Du6pO6SgU~7FWj(#eQTtwa32l_2lb?DMKnvLTda~>*f?1 z9$mF!a8C<%A=HFLLGHS<)k^ajiKGKfuSMYcg1+un?2b^g@7cR|F9~r-Hw5*~tBX9L z4(OeFBc6>tp>;u2lTI~JMr|X~2HTI{@24n)C^rJbIHEv z8*(V0ET7%#``NT#hpu{m{VpX{KZ0#e>X0F%>FbFc~HKeP+{5M10HY_M5%oO zia3=;nVSpMx2_h&-HPX>bX{$G$A-*7FjwLp0QR|2%|7V|&nG~&7u00v=t#;Q{a79T zMR3g`L>s%JSCp&Eo^*Z$8%`sM4Kf-Wc>U-Ohub=|AEFqZycRm`tMM1&wCdxIU5>_$Myu0$5>m-UB^%Tb`__2D&p=hEit{{$1C8mOQs468% zA2w@8PPkMbOd!T8RTC~ViAQu{spyIBxK3JR;A5}Yywi?KyF)W6>DeH_m*~>}J!6Z? z62;WQ(bW3mU4P}tR=hn9D|UTc1gbK*6C>z--5@a+BuMknMfd8m2ub);Ay%%go_P6c zR4$HDB8GqcNeM@pizbah-Vo~pDGSLnawmtfx~n@DTXpzO-*}Ei4d+wLyJprHjYaQ@ zT~%RC?ck9c_Ep|$ra~(iD6D@dbnpYwy?WZ%oP{Q`3)Hj+4EL$L*M*4VIp&3*5<`9C zqMbk6b8_EIpQAv~iY-s3BmB#I5xg_v!#s>X4?GV!XvV*%EOqSOV;`)-xS-u59Rb{F z_j`G#JQE2Y6j5rbUpD{dKI3u!KHcPO{}|)UYdwN7lH!<`rZ8W4lg}grXDPbpt*R^R za4Ge-KbWP%vp*{!tW1B$)T-My5&8WGgRK*rD=Tk_aPL2MPdAUKmQxuvJ$x6oO<W- zh>|KV#YQ~hL1f;aN?gX18v}r@vXH)K`X~Qzm`m%Xz{(!W7NFNhD;;slCVg)qH~7&>5Emv9%uFcF1ffJBNjJaFf|+ewf*F8xsDTaQZJ{Q)uNN6 zvsd*SP{dXGfYd_e4NY)dUba7BL8~r6!ZZIN;s1Jr_~tDlfWrTwHxd3L;Q_NcZeKqp z7H|R}{NI2rozMRV!c)EAbpXIArJ_c{DKo|kK}yjhq4rHda0&xNc;-8R(0)n(KOj?L zkk*G`juL1m`G1GMD4G<3QXS0FTE= ze+>l)V?D_rto$OB8;J@4R#aL}DPiUSNU)PJNenF8@JG~h!jmsMCSo`WlxnrhKL*eW zfMm-@snQ?Fp7hiTnU?ORCZ!M4GMq#A23~0qU28@{)>S6|8ej#q?Df`iLKIXGxFzo*-L*@&Z*TD zru3>jmMP2w`OHiFo^XR8i4_qXCNFbi3gDSv9`OJg3>32n@am6WULuLiB1uUZGyPd! zlorIy{)iA5G`y&gbu}Jco~1E&v9ZJ6$pD!a1}ZL&>+}FNp>Y$WH@ZZP67+}629opN z=>>sbcS-1DC~{9nw3bF~@$vJIuX$TRra&nvYP?V>nm{a0M!0}AF|sQ7kC@_y5Mt#; zD2YN-f`kfWpDAPzvv>#63<)Xi27Urf=z2#Nl3d7A*ps%iJd~s+NsW%BHmAEH8DjEw z^fBM;PX>Ue41zv~GblXj{=SsuLcvn-ltu0MXbzZL$K!|u()=3r_7Pz5UxXeP|Br)y z;q5K^Q)Oq5;<4tcsW;@mnfw84_0izPv*aXy(Uh=&8%T~K=zk${4n?4fn1VZhn_Qdy z!S5O5KNUoo6#Q4|_Xv`g=b`C^|63U^RKZ_?>%Ch4E7$n{Gs{7Lit1A#2D(N{Wug2F z0^h4B#}~p=R8Z4#AwUqH09?4d+9JZA1|D)1cFpnDQ9Suy1pKFKydbpS1xmjqajQ@L zCA|R9_?3}tN(~NJJiWjz{3A^P0v7+FTJ$2)|EF;RDOZ97{{XH&0zC}i{bOmMK&ihX z3j%%aMF_Y*xJ?k<1gIAD-U3C-@g%JLfBwQf{Zo&)1t@=d3L?T^AyEhjjD>h6DygqT ze}C^_IlmhEm?$0@r3zlgPA>EW0)Jur6E7fPVUT`Aq!LapmoSQ6`WInzZddM(3o&si z)Zf(M84DfdarYO;0{wR&SY%q$UiJMINOD2&4~e<_m0lbga#zzIm8W0qIS0{B4sQlx zSn6d$zSyjJS`@y&8Szw&m4>X-OK|GM>Y5#1u<>~+9Y1aUIVOL4Ju*66NK71sImDOkX+R$ zN!+s%jj2e-pv@KX-AQ4*b_+gQhNyh1y#hoOHziE|A43%$^Q{Q< ztx`9gHXAxqbQLE!+GPlIfJ66j?U9Cx7)a`W=?!N9gdGy{gkth)(to|8M{_uW4dS0-Q zfdU5pM_B+`Qh$6ZK9<}PDiAgh8=&X_wVn_@OTFn2;@6iUP}c_zy^TlUzR)6aPGBfh zdi;n7NH#ctApiW(EdDRd|4zUV``^U%r_V|Zy}bm~CZ0e5fPU)vzxa?Pg8)5*@E=_Y z3NR=APr>}ZkB8(DT3jLizrTP#|4+AbCW-sZ`6d+iU9VGW}j-`3-;u%f#f@Gw8!~BP{l<4MOa2a@aCihx-)|;o{&Z3*i7Kd@e4JWU2~Eo zEloiXYU`)+U&?{7fd0a1+OMvzju>13sChJS%m0ikcxX<$em3EpFs+X3spA9ie4(Mc z@dV%EJ$EQdbHmLu@=W#Rk6yDlWC0VaryTx0sI#Cj15N5$a|1|9Zj(SK>BmnXls|(7 z70P2DLb$ZFNu^?RbhJh)zNgB3KA-P}_*UfhsQ|3bxNb^)3%)c^iyqre-0JAM2=m+R z2aj*|N(;DZ7aGq5qq3CiD=p9~XVL(jilV3OPnhDVty>K$h8hDPLRRhGo`jM$R0lhI zq7 z%^j;N^!1_rBYOeQrfKjzv%LqRQ`MGU^!T*RF2kE=&u~_P=ooz3OeYBtx02G~+7^02 zhEr1~c6sR~Wj$D{VprEXTzpz}nb@hH^=jnY;eJtwdecT*o-98rY0#w4t1ahG^= zEPgA{Irey97GXOO>M;9xw$v_lrpYpBA=YPt1IxB})H|?IHZ0{+VHR;G=u4UI7hCdy{b&>^GXI>Zp&0|Ul zppe7<9vfR2&8TK~*P0Fm<>9G@X_N|yf8YgibWIRir>@M!&Z8`W%{}v zOa!(WVXIvGW$bE12ev=r=zE&PH*D(U9W`EzgZ@sSW%@E3>wq>$)Z|^8uE^!2vo+0k zPdE91$=CBfjeo%oCnH!XD_ZpGoTdALhQsO?$vys;HZF`B5^j>Tl$MN_F(K*6_*o8n0|k^IQRFKD7|fN{P`+#@ijr0AHG;sHxiGh`i_JFcZH-JB<1?9P`TgHoQ!tP&UR z+a>eYY4xx9rE^` zi5^T|pM-ZK%?E?ttN-ofj0SfLsXDkJkolQ#>P@157g5|s;_#*`|J$9p&ILYv(}#l_)2~v*micAb9B$%jxT=t;)P|hO!<vOTEhIa6iyIq4jz?^nYvZ+t~24a5>=ICdD1HNYkBci}+Sfs+sbVS6yz! z@IruzFL1}|9=;*$Hs~8%d*Xw{0+;=}6*e{3%p?@l_>5XJu4ZtP@YbTd=*=76)um6du=O$g$$6 zKo%$=%vrIxaCn+ofP|s^6<>ik8T%l+XFP2y>FI+e{_oew5#Zogca-c)zGv@|96LIQ z{TBg~(CU**VA=saZD}5)U#LL&#s@Dt-|TMIS}MuRZYt<0i@IBzK%bCm!6BHk1X{uY zZ0Kkc0sokbBg^{%!HANqR83uQ)udUU&4QGmZ{5S+*s?&seTj=A*WBA(JI52Xl4Gm|1*DLiS1LzOKqqpyG}eJK@D86n_=;)9 z43%kaVVSLMkY|w_)uqj(0n`b1dx1t*IVLv={(|QJ{_+&FLp>;|P8DLZFFC z8bP};xLQsJ+F7IkRMbe9gQ8#5d$1;w(Jsgr2KR=GsPGzju2sc0D{AJtByLthI+JGK zky;WzH5_)j(w`1s?<)6(e7)dS%rRMg#`Sd=%F_*vi;J})R;Z3S?og*}fNAt#r9C_q zV&b{ECrF)4@a&e&*2=soD+Wzea2R8wYRISLgL^~sH0NpIQbom!f9@re|{ zF5#yzQ~9ViVHAQv`qyTCJF&TQrpC)wY(^EVGSHukig{?5goUMNgGQ)G%=C#O+)?G? zdh>HAGowe3tjt1CygGu7GW$Ku4DZFTY8$oUn2hd)Xs6WyBiMZ~{1qE~Z`t<4!T2kb zKiS}L@W8<8b=PGzzqV)QHB((%OcW~@_jjKSe(`)9_3>Mo=Gg<&Ij?WC2NqIZ{L7r9 z&I&Z_ZtMeG<7-|nW3k&3pvNr+y^i=fL;oqx! zIq-7%A)F69x=Y7*Qgt3i>%G*}2M-?ody_$evO4n?cEu5C!b_0IP|1)K7HaJP*&PVqprNNqz1$!#PJ2??8=B^`|AfufA9K0g#+kHmumaR}xWR6xD% zkEaT!jc-4`5RRDOSQRHenx&A_xiMnC&3!5`HAok43nq)6w@dvFBB2xCLn5$>A@5Bj zrSTN|KJ?yV=``N3cWzywWzW!Ywxh!0@`I)NC%mQp#hwx43+#)-_}hP0#(~{Y{@=lu z6uq-%8l>sGU4iH-S6n!2T`h2CF;o(UTnSmGNz?DTp{o4c_F`hfj`*#;NC>xVD<{ES zK0eq;QugCE{R*h?tA`1Kvop>84j5!6Jj*ct*B$os8vKZzegP{XC64?WW^-VXmKD_a z0-l!SVIq$tOg23JkXts3v~nu}yoo=To>?#y9IwcjY-TJXkK+P2nQ^bQ_&(MiFo+<- z?{PbkORG|MXnP@~h0x`^ECvu-T#v-tjtHn#&Fcy^gLz5DeWran1I4Q!Ekr<>4-j*# zLFjIRzBL8)zdmJ!gfUv81=PK1}ckmhpfT!f4tUJ@^Sv{=oEtt5ID}FP(1r2q1+uQLC(e0UhdlanN5??#6 ztLhLHJPdj3^>(jzMlbfGi;w7tIgUMb$Niv|g{M;kRg=5gJ%z#8qh$`hAiiQQ*T`ap zkdv(olK8c~vW3utl)y+it5C0nU@U;z9TxIU#yK>y5Z2pgH}RG1xJYND#%0XU;H^nF z&J$vqe;`N}W(d%7urcXpPRo7R;xNl71Tpl|hn5$Wv>m>HZ3n0G$TRI-|4vsKaN!dZ zA8M9i)crWnthi+g_^OBTuXEcS-Ld9=k9SG1nD3?b)Cqj>xt8HHFE0dkY@x5*D?U4+ zh8;yCiHWD#j!p`X$P>P-^}b?aHDQ>TD&aZ|UA82d`?8jT$Lao&{m^v}VKdcL-=RPuwmtJ!V-i*$&by<(X ztg1FJQzj*MQGR;d6A;BUca_~RW6Q{d4IP-fk+`MBDAX!@kn&U9i^5c5;Ljz8xIz=G z-WlqHcs~VL2iFgpO}S2TM8XIEnBvI)OuD2HFLy25N#_6$8XxctgU)_j@NE;Y2B zOiD@CwpkY03j2I48f4`^Pu)XFa5~G2w9*fFoEWnvqdr$zg zU`V3mcxV;^!F?5{hVvGcmj$ylad!^B_GDG`$a*y_0IMe%`m#iUHkK0iyR>`QFe2Z! z8Y~!bDcpE_BJ*l=#o@MS^m*zwQ1`$JB|_;e z$XYPD(2q(-m@q%}czkn1%c;hi@=#mN!^eOp?(}zY?SjMyuY5I3B(=dCa}`xxg{(ia zT_O&BDTH!cXSW(5p5)qE`xp7COFG)L)%|5{Z473qPA=5+5&tYF(6aqf!OoZs9xkoa zuFh#1n7G}hGNNxZu@u#5WVr8l;#c8FO6IMlR+DTut#r#V9arHweq=0E$jYSFxKM2_ zz3T_*iz~F_^-3!D`_R&)E$mt-abV@hwPV4q8T)+WbrG zRtf*asGm&h`VAgPjaBRwv8QzxFsGy~TVAXnh6ro3N->aIdmu{OM@;rlPL+WNC!Y3)e?4U<> zuS~srK&`NF*9~>Xzp_y4nT-*oSW-o45;OIo4aylU_%%B}0E1Q~#_`b;@Kb5>=?CRb zNLTN=9fFj9|0VZDEA&vcqrPq!uj5wIb@$4l!@`FZB3dL>@ta=lP$S>1P?NoRM!jC> z3*4pEEjl~z%33adg!{BA)2m}kH15ek7Z>WLL?Ngax?G<8>qIM%$XWOKU^tfj{-Oi< z+;+RkEWGa|-NlANbrB?YN=VW-FL*}+1yu{K`C0U3HSO$vK)m8|3x00}O-^n!@c7g$ zfInVkvguvf3pg6WdoW($7f!cLk5n;=gZFr|*EqG~#r#Z)FWKi~@PbBoUbYr7!5ZeF z?oA|{Y=Kdi%<|dN-DwErpNTbh%)ExnHnU!bwJjNcPoit8EdC~g%7N5U7(&BHcs=e( z%Jv1WTDVrh0OjTWY6$-gQM5G#H;w%Y9e*_$?`h9wtf`=){}Jh4*n|v1~8h zC{W7=vV8H(Qw-hcE-9r8f2Xp}%iLNc8zX4UKK`Dz?hY2Yt$o-1oVjfkzru`ppS7_6 zmCBHPWN2#+yA|V!Ji^T<|ZJ1~HSb9Urd%KW2A0~C=8cDVnodw(~3Y1g& zfjQ;ig0wROyTokA<=}1+w5cv4Rd1@xj;>m%;H8qZNMf55=C|CNa+9!_wB&_V4Lvn) zja9gCixNI6hUm`#bKBhwwTUZ_@FeP|lw-H4;#)hsI6sq|1ILM?N{0C1tCh@D#sPWv z!0yNKGE|1Dpb`D!7E3sDVwE`FjX0TYqFjMygM8B#4sB~}ypxJe{#W<&GI%29_+h@Z z=Sd*pDtP#p2`J;?!1z~_V>xT8R&84=g-!jB>jM5ojM;B~)cw4o?4+>CaS0qBxEaBZ zc^|dcAK-1{JnSnrkvC&aYUu99>|%nGBTbnZ`{;heBxit2q@sp5X3Ei;r0z^`x}t0n z0pP_fbwixiCa5mo(i{6AJV|r@@Qz}lCm)G^eG=nkM>0)5H=>638O}~$Gy(NasgmMN zNDlxDs2A@A!@BCP{PNy8)S~1=zi>wZW~i(d5+@y105cNaDnTO=^-n&$%*zZ(S+wg) zF?|Ga|t$2T{-5w?w9scacrS_e`iWsC`Gw*ej&*Ev3HgN;f zu;`HGD%(6x^HnpTczPAf`L*ps+e@i|INxdi`fSx!?Ngd&$TKO zV>@lqm@mgs%;TePK+=>b`@N;ekm!srsO^EmC=a}v<4;clIC2TbHsI2vtHFBu5OY9# zBAVYb8ajOZ)LTfSU>eU4ye>9PkM)Pxj_Qa4*f`whLKN@VNJp7ScLnAAo0^ zr%Zk7{lfc|GBTlrGk)tD>v@a*oK7@Er~gxl57 z;mU2B_3TT2!t_J$a%c80oVgW~TPyhGYeXG#M_ae^2ARpb(^zK0Bw0!sFV8lm?H4L4 zH-p7rD2Bb5;;4C#3?*)|V*3M6Xv+0v>dw!FL|b_)0}06T5JX?mpDq`?(N%7DKBOi@ z{yD>PO+uL*=F(2r_3F2)|^hjvaXZzE$ODxP{1&Lk{_u9=;W^9=G;64DY7&| z(8-OpiAFczRb@h4a`E_pBcVb-1UiGskXdWJOhH<`J<#uU+P5U0`|Z6;yM|@?Zq-gF zXr!g^6_H=>pv=R`1zIp@1RjNp=OO269a?K!??7GG^Cs6&sW?7D;S^{@POLbW2X;8~ zv6pGAI%g7_j(8b+BsSxNGfI4tZ1sR=GwoXWn&Cznra`6AbR-lNGq=RS9(3g=7`37{ zy|aDdPtaZ8$q!#`(S=Da*x!q+WLB(Ck98fvo1^hRXdBDQ_t4$H^LM4&bk2pBpU9@eqW*l z%>1_B(S^#J5>UUf(yJjRG!M^9mzKC8my*>NJmLl4-sCjeHUnwJeEN)K9QBqfI|>Qf zlJZL8g~F#O;^kh%RJDgB96^1>6?#^JUPee0HX4>6ZyE63k(9=9#Y1gIQHWn3bf`ax zDfXQ$T#=n+qpg1jb%ntu5$+Y``|WG900{l!83kNLJnST@|3J(-zGmE-Pg5kBX?=Wb z!9Lf6*=U_r#2a!o-jtgl6!=Nzmu-T)D5h3Rb3pT^_k!r=f#Xz;Y<~+TFUQ457iGf& zuD6cv;Dl`dzX zK$L>H9yv;mvE9E21%I*JKH!pY8A_1(id7zMA_puJMvC}zCa~xQ=V~}(>aQGh>XaOy`Koqhy+&DVW?S7HU$vs9gwj=RiCkOuszNr= z@O=cu5igttvXVdy@7fx7v7N1jG}qxGJmra6ezPIwqR7cgeNnJB+wrdcmod7?_VkGh zacRr+miC>4>k9!TXL%Fhb`RL~1D-GDe1NB^KeO7ZGu}Dd>LOqis-7uZhSZ@)fr-V? zq-`DKV_;Y8`q9_<$%y)Ih8{)dBc-(TuiCC={A z?Rj_6_HuL>a&gsvEPE-a(o1>G(x+4D9#^yakIZaF*lm;JeBRJk_(_q`XrZ%k@N4(= z{W}`rqyXG5{`C5&ezAfh8Qve2_{2KaxCidpwfz!|PPs54bWLu46z#@axs7q0iW>&k z?NJ$TZY@>y&U=T9v3ftP{;eklb zk-R+z%(-Q7b!l2HQx+oY9XB)8%uLw^Vuj~+b{_RybYMn?-hAOE58iLg%gm6s1fY<) zeTQ?EsXOI8$-@)j74iJF0aY}zwvlWdZ%WtX0RxWq=D4Qh1j`AxU~iotD@ypjaP{g5 z!{9wSk@04|Nh|y3wi|)-`L6WHNK>OU^{saDQk9rF?A1xEb>YKHmhk6H1kH56uB03u zJL-+5SEMlsjweaa+#C+rr;CJMq&GRly8%S&H(qkLb7=!xJ``TsgRNPtDJ%mQ%xi8< z`}e$Gs%d*u+_RfIfkP8I zKD?{S*{4u#=H3W#c^;n@6ZfC=48*|)I93}2zvVAp-(5r{M2~)@nSM@AuB*W0KvWFh zJ7m!P(p9|D_}+MCLGxdPjPNGIbh3cC4DFs>*U3V;&?KgAGSa~XZ9)uHnJj^UY&TxI z?aH8Vwd%CkUwu95;)Jf%&tBn<;8@DbH&PR>1Z)*idyP2koHYlyeTEps4QCv;= z<#>9t^?wmo#d_pAjAPC^{Ur=T4@2!n4R*oyI)SlPTVyxSoOhITDjqUP)(4VTvOk}Z z-FySkIjbtvn8@Tpmy%L-n%MN2oP2=`(q+ zBfc_~CReTkG0Dky`v%5Lo9sy~RBv%YkqL+v#3AJaGX)%{1J71*@cIk09A^(N{I z!`jB?yUG4 zDdh8}lwK{nQn}M@{FJuo7eLRW-C5PAm% zI5&MB{*xxRX5CXl-|wi9ce@$r*z`^Dv(~5?jwBSXMDW6{$c6d`vS9hUTM7~{6)S%( zv)WCr_1pu8j}^pnPakfl80&&==`7gx;*l#P%_l@j~r*=hEg z=~etLrGrM&S0d2>6zr)h+`=X z{;B=oZW@dr@MeS%-BZUU8iY&rQ$cIvLS&LhZoh-bZ~RDYEwNy$HD4$U-OxxPyTvpV zprFuW5ZtPG9t7b2dXf+0>wYwcX$IPpRw{O-%xqnC`?*8atrd&{%(<4rO8d>O1oq>@T7O^Xm>G6JWn?Vu0ao2Pm2)7Mgq zRIUM0t|I-m2R9p!A4v}p^bpWL=ex%^8n|pam1bHmx)`A!G<1mh9MeR{?F+xYE0(ik zbs{UU(5+axl5G6x5&IyQb(I4ndXK^?eQsnb(>4!2IO?r$tV^P6WhQZK!3@hI2(hqQ zm0@hNG|H{Hd%p#8Lpm5Hm>;;O7+MPvmp_cs8uS&HJF7N)K`Qij7|nx?GPwKi3NpAY z22}L~#kBpT`rgk5b$M?AemyCI$Xn4D{V24|f*fMI)))NfEU726_9iWmT*xH2{}>Lx z61UBT!UpX{HMl3VCKnDSOAhEaqG^mU9ij^9rrfM`2Zff!r|BAa0EBLj0 zAj7jXo3!u)Rt=1}Y`BLhPL1*JV*=NqbeJC;`hM^Poo0vc9HxsuyDv zR6svY^-RBIko`RoGM5szoTd)p=H)hDTAhs;cVWsNH96^k(pjq2I}CEIQ;)mUD08(; zc{4mCSMO$uWaymP$=zRl%+~7(Ss={_q|%7%8A)=-7L2tMdkN11rR00Co*jk=N5pFH zuDK2yO4l{l=p?`#QVz2VWF(juW~&RCkFZO{h~LW}3kN{$UG2NLlxwQQV!P|I!>Ka~ zLT((GRB6);D#x~(G9vwuz0gu!IAkmwg_>2}H)EtCKY~kvYWU?xzCZ^9IVMW-Gu_vJFLg!Nb1_E-|;2ZSZUPd+DSL=)%xb+ zbQXd0rN?OECZ5N^h-Y?*s3>B}w%q}>*0BjnEes%tlpCzkvS#S$O*gvo>DT9JJ0mvI z?5J(eWoyWwr5m6S>Rt$TC%?!?ck^=_6L%#JD@${A=C}6ORCl(jr(ju=zC^54r$EAE z7AwOsSlW>7w(0LFB%rU2#iKCeRS87PlLac>Lb^-!;ab+3b$S1OEgcmP zY%;lb%fpfeb3A=uEK+nfJ~~Mt9AXGCY7>eouj+!vMYxH+4vYxI4=UG8Q)^2WpLZ{M z`Yuh-&^jhfy8M+Z!AyKqvnLV#5y1r}E#V;}+dA0C5oUo>(abvD~Ev2ZgOW7al zm3D#W106K!W~<+q4bX)3o^kc?#J~jG%wKk`FLmN53!Kv&R5&zu69k3O1JOC$NAt%6 zD8Zmu1hn93_oS zveV4msbFG(@Sne1!C_%WT74w!8Z&W=(y~GSO>tq|++8<|w9j z8HpA>sQqvTp1}FV&9EBvKfYk`4D>R4i;c5v;MH3 z3JXg7wM#pyG~bQe08U!=-(Y<>Tj)#cXKm~K{_taXWtA7w))@5gU6!5oz$}N=qjTR{ zR~Cj7;HjPF#MmS{R)pu768OLzKoL=%al#YmjhCq^HO+rP8u-B`Y2bF%g3?`l}%SBEaTKN<39G&)xeb4IT!1ZCr1`+k% zjSYdT*)Ne!kGp7Z_5+Bn`qByImy2RTuSHVQX8V@t;nqZacND*-*T8-GZXZ;+IrR;u zn4V%Y2^2ucWqx6Kc(xhqY;wu8JPT4IcSnwOGn{%ZoF8egz@I9xcD$ZYE7PVWT>1t* zOq!Q~3(IgiSxA58|$?1oE4oJ+ZD)n7rkbh54==BYNf- zy4@pJp)Huco<5@r^tFuI5!J-gl)^>D2b>D`rJqnN4|W|OOgeWG^_*2mdTnr@4(9nO?<<*^5}75j&=@LML(okG<`dq_n)Pb0tSv zyUwF^MGe{g>p!=^sl^wAk2p7>ZWc-nu|?&re$J^XfhTr9EH(ABvMFf3ddq`UYs5du zOoKq2dxLQd9+uzsOa1fcL8fY;o43nK3EwqN3;_I#+}S^P|Rf$1X^%k2j` zF$;z25=Y^om$Lqs=H7|Zv6~s2FPmbMEFl)al0;okEd6;Ku?sitbswu;Wm(*XRz41W zCK+a2sW?)HW9oFlxdyJ5+pPGs_$se7uApx1I<6>@WE_~m!fsKQlNeVBCpF`1Xqv=% zZl_3^MVFDbvyi@ZuwtAKz~bsbYV3#%Nn~7E_2}M4-o#!zQKlgu2%Xco0J!dU>`3dh z-LFLcxG6pws%$bbmVSOamcz_k+~d>OCAlpD)KK38Q1n- zjRJ%+PfgrxWyI0`xr}uxJ)H3v;n~6ZW8w?F^$B{5{lRkOP6Wwts*JBqMG^<~IUz%= zg^ju8I(##16R$En%4#_wmPz4CYEOvE6$;$JNW5vkH>2E|c$JvagOP-#4y~+?9Q7z< z3GJLkle}Cn{zV|gVrWRe_#4H?@Jh8P$&S_I{f4d;(*=JCQB2%@0O%dtg~-D_+BbI6 zG@oy#3T+Ky>8%XctAUN~Mz%ih0#yh_Ge7gLif@9^ie)c+WfaR75yB0;Kc(Q z>CZQG(o3#+T~VY;Xk!~H9_VU_p?k@p(;a+0Ka-@7r7bx91HaQh#auwxy3up*yOJz| zjvF|olTI>q8CA(TEpElf6oPUo?%yCCK9iSa*mIR7DmHGkJ1< z+jPs7_ZsUgPtyoIv-fNC344zhvT;ws;PtiN);a2*2Y(Kmv9yTMs#qdJ7{l39Tz%JY zl+f4Kuh>a;$F$QoBzs%j>jYD0GZJD*?}hibdPMNP@nJzc&`o8@jbGR^WQt zu9DigHFQ|O8m~E%VihTpK&CGcsA;|99;h6?34wAJQ1^A!Y{Zau6j0ZXCx)$q@F!K+o-BrOnY_Yv2gttl<9W0l!) zv0$9$mq64#sL@97YKzWX+4Ds-CR35G{ngV6B#asu zfn(%&;p|lLw;n_yE&GURaUa0OLq0|C zQD+Y#;zhD;V@hbpt$5X^Q#^+Cu{DrcByeOC`XW)i(Tl=w#C&lf!@Pw_A3>XOn*>#T+e#hxjw{HwBrwuPe(Ol5VWu z}J{`vM$#TQTGI4{T4BCUL7?1`TXmr+e=7 zDrS2-^NiRdhiy3-oCT9&EgvR^=WX}wwkEkYMzMeH<78Y8B&U|Jj2cwjRr{G~Z+Q$J zS2g|xZMc1*`x3rzNW3(0!NUIMz|c0KlKeDcQ&Ndd{^V9T`xm_hnRGK>)TYElvx)Nj ziHzAtE)Qr-&*LZl0<7ZvPsrIi9vc1g4vR08nTL4Mj!@Xi%iM7nTrpMAjQASV{{YdR zZE%LCn-K{+5(#z`Y1C|=VJ`S$%VR=wLMF4&u;`Y^il-bIGUH^q*f(Wkz>tf`sqihV z4!9?=jGA-Mt-C&muFcnBWG0E(rd7t96AoV_1ZK8ZJO2Piu)z&Ycq#3N+)o9MVs=EMrr$&BArt&+J)9x+D!3oNI zF{*rfKORP~zawsZa>}{@CxBOzT%P%+eh?dsh?oP*P{H5>r$4XReypm1+4IP zts(s*QWzJDMTW+YDkQrKB7K-!`v$=qjNWnK40T@B{{XOXoCYf5$*l=2`W5M z8Q>aNgjpV7pClF&dSaLnk)*4y>?P!W;M`)A?*KX$O;H`>47F2@@~Dik-o7xFg9kjPPNILc75wf;bwSIL<~BHip>M z&|YImhT1D$M4tjaMCf$BOy}p5%umzk8*!CI5sE_Xi+g?qc4grNcF0lAK{sQ}P_Zaf>E>pU;Y3zxW zC!{;3uG}5Ky^_yEnkH81wuuVmi;WVOv>#i`tjljFeLXOt8-FB8ji@<< z=b;f~Xco26r1qfGfmABwZEQHqysKK0C2D0;(BsRF7T)Au>zIgqCwu{=>#je&j0};UmvJ3lS);65vZI z0;Djfl$b7PuPm(TIf_*F_^2&JBeI#h&}@_$EZ=9#I(9{{V5LjrQm_ky`Rg zSVkQ$C!>RpBi7c+kAJ~Ra8O$YZ4(01TN>!H9`r@n=YkrvdSm3FJ!FVhCNE@cJS3hxcOv_coCCJN@I7DR%=p^F%<23l}(ay9#?66zn^@J>5&8E{{mP=9L@v(~u za=+R-NV z{{VFvObQa#@BJ@Flc@SwcqwclkDyf0o&3PB<$Gb zFnz}MUi1;TDwJ7oJqdaybR;BH;DcEgk@t%o;7I76uaQg9ktSek=dk|(ydr-=ZIf7& z*{wg3r!hYRYQ=q>33w17xhRB+J1CZWk9-TPvFMV-X|f`Skdbh2X^*m5TAk{B%t#NI z6Mx{_g5gDdi!XB~>*5NZK9P}IH3_OUq8PFoCTCe7VV;;3lNJ`Ka6VqQmIVL>;cq(Nea9F^Fya3`L{9zsNo9L;ti`Ep^e2XQloaHmHeKPJTV z`6<8c7J4FM3G)eT{%}gS_Yy|m(I%dXlc^EtX*Qk=bo7$!H(32-Peo6G;i4g?#3!s^ zR*GZpH3>>O-z@uvoDfOUryUhDksN){(~}<3CrfxKx4wsHnWhRq%)pv*HYkS;WMHGr zW?VrFO9ONL%PUXZfrdOZ{%OO1{dN+Xe((LplX)IIox*!Gv|NzwTI_{u2|Y851d|7m zO;7mphRrOSNq*8p^b09QP`58)32;+ZJs7MDzQkTY%i9-$50^mL$>@F~ykJ4d=@qQm zYT9B}0jA$U5N)y_C3nwq$zDf^L?F|^@O+AMJVZXn!v?ZTL81;OL z3mI#8DPt=wa$ty7OEQg>*+z7zCr77#ap(g_9R!z^mkJVs{bJLWoTe(jSqZw*t$Qcg>;+HkLFa zQwCiA2A$&Q#V=thAr}TrnRC-0B@xo8^il98ILR~RJ&4T|dl*_OVsK2A^lPGGqous| zDU*TTludMAg?1C&Suqhuy_J^)W)c!9iO`Y=SKO#q*x6a0$FhueIpquIle84=s$wQA6wvT61bWxqxojJydo7j8?I zo}D|5VfQir03rU+ERP{aQRVco{p84Mc1X$K&B%NPojwibZ$GDjoHOSb6X$1g&$cIp zJf}v)tE!Ryf{7-c&Tv+1uw=2^cHvBke2DlJGRb`+Bt(w_XjcpHLJ(AG1}+$$GBm_$ zjU;4U461yHCh%7Gkz{PabT(vd^VT+)orw%x93?XHkv;@ANSU3A*h!U_L%-~5d!$*# zTkMfKblSTsmhvwBjFF!Yn*K+bGR0Ds`6JGF$dWkFqunBvoA7SE3}I+)IfN(e?7=D~ ze2!~PmiNGwn3mqY;G2m{0*$GjUI;h z72ssK7UjuaAzV2Zfu2Z-!QhPcG0__@h-dIvwrXTYm-Gt}xFKmMwETp=Vl;d&4}m!{ z<3Z%i;*N@}W5X>Ol|Ca%#Oy99Xx0H%X7LBvq+lC-NvaTFwVt15gkVahyg3`(R7t5{ z>@KZC)%T>O&R{F?Q1r{gni%}tTQBf2#PXfXQ|>h?5iV`-*h1;{8WWXes_x`=-cjK; zG1za;f-lIWENSMCMN)hczc+(AS#eeU#^pnZS1P!XdLr`K%9mp2D(u+p;JuqPj(*tQ zYj4R8Pdr`!0Nytf<_0LQgD(Lm;vcE_Q46&m`aKLLHqPHsNICKmNkOnbWbEAE((T>Nlt|FTXtSs#0tBFd)qE?M6X?Ix>s);772S;0c3X|sD3*J2CJIUOBEt{5m zkFjx;SNxs?lutf_t1zfO`=U>`k7JA|x59fR$r59tD0cIc!HFe1K`pcQR~qC}57A^OfwH}HfYY4IJt&NEzzFoeBNhE9JeHpoMYPOy` z5ir;8Jo3ao!hxY>5zYrF`$~M6>5}xQf{I>>`w_Abh)2`lr7v8b#rG$oA$lVt@6g;x zN3rKa>`XQWci4)TB8z(<+Y-*!1e?L^O<;e4i^jeL!eczYB4$F^`2uf*c?~p?9^qe+ z8|R?jG;zss(DUHi!7&s)u{6GTC{L5)u!a`|)X2PKOHM5QA;v#yBb2XI%1GMN(5fh& zeWUXG7U#?|-=|@L;JWzEkefnQv9T`0vfCK4J8CQ0A;6JcG|zannn z(*P+_Ce79eO3dC8d92Fp*iS!|E;Hqa@qvjgJ$RAta6bM7%;u)6b3#?{@Yz?iF;fHX zc|PN8F)MEv@IA!3c?;2PDr+_Kvt-rXg>9Cd{2$mZmEvjeLNbWRd~`vsVF>$>qKb@( z3KOak5p; z7}{uWU))8i>XS4#*loAi((weAhrwt;J2Nw~JR$ofq zZT5?OlNhFOHB@&n!N#o2m#*(bQC3Q6@z{1gaq>EqQ0jTU5mM%oU&|M2p|q9!iuiBQ zArkj`FwJAbX592plLNv}yr`^o zi530JoTi8zrwKSL+%VeWK4Z01_C!8L+921zWA?KQ!# zwkMz1x>YifLm6Euir$LZkI9D1ec2GdG&Ugg=$`|A!*v{DOvjy?GCvZW2EiR0%Pz#= ztu9KMPa@)~{)dM4Fy}(8jhIPTw~@KK?A!~q_xNG6-MCLI_7_B}i0PBh2lO)8V}5I6S8J$`HSii97TW&6rRxx& zQpHGbK7EkFZ@}07k{>KGzkr4NDdch+;^rCx;d?63&l4DF>U1seHocdoWTY|lV5KAK z;j#%*rO@9?(Xuu$hQx*<;Mj6>eL9JcqTWS-+9DR3BB~_lU~C) zJa_$tBed)$#F6M{h>(Nm`7WF8M_4W*f>JWLFuV!n$ZY=rp{4DX^?~R9%6+<+h!hC0 z^o@%3&H00`?0!xLIyuUHhR9a*yd8#caAkBX#`^gQ^2Lu%YvgA{em-BInYRnVpK`p6 zS9jQBHG3}I&Ez?kYt0i=RS}6pUcYfso95s#SmD~L?F#nn>lhF9`Dv<7$Go5HE3>ItQl*;n;8*xkbX8RSGBSre zgybf-+B=>%d%5Z_Ict;bDtO9lrzCOq_Q)SEaT24fbA;P0^B z1rr=GqgfGxn-vCwLp~^v5=`7K1dSm*8_orY$!70kVpGCxFfk2uJ+Xw=2Cbo8nD`oA zf~NWdG)DL{6E4R&8OZR^nnniN#WKY_`wuIzbkoQwP zNxuyo7;*2pm!zy)DC=LZP+*>fab61R4a&)ZSl(-%(0H@SY&5g!uP4ZgYrk9R*hH0F zv|;g2bKrQCROP0)8G5*LjyxBgC!K{VVLOzU3b+COC)rC zR{A$bp=g7VFf|#0i3(|HG-Uk9_eJE-<96OBF9eXoi+FBdeN1_bT^l)uprcCtXqGHy{;^`w} z5=%xz8tJQI_N1%4-wZH*$OGFE_u<~0&RBvm?DvlZ&G=3h1gW*X?*h+z9!dBawzn64 z1zNa$jPdTt;I&(h^Osqie5%;Op-ww@6=HpbVi_s+`>-gs*>*BLUZX||bZIh_lvjeR zPsq~j{FL%B%qs35X;~c)Jdqh7+6{|Jip$p>Fg9SopvWX3#4#b9j&xl^LPVlQQ#l5R zc}D|Rrvx%cD@LB-np|jYG$%y(FAt=g8koU*8NylQ!X6jph>17J;GTx7GL5I?ukI({ zw7z;pl|&U7MR3IE+7c!P;}YOvo%%7dG#RAW6U%7sCW^A(%iu$GZs|VHy6`6wr3G5- zmjd^4d!rh0Njhs{iJ|+UoO7S-RVL@M9Q2EpE5vwUEhVAl%jkBTSDfsgqLFa;9!8d# zPh~Y^kJK>Xu2@ffjAvBQVWG|YX1xwvrSfZ0+_RCA*T9220;^cD7^0!HB#d;9<~x_@ z!Fn&FWG7byUW8tXHc^RSo_gS@f|VE$QOMHnM{z8Uh9HveMe5trZLi$K;upo(*JP00Gwd(8pqN{4Lt3X@ z=;*v6y#D}Z4t6WafemH7BJMBCP&@FSq7qiW6rC6@0N>aqGmn+fNwDS6%jo(-i4_Ph z(1alo3@(}LmS>_bRPr#MIyYKVUqXEeqXLhkTo8r@j*Ts*Btk<0YeO6M6LN%`M}VgA z8-zG#Dg?uyV%D(7=kPXn(@Mh~x@5+kjHRKIeTJ(96RtE;Y*3W%a~1eFu27q}c5fNL{3CfA z=0^!7FpU>Ik(Ar+w1Hd0j&@;j5kgpDQxbHsfh7mJKODx)TJ9!^weo3|8Fv2wlsI(> z>GD@wIm&jJuchE^7qTEp+=yk7A4UkeG$qn?$3{+-BK6U^MogJq5~MIKkezrI`cZ`N zB{D||2*rU@H=;fPut2O^xEE|r_%v*k_9v}J8VSi{#W`YLj{-_-Bi@-soC`_hZ^@DQ zlgX~dX^$`_zj5P78|Pyuwnd~j!2x61SQNUzS{;9|r)GRA{%q4_R*~>D$I7-VG@azn zv-mb6x;p)f6jMM+v|aEvzjTdp`{sZ|HxcF8pJML^0Lw=6*y^BkZ!<5{zBxSi6 zH?M}7yeIz7Z5CylgXUHCR7hVYhzkDzAmOOQU9KqLrS; z$U>So)%J8knk^PTNsFTwM*1$Ch;yO@7eK|)oC_uJC*X0TMLe#Vz?jH|Y;94Bi-aqr z?qf1{6zSP`>9$HdoT1tpW6vYJ8bL264Y`>9tEQBaNQH_20J_biJ@)i6VzYCy3+OeA z=eX^|u-zYloBKlR2POm9Sz`oeBEvUp5Z&9+Nn1_epv$;;5Wjc{g$!YeJU)cP&qGgQ zYVH+AX$aA_Hxlcyz^F7uY?ylJ)2qET|d$0}yfG$ipdQR>3MTIxn)!9jTlyc8TCUId0$ zzp>Ai&j1*B79L9 zVzDs@kVJ%tMqDDLN`Vi^OTusB_?C<=E-ovmF1#-ZURqzM4yUSVsCq&51zMRQ>kn9Z z&9y!u=?_`+A4%zil0bU#Bj@l6^$%bE4t^oxr%>?%A}7M0EPO-KU%-MGJOP{d6Ioau z0piaXn2f&%l2?%5C5%e7U;~-FqcoAO^z)JW711kVPN_j*^rIQdy5iv3R9=<{= z_@!lHC1rf%j07LSu}GND--9oiZyR`p8NZGENj%KNWj+Zgi7^_C9!UWRJ%0iTuU-&9 z_<{qk6X2w*81+w7M~G!*6B3Z76$&L~Sy@?M8nGXM1Stp%WC&VT4P~pqHf!Jyp78RB zOs9W@v|L|>yrb|KEW8vPycA!7S#gDKTPcc`@U*BNPYW&#BH;&);}-F8V+aPc_?PhqjbbHdtI4>0TFSu6#!2olOh{Vk_j9ngUz(GT)el1;o-ErAaue5>IMV^JP98}rZR$3 zQf(_K;aN#v7tDMM@nBuY-Y~g&gkdA^A9-%$D|nX}y!wy4S99uKS}HywEf~3S{9L(m z^DUOk@+&Qt%a+T36TnLFLJ)%&$*A};(aI->(GOn<2ZUZC8Ly2XA>>*iGr>k7DFG_a zXN%!wGO>bxC)Ovp!xZi&K1Th^_u|UDS1&CU6)i0o2aDw1UMgD%czhlY0V)TAd8uEB zSA|ORa{P=SWx<08L4?F(QAouj3Pwc%0t3J(;!++ZBO!T|5s)J`jNiF_{4W(4V(b(k zeheyFDqZG2O-T4H+ElUIJ9a9~kj|1-u8qGP1Fg z$RHBFHcKVNkAnPMzc=RJ0thDX@LXbIFfkY<{2@hzk#77Ki;Ieu%kWtED;h=^w7eD< z2ry;JM8w4SsUK*^--|Vfs~A2feezx!KrfP%ka5y zxJ!gwd|NJC{{X-xK!=RLf`kM-3=pWwMjrq|kwIX?#mko;4ddn`xckb)_|jHZSIPG) zE8Ik7vADM}QvU#rU(KJ5d=Ub8K4An<@xPV-0N^e~%V4uIrKNaUS`le^X>Z9D;(i5a zeja{5JQkMokx(E)4?3 z6ui8&w6~4n=AN?B^3Zbf-Anc2cn=BSTw(G?N2n-I+`oP*iHs^R`^Vlff5%t(BKWK0 z_u%Ik7(O!rmhgNArKPgdJ_?k|d`}(vgM#uN5=cJ-7gF=)eEA6>9eDgpbqFTCKy@k9 zq@+Y6;tRxs(hJ72o>2JEm6eA?tfa4z{2s6pj};h^QE^dmA?-e;JS{$_)M17ehw!yLFXBz*;N{?@rKRPi<)ysX{Kfpmygp~lv?P5?Pndec)&s;HPnbdD^uy8* zQ{oX`qI!>{ePVUsPFO-efW@Mvr81dzH$nB_Nf#ixgb+nSTP_2B0f8y=3SQwP5J@M1 zlg3BPJQkOPjuI$-5_v@9 zgneb8`h)6Z%XKf*Bv5R(P=m*Kuzh(xCJwx${J?bs2|Z`Tq#$rl6CONn!SxBeA5fAA zSCGYEeB+0VP?APcSHyDtOg;*Nmtedt)Fkzlhl3;~PNC}o*M%iIlz^3$naWDac&aFv zpHk!9J@TGsv%vO1!SVaNDuU`CgxA!+Q`Iix#CjpoFE7-$Qqc6D68%8JRn+*Dfna4| zKtQD;5F-@vA@N=cFOA}%B8yVc^@p#Gyhs^YSzo{g6Hhf+M}TE~0RaO81JtKb5j{$E z0V@M2@={ST06~mPhwuz!_D8?KnJaRzhYT^gJ_5~dW7yAUl6xZiitZ%rMM6Uh!GkJK zApsXGZn1nAxQ6Ag36&uMA0FUCz=>ISDB3CEP$fnQAP8k4Uc4g)5*SGliX}>dOP3fv zCCgq&SHP0VVJqf%KqVmr5&40B<>LG;FW=z|t>asn?~io%OUpr)%Vo=ti}FDxBKS#I zpDK8SF@F32^We9O*$3lhSc-!Mmk2=?W>W$1+@@10fXZd%;N_v?BJh3-LINs*D+Um; z@GmTd_(d$2mydurcx^8)7cb&?LSL4iA5lHZO2R4Uyj)j@--RX1CCl<7xmj64CL&YC zSziE3_YVO`L)#ws_Q$iu6ihA`DS*m+Qvz3tnSm`20V*sc{AOT+FVq*}+Ddss1`;x! z2aJk=2(p-Xh$ga=72?TczbJnoT3#@&<>mbKiSAZbQdEeD^1qFkw|+L3my7N*_detA zKBFH}vXYX%Rre0b?3V5-Dkp>3@DNCRDHFn_L&aDR1HyQN*MS5NhOiQyKuSVEC`vyD z5>iqS2}wkvVjeLu;^30V8BfpJcRijLzI$WY9{KN&oRCD%saaUdFJ$*icQ4~?MN{3s-!z*;bSr?Ne>-#y+Cq3w*%e0yiQduP5qsqdcI?U!>86v&mb z*=)DPvixVpW@WPDGc!I5cn9J*ejq>ixsNWglCrYDi3S1_Nlyh}C1oWMuP@?O$@`U*l#g_zVNrtyOBs~PWxO7b1^hxqLBc8GLnoPE5-BMu<_S_# z0#X7}Vq?wAC6fG)i-Ziheg~Cld3d>R0hceuz`_p`EG}AJUR%N8kAMgWODXTdlD-s` zh&)9tFD=)QKQG+3!!q9wshLa$Q{#DW5XMgsWpMCRmGBV01^iGzm6U_wNX@)eErTvx zx4|k@ufc!EDj$JfU-3G4B&l8x7DP+G2Y@0XA|v4puZTO8jHWSoIcSkm($fAX{{Rkx z2qLn-gRD%ftgNI2qEriM zeg(ylV&a|3O2A5PA zH7Y7oEh(1#LZvd9X=!PAxoK&6d1(G3yuVOTT}wguUMes=fVlZ0($d*!X>7JzErR|5 z{{X_j49b<{w6wRL^8QMdE5fCI0=y~*;%9=TK$R^I1;6@`4Wan1((?ZR{Bo_}eiKhO z$AzcNykHOz9YRTb4~+aj=f~&7@!k@6&jH}6Z!Nzkd_l|gFD(Tx<9TljOGV4efAQ0_ zSApXq-UEk@{Y%S1OZ6?}uRR_D7nYWmmj3|YjBxOWsCmGFm4WJ4#?W)-U#V{j_<;i} zDdA7Rh7s*Sgj{13th_!`Q7AxQX- z3HWU#B_KM45*QAl)jbh~N|h_Z-WUG>;sSmF@fLpia`L2OE&EC z_W(x=1gEVqKaE#V14=jNuZ4Q?KmPy{-xKry0LE_e@KVzL2jWrzDFOJ!C1qtJqqA`z z_;hm};sa(GDC1;Tip-srsgoy)v+`lih~*@tFg2NL|yGc zd)-!w_<#>J1%L!VzDz>6@w4?xT3S$#mX^!#R8%m$9K0MH6uiGv(JEA^lBIYbfDl0y0#PbyEU?V{Hx6N? z{+1RE5Ke7g4HrbS-KA*|o`L}>=MgI!BGJ_32SZVNO`EY;ZttiHv93!LhYZo_2ZZ~Z zATpV5$=Q1m#C$+N;nJD27?EtYT*^5>N|TE~7;?lh5?P{x#?)3&3{soV^x|T+6J=5^ zL$i_(8*aTlK9RB(_f1+V)V!Qa3-0_!ESbV{q7Ntq2#VQzmcm2+ARgj*R3+(##B|~f zf##uoij8UNGJ)=zaj`f}B*etTv&E1}WT%$Djt*K{U*IX=_*uW6^78WD7M9EKw6wGs zIIW-|;!|yXdi0r6Vg(YtazSB$49UO*d=b+p_7jO{1TD4D@FD9ki)xgYNUAvjIspk#&CN70J6)*t+NJ3Jst{zin__Q_)2Y4DA2ksn?jrccASr?Pxd-E6?+m* z{4+Ux*6iVKaEAhf*KvY}iB8r5VL;^QNVOsKgr2Z)=<-9CmhdDn?1zjK38}vtJTns$ z63Jw;SuRt;oseM-3IqTarWUzk1rW5njg4i#U{x7`WaHC{nA_19 zG*V#tud$5Kz$I`Av&gW$Z&6Eu9{?eE_8Md3W^E(%v!G?JxDCkspnzyLFJBPIxq(MU z`G82-(v52y*kzw2F(eBuUw+J#RpwE-wBY?l@K#i)HulM!b1TGN4=DOXFzYh<6gCTDjuZXDL5lhimx}Y+ zT3^I0wr9=$UB8PKmhrr|h0B*N47q+w@#}ZR4uHzA7giamc|>SgE-QrULl$(^yE zaAyL5$4gW|dam`5%9@CIK#=YZ;O;BnEyK%sfV~tHYW4ETjzCk~j(KMd(3s^f_KA3U zCE(kAHtbbObzG31wE$9QCD$Pbnne~aDv)$wkn}4k2T)Nc1B+g|mq<@okPMq? z689McSksU)^k6F;it<<*i~(lyQGq|%glk2rnzib=COeH7z=i)nQ8&@ zLCN2=u1?k=qMdl(8u_*El$GvRxSrxW@cQw6qW9!w@Za&v!Y*96kWv6zxCu?=L$TK4 zKJA1@m78mljjOgQg0&S*jO#5-o=wXhk7lg{4QPgoo(I5|#2J(N5WVw7(e;H8HCtZl z>Eb&9!-JS1b=)ivs%X(Tk3)Z|@@Rb-_j?Yn24(2snIZ{}J{5;C3*i*C~XK139b{sFL% z0LPc&s7lCeOpyq9B?Cx!fde$hJ`NWvB8D2Ir3<~9WMzjaBiYC&9-)D(7bbG!^%x9U zQA93E#YUlP;Uc42Tf``gN>^w#*kh^h{}LUD|Q7Yc>72LQ0E zRnZ_&fr}`Q8WP(aWmvgvvNp4yT9y~6z*)d~)HZMRba?8vgYs#5q};K#6LJVZRY)yyQADHU6oNQuEg35@qjGZD;O zUj;=G<^c4|6)UyN*+oF#XE8ws@BNF$SGL`z$QK{1v3jmVYgD&=To<@PCZOS`5NwJy zHJl)MGgS;TRB686MZC<&but{EK?`-vg$;|RrNm8W=LxM@<|>$sTXQtojhSo5>Xqb2 znuX(dMM{;2{{T2~_}}GkUmus{2GY6_)p4}ICWnJ8Xs~Tx-o52%)Tr-7y0Oq*f3%jHm{2QpVU6@MblH zDB8Fl%@_;B)yxCH>~|5AIn-sxh074rMY519U($(3>19CBdW(irI=fd#KqBq+s8>&- zKS$2XIvDhuKD`KufTFGii+XsoY#o&>5N2EaW$Hksb7RJ4C4?@2=?aCKN+ed1g%D{h z#Ed9Att*(sH?9G$J8sM7Br1d!X}d%GC5hLlE1-`50HDEP5FZ&-;ecoY>2Zx>bPw?SqC}L1!jng@w8u0dS8J#do+} z@>L%f6*hoH%e(FmaTwqoV6o3GB8=Y#U^HL0%cb~|^Nr>183h$mNpg&1{CepBFAz+;tqu?5CM`+`fGWn8p zgLK5YSimTG^^h|Y9&DC*ipomL%16t*`tY>0SAp*G7K@jU4uw@l3t}RT#>y3*>jWwU zTCQH0?%Kyn?jYG}&Z2E%)DyZia|&9vV78X|uAn4n7ZhHAfLLUp5hreHDhYLNb{h?X zOM5l0+;$;bBHvUEVXt8Vx^3yW5)wJkIj_Qc_B z$0QXEJ%~QEyfi)(FAJ%1(X!wy!knOiRWIpMAxr|pDo5u`uVP|~{l3OhL*x#ul%y2B zZXTi!;73+F82my+YOgDJB_oaB4iw&ahV&vR!H4ukKiDu+?7em(PUZsQQEqDRu=mMs z$92*!Y9Clx%|-Ts{6z78fe1szc(Pe3DJkJ(8E|}Ofxyr&_1Q~=;En;XYo2o(y^0{@ zQpkRA)2$t$!Q9c#MPSlVvA=PF6q-{;{cx2Kwo2-&ubsfHMiB7VVgCT6Q$Hn?ET;{) zr@M-LCmzg7bJ@Z5P=rE~fJ4c|G8eXLxOU>=sBG8zfnWI zCgqH^+aOStmmjo2aINt%stJ!RV%lJz21HkW!r4j26)R1oauAZM zVh4m2*4U=16lX}*2u38$Cs5l`*n9NPS`ZUM2X8E**)g zJaRZ?rij_e6G|V=?9L;(T|9=G(9PpGerYiYXE%^0Y>6kZMm!J;p%Y}9IVyD#AO4`BElrW zL#o{S9E$)QF{LoZAd*@!F+{%NzZE;MR~kahCPG_yLGAz?v0IS~)~1K{qGdii0w`u|w z9oSwr8834TXvdIUc8mKi3^*CH5{Qtl(6EIV>MM65)Q1dlgHav`Q^r@hSziGK25YwK+CsK_1H3!nNuv5sM@(`uw^tH-eWo{$Zr0EkU}>u?Sgt)+@qj0wp@87 zy2*xC3XCerF2Kgir)*iNQAG-^9Gdhp(aHs|v`al@ppsw+~b|zQdj7yl?6rO`-w%sfdaSC3Jf&*0*k2! zJKV=@@B?D{YnM#LA%NDQJK$_#n`+OH{YV_MK(O{eQeC%_rKeXb0)dY$YC2v91Ud$j zgY2#@52quGgB#jKt5;xC`o+M7y(htOk-2$WMgWzdLBR`lp>Fw$aSq8#Z0}a`lIj%8 zRxzLL%KDm$*lX<`eI(^sHF`@=1g6N`C1Rf31?|*&{0U6Ot%{X-45<_<+jmwlEtVW^ z9c^Y?y&)1ZPNESOK;9P!L>K~;&GT142|l`th%tD|}j^%VrSf=@uw6pYVsFdgf-OpHJvM6og_ zitA4}3T=36keU`Es`sW#t(j@4g-3=ft4JNKN31Xfsxb87mN!V{Fy2W_1{Yu|C<7|6 z4jjN^VRh5Fh*FqR^wUwtI-mxqa(abLpj4jk0$kvqV7Yl|d3kwxXgEd@D;#U9!UKN7 zw@czXfH)}oxFo{@!>vnPfQAK^@3^K|v}V@neZi748^_odngdEW$$}f?E4+gmc1ER) zQ~tWR=|LN5@Y&jrgN2^W*tN+!;_Wp<3)_%7FyUzg4i;KvTB zF-zNbfG*j_d&4khQ9ur+J&B0(@qi??NJ57dTcgOCurI7a!G89HI3k7nmXNF=1F`DO z+Y8KYji8lHoAne6n1R&G$&HyH5`lo;g{p{S0SUdP1ELZsNJ6D$7Lrzzu6f<-*_CTWm5vA2CIq4Sv0A0}?aRWex*wod2>k#n}2uTN#nV${J_*SSD zdJM9TSHzQwElje*0LoKCl^jfW<f<@9?f-wZJ;j5{k>whm)4&}+g8O_kia_-2{Hh`h^IsMBrwxKmm}VxNOB;Y7_$Ky2P(Q!ctI|fm}m6Xprl6 zya`oEV1N~Iy6Lt62E?(JPR4<4A615v_KFNI`*cErz;Qu+KwwaBnY`%RLpWj$p=ch| z)JZ|79jV;%;u2vbA~_K}6_u2g2zh;JBbI3L#VSPhIc|xYDSkt?p$hQUBPvC`YK9~x zT$o22N2C`9McAi+ne<0B%b0|S*4rGT5PO3T2P(8iZUU$vG&*{vp%+EA)LR)DP>_Xw z_YD_00R&Trwg6m)uNFZbc2j0r^zin_2I?LapyK^b0BHz0H4m6z$*>0y9((tRMikaf z!-9nrR^z}66Wk4!*Fn2*OHLo4lre8G;DB^CRxdgs-lSLPY9=haD&Ogb=~mjC7_J90 z;F5(2en$i>My`qlP%G~Q(-L?BVKB?317d70eXvx3)qnz;+0r_4Q`KDMtF|v){7AId zB@Ga;Tm=Im-PS{!rrCB{L_`?Ior7o_RXMR%Yf`Sm3g&3lg79k^Xf(f}Xe87B-g+ zQ2R_l9`I|AH-)x4h?PftAdRsvk_CDE7Yks&aUE@lra_jR+i^1M4Kh&GGIbEp1Ty23 z8xU265Ni-6c96`!U}BiN)?me^BPm`K4l@+y1dOZYoamR^4M7C_&IAGnl}pf)tRjai zyefB|P=q)wa9!lM_p_%YE}60^%9FWuMZw&q900D?=lp-EV--PK>}I~kc#g5u=d>gg zMuKE|hSL_v0$2_EBC74rOI1`>9&R)toDsMcrRWGdX+dSku?831GR(Z^$SPkl(Xyh8 z!A0GS-;&DAiO`ua7TD}g8IAUJ+)CC0^wupgd8sQVBP45_Mug5)DA+b0z|k47MG!VX z2x4h)TibTVv_6P0^I)X7>fWxdRzR^DG*Ujy+H}zdVkl5{uMmT!4=W0$`-!LJru5o- z&Bk8eY*^SI%XCCPv(I%3wCRfsIFP#;@T@|dxILwwYWZU$1q1=`%lgHB2mF-WD&MU^ zjtHKijj%d4G(l^*jagqq-l`bYphd}L@G}HfB6Jdyz)a55Xbt=iY@?&4eRSxLnBW0v z=ppq2i(lBBKvQT}>NZ#kD}Px=?)2ef={q7785cNmvVw%w94s$+-ZSdCWgri2Gt5yJ zd9`Rh*DgSMOE!s}yO)D7%E>m$uJ~?NgxeEeL@_TwISkc~IwMu%i{tebIdN!=9vzf> zSrh{q z2?_vR*$o^PVAjea4#PGaEhT^o6dA{7L@tXG&6r_S(74d!tjg&}i;3Sh0B}H$zrfzP zAte<#I59*J<_gm|gf6d~ zj5SN8u8U}Gzf7#Li_%XavK5p_gqVnzeuref#M8qOHeU>8X;!OEF>E{1A+}_yvB?NR z5M}t&KFPDG00U#B)8Jfy8(aibv`UZGMZID*XUOCg@sV1tluL_EApXgoPO~za1@afF-g}khFS(%ECgO1`Asa zH_`;G*r3x@2eWXR`xXl9IQ>9y$duECx%;U>*KWy1mQ(I0Ju%jXZ zCc?bdLRWD_l7j4p)t$_iABZ{|!k?*I&CL#7m(waJ=o$wkiI`Xcs&29e^aYVZ*=V^) zJLUu!It;xU63sKOW7G=P!u=$&c!IAhj7$=;O%TIwFido)ZUs5FKOr}h2hgR($HAC- zs|#&NhgJky90O-UTQ7zdyVtOdl(L+KfJ&MZ0@>wpF3l@a$*V>y+Z)=LP!+>R5}+vC z(_yrolOnEF;$E5Bc~IHAU?v;rS^Fv@+{BKMyvjhT;6!dtghr!Ci>J8o z*R=E{D-Bdcvt4=Lf(d2}ldL_KJ-H<_cPfyy-WM0#Fd^hoKlOA@b;=zJrWS4#f;KrBLqGsDx-NdJ zN5z`G!Tl+!NW-r|=Q7^Cd>P*@vj-Fy1Y zpB9U^^R1KjS^Y5f$NKmzPY)^<&73 zKa92LR#ZjJ49i^X1(6PRRTxUmYh{vhboT6os9xz2t91;jt?SF42+O#n141qAsoR^B zhSY%9WZvA6xGvP+gRH_-pd9j8yxTFnvll10$It_XdA^}!Y)q2*Uf9 zDgJQ6EF~$&{{W$w@O@R9T&3n-!-KP7p2sm*+!-L)~%IT7>B58H5El% zI}LLVm25$LTT4qD{S4jK!Q_8mVBwBCr8VGX^*p-Hu35|U;x3Jqi;jbYeL;2} zKn;d@&LvaD{@NeOCr3iGHHSNy2;pe|FQ^HCwu zL@Q90K<_Jti|ZPXDhNFFwaF7j{g_0jh_|>A0W4xiG_o~qoG+k9eUZF*Mc3%hAjMhY z>B3MJdNkr)^&-XhM}q$VQLC{84%K;d%B>R4EWUT7x@8s0yXZ01LmT3jAjbGV7KDGZb6DzSxPaY^DbtA0@tfFXbG5xtaRs z?c7!`);UbVt!in#h)Bt-4I8Jlp+V;CJr74yH3+AJj7CspC}*Z#rt<(+65E9Xs}m6( z8zrXo<2Fs1ELE}=4#>=9YfIY;AZju#HjUBOxXZLOG`yVbA%^&Dz~YyJ5e>Pq zWJHUuPWaSrP_t(yG0_nolj&p2`d9;^JG4y^LPU$w(RvSv+L=$A}HZ&WB@xbCI#(<4JCuQQ>rZ%4jW$M zzCema_6}tqqfLlXk_zlo1rar@w!uk*N{qjdENrlX<{~v^PDfNU68^wu8J~ZlV$V@@ z4ozrt#?tNR3MjTpoAhd5xvP*HW!LbCLd`U_Xo;&i!w7}(_&OG&eI%~IO5>Oy$ruMj zCCJ2XidmYCB}1~@63ZqPf?fsHx`jziSJ+b#KpIP|;9AmE7ZjO77Eqyjc4{6K4qVpE z3Fa?xyf$FqY9+8iP2c|eW(9jhLwUSjQS&f}UQGerlHF@F0o6AK@)e?~+{JC&mx#7iWY;Q&EqQD0p;6SE;Z>F`$ydg+#EYvnTFXXQP z1W|HQTWxco*adrpf!kLp=cZi|ECFieohMK-pimzrvrP9!I0j*v?6%9aya-{tD)fv;RcNy zRN#qSz^ImH+rZdDp&_G9gR0>Py5C~h|Ny|RjpoI{nlPOH_RuCWD73r&k& z+|e;NyeWcy0-0gJvW3e;~DRnck1LfLX?=UA?KmaJrp zE!yB~wvGP)p9d@roouaq`RWBjR6Nz(A4FQt0%992-iQ;F!`X)RFkhjpJ%~TJfGrJy z?QWR4dX1AQ#sx(N8>aDOWhRmk!1|)$hdKv59R?t{7=ecws8mGnq-X&MYFm}q6E=(p z-Q-iZWkz%8DTPxkywzMqyjfR{sHuBjETmI*j#;yYY~Sw6J6KfqxC3-G6!CH7%ZL=v zUP)uCt&UDgU?PCoqzGNNKI4}_LP7D(%drkfYuSa@QvG8<2RlWg27C=@8=_rGqcr|) zm=^&<3-#(-45bzBZEcp=Kf}}sMukG%+Uq^SC@rdvhRy~8nPOE5f>FuU#fTN1`60CF zv5ZyhF7_?ij|7kn*O1Fp$jY1s2_UAkzD+{^0EBT53!=us5$zLNE0C+-F^Z8iwOH;N zJBL<>Rc^4M4ihz4<(^!l#oQYwy;CSN5 zwT2f(3#M1GFXSl7kcZrFh9CeitMtqsIAKCLST;YvMpqKI!;=_3)KXjb_IF$RMm1S# z<_0o16$?4(rIxR2FODOqHry1$e6NU=Xo9-gaF`R-w<>oOj1bu6-*6yEq7Zu%oW+FT z6*F|}57kGiw}lv3e)eIG4Z3qFBTtxOoR!4AO*;CC$K;&>#1lVf$aYZAC`GWzlC^)WV##&GmP~OB10;*u&redBI3w+vi zBmgMmRUO%vKy=N)%Pa#EV5Yj^UL&H?Q_EdCdou6`0B?LbGu=Wv=8fIece@3E^5g()31WQec7ocL`F-U{3m>Qyz_9K)O+~|e6<>nT!l(pE>iYm>Z zE1+38wVFFUdm%zyHDy?c1BjlRUBmTQr@Txa(qU1-L4Z-r!+2_nS{|Na=HMl@USQa( z5K_bamB~z$WX?{aVC^qjQ zf>_0ey zflIBUb}G08MyfdN6l#>Qk~{|h5|jp3p|}eCNy(I6q!omUiqf_QiCji8aL(>~w9|>r zMS?!tJ<5_f-9iTCi)M;gJ)*L(nB>F~QHukHEFd<~!XQ6~`is(OuD zoh#WN5D*qw*lz9@77i(pwff~UV73%+&I)jVO4=D~_s2|OL#@<$J-w#N7&fD&%jt!c z83)n|%pi_BEG-REh@;mL!r3_u1zv4^b16!4=w~(_uP0H=_{O+s1ywO{71gsLS2w&_ zJpl~c0hv@4{K_Fb6;*dR0f5Xb#W*TwTN(stv6g}w2`<_h5{{V!xxGY7g;Lh^{5rW>|fBJ~Mb)u9dhU;0l zxHzp#kQykKAz;?p))+wGm^$Z)r+@InfCCv*ix`1R?vz$M*$P^?C%hF?lA^2}2H=%9 zjq2oWfdx6xJ&Ys+aaJ@$7?N#+@4f|+Q#mu<12LR+; zaceAOB72lQpa4VNH_HLOq5#sbPY#$K@Fj^eY6H{|UYNZx-k#-!30+2)M>wTHpqlV( zg4^TMbEdyWdP%mRs^za{s1XxxV(XXA!OjU>ETllcg609NPFI8Fzama%>vRjl_sqw0 z5%GtOI!ulZ*ez97^z}&{z~xF91+fN#6Jabd;wjdMS^+4mG*LzO$~D5N4?UtW%~=O! z#}E`aT!b=U!GjhK0pO%XmI8o|h|7hy9VUS4`gUKenO)v!$grd zaAodLj6&tc%FD$JQG5koMYsfwzzmB*@Hly8V~J)h3v!8nU}#k$-Wszj%F#Oq2x(zi z(59i1ihxq^S7>#0U>Rw*XSgG1*wg= zWCc^QnZO(qy*-)40U8x3;&F0j7X_jZt7gun7%kePANws4m_c`(uLn@p1dLnsazhln zz#rScQu^%VzPIq;g2V|>jwmI-7tg4g>nrIJD79d}?5Uu7R|AvP*=X)6+l^JHY-OUY z_L9ZT@c=t$h_u5900Bl-27uYa(p3`Zc&yOwg3%h86Tl}c3WyRjKf_px9&QT9!rxTC zRuc@F6IpgD#sy0lzgo5?Y)kmsoU`7Yo}hBvXx+M?H|8(DEGldY&|>AR#6cBeu7SQ_ zPJ-;nOFM46n1)yiHDlI`V1cNc<<@d_5Lmw`D9CWReO>}&>N&ReW}GWSL}?@x2)>EH zmS&ia8e&;>Y7pWTI|S@gwPB75pcNjE{{V@WIlH7(!Cy7K*t+QiNOm`^r@^;VKeR%M zc{%<-`KjEYTV1Qw#c~NXw_~Ng2V^cg?L)=zMCF*}FDDVBxTqh~Rn#iokE}F0sPTw9 zwF50#g2Rxjh_8SK8R|`1Gq?lO7)NfPnUdN^gdQIui*KvCbhtwiXu37378_aUW5@PH zx0P0|CG%<8tW>lys?gFkXK*}A zew`vxU6R!2be4OXKVwX00IqN@%B*Ht-ssJPnyPkP+)hy4^8MJP6gR5rP%Ki>ZdKwH zn48S*qEr6BZRO2GCfO{=Tjgn}D3H>^V7tSKg~OsZ+j8Tzm-e8TmKx~ABhgBh`f#A_ zVi7W(LdqbxgKIz$u^B-`1~_n_!Q~N$;8lAsVJ;St>1aR{xVYJme%VQQqu9`D+n2Gu zJrfoO2`=WqRwA0$j6gf@11(dHu8}EAsgIT4F=A;f^~erjjM0J0&W$`Hi11>kC@C$! zkc^F8fgPAGMT}<4)Lh1(J#e{zVz|k4;$r*F!;Wg0v=I8@UM*@a@JUItHwh8|X5S+U z_6ekf2q}nS@rX9Df@S30(8`jE=Hw2+%`jU`!tiRfkz1 z`a)GGG6jL#Gz2|spcJpX5hC$w+NV5TqN;O6y-nR+^K&!JA!S6M<3z(yvnpzn2!v{q z{Qz$g%KphEb;sdc8SP@dGpDxo4260iPo6FW%abWozZLad<$7n3QEhB&$d znl1(Fmis^Oili@FdKp~v3)ZztgGP{P%%dm^h-)g>_=LLh?QS?0%ebRKV{8avrCD95 z;j9A>uvkS0SGWMocrwma39t$7$VsFDP7Pqhv0>o(G}Nj&sM$c);wT3tu#{IfGIj;h zjA?x$Wj=fi4=ubx1Ma{Gc2}0O`e9-IMqVbM{x99u~TX z+ZxCyC2Z0ww$dV5Ps34t1YHW&X!WavF*+1ZGbjOuRV~7|CxQJm%3*TZ`zAfDf{qM1 zIA9y~Dvlbg65Ihdt3@>TUCY3Lt^kJ8zvC-WM5Y?n*Z~9K(K@+H7h#%4m{-t#GfZjr=6i*p*ro2KD|xPI^D)DBGHMyAV4 zgsdQNUL30%SKKR#=j5=HTj*{hT#@e-+Vc`7P)CqfMaF;t8~0{CL|krnO_j2)t(Ur6 zjD-xuYd4rs#?T7kHKcfgqY14jYXz8y)xcns-r?SiqrtsL-r7;AOTCt0_^WlOPZl-SY2oAM%ffJ zab0|6`)YTaHIx8}sm0(s1Y(VpOD z7)sj(KgJH{A@8&YHN#Otwin+5Bm!Nx3-##IdUpz9rO>Y$Q5GIX)~a+0AR?`z5Il@Aqx=Ii)F=PYX=5UfDS}%unS=_WE9Nx9T~&&jCXfy_Z)`QrrF+xBRbr4xG7WFl*&Bg$A$#4F)MmyhXZhYA zkSr)>twG(?B>UBxiJ-xB{{XBFvv8nt^uuCRQpY~vVu^<)OY79o2I)6puKYC3tlZWE5wFfY5SM zUq;`dN$R04g6yqhs6a>tAELBDdbzl9j_>TPDd7QC>$q=iGyeccA7oQjmhU50Eo9rw zsDqTaJ4d)M@X{z(6#9uoSw(R%zR62%ykN%#R3Rxx{{Yq1n2vST7%xarK*k)AF=|vU z1|iauL@-`IS8zaFEd61rNPq`H6>}S{TWH4C2o)5pR?+U;mRjX)&^Sx18k+_M^1N_I z$@86^t9+faIcf%(6dK?i!gkx@=dIiiYL^#{u&(7|LPD(>S7?b9S&JMys(4@o2-=}^ zL#`5FhBcNbQ)mRng|8C89@U6dh_=&eoEt_xIxM~|M$T{b0eHigATLcujBB`C8UPCv zR95>Gg)T<(0}SmX6O||*(}+P_gI8%%RB9^1H_?p}^=ithr3tv@S;z60P%X6FR#G;i zR)ezm>Ma1|!D<#=Y5)MIDN6&y#v^R0+fSfa45(Wy=+jv4B_)uv(v);^+(3DHakoU} z$~cQHMY@a0M9Q&H>T0%7=*|Ltys9W4PKXVjd0j@nb&NyZEP#&a?o~oM${{Qphma5VvENSXJh?hj$p+(vs&Kk zXqwKsY0x-tENqgUGdP6`O|cZcC*IbPR+tWDkS2h6>}lAk3^MX0t0HuHUBdtdj;*)@ z6D(W>xIXhOTium;aS2qa3Lx-Oozy{yAOyGeCSfQWa)=Fn(ju$Ha=)-{S=%6WW}sSS zG5FDr;nJebv%-p_0>#BiEc(;s6tB zyguA@z^c9BDcm1j57(G_jO^$IQqESW=OHYuhR|sH70WKe2dt38+S6;+(#K&1n*(|( zGAnJgv6S2#4#t>-!F?b_;{l)N-_nrzt3DV(je&F6gdU9bttiM!)=s zIokyYUAC}$)Te?hzJ5x`04QW;B!Eg5;0wbFYplJ*@FUhwkm0bR{{ZpA^D1{)Y0EEY zrc@T;2207EBM&7Fni~YFwNS$c+Z~O;RK##WG&O1uTDWT53s%WTKFO-}i1l_=s0KQ1 z43GJVZYf2)hEafOj-PWVEFWPCFxG5hcGy9~%iO)H)+Ly;@AG(4@cyN- zJ@^2l(}T#=L=@v#a7@a)IUvv^x#zK!YX%1X!o*!cT`&Y2G0x9$ zNP!clJ*k9+0tjXnW419Ctzm~Ix(k*bKo^u&=^{id0#v1;UFG5vRtkd+RQ$NaHA~Q$ zOI^lNf+-7RAk&4YkCkc_SL)aT<$A3?;`SB-1SO(XrB?GyX_E4+m%$K$c4>LnH7%BQ z4v5Zdrb3h)yaC2n^|oXQ(dph`NvUB%vceFymXT{vX%tUoN9Dtkfz1PSaS7kD?y;L= z3yH0qL1h_;77LQu!qY1&3n-@qt`4gqucQTzkrj%rt^z>96gQKXh{m>eO6apeiY-Hn zPzwsDJ={N0b_#C=Iuf|qSq#s5C1;jl0zqrHnurIi2+fdXJ*q7dIP(!hX56Zw=EE~n za+dh+Ac^l`L{P7N%B6uJLWOA@2caLqC@mYYD(`{I2kH4n$@(JFV5<$VhCEkp&a;R? z(v@-xcU-eb^StkX=pu-fGzaPaT)@VCGk}WY{#fJwt;O`KKqAGlofXB+(pV6K-oxy5DYls%TQs& zEeBVmge6Ul9&jW;JYbY2Rsqn0g&*={!ps%NaM)jJ*FWgNC`(}WZqBg=*pbs2$VYvM z0#oq?iR>!;hLK=X>2g5!CvGOFv2GY`TQOO>ZvNoRfJGSI2T(&P7F1|D6L?Y)Uef6{ zKq7kcfwSP$E2e@H)kuQ(?lWcKcg-jiI)KUnT7zylh``#Ln1DvH3^y7yYa$Yc(R4Ii01mr{&7jr}W!q|MogXEvh1hiVF*v!TRFEJ}5;boz z$XzMjOA|mN*CekX79=IrRGlNq1(5@s;d{bE_?ChO!IGUzDyq}5C|_x^4x?pu++^O#=NfNv<8{V~O^@Nwyth>8@k->jC(ItIBddQkT+IyNe+N#%;b z0#Px&pwS7T>$;X-06PU2TIeO&NAgoHV%p}G_)7BES+p$O{XjHPS_1<3?QwkBi4X&l z%UG@DAQ5+62i!7-h!;ki*Huh*f&pBku+{tK1y!>PE44+t%mDJM1yltIZjsZo7B-cZ zbFh&LsE1e%dCU<2Q#AML71eiJ)OAczTW<{FY*T{4s49RrSj@fa14Z=A7>2`@J>~)u z9eaRGfhZ}Ir2;+zO3ht#P(h+-ZjFNj#>qm<$S*F1CJ!y58>lSSFZ^iBxUK2R4vVvr zC2OXOy>^nRLzE>JN`3$+LcKeRX8;1UP%NVrDZC!o6n#9B+7T5MGJ%)aHU&k68ddS1p5W8p8q?gjgS%KN(&$ujT>xp> zM>LNCHlkXPVyYQtBy%exe-bA$WAlYCeu#Y)15hjt$m%!3Z2(nCgl@CMwUj7Wv6A_9 z0^jB;^|8vJwgAGUBRN2C+@aM7?hk8ATZ4WefJagTPXjQam*4`lbpd5cX8nx$vaLJ% z9rn6EajEQP{^4G0dDn0t2BL#hP~Cea(!mzR@@-;qNx@KC%npcv*#I4Y}kvgC-&}EXG{@UM-kBl`YG#IA7qvqw7Xh_z_=U|%1E*Q z0I=zXOLs?Sa*Wi`F?H$#wReg9VS-pPK)r~Hbr2=G7KaT->;VLV#H8g4;G|?m!dft5 z;Qs(&MLbj)rh>%uM_UxJd5cb0JfT|EmN;=MLol`7CE(3L!E*Ao1o7@C4L56Kr>>De zxGl6QwOq`#ZnMF*R~gW;m~HsZGT8#y0LJgp@*^@3;)A#}qUKcv@Pmfm>_8!~qx~X< z1ht>B;9;iAB1=utMc*)OfQ^eLfoi4$^cU_^o6wQk+Qg>u8rcp#zUFHjCz?8gXrka9 ztYPrX%xU^|#SXCq83C+oj)qJA{{W=MPk~u+LrK7dbCFpgnjHEeuoGRPD_$=V z>$cb_5TeIKi=w5eK+rJ4vY-N&KEs3tCP&2zfHXt9>XZIMm~IBS%Vz9|0;-5cu9&G4EU41S}LTbXGE$V|rL9ZJ4=f*D*kg#2YunqO?^+QG4t}Ld8MQ z>d>5V73-iv64IL}zJdWUn2S}5K|%>C$`UOBrPSTRzD!_WWXw@-V4l#RZaD?S5u4wj z_X;l{9KZ4xo)zoXvVpjpA|jVZ_?1JHHr@j;RA&es8^Oe2siMH^P)gOc7T-!3VtWGE zJ%7j^nddZOSx?k4L3jH>`n}9_Ki*)AO4`O#@Pw82AfCf7$TqnY3(|_B0Mqbm^(!bB zvJ;UkRCz%a8`bD~qC3&nl3GYubfh?xvSZP4Ut<;OP{kVNIpjb!#yv(cLR`8B(c&;jFbjUnGC{S6hsWYsrBxnFsO>VLMgjN%e zZ!)suc`tLYv0ioQoajdF%P_W9vc*2->O{WObv7*?F%LGClIz&YcnG;E=K2q3b3u4v zcL69-1eAjcYZ2|2)BZA$HX^lWb=*(j9rX{on+H|QHe-ctjNHm_+F_oet5&kuCN(hb z01|~SgZqzFor%dXD4jBp<2{#iauTp5K<|@<>)YJMXa%YtZg|{P!wn$UE>aVgS@8Xs zJxZVvhf!+`L9KNP=UM=U5-nws+SaR>jn#-5RaWuL6&>OK0A=+caDvzsB?Fj@#sarT zMmKD_0r39-rskQoeuEUk^3%jlEKn<;92d<&1+ZsDVOmRD5J^^PM7;@d6IkW58&sEz z_)3|^{iuytdbwv<8b=mi(=`dO0H!Rs5e!SkZdwc5K|~FWZN1;Itj4xDFACzxLKu1$ za2{&)+YOJUWLrs)Qwv$DMGldJl;z6L?#LXg0#Z7mVG-YjWWAtCWbz^d4%=rW17N?U z0?=X{3D7Uz6t+~Zg47cYnQl`kVw6tHgix$jQ2G)tcmic4@l+XTG| zOj9f_s^dCYQkA#^DRTRTh-HwS1ywJRskQYmR%!( ztz!CS-nD_D+bG(#E*`^c!aI=wEzzI*4UXMqTwsMb1t{!VCv02@#>5Uw8$#EJpRGab zS|e24FVwcA{{X2odkeDb=)##7^-Q@5XADaeu+ZK7oUrVBhX`Jnq79mI*jc00TB%KX z?j~7z!a&_O-NGAa&q%!*a@^$5*`M*8>c$$(wD3%Nm@^QNS1397>H#`X>mHkX0?g)-OzKTQ7SYRzUB2 zAzRN2*MJed(50wSx{Fy`8KZw?CDS+=AP5O-{{Z^oVr?17#u3xA{Ab&Gf(C|V%XX`s zY!0a*`8IZDZ3t!Qk0$g0sI-;>5Gx)N;V2(a_xf@cl4{%#+sgy5py6A~Zk3s4PK`X# ze|wB;`b`hiqZ51_P!;l~jSF3|^q>VM{{Wd&U}2pJMs^Vo1|X+mUZP8l<9aX}b%H1G z-=sJxL&J!DZ5?GfR+Wz8igNgSaRh5}=LW1`OU2I=`aF^Xhvge~w8Q?!t)wCw3`TJd zMzKwGD<;db6;%UX>Od70GFvPdFwwQ@fPusj454`%v0)G@1S@tkSPmel8!pkYR=v5F zF?gYY6sU`=y}uh%wj% zSF@aZQePcawwY37)OmqXYf>pk+YOo{84%Gmt-wRL&&kcX2h@K=AEE`P7ylOB=gD!-)kIKu0H&Cy2Bz z^}fI&$}ni$`b5-ChPfhZY$Twd{W3rvS1Y@NR|=E}haR5B7zYEF7dIORLuoQ<=;>n1 zIqCwA9>bs9cUf9$ICQeJQrdks_v#6nvXz9$%{gEtW0$5Z<~ndABP#)mGfT-W2Ve~- zfDlmG?oqblm2@526alQqWFvb5HpXFu0D-3*;$*EUgu1hivlyyiHsTu;Hs~o17+&PZ z+31K|jyK9BT`$r=lvRU0ICz0tE#MZl+5Z5rISmS6y|7p?ui#8f{YW_tYVl;cY+inD z<%G2gakJcDEM{oD`-QiPDS#mY$0p4`r>S^yb|bhyVXa?eq#pp;)&N0lxSHpjkV2sQ>1ZL1ZA-!4i$ulYr z(DF`h$?S|(OGGM%{`!gTD^K5KVsydFDM4&f%dRyoKoY~R@;RV3%{NdCcW=Jo)-fzO zBGQQTVPM(Lj}qVh%$bDg7h(KY62Mt`HbfJagR!4rM;2CRwp1j7 z3ehq!J~I;n0Cz!$MI>R6&d!XK4U`xONUKLH9g2i$?GjVUl}qLf%Y-mhd%h}IIoKwc zinA{GM$;w3)s&S?G>J>0t{@RJ1}}nsi+Wj}%M~ga!i=!d2Uu(>?@X>Wrh(C*Tjb0= z3@XyU^tC9_z>=?a>xk>+fnr)}uu7*Cg3xk4p;R4&SW3KZ6;X2-V7fvOP71dWM(A0nshSjC zZ~G4nFHq#4aq){+1pYF~m~GMgWz@Y@j5x;$efC{EID~b8g8u->Fye}Qysx&lh5w2)L07I_JTJfC)Bw@0r>v_APiL4O9;@e zCJ;CAiHsmjD`EChLt7T5h%T;;U-n?=HeS6lr7VpzI~e_BiSF%nXX!a1l;8DN-%{}~ z*Yx!a70X0vknXhuNVuXBjSdK!lo=w&I*PVM8!q9OBNi_~BiY#$nH(7q=WZ23!Iw1{ z;k53hj5V;*{m(=NrAp8$f7k}sTE1=`7_*V4C18tbfN6cp@j(^1KZ+rbT?#ld_Al_4psrR03gEhM5gVZ_R5}V(UI;fdhf49& zaJ|E%yyz3SNo*i*?xh=S6f5ZfFI6kX0dPvY(!jL-m|htF00fB$-aOq40`QML3xN9r zYLN8E2~YBe`w`Fyrm(QM`;>sUfj|XIk9e2fOT!q&(5#_t))0fD1%9Q05Yu)400NI`148$Y(2@ChiaXDx$56E(og?C95EQ=41?T==)J4iH1iV zMUeNzQy3kPCYTw8k5%ZIFRNYu0CH7H(onL@On%3vipGIExwvXer4IDN4#Y zmSCk7w9m*?GA2;P}mN;Y{~KFGpvGh{H^p;aSse9 z49u0u!!ni6`wI!XF%Sx>I=|!?cG+H_C>-kyy>+N`QOJa@aTEbYw$Jt(gWc{ALAw|g zc$aH-FSUDLNy}za<8yiXu#|6z$J5$GziXs(5IyZPJ~ck z=qiD#<8@C(1VR9*Ci1s`|2AgduTOIK&$tG1BmV((}!ndf8Q6;T^!WvRa z;y$gBN{Fow0cDv+uy=1MECF+@(gwKzHVvR571zLxv(`vwZC$V+QYmGU(|`!4COee9 zNoqLAKkQS|8bD*wxvf!=)$+W)KoaVZ4A|}unCmsv#aVcY(9LtTAPyUrN&tqU-BbWm ziuMrAxI0O?rv1ugMe#D^1fX5OYbLuTKy5>C3cuV1hR&d$IK9f;>jq;*%&{(^TB^_f z$`ygLv>}>5xzG7noHMVJZbSvtoUkrW7?xGu-qMs-E?NA*Be=j0afHJ$;YO+l|xIwBcP} z9n5kDmR1bmWg$Zjxwr)snl+*#;O+=NqXA}*`Exl!4KgI5MniE-jl$AxRH(qnthW+7 zc?bX*itO5pQ!Ynk<9$vL&gNMn{{T?|vv56*&SgtcU<$@zK`E@T1j#s=n;18!vKyhr z&FyFWs3*X(*oEP2f)!&aq}!gMurbCir3fi1+>)7N8Zu%KZ0rIEC|W^=<1|>?d9|h% z21YSVP==0~r)5`T-3C5bBSo)h0%2o(8ja6<#AvQsBShDgW>~bA!j02JXaU{N?V>uw zhV$Q}FrZz?2=$n|4Q-u0#HDbo01rf62`SoJQEAdlcL9@52$K!Owz|y&4g}c8xx|)F zvy!#k&IZAc(o+`SD|W-C2!ME(c!aQR<$@%Ity)tAP_W17l&B68Tv7>ipzfSPXTBxr zVWb~$2N7<8a{+S1)3FSUYchbLFWfCjLBD#JEhdYI29Tkb*--MP}DR9GXCd;~V<~5@TLf{{=EN#>O0Cftg zs8bGDv+S&Th0d7^!g4WKhGm*dO9db+Me`NQiChL_fDRlL4pc7mL6ahdnTGz7Bx@qo z9mEw~Q*!DW6-Lxxz*lVD#kS*-HP50MSU@Wke)Tfl>hp~E9Rqc^WwH){H^j`B@JKOv z7q|!)v#uAgwPmfp2857}zyUKq3o>_&-13oEd)n1IpLrF&QWn4;7H zqu9#AKiQ0ehR2z11{MDRXry0)WZiM> z?8*eA7=%V?e+i?G60g?ZY|1H>p4zzGs=6U+RBRf9gU51~e1(F!8~|@<7C8lHWRFzD zC9u?a2s>F|15@4DQpr>vH6e3H@xyTMO*v^|wwwxuET>3h$S^lcSX#D41UX_*l8Hf9 zA*zk{61=h5Eg_HxE_q_Ean(dTIN%@_mV1sifB1;f;BQg5XuYpEkI zDUam95kn``ZJPy-Hg^!$BYNU$z$~)J(b-*rzi=w<&wa`P*2V*t_^D`aEKv3`(58+U zGZ{dYOt|Tad%fZ(0Yn(mR!V7t0=Z=l!Ulo(%1|rnEQrIB%zJ)AAQ3ioal;ia3=6?| z<76zTW~c+TThCI|LZDuib1uqTj!X&&hE5*OWK!T&n}P(!VuSo_oMmR26Nl`lt#_ap z@3;k`mx6MbQ-t9z7}GYD7nVK+&DS^r2)o91ELT|K05O52jg|h9v@# zoBA=Nmh>!(a9a%+R?IHBI+yK%jHfDvJZAp@eZUM6z8mgan^|<%?gw!J&S7*)hR&^m zcU|IAlqnNi^aKzATWc&{O3XM1*SW}zzOGtupl6ADTM$bqlmm!fVhO(0e@6|u!QIw*`4dD==+aAm(!PO?$x*QU+Qr)zt)(+NBbwnD4#I|9W3hzGRwXnu! z!_MUdq~{g906u5$WWtf2s{D6#3ng{P{9SwyO%i_E^R zRDe0dy7%PSIw;VMFK zbYVoTc}!py~Y6=OF=(TQm!x+Kh>CkyuccE-xVyqjWZYEb%nU=vV(*ATj%P&J2;fmlPJwVH%Cg@LUd2TrbU)oJ$;TpAmz zfVvs^DDRCC20>c6RFAsxbrx)SW~0hwdu${SR#B(0G)nV<+_Mk9Hg!3@^&zh00t@;O zrX4g9DrI}Nrd${?WTpQAur#30FHqbYuh}BU3^$x`S401x4?cJXtt;8w|{0_sjVOu0#XdnugVqrNz%?ONJ^c zx|QBjUz1?joCh%4zd=MwaK54Ba|KG4a;!gYOoRb)f2$U$ZOzxHEp;yxVV1N2F~Nf5 zrq!#zuwOv068YHXsv$CoU#KeJI807awiKyASb>)m6HCO)*V?y^qXSO?T8nDk5?yGg zW;ZRyz2;GEkYL3g;%vI;q5lA~!DU9s50rRjqA0{3OvbBM_E(zvM&Mw)sYeU@o37xR zv$)wDBq_cx9YU2UU||kk;ITx#rW(vPT5(y#Rir~@M600x0NaSh03B4V7T#rWH`g-| zkLp(;$H-F@`;{Mf9Mm^}ccT9Q_G1<>Ah6?CiYY&F);WvoIJ5WEH5pcFHPve6s*7K# zgv*Jw4ULU)FW*jLsZ0ETAx>;9#*O9-Y0)N=H|iQx3j!fH!v3a`TSTd#t(S<_^8TaA z5(kbRy5F_WA{*2s($>Whn(KX*EF3YJCICXim+ zhZM8bvg34}pZQQCvxejQDc_Kf_)G|=6~Ba50eJraWw0#5?S_Dz$}nPLrTr4dV5^KK z%~lp!R)So|V-!oR?pLtn4d2;q+gFwqe3n#kTGx4%nOT{QfzP-N68edZf0VhyBRM>q zm}ZW18_27PNL{up?D)zRQ?({(Ve)MP&2z8+0I@V}T;g0tyt6#|W&(?Vtl*9<2M?+v z=xc){3f+Xi56(TkVW1)i$(6uLam3gGD}V+f|_P#Y3|_BLEd8-2IVTX8y2D5Lfd;YQ59ZT zR^kwBW4uDun*)i64MA<2w{M|>yDly4U-@vQ6gcBDmQ?tXE19Wq>pySuylaCe3ecXuxCt{Xnw-5D|%?EQ3~ z@9&SNx6r0dPL3pPnpaN3J~-}5uYHzg|A#mdGF{jP^TKJ3h!c4yhVJS6E!;8!p}Qa% zI~s&R{_}B3Q|nXJHMuD-rnKSSrbZQ3p=)2D!8T`^;PK`Ny+%*ks#{C?A5NmZTqzFe z61yni`{t?RN9}fY?4arNM+>pd5q`S5k%U=2PZJWv8lEUNfXw5 z&w>uTy@}$t5s(f!hpQYB9*)}f#5Wk7PWcpLlL+ZOxSLE@g2BYpvg4Zcqv$>2zd@4< z2!kVt!DXQ%0+cH44!B~v(X*L3CU=P)p^5M|qB^cn4thQj(FCd<23p(7FCXbemkeo( zb7GICRgbj#S4@t z9$JX0SNuw$SEDX^vf$S1guIWDH$3eCfx!HJf~ks8f*vt19^GzNMNm>XBk#p`jH<}2qF_hj?Nig?%{m; zQ&3*Ag9UO=Hq6x8B1HMw1x!XxAS6?Zk7(?ANC=)bE@4v6zMY04YS4M^NSBtd`@j^b zCPX;D*vujk6)0~cr__d3eUJ_AQeh%&Wbt0r+nGv?$+<>C0?In|pF zvdTtlaYdxUsO(kjG&;??b%HEFC+4Ym=JJDI%4bVNdHiD|XQU)h_M=TV=sU^P8oyha zbgAKro0!WVb_Hu8n)J>@)2kXCX5Kt z2K)quxeHm5iTCI?^lpUyuIMtxYI?tiPKljXlEVu|8{eyFO3^`ftx7WL5DSo8;oRhw zoAkfm<{(=JOb0Ztoa<+^#Fw!-`0H8+t;uTL5q->5dlg|R?45p^jy3Vf`fcY5vtV$} zIpvsen=OO2HN(cN?C@$WDeN{Wr*VAeIIN?#jJC9~gO9dr%*G|a&Hu<)7{o|G`t4jJ zf-LDh4Q)iR`}j3C4W}+~VoaP!z%m|+^%wH)z=Z{i6&>a~xJd7u!l|38IwPPMmG>?h z>E84b(}4Vtp1GJRV_vwg;2x~j*U;H!=FPf7Vjy926-iK*Lm#chzeq;&cR0@u--}>& zsbZ80sKCi>^2}G z!g7{lJ3uRb0A6a1*}^~<6K18rfM>#%I%BRYy|H`W;&U^$=hnq_B(^JYng@6-@dFM zxJ9U+w==#2&per_2S!~m^#&JcePRx zp-iA)aymr^+EbfYFsK4l%z$NHz4r6^A-m2j){->62Hy)s6tErW_0U~;SnOljwJ`@c z;HJu+=6w7pJcC@6xPX4?uWcdIk|MY58q*z>^+$BWWJF@R)>P~s3cv^{&MCnWPXg&5 zX34JudkpMu<6YDdPM>~~Q9jK0#y-R$x%jQfOrt6FS4rm7g!*byt{P17jV4&Xdy>FD)l&hcwBktZ8$IbbZ|*Ry_$lO3+z zx*XSLZF+Bd{2JY#36t!X-3W`cUYUkJJLuvj$~YCNh+q@;@uRq5pULlZ&~}vD{UwFW z5@pKZ=XrWcyr2QEI8$Dxd~Nq#!jy8$#AJFcP| zm>L3?v_QMJl|8r~Q75hY^L|%p-Tcoo zAnZH~Xs76!0+}@JF_y?Vrd!tkfm+-^ZSw)5jTl<3!H&%ct^V#JVlt$XeWAP3@$Tvv ze(c8#kxiP5(=P8@qvLDy3ktTBHjfiOF$;_N0=S$|kV=vb{n+7|+`r+XqYR^})S}kF zZ;r}s75l`(CA15t>j{UIBV9#3t_4lSwFqb7vz$E|jD;RPKF``RAbbj4^7dYKvNfef% zN>1j9LfT6=7?_+i)#*-`Pxg}kl*Y;UPK^{ODEDUr)tW+k+f4jCc45>O+F-O%D(Yi? zCakFNSdW?Bkx5&ZU>flzc{o%K#iQDuCrgr^sC#9^k~=;oN*1*V`11(aez2vqn~Z^v zF!2kP<<^oXQKlJ03o)9k-f(~|Tf@P56PE^d4-{6PVsyyXDaG2mw5DWIqbR5zEkkPw zgC>Y57ei6_fbiWr`q)MpcqcD$d%?@6wK{f6apnz-nVtLoL>D;JZN6wFEO z3`!!Q&Y>C~t6Fh!e*7ILpICzRuN|#ty5VR%fpTRI6kv2CcA#6S2`z%wft`e#jrDPq;W=cvFneORF= z9|eYHBzA=`$t2~uO0-@*cn%)i2K`Znn=g2i?+`P20!e$q>6T0_ozcJ+!sEHed}R+aIY$+)+-H>WC-Zf~C~E1SUtu}ZVtd6@Aqe3tvWu#d z4lYZKR=g?m&Rnlt*|E`gRZSUgVAhz#!ePc4Iug5)F3GlW^QF(yYZPiDYYsDQk(Px^ z;(MZz*T2J_mozhf#Yj)2IP~jo&MH_)rR_6>+=zbg$71B-w8PpBl!^E#X+^(@TqVJNn3liP$lyV+RP&pku(18z!Uj#o>Hi6Jp&%~EiutlRGr)957@ z%@O~BewNC6AXJ;4dmILz3ng##6-k-BR-Qty_nUzwE%0UjXw%!6ZzRX=*boz?5ziUT zf0c)s-L?8I+3~`BgQr=HEyghJ)twMc>;RuX^Kl zjJyJ~>KK0t5}D#=N&o;2UoVO6R6&WLiK6$Z15SD~hTIP2F6pbxnWMOoNb#E1Ca){H z8q1R1`X7kWag!k=TY*Jf?=v(g_Ik=h10p@DAUi+_%zhw+L#X)81iG%A#)QY6G`9j% ziY1+eg>#qBKwgp!=G7)^wbhxybFE9lO;UzN8<$0C-n+rVeyK$))enA z;?!|w+8q(7E<>fC^QA&pIh+%44E7I>D66rI;SRfm&rm=T8Nnb5eH}8K=&pr&r(4J% z520aRCT!%!sjN})+zMQppAKjMyQdRhKiZg%S>1$E`rk*@yd0rXDzuA23|XH{eun=1 zn1tQUKxy@z2Ntdp=0jY(=+H{KFRete(~1nus9S6l6!XO#Xlml9geis@T9i$D=8$M; zp*}~EbG1lBNoOWxv_n;eUDG+}5B*bf-P)pyU-1BqOb|#FTDhEIc+n9PgGkFGe6B=J^-tP9K< zkg^XbO!VMI6?o)1)3jkz;XC>S%!rX)$;K}y0#LIt;_drL+>M%82O>?d2Y3|h5n42z zVAM?*Wy~eb0A^4~9cS>Q3oi++k!(*}SJZQ&I%5d%MG2+WD)Ab^piv%YW>LTT_sanq z^gfGKannT!0+Vw8YR!N86H=56?8&HI}+I$|OTH`h-X%8~x zYi2k8q)XqaU89Zy*r+zvLy5zn3qCSz3Qt6*UeBV^{h{ zY^W?mEj3lX|0F_yb(Mh-v+JE^=j!Q@#>Q@;?lp(*wKU0Eozi%P!3jQ1>oq%W8u!b7 zoLX$7U_^{+sj}iaSM46)<3eY{#n5)zUFjMmWwLfXbc0^fn5v9JhqEI)dZ(;q`h%mw zvk7fe|0fm~sWLYNFT)U)x2zWS4@0Pal7m5&L3QWOX9|pZSQzk=CR+rE(zCi2{!Vh= z9D_pBi@?{8FIMCnS)tpkD{Y-dpBHbdRy#=5?xE##x#rlS(ogx>5#5Z74ue6CD%p>f zyGlQ$?7iP}MhH-sKQb2lw4A5KRUld1EF5s$a8>Q;E2D*|^K9<6a>T3%mr>}+C_hnf zRxFVt&_dIH>5nne(z@OwO{-BI;>nR%ci6l>X2^6HF&52x zb}E<&&4|nzRoSkFo6?_C2R2J}GA&Ggk8qQCGP_AuiW|GA%k{g$UhS&swvGXnq(kOQGyP69VguyjE7)VC7b?neAnRYOY|VrLflubFbZwl-#QmeyMKSQ+Z&kJ-i=hsg4HugYC}_Kq z9>>;snV_z^0+y#cK@=e7QM?KH>}zR(YK!LtI7zBeQ`)fiT7CwG3~hbn;hf zW-sK{Mhrt(7zOMstZe#)2m#B~LK9WvpM_Hs+4i=~mUd=gZ5wQA+L+j`of}XY{Bh#N z#}nC7T&Q6L*=8sV8^Va6+t?GW7OL^ZS=m*u8A{TXD=BpLR?uo<>9Nt0Te0AXA7a|! zs%euFW+C)W2vmkTpkWu;O4DqMZbuB#LaGrq2%9XEJv6l#0nIcYd<#r)I_ak72-K1o zQ>RtvhxF`u60sR52w{#T^a?|vq!VcB7~gELPtIK304oIU3abgqZNqZ<3}03{%H^jb z&F7_ZGlcHA_Yw$St3)UW5soTCANfp9?RPMLQlqhJ43nOi)-Y0Kc<#6$qtIF!V-Yg> zby+L^8GF9g)Ur73bXqJvwj)#JI(&UG96hOJmR`bJeTjhd%Q50WGp_Dz?<%_^r9h|4?}?s6#!7KH<^3s3A=Y=tm{xbLo{cO`zU>2 zKoF>>gd}b4>5qZQ8Bv(3z5%8M($NSUb<68$=%qkwCAPiriMMSA%7<}>5x$xXNT6o2@ksSyt=!%US(gdaX)LsT3pN)+t5SSt#|<_@sxX=#VrjV4{A(r0v~|VGDj)WO~jC zjS-AvHrPy6u90r*M~=o3+sQ1(PPXfPGaZAdpCDa)8(nN&ffB4#m^gZ)}uFciu<1@>cMYBmfowTsey7U4F(W*2{DlI=K(LCLG|9C$?#U zQy{@gzcL4LFL)=KM8>)gs{IFQ=S6sfF^{y|jI$P=7KX-)Ud}LwC1!QaYA2&qfhhvz z9a~nRX?gQycvX3*R1S6OYr_t35Y8aiB(P%|Wc{XzZyc>L1BRdM#dF}AM}tJIm~fq! zcxSn+Fil`o*Q*l?a$1|YN3c_yRc7B!-ZRY z22acu#|O#Q!$r(~vc=QEijLux3#Ik02h-bqRDx%2;wo9HWymR*vC3Ss!>kokx1T0N z_ne;TP8HwM?<)9j1Vn`if`Wws!9e}nK>s!mURuXecOX z(CMUXWx>E_s*%zY`BH7pDqP&p^F9n64JXZ|^pLaYVx&koU6Z9lx z!ST$jnQ=#dZu;)p9`eGP9`XuGFO37s_TP^#>T)At$9RTtBZobQ;4n~u!?Gce-V};s z7Z&QY%LroWu6CIl=|bDQ#XbLPQRe%vc`2wI36*+`a4Ist6M+Hfz>qoj+!GKY0&1iU zeJv#%MuaAOA?6H~;P#YzUc|J*>Q3OQvBM$mHtYy51}4E6CSo`k=>m0tf`);tT-!23 zhopI_p_4fF(g>BOoh=u zbRkSJd5{drCYNMsPB;XgE`_G9@->*@b0+ z5CtAabJYNJLPZchh8Zt<4E23S;M8R9x%aXh2M-TdlY3DLTwRSCE)Inm?>pxn1@+7z zubz7%$efp)L4O z+Hgb%%=S($1DF+m+l#GhZNkLqTiodX3~lV<(=8Bzy}2Lgj$T|wU&|ygAzDf&IE0v1 zwqp>_go5f?%Ol+|!z10eTF6a|kTj=T9!pdn)10)D%HNiSnh1lBB5nQ{+tS;NP`xRD14 z;qZUnLek0v=G+0LbzRhLD9-kPT));Xq6v z)2@H@#R+oZ)OAr0B!p~ebOVpcEC5!3-}f<}q$dXZKy-OGq_i^D2eK*mmX4s$_7^^iWx1+%f8sBF%Qfcu zT8!BIhr!LCNCApdY5>3Al_eyGE(P26vKQ`N6})w?BHz4fa%Ru?YaDVTr3+_CPU_Q@ zmDP0<%9<*UdZ_diec<(w7jB24eUHif$GZ0lR#LS68RiC#AZr#UpHTPLoonEXY_Gyf zhZBURAZhzv-f?Io2#AQsD6o6OSEzPAns|BM?)nZNF!vsNN&t6N3To<7+)G=>(icZo z_mpsG3gTLBqUtTu1O^Al%*+rt6&z6gK3(ap+jg z*VvM+JEa8kIm3iYQ_-g+_zh~?IvR_+>VM^yR`(W_V0Jtcxw8+@BENw zFO8MsZoLRdPh?A%KZr`zmRFAivNlOIZsT+uxyN8(XK%xk$o1ouk92wMR_})9N0}+^ zzPr2S$1vU>&j~BbwxguL^pGbBI<`bcf>|z=dvpJRitpxr|0+7@p< zkM~{K`do^;`u5>XSdsdmQ4x36LO5vmjVBHAWVQ z%S*GQVjR;)kdTd+M5rM^Id;~j;o=rjFmUW~@Q<}q!Vryglva^-+_z&l^dGiz_s_NL z7vmlZ>2K4OAc<*_+>n^Eq$U?OBIwMyQlB^(4Kg=tE@8)sI@mMt<3xDW8zAtP3{YSl z*jh0tiC&N+d{06hZWz>!} z+=-v|ocj(}LH=LCoqz{n@88d*&z);9+hN;&C&2Tj{?FdrpBwky=kNQnf443+N>&}) z^go$w3GO^-9`*x{VF3;A8ZY4f+~>`cPb7~!t1@{ajs^S;tU?!ku1UQ8+(HZgfqvAy zWBy{;LNm2sCk8=uh@_GVj)@-OYY?92zW9glJ#POMJVo>Ow>8py_TgZ3rQyY)DJo9F zTd7pOCEw^h&)5D+o&UTe{40CT&vQ13=DBK_`49nF9T)MKpCi6RK|JrVAs*XMyG zuHHGQ@570t%hy*zy%F>n20ew>d>SA4i-*6#tp%@i5ujC=e%Rs4 z4|z}e`B&2YqfDTS>F}BJm6O1s!M6I*BQyPh-|X)to1)~bU#p*j2cteTUHb37xddSd z0L>W@Ob|2_G#m^RECMVnJk0-V&tPI;fjLxR#Y`!%DcM8dI7P+PTvLj0s3cO|ng-{o zxg}N1_S8d*|6fZ7<`d{Q8>%oe4zu=vPJ=i`I2c&&qRFRU9*=1uA{GdmG{oYUnRJfN ziMaeqD$pkwlTDsPF{kE8g6D`9AD%q?m6YN~Fg|(mV-ky6E|psGE3g0{r3Aq{ia8mI z`6D>sLl`0D=M+lG`p?-MP4VVmDx(dMLtJP8(vs2tG8+uQz5NkRxsMSYZS*fpHAyCW zFB*eIiP2~ggG~sI_vtY%iuV!vA7_tXH?W&TDoF|+N(yHYr^O_eMGO|fJAybRkdl%a zqZfH)Oh^|TpF(LVUc!h?`$=yUIRpX72O0NPXY5mBtx81L&~H|Di^*HrAk^KzNDp8? zEqXv|W`KOWPZ2Wi*}s6=zs!u%WATvp`$PXRg~x!2HR$)Y8*$f@A86!a5SM~^m_&IP zgNXo~y0OaM%cLMk%HC5_0#ZrJru@4hK`_QOhyG)XQ!-LEg;mZ?L|Q~<5*!~8Z_!Ce zDH(%Bs}Yb+Zl$?vPA!METL3$mjubxmm5|b666H(AKSdFOYjwsrQUL{|02h;B!7h?X zu(G$Tu&l6@)KUY{DU=bhgJ9$pK(-%a97&-D*cRE~q!1t?89I!RUjUg1C4N=B567)S zsKsO|wE_?U$fko@2qQWLJV=IcD-#NE3r3KX1mpvhZ)_qddn*&-LP?E)aVr^u_0Noy zl=x-w<^%xwl=y&rX->(gf9e5ZBvTDUgyL7FQp*OsX3&d2asW*JlM|du%@J=tCP7X` zPW2o40Fc?`{*z3uP`<0qzg&7zfP+qvUr+uQtV4r1SZ0-Q)_>WL#``qONwrxrZOk^^ zbG!!ZMtmPLXL`g>&k5aHzxu7vO)5WyLzRm2O`+$TKEyePw;e^1HruFq_R)M=I7#y( z>$4*DODCbjyE6PI2{Pt?9LHPAXEUxY5LZ51Xd0!D$@7*k#9mox$}^0;I)8!VFV7o~ zGp81jnRpS3OBG6{lt~qd1k%_oM?((NL9P=fOiNi8~8Aga&n^DQnAtcU7Yc*xrQ3P#rrxMHcZr9aV=FIzom6m`<7(jYRzr@wm4e)gV?TA_OR&X>Hf`V zA-$oio6*CQgkj39*=XUL-ni5aRrUFj`DJa1|Bk|){nwJE>UvdIRlDib8wd}0aSRh^ zxVdSm-c@BU=E)s;GS}I6H}`z1QQB&kQI}pju)nIj1Im)l7^k7euO&sbxW6ZZNG|ad zY38`aI&}2Ey;(ijYO0jdED8S@pY+YveL&*w%90za!zIv2_@nFkGtkmkjDgWfPVgzQ zwru{L>Iz3ouA=VgYiE9&t`)>qu3|&IM!BMl2cQ1?MV(Vdq|xIj^dFi!6(Zr^~nebJQGvtW1I44hlfmPK}cd?yN9BH%*2s+HJ#cRffuQ}=AOOLtbEq1-~F?3FT&h(KMmo-qa{g8!aGp#k*}i_$_tdX z6#_5xIrXtTP6USd;+wZF)`t~5n+T@jwAB-1w|Q{&<#nx<>^O3Rz<+c*(e z`OpMSJ|$=7&Nxycw=%vQECuG&ms0JVuy~T|t&A&ieXR0xao3)-Z*Ip2p3W&7EuBim zX=Q2);qRyIO)|_(Lu8Zks^1;mCL;W|8F3kETOgSR#U6I_ni0jzi-yt5r3duKVLSS< zNK@Jg>qaaaOW^{O^fm2kScPSbDY|9$ESIqhb^2ZLY^GDOWm-nhTmDwp3cq)(ZF&*} z|61(k6|{z@7YO0l4NCjJXtjKb`sUqb;cO+os#woF_3*fbsn_Pnyh?LYAAJVQ^zK>J zEw56(MgMkxw;FZnO0%=2dDcb#+Ddy-!^&G(? zoeQ9&TA$p5blVA8$!2o(oOsm;#v^DOQ+UrgU*#Po9fOBW$4 z-XEtpVslAlg;RU?d(dK?)EzCG!!COgSJ~*o8uQN&FFZZlO$GnD6y}j2T@FO#?YmnzsRaLfR zA$*AK@5FbaR?6M9$g%ghb(U;B%CT=qz2gRZuRT){(qHFXYnCj@yJjTG5GN|ilQ<}7 z?sTNGfh%^^^{~QP^pK|JH$vJEvMz*t-Ko8)_vkA zW24QmU|=a@(=d4obY7d4Ke0*gexVJ zrR&cE8e5@FH=a+vNUFMqZ}?hvGvaApKc`DLdsZ1@pPJ1j_L`2CQJb$P@hsFBs*G77 zT=G}cBCBNKUj=A#&N%u`UG?yEST-2spA)VhNoxM8lp1A0F#0t?elD=1`vIMFK#NY%-umw&Evlc zVuM}m>Qs6)L}Qcw+1;wH>?$(jy4K297x#qk>6!_wj8|-KAEM)U4#qJ2kw2leqVR~l z^4lfKlw~?a4?@Rej8M0R<+i5dC0Q?MAF6L!WW^mRSBKKZMpO9BOZbAPn)`=RX6oJ2 zkIl55M0r~WkqM`DVpH0AQZCH4l-=G|%=+@;^yL`ZS_K&fVoQted+Hp&OQ9hxEUY2h z<5@Q$!>_${W~JM;PNSJ-Hd>p_OL9g-SJuB6g^OOBOTTt2+%rn+)!dn>Zqs;ebsq{@-Wm`mvI zE}`OeWjq)i-ni~qaEWzSwz-{VQZM%HD_cm9NhHTDFa8lOSQzyNCL*0tv;$t?5~LJqq>&+mC_w|F*<*Qz*Zer zgu0ZpAEna!L8PyGkNUecuRM?7lJO!pCI^ErX?$H+L9f4&;hvsDAHYfQf=ToBSpR{> zhONWW;+j-mSN6F@$f?LT#oyLt&q^L^#J;%6NcPt$2Fx$;))|p+CMF85 zL|wQ8EFH(pGqKqf9C>;4CmOF&mG<5L9aHH`1}Y&v=eM@XmA?!5-fvyKb=Nq?TLn-3 zt*o;0>Z(P&i$COA&vbYEPqqGn{S_?ws#v$tB52+=cEW>3Dm!G>jCJkZ%afMkD_+@t zePnD>>=f%;kWuu^bb1y^n%HTzAJcX(Q`ibGIF0GATKrr4s-)E%`V!RnP$t`dEd7b< z%;{a`GO5(DLF+$I8>vBlucdNEluE(dmh&}J!)x_Um43gf=G*j*TE+83+_rj9?#4&^ z9kAT>x0mLmz4tY70B6C$e>ix>$=pmjReM8zV7N;E5{@^oaCx(259iW@^aSsLp@2P`I_ZuV{5;JuTCSm8B6$ zqd*g?6TZ#630X=SeXdMSO4#9v5t5+|_=1VGHt?sVr!T(fB>8iafGKwz%#{xH{BW$j z7Ae2Y68iLo?fNtrb*PkIF_d04<=0P2m}MwB?eKP#z<%9OV1aLo)n?S)f@r3f`AYE= zI~^7teABPl5=^(_GeZJi!qdMb&1xH7<1%04zE>E>-#jthor*u$hTEv6t@lCr39}%UKTU@5Tx`O_rRavAp%mmPN_!n>_)%b7+9!$8g7eI z?QQ_SkJ9@7OJ{gr!T`_V&tOE|@{inmG{jra)Rk40>u0z$wA;0n%k@`V*s9ZnasiW- zTa(>6v~o3k9*|psZX5A+ptBatU^CDCEHTI?{`;d@=D^}&!_blp(04@n|AWH*hlKtA zp)hy~T=xI<4*^ISH0V&=9zm9$D-0?2h=v&<1Qaa_W(miE-^bLE@?6yf=h&hEsFbFP z4G#d)s5%sP)zosS*fnOAVJ1OSL2ro#k5cK_Cz#d)5XcnI7t>mvKI1IAw|@2&q8)y- z9NX%yn(FH6dML~j_E(W^0FOW}1(1#d9gbfKKwJ^A%Kt$przp!nZjlFQ?xhoq?zxw& zx)wtxrd|tI0MIac5tp%MVsMOy`zw+mSQ457lgw1}Yh#B|-^ESe?c?ah^h%~vW4EcB zAuQQ5fSwHbuK{S4g|=n;J9c9yduPOkW7*K23ia!*9A-FEbq+m>s?2vOo*`;4DKC8F z40%iUv@$`YOICcOLk(pxg0_wm?y9B+s%h2z+m0}<7ABdsCFhynua<|rl4dWqo*u(& zZT~lyB!fe9gn`m>8ln2?bJTEA6hg|Q3?<8xRK|8T7j)Rr>c}oQDa%xsY6>+ize_?MPTN1 z4hOy(RU08(Q;~aK)+%@uM}?p~2Z&l--L(fDE#6gCoK$e~@;9j9_$9J(2?gE`RZXwH zc)}`q7F->sF)wSwi)kqKkFX|>x~8Y5p(bDk4LtzVsqYZSh&P`>LenBfi4^gpFKxw8 z$Ab4@v~ zB+Y7Rr3fl+Kd!!Jy0-ub5(Jp1@-nZ#_L}sd_c^e_{qhgm&WcxGL+NE8x!BKFwC~Gn zpF0KoVFYtw3I+z`Yaus$&os%Fwdf=6{kC?Fi#6s@Qd1plWJr!dF)(51805%GyBms`IUd z-8jOj2u2EvtL^H$Uc%@o{TJ$YF@vQ%wTP=5H^B(MQs$<#@c&_6-2#`dR67C$Lzoes ztBTxYDn- z9N=DcIdE2OgQ6-W@*CEiVBCMgr=M&mUS0XBdDbPK5*x@T9*ndH^d$ktK)5$DzGvwy z*9W@!#4&a;Y(U+Fr3Sp1z^&0mn{mbIQ>zwVFH&-o*W?(2xo3k*XQLPQ7$1Knrg zVALD%q0n^+QD5NI>`8htgy+$FB_X{dqX^*_Qe4D_*yBKQY`fRf)`HS_>fIMd!EO=T z(ZUzy1zZNxpnL~kTA^X|0lJiUQ$tTcT7s8;){9{x7xX!<+U?^5Wk_l3y2eTk@{()w zQG})81HynS&G>V`A1c$NFnig$s85o>l2ZOtzs;J9Rm#kG0uobyjXD8XaD~NXYq#f# z`J`{=R+3;od&G4iZpoZr?Mb3Ug3p^LvERun2qe(f+tP6pxhOvN7c#e>I=B5FDDBRF zIB3R)5=mdd+TMS{v7_(I_uEs?Q+o;N^kJlrIATgD_7GQ*r`3#RQ!cjYxMF#;FMw)QTH!r%o3^1VYlg<CLZOdO-ici+ zo4#{)e{;Vi`A^VauwCGShRsHf0#k1xgyCS zsYh7a$}hO!6!|+}(l8kRAk`N`Z7sx7v}`jS?ZA`sGEKX{TY{3mWF$y?`-v$hI|?lZ zd!l9_H^QJO=aWkn2IaZf81=X*fOY;9EGvuJ0F0=tz=f=wLzbJp<_3e}Q28^krZRZ@ zQeU^JLW0*x9B)fvFjVN3+9i4h;7N?AV5&(}&?L>jec(_2%5zO3pNLgP5zolDM~8(d z!3f1{UgeBYQeO@lVb^zHGbv>+hwoQgNGtgfyetDEoO5MRBT&e46H zEUsY3M7T|lA~4cTA%-xv-7APDqJgA^Yi7XM0mq+V5dnXphBYJZn}?*E#!L?k!~EAgSgA_8a!M#LHFC+$C^AwM+aq^ohLywhosT@X@QfKRVm^ z4|D)$jOIWF5r~{I&ozhybL0} zZuu~(G9}V#A320%6zI%k=$A-w;@;Q&ABgPvFU$+sD?4mf$aX4MN2Et9@m=Lz-TB+D zE4{bvclv(H<3X3oY8j+nZ}j`1uW#tq>vE$(r2M#Ht3g1EOcX%#{=s?Bu+SeqK>vgD zfVLMV444BJ14~Sm!W5g*H3W_whl*1?rKm|%Ld`5RbzXgtOHxI{Ev$I&?*Fyd06gzl z0QtlPK>&NUljzVivXfjfUnV7z;Kwiu`@j7Z!!Mqr=ulE5WMX(?$TR`v>47L}%goZ35Q`fcxA&cLx&ag;FtC)H+QjVfT^%8zeLA!^HRTB2+#J``kj|Iw?X@ z0AZabGawI=cn*NxKe9!UWHSGYjv@AeCJsQaLYc`kOd|>AOC(S}B~yg{pCpGt+`}lq zpl-~7(XiyO`C5|k(l26>WYPqtQ9ppl|I-mHh97$AEZ?Combr8SF`zkf2^5}FfJ>3E z?;A`1rw_VTu61&ZVL%WYU!q8Y&q7I0P_P(2VdI5vPe)h66|I0i|BqoC)3=bBXkP-; zJ}V#_Kz$3sFh2st5h(8dDF~MA|L9SKWrZR%iowd}oB3uP3&ekRrId`rqm~8q4*Wp> zjDkM#&m>Zz%z#zMLe51@Be_LPe+lpXLeCC-|B%A|S1ytu5E>9O4iAAMY{r-)VDR)g zY=$gQ{_37^4KMuN9_VFZ6-)t*mF1oC{ zgYhIH?*G~9{|-Rfw=kgaAS4jaICJ!j-JAcJ`AYYdGymA)Ih$%cX_X$edpqJij5cFa1BVmM;3 zn36jG3e-O$k6EUX_z$QjdJKr{)jy{x8s>4@!>G>8x+O-raNSH*2ly3P| zoXNfgo2aHQa$wbJr2;t&G(k%G6-)~C{{`L=A?}5ce9k3{*Glzx8+|5xSyLWfoS2CK zhVAcj1CFdYlOWRQ*%#_DqeBcZ{!a#`@3GwBfPvX`Ro?NEm>kU7KJBy!g2=oOr-OwUFO%Xv~0t zz2EYg#vK;T8K^7#(913M@IhDF>il9$o z49CUb86ThvtZo}ZHv`&!9r%A+{*oBv>FERJ=^gH-4E!m>ja^-u?Co317pas<+E zo;2lrh=_`Mi&uRH^BXo~!hzQiW-qYm9wrQ?h77md3Nwez)zH_|SE14g?ddSX=^kK% z%w7*4!^XhoVW;^=nUgECxh%|VnMOJ*f&0Rx3C9i%A2?S-hZP!LGJ9p?@3_@_`n z$d_ADySN(k5IDn_>+tb1I*#I?;aCrdTNXkQM|FM7atkAaUVQkO)l{DQM)MDteEw2m zLd?JcxsK>p5a=D)?;kEy0>!YSTb=4;$M}L!pvXFOn7tizT*-B+n zt>DX`Cm0D-$o08UbT#HXejULxFG+Q_8_}(zCLDO5BDO5~Iv*c~J0ED+hs5FSkZ!w} zOfbSs9a~Ntg!}-wQpY->KT?0BABORG!ab`uSO;)G&_}_-aeogW(UdaPFg7gx0n%VR z9}S7JgOrB7b@TrKcp&5;^n1^EJi+D@C6$JjOl;VKW~Z%Gwxwkq1j)l>44@q; zf!Ko^h|XD!V{vMv=)MQqVng~SW$76j*C931ec<6UgP6a=%q^OU3gd8UD`Rdahu^2E z)6bG2GDT4zuug;TsN8pmZpp+fluyO#DKyAPi^Z)3Dok?(EFvnYSeG3b17~ zM#M}xabpg_a%^nweEr~@E*9w)?XKGbJj0(m;t5Qn&i-RZnGL57X))ydF9H=ESo+262)n731>z_` zET3zzOlE$ffmzi{sn=1Y>&uTW%n7ml0W$_R$X_5(w0gD$hK4Rthb}kyIsgO2#JGA+ zKo51RjG!W8>PJgg0%cdp!?S!wP~APcg@0O^F=hElWXNwHdOi%!*wumS0jZnEkYNpK z)O<Ue#!Y1dd`3O&SD3%)vk!lNX38n3=j3$vat`DsWsdKPx_3>i)CgabKihLGaJ* zjrwmx_Aw9P$2Gc#1$6fBF=Q*$J{CkaJYMrY7cQH78?ir2#Hv@MgXT37CO~MYBfW{k z<F{8r%~V{WGV z>_o?IMuV$C;-a1;TG`R+BO_$_{|ZLjck6fmFmSuyNlneU*`@^9JV9#Egp{b zCSYqn4jbJx{zh=mUk?UDerO5Aaal;n)IY)wf>PD* z0pU&(Lh09!sB2_V6Cr#!^J4`H=+;RUxIWrUye}Nsz9(KBnt*osyi4JZGrAH``ySIa zHXu3F>~#=6#);e!GGk&6-Xgu&xUJGdZBf%8Z4C;9@4QCu3x3SZnL+9+QL~^gMaJj3 zf~D0*2Uiv1prT2dfj9ZA!NBHa%AI)f3SmD7{Vj^&>%_zw+P$bx!1#^_uZGW$4n?*I zUwLi?}~GlOLd~gYyoX14CVmOnD26=xsIfW=vsUbZw04 zS|;w|*te@~`vEvC8D9s)ynCzB-?)v%kA%4TP&NCS+5of;z31^T(WuY9fIxkKg~jxq zk^JV}u2G+(el5df_aN)PP^rT(Zj7Nyoo=G$WlSibhPKEzC)y3AAe%r92*B7iFk;}i zTD+ME2yx%c7-&uSGZztxtM#4Jvk&>0aB+M(unMOT7u(zU%uL`|7NTUvjI6dduV}1# z`n2i!$Dam%AH!xi&O+pFP*?}V{49}q7+LP7CPY?N1xT<*B?j2*;7c|rdtFYKg6d@e z3$ePL$d2jMO%O@bO+>-O@QI5e{J;XQT7v?DnLO%lCX6b(7*BagzPAC5jEjiiFgn5* z+h}~nQ>cJcR~m>FXiM!X8S;=#MY|SiV+UDJ}bbC&9~F- zF=XHr;=-ylR?rPy;%7$Uh>$J2_wLrKVH&@E69zd z>%PK;%-Ie#zMdl)>H@2+e2*qCABZwJT&O6cd+G!^ar9+QoQb3TMBun*ae>ZEg6&7_ zt@$(Y9N98A#ebYp0MgfhBhVE9H#6{AD3g;Pbid{&36~gaD}F?0)Cj}KmS~&O5XAN* zYaI~WOt{SfW;*FqM`>scYQNGrO3;rHTV9%pdzecOonrTxhS3PxAlZ4?kJ+K13@5a9 z+|&T?6dk4o9VFfOgQMjzrbE;|@`xbVs`?nv<9i2r)GQNlxacb~*J#8an1~O9Hq;0& zLNpVkP@N*!%UI;p%vYzYOTPkiB`Xqqhz{j%!HY!Q%w=^j_7Qq0k#R?312&?)%<4V| zX;mBwQM}?%AsIHR6b)44z9PLRP(Y_c^H-V0W^9D99e=b2fWuTYg7pz5^fiV$C2D@~ zsO}800|9%8Y7*Ykm0)2^HrT>QBE)MxJV3kMKuHjY2!`W!KG2Xpu)|wKBT6vX_k@5W zSU&YN(qqOoHhc+}A>M)U$g2u!nMkq}*4Gu5h^vOl0Ev~mec@BMirc6#Yz(0rv8cZC zwZGvPLP-Ju`dK~9Fi`0q&KPDxUnzucVd~LO+(rXvciI3oFca+b=G?qjb1WbmS9?**F`_Goauwd%59A~4kfnQEl z(-j80_?cOU%}^cpgXR}38Ad9GH{v~>jU!!|?<&p1HUfOL;xbXVtPPlg!mI=yu@hdO z5VHa_-r|HFVI=8ZW06)PwS8d~F_jC^Ui*_9U1)pEKwb4rNHiM30X^m-JKQC&r%BaB zMq}nTdtbD~H^@)WOiIF(pRB~|p|2pAjtw|JLpWtLNPvM+Ly|0?ti(^u1mVx`SKeaW zejf7GOvj<_cqXK|gO@CSQ6Qx{E(9L3))B}TE@0C%_)9UyDI zp?iRIn3qsK(32RBn=zu+x|m_RxaV^^&6!7SW^y(WfP{WXm*_sAX1vIr($6#MKEH82 z#L^x__vd07+8Iz+F$5>H0O(?!NdA1!qey)N@^pq1%WugNxmPplFu?~g%i6gfY5r^a zMH^^-f_szoFz>f2gVs4;G3lcOKC#SlK7;uLPA@hlb;R8uU4c9sjAMA2PRQTFWgDp< zX~nnf;K+T#na7{*GavMs#*O%VpY1b^ZLmM^srZ2Y;in#T_(Xk3AJ%cd;9vKz{LV7A zLH@OzM|_xv*C3fk_xL~GGW3tu;qUwNF#Y_0?w(-$^Xon?I;s}p5CSadWvF4E^xCzY zFX-pt6Y(oTPk(v%fhYASq;SHvOu8 zCDsSS2K$B;IKqB>ioZ)U827Yceju2hkLN+HrlJ zrg5_Y^iepE@&5oJIIsGqaVLDO{AOeQ<9`{O{-b{xm$SF=nGWv9>UoYs(ks?|BB11M z2oEze)srU4@+n?u}~4O@R-k5nuv-BAdwJVs}Hoyr1ZLx?zJ*y)tDc&vwY7jKd~N7GPwW= zm6pqa>_?;84>5TdVT1BAWMHZ+#`w$e6<+pGYx>ko3<73~V{LDR(+LZyx(At!7|MW6J#6PeIM4bow~3bianoLRg9x$1hYhRm_71mYa8QkJgd#}q1wkJQBE2YUHxVn-nKf;a6kQ9WX}9Xgx)$|kY4 z-arOrvU*s5s^fOKkpA(6{{U?fNT6dW-f;YF#wy=4EY57{r`75Ofv%CWd zHcmmV^d}H98tGB~8>9aK_H|@tWfs(Ii>jBSl11%xF@m(98H5&EQdPcUt5F;`MT$K% zbTbYhy+Voe9I@$e7uXoiZ1n#CwjT@pA+Fwo{l4W1r#s|9^*0fj5E{MDfjV=#wqU3> zYO;R9aHAJW;VsZ~HL?4~U7IgeH+pUg8fDrm*rPO-Cnn>aiDy%IeKjI|vUF*o)su z-)V_Z0rHFOFoIaEu-N-WFVxD7HsJZl6|%D7xsVvnzQ6Vk6)TS{Ha&(Eq-M) f8xPqqUfsDh?< Tuple: + return tuple(version.split(".")) + + +def get_installed_version(package: str) -> Optional[str]: + try: + return pkg_resources.get_distribution(package).version + except Exception: + return None + + +def extract_base_package(package_string: str) -> str: + base_package = package_string.split("@git")[0] + return base_package + + +def install_requirements(req_file): + with open(req_file) as file: + for package in file: + try: + package = package.strip() + if "==" in package: + package_name, package_version = package.split("==") + installed_version = get_installed_version(package_name) + if installed_version != package_version: + launch.run_pip( + f"install -U {package}", + f"sd-webui-controlnet requirement: changing {package_name} version from {installed_version} to {package_version}", + ) + elif ">=" in package: + package_name, package_version = package.split(">=") + installed_version = get_installed_version(package_name) + if not installed_version or comparable_version( + installed_version + ) < comparable_version(package_version): + launch.run_pip( + f"install -U {package}", + f"sd-webui-controlnet requirement: changing {package_name} version from {installed_version} to {package_version}", + ) + elif not launch.is_installed(extract_base_package(package)): + launch.run_pip( + f"install {package}", + f"sd-webui-controlnet requirement: {package}", + ) + except Exception as e: + print(e) + print( + f"Warning: Failed to install {package}, some preprocessors may not work." + ) + + +def try_install_from_wheel(pkg_name: str, wheel_url: str): + if get_installed_version(pkg_name) is not None: + return + + try: + launch.run_pip( + f"install {wheel_url}", + f"sd-webui-controlnet requirement: {pkg_name}", + ) + except Exception as e: + print(e) + print(f"Warning: Failed to install {pkg_name}. Some processors will not work.") + + +def try_install_insight_face(): + """Attempt to install insightface library. The library is necessary to use ip-adapter faceid. + Note: Building insightface library from source requires compiling C++ code, which should be avoided + in principle. Here the solution is to download a precompiled wheel.""" + if get_installed_version("insightface") is not None: + return + + default_win_wheel = "https://github.com/Gourieff/Assets/raw/main/Insightface/insightface-0.7.3-cp310-cp310-win_amd64.whl" + wheel_url = os.environ.get("INSIGHTFACE_WHEEL", default_win_wheel) + + system = platform.system().lower() + architecture = platform.machine().lower() + python_version = sys.version_info + if wheel_url != default_win_wheel or ( + system == "windows" + and "amd64" in architecture + and python_version.major == 3 + and python_version.minor == 10 + ): + try: + launch.run_pip( + f"install {wheel_url}", + "sd-webui-controlnet requirement: insightface", + ) + except Exception as e: + print(e) + print( + "ControlNet init warning: Unable to install insightface automatically. " + ) + else: + print( + "ControlNet init warning: Unable to install insightface automatically. " + "Please try run `pip install insightface` manually." + ) + + +def try_remove_legacy_submodule(): + """Try remove annotators/hand_refiner_portable submodule dir.""" + submodule = repo_root / "annotator" / "hand_refiner_portable" + if os.path.exists(submodule): + try: + shutil.rmtree(submodule) + except Exception as e: + print(e) + print( + f"Failed to remove submodule {submodule} automatically. You can manually delete the directory." + ) + + +install_requirements(main_req_file) +try_install_insight_face() +try_install_from_wheel( + "handrefinerportable", + wheel_url=os.environ.get( + "HANDREFINER_WHEEL", + "https://github.com/huchenlei/HandRefinerPortable/releases/download/v1.0.0/handrefinerportable-2024.1.18.0-py2.py3-none-any.whl", + ), +) +try_install_from_wheel( + "depth_anything", + wheel_url=os.environ.get( + "DEPTH_ANYTHING_WHEEL", + "https://github.com/huchenlei/Depth-Anything/releases/download/v1.0.0/depth_anything-2024.1.22.0-py2.py3-none-any.whl", + ), +) +try_remove_legacy_submodule() diff --git a/extensions-builtin/sd_forge_controlnet/internal_controlnet/external_code.py b/extensions-builtin/sd_forge_controlnet/internal_controlnet/external_code.py new file mode 100644 index 00000000..dc280fbb --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/internal_controlnet/external_code.py @@ -0,0 +1,515 @@ +from dataclasses import dataclass +from enum import Enum +from copy import copy +from typing import List, Any, Optional, Union, Tuple, Dict +import numpy as np +from modules import scripts, processing, shared +from scripts import global_state +from scripts.processor import preprocessor_sliders_config, model_free_preprocessors +from scripts.logging import logger +from scripts.enums import HiResFixOption + +from modules.api import api + + +def get_api_version() -> int: + return 2 + + +class ControlMode(Enum): + """ + The improved guess mode. + """ + + BALANCED = "Balanced" + PROMPT = "My prompt is more important" + CONTROL = "ControlNet is more important" + + +class BatchOption(Enum): + DEFAULT = "All ControlNet units for all images in a batch" + SEPARATE = "Each ControlNet unit for each image in a batch" + + +class ResizeMode(Enum): + """ + Resize modes for ControlNet input images. + """ + + RESIZE = "Just Resize" + INNER_FIT = "Crop and Resize" + OUTER_FIT = "Resize and Fill" + + def int_value(self): + if self == ResizeMode.RESIZE: + return 0 + elif self == ResizeMode.INNER_FIT: + return 1 + elif self == ResizeMode.OUTER_FIT: + return 2 + assert False, "NOTREACHED" + + +resize_mode_aliases = { + 'Inner Fit (Scale to Fit)': 'Crop and Resize', + 'Outer Fit (Shrink to Fit)': 'Resize and Fill', + 'Scale to Fit (Inner Fit)': 'Crop and Resize', + 'Envelope (Outer Fit)': 'Resize and Fill', +} + + +def resize_mode_from_value(value: Union[str, int, ResizeMode]) -> ResizeMode: + if isinstance(value, str): + return ResizeMode(resize_mode_aliases.get(value, value)) + elif isinstance(value, int): + assert value >= 0 + if value == 3: # 'Just Resize (Latent upscale)' + return ResizeMode.RESIZE + + if value >= len(ResizeMode): + logger.warning(f'Unrecognized ResizeMode int value {value}. Fall back to RESIZE.') + return ResizeMode.RESIZE + + return [e for e in ResizeMode][value] + else: + return value + + +def control_mode_from_value(value: Union[str, int, ControlMode]) -> ControlMode: + if isinstance(value, str): + return ControlMode(value) + elif isinstance(value, int): + return [e for e in ControlMode][value] + else: + return value + + +def visualize_inpaint_mask(img): + if img.ndim == 3 and img.shape[2] == 4: + result = img.copy() + mask = result[:, :, 3] + mask = 255 - mask // 2 + result[:, :, 3] = mask + return np.ascontiguousarray(result.copy()) + return img + + +def pixel_perfect_resolution( + image: np.ndarray, + target_H: int, + target_W: int, + resize_mode: ResizeMode, +) -> int: + """ + Calculate the estimated resolution for resizing an image while preserving aspect ratio. + + The function first calculates scaling factors for height and width of the image based on the target + height and width. Then, based on the chosen resize mode, it either takes the smaller or the larger + scaling factor to estimate the new resolution. + + If the resize mode is OUTER_FIT, the function uses the smaller scaling factor, ensuring the whole image + fits within the target dimensions, potentially leaving some empty space. + + If the resize mode is not OUTER_FIT, the function uses the larger scaling factor, ensuring the target + dimensions are fully filled, potentially cropping the image. + + After calculating the estimated resolution, the function prints some debugging information. + + Args: + image (np.ndarray): A 3D numpy array representing an image. The dimensions represent [height, width, channels]. + target_H (int): The target height for the image. + target_W (int): The target width for the image. + resize_mode (ResizeMode): The mode for resizing. + + Returns: + int: The estimated resolution after resizing. + """ + raw_H, raw_W, _ = image.shape + + k0 = float(target_H) / float(raw_H) + k1 = float(target_W) / float(raw_W) + + if resize_mode == ResizeMode.OUTER_FIT: + estimation = min(k0, k1) * float(min(raw_H, raw_W)) + else: + estimation = max(k0, k1) * float(min(raw_H, raw_W)) + + logger.debug(f"Pixel Perfect Computation:") + logger.debug(f"resize_mode = {resize_mode}") + logger.debug(f"raw_H = {raw_H}") + logger.debug(f"raw_W = {raw_W}") + logger.debug(f"target_H = {target_H}") + logger.debug(f"target_W = {target_W}") + logger.debug(f"estimation = {estimation}") + + return int(np.round(estimation)) + + +InputImage = Union[np.ndarray, str] +InputImage = Union[Dict[str, InputImage], Tuple[InputImage, InputImage], InputImage] + + +@dataclass +class ControlNetUnit: + """ + Represents an entire ControlNet processing unit. + """ + enabled: bool = True + module: str = "none" + model: str = "None" + weight: float = 1.0 + image: Optional[Union[InputImage, List[InputImage]]] = None + resize_mode: Union[ResizeMode, int, str] = ResizeMode.INNER_FIT + low_vram: bool = False + processor_res: int = -1 + threshold_a: float = -1 + threshold_b: float = -1 + guidance_start: float = 0.0 + guidance_end: float = 1.0 + pixel_perfect: bool = False + control_mode: Union[ControlMode, int, str] = ControlMode.BALANCED + # Whether to crop input image based on A1111 img2img mask. This flag is only used when `inpaint area` + # in A1111 is set to `Only masked`. In API, this correspond to `inpaint_full_res = True`. + inpaint_crop_input_image: bool = True + # If hires fix is enabled in A1111, how should this ControlNet unit be applied. + # The value is ignored if the generation is not using hires fix. + hr_option: Union[HiResFixOption, int, str] = HiResFixOption.BOTH + + # Whether save the detected map of this unit. Setting this option to False prevents saving the + # detected map or sending detected map along with generated images via API. + # Currently the option is only accessible in API calls. + save_detected_map: bool = True + + # Weight for each layer of ControlNet params. + # For ControlNet: + # - SD1.5: 13 weights (4 encoder block * 3 + 1 middle block) + # - SDXL: 10 weights (3 encoder block * 3 + 1 middle block) + # For T2IAdapter + # - SD1.5: 5 weights (4 encoder block + 1 middle block) + # - SDXL: 4 weights (3 encoder block + 1 middle block) + # Note1: Setting advanced weighting will disable `soft_injection`, i.e. + # It is recommended to set ControlMode = BALANCED when using `advanced_weighting`. + # Note2: The field `weight` is still used in some places, e.g. reference_only, + # even advanced_weighting is set. + advanced_weighting: Optional[List[float]] = None + + def __eq__(self, other): + if not isinstance(other, ControlNetUnit): + return False + + return vars(self) == vars(other) + + def accepts_multiple_inputs(self) -> bool: + """This unit can accept multiple input images.""" + return False + + +def to_base64_nparray(encoding: str): + """ + Convert a base64 image into the image type the extension uses + """ + + return np.array(api.decode_base64_to_image(encoding)).astype('uint8') + + +def get_all_units_in_processing(p: processing.StableDiffusionProcessing) -> List[ControlNetUnit]: + """ + Fetch ControlNet processing units from a StableDiffusionProcessing. + """ + + return get_all_units(p.scripts, p.script_args) + + +def get_all_units(script_runner: scripts.ScriptRunner, script_args: List[Any]) -> List[ControlNetUnit]: + """ + Fetch ControlNet processing units from an existing script runner. + Use this function to fetch units from the list of all scripts arguments. + """ + + cn_script = find_cn_script(script_runner) + if cn_script: + return get_all_units_from(script_args[cn_script.args_from:cn_script.args_to]) + + return [] + + +def get_all_units_from(script_args: List[Any]) -> List[ControlNetUnit]: + """ + Fetch ControlNet processing units from ControlNet script arguments. + Use `external_code.get_all_units` to fetch units from the list of all scripts arguments. + """ + + def is_stale_unit(script_arg: Any) -> bool: + """ Returns whether the script_arg is potentially an stale version of + ControlNetUnit created before module reload.""" + return ( + 'ControlNetUnit' in type(script_arg).__name__ and + not isinstance(script_arg, ControlNetUnit) + ) + + def is_controlnet_unit(script_arg: Any) -> bool: + """ Returns whether the script_arg is ControlNetUnit or anything that + can be treated like ControlNetUnit. """ + return ( + isinstance(script_arg, (ControlNetUnit, dict)) or + ( + hasattr(script_arg, '__dict__') and + set(vars(ControlNetUnit()).keys()).issubset( + set(vars(script_arg).keys())) + ) + ) + + all_units = [ + to_processing_unit(script_arg) + for script_arg in script_args + if is_controlnet_unit(script_arg) + ] + if not all_units: + logger.warning( + "No ControlNetUnit detected in args. It is very likely that you are having an extension conflict." + f"Here are args received by ControlNet: {script_args}.") + if any(is_stale_unit(script_arg) for script_arg in script_args): + logger.debug( + "Stale version of ControlNetUnit detected. The ControlNetUnit received" + "by ControlNet is created before the newest load of ControlNet extension." + "They will still be used by ControlNet as long as they provide same fields" + "defined in the newest version of ControlNetUnit." + ) + + return all_units + + +def get_single_unit_from(script_args: List[Any], index: int = 0) -> Optional[ControlNetUnit]: + """ + Fetch a single ControlNet processing unit from ControlNet script arguments. + The list must not contain script positional arguments. It must only contain processing units. + """ + + i = 0 + while i < len(script_args) and index >= 0: + if index == 0 and script_args[i] is not None: + return to_processing_unit(script_args[i]) + i += 1 + + index -= 1 + + return None + + +def get_max_models_num(): + """ + Fetch the maximum number of allowed ControlNet models. + """ + + max_models_num = shared.opts.data.get("control_net_unit_count", 3) + return max_models_num + + +def to_processing_unit(unit: Union[Dict[str, Any], ControlNetUnit]) -> ControlNetUnit: + """ + Convert different types to processing unit. + If `unit` is a dict, alternative keys are supported. See `ext_compat_keys` in implementation for details. + """ + + ext_compat_keys = { + 'guessmode': 'guess_mode', + 'guidance': 'guidance_end', + 'lowvram': 'low_vram', + 'input_image': 'image' + } + + if isinstance(unit, dict): + unit = {ext_compat_keys.get(k, k): v for k, v in unit.items()} + + mask = None + if 'mask' in unit: + mask = unit['mask'] + del unit['mask'] + + if 'image' in unit and not isinstance(unit['image'], dict): + unit['image'] = {'image': unit['image'], 'mask': mask} if mask is not None else unit['image'] if unit[ + 'image'] else None + + if 'guess_mode' in unit: + logger.warning('Guess Mode is removed since 1.1.136. Please use Control Mode instead.') + + unit = ControlNetUnit(**{k: v for k, v in unit.items() if k in vars(ControlNetUnit).keys()}) + + # temporary, check #602 + # assert isinstance(unit, ControlNetUnit), f'bad argument to controlnet extension: {unit}\nexpected Union[dict[str, Any], ControlNetUnit]' + return unit + + +def update_cn_script_in_processing( + p: processing.StableDiffusionProcessing, + cn_units: List[ControlNetUnit], + **_kwargs, # for backwards compatibility +): + """ + Update the arguments of the ControlNet script in `p.script_args` in place, reading from `cn_units`. + `cn_units` and its elements are not modified. You can call this function repeatedly, as many times as you want. + + Does not update `p.script_args` if any of the folling is true: + - ControlNet is not present in `p.scripts` + - `p.script_args` is not filled with script arguments for scripts that are processed before ControlNet + """ + p.script_args = update_cn_script(p.scripts, p.script_args_value, cn_units) + + +def update_cn_script( + script_runner: scripts.ScriptRunner, + script_args: Union[Tuple[Any], List[Any]], + cn_units: List[ControlNetUnit], +) -> Union[Tuple[Any], List[Any]]: + """ + Returns: The updated `script_args` with given `cn_units` used as ControlNet + script args. + + Does not update `script_args` if any of the folling is true: + - ControlNet is not present in `script_runner` + - `script_args` is not filled with script arguments for scripts that are + processed before ControlNet + """ + script_args_type = type(script_args) + assert script_args_type in (tuple, list), script_args_type + updated_script_args = list(copy(script_args)) + + cn_script = find_cn_script(script_runner) + + if cn_script is None or len(script_args) < cn_script.args_from: + return script_args + + # fill in remaining parameters to satisfy max models, just in case script needs it. + max_models = shared.opts.data.get("control_net_unit_count", 3) + cn_units = cn_units + [ControlNetUnit(enabled=False)] * max(max_models - len(cn_units), 0) + + cn_script_args_diff = 0 + for script in script_runner.alwayson_scripts: + if script is cn_script: + cn_script_args_diff = len(cn_units) - (cn_script.args_to - cn_script.args_from) + updated_script_args[script.args_from:script.args_to] = cn_units + script.args_to = script.args_from + len(cn_units) + else: + script.args_from += cn_script_args_diff + script.args_to += cn_script_args_diff + + return script_args_type(updated_script_args) + + +def update_cn_script_in_place( + script_runner: scripts.ScriptRunner, + script_args: List[Any], + cn_units: List[ControlNetUnit], + **_kwargs, # for backwards compatibility +): + """ + @Deprecated(Raises assertion error if script_args passed in is Tuple) + + Update the arguments of the ControlNet script in `script_args` in place, reading from `cn_units`. + `cn_units` and its elements are not modified. You can call this function repeatedly, as many times as you want. + + Does not update `script_args` if any of the folling is true: + - ControlNet is not present in `script_runner` + - `script_args` is not filled with script arguments for scripts that are processed before ControlNet + """ + assert isinstance(script_args, list), type(script_args) + + cn_script = find_cn_script(script_runner) + if cn_script is None or len(script_args) < cn_script.args_from: + return + + # fill in remaining parameters to satisfy max models, just in case script needs it. + max_models = shared.opts.data.get("control_net_unit_count", 3) + cn_units = cn_units + [ControlNetUnit(enabled=False)] * max(max_models - len(cn_units), 0) + + cn_script_args_diff = 0 + for script in script_runner.alwayson_scripts: + if script is cn_script: + cn_script_args_diff = len(cn_units) - (cn_script.args_to - cn_script.args_from) + script_args[script.args_from:script.args_to] = cn_units + script.args_to = script.args_from + len(cn_units) + else: + script.args_from += cn_script_args_diff + script.args_to += cn_script_args_diff + + +def get_models(update: bool = False) -> List[str]: + """ + Fetch the list of available models. + Each value is a valid candidate of `ControlNetUnit.model`. + + Keyword arguments: + update -- Whether to refresh the list from disk. (default False) + """ + + if update: + global_state.update_cn_models() + + return list(global_state.cn_models_names.values()) + + +def get_modules(alias_names: bool = False) -> List[str]: + """ + Fetch the list of available preprocessors. + Each value is a valid candidate of `ControlNetUnit.module`. + + Keyword arguments: + alias_names -- Whether to get the ui alias names instead of internal keys + """ + + modules = list(global_state.cn_preprocessor_modules.keys()) + + if alias_names: + modules = [global_state.preprocessor_aliases.get(module, module) for module in modules] + + return modules + + +def get_modules_detail(alias_names: bool = False) -> Dict[str, Any]: + """ + get the detail of all preprocessors including + sliders: the slider config in Auto1111 webUI + + Keyword arguments: + alias_names -- Whether to get the module detail with alias names instead of internal keys + """ + + _module_detail = {} + _module_list = get_modules(False) + _module_list_alias = get_modules(True) + + _output_list = _module_list if not alias_names else _module_list_alias + for index, module in enumerate(_output_list): + if _module_list[index] in preprocessor_sliders_config: + _module_detail[module] = { + "model_free": module in model_free_preprocessors, + "sliders": preprocessor_sliders_config[_module_list[index]] + } + else: + _module_detail[module] = { + "model_free": False, + "sliders": [] + } + + return _module_detail + + +def find_cn_script(script_runner: scripts.ScriptRunner) -> Optional[scripts.Script]: + """ + Find the ControlNet script in `script_runner`. Returns `None` if `script_runner` does not contain a ControlNet script. + """ + + if script_runner is None: + return None + + for script in script_runner.alwayson_scripts: + if is_cn_script(script): + return script + + +def is_cn_script(script: scripts.Script) -> bool: + """ + Determine whether `script` is a ControlNet script. + """ + + return script.title().lower() == 'controlnet' diff --git a/extensions-builtin/sd_forge_controlnet/javascript/active_units.js b/extensions-builtin/sd_forge_controlnet/javascript/active_units.js new file mode 100644 index 00000000..a2662055 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/javascript/active_units.js @@ -0,0 +1,311 @@ +/** + * Give a badge on ControlNet Accordion indicating total number of active + * units. + * Make active unit's tab name green. + * Append control type to tab name. + * Disable resize mode selection when A1111 img2img input is used. + */ +(function () { + const cnetAllAccordions = new Set(); + onUiUpdate(() => { + const ImgChangeType = { + NO_CHANGE: 0, + REMOVE: 1, + ADD: 2, + SRC_CHANGE: 3, + }; + + function imgChangeObserved(mutationsList) { + // Iterate over all mutations that just occured + for (let mutation of mutationsList) { + // Check if the mutation is an addition or removal of a node + if (mutation.type === 'childList') { + // Check if nodes were added + if (mutation.addedNodes.length > 0) { + for (const node of mutation.addedNodes) { + if (node.tagName === 'IMG') { + return ImgChangeType.ADD; + } + } + } + + // Check if nodes were removed + if (mutation.removedNodes.length > 0) { + for (const node of mutation.removedNodes) { + if (node.tagName === 'IMG') { + return ImgChangeType.REMOVE; + } + } + } + } + // Check if the mutation is a change of an attribute + else if (mutation.type === 'attributes') { + if (mutation.target.tagName === 'IMG' && mutation.attributeName === 'src') { + return ImgChangeType.SRC_CHANGE; + } + } + } + return ImgChangeType.NO_CHANGE; + } + + function childIndex(element) { + // Get all child nodes of the parent + let children = Array.from(element.parentNode.childNodes); + + // Filter out non-element nodes (like text nodes and comments) + children = children.filter(child => child.nodeType === Node.ELEMENT_NODE); + + return children.indexOf(element); + } + + function imageInputDisabledAlert() { + alert('Inpaint control type must use a1111 input in img2img mode.'); + } + + class ControlNetUnitTab { + constructor(tab, accordion) { + this.tab = tab; + this.accordion = accordion; + this.isImg2Img = tab.querySelector('.cnet-unit-enabled').id.includes('img2img'); + + this.enabledCheckbox = tab.querySelector('.cnet-unit-enabled input'); + this.inputImage = tab.querySelector('.cnet-input-image-group .cnet-image input[type="file"]'); + this.inputImageContainer = tab.querySelector('.cnet-input-image-group .cnet-image'); + this.controlTypeRadios = tab.querySelectorAll('.controlnet_control_type_filter_group input[type="radio"]'); + this.resizeModeRadios = tab.querySelectorAll('.controlnet_resize_mode_radio input[type="radio"]'); + this.runPreprocessorButton = tab.querySelector('.cnet-run-preprocessor'); + + const tabs = tab.parentNode; + this.tabNav = tabs.querySelector('.tab-nav'); + this.tabIndex = childIndex(tab) - 1; // -1 because tab-nav is also at the same level. + + this.attachEnabledButtonListener(); + this.attachControlTypeRadioListener(); + this.attachTabNavChangeObserver(); + this.attachImageUploadListener(); + this.attachImageStateChangeObserver(); + this.attachA1111SendInfoObserver(); + this.attachPresetDropdownObserver(); + } + + getTabNavButton() { + return this.tabNav.querySelector(`:nth-child(${this.tabIndex + 1})`); + } + + getActiveControlType() { + for (let radio of this.controlTypeRadios) { + if (radio.checked) { + return radio.value; + } + } + return undefined; + } + + updateActiveState() { + const tabNavButton = this.getTabNavButton(); + if (!tabNavButton) return; + + if (this.enabledCheckbox.checked) { + tabNavButton.classList.add('cnet-unit-active'); + } else { + tabNavButton.classList.remove('cnet-unit-active'); + } + } + + updateActiveUnitCount() { + function getActiveUnitCount(checkboxes) { + let activeUnitCount = 0; + for (const checkbox of checkboxes) { + if (checkbox.checked) + activeUnitCount++; + } + return activeUnitCount; + } + + const checkboxes = this.accordion.querySelectorAll('.cnet-unit-enabled input'); + const span = this.accordion.querySelector('.label-wrap span'); + + // Remove existing badge. + if (span.childNodes.length !== 1) { + span.removeChild(span.lastChild); + } + // Add new badge if necessary. + const activeUnitCount = getActiveUnitCount(checkboxes); + if (activeUnitCount > 0) { + const div = document.createElement('div'); + div.classList.add('cnet-badge'); + div.classList.add('primary'); + div.innerHTML = `${activeUnitCount} unit${activeUnitCount > 1 ? 's' : ''}`; + span.appendChild(div); + } + } + + /** + * Add the active control type to tab displayed text. + */ + updateActiveControlType() { + const tabNavButton = this.getTabNavButton(); + if (!tabNavButton) return; + + // Remove the control if exists + const controlTypeSuffix = tabNavButton.querySelector('.control-type-suffix'); + if (controlTypeSuffix) controlTypeSuffix.remove(); + + // Add new suffix. + const controlType = this.getActiveControlType(); + if (controlType === 'All') return; + + const span = document.createElement('span'); + span.innerHTML = `[${controlType}]`; + span.classList.add('control-type-suffix'); + tabNavButton.appendChild(span); + } + + /** + * When 'Inpaint' control type is selected in img2img: + * - Make image input disabled + * - Clear existing image input + */ + updateImageInputState() { + if (!this.isImg2Img) return; + + const tabNavButton = this.getTabNavButton(); + if (!tabNavButton) return; + + const controlType = this.getActiveControlType(); + if (controlType.toLowerCase() === 'inpaint') { + this.inputImage.disabled = true; + this.inputImage.parentNode.addEventListener('click', imageInputDisabledAlert); + const removeButton = this.tab.querySelector( + '.cnet-input-image-group .cnet-image button[aria-label="Remove Image"]'); + if (removeButton) removeButton.click(); + } else { + this.inputImage.disabled = false; + this.inputImage.parentNode.removeEventListener('click', imageInputDisabledAlert); + } + } + + attachEnabledButtonListener() { + this.enabledCheckbox.addEventListener('change', () => { + this.updateActiveState(); + this.updateActiveUnitCount(); + }); + } + + attachControlTypeRadioListener() { + for (const radio of this.controlTypeRadios) { + radio.addEventListener('change', () => { + this.updateActiveControlType(); + }); + } + } + + /** + * Each time the active tab change, all tab nav buttons are cleared and + * regenerated by gradio. So we need to reapply the active states on + * them. + */ + attachTabNavChangeObserver() { + new MutationObserver((mutationsList) => { + for (const mutation of mutationsList) { + if (mutation.type === 'childList') { + this.updateActiveState(); + this.updateActiveControlType(); + } + } + }).observe(this.tabNav, { childList: true }); + } + + attachImageUploadListener() { + // Automatically check `enable` checkbox when image is uploaded. + this.inputImage.addEventListener('change', (event) => { + if (!event.target.files) return; + if (!this.enabledCheckbox.checked) + this.enabledCheckbox.click(); + }); + + // Automatically check `enable` checkbox when JSON pose file is uploaded. + this.tab.querySelector('.cnet-upload-pose input').addEventListener('change', (event) => { + if (!event.target.files) return; + if (!this.enabledCheckbox.checked) + this.enabledCheckbox.click(); + }); + } + + attachImageStateChangeObserver() { + new MutationObserver((mutationsList) => { + const changeObserved = imgChangeObserved(mutationsList); + + if (changeObserved === ImgChangeType.ADD) { + // enabling the run preprocessor button + this.runPreprocessorButton.removeAttribute("disabled"); + this.runPreprocessorButton.title = 'Run preprocessor'; + } + + if (changeObserved === ImgChangeType.REMOVE) { + // disabling the run preprocessor button + this.runPreprocessorButton.setAttribute("disabled", true); + this.runPreprocessorButton.title = "No ControlNet input image available"; + } + }).observe(this.inputImageContainer, { + childList: true, + subtree: true, + }); + } + + /** + * Observe send PNG info buttons in A1111, as they can also directly + * set states of ControlNetUnit. + */ + attachA1111SendInfoObserver() { + const pasteButtons = gradioApp().querySelectorAll('#paste'); + const pngButtons = gradioApp().querySelectorAll( + this.isImg2Img ? + '#img2img_tab, #inpaint_tab' : + '#txt2img_tab' + ); + + for (const button of [...pasteButtons, ...pngButtons]) { + button.addEventListener('click', () => { + // The paste/send img generation info feature goes + // though gradio, which is pretty slow. Ideally we should + // observe the event when gradio has done the job, but + // that is not an easy task. + // Here we just do a 2 second delay until the refresh. + setTimeout(() => { + this.updateActiveState(); + this.updateActiveUnitCount(); + }, 2000); + }); + } + } + + attachPresetDropdownObserver() { + const presetDropDown = this.tab.querySelector('.cnet-preset-dropdown'); + + new MutationObserver((mutationsList) => { + for (const mutation of mutationsList) { + if (mutation.removedNodes.length > 0) { + setTimeout(() => { + this.updateActiveState(); + this.updateActiveUnitCount(); + this.updateActiveControlType(); + }, 1000); + return; + } + } + }).observe(presetDropDown, { + childList: true, + subtree: true, + }); + } + } + + gradioApp().querySelectorAll('#controlnet').forEach(accordion => { + if (cnetAllAccordions.has(accordion)) return; + accordion.querySelectorAll('.cnet-unit-tab') + .forEach(tab => new ControlNetUnitTab(tab, accordion)); + cnetAllAccordions.add(accordion); + }); + }); +})(); \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/javascript/canvas.js b/extensions-builtin/sd_forge_controlnet/javascript/canvas.js new file mode 100644 index 00000000..a122c9fa --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/javascript/canvas.js @@ -0,0 +1,17 @@ +(function () { + var hasApplied = false; + onUiUpdate(function () { + if (!hasApplied) { + if (typeof window.applyZoomAndPanIntegration === "function") { + hasApplied = true; + window.applyZoomAndPanIntegration("#txt2img_controlnet", Array.from({ length: 20 }, (_, i) => `#txt2img_controlnet_ControlNet-${i}_input_image`)); + window.applyZoomAndPanIntegration("#img2img_controlnet", Array.from({ length: 20 }, (_, i) => `#img2img_controlnet_ControlNet-${i}_input_image`)); + window.applyZoomAndPanIntegration("#txt2img_controlnet", ["#txt2img_controlnet_ControlNet_input_image"]); + window.applyZoomAndPanIntegration("#img2img_controlnet", ["#img2img_controlnet_ControlNet_input_image"]); + //console.log("window.applyZoomAndPanIntegration applied."); + } else { + //console.log("window.applyZoomAndPanIntegration is not available."); + } + } + }); +})(); diff --git a/extensions-builtin/sd_forge_controlnet/javascript/modal.js b/extensions-builtin/sd_forge_controlnet/javascript/modal.js new file mode 100644 index 00000000..dc6190de --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/javascript/modal.js @@ -0,0 +1,33 @@ +(function () { + const cnetModalRegisteredElements = new Set(); + onUiUpdate(() => { + // Get all the buttons that open a modal + const btns = gradioApp().querySelectorAll(".cnet-modal-open"); + + // Get all the elements that close a modal + const spans = document.querySelectorAll(".cnet-modal-close"); + + // For each button, add a click event listener that opens the corresponding modal + btns.forEach((btn) => { + if (cnetModalRegisteredElements.has(btn)) return; + cnetModalRegisteredElements.add(btn); + + const modalId = btn.id.replace('cnet-modal-open-', ''); + const modal = document.getElementById("cnet-modal-" + modalId); + btn.addEventListener('click', () => { + modal.style.display = "block"; + }); + }); + + // For each element, add a click event listener that closes the corresponding modal + spans.forEach((span) => { + if (cnetModalRegisteredElements.has(span)) return; + cnetModalRegisteredElements.add(span); + + const modal = span.parentNode; + span.addEventListener('click', () => { + modal.style.display = "none"; + }); + }); + }); +})(); diff --git a/extensions-builtin/sd_forge_controlnet/javascript/openpose_editor.js b/extensions-builtin/sd_forge_controlnet/javascript/openpose_editor.js new file mode 100644 index 00000000..1c7b570a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/javascript/openpose_editor.js @@ -0,0 +1,152 @@ +(function () { + async function checkEditorAvailable() { + const LOCAL_EDITOR_PATH = '/openpose_editor_index'; + const REMOTE_EDITOR_PATH = 'https://huchenlei.github.io/sd-webui-openpose-editor/'; + + async function testEditorPath(path) { + const res = await fetch(path); + return res.status === 200 ? path : null; + } + + // Use local editor if the user has the extension installed. Fallback + // onto remote editor if the local editor is not ready yet. + // See https://github.com/huchenlei/sd-webui-openpose-editor/issues/53 + // for more details. + return await testEditorPath(LOCAL_EDITOR_PATH) || await testEditorPath(REMOTE_EDITOR_PATH); + } + + const cnetOpenposeEditorRegisteredElements = new Set(); + let editorURL = null; + function loadOpenposeEditor() { + // Simulate an `input` DOM event for Gradio Textbox component. Needed after you edit its contents in javascript, otherwise your edits + // will only visible on web page and not sent to python. + function updateInput(target) { + let e = new Event("input", { bubbles: true }) + Object.defineProperty(e, "target", { value: target }) + target.dispatchEvent(e); + } + + function navigateIframe(iframe, editorURL) { + function getPathname(rawURL) { + try { + return new URL(rawURL).pathname; + } catch (e) { + return rawURL; + } + } + + return new Promise((resolve) => { + const darkThemeParam = document.body.classList.contains('dark') ? + new URLSearchParams({ theme: 'dark' }).toString() : + ''; + + window.addEventListener('message', (event) => { + const message = event.data; + if (message['ready']) resolve(); + }, { once: true }); + + if ((editorURL.startsWith("http") ? iframe.src : getPathname(iframe.src)) !== editorURL) { + iframe.src = `${editorURL}?${darkThemeParam}`; + // By default assume 5 second is enough for the openpose editor + // to load. + setTimeout(resolve, 5000); + } else { + // If no navigation is required, immediately return. + resolve(); + } + }); + } + const tabs = gradioApp().querySelectorAll('.cnet-unit-tab'); + tabs.forEach(tab => { + if (cnetOpenposeEditorRegisteredElements.has(tab)) return; + cnetOpenposeEditorRegisteredElements.add(tab); + + const generatedImageGroup = tab.querySelector('.cnet-generated-image-group'); + const editButton = generatedImageGroup.querySelector('.cnet-edit-pose'); + + editButton.addEventListener('click', async () => { + const inputImageGroup = tab.querySelector('.cnet-input-image-group'); + const inputImage = inputImageGroup.querySelector('.cnet-image img'); + const downloadLink = generatedImageGroup.querySelector('.cnet-download-pose a'); + const modalId = editButton.id.replace('cnet-modal-open-', ''); + const modalIframe = generatedImageGroup.querySelector('.cnet-modal iframe'); + + if (!editorURL) { + editorURL = await checkEditorAvailable(); + if (!editorURL) { + alert("No openpose editor available.") + } + } + + await navigateIframe(modalIframe, editorURL); + modalIframe.contentWindow.postMessage({ + modalId, + imageURL: inputImage ? inputImage.src : undefined, + poseURL: downloadLink.href, + }, '*'); + // Focus the iframe so that the focus is no longer on the `Edit` button. + // Pressing space when the focus is on `Edit` button will trigger + // the click again to resend the frame message. + modalIframe.contentWindow.focus(); + }); + /* + * Writes the pose data URL to an link element on input image group. + * Click a hidden button to trigger a backend rendering of the pose JSON. + * + * The backend should: + * - Set the rendered pose image as preprocessor generated image. + */ + function updatePreviewPose(poseURL) { + const downloadLink = generatedImageGroup.querySelector('.cnet-download-pose a'); + const renderButton = generatedImageGroup.querySelector('.cnet-render-pose'); + const poseTextbox = generatedImageGroup.querySelector('.cnet-pose-json textarea'); + const allowPreviewCheckbox = tab.querySelector('.cnet-allow-preview input'); + + if (!allowPreviewCheckbox.checked) + allowPreviewCheckbox.click(); + + // Only set href when download link exists and needs an update. `downloadLink` + // can be null when user closes preview and click `Upload JSON` button again. + // https://github.com/Mikubill/sd-webui-controlnet/issues/2308 + if (downloadLink !== null) + downloadLink.href = poseURL; + + poseTextbox.value = poseURL; + updateInput(poseTextbox); + renderButton.click(); + } + + // Updates preview image when edit is done. + window.addEventListener('message', (event) => { + const message = event.data; + const modalId = editButton.id.replace('cnet-modal-open-', ''); + if (message.modalId !== modalId) return; + updatePreviewPose(message.poseURL); + + const closeModalButton = generatedImageGroup.querySelector('.cnet-modal .cnet-modal-close'); + closeModalButton.click(); + }); + + const inputImageGroup = tab.querySelector('.cnet-input-image-group'); + const uploadButton = inputImageGroup.querySelector('.cnet-upload-pose input'); + // Updates preview image when JSON file is uploaded. + uploadButton.addEventListener('change', (event) => { + const file = event.target.files[0]; + if (!file) + return; + + const reader = new FileReader(); + reader.onload = function (e) { + const contents = e.target.result; + const poseURL = `data:application/json;base64,${btoa(contents)}`; + updatePreviewPose(poseURL); + }; + reader.readAsText(file); + // Reset the file input value so that uploading the same file still triggers callback. + event.target.value = ''; + }); + }); + } + + onUiUpdate(loadOpenposeEditor); +})(); \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/javascript/photopea.js b/extensions-builtin/sd_forge_controlnet/javascript/photopea.js new file mode 100644 index 00000000..d2b1ebc9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/javascript/photopea.js @@ -0,0 +1,435 @@ +(function () { + /* + MIT LICENSE + Copyright 2011 Jon Leighton + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + // From: https://gist.github.com/jonleighton/958841 + function base64ArrayBuffer(arrayBuffer) { + var base64 = '' + var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' + + var bytes = new Uint8Array(arrayBuffer) + var byteLength = bytes.byteLength + var byteRemainder = byteLength % 3 + var mainLength = byteLength - byteRemainder + + var a, b, c, d + var chunk + + // Main loop deals with bytes in chunks of 3 + for (var i = 0; i < mainLength; i = i + 3) { + // Combine the three bytes into a single integer + chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2] + + // Use bitmasks to extract 6-bit segments from the triplet + a = (chunk & 16515072) >> 18 // 16515072 = (2^6 - 1) << 18 + b = (chunk & 258048) >> 12 // 258048 = (2^6 - 1) << 12 + c = (chunk & 4032) >> 6 // 4032 = (2^6 - 1) << 6 + d = chunk & 63 // 63 = 2^6 - 1 + + // Convert the raw binary segments to the appropriate ASCII encoding + base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d] + } + + // Deal with the remaining bytes and padding + if (byteRemainder == 1) { + chunk = bytes[mainLength] + + a = (chunk & 252) >> 2 // 252 = (2^6 - 1) << 2 + + // Set the 4 least significant bits to zero + b = (chunk & 3) << 4 // 3 = 2^2 - 1 + + base64 += encodings[a] + encodings[b] + '==' + } else if (byteRemainder == 2) { + chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1] + + a = (chunk & 64512) >> 10 // 64512 = (2^6 - 1) << 10 + b = (chunk & 1008) >> 4 // 1008 = (2^6 - 1) << 4 + + // Set the 2 least significant bits to zero + c = (chunk & 15) << 2 // 15 = 2^4 - 1 + + base64 += encodings[a] + encodings[b] + encodings[c] + '=' + } + + return base64 + } + + // Turn a base64 string into a blob. + // From https://gist.github.com/gauravmehla/7a7dfd87dd7d1b13697b6e894426615f + function b64toBlob(b64Data, contentType, sliceSize) { + var contentType = contentType || ''; + var sliceSize = sliceSize || 512; + var byteCharacters = atob(b64Data); + var byteArrays = []; + for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { + var slice = byteCharacters.slice(offset, offset + sliceSize); + var byteNumbers = new Array(slice.length); + for (var i = 0; i < slice.length; i++) { + byteNumbers[i] = slice.charCodeAt(i); + } + var byteArray = new Uint8Array(byteNumbers); + byteArrays.push(byteArray); + } + return new Blob(byteArrays, { type: contentType }); + } + + function createBlackImageBase64(width, height) { + // Create a canvas element + var canvas = document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + + // Get the context of the canvas + var ctx = canvas.getContext('2d'); + + // Fill the canvas with black color + ctx.fillStyle = 'black'; + ctx.fillRect(0, 0, width, height); + + // Get the base64 encoded string + var base64Image = canvas.toDataURL('image/png'); + + return base64Image; + } + + // Functions to be called within photopea context. + // Start of photopea functions + function pasteImage(base64image) { + app.open(base64image, null, /* asSmart */ true); + app.echoToOE("success"); + } + + function setLayerNames(names) { + const layers = app.activeDocument.layers; + if (layers.length !== names.length) { + console.error("layer length does not match names length"); + echoToOE("error"); + return; + } + + for (let i = 0; i < names.length; i++) { + const layer = layers[i]; + layer.name = names[i]; + } + app.echoToOE("success"); + } + + function removeLayersWithNames(names) { + const layers = app.activeDocument.layers; + for (let i = 0; i < layers.length; i++) { + const layer = layers[i]; + if (names.includes(layer.name)) { + layer.remove(); + } + } + app.echoToOE("success"); + } + + function getAllLayerNames() { + const layers = app.activeDocument.layers; + const names = []; + for (let i = 0; i < layers.length; i++) { + const layer = layers[i]; + names.push(layer.name); + } + app.echoToOE(JSON.stringify(names)); + } + + // Hides all layers except the current one, outputs the whole image, then restores the previous + // layers state. + function exportSelectedLayerOnly(format, layerName) { + // Gets all layers recursively, including the ones inside folders. + function getAllArtLayers(document) { + let allArtLayers = []; + + for (let i = 0; i < document.layers.length; i++) { + const currentLayer = document.layers[i]; + allArtLayers.push(currentLayer); + if (currentLayer.typename === "LayerSet") { + allArtLayers = allArtLayers.concat(getAllArtLayers(currentLayer)); + } + } + return allArtLayers; + } + + function makeLayerVisible(layer) { + let currentLayer = layer; + while (currentLayer != app.activeDocument) { + currentLayer.visible = true; + if (currentLayer.parent.typename != 'Document') { + currentLayer = currentLayer.parent; + } else { + break; + } + } + } + + + const allLayers = getAllArtLayers(app.activeDocument); + // Make all layers except the currently selected one invisible, and store + // their initial state. + const layerStates = []; + for (let i = 0; i < allLayers.length; i++) { + const layer = allLayers[i]; + layerStates.push(layer.visible); + } + // Hide all layers to begin with + for (let i = 0; i < allLayers.length; i++) { + const layer = allLayers[i]; + layer.visible = false; + } + for (let i = 0; i < allLayers.length; i++) { + const layer = allLayers[i]; + const selected = layer.name === layerName; + if (selected) { + makeLayerVisible(layer); + } + } + app.activeDocument.saveToOE(format); + + for (let i = 0; i < allLayers.length; i++) { + const layer = allLayers[i]; + layer.visible = layerStates[i]; + } + } + + function hasActiveDocument() { + app.echoToOE(app.documents.length > 0 ? "true" : "false"); + } + // End of photopea functions + + const MESSAGE_END_ACK = "done"; + const MESSAGE_ERROR = "error"; + const PHOTOPEA_URL = "https://www.photopea.com/"; + class PhotopeaContext { + constructor(photopeaIframe) { + this.photopeaIframe = photopeaIframe; + this.timeout = 1000; + } + + navigateIframe() { + const iframe = this.photopeaIframe; + const editorURL = PHOTOPEA_URL; + + return new Promise(async (resolve) => { + if (iframe.src !== editorURL) { + iframe.src = editorURL; + // Stop waiting after 10s. + setTimeout(resolve, 10000); + + // Testing whether photopea is able to accept message. + while (true) { + try { + await this.invoke(hasActiveDocument); + break; + } catch (e) { + console.log("Keep waiting for photopea to accept message."); + } + } + this.timeout = 5000; // Restore to a longer timeout in normal messaging. + } + resolve(); + }); + } + + // From https://github.com/huchenlei/stable-diffusion-ps-pea/blob/main/src/Photopea.ts + postMessageToPhotopea(message) { + return new Promise((resolve, reject) => { + const responseDataPieces = []; + let hasError = false; + const photopeaMessageHandle = (event) => { + if (event.source !== this.photopeaIframe.contentWindow) { + return; + } + // Filter out the ping messages + if (typeof event.data === 'string' && event.data.includes('MSFAPI#')) { + return; + } + // Ignore "done" when no data has been received. The "done" can come from + // MSFAPI ping. + if (event.data === MESSAGE_END_ACK && responseDataPieces.length === 0) { + return; + } + if (event.data === MESSAGE_END_ACK) { + window.removeEventListener("message", photopeaMessageHandle); + if (hasError) { + reject('Photopea Error.'); + } else { + resolve(responseDataPieces.length === 1 ? responseDataPieces[0] : responseDataPieces); + } + } else if (event.data === MESSAGE_ERROR) { + responseDataPieces.push(event.data); + hasError = true; + } else { + responseDataPieces.push(event.data); + } + }; + + window.addEventListener("message", photopeaMessageHandle); + setTimeout(() => reject("Photopea message timeout"), this.timeout); + this.photopeaIframe.contentWindow.postMessage(message, "*"); + }); + } + + // From https://github.com/huchenlei/stable-diffusion-ps-pea/blob/main/src/Photopea.ts + async invoke(func, ...args) { + await this.navigateIframe(); + const message = `${func.toString()} ${func.name}(${args.map(arg => JSON.stringify(arg)).join(',')});`; + try { + return await this.postMessageToPhotopea(message); + } catch (e) { + throw `Failed to invoke ${func.name}. ${e}.`; + } + } + + /** + * Fetch detected maps from each ControlNet units. + * Create a new photopea document. + * Add those detected maps to the created document. + */ + async fetchFromControlNet(tabs) { + if (tabs.length === 0) return; + const isImg2Img = tabs[0].querySelector('.cnet-unit-enabled').id.includes('img2img'); + const generationType = isImg2Img ? 'img2img' : 'txt2img'; + const width = gradioApp().querySelector(`#${generationType}_width input[type=number]`).value; + const height = gradioApp().querySelector(`#${generationType}_height input[type=number]`).value; + + const layerNames = ["background"]; + await this.invoke(pasteImage, createBlackImageBase64(width, height)); + await new Promise(r => setTimeout(r, 200)); + for (const [i, tab] of tabs.entries()) { + const generatedImage = tab.querySelector('.cnet-generated-image-group .cnet-image img'); + if (!generatedImage) continue; + await this.invoke(pasteImage, generatedImage.src); + // Wait 200ms for pasting to fully complete so that we do not ended up with 2 separate + // documents. + await new Promise(r => setTimeout(r, 200)); + layerNames.push(`unit-${i}`); + } + await this.invoke(removeLayersWithNames, layerNames); + await this.invoke(setLayerNames, layerNames.reverse()); + } + + /** + * Send the images in the active photopea document back to each ControlNet units. + */ + async sendToControlNet(tabs) { + // Gradio's image widgets are inputs. To set the image in one, we set the image on the input and + // force it to refresh. + function setImageOnInput(imageInput, file) { + // Createa a data transfer element to set as the data in the input. + const dt = new DataTransfer(); + dt.items.add(file); + const list = dt.files; + + // Actually set the image in the image widget. + imageInput.files = list; + + // Foce the image widget to update with the new image, after setting its source files. + const event = new Event('change', { + 'bubbles': true, + "composed": true + }); + imageInput.dispatchEvent(event); + } + + function sendToControlNetUnit(b64Image, index) { + const tab = tabs[index]; + // Upload image to output image element. + const outputImage = tab.querySelector('.cnet-photopea-output'); + const outputImageUpload = outputImage.querySelector('input[type="file"]'); + setImageOnInput(outputImageUpload, new File([b64toBlob(b64Image, "image/png")], "photopea_output.png")); + + // Make sure `UsePreviewAsInput` checkbox is checked. + const checkbox = tab.querySelector('.cnet-preview-as-input input[type="checkbox"]'); + if (!checkbox.checked) { + checkbox.click(); + } + } + + const layerNames = + JSON.parse(await this.invoke(getAllLayerNames)) + .filter(name => /unit-\d+/.test(name)); + + for (const layerName of layerNames) { + const arrayBuffer = await this.invoke(exportSelectedLayerOnly, 'PNG', layerName); + const b64Image = base64ArrayBuffer(arrayBuffer); + const layerIndex = Number.parseInt(layerName.split('-')[1]); + sendToControlNetUnit(b64Image, layerIndex); + } + } + } + + let photopeaWarningShown = false; + + function firstTimeUserPrompt() { + if (opts.controlnet_photopea_warning){ + const photopeaPopupMsg = "you are about to connect to https://photopea.com\n" + + "- Click OK: proceed.\n" + + "- Click Cancel: abort.\n" + + "Photopea integration can be disabled in Settings > ControlNet > Disable photopea edit.\n" + + "This popup can be disabled in Settings > ControlNet > Photopea popup warning."; + if (photopeaWarningShown || confirm(photopeaPopupMsg)) photopeaWarningShown = true; + else return false; + } + return true; + } + + const cnetRegisteredAccordions = new Set(); + function loadPhotopea() { + function registerCallbacks(accordion) { + const photopeaMainTrigger = accordion.querySelector('.cnet-photopea-main-trigger'); + // Photopea edit feature disabled. + if (!photopeaMainTrigger) { + console.log("ControlNet photopea edit disabled."); + return; + } + + const closeModalButton = accordion.querySelector('.cnet-photopea-edit .cnet-modal-close'); + const tabs = accordion.querySelectorAll('.cnet-unit-tab'); + const photopeaIframe = accordion.querySelector('.photopea-iframe'); + const photopeaContext = new PhotopeaContext(photopeaIframe, tabs); + + tabs.forEach(tab => { + const photopeaChildTrigger = tab.querySelector('.cnet-photopea-child-trigger'); + photopeaChildTrigger.addEventListener('click', async () => { + if (!firstTimeUserPrompt()) return; + + photopeaMainTrigger.click(); + if (await photopeaContext.invoke(hasActiveDocument) === "false") { + await photopeaContext.fetchFromControlNet(tabs); + } + }); + }); + accordion.querySelector('.photopea-fetch').addEventListener('click', () => photopeaContext.fetchFromControlNet(tabs)); + accordion.querySelector('.photopea-send').addEventListener('click', () => { + photopeaContext.sendToControlNet(tabs) + closeModalButton.click(); + }); + } + + const accordions = gradioApp().querySelectorAll('#controlnet'); + accordions.forEach(accordion => { + if (cnetRegisteredAccordions.has(accordion)) return; + registerCallbacks(accordion); + cnetRegisteredAccordions.add(accordion); + }); + } + + onUiUpdate(loadPhotopea); +})(); \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/models/put_controlnet_models_here.txt b/extensions-builtin/sd_forge_controlnet/models/put_controlnet_models_here.txt new file mode 100644 index 00000000..a1973559 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/models/put_controlnet_models_here.txt @@ -0,0 +1 @@ +put_controlnet_models_here \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/patch_version.py b/extensions-builtin/sd_forge_controlnet/patch_version.py new file mode 100644 index 00000000..b78fb043 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/patch_version.py @@ -0,0 +1,53 @@ +import re +import subprocess + + +def get_current_version(filename): + version_pattern = r"version_flag\s*=\s*'v(\d+\.\d+\.\d+)'" + + with open(filename, "r") as file: + content = file.read() + + match = re.search(version_pattern, content) + if match: + return match.group(1) + else: + raise ValueError("Version number not found in the file") + + +def increment_version(version): + major, minor, patch = map(int, version.split(".")) + patch += 1 # Increment the patch number + return f"{major}.{minor}.{patch}" + + +def update_version_file(filename, new_version): + with open(filename, "r") as file: + content = file.read() + + new_content = re.sub( + r"version_flag = 'v\d+\.\d+\.\d+'", f"version_flag = 'v{new_version}'", content + ) + + with open(filename, "w") as file: + file.write(new_content) + + +def git_commit_and_tag(filename, new_version): + commit_message = f":memo: Update to version v{new_version}" + tag_name = f"v{new_version}" + + # Commit the changes + subprocess.run(["git", "add", filename], check=True) + subprocess.run(["git", "commit", "-m", commit_message], check=True) + + # Create a new tag + subprocess.run(["git", "tag", tag_name], check=True) + + +if __name__ == "__main__": + filename = "scripts/controlnet_version.py" + current_version = get_current_version(filename) + new_version = increment_version(current_version) + update_version_file(filename, new_version) + git_commit_and_tag(filename, new_version) diff --git a/extensions-builtin/sd_forge_controlnet/preload.py b/extensions-builtin/sd_forge_controlnet/preload.py new file mode 100644 index 00000000..9bc15b70 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/preload.py @@ -0,0 +1,39 @@ +def preload(parser): + parser.add_argument( + "--controlnet-dir", + type=str, + help="Path to directory with ControlNet models", + default=None, + ) + parser.add_argument( + "--controlnet-annotator-models-path", + type=str, + help="Path to directory with annotator model directories", + default=None, + ) + parser.add_argument( + "--no-half-controlnet", + action="store_true", + help="do not switch the ControlNet models to 16-bit floats (only needed without --no-half)", + default=None, + ) + # Setting default max_size=16 as each cache entry contains image as both key + # and value (Very costly). + parser.add_argument( + "--controlnet-preprocessor-cache-size", + type=int, + help="Cache size for controlnet preprocessor results", + default=16, + ) + parser.add_argument( + "--controlnet-loglevel", + default="INFO", + choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], + help="Set the log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)", + ) + parser.add_argument( + "--controlnet-tracemalloc", + action="store_true", + help="Enable memory tracing.", + default=None, + ) diff --git a/extensions-builtin/sd_forge_controlnet/requirements.txt b/extensions-builtin/sd_forge_controlnet/requirements.txt new file mode 100644 index 00000000..d12e85b0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/requirements.txt @@ -0,0 +1,5 @@ +fvcore +mediapipe +onnxruntime +opencv-python>=4.8.0 +svglib diff --git a/extensions-builtin/sd_forge_controlnet/samples/an-gen.png b/extensions-builtin/sd_forge_controlnet/samples/an-gen.png new file mode 100644 index 0000000000000000000000000000000000000000..128292ec8e536e80e10a79e19b8b8dd234b3dd5f GIT binary patch literal 129751 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 cvxAiUsCrqA?MvQks}nnXH2>Y(IS9nW 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 literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/samples/an-pose.png b/extensions-builtin/sd_forge_controlnet/samples/an-pose.png new file mode 100644 index 0000000000000000000000000000000000000000..83b92e38fa105876be558aaf47ea16dc483ee8c1 GIT binary patch literal 3113 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 literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/samples/an-source.jpg b/extensions-builtin/sd_forge_controlnet/samples/an-source.jpg new file mode 100644 index 0000000000000000000000000000000000000000..01e2bddb52386de3b9e15890da1bc9c9ad2dfdaa GIT binary patch literal 18734 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

wg$vF`3Ht4bIU$jiw%$XrvOw^Jp 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 z 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≦}rQ4 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 literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/samples/cm2.png b/extensions-builtin/sd_forge_controlnet/samples/cm2.png new file mode 100644 index 0000000000000000000000000000000000000000..01b4e684c5f5d459e2e1f0fd74209d89da04a6aa GIT binary patch literal 396024 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

d@isR5e0}G7E`e7zpmn!n07JDk8%$ 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 N002ovPDHLkV1f*1yQ%;H literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/samples/cm3.png b/extensions-builtin/sd_forge_controlnet/samples/cm3.png new file mode 100644 index 0000000000000000000000000000000000000000..f9fc7fba2ab540fbfa5bbb62e3f00ac9daf79d7f GIT binary patch literal 384236 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 DkAHoa3wd#I@#EuXr-#Q(q*15$ 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[ZJBQ1f*w0gm^k`;+ms9^4v@c(wHGyYutevYX;wsjB5_Jsyt+b%8P3mhpvp zOo@z&Ifb5L19y;q;9RQ9$Z)ZXI3Q_oQcpg&=nMdovYxhp1Uo{8^uV28=AK#h$KT2U zJJ2N=aQSTsy#G~xpz^|Yg_(5P$Rp$B$8V%LO3}W^_Db@6rHnm0%60tz9@e*ukQ{p5 zUX1{39flr;Bug^+y3_O;5zvsGu?+i3ceh--S|0oQmE8eOtn6?{% zV|_Y9jFRRYnHXi`h*@DL;jQoKBo*is8}QDlbu6jbCKyvqUKes)8&U#W9H zO5Yrd!!`yY$k9=OEI94l57|oGsnjSN$()^@p92OE&)l{xv+tTU5Cx!h+qF<%%$Cjh zbC8W4Kho96Ry7p0cN>6UEcvDd9}pC(0VoS(1*0{QSXqFGN>Ol5ghf&7HtlNBw61f$ zC`DTYB5BqIvY@>@e|5y0^7zmYjtBPc$*ni-XxO-F59jB~wd=NP>w(slz4F~&f%V

s5W+DRDHi{JQOq>m>;$9idDR|tJ$i3)1 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%0D6>qcUXQC%9%=?iwRY7S+p8JQts)!1dZ;EvrQ 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

w8%^oa~-d&1g0)U9{9xT?^>@GyC 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%0D#)!> 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 literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/samples/dog_rel.jpg b/extensions-builtin/sd_forge_controlnet/samples/dog_rel.jpg new file mode 100644 index 0000000000000000000000000000000000000000..78a6d812a6c9b0d10ef325e19fdd40b53d728569 GIT binary patch literal 48778 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 literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/samples/dog_rel.png b/extensions-builtin/sd_forge_controlnet/samples/dog_rel.png new file mode 100644 index 0000000000000000000000000000000000000000..a67da581a1086fffdc03f289104e98d6bd123698 GIT binary patch literal 462986 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�~XqlROYRugwhF`T7D;TTs_;3KSr5 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®D%{Z8?>y^p(}>St>QRPjSnv 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

pQQVEnQLAq9|STXsr!>xOjER5QC3(QD8mVZC2|| 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%0D@2a9Qa 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 literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/samples/evt_gen.png b/extensions-builtin/sd_forge_controlnet/samples/evt_gen.png new file mode 100644 index 0000000000000000000000000000000000000000..5d0dbf1c62b5b7cb0b76140ea890389105fc5789 GIT binary patch literal 179979 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໠J-Eihcon6YTRBKK` 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

ghZU;a-q%|{_qh4X3c4xJDWl59!Ygo&P%0qb)i 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 literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/samples/evt_source.jpg b/extensions-builtin/sd_forge_controlnet/samples/evt_source.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0a21210a73535e56649948be7a92dcf9da15b47f GIT binary patch literal 145909 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 m&YddJL%I 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 DFT+ko literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/samples/mahiro-out.png b/extensions-builtin/sd_forge_controlnet/samples/mahiro-out.png new file mode 100644 index 0000000000000000000000000000000000000000..d1eb02503a54e300b60fe42cb147fbd9f0da2f8b GIT binary patch literal 415672 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 HD)JU zf0$!-CqAL6ZS{0$+MU0+zrD5Ps-iwg9tr_mj=D=Pqn*ZcRF2EySWRkv5Xk#H*E# zs=oqk#rC0I?YMBl!$p%#IMHgR3hM4?If3{=#H8&V#}(NmrLjz_dx(o6xEFvx>Q2U4 zSqyz5CQYn8IY~x=WnRW9>U(%wJFWaL`VulZJQS`=bB2-UBfi*?bY-7*VP`$vx@1_WHz{I&vg} z!tX?U6N!3qr!4*H(|bEdj{g4d{rU$#c+WrmXaC^%i4$GlS3YFCwvT^Y0>=NO!`JS` zn!6ltO&c2S4TG%A;rc0P<=$xg4%UN%)%{t2`C8>a0S@(OazbQg)$>qNK%}4U4-dcf z%^SPtCaKFwvX-fHV#;nb?Jm3Kii3B)?NlcOW2P7}PM6e`wvdhho43ucPIh{`X*nV0ZPW<`s1LbG1n z`Cz^r%&0hf9p1_uGZ@;QVkc0HR4T^KVh#GYZAh!|BeGlpj9Z8(Ozyc)>EzD#`ybi8 zIOm-{u@AkIR3{NH*BV+P@LFwW?Jc~oL0$U~SI_Cr(XZHAS3&a1%bSy#L5%@kF3ZR; zGHR&A^?pM=nPECTvXRq+51+pF>MNK*MsT+HXj~a3jr%8u4uNcM!=&orY%OVG8y84Yzj8BtWJ)ZP)g`rH#;(8IAw6-PnKtSqk{Cq8Vqmk4p0;Q>D!2Q({sp;{)=LAC? z`x~7yU?D57ynZuRZ4s`UsMUWeq-l0C*5`QLbg8AQE0vm`QZ%#a4eKNFAF+Gu)M;jx zc}AWX`uVG0_3Otrw!YyT{y(Yf;q9CsWl=x=@k#yC_{;6yVU@yb9=F!3wLAQ==N(af z`|KZcjQ4EiJZkX2a^c}DD{c;Kt{TZ)WN{3`{Lc3d_q=~P;XGmMz3-&UgDwt+t<9Zh zJY(|ItIzD7KY4hw7c#BQ^{B?q6=09HvaUNKBVtbEA!!?ZAbERXwPEX@dJG`ofRVE^ zZ6Dr_nWjN`v?Ld`!pV{QMZ283|3|$->qlM}e0bpaJvS!?CAqLaf8_BqS6y{kKy^1- zxi2RQl{1)0mX3G7_nzlJ|GAb2PN}F-$VI@ysi>DyC~MEMG3kY&u7mqRtwg|4Jx~?S zG7CjV1a)HOAd29qQ@UVgbwj~o2%^Cpno*ow%{_*j>vCtplf?UrWicuWRj1H;#AKh< zj1g&TJqk}N_G-J|TO`1-2hBA)D%Kkxsv`6HWZ4a_;AOUDG4*I7>lMZkj4Yc+tF@t& zLx;8>c<_<^1DGW>>x7`eju9$_8G&OE*mWeNJ6nLc>b%&&t=j;>#lg|s$~`7zM1rTL z){H15f{~4D;4-EY*5Qq9vl62HRO3?OoKY|wWeVo5W<`BI@O()qERdP_G-(niQUZuV zs}`@QD?UCza_b2KBm!Iq8?qQrCtd1$*b!S?W_#Dt{*AJGOSk`&>GJyN{D#fpinKVw z!%lBoqRF#(?!*Zy0#0O!EwM3a$DUw}3>1P!1MJam7$E|S_<}hqMZrdG)Q&qvERka7 zfCH`Of*UGv29YzI!|JyoAP%=UOBFsq+{KLDqcKxxvDqPYN(^cg(Sj23s9AT^$AFM6 z^5~urZ43~l9WD^K5tJaHD3^@%W6ONT^~1QM3(NU*>+moAk5}FO{`dXOZ~KO;uDObc zno(HKYCQSzr?UGio3{4F2;xU$^-&i76~#;f6JyMdY*Qz0g<%4dkVZh+3n&u`Lj@iil)+pfySIiH z0C7_SQypj&7YOaxVM8L_-@UlMcj460LmopQnB9n75(MVzDxGN2ldnXUg z7z;R(^f4YAfT@8wt0fjO>rl35J+tgChCR34p_n-nGYpg+?!;MnP#&VK3@fl8Dv1qn z7Iq+Uic%MIRTT9MH*yzBnQaghn3EW2((zT79pAlpZdo!?nh$xIRV1-6oQ1@+a2?5R zfWei>9LDJ20*ImxVRtHqf#BpOwX3wTvpQLg9i3eTE*yq3IZ~l6Lkf{|Z9mE!I}#!t zyA%u{TzA#=uYdEqX4^-EoP23s;Fd_tjaZzhz#RhW9O7;DkP~@=i#i#xBN2LaF60Ac zBai3rU?Vn=ktkR}N>Eqz7zI#2ypx-ovpHGI5Ju8m;KY=gfQ`_^CM`qh#6r|D^@^0O zJ8)SVQo=0xjLVd>_#kA_Rss+}NV;(E!UhzEv%`xf$3(hL$Zar`n5@Ub%s%aWgUbdM z+nl$g^vGlpS~)Sh5CoD4t}#iaQ0)O1rSY+wDhmPxQbMylHT~!j>P3L)ja#e0y{e3> zAB;GcGtaVHVD%MXe#}h&)IHQ&s9SY7!g(%wyP18R>yB)@bG}JgBce zjITo&z%?9gEx2(9Gc%L3t0(CW_VeD}!S1<>ulb$dx%$defBW0NT?=y^Y+2JJBR2hu zJG}k90;(-e8kwDsx&->fe(6cxp`OyKMK!O>IdC^KftWLq^!;S-!o%-)>z35+Gsz__ zl}a8aa`L&)kSk81o0dTyz2KA0EoU~wsDQP5MPtx`mTPDcB*}UV$Q2lj49z8s6>6%0 zMj|I3q$S_j*)%UfJ`=V0gS?`|h=AcM_)kv6?ao#Y*fb@T5w2B+8cJyT(1#vi;wvvZ zK?F5bbqGa=#%S&4szTmR`#*luTfX4)UI1NyD0>;Sh)A`HL;w}Tpyu!dp9;_Vlmtuj zOte(XxxkH$s%kRk^My{swS`nhQ7Iv8Xw_SlXRT#%-ui91nl`XGOGu1^`O-*0$>1fr z+7YRnka&xf+Fh)7oZtpy@Q8w&N3IWnD*w`~%en_AQupY9q^%&cVeA?an!A%TrJR?S zojh^&-1(0@dIls}6)YOX-XOSJG;WK+=fIL}Evx|uci z9WfPhWWm}eMy)#xNj?EYMhr?`CuLV#Zy{puZ*Ki5GY^97neSpQ=EM}N|>{wstU8XI|W)A)?R9yl>b z6r@ZfJjwR>JKj0j-;>liVM5f!pb6oPtFPx9Zqzgt^SyJ63kN!z&1jtU{83lmc*0R_ z0ECUHe8yTB)cF6(u8a$5G&>&L9UnS;xbIV4+JVz3sDXI1)+eB@L|xBEHPGPX zqsfcQ4|l>K=hQ#=(Aj>vwR3p8iYsG?F~Q8DSk~d@ICFmg?hoF7^9?tfJD5jPz(hja z3CFyW`7jK{m^mfhn8-$-ESKd_219me0YK(e>{$5{qpHO7y5FcpeqKlPwN+o`I!5jU z1zPAlyR#Bt{H!! zI^Afr2bbo?nwxB{&sTGQYd#Jn0DEh|XcbV4IT!P6p3MgHVkk!0X#men79}mb+s(9V zbf7%A6lD$lvP)#@Vn9q?C*}?|PEJX|7P+5T@zDa1BAP&4VPk|=*##xniiv{Zj(L;L z9EN~FNj=eQ>pk~=c6K{*ydw zd_`@@iV-QA@dq%r#45I!Xx_d1j@^gu=_b8)J*BBQxuc|Ra^TYlWynmw%Sk=`ti6| zQ5)*S`5FvH7Rp*&inX2H_Hz9NI0yza`tU=Kp1Az7jg2Xf7SD`eLQpM4Oev+!t+&7X zzFTg*ZhNz{=%eKtU{q>k!YOqC7OG1%7?{vA^$cMzIUg*CWihLhvO{G~m4J`5SGz=y zM5udXel+?vL@Qo{$6yp{nGSU-?mg+2fWXUP*gM#_5LrgJ(46wxBMkFsOrD~qmaHML z+Asv86$g(Giom0*Z+a|*OC6i3jfBCdwL}bZCo(J7U48k79=!kj-a`6mDNE*cWY@+^ zR3zB?kgZsO=DZwhVJJldw@dd!ggRWi3We1pjwT=DuZ@4uvd8srYHu;#w}=U9-7BHy zUCD{m5u>+YBp?AKSn_7_*8+@s?-&p!VX(C2i}4u|5w|gt#Py=1T6(H}*AZdRDD?GO`Us05_gsvMLqTd(j0fc*^D@)2@Iqy2X^FH{8B7+= z2Zfj3EsHEviY4=|Xe@D2usNb05zc08PUgtQi%j!EY65GZCv@#?+qS3T4Iwtdp%uEh zSLt_XxN6qQ1(d8y_dWW=>9Tn0bD#6W|L2dLKmYi*eaBxreC$X_+^9B89Pz@FAAb?P z;YqCjlZFPL)UkH`RpV!H1zCjV4RQx!bR`u^c;fUU?|Iku#)gxC#nnxVS;5xft(%`| zn}^sTnpw;K?t#JkNt@1FHx<^b|0~8TPD7OP26r_Y*r+lEz+PD}*Tb6~%m(FU&dZ#^T+D@-R?O^( zkmIj#LEI#@&8dbpuQ~hCz_;kG!AJP&(Z`o-CbgmI>WEv)7&@JH$B$h0t~>6MG?nlT z30aQLV?qGO!K6|2{6ync@+ zZ|zdsb6NRE@^N&A*L&M!VJjT%t55C<%D~{58|KRM!b|01U3SUNgHiEh;NqNB2Jn(- z056fUcMDB}bwH;X%&f2l@gUv8<-loPXsJ9v3ItaM zvAq=?;a~;dXH{k90ek3Hjdek$1jh3kpt5B$}Cu zCi6pEJ5PU3Iea)~7DeW4|KctYl1SUtbv>;RI5n#sUWRHKmg0G|xN-%tKHC3{DyDiO zcV}TUGdF@bM7Abdhqg?YL>BrJUO5%V%0!^5HY(&=+YM;n3?3aP+Zkgr}rjW&t3${u&J#WpKwGV+#a z7cc^<+C34gCE5yAf^(smgFDU-sBwb9tLYERzD5AW9f>bOw-hioz&=yl2cjxr^u|hp ztIVOQ{Oe{(vubF2S2A-a|a{}VYO zYceed+=Z;gG_{EY474}brFZ9++HGtdKYaK<|ImLb%Y$$EmT&B)v%c?CYnRovz3}A6 z|1Nj%q(Q>R9CYb_+Sc$(HZ4UxXU+byI6dCB84Q)I^SQiMCYK7ep7FOZB3`r$hvY&HB?stj|xLvVmrdZ)RMS{FC7(ZQao{m zI`iRU$M;WPU=)C?5&CPUz}MQSL)~lBg+L7L?c!2bO^V2!@Yv(0m-FS-CyooD)J&RI zZkw6NGkh-(Z+h&%p5zAP$9*p!*39nU6dSm@l` ztsqnCySQi6IETp0aofTQHLnb3WyPy`gK_koTYDhx>PTdQ#qmS451%hXPog#qx;g8B zMI#n4O3%iG2on+~Cz$6ZoC*W7Pq1J{>h#HXVHrv`lDLR#D@tCUro zbqreLtbjwu7GzPGjjB4~XgKN(v^2V|CZejyrOu4dHWs_-8|&jDQ1oGpHa1?Fy!P@6 zLgH={fefA+$PZ8F+#Vyhgns?h^@ZcQS_hWx;iA@_glv}FMU4j&by1UCs2HWxs}i^y zqa-s^Q*|$9OckV%JIt7zyfC{kIzgX0hG;2PpxNDsQ)iO0%cAgHMJW}hCA^qUyUDCi z46O@<$%znckphFp%?}G-m95m;lfXdgT#N@GbDEo6DDwD$?|RBI(L&c>bNTs;58rm% zd#*fn)ffGxFJcz0J)~EL=wmQxTdz;{&HtAjs|#<7dd1`dUDI;%@=n56;WmX0A}Gb8s3hnx*e)9J>}b}K{#xsn$MTB*JcMStkC@KqJwW|lW zC>cg0!2*Dcpl(MuQyC7F(%^J3SW$MC;&7H`AEO{RRs{h_OufX^<`p;RP3+QO1yCo; zw_GV&{1+hzdE`B+UIl2WJ5;PqRQ2C(34X&hH@xG0?}tn+*WT~0ZsyW@eEQltp_bis zU^M3~EI`ZKjPX=UL1Ro>w>3*GlBh{!G`tc@iK?5A{;=*bAh}NJu@+WZSZ)V7k6r|$ zc^zvS>L7x+{)hk~KT8C#lSEBM<*}h_s{PO_d)?2C4X<*_phXODknzd_MD$ZFo3Gh7 z#OjIXX&$4X9AFsKXjy15$)22q7$nB5W=qwQ9obRL)Zw+5!kA1*358&F#)u1?OD-g1 zMR(-1T-YT!c`?l(Bqm865xJ{d*^n;5m`Y5FR&en!=m^@bErsd}DB?ILMv4T0fwE~v zNr zlUWLa91-?a;LWtY$103uAL5ZEj8y zgFpxK;rzitadg7PmIOMcbLJJ z`y^>+cez|z2E%MfFoC=0Rz}0HLeP$U#y(~5scLJhBA(a?Mx+F7Ev1<25HWSFcB{%y zD)**9Aulik5S6cC#i)*ptqu5X_HdnHwWxq+$ zdgVtt#0|Am1Y4xCye*}sSZhH@MfcJ7yY)R9Gb*hi>MB)2Ezp#})9Ns{?Af6eKZBH1 zYaO}<&r{)hy<3gZggUYz`$*`!If|jwo7!q$9PD+XTQEjOumln~QvsFe>^)j03f8FR zxxGvubhXt|(=7C#l1ILd!@a z+zediA^Oldz1RUEnSgt9QWvDjU|qqqpwG*4;!uC~i3i{C=C>U=e)Q$v__eO6oB*vE z{Ev_G|NkKZSRE}<5;_sASY~%}7jj;fvv<88duKXU<^nIOg*LV~Z+a#!zeXoQZqWh@ zXxoPAu``c(%)CQ0%fVT$@P%K>4TW8g$HpV7U-z@4pkrLkaiNva4vIaL#u0lPKrWm8 zY-^+Fz#uYma+Zj=oyp0K(ByRS%@N^Y6$Y5Q5WCg1L3aA^gO6W%#brA?8!>g3gutX~ zY|fe~@mp_y_vKd}m*l(iyik`UZf53vN*#esCovsLs7dfV5d*v&$}+op2>$5s)>L4n z6epVJJYVKqv`_t5c<&A(2zg>kk=Syh#tKpGWZyhO6nVs*fQu>|1>`or_QdAt(~rw! z%T;#w_Jw=l6bvClm_s)KW+t*k&TbNYD1$a9s#M;{kvFJaE$XUJzlK)T|JO%YFRm>V zRHGDuLd?|yU3O$=YqP)OgCEL@l1o(Zm}z)5&?SqcnNn+P4L8_rjdiRXPh$>OgiIrz za7kR)z+EjuZs@+Q#hN~?Rl&9IY^Vc#BsuFMZ)Hh{h>Dyz8nMPqiE4R6wFxFe#m!^F zqh6GI)Hp@?Ft<M|fmdyW8GEe~<7-u46?qYXyiUDvcU4|y+RMIIq(C@v zC(LH9%0LokmSXOqXrhj&YbB*sFl^2S&hFV2Fx7#nqy!-%uo*KZrSLLSF)?NHWKITT zMJ{AKQSP04r_O@U5#f|rI`_^@h4a}gnxTI|xJ%t}v~wG&2M_A={7C=bGduJY!X_0y>-aPr2@BOsdXM8+pt3`o_RR^e$V$m0vHi+_D1gcvQd@cnkCHGCk$a;D($N;4Cd_4YM9R#u9@7Da7yHs*{DytyvYJltpYq6_pYpfj|dDOW&Br0 zE_5C4P3MW0+i-TKervY1von-pU}o{)$s5iR^4b=nK3{8H!_WeK)RO~%vGBPI7tfqK zfBiM5qN$ij(yZa9*i*LY?e{%`g5${hk3Ia_-~avl?)ykjT{0)P)OF@0Nkqu4Ff>s~ zLG(t4P}N1&=<-%d5x4DWH|vGrPP{bRFM6;Xh$u-Hoo0l*%@3%^7j-^RP3&kTgp@~~ zTcd%C!Px;5N(o1{w=Z0rr%ojG=PoYHJ8>p&3|zhU#;_DVvq_Jt^sox6K&`G46&a(B zI*!oN8pl$VDmDD7f#+JX0M)|B8xTP3_UxzJ_{d|Y@BPR*=ROAcro=^SM}TnrRo(As z8FF5O6Ln#6TTP>nT-y}mYHNT!sO$<_cooM6kcysB?R+(qiD;(UQZy3Bs%@=Xue!mJ zVQx+!@I0*=G|+gHy&YET>?&%aMq?VF)hkxDrg6+FrMfqmh?|Dkz1HCEw;>Rj#|tHhM6J8_jm_%GdD^Wv5z)8=YuNY+?dvCJd_Pq$ z`*XcKZcfZyr*| z(-O9iA3~y-r%Da9QPbO@#^ltnTxEVLhvAhkh$J5zk3D*BD7fO(adKk_0VEZt3E5Kf z>)&+S^ImY{cm3m+f9H36{dFgf{@gGA`o{6goCJWmOConS*FH%iVG>wW0I?9c`A}@0 zRSiT5>eF7fCfy_j6WbM{gOXLl^r%6R5HpW!in@w1TNzYUJJl?EeCU=ucSb=ph)d;$ zD-X^09?8R^PqQ-@_Oo^M9z=Xa1fm2MB7qT%91@&GjgBj%9YsS?k5yIh80(~fmH~+I zM&96mt>SE4%ScLufis|#a@7^54j(;!+nx6oGbdAb2NSc=s`|GYy1?w!^0A}kIV+ZD zcLAyvvxR%yGO)EdvH{@nx+_CkxuG!I?knSfM)r)UYSBCgwrlsYIv;0sXf)psQoJ_PGonJ!;Ef8W1D69# zcU2C2vaeDMJ#$A&WPO*6IfD+e9t<`Z<&e>dIMhg8*bu6;NXFFqY;%|uc!m{K2iPE` zj@3+wgv{K$@A|GwNOGXQFojU+CQfNN_@a;tvj~{X)CfkxGBsl7P&$(}M_Sp9MnkEQ zDhN{BpR(klT1wZmz^78w=703&H+jO>e)X4gL{B!F7*JDG{qH|MPSEhl#uDvQ5F99I z3Wd6^Qt|goIwPmnGp z5s^uXL4y$;3#$BiDIKw-QfC7)5OrL}Voc6%!?G+& zO|1y=td~jRL?i?!9OPkd7zQh0-GsW zwm&~VSJ~Le#`^~c;3$%J0PNl|C8k~|(kJXDk;Pc~;AZ^e*-$mZ4gEJc3(zQ|FmP67 zM$J;zXTK&&q1b!SnfOz0y7i9te_(&HWMVZnQ;w>&XySQE9O3JUr_q;;E2l+^;}wNb zC0iNbYF69YYZA4J@K-Q~su%&QRo%$__6A%XFu3-fLaQP1w$$5g8C?$6{-IigL1>F} zZR-#>d1pk^p*&r4r&X*(nVkrRKFP+U@7!Gr5g=)v zb5=7`5(mgN1g%v^=jKcjoEyUk%Aw&|3ya%Q4h!$+0N-R7w1EoY;8Vv=8U3~ zmbXs(){wB*S$lMKVjt<*yS>@PK=TOz5V>pEsx7FRDIh$%aZa~HkHNs6(m5|Fr) zBqr+aDJ4}B>N_@&&4=QK0!(`nqQqMP7>`$;cEA z(>j~ZK}I6O#nT^nm+zg+ERd;f%#K`r!^XAOmr3Ugkfn~KlQOtbXU20?S6vRvTuhKp zKlIQAY#!O1o!;Hs*pX7CpYBYhv%D}XNu;<65+#swpe=3zy1N^(bBChUFYNJQLTh;+6a*uLzYwDiF=<-GOMx1vY5g+*qo8 zFOMOI&|k-?wOym6WfyyJ$A4= z9N$XR5vv))JH~{9y`XT9sVYyDz~)+elT`sqtTT#g@{q2FxwK0jX?P~{Fv0OKFjj=x*E2|~y5^RhVr|!4E;nHg zn8>^^B^rYa$2buySg9~rV-yhgFlm}Pi2IEL&x_*BX-|2HZb_8jW{3h@CRWvA4(VKn z0$r$3i7Z{rKrLjN*oRya3nMLTX==U5q)Tp0Zi!7*)rgw*xVF?Hc4u{u1OPcHlM}<8 zC8-upV&)7=sn2l#J^F?>z5V3z6QBRNFJTch{?0vSS*>EpCpGk+3hV!5C;enm{h#8T z3Ntczg={)Nr51zm4&JTb1 z{zo49$mxq0&*yA;@Vx_mV(;ODg+8K3Z@uM~SO4}K-u$lHPM_w(hp)Zq>YMsbwl*d= z+;sAmr(S;I&~$S;fClkIP&W>fT_qIms+v+FVs8}$b$hJTSROt;5!H4>0saZ`(9K5+ zz{Nlv9lGk|x%Xe3l;~p11aX47Ht!C=3BoZ~#Np5ow+DYh!fJl*-2R!f=b!)l>k~?G zGo#e;FbqJEeDLTa%Madr{@|gH?Al|GoIAMe&{YTL-n8d-{EFE-A369(-~S_r4{h6p zy^|-de8CHz`plbdxaOKGPhNFmN|=`Aa#4md@5J4GSPmI8={b=ov$~mKGMQ{R?JkxE zAF`UEPqPgHc^-7xC3aF_W6H#Rg}#Bi9U!Qe7*hq*Fo~_*Z#Z)|=z-AU>JvxKoI7)P zK}#DF7a&ACfyGG#I`L{k-ZEo$m&*+~+ozIS*T26FGa z1cMM|Sb;H#LtxfR+%nUmHS5iZm{q;&lV%-;EU6>64kRS1Fk`r7l;S4L%&;LRA(1|p znC}x=hwO%;#Q{X|K`bm(jfy+FlQF5#pvIcXh?$+4Q`edD^5DuVkN?gaUjN|-9{q|h z`;u#~z7kb^yvFen)*!&g8r8p;<4+q2d=f{bZQ0dP+!bK3SaFCDvz|V8`n~U@`MG`K zZhPmtr#)pjb+X&p&I>wse*TX4eE5&vaQl1j_`vzy-RZ{U%F7QQ+TObUn#+zJKD^Oy zDa~d_`@27I-_QKQJO9pK|LPZi`r+q3Wg1+v)Ue0a)rbmW&p;_+U$!NgvA3RucG#_ZO%*;)CTHXi8VZc6**#`7#SvX z{M4!Q58Th(!Baz71ac-4(<)r1ied@G402_HlV{Tj%Y}<)_vgD;UUrzR2{EF5abC`P zdB^)7eDHyL|N0j^{V9iT_{izqTW@^&{M`KE$IooZ_l6^Yu@=^(i-BcU2NyF6KhM&}A;-#wm3yotE4s?mF&r z+!|Kbi}QmnZ4gYDRaH9a#HXET)|h$Z0Kq^$zcqiz?#9vnoSlrDF3Y*G#Kp9q^vUSD zD-XZp!{>Jg@4C(p=1-h{^wh~6VeV1b2X_Yxaa!vi93p7~Y&BrDiGYHNY4Vf${ealO z_{^*V-BUFA)K7Tcr`92Kg2*Y%Fq9su582 zTVC&2EL*R)uHK2-MyL)bE-r{Y!eZUep{4M>Wr+Isk;|AP?VA|c`~9!DFCa|z(@c)gxKB5 zo$JVGFvQfzNkm9o&1%^;xj=|TRcr4H5W!W;Bry{+OSG8~5oWUDA#HBHd9-wF6s^Ia z6b19W!-hN8!P{+pa`ykvb@^S<{z z@yNNS-g3)VeBoz5*QGhh@6a6Fl`jjF37o-SxJ~+g^Ly&6i0^`_FsY70-Ld z^{$h%k6wKI@pBgz<@E0S-Ul9g!)@>STi^cOKk$9u_2pmke6t)|$7`onazKk(XTl+D z^Qy8~8IDSd#&<`}MB9O5B;B?;VoEw~A2~c+I5)qzpHMf}NLW+rSH+>$@Mtx=Lb?t! z=f@s9J7m4$#IaJqEDmO;yj0S`wl?4K{`)7x^461wP9|(^PI^1rPjv&qB{W-?81ax$(xex$Y<_L$~g=@NjzwFsw4 zwt_TAqlEyBjK@f#py}%x?*aFE!K1J6_I0oVr%s*fr`vab=)vb+eR9G9lUv7;c5r1C z!yCjxVGs=3F3f0bkOKg&=E5O~)bVUYWc3v7MD61^RxfT<5Ip`GwfR_$TUy_Om)Hys zL+!D`#}kiKSOibu5Zk<9Fgy|5wE%Fg^%Wox#VCtzMV*Zo0l+=EfkjL?4^B+db2PIp zwgj7S&*~K?8EoR09wUP%->@jxA)tN#X z=1f8$GjsCdC{9G=22z`(G>GIv?vQ{r~eGb@`9(3FdR0zW<@y-!eZx-@5J@&;0T)e;kMY z*KgnU(?9>4_doW?wKtsnrk8*5=e^|lmmS;5^Zl)jiRr)+3^JJ&Qzy$JSS~MiliY0x z3W|4$nFz;DZ5}%{L+XKaalZT;f9;Fjd)EWEzx%fN;u&4)m|$*ER7wn}6UeLxO@bh< zVRcPi)G)fG=Oc&@SsiMGKEkv1(FsTpPk#K$%N|ti=Uj8Fo6irHhRy}9X<>?Ce? zzy0gJ=AZxI5B=yb{G-49b!FlCV9_&<9NRj!J$d$x*M8*}fBw0%d+&e$2Y>&KfBdt* z_R13{E`QnQz4X(cd-K*#vf>8^LsmF<#NuAMX}>sFsQWM( zMGChG6lcbBM;wn^49B4ot&nuTNm2!+s@rtxgCN4u`-jxF@W&ol;Gl~@uEWo(1 z!VQ{XY}64cibILSK_x50ggY}MLP}D!xT9ktW&+%7(uo(VqONi4OcxN9dy%w%Tu z^P+Aw(@t1P)j=X%qG4EeLIfr^A`)f*%y26X0G-#;H4sQdhGAJ?X_8o^c5xwqy!HMh ziYd=-1hQgAg}o$UGf3)F$7QJ-GoQ`6U;mBY*Q{Utm4BIqn4n{@iq!)Ai=zH%TpQyy z{qvvn;~p(u6nD>MIZZr~&X@ZKPn>?>-FG~2c7EuJXFZ^oz4HJ3pTGBq@8Ep#Yrg)= zzVJ)_*2&|uLsM`vw!O*3pbLVVF}yiTW&;V>r0=GQ8Q{)~6lVvhOQ_m<-P$Iy<@26> zKtR2Mr(wW(sDWP`Uxo30!BDi?+rC6d;6y;_F5be0dQEn_>mdJ(nf#i z*vYdWd4ka_BWm#!;1x$&ZJ7=xQV$h66O7WsPh8yC+}z%rxT!GIvw;cf-o5U&yA}(5 z@zXB1;UdsMkul`rMK-2Wu`)l|`S<W&b=-(bKW^T z{frkpgRvvXFm0*x0Iacivc3&bfMbyG%T0r zF6c&gY})q>g%`k?L;!)+hMBMifa~t4_N>80ic#JQODI`;$(QZ)W#OB4_GmX}K7f)? zXCxjCW)N-b$w%4ArQo)iv%s|t1y{TIF)Mp~DLMJ2-T`eB`kJR;m^!&X<>niH?RVe3 zyMJ)v$aZmWgii=c<3rY_%C+3uYbddb5#1Y^h?ouNZec{Nm4i3@7vW~`$?F|WR-8aM zosc1nqiDu;>nlUz>&T=+jQVWGyEkebA|n=O@G%a8gCal$Gdn|xj2Y3ezAkvTHjmRQ zAoA!^LCIQ(0-}`IgX94Tb%3gsl9zp-Cejfj=WGT^oH|y`21E;xQVJy@Cvp>x_Rc&M z1$iRtxOB{9fG|@uDCG7Gi4fg+i3!X}AZo0o2or!@O5zmemqpxF32-tiaCdc1sTUy@ zE-WBncDL%(xjE0E{(~0;!O&ulowasc;xi_+#kR7y)Ss~GhX=o=YZI3 zT+R*ie;kYaDU1f{`u~eG{WXn2aJZ^5sGoMg9A3;9_kHB?H{E{kz4tBd{+&17`{>@G zqyAUE?(@I;ue{)@D=y0m?|V<76bcz76Wju-qc-r0mI&fn$h?b!bFL~hZh?PD(%d8w z+y;*Gkb_Cp>#w;bk;hM;-`Y7$Tt$enmpmYANU7IA-s%IkZL`8xwEC|bRA}eKvBkx` z<^DdAM3Y30fFc%)6UXF~NCK#Fum&lXhMwMmjr_2l70 z`}+qEJaYQvv7>D6Zne2LR*`O;mc~6C6vSE}-_~R}L<_FJf(Z(W(MPae{YL}lYtAZS zh?dE~=<(XZtM@G2Q@qTuCfykoJANtJ^cDd%ejvpE5I2S~JQVN}-RdMPyZKijN4$1U;GQ9n#PbaWWmH`UQ#c1pl^E9dw={#UwQjG-a**7 z`R1qn?Z5qnf9dm{e&ldEd^DxL2u%%|M=}!N7<|iYY7tkPTI680KwY9jw1WN>9YZxP zBL|VWw7?v&){V;nfcweCi+h?gO?p&aV5G{p2HNehm^*{LPKat5u~ER+*w1()A<3>h z;iIQcKKkIpWhkln9IE5Q-N{TmdF^J<{D*dl&s{8!pFVTzQ?Km$ZkVfx7pKAf=+4Fm z?|JZ%dryD!*L|MYLH1rfA?S4yf;m*X$y{?kpZ|lGfAQb?{-6G}U;UkL`x{?z{?SLb zHfQr?HXlN7QcOrTVDK^|*K3ZSy!NGE^wQ7%q7Qud!*6@joBr3UfBlx5uY1``UwZSi zZ}rmQF+F$s{Csh+z0t#JCW9Qz!eNIQrIq2p6dYX zjBW8&8|`cBY_+;ukpKn%OwGG;Rl!zUG6p%Zo*N_X2I9~Ygsfon4UOBXp)H6B&M5W!~}9RwE~zWUN!oFv%#1Xz{S;EiAc@Nok+}VsY@mX_ZGurm-+Bv z%4PoBuYJ?a&wSb!yzFy9$toTAQMPkj0;}(RYArN@a$brEiLCg)k9x~b_EeW#?;4F- zeT>724XO#g`^4fmf8{kl_=ErbBWL!mdFs_)`&BRdrZ0QhBu(7T%Z{Yk%nK1m%j7_g zTr~~mFfgZROHPq?18X5i@-ZpbaDTI;fpZ*V3YTg*RSc2!sJ<7@OFe(){ISa~kLFZO z?A*9hY6U{Exo8w%OaG{`|`ry2zH?;m%HpxCXQCpviV# zo}VuBKmNwA{NA5^<@26@>oae?WqILr*G;m*)ZLXq%nY~bbhcP53uL)BSn+4y{FKjl z=B;}NXW#v{+yCb)Uw!biix+;zi=Xqn=NvjTSzKHWB~KD3mgrq5#Ks0>GA9-VNa0X- zbObVIGJ=DY$=JPPi7Kd`S&hBqe#%-rFY_c#VQ{g?0Rye|9b#M%#K*pyiVF5u{06Go zq9(N;1G)MD(NKjqf7{;UQtMyI5-?LKN`#|3o0p%w;_-94rrcN&5P;~2To+31deHDk&q^SxwO{~XLFy5iD@;T< zyB<1qY?+q_XU=!jxksB4BBI#v3}TXE%NTvjohkIph5h}5<*~!ZN-=k1X3|V<_dkB_ zb#Hyo=RN)UBWYM3P^7H{6)l=NIHgY9m8YAf>_7MBlVAV&FZi!N_+zj5{(pO_>&YvP z8IZ-{Bq*jboy;b)d|}^B5BBB<=gV|DeaTB+`spwF+y@_c=#O9jN3Z+6e|_Bz*S+Y4 zUvTuu(ZzC@O%fH5I|~w%7+4)eQ%bHw4Cw3#!X~7Q)(6v_Q0hW66;7VGfK0j!H5XQt z&@`*@@%n~eFo+h74naXmSaz_KOVA9&DoI^)vaibAHU@eG>+hlOpLMXy2P?lPU z=dMD4TN3I-gy3G>tV_a7t}*gRiPc@bE)RE@YTSNe56zkq9Hy`m6_!OUt2yzsr-tg8tk00H9$%~%X^?jqMsoBm?#t8qpkBW)SN^oxL;NoM=`z6Om`6e3w(CX`o z!%)*MS&NaW*?;{0|NKqg@*TI`{=OG|_A`I_r@rrRee=t%+DW{>Yx8~9VYag+T_2&P znGzETldypbMG0xe9<{SVMP2SXO!`_;+b)qt&k<5!2RvE_*02!q!O_eI*!v_Oxc9@Q zSiH@+r)lkD+e$MRn{y-)S|X_4fJ$}~6JV}|7{${p9iE1R-Wq6ZmwN?tbjy$Ir~4ck2z=bl{1ZAo}r!l#!FCJ}Xoyca$e7 z4;Q}fbDnq8X8Q4;_z9Wxu1c;T6BYtjiG59+*w$>;^}Uj$+0KB;?q2r6uetK7Z~5kL zdBykq%gZmn>=$1B^FR2bKYaIn_hFih3W-_JJ4sZvBkNsfVx2BG**DmyY(0#j;z}^C zp41W3!^sUsmN&L~nk2PCSdtBz2e`2ZO=68+^JqT@jP`ns!>83lX?)Je0*x{DSWnOv z@FnzXJ$0qPL+|AVP{+9P_^~r*&hIY|tC)R?G&|=(gl|^hr0_qa3keXYN zQyo>q&TII;ax(2wiDH(7hsMRZ{lYkjx^9>{VJ&X7SAHsPomIg-W1OHHX=)hY>?ZI; z+KUoKU2?2#ioWdGy%=Huy#Q>+?m{YzXu%;Y#LPUI4xFr;lxP5L1{g6B_s0D~NnMKb z(tJ=CN#VSN2vu)d+ljMVN6|#4!esoU}!0L_&xGXNW$j?yAU(qg$IFxcBkj{)4xE z=BGdVhHFl()*-bO^a*{yr^GMB-XlPlxuIXsrI+&YUbz0V^~kc>N;LG}9IyIfanN`D z2k-sRSA6-)f9mI7b>mG>|L5QJcfaS`zv+f6wssD?l)PNz-NCv;r)+Z6Q*Y6jUO3v0 z!(*1G3q**(7M%%J{YXfPa-@E%4+wPMTEI|k&mK4+Ai9E#5DgL?WMFdl?W4!`mdoAU zJv4z|jdxf15np$fhGtYMl5=nKK;iC@i82Q)=3p`FY^ytb{IIb?7!sf_0&8%M1%yce zhgmNC@FN$P)6o-$IB_WoBI$*B^82rO_sPx4Q?HznF3dqtu-5#8Bqexs>QW;!5M}90 zS^T}P`7-_RJ-_{1ubJ*_=3&v*&JBU3BR^*yQQvWw2+*QAhKZ}EgQcE6ced*{zvzp< z<{$mT@4Wn~%m4F_{n!8aLqGKRxikGVk*iQ)*NsWn5xC@zZQ6G*HO~e$azx{IgVk;j zYf!_8J$2HFbR-P2Vns_aEn$nz6w&{{zzBayD|Jk>o?&)dB;6M5+8b4%)!cUTDI*vk zJ7lhJ3XVSW1UYr`v*l(7`0@axMNbB)*WkJF9Qdd$pv>RbU5Y+BJW6eCl ztLzo7rsigD>hPFy0T)v7LRM1LZMeHRyA@Y0%OzRfociHy+2{#n>6Rx+ccwI@VM@kY z5-WU&S+9<9)MPZdtBX}F`aDCt&Zdtmk9HF5(ISd@ZEFE_|GN{rgzghiHKph>0i#x8 z0#~>bQ|eflLwdRjxZrSN66WYG7bG>2!@LNwu!K^mj!lIVLtsPP zf3x&HcJ{oPl6+2?-dwa2%vyZUhIP?klP2XO7T4)OM3?|L<5M#wLSW5F?d z%qi`RIzj@ihxP>HY)LV3q`LB{?Z4V$v9(+qJri+^1aH^RTA+$p^G|^hP#BToH((V$Dbn_$8XEC_)60IRQdM24bFWZXP*)EE)?F35XrM8vhgBLI}dh zYEL}z_~w*0CSA#enbo`l&Ys(Q_w65i@zbxJVF>2Y3DC&Nl0tmCshr?oHa5})Aia7z z+2im35HlwLc{ZCE z$dmMwPJL;n<`(G7U=A}FRg+9KqT|skd!yz98;t0`VtKk`3ylr}BYGa=!7-FXgv#y! z2SZf-oASM@3?PXK#%}CB%8!H) zx?@6iQip;H5UIlPu~k>luP&-WLN}m9V$nU;Vt8?nVNVI@hy(_ds)3Ch zzbU(=NFbtZdm@0ClgD@5-Id8ZLN9RB-M!tNt$sF}zWP`H@Y)-%dG@oOmbxxPv^1{5 z@d z(?9Xw{>%M$-n%^i(5JuPX-Ga;8gd#`eKMOJze>B_xb?(!Z@}A~3RQ_*fG##_W1i}t zXoRx*Z1B-GkQ13l2vC=aQ|$u)a`zb3VjPWJm&3Uy&foU-_gKkjgGtu>2V%FZHgCJ3 zP552E)1GID46WwlOgV-MO=$br_U6t`{S-j-+$93ooWs~8Fss_>Cr zs?&|x9q+q)xNz|^ZoWK;8`z@)GMfDwvm~BwP}hUp)X0%U)Rj60m77oPe9cQf+q2y z_uc=Xx{nPM(45-}d$;WySFyd!WodZ>M6r_ql`u_J{`<55H=*zFT=GNbR!>@k! zXMNT^x845M*T42Fzxri;D$D&nHYXcMd~)QFP9~HHmIXvH_=B2KV(oomVMmgx*(zxdX-yuC6?HDBm!AC_7UVuX{C zdX6+wg>F7NREIYLySOU_Br}>|`{;J+Il_E^>YS@6We1rPTo&_u{`~pFM-ES?ow*Sw zB9NrFyzP$5rhMbEjiOmSkqQ}$LyUy_zTc$DcA9QFkybkZKnjd|!f^0K&%WtPo_f_! z{OFHdRG1JWNAq%XC83yKMqUzm*F^-6Vg?ctF{e_%{fztVT+;m9{H80f{k~WHt1o`p zSNykMdey)B4?pzSxr-Z{ldc2PvgYE6%utFGwNRXCyjj&u)ldlxESLV+dD|a)=Tu6D zySkZq8@T}v1`rJvtP}dxuCITC}#dnj3-{Gx=+)o2aEmn#uHO-yJ`8;$82% zGZzas-z$_HhYJMuXzQkhhgLE6T55`bDwi9t6~xWiR4_Vzx~?s2x^wd6Ti$tRQGLntKV5{qI^VSwOlyCy9rPsM z`}oHv0P@v-y8&7XwP6V@8Tuz5&4V-;5zu874Flwhg=S3u)%X9%cl;l(_%A>FAO7Qi z_}*hX+xrhc{Hs6xlVA3-=WJ}){@L@EJ?AnXvg{nKIgiH=HDjASAggJnNJCuAN9|R^&1SKd#$u*Wi-K7!A!gf!eoj-c+1Mj}~BM&|d zYt7BpZ(OBlV@0k~0F}p!0I_DjDrzks`@VD%P+s`{)Znqec^(^nu!S@Z!H?Y`hFc5>dLl`&c0fxm6X#+4c2nUF}a-4 zu6TuBfC~BB|6-!Mk0Yv`grySy4fQv6(y8f}BS#j-GA<)f6*I-CI7EXgLTFx!r@^oU zvM1-Ma}Vjf)^*eyULXtW=C*NwoyQNlGjm?>G|P;8DBD1miG5*Z-z*Lxkoh+c#V4m)gT=3&ja- zv}7b>s12|jQ}&}x4qNYJ=C#lv@L+TUFKR^GrPQ%qdBss>dF`9-y7ktZpZ2tyK@yOr z`g&i5u7BR+6Gs4by^s!r7hP4&6R*I~Cp;RiX=NtvZ5}2o@*#d6mbK=A#WwGq1o3wq%`vhb+3! zKf@Rm#?m(@7*QxSF+w6#2p?J5_yHVltr$P7btIVqbQdn}UU__Lr|)lj`}=GtT&dIu z?A_f6=B{45-!}}qqR|2_SJhA}lCN46w^sKBkdq`jeEiUCqc;?gnT4D&`sERb$oay> zy~T2Q?C?%0rIgYU5%F8!clTo#=AZGLn^MQhofBP8j2icrhqCx|S zIn)VeoWU%dhQ(j~yw891j@$p>k8ac1wu&*UFhMCfQPBhz;t6*>r4V75Lp2&+ftb39 zaBqW^r6=@T`xlp+*!bqJ{rd0zhyVDlyB_)0fAsHv?~mWHy}dJGB_D#ii@B=3pmTUp zs!S{~vDCy4XB|>PKbbsy<{+g*#FLVXY8716F)=|Qp_(kO%_7@?==!M1&1ki$X!Wy8 zjDDy~Xxz~VYG94wbb>jEA)It5S6_a)!|%BBgJxX|5+g@Z=>r>cvg2B<^X8~2nMSDH zBpBoGdtFtb2@cNPyv5g1$^fjazt`ljGu5;(krNf??6N=DP=u%>h}t-T+ufsaG^BY^ zs(VFapjFMVyMdrihHkFif%SunItvMrIQL+3E`YH)h)w#rcl(y+G~Fw%NvNM>bwXlz ziDqqx^r#4l7aPnA3k<5RMCLGM%Zx&-a3vTFr0(ioLJ4Nh3J`T|e>=!PN|h2aP;n|z z1{@!(dARzFjnpX%5y7~%=c)ZcaY{a^N_U-Rr|-}D>5{{L+Hurm>YKXA|c|KK&RdD)l!<&ryH zy5>?!;l%yUVa&F}MN^IL$BS5Dw@X5x)qe4&wQ!EvZS{^ute_05Iyg|BZH=ZAt;r#( zX@*d1A)P(*#N|gfZ@lKZ*ZjddvUgyPy&qj$2q8B!CYO*6ks6sgl*CDDBbaanWQ~}O zh2aDXcEzo@tDPWauaTblZv5of&3D603syv@zrBkI1)t>F50J|NQm$ zzyBj$zv0WAvUbd7Acz?OEQBs`RJR0_RCgy*_at4PWYQB076)0mhxCj6;pXda`se@b z6`%jPU;1PJ{Z+5{cmMJ1zHV+Fv0OM09bww_^X03(^@>OaN)o}FQ z&?FlK5VDTFN60CmhHN|-56mk_6n*Vu9)OwFW*(-1fwcJ2tq@qGn-9aX6cMQI1DRT< zdJw!0Tn5}Ez&gE~yODz`6h(X94MP+yB&n@~3 zzPalYh-~)KLsMD629E8D2A(;bBnv3HdK7jLSU3qwWaKJ^;^rWxI&BoBRKZ^jC94;t zYTCwBJjQ%o<-3|MXyv1UE7t?72!P0&U%?ntwg9X--)e|H{#PtjnQG%rLzD zQgAeRm`|tESN-B^|Hfbaj_?0>|MZ{!gTFZ(>~3yt0U(WD|bHU1-HKcuKVtN=)5C=VTNikDwK!-LW#WU6e`*`CTl}i5s=%RikX?Z zDVvj;YXQ_s_EH4sI_{>46FddKAz(2_Hk(XmXV09^IUhfHgov&9B;kSkAAI|}-uK*_ zuRcB#I2p7+oeE$)?bF6Ibzm<{s$?o6n>*5P=3-vFlP-E(6@v;JhFebTeC>-r{bzpk zM<0J;F4JwWQF2dECM0t5#3T%k8UuLjJ9CXJ2a`>YTsd0aCq4TWM*>u|Xa2J+L?#x+>12I}rnoXt3fm2jjtGR06Y|2iB zyLm~OH!>ufVKN(NW1v}9HaE>m{Up<5Nz*-@?dHirnPllRoXPTH-^-$hi{&WhuPRd1 zc&ZMR=9u{jj&NSU0+RLw>+NsNMIzQ=IJKOfVMKZ1Zkb$S3N>1Se_fkMZJ;PTXxwW4 zoUlTO^-+!nrv~S!g)32q5TIWPCJ+D)H7{;Pja93u@kGb3JTBAzH-7t%p7&|bI(h6c zORYUzMIRr>(*Ieo|0j6O=*3h$4*(anl`!B*F5<~uLh}~J4rE;%?01vRfBSEK_=kS@ zM_&D#|Kqb>{4C>Pwz2Jovb5XY@~*q@y6>z0%9rk+f0SJvVo(Tm+lOc}0h!kVFQ?T` zUXO}D>K>tP^16E+k;}C@WEg0cof zclSd>QAZ)BHm(&IvvzQ(!i=ntmCjX6Ney1yi|XL6fVyj_58$L`?ylK%X`0Oj8xH2f za!HPqf+x3#;hDYUVZQWp7Z-#1bYqjbFY5iQ|KL6M?4CaRf~Q=QxTYPQkX@|bmdztJ znK_3d2@I$k_uXV;D{P&rF_Dn7!whqVrsWsD;Fd3X=C%L*$A4-+^WZ$pmxAOV4bi<@ zmpG>N1*1|sSi-Yr79`<5bsPPJ$&2P8d+}}n9V{`3M)nTn-_PWH-dz>e`I@x(m|Co*#Ps$!%NvoKL-23J>igAnzKZhyd1Nzz1| zW<4<{=WdyolRh!0xzPb_9?7F|N>k_n|QMFBY1k~45j7N(Yf zXvA3Pm<%zlxq7|o$-UKiI+;Vqvd;?ZTAn+2t(In~KODoc_VnYm>kW|VxqU^5uRt%2 z7y@n7O(>FR{9%=3wN+JxL*z!TWH#$3?|AnekDk8pMPK*@v+0D^@aL1**Go<9pBnzt z$NlffsOT_gDb{AlwdFVNj!Oc9OHhA&;ef|r3uImPTRZ>cyMEyHuYc#S{Kn5-cI+@S ziFAN_DT(MeUinL3`{gh7tONmsA#OT3v@M5^7NOcqgeaWr>M}=^?oW1a#uObzMPSIE z>)me_e}(bu6}NACT}Y!?2Tp*_muDZ_*x0!I_||i7y!?;<@C|(;k}lSkS@e8YS93Ef zrOuT#hnbdQn&Aar+zPq771Qii+|)Iz4rN#l`}4d%U+&L`gT*jkF7}tpdG-P^7MI#w z-K*@xZF2hDKC{neQ&XBwr^^Li`v-43wSi|{zhiK9VRJGNO(q*VvN7`ncMT1QRfkGE zopzfW#Y<(jpql0c>1<){+r+WH~z-&{{CCO>-&HB;(;7Jbey0BxFe-x z(I0>TuN}-hCMCcR&t$23W_O-a&yq?hs%DjQq!C(=_&xshmHMWAbA18D>ZjHeb1nEC z*L+LnV9Y3vzpQWt^?i56;p2QDA9>{Q?BS?u5v)IoN}Nhk zwsw6CnI3UmyA1!Ro%vB$b?J@;+$9mnOl@W1s}y)VXUMEqmZGhNQCTL7i+jGDPy6YN z?0Gj`{_y>GpLy&txDpwtPG7C$g4G%uE9Pcq=4w_{2QAA|2Fr^)91O$3a=E`)?$4J8 zi@ZPNgIpFRFEuYUFNzLc2Gwj9vuB$!qy{TcA-Q<&!ld(!S)X$j=es}j*qh(?zGpw} ziW{!pF3SvK1uS*l=60HGxFlQc1^{lb;st%`w|2lSNHt@L{SPOyK9SGA`O9B==7V?q z?(hB~M9MHsBf|mG#LkpN5=TZnc!$91qGoXKQj#Qnms08o;?54TaCbVgb1`+8>nSK zjUD!Oe-SBxu^-o<*b^HicwIb`PgeNt2f2QN(MF8=JMCurpONWbyo9U_*^^+a#T31ATlzOST&-lVGVAf99uu`fI-QixZY)%RFdGATKnT@YamT$aM{s zW5vphmt7&-`ZK-6i4zFK{iG+L6m2hUBGD!VuBV~q>DTVai2Kex_VCW;R_eF%V*j~M zxo+b0-aGC?Hb#M0MNpec$WSgr85X+O8|J&i!R|2M%gcj29F%;J^Fh{wTn>hOFz7rF z^D-=~WG@*oHYGQ9OJ?MCy446`$RlIOw12SJJ$GSib2gp!d3nHWfBg10AM7n({OqSr zItiwh*(S4Tx4r2-MI)^6(s7@JxHit~`svn=yE3zpfe0bJ7!;($w$shO?aM#!b-(t% z-g?IeraQ;-kUO}Lk*ko4yD$mI<6&V*B;+s@caKS@!ptO;l0%A#8ZQSom+XG9ckwAt zx$+18?LWEU#_Rvt5B%tB-+tfbky9KSm>uTC;zSNsX9p`Nbu{aEb8GVW?uCU)*H2^j zg$rtp^1&D@|OUAHO(Xn&eUXcWk=u)+F)vz6hxfC9SjgO!8Bw}s?gkB>CAu_QPiPh|Y6Nk#B z>5ti*4Jn%p#%g4+Y{lFQSY%Pb`J%mFvnHYfU|R{xBe53IS5pgHq)c>YJO{u(8pR;vMh4`+>(E z`;wP^UXm)ECt9~ePeyY58OWcHJ;nOhUg11BbUtThu!I(SyoMFYv-bCT7+iNm(K0NQ z`fvVg|G1R=%3t_F(Y<~$fsmTDP(gm`NB?IcdHxHY#$}Nlgd)jkD(UbsOg7PixmHZD z8hmldJy|95KIT4AY-bfFH&xZ9`wTSIByTH1XchWbPg1E^i1X?DA3VH$$j#l#tfwoE zoOsK(O z=AqSwd;eCEPlnoPOxK(ses{@!oC?bPog+4#Wp;%!Lb20mW`K!`mn@dHHh4N!2XhzddnQRNS{#y;^om3MH-7Qw z{Nhjk%)R$N$bF)+Na9I^Ik6;S4q8K1nV7*LO);pJ%#MkqPK1RO1QLTND4XR>GTEA! z#pYpr*LVM&mwn+&{?iZr=>Pb|SDS1k>AEUIhyar-)B?Hbq_>?7+TGiG{M?*)Dv2GI zwO9b`8sFF5J+{z+BPMc>ONgR`Kguk;<(DY3&{8$NAP^aQp@JsZ4~SmDACZ$2!_|=U z;jN9G!-vlAo;!Nt$Wx#7>>vHfpF4f_K>I$skrpy{;-KKnU12^-8X6(B(k0Ru614Y< z{&?omf`M8InZ-=i&`F!8L>rs4emdc9mbE_^cz@sL%c5p1WzrSFVrRlT2{SAXPwdFV zCtTb!$Voicy$eECm%r?47he>BFuAWPo_gL(RZzRguFC6%SJD;YloykNN z6U-+*@3_DVY#4@pcb!cqli4&6WjS9&-8LJ@h#aJ7Rkq{?QxtP^XF(Tje5k5>3ZW1w zK?#LXm@-ibBp#c^SJgS@F{h?B|FT*I;i#3WmAygh)iheY#sZ_c5_gP^kI-DyDB4{4 zo{$y9C}L)ZKmZ4`N5d*03A)MT4_^PqE3Uoj)1LiI5n3gD)@}5YxPVXT;iDr240&%i zrM_rR6j+!Sa`>Q8HBNFxCQB-+UCMHVi`6GHuo2Ol_e&q*wKsFjIQ;!m_9!n(=BeGed}T!^y2kzD5cW*NI`H#(w+_ zT1j=Fp$llm!y)pm?d->pAGNb|>!MU{w!7-qy?OS;AqFjTr>Oui||Ar3KgicYCBbP@G<)WJHkQC1q%i(~&_ zIG8Wy*$*<$vlw-pq$8S&9NC<1OnN4EvlRInD5Dk}dX0}w5#`msVju_x1}87pA$cxr zS-3Nw4MX3h&55Kk&%28vvu#f(R*1kXed@6&m@lX}bCY;cf=G^AgtL11I3L*qpnsQb>!}=SSTjgcvD%`#F|qTW)rA2Li!Px*~FXUDm-nG;;T)<>7H7mK_m>xQH^7Q$OZ}{W)e9=o^ zI-7MB?zZ)akM#s=7W-3qwDU&|unj}bg{0GBC6`K%_(;bio{?A4F$|1&2{>6D$U?eU66EK8>gS(vR5 z1e|I8ZO054t?)p;drxL#*w1ryNic~84$eqr~mZ@qK>U;x|<=4@s;+u~qY&a>tUH;BmK>Q-v&GS8-qk{3BI zOUY`*Rn1h@GzwbP&0^9?ZFtyvHC8-prtar<_x9)eM>e-6BK>URjc84 z%FfnL{>0DidoqF`3sm}KaFLXxi%*wbYYR(fINS@MiLLLb>qwZP(USlM6sMAt>4tLZ zy7CoY`Z@pb@BYpA+;#sy`PcvV?ank?N2F7DGwH~|ZnrkW8VSt=GKWuK=0NGY;hL^ZOy4;wwUraVgq8;G=% z#DJ=%E*ZFhK`Da%C^&YI5-C}AMsDu5$mL-0y?Hr(e*d8O;8IBDCYh&mm2-;&naTF{ z)}hVmR$|kW_UHf8e|p8vjHcX!q;~6af~rjALytfDYrplHzx&s}eqsZYsx@Y&pQg7VrI1=aoAh}F}u4H+|*p7 zZ>7T2)y&k2!OWw+D2S^l6s{83C}&00kW)8F7x#Df7sJlZ;jT;P<_B+l{X1TC>y^*G z<+41VD^i+nP}dWPDVpO)Nn88aHH39;*-sWO!rDz_w&CO+0|a0ND9(j>>B32T|LkA= zg3r+h@Bf*fd}Zc-P=#iw6Hsi)9OR3&(aaK?k(fXVw!}y^9FE_kqV6OPF6v%L)t7nq zdC$7#-~6+G=uY4Hul~z}yIE%2!!QT{R~8~>XDRAE>Grh0u)Dv%zaRw@!`VD0^SLv; z<~f4Y;nvF_3>wCsJQx=>;Qv3?-aB5htGF6nRkimy-F?H{i5g`j6cIuoaz+GUOwNuE zgR^l?;2b{NpL4=|w!t&QKH@}%XGq?M8pR;%Esoz0 zS=Jmxpvta;{BT&074C6(okHlY#01ZIp4Lxn{?@Pm&!715@3{OP=NO2BXem-*1j(jA z_|xBi`Gc;w$2o`hip|LZb7H4Jab<~`wlFWnF1Qw6H5aG5T#nt@|JT5D^;1^Zw`m$P z@B1_${XTsEz%AE522mId)xEP5JMr;5jx3GFQ2^wEbc@?n54zt+K78G6x1BI`sA|f| zeS6lI9?k;U+TxdKwfq{&M7X%IIlBk*pf0{>1uZs*0}i|ZGRnFVksx9H_(|_Ij7DKR z`Q#_ReA_KIeA72xx!PoRPzW?$qGs$;w@uMPEGpGS{p7=$Ud}{|fhS888-${cH+B`| zf`AwijdKX?Bx{p9zbap1Hc|LH&Y#24?J>^-eZ){a`P`Xg$Z0JkQ_KILPl zHbH^wwk%d0fJ4fVkTM&+ES`d&-^CedkwX2jd_{AON-YX5*@D$ zR|aQDB1w=Q+@a|#BoE1?_s}b6BPJe2iR|MBK(n)ytnNx8`EfIDH+W>KXq~|=RBKsThop>#HPs!^J&i!qgGm> zrfFx%kDp50GjN>r^91#AY$HqVlVufQHZv5iwX`0PsbwWqHiH6Yo(x%mj*_An_!D+Q_Gj*!Z0)#=M$a@d%`|K?@e)!X0de$?ZIv$S)GPCT|A+4>i zGOWb^m(c#-ebk>;nzn7)X^2hE$pLk@h1=;4(lxwQ2e~tmrZi91@#q(S?GMkt6JLa_SkRx~HlG}m8$(}%8o*YlqB4Q?6IR0*@Y#2A-WT?Re@L{(8qPF9r?yWi~2 z*S-V!4cCZv-mo`KBr{E2g$#$=IOyGmCa&TsTf%NF5DG3!CvLxW@5&^G(ihFO=K zd!D~4e(kmI={sX{?dDyVK>{1p%N4j9)M1r%D4D0LyPK=Q3amA-US;4=#n^W2fXhd6 z0BY()^V#Nfy1uf!w6cHiKfduzmtTC=1MhQznF|G`HZ;owsr``!y{i`cHMY^>Y$-2o zC3dlMY*to7Yza=~k2Pg|b+{15-g6_?%Xmw)FKANcIeapk~# zu0kB7$S|lKg{5&2vOABjI|btC1a-6OAy?ZxQ6!8tkzaI(IN-Z=U%RwqcU@#V8uE%C zT4`{wL99rNQ?*`Cci+1_UR_bJk+oqzxKYd3qJc1jMo zaR_C2Nbz;Uf~_82eUSzl+?<_+S(q!Np`}&E!KMO>!2{({!19RONJ4JNO4^$ij~%rl zJu2;}RFHmD2+YkbDan&FoIhXC`6F!q~S@!qez6(t7`@ePLzx0lL+pnS_f`0lflh|W0?U0&B&>I z=uX?4*Ckjyz!BLvJ5x50J7woG)TuJPWTnNodV~`b8FLQVRwxt1-PP2Y;Vxh+@c~ZG z<^y)@bqx&2Vck57P+i5Ji#4x;*$xx11w|q+O)+)T(lEBt0WvM97*oZ%qi(tZoFB*%WHeS@TD8R^qDXH(hHuv+&0_W+wKzE1|m-C zyUx=33MjyZxfe#vci&8hQFJiJ@mO;ru$!AvDY(Is)It-Rkgqtn_WY+j<}d#A&wlJh zKg;Y5n}9`F-Kd8D3W`*1wHs6M{5J{04pWrbeP)*6tQLYWGZUqxE<~`s%k)Fv^Gz>* zZTz+0dg+T_`1}W7eqP#KZzkh%R!bAxk;H~?J9^ao+$h{D9A;+B>bq}fl?aqGsdgO= zhg7-Fbw3Q>zOWA%7D-u;P5>DZ0aActcLG@nHShu;v&dvjdsfGHoH#a{c9wIHQJQXi z=X0JM(7)pEUhlm;^GT26u5X*@3^O+=E7&m1NiQXV568Yc6@;+<4^fdDGGJx)A-jN` zGox4lnHyVe86cp{xH1F73(dc{0EFshrP-m096VEmR@g{LGR5SW8}*%2W&`Iwx9%&W zAfvE6X;ppizI}5?>JsHVX-A_*y|>xsEVfa^SK8vk*tu>kuf*KDBX>QRi^zfk6SIiB zTbYg|jiGt~c$wpFWwx@mY{cfKbBcFnzEefF=!B%4-8GN|tHKdyBCf4lTv0nO#zd|l z7HKU{jL%w*`!_$* znVI1tHtVd_B9_wMHo&v(X-m}p2mivLi>Dt73=|K4K=q&wk%SK#!1Mmq1i zz74$HCm;MOzUIf3H#W>yw7_6#UiaG9zwY(_{0G1N8*9sr0G@}O69AE`hc^Dlr$6)2 zfB*NNdg(7CC75L|>sP6vxIFT}g>`ewcp)Zg7yZt=9gRm# zh<%ratLgQ-ck;nn#X0RdTFOa5PSPB?<@PhrJPo7-bw^L^il#gHn1|ov)o*#{2R?e^ z;~#l}LEJMFnY-E088(0n@UjTY$|&)o{JWKz=DTtQ8%{5(Sle(~5y8ydRE=)F<+gTt za`@~s-~0CWp0`R5zt_3*)G0U$QNxZNUMHrPD_MTZB8nA8n06(Ys3ZYg0=2~1(sT+- zMIotfy?O}LlQwObZ6A5)-Osu4rsJ=D&0l}_3%)~hCa4tTx>P*%j0FZCN&p4X4UANd zH5#a5P*Tf@o5&$R3GT#EvUa23-}N2OZI{FEzVziU`jO{ddEVLc*|Zr=x|F>L69e6L z?8H3#p2?U}U&jKL#Q>&?F#3=)xbIp-!+esm%&1lgyRQ6V&n!~$#r5+6wo!LxGB4n6 z)yp;PdzRbH`9_vtXpO`ur4bl6lIKbRKJTn)+lf#k1T969a`F*qNmMndyPClS zL~b>ead%Z`c2HK%7F>fT$B;In`^`h0<46c{f;{ za15xkdhJs)XGQ&$i87Ibl~^I_VlLTPU3#YkNhCeEcg~Ou=@B{)y>nQatQ^?)j(5KE z<{NK$)B_&G?jcm7xCZ{ROliSDd~L}0UB7?bk44^lmqUO|-LvLo8?)@ivCaWk6d#4% z&!-)#nw%Z9vA+JQzy90r|K9I;;6v^o%1FiP##>e|=bSTkfD{0E&!iQ2=3A`idf%*!>n4dmez3NSsdlY86m76z)<_xB*ID z9O7(ovKR>L~;{`X*TtKuEyfF{oF@9 zaC!5{$3OgG36%R;lw#M#&Oq(cj%n?U;iYID^!=)2s$h9tbdVwJc15 zqR+qS8BcuFqaN{xfBKIf`{J$Ej{ClwOxjtO+IBQq8XrHoap%cRgwal$*B}J$|UVWEiEl}?! z)oG;Wo>h~Y)w>ANq8E@tO(CA&H%~cx>a|#8*AiQ^X$CASX4$qfZF$&q-hyl? zb!xrASUd!02{FWWoZP#F-eRXbQ%pNOabo6)S_$G{r68e+L9@E$Za!sL6Jv;>)bq^5 zflbZSi8**24Ki#hatMX1qBr!$b460#%9v(sCtmN+D}%(`CnJHHB9aRalWdqxNN50+EP1CK4BS244H_Ckr_q=Az;YYsS&T7 zco#WqyZJY3rg)GJ1unp987NRrRzjE9Njqaqd)n=2R-D$ zeMXe%FhZR;DlBl1t$h3=AN%Ze|M5FN^=*VS1a|g3je&W2kA+x^9a;pv62N#T?E8R| z64@Z+Der1WtL$Z-&mg)Xm(f@x&SqVGeXE6AiSf0;teW%|r<_4340fVZw;$oukDJ)% z%p$6pLA`oxJZSf<$3Ns(Ui!)#K7YgI7oIbgU_|V5b_K664*p-);VD1JH4#f51)NHb(G+fhS zvR&YxS3yf{w6m%?A*UF541!uWN7BGZ#ZlSG(I}ZKv2Oh6w>;zL|Lj%m>hj$$xG<&M z#85h}%PDSVMC67Hkh3_55SU`1tYl6^!f=4hy*H<9OF>{Bn3MKq+{9?JInDcTefGDo zj9>Dq*Zs_kUU>fMsGm*E(OVe*?PqX z0IqCaJ#lGw;<1A>dQtvRUHTw%kAgarmXZEdd#rTM&BTbirRJ+LrCt?Qoj zn8(Ft{O7NF^{@Q?OMmVMzVGbQR-hf6z^qm*=(&ujD@wG%CZh1eK4d=5LQGN$kHQd0 z*&yUj$OK|ir@*mKI?F!q63kad%tE~l(3S%xU}h47XK*%`Q3N9=Bl9RuKmd$%6rGWX zi83AAoJTlu;$}4O&77JjmJ>6ZWtNcDK@Af#!$>V@c0*(@PICsBGqVzhTe>Ax=}ddG zPCX@`J9?ws(V>j0D3L_n0|$W2G%!3T zHJdppc+0H`U{N9wqgJ>f2y-OjGR=`04Duvp>}087%|PTP3sk{}jh(CQs2Y)GIFY*b zPC5IE&d*Bw{_|5ezW=(9J^t#)oN@S2RU8A05fEk7xx3q(LGV~rI1A`tCzyZzM?j4< zyO14n0%^{KoaR$=RyCCNY|{ZS-Bm0sa1#fZvg-Ngop;{3=Q)gtiY0Q%$w?UCzU#xN zdC5y(`J87w{@|X*=gCa7!5rk7+eutmGYYbk_U;OXPEIyRbO?2`>d-Y)#Xw%BrMuJ= zzw*7#08E!x##@`GC}k2KKDrl!$qG=o69iNfb!H)RB@5DQ9zC)$Y9ZwArkM%EZcd~W z#V$Q}&qas!zVn**Ty*|-HnFjs=RH~07=mUkpbdze+1*f!BEO?Zm2gga>g0OrRLF0?;R{c`>OT7>(x)jr25#E%@;r$(Yy>H@?8wP!0Vozc&8Yx2 zBwpvF!iZc9S{qf|IckLTsra*Sj6oG(F;#PoO$4iTCw}akp79HR@v`s!@tZiXkTFzV|q4)*{ck_3!-F zr;JzPZ~wu|f9J(NdT0_Yr!a>64%Q)Why`*(A2f+zaID3P6a>tq5F(GO-x5 zi$iOx6)6*!0d5XmV1&b7vAX07v`B-ccc889jg}j-%p3`np(O+vh{#sg*0yK)_{q&P z_b-Wv#CD!Mv?0c*{rqtcyZ@p6`+w(uz2e7y=2u_*)8F^N%P;A-H-$w+)IDXF5EyP+ znv_aKP-GD(UjC$1dyo(Vu``c%!xm7bpFYc{b#oI`l;VE$L%>B%W=!%%wtbcDLMjk z8TBQCNF+?cK@_ku?nnZ2Ad#Z~sagv-il2{z-MNqqX5=moVGh!a;wW+>#oQg7;XU$P z(_GVbP8&I&%DUd?6J0*hr<3YO40mMQnZprnk0Tz>yq@iprj3+Nsh-SOPjoEHachqz zIhvb0HQr(24v%+gd%`B`eY2hO>fyCFUHh(MTeGVl`zR~sAJOeXD>Y*hQ-j@pnj^un_mvwd2`u`SO?cAJ~_j98gncB2T2*5T>0r ztj~DTBj5MF4_^P36A0sCUBdwC{z28dpa_N4$ZaqTAD{-@MUaEt{Rlqz57xiIxNYP5 z#;G2@vA(UF+xNQUJQ4v%aV4@uKoCaJ5-Gvq0xP%A$cJBMwWY<1opsShdhuVOB1Pxm z&A44&GmhCD*?1rn6`@l_17_OS<`=)_De_%JK%hXEG|#8EaWn{ODG<-uua|+19*E+8;W! zj5POdwi0abh$4lyotU#yFb?WYP!UVkXD_$6RHRn2kz_Pi=_&9mEG3?pw*m=7OcvM# zS&#$eNGW;_mPD1!wBjt}<}A@^Cj(SMW>>fkpq*0@?N&qRVvUr|R8`2`av&WwSZdHx zp0F;lM^{%jB1Gwdxl6~Gv(Mq%?sG+U?=?^RG|iYpwh&ICU8iOpaRahVG;^9|O{%?W zGB~?gB4}3Y`gG{@{moK*_20Z@-+}!Pe9(PKf|)Pi3=DNCV5Bql3=WHc_`e}Q|NY0} z=k5H9ds6BWT%!8IKe^i1?fTY|nPR}QO_uFw~WQUn&NNiRQIR(_+h=mRm3-+xXKU@o6KNHE@^smW_fxj2x9--&kL9n@phn6Q50RB|`Ai!VOw ztaA<~C^Naum~#Olxk%C$7FP9kpomh*y~>Q(os|X$7UwFWcLRalDU;-;X;$`z(HIOM zld8apU6_(7Hxk6p-?QhNANYV*|G^&qxzSGvR88EBYT9p(rmkycxM-m{)|^v>g-`P{9|Xw(Q##^Zel4&8d>`1&+S+Z3ft zk+(aQ{<{GRt2eoV>wuRbj5R(~vYoI<0svH0*~>o?h+w4^mDDC-^qJ3pfn;2qDr5GoT791uy}{BCFM{k5O_$%o$m{xAE>zx&1C{FB?a)JNm2 z8VC$_6A&kLrO;*cpbT=i;3lqZq`)K+Krva|PP{S0M&hj;=GM#+s2RoaIJR-zGHeUB zA-3Hho3rsK`FK0W?OtZN*~;z7#K$|@Na)o2Y(`L~US#gPk+f%WbbD6m%+r@o-y7DN zG~w>F{mtG3&3MAIe%5!}}f1CAhn(nZi7Z1P%mthvuC7-rTaGGn#^r_s*Wd zC4^fUdV`Q6TiTtbCx1Bs9fgNp-!g;+Qc1(7JygwTxI zHUtl%dnQ&Kx(8+f7l2Ngyo}~{p|oe*T=&sW+s&qoj*cc3RD!P;3>5 z7-kaV$3OX>AO6?({m6GcBT{J;GB>iU1jLn9jK{;s;s5i88X}`Dd;teZ!~oHHY5k}f zJsS<3fDSikKK;=C&0|NzGN~7Ida=bzE-|$Al~UhP=Y_$hTl0;RE6d|5Mg^htZJGh1 zPUaq9PrCY%|MqY1Ixhac9p=7K2!!t2_ajC{e{n9WZjMjcxU(l>?kZR z3WqUy+s36mnV`sKop=^1EtTy&fkR01?W^y5pR4bE{-3|>WjdP719zIt-JK*#_6#ch za1571xCj}Og3XGGz4#j|siV)DwIJ>wKmrG5SB=bhwsqRt^7nq%cfR|BA4D8WXhwl2 zO;}zU&AJ(vQRxF)RdRspV&bK5v;eJ(MFk(M!m74sI4iue0A5dy0Tn9Pb-@hR_N;vN zi(lHDc@eXgsfzBd4i3%g@+63DZ?CH+4(!YX7t00M(d3>zPy11j7yrNyec$uH=fj`8 z{`-IYe|+row@R}-uzh4C#NwbJAyOT0ZJw*OBufT$=5zJrLZN9!P1AB4K*;R>jb7pt7ygf`1{SI*gJ1HJzj*KiF23It=jZKh*X)3kyQ!Nud-hw1WV(1i1r(?W zJ`KQEDduQ#1Qw>NWN(9)V+mwBAVa3?4p*@5Tbpd0JVu&_{yg|FF{oU7t{0*5hKq{q zi8<5O_BMe;qPx3VNh1f1 zNjW=<$8r|L1Tb0Vs*)*2a5QDGFFY<=U2a$$d`EQn0-Kj7Qw>qNVWe zx4lidnJLVBv);27AB$AFJu9$C!ljwB{u=5kQb%&{vzwOl2c_C;C`1V?+^4NeFFp5O z_rB-xlgGz_mRnw1U6SaxAGx!e^*;19Ri}qqtPYjc?rS?FD^&+T(4paf(EXH@hVF6` z058HR@-T`X+na7bN-UMWBPJp(pk1oK2@Hb6Vcg(aAhMnI^~k$=vpAc1y=odm@Dmi*soci@En^onr=UWtnH1 zJ8x)MPotxGe6(**&LJ`is!L*f8lFU1+PfDbU6+zNIH++cC(Xp2oh3Q47E|PGK=19z zuDxv=Kc1rFk@98DpktY%#o*}{k#q`lDPNfXDSxgQC2F|`wqtuIeZ9DRq|r^_d7 zWoB)!J+V(hT8nzx60dPTfg(l??TJo4bIiWFX>O!SATLdzN~G?4RwmB*gYUoY{4)+b zmoXO0=WIybw6!4SF^3hw{@W9RAR=rlD|F!xCr+y*%{>q=8~N+}M{ z@p>t1aXiTEKmd4Qra0hO>Ot_KPk;Ph-}Ua-{PC~l=@i=MWW_lG?9#SAS}`u#TQ0c$ zU8;cU0`2VX6+_V~wzk@!H>7T*ny+M?s}%~{ED6)Twbku;+TPZseN8!R+^i7P|J!wO zFI+7-gO1;MbUYfxAf5N*PU7ZT-jFe+Y%-1xj77ic$yfdHYu<3x!ybOd@;GanERF8? z>a9!hOvK1i7ePToXy}ouMGpWtW226j=Qx2vrN4f3jbtP^R`xs_XNWdM{rz#w&z3<~2t*|z(X$(#eI zjIrcqrZx)LIQi9Yef%T;#euk_kz=eLsmFk z1VswzL;Hi5yc$(7yzua)1q-yhvR)AOi!-2RVHM>h25CO+@R^_a^7WUU|1cuW#gLK^ zW6a$&N(f!f(8);GIAa5 z6yOmg*(t+k4uBeq)VY~@&Kkpc1XPH(eBTNkGw1~cYaM$&CaLUwtAWZnZ&><0kH`N$wY-duk*pm^{zle zS+z_qfI$VsT6hWvJE_+mVgmw`Iwj-sVq`AF#KEC%h{8@yhQ&NxTN_VWb zst?nXr=7NT;PCQ%-Zko7+zJhaQHU*4#w?{3H+H9HoV8zDqP69IMfx@}@(ejS5z%(r zj?+rBZ#+IV^I7MeSx(lgtGN=++OziAPksK&H{blsr#@xR+A1-5?Fk(+;L=HBIpofz zbq_^-jJps3C0oLrnJKm{OBBW8D1b$3>^z>nv5vGdzf1wQ7ua0P#k@-Dv3bs0aspj-Zk(4xA%SESxJ1Z~oO8+9fVTwo(wFb*3IbUuxf-)F8y6P3tVD7UC1-MP zj3&f@LY$dQ4d&#=AS26NYDarEyLn62L|$86JAQJb%Vtt2l~SW&u!1jZb1|vA%EKI7 zOg-VH)+p9_R@6S&y~D~uSu#&5JdB9P#Iv9E)YZwV zZcbZbg=H96QV$VujM?EvPLhEPfw~);Va~2Z(IF19AOvISjogF7TNp~uizy_4P1ObF zDRZ)3c{@@PnI&&Hx_TsKHdR&@<@T0sKe9DHF!4DPT)Vzw!P?3m2iH=I*v$xLPJQ;N z@|K1z4ci>%O6sAQU{oa1C?yS4=Gjxpg$qgxE5fW|PgflpiZy)Hq9k=ESF#+4&E1GI zM3XWaR$|w-F>@u0*@Tm~(v0A2+WP#^Qh#U_`^PDax6O$rc?Qfg!q|W;>=eTCWPfIM zu!{nnpx-m;_L5H~Q;9MPZh1!F>=Q?mr7>4YiAB#@9i2_xRLNx0W2wvDb>hig^J%B8 z{q|cvu-*HU9{)Hd86xmvjR61{oO|TCw<|rw!* zL9+oQA*%JlOhhSV+9d*|x?zWNV9~s=Kr`H#+0+1h`m>+;kN5oBKfdC3TLzgLSY6Q1 zg<&CL&mLn!5$3xYsHVLGEJd|hlS=yzL8_dd=Wv&5X

f!Q9DUxj4bXl-$!ilkw`x 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

(4!xT-WoE6XLA;IxCl#G15{veDl@+e(A+D} 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 z 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%0A2vkc8=rksiA9Cmr87zuMR}|zZ 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≠%H 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 KMNUMnLSTaEbe#YI literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/samples/ref.png b/extensions-builtin/sd_forge_controlnet/samples/ref.png new file mode 100644 index 0000000000000000000000000000000000000000..e5461fd578c85695b0c2ebd8136e8637e504f787 GIT binary patch literal 620406 zcmb5WQ+Q=f7d6^QN8Pb)+u0r4w$rh-V|Q$u9oyWoZQI66QE zrKcU1_j4%H6;m-%L^3IMx9dEoFUC{o7FtX7GM1k)u$l?orP-qLoQqXSm2 zBOCqp>KEyTGS!OhvbXlrw~oml5wwla{};HX60gj{{a;={FU3QXn)Ck;x<;{olm1^m zaMd7*$^ZPnV6cRUV& z{{MD<`Ttm9DZUs1-e98b8zwHcfMRJ^3eS3O`}c(}=1q|$!xc-fbC9fsg}PIxA__lH zlGhd?$aA})zaszJw`vmgr8VM7rKR%I4wK1KS`&Svn#}#AZ~xy=+bFAzK8!K3Q~gcy zLRDKs>sQxjWmafn6C{gOEsEzYQ`TCrPJPI4#BXTs8AV?0c7lVv8inMFb%j6F~y|w3I4afHV9LVBk&*2YJn3g@*oLAMjfTF~kHD_iT@kd9zM*mQHP>1y@Y3>Uh) z=`0%&e*P|Sw`azE6UQ#sq8EgZ`y6%Kai?yO&-+AV^G@{P#j;5v4Q9ppTGaB5NVVH% z22uG~@(}^*qu9J>Iai*y0;>`V>9@|g;JM^hSn8So+8yyyP~Vi-5=>Zm?3m%T0?U0r z&(|M{u{qj_^|D)McU=WupT9pxUeJD$Z3B<+tOVfYGBXBjwIFfR|_xHdE8iADuxh{AC+LD5g z?e~2_wY-FEM+^a#v;R(}FS^iErsJs#Et|jN91%$p;a4&@YzI2M;W}KCJ^7sHjvtr! z)+1iPAdF7e%cAC+fpEKWzRSs~?#xBq02e(c5^&q*+gsMfRwvrXRa1;`CY z!X-ZXfQ<@$02` zIV=RO`{3AUdpU0Q>ya$Zd$*krgkME<)I%EDHh=mke{e2pZBh|hC8+sJC+iU)63V>D z1)~c!7oTlx&pU}H@27P7uFd!g!d8b5Ir~}DNm{|JWw4GnI{mHl1%=)~U~qe(X|VT9 zl{lJ~%e)%~+Wl6CR%N$aFpo#w(VB~{N9Ft8*{)n=cVLlT(8cSXZVlPnz5DWUv)@W{ zWae3uo?i_gxc#F;>*JeR#?!|6QX6mj0r-i1F-qm_p-o4NkD$m)@FLTC+n7fSACYlX zToNt6M70J1;#f8}Cf?znd3}wQceweXfI4#u^)G$Q)zD-=IUm#=z&C=cy7{~}0h6ZQ zNE{W9=pBy_*#m0Na|*jJ6X` z&E~}Z>#;mwyl=@~FS7BX>lmIOZMeawk3AGsT^x&d@7e$}n4cdnf*J026%(r35vLuO zrjOyXRsGqZ{W0f@2f4u!Ij+_Rfvt>5FUX6>;7Nn?Cf)((qb1AEi0_*o=pC1LQUZ5* z!wYyXK}_0S+c=l(4QQr%o=6=YwXa?{%|HaW$5(IT9|#27XFE;y%UFZk9yb#X?5A{` zhZ$1#qw`&@YI?q#1RwQvri)=bt)6H$fYXX*2b@(8WYugJ?iG$#D)^3DU0S|3THKeZ z$mTcXn;+>E?B}1gUk{Y75|2r$SJoE?)qDsjX6k;4HNK`tmCGNmRl&AkCSZZQbD_8*3_53^s9Jg*WyCo=PS8GZk{pt%z#(gMXl&Hplv?nyO2 z$9e9unZCiO2`e_2QiHduxFYPbC(XbG0OPRj)V2J*C*A(N#dbHIpczq*2zl#y{*i^( z0!tOI4nCR}hL(T?X3zin;EG`TyU&|-xzlFl+XIx{JCkAaKF{Ko^Ybd+DdYQ~RE-RJ zS+I{Uf+rZ>?X+NVcd$r1LWQD*z+{WG>gk!wei`Ao)#>s5jiBrFL1(+86D=684Py5c z+;v`l(t>}Q)do#L;Kh9zNx*$W%3^(yYCBN#)n#j>uIkXxezlwMrgt0I@#a(*!m4&XQZhUE&6pI>M~17Jl5?e zecP_4_N7|3No(D~$j#N~pH|zjxLABaSK~tJQ=Ps9ujmuXY#6o%k48 z%t8BL4>`Zex9+D2)hU+=)z>O6yOlw;?Szg_TLK*W(Zh^$lbf@%6$ZIM0d73z{Ct9q-E*T?_Slv5T&&Wj-#CtLSFK z-gnM7rR+X2`e(w9yL-9q&lzD-6MT^8IFo~?m9GHZmu-e^nvXjx&yRG1-a1c<<(of~ zY0eM2ai|dAG3ZR<99x(o$FTQlxg++xm+o6N8hfim^ zhJ!vEA*-Ej*ruzp0(b+f7xSE^Y=C$maT=V7Z zKPRs6wOn6i+ry_E7E2R?pI$CDt_XwlUPNK^_|CrIx=oRKdmsMLj>Kzl>4v7hQ{j{o zdN_7k@s3Y1o2>pVy`(CiDx`O4*xZ2>{g%t%v;BtW@^DjgOGuo#?!^uAZrVrx0S)cS zs~&9oKK{gccf_$Z*ZGc4?tMt>dEk>V;e*9>LMt(Dznj>6$up>L1*K53dn~J)bUx=9 zabBP5ct4<1_LCpP)e(8IQHL}d-2yE}pC9wQTVpZtvmEqvd;vmB_PU*I_PA=b8}D2X zO0R7HL_zD>2#lAZF`S3;xWAg1P11L0xv_#W#L@c58@-C9@d>JN@q*lZ8g{W;7a26P zGPR{6)Hkh3Ckr|4@cbWLd=vjno|=A4O4&)iXlA%C*>hfFn#Gt@a$1+^>{vl^0F}n>^X^GJn?b2bSVG^q8)y zk)mTm!o=eNhV5&={~>=Sc7yRnwcQgf4uhk_s(u(wYz$oo`lOFDPuz!R6#J9ZMZ@!3 zT3s7Q=w2flX9WZ27i+%WzBax-w9PiSkN57sgfJ4#%Q7C?`)Iwm^_2oIFz3zlwLM zHzgy3--b>MYn;4MF77>9Zl^Gv*T3$gOASdg$OV^`K)n;*1#tM$6=-aw;nNhLP0xil znx&#rkAjJ9NQUxjUateGYzNBz<-z4Vfg<}#^vvU9pY!ByLc-@Qlyi56K;IK1J=Et7 zX`!#oZbU4KQdxFXt$gZ&0yL#k&|wfn(fax0@UUwHg?`2(J9_qglfz*Daq@EA_S0tD z?q_Lw0Pe-q4xOP`X1L1B`3c-#H8X~;n)P5z-{`yoOIKZg360z6htEhuu`LaeUoW*J=ixMUi_O6q4Wm6zPrfrM%kVZv!56IxqSZJ{rQ~{_g}I> z$6ogUciR;@ahU6J`Jrln4m^qS@lGhq zc@y4z@yPyj-0ATu52wka6f4J@llML|+hER%OF66S19Z(`hgFuk@XPbNU5|Nock9Q& zo8pmq(BlDukKcDbXC`p#sSxgr#L{)w;#Fv8%a=`$Yq!RmVavEsJ0{A+OZR?9{Ew|Fdh z*~M)dg16>?CB07UWV|be$E88r0WS<^-}|qRS1rRa@vMaU4BctA+R+zyS45t-101_~ za8078#-_C$ky7s`np1^?i{7q3d7U>pcPAbi)*U*(^64R*!OCg!TzBpsw60+d;oJUY zrA(K=1Clp7cImOfnu}J*&2C zBq>>0GF0CG#yq;DKHp;5yE+CaF^xlxbq(ztinq!IrY7mTTJYF_PR#>ZliDE%>B0Kr z)(GG@!JEA@n*p@&jzIs9JxG@drh0;wua?ge($wzPBg_Lnj#cR2Q(+Ev&pz(pUZ=fG zcgt}s)Iq+~JXKvD^n4h-dR}m{Z|OQ_)mc9K3c>p2Ph;L#TJ{jC3xnCqdR(76O*a-y zFGe*^4*%|EFrcmS27KWVw(g;t$nLYEd0fe5dsLcqg9<(ltQI?M2JyKWxa_$rn~$rQ zZd03fP&$7?NI|Vv1#O0WXW+xNNAw9>z{Ovo^(C~t~}!{&HMT; z_m#nOAxHCdbQC*ude~F)I-XP5|Fr3AoqVMQUv=_6F~2?vk$HlbzF(5P_j_ElyLc4xXM-R{pxvT?YUiMJ8<~%x@mv-@mJl}9~$lx z>yN9c?fU7^ZTu58s7{}@kv7QXSv74(*Lxb6emvrPMeXc-{~V!~^b0^G*re2Eo_yuE z^z7@K8SE8>nT7#t`T6aKLJ?fZJEZvM;G`igf7Gg>(q2wZX`= zff`puS)Zu1J_>xosIG$sGV03_k9GR;MCxSvhohhS>v3NK&yIj^v_Y$#kK4Wfv33?5 z(HPIxe&F9AU9oCeO4S42tZiyDqw|Rh1THcbu9BA7RA6R;yP;4 z8!S-&NnC`}P~5z$?Lz2sZr^mI3yHG|d9I29zQru|UBwUquK=cO;srSeB~HZWDTz4VaC4D~In{EgK;Y{>}UDfykd)E&D5b zA>*LQQ1X_=*RjWHoGhb)EQ_2XS;4sW#Ebb+`OXQWOp;(Pw1@c?4~y20VeJpB2R);b zc0lLBWaxSZt7nC*MfEQr6qpeoAzi|ynmM4OMQ>*EHkUVtH#!~`GU!nMmifV7_2YRe`K zvLsyp+MfK*%d9R~f!w;=1xQ@iX}-b9>a=ztx$USu-3;UUv(uqEI!9r==t73S$z9YT zIqd)}+#kq(uAQEkIy18ANXug8j`Nm&dIspxM43n7Jfje&DS#nWa&WG&WS>7v!;KEg#_oj6(CuV@yPE)?T30LA*Z8;mqEaj^XtuVwdaM)@X-}W~P&N6IeD%H=yu?jvMiqenOz-#5mX+6>OoJQvha4&u#X z!TeP$c{5m@8Q($rvTG$UyHhg!Ly6Ai;uhZpPqWG>_6Yl~c8n(rXU)fmWX;pXM|wTb z3_s?nR7Iz=HPB$4xbW{*Yxf|)DKf9di0g2GA(w5oK!niC*4zvQz;MSBi)H+fxPbbQ z&sBfAfI1G;)Y9P~N|Sk@v}4Z|vP5igCI*O|t)Sniix{{ZVLJjAW!dkms9*Z2Mn(3{);u+9h0>~4YLLY zEvFM@Va?*;;S*HB3*HHe z&JQK3Ml_|yZa*an*V4PnUhO1IA{zkbI&Ms1vBgZ2 zGXnpZ5@%3?@@I zbmxuB)0_WEdE7h3|8)Vn`cs;lw#zh3Y;2&S^y^&F2G!o6L7%#!^cuK>h>7moBrztC z6CRE$F*J(9&^pw+MIdfA=Bx~{K$oo9pqCv5MQEEmF>lKNfU88HXnX@Xt%7}JV%Ngi zYFisA)pR(=iQtkBfOY#hTb$M~uzLCeChgzI$_=gEa|tc~TED=fpj~R|NZ1GjToR0b-OrNy8Dt<(jEO#q^SF z_UywVwV>@r=EOKf1{9b$Mxq_jE`Tb3f$*C!M2XXzoN(;^ZVEpk6n$K$sbjQ_RfrWK zB9ep=WTb8U$`S6O1)0HhuCTU}K}-WPIg|sLROk@hccDIreMgENzUtEy4yKxt-)!ml zgMI~2zqWVYYTQN-GP8WnhwsE!JNIe|yipzab(Bu=Y@CXRiO38%8zs^Ge6o!NJ*(?v zFCvNY2kGx@Ggv;0%?5NGvhBPoZcevFt?8p&C7TGgA;O>wNt8yg!!eUnrECo!xAkDM zD0GkhZubE3lS2G8N<8C3Fk{JyRF>9!?ZGAC+R*dd@$aN@5d&+m_SVcqt#Bx#NL4CWj5LJoDxu4K0+`6aAap@_ zP=>b_j}-w9iD`wNIIW~Y&}teIDdp2PD6Y(lrS@~2e5VK~f(t3mh(Rff%FM~AE^KMI zSQu|vG)`173b{l(4m_UNx9uis80RzRZAzz4#G+(MLA{Y7H=*A{Md7RO zu!`QZuZpO|DWNN3lHNz)rjNBkop#Cf+}!? zpT`(&Hb%8>{QlhT*{xXrIz6~cS$XChxCcPr4BUI@-q?;l=A~fkQJfA7_jmA5oN6ru zT8S_9INv#&y#~QFNn=;-<$mDsxCA0JImi+t)@_K2PW0h1uoE2_kvSY*io)NCBrkk& z1ybgjLLwDZewY^o3WGZNz6?QTJdY1Dx8u&su`;_IF%RgyIsZa`1tq8AgNQw@9Cm71oc`SO3kLdXF zsS1!PEKi?_C}x^*@3OwKA{^U~PZoM9muu*%c6U7)&W!u_BZBNvXkA*T@m6lWG@W8Q$x59-NSSl zp)gI&tqhK>|D=SSapLm#aLcgc$>X&+4Bx7RETaBud1f<~fQ9F&OK5Tp7%XRR7kJg@ ziM#EM`WjYl)`*F|yd&9iG(mbYjMjElzkn_SsNu3Mai)D;;kdYK zY8EQ4K$y48VfH*~#S2{!6K+Jcoj^eBXJTOzR-D|3vKZ4nTq0Gr7AXY+q>}WK-QhQN zbc4LPkpWQrps)pGSZY2*V{+;Ywd1rjuK;wUp(2Yezt zWsrCjPnpXK`gkEFLs{sp%L1D;x3n~hJwc9YZ8>e3+M0*95A(6;L@v@D2^E&Pr=(+C zT(Mf}lG6ndv8zQ{|G?(EpNb*ykgmUPZ!Ce9^9R5bTN|BTCCT>FHc&aWrCZ2rv}uoAqDZDOOxUQW zlC*D=i7LJZJ7rj!#yMJCLY3$RjDfE;RILmxlB1TuXYdsXrpEf!BXEdaQZ`nSJ~RN8 zwUn@6yiywGXWCo2Szt_axni`4^$2O@CZg|@qx@>0PmcFcAT5fZ#z#^pGOuC*BNap_ zBUz&1;+@Az>>(^43pYS6zxvdbIZ(MQrs@!eZjwaPYhWr|8k43ir!TRbLUG3giSt?D zpdk4JE7cOwLp>(GZP%bN^+IcaU>m^7-C|U9u$crGZE!s-7B-(*hCLH*W$abvWkeE> zVe+ZPUjDZJ_%2#yC*j=BIaO`Rgj*~igyt+h(vhy@Jitm8(-tG7t-vW`B#n$~7{~V3 zw3clkzG5Tl=uMr7FmMm8c4an+nPMM{Ast^-SF-JPO9d6TG=>ht5JknPnsX)xbdg_H_763?L%g3*Mj<}f)6J?g@m0@s|}MZ z&jS$MK$tau?lhtiN1U(~=Q3tm#x2&L@4Q*TT=9`gd*1$X3ygeF32jBDrl2bt)mC@} zx{NE_3_5NK3HPpU8qhQjN7O~s{Xd!8Gv}#+N!0d23Z^~$OQQ$xr*Jlp7L9*27U6%` zNS;vA1wQE|qAj}JT&P5uK1W)z?^v(a;kUB(en`mgB|s+nT`8r+=mZr50-}_BPf!J( zbD`O3_WGW1Mjq|R6x}}Vv&4p4i47wsEo^BY02V+cg9Bck9-98O?u%$6A(4Rzdok87 zgfrSkoQM{y-$*wC2m7nQj-42-bUy$lqxP840bjD56s93iof6(~;nLmyzHLTSoCPNF zTT{U~J#L-g$mQZ%ybd6cPU@&O`}7R4rGq$;5)hwWj z2`IwN0}JQ$ju^ZTw_x}~6=0?jLgG@<7z7$TakL-t6<;&4aH)hvg)d-hXOzZHW{%XL zGdZkWA8Y0d5if}ote0x|)PG#Ct5q3k>=Gr)BG#V7=q6vKC~ng8tJ{&6SU_q|zlA+c zGe|rG8%gXdl&*I#3L)d7d9O?8I9q49()m}a#pCO9{RNK5my z6YS6QEogsIofJp1mP?eA!Xp*r4@epP&^(8x3p*ckH`2@!lV(Tk7Pg=uXN^>&9+eW7 z1I0n8CPuL){)peh6_hJIrZxUnTs(2a4PuTils6Z^Gq{-dAfAcOL7Ef;2#Y8SIxGo7 zK~8>o-1H#ta_{M-*7$mrswDgUmr5cQRX25*H1Qm=YqXcgsmv_Z&9Z$#Y-!LbL(BV&s)WP2^pXwd;?;St5p z>bIvZKgzXP7Y%<|Gx4eGh};I3Dk+h!B>(KeD-GaULpi$h*U{8mV9Bx`0|ro^3Q>wk$c>_uwckF zDXXeVC9?}vTgpIzC7rD}BTS%pe?%=zo;GsZ%1pdytOA#n@!Ie`@-NzewESN+Y4rR( z`7+rKN*lAs&EEMkNG?|)R+XRe52btZvr8q>tJw_soO#;_r|&{!t-6h`|2Zi?OhAfAe%8|vd-GGT2;@s zb+_;$a@tQN!a-pDa8S*3u)t_s4^je89b%ps%1XpQ|JLJHq79R&A@<`(Yc1!t{eUgl z{>GB#Ul)oOm!D5q(3-V2K4$$lirtm>=PTxFZ&2!a| zq-A(vdp(f`)pZ)QhXzTwV{~&ADi6q!+y&g?kdaXFFB3T>r4`%m0kYVJH;xzuKRFRh z&Ttp&6yA zKL`B!CD>(@a26q|H%*=DUD^|&5j{w&RK^q=(F{NRn*(JD_V6bma0g^JQ3%9IuLJS+ zbvb6J$gyP3R4!y9My#lGuKY$L)o5w_&>@~YREDa$iHC4)zzBA|j)x}d`%zRGf><%= zl)_j-3{form&73-X$FYNTic-L8&v*5D#vgj+bgx9nlWf!<4rm^^x=UoWhRC>gaZ z8AQcMNlVSVyaz{<0a04&YaVx|@lS4(xUw||!`UHD+KqTdK~@l#1X(mb&1+jv!cdO7 zgcAvMk+jlJR}pGJDc0;9_5t?yPzG3PGUWt9e}s~S_Zt`lFX;9|p1+xHziPy9D8bT} zLl#60f(*h+`i?p)#B86VV@s{gc?UvmsHa*glNG8Gn=jPi4xfW(Y3TrDBB^2~; zd8MHPQQU1873nAK3{r2Q;PA;>Eex*JOsn_{!0+5tmKaRa{4v|jeERd+XIlp3VYk)ay3 zCHW3yWI2gWzT!Y;p#_-Rjn{*iX`q`!O}Zq!2DrB}CJQ$QH{4+InbDd&%=n9OnrP2q zpG{-IW?$CGqf%?cisne7)QzUH52Yebm;20Ae4pr{Ji{Rw0~;EJ(7AIyNSo|~#L)}e z8-A*-KpZ0eID_N818C*GgA@@lZuQRdo*wLk(t}Ex1#27bcI%isagssnclKiST@1Oa zG!2!q2VAj4*HSfi@}`9fLB5|~_;hdsd-#*!`AKY9Fv6&34fT$WM=NwHf<#Vy zlw2+8t^mGTgwRJ0Zv@t4xM~8PfAt7=2hGgn%lu#I}^+2J^Q%GaWI3YQa;m(>iO^p`1}%P$M~X)BvA&YY@;yKq6@XDB*Z z6Sv8~W5ggG)gs50ag)fQU{!va=504f3OJ-|!jlNx<*?7wzRA)g5_8*?fY}_TSjc5} z-r5j|Q-oK9twDhOr*JnJCxkMS&nM!1YXepCZ^bU-3t{c#p$-8SyxU?nT>044+BgpW z$DOV@Mu|Q@D^DmnRc^*EK$8Vmlvf#pB0n>fMOv7wXy30`sz_-#5JQc%h!{W#_V>Y- z5O-BveEn0iceYb~D86Gbd`PsDBO92UE1eJ{oaG$YHKy`eIDi-&>0E-Ca0jgD2!LCy&^Gz)$nW7Xo9FLU%p@tmPAOoSwv{@*p)b$3&2%eph<557?Dt; zH%v3Qzp0mRWG&)o0o|Qojd#+nQoF5E{!kDy5^*d3m7U62l|@rera&Q5Q|uiYlN94I z3Je-jY(e-*5zD8HIW&6Cd0|GHlY84*8CQI1l#N7&dFL|N@Eg{6dTo^QkeP54QKrXSCB^D3@8GNLv7I(?M zQgE}Lqg$p)T66-rj^ZsDo{CA_oWl{vrfEJkN171ca(;|~ST4BWPPmPNDZB@ zRdv3ON)3+0aV(7jovIoPw>1gMNm?4|BHX9i_=K!(3o{m$nOG~;(8#(#i+Iy2isyDg z)SuNEgUam12APz)PBP{aie!>?%9Ub#bt~1lHL%lV+9D-T^x#>A+yvBeYsGgLi9m*Q zoLt&uQ1{#JbG`Ks0;v(5?Kv_I`+OiOZ=ye=xnPcY7_#E6Cb5X&u^4@iQqp1AWdw4T z%u^FpAk1o_v#pRXjA||2`8aoz3HwK*xVIsy-}uHMRW@vnx>M;CL|B!l#CYm){Fj$o z=z&Ao>h@i;F|O44!;B?eY!tmA`WuM4gN2}tCJMZqd=ivNQMAY@IPMgKuahYAB~f{4 zz(%^-(H*7U6hW`?y<*-;kwm-_ZaY)F;)EnzRc=LV>y3Fe0pQF2a83~5}-1`faHi1x#Z<%W(n}UV2nppa-Oh0q7Lu<$&1TJ-lKnu9 zX>-F(%NTughlvITHfN%#1jY4)!ZIRuYsm(fC9DX>9*m(H(?0dnJ-nNfC+APWml+ZE zlMp-Xwd^c8MJN|U7fisG0Yjimlyx>i*=1k1P+^3Tk(s0>)D_6ImA=c5_^aZGWGP!9 zWClVnj>l8Q|8OF1CPDU=x3s z>p8SH=eeT&dW*?Jrm=_jBprgmp>Y!z@T{1nj%|sZ8K(jt+S3Ols?O~z%OW2CECC`U znYbFw;J1Kf%f3LLXf1jYC8>%~?2c10Pf_c3Ygdjvockls3Hys5C<(iKslCVkglLzS z&)m$+3e}IIA!sp_5>~V?eT|}I0z0D~f+mM*N7*it^Fb{Ri$G>mknOeBp&-~R?pjev zAyKpyjtz4aV~!2eF)Izcr&8DkPK!?AMtT{U*)$xrQ_t5k@wf8q0#f4VGza}|fEKMk zYBDMjl*qJymV;4MinjwP^PTfy+jDhF8RK&qvslrwD%Do7$pR=B8A@^$%Ed_flM*f? z8vNMRCS?N%$#%G=*LpHISdeFm$`vQfcWFUcb?i!wP>8nvLv>Qz4Ai*@B=?oIguxkEgVPz*Oz9(7V6M=a4ZNAQA7be=`Np@aN#r``08oj~Q!dQts*EFh9jM$=;cWvV~se$6YqO&w{k8P@9XLxof zzSM%t(_1?&TzhY5mCZPTXMbeUy}`7=0ZqF!#7Ys@oE(M6rSge4m9@MX=p3NGXi7p= z5zgqSM>R=ZVJuo2_*u<%qVi zquj=pSglje#Xfqtecc}C)eIK)JOBd{`)g%^zgjCq359DsJ90V;E&=A&IfVPE3E_h2 z9E9cbtkf)S@RRh7QgMoC9{)MAap?dNxE@zZ`_H*0eTHBMBGfo(f@&$vvk+b*IS!!o zwG=F*jI>iKe}REOIb#_mQW2~)IjZ=Te*ThpXh_9Sm|y;G#)A2wufjIrLwKyFU&{@0 zehhbDeAup36dxMViJ6G;aC%A&N-soAOH_#}$Top_ZX`E?X#WqTn7D+*ld@EKTL={v z3D*Lg(ZtJXeKB)u_dyU)e-&;lods%s`!nu!n$VTS!}E!go=_Q6|3ot)Y%c9BJtUGe zZxPNc!U^FF0hEqbkVPpz9gKpgtVad;cB6JzH{R-S!KJ?naY7hbBI{>tP(TJs6=|53 zGxKUGZJzvtFs{V)-+(i!Ojtu0yvk6+Nd!o1_r}Rk0n5Y&H$A?qPYFOy?%aU!a8l(tJaf=K8I!-i(^gV%??qt9B43q{0hdV-J zN#*D5v!W&mX~W>2NZrf^_lv5+#E1jgEig(1hk{2|h}SlHg5lzOWwP9*X=N$U27fM4 zU-FKjyA!CwCJ|n{GxnNOi<3#{fdm~;t#>_@{0*wguTce!5e z`7S^|RD7aC+kE3yp%n2ZFf2|us%T=2t>IHVU5s0%yGkmWLGcl^+*#ME+p$`SLpH|w zeP8n!S8wZQ#fH`3d`o&!=;O(v2{s=8LPVl33892E<}|J>k!b?3GAlzPfz`}C$&!_- zusXKk)GSg3L=FT&Xi?I$Ggn3*T<9t;o+3){Lyd~`BM!vu>vvjssK5z#qJp@TSo+tc zW$IGuiCBm=mD-nXXJ6{5_^^bt2oEx{nq}?FsI$7dbX1tGClfA3=xCtuDUaLucEmxp z9Et+%PbI6aCxREK$xH2P3q=i@jyGv;QAvJmIbusB60(xxi_|#JP%xx}eG4}OY96m; z2!(XTX8Tn-(F*PEuvYv0P`opGnxJnb8Bp|C%mpNU7EGaRo~EGu1r9&HfNZ0fRT5h2 z%U6DAB#x9juGhd(X=C=Gx0>SP<7+|OM{+LGUY6lXS1xg60tQ>*jid1{MbbL#C;;}= zlNvetviYtEXA6!mQ!ICCu^!zS5@?rHqZ60VGcKrG`OnUXX6QW@?{C%j-@0#mUuf=U zJDKgJ_=)2`m;0hzgTkY6n4^I7)Ss&8LQcJXCSy5A`WKwrCl$G7lC8P0eYEL)~wiGlcmxd~E+AUF16hutb$E_g7D^dwB znV~F?kLfhH5NmCtZ)Wznk@rr@u?2=4o63qiLWdgMf%8{N5=Mi-<4p_JF%kfo49{y`UHN)-K+ND}##0e#qXQA86Y zYUxFGM{xlmP3v!sEy@9sl_`ai^cwcO#IQv!QLXmT8V=>uY=tT!6+4xyh4ODf#);HO z0B-zS6XF{)?jknRvgucMVT%OPg!=g~^((gRgD&4l4H*feZz}NY>M|u>ZvSBcEw~g-&mX-f$&TT)oSqB3?hnag`|VX-vuBjV@X&E zBqbqGNW+ve78G;)vZ$Djmq@>r19?YTC#ege+4dbFM4!9Owz2NrNQmkpDMFDI-Y}Ec zTLD>OwUCOTbPq&n>=;P_!?wrleP3K_T8?#ou32ViS))#ug|ic-WGIOr3UQeg~Dr`c`I4Goyl`mug)A?w@Z zswRjxu=*79Cj}Mv-n7MWb*~Fecwt)h63azlYf*L_KPC)mxWw9!Lx|;n+mE0~a71la zO!QGyj0YMO#^uK=JC#S|u_FGYmnJkGNwr9e=Z-C$7WnHazGkAfPRgh6k;TEAvXpK?E87M8*5Cnrhsh@?qFN&&OnAd+<&WJ1R8O;xC z(1wUcy{?CfJ+yfpWm=W^*|r)vZ4WFc=)XDAtU>Fs!XY{Wc3Cty)$oWecG9UPB|B)! z{8rebj>_G^)qa$U-bNRmA>ejy15t=fNi!`P(TnqHmVwfZNf;Mp5O7lQvD6ciAI24! zH^pg|lL%*WZD;J>L-g4OfjL5V0KsFRh<1K4;f$M+9VUtr3K&bx9!MPjnqR|EPT{Xj zug3J#HlnK4ESt=AXP9Emm36(W0I2&NgjGgGT%M0S9r;z`o2W{%;E+p;V3Na}h!N{W zJrz5aI^7SgvDLPZE7h2uG)?}3<~Y$WEda8M9IZbY%e714o7fZ1qxXb}0=e`YDxF7QFFV{i&l0`F3W3uMDz2O+ra+NIj4)1OIQ zuZzeNb%wLX`@6&85W+Z~(|P1{rQ@1cJ=1%i=)-%1db3%CM6`QDnBMy{Q@Pt7hnb5a znRx$`_;-Qm(gXGWpG@H`*&qxuQts{>dhjsqBSKz3ArCN zGvgY(T)Fp=545MOMvJ3W5y3cQZ$L&J?PyEq$j7Zz4oMNu_iOu^$MP-SMq!|mg*AfZ zAfpm#q#$FKF(E!AoQ15W5W#LyF2wN~z4!0+0ROocV1_$Vaf@UIaiq;|N(2rqN0O*n zM}hsulTPB1sr57!u}&JB0(rq)8AOA007C8lU95Y|DMxA#-ExM63c4%)xGq+U3BUO{ z(@;+d9cxIMlKbKpSIx+S90KIWZvT86B6Dh}tD+!bM2=COi|dMLK**dcT(E;L{b`T+ zmpL~JF_L+tA}?3ouWpc9mPE4!at@(RT^mPCEJaSj#}xpg03i6qJqHVgcIAET9{LNq zg)y?A5@S4C46pEXQLwo|7ZOz#Hni(I4 zo83!a7A`)%1h3#NSfqtit)St6gT3~CSk(^GUCewW-5uh zuOYW&>eS{+r6KWMP)y-1nSB`>8Xz;+Z%lPP2;wSJW}S!^GKh{_icj8xW2-f)zskju z7M56v>zEwf0wFaZyAWu^I`9h)lc*5Itt?ij)vqPUuo8(o=`u^eDzn%n_)$h0`;%Pf z6UUmDl$rtPg36g?L-ffI?ECt^5d~P1?Ih4U3a=C>|33hsKwiHb8Gog}@jBO>zBCC) zmB{ll+nE{Y3jp~XpnA_mE&)&N^@vJ-m+ZappZnLS)e7x}%9Ew(wpbgz9Hp{`&==xQ z>pIb<^BPlrJ#y32Hv4soq@FNdlYU^fnsi;xj zlFiIKSAWzipyhkcQ%m=o2~kQZXmTx974v5inV6Zkeeijd#ZLKRR>eSgMW@p6QYr%&0y&)soFD{t8^K%k+hLbdAZ%<%Q{+FOg9D4 zuN>E$(UR+V_YYT$DBRR=fe%r2N_Al8+d!(1Q+`HDZ%T?qR)mp) zv~0N85Ji`jYm|R3WoMEcr(CPVQfO_e>P!xMrk~XrA#&7Y65gH?Ay~1fLdc=mdEZNx z?u%FKdjR&`Z$G^1)xU#dk2ww#o1enSKn-Pbo|`Q!9vMMpZVec8CpdUNFoWs-Mr7Zn z&0DZ}Qxl8k4Px%VfmpupS-9_K_u&8D`5!DTER`y#R)~CPi*w&cTnOZwnscIwB#l(P z)o6$VNulCYoPktKQ_U2bYD~k9Z4olbPCMn#%W@ROZE_)nVLX``P7$(nrWHXFcWNGeG$c@$$qm_?Y zOQR}66ydnOUPz~#3E`FIT6AY-h?M-WO0;nf(nPA)S7O5|QYzp@fnuu6^?(^p7JH#_v+z4F+r9wV<@^PQ^B zx~RN+;lo*>N>ml871Eswr=^IQN-qw0I3<6M}x1MZ7T~xkaHB z(q*2CKCQTMWy3vDEDB|B3+OPi)l~7`S7*0M4yUZX%s9N4!oH~h7l*wQ+m%aRP|lB- z^zN6_Lg@G!C0Lm5@g%bvId7-w$F9%Gs5DEzD$H0_ z-gM2hEt_;nM+?*#p{D)4*`g?x)!dLYZ-@+bwvUSAb%gVyHc09LupJ~-D~0598iC9c zeG+Sc-qbE~ITrRv=K&WYi}hHI7~qr^Zf$jpq=J#6c-mn_iVD90u`?uI4ybHe3!6;ugL#yb`6_wn*)gFZ=_wEk0B~(>Y=_twZkjKT$j~ zq)(~Pl9ALWWV>Y#(^sH(pD!q!JlD$W#;P5OMM>%gC+74!6+Y+a+_|W`=l6nz3$SqU zK6u4JhhXtO`(ecWzB*9nW7&pQs+<%57Z2QvWe2zHW(H4BMD^7Q! z#>H>C@TOuWs!Z7nqI*bWow-Gts~R}vP27l8`AmMo^i;O6#d_@@FUeEt(}Bq6B{lv! z7yAfW+L-RhTdBC8&)ZDBo@h>A-Y`xjB%g>^+m%QjZ$D&6<(UoLw2=*(c<)k@1_T5I z1ibjMXyF+C=ns#|a9BS`AOHX!$#2|-@ zLYpasx;|h~8;&?1BZV$@+Y}aQq+qOmFt3w?REf}zEjCYd(bCYcE;$(;t`#mJ)0(%8 z$dyhzlN@&u6*JIKIF8Me@bKJ+|1kq61xYA!pOlnDfM72VtLRx<+bT`5?(s%5>M*ylE2}6Pu7XpF-MduwyY$E#r58_jNEy z32PquvTJ7(ixw|(jz=4tHg3Y!>86CQtCuPT9xR6IR1v$(IY_4)878N5u98hZlV?dn zQ6iX0@s$~0AVr-j=NOU0&-nq}u|(2HPCls)%^~}dV_VWJLx-OUPrmi^|quV55>6=^F)jrcbalRrL(p$O50 zT(ugz=}BVF0jKlVDly1PxJ)(-=sXGEQ^dIwnY^%a-^NGH`s&N705g50MA2QUbQPjh zii9ySNb004W~EXR$s4)2R+r`gkpL;*XPQLpfF~k}m3|^6Ex?38q9Ne9vLF_!M2;og zUW%#tuvzIhuNY;bG`D@Z@qAuR^s1U`VH@gDTKhcfTqh+_N!7ra=KPej2}zU)!DV|6 zzl@=fm_8)|d{-%(Jad}9=vb)^?dB702&7q;Rmgo8EDnvLSV>{a#5uK%mE7f6XiuX> zyy*Q25vAZcol^fApGpA5h69I!EBTTtAsKP`8rfALd%!tQ-MndOK^al}Mm*Q4SWLI8 zip@w=rDS;%Qn@ox>GM&_4uO!us&>@02(X?QM?p41mC4GZ7m8gWKcQ(;e>A z&krI>lTsuR2#LNwv$}C1#2(E};)1i5&mihX<#ZO+vJl>B*Zq!ixGH(&$y}eK)TbFB(kf-rN^)irfko=^q?3t?-3?~e@ixwI zNVrykW70}Yg6;90J2U;zztnZpp_s>FZ~G(lJQ>RCF%p%cU!T3)%3wRLViyTt9cvcF)>QyNgwa9mebDpjWQIp{rhpx$_sI9*;lqTio&E{|{RyC*3V4x|u0tb(E+=)Jk4vAxI6Am5HHE ztAq(fB1JRz@G|A9yO)YvQ(cK}v0_Utq8>SFauikVo({WBvION({RRu9a8%^`RK_|r zxrFj7(H?2q1go1)5f!bX!kJb#T6DcgkxL=aC1XV5=5Wq^)Z0AVeF!9JKtMpiOBAFa zeJ+C3gN~tNzxwrW2SsT>K){O7g$&Z zwBoiX#!}?nwsXoF$eI(VR0d#56($Q|+BoEp1F>So3e26e0IOcN0ylj126mS0)4X4D ze25^OH&SBqi`vcwLsZ=%VXi_FQOG#w^2 z=dM%JmXO)8@Du1XMdd{VOp*zKLf7JgJ4_lmC$_59$fH~;Zg+*LA2%e-ua%Kw>h4a&;5|%vOay>wWt5R88SuK{- z1(B?GCQUL?EhmuN!;yy5#v1WSHX-mw^<w-pOzAB+uV<`;7ukedzxVtNwD?Zsi4%xg)Z19&@5vPNun6xq zUKQC_04A3d3apHU{xHMHva}rA4`RjxOpa`h}nF zQy8O1iYiU5^VSw~FjnH6RlR(iknBEPfv>PG>$U%aO5rIX%Y7XA)B`9|8JN7UfqvZ^ zN<&b_@NgYV7mqogsD@6b#pzOVt+Kvw!F)GAO5Ey3ql<}&2BxQ*?lZ!aL=3oY+JE0= zm^U^b^X81;l?NZ>zF&ZO^XKt3np-v@tJYDf4RAzmyKjf~TarnHyk=P_!7%pQXKUcDrYH17%3}frW7Vgh^bLXM%?rCUf0GpoL z;>Nkn_OwzTM0;YAH%Pp?xnRS$VewIM}()FE0o{0#C@REsFft3P;$x>%W6L+ zaoo?YKRcO(bV_5It&qwr7bUHTfJA*2Da(-S&VVTUpk%1kuyyHIrBr$$ zsH{FRtmLEl&ct{oYHD;Xlh$-EqyjE!KFuhOl+WlrLaH2h-#H5I^s;;xHUxctA^>5XUQJGm}=d33viU|2?@IEveN(@?6X>v%ln_O`$ zd4qi=bFZe=-3__EhSle)8YQQnatl)*wy6MEyM@Jz_rdu1R^A|>(izLy9voF==J3L>k7;>n4+&jG41VU1!g_&5VoM(Hd$tGhRcI_cixh8Tzl5 z)G%gCtAaqQq34N`!%5YR zX;<_4x?^dhg;P{?rT7r%pyj-!u0KkWIwR7#6q%hM={01Yt{pv%E-liMY98p~Z%W+L z@v)Mml%gaqQdB@vEm*lHN_(TaW$0dLkL2@gXmNUB_vHM&oVmWjd;g9B<@#>AH9g&E zV9}!a7#&@LDs_sx@Wj?BY}~W~&DK`TnY#e{FWnCV&S&a&Gi;ui#?<6AYV{hH9k?9( z?YF;s?e6nr!}Dll&L~=~X&!?mOP4U4K6l};$B{06t8~$;PR|hsKDl|W`GAcS zqD!@iU6zVHrT(X9Iz8tzt{JG$Gu{|X+_NPvQY3J$Zhm%jk!Y%k-Hkw!1_T5I>;i}& zJ?wW5#pJ|95#IA+#*5zf|O}wCl-v&#btl<>Ai|5oo;2U zY^+sC6{rME9I+GIY-CJY5BIm2S-5bV2fE?)oYSL47}9E8!qI+|O? zowGHGdW}@7U5qV1#5oVnW$0|hqjv{jO77aCQkiU|OmK|UBUa^+%Bj&b z+y|A|JNp1MOtRwIV>op{39;)JCT}&w*%Pt8_!IR?w{2ZpMSWsi8%asYj(Sy`=qwe* zBZXJTL_oAe!AE@_l_kd+<)3X#Qw~$jmsWFQMheslb+a1_Dy~B0RVvk=SzH@S!%fsH zs7xgAU^Paa2tfBc;snd&xTm5*nkksf%!S}&rCH>O0zU^tHOjqWawbxyTasFqD|{1i z&p8=WR-x719N{zv&@fUWen`!!IT^`c&XrV>&{VJF)$r-u6ik5CYx71xEIBZZCp4kz zvs~1p8HM0>q*^ld9XY||=yP!;B7BKp(rVLQVMGKesVgO#TndPAP;aa`Cvz#{Riw9w zeAu+~ov5N?X|5HOZIQXKpYwneHG2HaKJvxuyymKCdy1PFj~W$xpOc)ID%HI zft4#)a=ME(Yktl|K~_*@eX=b-PJUrZr)(46Iupdk6z}187a{zjJokAIwmGK}yGC}d zoLJ5?OU1Z2{8??K5dRwfO!*BdUvMtuGrgBpmD-=YnUVQ$TNLD2q4G1myr!IQ*-Bna zD-4Dl;@djYuk-)8>||&R0OJO znXsZw5ia&*BPLL(m=`_wXgwLLxuK((&p%1us*wS{fi!O{&^Hr-V)I5ec_bA`%mvL7 zo{y2FB!OX~&1mr=&aawj|LZu38oQ5W_bN#A<=like@rH}MUybA{jzEg(|j|kgQKVo)%d#k{$T zuy*Y_OixXtKH%Dwlw6xSXm>jDxrNem_$Rz7wV#Q+Z|>=sXbKlvlN_l-8z7l%fEcyU zK9_6Gn-~$FS_)*vGNzidm@ez*K%UA*#>}bu*+C#l0|Ej9b^)Xy-5Uu~>%)zn2Y&Ud zU*XV051r)}1q1}V6hI$l_t|G3{{G$XdIvsu{zZGZMLqaTA$9lZw#LPA465}=3d&GL z+ODV$)2E(=4GIsc(E0cXo2Of*u=9ZoQBh;r}ctPZWY<3j{Hkc%dIkZ%Y&Jdx}an3b4U;8c`c5Uro#qxu3y^I zSC8RtK3lH$ubakW^gs&gSOt+LG_ry%v~%%7tvD>ZG8nJyL@ecT4~Yu|$QeB&1o3u|!4*6mjY! zErZSkZj4^u-GZQ_>n3tOm95b=%cYw8w(Q2e?e1aH-G58+!MaYMdDzM1+D#@%BTRL= zn3`;GTNkWaEBurz$tl#ls5prZ=Q%{wIHhfHW75n2DvH54@AW{B?C;5J zbL&NfT2x6D$9#MQQB_hm(|wdB?=?iQtMUCU3Rf;(rmS$6)v|^|u%Z3JxkvmStZuU9THH(Wz831x zNDDTpdX{r@YUp?WT0I}9zom;%jjC)nDzysR-H40Ml{g1*x8dvtIw;X*p<5)en*;4m%RQSWIj?wmXc&q6 zfI?4~Qn@4qYPl>MG0yl(Xnn#PJBt@C!W&LF1s!KsZu^gKqeb~p^O$pi+q}zm&~RSh zOy(%rM>p7IcisgH7rOZsW7Y4z9uGbAAXfbU?7a!FrRiB7_WbKP|5@+aeednPdwP0y zX*3cez$~(c$VN7Wk(I=;Qz#aM0s=M>N+^qpD^zenP!glWp|Amyf`ph9DqJju42nT3 zBZ-;OGJDTV@7?$I-Oj%JTi)$Ew}pk(6OD$Ed_L*Uy?vH{`PTn^zUO_O`yY@sZ3^5$h;=4D>KqQWWmuQh;_ z%U5zuolfT!ypnmDmwEYmEQjeKoY|zWrII6|o_b!VD*g@AO%B*`?8 z6g@2lvBm`kAwAgh_xVY=)HE>$HW}!eOmooxDd=Fg+Z^qBK<83p9iLe=oY-B40;F=# z%WRKEqlQywPgCHtj^)*5)N2V=TTRp`V%WNL2{*U4QL8r*WXharG?&obp{9n_N; z3(W-g-*t`xv_Dq&c231)BP9Vy)RZU9*hRfSE%7ClmecIn3`;z!I2APVv3{tHMyrl1 z*LUf&5!O}~arX34tS>E79Zm7}N8XIz_??d-3hIa`2#ezqC+;|b5e4I$*RG(T>-D`{ z0%4d|CI^n`BtX5MP;efg+Zl)@V|j&XDa^@Q{r0(}Vjcs`7*gui&936gW(-Vw zkr|1TycCdhk{QFZP$pS!>9fqN4SWUr*eIt|ZkU2VfwEksPjjHjY@4(&108S1Hd2ho zyTyFT#)79~LCi25BQG-sqNnUnHbqh+Bn5UNGgcBHBk&FkeYlv}3~L6c$&@mjlxb>g z&C)2E26p&PGZF^olq#!WvV+EMg|Q1Yy<5Pn%*Tw!>^#LR9k+yn zv<^IB03i$_Wse1+NJ|tY_s1$0mKU(+cQM-D5$0W%tF**43o+*YF&xwHoa#NMF;%5L z(!$wu_tMx*v9MCd(&`G5Y8`jnc_)q>JBq6>UKV4m_4OqTdLw#nENJ|NlCIC20?g!M zDTrw{w)yD*6fH5UrrRtE5~=p41EZV{rv2^G-49-oIe<;+s#Q-@oda|9E){qbJyruT zMe~(9gEz@lMjQj>38F?| z5f18)t3*t-jKM4GmnD%4vzmVV%sbF-h01@Vro+m|XOp~?CLLZI*@*0#0qn7n~scqs4qQwM{Jo0v&K7AV3uV0odp8fqD^tyd?_Pg|Vm*)DB z0VTYEGgRj|6TPV-C^SFd~qCr+F~XKx#K-E)uh)nn@$ zc=DNNaGBQTybN@Mz=IjkIX3P=ea_aI62?ANDGs-3CQFTfp!Y1A#m1y&P3yo65=-gV zxoA$SKb$k*)44{Bsi1B5aF8N5uIZ(v;6s=Xg`|=XrnxXG z*?pV?)X_wP(!c@&#V<;64epJBy+MIiGeD&lp<0Wf#uE`e(DUDsfCZyrUsC7Cbg+J> zk9eI^xeF{O38HL*{oQSJ_x7;3w1iHV0-lh99STzTJ4>tU7VwP4(u^t@IC27&p@YKdhh^Q87A7FP~3OBj_IoJ}` zmS=_^%p}e{(f-Vg@yU12;Ao%w1K)3^AX24D=Syy%MI~TSuIcXjZ%GI#8I9Hk1+e7%V(_Biu;{pnHm-sxn#c+P zO?eXl#)d0AW%a^SHk*QR20RM7tc*hemV#24g9nC7rJ-!4X(%d~VsW*l1jCGf?0QVT zK>k-21|S^(qMG8aA-Fop7pCWHj3(2X8H|rqN<_6db+aiqt=23*FjEpB+H+<+g``(Y`!V3pddaD}TbB+XD-T#k(%E6(0|M)c2bT)m1fJo6MiLuA^1vn>>zH_Flt7Ta7YzgSMgZCK3c zm!{@=_& z(RrDddHMP)wR-*QF5SM}Zok4;GcWTpFJEtk84YaU^ja!v)S@h=0UPu1za?;o=qUPP z*hD`Q3f87fzSM{D-C>C#1@=kAX?KC9`5D+coEGx1%&bZdkoku}t}g3oGRVOIY=wgS zN}%b;af1SYhNRxHJ1#qFXs{572H57-b)4KdgmkcrY&;g%>zJbU$!LUbw}(6Ke**;) zp#*Z1y^FYcbPNQ*anFfHS2!^Th2vjzipc zZXMtD&>5WAID(~C3ro!e51m<|`%yT0Qg{J}?`MnDnpgKxN> z?th4H{nl^6%IX?Mqk*LQ4SIci`ZFKLg-g$1+MnWeCr{z~-t`agp8xS537eFeIeD3? zHldlw_?CXo@fRC8aotDkbWYdIY~R9DMol?Q#lhJx%9$o$X#gPy$(4#H0EHymvl$ON zJ$ah;?fa@#8bvRINop+6TnRN4_~rs~G6>K8hAC^p5~aVne+mHat9vgq_-gdNZ@`J? z438Kw3N=NzC<0;43Q;mNAk6efo$#RmUK+#db+F_^slZl|I{?U7V~%<1fH?Qtxn&!e zDZrV$uiA+sJ0a#r`uQwXrmp~`{(*L!V;nMDSFyH2zH9QTFl0x8*%C8zCm|$40SwCw zH^!OjD284MXWgQQ(RB60M~~p>u~S%VFA1~s#*Hhudig~Rhkc9(G}iL5X;>zxHxJ>i zyI+Sp&fbNM!$;6uSVE=Nq;FNw-OSM4PSGqHX#LnCKKG|j;`u*$0xKuJ2^;U;#lQZ| zk0EZ~hxfeqZFuIhFJXWQmcs(aj<(Q9VydqYqu~UXu3V)#a!Ww2rG*7-jt4k?@)-Iw z5A1dKaP;Up*4EeX(uJ$&^)GV|QrU#kv9@N!yW1}EP3se-ffct@)a+9Z(1uH&7obY} znT!)d-lRX9S(O9nMK&QTXNN32r>$x8YhD;gYx=l_V-H(eu6K}ju7*$E3`2B))@-~w zlOh9OTuMGHMc08~j%~}X^Z|n~29omMykW*HJN_U`aRk2gzrq-DCZRHuZ17ck)iI=n zA}v0oEfFb>3ygD?ZcmKrl{E)gJrR49SfT|_QV`64it=*xvt=A%T+fySLQP7 zU(b{mtnJEM8Q2aKwGDyUi1Jj=)Pc3)@NU;rsYU|a4F+9IS~Z!s*bH%DaZwBqedc+x z42ftQ2MV_Ge9rTHL2C^ilTF)N?H2W!9F?SoMy)9ur`)V#T1!Xck+{=4DS+WtW!Pvo8b#H$%iQ=S|D1Yy#z?4_!sQTF1tbb$rvqZ^GlBc>*8$qYvSwm!88z zZ~9g|@X(vksJ3YCn_y$(C|b=Ho_PEV*xB61gAcwLr|&w6Qzwri9Z%5N-ovN<^k3u3 z<;%9ARLoeSvwan}E_es=rSvfzu&w2@#vs1c9L~2o7jrn)wB~t+nZlN7AZ${0vrj#f z!hmRUk0)wqD4U)1{jW=q^e-xJ|L^}V{N$kz;~RhQm-U6Wy$>Jyi6#8rTi%0zH^Y7j zkNntA;V0j5FIFm3^e%h^Klj5wjSp_oTR-qW;ghd_3P0C*E8h3kbv*M+Z^7UF#e;92 ze%lY?$G`78@$j(*Eqzm5{rE5AAHL@|@${>6oAWX+^YV3EKKAiXiE$H)bibB>(y!!N zPM$pZ%3a93%*(udT@`2C^uh}-h{OGBsR(GpP@q>(FszZ8I8vt$7}9`$I;MbUQiwx1 zr@1y`PqYS|8!JDkb5Ju9-AFYvVK!rFX}fH+Gn`To)bN%0#2^-@2v%YwF$0iwWumgt zQ9hz$q?nE}F-Bm+n_+KX&5DLyj7c^TEpGA=&*Idpb6Dd3NB z^vDtHbSrq~rJD%G1FWyzMfcgF^R^^)xEd@VSgm8Ha~*Mg5x?`>{|aYLE=vHve)4`y zh8?-C9#O@tv||d;0y=Jv zARVEVjwfr7bT`{1u|?IEGyaXK9d3rq|<0s|ccK`R7gD4nx0|Jwz1 zokN4KW+`6W zYNBGle5d2cV2n@_bG=5#2riw0jZ(bW#;0(MIEk_qBo|{BW6LVLm^UeEGjWS)Im6%1myGPkTKY zrycBX?NQxlSU!fpwF@tL9Vr=?)JX)D`5?rPOC^B7+{{8POHh19(WF^c7(B} z^>wG)tE^?3S?J4g7>ZtJNNd%ltJh@?ZB{F&wi?K$y5X5m^BGu}<(X*824O{*qWjx7 zaP8808O7{Jzjo>z){mb-(xSDxnxMYWLO#wg&8Dc*ytB8xhiR>jm~MPFHgapXLS+!R zj+%`H0gPFnbTXYF6_cf0*zsJa_dIY8$4(x@OBXKT?0xsqJhv$8OjM}|$k^|WaqQ>@ zPMv-yYMl8}jWFyF@#2Mx_@fW~9zOMFk7AanAe&nG3`o}Xz-cDywYiN7>rS(|Me4XT z9;(e@r2(X>|Lcp?2;UPwH$m9axoEMnboXdn=tknS5Hn5He)nYnuDy(Y_)3&l1te`A zc^L0|ubF^!&*Ou?_hz-*B`6s@qRGEvROsKDmlE*9!B z)*1-~yeYcfF6zt_qCl(OYGc&d!=&HAc0Ll_&SrCof{H4d3x}|{d<<`TqbH_J?d265 zJ9noD?`3I5a((CMV8Eu6$-)IRNMA>eI&aRbv~igdV-wWsTk5u;(R>~)KE&?r88p@P1HF&;#5((?y&+EHM)jcs8pDVh?y2>sHOsZ z4tysN08FtvO)caAnzaEL_^I7y|C1oSRKqE+P$s0XJ2|OPn90hvO;K^JC_3Zsxg(oz}7zJV&j5DQFRv~Y$?I>sb^7MCB>12hoSu)5ipQBI$Z zH>WY_((Uy`Fp!kZp!9s=|H1W>d(sy}->_40N%v`-)Ui(eZe?W^^?FmxlLCq>mltE4 zIB^2wH@uPNtxb$a1A4868nu5E#9#}RGM!>N=wTQnXcu+(Jv#XDLUXuV{!G)@V;k^3 z)osEW6&3i+nz*z3G(dPP^{9Uj`hDv6Io1v>zzY`XxP2_Qz6o!9=#ALh-p8d2FW{w% zFJNnX8+|r=%2PBOP1%sa&Ys9u2ndvGg_j0e+-}kOK46jRCW7`(gVAmQy*vRr)y-bP zBi|^No`FaVqOoG0_OVjtHvwimGfT=e{XLy#GyPG~n)DPzEDW$xxAg-ysqy#@m}-TS zVo)Y#Vad}9_FAfT>DZD6be0Etla77ryZ24*fq@wT4s9JMZH(*O2iq9(1e6iu7~ko) zYI;8Reb#DbMt){`q*EDZ&R|T}8|mx94%I%%tVi<&lMN0w4U|-IcD#>toRl_J(}?7r*hLC-DP6 z`Ubomzm4DHkK|v#2mh;I$D?23+fV=R{~i7z|8eLJJRID>&HV;ekNp3>n|Ya+d3hDe z5C50%!uS9EzxO5I`xn3R>-cB?{8wMy3;OpI21*@R`dTVA3N+vOJ>Mz8!tIp)V2FSD z{(nXb?&zz0W%DvG^D-~5e5o~KOW}gD?y?*i>-`O;m<$he@t7%8jXg(fpMDsaCqkdRHF`ZBVvnc^VlC;n|{5r(7CIu~#r0lIGP1F|G z5X4mquo&S@<$O~H`sk5?4ohnP;CAkmBkK&kKudotb?}4b?EGcGyC=xPoG`kL?%#4E0I{*soDA zlt}r_dkns~H6|cDzCvuWTU2F3_x_FrsT6dBOrp2N?xhsesYU zO3WrD>J)q@6zxYWonkQfh8&R=2j~H}u8`5z{<5G;1Fy)9b$I5N?KQ#;S zEvPRvRgf8K7T6aCT-0JtFNGTAROtGuB`OKCkriNJ9Cym*S*4n$l$i#ak}B^TJIhz& zZpYSOJx=EaWV(Anlp?TIa!J&*Kfp*&CD(pF+>HK9Im1p z2H6bkEDQxHO*_(s&!PZeDVk1O(xt?@l<=83kbt$C-mRxputR-W_EC??kN>X;f+zPC&JjyX`EH5Pq5ioK25lS=)PD_aI69Pbfo4v)jG;x4DW1R zfcBXHWmwS$7MdIV>~?|0s*;v@aqj8^x;{*%!ipV0QG|meek8z!@BT*x%rKLqI zEVPAj_T2MNqca#$y+>GFJ&et#X{`7G%@MKc9(xmEwu`ZofBPU+Y5h<%4H>{L9rF@1 z*wHsWA!{l!;4B(}k*2yjy;*HPU($v-?Ug?lnDT^xSEa(3JjZ#N0;h#@U}sjh=2t7r z(I#F6S4=3u*pC9rTWYv!ZbAXlT#eAOLJjpw19}6_DA3J7FklHbVRvQ=a|yWorE!KDfPU`#=u;bdo#wXurOUNvZtE| z9<#RToXo%$pctM2KSi#HuE*ofD`yN)tq*0G2M*(dfq!{9lbujGlv1=QrABhw?9lx# z1*whEE$`T-g8<4l-aG>+1-=L-(4igaNN(K_KnWYSnP{>Q$Lf8Fb|u;;a?TN}%V6 zJf-=m5LSBN(fklAgFmB(5te4)KG~!gugEL1SvuA~Nl0dD>U-(Gq6@8KtZ{6E3BEcB>T z?1~`&peo>Lm>kB+(KDD%rgZF7m|tvmG#&ON zupQEUj>;;XrzYp)=>Pbc(_q~HKEXaft- zIh9ki_b5;qPdGJD!GivvhiWZCS}b9A=O*?yuV6gR>F<3!_ziy*@A#p=jwe3zC`R3j z81K9&jFEgg#`Vh=s15_VwutJyk94q#&gL~7T3(cE=JQwST6(LDtPZh!6dXK}dQ zz`yc8F%ZS^-gBhNZ3mOOi6K;M9a!c&4xEh+F}@1CStsm}f5Y-Z9qLKVj~**Lvoj-?;M{ z>RcHqi8addktP~WNQg)6ji80tuTY_kaJaWYr;ZHe)yGlXXHcgDXU#cA>@$vld_TtC zZ*-NDPD)S;3Yu$Te;nXMB9#KHK@KS@mWk4N0>ccHrW*Ap%)oMb2iQgDfQ>S`KJhWa zFY8G+K?q`Dxg)(9BE}$bcm(M|7zEw$# z1Sda+qbKvF{3lA&Ozg#W*(|_e^g(F~h}!&ehEO%CSC3 zgFf=7C0eR!8_jv)h|^zaw?`+(+uf=}Z3lm+czN#*GInHg2z2RaBs3Ucm7i+fve)>S2*5rlD&HX?^;@PcxrVA}<7aI9HISPcRYrmGZ%3 zqrD#XU`{109?KDXYIP))R^8Dk#3gZ(xno8xZohVAiRYyMiAX)yz|IEK&`dmQ5wt0% z5eX^Ktc^TR?M07&UJ#AD!1$(|@ZT#vdr52K7IY^*7yHP3aH=yJ&vwGLaQxH8eeT9V z)*-d1U?Tb@gBcusO(+3s2K(*{4WD^fhcujOVS+LxF>sha3 z_q~HVYTu**>*n+E%~mtk1kY0xt%cHJ1O6y!HEXWwf$&8{u`uhkuQI4zZF+)1ecP-Q zCT^4OB%Mgab|YC1sC>Epm>*!r<#v^GNi zQtE5Zd?LE=Uqb;O13=O@FW)2hUBz$#$_x-!0nZ5hM zTi!QQseh&xXM6kv|BcO@{G9)Td6h_4YbIkE=qm`GU^yaD@{Win3=E?`p&-@00|-3< z0Lng-W>FPouuwV(zJwG-2T&=dBqsK)MyPY2%mTKoes@$nF`AeFD~f$?y9eYi7ImG?zl5f)${DSES%9+j^Iy2Qb5df??zU1vH-eR-ap(TK zVAAem%3h51FPuHAf_@oG?hP~{w5C=i#zR!8r=PqY)BNKB_zaKI!UW+!%3f)Y_Yx{7^UOIgeW`xd?j03;jBRk>`rI36NIrNc$y4*NG zO3=dG-p+&~NIAxMCbr1`A`m7qD;SJhgNw&nxYUeH&Y?4kqUU}ECI84?{9foM?~GWe z;0#NdhL%=dQ2y&+T9iFi>%z0_XU)Uw525>jcSue%ncQ!^T`H%f3a8Ejvq_(Wf@p{S z$ZN!BXXUO1ZBoeQifb;FUV(TW#sp~-ms#Jl$|pTF+aUBIaX@Bl5GuNZ-phn2(xCn$ zKrR7_a@nD`frlGfQkp;CjIIupwuug6ph|%8a`63CV>x7{z;5I4+>HmG(4(lQ;v*t9 z8@<_yOh$;EzJI$uuNoN^jKPQyN6d-~uD#l@lZT!c!h5;>P&hw&- zr{x#=fPXuGZDcQ$S(X%=t`s@uH6SK;JBJgsp{qg72TutT1)PLb~w@}6j50GOa2zDBdTC7=A;yA}6 zJwCUeKpC9NWHB-5XgX%h%Rb#GQVFRw!hZ+uE#-pPe(_-|kW+)AnngnGtv>)UB$|VH zfyXrjfFEgLo(da(^CBX^NFJlPdA+4i`aPEM+YO%h;0^Q z<=A7#0j@ZAH8u`z`hb47ncSg@fcJhZPkyD9rPgH&VGY=HO!a(*5oH^ll58 zdG3vM-r48INVv=?oO>JDZPSTg(f@t`B}b<>9daQj2HGG?`UzgtPMZznZIrlx+{FRP zO=2f)Wq|i#l9rVcnp;Wl8mZL%R1#j0sJ(?k-}QGRhVpT_)cbSx%om2e^`ewJ^i9Bl z*v@zIdH?oLWp1CHj$hHtt}btEDYI95W7hEeF|BQnGvvdcu;kF&;rJ1H&u{aeA`@1Xn83d6p!GTt|Z8>q7ZHum6YctdT-4to59MDV3OZPh=$%l%aR(zfBJTB4v3CqQ7AOJ$+;W*lz-@q$`a7_U09Mx0?+kXVd0TI#S1iH#bk+Vuh0sa9yJIAUHB=B6jwS>z}vnw z63@94`!T=$@+WzcOWtaQV_W3J1j;&sENFQDDuAJ5kE~n$E_z%IENU0Sy>=)R9iVDz zB@Q)`T+ldH)mSFpZ<73ZlE+X=THjy(ob$)KQ_L?;D0+}WY)OL?h!e$ljz0YxNcL zr;hBfhGdp*)aH{kR(7=iX7DQAH zRc~ckdbO@`Kb>7j52;;DaMXI#A3^*x0Xh(|^rUpde4qWo=S&TRUF3Dj8Ke^r|0Tlj z7c_77oWls&GIZ9Cx!v`lG68W#3vwNe(H}r44m=Pc-SoWl`F-SukA*C4Pz`tf-l{;f zZb}{4&x7>>G4HFWs^~I-mtaOcZ*aC|5i2?)6NkgegKnGsKHZ4*%Mx+E)T-z1huh(= zeU5FjnB9+UK`aUD6{@anM+l|;NW8L{xzR8EZA=$z;u=Wtl-~-@{F1|UP;WE@l~09% zGyx5g*tm*&($Rrzr~*lB2A8YBCBDeOb&PWSvWxQ1>I)D7K!azI#f0lVmRy*%?m**D zhvM;WL2gCsIq!?WETybQT9~qtE^kQ@slss72UXrdlY(ln3cDS2in*dU66B_7)bJLm zH}o0%^(F^H+8s_sP4QAPwD2@2hI2#|iMy_&;ePVP7$XJWlWLk}@tF~YD=5Gxn8l3J zgnMg_sXnGx0~od%+rMog$F~@N|2P zW42MKggzqljGFb}OiulaKT*b>pou4=ZCk@k>oL(OUf4h(ol>8Q+irt6O*c8mDE{J3 zdU1?zZnzs(qmg?oxi9VZPe^8Mdx=CMS&M6H-EJv+h2CJ`^A@${_unpBr%GC(5{LC^ z{l!ZLbj>iJVkDd-0k1!7bkfof+y2%VzfV8{L_)HT?GSB#2oHpzgddmw7?E6w#JndSTYRjNaty?DX| zUUak-axN#@_@>cTX0I=6G86Ud_1`X6d;P=cUQ!iVB?C-gWs)1I@nS@d?11Dk`x!TF z9BPb0%&a#TLvKua5xw2dZ#}=xpNYGEE!iFP+|d#w4whBD8{!$kFL-=yETdLUm!IjhTk3QAn zljBOIfUtDL^fT**lgw`*ML3SFG?8wbFiffZw_H?YKftLvI45_>aZGN zcGL3Y(50uilsMM?0YL+4s4+?oDa?qEx$%;| zF+0Y8IfPV}#|Yb>0@L%lNDY2ZzXjA{cl-A6jek{$V6}eHXvt55u(S z!!{&n%5IGSKcTX>`LFEs2f=f~yyyGYsF-_P1qqOeDUQ6YD<3Mg9$XSgui?`iw zD7I&{6^aolk*v5JETO68YxidbJ}mys-1;DFZoV&lBY(TP4!u0S61+hlC0@q$mdEe6 zPEwZV>nK*@uySWgvdL5OpObO63Z7y5jbnIV`!RtZi9ImVlJt|teHKE`G&{9fb2tcO zEP=-6=sl{&k*DIIxu0ke;g+A#G|UK*^Yl}`PYY6WDh(t#A6!xtxu5J;6>J`Jl5h8t z#`;|v2q+{+KsW{cMS!i7?$%kiWf8q(WjooADo2>osDqMt100qe2w5#dx_V`M^|qI| zIPIFj8QOv!&(EnO_vkm}ju?~4Gj^r8EJ^`BAi&T9mZims$S&Ov$slsq*5P+Ms}|$3fW5`F zJ&L_cTWSY`^PFPFa(e10sY+B))EX0nhE0Pl3_ zwlSF#uv8Eax?G_kG;HNfuud|)XRG*UR!B%3hbip$>jCCpj*EQ{Nv{C`|Gi6$T31SX zwa>1u!MQcroX=_D*$Z0g?&a1~vYy&)?)U$UEvt1+O#x`txh^UDcgT=1WSY$7)>}sp z-mxwd?fNnB7}pLJad*aHq;f?*qC7)yg^BoJ($=r1zdw=$2p3)CB4m{QifAH-nyZ)# zXj&jjxA77g#;%x?Bu|^7Qp*z+->Toeoc8+l6$Pd_57ouzm39z7F_{IM6)qfc zW-a+&7LDMz&OCMXS6Ex?_dCkxrbh6^MThsLZFGJ9#!Kmywku(Ow@j_&k$n5S^+w+L zi`(7)cWx+VUc$b&QTTEN>v4^{oq2kB>8z~nO%7dYTA%OG^U;xK35OSB`Z`4hoJsX4xWeG6UTthArbOo-Z4i= zq040|SaxU>YI18Ly%GJ76uTs6z8GOwI~{SOJB+6mCa|YfWT)=Oilw8Vf5TjU{a0#<%R2DIt0uVNJL67IjAG9S)uaKHu`S!a17gvRW| zem?!QfPhO)r09QoB>Y7~nvK@sj0$aG#X@)>8RCx}FM|M!rSP=~>Wd{sVZSjL(qoGD zfcDWpLWl45QL_g!}uUckg2)I+JRZOeq|5 zl(kx>U7;5Bygm|`T>^koG#wWK1FEHaWI!hJd8Xo!fp*^5{fF~HR&?DCNBrEEmr?tV z4b&~~SzSDov}BF}b2fMU#=N^v+j;VA|Kc7COOGqT!}%^KNH9JHDj&ShTZ*mzMAmqp zF40f8v-A2FjxaV)1& zC9oiUrBO>mz+bAii^yu8A@oDdV#NbhL?#`9w;K-I5nu#T)-8gqid& zmck{Gi*k)1ze{+P*-g55|D$%lg>=?5%Il7-N3vZOX=Ib!NU}tuRP76nUWGJgAu9Dl zWQ?$etm(q7_-#IOV1AVFdQiWAQNMLzUl01`LsE+=hu3l{YSWJAD-KDh?cq6`UJO609hlT@E~=DRguA%G%p) zFKj%UHcf<#T8Z8a#9AWFTFEX<7$pu;r`Z#D$0ibM6Pgu-p4I?7mE)`)V`!N#VyX_c zr%R7xr)Gg)s2FyIula}{&zqsPw`~lT;hXY+KY`&;^YyZpj2*L7{GLT+3(xP}B=Q|;r4%=$5weu+K{l+Ud3_#2eXORT~m`kLNVho*o>rfvIgv(9*`i6-YgCss3^5d z2>k$*Y_0EJ6lqi(z4*LkyK2;_Y=qvYZ;w>gvW-jGSnJVN{+KO7sIU?|JghiCSqw&SNxip6_ z*49lZv~sVQkQ3v|OoO}C{}G73zgAy}b@W&strV0D!+G9a+G6-n-jh*nRmQG9$KwUX zj}-It{5)SlIbdkfO0f0~eJ=AMZb=04aRQLydXlFlla*FIOwg3jA@!VfjDuNeOBMLl zT9RTfwpPo_-w*~*R_47%AunWIjmR~0$#wo8N&rbD%PSwo-UAnswZM$O7!y3I6$>7$ zc1-b@5fV13&}zTnyS6~8*3C7uW`|?`Qg+y6S6*CzsYz7V`T~U){S2Ns$*!V@c0lxKssPNNO!6Np^! z<04d!V=`mfPdTuwVTfTlSulhxG6`X>q*d{n*F8oJQfrKUd_>*yoc-W(xxo5rS#=K9 zU(n=MO_`2O`#Bs1kTWB`cQlZJHIW$*>hC|Wmi7nLKc-&PWoX1iPHIXD?JRYu_WL$9C_;u z@H3kcAquQncCZebuEtP0DW=(PC%~%3}kh0wOaO@gf9M27Gj*-ka3K~BcC0D5s)1plf${-Fs8%PIlGBz zM0Nb@FVV}y6y@ro~~Zevx^|C0q!;2Ejwtfcavk2^_(+g28}`W5#k zLXjErh#6|ZR9#52I4JuX#U|7$vZ|Z^Os~4ESWN!URB?3Yc|75ws~!zv+;b}zYT+a- z>{#!cQqUV5^wZq**GU|#q{RHOcGzBnTs&>KrNXx>T{7gqb6%;b2TgkZU!H{jqtw+h zY+UtbgN`Y72K_S(0h|5Gr5MA=X=L%`hUC3{-9w{%c#LuL%8>cPceHA2(kk8jJuAA6;!IArczG%=?^6)b zwgx6fQecz-tg;s)%3R$i-le|_95<8B?r^zNI1DK_+*j)nMGB!{Gp3f}xL+tlXsk)X z3>%eydb!3i6cttr@6n%K0ofjS^X$1A+5^XtxC#nFZF80idus!{yA4r%wue2QH$qm| zXiJ=O`Fi#po+15C@_T=x1vo}Ya{es2R54JPH!&@~{(uFR-{=(`X7e~iBpb|Esnl&) z9{lit2IV;-6?3Ipb+QshJhE}8)g)yY-ufZzI?r>h$&|u}Pz+$1+WZi`>My!2hPFhJp@8Jp_xEr72ODkP|e0Fq}6$S6@%V-0-Xt^3od|5E6ile`V>@9#^~ zEsz-NR^RGQavAOC^z=pOqZOCS`IF+ey!vi0qW}jtL@>Tk7|gB1bFGU2u^+`TG!<$q zx==gJM~8_aii?E^7BUC{c-jj={>an^DeLI9)F zpYl`SAcS+zRG@Bo!_T5QA>HyQfY7d02+sJGYniV~ev- zS$-C5OO?@MDS4!+#$$(J|97k?28(D~baXXprLE^XdGAK`8`a}JuY{d|ulwAyi4)x_ zhsk+b*5(4;uoDHStruNs%486#rZ#2abL%7?gcAf;(%>vXnn}Sk>kcGVvl~I_&Hkz- zF%Dh5TE#HECv`hc1xdRVTjY&=4a`qhztcL^u0-ZuH_{h{UO84`>((j4sLJK4mg%&} z)K|q-b?@>4E7xQq8$JoVF(RM+vT#Z+ciSk(yBC3h@_P4jFu6 z`3CHOQ#-qpjLE1)KJ}3T7)`_ZNx6aYqFfef)tO@}z*wJnj)Uc!ND_Lw0@ zwN?-(yAh$BxiRid+(qEx?V-@tY2&#@z|PVGPQi|$aFf_D zUrnT|jbhI(iQ&-St{pQnG?o-(Igqs97b)wsHtl)6rknA$A}5$uU8Y)12nL=zL)pT^Nnu~k zNiqXgfA(wr!<6yEEH}y%a(JXARv&aAlk!m51mw)&lrOgTBge;$hiXO$s??wam>+HR z+117L7Bm{X3=#E$*Q*GT{#X%|5ee_%yJNvLCV7~6663u}g7xUeh%_de%t%9qdV@Kk zH-nLngp_8>8f);*DDAjGP>^!;2NP2@v+)rdh;h9w3nPR#?Z_<4BT}7WAJHQ)(UlCj zNLEfp7s)&c)$+p3%n6_jbkNVLu*;l5F-r6}u3|DtM1b3nD2}?-q7-FE zquACeMoHpkJ|xFhlm<&C`kTBP26>LtyxCoPtWYs_{H>$8LYuYmyTkd!%_?O^RFm>3=Bk#>O^!j zG@Q?se?fW;UTU; z9kt|BpB_IvEb!tvEy%9tjr%Fe|5dwZkoXrS_LbxONDCKg$D_3&q1Ovhq#KQ6bN}AK zR}tL_m~aosG%_(A%NBRYKhci?p0%I%v+3pMH8r4MA32X`u%hK}Yy_vJKL0q>a8_)ScuSF?kJ70DH2!4wZDiuv5Z>-T{lnQQ{-!nqT%#uzH} zc+VjNDz`V=SX7?X^GT;g&Pilo#-;PHl>&kpBHiKrVX-S0p0h;)og-;y+Iqm)dmu}V zPPcz)E^ln*D(C!pISfo};Jmr)uLnor zUf%7`S^+7Z|6dyci&4bjMh0v!CfpVvGjVaaA*=a=!2=GKo07lj9o54xmQqzWD$6e& zF1ugpD__IAwS`5VW_sj&G=bZTp?RNhLrGDJCCWe*`KQfjxhNvR`1c!~UR-MRn>dK* z{t!BNZmc!740h0Jtr{jpGfxFOLS*rBnIgDFES2cr%v`~ODX$$(=T>I8`D5zb=@&Ka z4ZjP)?7z*)?%Ndgmtx{7VoL*)pNQ;8eIrsO1lQ}lDx;j^)YORoCt;ibokr7Abn>LpRCZhIBvbQ&c z^|HYJCnl-`B4XvEHO!RUR8)tHBZ8amcNFnMNIkC;3%>UwYK2PO(S4E2ut6lAcU=Q? zR&d8AeuR;`0;3`(T+w$|BIDIOhLInI-W17uIEWoWP%QCbQ+zzBtknAu0((OGi?Dlt z2udH6zpb~sdwwuus+E;+SVeS~ti#`=jg%ay_(X8SW=%?&=(Ia~GijkP`^1O#%*jp>7}>wY zh}j6&;l+%b`Ze5e6)v$rvmd{yU2~=GMBpn_hq7U4#8l@#z(U-^+Amuni?wn*muTqd zBut~qIi0R7HywPfq@UEVV3vHdm;1gT&^ESdU1JlN z+05?~ySm1smD|ac4q!cqIdS5E5aB$;-&gIMTf>KsvBxcLfZ#973gs=q{ge=_liUb# zIN|$JWSQT~{U~ACr;L+k-moTBRVrlT^T1$0VsyA<5ky;UU5Y_hPss2S!eyv>UAH$L z^TMNkhY$XTu)K_mZRys;V)jR+!Y?hI!gBfFFEtG$l%?9CNQSJ+X~!@@Vp1;p`OlU0 z%rfe>n_Dm#&Q?1qD-_N=eLd3os7c9Z!ZEWUybNxA8=*c+1LK&ZELUzU84non z^=akagCgh$^`kjM$hgc#1Gz>kj8>!`6BXzv+{)cb+jHPOz4gzYso4pdXY4j6Hsrpd zvSJd)!Fqg|XY$NVF_E=UClt(Wol>BssltLCkUs{{tJ$i|A(CWGOG-OiOtmxVEw53e zoNb3k%7{<;JNrtQiOSddXcYVSh~a3fJtk7f4QZ)soC8;Ma!H`_E0m>UamGOKRwJMX zdATnKXQC#wN?Y#hAy|&qF}RQoTQ|LdQWdXJ@70Gmji5({s@$DAc>>~*h~$E4lg%L6 zJ&gT$6P_^z{=!vB1CTlaZyViYkYE+NK*5C>U>Vno@tKuO{eMY8AD!#)w zk=&FUXUscW+x^~}kBAPK#mRWR!^z2M!c;|p&6bIJ(d)@}`k-i|GGuNaJz~v+hv4Ki z_f5)l7|b=iJnilE`C2(6w6MQONk+_+?skSu5Jd%_Oiwd=xPy!yMbi#0+az~%3 z?fw~z+$Ps+l!2?fBOE77lWpf!Dmd|5V(R44OS&E1^xC$%+M^_f@oI2IxHXXF|B=Oi z>lW89A=H6bS*>GzLSRJq5)iKYABf!W8CUe&IN6C^VW!SikQsFXqitS#XuyPK z1YPBxHwY$uezbuKJuq}lg%Kie)=l45nf+9O68oRE zqcd0J#t}!L;oWkZdhNVA24%tnNcKH-$yYwzq97OEL<0feR;1W`q`cAX$&Bn{>GIT)6ZahBbc0)KyL%+TN@pm14BTau$^k{cNps8kvZMbHty+wTD?42Fu29r(N_TZ1@|mQ09nLBcnLeR8va* z4K)aH>6?r~4Y2NL;?;rw53ER|2r@BDS z>4#^1v|432{c0`v`JbIt*uVn2H9!l=)w5^DuD)o_GwdgtA-|ITX4-A8iwbq3Owae+ z!=@{R^=_1y`>C<>MLL!Nl%GHzM~kQSPqnH^rK)y$Pag60GmCrEZ;u-!dcM1w&b;p` zr^*a-T>6@}2b;aGgaD$LyQ^X=R?gF6qc0bx%0uFwjl!4HY_iyUlUV&t&aUVFQ+bTp zMd3l*;#}6sOVb7mBqJ10SyZ&Sz(SvI_QB#sDB$beD}5#dd}cm)IO4%ivE zIbqlFy@T}_Nh_$Y3o7ak8#(x@HEC7GAtD?7tx{BCYMmyK|Fz26woZ=P}9@`bXZ7x@s(i^Vm>Pg&R21q@wH9L6_b`h()+ao)+VNEE( z%M0HcxS?S^ocVm4Bh-lIE-7ty+Qj=6%Y~APo?Y|9sLPB>V4 zqYBTDy7?^PGb}l7b$O6T)BpP*c8NdjVU-3TO*@CO94-(O@C`3jxU6gf7Gt8GGDkce)Iy+S$e+CzJ?1oy53JMgbr(Jvwx8G z@psnaro~9h1c|9hzVSD*!R8_|jBfWK-3+3{sU7sOp&~=FizX^6xy!Z`pp@;JPH;qd zvyfxj^v_;}EOep5o*0!)OTi?L|(&Jr+`8#VHpxDZUcs%)#aI94MN~bqO zJRz^$14dO&QT75anhLM}3bwQ*))R`M&L64q?(M^yX9Pof^78EF$wFsUp_aPf?E+m$@(5fQ<>40siUL)iyd^ zLVqk=M_F2s3mx+K2YAs*_~E;cQUU_mA4wM+ZqkQBPb+_Bm|ZR6(^-hM#Scdz)iP(` zXIQ4BWPIxLsJ{&O$t7at*XN$tl8@z@NFdNK4bPgVt1M z<#2_o6*9f$cxCzcMpr<3{gVQtZlpl}}4uE~6%Fy*3T_TtSst z#j%JQW)%#2s2X4}l1n$^H?q3`r69HnPFnxMyR^P7aC7>Hka-|>f5b%HeyKJ>CE)FX z#2;m^2&8LP#s)P!;U%7k~VJISWHFemsqJvRf^t2$*k8M_nBAv+*1My#vQohO|tni=FGR? zqcxUjCU3HZ%tl5y*19X0QW=S>ge9G>?-Q*TFHNEUs7HvZb?RDqZPs8I|K<69vkCJJFluLe!s_S5#!lY9fr^MB z`>@gd86=||bvGSp){w4iS>T)hoILKDc&Ss1sAFwqRBWbMGrN&!-JQ~JPj~Gq^L#-Q z&do$NlIR3iqUgk`^dNRNbL@Tq&0j;{GHTs;o~|WgxaGvMKFPcze&^mSKoPEYd`+Z zyo3w7t%76C817(isU87(&&&lC zAjUxrHQ{yeDqOhEFCYAs(|0WuX38i- zCeBYSRfRn&k2J z)pD(hpOdN`FZxJir(2b3O%Revl-?m&EKTg0r5JG;|dij53iz<=9GJX{n> zXJ*f*ryGyd$*4r8W&c@;fL2|!x@fl0vn!s=kRii&t?yrsJo)?`8vbG3V?&;TWxj}N zZ!KOBk;CASuq`k_q%NlEZ#+%QbjC0AwT_%!aw{yQmLC|kOS`A73CMOFe{Ik6VRFkg z);k(RrYI?{s{K=M~)P(}8jXI%mz)ggLkG&hSjQTUqgAj8h3;W*N$ z-uWlKAUskdwt1*Ep_E_?!Ea%XjFv_=)K?6#cq4G6)g4v0fG_*%T~;I&+2FGJu=yKm zF-R@y=!@Mb8;iz*VT69*WzP3W=%Y^$<|TE|A&9TaE#$8V)JCRU%^UcR8525TPAx#P zc^pbEP<+wX?_Bv=ugg@n7}`6!y8epqKYQI0r;dxu_Km04SG{5Yjr|w#%t77B(REBPebDa<^)E|!`m+(8pEV|T+Y}o33p+5?d6deu^9_K9!;9j5ugI6K&5MdO6 zzskw!SlRds&Iv<^7r(<<8?&Ly%Ym{EjNiH8u=r#>MN3pX@|GO*^vp$y=vpGIdm0tN zb75^enZh$-s%2&^ZXTPHLp=U*56w-4URH{N^HSL9b~L|v`g{10nsuqi%l$b@P&zL= zj22RvJ{y@eXTp(q+{>GM_kEA}by2=2t~OV{kq*L7@pLL&;B6+9RaTBRD?j5V2UwuO_%>G4*Nd&wr!pEx6(ew_w3;8clEr?$WrsYj6t$CqU@N9U6B? zAOv@J4-Nr>LvVN3;O?%&+Q6a_AT2+?<0UDyunRh z;{B~^r?7cC(nGLw23Wqe2U^af8`#2yi5Vwuume<1-G%)BO6-OgH>tSh?^di#NcYsI zjxzF|8Q5N?rl_j5*JbgbTU=*!CZzS6sH4^=oi|fqh(s`K>b(ip$@#~`ZUzndb4 zJ8PKb58Pil{T^>6AR<~IbK=C6G~>y@vXNwXo?-7p5tmbO9R%VO<4cPeEm5G_ONW#z zQ{NMd-9-;u$dPo2?{AH!EPGvL+7&ETI~oanyd8iQKV$FJq1UYuuYjzr;MriuV-<$| z1t(#uyYE+~$osENsQn(gRJS_sbDpkG+lssfKHQ2bKq!1Mgym(WAj4KRQcu9N&n+1X zhFzdc<;3%7b{C~%HL)@Aha&p=a2NWx5bpkrI1uOb?jcJ7JjK_)FWlS3)C-3Kbr)5`*<>TX)snBT%%17@1+AM5QOZ-{4Z z939qfY}am%8;V^J-Rt2wmAyvhH3Ie{C?4WCHViOaMvW9?S;hS7;_I_YC30nBT`dC{3zI9f;Nx^T{ z%*p%q%Xu)8r+p4|Me8zoF!nQzJ-{91gd6%}LI9tETB5B(T)oCylA$J+b=DXat{9~y z=V}AOWP9bsslanTv1>5Qd-1ej9((A+lGMnoMX1=~^_&x5z}5<*xo?T~%@~r!I8ndBu2Y@ylME;&GB3USDchz=tGrbS3106VQ*(REQtgNw$6oxDOR*1 z-JV2qyaSMramr)BG9|cbqrDsR5h(@(=1S|rdvTOcLTU^vw;nF^v}zmEMZNpm;P!r2 zx3su3oO+*Obz1qSYw{+6n`4@E)Gu9I2T^)Qc8D936P#-Q*4{ufTH{0P+Y8!Dx7t>5 zl=@S}A^m4y=c2`SUyk1!vy>^wTEH)+Mq#?t3 z&2$%YqMk;HrH#K!Qw&6ywvMiT6bw{r$9RYtEz9X!k$=($&r;_H?IsZ~xl-Dx(mQXG-h34u_^*wA~D`KQWkald%%s za{#1Q_e4m@YeCJ2Wyq1J=~*Iu8hl-8`!hJ2MXHF?^izO)nW-`H0l6l<$Axo^AXOiT zhSLb#w5bDpCFx5l@*)%TU|BSTr~88=k4B zaqN|U!4J=TVc@$~Bkq+<+->%JS#V;B$}$>k4T`Cl%0Uf*oE(2_i?#9X>5^xY-!|rt zp1N$XIDs$Z4{#swK>n0N;>#JE*D1%iXOFHzLz?BV0?#fiESQ+-t92Ha+1-Veg%tw( zGClE)b?VRWiM!9XSZP{KY&%Y_ry}#v@|d{r=3kxo=CY!Kr4-POmHyJi zY=WMTCd%n0pIc9Tx_zEERYhmM>dJrVg%<01_=um0IS{onx8K^nEbt%m%8$)2WHPlP z(MNSjJfV?}AGrs#_Cw+2jabdKohB-1 zD|uUxEXpJsaC#mc_AS#`bbru?p)sf$BQlKZhsQ-@!(s8DD;}VMCv-%;@7%UJ2i&d% zQ@t%Y6Zo)2Y(VnKygk;HT!>$uegOZU*ZtB@(e%)w*gvw`0mV|tKt*%QY`K0EFCn+DT#LGIvvqDDI+He8>(>44oKK{|VHj=OPRBU})eUEWrdNG(Bo z+zhwIAK1G=>cwtxFwEhF6doPX!(ewLK@Yx*u*7@F0E&dRgDApN76pQn8W$gHSd>-S zbKBA(?>+`lcF~igyA~wei6{-3z!j{rs9B+Sj#E{lW+=MICOJ@WGN(l-X%jT=4h?S{z9*2L}}1Od1dwRu)tuoY`fH)sZq~z%>vcJg;m(w-AMHLpk!Gr zbFgHzZ{$Lucj~bsyp=j=LflxjcTWNuA2H^8EdHB%aICqRFw@NwVol za?(BSa9R`>kwpDO&pcIyah^``S;rArE5^e)@tA}{Xuq`wf@<>MlA@! z;Iy3`Kba7yf-Kx9cigvc@oJW1L)kTmiwCpKjPqbXzX)`{{;#CP$Cr^V1c$INrdtr{ z;kl$6eh_wIVZ^=5(3g00VgtU^EV0I3nNi3XGp$bEf0z@9BkA|TK;K@tZft2@3g4M2ExOpa*A^73 zumkpy`lG1r*zv{tosmC-BC1QCwp4u?#>mAI2Re1?FRjUbj~};|dPK{(8qT$`65=@; zM*%$pN)ybX=V;#C;}hsJ4g@BXM504kPtS!4OsC#ua0UmxHWtnYG!j} z)}^lU+*#O8iAOSvXot8ysvJ&LIgu$ipf_KbLn?{Ze~6&^NNaIknLYE((bzVT?(HXk z_av7$>5Ks|ppF{D?_Ft*oc007+|i4?te2|Yh^6c!8U&|E3K|o2-<@sO&Y-rS4W z_ld*S|2StKVy-a~D>fG{A4qm}IOtEm?FdCq{7;E31=U*?f)g%}>Vgp;EHOHfWMos8 zUuV6_@;f@=HUwtna&el1w*XdZFduC|=4Qa?iqt+i>41ZG_F<{)I_JjML2=2I($4Un ze}mrjg;K)Y%06X;J2^S1E|K^ils$TA&I{K2V=?rE)u6!8+Brug}H*O_F*_Wu3#1D zC$9?Qp4!IlnA>vZ*Ef>ZAR5+cs7Bz^iX?yg|H9l#W2sR5jrISL3D2(Fd+@F%rVaqB zbpka1UpaUsDI?JY+u>N*+H-$D=T~EFeS)@2c~t%0ujq|BQfDeb?H86_5Uhx5|JXolq!bJK28@ zv6ZIyAn)RLG|;?BUBfl?k`rDOQZuT5Pww}i;qiJUJ&J*mQubxot~li8BA@PbnRq}@ zeQ35&=jvhI;nRnRS`S1f&UoPOWYXGD*vwLA-~JUjs4+IFP{@m5bkj8JO?P0$6W|q!oU9apz2)6qV0wv%bx&zY>QI6|CqXfwxh9yL_{sz z=*1g*>U&s`P9AmD=3;PIZo~KR_)qN#u?B-Er~!e*DZku_3>kV!d>mEKi}t0mF@R>l zjM~(2FLw3?MPFe0<@MxLIJS?C8|-~Ay}_M$c`4-N?f!P6D<|syDi!LoA?kN-5E(_) zczgCG^h)s5T#>MVp^k&WTap(>r=6sI(UX)lIHxKacX;@I0k`qxS$x-r{`IB(rgCUy zt)1@mS?nomTUP9`ZxN$_xq?f9g&^s3fBITAjs4I`b4JPVu@>cqIH|_ynUYga!oy?c zluvh|p&{s*Xe&u>EW?MFn6-n>9Q3x8$g26W5cw zJ`)!gV+xm{R`71|Jpa6StgeDy7;7z@!t%aRZ`Vn0rslg%U(0mzjD<}(Oyw5JDG)ui zk7CMG7-AkvMsny)A~#QtDKV{z5gU%QVZF>GF*5t&&wDAzq;vks@+oMwDC^490mj;w zKsVqp0GjONj4Q$?zQ3ari|HAWRA0$wtxT#BCf|p&OwW<_Z|y~*%76lYE!jXg+4xCd zGOqk`-83iH)DaL6nP^5j2~JC)D;rEVEF!!&q-OFq=r`gogv18{cq8NFH4&k>!yy5T zfN`oZZaL7HPJTSa`8T8lmAk*anv7`f!8Q9@ff#c$rJ(dvm@85JdQ~+af#M}0bS>x8GU?k>6ml6 zMEc|hyPMWdV@9y#a*}iu#7JWk;0oVe^iLDZ&59(x2*wabca1O4DGE~qn3Vql3qR9~ zOz*y5T%Uzf(o}s=Z^sS=!=|&b7Q;enRw@Sk5ik+I@W$Vo+p3I%vhj5ctd;4J@~8<> zBkxWwCB=IMHT`f(F$v=%{u3-&K5qnX+;71;Xg= zawISnbwSKw1=kVS26ybqGumt zX0QcJothmS_WRh%igLr};6gjuH!@aXW$ZIvoC=y#VBhzWxfp*Oa}7L=XxzFeK=3@3vxz`US#$%f@)A`ZJagNWkIVfpBo!LBQ% zBU{2mC#B2HnPDl_)Hkus)RKld&NPv@A@eb)X!DlOx35%h{gRWs@p|nitD!Ew-A)|M zu{7wW87$iqOBhf=ky!!s5jFot>d?)A>KGp;p{S=e-)ktpU`)BanQ%s=GG}W4h!v~Y z<3yHRX8G313Zyma=j93eJCsD;2WI1B2>J#lA`&3))2~hLXl)~(k92NfLa!GxwY1uq z%Yu0H;@nkoz*ua9%VmC{6j0z-MXnUGv`KSX(pgN12jzX z%U&I+&9agg@4XM64b1Fmlbf{@w)^-qV0bclhhDWzP8X(El94h+S#M(W9CYfZz3TNC zNpff~I>(2X1{?5wxsv4dpwu3!3y)MO5F^;nT*9fWJOqcMjNf=QA*o`}%E4acda zUH)D3V^kMy_?`)V&bxCbYoEQwso9MNe)CdoX>O+THB zBOrBriA!azydk9FcR)@zCni)ycVDrIL&=xj<>Ok>4!$^N6OB`NJiNNnxjikanYmjO zbclE2gO}Hj1Y%62``*~GqeKgq+r_z7|C#*5_)cj2&@SocY462<@GdU8Z)s1sgh>I= z%An$ak<&*?G8usI&~CkMw{umYvOFi+#)9H?|yP_nAn-yL9@ z3dm`Z##swUPj6+x8uZfDOI2JZRxBRS)x3A|j2_B!q8-E2p4MOz-wSj#nxtdGkta;a zFPHU?IZK0JS9}!*?w;^Fd4A0tp2MGvG8zmUDsmES%sXA%Yo%>6G8{7IOuz*!zu6XZ zAvIs=LUuU;r7q1A(uXqW=q4$V7?xBMHXjW|T4Nz2lyfPnT2sctF%$nn)A=+!bPeQY z@XW>~_*~>Lr;py!RpEY@4zi#b8-r&)XU4M+k5>~vLck?=ul4#|lwY_0C0zair44@MAH!7*c*5!o+#zbmTK(v>@0C4JuuL7^H_4Vp8(-++;&@Yb&S z^_^YxFIvM;JHxNepV|@*gH@6+#Z8w}Zod9Y5eA6E1O6%F|Kw_#BgaU|6~`kn#F#VXva zmm7Re%nvUi_C7vBcnbjCgYo8o-0q?zA}G1Av%8Gu570*y;HIqUuo4JNz48_mkP0F2 z5fKnfl<=c*(bd4FHX3VG35d*lg8AM{)@&<*^8zYb6c@FmDia1I9mA$DM6l^Nh z_pOW`ENSBQ#ZOkn;;1vyp1&GBVqI!xVLW7Ju85)5x&v}A!ISRMw!87(0Qb9lRX<9x zhjZ*81*^hCeoBCcuUVn2{UX5IVYpL`SDW~+ zX3kVdK4loFx9Nn(BA~N(ZNr5!;)pv@B5Pi^siA>F#(cBn^76q7ygQ{J+bzY;<(;nkIws@18iTixQ!%#i2lle2n}-MZDke&y@jiF9Iv9)6F0b{`R~qbBboIyGP}w*4}h z{3CUd6z%%&D8X{Pw#(>RhJ6hwjcqWxe~-@Bm2*#0$j=qD#Yn27!DRvb@cY3@Gd{MC zi{7t)(>(bm&<8?da;}3C@c9WiQ$najQ zJm9IA0vT0pHDNgnv{S{36;f>av;B4iwUQdtUL9+HzC7I_2BbI9xQif!nVGe3vb0^aF5nLB z*rJzhXFz9=hZ*N)VDI1zRC7%<+~^P zXO>^(329+Kpd2Naa+{~6xl4UMX+rF-bBQPDc|j`+$Nvln{GnVQGvPp`_&LY&l^Gvj z9m>TC)yGSvUa-@BX)zq_C+n;wSMuZ}>vKBI2*EzAl~tyw%w(SDGiD6z+__(@l&~I_ zD2>=MTse)n;&`Z8h@Z5SOqW5y*=`x{u9XO!PvSqHH-9s1YkZ%koe_|@%uYn@<3~aM zk>p@Mw~VGlRAs9{8pUVpNQ9kE^(oxK+jtlZ4n4NbCHV8rW%u_=T`vhO#gR^1bbVRQ zYw<1L4^Yh`g}}Pdu@sE1ZjFd(%>}ctTI|{+2Rv^GU5qCqoHaxK#)BCr0X2Po)702c z-Owk5r7e_JjrAWYrso^HT((O#I;h4tgxySg3upG0n?xLkS=R`S>)`kQ_U;D2DRvPv z6>!U>zf|D&lN8KjwN=tgwA(9wDL64K|2toM@i0ixo;eYb&lm23`rvJpoaK)&n@HbT z3A1B0^>QBJL2$^nRU(f;@lM@)O8aY^k(yXk8xeo{cd1M@#IhfLy{;>WTAbQZ@RLEw%^Q4zTV7vFZvhF?XUI=I*9(P`&A*h#Xmzu{EopV)ob;hqWz;tO-rXZli<*39%u zcEI2D$4nq=z_S&+&PDRV@`kXVs6C#Z-uIRUoB6U3{$wd{=;=_|l~x_CFyB6c`ppV; z*t!{iEjVSD4H|~O$v_VIkZEZn2_bywWTr(|G7RD*j-D+(@(-*b$>flOkaKiww*6H< z@7SPdfbT_Iku~A^wD~YA@cyRpbiO!Pc=39XRN0=6a9vzuIOq$rF@u-6V2}Nx;EFSY zThJd&*P8|*c315g49uiOaut*OL&KyV;-2fe-d}&z*6vk0r_r_c3QzPq?srxMSjA#A z+1Gru5l011mjWmXfmvAoWH*VU6@hiP6SCxkNT*Uw5>P?10nfVVo)Loz`-&}@+p-b7 z>ikKAb2)T$Rb_pWSfSP&n!FsFYoEOQv931ulTV2tq%Td?Re=a0#q=d?FpThGKfV2j z`7>t}z!P3??8zC*B#*F756-@|EZy!!q%Ynd-}8j@w3fWw!aLgeJvi;vE5PM zbM}7NBHZOv!p#!)qTMYjr}4BmzL|1hI9ry87z@(x$N#1hb(@BGEwuk_v|1*oM0u0L z%9L-p3po}sQl9kb;qu&%QtoH-!$p!QZKW4GlN}^aHi|E{L zGSo>C@&9=qmgX*6V&K7a?05U&pC&CNSE}N1hdBVn2>}``^T{!d3mOgBq@6kxO(77NrP|xrADO8&A0<;gQR`DG0aTK|2A&* zt*ZsBXqxzH4+B50angnAv zTQGB;w9n&B2un8Fi*j?;ZuaGnw1@GC>n8n%P5P=y2m8MG%kaaX^D?5WGRiV?7~euw zMLv(iVm{Pef~)@RE6eV$U4?)cZeoIBqX^12;BTX9Gi22|^}~k@7Ch|3 zHCiM{4QosXpXSItd)CFuY-a@=TetUtSXY;%{jJT}Q;oEk zA@_*4HW*FMZ~23--|G`PjxgZA|)Dyu(f z%q&)X6yn9~cNgNPE&Aa0iso@~kK=Qh(Bgd&+VaPpY7_UoA$BuQ$|}liDdJ{8=SdpU zFnSwsGr)@!^tO-mM$ofg5_i9dLvUVPxx7?dMe{#xtg7|7(F6UNBJg!eKviqpfSz2R z)`flyvHKKZkB5@c?}106%R=E*f@>2Eq!zVIK5HZ9ehrBr^W^U?%lyHvODn0h|LA@& zsld&0v|OL!fGW=I<^FOT%O2ow;0*Os@~nGtcmB-*`fK6>rr}=u9* zRYn~Dyz9%uMM^wTIB+|cN%#Fl{kO)(4=M45@gDO=8BV_~paCoMy?>G@A0wRL0j_(v zZ2YlB4=}khCBO1qy-(yQ{e2UJvW9t$F#aCgcEJ6)HNzwz`E!-CB8K6iNvevyEDF#U z-2q8z-l#M;UhIA%s$dZB0%^_1X!lf+Q_;M(pf|U`#_4k*ypy-5Y$1~DbXP@o$OdSg zIOIs#N>t6G_HK&E*}CK#)}wrl3dkfzL9SCJI9Ycv4$>>VSqohRx? ztrGd!eo9JI)2p_KBR-!+{Jcy znva*r1pZ`x4&ID$6VhTZT0caz)&JZ!Jlfhmv8&;6TQ<4B)Iq1et|I;UFWz0N4~Cy& z``V_#QSE>KamCPD5^oSQG|U$%ugs(Z6PsUrK`=Z_Sovhb0&3c))FKH-e&@X!=974r zC_x+K-l5*wG(m$LtklNgAB~7(aQR){Rre8APIfc4z2fDkyuqIsal!?-67Tu7m}*Rj z_BTkn3CjHCQycDm3Hl+UCgWRQl){pLCF?t>CAzR{t8tqFl zq%|=F`;nhLTEz%7OA9DLWL8Yxa7Q%Ef#cN2e^^*EHZ0?{nh&sLDQplL zUvJ!NpiEYWqpPGucb35|+8BRNSSkSjP~>#^dIZjJ0@`g@;FZ zN9lnEaM(Y!oZk90#3ixcroAtcdSZ}zb@#zi%tc<2cWs+^w4L3Rp$!GQ4N*gwNdxIi zyfMO%lYU_GhmQGNT5H^6Ew&oxguKyj2ud9koFbj0DO^370>XWovK{bmER4qe%2IWo zUYpyn=Ys!sd4PSH3Lt}9)A4AZ6rgzd;kXNx!hgy-A~tdiNy{$%4$AU<6ve_k-6T88 zdAQdnkYPH}tmbcNS}0ytNI_MMG<>G_sBRPz&}=J^a@b{b*Z5yfd+fM4_zT~mGFU#g z=JQHE&o{j~q@upXs1LiTTg38GX|=W*YDv{%>CqBlCjSi98!W@@g}@(h`p+A2ese2=j{?d*^Lp2u`>pS^7SKNtFNoa8Besx%Z<;?~Q7f4=rCQlc=ot zji-6G0i-ctWP3C~43Rl(iXLG@s->L^kABBYdt+#Lu{)v7jo;g1q%0UBZTl4jP8&1< zZIEKn?Qya}`+`-nxnM_46MubYtlaP~fBCgHy+?URD* zo*?yBC|Bjv_I@1!{<0X~U6tBtJZ)BYi|Uo>F)MZawSK>fE?zIs)Ij?$!`X_;Vs@du zb=28RyTV)O%#Lt7+=07|E4SEw=Gm2ED|5yfYhbw2z@bj4sx|R;lEBN5t!m!?c;7O8 z;ecdq5;{I5aB)Y>(!UBwjt#-LB~ zyDVIX)o#m4tA8`hI%NzmJVnzwgFPkE;>Xp^eYLnH4K~D8vI%ZUYFg37n@1+1NFCog zv=_9J!5BgLex=I($}NY)S_w7Ry7g3HXO1m@?(k3t&!AQmV-}`TRFYo|Lt!b*%_0iS zwZ|Y&-h5N6O-f7 zRmrpd8S#3VdHqcaUAz3rjbHt~Orx&QnYgs?v+>D)eG9K{ zBab_;N5IMdP1jz;?5OQ)_U{2gRp4-XED&2^1uN|g#_JMXHu3Lv$tHd&qe?qTPB{^a zSeJ4B;eO+*mic+d@e^iZu#Yj%jByk)Ao&MT7T_iNcV`RG6k;5*m1>O8^?6nFQ7+a& z&W8;kO*^<8_)SKNJs21V+Rn+yQb<Vp|`pVJh!E`l$Jj>X02Clt()7Q7QlyYCVI6DKC*ejQ8l4lyxsmnZ@T z_eHv6WLIQs+B%fNG|s1RwD>F6naQT)_uW1l#wI1oy0vdlxqsnVDPfe7R zabtZ~`FdCftK$Q(7R0FJgi^K*XH(~CnTeOx{CJF#{tR!SL@jD$_|d2y(<;t5xxO{72F)W<3|#vvZa~jlPlf2F`y(I;FK9_)zX{j z7ZA)ul6C&r4^Q0B{R_pr8bg?iAdN%`CDjg}D|Et$UVp|T!}eog9OXj9c*VyQ`oY8; z2BNEnNn$X(G7$UmA(|ca??Zqi(IC{ZnLk|4D-$E?S_%p zL+?lD-1YJtOoHeyP^%=N-VFX@v8;>ai~z5U5nafK13gFQZ(ujT7BIWcZ0oxKf)*P$ zWi4~uh#9L?YhNxpil>_R%O|xIR{yC})~=mS7Vp(|aoq#m$q` z_E+&&a3cO(NNin7ZxX^tSG|M7C1a4dAjG}htViJ1vuteEtGwt3{+v*7VY&7g3-Cp$ zkLcF;AvKb8l}KDJTK${SX|}UoXT-jhpdX)x(%A~|+iAxqg5Z6#-nH*5wxP`|bYnox zLS4N$IdY6%>04)h=53&pTvd_D zKO~7vC;wSJbZw@n#gydmkQ;s;@jSr{oK>NO?Q+h-^zq5PRY-(Ef=#CN*_bje3&M+l3D#NdO^M}*GFAIV1}vsI)~r+2J>NQZ zDdGrASnQBE#H6I5(ZSH3w9dSJUa!%saAp$@*Q3#YzI=G)rFQG{jXIk`ID)Fa5Q)hz zmoLNr*JQD^e!cr2eT!@B~MfxI9^7zAOJms((RVcd$ zxeFm+bZ<6Ri-wsc;K!^2RS&j2`{7#|`NgVUs);G>Lo{$)x=)Fh3e1;zDkSnLDitbc zP~*+Qrp;ILkKCWe4Q^squ+j%@nmfZ3r&!%NF3WS z`LU{h9erILoTraZsQQxuqR5pw{T%zbNuvu((IzD@5pMf>Rqe5aF3pL$AL;O7M5BNn zg~Xu-GTP!AYIb4NpoACEvrC|6yF09LR98N=OMQd)ld$fa%F@(Yf|L-S^)SzKWys(` ze+LJrd{0v#XN|k(*dU{aY~+9po}~>c3)323N6`Y-*B*i_Xynb+gW$`jF>a|mLpgDO zo57{!@uF$KKyi5h2HAL02Vin(a={hpfPml~BxO9>6w-*$7ROL^p|dyDiOayo#C3Y+ zojASevf!#{EH*|Viahz`E) z`9_c2kLB779jb-cRoyKy8dRRdmN_tS9#b|a*t;L?C|j)Y%ei`GkT*?Z5N>*;XXd+- ztW*jK$zG~bBcfC4w)lnAuDDok3d!8}6GHxQ|3sMT++)yYPWYtk#rdYR@5>e!nm}kb zlF0M3*3KnU2Jv?;)7nWpxUve|Wb3sQV~fOfu#V!yloZJxxIl6R^pDAkTYu~bsU@1+^T#j`>g-V0UxxA zS15eix#J-6{2mdF!gBLB*llrQg%uGT1BBEitV%Jt7nK~W%^C~wG6B`YzK^RR@}~w4 zL`sJD-+UV56DPE}f(zm5erlI+-ABE$HyGYuZU>_3y(UL8d$n`ba>i*|Y?Y2>#_r!A zW30x6V4N!aY}Eldkx0YG$C0560`Y<;iBX~D);FlJykR`IdfnS;3w0HgLUN%lmCFY& z7x&smgRkf9FVwow6k+eHw)Bj(gb8<=d#e&_bJnF9Nl#yJ*IU!&?-_TV!f7OhC64ie zQOM}y0EemfB6yC2$-^QUoz97^Pt4ry5lO^KMuIaVEA$ zndksdg&l0o>*+vd*N$e>g;kZUvY=C*FdTlG;2 zW@SVlbgvBlp4T(RDkQyzzWm47RsDT?qtgGt=l>ULu(phc08)mjY0XAwOu6Rx5~y-# zk;b)Ft!Sl^TqRSOE(H<=(l?&mdOiFjL*M@pXU@*sY-c^%R^@u}`0%xrP1mv9?@}Rd zzs<17^e+M;$awHZ87Glw%BnF#Fl%dS; z5Dr~4CM#H61Y*2G9fIix#;(mliMMbLwjhwXb@DdNqMO8UoByir4|P%Y%IvP^8 zA_`^$V5L@oLHwcXh$Q{OpfvWv>REShD(BXy`j!4{H+sOIhDE=n$Xrx=;a9c56Tcw& zrc!q#2!?4ZG+BTh9tBM3Nk7$#A;{%MMPKcVID5)&9TI})A8x>ew(9``r4q?$e%@py`YZyjAp8(QDDB->Zv?-(8q&AZyYO983(-+ORDAf zDZ)50I9wko*Vkdl*15H4SxXAxt@^f7I|I;R#A(edp+3p$o&ZT9Ix|poNATjF@cZBP zf!vgj+)AFz+r8Hv76<#nBihzP&S<@$(EM1Bw!}0SCjBu>0`*luuR%gZT3tS5S%YeS zT@L+Jlv5yl1#6CZ_*R`l1fiIBW_LIpX^^ZR*d#4O$262Sn zb+ALevoheMd{g9AXn2gv!5xYThec#R`EfKGTk?qKMIJWf?qkpZvWb&T^{u)j_12Y% zdqZgl%dd;Du9Vbs95-^m7*mw&&PRw(Noof#H^n-25u>pOg@4oy6tQ1S=jZ>|a-1%& znhz-vTia?>a>)p~MoY4p_N9YYAZl!E!s-`j_k%INZu?zl?K{61Xz@j)x04Py`ha_E zz(YL>hOGt~X^m^-leR6$pabg4S-xrOFKqVx9Y~N5>(!^7|LDgF9wfnWIJ$=fcxm5B z+Fg|LgyRQyiNYR;;^2}+1(cQ8moaNo&8Vjaaw0YJ9G&tY&i&?3t3tQXX^bs%BVS6@ z3Rc+Z{MmS}WyF3&%rUGqi141KI7k4g)9^2baIRH0qOj^?t6plSy=h-o(`}%K07b2hM&B`11m9Qr?xcXv?D)=lNqz1U_`RyA9m9lmfOGFY(TL7L>!@&-G_+I@$@n z@(f+|VyGR`cJg$kcNC`T@NgHLg)%`)_z6r7Ip@3>kxg7ygF|09r@GlldpXr!=U_C zbj&&@-94uI$dN69L(eQkC3NwNk?)=f_8w|j?%$PSKlY6z=&e%X7D? z-ClT@zu6j?ZcJtIyd<&%HUooz5m-iI9^lP^X~9i2J>0YtdfjgcvS)bfB!f*T!j0J0 zM#JAw#6wGH?<$9k${AAtxWAnoDb%$PJF1Ta0!69V;}XMRIr?5w(Z7EoVGE%|tUBa6 zdyNQ0h{5?kpFSz(f^k%U4~oA51Z9 zhM;V&Iymw(`~P9wUo5tO>u^^2F0>Rxi z5Zqk?1XyP0%kS$qhWg@7zB)e z9$?k@p1U`?DUq74T`?b~hVoMkx!IUG%aW{r{A(;tHT1Oi9B2MG2ifr=6J-GhhehE) zf}N(#yk_;c592uwzbiacBK!KQxnU&w0zPiUImq;rrjBwKuO54!2ynf9CW!w#$-De- zv?-QSoey4D zhl>jUZ{@Jj=DIn8tx8Bio-N9GX(3C$Q1NJg+y#V~E<92W>65cIM4EK@()l$*52j)$ za&nLOP~8Pql4@`>@))SUfejY~@jLhOAl-sI#-DmGly0uh zm%wJ8qS+7=r{h5Ql5&Dq0oK{QGp#^3h(ZMY-4?>wk#9M%2E?=MJ-N&eQGn|7q{l|c zTKX4RyAV65;B$>z8l=E$Vi$KfFiT-o{r+rY0d@=j&z#t6RO~zmJI z>Tkff)5+MG1=dT_!?wNd+6?^&s6|Y(cN66mODW`Vc&3v6_`xNYC5Ihehyp=OR4F!s zZ?hlkg8l;k=PN(t1`STnAU8zS)z_XSVyDN6MfjCrVmw%fTGc+2G%}n*-D{M}3A8F_?9ypNPRhr^5 zH`F+?2ey}D%1p^oEp_J+O}gs!2>0c7h3)uvfthOG$iXnJ`$~S>A?4wynt7Eic4n&oXRY2m1 zFGE^K%<6*9;ZGvvE6*+#4H1WCW!{w5yh5&(ywJvkdnqkRJ3QLaJ`H3vwN@(eN~o+` zBW|$eNn`%JRzwCUBJxDpb|LcMF_z;C`yA)|&VznN9{K>F6xM$TYc+Jn$}wlZ+4= zQm=tC#M21A6O}N(vq^f@eg$igi=NXA);Q+<4|I?lB5A`>$*1eIJe42RgApwg+eLU(gT5%*LO7z6Lu2#!azPon zKRA>7OYi4A!dob)>>Up~p}Io?i2>YKdXiZ`X4U+T;&(U3#pC3D=IF7d&l)G@6QAOp z>9+e}@I>w`Q1In-Q_^5lcyCzPR85$6C$I6TuBPXUcqU3bDhCdK&~dRrm$&FC<@K^& zXxr@6M*|1*@34 z9wqr|5Mo`PFlaV<$+%}j@dbR~6cnV0kQK8&e9w~nr{#3`KSIRU_aMJufd#*0rKuGD zW~++7Fn)@xSi9wPl7Y1z6p~n9t};)H<>IEZbT7^-1dITgqdBE&&jeD(qm?2v2l{@F z8dJFM&Zui2??qo&nVipR4|<8f=bW5TROy~pz9b!TV3n}px&J6-CZSOYUl%>qm*=d; zzi~NB4PWwXZo__2lI(mmK+Z+1uy7S};IzSe^m6W3)BS}X_}kEe_w7TA1KB&8NOcq7 zn~j8rWt1l;km}js_v`uviSTHtzmyquR9j3GTZo+>B0A>%beNk?rTlY#c8f{cI?K!L zPQot8Y);#VoJ?laueZ9TnT9m{+q?_xa5vuZ+Ie}6SfwicHOKn>e)~gQJ%w77dmvBYE}(y@=p9JGgTJpX z6nK+~PdPh7MLB#k!p;BO-3_$ozRexOP61~^RmcLTGmameE!c|x0}{t7+>&b zUDq-lK4lcNEU$G@V!zFw7p7_s;|-)=fs7R&$Cv#vS6qoG{*QW^|24P9>(d2H)AusN zY%SEj@x_@K*M+?C;SUvMZ!SzAc&g)?Cwrrg-9*Pl9k|sPKfz8aivPYK;45!cV;c~( z+tv&@_A|7Uz4Q>Gydgp8H2b8OGp^cfePFB(iMz4l3O02F7!iCOtTGy(Shs7?s-6e? zsHC<>x-pA#WpZxh;{)A}vSEC=a zPk@;NVSdWRo(Tg+Ys1^%$w&8Eu6io0J*&m_nn1mG{mPycNt1Vh9s)2necalhDbz^G zh+Fo!$Y9h7iaN44-8`g1-{SU2l5;_TsUC@A`*f5sg-nWr*4f!%zR+aGvuS`*5mtvM zuECAH(Z^;zd+%|*gq11&G7eRBf_%y0)~ZUry80U&wbwI)y-WBaqZ-<2Q(T^plOvKd zLS_lVuWqtyL@-lopYjI(mO<^2G1982^t#7n7bNO4YK`?*GK{08EdTyy#-r5zsQSzD zk1PoSd#9*z@Qj2YbI5+yjS*947c7wq5wChJ3e6zWnJ9j?eu$v@Djt|nih|y7gEr3# z$iBWY^TK67R_bS-JzudEAzh7xWmOHRZ*N}Z4IWt1jHvLe0t`7)Nl*{)yv$xj%#|#8 zE7Q42N{x81H>cFo{X*MqKY&8jdVkm;Paw+xnies4f^{`FGAJD=r%KWILA)L zc_RQrUhC~#H(B2oof0PGM;U9lfqHt;MesoV1B#_)_NMRgO!YaEkE)2L9e$KXR5+)m zStBt&g*gZxdGz4nZz(*Dvb&0sJifK`hwl)6if>Y+16h^la*CBvV`U^vh5{3#3@O7H>j0n9 zDrRzSfpa^0xe*o&n-Q@hi?T*!z$My`8wUFbie8uv&Y2cmi?ubN69I1=q&N&>D6}iO z>yA6!Eu{HF<6NRRuT$@M%|+7d55-T5?KHP>M@}7;Gnvz*JUd9z%IEMV$!>|FK(VQM zi^Zv6jHh|*g%fsu-)Fo6?D*e~TsO)k zGAT;r%y=kYTr(>GzM-eUVge+FkqF~xb71XFLmBoPQJRdBN85&s_3H}~{cOOucD!mi z#23Rt0_mWhM%ZTp`3mQ#w#i#p; zOoTjcJYl6|$M3AizSzMt@W@psfpCQSl-PQD!Na@#N8Y&eg8v_uLqL+}e~ID$DT#xR z$iH(rExv=Yr>-In8rHZLtM)`4WzfEh6K~e*kH$9%we2jP(2`C$!Yg>%!5OtLb&1!- z6lC$d?`AvJ$W47UhaQb-{3M#bL{RwCUz`HzNx3Je6?v2Y9w}VFdhDfCR*ua$eF5D zYj-JzC$Ht=&f2K#-?!{B%NjQPbJgR41Gh{;$om zAyk%t-HdxAp7GC!lPDN(wj_I3@M`p<%6MXCPQjDS$r}TG4D%Z5BnN>^IEHi&*E{6i%o6O{xUk1ge#`gHyT9Nj< zA2uQ^z9Nn?I@po62I>X5=;`Ud?SJ2;SGOo+6jd_yQTM#xqk1j|6p9YblU%`tSFk^q$1Zjmo;gG=urhz8cMBwE8D7(goIzZ#tk3Y|au91Eq+dFM znmR{2t{@xN&-y#?y0F36r@1+$#ANt&#YeM!tbaEW?%_ln(dpz~E$N8#!ryr*mfnt7 z8DnUtlcooYB1Jd*4Wwrd zJ@n%={Q}I8%!|+*xe$Iyk5ij_%Y5K@&n!@=@{h#l7R}en2l;I5)7GDRjbM4}zU=2y1W2RgH~~QBUZ08wr`)8x4X2 zpue$%^$QKGl1AkjUsP6SM!#08-y@F|_}cW@m_naIS&{GJh-?`_^(MRS)J<*WB_ejF zX@sG-45u>K-p%zsTSS8GFFK)E+y+uFIXjY}MQTdQLi)RE1FJDCB&fUM9_c>w zJ~K>G>hnw)=Y{9fM(L`LO)&6msB>2L+{ZJR|WUU4tpb@j3YCY0>mDE@zy6mB|#vNq>3r@r;55HOl^V#7eZ=MPH&pQ&Do8;PbN|z(63>BT@ zQK>;N_j?J^B=mdMWy`P8U_xScrNKa@({ei@@Anp?mpTH%)c!un8lU3O=p(bW0|;7j zeQ`%Ve(UCwymjo`1`Oc|D3w9HKY>Ck7!Ew6<9E)?-VWU>0`k;Sa+2kM+l=ojwK$?L zTjns_oIM5!xPMVr*$JS1_pJ73d5fA6yvF+r_i3r?gGv-fgM zN4U4HR>GtpL1R{7EgjUTUXUs-{W{OM(FyFZ{vr75`|SX3T*feR#c83RzJfhMtIJ{9 zqubfViG%0hD|(VD1et?^_s#WS4-#c9FD50Es+O4i>+gY?_P2D#%GAFq9pp^~a-~#T z(gW>2#&?K+968HiP;JO8ZV981^|gdK3k|{N=1iu!VR={tYf~IU(5n`{vUR@R{`~?q$!V4DgTbR)~WkR z9gDoCN;ny5qA{kljIjXb_`?u{FQibuYj6oKL8MCm%crCpfjbf4%wJRna`@sO9QCnM z&!(%$;+w)`epD zR8hK@rI~H9s;vZ&j;blM5bk%G(?s11@ueT|7SHM7X56eCMKJe@`D4#TJ;tc__d#p# zX*{3XgISyD`h?jv|3{GOSjM+G0~^7?>s(y*Squp2*k|gSYzD+7gWOucw!w@6UqLp9yMeBJN?V@b{T&9Dp%_U~ z3`N#erdtjt^YGuxO0BR$7N(ie*CRu}3WaH0F|w%sw;mdRv><8dst#*8!Tw4shy%@b zk#dA?SL5BaP8~t1xM33uTz>EeoKbF`KEu{J0bd+1P{FkGjRjnlRdDA$L$ExbYu(?< zG~cZlPUmX}3L)Lwpf2q1I-)U;!cro?4h|}i!dF&IDSZHuLd(YImgZM z(u!1WboT~+zN?1@F40J``6SZudXw>}w*GlrKw;q&(GEVQA$ux3)uYAQq_aF?+#;)r zQ%}2LkX_*U@UG4AAMv2C{D`1!Q8JR-Y}A-G91R9vZB6psAG$$rHy(E8PPS}K5)euA zioGP&v-(M5J!d2c1Hy+xlS-7m=7$Ldf>m>4Jk~-D4gw^^&Ybv6RUJHB5LBOXW>Q6a z!gy`8BVL&YL&q?7rzBhD+0NzA0+`K#NLZ0URl_9oBYvx?4Ah;y#>s5gbvp;wdq ziIuE%v%DsMYk0;To1tuKDJb-{uZGsRgWuUVS18Qe@rG^i$nX}hBQg7BSU-POV*{&5 zKzYoTgcBbisN#CuvrkraYonW~N=0Hi-QDO;%fomdJR&=&6>?|`W5bfq@?~mFBg{ghiKTBl>4pV}s?Pv+42SiXplc#<|LbONH?~Yl%CFj)SS8^us;%;5_H<2$` z!}bg~b}J#PPEDU(oD}*k81J%Ehb3o~@^vXKNvhm7ecfP4Y)b8%PV+HxVo#Q$O zPV+ENK5?|>FbI2>Rj{ifuAe zt_adjU)o9~2z5h~p5|aFk;X6zo7p5yrKkDnAzd^J5xbu$Th@ULF`AM0zEO60 zfyywcq%I02q#145SY59K2zqUP(vf+6A|fYi%CQ1|Zx{u;&^kRSX!^ub#Iyh`2jhIg zSG+VZYc;T8N40ktPf9SWg4%Q2yaQsY;@%^HX}z#l-i+6hgs4^& zG!KVrWjY6x60Tw3lMR&jH?=e$k0~F~1YJ=zd?r+4t?5ZXe`58uXQnh*kr-P_JcN;CEh=m}yW00Z_as-H5 z&xR@Pni{8OGd+4<3!Fa3foI?Tn_L~y)W2+s3n}RB{g$20pKN8!D&!qqyhz9J3^&%y z)F~%q?^%f}819Ji+u838hg&njFYg7y7@JFDvH4;Uk^WwJVyB@oKAGB3sms%kkc}`r zm*RseQk!g1jJKDma}@6tEjFKm>&Je23Z~9^Gi$&-ayRu`7bZP=18k7sT0Rd ziOEk-{*=~lUX4YSM#G29iV80Mz^>lp8!vfylnsoRXR#~tBqFOJ0q1kzivZj%n;n$n z{2({K^i5uHq-0!KIWta8eR6y!Si^OHmrP9L&70hN$N99>FiUr*RXt2Sf>!H_24xbR zD2z&rk|UEgcoq&jNKR)Z{yl1`1p@0925v856VO7x=M$EzSmIbTW7FH4N|0 zlw7#HVZilzp1{Z#)!WlQZFDOuJL*@Qr|JJWcC?^lOOxzX!hDzUl%oo_drVIl0Jyr$ zS#mleXDTFDYj*4@t>W`A2BbzMuvO7{&?SJNw_kVK_1$qzoLbFt^M;-pWsCX>%mTO; zgwpIN6J}(_KV@<;Fa^b5WFxq5ANEb2R&i}5{LrrNh07J$R)A2dt+Hs@}%9b_O|OOY3Kj5Xf^e$xK5*WHqbx7T;0n>;XaoPH z#ck<$QSV(vHk2D+HW%WqTg7lHY5b*G|JL>udXrp1#MU&Q{@3>M`&w$TU48b}@g_xY zEJzN#xZdhbx%P~fU00NEQUi=d>SC~N$@8bmdx}{9AS&_!n#dy|rDFj)+Vw&;-S-^X zW`Xu`eHt5PovXj?@dSaA+P`7d5+keM|L&J06oDvf3^CQ# zCeiw4wLZ>|=;s0+XI~rO7z;6**jR?X%rl%a1qj#_&f--UPtYA4fgi#nn_6AFH5WFC zOAwh&oEmzrZk&$(9+T;jsfLCx$|ea{`cz4O`Gz`gBs1cix$ZDrgTtQC9d1UASU3%M zZ;C9qzZX8;ph#{p$g{>aqC;1XBw9%@SlsTOJ?O_^eBciM!5{%Sv=tzJ+_@WQn{v>N-;CG;e-94l(B@-J$qC>>@m( zFT7)8PrI5=A1nrZ(i@>z8>3`c!@-`QuH60^n9CMh*UV(V5l^Yc;3`y06oEp8LB}eh zDbi9R@RrSbtqMA3zZih_UAwgC6T(x2Ahr%8f0`cKOwu*~t;q<5K(}t=fpw*Qg*I@P zO~6d3%`_%U5%KNM;nh&KK@3RZqz3D`3@SZwRY|xeC+WJAkl<9BpDN{I;|yOM7Z*>O zla#3OpZHj8$ZATzRDj)ziLNPoFXV!J$f!5~%leM9rMql+pf)*R9H#S|{$MTew~yjd||Q-+uV)RG}J zkE~Psy9kv|)o~R@iv@Y=#X2D8`PkXTn2{aP7iA%yzuJOMDR%~R-SrI!vyaua28Y1& zv2>-mwk}>*q%B3n+xO9diY?igCMM^eeq|eg9=A~Vy>EgDAW-Nfv z`7Kzd3y>9W5(}EoYJt~$nEvm=*6XqD6aNZr(NEf5j#VKVeAFR|2UA(dwjWoF+uN#f z(u`c-%&xX0I{xRPQ~Rjy42#L%zfL;sJ}*=L`Ewp7-poCV;9%#2oIC(n!QMKM14pC+ z#L9DovZ$S`h*hT5^J5)I367^6Ibw7|w~Dk^L!NX!%Z-`vo;<_5yt0(?VxOK&1*pF< z3<1Gh|J1(j{Ww^;ID4smpNms1QH=g~yQ zX4;!wxkf?;?~?X_an;6m!AW6tV1S%B_w;mYVXl+oZ#8e8j0pzIV$Tm4KgQ&2*cMQ} zJ0ew1PJ4!fX3dOQhj$E1F+c3Vu3s=*ln{JcS{UysDm*_VP5RR5=S-GMbe}tyTPP}P zSN9+gLp<(XwJY1KML?Psj0;IiPH!+owS5Gbc{-)D(1ed=Q~O8O@kx((>{WgWe;_R_ z?^J%w9i43^-gFk$(pW94k3Mry;`icmD3;wd5c*~#-oLp2Nk!cHD`VKFo3`|c+SAoy z{}5HWa#6qj4yBPL%HD0~>{V*yl7w)^vByz66>ULdvZOg*0Qvblo@y;snTk0Dv~=qm zYh>`v4okT7IVe)JE;M3}&66v6dRW+r9buaAMlbc(F3ByM4c)ds9Vvtd_Wqa&bJTr) zIu)H z#LwmTX(I%EJ`tRrBI)hbPpWhq(K0P8A)Y;Fm@vdNFPw?lE{hbVee{e|xRYca3jU(8 ztKYJwZQtB&sQI1fN8 z1MJi9)~M(^EFd$z=cZg(#T5kPy!yMp@yu6QAdtRc#KhdNHtt~Zji=ccj|}4zRn%MI z=tMlco%EQ#3KLn9^3>CBj7|D+A5iyS(-t-nG`UnJOD@~bsa z)hOv9`OC>n-mE8+DUswn<4ufXP2+~)4!SPs)9jZn2OR3iVm2q!Kp;%O0R+gg`s5Q@ zZNPFaWv+I9x|b{4zP0uDPyOgRt6IXin`9;^Thw=_xUY}YVsC?}YX@$3ey{#7ueEC? zn%ZZI>GQ|v(@6!|by-#%57WruPvzsa*F*ec)*W#$S5q#V91_+naqPBX6tkfRL)`-9 z)KNy*pfGcL6DLRojkf1n#>%m-sUS;sb-yqLne_fp&3uok^l6%Gx_wx9{vPM(+%@O) z{g>Tc-DH#t@!c+UbIPYugQYPbp zmX<7($XD{v8`nci528!@N7X@!x!Eah7PkCz5+UiE^w0FA`z{|=p~8)_YSlP}b-pYq z%)Obwq|8l}O}3)4iaBzemAQt?BcoG^%0{DuW%+~onBbXesUWj zf_g>2>igW-+y=ZjvH7rfp7|tm{`mX!?gJYg!`wyE>9Q21&V$nu-i;KBk>${gG=Fya zq;18mJ=v(+Km0a#Vz2GZ5jw5bFxF5bb~_KdKK_WQUsUE}ZMJ}xO!q$KF?;~-qg?uPc8{Pdj)v-&aN*XrIM=m^! zyVLfkSCNWE@zBr^V*wDR`W}^XI}V;&bQR&01VYYn;wiB(8K}Q-7CipzFcDtd7Pi}J z&a&E7>VgA?{U2xCg%A$|FeRCURyY<|m|J%SAT-_sWsd2^ugdRM>tOwXSMQ#V{TAp_ z!RJfp9m6}sD|+c)$v6@4#5o!p!=#DwVfvTi$h`ka7ZdW5dqQ|#yjUgzkeQWF-l>=s$x?AAhy>?Hzx(~@vL3Jg zRJPvN-gO~1NqJ1N8_$scAwaulGJM(PLp*Vv=Y zNyuCL=ImxK`}%>u9EC*n^mRt?jz$2+QgsR2p;L?{P!AVVQ|FKEtY3vJq&>2~?c{|` zJur-XD@o!|FGiqRs`u0u0+bQugw+hy9JTBd{X{6!y=oIN_X0Cv30r~HXUdn;)!s4e zz*}*O6epGu@cs$)L`}|UxwbTmrVRr*agw%#oOOE{0N@h&k(8mP2Bmv{mvq|_W5-pm zsrh?pnsDHz*n~JHZfdym5}p2x;NkV9jJBcJ_fg#hfjmyH-|l?*>n9d$ z9xYl)%xUl$J%U0XsTUMMbP3hxH_ckO^bRc+aRYkz+$K)SbEEM#rf}gv%KM-D6b+eK z)wQ~QOGEmOn3E2R&`R@iqom5sjq(hAT|v<_TrzWB=-1C=JY#)yJ+}?tAKGTY{4fwv zp9dj=&fna8LE_P$NE;2f+s~MOj6o7)4hI~yc~gQJwu5>it|kztw66Sm)!LQ0qmZqe z#|Ax$KgXVN+5M&{<2!wc(FEB$tZD;g!r~pV##zXtY41hJ1NP6T@_$UtsG>F;#-x)@ zPEC#Ru3M3R5)rrqO z8i|)a^Hn`rWxO5zXktQ=zdQF49s_LrbFepq(;TAciK2jt@nxWN1*If}BelYezh{Jj zb*GE7{+LwzXKJ;?m;IsNWBQSfNR86ZCHkj@GcNQA+s`B^WR04&i6`VfZ*g$1qmAC) zAH?)?_BcU9E3orT;Cjj>0O{{o>}i{1-rx1!2&eX#&$a56@{P#F zO+GjW$yag48YL6}CI{Pd>)8~^p_BJ}XZ8OzX1$<|algw?a?d*-mgFy$pB4r|_JYu&7F9x`N39hPw zjh4{Ax%u{xYHF;-`9_&tW71R3=dN%`FA>OR8wtiMhzLkknv!fpriV~d4ZrD{ z(x@$CbRcPpeHglQQR*|$2o6kkG_=}i+VS7{=s|6PHl}G1^7OiubbQSlNyAYIRlh-r;-V4(^9%O1w=fbTwlca$;8G$>RL%aYpv@ zy^5pKlTxy-3d0(1g8G3kjsVZ*-aj6+lKDZj%+fOZkBEV_HvFgV`7_BEMpFj1F{|qD zzmk{89*9xfZDEPr&Rx@N^>tbU-gA_3V#@*%apq9GILAg(Y1^WDhIR#+6mha<1loN1 zBUh}lc?RqgdQlp$RSzUcOB}D|Jf$~dNviBVqC-#gNad@y#L+;|4qJhb>>q(~!4*y~ zYTg?AD$Xb+WZQMuP4iZt)kk86ZY$V|)E5wF zTy0of6KuwZ(*w|sEh+Hq_6D&WQS2~oU1^+~>gpS#V<4>E<(XOT&sdpva`g=g2WYBq zF#4asM`3XaYP$dd_WK`ny`Amc!`Znk2rJ~*P1xQUH5#= zU6+`Hz%Ww8q$QJyA9Kot*@{Mz4>`E5Yh9(lI+hfXtdWOFNA{J>%(kxTkMPl%X~TTZ zT95dRyT-(QM~Uo&_r7kWtVHfy&1yG}@svaEAaZU@ivYBIx*0g`D8ek!R{$nB%B!r? z1?SiI(F`DPAk~w7(v-AD=IKIJq$zxrkpk%|jOdS}(w)qMH|voi%^7Hk^M+Ji&HB_W zcsS(KiObMKQeop%uT$;nFY?+StU+2st8sNLGukHBnSP5wb=|*)Qo?6Gr)leqkUhnh zK|e?>!WpHES*~P+3QM;LG6vw5(Ic6=L*luk?j6D3`(mRjhBH@R{vQ1$U%!Z}hQi_o zA^~R-qM$q2e@?0rY}bK^Mh@AYj4!)V zP;>$%D|;Bm=tU2)2xIL=(y;x-T4ShHBJHxKBdW5hp9a)zwEV;RHdr?)rPQoMBHi+h z45KXJwX=BFp;nc!PFXVt*M|U))W9=kbD!hPeS@60{n;^dGLIidI$e${-w*;rDh?nv z*A1CSdgwDe^iHpp907TEzzH1SL8lYR**^e`-lj9W?f1 z3E*s@o5WK(W+7*+a=)(I_TLeo+HRx57NK*{W#tYzyk>*rj6Btqs5-?%}xLg<8o5~l5UagMRT)& zVw>wx^Zy?6yZBM+wq!oI1^BhADea3;A(LTeQs2^k5+G*q=)E|TsU*R+hN+$58o3zf zNa48~FF8FOPhZ37$9N_Ggr^h4Z=;$B74KUJNAryZaV!nM9re5##J4kz^-Mg&GDQOd zq=jI9mz&!u$96}I>D0dAG!MV~$O*@AwX33>6Nx$7A~a@##b0zEQxkZp{0|#chC-nX zY#c)+F_F}AV2d$E_&9H>2g@ZRAX882QZ56u^q*)X>kc+cyEGAN5A0q!fimAf7?8_H0ipxtTJrwz&oC!MH?pld zW+cr5&rciua8|MA1mO`KmvgW@kRUklOqUkV@Bd7OE{7)LQZ-5)1j(F|;V6r9f?60) z9S>*ge1OyDb7H;D93}Mk`hwC z)IyLot7;f;n?@a|__D@Q3NSJVP?RcE;KidTh5_!hHAI9T*)ob}D3o@Ghl+%*y%G%7 zH*>FIHgHF38g1g&)+9V1C0c{?r8o*qi`jD`R)Gdw9@%)z^JDF^V{sB0VzV7CGowJ2 z2+Gkn*1lokm2M{c!tv_r*yliqfQX1I!)Teu8V4bs#02?CX>}zuCWP0>%f3%zq6NA z=69Xv2xhZCAuYG{EmQqXD+~30CrV#BDM^pGz-s07EgX)hti~sZ38(82UhtV{d-vK5 zsi5nsrs;0`o%*?P$T?ZpT~Lb-mb)bB0ovOE8V40%WCN^{3BSj1V!S4) zK#P1Hsy|jXw}$D|YKcPRk(zXFTb*tUC+!UHW7UyuX;%g8-93izE zw=XWQ>Nb|Rmc@q!1_LDZmomlAK+Pl@o`F#X;yyqo*3=(6G+to|Fo2HPR?^&As$^`iJ%>G>Qc29;zariq8lF*w+ezqN5%Vj{J-d=Zq%hjk z<3dw(;oOApGR37Pk=kaNTp3ycD+8a_>fD^oSJqVmYWZ|Ap@^Mpw%Wfkp-W?=@#x`; ztFz^CCIiC`R_{frk0-P8YAy2itLFY+VJnn*{2d~h3f@ljN-)4rbv?Ee4JwXnYQto_ zh)+(=Wr;CiJ{^KQ;TJ8jh8M^4Q_|+-Sc)ypGQ>pDH#$bb#RnVZ_$C}V8X_6kB(4Lp zgsG`XiK3YgAnJ{Ytfx|~>Vv4s+0jSJKRIKbos*T2e)o#2*Doa(+kFn5`o+6@fO5d! zn{M=lS)uiQn{SfsCXF+AlA5VOQU$<|)Cpgg&pIQu;ojqpD34JlA*(7pJcFz2^m z;K5$`atexDRKyx5XCy^#!d$(Wx!D>|_%VM2Q3glbdsBZ)6>f4SsExMhDX2#1$u3g< z^Er!*jWv-=}6h$^3IP3Pi-CFeCi0Z_cuD}wLY)sbapXZQ)7xz$=HJo?J zyG9c;OuL~V(1~dC)t<0|z#dhhs8J#h61EYMhOtiQ3W6+09SO@T4profEge~12q!fw zITsyB5|iWX=&oWpxEoTJ-NG4^Cli)0jfzFT#2Qut2fWJ?r-n>2)KPAIDZ($}8vWWd zh&<*}4wb2)?or$@ct_69$G&UTI;a2T?H&5*^G`m)!y64WK6l~;^ zO=?>x`qUg>Uy~^aGzdy^A9UhvTSEZyx%&DEA0}eoV?)h!Bzg;t2G2xB2SxgM2JUbm zBxu?8I?V5*?kGmMV4OvZZIz2)zna!2gsyNHk90+5drC=(xR?QcbwU0|c4>ns;r-@0 z)8~JIQEtl7C$BXRDfQ`e7?g8tySAZrOV_hp@tYXx>%V_J|E7BDRUfh?>fPMJT|(I( z7gmm%h|g{vh6_8$obUoTCVpmea%=|Qz}5yjg-$EB5eKZrYtH+pH0CW0*$?02!&7ZC z$;Pbip97m_D>Oy%k=Llk6V&U#UdPMNFjq%SK>o*D<1Qq|TA}UbDEF>eaot;ci>K=;IeQE{2We=frH1*)}2W_>tF^bJcJd6W2#R1Jj~AE3Db^fm}9%xJBA zzt;~{hdqDf& zF#aZZ^__i;e9um-Ot16~B|D1>X+T%i(|oU}l5ckpmJF2@u~{s7ZxT@3*khIzP+%-nZB{gMRGm@$-v#XJv$3kUZ?TLqxJSPruFQUSwk34;nJ=hTFL22$|uy;S$Nei^LXUZmQNzaru{ z#{q8#IPQR&)*fDZ3CP3)10eB7HS`$Kn#W-#oA3cG_hF1|N=mx(KqwInhPH}#(A}ow zv{iv~Zvq8`%xMOm$a1U*Cb1MWqH$GmXIcQik93skcTM|FE0RZ66us9Pe1fp$S;=)< zV)EBF@LQ3nR%Z`GQXhAYg&yaI9vn%0Yl-Aeo$=&Ap|u%ag}wUGKTHv33FzqNsH$fS zaub|L0`DL>hLsM7udXllb_!AF&$uWRl3M0+^1lIv^JkP~7SozoIe`djyRMm{+;fC# z*Z4~od+XcmAn=iGA>(+Qw?@i8NyI7zgh8p?191mYrYctZ#E$j^4=A?EegQGL3-au7 z=lwKd88`W-8Pzk~$#u@k8Z1ZfcDx7~VGh zU}`KHkkM$Q$Ih_`>d21s;8%HGTh=gpbD24jbp$v)LE~YYE05TDfi>VCq?m*s?_ezW zdjYQLA9Ew zV>el;sm#Iqa?IQ_+OSuSL787Pup{e?ptDORDUF;OhVms-**C1j`mxJ2*__6p+L#{^ zup$|n?=NhuR?Y7$s^&4=CT2Wcck04`V+E1ykcKoa+8ce{EE>(0${riYT%S%C*zU(F zdC=>1l)*{Bk8Ir}YH7)~8^nk^o47XE*7Ewz-Cfn2CdfzQC4wwm@2Ar_+(Cq})l?a6DRo}4I>GlEW~22+vtX0mL9qa-Yd>!ciuiI-$huvY4RPIQkve8BDpR~NtYEo? znKhvL{~9vc{TnpQ)w;4^Ej4wo8h|>#3uS`V#s%y#v(RcGS8~5FCG&-zlv|fNZm??; z*}$F=IM!G!tsA>uD;hSt-2;L#NVGj>bWpX=E4}wQ_MLSDE~8;Vo8K$lfHG^34wq}? zDD+iNSItQEiRVbTD-1Yqxkl5>i7`k$aGocneOhgaskn_^e*>+-Kta;E#K-(X z;?ybhT3rH%L5NV+5m(F8W$t-$52`jXUYL8|om*Szh81Rf9w-ZCx)u^2!_m32SvLkP z40 zg%=@R%*+OsTVF~P6!prEWh4D!Dh}#KzCp*=HB}=9;)GdT3|qZ`39L)0m)e#pFg9HS zq?fg0m1rvSzDvz(BlY9{c{6TGT5arIyM=bQi!bLY#m<{gr#OD}raTbMzp5v>Zht=8 zIzHaMw(je7Teo#vw{=^$FWp*6APEv(V{@bNR}g?}qa_Iofr3~P?BQ&R14*{&K!5-6 zF5JjLr`5qsl4q15f=-}%fpOH8-xEOYqX82+$5$3=I-jH42QJ2RWACAqGc?mAL=#k%Fi_NxYJFTa!2%J<)WCpsG_8%IGX(7qeBSascUa zF8>XX$@gpwHV_4ENwAi3{VnVab}&7EguR{X`aPsRveaB*y3)tl=u}HqogzV&&m{?* z<6`(G#=|3=&rg7MXf!LCT^1RplNEZAFUe_!M~4?^2Zb_eXiAj~B!NF0~)X!(-A!lS~~2 zLrMi2+)GAjU|3mlJuZyqspEvo)MTRFl(Q;WrDf5z(E>CGf}Tg+Xz9V~96Al#%#`yh z#?@G9H-(ZGlTnSi!qn*21O}`Tm7cw_zpU1&VnWrW79K$kEzhqF;Hd8Pl%~)UaMx%u zHYMJA-o8zwU6n|Pg9zKbZEUo9Dz^~(rli`H_)@r6K2I$`CgVXEqrb5sf0busIX+pM zz1}9;5_@F!QJZ#|XEM*0GH((j=>k2O#7nzDk;{Cb$q)5=eS&nd9u%ueLH5?RhvW2B zj7MWNKXbwwx1YO?gLYSkDz8eFvuJxIJc-YX`2vq#e}J^iB$lQq^P6ae9@=rJfM7s9 zRGFKed{1Z4SJvFdgVf5Cx z^l36I#fFvW>F)$c<3Rd6^i&#w;8Y>=q>%MQwPqRCg)!cu1OtKZ!pIXUW6`l}FpXv{ zp_g&y=Vbk&q-s7%kC>Z)<>nx)8`UCUk7NWZ<{qB^~LXUGz5h z5lf#W?T(H+HJS-tDjT!#REsyyS85&?w_9pV#LbdW#j0TU7VesD?r3@ za7vXhvS_N%8Ih%7 znpVbPT<4f$UD<8PIQ2G_!Dpo}yxeZgSa7ge8)^%%)|EAoYUcVS_TK1B8c^4i%v*4m zn}c70CN3F>4kZBUr3Fi&AaKJd=XH^3S}XXOoAP=mQ{Yg|+FaM}CzZCW-biy8fYktV z)B!cYTpLET)fM$@**@>Lya?)=!mgv0E_Bw>-nDM(I$nl}Yed%ySx+B%0#ClS}1E!PSZplj3x21ZpHm=w0m;TrHoH!g7d@IkjXVAJd(_R zpX+BJ(ZmvWnd?PV;*+nxga_xxc;Z?gH@9W|l6z^78>2GOW|IZ_btLyGx!2dZO5jkM z1Bk4FlBaSZk;HyoELAcjmirm6m*>V!-nb*5NxHfr(Pyt6j@#f6KkH zsmkYfaI?#~I+^~f*1jl6N>Jv>XWymt;p3x2OAY_xjThUJn+iYk+Do7Nivi9Yyc6$# z26*{DynvHG>vMUV+d4kpzV;Woub+M|zI$VefBSo{{#l>Nx~{%jWgN~Wc^=S>wp!r$bcn9pD?=|)9m8>uV3`{hUyyj}(o68eWr?^X zquFYXXu#ww$9y4)E*Y5)EhY*rxm}hSPRB=*Ajj|}F-VsgmJ9j5%}_t@%Ts=uUdZ>g zHHmLUE#wR89D3;VH|6^>oS!|y#o4hYEM!`J`VW5}q=WZsN1w*g$r)B@iEB|C*IWCjRxUpN>V3TL zUHgdoZPjNznU3+9yN77EBE0iv4+BY-cwVnxyoOiCGaN~O3@?_rcB`jJRw9WWSzdX$ zL|?`$=*lQ$CHjLM91Vw>w70tfb_ZR2>b3i5C7Y;N{ya9oV-nZ6zc@m>pUdwXDj`6Z zskBHHaGj)Nn$8i21JaFAgcB@%i3gfw5LA(*uiNfnwVYymtF6iVD3!4rBr*Upryn>*_ZvfU3+f zBQM}tu+_0L0(JG+J({OrfHli#wMn8~OXhQibSCp*F6TyL zH`O8y6ub=L1d+@emm4kexx25QVmw*ki92^Ndh`IEe12#9KsPwZB8%iRTe7aSI&BOW zDgNDOU%;C(k6AwL$oFh*w9)Ui;7LER+%=Us!m@5J3Y4`q9iPb@_Eh(eEZDQf5~s3` zd3_&kvXY$uv&q$Buwh@-%EB{a*|3UL_p&yig#r{-n~_*{;Csr#HD+6eMMvj#=Pm!! zsBz3%MtK58ftvETDTamdPq0^x*@Fuo)4v;9|S0c+Z z)dpUzJnYlDYH^jhbkNwQ8JUTv>CYQrXZP<4iiMmNk~f zZ|w7}-3{#S?cm9$o|LulTX1pw0FT~yL+%Y*IC}J=tg#omW{+gvlUdBMpq3=TrF6Ey z(a{MuWNq8s-H~-`sB?tIfTbtn*o%=dt_hO6Ry$Os2+B)Vrpf`^O%va9?A)`gO~Uhn2E^D66IW>;q&D^yHMsHoWj5g=v z^@*QR2505k__=EQJqCykOT5ziZdqD`It#d}0hqqN(wM5;QtwY@&2a7c8c7aar?e{z zTY6ofaZlIdz_Xi5&G`q)emCXfD;u}2d9UZ`f3-Yc%kI6mu>En#e5G6o!9MDcI&$ya z*|~)_!9`Ej5m~P&N5d)zN_Wulo^cW=fKEN(NMd&v{q0?KnO{xk`rL6O>(pd1H5$5V z9#z4Ueh#`ZhRX$h_p_hC#qtsU#$S22tS?>kx{2iQGfZbAxj$yIcC=J}rQ6|sT;@cX zVm=+|MiEQn$)E-U9}oOcTQ~F>$ZlcG344c$96KBdr7SVC$KwmW|NTP zLc=Sc>oHlw{EqVNM@hdZNJ`ckL7Dk{`j%3PFWwl;`d<6l*I)hom;Lf*-uD6A>Nfw% zaq{`!#b*w$c;v+gedY3xW*nkNzl~463cTlMeg*&JhaTWV-}UqOmw)Q3xqAE7fAFvIvA_Eike%SS ze&NFy{kK1hTmS0s;YU95!rSoe>$Yy|wr=b8_13b5i^7(CMJ~(6E3AqXomN|tjVZEp zf->QQe~fxnVsGyn-gxabw2}dQc_{DnL(CRKgps4=qhv3TfmyKJnI*fD1f`3yvMgI| zIvq>$B1whswlrxUPRL+_B;P$PP4D(Lv6LjIlyfLTvPm;Ieu<0GJ$StvT9#YMdB*Lo z>Y7%|6uzloa%Pbr(@<-0GaOM5Cg%e^-r;vF~p7@vj&Lw&jcXgqgw4H$$_ON_ z04FSMtV8q&a?R(GK=rY?)4?*INWaV9BxyVw50Q91tlT+#N0LK=w#Os12emS8`+Z+E zLRkV>tQI(#j1YHXEtA~d?`UF_FI@$(=x253&K+DlxMBb{0EuT9pO0BlwgwjUrHRF* zagr@zSKU&w(|BgJaZ=XudDpT!8^?0RVT|#V9^WzGfN^T}tWIHR!3xWaa%+pXc=kN3 zr#S&q$LPQ{MgOpWcP^hdEud0c;1mt$;uuq}+OV@~&jL8gUiFN_aRa#4Mi-P!tmYZk zFx)B&QUns8vCM%GN!Y{9-KVhA-bXLmR2@<#%48MOKIK9TFp38eHS#yph) zST2{?+}zN$p`fgUjCm`LkS$A@>p9NL1?t2{?CHrWpmTMQv@%$wx=}j@5aQn*qmk)q zjCd9Zt8Gl$SiKx{*BU4pgB?ZUOeiSeURs7r^t}XM>80J7pd!DWxt)z#xtiN@V z%VJuo85aSQ?X5j6eP6|Loe@j+0}Q0!T07UUaqAt*D6NV@`tJqfy>{cetbcv<W^d9X})WzYLMZ6c~`r~#pQwgIA`i_Ojfw&h;k>uf1#r)y|!)^Ez+@S4(kF3%YrDp?D-c0}#I zZkAHILxln4@Ppm}lg%CcA0Pj>c!#VVclP%YTZ62l$q`<9@FL_f0^jw$->LE5ZpXTA zE$3a;Asmt!)m)EJJ;?4Tv* z=gNbMtaXK~FJ$nZ4Nvj#t zGrN@3GT7TYxYC#Z*gyIw_~~aeOmYfJhX^G&CZG6a{M6t2Fg|&uBm9Z>Lm$B>eh&E1 z`+w$Z4&waSkA48X-~B~A@uR=|HU6eQpY3ZKAK!tW{vZDbe9sntmxtkAB#Xopxz3Hx z;GaJK<9IoWFi4^={P8dK+Sg%wJLV$3^S{AIf9WRv#q}S+Kf3(mci?A!=_9!LFP_5p z{$u%Plwjb+e~K&k)3guZr@sH4xc|?80RQ&hm+%Dyz;`Um=CAQl6{TvGU?Cj{SBy^H?$ajviDIU&;lDI6CQCE?DQ^+|;60*BFz|ql>ByF+kvZj+I zI@^6Ls~KkL1oPHG*Qf(ok=z3X)9^)QoujluxT`&Ke8aTy?R zS~xj>6P;FwtxAfrwE zT}$Foe4wr@lhv}jtPY%O%km9V)R>#_SdST|wp5p;{N!gz;;UG0?JA?x82&W;#M)^2 z@%IK4hGopw3TIpbXpi+ytr3l5z*`=d09hRN&`q|`3c47?n;5h#7Km zrgIsur2zgKnoiWOD_II4(zSP)ZX zDXJ%*arD12+#pa8yCt!A^G+AB#Lvqwy@sJYh>j(u{^*TY@NG}OQ_kDL=GLYH2k>N0 zl{3YMb~Zw6^x207z?e;G7R7nhRXxU{>Z6wP8_V^O=}K3h+OIL^hD9ep;)co|HjK}! zgH&Wtx?XA6q|QqFSTz~}>uw*Q(F@elXA6u~HbjiJpkeuzHFYkHwk7A1TEWRNS=wzh z91Xx!v+f+;Wm&kwdh*#QXkn*!9dRXVt~*141qxX!M#C|AsO695 z1zQP1sUcJCSZ2CeFKG5vy@lCnz`j}yr3`oqv!P*`r0(U0hhex|9&3Y-TQi-8TW;Oy z@fcjyV6LuSZm+9C)#!Tq2555}l}T`{X%E@*x+YbX0g3rvr_goIwVI&1o_R(OwK-=6 zICWhrwSQbAz#xB@x#9$JIHTKK+iNl#GhVYIDd4Lm=5CWoSC@b%H(bgcP zSLUjd%IoKK6mp-Q%|^HpKA~E>los;5L^q4bB<0%F>Gc%E%yYTdc6~%L*GkFhX?95< za(8PV{fh?};_z@V65E~sU52qTHF4#Mr0NkHGN;2b;1I#4M?x+ zPiy)Mzd3WzS#hBf-um{_-UTeo#vw{`mht&n6Q-oyFu5xVUf8J*1Q2w~j8`Ncy?!W|?T z!IhOf==X3jxj<{shA#xAH0d3-CcQbpD7C?l*Ikc^Sd!*%dDk8M&L>~Q*(k>=Z=Py`@t3~o2|Rgy z3%!JlkPSrg{baVSrVmlnDO!>!&9a%~J0?+m?TuG4ofo(^*hiDj9m-Ld3JVVdn$$4jTey$hExwJ4@POz8*NswSXUK+4a zp6zGLLY@gE>7&%aGS&W#1Dd_G@aEx&HSVgh#)qR|72(FdjM-}=JRBaQyV=DP2m4s8 z=2!$J7S#gnR-gdJd{W}sC*Fahi~FiUnM*(IZ49jQd9CH+tJT#di!@oJK3kRS;(m`p_=Bovq4@OqZZX| zgfaPWEOU+TaVt~8uci1-Ac=Z}jn*!1?>&W1)I;JXaC3>3a;atYDobFQUj#XopvUs! zpnxA|DBTW1w?q3(wMgpJY@y+!ND%t1nW;PaCUr#7tT+Ry|}=4KKqT>>ct8iq&YB@xH%mi;a%_8 zgfFp15YLqP8}RI6I7Y9ZC}Ws9fxSToc`EN)EL9&lmw6OMEd-9~uhIevS8c0I=2b|r zVkv!`1D17XktPGMTb)epkCM#p67H(H1huFEoJ&6~Gh@QUeFtvF5csBpy9wXw(oLK$ z^|h>*)Y+uVx?B13nFQB1?x5rLkWMBVBYqSp&`36Dt>wxyneQW{TN~ItxQ%O1Tu0dM z;_%S}-242eu)oztSH_f}4YfvR^HjlE$lAtvHj(rD}z7)A|t#KPSNg77w zCG+z!!&=Mtx3Kn>c!n5W6TGzw#hvmQD!{xnNkW($=0O4bhLXX!f0tL^p%8izD>qzph1 zct*}bI_8;oK7;EwcI35O4GsB;PA8T%fjXfca=GVweoGEkz>z-kWi9Z-xyBboa0$qA zZKiRP@0bm+zT8{63Cp~HJ{if{5f}hjUYm`_%0%_4(c9UO=ans)L$b!vG>Y1#oVW5! z6mtVf?y;U4U#al0YHWMTdbY+`3XB$3!okJ`b#C?jo^AltXs`!$@YC@qHI{QUOy*{j z#<7M_W)7@0CX7Ua2P4@~**Sx+n9cmvXjei|9Ov@?zVJ`8OY#4={oWtom6I;^Zkd1X ze*e$o*FX6Jjvn5{>!0}zeDrVc*f+ixANT`fJ$T z{Qy2J3+v0j`m^S(@B2IWr~m#_=Dl}6j(_vvAICGz_wh6Gz90Kve_LPw^`A4x{^?)- z4ZM7p$9@5yme;@aPn_lt|I%;cC*LLK_g6lImp}h2_~5}`!cTtqWBByT&AI+-{NndM ze*f-Y{#pEQAODoT#&h`ffAE1Xcy1s2x%YnY>-#En@7JomZSnDz#xb}Y<1hKz&*Eb; zM*sa!d<6gT^LKR&UjD!T;p6^%`p5B6j=|j*^yg*9&gXv{AN`@P?)iST+Mh*VUpCH{ z-}wlBSpV^Z_~`FQKmA>qqwLpDegxl#uW-(OiLd(LuYL%Bbr*QgPkzdNC%^AgGDqaa zzy6CdmcM}y|8@K3ANdGA@%fM8gU^1Au6y0qZQa&w-M%iGpG0_g@&K+RC2Nqhp;@nq?vM}0(sO+J}>)CMDCs)Li0BP?b!Ocq1jJ9-)a z>2tq}2j>ql%13zR^bHKB6P%6CmF=krjU*{gKedIw^@HDrzxw_=_`dJBiT~nzp2Igk zyCq4`5r&gfoTqc#J$!(dk6)F4kCCrR)&A?S3Pe8Nk6hJf?09m%#Z-aacFzF6EjPxs zCs{UsjJW0F`KRBZ%o*l0>1?GX$5~#ecI0@NvJer)+(VJMI6a?Xnr4_TfN56XM3T2D zGF&V&Os3M8G7hb7S6<7I^!ixLjmgLp&m5pD{T{~=Hafd_>4k^V&jcb81w}$helJEV z96p#MPbp{_z_0q)+u6ftGDAD;&@Tg>ww(8DiBytSvj28=2AF3PBm=pQcRz`zpWc!8 zP2iV~jH-`r(39);l^N$rviRD)2XcHeklJWV0_la0npIG8K+SuK?8@=yY00|*!;Efb zpg;?agc^-CHS%hH|6lgr1z5K8tPWiJ z)qD5*yzeht;HuZY%*i(~j#Ys`MDM;V#nSYZx6~#rSX+RX&w=^_7LC%;9pTK|2BI zR;MLnB2hCHbuE{hVY+qP2qo^GA(Vg9c!l6fL*|A(5@Vi`VJh>2#%(lOqnS)D*CC6Q z4BTG7k9)rAEAX{{^Ip9A-oJ`jGsJKG$?xOCk9-^-{KQA_f&cuQ_|=d7Hk#cUTWb;4 zRvW4xNHC)=-?pf89!w~lU_Ni02+dNaH%Fee%zKh8p_uAI=^gCs z+%Ds)#7NdoO@${QFKZL$Z<%Mx$R!(6GXSJcjnxERFTyOS5XfsdzjaQMF{w;A>S9vU zw&6g`xkjdedU?)@$-Y2TEXGcxt)_4T9%<|Yf>VICXAGn33!MS$iq+cdY-1+ zbA6QkmTB67fu@wqF=H!dG^b2Z14GHGWSbNf)5Hznlod`NJP@EZXIYs%0{e;kdZ*RX zJ<6B0Bu<(#pJ{^BK_ufVY|7r%vTPD&uAH0B^e4f|ZSR z-5VQC(*{+;qlgAj(t9$V{ALevXC0l@)AHIgSld30Raqwq-w`zK%6hc6wuW_C-&R)o z($_QjZZgpIqIAH#8c@j?^kts`_l=g!#qNfTVVOgPr(=wBn35kfoQ(Kd&#l#-zt~^w zrya)e?>rC)bPuq@Je4$&?@UP}kv%F>063Pp(3G*t2eWM=W@m)d-jxUU5YN8eL<)K{ zn})zB>yoRMEZeJ6O<6M_d!ftcSalaN%{OtW`5EEokI>xpPrn2AZtdZt%(efjx8Z00 z-S+_Re-pm){KwG$r$2>XJpUm6+0TC;-uL!@jkn(UDBgDO_u*&p8oc$sGkD}TK8QDO zZQ*C$u!|r2fuF)7Lkb9eJAV4#KY)Ax3;rbYO-HO_ur4}cYQzp@y??+>h?$S{MWr7C$Bp%uX_;h{LR~=+-VMC@oe$ufci$y_@LubK z_k0Z=`X}Fp2mj~`Q_U}2c_G@mi&y=~dAxJ+?>^2xmzmA^(jMOUXL}3Z_}{(;zx2TC zasMZQCuFSu=B>=x&r*|L{2$(fdw=?EIQ1KE#rglVE3ds1f4AL5pV|H&d;stM`@f5y z;2itlFXKD^#kT|h=UedLr*H9gmt|R&Wm%Tx%c@lJMS5^@fL8xD34n5}^!m6w-d8@$ z*3MZ40Qws(931RP+{Dzbrn+R)$mr9jdU#2J zD;hwJ2NMN(#_3do!BgnS-&gxRtoLYoBB4|^!uDzls z1Ze}%HMk+s$aFMS0BCJ%1%rbV#4Y)bbbY4LD1)JPyN@g53lj8&X!KiH-{|9+>rm5* z^rXPX={8n3yEwRdg0PM-o0Ld;WbK9+98ZuA3Jmr}IJMbCF2QCb`*kY8eP`_qrjwb} zHOBCODf&{s6A9W^13Y`Qi+f&nP6DAA*N^rk`0FE^NI)qO*Hqfrm!SIG=2=`hIz+c4 z0cg}hF467b{*jt3ev30^yzram1LoExIqlt6hU#%MNG4cRg%&~0p>A$3nB zSWQPBRyqmFu$Fe3V7tGrW?Yl$3`e6wY^__OQC%x#{ueJ5A6^Xb7qId-A3B^|UXL96F<456;;b4^jr#&^H7-j!plS>Wo@@6|xYcMMenUF`EK zWvT@V6a@dPeFK|Wm#R=5(z3{q$=uD9;ajTt6Tx%>v~`)v z_~;;7TT@^s=k?M|nNZDkTN%$ebxh0LQhsX*!LxE<)DksfOw*aZCThkCh|)ra+NMDx zQdtHCbDJ#%p4ngVD!&}BV?%z@_5SixPhmJ1$h=DM(mQw1Z)b?(6k*WT!Mywt~U1PeI^f;axHc$T=FX&QSO7+t#YS@Whccb|OvX&fINz$3t0XVQli&d8ed$~*6t^^@tx zL)AG=X9J96oeiAPS-ZQ2jg57rlL0296Frc~WQ@>Ij%oR`G?jHD)j2ks70NtLWc?jA zQdG*iG>I3Tx(fz%;5wr=r3;;}g-h?oA}yKoMrA=LbHes^E;hDA7_g^nLs6nFR*~?_BR?dCgzqM%6 zGeDkm(X?<)$+B{(?Pe%vOhh#ZqTB|7RcAJJLtY|K83#Vp45@DD!*^>A=K8L;Tzue z6VzJoM9n2>m{t~r8fYc5=Jn*efD9^Hsc93Ntiha!RXd58>N(`%%E?C5x-Xerf@3`U zwzCAz1gdn#el`rGS1FO82WiwY4>ij~B@8@LdT07Z+a-PL@)x+={L$1GsTdpcU#k#& zFV66Z|L}u2|3TnYKl*yS>e4UZTh4z>o#S`^*I&jb?tcgV)_uVHW;3L{Gr0G4cjLEy z{$u#DAGd2gG>}cP7~;Z*e+LioiGTh>_{Ocr@V;+-4?apmsH^Y9+kXD*@tbe>=Xm2g z-eM`)F|FG_z&Ex( zhJPc^t5MEJ&f}w>ehRPsHu-)0neT5|KHsv35C8c6cptH8NMAqoJ@`8>`Fb#=`>)*@ zN$;NSqKw^uO@3$)_|X&B&=1pUKijj792jH?9ID92=WqF_u#8Gy2{ z!BQeYUX|BaSy{#Y{y>Ag!C-{bXE$(2J-?)du3Y!-mwzQb{s(`Ia^@pS0&Jaa;M}>> zs#!W5&aiX3kMYq|0zb0eYNW>*wob1hXnGpJU%D{E>gpCg{i$cQ9@H^y_1jqWm`=!u zuW4zBc~|bcz^b%uD)%^%7yz*Zf<+UV1ZlHrinWb(L}{qN=9H=UQ>IbJs3ibB9-QFp zX{lE_LNjP$HYqSFrwEfu8F()_Cv7!3#6)6))2CK2kN|XbV-2hQ6&y-C=l%%OEW^3= z+i-ArAZ_Do`-D*sfdu3Il{WhQbGUltnVTMesw+z^w+c4`V9#?7%$^2{1fB?xSvvZS zlu$3XL{I_>yoNC&eU~C{alB$%E^Sqre5f=4wKPXhLGL>7o&#!_JF(Vf9ymL*sJTWe z4*(3xsT_mIf?5T7_?gs6tqceV9UHV#jn(SL^&DeKnPD_AAsFgF8cVz604-r|>ITTb z0kUKY5g;XNNLiMCp=L`BvR+-gsa!x1sV*N)mwW|7Q%hOxb z`RU03qv=@2OsIxQG~;0%$QI?C9gc>WOfzL&Gwq)b#-kAdg&;D0QUYLJsPYR0-SXMg zGy|m_l3r7pxhvhfapmGgWJQYgzC4E^qM(gzmMVjllQSzaWuGO@9xcq#?)2fwoV$Ge z3NG&NBar!7NS*7Tu@%D3U? z2B-(h7WN#VZD5x&Q=O)){;Vu@nFkaq{eS}F=`kjaE{eE=!O5-~!*Sr!e2rs*tliPz z2**c9=*e2tBk&_@B>Q0?b9(#qw)9mX?>$0`3}3kyvUw-dLZvr)s~rVw(~~jU%{5so zp2ADdZsF*7BJ1D`CtT+h^pRme;D(YGGEP=km=7IdG?KNi(LtFN^4<}~gG0>_An-*a zt)t@sdM6|7@5*|+(^WPp-N7lrL5YZzY}45Utws+SQ|AMd17L$x^PG8tjSJ`RN?E;g zN2|H&hR!X_*`o#y7R5Y8-sBKWjw5u&I8YtRK(!mK51H7`HG-ZUYM$o%b6i%zCS7+N zK+8GIc}u|2vo~uWTcSekyt!(pJzN@)XmXwl0P?2BpCZM!c9ruZnA$*5)xLE=tr2Qz zR@Kloifl`GmOfvp?sA~>P9JKTXfElcJ9yE}nvoB*}5rQOSED5Uc&jI>>;J!%ty^Dfn~K20aiEH0IO zg@$8NXZeo6PoW{A^;M~CUb1E>#}mu-X2lFi+>o)D>cL4&c@Y`+E%~Bxba+io9(xHj zoMRkOvsd;`%{1_g;op?+Kr_sGV)h;M%TgZR#a z{}JDN{zD3|yjH#};w9gOU;NZ_^PZ3KThy_A_uKKdwFhzjM}HM>eEVbg^?(20<1Ih= z@L#;Rd?`wHFXEA_H=cTgf-zfX@$&f-(clOwnFTa5Or?ntXpC!;(z4G(C~PN50gjCAzIHR^-8eb2J%Cu#w>Q z=54A8_OiS0!0>3OKwQ+7prW+&WCB_{65y|`ZeWy;;PnDbNAeYMV+Du9tLU^DMEJOH z{Qv>AQ^~ZGz`u|P=1-3fh&Lju$RcTJkkRk9_kNxQZ z2ID=nIz8lz#N*cK5 zt6zrW!?DyqN2?uSV`Ei~QXYBuX{ke7jVdZwIiS(PeM@mAY!Ex+5o2DO zafY|hC?!BuDk2cfKgwx?8py#?IkuSTyg6Xfb6}e{M?Dk@aL?5az=ccGHCCarTM5uq zrd^2IQnl;K0cc)eV25wOYVFu^3c`4n;;Kd)WQhd^%6N5s18h;lD0AdirlMb};m-Q% z7Fs^p-BSN5S8Y`SDa}r#;J60aQoka1PUo{JX44GQ<73RUg0-4~vHcGBcBOAqG@BiD zSnu`vS{FJ*6EF$l7%izv-0CP0n5ywgDPyo!M|oqtdKeN^Bip*!M4gjHmZ^I*S%_t3 z>FZGv;Ccf=)BWMnA$` zcifInH&HFpmW;82c?IKK>qgyLGHlCYqI##?5AJj3!vFvv07*naRA``e@u{bALhaa& zr|Slp>64T_Ept-p=F7Fl^;Fj3N*U5j-S*U=$&6(P^wnkU@HYda`EO5wEE}iBCO1{)6(wWx_CbAHn?t$P9WCMj7EwA`FFpi;Ff zt2t-gSNRMxr3>8O%^*$>WE8ct_Et#|1*MIhtxS5)^htFsRQ73s#R#t4TC~t=^%g)f zL1ePkr{gi2ehb}p3ysj$JKjU+8OuAT3DRt)z_uP(v7Ry8KUN-WqmH$|X0sGBC1ih- zeN4We@KB{JJT+;gelOGbnf0O;fs_D{*HHq9Y478~P}YjBF~h?qdMl?eIJk;tBS6sL z{<)?y7hG?ce&6Y@s&oTE*r36Ko~G=X9fV2WvT zYO-u;YG)>dYL!JmR);71`o#v4evyl@F@FUQHNFAg^iyxbgZI5x4SG%}w*Slr@tt3H z{xhWIK8auYSNF-|PJGk-KZJMx%Xi}^KK=E0%b$OlGBUSt?m16w@s4*d;_=T|n}Jf7 zKk;w>D(?Faw{R2pKZtkTH^smC*1PeOB-Q=PU&XcWv_I*6tZk|O;zNJFZsXs_zj@{N z;3seP{yuyQby}92Dj)sGA7F6*-^NdT`0pW+vG`jLz8w$z|B^-eUtT`1Is5sJ>76&> zo%i*n|DMEa|K2i<7AG-=!z1*2ZCt&4Btdx-o9in$vwaGeB$$em4t91{admVN zvq_5ewRKG=9!hZElR!T568!a7e-)m7<}ozVKk`B_ zOJ(gfr9B8-kkQM4PQo~J8ZDI)^s+zI z$=hovkm&iAB71|eHg`v^W&93sdG{IV%O+0uZ$pcz^wc2q=4{A0$YO8}*|kBOC@?|| z!i)wg#Y|b7b%8Y-X@7p2iuEtg~wR5^44-MI10CM zFCt83h?8hPxV`@tJn5eotWX;-ySItV9OfkB;N4S=PxNu~>Au_L!Z5y3yfZt-9;{Yt zgaDpy4Q-@pUR0S#WE{b-1b=$Gj}6}l>Ab~vuuWr5qGKJ{wT5+}srlx-4_reL%pfj! z%o#8nRdxTDWKQW_otU8Q*AqH<`=0_A9U#JWGvK6~KXu+NaYgQX4<6My9eBAUpU71c zjVc)3U-3I*AF zi-nx{TP<8S;ZkbEoYxVVolKnh=Ai3yB$U>HIYT&5QN1wxX1%AO*2 zPbI~|`T?6>XEnxFy;s}Pt>#bt8kqDi2f@({PF$O*!$AL^0<7iNsng9r7dghF-Mi_? z&RJgs^c{#FU>wvCaSb{rOv77Uhf`*!$~jtm@+HLb*EpI6O$zYJ#c`<&R}g2vk>i$U zPuYU3!dqMLlO#p5E(L?L4?aVK>!@8o0}XOR3)^@$syDwr(7j8JwXSf?-~c`{&t55{ zeLwSrC5N(leUyG4BcbEE95k|MweCa$HlE^#n%PrSdB-1?_#!KXAYM60|GcIV9ul>o z@pjh3u~>K{l7D?2c+%YTep2~8a>z>iN2}|S9=+$@yg22f@}`+_006Exqon1B+WmiEiJ)9;H}f&HMiaLHp;L=1+ys5zd?tc zS6hB-iR+vHwr+W*L*aYx(cCYk=o)7vd=A(B7pCljufGPvRQAS~`x%2x8j~)6NCo{o z*l`P_wd;j{+`LrH^)-tM`}1h#;)B_P;#RPvHfH*`R?{nW`N}y?+7)~$6)aKv@1}K| z-TX=a`X;FN{O9=cD*;RKbiw-bh2IY1B9mwXagk6Meh2O3XljC+88##x6idRw?_V5YNdeq@2EC{(~wr^UWiKg7q$) zi>XXCqC~zk?)6n7qYY${=bXJufF_mTJ*cmIp4IB|ELICc}F0xIeKe z5bfsd&kk1K0eRW!BC>-4v`NfYFG&6$epvo$|33U#6kh#?egIB7klj|!%ayH(2ef=r3Swcx~8qN>y!@WP9bc6sJ8vK?I6D)`_E zT7rNG6lHojJ25Ka<5?ikQh6X^F(NY-=Fq6q{zf% z7c1#j&V>Pq_H|&}nF8g|Mx&JvCz9vnu!)3X3x`*;8XxP`%DiPBQ_~?P_&gC|5L`nq z+_H`z@PsGlY&&G;UAK$KK_~5Y@`b03P04y28XsV#(=+grB#BSg5i#WWM^MM^I>4b3=r@8!{h)bRl>? z^|&dOV!0|e=|pj0xhL~j&hxF$^aI`SbC2&iFc;M9#`>q?s) zr_K?e5-JmIX!NaKQ)`|}Vw2z9X`v)Dw8m;dYr?idG&I?ckX)+0=L<(y5>!@+3gT+X z=HlPhTOD@#_yVZJbq{&`DjxRU#RuvzW)g;*jB{N%Ene+qElx8YD3K)+#^F+A>1MuI zi|`GS(`0=fFMelCeP>@HE0_mWs%-5P?ruzy|3D3-RSGgaLCJ+NFRy2YSUuuJ?Sk4L zke2puwZ|eW=E4@_76+9N5pg*laFW~^?#HZqW|kcpUZv8IeGf?4iU)k6UZ-BbJ^TVR zPb1calQ+sTh7@~yA}g^O)ZqxXV+i`1t3!M*oL30UDZD~c^`U$~e%f7VRxI>9cw+C- z5YiX8jOG%oQ2)0))V9iNn*0YO!UWovU(4IWn^=R3m;=ElUrtS*2=@x~3kQWbK@xlo z_R8g{(42<6_`j8rxHyLg&ZJ3jq;?44!z7BNY%W~|SC7U5*Rw)cQV-G4VlMjPcHe0a ziot~R5;Y+ljO2Iyo3|#zw77Jmg1UzI5X7aFKCd*C3Pi9I%wJd9h@^0^%#@1ua@3!4 z)IWzTzi2w*l?vIvWxa>!)e?&!`4@W>RnJo1cVlc==H{*7IEcjS|;)?~{MSf!1c z;nH;+))aHn>WUQ3v7YD6VuVU_qgC@^xR>(Qwr@XQ z%VH}5A&Qiy;g5=4+6GI|?@`n+8n-_cm;GYX{{TJve_s8^J2&5y1gW^&xu`KC)(yKS z+`H%IkH9|t5X6m}vd!dHTk-~Z#6*o=+Q-)}6RX44>o}oaY^l3>+8tExSCpR1Q<}cV zo?Z1nJIP(Ny^rg%3%R33fl?dKb)owKr&l01$>i*RYXQMqWt-6vCgxnp8h@5U+AfES zgE#V|?s`MelDoFme)sLVr6BYD-2L~+n29xWBjZQw_6k?@R2M70Bl}SAx4rxCS|SYW zYRLMi^+z)FtcP|e`mnRtCZNa@eF-)H_fXjN8-PNkX{+%2yBbS76z28sa)HJ5)ayI$SSw?p1!9HP@3 zf4BU$S~utw0vCG1~{3=uTd`Ud4F@8tpnytPaG*apUizBFh%aStk2#=cg^F0UH)JM#~IL3-Hz zBl^d->N$|R_Z$bk55vcs_9e?~%A&osh=oT{qN6R9j=FFQfxMXC;)>z3%OoBXqn>fT za4uCDqs;W?pS-&MN}4dFLo;8LT%--9?B_Uw^3lyjL4EvI`bqyAis&JKOFnt#jAtrb z=}2>?Am=#@O~Vn2MfO|tzZD}J9bNf9Wk>TvV^T%_PaNs7qe z++~aL&~?ySG&NjQCUjJmVsBO9^whL~3Y%9r&+_Gt_4m27X%M5y$Lji8x|NFf&bdnZ zJN-__GyrxC#Y=0aDONIAk%Bq_fPkQOyo;p39Gk_aA<>`DabHloH-|m?W~QZZ@j2Eu z#}>Xngo|{8YFptKfn%P>mUEfg34Q>tU=`|vk5nU~j}29YMOBw~4^;joeO0%e%w_S@ z_+%A>O>?%?;}gf`X)?-hZo@}XuoS^j zRwkiElbBY`NIOl&4^2%RRE*9!3+VGXi z@rfevLH>Cy4CLjG8rou$D$KY%xdkj@@vjnPlJC`4zU9i1KoTw`zqTcotjNeNrmR%` z*tjTGhKk6^bjx;#@HMZR!t@slEBc%>ImJlLZ8vp7wAdn{-&^6+dZT4W;N z7qxpH->Qa8*|sAr+Bhr~R0b{uX4`%zRLX}1SEdCqrdDh#P&PT+>wOW`@2>{W{%<)|P+t*0L%pfY0 z-lY4aJ96FmF&Z44M~@R7T)P%AHhltRbL~sr!VMcq>wr=^PbJb@lfQ)|Z_qw|@|?3^ zrfGDNHPW4V7?fZKOt6N2*8tyaG#!J8jIFvGIxzFui>7Q4n*+ja_YSr9kw>H}(naG| zwG5mBgUB>@7w=OM|DjuuWPCIz9~MK$)LpsCkP%TnFNp++r6-|-U~-8p=h9y95SEBg zN(Q^k9ohV9!n5j}I_pPDL0`Q~zOJOMQ0Nk6HK<$pZ~TCQKspHZ)!{VC)7v7N$FG%{1zj? zP#!oABOU);errblc$J6|&;C39EHC<$Y4v-&&*zl#sYyQ-L)HDa-Um?*hR}LWb`6*k3gJ38$`i)i%Kn=r&XjCX8L@dUkmd74* zKL@>DOKHqUF=?%rc z9Ss8hL?LIuBV;4%DsKC!?Tq$R;q>%2k)W7zyYf1NQzpFT@s8*x(7I5~}%y97^%({Q^kB>Vn z+(p;hV}*4?LWM=!smbELh$Vju_V0hkZN6IGZM?et-mbjtZ?6?!c)=+Mo8J6ED0S7$ z_Ht##!rjsG_94l^+0?rKc`g?1>+f6I5C6-Jag1mCIm}G#1*jxu_ukN$bo%Z$c9jo3 zOt~!g9Ab2l^Iwb!vY5 z@Ojm7NJ8W%-c!;J7J#W)<2WJ%D+{qVBXH`-@jc8Qi5SNg=mR!AcD1Bivh6S^;Kx%y z$9ceYUvlC8_)g|u^mb|<8PwUAVM{W#w{_ORdqMc9`XWF8MM3}iE(eb7L%@G zLon&+O0FsN@is!QJvU1;&bJiJEm=Bt5@nbq;J{vJx;;8s`%I}#dLjT8ZvLQ01~UpG zqsH(x0zUV^Iki2);ThMt6rA%&gOh}(4bE2dqz-lc|MA(B7L`Ctgt`iL2QLHBF9&f^t z(mYX^bOt`f;B4I{^twGK)kn6xHG;x3Z;P8|mROs!I<&exThX{|Tr#1gs@>xfEWaS#*-h{y7dh={+{xg5($_^2g<0y%z@JmjI6 zSDy<&o7F8Fy_8pbqGGUqGq`@!gDR8ESTI*YmUIdWs?#hS%W)pX>8_8ax;o0Rv?C?% zKWNl>hnKYEA#{41FgwLRM_Iq_W8lP$4ZKfLwTNd@Lnd#wPQfo=By1e9pmVe6NbKR; zNn27wMZMwE{~mq(&qpTK2Z0;A$)@IWo*3D9GlYB1cx9lBw5YGSzfo~tl0~EB=VM`6 zTOE@-&HGHVKk5JM_Q6A2>}IbyYfcb20v|-t`=fpX%`Bf}b|p%DGmF*>0$+of1O1%_q^ zwzx=<79^iPlWM=TWzO)iM_vy_JUuntYw^wII9)wi2R}sF;dLPNWqLLd3v=(;wQ|3FK1&{(Kk)hpcKVp5eHhG<*w>xXki^_k>n^pv z_EwuvQ~jE0!}q$O3E|B!sauyHxWrR}I%SZyHecr5P+6~kYm87r&~%lPOpYxm{F@h? zeKOLKbwaarQG3#hY3d|lGlpX`y=!;We{Ky|rz%j>Gg0X)+&`!a+1z%g4Pw^!C@@RC zcYwk<82$=0O)otogLsJ$WeTuj`jH(icc{m%Vih_H(Rdk4MU6z%WV!S`66Gyu=HRp- zTAy1CGdP4^wu%*pU@5O;HE&;QNPL-&$+m{|-~K&s-w((w-`&>i;c42B-#*eSXStII zz9g*`k9%8^@WHdR-u$6?1G|@NbCq-be@hkI_Nk}!i>L1&537G2c5Ilt23#lL>K6r* z;jVjng$P`T=I^9dK3@G84pZpAs#)qbvpq(y-J}Bijm#i5H4dBd#Pqs70sTI*6W1~L z4?$+r{&S$O8EXb-DKj$zpGf<`I4LiI5B(c?2@kd_9sGw9i&UiUMhfNywAW^0bS&Rl z<5R>qBoTrwW;Juu(`D9`-GEU^ z86_G#eT~_V0%&*daSM}>Die*U!IbYNv&FH0h>cRLh4Cf^Ga|E(qAaeg0rjJ1TH6Dug~`Lie8K6oue_A(VJ{`)*jcu zR_y}oq9>iFzNYsC^-L0oT?-&X~Jbo)2Yei zxGHt)J_Kngvh(oVjV@CD>Mc{mF6mIx-k3vW3hGt96}ctEs(XYk7bQOiU-R-a)nKszPoa(qGgAPQtQaTqXl2pEdutrT)B0&uWvhRaRvXFK zMu8nrvgBba3R%9bJk=ZHT>Y@$sj2HAX2u28BgkWQWm;CA>yx96J_{-%0rb(ZJWNNd z)en(@kCYgDp8`shMl$TLs&rKl>2qV-LA4N8eS0HFM7p+xW+5@3Pjk}VL7JXIzcPYt zfnVx`VR=PfCiOJa$XMLOPe_wtOjn)3eAf zfpJ7B(02z`B{UiIUlCtGB$GPypMn9U5%Ho6B=dZ*gIs6dxdwo7j zOAvYbTMe*P4Jq?pnpv3)4IL+elQc@>V@BJ|UY1$|w^%G1ww{ z-sas=6b!X3I#m0=S^#XS664$z;N;^_JDoRGIj~bD={gHS!r)tA9chlc58ZDZ^?v-yG?o$4f4#Zb zl4v~*a+CxGfs1a%ln92$2y_W~XtH=sO%Fac!gLEkGIzdnY`5L8qZXK*1>2*7!=P5S62yhG6t8?&Rxh zv#v`-^JLoB_Tj6^Y?{IQ-|A}%JxRE|BNO>O;;VuG(Mx6R$D4RYy2~~NqN^94fRxv{ z7pxdQ3+u_ta><~YTGY`}S%z>9Il5tY2I+e|Jczk_2eZ_dBPBwRkSv*kF7TfGp{mT> z>2!au@Dd*!5}5f4upT|6vpypgSm$XE-|j?@3;X$^>T^-ERolrg?T!rJr_-YkFc00N zhaVlSzSWwf2L2}aogpkP*>~Mv)X-9;wR~B(W#Rrg0_ke9JXR<2;rnJ*pdt^wj8<=R z(&)AvLKzLXEEQ>$H^zZ8LMv&vj6LNFW8L>t8|%9v=l}!u!b%JDcrAZSfbcCGNO7Fi z)+eSJ$Uaip{$p*PI`krD*e|l@{bB7B#PUL)~mcZ<_ z`|F8~!#}Q*3E6itK;silz)Z%pNX9e`7P+k&o^4M@)ROKu3pG3?S|w^S7Qlj3q2e!M zc%!#tVQ`pCMOq^h8ebI!bMmv|mynN7fH_3(_QNOP3=@nh%_t=f@cj6x zqA`A1`bP}`R-V?A9y$&v5NnJWOpjT zwY&;R^wL-hrU{03P11u`IwmMIFcVQJcM5X+xdKr;F9^wj%LlbY{Y5*Mz|sTY4kw&yBub`NJ9G6gkaI#gSO26%4Mu=cixiFq%|t@` zU=w_u65+6e;+KOJwb9EqqwB?vTiqJTTa*;G0H$vvGZYm88X0?xV`)?+vJ}gzSqcs& zP=wt4$cV+`Q3E32J{!IzFvWX#cGdLx8-@|M7mM7h2==ac7#g*KhPUucwk{ zI0QB%zlo2Z+B;ez)jOFVQ@1<}K^M!y(T(g9O&tw13)FnPY1969W4b0{6re|3sl+#4 zSx~PN9mj^#_Hn}i{vY;GdfdoeJ}SM^qEiX8j^>-wUqz)%z*@r1OGh@7B9 z@j(rSWitLcA1-nDW9szTixV`h<|E*}lcP?|0mP$3`Lu+IDrC&(m_6hM*2r``8)$yT zPN%lZ-c>EXdlusI0!G&@G+ll74R3NFW(O`%U+84kU_`g~vzD!>9ud{*yDLX5_AOEs zWlT&CToufRB`28FCRq;!f(K++u~p{vgf(P9=EEIL{ROW$h_~K_3ygfJA&!WL>fJ=# zB0i`cafpD?4~g#!fxP_+G}3tDz6A6Ib!&%%!rGwv_7!r&a;QJmXb+{3&1=KmOU@kH zde2#Pman=99C#8qRK9+};*=39wkr8WRCzKlE;1SB{q0OUQ%N(5hj!9TWie0AM?wT@ zRa@FnE1>LHP+7$cqE?ZaPYc4Gm;QqFNAZ9ZSA4iZqlk(ch%LRyy275GbP4gMd5%tK@)))dw7{rO|B<<(U)&4l7Q_sG=dp~tK4@tb|q9`T`J zn$QPSGwx*LY>@xE@oWWS?*EY|{a=NWhl=QkhockWk{_-nloX=}Yp5OU6|E&Z>Gek* zk$IOefY+a$q6Ot1B_lO2v1EoLdtZ;IRRQ!sS^i(_H-7uy zSum3hRIPK=wGl$7-!9h0#1KbX!9koM2=cCKwToW|h0F{jfURG(QYorJ5uph-R(>;+ zA{~-o0z|6B_>FfY(HuxIxJ`3XMK4p^>rQwW0{FPWzgF%_(6$ipDaXh`_pP5DiA$@T z?!;bL-mMx@D&4|ayELq&LWVL|#WKet=vFXci2f}DGtELgZOa*4KepYEFS<^)>yX%j zq*Gl8B>1B?a}H%6FXwVXZ^L0oIi)Wq9!s;LBNLQB|I3bCl$+=82qKKyMgJqW>YYVT ztt@T$Y+r}Gx|qO?%FJv(6gMw5*JRV6QAM2>6W!ooZ$v!yN=>c0?>0QA7bJ}C2=z7^ z+r!*njc7sz>gN*(r$H3gSJXjjGENlos$b&fLFE=7_4dZ()G8!BqB!!B01Wy>eg@xD(w%2TsFs4@tLU|co;Pa#QIbB_=yWuOdrNNv{zFr z4B5nHn-oQQ5vGlgdsnO)&XFm*n zd0!MkS#MR>GjI|>$D6b81GNd==B%x>fB; zTRY6_rh)A}G8uZ!l-7)}X&r8UccX?y8tV`b==_wD8GO3&04kO@8!5-W=C3T5Ixbkz zap6>i8#q>9{c!=u<9$ukD8OBZoITCqf{OMVrvW)%&e`cFhrSa{mvH<#!*5IuHqO6R z!=G^~q~;)F`WgH-sr9QF0R`XqI`6!q5`=K=)E|kObc4-g_FL}MG&VM8|3WIviqk&s z=u7?WY;!uqx)AXrG49Sfu}%B991gwL4X;m#vMX9q@UcZqzs7g{by7M}j^pzc%)^`^ zyY<$>;-px-H;MO=rFcmL&s9!%6hmA>Os;F=&9EwITc0Y%x&%){#(Fww5S@2oDiY&o z*eO}HUW!l%8~^#|#zeX8g7@9ZbC&Itw>N;Eou0V5f7zsR7Dt{#*Ia-`q)r@BRre-B zn>y10Imir(b<>yo0m4gYcp{p}?qgSXGSEclWVfT6pH!<6(~eMHabFxLhKypiZau17 zwlGwBgR@>LSJULJ;q$3*=QCd^a~q~92#cdR2twUy=p*fgD1OM~u}bmgn~WTlmrlGI zKwfroDtB@lJ`$2xoRR*Sw`;!mdBTEso%5qc1>-74C$& z(POz)X>QK<@ZAD5&!JZnWB87rJ-u^8oBR>ro2%SUoDI4ECT4OfI`W#Z#j-?!9Q)cn z)JT0{eT>xYs_~X8V;zNMbr)#rAfyqY1@!iSs?dbX4NXZ&w%J};X|odsU5*jUd0y6^ zB|{N?R`PGedMm%vh@0G$85nkAlrx#G)q9b)Ecx;%D+p6i@0?r<Dw6RhqgG1!ai%PLfxabhseBM1*FWX)xI5Mbq)4N?>ABi;adb8 zjB0di`n-A3>TmY>BwbCDwxhYsC0)AzOKRWzWDUEc)L;qvq8g)cVy9y_vsQ45ECycW zmnKz=$aCt;ZN^(4(LPRMCNA12W^?+&{SNc{?A5F~LVyb=t_JLdtP9VLToprLex#~$ zNJse6a)FZ(Q_WDyI%P&Y;$o^48CO-9zcK5>iZ_xdtZBgiiUlQB#A-T{86_MxH`r9A zQ}%WpUx#?3k-+D?rz+%e8@ zn3g4|Mx7q!`{W5zk89cC&kj_~J%GC!u&)wgP_BYsNhk>s?HkqosT3SfC?xiQPFu_T z>e-E&y}2hPlZ9|uOE&HDl;(+yYr`#>Lc2}Hg4)h4M-5ZIQ%`B3woFf(FrqfV<* zbb>Gu(=-nRv85WqnxqC+Y0qe!LOViID~vi3U+9{a2>mrRBRQ)3e%HCLdJY*ygGThG zc*e+N^K2;uXC3Zm-3kXBgD}y3G~-Rw8u=&9nki*ffDaRNUr<=?KC&I9FzmjgR42Z| zB1n=^<}R<&&efl%oTM0I-|f@p93G3jN!fBG3m@%50&x~D!7@VC%5V`8!RSc*!oBaC z(pmr$!uF03#Fcey2x%^asu<}b@$!8lBe)NgQ9{_7GS;hLQ+u&Cw5a>H`l}m8NxG8q zL!RS=p86mOW_4jct1Xdj`;TTs<56q=Dlwi3OV`Sp<5z(Cm(`rOc~9>WJlc5}_SoFw z`(rPl4h#0@YtZo+T-h~JHv{k~%~ogh8IK*5iz@UL9)H1^mlkl2O2sPh|IxlN?xr0s`wy4%MZEd5)L>G zr!`z4c-3fT@3jU9JdWY?PxdXSY_4lg*;^?nHzG6rEVRQ0gLMC{PJ z;Uk$v6}mi{&G=94{+N!>Dpj5P)^X zJc~9AMEdGley3XUtr%nXE|x%XsB-i=OT;nww=6p==4fF$7ksT5W5RdyD>?ns6X=io zhH;}QF``3FRJ5dHRTzvo*dRV^z>}0Y&^wMH%bJg*r)xNpYhOLUJ>t~F8b&6c%2!lX zKAA(2s}xjztaBNUvoSAMp`;x3?2JS;I>w+#u^H?Sp5R_!gif-^`CzIcHi2_-!r00h zJe{Y}NMTajZ3LQ` z2N8mT)Z{-?N(88Z!^@bS?0{;i8t5g;SDWYe%@mqKHfY>Vbi44mz z=lP+gYGto{=J1ae-dQx`ZIs{gL(&)kMaMdm^S@BiY%#G#>zA5a0_IPYV}BmqFKHHH z&7fl-)66-PGI1j*EMJE1w+oE+)qhB>Fji^h&X_c2eG#U|Q^bobF>rYc$TKrUEK zg~jD@rFsPUd)wy~^7p6vo+@>Zm>g123n2cO7r@DH0P|Nc)q@F#CzB||XCWajjj==h z=w{bn#CWJ}$u!h?QlDOyGwr_D`(m(DzST$^Q}cK6-WZ~0*I|2jr-6j4J%}irLdarA ztk-~#O_Yxw!qmGAdG9g>lk-yf18OEf++XoCuq~2)JMw06Qk&q)ju7$ls@i?GMfLKk zvDh394|J_Fq$*0)G8VS2xU1*S9^=8wsr0~|yhmV8wKxbEnmaK2(F3LIY0zI_hBiEs zG#~#X;GPfpQCh4TS6lrggXyDnIAk0gQa*j0_YHC!fjIddnI99`-i-!ai7Dn2EW*VS z_dz64`q8LTA94?IEB`I#`)*0{f|I|U?St4S9X*F45lFbn64x&c?7OAYBXt|p@cHhh zpR;^@nm$D;h_B~F(o6GsPEn3|2dnx@jn%P4_>9~vgQXVVDxF#`=QaYaN`rFG2%T|h zYU}ITifTanAvQ|iM`DK(Y9H0ELYC+5v2Yf$dJwmds z4t7M*83QDGbCzT|oUgn?TdA~-AwHryFp`5aY2@4iLxrl}!X^!e)eTi`&YgCw{md5& z-=Zr|=AL<;qMQX6@42<%x}!zdbtdocIzK?pVc9Jwe$T?A@?)Vbb-Wc~WPEByG=Lb_ z3I8cbk6sHT$h99SD-@gBLexB&t@Xe^>s=}8$2Nh{SZ*D|$nyW<>;IW}H;m@mjE=(L z6O7nws><%1SEL5ATU3Lk=4(zNw1z+|jNy44?+)iYj3a(>a=KYLc@G1!crW=v5d_pK zYNvs4S<#VUt*x{YY6nb|u|+Nxov-*&CIBnAg?Ug3bO|kisI0!lOYvYj7s}{PZN8rn+j{A{M2!z4D z$xlD9)PJw?wD{7)$+-NW`$7dnQU|Hm7LUDZ;g?t#^;Uq4o?8YLsVOtWl{y&htQ|?L zTeEVavD|^^!I;<=3m&=T`Pk;b8YeH?_9ytZ8SMM!DXhOaSt@YtMn|be>qI3 z29dP-lqsmD-9zA1NX=iCgix+)8SY-**CrBl8bv5(DLvmq&_gWbd89wmszlYY3g zr~wjP%@pL=?@)7LAJe_+DU(O_=qxMY=#QpAkNnQQFj>zQqEL}g=K0w}axg<0dstBt zHG^|M7y1E#=OJ}g4OeEPH*&A2Lc6*qYi#!>g+a6A<8X;!5%HP`5i#9du5iClhvRTgbu0JSsxZm=dvw6~r zDz1|<@ zR~!8kot}4oeLe+4W_dTY%w$C;=s_K3u}SaLrP~E}1?{X4eqo-?4Dyk>3lNQCNqn*i;G(eu<;0u1j{J|6Z=4r(8Y znB$$U4k2PFJEpukNYgDvX+E3i%3v$%8zvZs$1mf&4QG0emn4~sMTE$3wlqv+H;K%v z@AopMXQMq_ITwW%J^#K@MbIEjlDK?xIaUq5qsvIcub>vr;U5uqp~RRs4h-7D;Zm^) zeVN1IXMV4#hEASG;}IGZXrQ&ytRvJk~+N z8ib9y70AY%T4~)kJ!8HJkYzVxb|lk0leV5#Dn$yGYz>iZP9xq@zYCvKO~Zm7iVoG! zIWGr7cC~s?p|vgp`GqVnzRCjtd1(g2=uk&1-(*-8N{+h1O%FO-s2O?wVDMJE^A|j9 zoAwwKBb7~vVP-MQXG7sPYK_QC1Q)jVKnizUAn;AP&2^^q{L?L>QQM$P9%NLqLR;YZ zwaPsPn*ky#Ov?}=~Rl3xaBVB z;S@Vd$ED+QM6TcW*Birw<=&wtM#WN9i^$1&&-f6VZrzALW#h4DwXDD?jC<9W+C^`b zY(cVlF8?22HORZB8R>olWjGPS+Da>g{3i4SHC*7lx3tv{JA$m0NhmZ)1Y6Kz=)Fo3 zDnj*w?*pELh)ah`+bIw}1brU|YWSE3hs; zy&+jk%Yr|DG>=bSjbBQhTqP1(-wa+0}$VqX{z7wl)CXFD%2Ehh-9 zRyK5K&t}i>`KD$!>qQagUc$Bnr%a-1H^4)XtqMZHQ5dGB;ewc#8v44$BfZ zs2ckTAD3IXkd;e!%Q*j+mB?GLwpR%=$Mx&ESXYcvZl42pAX`WYm|xePWA7|CUs|2pB@;EF6XblyD(0~ zcS5h`$WI|4nnho@44Y_WdiU4Ez};BiRUr4n-W>JBS_-PWLOI|cn}or3pq(dmQu0Z9 z`&x#8J!~Qs3=CI2sn*L8t1h4iI$vAWGL*XBXsa4qAlK;9;;2`zd0@{n>Oa)91yfN1X56?Gk8 zPIi30+QLoI2vxj&gTA#RmQqRfki-0Ybu^Z2CQ6xZqiKhAwz6DQId#wIs?aPopPC~E z)226TN>ON_ZKGVG@oN$S?7hCc*SQ!kGN>o;HUVMU4;8?r0&eJ@ZA#@EM}izCi*&w5 zSEg~v%*h`F{lAWY|ILm1&-*Ej8zX^Jy5-OsvbgbHLi`FFjv@W4Cl*lN-FvSFQ^kb| zMW2NOfXagH{XKjbP7%S033mKm%jQc;&0-9<%!f3^l-bX-XAkua^<4d0N%7N?6$hGm zj;54li7f(1ziquMrzfs|Q6;J6H&$WYS#8Pb8Hh#z1l80V^d5gpuT*25*^MxP6P0%% zo>miYr<6?$8B*WPTx9)By-33F9w%8@p6kU6mvk=TILVgY7~#!9PARbB_h{rj~r8-5(SN5rz)_#3yw#9^o0NWTy^1WvagZEbZ6OoIm$Cq`{>R!kv}BE zBl`Q|wEk_{s`mUnK`F>w6os+ANt)cKl)^NnUnz0OWVOJd(0!^Ch2rJeV*PYvnZr6} z-C0YPq*6?D$sLM?$rGO5AF$sfraLI$=Wy=(k3Y||fD)C2LJ=s6(lADKbSjHzMXbtB zY+?a7ahf?c)G$4FH>w$V&Ek=u?Up)c&Q@hn!gToII48lz#=>y>P9?;yt<)l4g?9SJ za~!6#$!E_WuP4YHm3NQSG_x<(pBnnsO{Vx= zBg;pzg>=23Y^D!Ww7l{lqo}DfCrM+%p9QTTH?z*UzPvF~_*hd!_h1p}|DL$4}^7rX-fZ^=KPym=sq8ZL0#t`;BBaKKyG93fXAi zBV}CVyF}4JbvJC(C=fC&i>_vFCC)@mm*)+B&k3%4YoDziwIPlZGUJDZ&kJ`Ta{77u z2M{V(fFP-V+je_~zU18&oL7h{D8->SjS)p`i&q34;wLcZ9~e1%hBRwII;&jbEcoC@ zjWRZb{e>(vm!(a~{R`{wM(=OuA5%OldLy^(Kj$Vua=;>&)h=%|p7iF{ZPhBe* zHM7ZFd;>>m4S{h)1;UpviUcX2RR8@^^Xsv@cnsJG>HWcYMEW!3X#Hyc-%!xhirr<% z#mkx9m5q&!si5FefI9PH@FJ?bs)1B+tou<*7)3r|Cg z7mGKChmiUDGvQndeT&F1BUnY;VsBv{3 zl<`G~&+tT6J-=NE5vIkyPvh^Q$Ols~iH89c*JBt2L-0J0L{f}?i1~j7hF(avfrX~n zP?n+&^?{v-6|a)LmvGB7t@YpG0QF4oyxjrRD$J%HXLI3#q`_|!_u@OuAR%H1S>CWD z9})TIhQhLKHYjQ*mx@c%F<;|j>apm2nyXvpv~w+95By%yuSFh8grJs8@xyQsb$-c4 zj&l_j&0jLItsTI84DF zj(H3#UpgzVI44XfW-yoDzC~Qvklwe5nOiYK-~_ zt?vik)5qHSghjw_-f8v1Sa-Nq%{y{XNno<`C5hjaN>VTVZEI-EtBH8;=sFD$uO5wTr z@%_I{8h2ijKw<{Wb%VQcxjK z6X2Q*QiFZty%jhkCi>8dP(PW|!wOd}nyRUAu?n9_(&#gh#{9%EaYO!;q61H4c;Pw$ z6wL5-v=i1qLC(&&zP9?#pD+^0m3-B2%nVQm(7~2!R0GEbjyNHDD`uq2=jvJ-qZNAI zm{nq&PReHqhel;aOi3mRW?RzcjvbO@mTu6UvdmPMMAiyUYqHND=eqk9{$PpX-1u{8 zFzkd3TokCjOJHQRT?_B^uEEl4_~yp7B}hNQ&4K2Og7b!J{dj6m=nHb^&&Ik?`nL2i z*6xB{^U+wME^>!2E;nD9KYxV}mO-8E_B?SzqS6AKQ>F#&mY57b8Ym>>t|fT}eUv6A z{pR+g#H!oN;v;>bbYT(XvqYNVrTYBU6;zR zGOtk3dm$`w6r^W>(S9kZQ!;{3c>xQstzhbM@)6pjmkc{!efyQ6N9hm}HZ`d+f7GG_>R?OS_!tmUH zTHf5L$UnX`m;Wh#1-~kz`hozff82?sM<%*D#UZxZ|FC2&>w2wH>uj-+;Frb1?lxJf zF#YxR$?33Xm@vLnnSqY%^#B;qt;PQ zj=~p&`=k{1Z{hP?PHU1eCoj07dPk`7YS9Vq2FA%57>xBCshGN_K~*;fDOiQQzk+z-3i zI>0?;7NTY=vGE$z0oed(7ek$&5)!N`$+(b(vM9Uj-d)NEViUPvA7&W2?Kjdr-i2)? z4Jxpl{#8^ms%S(t4C?Gl5vK=I3f^q{Ex=zUz2IF#N*BeBW!?2 zwh)!zgT2x(UDE*k{;*~ao47Enk}?3F&pc3yTb6d?PDrx}ERYPOZumV@{yl_E901CiiQfAPs!r#DcRV6teY zIJpUqCA_;jqs-{5laaN*Ip;g(Cxk?_%8ijn(ZA?a!~Q!)b8cTJ5wtv9$4r2lNoGvc zduK>pwm*_!PMZRW21bBQX7uss)aEq(Qn|NSfDJthv$d4gCK|KZxyw0A8eSKCMW^28 zuM_uPxt>$I4ZadsFkFW6`;UA3euvMO!6tkBe@CfMy>lh0M3t89013$qr&k2UV1h$t z6i?l%gN5*vc!b%rDn;C3f`XERwy*BHV@*400_S@&aGlf@w_?gGshk;L`^jNyKI5f- zS$|iHcKPgaCJpO1YYU~C^=#~We~8}~$rU7phy%Mg4+i64qd?ei!61bxtrfpqj8i$w zIkBT#EruxFqY*%b?c1>}3{&Q4XdCxnlhVUyWwz9Y=7jP^*Qq5bnHCfsn_>;5Fci8!IoKS% z^tH1h{XsTByOIjl<+f?q0IV080^IxRi~dsnt~3}|n=*nYy4Uf+4hJ{=glfqv$=)DSe&dUR;MlwP>xw-4i+z6@pq2~S0h`z97#4pzw6xKB znp6ch?ST_GuFd_bvL#F+$U+2IZp@TiqFi7O?owqXv>M&Y%D3_NZbb^Fx?ofME>=U8 z8SC7gG#qW?5^|8Wj3&E(b1dX3W>UZ%i-%yW|E-|G=d++E!TLyE%aT2pjqoW%)X)@W z2^Jx=liFiSFxN{BsQ9=2U<#_dy-qq8#ERA<&gN#)Ae$$s{HH%7xct8 zn+IU%f>8S)Ir0JUgl=rexi5C73WgEVx8EM0hbq1MWXIxlFY0%OaKei^+Gj8T`!SZ; z`QG{m&|W>cFnemG0AbZQ|C{e5n+fXjq;J67sOD6IoRgM40?h~JqoMjAcDv?+oBJOQ z>B&;7&VGy!3-iYy3;30%U8jy5?cwW?H-CxyeUH@fAHg!^+0QV{SH2KIZ#j1V3s9T$_o4BTzE}H5WhyABxkbLS=_; zoI9gTMSpAj{*!ohI;s$jU`vwiGV}-CVhvuUR(NAx zi{t;Ue&O_h*;*eABVmJdr*GyF2Z?j+-b|R(6Cr77FmC;i z$@D=k<^@Z9`rQvta_U3KLTx2d*^Hn1rOEC+wo;nyLYG7IfwhEojH`o}(m3H|wUuo8 zE1l@%*1cSN9Ruep&&H$;G-YJYEf+Mh8(=m%H8ga#b(5%@U#ki?D_xbGh7+;JNHOqbHuG!Aq`o~?IFkJs1A~4%6nRYV z$I)kd#ZL7fi`sTUMKwHK3(~I8a$m=1ih6u~>PAWM(o7}?Rd3^vL=tOQo&J1Q-Pzb9 zLhtK+_vtlvNNV(OvumpX#CxvwPxAK)T?^Y zoJzN%heoMFO(Y^G;M*P3s6%yniEOU)_JizxYMuGjcxEu*GZBMM>PNNl-%4w=lZ;#Y z2*m>sN$C_!WNv##0M53oUl)Nuj&j!mU3tl>Qt_fd&`Ls{1{zg)S82ffg2%fwbYm}h z->L&I$`s-Sz74IjK_4F7wP9zIsyqiRhzz{_I4FR4A;Z^n5#z&;-$RC*{7R}i=!Wqr zu7{uPl|eyhK6Y`;%ACAAmRLjOA>P8x7av@J0=4tjhs;Lxl&v8jh%dq~?T0d{^KA(H zKe&H--wcjA|bAd&doQ`VLxub9>hU(Po zpY{gQ+P26`*cwYM7j(63Aiye!^LcdPSl(G& z4;R5Yr5O|3bT}0G1rELsclm#L$hp4?BuOR8b^M8JcstmaL#-`~U5B2{{{(eiTqE*-< z@4039ThHOwMke7Y`#LAG!F(rnQGlA{`iGzER<5+^la782-=1F{kT^Q^#=?jBYC7|W zw}W?h3cf)$;$A4RwX1WYJrP(L#xmn(ukn~BOf?9q^)FSYmJ;&9Q301JQMLJj&Isd7DV!#fEdhapO2%zjk=^NErdU- z52I4|V9xi1OYoi_`4nU^LvS{t5TPh~FfRRE(O>Ya#4xj7f;^}u@gXC>x{o5`C1zZJ zj56&IC5l?T!DvY{XqCstTQPBYcBvWM?AkE3!vz9`4l!Mm%{3OPHh8+ht+#c-KKHjG9xJw^ z70}`A@jsY)hwyCHJsmM8aBK5k-KJ;DOIj&RPnxVE^19oyOjSHr2}R>0*zm}1>Uzz3 z9e_Ex)Tig4TY|r@w|A5zNj?um*s) z$LSZJwnL0j^0kcf?P^jcV_rKWqBFV4n3V&3l}d#(uu2Ct9gI_jZ44K+O@~AX_qK2K zv-Y5l_pk)ua8XbN+#=D1PF7CNv6DrJ@z8E%n@BSf(ym)sqtLh-=EiInFyMuEKKgoi)I<9Z@r4 zERqvhz=GDU{Z4V+OrHX6VzgS(^Yl(4prFC-Qf#%d5I=%6!dy4SBUZd1F6^p{iN_GL zYZE3RRP55Mu>oB%fp`tE{3el{!gB=A2=HMY$e=ZsarM-dy6*5|9CfK^SPhrTi__BG zoEA?sA-)i^XTst`MpI`r5uTpvyW1JW$o(<}=>eBCjMigT^u+VtCJfy9sKiB(Y%9)n zc@i-JySSIcx~Q8FQqJ~;V7Z*bM=%0k6{#qxLN~Otzk@KC?eWbEKduhp;E%468e(qEZQ$z1ZxBgiLkB#}4^? z79oXq>dk8g3=CVuJn7r3B)KnVIQ-Ac`^y%Gh6ksJ&%@K361{3eb(+BV+mnjf7FxUK zdLOHwGz=Qy7Ai)i$AP{h#yZl*LEax8j9qn|D4(01r3tF<_!$}*gj>QISh^D+mR60b>>WI_y!CjV3~ zo05e7UBExI*Zf0R)-z51_nfei6g4HjJ!uPM{aVnVPiMjU6%`2tZJdkFTuRuzdQlpj zPP%OT7E~5QRqmy9QJrbixd}Kd(j=FR{)~$3GJI|P$8BahF>cm&BN)HJCnx_MQYzAx zk}5Zb`6A+6b@L*we)z2*0kionaZ_PNW=3N>6_|6q{Z=%VZ$)`4`A> zJAoh~`Xrumn<{w9dei(ML)_t?f#zqdO`tbQwtSCCFcyOFH!5_pVBaOn6!lawop@+? zTba7LTSYIvU)8K3RSwSN(!jg4F}*B@DPpem^LR(iPB^%k)Sn2t2Y8O+51 z)g+tN@FX(7#Spv;g@g=cR{pAp-&6DvV30iP8^x(FwMae-pyI(8mzk!%@i_fSWBk>q z5eDMF5VOY!E|)u^*MoEpXXv4C%qU9eh$!st&Kwsno@K9nc(M}CQ#xI81i%3@)FNfF zd}W4*_~dbR?*Lb{ot51glzi7F;lCu*LG_raI#EY^YES?_C?B>q=Dyu>!2>C(x-H6p zKV0m~^pGsG^;aKQWyDII7#{LOpGXbMW(B8GNAL|boa0oJUb7%HOlGlWi%|Yfx+4q# zH#04LLZ1BXh+IP)Y#;svuQ?Ayo&cQ+uQAb0@qvpTv%0(yi@siBEt2eD?)TAz*~wyQD>kE+j4-tR^P@61~RlsbDQ|JJ9d z^gCn`;&Si$Z&WI7;@Sf=l=f+KU~Scf*v|=d7&>`y1-~t&pp}lPqlTM={xmGy^6|^@ zT$=NqH4stFC;8*=A}UZ-7yD0}cL8tWLC`0Puah+y>n)1k5cSSGoF%-@#SjyC(9k!K zPuc*IWG6m-b?FDN#mK;3MXLiY)Kxu9wX7n=5d`C>lDbO6q5B3?pd@KEUs5=pw zHRU*Z3_L{or*H7#SLt>^5L3w+FL=wqgcHkg(gWTT43;K+vuqz9f2CG1da}FXAM(Y8 zu19nA5ng5FRR>awbR;T@7*KZv=1q)bvRV=^ryyY*-#n^@4RbwIMmb2CL4*Vhu1&o+ zK}(KJ9Y&@D`ec9)=bj>#z)%?7T?m2Pka@n9um*v>Zmua(%2)$))|GcY&63Mog*I-*51pCYnORUgZ~TGsV$cyd%E z@PTk|-S13XG1Dq35gH)AFmW}rkQ5Sjb?QM)i$*uM?ZiE5F3M&hSapO;LNC7O$JYy( zqOTJ$Z}mniy)ph&bN<-m3CY5D-{*LTNUeCS5bQ!hm@n#f0{8B8(*?-dB=(zBfgLbT>B3kdbptGQu!D_CI*~Mh55@eyRv)EG13=KGy zZuXjLP>kP6LgP9#PxVxIuKXt2GkaVQL7M{NZSRJ}QrPDl{4RQ}iLx1pG5)N$1Nwjz z)5g1p0LwGg>O(5U**Ykz$AeB6kV3h(Cci z6{8H41Q7=l`Q}&w)&ceJtIkO6e5zXLt<)uS7dnQCsI>5f=nK8s>=lCxiNOTLdmb?PfD zCJ0=W$(Uc#L3>1c47dAeK0>oL3O~RpbTeP^`Mt z+HQRqk`v0C=Ea9u7JgDS>kbEC?1YP_K@O-J%cp%-j&9KKSPy287}`x#o2Izy!E>H8 zfTgcP&wkpcRvc%pqSD-Inn;x!4@q~N>a`SJKH~A~iDgafS=Eh2Ge+{upSSpu+MN<_ z>3%Yvy|#}C1Ed`>;MSt7*z^{C^eMr7W|PhVL%z#P=kUol#IFQq68Kr|2t*&79wfh@ zQB_PJ;%I>Eg+GQg~zg~QAI!IMX`b&oNuDKju!)T-8cSG-Q%1^}%MJ>pNxJWgF z4@thUC2L&6{oy-UJHs`k2j@pFwB?Q%Q@j0b*VKjuHYf zv^br323M{X(?D1B$-EH&p~#p$MvkAID?dJy_hbP^|gDvzHQC@H_u*d_qK(rhdt-sA{*kZ*KU;38NQ%ZS(^Qx&d*Op6?artLf>^rSi~dT6uV}^&OSkCNV}*Hb zK=RQiRolXMxJTD0R@H=eY3=7(<1%SUOHZtxi~x1j?X%^f^Tmgs&#C+ z9)Hr)=f7R-uFB0-@l)=dukrGE=#h?aFm@a_z{VLHwQ2}w^CN(6ONrz=b?gTK-TObp z*)6=9X(uuV8(9;%AKc!hOoYRjLe<+}@O{=%9h1LwUhlcOAAd$`%p6!Y4w&$G+v-Q9 zZ~yL*Kiq6|s<7uh6?@l}$j@y|)a)G&y%|wRl^ktHmk}q&!tTUmr+Y!sC=C=40dK?; zMHkiXe*USOoj#lpY?`JAA8CGlADwUm&R;ZK?J4?P{G}L@7w;Ia2w@6)yD`!PG<3_< z`ue-o4-7I!_X1yQOb4#_gEuXp%*zQyXggoIPvm1=!%MDrV|EsQ8k`e_3B$hP zA5@_vq2^DOYUd#W=)wzTSO}@bLj?cLN5W`#_mJK}N0gUJP1*K8^0B#N?5B7x7Qdx} zx6ssslJU^9L}=xVs8DLAyb4lfRoxNYxEQ7_vO!2Pz=G+dquo9z(l=5jfMlupcEHHZ zup}UV)>YB*U{G_+b;!q5DEcWUI3}Ve82;z0IACwW6$s_N#>B*u{6h-Ak4QGVI%P8D zwqf_r}>`5u~K}EWh6$7Z~%d7krtP8vsEq#S21SQ_0I^g{!!(KbCBUP z_uP)T>SlMX-}|RJng;aomd2eq0j>+f?c)u;5c*I!GPuuzS!zgU?(HkOSJ9Jq9=B5Z z6U7L}1g<{DR$GI}Sj;GKg9!Y*tk~24ss#5$4b3}cXTH|C%n&At!LedqhhTYKx8p2- zw#)kSl5?2DaxGXZ49hJ0Esr-uoEZYZB)poEDO0x*FIGIpkcK9>s=9Jvhh8SRK=UTA zJ-$Dry{N$0t&xOhe>QSjNTCt5HB@i*EaCOmvgSm&LIKQDe)f^xA=w?xm+v{Gqm6<| z1!!1*Cj`W`0X_MH-JmnNsB@}}4j6H4Ws4ND2#$q8qw)tlHy6&y`WYYAIO_l++V7@$ zJ}9qKj$aCL9w(6YyT_T?dw9CsRVVv?$)Zhwt@aJZ$-uukMkaEaL%c8hRZ z<&nhlWHoC}mRg8fyn{fuOnns~tM8!`h#ZXv z$jfcr%Z=WuMT8ATg^2EKMMs*G4iYqS4y1v+UKgy+c6D1v@?r5D?|9Z^W_S!!+pEdl zmWJ4*k6X)QsN}jzm1~H{kUB3fLZ?G+6Z^e(8>au?hW8Tdbn2+Pz@IQZMPJOZaPSzH zXB028{8;KGN;0xONuOnV*=_&xcB-6hF}SBg?BfCeHJ;0c=9x7aKq_ccxUk5bzppi6 zn>AsVwR;2HiG+9DqzjZj97VA^020fG6jw=7v|c3TwEaQRKfWbe;LNv7OQh`Dey87c zOY(4N`kSrjQZceW`hy8;1*wAEf{uBBn|3S?n+erk&dG@TIVg6pv1brE=)#&ik3Px( z2ZvE#?oLlzaZ0?Hmr-?t|Bx#2^ttmN9A(DQ`17zRqYFFPG4y>d;7;iiSS{iadj=E# zW>L327K!fmi4__Z?<3a?Qe&w% zCdvUP$;W+L-YrQkfGOLuihZg74f_pukgGQ?hMJ0fCFW4mv^#X1FE8|>+j&y4JCMw0 z!>x!-tF&T_yqT?DM-^&?rWTIHg}$U!aKvSp#mI`2Y(odQ zb->Rw!g&pB-EVi{RtLoM984THU}0cNx^#>J_gci4&60L}(fnQPWi|jTYg5w?g0Sxy z5Hxwg5aj&&(P^ij`+tzThP%yqy#EZcCIHX$zxk@e02H|ZUP1X$Zk9tCWEdMt+(*?U z4kd@qdHevUQKmWEe2woZ&8unu5ZFI|27CfB+cIOvaSB=4s=#iIm zOEhPwVrJdAU1Z`O+EZ+67IsR>XE{>nS1CbMKMaO$K8&@i(fxh|9lTGf#4rP)TTxcR zudpmJIL#a76}fx$=5sL&`?1X8eU(#zq54vEbgJQUi@pX8&R;a3+MA5vIOhF^> zYS^q~^9pc~s4JwJI?st!y(nsBKe8r3p#xB4wDO2tV-=YhVMGgY#`=8ajV|J9eoPXe zW5kx*sE{}toXu+)05lAy!@#U$uH}jm3c0eGJJwl5sf{ti{^sWAWo7tfOOu};dJCLK z>gI}b!GJ(Mu@&91EFBTqWm-XIj(OsbAvr5$j? z)e%zZ>K=8F>FgSA{snM0 zbG%QK-(>q%^nb5`uW~J^x_Qa#V_(Nhd6p?pvX5TsU#bv-IEXGxUG{y6(QkK8!tR2q zHEfnMP8()3>|k3f+GgmA%;$W1EElY86q_deExaBezehKJ6aKfl%!Pjg6sVi;45yLR zY)AU|_E`V9!sK+R$LgA4JXxW zP)BEh`>W8q?8aLT>Z<5+5Z0Y*M_F19WJ#L%=JcNK&DJ5u0I&tn#=~I+{JcsM_D#My3bPP^t-RXWo#EewWW{1|;luKZAI(#GO|_rQawc~B z?(07U4n7cVzWPmS1nYc9*u*LOi+Qf3oU|&_`u^-0d}DHakD!=QjNPRi5P46ON+iWj zq{0_q>(;>J5@H5vLDBa`XXEIb){7!KAW$VxuC5Vd8}^N7L*VK4B9^di5%xFPe4e@U z?*3Fw-m~30-utbZ&EC$#L*`p!m7Tl-!yI*Q1C?})_i9O|ZiI3zilOmGOd;!bng;lf>uK6a*}D zKT(tgtK(Mx(Q9*EDi&n;KBY#MFWwX7uzzfP)vhe+=0D{?!aF(JYY$Xrd>RsRg|>6+ zRN_riX7S7d7aZS^9ni+n(s|}~*rJ~6>EAGnZ{c)I=nw|omBh9XSx>II-9Cp;dIfkV z>Qq*VMVaeGx4&GYuOA<=0Y;9(eEvG}OH44){YW*22YV)uj8SJN-JyO5VswRi*Im5j zf=23Oe$#xndTwN-u0Y^Ch;xrb-x;pS1#S83l>D*EA0aZNQ8c|RP-m?eB>D3OHM@M$w2|pR_}ne@p!`5@ zRuhA_wDRc4d&mys`tf1SHSnAFZMvG2glT0By-fW(xM-GRyU!TTzM3rbU2%P!s1NuWN#huoc&YiwQgPCu5wLwW zbz}2}0lpNixS|XC`@O3K+L%*(p6hcfR6*w=;UzrpeRlF*$E3Hz@)AfUHv{qDPZiPL+2`9@5pI}TRG7}wvQVaqi4 zG0Za<-lDZWSi}Ai*D2bgUJHciV#K|#(!B|bC&hpljgkE!8>LzHxkj0T<(Mlv6<%&b zAi#0ZUs>|oufDE%5GhxR=uf@F{wx9r9MSfmzq%nJ!R9*cK>(cMJ_B6C^@MFMW`*MTr(s>BnmP%pqNilbzB zbl%Tj#V-J5o)M#70at<`v^mulNftt~h zfT_BPy1P6Hy-bmN(ougxl=DCG4QH6de!;?{?a<4I>)1&iuP9e_U!NM|l2QWy>!l|_ zQyjAI`WurC*r{TdtoX`)Tz_{9%hi67z=lTojsW-$@RVn z$32bT_hG0x2L|a{?*gJuU!6epun$VAD1>{TZNuhllz=wi{`xq zn)V{aCOX(xI$nUVn-XZry%E_^u=9iJjl=I-DEB$_+;FK{FehWcKQ3ZNH?}=bTZc`H zQ~~})_sLDuaSp>{v6dlJDbr5OKINoizx+{u>5m9q8RT}EhSp2ap(m^jU`LbKqWx8` z*cqWg?kpZ>Yoev`r*R|k4w5Ir#rQk3r4I$V&DWS>7!sro$SLgqp`m+55N?SmR{DEi zp_0k;!hgL4R@r3pfpk)o;>645Kb!5NY<}`>QqJbB*#U^+07v^JK-X)!EA-EOx$yze zy9ZXLoSITA@c>JBYxrp9Qk$d_xk`dhLcu=_>h*^}fZ4`!0)^uWF=k7*@+Qd*pIspF z3A#Dw*ly43R@dyRFug$TiE_+lq-(XDj%kXZMYvzkRk7%OGUn)B!`;uvQ5K7x0pis4 zVe%}e{8S_mgw6H#&TGWB{|=7LJHfWF!*#!Syj}}+#vspgBHeZG`$}27iu5Zfqu?(W3~*S|rBkY`F2*_km@_RD%c6=Y z%Nq{AKfiC`Ox28m%NC22O-~O9fUQH5EqhFpOAZ>Qpc^6p_L}ZjTc2AV$0S^Z#L+>O zFZ50=bhD|WR|b|lS(Vi_c6G)?b2t&yC>KYXUze-LW7|&fp%j!_CYI&eZI|R7Ugw#-Nje28a_&J|NJC{V3W0m> z3*07Wsu>zXDrJOlWELmJp2YePqKQD-62BqA|UYl5xVx339M>JmL}W>H0HP$C@^==md}`zSU00 zQ)*}<)5MR0*a2T-U1ZPL1fOtWpZx+7D+iEH(w0oSMppa!_gR*BA(UVQDaDoVN-B#M zT?w*NHo~Na+k&C4&NUw7Y6cERO1cakPp+O%)ItJ+HH06q^-S&=BA05BaFkLq`LVOE z*et2gGZW1TzT_A}nnDX1k><9Ba9}UeLtC;27a6}KREtJ}ElS<9H)th&?ghh`(JU#8 z$E6^QAs!xPEwHAP+5I*y#w~RH)yUMUz5R#Jej+)#+%;qkNsuCyw8T~OjYLM;(FW?Q zliG8bJV4ATI}^sBo=j2Nq^G`beWo7t$Oma%W`PF{vG?BxHxNGjbZfQQwrr`tw!N3ac{Ob;Av4 z6_dDlr#5T4PF4lJXB&a`(L55JM9fsrPqHeB7TKidi^k1{(PG|1=Id_#5_G<8L0wf1 zi^rXL?%?Ag9$30brXPJUhKee994T86zLJq)jdj}qxm39G$1slxkKXbH9ikgvu*=>T zGPnNZ1cy^fdx~BhFgdb@4dCG+Ck9hW^lSeu~q0wafFWuva@z#$4+-?RJyT^IOd@ zr~Fs27BJJ@;L$(fs{K^oc{k;lB+&iTv3u>*BX4q(;U_Us(WM@Ewa)QHq5EG?>iP3j z{+Tt$m;8W#*}K1-#8gZkaQ`i-82n#P-ctwZGa_|Om%mRhg`4Yuf`oDNaI@uQ;xQQ; zII=%rc|~}v+rR!1H*j)ghIBXMxP{Ke)bb0(6YC3W^Z66{!+@?hO-;v5(_d5Zr<&KP z_P2}b@NyoFog@n~5;r{0{V}oTpLF!F&m=rz&|c%#Z7u&PrO?Yo0P4Fda=M*CJsfj) zwIw8=LM!#1X9xf7dm68}pjL zuEjIb#god*KlzVaRa8l9qc3vSptL{7=DHCR9ui8E;7-bwu>xYMchV=h=u33~)=(4! zB|Jly7Xg@mXNe*TodCBBwx*LtK3WDg(rrH4lgO=PLLT_N)tBoS`p#FQdhIO7tg;O= z&G++ZIcc`s&a*=~RM;@mn(1%#Im#S2yEeKMGt%eFu6JU0Ha(R;or9uq`mre7FAxSn zCX0W)3BV29*J{m2#4KMVBj~jd!Qth%+P+tc(9P!clE{!1;co*(3q-- zV}1!vzvEgcP?2fbBo8+|vZMZtu*qb8r)X-U496A#?JZowcv zz`y%E%nZ0)rt~s-s_L zj=G%O4IYYr1r=wB_dvqxo=+v9Yfvk`8)Zdj6&$B!O2~`Pg-1;Iv~y7lo!;kM=m7l< z?CSQ>=ZuRAahEy*>5)wSu3R{N#{<%?1x>1?*1(NiA4L)W757o2X?Re4vUP+Bi&=76 z;o2xTbk#VJu3qSlPXx`)!Btkj@dFfR=f@;JjBtWji{$sajy+&Q$l9m=Jmm{({dgQc2w*k~$mzcG?oKbed)5 z=O??$BW3v%XS07X{Zs1zORxX%`&(1rInPJYS-TiP4$y(a*S$B4t=w^vUQs!;#5?eV zhdb4m{dJ5ymfBlEb2vZj*FCi3*@uOr%GyMh`WQ1P*L)kN6{XwGc;a#mx=iKxIf=ci zk;3L`0Gp653pa_)6)`UwX|ZbvX}~@uDN)-m>GfxLp1S7bDa!E1wF0Mi>N-J~+5A;H zt2Z_~uj@p20PG#dSl7??+_MLC3kA~o3MC0$%y7WEz`@IyY$rYehuP)`@~vffJM3u) zHkpn1SYAg)%nP6bAzU=!`UUSfiA$Yx{gS6v;LY0a2xxukAhb~lxigY8R{U`wHrGTE zz*f?oP#sd$K3E{QZ}hRbPVRh#YQ}VwtRYa{E+@CE0etCzsW_}^qJpu&6KoTJ31CTH zwpT4>&D5(cW~WE49M&J z!~V3e_&hx|+Je5$H1#h*b+({}+-syLa4>uKu3KgId(ZXF&pyZhK%99Ok--G_wE9;R zaB-|N$r`H!t)Ed5T-vHmWUlv8;i-IP8x7Br1peKt6ibkWKP*LQ6X|1*7{cp!dAIS;x!c>M6HV^|GLY!H)M2o}6O zazN%#AGud-Wg$K2DtGFmg*(CW?nkh(cicpFH!N zv@=$^Uc7Cd;!4}uJz{C%oUmwZq0Lret??dZOHnwk_qZ;*)-YmwuZvn&R&=m1vV8gS zchhu(_RCO&sOZIBccQ2?rC9My4MmT7il^!A-4yA_!UygpO6&K(W;Tw->_yX>O;+n} z#Ipo3O_vtzL^X!giX$Az9>C~Ku^zWTDr9bdx>>upcb6zohZ|j-pI$`Ai)|qx_u}4$ zfOcVWQ-jmA`}Gg8OEZD&9**TxNIIeZix;I|`4K%f%@l#r9es?2>=&QGxc zXvyg)RtLZXT-<$Rlj?q(T3Kswt)w@b-1)Ai5{my5et4epD_#2s6M9I+d?_~){g(vP zR-9cxVJ-weT% z1Vkt=_1vBel9;}Wf6g<)DdO0&fK$*k8~CxMkjRK4CC946-Q~ z{+#a2yn0st}aqUsmekVZgBX8W-6(5I2es%0-dkRwxTd%?tYd&osR-_3b2 z6l)Q1^V!`%49eUehN;TWow8{rQn)68a`RYUt}4$ndXPoWPy0OP_V=vsJ0`RF__c0$ zjs%8r)jCm9LT$&$w9(IP1Uuq^Xl3YxpuBiHhk6 zehi5I?H3UzqS__RM9_fgi(3V25iLyq?JFt)@T=nlV@=X>CisF+RRlZ%((sd!aCwb@ zCNavF%=fPA39BjI4$CKG=|#VxDKyg+_(z#J$92kM5y;*dZe6Br;Q-%H_Bi8oaxjb` zc)g}iuPs3BT@MOQA9lWIj^a6ChWh2qxDEB18aF|H%k1^UWp}#YwArExoSUx3VFy=2 z#6_n%*^8l<;`#Wqr`LjnwIh2FxIez)nQAwIQ{yScLjiMKlmzOx>}aGcZovZL=ZKRM zR8K2Fo7%by2iC6>Ax^4+UX-Og!SXyWmGr*{U=J2hcaWlh|IaQb4;)zLpSp=;{`uz%OAKT$H(iBn7AV@sO*RWWay0 z_6`2ba}89{6LI>Tv^c|gxuzFCvr|jfYY_JI_3-BQEuzVxMvtg4&noZ9T$MdDI>#y* z_0I=ddRrH-TM!X-G%?Ja>2(pzD`xb;n+%B+iD%zL? z`9a7b#(ET(r*agvWp(8UeP_eKg6{x&;(E!@=SE;@8w2ob1{)ipN5zEe6LyLwld(Q0 zJ8pBr4vzIAo9Vb3Rubwwx8S8zMk9TG>+cq1q*u=3W2SvF)cF;&&jHF~a|1sI*iS~f z&p0mWwB4qfj;SX1B-YpJ=z9ZNr2s_K9}ag1(&<}Z**r7r3~oYUOhvK8X;&t>0jmK2 zr`d?tiA@B0MC(Ewq%+3SEpuT<&DodBVUWp z_2WffaHFKdOs@I-my6tmg6CGb_Gl~*|H*&i@4xO#A4d_Si%Hu4$DR1HE!(m!+ds4+ z!5RTAOK{}zHqSi#97uv9V|8WqbA3`z(sr->>I=S3-o($JC9nU@x5>AB@3+fOeZyP- zp1;##U*CKjcF*xi-8zXJK9l!}ZOb*_AKISWYXIRQeZ$^LwaC#DqyRG_cWL3mddD&M z9D`B+)%WDQtjL_mw3vxZqK>q1Bs^s`eHf7xy+54Fg}tF%b!Cw_69xSo;#%WnQ{WNKHR~VEMwE9x$!FP7{8Qg-D@ngr2%h~Y*^5CVh{KegWEoAXQpbT@d3saElWWPotji&R&Va#Qo*bUTXMSw> zTlgPZ8oZ7%Ex>V=0B#7%;T3Do$)0`o0e$k|Em{S#@NLDh5xzxPd11vprHYVLQhDeT ztjw~EATYkBG_tH5=u;Cg09YlJ^}9!AajN${bxaz_)&s2SMle1 zj|&3=X*p3F%Mz?xpQ+#$_yfikIQ$YvyyEl9}51y0iKt;&9}FVk$u;}CcT$Ry^*Nc0r**OSHMIYe{T zAv_)!fHRJ#nqzNHfC=*Aw6@?df*?BY+Ik^zByK!5WV;mr<#Nc8aUa?QN5R^I^fl1_ z-df+3(_2@|O57zw7l3vd$MoKXodq^IR{I^Pa=o9UJzA4gL`^E`rRxM?jYYXYRV@7+ z;5)#%*+~0la9Kak$#R5jI-5=8(z&zzx+LS%yka4tuPX!F#>0WM+I`82T>r&ybmf}-luwp^t|ec-kyR?*h*@b6psxJNUpK@*0tnuF{U*v8!)w)QVy`I zE(lVFk%cLNN$unLGtKn=X40=9!LFs9B4n(k=bRBZ_H-c7VHe;y=BWPL()D>`b6t9R z?tWggQl~7s9#FI;JAim3a*KOb6_d- z4Cw-x=i7Lv^@#KB#GIb#c*0zYF*{&qg8M@Q?MT;~kZYSb?^d&_2njj@7?mO;tGFo5 zMgy{Z9Jk{5&WzQo$7ySSM+`d@GS@kcbUjRv2;bxkb*lk-QzkFQF4k+D>hm{lrFt(Q zjRzP#li}VrH&C}uoFXt@XN5k;_ucgZY(;329y=e)T<6A&;A5z#n&^478RobcrzO{a z%mE9gtMxe8ET~G@c7)u}DFPdl@Bkl=hJ2p@3y7WVOUBrTH!6BMPRZbgmK}cQ2)7Tg z$wg2y;s$aB8;GFPYw1atbQpR@GCO>Db?(ozoO1vGJZxnuvOw+GhQ5d0f#>E)Lq$pG z##GI7$Qt|`u9RQ$WV>F2qZq#|r<9QN)cG_n)+WGMP^6>wBMy@%k zpI_XR7hb<5AA8@Q%X6Q5o4iQgE$@}*$TcU=%6%WkFTY&g{9oT7TkrZpdDVZw*PHUM ze&DC%hyTs9Wh)rT!+-P`zpDTBt@7b-y;*umF8}UBe<(k4&#%k#Z@y2i9GNB_)Yndm!6THK5y@S$Lr;lcfS8` zpTe21mpA_8x64=FuqjD7lKbBC3-Y?}xl8VT-tF?U|N9;CqBA{7vTeEhU2m1w{ovaL zPh~Jcf8^M^^%?y$_8L%u{LqH{wqv=HDH{B`{Px!E@+~*(>t<)=4}S7Ba>rfw%4_cW zL;05H>uXj&Dj)vP8{}iZvUq>+z^;2+bTylVjPPJnGuE07p+<*=mZ8<`Nk-R0T= zcV*+ka2ld>d_y0nT6DBxGGTxSG_e+STG(ZoC3ZjkhHK^XpM9f*T8W(9o6CKVoRgQl z?CH|qJi=g%Zhu{p^l5EIDelN{QA*KBeD!pBTObkSy^A#B4{LMchAe8e)Ll;1{t)% z;=?10HlS3paT3SIK5Dye6d-A$#ZWOd<{OlCU7s?#B=((5t}==aylYGe+ ze4e!YxoltF)x!bML6B8jHdb0P+kRLsKdAM|C(p_sedGZ-Kg#5ajlPT?z91)#UoE}f zNiDuQG8&9zI@*^@=RQSi1%y`gHa7GcI|S$;-M{?EwybY$@aw_uL@u7cAhYREqO>M7 z#WSm20Ma4VrWD!(d_gb=!12hJG`2)u3^RZz0U1mogD3zx0^CE$7ulHjS{!52Nk4@p zXi4ybrV&6CeG7zQVOlwcAXzyEgf{emGugl2_|CttArKpdZTjL0CG!pE2X0pF{6hgG z66ghUl(JQm>0+Kofh9$kE`{D$u8tW?kfk;&0D>1ZvjEv}jWzF0L2wU1u7`jy{TtS6T=m16#X|d)C(Zw-0Sy?Om`G@M1zQ%rY-!e{WaU zlw*`;C+!x`t8mA{rVZ9GY;w$omvz3(DR+if?xjm-Ww3Wi^65x&$c*)G*ZM0QOBmnX zPO58UCd1tw2Juj`uKn8WwwOK+-_Kh6eWv4OqDye~WB9hvKUqNoI5G03<00Z!HT3KLI%GlwhUfYzG5p6P$#hBiBhUi=!&quPo7s*Ox>jDFrJR36! zfpd=lY_HRo&D9OPrZq`1Rv^XJHFq?f6QG9&Yr)VX3pT>|Y64@df=LM*0!X^SOowyfM$~2!c0E?l0&f^oC8DQ)#{F225DiL&bOwOWuJi%eU`5${V*`Mf)ByNd4 zeLV&*5o~uGHw6|&{Qz4wB&gp|u8$2Rn?C^MGLBcAC)YTqR=_yN24L*gC_0IgRk{FQ z?K%nSHEtsYtjn;`@e%8IU6Fogm4QvIG_|=5KjYAn*x_-V>v~miZJ2Wd2Noh=Z{mRr z@X&YQG(4Q+bcG=CXtXEODS*>HeV5^{eBt7GuK%zA0YI(;T!w?oQq87bhNjh)P8yTxU10umQ_aR5#{C={POv!v^Bq2=x~3ISZs>EM$a1&ATA!plWRaOjPQ47R<-JQz|5c&ypIfVVw`Od%;G5Zx$X{lcOlLFvQ0EPM_%Z znL*O`-6LnGFOi#Grk~&SujRQ{-!Fgu+Iyw{TQ|!KkBYqamaAoJ`iT72`|Q_~c2D~5 zeezAOd5gUH_D%WYJ6|bxyj|o)-*>0{6@`u zE+6@|*ULBlhmZZ!pYPw>TxzuZ&7ybN9@}E+-FB|KsNk<-h%qW077w zBR6f{EkFGYuaS4$+m~;->zC#Aul)ge$G838@`nGoAwTz;E%}}AeY5arj^{1rd_ zi}J%S-j-keo>$79zc2EQufA38#s=b->BrX1a+|zazUg26uJpg{E%Mf{yF6FmuaoC~;%DUB|EIUgeb>HD-ujjw zke|&yCSP{vUy=#h>pTV>fC}WXELZ*c=`X%RZn^9A^2*!K$}PX3=lQB{mKW*QzxD55 zFPnG%oV@JPf0WnWb*~H``KRyk$J3thHQ+P0r_0yB`jzsMFTG7}PCh8#|FR#FcYO}e z=J4%Fx&|a|^T-4+n%BURw16mCk$LV!8^TeZ3n?03p~KG<0RwsA~a{dMVWozNnwCo5Y=^-X^z`DmX2%V?Z4uw-?$Fa0)> zc0Flzx^m64p3m=%FJ39dWJmV3VA{R-fSkJanLNi(E8D__w=|JQMjQ%}>3pJfY$y+2 z+?BJJ_hfG{B4Y>uK$1eKl}ZXWmv3w)SPg*P39rF~Pr;f}YUj5IRuouMvGz~lQxfYZp-HPDoAoo3B0|cD(3w!2kE20+VP(KAr0||Y zMNzE6E7mN{JS|pZIdN=D3%rp$a&}D63x#f~ue-LfBB>VpqYLNc;sX!MrR|A4v@?{G zCr(MM>(JF3SIZ4Ad@+M!_AcQ#E&1fVe=Q&QlY3-iBb8@8`vyrm9r~ex<%95z>He9G)Pd^h82o|gq(n4g;w@SH3b;5Y_;RUY_=0$}$kqfH2U z;$_}s!*94X-!g5CA0XG5$V4}k3FtS3t)9x4$jI`u}abpq@=uZe}fDr}uFDx0n zAR_2e7q&UVzCh>`g1m@T`sPXM8MBK>CYKP>)Cp7|_$6(nl4TA3NiDR;JQU|e&JZH> za}LIuXOdGg)5HR=Fz1k7jdP_hsdNrC1_7XfJ)f5*D~6;PfM-!-3#p`Zm(~tNMMf!; z-@zio_a$Q=7|2%9=3x=)Wq!6EnatSm+3FsV^^UHG@H#9Fe8pIV1RhK{;BLdcOH$_( zy)PqOQ>OG*glz%vj(j$j`DCd54KHR3n5#H%4F|6S$y!!9PMq(RL2Qq@&uT4 z9c=3X0Hi*0-^X-}Y)OA*MOu1XfKu>2y>RvuWTFxLhUA(|#KJ<4^xgq5yf{2ByR%)B znv1d6C|$-T8ojIu?+_raoyCMlKirHVN)3X3JoCfET(x z@JBV!9-B1)R6{WSTA>9IiVH>}3*BrY=)vim_bvcT+)GN;UC0i`34zQ*HjEE?2J1RD z9Pf!Y8R^_x<%Y?^(>F=`Iz}zX%>0fU2dw%AI0FnW=C(=TnKa%DZIi=uOjo-f7M4~8 z2F`L`*CjUvus1_cpR9V@B*3)+kZ&5D=lcF2rYa`jy~Z&ymOUL`up|(j*M2pVayDY< zS6G`A9zLs>BM1<~cz`E1jyWEWC7}%s*p>x7U?JV#xpbD#Qhc51^A0u<2%5_#`!drt zYP7#66aC(FjFGT=N-;Ihv2R37$vomW|P-MT?M{srR9Q=h(p0b0bq9kYQkKQEo0* z3-+{u=&&S!O$#<=$RG}#nuTVhX8D3U0(Q5BQ`x*Aua+C`2C%lHF6TuMHXKXXR^;>R zbMQv*S?3-70eX3*@Hl`{gb7e@M12e!V>RtFUeelzGirye! z`_da^_@39x9d9=V>3e_TFXZ8GJ!wC_|1ageBc0%-z6pBY`?XlJzd^hEo!=yH`hEVA z{O(_Ur@ZhqzP|)Xmu=aW?J3@nwz>2EPY;0To1?VYk^3*@a^qvaf6Ytej@v~3ukZe9 z`GpVe%9*czlf3Qq-zRT)&o|2(?|$M={WG=$>EyC~`nDyvy!sBgRzFL&PD-qAytb}< zmVi|%@^*Q{9rjz-Jnu%i@4?F=XSU>;i}%WZxiFHstjOr#`FOj0?QNTK_pf}N-1++! z{`9MFd5k*a^84hczxV9~Q{@*wDEEESOXON?O1|$gr*iwhmKSZ^E5G_RKPK;G@Z#I$ z=kXG^f0z6ITjc}z{>3-T55DtO`OTMnv%KQY*BHB`?9(nB#pOl;Q z^Y{MQ`(>oH%zSoM-uu4gbNn+mEs8p0x&PrEx%t}9^|?IG_9R>b+G~*h*YsMOnbfAE}p5dqFt(i^d@@F6UxU6;c&Ak>y{f#a0 zlT7aU%MZ(mQ`gE(>n8{{&i5~CAu`e8Vk#f_i~Hq~%llf`_+-J|`n+e#Ra>ceV3}zF zzjpMLo`;@Lwk5s6h9s9BmU9n$T#K|J8Bd9xBxLM!EmC&(cD0~MaPBm#M z3dttZVym?D=3I-Ui@V!$&9MzFSWAM7`D`NdX)f)_ME1^~m51)VhXGQjPjAVWZ=I5p zPrF`L^xyTHKVL>W+Y)zL1P+Ijsa&``l99J2AOF*j%jsiBq_@%)ztbV>XE4~+!abDB z7q(^pT&VZ*gq%LUCFgc7>pAPf6@_Gap{&QXG{xb@Uz|o3B2rW=7z@h2eOKrkGnc@8 zAe29XIn`7K9)jHqHm}LE$CSVVR01msV4ivO`2@H~9EA+MvCyMdxCnsqT@tm&`yY64 z#YR=_kwpscL4pjm$&v|HF{~-Kpc4lE1TL?tW>69&*+pZaMGOUtEDbvp^NT~sj$dHT zm1NZ+SR|&;sc&*%fE`*G)9(lbL}CB{AOJ~3K~zu2JUkWwj>4M|ASPH=katG#tb{bT z)n(w(WIECN*_V~glXMHna>rKEzrp7y_Q6C1C>_PdbnLBkB-DP~-`N#U$5p4(BDfp1 z+Xia5gkv3>&fB`$>p?vb(CuMhhS;ym}p0SNsA7YHaw~)}Ot^*MPhQooR zxR$&$z#3Kt2q%KV1xnf&-8wzY07c3zjIc6h8ImO*o$(1fK0KpgH+e&p$v8}(b@pMp=88+ z09G%^&e?mV&c_6~utqT~C#acZ560$-u5q0X7>PbTKPQ(TklAiay6fw5``o_n3aQBI$+}{jT8P3nZ9Da!eqYH zwuuG&5iGxcx21jMktvGKHU?!#YYjYe;FFCFC`gGD9ea3P+?&<@nsi$o&Ka;K_vaJY z9}MM^uK5G)r=~HMCqP$jkU)wJtAMO_st%8g@Z$ex?@gdKJ0as8_r$L-{*YVgojy7{_;dfS?^don}; z1J^B`)ZJcBlYlGA!CT{+j=ceruT|CAow~!OE86tN~UvN ztNOKX{{%A1y_r~JF?HD57SC5@IU#v3dI zk9!*qPJOfG!KuD6Mrbul>KkgjTdp~9foT_h2JsZ;Z&+_QKTJ9-fokM}A3m|I+WBlbxaFZRbBb zqlO%(+y3aYy2iS#+q$jWXKc^Z!PL!LGF*H}9{P0OyYIK;XYUhv)j$0zdDZbx`uc-! zk^lO;-txqMAA0NixP?yKYZKyC}c=UEkYll8Wqn%l{$&_NV?w`N?FY z&_`g2kVWbly+yc`YvL8hm3X!O-;c%hJtqA59AKv=I?zG|^R;K4p`;Ux*49F~wM+I6 zO8A=EI7x&4(-zv#Im$*gu^SlXjcBq301ZjoVmg=Yoh_R3r0Gfuy`Sg4_<0g-pOY_r z&hsRUMlu+Tq}60^p?#F^?~&!@_>p|^%f3#^xBtFub*E@_kwiWL%Tdk6xQVOC81u||xZ zs?oG{9RuJ3;EbXnjZn~vsv`K!($3Ck4uX|5pB_r(r4s1UyF6BEu!5~B5XSyD%LB&HJu-5Q( zf~gu$_pV+b>odX{@(goYXEjaCVtuYs|6a@vv@2r?lOb970E%%al0mx^rcCphWUHlk z0Pi~(vCU)<*mBb;qw@>^uyZ>y`v*E_O8{%jeVOfQJkj4LBT$1nO?8}>##3otn9|_R zuw)%dvY=YV>(C_-*?V0Pqzk-| z(hZnTFkYi(vHmX(BT00wKt~#k(`A}+ZWelfhX?!A)P+$FO1UF1rk*toy>MaI<`^QL z;s!BiJtKEZCU2e@;FNcVLo&#{R5kl2M_F@i;s@^^ha$GolEt9|OV$y)0FH|RBsoXq z=pZTPEwzB#PZ)&(Bmc5>O3M!(oGaU17Sc=mkn;%=0XPf-Lwdf@d92sM0l;u_oM3UN z^9AumL_Ydsf(3Axu*zWavU7b^S$3bNX z4tjB)zU5FF!$IuleDoOKz?jY*=$ku?k+=qqUZA52%~HFsG_Y)=bqz_24iXJwDg?kZ zr@V%1D){GTES6}x> zn5`xHp5g1~fepVbmK?VTCUHD)m>+o_J{9dVfTSY7`M^c_sTbcN-{kMe$KPQLntt;> z{n|Hvl{`=Xec{jkY9MsD{gtw2fv(%St=qcw&3}%(=I8%~>;y}B@ISsqe)cWzlOw=h zpJ*?Cj@%M2krB9Pu(Fqx9ESq>W%VK|3xnU>$iQe{34L^|Mo5N zz&HI>zd6?zsgdlQ{wzLxrOCo*M{YR6*LUz%uzTV90n&9_w`W0f188KL5;~`UG57WF zMYND~nd@2tBgxW4&6UlO2gL|Yd|GPM0o+@)CXu(vU~uTzPPR&In5cm!%;LB5u}2@1 zU~s35N1HO&Yu>zbQa*P72PI9Ha^l9b5;U$RN~KID6M5*7^K$?4Ku(`H!LnAk*TXak z8hu@<$>DHEu3o;Z33bCV{H9n*=u`wZ7BH4b4LfFcHkXGpkwZB^ z`Cty&I##PA&OcM;XxLmBm$oyEGl0$w%i>KbHKY?7YOujgIq3~Y3_A*pO!PV3)xpSO zf@~axi3)Z`r|^?Y+5wOd*ze2YSz_rSp*IFD_!-ACCO~AP*~S>d0+`y_eYvX;jO#34 z`z4?W8d$Yp2yJbQwQo?iZL{RJu52daEYr1V^TUJ}Oi}c$8S9RwC^@u7alZglZGfh! z%kb!qfL(Fl$#r!p9VgwqhzK*_I5(OCloVf{DM0jvp>0Z68CR++La-_wMh zdX7nCScERtL%?#^EL~EsGJt8yz%Wybd}@GSn8CEQ%$9T6Urd37Qp&+H;vZyrK?0+J zKn3+EZ8E!r5)8$WW1yvT&Fc(+jb{KOyavn5HuJyh3}fEu4Ajm8k*ev-%{v0*01hjS ziC`ReWV&J&)ikvM2u;nybf)99lmOBZ)VgJTvs}IMxXkyj%4lFT9-%E*=$PYk(U+Jf zO<~w~Wr0%ooFE$XV3)d<;r2~qA)Q0H#uqryCxIn5>XB>D=HtLAf*nBbfVo?IC1Wv@chyg{<`c=8M#@ zS0P(K-D1RY%a{lSFnY3e&Ffg=prEr1qmqD~OJE&Zq-4X^y~$wHv%YeEI3`)NHpQTsG}JM1Vy>`X{?BKPl%(S zH+XBgPuT=DdnP+gegadi;6)O7KAG##%&gF_V5K)T9ob{;n^OCxs7)z1;*Zg?^n0yL z!@R}b;CWupvNuvMh*Kz?9}P#8Fi01buAQ1pYcOvKN`fufc_!9Uf3~EI4-On4SpX(B zt`S5ySUl9P8&`Hz3D}GcIEaCksnI9KVF(8RZ1K)Wn`pF@SO4c$l=Vbr2*zlO#rK9%w+ z!hSagXN~w#Krp;07j&t|p$-B6qBMXg57l(;Ypk9wX0j^NCuCU&V8XZ!x~&w;&W))S z_I-R_#CLe_l!uUk#*CqilSI%>D_h4Kpg7F`bpAks^`FSszxDO#vb-c*9HN*WPrG>>mGS`N>z_ zF1sK2B}(b+T-+1+vfJecj*I-_l^4kCzVjuzZ(ls}W6#P`M$vkwU$PWz1lvXu_l43-rZ3vLZUO1Gqr41c0@vz&0!h zHn;>D1KB=vMsB|S#bioln%G~td_f-k$o+Ea%vsHUTuJka!0X8qC*{J0$C%7)j1#%- z+|6WyK!*?-eOaD~6D0IyIo!XhNz6)<#ws0qg|fRD(OcgDR# zHWE26(wG4jqGlIunUj4+T}m>HEGADw{5t@91$t_p3^xJ-L^SH@jA;*;V@~fd?X*5i zQIY7|)E*5q;WMR%U}{>OFJY?v5d!2K7_%G8GdiSn4mX;2Mjua@q`^6w`Bc}J-s$zq z(q`GHt;z0Qx{^b%XEk<2nxthYnI5>*Cd_nX7b$Op09^1>HOnN78C3dwQ(y-N}TP|$t`D4ot%vRbU<@-inN+cjN( z=VJ5=uVel}7NM%O{~NHT0C&~YZ9@sW1HC&Yu%#xGg#r8;Q}XU=-_<&9(5yo;4p5X# zO#pTPKJ1#wBz4+a=%g9|EeK3mC7E_$F5cokJ$FBmucht^=Ki+mo>jlSo!8k%NOw(q&CBEd)4ENA#8eQwhyK=r!s(gvMW% z&2&92dxIDx=1W=TGnqsq0etH;wal`Dj^#+42XP|HRVlOCQi5bmJxu_tSyq!_i~|6a zV%9ACgfSGDi=IjT8{>i3Z!}iw75mJ#37dj@Gz_?XEXZ1ADP$-!$wW zM|`hkNjO0imdzUdLK-;%IMV?Q?O0mZlN52P27qQ<$FG&uH_#Au3=^>;@Y0Y4x|mO8 zc6fy#BiX>{K!9xkLK@c?X6bcxN=aCkWEWP9g$3i#Y`#w?a+V5%EvY|`IDO{CmTV3* z9%}z14wQv4(*r{}h%CeWL@BcGGB&#U*{kJBD#%dix`T!();>zWTm6|*zdzIQC^bg9 zVAP?n9cXU?I5lz$JV@|c0=Uov1w+#h2ZYnZ5Fp%urT&iHP}TtP4H~l0DMbl2G+`~L zBKr}C6c|ezaHAV?eL{y840r_P&Tbg%+g?k!=AnYlb>U`4Fbd-mX^by>a2Lzo4|NP` z0C*PH7^8UE^5+p7;RWUdMi&^sKVk^fErmdi&kgVC(!Ki?qqbLHu-TBS)g+n4`QOY)akK+^{6`9vS@{Pbg+ zvBjcf2iCVoAn~SiXXMnKFP37a>l3VO7{YZ%ixohw0X2Q<7=y`76H3V1_(sA3tX%_= zJKVDn7cFT%A%)aeAz)6^)DPxPMZtq9n1&fC2!{+~=;=nukSy={YR3LTWd!CG0e3vM z+aGjr+-lyVi|e*#%-S|%?8iFf9JD-RXxAClYutbz_?%mK7i-DZ*SW6i0J_o`bNmbr z>B1&v1r4P~-0Khre~Q{?21!5k5qa$JyXEESd*n~9mE&D`k36{deR5}fzcG&ZH0_uF z(ND{lzU7Vbrr-NhdA;^i{=hx*@xxD|!DwRk{vZ5NdHo0eNM3jG?eZh9yyvNTnsr;Z zbz8S*VSDJUZ<6o1cF^?4_sIO%TjhWI>Q~7fKljh&{wMwIP5G98{08~%+3kyyIIJc$=2;;a`#e{(mx6BD=r%yYlXD z*S%Ul_jOXpegBW%_lxd$k`Mbt`?de{e)-|o{+QhRo*$J9Z-1Tqt$(ntE?Kvyw|S9a zr_jX4)r8-T>BQXiAPF?k@B)q!FB^q=RZf$fsP+kN2AUKlc(K=4bYGKZfG_~`hMGjC zSxuuMxc`neC$hb>qZtWGIv28L^ij!k@7`q@i~23MKP?H%q*SIw#ab$GDL^5(t6rHlum%!*p(nxNZ(0Z!na-T}-7 z>lLoRktTPMXLP&>t~dm9kwLoDF^O1wf^<=?V@FIRLi+t2!gWX@EIg1Dd3@O9mksCeTT3 zpxp+b)X~1{G@12eq5Zxwh$LO4;%mZ&68ZhT138=*vUSoUqig#3gND7QeSB$urrYWV zi*mg#CK zb==5DAH66mX!<#Z+2j(eG-aJfZ7|iU>Xaar<2wYa0aQWH(PcTQVFd$tlFm4b!&SVc zK4QT#&ZrAmZV1glt1p9RnLb#)lr3oKZjZz=q+>C_N&Rq5P5~g0F&yalcxD|SQRVN$ zumtlGWtF{g8MXf4Anf>LjioT(Ajk$FXQ*qb((9yVEqShFI-td>lqxeOPAzpJJ9BRm zN<(+@O41_Z-UfCZ{sstXH3mdNLOl-?ajlUih$;2|iZo-Q4sZrcR@)!SiBmT-nQmxo z)R3J8ybux^fJUHI2VKJ`)Sm&HmO8R70T?%k*td{VK-nfhE+<=&5tikZlzA?L;eZ0g z1ZKddt4e}MF#4Gu9+LSt7>@O4^jXrmPI-ME?c?FV;ekn+>73ky=Hj-_yCH!bFl5u^ zA=zx@%FKN_kW<^WlSR6a-Nj{D*85UaQ+-aOZ3tO}hUO$LB{yt3(;L8#T8h`<>oni_GGaO*fjLvqj#Wx8BQL2wdl0Y*d? zV+7}NnM(?=q{t~pQ0rK^Wb~SAMZJ+@}L3cRbcO8ZaKMr9disCmm$lTGhJgr>yxbqeN;b;#Mf)!v-508ydG>pA3!kz zc-2yp!qfM&NaLbg1Axo9CIE1wH)L(jfz}EL$>Rak#_savV9t{i~trJ8kOn#sm);w)+Ekqimo)Q zdJ6#zy2u{Ec$&ZApickzwwa?CyRK=T&^NBTt}pk7W^PRBlCCiTELq@y3TY%{)6tz~ zXw)ff4U-m?3;^n(5t?jp>KA0~3;T4ba~ay69u6_#;;uj6a__Uqvcw@009eF}(DSKz z+~7dL@ubrE(^`e@wM!m~S)Gy70HYWOV~b@WG5aWzmwn~eh&?8h5!`9h}iOZwg- zlvFU9r8y47B@n9rz8cT}zDS-0`UI1dbS5>SC zKwq+Yq65f0FeUxEHnCq3Aa#4=K{EMm#>{K1XR761lPJ-7ywrU)qw(4^+deZ$DsPj& z`=xLD3txMe{MgsNKz{5~zV;vFN51ltO7E|{O@8EMZ)@|L^ZQVZq+r`B~L^qA?C;w5o`?YVD zH@ti$zw-BfLVo?~(|&8~_Efar`1|tZzwsHq|GuA*zx|@OePR#%6s^#=%NxGoYvh-| z{0<2&y-VJYFX^88W3POh{FB>XB6n`hipWFS=zH}7pp24h*RW-PNiOj9{|>kGsi9+&LWgJevx zbPlWQVym0XU?$MCKIcF_PiBtjY9(4rUZO1S2}QTUUi7u}83JF|7%rCBvciStMDu zlG)xx?fhdB#bXJRh_j%9{%qCIq~#hgi1kzvSZg)5*iyk-+BW0R^zPIE1#!5+a$QTF zkU+Q|@oZ{Th7n7yp^FPP9L>YXP%|a<)EWk`0v2gw)-*YJZOanaJTGp=1a zSg@6pPD?W?+dL(inRZ{6ZV@cESdMPHMzbmNveImnjh+Y z^-MI!rIY%zKBil}+ga zovXTbC^vyQ*Yw6fdX2mwg-)`(;Q9!liK~4Fpb&r+KvGIuxW+JxhC?_+=$ZQ#`q+b} zsYipMW@Q+m4ynI3O@Y9Ab$y$loJ~fsYrsXlU(biBP{i0i8YE<$=DJQ82lR8}B;aAn zVwoDvZl~q%mt?m$WW);rFT;p#%cIY~njmFMsQ>_;)Zx{&bWPhBra%Dv0F>dG(02uZ z(iZU{BP$3xx2 zai~)ofNimS!jz3XV!h8Y%VoM;NfQV1{H>EROioDAxEk9r_6-fAXt3qET%R#?d*hh< zJ;s;1*_kelk_Z3F z?>;2&f9I#QFNaGwp$Ua^D~Q<=L_Ok$ZZ_`@e4c^w<5XzmE1QY;I^WG$V_&>GdI_;e;;TFcjI{oyob$X?e*lFO-ABt1`>xvj5Qs z<-vL-mu}paQ^&@#F&>gt3f)pLWd?Ae)}*`0mt;R3%vLO+pPW7?r*40V_?pl>G`p+` zLq_JAMMv3|$qRJkP__#^g-U180u>St4dcl*j@b^JZ^7QI8kU1o%<@_Sgv61$m7Pht zz&@)rF)thH)lm};*Fv)AM22BW+|#gCG#zHSF-^e5fO(a%OC|t9(+ujL`n^VHK@iPj zxnBT8K$Ffu2EkZDcPL3v67-u^xjb_IaXEg=b0yl?WVt-#0{}XQ0ZL>=cD9epaQv8D z-an)n#_1crM24qsl6nOuY$>a&kIT-9({gy>!!jDhvY4Abo@YzhcPhyTjSPoguSE$a zWzDi=u!X*N0+D83#nr zHAH-aGd$!55WmRI6XV7XZP8LcKLv~2HS9zH8%0J3Eorgtb-pa}x$L!`BzB}rtfj6m zfWjM2-9YWa5RTMV#d!sj8I-+5ePvXXQM>jGg9FIWNOvPObV_%3$H0KJG)fO4h;#@; zgOo^j2nf>M3=PsL(k1%wzU!Rxt+jtY&!4^Sb?xiEB0P?il`>gpq@l!It}|Pg_MO{J zUH^|QfwGK|rxFIM~E?2^(?PdPR=>_x0tIaK(5sytv{BU}Vv8W*Xb2Vpo$a;DJHbe2EzxPLhkSogoS7#)j;63-WG?6Ka z#U?CikoSysX$*TGU2Yn1PWuRC$K{cIr1@%S+K~<a=8)z465oN)0fYGZk9OXv&H{cUFHg^+GAP?z$nY=&0$< z)0ya>f0fdGeHgVpar50G_>WPDS+KdVLQqWFd3OlMzx~qnakuY>d7TDpf9A3t@j{{k z_dC|<1HS)b@w+?ikpFvkv-a}$hoC;Kb_2;vqQ``l857>S`Mm^K z<}VwVrsXMi)@+p!jw+0hnBwU;S7ah5LA}OMJ)SgA%@CpA{&|O|o@aOk?rYmb2y8>( zRgtIyAKBnIyOE~gvgeJL71N^2OS`tjyYssClZiF@)4TeBoy#GhOh1=KzfgaaK!0?+ z8$}0iNApnshe%yQX3y*Rf9l|6;i0~PiHk+5QaInQcVP3Lf9_g7_Jq_9a4iS zl>|J@3dCM!{1GYosV}x#I3sbneJz01-d1o^y7h!g(3u6onz?|QEzg>-rdZ!8xu-0= zm*g;Rm6p{ukYxSVuOVBjL*hiP$TUnC`o%a?jOY96JB#+osvSd2cI4#Yy1_e zfDNa--ZgEOELQKwSj^y>%Vxeehp^kRn;WJsYx#=Dh-4?I(p7@g0@D|{964{ouICeb zUVv!;tk&na#kLKMhs#ZrKc1#HbY-IbYe}ecD{>eXkQhgg{eUDD~qvnr@Yb1D8CP>96x1Qvk`wa(9%&l_F7Ri%4iz1u+VaJ;mdp{QJ(=6?hW zwXCWE7P8l$72~?sfS{1?AR?}QyXDl%t;u4CIQgj63}cFeKzOtSV0)NK{^tcy+Ap~0 zOg;aU%%3Gq+DdooRdCHkmi^4)Ud*Yu9~lLsIb4BUwifVU*Iaz5bc&Va zdB$q(`wW5O@#6r~H~i7Gc|i@N%4sb2kM1of1FJec6K3UJl_6!T_|dvlPP6o66ovmi z&}rQ?h*JPVJ`H(8XpX(%Jff#%O@$^d?9D)~$x_F=kTmx0$3pF}7memSic)}N-Sd3m zbhNBh!aO}NAB*C*d55kxk(F}7!{H@g>3NULiB?=c?QIdx+6g1k8&W(N%Wn2x6Q>F} z6RCODqLTGE#A2tlTHcGY12WYLju>%^Fvl&ZmJ}Sik{BM?C;C48TNT$kGMV3cu^FVeX)J{} zP8}uC{9aRxo^%$(qlm64;Kt(IqKM!3x}D^622j%{*pC2cOh%=<)r_(pQ@gMXtp?eq z2`ab!XVM>CUkayc{cLD|6JJ$-fpXj1G5Y)S<|r>~`xlQm{m-?5?OY7p+}mGnk8jss ze!p@IIXyW)Uk{$)cMl19?3b*F|JC;Noog4z2^YvM%Uri=YXa@K)GC< zsPIk#jJClp&*jr*Lz0SZF?44H@SU?TM~N0Jewedi7M3HxhDP)Zi{EMzXAAtM8MeYj z@?b0T1N|o~WXN-SY$!fkBH&xglrs0<(wpf?#%vc=Y7s&lv5do*f7HTm4x4z_+8hA^ z>3yhe4*`f>dnqru#3FH(pO@T4(So1`0~hoosilj)$b zREaJ4%9Ud%|3d6(q<~{HSI=K*zG&OFk|{MgMH&rmiY?u>WHmcpdb!PKO@t7QNiSHI zbY%hzUyX?+LvH|;vC2EQTcz{R;!pwb; zl2UF68^6+Bb+L*~yzaZv4j1OQzXYT^AG(PktW0qlR>2y3cB!kMv#cfH59kfv*JM$C zLzpeoz&5Wh9*37M9I3p%pOT){u-9tiOSo4kgQpS|nf5~{Y|%R*KX^^lXXZj#F4(9o zqfgUWrhLW<07%#O<8y2^8jdeZ@C46Y_yY13u-paaPnF`WrFCB#>;(|B5Z>mX+bQm* z@~S$v8s_`O+!=@phH4^?%Y9U*Hd;F-tw2a9I_w5p8DKFj^?>^%nPts zM>7HHEl%khK#>fm3gL*YL4OK020r)<2~?WVA@`4UTWl)8>bGTOyprnw??Wtyx} zP*euM6h+yDaeynkXox$VH4Z5v%U}=1N*B)(eQjSt%ipS5R zOw&jZ79J|mERCY@QtN*W0{iK5^QAQn)J{pFrz~p`ik989n^)Pkt)$!G?ozRR67oS9 zJuS8c77iCthQ(g>bmeafJPh-xpNl4m%-${W7nv3I#ol6;(2`ZdQf#Wbm&o@e`UA^V z;m^@)FuI`rl=n3XZesEz*86JU4hysc9P+}@Dx*}1>fsDdy~6H&v1i?ky?E8Uu`0{B z%v#tzn5Q>%(8kB!eM8xFp=hELJ?ez#OGxq?iPW<~WNTPEM(j*iTO~z510ufQdJIbb z+ugP7Xu`*Ae5~qK8#jOMTmkwAYn`z7W%X0gd7pDX3(mBD<=XGH8DAvPGquMTIOY!gq4~fs3Kf{&u~we zFP@cdo5BQ#*FOU$COZ#&VDRxLuxBfUL9PIY3~5USnosvbNk6@p;FL7hINM>&J0t^w zp}4MhBTPn=``z90GkQR)_3e7_z(rBSsCtsFKfrWML_NPfRFV>L{MG(-7}@>`w$ORG4$qqUi^ihwn!6HXVBZy>xh#eq zXD?Lu%e1~8aY%F8|Lp(B>Da^6L?-NqjFPKALWXJ?n1%lrz+XQ@?Nd=j-k~i;1GSB(M(~x<-P)@T#n_bmQ`9}W zN_5a@QXC-kNJUWYdBkY;*sKicIAQctEO@aMxZvQEi$=TPX^jlU)z1pcmF@ieWtTCL zW)sCoPAje!C+ZwvCh2qD*3i!aM9u6D4+>}1D&GbFke(;D(b zGu~awgdsf8oBD^$`lfpQ#IlA8(`i3rLvwn$_+2f+oYNLK3&+*(iX&#J&JzJH&$wtt@4$Aeu%uPmK>_5-YasK>d}d1}33-O%LDEQU&$a(TY7EzjkByLHfrT+g8NwWT^-a6$`m zKS;jq(O6s$%8p)<9q{t=WaDQ_iR+0VV$OgXgwZ(Y&43l2^V!BfCHu9$qAEVAdMn|E z6*j%PhI8dy)zSfs#J~|HoTSk6eEvF>W!KPES}(QifkxfYv(2MN1ncob#4H=fN8ZIy zKhlgS7A)}oq>kBi$vj(Cc(N@(O}U@75ROKe-B>yl=qn8v-hGuOFphRK3n%}^p3z?q zn3c1^R`d)#w;2@Nrvlc@?DNa$eabU4w8guYpkLz|txmkvWnAFfsoZDH+U4MqVZ^wo zLF(a6`^fSgMHXsgXyV!Z8-B*OH0;lwMQJAXE6zoB88=pCowu#oT?QrkVGEGj1e&C? zg|ONM1>1fD=r$$fO$RI6-3-HZ4sG(B9EFpa)Bq@XH1UBsfaa*mVL1o_nv8T&zG%X$)`f2-o07`v`oz^52QQ2kJrM& z33F`gjUl-YWiO`rERC5>-Du5JU$Jko;S(zh`U7x4PI%?ukz@>UtF^(SS31$tFhFVQ zq+S{0>1dZx6}wQ&!D_Q|uca*b&7G+S`l?hTxwgOs#Rwu zYx5C2YA19xLlw*7x|jHH$~sbzszHN5?(o$Sw4a_|YfHm~oIF)tiWL_W{|aFRl{dOm zML91X(KN5r1GaTF!;jUYHtLK;;n{}OMqt_v@~{f#$aBarYu76$*rD1Z-w zu1E7C&=^U-=h@`V<_&!;ZfLV&45p6<+Qx4tMv;>b|FURlYEFhQT!Zjb-sRIvpx0OE z9xv4xStz^gn?Ac$j=F1mo%fCH1SN@l@>wZK-SdhD&v<$NItq{_7&&u$hnvx;vaO4U zBJ2V9ntY6B*Cv0oL89isR9yS2>-zym**6#<&cWdPYWH`2C|dnNZ^in#&u^;OOQTv% zh4K#9v2*yJNmWnpaSE<&=7+X5w1vXn$bbY@SUi!I0;l>NDkOMzK_Kc#u@GS}QS?=i zjSd%<>DB}Aa=11<9cK?Y7OuCv|K-TM#yRWag}M$EfL=&e7I^Bik9Q^pk9~hPIVYeA zGJZZ3YTs5V^B>cJ&qJ7V)PvE^XzSjgV*Rc8`tY7lxa8!VT0(G@8+>*Cq-|LYEFpNZ zNCM)V6l?oH5dzcIR;qZ$mUMvqw!gRE?uVN(CjepYl+lePnq23B(}PE|FJNx{Gk4=X z^$-o21S^a1h@z)zbspJ#$?LKym|6g3D8Mdwj_X@J80e>r0oz|EhzOl8z@EXe$~GoS>@I29;&Mz9eCCw(kcpqENxM@aYn-Bg%nOKJAOGjh{_yR4EW-nc?ou%}5g;o^c8ao4k z*lppJ8t&-#>0B8V4!9|#S%(o?2BA$jPQ4 zk>5)%jkNWFxU@t#_C4@t>3|`ukkgQ~x>r@N3~sWRHMQgKP<@+%RTq zP7dQY*cJ_-zHPW~18je@&B!lS?vasDMYx50qlxU0T=}$S`*1Gcpz$vN7)Ra2{s8wpbczk;0BFJPO`NU zSNq>YV1?0PMW)g=m9N-ESIcP{C$p6el;-N~UQFv6M*lXi6T(K(&i}hL>EPdARmPc@ zQSK=`K2`hmjyxsWupQ`7*IEv`1YB>Q=jc`h#m1$R= zO|i=APakbGMLFkLb^%S)D54~OxVi0o*2KiP=OeC-k!^iQ0u`t+L=U>EoqJ@AE~N8| z6GnSze&C=vKb05*(T%hC0P<^`esos}lIx9N`!JZj6(sYW_%K{VB6Pm^nuBch%@$+3 zyXA)}%9VUd`BH5 z@}I0!OQ<}rF9u@jHjj(O)856r<5K~ZCU0o*YJH>bUHBjG)CU;nj0-RHx4?T9mco-B zp5EVI8d89!WAl&RksX?rdsoDUi{;fT4v9$XSg3un?%af8_iTq6XgFn)iDE31O#q2y z*2sp*0vRXubJGeXZXQVBD7aM>%T7ocN{!n;C~JF^@=JG*aV zUkyO@0xGS0bypYxUyS!84IShv9TEB@TO!gN6$hE!eS-b3++z~Z)=1~2yyFU{L@`b)$v$j?e0npwIuxxDls{w8*;H=9t_`75lNPapfllvAEpg#&k<`({0@F?8ROkmcCs$&suDDFTErfRs@&LEL z#RFTqkE`QSV|a-!$xn^*(6DqzWBT>Gi8Z)m=E8;{lgRfFNNi?HXMUr`EQ-v(@8=YU zSnk&*unOwQgm8jgReaCTf}|eSwwflfm8mSVMWMuI-Y!M$k30?ZiRPwwV4iD$Z$AK$ z!%c^%f^AysG1e8nhOg@RnlhOgG8G5|T0iV~4Q>P8{LrSah6L;^O`zBYm|}jA!Bg*F zLERL?c~it&9L%nDH-}S=$M?L*!!+g$JW<$rTJHVzlq^KBSj9pO6(Ox5*jCH2l|*&) zZF01e0q0N)8Y2^?Mp=iH82vME-f!mp9t=Rl3n-Vlp3Sjo6n=Ta!?M(ywQ#r0mtT)|X9ys7I7LH|==RL;kr18@$vo{r>kCPf{gQn(683I3?rV zzS6IBr$!FeW~I8;R^}Zz-ps8Xme2|tiT@5laQ><|Cwc$0#CDe=GJT4o;;3){3`kZs zF2o0#qtr`OyQ z>NvjDN`K|F#YTsT7l^xswIRgisRI0b;KRtH_}bZ9quZSXF4D)R4Y-6UQk-%W>cs4Y z|ANC22d1YvEP`T2z=cU1vr`36WfD$fNy>K(GxW<96=-4=3C-~%fwhy3gy;2fe_;$N zgap6)DELaaq52#dFtd)LO~I&xy|p`rw3SoKdorBNCwVC??)Hk;>GWMw+$QW$lCWkn z;5YCVBbsxMpL!zk2GZ|b9>Q6j>VbKYmH~u6hDs{Uinp81ii6)_`=Rm8_-qzHGIokr z8+G;RM`oc`jMvPFubs8~5$4hxP$1Wd9ZS*6&Xv>E4_+nPFI}sWV~HHYHv@Pn*6YyfLs` zp&6F;lOJQj&%xUi#S7BL;c|+}&$2^=Pzjj$p1!W0vHwI~QuKE*R>}V~l=JI2)n}RN zM()vUlxW7m#OXo3Q5z}b>JCVTwlM&F9=n7|F`roH;UKHLh!mq^L?QIJ>}0wEBOtOL z!@*?d2mTsiNwMDCODF0j2Vu;6yz?z5BcIjmlExPPwfJ^VAEZT*!KRm7xw6_yPaw^9 zH?V{*E}sk^3DzxRZYqzz*415WVae}O^Wee!O+?@7vEIn0w9?(0x>LEXQi@sF!tfbz zH-cg>cqZ7d_-NweD8(0k!rBf4D>=PtFc)$4r4Z~|h4q-sfBF|NE0hbYA0R~lPfi%6Hd66fQQxu?Ec_aFCqB{c+(=x3T~_0) z79%Qedaw~i`T3mrb+u*E`%WTh|D9S4nv^j+&h@*Hpzq#U6h>FC&<%*b&;de7x88%m zH2V%x3f*9nN|D)a>m?`APihHy>EVyB#$&$9C=B|M#|_L9MV^sdLpX(w@iar|AVduk z7CKgCfSLa@CSdSz%=v&>GH5Y`=nKX>EuF*sN zqqomC*{y!#|B%~Oi6@(PQQN!Azqb49z$#UxKF9p+w*`1lQ(e;P31URmE!%+gHJdr z9H@=%A*)d*ta-G)H1LMapk!#uMg<;)`C5(bB3vJEDLM4g<;%^7a}7Nrdjh62*RAX~ z&UHqpPJO6Hm|3gs>>3D)ok%=k*$Dm;@rG=)!W5C12K1-aD6&ALXF6DMl=tt6+m@oM zH<-y85#|;9W){ttSyyiCeJj4s2{t4hW?D=dau{hLXVjTqXP+rk|rGUTLO$Gg; zd_XXi)7j*8M)quH4y|Ru?#jGIv)ZoX=jIj$KR84e)-($kJdsWNjoSdk^1$5 zf1?fYL-ZE@P2xSO}b=<-oy`~C!EYn{@xwR<5RIA zNPYAtrZ7>_Zgz2I!sg&93>Pf}f)=I{*=w%51c)^hgB@j`g(ETWH0ElFX<*7de6CqT zwNpCY5Pk@!)=9HpE!_e(oCaF2!+`59$djfBBHpPrdV3{lJ=;JZv#8saWIZ2BtwbmC zaY4&gz@$X}#l~SE?ME81#}R^k;_`WX;9L4&+i31_9D(qekY{ynf*(L9iI7{j zzD$0u3(+u|a971g7{UUO2V~HRYM}p(osv^11ntjHh;>H$9TA9*8}1Y@r`Aulix&$= zJ1N(HprON?7nG?#1Bd!42O<{xO04jPg3;fxa&AQx=nyB^2~Z7B(kcVwSg2VYhQgxf zg;24pv8i&)@A&d~OnyLmDh@o^jjnwKOB4ukF+A%i264Q!EFXiU*b-i}38iD#ecGF8 zy*^5Y4ezLZlV|8wEcyGTYHSA$gO~k#WPtoX&~0w1SKV*?b$Vw&c}~Zo!QxoS{V2!K z*G~||T?AlFz1*N+>yVJRH!&0o+wj=w{n0k(iJ}ycSXH13L*`4ZxaVwBo?+37@S}YJ1&8zgr$%EQ$rIjDOQO4OcX@U)f5QghWKw~Ao zp+sEcGzE-zNa8+51hp0f;5G2?jaV#7wR8m~!Ytq`eck!B~ne=_hls_O3^u`f%LPe9|5*t_o}zESkY!b4POD^Zc~>Ey{3lhxC&#YAq)5xxQ&P2#v?=>4cDxx+p0SJ6d^Tq3F1l)paWl%-mbYTD^_T05 zfkuqS$;aceH+_pPT6=eh08N9;uNcbhMa7~;4bRTy$k*K>Sd6K=M=+!O{KID?Qrroq zQ?Va}%H1yQ30Kp*EV)eK{(Z(D$QH=U=m5pkE4=EnzDGu)jn=ohFs_?Y$sE*4J9QLBCax|IeK3XFh``L#&2k|%Qx%WFUl zl|~}N2`iM-+7uo3rg(_DaaMqwGF~Z@ljq8VpGAvR>&;*^{4EjkT&DZw(-INvX|^f^HafGLz7orImxy@gy{ zjGJlWM;CZ!0>H-+(}fG55_3MfvW~DZ6T~TgIgmq;flb>^n8>NCDe(5$eN8nM(I#Uo5$$`0KW7qh$D^ z%NW576PFz!3_>tb6`w)%MQ^hAM)H1HCc8JVPdPAbow3;A*SvuW3DDQYePpuZmgo`d zHPW@1Nc;#;!&cvA%TVU~?co3HAiSTijzH15iS7tL8J`1rr48bz>v>TjCpImYH{m?! z{ml5_@WL#$t_IVes+CuSOxUq5fq?(;X`vZcl>yz~XUZMxx*qm9U7me7+17r*gWdf6 znGLX2fD1(-^b5Ac%($@b@odsL9RfqzmQo6Yr&_itmAoED`)s(gvWPlJhU3h_!h&tL zwE&ZGo639L`thzBwqNty{cc{Wd2}=+r%Rl2*P>Au+6`}H?>@Ps@vtuYmUv(})6c{~ z0HO5C6C%Eq$)n;7%K#Sa6Qlh-*enoqKyE%PuKu#4$!LKS!{({$h zV_u`7;L$`(?kj}kZtvGHKTY;fD@sLrZ<21~`OpaKWVfTh(aXPrfw@SRk*!7j^ZET} ztR8e_TVB8Vq%(O}ugD2#0d)n{BNb_PZ>nnNlRbV6Ivt~lK69q=lrA-NT6I&bRqv{q zeXy!5iH#P3%0{8zO+lxn?!A#90zWsQ+41JxFqn(TD$y$qV18FsMxNV6qzNq{jdoo6#Kl-pIX0c-P`HuqW2@dMTl$z z8ls@cx{Xo8{VL8n@m%K5p3wV4a_BtQXc@D~7i&u0aMVGU%d5%YLE||zxgYuu&c#Rb z*l?#R!zVJP+G8W)bS&MAreqT_tNh1U;u5ify~!Y;BAk}xDVSH6nNNRY;cf8@UB%S_ z>ikbn+`^n@C1191a-vr(jNrv$HT1R)WN7s+HEkbrDN=Gim9cExb)b{xqNcRu|M=`T z%9mT+(n3w~L+=EHc&eOb7fYYY;xFw$U@jw`oDjoLsHcRVpe9#pP;PrrXD?z>EfEh& z{_vYb>DpP(hzOS7^j~VY-MuFhSqL1a-`N8 z@?UM3amc*W{#JEvL}fx-dgLWA4ufE+qI_8vNmK4wu-%tt`$4gGd@7eWhRM!0I|HCI zo#f~Ias6riQ@yf8AhT1iDlCHJ^uWg1yt1A5!ctFN!$}hD0ePHRAQl7IsN-{mt@qB{ zo43n$pI95{1+h|!gQa*s7Pu>tfGP@#@TJKJQzzx73sqjn>n!W7D{wj|QGlx?7wEfhUBff%I2P2%R6^Ni<;jaTlAeHAtN@?#nK>%kAb#>sSFs5p z(q!KrC8%x&u(J_Vzt+)I0}$+T13J3}ux0h0lF9USuKMBquH>=m&<~u>=ti9NBu9oN z7vv9;m=?p(1{?K4^w%eF1wtO_2gr_Io}RNB=L2N4xt}Kr_%ethe|f%2DzMl?MI|2`3n%6fsF%U$;$;dU@{k+R$zw0p53r#5uT#I=QCW-R{G@-jn z!-&DIb~s9|a524+sXaRBv^1ESiZ3@VRagATMXXo^wH;G_v~$<`SRB@#oT)998x_g? zt8&R`xD#WEp2L)HG8(kWEMCf+(i+krwVu*6=?5VP#@PWDs7C?=Gm$&Qa$v2T z?o&tx2deqrR1fwIRPWye#`DLXIb=TTVY-z!QKTg_>w^&wVcwYY7{8#mwMmnp^1>Ws zj#aDQ$?jTpCsXYhwJQ#oeQ`$1*lxq_Hi*S!(QRxFO8c0T-genm4eB{D^jBG7>`Z*ple~h`$iLLKt&?s z|06sQEJ(nKR!p{z4$;Mi%q3%dA|bCV_=OS8loCDOh?Q|X`?_}2o-uNBvZt6mM?;SX z5auYxJQyz*R&G>1*uN_j&q&?_4AvBg|2z8cZx5fCSLrcN5KZt-c`6T8=(-~c8J?Kf z`R%)dTbsBd{#9%|(q*R6ieK@viy`#nq;rq?{ajQc*DCp!IWI z4Tyi3`KUwtf(G9|@i`it`0=@`YkSDPxh0pL2?;yicQk4cRYaRi?>k!^B2uv50_o+W zy(pvJ0xqgwZ1WE36l4H&T5&m<3dQAi(^Jo#0t4NxS@c(lE1(t5PZlYBB2Kb!d_UXh5;v`g|m zFJ5x-oKrDY77J{vHucS-crv9$=ZyWtRhvT-%at733lbb1o5LLD@Y>*#;%F@uFC6G5 zpT<32wK;L=T#;VN_Oj-xOv!o_ZBVnVu5!Gmt|~;Nq#|?ZgB>!~U8{796Da_0@Df-A zO80I*1y5aodFZVk&~|P)KViRe(m^9D#!7;lN9w$JE`)z+Ua(_AL^f?Z#Ai1jzwG=O zP07Q&E))=NAXo|AzMRkTd@3uLME?h&_L!=M4c2<=6V;tP1s#8=pvE19Nf~+r@R-$% zW|=5)2p27A2BGA9WlP`wcu>z6K8V}M&dAJ8_V^HDCD5i#_qv&tP2BdhFU{Noyn@n!e9JcDKad_#YPHOS`L8fG2a(gDdD4-PG~|iC?HBT39rZ! zP0&g6pDE4YJw8l#8-y{ICghYv!e=N`Ol&8BvAlLwReFg8QRnJE!m4;7Ju9xN7Fq^9 zJrPyxSozJVut6W3%gm5U0){wvLKi%ZOC5_@TAMB_gUlXY@4xUw7~Z-7%$Sjr#;l=o zIC>*MXDy{z{VmLwrh%6W}X4IyMsevUgIlS@I%Vdo8UuSO(elmD2_enkMopOz1 zt+{(Ho;J&AcRnlq2iX~NWj?@%xrLhS^#8~+tsMlQyq0EL@^yWwnI%TtmMr|FU{@V{ zH3E}5t1&xY50-;XL=;JqTS`GR*4{z(XiQ{VjkQFg2zl)viY^)fRRS-{9IKhT0lT(L zmC_qtvWOKBw>n!7zZ_S~V`gL4Ou(!=-Nd-MV#`qw2viMvq}_(joac1fS2uA&-27Pf#p zm>`D#E1pOXOM1OJPv`#PgFyNPYWg`HS*#!BJ5Mc+qL(De-3tRpUy`t>H%9`Z{7;2x z9RHGgmBo(ArFAH0;vWkR0* zbF+yUJo4d_%MljA&*;uC7dVRjCIS!}QRV?O#dzbAW8rrM+xHVV6MN+l65n6EVCK8D z$B>Iwf{OGS`PTQn72`MaD3;*7KjM~R5Js8X4r0}#@E@bzZ;fHsp#8D|qIJn3(hdEYa&isu`j z0a?tPnnB*N+ca*2Y;;=k6)|7OknXVv%sF2qP( z_M06dMoXVg;GgHw!O?sF8T3Kkdm9mF$iqvQJyYK9@93g(9orB7k=ri`#qxtH@ zt*m9JJSk}xE+X4`gTk0tV;r5rZb_qfNF!Fh(b~_S?AF@}OcoUZN_#cwU%s(T#kv{3 zgEq;=v-1aZGrYZkQ#aeYR_}TC?M0ka;9ETxjpq|I;;dPjE#_i@=D)t5^O`i3?T+IB znb-O6BXOf;C4uBU(8qs^0SPoC^T(<#v~Jbdv`M>nMpwoPb;^eISvKLx0P@QkC8|sL zNqrD73_LA`pI@*W#zKLGPbWYp?Ld$i@mfz~N+8QFS1phHy1#M2?4(h%-6l!H5TiWV zuIS-Kou#5;Z^vHX`rqr;fFS4Uxq3vhcoW?+cuE!zWm?Z@{!DwURve9p8(}-jxOBfE z5kqq31gkQ2VWdIScK4G*II_A3*FeYm4g6siVTPJQtT!afRax!nqpC$W4+Yd(q-7k< zwj|x}!o>ohmoh&;9dtx7a!HJYVnGzmE1h5ah}n0NxWj`wYRTeA>`c`Q7SNN58w2=~ zWqI&vf9*r-+-128?WX~wu0V6EnU?Z>zA%iI*9{8uwiKe_RTg@`ot;$HybwTrka_=C z%Ez4Osf~EtO3en`=@%w@6aXMlmM$JCz8?~H7a?R{@rf6J>(CgXjMn&f@?M1tm8<56 zC@4)=FJ$fbMRE?lUmrvvD3&is~DhilY@wQp|3ok2_Zj>X;GgP#>n zrAs&2XI?4%M|9>bCXAs9*xQ;T7fBTp)blyD>(61MdMVM6I>7oq7j|_RbUoK~_!*ZW zcKvH6jF_4E(isGiSQS6JRGt@3zYl)3x=Jw6!a~7xaBl?7ZG}(aBnp%LdY_60ViWwq^bis`K^KWS$+*v&&YI=6`^Tx+JN8Lu|I_`{Y5eM4l#P4|Q&5@c zz3d9x>_XU26IC!RfSwAeURf)@C5Lv3(<7dzYb@dDKhi;?ZCowlP2nbz$Cct`IT$fSVXVhPfGaqv0;7n|?&s&Uc-?POPAPh#NSW%vz= zr=OSH9qvHh5bM8vBfB;9aQUcl0*8P5v!roEeCNy6mjM_Ef-j=mgn*}*Q_S3>fhha) z%RBp7F(oDJYpqOI_Op6Za+_8XU_gr4FqC~JNH2fR@`6rUcbgtn>}QCAD8c}#m9K9( zH~l}97sUM72z2_>*GwAYYM)I%zH^=|~@caQB z4b{DjwjdTFA@|%!2Gq#TI2l$swrM+0K`Pb5KFx~E{6P3t$z|0hx)N&p1J}i~J2+CN z3KrHrycg3aEqE&V!ukjx{t62OLW;){NRSQ$)#qH;vPfs|wB`}hc*+d&w z(8Y#PAt}=LraF%(pHsM*ldNmh>0B_zgJif{K88o>O}+g297pC2vV`RKtWx7I<9taI z5oj}+I)N!gSOfYA`lCB2;51%_ACWD4G8*Z+N}OFJ#E6h=L!!bRBj5WSLI+rYDqnei zxPS;TOcVXCH+`sVNt+(ZOB|&ig$ITA-2_I`Yx~p8NUqmHl$ng z<#=4n5OI_IM0#<0*g-PuSE*e@nC;!t$+8CnygL=2jQr4~!uq?+PpLUze?&B#s3nma zeO22Ew}i1SpjnJZ!`@4y>pa}?6HXzdEPK$0;JD=&;6?j5I#Vp4#& z$mhzM3jjhNO<-m?fz#C4GLu8rQDgX>BT~|2^tJFGNu&~t2N(b59<1W<=Si+(P2B-{S#}eftxEQ z&oG2!lvz#e@!QtX!@hIhqw$`t6<=K0+#glk1R7;B1>0b>Y+%iFk4x#l7(=tHH(YHb zYdNni1q#%>)5Z^qaPb@HvFkUl>gH$=nAe4!-$9Y@!t|mFc1U?J!U?Gy^5?$sFUjmB z!~8hf#QS8$h0SzMg~4grW2k{n%s&p3iv0z0`45Z@Si^Ne9fI4NHuPr;ER^JR7>S(H zYXApOC43^fsKzWTaF7({rxC8VNc)`;FF`Und=YDhT(Vls&nuwdyZCgF{YCzBP8ICe zT>c|T)u=go7N@hTtLw{vg)^ApvL&0rJkhP_E3xTV?2ezUqde=%<*0;}h*v7U6!Smh zJ#gprYgjKT(9K!0B$5>BKFQu3yXGdw^72JuG{RUx3EX4&UAd|__wrV@b4;#pvMTP>xk56 zR88Wf6Z3l)EYnoM?-f3H@&$5}e)T3JeZ{*9_DrR$r-KUj9|5#vO*nClklj~&H*{wC zqDi|!BD0|fNtQg80}dG1UY1RGDaYe~D0g=!#CPZkMu6*H<>LQV z7?lfq#^yOEZ2SAV%@XFg*}5YAy>67eSy>){XI*8x!@|t&PM2TaYp)M1i(%Od1YSg- zKhIcL1&E2I?))yA4~YF-D`~HYeh+!$8WfVFMrBUy*GKiiUSi>F0kzNFbwL1Dxji+C zib-^nR+BiVz5Gls2ihtXa31^{!M^pgXTVe3ityOnO~|uGs_={&_XXzvDyx5Dco5XO+GC7 zkWT}XcpGw6Hj}oxO2(W7o!j?FwN&;&0srW_UL!lN13ejM zyD1PcWo#(-nE*(8-6om*{ZEAaDa`->rTGO7Re!{&5qQ&+T_-5+otZ--5l*5hYEX%Hyx8w^yJq>akUlMR76A;5FR%5euKhT2{;(^#-U?1G@e=I_4@J zi~w7jc+A|nK*wDij9Sd(R#*C5+)w`od$gqMsk23VqG~^cW&#gxhluz>R9h`PvFYKA z^%F#L-xk+dda!6K9EwsZ5uak!JeRTEsV^;htr3PRO8|?WL9hG|3AUtB-3VDB>dpd^ zjCpd%Whbfbr-gk~n-H=1^=B73qXxLG+M&*jA6$GEv$|kGk}xbSIqrdx^BrpL6Lyz? zrcq6G`KUoT53NYMKapau>G^X%tn3qbm+mk)wK`;vdxIC@s4T-C=03hJywN32pAps`69mul5Uc7rI`nxhivqtJ3zsN4_ylAB^;`S;Wj@8a=ILIda^V>NcDR!%4M`j$~fkf#&VaxHR@Q%poeKW<*4M zOt#;SrrlVrB+tD#Gud!pSQt`RnrHW!OIKN79 z==Bzx${ofCmH91%Yfh~uwM;7P(boK<%}d>)Wq50E3#(D8DTGCxi<7QIS+b({dEW&m zq$D(>1>biB8Yik&;YW$P4TZ88dXZjP+~?@&YbZ~CHZ}YYzqv3IZawBO1ar`+Hdk^Uw9SF*cfqdwG*(&`B^r-*}Hwh<>Ya?CJY>HG4!dyr~JSITIa^_cHOR_u|q*AFB^HJYT<6zNsmv2IsqGR9K14o^_YQUcZL^Q@TnH%OJn!r=#&^0<0|nLfrAFa4MYRmZA_e5 zCbqpl4O#(|ZKJ(2O+FCKzF}gNwzx-tdQ3Luj4aCE)y+dn&__%?FBX%8r+vrg@7f5d zD45fH@fpCt>G z;il$GMb4?Q5=sb3X$*lZtqRlry^ulePh7@nX7-lrtS6)bMT~^)qLTQu}D_Z~421 z;(y+mKo95WNsrUxQhbg>c2e9gXhynwC{ADdUYB%!;5t+!_|Fdx3xM^k(L#-5d?!67 z4E~1g@p>tSZ{ z5EwSD;=5b_FC=9={P#@il`r~Bc@Gn_PNhIQV)}DTTYb7443k3vCtIc(Ku5b4;j1ceg930+Ap8VhmQBH@m3v^A z?Ev3NeZ+LZ$or4-Dl8eI!hdD_bO{3Y@QSZCI zui=NOD5sIsTut3v=?8>zg7-0dYSLQD{Yc+kZI|4|$ipq;gUR_Y8BKgJ?DsJO`-O$>xy9Rr*Ub@&H4Ti%8diK=*G`&LP@@dw6{ODbb z$urIeIbWvPb?=%k?5PdYE2Ti3e=j$!@~fB(`Um9Rw@nkcvl`{^X{7MqUkD60CZK(O z#P=o$ahsu-%|~|zKPRL*r(*F~<1`g=lXrn9)*lky*?J}YXV8)*c<%D@_2A}lJ)Ql4 zqk(g5oNCs*#i(j?*S*AtBh|-8nGBQkXM>OIu==56Z<9qb$FUhK2@di$#?$0(G#IJsRgX@zf z=Yp-t!7+bBK|LFCB|#qk{jXFnGQfU!G-DWWyV2P>wRof{I8{U`zZn~>GmfYnvzDDQ z5VNS@k1SXcot)jxJU-T|8tpEiZg)b%K()6qS_LNO-!yu8%aw3!s^>`z$q3h3FS8~C zb;H>KY2Sr}iqnanN_~x+?BQW|-=EF3>%ZISIyyy+;>O{(hR;#zPJLc|wH6Oi3EBL) zxen8~k^Zwo>t1To5hx|F9Wt`8HN{4a-gqz8GTmWdReUyehL6LngUnM*Eor@}zha47 z$FUJ-xqorrR9>n3kn?Y&3ptU8@m{6-8HG0b38zp*1qaXdcCmDLW63m4l+;w~$f-3gbq~6hA|7$uY*bwSc$1JLEE)+T~q8 zVX0CphBIP-KIdf#)RpPkkRpk{Aq96dkK0xKEG7@DRZq`15`OeAH#ELpOS7>{ zwwvzg9h3#EM6R<{Vt6^q=9&}UmbB# z$lc#ja0IW@796mX7O{e%6-W`3^&vMeS`NQ*S$@8^s`6O3QB2H3~QCB`udUIB^)AE(UCgpe9sTQFH zU#~#w`}9*tTo#$oU>}&se!JWR1Cpi7S+`%zpEP?wBQfb$==~2psZ}&~S(~5?C&?5} zfNQWj>oz99R{v{zi*Rb`Ta$sKbCenC;5VJ@6YTx(OAaowJ3C)ig z35XMLo?yUN$0y7q9b)|!ZbPPO&NgI};*16@lsar+$Luhx4Nb>#dkg;I+l=g$0&~tk zYhtbj(Jn;Gkq-j6v?2hnsZlP$bg2%FNo4QlIw6LWq5-)Bj9}n3to#Htoi%-Bp^(og zSMgnc7pb$1|JlzCQeB+Yl~2iS)Jgimyl83#4Id4G5dogW;6s(f*fxZivwsJt?L%Tv z3hmqFW#Gwrh19Hz67RYa7r9at{mROZzD_1aPTYf?;%i zNiJht_(Dh;7E#7uEq?_EUWeohbhIS$?tGe|V^X+z?6*G)jmpYlFZ)eC2KmjP!2P`+ z6h_?n4|+W9X4JD$W0>u1QD}dFHqyE5351GR^3Nc0zN8EP#V6+=Kd)HAWyI_S3s2VqKL;Je)!PV3M{l!6S zt5^qqR*+cWP6G5zJxx9V#sojoAQVAFEa)>^{f>uxVHHtGp~+z$D3GBb^sT5JAYjw) z+L8!%+FF|<3t>`FZf1~&@g0i+djA{Ea#$wApc~2iky(U=WB@gsfzz4(MEOAs_R9RV z(awIk!mEJl%{-h1h$Hju0BFi*lqOtN;nph2%%iOFi=3}$?j&vlsgRs}FhpYGb?Fg*{Sm`ev-Qub#t@d6{SDi$u zMTBY##^&~~!~SQ~TdceEMDZq2TjbMUhL-jKCfQ11!grE0WJk9%LZp*T#s}6QYg5~H z;kCteH)(m*6$+STW6frF^2uQ4g`n&8Ddck*hVkiLjiIqtT<`vkWj1@nG0@E>x|hzb z;s$?@mpJbh0W;fePe1LPnr=&TA{?OUq$MDPlSRz$B6WKP~ zy!zF5JhZ7#-L4I2T{En@`H?@Er}z^x_^9aki4sZM-|DSc5v8QAJ7l#EcbjA;(AS;S zMEofxk`k=;j~8nRCjk&#kBzJDr854K8ecg3{&MHM7_RTx=%-tkoTqRd(4 z6!=Z2>Hl`xH53wivs-tsWjyy-ash0pu?C1Pz^L?t1+Ml)dIi(ln1h;81B3@puU0sV zxYIvu$!eIU`ZS21U zSOfqioBTIO%+OY*$tZ?CG)K*P3;`yo|EkvtguZtl8J6e|$uJONE18rR;bgTmR69B* z!w&hRf7+GphmsdVaq?*+yOd4rO`V(lX);C&y5S=Yr=-|!8l-<>DZX$JZ>icRPyJc1 zCYuj3Jw_zHo7Tj`>*UrG@~xCxNHjvDEwbZz`psg#Q-d9ooU@wl&Ls6K>@2?-oYyCi zH7GYDi3oH+gy~XdTd(kUPblLsi*!uUz6C@9gQ+*#WInH#k)%T>eH|V^bwr2i)kyh* zk?R=YY`WlSBYP%3iG|lDQ{++SL^uZeer>>CIJGE^$lu-8zrf7_Wpa!cZU-pp@uR^H=jW@J3oFwt(o!5Z0X3cN9MN*q2gQ_! zG>JMJM{kV{QVVt=#w+-?S8+s zak-;HsaCPFwg`g0Dh4+;8e6AJqS7ahN<8IIQb7`Ih>6_4lqqF6l|9|OX~vMhG*~iE zY5$xocz)aU`~0T;$>84a!BB?0lMloiMe->a*tkHXdu+39NOXCK15kyVR5>v%;6|_j zwp_t)o7nc0mky4hok@G*ZHhCs(=YVYovoD^v{)g6_4U8iIt6rWl#q}c`I$jrzq%Nw zjTt3(KeMcBbJ)Rnq z@n|RqBG*C=k78#@7Jr0qlLb3U2ZOPV8igYB)f>6YM)3@Np6?sBBWq%^q;}G(BZN22 zlpvR3AE|d_Pel7Qg+&C=`+#ZELvaOZHRc2{B;pJ%%{Y0KP*wmh_!p4SQ9xMLvy(Af zwU-Bj#Z^d@(M8y#wARsWZoB2XNJnAVr;%_vDh%iDxQi{6gz7Q#C z{X_CQphbO}^}XT1w8%*YQQ?`cNok%g=DKe!8Y)zpN?xp~)535>Yxs5dHX&x+1kO9Z zyrGZcTQ1p1h{V`+>BF*-jT|c6Rj58RHg1J8W5+kXutx@R;aahiM?rk~QY_eN;XA!r z%_$RI%U$BN7#2akpmK zw~g9W69Q%i?r%skFD)hr<9;Nak=6jJzb%kEsQ2<#DG;Tbv?d&#D=Ed|Y;J4cbb1S{x2}zwdZU#H&u@M1^l{}gtvFN- zGMX>=F7a^u!l0UaK?aJQ^nfRZWI8;3O zYCQTU%CM}jt?_MBXKvvM5TzL6A=?GGTa92KEytIezae!#Gj{Pi{5kgdZ_iG#T}gzB zcw=9IwDELMM;Qa+To1(B>Y7`8v7f?4eU$`w%KByahz;pZbqQagNi`sFHcSj-2w8Yf zVygzE7=#Myzgf{13gSQIy`6j63wk#3QYrkOK72OTB%x;T;#EMAcnZ1xyg&{huJ#Ay ztf_16Mf!>+zz2SESueejfj;Kjg4=!lJ%5TmRgfzT&hR?V z|9@TphhCv`+c?nE$7JjZ&D!A%S)l&T-mYEnk58x8P{NNz_B(}2Z1gc#-k3)`)%stKW+f*gse~aN$e-8Yg^_`L_$YX+!EJYzw;`PYm zt0ljJ076oB0M5Sv8)#CE9%QCq1*&Xj?9e~LEfOiKXhf0p1{95{B2jNWqk0FLU?KKJ zkbrLOv~7;si#I&*7+4xJ@A(?_*g2Up#lKUpf{kUOYnatt(9TzvZu&gGxIswyjM}BD zO8E2{|NcX%GP32~iNmw}tv7JE`n{XgC=yt7)%Fj@lCFJffhXgIAlIi2aTLkvZIS#O zLn0B$4oNIz;FvZMa`2Ehb;6uwr(Qr;uBWp5ynJvkIBCuHPSs_Fz?M_~x0wFG>-1^4 ze&<^D83_JH+pInEXpMzHX-rWPpNL9h_NY2%!m$226CcO!u2 zM?8arP_#%$c8MUl1`Yv9omXtnui0G)7#`|m8h_{mV@$-_Dz#&LU35|XKK|@~?;axm zn@czF$6PcGyh7D90U6B?&%vzT#jYZslyk6QWa+D01D|N`0P3 zMt-+f*$oP_hoo?*HtJu(QA}M*nNmSa^V--t2R7S;0raDh#%@q#ta+Q?FM7*LJT)23 znp{S!t;ATsR@!JDm*oviv4o@9)7!Z^$W#q^)w*s@>CL9*P1qr7dI&!w2oWejS{GtF zXS!nJzj>$s%_0AwIYn!QK6b5)S& zjFaSVV-7DNr+$f1Gg!fEA=G60ToDwxUD$K_5Kq%T!Ij(hT&UleAu-zy6DG;y-1e`q z2R0q<@j;i5^p!`rOa{lE%ly{^^SF$)9%fs43Ewx_*vnD)s~47Ms5oX1YUHw6(FzyI z0Y1RnWBzhC=(-vGefze`vhbv7L@UagL0DXDvr9@!$2;Jq|3ggYYDQzR)c`8_3}O)n zmEnDCH1VNqtY5wO#?CroreV-BXFYf@bz%bT9=m@N`VtI)03^~jf}f&Shup=1{%9h( zHQRA6pkO}k|3 z+&D(^%o|iiJlqnbEfP{BsdH47{SR(@xWIzW3GbD{K!HYsslE0Z{bj*=b~*x33fpzg zL4oD+CSA;M>oWRM^=1D7N*Dq4P1!ahrN-*K43;`wW{*$%Mjc9EHvgpc^FS;Wlu=Sd zs7C%+We4w^#SK=rHqU4E?<(-F+pF8=y`3{mr|A&NI=~U+CAKv2fDqQ>MB5|W%|5X9 zQb@fmjB0&&HXmMd-dx`n=8yl3zz}dEx;(EmdB%yoF@ItwICBfOyly>#bz8s4RlOcx zKFi%el?84FQ`N8ZGLp!?`Nv&_93ls6sGzM=p?IFJxw3F_P0*Z zml|3{xUF^zg8Y`MZ++12-cMxV{}V4pwwYuM%eh6wf_8iZtjjk{vEbTDq>|%l8W))o z`7Jb2`Xob@^Cgj<5;IP^q-2P%(XCxw z?QH#Kz(LM9wV!Y1B}GR`vCy%?2>yOuRWLZPUJ=KaAnkYX6e1N!mjOzLCXt|L-mxjZ z6|}gZYP(S7NtqYD#-wst__m5oDvcZpFz%}Suc~ZZ8XfSC_I-8idk*76$rT#ksQ#p* z>IM=CK-8=+76ejgrfjIr@H6fN>y^*&>mSSyz7YCZ+KsZAx{wqOx`%!+b2s1!gubt% zHdd~m6_h9ZZO%aq3H_ZzG6eM%Fj4~$%ow;c>1o>}3h0VS^#JnzXh*mG7@4CUn8{~l z7_9z1p~!(z0#FNuUuDqRoIWikxKgRZfgzSTIUwu6@Oic9?9kaVE1QxZjS?v-98Q z*0JmZA$=Z>{h!NTF&mOGn$bp!>XbFZ&H0MDiZd?YxB#6QGJ*GMk|~t0k!Z5@ixG+H z*0)=BY&y|yMqX*3Z3xP`T@wZQ$ayG}^Smp&i{wzGM)Y@nPX3t&JT#y60i@X^vcBbe zU`5blXG92?COe24Mx%YzjoxS=S$2^Wl#z+nt>1z9*aSD1a|?1@vUQ0^>wW+!Fb`K< zpaEw480TP?V&^}f&{lC`L=7q2U2{9`W1u)OLfV-IJV~d|U-5$ZG0co2OSxH}s-4GO zIh3FDW`e^m07)%S?82x<&WLM&K=$!!&!IcBK}?7LIYd}Y_F2Wqa&k%aBqc#l`vGw3EcwyLnVy>papOC=#k! zEJ*Lw4_-I+Wbf1+Mb*-7H27X|D^=o7;a()Mo!x>slkf|<^?k3*$XMEbrQyZWH{ZfB zq3z9y!Z8gH?-_}HB{q1+5G z@qQ^XfqE`eZB2(4P`}+dy>S6xAO9%-%1(Lo4idV&;6HvFZO|5!%Z=9pG56tg!oJ>JN&xv`TG|qINaNDVIMtMwS?jLCR&hfWQTr<(0@5M#sg2CkL3$I zvdW@mwr_YUiFPrdS7D|QcsnP69OMZ8$Dc;j#~s`StD*d((3hd8>2$So>c5D4KV*?- zr-sSUb;ne%TqDQtj&=zjWZ${i>J!?iW1PdCA&I|6&1>(QbE1y#`Tojro#EtHwxdSx zqP?Q+DD=Tu!tqf(vZWLP4t0kp$!K-wP+@_^;q5-}1>ZXNF*@SLZ9;=8em53ggK@bg zEDCGz`=_=j_8I?r?|L>Q={UnIGGS?4wT_&bW-^r%I$S0;izqzVN6Jn5gX`Oxgu|cl zM&mqU1s>Uxidy`y_ezI6@J6UHgS7_6Chr&jmsDq)AQUA&F@d<7Q+5c`x zB??2eIT0n|{)Tp{eLCL6l@#O!b#&@7^>xU!5-YL0W0UCmi~dMb5hU)F$m}F}T4Y~rE++8y?q6^0KnFOoAXSR_PL#f}VE!gPC<475D1HeG71O=%u7}QtVgyZ=A#K zoj>QcF=BgJ#h7PF;82ZeuLxnFo;BF|ye$z~jZv>S{5MGh>pXW8BG-W;cuXMH7w|Q2 zm{3*(@MgEcDG%~ZV6OiwvsB5Pa#c7HAP$q64#}mKcK7~%U(-JzC=&n%C>zyH86sQB z=I$Eq4COZ9xC=x`9sWv+5QAXyO_0tONh%=5%iR8(l3{B%zq6=8oXv+Q zH_02R)>oo+eFxy`$9MUMBww$T4C5VjzT(GZ%`3w<^-mKu^<#24r>~i8-BzU99iK8_x`Ddi<)07^buU$6lT7_@7Rj3vt=hXHFZTQCc zjfn7r(=kbv0B(TOKRq8-92$YAXHdG5+!x)@~vr$d_->xDe?Zg!6_2yN$En&BWNaZ=?4l zVJ((qzTcf$@NHSE&y(DFSOCdl_)Pzi8Rv;V>E0rz56;EH8v|Wa)*QXC4mFh&k^~Jj=54ugJ@UE?ulXPP z&bE^bVbtu{J0iizjhj=Q%N|BM&X!qWpkVLK!R|-R5;!UnPIn)ofs2tthbQj3EC{QP zY0(4)jEqL?$Tc{e(gPvLS~XoRxzTI_GhXnCWAa1=NNnF%MpJ|qRe8W_Vr=eEC3QoW z-rm-Fxv*v~w6N>6Jja!uEbWeRZ7vm-J-2PQXHio}AF(`&<6|IYMXR*mY_XMHsKnhc zoc$%xD{a{>OrBr}eYUh$ggN_uF85P4cK~U$MPA#;6TMf6j^T?0S>zuVoFo+ExCpWc zRb03Q(oH-iZvVhx!h^2Y3kbf>n31HC6c!?|?N=(-pdr}EVoCa8wu(n!KATnjmjAt9u9cqb_v3 zjMbX$z-k=R)|9;q0O7lYKV5XF?t!M`pC<4TdCeG|x97(RD3S~fmi$)wXc>b7bGZlZ zg`)_~87HWYz*48v$w@sQnoMCn4o$^M3Oh7gYpM4u@3UHE%YgBKrkm!^(UuzV(xfZx zM)K0WFdad+<0T5C4eQYyEgnk&>Onz?I}K_`;J*=|n6>!BrQiA8h4uMbFU_uhPXCU2 z2ZK)24q?1JoW@N_V)gWm;OXeg=!;DI?IV`3@K`_^{ffo;+N%Q@c%AS6d{;VYo~?52 zy^494R}u25TfwbdwhUP9_IXuVkIKd%6E`*!ze>oZ4sd^S=r%@qByBGp;|o^#(=N08 zkC#MJ;G7}$98utmU7=-BsJ}DqiMdP@qE4VBcDZXeCe|_bFyLNQ>TR^JxyEixQTe1T zDyHQ?c{z(pRz3k&i5qI=c`LBo|)o zrAi?QO&$w5RF9j>5biLlQys#(V)$*DVEU~VV`ah0KC}R;WYgcH{x5_-O*A;WA4wU@ zVI^W@#s>ODcsg&RBpfGLp-kKCPcTZ{c@JWsNzZstC3>ETkGD%~0`GqCt{ai!{A%?? z2Gz~{VOc0y2lXN5nN&651RIcim~DYgcp}bX@oyE8-c&win;u{agGwxOVU$XF`li0W zfL=+9BSNzNGNVg3+&0c*M;9+ewQOcx*qlf1+KNWGtebEC%+|N)CTFwd%l)$@FUu`v zkAm@aSlz2$Yszf-naQUOK`%5N1e(~BG#sQcj5SJ@rP4E)(smMj`v|En>O>0nbIcEa zjpYSUh6!U;la%mmJefyjr8o#w5X_TdP!=~$#`|5dC(k)3N!s3R|6tS^Wz<{J{O#^} ztt-b8-yMHbRG28sTDYqbU7-}sCrM~fs}TLGAPV);F8@x!obhu%_NCzltZ%T4!9Zz5 zz}oP4-;=9I%tw;U%30J-rs}WTe+>5Z0KcuBt} zLt>MBR5)R9D@hepoOw=~c}(G&Sxe7u3=+ls7*O49$dOVA&KsNbEIV<$bXaht8z@a~ z9@Zx8HJ`ItOP@B_Pm$K*e5Zu82Bk0LNJ8NY{;$!5fm*3Cp^%?woPfgouSfXoivAAj z8D2yUP^YM?9cp_%)_=7|9p$Lb-Syu?B}mSa&ct$4)3Pa)!U!dueUd;M8~Y9 z=6U1;GkKMy0bLak;NfwnawAo4@38Wesh(m|Ia9|;s0cMiCSu{y!D5S(I6rp9BCLn+Zz6fsQDMhNQnwyh^+PS}8XB zBqx3~kDMNIEX87O-Q7Tb9~|&7nZ6sE(fZ#x0;4WxCoXSR(_1(vyl2pYfi1Sq&R~FU zao3|N7AX~~s7H3*@$!6Q>AE>E_nT#%ztLek>UakdRSJXoFSP<6GY2d#)bchFg`3r{ZMwIm(-qCLNU|{7sI6$*|gDX#ebk zPm9^>9n${fTRsFC$R*P?#@*n(V?&~vM0Bl8?fy!e~JF>h&NL#@;=jpmJa&8(6l*>U_znzgPvZ3zQ$ZPpsQ z*$KI}RGsomw(VK;on2hv=q-6q=XYmCCL@R1S zadL7(&uaI-kTzZt+gTK?d}rIR=BsT>XDajqEk2I_X0fkswEeHWsH8(j3v*h4t7}mZ zbt2g}894>4)y{DXzcyKcc3WJlkGG5Kegu~EvuhzO<89wY0RW}X)yUOk*`VfLYE%U% zc@xO5agtODEfmG75|VZoQWGuUH9`4(+H_k1NBgPu%ilB2nKw%W3CoInsaXd(9pRsg zVJKf<>8YPjx>xkvwWdxm&Ou zW`QiOey8@+K53<&;L*J|9$AqWv*iRZ-Xt8Dbob$*^M6m5M*j*;hXPe-5=kpmp%iDa#uK?WqY*yOy^e8RRRYxa95t}3`j`&DXm%w1!{%Nk0!I$G=uz`I? z$9Gh}Z^T5&Vu}!0f6bmw1^IrvnvXoD@_4JT$T!K)TlDq)oE2Q)9)6UKF_jy5#?|0r zw9DIRK~XQIDhxQ}z+p$29r_)2#(2CY+?+3;?WCKNp_L~6h;m?)8Rx`T-@u#y+H`=z zf6{3to2X|$CP>{K<{oA&nU7+F!@v-$%DekBI#Sw==js&z;6`Nc0~Y;$A*gd+;>}zd z8DDQR_28h-DLNZj*9L0Iu#T}OgneZ=`Z7n@ZBH9cK%&UBGD6YZE>!f%C8y`ld#QUeBk5Ln+eV^&%$JmmgzO(10ZAbr30j zFt?80`wM?HMI11M?rC-6`@3Rb*6w3hOnKp?r26%;1#v%PjLjEfA&uMLxdO0vFk~Xq zKRA_JT1)2To1rDj&>vN)Y-H+qOt@x>SlQ0Qrr$+_x6Sb?Kdn6h#n7;DdL$Fp0ACYr z#TMDOW#YySNr}ZnT!Kydnv9kRIysZ}p;D3-$b7oIlG68!@|Go0jR?FX4C zd9^2fB<`Dgbr$4t?T5J#1927&dI$WdwO-(fECW0LN%!|?-srEvRr)Ps4|Af3 zyLz^5ys<^smX^fAFmrf{JW;fY<|vRfb04Ce;p`%b)Q@5$O8(#;vsN2&Y^@%a*Un{8 zd4TCSI#oivKy{g}#|<;jfM%x!Bo!Tm=$6D}^w*U&|bZbYOTZ;`2C20}9t z!f!S-A{qi!qmh(h$h$Xpdy!m~YnwwT0d5SR_g)mBUr|7aW5LlGgBZ61w~BPwaVM~A9BZpEV{VeQJ)qo zHB3n55^slA^=gh22`uGYb_4u)-K~VC7nlYYtq)@||93axxv^vRc)#+(QCqZ|bNl9( zEjHX(;&%MjwDaN>R&f&)w6}Ab`dl7X_8b|Mq4d%enTys7`kg}KnE9wac1r!m%_GvK1z3-1>f4`@c$@pw86`oKd_eJ-I6BVw=TTbZHBY7KSp(fCc6}s!wcsBxT`QetohA>gB$qXro7l} zUo6_#dg^-prsRW76U}dSmA2{BSdvOW01%{ptSX_!AqBpD*MO3%l;7PdejRwu6 z!%s`{14viJcKh#N$SD8M3$SrFxZ^MtnW&(J!jmpu(!=uQ(jTBEc0$1?6$ZdLW$IEO z{YOgfxTr`yXf)_6ypuPj_O=-+aN-6MLEy%G!nWiuD1$Mv-_OHo>QFa5;Je z0S_4>jc~56qDr0GVKJnC;5VTL5W_JbeZEzXyEKUS0Uf|_d88hML_hxZ*u1)Um<&i>SPsAWI{tnUn6wyn5=j-c+%j}xNz3qma zI_FmHDN)BS^6|av>MH4w`I)EV{=PHIB~ne3D*jT>+Ii3O`vUxp&P2scLfwPm4{~)H zJsG{6FwTF@s3o}}e~Ax?R>n@y#8kfW#Y>H^g>N6G2OcA%Yk3qi4mQNtQ5tW;Q5)I6 zDQVxU)QCm4jEybU4fF2JDA#^js7<p!we;=a>8abEiONPAg{R0HoSh9mtAx> zmQ@EBc{DsMmJzq2Ejo{;N3>@^#i%W-?j0F)BmIR0T{p){A1o``c5w;1A3V|W7D6&K zlU6#B8qWZS*;*5OTqTbnfDQH>?Bs9O7`1L>=20lN9N)AI4Uy9YxSfqQ9MtP=aKmWc zknb-8WL4WiPNGBrzHTJvm8SLFyr;42A!h-1!;k1ip~UBKAZ;F*hset!s{U(Wuv^&9S z*fta!b-;7p?I^TAA~$MA6Q`WYZo?AkX*fkv@HPAoJBW~vR3tT}tT%Zq(YU1hJ=+#( z>j9eC8;((Fk`Eo?xtG1kX0mnf`oe+r4b3^^8;JQSUGUW_IIjhZuibCJiuOiyIj6m& zTV{?2_~6AMA89T2D9tGY-o8)oL<Js-v87A*zxq_=LB&;8H; zuylKd%73SpqD=pPlgh#f(AiwlnK&l0rnEa|YH*qL0}j*7UJC7Zv>5}A*&g^xodcb0k{z9$ z;yk*+4$|lr+S3n`H5(JTOc8e?RSv?&CLNyeL7{qaQ`Ct!?)FvnE_l6>n!_f$9sGRq z!E*@|*iN<3v}gI3Wr^<_g+%b(0!f*%F!E_U$Tp*LG!XCs3j3nZ7b=z1WhfVoP0YzE z=dhCeA^N`ySS7A(FY^MTh!wX-({62L%AV&E3I|nVv#Wx`-08NE0H^%3r6%j%31F0TMWWept3MMml|F{YUUs%`0y z0A>Y7JoP}?xVV+nt#12t6Ny9xER)7-+Zt5-!;2j*3+L>9KS1`cjHBRmSR_Rp)UWVl zOA!l-aTEsqNg5s_)@Iyncksjq;FU2NjHKDUQuEGUa9~UEkcDVflYJB$smif^y+F6W zOTOUp7)f!sE9%K0*%@(AiojZ2@vEc3W^<1Pso-8JypSAUxBZvEZ|<#ssmB!C^7C|h zjwjY5Za?Pegq412*0lU*rEK8@9w2mT$Dug<6Vf_yMnN&G-?i<>!C)$nsBoURt>&~v zE@z5hQW46+#Zx*P8VgHOm2!HVHBY1u&U#B_8Nu#?3(Lt*FJHgkR$}4$Kjq_&6YZpK zu5wl*U_MrLN8G2XNIcS=QZG2nv>daqk*C5pVt~`H{9&K%@8cYzD@h(v^fD-78^)tC zoK{C&{RSbVJvHpk<5Cm}o!K&O3HGK z)*;(ujOp_KXQpf|>!?8K;C~{TOIR`RysN%Bmpr<)yQ+bErQSZ)j3dMCLA}!Y*xtUK zA;;WgA6(P+g{=OAsIai;cdhJ+H?zfPyh!tdTbes!L=;C4zAw=iEEzPK)S4RWc}-Ub zDLlwFH74sPa;oxPfOrIRmh?`&!rb;iGq(s*d0PD6Fb3fTiSOO}+D@>l^a+9fr@5hZ z(j?~eNuScYGU6LZt|Thugcc>VGg!6?OO6Aa2MnW<^eI!sH#DOeStDn&G)@l3ir5uU zOp8>C<*&CDh4lv*7lAkRaByeiy8L%~+j}J6J3F~c*bj{g79Y2%Ic*!*IvD9ZrE?h@ z^#z@ZzQnOty>)fS?T_Bkam{46#M(Z1{y^Q%n|v_bP-H~E;?vIj736jO5j=MAe(Qc; zjy^X3KmEaF(@wuIzKP60*hA?XUV(ogQ7U%bV0Kw1<6SMae<$>{M@Y{9o=iyW`xjL< z{_OxK&NdZpV3nVn2)RN94m}aMIEKR*aFYK6uRu`0StTp|Q$jyD4hc%ZaIDvuwQP;y zDCD&+Z!>lvJbnJ9n4x|yTxmR84fAEPf%J(XR%MYz=<6QaB!z^!7jGMn031!9oK9A^ zTOOv2$0O=A?&*Dkfj+-U$aDuln!x;O>kuHsb7g7)It6#C}JNAJkd;X9g39?QeC_oW8FeRHXM;W#~3=Yu^YSbV~np%Tb?|5LU-%8F`z*@ zwAh>f2Kf0E^V2ZC0z>~QGxXma#t;AY-H#8i`K$jH1%^}lfX%^G;H=47!&{-7;dfI5MeUlR<>k=Ba7 z77ZH$lqiT%JXsWglR?W%2F*@yb|98(iK#^hn2x?5(qTQCooJ!s$>sG83p2QJFE)jI z{N5*W`t{$ItHpwCswh&>VhgrUrmtsM6`hjd0*fLLU@6+x(dz239nmGgTh%QAmTa>? zk2AHr4kw55I=LBK?7K>~C0MV$7DRhmTtw891Ut$F2y37~g?qLq7mF*Mhe+qEWg&|e zVL07_jf6rUMjy})MeDU~MOu`??S3PNT6`}xKlU^W379?xNqXi>cnW5?0RykQb zwv)&qT2jqGF3;b{;d|edSl1hj8(eFp>#))S@OGiAt-k}D^Tn&rrN|)eDEnoZSV_9b&nX~zPDU%t1ii%PV@A|Q%POU}yQ)vRdhPam#fU9MrbC_ye z8U$&mX(zQ7w5}{xYuz(r0?m+Fuzh#XpzCb8I=>`%h&}V@Y$AKcME65U5D+?*U8~oo zg?iCv1TkP9);BeQI_mxU2h>%}HmRtMOy%{rF&gK^8!ZdmGO5 zx^Kb5LreBes_WGi1W~h0_mu7OngH_P8jw%hsv)QW;BgZA^78dFo%5~6i0%_J7OTI1 z?Fd%#db8I33uoz?%v*qrwr@#aHC#6UZ;s|FwBj%3E8ZhE^K>tku5Z{D4Fe~b&Kw;a z=vsPY|3W(y?AQpvSCLb$B3%^&XjN5YoB`C>!gNZ1_cGl|tFM!;2BWmo_hxA0A>;V@ z^K+f=8_tVA0(&>1In;X}pXoJJ`gyS9nx|Q;X6Zq)|`&!;i89>Lc^Sl*8M!M zr2#Ol*M{d#jFw{L@GwVc+4|aCN(u{h23YN);g1 zD44=Me0KCmt}id|9e+7n7k0k?ABB zKMLhwZ!AHm*R*Wqi!Yx@5XG7wUQ27YVpMv+StqmUp^W2GnT${6gZF+#-h20bYIXyd z#OI7kpGA1Cn^nWE4xH+(p-OKy$ zK9)UQ+smsbx_)Eo#qQ6}*yg|7T*@Y!iydgr*Lj76SrFXcJnU_a9|@BF{vZ4i{|f^r z=#%2KdN+PH1KMAI@+W`tv%ZYo*p1!T4YJ1oj=U{bYnU`qgY+k0koJG22mf#W`iI%1 zKlJbY(1MR^`AI?2EX(ElpFR0oJKXQ`{BHcBjJKTw-qy&9YyeN7muZ`FyVYXZJrvSw z;5rTCCSw2;!8Gb*Br7fCLjo@b3#pF1Ydu@A!TQwb}+POTjp3yM_xBM7KOpSoZo8EhL(Mp%osIUc}-og7=d|Fje^F5k&ty~CS*{n zu_{(F4hP*#0DEk)M?1G2X#o_-2^gR+{#=X6deGLhV=|ina)9NALI{P8>v^)sHY}hB z%vGht@l3W_umiNk&yJ#r&K-)FluVMk0=Qzb_-wRzkK>3==+GF0&K%}y@8DSH1v-2w z|1I!)w%3nGClY#NvU1T19gX(1kP9W6&e+}#y-E~uaAODC5Ui1dQ6ODik?DrkNH$(- z!DQUI@0MBs0{}B^m?{Zf!^zlzrX|=W>5|OZzJptHB*zgCU{5W{>W#!F z9$kLRO-udSe4WbP{+ODUMYAEWv0g4Dm_X03lXo6|D03~A8!e#2y->DRBk|sW?2Tt~ zy|`pMFF<1e29P)yjb=LczFeMP5Tt?B0sv~rOH9VPwxQ1gc{H99NH{${lg)On*EHhu z>SX^+RytP}Y^L=(D=pf=Hf@bm{Ak2=N1J4-?^o-(6KDuLK0ndI4CWk+%wVJp9@zY5 zD^-$;9lC5ug;5k-sY{LBQsV<_ff(OzRuaWynSm7ua3!f|vQlXw52LNl1ke#s-x1JL z<7;q3KEdkfzU{$vxf`@H0d(Q81KO{xS<57x$p;_2Pd!+$(DF^Hv2(yZ1XiSHa;xbY zSn}Ruu$eshdy|8~bWZ1JkniZJhuc%aqar&W9ku{N zan$4o155X_FJ6$@=eWJ*3QuN-n$vWCCwq}xU2UbTz-l)1KK5my*HH2x+ocI#k+;-= zv;ksj&Z+d?JY5F>j~k8o`E?>6eDtoYw<+~s<0$-rZqry}E!Mq(1BetcYrx6dCcAU2 zIc~i!C=r2uv)zL6Z|fSnG$l(BJDO8ZPxg4=wA?Nz>9F1AV)-`ZTi7bD*NXW9IAr?{ zTfuG3D=@|ZVA|w}>yF^^{95xt(aP6<>0L5^kK&13pX+-er%pXxzgly&BPWM5-9v%g zEUv@>|J?M*RE8vr=@=S2K7s1PgMHo0E5_KP2ak9tbhtN@H&<^c)nYfAlX7$n7<9A; z)4D1xNp*i5>`w^V;W^=0gPGyA=H~8i!S6zh#hQO_mX`#bSDOU^Hh_7p6qI9tnIf#9 z;?YRfn~m-Xmr9 z7vH?OCIfY%u^ApfLcx{8{h8*NmB#5*k~Ek9m%TTOl_k5f!&XK{M#hlyeCPW{*2E&K zIW*bq3EeVm39ujumSGu2fB47#F>Kg?zidE%{;@w~z<~T^KtK8rU;_f&fZSF$-2K##?t>Q z8C%+4ntO6LmsBG>Vo?=g_@WERqciZ%Dqi467H|0*kQ7NA%2^Ja(srF z4o31l5vPgrl9HZ;G(Ng_vf6pWuN|^IiFYVs^&hfM$X{(cp7>o?56igLy=+lzuLdXM z%9n+k>uY_sN{R2L_*fJNO3h(=1zi^uH#|9R!O&-|K%Y1G?4y)1n^+Gn{l!4m4}Fn5 zOSmQR>*S?=c{KCSs{OfMmxKYW{A9t`Lrgi`lAUPmf%i(T=f?cEVi)C*RfbF zByN!)!^~>nydgSm6=_Ls+On1NjR{ktcla4B!&L?3V1z~DqEv3l&xr~X`Qx4@XDQTB z%9qh99^=FAV@1s5OC<>icU*ErS20;Z6d6UUBDog59s|#4xkjy60|m`(Ey)fgU^cZR zd*)Nv##P=@CUICwy&wX1No4F8xm*r;32qtir6o{bGO4*{dEXRnR)R^QL`ergg>IJp zu~aja)&MJQ+6W@@Gcrh*U~fqd%@uqJij$>>O|(X(QdeP=)pExRYuGvER^$Az-^E;_ z!X&+`=O|SVluK}vkpMgxU`fPE`3M=umDd#|09#0~xzsZEi}qvmMwduQfEWjfjD1>p z0U4~utF$JzOO>pQ&tivs0?~t8q&F`Q5FrY)CjDn3vR1LNN(Y+U*~oYV(ihHkqg>Wt z)yh#gCsxJj;joR_d;+^rm(Pt=X??Q@Rb|^qOyvrU9U^-cSZsaet0Tv$V^z@~20IQ~ zqLajC>&*r(FRyTL&{Wi3PJ+xx0{wJ4tJD*`9U_L$&R)lDyNza}ENf+>i7|5Xy4EgP z&$85ID$(&+tqnM0Z%REObF)~j6ur72XJ)dN05^x_$`o73DBTRXE-fbKZ9{1p5($i% zXknsaCc%3)NoyJIGPO`{Q6`KOMKzfzUnrGyRGbNx3h&T{HWIWi!i93vG12+->M?4i z8k&`+*yRMdye;o_@x1>S$A`z5NU&Wg7Bvyd`-;Q|$j2h$Gx;S`@BI$2dE$ z$htD|oe!QU59Dy->p@1qDqgV%+qU#@q){#6{`nEoVpHKflJ}?deJt}%F=0Xa48BKh zSjDcGgp;*Pf8)x!sa2~Oj|V%Es!U1mzbG~ys|t6l;%zK%jb#28(r2?wL?e^*g_p9y z+za%0yGmFu-+}N#MNvey#KYhKj|dWV~W*%vdQu zw#${+Zm2$TvocVt6*28k z8^}G@$~E){W2_SDG%){Dd@cz4xV7Ug0EQ=@FbDgNzTHeX2&tU021%P;9W@Q{a`uGB0{QR5f$U0vq z*bzf*@oSTmeQMv^x57C z3ogQ$`f!8T^f*?;q9%~Vhx7+srGFv)VvJL@LjvzZ)V;S*0O9jHUiW=GN;nMzRKOh8_7V*|X$1VI_Mh*I{?~ z96>l11J7xqnp6^CvQ%7oHszvPb#VXmRQ9ZEtTsF9kA#QU#uol$ie)JCXv~#r!4ta= z{W+G|Kxr80!+}p1O)C3!{_lUPpSW+zIn(V9aC&kG%lhdP&cOMf{m$=WJlQKA@7uoZ z+h5Ig|CLvNltc7iiPitbAWDDS@A)4Ov7SGD{BM3UFWTPE@7un;e4_}`PixhBL)E^2 zTFd1NIK5v`G?!|9Gx@+H_{ehOt4?XP+mp!fo5l*w8W zd~fACp>hOTSfN;SFdEF2w=yU9vy-A$^pqfmCCLvhX?Z=$`8g0 z8HZ*440NZObgq>uIxnFFr&-(7#By4$Uz7k^m94qe$=KMQr9y_b1h6-^ZQMP*D|5J0 z^bSH_#YaTF3pPBJLcQ@VVDcaPPPbFJtWJIMQ1cA7PT32ruHf zsHPprdc7HT(V6#^&SNb0KvXo7A@y2Qk$jQ7&*oT)jXQ>gykqW4Uzz?&vX~MnCcn>R zn0Q^G)2Y6c4Vqq$_2RO4cZq41@^4u_o){<>%lPaY4>1XQ82D|a6j+5DREkv`w+?ZB zevHXvw)>1U=YEZFK{1uB(sB@uT(4I#>PGtGRvfYAh4jgQC%$()4Ul#W_%bhqY;oQuvzel8x&DaUB){@BT%grFLSo3+ z$Qq%D5^b5B#o=;;j67d$#MiJdN*_YbNx8;yxe(u-Qm)%&lqf|2=_>x@8}F+9oS(Ol z5<6T3v7$+N0CUi+Vmchk+RKW+Na3^0nk;3hG^trqJAre#UkdajsMd(`_0ek7wY0p` z9xGzG(Q3*%%PBYHN`?F^6|Ez}axDJ2TqtW50u$!zO{516!%pp`?9VOCP;Hbo;m*V} zOW(OqEW(viO5nv_N!udtE>c;gW>A!(_!v^0c($w68BA`ovV&-6&d*$IVM^4vW$XAS z;!AeO)Od#$p9k8HjQE_QQ&izIs=q7uGtuLGHlSVlylWbOS|9-`Oo>YbPwV)RkznichJTwpLqj)d1mo)7V6~+ zGV*>N$dZGah+7K7y?Xy1o?Uz>KTpuAH1XugQ+NeW4^+w78?R{7IpsVKWgkx^7Fkzc zQ0FALeeV4EHkiv}IOya1RBb=5ZQ_^Xc;2hq|D0N<+s8loKYtrv`SM#ou_Tk_nnWY* zkwyEqZ~OLFx$)tFD5@7fz4#}2Q62RIoTSN4`E}QRn6vczKmQ1#^ap83f9NwmL6GiV zmeTjIFF&ic_w)O3eO*n^dX-mu4$qH*K6f(EP+a|6A6rfV7WyxPj&l5)!~bU z3W(2Oa6O;TG>{@MClh{imZ~*fQbFA_~Mz0p$OU_L-5>uF+7 z-iqkFl87lSb*CiJa>>^&P%j>6d0iCG75y@` zrt&+Ac(An8mw;!AU^?0b%;M9lt-GqKJ6|s3cfOVu5}9*UYhWb-Q6RsICBWtNA382P z&s8+ac1=XEgH^o6$>}Nn;7`AU&UZgj)L*M^wujKe>--NR6o!(sCaZL1e;_!R%}@g-LLz%vZ9O0DcxokRIUj=0??&V{4;m z+)BZf0nTBe<&U*Rib&LGhu~%j@>WGeR+^M|98b%YDe`0zuYfPNj@ig=CITkSK2x}@8f z$y$^@VVg~9!kdXPJv5MU;u@)y3dmY9+%1zUJ8F-NymmWJFcV)zft0hu7SdE_kA36{ zFNY#!V;OFtoK!7A(?7i*?ZZWIL z8>~~vrp5PIYvp7nS1_@Qsf?jX!-c;PU$Q}6?7Vy1*8~yQ(nM^|ak40vONgc`6iXRB z+z6(TERPh%>qtgiY(0onq-_CN*DD@C72%eOn6D?&Z&~NjM%ITbw!M^l62B#VT?8u? zisRpokB?`1|R@Oq8 z1Q-s+N~Zx^yzL^vdAWtrrL5oeKo9%KnK_qr>s4%oJ`ch2TH4HgtRwRo#|dinn%=KJ zC&fVyH-j7LGZUE>@~)|fKPK4nZc*-OcX+~t981}4@8wm+%e5*DnS+hYPj4_1dz|km z24oEoK}|{*`jJYhsrwnJ8jN&S?TS9TD(~-f`Y>gWV^_!LnM2u2i9p^x<)>7T%=cxDFy^;Go zlbAek;(-Q}=um+@S({E8kDq*qcq)5yrGew4Lp*-;1lc0{z0o9flIFpihw)$r+161y zlsQ;W@$~sSswRK;>{V36UWl$v^Wbw8$+N-`quwnJ52_&LCief>tlTM=wrS1cs#;D z?&*u4dtKkdJ%R~;(r6^&*TfTv?Rm)X%gG~~ugX_J6WJ@VPe=B*meE2O%U)esqgXst zK}tS>alhc9Zl0XF>`{@4f2`?hcU_U}sj zi{v2v*LmO1y6ye^zU|wm*ND1sCFo?5kjn2YrPcDbfC;zfaNLpv?8k~^3*|vRlTNFM zL!L>c1Y2SW-X&0Bc`cifUSbg~6`@CUV4^hs z*MIO|A`6tL(WRDU4mgcJ7kLVmnc`N%*JU;kvE>1*79Eh*va>{O`8(1rSWnT^agg}j|ZXLO4=wNlinok{fC9Alz5$=~<-{jXv=>Lc2Q%Clw|)=S$T z5rxY0N;H=Q@f5Cbyo?G6<+7&kH?HSmkfbs3rH`3dlM@fm?h!HGCVgU zb~{ouEom4ioI}NU6>;7!5lP@pG@qTeRRn6Qd~zEEvk=t^k+xGD92{sOKI?gqcvRQI zay6I0x}*mOo&>-tgJLox#D$!q?IvOqIWLdtc#eXsi$mGBLg_zWW5^t5TuYIo0h34a zeYINBpxbAE*~$tp5R%t{Y1m|S0~`n9KMCYJXn zl($$?DR`wE^5p{Tbxsq~wncvwAx>6Ek)v}xS3kr2|S{Q{G&r=f~YXDwT>Vv%hRJSo*$Lp(x`=6>rzG5Un<{E?T&1-(pSv^>pS1hjCig zriWm>#@YE1-hKCdxr?=gV7(O?#wVis;OBlc{gE;cb4OkmkrS!Ww9ucpYI zm>9f@sdOe(12;34Tw|jY2SieCA_EKYo$(-$d5_^1b_&~eB_(}Mp?;RfmdWazjb`Qy zx7S^S%dPs3LdjAen99&srWFmmj#5fPvh>&DM>d$v#i+!dGwD$JyF|*XE&TCTg|h4yA~~zo5)Ju2m&wa}xqLa~9UBvw zW?*QNp8U3>u@Bw=si(HFsRu>m(~h|B*?I9nCEVOR*Fz2Nk34uJI+y})JiP1rqyc~) z%#`X?8J|#jW!u-c;%jGUrV>S@M=!*IBJp=yBcu18j$`G!Ws;m|cwN7;Hc~3QHPtzw zcXdoxc{-WAyL-M zX&IMP%;x~H^N4#&q`uphHEPN;$#678r~6!=Q{pX!9~<&K6nyeGu^(W1?%86%Mi3KxhVVOI1Z|Cn;Zr*V0)>{UxI&9%52ZF`J?2 z*)>*~r5^N<3MKYKlw?0Slzl8E^W8i-#I5)q{wV_J>Xe{ zQ>8T^o%)h|vaFyHAF$y%{gm52N&0U=W03sl@w1A( z`ojp)Kl}H;sJ8d>`?ha?@ogm!|DFW26f7Yfpj#{{5|h7UIXcVSEMtU?X7}-oZ}R5dwYRet&Gbj1LX~*%KVb?t4-AB9Gh%WIqb*_ zNX1y9;3yE`czNa0TuLD25XmanPl&FOzA~BU!I&=6hT@jl{J|&nENPuIrIi&MUXZR zPcW5$mPAz6$3;GG|8d3h^9Di9U>Y>m@UStyu6{li}aKHZlzoaRkw(q&l1j;3(y(|EqwIs zF$}pMqG3<&-N%fj)R}X25i`xlr*iCCV$8aY34GTB%V^qSb||i-OiRfuEp^HB=~IBj?nJk zXc8->iI4(DERU~>?TmayDL0NejSVb-`_dGIH@i;M-I67%*sjQPPqt_W}2`9^r1F?yc1oSMyPaL6>MNa)ET zLT?kn6WgZkIC+-SS}2!}6>Z%f`UppJ6lxV+i-XY^qtO7h)|uLJFkh(O3FN*_JCXIn zQsPk76-)kWVxs}(Vs{zO7Mo6#zxZWaUJPj^gRr2I^=gZ3jiM)6En%mc{jk@EWs5yg z=*r3>?O3SF=iHGs^#6VR58;SUU?M6jui=4HWNy?q@F0h1Qzil%2W3TGPkO%6KoGIc z%(t2B=A&HC$+|3H*dHoVK3QiFFH9ulHDxj^TI29c?AN9uc}fLw=8F}|l{!BB;1M$U ztR~y4hZRMmK6>v$QK5;f>vD}~;|$702mRZD^w(9iw5Ua`vAxF z>BV!r^72JpV49#W*A;jhuv5bfKqKG)kJi50& zoRWvrllv$*HWt+S693_guP%BSUAu|7RK7~fvy}%nl=*EP)Uo6~Vx`3wFnL|mewFjK z@`{>S@ne~S@;;J!;Mvs`4jL`wf?dLs$YLJW^+z-0DzfGZIr;pY9xf2+`N8{gt(A;S z&Qv7o%Qg!8#LHNzCn%(r)DC3rrqt(>*D_xyC|Z{G#e=)?sG~fa1({DG$#2@Xs8_|# zqNUykxs;pr3JmcV+zUt-b9H?qzG$YLuspyS4m!$j%0e)5W^cA89^AW!k7TW{wlNM` z4YYeB8S}LsN_etf$$w1YFH*1+WG{}zh8@?|JuMOcm!()^6sQp7N_=^}+>ra4i;u8z z-Md1*Ttqk%`%t$UV;zo>@is_xl4q7<>Hak=Slct}XUPe%hF#UUfZ~<-SaR8?b^#>3U>+c(%@? z7#r4$5sZu_J~*fQ_b8-q8p6w_H5tq#F2(5POVaslwcmHn?_oXd%lM{g5O{QPA!9Fg zze(Z#=_{H*_hoL5YWKtk^Dx`O?X}E%ts(xhj8$sq(}{>>bwZ<2m+wFQl;xh2bl>)E z-}Y_aey;8O-h&+{s6L1NYa&WNAuoOL`+cq`?hcU_UW~s6(?z~GSgtb zl&?$B>cB9l1Wy=-sa%9iAUa7})wV+wT1jhw;bamCOk)W;O>89~WUv)5IYwlQ{Ql0# zYiJytYEZ&pmEszt1!MU-%O@GsK6`e7>njQu%v5~IadTP%Poa^GmaNCh^+>Uz@vwtI z?*@-PdK>MVC-5gjL=ucx=>)D}C`yARf@4UDQQTUOt|QG z5N-l2<52n645TH98cR?asDe3>ua31tCNZ%TNx;Gqbn;MA^r2R2B2Rv@)Dp4$eb?Va z%e7a_wU#6kX_>4xDrUp7?xnmxlt4C-F9{eU5a=}a7{r9(y)+MPogw9g|haY+;S|J?vE#U z^7I0gii}Tcfo%aO-8sf232{BR!6+EZm`Jc|OF%4R8>|;{&r=P03;B|sw6Q>wfj4<- z8SRoMkitf{olAM`QiV|@PDJ}TUW$+J&KsU0Y%OaiI8>3~bJXb}XUlz=8>I!9$i1>W z{N(rnJh74SY^r>Nnw+G#kg?WlC94F};Y@5HQLbFqvo(=xtmWS2_q3-*y^g`4tvsU_ zPcE<}7p3&E=rO5~QDoL=GFA@Rj0D^)9p+9)6>`!yluISC;Ru872!qjRC!j+6Sg~Yv zrRA?gPIAmbSqGI;OZwZ@Ae-Vi3(_{QL|Mj)ir7S3N8wt_cGF@Pwv0Ww>--r@ep4Fw za;wdXT~zWljD|kktRr)p*4GmG$0S`w?7rXc;^fXD0`k*}?Kci;TC%T+u-*_k&r?c_ z{%C+ktE%YKLLsNB-ccCp8f3XRlV48GRb-VZv_6aB9!qr924`^0!iA$n8}MmN&4LvKO^I?q$rmq z&TRuf9ILM(YMZ>MJTx&gB~9#+h9gO3m9E2cifZGWE0!QrIi2d|>s1P!o6^g1lDZv5 z-L-GqD3=SWXwJlKe>7D-;aK`klomN>Eo5cgX7R?WuV5y&`Mlkg_vDmjgve%!-DDLl zni1cZm$g=qvG2*+&f)T+rwHeAsi;ZQ(O`;&&vN>;jIq7rwk%cAzaFcI61g+0wW4zG zx=tFu{Ob?#_|dI$M=uu%s)uD9*6MiwohK+atIBKZ`x6X01DS^k>W4X9zl3R%OE+J# z^9$b)Xx>g}VkAh4k6?hs> z$Kpd5s1~bO25Z@CY(>sR;Y#K=R@Cn*;h{yS2XL;~b*FtR{a&gV*l0kW)|A+$r`(&h zY6IQ=6osOv+^ zGY&f49x^ElN6nV3@v0(@bEI*RFIGk@7ZK*;=1bXM^TfbS=T>P;T-Vlvu=!$_fTK82 zv(dzOGSY)SUXQ{|sr7Q+l_Q%;m>`yig@+1@4Nv_{ioKoLYESFKK77!atna|Zuo!;a#hl6Og z)kCGNxy0R9&h>yZlxq{^KMjW%j(Wbm<}4|}d|uhh2YvLCEd*ol%+0Mg2c z&zr(7#J}~--+QD53st*uLuzUUFBVfIdK)_UW*|ce?D9T~0fhSK)%(_EtQd@lIgLhCZ zmGR)-T}|@%;|`u*K2`NQ>D8xWM#FUETxEj>Q5@@oVJR^Z{Zw(CW001BWNklL5 zKRt>6{l-#40yc>Zi&JY&3^Os1FOlC(0z$E=X7d2!sgH`aMd#VI1gD3nmyR*;yV!_L z5Sc@P9}2OIhGU$bonpQS6oK_*c!B#z_mDR7sMIXP62Nce^A6;i-+upHMQSF}_d+Wt zw&UWa*H%UA;b^QX;^aVOvWVQ8z66^=G*hJTHWe$1hayO=Y7?vQ2Gw#-6GD-Ewkh+< z`N%sC#xq09JhNi=n^d9#T$5;tne-)=YdMys<(dsmz;4lQPms^sSelW}Khc{Xw;WLya2l>LH2AyegNeNBpR$(D&XpQTg%7KPfsU%`H0{YJsFQ!>?kchAg{tyw6*D!;zi;wDs>g%naVup4M&qx zZr;`PY8g-@)otenC9jMP`DhCbMf|O0oe?E>cu?158bwr6X$z~x`lWp!6Fto2Y&L1- z@m$4$Dr2{AM`%w5IKOj%{awaEK+;L;!~KNc_h}5yl(YbC|Sb!rPb6ySQHA?kNvjZj~~k z-l$_dp2%KdV9=kapidMpQE!!$hj_i($hw+{{|Hd6`*QDza%|G}i{c}R{x67MZsiP-Hz=G{{?FvZU-v1isn4CMY7pOh8f zxI(#H(?cC{hqAP~*B`2Y6A#-Ck56!Q^;p)^%hNqDWyrE=9;`4)oHBM4BNQwoZ*RNT zQRJ^`%_mDuysc#olPk6@zJUIHISNq9iw~()upA8J_id%2vBW1vthj)w011kwu@s-e zL_{_-K^6u}eBq7zvM){HCwwtKCW3%2K|2pJXamqDz;cBXR7GLbB%D%T`$ZdMF3U&`rvIc=TcdVY)A ziH%~zmA-^B=5_UZBeAcE-&1M;qRM%gm0qRvkSF2<^Ld23^p;|JD@>Pxa#>TvFlU(P zTy^yjHHF2KeIxV5nJVZ#e zZ8|G!{TLZn?%duTCM{M8-hSs#@Z~RlK@*qb`AkN1jcf5ImTReypBR(up=*7%-~oj# z{(nWDQ`ygs>W4B`29BByj7Qh9pLpUYV?BVPz$Et~3xkr-j+rI7FzU|x3wGm0W-R^{&ej0-G2a}&k@}J-z{?q>+|IOd~JNT{t;1t*Y z*EjK0|ME-t`~T>F!vFZ6{|4@M{%`!=#SdNNryxytKkt#G`?hbNe*0M=N$Mn#2g^V+qJcs<2D7SVhmdl!ES`jNO#UrB9Cc>1Qf=i-j zB1|Qqe=_QW7(uH3Qmyu=cFGVEsq{wCuyH(85exbC9 zZd6YcAv#q7shWxu+BFb1|$e@|Q zC}e!%#Y8#H=%sf+|S^8VFSnIcy*hD5lQN@*>9Cz^QTPZSlqmd|D| zY0B%lx6DT~IJq1OxiT&;KiCOvWgHA|&6h$^d9^7rIaiTDMBEaA%On%kha(w}wBxE^ zM=oEIpit&79cyx6Jf7l6Y+%gNOd~=ai>BrV^b*>qJ9I9eLkV7H7bOsnB(N7hL&Oz@ zSH?qM*TePmzLvWm-8(~Ur{J^vQ^tBKbLhx8I;M&1@d#@P;73GJyOxTp%)>|#p+rKZ zDavJLb-f-ok6@-uEknQUwZ*p>TE1+{m=gW#*+mS-K9cmVyu6$%;@_7#oC_<%an{A>B;!M_2D685i%9tK0cQcjTvz{ft zE6GBS#Rlb{)E2ptgFAPQRV|&$?ceyu2e|X_3}f+=q{w{pbFaxd7-NyFU40 z`A`pz>SFgP1k)w1p5H3pVYQZ58l#Q)aiz#`WqpeurZCOT)kth9#IOI_=kei3AB&Ad z2*r;8#y~m0ou8cRVU%fPG-*DX^s$gJ&KS1xdJ-{PKPV!QHD|e|%wrn6b>M5sr_KRB+G{U-!YIk2I;->kp*g7J9v& ze0B-re&MC;uUL;%EQs9Ov}ICta4mALAUI(>9Vw6OX1&qF8Ui7RT8&q+a&hL|JX~2L z(pfxzet`#fAHtvd*owcNi$5xr%ep^N9FO;>Fi!E^)oM-rilf}SU-<0ju#k03erT>K zOKdohepKpZJpf&Z57zR0xs@;!J7XaM417UR)acBDwx7&)Bjqli52O-Q>yZeQ8U%6av*o7m9xO#!wCubyMl_tEY8 zO1DCEsFB_AC@(f*t0hDEpxvUYRS8wu=e%qdhleL<9G$5!lT&Wso8S2k9=`T@@n1!G zUP>$7!R?@f-~W?8z?Z)K72T^oy7~Z<#TZX-t}r7yS8TshX<#@U%6>IhUqC-VPV|iI z9|z4td6uZkI1S|NAIKi*~?JwcXiE#PHzm2b7e1aO)YovAxmp^>fPd;~_B;B`t`}Et-DoI*w`pVnr z$n})ND-Kk#RiZ`-@+CMmEYgE%sr)t$^)*a%P*t8Kh(!tJcwmw?OyvV(vV&!b)j|_F zyM%808t=dRU0hv0$CHZ-6<%sJs`%q?eG~70^gh1*y|)ppr?|PjRUw3b@y&mUZ+-I{ zc=GZ0aCLR9NksOO<%0~ai5m5C1qllCDrVsoDiT;`R7IBPk_<%@DA<$DDt0uJu{5Ym z%MDCMZ3$SqcslB0C_!&XGz`%$EH9Q|e@bRiSjG#P>!}2gL-fYC*rt~l zPCB@`yu$DN?jNDuzeJ_!;qcBWI?FjavmvrBQK}7G^`BzC>`G9aV7urdh?oF%c07#| zkgk^$p32MTNbnaD0TcmD6t9-3%iO1uSP`uhFd=fyaq@~%oV4wiN)VI}edNlXim3GZ|aMOx=P@>Pyi6o*NT*<`NB*Mk>j;F?V=@_PnJ>rK$=R};s3C6Z!A8X^tKbwl zS}C4052re&M5-G`2G`Hsm$JdM+d~*k)koZP+A73E(IAr|by*^69ZixoWSyo#6l)Rh zKYkCrL05SiiN0-L_0T$KYNFnD(`ePovK9xhWiBb|LuK)t*f$Su$QPKlQaF~^FUZ{} zzM9FyIF2!&iVZb$n!qeqOEPXLy!!AQ;bM+ndyLbQD(1sb)@u%5cTM# zTy5lJzQvcPWxf#L==eZY;+cSS-5sKy2LYro3D+Ukk@Tlk6q|?itAIkuM7uLqp(9t` z*Jza0FEUA-FFAS`M*5GzU@WtcMY}t|@tqddi7#^6J-$6GC#b|~mWp51tZLV+mEt(H0SDc7~rI67)6x2VDT%PV+1t!!AC90k~Sk6Q7 zUstlO@|t+BR-3X8i9lx3o#ouN_(XCQC$MBsZ`7KKoV86CU;W}&aq;XzX(l=Y@u@1{ zRfI2}f6!=R(4ER_#UEzV>Z3f_dq?s+CS1$17t$Zof7-UpudLIH#~+H#iFFjxSgb~} zHkSy7YxUvd{z%3(RGOAzxvpb6Y_}DeOVP-pn-?D;{gwTR2aTi*uw*YMpSjGU*wa*> z16Y2*MD{{_*5&g{+ZI7A3u5~ z|3Amy{YU>be&fd=MSt*m`aM4RoKLQw{0Pc)-}Y_a{&KZ+Vo4ZiC=!ebAA=>YX~2@sfeNQ&at=QC>|aI`hn7>4Ahv)MgGC7<7&sB#!V+Str;|f$y_iTa=c6Z|)eT1)STNCP8yQVZ zj{KpPtTAX~FtgpHkgN^VC6Ft4IZcjg1~tWCx-9`-6$eM>I61qAncr2^2I2(yOhy8; zQ16A+?73@IBP-T6p~z&Si`oe01|1 zSG`L}ScS1q@uAJ`mNqOOU!s|#Xvs#!dzd^n6DG18<>PErYBHcuL|8pnLp7g=CH=|e zGcuQRxud1>hAx&u;(OyJ4lY43wp;z)JZWC&Rf?RMhKL9G)G(smNS!BKTo| z_da|g{pf3n@#Dvrm_-IQvOecj?arEFKc>t{tOq*@$4>08JM4*n7^$N5a+@LoNtL9D zS|(p5k?Z8nOcT*2^B%<;6-FcV0O=AQUp>aq@2kH_E0^pJg_g03imFQ`FJER_s(5If zRuQK*Vk3D)4~FqV6M8(PA@D9`rg6=({-a}j@8Tn+g4l}9=ZmKFU)FIwuiT}TvW@ez z7M@%_RX-Gl(eCg?x)aJep|bsW*4CsKMbQ?k8NT%8&&t>t`Z?p#RBT`7uToTTrb?-f z51(FOE$jQ}yaqcbUe_@&4dr#>v&mCTF3YvpKT)ex>#jG8>H}=@_xcphaiw2n6+T)n zs3y-tu(S&6P(eLoZgBT*4UL1mik$J^Tt1Cqe}F&w<8R^lle;Ccou2scye5RHdY-J)vR>CH6{?Cfuh);@WIPqZNr}N(V$Zu| zCHWscM6yR@QWSr3HKEUb+VVxkc~913#kO zT)^V9P1&z0+Q%d+4|#}yB?_OmRU)#G<0W=`c6x-Pqcgnn%Ik0}SIgPCmk^Cg4o^3m z!-Mlz@cJvC#l_{vc=GH++;lFH&*ovsS_()@BG(}Tbvz#{@|GO7D;Z~U5Ib^@m1+ff z*TqKc$~GJv9h@jd#+z@wiF&oFf>wE}CUeAn#8&Rotdr5ohg6n)%L5czSv-8}A!-M8 ztw8Wft_re|qd7%XblMU-$mwCAZKu@-{?KS}vC2uPKm8 zfjL(3Y?a@65>6D&O)3rUk3WyLPm=E2zU|w-?c2}2eS#qU1lfrn`1uE3iU0k-`z`#n z|Mnk$@~e0M2mI!L_@Ci7f9oIMpZ~en|KvJ<_PTps(tX>vzuYZfENEcO05$VM$bcvy zJs{ao2*5xoU%*jSf{ATLkx}baq$;l#)ody5l8&$?XXtpWhz|zs&#ynipM3NG#oOQd zhAJd~{OAI2zyCfi+gEsYbE%5;kDfeJjz-9J-}vk=<3IY3|4Y2}#os{n_^t#wE(Q|x zFIJ&~G08Pabe}{%njA7LPXe~IQUEY2P^4qV1s~Iiz}ZstB5Nv_D!IT&tjIF_+euFX zia^WNs-=qbeaC~zga-LHONBfR8WQ};zaj1$aMA@3dUH7rS+R+9I#Fa9(R9mY zfLSn+AWde>OH{c#l7M^`%v9uLGU*~G!RR9B%e@a|NAOWEWnS9;n1EgQQ$-;`)!et5 zaIkdlph!g~S=M526#HTcGdbCaqRC4C$W?oM*iy71g`YB+lqw8w3?_b8ih!F+KRFI6 z^b`iL#peCZT!PI|#V^Kl-j4*(W)7hQv#aG6p&y{+c*sj|y_~Ob^Y{kso33)e5oOlx zv@z^<5Keupg9rsThl$L?dNq{($td`14SMr=59Lxp?NSj+5`2?Cmx494f#c%?6>u`; zwG@0}(u>09iiXW*W&LGP$Q6_?_|Ewe?w{U4uXC%yDO{Id{)IR3*5^KhS0CKP@j(k$ zHy6m2TpTo8xW4GX$`B>);`y_#3bQ3~M$4C7FN5LW3ZvUgcqS7YZ{Xkijo-xMXCLe5 zQ@PpmZ1E4amio6Zy2?*ls~1tM*@`-wjD6*G>_~sEE(du3-N$Iuj&LjEvNgA;HLCjg zR6-Bt5p2hWX=UJ%XElmc$vj#v@$GlMi}#;A#dW)_0X~I-hzg%BW?*M162_Dy5n+0G zA)gtGrCs&gV%M@Bl$$WE>d%@ml-Gx0_|i7WL}eHUN=+f=rD9#ADBus9ZKT&D8l1_J zO0g*RG!&n))skLPKad;HEr{<)#j;K_nE5;i+3NEX)vGg33cE8M1Gblzc|24eR#Fhq zESfUc{4ACUlh2rvc}^ycN+E}Dee;`m`s4yLQhAh9a0(ezYdJKV1&pUdx&8+6Qa(@m zxE33J_Hi4PQVE{e>1q+n8VzxK*~PP`9kuI&T2toJ6u%;47_Lx|IUzNLVXWcViI%Z5 zX`e6&#}e)3N=0ReQXY**m=noI8Wy6f?=-Mc4xKqT6oR~~>zH;w@+;^-1w~Tl&vY`N7LFV39UPwoLLW&4q>6_zb zWqxdUSr4Cm_yC{#%qf2P7vIF?^)oEy6X}Ea`J1-VBc!a1A`yeoN2z3?dXPhB+(sh4 z*~pT&a-e1D6m#;$A8^eM`U7VGR|?!yr~J zZzhIW(mtL{R0!y0Th=u(^?R~bpeW@O6Mf>#qD7?spUGnKG&6BntyaZ8SIRNU1Df%0 zp#0ucuwN%T&R^1lu%!Ia(+|<^-D-I|>kxcdPt|f$dAys|CaQ%p-uvKfj7B~1Byl2R zur<=Uw~!-~hF@ZT3eF{K1ltAbhjrY!bE3%9-p!5JM_PSWT7}$HHc7_LMXP=S zJDpbnIQlrQ8zv&Tsgr+rE&I12_Z_YmSZo8ClN6@3CC5;X(R!u+qNF^fXnQkd$#X`a z3FXe9hraAPzxcJU>=4S!U8#H!uEjtI7W`T#FeE`D-UU~B&oT4eu79ny42OF{D zTB{~~HgIw#>q2}YD+KaN_2J;&opTvW*;lvZ+qIMeg9mmCjt$ z^$U3S(L4Cg_r8m7eDF;b7i@|zWODPJN8eGZn8%Nv$a+X&yI!l$_j2L~mqdFXD#b*9 z)P`5i;OzVq!E%nFJX=}CJge|!U9K>h4rH3raGa9TwZw5+=_$y?&Vw|U9PP!j`c)0h zjPy&};LobkEq!HI4;p2qiUc0@QZ%Bs(tdWm`~ST9wD*3 zokA;x1BhB!O5m`FwSE$TUzU#BD}x8$}~NR}qbN@-LVYYkl>m2P7yDP;sh*hO~mHseMM3A2Q#^YEW$wg zOGKEwpIo#=KyTBDBB>24jc^rUJzp>dsAy!{V*l1kV_{K@$~4icRZyvyw7h;W>x0>2 zmTWtwtw|Ab=2A)epZ)&-gN?OTK3ZSav}c#`+1K8HKV2yIo-6iWDi<_q9IXxbGN4$kc-zZpQH*F;)7gcmk?P; zs8ovx=DyMi@L=M$)5F=>k&0i9$+ennW!>*MFe$E56B{A2xY?|rE9;uJ`Gq&%!sCl) zN*h7ShwiY8TDd86zgA`W+s**ZWmD+}uG-J!Z;mE}{nT3hu2;yaN;k`LS++h8BJoW& zR^kJ41sUUd8KZd@K`d(_yFveIAlEI*{6)CDxkgre_)zBjGq1mjr;o0r-+iSzn9Qe& z0wiZCk-X$_CBNxf#%w9`Md6~!bfyAbz8}ck$hs(R6b((J?IK|PfQ*;S&rRpKCLa@o zs8li-4#h8sO|7gNr*z#Qn5V> zdWEwk5>x!QSCI8&pnh6W8)+SuLAvKi{86ds;a`0G4l2z&T6c+N#LC&18QP zpF17PK9@m_B1YnCmal0`VP&L0g+t{(ec3khN3!Q8=*fDl z%6v14)@mJ~E_=do)W?<>{VVt2SiK^5D!zqt!xt*g@mu zNXz%HI!|z*sPVgs_N9Q_ESjn9_2l}NpFt#hXs%37*998Q68ghy+{!b+7Y@IIaS(}o3r$u2MY$povI~NYGoDEA|(eA|JiIFquG=WUY`d%FN-g}_LkaHdpOV% zdGak6WPN93?JdL~6-h6Vb;Y+G>0y^6&kLi`5QaPhP|S*lwmb|Jhk)1!aB}AmS$9VZ z(Yu|adRW&(v|6Ex*69KA6AGI}x_`+KqSiW+xdSG%p&krGGPgW1AdhXiRD~mZ+oS#k z-v97peCbPH(Zi@(qoxNrOL?Z4rbDFi4lZSn*vS6dkuh=$Hg3ANvi8LXmkbP+H?n6Z zx|TLFAMZc?9)^$Vn9A%AVsOiAvmT zzU|w-{afF@j{^Pkl9_)N3;L5)?33NMN$SPx_F2+>+qb{$P0QZP73C3S@RyPhjJ%@@ zB8U=}g;8u|sinvL$qb1+fTv=L<(ODUu_gy%vo0>X&lDx`-nTzOI+up+N?_ezz^za4{`+s^{{7D(Tm;HZx>-$Or#Fh+2&N-V zFfD?amfKz4#>nSNFjEp#$Y&A-nw9|admp|dK@afic}uw$os6j>MW&TQxpfXp0&~04 zLi+tb#gh>^z9cxxz0g1`V4|&@$DrTELG4&RD=(kx z669{TDXh1eXGV}jC^V{?G~6yXs*$W^j~OCei7ZUuS`zFp2bv(?#I~YY``w`gj&(R` z8;jKntMw9juRtkq32q(a^EFr!xGoJ(lVvOeos6!v>~X8uLyj?3tY*y(Rs4TM9q_3Hk zz6BHHEL&_gjkD^h^!NW~?@hoZyUKFmx2ks4uG%$E=hPXxPmiH95kO>+n*jF#g#-~r z@gmpY4}uQ}BGWY(FERW#3JO1{3=blxXl@jYs0ddvfQE}C3<-oJ-RY#~GuK?Zc2(_N z)Bn9+b<&-w`-DD82eQ9BCw+#h+H0@%t+n>|t@nH1F>1D}fq1{`DD{F78fbE|RJ{Owy*AToheJ>xN{E!|L###T@z(h*LWrMZj>8%Vp(vp3H@$^sNai7FF>qA~)NeuF|oPnjt5CR$ptO+#}+WD)%E5 zP(>lMd$>&_`n0$+I1ZcI;+&$p?F&O?>5(iu>ohiF1JfC}u)0+UvS z9GiUt&8c7?j>&ioWZkUDoXH@QNg+4CsLFAqza7iFyvs(76dG%=L1DA%gWQ|xp)dcUN6NXPR?#j`51 zMY@Af-^8}v7sxsgQFV8jHdt9XjKL_W31ud!x$aL*74+cL7T-z4Ok@+{Bh{w(m8D#> zv)g81B@BHnpCvkSO>!}>tsT=U2y&8oBNxp^T~XjWw$7-S(F#^oFfBG1p+f<{ctn$u zeEuMko&2{%ruGLNrJkwTT_n;8dL{C?yz+3@BSEe7D9of~KMunixYD+oj2*?~LTIct zk(D+MWNl}n->x)epTk6iO?=aoy^|&E6yRDD-<{hskG0jR%(a1Xlx|JWqTF1^{QR`c z;XJ~6W20PN$L!1u(z1Wtb7Vj6IkXRm_GJx|6<5Z1 z==NpZ4=W81(WP~}id5PZe;jF&w%?Y$R`%FrIv{IvQ_0{1!IAWrtc&5a&b`qnsDe)u zPU(;eXENy@Chx2*46dEgF?HR$eAQI}}8{zwA0iY7G1 zfxZOCLxd&Bpz82oFjgS~2Bj1OAbQf2;GmF;!_3W~H|{DrDxSh zio7bjr=msWJtf;_Dx1bVO9vI%l}yDk47$o6IzOAioUwrQwKXJ@0W2MDVqs=px$D?B z?arDeGd5}z1gkYzN<5AHR8|7yo+hJu9??T4k`ioZGSd6qTHm1QHmxG|5IJWHw{TwW;(Tk^b!q4ZZs5C!OYw=v=Ur=t?9UmY&5J9tWZSylB(zl#0RE~OAqOMQcG(&4y2%9 zNjXcaIj-z$Pkh2kCZ%nC!WA_k6Ewn_zd_*CyM^b7!fUZHK5s_G79653jTjytGzGQIl z=sHqXTv60(2@}PoADWYX57SwFl#P8zb-ww{%xeJTS z%PLUCl6slBT9Qrb4X#^HKJQ6rc8H%&$($zgJdA3sj&wSUOgyD)M#ClwG=fAn32SJ| z?_|uyPq;kgrZUp6rnD=dV-&YyC=Lq~WNoky>YEYmJyJg8p7P8 zF*94#1pe6Qqvot@x%t}KD%{oxPujCv%d}%D@zI1OecDt`(ZNuBQMM*q<`F9z`b^Zz z;@=xnz^{#Aqp!kZL<19XJ01qr52s`-L#QDXh>HK2njj5DZ17iQ2JM1EB$1~l2~0{SD~ueEpw>1T%}N8X|~gCWB0ZTu=lRJ5R?9|HdmC&!t`Po zO6LUR8ce{k{m%85EPo!7n^^e0I8{$PNiDf>;%f+=eg6W>g@JMAWN z6zY;SE*i0vIv|ry$-3LdUHcBoy7Ck}?Z+-s5h@}hc{s}i=C*|`O0%-KvW|YIr)vqt z&g@oC=C-AxR2|1gacV|=EFwGcbgqco_wU8I7w(erYRZ}-`$!>!TCJf6tGjpa(B$KK zrKWQ>F72szn<&o9xRO?=KTz~#O7^+*c4@1OTT$NMbSjvhFY5lvd*gFUty9s1v1H1U z{_r$;$^PJ)gS7$H*Vj~7vC(ep;l+WY`{i17B*SrOcNb}SpC@~Tijl<=dQdqf&mQC; zK6YdgMkFU=W$PiQ=k}Fih6hun!aUk7qM0K~`Lkuq0;-2swW@@?q;Y9`Pxg#pV4ys! zti~zj=5WvV_wq`Qzz@&d{3NMwzWL^xZ)e>I_?+l6orLt9{N;W>KNuN$>d(CId&QbO z{O9_7q`vv~!*2{Ihm=2}zyTAcLvrJ_<)OQy>fVP}R&egFJ*sr=b~>mwnyTX4YBf}) zd+Y2xT1{I5+BiIUP^SQn)9Px%%wf4*Xn<^d8udm?kvglDW2&+n3?`73z^>QtO0XiI zN92yTj8L>FfijamtH{KOfa*&yH9$~<<%u}b;iKePOCXvIqTQ*YQfXk&HRY?TrGP^U zS1fGDAP~mvwyj9yN@%$foP?nQ3zc?FOXY14ffa#E5s5|vbNLww9Lvhf7LY(CY>XvX zjHB5khhr2$_qdQyr~@+B83}xA?W(TTL>Z3V5oUMJ%lJglX}F58iN<2865ef--?6Vq(uFPC<^D!EwssgZ z5^yH0D3W6fd-v``A`@1DAE)i0=ME&uH6&0?D&L+-A3;*?qbmdh!Cfsi*c}vR6K=_-ABDs zhDoHX+f$`%LjuK-Lk0E;7bR(7j;^hvwqC<#Fif zF&Sg=b&q}8Rn%7~oKe0+@|7}Ck}u4nYqaFvZ8RM5!*UhTL}xWpt18mf%DVVaN0H<6 zb0xjzk;S80Mo)@@KwyAUp(OX;Q(jLpcam3?2SKJPfv4nN!|K1@z>xLHMLZLP6=E{5 zjrl1HUfPto)kZd*Lp2iCq@0lmVc-o=ciV_%in1V_bAd6F|oY3Cf|2dp_?Kyq<4r#6AE7+^arvoJIcrFc#iBN296#(hV##P zD%MwR@#&_F6BETDSeYmmp0q^|q!9FA$a-^R>8P}$hHiHXak-~@&r!i4CYTN$T+#$` zGCe}YUc>YZ1*wMEea;>gIx3ZlFvX9LuCfF<8mXqTQ7Bnu%bd71ObdCK@d>rhVka zM_M5g+cK|*fkY*@Z3nLSp3#@pHD$^=6~lo;N71x9xah)jFr-qw?6cN|dt`n$@tyB} z2XpgV;K-Pj3e$Suq%a_#_?DRkS*PyOHY6#^B>q^GdD82+vM<}x_XV_U8}p@EEHAGq zSMi)hN{leJFPsCWRacI#$viQ29U;1tXl+CKV_UI+E2lU) zqnj=6kt5{NQ(6^Z2ikf_>B^i4m>U-l+bj!3qRHQV%&+R3Z@&5Fn{UT$+s@sZ%%I(e z7{x<#j-LGU(_i#*oSz43d;cDvzx7_k=vF-c<8A;-pt$c%{SjpV^oShl`+U7>f}^L<#;PA5Bb5MqO`oer=_b59Fxf`hNB=t;}{zC zDsq{;1Ojyl1XB9mm;@JrK?vvV-h`A6kq8yJ&cL|lt7vY6BTM1mo;Dw z7%_wbF)SXeBQOpz9zbbJ3C^&k=#SOLQAKLh)@sTTx3*f5plcw3-ayOkl0-pCz)K{Q zHyj}~oj@=qZK5zoK7$LTOs%Z|waBzISLpED3PdS1MT8 zx)qgb4d-mzts+#O8CF&94!Qm$U{AB8-V3S%@v%xx0_&&>C0S+?Ry;3ZS8|ddFw$`Q zBP|P$7={FF8N?zvOlM}a{JS&kO8;cBAc0=5(Lh7)uOk5@%Tql#VA3LFL~!^p7vLb4 z%gf5gSg)03kqsf4qT;)y$rlRXFkzH0W{|cRtQ#scGqbfssd`lG3X=I4a?^QfQx8K` ztao&5Vv#s1^<_-C1bhNZj(6&NDw?ZR^}M5SC+bYf#QIq|>1!yl&6|1wjamaS6gYAgY_JFt}-HyVy( z90(zwBkHRwJ~B`)LdS8DN)&O<*7LBmcnraisR26CQWT6~iSdYK_R>e^Y~O_`>2vbl zi8JEvqeqd+v34Q{JSPUZyLk}gm zwZh2d(&7^=RnHn^j-t{iFvEX|Hua=^p8P(ZN=pBXkc=j=wzj5a-;Ql7H)N|( z*U#ZxU`a8PkrY!J2O^qOTwjWB$OqH;maH3D7}1EXMPa$$i_X13lVqfQU~(v^h7fY|r}ain4=KVjUei-W6}e$s9LJtKJIVL0b`wXJ52Mkn>7n&7(APdO!W0_w zP|O7|^6Kg{@pw%7r;BE#iN(7PV%rqCeMdM_Syj{{QM2)Q0`YJ{?yZZg_#gQ!Lq=bd zw@j=MiA;ni*Ds>_sMbxvD;|EtrT@~>e!}4U{XUK@FKOv|X{MmUXiQ*}Mj#xFU}@>7 zBBEIePQF%B5-=&3PNrqetRfPfAa}zQ-r>3*G?aff77Hs9)d*8aE}(*J-L~BGD1_bH zw#)iclkp3q+^WcnJVh;1Fo)dEEDP@q9TmG8j{8c3!m{FcGA8$$Krx>}aXKse)kxlB zDi0=s0)>1YbF(E)lsB7AIE{|@QAp8@M~@yrv6NHp;C644T%xdF(n_fK9OofvOUQT4 zv;V zj&iw-A{e=*5CJ?8e`R$=fPC9Bo}|c_Dio24CzUHXDt)uEyo$E;^N!6&jnm9~<&))Rq0igk%_>B@aX zqVko}!(z^t(YTBLNS;x;JsJO)&Nb3au%9`u0lDARwI$ip3bF=B&wA%P6d1+ z;(a6LBT0Sp&9^7KF$l`$r({8vAS!I0YW;me8lR1+m`qNYdUYKgK74JuJpeI!{D1c* zFHay%ALi}<^{u%6?LQ8D;|sXs_^&Q_?REH%cK~<)-7E2{pS(X}^j;3q@q>`7zC97m zUjt5UkIfozX2uyzF11)RjGjAIR8cS((sJIwIEaqjmiTj$K&1+Ep*SOfNC0iB4)`!1XrRNSmjo!u>6nV25N#R= zj}i5#0^iWUjtcU7F1kPhuOpfmi{^8%%m~tjj0Elh6sK5HSI6qHW$9~EgC6oR1|*{{7KN$CVF{dN z%z{<9e+l42Oc;mIEU#+`d!xCIe5Qo+c0C1q?{PJu((5~jSp^BIb7-`y2uDLWwtkP? zwy!s%9! zmq5&riPn{XuD0GnFEPUWmJ;k{Skb)cR1DRYi*ziDc;1pgjLDM}dTj}GLviJ^B-d;> zP{1(gX=z?>*a5;4oaK@*17Qia`xtsbVtb0zenNF_m~E;Ohl3 zwIvHj#wKP4#q=h(sQv6~gy8~ZC4$)l;7ocXZq1$X}i7o;XWHRwln3eWhu$`)^ z%n!v0iP9;%>(Vbd@y)O%-pI!glEBbY;hi?(0r5RqpBU-)M-m|RV>ok6rBfhvX&^pOG~Vj^vb>%N)R+o@#2M(v!#bBK4%Qz^FfaW@{=$a%%e43)lVZo# z%bGw484R8i2vArinLub5!+bu985s+=W8+Y{Dg7+tEA8c)kk90${|1VrY_2Ry5FXL7 zZg(0eg&>oS=##I|h< znndKljg<>uvZ5X57ZQ<~-yQD82rC}J#+Bg`w zh$Ujmx5{>sQgSk%yUGHeDlapNg6Tl%!qQQvdA zBdnDBNOglqTQONrgDB1v5sD{JwmV4X^5{1!Dw1c!!ix6HrP9(K&N-+c6B9e^f3G{3 zBvKP8jVrQ0_k}^B`mx8(#yN zytL~mOcxQcLMj$Tv}AuU;ov=X>>##m+o7DWnM4}p+A4ao-bW2n<|F62^oO*k)#z%H zo!q+VR7Rf5NcG|&DSc}@EilpD3CvB+ z==@B3aWu7hB&w7;)1|3N(li{>!;oBlPWrzo{WnzK;v6C`DaF66Xk6DNjs^D!CTG`W zO`q8|C;LxVpB-$cp&a7e^9F7o#mtmaxUiyu2Od$G)7h!5%FEjCkdCDzBiEN_l*&W^ zuPbYFkX*ASTna^5vi{zipq1ZM-728x6$eK3nqqLwc6*I4*0dJd4DJ z=#iIaK-sMbiiM=C6^4wrEn^*p?aCNivX9!*W?Ad|0|UXav_bZuF!$xyK%OneGS{Qh zr>?9YS=3tVy7uxA#*9VKlkuoE%Q$Dxxq8q=K|xZSM76I+8}P!-Ge1e{n{U27p>1wq zhXjFHJvna3hVV#KM4w2;Q}n1A!`2;7k|4H@r6UJ7_47|4MIVgxJUKb~&}H`WyRUo@ zAAR;m@jE|p87|h}Wsu9tKX?DLCP*KQ9K8>+`hYTg-=1jZuK^pgM|%x8QzM^UwN^z& z+8GJOFjv~DflxvP8%CO_VX}mYss4zFjgbVyLrhQ2D_ZKFqlYE9Cz>fHfvu~^zht5S zFW5#b8m1Af*Ysx2AEKErtMvlmeCR{1f#8O=*8F~`z8O1rY`fap& zL>k&i%RMHuDdj_Sy&6Um9A>j7R@T-5Gl-^JmoXY6pO^(Y5;Rj?J!$BBa_$r&5vXc( zJVC*kv5MvpsoRwxF*B1#yS|QmDJwzySdoL_coe2NLS!7q(Z$w87-@Q1g48rt*H+O5 z6|_vfV|XP^*eyI0CzDJjwr$(?BoiAG+qUgw$F^3`S1S48Wt%rB7hdz&{A4f#YCnqmr%F}blw4Z>I_(BkOT!Va z^*Wc*s_rJFPs^{C9)=cDD{YY}6$KL8zK(IOTn{6$&`n3&Q|Wh#U;jkX7GId*Sjb?* zJR<~&p$WL`tAc`+sVhc}^X%iPK;DWM~uVtLpz>aw?ZcQ=sc+I>B#D5 z-VSEueLKXB0cyU~0n>pCbzKj69AyCd4EjE|jwsN6HFP23upDrvuD(Lf&-O)JF&;jc z5LNOjv5nasZz^t{uBi9!Qc32IpkxLRQ)J)CtiT^Hd_yZ4d(2Q2Jylp-F@r_K}*3c2oXs83lQ?l~`-Fm+n-!Ji@SDGC#zkqI+Z zq%^(_3o-oHmT;2=!);F=0|wqje!@!otiy^NvW!oCnigOmZYFGw&O9DSeLHrMPk&}c zn;BPURL{nIqk#qOK+7y8Egdp{SLqOi96Unp|NYP8UIl7a-YC}ldL2)_3n}W9Oc3ol z0Db%7KGmwF(JOOLo{RWpgy^P*x%(}-X2*S|3!hm1KEno@^+)HutCII^>Wc0j;sc{75PjG%$Uv2Gd5z++9(pM=~?Dy?2o zOO$b5Nr03N1~OM$gMq5{D4KV(BtcbtVpM})PLw{l*#qPrQ&|=6q>b{xmqs}z3KtGB zREk@~01IWLgFx}+mTu;{J|9}Im*8R)_#r{RU@)3|U_lD}^+$+!9tUDLyYj;PxpO+` zuh^1g$7%pYqMsunEs*bWj9Wi(K>5uLS0(#g-_Eb>FOozIu5g!9qIVqZdS3oGRc3R2 zb8+a81toWlf#KAtLbL;1fT^EVL_lz!lySi1V|%5Rs90iR106p*z@BK_X}LMeA#2Q3 zI@Un*?Y3i+=RS@wTiUE&`%&8bC@h)kCW@G);~g+>=X9PO!!}opijkNy`XQrhj-RAn zTZCv5qBQPp2|>bnm8r9)M$~2^l`UY)V@DwsfGWmyy;i?HzD9^KX(X+#p|QxvmNhw^ zpx^JjM%{ThiY@Ycy^=QtVz5O*Xg)s*4WY746wCEQMfrlc{v-fOh3Y{dacPfYU&7g# z&T54Y?a0Byy2vHB2i?J4`AaGuSqUcn&S>#l?6QcWMh-NnJU+rWx z)tpiNgoHG~#AjDIhKm640&-LpNQ4&E&hYH=pS+KoUM@Y4{GO0B!9M_pp=$UKKt2D6 zJaJI+N9)Xb6q;k<&B60Oq6Vzx`V5ym`w`43vbxe(93@b$T{q~H1qR-*LSyyKv#rQ?d$dN7NPw$H#Pm#%VZYT1S{;Up7pKpx1 zch$Z=sTKG=zjwCAqsL}^+TKwn-q`ekda;MtcEbk`^ZX(KW-QpV%!3|P(I@lp9>@wT zL~#=bq=J=H9wWrtsStK^Zt7yrqpuP{c^9foDx=4i0U;0`z_8A3B^z;SL5yOD+Wowo zgPbwW2@5<}Bk(Uq8Dq1RmY{(RT$`2RAKPq*BlrZ3Y#GSq1PHrlqn{UlP|B=Obwi1< z-NiH?4qmOgDgC>{70E+WA^5~uOFL~;siW@2vEKb6H47q0Bw~B*JJP>3k-cqlUj$1K13}C_dlu0GAB=wOK1S1GNJU4@B9#@iI5ut%$A^V=;0v@_D zFKr=z9W;5I?Qg;WqT;eL6M>uh@{1M?!RD-|Y;?)zlCuEW;(Jr#8jHmN>dbh+&iVyA zS{Dw$FZ{F{>EzbSB(l7xh5_$SqZ%V`5Sfs^RsapaFGd_M>II6J2=@FycZ`g?Cplt} zNe;CU$9aGMg|;jRVrxJ_VJ=dc`)3F(S}-NL^r&R+kSIahL+OVVe1YT$31$XbW8q91 zZ&r4;ga&_&a^sE@H1ZR9(K|wt^a6FY5XAia_meYC!MT*j?F{^L-`y3MlM|^l`sL)- zCje5CX9G^Uf}sY@glmDgGNN(2jou&O5QrY4c}z||IR_UWYqZDk(W^AtqFEU4Slj{- zJ8Y>OX}!4|7!u_8>scEzY6jBcz9vJBWZXDN1;rlLPm0gqUN2x7TQfQ&A67~E1piLO zEu@r1jei9u230Cmx+M9maX$CyC!&PnSH8RfY$cCuP*hR5CuX zQ(p?@RtMt1459j?e^F`VR?pnh^$lP>WV!#EAHYa{SPn-4|Ei*E-m~{Z4K*BZ%Q}R| zy5Odnigd~257rK5NzNP5=H*B@tufAuj8hY4O&a!+9=qjkbo`l6zM+6a3qJ4x)uVG- zYm^jD6(({z?8Brd!)P|`gm^JxUgi;KCd||tb4PHDs?#x~AjuCivB^1EXeTQ3?hv(5 zB6hoNZ@fe(1&`rVdK+UVLhSY87_b(`#gg#jCfP?3C4Lb$bgHU|Ga}{3BR6B7wn^t! zjkww;JIvcsnk)MV<@}#MLDFKnKhRk7$9a~&dYXTdv%_h~(>&_4?W)v%?lUG z%_KH6?+V~b<~(BW$y;OfRC@(boykKx->5l6*R!UDs$22Qm4MfjkUbaz)F!$RocRTj zszs&h-%+C?Mr0e)<|PlrPMPY?aUsH>nU%t^mh9|J5b+!5r9lwtY6if?bv@gmc+EvVd3$VK)4YlXZvLcE z{h+#v@GsLqAd$UBzD%0Bnm^$UEOB1A}t)AIBMPo3p5yO@4rNhUNxMKW5_8A8@4Z>i)czGx#=#fD^?(5F#PY)Cc~ z&F|1fS}M6aj#D&imXVZD^@^`8%~w8+mqjx+mFHD~1t9h=R_@g9`4r&_`*G+l zR^0Gn`aTMi+_Y8Z{VPMu=8EEfdy9oge8Yqx2M`oX^CLp!d-m^a&!Hu;#Spsot9N0P zJW3g)QqU!$QT+dAwm(wNZc>(YV}0B22XRKAZTq*!uRiwHdIq+)-0m823lZPa5W{^E z?!pZ|u&I3Q4o2js={))5R%%1#l69zMhJ^l%&n1sqD{0~7T zgG!ePx4m33M|KF+IaLZR=_<0w${QBlv=9LR@j#nq*elVbNzRbC?>nf_1_~(7gPq-3 zQP3T(g+OC@=8`?2{pU%G1aBT^F-$>>V?`i_I|@6zpGqObH0O#WH|vZ_mXzEaf5Z$U z67Upmr$}i=j4dr`NBg}NNlZRq_A>QLE~e5eEDFX!T+b{8%L$D-WIp~5*;M#D(Hfqc z%x+@eWb{jJ0r6foshXq~OK37k+8bp?ER3Ql0t%EO#AH!vC1xzl_mBWrA-~#Fm7Y^2 zZ(|@S&fn>umxpx>fFaGdIllP_SnJu}G1}wCyeF--rd|sH`*OQB%pL5dPoCCibU_=_ zq%b;VS*r{l6Pg7kpYLl}@!;>xFQe>h;f6^4Tx3)JS<>|8%*w6O)HnD!ser9?E2#F8 zEqx^GQ24}%n`4HrxjY~p02^9HEg;MFWA?=%&Wl@w+W_Pg{#i0K!WZ@*cQ+oYkA zrH~GVu0XL+e#myKO3zBxR&G=-VtW*_3X0C9%1(P0#OHJAJbSBwo#b&Oye}wJb3r|e z3M3@Pg~lqYyB_HBT*O4sJ8xD$X=oVN)^M#li&`p{M#dmx%YGaP4_u4Avro^Fpa-#QQMX_bN0=OZKo4kYi!uh&6NpXoJ z$;V}j1sbgB4_`|U_VfTAe$stGO}^ZujhdRZ9BKx4O_8s07S{MtgKye5gizUgJo10x zmn1z$>W5xxhY*Njqj}~-B+{#b5zt>YD3xBg$25CM?ozi9sbcY*d-08x5({fS z4j~C=ivTWR1M+;fv_x_|u;o%0OFz}F3fNOWfJGvlQBc}RK6OM*CEkK(l-OkW@se3( zzoP72yl>*R<7O^{sqy9kuxk10bYs6q^yWrk%6cL*iH#aR@qOLqm~-~g$W>Tk$%O_W z)@3ySaL0&aI$m@sSao1O_SJ}rX5*VR5YFROu*Vn8vxFoBNN1P?w*P{emDEIDRs!%ynA+~Cp4h}$)dy+Wl3cYNHe(iqcD+-Y^1$u;u_?kL6tS?nj%E?>S-_Fi~ ztJl<&|5{58{f;DqvWKfSPZQT{%!ql+FGmeSzDSih%umcGuDpkejcBo|O03+LQ>mtE zq4pHyPf7dIAGQqG{FGr$#jWM6h#q_ zdZp9vH;0kLn~mH0W88||TRU6j4%B6@o7fwgldB!a?effaw5vDxhn}ld&bOn_h<6-| z=Kq)+>xee+&BZ2%2SSY=UU*rg-|jxYf1U~HwYqk2ec&aMf)rAd1(QlDMH@21HzP^; z++{i**Gih8J1_gLxcHkNyDkT3C_dkH*ON$3?(lifMy7|RgCVUFYtmN0ALgd&SvGkX z-0=9lH#=_b4!3t`T&-Pz_}gC%#Ml}(eU_k%ka0W?q-7W~9_kPw1I%)Xb=vi41q@g!e*dW|r`N9zUfHrqnFfe50->o};?crJ> zk{shld7yx@Hi~_j;}gm$sae^5{cpI;RN!X_)U6L}-%$<2nJ0!2l!pF})}e^c8i`SWK{e;r*OZK>2q zktk5#!b4EP6d4Qa;IuC1Y#M95Um?v{%RL0eoahsK=XtO@DfX1oTaC)v&YIZViv3WK zqQl*w+_As`zU*3-lIrGdA>ly~AXr#Gs{a0cF!%mZuCX0{>b_J!;Y81VItgx+kZ!=J z1Uja~-k#R{v>8NI_ERjGA#ZaWz3hai<2<=U+a9$gvXx?^SU`Wa=|n2eD0xFGPz&VE zR~SI?sLGhR_DOu)_)0k~PAaK02SJSF&?bzp6r2F?V1Ax@NF;Gpw7^*^{L1AL{fpFu z%31x9@!RykXY^({*CHGu$v{jx@ke4>b*hBsjfy}pTs=1}Rm3-sclC~L4| zxDy!aIo4e$O7dB0S*aM@a2!-Fl?4L)xg2_5VjmB*lm zHV9=npGgj6r^{jo{+*pYS{_pfaidk=oja+Scd08baimX_3h6n!i zJ~0jA!N;{!@-X@(_e=A0nt{B-p|62NXIXSD$2(QOQjKpHWdxtbdxY!EBO+#SW`Xv9 zxd1;K1_96zZ}1=|Vr)+r-CvE+SjAq_+-$&qe@`tUJn^0<=} zUP8irYiDCT+8*-xq_E?dN}{`0#`vnb*7-(-#t<{PYOM{1`PC$HfOXn7Zz?fd&TWaN zo`kw~Fs1gTv3uG&YI7NfC3Wop>8c&){C+~2@hN*k9csP<-iJ+7eX%f~?09;;>#yje zS}UCgFt~Tw){wSGL9W)c(L*8h_!h7FIbSI*MohT`Yi4>>e3DONb{4W_Da(7ImaEZ? zEX8j1hzR#8yyLY)l4}9-J>xgI*H%hBHAMd~n?>mmK|!%1NoPSLaui^pCLx)i)(b6e zave5;6JBOkPR@DX1^OQIr&M&`Apg;$thw%?q2eV=^|3IqKG%ep7(m_`Ria&rAk;*vr^S;43o#BcZDG6&MqpM z6Sb6>!=4mbsXQgu;N&eyYihk^JrM+%Nem z_J1)->oQxB3_Vy+v+_FjYnK1Xue!6QDQEi~qQW76?@Ru!E9K9lv%3-i0&%n7hSXo< zyxXvd=@CQEH@;Hcm9Kn%L7#a0dLA!ZNAR89KlQ%q`YBHolZWvtkQ%ty43GG{J3sBv zm3ZD}+??3*W3}*$=ytf%d0<9bAQQio>K)yfex0dcE|}E8r~f^jZ&056*{(A5 ziG|QTDFwJmX$NLsP=DFG!2=C^^GDZkqzKa`>Nu+;6=}?*dbb8Gt|$%ckd=+dLg02r z>kKLP8<0!Y^pWF&G-G`u?^*n zT*QSC!~;e129>CpkrQ27PH8|b{s627ctAgqAuO{tEasTEGCMO% z?ZH-<^m*$~=C(`#hZ1h^7+6~nxf4|`5-bAa@v3?`{RBeW3zq14RrR?9|A?Pm&!C^T zSjZoLcU)WxunOu6W?|I+G0T4DjC^5FaXk$EmvVys$$#`gWPTQ_uVm_);*{;VrHZGt zVnA5fZ#$Kh%J}Fy^K)X=9ZlC(+L6kqkYBmZessIJ2 z1;xQuEWG~&tFSIp+G774DTg6Q^vgNO^0rMFG*oOPe-uN-fpnpy?N4}dp(s2k(Qx-> z&r+R3B==C8u+$`%t*dF>;6Ooy-%6wW`{giLLqwcO#cCouPNWgStAD*s@U_>cOrC=< z-!$(<@--wQf2U1K_@))0qO~UCWMRvRRQ6W^xA3&{2@Pdaw2&D~vy9D1dtr~{52qnC zSDWf2YZI%tq|MTf`b5wOxX5sJQIBZ6^o|u|QeyJ6jf2PA6>r`vNa73h0OcXDwKzL{onoc|@g*simM2E_85}`fw-`!P|FqjY>Z}e#N?hM9t!&UhRb**>-TBUHl>Ns% zTj~mbT^!%UR2aM$!lmTIJU_csoj7d-SnIHZ?7Z=4C0ASDnKqVpeG}xf0#7xbX7=eX z;$$RTBU9+JqO9S9CW{mON;%q|0whwYD#IMTlnOIzZPc>LxJ3o%ll}pBht-pHY;WKMZLW(Y~kr z=P5{B!kZ<#vzp!*J(>z{Y&Gs-mdJp9|1J0{ey+zjOQDbH#Pxw|Im@9d|6}qdXG=AK z%lbqJ!@03}`dpMcy)RD$x^7MLA88|%HF4H=q*P^xD`)GIg8T;qotJcPG2aX4m-K7I zkYUVGkLf`dQ7RF^&TQ;*G58<4>)n4I@ejwL@R|w@zX`B$l5V zRt6mH5iX{B@>1(9Q&Xe2(kP)Au?FjJ>`57$;f&}=TNmjL)f9$Y8fuQrM}N~{@SUJ2 zIero)CpM|Sv@Tm#2ofL`xj*r-u|?KLJ?07sooT{8XFRR#_YVB4_r-S@GSV$Fn#rsL z2Vt2=FTMV{Y-0;jT~+E?`(a`6Y%=7o6cLrIVKeS-ZjbDm_?&VRi3W-M_?OSs0T zv3Lm!(YRm!mJ!R&?))Ah!6=k32r3$e_iDy;Se!Z|f|IgBhk!a+nUFYrjtY<%kPQ3ojO0Kj=Mi z7X`I#I1@)mQi>Y~KR8;XW?4y+E>+Gc6=b}J{C3xsmw(0xUtpt##>J7aGmcqk5QQ8T z!VL2HVF;?1nq{}cI}ju(|8h(M#4EC{njQDzDIOaq?Ehs>I_}9{NUQ8GsGTgC6m8N5 zo5)rY=VVkAGwhH-yN-eqdH=ARhn97d{A3+RIB3Fa%iYQa>ud}~1w(z*-wQan5*0#7wv3aCErqk6)q~0-I@Q%n49sJi zK%vn`fC`RIeJY-ZJt5Py*5a1|b0^7{f{pP0Ma5=!u=v#+Pz)O#KO8e&PxkA`Gs|gf z8N z(E!_^5SPneOjb<0O0gDm@SNtRnvR#We80=elb*z);ewy=NEE7(ycn|* zxb#zMPjQ9pRbRNjBnFBv`b=7>xd0KoeMLw)TCR(9TJP_CQTq8|VKVv7G%iX<9@NRR z5FA5(e|HX&JSXF4k70n#7t zF=c@12aidWKT+X^bZ2;F2qC(50Zz8ANq-5WTBCxaNZf;mVxRT2hdGj>Da9bYiNXq> zIw~{fY5{XNd$-nY1ot9v9`_!ct*t=^P4&dXA`VrOgxq;BoYT?g(gKQ%c2-c0+S%Uy zflv+#ivPj|JY{>4=0?k5(kKesYPIOZIDfW-x2d)DsEaPifIpY*1+@p@Ce_nBdh2U& z&J|?=C@gC!-l-qYpp3d&Q2ob6A5+KpZ&a$Aa3cXEXXe_&vpe0t2FEw+aa_hu__)D8 zCwg^e4F3#wW9uc|GnOX7P~F_8?ZKZWM}Rzr6RE`X8n&r)SFR9P?QxR4=i<1ylOF65 zu}NXiiqG)O8zY-RHO%r5)yM#wxVtHf6qaz8nFm`#L!JZnn@A4zhc0{9qlr=)!| zu+!l?gyhIC*P29XI+}IS^-gjZOU-;6Gz;UVEs1$aKmJ+sM5x9x&1FnRZjU~V^Uqze zeJPPi9RZRi`1|6M0dQc=BR|vUXNu3u45n4`wIzg#9I!m;UBG`%Rrpc@e<)||5jMQn-BV=R1>e4p`_l-y0^QJJIf4P{zjuB z&pf{299=K+b~N-u&>#2Gs6E%X+8-mJ`V-T=D&Ol@w<#sX7kZG-?B$c?bH~^WEpRR4 z=z1Ol`h96h%*T%P@b;k2KQc_iGhfca*KCe8)eH`@6;6h`x{OHNA^Bk9!kW z?%$iQT}AVjdP24r;Ue(d7O%Q6Y&)$GBS7#b1fAaro(XIRN_4#fX6%NH zLD(V>C*B-8i9L>x{LVaoDpK;_vN3=cpS-ILIVpT6*2y^6)iO2xDcKJeUQfPV_%oaF zK_{wq3lzRe5BKZSm9f+H&z8MuYlqd}Qc z4;M-7R2Ww@d(o&rXv^Sv<7SLS2=-rdYz0!E`H$CES+_sEc-CEt`PHeX{(f%p*p-`l z;QzKB{2fUuH>DR)QQdhw$UrK|z3THKLeP(faWS+g@XD-x#*3on{YLWCRq=tq(2dPl zMXETm%Q)jbakYmqRI>}p>4f7L(hC=OpIGkm{PZ2l`1tej^!u5bA0=f6{OKU)jib=# zzTjz)MmLs2GWW60_XDM~N@0*fSAAH*_iUlHp{p?u=Rb*^mnUZj2bDvB;nkmJne9N| zo|nI8ThYGo01%?}ljP3q#Ptn9*JW)(<7$Xb)dB9X1 zOhSrw)KRg^j`>Un{O9`#o!80c$e%(>9y{IL-(JTlTM;vtGP`WP&uXoE)>r+ezV{4v z2P3ynqgs(qDXw1M^soW;6sdDa-gbxFp1N-Li#zvQ zZZa4^*Q*mbQIA{oz`<9vCX4)`7hx}y9IqL)Ckh_|cc`r==$fGC#j_hS?Fhurx%HcW z>%IgG9e3P~*|+pwdj(g0DthtF8{JYm&gkb%U#bnuBjEUq4`z+54?@p$3ACNfR|%}6-g?irG?;gPKD#tuz$P(uc;+jETN#j4EqIa z-}ax-%Ui)Y-A|Cc0$YskLeJt}$9T);f?)z3SkOMtkSosNUcNx}otj@5$6|%y=6ukgm-#Y1L07Kb-)d6Wu4lGE4sRz@Z0Byzo;PJQTj4ae zPiWeXM~2IHp-l+nOdNkv;bASp^NOXe9@|QUld>bU?(%%`b3o3hImeqLO76v~gAH3x z9_I;HlV6l;5saZ=iV1m9ecezRJpuQ{>5{BSaEbBW7-E;|i-99G>$|uR?`@wE?`A)q z&lj}TmkJc5K}!LT>p^3Dmn+^fDmp~I2EW^EXC{{|P}A#|xpu|QbPbBXX0Ijxvu>vA zHMjOh==_pe57tcdb`)awE;sJZMEA#Q>&fN%H7&W>m-l;NEJw$2%T{=f%u+2A_wz`& z^&WQZvkSAZ+Z(4%iES*+I;(Qqm2daE-{EVnt?7c-=k0~nIG1=#=PB3W z)zg=f&{(YYmQHWP)#rUs=DZ70mFs;u<8habp$ood?M6&H!<{F)X?+-PdHZ@6V^Opm zmgRNU_u;?EwT|jpxwLcPPI|F^qfkb*@eKKPlhteNYX?i8!GH1y%^$e@(K55~2<$tv z?epJ$5<_jd;fu9#B(SVlE~f;TP`p{f;7T}U?~rEga}Y$mW!gpJe_n)S4}g`3CM7V$ z^73RD$~?7vK1@6&uVeULl01cOcVPIpfeUyaEVk|)9D!AM+DjZM!xwIt(x`9falMlf z*j#nqytje^d!j3JUy<2IZ@M;T1>GQ|Y z`YQW2v^P)2;eS}@2y=uWE_=cntM zuL}0P*}m!X{F5K^qs5Vi|0!yDSIKl9VjF*WdL+5$mU+j~wx4ZvdyuBip&4iYzhmKl z5AxqdUj0Y*>bgLvZx6WJ=}h;JnRbltO@@fm89vuEzAvDO+JlEjAlHn~PoMKuhT#Lm zz`yR2hH>cf`EDlB|Km!IdWyx2NLsRDRnX8{aCltM*!ljpiRjIV$9dw6xZmI&mU9qXXQsSXTW!7Sl(7}4 z=6%kbd4%6f_X)%6n)j`tJ4y>pvlF~#%^O+EdQ$`uDHUVmH4^xGKCvB{!`t0*=`}X9 z_4pog4p}pdqgxNIsrdQ03F{Er?f9%Gz~K3}@d2Al4eqmZ+rGLArNkpRq8%DuJeBYKG|;8c zlZ|`WtZp{AwFr3FVSBY1u)Om`e3+klTEVGF&t>|2fZBNOR|77zbP7I*U_5#`o($&g zMsw^GlcemaEc@UvTx>)Lcs`t6uA2(H71>Vk{}7E5dt2xbaDC~zZRK-4V!58z^JLk2 zvcbqUApX1U_vm%{J^L<9wthqPLZD3;kU)@>YX>u;jIJjm3|y=SH6St-k%6=n@4{^?J$^v-4E}!;-?Mr z!xJBNBx)=ECAx}1p376Mj@B%i=U;E0@6Sa*3EvMI8W{>A1OhFd$CeMUocHjKn~hFEr%a;_x1jI(^!VF_KgZ8Klscbs{a z7c%g`E||j{*!?vSo{oaA{@Zt(2mcS&$36~V38e`eHneFl8)kk=F3x7~cT)+P-In8Y za2u!zXtof3!k=NgH(hhJ?nX8Y&fl=2)9U)F8D7@SFi z)Mh={-TAQHX zUCY+i#|_iJq&)h^Uu}kc&plgv_`#2CndV+V^_|ts?wc`qZgf_awy9rkUp8Ggp#qHm zO@eHFc4w?D*L$Vw%}1TUv!C)lA5BLLxen`kIp|cyu=9H3yOztmTgZj607zDiG~MyP z9wzv!+W7V~A%Z*bX$JWEz#B=GbE!}GcFqhuJ7?*SO_{E zUmplNKHe#Q9kQlfwdl16#P%G%KlN)^CjCE8)6HjZy^v5?(#)`znDegjwrczKqx)6{ z+CEmR*PU!i(Y-%(Iq(G05RuA5G)d$$t4aaAMs}mm~z|VDu;96kY zH}FFPsc>cn&-aGL?zKhNe_XAm@3#9*_HB;g3e0&%@A~r0{^o3mbb-_ zWvQay+oo+|70F|_OZCwsl}@{V@@Z+BKXQ*o-v<^!GbU^D*}>M&lHd3)I)98LFc}S# z6ujTqH=Srd`R6(u!1uIlHXjE`AU!08a-i+ClpzE$G=&ItL#1h(` zfHE3^OCBkA%^RCF6L>g#sx4fNe|5^JO5upJWr@&bGPp&WSyAFGKj1cyS|ODxb1En3 z_-k1HR>aUY_;%WnFT~~Ohi8&I-8vJlOtOVt2u0ksSAv8HmD}Ebr?^+j#)F>W#O!p=R7WC#SFdj z#s@J+<-BmF*S01FvX^|HZC~aE@P_W&6pxhVIf~j&5SfGr?fhRZz!Z-8mXTE>myRP$ zO@}#MqU0?ydf;K81EKc2mo7bSNhPHze6c|kt4{%o^+4|NiqV3|a`%l9Eb8z9s8$Yd zI=H$Z?x@JLg7Bkrhqt-&H(g&u zLYF=2@ERJ;(Q{h`?FJ~8j3*u{!3YEnTuUfJ2MRq?f#O|nj(qPfOPp&7yn}rI-QtF{ z$;R(BpvNAu?AWUF=H+}pvpidAb4GBr>HcmA@id3b^FDq)jr3p#=Rg}sCGu}b4eWPx z=PBl!MhMmh=X4}u#h(}8g)oTIAOA-G4u7p?s`Hze3&I~Tv0q~vJ~cp+xjM@bXD}>2 zTlpnIRwyv5w^F>o)U_X|#NQevL(JBfR%xS84;tSe}}~CNB84nn-0Csm~DtIz|g@$3SXcydYX4pIF`oEjCQ&~ zDn_@#bzK_c@A*nw;XE@7sb*i+UbVBs|6H9&$5(A1^njdVn=;hN+n11&NHol7yJ8b! z;OGk6bak24_2k~47dsy*4~dQU{dxg`9UQubzfw=)1gPKk1}4Vm(s8D_NPb;>uSbVU zf>5SHgh?_1qs20tuSA+<1=CxH^q+@ElXD`w)uDMiJli9Y=D;<$4Bw34Zwju8FH7#Ge{i1ss~ph6m(7 zHc6SVL=?y$4DKL4Piicc=GwS?#vNj?(qf@2b0&%0;GNm}b}tcdH@d=EQnClqZsont zab@F)#UfC1X!)Hb)BhXA@{C4;<`<6`F>wVh^Sp`+7A}~hzKW~?{e)#_ZZPoy>+6?Y zK-T)Q-O;cmoCHL<=-sejl?m=hIme+j#LY2Ue(W_oYbH|ZnBVX3;q?-tSS0?+G@T0H z%7i5Y*x{8hT@vQ!7&-Ut)hWsU1Y-}Vs^lj8oz@DWf9u2$RO0b3XzHIUhoHHV)Hsdy zBU0_3yLpN_c&g+lYdt(1mk9}1Sur_uGp$BzrV_)`3_j90(HMU|qytAjz`_e9OSSs( zw+%iKHVE{_%t$g+n&?j4JBgY?SY}Kp$Cx-Q;)noQsJb;jX>aH?&w7+-3e%{Wyr(G? z;HYmcIwbw-vO6gG=a?C+n?<>iF^y6K7Jj*?cY)c9&Xg=RWv9lNl3szCIvPtgdaIwZ za%>!=fr}@Q2?_#TJw&?-f4uAelmK$En>rCt#z3finX*CN7~EB$H0AXREM9?3SlKd7 zA*8VYp3k}}Wl#<=RU3H=<8kIts_8kZBfp5)5RIqvwlVm@JQM{ryMDU;`UPnpw3Y-7 z@j+CZp!Ku#)JxegyF9_4xIuUMZU;fR-3hj8t$iDZQ0h>&q1cHQnAc>F%ci3 z3W{IyTiB%cQ* z=M5oVrTA;Xk0ehWp#fMEq7j~~{602=^~dE?Ybq8Q!NnU%_!~9zE_v>!h%gso3Jz2i zX(!2>s^+`xXis|> zbccbUu_yyQF07(Lw=5a&sUuNy@B|_M6-~;~pm{54kVjeD6)^Xtvg`1M?HJr*pKr4y zl;Kw8ju*C78YbY;^*xTN?%z6v7fZei$Q@}!YPnYXq_A+x&Bk#m5gtydYa`6g3w9y; z#~4dj;r63tNR2&;fXE?GGirTVciY=xA{-r9V;8Oebv>{kc{00ZOsdye1;C zC%;nhmnlb@+`{J7O+dPe*$!lU$qgy_^On^Bb=9it#NC7d;s+DuUM;}y#hUW++d8jR z%FJfC-_hlts0!})ZIh!vm__0-z)Cb0EyVgtEre9pmcZOKyw8rGR5)$O{F18R{yC}y zN1U&kH(6zLF|hbZ#;D^1^*`yRt3t^9|I^v1DHq0aNq=TyoY~~+O}^6MW&i%R zR&lvpOJO#>TtMAWwcP0p=2oSK11$tpC?%)?!W`m^1V7z+16e)(M7;cCy<*!#&3nC8 z4@ze3*^iWVR2a5YuoZ5Fx*U;;w|&x_89gN4C*6b}qpfIjyhopQn#}hD%tV;ru{JT| zsi7~{aSuM0#E#sz_*^S+rT+KXsqp1U$;`j*K32es<(|;nl$yVmXQ<>rSn>s_rxE*h zrO({a0fLe&7w9aT&_zReWL&BEy&9Y^T-XIleZreHtzqI_nU~ePFf-$#eOvuT9-MKW zBx!t!U=@E<)ek7Kr(4M1O=cadWhAWcv9%dv& z^7G(C*8|jT@X=y<35Lbc(ati`h>cZu$Y_YND8;>XI4lh4OUPG}LvMoINd+Wr$We7^ zX#9&ej6xebl5o=4FR1r9D~YEHg_4-|w8pq6Ui=)-3_!MSb_{Utd6Ovw&b(QpNB;;p zJT``vqK&WEY|Y5*fnLH71>OVcT$a+k*3*QG6|8fEF;cq!dYnE6Ls{tAINAkh{FJTn z&_~SfakhG>wSnqc@s?#yH~sO$N*ac&G)D=cpH`g6$*W2Y#kg3^TT)Q0ZF@)c3f*Dn z+C$Q}f|ez>it6TjL%&oXiFI?Dv>%gfRaqDNTbs;P4m1{J*Jqo=*uUQ_efLb`PO}+k zV=#=2xP=lH;SFe0$p`>y>lK*%?L-;htUL@+sJ~|B@cCXX{=u)-HonKbsaDN_Wijb~ zvSas{=kNsvs8ou)>5_4*Un7AfA>ZRi0HF5&aP^Mid9KeFXp_cln#O9H#y2%rv2EMt$=>^SuIrrtx99u4o;5RT*35Lc!j(~$4TaqcGOIn>!kur)NjLM4 zjF&rSC0{RpVodmxKcXT@KN!1+DB+sSNQN2DsIp99sln*3snUh-(yVs!4vG^u0RieW z(SV%1Zrsu;jwrrJrvPia0B(ML))!H|gE7ne*VQWd2#M*8F7m*@Z)5^y64q~;1;>39 z3Gr6M-7~RWieoR9#?xO&Y5P8+gR(z_4U1IjNib0CQL}CE6MRGiQMwOp%&4@M=bjdRqV>aD@K%RhwGhx3P)Y;PEm~fibi#Z61PaLTaBsPKA3TnF$kr6xWRkQT# zYM)!IWH|1c%j;*o_`91_=kdidOy3*n@B>|^)iVd<)s&z{xSo?gwq*!2v)sys57jA! zD$x3{3G283@;}XaiJ@Zafq7S+k=8J?lYg8c3u~muLxlZSJ8iCpCtVdTG)ad|?tcXS zF>d!IT%q3GgWW4FPG&4qp>YN01n=I~Pn}7}Zn@ezpyT9GtX?P6_iXF_Me*c;S)X(wLpg2SWz6-8TZ^USqNe1IHD4o^m%4by z(@liu*d7oIQ4Vt8u01GMNHwPEzD9g0z^gx23mt#BEStN@XobpLe*j`u_3#qu-MwbEdugW zfWLW|dV1)Xya_koIk5Knu=HK;8=T~8K!+9sxhZ$mRyeNZ!A(iJ3Yj# zI~5#=({FvNmar5v0hUU1Vt^}K;(jX?N%T1Mzse$t>ici0e`}0?AD{JCu6j5-oJ#vZ z7Wdca(yedcyleO&X`~d2lOiMsQ_Sa%1FW>c{6xtPHq=jrpS)lwIbg8Th)$bL8%pEW3~ zQu}Bqs=|*%s3h65=BBkukW{_=q?xg~Fi=^@4sUHS4O=%*+__zO`gA70KF{+FNGF!m zgVPes`ETkQn#pyE%h!lza~w#fk_z9^<*MutMj)^3eg$&oAk96@hE?tewJ=}kGl@DO zL?c~uDXcPy#;4?y5MP^`H$zceph=ff)Hf@99=X~F8%!bMWKwPqpT2`Fx<_UC&i!YZ zp0visf1Vg+vb~Iedt4+N=S40+=DPgG|&KTEHXij3< z_fnVr$OphC`9}Vwo-rRQOfGlD)XAFL-PIi9NE^%JpXFkj@yL|268naV$%#zW?MhZN z^n`rngaUha*mnM{x1Nr-mwEPoDcqwa=I1|Q|DRgm^T(a=5E`mGBoe3dUzsKAGC16R z!$qoTEVOp|NjH?G13*~Zra{YwbwK%s0S3)V6$+JVpeXAGP|TtrMeq$g+5jJj`WcYG@GoEMM*v`buyd_YQi zFgqGjC8<30SE4jJBEqJwZQZOF%e+6>XOW(j!0wtyZt$rPE3vwRyeO+Nwr4d=!DLRe zL?R-^L>kVt%g`Z1bx#C8O%VtT`$gy0T09n7dV$OE>cdK51T5lC|@W}KtKq;`ebUN^ldxsHho3hyxUm|L$S)$+*RPr*} z%kGoH9`nBVbiX5ADZU8eTevOhrio+#Kny#rw?B-(qIcgj#&hZ?t;tbrb~juO^jK{vps^ahQ0!5rmhf%GwYxn{gAngkj5ho%|y^WRZ@ z0W&3PwTB2KS(z%ZLXynzQ8frfKq_YSpGXf9wfbYM;8} zX%VGwWd>+1&}u~Tu|{x1Qn$2oNM|TUhBt-s$SFQ@1}=XRI%v@iQo`1A!&+U7d$HKH zW29D$faL-TfvJF>`s3mT@J_Z7u*kmaw#S}|K!JIlbut@UMGI8j#S3OP;=WmwCeQ-J z+D{WMprH`Nsp+}|w^#a~7JA--`tl`$#){hJH%M(Rx6J4P(_Q+}1=4PyQ%IC z$z(amW3s)@8?`S;+;3lCW#NwGkJST2qIa&X8nr{l&eWsPH;z^Vj^FD54&k8YJv_N`j}We6D@ZnUQ0U# zPd%4L%Q;>07L>p@;!Fi*^Kz*~7_#b`7@Vm`C=makgif5qO*`L|vQ-GZ-7Jk$MACPC zp3D*Y)OpOr>2PQ`{r+U;Qc+t1Pzay${!imQV>aMplaF3l267e#Zp znbbK{7XL|}@KRFDHZw*5J|(t2f#fTz%1R@}A2gcIzRIa?z|cu6U)^};c)=Do1ZBB&sw0jaPW zf-R=}y*ryJ(X%#nE|h|`!+EO6!FFY!=1W+ru4$_96CW@itFK5I5ABgpxg0P5BRZ=r zAEOEQihbi{dkUbYIOJ{z63A#b{{WWR>^w6E&JE0(I4-LKS9+S^RjQgDId=IXXNqL> zKkw1)Izg|j$OKrbRJmJYbiTNEMp%2lXf(M$U|Zu5Hs&B*yIPd~D92%-?vKLnMz4sC zD=XnwXHGi3Cd+WioMzwPjY9FpMiXHTl@qkk#s(Uqk9jbA-1*ZEZu_S^#nES7XrBc9 zwHQC@sQ;f3>-7nM=W0@c(+LPqtFSN;6O8a zZjPlY6|B!fNpinYL1oYI(FFHJ+5Wbed%lqm%HNl+I}zucuurMR58_COGV0Qi&ja-Z zSIZUkzc0g&l89Rojp)KGgNHU8OuM9+v)(@P$lJ*;wMS?*ASMA863C465c$)QaSmjJ zd@cieS~a1%wD$fQ`6N_dbN}c9&@FaxiVEV5#IG=4&Y5J?$xV{ujdH`A6%e&oV4u-4 z4u`Jc+ELd~qkNT!qq1_@6K+lpk$=$jd*jguQWuL6T`)|EcXQ)@2~)sKl2Mk2`p`uf zdm4Jox9Hfnzj;+X#I94l;|&@x0a|57v0}dp3`{&_KDITiKt69VdK`=+RcN}x@qWO2 z!&`Sgp+|~{xa{9#4NiF8EL@$|((Vk;6-`~-^~wA06aCgy3&ced8Y> zm*R&LVz@zB80ra2XN*9o%CLRd;@W$@vss;I^4FPwGQ#zE*W~YRkh3MrJpT|k{=XFP z=LaLf9kecj8*=-@#mBxiDWufDZ~lmbcJ!bdDuM$n)6KJ!`4XehDK#?8QH1ETkDo37 z>ugD(`pAWVa`vFUF;`u~r;G)hX}Ji4D#^6O)jz&IEL4%G;O3K^AzDoSHhz)kHd2%> zO-v}8WtS)&ZLp9s*p9uOxz5OkI<;B%bhBFbWi#z-Y|rW5j7Z%h+I)Kx`?IG0!g3 z!?N4|T-9yEI^Gmwk4I`(@r{XMPt%59^~-&##=e2`?Z5_OVPVwZqfa-RZx{vByu9m? z+s2~~hwnLf!ybu1-w2|RN~~F3$W-pnX461Jyyp>5%_bYL4VOF8>XthHh0YIbuloaU zMBb;FjV^myFZ$gf26f>qZjp!)RbolLj`VSta<_8a4knkY01VOLuqzjzjpyVTLaSqHtI;WQ2o z@FLYd*c{`4$6RrLIh!i%9>Hyo(z7$n~jzpa4$+>AIgX$Q}PrLf$pL#{G)?G4m11`w`aZ zwkqhFOZ4{caU0`Bz=L&_?*%24*1stF*L}ues-tsP6T3HCE`T25FM{3;DJl+v=~}h! zU4C%?Hp>)awOp91QXIoK=HhVcc&BO}c2>Cex;9Oh&_wsIr%U9I{kgY)03}#b{SKgg zPn6$!Txd{C)QEu!LAq*X&({3J!@TR-EhlO0KObkzz|N!}msy62`4xPjzR5M(%7<|@ z{JxZbuOwcohHp2d6`kSRhWe&nIElbkb_v0XG;A2Db|j{C0-skZkC$|%u6*I@og&Z# zlPa}1nbcwGwkPdUUb%3&Gu@?`0xQGeN{4$afuwY@ffke*ZC1WAo_20P6Q*rGI=mna)$V- z@^R<=(#Ic5N<4irL7ep5xdSs$s-j~6&oxXTt07YRmt*mg4^C` zeG{-{qzG}XbS63TGjz^7g+EUPRB#kltkTXD?i_Ty4rvB$9yz#lKmtH^xj%FG<<5u0 zNN(+Wx_(vhfq@z%D5CU7AFa4Yty&*n z4>AWX>fl~)%PP0;8oh(Zr%4(b#<%(>I>ReH?}{eRsJ6xkUa{Uckvq{EXl=Kqm0tI> z-wlVhkSy3rrX$p_@Y{LPpcKY%aj551CKQyM4s=nj^nPq!Z1cWNypIfW<&rXfLMkfq_T{n`OXk&>Z&y$f5Pl8g{T=tn z{0AThi&b848kPp0RUAz!Pdxlt63n{VzP04w^7G1wnD0?J#v_zm0H9JFN*h9<#8=L0 zSI6g>EVQVwcyxAScEn4xTFjc7aHF-VcMCKCl7C!@7pJXCg4DsNWJ2Y}?!{Ek|7nT! zBjeIjckv^pHH&f7UiJnoaBL1?Ias_UiM4BpBBoE%vN2m9@#V)~5Yrgkfkkb!Ap3Ps z?mh8@r;-YY%+kQEx*PrLwrCsPgx{6g&gX_x^=_M8=__4_{HZ*2VAASggL1rA@Oqiq zRJPXS-vPe;yDhOqrR>kLM-yTVdI{3yMu*MmPdR|*v#~($K@x1b4<`gQsVbYovsuej z!=ZbzU7yPMR(nID#{)k76yf&^V`4mAu^{EOge{XJu=cKQ+wPW2^7MWm`?;N^g6Hl> z$LsJ2oBKXOW~Uu&+Q}Q;1(76Rt5_Ji{QP^(x%$u(Ivn`!Zu1G{EMdu^OGb2X2Mv8% zWb^ELz==+~#^yrDlho_Q$0q9)W92(8z|dFwX-<3aNa5hBm!QM1^KraW;9P{Q-7)kG zWuB#>%JZ1Ys`G~AeK+c(saf~?jU&B_bbX0>I;$IWfleV}Vz_`+St4%kDKi`W2;gr$ zO{V>rW$H`U!z(~y<}fs~^zI2l;$P!RNGNhZzT&Use-LyfwtsVZd5IGF`=2D}{h2?* zR7@;!yF13q+somTeX`D6zVm*C;0taf`$%V3*6fh6Tx=U;LTmcw^t+3ymNXtHcTfy% znyKHRd%zdf!4Y6y0jTv>KAT(q0-M`rFj-(GT#29CXIUyfoK=qIBTg5m3g_ykPD*?a zdL`=YrP4PvJu@IMvss3j+uz6rW0X$A2q7p=H>-%qfr%~6AQN0n#XgqgE-l%qM98oo z(b_m0Wyv^9QyYVb|5fS=OG9r%LYG*=5M?%P-&E6ee9VFb&1sXUDF}&v^Xh)*?J!&3 zraWn^wl^5s4r49D#K&MiRj6_=X)j?u{YY0_4!+Nq!r3+g14~r1K>5|4R9w0#ioXgy z)suRf2`ZgQ1%eR|o#f09hb|>RBrXX4qJFgv=3?Xw84l`BdT#EUk_{DVlvFQ+ax{4P zuimHH6*lK{D(!>#)>ik=h=aV*bBEI?DDOh$-0E_)B=NXE@rDb0ewA3{afWS|hHt>v zXIT{FEaI}h!hE<`?|xpgV&n6T7B^|Mue-Lw97Ir3>rQfHV+AifJ@8Rh&MP%`d4i|S zoip2+=y>3GU-!Pv%0|GLt2bW|ke0ec)qVkIbz5Fp>$mmOL|3CFELWuPS$7bXSO~J~*jSyqO1O zMr~1{WN?ufnuSHWfSMAf^f`me-t?>H7iPx<o%`@jpeI~Afi4Sw$uq?Mb zrSx^40IQ-wt>crWFL~XBf2DkLalG*LZ5+b)&ft@A&$5-IrjBTX>WRrxYr!gDSJcvK zA1o3DtNqp%qrR`9q!R&O4+RlGwb4(aiBmPQV$T3XPdvh>;T^}X%k+ntcD+wKHG zQevJTvG>n!iZqYGJ8|(C6%`dc+f)BWDs9@K zxaiczd>5PijVuDZqlYbH&dk0EA4#-~U2n2-bBJ|j@Tx#S2wV)#PvPaEFA~{-A%XsK zrr0Bk5n+FXbaG-McNv7HnzQ*LbR^PxN9-pDN%9DX5Rq6)HeYpG0#L_$E@MA7xjHX!D~D z0HoTfC#zA$v}RLQt0py@XZigee|}GB#xl<2A?<))o*S{`fIeVV?YU1?J90Nx%hu9? zkxBc+*HPF#hd_zv*Prfb!&um@iy#~*JtfGD_yV6cOC*n|jPTr+I6A_SYP6;=h-=z_ z%1uG^7~33HFbSAIZfPJOyYt|y61e1X%-;Qu^8<#gQ~T|Skia*Vaw=wSVu7~8Pwt1c z#f{fT$HH9L+(6O6!I&%H2^YN?CaiVVd}sQ}k|u3qQMH#*M!P=%9z$?Fz}$=r=82_O zVuB|?xhSe&&+sp_JVVeyQ5?T&1FYb@t=3O#=jhK1AL&|pyjll^#YLQK_^aJNL57Vp z!mW)6S&jl;jV_?tBgK}T?<%+=|Z zxga>Brk#S?aUz0Yw7EG~QZX2uvqaEy&p>-he?|#Tw08wYdJjPyv2Y8r28IsUg_p2o z>>AjXkTdtUKn)2`1uer!nK8Lw%K+t>9EJ(bqH5B4h{;-(*iv|yJBR``dQf&=b<{}F z2)QOGUfzL{)Ff1sP#-a^UKMNkf;wmBM2`VWhk-a+Id^Wn-PV*rQxHeyU`^h$4k3Q^y^E45fI2(z7U4M(xXjzysX}C1-sADZ&$vm zXIbKB{k|%*bwrs|HGT1qDn@lzjOrP&bcy-aBUh8Vc9z#_i!M=iq6$3Dg?UMdKz`!R zH~3t9k{l>}A!&37D(?wuGs)?*`LJ^N_&(1$!nVlUby*w;-@GF=l+cE8-5Md?7&PTS ze5)jeI}Z|GnA`QC-3QG9m@})5&CYr*lnp?{_rlOJ8N30MALkqW>r>yfz3Qp%QH9pV)3wYQwV%yVWP|V>%R^^1d<8 zQwv0)AwvB8YI<2kb@2lm@ceO!5^jQ;MCk`LBiAehiFT$~l%Gd2Go9nj7F=9*OBj^k zB`;1^h6Dxrn*!^(vpzv->{EQD&Ek<~U_Zt)$SznIfM(y7lAsvbW`!T~vg2#+mxMAW z79A81;;^Lx-s(8HK~`2e`sQCTXfy}oN zgUaiv1I^Xgs?F5(*s!)HI^MKi<9Hu=byn8s64mF&Z&j^Rf-3U`(h)?qJm5!b=ouDz zo{yoBoP(0XDIF5shE}L=TO_y$+*=3PR(T7p1j&kK09fMHY`k(YM;;J4sy@**ZZ$RF z(>TB0zjfp8d}d!<(+TTqV3e*1am5aZaY z=_PZ(fsa6!9zmw2GmPRf4`;5aLj*#_Gvva~=E~G7*XUAKI9*%seZD7=wyfA$U;pBl zCwTiJk=+UvH}#`p2AYG?;_GH8i=;6*0;?c5mOpMv&6r?gLckqfcY;2;w{fD5H$Fa* zK{+#3Wv z#M+I`H!qju4&iv`K~C_veSNX2McFEoAPjNv-!5+dPE^$G?*iW2Z36dCTi30d)@z3M zjY{?G1^4U=^cF$L$By^ShAtEKN3clZe~hX0zd-t_L}HB+U{@z6x}HQKdg~bFm~qfZ zU>u6p_d0S{Mlj0-9@eiozMAQU)MVMKRIVpg^G9>=G4QF8?FICp=6yA!9aCp143v?T z6-P`cCRD70uhJwv?|GU~3l@D7*DDp;Z4;MZG0*V&g4!m|rS9QrxcP-fI?Ui_YkT{z z;~aH8-f6}Sw(qY>UL6?^n92%Yv!_h_KbK1eP6V>*+~_MR^$#nV0TK)|7wS@*p)5rB zQv2^hGfH3oG{}_yP*pQ00B*2~SdeD5R+75uJANaGsh9{TK8`yc3#qqH?VKWy<8$xc z)Qp|49uuNAJ1phd>MbKlBdvf2&(8ugDXdx|0>vAoMjO>HHIg-FPW6n3t1x;{*aO>4vti;DMjZU?Wjkg|? z109Q6AqV;B1v=UyX3DrsDqMD~2bk8xOFq{7~4Y=qLF|eiz)K0?hy`elY`gR+n2!<>mRM>10VjPM@lYG zfR$8HV8xTjqI@vP_boD&qR-{cCc6iQ4H$3RW8bS7Bt|(OT|Xs#j)H5#0RGHPJOD{bl zwcj*4BY7WZJ}^{hI>RL}B-(DblWeRnz6tA2olxtFF1TTi3_L?+cDO-Ojz}a+4zO{s z^>n`zMna1uO9KuAAMgWqmVQCsd8!}L?)3EAv+-~ZG=A{PXB>ckV_YEP$QVD${V4uI zv+(E>`u%Q45$ti128hjcq(0GFA|XgUGSN!noGq0wiEHnhOZ|=YM3`8-6sT(2F*jTc zmua_V8&_=Vk|Vr>%t`y!#*TU5_xFiA6Q;U+vJs2N+4gIt*Pgx0yS>U(!JG0RT|?Ae z1a&%heFPA=`REc%AM;SCH4Y}H~!ctiAY4|~)4@5SO0NDG_3`G7tgHHX@saewuF1;Sz9d^K zpe}{BXuQ}5WjY>ONv}PaX{|^HF}4kd=~^jLE9Jj%$~o$aI;OqnSv~Dtov(duQDK%y zqAp9j@tgGD=sbuA8_QGJblGYyB6!Ta=)C{bJY+i4-hckrtMk?; z`lrE8*2@N_gR5>uGu+k8Y7p=Jyx6ZfS1`_r=4IM=NycrFy6%FO3K)euy06%KiEQT_ zdzm$;u0|?*D(+hg{#6IJqG*7uv%Q#WCOdqQf*~Bb{o}Fakd%T#?D{yLMEaJI!WDU& zz50Qo>2*bY=F2poUzGSzH%$!>&55})>Rvl&LAgPh4i|T8PX##8y-x3p%DcMcn>IR` zi)jZk%Wyb#xUGN_6hwPZ*Mjm(lgBw6r7rKo z=ndDQL{e8YXhTcDyJW&_s)fqd#>U5aqb0EQ!KtdQ4SOHdwLA=Eg-f8%MRWC(1Qbw` zuI^|E-Sa|TSogx&c)E9{ga29u*N@H_>|PvY?7v>U+DsnyV0%Qsp+{M%3gmuZ&iFVb zLh+*-Y@3p&>bI`h_uN}hH=SrU#fnr9%+F6PSiXS^_$BX zhPP_7-0{z>F#PiTE*&sLbX%Q<0?H;j{7)|0BIl>*=T*cKxcH;&h)?rYPJ&_<>5!2) zMS@gMoNbssrysQ7U2*Kp+(s9E!wMgLdM-=;+Se^p|LBNtV}Kp3jFD6GqP{-5x1FY0BEiWDZXo)~J zXsc?Zs~)&EzinfWZlI=dvs->AeNx!@oCd7<&o1jREgF4G5A|04AoHH{h zzVHmpTY3`1YZLX0e<~Rh=0g&5I?5dJTg^4`3m!AND`nD7z*DJGVVsdx*mtJ&&~J{!8MTgF zPRD)g8b{l+`%o3Y=I|K}4VSAWj9#8%Uqxt*GSB#4Psw|cWGPavW9ioZF(){UycsP3 zT4rSryMr6fmIrRq$qa;J?|rS>nBnQ1MWBT7xW1<&)=E(W7CJR$cHa5EJnRL1#<)$B zx4)gT?UQrs%;52~INQLF_OglXC*w>+a{y*t&-u94>j>|g!fU_t2kwqoe^ny4IF{r% zSh7P+QkE8kLi|^h$k=OVFil=bOr>aSPn&iA1-uxI7gW9OxQKLVH{g0D#qHJGt_Zdl z1?YeTkTSn<^WKYDdWgK0WB9TuZ!ZtnPw6$Q45MwkWCFU~n{wUEx~4AydylH-Au?~; zh{sZq9&Btbtdiw|63T129%iOs275WT>fmk{8f>1Y4J|T(uqSiEhR>Lh(8Xk**HzVZ zd23D4GAV6|K~rZZ*4Y$fkQ9=Ey;WW-+j1JQyw(Fxs$&CmggIgOU?Uv37x=@`i;xL# zwB^4jIXtS9tE`(CBn5CtPW)-}jcC-?nrBM{fZ<2EF!pl*()1C^31HuPImRTZi`NN_ z)5C*WJGSv$axn$5&=I!DFdZ6-Wb4ydWK+R&3ILOa1sCaIxrRPm4u(BQ zy*f6_6u-%$YuV<_^73LAW0pI%O7YH3Nnsy2Y`KDgc*y7ayeO=vS~WUkWu+< zPZ)lrtc)#FkxVND=nZM8mMd5)t75xwo3{g&1fX@ayKU7_)jGdQ-5u(|G^HX9T;T8MV=aKte!sEdDMY!FQ6gW0aJ!G4e}Uwq4&LukV=$l ze3{-XOGoPUkQP?OvIE&|xyrJ)tt$OgDk)f4#%m6dQ~b3;nfr@byGn<3UtG&veJ#f;Bnxx*bySnbT-Q*dM;IBL~iM{<$CYQ}Wtk&_OU@XILad7dB)^b)Ru z3<%_|<4&n7Ke-LnUF54n3sSo@v~XF(k;TCK7sX%F!xGm;w_8H?7{Cep-DblJ$-`w? zzY>PiM!l*%OoZ_PqEQmT+ZL=!W>4>?&M-Cho}-x}dQ1e{iHkfcO4DLAX%`N}T3M+A ze>XWL$)7CY3-!OX&5jH4_xpbU3D0_yIBrrEsc+4}Yl zJeni}63jLzV@+N5Yl80p5z6X&fSE*T`Noy~E_ zc)zviiCN7OA!*l{^R0n;XIry+Kj|Ur8lfQpq$&}r%1Wl+wXVKSjX@z3YTO)Yxb`%4 zy^FaMq?FvfOz{c&!e(+e0o@(NcNRU$Uptia?L7K`&0D_^*kg!B7&SXw@U`Ek!(2`> zoavs+F6@`usbmNE*2#n#N~tWZiWf~}a$JcR^xM_+78AEUJ7D12Ww4|dj*WG#{v9e%fd zaYi(tWldRMhS{9~*4*ds^@Uw5$5m2;q-2I>oiBl_R}d+$v;| zjt|@I7SkFjgN;Nw-(Fs^-n!4gJG~ PF>vGLEyXhjfL%Q4HJU9~4F2tW9#&?)AY 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 z�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%0Ad_}}TgcYJ_v&v)7JnQHrZ&^mo*&L6Tnj%=T0 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%0AOg!QNO+C|>zbp#;U`u@{jCP4tC}Bm5yOZ3`@fFS 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ℜ+w@2Q9DFzYy&+QOl!C94gXgrXcNZDiN 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

=|LMnDb&co;s1^S;HEJbS!p4nxTQ!u_ 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

  • dVkM~;8PK!61C-%8^>{@m+;HY-%w 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 F{{f@`1mOSx literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/samples/sk-b-dep.png b/extensions-builtin/sd_forge_controlnet/samples/sk-b-dep.png new file mode 100644 index 0000000000000000000000000000000000000000..1896956386c1416cdf17b5be6e24995a122527aa GIT binary patch literal 121145 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ν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�p=bdwzoe8vAhnP>jVMYoNnDhI8$U$6c<9`?3 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

    aD$}@RU2R>on2B?|7jKyy|QLFX4V7 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%0AL<9n)pnF@73|~+uiS;SQC-jo-2oRT!D0-B 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%0API(rna+}_^g(za|nsK751)YjKQ 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%0D779>w3 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/lq$Fia4b!lE0Q8LAaW_?N>20 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 literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/samples/sk-b-src.png b/extensions-builtin/sd_forge_controlnet/samples/sk-b-src.png new file mode 100644 index 0000000000000000000000000000000000000000..1bece79872480e2f5d60777688fbfe42e6215647 GIT binary patch literal 561584 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 z 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�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 z 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𝔍ij-=_>fzw722gkVE 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 VUJsY9rd=anYRcM5wQp>~{s-AnY@+}G literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/scripts/adapter.py b/extensions-builtin/sd_forge_controlnet/scripts/adapter.py new file mode 100644 index 00000000..d7f10a1c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/adapter.py @@ -0,0 +1,373 @@ +import torch +import torch.nn as nn +from collections import OrderedDict + +from omegaconf import OmegaConf +from copy import deepcopy +from modules import devices, lowvram, shared, scripts +cond_cast_unet = getattr(devices, 'cond_cast_unet', lambda x: x) + + +class TorchHijackForUnet: + """ + This is torch, but with cat that resizes tensors to appropriate dimensions if they do not match; + this makes it possible to create pictures with dimensions that are multiples of 8 rather than 64 + """ + + def __getattr__(self, item): + if item == 'cat': + return self.cat + + if hasattr(torch, item): + return getattr(torch, item) + + raise AttributeError("'{}' object has no attribute '{}'".format(type(self).__name__, item)) + + def cat(self, tensors, *args, **kwargs): + if len(tensors) == 2: + a, b = tensors + if a.shape[-2:] != b.shape[-2:]: + a = torch.nn.functional.interpolate(a, b.shape[-2:], mode="nearest") + + tensors = (a, b) + + return torch.cat(tensors, *args, **kwargs) + + +th = TorchHijackForUnet() + + +def align(hint, size): + b, c, h1, w1 = hint.shape + h, w = size + if h != h1 or w != w1: + hint = th.nn.functional.interpolate(hint, size=size, mode="nearest") + return hint + + +class PlugableAdapter(nn.Module): + def __init__(self, control_model) -> None: + super().__init__() + self.control_model = control_model + self.control = None + self.hint_cond = None + + def reset(self): + self.control = None + self.hint_cond = None + + def forward(self, hint=None, x=None, *args, **kwargs): + if self.control is not None: + return deepcopy(self.control) + + self.hint_cond = cond_cast_unet(hint) + hint_in = cond_cast_unet(hint) + + if hasattr(self.control_model, 'conv_in') and \ + (self.control_model.conv_in.in_channels == 64 or self.control_model.conv_in.in_channels == 256): + hint_in = hint_in[:, 0:1, :, :] + + self.control = self.control_model(hint_in) + return deepcopy(self.control) + + def aggressive_lowvram(self): + self.to(devices.get_device_for("controlnet")) + return + + def fullvram(self): + self.to(devices.get_device_for("controlnet")) + return + + +def conv_nd(dims, *args, **kwargs): + """ + Create a 1D, 2D, or 3D convolution module. + """ + if dims == 1: + return nn.Conv1d(*args, **kwargs) + elif dims == 2: + return nn.Conv2d(*args, **kwargs) + elif dims == 3: + return nn.Conv3d(*args, **kwargs) + raise ValueError(f"unsupported dimensions: {dims}") + +def avg_pool_nd(dims, *args, **kwargs): + """ + Create a 1D, 2D, or 3D average pooling module. + """ + if dims == 1: + return nn.AvgPool1d(*args, **kwargs) + elif dims == 2: + return nn.AvgPool2d(*args, **kwargs) + elif dims == 3: + return nn.AvgPool3d(*args, **kwargs) + raise ValueError(f"unsupported dimensions: {dims}") + + +class Downsample(nn.Module): + """ + A downsampling layer with an optional convolution. + :param channels: channels in the inputs and outputs. + :param use_conv: a bool determining if a convolution is applied. + :param dims: determines if the signal is 1D, 2D, or 3D. If 3D, then + downsampling occurs in the inner-two dimensions. + """ + + def __init__(self, channels, use_conv, dims=2, out_channels=None,padding=1): + super().__init__() + self.channels = channels + self.out_channels = out_channels or channels + self.use_conv = use_conv + self.dims = dims + stride = 2 if dims != 3 else (1, 2, 2) + if use_conv: + self.op = conv_nd( + dims, self.channels, self.out_channels, 3, stride=stride, padding=padding + ) + else: + assert self.channels == self.out_channels + self.op = avg_pool_nd(dims, kernel_size=stride, stride=stride) + + def forward(self, x): + assert x.shape[1] == self.channels + return self.op(x) + + +class ResnetBlock(nn.Module): + def __init__(self, in_c, out_c, down, ksize=3, sk=False, use_conv=True): + super().__init__() + ps = ksize//2 + if in_c != out_c or sk==False: + self.in_conv = nn.Conv2d(in_c, out_c, ksize, 1, ps) + else: + # print('n_in') + self.in_conv = None + self.block1 = nn.Conv2d(out_c, out_c, 3, 1, 1) + self.act = nn.ReLU() + self.block2 = nn.Conv2d(out_c, out_c, ksize, 1, ps) + if sk==False: + self.skep = nn.Conv2d(in_c, out_c, ksize, 1, ps) + else: + self.skep = None + + self.down = down + if self.down == True: + self.down_opt = Downsample(in_c, use_conv=use_conv) + + def forward(self, x): + if self.down == True: + x = self.down_opt(x) + if self.in_conv is not None: # edit + x = self.in_conv(x) + + h = self.block1(x) + h = self.act(h) + h = self.block2(h) + if self.skep is not None: + return h + self.skep(x) + else: + return h + x + + +class Adapter(nn.Module): + def __init__(self, channels=[320, 640, 1280, 1280], nums_rb=3, cin=64, ksize=3, sk=False, use_conv=True, is_sdxl=True): + super(Adapter, self).__init__() + + if is_sdxl: + self.pixel_shuffle = 16 + downsample_avoided = [1] + downsample_layers = [2] + else: + self.pixel_shuffle = 8 + downsample_avoided = [] + downsample_layers = [3, 2, 1] + + self.input_channels = cin // (self.pixel_shuffle * self.pixel_shuffle) + self.channels = channels + self.nums_rb = nums_rb + self.body = [] + + self.unshuffle = nn.PixelUnshuffle(self.pixel_shuffle) + + for i in range(len(channels)): + for r in range(nums_rb): + + if i in downsample_layers and r == 0: + self.body.append(ResnetBlock( + channels[i - 1], + channels[i], + down=True, + ksize=ksize, + sk=sk, + use_conv=use_conv)) + continue + + if i in downsample_avoided and r == 0: + self.body.append(ResnetBlock( + channels[i - 1], + channels[i], + down=False, + ksize=ksize, + sk=sk, + use_conv=use_conv)) + continue + + self.body.append(ResnetBlock( + channels[i], + channels[i], + down=False, + ksize=ksize, + sk=sk, + use_conv=use_conv + )) + + self.body = nn.ModuleList(self.body) + self.conv_in = nn.Conv2d(cin, channels[0], 3, 1, 1) + + def forward(self, x): + self.to(x.device) + + x = self.unshuffle(x) + hs = [] + + x = self.conv_in(x) + for i in range(len(self.channels)): + for r in range(self.nums_rb): + idx = i * self.nums_rb + r + x = self.body[idx](x) + hs.append(x) + + self.to('cpu') + return hs + + +class LayerNorm(nn.LayerNorm): + """Subclass torch's LayerNorm to handle fp16.""" + + def forward(self, x: torch.Tensor): + orig_type = x.dtype + ret = super().forward(x.type(torch.float32)) + return ret.type(orig_type) + + +class QuickGELU(nn.Module): + + def forward(self, x: torch.Tensor): + return x * torch.sigmoid(1.702 * x) + + +class ResidualAttentionBlock(nn.Module): + + def __init__(self, d_model: int, n_head: int, attn_mask: torch.Tensor = None): + super().__init__() + + self.attn = nn.MultiheadAttention(d_model, n_head) + self.ln_1 = LayerNorm(d_model) + self.mlp = nn.Sequential( + OrderedDict([("c_fc", nn.Linear(d_model, d_model * 4)), ("gelu", QuickGELU()), + ("c_proj", nn.Linear(d_model * 4, d_model))])) + self.ln_2 = LayerNorm(d_model) + self.attn_mask = attn_mask + + def attention(self, x: torch.Tensor): + self.attn_mask = self.attn_mask.to(dtype=x.dtype, device=x.device) if self.attn_mask is not None else None + return self.attn(x, x, x, need_weights=False, attn_mask=self.attn_mask)[0] + + def forward(self, x: torch.Tensor): + x = x + self.attention(self.ln_1(x)) + x = x + self.mlp(self.ln_2(x)) + return x + + +class StyleAdapter(nn.Module): + + def __init__(self, width=1024, context_dim=768, num_head=8, n_layes=3, num_token=4): + super().__init__() + + scale = width ** -0.5 + self.transformer_layes = nn.Sequential(*[ResidualAttentionBlock(width, num_head) for _ in range(n_layes)]) + self.num_token = num_token + self.style_embedding = nn.Parameter(torch.randn(1, num_token, width) * scale) + self.ln_post = LayerNorm(width) + self.ln_pre = LayerNorm(width) + self.proj = nn.Parameter(scale * torch.randn(width, context_dim)) + + def forward(self, x): + # x shape [N, HW+1, C] + style_embedding = self.style_embedding + torch.zeros( + (x.shape[0], self.num_token, self.style_embedding.shape[-1]), device=x.device) + + x = torch.cat([x, style_embedding], dim=1) + x = self.ln_pre(x) + x = x.permute(1, 0, 2) # NLD -> LND + x = self.transformer_layes(x) + x = x.permute(1, 0, 2) # LND -> NLD + + x = self.ln_post(x[:, -self.num_token:, :]) + x = x @ self.proj + + return x + + +class ResnetBlock_light(nn.Module): + def __init__(self, in_c): + super().__init__() + self.block1 = nn.Conv2d(in_c, in_c, 3, 1, 1) + self.act = nn.ReLU() + self.block2 = nn.Conv2d(in_c, in_c, 3, 1, 1) + + def forward(self, x): + h = self.block1(x) + h = self.act(h) + h = self.block2(h) + + return h + x + + +class extractor(nn.Module): + def __init__(self, in_c, inter_c, out_c, nums_rb, down=False): + super().__init__() + self.in_conv = nn.Conv2d(in_c, inter_c, 1, 1, 0) + self.body = [] + for _ in range(nums_rb): + self.body.append(ResnetBlock_light(inter_c)) + self.body = nn.Sequential(*self.body) + self.out_conv = nn.Conv2d(inter_c, out_c, 1, 1, 0) + self.down = down + if self.down == True: + self.down_opt = Downsample(in_c, use_conv=False) + + def forward(self, x): + if self.down == True: + x = self.down_opt(x) + x = self.in_conv(x) + x = self.body(x) + x = self.out_conv(x) + + return x + + +class Adapter_light(nn.Module): + def __init__(self, channels=[320, 640, 1280, 1280], nums_rb=3, cin=64): + super(Adapter_light, self).__init__() + self.unshuffle = nn.PixelUnshuffle(8) + self.channels = channels + self.nums_rb = nums_rb + self.body = [] + for i in range(len(channels)): + if i == 0: + self.body.append(extractor(in_c=cin, inter_c=channels[i]//4, out_c=channels[i], nums_rb=nums_rb, down=False)) + else: + self.body.append(extractor(in_c=channels[i-1], inter_c=channels[i]//4, out_c=channels[i], nums_rb=nums_rb, down=True)) + self.body = nn.ModuleList(self.body) + + def forward(self, x): + # unshuffle + x = self.unshuffle(x) + # extract features + features = [] + for i in range(len(self.channels)): + x = self.body[i](x) + features.append(x) + + return features diff --git a/extensions-builtin/sd_forge_controlnet/scripts/api.py b/extensions-builtin/sd_forge_controlnet/scripts/api.py new file mode 100644 index 00000000..c68e225b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/api.py @@ -0,0 +1,197 @@ +from typing import List, Optional + +import numpy as np +from fastapi import FastAPI, Body +from fastapi.exceptions import HTTPException +from pydantic import BaseModel + +from PIL import Image + +import gradio as gr + +from modules.api.models import * +from modules.api import api + +from scripts import external_code, global_state +from scripts.processor import preprocessor_filters +from scripts.logging import logger +from annotator.openpose import draw_poses, decode_json_as_poses +from annotator.openpose.animalpose import draw_animalposes + + +def encode_to_base64(image): + if isinstance(image, str): + return image + elif isinstance(image, Image.Image): + return api.encode_pil_to_base64(image) + elif isinstance(image, np.ndarray): + return encode_np_to_base64(image) + else: + return "" + + +def encode_np_to_base64(image): + pil = Image.fromarray(image) + return api.encode_pil_to_base64(pil) + + +def controlnet_api(_: gr.Blocks, app: FastAPI): + @app.get("/controlnet/version") + async def version(): + return {"version": external_code.get_api_version()} + + @app.get("/controlnet/model_list") + async def model_list(update: bool = True): + up_to_date_model_list = external_code.get_models(update=update) + logger.debug(up_to_date_model_list) + return {"model_list": up_to_date_model_list} + + @app.get("/controlnet/module_list") + async def module_list(alias_names: bool = False): + _module_list = external_code.get_modules(alias_names) + logger.debug(_module_list) + + return { + "module_list": _module_list, + "module_detail": external_code.get_modules_detail(alias_names), + } + + @app.get("/controlnet/control_types") + async def control_types(): + def format_control_type( + filtered_preprocessor_list, + filtered_model_list, + default_option, + default_model, + ): + return { + "module_list": filtered_preprocessor_list, + "model_list": filtered_model_list, + "default_option": default_option, + "default_model": default_model, + } + + return { + "control_types": { + control_type: format_control_type( + *global_state.select_control_type(control_type) + ) + for control_type in preprocessor_filters.keys() + } + } + + @app.get("/controlnet/settings") + async def settings(): + max_models_num = external_code.get_max_models_num() + return {"control_net_unit_count": max_models_num} + + cached_cn_preprocessors = global_state.cache_preprocessors( + global_state.cn_preprocessor_modules + ) + + @app.post("/controlnet/detect") + async def detect( + controlnet_module: str = Body("none", title="Controlnet Module"), + controlnet_input_images: List[str] = Body([], title="Controlnet Input Images"), + controlnet_processor_res: int = Body( + 512, title="Controlnet Processor Resolution" + ), + controlnet_threshold_a: float = Body(64, title="Controlnet Threshold a"), + controlnet_threshold_b: float = Body(64, title="Controlnet Threshold b"), + low_vram: bool = Body(False, title="Low vram"), + ): + controlnet_module = global_state.reverse_preprocessor_aliases.get( + controlnet_module, controlnet_module + ) + + if controlnet_module not in cached_cn_preprocessors: + raise HTTPException(status_code=422, detail="Module not available") + + if len(controlnet_input_images) == 0: + raise HTTPException(status_code=422, detail="No image selected") + + logger.info( + f"Detecting {str(len(controlnet_input_images))} images with the {controlnet_module} module." + ) + + results = [] + poses = [] + + processor_module = cached_cn_preprocessors[controlnet_module] + + for input_image in controlnet_input_images: + img = external_code.to_base64_nparray(input_image) + + class JsonAcceptor: + def __init__(self) -> None: + self.value = None + + def accept(self, json_dict: dict) -> None: + self.value = json_dict + + json_acceptor = JsonAcceptor() + + results.append( + processor_module( + img, + res=controlnet_processor_res, + thr_a=controlnet_threshold_a, + thr_b=controlnet_threshold_b, + json_pose_callback=json_acceptor.accept, + low_vram=low_vram, + )[0] + ) + + if "openpose" in controlnet_module: + assert json_acceptor.value is not None + poses.append(json_acceptor.value) + + global_state.cn_preprocessor_unloadable.get(controlnet_module, lambda: None)() + results64 = list(map(encode_to_base64, results)) + res = {"images": results64, "info": "Success"} + if poses: + res["poses"] = poses + + return res + + class Person(BaseModel): + pose_keypoints_2d: List[float] + hand_right_keypoints_2d: Optional[List[float]] + hand_left_keypoints_2d: Optional[List[float]] + face_keypoints_2d: Optional[List[float]] + + class PoseData(BaseModel): + people: List[Person] + canvas_width: int + canvas_height: int + + @app.post("/controlnet/render_openpose_json") + async def render_openpose_json( + pose_data: List[PoseData] = Body([], title="Pose json files to render.") + ): + if not pose_data: + return {"info": "No pose data detected."} + else: + + def draw(poses, animals, H, W): + if poses: + assert len(animals) == 0 + return draw_poses(poses, H, W) + else: + return draw_animalposes(animals, H, W) + + return { + "images": [ + encode_to_base64(draw(*decode_json_as_poses(pose.dict()))) + for pose in pose_data + ], + "info": "Success", + } + + +try: + import modules.script_callbacks as script_callbacks + + script_callbacks.on_app_started(controlnet_api) +except: + pass diff --git a/extensions-builtin/sd_forge_controlnet/scripts/batch_hijack.py b/extensions-builtin/sd_forge_controlnet/scripts/batch_hijack.py new file mode 100644 index 00000000..980d2df2 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/batch_hijack.py @@ -0,0 +1,210 @@ +import os +from copy import copy +from typing import Tuple, List + +from modules import img2img, processing, shared, script_callbacks +from scripts import external_code +from scripts.enums import InputMode + +class BatchHijack: + def __init__(self): + self.is_batch = False + self.batch_index = 0 + self.batch_size = 1 + self.init_seed = None + self.init_subseed = None + self.process_batch_callbacks = [self.on_process_batch] + self.process_batch_each_callbacks = [] + self.postprocess_batch_each_callbacks = [self.on_postprocess_batch_each] + self.postprocess_batch_callbacks = [self.on_postprocess_batch] + + def img2img_process_batch_hijack(self, p, *args, **kwargs): + cn_is_batch, batches, output_dir, _ = get_cn_batches(p) + if not cn_is_batch: + return getattr(img2img, '__controlnet_original_process_batch')(p, *args, **kwargs) + + self.dispatch_callbacks(self.process_batch_callbacks, p, batches, output_dir) + + try: + return getattr(img2img, '__controlnet_original_process_batch')(p, *args, **kwargs) + finally: + self.dispatch_callbacks(self.postprocess_batch_callbacks, p) + + def processing_process_images_hijack(self, p, *args, **kwargs): + if self.is_batch: + # we are in img2img batch tab, do a single batch iteration + return self.process_images_cn_batch(p, *args, **kwargs) + + cn_is_batch, batches, output_dir, input_file_names = get_cn_batches(p) + if not cn_is_batch: + # we are not in batch mode, fallback to original function + return getattr(processing, '__controlnet_original_process_images_inner')(p, *args, **kwargs) + + output_images = [] + try: + self.dispatch_callbacks(self.process_batch_callbacks, p, batches, output_dir) + + for batch_i in range(self.batch_size): + processed = self.process_images_cn_batch(p, *args, **kwargs) + if shared.opts.data.get('controlnet_show_batch_images_in_ui', False): + output_images.extend(processed.images[processed.index_of_first_image:]) + + if output_dir: + self.save_images(output_dir, input_file_names[batch_i], processed.images[processed.index_of_first_image:]) + + if shared.state.interrupted: + break + + finally: + self.dispatch_callbacks(self.postprocess_batch_callbacks, p) + + if output_images: + processed.images = output_images + else: + processed = processing.Processed(p, [], p.seed) + + return processed + + def process_images_cn_batch(self, p, *args, **kwargs): + self.dispatch_callbacks(self.process_batch_each_callbacks, p) + old_detectmap_output = shared.opts.data.get('control_net_no_detectmap', False) + try: + shared.opts.data.update({'control_net_no_detectmap': True}) + processed = getattr(processing, '__controlnet_original_process_images_inner')(p, *args, **kwargs) + finally: + shared.opts.data.update({'control_net_no_detectmap': old_detectmap_output}) + + self.dispatch_callbacks(self.postprocess_batch_each_callbacks, p, processed) + + # do not go past control net batch size + if self.batch_index >= self.batch_size: + shared.state.interrupted = True + + return processed + + def save_images(self, output_dir, init_image_path, output_images): + os.makedirs(output_dir, exist_ok=True) + for n, processed_image in enumerate(output_images): + filename = os.path.basename(init_image_path) + + if n > 0: + left, right = os.path.splitext(filename) + filename = f"{left}-{n}{right}" + + if processed_image.mode == 'RGBA': + processed_image = processed_image.convert("RGB") + processed_image.save(os.path.join(output_dir, filename)) + + def do_hijack(self): + script_callbacks.on_script_unloaded(self.undo_hijack) + hijack_function( + module=img2img, + name='process_batch', + new_name='__controlnet_original_process_batch', + new_value=self.img2img_process_batch_hijack, + ) + hijack_function( + module=processing, + name='process_images_inner', + new_name='__controlnet_original_process_images_inner', + new_value=self.processing_process_images_hijack + ) + + def undo_hijack(self): + unhijack_function( + module=img2img, + name='process_batch', + new_name='__controlnet_original_process_batch', + ) + unhijack_function( + module=processing, + name='process_images_inner', + new_name='__controlnet_original_process_images_inner', + ) + + def adjust_job_count(self, p): + if shared.state.job_count == -1: + shared.state.job_count = p.n_iter + shared.state.job_count *= self.batch_size + + def on_process_batch(self, p, batches, output_dir, *args): + print('controlnet batch mode') + self.is_batch = True + self.batch_index = 0 + self.batch_size = len(batches) + processing.fix_seed(p) + if shared.opts.data.get('controlnet_increment_seed_during_batch', False): + self.init_seed = p.seed + self.init_subseed = p.subseed + self.adjust_job_count(p) + p.do_not_save_grid = True + p.do_not_save_samples = bool(output_dir) + + def on_postprocess_batch_each(self, p, *args): + self.batch_index += 1 + if shared.opts.data.get('controlnet_increment_seed_during_batch', False): + p.seed = p.seed + len(p.all_prompts) + p.subseed = p.subseed + len(p.all_prompts) + + def on_postprocess_batch(self, p, *args): + self.is_batch = False + self.batch_index = 0 + self.batch_size = 1 + if shared.opts.data.get('controlnet_increment_seed_during_batch', False): + p.seed = self.init_seed + p.all_seeds = [self.init_seed] + p.subseed = self.init_subseed + p.all_subseeds = [self.init_subseed] + + def dispatch_callbacks(self, callbacks, *args): + for callback in callbacks: + callback(*args) + + +def hijack_function(module, name, new_name, new_value): + # restore original function in case of reload + unhijack_function(module=module, name=name, new_name=new_name) + setattr(module, new_name, getattr(module, name)) + setattr(module, name, new_value) + + +def unhijack_function(module, name, new_name): + if hasattr(module, new_name): + setattr(module, name, getattr(module, new_name)) + delattr(module, new_name) + + +def get_cn_batches(p: processing.StableDiffusionProcessing) -> Tuple[bool, List[List[str]], str, List[str]]: + units = external_code.get_all_units_in_processing(p) + units = [copy(unit) for unit in units if getattr(unit, 'enabled', False)] + any_unit_is_batch = False + output_dir = '' + input_file_names = [] + for unit in units: + if getattr(unit, 'input_mode', InputMode.SIMPLE) == InputMode.BATCH: + any_unit_is_batch = True + output_dir = getattr(unit, 'output_dir', '') + if isinstance(unit.batch_images, str): + unit.batch_images = shared.listfiles(unit.batch_images) + input_file_names = unit.batch_images + + if any_unit_is_batch: + cn_batch_size = min(len(getattr(unit, 'batch_images', [])) + for unit in units + if getattr(unit, 'input_mode', InputMode.SIMPLE) == InputMode.BATCH) + else: + cn_batch_size = 1 + + batches = [[] for _ in range(cn_batch_size)] + for i in range(cn_batch_size): + for unit in units: + input_mode = getattr(unit, 'input_mode', InputMode.SIMPLE) + if input_mode == InputMode.BATCH: + batches[i].append(unit.batch_images[i]) + else: + batches[i].append(unit.image) + + return any_unit_is_batch, batches, output_dir, input_file_names + + +instance = BatchHijack() diff --git a/extensions-builtin/sd_forge_controlnet/scripts/cldm.py b/extensions-builtin/sd_forge_controlnet/scripts/cldm.py new file mode 100644 index 00000000..00925e04 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/cldm.py @@ -0,0 +1,322 @@ +import torch +import torch.nn as nn + +from modules import devices + + +try: + from sgm.modules.diffusionmodules.openaimodel import conv_nd, linear, zero_module, timestep_embedding, \ + TimestepEmbedSequential, ResBlock, Downsample, SpatialTransformer, exists + using_sgm = True +except: + from ldm.modules.diffusionmodules.openaimodel import conv_nd, linear, zero_module, timestep_embedding, \ + TimestepEmbedSequential, ResBlock, Downsample, SpatialTransformer, exists + using_sgm = False + + +class PlugableControlModel(nn.Module): + def __init__(self, config, state_dict=None): + super().__init__() + self.config = config + self.control_model = ControlNet(**self.config).cpu() + if state_dict is not None: + self.control_model.load_state_dict(state_dict, strict=False) + self.gpu_component = None + self.is_control_lora = False + + def reset(self): + pass + + def forward(self, *args, **kwargs): + return self.control_model(*args, **kwargs) + + def aggressive_lowvram(self): + self.to('cpu') + + def send_me_to_gpu(module, _): + if self.gpu_component == module: + return + + if self.gpu_component is not None: + self.gpu_component.to('cpu') + + module.to(devices.get_device_for("controlnet")) + self.gpu_component = module + + self.control_model.time_embed.register_forward_pre_hook(send_me_to_gpu) + self.control_model.input_hint_block.register_forward_pre_hook(send_me_to_gpu) + self.control_model.label_emb.register_forward_pre_hook(send_me_to_gpu) + for m in self.control_model.input_blocks: + m.register_forward_pre_hook(send_me_to_gpu) + for m in self.control_model.zero_convs: + m.register_forward_pre_hook(send_me_to_gpu) + self.control_model.middle_block.register_forward_pre_hook(send_me_to_gpu) + self.control_model.middle_block_out.register_forward_pre_hook(send_me_to_gpu) + return + + def fullvram(self): + self.to(devices.get_device_for("controlnet")) + return + + +class ControlNet(nn.Module): + def __init__( + self, + in_channels, + model_channels, + hint_channels, + num_res_blocks, + attention_resolutions, + dropout=0, + channel_mult=(1, 2, 4, 8), + conv_resample=True, + dims=2, + num_classes=None, + use_checkpoint=False, + use_fp16=True, + num_heads=-1, + num_head_channels=-1, + num_heads_upsample=-1, + use_scale_shift_norm=False, + resblock_updown=False, + use_spatial_transformer=True, + transformer_depth=1, + context_dim=None, + n_embed=None, + legacy=False, + disable_self_attentions=None, + num_attention_blocks=None, + disable_middle_self_attn=False, + use_linear_in_transformer=False, + adm_in_channels=None, + transformer_depth_middle=None, + device=None, + global_average_pooling=False, + ): + super().__init__() + + self.global_average_pooling = global_average_pooling + + if num_heads_upsample == -1: + num_heads_upsample = num_heads + + self.dims = dims + self.in_channels = in_channels + self.model_channels = model_channels + if isinstance(transformer_depth, int): + transformer_depth = len(channel_mult) * [transformer_depth] + if transformer_depth_middle is None: + transformer_depth_middle = transformer_depth[-1] + if isinstance(num_res_blocks, int): + self.num_res_blocks = len(channel_mult) * [num_res_blocks] + else: + self.num_res_blocks = num_res_blocks + + self.attention_resolutions = attention_resolutions + self.dropout = dropout + self.channel_mult = channel_mult + self.conv_resample = conv_resample + self.num_classes = num_classes + self.use_checkpoint = use_checkpoint + self.dtype = torch.float16 if use_fp16 else torch.float32 + self.num_heads = num_heads + self.num_head_channels = num_head_channels + self.num_heads_upsample = num_heads_upsample + self.predict_codebook_ids = n_embed is not None + + time_embed_dim = model_channels * 4 + self.time_embed = nn.Sequential( + linear(model_channels, time_embed_dim, dtype=self.dtype, device=device), + nn.SiLU(), + linear(time_embed_dim, time_embed_dim, dtype=self.dtype, device=device), + ) + + if self.num_classes is not None: + if isinstance(self.num_classes, int): + self.label_emb = nn.Embedding(num_classes, time_embed_dim) + elif self.num_classes == "continuous": + print("setting up linear c_adm embedding layer") + self.label_emb = nn.Linear(1, time_embed_dim) + elif self.num_classes == "sequential": + assert adm_in_channels is not None + self.label_emb = nn.Sequential( + nn.Sequential( + linear(adm_in_channels, time_embed_dim, dtype=self.dtype, device=device), + nn.SiLU(), + linear(time_embed_dim, time_embed_dim, dtype=self.dtype, device=device), + ) + ) + else: + raise ValueError() + + self.input_blocks = nn.ModuleList( + [ + TimestepEmbedSequential( + conv_nd(dims, in_channels, model_channels, 3, padding=1, dtype=self.dtype, device=device) + ) + ] + ) + self.zero_convs = nn.ModuleList([self.make_zero_conv(model_channels)]) + + self.input_hint_block = TimestepEmbedSequential( + conv_nd(dims, hint_channels, 16, 3, padding=1), + nn.SiLU(), + conv_nd(dims, 16, 16, 3, padding=1), + nn.SiLU(), + conv_nd(dims, 16, 32, 3, padding=1, stride=2), + nn.SiLU(), + conv_nd(dims, 32, 32, 3, padding=1), + nn.SiLU(), + conv_nd(dims, 32, 96, 3, padding=1, stride=2), + nn.SiLU(), + conv_nd(dims, 96, 96, 3, padding=1), + nn.SiLU(), + conv_nd(dims, 96, 256, 3, padding=1, stride=2), + nn.SiLU(), + zero_module(conv_nd(dims, 256, model_channels, 3, padding=1)) + ) + + self._feature_size = model_channels + input_block_chans = [model_channels] + ch = model_channels + ds = 1 + for level, mult in enumerate(channel_mult): + for nr in range(self.num_res_blocks[level]): + layers = [ + ResBlock( + ch, + time_embed_dim, + dropout, + out_channels=mult * model_channels, + dims=dims, + use_checkpoint=use_checkpoint, + use_scale_shift_norm=use_scale_shift_norm + ) + ] + ch = mult * model_channels + if ds in attention_resolutions: + if num_head_channels == -1: + dim_head = ch // num_heads + else: + num_heads = ch // num_head_channels + dim_head = num_head_channels + if legacy: + #num_heads = 1 + dim_head = ch // num_heads if use_spatial_transformer else num_head_channels + if exists(disable_self_attentions): + disabled_sa = disable_self_attentions[level] + else: + disabled_sa = False + + if not exists(num_attention_blocks) or nr < num_attention_blocks[level]: + layers.append( + SpatialTransformer( + ch, num_heads, dim_head, depth=transformer_depth[level], context_dim=context_dim, + disable_self_attn=disabled_sa, use_linear=use_linear_in_transformer, + use_checkpoint=use_checkpoint + ) + ) + self.input_blocks.append(TimestepEmbedSequential(*layers)) + self.zero_convs.append(self.make_zero_conv(ch)) + self._feature_size += ch + input_block_chans.append(ch) + if level != len(channel_mult) - 1: + out_ch = ch + self.input_blocks.append( + TimestepEmbedSequential( + ResBlock( + ch, + time_embed_dim, + dropout, + out_channels=out_ch, + dims=dims, + use_checkpoint=use_checkpoint, + use_scale_shift_norm=use_scale_shift_norm, + down=True + ) + if resblock_updown + else Downsample( + ch, conv_resample, dims=dims, out_channels=out_ch + ) + ) + ) + ch = out_ch + input_block_chans.append(ch) + self.zero_convs.append(self.make_zero_conv(ch)) + ds *= 2 + self._feature_size += ch + + if num_head_channels == -1: + dim_head = ch // num_heads + else: + num_heads = ch // num_head_channels + dim_head = num_head_channels + if legacy: + #num_heads = 1 + dim_head = ch // num_heads if use_spatial_transformer else num_head_channels + self.middle_block = TimestepEmbedSequential( + ResBlock( + ch, + time_embed_dim, + dropout, + dims=dims, + use_checkpoint=use_checkpoint, + use_scale_shift_norm=use_scale_shift_norm + ), + SpatialTransformer( # always uses a self-attn + ch, num_heads, dim_head, depth=transformer_depth_middle, context_dim=context_dim, + disable_self_attn=disable_middle_self_attn, use_linear=use_linear_in_transformer, + use_checkpoint=use_checkpoint + ), + ResBlock( + ch, + time_embed_dim, + dropout, + dims=dims, + use_checkpoint=use_checkpoint, + use_scale_shift_norm=use_scale_shift_norm + ), + ) + self.middle_block_out = self.make_zero_conv(ch) + self._feature_size += ch + + def make_zero_conv(self, channels): + return TimestepEmbedSequential(zero_module(conv_nd(self.dims, channels, channels, 1, padding=0))) + + def forward(self, x, hint, timesteps, context, y=None, **kwargs): + original_type = x.dtype + + x = x.to(self.dtype) + hint = hint.to(self.dtype) + timesteps = timesteps.to(self.dtype) + context = context.to(self.dtype) + + if y is not None: + y = y.to(self.dtype) + + t_emb = timestep_embedding(timesteps, self.model_channels, repeat_only=False).to(self.dtype) + emb = self.time_embed(t_emb) + + guided_hint = self.input_hint_block(hint, emb, context) + outs = [] + + if self.num_classes is not None: + assert y.shape[0] == x.shape[0] + emb = emb + self.label_emb(y) + + h = x + for module, zero_conv in zip(self.input_blocks, self.zero_convs): + if guided_hint is not None: + h = module(h, emb, context) + h += guided_hint + guided_hint = None + else: + h = module(h, emb, context) + outs.append(zero_conv(h, emb, context)) + + h = self.middle_block(h, emb, context) + outs.append(self.middle_block_out(h, emb, context)) + + outs = [o.to(original_type) for o in outs] + + return outs diff --git a/extensions-builtin/sd_forge_controlnet/scripts/controlmodel_ipadapter.py b/extensions-builtin/sd_forge_controlnet/scripts/controlmodel_ipadapter.py new file mode 100644 index 00000000..6e6c66a8 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/controlmodel_ipadapter.py @@ -0,0 +1,614 @@ +import math +from typing import List + +import torch +import torch.nn as nn +from transformers.models.clip.modeling_clip import CLIPVisionModelOutput +from scripts.logging import logger + + +class MLPProjModel(torch.nn.Module): + def __init__(self, cross_attention_dim=1024, clip_embeddings_dim=1024): + super().__init__() + + self.proj = torch.nn.Sequential( + torch.nn.Linear(clip_embeddings_dim, clip_embeddings_dim), + torch.nn.GELU(), + torch.nn.Linear(clip_embeddings_dim, cross_attention_dim), + torch.nn.LayerNorm(cross_attention_dim) + ) + + def forward(self, image_embeds): + clip_extra_context_tokens = self.proj(image_embeds) + return clip_extra_context_tokens + + +class MLPProjModelFaceId(torch.nn.Module): + """ MLPProjModel used for FaceId. + Source: https://github.com/tencent-ailab/IP-Adapter/blob/main/ip_adapter/ip_adapter_faceid.py + """ + def __init__(self, cross_attention_dim=768, id_embeddings_dim=512, num_tokens=4): + super().__init__() + + self.cross_attention_dim = cross_attention_dim + self.num_tokens = num_tokens + + self.proj = torch.nn.Sequential( + torch.nn.Linear(id_embeddings_dim, id_embeddings_dim*2), + torch.nn.GELU(), + torch.nn.Linear(id_embeddings_dim*2, cross_attention_dim*num_tokens), + ) + self.norm = torch.nn.LayerNorm(cross_attention_dim) + + def forward(self, id_embeds): + clip_extra_context_tokens = self.proj(id_embeds) + clip_extra_context_tokens = clip_extra_context_tokens.reshape(-1, self.num_tokens, self.cross_attention_dim) + clip_extra_context_tokens = self.norm(clip_extra_context_tokens) + return clip_extra_context_tokens + + + +class FacePerceiverResampler(torch.nn.Module): + """ Source: https://github.com/tencent-ailab/IP-Adapter/blob/main/ip_adapter/ip_adapter_faceid.py """ + def __init__( + self, + *, + dim=768, + depth=4, + dim_head=64, + heads=16, + embedding_dim=1280, + output_dim=768, + ff_mult=4, + ): + super().__init__() + + self.proj_in = torch.nn.Linear(embedding_dim, dim) + self.proj_out = torch.nn.Linear(dim, output_dim) + self.norm_out = torch.nn.LayerNorm(output_dim) + self.layers = torch.nn.ModuleList([]) + for _ in range(depth): + self.layers.append( + torch.nn.ModuleList( + [ + PerceiverAttention(dim=dim, dim_head=dim_head, heads=heads), + FeedForward(dim=dim, mult=ff_mult), + ] + ) + ) + + def forward(self, latents, x): + x = self.proj_in(x) + for attn, ff in self.layers: + latents = attn(x, latents) + latents + latents = ff(latents) + latents + latents = self.proj_out(latents) + return self.norm_out(latents) + + +class ProjModelFaceIdPlus(torch.nn.Module): + """ Source: https://github.com/tencent-ailab/IP-Adapter/blob/main/ip_adapter/ip_adapter_faceid.py """ + def __init__(self, cross_attention_dim=768, id_embeddings_dim=512, clip_embeddings_dim=1280, num_tokens=4): + super().__init__() + + self.cross_attention_dim = cross_attention_dim + self.num_tokens = num_tokens + + self.proj = torch.nn.Sequential( + torch.nn.Linear(id_embeddings_dim, id_embeddings_dim*2), + torch.nn.GELU(), + torch.nn.Linear(id_embeddings_dim*2, cross_attention_dim*num_tokens), + ) + self.norm = torch.nn.LayerNorm(cross_attention_dim) + + self.perceiver_resampler = FacePerceiverResampler( + dim=cross_attention_dim, + depth=4, + dim_head=64, + heads=cross_attention_dim // 64, + embedding_dim=clip_embeddings_dim, + output_dim=cross_attention_dim, + ff_mult=4, + ) + + def forward(self, id_embeds, clip_embeds, scale=1.0, shortcut=False): + x = self.proj(id_embeds) + x = x.reshape(-1, self.num_tokens, self.cross_attention_dim) + x = self.norm(x) + out = self.perceiver_resampler(x, clip_embeds) + if shortcut: + out = x + scale * out + return out + + +class ImageProjModel(torch.nn.Module): + """Projection Model""" + + def __init__(self, cross_attention_dim=1024, clip_embeddings_dim=1024, clip_extra_context_tokens=4): + super().__init__() + + self.cross_attention_dim = cross_attention_dim + self.clip_extra_context_tokens = clip_extra_context_tokens + self.proj = torch.nn.Linear(clip_embeddings_dim, self.clip_extra_context_tokens * cross_attention_dim) + self.norm = torch.nn.LayerNorm(cross_attention_dim) + + def forward(self, image_embeds): + embeds = image_embeds + clip_extra_context_tokens = self.proj(embeds).reshape(-1, self.clip_extra_context_tokens, + self.cross_attention_dim) + clip_extra_context_tokens = self.norm(clip_extra_context_tokens) + return clip_extra_context_tokens + + +# Cross Attention to_k, to_v for IPAdapter +class To_KV(torch.nn.Module): + def __init__(self, state_dict): + super().__init__() + + self.to_kvs = nn.ModuleDict() + for key, value in state_dict.items(): + k = key.replace(".weight", "").replace(".", "_") + self.to_kvs[k] = nn.Linear(value.shape[1], value.shape[0], bias=False) + self.to_kvs[k].weight.data = value + + +def FeedForward(dim, mult=4): + inner_dim = int(dim * mult) + return nn.Sequential( + nn.LayerNorm(dim), + nn.Linear(dim, inner_dim, bias=False), + nn.GELU(), + nn.Linear(inner_dim, dim, bias=False), + ) + + +def reshape_tensor(x, heads): + bs, length, width = x.shape + #(bs, length, width) --> (bs, length, n_heads, dim_per_head) + x = x.view(bs, length, heads, -1) + # (bs, length, n_heads, dim_per_head) --> (bs, n_heads, length, dim_per_head) + x = x.transpose(1, 2) + # (bs, n_heads, length, dim_per_head) --> (bs*n_heads, length, dim_per_head) + x = x.reshape(bs, heads, length, -1) + return x + + +class PerceiverAttention(nn.Module): + def __init__(self, *, dim, dim_head=64, heads=8): + super().__init__() + self.scale = dim_head**-0.5 + self.dim_head = dim_head + self.heads = heads + inner_dim = dim_head * heads + + self.norm1 = nn.LayerNorm(dim) + self.norm2 = nn.LayerNorm(dim) + + self.to_q = nn.Linear(dim, inner_dim, bias=False) + self.to_kv = nn.Linear(dim, inner_dim * 2, bias=False) + self.to_out = nn.Linear(inner_dim, dim, bias=False) + + + def forward(self, x, latents): + """ + Args: + x (torch.Tensor): image features + shape (b, n1, D) + latent (torch.Tensor): latent features + shape (b, n2, D) + """ + x = self.norm1(x) + latents = self.norm2(latents) + + b, l, _ = latents.shape + + q = self.to_q(latents) + kv_input = torch.cat((x, latents), dim=-2) + k, v = self.to_kv(kv_input).chunk(2, dim=-1) + + q = reshape_tensor(q, self.heads) + k = reshape_tensor(k, self.heads) + v = reshape_tensor(v, self.heads) + + # attention + scale = 1 / math.sqrt(math.sqrt(self.dim_head)) + weight = (q * scale) @ (k * scale).transpose(-2, -1) # More stable with f16 than dividing afterwards + weight = torch.softmax(weight.float(), dim=-1).type(weight.dtype) + out = weight @ v + + out = out.permute(0, 2, 1, 3).reshape(b, l, -1) + + return self.to_out(out) + + +class Resampler(nn.Module): + def __init__( + self, + dim=1024, + depth=8, + dim_head=64, + heads=16, + num_queries=8, + embedding_dim=768, + output_dim=1024, + ff_mult=4, + ): + super().__init__() + + self.latents = nn.Parameter(torch.randn(1, num_queries, dim) / dim**0.5) + + self.proj_in = nn.Linear(embedding_dim, dim) + + self.proj_out = nn.Linear(dim, output_dim) + self.norm_out = nn.LayerNorm(output_dim) + + self.layers = nn.ModuleList([]) + for _ in range(depth): + self.layers.append( + nn.ModuleList( + [ + PerceiverAttention(dim=dim, dim_head=dim_head, heads=heads), + FeedForward(dim=dim, mult=ff_mult), + ] + ) + ) + + def forward(self, x): + + latents = self.latents.repeat(x.size(0), 1, 1) + + x = self.proj_in(x) + + for attn, ff in self.layers: + latents = attn(x, latents) + latents + latents = ff(latents) + latents + + latents = self.proj_out(latents) + return self.norm_out(latents) + + +class IPAdapterModel(torch.nn.Module): + def __init__(self, state_dict, clip_embeddings_dim, cross_attention_dim, + is_plus, sdxl_plus, is_full, is_faceid: bool, is_portrait: bool): + super().__init__() + self.device = "cpu" + + self.clip_embeddings_dim = clip_embeddings_dim + self.cross_attention_dim = cross_attention_dim + self.is_plus = is_plus + self.sdxl_plus = sdxl_plus + self.is_full = is_full + self.clip_extra_context_tokens = 16 if (self.is_plus or is_portrait) else 4 + + if is_faceid: + self.image_proj_model = self.init_proj_faceid() + elif self.is_plus: + if self.is_full: + self.image_proj_model = MLPProjModel( + cross_attention_dim=cross_attention_dim, + clip_embeddings_dim=clip_embeddings_dim + ) + else: + self.image_proj_model = Resampler( + dim=1280 if sdxl_plus else cross_attention_dim, + depth=4, + dim_head=64, + heads=20 if sdxl_plus else 12, + num_queries=self.clip_extra_context_tokens, + embedding_dim=clip_embeddings_dim, + output_dim=self.cross_attention_dim, + ff_mult=4 + ) + else: + self.clip_extra_context_tokens = state_dict["image_proj"]["proj.weight"].shape[0] // self.cross_attention_dim + + self.image_proj_model = ImageProjModel( + cross_attention_dim=self.cross_attention_dim, + clip_embeddings_dim=clip_embeddings_dim, + clip_extra_context_tokens=self.clip_extra_context_tokens + ) + + self.load_ip_adapter(state_dict) + + def init_proj_faceid(self): + if self.is_plus: + image_proj_model = ProjModelFaceIdPlus( + cross_attention_dim=self.cross_attention_dim, + id_embeddings_dim=512, + clip_embeddings_dim=self.clip_embeddings_dim, + num_tokens=4, + ) + else: + image_proj_model = MLPProjModelFaceId( + cross_attention_dim=self.cross_attention_dim, + id_embeddings_dim=512, + num_tokens=self.clip_extra_context_tokens, + ) + return image_proj_model + + def load_ip_adapter(self, state_dict): + self.image_proj_model.load_state_dict(state_dict["image_proj"]) + self.ip_layers = To_KV(state_dict["ip_adapter"]) + + @torch.inference_mode() + def get_image_embeds(self, clip_vision_output: CLIPVisionModelOutput): + self.image_proj_model.cpu() + + if self.is_plus: + from annotator.clipvision import clip_vision_h_uc, clip_vision_vith_uc + cond = self.image_proj_model(clip_vision_output['hidden_states'][-2].to(device='cpu', dtype=torch.float32)) + uncond = clip_vision_vith_uc.to(cond) if self.sdxl_plus else self.image_proj_model(clip_vision_h_uc.to(cond)) + return cond, uncond + + clip_image_embeds = clip_vision_output['image_embeds'].to(device='cpu', dtype=torch.float32) + image_prompt_embeds = self.image_proj_model(clip_image_embeds) + # input zero vector for unconditional. + uncond_image_prompt_embeds = self.image_proj_model(torch.zeros_like(clip_image_embeds)) + return image_prompt_embeds, uncond_image_prompt_embeds + + @torch.inference_mode() + def get_image_embeds_faceid_plus(self, face_embed, clip_vision_output: CLIPVisionModelOutput, is_v2: bool): + face_embed = face_embed.to(self.device, dtype=torch.float32) + from annotator.clipvision import clip_vision_h_uc + clip_embed = clip_vision_output['hidden_states'][-2].to(device=self.device, dtype=torch.float32) + return ( + self.image_proj_model(face_embed, clip_embed, shortcut=is_v2), + self.image_proj_model(torch.zeros_like(face_embed), clip_vision_h_uc.to(clip_embed), shortcut=is_v2), + ) + + @torch.inference_mode() + def get_image_embeds_faceid(self, insightface_outputs: List[torch.Tensor]): + """Get image embeds for non-plus faceid. Multiple inputs are supported.""" + batch_size = len(insightface_outputs) + + faceid_embeds = torch.cat(insightface_outputs, dim=0).to(self.device, dtype=torch.float32) + assert faceid_embeds.ndim == 2 + image_prompt_embeds = self.image_proj_model(faceid_embeds) + uncond_image_prompt_embeds = self.image_proj_model(torch.zeros_like(faceid_embeds)) + + c = image_prompt_embeds.size(-1) + image_prompt_embeds = image_prompt_embeds.reshape(batch_size, -1, c) + uncond_image_prompt_embeds = uncond_image_prompt_embeds.reshape(batch_size, -1, c) + return image_prompt_embeds, uncond_image_prompt_embeds + + +def get_block(model, flag): + return { + 'input': model.input_blocks, 'middle': [model.middle_block], 'output': model.output_blocks + }[flag] + + +def attn_forward_hacked(self, x, context=None, **kwargs): + batch_size, sequence_length, inner_dim = x.shape + h = self.heads + head_dim = inner_dim // h + + if context is None: + context = x + + q = self.to_q(x) + k = self.to_k(context) + v = self.to_v(context) + + del context + + q, k, v = map( + lambda t: t.view(batch_size, -1, h, head_dim).transpose(1, 2), + (q, k, v), + ) + + out = torch.nn.functional.scaled_dot_product_attention(q, k, v, attn_mask=None, dropout_p=0.0, is_causal=False) + out = out.transpose(1, 2).reshape(batch_size, -1, h * head_dim) + + del k, v + + for f in self.ipadapter_hacks: + out = out + f(self, x, q) + + del q, x + + return self.to_out(out) + + +all_hacks = {} +current_model = None + + +def hack_blk(block, function, type): + if not hasattr(block, 'ipadapter_hacks'): + block.ipadapter_hacks = [] + + if len(block.ipadapter_hacks) == 0: + all_hacks[block] = block.forward + block.forward = attn_forward_hacked.__get__(block, type) + + block.ipadapter_hacks.append(function) + return + + +def set_model_attn2_replace(model, function, flag, id): + from ldm.modules.attention import CrossAttention + block = get_block(model, flag)[id][1].transformer_blocks[0].attn2 + hack_blk(block, function, CrossAttention) + return + + +def set_model_patch_replace(model, function, flag, id, trans_id): + from sgm.modules.attention import CrossAttention + blk = get_block(model, flag) + block = blk[id][1].transformer_blocks[trans_id].attn2 + hack_blk(block, function, CrossAttention) + return + + +def clear_all_ip_adapter(): + global all_hacks, current_model + for k, v in all_hacks.items(): + k.forward = v + k.ipadapter_hacks = [] + all_hacks = {} + current_model = None + return + + +class PlugableIPAdapter(torch.nn.Module): + def __init__(self, state_dict, model_name: str): + """ + Arguments: + - state_dict: model state_dict. + - model_name: file name of the model. + """ + super().__init__() + self.is_v2 = "v2" in model_name + self.is_faceid = "faceid" in model_name + self.is_portrait = "portrait" in model_name + self.is_full = "proj.3.weight" in state_dict['image_proj'] + self.is_plus = ( + self.is_full or + "latents" in state_dict["image_proj"] or + "perceiver_resampler.proj_in.weight" in state_dict["image_proj"] + ) + cross_attention_dim = state_dict["ip_adapter"]["1.to_k_ip.weight"].shape[1] + self.sdxl = cross_attention_dim == 2048 + self.sdxl_plus = self.sdxl and self.is_plus + if self.is_faceid and self.is_v2 and self.is_plus: + logger.info("IP-Adapter faceid plus v2 detected.") + + if self.is_faceid: + if self.is_plus: + clip_embeddings_dim = 1280 + else: + # Plain faceid does not use clip_embeddings_dim. + clip_embeddings_dim = None + elif self.is_plus: + if self.sdxl_plus: + clip_embeddings_dim = int(state_dict["image_proj"]["latents"].shape[2]) + elif self.is_full: + clip_embeddings_dim = int(state_dict["image_proj"]["proj.0.weight"].shape[1]) + else: + clip_embeddings_dim = int(state_dict['image_proj']['proj_in.weight'].shape[1]) + else: + clip_embeddings_dim = int(state_dict['image_proj']['proj.weight'].shape[1]) + + self.ipadapter = IPAdapterModel(state_dict, + clip_embeddings_dim=clip_embeddings_dim, + cross_attention_dim=cross_attention_dim, + is_plus=self.is_plus, + sdxl_plus=self.sdxl_plus, + is_full=self.is_full, + is_faceid=self.is_faceid, + is_portrait=self.is_portrait) + self.disable_memory_management = True + self.dtype = None + self.weight = 1.0 + self.cache = None + self.p_start = 0.0 + self.p_end = 1.0 + return + + def reset(self): + self.cache = {} + return + + @torch.no_grad() + def hook(self, model, clip_vision_output, weight, start, end, dtype=torch.float32): + global current_model + current_model = model + + self.p_start = start + self.p_end = end + + self.cache = {} + + self.weight = weight + device = torch.device('cpu') + self.dtype = dtype + + self.ipadapter.to(device, dtype=self.dtype) + if self.is_faceid and self.is_plus: + # Note: FaceID plus uses both face_embed and clip_embed. + # This should be the return value from preprocessor. + assert isinstance(clip_vision_output, (list, tuple)) + assert len(clip_vision_output) == 2 + self.image_emb, self.uncond_image_emb = self.ipadapter.get_image_embeds_faceid_plus(*clip_vision_output, is_v2=self.is_v2) + elif self.is_faceid: + assert isinstance(clip_vision_output, (list, tuple)) + self.image_emb, self.uncond_image_emb = self.ipadapter.get_image_embeds_faceid(clip_vision_output) + else: + self.image_emb, self.uncond_image_emb = self.ipadapter.get_image_embeds(clip_vision_output) + + self.image_emb = self.image_emb.to(device, dtype=self.dtype) + self.uncond_image_emb = self.uncond_image_emb.to(device, dtype=self.dtype) + + # From https://github.com/laksjdjf/IPAdapter-ComfyUI + if not self.sdxl: + number = 0 # index of to_kvs + for id in [1, 2, 4, 5, 7, 8]: # id of input_blocks that have cross attention + set_model_attn2_replace(model, self.patch_forward(number), "input", id) + number += 1 + for id in [3, 4, 5, 6, 7, 8, 9, 10, 11]: # id of output_blocks that have cross attention + set_model_attn2_replace(model, self.patch_forward(number), "output", id) + number += 1 + set_model_attn2_replace(model, self.patch_forward(number), "middle", 0) + else: + number = 0 + for id in [4, 5, 7, 8]: # id of input_blocks that have cross attention + block_indices = range(2) if id in [4, 5] else range(10) # transformer_depth + for index in block_indices: + set_model_patch_replace(model, self.patch_forward(number), "input", id, index) + number += 1 + for id in range(6): # id of output_blocks that have cross attention + block_indices = range(2) if id in [3, 4, 5] else range(10) # transformer_depth + for index in block_indices: + set_model_patch_replace(model, self.patch_forward(number), "output", id, index) + number += 1 + for index in range(10): + set_model_patch_replace(model, self.patch_forward(number), "middle", 0, index) + number += 1 + + return + + def call_ip(self, key: str, feat, device): + if key in self.cache: + return self.cache[key] + else: + ip = self.ipadapter.ip_layers.to_kvs[key](feat).to(device) + self.cache[key] = ip + return ip + + @torch.no_grad() + def patch_forward(self, number: int): + @torch.no_grad() + def forward(attn_blk, x, q): + batch_size, sequence_length, inner_dim = x.shape + h = attn_blk.heads + head_dim = inner_dim // h + + current_sampling_percent = getattr(current_model, 'current_sampling_percent', 0.5) + if current_sampling_percent < self.p_start or current_sampling_percent > self.p_end: + return 0 + + cond_mark = current_model.cond_mark[:, :, :, 0].to(self.image_emb) + cond_uncond_image_emb = self.image_emb * cond_mark + self.uncond_image_emb * (1 - cond_mark) + k_key = f"{number * 2 + 1}_to_k_ip" + v_key = f"{number * 2 + 1}_to_v_ip" + ip_k = self.call_ip(k_key, cond_uncond_image_emb, device=q.device) + ip_v = self.call_ip(v_key, cond_uncond_image_emb, device=q.device) + + ip_k, ip_v = map( + lambda t: t.view(batch_size, -1, h, head_dim).transpose(1, 2), + (ip_k, ip_v), + ) + assert ip_k.dtype == ip_v.dtype + + # On MacOS, q can be float16 instead of float32. + # https://github.com/Mikubill/sd-webui-controlnet/issues/2208 + if q.dtype != ip_k.dtype: + ip_k = ip_k.to(dtype=q.dtype) + ip_v = ip_v.to(dtype=q.dtype) + + ip_out = torch.nn.functional.scaled_dot_product_attention(q, ip_k, ip_v, attn_mask=None, dropout_p=0.0, is_causal=False) + ip_out = ip_out.transpose(1, 2).reshape(batch_size, -1, h * head_dim) + + return ip_out * self.weight + return forward diff --git a/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py b/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py new file mode 100644 index 00000000..7e2742bb --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py @@ -0,0 +1,1283 @@ +import gc +import tracemalloc +import os +import logging +from collections import OrderedDict +from copy import copy +from typing import Dict, Optional, Tuple +import modules.scripts as scripts +from modules import shared, devices, script_callbacks, processing, masking, images +from modules.api.api import decode_base64_to_image +import gradio as gr +import time + +from einops import rearrange +from scripts import global_state, hook, external_code, batch_hijack, controlnet_version, utils +from scripts.controlnet_lora import bind_control_lora, unbind_control_lora +from scripts.processor import * +from scripts.controlnet_lllite import clear_all_lllite +from scripts.controlmodel_ipadapter import clear_all_ip_adapter +from scripts.utils import load_state_dict, get_unique_axis0, align_dim_latent +from scripts.hook import ControlParams, UnetHook, HackedImageRNG +from scripts.enums import ControlModelType, StableDiffusionVersion, HiResFixOption +from scripts.controlnet_ui.controlnet_ui_group import ControlNetUiGroup, UiControlNetUnit +from scripts.controlnet_ui.photopea import Photopea +from scripts.logging import logger +from modules.processing import StableDiffusionProcessingImg2Img, StableDiffusionProcessingTxt2Img, StableDiffusionProcessing +from modules.images import save_image +from scripts.infotext import Infotext + +import cv2 +import numpy as np +import torch + +from PIL import Image, ImageFilter, ImageOps +from scripts.lvminthin import lvmin_thin, nake_nms +from scripts.processor import model_free_preprocessors +from scripts.controlnet_model_guess import build_model_by_guess, ControlModel +from scripts.hook import torch_dfs + + +# Gradio 3.32 bug fix +import tempfile +gradio_tempfile_path = os.path.join(tempfile.gettempdir(), 'gradio') +os.makedirs(gradio_tempfile_path, exist_ok=True) + + +def clear_all_secondary_control_models(m): + all_modules = torch_dfs(m) + + for module in all_modules: + _original_inner_forward_cn_hijack = getattr(module, '_original_inner_forward_cn_hijack', None) + original_forward_cn_hijack = getattr(module, 'original_forward_cn_hijack', None) + if _original_inner_forward_cn_hijack is not None: + module._forward = _original_inner_forward_cn_hijack + if original_forward_cn_hijack is not None: + module.forward = original_forward_cn_hijack + + clear_all_lllite() + clear_all_ip_adapter() + + +def find_closest_lora_model_name(search: str): + if not search: + return None + if search in global_state.cn_models: + return search + search = search.lower() + if search in global_state.cn_models_names: + return global_state.cn_models_names.get(search) + applicable = [name for name in global_state.cn_models_names.keys() + if search in name.lower()] + if not applicable: + return None + applicable = sorted(applicable, key=lambda name: len(name)) + return global_state.cn_models_names[applicable[0]] + + +def swap_img2img_pipeline(p: processing.StableDiffusionProcessingImg2Img): + p.__class__ = processing.StableDiffusionProcessingTxt2Img + dummy = processing.StableDiffusionProcessingTxt2Img() + for k,v in dummy.__dict__.items(): + if hasattr(p, k): + continue + setattr(p, k, v) + + +global_state.update_cn_models() + + +def image_dict_from_any(image) -> Optional[Dict[str, np.ndarray]]: + if image is None: + return None + + if isinstance(image, (tuple, list)): + image = {'image': image[0], 'mask': image[1]} + elif not isinstance(image, dict): + image = {'image': image, 'mask': None} + else: # type(image) is dict + # copy to enable modifying the dict and prevent response serialization error + image = dict(image) + + if isinstance(image['image'], str): + if os.path.exists(image['image']): + image['image'] = np.array(Image.open(image['image'])).astype('uint8') + elif image['image']: + image['image'] = external_code.to_base64_nparray(image['image']) + else: + image['image'] = None + + # If there is no image, return image with None image and None mask + if image['image'] is None: + image['mask'] = None + return image + + if 'mask' not in image or image['mask'] is None: + image['mask'] = np.zeros_like(image['image'], dtype=np.uint8) + elif isinstance(image['mask'], str): + if os.path.exists(image['mask']): + image['mask'] = np.array(Image.open(image['mask'])).astype('uint8') + elif image['mask']: + image['mask'] = external_code.to_base64_nparray(image['mask']) + else: + image['mask'] = np.zeros_like(image['image'], dtype=np.uint8) + + return image + + +def prepare_mask( + mask: Image.Image, p: processing.StableDiffusionProcessing +) -> Image.Image: + """ + Prepare an image mask for the inpainting process. + + This function takes as input a PIL Image object and an instance of the + StableDiffusionProcessing class, and performs the following steps to prepare the mask: + + 1. Convert the mask to grayscale (mode "L"). + 2. If the 'inpainting_mask_invert' attribute of the processing instance is True, + invert the mask colors. + 3. If the 'mask_blur' attribute of the processing instance is greater than 0, + apply a Gaussian blur to the mask with a radius equal to 'mask_blur'. + + Args: + mask (Image.Image): The input mask as a PIL Image object. + p (processing.StableDiffusionProcessing): An instance of the StableDiffusionProcessing class + containing the processing parameters. + + Returns: + mask (Image.Image): The prepared mask as a PIL Image object. + """ + mask = mask.convert("L") + if getattr(p, "inpainting_mask_invert", False): + mask = ImageOps.invert(mask) + + if hasattr(p, 'mask_blur_x'): + if getattr(p, "mask_blur_x", 0) > 0: + np_mask = np.array(mask) + kernel_size = 2 * int(2.5 * p.mask_blur_x + 0.5) + 1 + np_mask = cv2.GaussianBlur(np_mask, (kernel_size, 1), p.mask_blur_x) + mask = Image.fromarray(np_mask) + if getattr(p, "mask_blur_y", 0) > 0: + np_mask = np.array(mask) + kernel_size = 2 * int(2.5 * p.mask_blur_y + 0.5) + 1 + np_mask = cv2.GaussianBlur(np_mask, (1, kernel_size), p.mask_blur_y) + mask = Image.fromarray(np_mask) + else: + if getattr(p, "mask_blur", 0) > 0: + mask = mask.filter(ImageFilter.GaussianBlur(p.mask_blur)) + + return mask + + +def set_numpy_seed(p: processing.StableDiffusionProcessing) -> Optional[int]: + """ + Set the random seed for NumPy based on the provided parameters. + + Args: + p (processing.StableDiffusionProcessing): The instance of the StableDiffusionProcessing class. + + Returns: + Optional[int]: The computed random seed if successful, or None if an exception occurs. + + This function sets the random seed for NumPy using the seed and subseed values from the given instance of + StableDiffusionProcessing. If either seed or subseed is -1, it uses the first value from `all_seeds`. + Otherwise, it takes the maximum of the provided seed value and 0. + + The final random seed is computed by adding the seed and subseed values, applying a bitwise AND operation + with 0xFFFFFFFF to ensure it fits within a 32-bit integer. + """ + try: + tmp_seed = int(p.all_seeds[0] if p.seed == -1 else max(int(p.seed), 0)) + tmp_subseed = int(p.all_seeds[0] if p.subseed == -1 else max(int(p.subseed), 0)) + seed = (tmp_seed + tmp_subseed) & 0xFFFFFFFF + np.random.seed(seed) + return seed + except Exception as e: + logger.warning(e) + logger.warning('Warning: Failed to use consistent random seed.') + return None + + +class Script(scripts.Script, metaclass=( + utils.TimeMeta if logger.level == logging.DEBUG else type)): + + model_cache: Dict[str, ControlModel] = OrderedDict() + + def __init__(self) -> None: + super().__init__() + self.latest_network = None + self.preprocessor = global_state.cache_preprocessors(global_state.cn_preprocessor_modules) + self.unloadable = global_state.cn_preprocessor_unloadable + self.input_image = None + self.latest_model_hash = "" + self.enabled_units = [] + self.detected_map = [] + self.post_processors = [] + self.noise_modifier = None + self.ui_batch_option_state = [external_code.BatchOption.DEFAULT.value, False] + batch_hijack.instance.process_batch_callbacks.append(self.batch_tab_process) + batch_hijack.instance.process_batch_each_callbacks.append(self.batch_tab_process_each) + batch_hijack.instance.postprocess_batch_each_callbacks.insert(0, self.batch_tab_postprocess_each) + batch_hijack.instance.postprocess_batch_callbacks.insert(0, self.batch_tab_postprocess) + + def title(self): + return "ControlNet" + + def show(self, is_img2img): + return scripts.AlwaysVisible + + @staticmethod + def get_default_ui_unit(is_ui=True): + cls = UiControlNetUnit if is_ui else external_code.ControlNetUnit + return cls( + enabled=False, + module="none", + model="None" + ) + + def uigroup(self, tabname: str, is_img2img: bool, elem_id_tabname: str, photopea: Optional[Photopea]) -> Tuple[ControlNetUiGroup, gr.State]: + group = ControlNetUiGroup( + is_img2img, + Script.get_default_ui_unit(), + self.preprocessor, + photopea, + ) + return group, group.render(tabname, elem_id_tabname) + + def ui_batch_options(self, is_img2img: bool, elem_id_tabname: str): + batch_option = gr.Radio( + choices=[e.value for e in external_code.BatchOption], + value=external_code.BatchOption.DEFAULT.value, + label="Batch Option", + elem_id=f"{elem_id_tabname}_controlnet_batch_option_radio", + elem_classes="controlnet_batch_option_radio", + ) + use_batch_style_align = gr.Checkbox( + label='[StyleAlign] Align image style in the batch.' + ) + + unit_args = [batch_option, use_batch_style_align] + + def update_ui_batch_options(*args): + self.ui_batch_option_state = args + return + + for comp in unit_args: + event_subscribers = [] + if hasattr(comp, "edit"): + event_subscribers.append(comp.edit) + elif hasattr(comp, "click"): + event_subscribers.append(comp.click) + elif isinstance(comp, gr.Slider) and hasattr(comp, "release"): + event_subscribers.append(comp.release) + elif hasattr(comp, "change"): + event_subscribers.append(comp.change) + + if hasattr(comp, "clear"): + event_subscribers.append(comp.clear) + + for event_subscriber in event_subscribers: + event_subscriber( + fn=update_ui_batch_options, inputs=unit_args + ) + + return + + def ui(self, is_img2img): + """this function should create gradio UI elements. See https://gradio.app/docs/#components + The return value should be an array of all components that are used in processing. + Values of those returned components will be passed to run() and process() functions. + """ + infotext = Infotext() + ui_groups = [] + controls = [] + max_models = shared.opts.data.get("control_net_unit_count", 3) + elem_id_tabname = ("img2img" if is_img2img else "txt2img") + "_controlnet" + with gr.Group(elem_id=elem_id_tabname): + with gr.Accordion(f"ControlNet {controlnet_version.version_flag}", open = False, elem_id="controlnet"): + photopea = Photopea() if not shared.opts.data.get("controlnet_disable_photopea_edit", False) else None + if max_models > 1: + with gr.Tabs(elem_id=f"{elem_id_tabname}_tabs"): + for i in range(max_models): + with gr.Tab(f"ControlNet Unit {i}", + elem_classes=['cnet-unit-tab']): + group, state = self.uigroup(f"ControlNet-{i}", is_img2img, elem_id_tabname, photopea) + ui_groups.append(group) + controls.append(state) + else: + with gr.Column(): + group, state = self.uigroup(f"ControlNet", is_img2img, elem_id_tabname, photopea) + ui_groups.append(group) + controls.append(state) + with gr.Accordion(f"Batch Options", open=False, elem_id="controlnet_batch_options"): + self.ui_batch_options(is_img2img, elem_id_tabname) + + for i, ui_group in enumerate(ui_groups): + infotext.register_unit(i, ui_group) + if shared.opts.data.get("control_net_sync_field_args", True): + self.infotext_fields = infotext.infotext_fields + self.paste_field_names = infotext.paste_field_names + + return tuple(controls) + + @staticmethod + def clear_control_model_cache(): + Script.model_cache.clear() + gc.collect() + devices.torch_gc() + + @staticmethod + def load_control_model(p, unet, model) -> ControlModel: + if model in Script.model_cache: + logger.info(f"Loading model from cache: {model}") + control_model = Script.model_cache[model] + if control_model.type == ControlModelType.Controlllite: + # Falls through to load Controlllite model fresh. + # TODO Fix context sharing issue for Controlllite. + pass + elif not control_model.type.allow_context_sharing(): + # Creates a shallow-copy of control_model so that configs/inputs + # from different units can be bind correctly. While heavy objects + # of the underlying nn.Module is not copied. + return ControlModel(copy(control_model.model), control_model.type) + else: + return control_model + + # Remove model from cache to clear space before building another model + if len(Script.model_cache) > 0 and len(Script.model_cache) >= shared.opts.data.get("control_net_model_cache_size", 2): + Script.model_cache.popitem(last=False) + gc.collect() + devices.torch_gc() + + control_model = Script.build_control_model(p, unet, model) + + if shared.opts.data.get("control_net_model_cache_size", 2) > 0: + Script.model_cache[model] = control_model + + return control_model + + @staticmethod + def build_control_model(p, unet, model) -> ControlModel: + if model is None or model == 'None': + raise RuntimeError(f"You have not selected any ControlNet Model.") + + model_path = global_state.cn_models.get(model, None) + if model_path is None: + model = find_closest_lora_model_name(model) + model_path = global_state.cn_models.get(model, None) + + if model_path is None: + raise RuntimeError(f"model not found: {model}") + + # trim '"' at start/end + if model_path.startswith("\"") and model_path.endswith("\""): + model_path = model_path[1:-1] + + if not os.path.exists(model_path): + raise ValueError(f"file not found: {model_path}") + + logger.info(f"Loading model: {model}") + state_dict = load_state_dict(model_path) + control_model = build_model_by_guess(state_dict, unet, model_path) + control_model.model.to('cpu', dtype=p.sd_model.dtype) + logger.info(f"ControlNet model {model} loaded.") + return control_model + + @staticmethod + def get_remote_call(p, attribute, default=None, idx=0, strict=False, force=False): + if not force and not shared.opts.data.get("control_net_allow_script_control", False): + return default + + def get_element(obj, strict=False): + if not isinstance(obj, list): + return obj if not strict or idx == 0 else None + elif idx < len(obj): + return obj[idx] + else: + return None + + attribute_value = get_element(getattr(p, attribute, None), strict) + return attribute_value if attribute_value is not None else default + + @staticmethod + def parse_remote_call(p, unit: external_code.ControlNetUnit, idx): + selector = Script.get_remote_call + + unit.enabled = selector(p, "control_net_enabled", unit.enabled, idx, strict=True) + unit.module = selector(p, "control_net_module", unit.module, idx) + unit.model = selector(p, "control_net_model", unit.model, idx) + unit.weight = selector(p, "control_net_weight", unit.weight, idx) + unit.image = selector(p, "control_net_image", unit.image, idx) + unit.resize_mode = selector(p, "control_net_resize_mode", unit.resize_mode, idx) + unit.low_vram = selector(p, "control_net_lowvram", unit.low_vram, idx) + unit.processor_res = selector(p, "control_net_pres", unit.processor_res, idx) + unit.threshold_a = selector(p, "control_net_pthr_a", unit.threshold_a, idx) + unit.threshold_b = selector(p, "control_net_pthr_b", unit.threshold_b, idx) + unit.guidance_start = selector(p, "control_net_guidance_start", unit.guidance_start, idx) + unit.guidance_end = selector(p, "control_net_guidance_end", unit.guidance_end, idx) + # Backward compatibility. See https://github.com/Mikubill/sd-webui-controlnet/issues/1740 + # for more details. + unit.guidance_end = selector(p, "control_net_guidance_strength", unit.guidance_end, idx) + unit.control_mode = selector(p, "control_net_control_mode", unit.control_mode, idx) + unit.pixel_perfect = selector(p, "control_net_pixel_perfect", unit.pixel_perfect, idx) + + return unit + + @staticmethod + def detectmap_proc(detected_map, module, resize_mode, h, w): + + if 'inpaint' in module: + detected_map = detected_map.astype(np.float32) + else: + detected_map = HWC3(detected_map) + + def safe_numpy(x): + # A very safe method to make sure that Apple/Mac works + y = x + + # below is very boring but do not change these. If you change these Apple or Mac may fail. + y = y.copy() + y = np.ascontiguousarray(y) + y = y.copy() + return y + + def get_pytorch_control(x): + # A very safe method to make sure that Apple/Mac works + y = x + + # below is very boring but do not change these. If you change these Apple or Mac may fail. + y = torch.from_numpy(y) + y = y.float() / 255.0 + y = rearrange(y, 'h w c -> 1 c h w') + y = y.clone() + y = y.to(devices.get_device_for("controlnet")) + y = y.clone() + return y + + def high_quality_resize(x, size): + # Written by lvmin + # Super high-quality control map up-scaling, considering binary, seg, and one-pixel edges + + inpaint_mask = None + if x.ndim == 3 and x.shape[2] == 4: + inpaint_mask = x[:, :, 3] + x = x[:, :, 0:3] + + if x.shape[0] != size[1] or x.shape[1] != size[0]: + new_size_is_smaller = (size[0] * size[1]) < (x.shape[0] * x.shape[1]) + new_size_is_bigger = (size[0] * size[1]) > (x.shape[0] * x.shape[1]) + unique_color_count = len(get_unique_axis0(x.reshape(-1, x.shape[2]))) + is_one_pixel_edge = False + is_binary = False + if unique_color_count == 2: + is_binary = np.min(x) < 16 and np.max(x) > 240 + if is_binary: + xc = x + xc = cv2.erode(xc, np.ones(shape=(3, 3), dtype=np.uint8), iterations=1) + xc = cv2.dilate(xc, np.ones(shape=(3, 3), dtype=np.uint8), iterations=1) + one_pixel_edge_count = np.where(xc < x)[0].shape[0] + all_edge_count = np.where(x > 127)[0].shape[0] + is_one_pixel_edge = one_pixel_edge_count * 2 > all_edge_count + + if 2 < unique_color_count < 200: + interpolation = cv2.INTER_NEAREST + elif new_size_is_smaller: + interpolation = cv2.INTER_AREA + else: + interpolation = cv2.INTER_CUBIC # Must be CUBIC because we now use nms. NEVER CHANGE THIS + + y = cv2.resize(x, size, interpolation=interpolation) + if inpaint_mask is not None: + inpaint_mask = cv2.resize(inpaint_mask, size, interpolation=interpolation) + + if is_binary: + y = np.mean(y.astype(np.float32), axis=2).clip(0, 255).astype(np.uint8) + if is_one_pixel_edge: + y = nake_nms(y) + _, y = cv2.threshold(y, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) + y = lvmin_thin(y, prunings=new_size_is_bigger) + else: + _, y = cv2.threshold(y, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) + y = np.stack([y] * 3, axis=2) + else: + y = x + + if inpaint_mask is not None: + inpaint_mask = (inpaint_mask > 127).astype(np.float32) * 255.0 + inpaint_mask = inpaint_mask[:, :, None].clip(0, 255).astype(np.uint8) + y = np.concatenate([y, inpaint_mask], axis=2) + + return y + + if resize_mode == external_code.ResizeMode.RESIZE: + detected_map = high_quality_resize(detected_map, (w, h)) + detected_map = safe_numpy(detected_map) + return get_pytorch_control(detected_map), detected_map + + old_h, old_w, _ = detected_map.shape + old_w = float(old_w) + old_h = float(old_h) + k0 = float(h) / old_h + k1 = float(w) / old_w + + safeint = lambda x: int(np.round(x)) + + if resize_mode == external_code.ResizeMode.OUTER_FIT: + k = min(k0, k1) + borders = np.concatenate([detected_map[0, :, :], detected_map[-1, :, :], detected_map[:, 0, :], detected_map[:, -1, :]], axis=0) + high_quality_border_color = np.median(borders, axis=0).astype(detected_map.dtype) + if len(high_quality_border_color) == 4: + # Inpaint hijack + high_quality_border_color[3] = 255 + high_quality_background = np.tile(high_quality_border_color[None, None], [h, w, 1]) + detected_map = high_quality_resize(detected_map, (safeint(old_w * k), safeint(old_h * k))) + new_h, new_w, _ = detected_map.shape + pad_h = max(0, (h - new_h) // 2) + pad_w = max(0, (w - new_w) // 2) + high_quality_background[pad_h:pad_h + new_h, pad_w:pad_w + new_w] = detected_map + detected_map = high_quality_background + detected_map = safe_numpy(detected_map) + return get_pytorch_control(detected_map), detected_map + else: + k = max(k0, k1) + detected_map = high_quality_resize(detected_map, (safeint(old_w * k), safeint(old_h * k))) + new_h, new_w, _ = detected_map.shape + pad_h = max(0, (new_h - h) // 2) + pad_w = max(0, (new_w - w) // 2) + detected_map = detected_map[pad_h:pad_h+h, pad_w:pad_w+w] + detected_map = safe_numpy(detected_map) + return get_pytorch_control(detected_map), detected_map + + @staticmethod + def get_enabled_units(p): + units = external_code.get_all_units_in_processing(p) + if len(units) == 0: + # fill a null group + remote_unit = Script.parse_remote_call(p, Script.get_default_ui_unit(), 0) + if remote_unit.enabled: + units.append(remote_unit) + + enabled_units = [] + for idx, unit in enumerate(units): + local_unit = Script.parse_remote_call(p, unit, idx) + if not local_unit.enabled: + continue + if hasattr(local_unit, "unfold_merged"): + enabled_units.extend(local_unit.unfold_merged()) + else: + enabled_units.append(copy(local_unit)) + + Infotext.write_infotext(enabled_units, p) + return enabled_units + + @staticmethod + def choose_input_image( + p: processing.StableDiffusionProcessing, + unit: external_code.ControlNetUnit, + idx: int + ) -> Tuple[np.ndarray, external_code.ResizeMode]: + """ Choose input image from following sources with descending priority: + - p.image_control: [Deprecated] Lagacy way to pass image to controlnet. + - p.control_net_input_image: [Deprecated] Lagacy way to pass image to controlnet. + - unit.image: ControlNet tab input image. + - p.init_images: A1111 img2img tab input image. + + Returns: + - The input image in ndarray form. + - The resize mode. + """ + def parse_unit_image(unit: external_code.ControlNetUnit) -> Union[List[Dict[str, np.ndarray]], Dict[str, np.ndarray]]: + unit_has_multiple_images = ( + isinstance(unit.image, list) and + len(unit.image) > 0 and + "image" in unit.image[0] + ) + if unit_has_multiple_images: + return [ + d + for img in unit.image + for d in (image_dict_from_any(img),) + if d is not None + ] + return image_dict_from_any(unit.image) + + def decode_image(img) -> np.ndarray: + """Need to check the image for API compatibility.""" + if isinstance(img, str): + return np.asarray(decode_base64_to_image(image['image'])) + else: + assert isinstance(img, np.ndarray) + return img + + # 4 input image sources. + p_image_control = getattr(p, "image_control", None) + p_input_image = Script.get_remote_call(p, "control_net_input_image", None, idx) + image = parse_unit_image(unit) + a1111_image = getattr(p, "init_images", [None])[0] + + resize_mode = external_code.resize_mode_from_value(unit.resize_mode) + + if batch_hijack.instance.is_batch and p_image_control is not None: + logger.warning("Warn: Using legacy field 'p.image_control'.") + input_image = HWC3(np.asarray(p_image_control)) + elif p_input_image is not None: + logger.warning("Warn: Using legacy field 'p.controlnet_input_image'") + if isinstance(p_input_image, dict) and "mask" in p_input_image and "image" in p_input_image: + color = HWC3(np.asarray(p_input_image['image'])) + alpha = np.asarray(p_input_image['mask'])[..., None] + input_image = np.concatenate([color, alpha], axis=2) + else: + input_image = HWC3(np.asarray(p_input_image)) + elif image: + if isinstance(image, list): + # Add mask logic if later there is a processor that accepts mask + # on multiple inputs. + input_image = [HWC3(decode_image(img['image'])) for img in image] + else: + input_image = HWC3(decode_image(image['image'])) + if 'mask' in image and image['mask'] is not None: + while len(image['mask'].shape) < 3: + image['mask'] = image['mask'][..., np.newaxis] + if 'inpaint' in unit.module: + logger.info("using inpaint as input") + color = HWC3(image['image']) + alpha = image['mask'][:, :, 0:1] + input_image = np.concatenate([color, alpha], axis=2) + elif ( + not shared.opts.data.get("controlnet_ignore_noninpaint_mask", False) and + # There is wield gradio issue that would produce mask that is + # not pure color when no scribble is made on canvas. + # See https://github.com/Mikubill/sd-webui-controlnet/issues/1638. + not ( + (image['mask'][:, :, 0] <= 5).all() or + (image['mask'][:, :, 0] >= 250).all() + ) + ): + logger.info("using mask as input") + input_image = HWC3(image['mask'][:, :, 0]) + unit.module = 'none' # Always use black bg and white line + elif a1111_image is not None: + input_image = HWC3(np.asarray(a1111_image)) + a1111_i2i_resize_mode = getattr(p, "resize_mode", None) + assert a1111_i2i_resize_mode is not None + resize_mode = external_code.resize_mode_from_value(a1111_i2i_resize_mode) + + a1111_mask_image : Optional[Image.Image] = getattr(p, "image_mask", None) + if 'inpaint' in unit.module: + if a1111_mask_image is not None: + a1111_mask = np.array(prepare_mask(a1111_mask_image, p)) + assert a1111_mask.ndim == 2 + assert a1111_mask.shape[0] == input_image.shape[0] + assert a1111_mask.shape[1] == input_image.shape[1] + input_image = np.concatenate([input_image[:, :, 0:3], a1111_mask[:, :, None]], axis=2) + else: + input_image = np.concatenate([ + input_image[:, :, 0:3], + np.zeros_like(input_image, dtype=np.uint8)[:, :, 0:1], + ], axis=2) + else: + # No input image detected. + if batch_hijack.instance.is_batch: + shared.state.interrupted = True + raise ValueError("controlnet is enabled but no input image is given") + + assert isinstance(input_image, (np.ndarray, list)) + return input_image, resize_mode + + @staticmethod + def try_crop_image_with_a1111_mask( + p: StableDiffusionProcessing, + unit: external_code.ControlNetUnit, + input_image: np.ndarray, + resize_mode: external_code.ResizeMode, + ) -> np.ndarray: + """ + Crop ControlNet input image based on A1111 inpaint mask given. + This logic is crutial in upscale scripts, as they use A1111 mask + inpaint_full_res + to crop tiles. + """ + # Note: The method determining whether the active script is an upscale script is purely + # based on `extra_generation_params` these scripts attach on `p`, and subject to change + # in the future. + # TODO: Change this to a more robust condition once A1111 offers a way to verify script name. + is_upscale_script = any("upscale" in k.lower() for k in getattr(p, "extra_generation_params", {}).keys()) + logger.debug(f"is_upscale_script={is_upscale_script}") + # Note: `inpaint_full_res` is "inpaint area" on UI. The flag is `True` when "Only masked" + # option is selected. + a1111_mask_image : Optional[Image.Image] = getattr(p, "image_mask", None) + is_only_masked_inpaint = ( + issubclass(type(p), StableDiffusionProcessingImg2Img) and + p.inpaint_full_res and + a1111_mask_image is not None + ) + if ( + 'reference' not in unit.module + and is_only_masked_inpaint + and (is_upscale_script or unit.inpaint_crop_input_image) + ): + logger.debug("Crop input image based on A1111 mask.") + input_image = [input_image[:, :, i] for i in range(input_image.shape[2])] + input_image = [Image.fromarray(x) for x in input_image] + + mask = prepare_mask(a1111_mask_image, p) + + crop_region = masking.get_crop_region(np.array(mask), p.inpaint_full_res_padding) + crop_region = masking.expand_crop_region(crop_region, p.width, p.height, mask.width, mask.height) + + input_image = [ + images.resize_image(resize_mode.int_value(), i, mask.width, mask.height) + for i in input_image + ] + + input_image = [x.crop(crop_region) for x in input_image] + input_image = [ + images.resize_image(external_code.ResizeMode.OUTER_FIT.int_value(), x, p.width, p.height) + for x in input_image + ] + + input_image = [np.asarray(x)[:, :, 0] for x in input_image] + input_image = np.stack(input_image, axis=2) + return input_image + + @staticmethod + def bound_check_params(unit: external_code.ControlNetUnit) -> None: + """ + Checks and corrects negative parameters in ControlNetUnit 'unit'. + Parameters 'processor_res', 'threshold_a', 'threshold_b' are reset to + their default values if negative. + + Args: + unit (external_code.ControlNetUnit): The ControlNetUnit instance to check. + """ + cfg = preprocessor_sliders_config.get( + global_state.get_module_basename(unit.module), []) + defaults = { + param: cfg_default['value'] + for param, cfg_default in zip( + ("processor_res", 'threshold_a', 'threshold_b'), cfg) + if cfg_default is not None + } + for param, default_value in defaults.items(): + value = getattr(unit, param) + if value < 0: + setattr(unit, param, default_value) + logger.warning(f'[{unit.module}.{param}] Invalid value({value}), using default value {default_value}.') + + @staticmethod + def check_sd_version_compatible(unit: external_code.ControlNetUnit) -> None: + """ + Checks whether the given ControlNet unit has model compatible with the currently + active sd model. An exception is thrown if ControlNet unit is detected to be + incompatible. + """ + sd_version = global_state.get_sd_version() + assert sd_version != StableDiffusionVersion.UNKNOWN + + if "revision" in unit.module.lower() and sd_version != StableDiffusionVersion.SDXL: + raise Exception(f"Preprocessor 'revision' only supports SDXL. Current SD base model is {sd_version}.") + + # No need to check if the ControlModelType does not require model to be present. + if unit.model is None or unit.model.lower() == "none": + return + + cnet_sd_version = StableDiffusionVersion.detect_from_model_name(unit.model) + + if cnet_sd_version == StableDiffusionVersion.UNKNOWN: + logger.warn(f"Unable to determine version for ControlNet model '{unit.model}'.") + return + + if not sd_version.is_compatible_with(cnet_sd_version): + raise Exception(f"ControlNet model {unit.model}({cnet_sd_version}) is not compatible with sd model({sd_version})") + + @staticmethod + def get_target_dimensions(p: StableDiffusionProcessing) -> Tuple[int, int, int, int]: + """Returns (h, w, hr_h, hr_w).""" + h = align_dim_latent(p.height) + w = align_dim_latent(p.width) + + high_res_fix = ( + isinstance(p, StableDiffusionProcessingTxt2Img) + and getattr(p, 'enable_hr', False) + ) + if high_res_fix: + if p.hr_resize_x == 0 and p.hr_resize_y == 0: + hr_y = int(p.height * p.hr_scale) + hr_x = int(p.width * p.hr_scale) + else: + hr_y, hr_x = p.hr_resize_y, p.hr_resize_x + hr_y = align_dim_latent(hr_y) + hr_x = align_dim_latent(hr_x) + else: + hr_y = h + hr_x = w + + return h, w, hr_y, hr_x + + def controlnet_main_entry(self, p): + sd_ldm = p.sd_model + unet = sd_ldm.model.diffusion_model + self.noise_modifier = None + + setattr(p, 'controlnet_control_loras', []) + + if self.latest_network is not None: + # always restore (~0.05s) + self.latest_network.restore() + + # always clear (~0.05s) + clear_all_secondary_control_models(unet) + + if not batch_hijack.instance.is_batch: + self.enabled_units = Script.get_enabled_units(p) + + batch_option_uint_separate = self.ui_batch_option_state[0] == external_code.BatchOption.SEPARATE.value + batch_option_style_align = self.ui_batch_option_state[1] + + if len(self.enabled_units) == 0 and not batch_option_style_align: + self.latest_network = None + return + + logger.info(f"unit_separate = {batch_option_uint_separate}, style_align = {batch_option_style_align}") + + detected_maps = [] + forward_params = [] + post_processors = [] + + # cache stuff + if self.latest_model_hash != p.sd_model.sd_model_hash: + Script.clear_control_model_cache() + + for idx, unit in enumerate(self.enabled_units): + unit.module = global_state.get_module_basename(unit.module) + + # unload unused preproc + module_list = [unit.module for unit in self.enabled_units] + for key in self.unloadable: + if key not in module_list: + self.unloadable.get(key, lambda:None)() + + self.latest_model_hash = p.sd_model.sd_model_hash + high_res_fix = isinstance(p, StableDiffusionProcessingTxt2Img) and getattr(p, 'enable_hr', False) + + for idx, unit in enumerate(self.enabled_units): + Script.bound_check_params(unit) + Script.check_sd_version_compatible(unit) + if ( + "ip-adapter" in unit.module and + not global_state.ip_adapter_pairing_model[unit.module](unit.model) + ): + logger.error(f"Invalid pair of IP-Adapter preprocessor({unit.module}) and model({unit.model}).\n" + "Please follow following pairing logic:\n" + + global_state.ip_adapter_pairing_logic_text) + continue + + if ( + 'inpaint_only' == unit.module and + issubclass(type(p), StableDiffusionProcessingImg2Img) and + p.image_mask is not None + ): + logger.warning('A1111 inpaint and ControlNet inpaint duplicated. Falls back to inpaint_global_harmonious.') + unit.module = 'inpaint' + + if unit.module in model_free_preprocessors: + model_net = None + if 'reference' in unit.module: + control_model_type = ControlModelType.AttentionInjection + elif 'revision' in unit.module: + control_model_type = ControlModelType.ReVision + else: + raise Exception("Unable to determine control_model_type.") + else: + model_net, control_model_type = Script.load_control_model(p, unet, unit.model) + model_net.reset() + + if control_model_type == ControlModelType.ControlLoRA: + control_lora = model_net.control_model + bind_control_lora(unet, control_lora) + p.controlnet_control_loras.append(control_lora) + # Change control_model_type to ControlNet as all processes + # in hook.py still want the ControlNetLoRA to be treated + # the same way as ControlNet. + control_model_type = ControlModelType.ControlNet + + h, w, hr_y, hr_x = Script.get_target_dimensions(p) + + input_image, resize_mode = Script.choose_input_image(p, unit, idx) + if isinstance(input_image, list): + assert unit.accepts_multiple_inputs() + # preprocessor function is cached, so all arguments must be hashable. + input_image = tuple(input_image) + else: + input_image = Script.try_crop_image_with_a1111_mask(p, unit, input_image, resize_mode) + input_image = np.ascontiguousarray(input_image.copy()).copy() # safe numpy + if unit.module == 'inpaint_only+lama' and resize_mode == external_code.ResizeMode.OUTER_FIT: + # inpaint_only+lama is special and required outpaint fix + _, input_image = Script.detectmap_proc(input_image, unit.module, resize_mode, hr_y, hr_x) + if unit.pixel_perfect: + unit.processor_res = external_code.pixel_perfect_resolution( + input_image, + target_H=h, + target_W=w, + resize_mode=resize_mode, + ) + # Preprocessor result may depend on numpy random operations, use the + # random seed in `StableDiffusionProcessing` to make the + # preprocessor result reproducable. + # Currently following preprocessors use numpy random: + # - shuffle + seed = set_numpy_seed(p) + logger.debug(f"Use numpy seed {seed}.") + logger.info(f"Using preprocessor: {unit.module}") + logger.info(f'preprocessor resolution = {unit.processor_res}') + detected_map, is_image = self.preprocessor[unit.module]( + input_image, + res=unit.processor_res, + thr_a=unit.threshold_a, + thr_b=unit.threshold_b, + low_vram=( + ("clip" in unit.module or unit.module == "ip-adapter_face_id_plus") and + shared.opts.data.get("controlnet_clip_detector_on_cpu", False) + ), + ) + + def store_detected_map(detected_map, module: str) -> None: + if unit.save_detected_map: + detected_maps.append((detected_map, module)) + + if high_res_fix: + if is_image: + hr_control, hr_detected_map = Script.detectmap_proc(detected_map, unit.module, resize_mode, hr_y, hr_x) + store_detected_map(hr_detected_map, unit.module) + else: + hr_control = detected_map + else: + hr_control = None + + if is_image: + control, detected_map = Script.detectmap_proc(detected_map, unit.module, resize_mode, h, w) + store_detected_map(detected_map, unit.module) + else: + control = detected_map + for img in (input_image if isinstance(input_image, (list, tuple)) else [input_image]): + store_detected_map(img, unit.module) + + if control_model_type == ControlModelType.T2I_StyleAdapter: + control = control['last_hidden_state'] + + if control_model_type == ControlModelType.ReVision: + control = control['image_embeds'] + + preprocessor_dict = dict( + name=unit.module, + preprocessor_resolution=unit.processor_res, + threshold_a=unit.threshold_a, + threshold_b=unit.threshold_b + ) + + global_average_pooling = ( + control_model_type == ControlModelType.ControlNet and + model_net.control_model.global_average_pooling + ) + control_mode = external_code.control_mode_from_value(unit.control_mode) + forward_param = ControlParams( + control_model=model_net, + preprocessor=preprocessor_dict, + hint_cond=control, + weight=unit.weight, + guidance_stopped=False, + start_guidance_percent=unit.guidance_start, + stop_guidance_percent=unit.guidance_end, + advanced_weighting=unit.advanced_weighting, + control_model_type=control_model_type, + global_average_pooling=global_average_pooling, + hr_hint_cond=hr_control, + hr_option=HiResFixOption.from_value(unit.hr_option) if high_res_fix else HiResFixOption.BOTH, + soft_injection=control_mode != external_code.ControlMode.BALANCED, + cfg_injection=control_mode == external_code.ControlMode.CONTROL, + ) + forward_params.append(forward_param) + + if 'inpaint_only' in unit.module: + final_inpaint_feed = hr_control if hr_control is not None else control + final_inpaint_feed = final_inpaint_feed.detach().cpu().numpy() + final_inpaint_feed = np.ascontiguousarray(final_inpaint_feed).copy() + final_inpaint_mask = final_inpaint_feed[0, 3, :, :].astype(np.float32) + final_inpaint_raw = final_inpaint_feed[0, :3].astype(np.float32) + sigma = shared.opts.data.get("control_net_inpaint_blur_sigma", 7) + final_inpaint_mask = cv2.dilate(final_inpaint_mask, np.ones((sigma, sigma), dtype=np.uint8)) + final_inpaint_mask = cv2.blur(final_inpaint_mask, (sigma, sigma))[None] + _, Hmask, Wmask = final_inpaint_mask.shape + final_inpaint_raw = torch.from_numpy(np.ascontiguousarray(final_inpaint_raw).copy()) + final_inpaint_mask = torch.from_numpy(np.ascontiguousarray(final_inpaint_mask).copy()) + + def inpaint_only_post_processing(x): + _, H, W = x.shape + if Hmask != H or Wmask != W: + logger.error('Error: ControlNet find post-processing resolution mismatch. This could be related to other extensions hacked processing.') + return x + r = final_inpaint_raw.to(x.dtype).to(x.device) + m = final_inpaint_mask.to(x.dtype).to(x.device) + y = m * x.clip(0, 1) + (1 - m) * r + y = y.clip(0, 1) + return y + + post_processors.append(inpaint_only_post_processing) + + if 'recolor' in unit.module: + final_feed = hr_control if hr_control is not None else control + final_feed = final_feed.detach().cpu().numpy() + final_feed = np.ascontiguousarray(final_feed).copy() + final_feed = final_feed[0, 0, :, :].astype(np.float32) + final_feed = (final_feed * 255).clip(0, 255).astype(np.uint8) + Hfeed, Wfeed = final_feed.shape + + if 'luminance' in unit.module: + + def recolor_luminance_post_processing(x): + C, H, W = x.shape + if Hfeed != H or Wfeed != W or C != 3: + logger.error('Error: ControlNet find post-processing resolution mismatch. This could be related to other extensions hacked processing.') + return x + h = x.detach().cpu().numpy().transpose((1, 2, 0)) + h = (h * 255).clip(0, 255).astype(np.uint8) + h = cv2.cvtColor(h, cv2.COLOR_RGB2LAB) + h[:, :, 0] = final_feed + h = cv2.cvtColor(h, cv2.COLOR_LAB2RGB) + h = (h.astype(np.float32) / 255.0).transpose((2, 0, 1)) + y = torch.from_numpy(h).clip(0, 1).to(x) + return y + + post_processors.append(recolor_luminance_post_processing) + + if 'intensity' in unit.module: + + def recolor_intensity_post_processing(x): + C, H, W = x.shape + if Hfeed != H or Wfeed != W or C != 3: + logger.error('Error: ControlNet find post-processing resolution mismatch. This could be related to other extensions hacked processing.') + return x + h = x.detach().cpu().numpy().transpose((1, 2, 0)) + h = (h * 255).clip(0, 255).astype(np.uint8) + h = cv2.cvtColor(h, cv2.COLOR_RGB2HSV) + h[:, :, 2] = final_feed + h = cv2.cvtColor(h, cv2.COLOR_HSV2RGB) + h = (h.astype(np.float32) / 255.0).transpose((2, 0, 1)) + y = torch.from_numpy(h).clip(0, 1).to(x) + return y + + post_processors.append(recolor_intensity_post_processing) + + if '+lama' in unit.module: + forward_param.used_hint_cond_latent = hook.UnetHook.call_vae_using_process(p, control) + self.noise_modifier = forward_param.used_hint_cond_latent + + del model_net + + is_low_vram = any(unit.low_vram for unit in self.enabled_units) + + self.latest_network = UnetHook(lowvram=is_low_vram) + self.latest_network.hook(model=unet, sd_ldm=sd_ldm, control_params=forward_params, process=p, + batch_option_uint_separate=batch_option_uint_separate, + batch_option_style_align=batch_option_style_align) + + for param in forward_params: + if param.control_model_type == ControlModelType.IPAdapter: + param.control_model.hook( + model=unet, + clip_vision_output=param.hint_cond, + weight=param.weight, + dtype=torch.float32, + start=param.start_guidance_percent, + end=param.stop_guidance_percent + ) + if param.control_model_type == ControlModelType.Controlllite: + param.control_model.hook( + model=unet, + cond=param.hint_cond, + weight=param.weight, + start=param.start_guidance_percent, + end=param.stop_guidance_percent + ) + + self.detected_map = detected_maps + self.post_processors = post_processors + + def controlnet_hack(self, p): + t = time.time() + if getattr(shared.cmd_opts, 'controlnet_tracemalloc', False): + tracemalloc.start() + setattr(self, "malloc_begin", tracemalloc.take_snapshot()) + + self.controlnet_main_entry(p) + if getattr(shared.cmd_opts, 'controlnet_tracemalloc', False): + logger.info("After hook malloc:") + for stat in tracemalloc.take_snapshot().compare_to(self.malloc_begin, "lineno")[:10]: + logger.info(stat) + + if len(self.enabled_units) > 0: + logger.info(f'ControlNet Hooked - Time = {time.time() - t}') + + @staticmethod + def process_has_sdxl_refiner(p): + return getattr(p, 'refiner_checkpoint', None) is not None + + def process(self, p, *args, **kwargs): + if not Script.process_has_sdxl_refiner(p): + self.controlnet_hack(p) + return + + def before_process_batch(self, p, *args, **kwargs): + if self.noise_modifier is not None: + p.rng = HackedImageRNG(rng=p.rng, + noise_modifier=self.noise_modifier, + sd_model=p.sd_model) + self.noise_modifier = None + if Script.process_has_sdxl_refiner(p): + self.controlnet_hack(p) + return + + def postprocess_batch(self, p, *args, **kwargs): + images = kwargs.get('images', []) + for post_processor in self.post_processors: + for i in range(len(images)): + images[i] = post_processor(images[i]) + return + + def postprocess(self, p, processed, *args): + sd_ldm = p.sd_model + unet = sd_ldm.model.diffusion_model + + clear_all_secondary_control_models(unet) + + self.noise_modifier = None + + for control_lora in getattr(p, 'controlnet_control_loras', []): + unbind_control_lora(control_lora) + p.controlnet_control_loras = [] + + self.post_processors = [] + setattr(p, 'controlnet_vae_cache', None) + + processor_params_flag = (', '.join(getattr(processed, 'extra_generation_params', []))).lower() + self.post_processors = [] + + if not batch_hijack.instance.is_batch: + self.enabled_units.clear() + + if shared.opts.data.get("control_net_detectmap_autosaving", False) and self.latest_network is not None: + for detect_map, module in self.detected_map: + detectmap_dir = os.path.join(shared.opts.data.get("control_net_detectedmap_dir", ""), module) + if not os.path.isabs(detectmap_dir): + detectmap_dir = os.path.join(p.outpath_samples, detectmap_dir) + if module != "none": + os.makedirs(detectmap_dir, exist_ok=True) + img = Image.fromarray(np.ascontiguousarray(detect_map.clip(0, 255).astype(np.uint8)).copy()) + save_image(img, detectmap_dir, module) + + if self.latest_network is None: + return + + if not batch_hijack.instance.is_batch: + if not shared.opts.data.get("control_net_no_detectmap", False): + if 'sd upscale' not in processor_params_flag: + if self.detected_map is not None: + for detect_map, module in self.detected_map: + if detect_map is None: + continue + detect_map = np.ascontiguousarray(detect_map.copy()).copy() + detect_map = external_code.visualize_inpaint_mask(detect_map) + processed.images.extend([ + Image.fromarray( + detect_map.clip(0, 255).astype(np.uint8) + ) + ]) + + self.input_image = None + self.latest_network.restore() + self.latest_network = None + self.detected_map.clear() + + gc.collect() + devices.torch_gc() + if getattr(shared.cmd_opts, 'controlnet_tracemalloc', False): + logger.info("After generation:") + for stat in tracemalloc.take_snapshot().compare_to(self.malloc_begin, "lineno")[:10]: + logger.info(stat) + tracemalloc.stop() + + def batch_tab_process(self, p, batches, *args, **kwargs): + self.enabled_units = Script.get_enabled_units(p) + for unit_i, unit in enumerate(self.enabled_units): + unit.batch_images = iter([batch[unit_i] for batch in batches]) + + def batch_tab_process_each(self, p, *args, **kwargs): + for unit_i, unit in enumerate(self.enabled_units): + if getattr(unit, 'loopback', False) and batch_hijack.instance.batch_index > 0: continue + + unit.image = next(unit.batch_images) + + def batch_tab_postprocess_each(self, p, processed, *args, **kwargs): + for unit_i, unit in enumerate(self.enabled_units): + if getattr(unit, 'loopback', False): + output_images = getattr(processed, 'images', [])[processed.index_of_first_image:] + if output_images: + unit.image = np.array(output_images[0]) + else: + logger.warning(f'Warning: No loopback image found for controlnet unit {unit_i}. Using control map from last batch iteration instead') + + def batch_tab_postprocess(self, p, *args, **kwargs): + self.enabled_units.clear() + self.input_image = None + if self.latest_network is None: return + + self.latest_network.restore() + self.latest_network = None + self.detected_map.clear() + + +def on_ui_settings(): + section = ('control_net', "ControlNet") + shared.opts.add_option("control_net_detectedmap_dir", shared.OptionInfo( + global_state.default_detectedmap_dir, "Directory for detected maps auto saving", section=section)) + shared.opts.add_option("control_net_models_path", shared.OptionInfo( + "", "Extra path to scan for ControlNet models (e.g. training output directory)", section=section)) + shared.opts.add_option("control_net_modules_path", shared.OptionInfo( + "", "Path to directory containing annotator model directories (requires restart, overrides corresponding command line flag)", section=section)) + shared.opts.add_option("control_net_unit_count", shared.OptionInfo( + 3, "Multi-ControlNet: ControlNet unit number (requires restart)", gr.Slider, {"minimum": 1, "maximum": 10, "step": 1}, section=section)) + shared.opts.add_option("control_net_model_cache_size", shared.OptionInfo( + 1, "Model cache size (requires restart)", gr.Slider, {"minimum": 1, "maximum": 10, "step": 1}, section=section)) + shared.opts.add_option("control_net_inpaint_blur_sigma", shared.OptionInfo( + 7, "ControlNet inpainting Gaussian blur sigma", gr.Slider, {"minimum": 0, "maximum": 64, "step": 1}, section=section)) + shared.opts.add_option("control_net_no_detectmap", shared.OptionInfo( + False, "Do not append detectmap to output", gr.Checkbox, {"interactive": True}, section=section)) + shared.opts.add_option("control_net_detectmap_autosaving", shared.OptionInfo( + False, "Allow detectmap auto saving", gr.Checkbox, {"interactive": True}, section=section)) + shared.opts.add_option("control_net_allow_script_control", shared.OptionInfo( + False, "Allow other script to control this extension", gr.Checkbox, {"interactive": True}, section=section)) + shared.opts.add_option("control_net_sync_field_args", shared.OptionInfo( + True, "Paste ControlNet parameters in infotext", gr.Checkbox, {"interactive": True}, section=section)) + shared.opts.add_option("controlnet_show_batch_images_in_ui", shared.OptionInfo( + False, "Show batch images in gradio gallery output", gr.Checkbox, {"interactive": True}, section=section)) + shared.opts.add_option("controlnet_increment_seed_during_batch", shared.OptionInfo( + False, "Increment seed after each controlnet batch iteration", gr.Checkbox, {"interactive": True}, section=section)) + shared.opts.add_option("controlnet_disable_openpose_edit", shared.OptionInfo( + False, "Disable openpose edit", gr.Checkbox, {"interactive": True}, section=section)) + shared.opts.add_option("controlnet_disable_photopea_edit", shared.OptionInfo( + False, "Disable photopea edit", gr.Checkbox, {"interactive": True}, section=section)) + shared.opts.add_option("controlnet_photopea_warning", shared.OptionInfo( + True, "Photopea popup warning", gr.Checkbox, {"interactive": True}, section=section)) + shared.opts.add_option("controlnet_ignore_noninpaint_mask", shared.OptionInfo( + False, "Ignore mask on ControlNet input image if control type is not inpaint", + gr.Checkbox, {"interactive": True}, section=section)) + shared.opts.add_option("controlnet_clip_detector_on_cpu", shared.OptionInfo( + False, "Load CLIP preprocessor model on CPU", + gr.Checkbox, {"interactive": True}, section=section)) + + +batch_hijack.instance.do_hijack() +script_callbacks.on_ui_settings(on_ui_settings) +script_callbacks.on_infotext_pasted(Infotext.on_infotext_pasted) +script_callbacks.on_after_component(ControlNetUiGroup.on_after_component) +script_callbacks.on_before_reload(ControlNetUiGroup.reset) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/scripts/controlnet_diffusers.py b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_diffusers.py new file mode 100644 index 00000000..3e118288 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_diffusers.py @@ -0,0 +1,95 @@ +# https://gist.github.com/takuma104/4adfb3d968d80bea1d18a30c06439242 +# 2nd editing by lllyasviel + +import torch + + +# =================# +# UNet Conversion # +# =================# + +unet_conversion_map = [ + # (stable-diffusion, HF Diffusers) + ("time_embed.0.weight", "time_embedding.linear_1.weight"), + ("time_embed.0.bias", "time_embedding.linear_1.bias"), + ("time_embed.2.weight", "time_embedding.linear_2.weight"), + ("time_embed.2.bias", "time_embedding.linear_2.bias"), + ("label_emb.0.0.weight", "add_embedding.linear_1.weight"), + ("label_emb.0.0.bias", "add_embedding.linear_1.bias"), + ("label_emb.0.2.weight", "add_embedding.linear_2.weight"), + ("label_emb.0.2.bias", "add_embedding.linear_2.bias"), + ("input_blocks.0.0.weight", "conv_in.weight"), + ("input_blocks.0.0.bias", "conv_in.bias"), + ("middle_block_out.0.weight", "controlnet_mid_block.weight"), + ("middle_block_out.0.bias", "controlnet_mid_block.bias"), +] + +unet_conversion_map_resnet = [ + # (stable-diffusion, HF Diffusers) + ("in_layers.0", "norm1"), + ("in_layers.2", "conv1"), + ("out_layers.0", "norm2"), + ("out_layers.3", "conv2"), + ("emb_layers.1", "time_emb_proj"), + ("skip_connection", "conv_shortcut"), +] + +unet_conversion_map_layer = [] +# hardcoded number of downblocks and resnets/attentions... +# would need smarter logic for other networks. +for i in range(4): + # loop over downblocks/upblocks + + for j in range(10): + # loop over resnets/attentions for downblocks + hf_down_res_prefix = f"down_blocks.{i}.resnets.{j}." + sd_down_res_prefix = f"input_blocks.{3*i + j + 1}.0." + unet_conversion_map_layer.append((sd_down_res_prefix, hf_down_res_prefix)) + + hf_down_atn_prefix = f"down_blocks.{i}.attentions.{j}." + sd_down_atn_prefix = f"input_blocks.{3 * i + j + 1}.1." + unet_conversion_map_layer.append((sd_down_atn_prefix, hf_down_atn_prefix)) + + hf_downsample_prefix = f"down_blocks.{i}.downsamplers.0.conv." + sd_downsample_prefix = f"input_blocks.{3 * (i + 1)}.0.op." + unet_conversion_map_layer.append((sd_downsample_prefix, hf_downsample_prefix)) + + +hf_mid_atn_prefix = "mid_block.attentions.0." +sd_mid_atn_prefix = "middle_block.1." +unet_conversion_map_layer.append((sd_mid_atn_prefix, hf_mid_atn_prefix)) + +for j in range(2): + hf_mid_res_prefix = f"mid_block.resnets.{j}." + sd_mid_res_prefix = f"middle_block.{2*j}." + unet_conversion_map_layer.append((sd_mid_res_prefix, hf_mid_res_prefix)) + +# controlnet specific + +controlnet_cond_embedding_names = ['conv_in'] + [f'blocks.{i}' for i in range(6)] + ['conv_out'] +for i, hf_prefix in enumerate(controlnet_cond_embedding_names): + hf_prefix = f"controlnet_cond_embedding.{hf_prefix}." + sd_prefix = f"input_hint_block.{i*2}." + unet_conversion_map_layer.append((sd_prefix, hf_prefix)) + +for i in range(12): + hf_prefix = f"controlnet_down_blocks.{i}." + sd_prefix = f"zero_convs.{i}.0." + unet_conversion_map_layer.append((sd_prefix, hf_prefix)) + + +def convert_from_diffuser_state_dict(unet_state_dict): + mapping = {k: k for k in unet_state_dict.keys()} + for sd_name, hf_name in unet_conversion_map: + mapping[hf_name] = sd_name + for k, v in mapping.items(): + if "resnets" in k: + for sd_part, hf_part in unet_conversion_map_resnet: + v = v.replace(hf_part, sd_part) + mapping[k] = v + for k, v in mapping.items(): + for sd_part, hf_part in unet_conversion_map_layer: + v = v.replace(hf_part, sd_part) + mapping[k] = v + new_state_dict = {v: unet_state_dict[k] for k, v in mapping.items() if k in unet_state_dict} + return new_state_dict diff --git a/extensions-builtin/sd_forge_controlnet/scripts/controlnet_lllite.py b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_lllite.py new file mode 100644 index 00000000..d13470cf --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_lllite.py @@ -0,0 +1,220 @@ +# https://github.com/kohya-ss/ControlNet-LLLite-ComfyUI/blob/main/node_control_net_lllite.py + +import re +import torch + +from modules import devices + + +class LLLiteModule(torch.nn.Module): + def __init__( + self, + name: str, + is_conv2d: bool, + in_dim: int, + depth: int, + cond_emb_dim: int, + mlp_dim: int, + ): + super().__init__() + self.name = name + self.is_conv2d = is_conv2d + self.is_first = False + + modules = [] + modules.append(torch.nn.Conv2d(3, cond_emb_dim // 2, kernel_size=4, stride=4, padding=0)) # to latent (from VAE) size*2 + if depth == 1: + modules.append(torch.nn.ReLU(inplace=True)) + modules.append(torch.nn.Conv2d(cond_emb_dim // 2, cond_emb_dim, kernel_size=2, stride=2, padding=0)) + elif depth == 2: + modules.append(torch.nn.ReLU(inplace=True)) + modules.append(torch.nn.Conv2d(cond_emb_dim // 2, cond_emb_dim, kernel_size=4, stride=4, padding=0)) + elif depth == 3: + # kernel size 8は大きすぎるので、4にする / kernel size 8 is too large, so set it to 4 + modules.append(torch.nn.ReLU(inplace=True)) + modules.append(torch.nn.Conv2d(cond_emb_dim // 2, cond_emb_dim // 2, kernel_size=4, stride=4, padding=0)) + modules.append(torch.nn.ReLU(inplace=True)) + modules.append(torch.nn.Conv2d(cond_emb_dim // 2, cond_emb_dim, kernel_size=2, stride=2, padding=0)) + + self.conditioning1 = torch.nn.Sequential(*modules) + + if self.is_conv2d: + self.down = torch.nn.Sequential( + torch.nn.Conv2d(in_dim, mlp_dim, kernel_size=1, stride=1, padding=0), + torch.nn.ReLU(inplace=True), + ) + self.mid = torch.nn.Sequential( + torch.nn.Conv2d(mlp_dim + cond_emb_dim, mlp_dim, kernel_size=1, stride=1, padding=0), + torch.nn.ReLU(inplace=True), + ) + self.up = torch.nn.Sequential( + torch.nn.Conv2d(mlp_dim, in_dim, kernel_size=1, stride=1, padding=0), + ) + else: + self.down = torch.nn.Sequential( + torch.nn.Linear(in_dim, mlp_dim), + torch.nn.ReLU(inplace=True), + ) + self.mid = torch.nn.Sequential( + torch.nn.Linear(mlp_dim + cond_emb_dim, mlp_dim), + torch.nn.ReLU(inplace=True), + ) + self.up = torch.nn.Sequential( + torch.nn.Linear(mlp_dim, in_dim), + ) + + self.depth = depth + self.cond_image = None + self.cond_emb = None + + def set_cond_image(self, cond_image): + self.cond_image = cond_image + self.cond_emb = None + + def forward(self, x, blk_shape): + if self.cond_emb is None: + # print(f"cond_emb is None, {self.name}") + cx = self.conditioning1(self.cond_image.to(x.device, dtype=x.dtype)) + + if blk_shape is not None: + b, c, h, w = blk_shape + cx = torch.nn.functional.interpolate(cx, (h, w), mode="nearest-exact") + + if not self.is_conv2d: + # reshape / b,c,h,w -> b,h*w,c + n, c, h, w = cx.shape + cx = cx.view(n, c, h * w).permute(0, 2, 1) + self.cond_emb = cx + + cx = self.cond_emb + + # uncond/condでxはバッチサイズが2倍 + if x.shape[0] != cx.shape[0]: + if self.is_conv2d: + cx = cx.repeat(x.shape[0] // cx.shape[0], 1, 1, 1) + else: + # print("x.shape[0] != cx.shape[0]", x.shape[0], cx.shape[0]) + cx = cx.repeat(x.shape[0] // cx.shape[0], 1, 1) + + cx = torch.cat([cx, self.down(x)], dim=1 if self.is_conv2d else 2) + cx = self.mid(cx) + cx = self.up(cx) + return cx + + +all_hack = {} + + +def clear_all_lllite(): + global all_hack + for k, v in all_hack.items(): + k.forward = v + k.lllite_list = [] + all_hack = {} + return + + +class PlugableControlLLLite(torch.nn.Module): + def __init__(self, state_dict): + super().__init__() + self.cache = {} + + module_weights = {} + for key, value in state_dict.items(): + fragments = key.split(".") + module_name = fragments[0] + weight_name = ".".join(fragments[1:]) + + if module_name not in module_weights: + module_weights[module_name] = {} + module_weights[module_name][weight_name] = value + + modules = {} + for module_name, weights in module_weights.items(): + if "conditioning1.4.weight" in weights: + depth = 3 + elif weights["conditioning1.2.weight"].shape[-1] == 4: + depth = 2 + else: + depth = 1 + + module = LLLiteModule( + name=module_name, + is_conv2d=weights["down.0.weight"].ndim == 4, + in_dim=weights["down.0.weight"].shape[1], + depth=depth, + cond_emb_dim=weights["conditioning1.0.weight"].shape[0] * 2, + mlp_dim=weights["down.0.weight"].shape[0], + ) + info = module.load_state_dict(weights) + modules[module_name] = module + setattr(self, module_name, module) + if len(modules) == 1: + module.is_first = True + + self.modules = modules + return + + def reset(self): + self.cache = {} + return + + @torch.no_grad() + def hook(self, model, cond, weight, start, end): + global all_hack + + cond_image = cond * 2.0 - 1.0 + + for module in self.modules.values(): + module.set_cond_image(cond_image) + + for k, v in self.modules.items(): + k = k.replace('middle_block', 'middle_blocks_0') + match = re.match("lllite_unet_(.*)_blocks_(.*)_1_transformer_blocks_(.*)_(.*)_to_(.*)", k, re.M | re.I) + assert match, 'Failed to load ControlLLLite!' + root = match.group(1) + block = match.group(2) + block_number = match.group(3) + attn_name = match.group(4) + proj_name = match.group(5) + if root == 'input': + b = model.input_blocks[int(block)][1].transformer_blocks[int(block_number)] + elif root == 'output': + b = model.output_blocks[int(block)][1].transformer_blocks[int(block_number)] + else: + b = model.middle_block[1].transformer_blocks[int(block_number)] + b = getattr(b, attn_name, None) + assert b is not None, 'Failed to load ControlLLLite!' + b = getattr(b, 'to_' + proj_name, None) + assert b is not None, 'Failed to load ControlLLLite!' + + if not hasattr(b, 'lllite_list'): + b.lllite_list = [] + + if len(b.lllite_list) == 0: + all_hack[b] = b.forward + b.forward = self.get_hacked_forward(original_forward=b.forward, model=model, blk=b) + + b.lllite_list.append((weight, start, end, v)) + return + + def get_hacked_forward(self, original_forward, model, blk): + @torch.no_grad() + def forward(x, **kwargs): + current_sampling_percent = getattr(model, 'current_sampling_percent', 0.5) + current_h_shape = getattr(model, 'current_h_shape', None) + is_in_high_res_fix = getattr(model, 'is_in_high_res_fix', False) + + if not is_in_high_res_fix: + hack = 0 + for weight, start, end, module in blk.lllite_list: + module.to(x.device) + if current_sampling_percent < start or current_sampling_percent > end: + hack = hack + 0 + else: + hack = hack + module(x, current_h_shape) * weight + + x = x + hack + + return original_forward(x, **kwargs) + return forward diff --git a/extensions-builtin/sd_forge_controlnet/scripts/controlnet_lora.py b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_lora.py new file mode 100644 index 00000000..a0cbd599 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_lora.py @@ -0,0 +1,191 @@ +import torch + +from contextlib import contextmanager +from typing import Union, Tuple + + +_size_2_t = Union[int, Tuple[int, int]] + + +class LinearWithLoRA(torch.nn.Module): + def __init__( + self, + in_features: int, + out_features: int, + bias: bool = True, + device=None, + dtype=None) -> None: + super().__init__() + self.weight_module = None + self.up = None + self.down = None + self.bias = None + self.in_features = in_features + self.out_features = out_features + self.device = device + self.dtype = dtype + self.weight = None + + def bind_lora(self, weight_module): + self.weight_module = [weight_module] + + def unbind_lora(self): + if self.up is not None and self.down is not None: # SAI's model is weird and needs this + self.weight_module = None + + def get_original_weight(self): + if self.weight_module is None: + return None + return self.weight_module[0].weight + + def forward(self, x): + if self.weight is not None: + return torch.nn.functional.linear(x, self.weight.to(x), + self.bias.to(x) if self.bias is not None else None) + + original_weight = self.get_original_weight() + + if original_weight is None: + return None # A1111 needs first_time_calculation + + if self.up is not None and self.down is not None: + weight = original_weight.to(x) + torch.mm(self.up, self.down).to(x) + else: + weight = original_weight.to(x) + + return torch.nn.functional.linear(x, weight, self.bias.to(x) if self.bias is not None else None) + + +class Conv2dWithLoRA(torch.nn.Module): + def __init__( + self, + in_channels: int, + out_channels: int, + kernel_size: _size_2_t, + stride: _size_2_t = 1, + padding: Union[str, _size_2_t] = 0, + dilation: _size_2_t = 1, + groups: int = 1, + bias: bool = True, + padding_mode: str = 'zeros', + device=None, + dtype=None + ) -> None: + super().__init__() + self.stride = stride + self.padding = padding + self.dilation = dilation + self.groups = groups + self.weight_module = None + self.bias = None + self.up = None + self.down = None + self.in_channels = in_channels + self.out_channels = out_channels + self.kernel_size = kernel_size + self.padding_mode = padding_mode + self.device = device + self.dtype = dtype + self.weight = None + + def bind_lora(self, weight_module): + self.weight_module = [weight_module] + + def unbind_lora(self): + if self.up is not None and self.down is not None: # SAI's model is weird and needs this + self.weight_module = None + + def get_original_weight(self): + if self.weight_module is None: + return None + return self.weight_module[0].weight + + def forward(self, x): + if self.weight is not None: + return torch.nn.functional.conv2d(x, self.weight.to(x), self.bias.to(x) if self.bias is not None else None, + self.stride, self.padding, self.dilation, self.groups) + + original_weight = self.get_original_weight() + + if original_weight is None: + return None # A1111 needs first_time_calculation + + if self.up is not None and self.down is not None: + weight = original_weight.to(x) + torch.mm(self.up.flatten(start_dim=1), self.down.flatten(start_dim=1)).reshape(original_weight.shape).to(x) + else: + weight = original_weight.to(x) + + return torch.nn.functional.conv2d(x, weight, self.bias.to(x) if self.bias is not None else None, + self.stride, self.padding, self.dilation, self.groups) + + +@contextmanager +def controlnet_lora_hijack(): + linear, conv2d = torch.nn.Linear, torch.nn.Conv2d + torch.nn.Linear, torch.nn.Conv2d = LinearWithLoRA, Conv2dWithLoRA + try: + yield + finally: + torch.nn.Linear, torch.nn.Conv2d = linear, conv2d + + +def recursive_set(obj, key, value): + if obj is None: + return + if '.' in key: + k1, k2 = key.split('.', 1) + recursive_set(getattr(obj, k1, None), k2, value) + else: + setattr(obj, key, value) + + +def force_load_state_dict(model, state_dict): + for k in list(state_dict.keys()): + recursive_set(model, k, torch.nn.Parameter(state_dict[k])) + del state_dict[k] + return + + +def recursive_bind_lora(obj, key, value): + if obj is None: + return + if '.' in key: + k1, k2 = key.split('.', 1) + recursive_bind_lora(getattr(obj, k1, None), k2, value) + else: + target = getattr(obj, key, None) + if target is not None and hasattr(target, 'bind_lora'): + target.bind_lora(value) + + +def recursive_get(obj, key): + if obj is None: + return + if '.' in key: + k1, k2 = key.split('.', 1) + return recursive_get(getattr(obj, k1, None), k2) + else: + return getattr(obj, key, None) + + +def bind_control_lora(base_model, control_lora_model): + sd = base_model.state_dict() + keys = list(sd.keys()) + keys = list(set([k.rsplit('.', 1)[0] for k in keys])) + module_dict = {k: recursive_get(base_model, k) for k in keys} + for k, v in module_dict.items(): + recursive_bind_lora(control_lora_model, k, v) + + +def torch_dfs(model: torch.nn.Module): + result = [model] + for child in model.children(): + result += torch_dfs(child) + return result + + +def unbind_control_lora(control_lora_model): + for m in torch_dfs(control_lora_model): + if hasattr(m, 'unbind_lora'): + m.unbind_lora() + return diff --git a/extensions-builtin/sd_forge_controlnet/scripts/controlnet_model_guess.py b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_model_guess.py new file mode 100644 index 00000000..8d204c88 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_model_guess.py @@ -0,0 +1,261 @@ +import copy +import os +import torch +from pathlib import Path +from typing import NamedTuple +from modules import devices + +from scripts.adapter import PlugableAdapter, Adapter, StyleAdapter, Adapter_light +from scripts.controlnet_lllite import PlugableControlLLLite +from scripts.cldm import PlugableControlModel +from scripts.controlmodel_ipadapter import PlugableIPAdapter +from scripts.logging import logger +from scripts.controlnet_diffusers import convert_from_diffuser_state_dict +from scripts.controlnet_lora import controlnet_lora_hijack, force_load_state_dict +from scripts.enums import ControlModelType + + +controlnet_default_config = {'adm_in_channels': None, + 'in_channels': 4, + 'model_channels': 320, + 'num_res_blocks': 2, + 'attention_resolutions': [1, 2, 4], + 'transformer_depth': [1, 1, 1, 0], + 'channel_mult': [1, 2, 4, 4], + 'transformer_depth_middle': 1, + 'use_linear_in_transformer': False, + 'context_dim': 768, + "num_heads": 8, + "global_average_pooling": False} + +controlnet_sdxl_config = {'num_classes': 'sequential', + 'adm_in_channels': 2816, + 'in_channels': 4, + 'model_channels': 320, + 'num_res_blocks': 2, + 'attention_resolutions': [2, 4], + 'transformer_depth': [0, 2, 10], + 'channel_mult': [1, 2, 4], + 'transformer_depth_middle': 10, + 'use_linear_in_transformer': True, + 'context_dim': 2048, + "num_head_channels": 64, + "global_average_pooling": False} + +controlnet_sdxl_mid_config = {'num_classes': 'sequential', + 'adm_in_channels': 2816, + 'in_channels': 4, + 'model_channels': 320, + 'num_res_blocks': 2, + 'attention_resolutions': [4], + 'transformer_depth': [0, 0, 1], + 'channel_mult': [1, 2, 4], + 'transformer_depth_middle': 1, + 'use_linear_in_transformer': True, + 'context_dim': 2048, + "num_head_channels": 64, + "global_average_pooling": False} + +controlnet_sdxl_small_config = {'num_classes': 'sequential', + 'adm_in_channels': 2816, + 'in_channels': 4, + 'model_channels': 320, + 'num_res_blocks': 2, + 'attention_resolutions': [], + 'transformer_depth': [0, 0, 0], + 'channel_mult': [1, 2, 4], + 'transformer_depth_middle': 0, + 'use_linear_in_transformer': True, + "num_head_channels": 64, + 'context_dim': 1, + "global_average_pooling": False} + +t2i_adapter_config = { + 'channels': [320, 640, 1280, 1280], + 'nums_rb': 2, + 'ksize': 1, + 'sk': True, + 'cin': 192, + 'use_conv': False +} + +t2i_adapter_light_config = { + 'channels': [320, 640, 1280, 1280], + 'nums_rb': 4, + 'cin': 192, +} + +t2i_adapter_style_config = { + 'width': 1024, + 'context_dim': 768, + 'num_head': 8, + 'n_layes': 3, + 'num_token': 8, +} + + +# Stolen from https://github.com/comfyanonymous/ComfyUI/blob/master/comfy/utils.py +def state_dict_key_replace(state_dict, keys_to_replace): + for x in keys_to_replace: + if x in state_dict: + state_dict[keys_to_replace[x]] = state_dict.pop(x) + return state_dict + + +# # Stolen from https://github.com/comfyanonymous/ComfyUI/blob/master/comfy/utils.py +def state_dict_prefix_replace(state_dict, replace_prefix): + for rp in replace_prefix: + replace = list(map(lambda a: (a, "{}{}".format(replace_prefix[rp], a[len(rp):])), filter(lambda a: a.startswith(rp), state_dict.keys()))) + for x in replace: + state_dict[x[1]] = state_dict.pop(x[0]) + return state_dict + + +class ControlModel(NamedTuple): + model: torch.nn.Module + type: ControlModelType + + +def build_model_by_guess(state_dict, unet, model_path: str) -> ControlModel: + if "lora_controlnet" in state_dict: + is_sdxl = "input_blocks.11.0.in_layers.0.weight" not in state_dict + logger.info(f"Using ControlNet lora ({'SDXL' if is_sdxl else 'SD15'})") + del state_dict['lora_controlnet'] + config = copy.deepcopy(controlnet_sdxl_config if is_sdxl else controlnet_default_config) + config['global_average_pooling'] = False + config['hint_channels'] = int(state_dict['input_hint_block.0.weight'].shape[1]) + config['use_fp16'] = devices.dtype_unet == torch.float16 + with controlnet_lora_hijack(): + network = PlugableControlModel(config, state_dict=None) + force_load_state_dict(network.control_model, state_dict) + network.is_control_lora = True + network.to(devices.dtype_unet) + return ControlModel(network, ControlModelType.ControlLoRA) + + if "controlnet_cond_embedding.conv_in.weight" in state_dict: # diffusers + state_dict = convert_from_diffuser_state_dict(state_dict) + + if 'adapter.body.0.resnets.0.block1.weight' in state_dict: # diffusers + prefix_replace = {} + for i in range(4): + for j in range(2): + prefix_replace["adapter.body.{}.resnets.{}.".format(i, j)] = "body.{}.".format(i * 2 + j) + prefix_replace["adapter.body.{}.".format(i)] = "body.{}.".format(i * 2) + prefix_replace["adapter."] = "" + state_dict = state_dict_prefix_replace(state_dict, prefix_replace) + + if any('image_proj.' in x for x in state_dict.keys()) and any('ip_adapter.' in x for x in state_dict.keys()): # safetensor ipadapters + st_model = {"image_proj": {}, "ip_adapter": {}} + for key in state_dict.keys(): + if key.startswith("image_proj."): + st_model["image_proj"][key.replace("image_proj.", "")] = state_dict[key] + elif key.startswith("ip_adapter."): + st_model["ip_adapter"][key.replace("ip_adapter.", "")] = state_dict[key] + # sort keys + model = {"image_proj": st_model["image_proj"], "ip_adapter": {}} + sorted_keys = sorted(st_model["ip_adapter"].keys(), key=lambda x: int(x.split(".")[0])) + for key in sorted_keys: + model["ip_adapter"][key] = st_model["ip_adapter"][key] + state_dict = model + del st_model + + model_has_shuffle_in_filename = 'shuffle' in Path(os.path.abspath(model_path)).stem.lower() + state_dict = {k.replace("control_model.", ""): v for k, v in state_dict.items()} + state_dict = {k.replace("adapter.", ""): v for k, v in state_dict.items()} + + if 'input_hint_block.0.weight' in state_dict: + if 'label_emb.0.0.bias' not in state_dict: + config = copy.deepcopy(controlnet_default_config) + logger.info('controlnet_default_config') + config['global_average_pooling'] = model_has_shuffle_in_filename + config['hint_channels'] = int(state_dict['input_hint_block.0.weight'].shape[1]) + config['context_dim'] = int(state_dict['input_blocks.5.1.transformer_blocks.0.attn2.to_k.weight'].shape[1]) + for key in state_dict.keys(): + p = state_dict[key] + if 'proj_in.weight' in key or 'proj_out.weight' in key: + if len(p.shape) == 2: + p = p[..., None, None] + state_dict[key] = p + else: + has_full_layers = 'input_blocks.8.1.transformer_blocks.9.norm3.weight' in state_dict + has_mid_layers = 'input_blocks.8.1.transformer_blocks.0.norm3.weight' in state_dict + if has_full_layers: + config = copy.deepcopy(controlnet_sdxl_config) + logger.info('controlnet_sdxl_config') + elif has_mid_layers: + config = copy.deepcopy(controlnet_sdxl_mid_config) + logger.info('controlnet_sdxl_mid_config') + else: + config = copy.deepcopy(controlnet_sdxl_small_config) + logger.info('controlnet_sdxl_small_config') + config['global_average_pooling'] = False + config['hint_channels'] = int(state_dict['input_hint_block.0.weight'].shape[1]) + + if 'difference' in state_dict and unet is not None: + unet_state_dict = unet.state_dict() + unet_state_dict_keys = unet_state_dict.keys() + final_state_dict = {} + for key in state_dict.keys(): + p = state_dict[key] + if key in unet_state_dict_keys: + p_new = p + unet_state_dict[key].clone().cpu() + else: + p_new = p + final_state_dict[key] = p_new + state_dict = final_state_dict + + config['use_fp16'] = devices.dtype_unet == torch.float16 + + network = PlugableControlModel(config, state_dict) + network.to(devices.dtype_unet) + return ControlModel(network, ControlModelType.ControlNet) + + if 'conv_in.weight' in state_dict: + logger.info('t2i_adapter_config') + cin = int(state_dict['conv_in.weight'].shape[1]) + channel = int(state_dict['conv_in.weight'].shape[0]) + ksize = int(state_dict['body.0.block2.weight'].shape[2]) + down_opts = tuple(filter(lambda item: item.endswith("down_opt.op.weight"), state_dict)) + use_conv = len(down_opts) > 0 + is_sdxl = cin == 256 or cin == 768 + adapter = Adapter( + cin=cin, + channels=[channel, channel*2, channel*4, channel*4], + nums_rb=2, + ksize=ksize, + sk=True, + use_conv=use_conv, + is_sdxl=is_sdxl + ).cpu() + adapter.load_state_dict(state_dict, strict=False) + network = PlugableAdapter(adapter) + return ControlModel(network, ControlModelType.T2I_Adapter) + + if 'style_embedding' in state_dict: + config = copy.deepcopy(t2i_adapter_style_config) + logger.info('t2i_adapter_style_config') + adapter = StyleAdapter(**config).cpu() + adapter.load_state_dict(state_dict, strict=False) + network = PlugableAdapter(adapter) + return ControlModel(network, ControlModelType.T2I_StyleAdapter) + + if 'body.0.in_conv.weight' in state_dict: + config = copy.deepcopy(t2i_adapter_light_config) + logger.info('t2i_adapter_light_config') + config['cin'] = int(state_dict['body.0.in_conv.weight'].shape[1]) + adapter = Adapter_light(**config).cpu() + adapter.load_state_dict(state_dict, strict=False) + network = PlugableAdapter(adapter) + return ControlModel(network, ControlModelType.T2I_Adapter) + + if 'ip_adapter' in state_dict: + network = PlugableIPAdapter(state_dict, model_path) + network.to('cpu') + return ControlModel(network, ControlModelType.IPAdapter) + + if any('lllite' in k for k in state_dict.keys()): + network = PlugableControlLLLite(state_dict) + network.to('cpu') + return ControlModel(network, ControlModelType.Controlllite) + + raise '[ControlNet Error] Cannot recognize the ControlModel!' diff --git a/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/controlnet_ui_group.py b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/controlnet_ui_group.py new file mode 100644 index 00000000..a00b3fd8 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/controlnet_ui_group.py @@ -0,0 +1,1412 @@ +import json +import gradio as gr +import functools +from copy import copy +from typing import List, Optional, Union, Callable, Dict, Tuple, Literal +from dataclasses import dataclass +import numpy as np + +from scripts.utils import svg_preprocess, read_image +from scripts import ( + global_state, + external_code, +) +from scripts.processor import ( + preprocessor_sliders_config, + no_control_mode_preprocessors, + flag_preprocessor_resolution, + model_free_preprocessors, + preprocessor_filters, + HWC3, +) +from scripts.logging import logger +from scripts.controlnet_ui.openpose_editor import OpenposeEditor +from scripts.controlnet_ui.preset import ControlNetPresetUI +from scripts.controlnet_ui.tool_button import ToolButton +from scripts.controlnet_ui.photopea import Photopea +from scripts.enums import InputMode +from modules import shared +from modules.ui_components import FormRow + + +@dataclass +class A1111Context: + """Contains all components from A1111.""" + + img2img_batch_input_dir: Optional[gr.components.IOComponent] = None + img2img_batch_output_dir: Optional[gr.components.IOComponent] = None + txt2img_submit_button: Optional[gr.components.IOComponent] = None + img2img_submit_button: Optional[gr.components.IOComponent] = None + + # Slider controls from A1111 WebUI. + txt2img_w_slider: Optional[gr.components.IOComponent] = None + txt2img_h_slider: Optional[gr.components.IOComponent] = None + img2img_w_slider: Optional[gr.components.IOComponent] = None + img2img_h_slider: Optional[gr.components.IOComponent] = None + + img2img_img2img_tab: Optional[gr.components.IOComponent] = None + img2img_img2img_sketch_tab: Optional[gr.components.IOComponent] = None + img2img_batch_tab: Optional[gr.components.IOComponent] = None + img2img_inpaint_tab: Optional[gr.components.IOComponent] = None + img2img_inpaint_sketch_tab: Optional[gr.components.IOComponent] = None + img2img_inpaint_upload_tab: Optional[gr.components.IOComponent] = None + + img2img_inpaint_area: Optional[gr.components.IOComponent] = None + # txt2img_enable_hr is only available for A1111 > 1.7.0. + txt2img_enable_hr: Optional[gr.components.IOComponent] = None + setting_sd_model_checkpoint: Optional[gr.components.IOComponent] = None + + @property + def img2img_inpaint_tabs(self) -> Tuple[gr.components.IOComponent]: + return ( + self.img2img_inpaint_tab, + self.img2img_inpaint_sketch_tab, + self.img2img_inpaint_upload_tab, + ) + + @property + def img2img_non_inpaint_tabs(self) -> List[gr.components.IOComponent]: + return ( + self.img2img_img2img_tab, + self.img2img_img2img_sketch_tab, + self.img2img_batch_tab, + ) + + @property + def ui_initialized(self) -> bool: + # Optional components are only available after A1111 v1.7.0. + optional_components = { + "img2img_img2img_tab": "img2img_img2img_tab", + "img2img_img2img_sketch_tab": "img2img_img2img_sketch_tab", + "img2img_batch_tab": "img2img_batch_tab", + "img2img_inpaint_tab": "img2img_inpaint_tab", + "img2img_inpaint_sketch_tab": "img2img_inpaint_sketch_tab", + "img2img_inpaint_upload_tab": "img2img_inpaint_upload_tab", + } + return all( + c + for name, c in vars(self).items() + if name not in optional_components.values() + ) + + def set_component(self, component: gr.components.IOComponent): + id_mapping = { + "img2img_batch_input_dir": "img2img_batch_input_dir", + "img2img_batch_output_dir": "img2img_batch_output_dir", + "txt2img_generate": "txt2img_submit_button", + "img2img_generate": "img2img_submit_button", + "txt2img_width": "txt2img_w_slider", + "txt2img_height": "txt2img_h_slider", + "img2img_width": "img2img_w_slider", + "img2img_height": "img2img_h_slider", + "img2img_img2img_tab": "img2img_img2img_tab", + "img2img_img2img_sketch_tab": "img2img_img2img_sketch_tab", + "img2img_batch_tab": "img2img_batch_tab", + "img2img_inpaint_tab": "img2img_inpaint_tab", + "img2img_inpaint_sketch_tab": "img2img_inpaint_sketch_tab", + "img2img_inpaint_upload_tab": "img2img_inpaint_upload_tab", + "img2img_inpaint_full_res": "img2img_inpaint_area", + "txt2img_hr-checkbox": "txt2img_enable_hr", + # setting_sd_model_checkpoint is expected to be initialized last. + "setting_sd_model_checkpoint": "setting_sd_model_checkpoint", + } + elem_id = getattr(component, "elem_id", None) + if elem_id in id_mapping: + setattr(self, id_mapping[elem_id], component) + logger.debug(f"Setting {elem_id}.") + logger.debug( + f"A1111 initialized {sum(c is not None for c in vars(self).values())}/{len(vars(self).keys())}." + ) + + +class UiControlNetUnit(external_code.ControlNetUnit): + """The data class that stores all states of a ControlNetUnit.""" + + def __init__( + self, + input_mode: InputMode = InputMode.SIMPLE, + batch_images: Optional[Union[str, List[external_code.InputImage]]] = None, + output_dir: str = "", + loopback: bool = False, + merge_gallery_files: List[ + Dict[Union[Literal["name"], Literal["data"]], str] + ] = [], + use_preview_as_input: bool = False, + generated_image: Optional[np.ndarray] = None, + mask_image: Optional[np.ndarray] = None, + enabled: bool = True, + module: Optional[str] = None, + model: Optional[str] = None, + weight: float = 1.0, + image: Optional[Dict[str, np.ndarray]] = None, + *args, + **kwargs, + ): + if use_preview_as_input and generated_image is not None: + input_image = generated_image + module = "none" + else: + input_image = image + + # Prefer uploaded mask_image over hand-drawn mask. + if input_image is not None and mask_image is not None: + assert isinstance(input_image, dict) + input_image["mask"] = mask_image + + if merge_gallery_files and input_mode == InputMode.MERGE: + input_image = [ + {"image": read_image(file["name"])} for file in merge_gallery_files + ] + + super().__init__(enabled, module, model, weight, input_image, *args, **kwargs) + self.is_ui = True + self.input_mode = input_mode + self.batch_images = batch_images + self.output_dir = output_dir + self.loopback = loopback + + def unfold_merged(self) -> List[external_code.ControlNetUnit]: + """Unfolds a merged unit to multiple units. Keeps the unit merged for + preprocessors that can accept multiple input images. + """ + if self.input_mode != InputMode.MERGE: + return [copy(self)] + + if self.accepts_multiple_inputs(): + self.input_mode = InputMode.SIMPLE + return [copy(self)] + + assert isinstance(self.image, list) + result = [] + for image in self.image: + unit = copy(self) + unit.image = image["image"] + unit.input_mode = InputMode.SIMPLE + unit.weight = self.weight / len(self.image) + result.append(unit) + return result + + +class ControlNetUiGroup(object): + refresh_symbol = "\U0001f504" # 🔄 + switch_values_symbol = "\U000021C5" # ⇅ + camera_symbol = "\U0001F4F7" # 📷 + reverse_symbol = "\U000021C4" # ⇄ + tossup_symbol = "\u2934" + trigger_symbol = "\U0001F4A5" # 💥 + open_symbol = "\U0001F4DD" # 📝 + + tooltips = { + "🔄": "Refresh", + "\u2934": "Send dimensions to stable diffusion", + "💥": "Run preprocessor", + "📝": "Open new canvas", + "📷": "Enable webcam", + "⇄": "Mirror webcam", + } + + global_batch_input_dir = gr.Textbox( + label="Controlnet input directory", + placeholder="Leave empty to use input directory", + **shared.hide_dirs, + elem_id="controlnet_batch_input_dir", + ) + a1111_context = A1111Context() + # All ControlNetUiGroup instances created. + all_ui_groups: List["ControlNetUiGroup"] = [] + + def __init__( + self, + is_img2img: bool, + default_unit: external_code.ControlNetUnit, + preprocessors: List[Callable], + photopea: Optional[Photopea], + ): + # Whether callbacks have been registered. + self.callbacks_registered: bool = False + + self.is_img2img = is_img2img + self.default_unit = default_unit + self.preprocessors = preprocessors + self.photopea = photopea + self.webcam_enabled = False + self.webcam_mirrored = False + + # Note: All gradio elements declared in `render` will be defined as member variable. + # Update counter to trigger a force update of UiControlNetUnit. + # This is useful when a field with no event subscriber available changes. + # e.g. gr.Gallery, gr.State, etc. + self.update_unit_counter = None + self.upload_tab = None + self.image = None + self.generated_image_group = None + self.generated_image = None + self.mask_image_group = None + self.mask_image = None + self.batch_tab = None + self.batch_image_dir = None + self.merge_tab = None + self.merge_gallery = None + self.merge_upload_button = None + self.merge_clear_button = None + self.create_canvas = None + self.canvas_width = None + self.canvas_height = None + self.canvas_create_button = None + self.canvas_cancel_button = None + self.open_new_canvas_button = None + self.webcam_enable = None + self.webcam_mirror = None + self.send_dimen_button = None + self.enabled = None + self.low_vram = None + self.pixel_perfect = None + self.preprocessor_preview = None + self.mask_upload = None + self.type_filter = None + self.module = None + self.trigger_preprocessor = None + self.model = None + self.refresh_models = None + self.weight = None + self.guidance_start = None + self.guidance_end = None + self.advanced = None + self.processor_res = None + self.threshold_a = None + self.threshold_b = None + self.control_mode = None + self.resize_mode = None + self.loopback = None + self.use_preview_as_input = None + self.openpose_editor = None + self.preset_panel = None + self.upload_independent_img_in_img2img = None + self.image_upload_panel = None + self.save_detected_map = None + self.input_mode = gr.State(InputMode.SIMPLE) + self.inpaint_crop_input_image = None + self.hr_option = None + self.batch_image_dir_state = None + self.output_dir_state = None + + # Internal states for UI state pasting. + self.prevent_next_n_module_update = 0 + self.prevent_next_n_slider_value_update = 0 + + # API-only fields + self.advanced_weighting = gr.State(None) + + ControlNetUiGroup.all_ui_groups.append(self) + + def render(self, tabname: str, elem_id_tabname: str) -> None: + """The pure HTML structure of a single ControlNetUnit. Calling this + function will populate `self` with all gradio element declared + in local scope. + + Args: + tabname: + elem_id_tabname: + + Returns: + None + """ + self.update_unit_counter = gr.Number(value=0, visible=False) + self.openpose_editor = OpenposeEditor() + + with gr.Group(visible=not self.is_img2img) as self.image_upload_panel: + self.save_detected_map = gr.Checkbox(value=True, visible=False) + with gr.Tabs(): + with gr.Tab(label="Single Image") as self.upload_tab: + with gr.Row(elem_classes=["cnet-image-row"], equal_height=True): + with gr.Group(elem_classes=["cnet-input-image-group"]): + self.image = gr.Image( + source="upload", + brush_radius=20, + mirror_webcam=False, + type="numpy", + tool="sketch", + elem_id=f"{elem_id_tabname}_{tabname}_input_image", + elem_classes=["cnet-image"], + brush_color=shared.opts.img2img_inpaint_mask_brush_color + if hasattr( + shared.opts, "img2img_inpaint_mask_brush_color" + ) + else None, + ) + self.image.preprocess = functools.partial( + svg_preprocess, preprocess=self.image.preprocess + ) + self.openpose_editor.render_upload() + + with gr.Group( + visible=False, elem_classes=["cnet-generated-image-group"] + ) as self.generated_image_group: + self.generated_image = gr.Image( + value=None, + label="Preprocessor Preview", + elem_id=f"{elem_id_tabname}_{tabname}_generated_image", + elem_classes=["cnet-image"], + interactive=True, + height=242, + ) # Gradio's magic number. Only 242 works. + + with gr.Group( + elem_classes=["cnet-generated-image-control-group"] + ): + if self.photopea: + self.photopea.render_child_trigger() + self.openpose_editor.render_edit() + preview_check_elem_id = f"{elem_id_tabname}_{tabname}_controlnet_preprocessor_preview_checkbox" + preview_close_button_js = f"document.querySelector('#{preview_check_elem_id} input[type=\\'checkbox\\']').click();" + gr.HTML( + value=f"""Close""", + visible=True, + elem_classes=["cnet-close-preview"], + ) + + with gr.Group( + visible=False, elem_classes=["cnet-mask-image-group"] + ) as self.mask_image_group: + self.mask_image = gr.Image( + value=None, + label="Upload Mask", + elem_id=f"{elem_id_tabname}_{tabname}_mask_image", + elem_classes=["cnet-mask-image"], + interactive=True, + ) + + with gr.Tab(label="Batch") as self.batch_tab: + self.batch_image_dir = gr.Textbox( + label="Input Directory", + placeholder="Leave empty to use img2img batch controlnet input directory", + elem_id=f"{elem_id_tabname}_{tabname}_batch_image_dir", + ) + + with gr.Tab(label="Multi-Inputs") as self.merge_tab: + self.merge_gallery = gr.Gallery( + columns=[4], rows=[2], object_fit="contain", height="auto" + ) + with gr.Row(): + self.merge_upload_button = gr.UploadButton( + "Upload Images", + file_types=["image"], + file_count="multiple", + ) + self.merge_clear_button = gr.Button("Clear Images") + + if self.photopea: + self.photopea.attach_photopea_output(self.generated_image) + + with gr.Accordion( + label="Open New Canvas", visible=False + ) as self.create_canvas: + self.canvas_width = gr.Slider( + label="New Canvas Width", + minimum=256, + maximum=1024, + value=512, + step=64, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_canvas_width", + ) + self.canvas_height = gr.Slider( + label="New Canvas Height", + minimum=256, + maximum=1024, + value=512, + step=64, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_canvas_height", + ) + with gr.Row(): + self.canvas_create_button = gr.Button( + value="Create New Canvas", + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_canvas_create_button", + ) + self.canvas_cancel_button = gr.Button( + value="Cancel", + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_canvas_cancel_button", + ) + + with gr.Row(elem_classes="controlnet_image_controls"): + gr.HTML( + value="

    Set the preprocessor to [invert] If your image has white background and black lines.

    ", + elem_classes="controlnet_invert_warning", + ) + self.open_new_canvas_button = ToolButton( + value=ControlNetUiGroup.open_symbol, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_open_new_canvas_button", + tooltip=ControlNetUiGroup.tooltips[ControlNetUiGroup.open_symbol], + ) + self.webcam_enable = ToolButton( + value=ControlNetUiGroup.camera_symbol, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_webcam_enable", + tooltip=ControlNetUiGroup.tooltips[ControlNetUiGroup.camera_symbol], + ) + self.webcam_mirror = ToolButton( + value=ControlNetUiGroup.reverse_symbol, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_webcam_mirror", + tooltip=ControlNetUiGroup.tooltips[ + ControlNetUiGroup.reverse_symbol + ], + ) + self.send_dimen_button = ToolButton( + value=ControlNetUiGroup.tossup_symbol, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_send_dimen_button", + tooltip=ControlNetUiGroup.tooltips[ControlNetUiGroup.tossup_symbol], + ) + + with FormRow(elem_classes=["controlnet_main_options"]): + self.enabled = gr.Checkbox( + label="Enable", + value=self.default_unit.enabled, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_enable_checkbox", + elem_classes=["cnet-unit-enabled"], + ) + self.low_vram = gr.Checkbox( + label="Low VRAM", + value=self.default_unit.low_vram, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_low_vram_checkbox", + ) + self.pixel_perfect = gr.Checkbox( + label="Pixel Perfect", + value=self.default_unit.pixel_perfect, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_pixel_perfect_checkbox", + ) + self.preprocessor_preview = gr.Checkbox( + label="Allow Preview", + value=False, + elem_classes=["cnet-allow-preview"], + elem_id=preview_check_elem_id, + visible=not self.is_img2img, + ) + self.mask_upload = gr.Checkbox( + label="Mask Upload", + value=False, + elem_classes=["cnet-mask-upload"], + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_mask_upload_checkbox", + visible=not self.is_img2img, + ) + self.use_preview_as_input = gr.Checkbox( + label="Preview as Input", + value=False, + elem_classes=["cnet-preview-as-input"], + visible=False, + ) + + with gr.Row(elem_classes="controlnet_img2img_options"): + if self.is_img2img: + self.upload_independent_img_in_img2img = gr.Checkbox( + label="Upload independent control image", + value=False, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_same_img2img_checkbox", + elem_classes=["cnet-unit-same_img2img"], + ) + else: + self.upload_independent_img_in_img2img = None + + # Note: The checkbox needs to exist for both img2img and txt2img as infotext + # needs the checkbox value. + self.inpaint_crop_input_image = gr.Checkbox( + label="Crop input image based on A1111 mask", + value=False, + elem_classes=["cnet-crop-input-image"], + visible=False, + ) + + with gr.Row(elem_classes=["controlnet_control_type", "controlnet_row"]): + self.type_filter = gr.Radio( + list(preprocessor_filters.keys()), + label=f"Control Type", + value="All", + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_type_filter_radio", + elem_classes="controlnet_control_type_filter_group", + ) + + with gr.Row(elem_classes=["controlnet_preprocessor_model", "controlnet_row"]): + self.module = gr.Dropdown( + global_state.ui_preprocessor_keys, + label=f"Preprocessor", + value=self.default_unit.module, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_preprocessor_dropdown", + ) + self.trigger_preprocessor = ToolButton( + value=ControlNetUiGroup.trigger_symbol, + visible=not self.is_img2img, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_trigger_preprocessor", + elem_classes=["cnet-run-preprocessor"], + tooltip=ControlNetUiGroup.tooltips[ControlNetUiGroup.trigger_symbol], + ) + self.model = gr.Dropdown( + list(global_state.cn_models.keys()), + label=f"Model", + value=self.default_unit.model, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_model_dropdown", + ) + self.refresh_models = ToolButton( + value=ControlNetUiGroup.refresh_symbol, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_refresh_models", + tooltip=ControlNetUiGroup.tooltips[ControlNetUiGroup.refresh_symbol], + ) + + with gr.Row(elem_classes=["controlnet_weight_steps", "controlnet_row"]): + self.weight = gr.Slider( + label=f"Control Weight", + value=self.default_unit.weight, + minimum=0.0, + maximum=2.0, + step=0.05, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_control_weight_slider", + elem_classes="controlnet_control_weight_slider", + ) + self.guidance_start = gr.Slider( + label="Starting Control Step", + value=self.default_unit.guidance_start, + minimum=0.0, + maximum=1.0, + interactive=True, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_start_control_step_slider", + elem_classes="controlnet_start_control_step_slider", + ) + self.guidance_end = gr.Slider( + label="Ending Control Step", + value=self.default_unit.guidance_end, + minimum=0.0, + maximum=1.0, + interactive=True, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_ending_control_step_slider", + elem_classes="controlnet_ending_control_step_slider", + ) + + # advanced options + with gr.Column(visible=False) as self.advanced: + self.processor_res = gr.Slider( + label="Preprocessor resolution", + value=self.default_unit.processor_res, + minimum=64, + maximum=2048, + visible=False, + interactive=True, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_preprocessor_resolution_slider", + ) + self.threshold_a = gr.Slider( + label="Threshold A", + value=self.default_unit.threshold_a, + minimum=64, + maximum=1024, + visible=False, + interactive=True, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_threshold_A_slider", + ) + self.threshold_b = gr.Slider( + label="Threshold B", + value=self.default_unit.threshold_b, + minimum=64, + maximum=1024, + visible=False, + interactive=True, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_threshold_B_slider", + ) + + self.control_mode = gr.Radio( + choices=[e.value for e in external_code.ControlMode], + value=self.default_unit.control_mode.value, + label="Control Mode", + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_control_mode_radio", + elem_classes="controlnet_control_mode_radio", + ) + + self.resize_mode = gr.Radio( + choices=[e.value for e in external_code.ResizeMode], + value=self.default_unit.resize_mode.value, + label="Resize Mode", + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_resize_mode_radio", + elem_classes="controlnet_resize_mode_radio", + visible=not self.is_img2img, + ) + + self.hr_option = gr.Radio( + choices=[e.value for e in external_code.HiResFixOption], + value=self.default_unit.hr_option.value, + label="Hires-Fix Option", + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_hr_option_radio", + elem_classes="controlnet_hr_option_radio", + visible=False, + ) + + self.loopback = gr.Checkbox( + label="[Batch Loopback] Automatically send generated images to this ControlNet unit in batch generation", + value=self.default_unit.loopback, + elem_id=f"{elem_id_tabname}_{tabname}_controlnet_automatically_send_generated_images_checkbox", + elem_classes="controlnet_loopback_checkbox", + visible=False, + ) + + self.preset_panel = ControlNetPresetUI( + id_prefix=f"{elem_id_tabname}_{tabname}_" + ) + + self.batch_image_dir_state = gr.State("") + self.output_dir_state = gr.State("") + unit_args = ( + self.input_mode, + self.batch_image_dir_state, + self.output_dir_state, + self.loopback, + # Non-persistent fields. + # Following inputs will not be persistent on `ControlNetUnit`. + # They are only used during object construction. + self.merge_gallery, + self.use_preview_as_input, + self.generated_image, + self.mask_image, + # End of Non-persistent fields. + self.enabled, + self.module, + self.model, + self.weight, + self.image, + self.resize_mode, + self.low_vram, + self.processor_res, + self.threshold_a, + self.threshold_b, + self.guidance_start, + self.guidance_end, + self.pixel_perfect, + self.control_mode, + self.inpaint_crop_input_image, + self.hr_option, + ) + + unit = gr.State(self.default_unit) + for comp in unit_args + (self.update_unit_counter,): + event_subscribers = [] + if hasattr(comp, "edit"): + event_subscribers.append(comp.edit) + elif hasattr(comp, "click"): + event_subscribers.append(comp.click) + elif isinstance(comp, gr.Slider) and hasattr(comp, "release"): + event_subscribers.append(comp.release) + elif hasattr(comp, "change"): + event_subscribers.append(comp.change) + + if hasattr(comp, "clear"): + event_subscribers.append(comp.clear) + + for event_subscriber in event_subscribers: + event_subscriber( + fn=UiControlNetUnit, inputs=list(unit_args), outputs=unit + ) + + ( + ControlNetUiGroup.a1111_context.img2img_submit_button + if self.is_img2img + else ControlNetUiGroup.a1111_context.txt2img_submit_button + ).click( + fn=UiControlNetUnit, + inputs=list(unit_args), + outputs=unit, + queue=False, + ) + + return unit + + def register_send_dimensions(self): + """Register event handler for send dimension button.""" + + def send_dimensions(image): + def closesteight(num): + rem = num % 8 + if rem <= 4: + return round(num - rem) + else: + return round(num + (8 - rem)) + + if image: + interm = np.asarray(image.get("image")) + return closesteight(interm.shape[1]), closesteight(interm.shape[0]) + else: + return gr.Slider.update(), gr.Slider.update() + + outputs = ( + [ + ControlNetUiGroup.a1111_context.img2img_w_slider, + ControlNetUiGroup.a1111_context.img2img_h_slider, + ] + if self.is_img2img + else [ + ControlNetUiGroup.a1111_context.txt2img_w_slider, + ControlNetUiGroup.a1111_context.txt2img_h_slider, + ] + ) + self.send_dimen_button.click( + fn=send_dimensions, + inputs=[self.image], + outputs=outputs, + show_progress=False, + ) + + def register_webcam_toggle(self): + def webcam_toggle(): + self.webcam_enabled = not self.webcam_enabled + return { + "value": None, + "source": "webcam" if self.webcam_enabled else "upload", + "__type__": "update", + } + + self.webcam_enable.click( + webcam_toggle, inputs=None, outputs=self.image, show_progress=False + ) + + def register_webcam_mirror_toggle(self): + def webcam_mirror_toggle(): + self.webcam_mirrored = not self.webcam_mirrored + return {"mirror_webcam": self.webcam_mirrored, "__type__": "update"} + + self.webcam_mirror.click( + webcam_mirror_toggle, inputs=None, outputs=self.image, show_progress=False + ) + + def register_refresh_all_models(self): + def refresh_all_models(*inputs): + global_state.update_cn_models() + + dd = inputs[0] + selected = dd if dd in global_state.cn_models else "None" + return gr.Dropdown.update( + value=selected, choices=list(global_state.cn_models.keys()) + ) + + self.refresh_models.click( + refresh_all_models, self.model, self.model, show_progress=False + ) + + def register_build_sliders(self): + def build_sliders(module: str, pp: bool): + logger.debug( + f"Prevent update slider value: {self.prevent_next_n_slider_value_update}" + ) + logger.debug(f"Build slider for module: {module} - {pp}") + + # Clear old slider values so that they do not cause confusion in + # infotext. + clear_slider_update = gr.update( + visible=False, + interactive=True, + minimum=-1, + maximum=-1, + value=-1, + ) + + grs = [] + module = global_state.get_module_basename(module) + if module not in preprocessor_sliders_config: + default_res_slider_config = dict( + label=flag_preprocessor_resolution, + minimum=64, + maximum=2048, + step=1, + ) + if self.prevent_next_n_slider_value_update == 0: + default_res_slider_config["value"] = 512 + + grs += [ + gr.update( + **default_res_slider_config, + visible=not pp, + interactive=True, + ), + copy(clear_slider_update), + copy(clear_slider_update), + gr.update(visible=True), + ] + else: + for slider_config in preprocessor_sliders_config[module]: + if isinstance(slider_config, dict): + visible = True + if slider_config["name"] == flag_preprocessor_resolution: + visible = not pp + slider_update = gr.update( + label=slider_config["name"], + minimum=slider_config["min"], + maximum=slider_config["max"], + step=slider_config["step"] + if "step" in slider_config + else 1, + visible=visible, + interactive=True, + ) + if self.prevent_next_n_slider_value_update == 0: + slider_update["value"] = slider_config["value"] + + grs.append(slider_update) + + else: + grs.append(copy(clear_slider_update)) + while len(grs) < 3: + grs.append(copy(clear_slider_update)) + grs.append(gr.update(visible=True)) + if module in model_free_preprocessors: + grs += [ + gr.update(visible=False, value="None"), + gr.update(visible=False), + ] + else: + grs += [gr.update(visible=True), gr.update(visible=True)] + + self.prevent_next_n_slider_value_update = max( + 0, self.prevent_next_n_slider_value_update - 1 + ) + + grs += [gr.update(visible=module not in no_control_mode_preprocessors)] + + return grs + + inputs = [ + self.module, + self.pixel_perfect, + ] + outputs = [ + self.processor_res, + self.threshold_a, + self.threshold_b, + self.advanced, + self.model, + self.refresh_models, + self.control_mode, + ] + self.module.change( + build_sliders, inputs=inputs, outputs=outputs, show_progress=False + ) + self.pixel_perfect.change( + build_sliders, inputs=inputs, outputs=outputs, show_progress=False + ) + + def filter_selected(k: str): + logger.debug(f"Prevent update {self.prevent_next_n_module_update}") + logger.debug(f"Switch to control type {k}") + ( + filtered_preprocessor_list, + filtered_model_list, + default_option, + default_model, + ) = global_state.select_control_type(k, global_state.get_sd_version()) + + if self.prevent_next_n_module_update > 0: + self.prevent_next_n_module_update -= 1 + return [ + gr.Dropdown.update(choices=filtered_preprocessor_list), + gr.Dropdown.update(choices=filtered_model_list), + ] + else: + return [ + gr.Dropdown.update( + value=default_option, choices=filtered_preprocessor_list + ), + gr.Dropdown.update( + value=default_model, choices=filtered_model_list + ), + ] + + self.type_filter.change( + fn=filter_selected, + inputs=[self.type_filter], + outputs=[self.module, self.model], + show_progress=False, + ) + + def sd_version_changed(type_filter: str, current_model: str): + """When SD version changes, update model dropdown choices.""" + ( + filtered_preprocessor_list, + filtered_model_list, + default_option, + default_model, + ) = global_state.select_control_type( + type_filter, global_state.get_sd_version() + ) + + if current_model in filtered_model_list: + return gr.update() + + return gr.Dropdown.update( + value=default_model, + choices=filtered_model_list, + ) + + ControlNetUiGroup.a1111_context.setting_sd_model_checkpoint.change( + fn=sd_version_changed, + inputs=[self.type_filter, self.model], + outputs=[self.model], + show_progress=False, + ) + + def register_run_annotator(self): + def run_annotator(image, module, pres, pthr_a, pthr_b, t2i_w, t2i_h, pp, rm): + if image is None: + return ( + gr.update(value=None, visible=True), + gr.update(), + *self.openpose_editor.update(""), + ) + + img = HWC3(image["image"]) + has_mask = not ( + (image["mask"][:, :, 0] <= 5).all() + or (image["mask"][:, :, 0] >= 250).all() + ) + if "inpaint" in module: + color = HWC3(image["image"]) + alpha = image["mask"][:, :, 0:1] + img = np.concatenate([color, alpha], axis=2) + elif has_mask and not shared.opts.data.get( + "controlnet_ignore_noninpaint_mask", False + ): + img = HWC3(image["mask"][:, :, 0]) + + module = global_state.get_module_basename(module) + preprocessor = self.preprocessors[module] + + if pp: + pres = external_code.pixel_perfect_resolution( + img, + target_H=t2i_h, + target_W=t2i_w, + resize_mode=external_code.resize_mode_from_value(rm), + ) + + class JsonAcceptor: + def __init__(self) -> None: + self.value = "" + + def accept(self, json_dict: dict) -> None: + self.value = json.dumps(json_dict) + + json_acceptor = JsonAcceptor() + + logger.info(f"Preview Resolution = {pres}") + + def is_openpose(module: str): + return "openpose" in module + + # Only openpose preprocessor returns a JSON output, pass json_acceptor + # only when a JSON output is expected. This will make preprocessor cache + # work for all other preprocessors other than openpose ones. JSON acceptor + # instance are different every call, which means cache will never take + # effect. + # TODO: Maybe we should let `preprocessor` return a Dict to alleviate this issue? + # This requires changing all callsites though. + result, is_image = preprocessor( + img, + res=pres, + thr_a=pthr_a, + thr_b=pthr_b, + low_vram=( + ("clip" in module or module == "ip-adapter_face_id_plus") + and shared.opts.data.get("controlnet_clip_detector_on_cpu", False) + ), + json_pose_callback=json_acceptor.accept + if is_openpose(module) + else None, + ) + + if not is_image: + result = img + is_image = True + + result = external_code.visualize_inpaint_mask(result) + return ( + # Update to `generated_image` + gr.update(value=result, visible=True, interactive=False), + # preprocessor_preview + gr.update(value=True), + # openpose editor + *self.openpose_editor.update(json_acceptor.value), + ) + + self.trigger_preprocessor.click( + fn=run_annotator, + inputs=[ + self.image, + self.module, + self.processor_res, + self.threshold_a, + self.threshold_b, + ControlNetUiGroup.a1111_context.img2img_w_slider + if self.is_img2img + else ControlNetUiGroup.a1111_context.txt2img_w_slider, + ControlNetUiGroup.a1111_context.img2img_h_slider + if self.is_img2img + else ControlNetUiGroup.a1111_context.txt2img_h_slider, + self.pixel_perfect, + self.resize_mode, + ], + outputs=[ + self.generated_image, + self.preprocessor_preview, + *self.openpose_editor.outputs(), + ], + ) + + def register_shift_preview(self): + def shift_preview(is_on): + return ( + # generated_image + gr.update() if is_on else gr.update(value=None), + # generated_image_group + gr.update(visible=is_on), + # use_preview_as_input, + gr.update(visible=False), # Now this is automatically managed + # download_pose_link + gr.update() if is_on else gr.update(value=None), + # modal edit button + gr.update() if is_on else gr.update(visible=False), + ) + + self.preprocessor_preview.change( + fn=shift_preview, + inputs=[self.preprocessor_preview], + outputs=[ + self.generated_image, + self.generated_image_group, + self.use_preview_as_input, + self.openpose_editor.download_link, + self.openpose_editor.modal, + ], + show_progress=False, + ) + + def register_create_canvas(self): + self.open_new_canvas_button.click( + lambda: gr.Accordion.update(visible=True), + inputs=None, + outputs=self.create_canvas, + show_progress=False, + ) + self.canvas_cancel_button.click( + lambda: gr.Accordion.update(visible=False), + inputs=None, + outputs=self.create_canvas, + show_progress=False, + ) + + def fn_canvas(h, w): + return np.zeros(shape=(h, w, 3), dtype=np.uint8) + 255, gr.Accordion.update( + visible=False + ) + + self.canvas_create_button.click( + fn=fn_canvas, + inputs=[self.canvas_height, self.canvas_width], + outputs=[self.image, self.create_canvas], + show_progress=False, + ) + + def register_img2img_same_input(self): + def fn_same_checked(x): + return [ + gr.update(value=None), + gr.update(value=None), + gr.update(value=False, visible=x), + ] + [gr.update(visible=x)] * 4 + + self.upload_independent_img_in_img2img.change( + fn_same_checked, + inputs=self.upload_independent_img_in_img2img, + outputs=[ + self.image, + self.batch_image_dir, + self.preprocessor_preview, + self.image_upload_panel, + self.trigger_preprocessor, + self.loopback, + self.resize_mode, + ], + show_progress=False, + ) + + def register_shift_crop_input_image(self): + # A1111 < 1.7.0 compatibility. + if any(c is None for c in ControlNetUiGroup.a1111_context.img2img_inpaint_tabs): + self.inpaint_crop_input_image.visible = True + self.inpaint_crop_input_image.value = True + return + + is_inpaint_tab = gr.State(False) + + def shift_crop_input_image(is_inpaint: bool, inpaint_area: int): + # Note: inpaint_area (0: Whole picture, 1: Only masked) + # By default set value to True, as most preprocessors need cropped result. + return gr.update(value=True, visible=is_inpaint and inpaint_area == 1) + + gradio_kwargs = dict( + fn=shift_crop_input_image, + inputs=[ + is_inpaint_tab, + ControlNetUiGroup.a1111_context.img2img_inpaint_area, + ], + outputs=[self.inpaint_crop_input_image], + show_progress=False, + ) + + for elem in ControlNetUiGroup.a1111_context.img2img_inpaint_tabs: + elem.select(fn=lambda: True, inputs=[], outputs=[is_inpaint_tab]).then( + **gradio_kwargs + ) + + for elem in ControlNetUiGroup.a1111_context.img2img_non_inpaint_tabs: + elem.select(fn=lambda: False, inputs=[], outputs=[is_inpaint_tab]).then( + **gradio_kwargs + ) + + ControlNetUiGroup.a1111_context.img2img_inpaint_area.change(**gradio_kwargs) + + def register_shift_hr_options(self): + # A1111 version < 1.6.0. + if not ControlNetUiGroup.a1111_context.txt2img_enable_hr: + return + + ControlNetUiGroup.a1111_context.txt2img_enable_hr.change( + fn=lambda checked: gr.update(visible=checked), + inputs=[ControlNetUiGroup.a1111_context.txt2img_enable_hr], + outputs=[self.hr_option], + show_progress=False, + ) + + def register_shift_upload_mask(self): + """Controls whether the upload mask input should be visible.""" + self.mask_upload.change( + fn=lambda checked: ( + # Clear mask_image if unchecked. + (gr.update(visible=False), gr.update(value=None)) + if not checked + else (gr.update(visible=True), gr.update()) + ), + inputs=[self.mask_upload], + outputs=[self.mask_image_group, self.mask_image], + show_progress=False, + ) + + if self.upload_independent_img_in_img2img is not None: + self.upload_independent_img_in_img2img.change( + fn=lambda checked: ( + # Uncheck `upload_mask` when not using independent input. + gr.update(visible=False, value=False) + if not checked + else gr.update(visible=True) + ), + inputs=[self.upload_independent_img_in_img2img], + outputs=[self.mask_upload], + show_progress=False, + ) + + def register_sync_batch_dir(self): + def determine_batch_dir(batch_dir, fallback_dir, fallback_fallback_dir): + if batch_dir: + return batch_dir + elif fallback_dir: + return fallback_dir + else: + return fallback_fallback_dir + + batch_dirs = [ + self.batch_image_dir, + ControlNetUiGroup.global_batch_input_dir, + ControlNetUiGroup.a1111_context.img2img_batch_input_dir, + ] + for batch_dir_comp in batch_dirs: + subscriber = getattr(batch_dir_comp, "blur", None) + if subscriber is None: + continue + subscriber( + fn=determine_batch_dir, + inputs=batch_dirs, + outputs=[self.batch_image_dir_state], + queue=False, + ) + + ControlNetUiGroup.a1111_context.img2img_batch_output_dir.blur( + fn=lambda a: a, + inputs=[ControlNetUiGroup.a1111_context.img2img_batch_output_dir], + outputs=[self.output_dir_state], + queue=False, + ) + + def register_clear_preview(self): + def clear_preview(x): + if x: + logger.info("Preview as input is cancelled.") + return gr.update(value=False), gr.update(value=None) + + for comp in ( + self.pixel_perfect, + self.module, + self.image, + self.processor_res, + self.threshold_a, + self.threshold_b, + self.upload_independent_img_in_img2img, + ): + event_subscribers = [] + if hasattr(comp, "edit"): + event_subscribers.append(comp.edit) + elif hasattr(comp, "click"): + event_subscribers.append(comp.click) + elif isinstance(comp, gr.Slider) and hasattr(comp, "release"): + event_subscribers.append(comp.release) + elif hasattr(comp, "change"): + event_subscribers.append(comp.change) + if hasattr(comp, "clear"): + event_subscribers.append(comp.clear) + for event_subscriber in event_subscribers: + event_subscriber( + fn=clear_preview, + inputs=self.use_preview_as_input, + outputs=[self.use_preview_as_input, self.generated_image], + ) + + def register_multi_images_upload(self): + """Register callbacks on merge tab multiple images upload.""" + self.merge_clear_button.click( + fn=lambda: [], + inputs=[], + outputs=[self.merge_gallery], + ).then( + fn=lambda x: gr.update(value=x + 1), + inputs=[self.update_unit_counter], + outputs=[self.update_unit_counter], + ) + + def upload_file(files, current_files): + return {file_d["name"] for file_d in current_files} | { + file.name for file in files + } + + self.merge_upload_button.upload( + upload_file, + inputs=[self.merge_upload_button, self.merge_gallery], + outputs=[self.merge_gallery], + queue=False, + ).then( + fn=lambda x: gr.update(value=x + 1), + inputs=[self.update_unit_counter], + outputs=[self.update_unit_counter], + ) + + def register_callbacks(self): + """Register callbacks on the UI elements.""" + # Prevent infinite recursion. + if self.callbacks_registered: + return + + self.callbacks_registered = True + self.register_send_dimensions() + self.register_webcam_toggle() + self.register_webcam_mirror_toggle() + self.register_refresh_all_models() + self.register_build_sliders() + self.register_run_annotator() + self.register_shift_preview() + self.register_shift_upload_mask() + self.register_create_canvas() + self.register_sync_batch_dir() + self.register_clear_preview() + self.register_multi_images_upload() + self.openpose_editor.register_callbacks( + self.generated_image, + self.use_preview_as_input, + self.model, + ) + assert self.type_filter is not None + self.preset_panel.register_callbacks( + self, + self.type_filter, + *[ + getattr(self, key) + for key in vars(external_code.ControlNetUnit()).keys() + ], + ) + if self.is_img2img: + self.register_img2img_same_input() + self.register_shift_crop_input_image() + else: + self.register_shift_hr_options() + + @staticmethod + def register_input_mode_sync(ui_groups: List["ControlNetUiGroup"]): + """ + - ui_group.input_mode should be updated when user switch tabs. + - Loopback checkbox should only be visible if at least one ControlNet unit + is set to batch mode. + + Argument: + ui_groups: All ControlNetUiGroup instances defined in current Script context. + + Returns: + None + """ + if not ui_groups: + return + + for ui_group in ui_groups: + batch_fn = lambda: InputMode.BATCH + simple_fn = lambda: InputMode.SIMPLE + merge_fn = lambda: InputMode.MERGE + for input_tab, fn in ( + (ui_group.upload_tab, simple_fn), + (ui_group.batch_tab, batch_fn), + (ui_group.merge_tab, merge_fn), + ): + # Sync input_mode. + input_tab.select( + fn=fn, + inputs=[], + outputs=[ui_group.input_mode], + show_progress=False, + ).then( + # Update visibility of loopback checkbox. + fn=lambda *mode_values: ( + ( + gr.update( + visible=any(m == InputMode.BATCH for m in mode_values) + ), + ) + * len(ui_groups) + ), + inputs=[g.input_mode for g in ui_groups], + outputs=[g.loopback for g in ui_groups], + show_progress=False, + ) + + @staticmethod + def reset(): + ControlNetUiGroup.a1111_context = A1111Context() + ControlNetUiGroup.all_ui_groups = [] + + @staticmethod + def try_register_all_callbacks(): + # All A1111 components ControlNet units care about are all registered. + if ControlNetUiGroup.a1111_context.ui_initialized and all( + not g.callbacks_registered for g in ControlNetUiGroup.all_ui_groups + ): + for ui_group in ControlNetUiGroup.all_ui_groups: + ui_group.register_callbacks() + + ControlNetUiGroup.register_input_mode_sync( + [g for g in ControlNetUiGroup.all_ui_groups if g.is_img2img] + ) + ControlNetUiGroup.register_input_mode_sync( + [g for g in ControlNetUiGroup.all_ui_groups if not g.is_img2img] + ) + logger.info("ControlNet UI callback registered.") + + @staticmethod + def on_after_component(component, **_kwargs): + """Register the A1111 component.""" + if getattr(component, "elem_id", None) == "img2img_batch_inpaint_mask_dir": + ControlNetUiGroup.global_batch_input_dir.render() + return + + ControlNetUiGroup.a1111_context.set_component(component) + ControlNetUiGroup.try_register_all_callbacks() diff --git a/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/modal.py b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/modal.py new file mode 100644 index 00000000..17ea4d67 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/modal.py @@ -0,0 +1,38 @@ +import gradio as gr +from typing import List + + +class ModalInterface(gr.Interface): + modal_id_counter = 0 + + def __init__( + self, + html_content: str, + open_button_text: str, + open_button_classes: List[str] = [], + open_button_extra_attrs: str = '' + ): + self.html_content = html_content + self.open_button_text = open_button_text + self.open_button_classes = open_button_classes + self.open_button_extra_attrs = open_button_extra_attrs + self.modal_id = ModalInterface.modal_id_counter + ModalInterface.modal_id_counter += 1 + + def __call__(self): + return self.create_modal() + + def create_modal(self, visible=True): + html_code = f""" +
    + × +
    + {self.html_content} +
    +
    +
    {self.open_button_text}
    + """ + return gr.HTML(value=html_code, visible=visible) diff --git a/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/openpose_editor.py b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/openpose_editor.py new file mode 100644 index 00000000..798d2834 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/openpose_editor.py @@ -0,0 +1,154 @@ +import base64 +import gradio as gr +import json +from typing import List, Dict, Any, Tuple + +from annotator.openpose import decode_json_as_poses, draw_poses +from annotator.openpose.animalpose import draw_animalposes +from scripts.controlnet_ui.modal import ModalInterface +from modules import shared +from scripts.logging import logger + + +def parse_data_url(data_url: str): + # Split the URL at the comma + media_type, data = data_url.split(",", 1) + + # Check if the data is base64-encoded + assert ";base64" in media_type + + # Decode the base64 data + return base64.b64decode(data) + + +def encode_data_url(json_string: str) -> str: + base64_encoded_json = base64.b64encode(json_string.encode("utf-8")).decode("utf-8") + return f"data:application/json;base64,{base64_encoded_json}" + + +class OpenposeEditor(object): + # Filename used when user click the download link. + download_file = "pose.json" + # URL the openpose editor is mounted on. + editor_url = "/openpose_editor_index" + + def __init__(self) -> None: + self.render_button = None + self.pose_input = None + self.download_link = None + self.upload_link = None + self.modal = None + + def render_edit(self): + """Renders the buttons in preview image control button group.""" + # The hidden button to trigger a re-render of generated image. + self.render_button = gr.Button(visible=False, elem_classes=["cnet-render-pose"]) + # The hidden element that stores the pose json for backend retrieval. + # The front-end javascript will write the edited JSON data to the element. + self.pose_input = gr.Textbox(visible=False, elem_classes=["cnet-pose-json"]) + + self.modal = ModalInterface( + # Use about:blank here as placeholder so that the iframe does not + # immediately navigate. Most of controlnet units do not need + # openpose editor active. Only navigate when the user first click + # 'Edit'. The navigation logic is in `openpose_editor.js`. + f'', + open_button_text="Edit", + open_button_classes=["cnet-edit-pose"], + open_button_extra_attrs=f'title="Send pose to {OpenposeEditor.editor_url} for edit."', + ).create_modal(visible=False) + self.download_link = gr.HTML( + value=f"""JSON""", + visible=False, + elem_classes=["cnet-download-pose"], + ) + + def render_upload(self): + """Renders the button in input image control button group.""" + self.upload_link = gr.HTML( + value=""" + + + """, + visible=False, + elem_classes=["cnet-upload-pose"], + ) + + def register_callbacks( + self, + generated_image: gr.Image, + use_preview_as_input: gr.Checkbox, + model: gr.Dropdown, + ): + def render_pose(pose_url: str) -> Tuple[Dict, Dict]: + json_string = parse_data_url(pose_url).decode("utf-8") + poses, animals, height, width = decode_json_as_poses( + json.loads(json_string) + ) + logger.info("Preview as input is enabled.") + return ( + # Generated image. + gr.update( + value=( + draw_poses( + poses, + height, + width, + draw_body=True, + draw_hand=True, + draw_face=True, + ) + if poses + else draw_animalposes(animals, height, width) + ), + visible=True, + ), + # Use preview as input. + gr.update(value=True), + # Self content. + *self.update(json_string), + ) + + self.render_button.click( + fn=render_pose, + inputs=[self.pose_input], + outputs=[generated_image, use_preview_as_input, *self.outputs()], + ) + + def update_upload_link(model: str) -> Dict: + return gr.update(visible="openpose" in model.lower()) + + model.change(fn=update_upload_link, inputs=[model], outputs=[self.upload_link]) + + def outputs(self) -> List[Any]: + return [ + self.download_link, + self.modal, + ] + + def update(self, json_string: str) -> List[Dict]: + """ + Called when there is a new JSON pose value generated by running + preprocessor. + + Args: + json_string: The new JSON string generated by preprocessor. + + Returns: + An gr.update event. + """ + hint = "Download the pose as .json file" + html = f""" + JSON""" + + visible = json_string != "" + return [ + # Download link update. + gr.update(value=html, visible=visible), + # Modal update. + gr.update( + visible=visible + and not shared.opts.data.get("controlnet_disable_openpose_edit", False) + ), + ] diff --git a/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/photopea.py b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/photopea.py new file mode 100644 index 00000000..9791dff5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/photopea.py @@ -0,0 +1,182 @@ +import gradio as gr + +from scripts.controlnet_ui.modal import ModalInterface + +PHOTOPEA_LOGO = """ + + + + + + + +""" + + +class Photopea(object): + def __init__(self) -> None: + self.modal = None + self.triggers = [] + self.render_editor() + + def render_editor(self): + """Render the editor modal.""" + with gr.Group(elem_classes=["cnet-photopea-edit"]): + self.modal = ModalInterface( + # Use about:blank here as placeholder so that the iframe does not + # immediately navigate. Only navigate when the user first click + # 'Edit'. The navigation logic is in `photopea.js`. + f""" +
    + + +
    + + """, + open_button_text="Edit", + open_button_classes=["cnet-photopea-main-trigger"], + open_button_extra_attrs="hidden", + ).create_modal(visible=True) + + def render_child_trigger(self): + self.triggers.append( + gr.HTML( + f"""
    + Edit {PHOTOPEA_LOGO} +
    """ + ) + ) + + def attach_photopea_output(self, generated_image: gr.Image): + """Called in ControlNetUiGroup to attach preprocessor preview image Gradio element + as the photopea output. If the front-end directly change the img HTML element's src + to reflect the edited image result from photopea, the backend won't be notified. + + In this method we let the front-end upload the result image an invisible gr.Image + instance and mirrors the value to preprocessor preview gr.Image. This is because + the generated image gr.Image instance is inferred to be an output image by Gradio + and has no ability to accept image upload directly. + + Arguments: + generated_image: preprocessor result Gradio Image output element. + + Returns: + None + """ + output = gr.Image( + visible=False, + source="upload", + type="numpy", + elem_classes=[f"cnet-photopea-output"], + ) + + output.upload( + fn=lambda img: img, + inputs=[output], + outputs=[generated_image], + ) diff --git a/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/preset.py b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/preset.py new file mode 100644 index 00000000..ba94dd68 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/preset.py @@ -0,0 +1,319 @@ +import os +import gradio as gr + +from typing import Dict, List + +from modules import scripts +from scripts.infotext import parse_unit, serialize_unit +from scripts.controlnet_ui.tool_button import ToolButton +from scripts.logging import logger +from scripts.processor import preprocessor_filters +from scripts import external_code + +save_symbol = "\U0001f4be" # 💾 +delete_symbol = "\U0001f5d1\ufe0f" # 🗑️ +refresh_symbol = "\U0001f504" # 🔄 +reset_symbol = "\U000021A9" # ↩ + +NEW_PRESET = "New Preset" + + +def load_presets(preset_dir: str) -> Dict[str, str]: + if not os.path.exists(preset_dir): + os.makedirs(preset_dir) + return {} + + presets = {} + for filename in os.listdir(preset_dir): + if filename.endswith(".txt"): + with open(os.path.join(preset_dir, filename), "r") as f: + name = filename.replace(".txt", "") + if name == NEW_PRESET: + continue + presets[name] = f.read() + return presets + + +def infer_control_type(module: str, model: str) -> str: + def matches_control_type(input_string: str, control_type: str) -> bool: + return any(t.lower() in input_string for t in control_type.split("/")) + + control_types = preprocessor_filters.keys() + control_type_candidates = [ + control_type + for control_type in control_types + if ( + matches_control_type(module, control_type) + or matches_control_type(model, control_type) + ) + ] + if len(control_type_candidates) != 1: + raise ValueError( + f"Unable to infer control type from module {module} and model {model}" + ) + return control_type_candidates[0] + + +class ControlNetPresetUI(object): + preset_directory = os.path.join(scripts.basedir(), "presets") + presets = load_presets(preset_directory) + + def __init__(self, id_prefix: str): + with gr.Row(): + self.dropdown = gr.Dropdown( + label="Presets", + show_label=True, + elem_classes=["cnet-preset-dropdown"], + choices=ControlNetPresetUI.dropdown_choices(), + value=NEW_PRESET, + ) + self.reset_button = ToolButton( + value=reset_symbol, + elem_classes=["cnet-preset-reset"], + tooltip="Reset preset", + visible=False, + ) + self.save_button = ToolButton( + value=save_symbol, + elem_classes=["cnet-preset-save"], + tooltip="Save preset", + ) + self.delete_button = ToolButton( + value=delete_symbol, + elem_classes=["cnet-preset-delete"], + tooltip="Delete preset", + ) + self.refresh_button = ToolButton( + value=refresh_symbol, + elem_classes=["cnet-preset-refresh"], + tooltip="Refresh preset", + ) + + with gr.Box( + elem_classes=["popup-dialog", "cnet-preset-enter-name"], + elem_id=f"{id_prefix}_cnet_preset_enter_name", + ) as self.name_dialog: + with gr.Row(): + self.preset_name = gr.Textbox( + label="Preset name", + show_label=True, + lines=1, + elem_classes=["cnet-preset-name"], + ) + self.confirm_preset_name = ToolButton( + value=save_symbol, + elem_classes=["cnet-preset-confirm-name"], + tooltip="Save preset", + ) + + def register_callbacks( + self, + uigroup, + control_type: gr.Radio, + *ui_states, + ): + def apply_preset(name: str, control_type: str, *ui_states): + if name == NEW_PRESET: + return ( + gr.update(visible=False), + *( + (gr.skip(),) + * (len(vars(external_code.ControlNetUnit()).keys()) + 1) + ), + ) + + assert name in ControlNetPresetUI.presets + + infotext = ControlNetPresetUI.presets[name] + preset_unit = parse_unit(infotext) + current_unit = external_code.ControlNetUnit(*ui_states) + preset_unit.image = None + current_unit.image = None + + # Do not compare module param that are not used in preset. + for module_param in ("processor_res", "threshold_a", "threshold_b"): + if getattr(preset_unit, module_param) == -1: + setattr(current_unit, module_param, -1) + + # No update necessary. + if vars(current_unit) == vars(preset_unit): + return ( + gr.update(visible=False), + *( + (gr.skip(),) + * (len(vars(external_code.ControlNetUnit()).keys()) + 1) + ), + ) + + unit = preset_unit + + try: + new_control_type = infer_control_type(unit.module, unit.model) + except ValueError as e: + logger.error(e) + new_control_type = control_type + + if new_control_type != control_type: + uigroup.prevent_next_n_module_update += 1 + + if preset_unit.module != current_unit.module: + uigroup.prevent_next_n_slider_value_update += 1 + + if preset_unit.pixel_perfect != current_unit.pixel_perfect: + uigroup.prevent_next_n_slider_value_update += 1 + + return ( + gr.update(visible=True), + gr.update(value=new_control_type), + *[ + gr.update(value=value) if value is not None else gr.update() + for value in vars(unit).values() + ], + ) + + for element, action in ( + (self.dropdown, "change"), + (self.reset_button, "click"), + ): + getattr(element, action)( + fn=apply_preset, + inputs=[self.dropdown, control_type, *ui_states], + outputs=[self.delete_button, control_type, *ui_states], + show_progress="hidden", + ).then( + fn=lambda: gr.update(visible=False), + inputs=None, + outputs=[self.reset_button], + ) + + def save_preset(name: str, *ui_states): + if name == NEW_PRESET: + return gr.update(visible=True), gr.update(), gr.update() + + ControlNetPresetUI.save_preset( + name, external_code.ControlNetUnit(*ui_states) + ) + return ( + gr.update(), # name dialog + gr.update(choices=ControlNetPresetUI.dropdown_choices(), value=name), + gr.update(visible=False), # Reset button + ) + + self.save_button.click( + fn=save_preset, + inputs=[self.dropdown, *ui_states], + outputs=[self.name_dialog, self.dropdown, self.reset_button], + show_progress="hidden", + ).then( + fn=None, + _js=f""" + (name) => {{ + if (name === "{NEW_PRESET}") + popup(gradioApp().getElementById('{self.name_dialog.elem_id}')); + }}""", + inputs=[self.dropdown], + ) + + def delete_preset(name: str): + ControlNetPresetUI.delete_preset(name) + return gr.Dropdown.update( + choices=ControlNetPresetUI.dropdown_choices(), + value=NEW_PRESET, + ), gr.update(visible=False) + + self.delete_button.click( + fn=delete_preset, + inputs=[self.dropdown], + outputs=[self.dropdown, self.reset_button], + show_progress="hidden", + ) + + self.name_dialog.visible = False + + def save_new_preset(new_name: str, *ui_states): + if new_name == NEW_PRESET: + logger.warn(f"Cannot save preset with reserved name '{NEW_PRESET}'") + return gr.update(visible=False), gr.update() + + ControlNetPresetUI.save_preset( + new_name, external_code.ControlNetUnit(*ui_states) + ) + return gr.update(visible=False), gr.update( + choices=ControlNetPresetUI.dropdown_choices(), value=new_name + ) + + self.confirm_preset_name.click( + fn=save_new_preset, + inputs=[self.preset_name, *ui_states], + outputs=[self.name_dialog, self.dropdown], + show_progress="hidden", + ).then(fn=None, _js="closePopup") + + self.refresh_button.click( + fn=ControlNetPresetUI.refresh_preset, + inputs=None, + outputs=[self.dropdown], + show_progress="hidden", + ) + + def update_reset_button(preset_name: str, *ui_states): + if preset_name == NEW_PRESET: + return gr.update(visible=False) + + infotext = ControlNetPresetUI.presets[preset_name] + preset_unit = parse_unit(infotext) + current_unit = external_code.ControlNetUnit(*ui_states) + preset_unit.image = None + current_unit.image = None + + # Do not compare module param that are not used in preset. + for module_param in ("processor_res", "threshold_a", "threshold_b"): + if getattr(preset_unit, module_param) == -1: + setattr(current_unit, module_param, -1) + + return gr.update(visible=vars(current_unit) != vars(preset_unit)) + + for ui_state in ui_states: + if isinstance(ui_state, gr.Image): + continue + + for action in ("edit", "click", "change", "clear", "release"): + if action == "release" and not isinstance(ui_state, gr.Slider): + continue + + if hasattr(ui_state, action): + getattr(ui_state, action)( + fn=update_reset_button, + inputs=[self.dropdown, *ui_states], + outputs=[self.reset_button], + ) + + @staticmethod + def dropdown_choices() -> List[str]: + return list(ControlNetPresetUI.presets.keys()) + [NEW_PRESET] + + @staticmethod + def save_preset(name: str, unit: external_code.ControlNetUnit): + infotext = serialize_unit(unit) + with open( + os.path.join(ControlNetPresetUI.preset_directory, f"{name}.txt"), "w" + ) as f: + f.write(infotext) + + ControlNetPresetUI.presets[name] = infotext + + @staticmethod + def delete_preset(name: str): + if name not in ControlNetPresetUI.presets: + return + + del ControlNetPresetUI.presets[name] + + file = os.path.join(ControlNetPresetUI.preset_directory, f"{name}.txt") + if os.path.exists(file): + os.unlink(file) + + @staticmethod + def refresh_preset(): + ControlNetPresetUI.presets = load_presets(ControlNetPresetUI.preset_directory) + return gr.update(choices=ControlNetPresetUI.dropdown_choices()) diff --git a/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/tool_button.py b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/tool_button.py new file mode 100644 index 00000000..8a38df8f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_ui/tool_button.py @@ -0,0 +1,12 @@ +import gradio as gr + +class ToolButton(gr.Button, gr.components.FormComponent): + """Small button with single emoji as text, fits inside gradio forms""" + + def __init__(self, **kwargs): + super().__init__(variant="tool", + elem_classes=kwargs.pop('elem_classes', []) + ["cnet-toolbutton"], + **kwargs) + + def get_block_name(self): + return "button" diff --git a/extensions-builtin/sd_forge_controlnet/scripts/controlnet_version.py b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_version.py new file mode 100644 index 00000000..6bc54042 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/controlnet_version.py @@ -0,0 +1,10 @@ +version_flag = 'v1.1.438' + +from scripts.logging import logger + +logger.info(f"ControlNet {version_flag}") +# A smart trick to know if user has updated as well as if user has restarted terminal. +# Note that in "controlnet.py" we do NOT use "importlib.reload" to reload this "controlnet_version.py" +# This means if user did not completely restart terminal, the "version_flag" will be the previous version. +# Then, if we get a screenshot from user, we will know that if that user has restarted the terminal. +# And we will also know what version the user is using so that bug track becomes easier. diff --git a/extensions-builtin/sd_forge_controlnet/scripts/enums.py b/extensions-builtin/sd_forge_controlnet/scripts/enums.py new file mode 100644 index 00000000..2ff8c99b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/enums.py @@ -0,0 +1,115 @@ +from enum import Enum +from typing import Any + + +class StableDiffusionVersion(Enum): + """The version family of stable diffusion model.""" + + UNKNOWN = 0 + SD1x = 1 + SD2x = 2 + SDXL = 3 + + @staticmethod + def detect_from_model_name(model_name: str) -> "StableDiffusionVersion": + """Based on the model name provided, guess what stable diffusion version it is. + This might not be accurate without actually inspect the file content. + """ + if any(f"sd{v}" in model_name.lower() for v in ("14", "15", "16")): + return StableDiffusionVersion.SD1x + + if "sd21" in model_name or "2.1" in model_name: + return StableDiffusionVersion.SD2x + + if "xl" in model_name.lower(): + return StableDiffusionVersion.SDXL + + return StableDiffusionVersion.UNKNOWN + + def encoder_block_num(self) -> int: + if self in (StableDiffusionVersion.SD1x, StableDiffusionVersion.SD2x, StableDiffusionVersion.UNKNOWN): + return 12 + else: + return 9 # SDXL + + def controlnet_layer_num(self) -> int: + return self.encoder_block_num() + 1 + + def is_compatible_with(self, other: "StableDiffusionVersion") -> bool: + """ Incompatible only when one of version is SDXL and other is not. """ + return ( + any(v == StableDiffusionVersion.UNKNOWN for v in [self, other]) or + sum(v == StableDiffusionVersion.SDXL for v in [self, other]) != 1 + ) + + +class ControlModelType(Enum): + """ + The type of Control Models (supported or not). + """ + + ControlNet = "ControlNet, Lvmin Zhang" + T2I_Adapter = "T2I_Adapter, Chong Mou" + T2I_StyleAdapter = "T2I_StyleAdapter, Chong Mou" + T2I_CoAdapter = "T2I_CoAdapter, Chong Mou" + MasaCtrl = "MasaCtrl, Mingdeng Cao" + GLIGEN = "GLIGEN, Yuheng Li" + AttentionInjection = "AttentionInjection, Lvmin Zhang" # A simple attention injection written by Lvmin + StableSR = "StableSR, Jianyi Wang" + PromptDiffusion = "PromptDiffusion, Zhendong Wang" + ControlLoRA = "ControlLoRA, Wu Hecong" + ReVision = "ReVision, Stability" + IPAdapter = "IPAdapter, Hu Ye" + Controlllite = "Controlllite, Kohya" + + def allow_context_sharing(self) -> bool: + """Returns whether this control model type allows the same PlugableControlModel + object map to multiple ControlNetUnit. + Both IPAdapter and Controlllite have unit specific input (clip/image) stored + on the model object during inference. Sharing the context means that the input + set earlier gets lost. + """ + return self not in ( + ControlModelType.IPAdapter, + ControlModelType.Controlllite, + ) + +# Written by Lvmin +class AutoMachine(Enum): + """ + Lvmin's algorithm for Attention/AdaIn AutoMachine States. + """ + + Read = "Read" + Write = "Write" + StyleAlign = "StyleAlign" + + +class HiResFixOption(Enum): + BOTH = "Both" + LOW_RES_ONLY = "Low res only" + HIGH_RES_ONLY = "High res only" + + @staticmethod + def from_value(value: Any) -> "HiResFixOption": + if isinstance(value, str) and value.startswith("HiResFixOption."): + _, field = value.split(".") + return getattr(HiResFixOption, field) + if isinstance(value, str): + return HiResFixOption(value) + elif isinstance(value, int): + return [x for x in HiResFixOption][value] + else: + assert isinstance(value, HiResFixOption) + return value + + +class InputMode(Enum): + # Single image to a single ControlNet unit. + SIMPLE = "simple" + # Input is a directory. N generations. Each generation takes 1 input image + # from the directory. + BATCH = "batch" + # Input is a directory. 1 generation. Each generation takes N input image + # from the directory. + MERGE = "merge" diff --git a/extensions-builtin/sd_forge_controlnet/scripts/external_code.py b/extensions-builtin/sd_forge_controlnet/scripts/external_code.py new file mode 100644 index 00000000..08cefb7a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/external_code.py @@ -0,0 +1 @@ +from internal_controlnet.external_code import * diff --git a/extensions-builtin/sd_forge_controlnet/scripts/global_state.py b/extensions-builtin/sd_forge_controlnet/scripts/global_state.py new file mode 100644 index 00000000..c2f47c58 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/global_state.py @@ -0,0 +1,355 @@ +import os.path +import stat +import functools +from collections import OrderedDict + +from modules import shared, scripts, sd_models +from modules.paths import models_path +from scripts.processor import * +import scripts.processor as processor +from scripts.utils import ndarray_lru_cache +from scripts.logging import logger +from scripts.enums import StableDiffusionVersion + +from typing import Dict, Callable, Optional, Tuple, List + +CN_MODEL_EXTS = [".pt", ".pth", ".ckpt", ".safetensors", ".bin"] +cn_models_dir = os.path.join(models_path, "ControlNet") +cn_models_dir_old = os.path.join(scripts.basedir(), "models") +cn_models = OrderedDict() # "My_Lora(abcd1234)" -> C:/path/to/model.safetensors +cn_models_names = {} # "my_lora" -> "My_Lora(abcd1234)" + +def cache_preprocessors(preprocessor_modules: Dict[str, Callable]) -> Dict[str, Callable]: + """ We want to share the preprocessor results in a single big cache, instead of a small + cache for each preprocessor function. """ + CACHE_SIZE = getattr(shared.cmd_opts, "controlnet_preprocessor_cache_size", 0) + + # Set CACHE_SIZE = 0 will completely remove the caching layer. This can be + # helpful when debugging preprocessor code. + if CACHE_SIZE == 0: + return preprocessor_modules + + logger.debug(f'Create LRU cache (max_size={CACHE_SIZE}) for preprocessor results.') + + @ndarray_lru_cache(max_size=CACHE_SIZE) + def unified_preprocessor(preprocessor_name: str, *args, **kwargs): + logger.debug(f'Calling preprocessor {preprocessor_name} outside of cache.') + return preprocessor_modules[preprocessor_name](*args, **kwargs) + + # TODO: Introduce a seed parameter for shuffle preprocessor? + uncacheable_preprocessors = ['shuffle'] + + return { + k: ( + v if k in uncacheable_preprocessors + else functools.partial(unified_preprocessor, k) + ) + for k, v + in preprocessor_modules.items() + } + +cn_preprocessor_modules = { + "none": lambda x, *args, **kwargs: (x, True), + "canny": canny, + "depth": midas, + "depth_leres": functools.partial(leres, boost=False), + "depth_leres++": functools.partial(leres, boost=True), + "depth_hand_refiner": g_hand_refiner_model.run_model, + "depth_anything": functools.partial(depth_anything, colored=False), + "hed": hed, + "hed_safe": hed_safe, + "mediapipe_face": mediapipe_face, + "mlsd": mlsd, + "normal_map": midas_normal, + "openpose": functools.partial(g_openpose_model.run_model, include_body=True, include_hand=False, include_face=False), + "openpose_hand": functools.partial(g_openpose_model.run_model, include_body=True, include_hand=True, include_face=False), + "openpose_face": functools.partial(g_openpose_model.run_model, include_body=True, include_hand=False, include_face=True), + "openpose_faceonly": functools.partial(g_openpose_model.run_model, include_body=False, include_hand=False, include_face=True), + "openpose_full": functools.partial(g_openpose_model.run_model, include_body=True, include_hand=True, include_face=True), + "dw_openpose_full": functools.partial(g_openpose_model.run_model, include_body=True, include_hand=True, include_face=True, use_dw_pose=True), + "animal_openpose": functools.partial(g_openpose_model.run_model, include_body=True, include_hand=False, include_face=False, use_animal_pose=True), + "clip_vision": functools.partial(clip, config='clip_vitl'), + "revision_clipvision": functools.partial(clip, config='clip_g'), + "revision_ignore_prompt": functools.partial(clip, config='clip_g'), + "ip-adapter_clip_sd15": functools.partial(clip, config='clip_h'), + "ip-adapter_clip_sdxl_plus_vith": functools.partial(clip, config='clip_h'), + "ip-adapter_clip_sdxl": functools.partial(clip, config='clip_g'), + "ip-adapter_face_id": g_insight_face_model.run_model, + "ip-adapter_face_id_plus": face_id_plus, + "color": color, + "pidinet": pidinet, + "pidinet_safe": pidinet_safe, + "pidinet_sketch": pidinet_ts, + "pidinet_scribble": scribble_pidinet, + "scribble_xdog": scribble_xdog, + "scribble_hed": scribble_hed, + "segmentation": uniformer, + "threshold": threshold, + "depth_zoe": zoe_depth, + "normal_bae": normal_bae, + "oneformer_coco": oneformer_coco, + "oneformer_ade20k": oneformer_ade20k, + "lineart": lineart, + "lineart_coarse": lineart_coarse, + "lineart_anime": lineart_anime, + "lineart_standard": lineart_standard, + "shuffle": shuffle, + "tile_resample": tile_resample, + "invert": invert, + "lineart_anime_denoise": lineart_anime_denoise, + "reference_only": identity, + "reference_adain": identity, + "reference_adain+attn": identity, + "inpaint": identity, + "inpaint_only": identity, + "inpaint_only+lama": lama_inpaint, + "tile_colorfix": identity, + "tile_colorfix+sharp": identity, + "recolor_luminance": recolor_luminance, + "recolor_intensity": recolor_intensity, + "blur_gaussian": blur_gaussian, + "anime_face_segment": anime_face_segment, + "densepose": functools.partial(densepose, cmap="viridis"), + "densepose_parula": functools.partial(densepose, cmap="parula"), + "te_hed":te_hed, +} + +cn_preprocessor_unloadable = { + "hed": unload_hed, + "fake_scribble": unload_hed, + "mlsd": unload_mlsd, + "clip_vision": functools.partial(unload_clip, config='clip_vitl'), + "revision_clipvision": functools.partial(unload_clip, config='clip_g'), + "revision_ignore_prompt": functools.partial(unload_clip, config='clip_g'), + "ip-adapter_clip_sd15": functools.partial(unload_clip, config='clip_h'), + "ip-adapter_clip_sdxl_plus_vith": functools.partial(unload_clip, config='clip_h'), + "ip-adapter_face_id_plus": functools.partial(unload_clip, config='clip_h'), + "ip-adapter_clip_sdxl": functools.partial(unload_clip, config='clip_g'), + "depth": unload_midas, + "depth_leres": unload_leres, + "depth_anything": unload_depth_anything, + "normal_map": unload_midas, + "pidinet": unload_pidinet, + "openpose": g_openpose_model.unload, + "openpose_hand": g_openpose_model.unload, + "openpose_face": g_openpose_model.unload, + "openpose_full": g_openpose_model.unload, + "dw_openpose_full": g_openpose_model.unload, + "animal_openpose": g_openpose_model.unload, + "segmentation": unload_uniformer, + "depth_zoe": unload_zoe_depth, + "normal_bae": unload_normal_bae, + "oneformer_coco": unload_oneformer_coco, + "oneformer_ade20k": unload_oneformer_ade20k, + "lineart": unload_lineart, + "lineart_coarse": unload_lineart_coarse, + "lineart_anime": unload_lineart_anime, + "lineart_anime_denoise": unload_lineart_anime_denoise, + "inpaint_only+lama": unload_lama_inpaint, + "anime_face_segment": unload_anime_face_segment, + "densepose": unload_densepose, + "densepose_parula": unload_densepose, + "depth_hand_refiner": g_hand_refiner_model.unload, + "te_hed":unload_te_hed, +} + +preprocessor_aliases = { + "invert": "invert (from white bg & black line)", + "lineart_standard": "lineart_standard (from white bg & black line)", + "lineart": "lineart_realistic", + "color": "t2ia_color_grid", + "clip_vision": "t2ia_style_clipvision", + "pidinet_sketch": "t2ia_sketch_pidi", + "depth": "depth_midas", + "normal_map": "normal_midas", + "hed": "softedge_hed", + "hed_safe": "softedge_hedsafe", + "pidinet": "softedge_pidinet", + "pidinet_safe": "softedge_pidisafe", + "segmentation": "seg_ufade20k", + "oneformer_coco": "seg_ofcoco", + "oneformer_ade20k": "seg_ofade20k", + "pidinet_scribble": "scribble_pidinet", + "inpaint": "inpaint_global_harmonious", + "anime_face_segment": "seg_anime_face", + "densepose": "densepose (pruple bg & purple torso)", + "densepose_parula": "densepose_parula (black bg & blue torso)", + "te_hed": "softedge_teed", +} + +ui_preprocessor_keys = ['none', preprocessor_aliases['invert']] +ui_preprocessor_keys += sorted([preprocessor_aliases.get(k, k) + for k in cn_preprocessor_modules.keys() + if preprocessor_aliases.get(k, k) not in ui_preprocessor_keys]) + +reverse_preprocessor_aliases = {preprocessor_aliases[k]: k for k in preprocessor_aliases.keys()} + + +def get_module_basename(module: Optional[str]) -> str: + if module is None: + module = 'none' + return reverse_preprocessor_aliases.get(module, module) + + +default_detectedmap_dir = os.path.join("detected_maps") +script_dir = scripts.basedir() + +os.makedirs(cn_models_dir, exist_ok=True) + + +def traverse_all_files(curr_path, model_list): + f_list = [ + (os.path.join(curr_path, entry.name), entry.stat()) + for entry in os.scandir(curr_path) + if os.path.isdir(curr_path) + ] + for f_info in f_list: + fname, fstat = f_info + if os.path.splitext(fname)[1] in CN_MODEL_EXTS: + model_list.append(f_info) + elif stat.S_ISDIR(fstat.st_mode): + model_list = traverse_all_files(fname, model_list) + return model_list + + +def get_all_models(sort_by, filter_by, path): + res = OrderedDict() + fileinfos = traverse_all_files(path, []) + filter_by = filter_by.strip(" ") + if len(filter_by) != 0: + fileinfos = [x for x in fileinfos if filter_by.lower() + in os.path.basename(x[0]).lower()] + if sort_by == "name": + fileinfos = sorted(fileinfos, key=lambda x: os.path.basename(x[0])) + elif sort_by == "date": + fileinfos = sorted(fileinfos, key=lambda x: -x[1].st_mtime) + elif sort_by == "path name": + fileinfos = sorted(fileinfos) + + for finfo in fileinfos: + filename = finfo[0] + name = os.path.splitext(os.path.basename(filename))[0] + # Prevent a hypothetical "None.pt" from being listed. + if name != "None": + res[name + f" [{sd_models.model_hash(filename)}]"] = filename + + return res + + +def update_cn_models(): + cn_models.clear() + ext_dirs = (shared.opts.data.get("control_net_models_path", None), getattr(shared.cmd_opts, 'controlnet_dir', None)) + extra_lora_paths = (extra_lora_path for extra_lora_path in ext_dirs + if extra_lora_path is not None and os.path.exists(extra_lora_path)) + paths = [cn_models_dir, cn_models_dir_old, *extra_lora_paths] + + for path in paths: + sort_by = shared.opts.data.get( + "control_net_models_sort_models_by", "name") + filter_by = shared.opts.data.get("control_net_models_name_filter", "") + found = get_all_models(sort_by, filter_by, path) + cn_models.update({**found, **cn_models}) + + # insert "None" at the beginning of `cn_models` in-place + cn_models_copy = OrderedDict(cn_models) + cn_models.clear() + cn_models.update({**{"None": None}, **cn_models_copy}) + + cn_models_names.clear() + for name_and_hash, filename in cn_models.items(): + if filename is None: + continue + name = os.path.splitext(os.path.basename(filename))[0].lower() + cn_models_names[name] = name_and_hash + + +def get_sd_version() -> StableDiffusionVersion: + if shared.sd_model.is_sdxl: + return StableDiffusionVersion.SDXL + elif shared.sd_model.is_sd2: + return StableDiffusionVersion.SD2x + elif shared.sd_model.is_sd1: + return StableDiffusionVersion.SD1x + else: + return StableDiffusionVersion.UNKNOWN + + +def select_control_type( + control_type: str, + sd_version: StableDiffusionVersion = StableDiffusionVersion.UNKNOWN, + cn_models: Dict = cn_models, # Override or testing +) -> Tuple[List[str], List[str], str, str]: + default_option = processor.preprocessor_filters[control_type] + pattern = control_type.lower() + preprocessor_list = ui_preprocessor_keys + all_models = list(cn_models.keys()) + + if pattern == "all": + return [ + preprocessor_list, + all_models, + 'none', #default option + "None" #default model + ] + filtered_preprocessor_list = [ + x + for x in preprocessor_list + if (( + pattern in x.lower() or + any(a in x.lower() for a in processor.preprocessor_filters_aliases.get(pattern, [])) or + x.lower() == "none" + ) and ( + sd_version.is_compatible_with(StableDiffusionVersion.detect_from_model_name(x)) + )) + ] + if pattern in ["canny", "lineart", "scribble/sketch", "mlsd"]: + filtered_preprocessor_list += [ + x for x in preprocessor_list if "invert" in x.lower() + ] + filtered_model_list = [ + model for model in all_models + if model.lower() == "none" or + (( + pattern in model.lower() or + any(a in model.lower() for a in processor.preprocessor_filters_aliases.get(pattern, [])) + ) and ( + sd_version.is_compatible_with(StableDiffusionVersion.detect_from_model_name(model)) + )) + ] + assert len(filtered_model_list) > 0, "'None' model should always be available." + if default_option not in filtered_preprocessor_list: + default_option = filtered_preprocessor_list[0] + if len(filtered_model_list) == 1: + default_model = "None" + else: + default_model = filtered_model_list[1] + for x in filtered_model_list: + if "11" in x.split("[")[0]: + default_model = x + break + + return ( + filtered_preprocessor_list, + filtered_model_list, + default_option, + default_model + ) + + +ip_adapter_pairing_model = { + "ip-adapter_clip_sdxl": lambda model: "faceid" not in model and "vit" not in model, + "ip-adapter_clip_sdxl_plus_vith": lambda model: "faceid" not in model and "vit" in model, + "ip-adapter_clip_sd15": lambda model: "faceid" not in model, + "ip-adapter_face_id": lambda model: "faceid" in model and "plus" not in model, + "ip-adapter_face_id_plus": lambda model: "faceid" in model and "plus" in model, +} + +ip_adapter_pairing_logic_text = """ +{ + "ip-adapter_clip_sdxl": lambda model: "faceid" not in model and "vit" not in model, + "ip-adapter_clip_sdxl_plus_vith": lambda model: "faceid" not in model and "vit" in model, + "ip-adapter_clip_sd15": lambda model: "faceid" not in model, + "ip-adapter_face_id": lambda model: "faceid" in model and "plus" not in model, + "ip-adapter_face_id_plus": lambda model: "faceid" in model and "plus" in model, +} +""" diff --git a/extensions-builtin/sd_forge_controlnet/scripts/hook.py b/extensions-builtin/sd_forge_controlnet/scripts/hook.py new file mode 100644 index 00000000..ae4a599e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/hook.py @@ -0,0 +1,1014 @@ +import torch +import hashlib +import numpy as np +import torch.nn as nn +from functools import partial + + +from scripts.logging import logger +from scripts.enums import ControlModelType, AutoMachine, HiResFixOption +from modules import devices, lowvram, shared, scripts + +cond_cast_unet = getattr(devices, 'cond_cast_unet', lambda x: x) + +from ldm.modules.diffusionmodules.util import timestep_embedding, make_beta_schedule +from ldm.modules.diffusionmodules.openaimodel import UNetModel +from ldm.modules.attention import BasicTransformerBlock +from ldm.models.diffusion.ddpm import extract_into_tensor + +from modules.prompt_parser import MulticondLearnedConditioning, ComposableScheduledPromptConditioning, ScheduledPromptConditioning +from modules.processing import StableDiffusionProcessing + + +try: + from sgm.modules.attention import BasicTransformerBlock as BasicTransformerBlockSGM +except: + print('Warning: ControlNet failed to load SGM - will use LDM instead.') + BasicTransformerBlockSGM = BasicTransformerBlock + + +POSITIVE_MARK_TOKEN = 1024 +NEGATIVE_MARK_TOKEN = - POSITIVE_MARK_TOKEN +MARK_EPS = 1e-3 + + +def prompt_context_is_marked(x): + t = x[..., 0, :] + m = torch.abs(t) - POSITIVE_MARK_TOKEN + m = torch.mean(torch.abs(m)).detach().cpu().float().numpy() + return float(m) < MARK_EPS + + +def mark_prompt_context(x, positive): + if isinstance(x, list): + for i in range(len(x)): + x[i] = mark_prompt_context(x[i], positive) + return x + if isinstance(x, MulticondLearnedConditioning): + x.batch = mark_prompt_context(x.batch, positive) + return x + if isinstance(x, ComposableScheduledPromptConditioning): + x.schedules = mark_prompt_context(x.schedules, positive) + return x + if isinstance(x, ScheduledPromptConditioning): + if isinstance(x.cond, dict): + cond = x.cond['crossattn'] + if prompt_context_is_marked(cond): + return x + mark = POSITIVE_MARK_TOKEN if positive else NEGATIVE_MARK_TOKEN + cond = torch.cat([torch.zeros_like(cond)[:1] + mark, cond], dim=0) + return ScheduledPromptConditioning(end_at_step=x.end_at_step, cond=dict(crossattn=cond, vector=x.cond['vector'])) + else: + cond = x.cond + if prompt_context_is_marked(cond): + return x + mark = POSITIVE_MARK_TOKEN if positive else NEGATIVE_MARK_TOKEN + cond = torch.cat([torch.zeros_like(cond)[:1] + mark, cond], dim=0) + return ScheduledPromptConditioning(end_at_step=x.end_at_step, cond=cond) + return x + + +disable_controlnet_prompt_warning = True +# You can disable this warning using disable_controlnet_prompt_warning. + + +def unmark_prompt_context(x): + if not prompt_context_is_marked(x): + # ControlNet must know whether a prompt is conditional prompt (positive prompt) or unconditional conditioning prompt (negative prompt). + # You can use the hook.py's `mark_prompt_context` to mark the prompts that will be seen by ControlNet. + # Let us say XXX is a MulticondLearnedConditioning or a ComposableScheduledPromptConditioning or a ScheduledPromptConditioning or a list of these components, + # if XXX is a positive prompt, you should call mark_prompt_context(XXX, positive=True) + # if XXX is a negative prompt, you should call mark_prompt_context(XXX, positive=False) + # After you mark the prompts, the ControlNet will know which prompt is cond/uncond and works as expected. + # After you mark the prompts, the mismatch errors will disappear. + if not disable_controlnet_prompt_warning: + logger.warning('ControlNet Error: Failed to detect whether an instance is cond or uncond!') + logger.warning('ControlNet Error: This is mainly because other extension(s) blocked A1111\'s \"process.sample()\" and deleted ControlNet\'s sample function.') + logger.warning('ControlNet Error: ControlNet will shift to a backup backend but the results will be worse than expectation.') + logger.warning('Solution (For extension developers): Take a look at ControlNet\' hook.py ' + 'UnetHook.hook.process_sample and manually call mark_prompt_context to mark cond/uncond prompts.') + mark_batch = torch.ones(size=(x.shape[0], 1, 1, 1), dtype=x.dtype, device=x.device) + context = x + return mark_batch, [], [], context + mark = x[:, 0, :] + context = x[:, 1:, :] + mark = torch.mean(torch.abs(mark - NEGATIVE_MARK_TOKEN), dim=1) + mark = (mark > MARK_EPS).float() + mark_batch = mark[:, None, None, None].to(x.dtype).to(x.device) + + mark = mark.detach().cpu().numpy().tolist() + uc_indices = [i for i, item in enumerate(mark) if item < 0.5] + c_indices = [i for i, item in enumerate(mark) if not item < 0.5] + + StableDiffusionProcessing.cached_c = [None, None] + StableDiffusionProcessing.cached_uc = [None, None] + + return mark_batch, uc_indices, c_indices, context + + +class HackedImageRNG: + def __init__(self, rng, noise_modifier, sd_model): + self.rng = rng + self.noise_modifier = noise_modifier + self.sd_model = sd_model + + def next(self): + result = self.rng.next() + x0 = self.noise_modifier + if result.shape[2] != x0.shape[2] or result.shape[3] != x0.shape[3]: + return result + x0 = x0.to(result.dtype).to(result.device) + ts = torch.tensor([999] * result.shape[0]).long().to(result.device) + result = predict_q_sample(self.sd_model, x0, ts, result) + logger.info(f'[ControlNet] Initial noise hack applied to {result.shape}.') + return result + + +class TorchHijackForUnet: + """ + This is torch, but with cat that resizes tensors to appropriate dimensions if they do not match; + this makes it possible to create pictures with dimensions that are multiples of 8 rather than 64 + """ + + def __getattr__(self, item): + if item == 'cat': + return self.cat + + if hasattr(torch, item): + return getattr(torch, item) + + raise AttributeError("'{}' object has no attribute '{}'".format(type(self).__name__, item)) + + def cat(self, tensors, *args, **kwargs): + if len(tensors) == 2: + a, b = tensors + if a.shape[-2:] != b.shape[-2:]: + a = torch.nn.functional.interpolate(a, b.shape[-2:], mode="nearest") + + tensors = (a, b) + + return torch.cat(tensors, *args, **kwargs) + + +th = TorchHijackForUnet() + + +class ControlParams: + def __init__( + self, + control_model, + preprocessor, + hint_cond, + weight, + guidance_stopped, + start_guidance_percent, + stop_guidance_percent, + advanced_weighting, + control_model_type, + hr_hint_cond, + global_average_pooling, + soft_injection, + cfg_injection, + hr_option: HiResFixOption = HiResFixOption.BOTH, + **kwargs # To avoid errors + ): + self.control_model = control_model + self.preprocessor = preprocessor + self._hint_cond = hint_cond + self.weight = weight + self.guidance_stopped = guidance_stopped + self.start_guidance_percent = start_guidance_percent + self.stop_guidance_percent = stop_guidance_percent + self.advanced_weighting = advanced_weighting + self.control_model_type = control_model_type + self.global_average_pooling = global_average_pooling + self.hr_hint_cond = hr_hint_cond + self.hr_option = hr_option + self.used_hint_cond = None + self.used_hint_cond_latent = None + self.used_hint_inpaint_hijack = None + self.soft_injection = soft_injection + self.cfg_injection = cfg_injection + self.vision_hint_count = None + + @property + def hint_cond(self): + return self._hint_cond + + # fix for all the extensions that modify hint_cond, + # by forcing used_hint_cond to update on the next timestep + # hr_hint_cond can stay the same, since most extensions dont modify the hires pass + # but if they do, it will cause problems + @hint_cond.setter + def hint_cond(self, new_hint_cond): + self._hint_cond = new_hint_cond + self.used_hint_cond = None + self.used_hint_cond_latent = None + self.used_hint_inpaint_hijack = None + + def disabled_by_hr_option(self, is_in_high_res_fix: bool) -> bool: + if self.hr_option == HiResFixOption.BOTH: + control_disabled = False + elif self.hr_option == HiResFixOption.LOW_RES_ONLY: + control_disabled = is_in_high_res_fix + elif self.hr_option == HiResFixOption.HIGH_RES_ONLY: + control_disabled = not is_in_high_res_fix + else: + assert False, "NOTREACHED" + return control_disabled + + +def aligned_adding(base, x, require_channel_alignment): + if isinstance(x, float): + if x == 0.0: + return base + return base + x + + if require_channel_alignment: + zeros = torch.zeros_like(base) + zeros[:, :x.shape[1], ...] = x + x = zeros + + # resize to sample resolution + base_h, base_w = base.shape[-2:] + xh, xw = x.shape[-2:] + + if xh > 1 or xw > 1: + if base_h != xh or base_w != xw: + # logger.info('[Warning] ControlNet finds unexpected mis-alignment in tensor shape.') + x = th.nn.functional.interpolate(x, size=(base_h, base_w), mode="nearest") + + return base + x + + +# DFS Search for Torch.nn.Module, Written by Lvmin +def torch_dfs(model: torch.nn.Module): + result = [model] + for child in model.children(): + result += torch_dfs(child) + return result + + +class AbstractLowScaleModel(nn.Module): + def __init__(self): + super(AbstractLowScaleModel, self).__init__() + self.register_schedule() + + def register_schedule(self, beta_schedule="linear", timesteps=1000, + linear_start=1e-4, linear_end=2e-2, cosine_s=8e-3): + betas = make_beta_schedule(beta_schedule, timesteps, linear_start=linear_start, linear_end=linear_end, + cosine_s=cosine_s) + alphas = 1. - betas + alphas_cumprod = np.cumprod(alphas, axis=0) + alphas_cumprod_prev = np.append(1., alphas_cumprod[:-1]) + + timesteps, = betas.shape + self.num_timesteps = int(timesteps) + self.linear_start = linear_start + self.linear_end = linear_end + assert alphas_cumprod.shape[0] == self.num_timesteps, 'alphas have to be defined for each timestep' + + to_torch = partial(torch.tensor, dtype=torch.float32) + + self.register_buffer('betas', to_torch(betas)) + self.register_buffer('alphas_cumprod', to_torch(alphas_cumprod)) + self.register_buffer('alphas_cumprod_prev', to_torch(alphas_cumprod_prev)) + + # calculations for diffusion q(x_t | x_{t-1}) and others + self.register_buffer('sqrt_alphas_cumprod', to_torch(np.sqrt(alphas_cumprod))) + self.register_buffer('sqrt_one_minus_alphas_cumprod', to_torch(np.sqrt(1. - alphas_cumprod))) + self.register_buffer('log_one_minus_alphas_cumprod', to_torch(np.log(1. - alphas_cumprod))) + self.register_buffer('sqrt_recip_alphas_cumprod', to_torch(np.sqrt(1. / alphas_cumprod))) + self.register_buffer('sqrt_recipm1_alphas_cumprod', to_torch(np.sqrt(1. / alphas_cumprod - 1))) + + def q_sample(self, x_start, t, noise=None): + if noise is None: + noise = torch.randn_like(x_start) + return (extract_into_tensor(self.sqrt_alphas_cumprod.to(x_start), t, x_start.shape) * x_start + + extract_into_tensor(self.sqrt_one_minus_alphas_cumprod.to(x_start), t, x_start.shape) * noise) + + +def register_schedule(self): + linear_start = 0.00085 + linear_end = 0.0120 + num_timesteps = 1000 + + betas = (torch.linspace(linear_start ** 0.5, linear_end ** 0.5, num_timesteps, dtype=torch.float64) ** 2.0).numpy() + + alphas = 1. - betas + alphas_cumprod = np.cumprod(alphas, axis=0) + alphas_cumprod_prev = np.append(1., alphas_cumprod[:-1]) + + to_torch = partial(torch.tensor, dtype=torch.float32) + + setattr(self, 'betas', to_torch(betas)) + # setattr(self, 'alphas_cumprod', to_torch(alphas_cumprod)) # a1111 already has this + setattr(self, 'alphas_cumprod_prev', to_torch(alphas_cumprod_prev)) + setattr(self, 'sqrt_alphas_cumprod', to_torch(np.sqrt(alphas_cumprod))) + setattr(self, 'sqrt_one_minus_alphas_cumprod', to_torch(np.sqrt(1. - alphas_cumprod))) + setattr(self, 'log_one_minus_alphas_cumprod', to_torch(np.log(1. - alphas_cumprod))) + setattr(self, 'sqrt_recip_alphas_cumprod', to_torch(np.sqrt(1. / alphas_cumprod))) + setattr(self, 'sqrt_recipm1_alphas_cumprod', to_torch(np.sqrt(1. / alphas_cumprod - 1))) + + +def predict_q_sample(ldm, x_start, t, noise=None): + if noise is None: + noise = torch.randn_like(x_start) + return extract_into_tensor(ldm.sqrt_alphas_cumprod.to(x_start), t, x_start.shape) * x_start + extract_into_tensor(ldm.sqrt_one_minus_alphas_cumprod.to(x_start), t, x_start.shape) * noise + + +def predict_start_from_noise(ldm, x_t, t, noise): + return extract_into_tensor(ldm.sqrt_recip_alphas_cumprod.to(x_t), t, x_t.shape) * x_t - extract_into_tensor(ldm.sqrt_recipm1_alphas_cumprod.to(x_t), t, x_t.shape) * noise + + +def predict_noise_from_start(ldm, x_t, t, x0): + return (extract_into_tensor(ldm.sqrt_recip_alphas_cumprod.to(x_t), t, x_t.shape) * x_t - x0) / extract_into_tensor(ldm.sqrt_recipm1_alphas_cumprod.to(x_t), t, x_t.shape) + + +def blur(x, k): + y = torch.nn.functional.pad(x, (k, k, k, k), mode='replicate') + y = torch.nn.functional.avg_pool2d(y, (k*2+1, k*2+1), stride=(1, 1)) + return y + + +class TorchCache: + def __init__(self): + self.cache = {} + + def hash(self, key): + v = key.detach().cpu().numpy().astype(np.float32) + v = (v * 1000.0).astype(np.int32) + v = np.ascontiguousarray(v.copy()) + sha = hashlib.sha1(v).hexdigest() + return sha + + def get(self, key): + key = self.hash(key) + return self.cache.get(key, None) + + def set(self, key, value): + self.cache[self.hash(key)] = value + + +class UnetHook(nn.Module): + def __init__(self, lowvram=False) -> None: + super().__init__() + self.lowvram = lowvram + self.model = None + self.sd_ldm = None + self.control_params = None + self.attention_auto_machine = AutoMachine.Read + self.attention_auto_machine_weight = 1.0 + self.gn_auto_machine = AutoMachine.Read + self.gn_auto_machine_weight = 1.0 + self.current_style_fidelity = 0.0 + self.current_uc_indices = [] + self.current_c_indices = [] + self.is_in_high_res_fix = False + + @staticmethod + def call_vae_using_process(p, x, batch_size=None, mask=None): + vae_cache = getattr(p, 'controlnet_vae_cache', None) + if vae_cache is None: + vae_cache = TorchCache() + setattr(p, 'controlnet_vae_cache', vae_cache) + try: + if x.shape[1] > 3: + x = x[:, 0:3, :, :] + x = x * 2.0 - 1.0 + if mask is not None: + x = x * (1.0 - mask) + x = x.type(devices.dtype_vae) + vae_output = vae_cache.get(x) + if vae_output is None: + with devices.autocast(): + vae_output = p.sd_model.encode_first_stage(x) + vae_output = p.sd_model.get_first_stage_encoding(vae_output) + if torch.all(torch.isnan(vae_output)).item(): + logger.info(f'ControlNet find Nans in the VAE encoding. \n ' + f'Now ControlNet will automatically retry.\n ' + f'To always start with 32-bit VAE, use --no-half-vae commandline flag.') + devices.dtype_vae = torch.float32 + x = x.to(devices.dtype_vae) + p.sd_model.first_stage_model.to(devices.dtype_vae) + vae_output = p.sd_model.encode_first_stage(x) + vae_output = p.sd_model.get_first_stage_encoding(vae_output) + vae_cache.set(x, vae_output) + logger.info(f'ControlNet used {str(devices.dtype_vae)} VAE to encode {vae_output.shape}.') + latent = vae_output + if batch_size is not None and latent.shape[0] != batch_size: + latent = torch.cat([latent.clone() for _ in range(batch_size)], dim=0) + latent = latent.type(devices.dtype_unet) + return latent + except Exception as e: + logger.error(e) + raise ValueError('ControlNet failed to use VAE. Please try to add `--no-half-vae`, `--no-half` and remove `--precision full` in launch cmd.') + + def guidance_schedule_handler(self, x): + for param in self.control_params: + current_sampling_percent = (x.sampling_step / x.total_sampling_steps) + param.guidance_stopped = current_sampling_percent < param.start_guidance_percent or current_sampling_percent > param.stop_guidance_percent + if self.model is not None: + self.model.current_sampling_percent = current_sampling_percent + + def hook(self, model, sd_ldm, control_params, process, batch_option_uint_separate=False, batch_option_style_align=False): + self.model = model + self.sd_ldm = sd_ldm + self.control_params = control_params + + model_is_sdxl = getattr(self.sd_ldm, 'is_sdxl', False) + + outer = self + + def process_sample(*args, **kwargs): + # ControlNet must know whether a prompt is conditional prompt (positive prompt) or unconditional conditioning prompt (negative prompt). + # You can use the hook.py's `mark_prompt_context` to mark the prompts that will be seen by ControlNet. + # Let us say XXX is a MulticondLearnedConditioning or a ComposableScheduledPromptConditioning or a ScheduledPromptConditioning or a list of these components, + # if XXX is a positive prompt, you should call mark_prompt_context(XXX, positive=True) + # if XXX is a negative prompt, you should call mark_prompt_context(XXX, positive=False) + # After you mark the prompts, the ControlNet will know which prompt is cond/uncond and works as expected. + # After you mark the prompts, the mismatch errors will disappear. + mark_prompt_context(kwargs.get('conditioning', []), positive=True) + mark_prompt_context(kwargs.get('unconditional_conditioning', []), positive=False) + mark_prompt_context(getattr(process, 'hr_c', []), positive=True) + mark_prompt_context(getattr(process, 'hr_uc', []), positive=False) + return process.sample_before_CN_hack(*args, **kwargs) + + def forward(self, x, timesteps=None, context=None, y=None, **kwargs): + is_sdxl = y is not None and model_is_sdxl + total_t2i_adapter_embedding = [0.0] * 4 + if is_sdxl: + total_controlnet_embedding = [0.0] * 10 + else: + total_controlnet_embedding = [0.0] * 13 + require_inpaint_hijack = False + is_in_high_res_fix = False + batch_size = int(x.shape[0]) + + # Handle cond-uncond marker + cond_mark, outer.current_uc_indices, outer.current_c_indices, context = unmark_prompt_context(context) + outer.model.cond_mark = cond_mark + # logger.info(str(cond_mark[:, 0, 0, 0].detach().cpu().numpy().tolist()) + ' - ' + str(outer.current_uc_indices)) + + # Revision + if is_sdxl: + revision_y1280 = 0 + + for param in outer.control_params: + if param.guidance_stopped: + continue + if param.control_model_type == ControlModelType.ReVision: + if param.vision_hint_count is None: + k = torch.Tensor([int(param.preprocessor['threshold_a'] * 1000)]).to(param.hint_cond).long().clip(0, 999) + param.vision_hint_count = outer.revision_q_sampler.q_sample(param.hint_cond, k) + revision_emb = param.vision_hint_count + if isinstance(revision_emb, torch.Tensor): + revision_y1280 += revision_emb * param.weight + + if isinstance(revision_y1280, torch.Tensor): + y[:, :1280] = revision_y1280 * cond_mark[:, :, 0, 0] + if any('ignore_prompt' in param.preprocessor['name'] for param in outer.control_params) \ + or (getattr(process, 'prompt', '') == '' and getattr(process, 'negative_prompt', '') == ''): + context = torch.zeros_like(context) + + # High-res fix + for param in outer.control_params: + # select which hint_cond to use + if param.used_hint_cond is None: + param.used_hint_cond = param.hint_cond + param.used_hint_cond_latent = None + param.used_hint_inpaint_hijack = None + + # has high-res fix + if isinstance(param.hr_hint_cond, torch.Tensor) and x.ndim == 4 and param.hint_cond.ndim == 4 and param.hr_hint_cond.ndim == 4: + _, _, h_lr, w_lr = param.hint_cond.shape + _, _, h_hr, w_hr = param.hr_hint_cond.shape + _, _, h, w = x.shape + h, w = h * 8, w * 8 + if abs(h - h_lr) < abs(h - h_hr): + is_in_high_res_fix = False + if param.used_hint_cond is not param.hint_cond: + param.used_hint_cond = param.hint_cond + param.used_hint_cond_latent = None + param.used_hint_inpaint_hijack = None + else: + is_in_high_res_fix = True + if param.used_hint_cond is not param.hr_hint_cond: + param.used_hint_cond = param.hr_hint_cond + param.used_hint_cond_latent = None + param.used_hint_inpaint_hijack = None + + self.is_in_high_res_fix = is_in_high_res_fix + outer.is_in_high_res_fix = is_in_high_res_fix + + # Convert control image to latent + for param in outer.control_params: + if param.used_hint_cond_latent is not None: + continue + if param.control_model_type not in [ControlModelType.AttentionInjection] \ + and 'colorfix' not in param.preprocessor['name'] \ + and 'inpaint_only' not in param.preprocessor['name']: + continue + param.used_hint_cond_latent = outer.call_vae_using_process(process, param.used_hint_cond, batch_size=batch_size) + + # vram + for param in outer.control_params: + if getattr(param.control_model, 'disable_memory_management', False): + continue + + if param.control_model is not None: + if outer.lowvram and is_sdxl and hasattr(param.control_model, 'aggressive_lowvram'): + param.control_model.aggressive_lowvram() + elif hasattr(param.control_model, 'fullvram'): + param.control_model.fullvram() + elif hasattr(param.control_model, 'to'): + param.control_model.to(devices.get_device_for("controlnet")) + + # handle prompt token control + for param in outer.control_params: + if param.guidance_stopped or param.disabled_by_hr_option(self.is_in_high_res_fix): + continue + + if param.control_model_type not in [ControlModelType.T2I_StyleAdapter]: + continue + + control = param.control_model(x=x, hint=param.used_hint_cond, timesteps=timesteps, context=context) + control = torch.cat([control.clone() for _ in range(batch_size)], dim=0) + control *= param.weight + control *= cond_mark[:, :, :, 0] + context = torch.cat([context, control.clone()], dim=1) + + # handle ControlNet / T2I_Adapter + for param_index, param in enumerate(outer.control_params): + if param.guidance_stopped or param.disabled_by_hr_option(self.is_in_high_res_fix): + continue + + if param.control_model_type not in [ControlModelType.ControlNet, ControlModelType.T2I_Adapter]: + continue + + # inpaint model workaround + x_in = x + control_model = param.control_model.control_model + + if param.control_model_type == ControlModelType.ControlNet: + if x.shape[1] != control_model.input_blocks[0][0].in_channels and x.shape[1] == 9: + # inpaint_model: 4 data + 4 downscaled image + 1 mask + x_in = x[:, :4, ...] + require_inpaint_hijack = True + + assert param.used_hint_cond is not None, f"Controlnet is enabled but no input image is given" + + hint = param.used_hint_cond + + # ControlNet inpaint protocol + if hint.shape[1] == 4: + c = hint[:, 0:3, :, :] + m = hint[:, 3:4, :, :] + m = (m > 0.5).float() + hint = c * (1 - m) - m + + control = param.control_model(x=x_in, hint=hint, timesteps=timesteps, context=context, y=y) + + if is_sdxl: + control_scales = [param.weight] * 10 + else: + control_scales = [param.weight] * 13 + + if param.cfg_injection or param.global_average_pooling: + if param.control_model_type == ControlModelType.T2I_Adapter: + control = [torch.cat([c.clone() for _ in range(batch_size)], dim=0) for c in control] + control = [c * cond_mark for c in control] + + high_res_fix_forced_soft_injection = False + + if is_in_high_res_fix: + if 'canny' in param.preprocessor['name']: + high_res_fix_forced_soft_injection = True + if 'mlsd' in param.preprocessor['name']: + high_res_fix_forced_soft_injection = True + + # if high_res_fix_forced_soft_injection: + # logger.info('[ControlNet] Forced soft_injection in high_res_fix in enabled.') + + if param.soft_injection or high_res_fix_forced_soft_injection: + # important! use the soft weights with high-res fix can significantly reduce artifacts. + if param.control_model_type == ControlModelType.T2I_Adapter: + control_scales = [param.weight * x for x in (0.25, 0.62, 0.825, 1.0)] + elif param.control_model_type == ControlModelType.ControlNet: + control_scales = [param.weight * (0.825 ** float(12 - i)) for i in range(13)] + + if is_sdxl and param.control_model_type == ControlModelType.ControlNet: + control_scales = control_scales[:10] + + if param.advanced_weighting is not None: + logger.info(f"Advanced weighting enabled. {param.advanced_weighting}") + if param.soft_injection or high_res_fix_forced_soft_injection: + logger.warn("Advanced weighting overwrites soft_injection effect.") + control_scales = param.advanced_weighting + + control = [c * scale for c, scale in zip(control, control_scales)] + if param.global_average_pooling: + control = [torch.mean(c, dim=(2, 3), keepdim=True) for c in control] + + for idx, item in enumerate(control): + target = None + if param.control_model_type == ControlModelType.ControlNet: + target = total_controlnet_embedding + if param.control_model_type == ControlModelType.T2I_Adapter: + target = total_t2i_adapter_embedding + if target is not None: + if batch_option_uint_separate: + for pi, ci in enumerate(outer.current_c_indices): + if pi % len(outer.control_params) != param_index: + item[ci] = 0 + for pi, ci in enumerate(outer.current_uc_indices): + if pi % len(outer.control_params) != param_index: + item[ci] = 0 + target[idx] = item + target[idx] + else: + target[idx] = item + target[idx] + + # Replace x_t to support inpaint models + for param in outer.control_params: + if not isinstance(param.used_hint_cond, torch.Tensor): + continue + if param.used_hint_cond.shape[1] != 4: + continue + if x.shape[1] != 9: + continue + if param.used_hint_inpaint_hijack is None: + mask_pixel = param.used_hint_cond[:, 3:4, :, :] + image_pixel = param.used_hint_cond[:, 0:3, :, :] + mask_pixel = (mask_pixel > 0.5).to(mask_pixel.dtype) + masked_latent = outer.call_vae_using_process(process, image_pixel, batch_size, mask=mask_pixel) + mask_latent = torch.nn.functional.max_pool2d(mask_pixel, (8, 8)) + if mask_latent.shape[0] != batch_size: + mask_latent = torch.cat([mask_latent.clone() for _ in range(batch_size)], dim=0) + param.used_hint_inpaint_hijack = torch.cat([mask_latent, masked_latent], dim=1) + param.used_hint_inpaint_hijack.to(x.dtype).to(x.device) + x = torch.cat([x[:, :4, :, :], param.used_hint_inpaint_hijack], dim=1) + + # vram + for param in outer.control_params: + if param.control_model is not None: + if outer.lowvram: + param.control_model.to('cpu') + + # A1111 fix for medvram. + if shared.cmd_opts.medvram or (getattr(shared.cmd_opts, 'medvram_sdxl', False) and is_sdxl): + try: + # Trigger the register_forward_pre_hook + outer.sd_ldm.model() + except: + pass + + # Clear attention and AdaIn cache + for module in outer.attn_module_list: + module.bank = [] + module.style_cfgs = [] + for module in outer.gn_module_list: + module.mean_bank = [] + module.var_bank = [] + module.style_cfgs = [] + + # Handle attention and AdaIn control + for param in outer.control_params: + if param.guidance_stopped or param.disabled_by_hr_option(self.is_in_high_res_fix): + continue + + if param.used_hint_cond_latent is None: + continue + + if param.control_model_type not in [ControlModelType.AttentionInjection]: + continue + + ref_xt = predict_q_sample(outer.sd_ldm, param.used_hint_cond_latent, torch.round(timesteps.float()).long()) + + # Inpaint Hijack + if x.shape[1] == 9: + ref_xt = torch.cat([ + ref_xt, + torch.zeros_like(ref_xt)[:, 0:1, :, :], + param.used_hint_cond_latent + ], dim=1) + + outer.current_style_fidelity = float(param.preprocessor['threshold_a']) + outer.current_style_fidelity = max(0.0, min(1.0, outer.current_style_fidelity)) + + if is_sdxl: + # sdxl's attention hacking is highly unstable. + # We have no other methods but to reduce the style_fidelity a bit. + # By default, 0.5 ** 3.0 = 0.125 + outer.current_style_fidelity = outer.current_style_fidelity ** 3.0 + + if param.cfg_injection: + outer.current_style_fidelity = 1.0 + elif param.soft_injection or is_in_high_res_fix: + outer.current_style_fidelity = 0.0 + + control_name = param.preprocessor['name'] + + if control_name in ['reference_only', 'reference_adain+attn']: + outer.attention_auto_machine = AutoMachine.Write + outer.attention_auto_machine_weight = param.weight + + if control_name in ['reference_adain', 'reference_adain+attn']: + outer.gn_auto_machine = AutoMachine.Write + outer.gn_auto_machine_weight = param.weight + + if is_sdxl: + outer.original_forward( + x=ref_xt.to(devices.dtype_unet), + timesteps=timesteps.to(devices.dtype_unet), + context=context.to(devices.dtype_unet), + y=y + ) + else: + outer.original_forward( + x=ref_xt.to(devices.dtype_unet), + timesteps=timesteps.to(devices.dtype_unet), + context=context.to(devices.dtype_unet) + ) + + outer.attention_auto_machine = AutoMachine.Read + outer.gn_auto_machine = AutoMachine.Read + + # U-Net Encoder + hs = [] + with th.no_grad(): + t_emb = cond_cast_unet(timestep_embedding(timesteps, self.model_channels, repeat_only=False)) + emb = self.time_embed(t_emb) + + if is_sdxl: + assert y.shape[0] == x.shape[0] + emb = emb + self.label_emb(y) + + h = x + for i, module in enumerate(self.input_blocks): + self.current_h_shape = (h.shape[0], h.shape[1], h.shape[2], h.shape[3]) + h = module(h, emb, context) + + t2i_injection = [3, 5, 8] if is_sdxl else [2, 5, 8, 11] + + if i in t2i_injection: + h = aligned_adding(h, total_t2i_adapter_embedding.pop(0), require_inpaint_hijack) + + hs.append(h) + + self.current_h_shape = (h.shape[0], h.shape[1], h.shape[2], h.shape[3]) + h = self.middle_block(h, emb, context) + + # U-Net Middle Block + h = aligned_adding(h, total_controlnet_embedding.pop(), require_inpaint_hijack) + + if len(total_t2i_adapter_embedding) > 0 and is_sdxl: + h = aligned_adding(h, total_t2i_adapter_embedding.pop(0), require_inpaint_hijack) + + # U-Net Decoder + for i, module in enumerate(self.output_blocks): + self.current_h_shape = (h.shape[0], h.shape[1], h.shape[2], h.shape[3]) + h = th.cat([h, aligned_adding(hs.pop(), total_controlnet_embedding.pop(), require_inpaint_hijack)], dim=1) + h = module(h, emb, context) + + # U-Net Output + h = h.type(x.dtype) + h = self.out(h) + + # Post-processing for color fix + for param in outer.control_params: + if param.used_hint_cond_latent is None: + continue + if 'colorfix' not in param.preprocessor['name']: + continue + + k = int(param.preprocessor['threshold_a']) + if is_in_high_res_fix and not param.disabled_by_hr_option(self.is_in_high_res_fix): + k *= 2 + + # Inpaint hijack + xt = x[:, :4, :, :] + + x0_origin = param.used_hint_cond_latent + t = torch.round(timesteps.float()).long() + x0_prd = predict_start_from_noise(outer.sd_ldm, xt, t, h) + x0 = x0_prd - blur(x0_prd, k) + blur(x0_origin, k) + + if '+sharp' in param.preprocessor['name']: + detail_weight = float(param.preprocessor['threshold_b']) * 0.01 + neg = detail_weight * blur(x0, k) + (1 - detail_weight) * x0 + x0 = cond_mark * x0 + (1 - cond_mark) * neg + + eps_prd = predict_noise_from_start(outer.sd_ldm, xt, t, x0) + + w = max(0.0, min(1.0, float(param.weight))) + h = eps_prd * w + h * (1 - w) + + # Post-processing for restore + for param in outer.control_params: + if param.used_hint_cond_latent is None: + continue + if 'inpaint_only' not in param.preprocessor['name']: + continue + if param.used_hint_cond.shape[1] != 4: + continue + + # Inpaint hijack + xt = x[:, :4, :, :] + + mask = param.used_hint_cond[:, 3:4, :, :] + mask = torch.nn.functional.max_pool2d(mask, (10, 10), stride=(8, 8), padding=1) + + x0_origin = param.used_hint_cond_latent + t = torch.round(timesteps.float()).long() + x0_prd = predict_start_from_noise(outer.sd_ldm, xt, t, h) + x0 = x0_prd * mask + x0_origin * (1 - mask) + eps_prd = predict_noise_from_start(outer.sd_ldm, xt, t, x0) + + w = max(0.0, min(1.0, float(param.weight))) + h = eps_prd * w + h * (1 - w) + + return h + + def move_all_control_model_to_cpu(): + for param in getattr(outer, 'control_params', []) or []: + if isinstance(param.control_model, torch.nn.Module): + param.control_model.to("cpu") + + def forward_webui(*args, **kwargs): + # webui will handle other compoments + try: + if shared.cmd_opts.lowvram: + lowvram.send_everything_to_cpu() + return forward(*args, **kwargs) + except Exception as e: + move_all_control_model_to_cpu() + raise e + finally: + if outer.lowvram: + move_all_control_model_to_cpu() + + def hacked_basic_transformer_inner_forward(self, x, context=None): + x_norm1 = self.norm1(x) + self_attn1 = None + if self.disable_self_attn: + # Do not use self-attention + self_attn1 = self.attn1(x_norm1, context=context) + else: + # Use self-attention + self_attention_context = x_norm1 + if outer.attention_auto_machine == AutoMachine.Write: + if outer.attention_auto_machine_weight > self.attn_weight: + self.bank.append(self_attention_context.detach().clone()) + self.style_cfgs.append(outer.current_style_fidelity) + if outer.attention_auto_machine == AutoMachine.Read: + if len(self.bank) > 0: + style_cfg = sum(self.style_cfgs) / float(len(self.style_cfgs)) + self_attn1_uc = self.attn1(x_norm1, context=torch.cat([self_attention_context] + self.bank, dim=1)) + self_attn1_c = self_attn1_uc.clone() + if len(outer.current_uc_indices) > 0 and style_cfg > 1e-5: + self_attn1_c[outer.current_uc_indices] = self.attn1( + x_norm1[outer.current_uc_indices], + context=self_attention_context[outer.current_uc_indices]) + self_attn1 = style_cfg * self_attn1_c + (1.0 - style_cfg) * self_attn1_uc + self.bank = [] + self.style_cfgs = [] + if outer.attention_auto_machine == AutoMachine.StyleAlign and not outer.is_in_high_res_fix: + # very VRAM hungry - disable at high_res_fix + + def shared_attn1(inner_x): + BB, FF, CC = inner_x.shape + return self.attn1(inner_x.reshape(1, BB * FF, CC)).reshape(BB, FF, CC) + + uc_layer = shared_attn1(x_norm1[outer.current_uc_indices]) + c_layer = shared_attn1(x_norm1[outer.current_c_indices]) + self_attn1 = torch.zeros_like(x_norm1).to(uc_layer) + self_attn1[outer.current_uc_indices] = uc_layer + self_attn1[outer.current_c_indices] = c_layer + del uc_layer, c_layer + if self_attn1 is None: + self_attn1 = self.attn1(x_norm1, context=self_attention_context) + + x = self_attn1.to(x.dtype) + x + x = self.attn2(self.norm2(x), context=context) + x + x = self.ff(self.norm3(x)) + x + return x + + def hacked_group_norm_forward(self, *args, **kwargs): + eps = 1e-6 + x = self.original_forward_cn_hijack(*args, **kwargs) + y = None + if outer.gn_auto_machine == AutoMachine.Write: + if outer.gn_auto_machine_weight > self.gn_weight: + var, mean = torch.var_mean(x, dim=(2, 3), keepdim=True, correction=0) + self.mean_bank.append(mean) + self.var_bank.append(var) + self.style_cfgs.append(outer.current_style_fidelity) + if outer.gn_auto_machine == AutoMachine.Read: + if len(self.mean_bank) > 0 and len(self.var_bank) > 0: + style_cfg = sum(self.style_cfgs) / float(len(self.style_cfgs)) + var, mean = torch.var_mean(x, dim=(2, 3), keepdim=True, correction=0) + std = torch.maximum(var, torch.zeros_like(var) + eps) ** 0.5 + mean_acc = sum(self.mean_bank) / float(len(self.mean_bank)) + var_acc = sum(self.var_bank) / float(len(self.var_bank)) + std_acc = torch.maximum(var_acc, torch.zeros_like(var_acc) + eps) ** 0.5 + y_uc = (((x - mean) / std) * std_acc) + mean_acc + y_c = y_uc.clone() + if len(outer.current_uc_indices) > 0 and style_cfg > 1e-5: + y_c[outer.current_uc_indices] = x.to(y_c.dtype)[outer.current_uc_indices] + y = style_cfg * y_c + (1.0 - style_cfg) * y_uc + self.mean_bank = [] + self.var_bank = [] + self.style_cfgs = [] + if y is None: + y = x + return y.to(x.dtype) + + if getattr(process, 'sample_before_CN_hack', None) is None: + process.sample_before_CN_hack = process.sample + process.sample = process_sample + + model._original_forward = model.forward + outer.original_forward = model.forward + model.forward = forward_webui.__get__(model, UNetModel) + + if model_is_sdxl: + register_schedule(sd_ldm) + outer.revision_q_sampler = AbstractLowScaleModel() + + need_attention_hijack = False + + for param in outer.control_params: + if param.control_model_type in [ControlModelType.AttentionInjection]: + need_attention_hijack = True + + if batch_option_style_align: + need_attention_hijack = True + outer.attention_auto_machine = AutoMachine.StyleAlign + outer.gn_auto_machine = AutoMachine.StyleAlign + + all_modules = torch_dfs(model) + + if need_attention_hijack: + attn_modules = [module for module in all_modules if isinstance(module, BasicTransformerBlock) or isinstance(module, BasicTransformerBlockSGM)] + attn_modules = sorted(attn_modules, key=lambda x: - x.norm1.normalized_shape[0]) + + for i, module in enumerate(attn_modules): + if getattr(module, '_original_inner_forward_cn_hijack', None) is None: + module._original_inner_forward_cn_hijack = module._forward + module._forward = hacked_basic_transformer_inner_forward.__get__(module, BasicTransformerBlock) + module.bank = [] + module.style_cfgs = [] + module.attn_weight = float(i) / float(len(attn_modules)) + + gn_modules = [model.middle_block] + model.middle_block.gn_weight = 0 + + if model_is_sdxl: + input_block_indices = [4, 5, 7, 8] + output_block_indices = [0, 1, 2, 3, 4, 5] + else: + input_block_indices = [4, 5, 7, 8, 10, 11] + output_block_indices = [0, 1, 2, 3, 4, 5, 6, 7] + + for w, i in enumerate(input_block_indices): + module = model.input_blocks[i] + module.gn_weight = 1.0 - float(w) / float(len(input_block_indices)) + gn_modules.append(module) + + for w, i in enumerate(output_block_indices): + module = model.output_blocks[i] + module.gn_weight = float(w) / float(len(output_block_indices)) + gn_modules.append(module) + + for i, module in enumerate(gn_modules): + if getattr(module, 'original_forward_cn_hijack', None) is None: + module.original_forward_cn_hijack = module.forward + module.forward = hacked_group_norm_forward.__get__(module, torch.nn.Module) + module.mean_bank = [] + module.var_bank = [] + module.style_cfgs = [] + module.gn_weight *= 2 + + outer.attn_module_list = attn_modules + outer.gn_module_list = gn_modules + else: + for module in all_modules: + _original_inner_forward_cn_hijack = getattr(module, '_original_inner_forward_cn_hijack', None) + original_forward_cn_hijack = getattr(module, 'original_forward_cn_hijack', None) + if _original_inner_forward_cn_hijack is not None: + module._forward = _original_inner_forward_cn_hijack + if original_forward_cn_hijack is not None: + module.forward = original_forward_cn_hijack + outer.attn_module_list = [] + outer.gn_module_list = [] + + scripts.script_callbacks.on_cfg_denoiser(self.guidance_schedule_handler) + + def restore(self): + scripts.script_callbacks.remove_callbacks_for_function(self.guidance_schedule_handler) + self.control_params = None + + if self.model is not None: + if hasattr(self.model, "_original_forward"): + self.model.forward = self.model._original_forward + del self.model._original_forward diff --git a/extensions-builtin/sd_forge_controlnet/scripts/infotext.py b/extensions-builtin/sd_forge_controlnet/scripts/infotext.py new file mode 100644 index 00000000..393674e9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/infotext.py @@ -0,0 +1,135 @@ +from typing import List, Tuple, Union + +import gradio as gr + +from modules.processing import StableDiffusionProcessing + +from scripts import external_code +from scripts.logging import logger + + +def field_to_displaytext(fieldname: str) -> str: + return " ".join([word.capitalize() for word in fieldname.split("_")]) + + +def displaytext_to_field(text: str) -> str: + return "_".join([word.lower() for word in text.split(" ")]) + + +def parse_value(value: str) -> Union[str, float, int, bool]: + if value in ("True", "False"): + return value == "True" + try: + return int(value) + except ValueError: + try: + return float(value) + except ValueError: + return value # Plain string. + + +def serialize_unit(unit: external_code.ControlNetUnit) -> str: + excluded_fields = ( + "image", + "enabled", + # Note: "advanced_weighting" is excluded as it is an API-only field. + "advanced_weighting", + # Note: "inpaint_crop_image" is img2img inpaint only flag, which does not + # provide much information when restoring the unit. + "inpaint_crop_input_image", + ) + + log_value = { + field_to_displaytext(field): getattr(unit, field) + for field in vars(external_code.ControlNetUnit()).keys() + if field not in excluded_fields and getattr(unit, field) != -1 + # Note: exclude hidden slider values. + } + if not all("," not in str(v) and ":" not in str(v) for v in log_value.values()): + logger.error(f"Unexpected tokens encountered:\n{log_value}") + return "" + + return ", ".join(f"{field}: {value}" for field, value in log_value.items()) + + +def parse_unit(text: str) -> external_code.ControlNetUnit: + return external_code.ControlNetUnit( + enabled=True, + **{ + displaytext_to_field(key): parse_value(value) + for item in text.split(",") + for (key, value) in (item.strip().split(": "),) + }, + ) + + +class Infotext(object): + def __init__(self) -> None: + self.infotext_fields: List[Tuple[gr.components.IOComponent, str]] = [] + self.paste_field_names: List[str] = [] + + @staticmethod + def unit_prefix(unit_index: int) -> str: + return f"ControlNet {unit_index}" + + def register_unit(self, unit_index: int, uigroup) -> None: + """Register the unit's UI group. By regsitering the unit, A1111 will be + able to paste values from infotext to IOComponents. + + Args: + unit_index: The index of the ControlNet unit + uigroup: The ControlNetUiGroup instance that contains all gradio + iocomponents. + """ + unit_prefix = Infotext.unit_prefix(unit_index) + for field in vars(external_code.ControlNetUnit()).keys(): + # Exclude image for infotext. + if field == "image": + continue + + # Every field in ControlNetUnit should have a cooresponding + # IOComponent in ControlNetUiGroup. + io_component = getattr(uigroup, field) + component_locator = f"{unit_prefix} {field}" + self.infotext_fields.append((io_component, component_locator)) + self.paste_field_names.append(component_locator) + + @staticmethod + def write_infotext( + units: List[external_code.ControlNetUnit], p: StableDiffusionProcessing + ): + """Write infotext to `p`.""" + p.extra_generation_params.update( + { + Infotext.unit_prefix(i): serialize_unit(unit) + for i, unit in enumerate(units) + if unit.enabled + } + ) + + @staticmethod + def on_infotext_pasted(infotext: str, results: dict) -> None: + """Parse ControlNet infotext string and write result to `results` dict.""" + updates = {} + for k, v in results.items(): + if not k.startswith("ControlNet"): + continue + + assert isinstance(v, str), f"Expect string but got {v}." + try: + for field, value in vars(parse_unit(v)).items(): + if field == "image": + continue + if value is None: + logger.debug(f"InfoText: Skipping {field} because value is None.") + continue + + component_locator = f"{k} {field}" + updates[component_locator] = value + logger.debug(f"InfoText: Setting {component_locator} = {value}") + except Exception as e: + logger.warn( + f"Failed to parse infotext, legacy format infotext is no longer supported:\n{v}\n{e}" + ) + + results.update(updates) diff --git a/extensions-builtin/sd_forge_controlnet/scripts/logging.py b/extensions-builtin/sd_forge_controlnet/scripts/logging.py new file mode 100644 index 00000000..f30d5eec --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/logging.py @@ -0,0 +1,41 @@ +import logging +import copy +import sys + +from modules import shared + + +class ColoredFormatter(logging.Formatter): + COLORS = { + "DEBUG": "\033[0;36m", # CYAN + "INFO": "\033[0;32m", # GREEN + "WARNING": "\033[0;33m", # YELLOW + "ERROR": "\033[0;31m", # RED + "CRITICAL": "\033[0;37;41m", # WHITE ON RED + "RESET": "\033[0m", # RESET COLOR + } + + def format(self, record): + colored_record = copy.copy(record) + levelname = colored_record.levelname + seq = self.COLORS.get(levelname, self.COLORS["RESET"]) + colored_record.levelname = f"{seq}{levelname}{self.COLORS['RESET']}" + return super().format(colored_record) + + +# Create a new logger +logger = logging.getLogger("ControlNet") +logger.propagate = False + +# Add handler if we don't have one. +if not logger.handlers: + handler = logging.StreamHandler(sys.stdout) + handler.setFormatter( + ColoredFormatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") + ) + logger.addHandler(handler) + +# Configure logger +loglevel_string = getattr(shared.cmd_opts, "controlnet_loglevel", "INFO") +loglevel = getattr(logging, loglevel_string.upper(), None) +logger.setLevel(loglevel) diff --git a/extensions-builtin/sd_forge_controlnet/scripts/lvminthin.py b/extensions-builtin/sd_forge_controlnet/scripts/lvminthin.py new file mode 100644 index 00000000..641227aa --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/lvminthin.py @@ -0,0 +1,88 @@ +# High Quality Edge Thinning using Pure Python +# Written by Lvmin Zhang +# 2023 April +# Stanford University +# If you use this, please Cite "High Quality Edge Thinning using Pure Python", Lvmin Zhang, In Mikubill/sd-webui-controlnet. + + +import cv2 +import numpy as np + + +lvmin_kernels_raw = [ + np.array([ + [-1, -1, -1], + [0, 1, 0], + [1, 1, 1] + ], dtype=np.int32), + np.array([ + [0, -1, -1], + [1, 1, -1], + [0, 1, 0] + ], dtype=np.int32) +] + +lvmin_kernels = [] +lvmin_kernels += [np.rot90(x, k=0, axes=(0, 1)) for x in lvmin_kernels_raw] +lvmin_kernels += [np.rot90(x, k=1, axes=(0, 1)) for x in lvmin_kernels_raw] +lvmin_kernels += [np.rot90(x, k=2, axes=(0, 1)) for x in lvmin_kernels_raw] +lvmin_kernels += [np.rot90(x, k=3, axes=(0, 1)) for x in lvmin_kernels_raw] + +lvmin_prunings_raw = [ + np.array([ + [-1, -1, -1], + [-1, 1, -1], + [0, 0, -1] + ], dtype=np.int32), + np.array([ + [-1, -1, -1], + [-1, 1, -1], + [-1, 0, 0] + ], dtype=np.int32) +] + +lvmin_prunings = [] +lvmin_prunings += [np.rot90(x, k=0, axes=(0, 1)) for x in lvmin_prunings_raw] +lvmin_prunings += [np.rot90(x, k=1, axes=(0, 1)) for x in lvmin_prunings_raw] +lvmin_prunings += [np.rot90(x, k=2, axes=(0, 1)) for x in lvmin_prunings_raw] +lvmin_prunings += [np.rot90(x, k=3, axes=(0, 1)) for x in lvmin_prunings_raw] + + +def remove_pattern(x, kernel): + objects = cv2.morphologyEx(x, cv2.MORPH_HITMISS, kernel) + objects = np.where(objects > 127) + x[objects] = 0 + return x, objects[0].shape[0] > 0 + + +def thin_one_time(x, kernels): + y = x + is_done = True + for k in kernels: + y, has_update = remove_pattern(y, k) + if has_update: + is_done = False + return y, is_done + + +def lvmin_thin(x, prunings=True): + y = x + for i in range(32): + y, is_done = thin_one_time(y, lvmin_kernels) + if is_done: + break + if prunings: + y, _ = thin_one_time(y, lvmin_prunings) + return y + + +def nake_nms(x): + f1 = np.array([[0, 0, 0], [1, 1, 1], [0, 0, 0]], dtype=np.uint8) + f2 = np.array([[0, 1, 0], [0, 1, 0], [0, 1, 0]], dtype=np.uint8) + f3 = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype=np.uint8) + f4 = np.array([[0, 0, 1], [0, 1, 0], [1, 0, 0]], dtype=np.uint8) + y = np.zeros_like(x) + for f in [f1, f2, f3, f4]: + np.putmask(y, cv2.dilate(x, kernel=f) == x, x) + return y + diff --git a/extensions-builtin/sd_forge_controlnet/scripts/movie2movie.py b/extensions-builtin/sd_forge_controlnet/scripts/movie2movie.py new file mode 100644 index 00000000..24c11837 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/movie2movie.py @@ -0,0 +1,176 @@ +import copy +import os +import shutil + +import cv2 +import gradio as gr +import modules.scripts as scripts + +from modules import images +from modules.processing import process_images +from modules.shared import opts +from PIL import Image + +import numpy as np + +_BASEDIR = "/controlnet-m2m" +_BASEFILE = "animation" + +def get_all_frames(video_path): + if video_path is None: + return None + cap = cv2.VideoCapture(video_path) + frame_list = [] + if not cap.isOpened(): + return + while True: + ret, frame = cap.read() + if ret: + frame_list.append(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) + else: + return frame_list + +def get_min_frame_num(video_list): + min_frame_num = -1 + for video in video_list: + if video is None: + continue + else: + frame_num = len(video) + print(frame_num) + if min_frame_num < 0: + min_frame_num = frame_num + elif frame_num < min_frame_num: + min_frame_num = frame_num + return min_frame_num + +def pil2cv(image): + new_image = np.array(image, dtype=np.uint8) + if new_image.ndim == 2: + pass + elif new_image.shape[2] == 3: + new_image = new_image[:, :, ::-1] + elif new_image.shape[2] == 4: + new_image = new_image[:, :, [2, 1, 0, 3]] + return new_image + + +def save_gif(path, image_list, name, duration): + tmp_dir = path + "/tmp/" + if os.path.isdir(tmp_dir): + shutil.rmtree(tmp_dir) + os.mkdir(tmp_dir) + for i, image in enumerate(image_list): + images.save_image(image, tmp_dir, f"output_{i}") + + os.makedirs(f"{path}{_BASEDIR}", exist_ok=True) + + image_list[0].save(f"{path}{_BASEDIR}/{name}.gif", save_all=True, append_images=image_list[1:], optimize=False, duration=duration, loop=0) + + +class Script(scripts.Script): + + def title(self): + return "controlnet m2m" + + def show(self, is_img2img): + return True + + def ui(self, is_img2img): + # How the script's is displayed in the UI. See https://gradio.app/docs/#components + # for the different UI components you can use and how to create them. + # Most UI components can return a value, such as a boolean for a checkbox. + # The returned values are passed to the run method as parameters. + + ctrls_group = () + max_models = opts.data.get("control_net_unit_count", 3) + + with gr.Group(): + with gr.Accordion("ControlNet-M2M", open = False): + duration = gr.Slider(label=f"Duration", value=50.0, minimum=10.0, maximum=200.0, step=10, interactive=True, elem_id='controlnet_movie2movie_duration_slider') + with gr.Tabs(): + for i in range(max_models): + with gr.Tab(f"ControlNet-{i}"): + with gr.TabItem("Movie Input"): + ctrls_group += (gr.Video(format='mp4', source='upload', elem_id = f"video_{i}"), ) + with gr.TabItem("Image Input"): + ctrls_group += (gr.Image(source='upload', brush_radius=20, mirror_webcam=False, type='numpy', tool='sketch', elem_id=f'image_{i}'), ) + ctrls_group += (gr.Checkbox(label=f"Save preprocessed", value=False, elem_id = f"save_pre_{i}"),) + + ctrls_group += (duration,) + + return ctrls_group + + def run(self, p, *args): + # This is where the additional processing is implemented. The parameters include + # self, the model object "p" (a StableDiffusionProcessing class, see + # processing.py), and the parameters returned by the ui method. + # Custom functions can be defined here, and additional libraries can be imported + # to be used in processing. The return value should be a Processed object, which is + # what is returned by the process_images method. + + contents_num = opts.data.get("control_net_unit_count", 3) + arg_num = 3 + item_list = [] + video_list = [] + for input_set in [tuple(args[:contents_num * arg_num][i:i+3]) for i in range(0, len(args[:contents_num * arg_num]), arg_num)]: + if input_set[0] is not None: + item_list.append([get_all_frames(input_set[0]), "video"]) + video_list.append(get_all_frames(input_set[0])) + if input_set[1] is not None: + item_list.append([cv2.cvtColor(pil2cv(input_set[1]["image"]), cv2.COLOR_BGRA2RGB), "image"]) + + save_pre = list(args[2:contents_num * arg_num:3]) + item_num = len(item_list) + video_num = len(video_list) + duration, = args[contents_num * arg_num:] + + frame_num = get_min_frame_num(video_list) + if frame_num > 0: + output_image_list = [] + pre_output_image_list = [] + for i in range(item_num): + pre_output_image_list.append([]) + + for frame in range(frame_num): + copy_p = copy.copy(p) + copy_p.control_net_input_image = [] + for item in item_list: + if item[1] == "video": + copy_p.control_net_input_image.append(item[0][frame]) + elif item[1] == "image": + copy_p.control_net_input_image.append(item[0]) + else: + continue + + proc = process_images(copy_p) + img = proc.images[0] + output_image_list.append(img) + + for i in range(len(save_pre)): + if save_pre[i]: + try: + pre_output_image_list[i].append(proc.images[i + 1]) + except: + print(f"proc.images[{i} failed") + + copy_p.close() + + # filename format is seq-seed-animation.gif seq is 5 places left filled with 0 + + seq = images.get_next_sequence_number(f"{p.outpath_samples}{_BASEDIR}", "") + filename = f"{seq:05}-{proc.seed}-{_BASEFILE}" + save_gif(p.outpath_samples, output_image_list, filename, duration) + proc.images = [f"{p.outpath_samples}{_BASEDIR}/{filename}.gif"] + + + for i in range(len(save_pre)): + if save_pre[i]: + # control files add -controlX.gif where X is the controlnet number + save_gif(p.outpath_samples, pre_output_image_list[i], f"{filename}-control{i}", duration) + proc.images.append(f"{p.outpath_samples}{_BASEDIR}/{filename}-control{i}.gif") + + else: + proc = process_images(p) + + return proc diff --git a/extensions-builtin/sd_forge_controlnet/scripts/processor.py b/extensions-builtin/sd_forge_controlnet/scripts/processor.py new file mode 100644 index 00000000..eac9777b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/processor.py @@ -0,0 +1,1245 @@ +import os +import cv2 +import numpy as np +import torch + +from annotator.util import HWC3 +from typing import Callable, Tuple, Union, List + +from modules.safe import Extra +from modules import devices +from scripts.logging import logger + + +def torch_handler(module: str, name: str): + """ Allow all torch access. Bypass A1111 safety whitelist. """ + if module == 'torch': + return getattr(torch, name) + if module == 'torch._tensor': + # depth_anything dep. + return getattr(torch._tensor, name) + + +def pad64(x): + return int(np.ceil(float(x) / 64.0) * 64 - x) + + +def safer_memory(x): + # Fix many MAC/AMD problems + return np.ascontiguousarray(x.copy()).copy() + + +def resize_image_with_pad(input_image, resolution, skip_hwc3=False): + if skip_hwc3: + img = input_image + else: + img = HWC3(input_image) + H_raw, W_raw, _ = img.shape + k = float(resolution) / float(min(H_raw, W_raw)) + interpolation = cv2.INTER_CUBIC if k > 1 else cv2.INTER_AREA + H_target = int(np.round(float(H_raw) * k)) + W_target = int(np.round(float(W_raw) * k)) + img = cv2.resize(img, (W_target, H_target), interpolation=interpolation) + H_pad, W_pad = pad64(H_target), pad64(W_target) + img_padded = np.pad(img, [[0, H_pad], [0, W_pad], [0, 0]], mode='edge') + + def remove_pad(x): + return safer_memory(x[:H_target, :W_target]) + + return safer_memory(img_padded), remove_pad + + +model_canny = None + + +def canny(img, res=512, thr_a=100, thr_b=200, **kwargs): + l, h = thr_a, thr_b + img, remove_pad = resize_image_with_pad(img, res) + global model_canny + if model_canny is None: + from annotator.canny import apply_canny + model_canny = apply_canny + result = model_canny(img, l, h) + return remove_pad(result), True + + +def scribble_thr(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + result = np.zeros_like(img, dtype=np.uint8) + result[np.min(img, axis=2) < 127] = 255 + return remove_pad(result), True + + +def scribble_xdog(img, res=512, thr_a=32, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + g1 = cv2.GaussianBlur(img.astype(np.float32), (0, 0), 0.5) + g2 = cv2.GaussianBlur(img.astype(np.float32), (0, 0), 5.0) + dog = (255 - np.min(g2 - g1, axis=2)).clip(0, 255).astype(np.uint8) + result = np.zeros_like(img, dtype=np.uint8) + result[2 * (255 - dog) > thr_a] = 255 + return remove_pad(result), True + + +def tile_resample(img, res=512, thr_a=1.0, **kwargs): + img = HWC3(img) + if thr_a < 1.1: + return img, True + H, W, C = img.shape + H = int(float(H) / float(thr_a)) + W = int(float(W) / float(thr_a)) + img = cv2.resize(img, (W, H), interpolation=cv2.INTER_AREA) + return img, True + + +def threshold(img, res=512, thr_a=127, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + result = np.zeros_like(img, dtype=np.uint8) + result[np.min(img, axis=2) > thr_a] = 255 + return remove_pad(result), True + + +def identity(img, **kwargs): + return img, True + + +def invert(img, res=512, **kwargs): + return 255 - HWC3(img), True + + +model_hed = None + + +def hed(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_hed + if model_hed is None: + from annotator.hed import apply_hed + model_hed = apply_hed + result = model_hed(img) + return remove_pad(result), True + + +def hed_safe(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_hed + if model_hed is None: + from annotator.hed import apply_hed + model_hed = apply_hed + result = model_hed(img, is_safe=True) + return remove_pad(result), True + + +def unload_hed(): + global model_hed + if model_hed is not None: + from annotator.hed import unload_hed_model + unload_hed_model() + + +def scribble_hed(img, res=512, **kwargs): + result, _ = hed(img, res) + import cv2 + from annotator.util import nms + result = nms(result, 127, 3.0) + result = cv2.GaussianBlur(result, (0, 0), 3.0) + result[result > 4] = 255 + result[result < 255] = 0 + return result, True + + +model_mediapipe_face = None + + +def mediapipe_face(img, res=512, thr_a: int = 10, thr_b: float = 0.5, **kwargs): + max_faces = int(thr_a) + min_confidence = thr_b + img, remove_pad = resize_image_with_pad(img, res) + global model_mediapipe_face + if model_mediapipe_face is None: + from annotator.mediapipe_face import apply_mediapipe_face + model_mediapipe_face = apply_mediapipe_face + result = model_mediapipe_face(img, max_faces=max_faces, min_confidence=min_confidence) + return remove_pad(result), True + + +model_mlsd = None + + +def mlsd(img, res=512, thr_a=0.1, thr_b=0.1, **kwargs): + thr_v, thr_d = thr_a, thr_b + img, remove_pad = resize_image_with_pad(img, res) + global model_mlsd + if model_mlsd is None: + from annotator.mlsd import apply_mlsd + model_mlsd = apply_mlsd + result = model_mlsd(img, thr_v, thr_d) + return remove_pad(result), True + + +def unload_mlsd(): + global model_mlsd + if model_mlsd is not None: + from annotator.mlsd import unload_mlsd_model + unload_mlsd_model() + + +model_depth_anything = None + + +def depth_anything(img, res:int = 512, colored:bool = True, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_depth_anything + if model_depth_anything is None: + with Extra(torch_handler): + from annotator.depth_anything import DepthAnythingDetector + device = devices.get_device_for("controlnet") + model_depth_anything = DepthAnythingDetector(device) + return remove_pad(model_depth_anything(img, colored=colored)), True + + +def unload_depth_anything(): + if model_depth_anything is not None: + model_depth_anything.unload_model() + + +model_midas = None + + +def midas(img, res=512, a=np.pi * 2.0, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_midas + if model_midas is None: + from annotator.midas import apply_midas + model_midas = apply_midas + result, _ = model_midas(img, a) + return remove_pad(result), True + + +def midas_normal(img, res=512, a=np.pi * 2.0, thr_a=0.4, **kwargs): # bg_th -> thr_a + bg_th = thr_a + img, remove_pad = resize_image_with_pad(img, res) + global model_midas + if model_midas is None: + from annotator.midas import apply_midas + model_midas = apply_midas + _, result = model_midas(img, a, bg_th) + return remove_pad(result), True + + +def unload_midas(): + global model_midas + if model_midas is not None: + from annotator.midas import unload_midas_model + unload_midas_model() + + +model_leres = None + + +def leres(img, res=512, a=np.pi * 2.0, thr_a=0, thr_b=0, boost=False, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_leres + if model_leres is None: + from annotator.leres import apply_leres + model_leres = apply_leres + result = model_leres(img, thr_a, thr_b, boost=boost) + return remove_pad(result), True + + +def unload_leres(): + global model_leres + if model_leres is not None: + from annotator.leres import unload_leres_model + unload_leres_model() + + +class OpenposeModel(object): + def __init__(self) -> None: + self.model_openpose = None + + def run_model( + self, + img: np.ndarray, + include_body: bool, + include_hand: bool, + include_face: bool, + use_dw_pose: bool = False, + use_animal_pose: bool = False, + json_pose_callback: Callable[[str], None] = None, + res: int = 512, + **kwargs # Ignore rest of kwargs + ) -> Tuple[np.ndarray, bool]: + """Run the openpose model. Returns a tuple of + - result image + - is_image flag + + The JSON format pose string is passed to `json_pose_callback`. + """ + if json_pose_callback is None: + json_pose_callback = lambda x: None + + img, remove_pad = resize_image_with_pad(img, res) + + if self.model_openpose is None: + from annotator.openpose import OpenposeDetector + self.model_openpose = OpenposeDetector() + + return remove_pad(self.model_openpose( + img, + include_body=include_body, + include_hand=include_hand, + include_face=include_face, + use_dw_pose=use_dw_pose, + use_animal_pose=use_animal_pose, + json_pose_callback=json_pose_callback + )), True + + def unload(self): + if self.model_openpose is not None: + self.model_openpose.unload_model() + + +g_openpose_model = OpenposeModel() + +model_uniformer = None + + +def uniformer(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_uniformer + if model_uniformer is None: + from annotator.uniformer import apply_uniformer + model_uniformer = apply_uniformer + result = model_uniformer(img) + return remove_pad(result), True + + +def unload_uniformer(): + global model_uniformer + if model_uniformer is not None: + from annotator.uniformer import unload_uniformer_model + unload_uniformer_model() + + +model_pidinet = None + + +def pidinet(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_pidinet + if model_pidinet is None: + from annotator.pidinet import apply_pidinet + model_pidinet = apply_pidinet + result = model_pidinet(img) + return remove_pad(result), True + + +def pidinet_ts(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_pidinet + if model_pidinet is None: + from annotator.pidinet import apply_pidinet + model_pidinet = apply_pidinet + result = model_pidinet(img, apply_fliter=True) + return remove_pad(result), True + + +def pidinet_safe(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_pidinet + if model_pidinet is None: + from annotator.pidinet import apply_pidinet + model_pidinet = apply_pidinet + result = model_pidinet(img, is_safe=True) + return remove_pad(result), True + + +def scribble_pidinet(img, res=512, **kwargs): + result, _ = pidinet(img, res) + import cv2 + from annotator.util import nms + result = nms(result, 127, 3.0) + result = cv2.GaussianBlur(result, (0, 0), 3.0) + result[result > 4] = 255 + result[result < 255] = 0 + return result, True + + +def unload_pidinet(): + global model_pidinet + if model_pidinet is not None: + from annotator.pidinet import unload_pid_model + unload_pid_model() + + +clip_encoder = { + 'clip_g': None, + 'clip_h': None, + 'clip_vitl': None, +} + + +def clip(img, res=512, config='clip_vitl', low_vram=False, **kwargs): + img = HWC3(img) + global clip_encoder + if clip_encoder[config] is None: + from annotator.clipvision import ClipVisionDetector + if low_vram: + logger.info("Loading CLIP model on CPU.") + clip_encoder[config] = ClipVisionDetector(config, low_vram) + result = clip_encoder[config](img) + return result, False + + +def unload_clip(config='clip_vitl'): + global clip_encoder + if clip_encoder[config] is not None: + clip_encoder[config].unload_model() + clip_encoder[config] = None + + +model_color = None + + +def color(img, res=512, **kwargs): + img = HWC3(img) + global model_color + if model_color is None: + from annotator.color import apply_color + model_color = apply_color + result = model_color(img, res=res) + return result, True + + +def lineart_standard(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + x = img.astype(np.float32) + g = cv2.GaussianBlur(x, (0, 0), 6.0) + intensity = np.min(g - x, axis=2).clip(0, 255) + intensity /= max(16, np.median(intensity[intensity > 8])) + intensity *= 127 + result = intensity.clip(0, 255).astype(np.uint8) + return remove_pad(result), True + + +model_lineart = None + + +def lineart(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_lineart + if model_lineart is None: + from annotator.lineart import LineartDetector + model_lineart = LineartDetector(LineartDetector.model_default) + + # applied auto inversion + result = 255 - model_lineart(img) + return remove_pad(result), True + + +def unload_lineart(): + global model_lineart + if model_lineart is not None: + model_lineart.unload_model() + + +model_lineart_coarse = None + + +def lineart_coarse(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_lineart_coarse + if model_lineart_coarse is None: + from annotator.lineart import LineartDetector + model_lineart_coarse = LineartDetector(LineartDetector.model_coarse) + + # applied auto inversion + result = 255 - model_lineart_coarse(img) + return remove_pad(result), True + + +def unload_lineart_coarse(): + global model_lineart_coarse + if model_lineart_coarse is not None: + model_lineart_coarse.unload_model() + + +model_lineart_anime = None + + +def lineart_anime(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_lineart_anime + if model_lineart_anime is None: + from annotator.lineart_anime import LineartAnimeDetector + model_lineart_anime = LineartAnimeDetector() + + # applied auto inversion + result = 255 - model_lineart_anime(img) + return remove_pad(result), True + + +def unload_lineart_anime(): + global model_lineart_anime + if model_lineart_anime is not None: + model_lineart_anime.unload_model() + + +model_manga_line = None + + +def lineart_anime_denoise(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_manga_line + if model_manga_line is None: + from annotator.manga_line import MangaLineExtration + model_manga_line = MangaLineExtration() + + # applied auto inversion + result = model_manga_line(img) + return remove_pad(result), True + + +def unload_lineart_anime_denoise(): + global model_manga_line + if model_manga_line is not None: + model_manga_line.unload_model() + + +model_lama = None + + +def lama_inpaint(img, res=512, **kwargs): + H, W, C = img.shape + raw_color = img[:, :, 0:3].copy() + raw_mask = img[:, :, 3:4].copy() + + res = 256 # Always use 256 since lama is trained on 256 + + img_res, remove_pad = resize_image_with_pad(img, res, skip_hwc3=True) + + global model_lama + if model_lama is None: + from annotator.lama import LamaInpainting + model_lama = LamaInpainting() + + # applied auto inversion + prd_color = model_lama(img_res) + prd_color = remove_pad(prd_color) + prd_color = cv2.resize(prd_color, (W, H)) + + alpha = raw_mask.astype(np.float32) / 255.0 + fin_color = prd_color.astype(np.float32) * alpha + raw_color.astype(np.float32) * (1 - alpha) + fin_color = fin_color.clip(0, 255).astype(np.uint8) + + result = np.concatenate([fin_color, raw_mask], axis=2) + + return result, True + + +def unload_lama_inpaint(): + global model_lama + if model_lama is not None: + model_lama.unload_model() + + +model_zoe_depth = None + + +def zoe_depth(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_zoe_depth + if model_zoe_depth is None: + from annotator.zoe import ZoeDetector + model_zoe_depth = ZoeDetector() + result = model_zoe_depth(img) + return remove_pad(result), True + + +def unload_zoe_depth(): + global model_zoe_depth + if model_zoe_depth is not None: + model_zoe_depth.unload_model() + + +model_normal_bae = None + + +def normal_bae(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_normal_bae + if model_normal_bae is None: + from annotator.normalbae import NormalBaeDetector + model_normal_bae = NormalBaeDetector() + result = model_normal_bae(img) + return remove_pad(result), True + + +def unload_normal_bae(): + global model_normal_bae + if model_normal_bae is not None: + model_normal_bae.unload_model() + + +model_oneformer_coco = None + + +def oneformer_coco(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_oneformer_coco + if model_oneformer_coco is None: + from annotator.oneformer import OneformerDetector + model_oneformer_coco = OneformerDetector(OneformerDetector.configs["coco"]) + result = model_oneformer_coco(img) + return remove_pad(result), True + + +def unload_oneformer_coco(): + global model_oneformer_coco + if model_oneformer_coco is not None: + model_oneformer_coco.unload_model() + + +model_oneformer_ade20k = None + + +def oneformer_ade20k(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_oneformer_ade20k + if model_oneformer_ade20k is None: + from annotator.oneformer import OneformerDetector + model_oneformer_ade20k = OneformerDetector(OneformerDetector.configs["ade20k"]) + result = model_oneformer_ade20k(img) + return remove_pad(result), True + + +def unload_oneformer_ade20k(): + global model_oneformer_ade20k + if model_oneformer_ade20k is not None: + model_oneformer_ade20k.unload_model() + + +model_shuffle = None + + +def shuffle(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + img = remove_pad(img) + global model_shuffle + if model_shuffle is None: + from annotator.shuffle import ContentShuffleDetector + model_shuffle = ContentShuffleDetector() + result = model_shuffle(img) + return result, True + + +def recolor_luminance(img, res=512, thr_a=1.0, **kwargs): + result = cv2.cvtColor(HWC3(img), cv2.COLOR_BGR2LAB) + result = result[:, :, 0].astype(np.float32) / 255.0 + result = result ** thr_a + result = (result * 255.0).clip(0, 255).astype(np.uint8) + result = cv2.cvtColor(result, cv2.COLOR_GRAY2RGB) + return result, True + + +def recolor_intensity(img, res=512, thr_a=1.0, **kwargs): + result = cv2.cvtColor(HWC3(img), cv2.COLOR_BGR2HSV) + result = result[:, :, 2].astype(np.float32) / 255.0 + result = result ** thr_a + result = (result * 255.0).clip(0, 255).astype(np.uint8) + result = cv2.cvtColor(result, cv2.COLOR_GRAY2RGB) + return result, True + + +def blur_gaussian(img, res=512, thr_a=1.0, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + img = remove_pad(img) + result = cv2.GaussianBlur(img, (0, 0), float(thr_a)) + return result, True + + +model_anime_face_segment = None + + +def anime_face_segment(img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_anime_face_segment + if model_anime_face_segment is None: + from annotator.anime_face_segment import AnimeFaceSegment + model_anime_face_segment = AnimeFaceSegment() + + result = model_anime_face_segment(img) + return remove_pad(result), True + + +def unload_anime_face_segment(): + global model_anime_face_segment + if model_anime_face_segment is not None: + model_anime_face_segment.unload_model() + + + +def densepose(img, res=512, cmap="viridis", **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + from annotator.densepose import apply_densepose + result = apply_densepose(img, cmap=cmap) + return remove_pad(result), True + + +def unload_densepose(): + from annotator.densepose import unload_model + unload_model() + +model_te_hed = None + +def te_hed(img, res=512, thr_a=2, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + global model_te_hed + if model_te_hed is None: + from annotator.teed import TEEDDector + model_te_hed = TEEDDector() + result = model_te_hed(img, safe_steps=int(thr_a)) + return remove_pad(result), True + +def unload_te_hed(): + if model_te_hed is not None: + model_te_hed.unload_model() + +class InsightFaceModel: + def __init__(self): + self.model = None + + def load_model(self): + if self.model is None: + from insightface.app import FaceAnalysis + from annotator.annotator_path import models_path + self.model = FaceAnalysis( + name="buffalo_l", + providers=['CUDAExecutionProvider', 'CPUExecutionProvider'], + root=os.path.join(models_path, "insightface"), + ) + self.model.prepare(ctx_id=0, det_size=(640, 640)) + + def run_model(self, imgs: Union[Tuple[np.ndarray], np.ndarray], **kwargs): + self.load_model() + imgs = imgs if isinstance(imgs, tuple) else (imgs,) + faceid_embeds = [] + for i, img in enumerate(imgs): + img = HWC3(img) + faces = self.model.get(img) + if not faces: + logger.warn(f"Insightface: No face found in image {i}.") + continue + if len(faces) > 1: + logger.warn("Insightface: More than one face is detected in the image. " + f"Only the first one will be used {i}.") + faceid_embeds.append(torch.from_numpy(faces[0].normed_embedding).unsqueeze(0)) + return faceid_embeds, False + + +g_insight_face_model = InsightFaceModel() + + +def face_id_plus(img, low_vram=False, **kwargs): + """ FaceID plus uses both face_embeding from insightface and clip_embeding from clip. """ + face_embed, _ = g_insight_face_model.run_model(img) + clip_embed, _ = clip(img, config='clip_h', low_vram=low_vram) + assert len(face_embed) > 0 + return (face_embed[0], clip_embed), False + + +class HandRefinerModel: + def __init__(self): + self.model = None + self.device = devices.get_device_for("controlnet") + + def load_model(self): + if self.model is None: + from annotator.annotator_path import models_path + from hand_refiner import MeshGraphormerDetector # installed via hand_refiner_portable + with Extra(torch_handler): + self.model = MeshGraphormerDetector.from_pretrained( + "hr16/ControlNet-HandRefiner-pruned", + cache_dir=os.path.join(models_path, "hand_refiner"), + device=self.device, + ) + else: + self.model.to(self.device) + + def unload(self): + if self.model is not None: + self.model.to("cpu") + + def run_model(self, img, res=512, **kwargs): + img, remove_pad = resize_image_with_pad(img, res) + self.load_model() + with Extra(torch_handler): + depth_map, mask, info = self.model( + img, output_type="np", + detect_resolution=res, + mask_bbox_padding=30, + ) + return remove_pad(depth_map), True + + +g_hand_refiner_model = HandRefinerModel() + + +model_free_preprocessors = [ + "reference_only", + "reference_adain", + "reference_adain+attn", + "revision_clipvision", + "revision_ignore_prompt" +] + +no_control_mode_preprocessors = [ + "revision_clipvision", + "revision_ignore_prompt", + "clip_vision", + "ip-adapter_clip_sd15", + "ip-adapter_clip_sdxl", + "ip-adapter_clip_sdxl_plus_vith", + "t2ia_style_clipvision", + "ip-adapter_face_id", + "ip-adapter_face_id_plus", +] + +flag_preprocessor_resolution = "Preprocessor Resolution" +preprocessor_sliders_config = { + "none": [], + "inpaint": [], + "inpaint_only": [], + "revision_clipvision": [ + None, + { + "name": "Noise Augmentation", + "value": 0.0, + "min": 0.0, + "max": 1.0 + }, + ], + "revision_ignore_prompt": [ + None, + { + "name": "Noise Augmentation", + "value": 0.0, + "min": 0.0, + "max": 1.0 + }, + ], + "canny": [ + { + "name": flag_preprocessor_resolution, + "value": 512, + "min": 64, + "max": 2048 + }, + { + "name": "Canny Low Threshold", + "value": 100, + "min": 1, + "max": 255 + }, + { + "name": "Canny High Threshold", + "value": 200, + "min": 1, + "max": 255 + }, + ], + "mlsd": [ + { + "name": flag_preprocessor_resolution, + "min": 64, + "max": 2048, + "value": 512 + }, + { + "name": "MLSD Value Threshold", + "min": 0.01, + "max": 2.0, + "value": 0.1, + "step": 0.01 + }, + { + "name": "MLSD Distance Threshold", + "min": 0.01, + "max": 20.0, + "value": 0.1, + "step": 0.01 + } + ], + "hed": [ + { + "name": flag_preprocessor_resolution, + "min": 64, + "max": 2048, + "value": 512 + } + ], + "scribble_hed": [ + { + "name": flag_preprocessor_resolution, + "min": 64, + "max": 2048, + "value": 512 + } + ], + "hed_safe": [ + { + "name": flag_preprocessor_resolution, + "min": 64, + "max": 2048, + "value": 512 + } + ], + "openpose": [ + { + "name": flag_preprocessor_resolution, + "min": 64, + "max": 2048, + "value": 512 + } + ], + "openpose_full": [ + { + "name": flag_preprocessor_resolution, + "min": 64, + "max": 2048, + "value": 512 + } + ], + "dw_openpose_full": [ + { + "name": flag_preprocessor_resolution, + "min": 64, + "max": 2048, + "value": 512 + } + ], + "animal_openpose": [ + { + "name": flag_preprocessor_resolution, + "min": 64, + "max": 2048, + "value": 512 + } + ], + "segmentation": [ + { + "name": flag_preprocessor_resolution, + "min": 64, + "max": 2048, + "value": 512 + } + ], + "depth": [ + { + "name": flag_preprocessor_resolution, + "min": 64, + "max": 2048, + "value": 512 + } + ], + "depth_leres": [ + { + "name": flag_preprocessor_resolution, + "min": 64, + "max": 2048, + "value": 512 + }, + { + "name": "Remove Near %", + "min": 0, + "max": 100, + "value": 0, + "step": 0.1, + }, + { + "name": "Remove Background %", + "min": 0, + "max": 100, + "value": 0, + "step": 0.1, + } + ], + "depth_leres++": [ + { + "name": flag_preprocessor_resolution, + "min": 64, + "max": 2048, + "value": 512 + }, + { + "name": "Remove Near %", + "min": 0, + "max": 100, + "value": 0, + "step": 0.1, + }, + { + "name": "Remove Background %", + "min": 0, + "max": 100, + "value": 0, + "step": 0.1, + } + ], + "normal_map": [ + { + "name": flag_preprocessor_resolution, + "min": 64, + "max": 2048, + "value": 512 + }, + { + "name": "Normal Background Threshold", + "min": 0.0, + "max": 1.0, + "value": 0.4, + "step": 0.01 + } + ], + "threshold": [ + { + "name": flag_preprocessor_resolution, + "value": 512, + "min": 64, + "max": 2048 + }, + { + "name": "Binarization Threshold", + "min": 0, + "max": 255, + "value": 127 + } + ], + + "scribble_xdog": [ + { + "name": flag_preprocessor_resolution, + "value": 512, + "min": 64, + "max": 2048 + }, + { + "name": "XDoG Threshold", + "min": 1, + "max": 64, + "value": 32, + } + ], + "blur_gaussian": [ + { + "name": flag_preprocessor_resolution, + "value": 512, + "min": 64, + "max": 2048 + }, + { + "name": "Sigma", + "min": 0.01, + "max": 64.0, + "value": 9.0, + } + ], + "tile_resample": [ + None, + { + "name": "Down Sampling Rate", + "value": 1.0, + "min": 1.0, + "max": 8.0, + "step": 0.01 + } + ], + "tile_colorfix": [ + None, + { + "name": "Variation", + "value": 8.0, + "min": 3.0, + "max": 32.0, + "step": 1.0 + } + ], + "tile_colorfix+sharp": [ + None, + { + "name": "Variation", + "value": 8.0, + "min": 3.0, + "max": 32.0, + "step": 1.0 + }, + { + "name": "Sharpness", + "value": 1.0, + "min": 0.0, + "max": 2.0, + "step": 0.01 + } + ], + "reference_only": [ + None, + { + "name": r'Style Fidelity (only for "Balanced" mode)', + "value": 0.5, + "min": 0.0, + "max": 1.0, + "step": 0.01 + } + ], + "reference_adain": [ + None, + { + "name": r'Style Fidelity (only for "Balanced" mode)', + "value": 0.5, + "min": 0.0, + "max": 1.0, + "step": 0.01 + } + ], + "reference_adain+attn": [ + None, + { + "name": r'Style Fidelity (only for "Balanced" mode)', + "value": 0.5, + "min": 0.0, + "max": 1.0, + "step": 0.01 + } + ], + "inpaint_only+lama": [], + "color": [ + { + "name": flag_preprocessor_resolution, + "value": 512, + "min": 64, + "max": 2048, + } + ], + "mediapipe_face": [ + { + "name": flag_preprocessor_resolution, + "value": 512, + "min": 64, + "max": 2048, + }, + { + "name": "Max Faces", + "value": 1, + "min": 1, + "max": 10, + "step": 1 + }, + { + "name": "Min Face Confidence", + "value": 0.5, + "min": 0.01, + "max": 1.0, + "step": 0.01 + } + ], + "recolor_luminance": [ + None, + { + "name": "Gamma Correction", + "value": 1.0, + "min": 0.1, + "max": 2.0, + "step": 0.001 + } + ], + "recolor_intensity": [ + None, + { + "name": "Gamma Correction", + "value": 1.0, + "min": 0.1, + "max": 2.0, + "step": 0.001 + } + ], + "anime_face_segment": [ + { + "name": flag_preprocessor_resolution, + "value": 512, + "min": 64, + "max": 2048 + } + ], + "densepose": [ + { + "name": flag_preprocessor_resolution, + "min": 64, + "max": 2048, + "value": 512 + } + ], + "densepose_parula": [ + { + "name": flag_preprocessor_resolution, + "min": 64, + "max": 2048, + "value": 512 + } + ], + "depth_hand_refiner": [ + { + "name": flag_preprocessor_resolution, + "value": 512, + "min": 64, + "max": 2048 + } + ], + "te_hed": [ + { + "name": flag_preprocessor_resolution, + "value": 512, + "min": 64, + "max": 2048 + }, + { + "name": "Safe Steps", + "min": 0, + "max": 10, + "value": 2, + "step": 1, + }, + ], +} + +preprocessor_filters = { + "All": "none", + "Canny": "canny", + "Depth": "depth_midas", + "NormalMap": "normal_bae", + "OpenPose": "openpose_full", + "MLSD": "mlsd", + "Lineart": "lineart_standard (from white bg & black line)", + "SoftEdge": "softedge_pidinet", + "Scribble/Sketch": "scribble_pidinet", + "Segmentation": "seg_ofade20k", + "Shuffle": "shuffle", + "Tile/Blur": "tile_resample", + "Inpaint": "inpaint_only", + "InstructP2P": "none", + "Reference": "reference_only", + "Recolor": "recolor_luminance", + "Revision": "revision_clipvision", + "T2I-Adapter": "none", + "IP-Adapter": "ip-adapter_clip_sd15", +} + +preprocessor_filters_aliases = { + 'instructp2p': ['ip2p'], + 'segmentation': ['seg'], + 'normalmap': ['normal'], + 't2i-adapter': ['t2i_adapter', 't2iadapter', 't2ia'], + 'ip-adapter': ['ip_adapter', 'ipadapter'], + 'scribble/sketch': ['scribble', 'sketch'], + 'tile/blur': ['tile', 'blur'], + 'openpose':['openpose', 'densepose'], +} # must use all lower texts diff --git a/extensions-builtin/sd_forge_controlnet/scripts/utils.py b/extensions-builtin/sd_forge_controlnet/scripts/utils.py new file mode 100644 index 00000000..7cd14aad --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/utils.py @@ -0,0 +1,180 @@ +import torch +import os +import functools +import time +import base64 +import numpy as np +import safetensors.torch +import cv2 +import logging + +from typing import Any, Callable, Dict, List +from modules.safe import unsafe_torch_load +from scripts.logging import logger + + +def load_state_dict(ckpt_path, location="cpu"): + _, extension = os.path.splitext(ckpt_path) + if extension.lower() == ".safetensors": + state_dict = safetensors.torch.load_file(ckpt_path, device=location) + else: + state_dict = unsafe_torch_load(ckpt_path, map_location=torch.device(location)) + state_dict = get_state_dict(state_dict) + logger.info(f"Loaded state_dict from [{ckpt_path}]") + return state_dict + + +def get_state_dict(d): + return d.get("state_dict", d) + + +def ndarray_lru_cache(max_size: int = 128, typed: bool = False): + """ + Decorator to enable caching for functions with numpy array arguments. + Numpy arrays are mutable, and thus not directly usable as hash keys. + + The idea here is to wrap the incoming arguments with type `np.ndarray` + as `HashableNpArray` so that `lru_cache` can correctly handles `np.ndarray` + arguments. + + `HashableNpArray` functions exactly the same way as `np.ndarray` except + having `__hash__` and `__eq__` overriden. + """ + + def decorator(func: Callable): + """The actual decorator that accept function as input.""" + + class HashableNpArray(np.ndarray): + def __new__(cls, input_array): + # Input array is an instance of ndarray. + # The view makes the input array and returned array share the same data. + obj = np.asarray(input_array).view(cls) + return obj + + def __eq__(self, other) -> bool: + return np.array_equal(self, other) + + def __hash__(self): + # Hash the bytes representing the data of the array. + return hash(self.tobytes()) + + @functools.lru_cache(maxsize=max_size, typed=typed) + def cached_func(*args, **kwargs): + """This function only accepts `HashableNpArray` as input params.""" + return func(*args, **kwargs) + + # Preserves original function.__name__ and __doc__. + @functools.wraps(func) + def decorated_func(*args, **kwargs): + """The decorated function that delegates the original function.""" + + def convert_item(item: Any): + if isinstance(item, np.ndarray): + return HashableNpArray(item) + if isinstance(item, tuple): + return tuple(convert_item(i) for i in item) + return item + + args = [convert_item(arg) for arg in args] + kwargs = {k: convert_item(arg) for k, arg in kwargs.items()} + return cached_func(*args, **kwargs) + + return decorated_func + + return decorator + + +def timer_decorator(func): + """Time the decorated function and output the result to debug logger.""" + if logger.level != logging.DEBUG: + return func + + @functools.wraps(func) + def wrapper(*args, **kwargs): + start_time = time.time() + result = func(*args, **kwargs) + end_time = time.time() + duration = end_time - start_time + # Only report function that are significant enough. + if duration > 1e-3: + logger.debug(f"{func.__name__} ran in: {duration:.3f} sec") + return result + + return wrapper + + +class TimeMeta(type): + """ Metaclass to record execution time on all methods of the + child class. """ + def __new__(cls, name, bases, attrs): + for attr_name, attr_value in attrs.items(): + if callable(attr_value): + attrs[attr_name] = timer_decorator(attr_value) + return super().__new__(cls, name, bases, attrs) + + +# svgsupports +svgsupport = False +try: + import io + from svglib.svglib import svg2rlg + from reportlab.graphics import renderPM + + svgsupport = True +except ImportError: + pass + + +def svg_preprocess(inputs: Dict, preprocess: Callable): + if not inputs: + return None + + if inputs["image"].startswith("data:image/svg+xml;base64,") and svgsupport: + svg_data = base64.b64decode( + inputs["image"].replace("data:image/svg+xml;base64,", "") + ) + drawing = svg2rlg(io.BytesIO(svg_data)) + png_data = renderPM.drawToString(drawing, fmt="PNG") + encoded_string = base64.b64encode(png_data) + base64_str = str(encoded_string, "utf-8") + base64_str = "data:image/png;base64," + base64_str + inputs["image"] = base64_str + return preprocess(inputs) + + +def get_unique_axis0(data): + arr = np.asanyarray(data) + idxs = np.lexsort(arr.T) + arr = arr[idxs] + unique_idxs = np.empty(len(arr), dtype=np.bool_) + unique_idxs[:1] = True + unique_idxs[1:] = np.any(arr[:-1, :] != arr[1:, :], axis=-1) + return arr[unique_idxs] + + +def read_image(img_path: str) -> str: + """Read image from specified path and return a base64 string.""" + img = cv2.imread(img_path) + _, bytes = cv2.imencode(".png", img) + encoded_image = base64.b64encode(bytes).decode("utf-8") + return encoded_image + + +def read_image_dir(img_dir: str, suffixes=('.png', '.jpg', '.jpeg', '.webp')) -> List[str]: + """Try read all images in given img_dir.""" + images = [] + for filename in os.listdir(img_dir): + if filename.endswith(suffixes): + img_path = os.path.join(img_dir, filename) + try: + images.append(read_image(img_path)) + except IOError: + logger.error(f"Error opening {img_path}") + return images + + +def align_dim_latent(x: int) -> int: + """ Align the pixel dimension (w/h) to latent dimension. + Stable diffusion 1:8 ratio for latent/pixel, i.e., + 1 latent unit == 8 pixel unit.""" + return (x // 8) * 8 \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/scripts/xyz_grid_support.py b/extensions-builtin/sd_forge_controlnet/scripts/xyz_grid_support.py new file mode 100644 index 00000000..199cf1d0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/scripts/xyz_grid_support.py @@ -0,0 +1,449 @@ +import re +import numpy as np + +from modules import scripts, shared + +try: + from scripts.global_state import update_cn_models, cn_models_names, cn_preprocessor_modules + from scripts.external_code import ResizeMode, ControlMode + +except (ImportError, NameError): + import_error = True +else: + import_error = False + +DEBUG_MODE = False + + +def debug_info(func): + def debug_info_(*args, **kwargs): + if DEBUG_MODE: + print(f"Debug info: {func.__name__}, {args}") + return func(*args, **kwargs) + return debug_info_ + + +def find_dict(dict_list, keyword, search_key="name", stop=False): + result = next((d for d in dict_list if d[search_key] == keyword), None) + if result or not stop: + return result + else: + raise ValueError(f"Dictionary with value '{keyword}' in key '{search_key}' not found.") + + +def flatten(lst): + result = [] + for element in lst: + if isinstance(element, list): + result.extend(flatten(element)) + else: + result.append(element) + return result + + +def is_all_included(target_list, check_list, allow_blank=False, stop=False): + for element in flatten(target_list): + if allow_blank and str(element) in ["None", ""]: + continue + elif element not in check_list: + if not stop: + return False + else: + raise ValueError(f"'{element}' is not included in check list.") + return True + + +class ListParser(): + """This class restores a broken list caused by the following process + in the xyz_grid module. + -> valslist = [x.strip() for x in chain.from_iterable( + csv.reader(StringIO(vals)))] + It also performs type conversion, + adjusts the number of elements in the list, and other operations. + + This class directly modifies the received list. + """ + numeric_pattern = { + int: { + "range": r"\s*([+-]?\s*\d+)\s*-\s*([+-]?\s*\d+)(?:\s*\(([+-]\d+)\s*\))?\s*", + "count": r"\s*([+-]?\s*\d+)\s*-\s*([+-]?\s*\d+)(?:\s*\[(\d+)\s*\])?\s*" + }, + float: { + "range": r"\s*([+-]?\s*\d+(?:\.\d*)?)\s*-\s*([+-]?\s*\d+(?:\.\d*)?)(?:\s*\(([+-]\d+(?:\.\d*)?)\s*\))?\s*", + "count": r"\s*([+-]?\s*\d+(?:\.\d*)?)\s*-\s*([+-]?\s*\d+(?:\.\d*)?)(?:\s*\[(\d+(?:\.\d*)?)\s*\])?\s*" + } + } + + ################################################ + # + # Initialization method from here. + # + ################################################ + + def __init__(self, my_list, converter=None, allow_blank=True, exclude_list=None, run=True): + self.my_list = my_list + self.converter = converter + self.allow_blank = allow_blank + self.exclude_list = exclude_list + self.re_bracket_start = None + self.re_bracket_start_precheck = None + self.re_bracket_end = None + self.re_bracket_end_precheck = None + self.re_range = None + self.re_count = None + self.compile_regex() + if run: + self.auto_normalize() + + def compile_regex(self): + exclude_pattern = "|".join(self.exclude_list) if self.exclude_list else None + if exclude_pattern is None: + self.re_bracket_start = re.compile(r"^\[") + self.re_bracket_end = re.compile(r"\]$") + else: + self.re_bracket_start = re.compile(fr"^\[(?!(?:{exclude_pattern})\])") + self.re_bracket_end = re.compile(fr"(? valslist = [opt.type(x) for x in valslist] + # Perform type conversion using the function + # set to the confirm attribute instead. + # + def identity(x): + return x + + def enable_script_control(): + shared.opts.data["control_net_allow_script_control"] = True + + def apply_field(field): + @debug_info + def apply_field_(p, x, xs): + enable_script_control() + setattr(p, field, x) + + return apply_field_ + + ################################################ + # The confirm function defined in this module + # enables list notation and performs type conversion. + # + # Example: + # any = [any, any, any, ...] + # [any] = [any, None, None, ...] + # [None, None, any] = [None, None, any] + # [,,any] = [None, None, any] + # any, [,any,] = [any, any, any, ...], [None, any, None] + # + # Enabled Only: + # any = [any] = [any, None, None, ...] + # (any and [any] are considered equivalent) + # + def confirm(func_or_str): + @debug_info + def confirm_(p, xs): + if callable(func_or_str): # func_or_str is converter + ListParser(xs, func_or_str, allow_blank=True) + return + + elif isinstance(func_or_str, str): # func_or_str is keyword + valid_data = find_dict(validation_data, func_or_str, stop=True) + converter = valid_data["type"] + exclude_list = valid_data["exclude"]() if valid_data["exclude"] else None + check_list = valid_data["check"]() + + ListParser(xs, converter, allow_blank=True, exclude_list=exclude_list) + is_all_included(xs, check_list, allow_blank=True, stop=True) + return + + else: + raise TypeError(f"Argument must be callable or str, not {type(func_or_str).__name__}.") + + return confirm_ + + def bool_(string): + string = str(string) + if string in ["None", ""]: + return None + elif string.lower() in ["true", "1"]: + return True + elif string.lower() in ["false", "0"]: + return False + else: + raise ValueError(f"Could not convert string to boolean: {string}") + + def choices_bool(): + return ["False", "True"] + + def choices_model(): + update_cn_models() + return list(cn_models_names.values()) + + def choices_control_mode(): + return [e.value for e in ControlMode] + + def choices_resize_mode(): + return [e.value for e in ResizeMode] + + def choices_preprocessor(): + return list(cn_preprocessor_modules) + + def make_excluded_list(): + pattern = re.compile(r"\[(\w+)\]") + return [match.group(1) for s in choices_model() + for match in pattern.finditer(s)] + + validation_data = [ + {"name": "model", "type": str, "check": choices_model, "exclude": make_excluded_list}, + {"name": "control_mode", "type": str, "check": choices_control_mode, "exclude": None}, + {"name": "resize_mode", "type": str, "check": choices_resize_mode, "exclude": None}, + {"name": "preprocessor", "type": str, "check": choices_preprocessor, "exclude": None}, + ] + + extra_axis_options = [ + xyz_grid.AxisOption("[ControlNet] Enabled", identity, apply_field("control_net_enabled"), confirm=confirm(bool_), choices=choices_bool), + xyz_grid.AxisOption("[ControlNet] Model", identity, apply_field("control_net_model"), confirm=confirm("model"), choices=choices_model, cost=0.9), + xyz_grid.AxisOption("[ControlNet] Weight", identity, apply_field("control_net_weight"), confirm=confirm(float)), + xyz_grid.AxisOption("[ControlNet] Guidance Start", identity, apply_field("control_net_guidance_start"), confirm=confirm(float)), + xyz_grid.AxisOption("[ControlNet] Guidance End", identity, apply_field("control_net_guidance_end"), confirm=confirm(float)), + xyz_grid.AxisOption("[ControlNet] Control Mode", identity, apply_field("control_net_control_mode"), confirm=confirm("control_mode"), choices=choices_control_mode), + xyz_grid.AxisOption("[ControlNet] Resize Mode", identity, apply_field("control_net_resize_mode"), confirm=confirm("resize_mode"), choices=choices_resize_mode), + xyz_grid.AxisOption("[ControlNet] Preprocessor", identity, apply_field("control_net_module"), confirm=confirm("preprocessor"), choices=choices_preprocessor), + xyz_grid.AxisOption("[ControlNet] Pre Resolution", identity, apply_field("control_net_pres"), confirm=confirm(int)), + xyz_grid.AxisOption("[ControlNet] Pre Threshold A", identity, apply_field("control_net_pthr_a"), confirm=confirm(float)), + xyz_grid.AxisOption("[ControlNet] Pre Threshold B", identity, apply_field("control_net_pthr_b"), confirm=confirm(float)), + ] + + xyz_grid.axis_options.extend(extra_axis_options) + + +def run(): + xyz_grid = find_module("xyz_grid.py, xy_grid.py") + if xyz_grid: + add_axis_options(xyz_grid) + + +if not import_error: + run() diff --git a/extensions-builtin/sd_forge_controlnet/style.css b/extensions-builtin/sd_forge_controlnet/style.css new file mode 100644 index 00000000..2e15e8d4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/style.css @@ -0,0 +1,182 @@ +.cnet-modal { + display: none; + /* Hidden by default */ + position: fixed; + /* Stay in place */ + z-index: 2147483647; + /* Sit on top */ + left: 0; + top: 0; + width: 100%; + /* Full width */ + height: 100%; + /* Full height */ + overflow: auto; + /* Enable scroll if needed */ + background-color: rgba(0, 0, 0, 0.4); + /* Black with opacity */ + max-width: none !important; + /* Fix sizing with SD.Next (vladmandic/automatic#2594) */ +} + +.cnet-modal-content { + position: relative; + background-color: var(--background-fill-primary); + margin: 5vh auto; + /* 15% from the top and centered */ + padding: 20px; + border: 1px solid #888; + width: 95%; + height: 90vh; + /* Could be more or less, depending on screen size */ + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); + animation-name: animatetop; + animation-duration: 0.4s; + max-width: none !important; + /* Fix sizing with SD.Next (vladmandic/automatic#2594) */ +} + +.cnet-modal-content iframe { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + border: none; +} + +.cnet-modal-content.alert { + padding: var(--size-5); +} + +.cnet-modal-content.alert ul { + list-style-type: none; +} + +.cnet-modal-close { + color: white !important; + right: 0.25em; + top: 0; + cursor: pointer; + position: absolute; + font-size: 56px; + font-weight: bold; +} + +@keyframes animatetop { + from { + top: -300px; + opacity: 0 + } + + to { + top: 0; + opacity: 1 + } +} + +.cnet-generated-image-control-group, +.cnet-upload-pose { + display: flex; + flex-direction: column; + align-items: flex-end; + + position: absolute; + right: var(--size-2); + bottom: var(--size-2); +} + +/* Gradio button style */ +.cnet-download-pose a, +.cnet-close-preview, +.cnet-edit-pose, +.cnet-upload-pose, +.cnet-photopea-child-trigger { + font-size: x-small !important; + font-weight: bold !important; + padding: 2px !important; + box-shadow: var(--shadow-drop); + border: 1px solid var(--button-secondary-border-color); + border-radius: var(--radius-sm); + background: var(--background-fill-primary); + height: var(--size-5); + color: var(--block-label-text-color) !important; + display: flex; + justify-content: center; + cursor: pointer; +} + +.cnet-download-pose:hover a, +.cnet-close-preview:hover a, +.cnet-edit-pose:hover, +.cnet-upload-pose:hover, +.cnet-photopea-child-trigger:hover { + color: var(--block-label-text-color) !important; +} + +.cnet-unit-active { + color: green !important; + font-weight: bold !important; +} + +.dark .cnet-unit-active { + color: greenyellow !important; +} + +.cnet-badge { + display: inline-block; + padding: 0.25em 0.75em; + font-size: 0.75em; + font-weight: bold; + color: white; + border-radius: 0.5em; + text-align: center; + vertical-align: middle; + margin-left: var(--size-2); +} + +.cnet-badge.primary { + background-color: green; +} + +.cnet-a1111-badge { + position: absolute; + bottom: 0px; + right: 0px; +} + +.cnet-disabled-radio { + opacity: 50%; +} + +.controlnet_row { + margin-top: 10px !important; +} + +/* JSON pose upload button styling */ +.cnet-upload-pose input[type=file] { + position: absolute; + left: 0; + top: 0; + opacity: 0; + width: 100%; + height: 100%; +} + +/* Photopea integration styles */ +.photopea-button-group { + position: absolute; + top: -30px; /* 20px modal padding + 10px margin */ +} + +.photopea-button { + font-size: 3rem; + font-weight: bold; + padding: 2px !important; + margin: 2px !important; + box-shadow: var(--shadow-drop); + border: 1px solid var(--button-secondary-border-color); + border-radius: var(--radius-sm); + background: var(--background-fill-primary); + color: var(--block-label-text-color); +} diff --git a/extensions-builtin/sd_forge_controlnet/tests/README.md b/extensions-builtin/sd_forge_controlnet/tests/README.md new file mode 100644 index 00000000..a8144800 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/README.md @@ -0,0 +1,47 @@ +# Tests +There are 2 types of tests: +- unittest: backend based tests that directly import A1111 shared modules +- api test: test functionality through A1111 web API + +# Run tests locally +Make sure the current working directory is A1111 root. + +## Install test dependencies +`pip install -r requirements-test.txt` + +## Start test server +```shell +python -m coverage run + --data-file=.coverage.server + launch.py + --skip-prepare-environment + --skip-torch-cuda-test + --test-server + --do-not-download-clip + --no-half + --disable-opt-split-attention + --use-cpu all + --api-server-stop +``` + +## Setting environment variables +Setting `CONTROLNET_TEST_SD_VERSION` for stable diffusion model family used during testing. +- 1 for SD1.x +- 2 for SD2.x +- 3 for SDXL + +## Run test +```shell +python -m pytest -vv --junitxml=test/results.xml --cov ./extensions/sd-webui-controlnet --cov-report=xml --verify-base-url ./extensions/sd-webui-controlnet/tests +``` + +## Check code coverage +Text report +```shell +python -m coverage report -i +``` + +HTML report +```shell +python -m coverage html -i +``` \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/tests/annotator_tests/openpose_tests/body_test.py b/extensions-builtin/sd_forge_controlnet/tests/annotator_tests/openpose_tests/body_test.py new file mode 100644 index 00000000..9c52fdfa --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/annotator_tests/openpose_tests/body_test.py @@ -0,0 +1,50 @@ +import unittest +import numpy as np + +import importlib +utils = importlib.import_module('extensions.sd-webui-controlnet.tests.utils', 'utils') + + +from annotator.openpose.body import Body, Keypoint, BodyResult + +class TestFormatBodyResult(unittest.TestCase): + def setUp(self): + self.candidate = np.array([ + [10, 20, 0.9, 0], + [30, 40, 0.8, 1], + [50, 60, 0.7, 2], + [70, 80, 0.6, 3] + ]) + + self.subset = np.array([ + [-1, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1.7, 2], + [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 0.6, 1] + ]) + + def test_format_body_result(self): + expected_result = [ + BodyResult( + keypoints=[ + None, + Keypoint(x=10, y=20, score=0.9, id=0), + Keypoint(x=30, y=40, score=0.8, id=1), + None + ] + [None] * 14, + total_score=1.7, + total_parts=2 + ), + BodyResult( + keypoints=[None] * 17 + [ + Keypoint(x=70, y=80, score=0.6, id=3) + ], + total_score=0.6, + total_parts=1 + ) + ] + + result = Body.format_body_result(self.candidate, self.subset) + + self.assertEqual(result, expected_result) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/tests/annotator_tests/openpose_tests/detection_test.py b/extensions-builtin/sd_forge_controlnet/tests/annotator_tests/openpose_tests/detection_test.py new file mode 100644 index 00000000..44e8c573 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/annotator_tests/openpose_tests/detection_test.py @@ -0,0 +1,109 @@ +import unittest +import numpy as np + +import importlib +utils = importlib.import_module('extensions.sd-webui-controlnet.tests.utils', 'utils') + + +from annotator.openpose.util import faceDetect, handDetect +from annotator.openpose.body import Keypoint, BodyResult + +class TestFaceDetect(unittest.TestCase): + def test_no_faces(self): + oriImg = np.zeros((100, 100, 3), dtype=np.uint8) + body = BodyResult([None] * 18, total_score=3, total_parts=0) + expected_result = None + result = faceDetect(body, oriImg) + + self.assertEqual(result, expected_result) + + def test_single_face(self): + body = BodyResult([ + Keypoint(50, 50), + *([None] * 13), + Keypoint(30, 40), + Keypoint(70, 40), + Keypoint(20, 50), + Keypoint(80, 50), + ], total_score=2, total_parts=5) + + oriImg = np.zeros((100, 100, 3), dtype=np.uint8) + + expected_result = (0, 0, 120) + result = faceDetect(body, oriImg) + + self.assertEqual(result, expected_result) + +class TestHandDetect(unittest.TestCase): + def test_no_hands(self): + oriImg = np.zeros((100, 100, 3), dtype=np.uint8) + body = BodyResult([None] * 18, total_score=3, total_parts=0) + expected_result = [] + result = handDetect(body, oriImg) + + self.assertEqual(result, expected_result) + + def test_single_left_hand(self): + oriImg = np.zeros((100, 100, 3), dtype=np.uint8) + + body = BodyResult([ + None, None, None, None, None, + Keypoint(20, 20), + Keypoint(40, 30), + Keypoint(60, 40), + *([None] * 8), + Keypoint(20, 60), + Keypoint(40, 70), + Keypoint(60, 80) + ], total_score=3, total_parts=0.5) + + expected_result = [(49, 26, 33, True)] + result = handDetect(body, oriImg) + + self.assertEqual(result, expected_result) + + def test_single_right_hand(self): + oriImg = np.zeros((100, 100, 3), dtype=np.uint8) + + body = BodyResult([ + None, None, + Keypoint(20, 20), + Keypoint(40, 30), + Keypoint(60, 40), + *([None] * 11), + Keypoint(20, 60), + Keypoint(40, 70), + Keypoint(60, 80) + ], total_score=3, total_parts=0.5) + + expected_result = [(49, 26, 33, False)] + result = handDetect(body, oriImg) + + self.assertEqual(result, expected_result) + + def test_multiple_hands(self): + body = BodyResult([ + Keypoint(20, 20), + Keypoint(40, 30), + Keypoint(60, 40), + Keypoint(20, 60), + Keypoint(40, 70), + Keypoint(60, 80), + Keypoint(10, 10), + Keypoint(30, 20), + Keypoint(50, 30), + Keypoint(10, 50), + Keypoint(30, 60), + Keypoint(50, 70), + *([None] * 6), + ], total_score=3, total_parts=0.5) + + oriImg = np.zeros((100, 100, 3), dtype=np.uint8) + + expected_result = [(0, 0, 100, True), (16, 43, 56, False)] + result = handDetect(body, oriImg) + self.assertEqual(result, expected_result) + + +if __name__ == '__main__': + unittest.main() diff --git a/extensions-builtin/sd_forge_controlnet/tests/annotator_tests/openpose_tests/json_encode_test.py b/extensions-builtin/sd_forge_controlnet/tests/annotator_tests/openpose_tests/json_encode_test.py new file mode 100644 index 00000000..6554aaee --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/annotator_tests/openpose_tests/json_encode_test.py @@ -0,0 +1,83 @@ +import unittest +import numpy as np + +import importlib +utils = importlib.import_module('extensions.sd-webui-controlnet.tests.utils', 'utils') + + +from annotator.openpose import encode_poses_as_json, HumanPoseResult, Keypoint +from annotator.openpose.body import BodyResult + +class TestEncodePosesAsJson(unittest.TestCase): + def test_empty_list(self): + poses = [] + canvas_height = 1080 + canvas_width = 1920 + result = encode_poses_as_json(poses, [], canvas_height, canvas_width) + expected = { + 'people': [], + 'animals': [], + 'canvas_height': canvas_height, + 'canvas_width': canvas_width, + } + self.assertDictEqual(result, expected) + + def test_single_pose_no_keypoints(self): + poses = [HumanPoseResult(BodyResult(None, 0, 0), None, None, None)] + canvas_height = 1080 + canvas_width = 1920 + result = encode_poses_as_json(poses, [],canvas_height, canvas_width) + expected = { + 'people': [ + { + 'pose_keypoints_2d': None, + 'face_keypoints_2d': None, + 'hand_left_keypoints_2d': None, + 'hand_right_keypoints_2d': None, + }, + ], + 'animals': [], + 'canvas_height': canvas_height, + 'canvas_width': canvas_width, + } + self.assertDictEqual(result, expected) + + def test_single_pose_with_keypoints(self): + keypoints = [Keypoint(np.float32(0.5), np.float32(0.5)), None, Keypoint(0.6, 0.6)] + poses = [HumanPoseResult(BodyResult(keypoints, 0, 0), keypoints, keypoints, keypoints)] + canvas_height = 1080 + canvas_width = 1920 + result = encode_poses_as_json(poses, [], canvas_height, canvas_width) + expected = { + 'people': [ + { + 'pose_keypoints_2d': [ + 0.5, 0.5, 1.0, + 0.0, 0.0, 0.0, + 0.6, 0.6, 1.0, + ], + 'face_keypoints_2d': [ + 0.5, 0.5, 1.0, + 0.0, 0.0, 0.0, + 0.6, 0.6, 1.0, + ], + 'hand_left_keypoints_2d': [ + 0.5, 0.5, 1.0, + 0.0, 0.0, 0.0, + 0.6, 0.6, 1.0, + ], + 'hand_right_keypoints_2d': [ + 0.5, 0.5, 1.0, + 0.0, 0.0, 0.0, + 0.6, 0.6, 1.0, + ], + }, + ], + 'animals': [], + 'canvas_height': canvas_height, + 'canvas_width': canvas_width, + } + self.assertDictEqual(result, expected) + +if __name__ == '__main__': + unittest.main() diff --git a/extensions-builtin/sd_forge_controlnet/tests/annotator_tests/openpose_tests/openpose_e2e_test_disabled.py b/extensions-builtin/sd_forge_controlnet/tests/annotator_tests/openpose_tests/openpose_e2e_test_disabled.py new file mode 100644 index 00000000..682c7ffd --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/annotator_tests/openpose_tests/openpose_e2e_test_disabled.py @@ -0,0 +1,115 @@ +""" +Disabled because unloading openpose detection models is flaky. +See https://github.com/Mikubill/sd-webui-controlnet/actions/runs/6758718106/job/18370634881 +for CI report of an example flaky run. +""" + +import unittest +import cv2 +import numpy as np +from pathlib import Path +from typing import Dict + + +import importlib +utils = importlib.import_module('extensions.sd-webui-controlnet.tests.utils', 'utils') + + +from annotator.openpose import OpenposeDetector + +class TestOpenposeDetector(unittest.TestCase): + image_path = str(Path(__file__).parent.parent.parent / 'images') + def setUp(self) -> None: + self.detector = OpenposeDetector() + self.detector.load_model() + + def tearDown(self) -> None: + self.detector.unload_model() + + def expect_same_image(self, img1, img2, diff_img_path: str): + # Calculate the difference between the two images + diff = cv2.absdiff(img1, img2) + + # Set a threshold to highlight the different pixels + threshold = 30 + diff_highlighted = np.where(diff > threshold, 255, 0).astype(np.uint8) + + # Assert that the two images are similar within a tolerance + similar = np.allclose(img1, img2, rtol=1e-05, atol=1e-08) + if not similar: + # Save the diff_highlighted image to inspect the differences + cv2.imwrite(diff_img_path, cv2.cvtColor(diff_highlighted, cv2.COLOR_RGB2BGR)) + + self.assertTrue(similar) + + # Save expectation image as png so that no compression issue happens. + def template(self, test_image: str, expected_image: str, detector_config: Dict, overwrite_expectation: bool = False): + oriImg = cv2.cvtColor(cv2.imread(test_image), cv2.COLOR_BGR2RGB) + canvas = self.detector(oriImg, **detector_config) + + # Create expectation file + if overwrite_expectation: + cv2.imwrite(expected_image, cv2.cvtColor(canvas, cv2.COLOR_RGB2BGR)) + else: + expected_canvas = cv2.cvtColor(cv2.imread(expected_image), cv2.COLOR_BGR2RGB) + self.expect_same_image(canvas, expected_canvas, diff_img_path=expected_image.replace('.png', '_diff.png')) + + def test_body(self): + self.template( + test_image = f'{TestOpenposeDetector.image_path}/ski.jpg', + expected_image = f'{TestOpenposeDetector.image_path}/expected_ski_output.png', + detector_config=dict(), + overwrite_expectation=False + ) + + def test_hand(self): + self.template( + test_image = f'{TestOpenposeDetector.image_path}/woman.jpeg', + expected_image = f'{TestOpenposeDetector.image_path}/expected_woman_hand_output.png', + detector_config=dict( + include_body=False, + include_face=False, + include_hand=True, + ), + overwrite_expectation=False + ) + + def test_face(self): + self.template( + test_image = f'{TestOpenposeDetector.image_path}/woman.jpeg', + expected_image = f'{TestOpenposeDetector.image_path}/expected_woman_face_output.png', + detector_config=dict( + include_body=False, + include_face=True, + include_hand=False, + ), + overwrite_expectation=False + ) + + def test_all(self): + self.template( + test_image = f'{TestOpenposeDetector.image_path}/woman.jpeg', + expected_image = f'{TestOpenposeDetector.image_path}/expected_woman_all_output.png', + detector_config=dict( + include_body=True, + include_face=True, + include_hand=True, + ), + overwrite_expectation=False + ) + + def test_dw(self): + self.template( + test_image = f'{TestOpenposeDetector.image_path}/woman.jpeg', + expected_image = f'{TestOpenposeDetector.image_path}/expected_woman_dw_all_output.png', + detector_config=dict( + include_body=True, + include_face=True, + include_hand=True, + use_dw_pose=True, + ), + overwrite_expectation=False, + ) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/tests/cn_script/__init__.py b/extensions-builtin/sd_forge_controlnet/tests/cn_script/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/extensions-builtin/sd_forge_controlnet/tests/cn_script/batch_hijack_test.py b/extensions-builtin/sd_forge_controlnet/tests/cn_script/batch_hijack_test.py new file mode 100644 index 00000000..0f68fe5b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/cn_script/batch_hijack_test.py @@ -0,0 +1,337 @@ +import unittest.mock +import importlib +from typing import Any + +utils = importlib.import_module('extensions.sd-webui-controlnet.tests.utils', 'utils') + + +from modules import processing, scripts, shared +from scripts import controlnet, external_code, batch_hijack + + +batch_hijack.instance.undo_hijack() +original_process_images_inner = processing.process_images_inner + + +class TestBatchHijack(unittest.TestCase): + @unittest.mock.patch('modules.script_callbacks.on_script_unloaded') + def setUp(self, on_script_unloaded_mock): + self.on_script_unloaded_mock = on_script_unloaded_mock + + self.batch_hijack_object = batch_hijack.BatchHijack() + self.batch_hijack_object.do_hijack() + + def tearDown(self): + self.batch_hijack_object.undo_hijack() + + def test_do_hijack__registers_on_script_unloaded(self): + self.on_script_unloaded_mock.assert_called_once_with(self.batch_hijack_object.undo_hijack) + + def test_do_hijack__call_once__hijacks_once(self): + self.assertEqual(getattr(processing, '__controlnet_original_process_images_inner'), original_process_images_inner) + self.assertEqual(processing.process_images_inner, self.batch_hijack_object.processing_process_images_hijack) + + @unittest.mock.patch('modules.processing.__controlnet_original_process_images_inner') + def test_do_hijack__multiple_times__hijacks_once(self, process_images_inner_mock): + self.batch_hijack_object.do_hijack() + self.batch_hijack_object.do_hijack() + self.batch_hijack_object.do_hijack() + self.assertEqual(process_images_inner_mock, getattr(processing, '__controlnet_original_process_images_inner')) + + +class TestGetControlNetBatchesWorks(unittest.TestCase): + def setUp(self): + self.p = unittest.mock.MagicMock() + assert scripts.scripts_txt2img is not None + self.p.scripts = scripts.scripts_txt2img + self.cn_script = controlnet.Script() + self.p.scripts.alwayson_scripts = [self.cn_script] + self.p.script_args = [] + + def tearDown(self): + batch_hijack.instance.dispatch_callbacks(batch_hijack.instance.postprocess_batch_callbacks, self.p) + + def assert_get_cn_batches_works(self, batch_images_list): + self.cn_script.args_from = 0 + self.cn_script.args_to = self.cn_script.args_from + len(self.p.script_args) + + is_cn_batch, batches, output_dir, _ = batch_hijack.get_cn_batches(self.p) + batch_hijack.instance.dispatch_callbacks(batch_hijack.instance.process_batch_callbacks, self.p, batches, output_dir) + + batch_units = [unit for unit in self.p.script_args if getattr(unit, 'input_mode', batch_hijack.InputMode.SIMPLE) == batch_hijack.InputMode.BATCH] + if batch_units: + self.assertEqual(min(len(list(unit.batch_images)) for unit in batch_units), len(batches)) + else: + self.assertEqual(1, len(batches)) + + for i, unit in enumerate(self.cn_script.enabled_units): + self.assertListEqual(batch_images_list[i], list(unit.batch_images)) + + def test_get_cn_batches__empty(self): + is_batch, batches, _, _ = batch_hijack.get_cn_batches(self.p) + self.assertEqual(1, len(batches)) + self.assertEqual(is_batch, False) + + def test_get_cn_batches__1_simple(self): + self.p.script_args.append(external_code.ControlNetUnit(image=get_dummy_image())) + self.assert_get_cn_batches_works([ + [self.p.script_args[0].image], + ]) + + def test_get_cn_batches__2_simples(self): + self.p.script_args.extend([ + external_code.ControlNetUnit(image=get_dummy_image(0)), + external_code.ControlNetUnit(image=get_dummy_image(1)), + ]) + self.assert_get_cn_batches_works([ + [get_dummy_image(0)], + [get_dummy_image(1)], + ]) + + def test_get_cn_batches__1_batch(self): + self.p.script_args.extend([ + controlnet.UiControlNetUnit( + input_mode=batch_hijack.InputMode.BATCH, + batch_images=[ + get_dummy_image(0), + get_dummy_image(1), + ], + ), + ]) + self.assert_get_cn_batches_works([ + [ + get_dummy_image(0), + get_dummy_image(1), + ], + ]) + + def test_get_cn_batches__2_batches(self): + self.p.script_args.extend([ + controlnet.UiControlNetUnit( + input_mode=batch_hijack.InputMode.BATCH, + batch_images=[ + get_dummy_image(0), + get_dummy_image(1), + ], + ), + controlnet.UiControlNetUnit( + input_mode=batch_hijack.InputMode.BATCH, + batch_images=[ + get_dummy_image(2), + get_dummy_image(3), + ], + ), + ]) + self.assert_get_cn_batches_works([ + [ + get_dummy_image(0), + get_dummy_image(1), + ], + [ + get_dummy_image(2), + get_dummy_image(3), + ], + ]) + + def test_get_cn_batches__2_mixed(self): + self.p.script_args.extend([ + external_code.ControlNetUnit(image=get_dummy_image(0)), + controlnet.UiControlNetUnit( + input_mode=batch_hijack.InputMode.BATCH, + batch_images=[ + get_dummy_image(1), + get_dummy_image(2), + ], + ), + ]) + self.assert_get_cn_batches_works([ + [ + get_dummy_image(0), + get_dummy_image(0), + ], + [ + get_dummy_image(1), + get_dummy_image(2), + ], + ]) + + def test_get_cn_batches__3_mixed(self): + self.p.script_args.extend([ + external_code.ControlNetUnit(image=get_dummy_image(0)), + controlnet.UiControlNetUnit( + input_mode=batch_hijack.InputMode.BATCH, + batch_images=[ + get_dummy_image(1), + get_dummy_image(2), + get_dummy_image(3), + ], + ), + controlnet.UiControlNetUnit( + input_mode=batch_hijack.InputMode.BATCH, + batch_images=[ + get_dummy_image(4), + get_dummy_image(5), + ], + ), + ]) + self.assert_get_cn_batches_works([ + [ + get_dummy_image(0), + get_dummy_image(0), + ], + [ + get_dummy_image(1), + get_dummy_image(2), + ], + [ + get_dummy_image(4), + get_dummy_image(5), + ], + ]) + +class TestProcessImagesPatchWorks(unittest.TestCase): + @unittest.mock.patch('modules.script_callbacks.on_script_unloaded') + def setUp(self, on_script_unloaded_mock): + self.on_script_unloaded_mock = on_script_unloaded_mock + self.p = unittest.mock.MagicMock() + assert scripts.scripts_txt2img is not None + self.p.scripts = scripts.scripts_txt2img + self.cn_script = controlnet.Script() + self.p.scripts.alwayson_scripts = [self.cn_script] + self.p.script_args = [] + self.p.all_seeds = [0] + self.p.all_subseeds = [0] + self.old_model, shared.sd_model = shared.sd_model, unittest.mock.MagicMock() + + self.batch_hijack_object = batch_hijack.BatchHijack() + self.callbacks_mock = unittest.mock.MagicMock() + self.batch_hijack_object.process_batch_callbacks.append(self.callbacks_mock.process) + self.batch_hijack_object.process_batch_each_callbacks.append(self.callbacks_mock.process_each) + self.batch_hijack_object.postprocess_batch_each_callbacks.insert(0, self.callbacks_mock.postprocess_each) + self.batch_hijack_object.postprocess_batch_callbacks.insert(0, self.callbacks_mock.postprocess) + self.batch_hijack_object.do_hijack() + shared.state.begin() + + def tearDown(self): + shared.state.end() + self.batch_hijack_object.undo_hijack() + shared.sd_model = self.old_model + + @unittest.mock.patch('modules.processing.__controlnet_original_process_images_inner') + def assert_process_images_hijack_called(self, process_images_mock, batch_count): + process_images_mock.return_value = processing.Processed(self.p, [get_dummy_image('output')]) + with unittest.mock.patch.dict(shared.opts.data, { + 'controlnet_show_batch_images_in_ui': True, + }): + res = processing.process_images_inner(self.p) + + self.assertEqual(res, process_images_mock.return_value) + + if batch_count > 0: + self.callbacks_mock.process.assert_called() + self.callbacks_mock.postprocess.assert_called() + else: + self.callbacks_mock.process.assert_not_called() + self.callbacks_mock.postprocess.assert_not_called() + + self.assertEqual(self.callbacks_mock.process_each.call_count, batch_count) + self.assertEqual(self.callbacks_mock.postprocess_each.call_count, batch_count) + + def test_process_images_no_units_forwards(self): + self.assert_process_images_hijack_called(batch_count=0) + + def test_process_images__only_simple_units__forwards(self): + self.p.script_args = [ + external_code.ControlNetUnit(image=get_dummy_image()), + external_code.ControlNetUnit(image=get_dummy_image()), + ] + self.assert_process_images_hijack_called(batch_count=0) + + def test_process_images__1_batch_1_unit__runs_1_batch(self): + self.p.script_args = [ + controlnet.UiControlNetUnit( + input_mode=batch_hijack.InputMode.BATCH, + batch_images=[ + get_dummy_image(), + ], + ), + ] + self.assert_process_images_hijack_called(batch_count=1) + + def test_process_images__2_batches_1_unit__runs_2_batches(self): + self.p.script_args = [ + controlnet.UiControlNetUnit( + input_mode=batch_hijack.InputMode.BATCH, + batch_images=[ + get_dummy_image(0), + get_dummy_image(1), + ], + ), + ] + self.assert_process_images_hijack_called(batch_count=2) + + def test_process_images__8_batches_1_unit__runs_8_batches(self): + batch_count = 8 + self.p.script_args = [ + controlnet.UiControlNetUnit( + input_mode=batch_hijack.InputMode.BATCH, + batch_images=[get_dummy_image(i) for i in range(batch_count)] + ), + ] + self.assert_process_images_hijack_called(batch_count=batch_count) + + def test_process_images__1_batch_2_units__runs_1_batch(self): + self.p.script_args = [ + controlnet.UiControlNetUnit( + input_mode=batch_hijack.InputMode.BATCH, + batch_images=[get_dummy_image(0)] + ), + controlnet.UiControlNetUnit( + input_mode=batch_hijack.InputMode.BATCH, + batch_images=[get_dummy_image(1)] + ), + ] + self.assert_process_images_hijack_called(batch_count=1) + + def test_process_images__2_batches_2_units__runs_2_batches(self): + self.p.script_args = [ + controlnet.UiControlNetUnit( + input_mode=batch_hijack.InputMode.BATCH, + batch_images=[ + get_dummy_image(0), + get_dummy_image(1), + ], + ), + controlnet.UiControlNetUnit( + input_mode=batch_hijack.InputMode.BATCH, + batch_images=[ + get_dummy_image(2), + get_dummy_image(3), + ], + ), + ] + self.assert_process_images_hijack_called(batch_count=2) + + def test_process_images__3_batches_2_mixed_units__runs_3_batches(self): + self.p.script_args = [ + controlnet.UiControlNetUnit( + input_mode=batch_hijack.InputMode.BATCH, + batch_images=[ + get_dummy_image(0), + get_dummy_image(1), + get_dummy_image(2), + ], + ), + controlnet.UiControlNetUnit( + input_mode=batch_hijack.InputMode.SIMPLE, + image=get_dummy_image(3), + ), + ] + self.assert_process_images_hijack_called(batch_count=3) + + +def get_dummy_image(name: Any = 0): + return f'base64#{name}...' + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/tests/cn_script/cn_script_test.py b/extensions-builtin/sd_forge_controlnet/tests/cn_script/cn_script_test.py new file mode 100644 index 00000000..ecaf74c8 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/cn_script/cn_script_test.py @@ -0,0 +1,184 @@ +from typing import Any, Dict, List +import unittest +from PIL import Image +import numpy as np + +import importlib + +utils = importlib.import_module("extensions.sd-webui-controlnet.tests.utils", "utils") + + +from scripts import external_code, processor +from scripts.controlnet import prepare_mask, Script, set_numpy_seed +from modules import processing + + +class TestPrepareMask(unittest.TestCase): + def test_prepare_mask(self): + p = processing.StableDiffusionProcessing() + p.inpainting_mask_invert = True + p.mask_blur = 5 + + mask = Image.new("RGB", (10, 10), color="white") + + processed_mask = prepare_mask(mask, p) + + # Check that mask is correctly converted to grayscale + self.assertTrue(processed_mask.mode, "L") + + # Check that mask colors are correctly inverted + self.assertEqual( + processed_mask.getpixel((0, 0)), 0 + ) # inverted white should be black + + p.inpainting_mask_invert = False + processed_mask = prepare_mask(mask, p) + + # Check that mask colors are not inverted when 'inpainting_mask_invert' is False + self.assertEqual( + processed_mask.getpixel((0, 0)), 255 + ) # white should remain white + + p.mask_blur = 0 + mask = Image.new("RGB", (10, 10), color="black") + processed_mask = prepare_mask(mask, p) + + # Check that mask is not blurred when 'mask_blur' is 0 + self.assertEqual( + processed_mask.getpixel((0, 0)), 0 + ) # black should remain black + + +class TestSetNumpySeed(unittest.TestCase): + def test_seed_subseed_minus_one(self): + p = processing.StableDiffusionProcessing() + p.seed = -1 + p.subseed = -1 + p.all_seeds = [123, 456] + expected_seed = (123 + 123) & 0xFFFFFFFF + self.assertEqual(set_numpy_seed(p), expected_seed) + + def test_valid_seed_subseed(self): + p = processing.StableDiffusionProcessing() + p.seed = 50 + p.subseed = 100 + p.all_seeds = [123, 456] + expected_seed = (50 + 100) & 0xFFFFFFFF + self.assertEqual(set_numpy_seed(p), expected_seed) + + def test_invalid_seed_subseed(self): + p = processing.StableDiffusionProcessing() + p.seed = "invalid" + p.subseed = 2.5 + p.all_seeds = [123, 456] + self.assertEqual(set_numpy_seed(p), None) + + def test_empty_all_seeds(self): + p = processing.StableDiffusionProcessing() + p.seed = -1 + p.subseed = 2 + p.all_seeds = [] + self.assertEqual(set_numpy_seed(p), None) + + def test_random_state_change(self): + p = processing.StableDiffusionProcessing() + p.seed = 50 + p.subseed = 100 + p.all_seeds = [123, 456] + expected_seed = (50 + 100) & 0xFFFFFFFF + + np.random.seed(0) # set a known seed + before_random = np.random.randint(0, 1000) # get a random integer + + seed = set_numpy_seed(p) + self.assertEqual(seed, expected_seed) + + after_random = np.random.randint(0, 1000) # get another random integer + + self.assertNotEqual(before_random, after_random) + + +class MockImg2ImgProcessing(processing.StableDiffusionProcessing): + """Mock the Img2Img processing as the WebUI version have dependency on + `sd_model`.""" + + def __init__(self, init_images, resize_mode, *args, **kwargs): + super().__init__(*args, **kwargs) + self.init_images = init_images + self.resize_mode = resize_mode + + +class TestScript(unittest.TestCase): + sample_base64_image = ( + "data:image/png;base64," + "iVBORw0KGgoAAAANSUhEUgAAARMAAAC3CAIAAAC+MS2jAAAAqUlEQVR4nO3BAQ" + "0AAADCoPdPbQ8HFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAA/wZOlAAB5tU+nAAAAABJRU5ErkJggg==" + ) + + sample_np_image = np.array( + [[100, 200, 50], [150, 75, 225], [30, 120, 180]], dtype=np.uint8 + ) + + def test_bound_check_params(self): + def param_required(module: str, param: str) -> bool: + configs = processor.preprocessor_sliders_config[module] + config_index = ("processor_res", "threshold_a", "threshold_b").index(param) + return config_index < len(configs) and configs[config_index] is not None + + for module in processor.preprocessor_sliders_config.keys(): + for param in ("processor_res", "threshold_a", "threshold_b"): + with self.subTest(param=param, module=module): + unit = external_code.ControlNetUnit( + module=module, + **{param: -100}, + ) + Script.bound_check_params(unit) + if param_required(module, param): + self.assertGreaterEqual(getattr(unit, param), 0) + else: + self.assertEqual(getattr(unit, param), -100) + + def test_choose_input_image(self): + with self.subTest(name="no image"): + with self.assertRaises(ValueError): + Script.choose_input_image( + p=processing.StableDiffusionProcessing(), + unit=external_code.ControlNetUnit(), + idx=0, + ) + + with self.subTest(name="control net input"): + _, resize_mode = Script.choose_input_image( + p=MockImg2ImgProcessing( + init_images=[TestScript.sample_np_image], + resize_mode=external_code.ResizeMode.OUTER_FIT, + ), + unit=external_code.ControlNetUnit( + image=TestScript.sample_base64_image, + module="none", + resize_mode=external_code.ResizeMode.INNER_FIT, + ), + idx=0, + ) + self.assertEqual(resize_mode, external_code.ResizeMode.INNER_FIT) + + with self.subTest(name="A1111 input"): + _, resize_mode = Script.choose_input_image( + p=MockImg2ImgProcessing( + init_images=[TestScript.sample_np_image], + resize_mode=external_code.ResizeMode.OUTER_FIT, + ), + unit=external_code.ControlNetUnit( + module="none", + resize_mode=external_code.ResizeMode.INNER_FIT, + ), + idx=0, + ) + self.assertEqual(resize_mode, external_code.ResizeMode.OUTER_FIT) + + +if __name__ == "__main__": + unittest.main() diff --git a/extensions-builtin/sd_forge_controlnet/tests/cn_script/global_state_test.py b/extensions-builtin/sd_forge_controlnet/tests/cn_script/global_state_test.py new file mode 100644 index 00000000..4c3f4741 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/cn_script/global_state_test.py @@ -0,0 +1,67 @@ +import importlib +utils = importlib.import_module("extensions.sd-webui-controlnet.tests.utils", "utils") + +from scripts.global_state import select_control_type, ui_preprocessor_keys +from scripts.enums import StableDiffusionVersion + + +dummy_value = "dummy" +cn_models = { + "None": dummy_value, + "canny_sd15": dummy_value, + "canny_sdxl": dummy_value, +} + + +# Tests for the select_control_type function +class TestSelectControlType: + def test_all_control_type(self): + result = select_control_type("All", cn_models=cn_models) + assert result == ( + [ui_preprocessor_keys, list(cn_models.keys()), "none", "None"] + ), "Expected all preprocessors and models" + + def test_sd_version(self): + (_, filtered_model_list, _, default_model) = select_control_type( + "Canny", sd_version=StableDiffusionVersion.UNKNOWN, cn_models=cn_models + ) + assert filtered_model_list == [ + "None", + "canny_sd15", + "canny_sdxl", + ], "UNKNOWN sd version should match all models" + assert default_model == "canny_sd15" + + (_, filtered_model_list, _, default_model) = select_control_type( + "Canny", sd_version=StableDiffusionVersion.SD1x, cn_models=cn_models + ) + assert filtered_model_list == [ + "None", + "canny_sd15", + ], "sd1x version should only sd1x" + assert default_model == "canny_sd15" + + (_, filtered_model_list, _, default_model) = select_control_type( + "Canny", sd_version=StableDiffusionVersion.SDXL, cn_models=cn_models + ) + assert filtered_model_list == [ + "None", + "canny_sdxl", + ], "sdxl version should only sdxl" + assert default_model == "canny_sdxl" + + def test_invert_preprocessor(self): + for control_type in ("Canny", "Lineart", "Scribble/Sketch", "MLSD"): + filtered_preprocessor_list, _, _, _ = select_control_type( + control_type, cn_models=cn_models + ) + assert any( + "invert" in module.lower() for module in filtered_preprocessor_list + ) + + def test_no_module_available(self): + (_, filtered_model_list, _, default_model) = select_control_type( + "Depth", cn_models=cn_models + ) + assert filtered_model_list == ["None"] + assert default_model == "None" diff --git a/extensions-builtin/sd_forge_controlnet/tests/cn_script/infotext_test.py b/extensions-builtin/sd_forge_controlnet/tests/cn_script/infotext_test.py new file mode 100644 index 00000000..61a7002e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/cn_script/infotext_test.py @@ -0,0 +1,34 @@ +import unittest +import importlib + +utils = importlib.import_module("extensions.sd-webui-controlnet.tests.utils", "utils") + +from scripts.infotext import parse_unit +from scripts.external_code import ControlNetUnit + + +class TestInfotext(unittest.TestCase): + def test_parsing(self): + infotext = ( + "Module: inpaint_only+lama, Model: control_v11p_sd15_inpaint [ebff9138], Weight: 1, " + "Resize Mode: Resize and Fill, Low Vram: False, Guidance Start: 0, Guidance End: 1, " + "Pixel Perfect: True, Control Mode: Balanced, Hr Option: Both, Save Detected Map: True" + ) + self.assertEqual( + vars( + ControlNetUnit( + module="inpaint_only+lama", + model="control_v11p_sd15_inpaint [ebff9138]", + weight=1, + resize_mode="Resize and Fill", + low_vram=False, + guidance_start=0, + guidance_end=1, + pixel_perfect=True, + control_mode="Balanced", + hr_option="Both", + save_detected_map=True, + ) + ), + vars(parse_unit(infotext)), + ) diff --git a/extensions-builtin/sd_forge_controlnet/tests/cn_script/utils_test.py b/extensions-builtin/sd_forge_controlnet/tests/cn_script/utils_test.py new file mode 100644 index 00000000..5904fa0c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/cn_script/utils_test.py @@ -0,0 +1,75 @@ +import importlib +utils = importlib.import_module('extensions.sd-webui-controlnet.tests.utils', 'utils') + + +from scripts.utils import ndarray_lru_cache, get_unique_axis0 + +import unittest +import numpy as np + +class TestNumpyLruCache(unittest.TestCase): + + def setUp(self): + self.arr1 = np.array([1, 2, 3, 4, 5]) + self.arr2 = np.array([1, 2, 3, 4, 5]) + + @ndarray_lru_cache(max_size=128) + def add_one(self, arr): + return arr + 1 + + def test_same_array(self): + # Test that the decorator works with numpy arrays. + result1 = self.add_one(self.arr1) + result2 = self.add_one(self.arr1) + + # If caching is working correctly, these should be the same object. + self.assertIs(result1, result2) + + def test_different_array_same_data(self): + # Test that the decorator works with different numpy arrays with the same data. + result1 = self.add_one(self.arr1) + result2 = self.add_one(self.arr2) + + # If caching is working correctly, these should be the same object. + self.assertIs(result1, result2) + + def test_cache_size(self): + # Test that the cache size limit is respected. + arrs = [np.array([i]) for i in range(150)] + + # Add all arrays to the cache. + + result1 = self.add_one(arrs[0]) + for arr in arrs[1:]: + self.add_one(arr) + + # Check that the first array is no longer in the cache. + result2 = self.add_one(arrs[0]) + + # If the cache size limit is working correctly, these should not be the same object. + self.assertIsNot(result1, result2) + + def test_large_array(self): + # Create two large arrays with the same elements in the beginning and end, but one different element in the middle. + arr1 = np.ones(10000) + arr2 = np.ones(10000) + arr2[len(arr2)//2] = 0 + + result1 = self.add_one(arr1) + result2 = self.add_one(arr2) + + # If hashing is working correctly, these should not be the same object because the input arrays are not equal. + self.assertIsNot(result1, result2) + +class TestUniqueFunctions(unittest.TestCase): + def test_get_unique_axis0(self): + data = np.random.randint(0, 100, size=(100000, 3)) + data = np.concatenate((data, data)) + numpy_unique_res = np.unique(data, axis=0) + get_unique_axis0_res = get_unique_axis0(data) + self.assertEqual(np.array_equal( + np.sort(numpy_unique_res, axis=0), np.sort(get_unique_axis0_res, axis=0), + ), True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/tests/external_code_api/__init__.py b/extensions-builtin/sd_forge_controlnet/tests/external_code_api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/extensions-builtin/sd_forge_controlnet/tests/external_code_api/external_code_test.py b/extensions-builtin/sd_forge_controlnet/tests/external_code_api/external_code_test.py new file mode 100644 index 00000000..b2b4101d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/external_code_api/external_code_test.py @@ -0,0 +1,170 @@ +import unittest +import importlib + +import numpy as np + +utils = importlib.import_module('extensions.sd-webui-controlnet.tests.utils', 'utils') + + +from copy import copy +from scripts import external_code +from scripts import controlnet +from modules import scripts, ui, shared + + +class TestExternalCodeWorking(unittest.TestCase): + max_models = 6 + args_offset = 10 + + def setUp(self): + self.scripts = copy(scripts.scripts_txt2img) + self.scripts.initialize_scripts(False) + ui.create_ui() + self.cn_script = controlnet.Script() + self.cn_script.args_from = self.args_offset + self.cn_script.args_to = self.args_offset + self.max_models + self.scripts.alwayson_scripts = [self.cn_script] + self.script_args = [None] * self.cn_script.args_from + + self.initial_max_models = shared.opts.data.get("control_net_unit_count", 3) + shared.opts.data.update(control_net_unit_count=self.max_models) + + self.extra_models = 0 + + def tearDown(self): + shared.opts.data.update(control_net_unit_count=self.initial_max_models) + + def get_expected_args_to(self): + args_len = max(self.max_models, len(self.cn_units)) + return self.args_offset + args_len + + def assert_update_in_place_ok(self): + external_code.update_cn_script_in_place(self.scripts, self.script_args, self.cn_units) + self.assertEqual(self.cn_script.args_to, self.get_expected_args_to()) + + def test_empty_resizes_min_args(self): + self.cn_units = [] + self.assert_update_in_place_ok() + + def test_empty_resizes_extra_args(self): + extra_models = 1 + self.cn_units = [external_code.ControlNetUnit()] * (self.max_models + extra_models) + self.assert_update_in_place_ok() + + +class TestControlNetUnitConversion(unittest.TestCase): + def setUp(self): + self.dummy_image = 'base64...' + self.input = {} + self.expected = external_code.ControlNetUnit() + + def assert_converts_to_expected(self): + self.assertEqual(vars(external_code.to_processing_unit(self.input)), vars(self.expected)) + + def test_empty_dict_works(self): + self.assert_converts_to_expected() + + def test_image_works(self): + self.input = { + 'image': self.dummy_image + } + self.expected = external_code.ControlNetUnit(image=self.dummy_image) + self.assert_converts_to_expected() + + def test_image_alias_works(self): + self.input = { + 'input_image': self.dummy_image + } + self.expected = external_code.ControlNetUnit(image=self.dummy_image) + self.assert_converts_to_expected() + + def test_masked_image_works(self): + self.input = { + 'image': self.dummy_image, + 'mask': self.dummy_image, + } + self.expected = external_code.ControlNetUnit(image={'image': self.dummy_image, 'mask': self.dummy_image}) + self.assert_converts_to_expected() + + +class TestControlNetUnitImageToDict(unittest.TestCase): + def setUp(self): + self.dummy_image = utils.readImage("test/test_files/img2img_basic.png") + self.input = external_code.ControlNetUnit() + self.expected_image = external_code.to_base64_nparray(self.dummy_image) + self.expected_mask = external_code.to_base64_nparray(self.dummy_image) + + def assert_dict_is_valid(self): + actual_dict = controlnet.image_dict_from_any(self.input.image) + self.assertEqual(actual_dict['image'].tolist(), self.expected_image.tolist()) + self.assertEqual(actual_dict['mask'].tolist(), self.expected_mask.tolist()) + + def test_none(self): + self.assertEqual(controlnet.image_dict_from_any(self.input.image), None) + + def test_image_without_mask(self): + self.input.image = self.dummy_image + self.expected_mask = np.zeros_like(self.expected_image, dtype=np.uint8) + self.assert_dict_is_valid() + + def test_masked_image_tuple(self): + self.input.image = (self.dummy_image, self.dummy_image,) + self.assert_dict_is_valid() + + def test_masked_image_dict(self): + self.input.image = {'image': self.dummy_image, 'mask': self.dummy_image} + self.assert_dict_is_valid() + + +class TestPixelPerfectResolution(unittest.TestCase): + def test_outer_fit(self): + image = np.zeros((100, 100, 3)) + target_H, target_W = 50, 100 + resize_mode = external_code.ResizeMode.OUTER_FIT + result = external_code.pixel_perfect_resolution(image, target_H, target_W, resize_mode) + expected = 50 # manually computed expected result + self.assertEqual(result, expected) + + def test_inner_fit(self): + image = np.zeros((100, 100, 3)) + target_H, target_W = 50, 100 + resize_mode = external_code.ResizeMode.INNER_FIT + result = external_code.pixel_perfect_resolution(image, target_H, target_W, resize_mode) + expected = 100 # manually computed expected result + self.assertEqual(result, expected) + + +class TestGetAllUnitsFrom(unittest.TestCase): + def test_none(self): + self.assertListEqual(external_code.get_all_units_from([None]), []) + + def test_bool(self): + self.assertListEqual(external_code.get_all_units_from([True]), []) + + def test_inheritance(self): + class Foo(external_code.ControlNetUnit): + def __init__(self): + super().__init__(self) + self.bar = 'a' + + foo = Foo() + self.assertListEqual(external_code.get_all_units_from([foo]), [foo]) + + def test_dict(self): + units = external_code.get_all_units_from([{}]) + self.assertGreater(len(units), 0) + self.assertIsInstance(units[0], external_code.ControlNetUnit) + + def test_unitlike(self): + class Foo(object): + """ bar """ + + foo = Foo() + for key in vars(external_code.ControlNetUnit()).keys(): + setattr(foo, key, True) + setattr(foo, 'bar', False) + self.assertListEqual(external_code.get_all_units_from([foo]), [foo]) + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/tests/external_code_api/importlib_reload_test.py b/extensions-builtin/sd_forge_controlnet/tests/external_code_api/importlib_reload_test.py new file mode 100644 index 00000000..68ba7fb8 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/external_code_api/importlib_reload_test.py @@ -0,0 +1,24 @@ +import unittest +import importlib +utils = importlib.import_module('extensions.sd-webui-controlnet.tests.utils', 'utils') + + +from scripts import external_code + + +class TestImportlibReload(unittest.TestCase): + def setUp(self): + self.ControlNetUnit = external_code.ControlNetUnit + + def test_reload_does_not_redefine(self): + importlib.reload(external_code) + NewControlNetUnit = external_code.ControlNetUnit + self.assertEqual(self.ControlNetUnit, NewControlNetUnit) + + def test_force_import_does_not_redefine(self): + external_code_copy = importlib.import_module('extensions.sd-webui-controlnet.scripts.external_code', 'external_code') + self.assertEqual(self.ControlNetUnit, external_code_copy.ControlNetUnit) + + +if __name__ == '__main__': + unittest.main() diff --git a/extensions-builtin/sd_forge_controlnet/tests/external_code_api/script_args_test.py b/extensions-builtin/sd_forge_controlnet/tests/external_code_api/script_args_test.py new file mode 100644 index 00000000..99c71026 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/external_code_api/script_args_test.py @@ -0,0 +1,34 @@ +import unittest +import importlib +utils = importlib.import_module('extensions.sd-webui-controlnet.tests.utils', 'utils') + + +from scripts import external_code + + +class TestGetAllUnitsFrom(unittest.TestCase): + def setUp(self): + self.control_unit = { + "module": "none", + "model": utils.get_model("canny"), + "image": utils.readImage("test/test_files/img2img_basic.png"), + "resize_mode": 1, + "low_vram": False, + "processor_res": 64, + "control_mode": external_code.ControlMode.BALANCED.value, + } + self.object_unit = external_code.ControlNetUnit(**self.control_unit) + + def test_empty_converts(self): + script_args = [] + units = external_code.get_all_units_from(script_args) + self.assertListEqual(units, []) + + def test_object_forwards(self): + script_args = [self.object_unit] + units = external_code.get_all_units_from(script_args) + self.assertListEqual(units, [self.object_unit]) + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/tests/images/1girl.png b/extensions-builtin/sd_forge_controlnet/tests/images/1girl.png new file mode 100644 index 0000000000000000000000000000000000000000..d825e716be9b40ddcce6987fdd8aab7d1e6871a0 GIT binary patch literal 493039 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

    06;WA!jqHr-~7ja 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%0Dc z;m*aEK7aQ;?ZbYS3_8up%q&d24&hfkm0 zedYMZhqs^l^xiY8IG1Q@>YE19_p4JKR_Nv$Bw|mVO^m!Z1Kno*%Dg2qD}OiWFHooij(oFW>UfQoG!Xl4NHXFDO)_n#pm#`WpV4?pU5mVf%s|6;jl zt<>ijxl(b;8jN6?rZ@c`6-sPgksPBBR;>`piDx(eWVjwNqH3x|?XV&g0M4@LDQhd% zsw_k*P@M&WYU?N%GzkdDdiMet2#}*V4WJ~InW{lfO3J8ZDS#RP0MsxSO3f3LL9YtG zED}GV<0R}I;czlz z#YIuV0tnf_6vq_3{Bj}NmStQrgk@%DlSL|1JFz0BG1bW433MmrGUd-`V^Cdf-NBRJ>2~%X ze*WR3Pu{%r%1^nQCzBH*q=sB+d!mtuqy#iVFjG@+i0`D-H)F?b?)vnH}CxB>(}ldT_gmJ zTi1Bsb|DHewVH5D}m=anhX9T0;d3GA_S0B3}l_xcK;If`{V=U{U66{Fkp?{Fkpi`OV|?|K*prKK=Aa zsRaYqwA{3aWQathG3nd63%jbRTG)z&fg9)Mi>B)`)vN7fxa`>!a#yV>M#*FfMfpuf zg&J@DAR$oOT(mz_b<7ZcMiY&7)_^>DWx?$e z%bSN^I7i^R#q#d;ozriwZyw$3=2z}q|9~mJ{FgsA3Z0uB$;&ssffx8j+ltCYBXDPs zt(jy1XvCeKyS(}1`R7j@oc{c?AAj`K6CncN(6sXyMEbRgQtMO&2#{DM03wouVH_q)aJ z-m9;@l4^2~rtJy~Pz)ATYtQE|wc5>!c*V-{<;($`@};Y8vSnUDb;w3_5FQP`*{z?5G|=ZMl+*aVJl! zPK-9?a+9#Dl2%;oMZ}c!GC~kbYk~!e(?K~SkF0EuJT!#KX0W0$Af(o_b&6{EZ@vJO zq|u40krpla#_NJi^#Z7OJ*(18c2Aj_@!d=TlpWvx`oS;%<3F4{c;tLX+?avM7KV*U zKmb4nX7&w|Lu|O)LFa+kM0C5+?Fv8$&Cd>i7{Qnu03zRs;UGO4c5a4*-ghBvT?&Ii zP!S{nwK((^dt&cqyUlEwLsW*%@bJq=pZ@;%-lrBfzT4k<>eam`zq`2jL_&XZ3<#dt zH%$`SVrlQF2`pOu?|yvgC(m8{`Fpp2@!8!6k4%gVxSMyb>ynHnM2l($Iit!D5LCsY zN(g|iX}fOTq015cNfV}A!@-jGb=(12J0-JJ{yEETQ$s>>-b^$1uMQrA8fZ9;{Vv;- zs&J};M-WjMKt&dON{?)H`mOC%J_;k)?F6i+sR$fdv25Q-oorQTdbkyUA z)iqGLbmjk9I8RN^rA6-q3afTl`RdfdU9IN@bD*FCjC^@S&T4Nit_3aS-Vn!Ha#MzA z1?nML!t-%KD0fbMDbk|?)T@>9XsNVlws(OuW5OYAfsyj&Db6sNF&!aS*Fdx41jc$o z%A=Lcu8&}UTBe&)2q+yjAn(*O#>cbG|3q6P$|v_+GVBm@n;4jb1kx!v{iT>)^ORbqU6_tB@nJGuLb$+qcscb@-~ z{inV^+dD@MOUz-vzIBan*t;Ma#Y_bdNMwJe|L)J9eDU)B|Mlk|eR`*V<(2aYFeFIR+s#eZbd~*h%V$u&_;M=Zg=j@x58B+kduK%P&mldmRriod+q+^7HYQUc3 zHmFJpa>HUzs;9b;ym1#-K9@EC0w|=(12>zWyY~Fi?XQl$y1o0vljKsUzY`HhoV+b* zN0>w=xV+y!b7|(;M8Oa`PkwiHx*GZ@MASJ~w|`M%^Wcfli|(}aoooB5_VH);*w}sd zN6sw{KmSl=Efhb0^XKvO@Wns>i!c~B^M~-_a359a;5-5t(#FzyF`A`z=ZwhGz>`-W z{mY$%vRmhbDapAhHP%K z&DCWX$+7lBsxpKk=Ga^d&V%dBDPGt6o7UOYY{E+Gr*Fy?W_Ka0}n2-O2$E7WrKrh1>;xsuRIUY*9X1O0? z-AZ6kY8F-VRCzYdR9eqkSF*83vzY=p8-DTt42q(efFDM4hSgydn|?~`P0+>Zy;No{ zJu!|&&T2)R#GPC{5#^9zU4|@NCJcN`Z^lv2!lZs0rd2V}YH!K|E|Qo=%N^zendSXt z0n^(B*D)J?zlHRmmjO#3G2AYV0=<2O#g-Wi#K=oc648e0ccTyN6$Y z0CCgI5B9G8WdGW$?PAAw4S=C1mFPV?azQ2ZYKXpRf(VK2?D4<<%cswG?f>!r`{pLf zzx(UwzjJjN2KnUus5^@l?2V3F9wNGiO6@Y>wNZ!X)*RAXv!%o6I-@M zArmE_qyj@a1I#WOiYT#zDvT-9f_(amx;EMjvBr-hpcQWr7#O>5|EX)I_wR0xjuscr zs~I2?J2gW>1g2!%Hzd%fuP!c}Yt@u;l0Guga@MT+L6Xg?h%YEAaEhE`L?L3+CF_gV z4j}3$_D~+f#g|_8v-$l`-Z352PQUu-cinvP>wo)iclT!i zn#%9iRW-;57NFn+PHjPHm20SYY1s-Hg%U*Mg1)&dc(v0^;iVSyDci_$kbXhciM=Gj zR14oI$ZZ0i=Ytw66`ZID4$% z`NUq6Z&BC~mbN(Mm|`)_s8td-VQ$6TR3$-9=C*tVoKSDZobgk5K*}#G7N~0dhY`#R ztFL>c2&Bo#&*%f?>*ast(}oBps_6Wizy8BVzkdS}*?R?4H39<}Ktf`Hr_ zKoPP70FWjo*9kwbw$rS1W$BNAYLKenhQ4>+TZtDa8~H5HugjNp_N=Fm*2U!L1#{Fa z&Rtp`K3W|0!nyK z#`Fx$1trJatW3=(+Udw4%a<~WRisa^TG>%hX>l<_VcD5jJP#RyMm!w7vsi%?i6I*~ zFfVul-ZBO&Dst{ipY2)oUg?UehNzF_==fF&FXz(i}1=>%HKB_QK|Da$inzV4A6=2_K_#1OEQ4Nkz5bIa5H zZL)px1}r;i+@#}f{V%;%=GU}sn(H5a@teQ&G|VfB3~)!}?)2-#_=lpIvzVH9w!RcZ7(@&M_d0Vu&J9V-P?TF%)#( z{)fMKy6K1i$A5VJ*{Apar+@L{!J_GdsTj80?zfog5*k=cOpS_VH}4&Z3V`Gsw~cEY zWyYGIks)`79zAr)z?d(i2Bnl(vaDj|3jhWL%xUN4f^-JC2H3PbN>Lpu<;b??sW`W? zf6-jibi4Z+w10e>S`z>gFd+c35klwr`K!zG`z?;N)+oh{f_dWB`%Iv*9^`DyRLsYo z08`B4!o%~=>^^&CuW48t+kgJq%YXEzG~Y1`!|>pXcYprHTkpl*tp{7d{MbEvd-L@D z$4?yHYb<~xObPV~Nz^3jAP^PZ-k$u|fBMyP-&OJ?q80~oZ02JaRARsFH3}dDF?vtF zBj+s!>{lcMYRo!J(;4^}AE)FTH83J{4v4`yRYg^l4Gb#{(VV0C68y}X8Fzc+W-9p6 z8^3$+%@5Sb#%RS70GiPjp)g^}08=UI*luM!>R6cTw|}NMF*;o{@K2B}Exw((#)P{U zzhnV{i49{U@|NqHV)=IQ92!=~#5gJ|K$plmOg3XCO$Mb>fkCOri~s~wvRS9lQzj`t zafR-(g^S*i$#Dszv*PutV4qPg$xuq+s`;6*EKUZ(Ttc%z|9GZ~=&8fYj*%>a&b(MA z3dbK9SG>q}fFdNIFt#a22dn0rafum9&Bi>os!WcuU|iI+Qlr(W=m$_19VQ>F_dWZQ zXS(PtYR2B*`s&`_{D=R%J~?LBU>*;kiH0FA>{2H(0ML|6T>V!#o}%n8m7V9W%sl13evnJdQtC0ssdX{rG^i>CMjU~{SuDkE!P4XNPt7mvw_P`Lj(4wK zzWk$~%r0C+B!zJO?Z3V8`+wBXo^GMHW#7JXH@^7r`00nY=fg2#3hrh?W&|>WV6qYG zfuA|I`fvXDtEZmaD(TP%5e0VCb$u9&n9!-3ieS@%@35P5)0sfrp2qDO5Rg1VL#`1K z2G`v$DA|N61&mMw&5OXhKl3hGLc=xX_qt#4oianRywjiY0j3j?8CZ($)9S0J%D{-B^*fV8fVrPTMbL5=gd&HnbaaL3xv5xP zs2r5zS01v6wr?+B6*8C)`*`I#x_X})u=VY?3vx`9QnRc=Fw>*Qr$76D|NW!8->~;c zl+6X8AVQW3q!2YNlIM2L?F`tFa~1~KtSkmZKyt`l4biuNtfIuu0Gw;tHxhdQVsa(| z2#y&I!e(W0uo!jNnt^NDX1?oYOW!nvgfeXJ+KE zfE2OFoKY2$ydgqX#{d4$p19WH|N4uMfBf1DfBou{0-1tgD*Pz=@?QJIr5yuf$EpB{ zBtk0Ag9sR7W`0CO?8^GlgaA}A4yuqFfl%o{fskW@F)zB+5Dqi5T>IKYFj;g;WMIYw zsz8vBN?lp2mcr^{F1sRqlG(9u!pZ68Y}8`MG(&a<79<2Qqxiz*d;juBUthlBT$6?p z0nz!+vo|#&LiC`Tdhua1C)a`*#0{DtlG*?UYz`4!yCCNP5P=XF)Hubh5fT~=Ya32M z1f2)pDmK*3(a)*vPVV1(^Y8!W=+R-yxx~uRiV+=)GiYSgX-gynj+K8Emuy+sX~bZe z=?VR=bnmQy7_BidVSDwLY8tl^pjfG6ja{_@wNO-+(Q1GNiRuH{_*Ui`lU+Zds%LRh$T1x1R zUmFkaR4>aDIr6uvabp?nC?v-PuP|G$Qyn-6#S2|@0?6K-jN~@)bkpQgh){a}jwE{! zqjMU29ZpdOGedIZTXLR=O;kmI$dH&l`$ZHKQB^b(B4Q!~Qwfkdj)tBPscqPGfX+3Z z5kZFj?pKe$e0x~kbKPS9+K>02{sH<1*p=uiWk&W+RZJlUNg-gWu<83he|6_-*Z!}+ zy#2lJedi}HJ`qGx7zQFHlc0(2w{-DhHwg57P&H(R48v-s5=F%bk%`zhb?>CYe93K9 zoBSoppS0^y1)OlA%=t6X$6{wPK$I9X$sbImOY=sfk!*tH+~9i60y1?+B+CpIODAKy zn6;g=elu*=00^$>d%3XZpT5vB6JpxrWaD|PCo!3_ro_Ua*kkiysTPUk7;|{}%3^Qd z$0*HyH$S(SU%h;{IFCDL*UT@ED`<>N8T-{Y3 zs6|h-K=OnZWms(usDJM2;nnAwX5ImVfs&(kZ^mSlC_JNtpepDc`G#jpWG|a_+?=Y2 z86Z1ytqemPHcA|#4#Qw-2Ht=yRk~LI>23WOhBbh3(*Qf624{12GxoDPU*3A_A776l zuX{aoYQ^AEBIdDxg_U5CY_X|^<~+S;Pa{~xg)-@dA{G><@v{|JCm=W?L&3HRZw1Ke zZ&NTi`*kE7`DnUT0q%OM!fndaR$Q#N#NwY4NU&^Ll&1vDYAU8BKD0=Nf=jhjTz>A- zKRL-YvJ#$eaDXdEs97whoiiz zvt6bODrw7Xa5Ob%;#fIEm3!aTXzGoy!Z?^jW@hIQF|{2eZisy{o1`=XcCGg< z6M~tB; zViYhC(Ny0mO-ycCN9Y<)M5d|=W`?N~o0%q`P)*L5?~H*+2+HEKx)> zpM-2gsOn}#+R_wg!t%!Bcy^N$qN+Iuum0%#)vNQkK91Y91Th0uXc-7JmcVZSNaCkn zFx9t6F0u;wMV?VU@AbqXrX0SuX^8XP*n@^)dph*%<^1u>7jL3lssbA5 zAaWWcs)o`8SxuuLIWq$y@(b=}2oa^X7(~^;A)^rjIbuc{kW&GBbj}mE2~scy98SOn z0Kl#@*MXl?x1^>MbDzBV*7f&4#uR3*83ZuX;l$^20bl~ET6R{W5CBX~b9uEKQC|TA zph9Qb1Zt)uSdF|6GbtR+E_N2mN9IxKN`A!(c1_fY%3G^CIb!6<-gET6jXfRfxa&#E zyT?XWTbOPUYGV>i!YR!{1p!KRy!hGIo8Vf-x#;*+8XHXlmz)TlZE6s@t zqpv~&M;t8ES{?&Rg|&LcEbvpq`JA{>?p^Ms$1VlDd4FeDY z5g@sCPQE4AqHDoax2F)dphC>V-T+fR8<9&6M`Wi4YQlt$9VffZ5HyNulo&-M_S>*o zBY|(`Znos6A?HkDTpb_Z{Al&)2BPge`GdV{uTnQRV%Incy{Z5}>I|$RnXQ|OsswS2 zO{2em|Nc|YTzd7z3#mvz<KHH zss>vPm!mRROuqSGjEj=}`}I^<&KgT0YBu>($sJm*uu?bmNcbkrM$gE0v()F?oa6l+ z{>gXu|M_2D-aqi0qm%x0)w=fnxhQU>ErPD!SU>%;fCgyE}Z-BtL^>;B-fulzW)1PJ^cJ$-#3qXcidb#wii~L zr-{#*^QWuT@q_hd_1F}ZFQeN-M{%?6x2u=--Z;N|ACMGG)k26sL@xONB9LQhKvY9S zCTbd=GS|Ko4&-+hQcR+?xP6tbH9pVW7S*5a+bvPsZ;$&6I0mtzyO*!I}pw@XS_ZgS9qDxi7#}zLV zGyQZH0eM&ESX(qTMelBW@y#!P_MiLH6J)0friRRj2%s7UG$Z0D!0nQnIr@g$R#kMn zvSDiykeFN}NuaACwaBcdsaAxmqS^<>kF=Kk$oPH5QS6vmJ&QL-5WujWbnHP=Oe9*bE{{!-N)CS+5i5F z2NI*Ec`dV+<15h;o0zeE?}cSI>r5oUp^B+$u61jcDi$QGqLmO}(WT zvoDiMF&^u(A96&HNhON;Fl6pj_7+xs+(wFLS)Z6NzP!zyqvxO9+3Wb)xt)LYSJy7= zv2Iq|)gil`55A<|eDFxYTkV)a*7y52>OE5CM~-i3}!!gaQgoilk}=W=J&K0ml$~lwcao zKumNP5Cy!Wb_Yl$4k{4+q~!FWUq8!JehFH3+q!U+&+&7d;#dqU9|ZmFsbqFi$%Ya|tdhlQli;XEdM*=^uZvJo9ADlTAP_qv5Q*$&DlwDnlQgC(4^9BIw=UK^8CKvowsSf zszTaq21#i*2~y{HB*JP2sA5q~liLBnOfx%x)V$KFX~n?A0EkMoPL4nTB=U}(E2RL( zeN^{z7GFgM6vi>0(zM?*uBfI`B|CHX-DhUrF@ijIW${;kb?x%yHf*+cZr^ZScl}oQ z;ENMx4`&)e6s}b6RxZ8nt&albqFw&c*Xv;&{EWcU^4ik} zFTBFDJq0{@c<1xC-`qZ0^~b|%E34VFw+^5G@{23XmywpR?P)#8@n(G(PbJ}yK%u&wOQ>9xWF;1;M(frAm&Gf)0M5wV zk>Ay+ET8(;1J)~)c^UOQ{HGt7{8euRXwmRjfBW07KKg{26ZWw4$>?S(D$#jofI!~O zchEK5bp{~)#So<^oreFIcYH40hOV#MvRiP21K7zR=GZPU&= z_J9D6;-CEZ%J*Kr5JeCmbN>=>QP3@!ZvhZY;8<{Nc^``Q5c+PK_Wn z=VXo>2kZGQQAxFjRZUPzTmk{VI+S~dsz&LUnIa*d-rfv{k!Id4yZviV?_PVJ+NFvf z-~ROWhriow!pTO0M%a1s#^LiHeRW0KOV)T8HeP!(IXThOQvxL>I#}3upS}f11k39946pr*r+C(SjY0AY)u492OpDK=U8HB?n@X5<)%$uarXjFJurn-%n1 zAVBBAcQD(bc8*QgpRPar{p;U+^B|?eQtASN1}Q0mD09RS-_CGBoQC{W>;eFTF`=h; zm9w6Jb;5J;Aj~U$#(MJY6JL=l@0zoiQ>Y{qCHD+wj91OI84-Z22&s%ld9zr7KmY)w zROh^y5Jvi~qw-uK3&$e~IrA&Y!tv_aaEh7u0@!GtH>(cH_} z&?fw+2GvduK`rb^#EzK}a|8?4N3y(TMFwH9HKY|c97B(?7Eoh^r9wcs`lvi6P~zBG3q#qeTu8F{*Z?mk$~fhrL%zuYHDVQsu>tl{zu)s6c_P&8A#dcnQ&T;p;nM{tDR!b?{Ve)QT^@9^HuyPtjdvGVer>+9of;M@frs-l$7 z432jpMFfyysmL3#aH`|2UBA0s_ZFgp5jzJ4DKqEfIBXsdZsyT9drw{4dFmQ*LQqcxQba`vHu-?mYY1!>gZvaX{{}K&!*n)8IWs!P71FTO^YgFFe?rajLnH;<$7W z6+t3mj(tuIW9I-^GztdxP9^rok7Vcx0bSFJNQ@SRxJh~Aq5?$74w%ugiK>c)o`w~I zAfpk1@37k?za+nSc<1iBe|WPWGUJd8foJj?;Tn;bG zWE3)$&9xsWDM@1t0Tgd~;n@k=&e${&a`6N#N|u$6mQ!Yv`K!}VWysVeTGWtHH8^8E zo$%~py}>#QNw!l_vc7FiDByxQIVP!f`9^t!siDLqy*X(FSi1j?S>c3~(4Wq%$V3|` zYg`3GehbSz>#7%)Hol_V_)l(p^_#!_2Mqy<%~F-!)FqQddU76-P0abu&E{?~N20i0 z*{}f>06=DR4#7;t0EyU$lH=Nd%+Qf{t~Ic@?Hyy-tm0;+8W0qT!}_>Ce#oxzivv{y zcH}&Ues%Ze$%8MEaPR6%^GnYfIgtneDF=(4M=)Y++SWkh5HtufqSj7&w-&S z(!)elqJWu1Ne#%%vQHs>z>+h7a8&eF)Acmf2eo2LO#IA}JJ?{{q2pf9@<74NR6s(w zxTkw9L&*tnj10skfBZ*Jy!^eZvyL8o_07Hej~<@#?>^nc%0>!|SUtFf#aS-ep1T-k znFNq*5})1Q-a8z~u^L1LG)QLp5J3SpC&TIejWA-{?Oc9paq%f?=R?1J_{Ap=Zr@(5 zZ53OXEp74ihqo_(@Y!zg=LYq%*|r?o#u4$l7YTTAd3s^@5hfi_4J~!N(j?i5JOh<- zloW?xV%W5XEO7&2MF0{45E42wvCtDcWF|jD1rsqJib(llyER~RYJg_yDyPnm&qPhEgIh2S0^%c>eh#oWri>j(tV-CyPRc>I_e$t82qCDmVE~J!O zno`|u?0$gbNv-?>3-V5PI{+9^c_D3C1RR+^7Vxf$502=Vg-1c&QCv)@bJ0o)kuSqa zMOG2hKg3iNYa0DX`|ICOJt|cZs&lHV)~@%rz7_RH1bBW9ml6`3V}uZbWMI|s36Vw&yp;sC+f_7wU}x}_lk zF(R1?0uUOpM|8}Nn84J;QW-dvNS;C%!fIm(aoB=68P*Wj?R?>8=lVVXA$c+#Hut|e zz5f}4?p}CicJXZV{*Ef5vFk9l-r_dl$cHRR^qC2qLyXNHf1!bs>L8z_Wh5ZT{NBw ze=l|+fO8%F^iQ6?^wj<^^tZnFW{b_|ckJVvJrdjGBv9GYiEyZanx-^2E9Qt4&I*8! zPvyp~(_v6@M2?Y3OMm&Ke+k0rI`)A?5dCa^@tOI-Q`jzt&FY)$Z{4|hd%KE30H#1$ zzX0dwHnZp6`230Aetfy73nE^&%4(jyZ|2cj0=crhgBBsxk&mX5v5^9RC`PkoWdx-Jvj%1HU{VpN zfeM=tpDsry zyBtxTf`X8eMpOoHhUz9+lCW(Iq_Ns}IiGH`;zB5A;SB#pAVOxwNiB%XqU+q1P~C|n zI5TmUT7H|VCG)Iimz|ZMjy#n$G|y_u9;nZiwu2>+dd43>NK7t`AxQwlq${4`d!rVU z7itm|2xlKIKf8^yFm5XC0e|&(Z{PduGiCxPb`dLKjtJ}<5FsS$mb5%iNb&TMZr5f2 zL@6kXkW``pATo0Y00=Reff(6$b9Bx?04)q#9kz%X`wf7x_l|)ra=U=0L+{Z!6A8zU z9)JCD>`xZwt}dQ-EWceR}$%@9eyI zbtgn)q8zze>@Xt@%BzcFCYEPS1-&P~JAdk_gQs8F^^GBbiXoAxgnmfQWXmQWR0T21 zry{w|&FZExQ$R&beHRrmxrmi02}Xmlv1nGS4NPK;A!L=%L`y)OshO#QN{NXs8Z$si zolH%a3{9gt)t`QMapht|0L%zT$wh5y-l0=@_Q}}~{^Y54=8kUPx_|e<0JAr5tZzM# z)Hx?3LRANH&LfCs*^`5g^290te13O(@4-fs%EhQznIQyrjYDJuCSr|I3B`!I-PyS( z=KEKX+Wz?Aqc1;vaO>;MmI8RU+#TrLCtvOU;p62>_CZy1CLuwcgj$Y?CuR;=<_d zhq~g$9E{&W{E7WHBV*>BS^B^PrM~s0LMO|Lmnep!UW~fv=*|F4E$x!IVFc1dL=rsO zgyCB`Bgp{dnK-4kPNoM&)BKogH5oM4$10^$VVs*{ORb+aKub430Lp=*cxIX^EN59@ zleMs-=Z;2sRTGU;9lCFf_|L)x{KYsIdXE7;!1`1lD#0F?Pux9>XAEKy=I<5JuJQY9pI1#2}j$sFLqgw*AQ?;~CG+QPUb4 zA;i_`@tqs}>Or@AZhqx?>J~--On{&u21cABJ_kTx&&gxL&ZW3bG<)(=_v4o@V%BNX z{vgdpMkw^QXn4g+4~PU5#MJEHygK_I{`&m?;m;2K{GXlMtox`qL?hzaj3L=vKQ;-j13Pr{3IPDSR0X5FBEM_Wkc%c8Fr*Ef3j7{!^|QO1?O>uBBE+Z?R77JGiIGv0 zl}n?BZRpp5+7<|TzPr5i)Xupl$&5ANOg@aUUE-D=mg?e6)3c0Rnl|CF?fgJwp4?wU>oufP4yo!fVa$iT8?zlJ~NEW#0M zvp02WmOewp(J)1sXLDjXv^nM7stu^v77A)tY4A_2LFN6?P%*^WK;-G}QkD5iL<}d~0Vhb%F%f+y<%twaW>O?QY zG)Nhn1O|Xps*c67ihwW?WfN~e78#@D#C(QpPxzuUOy@YQRSGo6YEObuU}&;KrkevjFVT&q$ntP{_^hQ*MI(xwmKdkIb)+4BC^X7 zPV8xRKmcL&NQMoNL*D|Z#z>Gm&Vd2CCMQW{ivXsiFeD6pA7cPeiyIAFQw3s+s+-5e zeP}&;MI55-?zR8j zzj@|+uk4ZqH6(|S++xWp0w9uuHcU$pXoilQ3ShNNq8c)#s-NX}WXnDwBC*6Ck3VUsM5*sA)2xbc_-p4nRQ80XXy>P)EKy zxp)8LH{KYAkQD~NDmF{0f{7?Cs9ju^P$_Lj+6jR+9qr(h!6e7WAXESub+j`uZ53_n zhPR4MXDk*Yk|YXjsvt#gfttHpp{0m~qJCD8%6+Y^B3&{6U=0`pFjEl$1XYWwacrsu z#j;t1KxS;!qmeC{Y3AJcw3c<7Q6fS4@B|qlr5)$)HubG)qQY^?%9XH;E6odHw&o?j zQzB-0rt0L63p-KJvN~O9spW;u)_hDxG3Q*VDFbz`tFI&dS|)2;kSZ3iJk!MTHGZ`W z2N7*0^6P*6!^!PieiW|&C1MykdAK8Ri*AnW;>jUeG-PtEsc8&gVu}A5pr2W$um(V2 z3dqjQeAf;A1|6bk+^%$UN<^+(P}50&YH{7{U2f*P3g8GZ4D0(}^+&gfXmR;@zc>%b z$V>^v3?(IzA&~c=ktwR7nISW%s%Z%E*{AnkxwcE$f$I9GcaMi{ua|b4gQZUbpE0#U zDW|~z2vjVZ&F0<_X^dTik9+;}`bpcgOuF6bxxMCxSLV;}cL$w&=hN-UX5jR|DX=F^ zwL%UEs^U7Wd-4a084wYg3XmWmlFMxb3d=@DbS&$wick^{$<)bUBDRssJBz1w=Pkpt zm*DHG+v_*soBP}CR=lHgJM#tW9vl$Qx zn81+^W}t{{mRh!hDws&xUxcaGG}!=31nr_bxC+P3uzmFS;n(^>WcNqsFD?%b&TqDO z+T#bGM+nFN?Vow>wnH>V>I207L?Z)|sv;T?s;P*m4P*_Oi?-=w4`9fSNkI%5Kp3eJ zTW?MtdSoDn#K~#~7J(4hp>H9I#;B>dNYlp6hA7o&8Vnpbg2)J-nid8T7{2`Evl}md z_WjqsucaMCEh1lSeL0T~VUkBwV4}!@Bs3~9Q2@rAvRGWd8B8f#12X@eEXsf3XC#dy zBxG?k8e7U>s}l&5N3iGzSWB8=CW|&Q(Bf+@Mw7Ii4GfX0+sw*H)HJ37=>o(w8lI|5 zJo9%kMvjUGpn;n{^eA3)Z>DNj&(B;F((G&s8CIMwV2`;iOuc`#oaeyP>YS~*LVYku zuKuERCEDI+dQ zCdDBjJC(>pmehPx$3Ew18A=dic8&kxi{~!yx)7ryf9oW?_r=NQx3=4LeEEf)zj*c1 zUIPx4%#gBK5e*bT)C`oFm^g|UsB`|;Z?5kjn)4)T67XPuZm59apMUS%6Bqi|KRx;C zt5uAW8YU(~(0J4gR5W*Xo5*SvNpWNvC6yJ;HWfkwOwpU2J2P@@TalM`=g(c4tp-CwXR_%0tR*l|G_bPC0hmw)2!MzrDj=$uGB}4CVQ-E< z`pHwbZanzr_SX--_-5zg-u}7W4{wF@%gwVFS}}o4^;5Q*)zgCcaGC*qa;LxdXaH_B zMpe~eP2`9;rZ$|;i39}nz6~Lyo-fiHBCuy0gqj(6->{R%7*>x?9zD4E-aG!)R~Hv{ z&R;wj`hF|t-n->z-Qkaa3=I#_{KIXt+5!=Y2r?lUflJDm!x?)QMI`zZlEuVkMvm0f z5V&1XzqYW}&11hfP{dS!3E7*71fj+u7zrA4T2F3Tiy?)&K@5ft9BJ^tEqSpfY&OU5 zz47kVXP(%VwIPfpm(OzK#Zcgg@!1YJw>T@7ks0~V5p0=Q8T(5NPehUkHt)au=UOcmJ~ z5U9DB$QR zAKh%;`tb1U`&$L}j?9c4W41?{#oQy_au-1$9ytRd=L7=HJ+3_gqNx}t5%93>p)tca zYu%!2E}UDu^z{76bM5{fHf#zyYZy%(+0G6VkeW-G$Y?-Wn=2F(jR~bx@`-AQKmedX zWEA5|SC`-a(X~g94*SjO&W&$o^BH&U51*}OEnnE-V!r@L7=w^I0Va1d*u9hZ#of(n zBd#&>PC^P2B0_eA28zI9A|lQc6Pd_hTaO(hQtPR4+to&g0IuowE;;65b^q}2;f;6R zzV^dcX9vrJ3+L_)5Y7MYQ+u>I{F5K~y@h=KHH&%Y5t*W?M%CD(V+J8)L?9AJtR`kE zf~W+fW+DPi+${IQsm9F;2;JhGb4`?}G075usHz6eF``LQ3m7z-2uJ`mZ05kujKLZ- zAvd7S?%lfe;X5Dv$zT1HaC$tkM9k(e8LXmnJg8H%L9)D0?Z%^7qpiWJkM86#)oSiDlWER%Kc;tYOu%%H6@rV$`Whube3mXJ={>mB~Or zNKFLGz^cNR2V0zeX%MBthMB2OrL}>bT>&ggLwbUuCQSYZ*^^;)K483xt)u+rSMMBs z^(BFV2^Kd|zETQ6M)ZpVP_h05B&IkHYB~i$Rh4ApCj}%*Ye;6w&KZ)%*tARVjiJdf z469Sn04l_uT>~1{kH3MS6v#>6cnsw{@}~aH(zfZDS&CTOIO_sR~mNMfZJ|{A;z7S|KhvL=dR4( z{c`=`jpIj;1~3d;H8rH9xfnZAG(aXG5HXM#vTBO#*pqjtNbEH#h$vg^8o%7%-F;#A z_Luh`A0IbPUwrZE_g_ALai`nq%rO!wm@#nL-Na-HVg_hjMLmqW&2np1;7mLXa_kwP zDIqDq4$4n|{KV%sAKm!q%ac2Ik1p-ItCt>}*c+cd{ZDSm^}#;8 zdHUet+Br%!bpZj$3s@Zblnf-=izp$+5R06uBfIyaoG)wNM?x#OiTCGmC8MZ5;72hs!;~Xf{TzZh7)xk zO0%nKX-EgX{8vtX<>%iLJ)>y1x7(Xk%QmlXe&0HDV2-#ZfzkSN+!QVfeV2F4ki{7g9m z6bX>O4C6E7sFaOMpGB|ZH{bu_)Av7Q8Nf;jNGwvQjFaaF$P`zPEe=EkK;+vrE)@aO z)KxI0Cjfw%GCL&DVc=$tzD37CFdU!Qutih@qGm>j;q+mDbgOG;{``vuCb4It{^6a? z(bq^gJ9o{^FBrK*VhIJ2K!gw&G4|V3OTiK6r(?z#1i0_}gWdM2z1f#X!`q)8zI|gY z1A;0!r%@3h1X&Nmy`ya(I&x)eTMGWkxp9^Q`)R$w*WW&pZBGoQh8nM3-rMci3>*P5 zF!BHx*Tbb9|8HO0|LIFRAK%=bY~q8v{pnUV{cyU9OyCI7@$Pc=+|}8^j(e~ThsU^d za`B)Qi2>olu3I`-y7>1WJpSm@Q)Icc*Zla0=PzFL|Jcbt{_;A3J$AB*GMJ znSsG_0rNsl%t~CuWcOGVby!3lk)=*&k&pq1(KK8+*S_@HwXbg8iR;tjJ9jT!+|ial zztiu{H?KWECor0BKfvU%2DMxFH`i~S4nZUu5}F3*e2kL0E>bF^#N-fJWFY52P2*sI z76&s#0>v%iR&asD(1@dpKt90X(b3VDAAIoScVFyw+^nCkjt0a1`-k!Hx2ou6h~Oy> zCe}N0zMXA08{aIF3l$MH4&)d>2~Aai*w7(~DS`<%Gnntk%~8L4+|GBYTiCF%VQbpE z=3>*JMv*ueZdJ$>h#fiy5)c4luZX}cvNKa^I_L*(=f{tZKK#R*moNWYb}7(d`IT)xlX|tx#(y8zd`EajO6z zg0pJ!Ns=I453O{{O)OjUm~2!O%K4}fK`EQ2B*TGa-{zEemsv{>MrB?xA%|7TQdE^X zKUQWKvIxcU51SlL$SPE^Zp^E zHGoPK*DlQnLhOS@rC^|MjQq&%StUVrBz-H*fgj#m0G5RYI7z&J0wnR|`>9`@NR_;(Ie9>*H<| z+ivA}6Bjau^wPY+KYJ-B@x&OP@XH}8DE7q>@A%~n-z z8JxpDz%YPk0_T~`dH^sJ#0JR#$YL~5BCl~k6F?;Aki3MRe2byQey#l}cQZs*00c&f zNM3X>Q*ui}Q;mdR&Z%f(PGmvNA)_e+x7f_lqQda`dmlXi(#tP?@5LYkro{Mi`ZLgu z?o&(F_8L&0Oz%`#Efmbc%CRdRSE83`fsO2Z3JNx@aWg@RGJVpTTM;i#}OI`8A80rQ#BKW4)U%d5jSVvH4I^T8f%GKr5Pb>+Q z&^$xusq@q|JZl-qavpRH7D9(%;o`+zc=3vV_B_4tguA?lJ2M4~Q6lKzAUKm`d`oS{ zf+&DGhum^BUG<8LjCyg`pT95p43wq`IPrCUcs@=PFe|>VyY{x5k^TXp+4+fw`$fQPRBJ}nbt6O(Z5HVF| zwi5LyQ7uMdMM6y~wnIcnwU43*JIBNt#Xuc1U`youV(DFL2JAh0=VrU@@*KAN$B&L5 z-1rhzn>nYR#^79T&*mJMw(Y(}h#{aSc4!i{-^j25FpDAf8;M&o^3D+ebLv*)kO&C4 z>42Ls48!WNbDrBdAP<}4(67)nNSu^=$DO6*e8)L4FZ37(1A^3?!L{gSvQ_=Ua$YjU*#@ zj|e*Y*UOU^c~yjp)%UFcX(r}5j~=G}6`fqX+SV(e7aK{L^rBoFoSE}nII(=biq15O zqSKX{v7^>7Dgoso$N7YDnx_iYs02*rp;!ge>qSI^g2PY0`1;d#Ki2IEOmeZ~%p?(0 zi$wO^F40UkCm=Cj!?ysasX$6z(kwkvAhMYf5upPEVrOOs8rLf#L?ksrK#H6G@OHmC zWa@bNv~i0JMARQX*q%N#Mt|@W&2|BSoM)zFELRgSWhQnGlObBo#1O%GV#9`A3}he>IhRVmPXU4VKZoqNFY&VkcW3qZhy0i5ztcc+@z)!+oUNX{pxoQzq)tuAQ&Mqp>xnRZqa(@s9|!Y!c|&C5sONysETGvxgt)k1d%$eGv+@; ze9-v0XEM+j7}daboV$E}p)njEuS661s9PZIu1PbZ`s=s}ZLljLdG$yqYh@K5)DKpn23oXH|RTX zjr1FfJyO>5K>Ad}W{}5GA|jeZm59VZ&JaNrWrG%glb@e}TBH`7`|8FgpMLP3b8afI zleE@pl89AQE4WsYev4w4Q81T{vJBE0MoSriY#PeO@8Wl?8>W~MDmWIIG6F}Xpf+LT zBczl~1XyZLR~z?8UPmMa|-}olN*zUL7s~(5Z^ID}; zc3+f}fFtB$ZJUKjvl{PQ^qgAvD&IRB@vTTt%aC7%WL>vPmB&ZH+B~2*!68-sL71Le ztjm7};>X9!k6N})@nfcXa+CQ(00g2(r<*tb@bUW5Az3b8U6^7u6B4&e@J@$Q8@9>A zL9R*7yowRcpg0-Xb%X?f%pL#$hKjeP)3<05JrB+Ly&fea8m z0fCwTD?0~B&Jhx+;+MBh4p%Wb5v(RU0+@kgfBojk@87zIrbv+;Dky+n*!R1g!_@25 z02RoL0UZDnIwC@3Vj>31t4N5Pd-_^JO-yA^3La49cL)G5XKo#X0b?p8i7nH)-MI%^ zueU=~A_BwGaI%~Ro06TeH&uz&tb5Mt-Ua}!{g{w~LR1q|K#(Ap7w)B3FZ-?)(4&Wk z5<@#DCH(mM$(@H{h@ukB!03wy+uyx^|MVmv0(l1p&arpwn80F^s39sK5ReX`@B3(A z?68!#G!Q~G=ldaq7>rm|p=tciE<0l9tqIM^|2LI4R8 zwoxTBSYkAd7E`M&L{O6;!+@X~qiQrF^v(ccR539C69oi6>r#4oe|o4YnKc4PXixwEhkoV& zO*OJd-!@T1CAiixVHEk|*3mm(Zi9J9hd8fX9^buX!; zoz>l#H>RCE+{O1*&QLi<24yvtp4a=f~I^Da8_ zU2}9SufKKo?qR=G1mxR?>z}`M_u*k=$3}=mP1^vPiW&$QXg`=K0!R$W`1kM5ebwV26E|003b3^JLAPZy5;cr@Z|8GYnsKuE_tt}+!8>tUYMD( z^J%9dm`c=Pa7}|C1VLr67{CN`qOSoGbu&oyeVREEg9Zyd0*R=i2Nj|onM_5J)t$&d zkc^y9006^a!v;}-9B>1EhHi$wdwBbsPu}@}auz_Y>sZzD>K)DIm7=F(L85GDNm!QQ zZo&kqVCEVAnMD1RLr#7wOysW=x{R4cPA!H8mioJ$0iSxM3hq;)T`VP|JQ@)fiWtiF z4k9YHcfhIu6#`pdKV!qrb5r0K5o%giI%hVe_-6n-XW~>LHsR!>XsU{J0)#r9^$?YD z0)VOIuCpmydpg~tZZs-#0OR@r00^W-92?r?Nh}tkq9*Kvb8p&uyN;-23evWP?>OXz!?T2^nImbygO?|W~FnpWm746@0O~CP>*HyI1!JlOAPUQd; z5URMFuaG20QVwx)?YbwXe#Ue?EGz;u4wq@XsN0K8NM|S6UmpE8Cq@#tVPwb zD#Xe+4XiYQL$gwUxJKzwZqJl0$JOsY*%RZsk1Jh&s%|owEu2nY5q(H7sJ{2kr;l!b z1r`k;)w3Kwi-p><+?cE6w%tXMlO$*s2eTldMQD!D41W<`#yD<$! zsOf-(Z8*NC+hZc;olCU1WW)%d+mm7aNTM{$1Gl_v=EAUv+aZPlOxbxA8TySQhXxKC z1keyf`Z%nH^(w4ZGHihvBpZC4cg)7jI+zSnQd1$%uEEQf+vUR7eL+aszFvIw2$*z3OtJRK0-hzTWm^yx z44x3NI{N_N5E{=ZF<3MKh-g%w)S_Q`a~m z0#F+QD3}SecgtN=I=%aKzh1j$*0de5M<#S&s;=qSu}V~l2}Kc9C7M|nLdvf*5gGb4 zNyvycq}m;-3fw@m078h{Qm5G=P#k*aJ$na`^&3c){wOtlF@%WPqY8i-v0)43(fgyr zM<4#-T^(Ze)>E#122&Tk6`dd_B2J7t6-+XK)xeG^{hO#2_28f3hy^LEe7K+%RIIGq z2NQjmAkm0=6^ExCBPM7w`FDk}458(ee9M+oy2?y{rieEAJIN`X?(SS8Cy}`Nyp??? zgeyQlh4Rs@J(0uJzMpj>8(DkR&L+kzEPo(*o@(XPGT^D?#ZgS=elp-3J0|ZO*Y*n0esOd2D4wZ^4qr$4^LH1)MVNC-+c1;AKrSzK;#ez(LhCrbiSNj zJ@1#ZQJhydeop8aPgo&gX+cWWf1tAOt0A#&kBrV>*=CQa?0*yh05xbmw_P)YaCo{M z%R<&ecIKSqOO0y_b<<7xSHiUjQ9HfW3nW-+pJ z>vSy3R$;KBc48EzkHCn^Rdtx6 z0YHK4@uxV9C$Cg*LHeDFi)jQ>`j#E1Z1ahM0_)vIV5%X>)gdwYKUQTl3*!9BRH?P; zRE&Sp#OI;rScB~Pn`#gS@eN4|A4T z3PX@$YeFF6c7bTxuOSSW(oi^6ZwEj$(R6YUf!Gl_H8mAPQV~K%_A#W>y9JFFLpF|u z)8X_1s1SKKzd+q?O6joJ%dj#;KRY1j5y^Ry}$hJg?5CD{EJs+|XBh8htd3;~Gze7D`%HIdcbn-Vt8cg{EI zb4XG8fsDWmK#&~(kn^UB2+pyFtqfa0GmWUCgM@9Lb#nvfT0lhh=DfyWVPhHr5ZULX z7eL7Qy`Y&7FfaokXe8+=b#*2*KLbAl=F`K+pS}N4zugjzRn<~%P2u3v06@V~mjn^f&yZV)LrU5LN+B#hwe|%wOGyJcS*$UnWd2Z#W)WQj zV8|R5R3*U@H_l)f)(=BCMFQXM@ZzGeQxh@^rw>)OZobdW+zbI7ph@gSg&5dD+cZcR z!`3Wn=w;}Uh`o>N)o}bc8j^QN2qAzeJ2aK#pJoDTTFnJDG={-7J096P@*bTd?-12O zA48D$KRSH<`q3}Hc>I6<`)|TPx%r2xMKe(VW6%40&H4RVWgm5aRVz>`@@vzrXQNs` zn5caCVJ z%6aRaDX!e=3oUzpgk(6&q^E9J0MqJfE@Ge>I*Q#XE1qR8CKsH@k^0YZD`P6kP>fS0 zFBh5FIaj>QHN~LFLqy14_1aClcsBA?DSxgqtxDd@DVu;nksuSZT#=g@kBb%o2w7dg z9EDAs>LoHdrqr~y%FDB}0n@*s{*Lv^^$(Wy$y@2(gTuF8f3rV1!Rdz6Of!HGiP3io zD#OMk0w(W-Q^3^XD)m`SU2IExJU{>w(GZavV-gcJjN2YWRRoby1^RV7eT)jk9WO4D zZver0ireG<^w5y8TY_uAP$Wu>*(l*i;}JUZvpKhO8HPA)fH_9(PacPpLyLX4vqSA- zyXjSw7$im!+pf22icD%E!$6LSo7B)106`R$hCWINOn|0Lx?aQI{p!L0^Kb5*tf=AK zLRN$3?qiM-X=gc`H;7gOZ&DC{-W6##8dUdLHngJ^9WL*h5_eJQSW+sp|1J?|2FE}| zLBK4vFtdiSn>7Y_cz7}lsT4$6#HuBa=cw+Al8#u+mL z)6)kxKLC(+e$aMviP3rXog*d{jZq-^cnq02_Cqp8n??zP=l~$59A%53AQ3I3Kqf#U z_DF0JP$OtadNZN{l4<~UjEmIP3mA~S0jTsCdy*bNfV@$Q=+XO=~=KQy(WU&aNay@YHS?uk33EVL5*M8G z>H;DYHRfANMZIEKwek0f5Ge2iV1w!({_x(zTVF8{=lcEtDv%O@Q;Z!sVh=h<*a9Zw zk4I{9Xf36nb$36raP zNU2(vrq*Om?kyskhnc6GtMwVJP6!7nrcg>0fNL+xwzat+^VM7PPk+46u|B118|?7v z2jH(gBrC(S?NHxLc;D$G!S;QVt_~0-0V0^8>ZKY+k{xLhfbJg3?V*A;Ms|)iINaTGB2E(}mVKHZzm;~6YN_9S@awSS{;em`$2taqNhHDC)xx5y zt+HeQp%!L9gf$?T(8^Lu1(TVoX#jAOoFrumSUq|@fdUYc9Z5oX*pUdt6A%dNEKoq9 zN467%ML4BQJTvE@^!Z1hefG)c;U0Z>S>Nny>B}}1YTM$Y%Xg6W1AkY*cmoqQ&u=&< zTg}XytUXpxyM&FEZ5YqfKZ2V}H}vAGc;iR0@(SmJZ4pTa(Cwu(zU?ma*d!Nkxe}D; zl~|*hOP=#0z6fwnQub>W8D)JzxQqb$+9868rkv;9wA)YfJms7vC6>e@{WWyC46$Cr zB@a&&J>k6GiL<=*#_eorfo%-H3Krc&Uam83hIGhQ zQu_R}Z{GX6-&$)dg6MzSm|2KZP!N$@ zGcCeG+!rb3a@y65r$qo9K*L7G~xElua3v+ zfp5-V-`E|FGgG1viX_5An|{QMX-dL;JS_Le3gWZlw0+ed^LWFx8wLRz-M{Xj*jR{& zfDQdm+(i}KO{>+` zS*-nAZ|nWda`%ck^;z6k`zzrf4i*7Lgbi|rz(SK_n_%EbBM_U`w;e)sjO zJ6A)DMD9xGhHsvDzm?-Yj*-GxBZiCHOEjd@aE>Qd2jF`y;{|A+pO`mrIRY0m3kC~* zCV#s3y}ABpG+Gb)h7rPr4Y=T-HY{HYCb%z0VV%^K|+_3eno-PXH&9HKD;P z0mZA1+$e-!L6d%isK`zj?TM znNnhsL1MawY42NOB2HJ}3~!;!&=QjgB!O-Q4A$H%dK}a#BVxCnq0Pv%6Ps2F6E@N+ zQziiISWmA5fb7!lZK8=JOP<4od2^wFedu2}pog?q1cq z7tBl$J04Qz{MMsTC&0Cuw(v;1xzt*h>TV2^%#spGE{kbv;m~TXM(z=WfJhP+f-?E& z&u0$=n!}u#f}!eZKVMz-frhJd?GfIqdVyGVMMh#S)_Z&AUTC{rxcoF?umCI~0z!~J zKrttflxh({5lq5_OoK-Rxg(sudfk5Y z!OPp*RvHdRC8BVWX<`m*%froUxOaj7G$kQ{2Qx=_Q(Kl2?&JY?7A8ix<=xfv_^pSh zU$v9=^2h3c*)&Z;8G*VKEfwSp>mqS1LgWDQGzFkqqCG@wDNUf%9v)6FpO@Pks|%+b z#585uKc?wwIUJvV@$NhcWX_CfH=FggEe?mN1tO>1e?ln}!Zoxkp_LI_H zOXCfWg3fo5K#Vaz1q2^D4=Xxspnb8=zvp?6`?|u+CG7trt8jU!3w$2G+oFzf#Fa%K z!DL+U>K7Ql8i6x8-4T2ZL{^Rjh|K_P-09{?^+R?io0x{O49M94W$^ORCzNqt&9E|=^f4uQ~@MZjTzOmnr#4ged7_l3++yjU}!Aai#?FXN||2yGclqR5F z#O&Shj&AO>3xaEbJD4Gfa`s?KnJ6eC%zH;zc!Y?X!8BBvL{bX4w@O-s+?S(ApLqv8 z+=eOwY4;ZM#GGZCpv?}qrUylksu6kmXySs5@nAFv?Lt5l$$T=;idE3 zTJ_U?q`4ea)uNSocLirNg$J`N%e|TBJX4p-au+5rsac;7DTF*B<=oUp*^*i<#SNjM zP2B^6YSz?i@zz@6Rd8x3#g4~+JjS#dcB1pfJIAV9x@ZLEn?>Jzw(jFZkO9Qf)T^3W z&ntUGIr5{q^$vD=3P{(92YmI-bF~^5qbB7%t4s0uaUSdckSWUmqG|hGdO`+ z(u_1cJpJa?Hy`BP9)WpxO_XC80Q1(VAqT>IyB!v0VHR!?9;UF`)0Q4)y0|-7WV#~e zum*1kckmDbig53{DN`^E!4ga!j<%p4fgsM5c7e%*mgB?6zyILH(--yl&})D$dFto} zA8V``17v;l=$!-34GU<*0h{e#|F_nvobh)1SgD8=N50Q6Z-MUiK5+(~H(dNnK-JE@T$Ap6U-ycJS-M%tFQsY zn~~dC$d#Zvo8YtU9NqleU!2!}y8~x?OBcT;fDuF@&tBdA?Js|6W$Ak((B+wH_hLG1 z5${Mc!n_p_KrDF|ea!M8e+ppzPLd>q0N%>MU5SXmh;VN#M136Mv)l!a}=OnDlf*?KJwfom@IbHvd$x`V2gP&5G zLIWVmvq!jTtM`3xXWmU|a&7fgv^1zD0+E=i{bsyKwjiB{kY>70FKJyY|3TyW+y^rK3b^7G#@tdayxKFzrh+yRvoDoH%CtuMC9Go{;hWo&%Qj}zZzLH7S+(! z+|A7i5v~B17YTUrqZRy6(0BZa|U02O->?h&UxleVR*`R&%V9z^=`#_9hhX%J=|Cz?r9A zcvv~Os|T5RfE)=yU1++G7$s%|M|kLh^0K!DaGqubWN82a002ouK~!aT&5{xP;)`#- z`R3*Q&AqkOM?Vp0RD`Y`d>;_kqq80-de_nffkw?CHUqJR59e6n5|S?;wC$_Sr~F4R z_(!fQt?zf{msi^7;>B^{exBcGt9&?n{+H3g`ZgDSaBT3|J=&CHo~B*ywORD$If8)E zRd?3qr#|R$TtE_;rrmzd^CTn)ScKJ5-OMApwoI)}RlComX02*#YO1Oo2#~VmoKosT zvermtt=YO@%0`TKjs@0TNpJkwnll);;lgh}b2@LDW!jE2zW+yGtlxCAPXVHL|Ms`v zeEJEI^jYly!Zch7Mic}l63#m!M5{2To+9HM4oW$IaC2=4CmOM*dvmQ_mk{9qds`?R zVWt`~1tPrF!z;H+AetTt?*bB>OiMZ3xGCqE^Pa%~OUm3k34|nP?}Nr*RSScliydBR zec&mH?0q@pNv5l7Z$`p-nn7=r1nSbqlBt=Q`Lx>$ON4W{ z)uu(0_#{kYk~kzwm@)P8T)uyOeEPDf@t_>XtY#V;kk+*8Y97}3l;ZnXza{f}(AXU{ zSf|05KoBDG5yFO#W^IONArfvD568uNdU`VeTlfnMCAgrCH|XI-uhaKo1BN9~kLIv| zT7>!Qhx+lC_q7;vVi8{yKo;V}r)9CmX`ZzlS}746Zu6Y?`|MUDV$PYgc~}s48drpS z2{aQzZGQ6OsO|Raj}VM-xG_hXk_d!-nuOiFwUo$A-JEj@rr-nz(6k*QEY#tYcUQ>S z>p^c{F}Vm43#Uw!(r!+>E00)SeS7=O2U~S2@ap+1;na;ZZGgM7Au$v`*Zd%1^`_68e&YZ)P&{+NSYI?Am2*~V;L+;lU!wIT z-i-gP=^{FRY=XDn3k5c&Xw5XOxzh~@2THFPIiA=H^@;C=D#9|Ql!UrsT!edXMOrOH zKf{qqk#+hcfx4(>L~z8+vYT>VW#@XAk*jGlHE+#Z_lPKhU=*iTPp7&RU6!^ir8NbD zgi@9?$yq#!&^h3ZEF1b@=d0M*IEszBqcLKphYlkzKwBh6BLI8Tb$s*x{itWFfz93w z?inod^_SoM_P_j>aN{&nz6z(%7Fvb?HgmW$XG#;o!WKx+{m#+DQp)5OT8886P9y}7 zYiK1HGeB%s!VFH~9u_P!BJ^})x&(oyne)ya#1jF!Jk)Xra+-Gi0$KXbv2bstm{kxl ziPjQ<=63(x*USA)TNa{854XPD@$M=_NR>jvT9~?3NwXxeS`Y{iZQ4vFbEt*4c_*n) z5X(FbZQd~pSA-m7z1cJ1YAGQcBr;7b9Gv*(_2Ks)yuNP?CSTe8Epg)!-MRMI$ekE& z_nBrv1Po-|zw3^Bw*qTLkMy2Khr0#26H1GfXbKPou^Eo1rnb6;7+wesO+xey$IK)Y z91b6Ew|Z+4tCqHhS$Kpxs>S^hzxv?ytJ~@Z5l-_&1XH`YUrKA;)8Ab`acg%kpO@p2 z;S=*d?}R8#VrCI;&BEQP`qJD@OKYu#hpQ1ySAX!w_5SJo^KS)2)YBdY56RrOBEnsj zDSBpxq7lK{LRQI?$flfyFke5~zx|e5Io&=xJ%5JUQs&X(!HK7t=PYnLzJB)UZ-vsd ze@rC38J;*>cl9KXg3CU0i>Wue48`TvTr0uJBTDt<;O-$J^A$@%tG*lwPQ>789ne-; zGJyc$lsou@yB}YX9!VrP@&1}95l^?@etUa=|NPmr(3YrV(?nn_UFkIsL`N+fL-tcK))AnzxcL1$Z0eID_VXVzu>#&0LVC3FY*%u7> z#W`Jqdw*xTpfP~B>=x*VnwVsbKs=!4=Ia=Oi$k9^xw;``IhWdRjLhh`1vU!Q!`wZ> z)y&;{X;K&AvT$?j+2dN4Wu_ zgPTDz^3H=IILyPni{)ylcD#tr<%AyYU?sezdFFW^^&#)WcxR=`G&85R)K*G89YHWC z?{*&0@BmrUe%?k@YPeZqA~ix-`03P^*7`bVs0T__RqeP)962XKFozHl{QdX7{_UrC zN|RlhUJw9YOW9~3`&x^z-lopP_*Q?pKD>SNI^aIsq(C(FrL=0=AHfbufUCJ$0P=8O z7d0Xpl_9=zJP|-}VikIEYA^0gAqKMWZb70Klmr~GZjB<;p$H=R7uGg}2&7h!~t_3#+Gl3d=dG`=X^wYcy3=&2wg9&J2b%iw+p!ATqQ0`UjA!!_!Z} zVP;xeJH9q+5l#$u?NrPp)07f*RTnjFwbq4YM=`obTd6EpL}K;MkGFb%7kbFMlyVMm zXiGAsX%CX+`RBLKKTGqpyLv*L0@6ixVK8fb%S2B+45(eHwLa|EwU_-fkM4O$4#@#W zI{{9_VFg5p=uP7(_c0iWIE}!tRzE%`a!97>it?UC+UfN5$Db9YuRs2X689-S80BG` zJ9wGV8+wCGZz96*A}$>E4P94P1ebZ*H+}sJD)9`;vAym>6|OtAE7#qBbZK%Q}Oc6;*R`0%_#F|=0&pEE6PvPpOX0b&i+cf|wfH8x6-FL$|BBnLa zR`c4_-T2Zltbg5)JD7bC#TdHU_jFTra}nC@=bSRg)D0sIJmQ)Fn2@?S#Sm9s*Y3=3 ztyW=+y8;e$J;oj|#rckoKVKt)H$ea5i;GaK>+R+A$%h|*`1{`y1*aYF-!ijkH9A-0 zfy4-~%rt7E3lUf{D2EfJ9YF9BR?eq>u1YW>3U`u8C`Bm9Ut(HOqhf=aab-q6^3o!Por%h;1!UquO%1eSW;ZdHmy_ zAV^IUGmDrSO9~Gb1VwY>@HFkCFCYbzA?MwbpWHwF>h;qvAN}yBp+?vXi#2mNGa+E^ zZbi$HlH@t(x86D(9_sRfi~ytFAx(~y^OJW@uO3c!PkDF6E%Ws?<$~gHf`ik{S{%6h z@^|v+@w|Ua%XK;4cW82pKHZ)~R4WI$2guO+wEnNirqL>gs(&5*!q9eC_*dy8c6&cRue!PlEjXlaGJ)7k^Q14%c6O@rQr( zC#^NCvntl>@><#XL zHzN(&Xr=QT#0GL_Mq|AYT$~OOrNnd2BIE>9FQxfLq^urv_f!DlPTZThkKh?2B|EGD zUj#f1g!M3&Xv>5LLe*Pqt*N_Hx9T0%qR-dp#S&ePKVqe2dUZGeH7iw*4=3_ACGO=& zJvfimHeQYxxJZYeKQ3|~XWLEZTNNW0Jx*W*eP<}SJmBX04=X_<9uYbnPrv)yzdycu zK|$&I2f-ZHye;8vdrXLgWg=#{g&T7sNv6Tm6^O~rTj{$c%wlj@z4)<@17jABFsyn^ zlxE_9RXyF48*}FQEk;)i<*?RH2X{~No@FMFfFUt4%;I!9dgwIobI#UIrl+uSc>1;L z66Wdg4+zN*&-0w}<9Cu!nr3fWA6|ex=REEd0f3p-Q_)hmUm8qOwvNGyaPP7N+xh}}OB@#kz$_jSFsH6L4rW0>TPv**BVq&rEGTCG<(pobjh>W-Brz$*>41=uQE&=C1>qQ{uu`FsHDJ5d|!Q!u) zZM?15rS&|2M8p;?ZFgf0AR>BI(?yw5SNx##L~A_~bZNfJ&XlxIK;6t{QF|L`Ba`44}8`&ubd+8*&(BlmuD`)(Rc-x_B6 z)@cg_&RJRXL3BhUK;Y)y%Ytc|C?|ylTler54-0bQ`(y2%pQ}2N1%39a{Oe!7`s;uH z{L?R&psu8l_Bqe{{olNQ_q(qTDd!f^!kfD}0#q%kqPcu|+y2AfKmYpE8xP_ntu!W1 z!dZ|257%b86f0F&c26F2o?1B`A6{Ei5BDI|Sc-O%rxQ#JOuOWzm4`!kn=&yF9zozd z?SJqiE2q0}zYqc?Rstg!K{3(-IZr||r@eZVVq&)AhS00=CJ?L`&BP?g8h*f5TJYZ_j+Q+6w zYp^zeQnKu>!qk>~A`m2^5mBD6-K+Zklp$){VdbYF?#HF(|m8fDjV6t5a>mld&aSFHBC4 z2ZoUv(Lg^IM-bHPcxtDz)TU}Z88ieWIzP)7lbOtYJE8ThXeEX~Lo%19l%`c{sGodd zNrPOE)ohGALEC+L<743ZRt?e%zieCFErP;IDqP;@?Y6HjL7zu;dw+cQSMMGlZdfE= zz0E1P6<<#5fp7wG5{jU_Lx1wk`t(F_ro5vtv=gidQx6U(&=ae0?W++UV5aB;eHg?L z3G(o&$A@s0H1YH#+<3~&LS){KAd_hqEFK`9+^m%aA`Fob5ouk zc{xRUn6Dqn)el=~eI+IDm|;Lrpz0VH8 zlrxyNzH_+KvE_gNt5@H?ZW^#avoKImw}=LO@%-?2|M2p=FAhYkj#4eu2~kcZf=HMh zW^Un<69~*xn)gX$xxZ=015*eSqGyA`-FTi-N~VU0e6>?;r^CS`h}q3st+m$a(c2{Z z<;AxV4whC5hY54uWtL>B9^iQj@|1U+5&$cUB%%2#+`|tUL8=~>_D^WH(|T8Lzk@dS z=GrJRm>m=jPKlEcqP+a1o?h;+9!ttiE!>4EOwByd1FW_Y!Godg;g5T7AqE24$m$A< zWMEPaG@?EOCRnoM3_?oM2dxDFVG!Kh56`^ZO1_faTSyZzFNedk&%gQEpZ(&q_kQ>E z>9^9e3mswCvstmM2b8gmh`~9xxe|*P@G=;pOFH?Y_P-bBtce3!SgRQ>Uf4XuTFn$mtwiLo81R{-}JcO%@QKo5$CMR8!HWBXaHa_DE6 zk0H&)>j;iD4hf9R3_y2!^|BYsUvY+*z$!tE+k7bT|N!a&lMIT2BY9RZI0CB%&mQAh%56t-&o2 zJI+a%ddVaZVa?P*6qI>l^!Z+uhzJ=GX6mr;uo@qJ`1)V}KR^E;e*NOv63mIm-5~0d z)f{lRbpm)x`>wqr>(f6xi}g`t(5c4FZMAR@xSLwI6T%n6-Cga)n?kLRyMJ*g|K^v^ z|K`2>oBPHv^5|2?#^c2lVUp;(7pM0=zbTDQi<;A^#7Xh8#4q1{`47K+xg4CrqKCl3 zy=4-BR`t3VB2QUZ%&ck9ZkP6tc%I#LIoz+!Nt6-^BPZdoAn(R@+V5If4tKYv4Il>r z!4%V!=SNQ>;`Zs6R+@yHn==t*gd;2vZCR`~SG6|u0b$|w!R!=~)b=UwS%~t?`B4Pw z?RVZv1h-m4hVDN_=Q%TRir||s-=)yJyBgLy;Er{Gh{GMO5n*O4j8T8o*TjHFxRu4* zf=(Mwy9oH{=vI3KN2}Bd@@|ZZ?CJfUJJqTW-!fC0pCIobA}N3S@%s+mJ^sOafAcq1 zl~!82Z}zSJzVj(Vv121}Hm`8S0J{9e1$5(V2QWg4ElN07@tob2)dH-}b_eS%{Mfjk zi+5PPpEEqIPAQ0xMfUTwn=&(vk_GpbdSdeN$E)kRWsPAG&8%8a$9qJK32!T$_S0kP zB|uD_50ddV#Qi5MyZvr=wM#jtb&BRl)W(Z{ z`Q7pMB?Z#;4`Rw;>Pvwe+`t$`Trz=@1EETkiD$^nB4HAPG*(Lit@y*NQ|M>5|{O|wur~mJFpWRg? zo_ZkFHyVS4#Dg3|1aJffw0UQUp^O+pAX$^#po(@-JSLfB5L`-~GpD zAAWpajJy0aF)eGlI?n3=RY45?y=}?akz0wh3)07xaOxDcR)~KAP z{Z&~Gr^9X6&0va@GYRbBwz-mcJutzw;$yFZr)unb=64XSd(|e z8(KvKp^Kmouoy8x|7RLn5K1J$f-qQN3L^GMLDEWV$3yq4sMi+_KqP;-@#Ri-Gw+`u z37E?L!?$02`Lloem*0N}OVOjp#;^CT2a*qguX@nEG z1m!f5hg)T4MCj?R+&(AvP?h;Q<=K~)5jwr|$4;|0E`k*N)ec4*BeDRIpCZS z;IF^A`|E%E`TzO<{^@`I@YP~{=6lbarY~>(=ENeY-{MOLX|#Q=0+7sXL16y+wm#f0 zlHl&3Ff?_&eb8_2S}7JpKy!&tzAgXuZ(n`;bcq(_c(U-cC&?ix%uFQn&_ncyFpH

    aX8@{@agFzkK)R*T1{{=)>DrFOP7~vjh-kJ)r~lEUANCN;!2gGzw1S2yK<8EYpr< z((-V4{q%Hy@LHz5G}ET$%t7EJ;Sq3Rx_a^mL8rrgErr6EIXpzt?#ZL+>N>nVJpY1) zAc=X_a`Ha9lQQQFFS?w}mQd4Dv@X;2I|xKuWCAiELc;m+6WTqB@cQtbYwK)FfQS=> z!Qv5=k~4YG>FKAs-0vP;1xt(pr%r&d^zc61L8GDljBMR&V~X$*k+tS(=0+)lD72w- zK(KHVAx0nx=NZC?SjEmFw6)h?5g}jyfb*U}f%MHszjyFEfAq({`_ZU8Om0xaPffm0+y80 zl+%7nyOH4?jp^QZK=mpKOL2gXUf!HmCgjl^3A)_}rTL!MP5Lxgs7 zp7I*4dspzHDG4~b_7bmleuG;c-uYOKPWG3ohtr~}y@b!h>6}8?oV%?}=Z!nC-p-ZD zUsJ{EURx`*wbm7DF4ppU@!Wb_&$;m4)GK`VaQN`o?;h`7h@`xKi>EoX*>WUrJ?Ypl zop>TiL|P%;SO`F#my$Uc8}H;2ZT~rcrp*~JPi$T<9>^~2S^Z8 zt3_*T%wTq>FeP^n>RqFj1w{10hp+#yfBn(_>Hqfr|NPObgJJ>w=IO(~`Oi=P!{5JZ zO(^<6jPo5|@8PKWNW>sE;M>=(Ev|MF7R+QVzI=N4;OX)||IO>y&rXts$N>8M>-OT= zNt?CS0wlt%w63{7C5g^kyM?WZ=gi+cJN^1M-+lef!~LN&kDL=zxRIHroT2U(%xvaO zU7NO2-J{=SZ_do_4se=gkbvCvr1j_st<_4^aE9fbXtSV@lv-;9**|^^tL6T+n-N90 zcA@>WdmJ+B@m`mOqQOUFht+nvd2MAupdA;jN=$h-NluU)wbsM2-rn0%2ioyYc5elX zEw`>Ggmob1%reawjIg9Mb53FH^x_Mll&0O;Ni<(OXgYHnF~(&Ffaq=0!;9}i{!Zl4 zD%_BS(-fvw?#YX{n&zuK@4}q`2oZW46NU&Gu|B-i)APK4%)2KbBDd4c&GWCm`=g)# z;^F@A`(OWxf*pfg9q>15#4h&#ISot$PRGyV;`hJ`iI-S;>9?P=#+NS|m~wthu|BtS zE>Rk>33}aXoKK2~m^mkzX4&PG(%LIVAfjQk)^-LWbS(}h>Cx9(T{LJ+X6a z`r^AUK4A`~oFD%PV67)_M?!>Izkz|oJP`{KOqC^(>;aDQ8g^RmGp*=9;+ZYb2!Oy~ ziHJ4GB}B7w@3t@rrN@vRftdw8UbYIB00l|fUAI;_CHI;HU7XeXgjFFu-n56Ca8gsw zoVB^$fC}$_5(a{&X&%u;qTwOi(DTqN4 zrjDRsYPFY%l3VK?KQMzCF_I*W&{K;nk|jJ`$ZI7@NWPLeJY{y`_ddM&|JxstD`HTNBS+BXNSR3Z)W|^hclGwg$vm!h5)aNShb8^; zeRcKIqRlMLNnDqfzx?(VltD}kW@)OW-tXuwAwy0GXQqI-2Ru5r1D4^aML2Qd7zIVXexNJ(04 z`$yNe4>vc@zj}-RwIE!r`xIz=E66BD~F2=ML^(yYrJ-F~`)6$GX5W4O;ZJ||hkx*=zxd?+5B~I@{KX&r`Om91 zf}Bx(^?o;rH>dF`BGjMoSH}95# znWsr65#BU5cqkOCJjw=b7$G017r^^^;9e4xL{bt&sG6Fu5y*PI>ooxw4ZcJqOx!>7 z$i@Mqy(=uHoOZi;$`fblHrdR&&?t}Xf!NLoTi``&*t9uuWC*qBrEvW(d0q6l0Q$@E zH?%GYF0=U*9#Pe*s+q-l2iALd5t?lldbQ%T9hvEHIDGOCzd7B$265g$q4}{}vvQ=c zE^I<9=u()>VDaAiJ3R_8^dZ_YLP0(2V7)~N;Q<4@hXNO?Gh_@w6mHPs^%!Qv32CMt z14jTHTHwKw2*f#^{Tj1gcjV386pS#nhu0LElB6t>CzyJ>%hyjZJ#uT|t(HSQ-D^9T zH=cJSN!7G!_t3N!j|G_lMYyYZty+tlrJVD`KrlSa$Q45hwNoG(u0%d+Tf;nR&N9uj zg_|o&VCb@2xTkqXkXF>j_(5lZB-+iBg?#wot6%=7FJHYrIrw3*|JN_S{x`pT_QA{g z{Dj*|2k=623R#?(aWMPMi_^dR;PBaP`RL~O{AEo!oZS)3l;+f091p71ASr?<93-dX zsAf(ndw77Zrgx?!pm2AQ6z0}+jI>E(KM<2gm?P&otWO*S3#TN(Tx)apprAyOn9%z@ zB8d<)i|FZOtvM0pU0CBSeQ}{60eJ%?gA+w)=oqQp>+K? zK<#u_kM~S$X3OEB)#Gk@d^OLUE$xN5_ne!RrPP;QE~@Vx4l=? zjJ4H(AmyM=bF~1RsGSbSSD%59@(#qK6<{#dH01C{>XxyRw0%=kZ!V1R2%f~X`ErU- zo^}AdRt5#kiH&6d8Bf7m%N`RUIO+YJFAwweW7$7OVnjT=czOHs^`HEcUvS>N_xFEi zRjHFD7as2g9;{GL+h@cD)SMCe4L5$}YBmV@|M&5R$imrqKmUMM0%ASv_BKpBWtnpy zeA&~iw8aYO?&DfL;=O*K*#N~V#z{oPl4P2uDNoYJq%+6asg8?x9M_*fYo}ZUuUOk@ z@^OEOh!Kt~EG$AK-1(^BvF&4AyZ7eykqp|r?}$+j!vSGRBk{t=L@-g{dp zTG%p3w*biwoQcUwNxR3uM1Jyei_k${uT`I`^}L8@`u1QMJ#Q=oVz{@1`vL}JCQiM& zf`tLsx&Q#r?udGlDQMc6Dwsl>k_StlJFmyrc6dod(Iw`Q^!OY>boEEXfzY62ZAmEw z5))+F88}+w!~nJBsO97odCGbJj#Z5e$+;X3^YyhPc!1zc60X6ZNPQXA`aCx>QxK<| z!ku_0OdjqO!o-}3(3*mcA_=GP6LSFIBqP!1Cd3Ys-CiU}*v*6KSnS{b$1nfO-{;-c zw43?yem9HnAMKM&XyxWXpT1}h_x|?VnNz;KIRU7Pf+#f1!xwXPaL=KJaM!JjB#9tq zCY*#i6^S5rEieyIp0d05;uJkK2lAYH5ZG!li?CjS(HU0q2%(sEQ*ABOHJm8ITw7RE zcjv@RoOgM;+8>|RMv3{rF8w6 zgzBpY3eWrNdR$I7-_4JnKs~@hX`-wGZ`HI(=2BHANps@mt$^rqD{=)l5Q7Aq0!?<; zHtl`6_tR^-{sT!9X$v)yi8@77D-m;=!>rysKixi?uitSk)@@_bB3%%w^&q=FU^4HumEN8jJ-v+8#inr8^6IPkkN(x}@ej-C z#?{K{`0T4s|KMkT_!ocmFF*eE-+ubxN5A+N|GZfp5IbsYMq$fH3~Ute_-(At|Ct4% zSQ!Gk#E<@KdQ;0`-Rc{}(glYd7e5E+0)khN>NrU`$=pew9!PC}x}Mnji|)@7`mCPO zY&zz5rIe;A$w-_~R|;Dhq&H8cUnY>Sb})BAE?!Z$&!pH+92De8W4r+Mnxat-)GgAQ zNyngJwsak0T{BM7t6v}QZ*op)x=L4Xx3*Y4QUqKPAfYq+&r_IEN|a|<^?DoDs5f=? zXMFHyYlJb}_D;iXBXS6!2!}P-8ZkuAF?6*6LRbTwBn8~HlFVUlz5q<&w3~?%u>=8T zdc2DODD`A4YH>fM>mNX_ycU3nm6=HrKps_01ld*1IZU-ycO#~h_8t{5c(kQ)nn6^m z3bT5olyXYmWsy8&%I;p5no@32CrO->1#v{cwW(Lnb0<_pJSd5lMs|WPG+l)n%@YNi zYBbti<*u<7AdwW&dL6M-psygpd z7iWmlyd2X0(Y)WYyv(cz3(sKjA4esFV{+pDk(@2#W}lX`gnF zyuMmqfBWbMe~wvwV8k9SY!s~-i(fy436+tCRYE)gW+3K2$<2;#hV zv(7J=w$MgIl=n1U$MRsu*ZI+pJ%T6$AYn>Vv?Fofa2%4%Tf2Qa@86brZ`we{#2yyb zwSA0+YuGW3yz5dCU><90t(o?M5pPG)l%^{^-a$+F4iUsDFa+UQL1TE#85Ns zH*yWLuof25cK(!Nq$5@ z&||cPXl2VfL~Yg`qpWOwr~nXgCQ4&*-K?FgEeI!`gC`;hvtD&-W$6YAK$_;vnO(h{ z7%q7tVkUtTK<)HO>q9_H!&{ZS2No9Qt9Jk(Twv^#!w}8&6l$%OdbpuzAkx}gD^YNo zAejJ}lAAI)-1`cgmXn8>$FXW{OV@j^wYAzPORy)IB4{}+wJc5Raw-AHB&w>dcCiR} z1jD1rbR|3mLTlANF3r?RTm1x>Rzx6-3CzsGdFC`rnwaN|Bq0&(&dw=<968Cve8o=W zO&KAKJTtnMk(sMotzDr90LYj^B=;dFt(0(RRqsWvMCswxcWqff$;{m~oFrvVbA*+b-iBCsa1c@r0< zQ5+)c5ch3$*6O6#?oEF{*7B_t>HAr(7I-rbfiU;hRLzOd$CCA6=Q5OtvEu6^I94_S z0ior%{QmF$ez|*vh-u!*qaV07YlVnm3(?@GKp@T`$vv2N%sI4qy(c*O5FLy-bL|6I zQy;4}0szjV&YcAA6dHO8Zv;RRzh< zL_Bu-a|U`EP2v!&GshekMY>RK93+)npymUE_PVb$s~ zin|FZUkeKhs~!;*+60

    g9DL$pK1CED>OqAdnLXt(GkWGpnwOUPhSbl*P2U8g(YP zG*cxOA~H2MXJPlSIPVwNuo@9yLYjmGuCQjVO~^SR+?fZr$sFj-f~wlJfQV{o9?nVT z{VYQ6?rLz>Vs0T>@+@H%+B%FN07ok=+}$EN2P^Cml9CX5ueh)X0}fXr77&@co3U_& zdw?WIXk8B4bU8j8?_RZ1-5P<+yjs=JoP{Z-X`=9Xzjv@M_gar;VbxEsZ?r5ar##JW z;jP;778-=;tVx;$G-gu=j3qLz%nV2@yXdh#_2Ms&FiJbf?Clh%+fAI2K$0htj9_MR z*9ZzCTaL@^cYvj7VwSPJL19inZ*n9;uN7Poc$@OEiVyeI1fn);2g)gkNUKmUfSw!( zB4_C}W)X_$N<$Hx>dkYjZFl`PO*;o#t1q8FyT5z*)1Uvz&;IP^U;ggh+n28rN#Erc zWscoh9(`F6mkGz-1@#8z&>Npde)|H(;|%pZGKljFY4!ZpYsXfd-;cId%U*oYN}gbS z!76ULLi|8cB6OAXvA8|y)#u}cn|o8MP2Kv@aMqp}#^4N(1LlYO&f^Dzav~Pt6;g3w zDdB5tW)~mcenZ5et(ghCHG+t5sc% z*6CwCvU&67T-?rnp@UC@r1a_gpM3ej?K?}^b{~+A(F9GdIr&(hxP-wEeLf}Py|s3 zRMkApotSJnw8LEtU&gcSt=xqlXnHFgLy{WcBoP1$$*lFD^)A?36oW&^LxVX0Qw>Br z96e7YDabs+RE0Ur6Y(x*fhR#kGjpp8TC^JF;dOZ9lyXW_ni7e(#jUx9nU+%BkmiXc zAY$(BP4X4g{q#yt_p06#Bg_mBmP{<1B>FuiQgwt2d!B`f!dygHNQ8l?CvA(n0mNb9 z4s~iZ+-Nx|k+{0mg*m1D+i9A@DKvQ0&V{LIGY^#{B+`Y^ZBZ*`%>!hml|?}$iHSr@ zD-Wk|mz3Q?m&L7$ut+isQ&%Mm93Jk?Jt$larltnCOf%AKTFt6KBYe5PJ-mL(@Sv~= z^O~8NBmyu`%qdIWUwOpCi!ZGeYlY@3mbrIyu&~4RbQe|;ZmoG!I9x5ztLKztE_Srq zyw+$+ZeC7qeV~{Dpfshcw*b`JXI^Urh`PY4uq4W#SP;xYDZ#gEyCG@ z9xfk7)jYbsKGmZEbz_)lc65oYr^hC&OLiY9lXt!!%L!$UxTh;*}}F>hjZO%12{6MQ1H&bH!so zz7v5(EV|zpTAC;&gj1da6t=*QU2+v+g!8;`4EC_U6`j|e z(|9Bp5l*nsQ&?jnN*OtKmpQ_E6$(f|5e$}Hz=%?qo7V2SAx#!xrgpj~1W3G9VnVRD zd&!R@UAb$h^(wjmz~DToHnRq2U5YIy(u!8Y5a3qsRf|=1GvTQ}{8meN1ISu2x7u25 z^>|#Cr4W3Yc1UcxxR(In6=XyRhFK#D3nSSD4AKcXLRw`c$vK7O$1I7&WtSu~X92C* z!sc*?5HW{^n-W4KARNS|(56~yw{0FC1T!NhnFLuxWOpUZT&uOFS{JJi%#m`EMDumd ziNn1$ZB-$ha!M(?Hlkn=4_8wX(o&H~CeAxysJ51;od{7tm(rH%=51L{%gKA)Muub& zVzBat>N|7m!~_u5%Az;!g_*)I@86R7x-74cx6dR= z%85=7<^ER9AOcWmJ>Gn4t%A6fR*p-UN)ofKIGaMN(}_rl$=yKg2=Dq-UAJYr4%vA- zxfMchFKuB?l0g{=SPO5&2`sLQ-M@reS9Az~L@?YC@7sUVOIv%AfF64Eauv`7P%s4E(hRoe1=QIHv=Vm4jA_SM4?<`urdQ2(1+3D`~_0wmE`{Pf3{Nq3P<3IlL z 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%0D$0h$wV6B#C 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
    hucU_g9Hl^RFHV7~Qm|60SdP~N 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 BR2BdL literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/tests/images/expected_woman_all_output.png b/extensions-builtin/sd_forge_controlnet/tests/images/expected_woman_all_output.png new file mode 100644 index 0000000000000000000000000000000000000000..94f93cc95e9ce3459fa19c4a83894319e5c4f876 GIT binary patch literal 13675 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 literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/tests/images/expected_woman_hand_output.png b/extensions-builtin/sd_forge_controlnet/tests/images/expected_woman_hand_output.png new file mode 100644 index 0000000000000000000000000000000000000000..ec520a3afdec2b05e86e75dfefdefe1daf0756cc GIT binary patch literal 6039 zcmeHLX;_n27KV~YfC>~7sR|e+0$~-g3dr`UKvEEp9b%v?;=-x~jf&f6kZGK+8_M_m7(|_gO_;yv0ebP_Kg+2L4-28}s(Y*_3%$-9p>7@MK_-dIxbV=SlpY;iZS@q!O<->aXQ9u6UuJ^Ph7kEn+c+|fT`LernilfIJJ7C{1McGdQZ;v%-6SFlz-uG!#T-V zxfrHh(l`IX^X_1x@+t%le7DNF16Rk$x`eS)xMLK|)fu@q?S`c&3{0Q@0!|yu_-l20 z0?Wef3gBlR_AZI(ljG_8hX2+sMu)WqbLQ$Z`pf)pt5}l{?oq2F<#~wxQUq+@LFqg=U(rL@$$9M3!kpHzZk4)xY{VwdnD(Q5BR? z)U($9Nn-)ms;Xb2l3ciHsS07+>Y9DSmRvMNMzcZ z?@NJy={x_+c;h1ol_Kb$p5Jl2Fx*%;t=H}fRPt?}ZB0*l)6lY;e!F~Lt(3W7`^E2q z&LsAx=fzt{tH@6JO9kMJ%rxP|z$69{<8Ad?MhS5jUM({-@dANGgS63R$hiDGck`)} zwpPlb32nY9aqJf&yA0I#&*vBU5quqKZg`WWhpAWKe?}xn1V)0=vqNMZJZqwI=;C>b zE^%xV?zpM%W2#PhLd1CVIj+@BjIz$8AjS8G$Z?W_MPwJKDkggB`3J=l0obWywo@z2 zZt)Xu@O`kNLF>`=WL;ixDhSNGUzZp!b*{H*y+~5%>a`n#&M%0iyom(d`^&SE?fCJL zgs}}oHm>qjzKDi~Js0|mvvM_tvqbh^R7WQEUF4gKSFVc~4{+_E$eiqO4goVg<4Vn) zCrc0q`o-LXiI+A4})5hG}1if_- zGTUzIqAe&dr#JJpw;@TC6QFHmMi!PD%=W4XB3m#~)GsbRB?j9osim)f`aKRcDr;yV}- zc3Avo-5xgE%9spvJ^Pz=#DbK$*;rV(P+fNiGWYv3@xk)Tc$QyIZ^3}`5`>?**<*pQ zaKSqdN9a)%|FFe!@68?uS(&bs1&_RAgo742U9{<{8(;OelD0)ok9V89WCt`oIy&J8 zs-K}^wf+yCdpt!FdaHx9qR(^P?yj2yp&rvd+_NfQY=(r@Zv5TuhU~Kgp=tZ5*P=kv zy%=)q%}^Vkr}NWKWUWE;0ua4l!Upm(&5VUcChA3~hD5~BA2C!o$g+)i)AVQCl}maF zV?%_4^AO9MU-dVUwuL~J**S=1hRnQ^ci@mMN#So$`3>x4P)b-Di|2Cwz@FiPMPHxm zf9}JTs0!kxo(gB;tvD!0w~9?o=^qtbq^60X(>{&U*SHqK5?UHmN)S*I1WK~4(L=N| zCFEXD3umnFyxe*WZ z$_^ByL#!dYslGW7A>g(D8WYocTkj(b#DB19E zqTwmv>SuNf?vH;|z@hGLZQ$T3nN|C6YZE^VFeEAJ2)BZOcJNJ2Ngox6%Vx`p!68P` z_aJ((u30YcR zSh248aRt7TwN^GR6h%k3$AYvuJcps9&sSWiXgmnuP5mYJ-( zY$f$ppuCD4EX}_U%e{W5#5~3&d#wyBRG#7&J0$p2)(YI{H9Vt6`W|~}*LhGy%Hs_F zF^lWY6wBT`?Hy(KVa37Fb?tLhnVK^CmFuW;Rcw(Rh)ZxLC-%brxwU{_s_UC}$&*}5 zRR^vr!DOc)n72}>yTc+#mBYFf0Dg< z{A*=Tl54(dofBy-nC@Vk(E*U^3SwIi+1}2G3A}sFzG};4b$OnX2YB~UjF34Qvfy`4 zCy~?k7_-Zdi?VEGd*9mRDjRX?!4zy;gooZ-I_%sW(!`ju2huiLbr{rKv_Np7IlXsOB;6OG*Kv=sKHUgA2mjIjNjTB5MliAf@KWsFdBLGO6s5A1yg(C(TBiCjm`JHB=D)2CS(vb}K& zJE%JXlJ2Q_d_YS5sCA(U48xE4fIl zcNhjP71fcGv_>!w(alb&t*DjL_d}`%@ChL}{M;)A|FEs`Aa??@WvUgbqi+pabcH&5 zMO8rsck-YMd@Unc@^_$BEiie_gOIAbc-9v1@;phbW;AULi)kE|Bn)?^-L2}!sbiId z>h(>TJ;^PP)e8yC{f?t#zUPvHM65`-R?od%MO^Y$ic^{3zOFB;nI8;XDvt`nYz#>y ztF1BXQ1A-7BL(E7G8FbiW=U)jt?vEfeGA^J;Qb){AI^eb4=+#jvg>t73I_jh*JAnx KZERTo8U8P;?=uzv literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/tests/images/living_room.webp b/extensions-builtin/sd_forge_controlnet/tests/images/living_room.webp new file mode 100644 index 0000000000000000000000000000000000000000..8dca290f6257c678ee70cff51e3a2e6bc4ce3e40 GIT binary patch literal 79796 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 G00015_3YgM literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/tests/images/mask.png b/extensions-builtin/sd_forge_controlnet/tests/images/mask.png new file mode 100644 index 0000000000000000000000000000000000000000..166203af05d94bec271dc3ea34b4ce41135b998f GIT binary patch literal 244 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k85o&?RK`JHULeI-9OUlAc=M!AJ&?m$;1OBO zz`!jG!i)^F=12eq*#dk*T!Hle|NocXoPQU{YWH+;45^s&_KYFW1PUiM3jiDPTj|a4UDxKn>Ai%-G)JP=d#{xF4+io4x<~-l+^~oTvr>mdKI;Vst0IV}F A5&!@I literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/tests/images/portrait/1.webp b/extensions-builtin/sd_forge_controlnet/tests/images/portrait/1.webp new file mode 100644 index 0000000000000000000000000000000000000000..5b9eccf01a16b051296f59b41281f9e31e0dbc74 GIT binary patch literal 20481 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 literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/tests/images/portrait/2.jpg b/extensions-builtin/sd_forge_controlnet/tests/images/portrait/2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c16127c298190d43f2f3e63a5c25a1c592eb51d3 GIT binary patch literal 37869 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 SkNok{D`BR*#FrN`46}N literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/tests/images/portrait/3.jpeg b/extensions-builtin/sd_forge_controlnet/tests/images/portrait/3.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..1936d9fc21cee9ef6bdead5368c8e4b14eea6927 GIT binary patch literal 22485 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 literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/tests/images/portrait/5.jpg b/extensions-builtin/sd_forge_controlnet/tests/images/portrait/5.jpg new file mode 100644 index 0000000000000000000000000000000000000000..605a914aaf0dba16ac8937b0f5b1bb72c3f04aa8 GIT binary patch literal 206595 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 OTs*6lt6cZK`2PVpf?tLJ literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/tests/images/ski.jpg b/extensions-builtin/sd_forge_controlnet/tests/images/ski.jpg new file mode 100644 index 0000000000000000000000000000000000000000..662484140f68ce8b4af4f815e47f1687c800bfa1 GIT binary patch literal 141529 zcmbSybzGFe_V=^N!ct2&OCt@^3M?JcUD8N*$%4`?-61L6AP9m;C@BJxA}Am&D$*e8 zyWac$?!CYF^LgX*o!_$}Dgz)801&Ea zx_EklNddsa)8AKLRRL{kW{$>t3xEN901gNPfUUisx0Zp5A%G)wWks|fPUtWGH=Qj2 zxRwB5mS0U5js7?P{|TY&y?y-w0HlkPzUkoTXOF|tIP4ze@BNp5h{F_iZhtWt`WO4+ z6vSbgzu4)YnC~Al|HPQT*ulfo0VnfUXKx1&hrjq04#x)uIN~rw6Nh61T^xgOcn*iz z-2*&aaQFg;DLfo){Qv+;_?PeRXzz@}LO4w5YpAb?!?ytdLFn`!*zP~DzvF$Jo&cce zQh5wTJKZC!%{inpS-amW>qI&ah-oNYqo99&y0FtLT+ob)Q zXO|BE&td?8X8GSd_EG>Ki3Whqss9)c)!+Hz?CBp#P%(tH8e` z|M%cO`V;uu-@j~!R&u;&8{qDb{%cfwFL$p1U$mdMt-T|f|9_pt|KAn=L#_YNgHPY_ zo};g$C$1}F+$?kPbi%pY)4|2x#mf`z;`zVx@c(DE|Ipzt{O7#J0rDrm0SapYfOLui zfP8%eK*^B+#IhJy0{WNVH1Umrzbns#dFP+=9*1$||49E^0#3zc!G11I=)Y`5eM7W; zfN$Vmj9U|b6Bs}MkN^|_Ex-h@0o(vTAOc7Lw*U;F3}^s4fFWQ8SONBcGvERE0zp71 z5COyjNkAHq4HN(+z!RVrXad@RXFxA701N{Yz%(!qd;r#fE#M1q2%G^wK_CzwhzLXu zq6IO7I6%B05s)NE7NiW)1nGm!KsF#JkS8br6bgz0C4n+P1)wreEvOaL4H^KAfo4GO zLF=GB&=Keg3;`2@DZq?iPOu-CfYv}ep|7B`&~@k`^f!zM#sK4mNyF4(rZ6X15G)p!1FM2{ zz+S`VVOy{>I2=v|=YmVX)!=4uS9l2g5&SW{8Qu?{fq#ad;^E=Z;_>3i;OXGm;`!sn z;^pHt;Jw6qhqr}yfj}ad5h4f`ggL?!5sAn_)FJv1?+`nPpZKKs9Qe}sI`|Iw!T728 zPw=1PPvLLj|0F;Wa1qE57!tS=L=fZ=G!eWeSRpt@B9W{}DWo3K1sRUaL$)ACk?Y7y zLNY=gLPbJL!T`b)!fL{P!uN#7L_|cKL>MA-B7dS3qFSOMqK`xu#N@;R#OlNj#9_pR z#GSs8lUR{pNpeWqNv22+NbyNINfk+LNgt9Hl6I3WlAfZ-QNk!4ln3e& zstz@V+9ksy<0Mlib0CW*s~{U9`%DfYXCqf6wRVq~*)dJNOH6yh=wIg)`brbbF>T?=;8Vrpi zO(IP*%{EsJfC?U0?BU5h=Gy`FuU1D`{Z z!77`P37kVP}L6}TfLpW0Sx$uz)kBGfUp~&1#qMIr=!)|un{2|IK>L^+)x+F#} zrX?09HYoN>TteJeyh(gdf?dK!qDW#QY)<+F!a&`ui>Z zTW+`NZtdRYy6t%T$?eZFtTMJTWio5BXjvQCQrR^*7CBqFa=8r*8^!@sh1rq6A@3^R zApcE4NWoX3L*ZOeTJeEmzY;`ARVh*FtumRik#d3ZM-^5TCzX1YLsc==5Y>J)nA#n+ zbhSlwMs<7jTJ=K>35^FDukH}uF}PE3XG4=m(^vDk7FbI|D^qJln?u`E`!aJF2iMcpE7aT87uFBeA2A>|ur{bOI5Si*Of~#q#BCH{G-ym>Y-wC;d~Tv- zl3}uDDrow^bi$0z%*CwB9M9a?yvqF4LfInQV#`v@GS+h8F4x`rcgL*gtlX_$Sd&=W zTDRN4Y)owGY_4r}Y|Cv=?bPjx><;Y}?Q`wFIA9#I9QGV#95Wnu?#bNCxVP&hpXo!8tU?@vyMCkeh`3GeWK@aU74u-LXMTc#LtA^J^5Jb2|OhyVtW<;JunM6I0 zW{eJx{v4wkQy)tl>l?cmcPp+W9vbfw|2E-fLVm*UM2E!jB%!37r0YlakH(XQlk<}Q zq})q+n<}1KoCZ(xOj}5oORvd5WneQtXKH13W}&kZvre+Dv&V8ob4qdvaszVL@-*|h z^4as#@~;b=3+4+I3Y&`A3HpLSBxocDq$>1D!D3kDP1a4E$b}jEYGQcR|HmU zKQVqXQYl$kTSZruRQ0RcvwE#Yzvfk~L~U&yLtSb;xIUnMufeimx>2dItBJpB;H+1~V&<7rU`c}HR=s57|p@R{?owJx)+nQo2l!RNQ0ck~GK zRQIy<7QUc-k=jSl7v1;gCHCcMzjyz^fYZR|LF>T}L#9J>uk>EMeSPQk=&;K0(1`rV z%Tbxp-ZAO1?s3WSXA|NRoo~e6bWDm(cDxmT+c_mM)io_O{e0&3Oy4`XcLTFZv%_=h za})F0^D_%Z3rmZZi)%{`OS|vg-~U(+T>kkXdjh{eJ%RN{q5;@ z%=b5kriWWUe1H5odUQ;CTzw*XGI*+c`ti);?B{vn1?@%6rR3$vmC4o4&!B6(>%3n# zem(zv=l9AVk3WC@d;?hI9lY!u0S62&763s2QV19V{~H(l7ybDFL<8V|5d?=IP+SUu z!k~W%28aEF;BY)V1Rfq7AD@5#AD{5Q69@uxclpFf2E z%>DOz|H}Ot1W*Xj8*n%TgaW`Q5CjGK^9ne@sSJhS!i)b>7JxyZa6Awgfe#RXfWIaG zSqS>8G#n2>imL?%L7;z!@=qZESAv4UNy+fgEW+dz2q8*VDvUg}2pc>8O(k51ATVyE z5ZpN75ZrKa?Vz9l3mHsUo*b@c%Sz!Rf)|mlz(!f7f0Lc+uytU@ZrxW=l!N+5BqGDW zUP(-xw9U^@nR6r4Uxf^3WDpDr$A^I7f4j%UY$z~`u)H1_gcL1gi}8s_XNBq>mf;!^ zQ6OK}huN{&{P2yuNl~u2L76eg{%08=#ElD#f}n7NKJlCTAwd|KP(u%2Z{ZeGsguyc ztT1qOdD2(dZZf3$yVJuJA!agkD%qTZ#FN<0)cz z-gDF>QD{jr2T9sCs{}GTWtc6X3x>;&YR^a&=8$;XkboRucHv9ZMBy}z#U(O^+(;hZ zf=Xw;gpKNUi}rQLmElLYoa@<&Hyk)Pe*e0R7dosL3)M9LM(ZBLF7OEb%}qC)=VZcq~&uNWx# zUM7j-w2Ek|Tlmj6#Cbw4?f0R&NX^fSN%K0}+h(5eX-|5Jv`iU(`N#wh>?P&D7-5+x z{U#%9R^7JNR-&eWbC(LD7RXGP=&n>~5ImFDK@V0DqjlvR{bC%{cL>m!0P4&2QK@i`I$UE^`>^=9d=lS|z4jdu%@593i|* z@V4+y>PI)Ng2!ywp0Um>8@kp%q}oBds|UIU475 zATFzb!ArZ?G_6$o$XIbLD^i|Lap5** zfgKFS5J1qe(LCiG28XRHYJ`y^k+t zpUu)O2P8f+_q?|q(JGiKskX5}>Ere?RCCP_Yp=%Q?7Yfm_hqMZfN~FIeX)30iqCJ6z~$UA`A} zlCfvsUr?^$rZrc!pn`98)=cNVwpjU`c`kK1~iPV+D_zdJPwF`6>64;sfp!EEE+2 zN>Rc{dK5chzaJFO0b3%wnligeWUkyfbfuv0Sa_3LMs%inra}D3PIP!Jmn}^@Z8=M2 zMVt_6b3dQzN&bN=U%(DUS3;y>8vcRx?csMpY)uSW4DfV!N&$hC7TCZNx5S2XZE2=`iy8_xgr25`4%nE|Mm-s>@{;+Y zMB!jpsV7HwqlK*1>AhUiiC@(0Eiv;MMVD+3?`aBrR+dN23TiZnB^f-R9}j%HKa;aIeC?!8UPW*H@zHtjYgTIIDMT|YYw{wTs`%@a{3WGF!rPAUNc+F^h#n$TS6rpK$klb9v&}1AK9-?>b#&R zLE{o!ZzopvbXZP*OiyX_=>yT5GcUAqi~Hhyup;lDk5{GjuA88!q9f(;o$WZ-T)CoX zW>wNjr(GejbMVN7Jn(usyu}n_?mFuuLpR1pGV&q&F-emIg&C*5#j*LN>!ndpmA;|y zBEHfR?__@kPwXSpO>KsbBU1RmD4L$d`+Z7UJUujuJE^{|S{^^EP#!|d()Dmo=a!%W zyUU8RfUApyuixqUJ^GhCPit!gB`LW*FhWpNXNOMP<@ph_rK^_ru1jCWlO+WjA!vB| zQ>wj}O#O!U6zE8++2uimRPYOjp*sITGrISFmLpXn7Ku@o!V(pQIx?iS347`JGkPY^ zq+qCH;z}-GP0c8Dy*cLv)6-MB$g&nAUX6WGchqI4v+LYIt>deQZhJjj5`I3{X9dHp zN+{;CE-%~qC$7BD-_j~kZP2h_WUI3EUUyJD*`2JbWd^|>gm53B^*JU?>YQ5of{Fw+gn#4eviShW@Tk%GrlVcT@lLOJv2Oh;Q93PKn>&&aJEOv;V zVgd_NWH&=BUso{&ei>u(p=0R2Wf<7Lcl>$c%>Ke-uUcYWM>g*G5k$B=6L3!szt2qs zy-gq0n#oY=4j!CE$Y|{qx9%rIuTnf_6!W&ydD`zspM);ugVM6wX;ZmimZ%Mra{C?h zI}^m{3O3y(#0`!3TIXN(uFx(59fufe}F`^!=A+ zlb6_{j7I8kBq$(1!TogIBYIb1zidoY<@ixmNXBx1FlzmQ7 z28N0dD(zV`rKjXc3_@Ro;oDAae_L7^Z&XDm?H`;zzxTv7wJI%vu+$YY&_aS3GV~H` z94NM4oUziGJN{k##;SwkQq}rIQrpc-^tH9gwy|8m^e3@j6cO7ar&~O} zR#&0F#!lplHDtW<$Jz1axSu;wYEf!zy>Guq>ZrHr<77>3v_7-*U5CS>DojhkF6C(p z38P|8&gqm{HFUO^O*c)4({i zuB5^D>o0q!rt5oueaP(pmC^ly^Z6x7Zf#}oJCk+)pxK8;ZdaeUq%t&{0wlN#bH-SW z#B(_f)rGQeOEgPVn+6;QF8NUFFj{Tr6o?FP+Y|~f&YBDr*K#K%p0y=gaz>j<>Tutk zpfJANr4WjSZo0rRX;+-$#f^5mIrRq&flsT(%MEMwoM9@avY^rxGPv27;bOUk;1>gD z6kc5KF+p3xam{=~3&@9ti^%X3EX4n?HmvpVA~hE^_=`eLVot9w?opt3TX0{G z>lP`038VG?!;syQXNS~rjYnMe7C8cD{A-&TTdoP!kQyc?P5&QQi<~3FFO$AIZf|+E zpZJk#%NG6^N#}RP$QCj@w|p<~aFK=)vz><@Ny9@m9qbmRYe^V$ers~abS+iubiu+J zRgpCn^<)kfaUn+t!7zcqTsv34rS4l-_?^qm4^=D&(@$Pry*J@&f4LL#dHMR|(1*#R zsLy|ZQlmRDveiFipm(=eHm;mwR}4Jm>R*Pw?Dn`%%o|wPQLv8gmZsj5yK%y{dc8bc zQ1qIC_US70K8qO2+yIY?-8sBFSF?*((nh0ZKA{*Aeejaxv zW-@u2$)tl7zRS`aSM|c{?avRZ*Kfb?9c^+q-TwaMhvHV4yWH3bT?^viHfX=AgY8 zwcA^*?n|VmbMW-4^3(0*WEX-rZU*RZEw!Oim)mZ2ZHw8WgOLpx(1=UpmDTlIP@4XI z%g!%v0z<|5J@HG!C#p^u!KG;u@bGX&$p_Zx-(DvlA583TS$=%Q?Z@H8t;4XM<5wa6o{Q`g6)tCte0X=o>VwEx-!|P}KgByq-D;Bm@%#Ja%c5Ud zZeQ@4f#ll)5kopQzh@6a>OE<(uH{18Fb&!5{lp{dmlI!lPd8o&e+fN%Jo&zR|44Ak zLu8B5JHUrxN(aNGE!tZaK)JaTbJwLxfBntYlFc{Q=w3|9@nc(-F8>^hzy*uZ*+fyk zJFQnlJm`EIOB9i!_dPm1NvFlFmzgKv-l-0+jh`yg55B#*vL3~zzQ1tQ(VXJc!<)za zHu)ABfAj~i(7+;`cKxaYQ5D657W^`83{g@$NyiVQPh^>EWQTsN^XsjI$&ZHJx+f@*F2UFi4KKvTb+FjeWb<@#SmEw-GhpGW2F+sA{aIMkI0nXaOOEs z5Gi6@5pe~6GwWqj2E%>H_g|J`S9e2CXLmzClD6CegGL`b49l=&Ix*P(1L*LMoYw8E z$ha7v9`oP4=Zn2B{TaLUt~iLKyu{-oJAMB;>%F9XO+&za`yZcP5@XGJPj_`%FJD%C zlE0iuBfXQ>T&u9`&%;(Rwf$A(E8ppMqe!!I1;2XTX)S>-=n)0`t>%*YDMlY)yL?Li zq}tPKyP9C0!t?=>F7V#1rA*zbvLqnH=KS9;|o zUr)>>r0Fb%H`aw`vnvjb!ZZ%W-tg7zyE|o7-`iv%{p(GPem~XWk!pKfx|7E1wD)sX zG6?%>Wq&`+*?9Z*!P6_rv#nE3X6B!t?p%CwT$MAssC@SAny-^ztit7G`c}!$!mDgORo!&uZQ6IJXX`E= zrDO{fd?>h}^*>O?C~PEsJ-~7v>*flp#B{J}#xEm|YNeqa=@~lcUlKr<4H>GSn|*-E=U!z)zmitjkZ-cZNT-)k@$QK#Zxec2cIDQ8 z#{^%?eJw8i9dmtwvHPrS5W1n4c@(uJr@j3)<ky`6a{u|d?rlnc7@Nb(6%WRMF=Y}y@sxf*tB`7e1)oxOd2)pW?A1jAnI3B za8afsQu9vG8t3?7?e+L`i3*CQ<^30mp~@U-Y}vu}CxO2BBn5TXY13KFlis!uokw54 ze`79#O)kw)%^$xl)_wm{E_ABqhvLk|UYK0f7f&xU&zj%O(qYv%h`c-Wcbz>)T6#D4 z*S|G%_S!3`r#ja;8IjSfn*>mDyw=k_mF=Ez8|0%ILWCeIY;48|?#+^JdOH(mauTb| zX%NmWa&#d57RRe@>@tJV@hbV&hAMj^pn=yRM+4GQQm&qL3p@=H3C97|DUWRrE-aQK zgv`|;MhaCa-sgc#A^uMSPmN`xhXmr9T(~r=p7;43b-Ind2=$MSlJ>*yF%^|AP72RaLuG>y5raxA_4==(DnV#i<*U8`c9SVlS}lO)fK<2 zd30tbQLcO%+V$TX6Y5F)O$9NS&bzhLfn`KbyW zI4I{s{&s_Q_3q?*m(w4G`2`Rl+mH6sK+a zJ*4n0yN)$YGZ;aJACtTCp*p!As&2pR%KS1kC;M_I8MCyBAK|RaBVM{n1II{3(ABw0 zQCFlE6x0?{1}D@e*jL|K@1=IX{Lq{!k<;iRX6sm8(fcr_J6Frm?QL<2VS%kNT}S9s zp%Z^DViR@c^bT@mN-f7OQic9B=a`653m>bVUE_qL> z3Q?5(h6#&zK*1(Oha&hw5sgiwSt|ck2X{p^P zF+A@1_(aKf=wITK1bDdZABH-MfoZ0o_jm`F0r&d~78hg34lY;YYAO>8qwkhQI!~pu zX&qGoZ$ROy(s6tzKDwN}0adKfd#=HPoo&lU+q>6SU&T&#`?wTN4z;gHl!HSW;HC;k zFY8lFI!65%DJ~15?tP4k_I&+r`VP1>uiDQlas8#8<1?7Y)Q-UQbNGgl)YCO3oOb z(9!*^dLD+zr=4D#?jMzY(AdR~@(9MJWs!%6ro>Ju42)lG%u$h~UCK@GFqgh!K!=MV zChvG#x|MV2-#mpE=e$a+39Rra$4K3bos1%Q{qdtYZWQ8g@l#4Bsvs9&Mgsy)Taxxa-|D`Tp zbS_4G&|!3~Y;!@~D6fvh&3TTcZpk40DIL9!b$4Um!%OB0n;u?!%k;04Qz|O161K*& zFhvKxH)VQlZhE`;Noz}_uqdF#hK&4P2ifNfF{-@=x%4a8`Ux|zfFP$5C5%eL=9f)W z7HV~U_H;k&&O_oaNwYhk7G1@qjn?THY6^>UJn+ z>;JBBi!bfm*+1%(mZl#VDt+)>I%oHTXT$gkgLA($NrVtO_R%yoe4vJ%KFZrvj4C2+ zj?AycMu>P;jm!<5=OK7P^m-Rgls8I)^vP8mn7a3*Hr`oCot$F0|AE9hy{j|_upAOq zHk#=G4ZqJr7tR?;0Bp5L#Lx`)o{spf_~~IM1i&lmPh+p{&E-Q~Uge!n=X=ayFAZLJ zM;)xVk!h$zfzswANFu!5>GAsWB&Z;^n-ZkMS%gSi9vKKri#Sn)|B|S(Nl)+HF93@G zo)I}dnIEMZOCb|0#g?w91SAE&MjDdvl5UNUF*-(4Ow*ZA-vr?26vHD01;<)B`o{;u{yDu-Gn6d=T{4)W-Lf5NM}a)>QJ9PgQ&=gkC5EKe@D` z!JDi$B)N+eeB&A)((jMrtamLqdQ#^A=*ubzFlSy~^=4d$+4gzIgxtQK{M0IQoZ*rW zMMochT`S=|;WEYMes8}xEo?Bs5}xGF6~jRoZ)W&z_M|_d^P!J~(77-?QuIa@zw$|;O{@4~YEgY~6D@~Pqm&1c53a_)LYjkxu){dy4V;R*jKue&*U5O(3 zW==Nu2KH^V?J4rwl?V|_6~MZ%)Jyj2xvHa_w8ruEL8T!c0|J4Dy-%F zPF$?z4z`1@tV*!VIa9k&ALrF6Uku@>4MWu) z*IV6xJP39t9>6K6{v@`I?rG@?OI~sImCo@4jAl01-8t2~06hxarKa>MqnnCGl&2bN zdZNJL3Tt0&ldJtnJm)k-1fiB@b_?vLnFa}BY6Kf7vgDV zT16JKD%Fo)GE<*_KNdRs12CQo%1LBObCpkmMfEBpUGoi9mRq;OMLBA+HMOQD;Sie^ z5?9^Ss41fET_PWfcY}i-biM>cb?QPHI8bP_BB$2pRd=ICi)-wF3(~JKtA{T{s$t+x z0Jh~YL``}bKx@%LtPG>b99zMHq?ls~Vrm|a9Vfh1joYcycE59nu0GFRK84)hmQ9M$ zTb_OLUWUW>MX{^jgCNz=#jlnVrzPP(qoy{^s7~8lcP*5Z?Ro6DLzFNaYAwyK1W_!~ zL`%vf5mYH$gteQK!keq!o(p5oTn<_3N%VxkK>R6edd}*XH#P-qD>_h}a6l$1WSd2R z2T?)*E!)3*b9myrMRaY6T$xw~N-bK;G5vUz6RbytW$*h)_DW17>KWyVlJ1*4HlHYd zoFM%QVd?)uCxKCN?6%jed$YuW^#h4DtF6nQ(=QBe2dc*a1#G8m%Lr~QbpQ)6X@7TiQwBY|@2hje@gPxDx9zI)|f)Rj;^@9~eS+olxPx+<-oYTd%4i zp)}cqqMklh6CJ_#C{bi4TR-2k-+;b!Bc%FO5W~%(vmla)tGhB^uDP&hzk}v!9I5uF zmG|bz>%gIeu!#;Pe~;dz&9KmI>+dDcEMwU!ucrXJf$~RR=N53XjmSM!7VJI$r9{qzWB}oU6Y1{ffC_u;alWVEBQ< z=S~aRkmY8Mz>Fsfx3>(@DIV`a*JtY}9|rY3bW)WF)M~JVKS8QVc_W?*SIf6NCXy$^ z16GKu4p_5AJ5*V}M4OkjGXOts(d)89=mH5NFc=1S_^I%uKyD>6G*h_rIiQ z%}OgAIq#^*D7b6V#(woApWH$a=V{%T>3PGZZa1=CTDe~-Pva~ZD3i6xY^<-vonQtGWe(i%A{5d zBnNrWYuZ~xk+MPtrf=f)ugKc%s+Uxza?NXc4YJOg`I)Y0RMmZm4VS;AFEC(aY^bka#-ik$b-Ph5;Egkt?ZbD!UN!Uuk4FT!# zi017Y8}>^|0yTuhdCcpMN%tsrk%rO0E;3q*%)efw5{!&p2!-q((%W z`e|nSp%`0}H3T)nOxO8+zB8QJp>h%upz4{fnE*mdT~E()a=)^{8^yv*b1xYL9S{@H zx`K)_Hqw>5N|9UIJtKzP6UbDd(4s01_hzS|eWgAdNXjE0(}M?@_T&s#lF3~=v4Sc; zA?-4|>1g0Q16>4ZY2BM9&54C$mhH`I0IK-7#PcMc!mJV201EZz-;FkNRk^~PdJd=A zxtUgr;>e~|44s;x;;r^r*2=mN-Vu9jZsk;#*oc$ zTqU2!Sfv&G2dI+yK{rXs3LPj7B?%{2$&8Wm2h)kmI`m%Vx{IMyLR0hV=?E}2=*HlB z0l`+^Wz?P0wizMu64DdDA5>i~YWE3zLw#BWm~r=T5FjuBf&t^>Q_Z}*-9Z9dD{bw2 z-2B(-^_f;D3+f1>G-k?I8OA&tZ2Y+zZ|gB7o*19#QpMS5)CqCk3HkMlxAIe_95xM<%RSU~2fkP1sOCoTR_=KajT$Rhw~j!pAjX^Y z9<{45xbF#X78(Q>Y@~@$p~~WI;cRW(#b|q)eC~Kah)@BeD@b`XHglBddW=zC?FEk) z5kL7(x%mQk8HHNf=dOP24h{}d7RA`Sq+dN91#^+|X26UtF8J?(;wevKmZ+WYMg&Ix zIQVqLSOc`6l4*R+ho8;F#H4heFsm4oB3LQn5Lu+ErMSkzPbgEKT(z{c?hQhksH7=> z-`NfGOLZ1W>pL0C+q43U*y2Iv9+l6pfG(AvpbsOy6ql`?@bbzQv3e(X%h#`iR{B8b zYD!)W!tr6;DaKF@@9$qq71s`YXzB1CW1$xd(iuGp!cS`}2HoAU{_LDGlPH-N>VtkO zJ$K@RG`S)n%qur%84)l^DSQ!ZF3{FuOaQ=EKIV;usA+}FK3?g;5Hn76*h;R4rY|B$ z%>Dr3cs1RUWb|p$l7x4b5i%13u0dT6#RopVAO`5U1h}7@jNE~E@BKG#lKTkM%qubc zSO-4_8mm`aFx&4ct;nw#q9bu}`QY?R<_*oeTVxT4pAEKTtR!E<#O?a zrBqZ@GJJ2TWT5M6>eiSW^Okd?M}4t;D!MeghYUR`z=>16IsM$vY79Y!!ra?EAWaOv zz~sL7mF3)s)Dy?OMk1vwnX8P}>7QIuWN{d|R3su*4T)rag^=-WpDXT$*#?HID|KD9 z;s1t^YxwhXD^0hc_IK<{$CScb3{psG6+cx(rjMfIj@JWAY^M{mxqW`46b82EZyPLFTfffxjqzLT z+Hzp~eP=BQojMk%ORFtu4H_HzBtw6lXZi<-S!U>2nd87;x-tC|vGQspO(`M>9Cz*a zEhdU&i5t!!fi0C_G4ze^PePmTQ_Y(yc9Y-ZkrY!#e zEZjv6S9J4PJ5FWXT~JFMeT;Un4DMqFyn0=nckVsitY!O2MG!DNI4#e7NMkUDuw9Fs zUm>`-yQEsvZ+3P*RV_DY3I2xYqFjm7j20@|)EL!H528$oUZ=jovn)07g^3ZzaRc*N z{RCOSrNzfd$~ZN-HA!^QJJLS@8YM&b-AY%sx1r(0uO(sXFv!-C+G*OVJv+NZ8@ol~ z&vYwduf((D+WdP!%j0*_k4s+rQ?WgM;d3put8rgT3Q4nTk!7yH45UR&H8AC$=Gu~% ztP7k-t+8%k$@j;nEU0ap1l%3+pFflC{al6?IN*#DZaEj${yloMgQj0K?W3Mw*?JRV zB@?`>A#iuJ`__8gr?NBoRZEeU0yWIe97%d1(3x1LDvy^N@I?#-%hW`{)wtg7Y-7otaQAnWdQmL*t#t12u}ou1zPQ^r94<2SHL z?P2o`(%g@0dhe z(__dI%*>Fo8ShZey!+hXmNsK-aT&AYhnO>4yvR7srmdnwut$UXn_yh$65V^u5(D_Qf@=7>n4y(>) z?~&W*ge205`s!S@#t6c1{3@5S@sja2ynKE)I`&5 zMAy7!4^q;^SGI9uku4?J6s9;=)U9`9Tz~Mzy=5;tByHu&?LBD}d}C zrDi2KM@VL8v_~>TAacqNF%#*Jszx63jj$Nj@ukBmu~8cqhM4uL+Di_SMlho~)6 z>#zeWXNNk{GWM3`l>G{MPof8v)We&meQn4JVsb z#~a^}3cCfB8B)b2DqTDFQUang5Gj=ca+M0)LolqHEEZlmjq+AH{YRfvGD^+asq3H+ zSQe=gA39adR)lnVTE!qm?mJv|VS7x8n(02) z$df$tMdr#Ddo`ikrr4Kwi&;i|%_+A(z@^#-q^+o>k4n$Px$VPdq(rQnoA9iHRX(kJ zZQ~fxSEY;ugg+PlTcrj;FBMWxT~BE;u;7VPl{A@Las@AU$>$UyR6O*P5ALknH~Ru5 zG`?HmZc|h?S7LiO!v=|^BJde!foDX!OoAvzk2a|c-37oxQ5fagH!=igN+;t}rG%v` ze5@GlOxdVe1S{6oY4)g3+SU=kJ4|VP#!gu3T{La%%@K&tvHg@;_e+*Wj@9(uiY~Nt znu@%FSb-FUKeHt*f}+*LW9Mvrt!j-R#9FO1hp9+|vX^z8F}7r25oT>;X|g`uy_n)I zYl0Be;HR&gPhH;SaD~zA(rDOX8dx_q(z1=2h8xPg+Y<1P;nlret?{tz4~rdC6-;{3 zEHu^_ZZTUD!{ig2EV=@rmZW|ag$Jg)8keS~dx!0_$R%DA+Xgw2)z`#1==DbdgCh-S z5ephu?hv%zeV|*N+qLc>!@E68gF_kv&7}5sMlc9w&CDYBaKt(Xm!UN~k#z7U8pk<} zyjZ6m!P;kx<9+e6Cvvb3TyCt51Z#{~@`WMJH5p$h__ZWuZVoyN1}&Lyk26hsC(Uks zB@Xr(ypdii?KGQRB9H7r_OhYzt7UU>6SXBNTtxx9(?n{uD*WX|drED}z0nVp2XC*I zFL?P*rZllS^;_^*P*G&U-O*|(HH|;GuQ$gECR_=gF|s*i+m}MCROoj{exzrek@iuj zzI({9hDysm-W$=pI$q>;Ys_&8xHqwG%DYZJ%k-$>D$=X%tu9-&kC}Fm8hthkhiNNg zAntsRaxGe=pSoK!K5GGfI)V#`sBoTx2|vN=SmLsLSieQ?n3O!OnN$_k!<0tuw6=sj zG>Kk1y~ARz`TObEUmg#H^{JlSXoZ4Du7!6;EKdeUG&5S_PaMf-C2^C|G5hF6x{UBH z2l=Ap2~&x^{9bl;ai0EdAz+fZWIN{=DY6$R)5Ed1>b?}{O)F0BYN%b@iX%2sG{K|ac83HP|16pLn zHGV>*>7lreEm&BzWfFzdDL0HxJ)Ex0Nc5RiUAqqbr!hyVeXt zneF|U<&|v^bkM1mja1)V*rG-oE?+|&L!Pw<^|QZG z28916#F-lhG-0T&F*jaM3^t<8ypJ+RTEMZKL*vMZ3)1CT;T3lnNC29x|RA6YeEN$ z-3167*LIp??9)y;1AhUbXNi1g=0DH%7Od=K^5ms!xmFKwES zrjPlMMQ~v)BTGG{X&XX$n1B6yfEtTnfj*EATL6?DDPv;N5|l@#7xJka z_9_L1CD^%`y7iuQ{e-oq&FB8O^Vm*%VR#M>oLM6rnxC+|J&eOT|~un)>25$gxkg2M-z7UpQg2`Z+~Oy zM%#q?k58$s&^g9rirjabD>1n{Jz%@~-Cj>>7fuRo;Ip-#DQb>+)NnG41$um=beVAN z4UQbz*C0+Iyd8n5>Vq6)t=W(GPA(NWL~iq*!;IsLhAPSz+k#2)8wZ`08m}6(#&*l z*jSgw>UAiZN_YGcL$OdQWAz6ZO3C|@T^s|?h{Bv~635t-3$?Yi&y`Cn9h8^PE(J5T zihcWrc7)2LpPP>8I3CX;q7|IS?Y&$2u(?o%Sd;Pp0Ukl&zW84&D+PNmaK2CptONOQ zkMVY)f!7PzF62&n09F7+2LOr)WoHW>fN)zUcq&;tju1@=#bJ9aEMu-wE42WJw@;Pu zuu#G|9dXm$dli%uLIVpPoOREuKfoA+Ru&g%UBP4`QTJF2BONh>8cM?WUn?bh5NZ%Ouc4?y)%7$W(1R12 zfN@43yBNNpQ(*`egnLRIg&5jbYY~JePZL}_FdV{wV*1)wU}_KZuo{hB))t8t!Oa&0XPri|q^U3+-q>a7JQ`#X9h6 z7s*Yu91XUFZ*8*V7SC_IGO+|*}A*iN)cFJ0vcTmYTSPPrqKq;r;VgNkGQ{{SuM zS&)+}iuO&J%~4wbOF4SV&JcII9#aooq3*HhJqh(?W6(VW`f`csl#@>7IK_Z2f03j>^&f$Ka)KP>PqfeM+-ebUB?ZT%~ht# ze9}gnU^z(>9&AMZt!Hv%O-1c!b2;?RZ}0XS782l=$N+Hg=qnSm4p#yRe!vv4C^eD7)6t{{R5`aD#G~;L`F5=)!Xc zc?G?wHLpwM!YjAB6Map#6(f{6W#>kCYHA+w*Y%AT$KR83ArALq*MME?LYXJmo&BY2XWj8189ue^W;P;XQ3*9!=o{{S#dIOy?! zebG2TF6;n_1$?Hcy_$W|N70Y@Z;i}Nb`%yI)L12JsYnyp<{qO9v>)Kl@?eg=gBe5; z1{%IkYA9s};S+?xmGW9sJ~|(d`Q6T9>}!#Q!8f=jSod_TkV_LtbSEEK2ef*K$NUxm z6QA6E6Iv6Y_I3i!Q(MsGV=MlX21`Z;eYz2kAg`BKm0>VDBq^u%`sHTJl7CK=B=P#7j zYtBG;Pzqde$^^xcatu94{HMm`+5ru`?QOHehPz$uCz)B2gBQ!o%?SS>w5`6TqoMmCgLg@uGipf^9j(UKwy zI9N?-DY1djH?BQ!!ug%A;|(s>=~)Dk!0cF}_)S=U$`CVPOIFKgJ<(TgHnk2ulB&Y@$_M@Zof9icgm za&>T=!quFjgFy&%2%I1mNlpI%6(fs)ZdN*yPooGzQ$PzDKxH;1>=qC5X?2F|)aHhx zC_1jmj;sra%O;tzJCXCZRF`SIx3VAr7Z%gm*xlA$o=XpNBoV;IlE#MG){Ab61^^lg zF@T6tw2=NyPQBP11Ee4#-r;AoE0Hqb+3Dq^K=l&7QzptXfP~E`JQPD*oe^ptfYRhv zGO>g{FtC94A+jgJ=6V3i5#!JgN(PmzbiydCAe!a!hq7rzrpgg(UY!X=rKl#HFKH2O z7BYuitdv|r5s4Gwb5mKAKg0wAY(%EC1)L&!;bZt|R{V*bJ-uukS>o*USRCI;C1+!)Ky~d1WjG+^lpT~GgZ3dQSdGZW)%7Q3A8xK4 z0Ua6_c?h_bgxJYVU<)ffaK1WY_+gwx(;<7}kjDC)t{Y2{ayd5d^v`3xaqa2Vn)@2t zm~@+0U4~g)(;dcxCdHvgWIaS!Lth&ekjoKq_yuieIGjtiD+n=Ee34AbEtxwI2R?A# zYhmACp!6z8OHe2fQ<;PgSHi$6-=O+8eXK zTTf2R@>-RwU8}Kntq62fi^L`>^4nbTtt~BGsDynDa0rID_AwC9nm|Vd7PKM)10b-c z1kmIdK{#srJ((^Oi(HRrB;{c?GE-OrB@^ladn~Mf4pvl6V~QmXv(DIBWRb!tOA%=f zYtC94h5{Q&;X?G1px{81wc72pv}V%n;=2TPyW7q;?!REM2B5|DtO96G(N(tU7k62Z za%(cpY{syigi$D`Jq3^xpOWHA87MT8K?tDogV7`pu$1=}g7Q#dD*zx?6JsSdFcCOJ z=hPa#f+s5rKC|qyRyu;S?pA%(t1W@84s)}F#^5u!mbcxY1#ZJgCC*uMQ)Vp!VhbIX z`0CvM0GVP}M_OmPc^eY?!&kXP0HBG}%L#%+$)6a#$b~4j(?w>%PbtL|Tmmj7VRxcX zVIi!_#sMDPtFSKIpuiCsKmdz!13)LESW0YQETVejr^>?kMD_Re6NTl6nS`n!pxTR(&9PaI%L?bS_@y z0gp*ISx2B9E*|vM&>W*{RB-^Lk&z2l-D%(=iNQ>7yuQz1{{R}12f8u}VF}WZpD8Fb zy?tOUM*3}4I@?QiUq3C|&mN~@$Q@$bMLtKpIDm_ZKn0G40hHDtI^(G*zX{ID$^euj z{s0R0^kbmP_E=vD`C-8*06j%#K8a=}Hb*!gW&Z$ix7s!WrIbY3p6OiH_M_FU$u9o@ zC%QMenR1DRFt4-(;P)oRN-qr=R&3$|io$G-jY(*^Izmu+LF1-T$^d!*>RgL~MaTl= z*nstCrWdeTSoM39FuSs`l=&SY{yCq4oFWrmLO3QCEE2Vvn|mn-2-j&F$hjpe(0>u=8l;_}Nt8k*2A~u`D^mT3^ zIly!U2?B3wY>fa)7kEa%3DSi$`A(R%7cX+VeNj88UcnhMT&<) zMpwC7PC2mLyz$KkA6q{pUY0TmaqE?zSw+F3OAe4QCmf;|XS-UXjJaEnv^BlRO_0o?Q5rph+A3o9K7S?T`(ev*r@rFYo7KtU7&!j3GghJzS$T^plw zk8li8!d_VzU?l}4!FM6hI|IC~<=vIsi`G_AC>7b17*LFq=HX>!6P}EJaxO%sw7E7Q zJy}GrewjgIpzFoBMXmd8Qj(JAroT=dGy&!MiuY=HEbBj^P+g~_o2>d!(w80Z4W zPnCthxs5GtUTV!OH^5m72nCc+qX-X4I9X2x!vH5|raCp4SyDSGg8>xhWn~X!`Pu`X zUDrRuo`kHdtftCBk^SD0=_d<5jP)M=oFL-8*TTph09i!(FjhS|=t?8mVK^Wb5N|*- zgg_$9lB9RBaL3wHoJsCkK%Y*10HS(#Bk$-dpWeHlSzXP`X^Sy}bxt~zI_ zE8O+&S@it$$3j*zfWpW}C1HC6PhWL~j)OjedLM3pWVsROE?vZ|rZ*v}(lv-YxV^)n z{w(2V_;Rv(6Vv5od@P{85k99* zz4`^7g%=`%B{8I+bI|)I6iRcED=HZK%yT{|E?j-NY)O>Ri;+L@{uWkO$4sw|nO_}n zv*-h$9YQCd9-JZ589)Ki&cf|PB0yco(Ubyf$pHI(ff7k42)P$$qd_E&!4|e{mYzq3 z0h7@G0Kh#vx?}jl`RR_BSm~aF+on1mm_ZL@PzZF-QbH~(9Wm4eXIAK`jD;kLq`04C z=XxS%V2@E(T@&Xu8DdWN4ut;z0BI}gUrUjQh1gLT>Q;K=_`SmRS<1**%EBYB!p2A# z^kHFqBa}UpoEjMJV~V4feOvu?u~PD{L( zWM-YAVPgn{LI|*hgc?c_74+dTxIiz3?3_VGqXr~nMYu$CAHX_$qJ|f_Kq62%=uQ{D zKTCW_GCuSf0QF=K%f=_dIutKvI_19xP^?Oi&KI>$~u4ACkq)s0ncC6)RCx>A$+dji6MNils%Wq%J^Qzdw`trg6#hQz|WunJq;xE$}dFc zraEV*YQYOAAP;{6Ib0Nm%y-p&%mSv(qap-C&?H zy}Em#0wXI6-=p1?sD_NTbUa^Q#_eqPP;psY=gjaH7j^>&T%wA`Q;0#xgguaU33pGG z@UXL$oFEY>doPq+fJYq(3C~5@{$hvl1Y80no}`8DyGjEHBH)2oLA^4vva`{{-{9Zp zI>?zc(%FzV0J&fz?mz${z0o*XS<22<76VhAluG#NoS@Q+5yJRiJutEty1*!$BIM_i zv;P1eD3W?%WqXy{fX6~`vPvGvw3I!OI9|&H^eZblMMyB35W_(CU7#l%CJc4T?$1)( ztRnm(N*?__I%EWLhq}tbB>=sO_ZO7rgEI% z5l1C_EC9W*vW8FqAiwN1AQRn$z+6ridJw)*>F|rP6TOh>f)~p8SXo~SAoTCbEp1D2p2d7Go}~mVSe<(HiR5InG*YhV->Ha1sZtTd9M~Ha%`B-j zW;ovFPGgPmvn7_!Ca)jd=Cy&ZylT2FlcZ&Q(-9E(Jl6x}4cAMD`EwM!DyopvSdyZXeYWQ{y?taOziu*42 zRN1lY?-JM8MI z(S^FZ4gUb!G#s;M1PfsP=cG zRe3y(YdMXI)vs?h`zD4oCIOK>oPEwI)67VC>}Fh__8|Z$v)Qr8nHen*y=2BFwe}|D zw6b`VcVlv!YS>iw+23B%+U_jFa5gBRi+vB%Vjq{CKRK8}hW95_h`InLF&x z;x<;}WFU!O14r8o@|85?wdKL=j%k*%jKWx`#6&ej42}~bigrQ`_K4ZKX>40~Wp2lH z9Ad4uNT^#6t!~G0eWyl0G8TC)uA@6J&j>5mTNgQ-ZB#aZZ1%v3qOD>#}LDn^Rkpx?Lqmq}c6dti`pk z=RQWyD1BBrwwTD-v9JSdM&}sg?=VE>HWvQ?^~mt%ip-gs`k{(8h#cpD*c%j$o&gB_ z$0*+E%#|c)YY%y@%A{K@nw`@dMWFd^+h^B4+(vKj9@p636CC@a+p*q9AU5OfmeZaK zy@Y`^9Zepu0Mr8&%xv4*KX)zq6Xh1KB|b5u?mF{oB*=E=b#aS8YNkYY!zAK- zBbF`Jt7V|MrLDuP!=crUefP6_1%6EaGe%wCB-HV?a;`&u%{sh{vR9pk%Ee3YwuLv@ zGE2R5ZPC8OjpJHhu8!)-jh}m>4W2c(-9=nmU_;&w`1(F z8;b=l)t=(Ft*uQbA**gmS_wHfm^HgAlX7d@sdl@EzVur=yLsAsMEZM|_44lZRQ3AKL1f9p zHFbA4IL?dl=c}t`w@=F0=%kX^GVHcdwVU0;Uo8q#T~k$#Hr)=4&O}Xp=@j<+;;2ln zjjb()Q5#)wwSQpa9XsD!wRT<|J>wd;umKCP6MpGyA83f|U(0T8iwv8$xY@rWL#;^I z<+=1o+i#vJ86S128}!O$bF4DvzHu#=7!8=*_}U0-n5MU7=r`In_P9w9S!>hlTCC{g znWy`$?V5tC8Yti4@x?yUJ95{y>7;$OPOIITXrYo$#t!-;pC5B%Sf;c9PSdobx?Cua0P8y>6Dd zt*=l|YT2kYPuOUyYwcFt4V{`>9Zl-CbQ-$$cRXIkwkUW99tFF(!sKu<(O$rI?`rm{ zQ2mdh@Y?W1Ev=MH4%k?TIf3&XonulRM3A|K?PH~z>mQz77`j;{Yix7j+|NVYM?XGV}r|HnILoVEdw$uh{M* z<^2aLqd$sxp7&X}@t-Kw$zxe+grAEe%jmc#Rmo*QSL638)!fOYyLL9r+ErP1ki^DW zwKcf|ocB5-UV4pamPlULYri4`W_jK$ZT52stj#MVvjgCc%qgxC86LnLEKX^$^t)Um z``*TO!z0TbkqdI64zjivW!1^W`32e*`K3vB+bx!g9R{~;zjXTuV}nv^3iRiPWkxC! zTs0)6dJW8_wr^76_N1u~j@u%`c9%sQYD}X3NOyfAmgvEuCR6;(p0+oFP5&mV?Mmy zp0?_w*4bJHt2P;0tu9q5Gg7?iby~fps7}hg&6fwa4S6&h4(>hlJMp&!wq5W)eBQ@v zD}JpcjC(F#g1t@c(=*|dGQl8l>;+iJbd!A~OPH+8N_?j-wBYA#UlfAy0>0gmzx!qh zCv|DrB?r!K>fnw@7!{UA#E< z+4QLzNJ&lq_gk%JX2~3z`M}L`l#4eSNf6P&RgjS~Jx0_d|Hv7s> z*_b(`lhV`2SCVWwZ;dPJH9PKKr`^9-r)+Bc_2Rp%uSy0_rJc5=>|`4rX=>F-b#hx= zL8oDJSxPNdt&_Rbc>!rVhM8ou3s`oAy|pa;65ZIXg{FOwOwl7RSB|uMW_QUm*k0&n zcijHhL^ARMk>#RkN;czRmey1@+{SD6FLd+H*jhtpA}C^)b|sy*Szs3vmqlZ{>%aii zv0BiQ#B&)ZlgM5v=lTlu*!$c%ZZ)&J$u}J9QCba)CAY$Sn{!pL@;8<=Jf~f-wZ?Rk z^B*bQ-tDRKdHcB~ZI2h$)7;Y7Hr0yNBiQm9)ZYF|Wr5pUE}pjHrI+>&;K0=2<`VaJ zJ?9U2EQzPONc){65(E8hn3&3Q7utg+7^3<`DJ5qn-^Z)gYgq}sX57wnmz%5AGhw%e zw)2#3c5Kq>?P{BL-0-tmuAcLCRpql{DkdYo*59vFi11CVoi@LLav>)G@&wZEJK1)t zUg;?B=E>NAU9fwC*!Q{Txq{^GCf9S8pG~^t8(ZEI@Lz#=x9m^t-40L6c=zn5k?3mp z-|Pw6MKef=mKfnXNHa^?r<(=x_aD8){!mS}Xh~xEu+2rcO#4oYzh!snb&J+6Ax=0A ziF;4lrn`u!iDpt-Gsokv7s1aVi^k^fIp(}GNgl650?)duyST;Q4lUR#e zw$eWKpKIc+m0ezsceL1U>~7_E3**1+e3QtO4;kbJz^JFP<-hRLjBtV~Ik2NNwxr+D+lFCFvWD0xGg`8#*Fk7C;tt@o}2 za>YB}`xckSJX4SU$awFP?Bm!u?3TxPe60#up-ylvFiD7{F*wYR|A;}<=Y#iBM z($OKhBXzFHr0ipmiZ-DerE{zXNu#%Vt28{L`(2jzjrkA7SGf-7wnj5beZ|CvrwNq1k%EVRUgY52PGM?h|i1H8) z0+stTO)Z^U!}1_=`v4KNg50#k0SzSwH3u{$F>fCEb%sJ&QL8ao_-aSs6WVg27Yc&(`z5&lXu-*mW zz8l2Wqr4sTuKG4{Kfh}y)@LpHw=qgfD#~9qNTX*t*nh5Y&Qo^3=T8xp^0Efj)lr%D zI99ciyJf>^^IFnQ@rdMWSv>JO%A8+aw>~T5Tnn3Qc6*N~{=e=j>O4o~nfH8a zlX&-U4(`6wTeH2mg2mtom91f`Zd!BmKO$M?VwL)08nf|(r(tO^NLpIPxX1nuYe;+F z-57B#j(A*IZOwH(q|nJ)(=9XDmIj8m4O>1}q0&zmDbY=@FLv}X2I5K#Ta)JHes}=-=k+zdEHBo%_RHHA!&z=wUOS{GAVy(qvhk#CDU1ZxJLVZ#b0%`9dpNC zMA7mpo1IS6!(8{0YN_oR%&ly7w4mghiZA0_;yzQWwL#Ij?C(Xcd23_}NbD8)vc~u} zQTKi{vDPy7n5T09cq8mBS2lL`GKc>Flv3qXu;?96V;z7bIOW{Bj}z8!Hy3w%Ee|E1 zSe*9A=2(yl_wGQiZS2`=_DvOa`&(L#ZnCEp=gV{BzDKp>`mPPbynA19pl;7gOIrrM zHg4^0tZ>iOZTBZ<9OC?2f$AZtYTLD(ZICzes?>DunsaioYP!}rwyVbLI=HD;k7EON zGqa6N^>R&V*GK35ESri`=x3&5(KU+C5Uyu}ycI=yE~fi2ZunmbVF|xmE+mzQH9UjD&$t&{HB!$m*3GS{NCv$3<(bKqw>tvZhs2`O>ir%$n zSH-U|Y4}uoQ{qlr6}x^*;ZyK#Sor(Zo@Zl_aaxw`(X+?-zRyQzbHca>kQLtq`45U} zH5D!Kcy@Z&>li8hlCqYdQor@e`)`6oTHtlpjZ^soNkfC386l$~vHt+_Y(%y&=BV6S zBD4Y7^LiQ@+?$hKDdw#OuPiSxv2o|D#?WE0pWv1}Z)$5t$enV?hQem@X z9MA9};6JV$^T|~9cx2OepSmdiqj%x0p*4`4@`$4;{CuyHVnkT%f4zb~Rb9TKM&kvWB)g zkx8#{5bE9=9cDSYJ|kxR{YQWE)OSoqxtD>zvUmy7%)%_mlj@!0$!o0frO>FcFQH88bICL_$M#kV8 z()Kn#tZ>j0! z;Q9$}>uYasoAYbux23-()6Vn5xzeuoP#r>)D~ z%(xEkoHDg=>XaV$4GzERZn2TJwvri6vyCzG>wI?GZPj>stQKkUs5P)bT3*_;oYL9` z!ti#Z!8^Sfp%%KgnS5721>G`CwnmAg*f+H6?ini9+`vxPbjE9K*xc-A;+|5kwwI6c z3tml|k#UYe$F}m0_qYNd2XXvt7DV9ok`qB;g1nPJ%d>{ryB#RD+{*2M+Vjq2W*p%u zMbbnilO>TdxM+@7>G;1U0#}g>Z z3->@ndesBDr@e|j4-n&;zt5XX}`kXVuSUh05#{8!K(V zBWp{6iblP5xu;=r9ds9N-`G!LsftkdwlKot$X^g^L}`%_{a%}A$u?R~5_s=hV`IO! zTSa2#pH}W43o@n|AYLj(cuo?^;j%B3fF2zwKn0+snsabrVV zRhI^{%>Mwh^7z+d`vvBYBY7*DIy;r@ZS+^P+kHhBe}8HV`tfFj^fsJf?b_7bYsGE1 zDb@aO7~x!|K0ilYxzKL-u9sb))Kt*%k+!+Ze4SRiZ|_Dpj}4z|e%x$y)pbsLW7IOd zqJ!Bl8|FJPzwpiT#<6K{3&3N|npJ*OGWH>I$U6+zLKE90pMde&Kb;}2fca^8(G}|vG5R`Kf;s#Mnao=9n-!iSV=@os;AaaPCc{q6pvl6dc$aJeqp1>(#lmNpgY zv;DR?T?W;U>85qd0=Q~Zu_B?{`67jbU)t~M)`pOq?+Sjf#!+B>s zxx#;1IL3iT^+MX*f4W#;uLx*yLF~kJrkn_ba}$K=3k0qNJRIGYNZrW!F4IG!^B?SI zp7-31lDCjaHESGlDh;7}#;UtDGjfQv`zPr9Q{{cGr^DZ<)cBs?_9~5DE#WR#rJ1|B zH+1Y9jwf}TrM!QYYHe;gmph)1Ao7nn3S8?|h^yIgM0$I5s4TR68nXOAy)Pb2KSp~q|SdmN74 zyFZNkE_AZEVC}hIAl*h>`IUHEEQTg`*Qsjs+Mft*=p6;_A*`Wr=pkAy9`}?@!GBuo zR8^qYX<=@<#i^on5SKgIvv(@hpD=)9%ZE5 zYxf$CVwtXH&tu8pd1o7;1iX94ej>HW__v6BU&H)9?%{WT31qGE-!$T!GlK7YtF_m1 zO*~r8PfKmYHQO6UhH5^Y{{W9PB1pJ4je_O+6^uKrR1Tkcu93AhvF<0o;EyCXiNUL% zNmlKD!gkU#dAxsTTUm3!+k2I~qvF1O50v0S1w_p1ZQEh730}* zh#elQVXWjfe0S!p#>-8*^G2UVE|c~X##`#zk0EgWOJ9A){B7h~zHj|U@+OwgCAYDx z&5165)3u?fuP|gg4-WDVI@hYp)C0Lr&LMVK_L~kt`4V!iA1*PCewJDF-YMMJv&=W# zcf_85ujH@SPbT=~&J0Ji1BFhF`^Sy=isgsNBzlWixAfr}xi(ye?*{#6wRq^bzK@F0 zmc!&p^!;*Oq z#e9mZIL9r$;{Eo=%lcun)pGr8^XxBIxg8BX zJ~OKGFYC1~MEjh2)j76XD77_Vs5QDC0%7CZ9v8mlbgX#8klN=wKTidyTMer20#*4TczS#9aVZY<*_f4bi5yw>jvkJayjGC^6oxomX{~jay~H*rrRT$tJ!|- zD4~w6xgxDbSj{laZ;bSya}U=2Alh;ZyFn}EDX+o&Q^j~aNw3tZHawtr*u7@+df&I z83AdqWT~fgtOBJ_ZMsJQ;)C*?j5*3j6!#W4_uuv>j&Yq2F7h9d%w`pPxoohUX4-N5Z`i=|XYgfktsmFY;Yj3~2 z%WyN2Qq=1g%ZkvW%Qm$4ykC&e<(f|+c#fYRtH-Wt>`!g9w7V+o(Rl+^xzXmP*wmWs6oHOOHt8EL5V`ZX~kyHT}$xA(tQnOM!87Q3o7?>4<*YZ@DKg^Q*jd zV`nvf6UN!c{{UJY%K7(`YwsS(;@iaZ{hU*%XB8BZx9{=?n)oHX*OEMiK;GE0)a9n|iwgTS+X?ar^v#kLx&`T<^;kb-(L;6J39m zY;O&QwYw|yXp*^AzDH7DK6vM2#y8b=HT465aC_Y1-|AM{ulqwS(}Z5+EPRn}zL@u0 z_RlqXW$c=@Lt@>XMLL{s$~-eb&Qq}PmiqR`Vfy>Twf;C|WZD^w2@t+CtK3THmF>h674UOIf`qRldBY203cy9`?Z*NAJ+wyx4 zGHe}f(Z&ST^v?y-Q`ZSB+OoBrUc=>S*HRXC^Uj4Axx!Z0YZ)}6HU_4WNgyKNobU&c zyr<*e6YBQ=0J9!X^ZDjqs~%?1aUUFbQ_P>Ryt8Nj0P~}tN5;QYKUgpLLY-jt%|c@6 z%q9tTTYXOsRCE8Qt-Y5R>)R7g1;$s4ZOW=>D*noO{{U^}ErFN2U%lJGJ^Syc z8z+&WTrPBRV4; zCALP#-@CAp+Q7zA{L2wHNw3!N{#!?ha1BnUZGJd*yrWCQ^}Z0_{{Ug(*y>4j)hSBo zrrPSoZzKNKc+1CEIsWU*eCfO=ifs3~`8ai%bld*`*gqs)R{6g$yEI#xbuajL!BTSJ z{<9X3idNHFX1D!9t(e>5-Xj*waSGP!ac>%Mju6{5h1P2{T0SqXo9$g~IKdHn=WN3C100bt0AwmmKxE)Qa8^miY7NK9iX|-f0#dQd?(?lS+@Py{gECg z{W$QCifqdxo@Ra>Zxapnnl?=8g^;ww9LLtR8zPE1rjfD1`%mXqat*1r3f%5%(c`Vz z2u8+n!6wcUwy{GR>#VY_XvUVr^|av9`Ti+U-o94)DZU zU5v5sEX5=micFJjz1v}An$ zdwWZs4)EMIb{gH?AME0&TGIqziA0LEXrm_~u8t_v@u`HKf*e4qQh;tmh7pMZYie#Vaw{t(vX$#xcI`sJ42WbJchHrnG?MI?`dhw3J?H|rM|(R1EY2G+C<+3w|R zTK**NOJ9a~vyW+=xa1s5gHitgZ@IM}yPIuSj5z+Ad%M%$zvW*e?exAD|b+*5$?z6~yuLCAJdZMCUfx&a%|{q#DDpM#ORu}P*HN#< zIJY_H7dU@|xbBes)iv;1+t`&pY^MmOc-FxcN$*vGli0B-(($dU!%mA+B-@RJ^CRbS zb*O8@3>zC_ygK?RkF_|S&a#`Mj_v6lb-G<{^Yzxm7d4_U!{W59f8SXU8eL6|-R?ids&Q>sD&*F$O=@ZE39JUAU6^x>yj_9oig60OPg`?i466OW=h}1QZ*v}meZ#K?lY>{{R{C+mX|1v^x!(VwX{%TRoM%fME}e-ikP(*X-^=1UkKRu*I^z>l+n%BFBF z*~x`^K-Ih3z*OEu;F_6vZzsFWc~kAhCEep2N$tGtg}vRYFLvIH;rv^U9z8(VmtPFs zf_bMB#^~UZDq7ppx5mB{@(+?O_}|CcFBWjWGycdHJ8!y|V{#o#p;d-U5x(Q~(MIbw zT|`3*V6YmhZmHEA6VF~j)w7Xu&3#>8H1S^sy}E4GYS0pyh;61v1VxC~_hk`OfuPiQw%zUk=$W`sVmc}8B+SY0J+nX{wMaEfod9>TLwj*mh;;zVQ zUcUPJ`V^#rlG!qD^&0dCBjj^)?sMXw2i1ehKeOIxi-CTuc+*L9-#4M<-ik#;t49OT~CL?~?6&Tl%}kcwAeb zF!1^|{F86a{EJsMt9`beqgSbR#@wuT5 z+>^->M_+|_&&Xa=lg9r5uY6m8Ye}z40cv-V8vtOjIG(jS>c-vSyGnZvotn^Dk~npg zG)Dt*IOj*+3uUb*y4PP+TYQJ3kmh;E|095u{y1rH5 zd~1en1Po~{fzmjA>ZR%F&EY>O+43g4k#jxO*tVST(zV6BZRHOuyMlhQ@E#u<9TiwU z$=(@Rtx(4_tg!uaN* zYhz<1Rf8KN?#Es@Y)tB~J*|ImY?6D*@&&oDS!u75OEAe-%05T0#^s-DsoO`&hr4x(*>)76F{znZ~1!nppAw06Ea|jveBiuRY?v zJn@d(o9=hJZh2HgkU>aNY^0^B0|Y-;}So5s%ofcz}eZYlG9@}DVwym*I?z@wGhE;xtmlb~b;g_Q$!W00KQeOKu|OlQa#-ee zyIcn%Hf_gljP8$JV$7pyN~>*bA%bf%+t@$0;EJ7h-G(^pMxoa1?kaU^QZ==c-+VfX zRHC8GcQ>pXo2&B8R<5ni-0{6M(q7o#vr32c&XVhD4VLO_&H80{7c0c(w*JmrJZF;~ zoErB%jDfI3EKKobtj(E2T{XZ3t$+>M?pV|1os_i3zs_6T6x(i3k4Te_>{O*6znr7X4Lj)pgJ6^`=TR?rfV*Ds+Wy zcEfKjw@zS+eZ@NN+snx=TB)SADBQoV(Nd=l_G=Y2kydP$>QZg(o&78m{ll4W2GR&gs#u=U*c4x!oQX-wbQKC#K`4 zakgy+YK0nCZ9bNn&@!~KRAU)5?~1$0jvuXkZ4Iu+hZc5&0}DuziNv@*G6`!7Ll_z! zLnDpvd}K*1t?zSLEKvx{UH<^oWc-@e%c3>obd`hu03KNda|md2rIWYmd{CIAlW$g; zmVKtdu|_9!)M_#tT#9%mebV>7+0(HbktkA<(J60$@XS_&zN{VugSd6h}+@2UOUD4mysso zI-ec!enqwa09o1WD$QCb&8ya14RS;^pBNSUP>MNPW^^b=6PiorY=2wRUEb&Y5w(yP zJ~H>da3YcHV`6R?*EE>f2o8Aqn_M-fX<{s8tFjn`Pm)|lOi;wo*e@9-iv-D5HaU(p z;fCFbDr@R9X}j4=SMR#%-D;d}hR5a4UOj}-Nv^43k^V*LE9e;GQ&VQ-we-*auFa+hj~lI-Z|Y=+Ev-`A2f1p{9KBz zgNW%FSiVT*?GoI+1{{Y4CyfLx2vNI@a z8;6?_R&0*?(}WTk7$tE5tdel|K0eX(eT`rfn4#@WhDOHG9hXY;6C-1zO_C|(+wyZx zi)VT;x3X=Bg|OMLw7Yhl8!9O*+hsi%g6(}{wl1$;wMK2Zt!m7IedgX;db*HHyX7=> zS5NnQn;K0XuUS?5O5k1OCG4786Q&6qtLUYX`yHPR;j%NE@Y|Q&bMY&~7RO-E#rosb zUAp@7+iZvl-mS%_tu3Bhak!4#-BPB-;_l8$YkkS+aNP%&{{Un+{DYNpT~?2Wam^1g z*zGRw?`z?)Ns-z=*$7i?*fL7?J^W*i9z%c2K6={o{{ScQUCrJ_y#09K&DBulRvl?F zKdqJNm%6PM#u*z3d3-2<<`1$#BU=MtZ+k(PwasvnCb91OTOgIK4upLS%w#w3%OWn3 z;=klaUcHGM8G)^q3o<%Sc19_uw91XBoE-UUv7wU}%w%1!g$Nv8(Co8IEv8t$+GX#4 z&9PIdWwmKqy2?7CS=#!|*w0^ARh*|HVeK*e*EX`M^jyIsX7QyTo*w-yGJHd9>7S zEo*kXpN( z`4lm0sd0UDGB(82A+a-rA6jh?=;_0?*x&uA@=m*r>D#We$~aF9;&=JaCbb1^e!puJ zWQxJguUs%N4%nh|9Pf8`5Yd;ZKBqtHW26vC8{G>cfK`@Q@e^480L>!9S)9bjuR70W3oijLcjk22Dq}zq>@O)F-{ANHXi4`5Z64ZWn+{wU1U$U zHprOiKCHU?PKrA5MozL@XJ4s?3v$~HmVLzIb!NpqboFmmcuFYZewX)cjj;5qd)*Yt2avi4Gx~*MJ>nhaxVKyoK?vm@6=wh)rij=W4VavG1 z2zduP)5W--AmvkE{bkwG+rRY(%S^S)zgv8b!(h~S zd&rxaH#~agj`gRuH2(mmGh!I4Mt>p93=^^N$y`NOxX9S;Kj}4((%B2x$zEG#CVo6~ zC(7o>5S6T%?2=Y8>}`d#KI*$GyP9%Z*Ho!nQ0=wYXv124tvYvWHYRRqNkz6H{4F;S zv~^bbJ^e18&l-x&h#*Y4a!F)mhB_KHFDNvo7@&|;hmynOxuDl;?b55yd6tXC+-Jo; zN!fWPRm-_v%TZT^@-HK8IJU0-w)HDqrfSUO8|wS(mMv^0kO0)l;jXqaZ+3UJY}grN z-bU-3@5x+m#hh=Yey`Be+3}wStHvv8^!u49v-<8US63FYjNAR^8RjwC z@#l{1>9_v?ta{kv%( zx7TWQR0W%Y5^hK(y?QoQ<4{%IQ>UVPW-{t{&b6|#;dNNrCAUjmRr?rR-K-UPE9hx! zRN7ArHJi!zTvlCN9G;`uwl8kN2yL>SYr_oNh{(IVj+8d}6P+DhCfa+RQ}Qp3d>O+0 ziOT$if!ht>=8IOV^Kl^0dhss2t{1)yE5X){55RU)bL= z*YgJ}=KPY@rY-K)UMDx|SL>G@(0IGdG%4*)pM`N=JzrzQG`xmBJ;1zmrmy9H6zhD4 z#eZIWc^uYkWoGE+(mRn6~PzHq)W5;+{J3O?fTd*u_JVZ!K(JZnyZCphL^HJTP1j5b$J~;y{(Qp zBT~Msk8gY`6IboGZqy2;SFx7fwE3B$)Y~pk6a#mWNjJs|0w78ze{q0t^v=aHx%pMi+{{Rl2 z?#G$zOg>7K_}_w9^JgldsN$Y5)A=WrRH;v6Vb`QK1d&qVJdRm7&j_U}tns^%N&7?P z%DhsBw}EW=K8ts!;r4fa2JzJY0I}Y0eQm6j_^sFT-!HkBHa2hZjkTMb9i5&0(Cz7Y z0>2X0>nS$VH&&#r;w?Q1wbyD|qqW)34yo}&$M4(c9Dko(*z#L+;HANJ8mjQtq0Fsr zE^w_KZEmvt3a@QGO?rdrYN5Nr?Q1Ccl36TrX&E#?#}%n0VS%twYgF%vj)+divsW#N z9>>Ji4R>+>0PYQi^T}-22CJiVlEwZ;{;sT6Io65_w>F%+kS$jihBxf^mWo@~c5-Hg z8(RadlTo^*XN>Tk3&*bu@=3OvU!(rwo$ZFs$8MIx>ekk}J+Cg+>0i0# z_a|+8H}=~(wU41)#-t3lu#TmF_FFd&%X_+gnw~Rm!YzE9J*~H|tFF{?{oTDIeC6l9 z8{ranmRt-l_lud&NHC5?WkVY#JI{Nq{3EpB;5{X4Hw)NQ7! z{ck3(Y~JCor9i7S&nSwg_8JP+wPIs7-oEM7wfmkmQIxdXdHnZYPt5vZl1nn4=GT#c z7^Z(^sFYGb<=E=@U5xavG3M#>KmO#mCs}XD1P{>ibh9Cb^9mMj#0hWI{Y^^y7ux%?DZOuoJHWjs;R!x1)2La&>t1D|!fwn2wuVwS@c0P6U zZwc^--)-!>Vdc&r$hJJ=m$mvxe_cOYY4{7q{I8n7Z&O*pHM*TwfV@9;{ry!vW}j2M zHE-Y0@aF3)e#d!W_=kn^$Zy`0fa}}Nxa=IEjf?d=!vo5GPvqA%oHhw$K1B1L*L|kt z&!9G2s`jdIjvY1s044G$Yu4Fv?X)v_0<_m|bN*GOiOr9ZO;?ub_DaUbmGOF&DO2B1 zVA$F!_1nYY73uOQtZZPJ2Uz29I_8g&+PfDqrK}H+S0^^}UmBNLwA)L4^1dS^aoS;H z+UH2yjBR$*d)*C&vR1xXg;P=(A5s^6(X^lIO^1zy%!tx2e0Sarb5b_!A7IC-W9EIX zKdBPQySjL90OEWCr`Q^0n#_ji{A%1Mb;&uEXR@PK+hJCu8;>c*=(hLv+o49h^_^o) zZj3T*p{zC>n_sSiP2SsKeZDW;ZK&Add)_e3k12Hnr@3fcqdy$6v*bG~@4r)xatqgg zW&Z$gE5%>O{ysdtn{VkjpBmixi(m|`knnuQbnO_q-@aD zp2sHEX!g+l4VK%#N|YOY#acS;R>_-q{)-aB^}yJ7T!N0GuE(6-+Qnm(axIOMPBT55 zuta3pv9fMAH(;k#{M%<+Ma7`2YemL2bn3r(uj5UBE7)^!28H?v=-FoLS028mmj3`R zU$n9_`Xn^ zoAM7QP0YC7mtW2KUG8Zfviy9_n?0V-Q#tY69A-GU#m;?R*34+1M^A4=$}-2z_BJf+ zGz`+zir8)W`AvfULC53NK}V8Jv}JfI(A3k`^Y?&N5gLAQ6t>zQ(O^? z`$~|^**UhxNw~)$*d2EgwY#-VnyR;}RIOASe8xTAr-|t6Y_@vo_xhSTtuCSaSMK(c zTBj`?C+$a&cDv2SnuiZ&=ZA0(A>!@U`)RE4Cgb(5_48@wer2i9RMYD%MNT-pf#n@{ z7UBN@tNu9t+j`Ha31qGpfjk$;_zxg+ zb_}P)`L7qya{cc(<+QEOtgo|sB(uqZH@HhR`Zl%p_A>H&mG)a6KUZJIb@ztXXCB&W zn%$=xRb$oiJG-t$wKcT*8SXQ5?mc?Nd3Jhw{I8vG?Oa^b%G+I=tnJ-=%l(^~1$|_x z_3b(~3Zz?Z!N?7Bk*z(c43y-T>YgDZwZ?Xhi`qu9u8uqHWU$bQ)h%ou#=5)?Ha1ea zT91^$EKi^M`<6>JQWmh7aXc~vF^Et53#e=?zcOtR5K&M|qKKHgfJ8#CSJ1u|4k%&q>^c{0@32SpF{B(Z7>hvukIo zi(RJH*)#GU6R(N}awvpUc<%RQZ()0kGnsimNvpTcyq(TDqoT7;+og{CnO3&D?6&K& zwkowpF(ok4Ls`9cJ5Pb_VpDJ%{z5 z+U;*KyPb~wZ7=eDVdk7;%>ESIc(UwzNo~*i)#C0e`uV~kvuA1{(!)WYu-;17@eM!g z-;DnN(zKIoELGS#=FyF#$#pw6YUy1Z82T zoi#bF@qP8c-czBeQ%vh@-C5qjt>?VUM-J0(w%Y8ZWu1AJ)2|j+WnZ#m^|qxwaGUb& zO);qmhOBleL?qP-nH=vsDRlB!hE0UZS`a=;^{vEiN2z=3%iJGUR~X$yI>c9`Z)T1O z8E<7XY+2V)gJPMDN37$UErT_>4Tid{1E|!= zW0i7!z1VoqDgOXuj*Uv>$u)CdZx-UGFXkL`hgaI(rC4kv-tXdkb8-DWu0O*yYF219 zTxN~vEXTav32X6c-d4A-)NySe8XiOOcE6o*PZWN)N5DCjr;FB(!*$ekkah$I6SZ=FcJhOD(>=7gh<4Xn*s8u=Q!YuZ(ZR6hTP^;e?reAY zJloJ}xc;Myay>j29SoN^uOQNs9Uf7!ahs1tQ%6SI-LukOmZqutVEeiq_3dP_ak%UG zejTja-b2YO)YELO-H&;9nA?9Y=A2FSH}~z^v6vd1{k)Biun({&V`|B+4z}BkW~K`D z;TBiTzOT@Nyv-qN0?w>RWecHFN` zb{<#;+ijqRjW*hB+o-a_wKu}sj0cf zCbh_8erAGsAWO*hIA(9XhviWuZKw`*$y=R~uW# z`Hi~&0P9PIc#D$qL#*)5f`r^R$6EVt<$gQk)#!O54jEs5{{Zf6M=e^AnwDE3bQdtu zsEC&ArViG^9as9l!>#xIoOk~KJp3K6_Pz0bKj88|$o|KQf9L-Ihp7Iq`g$Kv;86bn zUHl4vcjD~-0N0lx{{UeAu8;LUe#7#6t$%I#yWjR6?U&&GUa$Kf?l<4seVh;a@4cVW z{fGL0&e;C|W&JC&^y@#Y`YnELH(%3zf3+X(fBDbq2lT&o!}?FY*Wmspv%m4%_E0Mh-I zzc=iM`ah}v0C#);0IKfVeI3<*)sy=_2Cw?3<>-IaKO^Ra0dZyN(kzc3ZWG+hTQUt$itG<%+6`-IW`a3dKRWVzE$c zs8sY-b~sKIRZ8TjtG{OLY*ZZ@zK5|rilthr6{@8<6ja=`HqQ@ouKRG=RWmA6YXF@3 zCH6kdLgcXApiT`_8+N>HPN}(7M8=1L+d+-0p)-0W)m^ntH!oIgaGF7QY7<|v!m(DH zm7-#?3V^CmCkCme9XM2GUMY43;4XTXi)}p*X8SX$rv-Yts=INn;8SvpnxR;&vt<*+ z)p&xjmp?_g;yZ8~gHWkOX9@id@F}DnV5#T|8mg{Im3BX(Tu|(-6OTaAS8Y=!^dqLV zRZuDgf@4(4$4Rw1qF}4Co0aq{s_mkxp{C_M1l&f5RW&;~bXFlzS-(|8>H1>}S3Qr! zZH^COYxY$)M5h6jwDg0PYqmA_du`?MZI3%K!>^KY&{*tsj{Q0fcy!&T8SP9q7wSc^ zL>v)|yg=?Jp}clir`W5zPA*puh5PP~m@OOH{{YcORzwA|m}JVp5mqm|-1>)xCS<7rkRvdFQGI>pM=(Wy^9IBs?Q^s-GJ&BCW)%04dFa#kI!ep zQY)k`fLk9y{vkeN235%C)ee9l#BQ;{L=Vpo7y8&1;`Sx68DJoNo}Zr66Z?6Djw zaly7m!Rv5FdWSTP{{So%4|>fYSgKf#NVqh6kZ=sIJBCs$0+y+?@^%*vKo4pFI0M(Y zct|*1{%gbtPA_j?YM}|rwGidda=}MR7L#wkxd=wU7$ZF@O7U^|6_J>WS0n(j(?y9{ z%${P#QJy1@RZYCOJh!RP44L_2jE-!;UhFvpG7QaDkzv&A-HY?;5F#99r*$xUN*X|! z0bsZ%)bUH$K52yp=+OYUwZmIt8j&z6Hsjk$IF(C z$agRu4NMC9bnU;u8)A>2P_C0eG48I;_+w+7w%9k!=fbnggr-LbbAcJfpTwCX?wVOEw^_aU4) z!FU6D;;O2QNUF&`!;h`u5dBN@O0$^mkIdS4r+}Te$EQQC#vDi5 z>9#OcwC@fZ9h3^S=v3%gry&rV%IUcM(xiQR(bUz|Gm#d3qpOWw>RPL5-*eKd(VtR4 zd;61lcw~wDrSJP2?5P3A|nyoA^_`O+=fHe2<#)fu~AoVK7mU(H0W^i8YQKs4L^0@ zchj|I^B@V5OJFVsq*Gzk?&|%1TMnkIgkl<`u&Dr7nII{7e>b5hMCBwB3$&axqD?`I z+(01SqX0<}068v8Voj%>$||aVf%13!yHJ1)5F4>aTu6}aK_;FP9|(4<_<;rO3`KQ3 zwy1dOM8x*|MWdRAh%zDo2a(Ks&#P>&_yhuKcn+8wobx8m${%9(r4QL;#-b7q*WJEho%Krd>m=wVe+w1B# z%uS76uhlrPqpRih4vwKUG5SwjY$!#^Yws$ag{Mtx$}+p(&$QY4tda(`v*^GRW1nXM zjb7Bl(~ZDkYSPx!lWEp6z!_O1*JGw8p1%Ym0Yv9{(_JfhAJ@{=<1n=yJUxHQwH-Y` zB@!wPg-RM)lR9R|lHxr_>iKW7Glh^e{;WsI2*kdB5j?Qt)6li!<&D1NbjQ>HC$$m< zwydJmR2lutzxiN zckID@)xF+}qM@cgBs{m452$;fF+A3!yxyS)O@y-0YDU<0+>X5BAmO7Q+Z&&m-KN(z zF97jKoA_3_lUdL~Hd$!}nW@rWSku08R&5Fqn9o zLe$Un!XqR}Coz>M_XBE=SS)r?Vz5*S-sM2c6^Bix_A0xT-EE)s^;l>L84@kka^d>DooEP# z0^pqRDZ6IeRlVCPRW@RXcj94inWyoNv}n& z<85TyG1*UN2j{Z|inUUU6@sNzN}yFLgQwA1wv^ni<8i)wm~UXQRojBaRI;&Dss&Q0 zIMq}NrFcgcyKC)L+fQc7dpABxmTad3ny%U}nyRO>Wp+_lWi3@yRb07js-mi*ud`>% ziA7&xqUFnn|Jncu0RsXCKLGSolWcQk)UC)WoX^R1N5B6E?~#cWA0r0;p70ss&w@DupptY+<#YiiCw~a&|N9 zwS7e~J3J+Lo!7%-`Wb~)8CaOnF>t6A0%2-$QvfX6$)ap z3ba1O&yo~&zjCsENX9^roK$UT*qK!wv?-((XqOoL_b3z6n`laQ*vN?o3WTSBMASMY zZK7!_Hd?6FbPiW<{DXUq@F+GZmdXpWLR3P;yiv6_3hEmJwC#eUpU9q;mp_q#C7?Rs6s$PB2M+p?P*(Dk!p8iYX!fOOIgxn7Y|U5~Pg zs+(w^1p5b|nK+_*RY^h0Gv%IvD5ssPc^0KZG3b3mz3s#!3z zi0Y|`?N9C5oLOgY>Yt&qs&!Q1QoD{7Lltd$MK_pq0GK=9vTi^HpArGN?;lrCBJ@K) zG-IUMnZW(cXdLjx7|1aej)Rz3n3hbi_iVv)+^<2V{hO7dvvRy^#A|bOueaw&1JK zsluvmfZA~+VrVnM#le{>To8pdEc#%f|VuuLj_i}8W^H9p`CA~~FS zTE8xlc;R?BA6nY9^q9*ufMM5PVgu@s09L@l;1q-lN1j%O*`9euW_D<>xHWDP>p+m& zggF+7b@h8ujAfKalPP`ECeltP-9`CC3}JCURJpaouB9+l2;qOPy&YW`lc#tV!~Xz} zyNP16WvaXmN}UF&hT8Emz&Z8qU;h9}dQvbV-f}+$__XwlCR&H;{{Zr^k7E3Kv?CM< ztZ@}Yn+p(_*o3tFP@N<%iMnHvvRHjqFUKYX*-?X*>Z)=Bi`J|ftVle^&cn$^%*uHV znRXVjwl8=%T7&}t1{Zu6gedvHF&EUf0R4maH|{rn(afxoIi-Ya-fmxqMmeW=jeF0$ zug&IsQ5FloR#ZYcNpNb^4AdtQ^zBSj#^w06BN3Z3Fd)YxxRJ1mWheIoL?F9~&8D_>;;a9FPieoCRZl}stNs+>Y!ECr|FIs1?rKsEQ1)=)BlF+HB- zVLuRW1dT}Kej@fI0jN2SV(@V>G(G9!oRH%4Pia|oC7NHh4I}IYI%J)QV%Dw^HwC9&;mNkp&(wk+eeZ1vVoS2 zLuy3kV&#n^BV$OjtdY?Cac4PPnE{NA+=Z(yh|3dzF&+1y1hk00H3zm|6ak|I#W}R> z>r&Q?A}1?k0~6ct#M++~{{Ux507D6Zd)RvM>*d0&yDF%7POGyOP7P?Ow!Ci;{@i|} zXJhmCA(}ZvY+&QDt@U*sXoltnS7Uftqer)|*3=?yD=Svl!`Ixu50(*}zT)(cAl8-r z`H}^Z6pwZ1tuUs@ei29!B5-QAGFr~lMXeSCPfWxES28gYmve;Dsw9B&YTjDFdYrdf z3KgVfnVG?FkA0_-0^|Tr>V;Up>1)hKP=H0Pn7@Wbz~Qp{ZcJ@XQ!Jn}Em&$+GI7|S z>VdLf1A+JOYqpB1#_NshCkf3Dt-IA!rrPnyc7%ST@Ep(Tqa8Tqh_D;_@k2Bi8{!-u z<(E!FG;VQDvCRW26n{3L5@*UQF5&S;d5kpZ1Od2W){|+waB093B3svzhy8K{p^w~t z_-t zX5;*Z^sgPl?G9G9`Bzp*B7>los-5v9Kx8XdEGe=!#y~{ zILN|Ma>P&vAU(BE@^Lkp%`f!E$Lp1U+qW)}&8K`NSoVI?)P|hF)6|s!J|SErJ}Npx z#i<~2#9Br2KejhH>|fk6)SFf@tOq8uw5pt)XXQl?Fj$FrNf_EbKF$;G*sWA9syCSQ ziBZghbz*w%!HGsvsWzL>Swe9wAz>6FsNA%5Jp4@cG$SDr1Lk(A6!Am~T~jJZRz4iM zajq1gu zPt;+1a|QZ=EgT(W8DSsVCE`Eom1KJt{BZ-Ez6`YV&9Wv`pkN#0z;RKv#{t!M8>WLR z1$$bZ=9}IS*uDKr)T>+9ns}D#L;lQ+bwdHI5afaO>c{Vo^?gH{d6;TM{W66guCzZT z{k=m1)oOx4dW-9NsEqlC3ofJ&SWTxs!)gV?9)A@rJwgkM1@W-Im#G#axy(+zV4o!0FG#hNPyXi#jP#QBKw=3Uj6Pf& zHd(UGmMV?5CT-euuN<BVX#B=c+ai(}wLT zw2a7%atC`!U??p;iS)FmsXyJ7+x;#;PIEwiR#1AFI+m2=@PY95fJyE4Z_{h;W4h7w zE1HvF#b?y|k8l_dj>k5e6S}UJ2DwDu|uj#UG7sv(uZB1Ftx0MX0WB3N~y9W5#8X@dEumZtvz3`zE|z!duV zwPjZ_ECntBfNNaXwRB~v`6CGsCOkqwIg1fTBH=(?FdLNP(O1x5P=QqT>@H2)9z~W> zNCWChZN}u7T;9Nfb71%FVBYmo`+UUots*gr{j!t$8#IUY0du209cjWwq{c)NaW$`M zI(nXKP{f8KF{r@adspMuu95!$#!Nt%<{b5+V<#Te;(=qiXCA!`h_4igp%P6jLQ0FT z)ThNcPIp;4e5KW56)CZ;RiN0yy9SOj%zFb4=RNzCufuZ=H5GajDk`kfE_v}7ZDOBe zl}iTk+^)t7yP1WfWlCYiuI+jd((<}e)R!Sa)@%rBe?8`eC2!!;@oJt$sylM^sQFJL zmrp;kCfRuA_`f2AKU{B$GabS%rI{{SH$)u_%nh=7cVa&0E0^^;S@ za+=|H&wMv(AZ}4tcDuDyRa9K~l-o{*{##4?Vy9AG4LFO*k+cihe|~5A4=_H>KMsUt zgtaOp#|-bu9SF#Ie=lIt(eOpEl)kxkkU1tCcDs4X_aX{nhRSTBs$s^b4vM`8Q&3E3 z=|D^SlONm95G9gwagb$}Y{r)g(Mv{oOrltr$VvyCWGNtR1R<$EDtynIbN>J#Z3tF{ zhl*6RFt6OQ`JG?w-KPPQNPn_4J#x%?1y>~7wN9L>*s_|cDyk~%<;SA02D}<@yvOl= zeg;||Zczq8SwtL&PDI=z4;UaC!LO&`{ur5PLLw$)nF-JClu5eEumrgQx)UmHx!58$ z*K3l>l~w3(#-|d!E{WY#?V@x33FN4qIq6kY->*rpL3H3-vCpCF=uiN1O96=}>C7~u zSo-^ldlR0Uj@*3*%Y(^AaG@0*yzD*5>PP@h!oUT9atkQwm~F#yoIE(Lcn)k#u-{;^ z4%9VFT3Q5%8xE$J@k$_l#uXso;?Rjz=#=7DqEn4k4>D!-7HfbZ!yC;GU_O_P?w^60 z^J3HTzH&`JH5ZjDqJQ;Im0V0-3H`N~nAeZv9#noEEjM@7BgHOYyZ-=GYMTxn6Lee_ zJqDW{I;RG^9IZbzTk+~jQ4DM`XA;5P#v-aQl!*~>5KSWG%V6fGftpqYA3gZLCXS4O zki56-kKSYTWxmVSSeSX=G3HCi+oz?Yhbait7xtJ$=8luXCizAr<&=-yL|QL^;nh>y zvZYWgRgLW`&hvIpjQq@hE`vAr^>hQqAJZeG80Pw;68ItHKaYRF`L!o6`8D+o zOs9JTc07RKWftG^Ls!a^Em5c=EjD8qObnWw;!EZ~ZMHdDdit|Ev+@}u=4n~P28{mz zuO_2MP+OLl2cMbL`;7S{gljonV!upG!y{!l_Nlh5(M zcy%?rpaV2W`=&mJBqK;rE|rD+Tjdt65NYtbNM` z^H{7lVz5~BT5xM#9X2)U6V!nqkXVA#0Nscr5k;ltJfviF^`bR2wA%p5KsLWDbpHS+ z{FJgSAWWa>6j~p}c`Z{Z`F#HXlTsz0Q&cqJ6Mzm6SRYV3T{+!ohd2vL*Zw%^AIYSD zEF?TRorLst4XvmE5y02&THnrU!z5x3hm_JZ%0tFdF%$*Cd?Oi0_U-E1RY0*{C4$9c z)UaPYm@HMR1&Xz{RP_cIa{ycJn9G+JBEq!?mp|Ezi2?jFnE+2v zVVuSJ{a2m5)2w!3*0ELgEESK|t?pPXc3IxBSSklqDxET%8ttIlMX9G50Ce=_s3L#% z7})`Xn@z!JdEYUk{i;XFc{sO@O-)@uDgOZL2-ef$*78O$l=bv!xt1U688cb;+^X4nhWfN`1e3fXiR`)NO$7juAuvDt4?o7rPebSoJL*VWef^ zj)#|!6OK!V)&7X zoz;ro<$|-lVyLQ_)(aJDDh~Bps~KXj^fgZj#~rO$Z22q}D;0vpV5mFQO2J-M3W3#6 zLZ?io+SsTQ>~f!g>VbT=x4B@kSSkfttQIP?R0^d~DwR&3Zray!n<=>Jn{nb}w;i~w z6^hk@#bBr%RH_A1s1;8diltC0o&|Q-Wj52;skW+?uNSv|yJ^9$$}0PJDyg!o!n{h0 zpEMm&RZ&$_+N!znDyi*NT=}kCx2w7T+5iXv0RaX-0OLx3_+^8Z0L%XX!y(5UE0320 zDxNs`PsbcS82Tp9ugED8cVagv&1 zw8a1<_){O56DKkV@y2-JkCfvjI3AOk<^DM1jVxD!T z3XoSY$ImQ|7}ls)Zn&j56pMKY?M7y&~QPyhp& z!MM9d{If;3U_dRzRGhxddxW=!C}Sh0pbcz1XfvS3xl0<<`fEzkm~vnw5tDzI<%tOy z)X-oe(uat|VF#%3BgkN$Y%}=ak~nzb{CKH2I)zyC=k{VvB|$-2GXO{g47^QGE?BOr zw;J&{a9jd13*(J%R#B62re}d83#5{{SMUD-JOyw@UX#zu`|uH%lT+yDN@2mHGuFA+ z@57WNEps0X23G{OWO1j*0yjRYjK*N#NQ*`Jb#meT_^YtYWNBZ9SQ=ES@d`N)JSn(i zqz*K|>HLgqUmO_>mCxnDAY{A;!vZZoDfJ3rKw4w~I9Um)2ax{&903|;)%}XNfrEmk<$hGkp9Y`H3 zmSYrHnSkUJ;R&{CII4k}`?0Ak+*6xTf4>xKDFI$I6~$$?k}*ytO)*U*p8yFs2c!`= zmOdX0de-IH1zZos@E9OiNu=;%^dlerK6xB+uBA9SwuqFIP_IE;7aLWqY{tH$P(I96 zV6#Vz{G@3gWq9GEPi-7$ISfHqoEapxEGbgK!2N>(npq=S`k@O`_8e=nVg-1}K&}H_ zIWB()IeyF=cw>Q_eCZek>F0s&7OzrPIUDBx0LxtP-5Xe4kdP@(TzKV!H%f}etW|=6 zPb>t5W|X(g%fV@a;%9^)sgcOjL*rUgAEe*UD3DM~bph85YFI&JOZWl-9W36@=GL0acpaQNY6w?&ZZDDID>0C=!D*E(Rk>e5&e zzc!*MK^4Jcc`Cvbl1K^w<5CU{tkD#%)U}~FXri;Zyat|uL?3z2g>bO# zmT9)BAQxk;!u)*k8@ub5EmYt+9I+%`(PL6GHK{&$V34ZQK0YU&8Iqkv6hY>2OuWWK zaTLQSsa0Y#9C50oFNQO~dJ6MTED>6t4~`ClLr+(b#E&LQhKk$)^BB@eqa4S>kCp~x z(ST9UE*arHM^kY=bfrJSxIs`^zh->T*@|iW!sLCJQUPfJsGzG8iC~C{$z`m|m83 z<4@a%6ae$Dfx{6-EOH#^a2ZagULv?C!#bK*k;8(ysmS1xa~!aB05s%A4w`B4{{S2_ zJi6IPs+v#%;etzo-+{RP%n4p1D1KEsRQzyHwMw4?a3hM*8o2|YH9jW*F^({Ks2|;p zF*rv3@_j#W!4Gj9l;E`EfHcP;;%b$qC}K}n5~7$+s|1<<0EDc-6Hft*qb{78O@F%w zp+q3iYRnIgHA#0Gui`=gAGG2~t?l~LprCYB2wR?b{M%p!YIHRy2gd?LxsEWPm+H2b zT6otTPkR;0*CmV8Pu+(W_CQ8|hV16Qb_>qQGM)-W0Q<3|vA54AjMRO#;e~nkGax)d z)UuDZgA}*8kywxvY9X4u1qKDZQAPpvJ6FW=7!xx%a%j3u4g)_|Qj?*>lECukiK2Eaya5^i|hM|2Q{@B-3^%Jf zn&IPu?nq*M+BISokNdnUg=Lt@p{k5)sC)>|30td$kSR}13jWdiaU09HT|?3ZAeC4h zD%?R7=a1$tZmwc+>v<$*txthCc3FgA0$duer_T=-*Lu*x_3H5fhdK^l983DIxSr?% z?ZjbNHeB157`IwGbDy?W^m$bC!4gHGPGe8^90mXo4s{qkKpDx&mp?Euld++oAQ~Tu z!$>nHf#X``iKTQjOv3a2-Z%$BmHY;o5A(u>WDK<6C`dVid`=A08kaTG`*2Afn(!R( zY5)V42pmN~Um9VgcC7^nz$YYp&J2QvH}E`u7*L~0Jcsz45n7+}!8-JwJ|hH)4wF!5a>D@T zoL4?Sb{-hI*E)VlzEmgs@T+Yk7S%Pn?k%GlKpGZII zt`gqzJDWw2=}W02{G;cn96CV&$6lSN(?p7T}FWvN0rTVaZdYM7u z6;4(2IO*QsNi;%$Mku516u=+?5BTHJ=^*5IV09*9iYThbfF2n1^5#eQ;fpnE!~uq4 zDttWfY4&AI02t-OVy~Gwu=wJjQkikas#C-Ro_Gx4sW}5)CjqJkc^X&tW7H{LRPpc_ z(gh;~`i@|c!lMU(1%(!w8u%P6iBN?43i78AeEg0SO;F%wMp==SMhffcv0Te@1CA6* z;!Ka{FUo7cf;j!y4HJe}&8l+G#}fpEGMW--NC%Ep#9F`#f}wI1J^*+OJBQMVT`CO) zMpQm$5d%a}cu>@}GcEpDf)FZH=m$s|OA=23pE_3y5I&S1qt6Uj={eA1icL;!<%VV? zD%1cDZCYdURf3~>iO=?qSk)r}SBT|_6<)324oA#jJ2g)~@#p(+6+xtVnji4OyUNoY z3m9f4h*T6+&yZ0-IboY!L8Uwf8c7X$fP+ujhIXrD6o0y+gCXDs52mHE!7>d*(yV#Y z1TJ9E5JrD)GIFB1Q!W+GoG`965GhbHC&var`HbmW<%J}GNd$AI0?R!ae-DVqMH;fX zAwbTb_+V13SPf+0L>i?96qCdZXf0hQ(@rM}%-)J*pmWBpUYwvP{EGR3fxR3{c=Y|IL z=ntT}QAqRi#C8+)uh}9Aq2kEUQ!;suM-qOYWab2^F*6K@n;d|q3{SUJ+nKNw zt|dzww~F-zC$==<%OgYgV7u5$JOxIpn8vZ6h~hBa3t3zstDPhO0M593dkg61y-pT# z4w-)*n;ePqICySU+f5!$lH^Cn1xxiPeshpGbIB>GiT>e%ByuQv6{bvR!iJ+hM+7yD za)VVD2CCwxh+)SKd2eoHw1^(1%9^M=XvL2afzyzrfPx)OD0vWZ(B5QlUnsXV&5+X| z2q1%* z!JyBb4RK0;w*Z&Z;xNne5%QY<0EPrn4Q@_AWnaG)oJl85OTLZ@7m+-%Jkz_!6gnB> z47$pmAyi?PZ-m?0A^fu|Rz?GvZWZ`o-$ivSGDtNjRcaa<5_xCih*NTDFRrcunj0#F zi4f))Vn5{<)B=`H8?eWe_ zEC5z%G#{A(qJdu=N88=EV)I6WUHMRjBx_PB6zr_c>8%MEVgb)1TxKXp!)RJ^q4UEfYQu-e2US2hgO~%vSM9=$T0)8`ZcCY_RpxMt zDil=b$et(m3g3n0sWX`5vcq_%MO5_0Z%_XXsHa<29)MMwQxFa2Q4GR6k=7EC4Vn0YFE~2 zRv_x7ML@5YJSw9Q7}SB0HNXmKQOiC!^)NZ-pF9!9gMiBo6=+xG&xhTNs>=1PPXazZ zCmxoeKPm9>t~EQ1iPCu2`&SO(zEVX``h2j)G^}Ig)N`f)L7_Mw6OSJs9A}EV1prid zpCN+;aNpQqvVQrS9;901+xZ5{d z3!9yyc|8c4Q>Wm_!->R~HZSh>{X|C~{vr-SMdATt*DO7nPFR{XvrRxHM&QchBaITm(J%t2z>HkS3mccSLi3pEqPLGw5~!N~aGp33%nGSvh`?4Z|(AQ~L89j^5h^I0=xcM%3y>*U<4 zgx&UgrQWt?`F98btY`NokBT?PEHKn6c;lxbsRD{kPu-1V1P6(1zrP>LLelzm0;AJG z{-Z&Or|Vnv?agL}NkEZ^G@_>yhmoZb@uW{w)HsSTt_g;cNL1?ucoUvq3g9iXPdxKc zO}uDTN#vjdQ^L4=mb8{7h@EUBA%!@TTr+?rk?5rl9QYB4;Eq{gE&*txZA#2ZrlL82 zrx(`S^|V)ea}|;cvU)8Ox1{vNNj2a=<4k*adz?XfsvbxtV6noaoZYyBDZ`JCEK9i! z(d{O=)Vn;(rboF}I#y&%$woN?Oz}L@nWwwl=ant)B+pzyh|>!x5yk-@D*S7O)it!& zDFA6V2*SiD;)75bvu8@vjx6Sm-`sS7XO3a{ax8~UY8%uIIC)~C;wh(58AlXuHFO7REg)SHH5~Kv!AB;lDr$ZP zm`wv$r!ny1f}ujxP?6=GP8Uf$K{Peb3sI5a-hMcs2E4otaq6#+mRv>!NUd`O5l%mT zGohmfP;>CekF$msOaB0*x1adnvprax$v@hdkf|+Cm&oTz;hedQ9y|?bYH9m0=d2jl z)XcXbKI8qj&d6UR} zxQknO% z)ojQC6s1TYaQKW(qRLcdB;48>JW`-FZ3O16;Y{%(MJ$RL!$Pw}v9ht|4Mw5Mjyh>^ zEySb>v`BhrNB-~_^EEu0i;k;iQs) zH_D@hIRWG;fRMuS$loHMB$MzMJ9W$q@w9sGEG8;Qgq+(+H5Bo{-8Kv8=%c7DrIAul zIna}(hsOpT<}q!y}jL}-@v`Mm01tRI)mg!33U}V<5PyT+S<={XsYH5 z3x#(;IDs2!E%pP6Ai07|S)!(>rds90#7_9@Oqf zYD?5!m9)+KvIVN6SD2;|?{^Kh%*aTN;7kah;p?S7%ru*kxb8jUEf6(gwn6*Bs@nXI z3`4eW9la3RmyC)!&ZC_G)B7i2Nqf=&jWaL2xnT$_s+kJ%hcTyKs-nY5>f(Xa}fRX86SBD%j zcW%*bv~7$ET<&(4sT4$>3Dc01!yp0SjUBd4>ao<90$PaNjMSlC2a&EKy4`L)pScc} zZ2FwdDubsn!nFdtDnY_eEK*tR*1$;*M26Kd{K|A!92_X(}i|C!IzjgKw8q`)s1z$f{dZ zZyiy@K$ll?tSj;gXG)ANyOzCp6h^uU(6Gm)7zmE4l`aOV)_{28D_*gY9!0jcvABqc zh>@5Vew_-uSx{4fp{7F-?6%RPT3g()xZNZHWstQ7Oez8bzjZJqE2K0)g|4-r6fa&` z)|fGZ&84c;%AuD2gm#{De51JhPB3m#a%|4(2ut~Xf0Z2TstYv zj$;JZA;1R%KHSowBHD%ILffqc_0y5xmbubLMjV)Y&tts}?8q!Xxl0zX3 zI%HG@VsbSCxg2`wA!19CYSllye6WbMV(Y0%ISR2+S{#i*G&plS-~NiK)6{5l4ZvdJ zN4;t8S-*!GjR{@=o^&1<4N!FEwLU%=FBsGont?bHIi-GM$R9jv)G(*SaOZ&;nH9Oz zfkEPMZX0#8u{Qp>u4Iv3M^l!Rk3aLnowIaVNN-KTsX)MZgToJRyluS;f~WcK_!^H2 zk)C*asBM<$U8QZ-36@(hPGF3KDe(+2ux*gTZ78p%0Y-3g6shBjiSA^*S#DEY@;0q1 zIQ#}CW|5v}ZBHW|RW#2$5F{l2?L2WM<-NzZLZm4KYjS^ZarZ!5U`v_&ir zj|@D5;U>9XNwkMOInb7G0f`nJ7U`scpyqPSSDkThCA{)l%^T{rxs9mm!#zsFF-&UR zt_1fMw(AMKrkNxNO$+j3E5{7h_YQ+e4?QRCLn&?#|j5QjkoW3NvBa9x33 zdW9KC9L6m!dvA10Xrj{;7t&lQjTV`sY9Qo1xZ*hR2sh#f%$e zgnKU04Z_EDx0E+G*O8?d&m{S4Q>m#Mk)M_p&u+0Z%Ca@e!})p=Du{ZMvof$C(15K) zH7Dg5k|^$7ukVhjy3f+G3XX-@YFM+rWwRVA4=h_jZu8tiXDBX!(z5#X0BR~|MKk4q zhKq4JYGtNMIRW8fUan@sT_g9P~15VN5>P=vPm5TOUE;Xp5>?s1E$VO$TE{3Ycr`1u%juU&pLoBi2;T= zOn@MrjafZZqKf3ijz79jj#9%kbkqL;6p~1#2gCmW96Gff3CXh*p#9$*=rJ*5EL3G~ z^#o9`^$uD{84-k27fh7|s^+ADl}Yo<1n3d4V$eo4Y758Grl*HL3`=KuZ6&qR8c!9% z6<|k^7zIl^*U$j*%K@%QNZ;qF&pu#yj7W z1L-3pTrHKx=XUmE<$Do}v?_VqEnCDhWPE`|)t-87GVYbsB;J;xOb9=*xzG zZWd<%fs}4d4LOP*3^n>{wSwTZF%WufAZ5&f#IM5)vP07q(p;Q_6T=JDRS#ALPY~We z3Sna`0FAvTjWVI(hjJTCfQBnd&{Hv7DP9hsg1kQ8JP;Z{5~L|PijNPD5mV-Bw^8fD zyw{a5G`dP7HIXY^hb+8tuWH>FX|`mlt*+%^BMnj{jLbsu3M-lT;%MG!TdW4Q z&oUS_N1a7*k%mAA&FJ;XRxPdM=0P+bS#rX`G?GmK4Xshb0Hl{JE8)-f;{Mjw?cVb8 z1xpYSW0X4ptx!#9p}34sCAO=H0!qCa#&y+G%D9Gq)qVNN;ci?h03{*7U3X?MGcTT4gNc^Wt&Acm7l0hfqY<$)ndcGwmz zdu6ypXi7*~V{y_oc7B^2)|D9n&hAdO+S`g`j@JtWqZ=@WU^EjSqMQ9F_ z=Y@%vNl;jtbLWP+14=0XC^TL)G{X?3Ko!(;{@Gv+T7`K30Co^lj#Q;6JhAJiO@IZK zhJ=dK#{mfZ#i=ZEIpC~hvV%jFFc^A>t!d8@xl)9W;kX2f_>A~qRfq)Ar2W<7fE)31 z8PM~~#{tq-WK-$@T$ z84DgH5lRvF`Qt%qg83*sX_b7A1NC}MLMka*5LAronXNF4jPcHtW@`FDsUVE9<%#X! zy7z%yk~^RpF)V7{mJ0r%s)2wxfyW9Ig3h&$go3Ur3Ka9?ejYfAF|C_Wq@}73RT)x) zI{yG+h+(*p4FD2Xh!xZTr#g~;I7x0*uPSw2q>NXrDj1zW>pHlTTAn=cvc`f(jBAp) z`g0nBwE?AgjPUYE4x&pip<+~=>Q^udl79N-i1t6J+hv{2-KwhFZ*qEGV0Z$;gfRHi z5$=7Tx_+B->OYW`mQda$bFLZM&P({iQ(6yS$3f1R>E2q;Z9OOwR4e`baZ{NiBhLWR zqnM^E)1W*6!D2wC72#io4n!~Z%Mr3v(1AnG652sOQr1+{B1oaQ=aDrcnCjfju!B+o z;&9RJ$Qgn3$m1+Dw=$NNntUh^0CA^LrE{iO6{uPjVZ_rCEovQfhV#czdR;)*<`hzx zo>i!ckgWv)Z9_l2VyYPeiXxsAretC?p7wi%fjV)CA6|vW z#z*rRR1@&QM~n!@LB|vJ;iD%i>J{fsSSYh=2~91eubC7%{cb`k*iY%BF3S$ zBQGL(R}sYWl@U}#92QmLLV!F@Ad}f7!cxu9dV~rAtyJeia>H*Mw#i|8vsx+(&9>^? zFIA*drD8ca$kl-22c8z2rIhv;Gj$SJ;(K!zlrJPP#=@aMDxi$3&k$N}R<{;gh14vr_Cg{h*v2?r6}KGtS?g+zN)O;)Vxx<^StQ>9gTnv+`Kjk4lf z`0t>OOYuEo32{yet0rbWeunemnZ>D=RN3u!D^~XxcM&DTNC`bInhKTGBtbzrkA^NR z3^MMPAc=PVzPM5cX4KM%>zg{L45p!mRiFnKF|$ndVJN#5>P8fn44?{8&YB;)ju7st zAhw%uo@+Z>Xd#K?ie(JGm`IGXG6il!mxdvl3pZPRuu1LWMoO+s7FK0q@-~>HEKL9k zX~P!VoVOz8G%m(a4I`DP`g00;ri9dgn8l>Cvy*dEs!&zwL74;!aOZ|9Y7SNMrVKid zO+`&PoIFwfD*c{+eh4&UUPhw|4nUmGmLv)^qAe7U97eUF;=y>+BTP{;EtLje+lBxw zKu%P|L@%L6WaMZ*I3rH8LKNju%>Mv>6e%^OSRPsNu03Bj9eMa*i4Uf<9(Z~ZQihbE zHKtrgj~^@mU8EqNTc7+mVyMH@U)j$en986E>hbX(;fWg5G&at}#|t=iMXo@w0;ZW% z3^P=S(=xOS9=Wvdj=_a`45y z#r3eCY?ueL-QzWeL~b5q!xD*7YltUbOpwgz@fuJSp`|I6F&&QWxkua^PLlSAa=A$E z5o_}5Z&9E$rY|CU6Kfm#l{F)_VxXqFHeMqVt%a0(v`a>NxCkXc%z~zj2=K#OZWgjx z+^s7did4|>K6Stp;o*$M4tWkA+PF0o1D~E1rBdh(NL)zK0@JaqahhfR^)P0hLnBtA zya$FUT)3YMF(8plzs~{GW;u`Bg2jbgx*5^{{Y$*ouo&1u0-Q+jw2&6j*Zm$i38PBUmUR+0gD*_05ZHQ zi<**6O+4`=jJX_u#c7!}I6%Hf5~EN6-mixthK@B?mPPeQbEm@rSBmfeoa==Jg-OrD z?Ziro8J>Yxhxg#r>KtiKXO0aGNI4es!1WLfD#L{iWMOqSXYUwbb3E(E6?Uya0G!TQ zQ|!j70hbI$;mR_Q%101ukr;9F5GWRu)1MGN7_6Ftk_b_lBzTT^V;HG90CNY+8iY%s z^Be)F{{U|seo~1Aaup!bynk*k8aSRfYE86qm3LG;1C;<40PzEk40$fIQis&patFf) zOkoy00!x(pRRS92F$b+W50j_`S!PM%gi}Uz#IzS_dJTQ?5rMV(S(xX$p zkOf+rxK@I+1e`>ktpNUG#6cl-dWwUPH91!uIF+WkznxapNLNs1VL(e!YE2X#9C3GS z=#or@qG`2;RdCu}m6oA_p#boqt|yjh{nY6tV`dulA4nnoS|d{;J{X3}cNbSyR&YJE zdoJZyw~ZL)sI6KW{>)Fg+ux4Xo(K&0wt*ht2?c5lC^aJ2Aj2$M?z?;tUfa1>w^W)w zyAmp-LsCfa!d>rO(YZls1WGTvd!ajAMk)|GUMn@Ap@q|+DO$@+3w?Y1{U+WyrYW1ihu zC|CCFMrCFvF`Y5C-q~JT+(Eno+iJ%uvr9up8f#F%9K9X;SnIW+bzpOZ4!iFOp6#(E0Rgn$DJ{4X!Z~-rJ!RX0Z8Ox z!TPh*kj%6I5lnyw4%eHwvfGv;I`kBmxM1O4CX%bts+^5!!w0&zX*Pb??bM75KHIV+ z+|;lu?j%NSDWoxCeOz+OAEWk_t?t`lZyOt+SnI!_4cEETkQoxGzz$}o5yx|SBU_d) zEXyXSV$c}%B#aO}Am(`v6~sGUu&mk{;h3(TIpX5M?g71wL+l}0 zfe{OZGMN#Sk_=#iK{*-&o;K?(0`Bi^GNcx=1q{-49y_pH0a30pOEYjI7tMQf9?=re zZR;2!z(B0iOB_)$>(kXC^pBTTd1GenF5lWD*?Uc9EZ4V3sQabVNT%jl0x%rZ2teT6 zYnCFjO^$25&8^<)5Ii!pC#Jg0jy^@v5nv8r8hGN@YO;jgU2X&|lwvoD;ZlezQV3u} z1#0l;#2i^$YYgh5ns^0YKRh$A0B}lWmyRWRS5;^{u_3Jh{@Gv?;aXP|rgg~qVYKF_ zmk+-T#p|o^nwojxgAOA$1e)jlhACQ(3TZ>1_RkE&2ChND<3Yz7OJ>6`5BK0P1xewS zbl^Dn;Y8CIVyPxTokA!w^n$e{<;MV5RdNUR<5_BwJuA-)0;nu1#+4-2wH|&a6*< zKnL$P^W zP_;m*prti=<0gc(IjEkhy4N9I zAe@Jv#}KovSwe--bsDh*9IO8Tjvak%Bz;91lSn@@8rR2x`$iH9gjcHul0g`t6$n^@ zD@=x2nqo;ni&U%CmCFh(12F&^3W`*Uav);%&w1M<*zK(1FAdeqhT`^l5$FmP6()zC zc(&d?op&s9USC{Ew+*C7ua)L5o?r^JwLF+m(+g|5Ta~zFQnyfk zVlZF|nk`7EINSFv*3E3!bY8CA1kx(aG-jT$7^w^9a0ro7L;nB?&-Wg9GS2-t$@G)> zkATNdqt_u+wwD=d0O#Xma+-pYp%}Avvd@IiZLgqj$K&5;?W(CipMI$w88dOq+aGHfe&;UF*k&9bU zX&M70lsq!X*An#<(0Zf)0C?cDX^t3|^Ce@YK;u(f8#pxGO@58gmNu%Y)`Zj^d@(t^ zMp>bO-X^G3j#UAdR<1gLDk;p26EzW4h-YI;l5qs{$g(}*kXqQQ0yQI7t0|=l)QTbF z&n!ni*>f68XKC(kE`va-vE4a`rm;v!kk!ec8ijRG1+FcjyWHitf+j$gcTK7`Hshv- zMX0MCMx^o7aWTA>HWrH3*H+NU8|jT$w1zUIbr(@25KeR)Fn4XbXu85ewzf!`=R{wS z7~M)_p?RJnwW-GMC91SGPW@Rf@8TZsOE50!(yB&^;4>8&$gNn z83w4b75TMPn&!u!3`uXgYPShKxeTu5r((*JQCJZxISOfBN1i5W8TPw7ISs@se!+dk zuvTYS^@I6}5q&8`@t_#odzKBq+U-{_A+VBJk-{yymO3Mo)crcCW>N~%I@F9<_m=8q z?VilD2IgChC8xYL-MAza9_HZaZKyLVZcI2G;g<#E5LzY zGAV{M74bN1!DGk{I4@2okCDdRvTSy5eY)=#a9Hj3%D@Mn;lyz%W*{gmb0p9V&OfTZ z^&{WksBS42UAseTouGqK=3)G@Cz$divMJ=aJ7>{O-M9Kr+8c59+eNe0=s9Qxl$v^4iAcX^2TO@zh(#&Bz`aP#!XzfU}|nBj~r!@)9NRO zpWlXtM3yV-d0lR8WB>%yriw*tsfzF>Iqz>b==fXbN?+J$SM*^ZfE7+0WR*#HGiNYC!VDxF}sXq-x9 z=^?2x(ZAGd<6540eFVRshfsATTT$}{ zw9A$~rQPh8_Nhe{*BV&@DAJ2sR8V>18^p1Z($Q6##fV8Ie@?JU<)*dei`zZxYu&aj z>gws{j`wVtTH4;(w3SIBmnPAl3|~Xp@Lcb3Slh_^Rn&oPY%RG7*sXSZk;ap^=EW;i&^W<{Ey)^Hck^*p>VzL5NfE+ZACGBh|=TC+d#81bk1V?gx8q_qzP z_~JV|8CmTha?{8O0oV!wPGDf7G7Ss@sHH`C{eu!(MKc)m=(&+t)>@EGqu>Y_3j?V$ zeoCW|0<-WnV?mhX%NDj##cd4BEB^pI^o^J}8BH@CI#Ws0T2iM84&k?4ZPzUrxQ%XO zXpE8EDzr|a$I4eQ!-zPv+@Ew?_%9$AQ8@>wS?Z3mD_2PcNX*oYE%>ndedW#Fy6LvE zh6k28ArJFJz)~<8wJni3WNV0emkqe?S32VsgfR$37N96KRR>4_;P3Rh!&{sZK+alO5 zrS6X3+DgN1V_*!7o|cH{!rH)=!Y#h)NT#1lK#5T!81j4V;+QAJzEgA!2J&&Lw66t4_BnpCl`!n`pfR2mK*e6d8} zc??w5+l_oMu|pAOY=9hf9s?c0+}8JEa3C~lgm{B z@xc#WYmr)KT5-=5)CC9Opf&S6@LM292+m*w{-eg2AaDY;Ki!YYVthsm@n7Ao4h2Xq zGx$@?;4^8WQ0c8JodC}o+N7H5pvt~0!^1pjAk1}FOK|0orW!)RHl;?BrhsS16w#)> zs*I{ns8YFeA7%hmB0_y7IUZCzumpKDf}$xsM4IXRJh}M*PAMyyRx?D%ucT_`bM;oV z^YX-H(QB*Fq>vAo;4-Hg;)_uPY$iMypjIlZ+$u(@Wz6G2jbEh0O%|oH$!Kd|o9)XN zov^ol*iN!(gb^H&ykzPK`5j7g0Pz^L?f(A&+%9f5ww0mU`=3#Jt)-5yQZe;BOi!r^ z_+s05+dGo+wwZ_G?JXgbP) zTTrHDPA>b4XxuF}xg&(XbM|K0tTZ}FCPQyK5iDYrsvSTcIJk?opnmq))GYRUmfI7~ z*2^ynl?8&a92jvJcrPs`wYf~Eww)R`%fv7T2=?-{Or%L|Eoi}kule9M;$ggyD2&O| zSl)xgpcVUZvv&^LX!m=b*Kp>0c9ZhuNA&1;+PoB+73Yf?H@@8)R_(k@zo*zFQIfXg z)t#Bvpr&;LiN@V|+x^G8uX0<3S*+)P`*{~uY>!&UKzMNDjlp5vpq5JubhwrmdKuN& zY7n(OS^)*Ch#hWHN1PUD<0XuA$OZ?2JaWJytU#oL%p3xsR=Ic|vkX)a)jEL7BjJHc zsT8ev8sS8%mm^Ay{{X`jjev@|z~q(t2P{-lDH?#p=k2IC>8$8phN=jz0bH{5^Qa>k zuM@)=4@>;Gt#hdq=gTwYo)^>s94Udym}M$m!1S;@>(9#)+oP4by;6ZiGDA;LBR?D! z2U}F?%yZ8K3JK^!>EM9oLGd_~Or$KHnGI^J0R#i~fN^g$chTHQJd!Ndii`vyO6g-E z^ssuIhGLoV7}SwReHFCHJiC0cyw>t))#{KgT0p4GjyT%yFLyhc<%Jn8ZSMoR#uxZ~ zHe$y^15H1Mo(BqIp5ESdLgD9diB6)%5K_6Q)aImAXYrG7+HYonu>z>X=Vx!PuXF@4-mXa(iFm04%@XkRXq>q6S7;+lZfmA2Qidzbd@)V{iB zRf*OGD-r1^^gKYY2T`asIEFp4@phievs4?ea^A>c+bp7472Zy~hKlbZk`)PNIZy@| z+WT*4?sd7?%mVv!-%{RNGkttfgT`Y%uAE6#PBf|DSe!{`vtum;tUKoLPO{8sGUE9ZVKXKj=Be#eyluDx$ zA#$wDssr$?D~l_;*ju^x`#lmve}0ItTglQ`nALPpA?6GCDv^;Hr`3bGaX#*k^5%REK&=JxBae+8`bcHZT=OBJrTZKE>1 zlgRC%nPXDX7GafCnkwPdy)vmP(X}h^I8-3&YA76d_+pM4nbw@Va>A9VX3B(6fOs76 z42!0R<~i{=MU6Ge-@^f@O?-SX=G~q-T_lBFLY65y7@bb4fvFsVeDcEsSyZbmP8hC+ z83X4+52W$IDr-D#dZ<>E<5ONDfE*EQ?xCuz zgl5Z9XjphqR}C*$qfk(SXzUN+11f{h_TtSqNv5&0n5n$EhA}LV#V4pRj-WjigVMDi z_~5ZxB1fh>a`d1z71cvP8idehYmd#LP;~=LfTcd{{x}zQ@`$c2opiF)NEqtSQ!sMV zT8Fyh@*xv35eV+7$Hj+8~ z5^5fjIe6mZw6{B3Yu&E*^Wn9*j8C-gmdq)yLsd;j%}-D`xfTL{qutv8H;~&%=J#Ql z>-m8iom+5x4M46eWxt2n-79L^_lsvq?JgJhp_OW~Ddwl`7~EH3x=zIIdGy>*9ks*S zS>8DL&8sQ=rhXFF;M+|bM?4h_7*W0>#2!Ro z6eKV?j6-m`U6sQXJPi$KMmE`RQ7v0;gWE+6AcWIhM9`C&IE?6ySz(i?(KpKI2g-bj zz>H?K z4aHCQ;(&qRNuVEZ3@E7@GN9(CKiP+IngRoJ#}L4r*$)CM>Hh!>M&6Lo9I7*?nZY@j zoSMa4g>%aSL?BS+ql)oA-;doDBo01&a1AvU6|d~Yaunf+;N3R};hsb?0I)z$zb&$B0E49FID<@dq>wc1!D3ECjx_TWz-UuS zMNupIm=_2Mq4A*A_TmlJ@?X@gE}&PNZ1)peM|A^=1ZIGS$l?c;lIST}1*i&ERRm<< z8UT0^k9gab*!^dYOG`UAsT@io0b>g26a-QclvGrBP~u~>TVC$lOWunpA?b#=mg0Eb zVU1&rhvurYQJ2yVXDn@N+!x2N`(b6ImiO{SHsL((pQU5RDb{g z46zp7x7b5rX>O{v`+cG+D$^lF8JhT>I8d<|7L^J`PoI#%o?;ZT)k|^sj1*E%qe}T= ze5$~Bam3N|tJFGa<6NnOsYL}TADEyR&_K;{CnM_5?!cbo)a8v024|js--Be~ z;fH87#nMywXhuY}7k~tc5INy`dwIB$ZjiNv$h504)hTi__;JF?(J+GjNYSXvnX3S& z#PJ*e#jf9J61~*SbzC!*LBx;+D$GZy0CEDRmB#NR&`aF=t@Wp~8*qMrSoE#K$*FUW z;Pqn>4g|iTnpYk72GnM4t_}YHagT3%igj8Mb0(L4APTq4XgT9)zY+Dlwai9XX{bpa zpsyPt$%CmXM=)uPbpi7(*Uqcd&KbebiG)=4^ck##9o1!IuV{JL`Da1r5FWjbkE zP=AeZ{bXSAniXaBD9q=ET#l*`#AX2VKO7g;R%&{=)|{|-si&-X*URm}6x7F!Ic1G^ zE!203ArC;Fn9xTT$_L7*qr}rXl1?h_S!tSH$C2T!1}q6AwrXXiYit74yKIx^UXu zJ4XfEkXfXPgn$9o2d#6Z3G-8gb2dpJj^bXCc0?s>AyGv&)Mx>%M}fuHsZpX+FzOH) zjZ`pS-)#7P?N1Sn_FFqwn`XSTmfyH--aS^$8K4ayIUOX98PJ?hCfZs%XKhx(zN7~| zHS*zzzL|YxX}4b0yKbLtcR^-1yCvM7gk+G^m{^gh9EZaKIaPOL+a}j-DFdOo?egjw z^7XDq!2Os#!}Ruhp5p8~##_C|w&P-Mc6*Udyi(heN>Kc=DAH?)`=ht*X5DrHJKM_) zg?+`Xb5C;+Db znPHn%Dx_D9YAAodjvm;eLE;xVL(NOB|mk1P;9KxRlB2bsd%&N}y#oi>(XfHE;WMqC!T;$6#eEj8T7 z(8C}Wriuq3I1DYM(f*~iIz4vjBxMoG>rSj-9Go0GN1FqgW0=hI=ZPwzi_{fh2+xHp zz}BX?ifG+Qg~>6sbTvYaBze&Az?toZfQ2JkMGtUXtaT$#yiRcRq z*c$jNQyX30)w=E*W%A#&_CrEEVpyXKEU}YNK47{^=g*ccj{DzRU(?R)+(o>17BlVB zwUyYB)mCO}eO(yJ$)N-LB(rEVkP&(Q`B_5-dqoY39*IW@;$mOtH6I?vl-QxuX)6(dzc& zC2eZKj&-F~yhSlFxRNRCoFmScFG*r&IcZqP)H4}!2NCVNe$jV(VivK*w%VCzS+3}| z>HrGTmXk$6KP6j*acQ~zO~0SD_RDAfQ?u<%Q{I^LC}Ta{S!3%yr)2=?G}1;b_D2eQZ;@V3<+lm0+L9P@@5&5Dsv z%ZAYMX~-XsBbYc46(Fs0_<5hZ5+fc|p&anRfl*p&<(Di;EU2s${G@qc zwX%+)upxjM5uZFO$w2XnC^Vov>M=Ce2h$&^n1Pav>U@VhcDD6tKeJUgdu#4@QAljw zD~Gp|NZo*=2_lYAIQoL})I^rcqElrnLMLUUrDLF1WMEEeRM(lpI1UYJ75w>teDT+L zlG-+O5THVO(g3GHPzYUMF(jTx0y|q%J>=q$B8^f={FEGk1B)I2W^p#}yGsLHS;E5H z#>7Pcb_Q7(o-ZW=ntmNBJokGm{pQL!qTA-&zo#dJt;+5@w6WSM85Mx*#cZmAzNpqC zp^&73thXp53k~39hGAdLR7jk=5=kr`MpAsK%Mf=o*0J1o4231x?xs-U#evrxu|~kD zkWesY2ToKK&l^uieB5vEclo2T-7coRl6AThHi+Vp2C9W~r~on}EK9X_4%a@}xWWON z)@?07%TbyZQ<1GJUmO{3W_hN#{K+Sj)!mQcsm#~U1hoqRKs*oG@WP|lr&B}33iBXm zOa-?fsWdX@QY*w)hr=3_G-UwwIRxdzjE57;!wjNw?)lePC_oT3Lcn$|*o zU_h#P5rKEN-cMn4;iHm!c^W1v*%T#6%gEsk-JPd%ZEYJvb+YbhSf+)+)VkA4uNv{h zJ4a+lK9+7b6?pq+cev|px0g&w>BE0crMV=IpHvm(PAs-f+i2VNTj`%wz4qm~+NHFU z6R5ICj^VvODWx$rmwj#3?TBZ$wX*LGn&LajEhJ>qrbJdM$ixHcq3}327SsNxv&hA5 zH`tJfWdPER#3KWd3~&)qj}kQD7E1|D=wQNhkZ7lv#Aa$3kWdAnAP!ifz!pLBy7+uN z@IeF-nNyL^ADD(%iKEBm%#1rDRclZQPQB7n6m3(ldK9=S7a6cR~ZZZLI%0w3GbC8Y#mEl}X zxZTkh5U^VUN<^GAuZPD3DFD7@#~k?#RRbClS&5<44QdVN3Lu z)m8v%@Y7G*g<{%3G-b~qGar55TG_avOQrIt!~V*|SPs%$2INw=&f6QGtf&bc2dw{Pqlud=z^XX&-f%Np6bohCGy z-mG-UidBH1%;MK~?qJ=Q+qX9qalqp_U{x#`dF#Y%|YYwIMpJ^+kQ4V9DL$rxUN zO&USYq>;mo2tOYj3GSsbTrbH4Vu*{(7U$3uJ7ZQFNZcAGlf-&-s@w)wqXK|>|Ior!*ptVqNIB+O)H`BW`i4?UA^8&_)ENw@7? zyV|$%r%7i+adCIJ=zy5sQ4?Dy`W9UyJy@RZSS^;`NTTUH49nFqf)%AksMkYHN@zd= znPFI=>mCwGO(uk#^&U8%cE8aaNmNPY^mS!FEKy~t-GDSzQfXXn-NW2g@N643il9x- z>=cn>^=kCgs)Om$i&rhirhr4-R$GL>O?v}qk}JN}yt=n(FZWs1iGuPwP*k)^>FIKM zVZ9);)|Y*&-WKz&{dsDZF>f)u$+u0nYSi~u4s@3HF129Zq&-w3tx>gYnhoFQq!2|Tg|@Z4w|LPsEorY%?tW~Ih>9_Mgd>}aYWDNrE~uP#~P!Iv04p7FAgMl*9h+jqmiW?ap98=V?Vnd zi(;Dp0OD4l)610w1|w(c6D3wbAPO}cy($fK&~xWpbj^Sn}BoQWzchjXKmefC&b)r~?r^sFBG)j2DTmH7;DTBz^c;=9I0qOK7D{eo$&ToCb|t zSLTqhZCt?f#lF=0#lFV7l$`;+T%$=HrlaYV)jd>G#+|awh`+LjHvM5`z{-AAS z&1-jV07)%pkY%WfGM1sJ!lSKvjg$GDEP&9fWOJxKAdYxr5nt5cR%ms4MClrmK|BKr zW#fpP!eJokn38^an$Qp^0H^oh=o-TcX{B{nl`*bYdCY2}F)K6BcrK!71`}|z5OwX3 zQQ^3WX119C&N-ofOREAw2kgRkf71oq;k3Aequ-xO_bAd^eI$b;M+}7ZV3M^`p196j zFt9H&|5kq)5{*;f7z~f)2e{Tq{QvuvaL~%kTu0E ztQt$1tF7d7MDPkZ^T07PnX9X)Km*_g32#t5$;{w`op?5RVMxh^4SWs`tfXEbabboc z67F+K0B~1m?h1lnU#v?=@#UNav)Som?*pQ-%|E-1i%!B05}2 zIFnLbGUrKSY^V-IQ$M#Gto^ZMtL_Z%aJII=Z4qwN#UhCPN`jB2X_%-Zh77KUwYIIv zSKe+Lj#}UvT{EkDNu6QOy5{n!B16*aB`fnNZBzXa3chENKF!k&3!bJ(~3 z`?9s}9jeXm_f3Wsn(p!l5s^PKI8l{Yw2Gk_gH(Zz&)UA1TwLrs62~RZ^>c9yChG3& z>sajM>IX%RAQhxUH7wc-dNZ4C?hg37eWr8?akSYg?fY`YQ=&5r3Il5=Qx;-a&>k3M z_qK}maODNCEXtvMO;e;PU^w`B;?XUpb898U*H(yqA|oI~E;Fbsu^}ghSX)ikbzQd0 zd086R`)DuZx4XB{7|6286GW1%l?7aCApYsauW|Q%hi`Y+ZdA0rySm-Als9m_zfIA_ zy~9lomu{?OT#&$V0E}8~yDUG}JF*=Xwnzy>q%f(S=ml3IR;Gmb;qSYPr0lXAos+UH z*o!`}2Sjoi2okyUs?_N`E1otE#qJ$fvuzJ?X=i@Y8!LsfmNHJ$b|eQv36WA622tzv zQ%J_owB6r{q_Q(#+gz*yIiR+hD|sL^;LCQhBd&v_Q>R@~xEo)+x{}XqitZtOc@mb; zjN|un^$-RM|Rv?H(^V6XD;Dvmr`3s zqN*-p)+^H*8&yRsrkwG+Y+a{kceL#9Grwz1xk@K%xD?UAdIk&#B~`O4%;2-Q(ksB` zNXzfTIx;Z;A6{UJjJ!@Dl1bi4WCYx&OnzMrMH;72AlHEK#7Svw>Y9N%julBH4OQTv zpDe!2T#KU;wYxIOIyR{FA^a{zVxuiQaRQ~G7UTw&@@k=KgF>i$cvRdQmw?+o_GSz(j{;dL>{DN#g3X~<%JSk)_RdF%0DiH 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℘ZKQ(eXc{Sq_Q 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≦mSN{X(gMfo>%d4QDKO*A2H-E%s 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

    ok5o<)ju@s2Zdr?GAnT_Mssr#8FJU|0l$ z%%V!30RgA7I1%6nx&SEMR>V{cq|#33Vck>149CS#i@TR@1B4<`lvJojc%BdwvsE?;1D5(0wyw;tgX{8maG>{5KjQGWn{oG46$$+W)O!-uuAO&c2(=-RzVfB z0UQv@%g}^JPJ}Rp?bL!Pv=h?UtX0&H2~)<497b3mil(=us0X4H^y)@cZu9`0pdbiL zAPbFrf(3e|NOo4O`0TmXfu7MI>D0GLWtfEGAE0{Ri}GY6@l%-yfK12|Tqi8`mwG8Rx(usb#PeQ_?_h zVZ-|~>O6L=k3Z(6>-j7GcE6ba0D1#Y+V5#nCNNNjqGG-|vyzNN4eUDF7_ZQ46tL&j zSgM{Xn{2Qf3J^eRO&}}9H++S>m?a#a1xV1s#k1`a(!73W9*#QJ6`6>PKz>VeJ~xTX z`67Z2V_)ysB3n3|qNFmI2|lLFLX-rPhCP<@8gaPS^BK3xO*VSa{_88u9G_+tA_EM0 zQ7xsm*LKc7#;rU$xjc~>*b-0Twq;-~ubo#b*JeDawWd9;?0zTUzJHg;Mz-EjWPKyg z;_4Kw?@B=;YMS`{y2gZ)E^^{=>w7&0 zFus5m7+@@FB;kR8p2HUlYWiaxtZJ&{aN5YhXRomn%CD0N1&u|AqDn0CEc?FU$ZPf! zW94<;!B0d0YgBbdA*P7ZxQ4|H9Zz|gHQ1glR*N7lHHxyG1(LfRpdcivm{^KI_p^O^ zENo*>90nGES-o@%H`pw0n5-g_8CZgZW{Kqy)zDL47YutClEek6LpO@PJCKu1uC`ju z!EXD0_F&V}jPh8_XJ;h9qMfqUP?lJ4;&J(Wl?hs_3qa&E`d67Nt`;P-+-%(X{Oj9e zS3!2MD`Qn5Ypw!Csb?He6e9rvq`g+=>}6o~ROXmV zJK6+Q0v0S`V9-^sVyRe>n8k%~tEi=EHDPD8QoK>edf{T^mL!lv`|xE|GCgr=tB=+~ zJk8IoR$+|9vC>K2u_^xmGSfC@?&%%XFN0;LH^1_*l4+cpwdlK^L0 zH)F9RvoS>+VOO4%sW2IYp1lV3tjJgv5FZ{bF{3diQ(k%UQ^r>q9)vyVhSO?=j(paE zC5}lXxh90no4cwEv<}Q@OWGAH)r&&Vs|#6SI_ylTG`D#)Ie-{Wkz*nXiq}Y+yDhMj z33I$^$=^Bp1i)G-a8+S?!Z%z$WgqGZV#5_ji46 z?^M;`#)yGTAOSZ?=$2+H5oUFp`ONq}Kgh;`SZ;_1dkJFErx|~c8920AeWtb%Xk zLdA*V0s7BAch=8~rt6rKWy0Xwp~D8=+3a>TFzY67t^9m%8<+Ad#Jemh=8`xNa7{mLoY*_p4SYRvr}1d!DR^?)Ba2p#Td3mPM#RfWqr)+kxL?Kni|_ZccwI~F$tMDWGQgvDE`*J z1~jBpZ_b%HUK1fS(f7Oj{wR&Giv8@}=f^m$Jd#0JoD_b)L zZJ#cju#+%jN-RmX_AfEXA&;WgNIyecG{(1GNZ?JV^Jm!TlGwvdb`+yTqn-3C_#6|mP-Ut~e~M7ujAyKBSp$?%`c$CCAUCZEpXHTZwv_&yxeXTy?h zVw!*G_z6j_c}MRb^n40Q{{YB>zb?PC;dtq|aUlK0p+ZaNO+M)1#^~prv*ks{qLGuc z*^Vre!HkhO3E`2F!?L=f$iB$o_$1zCf<4XzcNDm><#utG$m4ahII{iJzk`p%;wpH1 z(CEc^*9~g~`BV9uq=~4e)*jD9(iEeSd`7)&aU(C^FUiG9n_qK?-e%8wAr3Ur8NnyHdDX2c^djr-e5N#QjKHF@N?88@ z1mx*s+3=F$ROaa`lX%;*_DhP=QLY?+Y&|b0#7$mn@QF7~y%HiZv65ZRY%#(~q8-yX zQpJ$+CNp95V7Qc)jAtxH-?Aw9zC1b7P~q>*EMSayuBFVoI;%KQY4H~OSp@|p_D9Su zmRT#(x?5WDBeP`I=#2ZJKAaTmOL|5g-+{^7DG!YZ@%Z=1-^(99-=mR7;o*!YD)HGJ z*}{x&elU?KJYf@k*(I=^+Af-OF5~;6_8Q#{J6L{4%k%bsyZw!;RM(!0U&)cCF6fGl z_ZxOm4~Y2GxRv^FirR4Zd3UJ}U@ja|XSAqOj74cnMym}O3IWY>-JDCuKUqh=r zegyvGUeOjfyF?`f;VGp1C$~kWw7iKc8+WA=rmqiiyd-{{GX1j0qFEbOWNqtO;JBig znzS@0q?XN(M3NI$ie)T~y(qGLNvOqJY<~|Zrzp1ft(T(cZRwpVEqghbqS0-bF|G_2 zhZpEf&7p~tUCEEY*48$*8+qt&2kEuvxZINOyV8WrnG7*to46T{Ai% zYPxNW%}MOPv0a}s`*m9=v8fcP>}1{PgMYDxi%0&3ojn&)(Xq=fVMV02EsCqTT{WXj zQduxI@+#8?SOU`Incm3fN>Y5W^WB^n$u1jiw`0|qDoqxX{EKE#p6G)jF9I24d?JSQQ5>|f zviD?STBJ%$OL5gBjl@bWPLiX9?o(@)J-mufmI)}Y1-&p}r)zOl969%6`CD?@#z4TOv!|ot9a|mRkItS;Jn= z6j$wCXhK7K4erRIQ+Dwm>`f)LY)w4p*zBCUen`dJ%heQEwL@OO$b6{zideLJaMVS?ge*JQseR4#x2h{*D|h@2 z`bIU)enjNIBGE=RHtqEDO8g9cD5k!GL)m4Ll)SMjZkz02@JZ$1f_b(jve6_tO8S&y zm(XJqMQM#vIkVgQ5WJnLTsaBu-8*My# z64?ktZEE`Mp++e#!{|d_K}(G;B$gtnec2!RJW7pQU*k$MdOxXrMeFNJkH(J!(2G!rMGtcvRp~IOLktXOqJEd<#v^!)%MXFzP2%WBDz09E^@GeOt#yKkziZv--IDi>20{bfLec zlOItbzLd59!~h@>00II70RaI40RaF2000000RjL61Q8Mt1rs0!6#v=)2mu2D0RjLL zn;{TG8I^%%e1@_$w;CDLu!{j@C#0|kuEd(H#meeY_F^w2>Y&DUTc<>HW&O;e(>KKAx35#_;wEgfu` zITig3f2Ccdh)S1IH%*Gb^8LCaQ8VzU4WKVIi8e0oBWrCoLX|Tay?QTEXL? zU!zs2u|E@v*w2P>lRlrXUP!Z`K@*&eVQF&(iF|RY0D^C(UOt@`;ag34xc>lBwrWm0 zV%vyu6)WI#x?#-EF1W zfC3LI#;XhJWn*BAEsgT)`NFTrp%tgr`8DKMb#|;|;M3;Nv@<|>mD7({$<0i4jXFWX z(hw=9^30~+kbZK+b+|X8EU;>7R)~PzpLR}L;?m}t(dsiI3H{<^RGO1a~ z^I<^gLV%zaIeMyxV|6r|?#RZW~B%lzx2%g|Wt z_gZ5BXtu1T$u7>Y#%Z7{r6_hWo&bm!_G@aX%iffQu7?XwMl&69BC;CmzOj)2Rjz{C zW-R~;BBubHj%uad3bla~PF1>Bsm@E}3;F?R{Z2`}Y$PZ^0tE_J@)drIGA>J~xQ5Kh z&W3D2dYYf1ZvX%V9IOB)p_X2AA1Z5m*Cj{_KmxH_0Gih!RX_m{BCm}0Wj0F?3?68q z5Qv~EfC*G=k5mAmRYS4LHud8xtYP2-&I<4XEsCrWp&fLB2%%I9?(4qAzo$5cktzj?)Pyj_yEwXD zmdg#n-s3gur~m+p23>$_t<6nq(-1L23k9yy>*??a0)WMzBu37Yf`z&44C^U5lP z0p__&67b})W_sHW2o0HI-NEP(n$s5?D*~z+tFd7k0T{7ooBbOhvO3uQH2?serFe7! z<#QtKBx3=Hwl`&+x9A>gz`G_bbk|yV@ti=Ql3y#pC?50Tr5Nd50vJIeDDVd$h^PjdZJVAy|HJ?>5dZ=L00jdA1_A;C0|5X4 z000335d#n*F+mbhVFVx|GI4>Cp)j!%!9vj#QeyG{+5iXv0|5g+0O@wW0+RMDt2CCZ zYhrSHkz2AHBdRA}5`6Md?!BDk#&sdnI$wz<0|$zKLbTg!@jFGy8In}8rb-9qvQK~8EEASYM;&h z9x=BS`bziaeKgBf`tv}Id zXjJTKG?_dU;?|FY8w!0;la9M^LRB19();ixtu)i;J6X80(M+*DQ8ZC#Q-v~7#Eu>& zlV7!+v*ORDH_J35c98_{rG5^rw;s&76p26hn2%^P5r4&=rv>~DOUDCLv7poLzv#ln zjlxO&1R)E7#pcD?7L5h5hbhIis*-5xg+0-!p{`dXYO}ntB?TNk?^ZZc#H9Q1%r52= z!gfMlA8hqEX1>JAdXbt|wAh1gF4N(o9|hgEyO^-rUy>5})p_8A)ux&g6X0Es z1GCgaSmI0bYxa7~E#nz4r85Qm(3D@~^!T4HByYCQ_I5NS;KRjLEHunEz6Urz%Ke_U zQEoVql3mkZ_Il+7E{MML{{ZffTHP!Oy6ms|Jx`};PYz4NOmlM-3Y&OR-ku_U_h>X55plVXG=)v@W{#~IRlq+zd@sr~4|oHbgm; zimFJ&z@JoY#q<9FVzM&iUCR^TPl7UwRj+dqI@currEE8ci59rB-3)Ik_DWmmg`-h0 zuzftRqf*71s#>+>juY#gwR|u3VJ#LKe_c!o$Kt|^`xp|Hq|)VXdRXm*zq9`UpWaWf z$l@m%D@3p{oTBM)$zimlpVbzYxhIloi`lFC8k+kx9G-$&{>(V)-rOFd7*~f4Td1VJ zZN3EyZQS3@F75U(qUlhQEs}gPdp!v9*%iQ_1Rn=ZsE$4xi{FFPM?}*{sl$C;EqyjI zqg_#N${G_|i&1+uH8ss0Qt&18B;6y@U`wV=&lCRuNUL|`l<<|ur^VTeIJJiAiS@Y3 z`=1FXth7W@q>c-*XWU8Tp9iMI-U%@^cys$R7YbE4xczn-_UdWua{3A?klQ1JCxe4s zX?#-c;dwgTv8S%CufHtd#hlWIeMm)oTC)vokr%zE!yD1>{ggeuy-~iyTMGLztFC$9T$4v;HpG!^mItG53I70+O-3}W z+w6MGX0azVhrW$lcieuG3k!&?Jd&KWBL$$@Cl>fadNNVilhk8lPd#h6x|%!wNiQgi z@W~?&)Zp~XMxDj-n&lp=2O3y-xOh^WUb1y>v-VTVMu%k@olK3ZR`?QECrKaY#`sp7 zFR-G&+19NxP#ax5J;*{yUAC7#i zdzOuJwsg@9D7nqjO3(bYE||(OTVCwxPrDK{`Y}!xhZnfy;VpKfqBNGHl6FNUeCSg( zDdnlDQWTezG-*s!HOU9T5qBcpw3{nC$tPpPlkLG#a{D7u4ldB8zVAj@O3FiLOBAE@6K$>e zEf+}|oE2YFRQwdg{{YyUwU)ly7}$~$Z7ur_Nw>JuCDnXCWo2R%mcxUzKBiKnJ09i8 z(H(e6m#-s4zUA(SfAy4kBi#`7`ZmZaUf zdT_Tfr1nr=cNBEpog1{@Zp7rSO0Qv9gheVfE-94Ue&}!FiF^`UGZ7NLN8crr?pYO+ zWhyl^65W;ZugN*PZpV6%!&~Y(I!39p0}Z()a`H5m?Y)Vwj}v|uVIgof%|$5F*mrbd z!;YjzTBN_(Tr_zeUA?YbA~EvH65Q-b@-{Xo#@}l#)DsiB2(!R_v$!dH~ zw$D*5$R)Lsdp4JAvl9MhLF;wnCsy=E92GCo*%*(SF(3Sye#es-*$C>{74oAJTadz3 zwU_itGH-j`K1?Y^DCywR+g04b!(TFgO-bS=mXZGRWsMKn*-+l^J7p@#WRZCz!05qG zSARkaXnsstb4#+*CzY(@+>e~7v5eqtXfd8dC7y<;Ldq#>(AUcw@?uMRHOoxm##T>0 zqozWkEf(d9E|(tr$}v{Q!X)`)@0w*A8Z7OUgv5Buv093}kEhA9<%uUlZuQN-a+JI+ zvSY~&j?3J{{W3fExnNECf_9?yxRT^4wx?`qf=XCt4$Yn zCGxF%vs-(yJr^IxRTcNivGyNt;!%%N;8KJd*~Di&cOsH&UnHfwvG7RKHSbAV;Bu31 zkq;&^FTq~-93=?9icj>1FHZ#JdT7UA*(awRhT`JJ_tWeqsYQ~6ntXd-y0D*}3isc- zI9O7gwqLW-zWM^(tP4DO6MYL!0* zBzDyjj_I#v6s=VzsE_$$B`u#ligT8lqH%{h-{ex?h5Sf)N-*h%&n>(o5|r^JNmEfp zES#E1=}MZ@LlQiZlBvZr0(z#m2OH>lz6}4yxg9O z$i`iA)^GLn5<;Xl(nMpWiNUOzB@*`*Oph@}9JV6f$^Em8cWDcysQycT#^m%AQgl&u z^)?hD str: + """ Find an available model with specified model name and sd_version. """ + if model_name.lower() == "none": + return "None" + + r = requests.get(BASE_URL+"/controlnet/model_list") + result = r.json() + if "model_list" not in result: + raise ValueError("No model available") + + candidates = [ + model + for model in result["model_list"] + if ( + model_name.lower() in model.lower() and + StableDiffusionVersion.detect_from_model_name(model) == sd_version + ) + ] + + if not candidates: + raise ValueError("No suitable model available") + + return candidates[0] + + +def get_modules(): + return requests.get(f"{BASE_URL}/controlnet/module_list").json() + + +def detect(json): + return requests.post(BASE_URL+"/controlnet/detect", json=json) diff --git a/extensions-builtin/sd_forge_controlnet/tests/web_api/__init__.py b/extensions-builtin/sd_forge_controlnet/tests/web_api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/extensions-builtin/sd_forge_controlnet/tests/web_api/animal_pose.json b/extensions-builtin/sd_forge_controlnet/tests/web_api/animal_pose.json new file mode 100644 index 00000000..4b0be5a3 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/web_api/animal_pose.json @@ -0,0 +1,60 @@ +{ + "version": "ap10k", + "animals": [ + [ + 450.2489471435547, + 131.68504521623254, + 1.0, + 392.43172235786915, + 129.75780439004302, + 1.0, + 422.3039551638067, + 170.2298617400229, + 1.0, + 424.2311959899962, + 254.06483767926693, + 1.0, + 460.84877168759704, + 416.9166874922812, + 0.7048550844192505, + 498.42996779829264, + 295.50051544234157, + 0.742408812046051, + 513.8478944078088, + 374.5173893161118, + 0.763853132724762, + 512.884273994714, + 438.1163365803659, + 1.0, + 372.1956936828792, + 301.2822379209101, + 0.7799525856971741, + 384.7227590531111, + 381.2627322077751, + 0.8117924928665161, + 381.8318978138268, + 442.9344386458397, + 1.0, + 553.3563313446939, + 327.2999890744686, + 0.7031180262565613, + 555.2835721708834, + 375.48100972920656, + 0.6529693603515625, + 562.0289150625467, + 420.77116914466023, + 0.8226040601730347, + 409.7768897935748, + 359.09946270659566, + 0.3695080578327179, + 436.75826136022806, + 414.0258262529969, + 0.6621587872505188, + 428.08567764237523, + 422.69840997084975, + 0.552909255027771 + ] + ], + "canvas_height": 512, + "canvas_width": 960 +} \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/tests/web_api/control_types_test.py b/extensions-builtin/sd_forge_controlnet/tests/web_api/control_types_test.py new file mode 100644 index 00000000..8abc5a73 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/web_api/control_types_test.py @@ -0,0 +1,24 @@ +import unittest +import importlib +import requests + +utils = importlib.import_module( + 'extensions.sd-webui-controlnet.tests.utils', 'utils') + + +from scripts.processor import preprocessor_filters + + +class TestControlTypes(unittest.TestCase): + def test_fetching_control_types(self): + response = requests.get(utils.BASE_URL + "/controlnet/control_types") + self.assertEqual(response.status_code, 200) + result = response.json() + self.assertIn('control_types', result) + + for control_type in preprocessor_filters: + self.assertIn(control_type, result['control_types']) + + +if __name__ == "__main__": + unittest.main() diff --git a/extensions-builtin/sd_forge_controlnet/tests/web_api/detect_test.py b/extensions-builtin/sd_forge_controlnet/tests/web_api/detect_test.py new file mode 100644 index 00000000..f10c41ea --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/web_api/detect_test.py @@ -0,0 +1,47 @@ +import requests +import unittest +import importlib +utils = importlib.import_module( + 'extensions.sd-webui-controlnet.tests.utils', 'utils') + + +class TestDetectEndpointWorking(unittest.TestCase): + def setUp(self): + self.base_detect_args = { + "controlnet_module": "canny", + "controlnet_input_images": [utils.readImage("test/test_files/img2img_basic.png")], + "controlnet_processor_res": 512, + "controlnet_threshold_a": 0, + "controlnet_threshold_b": 0, + } + + def test_detect_with_invalid_module_performed(self): + detect_args = self.base_detect_args.copy() + detect_args.update({ + "controlnet_module": "INVALID", + }) + self.assertEqual(utils.detect(detect_args).status_code, 422) + + def test_detect_with_no_input_images_performed(self): + detect_args = self.base_detect_args.copy() + detect_args.update({ + "controlnet_input_images": [], + }) + self.assertEqual(utils.detect(detect_args).status_code, 422) + + def test_detect_with_valid_args_performed(self): + detect_args = self.base_detect_args + response = utils.detect(detect_args) + + self.assertEqual(response.status_code, 200) + + def test_detect_invert(self): + detect_args = self.base_detect_args.copy() + detect_args["controlnet_module"] = "invert" + response = utils.detect(detect_args) + self.assertEqual(response.status_code, 200) + self.assertNotEqual(response.json()['images'], [""]) + + +if __name__ == "__main__": + unittest.main() diff --git a/extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/README.md b/extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/README.md new file mode 100644 index 00000000..28a47de6 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/README.md @@ -0,0 +1,3 @@ +# Full Coverage Tests +Tests that only run locally with all models available. Set environment variable +`CONTROLNET_TEST_FULL_COVERAGE` to any value to enable these tests. \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/__init__.py b/extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/depth_test.py b/extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/depth_test.py new file mode 100644 index 00000000..d2802d44 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/depth_test.py @@ -0,0 +1,66 @@ +import unittest +import pytest +from typing import NamedTuple, Optional + +from .template import ( + sd_version, + StableDiffusionVersion, + is_full_coverage, + APITestTemplate, + living_room_img, + general_negative_prompt, +) + +base_prompt = "A modern living room" + +general_depth_modules = [ + "depth", + "depth_leres", + "depth_leres++", + "depth_anything", +] +hand_refiner_module = "depth_hand_refiner" + +general_depth_models = [ + "control_sd15_depth_anything [48a4bc3a]", + "control_v11f1p_sd15_depth [cfd03158]", + "t2iadapter_depth_sd15v2 [3489cd37]", +] +hand_refiner_model = "control_sd15_inpaint_depth_hand_fp16 [09456e54]" + + +class TestDepthFullCoverage(unittest.TestCase): + def setUp(self): + if not is_full_coverage: + pytest.skip() + # TODO test SDXL. + if sd_version == StableDiffusionVersion.SDXL: + pytest.skip() + + def test_depth(self): + for module in general_depth_modules: + for model in general_depth_models: + name = f"depth_txt2img_{module}_{model}" + with self.subTest(name=name): + self.assertTrue( + APITestTemplate( + name, + "txt2img", + payload_overrides={ + "prompt": base_prompt, + "negative_prompt": general_negative_prompt, + "steps": 20, + "width": 768, + "height": 512, + }, + unit_overrides={ + "module": module, + "model": model, + "image": living_room_img, + }, + ).exec(result_only=False) + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/inpaint_test.py b/extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/inpaint_test.py new file mode 100644 index 00000000..1a37fe91 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/inpaint_test.py @@ -0,0 +1,219 @@ +import unittest +import pytest +from .template import ( + is_full_coverage, + APITestTemplate, + girl_img, + mask_img, + mask_small_img, +) + + +class TestInpaintFullCoverage(unittest.TestCase): + def setUp(self): + if not is_full_coverage: + pytest.skip() + + def test_inpaint(self): + for gen_type in ("img2img", "txt2img"): + if gen_type == "img2img": + payload = { + "init_images": [girl_img], + "mask": mask_img, + } + unit = {} + else: + payload = {} + unit = { + "image": { + "image": girl_img, + "mask": mask_img, + } + } + + unit["model"] = "control_v11p_sd15_inpaint [ebff9138]" + + for i_resize, resize_mode in enumerate( + ("Just Resize", "Crop and Resize", "Resize and Fill") + ): + # Gen 512x768(input image size) for resize. + if resize_mode == "Crop and Resize": + payload["height"] = 768 + payload["width"] = 512 + + # Gen 512x512 for inner fit. + if resize_mode == "Crop and Resize": + payload["height"] = 512 + payload["width"] = 512 + + # Gen 768x768 for outer fit. + if resize_mode == "Resize and Fill": + payload["height"] = 768 + payload["width"] = 768 + + if gen_type == "img2img": + payload["resize_mode"] = i_resize + else: + unit["resize_mode"] = resize_mode + + for module in ("inpaint_only", "inpaint", "inpaint_only+lama"): + unit["module"] = module + + with self.subTest( + gen_type=gen_type, + resize_mode=resize_mode, + module=module, + ): + self.assertTrue( + APITestTemplate( + f"{gen_type}_{resize_mode}_{module}", + gen_type, + payload_overrides=payload, + unit_overrides=unit, + ).exec() + ) + + def test_inpaint_no_mask(self): + """Inpaint should fail if no mask is provided. Output should not contain + ControlNet detected map.""" + for gen_type in ("img2img", "txt2img"): + if gen_type == "img2img": + payload = { + "init_images": [girl_img], + } + unit = {} + else: + payload = {} + unit = { + "image": { + "image": girl_img, + } + } + unit["model"] = "control_v11p_sd15_inpaint [ebff9138]" + unit["module"] = "inpaint_only" + with self.subTest(gen_type=gen_type): + self.assertTrue( + APITestTemplate( + f"{gen_type}_no_mask_fail", + gen_type, + payload_overrides=payload, + unit_overrides=unit, + ).exec() + ) + + def test_inpaint_double_mask(self): + """When mask is provided for both a1111 img2img input and ControlNet + unit input, ControlNet input mask should be used.""" + self.assertTrue( + APITestTemplate( + f"img2img_double_mask", + "img2img", + payload_overrides={ + "init_images": [girl_img], + "mask": mask_img, + }, + unit_overrides={ + "image": { + "image": girl_img, + "mask": mask_small_img, + }, + "model": "control_v11p_sd15_inpaint [ebff9138]", + "module": "inpaint", + }, + ).exec() + ) + + def test_img2img_mask_on_unit(self): + """ Usecase for inpaint_global_harmonious. """ + self.assertTrue( + APITestTemplate( + f"img2img_mask_on_unit", + "img2img", + payload_overrides={ + "init_images": [girl_img], + }, + unit_overrides={ + "image": { + "image": girl_img, + "mask": mask_small_img, + }, + "model": "control_v11p_sd15_inpaint [ebff9138]", + "module": "inpaint", + }, + ).exec() + ) + + def test_outpaint_without_mask(self): + self.assertTrue( + APITestTemplate( + f"img2img_outpaint_without_mask", + "img2img", + payload_overrides={ + "init_images": [girl_img], + "width": 768, + "height": 768, + "resize_mode": 2, + }, + unit_overrides={ + "model": "control_v11p_sd15_inpaint [ebff9138]", + "module": "inpaint_only+lama", + }, + ).exec() + ) + + self.assertTrue( + APITestTemplate( + f"txt2img_outpaint_without_mask", + "txt2img", + payload_overrides={ + "width": 768, + "height": 768, + }, + unit_overrides={ + "model": "control_v11p_sd15_inpaint [ebff9138]", + "module": "inpaint_only+lama", + "image": { + "image": girl_img, + }, + "resize_mode": 2, + }, + ).exec() + ) + + def test_inpaint_crop(self): + self.assertTrue( + APITestTemplate( + "img2img_inpaint_crop", + "img2img", + payload_overrides={ + "init_images": [girl_img], + "inpaint_full_res": True, + "mask": mask_small_img, + }, + unit_overrides={ + "model": "control_v11p_sd15_canny [d14c016b]", + "module": "canny", + "inpaint_crop_input_image": True, + }, + ).exec() + ) + self.assertTrue( + APITestTemplate( + "img2img_inpaint_no_crop", + "img2img", + payload_overrides={ + "init_images": [girl_img], + "inpaint_full_res": True, + "mask": mask_small_img, + }, + unit_overrides={ + "model": "control_v11p_sd15_canny [d14c016b]", + "module": "canny", + "inpaint_crop_input_image": False, + }, + ).exec() + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/ipadapter_test.py b/extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/ipadapter_test.py new file mode 100644 index 00000000..94d7417d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/ipadapter_test.py @@ -0,0 +1,169 @@ +import unittest +import pytest +from typing import NamedTuple, Optional + +from .template import ( + sd_version, + StableDiffusionVersion, + is_full_coverage, + APITestTemplate, + portrait_imgs, + realistic_girl_face_img, + general_negative_prompt, +) + + +class AdapterSetting(NamedTuple): + module: str + model: str + lora: Optional[str] = None + + @property + def lora_prompt(self) -> str: + return f"" if self.lora else "" + + +# Used to fix pose for better comparison between different settings. +openpose_unit = { + "module": "openpose", + "model": ( + "control_v11p_sd15_openpose [cab727d4]" + if sd_version != StableDiffusionVersion.SDXL + else "kohya_controllllite_xl_openpose_anime [7e5349e5]" + ), + "image": realistic_girl_face_img, + "weight": 0.8, +} +base_prompt = "1girl, simple background, (white_background: 1.2), portrait" +negative_prompts = { + "with_neg": general_negative_prompt, + "no_neg": "", +} + +sd15_face_id = AdapterSetting( + "ip-adapter_face_id", + "ip-adapter-faceid_sd15 [0a1757e9]", + "ip-adapter-faceid_sd15_lora", +) +sd15_face_id_plus = AdapterSetting( + "ip-adapter_face_id_plus", + "ip-adapter-faceid-plus_sd15 [d86a490f]", + "ip-adapter-faceid-plus_sd15_lora", +) +sd15_face_id_plus_v2 = AdapterSetting( + "ip-adapter_face_id_plus", + "ip-adapter-faceid-plusv2_sd15 [6e14fc1a]", + "ip-adapter-faceid-plusv2_sd15_lora", +) +sd15_face_id_portrait = AdapterSetting( + "ip-adapter_face_id", + "ip-adapter-faceid-portrait_sd15 [b2609049]", +) +sdxl_face_id = AdapterSetting( + "ip-adapter_face_id", + "ip-adapter-faceid_sdxl [59ee31a3]", + "ip-adapter-faceid_sdxl_lora", +) + + +class TestIPAdapterFullCoverage(unittest.TestCase): + def setUp(self): + if not is_full_coverage: + pytest.skip() + + if sd_version == StableDiffusionVersion.SDXL: + self.settings = [sdxl_face_id] + else: + self.settings = [ + sd15_face_id, + sd15_face_id_plus, + sd15_face_id_plus_v2, + sd15_face_id_portrait, + ] + + def test_face_id(self): + for s in self.settings: + for n, negative_prompt in negative_prompts.items(): + name = f"{s}_{n}" + with self.subTest(name=name): + self.assertTrue( + APITestTemplate( + name, + "txt2img", + payload_overrides={ + "prompt": f"{base_prompt},{s.lora_prompt}", + "negative_prompt": negative_prompt, + "steps": 20, + "width": 512, + "height": 512, + }, + unit_overrides=[ + { + "module": s.module, + "model": s.model, + "image": realistic_girl_face_img, + }, + openpose_unit, + ], + ).exec() + ) + + def test_face_id_multi_inputs(self): + for s in self.settings: + for n, negative_prompt in negative_prompts.items(): + name = f"multi_inputs_{s}_{n}" + with self.subTest(name=name): + self.assertTrue( + APITestTemplate( + name=name, + gen_type="txt2img", + payload_overrides={ + "prompt": f"{base_prompt}, {s.lora_prompt}", + "negative_prompt": negative_prompt, + "steps": 20, + "width": 512, + "height": 512, + }, + unit_overrides=[openpose_unit] + + [ + { + "image": img, + "module": s.module, + "model": s.model, + "weight": 1 / len(portrait_imgs), + } + for img in portrait_imgs + ], + ).exec() + ) + + def test_face_id_real_multi_inputs(self): + for s in (sd15_face_id, sd15_face_id_portrait): + for n, negative_prompt in negative_prompts.items(): + name = f"real_multi_{s}_{n}" + with self.subTest(name=name): + self.assertTrue( + APITestTemplate( + name=name, + gen_type="txt2img", + payload_overrides={ + "prompt": f"{base_prompt}, {s.lora_prompt}", + "negative_prompt": negative_prompt, + "steps": 20, + "width": 512, + "height": 512, + }, + unit_overrides=[ + openpose_unit, + { + "image": [{"image": img} for img in portrait_imgs], + "module": s.module, + "model": s.model, + }, + ], + ).exec() + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/template.py b/extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/template.py new file mode 100644 index 00000000..4d744568 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/web_api/full_coverage/template.py @@ -0,0 +1,265 @@ +import io +import os +import cv2 +import base64 +from typing import Dict, Any, List, Union, Literal +from pathlib import Path +import datetime +from enum import Enum +import numpy as np + +import requests +from PIL import Image + + +PayloadOverrideType = Dict[str, Any] + +timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") +test_result_dir = Path(__file__).parent / "results" / f"test_result_{timestamp}" +test_expectation_dir = Path(__file__).parent / "expectations" +os.makedirs(test_expectation_dir, exist_ok=True) +resource_dir = Path(__file__).parents[2] / "images" + + +def read_image(img_path: Path) -> str: + img = cv2.imread(str(img_path)) + _, bytes = cv2.imencode(".png", img) + encoded_image = base64.b64encode(bytes).decode("utf-8") + return encoded_image + + +def read_image_dir(img_dir: Path, suffixes=('.png', '.jpg', '.jpeg', '.webp')) -> List[str]: + """Try read all images in given img_dir.""" + img_dir = str(img_dir) + images = [] + for filename in os.listdir(img_dir): + if filename.endswith(suffixes): + img_path = os.path.join(img_dir, filename) + try: + images.append(read_image(img_path)) + except IOError: + print(f"Error opening {img_path}") + return images + + +girl_img = read_image(resource_dir / "1girl.png") +mask_img = read_image(resource_dir / "mask.png") +mask_small_img = read_image(resource_dir / "mask_small.png") +portrait_imgs = read_image_dir(resource_dir / "portrait") +realistic_girl_face_img = portrait_imgs[0] +living_room_img = read_image(resource_dir / "living_room.webp") + +general_negative_prompt = """ +(worst quality:2), (low quality:2), (normal quality:2), lowres, normal quality, +((monochrome)), ((grayscale)), skin spots, acnes, skin blemishes, age spot, +backlight,(ugly:1.331), (duplicate:1.331), (morbid:1.21), (mutilated:1.21), +(tranny:1.331), mutated hands, (poorly drawn hands:1.331), blurry, (bad anatomy:1.21), +(bad proportions:1.331), extra limbs, (missing arms:1.331), (extra legs:1.331), +(fused fingers:1.61051), (too many fingers:1.61051), (unclear eyes:1.331), bad hands, +missing fingers, extra digit, bad body, easynegative, nsfw""" + +class StableDiffusionVersion(Enum): + """The version family of stable diffusion model.""" + + UNKNOWN = 0 + SD1x = 1 + SD2x = 2 + SDXL = 3 + + +sd_version = StableDiffusionVersion( + int(os.environ.get("CONTROLNET_TEST_SD_VERSION", StableDiffusionVersion.SD1x.value)) +) + +is_full_coverage = os.environ.get("CONTROLNET_TEST_FULL_COVERAGE", None) is not None + + +class APITestTemplate: + is_set_expectation_run = os.environ.get("CONTROLNET_SET_EXP", "True") == "True" + + def __init__( + self, + name: str, + gen_type: Union[Literal["img2img"], Literal["txt2img"]], + payload_overrides: PayloadOverrideType, + unit_overrides: Union[PayloadOverrideType, List[PayloadOverrideType]], + ): + self.name = name + self.url = "http://localhost:7860/sdapi/v1/" + gen_type + self.payload = { + **(txt2img_payload if gen_type == "txt2img" else img2img_payload), + **payload_overrides, + } + unit_overrides = ( + unit_overrides + if isinstance(unit_overrides, (list, tuple)) + else [unit_overrides] + ) + self.payload["alwayson_scripts"]["ControlNet"]["args"] = [ + { + **default_unit, + **unit_override, + } + for unit_override in unit_overrides + ] + + def exec(self, result_only: bool = True) -> bool: + if not APITestTemplate.is_set_expectation_run: + os.makedirs(test_result_dir, exist_ok=True) + + failed = False + + response = requests.post(url=self.url, json=self.payload).json() + if "images" not in response: + print(response) + return False + + dest_dir = ( + test_expectation_dir + if APITestTemplate.is_set_expectation_run + else test_result_dir + ) + results = response["images"][:1] if result_only else response["images"] + for i, base64image in enumerate(results): + img_file_name = f"{self.name}_{i}.png" + Image.open(io.BytesIO(base64.b64decode(base64image.split(",", 1)[0]))).save( + dest_dir / img_file_name + ) + + if not APITestTemplate.is_set_expectation_run: + try: + img1 = cv2.imread(os.path.join(test_expectation_dir, img_file_name)) + img2 = cv2.imread(os.path.join(test_result_dir, img_file_name)) + except Exception as e: + print(f"Get exception reading imgs: {e}") + failed = True + continue + + if img1 is None: + print(f"Warn: No expectation file found {img_file_name}.") + continue + + if not expect_same_image( + img1, + img2, + diff_img_path=str(test_result_dir + / img_file_name.replace(".png", "_diff.png")), + ): + failed = True + return not failed + + +def expect_same_image(img1, img2, diff_img_path: str) -> bool: + # Calculate the difference between the two images + diff = cv2.absdiff(img1, img2) + + # Set a threshold to highlight the different pixels + threshold = 30 + diff_highlighted = np.where(diff > threshold, 255, 0).astype(np.uint8) + + # Assert that the two images are similar within a tolerance + similar = np.allclose(img1, img2, rtol=0.5, atol=1) + if not similar: + # Save the diff_highlighted image to inspect the differences + cv2.imwrite(diff_img_path, diff_highlighted) + + return similar + + +default_unit = { + "control_mode": 0, + "enabled": True, + "guidance_end": 1, + "guidance_start": 0, + "low_vram": False, + "pixel_perfect": True, + "processor_res": 512, + "resize_mode": 1, + "threshold_a": 64, + "threshold_b": 64, + "weight": 1, +} + +img2img_payload = { + "batch_size": 1, + "cfg_scale": 7, + "height": 768, + "width": 512, + "n_iter": 1, + "steps": 10, + "sampler_name": "Euler a", + "prompt": "(masterpiece: 1.3), (highres: 1.3), best quality,", + "negative_prompt": "", + "seed": 42, + "seed_enable_extras": False, + "seed_resize_from_h": 0, + "seed_resize_from_w": 0, + "subseed": -1, + "subseed_strength": 0, + "override_settings": {}, + "override_settings_restore_afterwards": False, + "do_not_save_grid": False, + "do_not_save_samples": False, + "s_churn": 0, + "s_min_uncond": 0, + "s_noise": 1, + "s_tmax": None, + "s_tmin": 0, + "script_args": [], + "script_name": None, + "styles": [], + "alwayson_scripts": {"ControlNet": {"args": [default_unit]}}, + "denoising_strength": 0.75, + "initial_noise_multiplier": 1, + "inpaint_full_res": 0, + "inpaint_full_res_padding": 32, + "inpainting_fill": 1, + "inpainting_mask_invert": 0, + "mask_blur_x": 4, + "mask_blur_y": 4, + "mask_blur": 4, + "resize_mode": 0, +} + +txt2img_payload = { + "alwayson_scripts": {"ControlNet": {"args": [default_unit]}}, + "batch_size": 1, + "cfg_scale": 7, + "comments": {}, + "disable_extra_networks": False, + "do_not_save_grid": False, + "do_not_save_samples": False, + "enable_hr": False, + "height": 768, + "hr_negative_prompt": "", + "hr_prompt": "", + "hr_resize_x": 0, + "hr_resize_y": 0, + "hr_scale": 2, + "hr_second_pass_steps": 0, + "hr_upscaler": "Latent", + "n_iter": 1, + "negative_prompt": "", + "override_settings": {}, + "override_settings_restore_afterwards": True, + "prompt": "(masterpiece: 1.3), (highres: 1.3), best quality,", + "restore_faces": False, + "s_churn": 0.0, + "s_min_uncond": 0, + "s_noise": 1.0, + "s_tmax": None, + "s_tmin": 0.0, + "sampler_name": "Euler a", + "script_args": [], + "script_name": None, + "seed": 42, + "seed_enable_extras": True, + "seed_resize_from_h": -1, + "seed_resize_from_w": -1, + "steps": 10, + "styles": [], + "subseed": -1, + "subseed_strength": 0, + "tiling": False, + "width": 512, +} diff --git a/extensions-builtin/sd_forge_controlnet/tests/web_api/img2img_test.py b/extensions-builtin/sd_forge_controlnet/tests/web_api/img2img_test.py new file mode 100644 index 00000000..bacf015b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/web_api/img2img_test.py @@ -0,0 +1,99 @@ +import os +import unittest +import importlib +utils = importlib.import_module('extensions.sd-webui-controlnet.tests.utils', 'utils') +import requests +from scripts.enums import StableDiffusionVersion + + +class TestImg2ImgWorkingBase(unittest.TestCase): + def setUp(self): + sd_version = StableDiffusionVersion(int( + os.environ.get("CONTROLNET_TEST_SD_VERSION", StableDiffusionVersion.SD1x.value))) + self.model = utils.get_model("canny", sd_version) + + controlnet_unit = { + "module": "none", + "model": self.model, + "weight": 1.0, + "input_image": utils.readImage("test/test_files/img2img_basic.png"), + "mask": utils.readImage("test/test_files/img2img_basic.png"), + "resize_mode": 1, + "lowvram": False, + "processor_res": 64, + "threshold_a": 64, + "threshold_b": 64, + "guidance_start": 0.0, + "guidance_end": 1.0, + "control_mode": 0, + } + setup_args = {"alwayson_scripts":{"ControlNet":{"args": ([controlnet_unit] * getattr(self, 'units_count', 1))}}} + self.setup_route(setup_args) + + def setup_route(self, setup_args): + self.url_img2img = "http://localhost:7860/sdapi/v1/img2img" + self.simple_img2img = { + "init_images": [utils.readImage("test/test_files/img2img_basic.png")], + "resize_mode": 0, + "denoising_strength": 0.75, + "image_cfg_scale": 0, + "mask_blur": 4, + "inpainting_fill": 0, + "inpaint_full_res": True, + "inpaint_full_res_padding": 0, + "inpainting_mask_invert": 0, + "initial_noise_multiplier": 0, + "prompt": "example prompt", + "styles": [], + "seed": -1, + "subseed": -1, + "subseed_strength": 0, + "seed_resize_from_h": -1, + "seed_resize_from_w": -1, + "sampler_name": "Euler a", + "batch_size": 1, + "n_iter": 1, + "steps": 3, + "cfg_scale": 7, + "width": 64, + "height": 64, + "restore_faces": False, + "tiling": False, + "do_not_save_samples": False, + "do_not_save_grid": False, + "negative_prompt": "", + "eta": 0, + "s_churn": 0, + "s_tmax": 0, + "s_tmin": 0, + "s_noise": 1, + "override_settings": {}, + "override_settings_restore_afterwards": True, + "sampler_index": "Euler a", + "include_init_images": False, + "send_images": True, + "save_images": False, + "alwayson_scripts": {} + } + self.simple_img2img.update(setup_args) + + def assert_status_ok(self): + self.assertEqual(requests.post(self.url_img2img, json=self.simple_img2img).status_code, 200) + + def test_img2img_simple_performed(self): + self.assert_status_ok() + + def test_img2img_alwayson_scripts_default_units(self): + self.units_count = 0 + self.setUp() + self.assert_status_ok() + + def test_img2img_default_params(self): + self.simple_img2img["alwayson_scripts"]["ControlNet"]["args"] = [{ + "input_image": utils.readImage("test/test_files/img2img_basic.png"), + "model": self.model, + }] + self.assert_status_ok() + +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/tests/web_api/pose.json b/extensions-builtin/sd_forge_controlnet/tests/web_api/pose.json new file mode 100644 index 00000000..4b8d9b78 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/web_api/pose.json @@ -0,0 +1,194 @@ +{ + "people": [ + { + "pose_keypoints_2d": [ + 275.2506064884899, + 196.32469357280343, + 1, + 303.3188016469506, + 272.70982071889466, + 1, + 244.98447950024644, + 292.09994638829477, + 1, + 236.38292745027104, + 517.7037729015278, + 1, + 168.3984479500246, + 418.0022744632577, + 1, + 412.90526047751445, + 257.2121425016039, + 1, + 403.17894535813576, + 510.14290732520925, + 1, + 294.43481869004336, + 376.4781345848482, + 1, + 265.25747216047955, + 562.5137576822758, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 359.0078938961762, + 562.0711206495608, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 240.097671925037, + 184.513914838073, + 1, + 308.33409148775263, + 161.22089906296208, + 1, + 204.7558201874076, + 213.05887067565308, + 1, + 366.61934701298674, + 148.9278832878512, + 1 + ], + "hand_right_keypoints_2d": [ + 168.39790150130915, + 418.0005271461072, + 1, + 181.79401055357368, + 399.3767976307846, + 1, + 184.8627576873498, + 384.75709227716266, + 1, + 198.118414869015, + 381.90007483819153, + 1, + 215.15048903799024, + 386.8527024571639, + 1, + 180.1325238303079, + 346.88417988394843, + 1, + 178.10795487568174, + 321.1018085790239, + 1, + 190.70710955474613, + 320.5669160600145, + 1, + 203.3062827659017, + 325.5456061326966, + 1, + 172.3536896669116, + 350.7525276652412, + 1, + 170.000622912838, + 325.0336533262108, + 1, + 185.70972426755964, + 323.476117950832, + 1, + 208.50724912413568, + 333.4635128502484, + 1, + 163.50256975319706, + 356.1325737292637, + 1, + 162.59147123450128, + 335.0197021116338, + 1, + 183.9828354600188, + 328.4553078224726, + 1, + 201.57171021013423, + 337.94383954551654, + 1, + 152.9805889462092, + 357.94403689402753, + 1, + 167.09651929267878, + 341.7437601311937, + 1, + 180.9402668216081, + 337.10207327446744, + 1, + 194.60028340222678, + 343.0449246874465, + 1 + ], + "hand_left_keypoints_2d": [ + 294.4393772120137, + 376.476024395234, + 1, + 271.70933825161165, + 384.48117305399165, + 1, + 257.2452829806548, + 374.58948859472207, + 1, + 238.26122936397638, + 375.2887100029166, + 1, + 219.89983184668415, + 382.69322630254595, + 1, + 263.0323651487124, + 320.1279349241104, + 1, + 246.94602107917282, + 309.8099960810156, + 1, + 233.73717716804694, + 314.1485136789638, + 1, + 224.27755744411303, + 322.7892154545116, + 1, + 264.97558037166135, + 334.6319791090978, + 1, + 254.35598193615226, + 315.5629746257517, + 1, + 238.25810853722876, + 321.2812182403252, + 1, + 223.57727818251382, + 328.39525394113423, + 1, + 278.15831452661644, + 337.1533682086847, + 1, + 265.12624946042416, + 323.3619430418993, + 1, + 250.5919197031302, + 325.30525908324694, + 1, + 235.2500911122877, + 332.6721359855453, + 1, + 285.9427695830851, + 341.50671458478496, + 1, + 274.50497773130155, + 333.1376809270594, + 1, + 261.49768784257105, + 328.7012203257942, + 1, + 248.90495501067193, + 332.0535195828255, + 1 + ] + } + ], + "canvas_width": 512, + "canvas_height": 512 +} \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/tests/web_api/render_openpose_json.py b/extensions-builtin/sd_forge_controlnet/tests/web_api/render_openpose_json.py new file mode 100644 index 00000000..c95ac06a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/web_api/render_openpose_json.py @@ -0,0 +1,51 @@ +import requests +import unittest +import importlib +import json +from pathlib import Path + +utils = importlib.import_module("extensions.sd-webui-controlnet.tests.utils", "utils") + + +def render(poses): + return requests.post( + utils.BASE_URL + "/controlnet/render_openpose_json", json=poses + ).json() + + +with open(Path(__file__).parent / "pose.json", "r") as f: + pose = json.load(f) + + +with open(Path(__file__).parent / "animal_pose.json", "r") as f: + animal_pose = json.load(f) + + +class TestDetectEndpointWorking(unittest.TestCase): + def test_render_single(self): + res = render([pose]) + self.assertEqual(res["info"], "Success") + self.assertEqual(len(res["images"]), 1) + + def test_render_multiple(self): + res = render([pose, pose]) + self.assertEqual(res["info"], "Success") + self.assertEqual(len(res["images"]), 2) + + def test_render_no_pose(self): + res = render([]) + self.assertNotEqual(res["info"], "Success") + + def test_render_invalid_pose(self): + res = render([{"foo": 10, "bar": 100}]) + self.assertNotIn("info", res) + self.assertNotIn("images", res) + + def test_render_animals(self): + res = render([animal_pose]) + self.assertEqual(res["info"], "Success") + self.assertEqual(len(res["images"]), 1) + + +if __name__ == "__main__": + unittest.main() diff --git a/extensions-builtin/sd_forge_controlnet/tests/web_api/txt2img_test.py b/extensions-builtin/sd_forge_controlnet/tests/web_api/txt2img_test.py new file mode 100644 index 00000000..ba54e191 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/tests/web_api/txt2img_test.py @@ -0,0 +1,286 @@ +import os +import unittest +import requests +import importlib + +utils = importlib.import_module("extensions.sd-webui-controlnet.tests.utils", "utils") +from scripts.enums import StableDiffusionVersion +from modules import shared + + +class TestAlwaysonTxt2ImgWorking(unittest.TestCase): + def setUp(self): + self.sd_version = StableDiffusionVersion( + int( + os.environ.get( + "CONTROLNET_TEST_SD_VERSION", StableDiffusionVersion.SD1x.value + ) + ) + ) + self.model = utils.get_model("canny", self.sd_version) + + controlnet_unit = { + "enabled": True, + "module": "none", + "model": self.model, + "weight": 1.0, + "image": utils.readImage("test/test_files/img2img_basic.png"), + "mask": utils.readImage("test/test_files/img2img_basic.png"), + "resize_mode": 1, + "lowvram": False, + "processor_res": 64, + "threshold_a": 64, + "threshold_b": 64, + "guidance_start": 0.0, + "guidance_end": 1.0, + "control_mode": 0, + "pixel_perfect": False, + } + setup_args = [controlnet_unit] * getattr(self, "units_count", 1) + self.setup_route(setup_args) + + def setup_route(self, setup_args): + self.url_txt2img = "http://localhost:7860/sdapi/v1/txt2img" + self.simple_txt2img = { + "enable_hr": False, + "denoising_strength": 0, + "firstphase_width": 0, + "firstphase_height": 0, + "prompt": "example prompt", + "styles": [], + "seed": -1, + "subseed": -1, + "subseed_strength": 0, + "seed_resize_from_h": -1, + "seed_resize_from_w": -1, + "batch_size": 1, + "n_iter": 1, + "steps": 3, + "cfg_scale": 7, + "width": 64, + "height": 64, + "restore_faces": False, + "tiling": False, + "negative_prompt": "", + "eta": 0, + "s_churn": 0, + "s_tmax": 0, + "s_tmin": 0, + "s_noise": 1, + "sampler_index": "Euler a", + "alwayson_scripts": {}, + } + self.setup_controlnet_params(setup_args) + + def setup_controlnet_params(self, setup_args): + self.simple_txt2img["alwayson_scripts"]["ControlNet"] = {"args": setup_args} + + def assert_status_ok(self, msg=None, expected_image_num=None): + msg = ("" if msg is None else msg) + f"\nPayload:\n{self.simple_txt2img}" + + resp = requests.post(self.url_txt2img, json=self.simple_txt2img) + self.assertEqual(resp.status_code, 200, msg) + # Note: Exception/error in ControlNet code likely will cause hook failure, which further leads + # to detected map not being appended at the end of response image array. + data = resp.json() + if expected_image_num is None: + expected_image_num = self.simple_txt2img["n_iter"] * self.simple_txt2img[ + "batch_size" + ] + min( + sum( + [ + unit.get("save_detected_map", True) + for unit in self.simple_txt2img["alwayson_scripts"]["ControlNet"][ + "args" + ] + ] + ), + shared.opts.data.get("control_net_unit_count", 3), + ) + self.assertEqual(len(data["images"]), expected_image_num, msg) + + def test_txt2img_simple_performed(self): + self.assert_status_ok() + + def test_txt2img_alwayson_scripts_default_units(self): + self.units_count = 0 + self.setUp() + self.assert_status_ok() + + def test_txt2img_multiple_batches_performed(self): + self.simple_txt2img["n_iter"] = 2 + self.assert_status_ok() + + def test_txt2img_batch_performed(self): + self.simple_txt2img["batch_size"] = 2 + self.assert_status_ok() + + def test_txt2img_2_units(self): + self.units_count = 2 + self.setUp() + self.assert_status_ok() + + def test_txt2img_8_units(self): + self.units_count = 8 + self.setUp() + self.assert_status_ok() + + def test_txt2img_default_params(self): + self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"] = [ + { + "input_image": utils.readImage("test/test_files/img2img_basic.png"), + "model": self.model, + } + ] + + self.assert_status_ok() + + def test_call_with_preprocessors(self): + available_modules = utils.get_modules() + available_modules_list = available_modules.get("module_list", []) + available_modules_detail = available_modules.get("module_detail", {}) + for module in ["depth", "openpose_full"]: + assert module in available_modules_list, f"Failed to find {module}." + assert ( + module in available_modules_detail + ), f"Failed to find {module}'s detail." + with self.subTest(module=module): + self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"] = [ + { + "input_image": utils.readImage( + "test/test_files/img2img_basic.png" + ), + "model": self.model, + "module": module, + } + ] + self.assert_status_ok(f"Running preprocessor module: {module}") + + def test_call_invalid_params(self): + for param in ("processor_res", "threshold_a", "threshold_b"): + with self.subTest(param=param): + self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"] = [ + { + "input_image": utils.readImage( + "test/test_files/img2img_basic.png" + ), + "model": self.model, + param: -1, + } + ] + self.assert_status_ok(f"Run with {param} = -1.") + + def test_save_detected_map(self): + for save_map in (True, False): + with self.subTest(save_map=save_map): + self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"] = [ + { + "input_image": utils.readImage( + "test/test_files/img2img_basic.png" + ), + "model": self.model, + "module": "depth", + "save_detected_map": save_map, + } + ] + + resp = requests.post(self.url_txt2img, json=self.simple_txt2img).json() + self.assertEqual(2 if save_map else 1, len(resp["images"])) + + def run_test_unit( + self, module: str, model: str, sd_version: StableDiffusionVersion + ) -> None: + if self.sd_version != sd_version: + return + + self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"] = [ + { + "input_image": utils.readImage("test/test_files/img2img_basic.png"), + "model": utils.get_model(model, sd_version), + "module": module, + } + ] + + self.assert_status_ok() + + def test_ip_adapter_face(self): + self.run_test_unit( + "ip-adapter_clip_sdxl_plus_vith", + "ip-adapter-plus-face_sdxl_vit-h", + StableDiffusionVersion.SDXL, + ) + self.run_test_unit( + "ip-adapter_clip_sd15", + "ip-adapter-plus-face_sd15", + StableDiffusionVersion.SD1x, + ) + + def test_ip_adapter_fullface(self): + self.run_test_unit( + "ip-adapter_clip_sd15", + "ip-adapter-full-face_sd15", + StableDiffusionVersion.SD1x, + ) + + def test_control_lora(self): + self.run_test_unit("canny", "sai_xl_canny_128lora", StableDiffusionVersion.SDXL) + self.run_test_unit("canny", "control_lora_rank128_v11p_sd15_canny", StableDiffusionVersion.SD1x) + + def test_control_lllite(self): + self.run_test_unit( + "canny", "kohya_controllllite_xl_canny", StableDiffusionVersion.SDXL + ) + + def test_diffusers_controlnet(self): + self.run_test_unit( + "canny", "diffusers_xl_canny_small", StableDiffusionVersion.SDXL + ) + + def test_t2i_adapter(self): + self.run_test_unit( + "canny", "t2iadapter_canny_sd15v2", StableDiffusionVersion.SD1x + ) + self.run_test_unit("canny", "t2i-adapter_xl_canny", StableDiffusionVersion.SDXL) + + def test_reference(self): + self.run_test_unit("reference_only", "None", StableDiffusionVersion.SD1x) + self.run_test_unit("reference_only", "None", StableDiffusionVersion.SDXL) + + def test_unrecognized_param(self): + unit = self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"][0] + unit["foo"] = True + unit["is_ui"] = False + self.assert_status_ok() + + def test_default_model(self): + # Model "None" should be used when model is not specified in the payload. + self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"] = [ + { + "input_image": utils.readImage("test/test_files/img2img_basic.png"), + "module": "reference_only", + } + ] + self.assert_status_ok() + + def test_advanced_weighting(self): + unit = self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"][0] + unit["advanced_weighting"] = [0.75] * self.sd_version.controlnet_layer_num() + self.assert_status_ok() + + def test_hr_option(self): + # In non-hr run, hr_option should be ignored. + unit = self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"][0] + unit["hr_option"] = "High res only" + self.assert_status_ok(expected_image_num=2) + + # Hr run. + self.simple_txt2img["enable_hr"] = True + self.assert_status_ok(expected_image_num=3) + + self.simple_txt2img["enable_hr"] = True + unit["hr_option"] = "HiResFixOption.BOTH" + self.assert_status_ok(expected_image_num=3) + + +if __name__ == "__main__": + unittest.main() diff --git a/extensions-builtin/sd_forge_controlnet/web_tests/README.md b/extensions-builtin/sd_forge_controlnet/web_tests/README.md new file mode 100644 index 00000000..c1c6eac0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/web_tests/README.md @@ -0,0 +1,15 @@ +# Web Tests +Web tests are selenium-based browser interaction tests, that fully simulate +actual user's behaviours. + +# Preparation +- Have Google Chrome (Any version) installed. +- Install following python packages with `pip`: + - `selenium` + - `webdriver-manager` + +# Run Tests +- Have WebUI with ControlNet installed running on `localhost:7860` +- Run `python main.py --overwrite_expectation` for the first run to set a +baseline. +- Run `python main.py` later to verify the baseline still holds. \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/web_tests/images/ski.jpg b/extensions-builtin/sd_forge_controlnet/web_tests/images/ski.jpg new file mode 100644 index 0000000000000000000000000000000000000000..662484140f68ce8b4af4f815e47f1687c800bfa1 GIT binary patch literal 141529 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%0DiH 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℘ZKQ(eXc{Sq_Q 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 "WebElement": + return driver.find_element(By.XPATH, xpath) + + def tab(self, driver: webdriver.Chrome) -> "WebElement": + return self._find_by_xpath( + driver, + f"//*[@id='tabs']/*[contains(@class, 'tab-nav')]//button[text()='{self.value}']", + ) + + def controlnet_panel(self, driver: webdriver.Chrome) -> "WebElement": + return self._find_by_xpath( + driver, f"//*[@id='tab_{self.value}']//*[@id='controlnet']" + ) + + def generate_button(self, driver: webdriver.Chrome) -> "WebElement": + return self._find_by_xpath(driver, f"//*[@id='{self.value}_generate_box']") + + def prompt_textarea(self, driver: webdriver.Chrome) -> "WebElement": + return self._find_by_xpath(driver, f"//*[@id='{self.value}_prompt']//textarea") + + +class SeleniumTestCase(unittest.TestCase): + def __init__(self, methodName: str = "runTest") -> None: + super().__init__(methodName) + self.driver = None + self.gen_type = None + + def setUp(self) -> None: + super().setUp() + self.driver = webdriver.Chrome(driver_path) + self.driver.get(webui_url) + wait = WebDriverWait(self.driver, TIMEOUT) + wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "#controlnet"))) + self.gen_type = GenType.txt2img + + def tearDown(self) -> None: + self.driver.quit() + super().tearDown() + + def select_gen_type(self, gen_type: GenType): + gen_type.tab(self.driver).click() + self.gen_type = gen_type + + def set_prompt(self, prompt: str): + textarea = self.gen_type.prompt_textarea(self.driver) + textarea.clear() + textarea.send_keys(prompt) + + def expand_controlnet_panel(self): + controlnet_panel = self.gen_type.controlnet_panel(self.driver) + input_image_group = controlnet_panel.find_element( + By.CSS_SELECTOR, ".cnet-input-image-group" + ) + if not input_image_group.is_displayed(): + controlnet_panel.click() + + def enable_controlnet_unit(self): + controlnet_panel = self.gen_type.controlnet_panel(self.driver) + enable_checkbox = controlnet_panel.find_element( + By.CSS_SELECTOR, ".cnet-unit-enabled input[type='checkbox']" + ) + if not enable_checkbox.is_selected(): + enable_checkbox.click() + + def iterate_preprocessor_types(self, ignore_none: bool = True): + dropdown = self.gen_type.controlnet_panel(self.driver).find_element( + By.CSS_SELECTOR, + f"#{self.gen_type.value}_controlnet_ControlNet-0_controlnet_preprocessor_dropdown", + ) + + index = 0 + while True: + dropdown.click() + options = dropdown.find_elements( + By.XPATH, "//ul[contains(@class, 'options')]/li" + ) + input_element = dropdown.find_element(By.CSS_SELECTOR, "input") + + if index >= len(options): + return + + option = options[index] + index += 1 + + if "none" in option.text and ignore_none: + continue + option_text = option.text + option.click() + + yield option_text + + def select_control_type(self, control_type: str): + controlnet_panel = self.gen_type.controlnet_panel(self.driver) + control_type_radio = controlnet_panel.find_element( + By.CSS_SELECTOR, f'.controlnet_control_type input[value="{control_type}"]' + ) + control_type_radio.click() + time.sleep(3) # Wait for gradio backend to update model/module + + def set_seed(self, seed: int): + seed_input = self.driver.find_element( + By.CSS_SELECTOR, f"#{self.gen_type.value}_seed input[type='number']" + ) + seed_input.clear() + seed_input.send_keys(seed) + + def set_subseed(self, seed: int): + show_button = self.driver.find_element( + By.CSS_SELECTOR, + f"#{self.gen_type.value}_subseed_show input[type='checkbox']", + ) + if not show_button.is_selected(): + show_button.click() + + subseed_locator = ( + By.CSS_SELECTOR, + f"#{self.gen_type.value}_subseed input[type='number']", + ) + WebDriverWait(self.driver, TIMEOUT).until( + EC.visibility_of_element_located(subseed_locator) + ) + subseed_input = self.driver.find_element(*subseed_locator) + subseed_input.clear() + subseed_input.send_keys(seed) + + def upload_controlnet_input(self, img_path: str): + controlnet_panel = self.gen_type.controlnet_panel(self.driver) + image_input = controlnet_panel.find_element( + By.CSS_SELECTOR, '.cnet-input-image-group .cnet-image input[type="file"]' + ) + image_input.send_keys(img_path) + + def upload_img2img_input(self, img_path: str): + image_input = self.driver.find_element( + By.CSS_SELECTOR, '#img2img_image input[type="file"]' + ) + image_input.send_keys(img_path) + + def generate_image(self, name: str): + self.gen_type.generate_button(self.driver).click() + progress_bar_locator_visible = EC.visibility_of_element_located( + (By.CSS_SELECTOR, f"#{self.gen_type.value}_results .progress") + ) + WebDriverWait(self.driver, TIMEOUT).until(progress_bar_locator_visible) + WebDriverWait(self.driver, TIMEOUT * 10).until_not(progress_bar_locator_visible) + generated_imgs = self.driver.find_elements( + By.CSS_SELECTOR, + f"#{self.gen_type.value}_results #{self.gen_type.value}_gallery img", + ) + for i, generated_img in enumerate(generated_imgs): + # Use requests to get the image content + img_content = requests.get(generated_img.get_attribute("src")).content + + # Save the image content to a file + global overwrite_expectation + dest_dir = ( + test_expectation_dir if overwrite_expectation else test_result_dir + ) + img_file_name = f"{self.__class__.__name__}_{name}_{i}.png" + with open( + os.path.join(dest_dir, img_file_name), + "wb", + ) as img_file: + img_file.write(img_content) + + if not overwrite_expectation: + try: + img1 = cv2.imread(os.path.join(test_expectation_dir, img_file_name)) + img2 = cv2.imread(os.path.join(test_result_dir, img_file_name)) + except Exception as e: + self.assertTrue(False, f"Get exception reading imgs: {e}") + continue + + self.expect_same_image( + img1, + img2, + diff_img_path=os.path.join( + test_result_dir, img_file_name.replace(".png", "_diff.png") + ), + ) + + def expect_same_image(self, img1, img2, diff_img_path: str): + # Calculate the difference between the two images + diff = cv2.absdiff(img1, img2) + + # Set a threshold to highlight the different pixels + threshold = 30 + diff_highlighted = np.where(diff > threshold, 255, 0).astype(np.uint8) + + # Assert that the two images are similar within a tolerance + similar = np.allclose(img1, img2, rtol=0.5, atol=1) + if not similar: + # Save the diff_highlighted image to inspect the differences + cv2.imwrite(diff_img_path, diff_highlighted) + + self.assertTrue(similar) + + +simple_control_types = { + "Canny": "canny", + "Depth": "depth_midas", + "Normal": "normal_bae", + "OpenPose": "openpose_full", + "MLSD": "mlsd", + "Lineart": "lineart_standard (from white bg & black line)", + "SoftEdge": "softedge_pidinet", + "Scribble": "scribble_pidinet", + "Seg": "seg_ofade20k", + "Tile": "tile_resample", + # Shuffle and Reference are not stable, and expected to fail. + # The majority of pixels are same, but some outlier pixels can have big diff. + "Shuffle": "shuffle", + "Reference": "reference_only", +}.keys() + + +class SeleniumTxt2ImgTest(SeleniumTestCase): + def setUp(self) -> None: + super().setUp() + self.select_gen_type(GenType.txt2img) + self.set_seed(100) + self.set_subseed(1000) + + def test_simple_control_types(self): + """Test simple control types that only requires input image.""" + for control_type in simple_control_types: + with self.subTest(control_type=control_type): + self.expand_controlnet_panel() + self.select_control_type(control_type) + self.upload_controlnet_input(SKI_IMAGE) + self.generate_image(f"{control_type}_ski") + + +class SeleniumImg2ImgTest(SeleniumTestCase): + def setUp(self) -> None: + super().setUp() + self.select_gen_type(GenType.img2img) + self.set_seed(100) + self.set_subseed(1000) + + def test_simple_control_types(self): + """Test simple control types that only requires input image.""" + for control_type in simple_control_types: + with self.subTest(control_type=control_type): + self.expand_controlnet_panel() + self.select_control_type(control_type) + self.upload_img2img_input(SKI_IMAGE) + self.upload_controlnet_input(SKI_IMAGE) + self.generate_image(f"img2img_{control_type}_ski") + + +class SeleniumInpaintTest(SeleniumTestCase): + def setUp(self) -> None: + super().setUp() + + def draw_inpaint_mask(self, target_canvas): + size = target_canvas.size + width = size["width"] + height = size["height"] + brush_radius = 5 + repeat = int(width * 0.1 / brush_radius) + + trace: List[Tuple[int, int]] = [ + (brush_radius, 0), + (0, height * 0.2), + (brush_radius, 0), + (0, -height * 0.2), + ] * repeat + + actions = ActionChains(self.driver) + actions.move_to_element(target_canvas) # move to the canvas + actions.move_by_offset(*trace[0]) + actions.click_and_hold() # click and hold the left mouse button down + for stop_point in trace[1:]: + actions.move_by_offset(*stop_point) + actions.release() # release the left mouse button + actions.perform() # perform the action chain + + def draw_cn_mask(self): + canvas = self.gen_type.controlnet_panel(self.driver).find_element( + By.CSS_SELECTOR, ".cnet-input-image-group .cnet-image canvas" + ) + self.draw_inpaint_mask(canvas) + + def draw_a1111_mask(self): + canvas = self.driver.find_element(By.CSS_SELECTOR, "#img2maskimg canvas") + self.draw_inpaint_mask(canvas) + + def test_txt2img_inpaint(self): + self.select_gen_type(GenType.txt2img) + self.expand_controlnet_panel() + self.select_control_type("Inpaint") + self.upload_controlnet_input(SKI_IMAGE) + self.draw_cn_mask() + + self.set_seed(100) + self.set_subseed(1000) + + for option in self.iterate_preprocessor_types(): + with self.subTest(option=option): + self.generate_image(f"{option}_txt2img_ski") + + def test_img2img_inpaint(self): + # Note: img2img inpaint can only use A1111 mask. + # ControlNet input is disabled in img2img inpaint. + self._test_img2img_inpaint(use_cn_mask=False, use_a1111_mask=True) + + def _test_img2img_inpaint(self, use_cn_mask: bool, use_a1111_mask: bool): + self.select_gen_type(GenType.img2img) + self.expand_controlnet_panel() + self.select_control_type("Inpaint") + self.upload_img2img_input(SKI_IMAGE) + # Send to inpaint + self.driver.find_element( + By.XPATH, f"//*[@id='img2img_copy_to_img2img']//button[text()='inpaint']" + ).click() + time.sleep(3) + # Select latent noise to make inpaint effect more visible. + self.driver.find_element( + By.XPATH, + f"//input[@name='radio-img2img_inpainting_fill' and @value='latent noise']", + ).click() + self.set_prompt("(coca-cola:2.0)") + self.enable_controlnet_unit() + self.upload_controlnet_input(SKI_IMAGE) + + self.set_seed(100) + self.set_subseed(1000) + + prefix = "" + if use_cn_mask: + self.draw_cn_mask() + prefix += "controlnet" + + if use_a1111_mask: + self.draw_a1111_mask() + prefix += "A1111" + + for option in self.iterate_preprocessor_types(): + with self.subTest(option=option, mask_prefix=prefix): + self.generate_image(f"{option}_{prefix}_img2img_ski") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Your script description.") + parser.add_argument( + "--overwrite_expectation", action="store_true", help="overwrite expectation" + ) + parser.add_argument( + "--target_url", type=str, default="http://localhost:7860", help="WebUI URL" + ) + args, unknown_args = parser.parse_known_args() + overwrite_expectation = args.overwrite_expectation + webui_url = args.target_url + + sys.argv = sys.argv[:1] + unknown_args + unittest.main()

    tv{ndZxd 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

  • e{-rWJ$~}u#mi@%cUBP! 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�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 fRjGO>X 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%0AwE7gPM}ETvo?>?>RY1N&w2C;=QG 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

    % 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 literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/clipvision/clip_vision_vith_uc.data b/extensions-builtin/sd_forge_controlnet/annotator/clipvision/clip_vision_vith_uc.data new file mode 100644 index 0000000000000000000000000000000000000000..0c0a61afe9f3a864dc46f3928ac621c33eeff303 GIT binary patch literal 66319 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 literal 0 HcmV?d00001 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/color/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/color/__init__.py new file mode 100644 index 00000000..65799a2a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/color/__init__.py @@ -0,0 +1,20 @@ +import cv2 + +def cv2_resize_shortest_edge(image, size): + h, w = image.shape[:2] + if h < w: + new_h = size + new_w = int(round(w / h * size)) + else: + new_w = size + new_h = int(round(h / w * size)) + resized_image = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_AREA) + return resized_image + +def apply_color(img, res=512): + img = cv2_resize_shortest_edge(img, res) + h, w = img.shape[:2] + + input_img_color = cv2.resize(img, (w//64, h//64), interpolation=cv2.INTER_CUBIC) + input_img_color = cv2.resize(input_img_color, (w, h), interpolation=cv2.INTER_NEAREST) + return input_img_color \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/densepose/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/densepose/__init__.py new file mode 100644 index 00000000..fc46bc2d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/densepose/__init__.py @@ -0,0 +1,57 @@ +import torchvision # Fix issue Unknown builtin op: torchvision::nms +import cv2 +import numpy as np +import torch +from einops import rearrange +from .densepose import DensePoseMaskedColormapResultsVisualizer, _extract_i_from_iuvarr, densepose_chart_predictor_output_to_result_with_confidences +from modules import devices +from annotator.annotator_path import models_path +import os + +N_PART_LABELS = 24 +result_visualizer = DensePoseMaskedColormapResultsVisualizer( + alpha=1, + data_extractor=_extract_i_from_iuvarr, + segm_extractor=_extract_i_from_iuvarr, + val_scale = 255.0 / N_PART_LABELS +) +remote_torchscript_path = "https://huggingface.co/LayerNorm/DensePose-TorchScript-with-hint-image/resolve/main/densepose_r50_fpn_dl.torchscript" +torchscript_model = None +model_dir = os.path.join(models_path, "densepose") + +def apply_densepose(input_image, cmap="viridis"): + global torchscript_model + if torchscript_model is None: + model_path = os.path.join(model_dir, "densepose_r50_fpn_dl.torchscript") + if not os.path.exists(model_path): + from basicsr.utils.download_util import load_file_from_url + load_file_from_url(remote_torchscript_path, model_dir=model_dir) + torchscript_model = torch.jit.load(model_path, map_location="cpu").to(devices.get_device_for("controlnet")).eval() + H, W = input_image.shape[:2] + + hint_image_canvas = np.zeros([H, W], dtype=np.uint8) + hint_image_canvas = np.tile(hint_image_canvas[:, :, np.newaxis], [1, 1, 3]) + input_image = rearrange(torch.from_numpy(input_image).to(devices.get_device_for("controlnet")), 'h w c -> c h w') + pred_boxes, corase_segm, fine_segm, u, v = torchscript_model(input_image) + + extractor = densepose_chart_predictor_output_to_result_with_confidences + densepose_results = [extractor(pred_boxes[i:i+1], corase_segm[i:i+1], fine_segm[i:i+1], u[i:i+1], v[i:i+1]) for i in range(len(pred_boxes))] + + if cmap=="viridis": + result_visualizer.mask_visualizer.cmap = cv2.COLORMAP_VIRIDIS + hint_image = result_visualizer.visualize(hint_image_canvas, densepose_results) + hint_image = cv2.cvtColor(hint_image, cv2.COLOR_BGR2RGB) + hint_image[:, :, 0][hint_image[:, :, 0] == 0] = 68 + hint_image[:, :, 1][hint_image[:, :, 1] == 0] = 1 + hint_image[:, :, 2][hint_image[:, :, 2] == 0] = 84 + else: + result_visualizer.mask_visualizer.cmap = cv2.COLORMAP_PARULA + hint_image = result_visualizer.visualize(hint_image_canvas, densepose_results) + hint_image = cv2.cvtColor(hint_image, cv2.COLOR_BGR2RGB) + + return hint_image + +def unload_model(): + global torchscript_model + if torchscript_model is not None: + torchscript_model.cpu() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/densepose/densepose.py b/extensions-builtin/sd_forge_controlnet/annotator/densepose/densepose.py new file mode 100644 index 00000000..5e43b05f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/densepose/densepose.py @@ -0,0 +1,347 @@ +from typing import Tuple +import math +import numpy as np +from enum import IntEnum +from typing import List, Tuple, Union +import torch +from torch.nn import functional as F +import logging +import cv2 + +Image = np.ndarray +Boxes = torch.Tensor +ImageSizeType = Tuple[int, int] +_RawBoxType = Union[List[float], Tuple[float, ...], torch.Tensor, np.ndarray] +IntTupleBox = Tuple[int, int, int, int] + +class BoxMode(IntEnum): + """ + Enum of different ways to represent a box. + """ + + XYXY_ABS = 0 + """ + (x0, y0, x1, y1) in absolute floating points coordinates. + The coordinates in range [0, width or height]. + """ + XYWH_ABS = 1 + """ + (x0, y0, w, h) in absolute floating points coordinates. + """ + XYXY_REL = 2 + """ + Not yet supported! + (x0, y0, x1, y1) in range [0, 1]. They are relative to the size of the image. + """ + XYWH_REL = 3 + """ + Not yet supported! + (x0, y0, w, h) in range [0, 1]. They are relative to the size of the image. + """ + XYWHA_ABS = 4 + """ + (xc, yc, w, h, a) in absolute floating points coordinates. + (xc, yc) is the center of the rotated box, and the angle a is in degrees ccw. + """ + + @staticmethod + def convert(box: _RawBoxType, from_mode: "BoxMode", to_mode: "BoxMode") -> _RawBoxType: + """ + Args: + box: can be a k-tuple, k-list or an Nxk array/tensor, where k = 4 or 5 + from_mode, to_mode (BoxMode) + + Returns: + The converted box of the same type. + """ + if from_mode == to_mode: + return box + + original_type = type(box) + is_numpy = isinstance(box, np.ndarray) + single_box = isinstance(box, (list, tuple)) + if single_box: + assert len(box) == 4 or len(box) == 5, ( + "BoxMode.convert takes either a k-tuple/list or an Nxk array/tensor," + " where k == 4 or 5" + ) + arr = torch.tensor(box)[None, :] + else: + # avoid modifying the input box + if is_numpy: + arr = torch.from_numpy(np.asarray(box)).clone() + else: + arr = box.clone() + + assert to_mode not in [BoxMode.XYXY_REL, BoxMode.XYWH_REL] and from_mode not in [ + BoxMode.XYXY_REL, + BoxMode.XYWH_REL, + ], "Relative mode not yet supported!" + + if from_mode == BoxMode.XYWHA_ABS and to_mode == BoxMode.XYXY_ABS: + assert ( + arr.shape[-1] == 5 + ), "The last dimension of input shape must be 5 for XYWHA format" + original_dtype = arr.dtype + arr = arr.double() + + w = arr[:, 2] + h = arr[:, 3] + a = arr[:, 4] + c = torch.abs(torch.cos(a * math.pi / 180.0)) + s = torch.abs(torch.sin(a * math.pi / 180.0)) + # This basically computes the horizontal bounding rectangle of the rotated box + new_w = c * w + s * h + new_h = c * h + s * w + + # convert center to top-left corner + arr[:, 0] -= new_w / 2.0 + arr[:, 1] -= new_h / 2.0 + # bottom-right corner + arr[:, 2] = arr[:, 0] + new_w + arr[:, 3] = arr[:, 1] + new_h + + arr = arr[:, :4].to(dtype=original_dtype) + elif from_mode == BoxMode.XYWH_ABS and to_mode == BoxMode.XYWHA_ABS: + original_dtype = arr.dtype + arr = arr.double() + arr[:, 0] += arr[:, 2] / 2.0 + arr[:, 1] += arr[:, 3] / 2.0 + angles = torch.zeros((arr.shape[0], 1), dtype=arr.dtype) + arr = torch.cat((arr, angles), axis=1).to(dtype=original_dtype) + else: + if to_mode == BoxMode.XYXY_ABS and from_mode == BoxMode.XYWH_ABS: + arr[:, 2] += arr[:, 0] + arr[:, 3] += arr[:, 1] + elif from_mode == BoxMode.XYXY_ABS and to_mode == BoxMode.XYWH_ABS: + arr[:, 2] -= arr[:, 0] + arr[:, 3] -= arr[:, 1] + else: + raise NotImplementedError( + "Conversion from BoxMode {} to {} is not supported yet".format( + from_mode, to_mode + ) + ) + + if single_box: + return original_type(arr.flatten().tolist()) + if is_numpy: + return arr.numpy() + else: + return arr + +class MatrixVisualizer: + """ + Base visualizer for matrix data + """ + + def __init__( + self, + inplace=True, + cmap=cv2.COLORMAP_PARULA, + val_scale=1.0, + alpha=0.7, + interp_method_matrix=cv2.INTER_LINEAR, + interp_method_mask=cv2.INTER_NEAREST, + ): + self.inplace = inplace + self.cmap = cmap + self.val_scale = val_scale + self.alpha = alpha + self.interp_method_matrix = interp_method_matrix + self.interp_method_mask = interp_method_mask + + def visualize(self, image_bgr, mask, matrix, bbox_xywh): + self._check_image(image_bgr) + self._check_mask_matrix(mask, matrix) + if self.inplace: + image_target_bgr = image_bgr + else: + image_target_bgr = image_bgr * 0 + x, y, w, h = [int(v) for v in bbox_xywh] + if w <= 0 or h <= 0: + return image_bgr + mask, matrix = self._resize(mask, matrix, w, h) + mask_bg = np.tile((mask == 0)[:, :, np.newaxis], [1, 1, 3]) + matrix_scaled = matrix.astype(np.float32) * self.val_scale + _EPSILON = 1e-6 + if np.any(matrix_scaled > 255 + _EPSILON): + logger = logging.getLogger(__name__) + logger.warning( + f"Matrix has values > {255 + _EPSILON} after " f"scaling, clipping to [0..255]" + ) + matrix_scaled_8u = matrix_scaled.clip(0, 255).astype(np.uint8) + matrix_vis = cv2.applyColorMap(matrix_scaled_8u, self.cmap) + matrix_vis[mask_bg] = image_target_bgr[y : y + h, x : x + w, :][mask_bg] + image_target_bgr[y : y + h, x : x + w, :] = ( + image_target_bgr[y : y + h, x : x + w, :] * (1.0 - self.alpha) + matrix_vis * self.alpha + ) + return image_target_bgr.astype(np.uint8) + + def _resize(self, mask, matrix, w, h): + if (w != mask.shape[1]) or (h != mask.shape[0]): + mask = cv2.resize(mask, (w, h), self.interp_method_mask) + if (w != matrix.shape[1]) or (h != matrix.shape[0]): + matrix = cv2.resize(matrix, (w, h), self.interp_method_matrix) + return mask, matrix + + def _check_image(self, image_rgb): + assert len(image_rgb.shape) == 3 + assert image_rgb.shape[2] == 3 + assert image_rgb.dtype == np.uint8 + + def _check_mask_matrix(self, mask, matrix): + assert len(matrix.shape) == 2 + assert len(mask.shape) == 2 + assert mask.dtype == np.uint8 + +class DensePoseResultsVisualizer: + def visualize( + self, + image_bgr: Image, + results, + ) -> Image: + context = self.create_visualization_context(image_bgr) + for i, result in enumerate(results): + boxes_xywh, labels, uv = result + iuv_array = torch.cat( + (labels[None].type(torch.float32), uv * 255.0) + ).type(torch.uint8) + self.visualize_iuv_arr(context, iuv_array.cpu().numpy(), boxes_xywh) + image_bgr = self.context_to_image_bgr(context) + return image_bgr + + def create_visualization_context(self, image_bgr: Image): + return image_bgr + + def visualize_iuv_arr(self, context, iuv_arr: np.ndarray, bbox_xywh) -> None: + pass + + def context_to_image_bgr(self, context): + return context + + def get_image_bgr_from_context(self, context): + return context + +class DensePoseMaskedColormapResultsVisualizer(DensePoseResultsVisualizer): + def __init__( + self, + data_extractor, + segm_extractor, + inplace=True, + cmap=cv2.COLORMAP_PARULA, + alpha=0.7, + val_scale=1.0, + **kwargs, + ): + self.mask_visualizer = MatrixVisualizer( + inplace=inplace, cmap=cmap, val_scale=val_scale, alpha=alpha + ) + self.data_extractor = data_extractor + self.segm_extractor = segm_extractor + + def context_to_image_bgr(self, context): + return context + + def visualize_iuv_arr(self, context, iuv_arr: np.ndarray, bbox_xywh) -> None: + image_bgr = self.get_image_bgr_from_context(context) + matrix = self.data_extractor(iuv_arr) + segm = self.segm_extractor(iuv_arr) + mask = np.zeros(matrix.shape, dtype=np.uint8) + mask[segm > 0] = 1 + image_bgr = self.mask_visualizer.visualize(image_bgr, mask, matrix, bbox_xywh) + + +def _extract_i_from_iuvarr(iuv_arr): + return iuv_arr[0, :, :] + + +def _extract_u_from_iuvarr(iuv_arr): + return iuv_arr[1, :, :] + + +def _extract_v_from_iuvarr(iuv_arr): + return iuv_arr[2, :, :] + +def make_int_box(box: torch.Tensor) -> IntTupleBox: + int_box = [0, 0, 0, 0] + int_box[0], int_box[1], int_box[2], int_box[3] = tuple(box.long().tolist()) + return int_box[0], int_box[1], int_box[2], int_box[3] + +def densepose_chart_predictor_output_to_result_with_confidences( + boxes: Boxes, + coarse_segm, + fine_segm, + u, v + +): + boxes_xyxy_abs = boxes.clone() + boxes_xywh_abs = BoxMode.convert(boxes_xyxy_abs, BoxMode.XYXY_ABS, BoxMode.XYWH_ABS) + box_xywh = make_int_box(boxes_xywh_abs[0]) + + labels = resample_fine_and_coarse_segm_tensors_to_bbox(fine_segm, coarse_segm, box_xywh).squeeze(0) + uv = resample_uv_tensors_to_bbox(u, v, labels, box_xywh) + confidences = [] + return box_xywh, labels, uv + +def resample_fine_and_coarse_segm_tensors_to_bbox( + fine_segm: torch.Tensor, coarse_segm: torch.Tensor, box_xywh_abs: IntTupleBox +): + """ + Resample fine and coarse segmentation tensors to the given + bounding box and derive labels for each pixel of the bounding box + + Args: + fine_segm: float tensor of shape [1, C, Hout, Wout] + coarse_segm: float tensor of shape [1, K, Hout, Wout] + box_xywh_abs (tuple of 4 int): bounding box given by its upper-left + corner coordinates, width (W) and height (H) + Return: + Labels for each pixel of the bounding box, a long tensor of size [1, H, W] + """ + x, y, w, h = box_xywh_abs + w = max(int(w), 1) + h = max(int(h), 1) + # coarse segmentation + coarse_segm_bbox = F.interpolate( + coarse_segm, + (h, w), + mode="bilinear", + align_corners=False, + ).argmax(dim=1) + # combined coarse and fine segmentation + labels = ( + F.interpolate(fine_segm, (h, w), mode="bilinear", align_corners=False).argmax(dim=1) + * (coarse_segm_bbox > 0).long() + ) + return labels + +def resample_uv_tensors_to_bbox( + u: torch.Tensor, + v: torch.Tensor, + labels: torch.Tensor, + box_xywh_abs: IntTupleBox, +) -> torch.Tensor: + """ + Resamples U and V coordinate estimates for the given bounding box + + Args: + u (tensor [1, C, H, W] of float): U coordinates + v (tensor [1, C, H, W] of float): V coordinates + labels (tensor [H, W] of long): labels obtained by resampling segmentation + outputs for the given bounding box + box_xywh_abs (tuple of 4 int): bounding box that corresponds to predictor outputs + Return: + Resampled U and V coordinates - a tensor [2, H, W] of float + """ + x, y, w, h = box_xywh_abs + w = max(int(w), 1) + h = max(int(h), 1) + u_bbox = F.interpolate(u, (h, w), mode="bilinear", align_corners=False) + v_bbox = F.interpolate(v, (h, w), mode="bilinear", align_corners=False) + uv = torch.zeros([2, h, w], dtype=torch.float32, device=u.device) + for part_id in range(1, u_bbox.size(1)): + uv[0][labels == part_id] = u_bbox[0, part_id][labels == part_id] + uv[1][labels == part_id] = v_bbox[0, part_id][labels == part_id] + return uv + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/depth_anything.py b/extensions-builtin/sd_forge_controlnet/annotator/depth_anything.py new file mode 100644 index 00000000..bbe480c5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/depth_anything.py @@ -0,0 +1,79 @@ +import os +import torch +import cv2 +import numpy as np +import torch.nn.functional as F +from torchvision.transforms import Compose + +from depth_anything.dpt import DPT_DINOv2 +from depth_anything.util.transform import Resize, NormalizeImage, PrepareForNet +from .util import load_model +from .annotator_path import models_path + + +transform = Compose( + [ + Resize( + width=518, + height=518, + resize_target=False, + keep_aspect_ratio=True, + ensure_multiple_of=14, + resize_method="lower_bound", + image_interpolation_method=cv2.INTER_CUBIC, + ), + NormalizeImage(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), + PrepareForNet(), + ] +) + + +class DepthAnythingDetector: + """https://github.com/LiheYoung/Depth-Anything""" + + model_dir = os.path.join(models_path, "depth_anything") + + def __init__(self, device: torch.device): + self.device = device + self.model = ( + DPT_DINOv2( + encoder="vitl", + features=256, + out_channels=[256, 512, 1024, 1024], + localhub=False, + ) + .to(device) + .eval() + ) + remote_url = os.environ.get( + "CONTROLNET_DEPTH_ANYTHING_MODEL_URL", + "https://huggingface.co/spaces/LiheYoung/Depth-Anything/resolve/main/checkpoints/depth_anything_vitl14.pth", + ) + model_path = load_model( + "depth_anything_vitl14.pth", remote_url=remote_url, model_dir=self.model_dir + ) + self.model.load_state_dict(torch.load(model_path)) + + def __call__(self, image: np.ndarray, colored: bool = True) -> np.ndarray: + self.model.to(self.device) + h, w = image.shape[:2] + + image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) / 255.0 + image = transform({"image": image})["image"] + image = torch.from_numpy(image).unsqueeze(0).to(self.device) + @torch.no_grad() + def predict_depth(model, image): + return model(image) + depth = predict_depth(self.model, image) + depth = F.interpolate( + depth[None], (h, w), mode="bilinear", align_corners=False + )[0, 0] + depth = (depth - depth.min()) / (depth.max() - depth.min()) * 255.0 + depth = depth.cpu().numpy().astype(np.uint8) + if colored: + return cv2.applyColorMap(depth, cv2.COLORMAP_INFERNO)[:, :, ::-1] + else: + return depth + + def unload_model(self): + self.model.to("cpu") diff --git a/extensions-builtin/sd_forge_controlnet/annotator/hed/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/hed/__init__.py new file mode 100644 index 00000000..0cabfef0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/hed/__init__.py @@ -0,0 +1,98 @@ +# This is an improved version and model of HED edge detection with Apache License, Version 2.0. +# Please use this implementation in your products +# This implementation may produce slightly different results from Saining Xie's official implementations, +# but it generates smoother edges and is more suitable for ControlNet as well as other image-to-image translations. +# Different from official models and other implementations, this is an RGB-input model (rather than BGR) +# and in this way it works better for gradio's RGB protocol + +import os +import cv2 +import torch +import numpy as np + +from einops import rearrange +import os +from modules import devices +from annotator.annotator_path import models_path +from annotator.util import safe_step, nms + + +class DoubleConvBlock(torch.nn.Module): + def __init__(self, input_channel, output_channel, layer_number): + super().__init__() + self.convs = torch.nn.Sequential() + self.convs.append(torch.nn.Conv2d(in_channels=input_channel, out_channels=output_channel, kernel_size=(3, 3), stride=(1, 1), padding=1)) + for i in range(1, layer_number): + self.convs.append(torch.nn.Conv2d(in_channels=output_channel, out_channels=output_channel, kernel_size=(3, 3), stride=(1, 1), padding=1)) + self.projection = torch.nn.Conv2d(in_channels=output_channel, out_channels=1, kernel_size=(1, 1), stride=(1, 1), padding=0) + + def __call__(self, x, down_sampling=False): + h = x + if down_sampling: + h = torch.nn.functional.max_pool2d(h, kernel_size=(2, 2), stride=(2, 2)) + for conv in self.convs: + h = conv(h) + h = torch.nn.functional.relu(h) + return h, self.projection(h) + + +class ControlNetHED_Apache2(torch.nn.Module): + def __init__(self): + super().__init__() + self.norm = torch.nn.Parameter(torch.zeros(size=(1, 3, 1, 1))) + self.block1 = DoubleConvBlock(input_channel=3, output_channel=64, layer_number=2) + self.block2 = DoubleConvBlock(input_channel=64, output_channel=128, layer_number=2) + self.block3 = DoubleConvBlock(input_channel=128, output_channel=256, layer_number=3) + self.block4 = DoubleConvBlock(input_channel=256, output_channel=512, layer_number=3) + self.block5 = DoubleConvBlock(input_channel=512, output_channel=512, layer_number=3) + + def __call__(self, x): + h = x - self.norm + h, projection1 = self.block1(h) + h, projection2 = self.block2(h, down_sampling=True) + h, projection3 = self.block3(h, down_sampling=True) + h, projection4 = self.block4(h, down_sampling=True) + h, projection5 = self.block5(h, down_sampling=True) + return projection1, projection2, projection3, projection4, projection5 + + +netNetwork = None +remote_model_path = "https://huggingface.co/lllyasviel/Annotators/resolve/main/ControlNetHED.pth" +modeldir = os.path.join(models_path, "hed") +old_modeldir = os.path.dirname(os.path.realpath(__file__)) + + +def apply_hed(input_image, is_safe=False): + global netNetwork + if netNetwork is None: + modelpath = os.path.join(modeldir, "ControlNetHED.pth") + old_modelpath = os.path.join(old_modeldir, "ControlNetHED.pth") + if os.path.exists(old_modelpath): + modelpath = old_modelpath + elif not os.path.exists(modelpath): + from basicsr.utils.download_util import load_file_from_url + load_file_from_url(remote_model_path, model_dir=modeldir) + netNetwork = ControlNetHED_Apache2().to(devices.get_device_for("controlnet")) + netNetwork.load_state_dict(torch.load(modelpath, map_location='cpu')) + netNetwork.to(devices.get_device_for("controlnet")).float().eval() + + assert input_image.ndim == 3 + H, W, C = input_image.shape + with torch.no_grad(): + image_hed = torch.from_numpy(input_image.copy()).float().to(devices.get_device_for("controlnet")) + image_hed = rearrange(image_hed, 'h w c -> 1 c h w') + edges = netNetwork(image_hed) + edges = [e.detach().cpu().numpy().astype(np.float32)[0, 0] for e in edges] + edges = [cv2.resize(e, (W, H), interpolation=cv2.INTER_LINEAR) for e in edges] + edges = np.stack(edges, axis=2) + edge = 1 / (1 + np.exp(-np.mean(edges, axis=2).astype(np.float64))) + if is_safe: + edge = safe_step(edge) + edge = (edge * 255.0).clip(0, 255).astype(np.uint8) + return edge + + +def unload_hed_model(): + global netNetwork + if netNetwork is not None: + netNetwork.cpu() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/keypose/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/keypose/__init__.py new file mode 100644 index 00000000..aa3dfa2e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/keypose/__init__.py @@ -0,0 +1,212 @@ +import numpy as np +import cv2 +import torch + +import os +from modules import devices +from annotator.annotator_path import models_path + +import mmcv +from mmdet.apis import inference_detector, init_detector +from mmpose.apis import inference_top_down_pose_model +from mmpose.apis import init_pose_model, process_mmdet_results, vis_pose_result + + +def preprocessing(image, device): + # Resize + scale = 640 / max(image.shape[:2]) + image = cv2.resize(image, dsize=None, fx=scale, fy=scale) + raw_image = image.astype(np.uint8) + + # Subtract mean values + image = image.astype(np.float32) + image -= np.array( + [ + float(104.008), + float(116.669), + float(122.675), + ] + ) + + # Convert to torch.Tensor and add "batch" axis + image = torch.from_numpy(image.transpose(2, 0, 1)).float().unsqueeze(0) + image = image.to(device) + + return image, raw_image + + +def imshow_keypoints(img, + pose_result, + skeleton=None, + kpt_score_thr=0.1, + pose_kpt_color=None, + pose_link_color=None, + radius=4, + thickness=1): + """Draw keypoints and links on an image. + Args: + img (ndarry): The image to draw poses on. + pose_result (list[kpts]): The poses to draw. Each element kpts is + a set of K keypoints as an Kx3 numpy.ndarray, where each + keypoint is represented as x, y, score. + kpt_score_thr (float, optional): Minimum score of keypoints + to be shown. Default: 0.3. + pose_kpt_color (np.array[Nx3]`): Color of N keypoints. If None, + the keypoint will not be drawn. + pose_link_color (np.array[Mx3]): Color of M links. If None, the + links will not be drawn. + thickness (int): Thickness of lines. + """ + + img_h, img_w, _ = img.shape + img = np.zeros(img.shape) + + for idx, kpts in enumerate(pose_result): + if idx > 1: + continue + kpts = kpts['keypoints'] + # print(kpts) + kpts = np.array(kpts, copy=False) + + # draw each point on image + if pose_kpt_color is not None: + assert len(pose_kpt_color) == len(kpts) + + for kid, kpt in enumerate(kpts): + x_coord, y_coord, kpt_score = int(kpt[0]), int(kpt[1]), kpt[2] + + if kpt_score < kpt_score_thr or pose_kpt_color[kid] is None: + # skip the point that should not be drawn + continue + + color = tuple(int(c) for c in pose_kpt_color[kid]) + cv2.circle(img, (int(x_coord), int(y_coord)), + radius, color, -1) + + # draw links + if skeleton is not None and pose_link_color is not None: + assert len(pose_link_color) == len(skeleton) + + for sk_id, sk in enumerate(skeleton): + pos1 = (int(kpts[sk[0], 0]), int(kpts[sk[0], 1])) + pos2 = (int(kpts[sk[1], 0]), int(kpts[sk[1], 1])) + + if (pos1[0] <= 0 or pos1[0] >= img_w or pos1[1] <= 0 or pos1[1] >= img_h or pos2[0] <= 0 + or pos2[0] >= img_w or pos2[1] <= 0 or pos2[1] >= img_h or kpts[sk[0], 2] < kpt_score_thr + or kpts[sk[1], 2] < kpt_score_thr or pose_link_color[sk_id] is None): + # skip the link that should not be drawn + continue + color = tuple(int(c) for c in pose_link_color[sk_id]) + cv2.line(img, pos1, pos2, color, thickness=thickness) + + return img + + +human_det, pose_model = None, None +det_model_path = "https://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_1x_coco/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth" +pose_model_path = "https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth" + +modeldir = os.path.join(models_path, "keypose") +old_modeldir = os.path.dirname(os.path.realpath(__file__)) + +det_config = 'faster_rcnn_r50_fpn_coco.py' +pose_config = 'hrnet_w48_coco_256x192.py' + +det_checkpoint = 'faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth' +pose_checkpoint = 'hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth' +det_cat_id = 1 +bbox_thr = 0.2 + +skeleton = [ + [15, 13], [13, 11], [16, 14], [14, 12], [11, 12], [5, 11], [6, 12], [5, 6], [5, 7], [6, 8], + [7, 9], [8, 10], + [1, 2], [0, 1], [0, 2], [1, 3], [2, 4], [3, 5], [4, 6] +] + +pose_kpt_color = [ + [51, 153, 255], [51, 153, 255], [51, 153, 255], [51, 153, 255], [51, 153, 255], + [0, 255, 0], + [255, 128, 0], [0, 255, 0], [255, 128, 0], [0, 255, 0], [255, 128, 0], [0, 255, 0], + [255, 128, 0], + [0, 255, 0], [255, 128, 0], [0, 255, 0], [255, 128, 0] +] + +pose_link_color = [ + [0, 255, 0], [0, 255, 0], [255, 128, 0], [255, 128, 0], + [51, 153, 255], [51, 153, 255], [51, 153, 255], [51, 153, 255], [0, 255, 0], + [255, 128, 0], + [0, 255, 0], [255, 128, 0], [51, 153, 255], [51, 153, 255], [51, 153, 255], + [51, 153, 255], + [51, 153, 255], [51, 153, 255], [51, 153, 255] +] + +def find_download_model(checkpoint, remote_path): + modelpath = os.path.join(modeldir, checkpoint) + old_modelpath = os.path.join(old_modeldir, checkpoint) + + if os.path.exists(old_modelpath): + modelpath = old_modelpath + elif not os.path.exists(modelpath): + from basicsr.utils.download_util import load_file_from_url + load_file_from_url(remote_path, model_dir=modeldir) + + return modelpath + +def apply_keypose(input_image): + global human_det, pose_model + if netNetwork is None: + det_model_local = find_download_model(det_checkpoint, det_model_path) + hrnet_model_local = find_download_model(pose_checkpoint, pose_model_path) + det_config_mmcv = mmcv.Config.fromfile(det_config) + pose_config_mmcv = mmcv.Config.fromfile(pose_config) + human_det = init_detector(det_config_mmcv, det_model_local, device=devices.get_device_for("controlnet")) + pose_model = init_pose_model(pose_config_mmcv, hrnet_model_local, device=devices.get_device_for("controlnet")) + + assert input_image.ndim == 3 + input_image = input_image.copy() + with torch.no_grad(): + image = torch.from_numpy(input_image).float().to(devices.get_device_for("controlnet")) + image = image / 255.0 + mmdet_results = inference_detector(human_det, image) + + # keep the person class bounding boxes. + person_results = process_mmdet_results(mmdet_results, det_cat_id) + + return_heatmap = False + dataset = pose_model.cfg.data['test']['type'] + + # e.g. use ('backbone', ) to return backbone feature + output_layer_names = None + pose_results, _ = inference_top_down_pose_model( + pose_model, + image, + person_results, + bbox_thr=bbox_thr, + format='xyxy', + dataset=dataset, + dataset_info=None, + return_heatmap=return_heatmap, + outputs=output_layer_names + ) + + im_keypose_out = imshow_keypoints( + image, + pose_results, + skeleton=skeleton, + pose_kpt_color=pose_kpt_color, + pose_link_color=pose_link_color, + radius=2, + thickness=2 + ) + im_keypose_out = im_keypose_out.astype(np.uint8) + + # image_hed = rearrange(image_hed, 'h w c -> 1 c h w') + # edge = netNetwork(image_hed)[0] + # edge = (edge.cpu().numpy() * 255.0).clip(0, 255).astype(np.uint8) + return im_keypose_out + + +def unload_hed_model(): + global netNetwork + if netNetwork is not None: + netNetwork.cpu() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/keypose/faster_rcnn_r50_fpn_coco.py b/extensions-builtin/sd_forge_controlnet/annotator/keypose/faster_rcnn_r50_fpn_coco.py new file mode 100644 index 00000000..a9ad9528 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/keypose/faster_rcnn_r50_fpn_coco.py @@ -0,0 +1,182 @@ +checkpoint_config = dict(interval=1) +# yapf:disable +log_config = dict( + interval=50, + hooks=[ + dict(type='TextLoggerHook'), + # dict(type='TensorboardLoggerHook') + ]) +# yapf:enable +dist_params = dict(backend='nccl') +log_level = 'INFO' +load_from = None +resume_from = None +workflow = [('train', 1)] +# optimizer +optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict( + policy='step', + warmup='linear', + warmup_iters=500, + warmup_ratio=0.001, + step=[8, 11]) +total_epochs = 12 + +model = dict( + type='FasterRCNN', + pretrained='torchvision://resnet50', + backbone=dict( + type='ResNet', + depth=50, + num_stages=4, + out_indices=(0, 1, 2, 3), + frozen_stages=1, + norm_cfg=dict(type='BN', requires_grad=True), + norm_eval=True, + style='pytorch'), + neck=dict( + type='FPN', + in_channels=[256, 512, 1024, 2048], + out_channels=256, + num_outs=5), + rpn_head=dict( + type='RPNHead', + in_channels=256, + feat_channels=256, + anchor_generator=dict( + type='AnchorGenerator', + scales=[8], + ratios=[0.5, 1.0, 2.0], + strides=[4, 8, 16, 32, 64]), + bbox_coder=dict( + type='DeltaXYWHBBoxCoder', + target_means=[.0, .0, .0, .0], + target_stds=[1.0, 1.0, 1.0, 1.0]), + loss_cls=dict( + type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0), + loss_bbox=dict(type='L1Loss', loss_weight=1.0)), + roi_head=dict( + type='StandardRoIHead', + bbox_roi_extractor=dict( + type='SingleRoIExtractor', + roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0), + out_channels=256, + featmap_strides=[4, 8, 16, 32]), + bbox_head=dict( + type='Shared2FCBBoxHead', + in_channels=256, + fc_out_channels=1024, + roi_feat_size=7, + num_classes=80, + bbox_coder=dict( + type='DeltaXYWHBBoxCoder', + target_means=[0., 0., 0., 0.], + target_stds=[0.1, 0.1, 0.2, 0.2]), + reg_class_agnostic=False, + loss_cls=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0), + loss_bbox=dict(type='L1Loss', loss_weight=1.0))), + # model training and testing settings + train_cfg=dict( + rpn=dict( + assigner=dict( + type='MaxIoUAssigner', + pos_iou_thr=0.7, + neg_iou_thr=0.3, + min_pos_iou=0.3, + match_low_quality=True, + ignore_iof_thr=-1), + sampler=dict( + type='RandomSampler', + num=256, + pos_fraction=0.5, + neg_pos_ub=-1, + add_gt_as_proposals=False), + allowed_border=-1, + pos_weight=-1, + debug=False), + rpn_proposal=dict( + nms_pre=2000, + max_per_img=1000, + nms=dict(type='nms', iou_threshold=0.7), + min_bbox_size=0), + rcnn=dict( + assigner=dict( + type='MaxIoUAssigner', + pos_iou_thr=0.5, + neg_iou_thr=0.5, + min_pos_iou=0.5, + match_low_quality=False, + ignore_iof_thr=-1), + sampler=dict( + type='RandomSampler', + num=512, + pos_fraction=0.25, + neg_pos_ub=-1, + add_gt_as_proposals=True), + pos_weight=-1, + debug=False)), + test_cfg=dict( + rpn=dict( + nms_pre=1000, + max_per_img=1000, + nms=dict(type='nms', iou_threshold=0.7), + min_bbox_size=0), + rcnn=dict( + score_thr=0.05, + nms=dict(type='nms', iou_threshold=0.5), + max_per_img=100) + # soft-nms is also supported for rcnn testing + # e.g., nms=dict(type='soft_nms', iou_threshold=0.5, min_score=0.05) + )) + +dataset_type = 'CocoDataset' +data_root = 'data/coco' +img_norm_cfg = dict( + mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations', with_bbox=True), + dict(type='Resize', img_scale=(1333, 800), keep_ratio=True), + dict(type='RandomFlip', flip_ratio=0.5), + dict(type='Normalize', **img_norm_cfg), + dict(type='Pad', size_divisor=32), + dict(type='DefaultFormatBundle'), + dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']), +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict( + type='MultiScaleFlipAug', + img_scale=(1333, 800), + flip=False, + transforms=[ + dict(type='Resize', keep_ratio=True), + dict(type='RandomFlip'), + dict(type='Normalize', **img_norm_cfg), + dict(type='Pad', size_divisor=32), + dict(type='DefaultFormatBundle'), + dict(type='Collect', keys=['img']), + ]) +] +data = dict( + samples_per_gpu=2, + workers_per_gpu=2, + train=dict( + type=dataset_type, + ann_file=f'{data_root}/annotations/instances_train2017.json', + img_prefix=f'{data_root}/train2017/', + pipeline=train_pipeline), + val=dict( + type=dataset_type, + ann_file=f'{data_root}/annotations/instances_val2017.json', + img_prefix=f'{data_root}/val2017/', + pipeline=test_pipeline), + test=dict( + type=dataset_type, + ann_file=f'{data_root}/annotations/instances_val2017.json', + img_prefix=f'{data_root}/val2017/', + pipeline=test_pipeline)) +evaluation = dict(interval=1, metric='bbox') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/keypose/hrnet_w48_coco_256x192.py b/extensions-builtin/sd_forge_controlnet/annotator/keypose/hrnet_w48_coco_256x192.py new file mode 100644 index 00000000..9755e677 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/keypose/hrnet_w48_coco_256x192.py @@ -0,0 +1,169 @@ +# _base_ = [ +# '../../../../_base_/default_runtime.py', +# '../../../../_base_/datasets/coco.py' +# ] +evaluation = dict(interval=10, metric='mAP', save_best='AP') + +optimizer = dict( + type='Adam', + lr=5e-4, +) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict( + policy='step', + warmup='linear', + warmup_iters=500, + warmup_ratio=0.001, + step=[170, 200]) +total_epochs = 210 +channel_cfg = dict( + num_output_channels=17, + dataset_joints=17, + dataset_channel=[ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + ], + inference_channel=[ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + ]) + +# model settings +model = dict( + type='TopDown', + pretrained='https://download.openmmlab.com/mmpose/' + 'pretrain_models/hrnet_w48-8ef0771d.pth', + backbone=dict( + type='HRNet', + in_channels=3, + extra=dict( + stage1=dict( + num_modules=1, + num_branches=1, + block='BOTTLENECK', + num_blocks=(4, ), + num_channels=(64, )), + stage2=dict( + num_modules=1, + num_branches=2, + block='BASIC', + num_blocks=(4, 4), + num_channels=(48, 96)), + stage3=dict( + num_modules=4, + num_branches=3, + block='BASIC', + num_blocks=(4, 4, 4), + num_channels=(48, 96, 192)), + stage4=dict( + num_modules=3, + num_branches=4, + block='BASIC', + num_blocks=(4, 4, 4, 4), + num_channels=(48, 96, 192, 384))), + ), + keypoint_head=dict( + type='TopdownHeatmapSimpleHead', + in_channels=48, + out_channels=channel_cfg['num_output_channels'], + num_deconv_layers=0, + extra=dict(final_conv_kernel=1, ), + loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True)), + train_cfg=dict(), + test_cfg=dict( + flip_test=True, + post_process='default', + shift_heatmap=True, + modulate_kernel=11)) + +data_cfg = dict( + image_size=[192, 256], + heatmap_size=[48, 64], + num_output_channels=channel_cfg['num_output_channels'], + num_joints=channel_cfg['dataset_joints'], + dataset_channel=channel_cfg['dataset_channel'], + inference_channel=channel_cfg['inference_channel'], + soft_nms=False, + nms_thr=1.0, + oks_thr=0.9, + vis_thr=0.2, + use_gt_bbox=False, + det_bbox_thr=0.0, + bbox_file='data/coco/person_detection_results/' + 'COCO_val2017_detections_AP_H_56_person.json', +) + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownGetBboxCenterScale', padding=1.25), + dict(type='TopDownRandomShiftBboxCenter', shift_factor=0.16, prob=0.3), + dict(type='TopDownRandomFlip', flip_prob=0.5), + dict( + type='TopDownHalfBodyTransform', + num_joints_half_body=8, + prob_half_body=0.3), + dict( + type='TopDownGetRandomScaleRotation', rot_factor=40, scale_factor=0.5), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict(type='TopDownGenerateTarget', sigma=2), + dict( + type='Collect', + keys=['img', 'target', 'target_weight'], + meta_keys=[ + 'image_file', 'joints_3d', 'joints_3d_visible', 'center', 'scale', + 'rotation', 'bbox_score', 'flip_pairs' + ]), +] + +val_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownGetBboxCenterScale', padding=1.25), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict( + type='Collect', + keys=['img'], + meta_keys=[ + 'image_file', 'center', 'scale', 'rotation', 'bbox_score', + 'flip_pairs' + ]), +] + +test_pipeline = val_pipeline + +data_root = 'data/coco' +data = dict( + samples_per_gpu=32, + workers_per_gpu=2, + val_dataloader=dict(samples_per_gpu=32), + test_dataloader=dict(samples_per_gpu=32), + train=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/person_keypoints_train2017.json', + img_prefix=f'{data_root}/train2017/', + data_cfg=data_cfg, + pipeline=train_pipeline, + dataset_info={{_base_.dataset_info}}), + val=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/person_keypoints_val2017.json', + img_prefix=f'{data_root}/val2017/', + data_cfg=data_cfg, + pipeline=val_pipeline, + dataset_info={{_base_.dataset_info}}), + test=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/person_keypoints_val2017.json', + img_prefix=f'{data_root}/val2017/', + data_cfg=data_cfg, + pipeline=test_pipeline, + dataset_info={{_base_.dataset_info}}), +) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/__init__.py new file mode 100644 index 00000000..a7784a38 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/__init__.py @@ -0,0 +1,58 @@ +# https://github.com/advimman/lama + +import yaml +import torch +from omegaconf import OmegaConf +import numpy as np + +from einops import rearrange +import os +from modules import devices +from annotator.annotator_path import models_path +from annotator.lama.saicinpainting.training.trainers import load_checkpoint + + +class LamaInpainting: + model_dir = os.path.join(models_path, "lama") + + def __init__(self): + self.model = None + self.device = devices.get_device_for("controlnet") + + def load_model(self): + remote_model_path = "https://huggingface.co/lllyasviel/Annotators/resolve/main/ControlNetLama.pth" + modelpath = os.path.join(self.model_dir, "ControlNetLama.pth") + if not os.path.exists(modelpath): + from basicsr.utils.download_util import load_file_from_url + load_file_from_url(remote_model_path, model_dir=self.model_dir) + config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config.yaml') + cfg = yaml.safe_load(open(config_path, 'rt')) + cfg = OmegaConf.create(cfg) + cfg.training_model.predict_only = True + cfg.visualizer.kind = 'noop' + self.model = load_checkpoint(cfg, os.path.abspath(modelpath), strict=False, map_location='cpu') + self.model = self.model.to(self.device) + self.model.eval() + + def unload_model(self): + if self.model is not None: + self.model.cpu() + + def __call__(self, input_image): + if self.model is None: + self.load_model() + self.model.to(self.device) + color = np.ascontiguousarray(input_image[:, :, 0:3]).astype(np.float32) / 255.0 + mask = np.ascontiguousarray(input_image[:, :, 3:4]).astype(np.float32) / 255.0 + with torch.no_grad(): + color = torch.from_numpy(color).float().to(self.device) + mask = torch.from_numpy(mask).float().to(self.device) + mask = (mask > 0.5).float() + color = color * (1 - mask) + image_feed = torch.cat([color, mask], dim=2) + image_feed = rearrange(image_feed, 'h w c -> 1 c h w') + result = self.model(image_feed)[0] + result = rearrange(result, 'c h w -> h w c') + result = result * mask + color * (1 - mask) + result *= 255.0 + return result.detach().cpu().numpy().clip(0, 255).astype(np.uint8) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/config.yaml b/extensions-builtin/sd_forge_controlnet/annotator/lama/config.yaml new file mode 100644 index 00000000..55fd91b5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/config.yaml @@ -0,0 +1,157 @@ +run_title: b18_ffc075_batch8x15 +training_model: + kind: default + visualize_each_iters: 1000 + concat_mask: true + store_discr_outputs_for_vis: true +losses: + l1: + weight_missing: 0 + weight_known: 10 + perceptual: + weight: 0 + adversarial: + kind: r1 + weight: 10 + gp_coef: 0.001 + mask_as_fake_target: true + allow_scale_mask: true + feature_matching: + weight: 100 + resnet_pl: + weight: 30 + weights_path: ${env:TORCH_HOME} + +optimizers: + generator: + kind: adam + lr: 0.001 + discriminator: + kind: adam + lr: 0.0001 +visualizer: + key_order: + - image + - predicted_image + - discr_output_fake + - discr_output_real + - inpainted + rescale_keys: + - discr_output_fake + - discr_output_real + kind: directory + outdir: /group-volume/User-Driven-Content-Generation/r.suvorov/inpainting/experiments/r.suvorov_2021-04-30_14-41-12_train_simple_pix2pix2_gap_sdpl_novgg_large_b18_ffc075_batch8x15/samples +location: + data_root_dir: /group-volume/User-Driven-Content-Generation/datasets/inpainting_data_root_large + out_root_dir: /group-volume/User-Driven-Content-Generation/${env:USER}/inpainting/experiments + tb_dir: /group-volume/User-Driven-Content-Generation/${env:USER}/inpainting/tb_logs +data: + batch_size: 15 + val_batch_size: 2 + num_workers: 3 + train: + indir: ${location.data_root_dir}/train + out_size: 256 + mask_gen_kwargs: + irregular_proba: 1 + irregular_kwargs: + max_angle: 4 + max_len: 200 + max_width: 100 + max_times: 5 + min_times: 1 + box_proba: 1 + box_kwargs: + margin: 10 + bbox_min_size: 30 + bbox_max_size: 150 + max_times: 3 + min_times: 1 + segm_proba: 0 + segm_kwargs: + confidence_threshold: 0.5 + max_object_area: 0.5 + min_mask_area: 0.07 + downsample_levels: 6 + num_variants_per_mask: 1 + rigidness_mode: 1 + max_foreground_coverage: 0.3 + max_foreground_intersection: 0.7 + max_mask_intersection: 0.1 + max_hidden_area: 0.1 + max_scale_change: 0.25 + horizontal_flip: true + max_vertical_shift: 0.2 + position_shuffle: true + transform_variant: distortions + dataloader_kwargs: + batch_size: ${data.batch_size} + shuffle: true + num_workers: ${data.num_workers} + val: + indir: ${location.data_root_dir}/val + img_suffix: .png + dataloader_kwargs: + batch_size: ${data.val_batch_size} + shuffle: false + num_workers: ${data.num_workers} + visual_test: + indir: ${location.data_root_dir}/korean_test + img_suffix: _input.png + pad_out_to_modulo: 32 + dataloader_kwargs: + batch_size: 1 + shuffle: false + num_workers: ${data.num_workers} +generator: + kind: ffc_resnet + input_nc: 4 + output_nc: 3 + ngf: 64 + n_downsampling: 3 + n_blocks: 18 + add_out_act: sigmoid + init_conv_kwargs: + ratio_gin: 0 + ratio_gout: 0 + enable_lfu: false + downsample_conv_kwargs: + ratio_gin: ${generator.init_conv_kwargs.ratio_gout} + ratio_gout: ${generator.downsample_conv_kwargs.ratio_gin} + enable_lfu: false + resnet_conv_kwargs: + ratio_gin: 0.75 + ratio_gout: ${generator.resnet_conv_kwargs.ratio_gin} + enable_lfu: false +discriminator: + kind: pix2pixhd_nlayer + input_nc: 3 + ndf: 64 + n_layers: 4 +evaluator: + kind: default + inpainted_key: inpainted + integral_kind: ssim_fid100_f1 +trainer: + kwargs: + gpus: -1 + accelerator: ddp + max_epochs: 200 + gradient_clip_val: 1 + log_gpu_memory: None + limit_train_batches: 25000 + val_check_interval: ${trainer.kwargs.limit_train_batches} + log_every_n_steps: 1000 + precision: 32 + terminate_on_nan: false + check_val_every_n_epoch: 1 + num_sanity_val_steps: 8 + limit_val_batches: 1000 + replace_sampler_ddp: false + checkpoint_kwargs: + verbose: true + save_top_k: 5 + save_last: true + period: 1 + monitor: val_ssim_fid100_f1_total_mean + mode: max diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/data/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/data/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/data/masks.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/data/masks.py new file mode 100644 index 00000000..27cb9050 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/data/masks.py @@ -0,0 +1,332 @@ +import math +import random +import hashlib +import logging +from enum import Enum + +import cv2 +import numpy as np + +# from annotator.lama.saicinpainting.evaluation.masks.mask import SegmentationMask +from annotator.lama.saicinpainting.utils import LinearRamp + +LOGGER = logging.getLogger(__name__) + + +class DrawMethod(Enum): + LINE = 'line' + CIRCLE = 'circle' + SQUARE = 'square' + + +def make_random_irregular_mask(shape, max_angle=4, max_len=60, max_width=20, min_times=0, max_times=10, + draw_method=DrawMethod.LINE): + draw_method = DrawMethod(draw_method) + + height, width = shape + mask = np.zeros((height, width), np.float32) + times = np.random.randint(min_times, max_times + 1) + for i in range(times): + start_x = np.random.randint(width) + start_y = np.random.randint(height) + for j in range(1 + np.random.randint(5)): + angle = 0.01 + np.random.randint(max_angle) + if i % 2 == 0: + angle = 2 * 3.1415926 - angle + length = 10 + np.random.randint(max_len) + brush_w = 5 + np.random.randint(max_width) + end_x = np.clip((start_x + length * np.sin(angle)).astype(np.int32), 0, width) + end_y = np.clip((start_y + length * np.cos(angle)).astype(np.int32), 0, height) + if draw_method == DrawMethod.LINE: + cv2.line(mask, (start_x, start_y), (end_x, end_y), 1.0, brush_w) + elif draw_method == DrawMethod.CIRCLE: + cv2.circle(mask, (start_x, start_y), radius=brush_w, color=1., thickness=-1) + elif draw_method == DrawMethod.SQUARE: + radius = brush_w // 2 + mask[start_y - radius:start_y + radius, start_x - radius:start_x + radius] = 1 + start_x, start_y = end_x, end_y + return mask[None, ...] + + +class RandomIrregularMaskGenerator: + def __init__(self, max_angle=4, max_len=60, max_width=20, min_times=0, max_times=10, ramp_kwargs=None, + draw_method=DrawMethod.LINE): + self.max_angle = max_angle + self.max_len = max_len + self.max_width = max_width + self.min_times = min_times + self.max_times = max_times + self.draw_method = draw_method + self.ramp = LinearRamp(**ramp_kwargs) if ramp_kwargs is not None else None + + def __call__(self, img, iter_i=None, raw_image=None): + coef = self.ramp(iter_i) if (self.ramp is not None) and (iter_i is not None) else 1 + cur_max_len = int(max(1, self.max_len * coef)) + cur_max_width = int(max(1, self.max_width * coef)) + cur_max_times = int(self.min_times + 1 + (self.max_times - self.min_times) * coef) + return make_random_irregular_mask(img.shape[1:], max_angle=self.max_angle, max_len=cur_max_len, + max_width=cur_max_width, min_times=self.min_times, max_times=cur_max_times, + draw_method=self.draw_method) + + +def make_random_rectangle_mask(shape, margin=10, bbox_min_size=30, bbox_max_size=100, min_times=0, max_times=3): + height, width = shape + mask = np.zeros((height, width), np.float32) + bbox_max_size = min(bbox_max_size, height - margin * 2, width - margin * 2) + times = np.random.randint(min_times, max_times + 1) + for i in range(times): + box_width = np.random.randint(bbox_min_size, bbox_max_size) + box_height = np.random.randint(bbox_min_size, bbox_max_size) + start_x = np.random.randint(margin, width - margin - box_width + 1) + start_y = np.random.randint(margin, height - margin - box_height + 1) + mask[start_y:start_y + box_height, start_x:start_x + box_width] = 1 + return mask[None, ...] + + +class RandomRectangleMaskGenerator: + def __init__(self, margin=10, bbox_min_size=30, bbox_max_size=100, min_times=0, max_times=3, ramp_kwargs=None): + self.margin = margin + self.bbox_min_size = bbox_min_size + self.bbox_max_size = bbox_max_size + self.min_times = min_times + self.max_times = max_times + self.ramp = LinearRamp(**ramp_kwargs) if ramp_kwargs is not None else None + + def __call__(self, img, iter_i=None, raw_image=None): + coef = self.ramp(iter_i) if (self.ramp is not None) and (iter_i is not None) else 1 + cur_bbox_max_size = int(self.bbox_min_size + 1 + (self.bbox_max_size - self.bbox_min_size) * coef) + cur_max_times = int(self.min_times + (self.max_times - self.min_times) * coef) + return make_random_rectangle_mask(img.shape[1:], margin=self.margin, bbox_min_size=self.bbox_min_size, + bbox_max_size=cur_bbox_max_size, min_times=self.min_times, + max_times=cur_max_times) + + +class RandomSegmentationMaskGenerator: + def __init__(self, **kwargs): + self.impl = None # will be instantiated in first call (effectively in subprocess) + self.kwargs = kwargs + + def __call__(self, img, iter_i=None, raw_image=None): + if self.impl is None: + self.impl = SegmentationMask(**self.kwargs) + + masks = self.impl.get_masks(np.transpose(img, (1, 2, 0))) + masks = [m for m in masks if len(np.unique(m)) > 1] + return np.random.choice(masks) + + +def make_random_superres_mask(shape, min_step=2, max_step=4, min_width=1, max_width=3): + height, width = shape + mask = np.zeros((height, width), np.float32) + step_x = np.random.randint(min_step, max_step + 1) + width_x = np.random.randint(min_width, min(step_x, max_width + 1)) + offset_x = np.random.randint(0, step_x) + + step_y = np.random.randint(min_step, max_step + 1) + width_y = np.random.randint(min_width, min(step_y, max_width + 1)) + offset_y = np.random.randint(0, step_y) + + for dy in range(width_y): + mask[offset_y + dy::step_y] = 1 + for dx in range(width_x): + mask[:, offset_x + dx::step_x] = 1 + return mask[None, ...] + + +class RandomSuperresMaskGenerator: + def __init__(self, **kwargs): + self.kwargs = kwargs + + def __call__(self, img, iter_i=None): + return make_random_superres_mask(img.shape[1:], **self.kwargs) + + +class DumbAreaMaskGenerator: + min_ratio = 0.1 + max_ratio = 0.35 + default_ratio = 0.225 + + def __init__(self, is_training): + #Parameters: + # is_training(bool): If true - random rectangular mask, if false - central square mask + self.is_training = is_training + + def _random_vector(self, dimension): + if self.is_training: + lower_limit = math.sqrt(self.min_ratio) + upper_limit = math.sqrt(self.max_ratio) + mask_side = round((random.random() * (upper_limit - lower_limit) + lower_limit) * dimension) + u = random.randint(0, dimension-mask_side-1) + v = u+mask_side + else: + margin = (math.sqrt(self.default_ratio) / 2) * dimension + u = round(dimension/2 - margin) + v = round(dimension/2 + margin) + return u, v + + def __call__(self, img, iter_i=None, raw_image=None): + c, height, width = img.shape + mask = np.zeros((height, width), np.float32) + x1, x2 = self._random_vector(width) + y1, y2 = self._random_vector(height) + mask[x1:x2, y1:y2] = 1 + return mask[None, ...] + + +class OutpaintingMaskGenerator: + def __init__(self, min_padding_percent:float=0.04, max_padding_percent:int=0.25, left_padding_prob:float=0.5, top_padding_prob:float=0.5, + right_padding_prob:float=0.5, bottom_padding_prob:float=0.5, is_fixed_randomness:bool=False): + """ + is_fixed_randomness - get identical paddings for the same image if args are the same + """ + self.min_padding_percent = min_padding_percent + self.max_padding_percent = max_padding_percent + self.probs = [left_padding_prob, top_padding_prob, right_padding_prob, bottom_padding_prob] + self.is_fixed_randomness = is_fixed_randomness + + assert self.min_padding_percent <= self.max_padding_percent + assert self.max_padding_percent > 0 + assert len([x for x in [self.min_padding_percent, self.max_padding_percent] if (x>=0 and x<=1)]) == 2, f"Padding percentage should be in [0,1]" + assert sum(self.probs) > 0, f"At least one of the padding probs should be greater than 0 - {self.probs}" + assert len([x for x in self.probs if (x >= 0) and (x <= 1)]) == 4, f"At least one of padding probs is not in [0,1] - {self.probs}" + if len([x for x in self.probs if x > 0]) == 1: + LOGGER.warning(f"Only one padding prob is greater than zero - {self.probs}. That means that the outpainting masks will be always on the same side") + + def apply_padding(self, mask, coord): + mask[int(coord[0][0]*self.img_h):int(coord[1][0]*self.img_h), + int(coord[0][1]*self.img_w):int(coord[1][1]*self.img_w)] = 1 + return mask + + def get_padding(self, size): + n1 = int(self.min_padding_percent*size) + n2 = int(self.max_padding_percent*size) + return self.rnd.randint(n1, n2) / size + + @staticmethod + def _img2rs(img): + arr = np.ascontiguousarray(img.astype(np.uint8)) + str_hash = hashlib.sha1(arr).hexdigest() + res = hash(str_hash)%(2**32) + return res + + def __call__(self, img, iter_i=None, raw_image=None): + c, self.img_h, self.img_w = img.shape + mask = np.zeros((self.img_h, self.img_w), np.float32) + at_least_one_mask_applied = False + + if self.is_fixed_randomness: + assert raw_image is not None, f"Cant calculate hash on raw_image=None" + rs = self._img2rs(raw_image) + self.rnd = np.random.RandomState(rs) + else: + self.rnd = np.random + + coords = [[ + (0,0), + (1,self.get_padding(size=self.img_h)) + ], + [ + (0,0), + (self.get_padding(size=self.img_w),1) + ], + [ + (0,1-self.get_padding(size=self.img_h)), + (1,1) + ], + [ + (1-self.get_padding(size=self.img_w),0), + (1,1) + ]] + + for pp, coord in zip(self.probs, coords): + if self.rnd.random() < pp: + at_least_one_mask_applied = True + mask = self.apply_padding(mask=mask, coord=coord) + + if not at_least_one_mask_applied: + idx = self.rnd.choice(range(len(coords)), p=np.array(self.probs)/sum(self.probs)) + mask = self.apply_padding(mask=mask, coord=coords[idx]) + return mask[None, ...] + + +class MixedMaskGenerator: + def __init__(self, irregular_proba=1/3, irregular_kwargs=None, + box_proba=1/3, box_kwargs=None, + segm_proba=1/3, segm_kwargs=None, + squares_proba=0, squares_kwargs=None, + superres_proba=0, superres_kwargs=None, + outpainting_proba=0, outpainting_kwargs=None, + invert_proba=0): + self.probas = [] + self.gens = [] + + if irregular_proba > 0: + self.probas.append(irregular_proba) + if irregular_kwargs is None: + irregular_kwargs = {} + else: + irregular_kwargs = dict(irregular_kwargs) + irregular_kwargs['draw_method'] = DrawMethod.LINE + self.gens.append(RandomIrregularMaskGenerator(**irregular_kwargs)) + + if box_proba > 0: + self.probas.append(box_proba) + if box_kwargs is None: + box_kwargs = {} + self.gens.append(RandomRectangleMaskGenerator(**box_kwargs)) + + if segm_proba > 0: + self.probas.append(segm_proba) + if segm_kwargs is None: + segm_kwargs = {} + self.gens.append(RandomSegmentationMaskGenerator(**segm_kwargs)) + + if squares_proba > 0: + self.probas.append(squares_proba) + if squares_kwargs is None: + squares_kwargs = {} + else: + squares_kwargs = dict(squares_kwargs) + squares_kwargs['draw_method'] = DrawMethod.SQUARE + self.gens.append(RandomIrregularMaskGenerator(**squares_kwargs)) + + if superres_proba > 0: + self.probas.append(superres_proba) + if superres_kwargs is None: + superres_kwargs = {} + self.gens.append(RandomSuperresMaskGenerator(**superres_kwargs)) + + if outpainting_proba > 0: + self.probas.append(outpainting_proba) + if outpainting_kwargs is None: + outpainting_kwargs = {} + self.gens.append(OutpaintingMaskGenerator(**outpainting_kwargs)) + + self.probas = np.array(self.probas, dtype='float32') + self.probas /= self.probas.sum() + self.invert_proba = invert_proba + + def __call__(self, img, iter_i=None, raw_image=None): + kind = np.random.choice(len(self.probas), p=self.probas) + gen = self.gens[kind] + result = gen(img, iter_i=iter_i, raw_image=raw_image) + if self.invert_proba > 0 and random.random() < self.invert_proba: + result = 1 - result + return result + + +def get_mask_generator(kind, kwargs): + if kind is None: + kind = "mixed" + if kwargs is None: + kwargs = {} + + if kind == "mixed": + cl = MixedMaskGenerator + elif kind == "outpainting": + cl = OutpaintingMaskGenerator + elif kind == "dumb": + cl = DumbAreaMaskGenerator + else: + raise NotImplementedError(f"No such generator kind = {kind}") + return cl(**kwargs) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/adversarial.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/adversarial.py new file mode 100644 index 00000000..d6db2967 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/adversarial.py @@ -0,0 +1,177 @@ +from typing import Tuple, Dict, Optional + +import torch +import torch.nn as nn +import torch.nn.functional as F + + +class BaseAdversarialLoss: + def pre_generator_step(self, real_batch: torch.Tensor, fake_batch: torch.Tensor, + generator: nn.Module, discriminator: nn.Module): + """ + Prepare for generator step + :param real_batch: Tensor, a batch of real samples + :param fake_batch: Tensor, a batch of samples produced by generator + :param generator: + :param discriminator: + :return: None + """ + + def pre_discriminator_step(self, real_batch: torch.Tensor, fake_batch: torch.Tensor, + generator: nn.Module, discriminator: nn.Module): + """ + Prepare for discriminator step + :param real_batch: Tensor, a batch of real samples + :param fake_batch: Tensor, a batch of samples produced by generator + :param generator: + :param discriminator: + :return: None + """ + + def generator_loss(self, real_batch: torch.Tensor, fake_batch: torch.Tensor, + discr_real_pred: torch.Tensor, discr_fake_pred: torch.Tensor, + mask: Optional[torch.Tensor] = None) \ + -> Tuple[torch.Tensor, Dict[str, torch.Tensor]]: + """ + Calculate generator loss + :param real_batch: Tensor, a batch of real samples + :param fake_batch: Tensor, a batch of samples produced by generator + :param discr_real_pred: Tensor, discriminator output for real_batch + :param discr_fake_pred: Tensor, discriminator output for fake_batch + :param mask: Tensor, actual mask, which was at input of generator when making fake_batch + :return: total generator loss along with some values that might be interesting to log + """ + raise NotImplemented() + + def discriminator_loss(self, real_batch: torch.Tensor, fake_batch: torch.Tensor, + discr_real_pred: torch.Tensor, discr_fake_pred: torch.Tensor, + mask: Optional[torch.Tensor] = None) \ + -> Tuple[torch.Tensor, Dict[str, torch.Tensor]]: + """ + Calculate discriminator loss and call .backward() on it + :param real_batch: Tensor, a batch of real samples + :param fake_batch: Tensor, a batch of samples produced by generator + :param discr_real_pred: Tensor, discriminator output for real_batch + :param discr_fake_pred: Tensor, discriminator output for fake_batch + :param mask: Tensor, actual mask, which was at input of generator when making fake_batch + :return: total discriminator loss along with some values that might be interesting to log + """ + raise NotImplemented() + + def interpolate_mask(self, mask, shape): + assert mask is not None + assert self.allow_scale_mask or shape == mask.shape[-2:] + if shape != mask.shape[-2:] and self.allow_scale_mask: + if self.mask_scale_mode == 'maxpool': + mask = F.adaptive_max_pool2d(mask, shape) + else: + mask = F.interpolate(mask, size=shape, mode=self.mask_scale_mode) + return mask + +def make_r1_gp(discr_real_pred, real_batch): + if torch.is_grad_enabled(): + grad_real = torch.autograd.grad(outputs=discr_real_pred.sum(), inputs=real_batch, create_graph=True)[0] + grad_penalty = (grad_real.view(grad_real.shape[0], -1).norm(2, dim=1) ** 2).mean() + else: + grad_penalty = 0 + real_batch.requires_grad = False + + return grad_penalty + +class NonSaturatingWithR1(BaseAdversarialLoss): + def __init__(self, gp_coef=5, weight=1, mask_as_fake_target=False, allow_scale_mask=False, + mask_scale_mode='nearest', extra_mask_weight_for_gen=0, + use_unmasked_for_gen=True, use_unmasked_for_discr=True): + self.gp_coef = gp_coef + self.weight = weight + # use for discr => use for gen; + # otherwise we teach only the discr to pay attention to very small difference + assert use_unmasked_for_gen or (not use_unmasked_for_discr) + # mask as target => use unmasked for discr: + # if we don't care about unmasked regions at all + # then it doesn't matter if the value of mask_as_fake_target is true or false + assert use_unmasked_for_discr or (not mask_as_fake_target) + self.use_unmasked_for_gen = use_unmasked_for_gen + self.use_unmasked_for_discr = use_unmasked_for_discr + self.mask_as_fake_target = mask_as_fake_target + self.allow_scale_mask = allow_scale_mask + self.mask_scale_mode = mask_scale_mode + self.extra_mask_weight_for_gen = extra_mask_weight_for_gen + + def generator_loss(self, real_batch: torch.Tensor, fake_batch: torch.Tensor, + discr_real_pred: torch.Tensor, discr_fake_pred: torch.Tensor, + mask=None) \ + -> Tuple[torch.Tensor, Dict[str, torch.Tensor]]: + fake_loss = F.softplus(-discr_fake_pred) + if (self.mask_as_fake_target and self.extra_mask_weight_for_gen > 0) or \ + not self.use_unmasked_for_gen: # == if masked region should be treated differently + mask = self.interpolate_mask(mask, discr_fake_pred.shape[-2:]) + if not self.use_unmasked_for_gen: + fake_loss = fake_loss * mask + else: + pixel_weights = 1 + mask * self.extra_mask_weight_for_gen + fake_loss = fake_loss * pixel_weights + + return fake_loss.mean() * self.weight, dict() + + def pre_discriminator_step(self, real_batch: torch.Tensor, fake_batch: torch.Tensor, + generator: nn.Module, discriminator: nn.Module): + real_batch.requires_grad = True + + def discriminator_loss(self, real_batch: torch.Tensor, fake_batch: torch.Tensor, + discr_real_pred: torch.Tensor, discr_fake_pred: torch.Tensor, + mask=None) \ + -> Tuple[torch.Tensor, Dict[str, torch.Tensor]]: + + real_loss = F.softplus(-discr_real_pred) + grad_penalty = make_r1_gp(discr_real_pred, real_batch) * self.gp_coef + fake_loss = F.softplus(discr_fake_pred) + + if not self.use_unmasked_for_discr or self.mask_as_fake_target: + # == if masked region should be treated differently + mask = self.interpolate_mask(mask, discr_fake_pred.shape[-2:]) + # use_unmasked_for_discr=False only makes sense for fakes; + # for reals there is no difference beetween two regions + fake_loss = fake_loss * mask + if self.mask_as_fake_target: + fake_loss = fake_loss + (1 - mask) * F.softplus(-discr_fake_pred) + + sum_discr_loss = real_loss + grad_penalty + fake_loss + metrics = dict(discr_real_out=discr_real_pred.mean(), + discr_fake_out=discr_fake_pred.mean(), + discr_real_gp=grad_penalty) + return sum_discr_loss.mean(), metrics + +class BCELoss(BaseAdversarialLoss): + def __init__(self, weight): + self.weight = weight + self.bce_loss = nn.BCEWithLogitsLoss() + + def generator_loss(self, discr_fake_pred: torch.Tensor) -> Tuple[torch.Tensor, Dict[str, torch.Tensor]]: + real_mask_gt = torch.zeros(discr_fake_pred.shape).to(discr_fake_pred.device) + fake_loss = self.bce_loss(discr_fake_pred, real_mask_gt) * self.weight + return fake_loss, dict() + + def pre_discriminator_step(self, real_batch: torch.Tensor, fake_batch: torch.Tensor, + generator: nn.Module, discriminator: nn.Module): + real_batch.requires_grad = True + + def discriminator_loss(self, + mask: torch.Tensor, + discr_real_pred: torch.Tensor, + discr_fake_pred: torch.Tensor) -> Tuple[torch.Tensor, Dict[str, torch.Tensor]]: + + real_mask_gt = torch.zeros(discr_real_pred.shape).to(discr_real_pred.device) + sum_discr_loss = (self.bce_loss(discr_real_pred, real_mask_gt) + self.bce_loss(discr_fake_pred, mask)) / 2 + metrics = dict(discr_real_out=discr_real_pred.mean(), + discr_fake_out=discr_fake_pred.mean(), + discr_real_gp=0) + return sum_discr_loss, metrics + + +def make_discrim_loss(kind, **kwargs): + if kind == 'r1': + return NonSaturatingWithR1(**kwargs) + elif kind == 'bce': + return BCELoss(**kwargs) + raise ValueError(f'Unknown adversarial loss kind {kind}') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/constants.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/constants.py new file mode 100644 index 00000000..ae3e5e15 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/constants.py @@ -0,0 +1,152 @@ +weights = {"ade20k": + [6.34517766497462, + 9.328358208955224, + 11.389521640091116, + 16.10305958132045, + 20.833333333333332, + 22.22222222222222, + 25.125628140703515, + 43.29004329004329, + 50.5050505050505, + 54.6448087431694, + 55.24861878453038, + 60.24096385542168, + 62.5, + 66.2251655629139, + 84.74576271186442, + 90.90909090909092, + 91.74311926605505, + 96.15384615384616, + 96.15384615384616, + 97.08737864077669, + 102.04081632653062, + 135.13513513513513, + 149.2537313432836, + 153.84615384615384, + 163.93442622950818, + 166.66666666666666, + 188.67924528301887, + 192.30769230769232, + 217.3913043478261, + 227.27272727272725, + 227.27272727272725, + 227.27272727272725, + 303.03030303030306, + 322.5806451612903, + 333.3333333333333, + 370.3703703703703, + 384.61538461538464, + 416.6666666666667, + 416.6666666666667, + 434.7826086956522, + 434.7826086956522, + 454.5454545454545, + 454.5454545454545, + 500.0, + 526.3157894736842, + 526.3157894736842, + 555.5555555555555, + 555.5555555555555, + 555.5555555555555, + 555.5555555555555, + 555.5555555555555, + 555.5555555555555, + 555.5555555555555, + 588.2352941176471, + 588.2352941176471, + 588.2352941176471, + 588.2352941176471, + 588.2352941176471, + 666.6666666666666, + 666.6666666666666, + 666.6666666666666, + 666.6666666666666, + 714.2857142857143, + 714.2857142857143, + 714.2857142857143, + 714.2857142857143, + 714.2857142857143, + 769.2307692307693, + 769.2307692307693, + 769.2307692307693, + 833.3333333333334, + 833.3333333333334, + 833.3333333333334, + 833.3333333333334, + 909.090909090909, + 1000.0, + 1111.111111111111, + 1111.111111111111, + 1111.111111111111, + 1111.111111111111, + 1111.111111111111, + 1250.0, + 1250.0, + 1250.0, + 1250.0, + 1250.0, + 1428.5714285714287, + 1428.5714285714287, + 1428.5714285714287, + 1428.5714285714287, + 1428.5714285714287, + 1428.5714285714287, + 1428.5714285714287, + 1666.6666666666667, + 1666.6666666666667, + 1666.6666666666667, + 1666.6666666666667, + 1666.6666666666667, + 1666.6666666666667, + 1666.6666666666667, + 1666.6666666666667, + 1666.6666666666667, + 1666.6666666666667, + 1666.6666666666667, + 2000.0, + 2000.0, + 2000.0, + 2000.0, + 2000.0, + 2000.0, + 2000.0, + 2000.0, + 2000.0, + 2000.0, + 2000.0, + 2000.0, + 2000.0, + 2000.0, + 2000.0, + 2000.0, + 2000.0, + 2500.0, + 2500.0, + 2500.0, + 2500.0, + 2500.0, + 2500.0, + 2500.0, + 2500.0, + 2500.0, + 2500.0, + 2500.0, + 2500.0, + 2500.0, + 3333.3333333333335, + 3333.3333333333335, + 3333.3333333333335, + 3333.3333333333335, + 3333.3333333333335, + 3333.3333333333335, + 3333.3333333333335, + 3333.3333333333335, + 3333.3333333333335, + 3333.3333333333335, + 3333.3333333333335, + 3333.3333333333335, + 3333.3333333333335, + 5000.0, + 5000.0, + 5000.0] +} \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/distance_weighting.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/distance_weighting.py new file mode 100644 index 00000000..90ce05be --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/distance_weighting.py @@ -0,0 +1,126 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +import torchvision + +from annotator.lama.saicinpainting.training.losses.perceptual import IMAGENET_STD, IMAGENET_MEAN + + +def dummy_distance_weighter(real_img, pred_img, mask): + return mask + + +def get_gauss_kernel(kernel_size, width_factor=1): + coords = torch.stack(torch.meshgrid(torch.arange(kernel_size), + torch.arange(kernel_size)), + dim=0).float() + diff = torch.exp(-((coords - kernel_size // 2) ** 2).sum(0) / kernel_size / width_factor) + diff /= diff.sum() + return diff + + +class BlurMask(nn.Module): + def __init__(self, kernel_size=5, width_factor=1): + super().__init__() + self.filter = nn.Conv2d(1, 1, kernel_size, padding=kernel_size // 2, padding_mode='replicate', bias=False) + self.filter.weight.data.copy_(get_gauss_kernel(kernel_size, width_factor=width_factor)) + + def forward(self, real_img, pred_img, mask): + with torch.no_grad(): + result = self.filter(mask) * mask + return result + + +class EmulatedEDTMask(nn.Module): + def __init__(self, dilate_kernel_size=5, blur_kernel_size=5, width_factor=1): + super().__init__() + self.dilate_filter = nn.Conv2d(1, 1, dilate_kernel_size, padding=dilate_kernel_size// 2, padding_mode='replicate', + bias=False) + self.dilate_filter.weight.data.copy_(torch.ones(1, 1, dilate_kernel_size, dilate_kernel_size, dtype=torch.float)) + self.blur_filter = nn.Conv2d(1, 1, blur_kernel_size, padding=blur_kernel_size // 2, padding_mode='replicate', bias=False) + self.blur_filter.weight.data.copy_(get_gauss_kernel(blur_kernel_size, width_factor=width_factor)) + + def forward(self, real_img, pred_img, mask): + with torch.no_grad(): + known_mask = 1 - mask + dilated_known_mask = (self.dilate_filter(known_mask) > 1).float() + result = self.blur_filter(1 - dilated_known_mask) * mask + return result + + +class PropagatePerceptualSim(nn.Module): + def __init__(self, level=2, max_iters=10, temperature=500, erode_mask_size=3): + super().__init__() + vgg = torchvision.models.vgg19(pretrained=True).features + vgg_avg_pooling = [] + + for weights in vgg.parameters(): + weights.requires_grad = False + + cur_level_i = 0 + for module in vgg.modules(): + if module.__class__.__name__ == 'Sequential': + continue + elif module.__class__.__name__ == 'MaxPool2d': + vgg_avg_pooling.append(nn.AvgPool2d(kernel_size=2, stride=2, padding=0)) + else: + vgg_avg_pooling.append(module) + if module.__class__.__name__ == 'ReLU': + cur_level_i += 1 + if cur_level_i == level: + break + + self.features = nn.Sequential(*vgg_avg_pooling) + + self.max_iters = max_iters + self.temperature = temperature + self.do_erode = erode_mask_size > 0 + if self.do_erode: + self.erode_mask = nn.Conv2d(1, 1, erode_mask_size, padding=erode_mask_size // 2, bias=False) + self.erode_mask.weight.data.fill_(1) + + def forward(self, real_img, pred_img, mask): + with torch.no_grad(): + real_img = (real_img - IMAGENET_MEAN.to(real_img)) / IMAGENET_STD.to(real_img) + real_feats = self.features(real_img) + + vertical_sim = torch.exp(-(real_feats[:, :, 1:] - real_feats[:, :, :-1]).pow(2).sum(1, keepdim=True) + / self.temperature) + horizontal_sim = torch.exp(-(real_feats[:, :, :, 1:] - real_feats[:, :, :, :-1]).pow(2).sum(1, keepdim=True) + / self.temperature) + + mask_scaled = F.interpolate(mask, size=real_feats.shape[-2:], mode='bilinear', align_corners=False) + if self.do_erode: + mask_scaled = (self.erode_mask(mask_scaled) > 1).float() + + cur_knowness = 1 - mask_scaled + + for iter_i in range(self.max_iters): + new_top_knowness = F.pad(cur_knowness[:, :, :-1] * vertical_sim, (0, 0, 1, 0), mode='replicate') + new_bottom_knowness = F.pad(cur_knowness[:, :, 1:] * vertical_sim, (0, 0, 0, 1), mode='replicate') + + new_left_knowness = F.pad(cur_knowness[:, :, :, :-1] * horizontal_sim, (1, 0, 0, 0), mode='replicate') + new_right_knowness = F.pad(cur_knowness[:, :, :, 1:] * horizontal_sim, (0, 1, 0, 0), mode='replicate') + + new_knowness = torch.stack([new_top_knowness, new_bottom_knowness, + new_left_knowness, new_right_knowness], + dim=0).max(0).values + + cur_knowness = torch.max(cur_knowness, new_knowness) + + cur_knowness = F.interpolate(cur_knowness, size=mask.shape[-2:], mode='bilinear') + result = torch.min(mask, 1 - cur_knowness) + + return result + + +def make_mask_distance_weighter(kind='none', **kwargs): + if kind == 'none': + return dummy_distance_weighter + if kind == 'blur': + return BlurMask(**kwargs) + if kind == 'edt': + return EmulatedEDTMask(**kwargs) + if kind == 'pps': + return PropagatePerceptualSim(**kwargs) + raise ValueError(f'Unknown mask distance weighter kind {kind}') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/feature_matching.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/feature_matching.py new file mode 100644 index 00000000..c019895c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/feature_matching.py @@ -0,0 +1,33 @@ +from typing import List + +import torch +import torch.nn.functional as F + + +def masked_l2_loss(pred, target, mask, weight_known, weight_missing): + per_pixel_l2 = F.mse_loss(pred, target, reduction='none') + pixel_weights = mask * weight_missing + (1 - mask) * weight_known + return (pixel_weights * per_pixel_l2).mean() + + +def masked_l1_loss(pred, target, mask, weight_known, weight_missing): + per_pixel_l1 = F.l1_loss(pred, target, reduction='none') + pixel_weights = mask * weight_missing + (1 - mask) * weight_known + return (pixel_weights * per_pixel_l1).mean() + + +def feature_matching_loss(fake_features: List[torch.Tensor], target_features: List[torch.Tensor], mask=None): + if mask is None: + res = torch.stack([F.mse_loss(fake_feat, target_feat) + for fake_feat, target_feat in zip(fake_features, target_features)]).mean() + else: + res = 0 + norm = 0 + for fake_feat, target_feat in zip(fake_features, target_features): + cur_mask = F.interpolate(mask, size=fake_feat.shape[-2:], mode='bilinear', align_corners=False) + error_weights = 1 - cur_mask + cur_val = ((fake_feat - target_feat).pow(2) * error_weights).mean() + res = res + cur_val + norm += 1 + res = res / norm + return res diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/perceptual.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/perceptual.py new file mode 100644 index 00000000..5d8b0b30 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/perceptual.py @@ -0,0 +1,113 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +import torchvision + +# from models.ade20k import ModelBuilder +from annotator.lama.saicinpainting.utils import check_and_warn_input_range + + +IMAGENET_MEAN = torch.FloatTensor([0.485, 0.456, 0.406])[None, :, None, None] +IMAGENET_STD = torch.FloatTensor([0.229, 0.224, 0.225])[None, :, None, None] + + +class PerceptualLoss(nn.Module): + def __init__(self, normalize_inputs=True): + super(PerceptualLoss, self).__init__() + + self.normalize_inputs = normalize_inputs + self.mean_ = IMAGENET_MEAN + self.std_ = IMAGENET_STD + + vgg = torchvision.models.vgg19(pretrained=True).features + vgg_avg_pooling = [] + + for weights in vgg.parameters(): + weights.requires_grad = False + + for module in vgg.modules(): + if module.__class__.__name__ == 'Sequential': + continue + elif module.__class__.__name__ == 'MaxPool2d': + vgg_avg_pooling.append(nn.AvgPool2d(kernel_size=2, stride=2, padding=0)) + else: + vgg_avg_pooling.append(module) + + self.vgg = nn.Sequential(*vgg_avg_pooling) + + def do_normalize_inputs(self, x): + return (x - self.mean_.to(x.device)) / self.std_.to(x.device) + + def partial_losses(self, input, target, mask=None): + check_and_warn_input_range(target, 0, 1, 'PerceptualLoss target in partial_losses') + + # we expect input and target to be in [0, 1] range + losses = [] + + if self.normalize_inputs: + features_input = self.do_normalize_inputs(input) + features_target = self.do_normalize_inputs(target) + else: + features_input = input + features_target = target + + for layer in self.vgg[:30]: + + features_input = layer(features_input) + features_target = layer(features_target) + + if layer.__class__.__name__ == 'ReLU': + loss = F.mse_loss(features_input, features_target, reduction='none') + + if mask is not None: + cur_mask = F.interpolate(mask, size=features_input.shape[-2:], + mode='bilinear', align_corners=False) + loss = loss * (1 - cur_mask) + + loss = loss.mean(dim=tuple(range(1, len(loss.shape)))) + losses.append(loss) + + return losses + + def forward(self, input, target, mask=None): + losses = self.partial_losses(input, target, mask=mask) + return torch.stack(losses).sum(dim=0) + + def get_global_features(self, input): + check_and_warn_input_range(input, 0, 1, 'PerceptualLoss input in get_global_features') + + if self.normalize_inputs: + features_input = self.do_normalize_inputs(input) + else: + features_input = input + + features_input = self.vgg(features_input) + return features_input + + +class ResNetPL(nn.Module): + def __init__(self, weight=1, + weights_path=None, arch_encoder='resnet50dilated', segmentation=True): + super().__init__() + self.impl = ModelBuilder.get_encoder(weights_path=weights_path, + arch_encoder=arch_encoder, + arch_decoder='ppm_deepsup', + fc_dim=2048, + segmentation=segmentation) + self.impl.eval() + for w in self.impl.parameters(): + w.requires_grad_(False) + + self.weight = weight + + def forward(self, pred, target): + pred = (pred - IMAGENET_MEAN.to(pred)) / IMAGENET_STD.to(pred) + target = (target - IMAGENET_MEAN.to(target)) / IMAGENET_STD.to(target) + + pred_feats = self.impl(pred, return_feature_maps=True) + target_feats = self.impl(target, return_feature_maps=True) + + result = torch.stack([F.mse_loss(cur_pred, cur_target) + for cur_pred, cur_target + in zip(pred_feats, target_feats)]).sum() * self.weight + return result diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/segmentation.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/segmentation.py new file mode 100644 index 00000000..3d4a9f94 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/segmentation.py @@ -0,0 +1,43 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F + +from .constants import weights as constant_weights + + +class CrossEntropy2d(nn.Module): + def __init__(self, reduction="mean", ignore_label=255, weights=None, *args, **kwargs): + """ + weight (Tensor, optional): a manual rescaling weight given to each class. + If given, has to be a Tensor of size "nclasses" + """ + super(CrossEntropy2d, self).__init__() + self.reduction = reduction + self.ignore_label = ignore_label + self.weights = weights + if self.weights is not None: + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + self.weights = torch.FloatTensor(constant_weights[weights]).to(device) + + def forward(self, predict, target): + """ + Args: + predict:(n, c, h, w) + target:(n, 1, h, w) + """ + target = target.long() + assert not target.requires_grad + assert predict.dim() == 4, "{0}".format(predict.size()) + assert target.dim() == 4, "{0}".format(target.size()) + assert predict.size(0) == target.size(0), "{0} vs {1} ".format(predict.size(0), target.size(0)) + assert target.size(1) == 1, "{0}".format(target.size(1)) + assert predict.size(2) == target.size(2), "{0} vs {1} ".format(predict.size(2), target.size(2)) + assert predict.size(3) == target.size(3), "{0} vs {1} ".format(predict.size(3), target.size(3)) + target = target.squeeze(1) + n, c, h, w = predict.size() + target_mask = (target >= 0) * (target != self.ignore_label) + target = target[target_mask] + predict = predict.transpose(1, 2).transpose(2, 3).contiguous() + predict = predict[target_mask.view(n, h, w, 1).repeat(1, 1, 1, c)].view(-1, c) + loss = F.cross_entropy(predict, target, weight=self.weights, reduction=self.reduction) + return loss diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/style_loss.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/style_loss.py new file mode 100644 index 00000000..0bb42d7f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/losses/style_loss.py @@ -0,0 +1,155 @@ +import torch +import torch.nn as nn +import torchvision.models as models + + +class PerceptualLoss(nn.Module): + r""" + Perceptual loss, VGG-based + https://arxiv.org/abs/1603.08155 + https://github.com/dxyang/StyleTransfer/blob/master/utils.py + """ + + def __init__(self, weights=[1.0, 1.0, 1.0, 1.0, 1.0]): + super(PerceptualLoss, self).__init__() + self.add_module('vgg', VGG19()) + self.criterion = torch.nn.L1Loss() + self.weights = weights + + def __call__(self, x, y): + # Compute features + x_vgg, y_vgg = self.vgg(x), self.vgg(y) + + content_loss = 0.0 + content_loss += self.weights[0] * self.criterion(x_vgg['relu1_1'], y_vgg['relu1_1']) + content_loss += self.weights[1] * self.criterion(x_vgg['relu2_1'], y_vgg['relu2_1']) + content_loss += self.weights[2] * self.criterion(x_vgg['relu3_1'], y_vgg['relu3_1']) + content_loss += self.weights[3] * self.criterion(x_vgg['relu4_1'], y_vgg['relu4_1']) + content_loss += self.weights[4] * self.criterion(x_vgg['relu5_1'], y_vgg['relu5_1']) + + + return content_loss + + +class VGG19(torch.nn.Module): + def __init__(self): + super(VGG19, self).__init__() + features = models.vgg19(pretrained=True).features + self.relu1_1 = torch.nn.Sequential() + self.relu1_2 = torch.nn.Sequential() + + self.relu2_1 = torch.nn.Sequential() + self.relu2_2 = torch.nn.Sequential() + + self.relu3_1 = torch.nn.Sequential() + self.relu3_2 = torch.nn.Sequential() + self.relu3_3 = torch.nn.Sequential() + self.relu3_4 = torch.nn.Sequential() + + self.relu4_1 = torch.nn.Sequential() + self.relu4_2 = torch.nn.Sequential() + self.relu4_3 = torch.nn.Sequential() + self.relu4_4 = torch.nn.Sequential() + + self.relu5_1 = torch.nn.Sequential() + self.relu5_2 = torch.nn.Sequential() + self.relu5_3 = torch.nn.Sequential() + self.relu5_4 = torch.nn.Sequential() + + for x in range(2): + self.relu1_1.add_module(str(x), features[x]) + + for x in range(2, 4): + self.relu1_2.add_module(str(x), features[x]) + + for x in range(4, 7): + self.relu2_1.add_module(str(x), features[x]) + + for x in range(7, 9): + self.relu2_2.add_module(str(x), features[x]) + + for x in range(9, 12): + self.relu3_1.add_module(str(x), features[x]) + + for x in range(12, 14): + self.relu3_2.add_module(str(x), features[x]) + + for x in range(14, 16): + self.relu3_2.add_module(str(x), features[x]) + + for x in range(16, 18): + self.relu3_4.add_module(str(x), features[x]) + + for x in range(18, 21): + self.relu4_1.add_module(str(x), features[x]) + + for x in range(21, 23): + self.relu4_2.add_module(str(x), features[x]) + + for x in range(23, 25): + self.relu4_3.add_module(str(x), features[x]) + + for x in range(25, 27): + self.relu4_4.add_module(str(x), features[x]) + + for x in range(27, 30): + self.relu5_1.add_module(str(x), features[x]) + + for x in range(30, 32): + self.relu5_2.add_module(str(x), features[x]) + + for x in range(32, 34): + self.relu5_3.add_module(str(x), features[x]) + + for x in range(34, 36): + self.relu5_4.add_module(str(x), features[x]) + + # don't need the gradients, just want the features + for param in self.parameters(): + param.requires_grad = False + + def forward(self, x): + relu1_1 = self.relu1_1(x) + relu1_2 = self.relu1_2(relu1_1) + + relu2_1 = self.relu2_1(relu1_2) + relu2_2 = self.relu2_2(relu2_1) + + relu3_1 = self.relu3_1(relu2_2) + relu3_2 = self.relu3_2(relu3_1) + relu3_3 = self.relu3_3(relu3_2) + relu3_4 = self.relu3_4(relu3_3) + + relu4_1 = self.relu4_1(relu3_4) + relu4_2 = self.relu4_2(relu4_1) + relu4_3 = self.relu4_3(relu4_2) + relu4_4 = self.relu4_4(relu4_3) + + relu5_1 = self.relu5_1(relu4_4) + relu5_2 = self.relu5_2(relu5_1) + relu5_3 = self.relu5_3(relu5_2) + relu5_4 = self.relu5_4(relu5_3) + + out = { + 'relu1_1': relu1_1, + 'relu1_2': relu1_2, + + 'relu2_1': relu2_1, + 'relu2_2': relu2_2, + + 'relu3_1': relu3_1, + 'relu3_2': relu3_2, + 'relu3_3': relu3_3, + 'relu3_4': relu3_4, + + 'relu4_1': relu4_1, + 'relu4_2': relu4_2, + 'relu4_3': relu4_3, + 'relu4_4': relu4_4, + + 'relu5_1': relu5_1, + 'relu5_2': relu5_2, + 'relu5_3': relu5_3, + 'relu5_4': relu5_4, + } + return out diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/__init__.py new file mode 100644 index 00000000..c5c56ad9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/__init__.py @@ -0,0 +1,31 @@ +import logging + +from annotator.lama.saicinpainting.training.modules.ffc import FFCResNetGenerator +from annotator.lama.saicinpainting.training.modules.pix2pixhd import GlobalGenerator, MultiDilatedGlobalGenerator, \ + NLayerDiscriminator, MultidilatedNLayerDiscriminator + +def make_generator(config, kind, **kwargs): + logging.info(f'Make generator {kind}') + + if kind == 'pix2pixhd_multidilated': + return MultiDilatedGlobalGenerator(**kwargs) + + if kind == 'pix2pixhd_global': + return GlobalGenerator(**kwargs) + + if kind == 'ffc_resnet': + return FFCResNetGenerator(**kwargs) + + raise ValueError(f'Unknown generator kind {kind}') + + +def make_discriminator(kind, **kwargs): + logging.info(f'Make discriminator {kind}') + + if kind == 'pix2pixhd_nlayer_multidilated': + return MultidilatedNLayerDiscriminator(**kwargs) + + if kind == 'pix2pixhd_nlayer': + return NLayerDiscriminator(**kwargs) + + raise ValueError(f'Unknown discriminator kind {kind}') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/base.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/base.py new file mode 100644 index 00000000..58c51398 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/base.py @@ -0,0 +1,80 @@ +import abc +from typing import Tuple, List + +import torch +import torch.nn as nn + +from annotator.lama.saicinpainting.training.modules.depthwise_sep_conv import DepthWiseSeperableConv +from annotator.lama.saicinpainting.training.modules.multidilated_conv import MultidilatedConv + + +class BaseDiscriminator(nn.Module): + @abc.abstractmethod + def forward(self, x: torch.Tensor) -> Tuple[torch.Tensor, List[torch.Tensor]]: + """ + Predict scores and get intermediate activations. Useful for feature matching loss + :return tuple (scores, list of intermediate activations) + """ + raise NotImplemented() + + +def get_conv_block_ctor(kind='default'): + if not isinstance(kind, str): + return kind + if kind == 'default': + return nn.Conv2d + if kind == 'depthwise': + return DepthWiseSeperableConv + if kind == 'multidilated': + return MultidilatedConv + raise ValueError(f'Unknown convolutional block kind {kind}') + + +def get_norm_layer(kind='bn'): + if not isinstance(kind, str): + return kind + if kind == 'bn': + return nn.BatchNorm2d + if kind == 'in': + return nn.InstanceNorm2d + raise ValueError(f'Unknown norm block kind {kind}') + + +def get_activation(kind='tanh'): + if kind == 'tanh': + return nn.Tanh() + if kind == 'sigmoid': + return nn.Sigmoid() + if kind is False: + return nn.Identity() + raise ValueError(f'Unknown activation kind {kind}') + + +class SimpleMultiStepGenerator(nn.Module): + def __init__(self, steps: List[nn.Module]): + super().__init__() + self.steps = nn.ModuleList(steps) + + def forward(self, x): + cur_in = x + outs = [] + for step in self.steps: + cur_out = step(cur_in) + outs.append(cur_out) + cur_in = torch.cat((cur_in, cur_out), dim=1) + return torch.cat(outs[::-1], dim=1) + +def deconv_factory(kind, ngf, mult, norm_layer, activation, max_features): + if kind == 'convtranspose': + return [nn.ConvTranspose2d(min(max_features, ngf * mult), + min(max_features, int(ngf * mult / 2)), + kernel_size=3, stride=2, padding=1, output_padding=1), + norm_layer(min(max_features, int(ngf * mult / 2))), activation] + elif kind == 'bilinear': + return [nn.Upsample(scale_factor=2, mode='bilinear'), + DepthWiseSeperableConv(min(max_features, ngf * mult), + min(max_features, int(ngf * mult / 2)), + kernel_size=3, stride=1, padding=1), + norm_layer(min(max_features, int(ngf * mult / 2))), activation] + else: + raise Exception(f"Invalid deconv kind: {kind}") \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/depthwise_sep_conv.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/depthwise_sep_conv.py new file mode 100644 index 00000000..83dd15c3 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/depthwise_sep_conv.py @@ -0,0 +1,17 @@ +import torch +import torch.nn as nn + +class DepthWiseSeperableConv(nn.Module): + def __init__(self, in_dim, out_dim, *args, **kwargs): + super().__init__() + if 'groups' in kwargs: + # ignoring groups for Depthwise Sep Conv + del kwargs['groups'] + + self.depthwise = nn.Conv2d(in_dim, in_dim, *args, groups=in_dim, **kwargs) + self.pointwise = nn.Conv2d(in_dim, out_dim, kernel_size=1) + + def forward(self, x): + out = self.depthwise(x) + out = self.pointwise(out) + return out \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/fake_fakes.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/fake_fakes.py new file mode 100644 index 00000000..45c4ad55 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/fake_fakes.py @@ -0,0 +1,47 @@ +import torch +from kornia import SamplePadding +from kornia.augmentation import RandomAffine, CenterCrop + + +class FakeFakesGenerator: + def __init__(self, aug_proba=0.5, img_aug_degree=30, img_aug_translate=0.2): + self.grad_aug = RandomAffine(degrees=360, + translate=0.2, + padding_mode=SamplePadding.REFLECTION, + keepdim=False, + p=1) + self.img_aug = RandomAffine(degrees=img_aug_degree, + translate=img_aug_translate, + padding_mode=SamplePadding.REFLECTION, + keepdim=True, + p=1) + self.aug_proba = aug_proba + + def __call__(self, input_images, masks): + blend_masks = self._fill_masks_with_gradient(masks) + blend_target = self._make_blend_target(input_images) + result = input_images * (1 - blend_masks) + blend_target * blend_masks + return result, blend_masks + + def _make_blend_target(self, input_images): + batch_size = input_images.shape[0] + permuted = input_images[torch.randperm(batch_size)] + augmented = self.img_aug(input_images) + is_aug = (torch.rand(batch_size, device=input_images.device)[:, None, None, None] < self.aug_proba).float() + result = augmented * is_aug + permuted * (1 - is_aug) + return result + + def _fill_masks_with_gradient(self, masks): + batch_size, _, height, width = masks.shape + grad = torch.linspace(0, 1, steps=width * 2, device=masks.device, dtype=masks.dtype) \ + .view(1, 1, 1, -1).expand(batch_size, 1, height * 2, width * 2) + grad = self.grad_aug(grad) + grad = CenterCrop((height, width))(grad) + grad *= masks + + grad_for_min = grad + (1 - masks) * 10 + grad -= grad_for_min.view(batch_size, -1).min(-1).values[:, None, None, None] + grad /= grad.view(batch_size, -1).max(-1).values[:, None, None, None] + 1e-6 + grad.clamp_(min=0, max=1) + + return grad diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/ffc.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/ffc.py new file mode 100644 index 00000000..e67ff9c8 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/ffc.py @@ -0,0 +1,485 @@ +# Fast Fourier Convolution NeurIPS 2020 +# original implementation https://github.com/pkumivision/FFC/blob/main/model_zoo/ffc.py +# paper https://proceedings.neurips.cc/paper/2020/file/2fd5d41ec6cfab47e32164d5624269b1-Paper.pdf + +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F + +from annotator.lama.saicinpainting.training.modules.base import get_activation, BaseDiscriminator +from annotator.lama.saicinpainting.training.modules.spatial_transform import LearnableSpatialTransformWrapper +from annotator.lama.saicinpainting.training.modules.squeeze_excitation import SELayer +from annotator.lama.saicinpainting.utils import get_shape + + +class FFCSE_block(nn.Module): + + def __init__(self, channels, ratio_g): + super(FFCSE_block, self).__init__() + in_cg = int(channels * ratio_g) + in_cl = channels - in_cg + r = 16 + + self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) + self.conv1 = nn.Conv2d(channels, channels // r, + kernel_size=1, bias=True) + self.relu1 = nn.ReLU(inplace=True) + self.conv_a2l = None if in_cl == 0 else nn.Conv2d( + channels // r, in_cl, kernel_size=1, bias=True) + self.conv_a2g = None if in_cg == 0 else nn.Conv2d( + channels // r, in_cg, kernel_size=1, bias=True) + self.sigmoid = nn.Sigmoid() + + def forward(self, x): + x = x if type(x) is tuple else (x, 0) + id_l, id_g = x + + x = id_l if type(id_g) is int else torch.cat([id_l, id_g], dim=1) + x = self.avgpool(x) + x = self.relu1(self.conv1(x)) + + x_l = 0 if self.conv_a2l is None else id_l * \ + self.sigmoid(self.conv_a2l(x)) + x_g = 0 if self.conv_a2g is None else id_g * \ + self.sigmoid(self.conv_a2g(x)) + return x_l, x_g + + +class FourierUnit(nn.Module): + + def __init__(self, in_channels, out_channels, groups=1, spatial_scale_factor=None, spatial_scale_mode='bilinear', + spectral_pos_encoding=False, use_se=False, se_kwargs=None, ffc3d=False, fft_norm='ortho'): + # bn_layer not used + super(FourierUnit, self).__init__() + self.groups = groups + + self.conv_layer = torch.nn.Conv2d(in_channels=in_channels * 2 + (2 if spectral_pos_encoding else 0), + out_channels=out_channels * 2, + kernel_size=1, stride=1, padding=0, groups=self.groups, bias=False) + self.bn = torch.nn.BatchNorm2d(out_channels * 2) + self.relu = torch.nn.ReLU(inplace=True) + + # squeeze and excitation block + self.use_se = use_se + if use_se: + if se_kwargs is None: + se_kwargs = {} + self.se = SELayer(self.conv_layer.in_channels, **se_kwargs) + + self.spatial_scale_factor = spatial_scale_factor + self.spatial_scale_mode = spatial_scale_mode + self.spectral_pos_encoding = spectral_pos_encoding + self.ffc3d = ffc3d + self.fft_norm = fft_norm + + def forward(self, x): + batch = x.shape[0] + + if self.spatial_scale_factor is not None: + orig_size = x.shape[-2:] + x = F.interpolate(x, scale_factor=self.spatial_scale_factor, mode=self.spatial_scale_mode, align_corners=False) + + r_size = x.size() + # (batch, c, h, w/2+1, 2) + fft_dim = (-3, -2, -1) if self.ffc3d else (-2, -1) + ffted = torch.fft.rfftn(x, dim=fft_dim, norm=self.fft_norm) + ffted = torch.stack((ffted.real, ffted.imag), dim=-1) + ffted = ffted.permute(0, 1, 4, 2, 3).contiguous() # (batch, c, 2, h, w/2+1) + ffted = ffted.view((batch, -1,) + ffted.size()[3:]) + + if self.spectral_pos_encoding: + height, width = ffted.shape[-2:] + coords_vert = torch.linspace(0, 1, height)[None, None, :, None].expand(batch, 1, height, width).to(ffted) + coords_hor = torch.linspace(0, 1, width)[None, None, None, :].expand(batch, 1, height, width).to(ffted) + ffted = torch.cat((coords_vert, coords_hor, ffted), dim=1) + + if self.use_se: + ffted = self.se(ffted) + + ffted = self.conv_layer(ffted) # (batch, c*2, h, w/2+1) + ffted = self.relu(self.bn(ffted)) + + ffted = ffted.view((batch, -1, 2,) + ffted.size()[2:]).permute( + 0, 1, 3, 4, 2).contiguous() # (batch,c, t, h, w/2+1, 2) + ffted = torch.complex(ffted[..., 0], ffted[..., 1]) + + ifft_shape_slice = x.shape[-3:] if self.ffc3d else x.shape[-2:] + output = torch.fft.irfftn(ffted, s=ifft_shape_slice, dim=fft_dim, norm=self.fft_norm) + + if self.spatial_scale_factor is not None: + output = F.interpolate(output, size=orig_size, mode=self.spatial_scale_mode, align_corners=False) + + return output + + +class SeparableFourierUnit(nn.Module): + + def __init__(self, in_channels, out_channels, groups=1, kernel_size=3): + # bn_layer not used + super(SeparableFourierUnit, self).__init__() + self.groups = groups + row_out_channels = out_channels // 2 + col_out_channels = out_channels - row_out_channels + self.row_conv = torch.nn.Conv2d(in_channels=in_channels * 2, + out_channels=row_out_channels * 2, + kernel_size=(kernel_size, 1), # kernel size is always like this, but the data will be transposed + stride=1, padding=(kernel_size // 2, 0), + padding_mode='reflect', + groups=self.groups, bias=False) + self.col_conv = torch.nn.Conv2d(in_channels=in_channels * 2, + out_channels=col_out_channels * 2, + kernel_size=(kernel_size, 1), # kernel size is always like this, but the data will be transposed + stride=1, padding=(kernel_size // 2, 0), + padding_mode='reflect', + groups=self.groups, bias=False) + self.row_bn = torch.nn.BatchNorm2d(row_out_channels * 2) + self.col_bn = torch.nn.BatchNorm2d(col_out_channels * 2) + self.relu = torch.nn.ReLU(inplace=True) + + def process_branch(self, x, conv, bn): + batch = x.shape[0] + + r_size = x.size() + # (batch, c, h, w/2+1, 2) + ffted = torch.fft.rfft(x, norm="ortho") + ffted = torch.stack((ffted.real, ffted.imag), dim=-1) + ffted = ffted.permute(0, 1, 4, 2, 3).contiguous() # (batch, c, 2, h, w/2+1) + ffted = ffted.view((batch, -1,) + ffted.size()[3:]) + + ffted = self.relu(bn(conv(ffted))) + + ffted = ffted.view((batch, -1, 2,) + ffted.size()[2:]).permute( + 0, 1, 3, 4, 2).contiguous() # (batch,c, t, h, w/2+1, 2) + ffted = torch.complex(ffted[..., 0], ffted[..., 1]) + + output = torch.fft.irfft(ffted, s=x.shape[-1:], norm="ortho") + return output + + + def forward(self, x): + rowwise = self.process_branch(x, self.row_conv, self.row_bn) + colwise = self.process_branch(x.permute(0, 1, 3, 2), self.col_conv, self.col_bn).permute(0, 1, 3, 2) + out = torch.cat((rowwise, colwise), dim=1) + return out + + +class SpectralTransform(nn.Module): + + def __init__(self, in_channels, out_channels, stride=1, groups=1, enable_lfu=True, separable_fu=False, **fu_kwargs): + # bn_layer not used + super(SpectralTransform, self).__init__() + self.enable_lfu = enable_lfu + if stride == 2: + self.downsample = nn.AvgPool2d(kernel_size=(2, 2), stride=2) + else: + self.downsample = nn.Identity() + + self.stride = stride + self.conv1 = nn.Sequential( + nn.Conv2d(in_channels, out_channels // + 2, kernel_size=1, groups=groups, bias=False), + nn.BatchNorm2d(out_channels // 2), + nn.ReLU(inplace=True) + ) + fu_class = SeparableFourierUnit if separable_fu else FourierUnit + self.fu = fu_class( + out_channels // 2, out_channels // 2, groups, **fu_kwargs) + if self.enable_lfu: + self.lfu = fu_class( + out_channels // 2, out_channels // 2, groups) + self.conv2 = torch.nn.Conv2d( + out_channels // 2, out_channels, kernel_size=1, groups=groups, bias=False) + + def forward(self, x): + + x = self.downsample(x) + x = self.conv1(x) + output = self.fu(x) + + if self.enable_lfu: + n, c, h, w = x.shape + split_no = 2 + split_s = h // split_no + xs = torch.cat(torch.split( + x[:, :c // 4], split_s, dim=-2), dim=1).contiguous() + xs = torch.cat(torch.split(xs, split_s, dim=-1), + dim=1).contiguous() + xs = self.lfu(xs) + xs = xs.repeat(1, 1, split_no, split_no).contiguous() + else: + xs = 0 + + output = self.conv2(x + output + xs) + + return output + + +class FFC(nn.Module): + + def __init__(self, in_channels, out_channels, kernel_size, + ratio_gin, ratio_gout, stride=1, padding=0, + dilation=1, groups=1, bias=False, enable_lfu=True, + padding_type='reflect', gated=False, **spectral_kwargs): + super(FFC, self).__init__() + + assert stride == 1 or stride == 2, "Stride should be 1 or 2." + self.stride = stride + + in_cg = int(in_channels * ratio_gin) + in_cl = in_channels - in_cg + out_cg = int(out_channels * ratio_gout) + out_cl = out_channels - out_cg + #groups_g = 1 if groups == 1 else int(groups * ratio_gout) + #groups_l = 1 if groups == 1 else groups - groups_g + + self.ratio_gin = ratio_gin + self.ratio_gout = ratio_gout + self.global_in_num = in_cg + + module = nn.Identity if in_cl == 0 or out_cl == 0 else nn.Conv2d + self.convl2l = module(in_cl, out_cl, kernel_size, + stride, padding, dilation, groups, bias, padding_mode=padding_type) + module = nn.Identity if in_cl == 0 or out_cg == 0 else nn.Conv2d + self.convl2g = module(in_cl, out_cg, kernel_size, + stride, padding, dilation, groups, bias, padding_mode=padding_type) + module = nn.Identity if in_cg == 0 or out_cl == 0 else nn.Conv2d + self.convg2l = module(in_cg, out_cl, kernel_size, + stride, padding, dilation, groups, bias, padding_mode=padding_type) + module = nn.Identity if in_cg == 0 or out_cg == 0 else SpectralTransform + self.convg2g = module( + in_cg, out_cg, stride, 1 if groups == 1 else groups // 2, enable_lfu, **spectral_kwargs) + + self.gated = gated + module = nn.Identity if in_cg == 0 or out_cl == 0 or not self.gated else nn.Conv2d + self.gate = module(in_channels, 2, 1) + + def forward(self, x): + x_l, x_g = x if type(x) is tuple else (x, 0) + out_xl, out_xg = 0, 0 + + if self.gated: + total_input_parts = [x_l] + if torch.is_tensor(x_g): + total_input_parts.append(x_g) + total_input = torch.cat(total_input_parts, dim=1) + + gates = torch.sigmoid(self.gate(total_input)) + g2l_gate, l2g_gate = gates.chunk(2, dim=1) + else: + g2l_gate, l2g_gate = 1, 1 + + if self.ratio_gout != 1: + out_xl = self.convl2l(x_l) + self.convg2l(x_g) * g2l_gate + if self.ratio_gout != 0: + out_xg = self.convl2g(x_l) * l2g_gate + self.convg2g(x_g) + + return out_xl, out_xg + + +class FFC_BN_ACT(nn.Module): + + def __init__(self, in_channels, out_channels, + kernel_size, ratio_gin, ratio_gout, + stride=1, padding=0, dilation=1, groups=1, bias=False, + norm_layer=nn.BatchNorm2d, activation_layer=nn.Identity, + padding_type='reflect', + enable_lfu=True, **kwargs): + super(FFC_BN_ACT, self).__init__() + self.ffc = FFC(in_channels, out_channels, kernel_size, + ratio_gin, ratio_gout, stride, padding, dilation, + groups, bias, enable_lfu, padding_type=padding_type, **kwargs) + lnorm = nn.Identity if ratio_gout == 1 else norm_layer + gnorm = nn.Identity if ratio_gout == 0 else norm_layer + global_channels = int(out_channels * ratio_gout) + self.bn_l = lnorm(out_channels - global_channels) + self.bn_g = gnorm(global_channels) + + lact = nn.Identity if ratio_gout == 1 else activation_layer + gact = nn.Identity if ratio_gout == 0 else activation_layer + self.act_l = lact(inplace=True) + self.act_g = gact(inplace=True) + + def forward(self, x): + x_l, x_g = self.ffc(x) + x_l = self.act_l(self.bn_l(x_l)) + x_g = self.act_g(self.bn_g(x_g)) + return x_l, x_g + + +class FFCResnetBlock(nn.Module): + def __init__(self, dim, padding_type, norm_layer, activation_layer=nn.ReLU, dilation=1, + spatial_transform_kwargs=None, inline=False, **conv_kwargs): + super().__init__() + self.conv1 = FFC_BN_ACT(dim, dim, kernel_size=3, padding=dilation, dilation=dilation, + norm_layer=norm_layer, + activation_layer=activation_layer, + padding_type=padding_type, + **conv_kwargs) + self.conv2 = FFC_BN_ACT(dim, dim, kernel_size=3, padding=dilation, dilation=dilation, + norm_layer=norm_layer, + activation_layer=activation_layer, + padding_type=padding_type, + **conv_kwargs) + if spatial_transform_kwargs is not None: + self.conv1 = LearnableSpatialTransformWrapper(self.conv1, **spatial_transform_kwargs) + self.conv2 = LearnableSpatialTransformWrapper(self.conv2, **spatial_transform_kwargs) + self.inline = inline + + def forward(self, x): + if self.inline: + x_l, x_g = x[:, :-self.conv1.ffc.global_in_num], x[:, -self.conv1.ffc.global_in_num:] + else: + x_l, x_g = x if type(x) is tuple else (x, 0) + + id_l, id_g = x_l, x_g + + x_l, x_g = self.conv1((x_l, x_g)) + x_l, x_g = self.conv2((x_l, x_g)) + + x_l, x_g = id_l + x_l, id_g + x_g + out = x_l, x_g + if self.inline: + out = torch.cat(out, dim=1) + return out + + +class ConcatTupleLayer(nn.Module): + def forward(self, x): + assert isinstance(x, tuple) + x_l, x_g = x + assert torch.is_tensor(x_l) or torch.is_tensor(x_g) + if not torch.is_tensor(x_g): + return x_l + return torch.cat(x, dim=1) + + +class FFCResNetGenerator(nn.Module): + def __init__(self, input_nc, output_nc, ngf=64, n_downsampling=3, n_blocks=9, norm_layer=nn.BatchNorm2d, + padding_type='reflect', activation_layer=nn.ReLU, + up_norm_layer=nn.BatchNorm2d, up_activation=nn.ReLU(True), + init_conv_kwargs={}, downsample_conv_kwargs={}, resnet_conv_kwargs={}, + spatial_transform_layers=None, spatial_transform_kwargs={}, + add_out_act=True, max_features=1024, out_ffc=False, out_ffc_kwargs={}): + assert (n_blocks >= 0) + super().__init__() + + model = [nn.ReflectionPad2d(3), + FFC_BN_ACT(input_nc, ngf, kernel_size=7, padding=0, norm_layer=norm_layer, + activation_layer=activation_layer, **init_conv_kwargs)] + + ### downsample + for i in range(n_downsampling): + mult = 2 ** i + if i == n_downsampling - 1: + cur_conv_kwargs = dict(downsample_conv_kwargs) + cur_conv_kwargs['ratio_gout'] = resnet_conv_kwargs.get('ratio_gin', 0) + else: + cur_conv_kwargs = downsample_conv_kwargs + model += [FFC_BN_ACT(min(max_features, ngf * mult), + min(max_features, ngf * mult * 2), + kernel_size=3, stride=2, padding=1, + norm_layer=norm_layer, + activation_layer=activation_layer, + **cur_conv_kwargs)] + + mult = 2 ** n_downsampling + feats_num_bottleneck = min(max_features, ngf * mult) + + ### resnet blocks + for i in range(n_blocks): + cur_resblock = FFCResnetBlock(feats_num_bottleneck, padding_type=padding_type, activation_layer=activation_layer, + norm_layer=norm_layer, **resnet_conv_kwargs) + if spatial_transform_layers is not None and i in spatial_transform_layers: + cur_resblock = LearnableSpatialTransformWrapper(cur_resblock, **spatial_transform_kwargs) + model += [cur_resblock] + + model += [ConcatTupleLayer()] + + ### upsample + for i in range(n_downsampling): + mult = 2 ** (n_downsampling - i) + model += [nn.ConvTranspose2d(min(max_features, ngf * mult), + min(max_features, int(ngf * mult / 2)), + kernel_size=3, stride=2, padding=1, output_padding=1), + up_norm_layer(min(max_features, int(ngf * mult / 2))), + up_activation] + + if out_ffc: + model += [FFCResnetBlock(ngf, padding_type=padding_type, activation_layer=activation_layer, + norm_layer=norm_layer, inline=True, **out_ffc_kwargs)] + + model += [nn.ReflectionPad2d(3), + nn.Conv2d(ngf, output_nc, kernel_size=7, padding=0)] + if add_out_act: + model.append(get_activation('tanh' if add_out_act is True else add_out_act)) + self.model = nn.Sequential(*model) + + def forward(self, input): + return self.model(input) + + +class FFCNLayerDiscriminator(BaseDiscriminator): + def __init__(self, input_nc, ndf=64, n_layers=3, norm_layer=nn.BatchNorm2d, max_features=512, + init_conv_kwargs={}, conv_kwargs={}): + super().__init__() + self.n_layers = n_layers + + def _act_ctor(inplace=True): + return nn.LeakyReLU(negative_slope=0.2, inplace=inplace) + + kw = 3 + padw = int(np.ceil((kw-1.0)/2)) + sequence = [[FFC_BN_ACT(input_nc, ndf, kernel_size=kw, padding=padw, norm_layer=norm_layer, + activation_layer=_act_ctor, **init_conv_kwargs)]] + + nf = ndf + for n in range(1, n_layers): + nf_prev = nf + nf = min(nf * 2, max_features) + + cur_model = [ + FFC_BN_ACT(nf_prev, nf, + kernel_size=kw, stride=2, padding=padw, + norm_layer=norm_layer, + activation_layer=_act_ctor, + **conv_kwargs) + ] + sequence.append(cur_model) + + nf_prev = nf + nf = min(nf * 2, 512) + + cur_model = [ + FFC_BN_ACT(nf_prev, nf, + kernel_size=kw, stride=1, padding=padw, + norm_layer=norm_layer, + activation_layer=lambda *args, **kwargs: nn.LeakyReLU(*args, negative_slope=0.2, **kwargs), + **conv_kwargs), + ConcatTupleLayer() + ] + sequence.append(cur_model) + + sequence += [[nn.Conv2d(nf, 1, kernel_size=kw, stride=1, padding=padw)]] + + for n in range(len(sequence)): + setattr(self, 'model'+str(n), nn.Sequential(*sequence[n])) + + def get_all_activations(self, x): + res = [x] + for n in range(self.n_layers + 2): + model = getattr(self, 'model' + str(n)) + res.append(model(res[-1])) + return res[1:] + + def forward(self, x): + act = self.get_all_activations(x) + feats = [] + for out in act[:-1]: + if isinstance(out, tuple): + if torch.is_tensor(out[1]): + out = torch.cat(out, dim=1) + else: + out = out[0] + feats.append(out) + return act[-1], feats diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/multidilated_conv.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/multidilated_conv.py new file mode 100644 index 00000000..c57d0b45 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/multidilated_conv.py @@ -0,0 +1,98 @@ +import torch +import torch.nn as nn +import random +from annotator.lama.saicinpainting.training.modules.depthwise_sep_conv import DepthWiseSeperableConv + +class MultidilatedConv(nn.Module): + def __init__(self, in_dim, out_dim, kernel_size, dilation_num=3, comb_mode='sum', equal_dim=True, + shared_weights=False, padding=1, min_dilation=1, shuffle_in_channels=False, use_depthwise=False, **kwargs): + super().__init__() + convs = [] + self.equal_dim = equal_dim + assert comb_mode in ('cat_out', 'sum', 'cat_in', 'cat_both'), comb_mode + if comb_mode in ('cat_out', 'cat_both'): + self.cat_out = True + if equal_dim: + assert out_dim % dilation_num == 0 + out_dims = [out_dim // dilation_num] * dilation_num + self.index = sum([[i + j * (out_dims[0]) for j in range(dilation_num)] for i in range(out_dims[0])], []) + else: + out_dims = [out_dim // 2 ** (i + 1) for i in range(dilation_num - 1)] + out_dims.append(out_dim - sum(out_dims)) + index = [] + starts = [0] + out_dims[:-1] + lengths = [out_dims[i] // out_dims[-1] for i in range(dilation_num)] + for i in range(out_dims[-1]): + for j in range(dilation_num): + index += list(range(starts[j], starts[j] + lengths[j])) + starts[j] += lengths[j] + self.index = index + assert(len(index) == out_dim) + self.out_dims = out_dims + else: + self.cat_out = False + self.out_dims = [out_dim] * dilation_num + + if comb_mode in ('cat_in', 'cat_both'): + if equal_dim: + assert in_dim % dilation_num == 0 + in_dims = [in_dim // dilation_num] * dilation_num + else: + in_dims = [in_dim // 2 ** (i + 1) for i in range(dilation_num - 1)] + in_dims.append(in_dim - sum(in_dims)) + self.in_dims = in_dims + self.cat_in = True + else: + self.cat_in = False + self.in_dims = [in_dim] * dilation_num + + conv_type = DepthWiseSeperableConv if use_depthwise else nn.Conv2d + dilation = min_dilation + for i in range(dilation_num): + if isinstance(padding, int): + cur_padding = padding * dilation + else: + cur_padding = padding[i] + convs.append(conv_type( + self.in_dims[i], self.out_dims[i], kernel_size, padding=cur_padding, dilation=dilation, **kwargs + )) + if i > 0 and shared_weights: + convs[-1].weight = convs[0].weight + convs[-1].bias = convs[0].bias + dilation *= 2 + self.convs = nn.ModuleList(convs) + + self.shuffle_in_channels = shuffle_in_channels + if self.shuffle_in_channels: + # shuffle list as shuffling of tensors is nondeterministic + in_channels_permute = list(range(in_dim)) + random.shuffle(in_channels_permute) + # save as buffer so it is saved and loaded with checkpoint + self.register_buffer('in_channels_permute', torch.tensor(in_channels_permute)) + + def forward(self, x): + if self.shuffle_in_channels: + x = x[:, self.in_channels_permute] + + outs = [] + if self.cat_in: + if self.equal_dim: + x = x.chunk(len(self.convs), dim=1) + else: + new_x = [] + start = 0 + for dim in self.in_dims: + new_x.append(x[:, start:start+dim]) + start += dim + x = new_x + for i, conv in enumerate(self.convs): + if self.cat_in: + input = x[i] + else: + input = x + outs.append(conv(input)) + if self.cat_out: + out = torch.cat(outs, dim=1)[:, self.index] + else: + out = sum(outs) + return out diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/multiscale.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/multiscale.py new file mode 100644 index 00000000..3f41252f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/multiscale.py @@ -0,0 +1,244 @@ +from typing import List, Tuple, Union, Optional + +import torch +import torch.nn as nn +import torch.nn.functional as F + +from annotator.lama.saicinpainting.training.modules.base import get_conv_block_ctor, get_activation +from annotator.lama.saicinpainting.training.modules.pix2pixhd import ResnetBlock + + +class ResNetHead(nn.Module): + def __init__(self, input_nc, ngf=64, n_downsampling=3, n_blocks=9, norm_layer=nn.BatchNorm2d, + padding_type='reflect', conv_kind='default', activation=nn.ReLU(True)): + assert (n_blocks >= 0) + super(ResNetHead, self).__init__() + + conv_layer = get_conv_block_ctor(conv_kind) + + model = [nn.ReflectionPad2d(3), + conv_layer(input_nc, ngf, kernel_size=7, padding=0), + norm_layer(ngf), + activation] + + ### downsample + for i in range(n_downsampling): + mult = 2 ** i + model += [conv_layer(ngf * mult, ngf * mult * 2, kernel_size=3, stride=2, padding=1), + norm_layer(ngf * mult * 2), + activation] + + mult = 2 ** n_downsampling + + ### resnet blocks + for i in range(n_blocks): + model += [ResnetBlock(ngf * mult, padding_type=padding_type, activation=activation, norm_layer=norm_layer, + conv_kind=conv_kind)] + + self.model = nn.Sequential(*model) + + def forward(self, input): + return self.model(input) + + +class ResNetTail(nn.Module): + def __init__(self, output_nc, ngf=64, n_downsampling=3, n_blocks=9, norm_layer=nn.BatchNorm2d, + padding_type='reflect', conv_kind='default', activation=nn.ReLU(True), + up_norm_layer=nn.BatchNorm2d, up_activation=nn.ReLU(True), add_out_act=False, out_extra_layers_n=0, + add_in_proj=None): + assert (n_blocks >= 0) + super(ResNetTail, self).__init__() + + mult = 2 ** n_downsampling + + model = [] + + if add_in_proj is not None: + model.append(nn.Conv2d(add_in_proj, ngf * mult, kernel_size=1)) + + ### resnet blocks + for i in range(n_blocks): + model += [ResnetBlock(ngf * mult, padding_type=padding_type, activation=activation, norm_layer=norm_layer, + conv_kind=conv_kind)] + + ### upsample + for i in range(n_downsampling): + mult = 2 ** (n_downsampling - i) + model += [nn.ConvTranspose2d(ngf * mult, int(ngf * mult / 2), kernel_size=3, stride=2, padding=1, + output_padding=1), + up_norm_layer(int(ngf * mult / 2)), + up_activation] + self.model = nn.Sequential(*model) + + out_layers = [] + for _ in range(out_extra_layers_n): + out_layers += [nn.Conv2d(ngf, ngf, kernel_size=1, padding=0), + up_norm_layer(ngf), + up_activation] + out_layers += [nn.ReflectionPad2d(3), + nn.Conv2d(ngf, output_nc, kernel_size=7, padding=0)] + + if add_out_act: + out_layers.append(get_activation('tanh' if add_out_act is True else add_out_act)) + + self.out_proj = nn.Sequential(*out_layers) + + def forward(self, input, return_last_act=False): + features = self.model(input) + out = self.out_proj(features) + if return_last_act: + return out, features + else: + return out + + +class MultiscaleResNet(nn.Module): + def __init__(self, input_nc, output_nc, ngf=64, n_downsampling=2, n_blocks_head=2, n_blocks_tail=6, n_scales=3, + norm_layer=nn.BatchNorm2d, padding_type='reflect', conv_kind='default', activation=nn.ReLU(True), + up_norm_layer=nn.BatchNorm2d, up_activation=nn.ReLU(True), add_out_act=False, out_extra_layers_n=0, + out_cumulative=False, return_only_hr=False): + super().__init__() + + self.heads = nn.ModuleList([ResNetHead(input_nc, ngf=ngf, n_downsampling=n_downsampling, + n_blocks=n_blocks_head, norm_layer=norm_layer, padding_type=padding_type, + conv_kind=conv_kind, activation=activation) + for i in range(n_scales)]) + tail_in_feats = ngf * (2 ** n_downsampling) + ngf + self.tails = nn.ModuleList([ResNetTail(output_nc, + ngf=ngf, n_downsampling=n_downsampling, + n_blocks=n_blocks_tail, norm_layer=norm_layer, padding_type=padding_type, + conv_kind=conv_kind, activation=activation, up_norm_layer=up_norm_layer, + up_activation=up_activation, add_out_act=add_out_act, + out_extra_layers_n=out_extra_layers_n, + add_in_proj=None if (i == n_scales - 1) else tail_in_feats) + for i in range(n_scales)]) + + self.out_cumulative = out_cumulative + self.return_only_hr = return_only_hr + + @property + def num_scales(self): + return len(self.heads) + + def forward(self, ms_inputs: List[torch.Tensor], smallest_scales_num: Optional[int] = None) \ + -> Union[torch.Tensor, List[torch.Tensor]]: + """ + :param ms_inputs: List of inputs of different resolutions from HR to LR + :param smallest_scales_num: int or None, number of smallest scales to take at input + :return: Depending on return_only_hr: + True: Only the most HR output + False: List of outputs of different resolutions from HR to LR + """ + if smallest_scales_num is None: + assert len(self.heads) == len(ms_inputs), (len(self.heads), len(ms_inputs), smallest_scales_num) + smallest_scales_num = len(self.heads) + else: + assert smallest_scales_num == len(ms_inputs) <= len(self.heads), (len(self.heads), len(ms_inputs), smallest_scales_num) + + cur_heads = self.heads[-smallest_scales_num:] + ms_features = [cur_head(cur_inp) for cur_head, cur_inp in zip(cur_heads, ms_inputs)] + + all_outputs = [] + prev_tail_features = None + for i in range(len(ms_features)): + scale_i = -i - 1 + + cur_tail_input = ms_features[-i - 1] + if prev_tail_features is not None: + if prev_tail_features.shape != cur_tail_input.shape: + prev_tail_features = F.interpolate(prev_tail_features, size=cur_tail_input.shape[2:], + mode='bilinear', align_corners=False) + cur_tail_input = torch.cat((cur_tail_input, prev_tail_features), dim=1) + + cur_out, cur_tail_feats = self.tails[scale_i](cur_tail_input, return_last_act=True) + + prev_tail_features = cur_tail_feats + all_outputs.append(cur_out) + + if self.out_cumulative: + all_outputs_cum = [all_outputs[0]] + for i in range(1, len(ms_features)): + cur_out = all_outputs[i] + cur_out_cum = cur_out + F.interpolate(all_outputs_cum[-1], size=cur_out.shape[2:], + mode='bilinear', align_corners=False) + all_outputs_cum.append(cur_out_cum) + all_outputs = all_outputs_cum + + if self.return_only_hr: + return all_outputs[-1] + else: + return all_outputs[::-1] + + +class MultiscaleDiscriminatorSimple(nn.Module): + def __init__(self, ms_impl): + super().__init__() + self.ms_impl = nn.ModuleList(ms_impl) + + @property + def num_scales(self): + return len(self.ms_impl) + + def forward(self, ms_inputs: List[torch.Tensor], smallest_scales_num: Optional[int] = None) \ + -> List[Tuple[torch.Tensor, List[torch.Tensor]]]: + """ + :param ms_inputs: List of inputs of different resolutions from HR to LR + :param smallest_scales_num: int or None, number of smallest scales to take at input + :return: List of pairs (prediction, features) for different resolutions from HR to LR + """ + if smallest_scales_num is None: + assert len(self.ms_impl) == len(ms_inputs), (len(self.ms_impl), len(ms_inputs), smallest_scales_num) + smallest_scales_num = len(self.heads) + else: + assert smallest_scales_num == len(ms_inputs) <= len(self.ms_impl), \ + (len(self.ms_impl), len(ms_inputs), smallest_scales_num) + + return [cur_discr(cur_input) for cur_discr, cur_input in zip(self.ms_impl[-smallest_scales_num:], ms_inputs)] + + +class SingleToMultiScaleInputMixin: + def forward(self, x: torch.Tensor) -> List: + orig_height, orig_width = x.shape[2:] + factors = [2 ** i for i in range(self.num_scales)] + ms_inputs = [F.interpolate(x, size=(orig_height // f, orig_width // f), mode='bilinear', align_corners=False) + for f in factors] + return super().forward(ms_inputs) + + +class GeneratorMultiToSingleOutputMixin: + def forward(self, x): + return super().forward(x)[0] + + +class DiscriminatorMultiToSingleOutputMixin: + def forward(self, x): + out_feat_tuples = super().forward(x) + return out_feat_tuples[0][0], [f for _, flist in out_feat_tuples for f in flist] + + +class DiscriminatorMultiToSingleOutputStackedMixin: + def __init__(self, *args, return_feats_only_levels=None, **kwargs): + super().__init__(*args, **kwargs) + self.return_feats_only_levels = return_feats_only_levels + + def forward(self, x): + out_feat_tuples = super().forward(x) + outs = [out for out, _ in out_feat_tuples] + scaled_outs = [outs[0]] + [F.interpolate(cur_out, size=outs[0].shape[-2:], + mode='bilinear', align_corners=False) + for cur_out in outs[1:]] + out = torch.cat(scaled_outs, dim=1) + if self.return_feats_only_levels is not None: + feat_lists = [out_feat_tuples[i][1] for i in self.return_feats_only_levels] + else: + feat_lists = [flist for _, flist in out_feat_tuples] + feats = [f for flist in feat_lists for f in flist] + return out, feats + + +class MultiscaleDiscrSingleInput(SingleToMultiScaleInputMixin, DiscriminatorMultiToSingleOutputStackedMixin, MultiscaleDiscriminatorSimple): + pass + + +class MultiscaleResNetSingle(GeneratorMultiToSingleOutputMixin, SingleToMultiScaleInputMixin, MultiscaleResNet): + pass diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/pix2pixhd.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/pix2pixhd.py new file mode 100644 index 00000000..2e4fcfcf --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/pix2pixhd.py @@ -0,0 +1,669 @@ +# original: https://github.com/NVIDIA/pix2pixHD/blob/master/models/networks.py +import collections +from functools import partial +import functools +import logging +from collections import defaultdict + +import numpy as np +import torch.nn as nn + +from annotator.lama.saicinpainting.training.modules.base import BaseDiscriminator, deconv_factory, get_conv_block_ctor, get_norm_layer, get_activation +from annotator.lama.saicinpainting.training.modules.ffc import FFCResnetBlock +from annotator.lama.saicinpainting.training.modules.multidilated_conv import MultidilatedConv + +class DotDict(defaultdict): + # https://stackoverflow.com/questions/2352181/how-to-use-a-dot-to-access-members-of-dictionary + """dot.notation access to dictionary attributes""" + __getattr__ = defaultdict.get + __setattr__ = defaultdict.__setitem__ + __delattr__ = defaultdict.__delitem__ + +class Identity(nn.Module): + def __init__(self): + super().__init__() + + def forward(self, x): + return x + + +class ResnetBlock(nn.Module): + def __init__(self, dim, padding_type, norm_layer, activation=nn.ReLU(True), use_dropout=False, conv_kind='default', + dilation=1, in_dim=None, groups=1, second_dilation=None): + super(ResnetBlock, self).__init__() + self.in_dim = in_dim + self.dim = dim + if second_dilation is None: + second_dilation = dilation + self.conv_block = self.build_conv_block(dim, padding_type, norm_layer, activation, use_dropout, + conv_kind=conv_kind, dilation=dilation, in_dim=in_dim, groups=groups, + second_dilation=second_dilation) + + if self.in_dim is not None: + self.input_conv = nn.Conv2d(in_dim, dim, 1) + + self.out_channnels = dim + + def build_conv_block(self, dim, padding_type, norm_layer, activation, use_dropout, conv_kind='default', + dilation=1, in_dim=None, groups=1, second_dilation=1): + conv_layer = get_conv_block_ctor(conv_kind) + + conv_block = [] + p = 0 + if padding_type == 'reflect': + conv_block += [nn.ReflectionPad2d(dilation)] + elif padding_type == 'replicate': + conv_block += [nn.ReplicationPad2d(dilation)] + elif padding_type == 'zero': + p = dilation + else: + raise NotImplementedError('padding [%s] is not implemented' % padding_type) + + if in_dim is None: + in_dim = dim + + conv_block += [conv_layer(in_dim, dim, kernel_size=3, padding=p, dilation=dilation), + norm_layer(dim), + activation] + if use_dropout: + conv_block += [nn.Dropout(0.5)] + + p = 0 + if padding_type == 'reflect': + conv_block += [nn.ReflectionPad2d(second_dilation)] + elif padding_type == 'replicate': + conv_block += [nn.ReplicationPad2d(second_dilation)] + elif padding_type == 'zero': + p = second_dilation + else: + raise NotImplementedError('padding [%s] is not implemented' % padding_type) + conv_block += [conv_layer(dim, dim, kernel_size=3, padding=p, dilation=second_dilation, groups=groups), + norm_layer(dim)] + + return nn.Sequential(*conv_block) + + def forward(self, x): + x_before = x + if self.in_dim is not None: + x = self.input_conv(x) + out = x + self.conv_block(x_before) + return out + +class ResnetBlock5x5(nn.Module): + def __init__(self, dim, padding_type, norm_layer, activation=nn.ReLU(True), use_dropout=False, conv_kind='default', + dilation=1, in_dim=None, groups=1, second_dilation=None): + super(ResnetBlock5x5, self).__init__() + self.in_dim = in_dim + self.dim = dim + if second_dilation is None: + second_dilation = dilation + self.conv_block = self.build_conv_block(dim, padding_type, norm_layer, activation, use_dropout, + conv_kind=conv_kind, dilation=dilation, in_dim=in_dim, groups=groups, + second_dilation=second_dilation) + + if self.in_dim is not None: + self.input_conv = nn.Conv2d(in_dim, dim, 1) + + self.out_channnels = dim + + def build_conv_block(self, dim, padding_type, norm_layer, activation, use_dropout, conv_kind='default', + dilation=1, in_dim=None, groups=1, second_dilation=1): + conv_layer = get_conv_block_ctor(conv_kind) + + conv_block = [] + p = 0 + if padding_type == 'reflect': + conv_block += [nn.ReflectionPad2d(dilation * 2)] + elif padding_type == 'replicate': + conv_block += [nn.ReplicationPad2d(dilation * 2)] + elif padding_type == 'zero': + p = dilation * 2 + else: + raise NotImplementedError('padding [%s] is not implemented' % padding_type) + + if in_dim is None: + in_dim = dim + + conv_block += [conv_layer(in_dim, dim, kernel_size=5, padding=p, dilation=dilation), + norm_layer(dim), + activation] + if use_dropout: + conv_block += [nn.Dropout(0.5)] + + p = 0 + if padding_type == 'reflect': + conv_block += [nn.ReflectionPad2d(second_dilation * 2)] + elif padding_type == 'replicate': + conv_block += [nn.ReplicationPad2d(second_dilation * 2)] + elif padding_type == 'zero': + p = second_dilation * 2 + else: + raise NotImplementedError('padding [%s] is not implemented' % padding_type) + conv_block += [conv_layer(dim, dim, kernel_size=5, padding=p, dilation=second_dilation, groups=groups), + norm_layer(dim)] + + return nn.Sequential(*conv_block) + + def forward(self, x): + x_before = x + if self.in_dim is not None: + x = self.input_conv(x) + out = x + self.conv_block(x_before) + return out + + +class MultidilatedResnetBlock(nn.Module): + def __init__(self, dim, padding_type, conv_layer, norm_layer, activation=nn.ReLU(True), use_dropout=False): + super().__init__() + self.conv_block = self.build_conv_block(dim, padding_type, conv_layer, norm_layer, activation, use_dropout) + + def build_conv_block(self, dim, padding_type, conv_layer, norm_layer, activation, use_dropout, dilation=1): + conv_block = [] + conv_block += [conv_layer(dim, dim, kernel_size=3, padding_mode=padding_type), + norm_layer(dim), + activation] + if use_dropout: + conv_block += [nn.Dropout(0.5)] + + conv_block += [conv_layer(dim, dim, kernel_size=3, padding_mode=padding_type), + norm_layer(dim)] + + return nn.Sequential(*conv_block) + + def forward(self, x): + out = x + self.conv_block(x) + return out + + +class MultiDilatedGlobalGenerator(nn.Module): + def __init__(self, input_nc, output_nc, ngf=64, n_downsampling=3, + n_blocks=3, norm_layer=nn.BatchNorm2d, + padding_type='reflect', conv_kind='default', + deconv_kind='convtranspose', activation=nn.ReLU(True), + up_norm_layer=nn.BatchNorm2d, affine=None, up_activation=nn.ReLU(True), + add_out_act=True, max_features=1024, multidilation_kwargs={}, + ffc_positions=None, ffc_kwargs={}): + assert (n_blocks >= 0) + super().__init__() + + conv_layer = get_conv_block_ctor(conv_kind) + resnet_conv_layer = functools.partial(get_conv_block_ctor('multidilated'), **multidilation_kwargs) + norm_layer = get_norm_layer(norm_layer) + if affine is not None: + norm_layer = partial(norm_layer, affine=affine) + up_norm_layer = get_norm_layer(up_norm_layer) + if affine is not None: + up_norm_layer = partial(up_norm_layer, affine=affine) + + model = [nn.ReflectionPad2d(3), + conv_layer(input_nc, ngf, kernel_size=7, padding=0), + norm_layer(ngf), + activation] + + identity = Identity() + ### downsample + for i in range(n_downsampling): + mult = 2 ** i + + model += [conv_layer(min(max_features, ngf * mult), + min(max_features, ngf * mult * 2), + kernel_size=3, stride=2, padding=1), + norm_layer(min(max_features, ngf * mult * 2)), + activation] + + mult = 2 ** n_downsampling + feats_num_bottleneck = min(max_features, ngf * mult) + + ### resnet blocks + for i in range(n_blocks): + if ffc_positions is not None and i in ffc_positions: + model += [FFCResnetBlock(feats_num_bottleneck, padding_type, norm_layer, activation_layer=nn.ReLU, + inline=True, **ffc_kwargs)] + model += [MultidilatedResnetBlock(feats_num_bottleneck, padding_type=padding_type, + conv_layer=resnet_conv_layer, activation=activation, + norm_layer=norm_layer)] + + ### upsample + for i in range(n_downsampling): + mult = 2 ** (n_downsampling - i) + model += deconv_factory(deconv_kind, ngf, mult, up_norm_layer, up_activation, max_features) + model += [nn.ReflectionPad2d(3), + nn.Conv2d(ngf, output_nc, kernel_size=7, padding=0)] + if add_out_act: + model.append(get_activation('tanh' if add_out_act is True else add_out_act)) + self.model = nn.Sequential(*model) + + def forward(self, input): + return self.model(input) + +class ConfigGlobalGenerator(nn.Module): + def __init__(self, input_nc, output_nc, ngf=64, n_downsampling=3, + n_blocks=3, norm_layer=nn.BatchNorm2d, + padding_type='reflect', conv_kind='default', + deconv_kind='convtranspose', activation=nn.ReLU(True), + up_norm_layer=nn.BatchNorm2d, affine=None, up_activation=nn.ReLU(True), + add_out_act=True, max_features=1024, + manual_block_spec=[], + resnet_block_kind='multidilatedresnetblock', + resnet_conv_kind='multidilated', + resnet_dilation=1, + multidilation_kwargs={}): + assert (n_blocks >= 0) + super().__init__() + + conv_layer = get_conv_block_ctor(conv_kind) + resnet_conv_layer = functools.partial(get_conv_block_ctor(resnet_conv_kind), **multidilation_kwargs) + norm_layer = get_norm_layer(norm_layer) + if affine is not None: + norm_layer = partial(norm_layer, affine=affine) + up_norm_layer = get_norm_layer(up_norm_layer) + if affine is not None: + up_norm_layer = partial(up_norm_layer, affine=affine) + + model = [nn.ReflectionPad2d(3), + conv_layer(input_nc, ngf, kernel_size=7, padding=0), + norm_layer(ngf), + activation] + + identity = Identity() + + ### downsample + for i in range(n_downsampling): + mult = 2 ** i + model += [conv_layer(min(max_features, ngf * mult), + min(max_features, ngf * mult * 2), + kernel_size=3, stride=2, padding=1), + norm_layer(min(max_features, ngf * mult * 2)), + activation] + + mult = 2 ** n_downsampling + feats_num_bottleneck = min(max_features, ngf * mult) + + if len(manual_block_spec) == 0: + manual_block_spec = [ + DotDict(lambda : None, { + 'n_blocks': n_blocks, + 'use_default': True}) + ] + + ### resnet blocks + for block_spec in manual_block_spec: + def make_and_add_blocks(model, block_spec): + block_spec = DotDict(lambda : None, block_spec) + if not block_spec.use_default: + resnet_conv_layer = functools.partial(get_conv_block_ctor(block_spec.resnet_conv_kind), **block_spec.multidilation_kwargs) + resnet_conv_kind = block_spec.resnet_conv_kind + resnet_block_kind = block_spec.resnet_block_kind + if block_spec.resnet_dilation is not None: + resnet_dilation = block_spec.resnet_dilation + for i in range(block_spec.n_blocks): + if resnet_block_kind == "multidilatedresnetblock": + model += [MultidilatedResnetBlock(feats_num_bottleneck, padding_type=padding_type, + conv_layer=resnet_conv_layer, activation=activation, + norm_layer=norm_layer)] + if resnet_block_kind == "resnetblock": + model += [ResnetBlock(ngf * mult, padding_type=padding_type, activation=activation, norm_layer=norm_layer, + conv_kind=resnet_conv_kind)] + if resnet_block_kind == "resnetblock5x5": + model += [ResnetBlock5x5(ngf * mult, padding_type=padding_type, activation=activation, norm_layer=norm_layer, + conv_kind=resnet_conv_kind)] + if resnet_block_kind == "resnetblockdwdil": + model += [ResnetBlock(ngf * mult, padding_type=padding_type, activation=activation, norm_layer=norm_layer, + conv_kind=resnet_conv_kind, dilation=resnet_dilation, second_dilation=resnet_dilation)] + make_and_add_blocks(model, block_spec) + + ### upsample + for i in range(n_downsampling): + mult = 2 ** (n_downsampling - i) + model += deconv_factory(deconv_kind, ngf, mult, up_norm_layer, up_activation, max_features) + model += [nn.ReflectionPad2d(3), + nn.Conv2d(ngf, output_nc, kernel_size=7, padding=0)] + if add_out_act: + model.append(get_activation('tanh' if add_out_act is True else add_out_act)) + self.model = nn.Sequential(*model) + + def forward(self, input): + return self.model(input) + + +def make_dil_blocks(dilated_blocks_n, dilation_block_kind, dilated_block_kwargs): + blocks = [] + for i in range(dilated_blocks_n): + if dilation_block_kind == 'simple': + blocks.append(ResnetBlock(**dilated_block_kwargs, dilation=2 ** (i + 1))) + elif dilation_block_kind == 'multi': + blocks.append(MultidilatedResnetBlock(**dilated_block_kwargs)) + else: + raise ValueError(f'dilation_block_kind could not be "{dilation_block_kind}"') + return blocks + + +class GlobalGenerator(nn.Module): + def __init__(self, input_nc, output_nc, ngf=64, n_downsampling=3, n_blocks=9, norm_layer=nn.BatchNorm2d, + padding_type='reflect', conv_kind='default', activation=nn.ReLU(True), + up_norm_layer=nn.BatchNorm2d, affine=None, + up_activation=nn.ReLU(True), dilated_blocks_n=0, dilated_blocks_n_start=0, + dilated_blocks_n_middle=0, + add_out_act=True, + max_features=1024, is_resblock_depthwise=False, + ffc_positions=None, ffc_kwargs={}, dilation=1, second_dilation=None, + dilation_block_kind='simple', multidilation_kwargs={}): + assert (n_blocks >= 0) + super().__init__() + + conv_layer = get_conv_block_ctor(conv_kind) + norm_layer = get_norm_layer(norm_layer) + if affine is not None: + norm_layer = partial(norm_layer, affine=affine) + up_norm_layer = get_norm_layer(up_norm_layer) + if affine is not None: + up_norm_layer = partial(up_norm_layer, affine=affine) + + if ffc_positions is not None: + ffc_positions = collections.Counter(ffc_positions) + + model = [nn.ReflectionPad2d(3), + conv_layer(input_nc, ngf, kernel_size=7, padding=0), + norm_layer(ngf), + activation] + + identity = Identity() + ### downsample + for i in range(n_downsampling): + mult = 2 ** i + + model += [conv_layer(min(max_features, ngf * mult), + min(max_features, ngf * mult * 2), + kernel_size=3, stride=2, padding=1), + norm_layer(min(max_features, ngf * mult * 2)), + activation] + + mult = 2 ** n_downsampling + feats_num_bottleneck = min(max_features, ngf * mult) + + dilated_block_kwargs = dict(dim=feats_num_bottleneck, padding_type=padding_type, + activation=activation, norm_layer=norm_layer) + if dilation_block_kind == 'simple': + dilated_block_kwargs['conv_kind'] = conv_kind + elif dilation_block_kind == 'multi': + dilated_block_kwargs['conv_layer'] = functools.partial( + get_conv_block_ctor('multidilated'), **multidilation_kwargs) + + # dilated blocks at the start of the bottleneck sausage + if dilated_blocks_n_start is not None and dilated_blocks_n_start > 0: + model += make_dil_blocks(dilated_blocks_n_start, dilation_block_kind, dilated_block_kwargs) + + # resnet blocks + for i in range(n_blocks): + # dilated blocks at the middle of the bottleneck sausage + if i == n_blocks // 2 and dilated_blocks_n_middle is not None and dilated_blocks_n_middle > 0: + model += make_dil_blocks(dilated_blocks_n_middle, dilation_block_kind, dilated_block_kwargs) + + if ffc_positions is not None and i in ffc_positions: + for _ in range(ffc_positions[i]): # same position can occur more than once + model += [FFCResnetBlock(feats_num_bottleneck, padding_type, norm_layer, activation_layer=nn.ReLU, + inline=True, **ffc_kwargs)] + + if is_resblock_depthwise: + resblock_groups = feats_num_bottleneck + else: + resblock_groups = 1 + + model += [ResnetBlock(feats_num_bottleneck, padding_type=padding_type, activation=activation, + norm_layer=norm_layer, conv_kind=conv_kind, groups=resblock_groups, + dilation=dilation, second_dilation=second_dilation)] + + + # dilated blocks at the end of the bottleneck sausage + if dilated_blocks_n is not None and dilated_blocks_n > 0: + model += make_dil_blocks(dilated_blocks_n, dilation_block_kind, dilated_block_kwargs) + + # upsample + for i in range(n_downsampling): + mult = 2 ** (n_downsampling - i) + model += [nn.ConvTranspose2d(min(max_features, ngf * mult), + min(max_features, int(ngf * mult / 2)), + kernel_size=3, stride=2, padding=1, output_padding=1), + up_norm_layer(min(max_features, int(ngf * mult / 2))), + up_activation] + model += [nn.ReflectionPad2d(3), + nn.Conv2d(ngf, output_nc, kernel_size=7, padding=0)] + if add_out_act: + model.append(get_activation('tanh' if add_out_act is True else add_out_act)) + self.model = nn.Sequential(*model) + + def forward(self, input): + return self.model(input) + + +class GlobalGeneratorGated(GlobalGenerator): + def __init__(self, *args, **kwargs): + real_kwargs=dict( + conv_kind='gated_bn_relu', + activation=nn.Identity(), + norm_layer=nn.Identity + ) + real_kwargs.update(kwargs) + super().__init__(*args, **real_kwargs) + + +class GlobalGeneratorFromSuperChannels(nn.Module): + def __init__(self, input_nc, output_nc, n_downsampling, n_blocks, super_channels, norm_layer="bn", padding_type='reflect', add_out_act=True): + super().__init__() + self.n_downsampling = n_downsampling + norm_layer = get_norm_layer(norm_layer) + if type(norm_layer) == functools.partial: + use_bias = (norm_layer.func == nn.InstanceNorm2d) + else: + use_bias = (norm_layer == nn.InstanceNorm2d) + + channels = self.convert_super_channels(super_channels) + self.channels = channels + + model = [nn.ReflectionPad2d(3), + nn.Conv2d(input_nc, channels[0], kernel_size=7, padding=0, bias=use_bias), + norm_layer(channels[0]), + nn.ReLU(True)] + + for i in range(n_downsampling): # add downsampling layers + mult = 2 ** i + model += [nn.Conv2d(channels[0+i], channels[1+i], kernel_size=3, stride=2, padding=1, bias=use_bias), + norm_layer(channels[1+i]), + nn.ReLU(True)] + + mult = 2 ** n_downsampling + + n_blocks1 = n_blocks // 3 + n_blocks2 = n_blocks1 + n_blocks3 = n_blocks - n_blocks1 - n_blocks2 + + for i in range(n_blocks1): + c = n_downsampling + dim = channels[c] + model += [ResnetBlock(dim, padding_type=padding_type, norm_layer=norm_layer)] + + for i in range(n_blocks2): + c = n_downsampling+1 + dim = channels[c] + kwargs = {} + if i == 0: + kwargs = {"in_dim": channels[c-1]} + model += [ResnetBlock(dim, padding_type=padding_type, norm_layer=norm_layer, **kwargs)] + + for i in range(n_blocks3): + c = n_downsampling+2 + dim = channels[c] + kwargs = {} + if i == 0: + kwargs = {"in_dim": channels[c-1]} + model += [ResnetBlock(dim, padding_type=padding_type, norm_layer=norm_layer, **kwargs)] + + for i in range(n_downsampling): # add upsampling layers + mult = 2 ** (n_downsampling - i) + model += [nn.ConvTranspose2d(channels[n_downsampling+3+i], + channels[n_downsampling+3+i+1], + kernel_size=3, stride=2, + padding=1, output_padding=1, + bias=use_bias), + norm_layer(channels[n_downsampling+3+i+1]), + nn.ReLU(True)] + model += [nn.ReflectionPad2d(3)] + model += [nn.Conv2d(channels[2*n_downsampling+3], output_nc, kernel_size=7, padding=0)] + + if add_out_act: + model.append(get_activation('tanh' if add_out_act is True else add_out_act)) + self.model = nn.Sequential(*model) + + def convert_super_channels(self, super_channels): + n_downsampling = self.n_downsampling + result = [] + cnt = 0 + + if n_downsampling == 2: + N1 = 10 + elif n_downsampling == 3: + N1 = 13 + else: + raise NotImplementedError + + for i in range(0, N1): + if i in [1,4,7,10]: + channel = super_channels[cnt] * (2 ** cnt) + config = {'channel': channel} + result.append(channel) + logging.info(f"Downsample channels {result[-1]}") + cnt += 1 + + for i in range(3): + for counter, j in enumerate(range(N1 + i * 3, N1 + 3 + i * 3)): + if len(super_channels) == 6: + channel = super_channels[3] * 4 + else: + channel = super_channels[i + 3] * 4 + config = {'channel': channel} + if counter == 0: + result.append(channel) + logging.info(f"Bottleneck channels {result[-1]}") + cnt = 2 + + for i in range(N1+9, N1+21): + if i in [22, 25,28]: + cnt -= 1 + if len(super_channels) == 6: + channel = super_channels[5 - cnt] * (2 ** cnt) + else: + channel = super_channels[7 - cnt] * (2 ** cnt) + result.append(int(channel)) + logging.info(f"Upsample channels {result[-1]}") + return result + + def forward(self, input): + return self.model(input) + + +# Defines the PatchGAN discriminator with the specified arguments. +class NLayerDiscriminator(BaseDiscriminator): + def __init__(self, input_nc, ndf=64, n_layers=3, norm_layer=nn.BatchNorm2d,): + super().__init__() + self.n_layers = n_layers + + kw = 4 + padw = int(np.ceil((kw-1.0)/2)) + sequence = [[nn.Conv2d(input_nc, ndf, kernel_size=kw, stride=2, padding=padw), + nn.LeakyReLU(0.2, True)]] + + nf = ndf + for n in range(1, n_layers): + nf_prev = nf + nf = min(nf * 2, 512) + + cur_model = [] + cur_model += [ + nn.Conv2d(nf_prev, nf, kernel_size=kw, stride=2, padding=padw), + norm_layer(nf), + nn.LeakyReLU(0.2, True) + ] + sequence.append(cur_model) + + nf_prev = nf + nf = min(nf * 2, 512) + + cur_model = [] + cur_model += [ + nn.Conv2d(nf_prev, nf, kernel_size=kw, stride=1, padding=padw), + norm_layer(nf), + nn.LeakyReLU(0.2, True) + ] + sequence.append(cur_model) + + sequence += [[nn.Conv2d(nf, 1, kernel_size=kw, stride=1, padding=padw)]] + + for n in range(len(sequence)): + setattr(self, 'model'+str(n), nn.Sequential(*sequence[n])) + + def get_all_activations(self, x): + res = [x] + for n in range(self.n_layers + 2): + model = getattr(self, 'model' + str(n)) + res.append(model(res[-1])) + return res[1:] + + def forward(self, x): + act = self.get_all_activations(x) + return act[-1], act[:-1] + + +class MultidilatedNLayerDiscriminator(BaseDiscriminator): + def __init__(self, input_nc, ndf=64, n_layers=3, norm_layer=nn.BatchNorm2d, multidilation_kwargs={}): + super().__init__() + self.n_layers = n_layers + + kw = 4 + padw = int(np.ceil((kw-1.0)/2)) + sequence = [[nn.Conv2d(input_nc, ndf, kernel_size=kw, stride=2, padding=padw), + nn.LeakyReLU(0.2, True)]] + + nf = ndf + for n in range(1, n_layers): + nf_prev = nf + nf = min(nf * 2, 512) + + cur_model = [] + cur_model += [ + MultidilatedConv(nf_prev, nf, kernel_size=kw, stride=2, padding=[2, 3], **multidilation_kwargs), + norm_layer(nf), + nn.LeakyReLU(0.2, True) + ] + sequence.append(cur_model) + + nf_prev = nf + nf = min(nf * 2, 512) + + cur_model = [] + cur_model += [ + nn.Conv2d(nf_prev, nf, kernel_size=kw, stride=1, padding=padw), + norm_layer(nf), + nn.LeakyReLU(0.2, True) + ] + sequence.append(cur_model) + + sequence += [[nn.Conv2d(nf, 1, kernel_size=kw, stride=1, padding=padw)]] + + for n in range(len(sequence)): + setattr(self, 'model'+str(n), nn.Sequential(*sequence[n])) + + def get_all_activations(self, x): + res = [x] + for n in range(self.n_layers + 2): + model = getattr(self, 'model' + str(n)) + res.append(model(res[-1])) + return res[1:] + + def forward(self, x): + act = self.get_all_activations(x) + return act[-1], act[:-1] + + +class NLayerDiscriminatorAsGen(NLayerDiscriminator): + def forward(self, x): + return super().forward(x)[0] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/spatial_transform.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/spatial_transform.py new file mode 100644 index 00000000..2de024ba --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/spatial_transform.py @@ -0,0 +1,49 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +from kornia.geometry.transform import rotate + + +class LearnableSpatialTransformWrapper(nn.Module): + def __init__(self, impl, pad_coef=0.5, angle_init_range=80, train_angle=True): + super().__init__() + self.impl = impl + self.angle = torch.rand(1) * angle_init_range + if train_angle: + self.angle = nn.Parameter(self.angle, requires_grad=True) + self.pad_coef = pad_coef + + def forward(self, x): + if torch.is_tensor(x): + return self.inverse_transform(self.impl(self.transform(x)), x) + elif isinstance(x, tuple): + x_trans = tuple(self.transform(elem) for elem in x) + y_trans = self.impl(x_trans) + return tuple(self.inverse_transform(elem, orig_x) for elem, orig_x in zip(y_trans, x)) + else: + raise ValueError(f'Unexpected input type {type(x)}') + + def transform(self, x): + height, width = x.shape[2:] + pad_h, pad_w = int(height * self.pad_coef), int(width * self.pad_coef) + x_padded = F.pad(x, [pad_w, pad_w, pad_h, pad_h], mode='reflect') + x_padded_rotated = rotate(x_padded, angle=self.angle.to(x_padded)) + return x_padded_rotated + + def inverse_transform(self, y_padded_rotated, orig_x): + height, width = orig_x.shape[2:] + pad_h, pad_w = int(height * self.pad_coef), int(width * self.pad_coef) + + y_padded = rotate(y_padded_rotated, angle=-self.angle.to(y_padded_rotated)) + y_height, y_width = y_padded.shape[2:] + y = y_padded[:, :, pad_h : y_height - pad_h, pad_w : y_width - pad_w] + return y + + +if __name__ == '__main__': + layer = LearnableSpatialTransformWrapper(nn.Identity()) + x = torch.arange(2* 3 * 15 * 15).view(2, 3, 15, 15).float() + y = layer(x) + assert x.shape == y.shape + assert torch.allclose(x[:, :, 1:, 1:][:, :, :-1, :-1], y[:, :, 1:, 1:][:, :, :-1, :-1]) + print('all ok') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/squeeze_excitation.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/squeeze_excitation.py new file mode 100644 index 00000000..d1d902bb --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/modules/squeeze_excitation.py @@ -0,0 +1,20 @@ +import torch.nn as nn + + +class SELayer(nn.Module): + def __init__(self, channel, reduction=16): + super(SELayer, self).__init__() + self.avg_pool = nn.AdaptiveAvgPool2d(1) + self.fc = nn.Sequential( + nn.Linear(channel, channel // reduction, bias=False), + nn.ReLU(inplace=True), + nn.Linear(channel // reduction, channel, bias=False), + nn.Sigmoid() + ) + + def forward(self, x): + b, c, _, _ = x.size() + y = self.avg_pool(x).view(b, c) + y = self.fc(y).view(b, c, 1, 1) + res = x * y.expand_as(x) + return res diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/trainers/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/trainers/__init__.py new file mode 100644 index 00000000..8307cd31 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/trainers/__init__.py @@ -0,0 +1,29 @@ +import logging +import torch +from annotator.lama.saicinpainting.training.trainers.default import DefaultInpaintingTrainingModule + + +def get_training_model_class(kind): + if kind == 'default': + return DefaultInpaintingTrainingModule + + raise ValueError(f'Unknown trainer module {kind}') + + +def make_training_model(config): + kind = config.training_model.kind + kwargs = dict(config.training_model) + kwargs.pop('kind') + kwargs['use_ddp'] = config.trainer.kwargs.get('accelerator', None) == 'ddp' + + logging.info(f'Make training model {kind}') + + cls = get_training_model_class(kind) + return cls(config, **kwargs) + + +def load_checkpoint(train_config, path, map_location='cuda', strict=True): + model = make_training_model(train_config).generator + state = torch.load(path, map_location=map_location) + model.load_state_dict(state, strict=strict) + return model diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/trainers/base.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/trainers/base.py new file mode 100644 index 00000000..372dd879 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/trainers/base.py @@ -0,0 +1,293 @@ +import copy +import logging +from typing import Dict, Tuple + +import pandas as pd +import pytorch_lightning as ptl +import torch +import torch.nn as nn +import torch.nn.functional as F +# from torch.utils.data import DistributedSampler + +# from annotator.lama.saicinpainting.evaluation import make_evaluator +# from annotator.lama.saicinpainting.training.data.datasets import make_default_train_dataloader, make_default_val_dataloader +# from annotator.lama.saicinpainting.training.losses.adversarial import make_discrim_loss +# from annotator.lama.saicinpainting.training.losses.perceptual import PerceptualLoss, ResNetPL +from annotator.lama.saicinpainting.training.modules import make_generator #, make_discriminator +# from annotator.lama.saicinpainting.training.visualizers import make_visualizer +from annotator.lama.saicinpainting.utils import add_prefix_to_keys, average_dicts, set_requires_grad, flatten_dict, \ + get_has_ddp_rank + +LOGGER = logging.getLogger(__name__) + + +def make_optimizer(parameters, kind='adamw', **kwargs): + if kind == 'adam': + optimizer_class = torch.optim.Adam + elif kind == 'adamw': + optimizer_class = torch.optim.AdamW + else: + raise ValueError(f'Unknown optimizer kind {kind}') + return optimizer_class(parameters, **kwargs) + + +def update_running_average(result: nn.Module, new_iterate_model: nn.Module, decay=0.999): + with torch.no_grad(): + res_params = dict(result.named_parameters()) + new_params = dict(new_iterate_model.named_parameters()) + + for k in res_params.keys(): + res_params[k].data.mul_(decay).add_(new_params[k].data, alpha=1 - decay) + + +def make_multiscale_noise(base_tensor, scales=6, scale_mode='bilinear'): + batch_size, _, height, width = base_tensor.shape + cur_height, cur_width = height, width + result = [] + align_corners = False if scale_mode in ('bilinear', 'bicubic') else None + for _ in range(scales): + cur_sample = torch.randn(batch_size, 1, cur_height, cur_width, device=base_tensor.device) + cur_sample_scaled = F.interpolate(cur_sample, size=(height, width), mode=scale_mode, align_corners=align_corners) + result.append(cur_sample_scaled) + cur_height //= 2 + cur_width //= 2 + return torch.cat(result, dim=1) + + +class BaseInpaintingTrainingModule(ptl.LightningModule): + def __init__(self, config, use_ddp, *args, predict_only=False, visualize_each_iters=100, + average_generator=False, generator_avg_beta=0.999, average_generator_start_step=30000, + average_generator_period=10, store_discr_outputs_for_vis=False, + **kwargs): + super().__init__(*args, **kwargs) + LOGGER.info('BaseInpaintingTrainingModule init called') + + self.config = config + + self.generator = make_generator(config, **self.config.generator) + self.use_ddp = use_ddp + + if not get_has_ddp_rank(): + LOGGER.info(f'Generator\n{self.generator}') + + # if not predict_only: + # self.save_hyperparameters(self.config) + # self.discriminator = make_discriminator(**self.config.discriminator) + # self.adversarial_loss = make_discrim_loss(**self.config.losses.adversarial) + # self.visualizer = make_visualizer(**self.config.visualizer) + # self.val_evaluator = make_evaluator(**self.config.evaluator) + # self.test_evaluator = make_evaluator(**self.config.evaluator) + # + # if not get_has_ddp_rank(): + # LOGGER.info(f'Discriminator\n{self.discriminator}') + # + # extra_val = self.config.data.get('extra_val', ()) + # if extra_val: + # self.extra_val_titles = list(extra_val) + # self.extra_evaluators = nn.ModuleDict({k: make_evaluator(**self.config.evaluator) + # for k in extra_val}) + # else: + # self.extra_evaluators = {} + # + # self.average_generator = average_generator + # self.generator_avg_beta = generator_avg_beta + # self.average_generator_start_step = average_generator_start_step + # self.average_generator_period = average_generator_period + # self.generator_average = None + # self.last_generator_averaging_step = -1 + # self.store_discr_outputs_for_vis = store_discr_outputs_for_vis + # + # if self.config.losses.get("l1", {"weight_known": 0})['weight_known'] > 0: + # self.loss_l1 = nn.L1Loss(reduction='none') + # + # if self.config.losses.get("mse", {"weight": 0})['weight'] > 0: + # self.loss_mse = nn.MSELoss(reduction='none') + # + # if self.config.losses.perceptual.weight > 0: + # self.loss_pl = PerceptualLoss() + # + # # if self.config.losses.get("resnet_pl", {"weight": 0})['weight'] > 0: + # # self.loss_resnet_pl = ResNetPL(**self.config.losses.resnet_pl) + # # else: + # # self.loss_resnet_pl = None + # + # self.loss_resnet_pl = None + + self.visualize_each_iters = visualize_each_iters + LOGGER.info('BaseInpaintingTrainingModule init done') + + def configure_optimizers(self): + discriminator_params = list(self.discriminator.parameters()) + return [ + dict(optimizer=make_optimizer(self.generator.parameters(), **self.config.optimizers.generator)), + dict(optimizer=make_optimizer(discriminator_params, **self.config.optimizers.discriminator)), + ] + + def train_dataloader(self): + kwargs = dict(self.config.data.train) + if self.use_ddp: + kwargs['ddp_kwargs'] = dict(num_replicas=self.trainer.num_nodes * self.trainer.num_processes, + rank=self.trainer.global_rank, + shuffle=True) + dataloader = make_default_train_dataloader(**self.config.data.train) + return dataloader + + def val_dataloader(self): + res = [make_default_val_dataloader(**self.config.data.val)] + + if self.config.data.visual_test is not None: + res = res + [make_default_val_dataloader(**self.config.data.visual_test)] + else: + res = res + res + + extra_val = self.config.data.get('extra_val', ()) + if extra_val: + res += [make_default_val_dataloader(**extra_val[k]) for k in self.extra_val_titles] + + return res + + def training_step(self, batch, batch_idx, optimizer_idx=None): + self._is_training_step = True + return self._do_step(batch, batch_idx, mode='train', optimizer_idx=optimizer_idx) + + def validation_step(self, batch, batch_idx, dataloader_idx): + extra_val_key = None + if dataloader_idx == 0: + mode = 'val' + elif dataloader_idx == 1: + mode = 'test' + else: + mode = 'extra_val' + extra_val_key = self.extra_val_titles[dataloader_idx - 2] + self._is_training_step = False + return self._do_step(batch, batch_idx, mode=mode, extra_val_key=extra_val_key) + + def training_step_end(self, batch_parts_outputs): + if self.training and self.average_generator \ + and self.global_step >= self.average_generator_start_step \ + and self.global_step >= self.last_generator_averaging_step + self.average_generator_period: + if self.generator_average is None: + self.generator_average = copy.deepcopy(self.generator) + else: + update_running_average(self.generator_average, self.generator, decay=self.generator_avg_beta) + self.last_generator_averaging_step = self.global_step + + full_loss = (batch_parts_outputs['loss'].mean() + if torch.is_tensor(batch_parts_outputs['loss']) # loss is not tensor when no discriminator used + else torch.tensor(batch_parts_outputs['loss']).float().requires_grad_(True)) + log_info = {k: v.mean() for k, v in batch_parts_outputs['log_info'].items()} + self.log_dict(log_info, on_step=True, on_epoch=False) + return full_loss + + def validation_epoch_end(self, outputs): + outputs = [step_out for out_group in outputs for step_out in out_group] + averaged_logs = average_dicts(step_out['log_info'] for step_out in outputs) + self.log_dict({k: v.mean() for k, v in averaged_logs.items()}) + + pd.set_option('display.max_columns', 500) + pd.set_option('display.width', 1000) + + # standard validation + val_evaluator_states = [s['val_evaluator_state'] for s in outputs if 'val_evaluator_state' in s] + val_evaluator_res = self.val_evaluator.evaluation_end(states=val_evaluator_states) + val_evaluator_res_df = pd.DataFrame(val_evaluator_res).stack(1).unstack(0) + val_evaluator_res_df.dropna(axis=1, how='all', inplace=True) + LOGGER.info(f'Validation metrics after epoch #{self.current_epoch}, ' + f'total {self.global_step} iterations:\n{val_evaluator_res_df}') + + for k, v in flatten_dict(val_evaluator_res).items(): + self.log(f'val_{k}', v) + + # standard visual test + test_evaluator_states = [s['test_evaluator_state'] for s in outputs + if 'test_evaluator_state' in s] + test_evaluator_res = self.test_evaluator.evaluation_end(states=test_evaluator_states) + test_evaluator_res_df = pd.DataFrame(test_evaluator_res).stack(1).unstack(0) + test_evaluator_res_df.dropna(axis=1, how='all', inplace=True) + LOGGER.info(f'Test metrics after epoch #{self.current_epoch}, ' + f'total {self.global_step} iterations:\n{test_evaluator_res_df}') + + for k, v in flatten_dict(test_evaluator_res).items(): + self.log(f'test_{k}', v) + + # extra validations + if self.extra_evaluators: + for cur_eval_title, cur_evaluator in self.extra_evaluators.items(): + cur_state_key = f'extra_val_{cur_eval_title}_evaluator_state' + cur_states = [s[cur_state_key] for s in outputs if cur_state_key in s] + cur_evaluator_res = cur_evaluator.evaluation_end(states=cur_states) + cur_evaluator_res_df = pd.DataFrame(cur_evaluator_res).stack(1).unstack(0) + cur_evaluator_res_df.dropna(axis=1, how='all', inplace=True) + LOGGER.info(f'Extra val {cur_eval_title} metrics after epoch #{self.current_epoch}, ' + f'total {self.global_step} iterations:\n{cur_evaluator_res_df}') + for k, v in flatten_dict(cur_evaluator_res).items(): + self.log(f'extra_val_{cur_eval_title}_{k}', v) + + def _do_step(self, batch, batch_idx, mode='train', optimizer_idx=None, extra_val_key=None): + if optimizer_idx == 0: # step for generator + set_requires_grad(self.generator, True) + set_requires_grad(self.discriminator, False) + elif optimizer_idx == 1: # step for discriminator + set_requires_grad(self.generator, False) + set_requires_grad(self.discriminator, True) + + batch = self(batch) + + total_loss = 0 + metrics = {} + + if optimizer_idx is None or optimizer_idx == 0: # step for generator + total_loss, metrics = self.generator_loss(batch) + + elif optimizer_idx is None or optimizer_idx == 1: # step for discriminator + if self.config.losses.adversarial.weight > 0: + total_loss, metrics = self.discriminator_loss(batch) + + if self.get_ddp_rank() in (None, 0) and (batch_idx % self.visualize_each_iters == 0 or mode == 'test'): + if self.config.losses.adversarial.weight > 0: + if self.store_discr_outputs_for_vis: + with torch.no_grad(): + self.store_discr_outputs(batch) + vis_suffix = f'_{mode}' + if mode == 'extra_val': + vis_suffix += f'_{extra_val_key}' + self.visualizer(self.current_epoch, batch_idx, batch, suffix=vis_suffix) + + metrics_prefix = f'{mode}_' + if mode == 'extra_val': + metrics_prefix += f'{extra_val_key}_' + result = dict(loss=total_loss, log_info=add_prefix_to_keys(metrics, metrics_prefix)) + if mode == 'val': + result['val_evaluator_state'] = self.val_evaluator.process_batch(batch) + elif mode == 'test': + result['test_evaluator_state'] = self.test_evaluator.process_batch(batch) + elif mode == 'extra_val': + result[f'extra_val_{extra_val_key}_evaluator_state'] = self.extra_evaluators[extra_val_key].process_batch(batch) + + return result + + def get_current_generator(self, no_average=False): + if not no_average and not self.training and self.average_generator and self.generator_average is not None: + return self.generator_average + return self.generator + + def forward(self, batch: Dict[str, torch.Tensor]) -> Dict[str, torch.Tensor]: + """Pass data through generator and obtain at leas 'predicted_image' and 'inpainted' keys""" + raise NotImplementedError() + + def generator_loss(self, batch) -> Tuple[torch.Tensor, Dict[str, torch.Tensor]]: + raise NotImplementedError() + + def discriminator_loss(self, batch) -> Tuple[torch.Tensor, Dict[str, torch.Tensor]]: + raise NotImplementedError() + + def store_discr_outputs(self, batch): + out_size = batch['image'].shape[2:] + discr_real_out, _ = self.discriminator(batch['image']) + discr_fake_out, _ = self.discriminator(batch['predicted_image']) + batch['discr_output_real'] = F.interpolate(discr_real_out, size=out_size, mode='nearest') + batch['discr_output_fake'] = F.interpolate(discr_fake_out, size=out_size, mode='nearest') + batch['discr_output_diff'] = batch['discr_output_real'] - batch['discr_output_fake'] + + def get_ddp_rank(self): + return self.trainer.global_rank if (self.trainer.num_nodes * self.trainer.num_processes) > 1 else None diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/trainers/default.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/trainers/default.py new file mode 100644 index 00000000..29cd10ec --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/trainers/default.py @@ -0,0 +1,175 @@ +import logging + +import torch +import torch.nn.functional as F +from omegaconf import OmegaConf + +# from annotator.lama.saicinpainting.training.data.datasets import make_constant_area_crop_params +from annotator.lama.saicinpainting.training.losses.distance_weighting import make_mask_distance_weighter +from annotator.lama.saicinpainting.training.losses.feature_matching import feature_matching_loss, masked_l1_loss +# from annotator.lama.saicinpainting.training.modules.fake_fakes import FakeFakesGenerator +from annotator.lama.saicinpainting.training.trainers.base import BaseInpaintingTrainingModule, make_multiscale_noise +from annotator.lama.saicinpainting.utils import add_prefix_to_keys, get_ramp + +LOGGER = logging.getLogger(__name__) + + +def make_constant_area_crop_batch(batch, **kwargs): + crop_y, crop_x, crop_height, crop_width = make_constant_area_crop_params(img_height=batch['image'].shape[2], + img_width=batch['image'].shape[3], + **kwargs) + batch['image'] = batch['image'][:, :, crop_y : crop_y + crop_height, crop_x : crop_x + crop_width] + batch['mask'] = batch['mask'][:, :, crop_y: crop_y + crop_height, crop_x: crop_x + crop_width] + return batch + + +class DefaultInpaintingTrainingModule(BaseInpaintingTrainingModule): + def __init__(self, *args, concat_mask=True, rescale_scheduler_kwargs=None, image_to_discriminator='predicted_image', + add_noise_kwargs=None, noise_fill_hole=False, const_area_crop_kwargs=None, + distance_weighter_kwargs=None, distance_weighted_mask_for_discr=False, + fake_fakes_proba=0, fake_fakes_generator_kwargs=None, + **kwargs): + super().__init__(*args, **kwargs) + self.concat_mask = concat_mask + self.rescale_size_getter = get_ramp(**rescale_scheduler_kwargs) if rescale_scheduler_kwargs is not None else None + self.image_to_discriminator = image_to_discriminator + self.add_noise_kwargs = add_noise_kwargs + self.noise_fill_hole = noise_fill_hole + self.const_area_crop_kwargs = const_area_crop_kwargs + self.refine_mask_for_losses = make_mask_distance_weighter(**distance_weighter_kwargs) \ + if distance_weighter_kwargs is not None else None + self.distance_weighted_mask_for_discr = distance_weighted_mask_for_discr + + self.fake_fakes_proba = fake_fakes_proba + if self.fake_fakes_proba > 1e-3: + self.fake_fakes_gen = FakeFakesGenerator(**(fake_fakes_generator_kwargs or {})) + + def forward(self, batch): + if self.training and self.rescale_size_getter is not None: + cur_size = self.rescale_size_getter(self.global_step) + batch['image'] = F.interpolate(batch['image'], size=cur_size, mode='bilinear', align_corners=False) + batch['mask'] = F.interpolate(batch['mask'], size=cur_size, mode='nearest') + + if self.training and self.const_area_crop_kwargs is not None: + batch = make_constant_area_crop_batch(batch, **self.const_area_crop_kwargs) + + img = batch['image'] + mask = batch['mask'] + + masked_img = img * (1 - mask) + + if self.add_noise_kwargs is not None: + noise = make_multiscale_noise(masked_img, **self.add_noise_kwargs) + if self.noise_fill_hole: + masked_img = masked_img + mask * noise[:, :masked_img.shape[1]] + masked_img = torch.cat([masked_img, noise], dim=1) + + if self.concat_mask: + masked_img = torch.cat([masked_img, mask], dim=1) + + batch['predicted_image'] = self.generator(masked_img) + batch['inpainted'] = mask * batch['predicted_image'] + (1 - mask) * batch['image'] + + if self.fake_fakes_proba > 1e-3: + if self.training and torch.rand(1).item() < self.fake_fakes_proba: + batch['fake_fakes'], batch['fake_fakes_masks'] = self.fake_fakes_gen(img, mask) + batch['use_fake_fakes'] = True + else: + batch['fake_fakes'] = torch.zeros_like(img) + batch['fake_fakes_masks'] = torch.zeros_like(mask) + batch['use_fake_fakes'] = False + + batch['mask_for_losses'] = self.refine_mask_for_losses(img, batch['predicted_image'], mask) \ + if self.refine_mask_for_losses is not None and self.training \ + else mask + + return batch + + def generator_loss(self, batch): + img = batch['image'] + predicted_img = batch[self.image_to_discriminator] + original_mask = batch['mask'] + supervised_mask = batch['mask_for_losses'] + + # L1 + l1_value = masked_l1_loss(predicted_img, img, supervised_mask, + self.config.losses.l1.weight_known, + self.config.losses.l1.weight_missing) + + total_loss = l1_value + metrics = dict(gen_l1=l1_value) + + # vgg-based perceptual loss + if self.config.losses.perceptual.weight > 0: + pl_value = self.loss_pl(predicted_img, img, mask=supervised_mask).sum() * self.config.losses.perceptual.weight + total_loss = total_loss + pl_value + metrics['gen_pl'] = pl_value + + # discriminator + # adversarial_loss calls backward by itself + mask_for_discr = supervised_mask if self.distance_weighted_mask_for_discr else original_mask + self.adversarial_loss.pre_generator_step(real_batch=img, fake_batch=predicted_img, + generator=self.generator, discriminator=self.discriminator) + discr_real_pred, discr_real_features = self.discriminator(img) + discr_fake_pred, discr_fake_features = self.discriminator(predicted_img) + adv_gen_loss, adv_metrics = self.adversarial_loss.generator_loss(real_batch=img, + fake_batch=predicted_img, + discr_real_pred=discr_real_pred, + discr_fake_pred=discr_fake_pred, + mask=mask_for_discr) + total_loss = total_loss + adv_gen_loss + metrics['gen_adv'] = adv_gen_loss + metrics.update(add_prefix_to_keys(adv_metrics, 'adv_')) + + # feature matching + if self.config.losses.feature_matching.weight > 0: + need_mask_in_fm = OmegaConf.to_container(self.config.losses.feature_matching).get('pass_mask', False) + mask_for_fm = supervised_mask if need_mask_in_fm else None + fm_value = feature_matching_loss(discr_fake_features, discr_real_features, + mask=mask_for_fm) * self.config.losses.feature_matching.weight + total_loss = total_loss + fm_value + metrics['gen_fm'] = fm_value + + if self.loss_resnet_pl is not None: + resnet_pl_value = self.loss_resnet_pl(predicted_img, img) + total_loss = total_loss + resnet_pl_value + metrics['gen_resnet_pl'] = resnet_pl_value + + return total_loss, metrics + + def discriminator_loss(self, batch): + total_loss = 0 + metrics = {} + + predicted_img = batch[self.image_to_discriminator].detach() + self.adversarial_loss.pre_discriminator_step(real_batch=batch['image'], fake_batch=predicted_img, + generator=self.generator, discriminator=self.discriminator) + discr_real_pred, discr_real_features = self.discriminator(batch['image']) + discr_fake_pred, discr_fake_features = self.discriminator(predicted_img) + adv_discr_loss, adv_metrics = self.adversarial_loss.discriminator_loss(real_batch=batch['image'], + fake_batch=predicted_img, + discr_real_pred=discr_real_pred, + discr_fake_pred=discr_fake_pred, + mask=batch['mask']) + total_loss = total_loss + adv_discr_loss + metrics['discr_adv'] = adv_discr_loss + metrics.update(add_prefix_to_keys(adv_metrics, 'adv_')) + + + if batch.get('use_fake_fakes', False): + fake_fakes = batch['fake_fakes'] + self.adversarial_loss.pre_discriminator_step(real_batch=batch['image'], fake_batch=fake_fakes, + generator=self.generator, discriminator=self.discriminator) + discr_fake_fakes_pred, _ = self.discriminator(fake_fakes) + fake_fakes_adv_discr_loss, fake_fakes_adv_metrics = self.adversarial_loss.discriminator_loss( + real_batch=batch['image'], + fake_batch=fake_fakes, + discr_real_pred=discr_real_pred, + discr_fake_pred=discr_fake_fakes_pred, + mask=batch['mask'] + ) + total_loss = total_loss + fake_fakes_adv_discr_loss + metrics['discr_adv_fake_fakes'] = fake_fakes_adv_discr_loss + metrics.update(add_prefix_to_keys(fake_fakes_adv_metrics, 'adv_')) + + return total_loss, metrics diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/__init__.py new file mode 100644 index 00000000..d280fd8d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/__init__.py @@ -0,0 +1,15 @@ +import logging + +from annotator.lama.saicinpainting.training.visualizers.directory import DirectoryVisualizer +from annotator.lama.saicinpainting.training.visualizers.noop import NoopVisualizer + + +def make_visualizer(kind, **kwargs): + logging.info(f'Make visualizer {kind}') + + if kind == 'directory': + return DirectoryVisualizer(**kwargs) + if kind == 'noop': + return NoopVisualizer() + + raise ValueError(f'Unknown visualizer kind {kind}') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/base.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/base.py new file mode 100644 index 00000000..675f0168 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/base.py @@ -0,0 +1,73 @@ +import abc +from typing import Dict, List + +import numpy as np +import torch +from skimage import color +from skimage.segmentation import mark_boundaries + +from . import colors + +COLORS, _ = colors.generate_colors(151) # 151 - max classes for semantic segmentation + + +class BaseVisualizer: + @abc.abstractmethod + def __call__(self, epoch_i, batch_i, batch, suffix='', rank=None): + """ + Take a batch, make an image from it and visualize + """ + raise NotImplementedError() + + +def visualize_mask_and_images(images_dict: Dict[str, np.ndarray], keys: List[str], + last_without_mask=True, rescale_keys=None, mask_only_first=None, + black_mask=False) -> np.ndarray: + mask = images_dict['mask'] > 0.5 + result = [] + for i, k in enumerate(keys): + img = images_dict[k] + img = np.transpose(img, (1, 2, 0)) + + if rescale_keys is not None and k in rescale_keys: + img = img - img.min() + img /= img.max() + 1e-5 + if len(img.shape) == 2: + img = np.expand_dims(img, 2) + + if img.shape[2] == 1: + img = np.repeat(img, 3, axis=2) + elif (img.shape[2] > 3): + img_classes = img.argmax(2) + img = color.label2rgb(img_classes, colors=COLORS) + + if mask_only_first: + need_mark_boundaries = i == 0 + else: + need_mark_boundaries = i < len(keys) - 1 or not last_without_mask + + if need_mark_boundaries: + if black_mask: + img = img * (1 - mask[0][..., None]) + img = mark_boundaries(img, + mask[0], + color=(1., 0., 0.), + outline_color=(1., 1., 1.), + mode='thick') + result.append(img) + return np.concatenate(result, axis=1) + + +def visualize_mask_and_images_batch(batch: Dict[str, torch.Tensor], keys: List[str], max_items=10, + last_without_mask=True, rescale_keys=None) -> np.ndarray: + batch = {k: tens.detach().cpu().numpy() for k, tens in batch.items() + if k in keys or k == 'mask'} + + batch_size = next(iter(batch.values())).shape[0] + items_to_vis = min(batch_size, max_items) + result = [] + for i in range(items_to_vis): + cur_dct = {k: tens[i] for k, tens in batch.items()} + result.append(visualize_mask_and_images(cur_dct, keys, last_without_mask=last_without_mask, + rescale_keys=rescale_keys)) + return np.concatenate(result, axis=0) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/colors.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/colors.py new file mode 100644 index 00000000..9e9e3918 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/colors.py @@ -0,0 +1,76 @@ +import random +import colorsys + +import numpy as np +import matplotlib +matplotlib.use('agg') +import matplotlib.pyplot as plt +from matplotlib.colors import LinearSegmentedColormap + + +def generate_colors(nlabels, type='bright', first_color_black=False, last_color_black=True, verbose=False): + # https://stackoverflow.com/questions/14720331/how-to-generate-random-colors-in-matplotlib + """ + Creates a random colormap to be used together with matplotlib. Useful for segmentation tasks + :param nlabels: Number of labels (size of colormap) + :param type: 'bright' for strong colors, 'soft' for pastel colors + :param first_color_black: Option to use first color as black, True or False + :param last_color_black: Option to use last color as black, True or False + :param verbose: Prints the number of labels and shows the colormap. True or False + :return: colormap for matplotlib + """ + if type not in ('bright', 'soft'): + print ('Please choose "bright" or "soft" for type') + return + + if verbose: + print('Number of labels: ' + str(nlabels)) + + # Generate color map for bright colors, based on hsv + if type == 'bright': + randHSVcolors = [(np.random.uniform(low=0.0, high=1), + np.random.uniform(low=0.2, high=1), + np.random.uniform(low=0.9, high=1)) for i in range(nlabels)] + + # Convert HSV list to RGB + randRGBcolors = [] + for HSVcolor in randHSVcolors: + randRGBcolors.append(colorsys.hsv_to_rgb(HSVcolor[0], HSVcolor[1], HSVcolor[2])) + + if first_color_black: + randRGBcolors[0] = [0, 0, 0] + + if last_color_black: + randRGBcolors[-1] = [0, 0, 0] + + random_colormap = LinearSegmentedColormap.from_list('new_map', randRGBcolors, N=nlabels) + + # Generate soft pastel colors, by limiting the RGB spectrum + if type == 'soft': + low = 0.6 + high = 0.95 + randRGBcolors = [(np.random.uniform(low=low, high=high), + np.random.uniform(low=low, high=high), + np.random.uniform(low=low, high=high)) for i in range(nlabels)] + + if first_color_black: + randRGBcolors[0] = [0, 0, 0] + + if last_color_black: + randRGBcolors[-1] = [0, 0, 0] + random_colormap = LinearSegmentedColormap.from_list('new_map', randRGBcolors, N=nlabels) + + # Display colorbar + if verbose: + from matplotlib import colors, colorbar + from matplotlib import pyplot as plt + fig, ax = plt.subplots(1, 1, figsize=(15, 0.5)) + + bounds = np.linspace(0, nlabels, nlabels + 1) + norm = colors.BoundaryNorm(bounds, nlabels) + + cb = colorbar.ColorbarBase(ax, cmap=random_colormap, norm=norm, spacing='proportional', ticks=None, + boundaries=bounds, format='%1i', orientation=u'horizontal') + + return randRGBcolors, random_colormap + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/directory.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/directory.py new file mode 100644 index 00000000..a0a3b5eb --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/directory.py @@ -0,0 +1,36 @@ +import os + +import cv2 +import numpy as np + +from annotator.lama.saicinpainting.training.visualizers.base import BaseVisualizer, visualize_mask_and_images_batch +from annotator.lama.saicinpainting.utils import check_and_warn_input_range + + +class DirectoryVisualizer(BaseVisualizer): + DEFAULT_KEY_ORDER = 'image predicted_image inpainted'.split(' ') + + def __init__(self, outdir, key_order=DEFAULT_KEY_ORDER, max_items_in_batch=10, + last_without_mask=True, rescale_keys=None): + self.outdir = outdir + os.makedirs(self.outdir, exist_ok=True) + self.key_order = key_order + self.max_items_in_batch = max_items_in_batch + self.last_without_mask = last_without_mask + self.rescale_keys = rescale_keys + + def __call__(self, epoch_i, batch_i, batch, suffix='', rank=None): + check_and_warn_input_range(batch['image'], 0, 1, 'DirectoryVisualizer target image') + vis_img = visualize_mask_and_images_batch(batch, self.key_order, max_items=self.max_items_in_batch, + last_without_mask=self.last_without_mask, + rescale_keys=self.rescale_keys) + + vis_img = np.clip(vis_img * 255, 0, 255).astype('uint8') + + curoutdir = os.path.join(self.outdir, f'epoch{epoch_i:04d}{suffix}') + os.makedirs(curoutdir, exist_ok=True) + rank_suffix = f'_r{rank}' if rank is not None else '' + out_fname = os.path.join(curoutdir, f'batch{batch_i:07d}{rank_suffix}.jpg') + + vis_img = cv2.cvtColor(vis_img, cv2.COLOR_RGB2BGR) + cv2.imwrite(out_fname, vis_img) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/noop.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/noop.py new file mode 100644 index 00000000..4479597b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/training/visualizers/noop.py @@ -0,0 +1,9 @@ +from annotator.lama.saicinpainting.training.visualizers.base import BaseVisualizer + + +class NoopVisualizer(BaseVisualizer): + def __init__(self, *args, **kwargs): + pass + + def __call__(self, epoch_i, batch_i, batch, suffix='', rank=None): + pass diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/utils.py b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/utils.py new file mode 100644 index 00000000..f36f5130 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lama/saicinpainting/utils.py @@ -0,0 +1,174 @@ +import bisect +import functools +import logging +import numbers +import os +import signal +import sys +import traceback +import warnings + +import torch +from pytorch_lightning import seed_everything + +LOGGER = logging.getLogger(__name__) + + +def check_and_warn_input_range(tensor, min_value, max_value, name): + actual_min = tensor.min() + actual_max = tensor.max() + if actual_min < min_value or actual_max > max_value: + warnings.warn(f"{name} must be in {min_value}..{max_value} range, but it ranges {actual_min}..{actual_max}") + + +def sum_dict_with_prefix(target, cur_dict, prefix, default=0): + for k, v in cur_dict.items(): + target_key = prefix + k + target[target_key] = target.get(target_key, default) + v + + +def average_dicts(dict_list): + result = {} + norm = 1e-3 + for dct in dict_list: + sum_dict_with_prefix(result, dct, '') + norm += 1 + for k in list(result): + result[k] /= norm + return result + + +def add_prefix_to_keys(dct, prefix): + return {prefix + k: v for k, v in dct.items()} + + +def set_requires_grad(module, value): + for param in module.parameters(): + param.requires_grad = value + + +def flatten_dict(dct): + result = {} + for k, v in dct.items(): + if isinstance(k, tuple): + k = '_'.join(k) + if isinstance(v, dict): + for sub_k, sub_v in flatten_dict(v).items(): + result[f'{k}_{sub_k}'] = sub_v + else: + result[k] = v + return result + + +class LinearRamp: + def __init__(self, start_value=0, end_value=1, start_iter=-1, end_iter=0): + self.start_value = start_value + self.end_value = end_value + self.start_iter = start_iter + self.end_iter = end_iter + + def __call__(self, i): + if i < self.start_iter: + return self.start_value + if i >= self.end_iter: + return self.end_value + part = (i - self.start_iter) / (self.end_iter - self.start_iter) + return self.start_value * (1 - part) + self.end_value * part + + +class LadderRamp: + def __init__(self, start_iters, values): + self.start_iters = start_iters + self.values = values + assert len(values) == len(start_iters) + 1, (len(values), len(start_iters)) + + def __call__(self, i): + segment_i = bisect.bisect_right(self.start_iters, i) + return self.values[segment_i] + + +def get_ramp(kind='ladder', **kwargs): + if kind == 'linear': + return LinearRamp(**kwargs) + if kind == 'ladder': + return LadderRamp(**kwargs) + raise ValueError(f'Unexpected ramp kind: {kind}') + + +def print_traceback_handler(sig, frame): + LOGGER.warning(f'Received signal {sig}') + bt = ''.join(traceback.format_stack()) + LOGGER.warning(f'Requested stack trace:\n{bt}') + + +def register_debug_signal_handlers(sig=None, handler=print_traceback_handler): + LOGGER.warning(f'Setting signal {sig} handler {handler}') + signal.signal(sig, handler) + + +def handle_deterministic_config(config): + seed = dict(config).get('seed', None) + if seed is None: + return False + + seed_everything(seed) + return True + + +def get_shape(t): + if torch.is_tensor(t): + return tuple(t.shape) + elif isinstance(t, dict): + return {n: get_shape(q) for n, q in t.items()} + elif isinstance(t, (list, tuple)): + return [get_shape(q) for q in t] + elif isinstance(t, numbers.Number): + return type(t) + else: + raise ValueError('unexpected type {}'.format(type(t))) + + +def get_has_ddp_rank(): + master_port = os.environ.get('MASTER_PORT', None) + node_rank = os.environ.get('NODE_RANK', None) + local_rank = os.environ.get('LOCAL_RANK', None) + world_size = os.environ.get('WORLD_SIZE', None) + has_rank = master_port is not None or node_rank is not None or local_rank is not None or world_size is not None + return has_rank + + +def handle_ddp_subprocess(): + def main_decorator(main_func): + @functools.wraps(main_func) + def new_main(*args, **kwargs): + # Trainer sets MASTER_PORT, NODE_RANK, LOCAL_RANK, WORLD_SIZE + parent_cwd = os.environ.get('TRAINING_PARENT_WORK_DIR', None) + has_parent = parent_cwd is not None + has_rank = get_has_ddp_rank() + assert has_parent == has_rank, f'Inconsistent state: has_parent={has_parent}, has_rank={has_rank}' + + if has_parent: + # we are in the worker + sys.argv.extend([ + f'hydra.run.dir={parent_cwd}', + # 'hydra/hydra_logging=disabled', + # 'hydra/job_logging=disabled' + ]) + # do nothing if this is a top-level process + # TRAINING_PARENT_WORK_DIR is set in handle_ddp_parent_process after hydra initialization + + main_func(*args, **kwargs) + return new_main + return main_decorator + + +def handle_ddp_parent_process(): + parent_cwd = os.environ.get('TRAINING_PARENT_WORK_DIR', None) + has_parent = parent_cwd is not None + has_rank = get_has_ddp_rank() + assert has_parent == has_rank, f'Inconsistent state: has_parent={has_parent}, has_rank={has_rank}' + + if parent_cwd is None: + os.environ['TRAINING_PARENT_WORK_DIR'] = os.getcwd() + + return has_parent diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/__init__.py new file mode 100644 index 00000000..9b11e44a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/__init__.py @@ -0,0 +1,113 @@ +import cv2 +import numpy as np +import torch +import os +from modules import devices, shared +from annotator.annotator_path import models_path +from torchvision.transforms import transforms + +# AdelaiDepth/LeReS imports +from .leres.depthmap import estimateleres, estimateboost +from .leres.multi_depth_model_woauxi import RelDepthModel +from .leres.net_tools import strip_prefix_if_present + +# pix2pix/merge net imports +from .pix2pix.options.test_options import TestOptions +from .pix2pix.models.pix2pix4depth_model import Pix2Pix4DepthModel + +base_model_path = os.path.join(models_path, "leres") +old_modeldir = os.path.dirname(os.path.realpath(__file__)) + +remote_model_path_leres = "https://huggingface.co/lllyasviel/Annotators/resolve/main/res101.pth" +remote_model_path_pix2pix = "https://huggingface.co/lllyasviel/Annotators/resolve/main/latest_net_G.pth" + +model = None +pix2pixmodel = None + +def unload_leres_model(): + global model, pix2pixmodel + if model is not None: + model = model.cpu() + if pix2pixmodel is not None: + pix2pixmodel = pix2pixmodel.unload_network('G') + + +def apply_leres(input_image, thr_a, thr_b, boost=False): + global model, pix2pixmodel + if model is None: + model_path = os.path.join(base_model_path, "res101.pth") + old_model_path = os.path.join(old_modeldir, "res101.pth") + + if os.path.exists(old_model_path): + model_path = old_model_path + elif not os.path.exists(model_path): + from basicsr.utils.download_util import load_file_from_url + load_file_from_url(remote_model_path_leres, model_dir=base_model_path) + + if torch.cuda.is_available(): + checkpoint = torch.load(model_path) + else: + checkpoint = torch.load(model_path, map_location=torch.device('cpu')) + + model = RelDepthModel(backbone='resnext101') + model.load_state_dict(strip_prefix_if_present(checkpoint['depth_model'], "module."), strict=True) + del checkpoint + + if boost and pix2pixmodel is None: + pix2pixmodel_path = os.path.join(base_model_path, "latest_net_G.pth") + if not os.path.exists(pix2pixmodel_path): + from basicsr.utils.download_util import load_file_from_url + load_file_from_url(remote_model_path_pix2pix, model_dir=base_model_path) + + opt = TestOptions().parse() + if not torch.cuda.is_available(): + opt.gpu_ids = [] # cpu mode + pix2pixmodel = Pix2Pix4DepthModel(opt) + pix2pixmodel.save_dir = base_model_path + pix2pixmodel.load_networks('latest') + pix2pixmodel.eval() + + if devices.get_device_for("controlnet").type != 'mps': + model = model.to(devices.get_device_for("controlnet")) + + assert input_image.ndim == 3 + height, width, dim = input_image.shape + + with torch.no_grad(): + + if boost: + depth = estimateboost(input_image, model, 0, pix2pixmodel, max(width, height)) + else: + depth = estimateleres(input_image, model, width, height) + + numbytes=2 + depth_min = depth.min() + depth_max = depth.max() + max_val = (2**(8*numbytes))-1 + + # check output before normalizing and mapping to 16 bit + if depth_max - depth_min > np.finfo("float").eps: + out = max_val * (depth - depth_min) / (depth_max - depth_min) + else: + out = np.zeros(depth.shape) + + # single channel, 16 bit image + depth_image = out.astype("uint16") + + # convert to uint8 + depth_image = cv2.convertScaleAbs(depth_image, alpha=(255.0/65535.0)) + + # remove near + if thr_a != 0: + thr_a = ((thr_a/100)*255) + depth_image = cv2.threshold(depth_image, thr_a, 255, cv2.THRESH_TOZERO)[1] + + # invert image + depth_image = cv2.bitwise_not(depth_image) + + # remove bg + if thr_b != 0: + thr_b = ((thr_b/100)*255) + depth_image = cv2.threshold(depth_image, thr_b, 255, cv2.THRESH_TOZERO)[1] + + return depth_image diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/LICENSE b/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/LICENSE new file mode 100644 index 00000000..e0f1d07d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/LICENSE @@ -0,0 +1,23 @@ +https://github.com/thygate/stable-diffusion-webui-depthmap-script + +MIT License + +Copyright (c) 2023 Bob Thiry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/Resnet.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/Resnet.py new file mode 100644 index 00000000..f12c9975 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/Resnet.py @@ -0,0 +1,199 @@ +import torch.nn as nn +import torch.nn as NN + +__all__ = ['ResNet', 'resnet18', 'resnet34', 'resnet50', 'resnet101', + 'resnet152'] + + +model_urls = { + 'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth', + 'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth', + 'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth', + 'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth', + 'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth', +} + + +def conv3x3(in_planes, out_planes, stride=1): + """3x3 convolution with padding""" + return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride, + padding=1, bias=False) + + +class BasicBlock(nn.Module): + expansion = 1 + + def __init__(self, inplanes, planes, stride=1, downsample=None): + super(BasicBlock, self).__init__() + self.conv1 = conv3x3(inplanes, planes, stride) + self.bn1 = NN.BatchNorm2d(planes) #NN.BatchNorm2d + self.relu = nn.ReLU(inplace=True) + self.conv2 = conv3x3(planes, planes) + self.bn2 = NN.BatchNorm2d(planes) #NN.BatchNorm2d + self.downsample = downsample + self.stride = stride + + def forward(self, x): + residual = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + + if self.downsample is not None: + residual = self.downsample(x) + + out += residual + out = self.relu(out) + + return out + + +class Bottleneck(nn.Module): + expansion = 4 + + def __init__(self, inplanes, planes, stride=1, downsample=None): + super(Bottleneck, self).__init__() + self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False) + self.bn1 = NN.BatchNorm2d(planes) #NN.BatchNorm2d + self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, + padding=1, bias=False) + self.bn2 = NN.BatchNorm2d(planes) #NN.BatchNorm2d + self.conv3 = nn.Conv2d(planes, planes * self.expansion, kernel_size=1, bias=False) + self.bn3 = NN.BatchNorm2d(planes * self.expansion) #NN.BatchNorm2d + self.relu = nn.ReLU(inplace=True) + self.downsample = downsample + self.stride = stride + + def forward(self, x): + residual = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + out = self.relu(out) + + out = self.conv3(out) + out = self.bn3(out) + + if self.downsample is not None: + residual = self.downsample(x) + + out += residual + out = self.relu(out) + + return out + + +class ResNet(nn.Module): + + def __init__(self, block, layers, num_classes=1000): + self.inplanes = 64 + super(ResNet, self).__init__() + self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, + bias=False) + self.bn1 = NN.BatchNorm2d(64) #NN.BatchNorm2d + self.relu = nn.ReLU(inplace=True) + self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) + self.layer1 = self._make_layer(block, 64, layers[0]) + self.layer2 = self._make_layer(block, 128, layers[1], stride=2) + self.layer3 = self._make_layer(block, 256, layers[2], stride=2) + self.layer4 = self._make_layer(block, 512, layers[3], stride=2) + #self.avgpool = nn.AvgPool2d(7, stride=1) + #self.fc = nn.Linear(512 * block.expansion, num_classes) + + for m in self.modules(): + if isinstance(m, nn.Conv2d): + nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') + elif isinstance(m, nn.BatchNorm2d): + nn.init.constant_(m.weight, 1) + nn.init.constant_(m.bias, 0) + + def _make_layer(self, block, planes, blocks, stride=1): + downsample = None + if stride != 1 or self.inplanes != planes * block.expansion: + downsample = nn.Sequential( + nn.Conv2d(self.inplanes, planes * block.expansion, + kernel_size=1, stride=stride, bias=False), + NN.BatchNorm2d(planes * block.expansion), #NN.BatchNorm2d + ) + + layers = [] + layers.append(block(self.inplanes, planes, stride, downsample)) + self.inplanes = planes * block.expansion + for i in range(1, blocks): + layers.append(block(self.inplanes, planes)) + + return nn.Sequential(*layers) + + def forward(self, x): + features = [] + + x = self.conv1(x) + x = self.bn1(x) + x = self.relu(x) + x = self.maxpool(x) + + x = self.layer1(x) + features.append(x) + x = self.layer2(x) + features.append(x) + x = self.layer3(x) + features.append(x) + x = self.layer4(x) + features.append(x) + + return features + + +def resnet18(pretrained=True, **kwargs): + """Constructs a ResNet-18 model. + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + """ + model = ResNet(BasicBlock, [2, 2, 2, 2], **kwargs) + return model + + +def resnet34(pretrained=True, **kwargs): + """Constructs a ResNet-34 model. + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + """ + model = ResNet(BasicBlock, [3, 4, 6, 3], **kwargs) + return model + + +def resnet50(pretrained=True, **kwargs): + """Constructs a ResNet-50 model. + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + """ + model = ResNet(Bottleneck, [3, 4, 6, 3], **kwargs) + + return model + + +def resnet101(pretrained=True, **kwargs): + """Constructs a ResNet-101 model. + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + """ + model = ResNet(Bottleneck, [3, 4, 23, 3], **kwargs) + + return model + + +def resnet152(pretrained=True, **kwargs): + """Constructs a ResNet-152 model. + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + """ + model = ResNet(Bottleneck, [3, 8, 36, 3], **kwargs) + return model diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/Resnext_torch.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/Resnext_torch.py new file mode 100644 index 00000000..9af54fcc --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/Resnext_torch.py @@ -0,0 +1,237 @@ +#!/usr/bin/env python +# coding: utf-8 +import torch.nn as nn + +try: + from urllib import urlretrieve +except ImportError: + from urllib.request import urlretrieve + +__all__ = ['resnext101_32x8d'] + + +model_urls = { + 'resnext50_32x4d': 'https://download.pytorch.org/models/resnext50_32x4d-7cdf4587.pth', + 'resnext101_32x8d': 'https://download.pytorch.org/models/resnext101_32x8d-8ba56ff5.pth', +} + + +def conv3x3(in_planes, out_planes, stride=1, groups=1, dilation=1): + """3x3 convolution with padding""" + return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride, + padding=dilation, groups=groups, bias=False, dilation=dilation) + + +def conv1x1(in_planes, out_planes, stride=1): + """1x1 convolution""" + return nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=stride, bias=False) + + +class BasicBlock(nn.Module): + expansion = 1 + + def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1, + base_width=64, dilation=1, norm_layer=None): + super(BasicBlock, self).__init__() + if norm_layer is None: + norm_layer = nn.BatchNorm2d + if groups != 1 or base_width != 64: + raise ValueError('BasicBlock only supports groups=1 and base_width=64') + if dilation > 1: + raise NotImplementedError("Dilation > 1 not supported in BasicBlock") + # Both self.conv1 and self.downsample layers downsample the input when stride != 1 + self.conv1 = conv3x3(inplanes, planes, stride) + self.bn1 = norm_layer(planes) + self.relu = nn.ReLU(inplace=True) + self.conv2 = conv3x3(planes, planes) + self.bn2 = norm_layer(planes) + self.downsample = downsample + self.stride = stride + + def forward(self, x): + identity = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + + if self.downsample is not None: + identity = self.downsample(x) + + out += identity + out = self.relu(out) + + return out + + +class Bottleneck(nn.Module): + # Bottleneck in torchvision places the stride for downsampling at 3x3 convolution(self.conv2) + # while original implementation places the stride at the first 1x1 convolution(self.conv1) + # according to "Deep residual learning for image recognition"https://arxiv.org/abs/1512.03385. + # This variant is also known as ResNet V1.5 and improves accuracy according to + # https://ngc.nvidia.com/catalog/model-scripts/nvidia:resnet_50_v1_5_for_pytorch. + + expansion = 4 + + def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1, + base_width=64, dilation=1, norm_layer=None): + super(Bottleneck, self).__init__() + if norm_layer is None: + norm_layer = nn.BatchNorm2d + width = int(planes * (base_width / 64.)) * groups + # Both self.conv2 and self.downsample layers downsample the input when stride != 1 + self.conv1 = conv1x1(inplanes, width) + self.bn1 = norm_layer(width) + self.conv2 = conv3x3(width, width, stride, groups, dilation) + self.bn2 = norm_layer(width) + self.conv3 = conv1x1(width, planes * self.expansion) + self.bn3 = norm_layer(planes * self.expansion) + self.relu = nn.ReLU(inplace=True) + self.downsample = downsample + self.stride = stride + + def forward(self, x): + identity = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + out = self.relu(out) + + out = self.conv3(out) + out = self.bn3(out) + + if self.downsample is not None: + identity = self.downsample(x) + + out += identity + out = self.relu(out) + + return out + + +class ResNet(nn.Module): + + def __init__(self, block, layers, num_classes=1000, zero_init_residual=False, + groups=1, width_per_group=64, replace_stride_with_dilation=None, + norm_layer=None): + super(ResNet, self).__init__() + if norm_layer is None: + norm_layer = nn.BatchNorm2d + self._norm_layer = norm_layer + + self.inplanes = 64 + self.dilation = 1 + if replace_stride_with_dilation is None: + # each element in the tuple indicates if we should replace + # the 2x2 stride with a dilated convolution instead + replace_stride_with_dilation = [False, False, False] + if len(replace_stride_with_dilation) != 3: + raise ValueError("replace_stride_with_dilation should be None " + "or a 3-element tuple, got {}".format(replace_stride_with_dilation)) + self.groups = groups + self.base_width = width_per_group + self.conv1 = nn.Conv2d(3, self.inplanes, kernel_size=7, stride=2, padding=3, + bias=False) + self.bn1 = norm_layer(self.inplanes) + self.relu = nn.ReLU(inplace=True) + self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) + self.layer1 = self._make_layer(block, 64, layers[0]) + self.layer2 = self._make_layer(block, 128, layers[1], stride=2, + dilate=replace_stride_with_dilation[0]) + self.layer3 = self._make_layer(block, 256, layers[2], stride=2, + dilate=replace_stride_with_dilation[1]) + self.layer4 = self._make_layer(block, 512, layers[3], stride=2, + dilate=replace_stride_with_dilation[2]) + #self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) + #self.fc = nn.Linear(512 * block.expansion, num_classes) + + for m in self.modules(): + if isinstance(m, nn.Conv2d): + nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') + elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)): + nn.init.constant_(m.weight, 1) + nn.init.constant_(m.bias, 0) + + # Zero-initialize the last BN in each residual branch, + # so that the residual branch starts with zeros, and each residual block behaves like an identity. + # This improves the model by 0.2~0.3% according to https://arxiv.org/abs/1706.02677 + if zero_init_residual: + for m in self.modules(): + if isinstance(m, Bottleneck): + nn.init.constant_(m.bn3.weight, 0) + elif isinstance(m, BasicBlock): + nn.init.constant_(m.bn2.weight, 0) + + def _make_layer(self, block, planes, blocks, stride=1, dilate=False): + norm_layer = self._norm_layer + downsample = None + previous_dilation = self.dilation + if dilate: + self.dilation *= stride + stride = 1 + if stride != 1 or self.inplanes != planes * block.expansion: + downsample = nn.Sequential( + conv1x1(self.inplanes, planes * block.expansion, stride), + norm_layer(planes * block.expansion), + ) + + layers = [] + layers.append(block(self.inplanes, planes, stride, downsample, self.groups, + self.base_width, previous_dilation, norm_layer)) + self.inplanes = planes * block.expansion + for _ in range(1, blocks): + layers.append(block(self.inplanes, planes, groups=self.groups, + base_width=self.base_width, dilation=self.dilation, + norm_layer=norm_layer)) + + return nn.Sequential(*layers) + + def _forward_impl(self, x): + # See note [TorchScript super()] + features = [] + x = self.conv1(x) + x = self.bn1(x) + x = self.relu(x) + x = self.maxpool(x) + + x = self.layer1(x) + features.append(x) + + x = self.layer2(x) + features.append(x) + + x = self.layer3(x) + features.append(x) + + x = self.layer4(x) + features.append(x) + + #x = self.avgpool(x) + #x = torch.flatten(x, 1) + #x = self.fc(x) + + return features + + def forward(self, x): + return self._forward_impl(x) + + + +def resnext101_32x8d(pretrained=True, **kwargs): + """Constructs a ResNet-152 model. + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + """ + kwargs['groups'] = 32 + kwargs['width_per_group'] = 8 + + model = ResNet(Bottleneck, [3, 4, 23, 3], **kwargs) + return model + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/depthmap.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/depthmap.py new file mode 100644 index 00000000..ebceecbe --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/depthmap.py @@ -0,0 +1,546 @@ +# Author: thygate +# https://github.com/thygate/stable-diffusion-webui-depthmap-script + +from modules import devices +from modules.shared import opts +from torchvision.transforms import transforms +from operator import getitem + +import torch, gc +import cv2 +import numpy as np +import skimage.measure + +whole_size_threshold = 1600 # R_max from the paper +pix2pixsize = 1024 + +def scale_torch(img): + """ + Scale the image and output it in torch.tensor. + :param img: input rgb is in shape [H, W, C], input depth/disp is in shape [H, W] + :param scale: the scale factor. float + :return: img. [C, H, W] + """ + if len(img.shape) == 2: + img = img[np.newaxis, :, :] + if img.shape[2] == 3: + transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.485, 0.456, 0.406) , (0.229, 0.224, 0.225) )]) + img = transform(img.astype(np.float32)) + else: + img = img.astype(np.float32) + img = torch.from_numpy(img) + return img + +def estimateleres(img, model, w, h): + # leres transform input + rgb_c = img[:, :, ::-1].copy() + A_resize = cv2.resize(rgb_c, (w, h)) + img_torch = scale_torch(A_resize)[None, :, :, :] + + # compute + with torch.no_grad(): + img_torch = img_torch.to(devices.get_device_for("controlnet")) + prediction = model.depth_model(img_torch) + + prediction = prediction.squeeze().cpu().numpy() + prediction = cv2.resize(prediction, (img.shape[1], img.shape[0]), interpolation=cv2.INTER_CUBIC) + + return prediction + +def generatemask(size): + # Generates a Guassian mask + mask = np.zeros(size, dtype=np.float32) + sigma = int(size[0]/16) + k_size = int(2 * np.ceil(2 * int(size[0]/16)) + 1) + mask[int(0.15*size[0]):size[0] - int(0.15*size[0]), int(0.15*size[1]): size[1] - int(0.15*size[1])] = 1 + mask = cv2.GaussianBlur(mask, (int(k_size), int(k_size)), sigma) + mask = (mask - mask.min()) / (mask.max() - mask.min()) + mask = mask.astype(np.float32) + return mask + +def resizewithpool(img, size): + i_size = img.shape[0] + n = int(np.floor(i_size/size)) + + out = skimage.measure.block_reduce(img, (n, n), np.max) + return out + +def rgb2gray(rgb): + # Converts rgb to gray + return np.dot(rgb[..., :3], [0.2989, 0.5870, 0.1140]) + +def calculateprocessingres(img, basesize, confidence=0.1, scale_threshold=3, whole_size_threshold=3000): + # Returns the R_x resolution described in section 5 of the main paper. + + # Parameters: + # img :input rgb image + # basesize : size the dilation kernel which is equal to receptive field of the network. + # confidence: value of x in R_x; allowed percentage of pixels that are not getting any contextual cue. + # scale_threshold: maximum allowed upscaling on the input image ; it has been set to 3. + # whole_size_threshold: maximum allowed resolution. (R_max from section 6 of the main paper) + + # Returns: + # outputsize_scale*speed_scale :The computed R_x resolution + # patch_scale: K parameter from section 6 of the paper + + # speed scale parameter is to process every image in a smaller size to accelerate the R_x resolution search + speed_scale = 32 + image_dim = int(min(img.shape[0:2])) + + gray = rgb2gray(img) + grad = np.abs(cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)) + np.abs(cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)) + grad = cv2.resize(grad, (image_dim, image_dim), cv2.INTER_AREA) + + # thresholding the gradient map to generate the edge-map as a proxy of the contextual cues + m = grad.min() + M = grad.max() + middle = m + (0.4 * (M - m)) + grad[grad < middle] = 0 + grad[grad >= middle] = 1 + + # dilation kernel with size of the receptive field + kernel = np.ones((int(basesize/speed_scale), int(basesize/speed_scale)), float) + # dilation kernel with size of the a quarter of receptive field used to compute k + # as described in section 6 of main paper + kernel2 = np.ones((int(basesize / (4*speed_scale)), int(basesize / (4*speed_scale))), float) + + # Output resolution limit set by the whole_size_threshold and scale_threshold. + threshold = min(whole_size_threshold, scale_threshold * max(img.shape[:2])) + + outputsize_scale = basesize / speed_scale + for p_size in range(int(basesize/speed_scale), int(threshold/speed_scale), int(basesize / (2*speed_scale))): + grad_resized = resizewithpool(grad, p_size) + grad_resized = cv2.resize(grad_resized, (p_size, p_size), cv2.INTER_NEAREST) + grad_resized[grad_resized >= 0.5] = 1 + grad_resized[grad_resized < 0.5] = 0 + + dilated = cv2.dilate(grad_resized, kernel, iterations=1) + meanvalue = (1-dilated).mean() + if meanvalue > confidence: + break + else: + outputsize_scale = p_size + + grad_region = cv2.dilate(grad_resized, kernel2, iterations=1) + patch_scale = grad_region.mean() + + return int(outputsize_scale*speed_scale), patch_scale + +# Generate a double-input depth estimation +def doubleestimate(img, size1, size2, pix2pixsize, model, net_type, pix2pixmodel): + # Generate the low resolution estimation + estimate1 = singleestimate(img, size1, model, net_type) + # Resize to the inference size of merge network. + estimate1 = cv2.resize(estimate1, (pix2pixsize, pix2pixsize), interpolation=cv2.INTER_CUBIC) + + # Generate the high resolution estimation + estimate2 = singleestimate(img, size2, model, net_type) + # Resize to the inference size of merge network. + estimate2 = cv2.resize(estimate2, (pix2pixsize, pix2pixsize), interpolation=cv2.INTER_CUBIC) + + # Inference on the merge model + pix2pixmodel.set_input(estimate1, estimate2) + pix2pixmodel.test() + visuals = pix2pixmodel.get_current_visuals() + prediction_mapped = visuals['fake_B'] + prediction_mapped = (prediction_mapped+1)/2 + prediction_mapped = (prediction_mapped - torch.min(prediction_mapped)) / ( + torch.max(prediction_mapped) - torch.min(prediction_mapped)) + prediction_mapped = prediction_mapped.squeeze().cpu().numpy() + + return prediction_mapped + +# Generate a single-input depth estimation +def singleestimate(img, msize, model, net_type): + # if net_type == 0: + return estimateleres(img, model, msize, msize) + # else: + # return estimatemidasBoost(img, model, msize, msize) + +def applyGridpatch(blsize, stride, img, box): + # Extract a simple grid patch. + counter1 = 0 + patch_bound_list = {} + for k in range(blsize, img.shape[1] - blsize, stride): + for j in range(blsize, img.shape[0] - blsize, stride): + patch_bound_list[str(counter1)] = {} + patchbounds = [j - blsize, k - blsize, j - blsize + 2 * blsize, k - blsize + 2 * blsize] + patch_bound = [box[0] + patchbounds[1], box[1] + patchbounds[0], patchbounds[3] - patchbounds[1], + patchbounds[2] - patchbounds[0]] + patch_bound_list[str(counter1)]['rect'] = patch_bound + patch_bound_list[str(counter1)]['size'] = patch_bound[2] + counter1 = counter1 + 1 + return patch_bound_list + +# Generating local patches to perform the local refinement described in section 6 of the main paper. +def generatepatchs(img, base_size): + + # Compute the gradients as a proxy of the contextual cues. + img_gray = rgb2gray(img) + whole_grad = np.abs(cv2.Sobel(img_gray, cv2.CV_64F, 0, 1, ksize=3)) +\ + np.abs(cv2.Sobel(img_gray, cv2.CV_64F, 1, 0, ksize=3)) + + threshold = whole_grad[whole_grad > 0].mean() + whole_grad[whole_grad < threshold] = 0 + + # We use the integral image to speed-up the evaluation of the amount of gradients for each patch. + gf = whole_grad.sum()/len(whole_grad.reshape(-1)) + grad_integral_image = cv2.integral(whole_grad) + + # Variables are selected such that the initial patch size would be the receptive field size + # and the stride is set to 1/3 of the receptive field size. + blsize = int(round(base_size/2)) + stride = int(round(blsize*0.75)) + + # Get initial Grid + patch_bound_list = applyGridpatch(blsize, stride, img, [0, 0, 0, 0]) + + # Refine initial Grid of patches by discarding the flat (in terms of gradients of the rgb image) ones. Refine + # each patch size to ensure that there will be enough depth cues for the network to generate a consistent depth map. + print("Selecting patches ...") + patch_bound_list = adaptiveselection(grad_integral_image, patch_bound_list, gf) + + # Sort the patch list to make sure the merging operation will be done with the correct order: starting from biggest + # patch + patchset = sorted(patch_bound_list.items(), key=lambda x: getitem(x[1], 'size'), reverse=True) + return patchset + +def getGF_fromintegral(integralimage, rect): + # Computes the gradient density of a given patch from the gradient integral image. + x1 = rect[1] + x2 = rect[1]+rect[3] + y1 = rect[0] + y2 = rect[0]+rect[2] + value = integralimage[x2, y2]-integralimage[x1, y2]-integralimage[x2, y1]+integralimage[x1, y1] + return value + +# Adaptively select patches +def adaptiveselection(integral_grad, patch_bound_list, gf): + patchlist = {} + count = 0 + height, width = integral_grad.shape + + search_step = int(32/factor) + + # Go through all patches + for c in range(len(patch_bound_list)): + # Get patch + bbox = patch_bound_list[str(c)]['rect'] + + # Compute the amount of gradients present in the patch from the integral image. + cgf = getGF_fromintegral(integral_grad, bbox)/(bbox[2]*bbox[3]) + + # Check if patching is beneficial by comparing the gradient density of the patch to + # the gradient density of the whole image + if cgf >= gf: + bbox_test = bbox.copy() + patchlist[str(count)] = {} + + # Enlarge each patch until the gradient density of the patch is equal + # to the whole image gradient density + while True: + + bbox_test[0] = bbox_test[0] - int(search_step/2) + bbox_test[1] = bbox_test[1] - int(search_step/2) + + bbox_test[2] = bbox_test[2] + search_step + bbox_test[3] = bbox_test[3] + search_step + + # Check if we are still within the image + if bbox_test[0] < 0 or bbox_test[1] < 0 or bbox_test[1] + bbox_test[3] >= height \ + or bbox_test[0] + bbox_test[2] >= width: + break + + # Compare gradient density + cgf = getGF_fromintegral(integral_grad, bbox_test)/(bbox_test[2]*bbox_test[3]) + if cgf < gf: + break + bbox = bbox_test.copy() + + # Add patch to selected patches + patchlist[str(count)]['rect'] = bbox + patchlist[str(count)]['size'] = bbox[2] + count = count + 1 + + # Return selected patches + return patchlist + +def impatch(image, rect): + # Extract the given patch pixels from a given image. + w1 = rect[0] + h1 = rect[1] + w2 = w1 + rect[2] + h2 = h1 + rect[3] + image_patch = image[h1:h2, w1:w2] + return image_patch + +class ImageandPatchs: + def __init__(self, root_dir, name, patchsinfo, rgb_image, scale=1): + self.root_dir = root_dir + self.patchsinfo = patchsinfo + self.name = name + self.patchs = patchsinfo + self.scale = scale + + self.rgb_image = cv2.resize(rgb_image, (round(rgb_image.shape[1]*scale), round(rgb_image.shape[0]*scale)), + interpolation=cv2.INTER_CUBIC) + + self.do_have_estimate = False + self.estimation_updated_image = None + self.estimation_base_image = None + + def __len__(self): + return len(self.patchs) + + def set_base_estimate(self, est): + self.estimation_base_image = est + if self.estimation_updated_image is not None: + self.do_have_estimate = True + + def set_updated_estimate(self, est): + self.estimation_updated_image = est + if self.estimation_base_image is not None: + self.do_have_estimate = True + + def __getitem__(self, index): + patch_id = int(self.patchs[index][0]) + rect = np.array(self.patchs[index][1]['rect']) + msize = self.patchs[index][1]['size'] + + ## applying scale to rect: + rect = np.round(rect * self.scale) + rect = rect.astype('int') + msize = round(msize * self.scale) + + patch_rgb = impatch(self.rgb_image, rect) + if self.do_have_estimate: + patch_whole_estimate_base = impatch(self.estimation_base_image, rect) + patch_whole_estimate_updated = impatch(self.estimation_updated_image, rect) + return {'patch_rgb': patch_rgb, 'patch_whole_estimate_base': patch_whole_estimate_base, + 'patch_whole_estimate_updated': patch_whole_estimate_updated, 'rect': rect, + 'size': msize, 'id': patch_id} + else: + return {'patch_rgb': patch_rgb, 'rect': rect, 'size': msize, 'id': patch_id} + + def print_options(self, opt): + """Print and save options + + It will print both current options and default values(if different). + It will save options into a text file / [checkpoints_dir] / opt.txt + """ + message = '' + message += '----------------- Options ---------------\n' + for k, v in sorted(vars(opt).items()): + comment = '' + default = self.parser.get_default(k) + if v != default: + comment = '\t[default: %s]' % str(default) + message += '{:>25}: {:<30}{}\n'.format(str(k), str(v), comment) + message += '----------------- End -------------------' + print(message) + + # save to the disk + """ + expr_dir = os.path.join(opt.checkpoints_dir, opt.name) + util.mkdirs(expr_dir) + file_name = os.path.join(expr_dir, '{}_opt.txt'.format(opt.phase)) + with open(file_name, 'wt') as opt_file: + opt_file.write(message) + opt_file.write('\n') + """ + + def parse(self): + """Parse our options, create checkpoints directory suffix, and set up gpu device.""" + opt = self.gather_options() + opt.isTrain = self.isTrain # train or test + + # process opt.suffix + if opt.suffix: + suffix = ('_' + opt.suffix.format(**vars(opt))) if opt.suffix != '' else '' + opt.name = opt.name + suffix + + #self.print_options(opt) + + # set gpu ids + str_ids = opt.gpu_ids.split(',') + opt.gpu_ids = [] + for str_id in str_ids: + id = int(str_id) + if id >= 0: + opt.gpu_ids.append(id) + #if len(opt.gpu_ids) > 0: + # torch.cuda.set_device(opt.gpu_ids[0]) + + self.opt = opt + return self.opt + + +def estimateboost(img, model, model_type, pix2pixmodel, max_res=512): + global whole_size_threshold + + # get settings + if hasattr(opts, 'depthmap_script_boost_rmax'): + whole_size_threshold = opts.depthmap_script_boost_rmax + + if model_type == 0: #leres + net_receptive_field_size = 448 + patch_netsize = 2 * net_receptive_field_size + elif model_type == 1: #dpt_beit_large_512 + net_receptive_field_size = 512 + patch_netsize = 2 * net_receptive_field_size + else: #other midas + net_receptive_field_size = 384 + patch_netsize = 2 * net_receptive_field_size + + gc.collect() + devices.torch_gc() + + # Generate mask used to smoothly blend the local pathc estimations to the base estimate. + # It is arbitrarily large to avoid artifacts during rescaling for each crop. + mask_org = generatemask((3000, 3000)) + mask = mask_org.copy() + + # Value x of R_x defined in the section 5 of the main paper. + r_threshold_value = 0.2 + #if R0: + # r_threshold_value = 0 + + input_resolution = img.shape + scale_threshold = 3 # Allows up-scaling with a scale up to 3 + + # Find the best input resolution R-x. The resolution search described in section 5-double estimation of the main paper and section B of the + # supplementary material. + whole_image_optimal_size, patch_scale = calculateprocessingres(img, net_receptive_field_size, r_threshold_value, scale_threshold, whole_size_threshold) + + # print('wholeImage being processed in :', whole_image_optimal_size) + + # Generate the base estimate using the double estimation. + whole_estimate = doubleestimate(img, net_receptive_field_size, whole_image_optimal_size, pix2pixsize, model, model_type, pix2pixmodel) + + # Compute the multiplier described in section 6 of the main paper to make sure our initial patch can select + # small high-density regions of the image. + global factor + factor = max(min(1, 4 * patch_scale * whole_image_optimal_size / whole_size_threshold), 0.2) + # print('Adjust factor is:', 1/factor) + + # Check if Local boosting is beneficial. + if max_res < whole_image_optimal_size: + # print("No Local boosting. Specified Max Res is smaller than R20, Returning doubleestimate result") + return cv2.resize(whole_estimate, (input_resolution[1], input_resolution[0]), interpolation=cv2.INTER_CUBIC) + + # Compute the default target resolution. + if img.shape[0] > img.shape[1]: + a = 2 * whole_image_optimal_size + b = round(2 * whole_image_optimal_size * img.shape[1] / img.shape[0]) + else: + a = round(2 * whole_image_optimal_size * img.shape[0] / img.shape[1]) + b = 2 * whole_image_optimal_size + b = int(round(b / factor)) + a = int(round(a / factor)) + + """ + # recompute a, b and saturate to max res. + if max(a,b) > max_res: + print('Default Res is higher than max-res: Reducing final resolution') + if img.shape[0] > img.shape[1]: + a = max_res + b = round(max_res * img.shape[1] / img.shape[0]) + else: + a = round(max_res * img.shape[0] / img.shape[1]) + b = max_res + b = int(b) + a = int(a) + """ + + img = cv2.resize(img, (b, a), interpolation=cv2.INTER_CUBIC) + + # Extract selected patches for local refinement + base_size = net_receptive_field_size * 2 + patchset = generatepatchs(img, base_size) + + # print('Target resolution: ', img.shape) + + # Computing a scale in case user prompted to generate the results as the same resolution of the input. + # Notice that our method output resolution is independent of the input resolution and this parameter will only + # enable a scaling operation during the local patch merge implementation to generate results with the same resolution + # as the input. + """ + if output_resolution == 1: + mergein_scale = input_resolution[0] / img.shape[0] + print('Dynamicly change merged-in resolution; scale:', mergein_scale) + else: + mergein_scale = 1 + """ + # always rescale to input res for now + mergein_scale = input_resolution[0] / img.shape[0] + + imageandpatchs = ImageandPatchs('', '', patchset, img, mergein_scale) + whole_estimate_resized = cv2.resize(whole_estimate, (round(img.shape[1]*mergein_scale), + round(img.shape[0]*mergein_scale)), interpolation=cv2.INTER_CUBIC) + imageandpatchs.set_base_estimate(whole_estimate_resized.copy()) + imageandpatchs.set_updated_estimate(whole_estimate_resized.copy()) + + print('Resulting depthmap resolution will be :', whole_estimate_resized.shape[:2]) + print('Patches to process: '+str(len(imageandpatchs))) + + # Enumerate through all patches, generate their estimations and refining the base estimate. + for patch_ind in range(len(imageandpatchs)): + + # Get patch information + patch = imageandpatchs[patch_ind] # patch object + patch_rgb = patch['patch_rgb'] # rgb patch + patch_whole_estimate_base = patch['patch_whole_estimate_base'] # corresponding patch from base + rect = patch['rect'] # patch size and location + patch_id = patch['id'] # patch ID + org_size = patch_whole_estimate_base.shape # the original size from the unscaled input + print('\t Processing patch', patch_ind, '/', len(imageandpatchs)-1, '|', rect) + + # We apply double estimation for patches. The high resolution value is fixed to twice the receptive + # field size of the network for patches to accelerate the process. + patch_estimation = doubleestimate(patch_rgb, net_receptive_field_size, patch_netsize, pix2pixsize, model, model_type, pix2pixmodel) + patch_estimation = cv2.resize(patch_estimation, (pix2pixsize, pix2pixsize), interpolation=cv2.INTER_CUBIC) + patch_whole_estimate_base = cv2.resize(patch_whole_estimate_base, (pix2pixsize, pix2pixsize), interpolation=cv2.INTER_CUBIC) + + # Merging the patch estimation into the base estimate using our merge network: + # We feed the patch estimation and the same region from the updated base estimate to the merge network + # to generate the target estimate for the corresponding region. + pix2pixmodel.set_input(patch_whole_estimate_base, patch_estimation) + + # Run merging network + pix2pixmodel.test() + visuals = pix2pixmodel.get_current_visuals() + + prediction_mapped = visuals['fake_B'] + prediction_mapped = (prediction_mapped+1)/2 + prediction_mapped = prediction_mapped.squeeze().cpu().numpy() + + mapped = prediction_mapped + + # We use a simple linear polynomial to make sure the result of the merge network would match the values of + # base estimate + p_coef = np.polyfit(mapped.reshape(-1), patch_whole_estimate_base.reshape(-1), deg=1) + merged = np.polyval(p_coef, mapped.reshape(-1)).reshape(mapped.shape) + + merged = cv2.resize(merged, (org_size[1],org_size[0]), interpolation=cv2.INTER_CUBIC) + + # Get patch size and location + w1 = rect[0] + h1 = rect[1] + w2 = w1 + rect[2] + h2 = h1 + rect[3] + + # To speed up the implementation, we only generate the Gaussian mask once with a sufficiently large size + # and resize it to our needed size while merging the patches. + if mask.shape != org_size: + mask = cv2.resize(mask_org, (org_size[1],org_size[0]), interpolation=cv2.INTER_LINEAR) + + tobemergedto = imageandpatchs.estimation_updated_image + + # Update the whole estimation: + # We use a simple Gaussian mask to blend the merged patch region with the base estimate to ensure seamless + # blending at the boundaries of the patch region. + tobemergedto[h1:h2, w1:w2] = np.multiply(tobemergedto[h1:h2, w1:w2], 1 - mask) + np.multiply(merged, mask) + imageandpatchs.set_updated_estimate(tobemergedto) + + # output + return cv2.resize(imageandpatchs.estimation_updated_image, (input_resolution[1], input_resolution[0]), interpolation=cv2.INTER_CUBIC) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/multi_depth_model_woauxi.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/multi_depth_model_woauxi.py new file mode 100644 index 00000000..822ab089 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/multi_depth_model_woauxi.py @@ -0,0 +1,34 @@ +from . import network_auxi as network +from .net_tools import get_func +import torch +import torch.nn as nn +from modules import devices + +class RelDepthModel(nn.Module): + def __init__(self, backbone='resnet50'): + super(RelDepthModel, self).__init__() + if backbone == 'resnet50': + encoder = 'resnet50_stride32' + elif backbone == 'resnext101': + encoder = 'resnext101_stride32x8d' + self.depth_model = DepthModel(encoder) + + def inference(self, rgb): + with torch.no_grad(): + input = rgb.to(self.depth_model.device) + depth = self.depth_model(input) + #pred_depth_out = depth - depth.min() + 0.01 + return depth #pred_depth_out + + +class DepthModel(nn.Module): + def __init__(self, encoder): + super(DepthModel, self).__init__() + backbone = network.__name__.split('.')[-1] + '.' + encoder + self.encoder_modules = get_func(backbone)() + self.decoder_modules = network.Decoder() + + def forward(self, x): + lateral_out = self.encoder_modules(x) + out_logit = self.decoder_modules(lateral_out) + return out_logit \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/net_tools.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/net_tools.py new file mode 100644 index 00000000..745ba5a0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/net_tools.py @@ -0,0 +1,54 @@ +import importlib +import torch +import os +from collections import OrderedDict + + +def get_func(func_name): + """Helper to return a function object by name. func_name must identify a + function in this module or the path to a function relative to the base + 'modeling' module. + """ + if func_name == '': + return None + try: + parts = func_name.split('.') + # Refers to a function in this module + if len(parts) == 1: + return globals()[parts[0]] + # Otherwise, assume we're referencing a module under modeling + module_name = 'annotator.leres.leres.' + '.'.join(parts[:-1]) + module = importlib.import_module(module_name) + return getattr(module, parts[-1]) + except Exception: + print('Failed to f1ind function: %s', func_name) + raise + +def load_ckpt(args, depth_model, shift_model, focal_model): + """ + Load checkpoint. + """ + if os.path.isfile(args.load_ckpt): + print("loading checkpoint %s" % args.load_ckpt) + checkpoint = torch.load(args.load_ckpt) + if shift_model is not None: + shift_model.load_state_dict(strip_prefix_if_present(checkpoint['shift_model'], 'module.'), + strict=True) + if focal_model is not None: + focal_model.load_state_dict(strip_prefix_if_present(checkpoint['focal_model'], 'module.'), + strict=True) + depth_model.load_state_dict(strip_prefix_if_present(checkpoint['depth_model'], "module."), + strict=True) + del checkpoint + if torch.cuda.is_available(): + torch.cuda.empty_cache() + + +def strip_prefix_if_present(state_dict, prefix): + keys = sorted(state_dict.keys()) + if not all(key.startswith(prefix) for key in keys): + return state_dict + stripped_state_dict = OrderedDict() + for key, value in state_dict.items(): + stripped_state_dict[key.replace(prefix, "")] = value + return stripped_state_dict \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/network_auxi.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/network_auxi.py new file mode 100644 index 00000000..1bd87011 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/leres/network_auxi.py @@ -0,0 +1,417 @@ +import torch +import torch.nn as nn +import torch.nn.init as init + +from . import Resnet, Resnext_torch + + +def resnet50_stride32(): + return DepthNet(backbone='resnet', depth=50, upfactors=[2, 2, 2, 2]) + +def resnext101_stride32x8d(): + return DepthNet(backbone='resnext101_32x8d', depth=101, upfactors=[2, 2, 2, 2]) + + +class Decoder(nn.Module): + def __init__(self): + super(Decoder, self).__init__() + self.inchannels = [256, 512, 1024, 2048] + self.midchannels = [256, 256, 256, 512] + self.upfactors = [2,2,2,2] + self.outchannels = 1 + + self.conv = FTB(inchannels=self.inchannels[3], midchannels=self.midchannels[3]) + self.conv1 = nn.Conv2d(in_channels=self.midchannels[3], out_channels=self.midchannels[2], kernel_size=3, padding=1, stride=1, bias=True) + self.upsample = nn.Upsample(scale_factor=self.upfactors[3], mode='bilinear', align_corners=True) + + self.ffm2 = FFM(inchannels=self.inchannels[2], midchannels=self.midchannels[2], outchannels = self.midchannels[2], upfactor=self.upfactors[2]) + self.ffm1 = FFM(inchannels=self.inchannels[1], midchannels=self.midchannels[1], outchannels = self.midchannels[1], upfactor=self.upfactors[1]) + self.ffm0 = FFM(inchannels=self.inchannels[0], midchannels=self.midchannels[0], outchannels = self.midchannels[0], upfactor=self.upfactors[0]) + + self.outconv = AO(inchannels=self.midchannels[0], outchannels=self.outchannels, upfactor=2) + self._init_params() + + def _init_params(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + init.normal_(m.weight, std=0.01) + if m.bias is not None: + init.constant_(m.bias, 0) + elif isinstance(m, nn.ConvTranspose2d): + init.normal_(m.weight, std=0.01) + if m.bias is not None: + init.constant_(m.bias, 0) + elif isinstance(m, nn.BatchNorm2d): #NN.BatchNorm2d + init.constant_(m.weight, 1) + init.constant_(m.bias, 0) + elif isinstance(m, nn.Linear): + init.normal_(m.weight, std=0.01) + if m.bias is not None: + init.constant_(m.bias, 0) + + def forward(self, features): + x_32x = self.conv(features[3]) # 1/32 + x_32 = self.conv1(x_32x) + x_16 = self.upsample(x_32) # 1/16 + + x_8 = self.ffm2(features[2], x_16) # 1/8 + x_4 = self.ffm1(features[1], x_8) # 1/4 + x_2 = self.ffm0(features[0], x_4) # 1/2 + #----------------------------------------- + x = self.outconv(x_2) # original size + return x + +class DepthNet(nn.Module): + __factory = { + 18: Resnet.resnet18, + 34: Resnet.resnet34, + 50: Resnet.resnet50, + 101: Resnet.resnet101, + 152: Resnet.resnet152 + } + def __init__(self, + backbone='resnet', + depth=50, + upfactors=[2, 2, 2, 2]): + super(DepthNet, self).__init__() + self.backbone = backbone + self.depth = depth + self.pretrained = False + self.inchannels = [256, 512, 1024, 2048] + self.midchannels = [256, 256, 256, 512] + self.upfactors = upfactors + self.outchannels = 1 + + # Build model + if self.backbone == 'resnet': + if self.depth not in DepthNet.__factory: + raise KeyError("Unsupported depth:", self.depth) + self.encoder = DepthNet.__factory[depth](pretrained=self.pretrained) + elif self.backbone == 'resnext101_32x8d': + self.encoder = Resnext_torch.resnext101_32x8d(pretrained=self.pretrained) + else: + self.encoder = Resnext_torch.resnext101(pretrained=self.pretrained) + + def forward(self, x): + x = self.encoder(x) # 1/32, 1/16, 1/8, 1/4 + return x + + +class FTB(nn.Module): + def __init__(self, inchannels, midchannels=512): + super(FTB, self).__init__() + self.in1 = inchannels + self.mid = midchannels + self.conv1 = nn.Conv2d(in_channels=self.in1, out_channels=self.mid, kernel_size=3, padding=1, stride=1, + bias=True) + # NN.BatchNorm2d + self.conv_branch = nn.Sequential(nn.ReLU(inplace=True), \ + nn.Conv2d(in_channels=self.mid, out_channels=self.mid, kernel_size=3, + padding=1, stride=1, bias=True), \ + nn.BatchNorm2d(num_features=self.mid), \ + nn.ReLU(inplace=True), \ + nn.Conv2d(in_channels=self.mid, out_channels=self.mid, kernel_size=3, + padding=1, stride=1, bias=True)) + self.relu = nn.ReLU(inplace=True) + + self.init_params() + + def forward(self, x): + x = self.conv1(x) + x = x + self.conv_branch(x) + x = self.relu(x) + + return x + + def init_params(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + init.normal_(m.weight, std=0.01) + if m.bias is not None: + init.constant_(m.bias, 0) + elif isinstance(m, nn.ConvTranspose2d): + # init.kaiming_normal_(m.weight, mode='fan_out') + init.normal_(m.weight, std=0.01) + # init.xavier_normal_(m.weight) + if m.bias is not None: + init.constant_(m.bias, 0) + elif isinstance(m, nn.BatchNorm2d): # NN.BatchNorm2d + init.constant_(m.weight, 1) + init.constant_(m.bias, 0) + elif isinstance(m, nn.Linear): + init.normal_(m.weight, std=0.01) + if m.bias is not None: + init.constant_(m.bias, 0) + + +class ATA(nn.Module): + def __init__(self, inchannels, reduction=8): + super(ATA, self).__init__() + self.inchannels = inchannels + self.avg_pool = nn.AdaptiveAvgPool2d(1) + self.fc = nn.Sequential(nn.Linear(self.inchannels * 2, self.inchannels // reduction), + nn.ReLU(inplace=True), + nn.Linear(self.inchannels // reduction, self.inchannels), + nn.Sigmoid()) + self.init_params() + + def forward(self, low_x, high_x): + n, c, _, _ = low_x.size() + x = torch.cat([low_x, high_x], 1) + x = self.avg_pool(x) + x = x.view(n, -1) + x = self.fc(x).view(n, c, 1, 1) + x = low_x * x + high_x + + return x + + def init_params(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + # init.kaiming_normal_(m.weight, mode='fan_out') + # init.normal(m.weight, std=0.01) + init.xavier_normal_(m.weight) + if m.bias is not None: + init.constant_(m.bias, 0) + elif isinstance(m, nn.ConvTranspose2d): + # init.kaiming_normal_(m.weight, mode='fan_out') + # init.normal_(m.weight, std=0.01) + init.xavier_normal_(m.weight) + if m.bias is not None: + init.constant_(m.bias, 0) + elif isinstance(m, nn.BatchNorm2d): # NN.BatchNorm2d + init.constant_(m.weight, 1) + init.constant_(m.bias, 0) + elif isinstance(m, nn.Linear): + init.normal_(m.weight, std=0.01) + if m.bias is not None: + init.constant_(m.bias, 0) + + +class FFM(nn.Module): + def __init__(self, inchannels, midchannels, outchannels, upfactor=2): + super(FFM, self).__init__() + self.inchannels = inchannels + self.midchannels = midchannels + self.outchannels = outchannels + self.upfactor = upfactor + + self.ftb1 = FTB(inchannels=self.inchannels, midchannels=self.midchannels) + # self.ata = ATA(inchannels = self.midchannels) + self.ftb2 = FTB(inchannels=self.midchannels, midchannels=self.outchannels) + + self.upsample = nn.Upsample(scale_factor=self.upfactor, mode='bilinear', align_corners=True) + + self.init_params() + + def forward(self, low_x, high_x): + x = self.ftb1(low_x) + x = x + high_x + x = self.ftb2(x) + x = self.upsample(x) + + return x + + def init_params(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + # init.kaiming_normal_(m.weight, mode='fan_out') + init.normal_(m.weight, std=0.01) + # init.xavier_normal_(m.weight) + if m.bias is not None: + init.constant_(m.bias, 0) + elif isinstance(m, nn.ConvTranspose2d): + # init.kaiming_normal_(m.weight, mode='fan_out') + init.normal_(m.weight, std=0.01) + # init.xavier_normal_(m.weight) + if m.bias is not None: + init.constant_(m.bias, 0) + elif isinstance(m, nn.BatchNorm2d): # NN.Batchnorm2d + init.constant_(m.weight, 1) + init.constant_(m.bias, 0) + elif isinstance(m, nn.Linear): + init.normal_(m.weight, std=0.01) + if m.bias is not None: + init.constant_(m.bias, 0) + + +class AO(nn.Module): + # Adaptive output module + def __init__(self, inchannels, outchannels, upfactor=2): + super(AO, self).__init__() + self.inchannels = inchannels + self.outchannels = outchannels + self.upfactor = upfactor + + self.adapt_conv = nn.Sequential( + nn.Conv2d(in_channels=self.inchannels, out_channels=self.inchannels // 2, kernel_size=3, padding=1, + stride=1, bias=True), \ + nn.BatchNorm2d(num_features=self.inchannels // 2), \ + nn.ReLU(inplace=True), \ + nn.Conv2d(in_channels=self.inchannels // 2, out_channels=self.outchannels, kernel_size=3, padding=1, + stride=1, bias=True), \ + nn.Upsample(scale_factor=self.upfactor, mode='bilinear', align_corners=True)) + + self.init_params() + + def forward(self, x): + x = self.adapt_conv(x) + return x + + def init_params(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + # init.kaiming_normal_(m.weight, mode='fan_out') + init.normal_(m.weight, std=0.01) + # init.xavier_normal_(m.weight) + if m.bias is not None: + init.constant_(m.bias, 0) + elif isinstance(m, nn.ConvTranspose2d): + # init.kaiming_normal_(m.weight, mode='fan_out') + init.normal_(m.weight, std=0.01) + # init.xavier_normal_(m.weight) + if m.bias is not None: + init.constant_(m.bias, 0) + elif isinstance(m, nn.BatchNorm2d): # NN.Batchnorm2d + init.constant_(m.weight, 1) + init.constant_(m.bias, 0) + elif isinstance(m, nn.Linear): + init.normal_(m.weight, std=0.01) + if m.bias is not None: + init.constant_(m.bias, 0) + + + +# ============================================================================================================== + + +class ResidualConv(nn.Module): + def __init__(self, inchannels): + super(ResidualConv, self).__init__() + # NN.BatchNorm2d + self.conv = nn.Sequential( + # nn.BatchNorm2d(num_features=inchannels), + nn.ReLU(inplace=False), + # nn.Conv2d(in_channels=inchannels, out_channels=inchannels, kernel_size=3, padding=1, stride=1, groups=inchannels,bias=True), + # nn.Conv2d(in_channels=inchannels, out_channels=inchannels, kernel_size=1, padding=0, stride=1, groups=1,bias=True) + nn.Conv2d(in_channels=inchannels, out_channels=inchannels / 2, kernel_size=3, padding=1, stride=1, + bias=False), + nn.BatchNorm2d(num_features=inchannels / 2), + nn.ReLU(inplace=False), + nn.Conv2d(in_channels=inchannels / 2, out_channels=inchannels, kernel_size=3, padding=1, stride=1, + bias=False) + ) + self.init_params() + + def forward(self, x): + x = self.conv(x) + x + return x + + def init_params(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + # init.kaiming_normal_(m.weight, mode='fan_out') + init.normal_(m.weight, std=0.01) + # init.xavier_normal_(m.weight) + if m.bias is not None: + init.constant_(m.bias, 0) + elif isinstance(m, nn.ConvTranspose2d): + # init.kaiming_normal_(m.weight, mode='fan_out') + init.normal_(m.weight, std=0.01) + # init.xavier_normal_(m.weight) + if m.bias is not None: + init.constant_(m.bias, 0) + elif isinstance(m, nn.BatchNorm2d): # NN.BatchNorm2d + init.constant_(m.weight, 1) + init.constant_(m.bias, 0) + elif isinstance(m, nn.Linear): + init.normal_(m.weight, std=0.01) + if m.bias is not None: + init.constant_(m.bias, 0) + + +class FeatureFusion(nn.Module): + def __init__(self, inchannels, outchannels): + super(FeatureFusion, self).__init__() + self.conv = ResidualConv(inchannels=inchannels) + # NN.BatchNorm2d + self.up = nn.Sequential(ResidualConv(inchannels=inchannels), + nn.ConvTranspose2d(in_channels=inchannels, out_channels=outchannels, kernel_size=3, + stride=2, padding=1, output_padding=1), + nn.BatchNorm2d(num_features=outchannels), + nn.ReLU(inplace=True)) + + def forward(self, lowfeat, highfeat): + return self.up(highfeat + self.conv(lowfeat)) + + def init_params(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + # init.kaiming_normal_(m.weight, mode='fan_out') + init.normal_(m.weight, std=0.01) + # init.xavier_normal_(m.weight) + if m.bias is not None: + init.constant_(m.bias, 0) + elif isinstance(m, nn.ConvTranspose2d): + # init.kaiming_normal_(m.weight, mode='fan_out') + init.normal_(m.weight, std=0.01) + # init.xavier_normal_(m.weight) + if m.bias is not None: + init.constant_(m.bias, 0) + elif isinstance(m, nn.BatchNorm2d): # NN.BatchNorm2d + init.constant_(m.weight, 1) + init.constant_(m.bias, 0) + elif isinstance(m, nn.Linear): + init.normal_(m.weight, std=0.01) + if m.bias is not None: + init.constant_(m.bias, 0) + + +class SenceUnderstand(nn.Module): + def __init__(self, channels): + super(SenceUnderstand, self).__init__() + self.channels = channels + self.conv1 = nn.Sequential(nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, padding=1), + nn.ReLU(inplace=True)) + self.pool = nn.AdaptiveAvgPool2d(8) + self.fc = nn.Sequential(nn.Linear(512 * 8 * 8, self.channels), + nn.ReLU(inplace=True)) + self.conv2 = nn.Sequential( + nn.Conv2d(in_channels=self.channels, out_channels=self.channels, kernel_size=1, padding=0), + nn.ReLU(inplace=True)) + self.initial_params() + + def forward(self, x): + n, c, h, w = x.size() + x = self.conv1(x) + x = self.pool(x) + x = x.view(n, -1) + x = self.fc(x) + x = x.view(n, self.channels, 1, 1) + x = self.conv2(x) + x = x.repeat(1, 1, h, w) + return x + + def initial_params(self, dev=0.01): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + # print torch.sum(m.weight) + m.weight.data.normal_(0, dev) + if m.bias is not None: + m.bias.data.fill_(0) + elif isinstance(m, nn.ConvTranspose2d): + # print torch.sum(m.weight) + m.weight.data.normal_(0, dev) + if m.bias is not None: + m.bias.data.fill_(0) + elif isinstance(m, nn.Linear): + m.weight.data.normal_(0, dev) + + +if __name__ == '__main__': + net = DepthNet(depth=50, pretrained=True) + print(net) + inputs = torch.ones(4,3,128,128) + out = net(inputs) + print(out.size()) + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/LICENSE b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/LICENSE new file mode 100644 index 00000000..38b1a24f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/LICENSE @@ -0,0 +1,19 @@ +https://github.com/compphoto/BoostingMonocularDepth + +Copyright 2021, Seyed Mahdi Hosseini Miangoleh, Sebastian Dille, Computational Photography Laboratory. All rights reserved. + +This software is for academic use only. A redistribution of this +software, with or without modifications, has to be for academic +use only, while giving the appropriate credit to the original +authors of the software. The methods implemented as a part of +this software may be covered under patents or patent applications. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/__init__.py new file mode 100644 index 00000000..f96e5c7f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/__init__.py @@ -0,0 +1,67 @@ +"""This package contains modules related to objective functions, optimizations, and network architectures. + +To add a custom model class called 'dummy', you need to add a file called 'dummy_model.py' and define a subclass DummyModel inherited from BaseModel. +You need to implement the following five functions: + -- <__init__>: initialize the class; first call BaseModel.__init__(self, opt). + -- : unpack data from dataset and apply preprocessing. + -- : produce intermediate results. + -- : calculate loss, gradients, and update network weights. + -- : (optionally) add model-specific options and set default options. + +In the function <__init__>, you need to define four lists: + -- self.loss_names (str list): specify the training losses that you want to plot and save. + -- self.model_names (str list): define networks used in our training. + -- self.visual_names (str list): specify the images that you want to display and save. + -- self.optimizers (optimizer list): define and initialize optimizers. You can define one optimizer for each network. If two networks are updated at the same time, you can use itertools.chain to group them. See cycle_gan_model.py for an usage. + +Now you can use the model class by specifying flag '--model dummy'. +See our template model class 'template_model.py' for more details. +""" + +import importlib +from .base_model import BaseModel + + +def find_model_using_name(model_name): + """Import the module "models/[model_name]_model.py". + + In the file, the class called DatasetNameModel() will + be instantiated. It has to be a subclass of BaseModel, + and it is case-insensitive. + """ + model_filename = "annotator.leres.pix2pix.models." + model_name + "_model" + modellib = importlib.import_module(model_filename) + model = None + target_model_name = model_name.replace('_', '') + 'model' + for name, cls in modellib.__dict__.items(): + if name.lower() == target_model_name.lower() \ + and issubclass(cls, BaseModel): + model = cls + + if model is None: + print("In %s.py, there should be a subclass of BaseModel with class name that matches %s in lowercase." % (model_filename, target_model_name)) + exit(0) + + return model + + +def get_option_setter(model_name): + """Return the static method of the model class.""" + model_class = find_model_using_name(model_name) + return model_class.modify_commandline_options + + +def create_model(opt): + """Create a model given the option. + + This function warps the class CustomDatasetDataLoader. + This is the main interface between this package and 'train.py'/'test.py' + + Example: + >>> from models import create_model + >>> model = create_model(opt) + """ + model = find_model_using_name(opt.model) + instance = model(opt) + print("model [%s] was created" % type(instance).__name__) + return instance diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/base_model.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/base_model.py new file mode 100644 index 00000000..a90c5f83 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/base_model.py @@ -0,0 +1,241 @@ +import os +import torch, gc +from modules import devices +from collections import OrderedDict +from abc import ABC, abstractmethod +from . import networks + + +class BaseModel(ABC): + """This class is an abstract base class (ABC) for models. + To create a subclass, you need to implement the following five functions: + -- <__init__>: initialize the class; first call BaseModel.__init__(self, opt). + -- : unpack data from dataset and apply preprocessing. + -- : produce intermediate results. + -- : calculate losses, gradients, and update network weights. + -- : (optionally) add model-specific options and set default options. + """ + + def __init__(self, opt): + """Initialize the BaseModel class. + + Parameters: + opt (Option class)-- stores all the experiment flags; needs to be a subclass of BaseOptions + + When creating your custom class, you need to implement your own initialization. + In this function, you should first call + Then, you need to define four lists: + -- self.loss_names (str list): specify the training losses that you want to plot and save. + -- self.model_names (str list): define networks used in our training. + -- self.visual_names (str list): specify the images that you want to display and save. + -- self.optimizers (optimizer list): define and initialize optimizers. You can define one optimizer for each network. If two networks are updated at the same time, you can use itertools.chain to group them. See cycle_gan_model.py for an example. + """ + self.opt = opt + self.gpu_ids = opt.gpu_ids + self.isTrain = opt.isTrain + self.device = torch.device('cuda:{}'.format(self.gpu_ids[0])) if self.gpu_ids else torch.device('cpu') # get device name: CPU or GPU + self.save_dir = os.path.join(opt.checkpoints_dir, opt.name) # save all the checkpoints to save_dir + if opt.preprocess != 'scale_width': # with [scale_width], input images might have different sizes, which hurts the performance of cudnn.benchmark. + torch.backends.cudnn.benchmark = True + self.loss_names = [] + self.model_names = [] + self.visual_names = [] + self.optimizers = [] + self.image_paths = [] + self.metric = 0 # used for learning rate policy 'plateau' + + @staticmethod + def modify_commandline_options(parser, is_train): + """Add new model-specific options, and rewrite default values for existing options. + + Parameters: + parser -- original option parser + is_train (bool) -- whether training phase or test phase. You can use this flag to add training-specific or test-specific options. + + Returns: + the modified parser. + """ + return parser + + @abstractmethod + def set_input(self, input): + """Unpack input data from the dataloader and perform necessary pre-processing steps. + + Parameters: + input (dict): includes the data itself and its metadata information. + """ + pass + + @abstractmethod + def forward(self): + """Run forward pass; called by both functions and .""" + pass + + @abstractmethod + def optimize_parameters(self): + """Calculate losses, gradients, and update network weights; called in every training iteration""" + pass + + def setup(self, opt): + """Load and print networks; create schedulers + + Parameters: + opt (Option class) -- stores all the experiment flags; needs to be a subclass of BaseOptions + """ + if self.isTrain: + self.schedulers = [networks.get_scheduler(optimizer, opt) for optimizer in self.optimizers] + if not self.isTrain or opt.continue_train: + load_suffix = 'iter_%d' % opt.load_iter if opt.load_iter > 0 else opt.epoch + self.load_networks(load_suffix) + self.print_networks(opt.verbose) + + def eval(self): + """Make models eval mode during test time""" + for name in self.model_names: + if isinstance(name, str): + net = getattr(self, 'net' + name) + net.eval() + + def test(self): + """Forward function used in test time. + + This function wraps function in no_grad() so we don't save intermediate steps for backprop + It also calls to produce additional visualization results + """ + with torch.no_grad(): + self.forward() + self.compute_visuals() + + def compute_visuals(self): + """Calculate additional output images for visdom and HTML visualization""" + pass + + def get_image_paths(self): + """ Return image paths that are used to load current data""" + return self.image_paths + + def update_learning_rate(self): + """Update learning rates for all the networks; called at the end of every epoch""" + old_lr = self.optimizers[0].param_groups[0]['lr'] + for scheduler in self.schedulers: + if self.opt.lr_policy == 'plateau': + scheduler.step(self.metric) + else: + scheduler.step() + + lr = self.optimizers[0].param_groups[0]['lr'] + print('learning rate %.7f -> %.7f' % (old_lr, lr)) + + def get_current_visuals(self): + """Return visualization images. train.py will display these images with visdom, and save the images to a HTML""" + visual_ret = OrderedDict() + for name in self.visual_names: + if isinstance(name, str): + visual_ret[name] = getattr(self, name) + return visual_ret + + def get_current_losses(self): + """Return traning losses / errors. train.py will print out these errors on console, and save them to a file""" + errors_ret = OrderedDict() + for name in self.loss_names: + if isinstance(name, str): + errors_ret[name] = float(getattr(self, 'loss_' + name)) # float(...) works for both scalar tensor and float number + return errors_ret + + def save_networks(self, epoch): + """Save all the networks to the disk. + + Parameters: + epoch (int) -- current epoch; used in the file name '%s_net_%s.pth' % (epoch, name) + """ + for name in self.model_names: + if isinstance(name, str): + save_filename = '%s_net_%s.pth' % (epoch, name) + save_path = os.path.join(self.save_dir, save_filename) + net = getattr(self, 'net' + name) + + if len(self.gpu_ids) > 0 and torch.cuda.is_available(): + torch.save(net.module.cpu().state_dict(), save_path) + net.cuda(self.gpu_ids[0]) + else: + torch.save(net.cpu().state_dict(), save_path) + + def unload_network(self, name): + """Unload network and gc. + """ + if isinstance(name, str): + net = getattr(self, 'net' + name) + del net + gc.collect() + devices.torch_gc() + return None + + def __patch_instance_norm_state_dict(self, state_dict, module, keys, i=0): + """Fix InstanceNorm checkpoints incompatibility (prior to 0.4)""" + key = keys[i] + if i + 1 == len(keys): # at the end, pointing to a parameter/buffer + if module.__class__.__name__.startswith('InstanceNorm') and \ + (key == 'running_mean' or key == 'running_var'): + if getattr(module, key) is None: + state_dict.pop('.'.join(keys)) + if module.__class__.__name__.startswith('InstanceNorm') and \ + (key == 'num_batches_tracked'): + state_dict.pop('.'.join(keys)) + else: + self.__patch_instance_norm_state_dict(state_dict, getattr(module, key), keys, i + 1) + + def load_networks(self, epoch): + """Load all the networks from the disk. + + Parameters: + epoch (int) -- current epoch; used in the file name '%s_net_%s.pth' % (epoch, name) + """ + for name in self.model_names: + if isinstance(name, str): + load_filename = '%s_net_%s.pth' % (epoch, name) + load_path = os.path.join(self.save_dir, load_filename) + net = getattr(self, 'net' + name) + if isinstance(net, torch.nn.DataParallel): + net = net.module + # print('Loading depth boost model from %s' % load_path) + # if you are using PyTorch newer than 0.4 (e.g., built from + # GitHub source), you can remove str() on self.device + state_dict = torch.load(load_path, map_location=str(self.device)) + if hasattr(state_dict, '_metadata'): + del state_dict._metadata + + # patch InstanceNorm checkpoints prior to 0.4 + for key in list(state_dict.keys()): # need to copy keys here because we mutate in loop + self.__patch_instance_norm_state_dict(state_dict, net, key.split('.')) + net.load_state_dict(state_dict) + + def print_networks(self, verbose): + """Print the total number of parameters in the network and (if verbose) network architecture + + Parameters: + verbose (bool) -- if verbose: print the network architecture + """ + print('---------- Networks initialized -------------') + for name in self.model_names: + if isinstance(name, str): + net = getattr(self, 'net' + name) + num_params = 0 + for param in net.parameters(): + num_params += param.numel() + if verbose: + print(net) + print('[Network %s] Total number of parameters : %.3f M' % (name, num_params / 1e6)) + print('-----------------------------------------------') + + def set_requires_grad(self, nets, requires_grad=False): + """Set requies_grad=Fasle for all the networks to avoid unnecessary computations + Parameters: + nets (network list) -- a list of networks + requires_grad (bool) -- whether the networks require gradients or not + """ + if not isinstance(nets, list): + nets = [nets] + for net in nets: + if net is not None: + for param in net.parameters(): + param.requires_grad = requires_grad diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/base_model_hg.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/base_model_hg.py new file mode 100644 index 00000000..1709accd --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/base_model_hg.py @@ -0,0 +1,58 @@ +import os +import torch + +class BaseModelHG(): + def name(self): + return 'BaseModel' + + def initialize(self, opt): + self.opt = opt + self.gpu_ids = opt.gpu_ids + self.isTrain = opt.isTrain + self.Tensor = torch.cuda.FloatTensor if self.gpu_ids else torch.Tensor + self.save_dir = os.path.join(opt.checkpoints_dir, opt.name) + + def set_input(self, input): + self.input = input + + def forward(self): + pass + + # used in test time, no backprop + def test(self): + pass + + def get_image_paths(self): + pass + + def optimize_parameters(self): + pass + + def get_current_visuals(self): + return self.input + + def get_current_errors(self): + return {} + + def save(self, label): + pass + + # helper saving function that can be used by subclasses + def save_network(self, network, network_label, epoch_label, gpu_ids): + save_filename = '_%s_net_%s.pth' % (epoch_label, network_label) + save_path = os.path.join(self.save_dir, save_filename) + torch.save(network.cpu().state_dict(), save_path) + if len(gpu_ids) and torch.cuda.is_available(): + network.cuda(device_id=gpu_ids[0]) + + # helper loading function that can be used by subclasses + def load_network(self, network, network_label, epoch_label): + save_filename = '%s_net_%s.pth' % (epoch_label, network_label) + save_path = os.path.join(self.save_dir, save_filename) + print(save_path) + model = torch.load(save_path) + return model + # network.load_state_dict(torch.load(save_path)) + + def update_learning_rate(): + pass diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/networks.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/networks.py new file mode 100644 index 00000000..0cf912b2 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/networks.py @@ -0,0 +1,623 @@ +import torch +import torch.nn as nn +from torch.nn import init +import functools +from torch.optim import lr_scheduler + + +############################################################################### +# Helper Functions +############################################################################### + + +class Identity(nn.Module): + def forward(self, x): + return x + + +def get_norm_layer(norm_type='instance'): + """Return a normalization layer + + Parameters: + norm_type (str) -- the name of the normalization layer: batch | instance | none + + For BatchNorm, we use learnable affine parameters and track running statistics (mean/stddev). + For InstanceNorm, we do not use learnable affine parameters. We do not track running statistics. + """ + if norm_type == 'batch': + norm_layer = functools.partial(nn.BatchNorm2d, affine=True, track_running_stats=True) + elif norm_type == 'instance': + norm_layer = functools.partial(nn.InstanceNorm2d, affine=False, track_running_stats=False) + elif norm_type == 'none': + def norm_layer(x): return Identity() + else: + raise NotImplementedError('normalization layer [%s] is not found' % norm_type) + return norm_layer + + +def get_scheduler(optimizer, opt): + """Return a learning rate scheduler + + Parameters: + optimizer -- the optimizer of the network + opt (option class) -- stores all the experiment flags; needs to be a subclass of BaseOptions.  + opt.lr_policy is the name of learning rate policy: linear | step | plateau | cosine + + For 'linear', we keep the same learning rate for the first epochs + and linearly decay the rate to zero over the next epochs. + For other schedulers (step, plateau, and cosine), we use the default PyTorch schedulers. + See https://pytorch.org/docs/stable/optim.html for more details. + """ + if opt.lr_policy == 'linear': + def lambda_rule(epoch): + lr_l = 1.0 - max(0, epoch + opt.epoch_count - opt.n_epochs) / float(opt.n_epochs_decay + 1) + return lr_l + scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda=lambda_rule) + elif opt.lr_policy == 'step': + scheduler = lr_scheduler.StepLR(optimizer, step_size=opt.lr_decay_iters, gamma=0.1) + elif opt.lr_policy == 'plateau': + scheduler = lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.2, threshold=0.01, patience=5) + elif opt.lr_policy == 'cosine': + scheduler = lr_scheduler.CosineAnnealingLR(optimizer, T_max=opt.n_epochs, eta_min=0) + else: + return NotImplementedError('learning rate policy [%s] is not implemented', opt.lr_policy) + return scheduler + + +def init_weights(net, init_type='normal', init_gain=0.02): + """Initialize network weights. + + Parameters: + net (network) -- network to be initialized + init_type (str) -- the name of an initialization method: normal | xavier | kaiming | orthogonal + init_gain (float) -- scaling factor for normal, xavier and orthogonal. + + We use 'normal' in the original pix2pix and CycleGAN paper. But xavier and kaiming might + work better for some applications. Feel free to try yourself. + """ + def init_func(m): # define the initialization function + classname = m.__class__.__name__ + if hasattr(m, 'weight') and (classname.find('Conv') != -1 or classname.find('Linear') != -1): + if init_type == 'normal': + init.normal_(m.weight.data, 0.0, init_gain) + elif init_type == 'xavier': + init.xavier_normal_(m.weight.data, gain=init_gain) + elif init_type == 'kaiming': + init.kaiming_normal_(m.weight.data, a=0, mode='fan_in') + elif init_type == 'orthogonal': + init.orthogonal_(m.weight.data, gain=init_gain) + else: + raise NotImplementedError('initialization method [%s] is not implemented' % init_type) + if hasattr(m, 'bias') and m.bias is not None: + init.constant_(m.bias.data, 0.0) + elif classname.find('BatchNorm2d') != -1: # BatchNorm Layer's weight is not a matrix; only normal distribution applies. + init.normal_(m.weight.data, 1.0, init_gain) + init.constant_(m.bias.data, 0.0) + + # print('initialize network with %s' % init_type) + net.apply(init_func) # apply the initialization function + + +def init_net(net, init_type='normal', init_gain=0.02, gpu_ids=[]): + """Initialize a network: 1. register CPU/GPU device (with multi-GPU support); 2. initialize the network weights + Parameters: + net (network) -- the network to be initialized + init_type (str) -- the name of an initialization method: normal | xavier | kaiming | orthogonal + gain (float) -- scaling factor for normal, xavier and orthogonal. + gpu_ids (int list) -- which GPUs the network runs on: e.g., 0,1,2 + + Return an initialized network. + """ + if len(gpu_ids) > 0: + assert(torch.cuda.is_available()) + net.to(gpu_ids[0]) + net = torch.nn.DataParallel(net, gpu_ids) # multi-GPUs + init_weights(net, init_type, init_gain=init_gain) + return net + + +def define_G(input_nc, output_nc, ngf, netG, norm='batch', use_dropout=False, init_type='normal', init_gain=0.02, gpu_ids=[]): + """Create a generator + + Parameters: + input_nc (int) -- the number of channels in input images + output_nc (int) -- the number of channels in output images + ngf (int) -- the number of filters in the last conv layer + netG (str) -- the architecture's name: resnet_9blocks | resnet_6blocks | unet_256 | unet_128 + norm (str) -- the name of normalization layers used in the network: batch | instance | none + use_dropout (bool) -- if use dropout layers. + init_type (str) -- the name of our initialization method. + init_gain (float) -- scaling factor for normal, xavier and orthogonal. + gpu_ids (int list) -- which GPUs the network runs on: e.g., 0,1,2 + + Returns a generator + + Our current implementation provides two types of generators: + U-Net: [unet_128] (for 128x128 input images) and [unet_256] (for 256x256 input images) + The original U-Net paper: https://arxiv.org/abs/1505.04597 + + Resnet-based generator: [resnet_6blocks] (with 6 Resnet blocks) and [resnet_9blocks] (with 9 Resnet blocks) + Resnet-based generator consists of several Resnet blocks between a few downsampling/upsampling operations. + We adapt Torch code from Justin Johnson's neural style transfer project (https://github.com/jcjohnson/fast-neural-style). + + + The generator has been initialized by . It uses RELU for non-linearity. + """ + net = None + norm_layer = get_norm_layer(norm_type=norm) + + if netG == 'resnet_9blocks': + net = ResnetGenerator(input_nc, output_nc, ngf, norm_layer=norm_layer, use_dropout=use_dropout, n_blocks=9) + elif netG == 'resnet_6blocks': + net = ResnetGenerator(input_nc, output_nc, ngf, norm_layer=norm_layer, use_dropout=use_dropout, n_blocks=6) + elif netG == 'resnet_12blocks': + net = ResnetGenerator(input_nc, output_nc, ngf, norm_layer=norm_layer, use_dropout=use_dropout, n_blocks=12) + elif netG == 'unet_128': + net = UnetGenerator(input_nc, output_nc, 7, ngf, norm_layer=norm_layer, use_dropout=use_dropout) + elif netG == 'unet_256': + net = UnetGenerator(input_nc, output_nc, 8, ngf, norm_layer=norm_layer, use_dropout=use_dropout) + elif netG == 'unet_672': + net = UnetGenerator(input_nc, output_nc, 5, ngf, norm_layer=norm_layer, use_dropout=use_dropout) + elif netG == 'unet_960': + net = UnetGenerator(input_nc, output_nc, 6, ngf, norm_layer=norm_layer, use_dropout=use_dropout) + elif netG == 'unet_1024': + net = UnetGenerator(input_nc, output_nc, 10, ngf, norm_layer=norm_layer, use_dropout=use_dropout) + else: + raise NotImplementedError('Generator model name [%s] is not recognized' % netG) + return init_net(net, init_type, init_gain, gpu_ids) + + +def define_D(input_nc, ndf, netD, n_layers_D=3, norm='batch', init_type='normal', init_gain=0.02, gpu_ids=[]): + """Create a discriminator + + Parameters: + input_nc (int) -- the number of channels in input images + ndf (int) -- the number of filters in the first conv layer + netD (str) -- the architecture's name: basic | n_layers | pixel + n_layers_D (int) -- the number of conv layers in the discriminator; effective when netD=='n_layers' + norm (str) -- the type of normalization layers used in the network. + init_type (str) -- the name of the initialization method. + init_gain (float) -- scaling factor for normal, xavier and orthogonal. + gpu_ids (int list) -- which GPUs the network runs on: e.g., 0,1,2 + + Returns a discriminator + + Our current implementation provides three types of discriminators: + [basic]: 'PatchGAN' classifier described in the original pix2pix paper. + It can classify whether 70×70 overlapping patches are real or fake. + Such a patch-level discriminator architecture has fewer parameters + than a full-image discriminator and can work on arbitrarily-sized images + in a fully convolutional fashion. + + [n_layers]: With this mode, you can specify the number of conv layers in the discriminator + with the parameter (default=3 as used in [basic] (PatchGAN).) + + [pixel]: 1x1 PixelGAN discriminator can classify whether a pixel is real or not. + It encourages greater color diversity but has no effect on spatial statistics. + + The discriminator has been initialized by . It uses Leakly RELU for non-linearity. + """ + net = None + norm_layer = get_norm_layer(norm_type=norm) + + if netD == 'basic': # default PatchGAN classifier + net = NLayerDiscriminator(input_nc, ndf, n_layers=3, norm_layer=norm_layer) + elif netD == 'n_layers': # more options + net = NLayerDiscriminator(input_nc, ndf, n_layers_D, norm_layer=norm_layer) + elif netD == 'pixel': # classify if each pixel is real or fake + net = PixelDiscriminator(input_nc, ndf, norm_layer=norm_layer) + else: + raise NotImplementedError('Discriminator model name [%s] is not recognized' % netD) + return init_net(net, init_type, init_gain, gpu_ids) + + +############################################################################## +# Classes +############################################################################## +class GANLoss(nn.Module): + """Define different GAN objectives. + + The GANLoss class abstracts away the need to create the target label tensor + that has the same size as the input. + """ + + def __init__(self, gan_mode, target_real_label=1.0, target_fake_label=0.0): + """ Initialize the GANLoss class. + + Parameters: + gan_mode (str) - - the type of GAN objective. It currently supports vanilla, lsgan, and wgangp. + target_real_label (bool) - - label for a real image + target_fake_label (bool) - - label of a fake image + + Note: Do not use sigmoid as the last layer of Discriminator. + LSGAN needs no sigmoid. vanilla GANs will handle it with BCEWithLogitsLoss. + """ + super(GANLoss, self).__init__() + self.register_buffer('real_label', torch.tensor(target_real_label)) + self.register_buffer('fake_label', torch.tensor(target_fake_label)) + self.gan_mode = gan_mode + if gan_mode == 'lsgan': + self.loss = nn.MSELoss() + elif gan_mode == 'vanilla': + self.loss = nn.BCEWithLogitsLoss() + elif gan_mode in ['wgangp']: + self.loss = None + else: + raise NotImplementedError('gan mode %s not implemented' % gan_mode) + + def get_target_tensor(self, prediction, target_is_real): + """Create label tensors with the same size as the input. + + Parameters: + prediction (tensor) - - tpyically the prediction from a discriminator + target_is_real (bool) - - if the ground truth label is for real images or fake images + + Returns: + A label tensor filled with ground truth label, and with the size of the input + """ + + if target_is_real: + target_tensor = self.real_label + else: + target_tensor = self.fake_label + return target_tensor.expand_as(prediction) + + def __call__(self, prediction, target_is_real): + """Calculate loss given Discriminator's output and grount truth labels. + + Parameters: + prediction (tensor) - - tpyically the prediction output from a discriminator + target_is_real (bool) - - if the ground truth label is for real images or fake images + + Returns: + the calculated loss. + """ + if self.gan_mode in ['lsgan', 'vanilla']: + target_tensor = self.get_target_tensor(prediction, target_is_real) + loss = self.loss(prediction, target_tensor) + elif self.gan_mode == 'wgangp': + if target_is_real: + loss = -prediction.mean() + else: + loss = prediction.mean() + return loss + + +def cal_gradient_penalty(netD, real_data, fake_data, device, type='mixed', constant=1.0, lambda_gp=10.0): + """Calculate the gradient penalty loss, used in WGAN-GP paper https://arxiv.org/abs/1704.00028 + + Arguments: + netD (network) -- discriminator network + real_data (tensor array) -- real images + fake_data (tensor array) -- generated images from the generator + device (str) -- GPU / CPU: from torch.device('cuda:{}'.format(self.gpu_ids[0])) if self.gpu_ids else torch.device('cpu') + type (str) -- if we mix real and fake data or not [real | fake | mixed]. + constant (float) -- the constant used in formula ( ||gradient||_2 - constant)^2 + lambda_gp (float) -- weight for this loss + + Returns the gradient penalty loss + """ + if lambda_gp > 0.0: + if type == 'real': # either use real images, fake images, or a linear interpolation of two. + interpolatesv = real_data + elif type == 'fake': + interpolatesv = fake_data + elif type == 'mixed': + alpha = torch.rand(real_data.shape[0], 1, device=device) + alpha = alpha.expand(real_data.shape[0], real_data.nelement() // real_data.shape[0]).contiguous().view(*real_data.shape) + interpolatesv = alpha * real_data + ((1 - alpha) * fake_data) + else: + raise NotImplementedError('{} not implemented'.format(type)) + interpolatesv.requires_grad_(True) + disc_interpolates = netD(interpolatesv) + gradients = torch.autograd.grad(outputs=disc_interpolates, inputs=interpolatesv, + grad_outputs=torch.ones(disc_interpolates.size()).to(device), + create_graph=True, retain_graph=True, only_inputs=True) + gradients = gradients[0].view(real_data.size(0), -1) # flat the data + gradient_penalty = (((gradients + 1e-16).norm(2, dim=1) - constant) ** 2).mean() * lambda_gp # added eps + return gradient_penalty, gradients + else: + return 0.0, None + + +class ResnetGenerator(nn.Module): + """Resnet-based generator that consists of Resnet blocks between a few downsampling/upsampling operations. + + We adapt Torch code and idea from Justin Johnson's neural style transfer project(https://github.com/jcjohnson/fast-neural-style) + """ + + def __init__(self, input_nc, output_nc, ngf=64, norm_layer=nn.BatchNorm2d, use_dropout=False, n_blocks=6, padding_type='reflect'): + """Construct a Resnet-based generator + + Parameters: + input_nc (int) -- the number of channels in input images + output_nc (int) -- the number of channels in output images + ngf (int) -- the number of filters in the last conv layer + norm_layer -- normalization layer + use_dropout (bool) -- if use dropout layers + n_blocks (int) -- the number of ResNet blocks + padding_type (str) -- the name of padding layer in conv layers: reflect | replicate | zero + """ + assert(n_blocks >= 0) + super(ResnetGenerator, self).__init__() + if type(norm_layer) == functools.partial: + use_bias = norm_layer.func == nn.InstanceNorm2d + else: + use_bias = norm_layer == nn.InstanceNorm2d + + model = [nn.ReflectionPad2d(3), + nn.Conv2d(input_nc, ngf, kernel_size=7, padding=0, bias=use_bias), + norm_layer(ngf), + nn.ReLU(True)] + + n_downsampling = 2 + for i in range(n_downsampling): # add downsampling layers + mult = 2 ** i + model += [nn.Conv2d(ngf * mult, ngf * mult * 2, kernel_size=3, stride=2, padding=1, bias=use_bias), + norm_layer(ngf * mult * 2), + nn.ReLU(True)] + + mult = 2 ** n_downsampling + for i in range(n_blocks): # add ResNet blocks + + model += [ResnetBlock(ngf * mult, padding_type=padding_type, norm_layer=norm_layer, use_dropout=use_dropout, use_bias=use_bias)] + + for i in range(n_downsampling): # add upsampling layers + mult = 2 ** (n_downsampling - i) + model += [nn.ConvTranspose2d(ngf * mult, int(ngf * mult / 2), + kernel_size=3, stride=2, + padding=1, output_padding=1, + bias=use_bias), + norm_layer(int(ngf * mult / 2)), + nn.ReLU(True)] + model += [nn.ReflectionPad2d(3)] + model += [nn.Conv2d(ngf, output_nc, kernel_size=7, padding=0)] + model += [nn.Tanh()] + + self.model = nn.Sequential(*model) + + def forward(self, input): + """Standard forward""" + return self.model(input) + + +class ResnetBlock(nn.Module): + """Define a Resnet block""" + + def __init__(self, dim, padding_type, norm_layer, use_dropout, use_bias): + """Initialize the Resnet block + + A resnet block is a conv block with skip connections + We construct a conv block with build_conv_block function, + and implement skip connections in function. + Original Resnet paper: https://arxiv.org/pdf/1512.03385.pdf + """ + super(ResnetBlock, self).__init__() + self.conv_block = self.build_conv_block(dim, padding_type, norm_layer, use_dropout, use_bias) + + def build_conv_block(self, dim, padding_type, norm_layer, use_dropout, use_bias): + """Construct a convolutional block. + + Parameters: + dim (int) -- the number of channels in the conv layer. + padding_type (str) -- the name of padding layer: reflect | replicate | zero + norm_layer -- normalization layer + use_dropout (bool) -- if use dropout layers. + use_bias (bool) -- if the conv layer uses bias or not + + Returns a conv block (with a conv layer, a normalization layer, and a non-linearity layer (ReLU)) + """ + conv_block = [] + p = 0 + if padding_type == 'reflect': + conv_block += [nn.ReflectionPad2d(1)] + elif padding_type == 'replicate': + conv_block += [nn.ReplicationPad2d(1)] + elif padding_type == 'zero': + p = 1 + else: + raise NotImplementedError('padding [%s] is not implemented' % padding_type) + + conv_block += [nn.Conv2d(dim, dim, kernel_size=3, padding=p, bias=use_bias), norm_layer(dim), nn.ReLU(True)] + if use_dropout: + conv_block += [nn.Dropout(0.5)] + + p = 0 + if padding_type == 'reflect': + conv_block += [nn.ReflectionPad2d(1)] + elif padding_type == 'replicate': + conv_block += [nn.ReplicationPad2d(1)] + elif padding_type == 'zero': + p = 1 + else: + raise NotImplementedError('padding [%s] is not implemented' % padding_type) + conv_block += [nn.Conv2d(dim, dim, kernel_size=3, padding=p, bias=use_bias), norm_layer(dim)] + + return nn.Sequential(*conv_block) + + def forward(self, x): + """Forward function (with skip connections)""" + out = x + self.conv_block(x) # add skip connections + return out + + +class UnetGenerator(nn.Module): + """Create a Unet-based generator""" + + def __init__(self, input_nc, output_nc, num_downs, ngf=64, norm_layer=nn.BatchNorm2d, use_dropout=False): + """Construct a Unet generator + Parameters: + input_nc (int) -- the number of channels in input images + output_nc (int) -- the number of channels in output images + num_downs (int) -- the number of downsamplings in UNet. For example, # if |num_downs| == 7, + image of size 128x128 will become of size 1x1 # at the bottleneck + ngf (int) -- the number of filters in the last conv layer + norm_layer -- normalization layer + + We construct the U-Net from the innermost layer to the outermost layer. + It is a recursive process. + """ + super(UnetGenerator, self).__init__() + # construct unet structure + unet_block = UnetSkipConnectionBlock(ngf * 8, ngf * 8, input_nc=None, submodule=None, norm_layer=norm_layer, innermost=True) # add the innermost layer + for i in range(num_downs - 5): # add intermediate layers with ngf * 8 filters + unet_block = UnetSkipConnectionBlock(ngf * 8, ngf * 8, input_nc=None, submodule=unet_block, norm_layer=norm_layer, use_dropout=use_dropout) + # gradually reduce the number of filters from ngf * 8 to ngf + unet_block = UnetSkipConnectionBlock(ngf * 4, ngf * 8, input_nc=None, submodule=unet_block, norm_layer=norm_layer) + unet_block = UnetSkipConnectionBlock(ngf * 2, ngf * 4, input_nc=None, submodule=unet_block, norm_layer=norm_layer) + unet_block = UnetSkipConnectionBlock(ngf, ngf * 2, input_nc=None, submodule=unet_block, norm_layer=norm_layer) + self.model = UnetSkipConnectionBlock(output_nc, ngf, input_nc=input_nc, submodule=unet_block, outermost=True, norm_layer=norm_layer) # add the outermost layer + + def forward(self, input): + """Standard forward""" + return self.model(input) + + +class UnetSkipConnectionBlock(nn.Module): + """Defines the Unet submodule with skip connection. + X -------------------identity---------------------- + |-- downsampling -- |submodule| -- upsampling --| + """ + + def __init__(self, outer_nc, inner_nc, input_nc=None, + submodule=None, outermost=False, innermost=False, norm_layer=nn.BatchNorm2d, use_dropout=False): + """Construct a Unet submodule with skip connections. + + Parameters: + outer_nc (int) -- the number of filters in the outer conv layer + inner_nc (int) -- the number of filters in the inner conv layer + input_nc (int) -- the number of channels in input images/features + submodule (UnetSkipConnectionBlock) -- previously defined submodules + outermost (bool) -- if this module is the outermost module + innermost (bool) -- if this module is the innermost module + norm_layer -- normalization layer + use_dropout (bool) -- if use dropout layers. + """ + super(UnetSkipConnectionBlock, self).__init__() + self.outermost = outermost + if type(norm_layer) == functools.partial: + use_bias = norm_layer.func == nn.InstanceNorm2d + else: + use_bias = norm_layer == nn.InstanceNorm2d + if input_nc is None: + input_nc = outer_nc + downconv = nn.Conv2d(input_nc, inner_nc, kernel_size=4, + stride=2, padding=1, bias=use_bias) + downrelu = nn.LeakyReLU(0.2, True) + downnorm = norm_layer(inner_nc) + uprelu = nn.ReLU(True) + upnorm = norm_layer(outer_nc) + + if outermost: + upconv = nn.ConvTranspose2d(inner_nc * 2, outer_nc, + kernel_size=4, stride=2, + padding=1) + down = [downconv] + up = [uprelu, upconv, nn.Tanh()] + model = down + [submodule] + up + elif innermost: + upconv = nn.ConvTranspose2d(inner_nc, outer_nc, + kernel_size=4, stride=2, + padding=1, bias=use_bias) + down = [downrelu, downconv] + up = [uprelu, upconv, upnorm] + model = down + up + else: + upconv = nn.ConvTranspose2d(inner_nc * 2, outer_nc, + kernel_size=4, stride=2, + padding=1, bias=use_bias) + down = [downrelu, downconv, downnorm] + up = [uprelu, upconv, upnorm] + + if use_dropout: + model = down + [submodule] + up + [nn.Dropout(0.5)] + else: + model = down + [submodule] + up + + self.model = nn.Sequential(*model) + + def forward(self, x): + if self.outermost: + return self.model(x) + else: # add skip connections + return torch.cat([x, self.model(x)], 1) + + +class NLayerDiscriminator(nn.Module): + """Defines a PatchGAN discriminator""" + + def __init__(self, input_nc, ndf=64, n_layers=3, norm_layer=nn.BatchNorm2d): + """Construct a PatchGAN discriminator + + Parameters: + input_nc (int) -- the number of channels in input images + ndf (int) -- the number of filters in the last conv layer + n_layers (int) -- the number of conv layers in the discriminator + norm_layer -- normalization layer + """ + super(NLayerDiscriminator, self).__init__() + if type(norm_layer) == functools.partial: # no need to use bias as BatchNorm2d has affine parameters + use_bias = norm_layer.func == nn.InstanceNorm2d + else: + use_bias = norm_layer == nn.InstanceNorm2d + + kw = 4 + padw = 1 + sequence = [nn.Conv2d(input_nc, ndf, kernel_size=kw, stride=2, padding=padw), nn.LeakyReLU(0.2, True)] + nf_mult = 1 + nf_mult_prev = 1 + for n in range(1, n_layers): # gradually increase the number of filters + nf_mult_prev = nf_mult + nf_mult = min(2 ** n, 8) + sequence += [ + nn.Conv2d(ndf * nf_mult_prev, ndf * nf_mult, kernel_size=kw, stride=2, padding=padw, bias=use_bias), + norm_layer(ndf * nf_mult), + nn.LeakyReLU(0.2, True) + ] + + nf_mult_prev = nf_mult + nf_mult = min(2 ** n_layers, 8) + sequence += [ + nn.Conv2d(ndf * nf_mult_prev, ndf * nf_mult, kernel_size=kw, stride=1, padding=padw, bias=use_bias), + norm_layer(ndf * nf_mult), + nn.LeakyReLU(0.2, True) + ] + + sequence += [nn.Conv2d(ndf * nf_mult, 1, kernel_size=kw, stride=1, padding=padw)] # output 1 channel prediction map + self.model = nn.Sequential(*sequence) + + def forward(self, input): + """Standard forward.""" + return self.model(input) + + +class PixelDiscriminator(nn.Module): + """Defines a 1x1 PatchGAN discriminator (pixelGAN)""" + + def __init__(self, input_nc, ndf=64, norm_layer=nn.BatchNorm2d): + """Construct a 1x1 PatchGAN discriminator + + Parameters: + input_nc (int) -- the number of channels in input images + ndf (int) -- the number of filters in the last conv layer + norm_layer -- normalization layer + """ + super(PixelDiscriminator, self).__init__() + if type(norm_layer) == functools.partial: # no need to use bias as BatchNorm2d has affine parameters + use_bias = norm_layer.func == nn.InstanceNorm2d + else: + use_bias = norm_layer == nn.InstanceNorm2d + + self.net = [ + nn.Conv2d(input_nc, ndf, kernel_size=1, stride=1, padding=0), + nn.LeakyReLU(0.2, True), + nn.Conv2d(ndf, ndf * 2, kernel_size=1, stride=1, padding=0, bias=use_bias), + norm_layer(ndf * 2), + nn.LeakyReLU(0.2, True), + nn.Conv2d(ndf * 2, 1, kernel_size=1, stride=1, padding=0, bias=use_bias)] + + self.net = nn.Sequential(*self.net) + + def forward(self, input): + """Standard forward.""" + return self.net(input) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/pix2pix4depth_model.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/pix2pix4depth_model.py new file mode 100644 index 00000000..89e89652 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/models/pix2pix4depth_model.py @@ -0,0 +1,155 @@ +import torch +from .base_model import BaseModel +from . import networks + + +class Pix2Pix4DepthModel(BaseModel): + """ This class implements the pix2pix model, for learning a mapping from input images to output images given paired data. + + The model training requires '--dataset_mode aligned' dataset. + By default, it uses a '--netG unet256' U-Net generator, + a '--netD basic' discriminator (PatchGAN), + and a '--gan_mode' vanilla GAN loss (the cross-entropy objective used in the orignal GAN paper). + + pix2pix paper: https://arxiv.org/pdf/1611.07004.pdf + """ + @staticmethod + def modify_commandline_options(parser, is_train=True): + """Add new dataset-specific options, and rewrite default values for existing options. + + Parameters: + parser -- original option parser + is_train (bool) -- whether training phase or test phase. You can use this flag to add training-specific or test-specific options. + + Returns: + the modified parser. + + For pix2pix, we do not use image buffer + The training objective is: GAN Loss + lambda_L1 * ||G(A)-B||_1 + By default, we use vanilla GAN loss, UNet with batchnorm, and aligned datasets. + """ + # changing the default values to match the pix2pix paper (https://phillipi.github.io/pix2pix/) + parser.set_defaults(input_nc=2,output_nc=1,norm='none', netG='unet_1024', dataset_mode='depthmerge') + if is_train: + parser.set_defaults(pool_size=0, gan_mode='vanilla',) + parser.add_argument('--lambda_L1', type=float, default=1000, help='weight for L1 loss') + return parser + + def __init__(self, opt): + """Initialize the pix2pix class. + + Parameters: + opt (Option class)-- stores all the experiment flags; needs to be a subclass of BaseOptions + """ + BaseModel.__init__(self, opt) + # specify the training losses you want to print out. The training/test scripts will call + + self.loss_names = ['G_GAN', 'G_L1', 'D_real', 'D_fake'] + # self.loss_names = ['G_L1'] + + # specify the images you want to save/display. The training/test scripts will call + if self.isTrain: + self.visual_names = ['outer','inner', 'fake_B', 'real_B'] + else: + self.visual_names = ['fake_B'] + + # specify the models you want to save to the disk. The training/test scripts will call and + if self.isTrain: + self.model_names = ['G','D'] + else: # during test time, only load G + self.model_names = ['G'] + + # define networks (both generator and discriminator) + self.netG = networks.define_G(opt.input_nc, opt.output_nc, 64, 'unet_1024', 'none', + False, 'normal', 0.02, self.gpu_ids) + + if self.isTrain: # define a discriminator; conditional GANs need to take both input and output images; Therefore, #channels for D is input_nc + output_nc + self.netD = networks.define_D(opt.input_nc + opt.output_nc, opt.ndf, opt.netD, + opt.n_layers_D, opt.norm, opt.init_type, opt.init_gain, self.gpu_ids) + + if self.isTrain: + # define loss functions + self.criterionGAN = networks.GANLoss(opt.gan_mode).to(self.device) + self.criterionL1 = torch.nn.L1Loss() + # initialize optimizers; schedulers will be automatically created by function . + self.optimizer_G = torch.optim.Adam(self.netG.parameters(), lr=1e-4, betas=(opt.beta1, 0.999)) + self.optimizer_D = torch.optim.Adam(self.netD.parameters(), lr=2e-06, betas=(opt.beta1, 0.999)) + self.optimizers.append(self.optimizer_G) + self.optimizers.append(self.optimizer_D) + + def set_input_train(self, input): + self.outer = input['data_outer'].to(self.device) + self.outer = torch.nn.functional.interpolate(self.outer,(1024,1024),mode='bilinear',align_corners=False) + + self.inner = input['data_inner'].to(self.device) + self.inner = torch.nn.functional.interpolate(self.inner,(1024,1024),mode='bilinear',align_corners=False) + + self.image_paths = input['image_path'] + + if self.isTrain: + self.gtfake = input['data_gtfake'].to(self.device) + self.gtfake = torch.nn.functional.interpolate(self.gtfake, (1024, 1024), mode='bilinear', align_corners=False) + self.real_B = self.gtfake + + self.real_A = torch.cat((self.outer, self.inner), 1) + + def set_input(self, outer, inner): + inner = torch.from_numpy(inner).unsqueeze(0).unsqueeze(0) + outer = torch.from_numpy(outer).unsqueeze(0).unsqueeze(0) + + inner = (inner - torch.min(inner))/(torch.max(inner)-torch.min(inner)) + outer = (outer - torch.min(outer))/(torch.max(outer)-torch.min(outer)) + + inner = self.normalize(inner) + outer = self.normalize(outer) + + self.real_A = torch.cat((outer, inner), 1).to(self.device) + + + def normalize(self, input): + input = input * 2 + input = input - 1 + return input + + def forward(self): + """Run forward pass; called by both functions and .""" + self.fake_B = self.netG(self.real_A) # G(A) + + def backward_D(self): + """Calculate GAN loss for the discriminator""" + # Fake; stop backprop to the generator by detaching fake_B + fake_AB = torch.cat((self.real_A, self.fake_B), 1) # we use conditional GANs; we need to feed both input and output to the discriminator + pred_fake = self.netD(fake_AB.detach()) + self.loss_D_fake = self.criterionGAN(pred_fake, False) + # Real + real_AB = torch.cat((self.real_A, self.real_B), 1) + pred_real = self.netD(real_AB) + self.loss_D_real = self.criterionGAN(pred_real, True) + # combine loss and calculate gradients + self.loss_D = (self.loss_D_fake + self.loss_D_real) * 0.5 + self.loss_D.backward() + + def backward_G(self): + """Calculate GAN and L1 loss for the generator""" + # First, G(A) should fake the discriminator + fake_AB = torch.cat((self.real_A, self.fake_B), 1) + pred_fake = self.netD(fake_AB) + self.loss_G_GAN = self.criterionGAN(pred_fake, True) + # Second, G(A) = B + self.loss_G_L1 = self.criterionL1(self.fake_B, self.real_B) * self.opt.lambda_L1 + # combine loss and calculate gradients + self.loss_G = self.loss_G_L1 + self.loss_G_GAN + self.loss_G.backward() + + def optimize_parameters(self): + self.forward() # compute fake images: G(A) + # update D + self.set_requires_grad(self.netD, True) # enable backprop for D + self.optimizer_D.zero_grad() # set D's gradients to zero + self.backward_D() # calculate gradients for D + self.optimizer_D.step() # update D's weights + # update G + self.set_requires_grad(self.netD, False) # D requires no gradients when optimizing G + self.optimizer_G.zero_grad() # set G's gradients to zero + self.backward_G() # calculate graidents for G + self.optimizer_G.step() # udpate G's weights \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/options/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/options/__init__.py new file mode 100644 index 00000000..e7eedebe --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/options/__init__.py @@ -0,0 +1 @@ +"""This package options includes option modules: training options, test options, and basic options (used in both training and test).""" diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/options/base_options.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/options/base_options.py new file mode 100644 index 00000000..533a1e88 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/options/base_options.py @@ -0,0 +1,156 @@ +import argparse +import os +from ...pix2pix.util import util +# import torch +from ...pix2pix import models +# import pix2pix.data +import numpy as np + +class BaseOptions(): + """This class defines options used during both training and test time. + + It also implements several helper functions such as parsing, printing, and saving the options. + It also gathers additional options defined in functions in both dataset class and model class. + """ + + def __init__(self): + """Reset the class; indicates the class hasn't been initailized""" + self.initialized = False + + def initialize(self, parser): + """Define the common options that are used in both training and test.""" + # basic parameters + parser.add_argument('--dataroot', help='path to images (should have subfolders trainA, trainB, valA, valB, etc)') + parser.add_argument('--name', type=str, default='void', help='mahdi_unet_new, scaled_unet') + parser.add_argument('--gpu_ids', type=str, default='0', help='gpu ids: e.g. 0 0,1,2, 0,2. use -1 for CPU') + parser.add_argument('--checkpoints_dir', type=str, default='./pix2pix/checkpoints', help='models are saved here') + # model parameters + parser.add_argument('--model', type=str, default='cycle_gan', help='chooses which model to use. [cycle_gan | pix2pix | test | colorization]') + parser.add_argument('--input_nc', type=int, default=2, help='# of input image channels: 3 for RGB and 1 for grayscale') + parser.add_argument('--output_nc', type=int, default=1, help='# of output image channels: 3 for RGB and 1 for grayscale') + parser.add_argument('--ngf', type=int, default=64, help='# of gen filters in the last conv layer') + parser.add_argument('--ndf', type=int, default=64, help='# of discrim filters in the first conv layer') + parser.add_argument('--netD', type=str, default='basic', help='specify discriminator architecture [basic | n_layers | pixel]. The basic model is a 70x70 PatchGAN. n_layers allows you to specify the layers in the discriminator') + parser.add_argument('--netG', type=str, default='resnet_9blocks', help='specify generator architecture [resnet_9blocks | resnet_6blocks | unet_256 | unet_128]') + parser.add_argument('--n_layers_D', type=int, default=3, help='only used if netD==n_layers') + parser.add_argument('--norm', type=str, default='instance', help='instance normalization or batch normalization [instance | batch | none]') + parser.add_argument('--init_type', type=str, default='normal', help='network initialization [normal | xavier | kaiming | orthogonal]') + parser.add_argument('--init_gain', type=float, default=0.02, help='scaling factor for normal, xavier and orthogonal.') + parser.add_argument('--no_dropout', action='store_true', help='no dropout for the generator') + # dataset parameters + parser.add_argument('--dataset_mode', type=str, default='unaligned', help='chooses how datasets are loaded. [unaligned | aligned | single | colorization]') + parser.add_argument('--direction', type=str, default='AtoB', help='AtoB or BtoA') + parser.add_argument('--serial_batches', action='store_true', help='if true, takes images in order to make batches, otherwise takes them randomly') + parser.add_argument('--num_threads', default=4, type=int, help='# threads for loading data') + parser.add_argument('--batch_size', type=int, default=1, help='input batch size') + parser.add_argument('--load_size', type=int, default=672, help='scale images to this size') + parser.add_argument('--crop_size', type=int, default=672, help='then crop to this size') + parser.add_argument('--max_dataset_size', type=int, default=10000, help='Maximum number of samples allowed per dataset. If the dataset directory contains more than max_dataset_size, only a subset is loaded.') + parser.add_argument('--preprocess', type=str, default='resize_and_crop', help='scaling and cropping of images at load time [resize_and_crop | crop | scale_width | scale_width_and_crop | none]') + parser.add_argument('--no_flip', action='store_true', help='if specified, do not flip the images for data augmentation') + parser.add_argument('--display_winsize', type=int, default=256, help='display window size for both visdom and HTML') + # additional parameters + parser.add_argument('--epoch', type=str, default='latest', help='which epoch to load? set to latest to use latest cached model') + parser.add_argument('--load_iter', type=int, default='0', help='which iteration to load? if load_iter > 0, the code will load models by iter_[load_iter]; otherwise, the code will load models by [epoch]') + parser.add_argument('--verbose', action='store_true', help='if specified, print more debugging information') + parser.add_argument('--suffix', default='', type=str, help='customized suffix: opt.name = opt.name + suffix: e.g., {model}_{netG}_size{load_size}') + + parser.add_argument('--data_dir', type=str, required=False, + help='input files directory images can be .png .jpg .tiff') + parser.add_argument('--output_dir', type=str, required=False, + help='result dir. result depth will be png. vides are JMPG as avi') + parser.add_argument('--savecrops', type=int, required=False) + parser.add_argument('--savewholeest', type=int, required=False) + parser.add_argument('--output_resolution', type=int, required=False, + help='0 for no restriction 1 for resize to input size') + parser.add_argument('--net_receptive_field_size', type=int, required=False) + parser.add_argument('--pix2pixsize', type=int, required=False) + parser.add_argument('--generatevideo', type=int, required=False) + parser.add_argument('--depthNet', type=int, required=False, help='0: midas 1:strurturedRL') + parser.add_argument('--R0', action='store_true') + parser.add_argument('--R20', action='store_true') + parser.add_argument('--Final', action='store_true') + parser.add_argument('--colorize_results', action='store_true') + parser.add_argument('--max_res', type=float, default=np.inf) + + self.initialized = True + return parser + + def gather_options(self): + """Initialize our parser with basic options(only once). + Add additional model-specific and dataset-specific options. + These options are defined in the function + in model and dataset classes. + """ + if not self.initialized: # check if it has been initialized + parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser = self.initialize(parser) + + # get the basic options + opt, _ = parser.parse_known_args() + + # modify model-related parser options + model_name = opt.model + model_option_setter = models.get_option_setter(model_name) + parser = model_option_setter(parser, self.isTrain) + opt, _ = parser.parse_known_args() # parse again with new defaults + + # modify dataset-related parser options + # dataset_name = opt.dataset_mode + # dataset_option_setter = pix2pix.data.get_option_setter(dataset_name) + # parser = dataset_option_setter(parser, self.isTrain) + + # save and return the parser + self.parser = parser + #return parser.parse_args() #EVIL + return opt + + def print_options(self, opt): + """Print and save options + + It will print both current options and default values(if different). + It will save options into a text file / [checkpoints_dir] / opt.txt + """ + message = '' + message += '----------------- Options ---------------\n' + for k, v in sorted(vars(opt).items()): + comment = '' + default = self.parser.get_default(k) + if v != default: + comment = '\t[default: %s]' % str(default) + message += '{:>25}: {:<30}{}\n'.format(str(k), str(v), comment) + message += '----------------- End -------------------' + print(message) + + # save to the disk + expr_dir = os.path.join(opt.checkpoints_dir, opt.name) + util.mkdirs(expr_dir) + file_name = os.path.join(expr_dir, '{}_opt.txt'.format(opt.phase)) + with open(file_name, 'wt') as opt_file: + opt_file.write(message) + opt_file.write('\n') + + def parse(self): + """Parse our options, create checkpoints directory suffix, and set up gpu device.""" + opt = self.gather_options() + opt.isTrain = self.isTrain # train or test + + # process opt.suffix + if opt.suffix: + suffix = ('_' + opt.suffix.format(**vars(opt))) if opt.suffix != '' else '' + opt.name = opt.name + suffix + + #self.print_options(opt) + + # set gpu ids + str_ids = opt.gpu_ids.split(',') + opt.gpu_ids = [] + for str_id in str_ids: + id = int(str_id) + if id >= 0: + opt.gpu_ids.append(id) + #if len(opt.gpu_ids) > 0: + # torch.cuda.set_device(opt.gpu_ids[0]) + + self.opt = opt + return self.opt diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/options/test_options.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/options/test_options.py new file mode 100644 index 00000000..a3424b5e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/options/test_options.py @@ -0,0 +1,22 @@ +from .base_options import BaseOptions + + +class TestOptions(BaseOptions): + """This class includes test options. + + It also includes shared options defined in BaseOptions. + """ + + def initialize(self, parser): + parser = BaseOptions.initialize(self, parser) # define shared options + parser.add_argument('--aspect_ratio', type=float, default=1.0, help='aspect ratio of result images') + parser.add_argument('--phase', type=str, default='test', help='train, val, test, etc') + # Dropout and Batchnorm has different behavioir during training and test. + parser.add_argument('--eval', action='store_true', help='use eval mode during test time.') + parser.add_argument('--num_test', type=int, default=50, help='how many test images to run') + # rewrite devalue values + parser.set_defaults(model='pix2pix4depth') + # To avoid cropping, the load_size should be the same as crop_size + parser.set_defaults(load_size=parser.get_default('crop_size')) + self.isTrain = False + return parser diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/__init__.py new file mode 100644 index 00000000..ae36f63d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/__init__.py @@ -0,0 +1 @@ +"""This package includes a miscellaneous collection of useful helper functions.""" diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/get_data.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/get_data.py new file mode 100644 index 00000000..97edc3ce --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/get_data.py @@ -0,0 +1,110 @@ +from __future__ import print_function +import os +import tarfile +import requests +from warnings import warn +from zipfile import ZipFile +from bs4 import BeautifulSoup +from os.path import abspath, isdir, join, basename + + +class GetData(object): + """A Python script for downloading CycleGAN or pix2pix datasets. + + Parameters: + technique (str) -- One of: 'cyclegan' or 'pix2pix'. + verbose (bool) -- If True, print additional information. + + Examples: + >>> from util.get_data import GetData + >>> gd = GetData(technique='cyclegan') + >>> new_data_path = gd.get(save_path='./datasets') # options will be displayed. + + Alternatively, You can use bash scripts: 'scripts/download_pix2pix_model.sh' + and 'scripts/download_cyclegan_model.sh'. + """ + + def __init__(self, technique='cyclegan', verbose=True): + url_dict = { + 'pix2pix': 'http://efrosgans.eecs.berkeley.edu/pix2pix/datasets/', + 'cyclegan': 'https://people.eecs.berkeley.edu/~taesung_park/CycleGAN/datasets' + } + self.url = url_dict.get(technique.lower()) + self._verbose = verbose + + def _print(self, text): + if self._verbose: + print(text) + + @staticmethod + def _get_options(r): + soup = BeautifulSoup(r.text, 'lxml') + options = [h.text for h in soup.find_all('a', href=True) + if h.text.endswith(('.zip', 'tar.gz'))] + return options + + def _present_options(self): + r = requests.get(self.url) + options = self._get_options(r) + print('Options:\n') + for i, o in enumerate(options): + print("{0}: {1}".format(i, o)) + choice = input("\nPlease enter the number of the " + "dataset above you wish to download:") + return options[int(choice)] + + def _download_data(self, dataset_url, save_path): + if not isdir(save_path): + os.makedirs(save_path) + + base = basename(dataset_url) + temp_save_path = join(save_path, base) + + with open(temp_save_path, "wb") as f: + r = requests.get(dataset_url) + f.write(r.content) + + if base.endswith('.tar.gz'): + obj = tarfile.open(temp_save_path) + elif base.endswith('.zip'): + obj = ZipFile(temp_save_path, 'r') + else: + raise ValueError("Unknown File Type: {0}.".format(base)) + + self._print("Unpacking Data...") + obj.extractall(save_path) + obj.close() + os.remove(temp_save_path) + + def get(self, save_path, dataset=None): + """ + + Download a dataset. + + Parameters: + save_path (str) -- A directory to save the data to. + dataset (str) -- (optional). A specific dataset to download. + Note: this must include the file extension. + If None, options will be presented for you + to choose from. + + Returns: + save_path_full (str) -- the absolute path to the downloaded data. + + """ + if dataset is None: + selected_dataset = self._present_options() + else: + selected_dataset = dataset + + save_path_full = join(save_path, selected_dataset.split('.')[0]) + + if isdir(save_path_full): + warn("\n'{0}' already exists. Voiding Download.".format( + save_path_full)) + else: + self._print('Downloading Data...') + url = "{0}/{1}".format(self.url, selected_dataset) + self._download_data(url, save_path=save_path) + + return abspath(save_path_full) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/guidedfilter.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/guidedfilter.py new file mode 100644 index 00000000..d377ff12 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/guidedfilter.py @@ -0,0 +1,47 @@ +import numpy as np + +class GuidedFilter(): + def __init__(self, source, reference, r=64, eps= 0.05**2): + self.source = source; + self.reference = reference; + self.r = r + self.eps = eps + + self.smooth = self.guidedfilter(self.source,self.reference,self.r,self.eps) + + def boxfilter(self,img, r): + (rows, cols) = img.shape + imDst = np.zeros_like(img) + + imCum = np.cumsum(img, 0) + imDst[0 : r+1, :] = imCum[r : 2*r+1, :] + imDst[r+1 : rows-r, :] = imCum[2*r+1 : rows, :] - imCum[0 : rows-2*r-1, :] + imDst[rows-r: rows, :] = np.tile(imCum[rows-1, :], [r, 1]) - imCum[rows-2*r-1 : rows-r-1, :] + + imCum = np.cumsum(imDst, 1) + imDst[:, 0 : r+1] = imCum[:, r : 2*r+1] + imDst[:, r+1 : cols-r] = imCum[:, 2*r+1 : cols] - imCum[:, 0 : cols-2*r-1] + imDst[:, cols-r: cols] = np.tile(imCum[:, cols-1], [r, 1]).T - imCum[:, cols-2*r-1 : cols-r-1] + + return imDst + + def guidedfilter(self,I, p, r, eps): + (rows, cols) = I.shape + N = self.boxfilter(np.ones([rows, cols]), r) + + meanI = self.boxfilter(I, r) / N + meanP = self.boxfilter(p, r) / N + meanIp = self.boxfilter(I * p, r) / N + covIp = meanIp - meanI * meanP + + meanII = self.boxfilter(I * I, r) / N + varI = meanII - meanI * meanI + + a = covIp / (varI + eps) + b = meanP - a * meanI + + meanA = self.boxfilter(a, r) / N + meanB = self.boxfilter(b, r) / N + + q = meanA * I + meanB + return q \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/html.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/html.py new file mode 100644 index 00000000..cc3262a1 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/html.py @@ -0,0 +1,86 @@ +import dominate +from dominate.tags import meta, h3, table, tr, td, p, a, img, br +import os + + +class HTML: + """This HTML class allows us to save images and write texts into a single HTML file. + + It consists of functions such as (add a text header to the HTML file), + (add a row of images to the HTML file), and (save the HTML to the disk). + It is based on Python library 'dominate', a Python library for creating and manipulating HTML documents using a DOM API. + """ + + def __init__(self, web_dir, title, refresh=0): + """Initialize the HTML classes + + Parameters: + web_dir (str) -- a directory that stores the webpage. HTML file will be created at /index.html; images will be saved at 0: + with self.doc.head: + meta(http_equiv="refresh", content=str(refresh)) + + def get_image_dir(self): + """Return the directory that stores images""" + return self.img_dir + + def add_header(self, text): + """Insert a header to the HTML file + + Parameters: + text (str) -- the header text + """ + with self.doc: + h3(text) + + def add_images(self, ims, txts, links, width=400): + """add images to the HTML file + + Parameters: + ims (str list) -- a list of image paths + txts (str list) -- a list of image names shown on the website + links (str list) -- a list of hyperref links; when you click an image, it will redirect you to a new page + """ + self.t = table(border=1, style="table-layout: fixed;") # Insert a table + self.doc.add(self.t) + with self.t: + with tr(): + for im, txt, link in zip(ims, txts, links): + with td(style="word-wrap: break-word;", halign="center", valign="top"): + with p(): + with a(href=os.path.join('images', link)): + img(style="width:%dpx" % width, src=os.path.join('images', im)) + br() + p(txt) + + def save(self): + """save the current content to the HMTL file""" + html_file = '%s/index.html' % self.web_dir + f = open(html_file, 'wt') + f.write(self.doc.render()) + f.close() + + +if __name__ == '__main__': # we show an example usage here. + html = HTML('web/', 'test_html') + html.add_header('hello world') + + ims, txts, links = [], [], [] + for n in range(4): + ims.append('image_%d.png' % n) + txts.append('text_%d' % n) + links.append('image_%d.png' % n) + html.add_images(ims, txts, links) + html.save() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/image_pool.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/image_pool.py new file mode 100644 index 00000000..6d086f88 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/image_pool.py @@ -0,0 +1,54 @@ +import random +import torch + + +class ImagePool(): + """This class implements an image buffer that stores previously generated images. + + This buffer enables us to update discriminators using a history of generated images + rather than the ones produced by the latest generators. + """ + + def __init__(self, pool_size): + """Initialize the ImagePool class + + Parameters: + pool_size (int) -- the size of image buffer, if pool_size=0, no buffer will be created + """ + self.pool_size = pool_size + if self.pool_size > 0: # create an empty pool + self.num_imgs = 0 + self.images = [] + + def query(self, images): + """Return an image from the pool. + + Parameters: + images: the latest generated images from the generator + + Returns images from the buffer. + + By 50/100, the buffer will return input images. + By 50/100, the buffer will return images previously stored in the buffer, + and insert the current images to the buffer. + """ + if self.pool_size == 0: # if the buffer size is 0, do nothing + return images + return_images = [] + for image in images: + image = torch.unsqueeze(image.data, 0) + if self.num_imgs < self.pool_size: # if the buffer is not full; keep inserting current images to the buffer + self.num_imgs = self.num_imgs + 1 + self.images.append(image) + return_images.append(image) + else: + p = random.uniform(0, 1) + if p > 0.5: # by 50% chance, the buffer will return a previously stored image, and insert the current image into the buffer + random_id = random.randint(0, self.pool_size - 1) # randint is inclusive + tmp = self.images[random_id].clone() + self.images[random_id] = image + return_images.append(tmp) + else: # by another 50% chance, the buffer will return the current image + return_images.append(image) + return_images = torch.cat(return_images, 0) # collect all the images and return + return return_images diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/util.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/util.py new file mode 100644 index 00000000..8a7aceaa --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/util.py @@ -0,0 +1,105 @@ +"""This module contains simple helper functions """ +from __future__ import print_function +import torch +import numpy as np +from PIL import Image +import os + + +def tensor2im(input_image, imtype=np.uint16): + """"Converts a Tensor array into a numpy image array. + + Parameters: + input_image (tensor) -- the input image tensor array + imtype (type) -- the desired type of the converted numpy array + """ + if not isinstance(input_image, np.ndarray): + if isinstance(input_image, torch.Tensor): # get the data from a variable + image_tensor = input_image.data + else: + return input_image + image_numpy = torch.squeeze(image_tensor).cpu().numpy() # convert it into a numpy array + image_numpy = (image_numpy + 1) / 2.0 * (2**16-1) # + else: # if it is a numpy array, do nothing + image_numpy = input_image + return image_numpy.astype(imtype) + + +def diagnose_network(net, name='network'): + """Calculate and print the mean of average absolute(gradients) + + Parameters: + net (torch network) -- Torch network + name (str) -- the name of the network + """ + mean = 0.0 + count = 0 + for param in net.parameters(): + if param.grad is not None: + mean += torch.mean(torch.abs(param.grad.data)) + count += 1 + if count > 0: + mean = mean / count + print(name) + print(mean) + + +def save_image(image_numpy, image_path, aspect_ratio=1.0): + """Save a numpy image to the disk + + Parameters: + image_numpy (numpy array) -- input numpy array + image_path (str) -- the path of the image + """ + image_pil = Image.fromarray(image_numpy) + + image_pil = image_pil.convert('I;16') + + # image_pil = Image.fromarray(image_numpy) + # h, w, _ = image_numpy.shape + # + # if aspect_ratio > 1.0: + # image_pil = image_pil.resize((h, int(w * aspect_ratio)), Image.BICUBIC) + # if aspect_ratio < 1.0: + # image_pil = image_pil.resize((int(h / aspect_ratio), w), Image.BICUBIC) + + image_pil.save(image_path) + + +def print_numpy(x, val=True, shp=False): + """Print the mean, min, max, median, std, and size of a numpy array + + Parameters: + val (bool) -- if print the values of the numpy array + shp (bool) -- if print the shape of the numpy array + """ + x = x.astype(np.float64) + if shp: + print('shape,', x.shape) + if val: + x = x.flatten() + print('mean = %3.3f, min = %3.3f, max = %3.3f, median = %3.3f, std=%3.3f' % ( + np.mean(x), np.min(x), np.max(x), np.median(x), np.std(x))) + + +def mkdirs(paths): + """create empty directories if they don't exist + + Parameters: + paths (str list) -- a list of directory paths + """ + if isinstance(paths, list) and not isinstance(paths, str): + for path in paths: + mkdir(path) + else: + mkdir(paths) + + +def mkdir(path): + """create a single empty directory if it didn't exist + + Parameters: + path (str) -- a single directory path + """ + if not os.path.exists(path): + os.makedirs(path) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/visualizer.py b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/visualizer.py new file mode 100644 index 00000000..810a0513 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/leres/pix2pix/util/visualizer.py @@ -0,0 +1,166 @@ +import numpy as np +import os +import sys +import ntpath +import time +from . import util, html +from subprocess import Popen, PIPE +import torch + + +if sys.version_info[0] == 2: + VisdomExceptionBase = Exception +else: + VisdomExceptionBase = ConnectionError + + +def save_images(webpage, visuals, image_path, aspect_ratio=1.0, width=256): + """Save images to the disk. + + Parameters: + webpage (the HTML class) -- the HTML webpage class that stores these imaegs (see html.py for more details) + visuals (OrderedDict) -- an ordered dictionary that stores (name, images (either tensor or numpy) ) pairs + image_path (str) -- the string is used to create image paths + aspect_ratio (float) -- the aspect ratio of saved images + width (int) -- the images will be resized to width x width + + This function will save images stored in 'visuals' to the HTML file specified by 'webpage'. + """ + image_dir = webpage.get_image_dir() + short_path = ntpath.basename(image_path[0]) + name = os.path.splitext(short_path)[0] + + webpage.add_header(name) + ims, txts, links = [], [], [] + + for label, im_data in visuals.items(): + im = util.tensor2im(im_data) + image_name = '%s_%s.png' % (name, label) + save_path = os.path.join(image_dir, image_name) + util.save_image(im, save_path, aspect_ratio=aspect_ratio) + ims.append(image_name) + txts.append(label) + links.append(image_name) + webpage.add_images(ims, txts, links, width=width) + + +class Visualizer(): + """This class includes several functions that can display/save images and print/save logging information. + + It uses a Python library 'visdom' for display, and a Python library 'dominate' (wrapped in 'HTML') for creating HTML files with images. + """ + + def __init__(self, opt): + """Initialize the Visualizer class + + Parameters: + opt -- stores all the experiment flags; needs to be a subclass of BaseOptions + Step 1: Cache the training/test options + Step 2: connect to a visdom server + Step 3: create an HTML object for saveing HTML filters + Step 4: create a logging file to store training losses + """ + self.opt = opt # cache the option + self.display_id = opt.display_id + self.use_html = opt.isTrain and not opt.no_html + self.win_size = opt.display_winsize + self.name = opt.name + self.port = opt.display_port + self.saved = False + + if self.use_html: # create an HTML object at /web/; images will be saved under /web/images/ + self.web_dir = os.path.join(opt.checkpoints_dir, opt.name, 'web') + self.img_dir = os.path.join(self.web_dir, 'images') + print('create web directory %s...' % self.web_dir) + util.mkdirs([self.web_dir, self.img_dir]) + # create a logging file to store training losses + self.log_name = os.path.join(opt.checkpoints_dir, opt.name, 'loss_log.txt') + with open(self.log_name, "a") as log_file: + now = time.strftime("%c") + log_file.write('================ Training Loss (%s) ================\n' % now) + + def reset(self): + """Reset the self.saved status""" + self.saved = False + + def create_visdom_connections(self): + """If the program could not connect to Visdom server, this function will start a new server at port < self.port > """ + cmd = sys.executable + ' -m visdom.server -p %d &>/dev/null &' % self.port + print('\n\nCould not connect to Visdom server. \n Trying to start a server....') + print('Command: %s' % cmd) + Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE) + + def display_current_results(self, visuals, epoch, save_result): + """Display current results on visdom; save current results to an HTML file. + + Parameters: + visuals (OrderedDict) - - dictionary of images to display or save + epoch (int) - - the current epoch + save_result (bool) - - if save the current results to an HTML file + """ + if self.use_html and (save_result or not self.saved): # save images to an HTML file if they haven't been saved. + self.saved = True + # save images to the disk + for label, image in visuals.items(): + image_numpy = util.tensor2im(image) + img_path = os.path.join(self.img_dir, 'epoch%.3d_%s.png' % (epoch, label)) + util.save_image(image_numpy, img_path) + + # update website + webpage = html.HTML(self.web_dir, 'Experiment name = %s' % self.name, refresh=1) + for n in range(epoch, 0, -1): + webpage.add_header('epoch [%d]' % n) + ims, txts, links = [], [], [] + + for label, image_numpy in visuals.items(): + # image_numpy = util.tensor2im(image) + img_path = 'epoch%.3d_%s.png' % (n, label) + ims.append(img_path) + txts.append(label) + links.append(img_path) + webpage.add_images(ims, txts, links, width=self.win_size) + webpage.save() + + # def plot_current_losses(self, epoch, counter_ratio, losses): + # """display the current losses on visdom display: dictionary of error labels and values + # + # Parameters: + # epoch (int) -- current epoch + # counter_ratio (float) -- progress (percentage) in the current epoch, between 0 to 1 + # losses (OrderedDict) -- training losses stored in the format of (name, float) pairs + # """ + # if not hasattr(self, 'plot_data'): + # self.plot_data = {'X': [], 'Y': [], 'legend': list(losses.keys())} + # self.plot_data['X'].append(epoch + counter_ratio) + # self.plot_data['Y'].append([losses[k] for k in self.plot_data['legend']]) + # try: + # self.vis.line( + # X=np.stack([np.array(self.plot_data['X'])] * len(self.plot_data['legend']), 1), + # Y=np.array(self.plot_data['Y']), + # opts={ + # 'title': self.name + ' loss over time', + # 'legend': self.plot_data['legend'], + # 'xlabel': 'epoch', + # 'ylabel': 'loss'}, + # win=self.display_id) + # except VisdomExceptionBase: + # self.create_visdom_connections() + + # losses: same format as |losses| of plot_current_losses + def print_current_losses(self, epoch, iters, losses, t_comp, t_data): + """print current losses on console; also save the losses to the disk + + Parameters: + epoch (int) -- current epoch + iters (int) -- current training iteration during this epoch (reset to 0 at the end of every epoch) + losses (OrderedDict) -- training losses stored in the format of (name, float) pairs + t_comp (float) -- computational time per data point (normalized by batch_size) + t_data (float) -- data loading time per data point (normalized by batch_size) + """ + message = '(epoch: %d, iters: %d, time: %.3f, data: %.3f) ' % (epoch, iters, t_comp, t_data) + for k, v in losses.items(): + message += '%s: %.3f ' % (k, v) + + print(message) # print the message + with open(self.log_name, "a") as log_file: + log_file.write('%s\n' % message) # save the message diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lineart/LICENSE b/extensions-builtin/sd_forge_controlnet/annotator/lineart/LICENSE new file mode 100644 index 00000000..16a9d56a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lineart/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Caroline Chan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lineart/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/lineart/__init__.py new file mode 100644 index 00000000..d0e43c50 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lineart/__init__.py @@ -0,0 +1,133 @@ +import os +import cv2 +import torch +import numpy as np + +import torch.nn as nn +from einops import rearrange +from modules import devices +from annotator.annotator_path import models_path + + +norm_layer = nn.InstanceNorm2d + + +class ResidualBlock(nn.Module): + def __init__(self, in_features): + super(ResidualBlock, self).__init__() + + conv_block = [ nn.ReflectionPad2d(1), + nn.Conv2d(in_features, in_features, 3), + norm_layer(in_features), + nn.ReLU(inplace=True), + nn.ReflectionPad2d(1), + nn.Conv2d(in_features, in_features, 3), + norm_layer(in_features) + ] + + self.conv_block = nn.Sequential(*conv_block) + + def forward(self, x): + return x + self.conv_block(x) + + +class Generator(nn.Module): + def __init__(self, input_nc, output_nc, n_residual_blocks=9, sigmoid=True): + super(Generator, self).__init__() + + # Initial convolution block + model0 = [ nn.ReflectionPad2d(3), + nn.Conv2d(input_nc, 64, 7), + norm_layer(64), + nn.ReLU(inplace=True) ] + self.model0 = nn.Sequential(*model0) + + # Downsampling + model1 = [] + in_features = 64 + out_features = in_features*2 + for _ in range(2): + model1 += [ nn.Conv2d(in_features, out_features, 3, stride=2, padding=1), + norm_layer(out_features), + nn.ReLU(inplace=True) ] + in_features = out_features + out_features = in_features*2 + self.model1 = nn.Sequential(*model1) + + model2 = [] + # Residual blocks + for _ in range(n_residual_blocks): + model2 += [ResidualBlock(in_features)] + self.model2 = nn.Sequential(*model2) + + # Upsampling + model3 = [] + out_features = in_features//2 + for _ in range(2): + model3 += [ nn.ConvTranspose2d(in_features, out_features, 3, stride=2, padding=1, output_padding=1), + norm_layer(out_features), + nn.ReLU(inplace=True) ] + in_features = out_features + out_features = in_features//2 + self.model3 = nn.Sequential(*model3) + + # Output layer + model4 = [ nn.ReflectionPad2d(3), + nn.Conv2d(64, output_nc, 7)] + if sigmoid: + model4 += [nn.Sigmoid()] + + self.model4 = nn.Sequential(*model4) + + def forward(self, x, cond=None): + out = self.model0(x) + out = self.model1(out) + out = self.model2(out) + out = self.model3(out) + out = self.model4(out) + + return out + + +class LineartDetector: + model_dir = os.path.join(models_path, "lineart") + model_default = 'sk_model.pth' + model_coarse = 'sk_model2.pth' + + def __init__(self, model_name): + self.model = None + self.model_name = model_name + self.device = devices.get_device_for("controlnet") + + def load_model(self, name): + remote_model_path = "https://huggingface.co/lllyasviel/Annotators/resolve/main/" + name + model_path = os.path.join(self.model_dir, name) + if not os.path.exists(model_path): + from basicsr.utils.download_util import load_file_from_url + load_file_from_url(remote_model_path, model_dir=self.model_dir) + model = Generator(3, 1, 3) + model.load_state_dict(torch.load(model_path, map_location=torch.device('cpu'))) + model.eval() + self.model = model.to(self.device) + + def unload_model(self): + if self.model is not None: + self.model.cpu() + + def __call__(self, input_image): + if self.model is None: + self.load_model(self.model_name) + self.model.to(self.device) + + assert input_image.ndim == 3 + image = input_image + with torch.no_grad(): + image = torch.from_numpy(image).float().to(self.device) + image = image / 255.0 + image = rearrange(image, 'h w c -> 1 c h w') + line = self.model(image)[0][0] + + line = line.cpu().numpy() + line = (line * 255.0).clip(0, 255).astype(np.uint8) + + return line \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lineart_anime/LICENSE b/extensions-builtin/sd_forge_controlnet/annotator/lineart_anime/LICENSE new file mode 100644 index 00000000..16a9d56a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lineart_anime/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Caroline Chan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/lineart_anime/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/lineart_anime/__init__.py new file mode 100644 index 00000000..dddfa979 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/lineart_anime/__init__.py @@ -0,0 +1,161 @@ +import numpy as np +import torch +import torch.nn as nn +import functools + +import os +import cv2 +from einops import rearrange +from modules import devices +from annotator.annotator_path import models_path + + +class UnetGenerator(nn.Module): + """Create a Unet-based generator""" + + def __init__(self, input_nc, output_nc, num_downs, ngf=64, norm_layer=nn.BatchNorm2d, use_dropout=False): + """Construct a Unet generator + Parameters: + input_nc (int) -- the number of channels in input images + output_nc (int) -- the number of channels in output images + num_downs (int) -- the number of downsamplings in UNet. For example, # if |num_downs| == 7, + image of size 128x128 will become of size 1x1 # at the bottleneck + ngf (int) -- the number of filters in the last conv layer + norm_layer -- normalization layer + We construct the U-Net from the innermost layer to the outermost layer. + It is a recursive process. + """ + super(UnetGenerator, self).__init__() + # construct unet structure + unet_block = UnetSkipConnectionBlock(ngf * 8, ngf * 8, input_nc=None, submodule=None, norm_layer=norm_layer, innermost=True) # add the innermost layer + for _ in range(num_downs - 5): # add intermediate layers with ngf * 8 filters + unet_block = UnetSkipConnectionBlock(ngf * 8, ngf * 8, input_nc=None, submodule=unet_block, norm_layer=norm_layer, use_dropout=use_dropout) + # gradually reduce the number of filters from ngf * 8 to ngf + unet_block = UnetSkipConnectionBlock(ngf * 4, ngf * 8, input_nc=None, submodule=unet_block, norm_layer=norm_layer) + unet_block = UnetSkipConnectionBlock(ngf * 2, ngf * 4, input_nc=None, submodule=unet_block, norm_layer=norm_layer) + unet_block = UnetSkipConnectionBlock(ngf, ngf * 2, input_nc=None, submodule=unet_block, norm_layer=norm_layer) + self.model = UnetSkipConnectionBlock(output_nc, ngf, input_nc=input_nc, submodule=unet_block, outermost=True, norm_layer=norm_layer) # add the outermost layer + + def forward(self, input): + """Standard forward""" + return self.model(input) + + +class UnetSkipConnectionBlock(nn.Module): + """Defines the Unet submodule with skip connection. + X -------------------identity---------------------- + |-- downsampling -- |submodule| -- upsampling --| + """ + + def __init__(self, outer_nc, inner_nc, input_nc=None, + submodule=None, outermost=False, innermost=False, norm_layer=nn.BatchNorm2d, use_dropout=False): + """Construct a Unet submodule with skip connections. + Parameters: + outer_nc (int) -- the number of filters in the outer conv layer + inner_nc (int) -- the number of filters in the inner conv layer + input_nc (int) -- the number of channels in input images/features + submodule (UnetSkipConnectionBlock) -- previously defined submodules + outermost (bool) -- if this module is the outermost module + innermost (bool) -- if this module is the innermost module + norm_layer -- normalization layer + use_dropout (bool) -- if use dropout layers. + """ + super(UnetSkipConnectionBlock, self).__init__() + self.outermost = outermost + if type(norm_layer) == functools.partial: + use_bias = norm_layer.func == nn.InstanceNorm2d + else: + use_bias = norm_layer == nn.InstanceNorm2d + if input_nc is None: + input_nc = outer_nc + downconv = nn.Conv2d(input_nc, inner_nc, kernel_size=4, + stride=2, padding=1, bias=use_bias) + downrelu = nn.LeakyReLU(0.2, True) + downnorm = norm_layer(inner_nc) + uprelu = nn.ReLU(True) + upnorm = norm_layer(outer_nc) + + if outermost: + upconv = nn.ConvTranspose2d(inner_nc * 2, outer_nc, + kernel_size=4, stride=2, + padding=1) + down = [downconv] + up = [uprelu, upconv, nn.Tanh()] + model = down + [submodule] + up + elif innermost: + upconv = nn.ConvTranspose2d(inner_nc, outer_nc, + kernel_size=4, stride=2, + padding=1, bias=use_bias) + down = [downrelu, downconv] + up = [uprelu, upconv, upnorm] + model = down + up + else: + upconv = nn.ConvTranspose2d(inner_nc * 2, outer_nc, + kernel_size=4, stride=2, + padding=1, bias=use_bias) + down = [downrelu, downconv, downnorm] + up = [uprelu, upconv, upnorm] + + if use_dropout: + model = down + [submodule] + up + [nn.Dropout(0.5)] + else: + model = down + [submodule] + up + + self.model = nn.Sequential(*model) + + def forward(self, x): + if self.outermost: + return self.model(x) + else: # add skip connections + return torch.cat([x, self.model(x)], 1) + + +class LineartAnimeDetector: + model_dir = os.path.join(models_path, "lineart_anime") + + def __init__(self): + self.model = None + self.device = devices.get_device_for("controlnet") + + def load_model(self): + remote_model_path = "https://huggingface.co/lllyasviel/Annotators/resolve/main/netG.pth" + modelpath = os.path.join(self.model_dir, "netG.pth") + if not os.path.exists(modelpath): + from basicsr.utils.download_util import load_file_from_url + load_file_from_url(remote_model_path, model_dir=self.model_dir) + norm_layer = functools.partial(nn.InstanceNorm2d, affine=False, track_running_stats=False) + net = UnetGenerator(3, 1, 8, 64, norm_layer=norm_layer, use_dropout=False) + ckpt = torch.load(modelpath) + for key in list(ckpt.keys()): + if 'module.' in key: + ckpt[key.replace('module.', '')] = ckpt[key] + del ckpt[key] + net.load_state_dict(ckpt) + net.eval() + self.model = net.to(self.device) + + def unload_model(self): + if self.model is not None: + self.model.cpu() + + def __call__(self, input_image): + if self.model is None: + self.load_model() + self.model.to(self.device) + + H, W, C = input_image.shape + Hn = 256 * int(np.ceil(float(H) / 256.0)) + Wn = 256 * int(np.ceil(float(W) / 256.0)) + img = cv2.resize(input_image, (Wn, Hn), interpolation=cv2.INTER_CUBIC) + with torch.no_grad(): + image_feed = torch.from_numpy(img).float().to(self.device) + image_feed = image_feed / 127.5 - 1.0 + image_feed = rearrange(image_feed, 'h w c -> 1 c h w') + + line = self.model(image_feed)[0, 0] * 127.5 + 127.5 + line = line.cpu().numpy() + + line = cv2.resize(line, (W, H), interpolation=cv2.INTER_CUBIC) + line = line.clip(0, 255).astype(np.uint8) + return line + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/manga_line/LICENSE b/extensions-builtin/sd_forge_controlnet/annotator/manga_line/LICENSE new file mode 100644 index 00000000..9bad0545 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/manga_line/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Miaomiao Li + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/extensions-builtin/sd_forge_controlnet/annotator/manga_line/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/manga_line/__init__.py new file mode 100644 index 00000000..c797fd22 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/manga_line/__init__.py @@ -0,0 +1,248 @@ +import os +import torch +import torch.nn as nn +from PIL import Image +import fnmatch +import cv2 + +import sys + +import numpy as np +from einops import rearrange +from modules import devices +from annotator.annotator_path import models_path + + +class _bn_relu_conv(nn.Module): + def __init__(self, in_filters, nb_filters, fw, fh, subsample=1): + super(_bn_relu_conv, self).__init__() + self.model = nn.Sequential( + nn.BatchNorm2d(in_filters, eps=1e-3), + nn.LeakyReLU(0.2), + nn.Conv2d(in_filters, nb_filters, (fw, fh), stride=subsample, padding=(fw//2, fh//2), padding_mode='zeros') + ) + + def forward(self, x): + return self.model(x) + + # the following are for debugs + print("****", np.max(x.cpu().numpy()), np.min(x.cpu().numpy()), np.mean(x.cpu().numpy()), np.std(x.cpu().numpy()), x.shape) + for i,layer in enumerate(self.model): + if i != 2: + x = layer(x) + else: + x = layer(x) + #x = nn.functional.pad(x, (1, 1, 1, 1), mode='constant', value=0) + print("____", np.max(x.cpu().numpy()), np.min(x.cpu().numpy()), np.mean(x.cpu().numpy()), np.std(x.cpu().numpy()), x.shape) + print(x[0]) + return x + +class _u_bn_relu_conv(nn.Module): + def __init__(self, in_filters, nb_filters, fw, fh, subsample=1): + super(_u_bn_relu_conv, self).__init__() + self.model = nn.Sequential( + nn.BatchNorm2d(in_filters, eps=1e-3), + nn.LeakyReLU(0.2), + nn.Conv2d(in_filters, nb_filters, (fw, fh), stride=subsample, padding=(fw//2, fh//2)), + nn.Upsample(scale_factor=2, mode='nearest') + ) + + def forward(self, x): + return self.model(x) + + + +class _shortcut(nn.Module): + def __init__(self, in_filters, nb_filters, subsample=1): + super(_shortcut, self).__init__() + self.process = False + self.model = None + if in_filters != nb_filters or subsample != 1: + self.process = True + self.model = nn.Sequential( + nn.Conv2d(in_filters, nb_filters, (1, 1), stride=subsample) + ) + + def forward(self, x, y): + #print(x.size(), y.size(), self.process) + if self.process: + y0 = self.model(x) + #print("merge+", torch.max(y0+y), torch.min(y0+y),torch.mean(y0+y), torch.std(y0+y), y0.shape) + return y0 + y + else: + #print("merge", torch.max(x+y), torch.min(x+y),torch.mean(x+y), torch.std(x+y), y.shape) + return x + y + +class _u_shortcut(nn.Module): + def __init__(self, in_filters, nb_filters, subsample): + super(_u_shortcut, self).__init__() + self.process = False + self.model = None + if in_filters != nb_filters: + self.process = True + self.model = nn.Sequential( + nn.Conv2d(in_filters, nb_filters, (1, 1), stride=subsample, padding_mode='zeros'), + nn.Upsample(scale_factor=2, mode='nearest') + ) + + def forward(self, x, y): + if self.process: + return self.model(x) + y + else: + return x + y + + +class basic_block(nn.Module): + def __init__(self, in_filters, nb_filters, init_subsample=1): + super(basic_block, self).__init__() + self.conv1 = _bn_relu_conv(in_filters, nb_filters, 3, 3, subsample=init_subsample) + self.residual = _bn_relu_conv(nb_filters, nb_filters, 3, 3) + self.shortcut = _shortcut(in_filters, nb_filters, subsample=init_subsample) + + def forward(self, x): + x1 = self.conv1(x) + x2 = self.residual(x1) + return self.shortcut(x, x2) + +class _u_basic_block(nn.Module): + def __init__(self, in_filters, nb_filters, init_subsample=1): + super(_u_basic_block, self).__init__() + self.conv1 = _u_bn_relu_conv(in_filters, nb_filters, 3, 3, subsample=init_subsample) + self.residual = _bn_relu_conv(nb_filters, nb_filters, 3, 3) + self.shortcut = _u_shortcut(in_filters, nb_filters, subsample=init_subsample) + + def forward(self, x): + y = self.residual(self.conv1(x)) + return self.shortcut(x, y) + + +class _residual_block(nn.Module): + def __init__(self, in_filters, nb_filters, repetitions, is_first_layer=False): + super(_residual_block, self).__init__() + layers = [] + for i in range(repetitions): + init_subsample = 1 + if i == repetitions - 1 and not is_first_layer: + init_subsample = 2 + if i == 0: + l = basic_block(in_filters=in_filters, nb_filters=nb_filters, init_subsample=init_subsample) + else: + l = basic_block(in_filters=nb_filters, nb_filters=nb_filters, init_subsample=init_subsample) + layers.append(l) + + self.model = nn.Sequential(*layers) + + def forward(self, x): + return self.model(x) + + +class _upsampling_residual_block(nn.Module): + def __init__(self, in_filters, nb_filters, repetitions): + super(_upsampling_residual_block, self).__init__() + layers = [] + for i in range(repetitions): + l = None + if i == 0: + l = _u_basic_block(in_filters=in_filters, nb_filters=nb_filters)#(input) + else: + l = basic_block(in_filters=nb_filters, nb_filters=nb_filters)#(input) + layers.append(l) + + self.model = nn.Sequential(*layers) + + def forward(self, x): + return self.model(x) + + +class res_skip(nn.Module): + + def __init__(self): + super(res_skip, self).__init__() + self.block0 = _residual_block(in_filters=1, nb_filters=24, repetitions=2, is_first_layer=True)#(input) + self.block1 = _residual_block(in_filters=24, nb_filters=48, repetitions=3)#(block0) + self.block2 = _residual_block(in_filters=48, nb_filters=96, repetitions=5)#(block1) + self.block3 = _residual_block(in_filters=96, nb_filters=192, repetitions=7)#(block2) + self.block4 = _residual_block(in_filters=192, nb_filters=384, repetitions=12)#(block3) + + self.block5 = _upsampling_residual_block(in_filters=384, nb_filters=192, repetitions=7)#(block4) + self.res1 = _shortcut(in_filters=192, nb_filters=192)#(block3, block5, subsample=(1,1)) + + self.block6 = _upsampling_residual_block(in_filters=192, nb_filters=96, repetitions=5)#(res1) + self.res2 = _shortcut(in_filters=96, nb_filters=96)#(block2, block6, subsample=(1,1)) + + self.block7 = _upsampling_residual_block(in_filters=96, nb_filters=48, repetitions=3)#(res2) + self.res3 = _shortcut(in_filters=48, nb_filters=48)#(block1, block7, subsample=(1,1)) + + self.block8 = _upsampling_residual_block(in_filters=48, nb_filters=24, repetitions=2)#(res3) + self.res4 = _shortcut(in_filters=24, nb_filters=24)#(block0,block8, subsample=(1,1)) + + self.block9 = _residual_block(in_filters=24, nb_filters=16, repetitions=2, is_first_layer=True)#(res4) + self.conv15 = _bn_relu_conv(in_filters=16, nb_filters=1, fh=1, fw=1, subsample=1)#(block7) + + def forward(self, x): + x0 = self.block0(x) + x1 = self.block1(x0) + x2 = self.block2(x1) + x3 = self.block3(x2) + x4 = self.block4(x3) + + x5 = self.block5(x4) + res1 = self.res1(x3, x5) + + x6 = self.block6(res1) + res2 = self.res2(x2, x6) + + x7 = self.block7(res2) + res3 = self.res3(x1, x7) + + x8 = self.block8(res3) + res4 = self.res4(x0, x8) + + x9 = self.block9(res4) + y = self.conv15(x9) + + return y + + +class MangaLineExtration: + model_dir = os.path.join(models_path, "manga_line") + + def __init__(self): + self.model = None + self.device = devices.get_device_for("controlnet") + + def load_model(self): + remote_model_path = "https://huggingface.co/lllyasviel/Annotators/resolve/main/erika.pth" + modelpath = os.path.join(self.model_dir, "erika.pth") + if not os.path.exists(modelpath): + from basicsr.utils.download_util import load_file_from_url + load_file_from_url(remote_model_path, model_dir=self.model_dir) + #norm_layer = functools.partial(nn.InstanceNorm2d, affine=False, track_running_stats=False) + net = res_skip() + ckpt = torch.load(modelpath) + for key in list(ckpt.keys()): + if 'module.' in key: + ckpt[key.replace('module.', '')] = ckpt[key] + del ckpt[key] + net.load_state_dict(ckpt) + net.eval() + self.model = net.to(self.device) + + def unload_model(self): + if self.model is not None: + self.model.cpu() + + def __call__(self, input_image): + if self.model is None: + self.load_model() + self.model.to(self.device) + img = cv2.cvtColor(input_image, cv2.COLOR_RGB2GRAY) + img = np.ascontiguousarray(img.copy()).copy() + with torch.no_grad(): + image_feed = torch.from_numpy(img).float().to(self.device) + image_feed = rearrange(image_feed, 'h w -> 1 1 h w') + line = self.model(image_feed) + line = 255 - line.cpu().numpy()[0, 0] + return line.clip(0, 255).astype(np.uint8) + + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mediapipe_face/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mediapipe_face/__init__.py new file mode 100644 index 00000000..f74edfb1 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mediapipe_face/__init__.py @@ -0,0 +1,5 @@ +from .mediapipe_face_common import generate_annotation + + +def apply_mediapipe_face(image, max_faces: int = 1, min_confidence: float = 0.5): + return generate_annotation(image, max_faces, min_confidence) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mediapipe_face/mediapipe_face_common.py b/extensions-builtin/sd_forge_controlnet/annotator/mediapipe_face/mediapipe_face_common.py new file mode 100644 index 00000000..0f7d3701 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mediapipe_face/mediapipe_face_common.py @@ -0,0 +1,155 @@ +from typing import Mapping + +import mediapipe as mp +import numpy + + +mp_drawing = mp.solutions.drawing_utils +mp_drawing_styles = mp.solutions.drawing_styles +mp_face_detection = mp.solutions.face_detection # Only for counting faces. +mp_face_mesh = mp.solutions.face_mesh +mp_face_connections = mp.solutions.face_mesh_connections.FACEMESH_TESSELATION +mp_hand_connections = mp.solutions.hands_connections.HAND_CONNECTIONS +mp_body_connections = mp.solutions.pose_connections.POSE_CONNECTIONS + +DrawingSpec = mp.solutions.drawing_styles.DrawingSpec +PoseLandmark = mp.solutions.drawing_styles.PoseLandmark + +min_face_size_pixels: int = 64 +f_thick = 2 +f_rad = 1 +right_iris_draw = DrawingSpec(color=(10, 200, 250), thickness=f_thick, circle_radius=f_rad) +right_eye_draw = DrawingSpec(color=(10, 200, 180), thickness=f_thick, circle_radius=f_rad) +right_eyebrow_draw = DrawingSpec(color=(10, 220, 180), thickness=f_thick, circle_radius=f_rad) +left_iris_draw = DrawingSpec(color=(250, 200, 10), thickness=f_thick, circle_radius=f_rad) +left_eye_draw = DrawingSpec(color=(180, 200, 10), thickness=f_thick, circle_radius=f_rad) +left_eyebrow_draw = DrawingSpec(color=(180, 220, 10), thickness=f_thick, circle_radius=f_rad) +mouth_draw = DrawingSpec(color=(10, 180, 10), thickness=f_thick, circle_radius=f_rad) +head_draw = DrawingSpec(color=(10, 200, 10), thickness=f_thick, circle_radius=f_rad) + +# mp_face_mesh.FACEMESH_CONTOURS has all the items we care about. +face_connection_spec = {} +for edge in mp_face_mesh.FACEMESH_FACE_OVAL: + face_connection_spec[edge] = head_draw +for edge in mp_face_mesh.FACEMESH_LEFT_EYE: + face_connection_spec[edge] = left_eye_draw +for edge in mp_face_mesh.FACEMESH_LEFT_EYEBROW: + face_connection_spec[edge] = left_eyebrow_draw +# for edge in mp_face_mesh.FACEMESH_LEFT_IRIS: +# face_connection_spec[edge] = left_iris_draw +for edge in mp_face_mesh.FACEMESH_RIGHT_EYE: + face_connection_spec[edge] = right_eye_draw +for edge in mp_face_mesh.FACEMESH_RIGHT_EYEBROW: + face_connection_spec[edge] = right_eyebrow_draw +# for edge in mp_face_mesh.FACEMESH_RIGHT_IRIS: +# face_connection_spec[edge] = right_iris_draw +for edge in mp_face_mesh.FACEMESH_LIPS: + face_connection_spec[edge] = mouth_draw +iris_landmark_spec = {468: right_iris_draw, 473: left_iris_draw} + + +def draw_pupils(image, landmark_list, drawing_spec, halfwidth: int = 2): + """We have a custom function to draw the pupils because the mp.draw_landmarks method requires a parameter for all + landmarks. Until our PR is merged into mediapipe, we need this separate method.""" + if len(image.shape) != 3: + raise ValueError("Input image must be H,W,C.") + image_rows, image_cols, image_channels = image.shape + if image_channels != 3: # BGR channels + raise ValueError('Input image must contain three channel bgr data.') + for idx, landmark in enumerate(landmark_list.landmark): + if ( + (landmark.HasField('visibility') and landmark.visibility < 0.9) or + (landmark.HasField('presence') and landmark.presence < 0.5) + ): + continue + if landmark.x >= 1.0 or landmark.x < 0 or landmark.y >= 1.0 or landmark.y < 0: + continue + image_x = int(image_cols*landmark.x) + image_y = int(image_rows*landmark.y) + draw_color = None + if isinstance(drawing_spec, Mapping): + if drawing_spec.get(idx) is None: + continue + else: + draw_color = drawing_spec[idx].color + elif isinstance(drawing_spec, DrawingSpec): + draw_color = drawing_spec.color + image[image_y-halfwidth:image_y+halfwidth, image_x-halfwidth:image_x+halfwidth, :] = draw_color + + +def reverse_channels(image): + """Given a numpy array in RGB form, convert to BGR. Will also convert from BGR to RGB.""" + # im[:,:,::-1] is a neat hack to convert BGR to RGB by reversing the indexing order. + # im[:,:,::[2,1,0]] would also work but makes a copy of the data. + return image[:, :, ::-1] + + +def generate_annotation( + img_rgb, + max_faces: int, + min_confidence: float +): + """ + Find up to 'max_faces' inside the provided input image. + If min_face_size_pixels is provided and nonzero it will be used to filter faces that occupy less than this many + pixels in the image. + """ + with mp_face_mesh.FaceMesh( + static_image_mode=True, + max_num_faces=max_faces, + refine_landmarks=True, + min_detection_confidence=min_confidence, + ) as facemesh: + img_height, img_width, img_channels = img_rgb.shape + assert(img_channels == 3) + + results = facemesh.process(img_rgb).multi_face_landmarks + + if results is None: + print("No faces detected in controlnet image for Mediapipe face annotator.") + return numpy.zeros_like(img_rgb) + + # Filter faces that are too small + filtered_landmarks = [] + for lm in results: + landmarks = lm.landmark + face_rect = [ + landmarks[0].x, + landmarks[0].y, + landmarks[0].x, + landmarks[0].y, + ] # Left, up, right, down. + for i in range(len(landmarks)): + face_rect[0] = min(face_rect[0], landmarks[i].x) + face_rect[1] = min(face_rect[1], landmarks[i].y) + face_rect[2] = max(face_rect[2], landmarks[i].x) + face_rect[3] = max(face_rect[3], landmarks[i].y) + if min_face_size_pixels > 0: + face_width = abs(face_rect[2] - face_rect[0]) + face_height = abs(face_rect[3] - face_rect[1]) + face_width_pixels = face_width * img_width + face_height_pixels = face_height * img_height + face_size = min(face_width_pixels, face_height_pixels) + if face_size >= min_face_size_pixels: + filtered_landmarks.append(lm) + else: + filtered_landmarks.append(lm) + + # Annotations are drawn in BGR for some reason, but we don't need to flip a zero-filled image at the start. + empty = numpy.zeros_like(img_rgb) + + # Draw detected faces: + for face_landmarks in filtered_landmarks: + mp_drawing.draw_landmarks( + empty, + face_landmarks, + connections=face_connection_spec.keys(), + landmark_drawing_spec=None, + connection_drawing_spec=face_connection_spec + ) + draw_pupils(empty, face_landmarks, iris_landmark_spec, 2) + + # Flip BGR back to RGB. + empty = reverse_channels(empty).copy() + + return empty diff --git a/extensions-builtin/sd_forge_controlnet/annotator/midas/LICENSE b/extensions-builtin/sd_forge_controlnet/annotator/midas/LICENSE new file mode 100644 index 00000000..277b5c11 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/midas/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Intel ISL (Intel Intelligent Systems Lab) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/extensions-builtin/sd_forge_controlnet/annotator/midas/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/midas/__init__.py new file mode 100644 index 00000000..dc247615 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/midas/__init__.py @@ -0,0 +1,49 @@ +import cv2 +import numpy as np +import torch + +from einops import rearrange +from .api import MiDaSInference +from modules import devices + +model = None + +def unload_midas_model(): + global model + if model is not None: + model = model.cpu() + +def apply_midas(input_image, a=np.pi * 2.0, bg_th=0.1): + global model + if model is None: + model = MiDaSInference(model_type="dpt_hybrid") + if devices.get_device_for("controlnet").type != 'mps': + model = model.to(devices.get_device_for("controlnet")) + + assert input_image.ndim == 3 + image_depth = input_image + with torch.no_grad(): + image_depth = torch.from_numpy(image_depth).float() + if devices.get_device_for("controlnet").type != 'mps': + image_depth = image_depth.to(devices.get_device_for("controlnet")) + image_depth = image_depth / 127.5 - 1.0 + image_depth = rearrange(image_depth, 'h w c -> 1 c h w') + depth = model(image_depth)[0] + + depth_pt = depth.clone() + depth_pt -= torch.min(depth_pt) + depth_pt /= torch.max(depth_pt) + depth_pt = depth_pt.cpu().numpy() + depth_image = (depth_pt * 255.0).clip(0, 255).astype(np.uint8) + + depth_np = depth.cpu().numpy() + x = cv2.Sobel(depth_np, cv2.CV_32F, 1, 0, ksize=3) + y = cv2.Sobel(depth_np, cv2.CV_32F, 0, 1, ksize=3) + z = np.ones_like(x) * a + x[depth_pt < bg_th] = 0 + y[depth_pt < bg_th] = 0 + normal = np.stack([x, y, z], axis=2) + normal /= np.sum(normal ** 2.0, axis=2, keepdims=True) ** 0.5 + normal_image = (normal * 127.5 + 127.5).clip(0, 255).astype(np.uint8)[:, :, ::-1] + + return depth_image, normal_image diff --git a/extensions-builtin/sd_forge_controlnet/annotator/midas/api.py b/extensions-builtin/sd_forge_controlnet/annotator/midas/api.py new file mode 100644 index 00000000..72870381 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/midas/api.py @@ -0,0 +1,181 @@ +# based on https://github.com/isl-org/MiDaS + +import cv2 +import torch +import torch.nn as nn +import os +from annotator.annotator_path import models_path + +from torchvision.transforms import Compose + +from .midas.dpt_depth import DPTDepthModel +from .midas.midas_net import MidasNet +from .midas.midas_net_custom import MidasNet_small +from .midas.transforms import Resize, NormalizeImage, PrepareForNet + +base_model_path = os.path.join(models_path, "midas") +old_modeldir = os.path.dirname(os.path.realpath(__file__)) +remote_model_path = "https://huggingface.co/lllyasviel/ControlNet/resolve/main/annotator/ckpts/dpt_hybrid-midas-501f0c75.pt" + +ISL_PATHS = { + "dpt_large": os.path.join(base_model_path, "dpt_large-midas-2f21e586.pt"), + "dpt_hybrid": os.path.join(base_model_path, "dpt_hybrid-midas-501f0c75.pt"), + "midas_v21": "", + "midas_v21_small": "", +} + +OLD_ISL_PATHS = { + "dpt_large": os.path.join(old_modeldir, "dpt_large-midas-2f21e586.pt"), + "dpt_hybrid": os.path.join(old_modeldir, "dpt_hybrid-midas-501f0c75.pt"), + "midas_v21": "", + "midas_v21_small": "", +} + + +def disabled_train(self, mode=True): + """Overwrite model.train with this function to make sure train/eval mode + does not change anymore.""" + return self + + +def load_midas_transform(model_type): + # https://github.com/isl-org/MiDaS/blob/master/run.py + # load transform only + if model_type == "dpt_large": # DPT-Large + net_w, net_h = 384, 384 + resize_mode = "minimal" + normalization = NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) + + elif model_type == "dpt_hybrid": # DPT-Hybrid + net_w, net_h = 384, 384 + resize_mode = "minimal" + normalization = NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) + + elif model_type == "midas_v21": + net_w, net_h = 384, 384 + resize_mode = "upper_bound" + normalization = NormalizeImage(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) + + elif model_type == "midas_v21_small": + net_w, net_h = 256, 256 + resize_mode = "upper_bound" + normalization = NormalizeImage(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) + + else: + assert False, f"model_type '{model_type}' not implemented, use: --model_type large" + + transform = Compose( + [ + Resize( + net_w, + net_h, + resize_target=None, + keep_aspect_ratio=True, + ensure_multiple_of=32, + resize_method=resize_mode, + image_interpolation_method=cv2.INTER_CUBIC, + ), + normalization, + PrepareForNet(), + ] + ) + + return transform + + +def load_model(model_type): + # https://github.com/isl-org/MiDaS/blob/master/run.py + # load network + model_path = ISL_PATHS[model_type] + old_model_path = OLD_ISL_PATHS[model_type] + if model_type == "dpt_large": # DPT-Large + model = DPTDepthModel( + path=model_path, + backbone="vitl16_384", + non_negative=True, + ) + net_w, net_h = 384, 384 + resize_mode = "minimal" + normalization = NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) + + elif model_type == "dpt_hybrid": # DPT-Hybrid + if os.path.exists(old_model_path): + model_path = old_model_path + elif not os.path.exists(model_path): + from basicsr.utils.download_util import load_file_from_url + load_file_from_url(remote_model_path, model_dir=base_model_path) + + model = DPTDepthModel( + path=model_path, + backbone="vitb_rn50_384", + non_negative=True, + ) + net_w, net_h = 384, 384 + resize_mode = "minimal" + normalization = NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) + + elif model_type == "midas_v21": + model = MidasNet(model_path, non_negative=True) + net_w, net_h = 384, 384 + resize_mode = "upper_bound" + normalization = NormalizeImage( + mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225] + ) + + elif model_type == "midas_v21_small": + model = MidasNet_small(model_path, features=64, backbone="efficientnet_lite3", exportable=True, + non_negative=True, blocks={'expand': True}) + net_w, net_h = 256, 256 + resize_mode = "upper_bound" + normalization = NormalizeImage( + mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225] + ) + + else: + print(f"model_type '{model_type}' not implemented, use: --model_type large") + assert False + + transform = Compose( + [ + Resize( + net_w, + net_h, + resize_target=None, + keep_aspect_ratio=True, + ensure_multiple_of=32, + resize_method=resize_mode, + image_interpolation_method=cv2.INTER_CUBIC, + ), + normalization, + PrepareForNet(), + ] + ) + + return model.eval(), transform + + +class MiDaSInference(nn.Module): + MODEL_TYPES_TORCH_HUB = [ + "DPT_Large", + "DPT_Hybrid", + "MiDaS_small" + ] + MODEL_TYPES_ISL = [ + "dpt_large", + "dpt_hybrid", + "midas_v21", + "midas_v21_small", + ] + + def __init__(self, model_type): + super().__init__() + assert (model_type in self.MODEL_TYPES_ISL) + model, _ = load_model(model_type) + self.model = model + self.model.train = disabled_train + + def forward(self, x): + with torch.no_grad(): + prediction = self.model(x) + return prediction + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/base_model.py b/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/base_model.py new file mode 100644 index 00000000..5cf43023 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/base_model.py @@ -0,0 +1,16 @@ +import torch + + +class BaseModel(torch.nn.Module): + def load(self, path): + """Load model from file. + + Args: + path (str): file path + """ + parameters = torch.load(path, map_location=torch.device('cpu')) + + if "optimizer" in parameters: + parameters = parameters["model"] + + self.load_state_dict(parameters) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/blocks.py b/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/blocks.py new file mode 100644 index 00000000..2145d18f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/blocks.py @@ -0,0 +1,342 @@ +import torch +import torch.nn as nn + +from .vit import ( + _make_pretrained_vitb_rn50_384, + _make_pretrained_vitl16_384, + _make_pretrained_vitb16_384, + forward_vit, +) + +def _make_encoder(backbone, features, use_pretrained, groups=1, expand=False, exportable=True, hooks=None, use_vit_only=False, use_readout="ignore",): + if backbone == "vitl16_384": + pretrained = _make_pretrained_vitl16_384( + use_pretrained, hooks=hooks, use_readout=use_readout + ) + scratch = _make_scratch( + [256, 512, 1024, 1024], features, groups=groups, expand=expand + ) # ViT-L/16 - 85.0% Top1 (backbone) + elif backbone == "vitb_rn50_384": + pretrained = _make_pretrained_vitb_rn50_384( + use_pretrained, + hooks=hooks, + use_vit_only=use_vit_only, + use_readout=use_readout, + ) + scratch = _make_scratch( + [256, 512, 768, 768], features, groups=groups, expand=expand + ) # ViT-H/16 - 85.0% Top1 (backbone) + elif backbone == "vitb16_384": + pretrained = _make_pretrained_vitb16_384( + use_pretrained, hooks=hooks, use_readout=use_readout + ) + scratch = _make_scratch( + [96, 192, 384, 768], features, groups=groups, expand=expand + ) # ViT-B/16 - 84.6% Top1 (backbone) + elif backbone == "resnext101_wsl": + pretrained = _make_pretrained_resnext101_wsl(use_pretrained) + scratch = _make_scratch([256, 512, 1024, 2048], features, groups=groups, expand=expand) # efficientnet_lite3 + elif backbone == "efficientnet_lite3": + pretrained = _make_pretrained_efficientnet_lite3(use_pretrained, exportable=exportable) + scratch = _make_scratch([32, 48, 136, 384], features, groups=groups, expand=expand) # efficientnet_lite3 + else: + print(f"Backbone '{backbone}' not implemented") + assert False + + return pretrained, scratch + + +def _make_scratch(in_shape, out_shape, groups=1, expand=False): + scratch = nn.Module() + + out_shape1 = out_shape + out_shape2 = out_shape + out_shape3 = out_shape + out_shape4 = out_shape + if expand==True: + out_shape1 = out_shape + out_shape2 = out_shape*2 + out_shape3 = out_shape*4 + out_shape4 = out_shape*8 + + scratch.layer1_rn = nn.Conv2d( + in_shape[0], out_shape1, kernel_size=3, stride=1, padding=1, bias=False, groups=groups + ) + scratch.layer2_rn = nn.Conv2d( + in_shape[1], out_shape2, kernel_size=3, stride=1, padding=1, bias=False, groups=groups + ) + scratch.layer3_rn = nn.Conv2d( + in_shape[2], out_shape3, kernel_size=3, stride=1, padding=1, bias=False, groups=groups + ) + scratch.layer4_rn = nn.Conv2d( + in_shape[3], out_shape4, kernel_size=3, stride=1, padding=1, bias=False, groups=groups + ) + + return scratch + + +def _make_pretrained_efficientnet_lite3(use_pretrained, exportable=False): + efficientnet = torch.hub.load( + "rwightman/gen-efficientnet-pytorch", + "tf_efficientnet_lite3", + pretrained=use_pretrained, + exportable=exportable + ) + return _make_efficientnet_backbone(efficientnet) + + +def _make_efficientnet_backbone(effnet): + pretrained = nn.Module() + + pretrained.layer1 = nn.Sequential( + effnet.conv_stem, effnet.bn1, effnet.act1, *effnet.blocks[0:2] + ) + pretrained.layer2 = nn.Sequential(*effnet.blocks[2:3]) + pretrained.layer3 = nn.Sequential(*effnet.blocks[3:5]) + pretrained.layer4 = nn.Sequential(*effnet.blocks[5:9]) + + return pretrained + + +def _make_resnet_backbone(resnet): + pretrained = nn.Module() + pretrained.layer1 = nn.Sequential( + resnet.conv1, resnet.bn1, resnet.relu, resnet.maxpool, resnet.layer1 + ) + + pretrained.layer2 = resnet.layer2 + pretrained.layer3 = resnet.layer3 + pretrained.layer4 = resnet.layer4 + + return pretrained + + +def _make_pretrained_resnext101_wsl(use_pretrained): + resnet = torch.hub.load("facebookresearch/WSL-Images", "resnext101_32x8d_wsl") + return _make_resnet_backbone(resnet) + + + +class Interpolate(nn.Module): + """Interpolation module. + """ + + def __init__(self, scale_factor, mode, align_corners=False): + """Init. + + Args: + scale_factor (float): scaling + mode (str): interpolation mode + """ + super(Interpolate, self).__init__() + + self.interp = nn.functional.interpolate + self.scale_factor = scale_factor + self.mode = mode + self.align_corners = align_corners + + def forward(self, x): + """Forward pass. + + Args: + x (tensor): input + + Returns: + tensor: interpolated data + """ + + x = self.interp( + x, scale_factor=self.scale_factor, mode=self.mode, align_corners=self.align_corners + ) + + return x + + +class ResidualConvUnit(nn.Module): + """Residual convolution module. + """ + + def __init__(self, features): + """Init. + + Args: + features (int): number of features + """ + super().__init__() + + self.conv1 = nn.Conv2d( + features, features, kernel_size=3, stride=1, padding=1, bias=True + ) + + self.conv2 = nn.Conv2d( + features, features, kernel_size=3, stride=1, padding=1, bias=True + ) + + self.relu = nn.ReLU(inplace=True) + + def forward(self, x): + """Forward pass. + + Args: + x (tensor): input + + Returns: + tensor: output + """ + out = self.relu(x) + out = self.conv1(out) + out = self.relu(out) + out = self.conv2(out) + + return out + x + + +class FeatureFusionBlock(nn.Module): + """Feature fusion block. + """ + + def __init__(self, features): + """Init. + + Args: + features (int): number of features + """ + super(FeatureFusionBlock, self).__init__() + + self.resConfUnit1 = ResidualConvUnit(features) + self.resConfUnit2 = ResidualConvUnit(features) + + def forward(self, *xs): + """Forward pass. + + Returns: + tensor: output + """ + output = xs[0] + + if len(xs) == 2: + output += self.resConfUnit1(xs[1]) + + output = self.resConfUnit2(output) + + output = nn.functional.interpolate( + output, scale_factor=2, mode="bilinear", align_corners=True + ) + + return output + + + + +class ResidualConvUnit_custom(nn.Module): + """Residual convolution module. + """ + + def __init__(self, features, activation, bn): + """Init. + + Args: + features (int): number of features + """ + super().__init__() + + self.bn = bn + + self.groups=1 + + self.conv1 = nn.Conv2d( + features, features, kernel_size=3, stride=1, padding=1, bias=True, groups=self.groups + ) + + self.conv2 = nn.Conv2d( + features, features, kernel_size=3, stride=1, padding=1, bias=True, groups=self.groups + ) + + if self.bn==True: + self.bn1 = nn.BatchNorm2d(features) + self.bn2 = nn.BatchNorm2d(features) + + self.activation = activation + + self.skip_add = nn.quantized.FloatFunctional() + + def forward(self, x): + """Forward pass. + + Args: + x (tensor): input + + Returns: + tensor: output + """ + + out = self.activation(x) + out = self.conv1(out) + if self.bn==True: + out = self.bn1(out) + + out = self.activation(out) + out = self.conv2(out) + if self.bn==True: + out = self.bn2(out) + + if self.groups > 1: + out = self.conv_merge(out) + + return self.skip_add.add(out, x) + + # return out + x + + +class FeatureFusionBlock_custom(nn.Module): + """Feature fusion block. + """ + + def __init__(self, features, activation, deconv=False, bn=False, expand=False, align_corners=True): + """Init. + + Args: + features (int): number of features + """ + super(FeatureFusionBlock_custom, self).__init__() + + self.deconv = deconv + self.align_corners = align_corners + + self.groups=1 + + self.expand = expand + out_features = features + if self.expand==True: + out_features = features//2 + + self.out_conv = nn.Conv2d(features, out_features, kernel_size=1, stride=1, padding=0, bias=True, groups=1) + + self.resConfUnit1 = ResidualConvUnit_custom(features, activation, bn) + self.resConfUnit2 = ResidualConvUnit_custom(features, activation, bn) + + self.skip_add = nn.quantized.FloatFunctional() + + def forward(self, *xs): + """Forward pass. + + Returns: + tensor: output + """ + output = xs[0] + + if len(xs) == 2: + res = self.resConfUnit1(xs[1]) + output = self.skip_add.add(output, res) + # output += res + + output = self.resConfUnit2(output) + + output = nn.functional.interpolate( + output, scale_factor=2, mode="bilinear", align_corners=self.align_corners + ) + + output = self.out_conv(output) + + return output + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/dpt_depth.py b/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/dpt_depth.py new file mode 100644 index 00000000..4e9aab5d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/dpt_depth.py @@ -0,0 +1,109 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F + +from .base_model import BaseModel +from .blocks import ( + FeatureFusionBlock, + FeatureFusionBlock_custom, + Interpolate, + _make_encoder, + forward_vit, +) + + +def _make_fusion_block(features, use_bn): + return FeatureFusionBlock_custom( + features, + nn.ReLU(False), + deconv=False, + bn=use_bn, + expand=False, + align_corners=True, + ) + + +class DPT(BaseModel): + def __init__( + self, + head, + features=256, + backbone="vitb_rn50_384", + readout="project", + channels_last=False, + use_bn=False, + ): + + super(DPT, self).__init__() + + self.channels_last = channels_last + + hooks = { + "vitb_rn50_384": [0, 1, 8, 11], + "vitb16_384": [2, 5, 8, 11], + "vitl16_384": [5, 11, 17, 23], + } + + # Instantiate backbone and reassemble blocks + self.pretrained, self.scratch = _make_encoder( + backbone, + features, + False, # Set to true of you want to train from scratch, uses ImageNet weights + groups=1, + expand=False, + exportable=False, + hooks=hooks[backbone], + use_readout=readout, + ) + + self.scratch.refinenet1 = _make_fusion_block(features, use_bn) + self.scratch.refinenet2 = _make_fusion_block(features, use_bn) + self.scratch.refinenet3 = _make_fusion_block(features, use_bn) + self.scratch.refinenet4 = _make_fusion_block(features, use_bn) + + self.scratch.output_conv = head + + + def forward(self, x): + if self.channels_last == True: + x.contiguous(memory_format=torch.channels_last) + + layer_1, layer_2, layer_3, layer_4 = forward_vit(self.pretrained, x) + + layer_1_rn = self.scratch.layer1_rn(layer_1) + layer_2_rn = self.scratch.layer2_rn(layer_2) + layer_3_rn = self.scratch.layer3_rn(layer_3) + layer_4_rn = self.scratch.layer4_rn(layer_4) + + path_4 = self.scratch.refinenet4(layer_4_rn) + path_3 = self.scratch.refinenet3(path_4, layer_3_rn) + path_2 = self.scratch.refinenet2(path_3, layer_2_rn) + path_1 = self.scratch.refinenet1(path_2, layer_1_rn) + + out = self.scratch.output_conv(path_1) + + return out + + +class DPTDepthModel(DPT): + def __init__(self, path=None, non_negative=True, **kwargs): + features = kwargs["features"] if "features" in kwargs else 256 + + head = nn.Sequential( + nn.Conv2d(features, features // 2, kernel_size=3, stride=1, padding=1), + Interpolate(scale_factor=2, mode="bilinear", align_corners=True), + nn.Conv2d(features // 2, 32, kernel_size=3, stride=1, padding=1), + nn.ReLU(True), + nn.Conv2d(32, 1, kernel_size=1, stride=1, padding=0), + nn.ReLU(True) if non_negative else nn.Identity(), + nn.Identity(), + ) + + super().__init__(head, **kwargs) + + if path is not None: + self.load(path) + + def forward(self, x): + return super().forward(x).squeeze(dim=1) + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/midas_net.py b/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/midas_net.py new file mode 100644 index 00000000..8a954977 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/midas_net.py @@ -0,0 +1,76 @@ +"""MidashNet: Network for monocular depth estimation trained by mixing several datasets. +This file contains code that is adapted from +https://github.com/thomasjpfan/pytorch_refinenet/blob/master/pytorch_refinenet/refinenet/refinenet_4cascade.py +""" +import torch +import torch.nn as nn + +from .base_model import BaseModel +from .blocks import FeatureFusionBlock, Interpolate, _make_encoder + + +class MidasNet(BaseModel): + """Network for monocular depth estimation. + """ + + def __init__(self, path=None, features=256, non_negative=True): + """Init. + + Args: + path (str, optional): Path to saved model. Defaults to None. + features (int, optional): Number of features. Defaults to 256. + backbone (str, optional): Backbone network for encoder. Defaults to resnet50 + """ + print("Loading weights: ", path) + + super(MidasNet, self).__init__() + + use_pretrained = False if path is None else True + + self.pretrained, self.scratch = _make_encoder(backbone="resnext101_wsl", features=features, use_pretrained=use_pretrained) + + self.scratch.refinenet4 = FeatureFusionBlock(features) + self.scratch.refinenet3 = FeatureFusionBlock(features) + self.scratch.refinenet2 = FeatureFusionBlock(features) + self.scratch.refinenet1 = FeatureFusionBlock(features) + + self.scratch.output_conv = nn.Sequential( + nn.Conv2d(features, 128, kernel_size=3, stride=1, padding=1), + Interpolate(scale_factor=2, mode="bilinear"), + nn.Conv2d(128, 32, kernel_size=3, stride=1, padding=1), + nn.ReLU(True), + nn.Conv2d(32, 1, kernel_size=1, stride=1, padding=0), + nn.ReLU(True) if non_negative else nn.Identity(), + ) + + if path: + self.load(path) + + def forward(self, x): + """Forward pass. + + Args: + x (tensor): input data (image) + + Returns: + tensor: depth + """ + + layer_1 = self.pretrained.layer1(x) + layer_2 = self.pretrained.layer2(layer_1) + layer_3 = self.pretrained.layer3(layer_2) + layer_4 = self.pretrained.layer4(layer_3) + + layer_1_rn = self.scratch.layer1_rn(layer_1) + layer_2_rn = self.scratch.layer2_rn(layer_2) + layer_3_rn = self.scratch.layer3_rn(layer_3) + layer_4_rn = self.scratch.layer4_rn(layer_4) + + path_4 = self.scratch.refinenet4(layer_4_rn) + path_3 = self.scratch.refinenet3(path_4, layer_3_rn) + path_2 = self.scratch.refinenet2(path_3, layer_2_rn) + path_1 = self.scratch.refinenet1(path_2, layer_1_rn) + + out = self.scratch.output_conv(path_1) + + return torch.squeeze(out, dim=1) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/midas_net_custom.py b/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/midas_net_custom.py new file mode 100644 index 00000000..50e4acb5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/midas_net_custom.py @@ -0,0 +1,128 @@ +"""MidashNet: Network for monocular depth estimation trained by mixing several datasets. +This file contains code that is adapted from +https://github.com/thomasjpfan/pytorch_refinenet/blob/master/pytorch_refinenet/refinenet/refinenet_4cascade.py +""" +import torch +import torch.nn as nn + +from .base_model import BaseModel +from .blocks import FeatureFusionBlock, FeatureFusionBlock_custom, Interpolate, _make_encoder + + +class MidasNet_small(BaseModel): + """Network for monocular depth estimation. + """ + + def __init__(self, path=None, features=64, backbone="efficientnet_lite3", non_negative=True, exportable=True, channels_last=False, align_corners=True, + blocks={'expand': True}): + """Init. + + Args: + path (str, optional): Path to saved model. Defaults to None. + features (int, optional): Number of features. Defaults to 256. + backbone (str, optional): Backbone network for encoder. Defaults to resnet50 + """ + print("Loading weights: ", path) + + super(MidasNet_small, self).__init__() + + use_pretrained = False if path else True + + self.channels_last = channels_last + self.blocks = blocks + self.backbone = backbone + + self.groups = 1 + + features1=features + features2=features + features3=features + features4=features + self.expand = False + if "expand" in self.blocks and self.blocks['expand'] == True: + self.expand = True + features1=features + features2=features*2 + features3=features*4 + features4=features*8 + + self.pretrained, self.scratch = _make_encoder(self.backbone, features, use_pretrained, groups=self.groups, expand=self.expand, exportable=exportable) + + self.scratch.activation = nn.ReLU(False) + + self.scratch.refinenet4 = FeatureFusionBlock_custom(features4, self.scratch.activation, deconv=False, bn=False, expand=self.expand, align_corners=align_corners) + self.scratch.refinenet3 = FeatureFusionBlock_custom(features3, self.scratch.activation, deconv=False, bn=False, expand=self.expand, align_corners=align_corners) + self.scratch.refinenet2 = FeatureFusionBlock_custom(features2, self.scratch.activation, deconv=False, bn=False, expand=self.expand, align_corners=align_corners) + self.scratch.refinenet1 = FeatureFusionBlock_custom(features1, self.scratch.activation, deconv=False, bn=False, align_corners=align_corners) + + + self.scratch.output_conv = nn.Sequential( + nn.Conv2d(features, features//2, kernel_size=3, stride=1, padding=1, groups=self.groups), + Interpolate(scale_factor=2, mode="bilinear"), + nn.Conv2d(features//2, 32, kernel_size=3, stride=1, padding=1), + self.scratch.activation, + nn.Conv2d(32, 1, kernel_size=1, stride=1, padding=0), + nn.ReLU(True) if non_negative else nn.Identity(), + nn.Identity(), + ) + + if path: + self.load(path) + + + def forward(self, x): + """Forward pass. + + Args: + x (tensor): input data (image) + + Returns: + tensor: depth + """ + if self.channels_last==True: + print("self.channels_last = ", self.channels_last) + x.contiguous(memory_format=torch.channels_last) + + + layer_1 = self.pretrained.layer1(x) + layer_2 = self.pretrained.layer2(layer_1) + layer_3 = self.pretrained.layer3(layer_2) + layer_4 = self.pretrained.layer4(layer_3) + + layer_1_rn = self.scratch.layer1_rn(layer_1) + layer_2_rn = self.scratch.layer2_rn(layer_2) + layer_3_rn = self.scratch.layer3_rn(layer_3) + layer_4_rn = self.scratch.layer4_rn(layer_4) + + + path_4 = self.scratch.refinenet4(layer_4_rn) + path_3 = self.scratch.refinenet3(path_4, layer_3_rn) + path_2 = self.scratch.refinenet2(path_3, layer_2_rn) + path_1 = self.scratch.refinenet1(path_2, layer_1_rn) + + out = self.scratch.output_conv(path_1) + + return torch.squeeze(out, dim=1) + + + +def fuse_model(m): + prev_previous_type = nn.Identity() + prev_previous_name = '' + previous_type = nn.Identity() + previous_name = '' + for name, module in m.named_modules(): + if prev_previous_type == nn.Conv2d and previous_type == nn.BatchNorm2d and type(module) == nn.ReLU: + # print("FUSED ", prev_previous_name, previous_name, name) + torch.quantization.fuse_modules(m, [prev_previous_name, previous_name, name], inplace=True) + elif prev_previous_type == nn.Conv2d and previous_type == nn.BatchNorm2d: + # print("FUSED ", prev_previous_name, previous_name) + torch.quantization.fuse_modules(m, [prev_previous_name, previous_name], inplace=True) + # elif previous_type == nn.Conv2d and type(module) == nn.ReLU: + # print("FUSED ", previous_name, name) + # torch.quantization.fuse_modules(m, [previous_name, name], inplace=True) + + prev_previous_type = previous_type + prev_previous_name = previous_name + previous_type = type(module) + previous_name = name \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/transforms.py b/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/transforms.py new file mode 100644 index 00000000..350cbc11 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/transforms.py @@ -0,0 +1,234 @@ +import numpy as np +import cv2 +import math + + +def apply_min_size(sample, size, image_interpolation_method=cv2.INTER_AREA): + """Rezise the sample to ensure the given size. Keeps aspect ratio. + + Args: + sample (dict): sample + size (tuple): image size + + Returns: + tuple: new size + """ + shape = list(sample["disparity"].shape) + + if shape[0] >= size[0] and shape[1] >= size[1]: + return sample + + scale = [0, 0] + scale[0] = size[0] / shape[0] + scale[1] = size[1] / shape[1] + + scale = max(scale) + + shape[0] = math.ceil(scale * shape[0]) + shape[1] = math.ceil(scale * shape[1]) + + # resize + sample["image"] = cv2.resize( + sample["image"], tuple(shape[::-1]), interpolation=image_interpolation_method + ) + + sample["disparity"] = cv2.resize( + sample["disparity"], tuple(shape[::-1]), interpolation=cv2.INTER_NEAREST + ) + sample["mask"] = cv2.resize( + sample["mask"].astype(np.float32), + tuple(shape[::-1]), + interpolation=cv2.INTER_NEAREST, + ) + sample["mask"] = sample["mask"].astype(bool) + + return tuple(shape) + + +class Resize(object): + """Resize sample to given size (width, height). + """ + + def __init__( + self, + width, + height, + resize_target=True, + keep_aspect_ratio=False, + ensure_multiple_of=1, + resize_method="lower_bound", + image_interpolation_method=cv2.INTER_AREA, + ): + """Init. + + Args: + width (int): desired output width + height (int): desired output height + resize_target (bool, optional): + True: Resize the full sample (image, mask, target). + False: Resize image only. + Defaults to True. + keep_aspect_ratio (bool, optional): + True: Keep the aspect ratio of the input sample. + Output sample might not have the given width and height, and + resize behaviour depends on the parameter 'resize_method'. + Defaults to False. + ensure_multiple_of (int, optional): + Output width and height is constrained to be multiple of this parameter. + Defaults to 1. + resize_method (str, optional): + "lower_bound": Output will be at least as large as the given size. + "upper_bound": Output will be at max as large as the given size. (Output size might be smaller than given size.) + "minimal": Scale as least as possible. (Output size might be smaller than given size.) + Defaults to "lower_bound". + """ + self.__width = width + self.__height = height + + self.__resize_target = resize_target + self.__keep_aspect_ratio = keep_aspect_ratio + self.__multiple_of = ensure_multiple_of + self.__resize_method = resize_method + self.__image_interpolation_method = image_interpolation_method + + def constrain_to_multiple_of(self, x, min_val=0, max_val=None): + y = (np.round(x / self.__multiple_of) * self.__multiple_of).astype(int) + + if max_val is not None and y > max_val: + y = (np.floor(x / self.__multiple_of) * self.__multiple_of).astype(int) + + if y < min_val: + y = (np.ceil(x / self.__multiple_of) * self.__multiple_of).astype(int) + + return y + + def get_size(self, width, height): + # determine new height and width + scale_height = self.__height / height + scale_width = self.__width / width + + if self.__keep_aspect_ratio: + if self.__resize_method == "lower_bound": + # scale such that output size is lower bound + if scale_width > scale_height: + # fit width + scale_height = scale_width + else: + # fit height + scale_width = scale_height + elif self.__resize_method == "upper_bound": + # scale such that output size is upper bound + if scale_width < scale_height: + # fit width + scale_height = scale_width + else: + # fit height + scale_width = scale_height + elif self.__resize_method == "minimal": + # scale as least as possbile + if abs(1 - scale_width) < abs(1 - scale_height): + # fit width + scale_height = scale_width + else: + # fit height + scale_width = scale_height + else: + raise ValueError( + f"resize_method {self.__resize_method} not implemented" + ) + + if self.__resize_method == "lower_bound": + new_height = self.constrain_to_multiple_of( + scale_height * height, min_val=self.__height + ) + new_width = self.constrain_to_multiple_of( + scale_width * width, min_val=self.__width + ) + elif self.__resize_method == "upper_bound": + new_height = self.constrain_to_multiple_of( + scale_height * height, max_val=self.__height + ) + new_width = self.constrain_to_multiple_of( + scale_width * width, max_val=self.__width + ) + elif self.__resize_method == "minimal": + new_height = self.constrain_to_multiple_of(scale_height * height) + new_width = self.constrain_to_multiple_of(scale_width * width) + else: + raise ValueError(f"resize_method {self.__resize_method} not implemented") + + return (new_width, new_height) + + def __call__(self, sample): + width, height = self.get_size( + sample["image"].shape[1], sample["image"].shape[0] + ) + + # resize sample + sample["image"] = cv2.resize( + sample["image"], + (width, height), + interpolation=self.__image_interpolation_method, + ) + + if self.__resize_target: + if "disparity" in sample: + sample["disparity"] = cv2.resize( + sample["disparity"], + (width, height), + interpolation=cv2.INTER_NEAREST, + ) + + if "depth" in sample: + sample["depth"] = cv2.resize( + sample["depth"], (width, height), interpolation=cv2.INTER_NEAREST + ) + + sample["mask"] = cv2.resize( + sample["mask"].astype(np.float32), + (width, height), + interpolation=cv2.INTER_NEAREST, + ) + sample["mask"] = sample["mask"].astype(bool) + + return sample + + +class NormalizeImage(object): + """Normlize image by given mean and std. + """ + + def __init__(self, mean, std): + self.__mean = mean + self.__std = std + + def __call__(self, sample): + sample["image"] = (sample["image"] - self.__mean) / self.__std + + return sample + + +class PrepareForNet(object): + """Prepare sample for usage as network input. + """ + + def __init__(self): + pass + + def __call__(self, sample): + image = np.transpose(sample["image"], (2, 0, 1)) + sample["image"] = np.ascontiguousarray(image).astype(np.float32) + + if "mask" in sample: + sample["mask"] = sample["mask"].astype(np.float32) + sample["mask"] = np.ascontiguousarray(sample["mask"]) + + if "disparity" in sample: + disparity = sample["disparity"].astype(np.float32) + sample["disparity"] = np.ascontiguousarray(disparity) + + if "depth" in sample: + depth = sample["depth"].astype(np.float32) + sample["depth"] = np.ascontiguousarray(depth) + + return sample diff --git a/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/vit.py b/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/vit.py new file mode 100644 index 00000000..ea46b1be --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/midas/midas/vit.py @@ -0,0 +1,491 @@ +import torch +import torch.nn as nn +import timm +import types +import math +import torch.nn.functional as F + + +class Slice(nn.Module): + def __init__(self, start_index=1): + super(Slice, self).__init__() + self.start_index = start_index + + def forward(self, x): + return x[:, self.start_index :] + + +class AddReadout(nn.Module): + def __init__(self, start_index=1): + super(AddReadout, self).__init__() + self.start_index = start_index + + def forward(self, x): + if self.start_index == 2: + readout = (x[:, 0] + x[:, 1]) / 2 + else: + readout = x[:, 0] + return x[:, self.start_index :] + readout.unsqueeze(1) + + +class ProjectReadout(nn.Module): + def __init__(self, in_features, start_index=1): + super(ProjectReadout, self).__init__() + self.start_index = start_index + + self.project = nn.Sequential(nn.Linear(2 * in_features, in_features), nn.GELU()) + + def forward(self, x): + readout = x[:, 0].unsqueeze(1).expand_as(x[:, self.start_index :]) + features = torch.cat((x[:, self.start_index :], readout), -1) + + return self.project(features) + + +class Transpose(nn.Module): + def __init__(self, dim0, dim1): + super(Transpose, self).__init__() + self.dim0 = dim0 + self.dim1 = dim1 + + def forward(self, x): + x = x.transpose(self.dim0, self.dim1) + return x + + +def forward_vit(pretrained, x): + b, c, h, w = x.shape + + glob = pretrained.model.forward_flex(x) + + layer_1 = pretrained.activations["1"] + layer_2 = pretrained.activations["2"] + layer_3 = pretrained.activations["3"] + layer_4 = pretrained.activations["4"] + + layer_1 = pretrained.act_postprocess1[0:2](layer_1) + layer_2 = pretrained.act_postprocess2[0:2](layer_2) + layer_3 = pretrained.act_postprocess3[0:2](layer_3) + layer_4 = pretrained.act_postprocess4[0:2](layer_4) + + unflatten = nn.Sequential( + nn.Unflatten( + 2, + torch.Size( + [ + h // pretrained.model.patch_size[1], + w // pretrained.model.patch_size[0], + ] + ), + ) + ) + + if layer_1.ndim == 3: + layer_1 = unflatten(layer_1) + if layer_2.ndim == 3: + layer_2 = unflatten(layer_2) + if layer_3.ndim == 3: + layer_3 = unflatten(layer_3) + if layer_4.ndim == 3: + layer_4 = unflatten(layer_4) + + layer_1 = pretrained.act_postprocess1[3 : len(pretrained.act_postprocess1)](layer_1) + layer_2 = pretrained.act_postprocess2[3 : len(pretrained.act_postprocess2)](layer_2) + layer_3 = pretrained.act_postprocess3[3 : len(pretrained.act_postprocess3)](layer_3) + layer_4 = pretrained.act_postprocess4[3 : len(pretrained.act_postprocess4)](layer_4) + + return layer_1, layer_2, layer_3, layer_4 + + +def _resize_pos_embed(self, posemb, gs_h, gs_w): + posemb_tok, posemb_grid = ( + posemb[:, : self.start_index], + posemb[0, self.start_index :], + ) + + gs_old = int(math.sqrt(len(posemb_grid))) + + posemb_grid = posemb_grid.reshape(1, gs_old, gs_old, -1).permute(0, 3, 1, 2) + posemb_grid = F.interpolate(posemb_grid, size=(gs_h, gs_w), mode="bilinear") + posemb_grid = posemb_grid.permute(0, 2, 3, 1).reshape(1, gs_h * gs_w, -1) + + posemb = torch.cat([posemb_tok, posemb_grid], dim=1) + + return posemb + + +def forward_flex(self, x): + b, c, h, w = x.shape + + pos_embed = self._resize_pos_embed( + self.pos_embed, h // self.patch_size[1], w // self.patch_size[0] + ) + + B = x.shape[0] + + if hasattr(self.patch_embed, "backbone"): + x = self.patch_embed.backbone(x) + if isinstance(x, (list, tuple)): + x = x[-1] # last feature if backbone outputs list/tuple of features + + x = self.patch_embed.proj(x).flatten(2).transpose(1, 2) + + if getattr(self, "dist_token", None) is not None: + cls_tokens = self.cls_token.expand( + B, -1, -1 + ) # stole cls_tokens impl from Phil Wang, thanks + dist_token = self.dist_token.expand(B, -1, -1) + x = torch.cat((cls_tokens, dist_token, x), dim=1) + else: + cls_tokens = self.cls_token.expand( + B, -1, -1 + ) # stole cls_tokens impl from Phil Wang, thanks + x = torch.cat((cls_tokens, x), dim=1) + + x = x + pos_embed + x = self.pos_drop(x) + + for blk in self.blocks: + x = blk(x) + + x = self.norm(x) + + return x + + +activations = {} + + +def get_activation(name): + def hook(model, input, output): + activations[name] = output + + return hook + + +def get_readout_oper(vit_features, features, use_readout, start_index=1): + if use_readout == "ignore": + readout_oper = [Slice(start_index)] * len(features) + elif use_readout == "add": + readout_oper = [AddReadout(start_index)] * len(features) + elif use_readout == "project": + readout_oper = [ + ProjectReadout(vit_features, start_index) for out_feat in features + ] + else: + assert ( + False + ), "wrong operation for readout token, use_readout can be 'ignore', 'add', or 'project'" + + return readout_oper + + +def _make_vit_b16_backbone( + model, + features=[96, 192, 384, 768], + size=[384, 384], + hooks=[2, 5, 8, 11], + vit_features=768, + use_readout="ignore", + start_index=1, +): + pretrained = nn.Module() + + pretrained.model = model + pretrained.model.blocks[hooks[0]].register_forward_hook(get_activation("1")) + pretrained.model.blocks[hooks[1]].register_forward_hook(get_activation("2")) + pretrained.model.blocks[hooks[2]].register_forward_hook(get_activation("3")) + pretrained.model.blocks[hooks[3]].register_forward_hook(get_activation("4")) + + pretrained.activations = activations + + readout_oper = get_readout_oper(vit_features, features, use_readout, start_index) + + # 32, 48, 136, 384 + pretrained.act_postprocess1 = nn.Sequential( + readout_oper[0], + Transpose(1, 2), + nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])), + nn.Conv2d( + in_channels=vit_features, + out_channels=features[0], + kernel_size=1, + stride=1, + padding=0, + ), + nn.ConvTranspose2d( + in_channels=features[0], + out_channels=features[0], + kernel_size=4, + stride=4, + padding=0, + bias=True, + dilation=1, + groups=1, + ), + ) + + pretrained.act_postprocess2 = nn.Sequential( + readout_oper[1], + Transpose(1, 2), + nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])), + nn.Conv2d( + in_channels=vit_features, + out_channels=features[1], + kernel_size=1, + stride=1, + padding=0, + ), + nn.ConvTranspose2d( + in_channels=features[1], + out_channels=features[1], + kernel_size=2, + stride=2, + padding=0, + bias=True, + dilation=1, + groups=1, + ), + ) + + pretrained.act_postprocess3 = nn.Sequential( + readout_oper[2], + Transpose(1, 2), + nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])), + nn.Conv2d( + in_channels=vit_features, + out_channels=features[2], + kernel_size=1, + stride=1, + padding=0, + ), + ) + + pretrained.act_postprocess4 = nn.Sequential( + readout_oper[3], + Transpose(1, 2), + nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])), + nn.Conv2d( + in_channels=vit_features, + out_channels=features[3], + kernel_size=1, + stride=1, + padding=0, + ), + nn.Conv2d( + in_channels=features[3], + out_channels=features[3], + kernel_size=3, + stride=2, + padding=1, + ), + ) + + pretrained.model.start_index = start_index + pretrained.model.patch_size = [16, 16] + + # We inject this function into the VisionTransformer instances so that + # we can use it with interpolated position embeddings without modifying the library source. + pretrained.model.forward_flex = types.MethodType(forward_flex, pretrained.model) + pretrained.model._resize_pos_embed = types.MethodType( + _resize_pos_embed, pretrained.model + ) + + return pretrained + + +def _make_pretrained_vitl16_384(pretrained, use_readout="ignore", hooks=None): + model = timm.create_model("vit_large_patch16_384", pretrained=pretrained) + + hooks = [5, 11, 17, 23] if hooks == None else hooks + return _make_vit_b16_backbone( + model, + features=[256, 512, 1024, 1024], + hooks=hooks, + vit_features=1024, + use_readout=use_readout, + ) + + +def _make_pretrained_vitb16_384(pretrained, use_readout="ignore", hooks=None): + model = timm.create_model("vit_base_patch16_384", pretrained=pretrained) + + hooks = [2, 5, 8, 11] if hooks == None else hooks + return _make_vit_b16_backbone( + model, features=[96, 192, 384, 768], hooks=hooks, use_readout=use_readout + ) + + +def _make_pretrained_deitb16_384(pretrained, use_readout="ignore", hooks=None): + model = timm.create_model("vit_deit_base_patch16_384", pretrained=pretrained) + + hooks = [2, 5, 8, 11] if hooks == None else hooks + return _make_vit_b16_backbone( + model, features=[96, 192, 384, 768], hooks=hooks, use_readout=use_readout + ) + + +def _make_pretrained_deitb16_distil_384(pretrained, use_readout="ignore", hooks=None): + model = timm.create_model( + "vit_deit_base_distilled_patch16_384", pretrained=pretrained + ) + + hooks = [2, 5, 8, 11] if hooks == None else hooks + return _make_vit_b16_backbone( + model, + features=[96, 192, 384, 768], + hooks=hooks, + use_readout=use_readout, + start_index=2, + ) + + +def _make_vit_b_rn50_backbone( + model, + features=[256, 512, 768, 768], + size=[384, 384], + hooks=[0, 1, 8, 11], + vit_features=768, + use_vit_only=False, + use_readout="ignore", + start_index=1, +): + pretrained = nn.Module() + + pretrained.model = model + + if use_vit_only == True: + pretrained.model.blocks[hooks[0]].register_forward_hook(get_activation("1")) + pretrained.model.blocks[hooks[1]].register_forward_hook(get_activation("2")) + else: + pretrained.model.patch_embed.backbone.stages[0].register_forward_hook( + get_activation("1") + ) + pretrained.model.patch_embed.backbone.stages[1].register_forward_hook( + get_activation("2") + ) + + pretrained.model.blocks[hooks[2]].register_forward_hook(get_activation("3")) + pretrained.model.blocks[hooks[3]].register_forward_hook(get_activation("4")) + + pretrained.activations = activations + + readout_oper = get_readout_oper(vit_features, features, use_readout, start_index) + + if use_vit_only == True: + pretrained.act_postprocess1 = nn.Sequential( + readout_oper[0], + Transpose(1, 2), + nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])), + nn.Conv2d( + in_channels=vit_features, + out_channels=features[0], + kernel_size=1, + stride=1, + padding=0, + ), + nn.ConvTranspose2d( + in_channels=features[0], + out_channels=features[0], + kernel_size=4, + stride=4, + padding=0, + bias=True, + dilation=1, + groups=1, + ), + ) + + pretrained.act_postprocess2 = nn.Sequential( + readout_oper[1], + Transpose(1, 2), + nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])), + nn.Conv2d( + in_channels=vit_features, + out_channels=features[1], + kernel_size=1, + stride=1, + padding=0, + ), + nn.ConvTranspose2d( + in_channels=features[1], + out_channels=features[1], + kernel_size=2, + stride=2, + padding=0, + bias=True, + dilation=1, + groups=1, + ), + ) + else: + pretrained.act_postprocess1 = nn.Sequential( + nn.Identity(), nn.Identity(), nn.Identity() + ) + pretrained.act_postprocess2 = nn.Sequential( + nn.Identity(), nn.Identity(), nn.Identity() + ) + + pretrained.act_postprocess3 = nn.Sequential( + readout_oper[2], + Transpose(1, 2), + nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])), + nn.Conv2d( + in_channels=vit_features, + out_channels=features[2], + kernel_size=1, + stride=1, + padding=0, + ), + ) + + pretrained.act_postprocess4 = nn.Sequential( + readout_oper[3], + Transpose(1, 2), + nn.Unflatten(2, torch.Size([size[0] // 16, size[1] // 16])), + nn.Conv2d( + in_channels=vit_features, + out_channels=features[3], + kernel_size=1, + stride=1, + padding=0, + ), + nn.Conv2d( + in_channels=features[3], + out_channels=features[3], + kernel_size=3, + stride=2, + padding=1, + ), + ) + + pretrained.model.start_index = start_index + pretrained.model.patch_size = [16, 16] + + # We inject this function into the VisionTransformer instances so that + # we can use it with interpolated position embeddings without modifying the library source. + pretrained.model.forward_flex = types.MethodType(forward_flex, pretrained.model) + + # We inject this function into the VisionTransformer instances so that + # we can use it with interpolated position embeddings without modifying the library source. + pretrained.model._resize_pos_embed = types.MethodType( + _resize_pos_embed, pretrained.model + ) + + return pretrained + + +def _make_pretrained_vitb_rn50_384( + pretrained, use_readout="ignore", hooks=None, use_vit_only=False +): + model = timm.create_model("vit_base_resnet50_384", pretrained=pretrained) + + hooks = [0, 1, 8, 11] if hooks == None else hooks + return _make_vit_b_rn50_backbone( + model, + features=[256, 512, 768, 768], + size=[384, 384], + hooks=hooks, + use_vit_only=use_vit_only, + use_readout=use_readout, + ) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/midas/utils.py b/extensions-builtin/sd_forge_controlnet/annotator/midas/utils.py new file mode 100644 index 00000000..9a9d3b5b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/midas/utils.py @@ -0,0 +1,189 @@ +"""Utils for monoDepth.""" +import sys +import re +import numpy as np +import cv2 +import torch + + +def read_pfm(path): + """Read pfm file. + + Args: + path (str): path to file + + Returns: + tuple: (data, scale) + """ + with open(path, "rb") as file: + + color = None + width = None + height = None + scale = None + endian = None + + header = file.readline().rstrip() + if header.decode("ascii") == "PF": + color = True + elif header.decode("ascii") == "Pf": + color = False + else: + raise Exception("Not a PFM file: " + path) + + dim_match = re.match(r"^(\d+)\s(\d+)\s$", file.readline().decode("ascii")) + if dim_match: + width, height = list(map(int, dim_match.groups())) + else: + raise Exception("Malformed PFM header.") + + scale = float(file.readline().decode("ascii").rstrip()) + if scale < 0: + # little-endian + endian = "<" + scale = -scale + else: + # big-endian + endian = ">" + + data = np.fromfile(file, endian + "f") + shape = (height, width, 3) if color else (height, width) + + data = np.reshape(data, shape) + data = np.flipud(data) + + return data, scale + + +def write_pfm(path, image, scale=1): + """Write pfm file. + + Args: + path (str): pathto file + image (array): data + scale (int, optional): Scale. Defaults to 1. + """ + + with open(path, "wb") as file: + color = None + + if image.dtype.name != "float32": + raise Exception("Image dtype must be float32.") + + image = np.flipud(image) + + if len(image.shape) == 3 and image.shape[2] == 3: # color image + color = True + elif ( + len(image.shape) == 2 or len(image.shape) == 3 and image.shape[2] == 1 + ): # greyscale + color = False + else: + raise Exception("Image must have H x W x 3, H x W x 1 or H x W dimensions.") + + file.write("PF\n" if color else "Pf\n".encode()) + file.write("%d %d\n".encode() % (image.shape[1], image.shape[0])) + + endian = image.dtype.byteorder + + if endian == "<" or endian == "=" and sys.byteorder == "little": + scale = -scale + + file.write("%f\n".encode() % scale) + + image.tofile(file) + + +def read_image(path): + """Read image and output RGB image (0-1). + + Args: + path (str): path to file + + Returns: + array: RGB image (0-1) + """ + img = cv2.imread(path) + + if img.ndim == 2: + img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) + + img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) / 255.0 + + return img + + +def resize_image(img): + """Resize image and make it fit for network. + + Args: + img (array): image + + Returns: + tensor: data ready for network + """ + height_orig = img.shape[0] + width_orig = img.shape[1] + + if width_orig > height_orig: + scale = width_orig / 384 + else: + scale = height_orig / 384 + + height = (np.ceil(height_orig / scale / 32) * 32).astype(int) + width = (np.ceil(width_orig / scale / 32) * 32).astype(int) + + img_resized = cv2.resize(img, (width, height), interpolation=cv2.INTER_AREA) + + img_resized = ( + torch.from_numpy(np.transpose(img_resized, (2, 0, 1))).contiguous().float() + ) + img_resized = img_resized.unsqueeze(0) + + return img_resized + + +def resize_depth(depth, width, height): + """Resize depth map and bring to CPU (numpy). + + Args: + depth (tensor): depth + width (int): image width + height (int): image height + + Returns: + array: processed depth + """ + depth = torch.squeeze(depth[0, :, :, :]).to("cpu") + + depth_resized = cv2.resize( + depth.numpy(), (width, height), interpolation=cv2.INTER_CUBIC + ) + + return depth_resized + +def write_depth(path, depth, bits=1): + """Write depth map to pfm and png file. + + Args: + path (str): filepath without extension + depth (array): depth + """ + write_pfm(path + ".pfm", depth.astype(np.float32)) + + depth_min = depth.min() + depth_max = depth.max() + + max_val = (2**(8*bits))-1 + + if depth_max - depth_min > np.finfo("float").eps: + out = max_val * (depth - depth_min) / (depth_max - depth_min) + else: + out = np.zeros(depth.shape, dtype=depth.type) + + if bits == 1: + cv2.imwrite(path + ".png", out.astype("uint8")) + elif bits == 2: + cv2.imwrite(path + ".png", out.astype("uint16")) + + return diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mlsd/LICENSE b/extensions-builtin/sd_forge_controlnet/annotator/mlsd/LICENSE new file mode 100644 index 00000000..d855c6db --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mlsd/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2021-present NAVER Corp. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mlsd/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mlsd/__init__.py new file mode 100644 index 00000000..c9791e3f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mlsd/__init__.py @@ -0,0 +1,49 @@ +import cv2 +import numpy as np +import torch +import os + +from einops import rearrange +from .models.mbv2_mlsd_tiny import MobileV2_MLSD_Tiny +from .models.mbv2_mlsd_large import MobileV2_MLSD_Large +from .utils import pred_lines +from modules import devices +from annotator.annotator_path import models_path + +mlsdmodel = None +remote_model_path = "https://huggingface.co/lllyasviel/ControlNet/resolve/main/annotator/ckpts/mlsd_large_512_fp32.pth" +old_modeldir = os.path.dirname(os.path.realpath(__file__)) +modeldir = os.path.join(models_path, "mlsd") + +def unload_mlsd_model(): + global mlsdmodel + if mlsdmodel is not None: + mlsdmodel = mlsdmodel.cpu() + +def apply_mlsd(input_image, thr_v, thr_d): + global modelpath, mlsdmodel + if mlsdmodel is None: + modelpath = os.path.join(modeldir, "mlsd_large_512_fp32.pth") + old_modelpath = os.path.join(old_modeldir, "mlsd_large_512_fp32.pth") + if os.path.exists(old_modelpath): + modelpath = old_modelpath + elif not os.path.exists(modelpath): + from basicsr.utils.download_util import load_file_from_url + load_file_from_url(remote_model_path, model_dir=modeldir) + mlsdmodel = MobileV2_MLSD_Large() + mlsdmodel.load_state_dict(torch.load(modelpath), strict=True) + mlsdmodel = mlsdmodel.to(devices.get_device_for("controlnet")).eval() + + model = mlsdmodel + assert input_image.ndim == 3 + img = input_image + img_output = np.zeros_like(img) + try: + with torch.no_grad(): + lines = pred_lines(img, model, [img.shape[0], img.shape[1]], thr_v, thr_d) + for line in lines: + x_start, y_start, x_end, y_end = [int(val) for val in line] + cv2.line(img_output, (x_start, y_start), (x_end, y_end), [255, 255, 255], 1) + except Exception as e: + pass + return img_output[:, :, 0] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mlsd/models/mbv2_mlsd_large.py b/extensions-builtin/sd_forge_controlnet/annotator/mlsd/models/mbv2_mlsd_large.py new file mode 100644 index 00000000..5b9799e7 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mlsd/models/mbv2_mlsd_large.py @@ -0,0 +1,292 @@ +import os +import sys +import torch +import torch.nn as nn +import torch.utils.model_zoo as model_zoo +from torch.nn import functional as F + + +class BlockTypeA(nn.Module): + def __init__(self, in_c1, in_c2, out_c1, out_c2, upscale = True): + super(BlockTypeA, self).__init__() + self.conv1 = nn.Sequential( + nn.Conv2d(in_c2, out_c2, kernel_size=1), + nn.BatchNorm2d(out_c2), + nn.ReLU(inplace=True) + ) + self.conv2 = nn.Sequential( + nn.Conv2d(in_c1, out_c1, kernel_size=1), + nn.BatchNorm2d(out_c1), + nn.ReLU(inplace=True) + ) + self.upscale = upscale + + def forward(self, a, b): + b = self.conv1(b) + a = self.conv2(a) + if self.upscale: + b = F.interpolate(b, scale_factor=2.0, mode='bilinear', align_corners=True) + return torch.cat((a, b), dim=1) + + +class BlockTypeB(nn.Module): + def __init__(self, in_c, out_c): + super(BlockTypeB, self).__init__() + self.conv1 = nn.Sequential( + nn.Conv2d(in_c, in_c, kernel_size=3, padding=1), + nn.BatchNorm2d(in_c), + nn.ReLU() + ) + self.conv2 = nn.Sequential( + nn.Conv2d(in_c, out_c, kernel_size=3, padding=1), + nn.BatchNorm2d(out_c), + nn.ReLU() + ) + + def forward(self, x): + x = self.conv1(x) + x + x = self.conv2(x) + return x + +class BlockTypeC(nn.Module): + def __init__(self, in_c, out_c): + super(BlockTypeC, self).__init__() + self.conv1 = nn.Sequential( + nn.Conv2d(in_c, in_c, kernel_size=3, padding=5, dilation=5), + nn.BatchNorm2d(in_c), + nn.ReLU() + ) + self.conv2 = nn.Sequential( + nn.Conv2d(in_c, in_c, kernel_size=3, padding=1), + nn.BatchNorm2d(in_c), + nn.ReLU() + ) + self.conv3 = nn.Conv2d(in_c, out_c, kernel_size=1) + + def forward(self, x): + x = self.conv1(x) + x = self.conv2(x) + x = self.conv3(x) + return x + +def _make_divisible(v, divisor, min_value=None): + """ + This function is taken from the original tf repo. + It ensures that all layers have a channel number that is divisible by 8 + It can be seen here: + https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py + :param v: + :param divisor: + :param min_value: + :return: + """ + if min_value is None: + min_value = divisor + new_v = max(min_value, int(v + divisor / 2) // divisor * divisor) + # Make sure that round down does not go down by more than 10%. + if new_v < 0.9 * v: + new_v += divisor + return new_v + + +class ConvBNReLU(nn.Sequential): + def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1): + self.channel_pad = out_planes - in_planes + self.stride = stride + #padding = (kernel_size - 1) // 2 + + # TFLite uses slightly different padding than PyTorch + if stride == 2: + padding = 0 + else: + padding = (kernel_size - 1) // 2 + + super(ConvBNReLU, self).__init__( + nn.Conv2d(in_planes, out_planes, kernel_size, stride, padding, groups=groups, bias=False), + nn.BatchNorm2d(out_planes), + nn.ReLU6(inplace=True) + ) + self.max_pool = nn.MaxPool2d(kernel_size=stride, stride=stride) + + + def forward(self, x): + # TFLite uses different padding + if self.stride == 2: + x = F.pad(x, (0, 1, 0, 1), "constant", 0) + #print(x.shape) + + for module in self: + if not isinstance(module, nn.MaxPool2d): + x = module(x) + return x + + +class InvertedResidual(nn.Module): + def __init__(self, inp, oup, stride, expand_ratio): + super(InvertedResidual, self).__init__() + self.stride = stride + assert stride in [1, 2] + + hidden_dim = int(round(inp * expand_ratio)) + self.use_res_connect = self.stride == 1 and inp == oup + + layers = [] + if expand_ratio != 1: + # pw + layers.append(ConvBNReLU(inp, hidden_dim, kernel_size=1)) + layers.extend([ + # dw + ConvBNReLU(hidden_dim, hidden_dim, stride=stride, groups=hidden_dim), + # pw-linear + nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False), + nn.BatchNorm2d(oup), + ]) + self.conv = nn.Sequential(*layers) + + def forward(self, x): + if self.use_res_connect: + return x + self.conv(x) + else: + return self.conv(x) + + +class MobileNetV2(nn.Module): + def __init__(self, pretrained=True): + """ + MobileNet V2 main class + Args: + num_classes (int): Number of classes + width_mult (float): Width multiplier - adjusts number of channels in each layer by this amount + inverted_residual_setting: Network structure + round_nearest (int): Round the number of channels in each layer to be a multiple of this number + Set to 1 to turn off rounding + block: Module specifying inverted residual building block for mobilenet + """ + super(MobileNetV2, self).__init__() + + block = InvertedResidual + input_channel = 32 + last_channel = 1280 + width_mult = 1.0 + round_nearest = 8 + + inverted_residual_setting = [ + # t, c, n, s + [1, 16, 1, 1], + [6, 24, 2, 2], + [6, 32, 3, 2], + [6, 64, 4, 2], + [6, 96, 3, 1], + #[6, 160, 3, 2], + #[6, 320, 1, 1], + ] + + # only check the first element, assuming user knows t,c,n,s are required + if len(inverted_residual_setting) == 0 or len(inverted_residual_setting[0]) != 4: + raise ValueError("inverted_residual_setting should be non-empty " + "or a 4-element list, got {}".format(inverted_residual_setting)) + + # building first layer + input_channel = _make_divisible(input_channel * width_mult, round_nearest) + self.last_channel = _make_divisible(last_channel * max(1.0, width_mult), round_nearest) + features = [ConvBNReLU(4, input_channel, stride=2)] + # building inverted residual blocks + for t, c, n, s in inverted_residual_setting: + output_channel = _make_divisible(c * width_mult, round_nearest) + for i in range(n): + stride = s if i == 0 else 1 + features.append(block(input_channel, output_channel, stride, expand_ratio=t)) + input_channel = output_channel + + self.features = nn.Sequential(*features) + self.fpn_selected = [1, 3, 6, 10, 13] + # weight initialization + for m in self.modules(): + if isinstance(m, nn.Conv2d): + nn.init.kaiming_normal_(m.weight, mode='fan_out') + if m.bias is not None: + nn.init.zeros_(m.bias) + elif isinstance(m, nn.BatchNorm2d): + nn.init.ones_(m.weight) + nn.init.zeros_(m.bias) + elif isinstance(m, nn.Linear): + nn.init.normal_(m.weight, 0, 0.01) + nn.init.zeros_(m.bias) + if pretrained: + self._load_pretrained_model() + + def _forward_impl(self, x): + # This exists since TorchScript doesn't support inheritance, so the superclass method + # (this one) needs to have a name other than `forward` that can be accessed in a subclass + fpn_features = [] + for i, f in enumerate(self.features): + if i > self.fpn_selected[-1]: + break + x = f(x) + if i in self.fpn_selected: + fpn_features.append(x) + + c1, c2, c3, c4, c5 = fpn_features + return c1, c2, c3, c4, c5 + + + def forward(self, x): + return self._forward_impl(x) + + def _load_pretrained_model(self): + pretrain_dict = model_zoo.load_url('https://download.pytorch.org/models/mobilenet_v2-b0353104.pth') + model_dict = {} + state_dict = self.state_dict() + for k, v in pretrain_dict.items(): + if k in state_dict: + model_dict[k] = v + state_dict.update(model_dict) + self.load_state_dict(state_dict) + + +class MobileV2_MLSD_Large(nn.Module): + def __init__(self): + super(MobileV2_MLSD_Large, self).__init__() + + self.backbone = MobileNetV2(pretrained=False) + ## A, B + self.block15 = BlockTypeA(in_c1= 64, in_c2= 96, + out_c1= 64, out_c2=64, + upscale=False) + self.block16 = BlockTypeB(128, 64) + + ## A, B + self.block17 = BlockTypeA(in_c1 = 32, in_c2 = 64, + out_c1= 64, out_c2= 64) + self.block18 = BlockTypeB(128, 64) + + ## A, B + self.block19 = BlockTypeA(in_c1=24, in_c2=64, + out_c1=64, out_c2=64) + self.block20 = BlockTypeB(128, 64) + + ## A, B, C + self.block21 = BlockTypeA(in_c1=16, in_c2=64, + out_c1=64, out_c2=64) + self.block22 = BlockTypeB(128, 64) + + self.block23 = BlockTypeC(64, 16) + + def forward(self, x): + c1, c2, c3, c4, c5 = self.backbone(x) + + x = self.block15(c4, c5) + x = self.block16(x) + + x = self.block17(c3, x) + x = self.block18(x) + + x = self.block19(c2, x) + x = self.block20(x) + + x = self.block21(c1, x) + x = self.block22(x) + x = self.block23(x) + x = x[:, 7:, :, :] + + return x \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mlsd/models/mbv2_mlsd_tiny.py b/extensions-builtin/sd_forge_controlnet/annotator/mlsd/models/mbv2_mlsd_tiny.py new file mode 100644 index 00000000..e3ed633f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mlsd/models/mbv2_mlsd_tiny.py @@ -0,0 +1,275 @@ +import os +import sys +import torch +import torch.nn as nn +import torch.utils.model_zoo as model_zoo +from torch.nn import functional as F + + +class BlockTypeA(nn.Module): + def __init__(self, in_c1, in_c2, out_c1, out_c2, upscale = True): + super(BlockTypeA, self).__init__() + self.conv1 = nn.Sequential( + nn.Conv2d(in_c2, out_c2, kernel_size=1), + nn.BatchNorm2d(out_c2), + nn.ReLU(inplace=True) + ) + self.conv2 = nn.Sequential( + nn.Conv2d(in_c1, out_c1, kernel_size=1), + nn.BatchNorm2d(out_c1), + nn.ReLU(inplace=True) + ) + self.upscale = upscale + + def forward(self, a, b): + b = self.conv1(b) + a = self.conv2(a) + b = F.interpolate(b, scale_factor=2.0, mode='bilinear', align_corners=True) + return torch.cat((a, b), dim=1) + + +class BlockTypeB(nn.Module): + def __init__(self, in_c, out_c): + super(BlockTypeB, self).__init__() + self.conv1 = nn.Sequential( + nn.Conv2d(in_c, in_c, kernel_size=3, padding=1), + nn.BatchNorm2d(in_c), + nn.ReLU() + ) + self.conv2 = nn.Sequential( + nn.Conv2d(in_c, out_c, kernel_size=3, padding=1), + nn.BatchNorm2d(out_c), + nn.ReLU() + ) + + def forward(self, x): + x = self.conv1(x) + x + x = self.conv2(x) + return x + +class BlockTypeC(nn.Module): + def __init__(self, in_c, out_c): + super(BlockTypeC, self).__init__() + self.conv1 = nn.Sequential( + nn.Conv2d(in_c, in_c, kernel_size=3, padding=5, dilation=5), + nn.BatchNorm2d(in_c), + nn.ReLU() + ) + self.conv2 = nn.Sequential( + nn.Conv2d(in_c, in_c, kernel_size=3, padding=1), + nn.BatchNorm2d(in_c), + nn.ReLU() + ) + self.conv3 = nn.Conv2d(in_c, out_c, kernel_size=1) + + def forward(self, x): + x = self.conv1(x) + x = self.conv2(x) + x = self.conv3(x) + return x + +def _make_divisible(v, divisor, min_value=None): + """ + This function is taken from the original tf repo. + It ensures that all layers have a channel number that is divisible by 8 + It can be seen here: + https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py + :param v: + :param divisor: + :param min_value: + :return: + """ + if min_value is None: + min_value = divisor + new_v = max(min_value, int(v + divisor / 2) // divisor * divisor) + # Make sure that round down does not go down by more than 10%. + if new_v < 0.9 * v: + new_v += divisor + return new_v + + +class ConvBNReLU(nn.Sequential): + def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1): + self.channel_pad = out_planes - in_planes + self.stride = stride + #padding = (kernel_size - 1) // 2 + + # TFLite uses slightly different padding than PyTorch + if stride == 2: + padding = 0 + else: + padding = (kernel_size - 1) // 2 + + super(ConvBNReLU, self).__init__( + nn.Conv2d(in_planes, out_planes, kernel_size, stride, padding, groups=groups, bias=False), + nn.BatchNorm2d(out_planes), + nn.ReLU6(inplace=True) + ) + self.max_pool = nn.MaxPool2d(kernel_size=stride, stride=stride) + + + def forward(self, x): + # TFLite uses different padding + if self.stride == 2: + x = F.pad(x, (0, 1, 0, 1), "constant", 0) + #print(x.shape) + + for module in self: + if not isinstance(module, nn.MaxPool2d): + x = module(x) + return x + + +class InvertedResidual(nn.Module): + def __init__(self, inp, oup, stride, expand_ratio): + super(InvertedResidual, self).__init__() + self.stride = stride + assert stride in [1, 2] + + hidden_dim = int(round(inp * expand_ratio)) + self.use_res_connect = self.stride == 1 and inp == oup + + layers = [] + if expand_ratio != 1: + # pw + layers.append(ConvBNReLU(inp, hidden_dim, kernel_size=1)) + layers.extend([ + # dw + ConvBNReLU(hidden_dim, hidden_dim, stride=stride, groups=hidden_dim), + # pw-linear + nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False), + nn.BatchNorm2d(oup), + ]) + self.conv = nn.Sequential(*layers) + + def forward(self, x): + if self.use_res_connect: + return x + self.conv(x) + else: + return self.conv(x) + + +class MobileNetV2(nn.Module): + def __init__(self, pretrained=True): + """ + MobileNet V2 main class + Args: + num_classes (int): Number of classes + width_mult (float): Width multiplier - adjusts number of channels in each layer by this amount + inverted_residual_setting: Network structure + round_nearest (int): Round the number of channels in each layer to be a multiple of this number + Set to 1 to turn off rounding + block: Module specifying inverted residual building block for mobilenet + """ + super(MobileNetV2, self).__init__() + + block = InvertedResidual + input_channel = 32 + last_channel = 1280 + width_mult = 1.0 + round_nearest = 8 + + inverted_residual_setting = [ + # t, c, n, s + [1, 16, 1, 1], + [6, 24, 2, 2], + [6, 32, 3, 2], + [6, 64, 4, 2], + #[6, 96, 3, 1], + #[6, 160, 3, 2], + #[6, 320, 1, 1], + ] + + # only check the first element, assuming user knows t,c,n,s are required + if len(inverted_residual_setting) == 0 or len(inverted_residual_setting[0]) != 4: + raise ValueError("inverted_residual_setting should be non-empty " + "or a 4-element list, got {}".format(inverted_residual_setting)) + + # building first layer + input_channel = _make_divisible(input_channel * width_mult, round_nearest) + self.last_channel = _make_divisible(last_channel * max(1.0, width_mult), round_nearest) + features = [ConvBNReLU(4, input_channel, stride=2)] + # building inverted residual blocks + for t, c, n, s in inverted_residual_setting: + output_channel = _make_divisible(c * width_mult, round_nearest) + for i in range(n): + stride = s if i == 0 else 1 + features.append(block(input_channel, output_channel, stride, expand_ratio=t)) + input_channel = output_channel + self.features = nn.Sequential(*features) + + self.fpn_selected = [3, 6, 10] + # weight initialization + for m in self.modules(): + if isinstance(m, nn.Conv2d): + nn.init.kaiming_normal_(m.weight, mode='fan_out') + if m.bias is not None: + nn.init.zeros_(m.bias) + elif isinstance(m, nn.BatchNorm2d): + nn.init.ones_(m.weight) + nn.init.zeros_(m.bias) + elif isinstance(m, nn.Linear): + nn.init.normal_(m.weight, 0, 0.01) + nn.init.zeros_(m.bias) + + #if pretrained: + # self._load_pretrained_model() + + def _forward_impl(self, x): + # This exists since TorchScript doesn't support inheritance, so the superclass method + # (this one) needs to have a name other than `forward` that can be accessed in a subclass + fpn_features = [] + for i, f in enumerate(self.features): + if i > self.fpn_selected[-1]: + break + x = f(x) + if i in self.fpn_selected: + fpn_features.append(x) + + c2, c3, c4 = fpn_features + return c2, c3, c4 + + + def forward(self, x): + return self._forward_impl(x) + + def _load_pretrained_model(self): + pretrain_dict = model_zoo.load_url('https://download.pytorch.org/models/mobilenet_v2-b0353104.pth') + model_dict = {} + state_dict = self.state_dict() + for k, v in pretrain_dict.items(): + if k in state_dict: + model_dict[k] = v + state_dict.update(model_dict) + self.load_state_dict(state_dict) + + +class MobileV2_MLSD_Tiny(nn.Module): + def __init__(self): + super(MobileV2_MLSD_Tiny, self).__init__() + + self.backbone = MobileNetV2(pretrained=True) + + self.block12 = BlockTypeA(in_c1= 32, in_c2= 64, + out_c1= 64, out_c2=64) + self.block13 = BlockTypeB(128, 64) + + self.block14 = BlockTypeA(in_c1 = 24, in_c2 = 64, + out_c1= 32, out_c2= 32) + self.block15 = BlockTypeB(64, 64) + + self.block16 = BlockTypeC(64, 16) + + def forward(self, x): + c2, c3, c4 = self.backbone(x) + + x = self.block12(c3, c4) + x = self.block13(x) + x = self.block14(c2, x) + x = self.block15(x) + x = self.block16(x) + x = x[:, 7:, :, :] + #print(x.shape) + x = F.interpolate(x, scale_factor=2.0, mode='bilinear', align_corners=True) + + return x \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mlsd/utils.py b/extensions-builtin/sd_forge_controlnet/annotator/mlsd/utils.py new file mode 100644 index 00000000..a9cc5d90 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mlsd/utils.py @@ -0,0 +1,581 @@ +''' +modified by lihaoweicv +pytorch version +''' + +''' +M-LSD +Copyright 2021-present NAVER Corp. +Apache License v2.0 +''' + +import os +import numpy as np +import cv2 +import torch +from torch.nn import functional as F +from modules import devices + + +def deccode_output_score_and_ptss(tpMap, topk_n = 200, ksize = 5): + ''' + tpMap: + center: tpMap[1, 0, :, :] + displacement: tpMap[1, 1:5, :, :] + ''' + b, c, h, w = tpMap.shape + assert b==1, 'only support bsize==1' + displacement = tpMap[:, 1:5, :, :][0] + center = tpMap[:, 0, :, :] + heat = torch.sigmoid(center) + hmax = F.max_pool2d( heat, (ksize, ksize), stride=1, padding=(ksize-1)//2) + keep = (hmax == heat).float() + heat = heat * keep + heat = heat.reshape(-1, ) + + scores, indices = torch.topk(heat, topk_n, dim=-1, largest=True) + yy = torch.floor_divide(indices, w).unsqueeze(-1) + xx = torch.fmod(indices, w).unsqueeze(-1) + ptss = torch.cat((yy, xx),dim=-1) + + ptss = ptss.detach().cpu().numpy() + scores = scores.detach().cpu().numpy() + displacement = displacement.detach().cpu().numpy() + displacement = displacement.transpose((1,2,0)) + return ptss, scores, displacement + + +def pred_lines(image, model, + input_shape=[512, 512], + score_thr=0.10, + dist_thr=20.0): + h, w, _ = image.shape + h_ratio, w_ratio = [h / input_shape[0], w / input_shape[1]] + + resized_image = np.concatenate([cv2.resize(image, (input_shape[1], input_shape[0]), interpolation=cv2.INTER_AREA), + np.ones([input_shape[0], input_shape[1], 1])], axis=-1) + + resized_image = resized_image.transpose((2,0,1)) + batch_image = np.expand_dims(resized_image, axis=0).astype('float32') + batch_image = (batch_image / 127.5) - 1.0 + + batch_image = torch.from_numpy(batch_image).float().to(devices.get_device_for("controlnet")) + outputs = model(batch_image) + pts, pts_score, vmap = deccode_output_score_and_ptss(outputs, 200, 3) + start = vmap[:, :, :2] + end = vmap[:, :, 2:] + dist_map = np.sqrt(np.sum((start - end) ** 2, axis=-1)) + + segments_list = [] + for center, score in zip(pts, pts_score): + y, x = center + distance = dist_map[y, x] + if score > score_thr and distance > dist_thr: + disp_x_start, disp_y_start, disp_x_end, disp_y_end = vmap[y, x, :] + x_start = x + disp_x_start + y_start = y + disp_y_start + x_end = x + disp_x_end + y_end = y + disp_y_end + segments_list.append([x_start, y_start, x_end, y_end]) + + lines = 2 * np.array(segments_list) # 256 > 512 + lines[:, 0] = lines[:, 0] * w_ratio + lines[:, 1] = lines[:, 1] * h_ratio + lines[:, 2] = lines[:, 2] * w_ratio + lines[:, 3] = lines[:, 3] * h_ratio + + return lines + + +def pred_squares(image, + model, + input_shape=[512, 512], + params={'score': 0.06, + 'outside_ratio': 0.28, + 'inside_ratio': 0.45, + 'w_overlap': 0.0, + 'w_degree': 1.95, + 'w_length': 0.0, + 'w_area': 1.86, + 'w_center': 0.14}): + ''' + shape = [height, width] + ''' + h, w, _ = image.shape + original_shape = [h, w] + + resized_image = np.concatenate([cv2.resize(image, (input_shape[0], input_shape[1]), interpolation=cv2.INTER_AREA), + np.ones([input_shape[0], input_shape[1], 1])], axis=-1) + resized_image = resized_image.transpose((2, 0, 1)) + batch_image = np.expand_dims(resized_image, axis=0).astype('float32') + batch_image = (batch_image / 127.5) - 1.0 + + batch_image = torch.from_numpy(batch_image).float().to(devices.get_device_for("controlnet")) + outputs = model(batch_image) + + pts, pts_score, vmap = deccode_output_score_and_ptss(outputs, 200, 3) + start = vmap[:, :, :2] # (x, y) + end = vmap[:, :, 2:] # (x, y) + dist_map = np.sqrt(np.sum((start - end) ** 2, axis=-1)) + + junc_list = [] + segments_list = [] + for junc, score in zip(pts, pts_score): + y, x = junc + distance = dist_map[y, x] + if score > params['score'] and distance > 20.0: + junc_list.append([x, y]) + disp_x_start, disp_y_start, disp_x_end, disp_y_end = vmap[y, x, :] + d_arrow = 1.0 + x_start = x + d_arrow * disp_x_start + y_start = y + d_arrow * disp_y_start + x_end = x + d_arrow * disp_x_end + y_end = y + d_arrow * disp_y_end + segments_list.append([x_start, y_start, x_end, y_end]) + + segments = np.array(segments_list) + + ####### post processing for squares + # 1. get unique lines + point = np.array([[0, 0]]) + point = point[0] + start = segments[:, :2] + end = segments[:, 2:] + diff = start - end + a = diff[:, 1] + b = -diff[:, 0] + c = a * start[:, 0] + b * start[:, 1] + + d = np.abs(a * point[0] + b * point[1] - c) / np.sqrt(a ** 2 + b ** 2 + 1e-10) + theta = np.arctan2(diff[:, 0], diff[:, 1]) * 180 / np.pi + theta[theta < 0.0] += 180 + hough = np.concatenate([d[:, None], theta[:, None]], axis=-1) + + d_quant = 1 + theta_quant = 2 + hough[:, 0] //= d_quant + hough[:, 1] //= theta_quant + _, indices, counts = np.unique(hough, axis=0, return_index=True, return_counts=True) + + acc_map = np.zeros([512 // d_quant + 1, 360 // theta_quant + 1], dtype='float32') + idx_map = np.zeros([512 // d_quant + 1, 360 // theta_quant + 1], dtype='int32') - 1 + yx_indices = hough[indices, :].astype('int32') + acc_map[yx_indices[:, 0], yx_indices[:, 1]] = counts + idx_map[yx_indices[:, 0], yx_indices[:, 1]] = indices + + acc_map_np = acc_map + # acc_map = acc_map[None, :, :, None] + # + # ### fast suppression using tensorflow op + # acc_map = tf.constant(acc_map, dtype=tf.float32) + # max_acc_map = tf.keras.layers.MaxPool2D(pool_size=(5, 5), strides=1, padding='same')(acc_map) + # acc_map = acc_map * tf.cast(tf.math.equal(acc_map, max_acc_map), tf.float32) + # flatten_acc_map = tf.reshape(acc_map, [1, -1]) + # topk_values, topk_indices = tf.math.top_k(flatten_acc_map, k=len(pts)) + # _, h, w, _ = acc_map.shape + # y = tf.expand_dims(topk_indices // w, axis=-1) + # x = tf.expand_dims(topk_indices % w, axis=-1) + # yx = tf.concat([y, x], axis=-1) + + ### fast suppression using pytorch op + acc_map = torch.from_numpy(acc_map_np).unsqueeze(0).unsqueeze(0) + _,_, h, w = acc_map.shape + max_acc_map = F.max_pool2d(acc_map,kernel_size=5, stride=1, padding=2) + acc_map = acc_map * ( (acc_map == max_acc_map).float() ) + flatten_acc_map = acc_map.reshape([-1, ]) + + scores, indices = torch.topk(flatten_acc_map, len(pts), dim=-1, largest=True) + yy = torch.div(indices, w, rounding_mode='floor').unsqueeze(-1) + xx = torch.fmod(indices, w).unsqueeze(-1) + yx = torch.cat((yy, xx), dim=-1) + + yx = yx.detach().cpu().numpy() + + topk_values = scores.detach().cpu().numpy() + indices = idx_map[yx[:, 0], yx[:, 1]] + basis = 5 // 2 + + merged_segments = [] + for yx_pt, max_indice, value in zip(yx, indices, topk_values): + y, x = yx_pt + if max_indice == -1 or value == 0: + continue + segment_list = [] + for y_offset in range(-basis, basis + 1): + for x_offset in range(-basis, basis + 1): + indice = idx_map[y + y_offset, x + x_offset] + cnt = int(acc_map_np[y + y_offset, x + x_offset]) + if indice != -1: + segment_list.append(segments[indice]) + if cnt > 1: + check_cnt = 1 + current_hough = hough[indice] + for new_indice, new_hough in enumerate(hough): + if (current_hough == new_hough).all() and indice != new_indice: + segment_list.append(segments[new_indice]) + check_cnt += 1 + if check_cnt == cnt: + break + group_segments = np.array(segment_list).reshape([-1, 2]) + sorted_group_segments = np.sort(group_segments, axis=0) + x_min, y_min = sorted_group_segments[0, :] + x_max, y_max = sorted_group_segments[-1, :] + + deg = theta[max_indice] + if deg >= 90: + merged_segments.append([x_min, y_max, x_max, y_min]) + else: + merged_segments.append([x_min, y_min, x_max, y_max]) + + # 2. get intersections + new_segments = np.array(merged_segments) # (x1, y1, x2, y2) + start = new_segments[:, :2] # (x1, y1) + end = new_segments[:, 2:] # (x2, y2) + new_centers = (start + end) / 2.0 + diff = start - end + dist_segments = np.sqrt(np.sum(diff ** 2, axis=-1)) + + # ax + by = c + a = diff[:, 1] + b = -diff[:, 0] + c = a * start[:, 0] + b * start[:, 1] + pre_det = a[:, None] * b[None, :] + det = pre_det - np.transpose(pre_det) + + pre_inter_y = a[:, None] * c[None, :] + inter_y = (pre_inter_y - np.transpose(pre_inter_y)) / (det + 1e-10) + pre_inter_x = c[:, None] * b[None, :] + inter_x = (pre_inter_x - np.transpose(pre_inter_x)) / (det + 1e-10) + inter_pts = np.concatenate([inter_x[:, :, None], inter_y[:, :, None]], axis=-1).astype('int32') + + # 3. get corner information + # 3.1 get distance + ''' + dist_segments: + | dist(0), dist(1), dist(2), ...| + dist_inter_to_segment1: + | dist(inter,0), dist(inter,0), dist(inter,0), ... | + | dist(inter,1), dist(inter,1), dist(inter,1), ... | + ... + dist_inter_to_semgnet2: + | dist(inter,0), dist(inter,1), dist(inter,2), ... | + | dist(inter,0), dist(inter,1), dist(inter,2), ... | + ... + ''' + + dist_inter_to_segment1_start = np.sqrt( + np.sum(((inter_pts - start[:, None, :]) ** 2), axis=-1, keepdims=True)) # [n_batch, n_batch, 1] + dist_inter_to_segment1_end = np.sqrt( + np.sum(((inter_pts - end[:, None, :]) ** 2), axis=-1, keepdims=True)) # [n_batch, n_batch, 1] + dist_inter_to_segment2_start = np.sqrt( + np.sum(((inter_pts - start[None, :, :]) ** 2), axis=-1, keepdims=True)) # [n_batch, n_batch, 1] + dist_inter_to_segment2_end = np.sqrt( + np.sum(((inter_pts - end[None, :, :]) ** 2), axis=-1, keepdims=True)) # [n_batch, n_batch, 1] + + # sort ascending + dist_inter_to_segment1 = np.sort( + np.concatenate([dist_inter_to_segment1_start, dist_inter_to_segment1_end], axis=-1), + axis=-1) # [n_batch, n_batch, 2] + dist_inter_to_segment2 = np.sort( + np.concatenate([dist_inter_to_segment2_start, dist_inter_to_segment2_end], axis=-1), + axis=-1) # [n_batch, n_batch, 2] + + # 3.2 get degree + inter_to_start = new_centers[:, None, :] - inter_pts + deg_inter_to_start = np.arctan2(inter_to_start[:, :, 1], inter_to_start[:, :, 0]) * 180 / np.pi + deg_inter_to_start[deg_inter_to_start < 0.0] += 360 + inter_to_end = new_centers[None, :, :] - inter_pts + deg_inter_to_end = np.arctan2(inter_to_end[:, :, 1], inter_to_end[:, :, 0]) * 180 / np.pi + deg_inter_to_end[deg_inter_to_end < 0.0] += 360 + + ''' + B -- G + | | + C -- R + B : blue / G: green / C: cyan / R: red + + 0 -- 1 + | | + 3 -- 2 + ''' + # rename variables + deg1_map, deg2_map = deg_inter_to_start, deg_inter_to_end + # sort deg ascending + deg_sort = np.sort(np.concatenate([deg1_map[:, :, None], deg2_map[:, :, None]], axis=-1), axis=-1) + + deg_diff_map = np.abs(deg1_map - deg2_map) + # we only consider the smallest degree of intersect + deg_diff_map[deg_diff_map > 180] = 360 - deg_diff_map[deg_diff_map > 180] + + # define available degree range + deg_range = [60, 120] + + corner_dict = {corner_info: [] for corner_info in range(4)} + inter_points = [] + for i in range(inter_pts.shape[0]): + for j in range(i + 1, inter_pts.shape[1]): + # i, j > line index, always i < j + x, y = inter_pts[i, j, :] + deg1, deg2 = deg_sort[i, j, :] + deg_diff = deg_diff_map[i, j] + + check_degree = deg_diff > deg_range[0] and deg_diff < deg_range[1] + + outside_ratio = params['outside_ratio'] # over ratio >>> drop it! + inside_ratio = params['inside_ratio'] # over ratio >>> drop it! + check_distance = ((dist_inter_to_segment1[i, j, 1] >= dist_segments[i] and \ + dist_inter_to_segment1[i, j, 0] <= dist_segments[i] * outside_ratio) or \ + (dist_inter_to_segment1[i, j, 1] <= dist_segments[i] and \ + dist_inter_to_segment1[i, j, 0] <= dist_segments[i] * inside_ratio)) and \ + ((dist_inter_to_segment2[i, j, 1] >= dist_segments[j] and \ + dist_inter_to_segment2[i, j, 0] <= dist_segments[j] * outside_ratio) or \ + (dist_inter_to_segment2[i, j, 1] <= dist_segments[j] and \ + dist_inter_to_segment2[i, j, 0] <= dist_segments[j] * inside_ratio)) + + if check_degree and check_distance: + corner_info = None + + if (deg1 >= 0 and deg1 <= 45 and deg2 >= 45 and deg2 <= 120) or \ + (deg2 >= 315 and deg1 >= 45 and deg1 <= 120): + corner_info, color_info = 0, 'blue' + elif (deg1 >= 45 and deg1 <= 125 and deg2 >= 125 and deg2 <= 225): + corner_info, color_info = 1, 'green' + elif (deg1 >= 125 and deg1 <= 225 and deg2 >= 225 and deg2 <= 315): + corner_info, color_info = 2, 'black' + elif (deg1 >= 0 and deg1 <= 45 and deg2 >= 225 and deg2 <= 315) or \ + (deg2 >= 315 and deg1 >= 225 and deg1 <= 315): + corner_info, color_info = 3, 'cyan' + else: + corner_info, color_info = 4, 'red' # we don't use it + continue + + corner_dict[corner_info].append([x, y, i, j]) + inter_points.append([x, y]) + + square_list = [] + connect_list = [] + segments_list = [] + for corner0 in corner_dict[0]: + for corner1 in corner_dict[1]: + connect01 = False + for corner0_line in corner0[2:]: + if corner0_line in corner1[2:]: + connect01 = True + break + if connect01: + for corner2 in corner_dict[2]: + connect12 = False + for corner1_line in corner1[2:]: + if corner1_line in corner2[2:]: + connect12 = True + break + if connect12: + for corner3 in corner_dict[3]: + connect23 = False + for corner2_line in corner2[2:]: + if corner2_line in corner3[2:]: + connect23 = True + break + if connect23: + for corner3_line in corner3[2:]: + if corner3_line in corner0[2:]: + # SQUARE!!! + ''' + 0 -- 1 + | | + 3 -- 2 + square_list: + order: 0 > 1 > 2 > 3 + | x0, y0, x1, y1, x2, y2, x3, y3 | + | x0, y0, x1, y1, x2, y2, x3, y3 | + ... + connect_list: + order: 01 > 12 > 23 > 30 + | line_idx01, line_idx12, line_idx23, line_idx30 | + | line_idx01, line_idx12, line_idx23, line_idx30 | + ... + segments_list: + order: 0 > 1 > 2 > 3 + | line_idx0_i, line_idx0_j, line_idx1_i, line_idx1_j, line_idx2_i, line_idx2_j, line_idx3_i, line_idx3_j | + | line_idx0_i, line_idx0_j, line_idx1_i, line_idx1_j, line_idx2_i, line_idx2_j, line_idx3_i, line_idx3_j | + ... + ''' + square_list.append(corner0[:2] + corner1[:2] + corner2[:2] + corner3[:2]) + connect_list.append([corner0_line, corner1_line, corner2_line, corner3_line]) + segments_list.append(corner0[2:] + corner1[2:] + corner2[2:] + corner3[2:]) + + def check_outside_inside(segments_info, connect_idx): + # return 'outside or inside', min distance, cover_param, peri_param + if connect_idx == segments_info[0]: + check_dist_mat = dist_inter_to_segment1 + else: + check_dist_mat = dist_inter_to_segment2 + + i, j = segments_info + min_dist, max_dist = check_dist_mat[i, j, :] + connect_dist = dist_segments[connect_idx] + if max_dist > connect_dist: + return 'outside', min_dist, 0, 1 + else: + return 'inside', min_dist, -1, -1 + + top_square = None + + try: + map_size = input_shape[0] / 2 + squares = np.array(square_list).reshape([-1, 4, 2]) + score_array = [] + connect_array = np.array(connect_list) + segments_array = np.array(segments_list).reshape([-1, 4, 2]) + + # get degree of corners: + squares_rollup = np.roll(squares, 1, axis=1) + squares_rolldown = np.roll(squares, -1, axis=1) + vec1 = squares_rollup - squares + normalized_vec1 = vec1 / (np.linalg.norm(vec1, axis=-1, keepdims=True) + 1e-10) + vec2 = squares_rolldown - squares + normalized_vec2 = vec2 / (np.linalg.norm(vec2, axis=-1, keepdims=True) + 1e-10) + inner_products = np.sum(normalized_vec1 * normalized_vec2, axis=-1) # [n_squares, 4] + squares_degree = np.arccos(inner_products) * 180 / np.pi # [n_squares, 4] + + # get square score + overlap_scores = [] + degree_scores = [] + length_scores = [] + + for connects, segments, square, degree in zip(connect_array, segments_array, squares, squares_degree): + ''' + 0 -- 1 + | | + 3 -- 2 + + # segments: [4, 2] + # connects: [4] + ''' + + ###################################### OVERLAP SCORES + cover = 0 + perimeter = 0 + # check 0 > 1 > 2 > 3 + square_length = [] + + for start_idx in range(4): + end_idx = (start_idx + 1) % 4 + + connect_idx = connects[start_idx] # segment idx of segment01 + start_segments = segments[start_idx] + end_segments = segments[end_idx] + + start_point = square[start_idx] + end_point = square[end_idx] + + # check whether outside or inside + start_position, start_min, start_cover_param, start_peri_param = check_outside_inside(start_segments, + connect_idx) + end_position, end_min, end_cover_param, end_peri_param = check_outside_inside(end_segments, connect_idx) + + cover += dist_segments[connect_idx] + start_cover_param * start_min + end_cover_param * end_min + perimeter += dist_segments[connect_idx] + start_peri_param * start_min + end_peri_param * end_min + + square_length.append( + dist_segments[connect_idx] + start_peri_param * start_min + end_peri_param * end_min) + + overlap_scores.append(cover / perimeter) + ###################################### + ###################################### DEGREE SCORES + ''' + deg0 vs deg2 + deg1 vs deg3 + ''' + deg0, deg1, deg2, deg3 = degree + deg_ratio1 = deg0 / deg2 + if deg_ratio1 > 1.0: + deg_ratio1 = 1 / deg_ratio1 + deg_ratio2 = deg1 / deg3 + if deg_ratio2 > 1.0: + deg_ratio2 = 1 / deg_ratio2 + degree_scores.append((deg_ratio1 + deg_ratio2) / 2) + ###################################### + ###################################### LENGTH SCORES + ''' + len0 vs len2 + len1 vs len3 + ''' + len0, len1, len2, len3 = square_length + len_ratio1 = len0 / len2 if len2 > len0 else len2 / len0 + len_ratio2 = len1 / len3 if len3 > len1 else len3 / len1 + length_scores.append((len_ratio1 + len_ratio2) / 2) + + ###################################### + + overlap_scores = np.array(overlap_scores) + overlap_scores /= np.max(overlap_scores) + + degree_scores = np.array(degree_scores) + # degree_scores /= np.max(degree_scores) + + length_scores = np.array(length_scores) + + ###################################### AREA SCORES + area_scores = np.reshape(squares, [-1, 4, 2]) + area_x = area_scores[:, :, 0] + area_y = area_scores[:, :, 1] + correction = area_x[:, -1] * area_y[:, 0] - area_y[:, -1] * area_x[:, 0] + area_scores = np.sum(area_x[:, :-1] * area_y[:, 1:], axis=-1) - np.sum(area_y[:, :-1] * area_x[:, 1:], axis=-1) + area_scores = 0.5 * np.abs(area_scores + correction) + area_scores /= (map_size * map_size) # np.max(area_scores) + ###################################### + + ###################################### CENTER SCORES + centers = np.array([[256 // 2, 256 // 2]], dtype='float32') # [1, 2] + # squares: [n, 4, 2] + square_centers = np.mean(squares, axis=1) # [n, 2] + center2center = np.sqrt(np.sum((centers - square_centers) ** 2)) + center_scores = center2center / (map_size / np.sqrt(2.0)) + + ''' + score_w = [overlap, degree, area, center, length] + ''' + score_w = [0.0, 1.0, 10.0, 0.5, 1.0] + score_array = params['w_overlap'] * overlap_scores \ + + params['w_degree'] * degree_scores \ + + params['w_area'] * area_scores \ + - params['w_center'] * center_scores \ + + params['w_length'] * length_scores + + best_square = [] + + sorted_idx = np.argsort(score_array)[::-1] + score_array = score_array[sorted_idx] + squares = squares[sorted_idx] + + except Exception as e: + pass + + '''return list + merged_lines, squares, scores + ''' + + try: + new_segments[:, 0] = new_segments[:, 0] * 2 / input_shape[1] * original_shape[1] + new_segments[:, 1] = new_segments[:, 1] * 2 / input_shape[0] * original_shape[0] + new_segments[:, 2] = new_segments[:, 2] * 2 / input_shape[1] * original_shape[1] + new_segments[:, 3] = new_segments[:, 3] * 2 / input_shape[0] * original_shape[0] + except: + new_segments = [] + + try: + squares[:, :, 0] = squares[:, :, 0] * 2 / input_shape[1] * original_shape[1] + squares[:, :, 1] = squares[:, :, 1] * 2 / input_shape[0] * original_shape[0] + except: + squares = [] + score_array = [] + + try: + inter_points = np.array(inter_points) + inter_points[:, 0] = inter_points[:, 0] * 2 / input_shape[1] * original_shape[1] + inter_points[:, 1] = inter_points[:, 1] * 2 / input_shape[0] * original_shape[0] + except: + inter_points = [] + + return new_segments, squares, score_array, inter_points diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/__init__.py new file mode 100644 index 00000000..210a2989 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/__init__.py @@ -0,0 +1,15 @@ +# Copyright (c) OpenMMLab. All rights reserved. +# flake8: noqa +from .arraymisc import * +from .fileio import * +from .image import * +from .utils import * +from .version import * +from .video import * +from .visualization import * + +# The following modules are not imported to this level, so mmcv may be used +# without PyTorch. +# - runner +# - parallel +# - op diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/arraymisc/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/arraymisc/__init__.py new file mode 100644 index 00000000..4b4700d6 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/arraymisc/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .quantization import dequantize, quantize + +__all__ = ['quantize', 'dequantize'] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/arraymisc/quantization.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/arraymisc/quantization.py new file mode 100644 index 00000000..8e47a354 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/arraymisc/quantization.py @@ -0,0 +1,55 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import numpy as np + + +def quantize(arr, min_val, max_val, levels, dtype=np.int64): + """Quantize an array of (-inf, inf) to [0, levels-1]. + + Args: + arr (ndarray): Input array. + min_val (scalar): Minimum value to be clipped. + max_val (scalar): Maximum value to be clipped. + levels (int): Quantization levels. + dtype (np.type): The type of the quantized array. + + Returns: + tuple: Quantized array. + """ + if not (isinstance(levels, int) and levels > 1): + raise ValueError( + f'levels must be a positive integer, but got {levels}') + if min_val >= max_val: + raise ValueError( + f'min_val ({min_val}) must be smaller than max_val ({max_val})') + + arr = np.clip(arr, min_val, max_val) - min_val + quantized_arr = np.minimum( + np.floor(levels * arr / (max_val - min_val)).astype(dtype), levels - 1) + + return quantized_arr + + +def dequantize(arr, min_val, max_val, levels, dtype=np.float64): + """Dequantize an array. + + Args: + arr (ndarray): Input array. + min_val (scalar): Minimum value to be clipped. + max_val (scalar): Maximum value to be clipped. + levels (int): Quantization levels. + dtype (np.type): The type of the dequantized array. + + Returns: + tuple: Dequantized array. + """ + if not (isinstance(levels, int) and levels > 1): + raise ValueError( + f'levels must be a positive integer, but got {levels}') + if min_val >= max_val: + raise ValueError( + f'min_val ({min_val}) must be smaller than max_val ({max_val})') + + dequantized_arr = (arr + 0.5).astype(dtype) * (max_val - + min_val) / levels + min_val + + return dequantized_arr diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/__init__.py new file mode 100644 index 00000000..7246c897 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/__init__.py @@ -0,0 +1,41 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .alexnet import AlexNet +# yapf: disable +from .bricks import (ACTIVATION_LAYERS, CONV_LAYERS, NORM_LAYERS, + PADDING_LAYERS, PLUGIN_LAYERS, UPSAMPLE_LAYERS, + ContextBlock, Conv2d, Conv3d, ConvAWS2d, ConvModule, + ConvTranspose2d, ConvTranspose3d, ConvWS2d, + DepthwiseSeparableConvModule, GeneralizedAttention, + HSigmoid, HSwish, Linear, MaxPool2d, MaxPool3d, + NonLocal1d, NonLocal2d, NonLocal3d, Scale, Swish, + build_activation_layer, build_conv_layer, + build_norm_layer, build_padding_layer, build_plugin_layer, + build_upsample_layer, conv_ws_2d, is_norm) +from .builder import MODELS, build_model_from_cfg +# yapf: enable +from .resnet import ResNet, make_res_layer +from .utils import (INITIALIZERS, Caffe2XavierInit, ConstantInit, KaimingInit, + NormalInit, PretrainedInit, TruncNormalInit, UniformInit, + XavierInit, bias_init_with_prob, caffe2_xavier_init, + constant_init, fuse_conv_bn, get_model_complexity_info, + initialize, kaiming_init, normal_init, trunc_normal_init, + uniform_init, xavier_init) +from .vgg import VGG, make_vgg_layer + +__all__ = [ + 'AlexNet', 'VGG', 'make_vgg_layer', 'ResNet', 'make_res_layer', + 'constant_init', 'xavier_init', 'normal_init', 'trunc_normal_init', + 'uniform_init', 'kaiming_init', 'caffe2_xavier_init', + 'bias_init_with_prob', 'ConvModule', 'build_activation_layer', + 'build_conv_layer', 'build_norm_layer', 'build_padding_layer', + 'build_upsample_layer', 'build_plugin_layer', 'is_norm', 'NonLocal1d', + 'NonLocal2d', 'NonLocal3d', 'ContextBlock', 'HSigmoid', 'Swish', 'HSwish', + 'GeneralizedAttention', 'ACTIVATION_LAYERS', 'CONV_LAYERS', 'NORM_LAYERS', + 'PADDING_LAYERS', 'UPSAMPLE_LAYERS', 'PLUGIN_LAYERS', 'Scale', + 'get_model_complexity_info', 'conv_ws_2d', 'ConvAWS2d', 'ConvWS2d', + 'fuse_conv_bn', 'DepthwiseSeparableConvModule', 'Linear', 'Conv2d', + 'ConvTranspose2d', 'MaxPool2d', 'ConvTranspose3d', 'MaxPool3d', 'Conv3d', + 'initialize', 'INITIALIZERS', 'ConstantInit', 'XavierInit', 'NormalInit', + 'TruncNormalInit', 'UniformInit', 'KaimingInit', 'PretrainedInit', + 'Caffe2XavierInit', 'MODELS', 'build_model_from_cfg' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/alexnet.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/alexnet.py new file mode 100644 index 00000000..89e36b8c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/alexnet.py @@ -0,0 +1,61 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import logging + +import torch.nn as nn + + +class AlexNet(nn.Module): + """AlexNet backbone. + + Args: + num_classes (int): number of classes for classification. + """ + + def __init__(self, num_classes=-1): + super(AlexNet, self).__init__() + self.num_classes = num_classes + self.features = nn.Sequential( + nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=3, stride=2), + nn.Conv2d(64, 192, kernel_size=5, padding=2), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=3, stride=2), + nn.Conv2d(192, 384, kernel_size=3, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(384, 256, kernel_size=3, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(256, 256, kernel_size=3, padding=1), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=3, stride=2), + ) + if self.num_classes > 0: + self.classifier = nn.Sequential( + nn.Dropout(), + nn.Linear(256 * 6 * 6, 4096), + nn.ReLU(inplace=True), + nn.Dropout(), + nn.Linear(4096, 4096), + nn.ReLU(inplace=True), + nn.Linear(4096, num_classes), + ) + + def init_weights(self, pretrained=None): + if isinstance(pretrained, str): + logger = logging.getLogger() + from ..runner import load_checkpoint + load_checkpoint(self, pretrained, strict=False, logger=logger) + elif pretrained is None: + # use default initializer + pass + else: + raise TypeError('pretrained must be a str or None') + + def forward(self, x): + + x = self.features(x) + if self.num_classes > 0: + x = x.view(x.size(0), 256 * 6 * 6) + x = self.classifier(x) + + return x diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/__init__.py new file mode 100644 index 00000000..0f33124e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/__init__.py @@ -0,0 +1,35 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .activation import build_activation_layer +from .context_block import ContextBlock +from .conv import build_conv_layer +from .conv2d_adaptive_padding import Conv2dAdaptivePadding +from .conv_module import ConvModule +from .conv_ws import ConvAWS2d, ConvWS2d, conv_ws_2d +from .depthwise_separable_conv_module import DepthwiseSeparableConvModule +from .drop import Dropout, DropPath +from .generalized_attention import GeneralizedAttention +from .hsigmoid import HSigmoid +from .hswish import HSwish +from .non_local import NonLocal1d, NonLocal2d, NonLocal3d +from .norm import build_norm_layer, is_norm +from .padding import build_padding_layer +from .plugin import build_plugin_layer +from .registry import (ACTIVATION_LAYERS, CONV_LAYERS, NORM_LAYERS, + PADDING_LAYERS, PLUGIN_LAYERS, UPSAMPLE_LAYERS) +from .scale import Scale +from .swish import Swish +from .upsample import build_upsample_layer +from .wrappers import (Conv2d, Conv3d, ConvTranspose2d, ConvTranspose3d, + Linear, MaxPool2d, MaxPool3d) + +__all__ = [ + 'ConvModule', 'build_activation_layer', 'build_conv_layer', + 'build_norm_layer', 'build_padding_layer', 'build_upsample_layer', + 'build_plugin_layer', 'is_norm', 'HSigmoid', 'HSwish', 'NonLocal1d', + 'NonLocal2d', 'NonLocal3d', 'ContextBlock', 'GeneralizedAttention', + 'ACTIVATION_LAYERS', 'CONV_LAYERS', 'NORM_LAYERS', 'PADDING_LAYERS', + 'UPSAMPLE_LAYERS', 'PLUGIN_LAYERS', 'Scale', 'ConvAWS2d', 'ConvWS2d', + 'conv_ws_2d', 'DepthwiseSeparableConvModule', 'Swish', 'Linear', + 'Conv2dAdaptivePadding', 'Conv2d', 'ConvTranspose2d', 'MaxPool2d', + 'ConvTranspose3d', 'MaxPool3d', 'Conv3d', 'Dropout', 'DropPath' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/activation.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/activation.py new file mode 100644 index 00000000..a8951058 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/activation.py @@ -0,0 +1,92 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.nn as nn +import torch.nn.functional as F + +from annotator.mmpkg.mmcv.utils import TORCH_VERSION, build_from_cfg, digit_version +from .registry import ACTIVATION_LAYERS + +for module in [ + nn.ReLU, nn.LeakyReLU, nn.PReLU, nn.RReLU, nn.ReLU6, nn.ELU, + nn.Sigmoid, nn.Tanh +]: + ACTIVATION_LAYERS.register_module(module=module) + + +@ACTIVATION_LAYERS.register_module(name='Clip') +@ACTIVATION_LAYERS.register_module() +class Clamp(nn.Module): + """Clamp activation layer. + + This activation function is to clamp the feature map value within + :math:`[min, max]`. More details can be found in ``torch.clamp()``. + + Args: + min (Number | optional): Lower-bound of the range to be clamped to. + Default to -1. + max (Number | optional): Upper-bound of the range to be clamped to. + Default to 1. + """ + + def __init__(self, min=-1., max=1.): + super(Clamp, self).__init__() + self.min = min + self.max = max + + def forward(self, x): + """Forward function. + + Args: + x (torch.Tensor): The input tensor. + + Returns: + torch.Tensor: Clamped tensor. + """ + return torch.clamp(x, min=self.min, max=self.max) + + +class GELU(nn.Module): + r"""Applies the Gaussian Error Linear Units function: + + .. math:: + \text{GELU}(x) = x * \Phi(x) + where :math:`\Phi(x)` is the Cumulative Distribution Function for + Gaussian Distribution. + + Shape: + - Input: :math:`(N, *)` where `*` means, any number of additional + dimensions + - Output: :math:`(N, *)`, same shape as the input + + .. image:: scripts/activation_images/GELU.png + + Examples:: + + >>> m = nn.GELU() + >>> input = torch.randn(2) + >>> output = m(input) + """ + + def forward(self, input): + return F.gelu(input) + + +if (TORCH_VERSION == 'parrots' + or digit_version(TORCH_VERSION) < digit_version('1.4')): + ACTIVATION_LAYERS.register_module(module=GELU) +else: + ACTIVATION_LAYERS.register_module(module=nn.GELU) + + +def build_activation_layer(cfg): + """Build activation layer. + + Args: + cfg (dict): The activation layer config, which should contain: + - type (str): Layer type. + - layer args: Args needed to instantiate an activation layer. + + Returns: + nn.Module: Created activation layer. + """ + return build_from_cfg(cfg, ACTIVATION_LAYERS) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/context_block.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/context_block.py new file mode 100644 index 00000000..d60fdb90 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/context_block.py @@ -0,0 +1,125 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +from torch import nn + +from ..utils import constant_init, kaiming_init +from .registry import PLUGIN_LAYERS + + +def last_zero_init(m): + if isinstance(m, nn.Sequential): + constant_init(m[-1], val=0) + else: + constant_init(m, val=0) + + +@PLUGIN_LAYERS.register_module() +class ContextBlock(nn.Module): + """ContextBlock module in GCNet. + + See 'GCNet: Non-local Networks Meet Squeeze-Excitation Networks and Beyond' + (https://arxiv.org/abs/1904.11492) for details. + + Args: + in_channels (int): Channels of the input feature map. + ratio (float): Ratio of channels of transform bottleneck + pooling_type (str): Pooling method for context modeling. + Options are 'att' and 'avg', stand for attention pooling and + average pooling respectively. Default: 'att'. + fusion_types (Sequence[str]): Fusion method for feature fusion, + Options are 'channels_add', 'channel_mul', stand for channelwise + addition and multiplication respectively. Default: ('channel_add',) + """ + + _abbr_ = 'context_block' + + def __init__(self, + in_channels, + ratio, + pooling_type='att', + fusion_types=('channel_add', )): + super(ContextBlock, self).__init__() + assert pooling_type in ['avg', 'att'] + assert isinstance(fusion_types, (list, tuple)) + valid_fusion_types = ['channel_add', 'channel_mul'] + assert all([f in valid_fusion_types for f in fusion_types]) + assert len(fusion_types) > 0, 'at least one fusion should be used' + self.in_channels = in_channels + self.ratio = ratio + self.planes = int(in_channels * ratio) + self.pooling_type = pooling_type + self.fusion_types = fusion_types + if pooling_type == 'att': + self.conv_mask = nn.Conv2d(in_channels, 1, kernel_size=1) + self.softmax = nn.Softmax(dim=2) + else: + self.avg_pool = nn.AdaptiveAvgPool2d(1) + if 'channel_add' in fusion_types: + self.channel_add_conv = nn.Sequential( + nn.Conv2d(self.in_channels, self.planes, kernel_size=1), + nn.LayerNorm([self.planes, 1, 1]), + nn.ReLU(inplace=True), # yapf: disable + nn.Conv2d(self.planes, self.in_channels, kernel_size=1)) + else: + self.channel_add_conv = None + if 'channel_mul' in fusion_types: + self.channel_mul_conv = nn.Sequential( + nn.Conv2d(self.in_channels, self.planes, kernel_size=1), + nn.LayerNorm([self.planes, 1, 1]), + nn.ReLU(inplace=True), # yapf: disable + nn.Conv2d(self.planes, self.in_channels, kernel_size=1)) + else: + self.channel_mul_conv = None + self.reset_parameters() + + def reset_parameters(self): + if self.pooling_type == 'att': + kaiming_init(self.conv_mask, mode='fan_in') + self.conv_mask.inited = True + + if self.channel_add_conv is not None: + last_zero_init(self.channel_add_conv) + if self.channel_mul_conv is not None: + last_zero_init(self.channel_mul_conv) + + def spatial_pool(self, x): + batch, channel, height, width = x.size() + if self.pooling_type == 'att': + input_x = x + # [N, C, H * W] + input_x = input_x.view(batch, channel, height * width) + # [N, 1, C, H * W] + input_x = input_x.unsqueeze(1) + # [N, 1, H, W] + context_mask = self.conv_mask(x) + # [N, 1, H * W] + context_mask = context_mask.view(batch, 1, height * width) + # [N, 1, H * W] + context_mask = self.softmax(context_mask) + # [N, 1, H * W, 1] + context_mask = context_mask.unsqueeze(-1) + # [N, 1, C, 1] + context = torch.matmul(input_x, context_mask) + # [N, C, 1, 1] + context = context.view(batch, channel, 1, 1) + else: + # [N, C, 1, 1] + context = self.avg_pool(x) + + return context + + def forward(self, x): + # [N, C, 1, 1] + context = self.spatial_pool(x) + + out = x + if self.channel_mul_conv is not None: + # [N, C, 1, 1] + channel_mul_term = torch.sigmoid(self.channel_mul_conv(context)) + out = out * channel_mul_term + if self.channel_add_conv is not None: + # [N, C, 1, 1] + channel_add_term = self.channel_add_conv(context) + out = out + channel_add_term + + return out diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/conv.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/conv.py new file mode 100644 index 00000000..cf544919 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/conv.py @@ -0,0 +1,44 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from torch import nn + +from .registry import CONV_LAYERS + +CONV_LAYERS.register_module('Conv1d', module=nn.Conv1d) +CONV_LAYERS.register_module('Conv2d', module=nn.Conv2d) +CONV_LAYERS.register_module('Conv3d', module=nn.Conv3d) +CONV_LAYERS.register_module('Conv', module=nn.Conv2d) + + +def build_conv_layer(cfg, *args, **kwargs): + """Build convolution layer. + + Args: + cfg (None or dict): The conv layer config, which should contain: + - type (str): Layer type. + - layer args: Args needed to instantiate an conv layer. + args (argument list): Arguments passed to the `__init__` + method of the corresponding conv layer. + kwargs (keyword arguments): Keyword arguments passed to the `__init__` + method of the corresponding conv layer. + + Returns: + nn.Module: Created conv layer. + """ + if cfg is None: + cfg_ = dict(type='Conv2d') + else: + if not isinstance(cfg, dict): + raise TypeError('cfg must be a dict') + if 'type' not in cfg: + raise KeyError('the cfg dict must contain the key "type"') + cfg_ = cfg.copy() + + layer_type = cfg_.pop('type') + if layer_type not in CONV_LAYERS: + raise KeyError(f'Unrecognized norm type {layer_type}') + else: + conv_layer = CONV_LAYERS.get(layer_type) + + layer = conv_layer(*args, **kwargs, **cfg_) + + return layer diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/conv2d_adaptive_padding.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/conv2d_adaptive_padding.py new file mode 100644 index 00000000..b45e758a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/conv2d_adaptive_padding.py @@ -0,0 +1,62 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import math + +from torch import nn +from torch.nn import functional as F + +from .registry import CONV_LAYERS + + +@CONV_LAYERS.register_module() +class Conv2dAdaptivePadding(nn.Conv2d): + """Implementation of 2D convolution in tensorflow with `padding` as "same", + which applies padding to input (if needed) so that input image gets fully + covered by filter and stride you specified. For stride 1, this will ensure + that output image size is same as input. For stride of 2, output dimensions + will be half, for example. + + Args: + in_channels (int): Number of channels in the input image + out_channels (int): Number of channels produced by the convolution + kernel_size (int or tuple): Size of the convolving kernel + stride (int or tuple, optional): Stride of the convolution. Default: 1 + padding (int or tuple, optional): Zero-padding added to both sides of + the input. Default: 0 + dilation (int or tuple, optional): Spacing between kernel elements. + Default: 1 + groups (int, optional): Number of blocked connections from input + channels to output channels. Default: 1 + bias (bool, optional): If ``True``, adds a learnable bias to the + output. Default: ``True`` + """ + + def __init__(self, + in_channels, + out_channels, + kernel_size, + stride=1, + padding=0, + dilation=1, + groups=1, + bias=True): + super().__init__(in_channels, out_channels, kernel_size, stride, 0, + dilation, groups, bias) + + def forward(self, x): + img_h, img_w = x.size()[-2:] + kernel_h, kernel_w = self.weight.size()[-2:] + stride_h, stride_w = self.stride + output_h = math.ceil(img_h / stride_h) + output_w = math.ceil(img_w / stride_w) + pad_h = ( + max((output_h - 1) * self.stride[0] + + (kernel_h - 1) * self.dilation[0] + 1 - img_h, 0)) + pad_w = ( + max((output_w - 1) * self.stride[1] + + (kernel_w - 1) * self.dilation[1] + 1 - img_w, 0)) + if pad_h > 0 or pad_w > 0: + x = F.pad(x, [ + pad_w // 2, pad_w - pad_w // 2, pad_h // 2, pad_h - pad_h // 2 + ]) + return F.conv2d(x, self.weight, self.bias, self.stride, self.padding, + self.dilation, self.groups) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/conv_module.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/conv_module.py new file mode 100644 index 00000000..43cab726 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/conv_module.py @@ -0,0 +1,206 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import warnings + +import torch.nn as nn + +from annotator.mmpkg.mmcv.utils import _BatchNorm, _InstanceNorm +from ..utils import constant_init, kaiming_init +from .activation import build_activation_layer +from .conv import build_conv_layer +from .norm import build_norm_layer +from .padding import build_padding_layer +from .registry import PLUGIN_LAYERS + + +@PLUGIN_LAYERS.register_module() +class ConvModule(nn.Module): + """A conv block that bundles conv/norm/activation layers. + + This block simplifies the usage of convolution layers, which are commonly + used with a norm layer (e.g., BatchNorm) and activation layer (e.g., ReLU). + It is based upon three build methods: `build_conv_layer()`, + `build_norm_layer()` and `build_activation_layer()`. + + Besides, we add some additional features in this module. + 1. Automatically set `bias` of the conv layer. + 2. Spectral norm is supported. + 3. More padding modes are supported. Before PyTorch 1.5, nn.Conv2d only + supports zero and circular padding, and we add "reflect" padding mode. + + Args: + in_channels (int): Number of channels in the input feature map. + Same as that in ``nn._ConvNd``. + out_channels (int): Number of channels produced by the convolution. + Same as that in ``nn._ConvNd``. + kernel_size (int | tuple[int]): Size of the convolving kernel. + Same as that in ``nn._ConvNd``. + stride (int | tuple[int]): Stride of the convolution. + Same as that in ``nn._ConvNd``. + padding (int | tuple[int]): Zero-padding added to both sides of + the input. Same as that in ``nn._ConvNd``. + dilation (int | tuple[int]): Spacing between kernel elements. + Same as that in ``nn._ConvNd``. + groups (int): Number of blocked connections from input channels to + output channels. Same as that in ``nn._ConvNd``. + bias (bool | str): If specified as `auto`, it will be decided by the + norm_cfg. Bias will be set as True if `norm_cfg` is None, otherwise + False. Default: "auto". + conv_cfg (dict): Config dict for convolution layer. Default: None, + which means using conv2d. + norm_cfg (dict): Config dict for normalization layer. Default: None. + act_cfg (dict): Config dict for activation layer. + Default: dict(type='ReLU'). + inplace (bool): Whether to use inplace mode for activation. + Default: True. + with_spectral_norm (bool): Whether use spectral norm in conv module. + Default: False. + padding_mode (str): If the `padding_mode` has not been supported by + current `Conv2d` in PyTorch, we will use our own padding layer + instead. Currently, we support ['zeros', 'circular'] with official + implementation and ['reflect'] with our own implementation. + Default: 'zeros'. + order (tuple[str]): The order of conv/norm/activation layers. It is a + sequence of "conv", "norm" and "act". Common examples are + ("conv", "norm", "act") and ("act", "conv", "norm"). + Default: ('conv', 'norm', 'act'). + """ + + _abbr_ = 'conv_block' + + def __init__(self, + in_channels, + out_channels, + kernel_size, + stride=1, + padding=0, + dilation=1, + groups=1, + bias='auto', + conv_cfg=None, + norm_cfg=None, + act_cfg=dict(type='ReLU'), + inplace=True, + with_spectral_norm=False, + padding_mode='zeros', + order=('conv', 'norm', 'act')): + super(ConvModule, self).__init__() + assert conv_cfg is None or isinstance(conv_cfg, dict) + assert norm_cfg is None or isinstance(norm_cfg, dict) + assert act_cfg is None or isinstance(act_cfg, dict) + official_padding_mode = ['zeros', 'circular'] + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + self.inplace = inplace + self.with_spectral_norm = with_spectral_norm + self.with_explicit_padding = padding_mode not in official_padding_mode + self.order = order + assert isinstance(self.order, tuple) and len(self.order) == 3 + assert set(order) == set(['conv', 'norm', 'act']) + + self.with_norm = norm_cfg is not None + self.with_activation = act_cfg is not None + # if the conv layer is before a norm layer, bias is unnecessary. + if bias == 'auto': + bias = not self.with_norm + self.with_bias = bias + + if self.with_explicit_padding: + pad_cfg = dict(type=padding_mode) + self.padding_layer = build_padding_layer(pad_cfg, padding) + + # reset padding to 0 for conv module + conv_padding = 0 if self.with_explicit_padding else padding + # build convolution layer + self.conv = build_conv_layer( + conv_cfg, + in_channels, + out_channels, + kernel_size, + stride=stride, + padding=conv_padding, + dilation=dilation, + groups=groups, + bias=bias) + # export the attributes of self.conv to a higher level for convenience + self.in_channels = self.conv.in_channels + self.out_channels = self.conv.out_channels + self.kernel_size = self.conv.kernel_size + self.stride = self.conv.stride + self.padding = padding + self.dilation = self.conv.dilation + self.transposed = self.conv.transposed + self.output_padding = self.conv.output_padding + self.groups = self.conv.groups + + if self.with_spectral_norm: + self.conv = nn.utils.spectral_norm(self.conv) + + # build normalization layers + if self.with_norm: + # norm layer is after conv layer + if order.index('norm') > order.index('conv'): + norm_channels = out_channels + else: + norm_channels = in_channels + self.norm_name, norm = build_norm_layer(norm_cfg, norm_channels) + self.add_module(self.norm_name, norm) + if self.with_bias: + if isinstance(norm, (_BatchNorm, _InstanceNorm)): + warnings.warn( + 'Unnecessary conv bias before batch/instance norm') + else: + self.norm_name = None + + # build activation layer + if self.with_activation: + act_cfg_ = act_cfg.copy() + # nn.Tanh has no 'inplace' argument + if act_cfg_['type'] not in [ + 'Tanh', 'PReLU', 'Sigmoid', 'HSigmoid', 'Swish' + ]: + act_cfg_.setdefault('inplace', inplace) + self.activate = build_activation_layer(act_cfg_) + + # Use msra init by default + self.init_weights() + + @property + def norm(self): + if self.norm_name: + return getattr(self, self.norm_name) + else: + return None + + def init_weights(self): + # 1. It is mainly for customized conv layers with their own + # initialization manners by calling their own ``init_weights()``, + # and we do not want ConvModule to override the initialization. + # 2. For customized conv layers without their own initialization + # manners (that is, they don't have their own ``init_weights()``) + # and PyTorch's conv layers, they will be initialized by + # this method with default ``kaiming_init``. + # Note: For PyTorch's conv layers, they will be overwritten by our + # initialization implementation using default ``kaiming_init``. + if not hasattr(self.conv, 'init_weights'): + if self.with_activation and self.act_cfg['type'] == 'LeakyReLU': + nonlinearity = 'leaky_relu' + a = self.act_cfg.get('negative_slope', 0.01) + else: + nonlinearity = 'relu' + a = 0 + kaiming_init(self.conv, a=a, nonlinearity=nonlinearity) + if self.with_norm: + constant_init(self.norm, 1, bias=0) + + def forward(self, x, activate=True, norm=True): + for layer in self.order: + if layer == 'conv': + if self.with_explicit_padding: + x = self.padding_layer(x) + x = self.conv(x) + elif layer == 'norm' and norm and self.with_norm: + x = self.norm(x) + elif layer == 'act' and activate and self.with_activation: + x = self.activate(x) + return x diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/conv_ws.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/conv_ws.py new file mode 100644 index 00000000..a3941e27 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/conv_ws.py @@ -0,0 +1,148 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.nn as nn +import torch.nn.functional as F + +from .registry import CONV_LAYERS + + +def conv_ws_2d(input, + weight, + bias=None, + stride=1, + padding=0, + dilation=1, + groups=1, + eps=1e-5): + c_in = weight.size(0) + weight_flat = weight.view(c_in, -1) + mean = weight_flat.mean(dim=1, keepdim=True).view(c_in, 1, 1, 1) + std = weight_flat.std(dim=1, keepdim=True).view(c_in, 1, 1, 1) + weight = (weight - mean) / (std + eps) + return F.conv2d(input, weight, bias, stride, padding, dilation, groups) + + +@CONV_LAYERS.register_module('ConvWS') +class ConvWS2d(nn.Conv2d): + + def __init__(self, + in_channels, + out_channels, + kernel_size, + stride=1, + padding=0, + dilation=1, + groups=1, + bias=True, + eps=1e-5): + super(ConvWS2d, self).__init__( + in_channels, + out_channels, + kernel_size, + stride=stride, + padding=padding, + dilation=dilation, + groups=groups, + bias=bias) + self.eps = eps + + def forward(self, x): + return conv_ws_2d(x, self.weight, self.bias, self.stride, self.padding, + self.dilation, self.groups, self.eps) + + +@CONV_LAYERS.register_module(name='ConvAWS') +class ConvAWS2d(nn.Conv2d): + """AWS (Adaptive Weight Standardization) + + This is a variant of Weight Standardization + (https://arxiv.org/pdf/1903.10520.pdf) + It is used in DetectoRS to avoid NaN + (https://arxiv.org/pdf/2006.02334.pdf) + + Args: + in_channels (int): Number of channels in the input image + out_channels (int): Number of channels produced by the convolution + kernel_size (int or tuple): Size of the conv kernel + stride (int or tuple, optional): Stride of the convolution. Default: 1 + padding (int or tuple, optional): Zero-padding added to both sides of + the input. Default: 0 + dilation (int or tuple, optional): Spacing between kernel elements. + Default: 1 + groups (int, optional): Number of blocked connections from input + channels to output channels. Default: 1 + bias (bool, optional): If set True, adds a learnable bias to the + output. Default: True + """ + + def __init__(self, + in_channels, + out_channels, + kernel_size, + stride=1, + padding=0, + dilation=1, + groups=1, + bias=True): + super().__init__( + in_channels, + out_channels, + kernel_size, + stride=stride, + padding=padding, + dilation=dilation, + groups=groups, + bias=bias) + self.register_buffer('weight_gamma', + torch.ones(self.out_channels, 1, 1, 1)) + self.register_buffer('weight_beta', + torch.zeros(self.out_channels, 1, 1, 1)) + + def _get_weight(self, weight): + weight_flat = weight.view(weight.size(0), -1) + mean = weight_flat.mean(dim=1).view(-1, 1, 1, 1) + std = torch.sqrt(weight_flat.var(dim=1) + 1e-5).view(-1, 1, 1, 1) + weight = (weight - mean) / std + weight = self.weight_gamma * weight + self.weight_beta + return weight + + def forward(self, x): + weight = self._get_weight(self.weight) + return F.conv2d(x, weight, self.bias, self.stride, self.padding, + self.dilation, self.groups) + + def _load_from_state_dict(self, state_dict, prefix, local_metadata, strict, + missing_keys, unexpected_keys, error_msgs): + """Override default load function. + + AWS overrides the function _load_from_state_dict to recover + weight_gamma and weight_beta if they are missing. If weight_gamma and + weight_beta are found in the checkpoint, this function will return + after super()._load_from_state_dict. Otherwise, it will compute the + mean and std of the pretrained weights and store them in weight_beta + and weight_gamma. + """ + + self.weight_gamma.data.fill_(-1) + local_missing_keys = [] + super()._load_from_state_dict(state_dict, prefix, local_metadata, + strict, local_missing_keys, + unexpected_keys, error_msgs) + if self.weight_gamma.data.mean() > 0: + for k in local_missing_keys: + missing_keys.append(k) + return + weight = self.weight.data + weight_flat = weight.view(weight.size(0), -1) + mean = weight_flat.mean(dim=1).view(-1, 1, 1, 1) + std = torch.sqrt(weight_flat.var(dim=1) + 1e-5).view(-1, 1, 1, 1) + self.weight_beta.data.copy_(mean) + self.weight_gamma.data.copy_(std) + missing_gamma_beta = [ + k for k in local_missing_keys + if k.endswith('weight_gamma') or k.endswith('weight_beta') + ] + for k in missing_gamma_beta: + local_missing_keys.remove(k) + for k in local_missing_keys: + missing_keys.append(k) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/depthwise_separable_conv_module.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/depthwise_separable_conv_module.py new file mode 100644 index 00000000..722d5d8d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/depthwise_separable_conv_module.py @@ -0,0 +1,96 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch.nn as nn + +from .conv_module import ConvModule + + +class DepthwiseSeparableConvModule(nn.Module): + """Depthwise separable convolution module. + + See https://arxiv.org/pdf/1704.04861.pdf for details. + + This module can replace a ConvModule with the conv block replaced by two + conv block: depthwise conv block and pointwise conv block. The depthwise + conv block contains depthwise-conv/norm/activation layers. The pointwise + conv block contains pointwise-conv/norm/activation layers. It should be + noted that there will be norm/activation layer in the depthwise conv block + if `norm_cfg` and `act_cfg` are specified. + + Args: + in_channels (int): Number of channels in the input feature map. + Same as that in ``nn._ConvNd``. + out_channels (int): Number of channels produced by the convolution. + Same as that in ``nn._ConvNd``. + kernel_size (int | tuple[int]): Size of the convolving kernel. + Same as that in ``nn._ConvNd``. + stride (int | tuple[int]): Stride of the convolution. + Same as that in ``nn._ConvNd``. Default: 1. + padding (int | tuple[int]): Zero-padding added to both sides of + the input. Same as that in ``nn._ConvNd``. Default: 0. + dilation (int | tuple[int]): Spacing between kernel elements. + Same as that in ``nn._ConvNd``. Default: 1. + norm_cfg (dict): Default norm config for both depthwise ConvModule and + pointwise ConvModule. Default: None. + act_cfg (dict): Default activation config for both depthwise ConvModule + and pointwise ConvModule. Default: dict(type='ReLU'). + dw_norm_cfg (dict): Norm config of depthwise ConvModule. If it is + 'default', it will be the same as `norm_cfg`. Default: 'default'. + dw_act_cfg (dict): Activation config of depthwise ConvModule. If it is + 'default', it will be the same as `act_cfg`. Default: 'default'. + pw_norm_cfg (dict): Norm config of pointwise ConvModule. If it is + 'default', it will be the same as `norm_cfg`. Default: 'default'. + pw_act_cfg (dict): Activation config of pointwise ConvModule. If it is + 'default', it will be the same as `act_cfg`. Default: 'default'. + kwargs (optional): Other shared arguments for depthwise and pointwise + ConvModule. See ConvModule for ref. + """ + + def __init__(self, + in_channels, + out_channels, + kernel_size, + stride=1, + padding=0, + dilation=1, + norm_cfg=None, + act_cfg=dict(type='ReLU'), + dw_norm_cfg='default', + dw_act_cfg='default', + pw_norm_cfg='default', + pw_act_cfg='default', + **kwargs): + super(DepthwiseSeparableConvModule, self).__init__() + assert 'groups' not in kwargs, 'groups should not be specified' + + # if norm/activation config of depthwise/pointwise ConvModule is not + # specified, use default config. + dw_norm_cfg = dw_norm_cfg if dw_norm_cfg != 'default' else norm_cfg + dw_act_cfg = dw_act_cfg if dw_act_cfg != 'default' else act_cfg + pw_norm_cfg = pw_norm_cfg if pw_norm_cfg != 'default' else norm_cfg + pw_act_cfg = pw_act_cfg if pw_act_cfg != 'default' else act_cfg + + # depthwise convolution + self.depthwise_conv = ConvModule( + in_channels, + in_channels, + kernel_size, + stride=stride, + padding=padding, + dilation=dilation, + groups=in_channels, + norm_cfg=dw_norm_cfg, + act_cfg=dw_act_cfg, + **kwargs) + + self.pointwise_conv = ConvModule( + in_channels, + out_channels, + 1, + norm_cfg=pw_norm_cfg, + act_cfg=pw_act_cfg, + **kwargs) + + def forward(self, x): + x = self.depthwise_conv(x) + x = self.pointwise_conv(x) + return x diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/drop.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/drop.py new file mode 100644 index 00000000..465ed383 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/drop.py @@ -0,0 +1,65 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.nn as nn + +from annotator.mmpkg.mmcv import build_from_cfg +from .registry import DROPOUT_LAYERS + + +def drop_path(x, drop_prob=0., training=False): + """Drop paths (Stochastic Depth) per sample (when applied in main path of + residual blocks). + + We follow the implementation + https://github.com/rwightman/pytorch-image-models/blob/a2727c1bf78ba0d7b5727f5f95e37fb7f8866b1f/timm/models/layers/drop.py # noqa: E501 + """ + if drop_prob == 0. or not training: + return x + keep_prob = 1 - drop_prob + # handle tensors with different dimensions, not just 4D tensors. + shape = (x.shape[0], ) + (1, ) * (x.ndim - 1) + random_tensor = keep_prob + torch.rand( + shape, dtype=x.dtype, device=x.device) + output = x.div(keep_prob) * random_tensor.floor() + return output + + +@DROPOUT_LAYERS.register_module() +class DropPath(nn.Module): + """Drop paths (Stochastic Depth) per sample (when applied in main path of + residual blocks). + + We follow the implementation + https://github.com/rwightman/pytorch-image-models/blob/a2727c1bf78ba0d7b5727f5f95e37fb7f8866b1f/timm/models/layers/drop.py # noqa: E501 + + Args: + drop_prob (float): Probability of the path to be zeroed. Default: 0.1 + """ + + def __init__(self, drop_prob=0.1): + super(DropPath, self).__init__() + self.drop_prob = drop_prob + + def forward(self, x): + return drop_path(x, self.drop_prob, self.training) + + +@DROPOUT_LAYERS.register_module() +class Dropout(nn.Dropout): + """A wrapper for ``torch.nn.Dropout``, We rename the ``p`` of + ``torch.nn.Dropout`` to ``drop_prob`` so as to be consistent with + ``DropPath`` + + Args: + drop_prob (float): Probability of the elements to be + zeroed. Default: 0.5. + inplace (bool): Do the operation inplace or not. Default: False. + """ + + def __init__(self, drop_prob=0.5, inplace=False): + super().__init__(p=drop_prob, inplace=inplace) + + +def build_dropout(cfg, default_args=None): + """Builder for drop out layers.""" + return build_from_cfg(cfg, DROPOUT_LAYERS, default_args) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/generalized_attention.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/generalized_attention.py new file mode 100644 index 00000000..988d9adf --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/generalized_attention.py @@ -0,0 +1,412 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import math + +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F + +from ..utils import kaiming_init +from .registry import PLUGIN_LAYERS + + +@PLUGIN_LAYERS.register_module() +class GeneralizedAttention(nn.Module): + """GeneralizedAttention module. + + See 'An Empirical Study of Spatial Attention Mechanisms in Deep Networks' + (https://arxiv.org/abs/1711.07971) for details. + + Args: + in_channels (int): Channels of the input feature map. + spatial_range (int): The spatial range. -1 indicates no spatial range + constraint. Default: -1. + num_heads (int): The head number of empirical_attention module. + Default: 9. + position_embedding_dim (int): The position embedding dimension. + Default: -1. + position_magnitude (int): A multiplier acting on coord difference. + Default: 1. + kv_stride (int): The feature stride acting on key/value feature map. + Default: 2. + q_stride (int): The feature stride acting on query feature map. + Default: 1. + attention_type (str): A binary indicator string for indicating which + items in generalized empirical_attention module are used. + Default: '1111'. + + - '1000' indicates 'query and key content' (appr - appr) item, + - '0100' indicates 'query content and relative position' + (appr - position) item, + - '0010' indicates 'key content only' (bias - appr) item, + - '0001' indicates 'relative position only' (bias - position) item. + """ + + _abbr_ = 'gen_attention_block' + + def __init__(self, + in_channels, + spatial_range=-1, + num_heads=9, + position_embedding_dim=-1, + position_magnitude=1, + kv_stride=2, + q_stride=1, + attention_type='1111'): + + super(GeneralizedAttention, self).__init__() + + # hard range means local range for non-local operation + self.position_embedding_dim = ( + position_embedding_dim + if position_embedding_dim > 0 else in_channels) + + self.position_magnitude = position_magnitude + self.num_heads = num_heads + self.in_channels = in_channels + self.spatial_range = spatial_range + self.kv_stride = kv_stride + self.q_stride = q_stride + self.attention_type = [bool(int(_)) for _ in attention_type] + self.qk_embed_dim = in_channels // num_heads + out_c = self.qk_embed_dim * num_heads + + if self.attention_type[0] or self.attention_type[1]: + self.query_conv = nn.Conv2d( + in_channels=in_channels, + out_channels=out_c, + kernel_size=1, + bias=False) + self.query_conv.kaiming_init = True + + if self.attention_type[0] or self.attention_type[2]: + self.key_conv = nn.Conv2d( + in_channels=in_channels, + out_channels=out_c, + kernel_size=1, + bias=False) + self.key_conv.kaiming_init = True + + self.v_dim = in_channels // num_heads + self.value_conv = nn.Conv2d( + in_channels=in_channels, + out_channels=self.v_dim * num_heads, + kernel_size=1, + bias=False) + self.value_conv.kaiming_init = True + + if self.attention_type[1] or self.attention_type[3]: + self.appr_geom_fc_x = nn.Linear( + self.position_embedding_dim // 2, out_c, bias=False) + self.appr_geom_fc_x.kaiming_init = True + + self.appr_geom_fc_y = nn.Linear( + self.position_embedding_dim // 2, out_c, bias=False) + self.appr_geom_fc_y.kaiming_init = True + + if self.attention_type[2]: + stdv = 1.0 / math.sqrt(self.qk_embed_dim * 2) + appr_bias_value = -2 * stdv * torch.rand(out_c) + stdv + self.appr_bias = nn.Parameter(appr_bias_value) + + if self.attention_type[3]: + stdv = 1.0 / math.sqrt(self.qk_embed_dim * 2) + geom_bias_value = -2 * stdv * torch.rand(out_c) + stdv + self.geom_bias = nn.Parameter(geom_bias_value) + + self.proj_conv = nn.Conv2d( + in_channels=self.v_dim * num_heads, + out_channels=in_channels, + kernel_size=1, + bias=True) + self.proj_conv.kaiming_init = True + self.gamma = nn.Parameter(torch.zeros(1)) + + if self.spatial_range >= 0: + # only works when non local is after 3*3 conv + if in_channels == 256: + max_len = 84 + elif in_channels == 512: + max_len = 42 + + max_len_kv = int((max_len - 1.0) / self.kv_stride + 1) + local_constraint_map = np.ones( + (max_len, max_len, max_len_kv, max_len_kv), dtype=np.int) + for iy in range(max_len): + for ix in range(max_len): + local_constraint_map[ + iy, ix, + max((iy - self.spatial_range) // + self.kv_stride, 0):min((iy + self.spatial_range + + 1) // self.kv_stride + + 1, max_len), + max((ix - self.spatial_range) // + self.kv_stride, 0):min((ix + self.spatial_range + + 1) // self.kv_stride + + 1, max_len)] = 0 + + self.local_constraint_map = nn.Parameter( + torch.from_numpy(local_constraint_map).byte(), + requires_grad=False) + + if self.q_stride > 1: + self.q_downsample = nn.AvgPool2d( + kernel_size=1, stride=self.q_stride) + else: + self.q_downsample = None + + if self.kv_stride > 1: + self.kv_downsample = nn.AvgPool2d( + kernel_size=1, stride=self.kv_stride) + else: + self.kv_downsample = None + + self.init_weights() + + def get_position_embedding(self, + h, + w, + h_kv, + w_kv, + q_stride, + kv_stride, + device, + dtype, + feat_dim, + wave_length=1000): + # the default type of Tensor is float32, leading to type mismatch + # in fp16 mode. Cast it to support fp16 mode. + h_idxs = torch.linspace(0, h - 1, h).to(device=device, dtype=dtype) + h_idxs = h_idxs.view((h, 1)) * q_stride + + w_idxs = torch.linspace(0, w - 1, w).to(device=device, dtype=dtype) + w_idxs = w_idxs.view((w, 1)) * q_stride + + h_kv_idxs = torch.linspace(0, h_kv - 1, h_kv).to( + device=device, dtype=dtype) + h_kv_idxs = h_kv_idxs.view((h_kv, 1)) * kv_stride + + w_kv_idxs = torch.linspace(0, w_kv - 1, w_kv).to( + device=device, dtype=dtype) + w_kv_idxs = w_kv_idxs.view((w_kv, 1)) * kv_stride + + # (h, h_kv, 1) + h_diff = h_idxs.unsqueeze(1) - h_kv_idxs.unsqueeze(0) + h_diff *= self.position_magnitude + + # (w, w_kv, 1) + w_diff = w_idxs.unsqueeze(1) - w_kv_idxs.unsqueeze(0) + w_diff *= self.position_magnitude + + feat_range = torch.arange(0, feat_dim / 4).to( + device=device, dtype=dtype) + + dim_mat = torch.Tensor([wave_length]).to(device=device, dtype=dtype) + dim_mat = dim_mat**((4. / feat_dim) * feat_range) + dim_mat = dim_mat.view((1, 1, -1)) + + embedding_x = torch.cat( + ((w_diff / dim_mat).sin(), (w_diff / dim_mat).cos()), dim=2) + + embedding_y = torch.cat( + ((h_diff / dim_mat).sin(), (h_diff / dim_mat).cos()), dim=2) + + return embedding_x, embedding_y + + def forward(self, x_input): + num_heads = self.num_heads + + # use empirical_attention + if self.q_downsample is not None: + x_q = self.q_downsample(x_input) + else: + x_q = x_input + n, _, h, w = x_q.shape + + if self.kv_downsample is not None: + x_kv = self.kv_downsample(x_input) + else: + x_kv = x_input + _, _, h_kv, w_kv = x_kv.shape + + if self.attention_type[0] or self.attention_type[1]: + proj_query = self.query_conv(x_q).view( + (n, num_heads, self.qk_embed_dim, h * w)) + proj_query = proj_query.permute(0, 1, 3, 2) + + if self.attention_type[0] or self.attention_type[2]: + proj_key = self.key_conv(x_kv).view( + (n, num_heads, self.qk_embed_dim, h_kv * w_kv)) + + if self.attention_type[1] or self.attention_type[3]: + position_embed_x, position_embed_y = self.get_position_embedding( + h, w, h_kv, w_kv, self.q_stride, self.kv_stride, + x_input.device, x_input.dtype, self.position_embedding_dim) + # (n, num_heads, w, w_kv, dim) + position_feat_x = self.appr_geom_fc_x(position_embed_x).\ + view(1, w, w_kv, num_heads, self.qk_embed_dim).\ + permute(0, 3, 1, 2, 4).\ + repeat(n, 1, 1, 1, 1) + + # (n, num_heads, h, h_kv, dim) + position_feat_y = self.appr_geom_fc_y(position_embed_y).\ + view(1, h, h_kv, num_heads, self.qk_embed_dim).\ + permute(0, 3, 1, 2, 4).\ + repeat(n, 1, 1, 1, 1) + + position_feat_x /= math.sqrt(2) + position_feat_y /= math.sqrt(2) + + # accelerate for saliency only + if (np.sum(self.attention_type) == 1) and self.attention_type[2]: + appr_bias = self.appr_bias.\ + view(1, num_heads, 1, self.qk_embed_dim).\ + repeat(n, 1, 1, 1) + + energy = torch.matmul(appr_bias, proj_key).\ + view(n, num_heads, 1, h_kv * w_kv) + + h = 1 + w = 1 + else: + # (n, num_heads, h*w, h_kv*w_kv), query before key, 540mb for + if not self.attention_type[0]: + energy = torch.zeros( + n, + num_heads, + h, + w, + h_kv, + w_kv, + dtype=x_input.dtype, + device=x_input.device) + + # attention_type[0]: appr - appr + # attention_type[1]: appr - position + # attention_type[2]: bias - appr + # attention_type[3]: bias - position + if self.attention_type[0] or self.attention_type[2]: + if self.attention_type[0] and self.attention_type[2]: + appr_bias = self.appr_bias.\ + view(1, num_heads, 1, self.qk_embed_dim) + energy = torch.matmul(proj_query + appr_bias, proj_key).\ + view(n, num_heads, h, w, h_kv, w_kv) + + elif self.attention_type[0]: + energy = torch.matmul(proj_query, proj_key).\ + view(n, num_heads, h, w, h_kv, w_kv) + + elif self.attention_type[2]: + appr_bias = self.appr_bias.\ + view(1, num_heads, 1, self.qk_embed_dim).\ + repeat(n, 1, 1, 1) + + energy += torch.matmul(appr_bias, proj_key).\ + view(n, num_heads, 1, 1, h_kv, w_kv) + + if self.attention_type[1] or self.attention_type[3]: + if self.attention_type[1] and self.attention_type[3]: + geom_bias = self.geom_bias.\ + view(1, num_heads, 1, self.qk_embed_dim) + + proj_query_reshape = (proj_query + geom_bias).\ + view(n, num_heads, h, w, self.qk_embed_dim) + + energy_x = torch.matmul( + proj_query_reshape.permute(0, 1, 3, 2, 4), + position_feat_x.permute(0, 1, 2, 4, 3)) + energy_x = energy_x.\ + permute(0, 1, 3, 2, 4).unsqueeze(4) + + energy_y = torch.matmul( + proj_query_reshape, + position_feat_y.permute(0, 1, 2, 4, 3)) + energy_y = energy_y.unsqueeze(5) + + energy += energy_x + energy_y + + elif self.attention_type[1]: + proj_query_reshape = proj_query.\ + view(n, num_heads, h, w, self.qk_embed_dim) + proj_query_reshape = proj_query_reshape.\ + permute(0, 1, 3, 2, 4) + position_feat_x_reshape = position_feat_x.\ + permute(0, 1, 2, 4, 3) + position_feat_y_reshape = position_feat_y.\ + permute(0, 1, 2, 4, 3) + + energy_x = torch.matmul(proj_query_reshape, + position_feat_x_reshape) + energy_x = energy_x.permute(0, 1, 3, 2, 4).unsqueeze(4) + + energy_y = torch.matmul(proj_query_reshape, + position_feat_y_reshape) + energy_y = energy_y.unsqueeze(5) + + energy += energy_x + energy_y + + elif self.attention_type[3]: + geom_bias = self.geom_bias.\ + view(1, num_heads, self.qk_embed_dim, 1).\ + repeat(n, 1, 1, 1) + + position_feat_x_reshape = position_feat_x.\ + view(n, num_heads, w*w_kv, self.qk_embed_dim) + + position_feat_y_reshape = position_feat_y.\ + view(n, num_heads, h * h_kv, self.qk_embed_dim) + + energy_x = torch.matmul(position_feat_x_reshape, geom_bias) + energy_x = energy_x.view(n, num_heads, 1, w, 1, w_kv) + + energy_y = torch.matmul(position_feat_y_reshape, geom_bias) + energy_y = energy_y.view(n, num_heads, h, 1, h_kv, 1) + + energy += energy_x + energy_y + + energy = energy.view(n, num_heads, h * w, h_kv * w_kv) + + if self.spatial_range >= 0: + cur_local_constraint_map = \ + self.local_constraint_map[:h, :w, :h_kv, :w_kv].\ + contiguous().\ + view(1, 1, h*w, h_kv*w_kv) + + energy = energy.masked_fill_(cur_local_constraint_map, + float('-inf')) + + attention = F.softmax(energy, 3) + + proj_value = self.value_conv(x_kv) + proj_value_reshape = proj_value.\ + view((n, num_heads, self.v_dim, h_kv * w_kv)).\ + permute(0, 1, 3, 2) + + out = torch.matmul(attention, proj_value_reshape).\ + permute(0, 1, 3, 2).\ + contiguous().\ + view(n, self.v_dim * self.num_heads, h, w) + + out = self.proj_conv(out) + + # output is downsampled, upsample back to input size + if self.q_downsample is not None: + out = F.interpolate( + out, + size=x_input.shape[2:], + mode='bilinear', + align_corners=False) + + out = self.gamma * out + x_input + return out + + def init_weights(self): + for m in self.modules(): + if hasattr(m, 'kaiming_init') and m.kaiming_init: + kaiming_init( + m, + mode='fan_in', + nonlinearity='leaky_relu', + bias=0, + distribution='uniform', + a=1) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/hsigmoid.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/hsigmoid.py new file mode 100644 index 00000000..30b1a3d6 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/hsigmoid.py @@ -0,0 +1,34 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch.nn as nn + +from .registry import ACTIVATION_LAYERS + + +@ACTIVATION_LAYERS.register_module() +class HSigmoid(nn.Module): + """Hard Sigmoid Module. Apply the hard sigmoid function: + Hsigmoid(x) = min(max((x + bias) / divisor, min_value), max_value) + Default: Hsigmoid(x) = min(max((x + 1) / 2, 0), 1) + + Args: + bias (float): Bias of the input feature map. Default: 1.0. + divisor (float): Divisor of the input feature map. Default: 2.0. + min_value (float): Lower bound value. Default: 0.0. + max_value (float): Upper bound value. Default: 1.0. + + Returns: + Tensor: The output tensor. + """ + + def __init__(self, bias=1.0, divisor=2.0, min_value=0.0, max_value=1.0): + super(HSigmoid, self).__init__() + self.bias = bias + self.divisor = divisor + assert self.divisor != 0 + self.min_value = min_value + self.max_value = max_value + + def forward(self, x): + x = (x + self.bias) / self.divisor + + return x.clamp_(self.min_value, self.max_value) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/hswish.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/hswish.py new file mode 100644 index 00000000..7e0c090f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/hswish.py @@ -0,0 +1,29 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch.nn as nn + +from .registry import ACTIVATION_LAYERS + + +@ACTIVATION_LAYERS.register_module() +class HSwish(nn.Module): + """Hard Swish Module. + + This module applies the hard swish function: + + .. math:: + Hswish(x) = x * ReLU6(x + 3) / 6 + + Args: + inplace (bool): can optionally do the operation in-place. + Default: False. + + Returns: + Tensor: The output tensor. + """ + + def __init__(self, inplace=False): + super(HSwish, self).__init__() + self.act = nn.ReLU6(inplace) + + def forward(self, x): + return x * self.act(x + 3) / 6 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/non_local.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/non_local.py new file mode 100644 index 00000000..92d00155 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/non_local.py @@ -0,0 +1,306 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from abc import ABCMeta + +import torch +import torch.nn as nn + +from ..utils import constant_init, normal_init +from .conv_module import ConvModule +from .registry import PLUGIN_LAYERS + + +class _NonLocalNd(nn.Module, metaclass=ABCMeta): + """Basic Non-local module. + + This module is proposed in + "Non-local Neural Networks" + Paper reference: https://arxiv.org/abs/1711.07971 + Code reference: https://github.com/AlexHex7/Non-local_pytorch + + Args: + in_channels (int): Channels of the input feature map. + reduction (int): Channel reduction ratio. Default: 2. + use_scale (bool): Whether to scale pairwise_weight by + `1/sqrt(inter_channels)` when the mode is `embedded_gaussian`. + Default: True. + conv_cfg (None | dict): The config dict for convolution layers. + If not specified, it will use `nn.Conv2d` for convolution layers. + Default: None. + norm_cfg (None | dict): The config dict for normalization layers. + Default: None. (This parameter is only applicable to conv_out.) + mode (str): Options are `gaussian`, `concatenation`, + `embedded_gaussian` and `dot_product`. Default: embedded_gaussian. + """ + + def __init__(self, + in_channels, + reduction=2, + use_scale=True, + conv_cfg=None, + norm_cfg=None, + mode='embedded_gaussian', + **kwargs): + super(_NonLocalNd, self).__init__() + self.in_channels = in_channels + self.reduction = reduction + self.use_scale = use_scale + self.inter_channels = max(in_channels // reduction, 1) + self.mode = mode + + if mode not in [ + 'gaussian', 'embedded_gaussian', 'dot_product', 'concatenation' + ]: + raise ValueError("Mode should be in 'gaussian', 'concatenation', " + f"'embedded_gaussian' or 'dot_product', but got " + f'{mode} instead.') + + # g, theta, phi are defaulted as `nn.ConvNd`. + # Here we use ConvModule for potential usage. + self.g = ConvModule( + self.in_channels, + self.inter_channels, + kernel_size=1, + conv_cfg=conv_cfg, + act_cfg=None) + self.conv_out = ConvModule( + self.inter_channels, + self.in_channels, + kernel_size=1, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=None) + + if self.mode != 'gaussian': + self.theta = ConvModule( + self.in_channels, + self.inter_channels, + kernel_size=1, + conv_cfg=conv_cfg, + act_cfg=None) + self.phi = ConvModule( + self.in_channels, + self.inter_channels, + kernel_size=1, + conv_cfg=conv_cfg, + act_cfg=None) + + if self.mode == 'concatenation': + self.concat_project = ConvModule( + self.inter_channels * 2, + 1, + kernel_size=1, + stride=1, + padding=0, + bias=False, + act_cfg=dict(type='ReLU')) + + self.init_weights(**kwargs) + + def init_weights(self, std=0.01, zeros_init=True): + if self.mode != 'gaussian': + for m in [self.g, self.theta, self.phi]: + normal_init(m.conv, std=std) + else: + normal_init(self.g.conv, std=std) + if zeros_init: + if self.conv_out.norm_cfg is None: + constant_init(self.conv_out.conv, 0) + else: + constant_init(self.conv_out.norm, 0) + else: + if self.conv_out.norm_cfg is None: + normal_init(self.conv_out.conv, std=std) + else: + normal_init(self.conv_out.norm, std=std) + + def gaussian(self, theta_x, phi_x): + # NonLocal1d pairwise_weight: [N, H, H] + # NonLocal2d pairwise_weight: [N, HxW, HxW] + # NonLocal3d pairwise_weight: [N, TxHxW, TxHxW] + pairwise_weight = torch.matmul(theta_x, phi_x) + pairwise_weight = pairwise_weight.softmax(dim=-1) + return pairwise_weight + + def embedded_gaussian(self, theta_x, phi_x): + # NonLocal1d pairwise_weight: [N, H, H] + # NonLocal2d pairwise_weight: [N, HxW, HxW] + # NonLocal3d pairwise_weight: [N, TxHxW, TxHxW] + pairwise_weight = torch.matmul(theta_x, phi_x) + if self.use_scale: + # theta_x.shape[-1] is `self.inter_channels` + pairwise_weight /= theta_x.shape[-1]**0.5 + pairwise_weight = pairwise_weight.softmax(dim=-1) + return pairwise_weight + + def dot_product(self, theta_x, phi_x): + # NonLocal1d pairwise_weight: [N, H, H] + # NonLocal2d pairwise_weight: [N, HxW, HxW] + # NonLocal3d pairwise_weight: [N, TxHxW, TxHxW] + pairwise_weight = torch.matmul(theta_x, phi_x) + pairwise_weight /= pairwise_weight.shape[-1] + return pairwise_weight + + def concatenation(self, theta_x, phi_x): + # NonLocal1d pairwise_weight: [N, H, H] + # NonLocal2d pairwise_weight: [N, HxW, HxW] + # NonLocal3d pairwise_weight: [N, TxHxW, TxHxW] + h = theta_x.size(2) + w = phi_x.size(3) + theta_x = theta_x.repeat(1, 1, 1, w) + phi_x = phi_x.repeat(1, 1, h, 1) + + concat_feature = torch.cat([theta_x, phi_x], dim=1) + pairwise_weight = self.concat_project(concat_feature) + n, _, h, w = pairwise_weight.size() + pairwise_weight = pairwise_weight.view(n, h, w) + pairwise_weight /= pairwise_weight.shape[-1] + + return pairwise_weight + + def forward(self, x): + # Assume `reduction = 1`, then `inter_channels = C` + # or `inter_channels = C` when `mode="gaussian"` + + # NonLocal1d x: [N, C, H] + # NonLocal2d x: [N, C, H, W] + # NonLocal3d x: [N, C, T, H, W] + n = x.size(0) + + # NonLocal1d g_x: [N, H, C] + # NonLocal2d g_x: [N, HxW, C] + # NonLocal3d g_x: [N, TxHxW, C] + g_x = self.g(x).view(n, self.inter_channels, -1) + g_x = g_x.permute(0, 2, 1) + + # NonLocal1d theta_x: [N, H, C], phi_x: [N, C, H] + # NonLocal2d theta_x: [N, HxW, C], phi_x: [N, C, HxW] + # NonLocal3d theta_x: [N, TxHxW, C], phi_x: [N, C, TxHxW] + if self.mode == 'gaussian': + theta_x = x.view(n, self.in_channels, -1) + theta_x = theta_x.permute(0, 2, 1) + if self.sub_sample: + phi_x = self.phi(x).view(n, self.in_channels, -1) + else: + phi_x = x.view(n, self.in_channels, -1) + elif self.mode == 'concatenation': + theta_x = self.theta(x).view(n, self.inter_channels, -1, 1) + phi_x = self.phi(x).view(n, self.inter_channels, 1, -1) + else: + theta_x = self.theta(x).view(n, self.inter_channels, -1) + theta_x = theta_x.permute(0, 2, 1) + phi_x = self.phi(x).view(n, self.inter_channels, -1) + + pairwise_func = getattr(self, self.mode) + # NonLocal1d pairwise_weight: [N, H, H] + # NonLocal2d pairwise_weight: [N, HxW, HxW] + # NonLocal3d pairwise_weight: [N, TxHxW, TxHxW] + pairwise_weight = pairwise_func(theta_x, phi_x) + + # NonLocal1d y: [N, H, C] + # NonLocal2d y: [N, HxW, C] + # NonLocal3d y: [N, TxHxW, C] + y = torch.matmul(pairwise_weight, g_x) + # NonLocal1d y: [N, C, H] + # NonLocal2d y: [N, C, H, W] + # NonLocal3d y: [N, C, T, H, W] + y = y.permute(0, 2, 1).contiguous().reshape(n, self.inter_channels, + *x.size()[2:]) + + output = x + self.conv_out(y) + + return output + + +class NonLocal1d(_NonLocalNd): + """1D Non-local module. + + Args: + in_channels (int): Same as `NonLocalND`. + sub_sample (bool): Whether to apply max pooling after pairwise + function (Note that the `sub_sample` is applied on spatial only). + Default: False. + conv_cfg (None | dict): Same as `NonLocalND`. + Default: dict(type='Conv1d'). + """ + + def __init__(self, + in_channels, + sub_sample=False, + conv_cfg=dict(type='Conv1d'), + **kwargs): + super(NonLocal1d, self).__init__( + in_channels, conv_cfg=conv_cfg, **kwargs) + + self.sub_sample = sub_sample + + if sub_sample: + max_pool_layer = nn.MaxPool1d(kernel_size=2) + self.g = nn.Sequential(self.g, max_pool_layer) + if self.mode != 'gaussian': + self.phi = nn.Sequential(self.phi, max_pool_layer) + else: + self.phi = max_pool_layer + + +@PLUGIN_LAYERS.register_module() +class NonLocal2d(_NonLocalNd): + """2D Non-local module. + + Args: + in_channels (int): Same as `NonLocalND`. + sub_sample (bool): Whether to apply max pooling after pairwise + function (Note that the `sub_sample` is applied on spatial only). + Default: False. + conv_cfg (None | dict): Same as `NonLocalND`. + Default: dict(type='Conv2d'). + """ + + _abbr_ = 'nonlocal_block' + + def __init__(self, + in_channels, + sub_sample=False, + conv_cfg=dict(type='Conv2d'), + **kwargs): + super(NonLocal2d, self).__init__( + in_channels, conv_cfg=conv_cfg, **kwargs) + + self.sub_sample = sub_sample + + if sub_sample: + max_pool_layer = nn.MaxPool2d(kernel_size=(2, 2)) + self.g = nn.Sequential(self.g, max_pool_layer) + if self.mode != 'gaussian': + self.phi = nn.Sequential(self.phi, max_pool_layer) + else: + self.phi = max_pool_layer + + +class NonLocal3d(_NonLocalNd): + """3D Non-local module. + + Args: + in_channels (int): Same as `NonLocalND`. + sub_sample (bool): Whether to apply max pooling after pairwise + function (Note that the `sub_sample` is applied on spatial only). + Default: False. + conv_cfg (None | dict): Same as `NonLocalND`. + Default: dict(type='Conv3d'). + """ + + def __init__(self, + in_channels, + sub_sample=False, + conv_cfg=dict(type='Conv3d'), + **kwargs): + super(NonLocal3d, self).__init__( + in_channels, conv_cfg=conv_cfg, **kwargs) + self.sub_sample = sub_sample + + if sub_sample: + max_pool_layer = nn.MaxPool3d(kernel_size=(1, 2, 2)) + self.g = nn.Sequential(self.g, max_pool_layer) + if self.mode != 'gaussian': + self.phi = nn.Sequential(self.phi, max_pool_layer) + else: + self.phi = max_pool_layer diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/norm.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/norm.py new file mode 100644 index 00000000..31f4e49b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/norm.py @@ -0,0 +1,144 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import inspect + +import torch.nn as nn + +from annotator.mmpkg.mmcv.utils import is_tuple_of +from annotator.mmpkg.mmcv.utils.parrots_wrapper import SyncBatchNorm, _BatchNorm, _InstanceNorm +from .registry import NORM_LAYERS + +NORM_LAYERS.register_module('BN', module=nn.BatchNorm2d) +NORM_LAYERS.register_module('BN1d', module=nn.BatchNorm1d) +NORM_LAYERS.register_module('BN2d', module=nn.BatchNorm2d) +NORM_LAYERS.register_module('BN3d', module=nn.BatchNorm3d) +NORM_LAYERS.register_module('SyncBN', module=SyncBatchNorm) +NORM_LAYERS.register_module('GN', module=nn.GroupNorm) +NORM_LAYERS.register_module('LN', module=nn.LayerNorm) +NORM_LAYERS.register_module('IN', module=nn.InstanceNorm2d) +NORM_LAYERS.register_module('IN1d', module=nn.InstanceNorm1d) +NORM_LAYERS.register_module('IN2d', module=nn.InstanceNorm2d) +NORM_LAYERS.register_module('IN3d', module=nn.InstanceNorm3d) + + +def infer_abbr(class_type): + """Infer abbreviation from the class name. + + When we build a norm layer with `build_norm_layer()`, we want to preserve + the norm type in variable names, e.g, self.bn1, self.gn. This method will + infer the abbreviation to map class types to abbreviations. + + Rule 1: If the class has the property "_abbr_", return the property. + Rule 2: If the parent class is _BatchNorm, GroupNorm, LayerNorm or + InstanceNorm, the abbreviation of this layer will be "bn", "gn", "ln" and + "in" respectively. + Rule 3: If the class name contains "batch", "group", "layer" or "instance", + the abbreviation of this layer will be "bn", "gn", "ln" and "in" + respectively. + Rule 4: Otherwise, the abbreviation falls back to "norm". + + Args: + class_type (type): The norm layer type. + + Returns: + str: The inferred abbreviation. + """ + if not inspect.isclass(class_type): + raise TypeError( + f'class_type must be a type, but got {type(class_type)}') + if hasattr(class_type, '_abbr_'): + return class_type._abbr_ + if issubclass(class_type, _InstanceNorm): # IN is a subclass of BN + return 'in' + elif issubclass(class_type, _BatchNorm): + return 'bn' + elif issubclass(class_type, nn.GroupNorm): + return 'gn' + elif issubclass(class_type, nn.LayerNorm): + return 'ln' + else: + class_name = class_type.__name__.lower() + if 'batch' in class_name: + return 'bn' + elif 'group' in class_name: + return 'gn' + elif 'layer' in class_name: + return 'ln' + elif 'instance' in class_name: + return 'in' + else: + return 'norm_layer' + + +def build_norm_layer(cfg, num_features, postfix=''): + """Build normalization layer. + + Args: + cfg (dict): The norm layer config, which should contain: + + - type (str): Layer type. + - layer args: Args needed to instantiate a norm layer. + - requires_grad (bool, optional): Whether stop gradient updates. + num_features (int): Number of input channels. + postfix (int | str): The postfix to be appended into norm abbreviation + to create named layer. + + Returns: + (str, nn.Module): The first element is the layer name consisting of + abbreviation and postfix, e.g., bn1, gn. The second element is the + created norm layer. + """ + if not isinstance(cfg, dict): + raise TypeError('cfg must be a dict') + if 'type' not in cfg: + raise KeyError('the cfg dict must contain the key "type"') + cfg_ = cfg.copy() + + layer_type = cfg_.pop('type') + if layer_type not in NORM_LAYERS: + raise KeyError(f'Unrecognized norm type {layer_type}') + + norm_layer = NORM_LAYERS.get(layer_type) + abbr = infer_abbr(norm_layer) + + assert isinstance(postfix, (int, str)) + name = abbr + str(postfix) + + requires_grad = cfg_.pop('requires_grad', True) + cfg_.setdefault('eps', 1e-5) + if layer_type != 'GN': + layer = norm_layer(num_features, **cfg_) + if layer_type == 'SyncBN' and hasattr(layer, '_specify_ddp_gpu_num'): + layer._specify_ddp_gpu_num(1) + else: + assert 'num_groups' in cfg_ + layer = norm_layer(num_channels=num_features, **cfg_) + + for param in layer.parameters(): + param.requires_grad = requires_grad + + return name, layer + + +def is_norm(layer, exclude=None): + """Check if a layer is a normalization layer. + + Args: + layer (nn.Module): The layer to be checked. + exclude (type | tuple[type]): Types to be excluded. + + Returns: + bool: Whether the layer is a norm layer. + """ + if exclude is not None: + if not isinstance(exclude, tuple): + exclude = (exclude, ) + if not is_tuple_of(exclude, type): + raise TypeError( + f'"exclude" must be either None or type or a tuple of types, ' + f'but got {type(exclude)}: {exclude}') + + if exclude and isinstance(layer, exclude): + return False + + all_norm_bases = (_BatchNorm, _InstanceNorm, nn.GroupNorm, nn.LayerNorm) + return isinstance(layer, all_norm_bases) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/padding.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/padding.py new file mode 100644 index 00000000..e4ac6b28 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/padding.py @@ -0,0 +1,36 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch.nn as nn + +from .registry import PADDING_LAYERS + +PADDING_LAYERS.register_module('zero', module=nn.ZeroPad2d) +PADDING_LAYERS.register_module('reflect', module=nn.ReflectionPad2d) +PADDING_LAYERS.register_module('replicate', module=nn.ReplicationPad2d) + + +def build_padding_layer(cfg, *args, **kwargs): + """Build padding layer. + + Args: + cfg (None or dict): The padding layer config, which should contain: + - type (str): Layer type. + - layer args: Args needed to instantiate a padding layer. + + Returns: + nn.Module: Created padding layer. + """ + if not isinstance(cfg, dict): + raise TypeError('cfg must be a dict') + if 'type' not in cfg: + raise KeyError('the cfg dict must contain the key "type"') + + cfg_ = cfg.copy() + padding_type = cfg_.pop('type') + if padding_type not in PADDING_LAYERS: + raise KeyError(f'Unrecognized padding type {padding_type}.') + else: + padding_layer = PADDING_LAYERS.get(padding_type) + + layer = padding_layer(*args, **kwargs, **cfg_) + + return layer diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/plugin.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/plugin.py new file mode 100644 index 00000000..07c010d4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/plugin.py @@ -0,0 +1,88 @@ +import inspect +import platform + +from .registry import PLUGIN_LAYERS + +if platform.system() == 'Windows': + import regex as re +else: + import re + + +def infer_abbr(class_type): + """Infer abbreviation from the class name. + + This method will infer the abbreviation to map class types to + abbreviations. + + Rule 1: If the class has the property "abbr", return the property. + Rule 2: Otherwise, the abbreviation falls back to snake case of class + name, e.g. the abbreviation of ``FancyBlock`` will be ``fancy_block``. + + Args: + class_type (type): The norm layer type. + + Returns: + str: The inferred abbreviation. + """ + + def camel2snack(word): + """Convert camel case word into snack case. + + Modified from `inflection lib + `_. + + Example:: + + >>> camel2snack("FancyBlock") + 'fancy_block' + """ + + word = re.sub(r'([A-Z]+)([A-Z][a-z])', r'\1_\2', word) + word = re.sub(r'([a-z\d])([A-Z])', r'\1_\2', word) + word = word.replace('-', '_') + return word.lower() + + if not inspect.isclass(class_type): + raise TypeError( + f'class_type must be a type, but got {type(class_type)}') + if hasattr(class_type, '_abbr_'): + return class_type._abbr_ + else: + return camel2snack(class_type.__name__) + + +def build_plugin_layer(cfg, postfix='', **kwargs): + """Build plugin layer. + + Args: + cfg (None or dict): cfg should contain: + type (str): identify plugin layer type. + layer args: args needed to instantiate a plugin layer. + postfix (int, str): appended into norm abbreviation to + create named layer. Default: ''. + + Returns: + tuple[str, nn.Module]: + name (str): abbreviation + postfix + layer (nn.Module): created plugin layer + """ + if not isinstance(cfg, dict): + raise TypeError('cfg must be a dict') + if 'type' not in cfg: + raise KeyError('the cfg dict must contain the key "type"') + cfg_ = cfg.copy() + + layer_type = cfg_.pop('type') + if layer_type not in PLUGIN_LAYERS: + raise KeyError(f'Unrecognized plugin type {layer_type}') + + plugin_layer = PLUGIN_LAYERS.get(layer_type) + abbr = infer_abbr(plugin_layer) + + assert isinstance(postfix, (int, str)) + name = abbr + str(postfix) + + layer = plugin_layer(**kwargs, **cfg_) + + return name, layer diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/registry.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/registry.py new file mode 100644 index 00000000..4f374cca --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/registry.py @@ -0,0 +1,16 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from annotator.mmpkg.mmcv.utils import Registry + +CONV_LAYERS = Registry('conv layer') +NORM_LAYERS = Registry('norm layer') +ACTIVATION_LAYERS = Registry('activation layer') +PADDING_LAYERS = Registry('padding layer') +UPSAMPLE_LAYERS = Registry('upsample layer') +PLUGIN_LAYERS = Registry('plugin layer') + +DROPOUT_LAYERS = Registry('drop out layers') +POSITIONAL_ENCODING = Registry('position encoding') +ATTENTION = Registry('attention') +FEEDFORWARD_NETWORK = Registry('feed-forward Network') +TRANSFORMER_LAYER = Registry('transformerLayer') +TRANSFORMER_LAYER_SEQUENCE = Registry('transformer-layers sequence') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/scale.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/scale.py new file mode 100644 index 00000000..c905fffc --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/scale.py @@ -0,0 +1,21 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.nn as nn + + +class Scale(nn.Module): + """A learnable scale parameter. + + This layer scales the input by a learnable factor. It multiplies a + learnable scale parameter of shape (1,) with input of any shape. + + Args: + scale (float): Initial value of scale factor. Default: 1.0 + """ + + def __init__(self, scale=1.0): + super(Scale, self).__init__() + self.scale = nn.Parameter(torch.tensor(scale, dtype=torch.float)) + + def forward(self, x): + return x * self.scale diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/swish.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/swish.py new file mode 100644 index 00000000..e2ca8ed7 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/swish.py @@ -0,0 +1,25 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.nn as nn + +from .registry import ACTIVATION_LAYERS + + +@ACTIVATION_LAYERS.register_module() +class Swish(nn.Module): + """Swish Module. + + This module applies the swish function: + + .. math:: + Swish(x) = x * Sigmoid(x) + + Returns: + Tensor: The output tensor. + """ + + def __init__(self): + super(Swish, self).__init__() + + def forward(self, x): + return x * torch.sigmoid(x) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/transformer.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/transformer.py new file mode 100644 index 00000000..e1670714 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/transformer.py @@ -0,0 +1,595 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import copy +import warnings + +import torch +import torch.nn as nn + +from annotator.mmpkg.mmcv import ConfigDict, deprecated_api_warning +from annotator.mmpkg.mmcv.cnn import Linear, build_activation_layer, build_norm_layer +from annotator.mmpkg.mmcv.runner.base_module import BaseModule, ModuleList, Sequential +from annotator.mmpkg.mmcv.utils import build_from_cfg +from .drop import build_dropout +from .registry import (ATTENTION, FEEDFORWARD_NETWORK, POSITIONAL_ENCODING, + TRANSFORMER_LAYER, TRANSFORMER_LAYER_SEQUENCE) + +# Avoid BC-breaking of importing MultiScaleDeformableAttention from this file +try: + from annotator.mmpkg.mmcv.ops.multi_scale_deform_attn import MultiScaleDeformableAttention # noqa F401 + warnings.warn( + ImportWarning( + '``MultiScaleDeformableAttention`` has been moved to ' + '``mmcv.ops.multi_scale_deform_attn``, please change original path ' # noqa E501 + '``from annotator.mmpkg.mmcv.cnn.bricks.transformer import MultiScaleDeformableAttention`` ' # noqa E501 + 'to ``from annotator.mmpkg.mmcv.ops.multi_scale_deform_attn import MultiScaleDeformableAttention`` ' # noqa E501 + )) + +except ImportError: + warnings.warn('Fail to import ``MultiScaleDeformableAttention`` from ' + '``mmcv.ops.multi_scale_deform_attn``, ' + 'You should install ``mmcv-full`` if you need this module. ') + + +def build_positional_encoding(cfg, default_args=None): + """Builder for Position Encoding.""" + return build_from_cfg(cfg, POSITIONAL_ENCODING, default_args) + + +def build_attention(cfg, default_args=None): + """Builder for attention.""" + return build_from_cfg(cfg, ATTENTION, default_args) + + +def build_feedforward_network(cfg, default_args=None): + """Builder for feed-forward network (FFN).""" + return build_from_cfg(cfg, FEEDFORWARD_NETWORK, default_args) + + +def build_transformer_layer(cfg, default_args=None): + """Builder for transformer layer.""" + return build_from_cfg(cfg, TRANSFORMER_LAYER, default_args) + + +def build_transformer_layer_sequence(cfg, default_args=None): + """Builder for transformer encoder and transformer decoder.""" + return build_from_cfg(cfg, TRANSFORMER_LAYER_SEQUENCE, default_args) + + +@ATTENTION.register_module() +class MultiheadAttention(BaseModule): + """A wrapper for ``torch.nn.MultiheadAttention``. + + This module implements MultiheadAttention with identity connection, + and positional encoding is also passed as input. + + Args: + embed_dims (int): The embedding dimension. + num_heads (int): Parallel attention heads. + attn_drop (float): A Dropout layer on attn_output_weights. + Default: 0.0. + proj_drop (float): A Dropout layer after `nn.MultiheadAttention`. + Default: 0.0. + dropout_layer (obj:`ConfigDict`): The dropout_layer used + when adding the shortcut. + init_cfg (obj:`mmcv.ConfigDict`): The Config for initialization. + Default: None. + batch_first (bool): When it is True, Key, Query and Value are shape of + (batch, n, embed_dim), otherwise (n, batch, embed_dim). + Default to False. + """ + + def __init__(self, + embed_dims, + num_heads, + attn_drop=0., + proj_drop=0., + dropout_layer=dict(type='Dropout', drop_prob=0.), + init_cfg=None, + batch_first=False, + **kwargs): + super(MultiheadAttention, self).__init__(init_cfg) + if 'dropout' in kwargs: + warnings.warn('The arguments `dropout` in MultiheadAttention ' + 'has been deprecated, now you can separately ' + 'set `attn_drop`(float), proj_drop(float), ' + 'and `dropout_layer`(dict) ') + attn_drop = kwargs['dropout'] + dropout_layer['drop_prob'] = kwargs.pop('dropout') + + self.embed_dims = embed_dims + self.num_heads = num_heads + self.batch_first = batch_first + + self.attn = nn.MultiheadAttention(embed_dims, num_heads, attn_drop, + **kwargs) + + self.proj_drop = nn.Dropout(proj_drop) + self.dropout_layer = build_dropout( + dropout_layer) if dropout_layer else nn.Identity() + + @deprecated_api_warning({'residual': 'identity'}, + cls_name='MultiheadAttention') + def forward(self, + query, + key=None, + value=None, + identity=None, + query_pos=None, + key_pos=None, + attn_mask=None, + key_padding_mask=None, + **kwargs): + """Forward function for `MultiheadAttention`. + + **kwargs allow passing a more general data flow when combining + with other operations in `transformerlayer`. + + Args: + query (Tensor): The input query with shape [num_queries, bs, + embed_dims] if self.batch_first is False, else + [bs, num_queries embed_dims]. + key (Tensor): The key tensor with shape [num_keys, bs, + embed_dims] if self.batch_first is False, else + [bs, num_keys, embed_dims] . + If None, the ``query`` will be used. Defaults to None. + value (Tensor): The value tensor with same shape as `key`. + Same in `nn.MultiheadAttention.forward`. Defaults to None. + If None, the `key` will be used. + identity (Tensor): This tensor, with the same shape as x, + will be used for the identity link. + If None, `x` will be used. Defaults to None. + query_pos (Tensor): The positional encoding for query, with + the same shape as `x`. If not None, it will + be added to `x` before forward function. Defaults to None. + key_pos (Tensor): The positional encoding for `key`, with the + same shape as `key`. Defaults to None. If not None, it will + be added to `key` before forward function. If None, and + `query_pos` has the same shape as `key`, then `query_pos` + will be used for `key_pos`. Defaults to None. + attn_mask (Tensor): ByteTensor mask with shape [num_queries, + num_keys]. Same in `nn.MultiheadAttention.forward`. + Defaults to None. + key_padding_mask (Tensor): ByteTensor with shape [bs, num_keys]. + Defaults to None. + + Returns: + Tensor: forwarded results with shape + [num_queries, bs, embed_dims] + if self.batch_first is False, else + [bs, num_queries embed_dims]. + """ + + if key is None: + key = query + if value is None: + value = key + if identity is None: + identity = query + if key_pos is None: + if query_pos is not None: + # use query_pos if key_pos is not available + if query_pos.shape == key.shape: + key_pos = query_pos + else: + warnings.warn(f'position encoding of key is' + f'missing in {self.__class__.__name__}.') + if query_pos is not None: + query = query + query_pos + if key_pos is not None: + key = key + key_pos + + # Because the dataflow('key', 'query', 'value') of + # ``torch.nn.MultiheadAttention`` is (num_query, batch, + # embed_dims), We should adjust the shape of dataflow from + # batch_first (batch, num_query, embed_dims) to num_query_first + # (num_query ,batch, embed_dims), and recover ``attn_output`` + # from num_query_first to batch_first. + if self.batch_first: + query = query.transpose(0, 1) + key = key.transpose(0, 1) + value = value.transpose(0, 1) + + out = self.attn( + query=query, + key=key, + value=value, + attn_mask=attn_mask, + key_padding_mask=key_padding_mask)[0] + + if self.batch_first: + out = out.transpose(0, 1) + + return identity + self.dropout_layer(self.proj_drop(out)) + + +@FEEDFORWARD_NETWORK.register_module() +class FFN(BaseModule): + """Implements feed-forward networks (FFNs) with identity connection. + + Args: + embed_dims (int): The feature dimension. Same as + `MultiheadAttention`. Defaults: 256. + feedforward_channels (int): The hidden dimension of FFNs. + Defaults: 1024. + num_fcs (int, optional): The number of fully-connected layers in + FFNs. Default: 2. + act_cfg (dict, optional): The activation config for FFNs. + Default: dict(type='ReLU') + ffn_drop (float, optional): Probability of an element to be + zeroed in FFN. Default 0.0. + add_identity (bool, optional): Whether to add the + identity connection. Default: `True`. + dropout_layer (obj:`ConfigDict`): The dropout_layer used + when adding the shortcut. + init_cfg (obj:`mmcv.ConfigDict`): The Config for initialization. + Default: None. + """ + + @deprecated_api_warning( + { + 'dropout': 'ffn_drop', + 'add_residual': 'add_identity' + }, + cls_name='FFN') + def __init__(self, + embed_dims=256, + feedforward_channels=1024, + num_fcs=2, + act_cfg=dict(type='ReLU', inplace=True), + ffn_drop=0., + dropout_layer=None, + add_identity=True, + init_cfg=None, + **kwargs): + super(FFN, self).__init__(init_cfg) + assert num_fcs >= 2, 'num_fcs should be no less ' \ + f'than 2. got {num_fcs}.' + self.embed_dims = embed_dims + self.feedforward_channels = feedforward_channels + self.num_fcs = num_fcs + self.act_cfg = act_cfg + self.activate = build_activation_layer(act_cfg) + + layers = [] + in_channels = embed_dims + for _ in range(num_fcs - 1): + layers.append( + Sequential( + Linear(in_channels, feedforward_channels), self.activate, + nn.Dropout(ffn_drop))) + in_channels = feedforward_channels + layers.append(Linear(feedforward_channels, embed_dims)) + layers.append(nn.Dropout(ffn_drop)) + self.layers = Sequential(*layers) + self.dropout_layer = build_dropout( + dropout_layer) if dropout_layer else torch.nn.Identity() + self.add_identity = add_identity + + @deprecated_api_warning({'residual': 'identity'}, cls_name='FFN') + def forward(self, x, identity=None): + """Forward function for `FFN`. + + The function would add x to the output tensor if residue is None. + """ + out = self.layers(x) + if not self.add_identity: + return self.dropout_layer(out) + if identity is None: + identity = x + return identity + self.dropout_layer(out) + + +@TRANSFORMER_LAYER.register_module() +class BaseTransformerLayer(BaseModule): + """Base `TransformerLayer` for vision transformer. + + It can be built from `mmcv.ConfigDict` and support more flexible + customization, for example, using any number of `FFN or LN ` and + use different kinds of `attention` by specifying a list of `ConfigDict` + named `attn_cfgs`. It is worth mentioning that it supports `prenorm` + when you specifying `norm` as the first element of `operation_order`. + More details about the `prenorm`: `On Layer Normalization in the + Transformer Architecture `_ . + + Args: + attn_cfgs (list[`mmcv.ConfigDict`] | obj:`mmcv.ConfigDict` | None )): + Configs for `self_attention` or `cross_attention` modules, + The order of the configs in the list should be consistent with + corresponding attentions in operation_order. + If it is a dict, all of the attention modules in operation_order + will be built with this config. Default: None. + ffn_cfgs (list[`mmcv.ConfigDict`] | obj:`mmcv.ConfigDict` | None )): + Configs for FFN, The order of the configs in the list should be + consistent with corresponding ffn in operation_order. + If it is a dict, all of the attention modules in operation_order + will be built with this config. + operation_order (tuple[str]): The execution order of operation + in transformer. Such as ('self_attn', 'norm', 'ffn', 'norm'). + Support `prenorm` when you specifying first element as `norm`. + Default:None. + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='LN'). + init_cfg (obj:`mmcv.ConfigDict`): The Config for initialization. + Default: None. + batch_first (bool): Key, Query and Value are shape + of (batch, n, embed_dim) + or (n, batch, embed_dim). Default to False. + """ + + def __init__(self, + attn_cfgs=None, + ffn_cfgs=dict( + type='FFN', + embed_dims=256, + feedforward_channels=1024, + num_fcs=2, + ffn_drop=0., + act_cfg=dict(type='ReLU', inplace=True), + ), + operation_order=None, + norm_cfg=dict(type='LN'), + init_cfg=None, + batch_first=False, + **kwargs): + + deprecated_args = dict( + feedforward_channels='feedforward_channels', + ffn_dropout='ffn_drop', + ffn_num_fcs='num_fcs') + for ori_name, new_name in deprecated_args.items(): + if ori_name in kwargs: + warnings.warn( + f'The arguments `{ori_name}` in BaseTransformerLayer ' + f'has been deprecated, now you should set `{new_name}` ' + f'and other FFN related arguments ' + f'to a dict named `ffn_cfgs`. ') + ffn_cfgs[new_name] = kwargs[ori_name] + + super(BaseTransformerLayer, self).__init__(init_cfg) + + self.batch_first = batch_first + + assert set(operation_order) & set( + ['self_attn', 'norm', 'ffn', 'cross_attn']) == \ + set(operation_order), f'The operation_order of' \ + f' {self.__class__.__name__} should ' \ + f'contains all four operation type ' \ + f"{['self_attn', 'norm', 'ffn', 'cross_attn']}" + + num_attn = operation_order.count('self_attn') + operation_order.count( + 'cross_attn') + if isinstance(attn_cfgs, dict): + attn_cfgs = [copy.deepcopy(attn_cfgs) for _ in range(num_attn)] + else: + assert num_attn == len(attn_cfgs), f'The length ' \ + f'of attn_cfg {num_attn} is ' \ + f'not consistent with the number of attention' \ + f'in operation_order {operation_order}.' + + self.num_attn = num_attn + self.operation_order = operation_order + self.norm_cfg = norm_cfg + self.pre_norm = operation_order[0] == 'norm' + self.attentions = ModuleList() + + index = 0 + for operation_name in operation_order: + if operation_name in ['self_attn', 'cross_attn']: + if 'batch_first' in attn_cfgs[index]: + assert self.batch_first == attn_cfgs[index]['batch_first'] + else: + attn_cfgs[index]['batch_first'] = self.batch_first + attention = build_attention(attn_cfgs[index]) + # Some custom attentions used as `self_attn` + # or `cross_attn` can have different behavior. + attention.operation_name = operation_name + self.attentions.append(attention) + index += 1 + + self.embed_dims = self.attentions[0].embed_dims + + self.ffns = ModuleList() + num_ffns = operation_order.count('ffn') + if isinstance(ffn_cfgs, dict): + ffn_cfgs = ConfigDict(ffn_cfgs) + if isinstance(ffn_cfgs, dict): + ffn_cfgs = [copy.deepcopy(ffn_cfgs) for _ in range(num_ffns)] + assert len(ffn_cfgs) == num_ffns + for ffn_index in range(num_ffns): + if 'embed_dims' not in ffn_cfgs[ffn_index]: + ffn_cfgs['embed_dims'] = self.embed_dims + else: + assert ffn_cfgs[ffn_index]['embed_dims'] == self.embed_dims + self.ffns.append( + build_feedforward_network(ffn_cfgs[ffn_index], + dict(type='FFN'))) + + self.norms = ModuleList() + num_norms = operation_order.count('norm') + for _ in range(num_norms): + self.norms.append(build_norm_layer(norm_cfg, self.embed_dims)[1]) + + def forward(self, + query, + key=None, + value=None, + query_pos=None, + key_pos=None, + attn_masks=None, + query_key_padding_mask=None, + key_padding_mask=None, + **kwargs): + """Forward function for `TransformerDecoderLayer`. + + **kwargs contains some specific arguments of attentions. + + Args: + query (Tensor): The input query with shape + [num_queries, bs, embed_dims] if + self.batch_first is False, else + [bs, num_queries embed_dims]. + key (Tensor): The key tensor with shape [num_keys, bs, + embed_dims] if self.batch_first is False, else + [bs, num_keys, embed_dims] . + value (Tensor): The value tensor with same shape as `key`. + query_pos (Tensor): The positional encoding for `query`. + Default: None. + key_pos (Tensor): The positional encoding for `key`. + Default: None. + attn_masks (List[Tensor] | None): 2D Tensor used in + calculation of corresponding attention. The length of + it should equal to the number of `attention` in + `operation_order`. Default: None. + query_key_padding_mask (Tensor): ByteTensor for `query`, with + shape [bs, num_queries]. Only used in `self_attn` layer. + Defaults to None. + key_padding_mask (Tensor): ByteTensor for `query`, with + shape [bs, num_keys]. Default: None. + + Returns: + Tensor: forwarded results with shape [num_queries, bs, embed_dims]. + """ + + norm_index = 0 + attn_index = 0 + ffn_index = 0 + identity = query + if attn_masks is None: + attn_masks = [None for _ in range(self.num_attn)] + elif isinstance(attn_masks, torch.Tensor): + attn_masks = [ + copy.deepcopy(attn_masks) for _ in range(self.num_attn) + ] + warnings.warn(f'Use same attn_mask in all attentions in ' + f'{self.__class__.__name__} ') + else: + assert len(attn_masks) == self.num_attn, f'The length of ' \ + f'attn_masks {len(attn_masks)} must be equal ' \ + f'to the number of attention in ' \ + f'operation_order {self.num_attn}' + + for layer in self.operation_order: + if layer == 'self_attn': + temp_key = temp_value = query + query = self.attentions[attn_index]( + query, + temp_key, + temp_value, + identity if self.pre_norm else None, + query_pos=query_pos, + key_pos=query_pos, + attn_mask=attn_masks[attn_index], + key_padding_mask=query_key_padding_mask, + **kwargs) + attn_index += 1 + identity = query + + elif layer == 'norm': + query = self.norms[norm_index](query) + norm_index += 1 + + elif layer == 'cross_attn': + query = self.attentions[attn_index]( + query, + key, + value, + identity if self.pre_norm else None, + query_pos=query_pos, + key_pos=key_pos, + attn_mask=attn_masks[attn_index], + key_padding_mask=key_padding_mask, + **kwargs) + attn_index += 1 + identity = query + + elif layer == 'ffn': + query = self.ffns[ffn_index]( + query, identity if self.pre_norm else None) + ffn_index += 1 + + return query + + +@TRANSFORMER_LAYER_SEQUENCE.register_module() +class TransformerLayerSequence(BaseModule): + """Base class for TransformerEncoder and TransformerDecoder in vision + transformer. + + As base-class of Encoder and Decoder in vision transformer. + Support customization such as specifying different kind + of `transformer_layer` in `transformer_coder`. + + Args: + transformerlayer (list[obj:`mmcv.ConfigDict`] | + obj:`mmcv.ConfigDict`): Config of transformerlayer + in TransformerCoder. If it is obj:`mmcv.ConfigDict`, + it would be repeated `num_layer` times to a + list[`mmcv.ConfigDict`]. Default: None. + num_layers (int): The number of `TransformerLayer`. Default: None. + init_cfg (obj:`mmcv.ConfigDict`): The Config for initialization. + Default: None. + """ + + def __init__(self, transformerlayers=None, num_layers=None, init_cfg=None): + super(TransformerLayerSequence, self).__init__(init_cfg) + if isinstance(transformerlayers, dict): + transformerlayers = [ + copy.deepcopy(transformerlayers) for _ in range(num_layers) + ] + else: + assert isinstance(transformerlayers, list) and \ + len(transformerlayers) == num_layers + self.num_layers = num_layers + self.layers = ModuleList() + for i in range(num_layers): + self.layers.append(build_transformer_layer(transformerlayers[i])) + self.embed_dims = self.layers[0].embed_dims + self.pre_norm = self.layers[0].pre_norm + + def forward(self, + query, + key, + value, + query_pos=None, + key_pos=None, + attn_masks=None, + query_key_padding_mask=None, + key_padding_mask=None, + **kwargs): + """Forward function for `TransformerCoder`. + + Args: + query (Tensor): Input query with shape + `(num_queries, bs, embed_dims)`. + key (Tensor): The key tensor with shape + `(num_keys, bs, embed_dims)`. + value (Tensor): The value tensor with shape + `(num_keys, bs, embed_dims)`. + query_pos (Tensor): The positional encoding for `query`. + Default: None. + key_pos (Tensor): The positional encoding for `key`. + Default: None. + attn_masks (List[Tensor], optional): Each element is 2D Tensor + which is used in calculation of corresponding attention in + operation_order. Default: None. + query_key_padding_mask (Tensor): ByteTensor for `query`, with + shape [bs, num_queries]. Only used in self-attention + Default: None. + key_padding_mask (Tensor): ByteTensor for `query`, with + shape [bs, num_keys]. Default: None. + + Returns: + Tensor: results with shape [num_queries, bs, embed_dims]. + """ + for layer in self.layers: + query = layer( + query, + key, + value, + query_pos=query_pos, + key_pos=key_pos, + attn_masks=attn_masks, + query_key_padding_mask=query_key_padding_mask, + key_padding_mask=key_padding_mask, + **kwargs) + return query diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/upsample.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/upsample.py new file mode 100644 index 00000000..a1a35376 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/upsample.py @@ -0,0 +1,84 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch.nn as nn +import torch.nn.functional as F + +from ..utils import xavier_init +from .registry import UPSAMPLE_LAYERS + +UPSAMPLE_LAYERS.register_module('nearest', module=nn.Upsample) +UPSAMPLE_LAYERS.register_module('bilinear', module=nn.Upsample) + + +@UPSAMPLE_LAYERS.register_module(name='pixel_shuffle') +class PixelShufflePack(nn.Module): + """Pixel Shuffle upsample layer. + + This module packs `F.pixel_shuffle()` and a nn.Conv2d module together to + achieve a simple upsampling with pixel shuffle. + + Args: + in_channels (int): Number of input channels. + out_channels (int): Number of output channels. + scale_factor (int): Upsample ratio. + upsample_kernel (int): Kernel size of the conv layer to expand the + channels. + """ + + def __init__(self, in_channels, out_channels, scale_factor, + upsample_kernel): + super(PixelShufflePack, self).__init__() + self.in_channels = in_channels + self.out_channels = out_channels + self.scale_factor = scale_factor + self.upsample_kernel = upsample_kernel + self.upsample_conv = nn.Conv2d( + self.in_channels, + self.out_channels * scale_factor * scale_factor, + self.upsample_kernel, + padding=(self.upsample_kernel - 1) // 2) + self.init_weights() + + def init_weights(self): + xavier_init(self.upsample_conv, distribution='uniform') + + def forward(self, x): + x = self.upsample_conv(x) + x = F.pixel_shuffle(x, self.scale_factor) + return x + + +def build_upsample_layer(cfg, *args, **kwargs): + """Build upsample layer. + + Args: + cfg (dict): The upsample layer config, which should contain: + + - type (str): Layer type. + - scale_factor (int): Upsample ratio, which is not applicable to + deconv. + - layer args: Args needed to instantiate a upsample layer. + args (argument list): Arguments passed to the ``__init__`` + method of the corresponding conv layer. + kwargs (keyword arguments): Keyword arguments passed to the + ``__init__`` method of the corresponding conv layer. + + Returns: + nn.Module: Created upsample layer. + """ + if not isinstance(cfg, dict): + raise TypeError(f'cfg must be a dict, but got {type(cfg)}') + if 'type' not in cfg: + raise KeyError( + f'the cfg dict must contain the key "type", but got {cfg}') + cfg_ = cfg.copy() + + layer_type = cfg_.pop('type') + if layer_type not in UPSAMPLE_LAYERS: + raise KeyError(f'Unrecognized upsample type {layer_type}') + else: + upsample = UPSAMPLE_LAYERS.get(layer_type) + + if upsample is nn.Upsample: + cfg_['mode'] = layer_type + layer = upsample(*args, **kwargs, **cfg_) + return layer diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/wrappers.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/wrappers.py new file mode 100644 index 00000000..8aebf67b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/bricks/wrappers.py @@ -0,0 +1,180 @@ +# Copyright (c) OpenMMLab. All rights reserved. +r"""Modified from https://github.com/facebookresearch/detectron2/blob/master/detectron2/layers/wrappers.py # noqa: E501 + +Wrap some nn modules to support empty tensor input. Currently, these wrappers +are mainly used in mask heads like fcn_mask_head and maskiou_heads since mask +heads are trained on only positive RoIs. +""" +import math + +import torch +import torch.nn as nn +from torch.nn.modules.utils import _pair, _triple + +from .registry import CONV_LAYERS, UPSAMPLE_LAYERS + +if torch.__version__ == 'parrots': + TORCH_VERSION = torch.__version__ +else: + # torch.__version__ could be 1.3.1+cu92, we only need the first two + # for comparison + TORCH_VERSION = tuple(int(x) for x in torch.__version__.split('.')[:2]) + + +def obsolete_torch_version(torch_version, version_threshold): + return torch_version == 'parrots' or torch_version <= version_threshold + + +class NewEmptyTensorOp(torch.autograd.Function): + + @staticmethod + def forward(ctx, x, new_shape): + ctx.shape = x.shape + return x.new_empty(new_shape) + + @staticmethod + def backward(ctx, grad): + shape = ctx.shape + return NewEmptyTensorOp.apply(grad, shape), None + + +@CONV_LAYERS.register_module('Conv', force=True) +class Conv2d(nn.Conv2d): + + def forward(self, x): + if x.numel() == 0 and obsolete_torch_version(TORCH_VERSION, (1, 4)): + out_shape = [x.shape[0], self.out_channels] + for i, k, p, s, d in zip(x.shape[-2:], self.kernel_size, + self.padding, self.stride, self.dilation): + o = (i + 2 * p - (d * (k - 1) + 1)) // s + 1 + out_shape.append(o) + empty = NewEmptyTensorOp.apply(x, out_shape) + if self.training: + # produce dummy gradient to avoid DDP warning. + dummy = sum(x.view(-1)[0] for x in self.parameters()) * 0.0 + return empty + dummy + else: + return empty + + return super().forward(x) + + +@CONV_LAYERS.register_module('Conv3d', force=True) +class Conv3d(nn.Conv3d): + + def forward(self, x): + if x.numel() == 0 and obsolete_torch_version(TORCH_VERSION, (1, 4)): + out_shape = [x.shape[0], self.out_channels] + for i, k, p, s, d in zip(x.shape[-3:], self.kernel_size, + self.padding, self.stride, self.dilation): + o = (i + 2 * p - (d * (k - 1) + 1)) // s + 1 + out_shape.append(o) + empty = NewEmptyTensorOp.apply(x, out_shape) + if self.training: + # produce dummy gradient to avoid DDP warning. + dummy = sum(x.view(-1)[0] for x in self.parameters()) * 0.0 + return empty + dummy + else: + return empty + + return super().forward(x) + + +@CONV_LAYERS.register_module() +@CONV_LAYERS.register_module('deconv') +@UPSAMPLE_LAYERS.register_module('deconv', force=True) +class ConvTranspose2d(nn.ConvTranspose2d): + + def forward(self, x): + if x.numel() == 0 and obsolete_torch_version(TORCH_VERSION, (1, 4)): + out_shape = [x.shape[0], self.out_channels] + for i, k, p, s, d, op in zip(x.shape[-2:], self.kernel_size, + self.padding, self.stride, + self.dilation, self.output_padding): + out_shape.append((i - 1) * s - 2 * p + (d * (k - 1) + 1) + op) + empty = NewEmptyTensorOp.apply(x, out_shape) + if self.training: + # produce dummy gradient to avoid DDP warning. + dummy = sum(x.view(-1)[0] for x in self.parameters()) * 0.0 + return empty + dummy + else: + return empty + + return super().forward(x) + + +@CONV_LAYERS.register_module() +@CONV_LAYERS.register_module('deconv3d') +@UPSAMPLE_LAYERS.register_module('deconv3d', force=True) +class ConvTranspose3d(nn.ConvTranspose3d): + + def forward(self, x): + if x.numel() == 0 and obsolete_torch_version(TORCH_VERSION, (1, 4)): + out_shape = [x.shape[0], self.out_channels] + for i, k, p, s, d, op in zip(x.shape[-3:], self.kernel_size, + self.padding, self.stride, + self.dilation, self.output_padding): + out_shape.append((i - 1) * s - 2 * p + (d * (k - 1) + 1) + op) + empty = NewEmptyTensorOp.apply(x, out_shape) + if self.training: + # produce dummy gradient to avoid DDP warning. + dummy = sum(x.view(-1)[0] for x in self.parameters()) * 0.0 + return empty + dummy + else: + return empty + + return super().forward(x) + + +class MaxPool2d(nn.MaxPool2d): + + def forward(self, x): + # PyTorch 1.9 does not support empty tensor inference yet + if x.numel() == 0 and obsolete_torch_version(TORCH_VERSION, (1, 9)): + out_shape = list(x.shape[:2]) + for i, k, p, s, d in zip(x.shape[-2:], _pair(self.kernel_size), + _pair(self.padding), _pair(self.stride), + _pair(self.dilation)): + o = (i + 2 * p - (d * (k - 1) + 1)) / s + 1 + o = math.ceil(o) if self.ceil_mode else math.floor(o) + out_shape.append(o) + empty = NewEmptyTensorOp.apply(x, out_shape) + return empty + + return super().forward(x) + + +class MaxPool3d(nn.MaxPool3d): + + def forward(self, x): + # PyTorch 1.9 does not support empty tensor inference yet + if x.numel() == 0 and obsolete_torch_version(TORCH_VERSION, (1, 9)): + out_shape = list(x.shape[:2]) + for i, k, p, s, d in zip(x.shape[-3:], _triple(self.kernel_size), + _triple(self.padding), + _triple(self.stride), + _triple(self.dilation)): + o = (i + 2 * p - (d * (k - 1) + 1)) / s + 1 + o = math.ceil(o) if self.ceil_mode else math.floor(o) + out_shape.append(o) + empty = NewEmptyTensorOp.apply(x, out_shape) + return empty + + return super().forward(x) + + +class Linear(torch.nn.Linear): + + def forward(self, x): + # empty tensor forward of Linear layer is supported in Pytorch 1.6 + if x.numel() == 0 and obsolete_torch_version(TORCH_VERSION, (1, 5)): + out_shape = [x.shape[0], self.out_features] + empty = NewEmptyTensorOp.apply(x, out_shape) + if self.training: + # produce dummy gradient to avoid DDP warning. + dummy = sum(x.view(-1)[0] for x in self.parameters()) * 0.0 + return empty + dummy + else: + return empty + + return super().forward(x) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/builder.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/builder.py new file mode 100644 index 00000000..7567316c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/builder.py @@ -0,0 +1,30 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from ..runner import Sequential +from ..utils import Registry, build_from_cfg + + +def build_model_from_cfg(cfg, registry, default_args=None): + """Build a PyTorch model from config dict(s). Different from + ``build_from_cfg``, if cfg is a list, a ``nn.Sequential`` will be built. + + Args: + cfg (dict, list[dict]): The config of modules, is is either a config + dict or a list of config dicts. If cfg is a list, a + the built modules will be wrapped with ``nn.Sequential``. + registry (:obj:`Registry`): A registry the module belongs to. + default_args (dict, optional): Default arguments to build the module. + Defaults to None. + + Returns: + nn.Module: A built nn module. + """ + if isinstance(cfg, list): + modules = [ + build_from_cfg(cfg_, registry, default_args) for cfg_ in cfg + ] + return Sequential(*modules) + else: + return build_from_cfg(cfg, registry, default_args) + + +MODELS = Registry('model', build_func=build_model_from_cfg) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/resnet.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/resnet.py new file mode 100644 index 00000000..1cb3ac05 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/resnet.py @@ -0,0 +1,316 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import logging + +import torch.nn as nn +import torch.utils.checkpoint as cp + +from .utils import constant_init, kaiming_init + + +def conv3x3(in_planes, out_planes, stride=1, dilation=1): + """3x3 convolution with padding.""" + return nn.Conv2d( + in_planes, + out_planes, + kernel_size=3, + stride=stride, + padding=dilation, + dilation=dilation, + bias=False) + + +class BasicBlock(nn.Module): + expansion = 1 + + def __init__(self, + inplanes, + planes, + stride=1, + dilation=1, + downsample=None, + style='pytorch', + with_cp=False): + super(BasicBlock, self).__init__() + assert style in ['pytorch', 'caffe'] + self.conv1 = conv3x3(inplanes, planes, stride, dilation) + self.bn1 = nn.BatchNorm2d(planes) + self.relu = nn.ReLU(inplace=True) + self.conv2 = conv3x3(planes, planes) + self.bn2 = nn.BatchNorm2d(planes) + self.downsample = downsample + self.stride = stride + self.dilation = dilation + assert not with_cp + + def forward(self, x): + residual = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + + if self.downsample is not None: + residual = self.downsample(x) + + out += residual + out = self.relu(out) + + return out + + +class Bottleneck(nn.Module): + expansion = 4 + + def __init__(self, + inplanes, + planes, + stride=1, + dilation=1, + downsample=None, + style='pytorch', + with_cp=False): + """Bottleneck block. + + If style is "pytorch", the stride-two layer is the 3x3 conv layer, if + it is "caffe", the stride-two layer is the first 1x1 conv layer. + """ + super(Bottleneck, self).__init__() + assert style in ['pytorch', 'caffe'] + if style == 'pytorch': + conv1_stride = 1 + conv2_stride = stride + else: + conv1_stride = stride + conv2_stride = 1 + self.conv1 = nn.Conv2d( + inplanes, planes, kernel_size=1, stride=conv1_stride, bias=False) + self.conv2 = nn.Conv2d( + planes, + planes, + kernel_size=3, + stride=conv2_stride, + padding=dilation, + dilation=dilation, + bias=False) + + self.bn1 = nn.BatchNorm2d(planes) + self.bn2 = nn.BatchNorm2d(planes) + self.conv3 = nn.Conv2d( + planes, planes * self.expansion, kernel_size=1, bias=False) + self.bn3 = nn.BatchNorm2d(planes * self.expansion) + self.relu = nn.ReLU(inplace=True) + self.downsample = downsample + self.stride = stride + self.dilation = dilation + self.with_cp = with_cp + + def forward(self, x): + + def _inner_forward(x): + residual = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + out = self.relu(out) + + out = self.conv3(out) + out = self.bn3(out) + + if self.downsample is not None: + residual = self.downsample(x) + + out += residual + + return out + + if self.with_cp and x.requires_grad: + out = cp.checkpoint(_inner_forward, x) + else: + out = _inner_forward(x) + + out = self.relu(out) + + return out + + +def make_res_layer(block, + inplanes, + planes, + blocks, + stride=1, + dilation=1, + style='pytorch', + with_cp=False): + downsample = None + if stride != 1 or inplanes != planes * block.expansion: + downsample = nn.Sequential( + nn.Conv2d( + inplanes, + planes * block.expansion, + kernel_size=1, + stride=stride, + bias=False), + nn.BatchNorm2d(planes * block.expansion), + ) + + layers = [] + layers.append( + block( + inplanes, + planes, + stride, + dilation, + downsample, + style=style, + with_cp=with_cp)) + inplanes = planes * block.expansion + for _ in range(1, blocks): + layers.append( + block(inplanes, planes, 1, dilation, style=style, with_cp=with_cp)) + + return nn.Sequential(*layers) + + +class ResNet(nn.Module): + """ResNet backbone. + + Args: + depth (int): Depth of resnet, from {18, 34, 50, 101, 152}. + num_stages (int): Resnet stages, normally 4. + strides (Sequence[int]): Strides of the first block of each stage. + dilations (Sequence[int]): Dilation of each stage. + out_indices (Sequence[int]): Output from which stages. + style (str): `pytorch` or `caffe`. If set to "pytorch", the stride-two + layer is the 3x3 conv layer, otherwise the stride-two layer is + the first 1x1 conv layer. + frozen_stages (int): Stages to be frozen (all param fixed). -1 means + not freezing any parameters. + bn_eval (bool): Whether to set BN layers as eval mode, namely, freeze + running stats (mean and var). + bn_frozen (bool): Whether to freeze weight and bias of BN layers. + with_cp (bool): Use checkpoint or not. Using checkpoint will save some + memory while slowing down the training speed. + """ + + arch_settings = { + 18: (BasicBlock, (2, 2, 2, 2)), + 34: (BasicBlock, (3, 4, 6, 3)), + 50: (Bottleneck, (3, 4, 6, 3)), + 101: (Bottleneck, (3, 4, 23, 3)), + 152: (Bottleneck, (3, 8, 36, 3)) + } + + def __init__(self, + depth, + num_stages=4, + strides=(1, 2, 2, 2), + dilations=(1, 1, 1, 1), + out_indices=(0, 1, 2, 3), + style='pytorch', + frozen_stages=-1, + bn_eval=True, + bn_frozen=False, + with_cp=False): + super(ResNet, self).__init__() + if depth not in self.arch_settings: + raise KeyError(f'invalid depth {depth} for resnet') + assert num_stages >= 1 and num_stages <= 4 + block, stage_blocks = self.arch_settings[depth] + stage_blocks = stage_blocks[:num_stages] + assert len(strides) == len(dilations) == num_stages + assert max(out_indices) < num_stages + + self.out_indices = out_indices + self.style = style + self.frozen_stages = frozen_stages + self.bn_eval = bn_eval + self.bn_frozen = bn_frozen + self.with_cp = with_cp + + self.inplanes = 64 + self.conv1 = nn.Conv2d( + 3, 64, kernel_size=7, stride=2, padding=3, bias=False) + self.bn1 = nn.BatchNorm2d(64) + self.relu = nn.ReLU(inplace=True) + self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) + + self.res_layers = [] + for i, num_blocks in enumerate(stage_blocks): + stride = strides[i] + dilation = dilations[i] + planes = 64 * 2**i + res_layer = make_res_layer( + block, + self.inplanes, + planes, + num_blocks, + stride=stride, + dilation=dilation, + style=self.style, + with_cp=with_cp) + self.inplanes = planes * block.expansion + layer_name = f'layer{i + 1}' + self.add_module(layer_name, res_layer) + self.res_layers.append(layer_name) + + self.feat_dim = block.expansion * 64 * 2**(len(stage_blocks) - 1) + + def init_weights(self, pretrained=None): + if isinstance(pretrained, str): + logger = logging.getLogger() + from ..runner import load_checkpoint + load_checkpoint(self, pretrained, strict=False, logger=logger) + elif pretrained is None: + for m in self.modules(): + if isinstance(m, nn.Conv2d): + kaiming_init(m) + elif isinstance(m, nn.BatchNorm2d): + constant_init(m, 1) + else: + raise TypeError('pretrained must be a str or None') + + def forward(self, x): + x = self.conv1(x) + x = self.bn1(x) + x = self.relu(x) + x = self.maxpool(x) + outs = [] + for i, layer_name in enumerate(self.res_layers): + res_layer = getattr(self, layer_name) + x = res_layer(x) + if i in self.out_indices: + outs.append(x) + if len(outs) == 1: + return outs[0] + else: + return tuple(outs) + + def train(self, mode=True): + super(ResNet, self).train(mode) + if self.bn_eval: + for m in self.modules(): + if isinstance(m, nn.BatchNorm2d): + m.eval() + if self.bn_frozen: + for params in m.parameters(): + params.requires_grad = False + if mode and self.frozen_stages >= 0: + for param in self.conv1.parameters(): + param.requires_grad = False + for param in self.bn1.parameters(): + param.requires_grad = False + self.bn1.eval() + self.bn1.weight.requires_grad = False + self.bn1.bias.requires_grad = False + for i in range(1, self.frozen_stages + 1): + mod = getattr(self, f'layer{i}') + mod.eval() + for param in mod.parameters(): + param.requires_grad = False diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/__init__.py new file mode 100644 index 00000000..a263e31c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/__init__.py @@ -0,0 +1,19 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .flops_counter import get_model_complexity_info +from .fuse_conv_bn import fuse_conv_bn +from .sync_bn import revert_sync_batchnorm +from .weight_init import (INITIALIZERS, Caffe2XavierInit, ConstantInit, + KaimingInit, NormalInit, PretrainedInit, + TruncNormalInit, UniformInit, XavierInit, + bias_init_with_prob, caffe2_xavier_init, + constant_init, initialize, kaiming_init, normal_init, + trunc_normal_init, uniform_init, xavier_init) + +__all__ = [ + 'get_model_complexity_info', 'bias_init_with_prob', 'caffe2_xavier_init', + 'constant_init', 'kaiming_init', 'normal_init', 'trunc_normal_init', + 'uniform_init', 'xavier_init', 'fuse_conv_bn', 'initialize', + 'INITIALIZERS', 'ConstantInit', 'XavierInit', 'NormalInit', + 'TruncNormalInit', 'UniformInit', 'KaimingInit', 'PretrainedInit', + 'Caffe2XavierInit', 'revert_sync_batchnorm' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/flops_counter.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/flops_counter.py new file mode 100644 index 00000000..104240bf --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/flops_counter.py @@ -0,0 +1,599 @@ +# Modified from flops-counter.pytorch by Vladislav Sovrasov +# original repo: https://github.com/sovrasov/flops-counter.pytorch + +# MIT License + +# Copyright (c) 2018 Vladislav Sovrasov + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import sys +from functools import partial + +import numpy as np +import torch +import torch.nn as nn + +import annotator.mmpkg.mmcv as mmcv + + +def get_model_complexity_info(model, + input_shape, + print_per_layer_stat=True, + as_strings=True, + input_constructor=None, + flush=False, + ost=sys.stdout): + """Get complexity information of a model. + + This method can calculate FLOPs and parameter counts of a model with + corresponding input shape. It can also print complexity information for + each layer in a model. + + Supported layers are listed as below: + - Convolutions: ``nn.Conv1d``, ``nn.Conv2d``, ``nn.Conv3d``. + - Activations: ``nn.ReLU``, ``nn.PReLU``, ``nn.ELU``, ``nn.LeakyReLU``, + ``nn.ReLU6``. + - Poolings: ``nn.MaxPool1d``, ``nn.MaxPool2d``, ``nn.MaxPool3d``, + ``nn.AvgPool1d``, ``nn.AvgPool2d``, ``nn.AvgPool3d``, + ``nn.AdaptiveMaxPool1d``, ``nn.AdaptiveMaxPool2d``, + ``nn.AdaptiveMaxPool3d``, ``nn.AdaptiveAvgPool1d``, + ``nn.AdaptiveAvgPool2d``, ``nn.AdaptiveAvgPool3d``. + - BatchNorms: ``nn.BatchNorm1d``, ``nn.BatchNorm2d``, + ``nn.BatchNorm3d``, ``nn.GroupNorm``, ``nn.InstanceNorm1d``, + ``InstanceNorm2d``, ``InstanceNorm3d``, ``nn.LayerNorm``. + - Linear: ``nn.Linear``. + - Deconvolution: ``nn.ConvTranspose2d``. + - Upsample: ``nn.Upsample``. + + Args: + model (nn.Module): The model for complexity calculation. + input_shape (tuple): Input shape used for calculation. + print_per_layer_stat (bool): Whether to print complexity information + for each layer in a model. Default: True. + as_strings (bool): Output FLOPs and params counts in a string form. + Default: True. + input_constructor (None | callable): If specified, it takes a callable + method that generates input. otherwise, it will generate a random + tensor with input shape to calculate FLOPs. Default: None. + flush (bool): same as that in :func:`print`. Default: False. + ost (stream): same as ``file`` param in :func:`print`. + Default: sys.stdout. + + Returns: + tuple[float | str]: If ``as_strings`` is set to True, it will return + FLOPs and parameter counts in a string format. otherwise, it will + return those in a float number format. + """ + assert type(input_shape) is tuple + assert len(input_shape) >= 1 + assert isinstance(model, nn.Module) + flops_model = add_flops_counting_methods(model) + flops_model.eval() + flops_model.start_flops_count() + if input_constructor: + input = input_constructor(input_shape) + _ = flops_model(**input) + else: + try: + batch = torch.ones(()).new_empty( + (1, *input_shape), + dtype=next(flops_model.parameters()).dtype, + device=next(flops_model.parameters()).device) + except StopIteration: + # Avoid StopIteration for models which have no parameters, + # like `nn.Relu()`, `nn.AvgPool2d`, etc. + batch = torch.ones(()).new_empty((1, *input_shape)) + + _ = flops_model(batch) + + flops_count, params_count = flops_model.compute_average_flops_cost() + if print_per_layer_stat: + print_model_with_flops( + flops_model, flops_count, params_count, ost=ost, flush=flush) + flops_model.stop_flops_count() + + if as_strings: + return flops_to_string(flops_count), params_to_string(params_count) + + return flops_count, params_count + + +def flops_to_string(flops, units='GFLOPs', precision=2): + """Convert FLOPs number into a string. + + Note that Here we take a multiply-add counts as one FLOP. + + Args: + flops (float): FLOPs number to be converted. + units (str | None): Converted FLOPs units. Options are None, 'GFLOPs', + 'MFLOPs', 'KFLOPs', 'FLOPs'. If set to None, it will automatically + choose the most suitable unit for FLOPs. Default: 'GFLOPs'. + precision (int): Digit number after the decimal point. Default: 2. + + Returns: + str: The converted FLOPs number with units. + + Examples: + >>> flops_to_string(1e9) + '1.0 GFLOPs' + >>> flops_to_string(2e5, 'MFLOPs') + '0.2 MFLOPs' + >>> flops_to_string(3e-9, None) + '3e-09 FLOPs' + """ + if units is None: + if flops // 10**9 > 0: + return str(round(flops / 10.**9, precision)) + ' GFLOPs' + elif flops // 10**6 > 0: + return str(round(flops / 10.**6, precision)) + ' MFLOPs' + elif flops // 10**3 > 0: + return str(round(flops / 10.**3, precision)) + ' KFLOPs' + else: + return str(flops) + ' FLOPs' + else: + if units == 'GFLOPs': + return str(round(flops / 10.**9, precision)) + ' ' + units + elif units == 'MFLOPs': + return str(round(flops / 10.**6, precision)) + ' ' + units + elif units == 'KFLOPs': + return str(round(flops / 10.**3, precision)) + ' ' + units + else: + return str(flops) + ' FLOPs' + + +def params_to_string(num_params, units=None, precision=2): + """Convert parameter number into a string. + + Args: + num_params (float): Parameter number to be converted. + units (str | None): Converted FLOPs units. Options are None, 'M', + 'K' and ''. If set to None, it will automatically choose the most + suitable unit for Parameter number. Default: None. + precision (int): Digit number after the decimal point. Default: 2. + + Returns: + str: The converted parameter number with units. + + Examples: + >>> params_to_string(1e9) + '1000.0 M' + >>> params_to_string(2e5) + '200.0 k' + >>> params_to_string(3e-9) + '3e-09' + """ + if units is None: + if num_params // 10**6 > 0: + return str(round(num_params / 10**6, precision)) + ' M' + elif num_params // 10**3: + return str(round(num_params / 10**3, precision)) + ' k' + else: + return str(num_params) + else: + if units == 'M': + return str(round(num_params / 10.**6, precision)) + ' ' + units + elif units == 'K': + return str(round(num_params / 10.**3, precision)) + ' ' + units + else: + return str(num_params) + + +def print_model_with_flops(model, + total_flops, + total_params, + units='GFLOPs', + precision=3, + ost=sys.stdout, + flush=False): + """Print a model with FLOPs for each layer. + + Args: + model (nn.Module): The model to be printed. + total_flops (float): Total FLOPs of the model. + total_params (float): Total parameter counts of the model. + units (str | None): Converted FLOPs units. Default: 'GFLOPs'. + precision (int): Digit number after the decimal point. Default: 3. + ost (stream): same as `file` param in :func:`print`. + Default: sys.stdout. + flush (bool): same as that in :func:`print`. Default: False. + + Example: + >>> class ExampleModel(nn.Module): + + >>> def __init__(self): + >>> super().__init__() + >>> self.conv1 = nn.Conv2d(3, 8, 3) + >>> self.conv2 = nn.Conv2d(8, 256, 3) + >>> self.conv3 = nn.Conv2d(256, 8, 3) + >>> self.avg_pool = nn.AdaptiveAvgPool2d((1, 1)) + >>> self.flatten = nn.Flatten() + >>> self.fc = nn.Linear(8, 1) + + >>> def forward(self, x): + >>> x = self.conv1(x) + >>> x = self.conv2(x) + >>> x = self.conv3(x) + >>> x = self.avg_pool(x) + >>> x = self.flatten(x) + >>> x = self.fc(x) + >>> return x + + >>> model = ExampleModel() + >>> x = (3, 16, 16) + to print the complexity information state for each layer, you can use + >>> get_model_complexity_info(model, x) + or directly use + >>> print_model_with_flops(model, 4579784.0, 37361) + ExampleModel( + 0.037 M, 100.000% Params, 0.005 GFLOPs, 100.000% FLOPs, + (conv1): Conv2d(0.0 M, 0.600% Params, 0.0 GFLOPs, 0.959% FLOPs, 3, 8, kernel_size=(3, 3), stride=(1, 1)) # noqa: E501 + (conv2): Conv2d(0.019 M, 50.020% Params, 0.003 GFLOPs, 58.760% FLOPs, 8, 256, kernel_size=(3, 3), stride=(1, 1)) + (conv3): Conv2d(0.018 M, 49.356% Params, 0.002 GFLOPs, 40.264% FLOPs, 256, 8, kernel_size=(3, 3), stride=(1, 1)) + (avg_pool): AdaptiveAvgPool2d(0.0 M, 0.000% Params, 0.0 GFLOPs, 0.017% FLOPs, output_size=(1, 1)) + (flatten): Flatten(0.0 M, 0.000% Params, 0.0 GFLOPs, 0.000% FLOPs, ) + (fc): Linear(0.0 M, 0.024% Params, 0.0 GFLOPs, 0.000% FLOPs, in_features=8, out_features=1, bias=True) + ) + """ + + def accumulate_params(self): + if is_supported_instance(self): + return self.__params__ + else: + sum = 0 + for m in self.children(): + sum += m.accumulate_params() + return sum + + def accumulate_flops(self): + if is_supported_instance(self): + return self.__flops__ / model.__batch_counter__ + else: + sum = 0 + for m in self.children(): + sum += m.accumulate_flops() + return sum + + def flops_repr(self): + accumulated_num_params = self.accumulate_params() + accumulated_flops_cost = self.accumulate_flops() + return ', '.join([ + params_to_string( + accumulated_num_params, units='M', precision=precision), + '{:.3%} Params'.format(accumulated_num_params / total_params), + flops_to_string( + accumulated_flops_cost, units=units, precision=precision), + '{:.3%} FLOPs'.format(accumulated_flops_cost / total_flops), + self.original_extra_repr() + ]) + + def add_extra_repr(m): + m.accumulate_flops = accumulate_flops.__get__(m) + m.accumulate_params = accumulate_params.__get__(m) + flops_extra_repr = flops_repr.__get__(m) + if m.extra_repr != flops_extra_repr: + m.original_extra_repr = m.extra_repr + m.extra_repr = flops_extra_repr + assert m.extra_repr != m.original_extra_repr + + def del_extra_repr(m): + if hasattr(m, 'original_extra_repr'): + m.extra_repr = m.original_extra_repr + del m.original_extra_repr + if hasattr(m, 'accumulate_flops'): + del m.accumulate_flops + + model.apply(add_extra_repr) + print(model, file=ost, flush=flush) + model.apply(del_extra_repr) + + +def get_model_parameters_number(model): + """Calculate parameter number of a model. + + Args: + model (nn.module): The model for parameter number calculation. + + Returns: + float: Parameter number of the model. + """ + num_params = sum(p.numel() for p in model.parameters() if p.requires_grad) + return num_params + + +def add_flops_counting_methods(net_main_module): + # adding additional methods to the existing module object, + # this is done this way so that each function has access to self object + net_main_module.start_flops_count = start_flops_count.__get__( + net_main_module) + net_main_module.stop_flops_count = stop_flops_count.__get__( + net_main_module) + net_main_module.reset_flops_count = reset_flops_count.__get__( + net_main_module) + net_main_module.compute_average_flops_cost = compute_average_flops_cost.__get__( # noqa: E501 + net_main_module) + + net_main_module.reset_flops_count() + + return net_main_module + + +def compute_average_flops_cost(self): + """Compute average FLOPs cost. + + A method to compute average FLOPs cost, which will be available after + `add_flops_counting_methods()` is called on a desired net object. + + Returns: + float: Current mean flops consumption per image. + """ + batches_count = self.__batch_counter__ + flops_sum = 0 + for module in self.modules(): + if is_supported_instance(module): + flops_sum += module.__flops__ + params_sum = get_model_parameters_number(self) + return flops_sum / batches_count, params_sum + + +def start_flops_count(self): + """Activate the computation of mean flops consumption per image. + + A method to activate the computation of mean flops consumption per image. + which will be available after ``add_flops_counting_methods()`` is called on + a desired net object. It should be called before running the network. + """ + add_batch_counter_hook_function(self) + + def add_flops_counter_hook_function(module): + if is_supported_instance(module): + if hasattr(module, '__flops_handle__'): + return + + else: + handle = module.register_forward_hook( + get_modules_mapping()[type(module)]) + + module.__flops_handle__ = handle + + self.apply(partial(add_flops_counter_hook_function)) + + +def stop_flops_count(self): + """Stop computing the mean flops consumption per image. + + A method to stop computing the mean flops consumption per image, which will + be available after ``add_flops_counting_methods()`` is called on a desired + net object. It can be called to pause the computation whenever. + """ + remove_batch_counter_hook_function(self) + self.apply(remove_flops_counter_hook_function) + + +def reset_flops_count(self): + """Reset statistics computed so far. + + A method to Reset computed statistics, which will be available after + `add_flops_counting_methods()` is called on a desired net object. + """ + add_batch_counter_variables_or_reset(self) + self.apply(add_flops_counter_variable_or_reset) + + +# ---- Internal functions +def empty_flops_counter_hook(module, input, output): + module.__flops__ += 0 + + +def upsample_flops_counter_hook(module, input, output): + output_size = output[0] + batch_size = output_size.shape[0] + output_elements_count = batch_size + for val in output_size.shape[1:]: + output_elements_count *= val + module.__flops__ += int(output_elements_count) + + +def relu_flops_counter_hook(module, input, output): + active_elements_count = output.numel() + module.__flops__ += int(active_elements_count) + + +def linear_flops_counter_hook(module, input, output): + input = input[0] + output_last_dim = output.shape[ + -1] # pytorch checks dimensions, so here we don't care much + module.__flops__ += int(np.prod(input.shape) * output_last_dim) + + +def pool_flops_counter_hook(module, input, output): + input = input[0] + module.__flops__ += int(np.prod(input.shape)) + + +def norm_flops_counter_hook(module, input, output): + input = input[0] + + batch_flops = np.prod(input.shape) + if (getattr(module, 'affine', False) + or getattr(module, 'elementwise_affine', False)): + batch_flops *= 2 + module.__flops__ += int(batch_flops) + + +def deconv_flops_counter_hook(conv_module, input, output): + # Can have multiple inputs, getting the first one + input = input[0] + + batch_size = input.shape[0] + input_height, input_width = input.shape[2:] + + kernel_height, kernel_width = conv_module.kernel_size + in_channels = conv_module.in_channels + out_channels = conv_module.out_channels + groups = conv_module.groups + + filters_per_channel = out_channels // groups + conv_per_position_flops = ( + kernel_height * kernel_width * in_channels * filters_per_channel) + + active_elements_count = batch_size * input_height * input_width + overall_conv_flops = conv_per_position_flops * active_elements_count + bias_flops = 0 + if conv_module.bias is not None: + output_height, output_width = output.shape[2:] + bias_flops = out_channels * batch_size * output_height * output_height + overall_flops = overall_conv_flops + bias_flops + + conv_module.__flops__ += int(overall_flops) + + +def conv_flops_counter_hook(conv_module, input, output): + # Can have multiple inputs, getting the first one + input = input[0] + + batch_size = input.shape[0] + output_dims = list(output.shape[2:]) + + kernel_dims = list(conv_module.kernel_size) + in_channels = conv_module.in_channels + out_channels = conv_module.out_channels + groups = conv_module.groups + + filters_per_channel = out_channels // groups + conv_per_position_flops = int( + np.prod(kernel_dims)) * in_channels * filters_per_channel + + active_elements_count = batch_size * int(np.prod(output_dims)) + + overall_conv_flops = conv_per_position_flops * active_elements_count + + bias_flops = 0 + + if conv_module.bias is not None: + + bias_flops = out_channels * active_elements_count + + overall_flops = overall_conv_flops + bias_flops + + conv_module.__flops__ += int(overall_flops) + + +def batch_counter_hook(module, input, output): + batch_size = 1 + if len(input) > 0: + # Can have multiple inputs, getting the first one + input = input[0] + batch_size = len(input) + else: + pass + print('Warning! No positional inputs found for a module, ' + 'assuming batch size is 1.') + module.__batch_counter__ += batch_size + + +def add_batch_counter_variables_or_reset(module): + + module.__batch_counter__ = 0 + + +def add_batch_counter_hook_function(module): + if hasattr(module, '__batch_counter_handle__'): + return + + handle = module.register_forward_hook(batch_counter_hook) + module.__batch_counter_handle__ = handle + + +def remove_batch_counter_hook_function(module): + if hasattr(module, '__batch_counter_handle__'): + module.__batch_counter_handle__.remove() + del module.__batch_counter_handle__ + + +def add_flops_counter_variable_or_reset(module): + if is_supported_instance(module): + if hasattr(module, '__flops__') or hasattr(module, '__params__'): + print('Warning: variables __flops__ or __params__ are already ' + 'defined for the module' + type(module).__name__ + + ' ptflops can affect your code!') + module.__flops__ = 0 + module.__params__ = get_model_parameters_number(module) + + +def is_supported_instance(module): + if type(module) in get_modules_mapping(): + return True + return False + + +def remove_flops_counter_hook_function(module): + if is_supported_instance(module): + if hasattr(module, '__flops_handle__'): + module.__flops_handle__.remove() + del module.__flops_handle__ + + +def get_modules_mapping(): + return { + # convolutions + nn.Conv1d: conv_flops_counter_hook, + nn.Conv2d: conv_flops_counter_hook, + mmcv.cnn.bricks.Conv2d: conv_flops_counter_hook, + nn.Conv3d: conv_flops_counter_hook, + mmcv.cnn.bricks.Conv3d: conv_flops_counter_hook, + # activations + nn.ReLU: relu_flops_counter_hook, + nn.PReLU: relu_flops_counter_hook, + nn.ELU: relu_flops_counter_hook, + nn.LeakyReLU: relu_flops_counter_hook, + nn.ReLU6: relu_flops_counter_hook, + # poolings + nn.MaxPool1d: pool_flops_counter_hook, + nn.AvgPool1d: pool_flops_counter_hook, + nn.AvgPool2d: pool_flops_counter_hook, + nn.MaxPool2d: pool_flops_counter_hook, + mmcv.cnn.bricks.MaxPool2d: pool_flops_counter_hook, + nn.MaxPool3d: pool_flops_counter_hook, + mmcv.cnn.bricks.MaxPool3d: pool_flops_counter_hook, + nn.AvgPool3d: pool_flops_counter_hook, + nn.AdaptiveMaxPool1d: pool_flops_counter_hook, + nn.AdaptiveAvgPool1d: pool_flops_counter_hook, + nn.AdaptiveMaxPool2d: pool_flops_counter_hook, + nn.AdaptiveAvgPool2d: pool_flops_counter_hook, + nn.AdaptiveMaxPool3d: pool_flops_counter_hook, + nn.AdaptiveAvgPool3d: pool_flops_counter_hook, + # normalizations + nn.BatchNorm1d: norm_flops_counter_hook, + nn.BatchNorm2d: norm_flops_counter_hook, + nn.BatchNorm3d: norm_flops_counter_hook, + nn.GroupNorm: norm_flops_counter_hook, + nn.InstanceNorm1d: norm_flops_counter_hook, + nn.InstanceNorm2d: norm_flops_counter_hook, + nn.InstanceNorm3d: norm_flops_counter_hook, + nn.LayerNorm: norm_flops_counter_hook, + # FC + nn.Linear: linear_flops_counter_hook, + mmcv.cnn.bricks.Linear: linear_flops_counter_hook, + # Upscale + nn.Upsample: upsample_flops_counter_hook, + # Deconvolution + nn.ConvTranspose2d: deconv_flops_counter_hook, + mmcv.cnn.bricks.ConvTranspose2d: deconv_flops_counter_hook, + } diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/fuse_conv_bn.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/fuse_conv_bn.py new file mode 100644 index 00000000..cb7076f8 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/fuse_conv_bn.py @@ -0,0 +1,59 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.nn as nn + + +def _fuse_conv_bn(conv, bn): + """Fuse conv and bn into one module. + + Args: + conv (nn.Module): Conv to be fused. + bn (nn.Module): BN to be fused. + + Returns: + nn.Module: Fused module. + """ + conv_w = conv.weight + conv_b = conv.bias if conv.bias is not None else torch.zeros_like( + bn.running_mean) + + factor = bn.weight / torch.sqrt(bn.running_var + bn.eps) + conv.weight = nn.Parameter(conv_w * + factor.reshape([conv.out_channels, 1, 1, 1])) + conv.bias = nn.Parameter((conv_b - bn.running_mean) * factor + bn.bias) + return conv + + +def fuse_conv_bn(module): + """Recursively fuse conv and bn in a module. + + During inference, the functionary of batch norm layers is turned off + but only the mean and var alone channels are used, which exposes the + chance to fuse it with the preceding conv layers to save computations and + simplify network structures. + + Args: + module (nn.Module): Module to be fused. + + Returns: + nn.Module: Fused module. + """ + last_conv = None + last_conv_name = None + + for name, child in module.named_children(): + if isinstance(child, + (nn.modules.batchnorm._BatchNorm, nn.SyncBatchNorm)): + if last_conv is None: # only fuse BN that is after Conv + continue + fused_conv = _fuse_conv_bn(last_conv, child) + module._modules[last_conv_name] = fused_conv + # To reduce changes, set BN as Identity instead of deleting it. + module._modules[name] = nn.Identity() + last_conv = None + elif isinstance(child, nn.Conv2d): + last_conv = child + last_conv_name = name + else: + fuse_conv_bn(child) + return module diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/sync_bn.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/sync_bn.py new file mode 100644 index 00000000..c0dbcb1b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/sync_bn.py @@ -0,0 +1,59 @@ +import torch + +import annotator.mmpkg.mmcv as mmcv + + +class _BatchNormXd(torch.nn.modules.batchnorm._BatchNorm): + """A general BatchNorm layer without input dimension check. + + Reproduced from @kapily's work: + (https://github.com/pytorch/pytorch/issues/41081#issuecomment-783961547) + The only difference between BatchNorm1d, BatchNorm2d, BatchNorm3d, etc + is `_check_input_dim` that is designed for tensor sanity checks. + The check has been bypassed in this class for the convenience of converting + SyncBatchNorm. + """ + + def _check_input_dim(self, input): + return + + +def revert_sync_batchnorm(module): + """Helper function to convert all `SyncBatchNorm` (SyncBN) and + `mmcv.ops.sync_bn.SyncBatchNorm`(MMSyncBN) layers in the model to + `BatchNormXd` layers. + + Adapted from @kapily's work: + (https://github.com/pytorch/pytorch/issues/41081#issuecomment-783961547) + + Args: + module (nn.Module): The module containing `SyncBatchNorm` layers. + + Returns: + module_output: The converted module with `BatchNormXd` layers. + """ + module_output = module + module_checklist = [torch.nn.modules.batchnorm.SyncBatchNorm] + if hasattr(mmcv, 'ops'): + module_checklist.append(mmcv.ops.SyncBatchNorm) + if isinstance(module, tuple(module_checklist)): + module_output = _BatchNormXd(module.num_features, module.eps, + module.momentum, module.affine, + module.track_running_stats) + if module.affine: + # no_grad() may not be needed here but + # just to be consistent with `convert_sync_batchnorm()` + with torch.no_grad(): + module_output.weight = module.weight + module_output.bias = module.bias + module_output.running_mean = module.running_mean + module_output.running_var = module.running_var + module_output.num_batches_tracked = module.num_batches_tracked + module_output.training = module.training + # qconfig exists in quantized models + if hasattr(module, 'qconfig'): + module_output.qconfig = module.qconfig + for name, child in module.named_children(): + module_output.add_module(name, revert_sync_batchnorm(child)) + del module + return module_output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/weight_init.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/weight_init.py new file mode 100644 index 00000000..096d0ddc --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/utils/weight_init.py @@ -0,0 +1,684 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import copy +import math +import warnings + +import numpy as np +import torch +import torch.nn as nn +from torch import Tensor + +from annotator.mmpkg.mmcv.utils import Registry, build_from_cfg, get_logger, print_log + +INITIALIZERS = Registry('initializer') + + +def update_init_info(module, init_info): + """Update the `_params_init_info` in the module if the value of parameters + are changed. + + Args: + module (obj:`nn.Module`): The module of PyTorch with a user-defined + attribute `_params_init_info` which records the initialization + information. + init_info (str): The string that describes the initialization. + """ + assert hasattr( + module, + '_params_init_info'), f'Can not find `_params_init_info` in {module}' + for name, param in module.named_parameters(): + + assert param in module._params_init_info, ( + f'Find a new :obj:`Parameter` ' + f'named `{name}` during executing the ' + f'`init_weights` of ' + f'`{module.__class__.__name__}`. ' + f'Please do not add or ' + f'replace parameters during executing ' + f'the `init_weights`. ') + + # The parameter has been changed during executing the + # `init_weights` of module + mean_value = param.data.mean() + if module._params_init_info[param]['tmp_mean_value'] != mean_value: + module._params_init_info[param]['init_info'] = init_info + module._params_init_info[param]['tmp_mean_value'] = mean_value + + +def constant_init(module, val, bias=0): + if hasattr(module, 'weight') and module.weight is not None: + nn.init.constant_(module.weight, val) + if hasattr(module, 'bias') and module.bias is not None: + nn.init.constant_(module.bias, bias) + + +def xavier_init(module, gain=1, bias=0, distribution='normal'): + assert distribution in ['uniform', 'normal'] + if hasattr(module, 'weight') and module.weight is not None: + if distribution == 'uniform': + nn.init.xavier_uniform_(module.weight, gain=gain) + else: + nn.init.xavier_normal_(module.weight, gain=gain) + if hasattr(module, 'bias') and module.bias is not None: + nn.init.constant_(module.bias, bias) + + +def normal_init(module, mean=0, std=1, bias=0): + if hasattr(module, 'weight') and module.weight is not None: + nn.init.normal_(module.weight, mean, std) + if hasattr(module, 'bias') and module.bias is not None: + nn.init.constant_(module.bias, bias) + + +def trunc_normal_init(module: nn.Module, + mean: float = 0, + std: float = 1, + a: float = -2, + b: float = 2, + bias: float = 0) -> None: + if hasattr(module, 'weight') and module.weight is not None: + trunc_normal_(module.weight, mean, std, a, b) # type: ignore + if hasattr(module, 'bias') and module.bias is not None: + nn.init.constant_(module.bias, bias) # type: ignore + + +def uniform_init(module, a=0, b=1, bias=0): + if hasattr(module, 'weight') and module.weight is not None: + nn.init.uniform_(module.weight, a, b) + if hasattr(module, 'bias') and module.bias is not None: + nn.init.constant_(module.bias, bias) + + +def kaiming_init(module, + a=0, + mode='fan_out', + nonlinearity='relu', + bias=0, + distribution='normal'): + assert distribution in ['uniform', 'normal'] + if hasattr(module, 'weight') and module.weight is not None: + if distribution == 'uniform': + nn.init.kaiming_uniform_( + module.weight, a=a, mode=mode, nonlinearity=nonlinearity) + else: + nn.init.kaiming_normal_( + module.weight, a=a, mode=mode, nonlinearity=nonlinearity) + if hasattr(module, 'bias') and module.bias is not None: + nn.init.constant_(module.bias, bias) + + +def caffe2_xavier_init(module, bias=0): + # `XavierFill` in Caffe2 corresponds to `kaiming_uniform_` in PyTorch + # Acknowledgment to FAIR's internal code + kaiming_init( + module, + a=1, + mode='fan_in', + nonlinearity='leaky_relu', + bias=bias, + distribution='uniform') + + +def bias_init_with_prob(prior_prob): + """initialize conv/fc bias value according to a given probability value.""" + bias_init = float(-np.log((1 - prior_prob) / prior_prob)) + return bias_init + + +def _get_bases_name(m): + return [b.__name__ for b in m.__class__.__bases__] + + +class BaseInit(object): + + def __init__(self, *, bias=0, bias_prob=None, layer=None): + self.wholemodule = False + if not isinstance(bias, (int, float)): + raise TypeError(f'bias must be a number, but got a {type(bias)}') + + if bias_prob is not None: + if not isinstance(bias_prob, float): + raise TypeError(f'bias_prob type must be float, \ + but got {type(bias_prob)}') + + if layer is not None: + if not isinstance(layer, (str, list)): + raise TypeError(f'layer must be a str or a list of str, \ + but got a {type(layer)}') + else: + layer = [] + + if bias_prob is not None: + self.bias = bias_init_with_prob(bias_prob) + else: + self.bias = bias + self.layer = [layer] if isinstance(layer, str) else layer + + def _get_init_info(self): + info = f'{self.__class__.__name__}, bias={self.bias}' + return info + + +@INITIALIZERS.register_module(name='Constant') +class ConstantInit(BaseInit): + """Initialize module parameters with constant values. + + Args: + val (int | float): the value to fill the weights in the module with + bias (int | float): the value to fill the bias. Defaults to 0. + bias_prob (float, optional): the probability for bias initialization. + Defaults to None. + layer (str | list[str], optional): the layer will be initialized. + Defaults to None. + """ + + def __init__(self, val, **kwargs): + super().__init__(**kwargs) + self.val = val + + def __call__(self, module): + + def init(m): + if self.wholemodule: + constant_init(m, self.val, self.bias) + else: + layername = m.__class__.__name__ + basesname = _get_bases_name(m) + if len(set(self.layer) & set([layername] + basesname)): + constant_init(m, self.val, self.bias) + + module.apply(init) + if hasattr(module, '_params_init_info'): + update_init_info(module, init_info=self._get_init_info()) + + def _get_init_info(self): + info = f'{self.__class__.__name__}: val={self.val}, bias={self.bias}' + return info + + +@INITIALIZERS.register_module(name='Xavier') +class XavierInit(BaseInit): + r"""Initialize module parameters with values according to the method + described in `Understanding the difficulty of training deep feedforward + neural networks - Glorot, X. & Bengio, Y. (2010). + `_ + + Args: + gain (int | float): an optional scaling factor. Defaults to 1. + bias (int | float): the value to fill the bias. Defaults to 0. + bias_prob (float, optional): the probability for bias initialization. + Defaults to None. + distribution (str): distribution either be ``'normal'`` + or ``'uniform'``. Defaults to ``'normal'``. + layer (str | list[str], optional): the layer will be initialized. + Defaults to None. + """ + + def __init__(self, gain=1, distribution='normal', **kwargs): + super().__init__(**kwargs) + self.gain = gain + self.distribution = distribution + + def __call__(self, module): + + def init(m): + if self.wholemodule: + xavier_init(m, self.gain, self.bias, self.distribution) + else: + layername = m.__class__.__name__ + basesname = _get_bases_name(m) + if len(set(self.layer) & set([layername] + basesname)): + xavier_init(m, self.gain, self.bias, self.distribution) + + module.apply(init) + if hasattr(module, '_params_init_info'): + update_init_info(module, init_info=self._get_init_info()) + + def _get_init_info(self): + info = f'{self.__class__.__name__}: gain={self.gain}, ' \ + f'distribution={self.distribution}, bias={self.bias}' + return info + + +@INITIALIZERS.register_module(name='Normal') +class NormalInit(BaseInit): + r"""Initialize module parameters with the values drawn from the normal + distribution :math:`\mathcal{N}(\text{mean}, \text{std}^2)`. + + Args: + mean (int | float):the mean of the normal distribution. Defaults to 0. + std (int | float): the standard deviation of the normal distribution. + Defaults to 1. + bias (int | float): the value to fill the bias. Defaults to 0. + bias_prob (float, optional): the probability for bias initialization. + Defaults to None. + layer (str | list[str], optional): the layer will be initialized. + Defaults to None. + + """ + + def __init__(self, mean=0, std=1, **kwargs): + super().__init__(**kwargs) + self.mean = mean + self.std = std + + def __call__(self, module): + + def init(m): + if self.wholemodule: + normal_init(m, self.mean, self.std, self.bias) + else: + layername = m.__class__.__name__ + basesname = _get_bases_name(m) + if len(set(self.layer) & set([layername] + basesname)): + normal_init(m, self.mean, self.std, self.bias) + + module.apply(init) + if hasattr(module, '_params_init_info'): + update_init_info(module, init_info=self._get_init_info()) + + def _get_init_info(self): + info = f'{self.__class__.__name__}: mean={self.mean},' \ + f' std={self.std}, bias={self.bias}' + return info + + +@INITIALIZERS.register_module(name='TruncNormal') +class TruncNormalInit(BaseInit): + r"""Initialize module parameters with the values drawn from the normal + distribution :math:`\mathcal{N}(\text{mean}, \text{std}^2)` with values + outside :math:`[a, b]`. + + Args: + mean (float): the mean of the normal distribution. Defaults to 0. + std (float): the standard deviation of the normal distribution. + Defaults to 1. + a (float): The minimum cutoff value. + b ( float): The maximum cutoff value. + bias (float): the value to fill the bias. Defaults to 0. + bias_prob (float, optional): the probability for bias initialization. + Defaults to None. + layer (str | list[str], optional): the layer will be initialized. + Defaults to None. + + """ + + def __init__(self, + mean: float = 0, + std: float = 1, + a: float = -2, + b: float = 2, + **kwargs) -> None: + super().__init__(**kwargs) + self.mean = mean + self.std = std + self.a = a + self.b = b + + def __call__(self, module: nn.Module) -> None: + + def init(m): + if self.wholemodule: + trunc_normal_init(m, self.mean, self.std, self.a, self.b, + self.bias) + else: + layername = m.__class__.__name__ + basesname = _get_bases_name(m) + if len(set(self.layer) & set([layername] + basesname)): + trunc_normal_init(m, self.mean, self.std, self.a, self.b, + self.bias) + + module.apply(init) + if hasattr(module, '_params_init_info'): + update_init_info(module, init_info=self._get_init_info()) + + def _get_init_info(self): + info = f'{self.__class__.__name__}: a={self.a}, b={self.b},' \ + f' mean={self.mean}, std={self.std}, bias={self.bias}' + return info + + +@INITIALIZERS.register_module(name='Uniform') +class UniformInit(BaseInit): + r"""Initialize module parameters with values drawn from the uniform + distribution :math:`\mathcal{U}(a, b)`. + + Args: + a (int | float): the lower bound of the uniform distribution. + Defaults to 0. + b (int | float): the upper bound of the uniform distribution. + Defaults to 1. + bias (int | float): the value to fill the bias. Defaults to 0. + bias_prob (float, optional): the probability for bias initialization. + Defaults to None. + layer (str | list[str], optional): the layer will be initialized. + Defaults to None. + """ + + def __init__(self, a=0, b=1, **kwargs): + super().__init__(**kwargs) + self.a = a + self.b = b + + def __call__(self, module): + + def init(m): + if self.wholemodule: + uniform_init(m, self.a, self.b, self.bias) + else: + layername = m.__class__.__name__ + basesname = _get_bases_name(m) + if len(set(self.layer) & set([layername] + basesname)): + uniform_init(m, self.a, self.b, self.bias) + + module.apply(init) + if hasattr(module, '_params_init_info'): + update_init_info(module, init_info=self._get_init_info()) + + def _get_init_info(self): + info = f'{self.__class__.__name__}: a={self.a},' \ + f' b={self.b}, bias={self.bias}' + return info + + +@INITIALIZERS.register_module(name='Kaiming') +class KaimingInit(BaseInit): + r"""Initialize module parameters with the values according to the method + described in `Delving deep into rectifiers: Surpassing human-level + performance on ImageNet classification - He, K. et al. (2015). + `_ + + Args: + a (int | float): the negative slope of the rectifier used after this + layer (only used with ``'leaky_relu'``). Defaults to 0. + mode (str): either ``'fan_in'`` or ``'fan_out'``. Choosing + ``'fan_in'`` preserves the magnitude of the variance of the weights + in the forward pass. Choosing ``'fan_out'`` preserves the + magnitudes in the backwards pass. Defaults to ``'fan_out'``. + nonlinearity (str): the non-linear function (`nn.functional` name), + recommended to use only with ``'relu'`` or ``'leaky_relu'`` . + Defaults to 'relu'. + bias (int | float): the value to fill the bias. Defaults to 0. + bias_prob (float, optional): the probability for bias initialization. + Defaults to None. + distribution (str): distribution either be ``'normal'`` or + ``'uniform'``. Defaults to ``'normal'``. + layer (str | list[str], optional): the layer will be initialized. + Defaults to None. + """ + + def __init__(self, + a=0, + mode='fan_out', + nonlinearity='relu', + distribution='normal', + **kwargs): + super().__init__(**kwargs) + self.a = a + self.mode = mode + self.nonlinearity = nonlinearity + self.distribution = distribution + + def __call__(self, module): + + def init(m): + if self.wholemodule: + kaiming_init(m, self.a, self.mode, self.nonlinearity, + self.bias, self.distribution) + else: + layername = m.__class__.__name__ + basesname = _get_bases_name(m) + if len(set(self.layer) & set([layername] + basesname)): + kaiming_init(m, self.a, self.mode, self.nonlinearity, + self.bias, self.distribution) + + module.apply(init) + if hasattr(module, '_params_init_info'): + update_init_info(module, init_info=self._get_init_info()) + + def _get_init_info(self): + info = f'{self.__class__.__name__}: a={self.a}, mode={self.mode}, ' \ + f'nonlinearity={self.nonlinearity}, ' \ + f'distribution ={self.distribution}, bias={self.bias}' + return info + + +@INITIALIZERS.register_module(name='Caffe2Xavier') +class Caffe2XavierInit(KaimingInit): + # `XavierFill` in Caffe2 corresponds to `kaiming_uniform_` in PyTorch + # Acknowledgment to FAIR's internal code + def __init__(self, **kwargs): + super().__init__( + a=1, + mode='fan_in', + nonlinearity='leaky_relu', + distribution='uniform', + **kwargs) + + def __call__(self, module): + super().__call__(module) + + +@INITIALIZERS.register_module(name='Pretrained') +class PretrainedInit(object): + """Initialize module by loading a pretrained model. + + Args: + checkpoint (str): the checkpoint file of the pretrained model should + be load. + prefix (str, optional): the prefix of a sub-module in the pretrained + model. it is for loading a part of the pretrained model to + initialize. For example, if we would like to only load the + backbone of a detector model, we can set ``prefix='backbone.'``. + Defaults to None. + map_location (str): map tensors into proper locations. + """ + + def __init__(self, checkpoint, prefix=None, map_location=None): + self.checkpoint = checkpoint + self.prefix = prefix + self.map_location = map_location + + def __call__(self, module): + from annotator.mmpkg.mmcv.runner import (_load_checkpoint_with_prefix, load_checkpoint, + load_state_dict) + logger = get_logger('mmcv') + if self.prefix is None: + print_log(f'load model from: {self.checkpoint}', logger=logger) + load_checkpoint( + module, + self.checkpoint, + map_location=self.map_location, + strict=False, + logger=logger) + else: + print_log( + f'load {self.prefix} in model from: {self.checkpoint}', + logger=logger) + state_dict = _load_checkpoint_with_prefix( + self.prefix, self.checkpoint, map_location=self.map_location) + load_state_dict(module, state_dict, strict=False, logger=logger) + + if hasattr(module, '_params_init_info'): + update_init_info(module, init_info=self._get_init_info()) + + def _get_init_info(self): + info = f'{self.__class__.__name__}: load from {self.checkpoint}' + return info + + +def _initialize(module, cfg, wholemodule=False): + func = build_from_cfg(cfg, INITIALIZERS) + # wholemodule flag is for override mode, there is no layer key in override + # and initializer will give init values for the whole module with the name + # in override. + func.wholemodule = wholemodule + func(module) + + +def _initialize_override(module, override, cfg): + if not isinstance(override, (dict, list)): + raise TypeError(f'override must be a dict or a list of dict, \ + but got {type(override)}') + + override = [override] if isinstance(override, dict) else override + + for override_ in override: + + cp_override = copy.deepcopy(override_) + name = cp_override.pop('name', None) + if name is None: + raise ValueError('`override` must contain the key "name",' + f'but got {cp_override}') + # if override only has name key, it means use args in init_cfg + if not cp_override: + cp_override.update(cfg) + # if override has name key and other args except type key, it will + # raise error + elif 'type' not in cp_override.keys(): + raise ValueError( + f'`override` need "type" key, but got {cp_override}') + + if hasattr(module, name): + _initialize(getattr(module, name), cp_override, wholemodule=True) + else: + raise RuntimeError(f'module did not have attribute {name}, ' + f'but init_cfg is {cp_override}.') + + +def initialize(module, init_cfg): + """Initialize a module. + + Args: + module (``torch.nn.Module``): the module will be initialized. + init_cfg (dict | list[dict]): initialization configuration dict to + define initializer. OpenMMLab has implemented 6 initializers + including ``Constant``, ``Xavier``, ``Normal``, ``Uniform``, + ``Kaiming``, and ``Pretrained``. + Example: + >>> module = nn.Linear(2, 3, bias=True) + >>> init_cfg = dict(type='Constant', layer='Linear', val =1 , bias =2) + >>> initialize(module, init_cfg) + + >>> module = nn.Sequential(nn.Conv1d(3, 1, 3), nn.Linear(1,2)) + >>> # define key ``'layer'`` for initializing layer with different + >>> # configuration + >>> init_cfg = [dict(type='Constant', layer='Conv1d', val=1), + dict(type='Constant', layer='Linear', val=2)] + >>> initialize(module, init_cfg) + + >>> # define key``'override'`` to initialize some specific part in + >>> # module + >>> class FooNet(nn.Module): + >>> def __init__(self): + >>> super().__init__() + >>> self.feat = nn.Conv2d(3, 16, 3) + >>> self.reg = nn.Conv2d(16, 10, 3) + >>> self.cls = nn.Conv2d(16, 5, 3) + >>> model = FooNet() + >>> init_cfg = dict(type='Constant', val=1, bias=2, layer='Conv2d', + >>> override=dict(type='Constant', name='reg', val=3, bias=4)) + >>> initialize(model, init_cfg) + + >>> model = ResNet(depth=50) + >>> # Initialize weights with the pretrained model. + >>> init_cfg = dict(type='Pretrained', + checkpoint='torchvision://resnet50') + >>> initialize(model, init_cfg) + + >>> # Initialize weights of a sub-module with the specific part of + >>> # a pretrained model by using "prefix". + >>> url = 'http://download.openmmlab.com/mmdetection/v2.0/retinanet/'\ + >>> 'retinanet_r50_fpn_1x_coco/'\ + >>> 'retinanet_r50_fpn_1x_coco_20200130-c2398f9e.pth' + >>> init_cfg = dict(type='Pretrained', + checkpoint=url, prefix='backbone.') + """ + if not isinstance(init_cfg, (dict, list)): + raise TypeError(f'init_cfg must be a dict or a list of dict, \ + but got {type(init_cfg)}') + + if isinstance(init_cfg, dict): + init_cfg = [init_cfg] + + for cfg in init_cfg: + # should deeply copy the original config because cfg may be used by + # other modules, e.g., one init_cfg shared by multiple bottleneck + # blocks, the expected cfg will be changed after pop and will change + # the initialization behavior of other modules + cp_cfg = copy.deepcopy(cfg) + override = cp_cfg.pop('override', None) + _initialize(module, cp_cfg) + + if override is not None: + cp_cfg.pop('layer', None) + _initialize_override(module, override, cp_cfg) + else: + # All attributes in module have same initialization. + pass + + +def _no_grad_trunc_normal_(tensor: Tensor, mean: float, std: float, a: float, + b: float) -> Tensor: + # Method based on + # https://people.sc.fsu.edu/~jburkardt/presentations/truncated_normal.pdf + # Modified from + # https://github.com/pytorch/pytorch/blob/master/torch/nn/init.py + def norm_cdf(x): + # Computes standard normal cumulative distribution function + return (1. + math.erf(x / math.sqrt(2.))) / 2. + + if (mean < a - 2 * std) or (mean > b + 2 * std): + warnings.warn( + 'mean is more than 2 std from [a, b] in nn.init.trunc_normal_. ' + 'The distribution of values may be incorrect.', + stacklevel=2) + + with torch.no_grad(): + # Values are generated by using a truncated uniform distribution and + # then using the inverse CDF for the normal distribution. + # Get upper and lower cdf values + lower = norm_cdf((a - mean) / std) + upper = norm_cdf((b - mean) / std) + + # Uniformly fill tensor with values from [lower, upper], then translate + # to [2lower-1, 2upper-1]. + tensor.uniform_(2 * lower - 1, 2 * upper - 1) + + # Use inverse cdf transform for normal distribution to get truncated + # standard normal + tensor.erfinv_() + + # Transform to proper mean, std + tensor.mul_(std * math.sqrt(2.)) + tensor.add_(mean) + + # Clamp to ensure it's in the proper range + tensor.clamp_(min=a, max=b) + return tensor + + +def trunc_normal_(tensor: Tensor, + mean: float = 0., + std: float = 1., + a: float = -2., + b: float = 2.) -> Tensor: + r"""Fills the input Tensor with values drawn from a truncated + normal distribution. The values are effectively drawn from the + normal distribution :math:`\mathcal{N}(\text{mean}, \text{std}^2)` + with values outside :math:`[a, b]` redrawn until they are within + the bounds. The method used for generating the random values works + best when :math:`a \leq \text{mean} \leq b`. + + Modified from + https://github.com/pytorch/pytorch/blob/master/torch/nn/init.py + + Args: + tensor (``torch.Tensor``): an n-dimensional `torch.Tensor`. + mean (float): the mean of the normal distribution. + std (float): the standard deviation of the normal distribution. + a (float): the minimum cutoff value. + b (float): the maximum cutoff value. + """ + return _no_grad_trunc_normal_(tensor, mean, std, a, b) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/vgg.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/vgg.py new file mode 100644 index 00000000..8778b649 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/cnn/vgg.py @@ -0,0 +1,175 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import logging + +import torch.nn as nn + +from .utils import constant_init, kaiming_init, normal_init + + +def conv3x3(in_planes, out_planes, dilation=1): + """3x3 convolution with padding.""" + return nn.Conv2d( + in_planes, + out_planes, + kernel_size=3, + padding=dilation, + dilation=dilation) + + +def make_vgg_layer(inplanes, + planes, + num_blocks, + dilation=1, + with_bn=False, + ceil_mode=False): + layers = [] + for _ in range(num_blocks): + layers.append(conv3x3(inplanes, planes, dilation)) + if with_bn: + layers.append(nn.BatchNorm2d(planes)) + layers.append(nn.ReLU(inplace=True)) + inplanes = planes + layers.append(nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=ceil_mode)) + + return layers + + +class VGG(nn.Module): + """VGG backbone. + + Args: + depth (int): Depth of vgg, from {11, 13, 16, 19}. + with_bn (bool): Use BatchNorm or not. + num_classes (int): number of classes for classification. + num_stages (int): VGG stages, normally 5. + dilations (Sequence[int]): Dilation of each stage. + out_indices (Sequence[int]): Output from which stages. + frozen_stages (int): Stages to be frozen (all param fixed). -1 means + not freezing any parameters. + bn_eval (bool): Whether to set BN layers as eval mode, namely, freeze + running stats (mean and var). + bn_frozen (bool): Whether to freeze weight and bias of BN layers. + """ + + arch_settings = { + 11: (1, 1, 2, 2, 2), + 13: (2, 2, 2, 2, 2), + 16: (2, 2, 3, 3, 3), + 19: (2, 2, 4, 4, 4) + } + + def __init__(self, + depth, + with_bn=False, + num_classes=-1, + num_stages=5, + dilations=(1, 1, 1, 1, 1), + out_indices=(0, 1, 2, 3, 4), + frozen_stages=-1, + bn_eval=True, + bn_frozen=False, + ceil_mode=False, + with_last_pool=True): + super(VGG, self).__init__() + if depth not in self.arch_settings: + raise KeyError(f'invalid depth {depth} for vgg') + assert num_stages >= 1 and num_stages <= 5 + stage_blocks = self.arch_settings[depth] + self.stage_blocks = stage_blocks[:num_stages] + assert len(dilations) == num_stages + assert max(out_indices) <= num_stages + + self.num_classes = num_classes + self.out_indices = out_indices + self.frozen_stages = frozen_stages + self.bn_eval = bn_eval + self.bn_frozen = bn_frozen + + self.inplanes = 3 + start_idx = 0 + vgg_layers = [] + self.range_sub_modules = [] + for i, num_blocks in enumerate(self.stage_blocks): + num_modules = num_blocks * (2 + with_bn) + 1 + end_idx = start_idx + num_modules + dilation = dilations[i] + planes = 64 * 2**i if i < 4 else 512 + vgg_layer = make_vgg_layer( + self.inplanes, + planes, + num_blocks, + dilation=dilation, + with_bn=with_bn, + ceil_mode=ceil_mode) + vgg_layers.extend(vgg_layer) + self.inplanes = planes + self.range_sub_modules.append([start_idx, end_idx]) + start_idx = end_idx + if not with_last_pool: + vgg_layers.pop(-1) + self.range_sub_modules[-1][1] -= 1 + self.module_name = 'features' + self.add_module(self.module_name, nn.Sequential(*vgg_layers)) + + if self.num_classes > 0: + self.classifier = nn.Sequential( + nn.Linear(512 * 7 * 7, 4096), + nn.ReLU(True), + nn.Dropout(), + nn.Linear(4096, 4096), + nn.ReLU(True), + nn.Dropout(), + nn.Linear(4096, num_classes), + ) + + def init_weights(self, pretrained=None): + if isinstance(pretrained, str): + logger = logging.getLogger() + from ..runner import load_checkpoint + load_checkpoint(self, pretrained, strict=False, logger=logger) + elif pretrained is None: + for m in self.modules(): + if isinstance(m, nn.Conv2d): + kaiming_init(m) + elif isinstance(m, nn.BatchNorm2d): + constant_init(m, 1) + elif isinstance(m, nn.Linear): + normal_init(m, std=0.01) + else: + raise TypeError('pretrained must be a str or None') + + def forward(self, x): + outs = [] + vgg_layers = getattr(self, self.module_name) + for i in range(len(self.stage_blocks)): + for j in range(*self.range_sub_modules[i]): + vgg_layer = vgg_layers[j] + x = vgg_layer(x) + if i in self.out_indices: + outs.append(x) + if self.num_classes > 0: + x = x.view(x.size(0), -1) + x = self.classifier(x) + outs.append(x) + if len(outs) == 1: + return outs[0] + else: + return tuple(outs) + + def train(self, mode=True): + super(VGG, self).train(mode) + if self.bn_eval: + for m in self.modules(): + if isinstance(m, nn.BatchNorm2d): + m.eval() + if self.bn_frozen: + for params in m.parameters(): + params.requires_grad = False + vgg_layers = getattr(self, self.module_name) + if mode and self.frozen_stages >= 0: + for i in range(self.frozen_stages): + for j in range(*self.range_sub_modules[i]): + mod = vgg_layers[j] + mod.eval() + for param in mod.parameters(): + param.requires_grad = False diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/engine/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/engine/__init__.py new file mode 100644 index 00000000..3193b7f6 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/engine/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .test import (collect_results_cpu, collect_results_gpu, multi_gpu_test, + single_gpu_test) + +__all__ = [ + 'collect_results_cpu', 'collect_results_gpu', 'multi_gpu_test', + 'single_gpu_test' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/engine/test.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/engine/test.py new file mode 100644 index 00000000..ad5f55c4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/engine/test.py @@ -0,0 +1,202 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os.path as osp +import pickle +import shutil +import tempfile +import time + +import torch +import torch.distributed as dist + +import annotator.mmpkg.mmcv as mmcv +from annotator.mmpkg.mmcv.runner import get_dist_info + + +def single_gpu_test(model, data_loader): + """Test model with a single gpu. + + This method tests model with a single gpu and displays test progress bar. + + Args: + model (nn.Module): Model to be tested. + data_loader (nn.Dataloader): Pytorch data loader. + + Returns: + list: The prediction results. + """ + model.eval() + results = [] + dataset = data_loader.dataset + prog_bar = mmcv.ProgressBar(len(dataset)) + for data in data_loader: + with torch.no_grad(): + result = model(return_loss=False, **data) + results.extend(result) + + # Assume result has the same length of batch_size + # refer to https://github.com/open-mmlab/mmcv/issues/985 + batch_size = len(result) + for _ in range(batch_size): + prog_bar.update() + return results + + +def multi_gpu_test(model, data_loader, tmpdir=None, gpu_collect=False): + """Test model with multiple gpus. + + This method tests model with multiple gpus and collects the results + under two different modes: gpu and cpu modes. By setting + ``gpu_collect=True``, it encodes results to gpu tensors and use gpu + communication for results collection. On cpu mode it saves the results on + different gpus to ``tmpdir`` and collects them by the rank 0 worker. + + Args: + model (nn.Module): Model to be tested. + data_loader (nn.Dataloader): Pytorch data loader. + tmpdir (str): Path of directory to save the temporary results from + different gpus under cpu mode. + gpu_collect (bool): Option to use either gpu or cpu to collect results. + + Returns: + list: The prediction results. + """ + model.eval() + results = [] + dataset = data_loader.dataset + rank, world_size = get_dist_info() + if rank == 0: + prog_bar = mmcv.ProgressBar(len(dataset)) + time.sleep(2) # This line can prevent deadlock problem in some cases. + for i, data in enumerate(data_loader): + with torch.no_grad(): + result = model(return_loss=False, **data) + results.extend(result) + + if rank == 0: + batch_size = len(result) + batch_size_all = batch_size * world_size + if batch_size_all + prog_bar.completed > len(dataset): + batch_size_all = len(dataset) - prog_bar.completed + for _ in range(batch_size_all): + prog_bar.update() + + # collect results from all ranks + if gpu_collect: + results = collect_results_gpu(results, len(dataset)) + else: + results = collect_results_cpu(results, len(dataset), tmpdir) + return results + + +def collect_results_cpu(result_part, size, tmpdir=None): + """Collect results under cpu mode. + + On cpu mode, this function will save the results on different gpus to + ``tmpdir`` and collect them by the rank 0 worker. + + Args: + result_part (list): Result list containing result parts + to be collected. + size (int): Size of the results, commonly equal to length of + the results. + tmpdir (str | None): temporal directory for collected results to + store. If set to None, it will create a random temporal directory + for it. + + Returns: + list: The collected results. + """ + rank, world_size = get_dist_info() + # create a tmp dir if it is not specified + if tmpdir is None: + MAX_LEN = 512 + # 32 is whitespace + dir_tensor = torch.full((MAX_LEN, ), + 32, + dtype=torch.uint8, + device='cuda') + if rank == 0: + mmcv.mkdir_or_exist('.dist_test') + tmpdir = tempfile.mkdtemp(dir='.dist_test') + tmpdir = torch.tensor( + bytearray(tmpdir.encode()), dtype=torch.uint8, device='cuda') + dir_tensor[:len(tmpdir)] = tmpdir + dist.broadcast(dir_tensor, 0) + tmpdir = dir_tensor.cpu().numpy().tobytes().decode().rstrip() + else: + mmcv.mkdir_or_exist(tmpdir) + # dump the part result to the dir + mmcv.dump(result_part, osp.join(tmpdir, f'part_{rank}.pkl')) + dist.barrier() + # collect all parts + if rank != 0: + return None + else: + # load results of all parts from tmp dir + part_list = [] + for i in range(world_size): + part_file = osp.join(tmpdir, f'part_{i}.pkl') + part_result = mmcv.load(part_file) + # When data is severely insufficient, an empty part_result + # on a certain gpu could makes the overall outputs empty. + if part_result: + part_list.append(part_result) + # sort the results + ordered_results = [] + for res in zip(*part_list): + ordered_results.extend(list(res)) + # the dataloader may pad some samples + ordered_results = ordered_results[:size] + # remove tmp dir + shutil.rmtree(tmpdir) + return ordered_results + + +def collect_results_gpu(result_part, size): + """Collect results under gpu mode. + + On gpu mode, this function will encode results to gpu tensors and use gpu + communication for results collection. + + Args: + result_part (list): Result list containing result parts + to be collected. + size (int): Size of the results, commonly equal to length of + the results. + + Returns: + list: The collected results. + """ + rank, world_size = get_dist_info() + # dump result part to tensor with pickle + part_tensor = torch.tensor( + bytearray(pickle.dumps(result_part)), dtype=torch.uint8, device='cuda') + # gather all result part tensor shape + shape_tensor = torch.tensor(part_tensor.shape, device='cuda') + shape_list = [shape_tensor.clone() for _ in range(world_size)] + dist.all_gather(shape_list, shape_tensor) + # padding result part tensor to max length + shape_max = torch.tensor(shape_list).max() + part_send = torch.zeros(shape_max, dtype=torch.uint8, device='cuda') + part_send[:shape_tensor[0]] = part_tensor + part_recv_list = [ + part_tensor.new_zeros(shape_max) for _ in range(world_size) + ] + # gather all result part + dist.all_gather(part_recv_list, part_send) + + if rank == 0: + part_list = [] + for recv, shape in zip(part_recv_list, shape_list): + part_result = pickle.loads(recv[:shape[0]].cpu().numpy().tobytes()) + # When data is severely insufficient, an empty part_result + # on a certain gpu could makes the overall outputs empty. + if part_result: + part_list.append(part_result) + # sort the results + ordered_results = [] + for res in zip(*part_list): + ordered_results.extend(list(res)) + # the dataloader may pad some samples + ordered_results = ordered_results[:size] + return ordered_results diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/__init__.py new file mode 100644 index 00000000..2051b85f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/__init__.py @@ -0,0 +1,11 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .file_client import BaseStorageBackend, FileClient +from .handlers import BaseFileHandler, JsonHandler, PickleHandler, YamlHandler +from .io import dump, load, register_handler +from .parse import dict_from_file, list_from_file + +__all__ = [ + 'BaseStorageBackend', 'FileClient', 'load', 'dump', 'register_handler', + 'BaseFileHandler', 'JsonHandler', 'PickleHandler', 'YamlHandler', + 'list_from_file', 'dict_from_file' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/file_client.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/file_client.py new file mode 100644 index 00000000..1ed2bf5f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/file_client.py @@ -0,0 +1,1148 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import inspect +import os +import os.path as osp +import re +import tempfile +import warnings +from abc import ABCMeta, abstractmethod +from contextlib import contextmanager +from pathlib import Path +from typing import Iterable, Iterator, Optional, Tuple, Union +from urllib.request import urlopen + +import annotator.mmpkg.mmcv as mmcv +from annotator.mmpkg.mmcv.utils.misc import has_method +from annotator.mmpkg.mmcv.utils.path import is_filepath + + +class BaseStorageBackend(metaclass=ABCMeta): + """Abstract class of storage backends. + + All backends need to implement two apis: ``get()`` and ``get_text()``. + ``get()`` reads the file as a byte stream and ``get_text()`` reads the file + as texts. + """ + + # a flag to indicate whether the backend can create a symlink for a file + _allow_symlink = False + + @property + def name(self): + return self.__class__.__name__ + + @property + def allow_symlink(self): + return self._allow_symlink + + @abstractmethod + def get(self, filepath): + pass + + @abstractmethod + def get_text(self, filepath): + pass + + +class CephBackend(BaseStorageBackend): + """Ceph storage backend (for internal use). + + Args: + path_mapping (dict|None): path mapping dict from local path to Petrel + path. When ``path_mapping={'src': 'dst'}``, ``src`` in ``filepath`` + will be replaced by ``dst``. Default: None. + + .. warning:: + :class:`mmcv.fileio.file_client.CephBackend` will be deprecated, + please use :class:`mmcv.fileio.file_client.PetrelBackend` instead. + """ + + def __init__(self, path_mapping=None): + try: + import ceph + except ImportError: + raise ImportError('Please install ceph to enable CephBackend.') + + warnings.warn( + 'CephBackend will be deprecated, please use PetrelBackend instead') + self._client = ceph.S3Client() + assert isinstance(path_mapping, dict) or path_mapping is None + self.path_mapping = path_mapping + + def get(self, filepath): + filepath = str(filepath) + if self.path_mapping is not None: + for k, v in self.path_mapping.items(): + filepath = filepath.replace(k, v) + value = self._client.Get(filepath) + value_buf = memoryview(value) + return value_buf + + def get_text(self, filepath, encoding=None): + raise NotImplementedError + + +class PetrelBackend(BaseStorageBackend): + """Petrel storage backend (for internal use). + + PetrelBackend supports reading and writing data to multiple clusters. + If the file path contains the cluster name, PetrelBackend will read data + from specified cluster or write data to it. Otherwise, PetrelBackend will + access the default cluster. + + Args: + path_mapping (dict, optional): Path mapping dict from local path to + Petrel path. When ``path_mapping={'src': 'dst'}``, ``src`` in + ``filepath`` will be replaced by ``dst``. Default: None. + enable_mc (bool, optional): Whether to enable memcached support. + Default: True. + + Examples: + >>> filepath1 = 's3://path/of/file' + >>> filepath2 = 'cluster-name:s3://path/of/file' + >>> client = PetrelBackend() + >>> client.get(filepath1) # get data from default cluster + >>> client.get(filepath2) # get data from 'cluster-name' cluster + """ + + def __init__(self, + path_mapping: Optional[dict] = None, + enable_mc: bool = True): + try: + from petrel_client import client + except ImportError: + raise ImportError('Please install petrel_client to enable ' + 'PetrelBackend.') + + self._client = client.Client(enable_mc=enable_mc) + assert isinstance(path_mapping, dict) or path_mapping is None + self.path_mapping = path_mapping + + def _map_path(self, filepath: Union[str, Path]) -> str: + """Map ``filepath`` to a string path whose prefix will be replaced by + :attr:`self.path_mapping`. + + Args: + filepath (str): Path to be mapped. + """ + filepath = str(filepath) + if self.path_mapping is not None: + for k, v in self.path_mapping.items(): + filepath = filepath.replace(k, v) + return filepath + + def _format_path(self, filepath: str) -> str: + """Convert a ``filepath`` to standard format of petrel oss. + + If the ``filepath`` is concatenated by ``os.path.join``, in a Windows + environment, the ``filepath`` will be the format of + 's3://bucket_name\\image.jpg'. By invoking :meth:`_format_path`, the + above ``filepath`` will be converted to 's3://bucket_name/image.jpg'. + + Args: + filepath (str): Path to be formatted. + """ + return re.sub(r'\\+', '/', filepath) + + def get(self, filepath: Union[str, Path]) -> memoryview: + """Read data from a given ``filepath`` with 'rb' mode. + + Args: + filepath (str or Path): Path to read data. + + Returns: + memoryview: A memory view of expected bytes object to avoid + copying. The memoryview object can be converted to bytes by + ``value_buf.tobytes()``. + """ + filepath = self._map_path(filepath) + filepath = self._format_path(filepath) + value = self._client.Get(filepath) + value_buf = memoryview(value) + return value_buf + + def get_text(self, + filepath: Union[str, Path], + encoding: str = 'utf-8') -> str: + """Read data from a given ``filepath`` with 'r' mode. + + Args: + filepath (str or Path): Path to read data. + encoding (str): The encoding format used to open the ``filepath``. + Default: 'utf-8'. + + Returns: + str: Expected text reading from ``filepath``. + """ + return str(self.get(filepath), encoding=encoding) + + def put(self, obj: bytes, filepath: Union[str, Path]) -> None: + """Save data to a given ``filepath``. + + Args: + obj (bytes): Data to be saved. + filepath (str or Path): Path to write data. + """ + filepath = self._map_path(filepath) + filepath = self._format_path(filepath) + self._client.put(filepath, obj) + + def put_text(self, + obj: str, + filepath: Union[str, Path], + encoding: str = 'utf-8') -> None: + """Save data to a given ``filepath``. + + Args: + obj (str): Data to be written. + filepath (str or Path): Path to write data. + encoding (str): The encoding format used to encode the ``obj``. + Default: 'utf-8'. + """ + self.put(bytes(obj, encoding=encoding), filepath) + + def remove(self, filepath: Union[str, Path]) -> None: + """Remove a file. + + Args: + filepath (str or Path): Path to be removed. + """ + if not has_method(self._client, 'delete'): + raise NotImplementedError( + ('Current version of Petrel Python SDK has not supported ' + 'the `delete` method, please use a higher version or dev' + ' branch instead.')) + + filepath = self._map_path(filepath) + filepath = self._format_path(filepath) + self._client.delete(filepath) + + def exists(self, filepath: Union[str, Path]) -> bool: + """Check whether a file path exists. + + Args: + filepath (str or Path): Path to be checked whether exists. + + Returns: + bool: Return ``True`` if ``filepath`` exists, ``False`` otherwise. + """ + if not (has_method(self._client, 'contains') + and has_method(self._client, 'isdir')): + raise NotImplementedError( + ('Current version of Petrel Python SDK has not supported ' + 'the `contains` and `isdir` methods, please use a higher' + 'version or dev branch instead.')) + + filepath = self._map_path(filepath) + filepath = self._format_path(filepath) + return self._client.contains(filepath) or self._client.isdir(filepath) + + def isdir(self, filepath: Union[str, Path]) -> bool: + """Check whether a file path is a directory. + + Args: + filepath (str or Path): Path to be checked whether it is a + directory. + + Returns: + bool: Return ``True`` if ``filepath`` points to a directory, + ``False`` otherwise. + """ + if not has_method(self._client, 'isdir'): + raise NotImplementedError( + ('Current version of Petrel Python SDK has not supported ' + 'the `isdir` method, please use a higher version or dev' + ' branch instead.')) + + filepath = self._map_path(filepath) + filepath = self._format_path(filepath) + return self._client.isdir(filepath) + + def isfile(self, filepath: Union[str, Path]) -> bool: + """Check whether a file path is a file. + + Args: + filepath (str or Path): Path to be checked whether it is a file. + + Returns: + bool: Return ``True`` if ``filepath`` points to a file, ``False`` + otherwise. + """ + if not has_method(self._client, 'contains'): + raise NotImplementedError( + ('Current version of Petrel Python SDK has not supported ' + 'the `contains` method, please use a higher version or ' + 'dev branch instead.')) + + filepath = self._map_path(filepath) + filepath = self._format_path(filepath) + return self._client.contains(filepath) + + def join_path(self, filepath: Union[str, Path], + *filepaths: Union[str, Path]) -> str: + """Concatenate all file paths. + + Args: + filepath (str or Path): Path to be concatenated. + + Returns: + str: The result after concatenation. + """ + filepath = self._format_path(self._map_path(filepath)) + if filepath.endswith('/'): + filepath = filepath[:-1] + formatted_paths = [filepath] + for path in filepaths: + formatted_paths.append(self._format_path(self._map_path(path))) + return '/'.join(formatted_paths) + + @contextmanager + def get_local_path(self, filepath: Union[str, Path]) -> Iterable[str]: + """Download a file from ``filepath`` and return a temporary path. + + ``get_local_path`` is decorated by :meth:`contxtlib.contextmanager`. It + can be called with ``with`` statement, and when exists from the + ``with`` statement, the temporary path will be released. + + Args: + filepath (str | Path): Download a file from ``filepath``. + + Examples: + >>> client = PetrelBackend() + >>> # After existing from the ``with`` clause, + >>> # the path will be removed + >>> with client.get_local_path('s3://path/of/your/file') as path: + ... # do something here + + Yields: + Iterable[str]: Only yield one temporary path. + """ + filepath = self._map_path(filepath) + filepath = self._format_path(filepath) + assert self.isfile(filepath) + try: + f = tempfile.NamedTemporaryFile(delete=False) + f.write(self.get(filepath)) + f.close() + yield f.name + finally: + os.remove(f.name) + + def list_dir_or_file(self, + dir_path: Union[str, Path], + list_dir: bool = True, + list_file: bool = True, + suffix: Optional[Union[str, Tuple[str]]] = None, + recursive: bool = False) -> Iterator[str]: + """Scan a directory to find the interested directories or files in + arbitrary order. + + Note: + Petrel has no concept of directories but it simulates the directory + hierarchy in the filesystem through public prefixes. In addition, + if the returned path ends with '/', it means the path is a public + prefix which is a logical directory. + + Note: + :meth:`list_dir_or_file` returns the path relative to ``dir_path``. + In addition, the returned path of directory will not contains the + suffix '/' which is consistent with other backends. + + Args: + dir_path (str | Path): Path of the directory. + list_dir (bool): List the directories. Default: True. + list_file (bool): List the path of files. Default: True. + suffix (str or tuple[str], optional): File suffix + that we are interested in. Default: None. + recursive (bool): If set to True, recursively scan the + directory. Default: False. + + Yields: + Iterable[str]: A relative path to ``dir_path``. + """ + if not has_method(self._client, 'list'): + raise NotImplementedError( + ('Current version of Petrel Python SDK has not supported ' + 'the `list` method, please use a higher version or dev' + ' branch instead.')) + + dir_path = self._map_path(dir_path) + dir_path = self._format_path(dir_path) + if list_dir and suffix is not None: + raise TypeError( + '`list_dir` should be False when `suffix` is not None') + + if (suffix is not None) and not isinstance(suffix, (str, tuple)): + raise TypeError('`suffix` must be a string or tuple of strings') + + # Petrel's simulated directory hierarchy assumes that directory paths + # should end with `/` + if not dir_path.endswith('/'): + dir_path += '/' + + root = dir_path + + def _list_dir_or_file(dir_path, list_dir, list_file, suffix, + recursive): + for path in self._client.list(dir_path): + # the `self.isdir` is not used here to determine whether path + # is a directory, because `self.isdir` relies on + # `self._client.list` + if path.endswith('/'): # a directory path + next_dir_path = self.join_path(dir_path, path) + if list_dir: + # get the relative path and exclude the last + # character '/' + rel_dir = next_dir_path[len(root):-1] + yield rel_dir + if recursive: + yield from _list_dir_or_file(next_dir_path, list_dir, + list_file, suffix, + recursive) + else: # a file path + absolute_path = self.join_path(dir_path, path) + rel_path = absolute_path[len(root):] + if (suffix is None + or rel_path.endswith(suffix)) and list_file: + yield rel_path + + return _list_dir_or_file(dir_path, list_dir, list_file, suffix, + recursive) + + +class MemcachedBackend(BaseStorageBackend): + """Memcached storage backend. + + Attributes: + server_list_cfg (str): Config file for memcached server list. + client_cfg (str): Config file for memcached client. + sys_path (str | None): Additional path to be appended to `sys.path`. + Default: None. + """ + + def __init__(self, server_list_cfg, client_cfg, sys_path=None): + if sys_path is not None: + import sys + sys.path.append(sys_path) + try: + import mc + except ImportError: + raise ImportError( + 'Please install memcached to enable MemcachedBackend.') + + self.server_list_cfg = server_list_cfg + self.client_cfg = client_cfg + self._client = mc.MemcachedClient.GetInstance(self.server_list_cfg, + self.client_cfg) + # mc.pyvector servers as a point which points to a memory cache + self._mc_buffer = mc.pyvector() + + def get(self, filepath): + filepath = str(filepath) + import mc + self._client.Get(filepath, self._mc_buffer) + value_buf = mc.ConvertBuffer(self._mc_buffer) + return value_buf + + def get_text(self, filepath, encoding=None): + raise NotImplementedError + + +class LmdbBackend(BaseStorageBackend): + """Lmdb storage backend. + + Args: + db_path (str): Lmdb database path. + readonly (bool, optional): Lmdb environment parameter. If True, + disallow any write operations. Default: True. + lock (bool, optional): Lmdb environment parameter. If False, when + concurrent access occurs, do not lock the database. Default: False. + readahead (bool, optional): Lmdb environment parameter. If False, + disable the OS filesystem readahead mechanism, which may improve + random read performance when a database is larger than RAM. + Default: False. + + Attributes: + db_path (str): Lmdb database path. + """ + + def __init__(self, + db_path, + readonly=True, + lock=False, + readahead=False, + **kwargs): + try: + import lmdb + except ImportError: + raise ImportError('Please install lmdb to enable LmdbBackend.') + + self.db_path = str(db_path) + self._client = lmdb.open( + self.db_path, + readonly=readonly, + lock=lock, + readahead=readahead, + **kwargs) + + def get(self, filepath): + """Get values according to the filepath. + + Args: + filepath (str | obj:`Path`): Here, filepath is the lmdb key. + """ + filepath = str(filepath) + with self._client.begin(write=False) as txn: + value_buf = txn.get(filepath.encode('ascii')) + return value_buf + + def get_text(self, filepath, encoding=None): + raise NotImplementedError + + +class HardDiskBackend(BaseStorageBackend): + """Raw hard disks storage backend.""" + + _allow_symlink = True + + def get(self, filepath: Union[str, Path]) -> bytes: + """Read data from a given ``filepath`` with 'rb' mode. + + Args: + filepath (str or Path): Path to read data. + + Returns: + bytes: Expected bytes object. + """ + with open(filepath, 'rb') as f: + value_buf = f.read() + return value_buf + + def get_text(self, + filepath: Union[str, Path], + encoding: str = 'utf-8') -> str: + """Read data from a given ``filepath`` with 'r' mode. + + Args: + filepath (str or Path): Path to read data. + encoding (str): The encoding format used to open the ``filepath``. + Default: 'utf-8'. + + Returns: + str: Expected text reading from ``filepath``. + """ + with open(filepath, 'r', encoding=encoding) as f: + value_buf = f.read() + return value_buf + + def put(self, obj: bytes, filepath: Union[str, Path]) -> None: + """Write data to a given ``filepath`` with 'wb' mode. + + Note: + ``put`` will create a directory if the directory of ``filepath`` + does not exist. + + Args: + obj (bytes): Data to be written. + filepath (str or Path): Path to write data. + """ + mmcv.mkdir_or_exist(osp.dirname(filepath)) + with open(filepath, 'wb') as f: + f.write(obj) + + def put_text(self, + obj: str, + filepath: Union[str, Path], + encoding: str = 'utf-8') -> None: + """Write data to a given ``filepath`` with 'w' mode. + + Note: + ``put_text`` will create a directory if the directory of + ``filepath`` does not exist. + + Args: + obj (str): Data to be written. + filepath (str or Path): Path to write data. + encoding (str): The encoding format used to open the ``filepath``. + Default: 'utf-8'. + """ + mmcv.mkdir_or_exist(osp.dirname(filepath)) + with open(filepath, 'w', encoding=encoding) as f: + f.write(obj) + + def remove(self, filepath: Union[str, Path]) -> None: + """Remove a file. + + Args: + filepath (str or Path): Path to be removed. + """ + os.remove(filepath) + + def exists(self, filepath: Union[str, Path]) -> bool: + """Check whether a file path exists. + + Args: + filepath (str or Path): Path to be checked whether exists. + + Returns: + bool: Return ``True`` if ``filepath`` exists, ``False`` otherwise. + """ + return osp.exists(filepath) + + def isdir(self, filepath: Union[str, Path]) -> bool: + """Check whether a file path is a directory. + + Args: + filepath (str or Path): Path to be checked whether it is a + directory. + + Returns: + bool: Return ``True`` if ``filepath`` points to a directory, + ``False`` otherwise. + """ + return osp.isdir(filepath) + + def isfile(self, filepath: Union[str, Path]) -> bool: + """Check whether a file path is a file. + + Args: + filepath (str or Path): Path to be checked whether it is a file. + + Returns: + bool: Return ``True`` if ``filepath`` points to a file, ``False`` + otherwise. + """ + return osp.isfile(filepath) + + def join_path(self, filepath: Union[str, Path], + *filepaths: Union[str, Path]) -> str: + """Concatenate all file paths. + + Join one or more filepath components intelligently. The return value + is the concatenation of filepath and any members of *filepaths. + + Args: + filepath (str or Path): Path to be concatenated. + + Returns: + str: The result of concatenation. + """ + return osp.join(filepath, *filepaths) + + @contextmanager + def get_local_path( + self, filepath: Union[str, Path]) -> Iterable[Union[str, Path]]: + """Only for unified API and do nothing.""" + yield filepath + + def list_dir_or_file(self, + dir_path: Union[str, Path], + list_dir: bool = True, + list_file: bool = True, + suffix: Optional[Union[str, Tuple[str]]] = None, + recursive: bool = False) -> Iterator[str]: + """Scan a directory to find the interested directories or files in + arbitrary order. + + Note: + :meth:`list_dir_or_file` returns the path relative to ``dir_path``. + + Args: + dir_path (str | Path): Path of the directory. + list_dir (bool): List the directories. Default: True. + list_file (bool): List the path of files. Default: True. + suffix (str or tuple[str], optional): File suffix + that we are interested in. Default: None. + recursive (bool): If set to True, recursively scan the + directory. Default: False. + + Yields: + Iterable[str]: A relative path to ``dir_path``. + """ + if list_dir and suffix is not None: + raise TypeError('`suffix` should be None when `list_dir` is True') + + if (suffix is not None) and not isinstance(suffix, (str, tuple)): + raise TypeError('`suffix` must be a string or tuple of strings') + + root = dir_path + + def _list_dir_or_file(dir_path, list_dir, list_file, suffix, + recursive): + for entry in os.scandir(dir_path): + if not entry.name.startswith('.') and entry.is_file(): + rel_path = osp.relpath(entry.path, root) + if (suffix is None + or rel_path.endswith(suffix)) and list_file: + yield rel_path + elif osp.isdir(entry.path): + if list_dir: + rel_dir = osp.relpath(entry.path, root) + yield rel_dir + if recursive: + yield from _list_dir_or_file(entry.path, list_dir, + list_file, suffix, + recursive) + + return _list_dir_or_file(dir_path, list_dir, list_file, suffix, + recursive) + + +class HTTPBackend(BaseStorageBackend): + """HTTP and HTTPS storage bachend.""" + + def get(self, filepath): + value_buf = urlopen(filepath).read() + return value_buf + + def get_text(self, filepath, encoding='utf-8'): + value_buf = urlopen(filepath).read() + return value_buf.decode(encoding) + + @contextmanager + def get_local_path(self, filepath: str) -> Iterable[str]: + """Download a file from ``filepath``. + + ``get_local_path`` is decorated by :meth:`contxtlib.contextmanager`. It + can be called with ``with`` statement, and when exists from the + ``with`` statement, the temporary path will be released. + + Args: + filepath (str): Download a file from ``filepath``. + + Examples: + >>> client = HTTPBackend() + >>> # After existing from the ``with`` clause, + >>> # the path will be removed + >>> with client.get_local_path('http://path/of/your/file') as path: + ... # do something here + """ + try: + f = tempfile.NamedTemporaryFile(delete=False) + f.write(self.get(filepath)) + f.close() + yield f.name + finally: + os.remove(f.name) + + +class FileClient: + """A general file client to access files in different backends. + + The client loads a file or text in a specified backend from its path + and returns it as a binary or text file. There are two ways to choose a + backend, the name of backend and the prefix of path. Although both of them + can be used to choose a storage backend, ``backend`` has a higher priority + that is if they are all set, the storage backend will be chosen by the + backend argument. If they are all `None`, the disk backend will be chosen. + Note that It can also register other backend accessor with a given name, + prefixes, and backend class. In addition, We use the singleton pattern to + avoid repeated object creation. If the arguments are the same, the same + object will be returned. + + Args: + backend (str, optional): The storage backend type. Options are "disk", + "ceph", "memcached", "lmdb", "http" and "petrel". Default: None. + prefix (str, optional): The prefix of the registered storage backend. + Options are "s3", "http", "https". Default: None. + + Examples: + >>> # only set backend + >>> file_client = FileClient(backend='petrel') + >>> # only set prefix + >>> file_client = FileClient(prefix='s3') + >>> # set both backend and prefix but use backend to choose client + >>> file_client = FileClient(backend='petrel', prefix='s3') + >>> # if the arguments are the same, the same object is returned + >>> file_client1 = FileClient(backend='petrel') + >>> file_client1 is file_client + True + + Attributes: + client (:obj:`BaseStorageBackend`): The backend object. + """ + + _backends = { + 'disk': HardDiskBackend, + 'ceph': CephBackend, + 'memcached': MemcachedBackend, + 'lmdb': LmdbBackend, + 'petrel': PetrelBackend, + 'http': HTTPBackend, + } + # This collection is used to record the overridden backends, and when a + # backend appears in the collection, the singleton pattern is disabled for + # that backend, because if the singleton pattern is used, then the object + # returned will be the backend before overwriting + _overridden_backends = set() + _prefix_to_backends = { + 's3': PetrelBackend, + 'http': HTTPBackend, + 'https': HTTPBackend, + } + _overridden_prefixes = set() + + _instances = {} + + def __new__(cls, backend=None, prefix=None, **kwargs): + if backend is None and prefix is None: + backend = 'disk' + if backend is not None and backend not in cls._backends: + raise ValueError( + f'Backend {backend} is not supported. Currently supported ones' + f' are {list(cls._backends.keys())}') + if prefix is not None and prefix not in cls._prefix_to_backends: + raise ValueError( + f'prefix {prefix} is not supported. Currently supported ones ' + f'are {list(cls._prefix_to_backends.keys())}') + + # concatenate the arguments to a unique key for determining whether + # objects with the same arguments were created + arg_key = f'{backend}:{prefix}' + for key, value in kwargs.items(): + arg_key += f':{key}:{value}' + + # if a backend was overridden, it will create a new object + if (arg_key in cls._instances + and backend not in cls._overridden_backends + and prefix not in cls._overridden_prefixes): + _instance = cls._instances[arg_key] + else: + # create a new object and put it to _instance + _instance = super().__new__(cls) + if backend is not None: + _instance.client = cls._backends[backend](**kwargs) + else: + _instance.client = cls._prefix_to_backends[prefix](**kwargs) + + cls._instances[arg_key] = _instance + + return _instance + + @property + def name(self): + return self.client.name + + @property + def allow_symlink(self): + return self.client.allow_symlink + + @staticmethod + def parse_uri_prefix(uri: Union[str, Path]) -> Optional[str]: + """Parse the prefix of a uri. + + Args: + uri (str | Path): Uri to be parsed that contains the file prefix. + + Examples: + >>> FileClient.parse_uri_prefix('s3://path/of/your/file') + 's3' + + Returns: + str | None: Return the prefix of uri if the uri contains '://' + else ``None``. + """ + assert is_filepath(uri) + uri = str(uri) + if '://' not in uri: + return None + else: + prefix, _ = uri.split('://') + # In the case of PetrelBackend, the prefix may contains the cluster + # name like clusterName:s3 + if ':' in prefix: + _, prefix = prefix.split(':') + return prefix + + @classmethod + def infer_client(cls, + file_client_args: Optional[dict] = None, + uri: Optional[Union[str, Path]] = None) -> 'FileClient': + """Infer a suitable file client based on the URI and arguments. + + Args: + file_client_args (dict, optional): Arguments to instantiate a + FileClient. Default: None. + uri (str | Path, optional): Uri to be parsed that contains the file + prefix. Default: None. + + Examples: + >>> uri = 's3://path/of/your/file' + >>> file_client = FileClient.infer_client(uri=uri) + >>> file_client_args = {'backend': 'petrel'} + >>> file_client = FileClient.infer_client(file_client_args) + + Returns: + FileClient: Instantiated FileClient object. + """ + assert file_client_args is not None or uri is not None + if file_client_args is None: + file_prefix = cls.parse_uri_prefix(uri) # type: ignore + return cls(prefix=file_prefix) + else: + return cls(**file_client_args) + + @classmethod + def _register_backend(cls, name, backend, force=False, prefixes=None): + if not isinstance(name, str): + raise TypeError('the backend name should be a string, ' + f'but got {type(name)}') + if not inspect.isclass(backend): + raise TypeError( + f'backend should be a class but got {type(backend)}') + if not issubclass(backend, BaseStorageBackend): + raise TypeError( + f'backend {backend} is not a subclass of BaseStorageBackend') + if not force and name in cls._backends: + raise KeyError( + f'{name} is already registered as a storage backend, ' + 'add "force=True" if you want to override it') + + if name in cls._backends and force: + cls._overridden_backends.add(name) + cls._backends[name] = backend + + if prefixes is not None: + if isinstance(prefixes, str): + prefixes = [prefixes] + else: + assert isinstance(prefixes, (list, tuple)) + for prefix in prefixes: + if prefix not in cls._prefix_to_backends: + cls._prefix_to_backends[prefix] = backend + elif (prefix in cls._prefix_to_backends) and force: + cls._overridden_prefixes.add(prefix) + cls._prefix_to_backends[prefix] = backend + else: + raise KeyError( + f'{prefix} is already registered as a storage backend,' + ' add "force=True" if you want to override it') + + @classmethod + def register_backend(cls, name, backend=None, force=False, prefixes=None): + """Register a backend to FileClient. + + This method can be used as a normal class method or a decorator. + + .. code-block:: python + + class NewBackend(BaseStorageBackend): + + def get(self, filepath): + return filepath + + def get_text(self, filepath): + return filepath + + FileClient.register_backend('new', NewBackend) + + or + + .. code-block:: python + + @FileClient.register_backend('new') + class NewBackend(BaseStorageBackend): + + def get(self, filepath): + return filepath + + def get_text(self, filepath): + return filepath + + Args: + name (str): The name of the registered backend. + backend (class, optional): The backend class to be registered, + which must be a subclass of :class:`BaseStorageBackend`. + When this method is used as a decorator, backend is None. + Defaults to None. + force (bool, optional): Whether to override the backend if the name + has already been registered. Defaults to False. + prefixes (str or list[str] or tuple[str], optional): The prefixes + of the registered storage backend. Default: None. + `New in version 1.3.15.` + """ + if backend is not None: + cls._register_backend( + name, backend, force=force, prefixes=prefixes) + return + + def _register(backend_cls): + cls._register_backend( + name, backend_cls, force=force, prefixes=prefixes) + return backend_cls + + return _register + + def get(self, filepath: Union[str, Path]) -> Union[bytes, memoryview]: + """Read data from a given ``filepath`` with 'rb' mode. + + Note: + There are two types of return values for ``get``, one is ``bytes`` + and the other is ``memoryview``. The advantage of using memoryview + is that you can avoid copying, and if you want to convert it to + ``bytes``, you can use ``.tobytes()``. + + Args: + filepath (str or Path): Path to read data. + + Returns: + bytes | memoryview: Expected bytes object or a memory view of the + bytes object. + """ + return self.client.get(filepath) + + def get_text(self, filepath: Union[str, Path], encoding='utf-8') -> str: + """Read data from a given ``filepath`` with 'r' mode. + + Args: + filepath (str or Path): Path to read data. + encoding (str): The encoding format used to open the ``filepath``. + Default: 'utf-8'. + + Returns: + str: Expected text reading from ``filepath``. + """ + return self.client.get_text(filepath, encoding) + + def put(self, obj: bytes, filepath: Union[str, Path]) -> None: + """Write data to a given ``filepath`` with 'wb' mode. + + Note: + ``put`` should create a directory if the directory of ``filepath`` + does not exist. + + Args: + obj (bytes): Data to be written. + filepath (str or Path): Path to write data. + """ + self.client.put(obj, filepath) + + def put_text(self, obj: str, filepath: Union[str, Path]) -> None: + """Write data to a given ``filepath`` with 'w' mode. + + Note: + ``put_text`` should create a directory if the directory of + ``filepath`` does not exist. + + Args: + obj (str): Data to be written. + filepath (str or Path): Path to write data. + encoding (str, optional): The encoding format used to open the + `filepath`. Default: 'utf-8'. + """ + self.client.put_text(obj, filepath) + + def remove(self, filepath: Union[str, Path]) -> None: + """Remove a file. + + Args: + filepath (str, Path): Path to be removed. + """ + self.client.remove(filepath) + + def exists(self, filepath: Union[str, Path]) -> bool: + """Check whether a file path exists. + + Args: + filepath (str or Path): Path to be checked whether exists. + + Returns: + bool: Return ``True`` if ``filepath`` exists, ``False`` otherwise. + """ + return self.client.exists(filepath) + + def isdir(self, filepath: Union[str, Path]) -> bool: + """Check whether a file path is a directory. + + Args: + filepath (str or Path): Path to be checked whether it is a + directory. + + Returns: + bool: Return ``True`` if ``filepath`` points to a directory, + ``False`` otherwise. + """ + return self.client.isdir(filepath) + + def isfile(self, filepath: Union[str, Path]) -> bool: + """Check whether a file path is a file. + + Args: + filepath (str or Path): Path to be checked whether it is a file. + + Returns: + bool: Return ``True`` if ``filepath`` points to a file, ``False`` + otherwise. + """ + return self.client.isfile(filepath) + + def join_path(self, filepath: Union[str, Path], + *filepaths: Union[str, Path]) -> str: + """Concatenate all file paths. + + Join one or more filepath components intelligently. The return value + is the concatenation of filepath and any members of *filepaths. + + Args: + filepath (str or Path): Path to be concatenated. + + Returns: + str: The result of concatenation. + """ + return self.client.join_path(filepath, *filepaths) + + @contextmanager + def get_local_path(self, filepath: Union[str, Path]) -> Iterable[str]: + """Download data from ``filepath`` and write the data to local path. + + ``get_local_path`` is decorated by :meth:`contxtlib.contextmanager`. It + can be called with ``with`` statement, and when exists from the + ``with`` statement, the temporary path will be released. + + Note: + If the ``filepath`` is a local path, just return itself. + + .. warning:: + ``get_local_path`` is an experimental interface that may change in + the future. + + Args: + filepath (str or Path): Path to be read data. + + Examples: + >>> file_client = FileClient(prefix='s3') + >>> with file_client.get_local_path('s3://bucket/abc.jpg') as path: + ... # do something here + + Yields: + Iterable[str]: Only yield one path. + """ + with self.client.get_local_path(str(filepath)) as local_path: + yield local_path + + def list_dir_or_file(self, + dir_path: Union[str, Path], + list_dir: bool = True, + list_file: bool = True, + suffix: Optional[Union[str, Tuple[str]]] = None, + recursive: bool = False) -> Iterator[str]: + """Scan a directory to find the interested directories or files in + arbitrary order. + + Note: + :meth:`list_dir_or_file` returns the path relative to ``dir_path``. + + Args: + dir_path (str | Path): Path of the directory. + list_dir (bool): List the directories. Default: True. + list_file (bool): List the path of files. Default: True. + suffix (str or tuple[str], optional): File suffix + that we are interested in. Default: None. + recursive (bool): If set to True, recursively scan the + directory. Default: False. + + Yields: + Iterable[str]: A relative path to ``dir_path``. + """ + yield from self.client.list_dir_or_file(dir_path, list_dir, list_file, + suffix, recursive) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/__init__.py new file mode 100644 index 00000000..aa24d919 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .base import BaseFileHandler +from .json_handler import JsonHandler +from .pickle_handler import PickleHandler +from .yaml_handler import YamlHandler + +__all__ = ['BaseFileHandler', 'JsonHandler', 'PickleHandler', 'YamlHandler'] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/base.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/base.py new file mode 100644 index 00000000..288878bc --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/base.py @@ -0,0 +1,30 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from abc import ABCMeta, abstractmethod + + +class BaseFileHandler(metaclass=ABCMeta): + # `str_like` is a flag to indicate whether the type of file object is + # str-like object or bytes-like object. Pickle only processes bytes-like + # objects but json only processes str-like object. If it is str-like + # object, `StringIO` will be used to process the buffer. + str_like = True + + @abstractmethod + def load_from_fileobj(self, file, **kwargs): + pass + + @abstractmethod + def dump_to_fileobj(self, obj, file, **kwargs): + pass + + @abstractmethod + def dump_to_str(self, obj, **kwargs): + pass + + def load_from_path(self, filepath, mode='r', **kwargs): + with open(filepath, mode) as f: + return self.load_from_fileobj(f, **kwargs) + + def dump_to_path(self, obj, filepath, mode='w', **kwargs): + with open(filepath, mode) as f: + self.dump_to_fileobj(obj, f, **kwargs) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/json_handler.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/json_handler.py new file mode 100644 index 00000000..18d4f15f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/json_handler.py @@ -0,0 +1,36 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import json + +import numpy as np + +from .base import BaseFileHandler + + +def set_default(obj): + """Set default json values for non-serializable values. + + It helps convert ``set``, ``range`` and ``np.ndarray`` data types to list. + It also converts ``np.generic`` (including ``np.int32``, ``np.float32``, + etc.) into plain numbers of plain python built-in types. + """ + if isinstance(obj, (set, range)): + return list(obj) + elif isinstance(obj, np.ndarray): + return obj.tolist() + elif isinstance(obj, np.generic): + return obj.item() + raise TypeError(f'{type(obj)} is unsupported for json dump') + + +class JsonHandler(BaseFileHandler): + + def load_from_fileobj(self, file): + return json.load(file) + + def dump_to_fileobj(self, obj, file, **kwargs): + kwargs.setdefault('default', set_default) + json.dump(obj, file, **kwargs) + + def dump_to_str(self, obj, **kwargs): + kwargs.setdefault('default', set_default) + return json.dumps(obj, **kwargs) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/pickle_handler.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/pickle_handler.py new file mode 100644 index 00000000..b37c79be --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/pickle_handler.py @@ -0,0 +1,28 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import pickle + +from .base import BaseFileHandler + + +class PickleHandler(BaseFileHandler): + + str_like = False + + def load_from_fileobj(self, file, **kwargs): + return pickle.load(file, **kwargs) + + def load_from_path(self, filepath, **kwargs): + return super(PickleHandler, self).load_from_path( + filepath, mode='rb', **kwargs) + + def dump_to_str(self, obj, **kwargs): + kwargs.setdefault('protocol', 2) + return pickle.dumps(obj, **kwargs) + + def dump_to_fileobj(self, obj, file, **kwargs): + kwargs.setdefault('protocol', 2) + pickle.dump(obj, file, **kwargs) + + def dump_to_path(self, obj, filepath, **kwargs): + super(PickleHandler, self).dump_to_path( + obj, filepath, mode='wb', **kwargs) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/yaml_handler.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/yaml_handler.py new file mode 100644 index 00000000..c5aa2eea --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/handlers/yaml_handler.py @@ -0,0 +1,24 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import yaml + +try: + from yaml import CLoader as Loader, CDumper as Dumper +except ImportError: + from yaml import Loader, Dumper + +from .base import BaseFileHandler # isort:skip + + +class YamlHandler(BaseFileHandler): + + def load_from_fileobj(self, file, **kwargs): + kwargs.setdefault('Loader', Loader) + return yaml.load(file, **kwargs) + + def dump_to_fileobj(self, obj, file, **kwargs): + kwargs.setdefault('Dumper', Dumper) + yaml.dump(obj, file, **kwargs) + + def dump_to_str(self, obj, **kwargs): + kwargs.setdefault('Dumper', Dumper) + return yaml.dump(obj, **kwargs) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/io.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/io.py new file mode 100644 index 00000000..aaefde58 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/io.py @@ -0,0 +1,151 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from io import BytesIO, StringIO +from pathlib import Path + +from ..utils import is_list_of, is_str +from .file_client import FileClient +from .handlers import BaseFileHandler, JsonHandler, PickleHandler, YamlHandler + +file_handlers = { + 'json': JsonHandler(), + 'yaml': YamlHandler(), + 'yml': YamlHandler(), + 'pickle': PickleHandler(), + 'pkl': PickleHandler() +} + + +def load(file, file_format=None, file_client_args=None, **kwargs): + """Load data from json/yaml/pickle files. + + This method provides a unified api for loading data from serialized files. + + Note: + In v1.3.16 and later, ``load`` supports loading data from serialized + files those can be storaged in different backends. + + Args: + file (str or :obj:`Path` or file-like object): Filename or a file-like + object. + file_format (str, optional): If not specified, the file format will be + inferred from the file extension, otherwise use the specified one. + Currently supported formats include "json", "yaml/yml" and + "pickle/pkl". + file_client_args (dict, optional): Arguments to instantiate a + FileClient. See :class:`mmcv.fileio.FileClient` for details. + Default: None. + + Examples: + >>> load('/path/of/your/file') # file is storaged in disk + >>> load('https://path/of/your/file') # file is storaged in Internet + >>> load('s3://path/of/your/file') # file is storaged in petrel + + Returns: + The content from the file. + """ + if isinstance(file, Path): + file = str(file) + if file_format is None and is_str(file): + file_format = file.split('.')[-1] + if file_format not in file_handlers: + raise TypeError(f'Unsupported format: {file_format}') + + handler = file_handlers[file_format] + if is_str(file): + file_client = FileClient.infer_client(file_client_args, file) + if handler.str_like: + with StringIO(file_client.get_text(file)) as f: + obj = handler.load_from_fileobj(f, **kwargs) + else: + with BytesIO(file_client.get(file)) as f: + obj = handler.load_from_fileobj(f, **kwargs) + elif hasattr(file, 'read'): + obj = handler.load_from_fileobj(file, **kwargs) + else: + raise TypeError('"file" must be a filepath str or a file-object') + return obj + + +def dump(obj, file=None, file_format=None, file_client_args=None, **kwargs): + """Dump data to json/yaml/pickle strings or files. + + This method provides a unified api for dumping data as strings or to files, + and also supports custom arguments for each file format. + + Note: + In v1.3.16 and later, ``dump`` supports dumping data as strings or to + files which is saved to different backends. + + Args: + obj (any): The python object to be dumped. + file (str or :obj:`Path` or file-like object, optional): If not + specified, then the object is dumped to a str, otherwise to a file + specified by the filename or file-like object. + file_format (str, optional): Same as :func:`load`. + file_client_args (dict, optional): Arguments to instantiate a + FileClient. See :class:`mmcv.fileio.FileClient` for details. + Default: None. + + Examples: + >>> dump('hello world', '/path/of/your/file') # disk + >>> dump('hello world', 's3://path/of/your/file') # ceph or petrel + + Returns: + bool: True for success, False otherwise. + """ + if isinstance(file, Path): + file = str(file) + if file_format is None: + if is_str(file): + file_format = file.split('.')[-1] + elif file is None: + raise ValueError( + 'file_format must be specified since file is None') + if file_format not in file_handlers: + raise TypeError(f'Unsupported format: {file_format}') + + handler = file_handlers[file_format] + if file is None: + return handler.dump_to_str(obj, **kwargs) + elif is_str(file): + file_client = FileClient.infer_client(file_client_args, file) + if handler.str_like: + with StringIO() as f: + handler.dump_to_fileobj(obj, f, **kwargs) + file_client.put_text(f.getvalue(), file) + else: + with BytesIO() as f: + handler.dump_to_fileobj(obj, f, **kwargs) + file_client.put(f.getvalue(), file) + elif hasattr(file, 'write'): + handler.dump_to_fileobj(obj, file, **kwargs) + else: + raise TypeError('"file" must be a filename str or a file-object') + + +def _register_handler(handler, file_formats): + """Register a handler for some file extensions. + + Args: + handler (:obj:`BaseFileHandler`): Handler to be registered. + file_formats (str or list[str]): File formats to be handled by this + handler. + """ + if not isinstance(handler, BaseFileHandler): + raise TypeError( + f'handler must be a child of BaseFileHandler, not {type(handler)}') + if isinstance(file_formats, str): + file_formats = [file_formats] + if not is_list_of(file_formats, str): + raise TypeError('file_formats must be a str or a list of str') + for ext in file_formats: + file_handlers[ext] = handler + + +def register_handler(file_formats, **kwargs): + + def wrap(cls): + _register_handler(cls(**kwargs), file_formats) + return cls + + return wrap diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/parse.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/parse.py new file mode 100644 index 00000000..f60f0d61 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/fileio/parse.py @@ -0,0 +1,97 @@ +# Copyright (c) OpenMMLab. All rights reserved. + +from io import StringIO + +from .file_client import FileClient + + +def list_from_file(filename, + prefix='', + offset=0, + max_num=0, + encoding='utf-8', + file_client_args=None): + """Load a text file and parse the content as a list of strings. + + Note: + In v1.3.16 and later, ``list_from_file`` supports loading a text file + which can be storaged in different backends and parsing the content as + a list for strings. + + Args: + filename (str): Filename. + prefix (str): The prefix to be inserted to the beginning of each item. + offset (int): The offset of lines. + max_num (int): The maximum number of lines to be read, + zeros and negatives mean no limitation. + encoding (str): Encoding used to open the file. Default utf-8. + file_client_args (dict, optional): Arguments to instantiate a + FileClient. See :class:`mmcv.fileio.FileClient` for details. + Default: None. + + Examples: + >>> list_from_file('/path/of/your/file') # disk + ['hello', 'world'] + >>> list_from_file('s3://path/of/your/file') # ceph or petrel + ['hello', 'world'] + + Returns: + list[str]: A list of strings. + """ + cnt = 0 + item_list = [] + file_client = FileClient.infer_client(file_client_args, filename) + with StringIO(file_client.get_text(filename, encoding)) as f: + for _ in range(offset): + f.readline() + for line in f: + if 0 < max_num <= cnt: + break + item_list.append(prefix + line.rstrip('\n\r')) + cnt += 1 + return item_list + + +def dict_from_file(filename, + key_type=str, + encoding='utf-8', + file_client_args=None): + """Load a text file and parse the content as a dict. + + Each line of the text file will be two or more columns split by + whitespaces or tabs. The first column will be parsed as dict keys, and + the following columns will be parsed as dict values. + + Note: + In v1.3.16 and later, ``dict_from_file`` supports loading a text file + which can be storaged in different backends and parsing the content as + a dict. + + Args: + filename(str): Filename. + key_type(type): Type of the dict keys. str is user by default and + type conversion will be performed if specified. + encoding (str): Encoding used to open the file. Default utf-8. + file_client_args (dict, optional): Arguments to instantiate a + FileClient. See :class:`mmcv.fileio.FileClient` for details. + Default: None. + + Examples: + >>> dict_from_file('/path/of/your/file') # disk + {'key1': 'value1', 'key2': 'value2'} + >>> dict_from_file('s3://path/of/your/file') # ceph or petrel + {'key1': 'value1', 'key2': 'value2'} + + Returns: + dict: The parsed contents. + """ + mapping = {} + file_client = FileClient.infer_client(file_client_args, filename) + with StringIO(file_client.get_text(filename, encoding)) as f: + for line in f: + items = line.rstrip('\n').split() + assert len(items) >= 2 + key = key_type(items[0]) + val = items[1:] if len(items) > 2 else items[1] + mapping[key] = val + return mapping diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/__init__.py new file mode 100644 index 00000000..d0051d60 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/__init__.py @@ -0,0 +1,28 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .colorspace import (bgr2gray, bgr2hls, bgr2hsv, bgr2rgb, bgr2ycbcr, + gray2bgr, gray2rgb, hls2bgr, hsv2bgr, imconvert, + rgb2bgr, rgb2gray, rgb2ycbcr, ycbcr2bgr, ycbcr2rgb) +from .geometric import (cutout, imcrop, imflip, imflip_, impad, + impad_to_multiple, imrescale, imresize, imresize_like, + imresize_to_multiple, imrotate, imshear, imtranslate, + rescale_size) +from .io import imfrombytes, imread, imwrite, supported_backends, use_backend +from .misc import tensor2imgs +from .photometric import (adjust_brightness, adjust_color, adjust_contrast, + adjust_lighting, adjust_sharpness, auto_contrast, + clahe, imdenormalize, imequalize, iminvert, + imnormalize, imnormalize_, lut_transform, posterize, + solarize) + +__all__ = [ + 'bgr2gray', 'bgr2hls', 'bgr2hsv', 'bgr2rgb', 'gray2bgr', 'gray2rgb', + 'hls2bgr', 'hsv2bgr', 'imconvert', 'rgb2bgr', 'rgb2gray', 'imrescale', + 'imresize', 'imresize_like', 'imresize_to_multiple', 'rescale_size', + 'imcrop', 'imflip', 'imflip_', 'impad', 'impad_to_multiple', 'imrotate', + 'imfrombytes', 'imread', 'imwrite', 'supported_backends', 'use_backend', + 'imdenormalize', 'imnormalize', 'imnormalize_', 'iminvert', 'posterize', + 'solarize', 'rgb2ycbcr', 'bgr2ycbcr', 'ycbcr2rgb', 'ycbcr2bgr', + 'tensor2imgs', 'imshear', 'imtranslate', 'adjust_color', 'imequalize', + 'adjust_brightness', 'adjust_contrast', 'lut_transform', 'clahe', + 'adjust_sharpness', 'auto_contrast', 'cutout', 'adjust_lighting' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/colorspace.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/colorspace.py new file mode 100644 index 00000000..81453395 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/colorspace.py @@ -0,0 +1,306 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import cv2 +import numpy as np + + +def imconvert(img, src, dst): + """Convert an image from the src colorspace to dst colorspace. + + Args: + img (ndarray): The input image. + src (str): The source colorspace, e.g., 'rgb', 'hsv'. + dst (str): The destination colorspace, e.g., 'rgb', 'hsv'. + + Returns: + ndarray: The converted image. + """ + code = getattr(cv2, f'COLOR_{src.upper()}2{dst.upper()}') + out_img = cv2.cvtColor(img, code) + return out_img + + +def bgr2gray(img, keepdim=False): + """Convert a BGR image to grayscale image. + + Args: + img (ndarray): The input image. + keepdim (bool): If False (by default), then return the grayscale image + with 2 dims, otherwise 3 dims. + + Returns: + ndarray: The converted grayscale image. + """ + out_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + if keepdim: + out_img = out_img[..., None] + return out_img + + +def rgb2gray(img, keepdim=False): + """Convert a RGB image to grayscale image. + + Args: + img (ndarray): The input image. + keepdim (bool): If False (by default), then return the grayscale image + with 2 dims, otherwise 3 dims. + + Returns: + ndarray: The converted grayscale image. + """ + out_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) + if keepdim: + out_img = out_img[..., None] + return out_img + + +def gray2bgr(img): + """Convert a grayscale image to BGR image. + + Args: + img (ndarray): The input image. + + Returns: + ndarray: The converted BGR image. + """ + img = img[..., None] if img.ndim == 2 else img + out_img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) + return out_img + + +def gray2rgb(img): + """Convert a grayscale image to RGB image. + + Args: + img (ndarray): The input image. + + Returns: + ndarray: The converted RGB image. + """ + img = img[..., None] if img.ndim == 2 else img + out_img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB) + return out_img + + +def _convert_input_type_range(img): + """Convert the type and range of the input image. + + It converts the input image to np.float32 type and range of [0, 1]. + It is mainly used for pre-processing the input image in colorspace + conversion functions such as rgb2ycbcr and ycbcr2rgb. + + Args: + img (ndarray): The input image. It accepts: + 1. np.uint8 type with range [0, 255]; + 2. np.float32 type with range [0, 1]. + + Returns: + (ndarray): The converted image with type of np.float32 and range of + [0, 1]. + """ + img_type = img.dtype + img = img.astype(np.float32) + if img_type == np.float32: + pass + elif img_type == np.uint8: + img /= 255. + else: + raise TypeError('The img type should be np.float32 or np.uint8, ' + f'but got {img_type}') + return img + + +def _convert_output_type_range(img, dst_type): + """Convert the type and range of the image according to dst_type. + + It converts the image to desired type and range. If `dst_type` is np.uint8, + images will be converted to np.uint8 type with range [0, 255]. If + `dst_type` is np.float32, it converts the image to np.float32 type with + range [0, 1]. + It is mainly used for post-processing images in colorspace conversion + functions such as rgb2ycbcr and ycbcr2rgb. + + Args: + img (ndarray): The image to be converted with np.float32 type and + range [0, 255]. + dst_type (np.uint8 | np.float32): If dst_type is np.uint8, it + converts the image to np.uint8 type with range [0, 255]. If + dst_type is np.float32, it converts the image to np.float32 type + with range [0, 1]. + + Returns: + (ndarray): The converted image with desired type and range. + """ + if dst_type not in (np.uint8, np.float32): + raise TypeError('The dst_type should be np.float32 or np.uint8, ' + f'but got {dst_type}') + if dst_type == np.uint8: + img = img.round() + else: + img /= 255. + return img.astype(dst_type) + + +def rgb2ycbcr(img, y_only=False): + """Convert a RGB image to YCbCr image. + + This function produces the same results as Matlab's `rgb2ycbcr` function. + It implements the ITU-R BT.601 conversion for standard-definition + television. See more details in + https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion. + + It differs from a similar function in cv2.cvtColor: `RGB <-> YCrCb`. + In OpenCV, it implements a JPEG conversion. See more details in + https://en.wikipedia.org/wiki/YCbCr#JPEG_conversion. + + Args: + img (ndarray): The input image. It accepts: + 1. np.uint8 type with range [0, 255]; + 2. np.float32 type with range [0, 1]. + y_only (bool): Whether to only return Y channel. Default: False. + + Returns: + ndarray: The converted YCbCr image. The output image has the same type + and range as input image. + """ + img_type = img.dtype + img = _convert_input_type_range(img) + if y_only: + out_img = np.dot(img, [65.481, 128.553, 24.966]) + 16.0 + else: + out_img = np.matmul( + img, [[65.481, -37.797, 112.0], [128.553, -74.203, -93.786], + [24.966, 112.0, -18.214]]) + [16, 128, 128] + out_img = _convert_output_type_range(out_img, img_type) + return out_img + + +def bgr2ycbcr(img, y_only=False): + """Convert a BGR image to YCbCr image. + + The bgr version of rgb2ycbcr. + It implements the ITU-R BT.601 conversion for standard-definition + television. See more details in + https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion. + + It differs from a similar function in cv2.cvtColor: `BGR <-> YCrCb`. + In OpenCV, it implements a JPEG conversion. See more details in + https://en.wikipedia.org/wiki/YCbCr#JPEG_conversion. + + Args: + img (ndarray): The input image. It accepts: + 1. np.uint8 type with range [0, 255]; + 2. np.float32 type with range [0, 1]. + y_only (bool): Whether to only return Y channel. Default: False. + + Returns: + ndarray: The converted YCbCr image. The output image has the same type + and range as input image. + """ + img_type = img.dtype + img = _convert_input_type_range(img) + if y_only: + out_img = np.dot(img, [24.966, 128.553, 65.481]) + 16.0 + else: + out_img = np.matmul( + img, [[24.966, 112.0, -18.214], [128.553, -74.203, -93.786], + [65.481, -37.797, 112.0]]) + [16, 128, 128] + out_img = _convert_output_type_range(out_img, img_type) + return out_img + + +def ycbcr2rgb(img): + """Convert a YCbCr image to RGB image. + + This function produces the same results as Matlab's ycbcr2rgb function. + It implements the ITU-R BT.601 conversion for standard-definition + television. See more details in + https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion. + + It differs from a similar function in cv2.cvtColor: `YCrCb <-> RGB`. + In OpenCV, it implements a JPEG conversion. See more details in + https://en.wikipedia.org/wiki/YCbCr#JPEG_conversion. + + Args: + img (ndarray): The input image. It accepts: + 1. np.uint8 type with range [0, 255]; + 2. np.float32 type with range [0, 1]. + + Returns: + ndarray: The converted RGB image. The output image has the same type + and range as input image. + """ + img_type = img.dtype + img = _convert_input_type_range(img) * 255 + out_img = np.matmul(img, [[0.00456621, 0.00456621, 0.00456621], + [0, -0.00153632, 0.00791071], + [0.00625893, -0.00318811, 0]]) * 255.0 + [ + -222.921, 135.576, -276.836 + ] + out_img = _convert_output_type_range(out_img, img_type) + return out_img + + +def ycbcr2bgr(img): + """Convert a YCbCr image to BGR image. + + The bgr version of ycbcr2rgb. + It implements the ITU-R BT.601 conversion for standard-definition + television. See more details in + https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion. + + It differs from a similar function in cv2.cvtColor: `YCrCb <-> BGR`. + In OpenCV, it implements a JPEG conversion. See more details in + https://en.wikipedia.org/wiki/YCbCr#JPEG_conversion. + + Args: + img (ndarray): The input image. It accepts: + 1. np.uint8 type with range [0, 255]; + 2. np.float32 type with range [0, 1]. + + Returns: + ndarray: The converted BGR image. The output image has the same type + and range as input image. + """ + img_type = img.dtype + img = _convert_input_type_range(img) * 255 + out_img = np.matmul(img, [[0.00456621, 0.00456621, 0.00456621], + [0.00791071, -0.00153632, 0], + [0, -0.00318811, 0.00625893]]) * 255.0 + [ + -276.836, 135.576, -222.921 + ] + out_img = _convert_output_type_range(out_img, img_type) + return out_img + + +def convert_color_factory(src, dst): + + code = getattr(cv2, f'COLOR_{src.upper()}2{dst.upper()}') + + def convert_color(img): + out_img = cv2.cvtColor(img, code) + return out_img + + convert_color.__doc__ = f"""Convert a {src.upper()} image to {dst.upper()} + image. + + Args: + img (ndarray or str): The input image. + + Returns: + ndarray: The converted {dst.upper()} image. + """ + + return convert_color + + +bgr2rgb = convert_color_factory('bgr', 'rgb') + +rgb2bgr = convert_color_factory('rgb', 'bgr') + +bgr2hsv = convert_color_factory('bgr', 'hsv') + +hsv2bgr = convert_color_factory('hsv', 'bgr') + +bgr2hls = convert_color_factory('bgr', 'hls') + +hls2bgr = convert_color_factory('hls', 'bgr') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/geometric.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/geometric.py new file mode 100644 index 00000000..cf97c201 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/geometric.py @@ -0,0 +1,728 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import numbers + +import cv2 +import numpy as np + +from ..utils import to_2tuple +from .io import imread_backend + +try: + from PIL import Image +except ImportError: + Image = None + + +def _scale_size(size, scale): + """Rescale a size by a ratio. + + Args: + size (tuple[int]): (w, h). + scale (float | tuple(float)): Scaling factor. + + Returns: + tuple[int]: scaled size. + """ + if isinstance(scale, (float, int)): + scale = (scale, scale) + w, h = size + return int(w * float(scale[0]) + 0.5), int(h * float(scale[1]) + 0.5) + + +cv2_interp_codes = { + 'nearest': cv2.INTER_NEAREST, + 'bilinear': cv2.INTER_LINEAR, + 'bicubic': cv2.INTER_CUBIC, + 'area': cv2.INTER_AREA, + 'lanczos': cv2.INTER_LANCZOS4 +} + +if Image is not None: + pillow_interp_codes = { + 'nearest': Image.NEAREST, + 'bilinear': Image.BILINEAR, + 'bicubic': Image.BICUBIC, + 'box': Image.BOX, + 'lanczos': Image.LANCZOS, + 'hamming': Image.HAMMING + } + + +def imresize(img, + size, + return_scale=False, + interpolation='bilinear', + out=None, + backend=None): + """Resize image to a given size. + + Args: + img (ndarray): The input image. + size (tuple[int]): Target size (w, h). + return_scale (bool): Whether to return `w_scale` and `h_scale`. + interpolation (str): Interpolation method, accepted values are + "nearest", "bilinear", "bicubic", "area", "lanczos" for 'cv2' + backend, "nearest", "bilinear" for 'pillow' backend. + out (ndarray): The output destination. + backend (str | None): The image resize backend type. Options are `cv2`, + `pillow`, `None`. If backend is None, the global imread_backend + specified by ``mmcv.use_backend()`` will be used. Default: None. + + Returns: + tuple | ndarray: (`resized_img`, `w_scale`, `h_scale`) or + `resized_img`. + """ + h, w = img.shape[:2] + if backend is None: + backend = imread_backend + if backend not in ['cv2', 'pillow']: + raise ValueError(f'backend: {backend} is not supported for resize.' + f"Supported backends are 'cv2', 'pillow'") + + if backend == 'pillow': + assert img.dtype == np.uint8, 'Pillow backend only support uint8 type' + pil_image = Image.fromarray(img) + pil_image = pil_image.resize(size, pillow_interp_codes[interpolation]) + resized_img = np.array(pil_image) + else: + resized_img = cv2.resize( + img, size, dst=out, interpolation=cv2_interp_codes[interpolation]) + if not return_scale: + return resized_img + else: + w_scale = size[0] / w + h_scale = size[1] / h + return resized_img, w_scale, h_scale + + +def imresize_to_multiple(img, + divisor, + size=None, + scale_factor=None, + keep_ratio=False, + return_scale=False, + interpolation='bilinear', + out=None, + backend=None): + """Resize image according to a given size or scale factor and then rounds + up the the resized or rescaled image size to the nearest value that can be + divided by the divisor. + + Args: + img (ndarray): The input image. + divisor (int | tuple): Resized image size will be a multiple of + divisor. If divisor is a tuple, divisor should be + (w_divisor, h_divisor). + size (None | int | tuple[int]): Target size (w, h). Default: None. + scale_factor (None | float | tuple[float]): Multiplier for spatial + size. Should match input size if it is a tuple and the 2D style is + (w_scale_factor, h_scale_factor). Default: None. + keep_ratio (bool): Whether to keep the aspect ratio when resizing the + image. Default: False. + return_scale (bool): Whether to return `w_scale` and `h_scale`. + interpolation (str): Interpolation method, accepted values are + "nearest", "bilinear", "bicubic", "area", "lanczos" for 'cv2' + backend, "nearest", "bilinear" for 'pillow' backend. + out (ndarray): The output destination. + backend (str | None): The image resize backend type. Options are `cv2`, + `pillow`, `None`. If backend is None, the global imread_backend + specified by ``mmcv.use_backend()`` will be used. Default: None. + + Returns: + tuple | ndarray: (`resized_img`, `w_scale`, `h_scale`) or + `resized_img`. + """ + h, w = img.shape[:2] + if size is not None and scale_factor is not None: + raise ValueError('only one of size or scale_factor should be defined') + elif size is None and scale_factor is None: + raise ValueError('one of size or scale_factor should be defined') + elif size is not None: + size = to_2tuple(size) + if keep_ratio: + size = rescale_size((w, h), size, return_scale=False) + else: + size = _scale_size((w, h), scale_factor) + + divisor = to_2tuple(divisor) + size = tuple([int(np.ceil(s / d)) * d for s, d in zip(size, divisor)]) + resized_img, w_scale, h_scale = imresize( + img, + size, + return_scale=True, + interpolation=interpolation, + out=out, + backend=backend) + if return_scale: + return resized_img, w_scale, h_scale + else: + return resized_img + + +def imresize_like(img, + dst_img, + return_scale=False, + interpolation='bilinear', + backend=None): + """Resize image to the same size of a given image. + + Args: + img (ndarray): The input image. + dst_img (ndarray): The target image. + return_scale (bool): Whether to return `w_scale` and `h_scale`. + interpolation (str): Same as :func:`resize`. + backend (str | None): Same as :func:`resize`. + + Returns: + tuple or ndarray: (`resized_img`, `w_scale`, `h_scale`) or + `resized_img`. + """ + h, w = dst_img.shape[:2] + return imresize(img, (w, h), return_scale, interpolation, backend=backend) + + +def rescale_size(old_size, scale, return_scale=False): + """Calculate the new size to be rescaled to. + + Args: + old_size (tuple[int]): The old size (w, h) of image. + scale (float | tuple[int]): The scaling factor or maximum size. + If it is a float number, then the image will be rescaled by this + factor, else if it is a tuple of 2 integers, then the image will + be rescaled as large as possible within the scale. + return_scale (bool): Whether to return the scaling factor besides the + rescaled image size. + + Returns: + tuple[int]: The new rescaled image size. + """ + w, h = old_size + if isinstance(scale, (float, int)): + if scale <= 0: + raise ValueError(f'Invalid scale {scale}, must be positive.') + scale_factor = scale + elif isinstance(scale, tuple): + max_long_edge = max(scale) + max_short_edge = min(scale) + scale_factor = min(max_long_edge / max(h, w), + max_short_edge / min(h, w)) + else: + raise TypeError( + f'Scale must be a number or tuple of int, but got {type(scale)}') + + new_size = _scale_size((w, h), scale_factor) + + if return_scale: + return new_size, scale_factor + else: + return new_size + + +def imrescale(img, + scale, + return_scale=False, + interpolation='bilinear', + backend=None): + """Resize image while keeping the aspect ratio. + + Args: + img (ndarray): The input image. + scale (float | tuple[int]): The scaling factor or maximum size. + If it is a float number, then the image will be rescaled by this + factor, else if it is a tuple of 2 integers, then the image will + be rescaled as large as possible within the scale. + return_scale (bool): Whether to return the scaling factor besides the + rescaled image. + interpolation (str): Same as :func:`resize`. + backend (str | None): Same as :func:`resize`. + + Returns: + ndarray: The rescaled image. + """ + h, w = img.shape[:2] + new_size, scale_factor = rescale_size((w, h), scale, return_scale=True) + rescaled_img = imresize( + img, new_size, interpolation=interpolation, backend=backend) + if return_scale: + return rescaled_img, scale_factor + else: + return rescaled_img + + +def imflip(img, direction='horizontal'): + """Flip an image horizontally or vertically. + + Args: + img (ndarray): Image to be flipped. + direction (str): The flip direction, either "horizontal" or + "vertical" or "diagonal". + + Returns: + ndarray: The flipped image. + """ + assert direction in ['horizontal', 'vertical', 'diagonal'] + if direction == 'horizontal': + return np.flip(img, axis=1) + elif direction == 'vertical': + return np.flip(img, axis=0) + else: + return np.flip(img, axis=(0, 1)) + + +def imflip_(img, direction='horizontal'): + """Inplace flip an image horizontally or vertically. + + Args: + img (ndarray): Image to be flipped. + direction (str): The flip direction, either "horizontal" or + "vertical" or "diagonal". + + Returns: + ndarray: The flipped image (inplace). + """ + assert direction in ['horizontal', 'vertical', 'diagonal'] + if direction == 'horizontal': + return cv2.flip(img, 1, img) + elif direction == 'vertical': + return cv2.flip(img, 0, img) + else: + return cv2.flip(img, -1, img) + + +def imrotate(img, + angle, + center=None, + scale=1.0, + border_value=0, + interpolation='bilinear', + auto_bound=False): + """Rotate an image. + + Args: + img (ndarray): Image to be rotated. + angle (float): Rotation angle in degrees, positive values mean + clockwise rotation. + center (tuple[float], optional): Center point (w, h) of the rotation in + the source image. If not specified, the center of the image will be + used. + scale (float): Isotropic scale factor. + border_value (int): Border value. + interpolation (str): Same as :func:`resize`. + auto_bound (bool): Whether to adjust the image size to cover the whole + rotated image. + + Returns: + ndarray: The rotated image. + """ + if center is not None and auto_bound: + raise ValueError('`auto_bound` conflicts with `center`') + h, w = img.shape[:2] + if center is None: + center = ((w - 1) * 0.5, (h - 1) * 0.5) + assert isinstance(center, tuple) + + matrix = cv2.getRotationMatrix2D(center, -angle, scale) + if auto_bound: + cos = np.abs(matrix[0, 0]) + sin = np.abs(matrix[0, 1]) + new_w = h * sin + w * cos + new_h = h * cos + w * sin + matrix[0, 2] += (new_w - w) * 0.5 + matrix[1, 2] += (new_h - h) * 0.5 + w = int(np.round(new_w)) + h = int(np.round(new_h)) + rotated = cv2.warpAffine( + img, + matrix, (w, h), + flags=cv2_interp_codes[interpolation], + borderValue=border_value) + return rotated + + +def bbox_clip(bboxes, img_shape): + """Clip bboxes to fit the image shape. + + Args: + bboxes (ndarray): Shape (..., 4*k) + img_shape (tuple[int]): (height, width) of the image. + + Returns: + ndarray: Clipped bboxes. + """ + assert bboxes.shape[-1] % 4 == 0 + cmin = np.empty(bboxes.shape[-1], dtype=bboxes.dtype) + cmin[0::2] = img_shape[1] - 1 + cmin[1::2] = img_shape[0] - 1 + clipped_bboxes = np.maximum(np.minimum(bboxes, cmin), 0) + return clipped_bboxes + + +def bbox_scaling(bboxes, scale, clip_shape=None): + """Scaling bboxes w.r.t the box center. + + Args: + bboxes (ndarray): Shape(..., 4). + scale (float): Scaling factor. + clip_shape (tuple[int], optional): If specified, bboxes that exceed the + boundary will be clipped according to the given shape (h, w). + + Returns: + ndarray: Scaled bboxes. + """ + if float(scale) == 1.0: + scaled_bboxes = bboxes.copy() + else: + w = bboxes[..., 2] - bboxes[..., 0] + 1 + h = bboxes[..., 3] - bboxes[..., 1] + 1 + dw = (w * (scale - 1)) * 0.5 + dh = (h * (scale - 1)) * 0.5 + scaled_bboxes = bboxes + np.stack((-dw, -dh, dw, dh), axis=-1) + if clip_shape is not None: + return bbox_clip(scaled_bboxes, clip_shape) + else: + return scaled_bboxes + + +def imcrop(img, bboxes, scale=1.0, pad_fill=None): + """Crop image patches. + + 3 steps: scale the bboxes -> clip bboxes -> crop and pad. + + Args: + img (ndarray): Image to be cropped. + bboxes (ndarray): Shape (k, 4) or (4, ), location of cropped bboxes. + scale (float, optional): Scale ratio of bboxes, the default value + 1.0 means no padding. + pad_fill (Number | list[Number]): Value to be filled for padding. + Default: None, which means no padding. + + Returns: + list[ndarray] | ndarray: The cropped image patches. + """ + chn = 1 if img.ndim == 2 else img.shape[2] + if pad_fill is not None: + if isinstance(pad_fill, (int, float)): + pad_fill = [pad_fill for _ in range(chn)] + assert len(pad_fill) == chn + + _bboxes = bboxes[None, ...] if bboxes.ndim == 1 else bboxes + scaled_bboxes = bbox_scaling(_bboxes, scale).astype(np.int32) + clipped_bbox = bbox_clip(scaled_bboxes, img.shape) + + patches = [] + for i in range(clipped_bbox.shape[0]): + x1, y1, x2, y2 = tuple(clipped_bbox[i, :]) + if pad_fill is None: + patch = img[y1:y2 + 1, x1:x2 + 1, ...] + else: + _x1, _y1, _x2, _y2 = tuple(scaled_bboxes[i, :]) + if chn == 1: + patch_shape = (_y2 - _y1 + 1, _x2 - _x1 + 1) + else: + patch_shape = (_y2 - _y1 + 1, _x2 - _x1 + 1, chn) + patch = np.array( + pad_fill, dtype=img.dtype) * np.ones( + patch_shape, dtype=img.dtype) + x_start = 0 if _x1 >= 0 else -_x1 + y_start = 0 if _y1 >= 0 else -_y1 + w = x2 - x1 + 1 + h = y2 - y1 + 1 + patch[y_start:y_start + h, x_start:x_start + w, + ...] = img[y1:y1 + h, x1:x1 + w, ...] + patches.append(patch) + + if bboxes.ndim == 1: + return patches[0] + else: + return patches + + +def impad(img, + *, + shape=None, + padding=None, + pad_val=0, + padding_mode='constant'): + """Pad the given image to a certain shape or pad on all sides with + specified padding mode and padding value. + + Args: + img (ndarray): Image to be padded. + shape (tuple[int]): Expected padding shape (h, w). Default: None. + padding (int or tuple[int]): Padding on each border. If a single int is + provided this is used to pad all borders. If tuple of length 2 is + provided this is the padding on left/right and top/bottom + respectively. If a tuple of length 4 is provided this is the + padding for the left, top, right and bottom borders respectively. + Default: None. Note that `shape` and `padding` can not be both + set. + pad_val (Number | Sequence[Number]): Values to be filled in padding + areas when padding_mode is 'constant'. Default: 0. + padding_mode (str): Type of padding. Should be: constant, edge, + reflect or symmetric. Default: constant. + + - constant: pads with a constant value, this value is specified + with pad_val. + - edge: pads with the last value at the edge of the image. + - reflect: pads with reflection of image without repeating the + last value on the edge. For example, padding [1, 2, 3, 4] + with 2 elements on both sides in reflect mode will result + in [3, 2, 1, 2, 3, 4, 3, 2]. + - symmetric: pads with reflection of image repeating the last + value on the edge. For example, padding [1, 2, 3, 4] with + 2 elements on both sides in symmetric mode will result in + [2, 1, 1, 2, 3, 4, 4, 3] + + Returns: + ndarray: The padded image. + """ + + assert (shape is not None) ^ (padding is not None) + if shape is not None: + padding = (0, 0, shape[1] - img.shape[1], shape[0] - img.shape[0]) + + # check pad_val + if isinstance(pad_val, tuple): + assert len(pad_val) == img.shape[-1] + elif not isinstance(pad_val, numbers.Number): + raise TypeError('pad_val must be a int or a tuple. ' + f'But received {type(pad_val)}') + + # check padding + if isinstance(padding, tuple) and len(padding) in [2, 4]: + if len(padding) == 2: + padding = (padding[0], padding[1], padding[0], padding[1]) + elif isinstance(padding, numbers.Number): + padding = (padding, padding, padding, padding) + else: + raise ValueError('Padding must be a int or a 2, or 4 element tuple.' + f'But received {padding}') + + # check padding mode + assert padding_mode in ['constant', 'edge', 'reflect', 'symmetric'] + + border_type = { + 'constant': cv2.BORDER_CONSTANT, + 'edge': cv2.BORDER_REPLICATE, + 'reflect': cv2.BORDER_REFLECT_101, + 'symmetric': cv2.BORDER_REFLECT + } + img = cv2.copyMakeBorder( + img, + padding[1], + padding[3], + padding[0], + padding[2], + border_type[padding_mode], + value=pad_val) + + return img + + +def impad_to_multiple(img, divisor, pad_val=0): + """Pad an image to ensure each edge to be multiple to some number. + + Args: + img (ndarray): Image to be padded. + divisor (int): Padded image edges will be multiple to divisor. + pad_val (Number | Sequence[Number]): Same as :func:`impad`. + + Returns: + ndarray: The padded image. + """ + pad_h = int(np.ceil(img.shape[0] / divisor)) * divisor + pad_w = int(np.ceil(img.shape[1] / divisor)) * divisor + return impad(img, shape=(pad_h, pad_w), pad_val=pad_val) + + +def cutout(img, shape, pad_val=0): + """Randomly cut out a rectangle from the original img. + + Args: + img (ndarray): Image to be cutout. + shape (int | tuple[int]): Expected cutout shape (h, w). If given as a + int, the value will be used for both h and w. + pad_val (int | float | tuple[int | float]): Values to be filled in the + cut area. Defaults to 0. + + Returns: + ndarray: The cutout image. + """ + + channels = 1 if img.ndim == 2 else img.shape[2] + if isinstance(shape, int): + cut_h, cut_w = shape, shape + else: + assert isinstance(shape, tuple) and len(shape) == 2, \ + f'shape must be a int or a tuple with length 2, but got type ' \ + f'{type(shape)} instead.' + cut_h, cut_w = shape + if isinstance(pad_val, (int, float)): + pad_val = tuple([pad_val] * channels) + elif isinstance(pad_val, tuple): + assert len(pad_val) == channels, \ + 'Expected the num of elements in tuple equals the channels' \ + 'of input image. Found {} vs {}'.format( + len(pad_val), channels) + else: + raise TypeError(f'Invalid type {type(pad_val)} for `pad_val`') + + img_h, img_w = img.shape[:2] + y0 = np.random.uniform(img_h) + x0 = np.random.uniform(img_w) + + y1 = int(max(0, y0 - cut_h / 2.)) + x1 = int(max(0, x0 - cut_w / 2.)) + y2 = min(img_h, y1 + cut_h) + x2 = min(img_w, x1 + cut_w) + + if img.ndim == 2: + patch_shape = (y2 - y1, x2 - x1) + else: + patch_shape = (y2 - y1, x2 - x1, channels) + + img_cutout = img.copy() + patch = np.array( + pad_val, dtype=img.dtype) * np.ones( + patch_shape, dtype=img.dtype) + img_cutout[y1:y2, x1:x2, ...] = patch + + return img_cutout + + +def _get_shear_matrix(magnitude, direction='horizontal'): + """Generate the shear matrix for transformation. + + Args: + magnitude (int | float): The magnitude used for shear. + direction (str): The flip direction, either "horizontal" + or "vertical". + + Returns: + ndarray: The shear matrix with dtype float32. + """ + if direction == 'horizontal': + shear_matrix = np.float32([[1, magnitude, 0], [0, 1, 0]]) + elif direction == 'vertical': + shear_matrix = np.float32([[1, 0, 0], [magnitude, 1, 0]]) + return shear_matrix + + +def imshear(img, + magnitude, + direction='horizontal', + border_value=0, + interpolation='bilinear'): + """Shear an image. + + Args: + img (ndarray): Image to be sheared with format (h, w) + or (h, w, c). + magnitude (int | float): The magnitude used for shear. + direction (str): The flip direction, either "horizontal" + or "vertical". + border_value (int | tuple[int]): Value used in case of a + constant border. + interpolation (str): Same as :func:`resize`. + + Returns: + ndarray: The sheared image. + """ + assert direction in ['horizontal', + 'vertical'], f'Invalid direction: {direction}' + height, width = img.shape[:2] + if img.ndim == 2: + channels = 1 + elif img.ndim == 3: + channels = img.shape[-1] + if isinstance(border_value, int): + border_value = tuple([border_value] * channels) + elif isinstance(border_value, tuple): + assert len(border_value) == channels, \ + 'Expected the num of elements in tuple equals the channels' \ + 'of input image. Found {} vs {}'.format( + len(border_value), channels) + else: + raise ValueError( + f'Invalid type {type(border_value)} for `border_value`') + shear_matrix = _get_shear_matrix(magnitude, direction) + sheared = cv2.warpAffine( + img, + shear_matrix, + (width, height), + # Note case when the number elements in `border_value` + # greater than 3 (e.g. shearing masks whose channels large + # than 3) will raise TypeError in `cv2.warpAffine`. + # Here simply slice the first 3 values in `border_value`. + borderValue=border_value[:3], + flags=cv2_interp_codes[interpolation]) + return sheared + + +def _get_translate_matrix(offset, direction='horizontal'): + """Generate the translate matrix. + + Args: + offset (int | float): The offset used for translate. + direction (str): The translate direction, either + "horizontal" or "vertical". + + Returns: + ndarray: The translate matrix with dtype float32. + """ + if direction == 'horizontal': + translate_matrix = np.float32([[1, 0, offset], [0, 1, 0]]) + elif direction == 'vertical': + translate_matrix = np.float32([[1, 0, 0], [0, 1, offset]]) + return translate_matrix + + +def imtranslate(img, + offset, + direction='horizontal', + border_value=0, + interpolation='bilinear'): + """Translate an image. + + Args: + img (ndarray): Image to be translated with format + (h, w) or (h, w, c). + offset (int | float): The offset used for translate. + direction (str): The translate direction, either "horizontal" + or "vertical". + border_value (int | tuple[int]): Value used in case of a + constant border. + interpolation (str): Same as :func:`resize`. + + Returns: + ndarray: The translated image. + """ + assert direction in ['horizontal', + 'vertical'], f'Invalid direction: {direction}' + height, width = img.shape[:2] + if img.ndim == 2: + channels = 1 + elif img.ndim == 3: + channels = img.shape[-1] + if isinstance(border_value, int): + border_value = tuple([border_value] * channels) + elif isinstance(border_value, tuple): + assert len(border_value) == channels, \ + 'Expected the num of elements in tuple equals the channels' \ + 'of input image. Found {} vs {}'.format( + len(border_value), channels) + else: + raise ValueError( + f'Invalid type {type(border_value)} for `border_value`.') + translate_matrix = _get_translate_matrix(offset, direction) + translated = cv2.warpAffine( + img, + translate_matrix, + (width, height), + # Note case when the number elements in `border_value` + # greater than 3 (e.g. translating masks whose channels + # large than 3) will raise TypeError in `cv2.warpAffine`. + # Here simply slice the first 3 values in `border_value`. + borderValue=border_value[:3], + flags=cv2_interp_codes[interpolation]) + return translated diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/io.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/io.py new file mode 100644 index 00000000..4e8f1877 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/io.py @@ -0,0 +1,258 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import io +import os.path as osp +from pathlib import Path + +import cv2 +import numpy as np +from cv2 import (IMREAD_COLOR, IMREAD_GRAYSCALE, IMREAD_IGNORE_ORIENTATION, + IMREAD_UNCHANGED) + +from annotator.mmpkg.mmcv.utils import check_file_exist, is_str, mkdir_or_exist + +try: + from turbojpeg import TJCS_RGB, TJPF_BGR, TJPF_GRAY, TurboJPEG +except ImportError: + TJCS_RGB = TJPF_GRAY = TJPF_BGR = TurboJPEG = None + +try: + from PIL import Image, ImageOps +except ImportError: + Image = None + +try: + import tifffile +except ImportError: + tifffile = None + +jpeg = None +supported_backends = ['cv2', 'turbojpeg', 'pillow', 'tifffile'] + +imread_flags = { + 'color': IMREAD_COLOR, + 'grayscale': IMREAD_GRAYSCALE, + 'unchanged': IMREAD_UNCHANGED, + 'color_ignore_orientation': IMREAD_IGNORE_ORIENTATION | IMREAD_COLOR, + 'grayscale_ignore_orientation': + IMREAD_IGNORE_ORIENTATION | IMREAD_GRAYSCALE +} + +imread_backend = 'cv2' + + +def use_backend(backend): + """Select a backend for image decoding. + + Args: + backend (str): The image decoding backend type. Options are `cv2`, + `pillow`, `turbojpeg` (see https://github.com/lilohuang/PyTurboJPEG) + and `tifffile`. `turbojpeg` is faster but it only supports `.jpeg` + file format. + """ + assert backend in supported_backends + global imread_backend + imread_backend = backend + if imread_backend == 'turbojpeg': + if TurboJPEG is None: + raise ImportError('`PyTurboJPEG` is not installed') + global jpeg + if jpeg is None: + jpeg = TurboJPEG() + elif imread_backend == 'pillow': + if Image is None: + raise ImportError('`Pillow` is not installed') + elif imread_backend == 'tifffile': + if tifffile is None: + raise ImportError('`tifffile` is not installed') + + +def _jpegflag(flag='color', channel_order='bgr'): + channel_order = channel_order.lower() + if channel_order not in ['rgb', 'bgr']: + raise ValueError('channel order must be either "rgb" or "bgr"') + + if flag == 'color': + if channel_order == 'bgr': + return TJPF_BGR + elif channel_order == 'rgb': + return TJCS_RGB + elif flag == 'grayscale': + return TJPF_GRAY + else: + raise ValueError('flag must be "color" or "grayscale"') + + +def _pillow2array(img, flag='color', channel_order='bgr'): + """Convert a pillow image to numpy array. + + Args: + img (:obj:`PIL.Image.Image`): The image loaded using PIL + flag (str): Flags specifying the color type of a loaded image, + candidates are 'color', 'grayscale' and 'unchanged'. + Default to 'color'. + channel_order (str): The channel order of the output image array, + candidates are 'bgr' and 'rgb'. Default to 'bgr'. + + Returns: + np.ndarray: The converted numpy array + """ + channel_order = channel_order.lower() + if channel_order not in ['rgb', 'bgr']: + raise ValueError('channel order must be either "rgb" or "bgr"') + + if flag == 'unchanged': + array = np.array(img) + if array.ndim >= 3 and array.shape[2] >= 3: # color image + array[:, :, :3] = array[:, :, (2, 1, 0)] # RGB to BGR + else: + # Handle exif orientation tag + if flag in ['color', 'grayscale']: + img = ImageOps.exif_transpose(img) + # If the image mode is not 'RGB', convert it to 'RGB' first. + if img.mode != 'RGB': + if img.mode != 'LA': + # Most formats except 'LA' can be directly converted to RGB + img = img.convert('RGB') + else: + # When the mode is 'LA', the default conversion will fill in + # the canvas with black, which sometimes shadows black objects + # in the foreground. + # + # Therefore, a random color (124, 117, 104) is used for canvas + img_rgba = img.convert('RGBA') + img = Image.new('RGB', img_rgba.size, (124, 117, 104)) + img.paste(img_rgba, mask=img_rgba.split()[3]) # 3 is alpha + if flag in ['color', 'color_ignore_orientation']: + array = np.array(img) + if channel_order != 'rgb': + array = array[:, :, ::-1] # RGB to BGR + elif flag in ['grayscale', 'grayscale_ignore_orientation']: + img = img.convert('L') + array = np.array(img) + else: + raise ValueError( + 'flag must be "color", "grayscale", "unchanged", ' + f'"color_ignore_orientation" or "grayscale_ignore_orientation"' + f' but got {flag}') + return array + + +def imread(img_or_path, flag='color', channel_order='bgr', backend=None): + """Read an image. + + Args: + img_or_path (ndarray or str or Path): Either a numpy array or str or + pathlib.Path. If it is a numpy array (loaded image), then + it will be returned as is. + flag (str): Flags specifying the color type of a loaded image, + candidates are `color`, `grayscale`, `unchanged`, + `color_ignore_orientation` and `grayscale_ignore_orientation`. + By default, `cv2` and `pillow` backend would rotate the image + according to its EXIF info unless called with `unchanged` or + `*_ignore_orientation` flags. `turbojpeg` and `tifffile` backend + always ignore image's EXIF info regardless of the flag. + The `turbojpeg` backend only supports `color` and `grayscale`. + channel_order (str): Order of channel, candidates are `bgr` and `rgb`. + backend (str | None): The image decoding backend type. Options are + `cv2`, `pillow`, `turbojpeg`, `tifffile`, `None`. + If backend is None, the global imread_backend specified by + ``mmcv.use_backend()`` will be used. Default: None. + + Returns: + ndarray: Loaded image array. + """ + + if backend is None: + backend = imread_backend + if backend not in supported_backends: + raise ValueError(f'backend: {backend} is not supported. Supported ' + "backends are 'cv2', 'turbojpeg', 'pillow'") + if isinstance(img_or_path, Path): + img_or_path = str(img_or_path) + + if isinstance(img_or_path, np.ndarray): + return img_or_path + elif is_str(img_or_path): + check_file_exist(img_or_path, + f'img file does not exist: {img_or_path}') + if backend == 'turbojpeg': + with open(img_or_path, 'rb') as in_file: + img = jpeg.decode(in_file.read(), + _jpegflag(flag, channel_order)) + if img.shape[-1] == 1: + img = img[:, :, 0] + return img + elif backend == 'pillow': + img = Image.open(img_or_path) + img = _pillow2array(img, flag, channel_order) + return img + elif backend == 'tifffile': + img = tifffile.imread(img_or_path) + return img + else: + flag = imread_flags[flag] if is_str(flag) else flag + img = cv2.imread(img_or_path, flag) + if flag == IMREAD_COLOR and channel_order == 'rgb': + cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img) + return img + else: + raise TypeError('"img" must be a numpy array or a str or ' + 'a pathlib.Path object') + + +def imfrombytes(content, flag='color', channel_order='bgr', backend=None): + """Read an image from bytes. + + Args: + content (bytes): Image bytes got from files or other streams. + flag (str): Same as :func:`imread`. + backend (str | None): The image decoding backend type. Options are + `cv2`, `pillow`, `turbojpeg`, `None`. If backend is None, the + global imread_backend specified by ``mmcv.use_backend()`` will be + used. Default: None. + + Returns: + ndarray: Loaded image array. + """ + + if backend is None: + backend = imread_backend + if backend not in supported_backends: + raise ValueError(f'backend: {backend} is not supported. Supported ' + "backends are 'cv2', 'turbojpeg', 'pillow'") + if backend == 'turbojpeg': + img = jpeg.decode(content, _jpegflag(flag, channel_order)) + if img.shape[-1] == 1: + img = img[:, :, 0] + return img + elif backend == 'pillow': + buff = io.BytesIO(content) + img = Image.open(buff) + img = _pillow2array(img, flag, channel_order) + return img + else: + img_np = np.frombuffer(content, np.uint8) + flag = imread_flags[flag] if is_str(flag) else flag + img = cv2.imdecode(img_np, flag) + if flag == IMREAD_COLOR and channel_order == 'rgb': + cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img) + return img + + +def imwrite(img, file_path, params=None, auto_mkdir=True): + """Write image to file. + + Args: + img (ndarray): Image array to be written. + file_path (str): Image file path. + params (None or list): Same as opencv :func:`imwrite` interface. + auto_mkdir (bool): If the parent folder of `file_path` does not exist, + whether to create it automatically. + + Returns: + bool: Successful or not. + """ + if auto_mkdir: + dir_name = osp.abspath(osp.dirname(file_path)) + mkdir_or_exist(dir_name) + return cv2.imwrite(file_path, img, params) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/misc.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/misc.py new file mode 100644 index 00000000..cd60e661 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/misc.py @@ -0,0 +1,44 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import numpy as np + +import annotator.mmpkg.mmcv as mmcv + +try: + import torch +except ImportError: + torch = None + + +def tensor2imgs(tensor, mean=(0, 0, 0), std=(1, 1, 1), to_rgb=True): + """Convert tensor to 3-channel images. + + Args: + tensor (torch.Tensor): Tensor that contains multiple images, shape ( + N, C, H, W). + mean (tuple[float], optional): Mean of images. Defaults to (0, 0, 0). + std (tuple[float], optional): Standard deviation of images. + Defaults to (1, 1, 1). + to_rgb (bool, optional): Whether the tensor was converted to RGB + format in the first place. If so, convert it back to BGR. + Defaults to True. + + Returns: + list[np.ndarray]: A list that contains multiple images. + """ + + if torch is None: + raise RuntimeError('pytorch is not installed') + assert torch.is_tensor(tensor) and tensor.ndim == 4 + assert len(mean) == 3 + assert len(std) == 3 + + num_imgs = tensor.size(0) + mean = np.array(mean, dtype=np.float32) + std = np.array(std, dtype=np.float32) + imgs = [] + for img_id in range(num_imgs): + img = tensor[img_id, ...].cpu().numpy().transpose(1, 2, 0) + img = mmcv.imdenormalize( + img, mean, std, to_bgr=to_rgb).astype(np.uint8) + imgs.append(np.ascontiguousarray(img)) + return imgs diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/photometric.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/photometric.py new file mode 100644 index 00000000..5085d012 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/image/photometric.py @@ -0,0 +1,428 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import cv2 +import numpy as np + +from ..utils import is_tuple_of +from .colorspace import bgr2gray, gray2bgr + + +def imnormalize(img, mean, std, to_rgb=True): + """Normalize an image with mean and std. + + Args: + img (ndarray): Image to be normalized. + mean (ndarray): The mean to be used for normalize. + std (ndarray): The std to be used for normalize. + to_rgb (bool): Whether to convert to rgb. + + Returns: + ndarray: The normalized image. + """ + img = img.copy().astype(np.float32) + return imnormalize_(img, mean, std, to_rgb) + + +def imnormalize_(img, mean, std, to_rgb=True): + """Inplace normalize an image with mean and std. + + Args: + img (ndarray): Image to be normalized. + mean (ndarray): The mean to be used for normalize. + std (ndarray): The std to be used for normalize. + to_rgb (bool): Whether to convert to rgb. + + Returns: + ndarray: The normalized image. + """ + # cv2 inplace normalization does not accept uint8 + assert img.dtype != np.uint8 + mean = np.float64(mean.reshape(1, -1)) + stdinv = 1 / np.float64(std.reshape(1, -1)) + if to_rgb: + cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img) # inplace + cv2.subtract(img, mean, img) # inplace + cv2.multiply(img, stdinv, img) # inplace + return img + + +def imdenormalize(img, mean, std, to_bgr=True): + assert img.dtype != np.uint8 + mean = mean.reshape(1, -1).astype(np.float64) + std = std.reshape(1, -1).astype(np.float64) + img = cv2.multiply(img, std) # make a copy + cv2.add(img, mean, img) # inplace + if to_bgr: + cv2.cvtColor(img, cv2.COLOR_RGB2BGR, img) # inplace + return img + + +def iminvert(img): + """Invert (negate) an image. + + Args: + img (ndarray): Image to be inverted. + + Returns: + ndarray: The inverted image. + """ + return np.full_like(img, 255) - img + + +def solarize(img, thr=128): + """Solarize an image (invert all pixel values above a threshold) + + Args: + img (ndarray): Image to be solarized. + thr (int): Threshold for solarizing (0 - 255). + + Returns: + ndarray: The solarized image. + """ + img = np.where(img < thr, img, 255 - img) + return img + + +def posterize(img, bits): + """Posterize an image (reduce the number of bits for each color channel) + + Args: + img (ndarray): Image to be posterized. + bits (int): Number of bits (1 to 8) to use for posterizing. + + Returns: + ndarray: The posterized image. + """ + shift = 8 - bits + img = np.left_shift(np.right_shift(img, shift), shift) + return img + + +def adjust_color(img, alpha=1, beta=None, gamma=0): + r"""It blends the source image and its gray image: + + .. math:: + output = img * alpha + gray\_img * beta + gamma + + Args: + img (ndarray): The input source image. + alpha (int | float): Weight for the source image. Default 1. + beta (int | float): Weight for the converted gray image. + If None, it's assigned the value (1 - `alpha`). + gamma (int | float): Scalar added to each sum. + Same as :func:`cv2.addWeighted`. Default 0. + + Returns: + ndarray: Colored image which has the same size and dtype as input. + """ + gray_img = bgr2gray(img) + gray_img = np.tile(gray_img[..., None], [1, 1, 3]) + if beta is None: + beta = 1 - alpha + colored_img = cv2.addWeighted(img, alpha, gray_img, beta, gamma) + if not colored_img.dtype == np.uint8: + # Note when the dtype of `img` is not the default `np.uint8` + # (e.g. np.float32), the value in `colored_img` got from cv2 + # is not guaranteed to be in range [0, 255], so here clip + # is needed. + colored_img = np.clip(colored_img, 0, 255) + return colored_img + + +def imequalize(img): + """Equalize the image histogram. + + This function applies a non-linear mapping to the input image, + in order to create a uniform distribution of grayscale values + in the output image. + + Args: + img (ndarray): Image to be equalized. + + Returns: + ndarray: The equalized image. + """ + + def _scale_channel(im, c): + """Scale the data in the corresponding channel.""" + im = im[:, :, c] + # Compute the histogram of the image channel. + histo = np.histogram(im, 256, (0, 255))[0] + # For computing the step, filter out the nonzeros. + nonzero_histo = histo[histo > 0] + step = (np.sum(nonzero_histo) - nonzero_histo[-1]) // 255 + if not step: + lut = np.array(range(256)) + else: + # Compute the cumulative sum, shifted by step // 2 + # and then normalized by step. + lut = (np.cumsum(histo) + (step // 2)) // step + # Shift lut, prepending with 0. + lut = np.concatenate([[0], lut[:-1]], 0) + # handle potential integer overflow + lut[lut > 255] = 255 + # If step is zero, return the original image. + # Otherwise, index from lut. + return np.where(np.equal(step, 0), im, lut[im]) + + # Scales each channel independently and then stacks + # the result. + s1 = _scale_channel(img, 0) + s2 = _scale_channel(img, 1) + s3 = _scale_channel(img, 2) + equalized_img = np.stack([s1, s2, s3], axis=-1) + return equalized_img.astype(img.dtype) + + +def adjust_brightness(img, factor=1.): + """Adjust image brightness. + + This function controls the brightness of an image. An + enhancement factor of 0.0 gives a black image. + A factor of 1.0 gives the original image. This function + blends the source image and the degenerated black image: + + .. math:: + output = img * factor + degenerated * (1 - factor) + + Args: + img (ndarray): Image to be brightened. + factor (float): A value controls the enhancement. + Factor 1.0 returns the original image, lower + factors mean less color (brightness, contrast, + etc), and higher values more. Default 1. + + Returns: + ndarray: The brightened image. + """ + degenerated = np.zeros_like(img) + # Note manually convert the dtype to np.float32, to + # achieve as close results as PIL.ImageEnhance.Brightness. + # Set beta=1-factor, and gamma=0 + brightened_img = cv2.addWeighted( + img.astype(np.float32), factor, degenerated.astype(np.float32), + 1 - factor, 0) + brightened_img = np.clip(brightened_img, 0, 255) + return brightened_img.astype(img.dtype) + + +def adjust_contrast(img, factor=1.): + """Adjust image contrast. + + This function controls the contrast of an image. An + enhancement factor of 0.0 gives a solid grey + image. A factor of 1.0 gives the original image. It + blends the source image and the degenerated mean image: + + .. math:: + output = img * factor + degenerated * (1 - factor) + + Args: + img (ndarray): Image to be contrasted. BGR order. + factor (float): Same as :func:`mmcv.adjust_brightness`. + + Returns: + ndarray: The contrasted image. + """ + gray_img = bgr2gray(img) + hist = np.histogram(gray_img, 256, (0, 255))[0] + mean = round(np.sum(gray_img) / np.sum(hist)) + degenerated = (np.ones_like(img[..., 0]) * mean).astype(img.dtype) + degenerated = gray2bgr(degenerated) + contrasted_img = cv2.addWeighted( + img.astype(np.float32), factor, degenerated.astype(np.float32), + 1 - factor, 0) + contrasted_img = np.clip(contrasted_img, 0, 255) + return contrasted_img.astype(img.dtype) + + +def auto_contrast(img, cutoff=0): + """Auto adjust image contrast. + + This function maximize (normalize) image contrast by first removing cutoff + percent of the lightest and darkest pixels from the histogram and remapping + the image so that the darkest pixel becomes black (0), and the lightest + becomes white (255). + + Args: + img (ndarray): Image to be contrasted. BGR order. + cutoff (int | float | tuple): The cutoff percent of the lightest and + darkest pixels to be removed. If given as tuple, it shall be + (low, high). Otherwise, the single value will be used for both. + Defaults to 0. + + Returns: + ndarray: The contrasted image. + """ + + def _auto_contrast_channel(im, c, cutoff): + im = im[:, :, c] + # Compute the histogram of the image channel. + histo = np.histogram(im, 256, (0, 255))[0] + # Remove cut-off percent pixels from histo + histo_sum = np.cumsum(histo) + cut_low = histo_sum[-1] * cutoff[0] // 100 + cut_high = histo_sum[-1] - histo_sum[-1] * cutoff[1] // 100 + histo_sum = np.clip(histo_sum, cut_low, cut_high) - cut_low + histo = np.concatenate([[histo_sum[0]], np.diff(histo_sum)], 0) + + # Compute mapping + low, high = np.nonzero(histo)[0][0], np.nonzero(histo)[0][-1] + # If all the values have been cut off, return the origin img + if low >= high: + return im + scale = 255.0 / (high - low) + offset = -low * scale + lut = np.array(range(256)) + lut = lut * scale + offset + lut = np.clip(lut, 0, 255) + return lut[im] + + if isinstance(cutoff, (int, float)): + cutoff = (cutoff, cutoff) + else: + assert isinstance(cutoff, tuple), 'cutoff must be of type int, ' \ + f'float or tuple, but got {type(cutoff)} instead.' + # Auto adjusts contrast for each channel independently and then stacks + # the result. + s1 = _auto_contrast_channel(img, 0, cutoff) + s2 = _auto_contrast_channel(img, 1, cutoff) + s3 = _auto_contrast_channel(img, 2, cutoff) + contrasted_img = np.stack([s1, s2, s3], axis=-1) + return contrasted_img.astype(img.dtype) + + +def adjust_sharpness(img, factor=1., kernel=None): + """Adjust image sharpness. + + This function controls the sharpness of an image. An + enhancement factor of 0.0 gives a blurred image. A + factor of 1.0 gives the original image. And a factor + of 2.0 gives a sharpened image. It blends the source + image and the degenerated mean image: + + .. math:: + output = img * factor + degenerated * (1 - factor) + + Args: + img (ndarray): Image to be sharpened. BGR order. + factor (float): Same as :func:`mmcv.adjust_brightness`. + kernel (np.ndarray, optional): Filter kernel to be applied on the img + to obtain the degenerated img. Defaults to None. + + Note: + No value sanity check is enforced on the kernel set by users. So with + an inappropriate kernel, the ``adjust_sharpness`` may fail to perform + the function its name indicates but end up performing whatever + transform determined by the kernel. + + Returns: + ndarray: The sharpened image. + """ + + if kernel is None: + # adopted from PIL.ImageFilter.SMOOTH + kernel = np.array([[1., 1., 1.], [1., 5., 1.], [1., 1., 1.]]) / 13 + assert isinstance(kernel, np.ndarray), \ + f'kernel must be of type np.ndarray, but got {type(kernel)} instead.' + assert kernel.ndim == 2, \ + f'kernel must have a dimension of 2, but got {kernel.ndim} instead.' + + degenerated = cv2.filter2D(img, -1, kernel) + sharpened_img = cv2.addWeighted( + img.astype(np.float32), factor, degenerated.astype(np.float32), + 1 - factor, 0) + sharpened_img = np.clip(sharpened_img, 0, 255) + return sharpened_img.astype(img.dtype) + + +def adjust_lighting(img, eigval, eigvec, alphastd=0.1, to_rgb=True): + """AlexNet-style PCA jitter. + + This data augmentation is proposed in `ImageNet Classification with Deep + Convolutional Neural Networks + `_. + + Args: + img (ndarray): Image to be adjusted lighting. BGR order. + eigval (ndarray): the eigenvalue of the convariance matrix of pixel + values, respectively. + eigvec (ndarray): the eigenvector of the convariance matrix of pixel + values, respectively. + alphastd (float): The standard deviation for distribution of alpha. + Defaults to 0.1 + to_rgb (bool): Whether to convert img to rgb. + + Returns: + ndarray: The adjusted image. + """ + assert isinstance(eigval, np.ndarray) and isinstance(eigvec, np.ndarray), \ + f'eigval and eigvec should both be of type np.ndarray, got ' \ + f'{type(eigval)} and {type(eigvec)} instead.' + + assert eigval.ndim == 1 and eigvec.ndim == 2 + assert eigvec.shape == (3, eigval.shape[0]) + n_eigval = eigval.shape[0] + assert isinstance(alphastd, float), 'alphastd should be of type float, ' \ + f'got {type(alphastd)} instead.' + + img = img.copy().astype(np.float32) + if to_rgb: + cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img) # inplace + + alpha = np.random.normal(0, alphastd, n_eigval) + alter = eigvec \ + * np.broadcast_to(alpha.reshape(1, n_eigval), (3, n_eigval)) \ + * np.broadcast_to(eigval.reshape(1, n_eigval), (3, n_eigval)) + alter = np.broadcast_to(alter.sum(axis=1).reshape(1, 1, 3), img.shape) + img_adjusted = img + alter + return img_adjusted + + +def lut_transform(img, lut_table): + """Transform array by look-up table. + + The function lut_transform fills the output array with values from the + look-up table. Indices of the entries are taken from the input array. + + Args: + img (ndarray): Image to be transformed. + lut_table (ndarray): look-up table of 256 elements; in case of + multi-channel input array, the table should either have a single + channel (in this case the same table is used for all channels) or + the same number of channels as in the input array. + + Returns: + ndarray: The transformed image. + """ + assert isinstance(img, np.ndarray) + assert 0 <= np.min(img) and np.max(img) <= 255 + assert isinstance(lut_table, np.ndarray) + assert lut_table.shape == (256, ) + + return cv2.LUT(np.array(img, dtype=np.uint8), lut_table) + + +def clahe(img, clip_limit=40.0, tile_grid_size=(8, 8)): + """Use CLAHE method to process the image. + + See `ZUIDERVELD,K. Contrast Limited Adaptive Histogram Equalization[J]. + Graphics Gems, 1994:474-485.` for more information. + + Args: + img (ndarray): Image to be processed. + clip_limit (float): Threshold for contrast limiting. Default: 40.0. + tile_grid_size (tuple[int]): Size of grid for histogram equalization. + Input image will be divided into equally sized rectangular tiles. + It defines the number of tiles in row and column. Default: (8, 8). + + Returns: + ndarray: The processed image. + """ + assert isinstance(img, np.ndarray) + assert img.ndim == 2 + assert isinstance(clip_limit, (float, int)) + assert is_tuple_of(tile_grid_size, int) + assert len(tile_grid_size) == 2 + + clahe = cv2.createCLAHE(clip_limit, tile_grid_size) + return clahe.apply(np.array(img, dtype=np.uint8)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/model_zoo/deprecated.json b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/model_zoo/deprecated.json new file mode 100644 index 00000000..25cf6f28 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/model_zoo/deprecated.json @@ -0,0 +1,6 @@ +{ + "resnet50_caffe": "detectron/resnet50_caffe", + "resnet50_caffe_bgr": "detectron2/resnet50_caffe_bgr", + "resnet101_caffe": "detectron/resnet101_caffe", + "resnet101_caffe_bgr": "detectron2/resnet101_caffe_bgr" +} diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/model_zoo/mmcls.json b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/model_zoo/mmcls.json new file mode 100644 index 00000000..bdb311d9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/model_zoo/mmcls.json @@ -0,0 +1,31 @@ +{ + "vgg11": "https://download.openmmlab.com/mmclassification/v0/vgg/vgg11_batch256_imagenet_20210208-4271cd6c.pth", + "vgg13": "https://download.openmmlab.com/mmclassification/v0/vgg/vgg13_batch256_imagenet_20210208-4d1d6080.pth", + "vgg16": "https://download.openmmlab.com/mmclassification/v0/vgg/vgg16_batch256_imagenet_20210208-db26f1a5.pth", + "vgg19": "https://download.openmmlab.com/mmclassification/v0/vgg/vgg19_batch256_imagenet_20210208-e6920e4a.pth", + "vgg11_bn": "https://download.openmmlab.com/mmclassification/v0/vgg/vgg11_bn_batch256_imagenet_20210207-f244902c.pth", + "vgg13_bn": "https://download.openmmlab.com/mmclassification/v0/vgg/vgg13_bn_batch256_imagenet_20210207-1a8b7864.pth", + "vgg16_bn": "https://download.openmmlab.com/mmclassification/v0/vgg/vgg16_bn_batch256_imagenet_20210208-7e55cd29.pth", + "vgg19_bn": "https://download.openmmlab.com/mmclassification/v0/vgg/vgg19_bn_batch256_imagenet_20210208-da620c4f.pth", + "resnet18": "https://download.openmmlab.com/mmclassification/v0/resnet/resnet18_batch256_imagenet_20200708-34ab8f90.pth", + "resnet34": "https://download.openmmlab.com/mmclassification/v0/resnet/resnet34_batch256_imagenet_20200708-32ffb4f7.pth", + "resnet50": "https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_batch256_imagenet_20200708-cfb998bf.pth", + "resnet101": "https://download.openmmlab.com/mmclassification/v0/resnet/resnet101_batch256_imagenet_20200708-753f3608.pth", + "resnet152": "https://download.openmmlab.com/mmclassification/v0/resnet/resnet152_batch256_imagenet_20200708-ec25b1f9.pth", + "resnet50_v1d": "https://download.openmmlab.com/mmclassification/v0/resnet/resnetv1d50_batch256_imagenet_20200708-1ad0ce94.pth", + "resnet101_v1d": "https://download.openmmlab.com/mmclassification/v0/resnet/resnetv1d101_batch256_imagenet_20200708-9cb302ef.pth", + "resnet152_v1d": "https://download.openmmlab.com/mmclassification/v0/resnet/resnetv1d152_batch256_imagenet_20200708-e79cb6a2.pth", + "resnext50_32x4d": "https://download.openmmlab.com/mmclassification/v0/resnext/resnext50_32x4d_b32x8_imagenet_20210429-56066e27.pth", + "resnext101_32x4d": "https://download.openmmlab.com/mmclassification/v0/resnext/resnext101_32x4d_b32x8_imagenet_20210506-e0fa3dd5.pth", + "resnext101_32x8d": "https://download.openmmlab.com/mmclassification/v0/resnext/resnext101_32x8d_b32x8_imagenet_20210506-23a247d5.pth", + "resnext152_32x4d": "https://download.openmmlab.com/mmclassification/v0/resnext/resnext152_32x4d_b32x8_imagenet_20210524-927787be.pth", + "se-resnet50": "https://download.openmmlab.com/mmclassification/v0/se-resnet/se-resnet50_batch256_imagenet_20200804-ae206104.pth", + "se-resnet101": "https://download.openmmlab.com/mmclassification/v0/se-resnet/se-resnet101_batch256_imagenet_20200804-ba5b51d4.pth", + "resnest50": "https://download.openmmlab.com/mmclassification/v0/resnest/resnest50_imagenet_converted-1ebf0afe.pth", + "resnest101": "https://download.openmmlab.com/mmclassification/v0/resnest/resnest101_imagenet_converted-032caa52.pth", + "resnest200": "https://download.openmmlab.com/mmclassification/v0/resnest/resnest200_imagenet_converted-581a60f2.pth", + "resnest269": "https://download.openmmlab.com/mmclassification/v0/resnest/resnest269_imagenet_converted-59930960.pth", + "shufflenet_v1": "https://download.openmmlab.com/mmclassification/v0/shufflenet_v1/shufflenet_v1_batch1024_imagenet_20200804-5d6cec73.pth", + "shufflenet_v2": "https://download.openmmlab.com/mmclassification/v0/shufflenet_v2/shufflenet_v2_batch1024_imagenet_20200812-5bf4721e.pth", + "mobilenet_v2": "https://download.openmmlab.com/mmclassification/v0/mobilenet_v2/mobilenet_v2_batch256_imagenet_20200708-3b2dc3af.pth" +} diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/model_zoo/open_mmlab.json b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/model_zoo/open_mmlab.json new file mode 100644 index 00000000..8311db4f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/model_zoo/open_mmlab.json @@ -0,0 +1,50 @@ +{ + "vgg16_caffe": "https://download.openmmlab.com/pretrain/third_party/vgg16_caffe-292e1171.pth", + "detectron/resnet50_caffe": "https://download.openmmlab.com/pretrain/third_party/resnet50_caffe-788b5fa3.pth", + "detectron2/resnet50_caffe": "https://download.openmmlab.com/pretrain/third_party/resnet50_msra-5891d200.pth", + "detectron/resnet101_caffe": "https://download.openmmlab.com/pretrain/third_party/resnet101_caffe-3ad79236.pth", + "detectron2/resnet101_caffe": "https://download.openmmlab.com/pretrain/third_party/resnet101_msra-6cc46731.pth", + "detectron2/resnext101_32x8d": "https://download.openmmlab.com/pretrain/third_party/resnext101_32x8d-1516f1aa.pth", + "resnext50_32x4d": "https://download.openmmlab.com/pretrain/third_party/resnext50-32x4d-0ab1a123.pth", + "resnext101_32x4d": "https://download.openmmlab.com/pretrain/third_party/resnext101_32x4d-a5af3160.pth", + "resnext101_64x4d": "https://download.openmmlab.com/pretrain/third_party/resnext101_64x4d-ee2c6f71.pth", + "contrib/resnet50_gn": "https://download.openmmlab.com/pretrain/third_party/resnet50_gn_thangvubk-ad1730dd.pth", + "detectron/resnet50_gn": "https://download.openmmlab.com/pretrain/third_party/resnet50_gn-9186a21c.pth", + "detectron/resnet101_gn": "https://download.openmmlab.com/pretrain/third_party/resnet101_gn-cac0ab98.pth", + "jhu/resnet50_gn_ws": "https://download.openmmlab.com/pretrain/third_party/resnet50_gn_ws-15beedd8.pth", + "jhu/resnet101_gn_ws": "https://download.openmmlab.com/pretrain/third_party/resnet101_gn_ws-3e3c308c.pth", + "jhu/resnext50_32x4d_gn_ws": "https://download.openmmlab.com/pretrain/third_party/resnext50_32x4d_gn_ws-0d87ac85.pth", + "jhu/resnext101_32x4d_gn_ws": "https://download.openmmlab.com/pretrain/third_party/resnext101_32x4d_gn_ws-34ac1a9e.pth", + "jhu/resnext50_32x4d_gn": "https://download.openmmlab.com/pretrain/third_party/resnext50_32x4d_gn-c7e8b754.pth", + "jhu/resnext101_32x4d_gn": "https://download.openmmlab.com/pretrain/third_party/resnext101_32x4d_gn-ac3bb84e.pth", + "msra/hrnetv2_w18_small": "https://download.openmmlab.com/pretrain/third_party/hrnetv2_w18_small-b5a04e21.pth", + "msra/hrnetv2_w18": "https://download.openmmlab.com/pretrain/third_party/hrnetv2_w18-00eb2006.pth", + "msra/hrnetv2_w32": "https://download.openmmlab.com/pretrain/third_party/hrnetv2_w32-dc9eeb4f.pth", + "msra/hrnetv2_w40": "https://download.openmmlab.com/pretrain/third_party/hrnetv2_w40-ed0b031c.pth", + "msra/hrnetv2_w48": "https://download.openmmlab.com/pretrain/third_party/hrnetv2_w48-d2186c55.pth", + "bninception_caffe": "https://download.openmmlab.com/pretrain/third_party/bn_inception_caffe-ed2e8665.pth", + "kin400/i3d_r50_f32s2_k400": "https://download.openmmlab.com/pretrain/third_party/i3d_r50_f32s2_k400-2c57e077.pth", + "kin400/nl3d_r50_f32s2_k400": "https://download.openmmlab.com/pretrain/third_party/nl3d_r50_f32s2_k400-fa7e7caa.pth", + "res2net101_v1d_26w_4s": "https://download.openmmlab.com/pretrain/third_party/res2net101_v1d_26w_4s_mmdetv2-f0a600f9.pth", + "regnetx_400mf": "https://download.openmmlab.com/pretrain/third_party/regnetx_400mf-a5b10d96.pth", + "regnetx_800mf": "https://download.openmmlab.com/pretrain/third_party/regnetx_800mf-1f4be4c7.pth", + "regnetx_1.6gf": "https://download.openmmlab.com/pretrain/third_party/regnetx_1.6gf-5791c176.pth", + "regnetx_3.2gf": "https://download.openmmlab.com/pretrain/third_party/regnetx_3.2gf-c2599b0f.pth", + "regnetx_4.0gf": "https://download.openmmlab.com/pretrain/third_party/regnetx_4.0gf-a88f671e.pth", + "regnetx_6.4gf": "https://download.openmmlab.com/pretrain/third_party/regnetx_6.4gf-006af45d.pth", + "regnetx_8.0gf": "https://download.openmmlab.com/pretrain/third_party/regnetx_8.0gf-3c68abe7.pth", + "regnetx_12gf": "https://download.openmmlab.com/pretrain/third_party/regnetx_12gf-4c2a3350.pth", + "resnet18_v1c": "https://download.openmmlab.com/pretrain/third_party/resnet18_v1c-b5776b93.pth", + "resnet50_v1c": "https://download.openmmlab.com/pretrain/third_party/resnet50_v1c-2cccc1ad.pth", + "resnet101_v1c": "https://download.openmmlab.com/pretrain/third_party/resnet101_v1c-e67eebb6.pth", + "mmedit/vgg16": "https://download.openmmlab.com/mmediting/third_party/vgg_state_dict.pth", + "mmedit/res34_en_nomixup": "https://download.openmmlab.com/mmediting/third_party/model_best_resnet34_En_nomixup.pth", + "mmedit/mobilenet_v2": "https://download.openmmlab.com/mmediting/third_party/mobilenet_v2.pth", + "contrib/mobilenet_v3_large": "https://download.openmmlab.com/pretrain/third_party/mobilenet_v3_large-bc2c3fd3.pth", + "contrib/mobilenet_v3_small": "https://download.openmmlab.com/pretrain/third_party/mobilenet_v3_small-47085aa1.pth", + "resnest50": "https://download.openmmlab.com/pretrain/third_party/resnest50_d2-7497a55b.pth", + "resnest101": "https://download.openmmlab.com/pretrain/third_party/resnest101_d2-f3b931b2.pth", + "resnest200": "https://download.openmmlab.com/pretrain/third_party/resnest200_d2-ca88e41f.pth", + "darknet53": "https://download.openmmlab.com/pretrain/third_party/darknet53-a628ea1b.pth", + "mmdet/mobilenet_v2": "https://download.openmmlab.com/mmdetection/v2.0/third_party/mobilenet_v2_batch256_imagenet-ff34753d.pth" +} diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/__init__.py new file mode 100644 index 00000000..999e090a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/__init__.py @@ -0,0 +1,81 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .assign_score_withk import assign_score_withk +from .ball_query import ball_query +from .bbox import bbox_overlaps +from .border_align import BorderAlign, border_align +from .box_iou_rotated import box_iou_rotated +from .carafe import CARAFE, CARAFENaive, CARAFEPack, carafe, carafe_naive +from .cc_attention import CrissCrossAttention +from .contour_expand import contour_expand +from .corner_pool import CornerPool +from .correlation import Correlation +from .deform_conv import DeformConv2d, DeformConv2dPack, deform_conv2d +from .deform_roi_pool import (DeformRoIPool, DeformRoIPoolPack, + ModulatedDeformRoIPoolPack, deform_roi_pool) +from .deprecated_wrappers import Conv2d_deprecated as Conv2d +from .deprecated_wrappers import ConvTranspose2d_deprecated as ConvTranspose2d +from .deprecated_wrappers import Linear_deprecated as Linear +from .deprecated_wrappers import MaxPool2d_deprecated as MaxPool2d +from .focal_loss import (SigmoidFocalLoss, SoftmaxFocalLoss, + sigmoid_focal_loss, softmax_focal_loss) +from .furthest_point_sample import (furthest_point_sample, + furthest_point_sample_with_dist) +from .fused_bias_leakyrelu import FusedBiasLeakyReLU, fused_bias_leakyrelu +from .gather_points import gather_points +from .group_points import GroupAll, QueryAndGroup, grouping_operation +from .info import (get_compiler_version, get_compiling_cuda_version, + get_onnxruntime_op_path) +from .iou3d import boxes_iou_bev, nms_bev, nms_normal_bev +from .knn import knn +from .masked_conv import MaskedConv2d, masked_conv2d +from .modulated_deform_conv import (ModulatedDeformConv2d, + ModulatedDeformConv2dPack, + modulated_deform_conv2d) +from .multi_scale_deform_attn import MultiScaleDeformableAttention +from .nms import batched_nms, nms, nms_match, nms_rotated, soft_nms +from .pixel_group import pixel_group +from .point_sample import (SimpleRoIAlign, point_sample, + rel_roi_point_to_rel_img_point) +from .points_in_boxes import (points_in_boxes_all, points_in_boxes_cpu, + points_in_boxes_part) +from .points_sampler import PointsSampler +from .psa_mask import PSAMask +from .roi_align import RoIAlign, roi_align +from .roi_align_rotated import RoIAlignRotated, roi_align_rotated +from .roi_pool import RoIPool, roi_pool +from .roiaware_pool3d import RoIAwarePool3d +from .roipoint_pool3d import RoIPointPool3d +from .saconv import SAConv2d +from .scatter_points import DynamicScatter, dynamic_scatter +from .sync_bn import SyncBatchNorm +from .three_interpolate import three_interpolate +from .three_nn import three_nn +from .tin_shift import TINShift, tin_shift +from .upfirdn2d import upfirdn2d +from .voxelize import Voxelization, voxelization + +__all__ = [ + 'bbox_overlaps', 'CARAFE', 'CARAFENaive', 'CARAFEPack', 'carafe', + 'carafe_naive', 'CornerPool', 'DeformConv2d', 'DeformConv2dPack', + 'deform_conv2d', 'DeformRoIPool', 'DeformRoIPoolPack', + 'ModulatedDeformRoIPoolPack', 'deform_roi_pool', 'SigmoidFocalLoss', + 'SoftmaxFocalLoss', 'sigmoid_focal_loss', 'softmax_focal_loss', + 'get_compiler_version', 'get_compiling_cuda_version', + 'get_onnxruntime_op_path', 'MaskedConv2d', 'masked_conv2d', + 'ModulatedDeformConv2d', 'ModulatedDeformConv2dPack', + 'modulated_deform_conv2d', 'batched_nms', 'nms', 'soft_nms', 'nms_match', + 'RoIAlign', 'roi_align', 'RoIPool', 'roi_pool', 'SyncBatchNorm', 'Conv2d', + 'ConvTranspose2d', 'Linear', 'MaxPool2d', 'CrissCrossAttention', 'PSAMask', + 'point_sample', 'rel_roi_point_to_rel_img_point', 'SimpleRoIAlign', + 'SAConv2d', 'TINShift', 'tin_shift', 'assign_score_withk', + 'box_iou_rotated', 'RoIPointPool3d', 'nms_rotated', 'knn', 'ball_query', + 'upfirdn2d', 'FusedBiasLeakyReLU', 'fused_bias_leakyrelu', + 'RoIAlignRotated', 'roi_align_rotated', 'pixel_group', 'QueryAndGroup', + 'GroupAll', 'grouping_operation', 'contour_expand', 'three_nn', + 'three_interpolate', 'MultiScaleDeformableAttention', 'BorderAlign', + 'border_align', 'gather_points', 'furthest_point_sample', + 'furthest_point_sample_with_dist', 'PointsSampler', 'Correlation', + 'boxes_iou_bev', 'nms_bev', 'nms_normal_bev', 'Voxelization', + 'voxelization', 'dynamic_scatter', 'DynamicScatter', 'RoIAwarePool3d', + 'points_in_boxes_part', 'points_in_boxes_cpu', 'points_in_boxes_all' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/assign_score_withk.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/assign_score_withk.py new file mode 100644 index 00000000..4906adaa --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/assign_score_withk.py @@ -0,0 +1,123 @@ +from torch.autograd import Function + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext( + '_ext', ['assign_score_withk_forward', 'assign_score_withk_backward']) + + +class AssignScoreWithK(Function): + r"""Perform weighted sum to generate output features according to scores. + Modified from `PAConv `_. + + This is a memory-efficient CUDA implementation of assign_scores operation, + which first transform all point features with weight bank, then assemble + neighbor features with ``knn_idx`` and perform weighted sum of ``scores``. + + See the `paper `_ appendix Sec. D for + more detailed descriptions. + + Note: + This implementation assumes using ``neighbor`` kernel input, which is + (point_features - center_features, point_features). + See https://github.com/CVMI-Lab/PAConv/blob/main/scene_seg/model/ + pointnet2/paconv.py#L128 for more details. + """ + + @staticmethod + def forward(ctx, + scores, + point_features, + center_features, + knn_idx, + aggregate='sum'): + """ + Args: + scores (torch.Tensor): (B, npoint, K, M), predicted scores to + aggregate weight matrices in the weight bank. + ``npoint`` is the number of sampled centers. + ``K`` is the number of queried neighbors. + ``M`` is the number of weight matrices in the weight bank. + point_features (torch.Tensor): (B, N, M, out_dim) + Pre-computed point features to be aggregated. + center_features (torch.Tensor): (B, N, M, out_dim) + Pre-computed center features to be aggregated. + knn_idx (torch.Tensor): (B, npoint, K), index of sampled kNN. + We assume the first idx in each row is the idx of the center. + aggregate (str, optional): Aggregation method. + Can be 'sum', 'avg' or 'max'. Defaults: 'sum'. + + Returns: + torch.Tensor: (B, out_dim, npoint, K), the aggregated features. + """ + agg = {'sum': 0, 'avg': 1, 'max': 2} + + B, N, M, out_dim = point_features.size() + _, npoint, K, _ = scores.size() + + output = point_features.new_zeros((B, out_dim, npoint, K)) + ext_module.assign_score_withk_forward( + point_features.contiguous(), + center_features.contiguous(), + scores.contiguous(), + knn_idx.contiguous(), + output, + B=B, + N0=N, + N1=npoint, + M=M, + K=K, + O=out_dim, + aggregate=agg[aggregate]) + + ctx.save_for_backward(output, point_features, center_features, scores, + knn_idx) + ctx.agg = agg[aggregate] + + return output + + @staticmethod + def backward(ctx, grad_out): + """ + Args: + grad_out (torch.Tensor): (B, out_dim, npoint, K) + + Returns: + grad_scores (torch.Tensor): (B, npoint, K, M) + grad_point_features (torch.Tensor): (B, N, M, out_dim) + grad_center_features (torch.Tensor): (B, N, M, out_dim) + """ + _, point_features, center_features, scores, knn_idx = ctx.saved_tensors + + agg = ctx.agg + + B, N, M, out_dim = point_features.size() + _, npoint, K, _ = scores.size() + + grad_point_features = point_features.new_zeros(point_features.shape) + grad_center_features = center_features.new_zeros(center_features.shape) + grad_scores = scores.new_zeros(scores.shape) + + ext_module.assign_score_withk_backward( + grad_out.contiguous(), + point_features.contiguous(), + center_features.contiguous(), + scores.contiguous(), + knn_idx.contiguous(), + grad_point_features, + grad_center_features, + grad_scores, + B=B, + N0=N, + N1=npoint, + M=M, + K=K, + O=out_dim, + aggregate=agg) + + return grad_scores, grad_point_features, \ + grad_center_features, None, None + + +assign_score_withk = AssignScoreWithK.apply diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/ball_query.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/ball_query.py new file mode 100644 index 00000000..d0466847 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/ball_query.py @@ -0,0 +1,55 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +from torch.autograd import Function + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', ['ball_query_forward']) + + +class BallQuery(Function): + """Find nearby points in spherical space.""" + + @staticmethod + def forward(ctx, min_radius: float, max_radius: float, sample_num: int, + xyz: torch.Tensor, center_xyz: torch.Tensor) -> torch.Tensor: + """ + Args: + min_radius (float): minimum radius of the balls. + max_radius (float): maximum radius of the balls. + sample_num (int): maximum number of features in the balls. + xyz (Tensor): (B, N, 3) xyz coordinates of the features. + center_xyz (Tensor): (B, npoint, 3) centers of the ball query. + + Returns: + Tensor: (B, npoint, nsample) tensor with the indices of + the features that form the query balls. + """ + assert center_xyz.is_contiguous() + assert xyz.is_contiguous() + assert min_radius < max_radius + + B, N, _ = xyz.size() + npoint = center_xyz.size(1) + idx = xyz.new_zeros(B, npoint, sample_num, dtype=torch.int) + + ext_module.ball_query_forward( + center_xyz, + xyz, + idx, + b=B, + n=N, + m=npoint, + min_radius=min_radius, + max_radius=max_radius, + nsample=sample_num) + if torch.__version__ != 'parrots': + ctx.mark_non_differentiable(idx) + return idx + + @staticmethod + def backward(ctx, a=None): + return None, None, None, None + + +ball_query = BallQuery.apply diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/bbox.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/bbox.py new file mode 100644 index 00000000..0c4d58b6 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/bbox.py @@ -0,0 +1,72 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', ['bbox_overlaps']) + + +def bbox_overlaps(bboxes1, bboxes2, mode='iou', aligned=False, offset=0): + """Calculate overlap between two set of bboxes. + + If ``aligned`` is ``False``, then calculate the ious between each bbox + of bboxes1 and bboxes2, otherwise the ious between each aligned pair of + bboxes1 and bboxes2. + + Args: + bboxes1 (Tensor): shape (m, 4) in format or empty. + bboxes2 (Tensor): shape (n, 4) in format or empty. + If aligned is ``True``, then m and n must be equal. + mode (str): "iou" (intersection over union) or iof (intersection over + foreground). + + Returns: + ious(Tensor): shape (m, n) if aligned == False else shape (m, 1) + + Example: + >>> bboxes1 = torch.FloatTensor([ + >>> [0, 0, 10, 10], + >>> [10, 10, 20, 20], + >>> [32, 32, 38, 42], + >>> ]) + >>> bboxes2 = torch.FloatTensor([ + >>> [0, 0, 10, 20], + >>> [0, 10, 10, 19], + >>> [10, 10, 20, 20], + >>> ]) + >>> bbox_overlaps(bboxes1, bboxes2) + tensor([[0.5000, 0.0000, 0.0000], + [0.0000, 0.0000, 1.0000], + [0.0000, 0.0000, 0.0000]]) + + Example: + >>> empty = torch.FloatTensor([]) + >>> nonempty = torch.FloatTensor([ + >>> [0, 0, 10, 9], + >>> ]) + >>> assert tuple(bbox_overlaps(empty, nonempty).shape) == (0, 1) + >>> assert tuple(bbox_overlaps(nonempty, empty).shape) == (1, 0) + >>> assert tuple(bbox_overlaps(empty, empty).shape) == (0, 0) + """ + + mode_dict = {'iou': 0, 'iof': 1} + assert mode in mode_dict.keys() + mode_flag = mode_dict[mode] + # Either the boxes are empty or the length of boxes' last dimension is 4 + assert (bboxes1.size(-1) == 4 or bboxes1.size(0) == 0) + assert (bboxes2.size(-1) == 4 or bboxes2.size(0) == 0) + assert offset == 1 or offset == 0 + + rows = bboxes1.size(0) + cols = bboxes2.size(0) + if aligned: + assert rows == cols + + if rows * cols == 0: + return bboxes1.new(rows, 1) if aligned else bboxes1.new(rows, cols) + + if aligned: + ious = bboxes1.new_zeros(rows) + else: + ious = bboxes1.new_zeros((rows, cols)) + ext_module.bbox_overlaps( + bboxes1, bboxes2, ious, mode=mode_flag, aligned=aligned, offset=offset) + return ious diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/border_align.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/border_align.py new file mode 100644 index 00000000..ff305be3 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/border_align.py @@ -0,0 +1,109 @@ +# Copyright (c) OpenMMLab. All rights reserved. +# modified from +# https://github.com/Megvii-BaseDetection/cvpods/blob/master/cvpods/layers/border_align.py + +import torch +import torch.nn as nn +from torch.autograd import Function +from torch.autograd.function import once_differentiable + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext( + '_ext', ['border_align_forward', 'border_align_backward']) + + +class BorderAlignFunction(Function): + + @staticmethod + def symbolic(g, input, boxes, pool_size): + return g.op( + 'mmcv::MMCVBorderAlign', input, boxes, pool_size_i=pool_size) + + @staticmethod + def forward(ctx, input, boxes, pool_size): + ctx.pool_size = pool_size + ctx.input_shape = input.size() + + assert boxes.ndim == 3, 'boxes must be with shape [B, H*W, 4]' + assert boxes.size(2) == 4, \ + 'the last dimension of boxes must be (x1, y1, x2, y2)' + assert input.size(1) % 4 == 0, \ + 'the channel for input feature must be divisible by factor 4' + + # [B, C//4, H*W, 4] + output_shape = (input.size(0), input.size(1) // 4, boxes.size(1), 4) + output = input.new_zeros(output_shape) + # `argmax_idx` only used for backward + argmax_idx = input.new_zeros(output_shape).to(torch.int) + + ext_module.border_align_forward( + input, boxes, output, argmax_idx, pool_size=ctx.pool_size) + + ctx.save_for_backward(boxes, argmax_idx) + return output + + @staticmethod + @once_differentiable + def backward(ctx, grad_output): + boxes, argmax_idx = ctx.saved_tensors + grad_input = grad_output.new_zeros(ctx.input_shape) + # complex head architecture may cause grad_output uncontiguous + grad_output = grad_output.contiguous() + ext_module.border_align_backward( + grad_output, + boxes, + argmax_idx, + grad_input, + pool_size=ctx.pool_size) + return grad_input, None, None + + +border_align = BorderAlignFunction.apply + + +class BorderAlign(nn.Module): + r"""Border align pooling layer. + + Applies border_align over the input feature based on predicted bboxes. + The details were described in the paper + `BorderDet: Border Feature for Dense Object Detection + `_. + + For each border line (e.g. top, left, bottom or right) of each box, + border_align does the following: + 1. uniformly samples `pool_size`+1 positions on this line, involving \ + the start and end points. + 2. the corresponding features on these points are computed by \ + bilinear interpolation. + 3. max pooling over all the `pool_size`+1 positions are used for \ + computing pooled feature. + + Args: + pool_size (int): number of positions sampled over the boxes' borders + (e.g. top, bottom, left, right). + + """ + + def __init__(self, pool_size): + super(BorderAlign, self).__init__() + self.pool_size = pool_size + + def forward(self, input, boxes): + """ + Args: + input: Features with shape [N,4C,H,W]. Channels ranged in [0,C), + [C,2C), [2C,3C), [3C,4C) represent the top, left, bottom, + right features respectively. + boxes: Boxes with shape [N,H*W,4]. Coordinate format (x1,y1,x2,y2). + + Returns: + Tensor: Pooled features with shape [N,C,H*W,4]. The order is + (top,left,bottom,right) for the last dimension. + """ + return border_align(input, boxes, self.pool_size) + + def __repr__(self): + s = self.__class__.__name__ + s += f'(pool_size={self.pool_size})' + return s diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/box_iou_rotated.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/box_iou_rotated.py new file mode 100644 index 00000000..2d78015e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/box_iou_rotated.py @@ -0,0 +1,45 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', ['box_iou_rotated']) + + +def box_iou_rotated(bboxes1, bboxes2, mode='iou', aligned=False): + """Return intersection-over-union (Jaccard index) of boxes. + + Both sets of boxes are expected to be in + (x_center, y_center, width, height, angle) format. + + If ``aligned`` is ``False``, then calculate the ious between each bbox + of bboxes1 and bboxes2, otherwise the ious between each aligned pair of + bboxes1 and bboxes2. + + Arguments: + boxes1 (Tensor): rotated bboxes 1. \ + It has shape (N, 5), indicating (x, y, w, h, theta) for each row. + Note that theta is in radian. + boxes2 (Tensor): rotated bboxes 2. \ + It has shape (M, 5), indicating (x, y, w, h, theta) for each row. + Note that theta is in radian. + mode (str): "iou" (intersection over union) or iof (intersection over + foreground). + + Returns: + ious(Tensor): shape (N, M) if aligned == False else shape (N,) + """ + assert mode in ['iou', 'iof'] + mode_dict = {'iou': 0, 'iof': 1} + mode_flag = mode_dict[mode] + rows = bboxes1.size(0) + cols = bboxes2.size(0) + if aligned: + ious = bboxes1.new_zeros(rows) + else: + ious = bboxes1.new_zeros((rows * cols)) + bboxes1 = bboxes1.contiguous() + bboxes2 = bboxes2.contiguous() + ext_module.box_iou_rotated( + bboxes1, bboxes2, ious, mode_flag=mode_flag, aligned=aligned) + if not aligned: + ious = ious.view(rows, cols) + return ious diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/carafe.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/carafe.py new file mode 100644 index 00000000..5154cb3a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/carafe.py @@ -0,0 +1,287 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.nn as nn +import torch.nn.functional as F +from torch.autograd import Function +from torch.nn.modules.module import Module + +from ..cnn import UPSAMPLE_LAYERS, normal_init, xavier_init +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', [ + 'carafe_naive_forward', 'carafe_naive_backward', 'carafe_forward', + 'carafe_backward' +]) + + +class CARAFENaiveFunction(Function): + + @staticmethod + def symbolic(g, features, masks, kernel_size, group_size, scale_factor): + return g.op( + 'mmcv::MMCVCARAFENaive', + features, + masks, + kernel_size_i=kernel_size, + group_size_i=group_size, + scale_factor_f=scale_factor) + + @staticmethod + def forward(ctx, features, masks, kernel_size, group_size, scale_factor): + assert scale_factor >= 1 + assert masks.size(1) == kernel_size * kernel_size * group_size + assert masks.size(-1) == features.size(-1) * scale_factor + assert masks.size(-2) == features.size(-2) * scale_factor + assert features.size(1) % group_size == 0 + assert (kernel_size - 1) % 2 == 0 and kernel_size >= 1 + ctx.kernel_size = kernel_size + ctx.group_size = group_size + ctx.scale_factor = scale_factor + ctx.feature_size = features.size() + ctx.mask_size = masks.size() + + n, c, h, w = features.size() + output = features.new_zeros((n, c, h * scale_factor, w * scale_factor)) + ext_module.carafe_naive_forward( + features, + masks, + output, + kernel_size=kernel_size, + group_size=group_size, + scale_factor=scale_factor) + + if features.requires_grad or masks.requires_grad: + ctx.save_for_backward(features, masks) + return output + + @staticmethod + def backward(ctx, grad_output): + assert grad_output.is_cuda + + features, masks = ctx.saved_tensors + kernel_size = ctx.kernel_size + group_size = ctx.group_size + scale_factor = ctx.scale_factor + + grad_input = torch.zeros_like(features) + grad_masks = torch.zeros_like(masks) + ext_module.carafe_naive_backward( + grad_output.contiguous(), + features, + masks, + grad_input, + grad_masks, + kernel_size=kernel_size, + group_size=group_size, + scale_factor=scale_factor) + + return grad_input, grad_masks, None, None, None + + +carafe_naive = CARAFENaiveFunction.apply + + +class CARAFENaive(Module): + + def __init__(self, kernel_size, group_size, scale_factor): + super(CARAFENaive, self).__init__() + + assert isinstance(kernel_size, int) and isinstance( + group_size, int) and isinstance(scale_factor, int) + self.kernel_size = kernel_size + self.group_size = group_size + self.scale_factor = scale_factor + + def forward(self, features, masks): + return carafe_naive(features, masks, self.kernel_size, self.group_size, + self.scale_factor) + + +class CARAFEFunction(Function): + + @staticmethod + def symbolic(g, features, masks, kernel_size, group_size, scale_factor): + return g.op( + 'mmcv::MMCVCARAFE', + features, + masks, + kernel_size_i=kernel_size, + group_size_i=group_size, + scale_factor_f=scale_factor) + + @staticmethod + def forward(ctx, features, masks, kernel_size, group_size, scale_factor): + assert scale_factor >= 1 + assert masks.size(1) == kernel_size * kernel_size * group_size + assert masks.size(-1) == features.size(-1) * scale_factor + assert masks.size(-2) == features.size(-2) * scale_factor + assert features.size(1) % group_size == 0 + assert (kernel_size - 1) % 2 == 0 and kernel_size >= 1 + ctx.kernel_size = kernel_size + ctx.group_size = group_size + ctx.scale_factor = scale_factor + ctx.feature_size = features.size() + ctx.mask_size = masks.size() + + n, c, h, w = features.size() + output = features.new_zeros((n, c, h * scale_factor, w * scale_factor)) + routput = features.new_zeros(output.size(), requires_grad=False) + rfeatures = features.new_zeros(features.size(), requires_grad=False) + rmasks = masks.new_zeros(masks.size(), requires_grad=False) + ext_module.carafe_forward( + features, + masks, + rfeatures, + routput, + rmasks, + output, + kernel_size=kernel_size, + group_size=group_size, + scale_factor=scale_factor) + + if features.requires_grad or masks.requires_grad: + ctx.save_for_backward(features, masks, rfeatures) + return output + + @staticmethod + def backward(ctx, grad_output): + assert grad_output.is_cuda + + features, masks, rfeatures = ctx.saved_tensors + kernel_size = ctx.kernel_size + group_size = ctx.group_size + scale_factor = ctx.scale_factor + + rgrad_output = torch.zeros_like(grad_output, requires_grad=False) + rgrad_input_hs = torch.zeros_like(grad_output, requires_grad=False) + rgrad_input = torch.zeros_like(features, requires_grad=False) + rgrad_masks = torch.zeros_like(masks, requires_grad=False) + grad_input = torch.zeros_like(features, requires_grad=False) + grad_masks = torch.zeros_like(masks, requires_grad=False) + ext_module.carafe_backward( + grad_output.contiguous(), + rfeatures, + masks, + rgrad_output, + rgrad_input_hs, + rgrad_input, + rgrad_masks, + grad_input, + grad_masks, + kernel_size=kernel_size, + group_size=group_size, + scale_factor=scale_factor) + return grad_input, grad_masks, None, None, None + + +carafe = CARAFEFunction.apply + + +class CARAFE(Module): + """ CARAFE: Content-Aware ReAssembly of FEatures + + Please refer to https://arxiv.org/abs/1905.02188 for more details. + + Args: + kernel_size (int): reassemble kernel size + group_size (int): reassemble group size + scale_factor (int): upsample ratio + + Returns: + upsampled feature map + """ + + def __init__(self, kernel_size, group_size, scale_factor): + super(CARAFE, self).__init__() + + assert isinstance(kernel_size, int) and isinstance( + group_size, int) and isinstance(scale_factor, int) + self.kernel_size = kernel_size + self.group_size = group_size + self.scale_factor = scale_factor + + def forward(self, features, masks): + return carafe(features, masks, self.kernel_size, self.group_size, + self.scale_factor) + + +@UPSAMPLE_LAYERS.register_module(name='carafe') +class CARAFEPack(nn.Module): + """A unified package of CARAFE upsampler that contains: 1) channel + compressor 2) content encoder 3) CARAFE op. + + Official implementation of ICCV 2019 paper + CARAFE: Content-Aware ReAssembly of FEatures + Please refer to https://arxiv.org/abs/1905.02188 for more details. + + Args: + channels (int): input feature channels + scale_factor (int): upsample ratio + up_kernel (int): kernel size of CARAFE op + up_group (int): group size of CARAFE op + encoder_kernel (int): kernel size of content encoder + encoder_dilation (int): dilation of content encoder + compressed_channels (int): output channels of channels compressor + + Returns: + upsampled feature map + """ + + def __init__(self, + channels, + scale_factor, + up_kernel=5, + up_group=1, + encoder_kernel=3, + encoder_dilation=1, + compressed_channels=64): + super(CARAFEPack, self).__init__() + self.channels = channels + self.scale_factor = scale_factor + self.up_kernel = up_kernel + self.up_group = up_group + self.encoder_kernel = encoder_kernel + self.encoder_dilation = encoder_dilation + self.compressed_channels = compressed_channels + self.channel_compressor = nn.Conv2d(channels, self.compressed_channels, + 1) + self.content_encoder = nn.Conv2d( + self.compressed_channels, + self.up_kernel * self.up_kernel * self.up_group * + self.scale_factor * self.scale_factor, + self.encoder_kernel, + padding=int((self.encoder_kernel - 1) * self.encoder_dilation / 2), + dilation=self.encoder_dilation, + groups=1) + self.init_weights() + + def init_weights(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + xavier_init(m, distribution='uniform') + normal_init(self.content_encoder, std=0.001) + + def kernel_normalizer(self, mask): + mask = F.pixel_shuffle(mask, self.scale_factor) + n, mask_c, h, w = mask.size() + # use float division explicitly, + # to void inconsistency while exporting to onnx + mask_channel = int(mask_c / float(self.up_kernel**2)) + mask = mask.view(n, mask_channel, -1, h, w) + + mask = F.softmax(mask, dim=2, dtype=mask.dtype) + mask = mask.view(n, mask_c, h, w).contiguous() + + return mask + + def feature_reassemble(self, x, mask): + x = carafe(x, mask, self.up_kernel, self.up_group, self.scale_factor) + return x + + def forward(self, x): + compressed_x = self.channel_compressor(x) + mask = self.content_encoder(compressed_x) + mask = self.kernel_normalizer(mask) + + x = self.feature_reassemble(x, mask) + return x diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/cc_attention.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/cc_attention.py new file mode 100644 index 00000000..8982f467 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/cc_attention.py @@ -0,0 +1,83 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.nn as nn +import torch.nn.functional as F + +from annotator.mmpkg.mmcv.cnn import PLUGIN_LAYERS, Scale + + +def NEG_INF_DIAG(n, device): + """Returns a diagonal matrix of size [n, n]. + + The diagonal are all "-inf". This is for avoiding calculating the + overlapped element in the Criss-Cross twice. + """ + return torch.diag(torch.tensor(float('-inf')).to(device).repeat(n), 0) + + +@PLUGIN_LAYERS.register_module() +class CrissCrossAttention(nn.Module): + """Criss-Cross Attention Module. + + .. note:: + Before v1.3.13, we use a CUDA op. Since v1.3.13, we switch + to a pure PyTorch and equivalent implementation. For more + details, please refer to https://github.com/open-mmlab/mmcv/pull/1201. + + Speed comparison for one forward pass + + - Input size: [2,512,97,97] + - Device: 1 NVIDIA GeForce RTX 2080 Ti + + +-----------------------+---------------+------------+---------------+ + | |PyTorch version|CUDA version|Relative speed | + +=======================+===============+============+===============+ + |with torch.no_grad() |0.00554402 s |0.0299619 s |5.4x | + +-----------------------+---------------+------------+---------------+ + |no with torch.no_grad()|0.00562803 s |0.0301349 s |5.4x | + +-----------------------+---------------+------------+---------------+ + + Args: + in_channels (int): Channels of the input feature map. + """ + + def __init__(self, in_channels): + super().__init__() + self.query_conv = nn.Conv2d(in_channels, in_channels // 8, 1) + self.key_conv = nn.Conv2d(in_channels, in_channels // 8, 1) + self.value_conv = nn.Conv2d(in_channels, in_channels, 1) + self.gamma = Scale(0.) + self.in_channels = in_channels + + def forward(self, x): + """forward function of Criss-Cross Attention. + + Args: + x (Tensor): Input feature. \ + shape (batch_size, in_channels, height, width) + Returns: + Tensor: Output of the layer, with shape of \ + (batch_size, in_channels, height, width) + """ + B, C, H, W = x.size() + query = self.query_conv(x) + key = self.key_conv(x) + value = self.value_conv(x) + energy_H = torch.einsum('bchw,bciw->bwhi', query, key) + NEG_INF_DIAG( + H, query.device) + energy_H = energy_H.transpose(1, 2) + energy_W = torch.einsum('bchw,bchj->bhwj', query, key) + attn = F.softmax( + torch.cat([energy_H, energy_W], dim=-1), dim=-1) # [B,H,W,(H+W)] + out = torch.einsum('bciw,bhwi->bchw', value, attn[..., :H]) + out += torch.einsum('bchj,bhwj->bchw', value, attn[..., H:]) + + out = self.gamma(out) + x + out = out.contiguous() + + return out + + def __repr__(self): + s = self.__class__.__name__ + s += f'(in_channels={self.in_channels})' + return s diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/contour_expand.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/contour_expand.py new file mode 100644 index 00000000..ea1111e1 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/contour_expand.py @@ -0,0 +1,49 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import numpy as np +import torch + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', ['contour_expand']) + + +def contour_expand(kernel_mask, internal_kernel_label, min_kernel_area, + kernel_num): + """Expand kernel contours so that foreground pixels are assigned into + instances. + + Arguments: + kernel_mask (np.array or Tensor): The instance kernel mask with + size hxw. + internal_kernel_label (np.array or Tensor): The instance internal + kernel label with size hxw. + min_kernel_area (int): The minimum kernel area. + kernel_num (int): The instance kernel number. + + Returns: + label (list): The instance index map with size hxw. + """ + assert isinstance(kernel_mask, (torch.Tensor, np.ndarray)) + assert isinstance(internal_kernel_label, (torch.Tensor, np.ndarray)) + assert isinstance(min_kernel_area, int) + assert isinstance(kernel_num, int) + + if isinstance(kernel_mask, np.ndarray): + kernel_mask = torch.from_numpy(kernel_mask) + if isinstance(internal_kernel_label, np.ndarray): + internal_kernel_label = torch.from_numpy(internal_kernel_label) + + if torch.__version__ == 'parrots': + if kernel_mask.shape[0] == 0 or internal_kernel_label.shape[0] == 0: + label = [] + else: + label = ext_module.contour_expand( + kernel_mask, + internal_kernel_label, + min_kernel_area=min_kernel_area, + kernel_num=kernel_num) + label = label.tolist() + else: + label = ext_module.contour_expand(kernel_mask, internal_kernel_label, + min_kernel_area, kernel_num) + return label diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/corner_pool.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/corner_pool.py new file mode 100644 index 00000000..a33d798b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/corner_pool.py @@ -0,0 +1,161 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +from torch import nn +from torch.autograd import Function + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', [ + 'top_pool_forward', 'top_pool_backward', 'bottom_pool_forward', + 'bottom_pool_backward', 'left_pool_forward', 'left_pool_backward', + 'right_pool_forward', 'right_pool_backward' +]) + +_mode_dict = {'top': 0, 'bottom': 1, 'left': 2, 'right': 3} + + +class TopPoolFunction(Function): + + @staticmethod + def symbolic(g, input): + output = g.op( + 'mmcv::MMCVCornerPool', input, mode_i=int(_mode_dict['top'])) + return output + + @staticmethod + def forward(ctx, input): + output = ext_module.top_pool_forward(input) + ctx.save_for_backward(input) + return output + + @staticmethod + def backward(ctx, grad_output): + input, = ctx.saved_tensors + output = ext_module.top_pool_backward(input, grad_output) + return output + + +class BottomPoolFunction(Function): + + @staticmethod + def symbolic(g, input): + output = g.op( + 'mmcv::MMCVCornerPool', input, mode_i=int(_mode_dict['bottom'])) + return output + + @staticmethod + def forward(ctx, input): + output = ext_module.bottom_pool_forward(input) + ctx.save_for_backward(input) + return output + + @staticmethod + def backward(ctx, grad_output): + input, = ctx.saved_tensors + output = ext_module.bottom_pool_backward(input, grad_output) + return output + + +class LeftPoolFunction(Function): + + @staticmethod + def symbolic(g, input): + output = g.op( + 'mmcv::MMCVCornerPool', input, mode_i=int(_mode_dict['left'])) + return output + + @staticmethod + def forward(ctx, input): + output = ext_module.left_pool_forward(input) + ctx.save_for_backward(input) + return output + + @staticmethod + def backward(ctx, grad_output): + input, = ctx.saved_tensors + output = ext_module.left_pool_backward(input, grad_output) + return output + + +class RightPoolFunction(Function): + + @staticmethod + def symbolic(g, input): + output = g.op( + 'mmcv::MMCVCornerPool', input, mode_i=int(_mode_dict['right'])) + return output + + @staticmethod + def forward(ctx, input): + output = ext_module.right_pool_forward(input) + ctx.save_for_backward(input) + return output + + @staticmethod + def backward(ctx, grad_output): + input, = ctx.saved_tensors + output = ext_module.right_pool_backward(input, grad_output) + return output + + +class CornerPool(nn.Module): + """Corner Pooling. + + Corner Pooling is a new type of pooling layer that helps a + convolutional network better localize corners of bounding boxes. + + Please refer to https://arxiv.org/abs/1808.01244 for more details. + Code is modified from https://github.com/princeton-vl/CornerNet-Lite. + + Args: + mode(str): Pooling orientation for the pooling layer + + - 'bottom': Bottom Pooling + - 'left': Left Pooling + - 'right': Right Pooling + - 'top': Top Pooling + + Returns: + Feature map after pooling. + """ + + pool_functions = { + 'bottom': BottomPoolFunction, + 'left': LeftPoolFunction, + 'right': RightPoolFunction, + 'top': TopPoolFunction, + } + + cummax_dim_flip = { + 'bottom': (2, False), + 'left': (3, True), + 'right': (3, False), + 'top': (2, True), + } + + def __init__(self, mode): + super(CornerPool, self).__init__() + assert mode in self.pool_functions + self.mode = mode + self.corner_pool = self.pool_functions[mode] + + def forward(self, x): + if torch.__version__ != 'parrots' and torch.__version__ >= '1.5.0': + if torch.onnx.is_in_onnx_export(): + assert torch.__version__ >= '1.7.0', \ + 'When `cummax` serves as an intermediate component whose '\ + 'outputs is used as inputs for another modules, it\'s '\ + 'expected that pytorch version must be >= 1.7.0, '\ + 'otherwise Error appears like: `RuntimeError: tuple '\ + 'appears in op that does not forward tuples, unsupported '\ + 'kind: prim::PythonOp`.' + + dim, flip = self.cummax_dim_flip[self.mode] + if flip: + x = x.flip(dim) + pool_tensor, _ = torch.cummax(x, dim=dim) + if flip: + pool_tensor = pool_tensor.flip(dim) + return pool_tensor + else: + return self.corner_pool.apply(x) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/correlation.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/correlation.py new file mode 100644 index 00000000..3d0b79c3 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/correlation.py @@ -0,0 +1,196 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +from torch import Tensor, nn +from torch.autograd import Function +from torch.autograd.function import once_differentiable +from torch.nn.modules.utils import _pair + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext( + '_ext', ['correlation_forward', 'correlation_backward']) + + +class CorrelationFunction(Function): + + @staticmethod + def forward(ctx, + input1, + input2, + kernel_size=1, + max_displacement=1, + stride=1, + padding=1, + dilation=1, + dilation_patch=1): + + ctx.save_for_backward(input1, input2) + + kH, kW = ctx.kernel_size = _pair(kernel_size) + patch_size = max_displacement * 2 + 1 + ctx.patch_size = patch_size + dH, dW = ctx.stride = _pair(stride) + padH, padW = ctx.padding = _pair(padding) + dilationH, dilationW = ctx.dilation = _pair(dilation) + dilation_patchH, dilation_patchW = ctx.dilation_patch = _pair( + dilation_patch) + + output_size = CorrelationFunction._output_size(ctx, input1) + + output = input1.new_zeros(output_size) + + ext_module.correlation_forward( + input1, + input2, + output, + kH=kH, + kW=kW, + patchH=patch_size, + patchW=patch_size, + padH=padH, + padW=padW, + dilationH=dilationH, + dilationW=dilationW, + dilation_patchH=dilation_patchH, + dilation_patchW=dilation_patchW, + dH=dH, + dW=dW) + + return output + + @staticmethod + @once_differentiable + def backward(ctx, grad_output): + input1, input2 = ctx.saved_tensors + + kH, kW = ctx.kernel_size + patch_size = ctx.patch_size + padH, padW = ctx.padding + dilationH, dilationW = ctx.dilation + dilation_patchH, dilation_patchW = ctx.dilation_patch + dH, dW = ctx.stride + grad_input1 = torch.zeros_like(input1) + grad_input2 = torch.zeros_like(input2) + + ext_module.correlation_backward( + grad_output, + input1, + input2, + grad_input1, + grad_input2, + kH=kH, + kW=kW, + patchH=patch_size, + patchW=patch_size, + padH=padH, + padW=padW, + dilationH=dilationH, + dilationW=dilationW, + dilation_patchH=dilation_patchH, + dilation_patchW=dilation_patchW, + dH=dH, + dW=dW) + return grad_input1, grad_input2, None, None, None, None, None, None + + @staticmethod + def _output_size(ctx, input1): + iH, iW = input1.size(2), input1.size(3) + batch_size = input1.size(0) + kH, kW = ctx.kernel_size + patch_size = ctx.patch_size + dH, dW = ctx.stride + padH, padW = ctx.padding + dilationH, dilationW = ctx.dilation + dilatedKH = (kH - 1) * dilationH + 1 + dilatedKW = (kW - 1) * dilationW + 1 + + oH = int((iH + 2 * padH - dilatedKH) / dH + 1) + oW = int((iW + 2 * padW - dilatedKW) / dW + 1) + + output_size = (batch_size, patch_size, patch_size, oH, oW) + return output_size + + +class Correlation(nn.Module): + r"""Correlation operator + + This correlation operator works for optical flow correlation computation. + + There are two batched tensors with shape :math:`(N, C, H, W)`, + and the correlation output's shape is :math:`(N, max\_displacement \times + 2 + 1, max\_displacement * 2 + 1, H_{out}, W_{out})` + + where + + .. math:: + H_{out} = \left\lfloor\frac{H_{in} + 2 \times padding - + dilation \times (kernel\_size - 1) - 1} + {stride} + 1\right\rfloor + + .. math:: + W_{out} = \left\lfloor\frac{W_{in} + 2 \times padding - dilation + \times (kernel\_size - 1) - 1} + {stride} + 1\right\rfloor + + the correlation item :math:`(N_i, dy, dx)` is formed by taking the sliding + window convolution between input1 and shifted input2, + + .. math:: + Corr(N_i, dx, dy) = + \sum_{c=0}^{C-1} + input1(N_i, c) \star + \mathcal{S}(input2(N_i, c), dy, dx) + + where :math:`\star` is the valid 2d sliding window convolution operator, + and :math:`\mathcal{S}` means shifting the input features (auto-complete + zero marginal), and :math:`dx, dy` are shifting distance, :math:`dx, dy \in + [-max\_displacement \times dilation\_patch, max\_displacement \times + dilation\_patch]`. + + Args: + kernel_size (int): The size of sliding window i.e. local neighborhood + representing the center points and involved in correlation + computation. Defaults to 1. + max_displacement (int): The radius for computing correlation volume, + but the actual working space can be dilated by dilation_patch. + Defaults to 1. + stride (int): The stride of the sliding blocks in the input spatial + dimensions. Defaults to 1. + padding (int): Zero padding added to all four sides of the input1. + Defaults to 0. + dilation (int): The spacing of local neighborhood that will involved + in correlation. Defaults to 1. + dilation_patch (int): The spacing between position need to compute + correlation. Defaults to 1. + """ + + def __init__(self, + kernel_size: int = 1, + max_displacement: int = 1, + stride: int = 1, + padding: int = 0, + dilation: int = 1, + dilation_patch: int = 1) -> None: + super().__init__() + self.kernel_size = kernel_size + self.max_displacement = max_displacement + self.stride = stride + self.padding = padding + self.dilation = dilation + self.dilation_patch = dilation_patch + + def forward(self, input1: Tensor, input2: Tensor) -> Tensor: + return CorrelationFunction.apply(input1, input2, self.kernel_size, + self.max_displacement, self.stride, + self.padding, self.dilation, + self.dilation_patch) + + def __repr__(self) -> str: + s = self.__class__.__name__ + s += f'(kernel_size={self.kernel_size}, ' + s += f'max_displacement={self.max_displacement}, ' + s += f'stride={self.stride}, ' + s += f'padding={self.padding}, ' + s += f'dilation={self.dilation}, ' + s += f'dilation_patch={self.dilation_patch})' + return s diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/deform_conv.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/deform_conv.py new file mode 100644 index 00000000..3de3aae1 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/deform_conv.py @@ -0,0 +1,405 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from typing import Tuple, Union + +import torch +import torch.nn as nn +import torch.nn.functional as F +from torch import Tensor +from torch.autograd import Function +from torch.autograd.function import once_differentiable +from torch.nn.modules.utils import _pair, _single + +from annotator.mmpkg.mmcv.utils import deprecated_api_warning +from ..cnn import CONV_LAYERS +from ..utils import ext_loader, print_log + +ext_module = ext_loader.load_ext('_ext', [ + 'deform_conv_forward', 'deform_conv_backward_input', + 'deform_conv_backward_parameters' +]) + + +class DeformConv2dFunction(Function): + + @staticmethod + def symbolic(g, + input, + offset, + weight, + stride, + padding, + dilation, + groups, + deform_groups, + bias=False, + im2col_step=32): + return g.op( + 'mmcv::MMCVDeformConv2d', + input, + offset, + weight, + stride_i=stride, + padding_i=padding, + dilation_i=dilation, + groups_i=groups, + deform_groups_i=deform_groups, + bias_i=bias, + im2col_step_i=im2col_step) + + @staticmethod + def forward(ctx, + input, + offset, + weight, + stride=1, + padding=0, + dilation=1, + groups=1, + deform_groups=1, + bias=False, + im2col_step=32): + if input is not None and input.dim() != 4: + raise ValueError( + f'Expected 4D tensor as input, got {input.dim()}D tensor \ + instead.') + assert bias is False, 'Only support bias is False.' + ctx.stride = _pair(stride) + ctx.padding = _pair(padding) + ctx.dilation = _pair(dilation) + ctx.groups = groups + ctx.deform_groups = deform_groups + ctx.im2col_step = im2col_step + + # When pytorch version >= 1.6.0, amp is adopted for fp16 mode; + # amp won't cast the type of model (float32), but "offset" is cast + # to float16 by nn.Conv2d automatically, leading to the type + # mismatch with input (when it is float32) or weight. + # The flag for whether to use fp16 or amp is the type of "offset", + # we cast weight and input to temporarily support fp16 and amp + # whatever the pytorch version is. + input = input.type_as(offset) + weight = weight.type_as(input) + ctx.save_for_backward(input, offset, weight) + + output = input.new_empty( + DeformConv2dFunction._output_size(ctx, input, weight)) + + ctx.bufs_ = [input.new_empty(0), input.new_empty(0)] # columns, ones + + cur_im2col_step = min(ctx.im2col_step, input.size(0)) + assert (input.size(0) % + cur_im2col_step) == 0, 'im2col step must divide batchsize' + ext_module.deform_conv_forward( + input, + weight, + offset, + output, + ctx.bufs_[0], + ctx.bufs_[1], + kW=weight.size(3), + kH=weight.size(2), + dW=ctx.stride[1], + dH=ctx.stride[0], + padW=ctx.padding[1], + padH=ctx.padding[0], + dilationW=ctx.dilation[1], + dilationH=ctx.dilation[0], + group=ctx.groups, + deformable_group=ctx.deform_groups, + im2col_step=cur_im2col_step) + return output + + @staticmethod + @once_differentiable + def backward(ctx, grad_output): + input, offset, weight = ctx.saved_tensors + + grad_input = grad_offset = grad_weight = None + + cur_im2col_step = min(ctx.im2col_step, input.size(0)) + assert (input.size(0) % cur_im2col_step + ) == 0, 'batch size must be divisible by im2col_step' + + grad_output = grad_output.contiguous() + if ctx.needs_input_grad[0] or ctx.needs_input_grad[1]: + grad_input = torch.zeros_like(input) + grad_offset = torch.zeros_like(offset) + ext_module.deform_conv_backward_input( + input, + offset, + grad_output, + grad_input, + grad_offset, + weight, + ctx.bufs_[0], + kW=weight.size(3), + kH=weight.size(2), + dW=ctx.stride[1], + dH=ctx.stride[0], + padW=ctx.padding[1], + padH=ctx.padding[0], + dilationW=ctx.dilation[1], + dilationH=ctx.dilation[0], + group=ctx.groups, + deformable_group=ctx.deform_groups, + im2col_step=cur_im2col_step) + + if ctx.needs_input_grad[2]: + grad_weight = torch.zeros_like(weight) + ext_module.deform_conv_backward_parameters( + input, + offset, + grad_output, + grad_weight, + ctx.bufs_[0], + ctx.bufs_[1], + kW=weight.size(3), + kH=weight.size(2), + dW=ctx.stride[1], + dH=ctx.stride[0], + padW=ctx.padding[1], + padH=ctx.padding[0], + dilationW=ctx.dilation[1], + dilationH=ctx.dilation[0], + group=ctx.groups, + deformable_group=ctx.deform_groups, + scale=1, + im2col_step=cur_im2col_step) + + return grad_input, grad_offset, grad_weight, \ + None, None, None, None, None, None, None + + @staticmethod + def _output_size(ctx, input, weight): + channels = weight.size(0) + output_size = (input.size(0), channels) + for d in range(input.dim() - 2): + in_size = input.size(d + 2) + pad = ctx.padding[d] + kernel = ctx.dilation[d] * (weight.size(d + 2) - 1) + 1 + stride_ = ctx.stride[d] + output_size += ((in_size + (2 * pad) - kernel) // stride_ + 1, ) + if not all(map(lambda s: s > 0, output_size)): + raise ValueError( + 'convolution input is too small (output would be ' + + 'x'.join(map(str, output_size)) + ')') + return output_size + + +deform_conv2d = DeformConv2dFunction.apply + + +class DeformConv2d(nn.Module): + r"""Deformable 2D convolution. + + Applies a deformable 2D convolution over an input signal composed of + several input planes. DeformConv2d was described in the paper + `Deformable Convolutional Networks + `_ + + Note: + The argument ``im2col_step`` was added in version 1.3.17, which means + number of samples processed by the ``im2col_cuda_kernel`` per call. + It enables users to define ``batch_size`` and ``im2col_step`` more + flexibly and solved `issue mmcv#1440 + `_. + + Args: + in_channels (int): Number of channels in the input image. + out_channels (int): Number of channels produced by the convolution. + kernel_size(int, tuple): Size of the convolving kernel. + stride(int, tuple): Stride of the convolution. Default: 1. + padding (int or tuple): Zero-padding added to both sides of the input. + Default: 0. + dilation (int or tuple): Spacing between kernel elements. Default: 1. + groups (int): Number of blocked connections from input. + channels to output channels. Default: 1. + deform_groups (int): Number of deformable group partitions. + bias (bool): If True, adds a learnable bias to the output. + Default: False. + im2col_step (int): Number of samples processed by im2col_cuda_kernel + per call. It will work when ``batch_size`` > ``im2col_step``, but + ``batch_size`` must be divisible by ``im2col_step``. Default: 32. + `New in version 1.3.17.` + """ + + @deprecated_api_warning({'deformable_groups': 'deform_groups'}, + cls_name='DeformConv2d') + def __init__(self, + in_channels: int, + out_channels: int, + kernel_size: Union[int, Tuple[int, ...]], + stride: Union[int, Tuple[int, ...]] = 1, + padding: Union[int, Tuple[int, ...]] = 0, + dilation: Union[int, Tuple[int, ...]] = 1, + groups: int = 1, + deform_groups: int = 1, + bias: bool = False, + im2col_step: int = 32) -> None: + super(DeformConv2d, self).__init__() + + assert not bias, \ + f'bias={bias} is not supported in DeformConv2d.' + assert in_channels % groups == 0, \ + f'in_channels {in_channels} cannot be divisible by groups {groups}' + assert out_channels % groups == 0, \ + f'out_channels {out_channels} cannot be divisible by groups \ + {groups}' + + self.in_channels = in_channels + self.out_channels = out_channels + self.kernel_size = _pair(kernel_size) + self.stride = _pair(stride) + self.padding = _pair(padding) + self.dilation = _pair(dilation) + self.groups = groups + self.deform_groups = deform_groups + self.im2col_step = im2col_step + # enable compatibility with nn.Conv2d + self.transposed = False + self.output_padding = _single(0) + + # only weight, no bias + self.weight = nn.Parameter( + torch.Tensor(out_channels, in_channels // self.groups, + *self.kernel_size)) + + self.reset_parameters() + + def reset_parameters(self): + # switch the initialization of `self.weight` to the standard kaiming + # method described in `Delving deep into rectifiers: Surpassing + # human-level performance on ImageNet classification` - He, K. et al. + # (2015), using a uniform distribution + nn.init.kaiming_uniform_(self.weight, nonlinearity='relu') + + def forward(self, x: Tensor, offset: Tensor) -> Tensor: + """Deformable Convolutional forward function. + + Args: + x (Tensor): Input feature, shape (B, C_in, H_in, W_in) + offset (Tensor): Offset for deformable convolution, shape + (B, deform_groups*kernel_size[0]*kernel_size[1]*2, + H_out, W_out), H_out, W_out are equal to the output's. + + An offset is like `[y0, x0, y1, x1, y2, x2, ..., y8, x8]`. + The spatial arrangement is like: + + .. code:: text + + (x0, y0) (x1, y1) (x2, y2) + (x3, y3) (x4, y4) (x5, y5) + (x6, y6) (x7, y7) (x8, y8) + + Returns: + Tensor: Output of the layer. + """ + # To fix an assert error in deform_conv_cuda.cpp:128 + # input image is smaller than kernel + input_pad = (x.size(2) < self.kernel_size[0]) or (x.size(3) < + self.kernel_size[1]) + if input_pad: + pad_h = max(self.kernel_size[0] - x.size(2), 0) + pad_w = max(self.kernel_size[1] - x.size(3), 0) + x = F.pad(x, (0, pad_w, 0, pad_h), 'constant', 0).contiguous() + offset = F.pad(offset, (0, pad_w, 0, pad_h), 'constant', 0) + offset = offset.contiguous() + out = deform_conv2d(x, offset, self.weight, self.stride, self.padding, + self.dilation, self.groups, self.deform_groups, + False, self.im2col_step) + if input_pad: + out = out[:, :, :out.size(2) - pad_h, :out.size(3) - + pad_w].contiguous() + return out + + def __repr__(self): + s = self.__class__.__name__ + s += f'(in_channels={self.in_channels},\n' + s += f'out_channels={self.out_channels},\n' + s += f'kernel_size={self.kernel_size},\n' + s += f'stride={self.stride},\n' + s += f'padding={self.padding},\n' + s += f'dilation={self.dilation},\n' + s += f'groups={self.groups},\n' + s += f'deform_groups={self.deform_groups},\n' + # bias is not supported in DeformConv2d. + s += 'bias=False)' + return s + + +@CONV_LAYERS.register_module('DCN') +class DeformConv2dPack(DeformConv2d): + """A Deformable Conv Encapsulation that acts as normal Conv layers. + + The offset tensor is like `[y0, x0, y1, x1, y2, x2, ..., y8, x8]`. + The spatial arrangement is like: + + .. code:: text + + (x0, y0) (x1, y1) (x2, y2) + (x3, y3) (x4, y4) (x5, y5) + (x6, y6) (x7, y7) (x8, y8) + + Args: + in_channels (int): Same as nn.Conv2d. + out_channels (int): Same as nn.Conv2d. + kernel_size (int or tuple[int]): Same as nn.Conv2d. + stride (int or tuple[int]): Same as nn.Conv2d. + padding (int or tuple[int]): Same as nn.Conv2d. + dilation (int or tuple[int]): Same as nn.Conv2d. + groups (int): Same as nn.Conv2d. + bias (bool or str): If specified as `auto`, it will be decided by the + norm_cfg. Bias will be set as True if norm_cfg is None, otherwise + False. + """ + + _version = 2 + + def __init__(self, *args, **kwargs): + super(DeformConv2dPack, self).__init__(*args, **kwargs) + self.conv_offset = nn.Conv2d( + self.in_channels, + self.deform_groups * 2 * self.kernel_size[0] * self.kernel_size[1], + kernel_size=self.kernel_size, + stride=_pair(self.stride), + padding=_pair(self.padding), + dilation=_pair(self.dilation), + bias=True) + self.init_offset() + + def init_offset(self): + self.conv_offset.weight.data.zero_() + self.conv_offset.bias.data.zero_() + + def forward(self, x): + offset = self.conv_offset(x) + return deform_conv2d(x, offset, self.weight, self.stride, self.padding, + self.dilation, self.groups, self.deform_groups, + False, self.im2col_step) + + def _load_from_state_dict(self, state_dict, prefix, local_metadata, strict, + missing_keys, unexpected_keys, error_msgs): + version = local_metadata.get('version', None) + + if version is None or version < 2: + # the key is different in early versions + # In version < 2, DeformConvPack loads previous benchmark models. + if (prefix + 'conv_offset.weight' not in state_dict + and prefix[:-1] + '_offset.weight' in state_dict): + state_dict[prefix + 'conv_offset.weight'] = state_dict.pop( + prefix[:-1] + '_offset.weight') + if (prefix + 'conv_offset.bias' not in state_dict + and prefix[:-1] + '_offset.bias' in state_dict): + state_dict[prefix + + 'conv_offset.bias'] = state_dict.pop(prefix[:-1] + + '_offset.bias') + + if version is not None and version > 1: + print_log( + f'DeformConv2dPack {prefix.rstrip(".")} is upgraded to ' + 'version 2.', + logger='root') + + super()._load_from_state_dict(state_dict, prefix, local_metadata, + strict, missing_keys, unexpected_keys, + error_msgs) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/deform_roi_pool.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/deform_roi_pool.py new file mode 100644 index 00000000..cc245ba9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/deform_roi_pool.py @@ -0,0 +1,204 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from torch import nn +from torch.autograd import Function +from torch.autograd.function import once_differentiable +from torch.nn.modules.utils import _pair + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext( + '_ext', ['deform_roi_pool_forward', 'deform_roi_pool_backward']) + + +class DeformRoIPoolFunction(Function): + + @staticmethod + def symbolic(g, input, rois, offset, output_size, spatial_scale, + sampling_ratio, gamma): + return g.op( + 'mmcv::MMCVDeformRoIPool', + input, + rois, + offset, + pooled_height_i=output_size[0], + pooled_width_i=output_size[1], + spatial_scale_f=spatial_scale, + sampling_ratio_f=sampling_ratio, + gamma_f=gamma) + + @staticmethod + def forward(ctx, + input, + rois, + offset, + output_size, + spatial_scale=1.0, + sampling_ratio=0, + gamma=0.1): + if offset is None: + offset = input.new_zeros(0) + ctx.output_size = _pair(output_size) + ctx.spatial_scale = float(spatial_scale) + ctx.sampling_ratio = int(sampling_ratio) + ctx.gamma = float(gamma) + + assert rois.size(1) == 5, 'RoI must be (idx, x1, y1, x2, y2)!' + + output_shape = (rois.size(0), input.size(1), ctx.output_size[0], + ctx.output_size[1]) + output = input.new_zeros(output_shape) + + ext_module.deform_roi_pool_forward( + input, + rois, + offset, + output, + pooled_height=ctx.output_size[0], + pooled_width=ctx.output_size[1], + spatial_scale=ctx.spatial_scale, + sampling_ratio=ctx.sampling_ratio, + gamma=ctx.gamma) + + ctx.save_for_backward(input, rois, offset) + return output + + @staticmethod + @once_differentiable + def backward(ctx, grad_output): + input, rois, offset = ctx.saved_tensors + grad_input = grad_output.new_zeros(input.shape) + grad_offset = grad_output.new_zeros(offset.shape) + + ext_module.deform_roi_pool_backward( + grad_output, + input, + rois, + offset, + grad_input, + grad_offset, + pooled_height=ctx.output_size[0], + pooled_width=ctx.output_size[1], + spatial_scale=ctx.spatial_scale, + sampling_ratio=ctx.sampling_ratio, + gamma=ctx.gamma) + if grad_offset.numel() == 0: + grad_offset = None + return grad_input, None, grad_offset, None, None, None, None + + +deform_roi_pool = DeformRoIPoolFunction.apply + + +class DeformRoIPool(nn.Module): + + def __init__(self, + output_size, + spatial_scale=1.0, + sampling_ratio=0, + gamma=0.1): + super(DeformRoIPool, self).__init__() + self.output_size = _pair(output_size) + self.spatial_scale = float(spatial_scale) + self.sampling_ratio = int(sampling_ratio) + self.gamma = float(gamma) + + def forward(self, input, rois, offset=None): + return deform_roi_pool(input, rois, offset, self.output_size, + self.spatial_scale, self.sampling_ratio, + self.gamma) + + +class DeformRoIPoolPack(DeformRoIPool): + + def __init__(self, + output_size, + output_channels, + deform_fc_channels=1024, + spatial_scale=1.0, + sampling_ratio=0, + gamma=0.1): + super(DeformRoIPoolPack, self).__init__(output_size, spatial_scale, + sampling_ratio, gamma) + + self.output_channels = output_channels + self.deform_fc_channels = deform_fc_channels + + self.offset_fc = nn.Sequential( + nn.Linear( + self.output_size[0] * self.output_size[1] * + self.output_channels, self.deform_fc_channels), + nn.ReLU(inplace=True), + nn.Linear(self.deform_fc_channels, self.deform_fc_channels), + nn.ReLU(inplace=True), + nn.Linear(self.deform_fc_channels, + self.output_size[0] * self.output_size[1] * 2)) + self.offset_fc[-1].weight.data.zero_() + self.offset_fc[-1].bias.data.zero_() + + def forward(self, input, rois): + assert input.size(1) == self.output_channels + x = deform_roi_pool(input, rois, None, self.output_size, + self.spatial_scale, self.sampling_ratio, + self.gamma) + rois_num = rois.size(0) + offset = self.offset_fc(x.view(rois_num, -1)) + offset = offset.view(rois_num, 2, self.output_size[0], + self.output_size[1]) + return deform_roi_pool(input, rois, offset, self.output_size, + self.spatial_scale, self.sampling_ratio, + self.gamma) + + +class ModulatedDeformRoIPoolPack(DeformRoIPool): + + def __init__(self, + output_size, + output_channels, + deform_fc_channels=1024, + spatial_scale=1.0, + sampling_ratio=0, + gamma=0.1): + super(ModulatedDeformRoIPoolPack, + self).__init__(output_size, spatial_scale, sampling_ratio, gamma) + + self.output_channels = output_channels + self.deform_fc_channels = deform_fc_channels + + self.offset_fc = nn.Sequential( + nn.Linear( + self.output_size[0] * self.output_size[1] * + self.output_channels, self.deform_fc_channels), + nn.ReLU(inplace=True), + nn.Linear(self.deform_fc_channels, self.deform_fc_channels), + nn.ReLU(inplace=True), + nn.Linear(self.deform_fc_channels, + self.output_size[0] * self.output_size[1] * 2)) + self.offset_fc[-1].weight.data.zero_() + self.offset_fc[-1].bias.data.zero_() + + self.mask_fc = nn.Sequential( + nn.Linear( + self.output_size[0] * self.output_size[1] * + self.output_channels, self.deform_fc_channels), + nn.ReLU(inplace=True), + nn.Linear(self.deform_fc_channels, + self.output_size[0] * self.output_size[1] * 1), + nn.Sigmoid()) + self.mask_fc[2].weight.data.zero_() + self.mask_fc[2].bias.data.zero_() + + def forward(self, input, rois): + assert input.size(1) == self.output_channels + x = deform_roi_pool(input, rois, None, self.output_size, + self.spatial_scale, self.sampling_ratio, + self.gamma) + rois_num = rois.size(0) + offset = self.offset_fc(x.view(rois_num, -1)) + offset = offset.view(rois_num, 2, self.output_size[0], + self.output_size[1]) + mask = self.mask_fc(x.view(rois_num, -1)) + mask = mask.view(rois_num, 1, self.output_size[0], self.output_size[1]) + d = deform_roi_pool(input, rois, offset, self.output_size, + self.spatial_scale, self.sampling_ratio, + self.gamma) + return d * mask diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/deprecated_wrappers.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/deprecated_wrappers.py new file mode 100644 index 00000000..a2e593df --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/deprecated_wrappers.py @@ -0,0 +1,43 @@ +# Copyright (c) OpenMMLab. All rights reserved. +# This file is for backward compatibility. +# Module wrappers for empty tensor have been moved to mmcv.cnn.bricks. +import warnings + +from ..cnn.bricks.wrappers import Conv2d, ConvTranspose2d, Linear, MaxPool2d + + +class Conv2d_deprecated(Conv2d): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + warnings.warn( + 'Importing Conv2d wrapper from "mmcv.ops" will be deprecated in' + ' the future. Please import them from "mmcv.cnn" instead') + + +class ConvTranspose2d_deprecated(ConvTranspose2d): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + warnings.warn( + 'Importing ConvTranspose2d wrapper from "mmcv.ops" will be ' + 'deprecated in the future. Please import them from "mmcv.cnn" ' + 'instead') + + +class MaxPool2d_deprecated(MaxPool2d): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + warnings.warn( + 'Importing MaxPool2d wrapper from "mmcv.ops" will be deprecated in' + ' the future. Please import them from "mmcv.cnn" instead') + + +class Linear_deprecated(Linear): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + warnings.warn( + 'Importing Linear wrapper from "mmcv.ops" will be deprecated in' + ' the future. Please import them from "mmcv.cnn" instead') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/focal_loss.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/focal_loss.py new file mode 100644 index 00000000..763bc93b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/focal_loss.py @@ -0,0 +1,212 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.nn as nn +from torch.autograd import Function +from torch.autograd.function import once_differentiable + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', [ + 'sigmoid_focal_loss_forward', 'sigmoid_focal_loss_backward', + 'softmax_focal_loss_forward', 'softmax_focal_loss_backward' +]) + + +class SigmoidFocalLossFunction(Function): + + @staticmethod + def symbolic(g, input, target, gamma, alpha, weight, reduction): + return g.op( + 'mmcv::MMCVSigmoidFocalLoss', + input, + target, + gamma_f=gamma, + alpha_f=alpha, + weight_f=weight, + reduction_s=reduction) + + @staticmethod + def forward(ctx, + input, + target, + gamma=2.0, + alpha=0.25, + weight=None, + reduction='mean'): + + assert isinstance(target, (torch.LongTensor, torch.cuda.LongTensor)) + assert input.dim() == 2 + assert target.dim() == 1 + assert input.size(0) == target.size(0) + if weight is None: + weight = input.new_empty(0) + else: + assert weight.dim() == 1 + assert input.size(1) == weight.size(0) + ctx.reduction_dict = {'none': 0, 'mean': 1, 'sum': 2} + assert reduction in ctx.reduction_dict.keys() + + ctx.gamma = float(gamma) + ctx.alpha = float(alpha) + ctx.reduction = ctx.reduction_dict[reduction] + + output = input.new_zeros(input.size()) + + ext_module.sigmoid_focal_loss_forward( + input, target, weight, output, gamma=ctx.gamma, alpha=ctx.alpha) + if ctx.reduction == ctx.reduction_dict['mean']: + output = output.sum() / input.size(0) + elif ctx.reduction == ctx.reduction_dict['sum']: + output = output.sum() + ctx.save_for_backward(input, target, weight) + return output + + @staticmethod + @once_differentiable + def backward(ctx, grad_output): + input, target, weight = ctx.saved_tensors + + grad_input = input.new_zeros(input.size()) + + ext_module.sigmoid_focal_loss_backward( + input, + target, + weight, + grad_input, + gamma=ctx.gamma, + alpha=ctx.alpha) + + grad_input *= grad_output + if ctx.reduction == ctx.reduction_dict['mean']: + grad_input /= input.size(0) + return grad_input, None, None, None, None, None + + +sigmoid_focal_loss = SigmoidFocalLossFunction.apply + + +class SigmoidFocalLoss(nn.Module): + + def __init__(self, gamma, alpha, weight=None, reduction='mean'): + super(SigmoidFocalLoss, self).__init__() + self.gamma = gamma + self.alpha = alpha + self.register_buffer('weight', weight) + self.reduction = reduction + + def forward(self, input, target): + return sigmoid_focal_loss(input, target, self.gamma, self.alpha, + self.weight, self.reduction) + + def __repr__(self): + s = self.__class__.__name__ + s += f'(gamma={self.gamma}, ' + s += f'alpha={self.alpha}, ' + s += f'reduction={self.reduction})' + return s + + +class SoftmaxFocalLossFunction(Function): + + @staticmethod + def symbolic(g, input, target, gamma, alpha, weight, reduction): + return g.op( + 'mmcv::MMCVSoftmaxFocalLoss', + input, + target, + gamma_f=gamma, + alpha_f=alpha, + weight_f=weight, + reduction_s=reduction) + + @staticmethod + def forward(ctx, + input, + target, + gamma=2.0, + alpha=0.25, + weight=None, + reduction='mean'): + + assert isinstance(target, (torch.LongTensor, torch.cuda.LongTensor)) + assert input.dim() == 2 + assert target.dim() == 1 + assert input.size(0) == target.size(0) + if weight is None: + weight = input.new_empty(0) + else: + assert weight.dim() == 1 + assert input.size(1) == weight.size(0) + ctx.reduction_dict = {'none': 0, 'mean': 1, 'sum': 2} + assert reduction in ctx.reduction_dict.keys() + + ctx.gamma = float(gamma) + ctx.alpha = float(alpha) + ctx.reduction = ctx.reduction_dict[reduction] + + channel_stats, _ = torch.max(input, dim=1) + input_softmax = input - channel_stats.unsqueeze(1).expand_as(input) + input_softmax.exp_() + + channel_stats = input_softmax.sum(dim=1) + input_softmax /= channel_stats.unsqueeze(1).expand_as(input) + + output = input.new_zeros(input.size(0)) + ext_module.softmax_focal_loss_forward( + input_softmax, + target, + weight, + output, + gamma=ctx.gamma, + alpha=ctx.alpha) + + if ctx.reduction == ctx.reduction_dict['mean']: + output = output.sum() / input.size(0) + elif ctx.reduction == ctx.reduction_dict['sum']: + output = output.sum() + ctx.save_for_backward(input_softmax, target, weight) + return output + + @staticmethod + def backward(ctx, grad_output): + input_softmax, target, weight = ctx.saved_tensors + buff = input_softmax.new_zeros(input_softmax.size(0)) + grad_input = input_softmax.new_zeros(input_softmax.size()) + + ext_module.softmax_focal_loss_backward( + input_softmax, + target, + weight, + buff, + grad_input, + gamma=ctx.gamma, + alpha=ctx.alpha) + + grad_input *= grad_output + if ctx.reduction == ctx.reduction_dict['mean']: + grad_input /= input_softmax.size(0) + return grad_input, None, None, None, None, None + + +softmax_focal_loss = SoftmaxFocalLossFunction.apply + + +class SoftmaxFocalLoss(nn.Module): + + def __init__(self, gamma, alpha, weight=None, reduction='mean'): + super(SoftmaxFocalLoss, self).__init__() + self.gamma = gamma + self.alpha = alpha + self.register_buffer('weight', weight) + self.reduction = reduction + + def forward(self, input, target): + return softmax_focal_loss(input, target, self.gamma, self.alpha, + self.weight, self.reduction) + + def __repr__(self): + s = self.__class__.__name__ + s += f'(gamma={self.gamma}, ' + s += f'alpha={self.alpha}, ' + s += f'reduction={self.reduction})' + return s diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/furthest_point_sample.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/furthest_point_sample.py new file mode 100644 index 00000000..374b7a87 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/furthest_point_sample.py @@ -0,0 +1,83 @@ +import torch +from torch.autograd import Function + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', [ + 'furthest_point_sampling_forward', + 'furthest_point_sampling_with_dist_forward' +]) + + +class FurthestPointSampling(Function): + """Uses iterative furthest point sampling to select a set of features whose + corresponding points have the furthest distance.""" + + @staticmethod + def forward(ctx, points_xyz: torch.Tensor, + num_points: int) -> torch.Tensor: + """ + Args: + points_xyz (Tensor): (B, N, 3) where N > num_points. + num_points (int): Number of points in the sampled set. + + Returns: + Tensor: (B, num_points) indices of the sampled points. + """ + assert points_xyz.is_contiguous() + + B, N = points_xyz.size()[:2] + output = torch.cuda.IntTensor(B, num_points) + temp = torch.cuda.FloatTensor(B, N).fill_(1e10) + + ext_module.furthest_point_sampling_forward( + points_xyz, + temp, + output, + b=B, + n=N, + m=num_points, + ) + if torch.__version__ != 'parrots': + ctx.mark_non_differentiable(output) + return output + + @staticmethod + def backward(xyz, a=None): + return None, None + + +class FurthestPointSamplingWithDist(Function): + """Uses iterative furthest point sampling to select a set of features whose + corresponding points have the furthest distance.""" + + @staticmethod + def forward(ctx, points_dist: torch.Tensor, + num_points: int) -> torch.Tensor: + """ + Args: + points_dist (Tensor): (B, N, N) Distance between each point pair. + num_points (int): Number of points in the sampled set. + + Returns: + Tensor: (B, num_points) indices of the sampled points. + """ + assert points_dist.is_contiguous() + + B, N, _ = points_dist.size() + output = points_dist.new_zeros([B, num_points], dtype=torch.int32) + temp = points_dist.new_zeros([B, N]).fill_(1e10) + + ext_module.furthest_point_sampling_with_dist_forward( + points_dist, temp, output, b=B, n=N, m=num_points) + if torch.__version__ != 'parrots': + ctx.mark_non_differentiable(output) + return output + + @staticmethod + def backward(xyz, a=None): + return None, None + + +furthest_point_sample = FurthestPointSampling.apply +furthest_point_sample_with_dist = FurthestPointSamplingWithDist.apply diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/fused_bias_leakyrelu.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/fused_bias_leakyrelu.py new file mode 100644 index 00000000..6d125084 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/fused_bias_leakyrelu.py @@ -0,0 +1,268 @@ +# modified from https://github.com/rosinality/stylegan2-pytorch/blob/master/op/fused_act.py # noqa:E501 + +# Copyright (c) 2021, NVIDIA Corporation. All rights reserved. +# NVIDIA Source Code License for StyleGAN2 with Adaptive Discriminator +# Augmentation (ADA) +# ======================================================================= + +# 1. Definitions + +# "Licensor" means any person or entity that distributes its Work. + +# "Software" means the original work of authorship made available under +# this License. + +# "Work" means the Software and any additions to or derivative works of +# the Software that are made available under this License. + +# The terms "reproduce," "reproduction," "derivative works," and +# "distribution" have the meaning as provided under U.S. copyright law; +# provided, however, that for the purposes of this License, derivative +# works shall not include works that remain separable from, or merely +# link (or bind by name) to the interfaces of, the Work. + +# Works, including the Software, are "made available" under this License +# by including in or with the Work either (a) a copyright notice +# referencing the applicability of this License to the Work, or (b) a +# copy of this License. + +# 2. License Grants + +# 2.1 Copyright Grant. Subject to the terms and conditions of this +# License, each Licensor grants to you a perpetual, worldwide, +# non-exclusive, royalty-free, copyright license to reproduce, +# prepare derivative works of, publicly display, publicly perform, +# sublicense and distribute its Work and any resulting derivative +# works in any form. + +# 3. Limitations + +# 3.1 Redistribution. You may reproduce or distribute the Work only +# if (a) you do so under this License, (b) you include a complete +# copy of this License with your distribution, and (c) you retain +# without modification any copyright, patent, trademark, or +# attribution notices that are present in the Work. + +# 3.2 Derivative Works. You may specify that additional or different +# terms apply to the use, reproduction, and distribution of your +# derivative works of the Work ("Your Terms") only if (a) Your Terms +# provide that the use limitation in Section 3.3 applies to your +# derivative works, and (b) you identify the specific derivative +# works that are subject to Your Terms. Notwithstanding Your Terms, +# this License (including the redistribution requirements in Section +# 3.1) will continue to apply to the Work itself. + +# 3.3 Use Limitation. The Work and any derivative works thereof only +# may be used or intended for use non-commercially. Notwithstanding +# the foregoing, NVIDIA and its affiliates may use the Work and any +# derivative works commercially. As used herein, "non-commercially" +# means for research or evaluation purposes only. + +# 3.4 Patent Claims. If you bring or threaten to bring a patent claim +# against any Licensor (including any claim, cross-claim or +# counterclaim in a lawsuit) to enforce any patents that you allege +# are infringed by any Work, then your rights under this License from +# such Licensor (including the grant in Section 2.1) will terminate +# immediately. + +# 3.5 Trademarks. This License does not grant any rights to use any +# Licensor’s or its affiliates’ names, logos, or trademarks, except +# as necessary to reproduce the notices described in this License. + +# 3.6 Termination. If you violate any term of this License, then your +# rights under this License (including the grant in Section 2.1) will +# terminate immediately. + +# 4. Disclaimer of Warranty. + +# THE WORK IS PROVIDED "AS IS" WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WARRANTIES OR CONDITIONS OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR +# NON-INFRINGEMENT. YOU BEAR THE RISK OF UNDERTAKING ANY ACTIVITIES UNDER +# THIS LICENSE. + +# 5. Limitation of Liability. + +# EXCEPT AS PROHIBITED BY APPLICABLE LAW, IN NO EVENT AND UNDER NO LEGAL +# THEORY, WHETHER IN TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE +# SHALL ANY LICENSOR BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY DIRECT, +# INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF +# OR RELATED TO THIS LICENSE, THE USE OR INABILITY TO USE THE WORK +# (INCLUDING BUT NOT LIMITED TO LOSS OF GOODWILL, BUSINESS INTERRUPTION, +# LOST PROFITS OR DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY OTHER +# COMMERCIAL DAMAGES OR LOSSES), EVEN IF THE LICENSOR HAS BEEN ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGES. + +# ======================================================================= + +import torch +import torch.nn.functional as F +from torch import nn +from torch.autograd import Function + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', ['fused_bias_leakyrelu']) + + +class FusedBiasLeakyReLUFunctionBackward(Function): + """Calculate second order deviation. + + This function is to compute the second order deviation for the fused leaky + relu operation. + """ + + @staticmethod + def forward(ctx, grad_output, out, negative_slope, scale): + ctx.save_for_backward(out) + ctx.negative_slope = negative_slope + ctx.scale = scale + + empty = grad_output.new_empty(0) + + grad_input = ext_module.fused_bias_leakyrelu( + grad_output, + empty, + out, + act=3, + grad=1, + alpha=negative_slope, + scale=scale) + + dim = [0] + + if grad_input.ndim > 2: + dim += list(range(2, grad_input.ndim)) + + grad_bias = grad_input.sum(dim).detach() + + return grad_input, grad_bias + + @staticmethod + def backward(ctx, gradgrad_input, gradgrad_bias): + out, = ctx.saved_tensors + + # The second order deviation, in fact, contains two parts, while the + # the first part is zero. Thus, we direct consider the second part + # which is similar with the first order deviation in implementation. + gradgrad_out = ext_module.fused_bias_leakyrelu( + gradgrad_input, + gradgrad_bias.to(out.dtype), + out, + act=3, + grad=1, + alpha=ctx.negative_slope, + scale=ctx.scale) + + return gradgrad_out, None, None, None + + +class FusedBiasLeakyReLUFunction(Function): + + @staticmethod + def forward(ctx, input, bias, negative_slope, scale): + empty = input.new_empty(0) + + out = ext_module.fused_bias_leakyrelu( + input, + bias, + empty, + act=3, + grad=0, + alpha=negative_slope, + scale=scale) + ctx.save_for_backward(out) + ctx.negative_slope = negative_slope + ctx.scale = scale + + return out + + @staticmethod + def backward(ctx, grad_output): + out, = ctx.saved_tensors + + grad_input, grad_bias = FusedBiasLeakyReLUFunctionBackward.apply( + grad_output, out, ctx.negative_slope, ctx.scale) + + return grad_input, grad_bias, None, None + + +class FusedBiasLeakyReLU(nn.Module): + """Fused bias leaky ReLU. + + This function is introduced in the StyleGAN2: + http://arxiv.org/abs/1912.04958 + + The bias term comes from the convolution operation. In addition, to keep + the variance of the feature map or gradients unchanged, they also adopt a + scale similarly with Kaiming initialization. However, since the + :math:`1+{alpha}^2` : is too small, we can just ignore it. Therefore, the + final scale is just :math:`\sqrt{2}`:. Of course, you may change it with # noqa: W605, E501 + your own scale. + + TODO: Implement the CPU version. + + Args: + channel (int): The channel number of the feature map. + negative_slope (float, optional): Same as nn.LeakyRelu. + Defaults to 0.2. + scale (float, optional): A scalar to adjust the variance of the feature + map. Defaults to 2**0.5. + """ + + def __init__(self, num_channels, negative_slope=0.2, scale=2**0.5): + super(FusedBiasLeakyReLU, self).__init__() + + self.bias = nn.Parameter(torch.zeros(num_channels)) + self.negative_slope = negative_slope + self.scale = scale + + def forward(self, input): + return fused_bias_leakyrelu(input, self.bias, self.negative_slope, + self.scale) + + +def fused_bias_leakyrelu(input, bias, negative_slope=0.2, scale=2**0.5): + """Fused bias leaky ReLU function. + + This function is introduced in the StyleGAN2: + http://arxiv.org/abs/1912.04958 + + The bias term comes from the convolution operation. In addition, to keep + the variance of the feature map or gradients unchanged, they also adopt a + scale similarly with Kaiming initialization. However, since the + :math:`1+{alpha}^2` : is too small, we can just ignore it. Therefore, the + final scale is just :math:`\sqrt{2}`:. Of course, you may change it with # noqa: W605, E501 + your own scale. + + Args: + input (torch.Tensor): Input feature map. + bias (nn.Parameter): The bias from convolution operation. + negative_slope (float, optional): Same as nn.LeakyRelu. + Defaults to 0.2. + scale (float, optional): A scalar to adjust the variance of the feature + map. Defaults to 2**0.5. + + Returns: + torch.Tensor: Feature map after non-linear activation. + """ + + if not input.is_cuda: + return bias_leakyrelu_ref(input, bias, negative_slope, scale) + + return FusedBiasLeakyReLUFunction.apply(input, bias.to(input.dtype), + negative_slope, scale) + + +def bias_leakyrelu_ref(x, bias, negative_slope=0.2, scale=2**0.5): + + if bias is not None: + assert bias.ndim == 1 + assert bias.shape[0] == x.shape[1] + x = x + bias.reshape([-1 if i == 1 else 1 for i in range(x.ndim)]) + + x = F.leaky_relu(x, negative_slope) + if scale != 1: + x = x * scale + + return x diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/gather_points.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/gather_points.py new file mode 100644 index 00000000..f52f1677 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/gather_points.py @@ -0,0 +1,57 @@ +import torch +from torch.autograd import Function + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext( + '_ext', ['gather_points_forward', 'gather_points_backward']) + + +class GatherPoints(Function): + """Gather points with given index.""" + + @staticmethod + def forward(ctx, features: torch.Tensor, + indices: torch.Tensor) -> torch.Tensor: + """ + Args: + features (Tensor): (B, C, N) features to gather. + indices (Tensor): (B, M) where M is the number of points. + + Returns: + Tensor: (B, C, M) where M is the number of points. + """ + assert features.is_contiguous() + assert indices.is_contiguous() + + B, npoint = indices.size() + _, C, N = features.size() + output = torch.cuda.FloatTensor(B, C, npoint) + + ext_module.gather_points_forward( + features, indices, output, b=B, c=C, n=N, npoints=npoint) + + ctx.for_backwards = (indices, C, N) + if torch.__version__ != 'parrots': + ctx.mark_non_differentiable(indices) + return output + + @staticmethod + def backward(ctx, grad_out): + idx, C, N = ctx.for_backwards + B, npoint = idx.size() + + grad_features = torch.cuda.FloatTensor(B, C, N).zero_() + grad_out_data = grad_out.data.contiguous() + ext_module.gather_points_backward( + grad_out_data, + idx, + grad_features.data, + b=B, + c=C, + n=N, + npoints=npoint) + return grad_features, None + + +gather_points = GatherPoints.apply diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/group_points.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/group_points.py new file mode 100644 index 00000000..6c3ec9d7 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/group_points.py @@ -0,0 +1,224 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from typing import Tuple + +import torch +from torch import nn as nn +from torch.autograd import Function + +from ..utils import ext_loader +from .ball_query import ball_query +from .knn import knn + +ext_module = ext_loader.load_ext( + '_ext', ['group_points_forward', 'group_points_backward']) + + +class QueryAndGroup(nn.Module): + """Groups points with a ball query of radius. + + Args: + max_radius (float): The maximum radius of the balls. + If None is given, we will use kNN sampling instead of ball query. + sample_num (int): Maximum number of features to gather in the ball. + min_radius (float, optional): The minimum radius of the balls. + Default: 0. + use_xyz (bool, optional): Whether to use xyz. + Default: True. + return_grouped_xyz (bool, optional): Whether to return grouped xyz. + Default: False. + normalize_xyz (bool, optional): Whether to normalize xyz. + Default: False. + uniform_sample (bool, optional): Whether to sample uniformly. + Default: False + return_unique_cnt (bool, optional): Whether to return the count of + unique samples. Default: False. + return_grouped_idx (bool, optional): Whether to return grouped idx. + Default: False. + """ + + def __init__(self, + max_radius, + sample_num, + min_radius=0, + use_xyz=True, + return_grouped_xyz=False, + normalize_xyz=False, + uniform_sample=False, + return_unique_cnt=False, + return_grouped_idx=False): + super().__init__() + self.max_radius = max_radius + self.min_radius = min_radius + self.sample_num = sample_num + self.use_xyz = use_xyz + self.return_grouped_xyz = return_grouped_xyz + self.normalize_xyz = normalize_xyz + self.uniform_sample = uniform_sample + self.return_unique_cnt = return_unique_cnt + self.return_grouped_idx = return_grouped_idx + if self.return_unique_cnt: + assert self.uniform_sample, \ + 'uniform_sample should be True when ' \ + 'returning the count of unique samples' + if self.max_radius is None: + assert not self.normalize_xyz, \ + 'can not normalize grouped xyz when max_radius is None' + + def forward(self, points_xyz, center_xyz, features=None): + """ + Args: + points_xyz (Tensor): (B, N, 3) xyz coordinates of the features. + center_xyz (Tensor): (B, npoint, 3) coordinates of the centriods. + features (Tensor): (B, C, N) Descriptors of the features. + + Returns: + Tensor: (B, 3 + C, npoint, sample_num) Grouped feature. + """ + # if self.max_radius is None, we will perform kNN instead of ball query + # idx is of shape [B, npoint, sample_num] + if self.max_radius is None: + idx = knn(self.sample_num, points_xyz, center_xyz, False) + idx = idx.transpose(1, 2).contiguous() + else: + idx = ball_query(self.min_radius, self.max_radius, self.sample_num, + points_xyz, center_xyz) + + if self.uniform_sample: + unique_cnt = torch.zeros((idx.shape[0], idx.shape[1])) + for i_batch in range(idx.shape[0]): + for i_region in range(idx.shape[1]): + unique_ind = torch.unique(idx[i_batch, i_region, :]) + num_unique = unique_ind.shape[0] + unique_cnt[i_batch, i_region] = num_unique + sample_ind = torch.randint( + 0, + num_unique, (self.sample_num - num_unique, ), + dtype=torch.long) + all_ind = torch.cat((unique_ind, unique_ind[sample_ind])) + idx[i_batch, i_region, :] = all_ind + + xyz_trans = points_xyz.transpose(1, 2).contiguous() + # (B, 3, npoint, sample_num) + grouped_xyz = grouping_operation(xyz_trans, idx) + grouped_xyz_diff = grouped_xyz - \ + center_xyz.transpose(1, 2).unsqueeze(-1) # relative offsets + if self.normalize_xyz: + grouped_xyz_diff /= self.max_radius + + if features is not None: + grouped_features = grouping_operation(features, idx) + if self.use_xyz: + # (B, C + 3, npoint, sample_num) + new_features = torch.cat([grouped_xyz_diff, grouped_features], + dim=1) + else: + new_features = grouped_features + else: + assert (self.use_xyz + ), 'Cannot have not features and not use xyz as a feature!' + new_features = grouped_xyz_diff + + ret = [new_features] + if self.return_grouped_xyz: + ret.append(grouped_xyz) + if self.return_unique_cnt: + ret.append(unique_cnt) + if self.return_grouped_idx: + ret.append(idx) + if len(ret) == 1: + return ret[0] + else: + return tuple(ret) + + +class GroupAll(nn.Module): + """Group xyz with feature. + + Args: + use_xyz (bool): Whether to use xyz. + """ + + def __init__(self, use_xyz: bool = True): + super().__init__() + self.use_xyz = use_xyz + + def forward(self, + xyz: torch.Tensor, + new_xyz: torch.Tensor, + features: torch.Tensor = None): + """ + Args: + xyz (Tensor): (B, N, 3) xyz coordinates of the features. + new_xyz (Tensor): new xyz coordinates of the features. + features (Tensor): (B, C, N) features to group. + + Returns: + Tensor: (B, C + 3, 1, N) Grouped feature. + """ + grouped_xyz = xyz.transpose(1, 2).unsqueeze(2) + if features is not None: + grouped_features = features.unsqueeze(2) + if self.use_xyz: + # (B, 3 + C, 1, N) + new_features = torch.cat([grouped_xyz, grouped_features], + dim=1) + else: + new_features = grouped_features + else: + new_features = grouped_xyz + + return new_features + + +class GroupingOperation(Function): + """Group feature with given index.""" + + @staticmethod + def forward(ctx, features: torch.Tensor, + indices: torch.Tensor) -> torch.Tensor: + """ + Args: + features (Tensor): (B, C, N) tensor of features to group. + indices (Tensor): (B, npoint, nsample) the indices of + features to group with. + + Returns: + Tensor: (B, C, npoint, nsample) Grouped features. + """ + features = features.contiguous() + indices = indices.contiguous() + + B, nfeatures, nsample = indices.size() + _, C, N = features.size() + output = torch.cuda.FloatTensor(B, C, nfeatures, nsample) + + ext_module.group_points_forward(B, C, N, nfeatures, nsample, features, + indices, output) + + ctx.for_backwards = (indices, N) + return output + + @staticmethod + def backward(ctx, + grad_out: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]: + """ + Args: + grad_out (Tensor): (B, C, npoint, nsample) tensor of the gradients + of the output from forward. + + Returns: + Tensor: (B, C, N) gradient of the features. + """ + idx, N = ctx.for_backwards + + B, C, npoint, nsample = grad_out.size() + grad_features = torch.cuda.FloatTensor(B, C, N).zero_() + + grad_out_data = grad_out.data.contiguous() + ext_module.group_points_backward(B, C, N, npoint, nsample, + grad_out_data, idx, + grad_features.data) + return grad_features, None + + +grouping_operation = GroupingOperation.apply diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/info.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/info.py new file mode 100644 index 00000000..29f2e559 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/info.py @@ -0,0 +1,36 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import glob +import os + +import torch + +if torch.__version__ == 'parrots': + import parrots + + def get_compiler_version(): + return 'GCC ' + parrots.version.compiler + + def get_compiling_cuda_version(): + return parrots.version.cuda +else: + from ..utils import ext_loader + ext_module = ext_loader.load_ext( + '_ext', ['get_compiler_version', 'get_compiling_cuda_version']) + + def get_compiler_version(): + return ext_module.get_compiler_version() + + def get_compiling_cuda_version(): + return ext_module.get_compiling_cuda_version() + + +def get_onnxruntime_op_path(): + wildcard = os.path.join( + os.path.abspath(os.path.dirname(os.path.dirname(__file__))), + '_ext_ort.*.so') + + paths = glob.glob(wildcard) + if len(paths) > 0: + return paths[0] + else: + return '' diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/iou3d.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/iou3d.py new file mode 100644 index 00000000..6fc71979 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/iou3d.py @@ -0,0 +1,85 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', [ + 'iou3d_boxes_iou_bev_forward', 'iou3d_nms_forward', + 'iou3d_nms_normal_forward' +]) + + +def boxes_iou_bev(boxes_a, boxes_b): + """Calculate boxes IoU in the Bird's Eye View. + + Args: + boxes_a (torch.Tensor): Input boxes a with shape (M, 5). + boxes_b (torch.Tensor): Input boxes b with shape (N, 5). + + Returns: + ans_iou (torch.Tensor): IoU result with shape (M, N). + """ + ans_iou = boxes_a.new_zeros( + torch.Size((boxes_a.shape[0], boxes_b.shape[0]))) + + ext_module.iou3d_boxes_iou_bev_forward(boxes_a.contiguous(), + boxes_b.contiguous(), ans_iou) + + return ans_iou + + +def nms_bev(boxes, scores, thresh, pre_max_size=None, post_max_size=None): + """NMS function GPU implementation (for BEV boxes). The overlap of two + boxes for IoU calculation is defined as the exact overlapping area of the + two boxes. In this function, one can also set ``pre_max_size`` and + ``post_max_size``. + + Args: + boxes (torch.Tensor): Input boxes with the shape of [N, 5] + ([x1, y1, x2, y2, ry]). + scores (torch.Tensor): Scores of boxes with the shape of [N]. + thresh (float): Overlap threshold of NMS. + pre_max_size (int, optional): Max size of boxes before NMS. + Default: None. + post_max_size (int, optional): Max size of boxes after NMS. + Default: None. + + Returns: + torch.Tensor: Indexes after NMS. + """ + assert boxes.size(1) == 5, 'Input boxes shape should be [N, 5]' + order = scores.sort(0, descending=True)[1] + + if pre_max_size is not None: + order = order[:pre_max_size] + boxes = boxes[order].contiguous() + + keep = torch.zeros(boxes.size(0), dtype=torch.long) + num_out = ext_module.iou3d_nms_forward(boxes, keep, thresh) + keep = order[keep[:num_out].cuda(boxes.device)].contiguous() + if post_max_size is not None: + keep = keep[:post_max_size] + return keep + + +def nms_normal_bev(boxes, scores, thresh): + """Normal NMS function GPU implementation (for BEV boxes). The overlap of + two boxes for IoU calculation is defined as the exact overlapping area of + the two boxes WITH their yaw angle set to 0. + + Args: + boxes (torch.Tensor): Input boxes with shape (N, 5). + scores (torch.Tensor): Scores of predicted boxes with shape (N). + thresh (float): Overlap threshold of NMS. + + Returns: + torch.Tensor: Remaining indices with scores in descending order. + """ + assert boxes.shape[1] == 5, 'Input boxes shape should be [N, 5]' + order = scores.sort(0, descending=True)[1] + + boxes = boxes[order].contiguous() + + keep = torch.zeros(boxes.size(0), dtype=torch.long) + num_out = ext_module.iou3d_nms_normal_forward(boxes, keep, thresh) + return order[keep[:num_out].cuda(boxes.device)].contiguous() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/knn.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/knn.py new file mode 100644 index 00000000..f3357850 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/knn.py @@ -0,0 +1,77 @@ +import torch +from torch.autograd import Function + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', ['knn_forward']) + + +class KNN(Function): + r"""KNN (CUDA) based on heap data structure. + Modified from `PAConv `_. + + Find k-nearest points. + """ + + @staticmethod + def forward(ctx, + k: int, + xyz: torch.Tensor, + center_xyz: torch.Tensor = None, + transposed: bool = False) -> torch.Tensor: + """ + Args: + k (int): number of nearest neighbors. + xyz (Tensor): (B, N, 3) if transposed == False, else (B, 3, N). + xyz coordinates of the features. + center_xyz (Tensor, optional): (B, npoint, 3) if transposed == + False, else (B, 3, npoint). centers of the knn query. + Default: None. + transposed (bool, optional): whether the input tensors are + transposed. Should not explicitly use this keyword when + calling knn (=KNN.apply), just add the fourth param. + Default: False. + + Returns: + Tensor: (B, k, npoint) tensor with the indices of + the features that form k-nearest neighbours. + """ + assert (k > 0) & (k < 100), 'k should be in range(0, 100)' + + if center_xyz is None: + center_xyz = xyz + + if transposed: + xyz = xyz.transpose(2, 1).contiguous() + center_xyz = center_xyz.transpose(2, 1).contiguous() + + assert xyz.is_contiguous() # [B, N, 3] + assert center_xyz.is_contiguous() # [B, npoint, 3] + + center_xyz_device = center_xyz.get_device() + assert center_xyz_device == xyz.get_device(), \ + 'center_xyz and xyz should be put on the same device' + if torch.cuda.current_device() != center_xyz_device: + torch.cuda.set_device(center_xyz_device) + + B, npoint, _ = center_xyz.shape + N = xyz.shape[1] + + idx = center_xyz.new_zeros((B, npoint, k)).int() + dist2 = center_xyz.new_zeros((B, npoint, k)).float() + + ext_module.knn_forward( + xyz, center_xyz, idx, dist2, b=B, n=N, m=npoint, nsample=k) + # idx shape to [B, k, npoint] + idx = idx.transpose(2, 1).contiguous() + if torch.__version__ != 'parrots': + ctx.mark_non_differentiable(idx) + return idx + + @staticmethod + def backward(ctx, a=None): + return None, None, None + + +knn = KNN.apply diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/masked_conv.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/masked_conv.py new file mode 100644 index 00000000..cd514cc2 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/masked_conv.py @@ -0,0 +1,111 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import math + +import torch +import torch.nn as nn +from torch.autograd import Function +from torch.autograd.function import once_differentiable +from torch.nn.modules.utils import _pair + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext( + '_ext', ['masked_im2col_forward', 'masked_col2im_forward']) + + +class MaskedConv2dFunction(Function): + + @staticmethod + def symbolic(g, features, mask, weight, bias, padding, stride): + return g.op( + 'mmcv::MMCVMaskedConv2d', + features, + mask, + weight, + bias, + padding_i=padding, + stride_i=stride) + + @staticmethod + def forward(ctx, features, mask, weight, bias, padding=0, stride=1): + assert mask.dim() == 3 and mask.size(0) == 1 + assert features.dim() == 4 and features.size(0) == 1 + assert features.size()[2:] == mask.size()[1:] + pad_h, pad_w = _pair(padding) + stride_h, stride_w = _pair(stride) + if stride_h != 1 or stride_w != 1: + raise ValueError( + 'Stride could not only be 1 in masked_conv2d currently.') + out_channel, in_channel, kernel_h, kernel_w = weight.size() + + batch_size = features.size(0) + out_h = int( + math.floor((features.size(2) + 2 * pad_h - + (kernel_h - 1) - 1) / stride_h + 1)) + out_w = int( + math.floor((features.size(3) + 2 * pad_w - + (kernel_h - 1) - 1) / stride_w + 1)) + mask_inds = torch.nonzero(mask[0] > 0, as_tuple=False) + output = features.new_zeros(batch_size, out_channel, out_h, out_w) + if mask_inds.numel() > 0: + mask_h_idx = mask_inds[:, 0].contiguous() + mask_w_idx = mask_inds[:, 1].contiguous() + data_col = features.new_zeros(in_channel * kernel_h * kernel_w, + mask_inds.size(0)) + ext_module.masked_im2col_forward( + features, + mask_h_idx, + mask_w_idx, + data_col, + kernel_h=kernel_h, + kernel_w=kernel_w, + pad_h=pad_h, + pad_w=pad_w) + + masked_output = torch.addmm(1, bias[:, None], 1, + weight.view(out_channel, -1), data_col) + ext_module.masked_col2im_forward( + masked_output, + mask_h_idx, + mask_w_idx, + output, + height=out_h, + width=out_w, + channels=out_channel) + return output + + @staticmethod + @once_differentiable + def backward(ctx, grad_output): + return (None, ) * 5 + + +masked_conv2d = MaskedConv2dFunction.apply + + +class MaskedConv2d(nn.Conv2d): + """A MaskedConv2d which inherits the official Conv2d. + + The masked forward doesn't implement the backward function and only + supports the stride parameter to be 1 currently. + """ + + def __init__(self, + in_channels, + out_channels, + kernel_size, + stride=1, + padding=0, + dilation=1, + groups=1, + bias=True): + super(MaskedConv2d, + self).__init__(in_channels, out_channels, kernel_size, stride, + padding, dilation, groups, bias) + + def forward(self, input, mask=None): + if mask is None: # fallback to the normal Conv2d + return super(MaskedConv2d, self).forward(input) + else: + return masked_conv2d(input, mask, self.weight, self.bias, + self.padding) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/merge_cells.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/merge_cells.py new file mode 100644 index 00000000..48ca8cc0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/merge_cells.py @@ -0,0 +1,149 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from abc import abstractmethod + +import torch +import torch.nn as nn +import torch.nn.functional as F + +from ..cnn import ConvModule + + +class BaseMergeCell(nn.Module): + """The basic class for cells used in NAS-FPN and NAS-FCOS. + + BaseMergeCell takes 2 inputs. After applying convolution + on them, they are resized to the target size. Then, + they go through binary_op, which depends on the type of cell. + If with_out_conv is True, the result of output will go through + another convolution layer. + + Args: + in_channels (int): number of input channels in out_conv layer. + out_channels (int): number of output channels in out_conv layer. + with_out_conv (bool): Whether to use out_conv layer + out_conv_cfg (dict): Config dict for convolution layer, which should + contain "groups", "kernel_size", "padding", "bias" to build + out_conv layer. + out_norm_cfg (dict): Config dict for normalization layer in out_conv. + out_conv_order (tuple): The order of conv/norm/activation layers in + out_conv. + with_input1_conv (bool): Whether to use convolution on input1. + with_input2_conv (bool): Whether to use convolution on input2. + input_conv_cfg (dict): Config dict for building input1_conv layer and + input2_conv layer, which is expected to contain the type of + convolution. + Default: None, which means using conv2d. + input_norm_cfg (dict): Config dict for normalization layer in + input1_conv and input2_conv layer. Default: None. + upsample_mode (str): Interpolation method used to resize the output + of input1_conv and input2_conv to target size. Currently, we + support ['nearest', 'bilinear']. Default: 'nearest'. + """ + + def __init__(self, + fused_channels=256, + out_channels=256, + with_out_conv=True, + out_conv_cfg=dict( + groups=1, kernel_size=3, padding=1, bias=True), + out_norm_cfg=None, + out_conv_order=('act', 'conv', 'norm'), + with_input1_conv=False, + with_input2_conv=False, + input_conv_cfg=None, + input_norm_cfg=None, + upsample_mode='nearest'): + super(BaseMergeCell, self).__init__() + assert upsample_mode in ['nearest', 'bilinear'] + self.with_out_conv = with_out_conv + self.with_input1_conv = with_input1_conv + self.with_input2_conv = with_input2_conv + self.upsample_mode = upsample_mode + + if self.with_out_conv: + self.out_conv = ConvModule( + fused_channels, + out_channels, + **out_conv_cfg, + norm_cfg=out_norm_cfg, + order=out_conv_order) + + self.input1_conv = self._build_input_conv( + out_channels, input_conv_cfg, + input_norm_cfg) if with_input1_conv else nn.Sequential() + self.input2_conv = self._build_input_conv( + out_channels, input_conv_cfg, + input_norm_cfg) if with_input2_conv else nn.Sequential() + + def _build_input_conv(self, channel, conv_cfg, norm_cfg): + return ConvModule( + channel, + channel, + 3, + padding=1, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + bias=True) + + @abstractmethod + def _binary_op(self, x1, x2): + pass + + def _resize(self, x, size): + if x.shape[-2:] == size: + return x + elif x.shape[-2:] < size: + return F.interpolate(x, size=size, mode=self.upsample_mode) + else: + assert x.shape[-2] % size[-2] == 0 and x.shape[-1] % size[-1] == 0 + kernel_size = x.shape[-1] // size[-1] + x = F.max_pool2d(x, kernel_size=kernel_size, stride=kernel_size) + return x + + def forward(self, x1, x2, out_size=None): + assert x1.shape[:2] == x2.shape[:2] + assert out_size is None or len(out_size) == 2 + if out_size is None: # resize to larger one + out_size = max(x1.size()[2:], x2.size()[2:]) + + x1 = self.input1_conv(x1) + x2 = self.input2_conv(x2) + + x1 = self._resize(x1, out_size) + x2 = self._resize(x2, out_size) + + x = self._binary_op(x1, x2) + if self.with_out_conv: + x = self.out_conv(x) + return x + + +class SumCell(BaseMergeCell): + + def __init__(self, in_channels, out_channels, **kwargs): + super(SumCell, self).__init__(in_channels, out_channels, **kwargs) + + def _binary_op(self, x1, x2): + return x1 + x2 + + +class ConcatCell(BaseMergeCell): + + def __init__(self, in_channels, out_channels, **kwargs): + super(ConcatCell, self).__init__(in_channels * 2, out_channels, + **kwargs) + + def _binary_op(self, x1, x2): + ret = torch.cat([x1, x2], dim=1) + return ret + + +class GlobalPoolingCell(BaseMergeCell): + + def __init__(self, in_channels=None, out_channels=None, **kwargs): + super().__init__(in_channels, out_channels, **kwargs) + self.global_pool = nn.AdaptiveAvgPool2d((1, 1)) + + def _binary_op(self, x1, x2): + x2_att = self.global_pool(x2).sigmoid() + return x2 + x2_att * x1 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/modulated_deform_conv.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/modulated_deform_conv.py new file mode 100644 index 00000000..f9727836 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/modulated_deform_conv.py @@ -0,0 +1,282 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import math + +import torch +import torch.nn as nn +from torch.autograd import Function +from torch.autograd.function import once_differentiable +from torch.nn.modules.utils import _pair, _single + +from annotator.mmpkg.mmcv.utils import deprecated_api_warning +from ..cnn import CONV_LAYERS +from ..utils import ext_loader, print_log + +ext_module = ext_loader.load_ext( + '_ext', + ['modulated_deform_conv_forward', 'modulated_deform_conv_backward']) + + +class ModulatedDeformConv2dFunction(Function): + + @staticmethod + def symbolic(g, input, offset, mask, weight, bias, stride, padding, + dilation, groups, deform_groups): + input_tensors = [input, offset, mask, weight] + if bias is not None: + input_tensors.append(bias) + return g.op( + 'mmcv::MMCVModulatedDeformConv2d', + *input_tensors, + stride_i=stride, + padding_i=padding, + dilation_i=dilation, + groups_i=groups, + deform_groups_i=deform_groups) + + @staticmethod + def forward(ctx, + input, + offset, + mask, + weight, + bias=None, + stride=1, + padding=0, + dilation=1, + groups=1, + deform_groups=1): + if input is not None and input.dim() != 4: + raise ValueError( + f'Expected 4D tensor as input, got {input.dim()}D tensor \ + instead.') + ctx.stride = _pair(stride) + ctx.padding = _pair(padding) + ctx.dilation = _pair(dilation) + ctx.groups = groups + ctx.deform_groups = deform_groups + ctx.with_bias = bias is not None + if not ctx.with_bias: + bias = input.new_empty(0) # fake tensor + # When pytorch version >= 1.6.0, amp is adopted for fp16 mode; + # amp won't cast the type of model (float32), but "offset" is cast + # to float16 by nn.Conv2d automatically, leading to the type + # mismatch with input (when it is float32) or weight. + # The flag for whether to use fp16 or amp is the type of "offset", + # we cast weight and input to temporarily support fp16 and amp + # whatever the pytorch version is. + input = input.type_as(offset) + weight = weight.type_as(input) + ctx.save_for_backward(input, offset, mask, weight, bias) + output = input.new_empty( + ModulatedDeformConv2dFunction._output_size(ctx, input, weight)) + ctx._bufs = [input.new_empty(0), input.new_empty(0)] + ext_module.modulated_deform_conv_forward( + input, + weight, + bias, + ctx._bufs[0], + offset, + mask, + output, + ctx._bufs[1], + kernel_h=weight.size(2), + kernel_w=weight.size(3), + stride_h=ctx.stride[0], + stride_w=ctx.stride[1], + pad_h=ctx.padding[0], + pad_w=ctx.padding[1], + dilation_h=ctx.dilation[0], + dilation_w=ctx.dilation[1], + group=ctx.groups, + deformable_group=ctx.deform_groups, + with_bias=ctx.with_bias) + return output + + @staticmethod + @once_differentiable + def backward(ctx, grad_output): + input, offset, mask, weight, bias = ctx.saved_tensors + grad_input = torch.zeros_like(input) + grad_offset = torch.zeros_like(offset) + grad_mask = torch.zeros_like(mask) + grad_weight = torch.zeros_like(weight) + grad_bias = torch.zeros_like(bias) + grad_output = grad_output.contiguous() + ext_module.modulated_deform_conv_backward( + input, + weight, + bias, + ctx._bufs[0], + offset, + mask, + ctx._bufs[1], + grad_input, + grad_weight, + grad_bias, + grad_offset, + grad_mask, + grad_output, + kernel_h=weight.size(2), + kernel_w=weight.size(3), + stride_h=ctx.stride[0], + stride_w=ctx.stride[1], + pad_h=ctx.padding[0], + pad_w=ctx.padding[1], + dilation_h=ctx.dilation[0], + dilation_w=ctx.dilation[1], + group=ctx.groups, + deformable_group=ctx.deform_groups, + with_bias=ctx.with_bias) + if not ctx.with_bias: + grad_bias = None + + return (grad_input, grad_offset, grad_mask, grad_weight, grad_bias, + None, None, None, None, None) + + @staticmethod + def _output_size(ctx, input, weight): + channels = weight.size(0) + output_size = (input.size(0), channels) + for d in range(input.dim() - 2): + in_size = input.size(d + 2) + pad = ctx.padding[d] + kernel = ctx.dilation[d] * (weight.size(d + 2) - 1) + 1 + stride_ = ctx.stride[d] + output_size += ((in_size + (2 * pad) - kernel) // stride_ + 1, ) + if not all(map(lambda s: s > 0, output_size)): + raise ValueError( + 'convolution input is too small (output would be ' + + 'x'.join(map(str, output_size)) + ')') + return output_size + + +modulated_deform_conv2d = ModulatedDeformConv2dFunction.apply + + +class ModulatedDeformConv2d(nn.Module): + + @deprecated_api_warning({'deformable_groups': 'deform_groups'}, + cls_name='ModulatedDeformConv2d') + def __init__(self, + in_channels, + out_channels, + kernel_size, + stride=1, + padding=0, + dilation=1, + groups=1, + deform_groups=1, + bias=True): + super(ModulatedDeformConv2d, self).__init__() + self.in_channels = in_channels + self.out_channels = out_channels + self.kernel_size = _pair(kernel_size) + self.stride = _pair(stride) + self.padding = _pair(padding) + self.dilation = _pair(dilation) + self.groups = groups + self.deform_groups = deform_groups + # enable compatibility with nn.Conv2d + self.transposed = False + self.output_padding = _single(0) + + self.weight = nn.Parameter( + torch.Tensor(out_channels, in_channels // groups, + *self.kernel_size)) + if bias: + self.bias = nn.Parameter(torch.Tensor(out_channels)) + else: + self.register_parameter('bias', None) + self.init_weights() + + def init_weights(self): + n = self.in_channels + for k in self.kernel_size: + n *= k + stdv = 1. / math.sqrt(n) + self.weight.data.uniform_(-stdv, stdv) + if self.bias is not None: + self.bias.data.zero_() + + def forward(self, x, offset, mask): + return modulated_deform_conv2d(x, offset, mask, self.weight, self.bias, + self.stride, self.padding, + self.dilation, self.groups, + self.deform_groups) + + +@CONV_LAYERS.register_module('DCNv2') +class ModulatedDeformConv2dPack(ModulatedDeformConv2d): + """A ModulatedDeformable Conv Encapsulation that acts as normal Conv + layers. + + Args: + in_channels (int): Same as nn.Conv2d. + out_channels (int): Same as nn.Conv2d. + kernel_size (int or tuple[int]): Same as nn.Conv2d. + stride (int): Same as nn.Conv2d, while tuple is not supported. + padding (int): Same as nn.Conv2d, while tuple is not supported. + dilation (int): Same as nn.Conv2d, while tuple is not supported. + groups (int): Same as nn.Conv2d. + bias (bool or str): If specified as `auto`, it will be decided by the + norm_cfg. Bias will be set as True if norm_cfg is None, otherwise + False. + """ + + _version = 2 + + def __init__(self, *args, **kwargs): + super(ModulatedDeformConv2dPack, self).__init__(*args, **kwargs) + self.conv_offset = nn.Conv2d( + self.in_channels, + self.deform_groups * 3 * self.kernel_size[0] * self.kernel_size[1], + kernel_size=self.kernel_size, + stride=self.stride, + padding=self.padding, + dilation=self.dilation, + bias=True) + self.init_weights() + + def init_weights(self): + super(ModulatedDeformConv2dPack, self).init_weights() + if hasattr(self, 'conv_offset'): + self.conv_offset.weight.data.zero_() + self.conv_offset.bias.data.zero_() + + def forward(self, x): + out = self.conv_offset(x) + o1, o2, mask = torch.chunk(out, 3, dim=1) + offset = torch.cat((o1, o2), dim=1) + mask = torch.sigmoid(mask) + return modulated_deform_conv2d(x, offset, mask, self.weight, self.bias, + self.stride, self.padding, + self.dilation, self.groups, + self.deform_groups) + + def _load_from_state_dict(self, state_dict, prefix, local_metadata, strict, + missing_keys, unexpected_keys, error_msgs): + version = local_metadata.get('version', None) + + if version is None or version < 2: + # the key is different in early versions + # In version < 2, ModulatedDeformConvPack + # loads previous benchmark models. + if (prefix + 'conv_offset.weight' not in state_dict + and prefix[:-1] + '_offset.weight' in state_dict): + state_dict[prefix + 'conv_offset.weight'] = state_dict.pop( + prefix[:-1] + '_offset.weight') + if (prefix + 'conv_offset.bias' not in state_dict + and prefix[:-1] + '_offset.bias' in state_dict): + state_dict[prefix + + 'conv_offset.bias'] = state_dict.pop(prefix[:-1] + + '_offset.bias') + + if version is not None and version > 1: + print_log( + f'ModulatedDeformConvPack {prefix.rstrip(".")} is upgraded to ' + 'version 2.', + logger='root') + + super()._load_from_state_dict(state_dict, prefix, local_metadata, + strict, missing_keys, unexpected_keys, + error_msgs) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/multi_scale_deform_attn.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/multi_scale_deform_attn.py new file mode 100644 index 00000000..fe755eaa --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/multi_scale_deform_attn.py @@ -0,0 +1,358 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import math +import warnings + +import torch +import torch.nn as nn +import torch.nn.functional as F +from torch.autograd.function import Function, once_differentiable + +from annotator.mmpkg.mmcv import deprecated_api_warning +from annotator.mmpkg.mmcv.cnn import constant_init, xavier_init +from annotator.mmpkg.mmcv.cnn.bricks.registry import ATTENTION +from annotator.mmpkg.mmcv.runner import BaseModule +from ..utils import ext_loader + +ext_module = ext_loader.load_ext( + '_ext', ['ms_deform_attn_backward', 'ms_deform_attn_forward']) + + +class MultiScaleDeformableAttnFunction(Function): + + @staticmethod + def forward(ctx, value, value_spatial_shapes, value_level_start_index, + sampling_locations, attention_weights, im2col_step): + """GPU version of multi-scale deformable attention. + + Args: + value (Tensor): The value has shape + (bs, num_keys, mum_heads, embed_dims//num_heads) + value_spatial_shapes (Tensor): Spatial shape of + each feature map, has shape (num_levels, 2), + last dimension 2 represent (h, w) + sampling_locations (Tensor): The location of sampling points, + has shape + (bs ,num_queries, num_heads, num_levels, num_points, 2), + the last dimension 2 represent (x, y). + attention_weights (Tensor): The weight of sampling points used + when calculate the attention, has shape + (bs ,num_queries, num_heads, num_levels, num_points), + im2col_step (Tensor): The step used in image to column. + + Returns: + Tensor: has shape (bs, num_queries, embed_dims) + """ + + ctx.im2col_step = im2col_step + output = ext_module.ms_deform_attn_forward( + value, + value_spatial_shapes, + value_level_start_index, + sampling_locations, + attention_weights, + im2col_step=ctx.im2col_step) + ctx.save_for_backward(value, value_spatial_shapes, + value_level_start_index, sampling_locations, + attention_weights) + return output + + @staticmethod + @once_differentiable + def backward(ctx, grad_output): + """GPU version of backward function. + + Args: + grad_output (Tensor): Gradient + of output tensor of forward. + + Returns: + Tuple[Tensor]: Gradient + of input tensors in forward. + """ + value, value_spatial_shapes, value_level_start_index,\ + sampling_locations, attention_weights = ctx.saved_tensors + grad_value = torch.zeros_like(value) + grad_sampling_loc = torch.zeros_like(sampling_locations) + grad_attn_weight = torch.zeros_like(attention_weights) + + ext_module.ms_deform_attn_backward( + value, + value_spatial_shapes, + value_level_start_index, + sampling_locations, + attention_weights, + grad_output.contiguous(), + grad_value, + grad_sampling_loc, + grad_attn_weight, + im2col_step=ctx.im2col_step) + + return grad_value, None, None, \ + grad_sampling_loc, grad_attn_weight, None + + +def multi_scale_deformable_attn_pytorch(value, value_spatial_shapes, + sampling_locations, attention_weights): + """CPU version of multi-scale deformable attention. + + Args: + value (Tensor): The value has shape + (bs, num_keys, mum_heads, embed_dims//num_heads) + value_spatial_shapes (Tensor): Spatial shape of + each feature map, has shape (num_levels, 2), + last dimension 2 represent (h, w) + sampling_locations (Tensor): The location of sampling points, + has shape + (bs ,num_queries, num_heads, num_levels, num_points, 2), + the last dimension 2 represent (x, y). + attention_weights (Tensor): The weight of sampling points used + when calculate the attention, has shape + (bs ,num_queries, num_heads, num_levels, num_points), + + Returns: + Tensor: has shape (bs, num_queries, embed_dims) + """ + + bs, _, num_heads, embed_dims = value.shape + _, num_queries, num_heads, num_levels, num_points, _ =\ + sampling_locations.shape + value_list = value.split([H_ * W_ for H_, W_ in value_spatial_shapes], + dim=1) + sampling_grids = 2 * sampling_locations - 1 + sampling_value_list = [] + for level, (H_, W_) in enumerate(value_spatial_shapes): + # bs, H_*W_, num_heads, embed_dims -> + # bs, H_*W_, num_heads*embed_dims -> + # bs, num_heads*embed_dims, H_*W_ -> + # bs*num_heads, embed_dims, H_, W_ + value_l_ = value_list[level].flatten(2).transpose(1, 2).reshape( + bs * num_heads, embed_dims, H_, W_) + # bs, num_queries, num_heads, num_points, 2 -> + # bs, num_heads, num_queries, num_points, 2 -> + # bs*num_heads, num_queries, num_points, 2 + sampling_grid_l_ = sampling_grids[:, :, :, + level].transpose(1, 2).flatten(0, 1) + # bs*num_heads, embed_dims, num_queries, num_points + sampling_value_l_ = F.grid_sample( + value_l_, + sampling_grid_l_, + mode='bilinear', + padding_mode='zeros', + align_corners=False) + sampling_value_list.append(sampling_value_l_) + # (bs, num_queries, num_heads, num_levels, num_points) -> + # (bs, num_heads, num_queries, num_levels, num_points) -> + # (bs, num_heads, 1, num_queries, num_levels*num_points) + attention_weights = attention_weights.transpose(1, 2).reshape( + bs * num_heads, 1, num_queries, num_levels * num_points) + output = (torch.stack(sampling_value_list, dim=-2).flatten(-2) * + attention_weights).sum(-1).view(bs, num_heads * embed_dims, + num_queries) + return output.transpose(1, 2).contiguous() + + +@ATTENTION.register_module() +class MultiScaleDeformableAttention(BaseModule): + """An attention module used in Deformable-Detr. + + `Deformable DETR: Deformable Transformers for End-to-End Object Detection. + `_. + + Args: + embed_dims (int): The embedding dimension of Attention. + Default: 256. + num_heads (int): Parallel attention heads. Default: 64. + num_levels (int): The number of feature map used in + Attention. Default: 4. + num_points (int): The number of sampling points for + each query in each head. Default: 4. + im2col_step (int): The step used in image_to_column. + Default: 64. + dropout (float): A Dropout layer on `inp_identity`. + Default: 0.1. + batch_first (bool): Key, Query and Value are shape of + (batch, n, embed_dim) + or (n, batch, embed_dim). Default to False. + norm_cfg (dict): Config dict for normalization layer. + Default: None. + init_cfg (obj:`mmcv.ConfigDict`): The Config for initialization. + Default: None. + """ + + def __init__(self, + embed_dims=256, + num_heads=8, + num_levels=4, + num_points=4, + im2col_step=64, + dropout=0.1, + batch_first=False, + norm_cfg=None, + init_cfg=None): + super().__init__(init_cfg) + if embed_dims % num_heads != 0: + raise ValueError(f'embed_dims must be divisible by num_heads, ' + f'but got {embed_dims} and {num_heads}') + dim_per_head = embed_dims // num_heads + self.norm_cfg = norm_cfg + self.dropout = nn.Dropout(dropout) + self.batch_first = batch_first + + # you'd better set dim_per_head to a power of 2 + # which is more efficient in the CUDA implementation + def _is_power_of_2(n): + if (not isinstance(n, int)) or (n < 0): + raise ValueError( + 'invalid input for _is_power_of_2: {} (type: {})'.format( + n, type(n))) + return (n & (n - 1) == 0) and n != 0 + + if not _is_power_of_2(dim_per_head): + warnings.warn( + "You'd better set embed_dims in " + 'MultiScaleDeformAttention to make ' + 'the dimension of each attention head a power of 2 ' + 'which is more efficient in our CUDA implementation.') + + self.im2col_step = im2col_step + self.embed_dims = embed_dims + self.num_levels = num_levels + self.num_heads = num_heads + self.num_points = num_points + self.sampling_offsets = nn.Linear( + embed_dims, num_heads * num_levels * num_points * 2) + self.attention_weights = nn.Linear(embed_dims, + num_heads * num_levels * num_points) + self.value_proj = nn.Linear(embed_dims, embed_dims) + self.output_proj = nn.Linear(embed_dims, embed_dims) + self.init_weights() + + def init_weights(self): + """Default initialization for Parameters of Module.""" + constant_init(self.sampling_offsets, 0.) + thetas = torch.arange( + self.num_heads, + dtype=torch.float32) * (2.0 * math.pi / self.num_heads) + grid_init = torch.stack([thetas.cos(), thetas.sin()], -1) + grid_init = (grid_init / + grid_init.abs().max(-1, keepdim=True)[0]).view( + self.num_heads, 1, 1, + 2).repeat(1, self.num_levels, self.num_points, 1) + for i in range(self.num_points): + grid_init[:, :, i, :] *= i + 1 + + self.sampling_offsets.bias.data = grid_init.view(-1) + constant_init(self.attention_weights, val=0., bias=0.) + xavier_init(self.value_proj, distribution='uniform', bias=0.) + xavier_init(self.output_proj, distribution='uniform', bias=0.) + self._is_init = True + + @deprecated_api_warning({'residual': 'identity'}, + cls_name='MultiScaleDeformableAttention') + def forward(self, + query, + key=None, + value=None, + identity=None, + query_pos=None, + key_padding_mask=None, + reference_points=None, + spatial_shapes=None, + level_start_index=None, + **kwargs): + """Forward Function of MultiScaleDeformAttention. + + Args: + query (Tensor): Query of Transformer with shape + (num_query, bs, embed_dims). + key (Tensor): The key tensor with shape + `(num_key, bs, embed_dims)`. + value (Tensor): The value tensor with shape + `(num_key, bs, embed_dims)`. + identity (Tensor): The tensor used for addition, with the + same shape as `query`. Default None. If None, + `query` will be used. + query_pos (Tensor): The positional encoding for `query`. + Default: None. + key_pos (Tensor): The positional encoding for `key`. Default + None. + reference_points (Tensor): The normalized reference + points with shape (bs, num_query, num_levels, 2), + all elements is range in [0, 1], top-left (0,0), + bottom-right (1, 1), including padding area. + or (N, Length_{query}, num_levels, 4), add + additional two dimensions is (w, h) to + form reference boxes. + key_padding_mask (Tensor): ByteTensor for `query`, with + shape [bs, num_key]. + spatial_shapes (Tensor): Spatial shape of features in + different levels. With shape (num_levels, 2), + last dimension represents (h, w). + level_start_index (Tensor): The start index of each level. + A tensor has shape ``(num_levels, )`` and can be represented + as [0, h_0*w_0, h_0*w_0+h_1*w_1, ...]. + + Returns: + Tensor: forwarded results with shape [num_query, bs, embed_dims]. + """ + + if value is None: + value = query + + if identity is None: + identity = query + if query_pos is not None: + query = query + query_pos + if not self.batch_first: + # change to (bs, num_query ,embed_dims) + query = query.permute(1, 0, 2) + value = value.permute(1, 0, 2) + + bs, num_query, _ = query.shape + bs, num_value, _ = value.shape + assert (spatial_shapes[:, 0] * spatial_shapes[:, 1]).sum() == num_value + + value = self.value_proj(value) + if key_padding_mask is not None: + value = value.masked_fill(key_padding_mask[..., None], 0.0) + value = value.view(bs, num_value, self.num_heads, -1) + sampling_offsets = self.sampling_offsets(query).view( + bs, num_query, self.num_heads, self.num_levels, self.num_points, 2) + attention_weights = self.attention_weights(query).view( + bs, num_query, self.num_heads, self.num_levels * self.num_points) + attention_weights = attention_weights.softmax(-1) + + attention_weights = attention_weights.view(bs, num_query, + self.num_heads, + self.num_levels, + self.num_points) + if reference_points.shape[-1] == 2: + offset_normalizer = torch.stack( + [spatial_shapes[..., 1], spatial_shapes[..., 0]], -1) + sampling_locations = reference_points[:, :, None, :, None, :] \ + + sampling_offsets \ + / offset_normalizer[None, None, None, :, None, :] + elif reference_points.shape[-1] == 4: + sampling_locations = reference_points[:, :, None, :, None, :2] \ + + sampling_offsets / self.num_points \ + * reference_points[:, :, None, :, None, 2:] \ + * 0.5 + else: + raise ValueError( + f'Last dim of reference_points must be' + f' 2 or 4, but get {reference_points.shape[-1]} instead.') + if torch.cuda.is_available() and value.is_cuda: + output = MultiScaleDeformableAttnFunction.apply( + value, spatial_shapes, level_start_index, sampling_locations, + attention_weights, self.im2col_step) + else: + output = multi_scale_deformable_attn_pytorch( + value, spatial_shapes, sampling_locations, attention_weights) + + output = self.output_proj(output) + + if not self.batch_first: + # (num_query, bs ,embed_dims) + output = output.permute(1, 0, 2) + + return self.dropout(output) + identity diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/nms.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/nms.py new file mode 100644 index 00000000..908ac666 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/nms.py @@ -0,0 +1,417 @@ +import os + +import numpy as np +import torch + +from annotator.mmpkg.mmcv.utils import deprecated_api_warning +from ..utils import ext_loader + +ext_module = ext_loader.load_ext( + '_ext', ['nms', 'softnms', 'nms_match', 'nms_rotated']) + + +# This function is modified from: https://github.com/pytorch/vision/ +class NMSop(torch.autograd.Function): + + @staticmethod + def forward(ctx, bboxes, scores, iou_threshold, offset, score_threshold, + max_num): + is_filtering_by_score = score_threshold > 0 + if is_filtering_by_score: + valid_mask = scores > score_threshold + bboxes, scores = bboxes[valid_mask], scores[valid_mask] + valid_inds = torch.nonzero( + valid_mask, as_tuple=False).squeeze(dim=1) + + inds = ext_module.nms( + bboxes, scores, iou_threshold=float(iou_threshold), offset=offset) + + if max_num > 0: + inds = inds[:max_num] + if is_filtering_by_score: + inds = valid_inds[inds] + return inds + + @staticmethod + def symbolic(g, bboxes, scores, iou_threshold, offset, score_threshold, + max_num): + from ..onnx import is_custom_op_loaded + has_custom_op = is_custom_op_loaded() + # TensorRT nms plugin is aligned with original nms in ONNXRuntime + is_trt_backend = os.environ.get('ONNX_BACKEND') == 'MMCVTensorRT' + if has_custom_op and (not is_trt_backend): + return g.op( + 'mmcv::NonMaxSuppression', + bboxes, + scores, + iou_threshold_f=float(iou_threshold), + offset_i=int(offset)) + else: + from torch.onnx.symbolic_opset9 import select, squeeze, unsqueeze + from ..onnx.onnx_utils.symbolic_helper import _size_helper + + boxes = unsqueeze(g, bboxes, 0) + scores = unsqueeze(g, unsqueeze(g, scores, 0), 0) + + if max_num > 0: + max_num = g.op( + 'Constant', + value_t=torch.tensor(max_num, dtype=torch.long)) + else: + dim = g.op('Constant', value_t=torch.tensor(0)) + max_num = _size_helper(g, bboxes, dim) + max_output_per_class = max_num + iou_threshold = g.op( + 'Constant', + value_t=torch.tensor([iou_threshold], dtype=torch.float)) + score_threshold = g.op( + 'Constant', + value_t=torch.tensor([score_threshold], dtype=torch.float)) + nms_out = g.op('NonMaxSuppression', boxes, scores, + max_output_per_class, iou_threshold, + score_threshold) + return squeeze( + g, + select( + g, nms_out, 1, + g.op( + 'Constant', + value_t=torch.tensor([2], dtype=torch.long))), 1) + + +class SoftNMSop(torch.autograd.Function): + + @staticmethod + def forward(ctx, boxes, scores, iou_threshold, sigma, min_score, method, + offset): + dets = boxes.new_empty((boxes.size(0), 5), device='cpu') + inds = ext_module.softnms( + boxes.cpu(), + scores.cpu(), + dets.cpu(), + iou_threshold=float(iou_threshold), + sigma=float(sigma), + min_score=float(min_score), + method=int(method), + offset=int(offset)) + return dets, inds + + @staticmethod + def symbolic(g, boxes, scores, iou_threshold, sigma, min_score, method, + offset): + from packaging import version + assert version.parse(torch.__version__) >= version.parse('1.7.0') + nms_out = g.op( + 'mmcv::SoftNonMaxSuppression', + boxes, + scores, + iou_threshold_f=float(iou_threshold), + sigma_f=float(sigma), + min_score_f=float(min_score), + method_i=int(method), + offset_i=int(offset), + outputs=2) + return nms_out + + +@deprecated_api_warning({'iou_thr': 'iou_threshold'}) +def nms(boxes, scores, iou_threshold, offset=0, score_threshold=0, max_num=-1): + """Dispatch to either CPU or GPU NMS implementations. + + The input can be either torch tensor or numpy array. GPU NMS will be used + if the input is gpu tensor, otherwise CPU NMS + will be used. The returned type will always be the same as inputs. + + Arguments: + boxes (torch.Tensor or np.ndarray): boxes in shape (N, 4). + scores (torch.Tensor or np.ndarray): scores in shape (N, ). + iou_threshold (float): IoU threshold for NMS. + offset (int, 0 or 1): boxes' width or height is (x2 - x1 + offset). + score_threshold (float): score threshold for NMS. + max_num (int): maximum number of boxes after NMS. + + Returns: + tuple: kept dets(boxes and scores) and indice, which is always the \ + same data type as the input. + + Example: + >>> boxes = np.array([[49.1, 32.4, 51.0, 35.9], + >>> [49.3, 32.9, 51.0, 35.3], + >>> [49.2, 31.8, 51.0, 35.4], + >>> [35.1, 11.5, 39.1, 15.7], + >>> [35.6, 11.8, 39.3, 14.2], + >>> [35.3, 11.5, 39.9, 14.5], + >>> [35.2, 11.7, 39.7, 15.7]], dtype=np.float32) + >>> scores = np.array([0.9, 0.9, 0.5, 0.5, 0.5, 0.4, 0.3],\ + dtype=np.float32) + >>> iou_threshold = 0.6 + >>> dets, inds = nms(boxes, scores, iou_threshold) + >>> assert len(inds) == len(dets) == 3 + """ + assert isinstance(boxes, (torch.Tensor, np.ndarray)) + assert isinstance(scores, (torch.Tensor, np.ndarray)) + is_numpy = False + if isinstance(boxes, np.ndarray): + is_numpy = True + boxes = torch.from_numpy(boxes) + if isinstance(scores, np.ndarray): + scores = torch.from_numpy(scores) + assert boxes.size(1) == 4 + assert boxes.size(0) == scores.size(0) + assert offset in (0, 1) + + if torch.__version__ == 'parrots': + indata_list = [boxes, scores] + indata_dict = { + 'iou_threshold': float(iou_threshold), + 'offset': int(offset) + } + inds = ext_module.nms(*indata_list, **indata_dict) + else: + inds = NMSop.apply(boxes, scores, iou_threshold, offset, + score_threshold, max_num) + dets = torch.cat((boxes[inds], scores[inds].reshape(-1, 1)), dim=1) + if is_numpy: + dets = dets.cpu().numpy() + inds = inds.cpu().numpy() + return dets, inds + + +@deprecated_api_warning({'iou_thr': 'iou_threshold'}) +def soft_nms(boxes, + scores, + iou_threshold=0.3, + sigma=0.5, + min_score=1e-3, + method='linear', + offset=0): + """Dispatch to only CPU Soft NMS implementations. + + The input can be either a torch tensor or numpy array. + The returned type will always be the same as inputs. + + Arguments: + boxes (torch.Tensor or np.ndarray): boxes in shape (N, 4). + scores (torch.Tensor or np.ndarray): scores in shape (N, ). + iou_threshold (float): IoU threshold for NMS. + sigma (float): hyperparameter for gaussian method + min_score (float): score filter threshold + method (str): either 'linear' or 'gaussian' + offset (int, 0 or 1): boxes' width or height is (x2 - x1 + offset). + + Returns: + tuple: kept dets(boxes and scores) and indice, which is always the \ + same data type as the input. + + Example: + >>> boxes = np.array([[4., 3., 5., 3.], + >>> [4., 3., 5., 4.], + >>> [3., 1., 3., 1.], + >>> [3., 1., 3., 1.], + >>> [3., 1., 3., 1.], + >>> [3., 1., 3., 1.]], dtype=np.float32) + >>> scores = np.array([0.9, 0.9, 0.5, 0.5, 0.4, 0.0], dtype=np.float32) + >>> iou_threshold = 0.6 + >>> dets, inds = soft_nms(boxes, scores, iou_threshold, sigma=0.5) + >>> assert len(inds) == len(dets) == 5 + """ + + assert isinstance(boxes, (torch.Tensor, np.ndarray)) + assert isinstance(scores, (torch.Tensor, np.ndarray)) + is_numpy = False + if isinstance(boxes, np.ndarray): + is_numpy = True + boxes = torch.from_numpy(boxes) + if isinstance(scores, np.ndarray): + scores = torch.from_numpy(scores) + assert boxes.size(1) == 4 + assert boxes.size(0) == scores.size(0) + assert offset in (0, 1) + method_dict = {'naive': 0, 'linear': 1, 'gaussian': 2} + assert method in method_dict.keys() + + if torch.__version__ == 'parrots': + dets = boxes.new_empty((boxes.size(0), 5), device='cpu') + indata_list = [boxes.cpu(), scores.cpu(), dets.cpu()] + indata_dict = { + 'iou_threshold': float(iou_threshold), + 'sigma': float(sigma), + 'min_score': min_score, + 'method': method_dict[method], + 'offset': int(offset) + } + inds = ext_module.softnms(*indata_list, **indata_dict) + else: + dets, inds = SoftNMSop.apply(boxes.cpu(), scores.cpu(), + float(iou_threshold), float(sigma), + float(min_score), method_dict[method], + int(offset)) + + dets = dets[:inds.size(0)] + + if is_numpy: + dets = dets.cpu().numpy() + inds = inds.cpu().numpy() + return dets, inds + else: + return dets.to(device=boxes.device), inds.to(device=boxes.device) + + +def batched_nms(boxes, scores, idxs, nms_cfg, class_agnostic=False): + """Performs non-maximum suppression in a batched fashion. + + Modified from https://github.com/pytorch/vision/blob + /505cd6957711af790211896d32b40291bea1bc21/torchvision/ops/boxes.py#L39. + In order to perform NMS independently per class, we add an offset to all + the boxes. The offset is dependent only on the class idx, and is large + enough so that boxes from different classes do not overlap. + + Arguments: + boxes (torch.Tensor): boxes in shape (N, 4). + scores (torch.Tensor): scores in shape (N, ). + idxs (torch.Tensor): each index value correspond to a bbox cluster, + and NMS will not be applied between elements of different idxs, + shape (N, ). + nms_cfg (dict): specify nms type and other parameters like iou_thr. + Possible keys includes the following. + + - iou_thr (float): IoU threshold used for NMS. + - split_thr (float): threshold number of boxes. In some cases the + number of boxes is large (e.g., 200k). To avoid OOM during + training, the users could set `split_thr` to a small value. + If the number of boxes is greater than the threshold, it will + perform NMS on each group of boxes separately and sequentially. + Defaults to 10000. + class_agnostic (bool): if true, nms is class agnostic, + i.e. IoU thresholding happens over all boxes, + regardless of the predicted class. + + Returns: + tuple: kept dets and indice. + """ + nms_cfg_ = nms_cfg.copy() + class_agnostic = nms_cfg_.pop('class_agnostic', class_agnostic) + if class_agnostic: + boxes_for_nms = boxes + else: + max_coordinate = boxes.max() + offsets = idxs.to(boxes) * (max_coordinate + torch.tensor(1).to(boxes)) + boxes_for_nms = boxes + offsets[:, None] + + nms_type = nms_cfg_.pop('type', 'nms') + nms_op = eval(nms_type) + + split_thr = nms_cfg_.pop('split_thr', 10000) + # Won't split to multiple nms nodes when exporting to onnx + if boxes_for_nms.shape[0] < split_thr or torch.onnx.is_in_onnx_export(): + dets, keep = nms_op(boxes_for_nms, scores, **nms_cfg_) + boxes = boxes[keep] + # -1 indexing works abnormal in TensorRT + # This assumes `dets` has 5 dimensions where + # the last dimension is score. + # TODO: more elegant way to handle the dimension issue. + # Some type of nms would reweight the score, such as SoftNMS + scores = dets[:, 4] + else: + max_num = nms_cfg_.pop('max_num', -1) + total_mask = scores.new_zeros(scores.size(), dtype=torch.bool) + # Some type of nms would reweight the score, such as SoftNMS + scores_after_nms = scores.new_zeros(scores.size()) + for id in torch.unique(idxs): + mask = (idxs == id).nonzero(as_tuple=False).view(-1) + dets, keep = nms_op(boxes_for_nms[mask], scores[mask], **nms_cfg_) + total_mask[mask[keep]] = True + scores_after_nms[mask[keep]] = dets[:, -1] + keep = total_mask.nonzero(as_tuple=False).view(-1) + + scores, inds = scores_after_nms[keep].sort(descending=True) + keep = keep[inds] + boxes = boxes[keep] + + if max_num > 0: + keep = keep[:max_num] + boxes = boxes[:max_num] + scores = scores[:max_num] + + return torch.cat([boxes, scores[:, None]], -1), keep + + +def nms_match(dets, iou_threshold): + """Matched dets into different groups by NMS. + + NMS match is Similar to NMS but when a bbox is suppressed, nms match will + record the indice of suppressed bbox and form a group with the indice of + kept bbox. In each group, indice is sorted as score order. + + Arguments: + dets (torch.Tensor | np.ndarray): Det boxes with scores, shape (N, 5). + iou_thr (float): IoU thresh for NMS. + + Returns: + List[torch.Tensor | np.ndarray]: The outer list corresponds different + matched group, the inner Tensor corresponds the indices for a group + in score order. + """ + if dets.shape[0] == 0: + matched = [] + else: + assert dets.shape[-1] == 5, 'inputs dets.shape should be (N, 5), ' \ + f'but get {dets.shape}' + if isinstance(dets, torch.Tensor): + dets_t = dets.detach().cpu() + else: + dets_t = torch.from_numpy(dets) + indata_list = [dets_t] + indata_dict = {'iou_threshold': float(iou_threshold)} + matched = ext_module.nms_match(*indata_list, **indata_dict) + if torch.__version__ == 'parrots': + matched = matched.tolist() + + if isinstance(dets, torch.Tensor): + return [dets.new_tensor(m, dtype=torch.long) for m in matched] + else: + return [np.array(m, dtype=np.int) for m in matched] + + +def nms_rotated(dets, scores, iou_threshold, labels=None): + """Performs non-maximum suppression (NMS) on the rotated boxes according to + their intersection-over-union (IoU). + + Rotated NMS iteratively removes lower scoring rotated boxes which have an + IoU greater than iou_threshold with another (higher scoring) rotated box. + + Args: + boxes (Tensor): Rotated boxes in shape (N, 5). They are expected to \ + be in (x_ctr, y_ctr, width, height, angle_radian) format. + scores (Tensor): scores in shape (N, ). + iou_threshold (float): IoU thresh for NMS. + labels (Tensor): boxes' label in shape (N,). + + Returns: + tuple: kept dets(boxes and scores) and indice, which is always the \ + same data type as the input. + """ + if dets.shape[0] == 0: + return dets, None + multi_label = labels is not None + if multi_label: + dets_wl = torch.cat((dets, labels.unsqueeze(1)), 1) + else: + dets_wl = dets + _, order = scores.sort(0, descending=True) + dets_sorted = dets_wl.index_select(0, order) + + if torch.__version__ == 'parrots': + keep_inds = ext_module.nms_rotated( + dets_wl, + scores, + order, + dets_sorted, + iou_threshold=iou_threshold, + multi_label=multi_label) + else: + keep_inds = ext_module.nms_rotated(dets_wl, scores, order, dets_sorted, + iou_threshold, multi_label) + dets = torch.cat((dets[keep_inds], scores[keep_inds].reshape(-1, 1)), + dim=1) + return dets, keep_inds diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/pixel_group.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/pixel_group.py new file mode 100644 index 00000000..2143c75f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/pixel_group.py @@ -0,0 +1,75 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import numpy as np +import torch + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', ['pixel_group']) + + +def pixel_group(score, mask, embedding, kernel_label, kernel_contour, + kernel_region_num, distance_threshold): + """Group pixels into text instances, which is widely used text detection + methods. + + Arguments: + score (np.array or Tensor): The foreground score with size hxw. + mask (np.array or Tensor): The foreground mask with size hxw. + embedding (np.array or Tensor): The embedding with size hxwxc to + distinguish instances. + kernel_label (np.array or Tensor): The instance kernel index with + size hxw. + kernel_contour (np.array or Tensor): The kernel contour with size hxw. + kernel_region_num (int): The instance kernel region number. + distance_threshold (float): The embedding distance threshold between + kernel and pixel in one instance. + + Returns: + pixel_assignment (List[List[float]]): The instance coordinate list. + Each element consists of averaged confidence, pixel number, and + coordinates (x_i, y_i for all pixels) in order. + """ + assert isinstance(score, (torch.Tensor, np.ndarray)) + assert isinstance(mask, (torch.Tensor, np.ndarray)) + assert isinstance(embedding, (torch.Tensor, np.ndarray)) + assert isinstance(kernel_label, (torch.Tensor, np.ndarray)) + assert isinstance(kernel_contour, (torch.Tensor, np.ndarray)) + assert isinstance(kernel_region_num, int) + assert isinstance(distance_threshold, float) + + if isinstance(score, np.ndarray): + score = torch.from_numpy(score) + if isinstance(mask, np.ndarray): + mask = torch.from_numpy(mask) + if isinstance(embedding, np.ndarray): + embedding = torch.from_numpy(embedding) + if isinstance(kernel_label, np.ndarray): + kernel_label = torch.from_numpy(kernel_label) + if isinstance(kernel_contour, np.ndarray): + kernel_contour = torch.from_numpy(kernel_contour) + + if torch.__version__ == 'parrots': + label = ext_module.pixel_group( + score, + mask, + embedding, + kernel_label, + kernel_contour, + kernel_region_num=kernel_region_num, + distance_threshold=distance_threshold) + label = label.tolist() + label = label[0] + list_index = kernel_region_num + pixel_assignment = [] + for x in range(kernel_region_num): + pixel_assignment.append( + np.array( + label[list_index:list_index + int(label[x])], + dtype=np.float)) + list_index = list_index + int(label[x]) + else: + pixel_assignment = ext_module.pixel_group(score, mask, embedding, + kernel_label, kernel_contour, + kernel_region_num, + distance_threshold) + return pixel_assignment diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/point_sample.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/point_sample.py new file mode 100644 index 00000000..08b16178 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/point_sample.py @@ -0,0 +1,336 @@ +# Modified from https://github.com/facebookresearch/detectron2/tree/master/projects/PointRend # noqa + +from os import path as osp + +import torch +import torch.nn as nn +import torch.nn.functional as F +from torch.nn.modules.utils import _pair +from torch.onnx.operators import shape_as_tensor + + +def bilinear_grid_sample(im, grid, align_corners=False): + """Given an input and a flow-field grid, computes the output using input + values and pixel locations from grid. Supported only bilinear interpolation + method to sample the input pixels. + + Args: + im (torch.Tensor): Input feature map, shape (N, C, H, W) + grid (torch.Tensor): Point coordinates, shape (N, Hg, Wg, 2) + align_corners {bool}: If set to True, the extrema (-1 and 1) are + considered as referring to the center points of the input’s + corner pixels. If set to False, they are instead considered as + referring to the corner points of the input’s corner pixels, + making the sampling more resolution agnostic. + Returns: + torch.Tensor: A tensor with sampled points, shape (N, C, Hg, Wg) + """ + n, c, h, w = im.shape + gn, gh, gw, _ = grid.shape + assert n == gn + + x = grid[:, :, :, 0] + y = grid[:, :, :, 1] + + if align_corners: + x = ((x + 1) / 2) * (w - 1) + y = ((y + 1) / 2) * (h - 1) + else: + x = ((x + 1) * w - 1) / 2 + y = ((y + 1) * h - 1) / 2 + + x = x.view(n, -1) + y = y.view(n, -1) + + x0 = torch.floor(x).long() + y0 = torch.floor(y).long() + x1 = x0 + 1 + y1 = y0 + 1 + + wa = ((x1 - x) * (y1 - y)).unsqueeze(1) + wb = ((x1 - x) * (y - y0)).unsqueeze(1) + wc = ((x - x0) * (y1 - y)).unsqueeze(1) + wd = ((x - x0) * (y - y0)).unsqueeze(1) + + # Apply default for grid_sample function zero padding + im_padded = F.pad(im, pad=[1, 1, 1, 1], mode='constant', value=0) + padded_h = h + 2 + padded_w = w + 2 + # save points positions after padding + x0, x1, y0, y1 = x0 + 1, x1 + 1, y0 + 1, y1 + 1 + + # Clip coordinates to padded image size + x0 = torch.where(x0 < 0, torch.tensor(0), x0) + x0 = torch.where(x0 > padded_w - 1, torch.tensor(padded_w - 1), x0) + x1 = torch.where(x1 < 0, torch.tensor(0), x1) + x1 = torch.where(x1 > padded_w - 1, torch.tensor(padded_w - 1), x1) + y0 = torch.where(y0 < 0, torch.tensor(0), y0) + y0 = torch.where(y0 > padded_h - 1, torch.tensor(padded_h - 1), y0) + y1 = torch.where(y1 < 0, torch.tensor(0), y1) + y1 = torch.where(y1 > padded_h - 1, torch.tensor(padded_h - 1), y1) + + im_padded = im_padded.view(n, c, -1) + + x0_y0 = (x0 + y0 * padded_w).unsqueeze(1).expand(-1, c, -1) + x0_y1 = (x0 + y1 * padded_w).unsqueeze(1).expand(-1, c, -1) + x1_y0 = (x1 + y0 * padded_w).unsqueeze(1).expand(-1, c, -1) + x1_y1 = (x1 + y1 * padded_w).unsqueeze(1).expand(-1, c, -1) + + Ia = torch.gather(im_padded, 2, x0_y0) + Ib = torch.gather(im_padded, 2, x0_y1) + Ic = torch.gather(im_padded, 2, x1_y0) + Id = torch.gather(im_padded, 2, x1_y1) + + return (Ia * wa + Ib * wb + Ic * wc + Id * wd).reshape(n, c, gh, gw) + + +def is_in_onnx_export_without_custom_ops(): + from annotator.mmpkg.mmcv.ops import get_onnxruntime_op_path + ort_custom_op_path = get_onnxruntime_op_path() + return torch.onnx.is_in_onnx_export( + ) and not osp.exists(ort_custom_op_path) + + +def normalize(grid): + """Normalize input grid from [-1, 1] to [0, 1] + Args: + grid (Tensor): The grid to be normalize, range [-1, 1]. + Returns: + Tensor: Normalized grid, range [0, 1]. + """ + + return (grid + 1.0) / 2.0 + + +def denormalize(grid): + """Denormalize input grid from range [0, 1] to [-1, 1] + Args: + grid (Tensor): The grid to be denormalize, range [0, 1]. + Returns: + Tensor: Denormalized grid, range [-1, 1]. + """ + + return grid * 2.0 - 1.0 + + +def generate_grid(num_grid, size, device): + """Generate regular square grid of points in [0, 1] x [0, 1] coordinate + space. + + Args: + num_grid (int): The number of grids to sample, one for each region. + size (tuple(int, int)): The side size of the regular grid. + device (torch.device): Desired device of returned tensor. + + Returns: + (torch.Tensor): A tensor of shape (num_grid, size[0]*size[1], 2) that + contains coordinates for the regular grids. + """ + + affine_trans = torch.tensor([[[1., 0., 0.], [0., 1., 0.]]], device=device) + grid = F.affine_grid( + affine_trans, torch.Size((1, 1, *size)), align_corners=False) + grid = normalize(grid) + return grid.view(1, -1, 2).expand(num_grid, -1, -1) + + +def rel_roi_point_to_abs_img_point(rois, rel_roi_points): + """Convert roi based relative point coordinates to image based absolute + point coordinates. + + Args: + rois (Tensor): RoIs or BBoxes, shape (N, 4) or (N, 5) + rel_roi_points (Tensor): Point coordinates inside RoI, relative to + RoI, location, range (0, 1), shape (N, P, 2) + Returns: + Tensor: Image based absolute point coordinates, shape (N, P, 2) + """ + + with torch.no_grad(): + assert rel_roi_points.size(0) == rois.size(0) + assert rois.dim() == 2 + assert rel_roi_points.dim() == 3 + assert rel_roi_points.size(2) == 2 + # remove batch idx + if rois.size(1) == 5: + rois = rois[:, 1:] + abs_img_points = rel_roi_points.clone() + # To avoid an error during exporting to onnx use independent + # variables instead inplace computation + xs = abs_img_points[:, :, 0] * (rois[:, None, 2] - rois[:, None, 0]) + ys = abs_img_points[:, :, 1] * (rois[:, None, 3] - rois[:, None, 1]) + xs += rois[:, None, 0] + ys += rois[:, None, 1] + abs_img_points = torch.stack([xs, ys], dim=2) + return abs_img_points + + +def get_shape_from_feature_map(x): + """Get spatial resolution of input feature map considering exporting to + onnx mode. + + Args: + x (torch.Tensor): Input tensor, shape (N, C, H, W) + Returns: + torch.Tensor: Spatial resolution (width, height), shape (1, 1, 2) + """ + if torch.onnx.is_in_onnx_export(): + img_shape = shape_as_tensor(x)[2:].flip(0).view(1, 1, 2).to( + x.device).float() + else: + img_shape = torch.tensor(x.shape[2:]).flip(0).view(1, 1, 2).to( + x.device).float() + return img_shape + + +def abs_img_point_to_rel_img_point(abs_img_points, img, spatial_scale=1.): + """Convert image based absolute point coordinates to image based relative + coordinates for sampling. + + Args: + abs_img_points (Tensor): Image based absolute point coordinates, + shape (N, P, 2) + img (tuple/Tensor): (height, width) of image or feature map. + spatial_scale (float): Scale points by this factor. Default: 1. + + Returns: + Tensor: Image based relative point coordinates for sampling, + shape (N, P, 2) + """ + + assert (isinstance(img, tuple) and len(img) == 2) or \ + (isinstance(img, torch.Tensor) and len(img.shape) == 4) + + if isinstance(img, tuple): + h, w = img + scale = torch.tensor([w, h], + dtype=torch.float, + device=abs_img_points.device) + scale = scale.view(1, 1, 2) + else: + scale = get_shape_from_feature_map(img) + + return abs_img_points / scale * spatial_scale + + +def rel_roi_point_to_rel_img_point(rois, + rel_roi_points, + img, + spatial_scale=1.): + """Convert roi based relative point coordinates to image based absolute + point coordinates. + + Args: + rois (Tensor): RoIs or BBoxes, shape (N, 4) or (N, 5) + rel_roi_points (Tensor): Point coordinates inside RoI, relative to + RoI, location, range (0, 1), shape (N, P, 2) + img (tuple/Tensor): (height, width) of image or feature map. + spatial_scale (float): Scale points by this factor. Default: 1. + + Returns: + Tensor: Image based relative point coordinates for sampling, + shape (N, P, 2) + """ + + abs_img_point = rel_roi_point_to_abs_img_point(rois, rel_roi_points) + rel_img_point = abs_img_point_to_rel_img_point(abs_img_point, img, + spatial_scale) + + return rel_img_point + + +def point_sample(input, points, align_corners=False, **kwargs): + """A wrapper around :func:`grid_sample` to support 3D point_coords tensors + Unlike :func:`torch.nn.functional.grid_sample` it assumes point_coords to + lie inside ``[0, 1] x [0, 1]`` square. + + Args: + input (Tensor): Feature map, shape (N, C, H, W). + points (Tensor): Image based absolute point coordinates (normalized), + range [0, 1] x [0, 1], shape (N, P, 2) or (N, Hgrid, Wgrid, 2). + align_corners (bool): Whether align_corners. Default: False + + Returns: + Tensor: Features of `point` on `input`, shape (N, C, P) or + (N, C, Hgrid, Wgrid). + """ + + add_dim = False + if points.dim() == 3: + add_dim = True + points = points.unsqueeze(2) + if is_in_onnx_export_without_custom_ops(): + # If custom ops for onnx runtime not compiled use python + # implementation of grid_sample function to make onnx graph + # with supported nodes + output = bilinear_grid_sample( + input, denormalize(points), align_corners=align_corners) + else: + output = F.grid_sample( + input, denormalize(points), align_corners=align_corners, **kwargs) + if add_dim: + output = output.squeeze(3) + return output + + +class SimpleRoIAlign(nn.Module): + + def __init__(self, output_size, spatial_scale, aligned=True): + """Simple RoI align in PointRend, faster than standard RoIAlign. + + Args: + output_size (tuple[int]): h, w + spatial_scale (float): scale the input boxes by this number + aligned (bool): if False, use the legacy implementation in + MMDetection, align_corners=True will be used in F.grid_sample. + If True, align the results more perfectly. + """ + + super(SimpleRoIAlign, self).__init__() + self.output_size = _pair(output_size) + self.spatial_scale = float(spatial_scale) + # to be consistent with other RoI ops + self.use_torchvision = False + self.aligned = aligned + + def forward(self, features, rois): + num_imgs = features.size(0) + num_rois = rois.size(0) + rel_roi_points = generate_grid( + num_rois, self.output_size, device=rois.device) + + if torch.onnx.is_in_onnx_export(): + rel_img_points = rel_roi_point_to_rel_img_point( + rois, rel_roi_points, features, self.spatial_scale) + rel_img_points = rel_img_points.reshape(num_imgs, -1, + *rel_img_points.shape[1:]) + point_feats = point_sample( + features, rel_img_points, align_corners=not self.aligned) + point_feats = point_feats.transpose(1, 2) + else: + point_feats = [] + for batch_ind in range(num_imgs): + # unravel batch dim + feat = features[batch_ind].unsqueeze(0) + inds = (rois[:, 0].long() == batch_ind) + if inds.any(): + rel_img_points = rel_roi_point_to_rel_img_point( + rois[inds], rel_roi_points[inds], feat, + self.spatial_scale).unsqueeze(0) + point_feat = point_sample( + feat, rel_img_points, align_corners=not self.aligned) + point_feat = point_feat.squeeze(0).transpose(0, 1) + point_feats.append(point_feat) + + point_feats = torch.cat(point_feats, dim=0) + + channels = features.size(1) + roi_feats = point_feats.reshape(num_rois, channels, *self.output_size) + + return roi_feats + + def __repr__(self): + format_str = self.__class__.__name__ + format_str += '(output_size={}, spatial_scale={}'.format( + self.output_size, self.spatial_scale) + return format_str diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/points_in_boxes.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/points_in_boxes.py new file mode 100644 index 00000000..4003173a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/points_in_boxes.py @@ -0,0 +1,133 @@ +import torch + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', [ + 'points_in_boxes_part_forward', 'points_in_boxes_cpu_forward', + 'points_in_boxes_all_forward' +]) + + +def points_in_boxes_part(points, boxes): + """Find the box in which each point is (CUDA). + + Args: + points (torch.Tensor): [B, M, 3], [x, y, z] in LiDAR/DEPTH coordinate + boxes (torch.Tensor): [B, T, 7], + num_valid_boxes <= T, [x, y, z, x_size, y_size, z_size, rz] in + LiDAR/DEPTH coordinate, (x, y, z) is the bottom center + + Returns: + box_idxs_of_pts (torch.Tensor): (B, M), default background = -1 + """ + assert points.shape[0] == boxes.shape[0], \ + 'Points and boxes should have the same batch size, ' \ + f'but got {points.shape[0]} and {boxes.shape[0]}' + assert boxes.shape[2] == 7, \ + 'boxes dimension should be 7, ' \ + f'but got unexpected shape {boxes.shape[2]}' + assert points.shape[2] == 3, \ + 'points dimension should be 3, ' \ + f'but got unexpected shape {points.shape[2]}' + batch_size, num_points, _ = points.shape + + box_idxs_of_pts = points.new_zeros((batch_size, num_points), + dtype=torch.int).fill_(-1) + + # If manually put the tensor 'points' or 'boxes' on a device + # which is not the current device, some temporary variables + # will be created on the current device in the cuda op, + # and the output will be incorrect. + # Therefore, we force the current device to be the same + # as the device of the tensors if it was not. + # Please refer to https://github.com/open-mmlab/mmdetection3d/issues/305 + # for the incorrect output before the fix. + points_device = points.get_device() + assert points_device == boxes.get_device(), \ + 'Points and boxes should be put on the same device' + if torch.cuda.current_device() != points_device: + torch.cuda.set_device(points_device) + + ext_module.points_in_boxes_part_forward(boxes.contiguous(), + points.contiguous(), + box_idxs_of_pts) + + return box_idxs_of_pts + + +def points_in_boxes_cpu(points, boxes): + """Find all boxes in which each point is (CPU). The CPU version of + :meth:`points_in_boxes_all`. + + Args: + points (torch.Tensor): [B, M, 3], [x, y, z] in + LiDAR/DEPTH coordinate + boxes (torch.Tensor): [B, T, 7], + num_valid_boxes <= T, [x, y, z, x_size, y_size, z_size, rz], + (x, y, z) is the bottom center. + + Returns: + box_idxs_of_pts (torch.Tensor): (B, M, T), default background = 0. + """ + assert points.shape[0] == boxes.shape[0], \ + 'Points and boxes should have the same batch size, ' \ + f'but got {points.shape[0]} and {boxes.shape[0]}' + assert boxes.shape[2] == 7, \ + 'boxes dimension should be 7, ' \ + f'but got unexpected shape {boxes.shape[2]}' + assert points.shape[2] == 3, \ + 'points dimension should be 3, ' \ + f'but got unexpected shape {points.shape[2]}' + batch_size, num_points, _ = points.shape + num_boxes = boxes.shape[1] + + point_indices = points.new_zeros((batch_size, num_boxes, num_points), + dtype=torch.int) + for b in range(batch_size): + ext_module.points_in_boxes_cpu_forward(boxes[b].float().contiguous(), + points[b].float().contiguous(), + point_indices[b]) + point_indices = point_indices.transpose(1, 2) + + return point_indices + + +def points_in_boxes_all(points, boxes): + """Find all boxes in which each point is (CUDA). + + Args: + points (torch.Tensor): [B, M, 3], [x, y, z] in LiDAR/DEPTH coordinate + boxes (torch.Tensor): [B, T, 7], + num_valid_boxes <= T, [x, y, z, x_size, y_size, z_size, rz], + (x, y, z) is the bottom center. + + Returns: + box_idxs_of_pts (torch.Tensor): (B, M, T), default background = 0. + """ + assert boxes.shape[0] == points.shape[0], \ + 'Points and boxes should have the same batch size, ' \ + f'but got {boxes.shape[0]} and {boxes.shape[0]}' + assert boxes.shape[2] == 7, \ + 'boxes dimension should be 7, ' \ + f'but got unexpected shape {boxes.shape[2]}' + assert points.shape[2] == 3, \ + 'points dimension should be 3, ' \ + f'but got unexpected shape {points.shape[2]}' + batch_size, num_points, _ = points.shape + num_boxes = boxes.shape[1] + + box_idxs_of_pts = points.new_zeros((batch_size, num_points, num_boxes), + dtype=torch.int).fill_(0) + + # Same reason as line 25-32 + points_device = points.get_device() + assert points_device == boxes.get_device(), \ + 'Points and boxes should be put on the same device' + if torch.cuda.current_device() != points_device: + torch.cuda.set_device(points_device) + + ext_module.points_in_boxes_all_forward(boxes.contiguous(), + points.contiguous(), + box_idxs_of_pts) + + return box_idxs_of_pts diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/points_sampler.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/points_sampler.py new file mode 100644 index 00000000..ae1a24f9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/points_sampler.py @@ -0,0 +1,177 @@ +from typing import List + +import torch +from torch import nn as nn + +from annotator.mmpkg.mmcv.runner import force_fp32 +from .furthest_point_sample import (furthest_point_sample, + furthest_point_sample_with_dist) + + +def calc_square_dist(point_feat_a, point_feat_b, norm=True): + """Calculating square distance between a and b. + + Args: + point_feat_a (Tensor): (B, N, C) Feature vector of each point. + point_feat_b (Tensor): (B, M, C) Feature vector of each point. + norm (Bool, optional): Whether to normalize the distance. + Default: True. + + Returns: + Tensor: (B, N, M) Distance between each pair points. + """ + num_channel = point_feat_a.shape[-1] + # [bs, n, 1] + a_square = torch.sum(point_feat_a.unsqueeze(dim=2).pow(2), dim=-1) + # [bs, 1, m] + b_square = torch.sum(point_feat_b.unsqueeze(dim=1).pow(2), dim=-1) + + corr_matrix = torch.matmul(point_feat_a, point_feat_b.transpose(1, 2)) + + dist = a_square + b_square - 2 * corr_matrix + if norm: + dist = torch.sqrt(dist) / num_channel + return dist + + +def get_sampler_cls(sampler_type): + """Get the type and mode of points sampler. + + Args: + sampler_type (str): The type of points sampler. + The valid value are "D-FPS", "F-FPS", or "FS". + + Returns: + class: Points sampler type. + """ + sampler_mappings = { + 'D-FPS': DFPSSampler, + 'F-FPS': FFPSSampler, + 'FS': FSSampler, + } + try: + return sampler_mappings[sampler_type] + except KeyError: + raise KeyError( + f'Supported `sampler_type` are {sampler_mappings.keys()}, but got \ + {sampler_type}') + + +class PointsSampler(nn.Module): + """Points sampling. + + Args: + num_point (list[int]): Number of sample points. + fps_mod_list (list[str], optional): Type of FPS method, valid mod + ['F-FPS', 'D-FPS', 'FS'], Default: ['D-FPS']. + F-FPS: using feature distances for FPS. + D-FPS: using Euclidean distances of points for FPS. + FS: using F-FPS and D-FPS simultaneously. + fps_sample_range_list (list[int], optional): + Range of points to apply FPS. Default: [-1]. + """ + + def __init__(self, + num_point: List[int], + fps_mod_list: List[str] = ['D-FPS'], + fps_sample_range_list: List[int] = [-1]): + super().__init__() + # FPS would be applied to different fps_mod in the list, + # so the length of the num_point should be equal to + # fps_mod_list and fps_sample_range_list. + assert len(num_point) == len(fps_mod_list) == len( + fps_sample_range_list) + self.num_point = num_point + self.fps_sample_range_list = fps_sample_range_list + self.samplers = nn.ModuleList() + for fps_mod in fps_mod_list: + self.samplers.append(get_sampler_cls(fps_mod)()) + self.fp16_enabled = False + + @force_fp32() + def forward(self, points_xyz, features): + """ + Args: + points_xyz (Tensor): (B, N, 3) xyz coordinates of the features. + features (Tensor): (B, C, N) Descriptors of the features. + + Returns: + Tensor: (B, npoint, sample_num) Indices of sampled points. + """ + indices = [] + last_fps_end_index = 0 + + for fps_sample_range, sampler, npoint in zip( + self.fps_sample_range_list, self.samplers, self.num_point): + assert fps_sample_range < points_xyz.shape[1] + + if fps_sample_range == -1: + sample_points_xyz = points_xyz[:, last_fps_end_index:] + if features is not None: + sample_features = features[:, :, last_fps_end_index:] + else: + sample_features = None + else: + sample_points_xyz = \ + points_xyz[:, last_fps_end_index:fps_sample_range] + if features is not None: + sample_features = features[:, :, last_fps_end_index: + fps_sample_range] + else: + sample_features = None + + fps_idx = sampler(sample_points_xyz.contiguous(), sample_features, + npoint) + + indices.append(fps_idx + last_fps_end_index) + last_fps_end_index += fps_sample_range + indices = torch.cat(indices, dim=1) + + return indices + + +class DFPSSampler(nn.Module): + """Using Euclidean distances of points for FPS.""" + + def __init__(self): + super().__init__() + + def forward(self, points, features, npoint): + """Sampling points with D-FPS.""" + fps_idx = furthest_point_sample(points.contiguous(), npoint) + return fps_idx + + +class FFPSSampler(nn.Module): + """Using feature distances for FPS.""" + + def __init__(self): + super().__init__() + + def forward(self, points, features, npoint): + """Sampling points with F-FPS.""" + assert features is not None, \ + 'feature input to FFPS_Sampler should not be None' + features_for_fps = torch.cat([points, features.transpose(1, 2)], dim=2) + features_dist = calc_square_dist( + features_for_fps, features_for_fps, norm=False) + fps_idx = furthest_point_sample_with_dist(features_dist, npoint) + return fps_idx + + +class FSSampler(nn.Module): + """Using F-FPS and D-FPS simultaneously.""" + + def __init__(self): + super().__init__() + + def forward(self, points, features, npoint): + """Sampling points with FS_Sampling.""" + assert features is not None, \ + 'feature input to FS_Sampler should not be None' + ffps_sampler = FFPSSampler() + dfps_sampler = DFPSSampler() + fps_idx_ffps = ffps_sampler(points, features, npoint) + fps_idx_dfps = dfps_sampler(points, features, npoint) + fps_idx = torch.cat([fps_idx_ffps, fps_idx_dfps], dim=1) + return fps_idx diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/psa_mask.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/psa_mask.py new file mode 100644 index 00000000..cdf14e62 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/psa_mask.py @@ -0,0 +1,92 @@ +# Modified from https://github.com/hszhao/semseg/blob/master/lib/psa +from torch import nn +from torch.autograd import Function +from torch.nn.modules.utils import _pair + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', + ['psamask_forward', 'psamask_backward']) + + +class PSAMaskFunction(Function): + + @staticmethod + def symbolic(g, input, psa_type, mask_size): + return g.op( + 'mmcv::MMCVPSAMask', + input, + psa_type_i=psa_type, + mask_size_i=mask_size) + + @staticmethod + def forward(ctx, input, psa_type, mask_size): + ctx.psa_type = psa_type + ctx.mask_size = _pair(mask_size) + ctx.save_for_backward(input) + + h_mask, w_mask = ctx.mask_size + batch_size, channels, h_feature, w_feature = input.size() + assert channels == h_mask * w_mask + output = input.new_zeros( + (batch_size, h_feature * w_feature, h_feature, w_feature)) + + ext_module.psamask_forward( + input, + output, + psa_type=psa_type, + num_=batch_size, + h_feature=h_feature, + w_feature=w_feature, + h_mask=h_mask, + w_mask=w_mask, + half_h_mask=(h_mask - 1) // 2, + half_w_mask=(w_mask - 1) // 2) + return output + + @staticmethod + def backward(ctx, grad_output): + input = ctx.saved_tensors[0] + psa_type = ctx.psa_type + h_mask, w_mask = ctx.mask_size + batch_size, channels, h_feature, w_feature = input.size() + grad_input = grad_output.new_zeros( + (batch_size, channels, h_feature, w_feature)) + ext_module.psamask_backward( + grad_output, + grad_input, + psa_type=psa_type, + num_=batch_size, + h_feature=h_feature, + w_feature=w_feature, + h_mask=h_mask, + w_mask=w_mask, + half_h_mask=(h_mask - 1) // 2, + half_w_mask=(w_mask - 1) // 2) + return grad_input, None, None, None + + +psa_mask = PSAMaskFunction.apply + + +class PSAMask(nn.Module): + + def __init__(self, psa_type, mask_size=None): + super(PSAMask, self).__init__() + assert psa_type in ['collect', 'distribute'] + if psa_type == 'collect': + psa_type_enum = 0 + else: + psa_type_enum = 1 + self.psa_type_enum = psa_type_enum + self.mask_size = mask_size + self.psa_type = psa_type + + def forward(self, input): + return psa_mask(input, self.psa_type_enum, self.mask_size) + + def __repr__(self): + s = self.__class__.__name__ + s += f'(psa_type={self.psa_type}, ' + s += f'mask_size={self.mask_size})' + return s diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roi_align.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roi_align.py new file mode 100644 index 00000000..0755aefc --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roi_align.py @@ -0,0 +1,223 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.nn as nn +from torch.autograd import Function +from torch.autograd.function import once_differentiable +from torch.nn.modules.utils import _pair + +from ..utils import deprecated_api_warning, ext_loader + +ext_module = ext_loader.load_ext('_ext', + ['roi_align_forward', 'roi_align_backward']) + + +class RoIAlignFunction(Function): + + @staticmethod + def symbolic(g, input, rois, output_size, spatial_scale, sampling_ratio, + pool_mode, aligned): + from ..onnx import is_custom_op_loaded + has_custom_op = is_custom_op_loaded() + if has_custom_op: + return g.op( + 'mmcv::MMCVRoiAlign', + input, + rois, + output_height_i=output_size[0], + output_width_i=output_size[1], + spatial_scale_f=spatial_scale, + sampling_ratio_i=sampling_ratio, + mode_s=pool_mode, + aligned_i=aligned) + else: + from torch.onnx.symbolic_opset9 import sub, squeeze + from torch.onnx.symbolic_helper import _slice_helper + from torch.onnx import TensorProtoDataType + # batch_indices = rois[:, 0].long() + batch_indices = _slice_helper( + g, rois, axes=[1], starts=[0], ends=[1]) + batch_indices = squeeze(g, batch_indices, 1) + batch_indices = g.op( + 'Cast', batch_indices, to_i=TensorProtoDataType.INT64) + # rois = rois[:, 1:] + rois = _slice_helper(g, rois, axes=[1], starts=[1], ends=[5]) + if aligned: + # rois -= 0.5/spatial_scale + aligned_offset = g.op( + 'Constant', + value_t=torch.tensor([0.5 / spatial_scale], + dtype=torch.float32)) + rois = sub(g, rois, aligned_offset) + # roi align + return g.op( + 'RoiAlign', + input, + rois, + batch_indices, + output_height_i=output_size[0], + output_width_i=output_size[1], + spatial_scale_f=spatial_scale, + sampling_ratio_i=max(0, sampling_ratio), + mode_s=pool_mode) + + @staticmethod + def forward(ctx, + input, + rois, + output_size, + spatial_scale=1.0, + sampling_ratio=0, + pool_mode='avg', + aligned=True): + ctx.output_size = _pair(output_size) + ctx.spatial_scale = spatial_scale + ctx.sampling_ratio = sampling_ratio + assert pool_mode in ('max', 'avg') + ctx.pool_mode = 0 if pool_mode == 'max' else 1 + ctx.aligned = aligned + ctx.input_shape = input.size() + + assert rois.size(1) == 5, 'RoI must be (idx, x1, y1, x2, y2)!' + + output_shape = (rois.size(0), input.size(1), ctx.output_size[0], + ctx.output_size[1]) + output = input.new_zeros(output_shape) + if ctx.pool_mode == 0: + argmax_y = input.new_zeros(output_shape) + argmax_x = input.new_zeros(output_shape) + else: + argmax_y = input.new_zeros(0) + argmax_x = input.new_zeros(0) + + ext_module.roi_align_forward( + input, + rois, + output, + argmax_y, + argmax_x, + aligned_height=ctx.output_size[0], + aligned_width=ctx.output_size[1], + spatial_scale=ctx.spatial_scale, + sampling_ratio=ctx.sampling_ratio, + pool_mode=ctx.pool_mode, + aligned=ctx.aligned) + + ctx.save_for_backward(rois, argmax_y, argmax_x) + return output + + @staticmethod + @once_differentiable + def backward(ctx, grad_output): + rois, argmax_y, argmax_x = ctx.saved_tensors + grad_input = grad_output.new_zeros(ctx.input_shape) + # complex head architecture may cause grad_output uncontiguous. + grad_output = grad_output.contiguous() + ext_module.roi_align_backward( + grad_output, + rois, + argmax_y, + argmax_x, + grad_input, + aligned_height=ctx.output_size[0], + aligned_width=ctx.output_size[1], + spatial_scale=ctx.spatial_scale, + sampling_ratio=ctx.sampling_ratio, + pool_mode=ctx.pool_mode, + aligned=ctx.aligned) + return grad_input, None, None, None, None, None, None + + +roi_align = RoIAlignFunction.apply + + +class RoIAlign(nn.Module): + """RoI align pooling layer. + + Args: + output_size (tuple): h, w + spatial_scale (float): scale the input boxes by this number + sampling_ratio (int): number of inputs samples to take for each + output sample. 0 to take samples densely for current models. + pool_mode (str, 'avg' or 'max'): pooling mode in each bin. + aligned (bool): if False, use the legacy implementation in + MMDetection. If True, align the results more perfectly. + use_torchvision (bool): whether to use roi_align from torchvision. + + Note: + The implementation of RoIAlign when aligned=True is modified from + https://github.com/facebookresearch/detectron2/ + + The meaning of aligned=True: + + Given a continuous coordinate c, its two neighboring pixel + indices (in our pixel model) are computed by floor(c - 0.5) and + ceil(c - 0.5). For example, c=1.3 has pixel neighbors with discrete + indices [0] and [1] (which are sampled from the underlying signal + at continuous coordinates 0.5 and 1.5). But the original roi_align + (aligned=False) does not subtract the 0.5 when computing + neighboring pixel indices and therefore it uses pixels with a + slightly incorrect alignment (relative to our pixel model) when + performing bilinear interpolation. + + With `aligned=True`, + we first appropriately scale the ROI and then shift it by -0.5 + prior to calling roi_align. This produces the correct neighbors; + + The difference does not make a difference to the model's + performance if ROIAlign is used together with conv layers. + """ + + @deprecated_api_warning( + { + 'out_size': 'output_size', + 'sample_num': 'sampling_ratio' + }, + cls_name='RoIAlign') + def __init__(self, + output_size, + spatial_scale=1.0, + sampling_ratio=0, + pool_mode='avg', + aligned=True, + use_torchvision=False): + super(RoIAlign, self).__init__() + + self.output_size = _pair(output_size) + self.spatial_scale = float(spatial_scale) + self.sampling_ratio = int(sampling_ratio) + self.pool_mode = pool_mode + self.aligned = aligned + self.use_torchvision = use_torchvision + + def forward(self, input, rois): + """ + Args: + input: NCHW images + rois: Bx5 boxes. First column is the index into N.\ + The other 4 columns are xyxy. + """ + if self.use_torchvision: + from torchvision.ops import roi_align as tv_roi_align + if 'aligned' in tv_roi_align.__code__.co_varnames: + return tv_roi_align(input, rois, self.output_size, + self.spatial_scale, self.sampling_ratio, + self.aligned) + else: + if self.aligned: + rois -= rois.new_tensor([0.] + + [0.5 / self.spatial_scale] * 4) + return tv_roi_align(input, rois, self.output_size, + self.spatial_scale, self.sampling_ratio) + else: + return roi_align(input, rois, self.output_size, self.spatial_scale, + self.sampling_ratio, self.pool_mode, self.aligned) + + def __repr__(self): + s = self.__class__.__name__ + s += f'(output_size={self.output_size}, ' + s += f'spatial_scale={self.spatial_scale}, ' + s += f'sampling_ratio={self.sampling_ratio}, ' + s += f'pool_mode={self.pool_mode}, ' + s += f'aligned={self.aligned}, ' + s += f'use_torchvision={self.use_torchvision})' + return s diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roi_align_rotated.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roi_align_rotated.py new file mode 100644 index 00000000..0ce4961a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roi_align_rotated.py @@ -0,0 +1,177 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch.nn as nn +from torch.autograd import Function + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext( + '_ext', ['roi_align_rotated_forward', 'roi_align_rotated_backward']) + + +class RoIAlignRotatedFunction(Function): + + @staticmethod + def symbolic(g, features, rois, out_size, spatial_scale, sample_num, + aligned, clockwise): + if isinstance(out_size, int): + out_h = out_size + out_w = out_size + elif isinstance(out_size, tuple): + assert len(out_size) == 2 + assert isinstance(out_size[0], int) + assert isinstance(out_size[1], int) + out_h, out_w = out_size + else: + raise TypeError( + '"out_size" must be an integer or tuple of integers') + return g.op( + 'mmcv::MMCVRoIAlignRotated', + features, + rois, + output_height_i=out_h, + output_width_i=out_h, + spatial_scale_f=spatial_scale, + sampling_ratio_i=sample_num, + aligned_i=aligned, + clockwise_i=clockwise) + + @staticmethod + def forward(ctx, + features, + rois, + out_size, + spatial_scale, + sample_num=0, + aligned=True, + clockwise=False): + if isinstance(out_size, int): + out_h = out_size + out_w = out_size + elif isinstance(out_size, tuple): + assert len(out_size) == 2 + assert isinstance(out_size[0], int) + assert isinstance(out_size[1], int) + out_h, out_w = out_size + else: + raise TypeError( + '"out_size" must be an integer or tuple of integers') + ctx.spatial_scale = spatial_scale + ctx.sample_num = sample_num + ctx.aligned = aligned + ctx.clockwise = clockwise + ctx.save_for_backward(rois) + ctx.feature_size = features.size() + + batch_size, num_channels, data_height, data_width = features.size() + num_rois = rois.size(0) + + output = features.new_zeros(num_rois, num_channels, out_h, out_w) + ext_module.roi_align_rotated_forward( + features, + rois, + output, + pooled_height=out_h, + pooled_width=out_w, + spatial_scale=spatial_scale, + sample_num=sample_num, + aligned=aligned, + clockwise=clockwise) + return output + + @staticmethod + def backward(ctx, grad_output): + feature_size = ctx.feature_size + spatial_scale = ctx.spatial_scale + aligned = ctx.aligned + clockwise = ctx.clockwise + sample_num = ctx.sample_num + rois = ctx.saved_tensors[0] + assert feature_size is not None + batch_size, num_channels, data_height, data_width = feature_size + + out_w = grad_output.size(3) + out_h = grad_output.size(2) + + grad_input = grad_rois = None + + if ctx.needs_input_grad[0]: + grad_input = rois.new_zeros(batch_size, num_channels, data_height, + data_width) + ext_module.roi_align_rotated_backward( + grad_output.contiguous(), + rois, + grad_input, + pooled_height=out_h, + pooled_width=out_w, + spatial_scale=spatial_scale, + sample_num=sample_num, + aligned=aligned, + clockwise=clockwise) + return grad_input, grad_rois, None, None, None, None, None + + +roi_align_rotated = RoIAlignRotatedFunction.apply + + +class RoIAlignRotated(nn.Module): + """RoI align pooling layer for rotated proposals. + + It accepts a feature map of shape (N, C, H, W) and rois with shape + (n, 6) with each roi decoded as (batch_index, center_x, center_y, + w, h, angle). The angle is in radian. + + Args: + out_size (tuple): h, w + spatial_scale (float): scale the input boxes by this number + sample_num (int): number of inputs samples to take for each + output sample. 0 to take samples densely for current models. + aligned (bool): if False, use the legacy implementation in + MMDetection. If True, align the results more perfectly. + Default: True. + clockwise (bool): If True, the angle in each proposal follows a + clockwise fashion in image space, otherwise, the angle is + counterclockwise. Default: False. + + Note: + The implementation of RoIAlign when aligned=True is modified from + https://github.com/facebookresearch/detectron2/ + + The meaning of aligned=True: + + Given a continuous coordinate c, its two neighboring pixel + indices (in our pixel model) are computed by floor(c - 0.5) and + ceil(c - 0.5). For example, c=1.3 has pixel neighbors with discrete + indices [0] and [1] (which are sampled from the underlying signal + at continuous coordinates 0.5 and 1.5). But the original roi_align + (aligned=False) does not subtract the 0.5 when computing + neighboring pixel indices and therefore it uses pixels with a + slightly incorrect alignment (relative to our pixel model) when + performing bilinear interpolation. + + With `aligned=True`, + we first appropriately scale the ROI and then shift it by -0.5 + prior to calling roi_align. This produces the correct neighbors; + + The difference does not make a difference to the model's + performance if ROIAlign is used together with conv layers. + """ + + def __init__(self, + out_size, + spatial_scale, + sample_num=0, + aligned=True, + clockwise=False): + super(RoIAlignRotated, self).__init__() + + self.out_size = out_size + self.spatial_scale = float(spatial_scale) + self.sample_num = int(sample_num) + self.aligned = aligned + self.clockwise = clockwise + + def forward(self, features, rois): + return RoIAlignRotatedFunction.apply(features, rois, self.out_size, + self.spatial_scale, + self.sample_num, self.aligned, + self.clockwise) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roi_pool.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roi_pool.py new file mode 100644 index 00000000..d339d8f2 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roi_pool.py @@ -0,0 +1,86 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.nn as nn +from torch.autograd import Function +from torch.autograd.function import once_differentiable +from torch.nn.modules.utils import _pair + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', + ['roi_pool_forward', 'roi_pool_backward']) + + +class RoIPoolFunction(Function): + + @staticmethod + def symbolic(g, input, rois, output_size, spatial_scale): + return g.op( + 'MaxRoiPool', + input, + rois, + pooled_shape_i=output_size, + spatial_scale_f=spatial_scale) + + @staticmethod + def forward(ctx, input, rois, output_size, spatial_scale=1.0): + ctx.output_size = _pair(output_size) + ctx.spatial_scale = spatial_scale + ctx.input_shape = input.size() + + assert rois.size(1) == 5, 'RoI must be (idx, x1, y1, x2, y2)!' + + output_shape = (rois.size(0), input.size(1), ctx.output_size[0], + ctx.output_size[1]) + output = input.new_zeros(output_shape) + argmax = input.new_zeros(output_shape, dtype=torch.int) + + ext_module.roi_pool_forward( + input, + rois, + output, + argmax, + pooled_height=ctx.output_size[0], + pooled_width=ctx.output_size[1], + spatial_scale=ctx.spatial_scale) + + ctx.save_for_backward(rois, argmax) + return output + + @staticmethod + @once_differentiable + def backward(ctx, grad_output): + rois, argmax = ctx.saved_tensors + grad_input = grad_output.new_zeros(ctx.input_shape) + + ext_module.roi_pool_backward( + grad_output, + rois, + argmax, + grad_input, + pooled_height=ctx.output_size[0], + pooled_width=ctx.output_size[1], + spatial_scale=ctx.spatial_scale) + + return grad_input, None, None, None + + +roi_pool = RoIPoolFunction.apply + + +class RoIPool(nn.Module): + + def __init__(self, output_size, spatial_scale=1.0): + super(RoIPool, self).__init__() + + self.output_size = _pair(output_size) + self.spatial_scale = float(spatial_scale) + + def forward(self, input, rois): + return roi_pool(input, rois, self.output_size, self.spatial_scale) + + def __repr__(self): + s = self.__class__.__name__ + s += f'(output_size={self.output_size}, ' + s += f'spatial_scale={self.spatial_scale})' + return s diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roiaware_pool3d.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roiaware_pool3d.py new file mode 100644 index 00000000..8191920c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roiaware_pool3d.py @@ -0,0 +1,114 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +from torch import nn as nn +from torch.autograd import Function + +import annotator.mmpkg.mmcv as mmcv +from ..utils import ext_loader + +ext_module = ext_loader.load_ext( + '_ext', ['roiaware_pool3d_forward', 'roiaware_pool3d_backward']) + + +class RoIAwarePool3d(nn.Module): + """Encode the geometry-specific features of each 3D proposal. + + Please refer to `PartA2 `_ for more + details. + + Args: + out_size (int or tuple): The size of output features. n or + [n1, n2, n3]. + max_pts_per_voxel (int, optional): The maximum number of points per + voxel. Default: 128. + mode (str, optional): Pooling method of RoIAware, 'max' or 'avg'. + Default: 'max'. + """ + + def __init__(self, out_size, max_pts_per_voxel=128, mode='max'): + super().__init__() + + self.out_size = out_size + self.max_pts_per_voxel = max_pts_per_voxel + assert mode in ['max', 'avg'] + pool_mapping = {'max': 0, 'avg': 1} + self.mode = pool_mapping[mode] + + def forward(self, rois, pts, pts_feature): + """ + Args: + rois (torch.Tensor): [N, 7], in LiDAR coordinate, + (x, y, z) is the bottom center of rois. + pts (torch.Tensor): [npoints, 3], coordinates of input points. + pts_feature (torch.Tensor): [npoints, C], features of input points. + + Returns: + pooled_features (torch.Tensor): [N, out_x, out_y, out_z, C] + """ + + return RoIAwarePool3dFunction.apply(rois, pts, pts_feature, + self.out_size, + self.max_pts_per_voxel, self.mode) + + +class RoIAwarePool3dFunction(Function): + + @staticmethod + def forward(ctx, rois, pts, pts_feature, out_size, max_pts_per_voxel, + mode): + """ + Args: + rois (torch.Tensor): [N, 7], in LiDAR coordinate, + (x, y, z) is the bottom center of rois. + pts (torch.Tensor): [npoints, 3], coordinates of input points. + pts_feature (torch.Tensor): [npoints, C], features of input points. + out_size (int or tuple): The size of output features. n or + [n1, n2, n3]. + max_pts_per_voxel (int): The maximum number of points per voxel. + Default: 128. + mode (int): Pooling method of RoIAware, 0 (max pool) or 1 (average + pool). + + Returns: + pooled_features (torch.Tensor): [N, out_x, out_y, out_z, C], output + pooled features. + """ + + if isinstance(out_size, int): + out_x = out_y = out_z = out_size + else: + assert len(out_size) == 3 + assert mmcv.is_tuple_of(out_size, int) + out_x, out_y, out_z = out_size + + num_rois = rois.shape[0] + num_channels = pts_feature.shape[-1] + num_pts = pts.shape[0] + + pooled_features = pts_feature.new_zeros( + (num_rois, out_x, out_y, out_z, num_channels)) + argmax = pts_feature.new_zeros( + (num_rois, out_x, out_y, out_z, num_channels), dtype=torch.int) + pts_idx_of_voxels = pts_feature.new_zeros( + (num_rois, out_x, out_y, out_z, max_pts_per_voxel), + dtype=torch.int) + + ext_module.roiaware_pool3d_forward(rois, pts, pts_feature, argmax, + pts_idx_of_voxels, pooled_features, + mode) + + ctx.roiaware_pool3d_for_backward = (pts_idx_of_voxels, argmax, mode, + num_pts, num_channels) + return pooled_features + + @staticmethod + def backward(ctx, grad_out): + ret = ctx.roiaware_pool3d_for_backward + pts_idx_of_voxels, argmax, mode, num_pts, num_channels = ret + + grad_in = grad_out.new_zeros((num_pts, num_channels)) + ext_module.roiaware_pool3d_backward(pts_idx_of_voxels, argmax, + grad_out.contiguous(), grad_in, + mode) + + return None, None, grad_in, None, None, None diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roipoint_pool3d.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roipoint_pool3d.py new file mode 100644 index 00000000..0a21412c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/roipoint_pool3d.py @@ -0,0 +1,77 @@ +from torch import nn as nn +from torch.autograd import Function + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', ['roipoint_pool3d_forward']) + + +class RoIPointPool3d(nn.Module): + """Encode the geometry-specific features of each 3D proposal. + + Please refer to `Paper of PartA2 `_ + for more details. + + Args: + num_sampled_points (int, optional): Number of samples in each roi. + Default: 512. + """ + + def __init__(self, num_sampled_points=512): + super().__init__() + self.num_sampled_points = num_sampled_points + + def forward(self, points, point_features, boxes3d): + """ + Args: + points (torch.Tensor): Input points whose shape is (B, N, C). + point_features (torch.Tensor): Features of input points whose shape + is (B, N, C). + boxes3d (B, M, 7), Input bounding boxes whose shape is (B, M, 7). + + Returns: + pooled_features (torch.Tensor): The output pooled features whose + shape is (B, M, 512, 3 + C). + pooled_empty_flag (torch.Tensor): Empty flag whose shape is (B, M). + """ + return RoIPointPool3dFunction.apply(points, point_features, boxes3d, + self.num_sampled_points) + + +class RoIPointPool3dFunction(Function): + + @staticmethod + def forward(ctx, points, point_features, boxes3d, num_sampled_points=512): + """ + Args: + points (torch.Tensor): Input points whose shape is (B, N, C). + point_features (torch.Tensor): Features of input points whose shape + is (B, N, C). + boxes3d (B, M, 7), Input bounding boxes whose shape is (B, M, 7). + num_sampled_points (int, optional): The num of sampled points. + Default: 512. + + Returns: + pooled_features (torch.Tensor): The output pooled features whose + shape is (B, M, 512, 3 + C). + pooled_empty_flag (torch.Tensor): Empty flag whose shape is (B, M). + """ + assert len(points.shape) == 3 and points.shape[2] == 3 + batch_size, boxes_num, feature_len = points.shape[0], boxes3d.shape[ + 1], point_features.shape[2] + pooled_boxes3d = boxes3d.view(batch_size, -1, 7) + pooled_features = point_features.new_zeros( + (batch_size, boxes_num, num_sampled_points, 3 + feature_len)) + pooled_empty_flag = point_features.new_zeros( + (batch_size, boxes_num)).int() + + ext_module.roipoint_pool3d_forward(points.contiguous(), + pooled_boxes3d.contiguous(), + point_features.contiguous(), + pooled_features, pooled_empty_flag) + + return pooled_features, pooled_empty_flag + + @staticmethod + def backward(ctx, grad_out): + raise NotImplementedError diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/saconv.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/saconv.py new file mode 100644 index 00000000..9d7be88c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/saconv.py @@ -0,0 +1,145 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.nn as nn +import torch.nn.functional as F + +from annotator.mmpkg.mmcv.cnn import CONV_LAYERS, ConvAWS2d, constant_init +from annotator.mmpkg.mmcv.ops.deform_conv import deform_conv2d +from annotator.mmpkg.mmcv.utils import TORCH_VERSION, digit_version + + +@CONV_LAYERS.register_module(name='SAC') +class SAConv2d(ConvAWS2d): + """SAC (Switchable Atrous Convolution) + + This is an implementation of SAC in DetectoRS + (https://arxiv.org/pdf/2006.02334.pdf). + + Args: + in_channels (int): Number of channels in the input image + out_channels (int): Number of channels produced by the convolution + kernel_size (int or tuple): Size of the convolving kernel + stride (int or tuple, optional): Stride of the convolution. Default: 1 + padding (int or tuple, optional): Zero-padding added to both sides of + the input. Default: 0 + padding_mode (string, optional): ``'zeros'``, ``'reflect'``, + ``'replicate'`` or ``'circular'``. Default: ``'zeros'`` + dilation (int or tuple, optional): Spacing between kernel elements. + Default: 1 + groups (int, optional): Number of blocked connections from input + channels to output channels. Default: 1 + bias (bool, optional): If ``True``, adds a learnable bias to the + output. Default: ``True`` + use_deform: If ``True``, replace convolution with deformable + convolution. Default: ``False``. + """ + + def __init__(self, + in_channels, + out_channels, + kernel_size, + stride=1, + padding=0, + dilation=1, + groups=1, + bias=True, + use_deform=False): + super().__init__( + in_channels, + out_channels, + kernel_size, + stride=stride, + padding=padding, + dilation=dilation, + groups=groups, + bias=bias) + self.use_deform = use_deform + self.switch = nn.Conv2d( + self.in_channels, 1, kernel_size=1, stride=stride, bias=True) + self.weight_diff = nn.Parameter(torch.Tensor(self.weight.size())) + self.pre_context = nn.Conv2d( + self.in_channels, self.in_channels, kernel_size=1, bias=True) + self.post_context = nn.Conv2d( + self.out_channels, self.out_channels, kernel_size=1, bias=True) + if self.use_deform: + self.offset_s = nn.Conv2d( + self.in_channels, + 18, + kernel_size=3, + padding=1, + stride=stride, + bias=True) + self.offset_l = nn.Conv2d( + self.in_channels, + 18, + kernel_size=3, + padding=1, + stride=stride, + bias=True) + self.init_weights() + + def init_weights(self): + constant_init(self.switch, 0, bias=1) + self.weight_diff.data.zero_() + constant_init(self.pre_context, 0) + constant_init(self.post_context, 0) + if self.use_deform: + constant_init(self.offset_s, 0) + constant_init(self.offset_l, 0) + + def forward(self, x): + # pre-context + avg_x = F.adaptive_avg_pool2d(x, output_size=1) + avg_x = self.pre_context(avg_x) + avg_x = avg_x.expand_as(x) + x = x + avg_x + # switch + avg_x = F.pad(x, pad=(2, 2, 2, 2), mode='reflect') + avg_x = F.avg_pool2d(avg_x, kernel_size=5, stride=1, padding=0) + switch = self.switch(avg_x) + # sac + weight = self._get_weight(self.weight) + zero_bias = torch.zeros( + self.out_channels, device=weight.device, dtype=weight.dtype) + + if self.use_deform: + offset = self.offset_s(avg_x) + out_s = deform_conv2d(x, offset, weight, self.stride, self.padding, + self.dilation, self.groups, 1) + else: + if (TORCH_VERSION == 'parrots' + or digit_version(TORCH_VERSION) < digit_version('1.5.0')): + out_s = super().conv2d_forward(x, weight) + elif digit_version(TORCH_VERSION) >= digit_version('1.8.0'): + # bias is a required argument of _conv_forward in torch 1.8.0 + out_s = super()._conv_forward(x, weight, zero_bias) + else: + out_s = super()._conv_forward(x, weight) + ori_p = self.padding + ori_d = self.dilation + self.padding = tuple(3 * p for p in self.padding) + self.dilation = tuple(3 * d for d in self.dilation) + weight = weight + self.weight_diff + if self.use_deform: + offset = self.offset_l(avg_x) + out_l = deform_conv2d(x, offset, weight, self.stride, self.padding, + self.dilation, self.groups, 1) + else: + if (TORCH_VERSION == 'parrots' + or digit_version(TORCH_VERSION) < digit_version('1.5.0')): + out_l = super().conv2d_forward(x, weight) + elif digit_version(TORCH_VERSION) >= digit_version('1.8.0'): + # bias is a required argument of _conv_forward in torch 1.8.0 + out_l = super()._conv_forward(x, weight, zero_bias) + else: + out_l = super()._conv_forward(x, weight) + + out = switch * out_s + (1 - switch) * out_l + self.padding = ori_p + self.dilation = ori_d + # post-context + avg_x = F.adaptive_avg_pool2d(out, output_size=1) + avg_x = self.post_context(avg_x) + avg_x = avg_x.expand_as(out) + out = out + avg_x + return out diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/scatter_points.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/scatter_points.py new file mode 100644 index 00000000..2b8aa416 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/scatter_points.py @@ -0,0 +1,135 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +from torch import nn +from torch.autograd import Function + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext( + '_ext', + ['dynamic_point_to_voxel_forward', 'dynamic_point_to_voxel_backward']) + + +class _DynamicScatter(Function): + + @staticmethod + def forward(ctx, feats, coors, reduce_type='max'): + """convert kitti points(N, >=3) to voxels. + + Args: + feats (torch.Tensor): [N, C]. Points features to be reduced + into voxels. + coors (torch.Tensor): [N, ndim]. Corresponding voxel coordinates + (specifically multi-dim voxel index) of each points. + reduce_type (str, optional): Reduce op. support 'max', 'sum' and + 'mean'. Default: 'max'. + + Returns: + voxel_feats (torch.Tensor): [M, C]. Reduced features, input + features that shares the same voxel coordinates are reduced to + one row. + voxel_coors (torch.Tensor): [M, ndim]. Voxel coordinates. + """ + results = ext_module.dynamic_point_to_voxel_forward( + feats, coors, reduce_type) + (voxel_feats, voxel_coors, point2voxel_map, + voxel_points_count) = results + ctx.reduce_type = reduce_type + ctx.save_for_backward(feats, voxel_feats, point2voxel_map, + voxel_points_count) + ctx.mark_non_differentiable(voxel_coors) + return voxel_feats, voxel_coors + + @staticmethod + def backward(ctx, grad_voxel_feats, grad_voxel_coors=None): + (feats, voxel_feats, point2voxel_map, + voxel_points_count) = ctx.saved_tensors + grad_feats = torch.zeros_like(feats) + # TODO: whether to use index put or use cuda_backward + # To use index put, need point to voxel index + ext_module.dynamic_point_to_voxel_backward( + grad_feats, grad_voxel_feats.contiguous(), feats, voxel_feats, + point2voxel_map, voxel_points_count, ctx.reduce_type) + return grad_feats, None, None + + +dynamic_scatter = _DynamicScatter.apply + + +class DynamicScatter(nn.Module): + """Scatters points into voxels, used in the voxel encoder with dynamic + voxelization. + + Note: + The CPU and GPU implementation get the same output, but have numerical + difference after summation and division (e.g., 5e-7). + + Args: + voxel_size (list): list [x, y, z] size of three dimension. + point_cloud_range (list): The coordinate range of points, [x_min, + y_min, z_min, x_max, y_max, z_max]. + average_points (bool): whether to use avg pooling to scatter points + into voxel. + """ + + def __init__(self, voxel_size, point_cloud_range, average_points: bool): + super().__init__() + + self.voxel_size = voxel_size + self.point_cloud_range = point_cloud_range + self.average_points = average_points + + def forward_single(self, points, coors): + """Scatters points into voxels. + + Args: + points (torch.Tensor): Points to be reduced into voxels. + coors (torch.Tensor): Corresponding voxel coordinates (specifically + multi-dim voxel index) of each points. + + Returns: + voxel_feats (torch.Tensor): Reduced features, input features that + shares the same voxel coordinates are reduced to one row. + voxel_coors (torch.Tensor): Voxel coordinates. + """ + reduce = 'mean' if self.average_points else 'max' + return dynamic_scatter(points.contiguous(), coors.contiguous(), reduce) + + def forward(self, points, coors): + """Scatters points/features into voxels. + + Args: + points (torch.Tensor): Points to be reduced into voxels. + coors (torch.Tensor): Corresponding voxel coordinates (specifically + multi-dim voxel index) of each points. + + Returns: + voxel_feats (torch.Tensor): Reduced features, input features that + shares the same voxel coordinates are reduced to one row. + voxel_coors (torch.Tensor): Voxel coordinates. + """ + if coors.size(-1) == 3: + return self.forward_single(points, coors) + else: + batch_size = coors[-1, 0] + 1 + voxels, voxel_coors = [], [] + for i in range(batch_size): + inds = torch.where(coors[:, 0] == i) + voxel, voxel_coor = self.forward_single( + points[inds], coors[inds][:, 1:]) + coor_pad = nn.functional.pad( + voxel_coor, (1, 0), mode='constant', value=i) + voxel_coors.append(coor_pad) + voxels.append(voxel) + features = torch.cat(voxels, dim=0) + feature_coors = torch.cat(voxel_coors, dim=0) + + return features, feature_coors + + def __repr__(self): + s = self.__class__.__name__ + '(' + s += 'voxel_size=' + str(self.voxel_size) + s += ', point_cloud_range=' + str(self.point_cloud_range) + s += ', average_points=' + str(self.average_points) + s += ')' + return s diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/sync_bn.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/sync_bn.py new file mode 100644 index 00000000..46db9200 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/sync_bn.py @@ -0,0 +1,279 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.distributed as dist +import torch.nn.functional as F +from torch.autograd import Function +from torch.autograd.function import once_differentiable +from torch.nn.modules.module import Module +from torch.nn.parameter import Parameter + +from annotator.mmpkg.mmcv.cnn import NORM_LAYERS +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', [ + 'sync_bn_forward_mean', 'sync_bn_forward_var', 'sync_bn_forward_output', + 'sync_bn_backward_param', 'sync_bn_backward_data' +]) + + +class SyncBatchNormFunction(Function): + + @staticmethod + def symbolic(g, input, running_mean, running_var, weight, bias, momentum, + eps, group, group_size, stats_mode): + return g.op( + 'mmcv::MMCVSyncBatchNorm', + input, + running_mean, + running_var, + weight, + bias, + momentum_f=momentum, + eps_f=eps, + group_i=group, + group_size_i=group_size, + stats_mode=stats_mode) + + @staticmethod + def forward(self, input, running_mean, running_var, weight, bias, momentum, + eps, group, group_size, stats_mode): + self.momentum = momentum + self.eps = eps + self.group = group + self.group_size = group_size + self.stats_mode = stats_mode + + assert isinstance( + input, (torch.HalfTensor, torch.FloatTensor, + torch.cuda.HalfTensor, torch.cuda.FloatTensor)), \ + f'only support Half or Float Tensor, but {input.type()}' + output = torch.zeros_like(input) + input3d = input.flatten(start_dim=2) + output3d = output.view_as(input3d) + num_channels = input3d.size(1) + + # ensure mean/var/norm/std are initialized as zeros + # ``torch.empty()`` does not guarantee that + mean = torch.zeros( + num_channels, dtype=torch.float, device=input3d.device) + var = torch.zeros( + num_channels, dtype=torch.float, device=input3d.device) + norm = torch.zeros_like( + input3d, dtype=torch.float, device=input3d.device) + std = torch.zeros( + num_channels, dtype=torch.float, device=input3d.device) + + batch_size = input3d.size(0) + if batch_size > 0: + ext_module.sync_bn_forward_mean(input3d, mean) + batch_flag = torch.ones([1], device=mean.device, dtype=mean.dtype) + else: + # skip updating mean and leave it as zeros when the input is empty + batch_flag = torch.zeros([1], device=mean.device, dtype=mean.dtype) + + # synchronize mean and the batch flag + vec = torch.cat([mean, batch_flag]) + if self.stats_mode == 'N': + vec *= batch_size + if self.group_size > 1: + dist.all_reduce(vec, group=self.group) + total_batch = vec[-1].detach() + mean = vec[:num_channels] + + if self.stats_mode == 'default': + mean = mean / self.group_size + elif self.stats_mode == 'N': + mean = mean / total_batch.clamp(min=1) + else: + raise NotImplementedError + + # leave var as zeros when the input is empty + if batch_size > 0: + ext_module.sync_bn_forward_var(input3d, mean, var) + + if self.stats_mode == 'N': + var *= batch_size + if self.group_size > 1: + dist.all_reduce(var, group=self.group) + + if self.stats_mode == 'default': + var /= self.group_size + elif self.stats_mode == 'N': + var /= total_batch.clamp(min=1) + else: + raise NotImplementedError + + # if the total batch size over all the ranks is zero, + # we should not update the statistics in the current batch + update_flag = total_batch.clamp(max=1) + momentum = update_flag * self.momentum + ext_module.sync_bn_forward_output( + input3d, + mean, + var, + weight, + bias, + running_mean, + running_var, + norm, + std, + output3d, + eps=self.eps, + momentum=momentum, + group_size=self.group_size) + self.save_for_backward(norm, std, weight) + return output + + @staticmethod + @once_differentiable + def backward(self, grad_output): + norm, std, weight = self.saved_tensors + grad_weight = torch.zeros_like(weight) + grad_bias = torch.zeros_like(weight) + grad_input = torch.zeros_like(grad_output) + grad_output3d = grad_output.flatten(start_dim=2) + grad_input3d = grad_input.view_as(grad_output3d) + + batch_size = grad_input3d.size(0) + if batch_size > 0: + ext_module.sync_bn_backward_param(grad_output3d, norm, grad_weight, + grad_bias) + + # all reduce + if self.group_size > 1: + dist.all_reduce(grad_weight, group=self.group) + dist.all_reduce(grad_bias, group=self.group) + grad_weight /= self.group_size + grad_bias /= self.group_size + + if batch_size > 0: + ext_module.sync_bn_backward_data(grad_output3d, weight, + grad_weight, grad_bias, norm, std, + grad_input3d) + + return grad_input, None, None, grad_weight, grad_bias, \ + None, None, None, None, None + + +@NORM_LAYERS.register_module(name='MMSyncBN') +class SyncBatchNorm(Module): + """Synchronized Batch Normalization. + + Args: + num_features (int): number of features/chennels in input tensor + eps (float, optional): a value added to the denominator for numerical + stability. Defaults to 1e-5. + momentum (float, optional): the value used for the running_mean and + running_var computation. Defaults to 0.1. + affine (bool, optional): whether to use learnable affine parameters. + Defaults to True. + track_running_stats (bool, optional): whether to track the running + mean and variance during training. When set to False, this + module does not track such statistics, and initializes statistics + buffers ``running_mean`` and ``running_var`` as ``None``. When + these buffers are ``None``, this module always uses batch + statistics in both training and eval modes. Defaults to True. + group (int, optional): synchronization of stats happen within + each process group individually. By default it is synchronization + across the whole world. Defaults to None. + stats_mode (str, optional): The statistical mode. Available options + includes ``'default'`` and ``'N'``. Defaults to 'default'. + When ``stats_mode=='default'``, it computes the overall statistics + using those from each worker with equal weight, i.e., the + statistics are synchronized and simply divied by ``group``. This + mode will produce inaccurate statistics when empty tensors occur. + When ``stats_mode=='N'``, it compute the overall statistics using + the total number of batches in each worker ignoring the number of + group, i.e., the statistics are synchronized and then divied by + the total batch ``N``. This mode is beneficial when empty tensors + occur during training, as it average the total mean by the real + number of batch. + """ + + def __init__(self, + num_features, + eps=1e-5, + momentum=0.1, + affine=True, + track_running_stats=True, + group=None, + stats_mode='default'): + super(SyncBatchNorm, self).__init__() + self.num_features = num_features + self.eps = eps + self.momentum = momentum + self.affine = affine + self.track_running_stats = track_running_stats + group = dist.group.WORLD if group is None else group + self.group = group + self.group_size = dist.get_world_size(group) + assert stats_mode in ['default', 'N'], \ + f'"stats_mode" only accepts "default" and "N", got "{stats_mode}"' + self.stats_mode = stats_mode + if self.affine: + self.weight = Parameter(torch.Tensor(num_features)) + self.bias = Parameter(torch.Tensor(num_features)) + else: + self.register_parameter('weight', None) + self.register_parameter('bias', None) + if self.track_running_stats: + self.register_buffer('running_mean', torch.zeros(num_features)) + self.register_buffer('running_var', torch.ones(num_features)) + self.register_buffer('num_batches_tracked', + torch.tensor(0, dtype=torch.long)) + else: + self.register_buffer('running_mean', None) + self.register_buffer('running_var', None) + self.register_buffer('num_batches_tracked', None) + self.reset_parameters() + + def reset_running_stats(self): + if self.track_running_stats: + self.running_mean.zero_() + self.running_var.fill_(1) + self.num_batches_tracked.zero_() + + def reset_parameters(self): + self.reset_running_stats() + if self.affine: + self.weight.data.uniform_() # pytorch use ones_() + self.bias.data.zero_() + + def forward(self, input): + if input.dim() < 2: + raise ValueError( + f'expected at least 2D input, got {input.dim()}D input') + if self.momentum is None: + exponential_average_factor = 0.0 + else: + exponential_average_factor = self.momentum + + if self.training and self.track_running_stats: + if self.num_batches_tracked is not None: + self.num_batches_tracked += 1 + if self.momentum is None: # use cumulative moving average + exponential_average_factor = 1.0 / float( + self.num_batches_tracked) + else: # use exponential moving average + exponential_average_factor = self.momentum + + if self.training or not self.track_running_stats: + return SyncBatchNormFunction.apply( + input, self.running_mean, self.running_var, self.weight, + self.bias, exponential_average_factor, self.eps, self.group, + self.group_size, self.stats_mode) + else: + return F.batch_norm(input, self.running_mean, self.running_var, + self.weight, self.bias, False, + exponential_average_factor, self.eps) + + def __repr__(self): + s = self.__class__.__name__ + s += f'({self.num_features}, ' + s += f'eps={self.eps}, ' + s += f'momentum={self.momentum}, ' + s += f'affine={self.affine}, ' + s += f'track_running_stats={self.track_running_stats}, ' + s += f'group_size={self.group_size},' + s += f'stats_mode={self.stats_mode})' + return s diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/three_interpolate.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/three_interpolate.py new file mode 100644 index 00000000..203f47f0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/three_interpolate.py @@ -0,0 +1,68 @@ +from typing import Tuple + +import torch +from torch.autograd import Function + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext( + '_ext', ['three_interpolate_forward', 'three_interpolate_backward']) + + +class ThreeInterpolate(Function): + """Performs weighted linear interpolation on 3 features. + + Please refer to `Paper of PointNet++ `_ + for more details. + """ + + @staticmethod + def forward(ctx, features: torch.Tensor, indices: torch.Tensor, + weight: torch.Tensor) -> torch.Tensor: + """ + Args: + features (Tensor): (B, C, M) Features descriptors to be + interpolated + indices (Tensor): (B, n, 3) index three nearest neighbors + of the target features in features + weight (Tensor): (B, n, 3) weights of interpolation + + Returns: + Tensor: (B, C, N) tensor of the interpolated features + """ + assert features.is_contiguous() + assert indices.is_contiguous() + assert weight.is_contiguous() + + B, c, m = features.size() + n = indices.size(1) + ctx.three_interpolate_for_backward = (indices, weight, m) + output = torch.cuda.FloatTensor(B, c, n) + + ext_module.three_interpolate_forward( + features, indices, weight, output, b=B, c=c, m=m, n=n) + return output + + @staticmethod + def backward( + ctx, grad_out: torch.Tensor + ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]: + """ + Args: + grad_out (Tensor): (B, C, N) tensor with gradients of outputs + + Returns: + Tensor: (B, C, M) tensor with gradients of features + """ + idx, weight, m = ctx.three_interpolate_for_backward + B, c, n = grad_out.size() + + grad_features = torch.cuda.FloatTensor(B, c, m).zero_() + grad_out_data = grad_out.data.contiguous() + + ext_module.three_interpolate_backward( + grad_out_data, idx, weight, grad_features.data, b=B, c=c, n=n, m=m) + return grad_features, None, None + + +three_interpolate = ThreeInterpolate.apply diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/three_nn.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/three_nn.py new file mode 100644 index 00000000..2b01047a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/three_nn.py @@ -0,0 +1,51 @@ +from typing import Tuple + +import torch +from torch.autograd import Function + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', ['three_nn_forward']) + + +class ThreeNN(Function): + """Find the top-3 nearest neighbors of the target set from the source set. + + Please refer to `Paper of PointNet++ `_ + for more details. + """ + + @staticmethod + def forward(ctx, target: torch.Tensor, + source: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]: + """ + Args: + target (Tensor): shape (B, N, 3), points set that needs to + find the nearest neighbors. + source (Tensor): shape (B, M, 3), points set that is used + to find the nearest neighbors of points in target set. + + Returns: + Tensor: shape (B, N, 3), L2 distance of each point in target + set to their corresponding nearest neighbors. + """ + target = target.contiguous() + source = source.contiguous() + + B, N, _ = target.size() + m = source.size(1) + dist2 = torch.cuda.FloatTensor(B, N, 3) + idx = torch.cuda.IntTensor(B, N, 3) + + ext_module.three_nn_forward(target, source, dist2, idx, b=B, n=N, m=m) + if torch.__version__ != 'parrots': + ctx.mark_non_differentiable(idx) + + return torch.sqrt(dist2), idx + + @staticmethod + def backward(ctx, a=None, b=None): + return None, None + + +three_nn = ThreeNN.apply diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/tin_shift.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/tin_shift.py new file mode 100644 index 00000000..472c9fcf --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/tin_shift.py @@ -0,0 +1,68 @@ +# Copyright (c) OpenMMLab. All rights reserved. +# Code reference from "Temporal Interlacing Network" +# https://github.com/deepcs233/TIN/blob/master/cuda_shift/rtc_wrap.py +# Hao Shao, Shengju Qian, Yu Liu +# shaoh19@mails.tsinghua.edu.cn, sjqian@cse.cuhk.edu.hk, yuliu@ee.cuhk.edu.hk + +import torch +import torch.nn as nn +from torch.autograd import Function + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext('_ext', + ['tin_shift_forward', 'tin_shift_backward']) + + +class TINShiftFunction(Function): + + @staticmethod + def forward(ctx, input, shift): + C = input.size(2) + num_segments = shift.size(1) + if C // num_segments <= 0 or C % num_segments != 0: + raise ValueError('C should be a multiple of num_segments, ' + f'but got C={C} and num_segments={num_segments}.') + + ctx.save_for_backward(shift) + + out = torch.zeros_like(input) + ext_module.tin_shift_forward(input, shift, out) + + return out + + @staticmethod + def backward(ctx, grad_output): + + shift = ctx.saved_tensors[0] + data_grad_input = grad_output.new(*grad_output.size()).zero_() + shift_grad_input = shift.new(*shift.size()).zero_() + ext_module.tin_shift_backward(grad_output, shift, data_grad_input) + + return data_grad_input, shift_grad_input + + +tin_shift = TINShiftFunction.apply + + +class TINShift(nn.Module): + """Temporal Interlace Shift. + + Temporal Interlace shift is a differentiable temporal-wise frame shifting + which is proposed in "Temporal Interlacing Network" + + Please refer to https://arxiv.org/abs/2001.06499 for more details. + Code is modified from https://github.com/mit-han-lab/temporal-shift-module + """ + + def forward(self, input, shift): + """Perform temporal interlace shift. + + Args: + input (Tensor): Feature map with shape [N, num_segments, C, H * W]. + shift (Tensor): Shift tensor with shape [N, num_segments]. + + Returns: + Feature map after temporal interlace shift. + """ + return tin_shift(input, shift) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/upfirdn2d.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/upfirdn2d.py new file mode 100644 index 00000000..751db20a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/upfirdn2d.py @@ -0,0 +1,330 @@ +# modified from https://github.com/rosinality/stylegan2-pytorch/blob/master/op/upfirdn2d.py # noqa:E501 + +# Copyright (c) 2021, NVIDIA Corporation. All rights reserved. +# NVIDIA Source Code License for StyleGAN2 with Adaptive Discriminator +# Augmentation (ADA) +# ======================================================================= + +# 1. Definitions + +# "Licensor" means any person or entity that distributes its Work. + +# "Software" means the original work of authorship made available under +# this License. + +# "Work" means the Software and any additions to or derivative works of +# the Software that are made available under this License. + +# The terms "reproduce," "reproduction," "derivative works," and +# "distribution" have the meaning as provided under U.S. copyright law; +# provided, however, that for the purposes of this License, derivative +# works shall not include works that remain separable from, or merely +# link (or bind by name) to the interfaces of, the Work. + +# Works, including the Software, are "made available" under this License +# by including in or with the Work either (a) a copyright notice +# referencing the applicability of this License to the Work, or (b) a +# copy of this License. + +# 2. License Grants + +# 2.1 Copyright Grant. Subject to the terms and conditions of this +# License, each Licensor grants to you a perpetual, worldwide, +# non-exclusive, royalty-free, copyright license to reproduce, +# prepare derivative works of, publicly display, publicly perform, +# sublicense and distribute its Work and any resulting derivative +# works in any form. + +# 3. Limitations + +# 3.1 Redistribution. You may reproduce or distribute the Work only +# if (a) you do so under this License, (b) you include a complete +# copy of this License with your distribution, and (c) you retain +# without modification any copyright, patent, trademark, or +# attribution notices that are present in the Work. + +# 3.2 Derivative Works. You may specify that additional or different +# terms apply to the use, reproduction, and distribution of your +# derivative works of the Work ("Your Terms") only if (a) Your Terms +# provide that the use limitation in Section 3.3 applies to your +# derivative works, and (b) you identify the specific derivative +# works that are subject to Your Terms. Notwithstanding Your Terms, +# this License (including the redistribution requirements in Section +# 3.1) will continue to apply to the Work itself. + +# 3.3 Use Limitation. The Work and any derivative works thereof only +# may be used or intended for use non-commercially. Notwithstanding +# the foregoing, NVIDIA and its affiliates may use the Work and any +# derivative works commercially. As used herein, "non-commercially" +# means for research or evaluation purposes only. + +# 3.4 Patent Claims. If you bring or threaten to bring a patent claim +# against any Licensor (including any claim, cross-claim or +# counterclaim in a lawsuit) to enforce any patents that you allege +# are infringed by any Work, then your rights under this License from +# such Licensor (including the grant in Section 2.1) will terminate +# immediately. + +# 3.5 Trademarks. This License does not grant any rights to use any +# Licensor’s or its affiliates’ names, logos, or trademarks, except +# as necessary to reproduce the notices described in this License. + +# 3.6 Termination. If you violate any term of this License, then your +# rights under this License (including the grant in Section 2.1) will +# terminate immediately. + +# 4. Disclaimer of Warranty. + +# THE WORK IS PROVIDED "AS IS" WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WARRANTIES OR CONDITIONS OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR +# NON-INFRINGEMENT. YOU BEAR THE RISK OF UNDERTAKING ANY ACTIVITIES UNDER +# THIS LICENSE. + +# 5. Limitation of Liability. + +# EXCEPT AS PROHIBITED BY APPLICABLE LAW, IN NO EVENT AND UNDER NO LEGAL +# THEORY, WHETHER IN TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE +# SHALL ANY LICENSOR BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY DIRECT, +# INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF +# OR RELATED TO THIS LICENSE, THE USE OR INABILITY TO USE THE WORK +# (INCLUDING BUT NOT LIMITED TO LOSS OF GOODWILL, BUSINESS INTERRUPTION, +# LOST PROFITS OR DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY OTHER +# COMMERCIAL DAMAGES OR LOSSES), EVEN IF THE LICENSOR HAS BEEN ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGES. + +# ======================================================================= + +import torch +from torch.autograd import Function +from torch.nn import functional as F + +from annotator.mmpkg.mmcv.utils import to_2tuple +from ..utils import ext_loader + +upfirdn2d_ext = ext_loader.load_ext('_ext', ['upfirdn2d']) + + +class UpFirDn2dBackward(Function): + + @staticmethod + def forward(ctx, grad_output, kernel, grad_kernel, up, down, pad, g_pad, + in_size, out_size): + + up_x, up_y = up + down_x, down_y = down + g_pad_x0, g_pad_x1, g_pad_y0, g_pad_y1 = g_pad + + grad_output = grad_output.reshape(-1, out_size[0], out_size[1], 1) + + grad_input = upfirdn2d_ext.upfirdn2d( + grad_output, + grad_kernel, + up_x=down_x, + up_y=down_y, + down_x=up_x, + down_y=up_y, + pad_x0=g_pad_x0, + pad_x1=g_pad_x1, + pad_y0=g_pad_y0, + pad_y1=g_pad_y1) + grad_input = grad_input.view(in_size[0], in_size[1], in_size[2], + in_size[3]) + + ctx.save_for_backward(kernel) + + pad_x0, pad_x1, pad_y0, pad_y1 = pad + + ctx.up_x = up_x + ctx.up_y = up_y + ctx.down_x = down_x + ctx.down_y = down_y + ctx.pad_x0 = pad_x0 + ctx.pad_x1 = pad_x1 + ctx.pad_y0 = pad_y0 + ctx.pad_y1 = pad_y1 + ctx.in_size = in_size + ctx.out_size = out_size + + return grad_input + + @staticmethod + def backward(ctx, gradgrad_input): + kernel, = ctx.saved_tensors + + gradgrad_input = gradgrad_input.reshape(-1, ctx.in_size[2], + ctx.in_size[3], 1) + + gradgrad_out = upfirdn2d_ext.upfirdn2d( + gradgrad_input, + kernel, + up_x=ctx.up_x, + up_y=ctx.up_y, + down_x=ctx.down_x, + down_y=ctx.down_y, + pad_x0=ctx.pad_x0, + pad_x1=ctx.pad_x1, + pad_y0=ctx.pad_y0, + pad_y1=ctx.pad_y1) + # gradgrad_out = gradgrad_out.view(ctx.in_size[0], ctx.out_size[0], + # ctx.out_size[1], ctx.in_size[3]) + gradgrad_out = gradgrad_out.view(ctx.in_size[0], ctx.in_size[1], + ctx.out_size[0], ctx.out_size[1]) + + return gradgrad_out, None, None, None, None, None, None, None, None + + +class UpFirDn2d(Function): + + @staticmethod + def forward(ctx, input, kernel, up, down, pad): + up_x, up_y = up + down_x, down_y = down + pad_x0, pad_x1, pad_y0, pad_y1 = pad + + kernel_h, kernel_w = kernel.shape + batch, channel, in_h, in_w = input.shape + ctx.in_size = input.shape + + input = input.reshape(-1, in_h, in_w, 1) + + ctx.save_for_backward(kernel, torch.flip(kernel, [0, 1])) + + out_h = (in_h * up_y + pad_y0 + pad_y1 - kernel_h) // down_y + 1 + out_w = (in_w * up_x + pad_x0 + pad_x1 - kernel_w) // down_x + 1 + ctx.out_size = (out_h, out_w) + + ctx.up = (up_x, up_y) + ctx.down = (down_x, down_y) + ctx.pad = (pad_x0, pad_x1, pad_y0, pad_y1) + + g_pad_x0 = kernel_w - pad_x0 - 1 + g_pad_y0 = kernel_h - pad_y0 - 1 + g_pad_x1 = in_w * up_x - out_w * down_x + pad_x0 - up_x + 1 + g_pad_y1 = in_h * up_y - out_h * down_y + pad_y0 - up_y + 1 + + ctx.g_pad = (g_pad_x0, g_pad_x1, g_pad_y0, g_pad_y1) + + out = upfirdn2d_ext.upfirdn2d( + input, + kernel, + up_x=up_x, + up_y=up_y, + down_x=down_x, + down_y=down_y, + pad_x0=pad_x0, + pad_x1=pad_x1, + pad_y0=pad_y0, + pad_y1=pad_y1) + # out = out.view(major, out_h, out_w, minor) + out = out.view(-1, channel, out_h, out_w) + + return out + + @staticmethod + def backward(ctx, grad_output): + kernel, grad_kernel = ctx.saved_tensors + + grad_input = UpFirDn2dBackward.apply( + grad_output, + kernel, + grad_kernel, + ctx.up, + ctx.down, + ctx.pad, + ctx.g_pad, + ctx.in_size, + ctx.out_size, + ) + + return grad_input, None, None, None, None + + +def upfirdn2d(input, kernel, up=1, down=1, pad=(0, 0)): + """UpFRIDn for 2d features. + + UpFIRDn is short for upsample, apply FIR filter and downsample. More + details can be found in: + https://www.mathworks.com/help/signal/ref/upfirdn.html + + Args: + input (Tensor): Tensor with shape of (n, c, h, w). + kernel (Tensor): Filter kernel. + up (int | tuple[int], optional): Upsampling factor. If given a number, + we will use this factor for the both height and width side. + Defaults to 1. + down (int | tuple[int], optional): Downsampling factor. If given a + number, we will use this factor for the both height and width side. + Defaults to 1. + pad (tuple[int], optional): Padding for tensors, (x_pad, y_pad) or + (x_pad_0, x_pad_1, y_pad_0, y_pad_1). Defaults to (0, 0). + + Returns: + Tensor: Tensor after UpFIRDn. + """ + if input.device.type == 'cpu': + if len(pad) == 2: + pad = (pad[0], pad[1], pad[0], pad[1]) + + up = to_2tuple(up) + + down = to_2tuple(down) + + out = upfirdn2d_native(input, kernel, up[0], up[1], down[0], down[1], + pad[0], pad[1], pad[2], pad[3]) + else: + _up = to_2tuple(up) + + _down = to_2tuple(down) + + if len(pad) == 4: + _pad = pad + elif len(pad) == 2: + _pad = (pad[0], pad[1], pad[0], pad[1]) + + out = UpFirDn2d.apply(input, kernel, _up, _down, _pad) + + return out + + +def upfirdn2d_native(input, kernel, up_x, up_y, down_x, down_y, pad_x0, pad_x1, + pad_y0, pad_y1): + _, channel, in_h, in_w = input.shape + input = input.reshape(-1, in_h, in_w, 1) + + _, in_h, in_w, minor = input.shape + kernel_h, kernel_w = kernel.shape + + out = input.view(-1, in_h, 1, in_w, 1, minor) + out = F.pad(out, [0, 0, 0, up_x - 1, 0, 0, 0, up_y - 1]) + out = out.view(-1, in_h * up_y, in_w * up_x, minor) + + out = F.pad( + out, + [0, 0, + max(pad_x0, 0), + max(pad_x1, 0), + max(pad_y0, 0), + max(pad_y1, 0)]) + out = out[:, + max(-pad_y0, 0):out.shape[1] - max(-pad_y1, 0), + max(-pad_x0, 0):out.shape[2] - max(-pad_x1, 0), :, ] + + out = out.permute(0, 3, 1, 2) + out = out.reshape( + [-1, 1, in_h * up_y + pad_y0 + pad_y1, in_w * up_x + pad_x0 + pad_x1]) + w = torch.flip(kernel, [0, 1]).view(1, 1, kernel_h, kernel_w) + out = F.conv2d(out, w) + out = out.reshape( + -1, + minor, + in_h * up_y + pad_y0 + pad_y1 - kernel_h + 1, + in_w * up_x + pad_x0 + pad_x1 - kernel_w + 1, + ) + out = out.permute(0, 2, 3, 1) + out = out[:, ::down_y, ::down_x, :] + + out_h = (in_h * up_y + pad_y0 + pad_y1 - kernel_h) // down_y + 1 + out_w = (in_w * up_x + pad_x0 + pad_x1 - kernel_w) // down_x + 1 + + return out.view(-1, channel, out_h, out_w) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/voxelize.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/voxelize.py new file mode 100644 index 00000000..ca3226a4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/ops/voxelize.py @@ -0,0 +1,132 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +from torch import nn +from torch.autograd import Function +from torch.nn.modules.utils import _pair + +from ..utils import ext_loader + +ext_module = ext_loader.load_ext( + '_ext', ['dynamic_voxelize_forward', 'hard_voxelize_forward']) + + +class _Voxelization(Function): + + @staticmethod + def forward(ctx, + points, + voxel_size, + coors_range, + max_points=35, + max_voxels=20000): + """Convert kitti points(N, >=3) to voxels. + + Args: + points (torch.Tensor): [N, ndim]. Points[:, :3] contain xyz points + and points[:, 3:] contain other information like reflectivity. + voxel_size (tuple or float): The size of voxel with the shape of + [3]. + coors_range (tuple or float): The coordinate range of voxel with + the shape of [6]. + max_points (int, optional): maximum points contained in a voxel. if + max_points=-1, it means using dynamic_voxelize. Default: 35. + max_voxels (int, optional): maximum voxels this function create. + for second, 20000 is a good choice. Users should shuffle points + before call this function because max_voxels may drop points. + Default: 20000. + + Returns: + voxels_out (torch.Tensor): Output voxels with the shape of [M, + max_points, ndim]. Only contain points and returned when + max_points != -1. + coors_out (torch.Tensor): Output coordinates with the shape of + [M, 3]. + num_points_per_voxel_out (torch.Tensor): Num points per voxel with + the shape of [M]. Only returned when max_points != -1. + """ + if max_points == -1 or max_voxels == -1: + coors = points.new_zeros(size=(points.size(0), 3), dtype=torch.int) + ext_module.dynamic_voxelize_forward(points, coors, voxel_size, + coors_range, 3) + return coors + else: + voxels = points.new_zeros( + size=(max_voxels, max_points, points.size(1))) + coors = points.new_zeros(size=(max_voxels, 3), dtype=torch.int) + num_points_per_voxel = points.new_zeros( + size=(max_voxels, ), dtype=torch.int) + voxel_num = ext_module.hard_voxelize_forward( + points, voxels, coors, num_points_per_voxel, voxel_size, + coors_range, max_points, max_voxels, 3) + # select the valid voxels + voxels_out = voxels[:voxel_num] + coors_out = coors[:voxel_num] + num_points_per_voxel_out = num_points_per_voxel[:voxel_num] + return voxels_out, coors_out, num_points_per_voxel_out + + +voxelization = _Voxelization.apply + + +class Voxelization(nn.Module): + """Convert kitti points(N, >=3) to voxels. + + Please refer to `PVCNN `_ for more + details. + + Args: + voxel_size (tuple or float): The size of voxel with the shape of [3]. + point_cloud_range (tuple or float): The coordinate range of voxel with + the shape of [6]. + max_num_points (int): maximum points contained in a voxel. if + max_points=-1, it means using dynamic_voxelize. + max_voxels (int, optional): maximum voxels this function create. + for second, 20000 is a good choice. Users should shuffle points + before call this function because max_voxels may drop points. + Default: 20000. + """ + + def __init__(self, + voxel_size, + point_cloud_range, + max_num_points, + max_voxels=20000): + super().__init__() + + self.voxel_size = voxel_size + self.point_cloud_range = point_cloud_range + self.max_num_points = max_num_points + if isinstance(max_voxels, tuple): + self.max_voxels = max_voxels + else: + self.max_voxels = _pair(max_voxels) + + point_cloud_range = torch.tensor( + point_cloud_range, dtype=torch.float32) + voxel_size = torch.tensor(voxel_size, dtype=torch.float32) + grid_size = (point_cloud_range[3:] - + point_cloud_range[:3]) / voxel_size + grid_size = torch.round(grid_size).long() + input_feat_shape = grid_size[:2] + self.grid_size = grid_size + # the origin shape is as [x-len, y-len, z-len] + # [w, h, d] -> [d, h, w] + self.pcd_shape = [*input_feat_shape, 1][::-1] + + def forward(self, input): + if self.training: + max_voxels = self.max_voxels[0] + else: + max_voxels = self.max_voxels[1] + + return voxelization(input, self.voxel_size, self.point_cloud_range, + self.max_num_points, max_voxels) + + def __repr__(self): + s = self.__class__.__name__ + '(' + s += 'voxel_size=' + str(self.voxel_size) + s += ', point_cloud_range=' + str(self.point_cloud_range) + s += ', max_num_points=' + str(self.max_num_points) + s += ', max_voxels=' + str(self.max_voxels) + s += ')' + return s diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/__init__.py new file mode 100644 index 00000000..2ed2c17a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/__init__.py @@ -0,0 +1,13 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .collate import collate +from .data_container import DataContainer +from .data_parallel import MMDataParallel +from .distributed import MMDistributedDataParallel +from .registry import MODULE_WRAPPERS +from .scatter_gather import scatter, scatter_kwargs +from .utils import is_module_wrapper + +__all__ = [ + 'collate', 'DataContainer', 'MMDataParallel', 'MMDistributedDataParallel', + 'scatter', 'scatter_kwargs', 'is_module_wrapper', 'MODULE_WRAPPERS' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/_functions.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/_functions.py new file mode 100644 index 00000000..9b5a8a44 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/_functions.py @@ -0,0 +1,79 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +from torch.nn.parallel._functions import _get_stream + + +def scatter(input, devices, streams=None): + """Scatters tensor across multiple GPUs.""" + if streams is None: + streams = [None] * len(devices) + + if isinstance(input, list): + chunk_size = (len(input) - 1) // len(devices) + 1 + outputs = [ + scatter(input[i], [devices[i // chunk_size]], + [streams[i // chunk_size]]) for i in range(len(input)) + ] + return outputs + elif isinstance(input, torch.Tensor): + output = input.contiguous() + # TODO: copy to a pinned buffer first (if copying from CPU) + stream = streams[0] if output.numel() > 0 else None + if devices != [-1]: + with torch.cuda.device(devices[0]), torch.cuda.stream(stream): + output = output.cuda(devices[0], non_blocking=True) + else: + # unsqueeze the first dimension thus the tensor's shape is the + # same as those scattered with GPU. + output = output.unsqueeze(0) + return output + else: + raise Exception(f'Unknown type {type(input)}.') + + +def synchronize_stream(output, devices, streams): + if isinstance(output, list): + chunk_size = len(output) // len(devices) + for i in range(len(devices)): + for j in range(chunk_size): + synchronize_stream(output[i * chunk_size + j], [devices[i]], + [streams[i]]) + elif isinstance(output, torch.Tensor): + if output.numel() != 0: + with torch.cuda.device(devices[0]): + main_stream = torch.cuda.current_stream() + main_stream.wait_stream(streams[0]) + output.record_stream(main_stream) + else: + raise Exception(f'Unknown type {type(output)}.') + + +def get_input_device(input): + if isinstance(input, list): + for item in input: + input_device = get_input_device(item) + if input_device != -1: + return input_device + return -1 + elif isinstance(input, torch.Tensor): + return input.get_device() if input.is_cuda else -1 + else: + raise Exception(f'Unknown type {type(input)}.') + + +class Scatter: + + @staticmethod + def forward(target_gpus, input): + input_device = get_input_device(input) + streams = None + if input_device == -1 and target_gpus != [-1]: + # Perform CPU to GPU copies in a background stream + streams = [_get_stream(device) for device in target_gpus] + + outputs = scatter(input, target_gpus, streams) + # Synchronize with the copy stream + if streams is not None: + synchronize_stream(outputs, target_gpus, streams) + + return tuple(outputs) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/collate.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/collate.py new file mode 100644 index 00000000..ad749197 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/collate.py @@ -0,0 +1,84 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from collections.abc import Mapping, Sequence + +import torch +import torch.nn.functional as F +from torch.utils.data.dataloader import default_collate + +from .data_container import DataContainer + + +def collate(batch, samples_per_gpu=1): + """Puts each data field into a tensor/DataContainer with outer dimension + batch size. + + Extend default_collate to add support for + :type:`~mmcv.parallel.DataContainer`. There are 3 cases. + + 1. cpu_only = True, e.g., meta data + 2. cpu_only = False, stack = True, e.g., images tensors + 3. cpu_only = False, stack = False, e.g., gt bboxes + """ + + if not isinstance(batch, Sequence): + raise TypeError(f'{batch.dtype} is not supported.') + + if isinstance(batch[0], DataContainer): + stacked = [] + if batch[0].cpu_only: + for i in range(0, len(batch), samples_per_gpu): + stacked.append( + [sample.data for sample in batch[i:i + samples_per_gpu]]) + return DataContainer( + stacked, batch[0].stack, batch[0].padding_value, cpu_only=True) + elif batch[0].stack: + for i in range(0, len(batch), samples_per_gpu): + assert isinstance(batch[i].data, torch.Tensor) + + if batch[i].pad_dims is not None: + ndim = batch[i].dim() + assert ndim > batch[i].pad_dims + max_shape = [0 for _ in range(batch[i].pad_dims)] + for dim in range(1, batch[i].pad_dims + 1): + max_shape[dim - 1] = batch[i].size(-dim) + for sample in batch[i:i + samples_per_gpu]: + for dim in range(0, ndim - batch[i].pad_dims): + assert batch[i].size(dim) == sample.size(dim) + for dim in range(1, batch[i].pad_dims + 1): + max_shape[dim - 1] = max(max_shape[dim - 1], + sample.size(-dim)) + padded_samples = [] + for sample in batch[i:i + samples_per_gpu]: + pad = [0 for _ in range(batch[i].pad_dims * 2)] + for dim in range(1, batch[i].pad_dims + 1): + pad[2 * dim - + 1] = max_shape[dim - 1] - sample.size(-dim) + padded_samples.append( + F.pad( + sample.data, pad, value=sample.padding_value)) + stacked.append(default_collate(padded_samples)) + elif batch[i].pad_dims is None: + stacked.append( + default_collate([ + sample.data + for sample in batch[i:i + samples_per_gpu] + ])) + else: + raise ValueError( + 'pad_dims should be either None or integers (1-3)') + + else: + for i in range(0, len(batch), samples_per_gpu): + stacked.append( + [sample.data for sample in batch[i:i + samples_per_gpu]]) + return DataContainer(stacked, batch[0].stack, batch[0].padding_value) + elif isinstance(batch[0], Sequence): + transposed = zip(*batch) + return [collate(samples, samples_per_gpu) for samples in transposed] + elif isinstance(batch[0], Mapping): + return { + key: collate([d[key] for d in batch], samples_per_gpu) + for key in batch[0] + } + else: + return default_collate(batch) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/data_container.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/data_container.py new file mode 100644 index 00000000..cedb0d32 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/data_container.py @@ -0,0 +1,89 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import functools + +import torch + + +def assert_tensor_type(func): + + @functools.wraps(func) + def wrapper(*args, **kwargs): + if not isinstance(args[0].data, torch.Tensor): + raise AttributeError( + f'{args[0].__class__.__name__} has no attribute ' + f'{func.__name__} for type {args[0].datatype}') + return func(*args, **kwargs) + + return wrapper + + +class DataContainer: + """A container for any type of objects. + + Typically tensors will be stacked in the collate function and sliced along + some dimension in the scatter function. This behavior has some limitations. + 1. All tensors have to be the same size. + 2. Types are limited (numpy array or Tensor). + + We design `DataContainer` and `MMDataParallel` to overcome these + limitations. The behavior can be either of the following. + + - copy to GPU, pad all tensors to the same size and stack them + - copy to GPU without stacking + - leave the objects as is and pass it to the model + - pad_dims specifies the number of last few dimensions to do padding + """ + + def __init__(self, + data, + stack=False, + padding_value=0, + cpu_only=False, + pad_dims=2): + self._data = data + self._cpu_only = cpu_only + self._stack = stack + self._padding_value = padding_value + assert pad_dims in [None, 1, 2, 3] + self._pad_dims = pad_dims + + def __repr__(self): + return f'{self.__class__.__name__}({repr(self.data)})' + + def __len__(self): + return len(self._data) + + @property + def data(self): + return self._data + + @property + def datatype(self): + if isinstance(self.data, torch.Tensor): + return self.data.type() + else: + return type(self.data) + + @property + def cpu_only(self): + return self._cpu_only + + @property + def stack(self): + return self._stack + + @property + def padding_value(self): + return self._padding_value + + @property + def pad_dims(self): + return self._pad_dims + + @assert_tensor_type + def size(self, *args, **kwargs): + return self.data.size(*args, **kwargs) + + @assert_tensor_type + def dim(self): + return self.data.dim() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/data_parallel.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/data_parallel.py new file mode 100644 index 00000000..79b5f69b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/data_parallel.py @@ -0,0 +1,89 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from itertools import chain + +from torch.nn.parallel import DataParallel + +from .scatter_gather import scatter_kwargs + + +class MMDataParallel(DataParallel): + """The DataParallel module that supports DataContainer. + + MMDataParallel has two main differences with PyTorch DataParallel: + + - It supports a custom type :class:`DataContainer` which allows more + flexible control of input data during both GPU and CPU inference. + - It implement two more APIs ``train_step()`` and ``val_step()``. + + Args: + module (:class:`nn.Module`): Module to be encapsulated. + device_ids (list[int]): Device IDS of modules to be scattered to. + Defaults to None when GPU is not available. + output_device (str | int): Device ID for output. Defaults to None. + dim (int): Dimension used to scatter the data. Defaults to 0. + """ + + def __init__(self, *args, dim=0, **kwargs): + super(MMDataParallel, self).__init__(*args, dim=dim, **kwargs) + self.dim = dim + + def forward(self, *inputs, **kwargs): + """Override the original forward function. + + The main difference lies in the CPU inference where the data in + :class:`DataContainers` will still be gathered. + """ + if not self.device_ids: + # We add the following line thus the module could gather and + # convert data containers as those in GPU inference + inputs, kwargs = self.scatter(inputs, kwargs, [-1]) + return self.module(*inputs[0], **kwargs[0]) + else: + return super().forward(*inputs, **kwargs) + + def scatter(self, inputs, kwargs, device_ids): + return scatter_kwargs(inputs, kwargs, device_ids, dim=self.dim) + + def train_step(self, *inputs, **kwargs): + if not self.device_ids: + # We add the following line thus the module could gather and + # convert data containers as those in GPU inference + inputs, kwargs = self.scatter(inputs, kwargs, [-1]) + return self.module.train_step(*inputs[0], **kwargs[0]) + + assert len(self.device_ids) == 1, \ + ('MMDataParallel only supports single GPU training, if you need to' + ' train with multiple GPUs, please use MMDistributedDataParallel' + 'instead.') + + for t in chain(self.module.parameters(), self.module.buffers()): + if t.device != self.src_device_obj: + raise RuntimeError( + 'module must have its parameters and buffers ' + f'on device {self.src_device_obj} (device_ids[0]) but ' + f'found one of them on device: {t.device}') + + inputs, kwargs = self.scatter(inputs, kwargs, self.device_ids) + return self.module.train_step(*inputs[0], **kwargs[0]) + + def val_step(self, *inputs, **kwargs): + if not self.device_ids: + # We add the following line thus the module could gather and + # convert data containers as those in GPU inference + inputs, kwargs = self.scatter(inputs, kwargs, [-1]) + return self.module.val_step(*inputs[0], **kwargs[0]) + + assert len(self.device_ids) == 1, \ + ('MMDataParallel only supports single GPU training, if you need to' + ' train with multiple GPUs, please use MMDistributedDataParallel' + ' instead.') + + for t in chain(self.module.parameters(), self.module.buffers()): + if t.device != self.src_device_obj: + raise RuntimeError( + 'module must have its parameters and buffers ' + f'on device {self.src_device_obj} (device_ids[0]) but ' + f'found one of them on device: {t.device}') + + inputs, kwargs = self.scatter(inputs, kwargs, self.device_ids) + return self.module.val_step(*inputs[0], **kwargs[0]) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/distributed.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/distributed.py new file mode 100644 index 00000000..929c7a45 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/distributed.py @@ -0,0 +1,112 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +from torch.nn.parallel.distributed import (DistributedDataParallel, + _find_tensors) + +from annotator.mmpkg.mmcv import print_log +from annotator.mmpkg.mmcv.utils import TORCH_VERSION, digit_version +from .scatter_gather import scatter_kwargs + + +class MMDistributedDataParallel(DistributedDataParallel): + """The DDP module that supports DataContainer. + + MMDDP has two main differences with PyTorch DDP: + + - It supports a custom type :class:`DataContainer` which allows more + flexible control of input data. + - It implement two APIs ``train_step()`` and ``val_step()``. + """ + + def to_kwargs(self, inputs, kwargs, device_id): + # Use `self.to_kwargs` instead of `self.scatter` in pytorch1.8 + # to move all tensors to device_id + return scatter_kwargs(inputs, kwargs, [device_id], dim=self.dim) + + def scatter(self, inputs, kwargs, device_ids): + return scatter_kwargs(inputs, kwargs, device_ids, dim=self.dim) + + def train_step(self, *inputs, **kwargs): + """train_step() API for module wrapped by DistributedDataParallel. + + This method is basically the same as + ``DistributedDataParallel.forward()``, while replacing + ``self.module.forward()`` with ``self.module.train_step()``. + It is compatible with PyTorch 1.1 - 1.5. + """ + + # In PyTorch >= 1.7, ``reducer._rebuild_buckets()`` is moved from the + # end of backward to the beginning of forward. + if ('parrots' not in TORCH_VERSION + and digit_version(TORCH_VERSION) >= digit_version('1.7') + and self.reducer._rebuild_buckets()): + print_log( + 'Reducer buckets have been rebuilt in this iteration.', + logger='mmcv') + + if getattr(self, 'require_forward_param_sync', True): + self._sync_params() + if self.device_ids: + inputs, kwargs = self.scatter(inputs, kwargs, self.device_ids) + if len(self.device_ids) == 1: + output = self.module.train_step(*inputs[0], **kwargs[0]) + else: + outputs = self.parallel_apply( + self._module_copies[:len(inputs)], inputs, kwargs) + output = self.gather(outputs, self.output_device) + else: + output = self.module.train_step(*inputs, **kwargs) + + if torch.is_grad_enabled() and getattr( + self, 'require_backward_grad_sync', True): + if self.find_unused_parameters: + self.reducer.prepare_for_backward(list(_find_tensors(output))) + else: + self.reducer.prepare_for_backward([]) + else: + if ('parrots' not in TORCH_VERSION + and digit_version(TORCH_VERSION) > digit_version('1.2')): + self.require_forward_param_sync = False + return output + + def val_step(self, *inputs, **kwargs): + """val_step() API for module wrapped by DistributedDataParallel. + + This method is basically the same as + ``DistributedDataParallel.forward()``, while replacing + ``self.module.forward()`` with ``self.module.val_step()``. + It is compatible with PyTorch 1.1 - 1.5. + """ + # In PyTorch >= 1.7, ``reducer._rebuild_buckets()`` is moved from the + # end of backward to the beginning of forward. + if ('parrots' not in TORCH_VERSION + and digit_version(TORCH_VERSION) >= digit_version('1.7') + and self.reducer._rebuild_buckets()): + print_log( + 'Reducer buckets have been rebuilt in this iteration.', + logger='mmcv') + + if getattr(self, 'require_forward_param_sync', True): + self._sync_params() + if self.device_ids: + inputs, kwargs = self.scatter(inputs, kwargs, self.device_ids) + if len(self.device_ids) == 1: + output = self.module.val_step(*inputs[0], **kwargs[0]) + else: + outputs = self.parallel_apply( + self._module_copies[:len(inputs)], inputs, kwargs) + output = self.gather(outputs, self.output_device) + else: + output = self.module.val_step(*inputs, **kwargs) + + if torch.is_grad_enabled() and getattr( + self, 'require_backward_grad_sync', True): + if self.find_unused_parameters: + self.reducer.prepare_for_backward(list(_find_tensors(output))) + else: + self.reducer.prepare_for_backward([]) + else: + if ('parrots' not in TORCH_VERSION + and digit_version(TORCH_VERSION) > digit_version('1.2')): + self.require_forward_param_sync = False + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/distributed_deprecated.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/distributed_deprecated.py new file mode 100644 index 00000000..be60a370 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/distributed_deprecated.py @@ -0,0 +1,70 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.distributed as dist +import torch.nn as nn +from torch._utils import (_flatten_dense_tensors, _take_tensors, + _unflatten_dense_tensors) + +from annotator.mmpkg.mmcv.utils import TORCH_VERSION, digit_version +from .registry import MODULE_WRAPPERS +from .scatter_gather import scatter_kwargs + + +@MODULE_WRAPPERS.register_module() +class MMDistributedDataParallel(nn.Module): + + def __init__(self, + module, + dim=0, + broadcast_buffers=True, + bucket_cap_mb=25): + super(MMDistributedDataParallel, self).__init__() + self.module = module + self.dim = dim + self.broadcast_buffers = broadcast_buffers + + self.broadcast_bucket_size = bucket_cap_mb * 1024 * 1024 + self._sync_params() + + def _dist_broadcast_coalesced(self, tensors, buffer_size): + for tensors in _take_tensors(tensors, buffer_size): + flat_tensors = _flatten_dense_tensors(tensors) + dist.broadcast(flat_tensors, 0) + for tensor, synced in zip( + tensors, _unflatten_dense_tensors(flat_tensors, tensors)): + tensor.copy_(synced) + + def _sync_params(self): + module_states = list(self.module.state_dict().values()) + if len(module_states) > 0: + self._dist_broadcast_coalesced(module_states, + self.broadcast_bucket_size) + if self.broadcast_buffers: + if (TORCH_VERSION != 'parrots' + and digit_version(TORCH_VERSION) < digit_version('1.0')): + buffers = [b.data for b in self.module._all_buffers()] + else: + buffers = [b.data for b in self.module.buffers()] + if len(buffers) > 0: + self._dist_broadcast_coalesced(buffers, + self.broadcast_bucket_size) + + def scatter(self, inputs, kwargs, device_ids): + return scatter_kwargs(inputs, kwargs, device_ids, dim=self.dim) + + def forward(self, *inputs, **kwargs): + inputs, kwargs = self.scatter(inputs, kwargs, + [torch.cuda.current_device()]) + return self.module(*inputs[0], **kwargs[0]) + + def train_step(self, *inputs, **kwargs): + inputs, kwargs = self.scatter(inputs, kwargs, + [torch.cuda.current_device()]) + output = self.module.train_step(*inputs[0], **kwargs[0]) + return output + + def val_step(self, *inputs, **kwargs): + inputs, kwargs = self.scatter(inputs, kwargs, + [torch.cuda.current_device()]) + output = self.module.val_step(*inputs[0], **kwargs[0]) + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/registry.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/registry.py new file mode 100644 index 00000000..6ce151e5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/registry.py @@ -0,0 +1,8 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from torch.nn.parallel import DataParallel, DistributedDataParallel + +from annotator.mmpkg.mmcv.utils import Registry + +MODULE_WRAPPERS = Registry('module wrapper') +MODULE_WRAPPERS.register_module(module=DataParallel) +MODULE_WRAPPERS.register_module(module=DistributedDataParallel) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/scatter_gather.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/scatter_gather.py new file mode 100644 index 00000000..900ff885 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/scatter_gather.py @@ -0,0 +1,59 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +from torch.nn.parallel._functions import Scatter as OrigScatter + +from ._functions import Scatter +from .data_container import DataContainer + + +def scatter(inputs, target_gpus, dim=0): + """Scatter inputs to target gpus. + + The only difference from original :func:`scatter` is to add support for + :type:`~mmcv.parallel.DataContainer`. + """ + + def scatter_map(obj): + if isinstance(obj, torch.Tensor): + if target_gpus != [-1]: + return OrigScatter.apply(target_gpus, None, dim, obj) + else: + # for CPU inference we use self-implemented scatter + return Scatter.forward(target_gpus, obj) + if isinstance(obj, DataContainer): + if obj.cpu_only: + return obj.data + else: + return Scatter.forward(target_gpus, obj.data) + if isinstance(obj, tuple) and len(obj) > 0: + return list(zip(*map(scatter_map, obj))) + if isinstance(obj, list) and len(obj) > 0: + out = list(map(list, zip(*map(scatter_map, obj)))) + return out + if isinstance(obj, dict) and len(obj) > 0: + out = list(map(type(obj), zip(*map(scatter_map, obj.items())))) + return out + return [obj for targets in target_gpus] + + # After scatter_map is called, a scatter_map cell will exist. This cell + # has a reference to the actual function scatter_map, which has references + # to a closure that has a reference to the scatter_map cell (because the + # fn is recursive). To avoid this reference cycle, we set the function to + # None, clearing the cell + try: + return scatter_map(inputs) + finally: + scatter_map = None + + +def scatter_kwargs(inputs, kwargs, target_gpus, dim=0): + """Scatter with support for kwargs dictionary.""" + inputs = scatter(inputs, target_gpus, dim) if inputs else [] + kwargs = scatter(kwargs, target_gpus, dim) if kwargs else [] + if len(inputs) < len(kwargs): + inputs.extend([() for _ in range(len(kwargs) - len(inputs))]) + elif len(kwargs) < len(inputs): + kwargs.extend([{} for _ in range(len(inputs) - len(kwargs))]) + inputs = tuple(inputs) + kwargs = tuple(kwargs) + return inputs, kwargs diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/utils.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/utils.py new file mode 100644 index 00000000..0f5712cb --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/parallel/utils.py @@ -0,0 +1,20 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .registry import MODULE_WRAPPERS + + +def is_module_wrapper(module): + """Check if a module is a module wrapper. + + The following 3 modules in MMCV (and their subclasses) are regarded as + module wrappers: DataParallel, DistributedDataParallel, + MMDistributedDataParallel (the deprecated version). You may add you own + module wrapper by registering it to mmcv.parallel.MODULE_WRAPPERS. + + Args: + module (nn.Module): The module to be checked. + + Returns: + bool: True if the input module is a module wrapper. + """ + module_wrappers = tuple(MODULE_WRAPPERS.module_dict.values()) + return isinstance(module, module_wrappers) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/__init__.py new file mode 100644 index 00000000..52e4b48d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/__init__.py @@ -0,0 +1,47 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .base_module import BaseModule, ModuleList, Sequential +from .base_runner import BaseRunner +from .builder import RUNNERS, build_runner +from .checkpoint import (CheckpointLoader, _load_checkpoint, + _load_checkpoint_with_prefix, load_checkpoint, + load_state_dict, save_checkpoint, weights_to_cpu) +from .default_constructor import DefaultRunnerConstructor +from .dist_utils import (allreduce_grads, allreduce_params, get_dist_info, + init_dist, master_only) +from .epoch_based_runner import EpochBasedRunner, Runner +from .fp16_utils import LossScaler, auto_fp16, force_fp32, wrap_fp16_model +from .hooks import (HOOKS, CheckpointHook, ClosureHook, DistEvalHook, + DistSamplerSeedHook, DvcliveLoggerHook, EMAHook, EvalHook, + Fp16OptimizerHook, GradientCumulativeFp16OptimizerHook, + GradientCumulativeOptimizerHook, Hook, IterTimerHook, + LoggerHook, LrUpdaterHook, MlflowLoggerHook, + NeptuneLoggerHook, OptimizerHook, PaviLoggerHook, + SyncBuffersHook, TensorboardLoggerHook, TextLoggerHook, + WandbLoggerHook) +from .iter_based_runner import IterBasedRunner, IterLoader +from .log_buffer import LogBuffer +from .optimizer import (OPTIMIZER_BUILDERS, OPTIMIZERS, + DefaultOptimizerConstructor, build_optimizer, + build_optimizer_constructor) +from .priority import Priority, get_priority +from .utils import get_host_info, get_time_str, obj_from_dict, set_random_seed + +__all__ = [ + 'BaseRunner', 'Runner', 'EpochBasedRunner', 'IterBasedRunner', 'LogBuffer', + 'HOOKS', 'Hook', 'CheckpointHook', 'ClosureHook', 'LrUpdaterHook', + 'OptimizerHook', 'IterTimerHook', 'DistSamplerSeedHook', 'LoggerHook', + 'PaviLoggerHook', 'TextLoggerHook', 'TensorboardLoggerHook', + 'NeptuneLoggerHook', 'WandbLoggerHook', 'MlflowLoggerHook', + 'DvcliveLoggerHook', '_load_checkpoint', 'load_state_dict', + 'load_checkpoint', 'weights_to_cpu', 'save_checkpoint', 'Priority', + 'get_priority', 'get_host_info', 'get_time_str', 'obj_from_dict', + 'init_dist', 'get_dist_info', 'master_only', 'OPTIMIZER_BUILDERS', + 'OPTIMIZERS', 'DefaultOptimizerConstructor', 'build_optimizer', + 'build_optimizer_constructor', 'IterLoader', 'set_random_seed', + 'auto_fp16', 'force_fp32', 'wrap_fp16_model', 'Fp16OptimizerHook', + 'SyncBuffersHook', 'EMAHook', 'build_runner', 'RUNNERS', 'allreduce_grads', + 'allreduce_params', 'LossScaler', 'CheckpointLoader', 'BaseModule', + '_load_checkpoint_with_prefix', 'EvalHook', 'DistEvalHook', 'Sequential', + 'ModuleList', 'GradientCumulativeOptimizerHook', + 'GradientCumulativeFp16OptimizerHook', 'DefaultRunnerConstructor' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/base_module.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/base_module.py new file mode 100644 index 00000000..72e1164d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/base_module.py @@ -0,0 +1,195 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import copy +import warnings +from abc import ABCMeta +from collections import defaultdict +from logging import FileHandler + +import torch.nn as nn + +from annotator.mmpkg.mmcv.runner.dist_utils import master_only +from annotator.mmpkg.mmcv.utils.logging import get_logger, logger_initialized, print_log + + +class BaseModule(nn.Module, metaclass=ABCMeta): + """Base module for all modules in openmmlab. + + ``BaseModule`` is a wrapper of ``torch.nn.Module`` with additional + functionality of parameter initialization. Compared with + ``torch.nn.Module``, ``BaseModule`` mainly adds three attributes. + + - ``init_cfg``: the config to control the initialization. + - ``init_weights``: The function of parameter + initialization and recording initialization + information. + - ``_params_init_info``: Used to track the parameter + initialization information. This attribute only + exists during executing the ``init_weights``. + + Args: + init_cfg (dict, optional): Initialization config dict. + """ + + def __init__(self, init_cfg=None): + """Initialize BaseModule, inherited from `torch.nn.Module`""" + + # NOTE init_cfg can be defined in different levels, but init_cfg + # in low levels has a higher priority. + + super(BaseModule, self).__init__() + # define default value of init_cfg instead of hard code + # in init_weights() function + self._is_init = False + + self.init_cfg = copy.deepcopy(init_cfg) + + # Backward compatibility in derived classes + # if pretrained is not None: + # warnings.warn('DeprecationWarning: pretrained is a deprecated \ + # key, please consider using init_cfg') + # self.init_cfg = dict(type='Pretrained', checkpoint=pretrained) + + @property + def is_init(self): + return self._is_init + + def init_weights(self): + """Initialize the weights.""" + + is_top_level_module = False + # check if it is top-level module + if not hasattr(self, '_params_init_info'): + # The `_params_init_info` is used to record the initialization + # information of the parameters + # the key should be the obj:`nn.Parameter` of model and the value + # should be a dict containing + # - init_info (str): The string that describes the initialization. + # - tmp_mean_value (FloatTensor): The mean of the parameter, + # which indicates whether the parameter has been modified. + # this attribute would be deleted after all parameters + # is initialized. + self._params_init_info = defaultdict(dict) + is_top_level_module = True + + # Initialize the `_params_init_info`, + # When detecting the `tmp_mean_value` of + # the corresponding parameter is changed, update related + # initialization information + for name, param in self.named_parameters(): + self._params_init_info[param][ + 'init_info'] = f'The value is the same before and ' \ + f'after calling `init_weights` ' \ + f'of {self.__class__.__name__} ' + self._params_init_info[param][ + 'tmp_mean_value'] = param.data.mean() + + # pass `params_init_info` to all submodules + # All submodules share the same `params_init_info`, + # so it will be updated when parameters are + # modified at any level of the model. + for sub_module in self.modules(): + sub_module._params_init_info = self._params_init_info + + # Get the initialized logger, if not exist, + # create a logger named `mmcv` + logger_names = list(logger_initialized.keys()) + logger_name = logger_names[0] if logger_names else 'mmcv' + + from ..cnn import initialize + from ..cnn.utils.weight_init import update_init_info + module_name = self.__class__.__name__ + if not self._is_init: + if self.init_cfg: + print_log( + f'initialize {module_name} with init_cfg {self.init_cfg}', + logger=logger_name) + initialize(self, self.init_cfg) + if isinstance(self.init_cfg, dict): + # prevent the parameters of + # the pre-trained model + # from being overwritten by + # the `init_weights` + if self.init_cfg['type'] == 'Pretrained': + return + + for m in self.children(): + if hasattr(m, 'init_weights'): + m.init_weights() + # users may overload the `init_weights` + update_init_info( + m, + init_info=f'Initialized by ' + f'user-defined `init_weights`' + f' in {m.__class__.__name__} ') + + self._is_init = True + else: + warnings.warn(f'init_weights of {self.__class__.__name__} has ' + f'been called more than once.') + + if is_top_level_module: + self._dump_init_info(logger_name) + + for sub_module in self.modules(): + del sub_module._params_init_info + + @master_only + def _dump_init_info(self, logger_name): + """Dump the initialization information to a file named + `initialization.log.json` in workdir. + + Args: + logger_name (str): The name of logger. + """ + + logger = get_logger(logger_name) + + with_file_handler = False + # dump the information to the logger file if there is a `FileHandler` + for handler in logger.handlers: + if isinstance(handler, FileHandler): + handler.stream.write( + 'Name of parameter - Initialization information\n') + for name, param in self.named_parameters(): + handler.stream.write( + f'\n{name} - {param.shape}: ' + f"\n{self._params_init_info[param]['init_info']} \n") + handler.stream.flush() + with_file_handler = True + if not with_file_handler: + for name, param in self.named_parameters(): + print_log( + f'\n{name} - {param.shape}: ' + f"\n{self._params_init_info[param]['init_info']} \n ", + logger=logger_name) + + def __repr__(self): + s = super().__repr__() + if self.init_cfg: + s += f'\ninit_cfg={self.init_cfg}' + return s + + +class Sequential(BaseModule, nn.Sequential): + """Sequential module in openmmlab. + + Args: + init_cfg (dict, optional): Initialization config dict. + """ + + def __init__(self, *args, init_cfg=None): + BaseModule.__init__(self, init_cfg) + nn.Sequential.__init__(self, *args) + + +class ModuleList(BaseModule, nn.ModuleList): + """ModuleList in openmmlab. + + Args: + modules (iterable, optional): an iterable of modules to add. + init_cfg (dict, optional): Initialization config dict. + """ + + def __init__(self, modules=None, init_cfg=None): + BaseModule.__init__(self, init_cfg) + nn.ModuleList.__init__(self, modules) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/base_runner.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/base_runner.py new file mode 100644 index 00000000..a75a7d5d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/base_runner.py @@ -0,0 +1,542 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import copy +import logging +import os.path as osp +import warnings +from abc import ABCMeta, abstractmethod + +import torch +from torch.optim import Optimizer + +import annotator.mmpkg.mmcv as mmcv +from ..parallel import is_module_wrapper +from .checkpoint import load_checkpoint +from .dist_utils import get_dist_info +from .hooks import HOOKS, Hook +from .log_buffer import LogBuffer +from .priority import Priority, get_priority +from .utils import get_time_str + + +class BaseRunner(metaclass=ABCMeta): + """The base class of Runner, a training helper for PyTorch. + + All subclasses should implement the following APIs: + + - ``run()`` + - ``train()`` + - ``val()`` + - ``save_checkpoint()`` + + Args: + model (:obj:`torch.nn.Module`): The model to be run. + batch_processor (callable): A callable method that process a data + batch. The interface of this method should be + `batch_processor(model, data, train_mode) -> dict` + optimizer (dict or :obj:`torch.optim.Optimizer`): It can be either an + optimizer (in most cases) or a dict of optimizers (in models that + requires more than one optimizer, e.g., GAN). + work_dir (str, optional): The working directory to save checkpoints + and logs. Defaults to None. + logger (:obj:`logging.Logger`): Logger used during training. + Defaults to None. (The default value is just for backward + compatibility) + meta (dict | None): A dict records some import information such as + environment info and seed, which will be logged in logger hook. + Defaults to None. + max_epochs (int, optional): Total training epochs. + max_iters (int, optional): Total training iterations. + """ + + def __init__(self, + model, + batch_processor=None, + optimizer=None, + work_dir=None, + logger=None, + meta=None, + max_iters=None, + max_epochs=None): + if batch_processor is not None: + if not callable(batch_processor): + raise TypeError('batch_processor must be callable, ' + f'but got {type(batch_processor)}') + warnings.warn('batch_processor is deprecated, please implement ' + 'train_step() and val_step() in the model instead.') + # raise an error is `batch_processor` is not None and + # `model.train_step()` exists. + if is_module_wrapper(model): + _model = model.module + else: + _model = model + if hasattr(_model, 'train_step') or hasattr(_model, 'val_step'): + raise RuntimeError( + 'batch_processor and model.train_step()/model.val_step() ' + 'cannot be both available.') + else: + assert hasattr(model, 'train_step') + + # check the type of `optimizer` + if isinstance(optimizer, dict): + for name, optim in optimizer.items(): + if not isinstance(optim, Optimizer): + raise TypeError( + f'optimizer must be a dict of torch.optim.Optimizers, ' + f'but optimizer["{name}"] is a {type(optim)}') + elif not isinstance(optimizer, Optimizer) and optimizer is not None: + raise TypeError( + f'optimizer must be a torch.optim.Optimizer object ' + f'or dict or None, but got {type(optimizer)}') + + # check the type of `logger` + if not isinstance(logger, logging.Logger): + raise TypeError(f'logger must be a logging.Logger object, ' + f'but got {type(logger)}') + + # check the type of `meta` + if meta is not None and not isinstance(meta, dict): + raise TypeError( + f'meta must be a dict or None, but got {type(meta)}') + + self.model = model + self.batch_processor = batch_processor + self.optimizer = optimizer + self.logger = logger + self.meta = meta + # create work_dir + if mmcv.is_str(work_dir): + self.work_dir = osp.abspath(work_dir) + mmcv.mkdir_or_exist(self.work_dir) + elif work_dir is None: + self.work_dir = None + else: + raise TypeError('"work_dir" must be a str or None') + + # get model name from the model class + if hasattr(self.model, 'module'): + self._model_name = self.model.module.__class__.__name__ + else: + self._model_name = self.model.__class__.__name__ + + self._rank, self._world_size = get_dist_info() + self.timestamp = get_time_str() + self.mode = None + self._hooks = [] + self._epoch = 0 + self._iter = 0 + self._inner_iter = 0 + + if max_epochs is not None and max_iters is not None: + raise ValueError( + 'Only one of `max_epochs` or `max_iters` can be set.') + + self._max_epochs = max_epochs + self._max_iters = max_iters + # TODO: Redesign LogBuffer, it is not flexible and elegant enough + self.log_buffer = LogBuffer() + + @property + def model_name(self): + """str: Name of the model, usually the module class name.""" + return self._model_name + + @property + def rank(self): + """int: Rank of current process. (distributed training)""" + return self._rank + + @property + def world_size(self): + """int: Number of processes participating in the job. + (distributed training)""" + return self._world_size + + @property + def hooks(self): + """list[:obj:`Hook`]: A list of registered hooks.""" + return self._hooks + + @property + def epoch(self): + """int: Current epoch.""" + return self._epoch + + @property + def iter(self): + """int: Current iteration.""" + return self._iter + + @property + def inner_iter(self): + """int: Iteration in an epoch.""" + return self._inner_iter + + @property + def max_epochs(self): + """int: Maximum training epochs.""" + return self._max_epochs + + @property + def max_iters(self): + """int: Maximum training iterations.""" + return self._max_iters + + @abstractmethod + def train(self): + pass + + @abstractmethod + def val(self): + pass + + @abstractmethod + def run(self, data_loaders, workflow, **kwargs): + pass + + @abstractmethod + def save_checkpoint(self, + out_dir, + filename_tmpl, + save_optimizer=True, + meta=None, + create_symlink=True): + pass + + def current_lr(self): + """Get current learning rates. + + Returns: + list[float] | dict[str, list[float]]: Current learning rates of all + param groups. If the runner has a dict of optimizers, this + method will return a dict. + """ + if isinstance(self.optimizer, torch.optim.Optimizer): + lr = [group['lr'] for group in self.optimizer.param_groups] + elif isinstance(self.optimizer, dict): + lr = dict() + for name, optim in self.optimizer.items(): + lr[name] = [group['lr'] for group in optim.param_groups] + else: + raise RuntimeError( + 'lr is not applicable because optimizer does not exist.') + return lr + + def current_momentum(self): + """Get current momentums. + + Returns: + list[float] | dict[str, list[float]]: Current momentums of all + param groups. If the runner has a dict of optimizers, this + method will return a dict. + """ + + def _get_momentum(optimizer): + momentums = [] + for group in optimizer.param_groups: + if 'momentum' in group.keys(): + momentums.append(group['momentum']) + elif 'betas' in group.keys(): + momentums.append(group['betas'][0]) + else: + momentums.append(0) + return momentums + + if self.optimizer is None: + raise RuntimeError( + 'momentum is not applicable because optimizer does not exist.') + elif isinstance(self.optimizer, torch.optim.Optimizer): + momentums = _get_momentum(self.optimizer) + elif isinstance(self.optimizer, dict): + momentums = dict() + for name, optim in self.optimizer.items(): + momentums[name] = _get_momentum(optim) + return momentums + + def register_hook(self, hook, priority='NORMAL'): + """Register a hook into the hook list. + + The hook will be inserted into a priority queue, with the specified + priority (See :class:`Priority` for details of priorities). + For hooks with the same priority, they will be triggered in the same + order as they are registered. + + Args: + hook (:obj:`Hook`): The hook to be registered. + priority (int or str or :obj:`Priority`): Hook priority. + Lower value means higher priority. + """ + assert isinstance(hook, Hook) + if hasattr(hook, 'priority'): + raise ValueError('"priority" is a reserved attribute for hooks') + priority = get_priority(priority) + hook.priority = priority + # insert the hook to a sorted list + inserted = False + for i in range(len(self._hooks) - 1, -1, -1): + if priority >= self._hooks[i].priority: + self._hooks.insert(i + 1, hook) + inserted = True + break + if not inserted: + self._hooks.insert(0, hook) + + def register_hook_from_cfg(self, hook_cfg): + """Register a hook from its cfg. + + Args: + hook_cfg (dict): Hook config. It should have at least keys 'type' + and 'priority' indicating its type and priority. + + Notes: + The specific hook class to register should not use 'type' and + 'priority' arguments during initialization. + """ + hook_cfg = hook_cfg.copy() + priority = hook_cfg.pop('priority', 'NORMAL') + hook = mmcv.build_from_cfg(hook_cfg, HOOKS) + self.register_hook(hook, priority=priority) + + def call_hook(self, fn_name): + """Call all hooks. + + Args: + fn_name (str): The function name in each hook to be called, such as + "before_train_epoch". + """ + for hook in self._hooks: + getattr(hook, fn_name)(self) + + def get_hook_info(self): + # Get hooks info in each stage + stage_hook_map = {stage: [] for stage in Hook.stages} + for hook in self.hooks: + try: + priority = Priority(hook.priority).name + except ValueError: + priority = hook.priority + classname = hook.__class__.__name__ + hook_info = f'({priority:<12}) {classname:<35}' + for trigger_stage in hook.get_triggered_stages(): + stage_hook_map[trigger_stage].append(hook_info) + + stage_hook_infos = [] + for stage in Hook.stages: + hook_infos = stage_hook_map[stage] + if len(hook_infos) > 0: + info = f'{stage}:\n' + info += '\n'.join(hook_infos) + info += '\n -------------------- ' + stage_hook_infos.append(info) + return '\n'.join(stage_hook_infos) + + def load_checkpoint(self, + filename, + map_location='cpu', + strict=False, + revise_keys=[(r'^module.', '')]): + return load_checkpoint( + self.model, + filename, + map_location, + strict, + self.logger, + revise_keys=revise_keys) + + def resume(self, + checkpoint, + resume_optimizer=True, + map_location='default'): + if map_location == 'default': + if torch.cuda.is_available(): + device_id = torch.cuda.current_device() + checkpoint = self.load_checkpoint( + checkpoint, + map_location=lambda storage, loc: storage.cuda(device_id)) + else: + checkpoint = self.load_checkpoint(checkpoint) + else: + checkpoint = self.load_checkpoint( + checkpoint, map_location=map_location) + + self._epoch = checkpoint['meta']['epoch'] + self._iter = checkpoint['meta']['iter'] + if self.meta is None: + self.meta = {} + self.meta.setdefault('hook_msgs', {}) + # load `last_ckpt`, `best_score`, `best_ckpt`, etc. for hook messages + self.meta['hook_msgs'].update(checkpoint['meta'].get('hook_msgs', {})) + + # Re-calculate the number of iterations when resuming + # models with different number of GPUs + if 'config' in checkpoint['meta']: + config = mmcv.Config.fromstring( + checkpoint['meta']['config'], file_format='.py') + previous_gpu_ids = config.get('gpu_ids', None) + if previous_gpu_ids and len(previous_gpu_ids) > 0 and len( + previous_gpu_ids) != self.world_size: + self._iter = int(self._iter * len(previous_gpu_ids) / + self.world_size) + self.logger.info('the iteration number is changed due to ' + 'change of GPU number') + + # resume meta information meta + self.meta = checkpoint['meta'] + + if 'optimizer' in checkpoint and resume_optimizer: + if isinstance(self.optimizer, Optimizer): + self.optimizer.load_state_dict(checkpoint['optimizer']) + elif isinstance(self.optimizer, dict): + for k in self.optimizer.keys(): + self.optimizer[k].load_state_dict( + checkpoint['optimizer'][k]) + else: + raise TypeError( + 'Optimizer should be dict or torch.optim.Optimizer ' + f'but got {type(self.optimizer)}') + + self.logger.info('resumed epoch %d, iter %d', self.epoch, self.iter) + + def register_lr_hook(self, lr_config): + if lr_config is None: + return + elif isinstance(lr_config, dict): + assert 'policy' in lr_config + policy_type = lr_config.pop('policy') + # If the type of policy is all in lower case, e.g., 'cyclic', + # then its first letter will be capitalized, e.g., to be 'Cyclic'. + # This is for the convenient usage of Lr updater. + # Since this is not applicable for ` + # CosineAnnealingLrUpdater`, + # the string will not be changed if it contains capital letters. + if policy_type == policy_type.lower(): + policy_type = policy_type.title() + hook_type = policy_type + 'LrUpdaterHook' + lr_config['type'] = hook_type + hook = mmcv.build_from_cfg(lr_config, HOOKS) + else: + hook = lr_config + self.register_hook(hook, priority='VERY_HIGH') + + def register_momentum_hook(self, momentum_config): + if momentum_config is None: + return + if isinstance(momentum_config, dict): + assert 'policy' in momentum_config + policy_type = momentum_config.pop('policy') + # If the type of policy is all in lower case, e.g., 'cyclic', + # then its first letter will be capitalized, e.g., to be 'Cyclic'. + # This is for the convenient usage of momentum updater. + # Since this is not applicable for + # `CosineAnnealingMomentumUpdater`, + # the string will not be changed if it contains capital letters. + if policy_type == policy_type.lower(): + policy_type = policy_type.title() + hook_type = policy_type + 'MomentumUpdaterHook' + momentum_config['type'] = hook_type + hook = mmcv.build_from_cfg(momentum_config, HOOKS) + else: + hook = momentum_config + self.register_hook(hook, priority='HIGH') + + def register_optimizer_hook(self, optimizer_config): + if optimizer_config is None: + return + if isinstance(optimizer_config, dict): + optimizer_config.setdefault('type', 'OptimizerHook') + hook = mmcv.build_from_cfg(optimizer_config, HOOKS) + else: + hook = optimizer_config + self.register_hook(hook, priority='ABOVE_NORMAL') + + def register_checkpoint_hook(self, checkpoint_config): + if checkpoint_config is None: + return + if isinstance(checkpoint_config, dict): + checkpoint_config.setdefault('type', 'CheckpointHook') + hook = mmcv.build_from_cfg(checkpoint_config, HOOKS) + else: + hook = checkpoint_config + self.register_hook(hook, priority='NORMAL') + + def register_logger_hooks(self, log_config): + if log_config is None: + return + log_interval = log_config['interval'] + for info in log_config['hooks']: + logger_hook = mmcv.build_from_cfg( + info, HOOKS, default_args=dict(interval=log_interval)) + self.register_hook(logger_hook, priority='VERY_LOW') + + def register_timer_hook(self, timer_config): + if timer_config is None: + return + if isinstance(timer_config, dict): + timer_config_ = copy.deepcopy(timer_config) + hook = mmcv.build_from_cfg(timer_config_, HOOKS) + else: + hook = timer_config + self.register_hook(hook, priority='LOW') + + def register_custom_hooks(self, custom_config): + if custom_config is None: + return + + if not isinstance(custom_config, list): + custom_config = [custom_config] + + for item in custom_config: + if isinstance(item, dict): + self.register_hook_from_cfg(item) + else: + self.register_hook(item, priority='NORMAL') + + def register_profiler_hook(self, profiler_config): + if profiler_config is None: + return + if isinstance(profiler_config, dict): + profiler_config.setdefault('type', 'ProfilerHook') + hook = mmcv.build_from_cfg(profiler_config, HOOKS) + else: + hook = profiler_config + self.register_hook(hook) + + def register_training_hooks(self, + lr_config, + optimizer_config=None, + checkpoint_config=None, + log_config=None, + momentum_config=None, + timer_config=dict(type='IterTimerHook'), + custom_hooks_config=None): + """Register default and custom hooks for training. + + Default and custom hooks include: + + +----------------------+-------------------------+ + | Hooks | Priority | + +======================+=========================+ + | LrUpdaterHook | VERY_HIGH (10) | + +----------------------+-------------------------+ + | MomentumUpdaterHook | HIGH (30) | + +----------------------+-------------------------+ + | OptimizerStepperHook | ABOVE_NORMAL (40) | + +----------------------+-------------------------+ + | CheckpointSaverHook | NORMAL (50) | + +----------------------+-------------------------+ + | IterTimerHook | LOW (70) | + +----------------------+-------------------------+ + | LoggerHook(s) | VERY_LOW (90) | + +----------------------+-------------------------+ + | CustomHook(s) | defaults to NORMAL (50) | + +----------------------+-------------------------+ + + If custom hooks have same priority with default hooks, custom hooks + will be triggered after default hooks. + """ + self.register_lr_hook(lr_config) + self.register_momentum_hook(momentum_config) + self.register_optimizer_hook(optimizer_config) + self.register_checkpoint_hook(checkpoint_config) + self.register_timer_hook(timer_config) + self.register_logger_hooks(log_config) + self.register_custom_hooks(custom_hooks_config) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/builder.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/builder.py new file mode 100644 index 00000000..77c96ba0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/builder.py @@ -0,0 +1,24 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import copy + +from ..utils import Registry + +RUNNERS = Registry('runner') +RUNNER_BUILDERS = Registry('runner builder') + + +def build_runner_constructor(cfg): + return RUNNER_BUILDERS.build(cfg) + + +def build_runner(cfg, default_args=None): + runner_cfg = copy.deepcopy(cfg) + constructor_type = runner_cfg.pop('constructor', + 'DefaultRunnerConstructor') + runner_constructor = build_runner_constructor( + dict( + type=constructor_type, + runner_cfg=runner_cfg, + default_args=default_args)) + runner = runner_constructor() + return runner diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/checkpoint.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/checkpoint.py new file mode 100644 index 00000000..d690be1d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/checkpoint.py @@ -0,0 +1,707 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import io +import os +import os.path as osp +import pkgutil +import re +import time +import warnings +from collections import OrderedDict +from importlib import import_module +from tempfile import TemporaryDirectory + +import torch +import torchvision +from torch.optim import Optimizer +from torch.utils import model_zoo + +import annotator.mmpkg.mmcv as mmcv +from ..fileio import FileClient +from ..fileio import load as load_file +from ..parallel import is_module_wrapper +from ..utils import mkdir_or_exist +from .dist_utils import get_dist_info + +ENV_MMCV_HOME = 'MMCV_HOME' +ENV_XDG_CACHE_HOME = 'XDG_CACHE_HOME' +DEFAULT_CACHE_DIR = '~/.cache' + + +def _get_mmcv_home(): + mmcv_home = os.path.expanduser( + os.getenv( + ENV_MMCV_HOME, + os.path.join( + os.getenv(ENV_XDG_CACHE_HOME, DEFAULT_CACHE_DIR), 'mmcv'))) + + mkdir_or_exist(mmcv_home) + return mmcv_home + + +def load_state_dict(module, state_dict, strict=False, logger=None): + """Load state_dict to a module. + + This method is modified from :meth:`torch.nn.Module.load_state_dict`. + Default value for ``strict`` is set to ``False`` and the message for + param mismatch will be shown even if strict is False. + + Args: + module (Module): Module that receives the state_dict. + state_dict (OrderedDict): Weights. + strict (bool): whether to strictly enforce that the keys + in :attr:`state_dict` match the keys returned by this module's + :meth:`~torch.nn.Module.state_dict` function. Default: ``False``. + logger (:obj:`logging.Logger`, optional): Logger to log the error + message. If not specified, print function will be used. + """ + unexpected_keys = [] + all_missing_keys = [] + err_msg = [] + + metadata = getattr(state_dict, '_metadata', None) + state_dict = state_dict.copy() + if metadata is not None: + state_dict._metadata = metadata + + # use _load_from_state_dict to enable checkpoint version control + def load(module, prefix=''): + # recursively check parallel module in case that the model has a + # complicated structure, e.g., nn.Module(nn.Module(DDP)) + if is_module_wrapper(module): + module = module.module + local_metadata = {} if metadata is None else metadata.get( + prefix[:-1], {}) + module._load_from_state_dict(state_dict, prefix, local_metadata, True, + all_missing_keys, unexpected_keys, + err_msg) + for name, child in module._modules.items(): + if child is not None: + load(child, prefix + name + '.') + + load(module) + load = None # break load->load reference cycle + + # ignore "num_batches_tracked" of BN layers + missing_keys = [ + key for key in all_missing_keys if 'num_batches_tracked' not in key + ] + + if unexpected_keys: + err_msg.append('unexpected key in source ' + f'state_dict: {", ".join(unexpected_keys)}\n') + if missing_keys: + err_msg.append( + f'missing keys in source state_dict: {", ".join(missing_keys)}\n') + + rank, _ = get_dist_info() + if len(err_msg) > 0 and rank == 0: + err_msg.insert( + 0, 'The model and loaded state dict do not match exactly\n') + err_msg = '\n'.join(err_msg) + if strict: + raise RuntimeError(err_msg) + elif logger is not None: + logger.warning(err_msg) + else: + print(err_msg) + + +def get_torchvision_models(): + model_urls = dict() + for _, name, ispkg in pkgutil.walk_packages(torchvision.models.__path__): + if ispkg: + continue + _zoo = import_module(f'torchvision.models.{name}') + if hasattr(_zoo, 'model_urls'): + _urls = getattr(_zoo, 'model_urls') + model_urls.update(_urls) + return model_urls + + +def get_external_models(): + mmcv_home = _get_mmcv_home() + default_json_path = osp.join(mmcv.__path__[0], 'model_zoo/open_mmlab.json') + default_urls = load_file(default_json_path) + assert isinstance(default_urls, dict) + external_json_path = osp.join(mmcv_home, 'open_mmlab.json') + if osp.exists(external_json_path): + external_urls = load_file(external_json_path) + assert isinstance(external_urls, dict) + default_urls.update(external_urls) + + return default_urls + + +def get_mmcls_models(): + mmcls_json_path = osp.join(mmcv.__path__[0], 'model_zoo/mmcls.json') + mmcls_urls = load_file(mmcls_json_path) + + return mmcls_urls + + +def get_deprecated_model_names(): + deprecate_json_path = osp.join(mmcv.__path__[0], + 'model_zoo/deprecated.json') + deprecate_urls = load_file(deprecate_json_path) + assert isinstance(deprecate_urls, dict) + + return deprecate_urls + + +def _process_mmcls_checkpoint(checkpoint): + state_dict = checkpoint['state_dict'] + new_state_dict = OrderedDict() + for k, v in state_dict.items(): + if k.startswith('backbone.'): + new_state_dict[k[9:]] = v + new_checkpoint = dict(state_dict=new_state_dict) + + return new_checkpoint + + +class CheckpointLoader: + """A general checkpoint loader to manage all schemes.""" + + _schemes = {} + + @classmethod + def _register_scheme(cls, prefixes, loader, force=False): + if isinstance(prefixes, str): + prefixes = [prefixes] + else: + assert isinstance(prefixes, (list, tuple)) + for prefix in prefixes: + if (prefix not in cls._schemes) or force: + cls._schemes[prefix] = loader + else: + raise KeyError( + f'{prefix} is already registered as a loader backend, ' + 'add "force=True" if you want to override it') + # sort, longer prefixes take priority + cls._schemes = OrderedDict( + sorted(cls._schemes.items(), key=lambda t: t[0], reverse=True)) + + @classmethod + def register_scheme(cls, prefixes, loader=None, force=False): + """Register a loader to CheckpointLoader. + + This method can be used as a normal class method or a decorator. + + Args: + prefixes (str or list[str] or tuple[str]): + The prefix of the registered loader. + loader (function, optional): The loader function to be registered. + When this method is used as a decorator, loader is None. + Defaults to None. + force (bool, optional): Whether to override the loader + if the prefix has already been registered. Defaults to False. + """ + + if loader is not None: + cls._register_scheme(prefixes, loader, force=force) + return + + def _register(loader_cls): + cls._register_scheme(prefixes, loader_cls, force=force) + return loader_cls + + return _register + + @classmethod + def _get_checkpoint_loader(cls, path): + """Finds a loader that supports the given path. Falls back to the local + loader if no other loader is found. + + Args: + path (str): checkpoint path + + Returns: + loader (function): checkpoint loader + """ + + for p in cls._schemes: + if path.startswith(p): + return cls._schemes[p] + + @classmethod + def load_checkpoint(cls, filename, map_location=None, logger=None): + """load checkpoint through URL scheme path. + + Args: + filename (str): checkpoint file name with given prefix + map_location (str, optional): Same as :func:`torch.load`. + Default: None + logger (:mod:`logging.Logger`, optional): The logger for message. + Default: None + + Returns: + dict or OrderedDict: The loaded checkpoint. + """ + + checkpoint_loader = cls._get_checkpoint_loader(filename) + class_name = checkpoint_loader.__name__ + mmcv.print_log( + f'load checkpoint from {class_name[10:]} path: {filename}', logger) + return checkpoint_loader(filename, map_location) + + +@CheckpointLoader.register_scheme(prefixes='') +def load_from_local(filename, map_location): + """load checkpoint by local file path. + + Args: + filename (str): local checkpoint file path + map_location (str, optional): Same as :func:`torch.load`. + + Returns: + dict or OrderedDict: The loaded checkpoint. + """ + + if not osp.isfile(filename): + raise IOError(f'{filename} is not a checkpoint file') + checkpoint = torch.load(filename, map_location=map_location) + return checkpoint + + +@CheckpointLoader.register_scheme(prefixes=('http://', 'https://')) +def load_from_http(filename, map_location=None, model_dir=None): + """load checkpoint through HTTP or HTTPS scheme path. In distributed + setting, this function only download checkpoint at local rank 0. + + Args: + filename (str): checkpoint file path with modelzoo or + torchvision prefix + map_location (str, optional): Same as :func:`torch.load`. + model_dir (string, optional): directory in which to save the object, + Default: None + + Returns: + dict or OrderedDict: The loaded checkpoint. + """ + rank, world_size = get_dist_info() + rank = int(os.environ.get('LOCAL_RANK', rank)) + if rank == 0: + checkpoint = model_zoo.load_url( + filename, model_dir=model_dir, map_location=map_location) + if world_size > 1: + torch.distributed.barrier() + if rank > 0: + checkpoint = model_zoo.load_url( + filename, model_dir=model_dir, map_location=map_location) + return checkpoint + + +@CheckpointLoader.register_scheme(prefixes='pavi://') +def load_from_pavi(filename, map_location=None): + """load checkpoint through the file path prefixed with pavi. In distributed + setting, this function download ckpt at all ranks to different temporary + directories. + + Args: + filename (str): checkpoint file path with pavi prefix + map_location (str, optional): Same as :func:`torch.load`. + Default: None + + Returns: + dict or OrderedDict: The loaded checkpoint. + """ + assert filename.startswith('pavi://'), \ + f'Expected filename startswith `pavi://`, but get {filename}' + model_path = filename[7:] + + try: + from pavi import modelcloud + except ImportError: + raise ImportError( + 'Please install pavi to load checkpoint from modelcloud.') + + model = modelcloud.get(model_path) + with TemporaryDirectory() as tmp_dir: + downloaded_file = osp.join(tmp_dir, model.name) + model.download(downloaded_file) + checkpoint = torch.load(downloaded_file, map_location=map_location) + return checkpoint + + +@CheckpointLoader.register_scheme(prefixes='s3://') +def load_from_ceph(filename, map_location=None, backend='petrel'): + """load checkpoint through the file path prefixed with s3. In distributed + setting, this function download ckpt at all ranks to different temporary + directories. + + Args: + filename (str): checkpoint file path with s3 prefix + map_location (str, optional): Same as :func:`torch.load`. + backend (str, optional): The storage backend type. Options are 'ceph', + 'petrel'. Default: 'petrel'. + + .. warning:: + :class:`mmcv.fileio.file_client.CephBackend` will be deprecated, + please use :class:`mmcv.fileio.file_client.PetrelBackend` instead. + + Returns: + dict or OrderedDict: The loaded checkpoint. + """ + allowed_backends = ['ceph', 'petrel'] + if backend not in allowed_backends: + raise ValueError(f'Load from Backend {backend} is not supported.') + + if backend == 'ceph': + warnings.warn( + 'CephBackend will be deprecated, please use PetrelBackend instead') + + # CephClient and PetrelBackend have the same prefix 's3://' and the latter + # will be chosen as default. If PetrelBackend can not be instantiated + # successfully, the CephClient will be chosen. + try: + file_client = FileClient(backend=backend) + except ImportError: + allowed_backends.remove(backend) + file_client = FileClient(backend=allowed_backends[0]) + + with io.BytesIO(file_client.get(filename)) as buffer: + checkpoint = torch.load(buffer, map_location=map_location) + return checkpoint + + +@CheckpointLoader.register_scheme(prefixes=('modelzoo://', 'torchvision://')) +def load_from_torchvision(filename, map_location=None): + """load checkpoint through the file path prefixed with modelzoo or + torchvision. + + Args: + filename (str): checkpoint file path with modelzoo or + torchvision prefix + map_location (str, optional): Same as :func:`torch.load`. + + Returns: + dict or OrderedDict: The loaded checkpoint. + """ + model_urls = get_torchvision_models() + if filename.startswith('modelzoo://'): + warnings.warn('The URL scheme of "modelzoo://" is deprecated, please ' + 'use "torchvision://" instead') + model_name = filename[11:] + else: + model_name = filename[14:] + return load_from_http(model_urls[model_name], map_location=map_location) + + +@CheckpointLoader.register_scheme(prefixes=('open-mmlab://', 'openmmlab://')) +def load_from_openmmlab(filename, map_location=None): + """load checkpoint through the file path prefixed with open-mmlab or + openmmlab. + + Args: + filename (str): checkpoint file path with open-mmlab or + openmmlab prefix + map_location (str, optional): Same as :func:`torch.load`. + Default: None + + Returns: + dict or OrderedDict: The loaded checkpoint. + """ + + model_urls = get_external_models() + prefix_str = 'open-mmlab://' + if filename.startswith(prefix_str): + model_name = filename[13:] + else: + model_name = filename[12:] + prefix_str = 'openmmlab://' + + deprecated_urls = get_deprecated_model_names() + if model_name in deprecated_urls: + warnings.warn(f'{prefix_str}{model_name} is deprecated in favor ' + f'of {prefix_str}{deprecated_urls[model_name]}') + model_name = deprecated_urls[model_name] + model_url = model_urls[model_name] + # check if is url + if model_url.startswith(('http://', 'https://')): + checkpoint = load_from_http(model_url, map_location=map_location) + else: + filename = osp.join(_get_mmcv_home(), model_url) + if not osp.isfile(filename): + raise IOError(f'{filename} is not a checkpoint file') + checkpoint = torch.load(filename, map_location=map_location) + return checkpoint + + +@CheckpointLoader.register_scheme(prefixes='mmcls://') +def load_from_mmcls(filename, map_location=None): + """load checkpoint through the file path prefixed with mmcls. + + Args: + filename (str): checkpoint file path with mmcls prefix + map_location (str, optional): Same as :func:`torch.load`. + + Returns: + dict or OrderedDict: The loaded checkpoint. + """ + + model_urls = get_mmcls_models() + model_name = filename[8:] + checkpoint = load_from_http( + model_urls[model_name], map_location=map_location) + checkpoint = _process_mmcls_checkpoint(checkpoint) + return checkpoint + + +def _load_checkpoint(filename, map_location=None, logger=None): + """Load checkpoint from somewhere (modelzoo, file, url). + + Args: + filename (str): Accept local filepath, URL, ``torchvision://xxx``, + ``open-mmlab://xxx``. Please refer to ``docs/model_zoo.md`` for + details. + map_location (str, optional): Same as :func:`torch.load`. + Default: None. + logger (:mod:`logging.Logger`, optional): The logger for error message. + Default: None + + Returns: + dict or OrderedDict: The loaded checkpoint. It can be either an + OrderedDict storing model weights or a dict containing other + information, which depends on the checkpoint. + """ + return CheckpointLoader.load_checkpoint(filename, map_location, logger) + + +def _load_checkpoint_with_prefix(prefix, filename, map_location=None): + """Load partial pretrained model with specific prefix. + + Args: + prefix (str): The prefix of sub-module. + filename (str): Accept local filepath, URL, ``torchvision://xxx``, + ``open-mmlab://xxx``. Please refer to ``docs/model_zoo.md`` for + details. + map_location (str | None): Same as :func:`torch.load`. Default: None. + + Returns: + dict or OrderedDict: The loaded checkpoint. + """ + + checkpoint = _load_checkpoint(filename, map_location=map_location) + + if 'state_dict' in checkpoint: + state_dict = checkpoint['state_dict'] + else: + state_dict = checkpoint + if not prefix.endswith('.'): + prefix += '.' + prefix_len = len(prefix) + + state_dict = { + k[prefix_len:]: v + for k, v in state_dict.items() if k.startswith(prefix) + } + + assert state_dict, f'{prefix} is not in the pretrained model' + return state_dict + + +def load_checkpoint(model, + filename, + map_location=None, + strict=False, + logger=None, + revise_keys=[(r'^module\.', '')]): + """Load checkpoint from a file or URI. + + Args: + model (Module): Module to load checkpoint. + filename (str): Accept local filepath, URL, ``torchvision://xxx``, + ``open-mmlab://xxx``. Please refer to ``docs/model_zoo.md`` for + details. + map_location (str): Same as :func:`torch.load`. + strict (bool): Whether to allow different params for the model and + checkpoint. + logger (:mod:`logging.Logger` or None): The logger for error message. + revise_keys (list): A list of customized keywords to modify the + state_dict in checkpoint. Each item is a (pattern, replacement) + pair of the regular expression operations. Default: strip + the prefix 'module.' by [(r'^module\\.', '')]. + + Returns: + dict or OrderedDict: The loaded checkpoint. + """ + checkpoint = _load_checkpoint(filename, map_location, logger) + # OrderedDict is a subclass of dict + if not isinstance(checkpoint, dict): + raise RuntimeError( + f'No state_dict found in checkpoint file {filename}') + # get state_dict from checkpoint + if 'state_dict' in checkpoint: + state_dict = checkpoint['state_dict'] + else: + state_dict = checkpoint + + # strip prefix of state_dict + metadata = getattr(state_dict, '_metadata', OrderedDict()) + for p, r in revise_keys: + state_dict = OrderedDict( + {re.sub(p, r, k): v + for k, v in state_dict.items()}) + # Keep metadata in state_dict + state_dict._metadata = metadata + + # load state_dict + load_state_dict(model, state_dict, strict, logger) + return checkpoint + + +def weights_to_cpu(state_dict): + """Copy a model state_dict to cpu. + + Args: + state_dict (OrderedDict): Model weights on GPU. + + Returns: + OrderedDict: Model weights on GPU. + """ + state_dict_cpu = OrderedDict() + for key, val in state_dict.items(): + state_dict_cpu[key] = val.cpu() + # Keep metadata in state_dict + state_dict_cpu._metadata = getattr(state_dict, '_metadata', OrderedDict()) + return state_dict_cpu + + +def _save_to_state_dict(module, destination, prefix, keep_vars): + """Saves module state to `destination` dictionary. + + This method is modified from :meth:`torch.nn.Module._save_to_state_dict`. + + Args: + module (nn.Module): The module to generate state_dict. + destination (dict): A dict where state will be stored. + prefix (str): The prefix for parameters and buffers used in this + module. + """ + for name, param in module._parameters.items(): + if param is not None: + destination[prefix + name] = param if keep_vars else param.detach() + for name, buf in module._buffers.items(): + # remove check of _non_persistent_buffers_set to allow nn.BatchNorm2d + if buf is not None: + destination[prefix + name] = buf if keep_vars else buf.detach() + + +def get_state_dict(module, destination=None, prefix='', keep_vars=False): + """Returns a dictionary containing a whole state of the module. + + Both parameters and persistent buffers (e.g. running averages) are + included. Keys are corresponding parameter and buffer names. + + This method is modified from :meth:`torch.nn.Module.state_dict` to + recursively check parallel module in case that the model has a complicated + structure, e.g., nn.Module(nn.Module(DDP)). + + Args: + module (nn.Module): The module to generate state_dict. + destination (OrderedDict): Returned dict for the state of the + module. + prefix (str): Prefix of the key. + keep_vars (bool): Whether to keep the variable property of the + parameters. Default: False. + + Returns: + dict: A dictionary containing a whole state of the module. + """ + # recursively check parallel module in case that the model has a + # complicated structure, e.g., nn.Module(nn.Module(DDP)) + if is_module_wrapper(module): + module = module.module + + # below is the same as torch.nn.Module.state_dict() + if destination is None: + destination = OrderedDict() + destination._metadata = OrderedDict() + destination._metadata[prefix[:-1]] = local_metadata = dict( + version=module._version) + _save_to_state_dict(module, destination, prefix, keep_vars) + for name, child in module._modules.items(): + if child is not None: + get_state_dict( + child, destination, prefix + name + '.', keep_vars=keep_vars) + for hook in module._state_dict_hooks.values(): + hook_result = hook(module, destination, prefix, local_metadata) + if hook_result is not None: + destination = hook_result + return destination + + +def save_checkpoint(model, + filename, + optimizer=None, + meta=None, + file_client_args=None): + """Save checkpoint to file. + + The checkpoint will have 3 fields: ``meta``, ``state_dict`` and + ``optimizer``. By default ``meta`` will contain version and time info. + + Args: + model (Module): Module whose params are to be saved. + filename (str): Checkpoint filename. + optimizer (:obj:`Optimizer`, optional): Optimizer to be saved. + meta (dict, optional): Metadata to be saved in checkpoint. + file_client_args (dict, optional): Arguments to instantiate a + FileClient. See :class:`mmcv.fileio.FileClient` for details. + Default: None. + `New in version 1.3.16.` + """ + if meta is None: + meta = {} + elif not isinstance(meta, dict): + raise TypeError(f'meta must be a dict or None, but got {type(meta)}') + meta.update(mmcv_version=mmcv.__version__, time=time.asctime()) + + if is_module_wrapper(model): + model = model.module + + if hasattr(model, 'CLASSES') and model.CLASSES is not None: + # save class name to the meta + meta.update(CLASSES=model.CLASSES) + + checkpoint = { + 'meta': meta, + 'state_dict': weights_to_cpu(get_state_dict(model)) + } + # save optimizer state dict in the checkpoint + if isinstance(optimizer, Optimizer): + checkpoint['optimizer'] = optimizer.state_dict() + elif isinstance(optimizer, dict): + checkpoint['optimizer'] = {} + for name, optim in optimizer.items(): + checkpoint['optimizer'][name] = optim.state_dict() + + if filename.startswith('pavi://'): + if file_client_args is not None: + raise ValueError( + 'file_client_args should be "None" if filename starts with' + f'"pavi://", but got {file_client_args}') + try: + from pavi import modelcloud + from pavi import exception + except ImportError: + raise ImportError( + 'Please install pavi to load checkpoint from modelcloud.') + model_path = filename[7:] + root = modelcloud.Folder() + model_dir, model_name = osp.split(model_path) + try: + model = modelcloud.get(model_dir) + except exception.NodeNotFoundError: + model = root.create_training_model(model_dir) + with TemporaryDirectory() as tmp_dir: + checkpoint_file = osp.join(tmp_dir, model_name) + with open(checkpoint_file, 'wb') as f: + torch.save(checkpoint, f) + f.flush() + model.create_file(checkpoint_file, name=model_name) + else: + file_client = FileClient.infer_client(file_client_args, filename) + with io.BytesIO() as f: + torch.save(checkpoint, f) + file_client.put(f.getvalue(), filename) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/default_constructor.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/default_constructor.py new file mode 100644 index 00000000..bdd78032 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/default_constructor.py @@ -0,0 +1,44 @@ +from .builder import RUNNER_BUILDERS, RUNNERS + + +@RUNNER_BUILDERS.register_module() +class DefaultRunnerConstructor: + """Default constructor for runners. + + Custom existing `Runner` like `EpocBasedRunner` though `RunnerConstructor`. + For example, We can inject some new properties and functions for `Runner`. + + Example: + >>> from annotator.mmpkg.mmcv.runner import RUNNER_BUILDERS, build_runner + >>> # Define a new RunnerReconstructor + >>> @RUNNER_BUILDERS.register_module() + >>> class MyRunnerConstructor: + ... def __init__(self, runner_cfg, default_args=None): + ... if not isinstance(runner_cfg, dict): + ... raise TypeError('runner_cfg should be a dict', + ... f'but got {type(runner_cfg)}') + ... self.runner_cfg = runner_cfg + ... self.default_args = default_args + ... + ... def __call__(self): + ... runner = RUNNERS.build(self.runner_cfg, + ... default_args=self.default_args) + ... # Add new properties for existing runner + ... runner.my_name = 'my_runner' + ... runner.my_function = lambda self: print(self.my_name) + ... ... + >>> # build your runner + >>> runner_cfg = dict(type='EpochBasedRunner', max_epochs=40, + ... constructor='MyRunnerConstructor') + >>> runner = build_runner(runner_cfg) + """ + + def __init__(self, runner_cfg, default_args=None): + if not isinstance(runner_cfg, dict): + raise TypeError('runner_cfg should be a dict', + f'but got {type(runner_cfg)}') + self.runner_cfg = runner_cfg + self.default_args = default_args + + def __call__(self): + return RUNNERS.build(self.runner_cfg, default_args=self.default_args) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/dist_utils.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/dist_utils.py new file mode 100644 index 00000000..d3a1ef3f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/dist_utils.py @@ -0,0 +1,164 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import functools +import os +import subprocess +from collections import OrderedDict + +import torch +import torch.multiprocessing as mp +from torch import distributed as dist +from torch._utils import (_flatten_dense_tensors, _take_tensors, + _unflatten_dense_tensors) + + +def init_dist(launcher, backend='nccl', **kwargs): + if mp.get_start_method(allow_none=True) is None: + mp.set_start_method('spawn') + if launcher == 'pytorch': + _init_dist_pytorch(backend, **kwargs) + elif launcher == 'mpi': + _init_dist_mpi(backend, **kwargs) + elif launcher == 'slurm': + _init_dist_slurm(backend, **kwargs) + else: + raise ValueError(f'Invalid launcher type: {launcher}') + + +def _init_dist_pytorch(backend, **kwargs): + # TODO: use local_rank instead of rank % num_gpus + rank = int(os.environ['RANK']) + num_gpus = torch.cuda.device_count() + torch.cuda.set_device(rank % num_gpus) + dist.init_process_group(backend=backend, **kwargs) + + +def _init_dist_mpi(backend, **kwargs): + # TODO: use local_rank instead of rank % num_gpus + rank = int(os.environ['OMPI_COMM_WORLD_RANK']) + num_gpus = torch.cuda.device_count() + torch.cuda.set_device(rank % num_gpus) + dist.init_process_group(backend=backend, **kwargs) + + +def _init_dist_slurm(backend, port=None): + """Initialize slurm distributed training environment. + + If argument ``port`` is not specified, then the master port will be system + environment variable ``MASTER_PORT``. If ``MASTER_PORT`` is not in system + environment variable, then a default port ``29500`` will be used. + + Args: + backend (str): Backend of torch.distributed. + port (int, optional): Master port. Defaults to None. + """ + proc_id = int(os.environ['SLURM_PROCID']) + ntasks = int(os.environ['SLURM_NTASKS']) + node_list = os.environ['SLURM_NODELIST'] + num_gpus = torch.cuda.device_count() + torch.cuda.set_device(proc_id % num_gpus) + addr = subprocess.getoutput( + f'scontrol show hostname {node_list} | head -n1') + # specify master port + if port is not None: + os.environ['MASTER_PORT'] = str(port) + elif 'MASTER_PORT' in os.environ: + pass # use MASTER_PORT in the environment variable + else: + # 29500 is torch.distributed default port + os.environ['MASTER_PORT'] = '29500' + # use MASTER_ADDR in the environment variable if it already exists + if 'MASTER_ADDR' not in os.environ: + os.environ['MASTER_ADDR'] = addr + os.environ['WORLD_SIZE'] = str(ntasks) + os.environ['LOCAL_RANK'] = str(proc_id % num_gpus) + os.environ['RANK'] = str(proc_id) + dist.init_process_group(backend=backend) + + +def get_dist_info(): + if dist.is_available() and dist.is_initialized(): + rank = dist.get_rank() + world_size = dist.get_world_size() + else: + rank = 0 + world_size = 1 + return rank, world_size + + +def master_only(func): + + @functools.wraps(func) + def wrapper(*args, **kwargs): + rank, _ = get_dist_info() + if rank == 0: + return func(*args, **kwargs) + + return wrapper + + +def allreduce_params(params, coalesce=True, bucket_size_mb=-1): + """Allreduce parameters. + + Args: + params (list[torch.Parameters]): List of parameters or buffers of a + model. + coalesce (bool, optional): Whether allreduce parameters as a whole. + Defaults to True. + bucket_size_mb (int, optional): Size of bucket, the unit is MB. + Defaults to -1. + """ + _, world_size = get_dist_info() + if world_size == 1: + return + params = [param.data for param in params] + if coalesce: + _allreduce_coalesced(params, world_size, bucket_size_mb) + else: + for tensor in params: + dist.all_reduce(tensor.div_(world_size)) + + +def allreduce_grads(params, coalesce=True, bucket_size_mb=-1): + """Allreduce gradients. + + Args: + params (list[torch.Parameters]): List of parameters of a model + coalesce (bool, optional): Whether allreduce parameters as a whole. + Defaults to True. + bucket_size_mb (int, optional): Size of bucket, the unit is MB. + Defaults to -1. + """ + grads = [ + param.grad.data for param in params + if param.requires_grad and param.grad is not None + ] + _, world_size = get_dist_info() + if world_size == 1: + return + if coalesce: + _allreduce_coalesced(grads, world_size, bucket_size_mb) + else: + for tensor in grads: + dist.all_reduce(tensor.div_(world_size)) + + +def _allreduce_coalesced(tensors, world_size, bucket_size_mb=-1): + if bucket_size_mb > 0: + bucket_size_bytes = bucket_size_mb * 1024 * 1024 + buckets = _take_tensors(tensors, bucket_size_bytes) + else: + buckets = OrderedDict() + for tensor in tensors: + tp = tensor.type() + if tp not in buckets: + buckets[tp] = [] + buckets[tp].append(tensor) + buckets = buckets.values() + + for bucket in buckets: + flat_tensors = _flatten_dense_tensors(bucket) + dist.all_reduce(flat_tensors) + flat_tensors.div_(world_size) + for tensor, synced in zip( + bucket, _unflatten_dense_tensors(flat_tensors, bucket)): + tensor.copy_(synced) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/epoch_based_runner.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/epoch_based_runner.py new file mode 100644 index 00000000..d4df071e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/epoch_based_runner.py @@ -0,0 +1,187 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os.path as osp +import platform +import shutil +import time +import warnings + +import torch + +import annotator.mmpkg.mmcv as mmcv +from .base_runner import BaseRunner +from .builder import RUNNERS +from .checkpoint import save_checkpoint +from .utils import get_host_info + + +@RUNNERS.register_module() +class EpochBasedRunner(BaseRunner): + """Epoch-based Runner. + + This runner train models epoch by epoch. + """ + + def run_iter(self, data_batch, train_mode, **kwargs): + if self.batch_processor is not None: + outputs = self.batch_processor( + self.model, data_batch, train_mode=train_mode, **kwargs) + elif train_mode: + outputs = self.model.train_step(data_batch, self.optimizer, + **kwargs) + else: + outputs = self.model.val_step(data_batch, self.optimizer, **kwargs) + if not isinstance(outputs, dict): + raise TypeError('"batch_processor()" or "model.train_step()"' + 'and "model.val_step()" must return a dict') + if 'log_vars' in outputs: + self.log_buffer.update(outputs['log_vars'], outputs['num_samples']) + self.outputs = outputs + + def train(self, data_loader, **kwargs): + self.model.train() + self.mode = 'train' + self.data_loader = data_loader + self._max_iters = self._max_epochs * len(self.data_loader) + self.call_hook('before_train_epoch') + time.sleep(2) # Prevent possible deadlock during epoch transition + for i, data_batch in enumerate(self.data_loader): + self._inner_iter = i + self.call_hook('before_train_iter') + self.run_iter(data_batch, train_mode=True, **kwargs) + self.call_hook('after_train_iter') + self._iter += 1 + + self.call_hook('after_train_epoch') + self._epoch += 1 + + @torch.no_grad() + def val(self, data_loader, **kwargs): + self.model.eval() + self.mode = 'val' + self.data_loader = data_loader + self.call_hook('before_val_epoch') + time.sleep(2) # Prevent possible deadlock during epoch transition + for i, data_batch in enumerate(self.data_loader): + self._inner_iter = i + self.call_hook('before_val_iter') + self.run_iter(data_batch, train_mode=False) + self.call_hook('after_val_iter') + + self.call_hook('after_val_epoch') + + def run(self, data_loaders, workflow, max_epochs=None, **kwargs): + """Start running. + + Args: + data_loaders (list[:obj:`DataLoader`]): Dataloaders for training + and validation. + workflow (list[tuple]): A list of (phase, epochs) to specify the + running order and epochs. E.g, [('train', 2), ('val', 1)] means + running 2 epochs for training and 1 epoch for validation, + iteratively. + """ + assert isinstance(data_loaders, list) + assert mmcv.is_list_of(workflow, tuple) + assert len(data_loaders) == len(workflow) + if max_epochs is not None: + warnings.warn( + 'setting max_epochs in run is deprecated, ' + 'please set max_epochs in runner_config', DeprecationWarning) + self._max_epochs = max_epochs + + assert self._max_epochs is not None, ( + 'max_epochs must be specified during instantiation') + + for i, flow in enumerate(workflow): + mode, epochs = flow + if mode == 'train': + self._max_iters = self._max_epochs * len(data_loaders[i]) + break + + work_dir = self.work_dir if self.work_dir is not None else 'NONE' + self.logger.info('Start running, host: %s, work_dir: %s', + get_host_info(), work_dir) + self.logger.info('Hooks will be executed in the following order:\n%s', + self.get_hook_info()) + self.logger.info('workflow: %s, max: %d epochs', workflow, + self._max_epochs) + self.call_hook('before_run') + + while self.epoch < self._max_epochs: + for i, flow in enumerate(workflow): + mode, epochs = flow + if isinstance(mode, str): # self.train() + if not hasattr(self, mode): + raise ValueError( + f'runner has no method named "{mode}" to run an ' + 'epoch') + epoch_runner = getattr(self, mode) + else: + raise TypeError( + 'mode in workflow must be a str, but got {}'.format( + type(mode))) + + for _ in range(epochs): + if mode == 'train' and self.epoch >= self._max_epochs: + break + epoch_runner(data_loaders[i], **kwargs) + + time.sleep(1) # wait for some hooks like loggers to finish + self.call_hook('after_run') + + def save_checkpoint(self, + out_dir, + filename_tmpl='epoch_{}.pth', + save_optimizer=True, + meta=None, + create_symlink=True): + """Save the checkpoint. + + Args: + out_dir (str): The directory that checkpoints are saved. + filename_tmpl (str, optional): The checkpoint filename template, + which contains a placeholder for the epoch number. + Defaults to 'epoch_{}.pth'. + save_optimizer (bool, optional): Whether to save the optimizer to + the checkpoint. Defaults to True. + meta (dict, optional): The meta information to be saved in the + checkpoint. Defaults to None. + create_symlink (bool, optional): Whether to create a symlink + "latest.pth" to point to the latest checkpoint. + Defaults to True. + """ + if meta is None: + meta = {} + elif not isinstance(meta, dict): + raise TypeError( + f'meta should be a dict or None, but got {type(meta)}') + if self.meta is not None: + meta.update(self.meta) + # Note: meta.update(self.meta) should be done before + # meta.update(epoch=self.epoch + 1, iter=self.iter) otherwise + # there will be problems with resumed checkpoints. + # More details in https://github.com/open-mmlab/mmcv/pull/1108 + meta.update(epoch=self.epoch + 1, iter=self.iter) + + filename = filename_tmpl.format(self.epoch + 1) + filepath = osp.join(out_dir, filename) + optimizer = self.optimizer if save_optimizer else None + save_checkpoint(self.model, filepath, optimizer=optimizer, meta=meta) + # in some environments, `os.symlink` is not supported, you may need to + # set `create_symlink` to False + if create_symlink: + dst_file = osp.join(out_dir, 'latest.pth') + if platform.system() != 'Windows': + mmcv.symlink(filename, dst_file) + else: + shutil.copy(filepath, dst_file) + + +@RUNNERS.register_module() +class Runner(EpochBasedRunner): + """Deprecated name of EpochBasedRunner.""" + + def __init__(self, *args, **kwargs): + warnings.warn( + 'Runner was deprecated, please use EpochBasedRunner instead') + super().__init__(*args, **kwargs) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/fp16_utils.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/fp16_utils.py new file mode 100644 index 00000000..f6b54886 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/fp16_utils.py @@ -0,0 +1,410 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import functools +import warnings +from collections import abc +from inspect import getfullargspec + +import numpy as np +import torch +import torch.nn as nn + +from annotator.mmpkg.mmcv.utils import TORCH_VERSION, digit_version +from .dist_utils import allreduce_grads as _allreduce_grads + +try: + # If PyTorch version >= 1.6.0, torch.cuda.amp.autocast would be imported + # and used; otherwise, auto fp16 will adopt mmcv's implementation. + # Note that when PyTorch >= 1.6.0, we still cast tensor types to fp16 + # manually, so the behavior may not be consistent with real amp. + from torch.cuda.amp import autocast +except ImportError: + pass + + +def cast_tensor_type(inputs, src_type, dst_type): + """Recursively convert Tensor in inputs from src_type to dst_type. + + Args: + inputs: Inputs that to be casted. + src_type (torch.dtype): Source type.. + dst_type (torch.dtype): Destination type. + + Returns: + The same type with inputs, but all contained Tensors have been cast. + """ + if isinstance(inputs, nn.Module): + return inputs + elif isinstance(inputs, torch.Tensor): + return inputs.to(dst_type) + elif isinstance(inputs, str): + return inputs + elif isinstance(inputs, np.ndarray): + return inputs + elif isinstance(inputs, abc.Mapping): + return type(inputs)({ + k: cast_tensor_type(v, src_type, dst_type) + for k, v in inputs.items() + }) + elif isinstance(inputs, abc.Iterable): + return type(inputs)( + cast_tensor_type(item, src_type, dst_type) for item in inputs) + else: + return inputs + + +def auto_fp16(apply_to=None, out_fp32=False): + """Decorator to enable fp16 training automatically. + + This decorator is useful when you write custom modules and want to support + mixed precision training. If inputs arguments are fp32 tensors, they will + be converted to fp16 automatically. Arguments other than fp32 tensors are + ignored. If you are using PyTorch >= 1.6, torch.cuda.amp is used as the + backend, otherwise, original mmcv implementation will be adopted. + + Args: + apply_to (Iterable, optional): The argument names to be converted. + `None` indicates all arguments. + out_fp32 (bool): Whether to convert the output back to fp32. + + Example: + + >>> import torch.nn as nn + >>> class MyModule1(nn.Module): + >>> + >>> # Convert x and y to fp16 + >>> @auto_fp16() + >>> def forward(self, x, y): + >>> pass + + >>> import torch.nn as nn + >>> class MyModule2(nn.Module): + >>> + >>> # convert pred to fp16 + >>> @auto_fp16(apply_to=('pred', )) + >>> def do_something(self, pred, others): + >>> pass + """ + + def auto_fp16_wrapper(old_func): + + @functools.wraps(old_func) + def new_func(*args, **kwargs): + # check if the module has set the attribute `fp16_enabled`, if not, + # just fallback to the original method. + if not isinstance(args[0], torch.nn.Module): + raise TypeError('@auto_fp16 can only be used to decorate the ' + 'method of nn.Module') + if not (hasattr(args[0], 'fp16_enabled') and args[0].fp16_enabled): + return old_func(*args, **kwargs) + + # get the arg spec of the decorated method + args_info = getfullargspec(old_func) + # get the argument names to be casted + args_to_cast = args_info.args if apply_to is None else apply_to + # convert the args that need to be processed + new_args = [] + # NOTE: default args are not taken into consideration + if args: + arg_names = args_info.args[:len(args)] + for i, arg_name in enumerate(arg_names): + if arg_name in args_to_cast: + new_args.append( + cast_tensor_type(args[i], torch.float, torch.half)) + else: + new_args.append(args[i]) + # convert the kwargs that need to be processed + new_kwargs = {} + if kwargs: + for arg_name, arg_value in kwargs.items(): + if arg_name in args_to_cast: + new_kwargs[arg_name] = cast_tensor_type( + arg_value, torch.float, torch.half) + else: + new_kwargs[arg_name] = arg_value + # apply converted arguments to the decorated method + if (TORCH_VERSION != 'parrots' and + digit_version(TORCH_VERSION) >= digit_version('1.6.0')): + with autocast(enabled=True): + output = old_func(*new_args, **new_kwargs) + else: + output = old_func(*new_args, **new_kwargs) + # cast the results back to fp32 if necessary + if out_fp32: + output = cast_tensor_type(output, torch.half, torch.float) + return output + + return new_func + + return auto_fp16_wrapper + + +def force_fp32(apply_to=None, out_fp16=False): + """Decorator to convert input arguments to fp32 in force. + + This decorator is useful when you write custom modules and want to support + mixed precision training. If there are some inputs that must be processed + in fp32 mode, then this decorator can handle it. If inputs arguments are + fp16 tensors, they will be converted to fp32 automatically. Arguments other + than fp16 tensors are ignored. If you are using PyTorch >= 1.6, + torch.cuda.amp is used as the backend, otherwise, original mmcv + implementation will be adopted. + + Args: + apply_to (Iterable, optional): The argument names to be converted. + `None` indicates all arguments. + out_fp16 (bool): Whether to convert the output back to fp16. + + Example: + + >>> import torch.nn as nn + >>> class MyModule1(nn.Module): + >>> + >>> # Convert x and y to fp32 + >>> @force_fp32() + >>> def loss(self, x, y): + >>> pass + + >>> import torch.nn as nn + >>> class MyModule2(nn.Module): + >>> + >>> # convert pred to fp32 + >>> @force_fp32(apply_to=('pred', )) + >>> def post_process(self, pred, others): + >>> pass + """ + + def force_fp32_wrapper(old_func): + + @functools.wraps(old_func) + def new_func(*args, **kwargs): + # check if the module has set the attribute `fp16_enabled`, if not, + # just fallback to the original method. + if not isinstance(args[0], torch.nn.Module): + raise TypeError('@force_fp32 can only be used to decorate the ' + 'method of nn.Module') + if not (hasattr(args[0], 'fp16_enabled') and args[0].fp16_enabled): + return old_func(*args, **kwargs) + # get the arg spec of the decorated method + args_info = getfullargspec(old_func) + # get the argument names to be casted + args_to_cast = args_info.args if apply_to is None else apply_to + # convert the args that need to be processed + new_args = [] + if args: + arg_names = args_info.args[:len(args)] + for i, arg_name in enumerate(arg_names): + if arg_name in args_to_cast: + new_args.append( + cast_tensor_type(args[i], torch.half, torch.float)) + else: + new_args.append(args[i]) + # convert the kwargs that need to be processed + new_kwargs = dict() + if kwargs: + for arg_name, arg_value in kwargs.items(): + if arg_name in args_to_cast: + new_kwargs[arg_name] = cast_tensor_type( + arg_value, torch.half, torch.float) + else: + new_kwargs[arg_name] = arg_value + # apply converted arguments to the decorated method + if (TORCH_VERSION != 'parrots' and + digit_version(TORCH_VERSION) >= digit_version('1.6.0')): + with autocast(enabled=False): + output = old_func(*new_args, **new_kwargs) + else: + output = old_func(*new_args, **new_kwargs) + # cast the results back to fp32 if necessary + if out_fp16: + output = cast_tensor_type(output, torch.float, torch.half) + return output + + return new_func + + return force_fp32_wrapper + + +def allreduce_grads(params, coalesce=True, bucket_size_mb=-1): + warnings.warning( + '"mmcv.runner.fp16_utils.allreduce_grads" is deprecated, and will be ' + 'removed in v2.8. Please switch to "mmcv.runner.allreduce_grads') + _allreduce_grads(params, coalesce=coalesce, bucket_size_mb=bucket_size_mb) + + +def wrap_fp16_model(model): + """Wrap the FP32 model to FP16. + + If you are using PyTorch >= 1.6, torch.cuda.amp is used as the + backend, otherwise, original mmcv implementation will be adopted. + + For PyTorch >= 1.6, this function will + 1. Set fp16 flag inside the model to True. + + Otherwise: + 1. Convert FP32 model to FP16. + 2. Remain some necessary layers to be FP32, e.g., normalization layers. + 3. Set `fp16_enabled` flag inside the model to True. + + Args: + model (nn.Module): Model in FP32. + """ + if (TORCH_VERSION == 'parrots' + or digit_version(TORCH_VERSION) < digit_version('1.6.0')): + # convert model to fp16 + model.half() + # patch the normalization layers to make it work in fp32 mode + patch_norm_fp32(model) + # set `fp16_enabled` flag + for m in model.modules(): + if hasattr(m, 'fp16_enabled'): + m.fp16_enabled = True + + +def patch_norm_fp32(module): + """Recursively convert normalization layers from FP16 to FP32. + + Args: + module (nn.Module): The modules to be converted in FP16. + + Returns: + nn.Module: The converted module, the normalization layers have been + converted to FP32. + """ + if isinstance(module, (nn.modules.batchnorm._BatchNorm, nn.GroupNorm)): + module.float() + if isinstance(module, nn.GroupNorm) or torch.__version__ < '1.3': + module.forward = patch_forward_method(module.forward, torch.half, + torch.float) + for child in module.children(): + patch_norm_fp32(child) + return module + + +def patch_forward_method(func, src_type, dst_type, convert_output=True): + """Patch the forward method of a module. + + Args: + func (callable): The original forward method. + src_type (torch.dtype): Type of input arguments to be converted from. + dst_type (torch.dtype): Type of input arguments to be converted to. + convert_output (bool): Whether to convert the output back to src_type. + + Returns: + callable: The patched forward method. + """ + + def new_forward(*args, **kwargs): + output = func(*cast_tensor_type(args, src_type, dst_type), + **cast_tensor_type(kwargs, src_type, dst_type)) + if convert_output: + output = cast_tensor_type(output, dst_type, src_type) + return output + + return new_forward + + +class LossScaler: + """Class that manages loss scaling in mixed precision training which + supports both dynamic or static mode. + + The implementation refers to + https://github.com/NVIDIA/apex/blob/master/apex/fp16_utils/loss_scaler.py. + Indirectly, by supplying ``mode='dynamic'`` for dynamic loss scaling. + It's important to understand how :class:`LossScaler` operates. + Loss scaling is designed to combat the problem of underflowing + gradients encountered at long times when training fp16 networks. + Dynamic loss scaling begins by attempting a very high loss + scale. Ironically, this may result in OVERflowing gradients. + If overflowing gradients are encountered, :class:`FP16_Optimizer` then + skips the update step for this particular iteration/minibatch, + and :class:`LossScaler` adjusts the loss scale to a lower value. + If a certain number of iterations occur without overflowing gradients + detected,:class:`LossScaler` increases the loss scale once more. + In this way :class:`LossScaler` attempts to "ride the edge" of always + using the highest loss scale possible without incurring overflow. + + Args: + init_scale (float): Initial loss scale value, default: 2**32. + scale_factor (float): Factor used when adjusting the loss scale. + Default: 2. + mode (str): Loss scaling mode. 'dynamic' or 'static' + scale_window (int): Number of consecutive iterations without an + overflow to wait before increasing the loss scale. Default: 1000. + """ + + def __init__(self, + init_scale=2**32, + mode='dynamic', + scale_factor=2., + scale_window=1000): + self.cur_scale = init_scale + self.cur_iter = 0 + assert mode in ('dynamic', + 'static'), 'mode can only be dynamic or static' + self.mode = mode + self.last_overflow_iter = -1 + self.scale_factor = scale_factor + self.scale_window = scale_window + + def has_overflow(self, params): + """Check if params contain overflow.""" + if self.mode != 'dynamic': + return False + for p in params: + if p.grad is not None and LossScaler._has_inf_or_nan(p.grad.data): + return True + return False + + def _has_inf_or_nan(x): + """Check if params contain NaN.""" + try: + cpu_sum = float(x.float().sum()) + except RuntimeError as instance: + if 'value cannot be converted' not in instance.args[0]: + raise + return True + else: + if cpu_sum == float('inf') or cpu_sum == -float('inf') \ + or cpu_sum != cpu_sum: + return True + return False + + def update_scale(self, overflow): + """update the current loss scale value when overflow happens.""" + if self.mode != 'dynamic': + return + if overflow: + self.cur_scale = max(self.cur_scale / self.scale_factor, 1) + self.last_overflow_iter = self.cur_iter + else: + if (self.cur_iter - self.last_overflow_iter) % \ + self.scale_window == 0: + self.cur_scale *= self.scale_factor + self.cur_iter += 1 + + def state_dict(self): + """Returns the state of the scaler as a :class:`dict`.""" + return dict( + cur_scale=self.cur_scale, + cur_iter=self.cur_iter, + mode=self.mode, + last_overflow_iter=self.last_overflow_iter, + scale_factor=self.scale_factor, + scale_window=self.scale_window) + + def load_state_dict(self, state_dict): + """Loads the loss_scaler state dict. + + Args: + state_dict (dict): scaler state. + """ + self.cur_scale = state_dict['cur_scale'] + self.cur_iter = state_dict['cur_iter'] + self.mode = state_dict['mode'] + self.last_overflow_iter = state_dict['last_overflow_iter'] + self.scale_factor = state_dict['scale_factor'] + self.scale_window = state_dict['scale_window'] + + @property + def loss_scale(self): + return self.cur_scale diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/__init__.py new file mode 100644 index 00000000..915af28c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/__init__.py @@ -0,0 +1,29 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .checkpoint import CheckpointHook +from .closure import ClosureHook +from .ema import EMAHook +from .evaluation import DistEvalHook, EvalHook +from .hook import HOOKS, Hook +from .iter_timer import IterTimerHook +from .logger import (DvcliveLoggerHook, LoggerHook, MlflowLoggerHook, + NeptuneLoggerHook, PaviLoggerHook, TensorboardLoggerHook, + TextLoggerHook, WandbLoggerHook) +from .lr_updater import LrUpdaterHook +from .memory import EmptyCacheHook +from .momentum_updater import MomentumUpdaterHook +from .optimizer import (Fp16OptimizerHook, GradientCumulativeFp16OptimizerHook, + GradientCumulativeOptimizerHook, OptimizerHook) +from .profiler import ProfilerHook +from .sampler_seed import DistSamplerSeedHook +from .sync_buffer import SyncBuffersHook + +__all__ = [ + 'HOOKS', 'Hook', 'CheckpointHook', 'ClosureHook', 'LrUpdaterHook', + 'OptimizerHook', 'Fp16OptimizerHook', 'IterTimerHook', + 'DistSamplerSeedHook', 'EmptyCacheHook', 'LoggerHook', 'MlflowLoggerHook', + 'PaviLoggerHook', 'TextLoggerHook', 'TensorboardLoggerHook', + 'NeptuneLoggerHook', 'WandbLoggerHook', 'DvcliveLoggerHook', + 'MomentumUpdaterHook', 'SyncBuffersHook', 'EMAHook', 'EvalHook', + 'DistEvalHook', 'ProfilerHook', 'GradientCumulativeOptimizerHook', + 'GradientCumulativeFp16OptimizerHook' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/checkpoint.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/checkpoint.py new file mode 100644 index 00000000..877aa8b8 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/checkpoint.py @@ -0,0 +1,167 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os.path as osp +import warnings + +from annotator.mmpkg.mmcv.fileio import FileClient +from ..dist_utils import allreduce_params, master_only +from .hook import HOOKS, Hook + + +@HOOKS.register_module() +class CheckpointHook(Hook): + """Save checkpoints periodically. + + Args: + interval (int): The saving period. If ``by_epoch=True``, interval + indicates epochs, otherwise it indicates iterations. + Default: -1, which means "never". + by_epoch (bool): Saving checkpoints by epoch or by iteration. + Default: True. + save_optimizer (bool): Whether to save optimizer state_dict in the + checkpoint. It is usually used for resuming experiments. + Default: True. + out_dir (str, optional): The root directory to save checkpoints. If not + specified, ``runner.work_dir`` will be used by default. If + specified, the ``out_dir`` will be the concatenation of ``out_dir`` + and the last level directory of ``runner.work_dir``. + `Changed in version 1.3.16.` + max_keep_ckpts (int, optional): The maximum checkpoints to keep. + In some cases we want only the latest few checkpoints and would + like to delete old ones to save the disk space. + Default: -1, which means unlimited. + save_last (bool, optional): Whether to force the last checkpoint to be + saved regardless of interval. Default: True. + sync_buffer (bool, optional): Whether to synchronize buffers in + different gpus. Default: False. + file_client_args (dict, optional): Arguments to instantiate a + FileClient. See :class:`mmcv.fileio.FileClient` for details. + Default: None. + `New in version 1.3.16.` + + .. warning:: + Before v1.3.16, the ``out_dir`` argument indicates the path where the + checkpoint is stored. However, since v1.3.16, ``out_dir`` indicates the + root directory and the final path to save checkpoint is the + concatenation of ``out_dir`` and the last level directory of + ``runner.work_dir``. Suppose the value of ``out_dir`` is "/path/of/A" + and the value of ``runner.work_dir`` is "/path/of/B", then the final + path will be "/path/of/A/B". + """ + + def __init__(self, + interval=-1, + by_epoch=True, + save_optimizer=True, + out_dir=None, + max_keep_ckpts=-1, + save_last=True, + sync_buffer=False, + file_client_args=None, + **kwargs): + self.interval = interval + self.by_epoch = by_epoch + self.save_optimizer = save_optimizer + self.out_dir = out_dir + self.max_keep_ckpts = max_keep_ckpts + self.save_last = save_last + self.args = kwargs + self.sync_buffer = sync_buffer + self.file_client_args = file_client_args + + def before_run(self, runner): + if not self.out_dir: + self.out_dir = runner.work_dir + + self.file_client = FileClient.infer_client(self.file_client_args, + self.out_dir) + + # if `self.out_dir` is not equal to `runner.work_dir`, it means that + # `self.out_dir` is set so the final `self.out_dir` is the + # concatenation of `self.out_dir` and the last level directory of + # `runner.work_dir` + if self.out_dir != runner.work_dir: + basename = osp.basename(runner.work_dir.rstrip(osp.sep)) + self.out_dir = self.file_client.join_path(self.out_dir, basename) + + runner.logger.info((f'Checkpoints will be saved to {self.out_dir} by ' + f'{self.file_client.name}.')) + + # disable the create_symlink option because some file backends do not + # allow to create a symlink + if 'create_symlink' in self.args: + if self.args[ + 'create_symlink'] and not self.file_client.allow_symlink: + self.args['create_symlink'] = False + warnings.warn( + ('create_symlink is set as True by the user but is changed' + 'to be False because creating symbolic link is not ' + f'allowed in {self.file_client.name}')) + else: + self.args['create_symlink'] = self.file_client.allow_symlink + + def after_train_epoch(self, runner): + if not self.by_epoch: + return + + # save checkpoint for following cases: + # 1. every ``self.interval`` epochs + # 2. reach the last epoch of training + if self.every_n_epochs( + runner, self.interval) or (self.save_last + and self.is_last_epoch(runner)): + runner.logger.info( + f'Saving checkpoint at {runner.epoch + 1} epochs') + if self.sync_buffer: + allreduce_params(runner.model.buffers()) + self._save_checkpoint(runner) + + @master_only + def _save_checkpoint(self, runner): + """Save the current checkpoint and delete unwanted checkpoint.""" + runner.save_checkpoint( + self.out_dir, save_optimizer=self.save_optimizer, **self.args) + if runner.meta is not None: + if self.by_epoch: + cur_ckpt_filename = self.args.get( + 'filename_tmpl', 'epoch_{}.pth').format(runner.epoch + 1) + else: + cur_ckpt_filename = self.args.get( + 'filename_tmpl', 'iter_{}.pth').format(runner.iter + 1) + runner.meta.setdefault('hook_msgs', dict()) + runner.meta['hook_msgs']['last_ckpt'] = self.file_client.join_path( + self.out_dir, cur_ckpt_filename) + # remove other checkpoints + if self.max_keep_ckpts > 0: + if self.by_epoch: + name = 'epoch_{}.pth' + current_ckpt = runner.epoch + 1 + else: + name = 'iter_{}.pth' + current_ckpt = runner.iter + 1 + redundant_ckpts = range( + current_ckpt - self.max_keep_ckpts * self.interval, 0, + -self.interval) + filename_tmpl = self.args.get('filename_tmpl', name) + for _step in redundant_ckpts: + ckpt_path = self.file_client.join_path( + self.out_dir, filename_tmpl.format(_step)) + if self.file_client.isfile(ckpt_path): + self.file_client.remove(ckpt_path) + else: + break + + def after_train_iter(self, runner): + if self.by_epoch: + return + + # save checkpoint for following cases: + # 1. every ``self.interval`` iterations + # 2. reach the last iteration of training + if self.every_n_iters( + runner, self.interval) or (self.save_last + and self.is_last_iter(runner)): + runner.logger.info( + f'Saving checkpoint at {runner.iter + 1} iterations') + if self.sync_buffer: + allreduce_params(runner.model.buffers()) + self._save_checkpoint(runner) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/closure.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/closure.py new file mode 100644 index 00000000..b955f81f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/closure.py @@ -0,0 +1,11 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .hook import HOOKS, Hook + + +@HOOKS.register_module() +class ClosureHook(Hook): + + def __init__(self, fn_name, fn): + assert hasattr(self, fn_name) + assert callable(fn) + setattr(self, fn_name, fn) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/ema.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/ema.py new file mode 100644 index 00000000..15c7e680 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/ema.py @@ -0,0 +1,89 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from ...parallel import is_module_wrapper +from ..hooks.hook import HOOKS, Hook + + +@HOOKS.register_module() +class EMAHook(Hook): + r"""Exponential Moving Average Hook. + + Use Exponential Moving Average on all parameters of model in training + process. All parameters have a ema backup, which update by the formula + as below. EMAHook takes priority over EvalHook and CheckpointSaverHook. + + .. math:: + + \text{Xema\_{t+1}} = (1 - \text{momentum}) \times + \text{Xema\_{t}} + \text{momentum} \times X_t + + Args: + momentum (float): The momentum used for updating ema parameter. + Defaults to 0.0002. + interval (int): Update ema parameter every interval iteration. + Defaults to 1. + warm_up (int): During first warm_up steps, we may use smaller momentum + to update ema parameters more slowly. Defaults to 100. + resume_from (str): The checkpoint path. Defaults to None. + """ + + def __init__(self, + momentum=0.0002, + interval=1, + warm_up=100, + resume_from=None): + assert isinstance(interval, int) and interval > 0 + self.warm_up = warm_up + self.interval = interval + assert momentum > 0 and momentum < 1 + self.momentum = momentum**interval + self.checkpoint = resume_from + + def before_run(self, runner): + """To resume model with it's ema parameters more friendly. + + Register ema parameter as ``named_buffer`` to model + """ + model = runner.model + if is_module_wrapper(model): + model = model.module + self.param_ema_buffer = {} + self.model_parameters = dict(model.named_parameters(recurse=True)) + for name, value in self.model_parameters.items(): + # "." is not allowed in module's buffer name + buffer_name = f"ema_{name.replace('.', '_')}" + self.param_ema_buffer[name] = buffer_name + model.register_buffer(buffer_name, value.data.clone()) + self.model_buffers = dict(model.named_buffers(recurse=True)) + if self.checkpoint is not None: + runner.resume(self.checkpoint) + + def after_train_iter(self, runner): + """Update ema parameter every self.interval iterations.""" + curr_step = runner.iter + # We warm up the momentum considering the instability at beginning + momentum = min(self.momentum, + (1 + curr_step) / (self.warm_up + curr_step)) + if curr_step % self.interval != 0: + return + for name, parameter in self.model_parameters.items(): + buffer_name = self.param_ema_buffer[name] + buffer_parameter = self.model_buffers[buffer_name] + buffer_parameter.mul_(1 - momentum).add_(momentum, parameter.data) + + def after_train_epoch(self, runner): + """We load parameter values from ema backup to model before the + EvalHook.""" + self._swap_ema_parameters() + + def before_train_epoch(self, runner): + """We recover model's parameter from ema backup after last epoch's + EvalHook.""" + self._swap_ema_parameters() + + def _swap_ema_parameters(self): + """Swap the parameter of model with parameter in ema_buffer.""" + for name, value in self.model_parameters.items(): + temp = value.data.clone() + ema_buffer = self.model_buffers[self.param_ema_buffer[name]] + value.data.copy_(ema_buffer.data) + ema_buffer.data.copy_(temp) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/evaluation.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/evaluation.py new file mode 100644 index 00000000..a1dbdfd5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/evaluation.py @@ -0,0 +1,509 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os.path as osp +import warnings +from math import inf + +import torch.distributed as dist +from torch.nn.modules.batchnorm import _BatchNorm +from torch.utils.data import DataLoader + +from annotator.mmpkg.mmcv.fileio import FileClient +from annotator.mmpkg.mmcv.utils import is_seq_of +from .hook import Hook +from .logger import LoggerHook + + +class EvalHook(Hook): + """Non-Distributed evaluation hook. + + This hook will regularly perform evaluation in a given interval when + performing in non-distributed environment. + + Args: + dataloader (DataLoader): A PyTorch dataloader, whose dataset has + implemented ``evaluate`` function. + start (int | None, optional): Evaluation starting epoch. It enables + evaluation before the training starts if ``start`` <= the resuming + epoch. If None, whether to evaluate is merely decided by + ``interval``. Default: None. + interval (int): Evaluation interval. Default: 1. + by_epoch (bool): Determine perform evaluation by epoch or by iteration. + If set to True, it will perform by epoch. Otherwise, by iteration. + Default: True. + save_best (str, optional): If a metric is specified, it would measure + the best checkpoint during evaluation. The information about best + checkpoint would be saved in ``runner.meta['hook_msgs']`` to keep + best score value and best checkpoint path, which will be also + loaded when resume checkpoint. Options are the evaluation metrics + on the test dataset. e.g., ``bbox_mAP``, ``segm_mAP`` for bbox + detection and instance segmentation. ``AR@100`` for proposal + recall. If ``save_best`` is ``auto``, the first key of the returned + ``OrderedDict`` result will be used. Default: None. + rule (str | None, optional): Comparison rule for best score. If set to + None, it will infer a reasonable rule. Keys such as 'acc', 'top' + .etc will be inferred by 'greater' rule. Keys contain 'loss' will + be inferred by 'less' rule. Options are 'greater', 'less', None. + Default: None. + test_fn (callable, optional): test a model with samples from a + dataloader, and return the test results. If ``None``, the default + test function ``mmcv.engine.single_gpu_test`` will be used. + (default: ``None``) + greater_keys (List[str] | None, optional): Metric keys that will be + inferred by 'greater' comparison rule. If ``None``, + _default_greater_keys will be used. (default: ``None``) + less_keys (List[str] | None, optional): Metric keys that will be + inferred by 'less' comparison rule. If ``None``, _default_less_keys + will be used. (default: ``None``) + out_dir (str, optional): The root directory to save checkpoints. If not + specified, `runner.work_dir` will be used by default. If specified, + the `out_dir` will be the concatenation of `out_dir` and the last + level directory of `runner.work_dir`. + `New in version 1.3.16.` + file_client_args (dict): Arguments to instantiate a FileClient. + See :class:`mmcv.fileio.FileClient` for details. Default: None. + `New in version 1.3.16.` + **eval_kwargs: Evaluation arguments fed into the evaluate function of + the dataset. + + Notes: + If new arguments are added for EvalHook, tools/test.py, + tools/eval_metric.py may be affected. + """ + + # Since the key for determine greater or less is related to the downstream + # tasks, downstream repos may need to overwrite the following inner + # variable accordingly. + + rule_map = {'greater': lambda x, y: x > y, 'less': lambda x, y: x < y} + init_value_map = {'greater': -inf, 'less': inf} + _default_greater_keys = [ + 'acc', 'top', 'AR@', 'auc', 'precision', 'mAP', 'mDice', 'mIoU', + 'mAcc', 'aAcc' + ] + _default_less_keys = ['loss'] + + def __init__(self, + dataloader, + start=None, + interval=1, + by_epoch=True, + save_best=None, + rule=None, + test_fn=None, + greater_keys=None, + less_keys=None, + out_dir=None, + file_client_args=None, + **eval_kwargs): + if not isinstance(dataloader, DataLoader): + raise TypeError(f'dataloader must be a pytorch DataLoader, ' + f'but got {type(dataloader)}') + + if interval <= 0: + raise ValueError(f'interval must be a positive number, ' + f'but got {interval}') + + assert isinstance(by_epoch, bool), '``by_epoch`` should be a boolean' + + if start is not None and start < 0: + raise ValueError(f'The evaluation start epoch {start} is smaller ' + f'than 0') + + self.dataloader = dataloader + self.interval = interval + self.start = start + self.by_epoch = by_epoch + + assert isinstance(save_best, str) or save_best is None, \ + '""save_best"" should be a str or None ' \ + f'rather than {type(save_best)}' + self.save_best = save_best + self.eval_kwargs = eval_kwargs + self.initial_flag = True + + if test_fn is None: + from annotator.mmpkg.mmcv.engine import single_gpu_test + self.test_fn = single_gpu_test + else: + self.test_fn = test_fn + + if greater_keys is None: + self.greater_keys = self._default_greater_keys + else: + if not isinstance(greater_keys, (list, tuple)): + greater_keys = (greater_keys, ) + assert is_seq_of(greater_keys, str) + self.greater_keys = greater_keys + + if less_keys is None: + self.less_keys = self._default_less_keys + else: + if not isinstance(less_keys, (list, tuple)): + less_keys = (less_keys, ) + assert is_seq_of(less_keys, str) + self.less_keys = less_keys + + if self.save_best is not None: + self.best_ckpt_path = None + self._init_rule(rule, self.save_best) + + self.out_dir = out_dir + self.file_client_args = file_client_args + + def _init_rule(self, rule, key_indicator): + """Initialize rule, key_indicator, comparison_func, and best score. + + Here is the rule to determine which rule is used for key indicator + when the rule is not specific (note that the key indicator matching + is case-insensitive): + 1. If the key indicator is in ``self.greater_keys``, the rule will be + specified as 'greater'. + 2. Or if the key indicator is in ``self.less_keys``, the rule will be + specified as 'less'. + 3. Or if the key indicator is equal to the substring in any one item + in ``self.greater_keys``, the rule will be specified as 'greater'. + 4. Or if the key indicator is equal to the substring in any one item + in ``self.less_keys``, the rule will be specified as 'less'. + + Args: + rule (str | None): Comparison rule for best score. + key_indicator (str | None): Key indicator to determine the + comparison rule. + """ + if rule not in self.rule_map and rule is not None: + raise KeyError(f'rule must be greater, less or None, ' + f'but got {rule}.') + + if rule is None: + if key_indicator != 'auto': + # `_lc` here means we use the lower case of keys for + # case-insensitive matching + key_indicator_lc = key_indicator.lower() + greater_keys = [key.lower() for key in self.greater_keys] + less_keys = [key.lower() for key in self.less_keys] + + if key_indicator_lc in greater_keys: + rule = 'greater' + elif key_indicator_lc in less_keys: + rule = 'less' + elif any(key in key_indicator_lc for key in greater_keys): + rule = 'greater' + elif any(key in key_indicator_lc for key in less_keys): + rule = 'less' + else: + raise ValueError(f'Cannot infer the rule for key ' + f'{key_indicator}, thus a specific rule ' + f'must be specified.') + self.rule = rule + self.key_indicator = key_indicator + if self.rule is not None: + self.compare_func = self.rule_map[self.rule] + + def before_run(self, runner): + if not self.out_dir: + self.out_dir = runner.work_dir + + self.file_client = FileClient.infer_client(self.file_client_args, + self.out_dir) + + # if `self.out_dir` is not equal to `runner.work_dir`, it means that + # `self.out_dir` is set so the final `self.out_dir` is the + # concatenation of `self.out_dir` and the last level directory of + # `runner.work_dir` + if self.out_dir != runner.work_dir: + basename = osp.basename(runner.work_dir.rstrip(osp.sep)) + self.out_dir = self.file_client.join_path(self.out_dir, basename) + runner.logger.info( + (f'The best checkpoint will be saved to {self.out_dir} by ' + f'{self.file_client.name}')) + + if self.save_best is not None: + if runner.meta is None: + warnings.warn('runner.meta is None. Creating an empty one.') + runner.meta = dict() + runner.meta.setdefault('hook_msgs', dict()) + self.best_ckpt_path = runner.meta['hook_msgs'].get( + 'best_ckpt', None) + + def before_train_iter(self, runner): + """Evaluate the model only at the start of training by iteration.""" + if self.by_epoch or not self.initial_flag: + return + if self.start is not None and runner.iter >= self.start: + self.after_train_iter(runner) + self.initial_flag = False + + def before_train_epoch(self, runner): + """Evaluate the model only at the start of training by epoch.""" + if not (self.by_epoch and self.initial_flag): + return + if self.start is not None and runner.epoch >= self.start: + self.after_train_epoch(runner) + self.initial_flag = False + + def after_train_iter(self, runner): + """Called after every training iter to evaluate the results.""" + if not self.by_epoch and self._should_evaluate(runner): + # Because the priority of EvalHook is higher than LoggerHook, the + # training log and the evaluating log are mixed. Therefore, + # we need to dump the training log and clear it before evaluating + # log is generated. In addition, this problem will only appear in + # `IterBasedRunner` whose `self.by_epoch` is False, because + # `EpochBasedRunner` whose `self.by_epoch` is True calls + # `_do_evaluate` in `after_train_epoch` stage, and at this stage + # the training log has been printed, so it will not cause any + # problem. more details at + # https://github.com/open-mmlab/mmsegmentation/issues/694 + for hook in runner._hooks: + if isinstance(hook, LoggerHook): + hook.after_train_iter(runner) + runner.log_buffer.clear() + + self._do_evaluate(runner) + + def after_train_epoch(self, runner): + """Called after every training epoch to evaluate the results.""" + if self.by_epoch and self._should_evaluate(runner): + self._do_evaluate(runner) + + def _do_evaluate(self, runner): + """perform evaluation and save ckpt.""" + results = self.test_fn(runner.model, self.dataloader) + runner.log_buffer.output['eval_iter_num'] = len(self.dataloader) + key_score = self.evaluate(runner, results) + # the key_score may be `None` so it needs to skip the action to save + # the best checkpoint + if self.save_best and key_score: + self._save_ckpt(runner, key_score) + + def _should_evaluate(self, runner): + """Judge whether to perform evaluation. + + Here is the rule to judge whether to perform evaluation: + 1. It will not perform evaluation during the epoch/iteration interval, + which is determined by ``self.interval``. + 2. It will not perform evaluation if the start time is larger than + current time. + 3. It will not perform evaluation when current time is larger than + the start time but during epoch/iteration interval. + + Returns: + bool: The flag indicating whether to perform evaluation. + """ + if self.by_epoch: + current = runner.epoch + check_time = self.every_n_epochs + else: + current = runner.iter + check_time = self.every_n_iters + + if self.start is None: + if not check_time(runner, self.interval): + # No evaluation during the interval. + return False + elif (current + 1) < self.start: + # No evaluation if start is larger than the current time. + return False + else: + # Evaluation only at epochs/iters 3, 5, 7... + # if start==3 and interval==2 + if (current + 1 - self.start) % self.interval: + return False + return True + + def _save_ckpt(self, runner, key_score): + """Save the best checkpoint. + + It will compare the score according to the compare function, write + related information (best score, best checkpoint path) and save the + best checkpoint into ``work_dir``. + """ + if self.by_epoch: + current = f'epoch_{runner.epoch + 1}' + cur_type, cur_time = 'epoch', runner.epoch + 1 + else: + current = f'iter_{runner.iter + 1}' + cur_type, cur_time = 'iter', runner.iter + 1 + + best_score = runner.meta['hook_msgs'].get( + 'best_score', self.init_value_map[self.rule]) + if self.compare_func(key_score, best_score): + best_score = key_score + runner.meta['hook_msgs']['best_score'] = best_score + + if self.best_ckpt_path and self.file_client.isfile( + self.best_ckpt_path): + self.file_client.remove(self.best_ckpt_path) + runner.logger.info( + (f'The previous best checkpoint {self.best_ckpt_path} was ' + 'removed')) + + best_ckpt_name = f'best_{self.key_indicator}_{current}.pth' + self.best_ckpt_path = self.file_client.join_path( + self.out_dir, best_ckpt_name) + runner.meta['hook_msgs']['best_ckpt'] = self.best_ckpt_path + + runner.save_checkpoint( + self.out_dir, best_ckpt_name, create_symlink=False) + runner.logger.info( + f'Now best checkpoint is saved as {best_ckpt_name}.') + runner.logger.info( + f'Best {self.key_indicator} is {best_score:0.4f} ' + f'at {cur_time} {cur_type}.') + + def evaluate(self, runner, results): + """Evaluate the results. + + Args: + runner (:obj:`mmcv.Runner`): The underlined training runner. + results (list): Output results. + """ + eval_res = self.dataloader.dataset.evaluate( + results, logger=runner.logger, **self.eval_kwargs) + + for name, val in eval_res.items(): + runner.log_buffer.output[name] = val + runner.log_buffer.ready = True + + if self.save_best is not None: + # If the performance of model is pool, the `eval_res` may be an + # empty dict and it will raise exception when `self.save_best` is + # not None. More details at + # https://github.com/open-mmlab/mmdetection/issues/6265. + if not eval_res: + warnings.warn( + 'Since `eval_res` is an empty dict, the behavior to save ' + 'the best checkpoint will be skipped in this evaluation.') + return None + + if self.key_indicator == 'auto': + # infer from eval_results + self._init_rule(self.rule, list(eval_res.keys())[0]) + return eval_res[self.key_indicator] + + return None + + +class DistEvalHook(EvalHook): + """Distributed evaluation hook. + + This hook will regularly perform evaluation in a given interval when + performing in distributed environment. + + Args: + dataloader (DataLoader): A PyTorch dataloader, whose dataset has + implemented ``evaluate`` function. + start (int | None, optional): Evaluation starting epoch. It enables + evaluation before the training starts if ``start`` <= the resuming + epoch. If None, whether to evaluate is merely decided by + ``interval``. Default: None. + interval (int): Evaluation interval. Default: 1. + by_epoch (bool): Determine perform evaluation by epoch or by iteration. + If set to True, it will perform by epoch. Otherwise, by iteration. + default: True. + save_best (str, optional): If a metric is specified, it would measure + the best checkpoint during evaluation. The information about best + checkpoint would be saved in ``runner.meta['hook_msgs']`` to keep + best score value and best checkpoint path, which will be also + loaded when resume checkpoint. Options are the evaluation metrics + on the test dataset. e.g., ``bbox_mAP``, ``segm_mAP`` for bbox + detection and instance segmentation. ``AR@100`` for proposal + recall. If ``save_best`` is ``auto``, the first key of the returned + ``OrderedDict`` result will be used. Default: None. + rule (str | None, optional): Comparison rule for best score. If set to + None, it will infer a reasonable rule. Keys such as 'acc', 'top' + .etc will be inferred by 'greater' rule. Keys contain 'loss' will + be inferred by 'less' rule. Options are 'greater', 'less', None. + Default: None. + test_fn (callable, optional): test a model with samples from a + dataloader in a multi-gpu manner, and return the test results. If + ``None``, the default test function ``mmcv.engine.multi_gpu_test`` + will be used. (default: ``None``) + tmpdir (str | None): Temporary directory to save the results of all + processes. Default: None. + gpu_collect (bool): Whether to use gpu or cpu to collect results. + Default: False. + broadcast_bn_buffer (bool): Whether to broadcast the + buffer(running_mean and running_var) of rank 0 to other rank + before evaluation. Default: True. + out_dir (str, optional): The root directory to save checkpoints. If not + specified, `runner.work_dir` will be used by default. If specified, + the `out_dir` will be the concatenation of `out_dir` and the last + level directory of `runner.work_dir`. + file_client_args (dict): Arguments to instantiate a FileClient. + See :class:`mmcv.fileio.FileClient` for details. Default: None. + **eval_kwargs: Evaluation arguments fed into the evaluate function of + the dataset. + """ + + def __init__(self, + dataloader, + start=None, + interval=1, + by_epoch=True, + save_best=None, + rule=None, + test_fn=None, + greater_keys=None, + less_keys=None, + broadcast_bn_buffer=True, + tmpdir=None, + gpu_collect=False, + out_dir=None, + file_client_args=None, + **eval_kwargs): + + if test_fn is None: + from annotator.mmpkg.mmcv.engine import multi_gpu_test + test_fn = multi_gpu_test + + super().__init__( + dataloader, + start=start, + interval=interval, + by_epoch=by_epoch, + save_best=save_best, + rule=rule, + test_fn=test_fn, + greater_keys=greater_keys, + less_keys=less_keys, + out_dir=out_dir, + file_client_args=file_client_args, + **eval_kwargs) + + self.broadcast_bn_buffer = broadcast_bn_buffer + self.tmpdir = tmpdir + self.gpu_collect = gpu_collect + + def _do_evaluate(self, runner): + """perform evaluation and save ckpt.""" + # Synchronization of BatchNorm's buffer (running_mean + # and running_var) is not supported in the DDP of pytorch, + # which may cause the inconsistent performance of models in + # different ranks, so we broadcast BatchNorm's buffers + # of rank 0 to other ranks to avoid this. + if self.broadcast_bn_buffer: + model = runner.model + for name, module in model.named_modules(): + if isinstance(module, + _BatchNorm) and module.track_running_stats: + dist.broadcast(module.running_var, 0) + dist.broadcast(module.running_mean, 0) + + tmpdir = self.tmpdir + if tmpdir is None: + tmpdir = osp.join(runner.work_dir, '.eval_hook') + + results = self.test_fn( + runner.model, + self.dataloader, + tmpdir=tmpdir, + gpu_collect=self.gpu_collect) + if runner.rank == 0: + print('\n') + runner.log_buffer.output['eval_iter_num'] = len(self.dataloader) + key_score = self.evaluate(runner, results) + # the key_score may be `None` so it needs to skip the action to + # save the best checkpoint + if self.save_best and key_score: + self._save_ckpt(runner, key_score) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/hook.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/hook.py new file mode 100644 index 00000000..bd31f985 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/hook.py @@ -0,0 +1,92 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from annotator.mmpkg.mmcv.utils import Registry, is_method_overridden + +HOOKS = Registry('hook') + + +class Hook: + stages = ('before_run', 'before_train_epoch', 'before_train_iter', + 'after_train_iter', 'after_train_epoch', 'before_val_epoch', + 'before_val_iter', 'after_val_iter', 'after_val_epoch', + 'after_run') + + def before_run(self, runner): + pass + + def after_run(self, runner): + pass + + def before_epoch(self, runner): + pass + + def after_epoch(self, runner): + pass + + def before_iter(self, runner): + pass + + def after_iter(self, runner): + pass + + def before_train_epoch(self, runner): + self.before_epoch(runner) + + def before_val_epoch(self, runner): + self.before_epoch(runner) + + def after_train_epoch(self, runner): + self.after_epoch(runner) + + def after_val_epoch(self, runner): + self.after_epoch(runner) + + def before_train_iter(self, runner): + self.before_iter(runner) + + def before_val_iter(self, runner): + self.before_iter(runner) + + def after_train_iter(self, runner): + self.after_iter(runner) + + def after_val_iter(self, runner): + self.after_iter(runner) + + def every_n_epochs(self, runner, n): + return (runner.epoch + 1) % n == 0 if n > 0 else False + + def every_n_inner_iters(self, runner, n): + return (runner.inner_iter + 1) % n == 0 if n > 0 else False + + def every_n_iters(self, runner, n): + return (runner.iter + 1) % n == 0 if n > 0 else False + + def end_of_epoch(self, runner): + return runner.inner_iter + 1 == len(runner.data_loader) + + def is_last_epoch(self, runner): + return runner.epoch + 1 == runner._max_epochs + + def is_last_iter(self, runner): + return runner.iter + 1 == runner._max_iters + + def get_triggered_stages(self): + trigger_stages = set() + for stage in Hook.stages: + if is_method_overridden(stage, Hook, self): + trigger_stages.add(stage) + + # some methods will be triggered in multi stages + # use this dict to map method to stages. + method_stages_map = { + 'before_epoch': ['before_train_epoch', 'before_val_epoch'], + 'after_epoch': ['after_train_epoch', 'after_val_epoch'], + 'before_iter': ['before_train_iter', 'before_val_iter'], + 'after_iter': ['after_train_iter', 'after_val_iter'], + } + + for method, map_stages in method_stages_map.items(): + if is_method_overridden(method, Hook, self): + trigger_stages.update(map_stages) + + return [stage for stage in Hook.stages if stage in trigger_stages] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/iter_timer.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/iter_timer.py new file mode 100644 index 00000000..cfd5002f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/iter_timer.py @@ -0,0 +1,18 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import time + +from .hook import HOOKS, Hook + + +@HOOKS.register_module() +class IterTimerHook(Hook): + + def before_epoch(self, runner): + self.t = time.time() + + def before_iter(self, runner): + runner.log_buffer.update({'data_time': time.time() - self.t}) + + def after_iter(self, runner): + runner.log_buffer.update({'time': time.time() - self.t}) + self.t = time.time() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/__init__.py new file mode 100644 index 00000000..a0b6b345 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/__init__.py @@ -0,0 +1,15 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .base import LoggerHook +from .dvclive import DvcliveLoggerHook +from .mlflow import MlflowLoggerHook +from .neptune import NeptuneLoggerHook +from .pavi import PaviLoggerHook +from .tensorboard import TensorboardLoggerHook +from .text import TextLoggerHook +from .wandb import WandbLoggerHook + +__all__ = [ + 'LoggerHook', 'MlflowLoggerHook', 'PaviLoggerHook', + 'TensorboardLoggerHook', 'TextLoggerHook', 'WandbLoggerHook', + 'NeptuneLoggerHook', 'DvcliveLoggerHook' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/base.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/base.py new file mode 100644 index 00000000..f8452567 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/base.py @@ -0,0 +1,166 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import numbers +from abc import ABCMeta, abstractmethod + +import numpy as np +import torch + +from ..hook import Hook + + +class LoggerHook(Hook): + """Base class for logger hooks. + + Args: + interval (int): Logging interval (every k iterations). + ignore_last (bool): Ignore the log of last iterations in each epoch + if less than `interval`. + reset_flag (bool): Whether to clear the output buffer after logging. + by_epoch (bool): Whether EpochBasedRunner is used. + """ + + __metaclass__ = ABCMeta + + def __init__(self, + interval=10, + ignore_last=True, + reset_flag=False, + by_epoch=True): + self.interval = interval + self.ignore_last = ignore_last + self.reset_flag = reset_flag + self.by_epoch = by_epoch + + @abstractmethod + def log(self, runner): + pass + + @staticmethod + def is_scalar(val, include_np=True, include_torch=True): + """Tell the input variable is a scalar or not. + + Args: + val: Input variable. + include_np (bool): Whether include 0-d np.ndarray as a scalar. + include_torch (bool): Whether include 0-d torch.Tensor as a scalar. + + Returns: + bool: True or False. + """ + if isinstance(val, numbers.Number): + return True + elif include_np and isinstance(val, np.ndarray) and val.ndim == 0: + return True + elif include_torch and isinstance(val, torch.Tensor) and len(val) == 1: + return True + else: + return False + + def get_mode(self, runner): + if runner.mode == 'train': + if 'time' in runner.log_buffer.output: + mode = 'train' + else: + mode = 'val' + elif runner.mode == 'val': + mode = 'val' + else: + raise ValueError(f"runner mode should be 'train' or 'val', " + f'but got {runner.mode}') + return mode + + def get_epoch(self, runner): + if runner.mode == 'train': + epoch = runner.epoch + 1 + elif runner.mode == 'val': + # normal val mode + # runner.epoch += 1 has been done before val workflow + epoch = runner.epoch + else: + raise ValueError(f"runner mode should be 'train' or 'val', " + f'but got {runner.mode}') + return epoch + + def get_iter(self, runner, inner_iter=False): + """Get the current training iteration step.""" + if self.by_epoch and inner_iter: + current_iter = runner.inner_iter + 1 + else: + current_iter = runner.iter + 1 + return current_iter + + def get_lr_tags(self, runner): + tags = {} + lrs = runner.current_lr() + if isinstance(lrs, dict): + for name, value in lrs.items(): + tags[f'learning_rate/{name}'] = value[0] + else: + tags['learning_rate'] = lrs[0] + return tags + + def get_momentum_tags(self, runner): + tags = {} + momentums = runner.current_momentum() + if isinstance(momentums, dict): + for name, value in momentums.items(): + tags[f'momentum/{name}'] = value[0] + else: + tags['momentum'] = momentums[0] + return tags + + def get_loggable_tags(self, + runner, + allow_scalar=True, + allow_text=False, + add_mode=True, + tags_to_skip=('time', 'data_time')): + tags = {} + for var, val in runner.log_buffer.output.items(): + if var in tags_to_skip: + continue + if self.is_scalar(val) and not allow_scalar: + continue + if isinstance(val, str) and not allow_text: + continue + if add_mode: + var = f'{self.get_mode(runner)}/{var}' + tags[var] = val + tags.update(self.get_lr_tags(runner)) + tags.update(self.get_momentum_tags(runner)) + return tags + + def before_run(self, runner): + for hook in runner.hooks[::-1]: + if isinstance(hook, LoggerHook): + hook.reset_flag = True + break + + def before_epoch(self, runner): + runner.log_buffer.clear() # clear logs of last epoch + + def after_train_iter(self, runner): + if self.by_epoch and self.every_n_inner_iters(runner, self.interval): + runner.log_buffer.average(self.interval) + elif not self.by_epoch and self.every_n_iters(runner, self.interval): + runner.log_buffer.average(self.interval) + elif self.end_of_epoch(runner) and not self.ignore_last: + # not precise but more stable + runner.log_buffer.average(self.interval) + + if runner.log_buffer.ready: + self.log(runner) + if self.reset_flag: + runner.log_buffer.clear_output() + + def after_train_epoch(self, runner): + if runner.log_buffer.ready: + self.log(runner) + if self.reset_flag: + runner.log_buffer.clear_output() + + def after_val_epoch(self, runner): + runner.log_buffer.average() + self.log(runner) + if self.reset_flag: + runner.log_buffer.clear_output() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/dvclive.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/dvclive.py new file mode 100644 index 00000000..687cdc58 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/dvclive.py @@ -0,0 +1,58 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from ...dist_utils import master_only +from ..hook import HOOKS +from .base import LoggerHook + + +@HOOKS.register_module() +class DvcliveLoggerHook(LoggerHook): + """Class to log metrics with dvclive. + + It requires `dvclive`_ to be installed. + + Args: + path (str): Directory where dvclive will write TSV log files. + interval (int): Logging interval (every k iterations). + Default 10. + ignore_last (bool): Ignore the log of last iterations in each epoch + if less than `interval`. + Default: True. + reset_flag (bool): Whether to clear the output buffer after logging. + Default: True. + by_epoch (bool): Whether EpochBasedRunner is used. + Default: True. + + .. _dvclive: + https://dvc.org/doc/dvclive + """ + + def __init__(self, + path, + interval=10, + ignore_last=True, + reset_flag=True, + by_epoch=True): + + super(DvcliveLoggerHook, self).__init__(interval, ignore_last, + reset_flag, by_epoch) + self.path = path + self.import_dvclive() + + def import_dvclive(self): + try: + import dvclive + except ImportError: + raise ImportError( + 'Please run "pip install dvclive" to install dvclive') + self.dvclive = dvclive + + @master_only + def before_run(self, runner): + self.dvclive.init(self.path) + + @master_only + def log(self, runner): + tags = self.get_loggable_tags(runner) + if tags: + for k, v in tags.items(): + self.dvclive.log(k, v, step=self.get_iter(runner)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/mlflow.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/mlflow.py new file mode 100644 index 00000000..f9a72592 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/mlflow.py @@ -0,0 +1,78 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from ...dist_utils import master_only +from ..hook import HOOKS +from .base import LoggerHook + + +@HOOKS.register_module() +class MlflowLoggerHook(LoggerHook): + + def __init__(self, + exp_name=None, + tags=None, + log_model=True, + interval=10, + ignore_last=True, + reset_flag=False, + by_epoch=True): + """Class to log metrics and (optionally) a trained model to MLflow. + + It requires `MLflow`_ to be installed. + + Args: + exp_name (str, optional): Name of the experiment to be used. + Default None. + If not None, set the active experiment. + If experiment does not exist, an experiment with provided name + will be created. + tags (dict of str: str, optional): Tags for the current run. + Default None. + If not None, set tags for the current run. + log_model (bool, optional): Whether to log an MLflow artifact. + Default True. + If True, log runner.model as an MLflow artifact + for the current run. + interval (int): Logging interval (every k iterations). + ignore_last (bool): Ignore the log of last iterations in each epoch + if less than `interval`. + reset_flag (bool): Whether to clear the output buffer after logging + by_epoch (bool): Whether EpochBasedRunner is used. + + .. _MLflow: + https://www.mlflow.org/docs/latest/index.html + """ + super(MlflowLoggerHook, self).__init__(interval, ignore_last, + reset_flag, by_epoch) + self.import_mlflow() + self.exp_name = exp_name + self.tags = tags + self.log_model = log_model + + def import_mlflow(self): + try: + import mlflow + import mlflow.pytorch as mlflow_pytorch + except ImportError: + raise ImportError( + 'Please run "pip install mlflow" to install mlflow') + self.mlflow = mlflow + self.mlflow_pytorch = mlflow_pytorch + + @master_only + def before_run(self, runner): + super(MlflowLoggerHook, self).before_run(runner) + if self.exp_name is not None: + self.mlflow.set_experiment(self.exp_name) + if self.tags is not None: + self.mlflow.set_tags(self.tags) + + @master_only + def log(self, runner): + tags = self.get_loggable_tags(runner) + if tags: + self.mlflow.log_metrics(tags, step=self.get_iter(runner)) + + @master_only + def after_run(self, runner): + if self.log_model: + self.mlflow_pytorch.log_model(runner.model, 'models') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/neptune.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/neptune.py new file mode 100644 index 00000000..7a38772b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/neptune.py @@ -0,0 +1,82 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from ...dist_utils import master_only +from ..hook import HOOKS +from .base import LoggerHook + + +@HOOKS.register_module() +class NeptuneLoggerHook(LoggerHook): + """Class to log metrics to NeptuneAI. + + It requires `neptune-client` to be installed. + + Args: + init_kwargs (dict): a dict contains the initialization keys as below: + - project (str): Name of a project in a form of + namespace/project_name. If None, the value of + NEPTUNE_PROJECT environment variable will be taken. + - api_token (str): User’s API token. + If None, the value of NEPTUNE_API_TOKEN environment + variable will be taken. Note: It is strongly recommended + to use NEPTUNE_API_TOKEN environment variable rather than + placing your API token in plain text in your source code. + - name (str, optional, default is 'Untitled'): Editable name of + the run. Name is displayed in the run's Details and in + Runs table as a column. + Check https://docs.neptune.ai/api-reference/neptune#init for + more init arguments. + interval (int): Logging interval (every k iterations). + ignore_last (bool): Ignore the log of last iterations in each epoch + if less than `interval`. + reset_flag (bool): Whether to clear the output buffer after logging + by_epoch (bool): Whether EpochBasedRunner is used. + + .. _NeptuneAI: + https://docs.neptune.ai/you-should-know/logging-metadata + """ + + def __init__(self, + init_kwargs=None, + interval=10, + ignore_last=True, + reset_flag=True, + with_step=True, + by_epoch=True): + + super(NeptuneLoggerHook, self).__init__(interval, ignore_last, + reset_flag, by_epoch) + self.import_neptune() + self.init_kwargs = init_kwargs + self.with_step = with_step + + def import_neptune(self): + try: + import neptune.new as neptune + except ImportError: + raise ImportError( + 'Please run "pip install neptune-client" to install neptune') + self.neptune = neptune + self.run = None + + @master_only + def before_run(self, runner): + if self.init_kwargs: + self.run = self.neptune.init(**self.init_kwargs) + else: + self.run = self.neptune.init() + + @master_only + def log(self, runner): + tags = self.get_loggable_tags(runner) + if tags: + for tag_name, tag_value in tags.items(): + if self.with_step: + self.run[tag_name].log( + tag_value, step=self.get_iter(runner)) + else: + tags['global_step'] = self.get_iter(runner) + self.run[tag_name].log(tags) + + @master_only + def after_run(self, runner): + self.run.stop() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/pavi.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/pavi.py new file mode 100644 index 00000000..5d1c4286 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/pavi.py @@ -0,0 +1,117 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import json +import os +import os.path as osp + +import torch +import yaml + +import annotator.mmpkg.mmcv as mmcv +from ....parallel.utils import is_module_wrapper +from ...dist_utils import master_only +from ..hook import HOOKS +from .base import LoggerHook + + +@HOOKS.register_module() +class PaviLoggerHook(LoggerHook): + + def __init__(self, + init_kwargs=None, + add_graph=False, + add_last_ckpt=False, + interval=10, + ignore_last=True, + reset_flag=False, + by_epoch=True, + img_key='img_info'): + super(PaviLoggerHook, self).__init__(interval, ignore_last, reset_flag, + by_epoch) + self.init_kwargs = init_kwargs + self.add_graph = add_graph + self.add_last_ckpt = add_last_ckpt + self.img_key = img_key + + @master_only + def before_run(self, runner): + super(PaviLoggerHook, self).before_run(runner) + try: + from pavi import SummaryWriter + except ImportError: + raise ImportError('Please run "pip install pavi" to install pavi.') + + self.run_name = runner.work_dir.split('/')[-1] + + if not self.init_kwargs: + self.init_kwargs = dict() + self.init_kwargs['name'] = self.run_name + self.init_kwargs['model'] = runner._model_name + if runner.meta is not None: + if 'config_dict' in runner.meta: + config_dict = runner.meta['config_dict'] + assert isinstance( + config_dict, + dict), ('meta["config_dict"] has to be of a dict, ' + f'but got {type(config_dict)}') + elif 'config_file' in runner.meta: + config_file = runner.meta['config_file'] + config_dict = dict(mmcv.Config.fromfile(config_file)) + else: + config_dict = None + if config_dict is not None: + # 'max_.*iter' is parsed in pavi sdk as the maximum iterations + # to properly set up the progress bar. + config_dict = config_dict.copy() + config_dict.setdefault('max_iter', runner.max_iters) + # non-serializable values are first converted in + # mmcv.dump to json + config_dict = json.loads( + mmcv.dump(config_dict, file_format='json')) + session_text = yaml.dump(config_dict) + self.init_kwargs['session_text'] = session_text + self.writer = SummaryWriter(**self.init_kwargs) + + def get_step(self, runner): + """Get the total training step/epoch.""" + if self.get_mode(runner) == 'val' and self.by_epoch: + return self.get_epoch(runner) + else: + return self.get_iter(runner) + + @master_only + def log(self, runner): + tags = self.get_loggable_tags(runner, add_mode=False) + if tags: + self.writer.add_scalars( + self.get_mode(runner), tags, self.get_step(runner)) + + @master_only + def after_run(self, runner): + if self.add_last_ckpt: + ckpt_path = osp.join(runner.work_dir, 'latest.pth') + if osp.islink(ckpt_path): + ckpt_path = osp.join(runner.work_dir, os.readlink(ckpt_path)) + + if osp.isfile(ckpt_path): + # runner.epoch += 1 has been done before `after_run`. + iteration = runner.epoch if self.by_epoch else runner.iter + return self.writer.add_snapshot_file( + tag=self.run_name, + snapshot_file_path=ckpt_path, + iteration=iteration) + + # flush the buffer and send a task ending signal to Pavi + self.writer.close() + + @master_only + def before_epoch(self, runner): + if runner.epoch == 0 and self.add_graph: + if is_module_wrapper(runner.model): + _model = runner.model.module + else: + _model = runner.model + device = next(_model.parameters()).device + data = next(iter(runner.data_loader)) + image = data[self.img_key][0:1].to(device) + with torch.no_grad(): + self.writer.add_graph(_model, image) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/tensorboard.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/tensorboard.py new file mode 100644 index 00000000..7c480a56 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/tensorboard.py @@ -0,0 +1,57 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os.path as osp + +from annotator.mmpkg.mmcv.utils import TORCH_VERSION, digit_version +from ...dist_utils import master_only +from ..hook import HOOKS +from .base import LoggerHook + + +@HOOKS.register_module() +class TensorboardLoggerHook(LoggerHook): + + def __init__(self, + log_dir=None, + interval=10, + ignore_last=True, + reset_flag=False, + by_epoch=True): + super(TensorboardLoggerHook, self).__init__(interval, ignore_last, + reset_flag, by_epoch) + self.log_dir = log_dir + + @master_only + def before_run(self, runner): + super(TensorboardLoggerHook, self).before_run(runner) + if (TORCH_VERSION == 'parrots' + or digit_version(TORCH_VERSION) < digit_version('1.1')): + try: + from tensorboardX import SummaryWriter + except ImportError: + raise ImportError('Please install tensorboardX to use ' + 'TensorboardLoggerHook.') + else: + try: + from torch.utils.tensorboard import SummaryWriter + except ImportError: + raise ImportError( + 'Please run "pip install future tensorboard" to install ' + 'the dependencies to use torch.utils.tensorboard ' + '(applicable to PyTorch 1.1 or higher)') + + if self.log_dir is None: + self.log_dir = osp.join(runner.work_dir, 'tf_logs') + self.writer = SummaryWriter(self.log_dir) + + @master_only + def log(self, runner): + tags = self.get_loggable_tags(runner, allow_text=True) + for tag, val in tags.items(): + if isinstance(val, str): + self.writer.add_text(tag, val, self.get_iter(runner)) + else: + self.writer.add_scalar(tag, val, self.get_iter(runner)) + + @master_only + def after_run(self, runner): + self.writer.close() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/text.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/text.py new file mode 100644 index 00000000..0b305774 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/text.py @@ -0,0 +1,256 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import datetime +import os +import os.path as osp +from collections import OrderedDict + +import torch +import torch.distributed as dist + +import annotator.mmpkg.mmcv as mmcv +from annotator.mmpkg.mmcv.fileio.file_client import FileClient +from annotator.mmpkg.mmcv.utils import is_tuple_of, scandir +from ..hook import HOOKS +from .base import LoggerHook + + +@HOOKS.register_module() +class TextLoggerHook(LoggerHook): + """Logger hook in text. + + In this logger hook, the information will be printed on terminal and + saved in json file. + + Args: + by_epoch (bool, optional): Whether EpochBasedRunner is used. + Default: True. + interval (int, optional): Logging interval (every k iterations). + Default: 10. + ignore_last (bool, optional): Ignore the log of last iterations in each + epoch if less than :attr:`interval`. Default: True. + reset_flag (bool, optional): Whether to clear the output buffer after + logging. Default: False. + interval_exp_name (int, optional): Logging interval for experiment + name. This feature is to help users conveniently get the experiment + information from screen or log file. Default: 1000. + out_dir (str, optional): Logs are saved in ``runner.work_dir`` default. + If ``out_dir`` is specified, logs will be copied to a new directory + which is the concatenation of ``out_dir`` and the last level + directory of ``runner.work_dir``. Default: None. + `New in version 1.3.16.` + out_suffix (str or tuple[str], optional): Those filenames ending with + ``out_suffix`` will be copied to ``out_dir``. + Default: ('.log.json', '.log', '.py'). + `New in version 1.3.16.` + keep_local (bool, optional): Whether to keep local log when + :attr:`out_dir` is specified. If False, the local log will be + removed. Default: True. + `New in version 1.3.16.` + file_client_args (dict, optional): Arguments to instantiate a + FileClient. See :class:`mmcv.fileio.FileClient` for details. + Default: None. + `New in version 1.3.16.` + """ + + def __init__(self, + by_epoch=True, + interval=10, + ignore_last=True, + reset_flag=False, + interval_exp_name=1000, + out_dir=None, + out_suffix=('.log.json', '.log', '.py'), + keep_local=True, + file_client_args=None): + super(TextLoggerHook, self).__init__(interval, ignore_last, reset_flag, + by_epoch) + self.by_epoch = by_epoch + self.time_sec_tot = 0 + self.interval_exp_name = interval_exp_name + + if out_dir is None and file_client_args is not None: + raise ValueError( + 'file_client_args should be "None" when `out_dir` is not' + 'specified.') + self.out_dir = out_dir + + if not (out_dir is None or isinstance(out_dir, str) + or is_tuple_of(out_dir, str)): + raise TypeError('out_dir should be "None" or string or tuple of ' + 'string, but got {out_dir}') + self.out_suffix = out_suffix + + self.keep_local = keep_local + self.file_client_args = file_client_args + if self.out_dir is not None: + self.file_client = FileClient.infer_client(file_client_args, + self.out_dir) + + def before_run(self, runner): + super(TextLoggerHook, self).before_run(runner) + + if self.out_dir is not None: + self.file_client = FileClient.infer_client(self.file_client_args, + self.out_dir) + # The final `self.out_dir` is the concatenation of `self.out_dir` + # and the last level directory of `runner.work_dir` + basename = osp.basename(runner.work_dir.rstrip(osp.sep)) + self.out_dir = self.file_client.join_path(self.out_dir, basename) + runner.logger.info( + (f'Text logs will be saved to {self.out_dir} by ' + f'{self.file_client.name} after the training process.')) + + self.start_iter = runner.iter + self.json_log_path = osp.join(runner.work_dir, + f'{runner.timestamp}.log.json') + if runner.meta is not None: + self._dump_log(runner.meta, runner) + + def _get_max_memory(self, runner): + device = getattr(runner.model, 'output_device', None) + mem = torch.cuda.max_memory_allocated(device=device) + mem_mb = torch.tensor([mem / (1024 * 1024)], + dtype=torch.int, + device=device) + if runner.world_size > 1: + dist.reduce(mem_mb, 0, op=dist.ReduceOp.MAX) + return mem_mb.item() + + def _log_info(self, log_dict, runner): + # print exp name for users to distinguish experiments + # at every ``interval_exp_name`` iterations and the end of each epoch + if runner.meta is not None and 'exp_name' in runner.meta: + if (self.every_n_iters(runner, self.interval_exp_name)) or ( + self.by_epoch and self.end_of_epoch(runner)): + exp_info = f'Exp name: {runner.meta["exp_name"]}' + runner.logger.info(exp_info) + + if log_dict['mode'] == 'train': + if isinstance(log_dict['lr'], dict): + lr_str = [] + for k, val in log_dict['lr'].items(): + lr_str.append(f'lr_{k}: {val:.3e}') + lr_str = ' '.join(lr_str) + else: + lr_str = f'lr: {log_dict["lr"]:.3e}' + + # by epoch: Epoch [4][100/1000] + # by iter: Iter [100/100000] + if self.by_epoch: + log_str = f'Epoch [{log_dict["epoch"]}]' \ + f'[{log_dict["iter"]}/{len(runner.data_loader)}]\t' + else: + log_str = f'Iter [{log_dict["iter"]}/{runner.max_iters}]\t' + log_str += f'{lr_str}, ' + + if 'time' in log_dict.keys(): + self.time_sec_tot += (log_dict['time'] * self.interval) + time_sec_avg = self.time_sec_tot / ( + runner.iter - self.start_iter + 1) + eta_sec = time_sec_avg * (runner.max_iters - runner.iter - 1) + eta_str = str(datetime.timedelta(seconds=int(eta_sec))) + log_str += f'eta: {eta_str}, ' + log_str += f'time: {log_dict["time"]:.3f}, ' \ + f'data_time: {log_dict["data_time"]:.3f}, ' + # statistic memory + if torch.cuda.is_available(): + log_str += f'memory: {log_dict["memory"]}, ' + else: + # val/test time + # here 1000 is the length of the val dataloader + # by epoch: Epoch[val] [4][1000] + # by iter: Iter[val] [1000] + if self.by_epoch: + log_str = f'Epoch({log_dict["mode"]}) ' \ + f'[{log_dict["epoch"]}][{log_dict["iter"]}]\t' + else: + log_str = f'Iter({log_dict["mode"]}) [{log_dict["iter"]}]\t' + + log_items = [] + for name, val in log_dict.items(): + # TODO: resolve this hack + # these items have been in log_str + if name in [ + 'mode', 'Epoch', 'iter', 'lr', 'time', 'data_time', + 'memory', 'epoch' + ]: + continue + if isinstance(val, float): + val = f'{val:.4f}' + log_items.append(f'{name}: {val}') + log_str += ', '.join(log_items) + + runner.logger.info(log_str) + + def _dump_log(self, log_dict, runner): + # dump log in json format + json_log = OrderedDict() + for k, v in log_dict.items(): + json_log[k] = self._round_float(v) + # only append log at last line + if runner.rank == 0: + with open(self.json_log_path, 'a+') as f: + mmcv.dump(json_log, f, file_format='json') + f.write('\n') + + def _round_float(self, items): + if isinstance(items, list): + return [self._round_float(item) for item in items] + elif isinstance(items, float): + return round(items, 5) + else: + return items + + def log(self, runner): + if 'eval_iter_num' in runner.log_buffer.output: + # this doesn't modify runner.iter and is regardless of by_epoch + cur_iter = runner.log_buffer.output.pop('eval_iter_num') + else: + cur_iter = self.get_iter(runner, inner_iter=True) + + log_dict = OrderedDict( + mode=self.get_mode(runner), + epoch=self.get_epoch(runner), + iter=cur_iter) + + # only record lr of the first param group + cur_lr = runner.current_lr() + if isinstance(cur_lr, list): + log_dict['lr'] = cur_lr[0] + else: + assert isinstance(cur_lr, dict) + log_dict['lr'] = {} + for k, lr_ in cur_lr.items(): + assert isinstance(lr_, list) + log_dict['lr'].update({k: lr_[0]}) + + if 'time' in runner.log_buffer.output: + # statistic memory + if torch.cuda.is_available(): + log_dict['memory'] = self._get_max_memory(runner) + + log_dict = dict(log_dict, **runner.log_buffer.output) + + self._log_info(log_dict, runner) + self._dump_log(log_dict, runner) + return log_dict + + def after_run(self, runner): + # copy or upload logs to self.out_dir + if self.out_dir is not None: + for filename in scandir(runner.work_dir, self.out_suffix, True): + local_filepath = osp.join(runner.work_dir, filename) + out_filepath = self.file_client.join_path( + self.out_dir, filename) + with open(local_filepath, 'r') as f: + self.file_client.put_text(f.read(), out_filepath) + + runner.logger.info( + (f'The file {local_filepath} has been uploaded to ' + f'{out_filepath}.')) + + if not self.keep_local: + os.remove(local_filepath) + runner.logger.info( + (f'{local_filepath} was removed due to the ' + '`self.keep_local=False`')) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/wandb.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/wandb.py new file mode 100644 index 00000000..9f680846 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/logger/wandb.py @@ -0,0 +1,56 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from ...dist_utils import master_only +from ..hook import HOOKS +from .base import LoggerHook + + +@HOOKS.register_module() +class WandbLoggerHook(LoggerHook): + + def __init__(self, + init_kwargs=None, + interval=10, + ignore_last=True, + reset_flag=False, + commit=True, + by_epoch=True, + with_step=True): + super(WandbLoggerHook, self).__init__(interval, ignore_last, + reset_flag, by_epoch) + self.import_wandb() + self.init_kwargs = init_kwargs + self.commit = commit + self.with_step = with_step + + def import_wandb(self): + try: + import wandb + except ImportError: + raise ImportError( + 'Please run "pip install wandb" to install wandb') + self.wandb = wandb + + @master_only + def before_run(self, runner): + super(WandbLoggerHook, self).before_run(runner) + if self.wandb is None: + self.import_wandb() + if self.init_kwargs: + self.wandb.init(**self.init_kwargs) + else: + self.wandb.init() + + @master_only + def log(self, runner): + tags = self.get_loggable_tags(runner) + if tags: + if self.with_step: + self.wandb.log( + tags, step=self.get_iter(runner), commit=self.commit) + else: + tags['global_step'] = self.get_iter(runner) + self.wandb.log(tags, commit=self.commit) + + @master_only + def after_run(self, runner): + self.wandb.join() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/lr_updater.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/lr_updater.py new file mode 100644 index 00000000..b9851d2c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/lr_updater.py @@ -0,0 +1,670 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import numbers +from math import cos, pi + +import annotator.mmpkg.mmcv as mmcv +from .hook import HOOKS, Hook + + +class LrUpdaterHook(Hook): + """LR Scheduler in MMCV. + + Args: + by_epoch (bool): LR changes epoch by epoch + warmup (string): Type of warmup used. It can be None(use no warmup), + 'constant', 'linear' or 'exp' + warmup_iters (int): The number of iterations or epochs that warmup + lasts + warmup_ratio (float): LR used at the beginning of warmup equals to + warmup_ratio * initial_lr + warmup_by_epoch (bool): When warmup_by_epoch == True, warmup_iters + means the number of epochs that warmup lasts, otherwise means the + number of iteration that warmup lasts + """ + + def __init__(self, + by_epoch=True, + warmup=None, + warmup_iters=0, + warmup_ratio=0.1, + warmup_by_epoch=False): + # validate the "warmup" argument + if warmup is not None: + if warmup not in ['constant', 'linear', 'exp']: + raise ValueError( + f'"{warmup}" is not a supported type for warming up, valid' + ' types are "constant" and "linear"') + if warmup is not None: + assert warmup_iters > 0, \ + '"warmup_iters" must be a positive integer' + assert 0 < warmup_ratio <= 1.0, \ + '"warmup_ratio" must be in range (0,1]' + + self.by_epoch = by_epoch + self.warmup = warmup + self.warmup_iters = warmup_iters + self.warmup_ratio = warmup_ratio + self.warmup_by_epoch = warmup_by_epoch + + if self.warmup_by_epoch: + self.warmup_epochs = self.warmup_iters + self.warmup_iters = None + else: + self.warmup_epochs = None + + self.base_lr = [] # initial lr for all param groups + self.regular_lr = [] # expected lr if no warming up is performed + + def _set_lr(self, runner, lr_groups): + if isinstance(runner.optimizer, dict): + for k, optim in runner.optimizer.items(): + for param_group, lr in zip(optim.param_groups, lr_groups[k]): + param_group['lr'] = lr + else: + for param_group, lr in zip(runner.optimizer.param_groups, + lr_groups): + param_group['lr'] = lr + + def get_lr(self, runner, base_lr): + raise NotImplementedError + + def get_regular_lr(self, runner): + if isinstance(runner.optimizer, dict): + lr_groups = {} + for k in runner.optimizer.keys(): + _lr_group = [ + self.get_lr(runner, _base_lr) + for _base_lr in self.base_lr[k] + ] + lr_groups.update({k: _lr_group}) + + return lr_groups + else: + return [self.get_lr(runner, _base_lr) for _base_lr in self.base_lr] + + def get_warmup_lr(self, cur_iters): + + def _get_warmup_lr(cur_iters, regular_lr): + if self.warmup == 'constant': + warmup_lr = [_lr * self.warmup_ratio for _lr in regular_lr] + elif self.warmup == 'linear': + k = (1 - cur_iters / self.warmup_iters) * (1 - + self.warmup_ratio) + warmup_lr = [_lr * (1 - k) for _lr in regular_lr] + elif self.warmup == 'exp': + k = self.warmup_ratio**(1 - cur_iters / self.warmup_iters) + warmup_lr = [_lr * k for _lr in regular_lr] + return warmup_lr + + if isinstance(self.regular_lr, dict): + lr_groups = {} + for key, regular_lr in self.regular_lr.items(): + lr_groups[key] = _get_warmup_lr(cur_iters, regular_lr) + return lr_groups + else: + return _get_warmup_lr(cur_iters, self.regular_lr) + + def before_run(self, runner): + # NOTE: when resuming from a checkpoint, if 'initial_lr' is not saved, + # it will be set according to the optimizer params + if isinstance(runner.optimizer, dict): + self.base_lr = {} + for k, optim in runner.optimizer.items(): + for group in optim.param_groups: + group.setdefault('initial_lr', group['lr']) + _base_lr = [ + group['initial_lr'] for group in optim.param_groups + ] + self.base_lr.update({k: _base_lr}) + else: + for group in runner.optimizer.param_groups: + group.setdefault('initial_lr', group['lr']) + self.base_lr = [ + group['initial_lr'] for group in runner.optimizer.param_groups + ] + + def before_train_epoch(self, runner): + if self.warmup_iters is None: + epoch_len = len(runner.data_loader) + self.warmup_iters = self.warmup_epochs * epoch_len + + if not self.by_epoch: + return + + self.regular_lr = self.get_regular_lr(runner) + self._set_lr(runner, self.regular_lr) + + def before_train_iter(self, runner): + cur_iter = runner.iter + if not self.by_epoch: + self.regular_lr = self.get_regular_lr(runner) + if self.warmup is None or cur_iter >= self.warmup_iters: + self._set_lr(runner, self.regular_lr) + else: + warmup_lr = self.get_warmup_lr(cur_iter) + self._set_lr(runner, warmup_lr) + elif self.by_epoch: + if self.warmup is None or cur_iter > self.warmup_iters: + return + elif cur_iter == self.warmup_iters: + self._set_lr(runner, self.regular_lr) + else: + warmup_lr = self.get_warmup_lr(cur_iter) + self._set_lr(runner, warmup_lr) + + +@HOOKS.register_module() +class FixedLrUpdaterHook(LrUpdaterHook): + + def __init__(self, **kwargs): + super(FixedLrUpdaterHook, self).__init__(**kwargs) + + def get_lr(self, runner, base_lr): + return base_lr + + +@HOOKS.register_module() +class StepLrUpdaterHook(LrUpdaterHook): + """Step LR scheduler with min_lr clipping. + + Args: + step (int | list[int]): Step to decay the LR. If an int value is given, + regard it as the decay interval. If a list is given, decay LR at + these steps. + gamma (float, optional): Decay LR ratio. Default: 0.1. + min_lr (float, optional): Minimum LR value to keep. If LR after decay + is lower than `min_lr`, it will be clipped to this value. If None + is given, we don't perform lr clipping. Default: None. + """ + + def __init__(self, step, gamma=0.1, min_lr=None, **kwargs): + if isinstance(step, list): + assert mmcv.is_list_of(step, int) + assert all([s > 0 for s in step]) + elif isinstance(step, int): + assert step > 0 + else: + raise TypeError('"step" must be a list or integer') + self.step = step + self.gamma = gamma + self.min_lr = min_lr + super(StepLrUpdaterHook, self).__init__(**kwargs) + + def get_lr(self, runner, base_lr): + progress = runner.epoch if self.by_epoch else runner.iter + + # calculate exponential term + if isinstance(self.step, int): + exp = progress // self.step + else: + exp = len(self.step) + for i, s in enumerate(self.step): + if progress < s: + exp = i + break + + lr = base_lr * (self.gamma**exp) + if self.min_lr is not None: + # clip to a minimum value + lr = max(lr, self.min_lr) + return lr + + +@HOOKS.register_module() +class ExpLrUpdaterHook(LrUpdaterHook): + + def __init__(self, gamma, **kwargs): + self.gamma = gamma + super(ExpLrUpdaterHook, self).__init__(**kwargs) + + def get_lr(self, runner, base_lr): + progress = runner.epoch if self.by_epoch else runner.iter + return base_lr * self.gamma**progress + + +@HOOKS.register_module() +class PolyLrUpdaterHook(LrUpdaterHook): + + def __init__(self, power=1., min_lr=0., **kwargs): + self.power = power + self.min_lr = min_lr + super(PolyLrUpdaterHook, self).__init__(**kwargs) + + def get_lr(self, runner, base_lr): + if self.by_epoch: + progress = runner.epoch + max_progress = runner.max_epochs + else: + progress = runner.iter + max_progress = runner.max_iters + coeff = (1 - progress / max_progress)**self.power + return (base_lr - self.min_lr) * coeff + self.min_lr + + +@HOOKS.register_module() +class InvLrUpdaterHook(LrUpdaterHook): + + def __init__(self, gamma, power=1., **kwargs): + self.gamma = gamma + self.power = power + super(InvLrUpdaterHook, self).__init__(**kwargs) + + def get_lr(self, runner, base_lr): + progress = runner.epoch if self.by_epoch else runner.iter + return base_lr * (1 + self.gamma * progress)**(-self.power) + + +@HOOKS.register_module() +class CosineAnnealingLrUpdaterHook(LrUpdaterHook): + + def __init__(self, min_lr=None, min_lr_ratio=None, **kwargs): + assert (min_lr is None) ^ (min_lr_ratio is None) + self.min_lr = min_lr + self.min_lr_ratio = min_lr_ratio + super(CosineAnnealingLrUpdaterHook, self).__init__(**kwargs) + + def get_lr(self, runner, base_lr): + if self.by_epoch: + progress = runner.epoch + max_progress = runner.max_epochs + else: + progress = runner.iter + max_progress = runner.max_iters + + if self.min_lr_ratio is not None: + target_lr = base_lr * self.min_lr_ratio + else: + target_lr = self.min_lr + return annealing_cos(base_lr, target_lr, progress / max_progress) + + +@HOOKS.register_module() +class FlatCosineAnnealingLrUpdaterHook(LrUpdaterHook): + """Flat + Cosine lr schedule. + + Modified from https://github.com/fastai/fastai/blob/master/fastai/callback/schedule.py#L128 # noqa: E501 + + Args: + start_percent (float): When to start annealing the learning rate + after the percentage of the total training steps. + The value should be in range [0, 1). + Default: 0.75 + min_lr (float, optional): The minimum lr. Default: None. + min_lr_ratio (float, optional): The ratio of minimum lr to the base lr. + Either `min_lr` or `min_lr_ratio` should be specified. + Default: None. + """ + + def __init__(self, + start_percent=0.75, + min_lr=None, + min_lr_ratio=None, + **kwargs): + assert (min_lr is None) ^ (min_lr_ratio is None) + if start_percent < 0 or start_percent > 1 or not isinstance( + start_percent, float): + raise ValueError( + 'expected float between 0 and 1 start_percent, but ' + f'got {start_percent}') + self.start_percent = start_percent + self.min_lr = min_lr + self.min_lr_ratio = min_lr_ratio + super(FlatCosineAnnealingLrUpdaterHook, self).__init__(**kwargs) + + def get_lr(self, runner, base_lr): + if self.by_epoch: + start = round(runner.max_epochs * self.start_percent) + progress = runner.epoch - start + max_progress = runner.max_epochs - start + else: + start = round(runner.max_iters * self.start_percent) + progress = runner.iter - start + max_progress = runner.max_iters - start + + if self.min_lr_ratio is not None: + target_lr = base_lr * self.min_lr_ratio + else: + target_lr = self.min_lr + + if progress < 0: + return base_lr + else: + return annealing_cos(base_lr, target_lr, progress / max_progress) + + +@HOOKS.register_module() +class CosineRestartLrUpdaterHook(LrUpdaterHook): + """Cosine annealing with restarts learning rate scheme. + + Args: + periods (list[int]): Periods for each cosine anneling cycle. + restart_weights (list[float], optional): Restart weights at each + restart iteration. Default: [1]. + min_lr (float, optional): The minimum lr. Default: None. + min_lr_ratio (float, optional): The ratio of minimum lr to the base lr. + Either `min_lr` or `min_lr_ratio` should be specified. + Default: None. + """ + + def __init__(self, + periods, + restart_weights=[1], + min_lr=None, + min_lr_ratio=None, + **kwargs): + assert (min_lr is None) ^ (min_lr_ratio is None) + self.periods = periods + self.min_lr = min_lr + self.min_lr_ratio = min_lr_ratio + self.restart_weights = restart_weights + assert (len(self.periods) == len(self.restart_weights) + ), 'periods and restart_weights should have the same length.' + super(CosineRestartLrUpdaterHook, self).__init__(**kwargs) + + self.cumulative_periods = [ + sum(self.periods[0:i + 1]) for i in range(0, len(self.periods)) + ] + + def get_lr(self, runner, base_lr): + if self.by_epoch: + progress = runner.epoch + else: + progress = runner.iter + + if self.min_lr_ratio is not None: + target_lr = base_lr * self.min_lr_ratio + else: + target_lr = self.min_lr + + idx = get_position_from_periods(progress, self.cumulative_periods) + current_weight = self.restart_weights[idx] + nearest_restart = 0 if idx == 0 else self.cumulative_periods[idx - 1] + current_periods = self.periods[idx] + + alpha = min((progress - nearest_restart) / current_periods, 1) + return annealing_cos(base_lr, target_lr, alpha, current_weight) + + +def get_position_from_periods(iteration, cumulative_periods): + """Get the position from a period list. + + It will return the index of the right-closest number in the period list. + For example, the cumulative_periods = [100, 200, 300, 400], + if iteration == 50, return 0; + if iteration == 210, return 2; + if iteration == 300, return 3. + + Args: + iteration (int): Current iteration. + cumulative_periods (list[int]): Cumulative period list. + + Returns: + int: The position of the right-closest number in the period list. + """ + for i, period in enumerate(cumulative_periods): + if iteration < period: + return i + raise ValueError(f'Current iteration {iteration} exceeds ' + f'cumulative_periods {cumulative_periods}') + + +@HOOKS.register_module() +class CyclicLrUpdaterHook(LrUpdaterHook): + """Cyclic LR Scheduler. + + Implement the cyclical learning rate policy (CLR) described in + https://arxiv.org/pdf/1506.01186.pdf + + Different from the original paper, we use cosine annealing rather than + triangular policy inside a cycle. This improves the performance in the + 3D detection area. + + Args: + by_epoch (bool): Whether to update LR by epoch. + target_ratio (tuple[float]): Relative ratio of the highest LR and the + lowest LR to the initial LR. + cyclic_times (int): Number of cycles during training + step_ratio_up (float): The ratio of the increasing process of LR in + the total cycle. + anneal_strategy (str): {'cos', 'linear'} + Specifies the annealing strategy: 'cos' for cosine annealing, + 'linear' for linear annealing. Default: 'cos'. + """ + + def __init__(self, + by_epoch=False, + target_ratio=(10, 1e-4), + cyclic_times=1, + step_ratio_up=0.4, + anneal_strategy='cos', + **kwargs): + if isinstance(target_ratio, float): + target_ratio = (target_ratio, target_ratio / 1e5) + elif isinstance(target_ratio, tuple): + target_ratio = (target_ratio[0], target_ratio[0] / 1e5) \ + if len(target_ratio) == 1 else target_ratio + else: + raise ValueError('target_ratio should be either float ' + f'or tuple, got {type(target_ratio)}') + + assert len(target_ratio) == 2, \ + '"target_ratio" must be list or tuple of two floats' + assert 0 <= step_ratio_up < 1.0, \ + '"step_ratio_up" must be in range [0,1)' + + self.target_ratio = target_ratio + self.cyclic_times = cyclic_times + self.step_ratio_up = step_ratio_up + self.lr_phases = [] # init lr_phases + # validate anneal_strategy + if anneal_strategy not in ['cos', 'linear']: + raise ValueError('anneal_strategy must be one of "cos" or ' + f'"linear", instead got {anneal_strategy}') + elif anneal_strategy == 'cos': + self.anneal_func = annealing_cos + elif anneal_strategy == 'linear': + self.anneal_func = annealing_linear + + assert not by_epoch, \ + 'currently only support "by_epoch" = False' + super(CyclicLrUpdaterHook, self).__init__(by_epoch, **kwargs) + + def before_run(self, runner): + super(CyclicLrUpdaterHook, self).before_run(runner) + # initiate lr_phases + # total lr_phases are separated as up and down + max_iter_per_phase = runner.max_iters // self.cyclic_times + iter_up_phase = int(self.step_ratio_up * max_iter_per_phase) + self.lr_phases.append( + [0, iter_up_phase, max_iter_per_phase, 1, self.target_ratio[0]]) + self.lr_phases.append([ + iter_up_phase, max_iter_per_phase, max_iter_per_phase, + self.target_ratio[0], self.target_ratio[1] + ]) + + def get_lr(self, runner, base_lr): + curr_iter = runner.iter + for (start_iter, end_iter, max_iter_per_phase, start_ratio, + end_ratio) in self.lr_phases: + curr_iter %= max_iter_per_phase + if start_iter <= curr_iter < end_iter: + progress = curr_iter - start_iter + return self.anneal_func(base_lr * start_ratio, + base_lr * end_ratio, + progress / (end_iter - start_iter)) + + +@HOOKS.register_module() +class OneCycleLrUpdaterHook(LrUpdaterHook): + """One Cycle LR Scheduler. + + The 1cycle learning rate policy changes the learning rate after every + batch. The one cycle learning rate policy is described in + https://arxiv.org/pdf/1708.07120.pdf + + Args: + max_lr (float or list): Upper learning rate boundaries in the cycle + for each parameter group. + total_steps (int, optional): The total number of steps in the cycle. + Note that if a value is not provided here, it will be the max_iter + of runner. Default: None. + pct_start (float): The percentage of the cycle (in number of steps) + spent increasing the learning rate. + Default: 0.3 + anneal_strategy (str): {'cos', 'linear'} + Specifies the annealing strategy: 'cos' for cosine annealing, + 'linear' for linear annealing. + Default: 'cos' + div_factor (float): Determines the initial learning rate via + initial_lr = max_lr/div_factor + Default: 25 + final_div_factor (float): Determines the minimum learning rate via + min_lr = initial_lr/final_div_factor + Default: 1e4 + three_phase (bool): If three_phase is True, use a third phase of the + schedule to annihilate the learning rate according to + final_div_factor instead of modifying the second phase (the first + two phases will be symmetrical about the step indicated by + pct_start). + Default: False + """ + + def __init__(self, + max_lr, + total_steps=None, + pct_start=0.3, + anneal_strategy='cos', + div_factor=25, + final_div_factor=1e4, + three_phase=False, + **kwargs): + # validate by_epoch, currently only support by_epoch = False + if 'by_epoch' not in kwargs: + kwargs['by_epoch'] = False + else: + assert not kwargs['by_epoch'], \ + 'currently only support "by_epoch" = False' + if not isinstance(max_lr, (numbers.Number, list, dict)): + raise ValueError('the type of max_lr must be the one of list or ' + f'dict, but got {type(max_lr)}') + self._max_lr = max_lr + if total_steps is not None: + if not isinstance(total_steps, int): + raise ValueError('the type of total_steps must be int, but' + f'got {type(total_steps)}') + self.total_steps = total_steps + # validate pct_start + if pct_start < 0 or pct_start > 1 or not isinstance(pct_start, float): + raise ValueError('expected float between 0 and 1 pct_start, but ' + f'got {pct_start}') + self.pct_start = pct_start + # validate anneal_strategy + if anneal_strategy not in ['cos', 'linear']: + raise ValueError('anneal_strategy must be one of "cos" or ' + f'"linear", instead got {anneal_strategy}') + elif anneal_strategy == 'cos': + self.anneal_func = annealing_cos + elif anneal_strategy == 'linear': + self.anneal_func = annealing_linear + self.div_factor = div_factor + self.final_div_factor = final_div_factor + self.three_phase = three_phase + self.lr_phases = [] # init lr_phases + super(OneCycleLrUpdaterHook, self).__init__(**kwargs) + + def before_run(self, runner): + if hasattr(self, 'total_steps'): + total_steps = self.total_steps + else: + total_steps = runner.max_iters + if total_steps < runner.max_iters: + raise ValueError( + 'The total steps must be greater than or equal to max ' + f'iterations {runner.max_iters} of runner, but total steps ' + f'is {total_steps}.') + + if isinstance(runner.optimizer, dict): + self.base_lr = {} + for k, optim in runner.optimizer.items(): + _max_lr = format_param(k, optim, self._max_lr) + self.base_lr[k] = [lr / self.div_factor for lr in _max_lr] + for group, lr in zip(optim.param_groups, self.base_lr[k]): + group.setdefault('initial_lr', lr) + else: + k = type(runner.optimizer).__name__ + _max_lr = format_param(k, runner.optimizer, self._max_lr) + self.base_lr = [lr / self.div_factor for lr in _max_lr] + for group, lr in zip(runner.optimizer.param_groups, self.base_lr): + group.setdefault('initial_lr', lr) + + if self.three_phase: + self.lr_phases.append( + [float(self.pct_start * total_steps) - 1, 1, self.div_factor]) + self.lr_phases.append([ + float(2 * self.pct_start * total_steps) - 2, self.div_factor, 1 + ]) + self.lr_phases.append( + [total_steps - 1, 1, 1 / self.final_div_factor]) + else: + self.lr_phases.append( + [float(self.pct_start * total_steps) - 1, 1, self.div_factor]) + self.lr_phases.append( + [total_steps - 1, self.div_factor, 1 / self.final_div_factor]) + + def get_lr(self, runner, base_lr): + curr_iter = runner.iter + start_iter = 0 + for i, (end_iter, start_lr, end_lr) in enumerate(self.lr_phases): + if curr_iter <= end_iter: + pct = (curr_iter - start_iter) / (end_iter - start_iter) + lr = self.anneal_func(base_lr * start_lr, base_lr * end_lr, + pct) + break + start_iter = end_iter + return lr + + +def annealing_cos(start, end, factor, weight=1): + """Calculate annealing cos learning rate. + + Cosine anneal from `weight * start + (1 - weight) * end` to `end` as + percentage goes from 0.0 to 1.0. + + Args: + start (float): The starting learning rate of the cosine annealing. + end (float): The ending learing rate of the cosine annealing. + factor (float): The coefficient of `pi` when calculating the current + percentage. Range from 0.0 to 1.0. + weight (float, optional): The combination factor of `start` and `end` + when calculating the actual starting learning rate. Default to 1. + """ + cos_out = cos(pi * factor) + 1 + return end + 0.5 * weight * (start - end) * cos_out + + +def annealing_linear(start, end, factor): + """Calculate annealing linear learning rate. + + Linear anneal from `start` to `end` as percentage goes from 0.0 to 1.0. + + Args: + start (float): The starting learning rate of the linear annealing. + end (float): The ending learing rate of the linear annealing. + factor (float): The coefficient of `pi` when calculating the current + percentage. Range from 0.0 to 1.0. + """ + return start + (end - start) * factor + + +def format_param(name, optim, param): + if isinstance(param, numbers.Number): + return [param] * len(optim.param_groups) + elif isinstance(param, (list, tuple)): # multi param groups + if len(param) != len(optim.param_groups): + raise ValueError(f'expected {len(optim.param_groups)} ' + f'values for {name}, got {len(param)}') + return param + else: # multi optimizers + if name not in param: + raise KeyError(f'{name} is not found in {param.keys()}') + return param[name] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/memory.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/memory.py new file mode 100644 index 00000000..70cf9a83 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/memory.py @@ -0,0 +1,25 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch + +from .hook import HOOKS, Hook + + +@HOOKS.register_module() +class EmptyCacheHook(Hook): + + def __init__(self, before_epoch=False, after_epoch=True, after_iter=False): + self._before_epoch = before_epoch + self._after_epoch = after_epoch + self._after_iter = after_iter + + def after_iter(self, runner): + if self._after_iter: + torch.cuda.empty_cache() + + def before_epoch(self, runner): + if self._before_epoch: + torch.cuda.empty_cache() + + def after_epoch(self, runner): + if self._after_epoch: + torch.cuda.empty_cache() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/momentum_updater.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/momentum_updater.py new file mode 100644 index 00000000..cdc70246 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/momentum_updater.py @@ -0,0 +1,493 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import annotator.mmpkg.mmcv as mmcv +from .hook import HOOKS, Hook +from .lr_updater import annealing_cos, annealing_linear, format_param + + +class MomentumUpdaterHook(Hook): + + def __init__(self, + by_epoch=True, + warmup=None, + warmup_iters=0, + warmup_ratio=0.9): + # validate the "warmup" argument + if warmup is not None: + if warmup not in ['constant', 'linear', 'exp']: + raise ValueError( + f'"{warmup}" is not a supported type for warming up, valid' + ' types are "constant" and "linear"') + if warmup is not None: + assert warmup_iters > 0, \ + '"warmup_iters" must be a positive integer' + assert 0 < warmup_ratio <= 1.0, \ + '"warmup_momentum" must be in range (0,1]' + + self.by_epoch = by_epoch + self.warmup = warmup + self.warmup_iters = warmup_iters + self.warmup_ratio = warmup_ratio + + self.base_momentum = [] # initial momentum for all param groups + self.regular_momentum = [ + ] # expected momentum if no warming up is performed + + def _set_momentum(self, runner, momentum_groups): + if isinstance(runner.optimizer, dict): + for k, optim in runner.optimizer.items(): + for param_group, mom in zip(optim.param_groups, + momentum_groups[k]): + if 'momentum' in param_group.keys(): + param_group['momentum'] = mom + elif 'betas' in param_group.keys(): + param_group['betas'] = (mom, param_group['betas'][1]) + else: + for param_group, mom in zip(runner.optimizer.param_groups, + momentum_groups): + if 'momentum' in param_group.keys(): + param_group['momentum'] = mom + elif 'betas' in param_group.keys(): + param_group['betas'] = (mom, param_group['betas'][1]) + + def get_momentum(self, runner, base_momentum): + raise NotImplementedError + + def get_regular_momentum(self, runner): + if isinstance(runner.optimizer, dict): + momentum_groups = {} + for k in runner.optimizer.keys(): + _momentum_group = [ + self.get_momentum(runner, _base_momentum) + for _base_momentum in self.base_momentum[k] + ] + momentum_groups.update({k: _momentum_group}) + return momentum_groups + else: + return [ + self.get_momentum(runner, _base_momentum) + for _base_momentum in self.base_momentum + ] + + def get_warmup_momentum(self, cur_iters): + + def _get_warmup_momentum(cur_iters, regular_momentum): + if self.warmup == 'constant': + warmup_momentum = [ + _momentum / self.warmup_ratio + for _momentum in self.regular_momentum + ] + elif self.warmup == 'linear': + k = (1 - cur_iters / self.warmup_iters) * (1 - + self.warmup_ratio) + warmup_momentum = [ + _momentum / (1 - k) for _momentum in self.regular_mom + ] + elif self.warmup == 'exp': + k = self.warmup_ratio**(1 - cur_iters / self.warmup_iters) + warmup_momentum = [ + _momentum / k for _momentum in self.regular_mom + ] + return warmup_momentum + + if isinstance(self.regular_momentum, dict): + momentum_groups = {} + for key, regular_momentum in self.regular_momentum.items(): + momentum_groups[key] = _get_warmup_momentum( + cur_iters, regular_momentum) + return momentum_groups + else: + return _get_warmup_momentum(cur_iters, self.regular_momentum) + + def before_run(self, runner): + # NOTE: when resuming from a checkpoint, + # if 'initial_momentum' is not saved, + # it will be set according to the optimizer params + if isinstance(runner.optimizer, dict): + self.base_momentum = {} + for k, optim in runner.optimizer.items(): + for group in optim.param_groups: + if 'momentum' in group.keys(): + group.setdefault('initial_momentum', group['momentum']) + else: + group.setdefault('initial_momentum', group['betas'][0]) + _base_momentum = [ + group['initial_momentum'] for group in optim.param_groups + ] + self.base_momentum.update({k: _base_momentum}) + else: + for group in runner.optimizer.param_groups: + if 'momentum' in group.keys(): + group.setdefault('initial_momentum', group['momentum']) + else: + group.setdefault('initial_momentum', group['betas'][0]) + self.base_momentum = [ + group['initial_momentum'] + for group in runner.optimizer.param_groups + ] + + def before_train_epoch(self, runner): + if not self.by_epoch: + return + self.regular_mom = self.get_regular_momentum(runner) + self._set_momentum(runner, self.regular_mom) + + def before_train_iter(self, runner): + cur_iter = runner.iter + if not self.by_epoch: + self.regular_mom = self.get_regular_momentum(runner) + if self.warmup is None or cur_iter >= self.warmup_iters: + self._set_momentum(runner, self.regular_mom) + else: + warmup_momentum = self.get_warmup_momentum(cur_iter) + self._set_momentum(runner, warmup_momentum) + elif self.by_epoch: + if self.warmup is None or cur_iter > self.warmup_iters: + return + elif cur_iter == self.warmup_iters: + self._set_momentum(runner, self.regular_mom) + else: + warmup_momentum = self.get_warmup_momentum(cur_iter) + self._set_momentum(runner, warmup_momentum) + + +@HOOKS.register_module() +class StepMomentumUpdaterHook(MomentumUpdaterHook): + """Step momentum scheduler with min value clipping. + + Args: + step (int | list[int]): Step to decay the momentum. If an int value is + given, regard it as the decay interval. If a list is given, decay + momentum at these steps. + gamma (float, optional): Decay momentum ratio. Default: 0.5. + min_momentum (float, optional): Minimum momentum value to keep. If + momentum after decay is lower than this value, it will be clipped + accordingly. If None is given, we don't perform lr clipping. + Default: None. + """ + + def __init__(self, step, gamma=0.5, min_momentum=None, **kwargs): + if isinstance(step, list): + assert mmcv.is_list_of(step, int) + assert all([s > 0 for s in step]) + elif isinstance(step, int): + assert step > 0 + else: + raise TypeError('"step" must be a list or integer') + self.step = step + self.gamma = gamma + self.min_momentum = min_momentum + super(StepMomentumUpdaterHook, self).__init__(**kwargs) + + def get_momentum(self, runner, base_momentum): + progress = runner.epoch if self.by_epoch else runner.iter + + # calculate exponential term + if isinstance(self.step, int): + exp = progress // self.step + else: + exp = len(self.step) + for i, s in enumerate(self.step): + if progress < s: + exp = i + break + + momentum = base_momentum * (self.gamma**exp) + if self.min_momentum is not None: + # clip to a minimum value + momentum = max(momentum, self.min_momentum) + return momentum + + +@HOOKS.register_module() +class CosineAnnealingMomentumUpdaterHook(MomentumUpdaterHook): + + def __init__(self, min_momentum=None, min_momentum_ratio=None, **kwargs): + assert (min_momentum is None) ^ (min_momentum_ratio is None) + self.min_momentum = min_momentum + self.min_momentum_ratio = min_momentum_ratio + super(CosineAnnealingMomentumUpdaterHook, self).__init__(**kwargs) + + def get_momentum(self, runner, base_momentum): + if self.by_epoch: + progress = runner.epoch + max_progress = runner.max_epochs + else: + progress = runner.iter + max_progress = runner.max_iters + if self.min_momentum_ratio is not None: + target_momentum = base_momentum * self.min_momentum_ratio + else: + target_momentum = self.min_momentum + return annealing_cos(base_momentum, target_momentum, + progress / max_progress) + + +@HOOKS.register_module() +class CyclicMomentumUpdaterHook(MomentumUpdaterHook): + """Cyclic momentum Scheduler. + + Implement the cyclical momentum scheduler policy described in + https://arxiv.org/pdf/1708.07120.pdf + + This momentum scheduler usually used together with the CyclicLRUpdater + to improve the performance in the 3D detection area. + + Attributes: + target_ratio (tuple[float]): Relative ratio of the lowest momentum and + the highest momentum to the initial momentum. + cyclic_times (int): Number of cycles during training + step_ratio_up (float): The ratio of the increasing process of momentum + in the total cycle. + by_epoch (bool): Whether to update momentum by epoch. + """ + + def __init__(self, + by_epoch=False, + target_ratio=(0.85 / 0.95, 1), + cyclic_times=1, + step_ratio_up=0.4, + **kwargs): + if isinstance(target_ratio, float): + target_ratio = (target_ratio, target_ratio / 1e5) + elif isinstance(target_ratio, tuple): + target_ratio = (target_ratio[0], target_ratio[0] / 1e5) \ + if len(target_ratio) == 1 else target_ratio + else: + raise ValueError('target_ratio should be either float ' + f'or tuple, got {type(target_ratio)}') + + assert len(target_ratio) == 2, \ + '"target_ratio" must be list or tuple of two floats' + assert 0 <= step_ratio_up < 1.0, \ + '"step_ratio_up" must be in range [0,1)' + + self.target_ratio = target_ratio + self.cyclic_times = cyclic_times + self.step_ratio_up = step_ratio_up + self.momentum_phases = [] # init momentum_phases + # currently only support by_epoch=False + assert not by_epoch, \ + 'currently only support "by_epoch" = False' + super(CyclicMomentumUpdaterHook, self).__init__(by_epoch, **kwargs) + + def before_run(self, runner): + super(CyclicMomentumUpdaterHook, self).before_run(runner) + # initiate momentum_phases + # total momentum_phases are separated as up and down + max_iter_per_phase = runner.max_iters // self.cyclic_times + iter_up_phase = int(self.step_ratio_up * max_iter_per_phase) + self.momentum_phases.append( + [0, iter_up_phase, max_iter_per_phase, 1, self.target_ratio[0]]) + self.momentum_phases.append([ + iter_up_phase, max_iter_per_phase, max_iter_per_phase, + self.target_ratio[0], self.target_ratio[1] + ]) + + def get_momentum(self, runner, base_momentum): + curr_iter = runner.iter + for (start_iter, end_iter, max_iter_per_phase, start_ratio, + end_ratio) in self.momentum_phases: + curr_iter %= max_iter_per_phase + if start_iter <= curr_iter < end_iter: + progress = curr_iter - start_iter + return annealing_cos(base_momentum * start_ratio, + base_momentum * end_ratio, + progress / (end_iter - start_iter)) + + +@HOOKS.register_module() +class OneCycleMomentumUpdaterHook(MomentumUpdaterHook): + """OneCycle momentum Scheduler. + + This momentum scheduler usually used together with the OneCycleLrUpdater + to improve the performance. + + Args: + base_momentum (float or list): Lower momentum boundaries in the cycle + for each parameter group. Note that momentum is cycled inversely + to learning rate; at the peak of a cycle, momentum is + 'base_momentum' and learning rate is 'max_lr'. + Default: 0.85 + max_momentum (float or list): Upper momentum boundaries in the cycle + for each parameter group. Functionally, + it defines the cycle amplitude (max_momentum - base_momentum). + Note that momentum is cycled inversely + to learning rate; at the start of a cycle, momentum is + 'max_momentum' and learning rate is 'base_lr' + Default: 0.95 + pct_start (float): The percentage of the cycle (in number of steps) + spent increasing the learning rate. + Default: 0.3 + anneal_strategy (str): {'cos', 'linear'} + Specifies the annealing strategy: 'cos' for cosine annealing, + 'linear' for linear annealing. + Default: 'cos' + three_phase (bool): If three_phase is True, use a third phase of the + schedule to annihilate the learning rate according to + final_div_factor instead of modifying the second phase (the first + two phases will be symmetrical about the step indicated by + pct_start). + Default: False + """ + + def __init__(self, + base_momentum=0.85, + max_momentum=0.95, + pct_start=0.3, + anneal_strategy='cos', + three_phase=False, + **kwargs): + # validate by_epoch, currently only support by_epoch=False + if 'by_epoch' not in kwargs: + kwargs['by_epoch'] = False + else: + assert not kwargs['by_epoch'], \ + 'currently only support "by_epoch" = False' + if not isinstance(base_momentum, (float, list, dict)): + raise ValueError('base_momentum must be the type among of float,' + 'list or dict.') + self._base_momentum = base_momentum + if not isinstance(max_momentum, (float, list, dict)): + raise ValueError('max_momentum must be the type among of float,' + 'list or dict.') + self._max_momentum = max_momentum + # validate pct_start + if pct_start < 0 or pct_start > 1 or not isinstance(pct_start, float): + raise ValueError('Expected float between 0 and 1 pct_start, but ' + f'got {pct_start}') + self.pct_start = pct_start + # validate anneal_strategy + if anneal_strategy not in ['cos', 'linear']: + raise ValueError('anneal_strategy must by one of "cos" or ' + f'"linear", instead got {anneal_strategy}') + elif anneal_strategy == 'cos': + self.anneal_func = annealing_cos + elif anneal_strategy == 'linear': + self.anneal_func = annealing_linear + self.three_phase = three_phase + self.momentum_phases = [] # init momentum_phases + super(OneCycleMomentumUpdaterHook, self).__init__(**kwargs) + + def before_run(self, runner): + if isinstance(runner.optimizer, dict): + for k, optim in runner.optimizer.items(): + if ('momentum' not in optim.defaults + and 'betas' not in optim.defaults): + raise ValueError('optimizer must support momentum with' + 'option enabled') + self.use_beta1 = 'betas' in optim.defaults + _base_momentum = format_param(k, optim, self._base_momentum) + _max_momentum = format_param(k, optim, self._max_momentum) + for group, b_momentum, m_momentum in zip( + optim.param_groups, _base_momentum, _max_momentum): + if self.use_beta1: + _, beta2 = group['betas'] + group['betas'] = (m_momentum, beta2) + else: + group['momentum'] = m_momentum + group['base_momentum'] = b_momentum + group['max_momentum'] = m_momentum + else: + optim = runner.optimizer + if ('momentum' not in optim.defaults + and 'betas' not in optim.defaults): + raise ValueError('optimizer must support momentum with' + 'option enabled') + self.use_beta1 = 'betas' in optim.defaults + k = type(optim).__name__ + _base_momentum = format_param(k, optim, self._base_momentum) + _max_momentum = format_param(k, optim, self._max_momentum) + for group, b_momentum, m_momentum in zip(optim.param_groups, + _base_momentum, + _max_momentum): + if self.use_beta1: + _, beta2 = group['betas'] + group['betas'] = (m_momentum, beta2) + else: + group['momentum'] = m_momentum + group['base_momentum'] = b_momentum + group['max_momentum'] = m_momentum + + if self.three_phase: + self.momentum_phases.append({ + 'end_iter': + float(self.pct_start * runner.max_iters) - 1, + 'start_momentum': + 'max_momentum', + 'end_momentum': + 'base_momentum' + }) + self.momentum_phases.append({ + 'end_iter': + float(2 * self.pct_start * runner.max_iters) - 2, + 'start_momentum': + 'base_momentum', + 'end_momentum': + 'max_momentum' + }) + self.momentum_phases.append({ + 'end_iter': runner.max_iters - 1, + 'start_momentum': 'max_momentum', + 'end_momentum': 'max_momentum' + }) + else: + self.momentum_phases.append({ + 'end_iter': + float(self.pct_start * runner.max_iters) - 1, + 'start_momentum': + 'max_momentum', + 'end_momentum': + 'base_momentum' + }) + self.momentum_phases.append({ + 'end_iter': runner.max_iters - 1, + 'start_momentum': 'base_momentum', + 'end_momentum': 'max_momentum' + }) + + def _set_momentum(self, runner, momentum_groups): + if isinstance(runner.optimizer, dict): + for k, optim in runner.optimizer.items(): + for param_group, mom in zip(optim.param_groups, + momentum_groups[k]): + if 'momentum' in param_group.keys(): + param_group['momentum'] = mom + elif 'betas' in param_group.keys(): + param_group['betas'] = (mom, param_group['betas'][1]) + else: + for param_group, mom in zip(runner.optimizer.param_groups, + momentum_groups): + if 'momentum' in param_group.keys(): + param_group['momentum'] = mom + elif 'betas' in param_group.keys(): + param_group['betas'] = (mom, param_group['betas'][1]) + + def get_momentum(self, runner, param_group): + curr_iter = runner.iter + start_iter = 0 + for i, phase in enumerate(self.momentum_phases): + end_iter = phase['end_iter'] + if curr_iter <= end_iter or i == len(self.momentum_phases) - 1: + pct = (curr_iter - start_iter) / (end_iter - start_iter) + momentum = self.anneal_func( + param_group[phase['start_momentum']], + param_group[phase['end_momentum']], pct) + break + start_iter = end_iter + return momentum + + def get_regular_momentum(self, runner): + if isinstance(runner.optimizer, dict): + momentum_groups = {} + for k, optim in runner.optimizer.items(): + _momentum_group = [ + self.get_momentum(runner, param_group) + for param_group in optim.param_groups + ] + momentum_groups.update({k: _momentum_group}) + return momentum_groups + else: + momentum_groups = [] + for param_group in runner.optimizer.param_groups: + momentum_groups.append(self.get_momentum(runner, param_group)) + return momentum_groups diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/optimizer.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/optimizer.py new file mode 100644 index 00000000..580a1836 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/optimizer.py @@ -0,0 +1,508 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import copy +from collections import defaultdict +from itertools import chain + +from torch.nn.utils import clip_grad + +from annotator.mmpkg.mmcv.utils import TORCH_VERSION, _BatchNorm, digit_version +from ..dist_utils import allreduce_grads +from ..fp16_utils import LossScaler, wrap_fp16_model +from .hook import HOOKS, Hook + +try: + # If PyTorch version >= 1.6.0, torch.cuda.amp.GradScaler would be imported + # and used; otherwise, auto fp16 will adopt mmcv's implementation. + from torch.cuda.amp import GradScaler +except ImportError: + pass + + +@HOOKS.register_module() +class OptimizerHook(Hook): + + def __init__(self, grad_clip=None): + self.grad_clip = grad_clip + + def clip_grads(self, params): + params = list( + filter(lambda p: p.requires_grad and p.grad is not None, params)) + if len(params) > 0: + return clip_grad.clip_grad_norm_(params, **self.grad_clip) + + def after_train_iter(self, runner): + runner.optimizer.zero_grad() + runner.outputs['loss'].backward() + if self.grad_clip is not None: + grad_norm = self.clip_grads(runner.model.parameters()) + if grad_norm is not None: + # Add grad norm to the logger + runner.log_buffer.update({'grad_norm': float(grad_norm)}, + runner.outputs['num_samples']) + runner.optimizer.step() + + +@HOOKS.register_module() +class GradientCumulativeOptimizerHook(OptimizerHook): + """Optimizer Hook implements multi-iters gradient cumulating. + + Args: + cumulative_iters (int, optional): Num of gradient cumulative iters. + The optimizer will step every `cumulative_iters` iters. + Defaults to 1. + + Examples: + >>> # Use cumulative_iters to simulate a large batch size + >>> # It is helpful when the hardware cannot handle a large batch size. + >>> loader = DataLoader(data, batch_size=64) + >>> optim_hook = GradientCumulativeOptimizerHook(cumulative_iters=4) + >>> # almost equals to + >>> loader = DataLoader(data, batch_size=256) + >>> optim_hook = OptimizerHook() + """ + + def __init__(self, cumulative_iters=1, **kwargs): + super(GradientCumulativeOptimizerHook, self).__init__(**kwargs) + + assert isinstance(cumulative_iters, int) and cumulative_iters > 0, \ + f'cumulative_iters only accepts positive int, but got ' \ + f'{type(cumulative_iters)} instead.' + + self.cumulative_iters = cumulative_iters + self.divisible_iters = 0 + self.remainder_iters = 0 + self.initialized = False + + def has_batch_norm(self, module): + if isinstance(module, _BatchNorm): + return True + for m in module.children(): + if self.has_batch_norm(m): + return True + return False + + def _init(self, runner): + if runner.iter % self.cumulative_iters != 0: + runner.logger.warning( + 'Resume iter number is not divisible by cumulative_iters in ' + 'GradientCumulativeOptimizerHook, which means the gradient of ' + 'some iters is lost and the result may be influenced slightly.' + ) + + if self.has_batch_norm(runner.model) and self.cumulative_iters > 1: + runner.logger.warning( + 'GradientCumulativeOptimizerHook may slightly decrease ' + 'performance if the model has BatchNorm layers.') + + residual_iters = runner.max_iters - runner.iter + + self.divisible_iters = ( + residual_iters // self.cumulative_iters * self.cumulative_iters) + self.remainder_iters = residual_iters - self.divisible_iters + + self.initialized = True + + def after_train_iter(self, runner): + if not self.initialized: + self._init(runner) + + if runner.iter < self.divisible_iters: + loss_factor = self.cumulative_iters + else: + loss_factor = self.remainder_iters + loss = runner.outputs['loss'] + loss = loss / loss_factor + loss.backward() + + if (self.every_n_iters(runner, self.cumulative_iters) + or self.is_last_iter(runner)): + + if self.grad_clip is not None: + grad_norm = self.clip_grads(runner.model.parameters()) + if grad_norm is not None: + # Add grad norm to the logger + runner.log_buffer.update({'grad_norm': float(grad_norm)}, + runner.outputs['num_samples']) + runner.optimizer.step() + runner.optimizer.zero_grad() + + +if (TORCH_VERSION != 'parrots' + and digit_version(TORCH_VERSION) >= digit_version('1.6.0')): + + @HOOKS.register_module() + class Fp16OptimizerHook(OptimizerHook): + """FP16 optimizer hook (using PyTorch's implementation). + + If you are using PyTorch >= 1.6, torch.cuda.amp is used as the backend, + to take care of the optimization procedure. + + Args: + loss_scale (float | str | dict): Scale factor configuration. + If loss_scale is a float, static loss scaling will be used with + the specified scale. If loss_scale is a string, it must be + 'dynamic', then dynamic loss scaling will be used. + It can also be a dict containing arguments of GradScalar. + Defaults to 512. For Pytorch >= 1.6, mmcv uses official + implementation of GradScaler. If you use a dict version of + loss_scale to create GradScaler, please refer to: + https://pytorch.org/docs/stable/amp.html#torch.cuda.amp.GradScaler + for the parameters. + + Examples: + >>> loss_scale = dict( + ... init_scale=65536.0, + ... growth_factor=2.0, + ... backoff_factor=0.5, + ... growth_interval=2000 + ... ) + >>> optimizer_hook = Fp16OptimizerHook(loss_scale=loss_scale) + """ + + def __init__(self, + grad_clip=None, + coalesce=True, + bucket_size_mb=-1, + loss_scale=512., + distributed=True): + self.grad_clip = grad_clip + self.coalesce = coalesce + self.bucket_size_mb = bucket_size_mb + self.distributed = distributed + self._scale_update_param = None + if loss_scale == 'dynamic': + self.loss_scaler = GradScaler() + elif isinstance(loss_scale, float): + self._scale_update_param = loss_scale + self.loss_scaler = GradScaler(init_scale=loss_scale) + elif isinstance(loss_scale, dict): + self.loss_scaler = GradScaler(**loss_scale) + else: + raise ValueError('loss_scale must be of type float, dict, or ' + f'"dynamic", got {loss_scale}') + + def before_run(self, runner): + """Preparing steps before Mixed Precision Training.""" + # wrap model mode to fp16 + wrap_fp16_model(runner.model) + # resume from state dict + if 'fp16' in runner.meta and 'loss_scaler' in runner.meta['fp16']: + scaler_state_dict = runner.meta['fp16']['loss_scaler'] + self.loss_scaler.load_state_dict(scaler_state_dict) + + def copy_grads_to_fp32(self, fp16_net, fp32_weights): + """Copy gradients from fp16 model to fp32 weight copy.""" + for fp32_param, fp16_param in zip(fp32_weights, + fp16_net.parameters()): + if fp16_param.grad is not None: + if fp32_param.grad is None: + fp32_param.grad = fp32_param.data.new( + fp32_param.size()) + fp32_param.grad.copy_(fp16_param.grad) + + def copy_params_to_fp16(self, fp16_net, fp32_weights): + """Copy updated params from fp32 weight copy to fp16 model.""" + for fp16_param, fp32_param in zip(fp16_net.parameters(), + fp32_weights): + fp16_param.data.copy_(fp32_param.data) + + def after_train_iter(self, runner): + """Backward optimization steps for Mixed Precision Training. For + dynamic loss scaling, please refer to + https://pytorch.org/docs/stable/amp.html#torch.cuda.amp.GradScaler. + + 1. Scale the loss by a scale factor. + 2. Backward the loss to obtain the gradients. + 3. Unscale the optimizer’s gradient tensors. + 4. Call optimizer.step() and update scale factor. + 5. Save loss_scaler state_dict for resume purpose. + """ + # clear grads of last iteration + runner.model.zero_grad() + runner.optimizer.zero_grad() + + self.loss_scaler.scale(runner.outputs['loss']).backward() + self.loss_scaler.unscale_(runner.optimizer) + # grad clip + if self.grad_clip is not None: + grad_norm = self.clip_grads(runner.model.parameters()) + if grad_norm is not None: + # Add grad norm to the logger + runner.log_buffer.update({'grad_norm': float(grad_norm)}, + runner.outputs['num_samples']) + # backward and update scaler + self.loss_scaler.step(runner.optimizer) + self.loss_scaler.update(self._scale_update_param) + + # save state_dict of loss_scaler + runner.meta.setdefault( + 'fp16', {})['loss_scaler'] = self.loss_scaler.state_dict() + + @HOOKS.register_module() + class GradientCumulativeFp16OptimizerHook(GradientCumulativeOptimizerHook, + Fp16OptimizerHook): + """Fp16 optimizer Hook (using PyTorch's implementation) implements + multi-iters gradient cumulating. + + If you are using PyTorch >= 1.6, torch.cuda.amp is used as the backend, + to take care of the optimization procedure. + """ + + def __init__(self, *args, **kwargs): + super(GradientCumulativeFp16OptimizerHook, + self).__init__(*args, **kwargs) + + def after_train_iter(self, runner): + if not self.initialized: + self._init(runner) + + if runner.iter < self.divisible_iters: + loss_factor = self.cumulative_iters + else: + loss_factor = self.remainder_iters + loss = runner.outputs['loss'] + loss = loss / loss_factor + + self.loss_scaler.scale(loss).backward() + + if (self.every_n_iters(runner, self.cumulative_iters) + or self.is_last_iter(runner)): + + # copy fp16 grads in the model to fp32 params in the optimizer + self.loss_scaler.unscale_(runner.optimizer) + + if self.grad_clip is not None: + grad_norm = self.clip_grads(runner.model.parameters()) + if grad_norm is not None: + # Add grad norm to the logger + runner.log_buffer.update( + {'grad_norm': float(grad_norm)}, + runner.outputs['num_samples']) + + # backward and update scaler + self.loss_scaler.step(runner.optimizer) + self.loss_scaler.update(self._scale_update_param) + + # save state_dict of loss_scaler + runner.meta.setdefault( + 'fp16', {})['loss_scaler'] = self.loss_scaler.state_dict() + + # clear grads + runner.model.zero_grad() + runner.optimizer.zero_grad() + +else: + + @HOOKS.register_module() + class Fp16OptimizerHook(OptimizerHook): + """FP16 optimizer hook (mmcv's implementation). + + The steps of fp16 optimizer is as follows. + 1. Scale the loss value. + 2. BP in the fp16 model. + 2. Copy gradients from fp16 model to fp32 weights. + 3. Update fp32 weights. + 4. Copy updated parameters from fp32 weights to fp16 model. + + Refer to https://arxiv.org/abs/1710.03740 for more details. + + Args: + loss_scale (float | str | dict): Scale factor configuration. + If loss_scale is a float, static loss scaling will be used with + the specified scale. If loss_scale is a string, it must be + 'dynamic', then dynamic loss scaling will be used. + It can also be a dict containing arguments of LossScaler. + Defaults to 512. + """ + + def __init__(self, + grad_clip=None, + coalesce=True, + bucket_size_mb=-1, + loss_scale=512., + distributed=True): + self.grad_clip = grad_clip + self.coalesce = coalesce + self.bucket_size_mb = bucket_size_mb + self.distributed = distributed + if loss_scale == 'dynamic': + self.loss_scaler = LossScaler(mode='dynamic') + elif isinstance(loss_scale, float): + self.loss_scaler = LossScaler( + init_scale=loss_scale, mode='static') + elif isinstance(loss_scale, dict): + self.loss_scaler = LossScaler(**loss_scale) + else: + raise ValueError('loss_scale must be of type float, dict, or ' + f'"dynamic", got {loss_scale}') + + def before_run(self, runner): + """Preparing steps before Mixed Precision Training. + + 1. Make a master copy of fp32 weights for optimization. + 2. Convert the main model from fp32 to fp16. + """ + # keep a copy of fp32 weights + old_groups = runner.optimizer.param_groups + runner.optimizer.param_groups = copy.deepcopy( + runner.optimizer.param_groups) + state = defaultdict(dict) + p_map = { + old_p: p + for old_p, p in zip( + chain(*(g['params'] for g in old_groups)), + chain(*(g['params'] + for g in runner.optimizer.param_groups))) + } + for k, v in runner.optimizer.state.items(): + state[p_map[k]] = v + runner.optimizer.state = state + # convert model to fp16 + wrap_fp16_model(runner.model) + # resume from state dict + if 'fp16' in runner.meta and 'loss_scaler' in runner.meta['fp16']: + scaler_state_dict = runner.meta['fp16']['loss_scaler'] + self.loss_scaler.load_state_dict(scaler_state_dict) + + def copy_grads_to_fp32(self, fp16_net, fp32_weights): + """Copy gradients from fp16 model to fp32 weight copy.""" + for fp32_param, fp16_param in zip(fp32_weights, + fp16_net.parameters()): + if fp16_param.grad is not None: + if fp32_param.grad is None: + fp32_param.grad = fp32_param.data.new( + fp32_param.size()) + fp32_param.grad.copy_(fp16_param.grad) + + def copy_params_to_fp16(self, fp16_net, fp32_weights): + """Copy updated params from fp32 weight copy to fp16 model.""" + for fp16_param, fp32_param in zip(fp16_net.parameters(), + fp32_weights): + fp16_param.data.copy_(fp32_param.data) + + def after_train_iter(self, runner): + """Backward optimization steps for Mixed Precision Training. For + dynamic loss scaling, please refer `loss_scalar.py` + + 1. Scale the loss by a scale factor. + 2. Backward the loss to obtain the gradients (fp16). + 3. Copy gradients from the model to the fp32 weight copy. + 4. Scale the gradients back and update the fp32 weight copy. + 5. Copy back the params from fp32 weight copy to the fp16 model. + 6. Save loss_scaler state_dict for resume purpose. + """ + # clear grads of last iteration + runner.model.zero_grad() + runner.optimizer.zero_grad() + # scale the loss value + scaled_loss = runner.outputs['loss'] * self.loss_scaler.loss_scale + scaled_loss.backward() + # copy fp16 grads in the model to fp32 params in the optimizer + + fp32_weights = [] + for param_group in runner.optimizer.param_groups: + fp32_weights += param_group['params'] + self.copy_grads_to_fp32(runner.model, fp32_weights) + # allreduce grads + if self.distributed: + allreduce_grads(fp32_weights, self.coalesce, + self.bucket_size_mb) + + has_overflow = self.loss_scaler.has_overflow(fp32_weights) + # if has overflow, skip this iteration + if not has_overflow: + # scale the gradients back + for param in fp32_weights: + if param.grad is not None: + param.grad.div_(self.loss_scaler.loss_scale) + if self.grad_clip is not None: + grad_norm = self.clip_grads(fp32_weights) + if grad_norm is not None: + # Add grad norm to the logger + runner.log_buffer.update( + {'grad_norm': float(grad_norm)}, + runner.outputs['num_samples']) + # update fp32 params + runner.optimizer.step() + # copy fp32 params to the fp16 model + self.copy_params_to_fp16(runner.model, fp32_weights) + self.loss_scaler.update_scale(has_overflow) + if has_overflow: + runner.logger.warning('Check overflow, downscale loss scale ' + f'to {self.loss_scaler.cur_scale}') + + # save state_dict of loss_scaler + runner.meta.setdefault( + 'fp16', {})['loss_scaler'] = self.loss_scaler.state_dict() + + @HOOKS.register_module() + class GradientCumulativeFp16OptimizerHook(GradientCumulativeOptimizerHook, + Fp16OptimizerHook): + """Fp16 optimizer Hook (using mmcv implementation) implements multi- + iters gradient cumulating.""" + + def __init__(self, *args, **kwargs): + super(GradientCumulativeFp16OptimizerHook, + self).__init__(*args, **kwargs) + + def after_train_iter(self, runner): + if not self.initialized: + self._init(runner) + + if runner.iter < self.divisible_iters: + loss_factor = self.cumulative_iters + else: + loss_factor = self.remainder_iters + + loss = runner.outputs['loss'] + loss = loss / loss_factor + + # scale the loss value + scaled_loss = loss * self.loss_scaler.loss_scale + scaled_loss.backward() + + if (self.every_n_iters(runner, self.cumulative_iters) + or self.is_last_iter(runner)): + + # copy fp16 grads in the model to fp32 params in the optimizer + fp32_weights = [] + for param_group in runner.optimizer.param_groups: + fp32_weights += param_group['params'] + self.copy_grads_to_fp32(runner.model, fp32_weights) + # allreduce grads + if self.distributed: + allreduce_grads(fp32_weights, self.coalesce, + self.bucket_size_mb) + + has_overflow = self.loss_scaler.has_overflow(fp32_weights) + # if has overflow, skip this iteration + if not has_overflow: + # scale the gradients back + for param in fp32_weights: + if param.grad is not None: + param.grad.div_(self.loss_scaler.loss_scale) + if self.grad_clip is not None: + grad_norm = self.clip_grads(fp32_weights) + if grad_norm is not None: + # Add grad norm to the logger + runner.log_buffer.update( + {'grad_norm': float(grad_norm)}, + runner.outputs['num_samples']) + # update fp32 params + runner.optimizer.step() + # copy fp32 params to the fp16 model + self.copy_params_to_fp16(runner.model, fp32_weights) + else: + runner.logger.warning( + 'Check overflow, downscale loss scale ' + f'to {self.loss_scaler.cur_scale}') + + self.loss_scaler.update_scale(has_overflow) + + # save state_dict of loss_scaler + runner.meta.setdefault( + 'fp16', {})['loss_scaler'] = self.loss_scaler.state_dict() + + # clear grads + runner.model.zero_grad() + runner.optimizer.zero_grad() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/profiler.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/profiler.py new file mode 100644 index 00000000..b7023699 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/profiler.py @@ -0,0 +1,180 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import warnings +from typing import Callable, List, Optional, Union + +import torch + +from ..dist_utils import master_only +from .hook import HOOKS, Hook + + +@HOOKS.register_module() +class ProfilerHook(Hook): + """Profiler to analyze performance during training. + + PyTorch Profiler is a tool that allows the collection of the performance + metrics during the training. More details on Profiler can be found at + https://pytorch.org/docs/1.8.1/profiler.html#torch.profiler.profile + + Args: + by_epoch (bool): Profile performance by epoch or by iteration. + Default: True. + profile_iters (int): Number of iterations for profiling. + If ``by_epoch=True``, profile_iters indicates that they are the + first profile_iters epochs at the beginning of the + training, otherwise it indicates the first profile_iters + iterations. Default: 1. + activities (list[str]): List of activity groups (CPU, CUDA) to use in + profiling. Default: ['cpu', 'cuda']. + schedule (dict, optional): Config of generating the callable schedule. + if schedule is None, profiler will not add step markers into the + trace and table view. Default: None. + on_trace_ready (callable, dict): Either a handler or a dict of generate + handler. Default: None. + record_shapes (bool): Save information about operator's input shapes. + Default: False. + profile_memory (bool): Track tensor memory allocation/deallocation. + Default: False. + with_stack (bool): Record source information (file and line number) + for the ops. Default: False. + with_flops (bool): Use formula to estimate the FLOPS of specific + operators (matrix multiplication and 2D convolution). + Default: False. + json_trace_path (str, optional): Exports the collected trace in Chrome + JSON format. Default: None. + + Example: + >>> runner = ... # instantiate a Runner + >>> # tensorboard trace + >>> trace_config = dict(type='tb_trace', dir_name='work_dir') + >>> profiler_config = dict(on_trace_ready=trace_config) + >>> runner.register_profiler_hook(profiler_config) + >>> runner.run(data_loaders=[trainloader], workflow=[('train', 1)]) + """ + + def __init__(self, + by_epoch: bool = True, + profile_iters: int = 1, + activities: List[str] = ['cpu', 'cuda'], + schedule: Optional[dict] = None, + on_trace_ready: Optional[Union[Callable, dict]] = None, + record_shapes: bool = False, + profile_memory: bool = False, + with_stack: bool = False, + with_flops: bool = False, + json_trace_path: Optional[str] = None) -> None: + try: + from torch import profiler # torch version >= 1.8.1 + except ImportError: + raise ImportError('profiler is the new feature of torch1.8.1, ' + f'but your version is {torch.__version__}') + + assert isinstance(by_epoch, bool), '``by_epoch`` should be a boolean.' + self.by_epoch = by_epoch + + if profile_iters < 1: + raise ValueError('profile_iters should be greater than 0, but got ' + f'{profile_iters}') + self.profile_iters = profile_iters + + if not isinstance(activities, list): + raise ValueError( + f'activities should be list, but got {type(activities)}') + self.activities = [] + for activity in activities: + activity = activity.lower() + if activity == 'cpu': + self.activities.append(profiler.ProfilerActivity.CPU) + elif activity == 'cuda': + self.activities.append(profiler.ProfilerActivity.CUDA) + else: + raise ValueError( + f'activity should be "cpu" or "cuda", but got {activity}') + + if schedule is not None: + self.schedule = profiler.schedule(**schedule) + else: + self.schedule = None + + self.on_trace_ready = on_trace_ready + self.record_shapes = record_shapes + self.profile_memory = profile_memory + self.with_stack = with_stack + self.with_flops = with_flops + self.json_trace_path = json_trace_path + + @master_only + def before_run(self, runner): + if self.by_epoch and runner.max_epochs < self.profile_iters: + raise ValueError('self.profile_iters should not be greater than ' + f'{runner.max_epochs}') + + if not self.by_epoch and runner.max_iters < self.profile_iters: + raise ValueError('self.profile_iters should not be greater than ' + f'{runner.max_iters}') + + if callable(self.on_trace_ready): # handler + _on_trace_ready = self.on_trace_ready + elif isinstance(self.on_trace_ready, dict): # config of handler + trace_cfg = self.on_trace_ready.copy() + trace_type = trace_cfg.pop('type') # log_trace handler + if trace_type == 'log_trace': + + def _log_handler(prof): + print(prof.key_averages().table(**trace_cfg)) + + _on_trace_ready = _log_handler + elif trace_type == 'tb_trace': # tensorboard_trace handler + try: + import torch_tb_profiler # noqa: F401 + except ImportError: + raise ImportError('please run "pip install ' + 'torch-tb-profiler" to install ' + 'torch_tb_profiler') + _on_trace_ready = torch.profiler.tensorboard_trace_handler( + **trace_cfg) + else: + raise ValueError('trace_type should be "log_trace" or ' + f'"tb_trace", but got {trace_type}') + elif self.on_trace_ready is None: + _on_trace_ready = None # type: ignore + else: + raise ValueError('on_trace_ready should be handler, dict or None, ' + f'but got {type(self.on_trace_ready)}') + + if runner.max_epochs > 1: + warnings.warn(f'profiler will profile {runner.max_epochs} epochs ' + 'instead of 1 epoch. Since profiler will slow down ' + 'the training, it is recommended to train 1 epoch ' + 'with ProfilerHook and adjust your setting according' + ' to the profiler summary. During normal training ' + '(epoch > 1), you may disable the ProfilerHook.') + + self.profiler = torch.profiler.profile( + activities=self.activities, + schedule=self.schedule, + on_trace_ready=_on_trace_ready, + record_shapes=self.record_shapes, + profile_memory=self.profile_memory, + with_stack=self.with_stack, + with_flops=self.with_flops) + + self.profiler.__enter__() + runner.logger.info('profiler is profiling...') + + @master_only + def after_train_epoch(self, runner): + if self.by_epoch and runner.epoch == self.profile_iters - 1: + runner.logger.info('profiler may take a few minutes...') + self.profiler.__exit__(None, None, None) + if self.json_trace_path is not None: + self.profiler.export_chrome_trace(self.json_trace_path) + + @master_only + def after_train_iter(self, runner): + self.profiler.step() + if not self.by_epoch and runner.iter == self.profile_iters - 1: + runner.logger.info('profiler may take a few minutes...') + self.profiler.__exit__(None, None, None) + if self.json_trace_path is not None: + self.profiler.export_chrome_trace(self.json_trace_path) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/sampler_seed.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/sampler_seed.py new file mode 100644 index 00000000..ee0dc6bd --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/sampler_seed.py @@ -0,0 +1,20 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .hook import HOOKS, Hook + + +@HOOKS.register_module() +class DistSamplerSeedHook(Hook): + """Data-loading sampler for distributed training. + + When distributed training, it is only useful in conjunction with + :obj:`EpochBasedRunner`, while :obj:`IterBasedRunner` achieves the same + purpose with :obj:`IterLoader`. + """ + + def before_epoch(self, runner): + if hasattr(runner.data_loader.sampler, 'set_epoch'): + # in case the data loader uses `SequentialSampler` in Pytorch + runner.data_loader.sampler.set_epoch(runner.epoch) + elif hasattr(runner.data_loader.batch_sampler.sampler, 'set_epoch'): + # batch sampler in pytorch warps the sampler as its attributes. + runner.data_loader.batch_sampler.sampler.set_epoch(runner.epoch) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/sync_buffer.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/sync_buffer.py new file mode 100644 index 00000000..6376b7ff --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/hooks/sync_buffer.py @@ -0,0 +1,22 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from ..dist_utils import allreduce_params +from .hook import HOOKS, Hook + + +@HOOKS.register_module() +class SyncBuffersHook(Hook): + """Synchronize model buffers such as running_mean and running_var in BN at + the end of each epoch. + + Args: + distributed (bool): Whether distributed training is used. It is + effective only for distributed training. Defaults to True. + """ + + def __init__(self, distributed=True): + self.distributed = distributed + + def after_epoch(self, runner): + """All-reduce model buffers at the end of each epoch.""" + if self.distributed: + allreduce_params(runner.model.buffers()) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/iter_based_runner.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/iter_based_runner.py new file mode 100644 index 00000000..e93849ba --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/iter_based_runner.py @@ -0,0 +1,273 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os.path as osp +import platform +import shutil +import time +import warnings + +import torch +from torch.optim import Optimizer + +import annotator.mmpkg.mmcv as mmcv +from .base_runner import BaseRunner +from .builder import RUNNERS +from .checkpoint import save_checkpoint +from .hooks import IterTimerHook +from .utils import get_host_info + + +class IterLoader: + + def __init__(self, dataloader): + self._dataloader = dataloader + self.iter_loader = iter(self._dataloader) + self._epoch = 0 + + @property + def epoch(self): + return self._epoch + + def __next__(self): + try: + data = next(self.iter_loader) + except StopIteration: + self._epoch += 1 + if hasattr(self._dataloader.sampler, 'set_epoch'): + self._dataloader.sampler.set_epoch(self._epoch) + time.sleep(2) # Prevent possible deadlock during epoch transition + self.iter_loader = iter(self._dataloader) + data = next(self.iter_loader) + + return data + + def __len__(self): + return len(self._dataloader) + + +@RUNNERS.register_module() +class IterBasedRunner(BaseRunner): + """Iteration-based Runner. + + This runner train models iteration by iteration. + """ + + def train(self, data_loader, **kwargs): + self.model.train() + self.mode = 'train' + self.data_loader = data_loader + self._epoch = data_loader.epoch + data_batch = next(data_loader) + self.call_hook('before_train_iter') + outputs = self.model.train_step(data_batch, self.optimizer, **kwargs) + if not isinstance(outputs, dict): + raise TypeError('model.train_step() must return a dict') + if 'log_vars' in outputs: + self.log_buffer.update(outputs['log_vars'], outputs['num_samples']) + self.outputs = outputs + self.call_hook('after_train_iter') + self._inner_iter += 1 + self._iter += 1 + + @torch.no_grad() + def val(self, data_loader, **kwargs): + self.model.eval() + self.mode = 'val' + self.data_loader = data_loader + data_batch = next(data_loader) + self.call_hook('before_val_iter') + outputs = self.model.val_step(data_batch, **kwargs) + if not isinstance(outputs, dict): + raise TypeError('model.val_step() must return a dict') + if 'log_vars' in outputs: + self.log_buffer.update(outputs['log_vars'], outputs['num_samples']) + self.outputs = outputs + self.call_hook('after_val_iter') + self._inner_iter += 1 + + def run(self, data_loaders, workflow, max_iters=None, **kwargs): + """Start running. + + Args: + data_loaders (list[:obj:`DataLoader`]): Dataloaders for training + and validation. + workflow (list[tuple]): A list of (phase, iters) to specify the + running order and iterations. E.g, [('train', 10000), + ('val', 1000)] means running 10000 iterations for training and + 1000 iterations for validation, iteratively. + """ + assert isinstance(data_loaders, list) + assert mmcv.is_list_of(workflow, tuple) + assert len(data_loaders) == len(workflow) + if max_iters is not None: + warnings.warn( + 'setting max_iters in run is deprecated, ' + 'please set max_iters in runner_config', DeprecationWarning) + self._max_iters = max_iters + assert self._max_iters is not None, ( + 'max_iters must be specified during instantiation') + + work_dir = self.work_dir if self.work_dir is not None else 'NONE' + self.logger.info('Start running, host: %s, work_dir: %s', + get_host_info(), work_dir) + self.logger.info('Hooks will be executed in the following order:\n%s', + self.get_hook_info()) + self.logger.info('workflow: %s, max: %d iters', workflow, + self._max_iters) + self.call_hook('before_run') + + iter_loaders = [IterLoader(x) for x in data_loaders] + + self.call_hook('before_epoch') + + while self.iter < self._max_iters: + for i, flow in enumerate(workflow): + self._inner_iter = 0 + mode, iters = flow + if not isinstance(mode, str) or not hasattr(self, mode): + raise ValueError( + 'runner has no method named "{}" to run a workflow'. + format(mode)) + iter_runner = getattr(self, mode) + for _ in range(iters): + if mode == 'train' and self.iter >= self._max_iters: + break + iter_runner(iter_loaders[i], **kwargs) + + time.sleep(1) # wait for some hooks like loggers to finish + self.call_hook('after_epoch') + self.call_hook('after_run') + + def resume(self, + checkpoint, + resume_optimizer=True, + map_location='default'): + """Resume model from checkpoint. + + Args: + checkpoint (str): Checkpoint to resume from. + resume_optimizer (bool, optional): Whether resume the optimizer(s) + if the checkpoint file includes optimizer(s). Default to True. + map_location (str, optional): Same as :func:`torch.load`. + Default to 'default'. + """ + if map_location == 'default': + device_id = torch.cuda.current_device() + checkpoint = self.load_checkpoint( + checkpoint, + map_location=lambda storage, loc: storage.cuda(device_id)) + else: + checkpoint = self.load_checkpoint( + checkpoint, map_location=map_location) + + self._epoch = checkpoint['meta']['epoch'] + self._iter = checkpoint['meta']['iter'] + self._inner_iter = checkpoint['meta']['iter'] + if 'optimizer' in checkpoint and resume_optimizer: + if isinstance(self.optimizer, Optimizer): + self.optimizer.load_state_dict(checkpoint['optimizer']) + elif isinstance(self.optimizer, dict): + for k in self.optimizer.keys(): + self.optimizer[k].load_state_dict( + checkpoint['optimizer'][k]) + else: + raise TypeError( + 'Optimizer should be dict or torch.optim.Optimizer ' + f'but got {type(self.optimizer)}') + + self.logger.info(f'resumed from epoch: {self.epoch}, iter {self.iter}') + + def save_checkpoint(self, + out_dir, + filename_tmpl='iter_{}.pth', + meta=None, + save_optimizer=True, + create_symlink=True): + """Save checkpoint to file. + + Args: + out_dir (str): Directory to save checkpoint files. + filename_tmpl (str, optional): Checkpoint file template. + Defaults to 'iter_{}.pth'. + meta (dict, optional): Metadata to be saved in checkpoint. + Defaults to None. + save_optimizer (bool, optional): Whether save optimizer. + Defaults to True. + create_symlink (bool, optional): Whether create symlink to the + latest checkpoint file. Defaults to True. + """ + if meta is None: + meta = {} + elif not isinstance(meta, dict): + raise TypeError( + f'meta should be a dict or None, but got {type(meta)}') + if self.meta is not None: + meta.update(self.meta) + # Note: meta.update(self.meta) should be done before + # meta.update(epoch=self.epoch + 1, iter=self.iter) otherwise + # there will be problems with resumed checkpoints. + # More details in https://github.com/open-mmlab/mmcv/pull/1108 + meta.update(epoch=self.epoch + 1, iter=self.iter) + + filename = filename_tmpl.format(self.iter + 1) + filepath = osp.join(out_dir, filename) + optimizer = self.optimizer if save_optimizer else None + save_checkpoint(self.model, filepath, optimizer=optimizer, meta=meta) + # in some environments, `os.symlink` is not supported, you may need to + # set `create_symlink` to False + if create_symlink: + dst_file = osp.join(out_dir, 'latest.pth') + if platform.system() != 'Windows': + mmcv.symlink(filename, dst_file) + else: + shutil.copy(filepath, dst_file) + + def register_training_hooks(self, + lr_config, + optimizer_config=None, + checkpoint_config=None, + log_config=None, + momentum_config=None, + custom_hooks_config=None): + """Register default hooks for iter-based training. + + Checkpoint hook, optimizer stepper hook and logger hooks will be set to + `by_epoch=False` by default. + + Default hooks include: + + +----------------------+-------------------------+ + | Hooks | Priority | + +======================+=========================+ + | LrUpdaterHook | VERY_HIGH (10) | + +----------------------+-------------------------+ + | MomentumUpdaterHook | HIGH (30) | + +----------------------+-------------------------+ + | OptimizerStepperHook | ABOVE_NORMAL (40) | + +----------------------+-------------------------+ + | CheckpointSaverHook | NORMAL (50) | + +----------------------+-------------------------+ + | IterTimerHook | LOW (70) | + +----------------------+-------------------------+ + | LoggerHook(s) | VERY_LOW (90) | + +----------------------+-------------------------+ + | CustomHook(s) | defaults to NORMAL (50) | + +----------------------+-------------------------+ + + If custom hooks have same priority with default hooks, custom hooks + will be triggered after default hooks. + """ + if checkpoint_config is not None: + checkpoint_config.setdefault('by_epoch', False) + if lr_config is not None: + lr_config.setdefault('by_epoch', False) + if log_config is not None: + for info in log_config['hooks']: + info.setdefault('by_epoch', False) + super(IterBasedRunner, self).register_training_hooks( + lr_config=lr_config, + momentum_config=momentum_config, + optimizer_config=optimizer_config, + checkpoint_config=checkpoint_config, + log_config=log_config, + timer_config=IterTimerHook(), + custom_hooks_config=custom_hooks_config) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/log_buffer.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/log_buffer.py new file mode 100644 index 00000000..d949e294 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/log_buffer.py @@ -0,0 +1,41 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from collections import OrderedDict + +import numpy as np + + +class LogBuffer: + + def __init__(self): + self.val_history = OrderedDict() + self.n_history = OrderedDict() + self.output = OrderedDict() + self.ready = False + + def clear(self): + self.val_history.clear() + self.n_history.clear() + self.clear_output() + + def clear_output(self): + self.output.clear() + self.ready = False + + def update(self, vars, count=1): + assert isinstance(vars, dict) + for key, var in vars.items(): + if key not in self.val_history: + self.val_history[key] = [] + self.n_history[key] = [] + self.val_history[key].append(var) + self.n_history[key].append(count) + + def average(self, n=0): + """Average latest n values or all values.""" + assert n >= 0 + for key in self.val_history: + values = np.array(self.val_history[key][-n:]) + nums = np.array(self.n_history[key][-n:]) + avg = np.sum(values * nums) / np.sum(nums) + self.output[key] = avg + self.ready = True diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/optimizer/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/optimizer/__init__.py new file mode 100644 index 00000000..53c34d04 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/optimizer/__init__.py @@ -0,0 +1,9 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .builder import (OPTIMIZER_BUILDERS, OPTIMIZERS, build_optimizer, + build_optimizer_constructor) +from .default_constructor import DefaultOptimizerConstructor + +__all__ = [ + 'OPTIMIZER_BUILDERS', 'OPTIMIZERS', 'DefaultOptimizerConstructor', + 'build_optimizer', 'build_optimizer_constructor' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/optimizer/builder.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/optimizer/builder.py new file mode 100644 index 00000000..f9234eed --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/optimizer/builder.py @@ -0,0 +1,44 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import copy +import inspect + +import torch + +from ...utils import Registry, build_from_cfg + +OPTIMIZERS = Registry('optimizer') +OPTIMIZER_BUILDERS = Registry('optimizer builder') + + +def register_torch_optimizers(): + torch_optimizers = [] + for module_name in dir(torch.optim): + if module_name.startswith('__'): + continue + _optim = getattr(torch.optim, module_name) + if inspect.isclass(_optim) and issubclass(_optim, + torch.optim.Optimizer): + OPTIMIZERS.register_module()(_optim) + torch_optimizers.append(module_name) + return torch_optimizers + + +TORCH_OPTIMIZERS = register_torch_optimizers() + + +def build_optimizer_constructor(cfg): + return build_from_cfg(cfg, OPTIMIZER_BUILDERS) + + +def build_optimizer(model, cfg): + optimizer_cfg = copy.deepcopy(cfg) + constructor_type = optimizer_cfg.pop('constructor', + 'DefaultOptimizerConstructor') + paramwise_cfg = optimizer_cfg.pop('paramwise_cfg', None) + optim_constructor = build_optimizer_constructor( + dict( + type=constructor_type, + optimizer_cfg=optimizer_cfg, + paramwise_cfg=paramwise_cfg)) + optimizer = optim_constructor(model) + return optimizer diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/optimizer/default_constructor.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/optimizer/default_constructor.py new file mode 100644 index 00000000..de2ae39c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/optimizer/default_constructor.py @@ -0,0 +1,249 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import warnings + +import torch +from torch.nn import GroupNorm, LayerNorm + +from annotator.mmpkg.mmcv.utils import _BatchNorm, _InstanceNorm, build_from_cfg, is_list_of +from annotator.mmpkg.mmcv.utils.ext_loader import check_ops_exist +from .builder import OPTIMIZER_BUILDERS, OPTIMIZERS + + +@OPTIMIZER_BUILDERS.register_module() +class DefaultOptimizerConstructor: + """Default constructor for optimizers. + + By default each parameter share the same optimizer settings, and we + provide an argument ``paramwise_cfg`` to specify parameter-wise settings. + It is a dict and may contain the following fields: + + - ``custom_keys`` (dict): Specified parameters-wise settings by keys. If + one of the keys in ``custom_keys`` is a substring of the name of one + parameter, then the setting of the parameter will be specified by + ``custom_keys[key]`` and other setting like ``bias_lr_mult`` etc. will + be ignored. It should be noted that the aforementioned ``key`` is the + longest key that is a substring of the name of the parameter. If there + are multiple matched keys with the same length, then the key with lower + alphabet order will be chosen. + ``custom_keys[key]`` should be a dict and may contain fields ``lr_mult`` + and ``decay_mult``. See Example 2 below. + - ``bias_lr_mult`` (float): It will be multiplied to the learning + rate for all bias parameters (except for those in normalization + layers and offset layers of DCN). + - ``bias_decay_mult`` (float): It will be multiplied to the weight + decay for all bias parameters (except for those in + normalization layers, depthwise conv layers, offset layers of DCN). + - ``norm_decay_mult`` (float): It will be multiplied to the weight + decay for all weight and bias parameters of normalization + layers. + - ``dwconv_decay_mult`` (float): It will be multiplied to the weight + decay for all weight and bias parameters of depthwise conv + layers. + - ``dcn_offset_lr_mult`` (float): It will be multiplied to the learning + rate for parameters of offset layer in the deformable convs + of a model. + - ``bypass_duplicate`` (bool): If true, the duplicate parameters + would not be added into optimizer. Default: False. + + Note: + 1. If the option ``dcn_offset_lr_mult`` is used, the constructor will + override the effect of ``bias_lr_mult`` in the bias of offset + layer. So be careful when using both ``bias_lr_mult`` and + ``dcn_offset_lr_mult``. If you wish to apply both of them to the + offset layer in deformable convs, set ``dcn_offset_lr_mult`` + to the original ``dcn_offset_lr_mult`` * ``bias_lr_mult``. + 2. If the option ``dcn_offset_lr_mult`` is used, the constructor will + apply it to all the DCN layers in the model. So be careful when + the model contains multiple DCN layers in places other than + backbone. + + Args: + model (:obj:`nn.Module`): The model with parameters to be optimized. + optimizer_cfg (dict): The config dict of the optimizer. + Positional fields are + + - `type`: class name of the optimizer. + + Optional fields are + + - any arguments of the corresponding optimizer type, e.g., + lr, weight_decay, momentum, etc. + paramwise_cfg (dict, optional): Parameter-wise options. + + Example 1: + >>> model = torch.nn.modules.Conv1d(1, 1, 1) + >>> optimizer_cfg = dict(type='SGD', lr=0.01, momentum=0.9, + >>> weight_decay=0.0001) + >>> paramwise_cfg = dict(norm_decay_mult=0.) + >>> optim_builder = DefaultOptimizerConstructor( + >>> optimizer_cfg, paramwise_cfg) + >>> optimizer = optim_builder(model) + + Example 2: + >>> # assume model have attribute model.backbone and model.cls_head + >>> optimizer_cfg = dict(type='SGD', lr=0.01, weight_decay=0.95) + >>> paramwise_cfg = dict(custom_keys={ + '.backbone': dict(lr_mult=0.1, decay_mult=0.9)}) + >>> optim_builder = DefaultOptimizerConstructor( + >>> optimizer_cfg, paramwise_cfg) + >>> optimizer = optim_builder(model) + >>> # Then the `lr` and `weight_decay` for model.backbone is + >>> # (0.01 * 0.1, 0.95 * 0.9). `lr` and `weight_decay` for + >>> # model.cls_head is (0.01, 0.95). + """ + + def __init__(self, optimizer_cfg, paramwise_cfg=None): + if not isinstance(optimizer_cfg, dict): + raise TypeError('optimizer_cfg should be a dict', + f'but got {type(optimizer_cfg)}') + self.optimizer_cfg = optimizer_cfg + self.paramwise_cfg = {} if paramwise_cfg is None else paramwise_cfg + self.base_lr = optimizer_cfg.get('lr', None) + self.base_wd = optimizer_cfg.get('weight_decay', None) + self._validate_cfg() + + def _validate_cfg(self): + if not isinstance(self.paramwise_cfg, dict): + raise TypeError('paramwise_cfg should be None or a dict, ' + f'but got {type(self.paramwise_cfg)}') + + if 'custom_keys' in self.paramwise_cfg: + if not isinstance(self.paramwise_cfg['custom_keys'], dict): + raise TypeError( + 'If specified, custom_keys must be a dict, ' + f'but got {type(self.paramwise_cfg["custom_keys"])}') + if self.base_wd is None: + for key in self.paramwise_cfg['custom_keys']: + if 'decay_mult' in self.paramwise_cfg['custom_keys'][key]: + raise ValueError('base_wd should not be None') + + # get base lr and weight decay + # weight_decay must be explicitly specified if mult is specified + if ('bias_decay_mult' in self.paramwise_cfg + or 'norm_decay_mult' in self.paramwise_cfg + or 'dwconv_decay_mult' in self.paramwise_cfg): + if self.base_wd is None: + raise ValueError('base_wd should not be None') + + def _is_in(self, param_group, param_group_list): + assert is_list_of(param_group_list, dict) + param = set(param_group['params']) + param_set = set() + for group in param_group_list: + param_set.update(set(group['params'])) + + return not param.isdisjoint(param_set) + + def add_params(self, params, module, prefix='', is_dcn_module=None): + """Add all parameters of module to the params list. + + The parameters of the given module will be added to the list of param + groups, with specific rules defined by paramwise_cfg. + + Args: + params (list[dict]): A list of param groups, it will be modified + in place. + module (nn.Module): The module to be added. + prefix (str): The prefix of the module + is_dcn_module (int|float|None): If the current module is a + submodule of DCN, `is_dcn_module` will be passed to + control conv_offset layer's learning rate. Defaults to None. + """ + # get param-wise options + custom_keys = self.paramwise_cfg.get('custom_keys', {}) + # first sort with alphabet order and then sort with reversed len of str + sorted_keys = sorted(sorted(custom_keys.keys()), key=len, reverse=True) + + bias_lr_mult = self.paramwise_cfg.get('bias_lr_mult', 1.) + bias_decay_mult = self.paramwise_cfg.get('bias_decay_mult', 1.) + norm_decay_mult = self.paramwise_cfg.get('norm_decay_mult', 1.) + dwconv_decay_mult = self.paramwise_cfg.get('dwconv_decay_mult', 1.) + bypass_duplicate = self.paramwise_cfg.get('bypass_duplicate', False) + dcn_offset_lr_mult = self.paramwise_cfg.get('dcn_offset_lr_mult', 1.) + + # special rules for norm layers and depth-wise conv layers + is_norm = isinstance(module, + (_BatchNorm, _InstanceNorm, GroupNorm, LayerNorm)) + is_dwconv = ( + isinstance(module, torch.nn.Conv2d) + and module.in_channels == module.groups) + + for name, param in module.named_parameters(recurse=False): + param_group = {'params': [param]} + if not param.requires_grad: + params.append(param_group) + continue + if bypass_duplicate and self._is_in(param_group, params): + warnings.warn(f'{prefix} is duplicate. It is skipped since ' + f'bypass_duplicate={bypass_duplicate}') + continue + # if the parameter match one of the custom keys, ignore other rules + is_custom = False + for key in sorted_keys: + if key in f'{prefix}.{name}': + is_custom = True + lr_mult = custom_keys[key].get('lr_mult', 1.) + param_group['lr'] = self.base_lr * lr_mult + if self.base_wd is not None: + decay_mult = custom_keys[key].get('decay_mult', 1.) + param_group['weight_decay'] = self.base_wd * decay_mult + break + + if not is_custom: + # bias_lr_mult affects all bias parameters + # except for norm.bias dcn.conv_offset.bias + if name == 'bias' and not (is_norm or is_dcn_module): + param_group['lr'] = self.base_lr * bias_lr_mult + + if (prefix.find('conv_offset') != -1 and is_dcn_module + and isinstance(module, torch.nn.Conv2d)): + # deal with both dcn_offset's bias & weight + param_group['lr'] = self.base_lr * dcn_offset_lr_mult + + # apply weight decay policies + if self.base_wd is not None: + # norm decay + if is_norm: + param_group[ + 'weight_decay'] = self.base_wd * norm_decay_mult + # depth-wise conv + elif is_dwconv: + param_group[ + 'weight_decay'] = self.base_wd * dwconv_decay_mult + # bias lr and decay + elif name == 'bias' and not is_dcn_module: + # TODO: current bias_decay_mult will have affect on DCN + param_group[ + 'weight_decay'] = self.base_wd * bias_decay_mult + params.append(param_group) + + if check_ops_exist(): + from annotator.mmpkg.mmcv.ops import DeformConv2d, ModulatedDeformConv2d + is_dcn_module = isinstance(module, + (DeformConv2d, ModulatedDeformConv2d)) + else: + is_dcn_module = False + for child_name, child_mod in module.named_children(): + child_prefix = f'{prefix}.{child_name}' if prefix else child_name + self.add_params( + params, + child_mod, + prefix=child_prefix, + is_dcn_module=is_dcn_module) + + def __call__(self, model): + if hasattr(model, 'module'): + model = model.module + + optimizer_cfg = self.optimizer_cfg.copy() + # if no paramwise option is specified, just use the global setting + if not self.paramwise_cfg: + optimizer_cfg['params'] = model.parameters() + return build_from_cfg(optimizer_cfg, OPTIMIZERS) + + # set param-wise lr and weight decay recursively + params = [] + self.add_params(params, model) + optimizer_cfg['params'] = params + + return build_from_cfg(optimizer_cfg, OPTIMIZERS) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/priority.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/priority.py new file mode 100644 index 00000000..64cc4e3a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/priority.py @@ -0,0 +1,60 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from enum import Enum + + +class Priority(Enum): + """Hook priority levels. + + +--------------+------------+ + | Level | Value | + +==============+============+ + | HIGHEST | 0 | + +--------------+------------+ + | VERY_HIGH | 10 | + +--------------+------------+ + | HIGH | 30 | + +--------------+------------+ + | ABOVE_NORMAL | 40 | + +--------------+------------+ + | NORMAL | 50 | + +--------------+------------+ + | BELOW_NORMAL | 60 | + +--------------+------------+ + | LOW | 70 | + +--------------+------------+ + | VERY_LOW | 90 | + +--------------+------------+ + | LOWEST | 100 | + +--------------+------------+ + """ + + HIGHEST = 0 + VERY_HIGH = 10 + HIGH = 30 + ABOVE_NORMAL = 40 + NORMAL = 50 + BELOW_NORMAL = 60 + LOW = 70 + VERY_LOW = 90 + LOWEST = 100 + + +def get_priority(priority): + """Get priority value. + + Args: + priority (int or str or :obj:`Priority`): Priority. + + Returns: + int: The priority value. + """ + if isinstance(priority, int): + if priority < 0 or priority > 100: + raise ValueError('priority must be between 0 and 100') + return priority + elif isinstance(priority, Priority): + return priority.value + elif isinstance(priority, str): + return Priority[priority.upper()].value + else: + raise TypeError('priority must be an integer or Priority enum value') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/utils.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/utils.py new file mode 100644 index 00000000..11bbc523 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/runner/utils.py @@ -0,0 +1,93 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os +import random +import sys +import time +import warnings +from getpass import getuser +from socket import gethostname + +import numpy as np +import torch + +import annotator.mmpkg.mmcv as mmcv + + +def get_host_info(): + """Get hostname and username. + + Return empty string if exception raised, e.g. ``getpass.getuser()`` will + lead to error in docker container + """ + host = '' + try: + host = f'{getuser()}@{gethostname()}' + except Exception as e: + warnings.warn(f'Host or user not found: {str(e)}') + finally: + return host + + +def get_time_str(): + return time.strftime('%Y%m%d_%H%M%S', time.localtime()) + + +def obj_from_dict(info, parent=None, default_args=None): + """Initialize an object from dict. + + The dict must contain the key "type", which indicates the object type, it + can be either a string or type, such as "list" or ``list``. Remaining + fields are treated as the arguments for constructing the object. + + Args: + info (dict): Object types and arguments. + parent (:class:`module`): Module which may containing expected object + classes. + default_args (dict, optional): Default arguments for initializing the + object. + + Returns: + any type: Object built from the dict. + """ + assert isinstance(info, dict) and 'type' in info + assert isinstance(default_args, dict) or default_args is None + args = info.copy() + obj_type = args.pop('type') + if mmcv.is_str(obj_type): + if parent is not None: + obj_type = getattr(parent, obj_type) + else: + obj_type = sys.modules[obj_type] + elif not isinstance(obj_type, type): + raise TypeError('type must be a str or valid type, but ' + f'got {type(obj_type)}') + if default_args is not None: + for name, value in default_args.items(): + args.setdefault(name, value) + return obj_type(**args) + + +def set_random_seed(seed, deterministic=False, use_rank_shift=False): + """Set random seed. + + Args: + seed (int): Seed to be used. + deterministic (bool): Whether to set the deterministic option for + CUDNN backend, i.e., set `torch.backends.cudnn.deterministic` + to True and `torch.backends.cudnn.benchmark` to False. + Default: False. + rank_shift (bool): Whether to add rank number to the random seed to + have different random seed in different threads. Default: False. + """ + if use_rank_shift: + rank, _ = mmcv.runner.get_dist_info() + seed += rank + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + torch.cuda.manual_seed(seed) + torch.cuda.manual_seed_all(seed) + os.environ['PYTHONHASHSEED'] = str(seed) + if deterministic: + torch.backends.cudnn.deterministic = True + torch.backends.cudnn.benchmark = False diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/__init__.py new file mode 100644 index 00000000..378a0068 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/__init__.py @@ -0,0 +1,69 @@ +# flake8: noqa +# Copyright (c) OpenMMLab. All rights reserved. +from .config import Config, ConfigDict, DictAction +from .misc import (check_prerequisites, concat_list, deprecated_api_warning, + has_method, import_modules_from_strings, is_list_of, + is_method_overridden, is_seq_of, is_str, is_tuple_of, + iter_cast, list_cast, requires_executable, requires_package, + slice_list, to_1tuple, to_2tuple, to_3tuple, to_4tuple, + to_ntuple, tuple_cast) +from .path import (check_file_exist, fopen, is_filepath, mkdir_or_exist, + scandir, symlink) +from .progressbar import (ProgressBar, track_iter_progress, + track_parallel_progress, track_progress) +from .testing import (assert_attrs_equal, assert_dict_contains_subset, + assert_dict_has_keys, assert_is_norm_layer, + assert_keys_equal, assert_params_all_zeros, + check_python_script) +from .timer import Timer, TimerError, check_time +from .version_utils import digit_version, get_git_hash + +try: + import torch +except ImportError: + __all__ = [ + 'Config', 'ConfigDict', 'DictAction', 'is_str', 'iter_cast', + 'list_cast', 'tuple_cast', 'is_seq_of', 'is_list_of', 'is_tuple_of', + 'slice_list', 'concat_list', 'check_prerequisites', 'requires_package', + 'requires_executable', 'is_filepath', 'fopen', 'check_file_exist', + 'mkdir_or_exist', 'symlink', 'scandir', 'ProgressBar', + 'track_progress', 'track_iter_progress', 'track_parallel_progress', + 'Timer', 'TimerError', 'check_time', 'deprecated_api_warning', + 'digit_version', 'get_git_hash', 'import_modules_from_strings', + 'assert_dict_contains_subset', 'assert_attrs_equal', + 'assert_dict_has_keys', 'assert_keys_equal', 'check_python_script', + 'to_1tuple', 'to_2tuple', 'to_3tuple', 'to_4tuple', 'to_ntuple', + 'is_method_overridden', 'has_method' + ] +else: + from .env import collect_env + from .logging import get_logger, print_log + from .parrots_jit import jit, skip_no_elena + from .parrots_wrapper import ( + TORCH_VERSION, BuildExtension, CppExtension, CUDAExtension, DataLoader, + PoolDataLoader, SyncBatchNorm, _AdaptiveAvgPoolNd, _AdaptiveMaxPoolNd, + _AvgPoolNd, _BatchNorm, _ConvNd, _ConvTransposeMixin, _InstanceNorm, + _MaxPoolNd, get_build_config, is_rocm_pytorch, _get_cuda_home) + from .registry import Registry, build_from_cfg + from .trace import is_jit_tracing + __all__ = [ + 'Config', 'ConfigDict', 'DictAction', 'collect_env', 'get_logger', + 'print_log', 'is_str', 'iter_cast', 'list_cast', 'tuple_cast', + 'is_seq_of', 'is_list_of', 'is_tuple_of', 'slice_list', 'concat_list', + 'check_prerequisites', 'requires_package', 'requires_executable', + 'is_filepath', 'fopen', 'check_file_exist', 'mkdir_or_exist', + 'symlink', 'scandir', 'ProgressBar', 'track_progress', + 'track_iter_progress', 'track_parallel_progress', 'Registry', + 'build_from_cfg', 'Timer', 'TimerError', 'check_time', 'SyncBatchNorm', + '_AdaptiveAvgPoolNd', '_AdaptiveMaxPoolNd', '_AvgPoolNd', '_BatchNorm', + '_ConvNd', '_ConvTransposeMixin', '_InstanceNorm', '_MaxPoolNd', + 'get_build_config', 'BuildExtension', 'CppExtension', 'CUDAExtension', + 'DataLoader', 'PoolDataLoader', 'TORCH_VERSION', + 'deprecated_api_warning', 'digit_version', 'get_git_hash', + 'import_modules_from_strings', 'jit', 'skip_no_elena', + 'assert_dict_contains_subset', 'assert_attrs_equal', + 'assert_dict_has_keys', 'assert_keys_equal', 'assert_is_norm_layer', + 'assert_params_all_zeros', 'check_python_script', + 'is_method_overridden', 'is_jit_tracing', 'is_rocm_pytorch', + '_get_cuda_home', 'has_method' + ] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/config.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/config.py new file mode 100644 index 00000000..e2f7551f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/config.py @@ -0,0 +1,688 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import ast +import copy +import os +import os.path as osp +import platform +import shutil +import sys +import tempfile +import uuid +import warnings +from argparse import Action, ArgumentParser +from collections import abc +from importlib import import_module + +from addict import Dict +from yapf.yapflib.yapf_api import FormatCode + +from .misc import import_modules_from_strings +from .path import check_file_exist + +if platform.system() == 'Windows': + import regex as re +else: + import re + +BASE_KEY = '_base_' +DELETE_KEY = '_delete_' +DEPRECATION_KEY = '_deprecation_' +RESERVED_KEYS = ['filename', 'text', 'pretty_text'] + + +class ConfigDict(Dict): + + def __missing__(self, name): + raise KeyError(name) + + def __getattr__(self, name): + try: + value = super(ConfigDict, self).__getattr__(name) + except KeyError: + ex = AttributeError(f"'{self.__class__.__name__}' object has no " + f"attribute '{name}'") + except Exception as e: + ex = e + else: + return value + raise ex + + +def add_args(parser, cfg, prefix=''): + for k, v in cfg.items(): + if isinstance(v, str): + parser.add_argument('--' + prefix + k) + elif isinstance(v, int): + parser.add_argument('--' + prefix + k, type=int) + elif isinstance(v, float): + parser.add_argument('--' + prefix + k, type=float) + elif isinstance(v, bool): + parser.add_argument('--' + prefix + k, action='store_true') + elif isinstance(v, dict): + add_args(parser, v, prefix + k + '.') + elif isinstance(v, abc.Iterable): + parser.add_argument('--' + prefix + k, type=type(v[0]), nargs='+') + else: + print(f'cannot parse key {prefix + k} of type {type(v)}') + return parser + + +class Config: + """A facility for config and config files. + + It supports common file formats as configs: python/json/yaml. The interface + is the same as a dict object and also allows access config values as + attributes. + + Example: + >>> cfg = Config(dict(a=1, b=dict(b1=[0, 1]))) + >>> cfg.a + 1 + >>> cfg.b + {'b1': [0, 1]} + >>> cfg.b.b1 + [0, 1] + >>> cfg = Config.fromfile('tests/data/config/a.py') + >>> cfg.filename + "/home/kchen/projects/mmcv/tests/data/config/a.py" + >>> cfg.item4 + 'test' + >>> cfg + "Config [path: /home/kchen/projects/mmcv/tests/data/config/a.py]: " + "{'item1': [1, 2], 'item2': {'a': 0}, 'item3': True, 'item4': 'test'}" + """ + + @staticmethod + def _validate_py_syntax(filename): + with open(filename, 'r', encoding='utf-8') as f: + # Setting encoding explicitly to resolve coding issue on windows + content = f.read() + try: + ast.parse(content) + except SyntaxError as e: + raise SyntaxError('There are syntax errors in config ' + f'file {filename}: {e}') + + @staticmethod + def _substitute_predefined_vars(filename, temp_config_name): + file_dirname = osp.dirname(filename) + file_basename = osp.basename(filename) + file_basename_no_extension = osp.splitext(file_basename)[0] + file_extname = osp.splitext(filename)[1] + support_templates = dict( + fileDirname=file_dirname, + fileBasename=file_basename, + fileBasenameNoExtension=file_basename_no_extension, + fileExtname=file_extname) + with open(filename, 'r', encoding='utf-8') as f: + # Setting encoding explicitly to resolve coding issue on windows + config_file = f.read() + for key, value in support_templates.items(): + regexp = r'\{\{\s*' + str(key) + r'\s*\}\}' + value = value.replace('\\', '/') + config_file = re.sub(regexp, value, config_file) + with open(temp_config_name, 'w', encoding='utf-8') as tmp_config_file: + tmp_config_file.write(config_file) + + @staticmethod + def _pre_substitute_base_vars(filename, temp_config_name): + """Substitute base variable placehoders to string, so that parsing + would work.""" + with open(filename, 'r', encoding='utf-8') as f: + # Setting encoding explicitly to resolve coding issue on windows + config_file = f.read() + base_var_dict = {} + regexp = r'\{\{\s*' + BASE_KEY + r'\.([\w\.]+)\s*\}\}' + base_vars = set(re.findall(regexp, config_file)) + for base_var in base_vars: + randstr = f'_{base_var}_{uuid.uuid4().hex.lower()[:6]}' + base_var_dict[randstr] = base_var + regexp = r'\{\{\s*' + BASE_KEY + r'\.' + base_var + r'\s*\}\}' + config_file = re.sub(regexp, f'"{randstr}"', config_file) + with open(temp_config_name, 'w', encoding='utf-8') as tmp_config_file: + tmp_config_file.write(config_file) + return base_var_dict + + @staticmethod + def _substitute_base_vars(cfg, base_var_dict, base_cfg): + """Substitute variable strings to their actual values.""" + cfg = copy.deepcopy(cfg) + + if isinstance(cfg, dict): + for k, v in cfg.items(): + if isinstance(v, str) and v in base_var_dict: + new_v = base_cfg + for new_k in base_var_dict[v].split('.'): + new_v = new_v[new_k] + cfg[k] = new_v + elif isinstance(v, (list, tuple, dict)): + cfg[k] = Config._substitute_base_vars( + v, base_var_dict, base_cfg) + elif isinstance(cfg, tuple): + cfg = tuple( + Config._substitute_base_vars(c, base_var_dict, base_cfg) + for c in cfg) + elif isinstance(cfg, list): + cfg = [ + Config._substitute_base_vars(c, base_var_dict, base_cfg) + for c in cfg + ] + elif isinstance(cfg, str) and cfg in base_var_dict: + new_v = base_cfg + for new_k in base_var_dict[cfg].split('.'): + new_v = new_v[new_k] + cfg = new_v + + return cfg + + @staticmethod + def _file2dict(filename, use_predefined_variables=True): + filename = osp.abspath(osp.expanduser(filename)) + check_file_exist(filename) + fileExtname = osp.splitext(filename)[1] + if fileExtname not in ['.py', '.json', '.yaml', '.yml']: + raise IOError('Only py/yml/yaml/json type are supported now!') + + with tempfile.TemporaryDirectory() as temp_config_dir: + temp_config_file = tempfile.NamedTemporaryFile( + dir=temp_config_dir, suffix=fileExtname) + if platform.system() == 'Windows': + temp_config_file.close() + temp_config_name = osp.basename(temp_config_file.name) + # Substitute predefined variables + if use_predefined_variables: + Config._substitute_predefined_vars(filename, + temp_config_file.name) + else: + shutil.copyfile(filename, temp_config_file.name) + # Substitute base variables from placeholders to strings + base_var_dict = Config._pre_substitute_base_vars( + temp_config_file.name, temp_config_file.name) + + if filename.endswith('.py'): + temp_module_name = osp.splitext(temp_config_name)[0] + sys.path.insert(0, temp_config_dir) + Config._validate_py_syntax(filename) + mod = import_module(temp_module_name) + sys.path.pop(0) + cfg_dict = { + name: value + for name, value in mod.__dict__.items() + if not name.startswith('__') + } + # delete imported module + del sys.modules[temp_module_name] + elif filename.endswith(('.yml', '.yaml', '.json')): + import annotator.mmpkg.mmcv as mmcv + cfg_dict = mmcv.load(temp_config_file.name) + # close temp file + temp_config_file.close() + + # check deprecation information + if DEPRECATION_KEY in cfg_dict: + deprecation_info = cfg_dict.pop(DEPRECATION_KEY) + warning_msg = f'The config file {filename} will be deprecated ' \ + 'in the future.' + if 'expected' in deprecation_info: + warning_msg += f' Please use {deprecation_info["expected"]} ' \ + 'instead.' + if 'reference' in deprecation_info: + warning_msg += ' More information can be found at ' \ + f'{deprecation_info["reference"]}' + warnings.warn(warning_msg) + + cfg_text = filename + '\n' + with open(filename, 'r', encoding='utf-8') as f: + # Setting encoding explicitly to resolve coding issue on windows + cfg_text += f.read() + + if BASE_KEY in cfg_dict: + cfg_dir = osp.dirname(filename) + base_filename = cfg_dict.pop(BASE_KEY) + base_filename = base_filename if isinstance( + base_filename, list) else [base_filename] + + cfg_dict_list = list() + cfg_text_list = list() + for f in base_filename: + _cfg_dict, _cfg_text = Config._file2dict(osp.join(cfg_dir, f)) + cfg_dict_list.append(_cfg_dict) + cfg_text_list.append(_cfg_text) + + base_cfg_dict = dict() + for c in cfg_dict_list: + duplicate_keys = base_cfg_dict.keys() & c.keys() + if len(duplicate_keys) > 0: + raise KeyError('Duplicate key is not allowed among bases. ' + f'Duplicate keys: {duplicate_keys}') + base_cfg_dict.update(c) + + # Substitute base variables from strings to their actual values + cfg_dict = Config._substitute_base_vars(cfg_dict, base_var_dict, + base_cfg_dict) + + base_cfg_dict = Config._merge_a_into_b(cfg_dict, base_cfg_dict) + cfg_dict = base_cfg_dict + + # merge cfg_text + cfg_text_list.append(cfg_text) + cfg_text = '\n'.join(cfg_text_list) + + return cfg_dict, cfg_text + + @staticmethod + def _merge_a_into_b(a, b, allow_list_keys=False): + """merge dict ``a`` into dict ``b`` (non-inplace). + + Values in ``a`` will overwrite ``b``. ``b`` is copied first to avoid + in-place modifications. + + Args: + a (dict): The source dict to be merged into ``b``. + b (dict): The origin dict to be fetch keys from ``a``. + allow_list_keys (bool): If True, int string keys (e.g. '0', '1') + are allowed in source ``a`` and will replace the element of the + corresponding index in b if b is a list. Default: False. + + Returns: + dict: The modified dict of ``b`` using ``a``. + + Examples: + # Normally merge a into b. + >>> Config._merge_a_into_b( + ... dict(obj=dict(a=2)), dict(obj=dict(a=1))) + {'obj': {'a': 2}} + + # Delete b first and merge a into b. + >>> Config._merge_a_into_b( + ... dict(obj=dict(_delete_=True, a=2)), dict(obj=dict(a=1))) + {'obj': {'a': 2}} + + # b is a list + >>> Config._merge_a_into_b( + ... {'0': dict(a=2)}, [dict(a=1), dict(b=2)], True) + [{'a': 2}, {'b': 2}] + """ + b = b.copy() + for k, v in a.items(): + if allow_list_keys and k.isdigit() and isinstance(b, list): + k = int(k) + if len(b) <= k: + raise KeyError(f'Index {k} exceeds the length of list {b}') + b[k] = Config._merge_a_into_b(v, b[k], allow_list_keys) + elif isinstance(v, + dict) and k in b and not v.pop(DELETE_KEY, False): + allowed_types = (dict, list) if allow_list_keys else dict + if not isinstance(b[k], allowed_types): + raise TypeError( + f'{k}={v} in child config cannot inherit from base ' + f'because {k} is a dict in the child config but is of ' + f'type {type(b[k])} in base config. You may set ' + f'`{DELETE_KEY}=True` to ignore the base config') + b[k] = Config._merge_a_into_b(v, b[k], allow_list_keys) + else: + b[k] = v + return b + + @staticmethod + def fromfile(filename, + use_predefined_variables=True, + import_custom_modules=True): + cfg_dict, cfg_text = Config._file2dict(filename, + use_predefined_variables) + if import_custom_modules and cfg_dict.get('custom_imports', None): + import_modules_from_strings(**cfg_dict['custom_imports']) + return Config(cfg_dict, cfg_text=cfg_text, filename=filename) + + @staticmethod + def fromstring(cfg_str, file_format): + """Generate config from config str. + + Args: + cfg_str (str): Config str. + file_format (str): Config file format corresponding to the + config str. Only py/yml/yaml/json type are supported now! + + Returns: + obj:`Config`: Config obj. + """ + if file_format not in ['.py', '.json', '.yaml', '.yml']: + raise IOError('Only py/yml/yaml/json type are supported now!') + if file_format != '.py' and 'dict(' in cfg_str: + # check if users specify a wrong suffix for python + warnings.warn( + 'Please check "file_format", the file format may be .py') + with tempfile.NamedTemporaryFile( + 'w', encoding='utf-8', suffix=file_format, + delete=False) as temp_file: + temp_file.write(cfg_str) + # on windows, previous implementation cause error + # see PR 1077 for details + cfg = Config.fromfile(temp_file.name) + os.remove(temp_file.name) + return cfg + + @staticmethod + def auto_argparser(description=None): + """Generate argparser from config file automatically (experimental)""" + partial_parser = ArgumentParser(description=description) + partial_parser.add_argument('config', help='config file path') + cfg_file = partial_parser.parse_known_args()[0].config + cfg = Config.fromfile(cfg_file) + parser = ArgumentParser(description=description) + parser.add_argument('config', help='config file path') + add_args(parser, cfg) + return parser, cfg + + def __init__(self, cfg_dict=None, cfg_text=None, filename=None): + if cfg_dict is None: + cfg_dict = dict() + elif not isinstance(cfg_dict, dict): + raise TypeError('cfg_dict must be a dict, but ' + f'got {type(cfg_dict)}') + for key in cfg_dict: + if key in RESERVED_KEYS: + raise KeyError(f'{key} is reserved for config file') + + super(Config, self).__setattr__('_cfg_dict', ConfigDict(cfg_dict)) + super(Config, self).__setattr__('_filename', filename) + if cfg_text: + text = cfg_text + elif filename: + with open(filename, 'r') as f: + text = f.read() + else: + text = '' + super(Config, self).__setattr__('_text', text) + + @property + def filename(self): + return self._filename + + @property + def text(self): + return self._text + + @property + def pretty_text(self): + + indent = 4 + + def _indent(s_, num_spaces): + s = s_.split('\n') + if len(s) == 1: + return s_ + first = s.pop(0) + s = [(num_spaces * ' ') + line for line in s] + s = '\n'.join(s) + s = first + '\n' + s + return s + + def _format_basic_types(k, v, use_mapping=False): + if isinstance(v, str): + v_str = f"'{v}'" + else: + v_str = str(v) + + if use_mapping: + k_str = f"'{k}'" if isinstance(k, str) else str(k) + attr_str = f'{k_str}: {v_str}' + else: + attr_str = f'{str(k)}={v_str}' + attr_str = _indent(attr_str, indent) + + return attr_str + + def _format_list(k, v, use_mapping=False): + # check if all items in the list are dict + if all(isinstance(_, dict) for _ in v): + v_str = '[\n' + v_str += '\n'.join( + f'dict({_indent(_format_dict(v_), indent)}),' + for v_ in v).rstrip(',') + if use_mapping: + k_str = f"'{k}'" if isinstance(k, str) else str(k) + attr_str = f'{k_str}: {v_str}' + else: + attr_str = f'{str(k)}={v_str}' + attr_str = _indent(attr_str, indent) + ']' + else: + attr_str = _format_basic_types(k, v, use_mapping) + return attr_str + + def _contain_invalid_identifier(dict_str): + contain_invalid_identifier = False + for key_name in dict_str: + contain_invalid_identifier |= \ + (not str(key_name).isidentifier()) + return contain_invalid_identifier + + def _format_dict(input_dict, outest_level=False): + r = '' + s = [] + + use_mapping = _contain_invalid_identifier(input_dict) + if use_mapping: + r += '{' + for idx, (k, v) in enumerate(input_dict.items()): + is_last = idx >= len(input_dict) - 1 + end = '' if outest_level or is_last else ',' + if isinstance(v, dict): + v_str = '\n' + _format_dict(v) + if use_mapping: + k_str = f"'{k}'" if isinstance(k, str) else str(k) + attr_str = f'{k_str}: dict({v_str}' + else: + attr_str = f'{str(k)}=dict({v_str}' + attr_str = _indent(attr_str, indent) + ')' + end + elif isinstance(v, list): + attr_str = _format_list(k, v, use_mapping) + end + else: + attr_str = _format_basic_types(k, v, use_mapping) + end + + s.append(attr_str) + r += '\n'.join(s) + if use_mapping: + r += '}' + return r + + cfg_dict = self._cfg_dict.to_dict() + text = _format_dict(cfg_dict, outest_level=True) + # copied from setup.cfg + yapf_style = dict( + based_on_style='pep8', + blank_line_before_nested_class_or_def=True, + split_before_expression_after_opening_paren=True) + text, _ = FormatCode(text, style_config=yapf_style, verify=True) + + return text + + def __repr__(self): + return f'Config (path: {self.filename}): {self._cfg_dict.__repr__()}' + + def __len__(self): + return len(self._cfg_dict) + + def __getattr__(self, name): + return getattr(self._cfg_dict, name) + + def __getitem__(self, name): + return self._cfg_dict.__getitem__(name) + + def __setattr__(self, name, value): + if isinstance(value, dict): + value = ConfigDict(value) + self._cfg_dict.__setattr__(name, value) + + def __setitem__(self, name, value): + if isinstance(value, dict): + value = ConfigDict(value) + self._cfg_dict.__setitem__(name, value) + + def __iter__(self): + return iter(self._cfg_dict) + + def __getstate__(self): + return (self._cfg_dict, self._filename, self._text) + + def __setstate__(self, state): + _cfg_dict, _filename, _text = state + super(Config, self).__setattr__('_cfg_dict', _cfg_dict) + super(Config, self).__setattr__('_filename', _filename) + super(Config, self).__setattr__('_text', _text) + + def dump(self, file=None): + cfg_dict = super(Config, self).__getattribute__('_cfg_dict').to_dict() + if self.filename.endswith('.py'): + if file is None: + return self.pretty_text + else: + with open(file, 'w', encoding='utf-8') as f: + f.write(self.pretty_text) + else: + import annotator.mmpkg.mmcv as mmcv + if file is None: + file_format = self.filename.split('.')[-1] + return mmcv.dump(cfg_dict, file_format=file_format) + else: + mmcv.dump(cfg_dict, file) + + def merge_from_dict(self, options, allow_list_keys=True): + """Merge list into cfg_dict. + + Merge the dict parsed by MultipleKVAction into this cfg. + + Examples: + >>> options = {'model.backbone.depth': 50, + ... 'model.backbone.with_cp':True} + >>> cfg = Config(dict(model=dict(backbone=dict(type='ResNet')))) + >>> cfg.merge_from_dict(options) + >>> cfg_dict = super(Config, self).__getattribute__('_cfg_dict') + >>> assert cfg_dict == dict( + ... model=dict(backbone=dict(depth=50, with_cp=True))) + + # Merge list element + >>> cfg = Config(dict(pipeline=[ + ... dict(type='LoadImage'), dict(type='LoadAnnotations')])) + >>> options = dict(pipeline={'0': dict(type='SelfLoadImage')}) + >>> cfg.merge_from_dict(options, allow_list_keys=True) + >>> cfg_dict = super(Config, self).__getattribute__('_cfg_dict') + >>> assert cfg_dict == dict(pipeline=[ + ... dict(type='SelfLoadImage'), dict(type='LoadAnnotations')]) + + Args: + options (dict): dict of configs to merge from. + allow_list_keys (bool): If True, int string keys (e.g. '0', '1') + are allowed in ``options`` and will replace the element of the + corresponding index in the config if the config is a list. + Default: True. + """ + option_cfg_dict = {} + for full_key, v in options.items(): + d = option_cfg_dict + key_list = full_key.split('.') + for subkey in key_list[:-1]: + d.setdefault(subkey, ConfigDict()) + d = d[subkey] + subkey = key_list[-1] + d[subkey] = v + + cfg_dict = super(Config, self).__getattribute__('_cfg_dict') + super(Config, self).__setattr__( + '_cfg_dict', + Config._merge_a_into_b( + option_cfg_dict, cfg_dict, allow_list_keys=allow_list_keys)) + + +class DictAction(Action): + """ + argparse action to split an argument into KEY=VALUE form + on the first = and append to a dictionary. List options can + be passed as comma separated values, i.e 'KEY=V1,V2,V3', or with explicit + brackets, i.e. 'KEY=[V1,V2,V3]'. It also support nested brackets to build + list/tuple values. e.g. 'KEY=[(V1,V2),(V3,V4)]' + """ + + @staticmethod + def _parse_int_float_bool(val): + try: + return int(val) + except ValueError: + pass + try: + return float(val) + except ValueError: + pass + if val.lower() in ['true', 'false']: + return True if val.lower() == 'true' else False + return val + + @staticmethod + def _parse_iterable(val): + """Parse iterable values in the string. + + All elements inside '()' or '[]' are treated as iterable values. + + Args: + val (str): Value string. + + Returns: + list | tuple: The expanded list or tuple from the string. + + Examples: + >>> DictAction._parse_iterable('1,2,3') + [1, 2, 3] + >>> DictAction._parse_iterable('[a, b, c]') + ['a', 'b', 'c'] + >>> DictAction._parse_iterable('[(1, 2, 3), [a, b], c]') + [(1, 2, 3), ['a', 'b'], 'c'] + """ + + def find_next_comma(string): + """Find the position of next comma in the string. + + If no ',' is found in the string, return the string length. All + chars inside '()' and '[]' are treated as one element and thus ',' + inside these brackets are ignored. + """ + assert (string.count('(') == string.count(')')) and ( + string.count('[') == string.count(']')), \ + f'Imbalanced brackets exist in {string}' + end = len(string) + for idx, char in enumerate(string): + pre = string[:idx] + # The string before this ',' is balanced + if ((char == ',') and (pre.count('(') == pre.count(')')) + and (pre.count('[') == pre.count(']'))): + end = idx + break + return end + + # Strip ' and " characters and replace whitespace. + val = val.strip('\'\"').replace(' ', '') + is_tuple = False + if val.startswith('(') and val.endswith(')'): + is_tuple = True + val = val[1:-1] + elif val.startswith('[') and val.endswith(']'): + val = val[1:-1] + elif ',' not in val: + # val is a single value + return DictAction._parse_int_float_bool(val) + + values = [] + while len(val) > 0: + comma_idx = find_next_comma(val) + element = DictAction._parse_iterable(val[:comma_idx]) + values.append(element) + val = val[comma_idx + 1:] + if is_tuple: + values = tuple(values) + return values + + def __call__(self, parser, namespace, values, option_string=None): + options = {} + for kv in values: + key, val = kv.split('=', maxsplit=1) + options[key] = self._parse_iterable(val) + setattr(namespace, self.dest, options) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/env.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/env.py new file mode 100644 index 00000000..a0c6e64a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/env.py @@ -0,0 +1,95 @@ +# Copyright (c) OpenMMLab. All rights reserved. +"""This file holding some environment constant for sharing by other files.""" + +import os.path as osp +import subprocess +import sys +from collections import defaultdict + +import cv2 +import torch + +import annotator.mmpkg.mmcv as mmcv +from .parrots_wrapper import get_build_config + + +def collect_env(): + """Collect the information of the running environments. + + Returns: + dict: The environment information. The following fields are contained. + + - sys.platform: The variable of ``sys.platform``. + - Python: Python version. + - CUDA available: Bool, indicating if CUDA is available. + - GPU devices: Device type of each GPU. + - CUDA_HOME (optional): The env var ``CUDA_HOME``. + - NVCC (optional): NVCC version. + - GCC: GCC version, "n/a" if GCC is not installed. + - PyTorch: PyTorch version. + - PyTorch compiling details: The output of \ + ``torch.__config__.show()``. + - TorchVision (optional): TorchVision version. + - OpenCV: OpenCV version. + - MMCV: MMCV version. + - MMCV Compiler: The GCC version for compiling MMCV ops. + - MMCV CUDA Compiler: The CUDA version for compiling MMCV ops. + """ + env_info = {} + env_info['sys.platform'] = sys.platform + env_info['Python'] = sys.version.replace('\n', '') + + cuda_available = torch.cuda.is_available() + env_info['CUDA available'] = cuda_available + + if cuda_available: + devices = defaultdict(list) + for k in range(torch.cuda.device_count()): + devices[torch.cuda.get_device_name(k)].append(str(k)) + for name, device_ids in devices.items(): + env_info['GPU ' + ','.join(device_ids)] = name + + from annotator.mmpkg.mmcv.utils.parrots_wrapper import _get_cuda_home + CUDA_HOME = _get_cuda_home() + env_info['CUDA_HOME'] = CUDA_HOME + + if CUDA_HOME is not None and osp.isdir(CUDA_HOME): + try: + nvcc = osp.join(CUDA_HOME, 'bin/nvcc') + nvcc = subprocess.check_output( + f'"{nvcc}" -V | tail -n1', shell=True) + nvcc = nvcc.decode('utf-8').strip() + except subprocess.SubprocessError: + nvcc = 'Not Available' + env_info['NVCC'] = nvcc + + try: + gcc = subprocess.check_output('gcc --version | head -n1', shell=True) + gcc = gcc.decode('utf-8').strip() + env_info['GCC'] = gcc + except subprocess.CalledProcessError: # gcc is unavailable + env_info['GCC'] = 'n/a' + + env_info['PyTorch'] = torch.__version__ + env_info['PyTorch compiling details'] = get_build_config() + + try: + import torchvision + env_info['TorchVision'] = torchvision.__version__ + except ModuleNotFoundError: + pass + + env_info['OpenCV'] = cv2.__version__ + + env_info['MMCV'] = mmcv.__version__ + + try: + from annotator.mmpkg.mmcv.ops import get_compiler_version, get_compiling_cuda_version + except ModuleNotFoundError: + env_info['MMCV Compiler'] = 'n/a' + env_info['MMCV CUDA Compiler'] = 'n/a' + else: + env_info['MMCV Compiler'] = get_compiler_version() + env_info['MMCV CUDA Compiler'] = get_compiling_cuda_version() + + return env_info diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/ext_loader.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/ext_loader.py new file mode 100644 index 00000000..08132d2c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/ext_loader.py @@ -0,0 +1,71 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import importlib +import os +import pkgutil +import warnings +from collections import namedtuple + +import torch + +if torch.__version__ != 'parrots': + + def load_ext(name, funcs): + ext = importlib.import_module('mmcv.' + name) + for fun in funcs: + assert hasattr(ext, fun), f'{fun} miss in module {name}' + return ext +else: + from parrots import extension + from parrots.base import ParrotsException + + has_return_value_ops = [ + 'nms', + 'softnms', + 'nms_match', + 'nms_rotated', + 'top_pool_forward', + 'top_pool_backward', + 'bottom_pool_forward', + 'bottom_pool_backward', + 'left_pool_forward', + 'left_pool_backward', + 'right_pool_forward', + 'right_pool_backward', + 'fused_bias_leakyrelu', + 'upfirdn2d', + 'ms_deform_attn_forward', + 'pixel_group', + 'contour_expand', + ] + + def get_fake_func(name, e): + + def fake_func(*args, **kwargs): + warnings.warn(f'{name} is not supported in parrots now') + raise e + + return fake_func + + def load_ext(name, funcs): + ExtModule = namedtuple('ExtModule', funcs) + ext_list = [] + lib_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + for fun in funcs: + try: + ext_fun = extension.load(fun, name, lib_dir=lib_root) + except ParrotsException as e: + if 'No element registered' not in e.message: + warnings.warn(e.message) + ext_fun = get_fake_func(fun, e) + ext_list.append(ext_fun) + else: + if fun in has_return_value_ops: + ext_list.append(ext_fun.op) + else: + ext_list.append(ext_fun.op_) + return ExtModule(*ext_list) + + +def check_ops_exist(): + ext_loader = pkgutil.find_loader('mmcv._ext') + return ext_loader is not None diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/logging.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/logging.py new file mode 100644 index 00000000..4aa0e04b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/logging.py @@ -0,0 +1,110 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import logging + +import torch.distributed as dist + +logger_initialized = {} + + +def get_logger(name, log_file=None, log_level=logging.INFO, file_mode='w'): + """Initialize and get a logger by name. + + If the logger has not been initialized, this method will initialize the + logger by adding one or two handlers, otherwise the initialized logger will + be directly returned. During initialization, a StreamHandler will always be + added. If `log_file` is specified and the process rank is 0, a FileHandler + will also be added. + + Args: + name (str): Logger name. + log_file (str | None): The log filename. If specified, a FileHandler + will be added to the logger. + log_level (int): The logger level. Note that only the process of + rank 0 is affected, and other processes will set the level to + "Error" thus be silent most of the time. + file_mode (str): The file mode used in opening log file. + Defaults to 'w'. + + Returns: + logging.Logger: The expected logger. + """ + logger = logging.getLogger(name) + if name in logger_initialized: + return logger + # handle hierarchical names + # e.g., logger "a" is initialized, then logger "a.b" will skip the + # initialization since it is a child of "a". + for logger_name in logger_initialized: + if name.startswith(logger_name): + return logger + + # handle duplicate logs to the console + # Starting in 1.8.0, PyTorch DDP attaches a StreamHandler (NOTSET) + # to the root logger. As logger.propagate is True by default, this root + # level handler causes logging messages from rank>0 processes to + # unexpectedly show up on the console, creating much unwanted clutter. + # To fix this issue, we set the root logger's StreamHandler, if any, to log + # at the ERROR level. + for handler in logger.root.handlers: + if type(handler) is logging.StreamHandler: + handler.setLevel(logging.ERROR) + + stream_handler = logging.StreamHandler() + handlers = [stream_handler] + + if dist.is_available() and dist.is_initialized(): + rank = dist.get_rank() + else: + rank = 0 + + # only rank 0 will add a FileHandler + if rank == 0 and log_file is not None: + # Here, the default behaviour of the official logger is 'a'. Thus, we + # provide an interface to change the file mode to the default + # behaviour. + file_handler = logging.FileHandler(log_file, file_mode) + handlers.append(file_handler) + + formatter = logging.Formatter( + '%(asctime)s - %(name)s - %(levelname)s - %(message)s') + for handler in handlers: + handler.setFormatter(formatter) + handler.setLevel(log_level) + logger.addHandler(handler) + + if rank == 0: + logger.setLevel(log_level) + else: + logger.setLevel(logging.ERROR) + + logger_initialized[name] = True + + return logger + + +def print_log(msg, logger=None, level=logging.INFO): + """Print a log message. + + Args: + msg (str): The message to be logged. + logger (logging.Logger | str | None): The logger to be used. + Some special loggers are: + - "silent": no message will be printed. + - other str: the logger obtained with `get_root_logger(logger)`. + - None: The `print()` method will be used to print log messages. + level (int): Logging level. Only available when `logger` is a Logger + object or "root". + """ + if logger is None: + print(msg) + elif isinstance(logger, logging.Logger): + logger.log(level, msg) + elif logger == 'silent': + pass + elif isinstance(logger, str): + _logger = get_logger(logger) + _logger.log(level, msg) + else: + raise TypeError( + 'logger should be either a logging.Logger object, str, ' + f'"silent" or None, but got {type(logger)}') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/misc.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/misc.py new file mode 100644 index 00000000..2c58d0d7 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/misc.py @@ -0,0 +1,377 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import collections.abc +import functools +import itertools +import subprocess +import warnings +from collections import abc +from importlib import import_module +from inspect import getfullargspec +from itertools import repeat + + +# From PyTorch internals +def _ntuple(n): + + def parse(x): + if isinstance(x, collections.abc.Iterable): + return x + return tuple(repeat(x, n)) + + return parse + + +to_1tuple = _ntuple(1) +to_2tuple = _ntuple(2) +to_3tuple = _ntuple(3) +to_4tuple = _ntuple(4) +to_ntuple = _ntuple + + +def is_str(x): + """Whether the input is an string instance. + + Note: This method is deprecated since python 2 is no longer supported. + """ + return isinstance(x, str) + + +def import_modules_from_strings(imports, allow_failed_imports=False): + """Import modules from the given list of strings. + + Args: + imports (list | str | None): The given module names to be imported. + allow_failed_imports (bool): If True, the failed imports will return + None. Otherwise, an ImportError is raise. Default: False. + + Returns: + list[module] | module | None: The imported modules. + + Examples: + >>> osp, sys = import_modules_from_strings( + ... ['os.path', 'sys']) + >>> import os.path as osp_ + >>> import sys as sys_ + >>> assert osp == osp_ + >>> assert sys == sys_ + """ + if not imports: + return + single_import = False + if isinstance(imports, str): + single_import = True + imports = [imports] + if not isinstance(imports, list): + raise TypeError( + f'custom_imports must be a list but got type {type(imports)}') + imported = [] + for imp in imports: + if not isinstance(imp, str): + raise TypeError( + f'{imp} is of type {type(imp)} and cannot be imported.') + try: + imported_tmp = import_module(imp) + except ImportError: + if allow_failed_imports: + warnings.warn(f'{imp} failed to import and is ignored.', + UserWarning) + imported_tmp = None + else: + raise ImportError + imported.append(imported_tmp) + if single_import: + imported = imported[0] + return imported + + +def iter_cast(inputs, dst_type, return_type=None): + """Cast elements of an iterable object into some type. + + Args: + inputs (Iterable): The input object. + dst_type (type): Destination type. + return_type (type, optional): If specified, the output object will be + converted to this type, otherwise an iterator. + + Returns: + iterator or specified type: The converted object. + """ + if not isinstance(inputs, abc.Iterable): + raise TypeError('inputs must be an iterable object') + if not isinstance(dst_type, type): + raise TypeError('"dst_type" must be a valid type') + + out_iterable = map(dst_type, inputs) + + if return_type is None: + return out_iterable + else: + return return_type(out_iterable) + + +def list_cast(inputs, dst_type): + """Cast elements of an iterable object into a list of some type. + + A partial method of :func:`iter_cast`. + """ + return iter_cast(inputs, dst_type, return_type=list) + + +def tuple_cast(inputs, dst_type): + """Cast elements of an iterable object into a tuple of some type. + + A partial method of :func:`iter_cast`. + """ + return iter_cast(inputs, dst_type, return_type=tuple) + + +def is_seq_of(seq, expected_type, seq_type=None): + """Check whether it is a sequence of some type. + + Args: + seq (Sequence): The sequence to be checked. + expected_type (type): Expected type of sequence items. + seq_type (type, optional): Expected sequence type. + + Returns: + bool: Whether the sequence is valid. + """ + if seq_type is None: + exp_seq_type = abc.Sequence + else: + assert isinstance(seq_type, type) + exp_seq_type = seq_type + if not isinstance(seq, exp_seq_type): + return False + for item in seq: + if not isinstance(item, expected_type): + return False + return True + + +def is_list_of(seq, expected_type): + """Check whether it is a list of some type. + + A partial method of :func:`is_seq_of`. + """ + return is_seq_of(seq, expected_type, seq_type=list) + + +def is_tuple_of(seq, expected_type): + """Check whether it is a tuple of some type. + + A partial method of :func:`is_seq_of`. + """ + return is_seq_of(seq, expected_type, seq_type=tuple) + + +def slice_list(in_list, lens): + """Slice a list into several sub lists by a list of given length. + + Args: + in_list (list): The list to be sliced. + lens(int or list): The expected length of each out list. + + Returns: + list: A list of sliced list. + """ + if isinstance(lens, int): + assert len(in_list) % lens == 0 + lens = [lens] * int(len(in_list) / lens) + if not isinstance(lens, list): + raise TypeError('"indices" must be an integer or a list of integers') + elif sum(lens) != len(in_list): + raise ValueError('sum of lens and list length does not ' + f'match: {sum(lens)} != {len(in_list)}') + out_list = [] + idx = 0 + for i in range(len(lens)): + out_list.append(in_list[idx:idx + lens[i]]) + idx += lens[i] + return out_list + + +def concat_list(in_list): + """Concatenate a list of list into a single list. + + Args: + in_list (list): The list of list to be merged. + + Returns: + list: The concatenated flat list. + """ + return list(itertools.chain(*in_list)) + + +def check_prerequisites( + prerequisites, + checker, + msg_tmpl='Prerequisites "{}" are required in method "{}" but not ' + 'found, please install them first.'): # yapf: disable + """A decorator factory to check if prerequisites are satisfied. + + Args: + prerequisites (str of list[str]): Prerequisites to be checked. + checker (callable): The checker method that returns True if a + prerequisite is meet, False otherwise. + msg_tmpl (str): The message template with two variables. + + Returns: + decorator: A specific decorator. + """ + + def wrap(func): + + @functools.wraps(func) + def wrapped_func(*args, **kwargs): + requirements = [prerequisites] if isinstance( + prerequisites, str) else prerequisites + missing = [] + for item in requirements: + if not checker(item): + missing.append(item) + if missing: + print(msg_tmpl.format(', '.join(missing), func.__name__)) + raise RuntimeError('Prerequisites not meet.') + else: + return func(*args, **kwargs) + + return wrapped_func + + return wrap + + +def _check_py_package(package): + try: + import_module(package) + except ImportError: + return False + else: + return True + + +def _check_executable(cmd): + if subprocess.call(f'which {cmd}', shell=True) != 0: + return False + else: + return True + + +def requires_package(prerequisites): + """A decorator to check if some python packages are installed. + + Example: + >>> @requires_package('numpy') + >>> func(arg1, args): + >>> return numpy.zeros(1) + array([0.]) + >>> @requires_package(['numpy', 'non_package']) + >>> func(arg1, args): + >>> return numpy.zeros(1) + ImportError + """ + return check_prerequisites(prerequisites, checker=_check_py_package) + + +def requires_executable(prerequisites): + """A decorator to check if some executable files are installed. + + Example: + >>> @requires_executable('ffmpeg') + >>> func(arg1, args): + >>> print(1) + 1 + """ + return check_prerequisites(prerequisites, checker=_check_executable) + + +def deprecated_api_warning(name_dict, cls_name=None): + """A decorator to check if some arguments are deprecate and try to replace + deprecate src_arg_name to dst_arg_name. + + Args: + name_dict(dict): + key (str): Deprecate argument names. + val (str): Expected argument names. + + Returns: + func: New function. + """ + + def api_warning_wrapper(old_func): + + @functools.wraps(old_func) + def new_func(*args, **kwargs): + # get the arg spec of the decorated method + args_info = getfullargspec(old_func) + # get name of the function + func_name = old_func.__name__ + if cls_name is not None: + func_name = f'{cls_name}.{func_name}' + if args: + arg_names = args_info.args[:len(args)] + for src_arg_name, dst_arg_name in name_dict.items(): + if src_arg_name in arg_names: + warnings.warn( + f'"{src_arg_name}" is deprecated in ' + f'`{func_name}`, please use "{dst_arg_name}" ' + 'instead') + arg_names[arg_names.index(src_arg_name)] = dst_arg_name + if kwargs: + for src_arg_name, dst_arg_name in name_dict.items(): + if src_arg_name in kwargs: + + assert dst_arg_name not in kwargs, ( + f'The expected behavior is to replace ' + f'the deprecated key `{src_arg_name}` to ' + f'new key `{dst_arg_name}`, but got them ' + f'in the arguments at the same time, which ' + f'is confusing. `{src_arg_name} will be ' + f'deprecated in the future, please ' + f'use `{dst_arg_name}` instead.') + + warnings.warn( + f'"{src_arg_name}" is deprecated in ' + f'`{func_name}`, please use "{dst_arg_name}" ' + 'instead') + kwargs[dst_arg_name] = kwargs.pop(src_arg_name) + + # apply converted arguments to the decorated method + output = old_func(*args, **kwargs) + return output + + return new_func + + return api_warning_wrapper + + +def is_method_overridden(method, base_class, derived_class): + """Check if a method of base class is overridden in derived class. + + Args: + method (str): the method name to check. + base_class (type): the class of the base class. + derived_class (type | Any): the class or instance of the derived class. + """ + assert isinstance(base_class, type), \ + "base_class doesn't accept instance, Please pass class instead." + + if not isinstance(derived_class, type): + derived_class = derived_class.__class__ + + base_method = getattr(base_class, method) + derived_method = getattr(derived_class, method) + return derived_method != base_method + + +def has_method(obj: object, method: str) -> bool: + """Check whether the object has a method. + + Args: + method (str): The method name to check. + obj (object): The object to check. + + Returns: + bool: True if the object has the method else False. + """ + return hasattr(obj, method) and callable(getattr(obj, method)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/parrots_jit.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/parrots_jit.py new file mode 100644 index 00000000..61873f6d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/parrots_jit.py @@ -0,0 +1,41 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os + +from .parrots_wrapper import TORCH_VERSION + +parrots_jit_option = os.getenv('PARROTS_JIT_OPTION') + +if TORCH_VERSION == 'parrots' and parrots_jit_option == 'ON': + from parrots.jit import pat as jit +else: + + def jit(func=None, + check_input=None, + full_shape=True, + derivate=False, + coderize=False, + optimize=False): + + def wrapper(func): + + def wrapper_inner(*args, **kargs): + return func(*args, **kargs) + + return wrapper_inner + + if func is None: + return wrapper + else: + return func + + +if TORCH_VERSION == 'parrots': + from parrots.utils.tester import skip_no_elena +else: + + def skip_no_elena(func): + + def wrapper(*args, **kargs): + return func(*args, **kargs) + + return wrapper diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/parrots_wrapper.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/parrots_wrapper.py new file mode 100644 index 00000000..93c97640 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/parrots_wrapper.py @@ -0,0 +1,107 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from functools import partial + +import torch + +TORCH_VERSION = torch.__version__ + + +def is_rocm_pytorch() -> bool: + is_rocm = False + if TORCH_VERSION != 'parrots': + try: + from torch.utils.cpp_extension import ROCM_HOME + is_rocm = True if ((torch.version.hip is not None) and + (ROCM_HOME is not None)) else False + except ImportError: + pass + return is_rocm + + +def _get_cuda_home(): + if TORCH_VERSION == 'parrots': + from parrots.utils.build_extension import CUDA_HOME + else: + if is_rocm_pytorch(): + from torch.utils.cpp_extension import ROCM_HOME + CUDA_HOME = ROCM_HOME + else: + from torch.utils.cpp_extension import CUDA_HOME + return CUDA_HOME + + +def get_build_config(): + if TORCH_VERSION == 'parrots': + from parrots.config import get_build_info + return get_build_info() + else: + return torch.__config__.show() + + +def _get_conv(): + if TORCH_VERSION == 'parrots': + from parrots.nn.modules.conv import _ConvNd, _ConvTransposeMixin + else: + from torch.nn.modules.conv import _ConvNd, _ConvTransposeMixin + return _ConvNd, _ConvTransposeMixin + + +def _get_dataloader(): + if TORCH_VERSION == 'parrots': + from torch.utils.data import DataLoader, PoolDataLoader + else: + from torch.utils.data import DataLoader + PoolDataLoader = DataLoader + return DataLoader, PoolDataLoader + + +def _get_extension(): + if TORCH_VERSION == 'parrots': + from parrots.utils.build_extension import BuildExtension, Extension + CppExtension = partial(Extension, cuda=False) + CUDAExtension = partial(Extension, cuda=True) + else: + from torch.utils.cpp_extension import (BuildExtension, CppExtension, + CUDAExtension) + return BuildExtension, CppExtension, CUDAExtension + + +def _get_pool(): + if TORCH_VERSION == 'parrots': + from parrots.nn.modules.pool import (_AdaptiveAvgPoolNd, + _AdaptiveMaxPoolNd, _AvgPoolNd, + _MaxPoolNd) + else: + from torch.nn.modules.pooling import (_AdaptiveAvgPoolNd, + _AdaptiveMaxPoolNd, _AvgPoolNd, + _MaxPoolNd) + return _AdaptiveAvgPoolNd, _AdaptiveMaxPoolNd, _AvgPoolNd, _MaxPoolNd + + +def _get_norm(): + if TORCH_VERSION == 'parrots': + from parrots.nn.modules.batchnorm import _BatchNorm, _InstanceNorm + SyncBatchNorm_ = torch.nn.SyncBatchNorm2d + else: + from torch.nn.modules.instancenorm import _InstanceNorm + from torch.nn.modules.batchnorm import _BatchNorm + SyncBatchNorm_ = torch.nn.SyncBatchNorm + return _BatchNorm, _InstanceNorm, SyncBatchNorm_ + + +_ConvNd, _ConvTransposeMixin = _get_conv() +DataLoader, PoolDataLoader = _get_dataloader() +BuildExtension, CppExtension, CUDAExtension = _get_extension() +_BatchNorm, _InstanceNorm, SyncBatchNorm_ = _get_norm() +_AdaptiveAvgPoolNd, _AdaptiveMaxPoolNd, _AvgPoolNd, _MaxPoolNd = _get_pool() + + +class SyncBatchNorm(SyncBatchNorm_): + + def _check_input_dim(self, input): + if TORCH_VERSION == 'parrots': + if input.dim() < 2: + raise ValueError( + f'expected at least 2D input (got {input.dim()}D input)') + else: + super()._check_input_dim(input) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/path.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/path.py new file mode 100644 index 00000000..7dab4b30 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/path.py @@ -0,0 +1,101 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os +import os.path as osp +from pathlib import Path + +from .misc import is_str + + +def is_filepath(x): + return is_str(x) or isinstance(x, Path) + + +def fopen(filepath, *args, **kwargs): + if is_str(filepath): + return open(filepath, *args, **kwargs) + elif isinstance(filepath, Path): + return filepath.open(*args, **kwargs) + raise ValueError('`filepath` should be a string or a Path') + + +def check_file_exist(filename, msg_tmpl='file "{}" does not exist'): + if not osp.isfile(filename): + raise FileNotFoundError(msg_tmpl.format(filename)) + + +def mkdir_or_exist(dir_name, mode=0o777): + if dir_name == '': + return + dir_name = osp.expanduser(dir_name) + os.makedirs(dir_name, mode=mode, exist_ok=True) + + +def symlink(src, dst, overwrite=True, **kwargs): + if os.path.lexists(dst) and overwrite: + os.remove(dst) + os.symlink(src, dst, **kwargs) + + +def scandir(dir_path, suffix=None, recursive=False, case_sensitive=True): + """Scan a directory to find the interested files. + + Args: + dir_path (str | obj:`Path`): Path of the directory. + suffix (str | tuple(str), optional): File suffix that we are + interested in. Default: None. + recursive (bool, optional): If set to True, recursively scan the + directory. Default: False. + case_sensitive (bool, optional) : If set to False, ignore the case of + suffix. Default: True. + + Returns: + A generator for all the interested files with relative paths. + """ + if isinstance(dir_path, (str, Path)): + dir_path = str(dir_path) + else: + raise TypeError('"dir_path" must be a string or Path object') + + if (suffix is not None) and not isinstance(suffix, (str, tuple)): + raise TypeError('"suffix" must be a string or tuple of strings') + + if suffix is not None and not case_sensitive: + suffix = suffix.lower() if isinstance(suffix, str) else tuple( + item.lower() for item in suffix) + + root = dir_path + + def _scandir(dir_path, suffix, recursive, case_sensitive): + for entry in os.scandir(dir_path): + if not entry.name.startswith('.') and entry.is_file(): + rel_path = osp.relpath(entry.path, root) + _rel_path = rel_path if case_sensitive else rel_path.lower() + if suffix is None or _rel_path.endswith(suffix): + yield rel_path + elif recursive and os.path.isdir(entry.path): + # scan recursively if entry.path is a directory + yield from _scandir(entry.path, suffix, recursive, + case_sensitive) + + return _scandir(dir_path, suffix, recursive, case_sensitive) + + +def find_vcs_root(path, markers=('.git', )): + """Finds the root directory (including itself) of specified markers. + + Args: + path (str): Path of directory or file. + markers (list[str], optional): List of file or directory names. + + Returns: + The directory contained one of the markers or None if not found. + """ + if osp.isfile(path): + path = osp.dirname(path) + + prev, cur = None, osp.abspath(osp.expanduser(path)) + while cur != prev: + if any(osp.exists(osp.join(cur, marker)) for marker in markers): + return cur + prev, cur = cur, osp.split(cur)[0] + return None diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/progressbar.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/progressbar.py new file mode 100644 index 00000000..0062f670 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/progressbar.py @@ -0,0 +1,208 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import sys +from collections.abc import Iterable +from multiprocessing import Pool +from shutil import get_terminal_size + +from .timer import Timer + + +class ProgressBar: + """A progress bar which can print the progress.""" + + def __init__(self, task_num=0, bar_width=50, start=True, file=sys.stdout): + self.task_num = task_num + self.bar_width = bar_width + self.completed = 0 + self.file = file + if start: + self.start() + + @property + def terminal_width(self): + width, _ = get_terminal_size() + return width + + def start(self): + if self.task_num > 0: + self.file.write(f'[{" " * self.bar_width}] 0/{self.task_num}, ' + 'elapsed: 0s, ETA:') + else: + self.file.write('completed: 0, elapsed: 0s') + self.file.flush() + self.timer = Timer() + + def update(self, num_tasks=1): + assert num_tasks > 0 + self.completed += num_tasks + elapsed = self.timer.since_start() + if elapsed > 0: + fps = self.completed / elapsed + else: + fps = float('inf') + if self.task_num > 0: + percentage = self.completed / float(self.task_num) + eta = int(elapsed * (1 - percentage) / percentage + 0.5) + msg = f'\r[{{}}] {self.completed}/{self.task_num}, ' \ + f'{fps:.1f} task/s, elapsed: {int(elapsed + 0.5)}s, ' \ + f'ETA: {eta:5}s' + + bar_width = min(self.bar_width, + int(self.terminal_width - len(msg)) + 2, + int(self.terminal_width * 0.6)) + bar_width = max(2, bar_width) + mark_width = int(bar_width * percentage) + bar_chars = '>' * mark_width + ' ' * (bar_width - mark_width) + self.file.write(msg.format(bar_chars)) + else: + self.file.write( + f'completed: {self.completed}, elapsed: {int(elapsed + 0.5)}s,' + f' {fps:.1f} tasks/s') + self.file.flush() + + +def track_progress(func, tasks, bar_width=50, file=sys.stdout, **kwargs): + """Track the progress of tasks execution with a progress bar. + + Tasks are done with a simple for-loop. + + Args: + func (callable): The function to be applied to each task. + tasks (list or tuple[Iterable, int]): A list of tasks or + (tasks, total num). + bar_width (int): Width of progress bar. + + Returns: + list: The task results. + """ + if isinstance(tasks, tuple): + assert len(tasks) == 2 + assert isinstance(tasks[0], Iterable) + assert isinstance(tasks[1], int) + task_num = tasks[1] + tasks = tasks[0] + elif isinstance(tasks, Iterable): + task_num = len(tasks) + else: + raise TypeError( + '"tasks" must be an iterable object or a (iterator, int) tuple') + prog_bar = ProgressBar(task_num, bar_width, file=file) + results = [] + for task in tasks: + results.append(func(task, **kwargs)) + prog_bar.update() + prog_bar.file.write('\n') + return results + + +def init_pool(process_num, initializer=None, initargs=None): + if initializer is None: + return Pool(process_num) + elif initargs is None: + return Pool(process_num, initializer) + else: + if not isinstance(initargs, tuple): + raise TypeError('"initargs" must be a tuple') + return Pool(process_num, initializer, initargs) + + +def track_parallel_progress(func, + tasks, + nproc, + initializer=None, + initargs=None, + bar_width=50, + chunksize=1, + skip_first=False, + keep_order=True, + file=sys.stdout): + """Track the progress of parallel task execution with a progress bar. + + The built-in :mod:`multiprocessing` module is used for process pools and + tasks are done with :func:`Pool.map` or :func:`Pool.imap_unordered`. + + Args: + func (callable): The function to be applied to each task. + tasks (list or tuple[Iterable, int]): A list of tasks or + (tasks, total num). + nproc (int): Process (worker) number. + initializer (None or callable): Refer to :class:`multiprocessing.Pool` + for details. + initargs (None or tuple): Refer to :class:`multiprocessing.Pool` for + details. + chunksize (int): Refer to :class:`multiprocessing.Pool` for details. + bar_width (int): Width of progress bar. + skip_first (bool): Whether to skip the first sample for each worker + when estimating fps, since the initialization step may takes + longer. + keep_order (bool): If True, :func:`Pool.imap` is used, otherwise + :func:`Pool.imap_unordered` is used. + + Returns: + list: The task results. + """ + if isinstance(tasks, tuple): + assert len(tasks) == 2 + assert isinstance(tasks[0], Iterable) + assert isinstance(tasks[1], int) + task_num = tasks[1] + tasks = tasks[0] + elif isinstance(tasks, Iterable): + task_num = len(tasks) + else: + raise TypeError( + '"tasks" must be an iterable object or a (iterator, int) tuple') + pool = init_pool(nproc, initializer, initargs) + start = not skip_first + task_num -= nproc * chunksize * int(skip_first) + prog_bar = ProgressBar(task_num, bar_width, start, file=file) + results = [] + if keep_order: + gen = pool.imap(func, tasks, chunksize) + else: + gen = pool.imap_unordered(func, tasks, chunksize) + for result in gen: + results.append(result) + if skip_first: + if len(results) < nproc * chunksize: + continue + elif len(results) == nproc * chunksize: + prog_bar.start() + continue + prog_bar.update() + prog_bar.file.write('\n') + pool.close() + pool.join() + return results + + +def track_iter_progress(tasks, bar_width=50, file=sys.stdout): + """Track the progress of tasks iteration or enumeration with a progress + bar. + + Tasks are yielded with a simple for-loop. + + Args: + tasks (list or tuple[Iterable, int]): A list of tasks or + (tasks, total num). + bar_width (int): Width of progress bar. + + Yields: + list: The task results. + """ + if isinstance(tasks, tuple): + assert len(tasks) == 2 + assert isinstance(tasks[0], Iterable) + assert isinstance(tasks[1], int) + task_num = tasks[1] + tasks = tasks[0] + elif isinstance(tasks, Iterable): + task_num = len(tasks) + else: + raise TypeError( + '"tasks" must be an iterable object or a (iterator, int) tuple') + prog_bar = ProgressBar(task_num, bar_width, file=file) + for task in tasks: + yield task + prog_bar.update() + prog_bar.file.write('\n') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/registry.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/registry.py new file mode 100644 index 00000000..fa9df39b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/registry.py @@ -0,0 +1,315 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import inspect +import warnings +from functools import partial + +from .misc import is_seq_of + + +def build_from_cfg(cfg, registry, default_args=None): + """Build a module from config dict. + + Args: + cfg (dict): Config dict. It should at least contain the key "type". + registry (:obj:`Registry`): The registry to search the type from. + default_args (dict, optional): Default initialization arguments. + + Returns: + object: The constructed object. + """ + if not isinstance(cfg, dict): + raise TypeError(f'cfg must be a dict, but got {type(cfg)}') + if 'type' not in cfg: + if default_args is None or 'type' not in default_args: + raise KeyError( + '`cfg` or `default_args` must contain the key "type", ' + f'but got {cfg}\n{default_args}') + if not isinstance(registry, Registry): + raise TypeError('registry must be an mmcv.Registry object, ' + f'but got {type(registry)}') + if not (isinstance(default_args, dict) or default_args is None): + raise TypeError('default_args must be a dict or None, ' + f'but got {type(default_args)}') + + args = cfg.copy() + + if default_args is not None: + for name, value in default_args.items(): + args.setdefault(name, value) + + obj_type = args.pop('type') + if isinstance(obj_type, str): + obj_cls = registry.get(obj_type) + if obj_cls is None: + raise KeyError( + f'{obj_type} is not in the {registry.name} registry') + elif inspect.isclass(obj_type): + obj_cls = obj_type + else: + raise TypeError( + f'type must be a str or valid type, but got {type(obj_type)}') + try: + return obj_cls(**args) + except Exception as e: + # Normal TypeError does not print class name. + raise type(e)(f'{obj_cls.__name__}: {e}') + + +class Registry: + """A registry to map strings to classes. + + Registered object could be built from registry. + Example: + >>> MODELS = Registry('models') + >>> @MODELS.register_module() + >>> class ResNet: + >>> pass + >>> resnet = MODELS.build(dict(type='ResNet')) + + Please refer to + https://mmcv.readthedocs.io/en/latest/understand_mmcv/registry.html for + advanced usage. + + Args: + name (str): Registry name. + build_func(func, optional): Build function to construct instance from + Registry, func:`build_from_cfg` is used if neither ``parent`` or + ``build_func`` is specified. If ``parent`` is specified and + ``build_func`` is not given, ``build_func`` will be inherited + from ``parent``. Default: None. + parent (Registry, optional): Parent registry. The class registered in + children registry could be built from parent. Default: None. + scope (str, optional): The scope of registry. It is the key to search + for children registry. If not specified, scope will be the name of + the package where class is defined, e.g. mmdet, mmcls, mmseg. + Default: None. + """ + + def __init__(self, name, build_func=None, parent=None, scope=None): + self._name = name + self._module_dict = dict() + self._children = dict() + self._scope = self.infer_scope() if scope is None else scope + + # self.build_func will be set with the following priority: + # 1. build_func + # 2. parent.build_func + # 3. build_from_cfg + if build_func is None: + if parent is not None: + self.build_func = parent.build_func + else: + self.build_func = build_from_cfg + else: + self.build_func = build_func + if parent is not None: + assert isinstance(parent, Registry) + parent._add_children(self) + self.parent = parent + else: + self.parent = None + + def __len__(self): + return len(self._module_dict) + + def __contains__(self, key): + return self.get(key) is not None + + def __repr__(self): + format_str = self.__class__.__name__ + \ + f'(name={self._name}, ' \ + f'items={self._module_dict})' + return format_str + + @staticmethod + def infer_scope(): + """Infer the scope of registry. + + The name of the package where registry is defined will be returned. + + Example: + # in mmdet/models/backbone/resnet.py + >>> MODELS = Registry('models') + >>> @MODELS.register_module() + >>> class ResNet: + >>> pass + The scope of ``ResNet`` will be ``mmdet``. + + + Returns: + scope (str): The inferred scope name. + """ + # inspect.stack() trace where this function is called, the index-2 + # indicates the frame where `infer_scope()` is called + filename = inspect.getmodule(inspect.stack()[2][0]).__name__ + split_filename = filename.split('.') + return split_filename[0] + + @staticmethod + def split_scope_key(key): + """Split scope and key. + + The first scope will be split from key. + + Examples: + >>> Registry.split_scope_key('mmdet.ResNet') + 'mmdet', 'ResNet' + >>> Registry.split_scope_key('ResNet') + None, 'ResNet' + + Return: + scope (str, None): The first scope. + key (str): The remaining key. + """ + split_index = key.find('.') + if split_index != -1: + return key[:split_index], key[split_index + 1:] + else: + return None, key + + @property + def name(self): + return self._name + + @property + def scope(self): + return self._scope + + @property + def module_dict(self): + return self._module_dict + + @property + def children(self): + return self._children + + def get(self, key): + """Get the registry record. + + Args: + key (str): The class name in string format. + + Returns: + class: The corresponding class. + """ + scope, real_key = self.split_scope_key(key) + if scope is None or scope == self._scope: + # get from self + if real_key in self._module_dict: + return self._module_dict[real_key] + else: + # get from self._children + if scope in self._children: + return self._children[scope].get(real_key) + else: + # goto root + parent = self.parent + while parent.parent is not None: + parent = parent.parent + return parent.get(key) + + def build(self, *args, **kwargs): + return self.build_func(*args, **kwargs, registry=self) + + def _add_children(self, registry): + """Add children for a registry. + + The ``registry`` will be added as children based on its scope. + The parent registry could build objects from children registry. + + Example: + >>> models = Registry('models') + >>> mmdet_models = Registry('models', parent=models) + >>> @mmdet_models.register_module() + >>> class ResNet: + >>> pass + >>> resnet = models.build(dict(type='mmdet.ResNet')) + """ + + assert isinstance(registry, Registry) + assert registry.scope is not None + assert registry.scope not in self.children, \ + f'scope {registry.scope} exists in {self.name} registry' + self.children[registry.scope] = registry + + def _register_module(self, module_class, module_name=None, force=False): + if not inspect.isclass(module_class): + raise TypeError('module must be a class, ' + f'but got {type(module_class)}') + + if module_name is None: + module_name = module_class.__name__ + if isinstance(module_name, str): + module_name = [module_name] + for name in module_name: + if not force and name in self._module_dict: + raise KeyError(f'{name} is already registered ' + f'in {self.name}') + self._module_dict[name] = module_class + + def deprecated_register_module(self, cls=None, force=False): + warnings.warn( + 'The old API of register_module(module, force=False) ' + 'is deprecated and will be removed, please use the new API ' + 'register_module(name=None, force=False, module=None) instead.') + if cls is None: + return partial(self.deprecated_register_module, force=force) + self._register_module(cls, force=force) + return cls + + def register_module(self, name=None, force=False, module=None): + """Register a module. + + A record will be added to `self._module_dict`, whose key is the class + name or the specified name, and value is the class itself. + It can be used as a decorator or a normal function. + + Example: + >>> backbones = Registry('backbone') + >>> @backbones.register_module() + >>> class ResNet: + >>> pass + + >>> backbones = Registry('backbone') + >>> @backbones.register_module(name='mnet') + >>> class MobileNet: + >>> pass + + >>> backbones = Registry('backbone') + >>> class ResNet: + >>> pass + >>> backbones.register_module(ResNet) + + Args: + name (str | None): The module name to be registered. If not + specified, the class name will be used. + force (bool, optional): Whether to override an existing class with + the same name. Default: False. + module (type): Module class to be registered. + """ + if not isinstance(force, bool): + raise TypeError(f'force must be a boolean, but got {type(force)}') + # NOTE: This is a walkaround to be compatible with the old api, + # while it may introduce unexpected bugs. + if isinstance(name, type): + return self.deprecated_register_module(name, force=force) + + # raise the error ahead of time + if not (name is None or isinstance(name, str) or is_seq_of(name, str)): + raise TypeError( + 'name must be either of None, an instance of str or a sequence' + f' of str, but got {type(name)}') + + # use it as a normal method: x.register_module(module=SomeClass) + if module is not None: + self._register_module( + module_class=module, module_name=name, force=force) + return module + + # use it as a decorator: @x.register_module() + def _register(cls): + self._register_module( + module_class=cls, module_name=name, force=force) + return cls + + return _register diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/testing.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/testing.py new file mode 100644 index 00000000..a27f936d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/testing.py @@ -0,0 +1,140 @@ +# Copyright (c) Open-MMLab. +import sys +from collections.abc import Iterable +from runpy import run_path +from shlex import split +from typing import Any, Dict, List +from unittest.mock import patch + + +def check_python_script(cmd): + """Run the python cmd script with `__main__`. The difference between + `os.system` is that, this function exectues code in the current process, so + that it can be tracked by coverage tools. Currently it supports two forms: + + - ./tests/data/scripts/hello.py zz + - python tests/data/scripts/hello.py zz + """ + args = split(cmd) + if args[0] == 'python': + args = args[1:] + with patch.object(sys, 'argv', args): + run_path(args[0], run_name='__main__') + + +def _any(judge_result): + """Since built-in ``any`` works only when the element of iterable is not + iterable, implement the function.""" + if not isinstance(judge_result, Iterable): + return judge_result + + try: + for element in judge_result: + if _any(element): + return True + except TypeError: + # Maybe encounter the case: torch.tensor(True) | torch.tensor(False) + if judge_result: + return True + return False + + +def assert_dict_contains_subset(dict_obj: Dict[Any, Any], + expected_subset: Dict[Any, Any]) -> bool: + """Check if the dict_obj contains the expected_subset. + + Args: + dict_obj (Dict[Any, Any]): Dict object to be checked. + expected_subset (Dict[Any, Any]): Subset expected to be contained in + dict_obj. + + Returns: + bool: Whether the dict_obj contains the expected_subset. + """ + + for key, value in expected_subset.items(): + if key not in dict_obj.keys() or _any(dict_obj[key] != value): + return False + return True + + +def assert_attrs_equal(obj: Any, expected_attrs: Dict[str, Any]) -> bool: + """Check if attribute of class object is correct. + + Args: + obj (object): Class object to be checked. + expected_attrs (Dict[str, Any]): Dict of the expected attrs. + + Returns: + bool: Whether the attribute of class object is correct. + """ + for attr, value in expected_attrs.items(): + if not hasattr(obj, attr) or _any(getattr(obj, attr) != value): + return False + return True + + +def assert_dict_has_keys(obj: Dict[str, Any], + expected_keys: List[str]) -> bool: + """Check if the obj has all the expected_keys. + + Args: + obj (Dict[str, Any]): Object to be checked. + expected_keys (List[str]): Keys expected to contained in the keys of + the obj. + + Returns: + bool: Whether the obj has the expected keys. + """ + return set(expected_keys).issubset(set(obj.keys())) + + +def assert_keys_equal(result_keys: List[str], target_keys: List[str]) -> bool: + """Check if target_keys is equal to result_keys. + + Args: + result_keys (List[str]): Result keys to be checked. + target_keys (List[str]): Target keys to be checked. + + Returns: + bool: Whether target_keys is equal to result_keys. + """ + return set(result_keys) == set(target_keys) + + +def assert_is_norm_layer(module) -> bool: + """Check if the module is a norm layer. + + Args: + module (nn.Module): The module to be checked. + + Returns: + bool: Whether the module is a norm layer. + """ + from .parrots_wrapper import _BatchNorm, _InstanceNorm + from torch.nn import GroupNorm, LayerNorm + norm_layer_candidates = (_BatchNorm, _InstanceNorm, GroupNorm, LayerNorm) + return isinstance(module, norm_layer_candidates) + + +def assert_params_all_zeros(module) -> bool: + """Check if the parameters of the module is all zeros. + + Args: + module (nn.Module): The module to be checked. + + Returns: + bool: Whether the parameters of the module is all zeros. + """ + weight_data = module.weight.data + is_weight_zero = weight_data.allclose( + weight_data.new_zeros(weight_data.size())) + + if hasattr(module, 'bias') and module.bias is not None: + bias_data = module.bias.data + is_bias_zero = bias_data.allclose( + bias_data.new_zeros(bias_data.size())) + else: + is_bias_zero = True + + return is_weight_zero and is_bias_zero diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/timer.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/timer.py new file mode 100644 index 00000000..0435c125 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/timer.py @@ -0,0 +1,118 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from time import time + + +class TimerError(Exception): + + def __init__(self, message): + self.message = message + super(TimerError, self).__init__(message) + + +class Timer: + """A flexible Timer class. + + :Example: + + >>> import time + >>> import annotator.mmpkg.mmcv as mmcv + >>> with mmcv.Timer(): + >>> # simulate a code block that will run for 1s + >>> time.sleep(1) + 1.000 + >>> with mmcv.Timer(print_tmpl='it takes {:.1f} seconds'): + >>> # simulate a code block that will run for 1s + >>> time.sleep(1) + it takes 1.0 seconds + >>> timer = mmcv.Timer() + >>> time.sleep(0.5) + >>> print(timer.since_start()) + 0.500 + >>> time.sleep(0.5) + >>> print(timer.since_last_check()) + 0.500 + >>> print(timer.since_start()) + 1.000 + """ + + def __init__(self, start=True, print_tmpl=None): + self._is_running = False + self.print_tmpl = print_tmpl if print_tmpl else '{:.3f}' + if start: + self.start() + + @property + def is_running(self): + """bool: indicate whether the timer is running""" + return self._is_running + + def __enter__(self): + self.start() + return self + + def __exit__(self, type, value, traceback): + print(self.print_tmpl.format(self.since_last_check())) + self._is_running = False + + def start(self): + """Start the timer.""" + if not self._is_running: + self._t_start = time() + self._is_running = True + self._t_last = time() + + def since_start(self): + """Total time since the timer is started. + + Returns (float): Time in seconds. + """ + if not self._is_running: + raise TimerError('timer is not running') + self._t_last = time() + return self._t_last - self._t_start + + def since_last_check(self): + """Time since the last checking. + + Either :func:`since_start` or :func:`since_last_check` is a checking + operation. + + Returns (float): Time in seconds. + """ + if not self._is_running: + raise TimerError('timer is not running') + dur = time() - self._t_last + self._t_last = time() + return dur + + +_g_timers = {} # global timers + + +def check_time(timer_id): + """Add check points in a single line. + + This method is suitable for running a task on a list of items. A timer will + be registered when the method is called for the first time. + + :Example: + + >>> import time + >>> import annotator.mmpkg.mmcv as mmcv + >>> for i in range(1, 6): + >>> # simulate a code block + >>> time.sleep(i) + >>> mmcv.check_time('task1') + 2.000 + 3.000 + 4.000 + 5.000 + + Args: + timer_id (str): Timer identifier. + """ + if timer_id not in _g_timers: + _g_timers[timer_id] = Timer() + return 0 + else: + return _g_timers[timer_id].since_last_check() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/trace.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/trace.py new file mode 100644 index 00000000..51f6e3ca --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/trace.py @@ -0,0 +1,23 @@ +import warnings + +import torch + +from annotator.mmpkg.mmcv.utils import digit_version + + +def is_jit_tracing() -> bool: + if (torch.__version__ != 'parrots' + and digit_version(torch.__version__) >= digit_version('1.6.0')): + on_trace = torch.jit.is_tracing() + # In PyTorch 1.6, torch.jit.is_tracing has a bug. + # Refers to https://github.com/pytorch/pytorch/issues/42448 + if isinstance(on_trace, bool): + return on_trace + else: + return torch._C._is_tracing() + else: + warnings.warn( + 'torch.jit.is_tracing is only supported after v1.6.0. ' + 'Therefore is_tracing returns False automatically. Please ' + 'set on_trace manually if you are using trace.', UserWarning) + return False diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/version_utils.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/version_utils.py new file mode 100644 index 00000000..963c45a2 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/utils/version_utils.py @@ -0,0 +1,90 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os +import subprocess +import warnings + +from packaging.version import parse + + +def digit_version(version_str: str, length: int = 4): + """Convert a version string into a tuple of integers. + + This method is usually used for comparing two versions. For pre-release + versions: alpha < beta < rc. + + Args: + version_str (str): The version string. + length (int): The maximum number of version levels. Default: 4. + + Returns: + tuple[int]: The version info in digits (integers). + """ + assert 'parrots' not in version_str + version = parse(version_str) + assert version.release, f'failed to parse version {version_str}' + release = list(version.release) + release = release[:length] + if len(release) < length: + release = release + [0] * (length - len(release)) + if version.is_prerelease: + mapping = {'a': -3, 'b': -2, 'rc': -1} + val = -4 + # version.pre can be None + if version.pre: + if version.pre[0] not in mapping: + warnings.warn(f'unknown prerelease version {version.pre[0]}, ' + 'version checking may go wrong') + else: + val = mapping[version.pre[0]] + release.extend([val, version.pre[-1]]) + else: + release.extend([val, 0]) + + elif version.is_postrelease: + release.extend([1, version.post]) + else: + release.extend([0, 0]) + return tuple(release) + + +def _minimal_ext_cmd(cmd): + # construct minimal environment + env = {} + for k in ['SYSTEMROOT', 'PATH', 'HOME']: + v = os.environ.get(k) + if v is not None: + env[k] = v + # LANGUAGE is used on win32 + env['LANGUAGE'] = 'C' + env['LANG'] = 'C' + env['LC_ALL'] = 'C' + out = subprocess.Popen( + cmd, stdout=subprocess.PIPE, env=env).communicate()[0] + return out + + +def get_git_hash(fallback='unknown', digits=None): + """Get the git hash of the current repo. + + Args: + fallback (str, optional): The fallback string when git hash is + unavailable. Defaults to 'unknown'. + digits (int, optional): kept digits of the hash. Defaults to None, + meaning all digits are kept. + + Returns: + str: Git commit hash. + """ + + if digits is not None and not isinstance(digits, int): + raise TypeError('digits must be None or an integer') + + try: + out = _minimal_ext_cmd(['git', 'rev-parse', 'HEAD']) + sha = out.strip().decode('ascii') + if digits is not None: + sha = sha[:digits] + except OSError: + sha = fallback + + return sha diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/version.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/version.py new file mode 100644 index 00000000..1cce4e50 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/version.py @@ -0,0 +1,35 @@ +# Copyright (c) OpenMMLab. All rights reserved. +__version__ = '1.3.17' + + +def parse_version_info(version_str: str, length: int = 4) -> tuple: + """Parse a version string into a tuple. + + Args: + version_str (str): The version string. + length (int): The maximum number of version levels. Default: 4. + + Returns: + tuple[int | str]: The version info, e.g., "1.3.0" is parsed into + (1, 3, 0, 0, 0, 0), and "2.0.0rc1" is parsed into + (2, 0, 0, 0, 'rc', 1) (when length is set to 4). + """ + from packaging.version import parse + version = parse(version_str) + assert version.release, f'failed to parse version {version_str}' + release = list(version.release) + release = release[:length] + if len(release) < length: + release = release + [0] * (length - len(release)) + if version.is_prerelease: + release.extend(list(version.pre)) + elif version.is_postrelease: + release.extend(list(version.post)) + else: + release.extend([0, 0]) + return tuple(release) + + +version_info = tuple(int(x) for x in __version__.split('.')[:3]) + +__all__ = ['__version__', 'version_info', 'parse_version_info'] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/video/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/video/__init__.py new file mode 100644 index 00000000..73199b01 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/video/__init__.py @@ -0,0 +1,11 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .io import Cache, VideoReader, frames2video +from .optflow import (dequantize_flow, flow_from_bytes, flow_warp, flowread, + flowwrite, quantize_flow, sparse_flow_from_bytes) +from .processing import concat_video, convert_video, cut_video, resize_video + +__all__ = [ + 'Cache', 'VideoReader', 'frames2video', 'convert_video', 'resize_video', + 'cut_video', 'concat_video', 'flowread', 'flowwrite', 'quantize_flow', + 'dequantize_flow', 'flow_warp', 'flow_from_bytes', 'sparse_flow_from_bytes' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/video/io.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/video/io.py new file mode 100644 index 00000000..06ae9b8a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/video/io.py @@ -0,0 +1,318 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os.path as osp +from collections import OrderedDict + +import cv2 +from cv2 import (CAP_PROP_FOURCC, CAP_PROP_FPS, CAP_PROP_FRAME_COUNT, + CAP_PROP_FRAME_HEIGHT, CAP_PROP_FRAME_WIDTH, + CAP_PROP_POS_FRAMES, VideoWriter_fourcc) + +from annotator.mmpkg.mmcv.utils import (check_file_exist, mkdir_or_exist, scandir, + track_progress) + + +class Cache: + + def __init__(self, capacity): + self._cache = OrderedDict() + self._capacity = int(capacity) + if capacity <= 0: + raise ValueError('capacity must be a positive integer') + + @property + def capacity(self): + return self._capacity + + @property + def size(self): + return len(self._cache) + + def put(self, key, val): + if key in self._cache: + return + if len(self._cache) >= self.capacity: + self._cache.popitem(last=False) + self._cache[key] = val + + def get(self, key, default=None): + val = self._cache[key] if key in self._cache else default + return val + + +class VideoReader: + """Video class with similar usage to a list object. + + This video warpper class provides convenient apis to access frames. + There exists an issue of OpenCV's VideoCapture class that jumping to a + certain frame may be inaccurate. It is fixed in this class by checking + the position after jumping each time. + Cache is used when decoding videos. So if the same frame is visited for + the second time, there is no need to decode again if it is stored in the + cache. + + :Example: + + >>> import annotator.mmpkg.mmcv as mmcv + >>> v = mmcv.VideoReader('sample.mp4') + >>> len(v) # get the total frame number with `len()` + 120 + >>> for img in v: # v is iterable + >>> mmcv.imshow(img) + >>> v[5] # get the 6th frame + """ + + def __init__(self, filename, cache_capacity=10): + # Check whether the video path is a url + if not filename.startswith(('https://', 'http://')): + check_file_exist(filename, 'Video file not found: ' + filename) + self._vcap = cv2.VideoCapture(filename) + assert cache_capacity > 0 + self._cache = Cache(cache_capacity) + self._position = 0 + # get basic info + self._width = int(self._vcap.get(CAP_PROP_FRAME_WIDTH)) + self._height = int(self._vcap.get(CAP_PROP_FRAME_HEIGHT)) + self._fps = self._vcap.get(CAP_PROP_FPS) + self._frame_cnt = int(self._vcap.get(CAP_PROP_FRAME_COUNT)) + self._fourcc = self._vcap.get(CAP_PROP_FOURCC) + + @property + def vcap(self): + """:obj:`cv2.VideoCapture`: The raw VideoCapture object.""" + return self._vcap + + @property + def opened(self): + """bool: Indicate whether the video is opened.""" + return self._vcap.isOpened() + + @property + def width(self): + """int: Width of video frames.""" + return self._width + + @property + def height(self): + """int: Height of video frames.""" + return self._height + + @property + def resolution(self): + """tuple: Video resolution (width, height).""" + return (self._width, self._height) + + @property + def fps(self): + """float: FPS of the video.""" + return self._fps + + @property + def frame_cnt(self): + """int: Total frames of the video.""" + return self._frame_cnt + + @property + def fourcc(self): + """str: "Four character code" of the video.""" + return self._fourcc + + @property + def position(self): + """int: Current cursor position, indicating frame decoded.""" + return self._position + + def _get_real_position(self): + return int(round(self._vcap.get(CAP_PROP_POS_FRAMES))) + + def _set_real_position(self, frame_id): + self._vcap.set(CAP_PROP_POS_FRAMES, frame_id) + pos = self._get_real_position() + for _ in range(frame_id - pos): + self._vcap.read() + self._position = frame_id + + def read(self): + """Read the next frame. + + If the next frame have been decoded before and in the cache, then + return it directly, otherwise decode, cache and return it. + + Returns: + ndarray or None: Return the frame if successful, otherwise None. + """ + # pos = self._position + if self._cache: + img = self._cache.get(self._position) + if img is not None: + ret = True + else: + if self._position != self._get_real_position(): + self._set_real_position(self._position) + ret, img = self._vcap.read() + if ret: + self._cache.put(self._position, img) + else: + ret, img = self._vcap.read() + if ret: + self._position += 1 + return img + + def get_frame(self, frame_id): + """Get frame by index. + + Args: + frame_id (int): Index of the expected frame, 0-based. + + Returns: + ndarray or None: Return the frame if successful, otherwise None. + """ + if frame_id < 0 or frame_id >= self._frame_cnt: + raise IndexError( + f'"frame_id" must be between 0 and {self._frame_cnt - 1}') + if frame_id == self._position: + return self.read() + if self._cache: + img = self._cache.get(frame_id) + if img is not None: + self._position = frame_id + 1 + return img + self._set_real_position(frame_id) + ret, img = self._vcap.read() + if ret: + if self._cache: + self._cache.put(self._position, img) + self._position += 1 + return img + + def current_frame(self): + """Get the current frame (frame that is just visited). + + Returns: + ndarray or None: If the video is fresh, return None, otherwise + return the frame. + """ + if self._position == 0: + return None + return self._cache.get(self._position - 1) + + def cvt2frames(self, + frame_dir, + file_start=0, + filename_tmpl='{:06d}.jpg', + start=0, + max_num=0, + show_progress=True): + """Convert a video to frame images. + + Args: + frame_dir (str): Output directory to store all the frame images. + file_start (int): Filenames will start from the specified number. + filename_tmpl (str): Filename template with the index as the + placeholder. + start (int): The starting frame index. + max_num (int): Maximum number of frames to be written. + show_progress (bool): Whether to show a progress bar. + """ + mkdir_or_exist(frame_dir) + if max_num == 0: + task_num = self.frame_cnt - start + else: + task_num = min(self.frame_cnt - start, max_num) + if task_num <= 0: + raise ValueError('start must be less than total frame number') + if start > 0: + self._set_real_position(start) + + def write_frame(file_idx): + img = self.read() + if img is None: + return + filename = osp.join(frame_dir, filename_tmpl.format(file_idx)) + cv2.imwrite(filename, img) + + if show_progress: + track_progress(write_frame, range(file_start, + file_start + task_num)) + else: + for i in range(task_num): + write_frame(file_start + i) + + def __len__(self): + return self.frame_cnt + + def __getitem__(self, index): + if isinstance(index, slice): + return [ + self.get_frame(i) + for i in range(*index.indices(self.frame_cnt)) + ] + # support negative indexing + if index < 0: + index += self.frame_cnt + if index < 0: + raise IndexError('index out of range') + return self.get_frame(index) + + def __iter__(self): + self._set_real_position(0) + return self + + def __next__(self): + img = self.read() + if img is not None: + return img + else: + raise StopIteration + + next = __next__ + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + self._vcap.release() + + +def frames2video(frame_dir, + video_file, + fps=30, + fourcc='XVID', + filename_tmpl='{:06d}.jpg', + start=0, + end=0, + show_progress=True): + """Read the frame images from a directory and join them as a video. + + Args: + frame_dir (str): The directory containing video frames. + video_file (str): Output filename. + fps (float): FPS of the output video. + fourcc (str): Fourcc of the output video, this should be compatible + with the output file type. + filename_tmpl (str): Filename template with the index as the variable. + start (int): Starting frame index. + end (int): Ending frame index. + show_progress (bool): Whether to show a progress bar. + """ + if end == 0: + ext = filename_tmpl.split('.')[-1] + end = len([name for name in scandir(frame_dir, ext)]) + first_file = osp.join(frame_dir, filename_tmpl.format(start)) + check_file_exist(first_file, 'The start frame not found: ' + first_file) + img = cv2.imread(first_file) + height, width = img.shape[:2] + resolution = (width, height) + vwriter = cv2.VideoWriter(video_file, VideoWriter_fourcc(*fourcc), fps, + resolution) + + def write_frame(file_idx): + filename = osp.join(frame_dir, filename_tmpl.format(file_idx)) + img = cv2.imread(filename) + vwriter.write(img) + + if show_progress: + track_progress(write_frame, range(start, end)) + else: + for i in range(start, end): + write_frame(i) + vwriter.release() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/video/optflow.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/video/optflow.py new file mode 100644 index 00000000..7bd78970 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/video/optflow.py @@ -0,0 +1,254 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import warnings + +import cv2 +import numpy as np + +from annotator.mmpkg.mmcv.arraymisc import dequantize, quantize +from annotator.mmpkg.mmcv.image import imread, imwrite +from annotator.mmpkg.mmcv.utils import is_str + + +def flowread(flow_or_path, quantize=False, concat_axis=0, *args, **kwargs): + """Read an optical flow map. + + Args: + flow_or_path (ndarray or str): A flow map or filepath. + quantize (bool): whether to read quantized pair, if set to True, + remaining args will be passed to :func:`dequantize_flow`. + concat_axis (int): The axis that dx and dy are concatenated, + can be either 0 or 1. Ignored if quantize is False. + + Returns: + ndarray: Optical flow represented as a (h, w, 2) numpy array + """ + if isinstance(flow_or_path, np.ndarray): + if (flow_or_path.ndim != 3) or (flow_or_path.shape[-1] != 2): + raise ValueError(f'Invalid flow with shape {flow_or_path.shape}') + return flow_or_path + elif not is_str(flow_or_path): + raise TypeError(f'"flow_or_path" must be a filename or numpy array, ' + f'not {type(flow_or_path)}') + + if not quantize: + with open(flow_or_path, 'rb') as f: + try: + header = f.read(4).decode('utf-8') + except Exception: + raise IOError(f'Invalid flow file: {flow_or_path}') + else: + if header != 'PIEH': + raise IOError(f'Invalid flow file: {flow_or_path}, ' + 'header does not contain PIEH') + + w = np.fromfile(f, np.int32, 1).squeeze() + h = np.fromfile(f, np.int32, 1).squeeze() + flow = np.fromfile(f, np.float32, w * h * 2).reshape((h, w, 2)) + else: + assert concat_axis in [0, 1] + cat_flow = imread(flow_or_path, flag='unchanged') + if cat_flow.ndim != 2: + raise IOError( + f'{flow_or_path} is not a valid quantized flow file, ' + f'its dimension is {cat_flow.ndim}.') + assert cat_flow.shape[concat_axis] % 2 == 0 + dx, dy = np.split(cat_flow, 2, axis=concat_axis) + flow = dequantize_flow(dx, dy, *args, **kwargs) + + return flow.astype(np.float32) + + +def flowwrite(flow, filename, quantize=False, concat_axis=0, *args, **kwargs): + """Write optical flow to file. + + If the flow is not quantized, it will be saved as a .flo file losslessly, + otherwise a jpeg image which is lossy but of much smaller size. (dx and dy + will be concatenated horizontally into a single image if quantize is True.) + + Args: + flow (ndarray): (h, w, 2) array of optical flow. + filename (str): Output filepath. + quantize (bool): Whether to quantize the flow and save it to 2 jpeg + images. If set to True, remaining args will be passed to + :func:`quantize_flow`. + concat_axis (int): The axis that dx and dy are concatenated, + can be either 0 or 1. Ignored if quantize is False. + """ + if not quantize: + with open(filename, 'wb') as f: + f.write('PIEH'.encode('utf-8')) + np.array([flow.shape[1], flow.shape[0]], dtype=np.int32).tofile(f) + flow = flow.astype(np.float32) + flow.tofile(f) + f.flush() + else: + assert concat_axis in [0, 1] + dx, dy = quantize_flow(flow, *args, **kwargs) + dxdy = np.concatenate((dx, dy), axis=concat_axis) + imwrite(dxdy, filename) + + +def quantize_flow(flow, max_val=0.02, norm=True): + """Quantize flow to [0, 255]. + + After this step, the size of flow will be much smaller, and can be + dumped as jpeg images. + + Args: + flow (ndarray): (h, w, 2) array of optical flow. + max_val (float): Maximum value of flow, values beyond + [-max_val, max_val] will be truncated. + norm (bool): Whether to divide flow values by image width/height. + + Returns: + tuple[ndarray]: Quantized dx and dy. + """ + h, w, _ = flow.shape + dx = flow[..., 0] + dy = flow[..., 1] + if norm: + dx = dx / w # avoid inplace operations + dy = dy / h + # use 255 levels instead of 256 to make sure 0 is 0 after dequantization. + flow_comps = [ + quantize(d, -max_val, max_val, 255, np.uint8) for d in [dx, dy] + ] + return tuple(flow_comps) + + +def dequantize_flow(dx, dy, max_val=0.02, denorm=True): + """Recover from quantized flow. + + Args: + dx (ndarray): Quantized dx. + dy (ndarray): Quantized dy. + max_val (float): Maximum value used when quantizing. + denorm (bool): Whether to multiply flow values with width/height. + + Returns: + ndarray: Dequantized flow. + """ + assert dx.shape == dy.shape + assert dx.ndim == 2 or (dx.ndim == 3 and dx.shape[-1] == 1) + + dx, dy = [dequantize(d, -max_val, max_val, 255) for d in [dx, dy]] + + if denorm: + dx *= dx.shape[1] + dy *= dx.shape[0] + flow = np.dstack((dx, dy)) + return flow + + +def flow_warp(img, flow, filling_value=0, interpolate_mode='nearest'): + """Use flow to warp img. + + Args: + img (ndarray, float or uint8): Image to be warped. + flow (ndarray, float): Optical Flow. + filling_value (int): The missing pixels will be set with filling_value. + interpolate_mode (str): bilinear -> Bilinear Interpolation; + nearest -> Nearest Neighbor. + + Returns: + ndarray: Warped image with the same shape of img + """ + warnings.warn('This function is just for prototyping and cannot ' + 'guarantee the computational efficiency.') + assert flow.ndim == 3, 'Flow must be in 3D arrays.' + height = flow.shape[0] + width = flow.shape[1] + channels = img.shape[2] + + output = np.ones( + (height, width, channels), dtype=img.dtype) * filling_value + + grid = np.indices((height, width)).swapaxes(0, 1).swapaxes(1, 2) + dx = grid[:, :, 0] + flow[:, :, 1] + dy = grid[:, :, 1] + flow[:, :, 0] + sx = np.floor(dx).astype(int) + sy = np.floor(dy).astype(int) + valid = (sx >= 0) & (sx < height - 1) & (sy >= 0) & (sy < width - 1) + + if interpolate_mode == 'nearest': + output[valid, :] = img[dx[valid].round().astype(int), + dy[valid].round().astype(int), :] + elif interpolate_mode == 'bilinear': + # dirty walkround for integer positions + eps_ = 1e-6 + dx, dy = dx + eps_, dy + eps_ + left_top_ = img[np.floor(dx[valid]).astype(int), + np.floor(dy[valid]).astype(int), :] * ( + np.ceil(dx[valid]) - dx[valid])[:, None] * ( + np.ceil(dy[valid]) - dy[valid])[:, None] + left_down_ = img[np.ceil(dx[valid]).astype(int), + np.floor(dy[valid]).astype(int), :] * ( + dx[valid] - np.floor(dx[valid]))[:, None] * ( + np.ceil(dy[valid]) - dy[valid])[:, None] + right_top_ = img[np.floor(dx[valid]).astype(int), + np.ceil(dy[valid]).astype(int), :] * ( + np.ceil(dx[valid]) - dx[valid])[:, None] * ( + dy[valid] - np.floor(dy[valid]))[:, None] + right_down_ = img[np.ceil(dx[valid]).astype(int), + np.ceil(dy[valid]).astype(int), :] * ( + dx[valid] - np.floor(dx[valid]))[:, None] * ( + dy[valid] - np.floor(dy[valid]))[:, None] + output[valid, :] = left_top_ + left_down_ + right_top_ + right_down_ + else: + raise NotImplementedError( + 'We only support interpolation modes of nearest and bilinear, ' + f'but got {interpolate_mode}.') + return output.astype(img.dtype) + + +def flow_from_bytes(content): + """Read dense optical flow from bytes. + + .. note:: + This load optical flow function works for FlyingChairs, FlyingThings3D, + Sintel, FlyingChairsOcc datasets, but cannot load the data from + ChairsSDHom. + + Args: + content (bytes): Optical flow bytes got from files or other streams. + + Returns: + ndarray: Loaded optical flow with the shape (H, W, 2). + """ + + # header in first 4 bytes + header = content[:4] + if header.decode('utf-8') != 'PIEH': + raise Exception('Flow file header does not contain PIEH') + # width in second 4 bytes + width = np.frombuffer(content[4:], np.int32, 1).squeeze() + # height in third 4 bytes + height = np.frombuffer(content[8:], np.int32, 1).squeeze() + # after first 12 bytes, all bytes are flow + flow = np.frombuffer(content[12:], np.float32, width * height * 2).reshape( + (height, width, 2)) + + return flow + + +def sparse_flow_from_bytes(content): + """Read the optical flow in KITTI datasets from bytes. + + This function is modified from RAFT load the `KITTI datasets + `_. + + Args: + content (bytes): Optical flow bytes got from files or other streams. + + Returns: + Tuple(ndarray, ndarray): Loaded optical flow with the shape (H, W, 2) + and flow valid mask with the shape (H, W). + """ # nopa + + content = np.frombuffer(content, np.uint8) + flow = cv2.imdecode(content, cv2.IMREAD_ANYDEPTH | cv2.IMREAD_COLOR) + flow = flow[:, :, ::-1].astype(np.float32) + # flow shape (H, W, 2) valid shape (H, W) + flow, valid = flow[:, :, :2], flow[:, :, 2] + flow = (flow - 2**15) / 64.0 + return flow, valid diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/video/processing.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/video/processing.py new file mode 100644 index 00000000..2b93a592 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/video/processing.py @@ -0,0 +1,160 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os +import os.path as osp +import subprocess +import tempfile + +from annotator.mmpkg.mmcv.utils import requires_executable + + +@requires_executable('ffmpeg') +def convert_video(in_file, + out_file, + print_cmd=False, + pre_options='', + **kwargs): + """Convert a video with ffmpeg. + + This provides a general api to ffmpeg, the executed command is:: + + `ffmpeg -y -i ` + + Options(kwargs) are mapped to ffmpeg commands with the following rules: + + - key=val: "-key val" + - key=True: "-key" + - key=False: "" + + Args: + in_file (str): Input video filename. + out_file (str): Output video filename. + pre_options (str): Options appears before "-i ". + print_cmd (bool): Whether to print the final ffmpeg command. + """ + options = [] + for k, v in kwargs.items(): + if isinstance(v, bool): + if v: + options.append(f'-{k}') + elif k == 'log_level': + assert v in [ + 'quiet', 'panic', 'fatal', 'error', 'warning', 'info', + 'verbose', 'debug', 'trace' + ] + options.append(f'-loglevel {v}') + else: + options.append(f'-{k} {v}') + cmd = f'ffmpeg -y {pre_options} -i {in_file} {" ".join(options)} ' \ + f'{out_file}' + if print_cmd: + print(cmd) + subprocess.call(cmd, shell=True) + + +@requires_executable('ffmpeg') +def resize_video(in_file, + out_file, + size=None, + ratio=None, + keep_ar=False, + log_level='info', + print_cmd=False): + """Resize a video. + + Args: + in_file (str): Input video filename. + out_file (str): Output video filename. + size (tuple): Expected size (w, h), eg, (320, 240) or (320, -1). + ratio (tuple or float): Expected resize ratio, (2, 0.5) means + (w*2, h*0.5). + keep_ar (bool): Whether to keep original aspect ratio. + log_level (str): Logging level of ffmpeg. + print_cmd (bool): Whether to print the final ffmpeg command. + """ + if size is None and ratio is None: + raise ValueError('expected size or ratio must be specified') + if size is not None and ratio is not None: + raise ValueError('size and ratio cannot be specified at the same time') + options = {'log_level': log_level} + if size: + if not keep_ar: + options['vf'] = f'scale={size[0]}:{size[1]}' + else: + options['vf'] = f'scale=w={size[0]}:h={size[1]}:' \ + 'force_original_aspect_ratio=decrease' + else: + if not isinstance(ratio, tuple): + ratio = (ratio, ratio) + options['vf'] = f'scale="trunc(iw*{ratio[0]}):trunc(ih*{ratio[1]})"' + convert_video(in_file, out_file, print_cmd, **options) + + +@requires_executable('ffmpeg') +def cut_video(in_file, + out_file, + start=None, + end=None, + vcodec=None, + acodec=None, + log_level='info', + print_cmd=False): + """Cut a clip from a video. + + Args: + in_file (str): Input video filename. + out_file (str): Output video filename. + start (None or float): Start time (in seconds). + end (None or float): End time (in seconds). + vcodec (None or str): Output video codec, None for unchanged. + acodec (None or str): Output audio codec, None for unchanged. + log_level (str): Logging level of ffmpeg. + print_cmd (bool): Whether to print the final ffmpeg command. + """ + options = {'log_level': log_level} + if vcodec is None: + options['vcodec'] = 'copy' + if acodec is None: + options['acodec'] = 'copy' + if start: + options['ss'] = start + else: + start = 0 + if end: + options['t'] = end - start + convert_video(in_file, out_file, print_cmd, **options) + + +@requires_executable('ffmpeg') +def concat_video(video_list, + out_file, + vcodec=None, + acodec=None, + log_level='info', + print_cmd=False): + """Concatenate multiple videos into a single one. + + Args: + video_list (list): A list of video filenames + out_file (str): Output video filename + vcodec (None or str): Output video codec, None for unchanged + acodec (None or str): Output audio codec, None for unchanged + log_level (str): Logging level of ffmpeg. + print_cmd (bool): Whether to print the final ffmpeg command. + """ + tmp_filehandler, tmp_filename = tempfile.mkstemp(suffix='.txt', text=True) + with open(tmp_filename, 'w') as f: + for filename in video_list: + f.write(f'file {osp.abspath(filename)}\n') + options = {'log_level': log_level} + if vcodec is None: + options['vcodec'] = 'copy' + if acodec is None: + options['acodec'] = 'copy' + convert_video( + tmp_filename, + out_file, + print_cmd, + pre_options='-f concat -safe 0', + **options) + os.close(tmp_filehandler) + os.remove(tmp_filename) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/visualization/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/visualization/__init__.py new file mode 100644 index 00000000..835df136 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/visualization/__init__.py @@ -0,0 +1,9 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .color import Color, color_val +from .image import imshow, imshow_bboxes, imshow_det_bboxes +from .optflow import flow2rgb, flowshow, make_color_wheel + +__all__ = [ + 'Color', 'color_val', 'imshow', 'imshow_bboxes', 'imshow_det_bboxes', + 'flowshow', 'flow2rgb', 'make_color_wheel' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/visualization/color.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/visualization/color.py new file mode 100644 index 00000000..48379a28 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/visualization/color.py @@ -0,0 +1,51 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from enum import Enum + +import numpy as np + +from annotator.mmpkg.mmcv.utils import is_str + + +class Color(Enum): + """An enum that defines common colors. + + Contains red, green, blue, cyan, yellow, magenta, white and black. + """ + red = (0, 0, 255) + green = (0, 255, 0) + blue = (255, 0, 0) + cyan = (255, 255, 0) + yellow = (0, 255, 255) + magenta = (255, 0, 255) + white = (255, 255, 255) + black = (0, 0, 0) + + +def color_val(color): + """Convert various input to color tuples. + + Args: + color (:obj:`Color`/str/tuple/int/ndarray): Color inputs + + Returns: + tuple[int]: A tuple of 3 integers indicating BGR channels. + """ + if is_str(color): + return Color[color].value + elif isinstance(color, Color): + return color.value + elif isinstance(color, tuple): + assert len(color) == 3 + for channel in color: + assert 0 <= channel <= 255 + return color + elif isinstance(color, int): + assert 0 <= color <= 255 + return color, color, color + elif isinstance(color, np.ndarray): + assert color.ndim == 1 and color.size == 3 + assert np.all((color >= 0) & (color <= 255)) + color = color.astype(np.uint8) + return tuple(color) + else: + raise TypeError(f'Invalid type for color: {type(color)}') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/visualization/image.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/visualization/image.py new file mode 100644 index 00000000..378de210 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/visualization/image.py @@ -0,0 +1,152 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import cv2 +import numpy as np + +from annotator.mmpkg.mmcv.image import imread, imwrite +from .color import color_val + + +def imshow(img, win_name='', wait_time=0): + """Show an image. + + Args: + img (str or ndarray): The image to be displayed. + win_name (str): The window name. + wait_time (int): Value of waitKey param. + """ + cv2.imshow(win_name, imread(img)) + if wait_time == 0: # prevent from hanging if windows was closed + while True: + ret = cv2.waitKey(1) + + closed = cv2.getWindowProperty(win_name, cv2.WND_PROP_VISIBLE) < 1 + # if user closed window or if some key pressed + if closed or ret != -1: + break + else: + ret = cv2.waitKey(wait_time) + + +def imshow_bboxes(img, + bboxes, + colors='green', + top_k=-1, + thickness=1, + show=True, + win_name='', + wait_time=0, + out_file=None): + """Draw bboxes on an image. + + Args: + img (str or ndarray): The image to be displayed. + bboxes (list or ndarray): A list of ndarray of shape (k, 4). + colors (list[str or tuple or Color]): A list of colors. + top_k (int): Plot the first k bboxes only if set positive. + thickness (int): Thickness of lines. + show (bool): Whether to show the image. + win_name (str): The window name. + wait_time (int): Value of waitKey param. + out_file (str, optional): The filename to write the image. + + Returns: + ndarray: The image with bboxes drawn on it. + """ + img = imread(img) + img = np.ascontiguousarray(img) + + if isinstance(bboxes, np.ndarray): + bboxes = [bboxes] + if not isinstance(colors, list): + colors = [colors for _ in range(len(bboxes))] + colors = [color_val(c) for c in colors] + assert len(bboxes) == len(colors) + + for i, _bboxes in enumerate(bboxes): + _bboxes = _bboxes.astype(np.int32) + if top_k <= 0: + _top_k = _bboxes.shape[0] + else: + _top_k = min(top_k, _bboxes.shape[0]) + for j in range(_top_k): + left_top = (_bboxes[j, 0], _bboxes[j, 1]) + right_bottom = (_bboxes[j, 2], _bboxes[j, 3]) + cv2.rectangle( + img, left_top, right_bottom, colors[i], thickness=thickness) + + if show: + imshow(img, win_name, wait_time) + if out_file is not None: + imwrite(img, out_file) + return img + + +def imshow_det_bboxes(img, + bboxes, + labels, + class_names=None, + score_thr=0, + bbox_color='green', + text_color='green', + thickness=1, + font_scale=0.5, + show=True, + win_name='', + wait_time=0, + out_file=None): + """Draw bboxes and class labels (with scores) on an image. + + Args: + img (str or ndarray): The image to be displayed. + bboxes (ndarray): Bounding boxes (with scores), shaped (n, 4) or + (n, 5). + labels (ndarray): Labels of bboxes. + class_names (list[str]): Names of each classes. + score_thr (float): Minimum score of bboxes to be shown. + bbox_color (str or tuple or :obj:`Color`): Color of bbox lines. + text_color (str or tuple or :obj:`Color`): Color of texts. + thickness (int): Thickness of lines. + font_scale (float): Font scales of texts. + show (bool): Whether to show the image. + win_name (str): The window name. + wait_time (int): Value of waitKey param. + out_file (str or None): The filename to write the image. + + Returns: + ndarray: The image with bboxes drawn on it. + """ + assert bboxes.ndim == 2 + assert labels.ndim == 1 + assert bboxes.shape[0] == labels.shape[0] + assert bboxes.shape[1] == 4 or bboxes.shape[1] == 5 + img = imread(img) + img = np.ascontiguousarray(img) + + if score_thr > 0: + assert bboxes.shape[1] == 5 + scores = bboxes[:, -1] + inds = scores > score_thr + bboxes = bboxes[inds, :] + labels = labels[inds] + + bbox_color = color_val(bbox_color) + text_color = color_val(text_color) + + for bbox, label in zip(bboxes, labels): + bbox_int = bbox.astype(np.int32) + left_top = (bbox_int[0], bbox_int[1]) + right_bottom = (bbox_int[2], bbox_int[3]) + cv2.rectangle( + img, left_top, right_bottom, bbox_color, thickness=thickness) + label_text = class_names[ + label] if class_names is not None else f'cls {label}' + if len(bbox) > 4: + label_text += f'|{bbox[-1]:.02f}' + cv2.putText(img, label_text, (bbox_int[0], bbox_int[1] - 2), + cv2.FONT_HERSHEY_COMPLEX, font_scale, text_color) + + if show: + imshow(img, win_name, wait_time) + if out_file is not None: + imwrite(img, out_file) + return img diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/visualization/optflow.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/visualization/optflow.py new file mode 100644 index 00000000..b4c3ce98 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmcv/visualization/optflow.py @@ -0,0 +1,112 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from __future__ import division + +import numpy as np + +from annotator.mmpkg.mmcv.image import rgb2bgr +from annotator.mmpkg.mmcv.video import flowread +from .image import imshow + + +def flowshow(flow, win_name='', wait_time=0): + """Show optical flow. + + Args: + flow (ndarray or str): The optical flow to be displayed. + win_name (str): The window name. + wait_time (int): Value of waitKey param. + """ + flow = flowread(flow) + flow_img = flow2rgb(flow) + imshow(rgb2bgr(flow_img), win_name, wait_time) + + +def flow2rgb(flow, color_wheel=None, unknown_thr=1e6): + """Convert flow map to RGB image. + + Args: + flow (ndarray): Array of optical flow. + color_wheel (ndarray or None): Color wheel used to map flow field to + RGB colorspace. Default color wheel will be used if not specified. + unknown_thr (str): Values above this threshold will be marked as + unknown and thus ignored. + + Returns: + ndarray: RGB image that can be visualized. + """ + assert flow.ndim == 3 and flow.shape[-1] == 2 + if color_wheel is None: + color_wheel = make_color_wheel() + assert color_wheel.ndim == 2 and color_wheel.shape[1] == 3 + num_bins = color_wheel.shape[0] + + dx = flow[:, :, 0].copy() + dy = flow[:, :, 1].copy() + + ignore_inds = ( + np.isnan(dx) | np.isnan(dy) | (np.abs(dx) > unknown_thr) | + (np.abs(dy) > unknown_thr)) + dx[ignore_inds] = 0 + dy[ignore_inds] = 0 + + rad = np.sqrt(dx**2 + dy**2) + if np.any(rad > np.finfo(float).eps): + max_rad = np.max(rad) + dx /= max_rad + dy /= max_rad + + rad = np.sqrt(dx**2 + dy**2) + angle = np.arctan2(-dy, -dx) / np.pi + + bin_real = (angle + 1) / 2 * (num_bins - 1) + bin_left = np.floor(bin_real).astype(int) + bin_right = (bin_left + 1) % num_bins + w = (bin_real - bin_left.astype(np.float32))[..., None] + flow_img = (1 - + w) * color_wheel[bin_left, :] + w * color_wheel[bin_right, :] + small_ind = rad <= 1 + flow_img[small_ind] = 1 - rad[small_ind, None] * (1 - flow_img[small_ind]) + flow_img[np.logical_not(small_ind)] *= 0.75 + + flow_img[ignore_inds, :] = 0 + + return flow_img + + +def make_color_wheel(bins=None): + """Build a color wheel. + + Args: + bins(list or tuple, optional): Specify the number of bins for each + color range, corresponding to six ranges: red -> yellow, + yellow -> green, green -> cyan, cyan -> blue, blue -> magenta, + magenta -> red. [15, 6, 4, 11, 13, 6] is used for default + (see Middlebury). + + Returns: + ndarray: Color wheel of shape (total_bins, 3). + """ + if bins is None: + bins = [15, 6, 4, 11, 13, 6] + assert len(bins) == 6 + + RY, YG, GC, CB, BM, MR = tuple(bins) + + ry = [1, np.arange(RY) / RY, 0] + yg = [1 - np.arange(YG) / YG, 1, 0] + gc = [0, 1, np.arange(GC) / GC] + cb = [0, 1 - np.arange(CB) / CB, 1] + bm = [np.arange(BM) / BM, 0, 1] + mr = [1, 0, 1 - np.arange(MR) / MR] + + num_bins = RY + YG + GC + CB + BM + MR + + color_wheel = np.zeros((3, num_bins), dtype=np.float32) + + col = 0 + for i, color in enumerate([ry, yg, gc, cb, bm, mr]): + for j in range(3): + color_wheel[j, col:col + bins[i]] = color[j] + col += bins[i] + + return color_wheel.T diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/apis/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/apis/__init__.py new file mode 100644 index 00000000..170724be --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/apis/__init__.py @@ -0,0 +1,9 @@ +from .inference import inference_segmentor, init_segmentor, show_result_pyplot +from .test import multi_gpu_test, single_gpu_test +from .train import get_root_logger, set_random_seed, train_segmentor + +__all__ = [ + 'get_root_logger', 'set_random_seed', 'train_segmentor', 'init_segmentor', + 'inference_segmentor', 'multi_gpu_test', 'single_gpu_test', + 'show_result_pyplot' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/apis/inference.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/apis/inference.py new file mode 100644 index 00000000..515e459f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/apis/inference.py @@ -0,0 +1,138 @@ +import matplotlib.pyplot as plt +import annotator.mmpkg.mmcv as mmcv +import torch +from annotator.mmpkg.mmcv.parallel import collate, scatter +from annotator.mmpkg.mmcv.runner import load_checkpoint + +from annotator.mmpkg.mmseg.datasets.pipelines import Compose +from annotator.mmpkg.mmseg.models import build_segmentor +from modules import devices + + +def init_segmentor(config, checkpoint=None, device=devices.get_device_for("controlnet")): + """Initialize a segmentor from config file. + + Args: + config (str or :obj:`mmcv.Config`): Config file path or the config + object. + checkpoint (str, optional): Checkpoint path. If left as None, the model + will not load any weights. + device (str, optional) CPU/CUDA device option. Default 'cuda:0'. + Use 'cpu' for loading model on CPU. + Returns: + nn.Module: The constructed segmentor. + """ + if isinstance(config, str): + config = mmcv.Config.fromfile(config) + elif not isinstance(config, mmcv.Config): + raise TypeError('config must be a filename or Config object, ' + 'but got {}'.format(type(config))) + config.model.pretrained = None + config.model.train_cfg = None + model = build_segmentor(config.model, test_cfg=config.get('test_cfg')) + if checkpoint is not None: + checkpoint = load_checkpoint(model, checkpoint, map_location='cpu') + model.CLASSES = checkpoint['meta']['CLASSES'] + model.PALETTE = checkpoint['meta']['PALETTE'] + model.cfg = config # save the config in the model for convenience + model.to(device) + model.eval() + return model + + +class LoadImage: + """A simple pipeline to load image.""" + + def __call__(self, results): + """Call function to load images into results. + + Args: + results (dict): A result dict contains the file name + of the image to be read. + + Returns: + dict: ``results`` will be returned containing loaded image. + """ + + if isinstance(results['img'], str): + results['filename'] = results['img'] + results['ori_filename'] = results['img'] + else: + results['filename'] = None + results['ori_filename'] = None + img = mmcv.imread(results['img']) + results['img'] = img + results['img_shape'] = img.shape + results['ori_shape'] = img.shape + return results + + +def inference_segmentor(model, img): + """Inference image(s) with the segmentor. + + Args: + model (nn.Module): The loaded segmentor. + imgs (str/ndarray or list[str/ndarray]): Either image files or loaded + images. + + Returns: + (list[Tensor]): The segmentation result. + """ + cfg = model.cfg + device = next(model.parameters()).device # model device + # build the data pipeline + test_pipeline = [LoadImage()] + cfg.data.test.pipeline[1:] + test_pipeline = Compose(test_pipeline) + # prepare data + data = dict(img=img) + data = test_pipeline(data) + data = collate([data], samples_per_gpu=1) + if next(model.parameters()).is_cuda: + # scatter to specified GPU + data = scatter(data, [device])[0] + else: + data['img'][0] = data['img'][0].to(devices.get_device_for("controlnet")) + data['img_metas'] = [i.data[0] for i in data['img_metas']] + + # forward the model + with torch.no_grad(): + result = model(return_loss=False, rescale=True, **data) + return result + + +def show_result_pyplot(model, + img, + result, + palette=None, + fig_size=(15, 10), + opacity=0.5, + title='', + block=True): + """Visualize the segmentation results on the image. + + Args: + model (nn.Module): The loaded segmentor. + img (str or np.ndarray): Image filename or loaded image. + result (list): The segmentation result. + palette (list[list[int]]] | None): The palette of segmentation + map. If None is given, random palette will be generated. + Default: None + fig_size (tuple): Figure size of the pyplot figure. + opacity(float): Opacity of painted segmentation map. + Default 0.5. + Must be in (0, 1] range. + title (str): The title of pyplot figure. + Default is ''. + block (bool): Whether to block the pyplot figure. + Default is True. + """ + if hasattr(model, 'module'): + model = model.module + img = model.show_result( + img, result, palette=palette, show=False, opacity=opacity) + # plt.figure(figsize=fig_size) + # plt.imshow(mmcv.bgr2rgb(img)) + # plt.title(title) + # plt.tight_layout() + # plt.show(block=block) + return mmcv.bgr2rgb(img) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/apis/test.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/apis/test.py new file mode 100644 index 00000000..f9954e6a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/apis/test.py @@ -0,0 +1,238 @@ +import os.path as osp +import pickle +import shutil +import tempfile + +import annotator.mmpkg.mmcv as mmcv +import numpy as np +import torch +import torch.distributed as dist +from annotator.mmpkg.mmcv.image import tensor2imgs +from annotator.mmpkg.mmcv.runner import get_dist_info + + +def np2tmp(array, temp_file_name=None): + """Save ndarray to local numpy file. + + Args: + array (ndarray): Ndarray to save. + temp_file_name (str): Numpy file name. If 'temp_file_name=None', this + function will generate a file name with tempfile.NamedTemporaryFile + to save ndarray. Default: None. + + Returns: + str: The numpy file name. + """ + + if temp_file_name is None: + temp_file_name = tempfile.NamedTemporaryFile( + suffix='.npy', delete=False).name + np.save(temp_file_name, array) + return temp_file_name + + +def single_gpu_test(model, + data_loader, + show=False, + out_dir=None, + efficient_test=False, + opacity=0.5): + """Test with single GPU. + + Args: + model (nn.Module): Model to be tested. + data_loader (utils.data.Dataloader): Pytorch data loader. + show (bool): Whether show results during inference. Default: False. + out_dir (str, optional): If specified, the results will be dumped into + the directory to save output results. + efficient_test (bool): Whether save the results as local numpy files to + save CPU memory during evaluation. Default: False. + opacity(float): Opacity of painted segmentation map. + Default 0.5. + Must be in (0, 1] range. + Returns: + list: The prediction results. + """ + + model.eval() + results = [] + dataset = data_loader.dataset + prog_bar = mmcv.ProgressBar(len(dataset)) + for i, data in enumerate(data_loader): + with torch.no_grad(): + result = model(return_loss=False, **data) + + if show or out_dir: + img_tensor = data['img'][0] + img_metas = data['img_metas'][0].data[0] + imgs = tensor2imgs(img_tensor, **img_metas[0]['img_norm_cfg']) + assert len(imgs) == len(img_metas) + + for img, img_meta in zip(imgs, img_metas): + h, w, _ = img_meta['img_shape'] + img_show = img[:h, :w, :] + + ori_h, ori_w = img_meta['ori_shape'][:-1] + img_show = mmcv.imresize(img_show, (ori_w, ori_h)) + + if out_dir: + out_file = osp.join(out_dir, img_meta['ori_filename']) + else: + out_file = None + + model.module.show_result( + img_show, + result, + palette=dataset.PALETTE, + show=show, + out_file=out_file, + opacity=opacity) + + if isinstance(result, list): + if efficient_test: + result = [np2tmp(_) for _ in result] + results.extend(result) + else: + if efficient_test: + result = np2tmp(result) + results.append(result) + + batch_size = len(result) + for _ in range(batch_size): + prog_bar.update() + return results + + +def multi_gpu_test(model, + data_loader, + tmpdir=None, + gpu_collect=False, + efficient_test=False): + """Test model with multiple gpus. + + This method tests model with multiple gpus and collects the results + under two different modes: gpu and cpu modes. By setting 'gpu_collect=True' + it encodes results to gpu tensors and use gpu communication for results + collection. On cpu mode it saves the results on different gpus to 'tmpdir' + and collects them by the rank 0 worker. + + Args: + model (nn.Module): Model to be tested. + data_loader (utils.data.Dataloader): Pytorch data loader. + tmpdir (str): Path of directory to save the temporary results from + different gpus under cpu mode. + gpu_collect (bool): Option to use either gpu or cpu to collect results. + efficient_test (bool): Whether save the results as local numpy files to + save CPU memory during evaluation. Default: False. + + Returns: + list: The prediction results. + """ + + model.eval() + results = [] + dataset = data_loader.dataset + rank, world_size = get_dist_info() + if rank == 0: + prog_bar = mmcv.ProgressBar(len(dataset)) + for i, data in enumerate(data_loader): + with torch.no_grad(): + result = model(return_loss=False, rescale=True, **data) + + if isinstance(result, list): + if efficient_test: + result = [np2tmp(_) for _ in result] + results.extend(result) + else: + if efficient_test: + result = np2tmp(result) + results.append(result) + + if rank == 0: + batch_size = data['img'][0].size(0) + for _ in range(batch_size * world_size): + prog_bar.update() + + # collect results from all ranks + if gpu_collect: + results = collect_results_gpu(results, len(dataset)) + else: + results = collect_results_cpu(results, len(dataset), tmpdir) + return results + + +def collect_results_cpu(result_part, size, tmpdir=None): + """Collect results with CPU.""" + rank, world_size = get_dist_info() + # create a tmp dir if it is not specified + if tmpdir is None: + MAX_LEN = 512 + # 32 is whitespace + dir_tensor = torch.full((MAX_LEN, ), + 32, + dtype=torch.uint8, + device='cuda') + if rank == 0: + tmpdir = tempfile.mkdtemp() + tmpdir = torch.tensor( + bytearray(tmpdir.encode()), dtype=torch.uint8, device='cuda') + dir_tensor[:len(tmpdir)] = tmpdir + dist.broadcast(dir_tensor, 0) + tmpdir = dir_tensor.cpu().numpy().tobytes().decode().rstrip() + else: + mmcv.mkdir_or_exist(tmpdir) + # dump the part result to the dir + mmcv.dump(result_part, osp.join(tmpdir, 'part_{}.pkl'.format(rank))) + dist.barrier() + # collect all parts + if rank != 0: + return None + else: + # load results of all parts from tmp dir + part_list = [] + for i in range(world_size): + part_file = osp.join(tmpdir, 'part_{}.pkl'.format(i)) + part_list.append(mmcv.load(part_file)) + # sort the results + ordered_results = [] + for res in zip(*part_list): + ordered_results.extend(list(res)) + # the dataloader may pad some samples + ordered_results = ordered_results[:size] + # remove tmp dir + shutil.rmtree(tmpdir) + return ordered_results + + +def collect_results_gpu(result_part, size): + """Collect results with GPU.""" + rank, world_size = get_dist_info() + # dump result part to tensor with pickle + part_tensor = torch.tensor( + bytearray(pickle.dumps(result_part)), dtype=torch.uint8, device='cuda') + # gather all result part tensor shape + shape_tensor = torch.tensor(part_tensor.shape, device='cuda') + shape_list = [shape_tensor.clone() for _ in range(world_size)] + dist.all_gather(shape_list, shape_tensor) + # padding result part tensor to max length + shape_max = torch.tensor(shape_list).max() + part_send = torch.zeros(shape_max, dtype=torch.uint8, device='cuda') + part_send[:shape_tensor[0]] = part_tensor + part_recv_list = [ + part_tensor.new_zeros(shape_max) for _ in range(world_size) + ] + # gather all result part + dist.all_gather(part_recv_list, part_send) + + if rank == 0: + part_list = [] + for recv, shape in zip(part_recv_list, shape_list): + part_list.append( + pickle.loads(recv[:shape[0]].cpu().numpy().tobytes())) + # sort the results + ordered_results = [] + for res in zip(*part_list): + ordered_results.extend(list(res)) + # the dataloader may pad some samples + ordered_results = ordered_results[:size] + return ordered_results diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/apis/train.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/apis/train.py new file mode 100644 index 00000000..f0a87d65 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/apis/train.py @@ -0,0 +1,116 @@ +import random +import warnings + +import numpy as np +import torch +from annotator.mmpkg.mmcv.parallel import MMDataParallel, MMDistributedDataParallel +from annotator.mmpkg.mmcv.runner import build_optimizer, build_runner + +from annotator.mmpkg.mmseg.core import DistEvalHook, EvalHook +from annotator.mmpkg.mmseg.datasets import build_dataloader, build_dataset +from annotator.mmpkg.mmseg.utils import get_root_logger + + +def set_random_seed(seed, deterministic=False): + """Set random seed. + + Args: + seed (int): Seed to be used. + deterministic (bool): Whether to set the deterministic option for + CUDNN backend, i.e., set `torch.backends.cudnn.deterministic` + to True and `torch.backends.cudnn.benchmark` to False. + Default: False. + """ + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + torch.cuda.manual_seed_all(seed) + if deterministic: + torch.backends.cudnn.deterministic = True + torch.backends.cudnn.benchmark = False + + +def train_segmentor(model, + dataset, + cfg, + distributed=False, + validate=False, + timestamp=None, + meta=None): + """Launch segmentor training.""" + logger = get_root_logger(cfg.log_level) + + # prepare data loaders + dataset = dataset if isinstance(dataset, (list, tuple)) else [dataset] + data_loaders = [ + build_dataloader( + ds, + cfg.data.samples_per_gpu, + cfg.data.workers_per_gpu, + # cfg.gpus will be ignored if distributed + len(cfg.gpu_ids), + dist=distributed, + seed=cfg.seed, + drop_last=True) for ds in dataset + ] + + # put model on gpus + if distributed: + find_unused_parameters = cfg.get('find_unused_parameters', False) + # Sets the `find_unused_parameters` parameter in + # torch.nn.parallel.DistributedDataParallel + model = MMDistributedDataParallel( + model.cuda(), + device_ids=[torch.cuda.current_device()], + broadcast_buffers=False, + find_unused_parameters=find_unused_parameters) + else: + model = MMDataParallel( + model.cuda(cfg.gpu_ids[0]), device_ids=cfg.gpu_ids) + + # build runner + optimizer = build_optimizer(model, cfg.optimizer) + + if cfg.get('runner') is None: + cfg.runner = {'type': 'IterBasedRunner', 'max_iters': cfg.total_iters} + warnings.warn( + 'config is now expected to have a `runner` section, ' + 'please set `runner` in your config.', UserWarning) + + runner = build_runner( + cfg.runner, + default_args=dict( + model=model, + batch_processor=None, + optimizer=optimizer, + work_dir=cfg.work_dir, + logger=logger, + meta=meta)) + + # register hooks + runner.register_training_hooks(cfg.lr_config, cfg.optimizer_config, + cfg.checkpoint_config, cfg.log_config, + cfg.get('momentum_config', None)) + + # an ugly walkaround to make the .log and .log.json filenames the same + runner.timestamp = timestamp + + # register eval hooks + if validate: + val_dataset = build_dataset(cfg.data.val, dict(test_mode=True)) + val_dataloader = build_dataloader( + val_dataset, + samples_per_gpu=1, + workers_per_gpu=cfg.data.workers_per_gpu, + dist=distributed, + shuffle=False) + eval_cfg = cfg.get('evaluation', {}) + eval_cfg['by_epoch'] = cfg.runner['type'] != 'IterBasedRunner' + eval_hook = DistEvalHook if distributed else EvalHook + runner.register_hook(eval_hook(val_dataloader, **eval_cfg), priority='LOW') + + if cfg.resume_from: + runner.resume(cfg.resume_from) + elif cfg.load_from: + runner.load_checkpoint(cfg.load_from) + runner.run(data_loaders, cfg.workflow) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/__init__.py new file mode 100644 index 00000000..96560558 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/__init__.py @@ -0,0 +1,3 @@ +from .evaluation import * # noqa: F401, F403 +from .seg import * # noqa: F401, F403 +from .utils import * # noqa: F401, F403 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/evaluation/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/evaluation/__init__.py new file mode 100644 index 00000000..f7cc4b23 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/evaluation/__init__.py @@ -0,0 +1,8 @@ +from .class_names import get_classes, get_palette +from .eval_hooks import DistEvalHook, EvalHook +from .metrics import eval_metrics, mean_dice, mean_fscore, mean_iou + +__all__ = [ + 'EvalHook', 'DistEvalHook', 'mean_dice', 'mean_iou', 'mean_fscore', + 'eval_metrics', 'get_classes', 'get_palette' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/evaluation/class_names.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/evaluation/class_names.py new file mode 100644 index 00000000..532c5fd7 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/evaluation/class_names.py @@ -0,0 +1,152 @@ +import annotator.mmpkg.mmcv as mmcv + + +def cityscapes_classes(): + """Cityscapes class names for external use.""" + return [ + 'road', 'sidewalk', 'building', 'wall', 'fence', 'pole', + 'traffic light', 'traffic sign', 'vegetation', 'terrain', 'sky', + 'person', 'rider', 'car', 'truck', 'bus', 'train', 'motorcycle', + 'bicycle' + ] + + +def ade_classes(): + """ADE20K class names for external use.""" + return [ + 'wall', 'building', 'sky', 'floor', 'tree', 'ceiling', 'road', 'bed ', + 'windowpane', 'grass', 'cabinet', 'sidewalk', 'person', 'earth', + 'door', 'table', 'mountain', 'plant', 'curtain', 'chair', 'car', + 'water', 'painting', 'sofa', 'shelf', 'house', 'sea', 'mirror', 'rug', + 'field', 'armchair', 'seat', 'fence', 'desk', 'rock', 'wardrobe', + 'lamp', 'bathtub', 'railing', 'cushion', 'base', 'box', 'column', + 'signboard', 'chest of drawers', 'counter', 'sand', 'sink', + 'skyscraper', 'fireplace', 'refrigerator', 'grandstand', 'path', + 'stairs', 'runway', 'case', 'pool table', 'pillow', 'screen door', + 'stairway', 'river', 'bridge', 'bookcase', 'blind', 'coffee table', + 'toilet', 'flower', 'book', 'hill', 'bench', 'countertop', 'stove', + 'palm', 'kitchen island', 'computer', 'swivel chair', 'boat', 'bar', + 'arcade machine', 'hovel', 'bus', 'towel', 'light', 'truck', 'tower', + 'chandelier', 'awning', 'streetlight', 'booth', 'television receiver', + 'airplane', 'dirt track', 'apparel', 'pole', 'land', 'bannister', + 'escalator', 'ottoman', 'bottle', 'buffet', 'poster', 'stage', 'van', + 'ship', 'fountain', 'conveyer belt', 'canopy', 'washer', 'plaything', + 'swimming pool', 'stool', 'barrel', 'basket', 'waterfall', 'tent', + 'bag', 'minibike', 'cradle', 'oven', 'ball', 'food', 'step', 'tank', + 'trade name', 'microwave', 'pot', 'animal', 'bicycle', 'lake', + 'dishwasher', 'screen', 'blanket', 'sculpture', 'hood', 'sconce', + 'vase', 'traffic light', 'tray', 'ashcan', 'fan', 'pier', 'crt screen', + 'plate', 'monitor', 'bulletin board', 'shower', 'radiator', 'glass', + 'clock', 'flag' + ] + + +def voc_classes(): + """Pascal VOC class names for external use.""" + return [ + 'background', 'aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', + 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', 'horse', + 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', + 'tvmonitor' + ] + + +def cityscapes_palette(): + """Cityscapes palette for external use.""" + return [[128, 64, 128], [244, 35, 232], [70, 70, 70], [102, 102, 156], + [190, 153, 153], [153, 153, 153], [250, 170, 30], [220, 220, 0], + [107, 142, 35], [152, 251, 152], [70, 130, 180], [220, 20, 60], + [255, 0, 0], [0, 0, 142], [0, 0, 70], [0, 60, 100], [0, 80, 100], + [0, 0, 230], [119, 11, 32]] + + +def ade_palette(): + """ADE20K palette for external use.""" + return [[120, 120, 120], [180, 120, 120], [6, 230, 230], [80, 50, 50], + [4, 200, 3], [120, 120, 80], [140, 140, 140], [204, 5, 255], + [230, 230, 230], [4, 250, 7], [224, 5, 255], [235, 255, 7], + [150, 5, 61], [120, 120, 70], [8, 255, 51], [255, 6, 82], + [143, 255, 140], [204, 255, 4], [255, 51, 7], [204, 70, 3], + [0, 102, 200], [61, 230, 250], [255, 6, 51], [11, 102, 255], + [255, 7, 71], [255, 9, 224], [9, 7, 230], [220, 220, 220], + [255, 9, 92], [112, 9, 255], [8, 255, 214], [7, 255, 224], + [255, 184, 6], [10, 255, 71], [255, 41, 10], [7, 255, 255], + [224, 255, 8], [102, 8, 255], [255, 61, 6], [255, 194, 7], + [255, 122, 8], [0, 255, 20], [255, 8, 41], [255, 5, 153], + [6, 51, 255], [235, 12, 255], [160, 150, 20], [0, 163, 255], + [140, 140, 140], [250, 10, 15], [20, 255, 0], [31, 255, 0], + [255, 31, 0], [255, 224, 0], [153, 255, 0], [0, 0, 255], + [255, 71, 0], [0, 235, 255], [0, 173, 255], [31, 0, 255], + [11, 200, 200], [255, 82, 0], [0, 255, 245], [0, 61, 255], + [0, 255, 112], [0, 255, 133], [255, 0, 0], [255, 163, 0], + [255, 102, 0], [194, 255, 0], [0, 143, 255], [51, 255, 0], + [0, 82, 255], [0, 255, 41], [0, 255, 173], [10, 0, 255], + [173, 255, 0], [0, 255, 153], [255, 92, 0], [255, 0, 255], + [255, 0, 245], [255, 0, 102], [255, 173, 0], [255, 0, 20], + [255, 184, 184], [0, 31, 255], [0, 255, 61], [0, 71, 255], + [255, 0, 204], [0, 255, 194], [0, 255, 82], [0, 10, 255], + [0, 112, 255], [51, 0, 255], [0, 194, 255], [0, 122, 255], + [0, 255, 163], [255, 153, 0], [0, 255, 10], [255, 112, 0], + [143, 255, 0], [82, 0, 255], [163, 255, 0], [255, 235, 0], + [8, 184, 170], [133, 0, 255], [0, 255, 92], [184, 0, 255], + [255, 0, 31], [0, 184, 255], [0, 214, 255], [255, 0, 112], + [92, 255, 0], [0, 224, 255], [112, 224, 255], [70, 184, 160], + [163, 0, 255], [153, 0, 255], [71, 255, 0], [255, 0, 163], + [255, 204, 0], [255, 0, 143], [0, 255, 235], [133, 255, 0], + [255, 0, 235], [245, 0, 255], [255, 0, 122], [255, 245, 0], + [10, 190, 212], [214, 255, 0], [0, 204, 255], [20, 0, 255], + [255, 255, 0], [0, 153, 255], [0, 41, 255], [0, 255, 204], + [41, 0, 255], [41, 255, 0], [173, 0, 255], [0, 245, 255], + [71, 0, 255], [122, 0, 255], [0, 255, 184], [0, 92, 255], + [184, 255, 0], [0, 133, 255], [255, 214, 0], [25, 194, 194], + [102, 255, 0], [92, 0, 255]] + + +def voc_palette(): + """Pascal VOC palette for external use.""" + return [[0, 0, 0], [128, 0, 0], [0, 128, 0], [128, 128, 0], [0, 0, 128], + [128, 0, 128], [0, 128, 128], [128, 128, 128], [64, 0, 0], + [192, 0, 0], [64, 128, 0], [192, 128, 0], [64, 0, 128], + [192, 0, 128], [64, 128, 128], [192, 128, 128], [0, 64, 0], + [128, 64, 0], [0, 192, 0], [128, 192, 0], [0, 64, 128]] + + +dataset_aliases = { + 'cityscapes': ['cityscapes'], + 'ade': ['ade', 'ade20k'], + 'voc': ['voc', 'pascal_voc', 'voc12', 'voc12aug'] +} + + +def get_classes(dataset): + """Get class names of a dataset.""" + alias2name = {} + for name, aliases in dataset_aliases.items(): + for alias in aliases: + alias2name[alias] = name + + if mmcv.is_str(dataset): + if dataset in alias2name: + labels = eval(alias2name[dataset] + '_classes()') + else: + raise ValueError(f'Unrecognized dataset: {dataset}') + else: + raise TypeError(f'dataset must a str, but got {type(dataset)}') + return labels + + +def get_palette(dataset): + """Get class palette (RGB) of a dataset.""" + alias2name = {} + for name, aliases in dataset_aliases.items(): + for alias in aliases: + alias2name[alias] = name + + if mmcv.is_str(dataset): + if dataset in alias2name: + labels = eval(alias2name[dataset] + '_palette()') + else: + raise ValueError(f'Unrecognized dataset: {dataset}') + else: + raise TypeError(f'dataset must a str, but got {type(dataset)}') + return labels diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/evaluation/eval_hooks.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/evaluation/eval_hooks.py new file mode 100644 index 00000000..408e9670 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/evaluation/eval_hooks.py @@ -0,0 +1,109 @@ +import os.path as osp + +from annotator.mmpkg.mmcv.runner import DistEvalHook as _DistEvalHook +from annotator.mmpkg.mmcv.runner import EvalHook as _EvalHook + + +class EvalHook(_EvalHook): + """Single GPU EvalHook, with efficient test support. + + Args: + by_epoch (bool): Determine perform evaluation by epoch or by iteration. + If set to True, it will perform by epoch. Otherwise, by iteration. + Default: False. + efficient_test (bool): Whether save the results as local numpy files to + save CPU memory during evaluation. Default: False. + Returns: + list: The prediction results. + """ + + greater_keys = ['mIoU', 'mAcc', 'aAcc'] + + def __init__(self, *args, by_epoch=False, efficient_test=False, **kwargs): + super().__init__(*args, by_epoch=by_epoch, **kwargs) + self.efficient_test = efficient_test + + def after_train_iter(self, runner): + """After train epoch hook. + + Override default ``single_gpu_test``. + """ + if self.by_epoch or not self.every_n_iters(runner, self.interval): + return + from annotator.mmpkg.mmseg.apis import single_gpu_test + runner.log_buffer.clear() + results = single_gpu_test( + runner.model, + self.dataloader, + show=False, + efficient_test=self.efficient_test) + self.evaluate(runner, results) + + def after_train_epoch(self, runner): + """After train epoch hook. + + Override default ``single_gpu_test``. + """ + if not self.by_epoch or not self.every_n_epochs(runner, self.interval): + return + from annotator.mmpkg.mmseg.apis import single_gpu_test + runner.log_buffer.clear() + results = single_gpu_test(runner.model, self.dataloader, show=False) + self.evaluate(runner, results) + + +class DistEvalHook(_DistEvalHook): + """Distributed EvalHook, with efficient test support. + + Args: + by_epoch (bool): Determine perform evaluation by epoch or by iteration. + If set to True, it will perform by epoch. Otherwise, by iteration. + Default: False. + efficient_test (bool): Whether save the results as local numpy files to + save CPU memory during evaluation. Default: False. + Returns: + list: The prediction results. + """ + + greater_keys = ['mIoU', 'mAcc', 'aAcc'] + + def __init__(self, *args, by_epoch=False, efficient_test=False, **kwargs): + super().__init__(*args, by_epoch=by_epoch, **kwargs) + self.efficient_test = efficient_test + + def after_train_iter(self, runner): + """After train epoch hook. + + Override default ``multi_gpu_test``. + """ + if self.by_epoch or not self.every_n_iters(runner, self.interval): + return + from annotator.mmpkg.mmseg.apis import multi_gpu_test + runner.log_buffer.clear() + results = multi_gpu_test( + runner.model, + self.dataloader, + tmpdir=osp.join(runner.work_dir, '.eval_hook'), + gpu_collect=self.gpu_collect, + efficient_test=self.efficient_test) + if runner.rank == 0: + print('\n') + self.evaluate(runner, results) + + def after_train_epoch(self, runner): + """After train epoch hook. + + Override default ``multi_gpu_test``. + """ + if not self.by_epoch or not self.every_n_epochs(runner, self.interval): + return + from annotator.mmpkg.mmseg.apis import multi_gpu_test + runner.log_buffer.clear() + results = multi_gpu_test( + runner.model, + self.dataloader, + tmpdir=osp.join(runner.work_dir, '.eval_hook'), + gpu_collect=self.gpu_collect) + if runner.rank == 0: + print('\n') + self.evaluate(runner, results) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/evaluation/metrics.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/evaluation/metrics.py new file mode 100644 index 00000000..8ede7376 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/evaluation/metrics.py @@ -0,0 +1,326 @@ +from collections import OrderedDict + +import annotator.mmpkg.mmcv as mmcv +import numpy as np +import torch + + +def f_score(precision, recall, beta=1): + """calcuate the f-score value. + + Args: + precision (float | torch.Tensor): The precision value. + recall (float | torch.Tensor): The recall value. + beta (int): Determines the weight of recall in the combined score. + Default: False. + + Returns: + [torch.tensor]: The f-score value. + """ + score = (1 + beta**2) * (precision * recall) / ( + (beta**2 * precision) + recall) + return score + + +def intersect_and_union(pred_label, + label, + num_classes, + ignore_index, + label_map=dict(), + reduce_zero_label=False): + """Calculate intersection and Union. + + Args: + pred_label (ndarray | str): Prediction segmentation map + or predict result filename. + label (ndarray | str): Ground truth segmentation map + or label filename. + num_classes (int): Number of categories. + ignore_index (int): Index that will be ignored in evaluation. + label_map (dict): Mapping old labels to new labels. The parameter will + work only when label is str. Default: dict(). + reduce_zero_label (bool): Whether ignore zero label. The parameter will + work only when label is str. Default: False. + + Returns: + torch.Tensor: The intersection of prediction and ground truth + histogram on all classes. + torch.Tensor: The union of prediction and ground truth histogram on + all classes. + torch.Tensor: The prediction histogram on all classes. + torch.Tensor: The ground truth histogram on all classes. + """ + + if isinstance(pred_label, str): + pred_label = torch.from_numpy(np.load(pred_label)) + else: + pred_label = torch.from_numpy((pred_label)) + + if isinstance(label, str): + label = torch.from_numpy( + mmcv.imread(label, flag='unchanged', backend='pillow')) + else: + label = torch.from_numpy(label) + + if label_map is not None: + for old_id, new_id in label_map.items(): + label[label == old_id] = new_id + if reduce_zero_label: + label[label == 0] = 255 + label = label - 1 + label[label == 254] = 255 + + mask = (label != ignore_index) + pred_label = pred_label[mask] + label = label[mask] + + intersect = pred_label[pred_label == label] + area_intersect = torch.histc( + intersect.float(), bins=(num_classes), min=0, max=num_classes - 1) + area_pred_label = torch.histc( + pred_label.float(), bins=(num_classes), min=0, max=num_classes - 1) + area_label = torch.histc( + label.float(), bins=(num_classes), min=0, max=num_classes - 1) + area_union = area_pred_label + area_label - area_intersect + return area_intersect, area_union, area_pred_label, area_label + + +def total_intersect_and_union(results, + gt_seg_maps, + num_classes, + ignore_index, + label_map=dict(), + reduce_zero_label=False): + """Calculate Total Intersection and Union. + + Args: + results (list[ndarray] | list[str]): List of prediction segmentation + maps or list of prediction result filenames. + gt_seg_maps (list[ndarray] | list[str]): list of ground truth + segmentation maps or list of label filenames. + num_classes (int): Number of categories. + ignore_index (int): Index that will be ignored in evaluation. + label_map (dict): Mapping old labels to new labels. Default: dict(). + reduce_zero_label (bool): Whether ignore zero label. Default: False. + + Returns: + ndarray: The intersection of prediction and ground truth histogram + on all classes. + ndarray: The union of prediction and ground truth histogram on all + classes. + ndarray: The prediction histogram on all classes. + ndarray: The ground truth histogram on all classes. + """ + num_imgs = len(results) + assert len(gt_seg_maps) == num_imgs + total_area_intersect = torch.zeros((num_classes, ), dtype=torch.float64) + total_area_union = torch.zeros((num_classes, ), dtype=torch.float64) + total_area_pred_label = torch.zeros((num_classes, ), dtype=torch.float64) + total_area_label = torch.zeros((num_classes, ), dtype=torch.float64) + for i in range(num_imgs): + area_intersect, area_union, area_pred_label, area_label = \ + intersect_and_union( + results[i], gt_seg_maps[i], num_classes, ignore_index, + label_map, reduce_zero_label) + total_area_intersect += area_intersect + total_area_union += area_union + total_area_pred_label += area_pred_label + total_area_label += area_label + return total_area_intersect, total_area_union, total_area_pred_label, \ + total_area_label + + +def mean_iou(results, + gt_seg_maps, + num_classes, + ignore_index, + nan_to_num=None, + label_map=dict(), + reduce_zero_label=False): + """Calculate Mean Intersection and Union (mIoU) + + Args: + results (list[ndarray] | list[str]): List of prediction segmentation + maps or list of prediction result filenames. + gt_seg_maps (list[ndarray] | list[str]): list of ground truth + segmentation maps or list of label filenames. + num_classes (int): Number of categories. + ignore_index (int): Index that will be ignored in evaluation. + nan_to_num (int, optional): If specified, NaN values will be replaced + by the numbers defined by the user. Default: None. + label_map (dict): Mapping old labels to new labels. Default: dict(). + reduce_zero_label (bool): Whether ignore zero label. Default: False. + + Returns: + dict[str, float | ndarray]: + float: Overall accuracy on all images. + ndarray: Per category accuracy, shape (num_classes, ). + ndarray: Per category IoU, shape (num_classes, ). + """ + iou_result = eval_metrics( + results=results, + gt_seg_maps=gt_seg_maps, + num_classes=num_classes, + ignore_index=ignore_index, + metrics=['mIoU'], + nan_to_num=nan_to_num, + label_map=label_map, + reduce_zero_label=reduce_zero_label) + return iou_result + + +def mean_dice(results, + gt_seg_maps, + num_classes, + ignore_index, + nan_to_num=None, + label_map=dict(), + reduce_zero_label=False): + """Calculate Mean Dice (mDice) + + Args: + results (list[ndarray] | list[str]): List of prediction segmentation + maps or list of prediction result filenames. + gt_seg_maps (list[ndarray] | list[str]): list of ground truth + segmentation maps or list of label filenames. + num_classes (int): Number of categories. + ignore_index (int): Index that will be ignored in evaluation. + nan_to_num (int, optional): If specified, NaN values will be replaced + by the numbers defined by the user. Default: None. + label_map (dict): Mapping old labels to new labels. Default: dict(). + reduce_zero_label (bool): Whether ignore zero label. Default: False. + + Returns: + dict[str, float | ndarray]: Default metrics. + float: Overall accuracy on all images. + ndarray: Per category accuracy, shape (num_classes, ). + ndarray: Per category dice, shape (num_classes, ). + """ + + dice_result = eval_metrics( + results=results, + gt_seg_maps=gt_seg_maps, + num_classes=num_classes, + ignore_index=ignore_index, + metrics=['mDice'], + nan_to_num=nan_to_num, + label_map=label_map, + reduce_zero_label=reduce_zero_label) + return dice_result + + +def mean_fscore(results, + gt_seg_maps, + num_classes, + ignore_index, + nan_to_num=None, + label_map=dict(), + reduce_zero_label=False, + beta=1): + """Calculate Mean Intersection and Union (mIoU) + + Args: + results (list[ndarray] | list[str]): List of prediction segmentation + maps or list of prediction result filenames. + gt_seg_maps (list[ndarray] | list[str]): list of ground truth + segmentation maps or list of label filenames. + num_classes (int): Number of categories. + ignore_index (int): Index that will be ignored in evaluation. + nan_to_num (int, optional): If specified, NaN values will be replaced + by the numbers defined by the user. Default: None. + label_map (dict): Mapping old labels to new labels. Default: dict(). + reduce_zero_label (bool): Whether ignore zero label. Default: False. + beta (int): Determines the weight of recall in the combined score. + Default: False. + + + Returns: + dict[str, float | ndarray]: Default metrics. + float: Overall accuracy on all images. + ndarray: Per category recall, shape (num_classes, ). + ndarray: Per category precision, shape (num_classes, ). + ndarray: Per category f-score, shape (num_classes, ). + """ + fscore_result = eval_metrics( + results=results, + gt_seg_maps=gt_seg_maps, + num_classes=num_classes, + ignore_index=ignore_index, + metrics=['mFscore'], + nan_to_num=nan_to_num, + label_map=label_map, + reduce_zero_label=reduce_zero_label, + beta=beta) + return fscore_result + + +def eval_metrics(results, + gt_seg_maps, + num_classes, + ignore_index, + metrics=['mIoU'], + nan_to_num=None, + label_map=dict(), + reduce_zero_label=False, + beta=1): + """Calculate evaluation metrics + Args: + results (list[ndarray] | list[str]): List of prediction segmentation + maps or list of prediction result filenames. + gt_seg_maps (list[ndarray] | list[str]): list of ground truth + segmentation maps or list of label filenames. + num_classes (int): Number of categories. + ignore_index (int): Index that will be ignored in evaluation. + metrics (list[str] | str): Metrics to be evaluated, 'mIoU' and 'mDice'. + nan_to_num (int, optional): If specified, NaN values will be replaced + by the numbers defined by the user. Default: None. + label_map (dict): Mapping old labels to new labels. Default: dict(). + reduce_zero_label (bool): Whether ignore zero label. Default: False. + Returns: + float: Overall accuracy on all images. + ndarray: Per category accuracy, shape (num_classes, ). + ndarray: Per category evaluation metrics, shape (num_classes, ). + """ + if isinstance(metrics, str): + metrics = [metrics] + allowed_metrics = ['mIoU', 'mDice', 'mFscore'] + if not set(metrics).issubset(set(allowed_metrics)): + raise KeyError('metrics {} is not supported'.format(metrics)) + + total_area_intersect, total_area_union, total_area_pred_label, \ + total_area_label = total_intersect_and_union( + results, gt_seg_maps, num_classes, ignore_index, label_map, + reduce_zero_label) + all_acc = total_area_intersect.sum() / total_area_label.sum() + ret_metrics = OrderedDict({'aAcc': all_acc}) + for metric in metrics: + if metric == 'mIoU': + iou = total_area_intersect / total_area_union + acc = total_area_intersect / total_area_label + ret_metrics['IoU'] = iou + ret_metrics['Acc'] = acc + elif metric == 'mDice': + dice = 2 * total_area_intersect / ( + total_area_pred_label + total_area_label) + acc = total_area_intersect / total_area_label + ret_metrics['Dice'] = dice + ret_metrics['Acc'] = acc + elif metric == 'mFscore': + precision = total_area_intersect / total_area_pred_label + recall = total_area_intersect / total_area_label + f_value = torch.tensor( + [f_score(x[0], x[1], beta) for x in zip(precision, recall)]) + ret_metrics['Fscore'] = f_value + ret_metrics['Precision'] = precision + ret_metrics['Recall'] = recall + + ret_metrics = { + metric: value.numpy() + for metric, value in ret_metrics.items() + } + if nan_to_num is not None: + ret_metrics = OrderedDict({ + metric: np.nan_to_num(metric_value, nan=nan_to_num) + for metric, metric_value in ret_metrics.items() + }) + return ret_metrics diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/__init__.py new file mode 100644 index 00000000..93bc129b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/__init__.py @@ -0,0 +1,4 @@ +from .builder import build_pixel_sampler +from .sampler import BasePixelSampler, OHEMPixelSampler + +__all__ = ['build_pixel_sampler', 'BasePixelSampler', 'OHEMPixelSampler'] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/builder.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/builder.py new file mode 100644 index 00000000..f8fff637 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/builder.py @@ -0,0 +1,8 @@ +from annotator.mmpkg.mmcv.utils import Registry, build_from_cfg + +PIXEL_SAMPLERS = Registry('pixel sampler') + + +def build_pixel_sampler(cfg, **default_args): + """Build pixel sampler for segmentation map.""" + return build_from_cfg(cfg, PIXEL_SAMPLERS, default_args) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/sampler/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/sampler/__init__.py new file mode 100644 index 00000000..332b242c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/sampler/__init__.py @@ -0,0 +1,4 @@ +from .base_pixel_sampler import BasePixelSampler +from .ohem_pixel_sampler import OHEMPixelSampler + +__all__ = ['BasePixelSampler', 'OHEMPixelSampler'] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/sampler/base_pixel_sampler.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/sampler/base_pixel_sampler.py new file mode 100644 index 00000000..b75b1566 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/sampler/base_pixel_sampler.py @@ -0,0 +1,12 @@ +from abc import ABCMeta, abstractmethod + + +class BasePixelSampler(metaclass=ABCMeta): + """Base class of pixel sampler.""" + + def __init__(self, **kwargs): + pass + + @abstractmethod + def sample(self, seg_logit, seg_label): + """Placeholder for sample function.""" diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/sampler/ohem_pixel_sampler.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/sampler/ohem_pixel_sampler.py new file mode 100644 index 00000000..88bb10d4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/seg/sampler/ohem_pixel_sampler.py @@ -0,0 +1,76 @@ +import torch +import torch.nn.functional as F + +from ..builder import PIXEL_SAMPLERS +from .base_pixel_sampler import BasePixelSampler + + +@PIXEL_SAMPLERS.register_module() +class OHEMPixelSampler(BasePixelSampler): + """Online Hard Example Mining Sampler for segmentation. + + Args: + context (nn.Module): The context of sampler, subclass of + :obj:`BaseDecodeHead`. + thresh (float, optional): The threshold for hard example selection. + Below which, are prediction with low confidence. If not + specified, the hard examples will be pixels of top ``min_kept`` + loss. Default: None. + min_kept (int, optional): The minimum number of predictions to keep. + Default: 100000. + """ + + def __init__(self, context, thresh=None, min_kept=100000): + super(OHEMPixelSampler, self).__init__() + self.context = context + assert min_kept > 1 + self.thresh = thresh + self.min_kept = min_kept + + def sample(self, seg_logit, seg_label): + """Sample pixels that have high loss or with low prediction confidence. + + Args: + seg_logit (torch.Tensor): segmentation logits, shape (N, C, H, W) + seg_label (torch.Tensor): segmentation label, shape (N, 1, H, W) + + Returns: + torch.Tensor: segmentation weight, shape (N, H, W) + """ + with torch.no_grad(): + assert seg_logit.shape[2:] == seg_label.shape[2:] + assert seg_label.shape[1] == 1 + seg_label = seg_label.squeeze(1).long() + batch_kept = self.min_kept * seg_label.size(0) + valid_mask = seg_label != self.context.ignore_index + seg_weight = seg_logit.new_zeros(size=seg_label.size()) + valid_seg_weight = seg_weight[valid_mask] + if self.thresh is not None: + seg_prob = F.softmax(seg_logit, dim=1) + + tmp_seg_label = seg_label.clone().unsqueeze(1) + tmp_seg_label[tmp_seg_label == self.context.ignore_index] = 0 + seg_prob = seg_prob.gather(1, tmp_seg_label).squeeze(1) + sort_prob, sort_indices = seg_prob[valid_mask].sort() + + if sort_prob.numel() > 0: + min_threshold = sort_prob[min(batch_kept, + sort_prob.numel() - 1)] + else: + min_threshold = 0.0 + threshold = max(min_threshold, self.thresh) + valid_seg_weight[seg_prob[valid_mask] < threshold] = 1. + else: + losses = self.context.loss_decode( + seg_logit, + seg_label, + weight=None, + ignore_index=self.context.ignore_index, + reduction_override='none') + # faster than topk according to https://github.com/pytorch/pytorch/issues/22812 # noqa + _, sort_indices = losses[valid_mask].sort(descending=True) + valid_seg_weight[sort_indices[:batch_kept]] = 1. + + seg_weight[valid_mask] = valid_seg_weight + + return seg_weight diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/utils/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/utils/__init__.py new file mode 100644 index 00000000..f2678b32 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/utils/__init__.py @@ -0,0 +1,3 @@ +from .misc import add_prefix + +__all__ = ['add_prefix'] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/utils/misc.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/utils/misc.py new file mode 100644 index 00000000..eb862a82 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/core/utils/misc.py @@ -0,0 +1,17 @@ +def add_prefix(inputs, prefix): + """Add prefix for dict. + + Args: + inputs (dict): The input dict with str keys. + prefix (str): The prefix to add. + + Returns: + + dict: The dict with keys updated with ``prefix``. + """ + + outputs = dict() + for name, value in inputs.items(): + outputs[f'{prefix}.{name}'] = value + + return outputs diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/__init__.py new file mode 100644 index 00000000..ebeaef4a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/__init__.py @@ -0,0 +1,19 @@ +from .ade import ADE20KDataset +from .builder import DATASETS, PIPELINES, build_dataloader, build_dataset +from .chase_db1 import ChaseDB1Dataset +from .cityscapes import CityscapesDataset +from .custom import CustomDataset +from .dataset_wrappers import ConcatDataset, RepeatDataset +from .drive import DRIVEDataset +from .hrf import HRFDataset +from .pascal_context import PascalContextDataset, PascalContextDataset59 +from .stare import STAREDataset +from .voc import PascalVOCDataset + +__all__ = [ + 'CustomDataset', 'build_dataloader', 'ConcatDataset', 'RepeatDataset', + 'DATASETS', 'build_dataset', 'PIPELINES', 'CityscapesDataset', + 'PascalVOCDataset', 'ADE20KDataset', 'PascalContextDataset', + 'PascalContextDataset59', 'ChaseDB1Dataset', 'DRIVEDataset', 'HRFDataset', + 'STAREDataset' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/ade.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/ade.py new file mode 100644 index 00000000..5913e437 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/ade.py @@ -0,0 +1,84 @@ +from .builder import DATASETS +from .custom import CustomDataset + + +@DATASETS.register_module() +class ADE20KDataset(CustomDataset): + """ADE20K dataset. + + In segmentation map annotation for ADE20K, 0 stands for background, which + is not included in 150 categories. ``reduce_zero_label`` is fixed to True. + The ``img_suffix`` is fixed to '.jpg' and ``seg_map_suffix`` is fixed to + '.png'. + """ + CLASSES = ( + 'wall', 'building', 'sky', 'floor', 'tree', 'ceiling', 'road', 'bed ', + 'windowpane', 'grass', 'cabinet', 'sidewalk', 'person', 'earth', + 'door', 'table', 'mountain', 'plant', 'curtain', 'chair', 'car', + 'water', 'painting', 'sofa', 'shelf', 'house', 'sea', 'mirror', 'rug', + 'field', 'armchair', 'seat', 'fence', 'desk', 'rock', 'wardrobe', + 'lamp', 'bathtub', 'railing', 'cushion', 'base', 'box', 'column', + 'signboard', 'chest of drawers', 'counter', 'sand', 'sink', + 'skyscraper', 'fireplace', 'refrigerator', 'grandstand', 'path', + 'stairs', 'runway', 'case', 'pool table', 'pillow', 'screen door', + 'stairway', 'river', 'bridge', 'bookcase', 'blind', 'coffee table', + 'toilet', 'flower', 'book', 'hill', 'bench', 'countertop', 'stove', + 'palm', 'kitchen island', 'computer', 'swivel chair', 'boat', 'bar', + 'arcade machine', 'hovel', 'bus', 'towel', 'light', 'truck', 'tower', + 'chandelier', 'awning', 'streetlight', 'booth', 'television receiver', + 'airplane', 'dirt track', 'apparel', 'pole', 'land', 'bannister', + 'escalator', 'ottoman', 'bottle', 'buffet', 'poster', 'stage', 'van', + 'ship', 'fountain', 'conveyer belt', 'canopy', 'washer', 'plaything', + 'swimming pool', 'stool', 'barrel', 'basket', 'waterfall', 'tent', + 'bag', 'minibike', 'cradle', 'oven', 'ball', 'food', 'step', 'tank', + 'trade name', 'microwave', 'pot', 'animal', 'bicycle', 'lake', + 'dishwasher', 'screen', 'blanket', 'sculpture', 'hood', 'sconce', + 'vase', 'traffic light', 'tray', 'ashcan', 'fan', 'pier', 'crt screen', + 'plate', 'monitor', 'bulletin board', 'shower', 'radiator', 'glass', + 'clock', 'flag') + + PALETTE = [[120, 120, 120], [180, 120, 120], [6, 230, 230], [80, 50, 50], + [4, 200, 3], [120, 120, 80], [140, 140, 140], [204, 5, 255], + [230, 230, 230], [4, 250, 7], [224, 5, 255], [235, 255, 7], + [150, 5, 61], [120, 120, 70], [8, 255, 51], [255, 6, 82], + [143, 255, 140], [204, 255, 4], [255, 51, 7], [204, 70, 3], + [0, 102, 200], [61, 230, 250], [255, 6, 51], [11, 102, 255], + [255, 7, 71], [255, 9, 224], [9, 7, 230], [220, 220, 220], + [255, 9, 92], [112, 9, 255], [8, 255, 214], [7, 255, 224], + [255, 184, 6], [10, 255, 71], [255, 41, 10], [7, 255, 255], + [224, 255, 8], [102, 8, 255], [255, 61, 6], [255, 194, 7], + [255, 122, 8], [0, 255, 20], [255, 8, 41], [255, 5, 153], + [6, 51, 255], [235, 12, 255], [160, 150, 20], [0, 163, 255], + [140, 140, 140], [250, 10, 15], [20, 255, 0], [31, 255, 0], + [255, 31, 0], [255, 224, 0], [153, 255, 0], [0, 0, 255], + [255, 71, 0], [0, 235, 255], [0, 173, 255], [31, 0, 255], + [11, 200, 200], [255, 82, 0], [0, 255, 245], [0, 61, 255], + [0, 255, 112], [0, 255, 133], [255, 0, 0], [255, 163, 0], + [255, 102, 0], [194, 255, 0], [0, 143, 255], [51, 255, 0], + [0, 82, 255], [0, 255, 41], [0, 255, 173], [10, 0, 255], + [173, 255, 0], [0, 255, 153], [255, 92, 0], [255, 0, 255], + [255, 0, 245], [255, 0, 102], [255, 173, 0], [255, 0, 20], + [255, 184, 184], [0, 31, 255], [0, 255, 61], [0, 71, 255], + [255, 0, 204], [0, 255, 194], [0, 255, 82], [0, 10, 255], + [0, 112, 255], [51, 0, 255], [0, 194, 255], [0, 122, 255], + [0, 255, 163], [255, 153, 0], [0, 255, 10], [255, 112, 0], + [143, 255, 0], [82, 0, 255], [163, 255, 0], [255, 235, 0], + [8, 184, 170], [133, 0, 255], [0, 255, 92], [184, 0, 255], + [255, 0, 31], [0, 184, 255], [0, 214, 255], [255, 0, 112], + [92, 255, 0], [0, 224, 255], [112, 224, 255], [70, 184, 160], + [163, 0, 255], [153, 0, 255], [71, 255, 0], [255, 0, 163], + [255, 204, 0], [255, 0, 143], [0, 255, 235], [133, 255, 0], + [255, 0, 235], [245, 0, 255], [255, 0, 122], [255, 245, 0], + [10, 190, 212], [214, 255, 0], [0, 204, 255], [20, 0, 255], + [255, 255, 0], [0, 153, 255], [0, 41, 255], [0, 255, 204], + [41, 0, 255], [41, 255, 0], [173, 0, 255], [0, 245, 255], + [71, 0, 255], [122, 0, 255], [0, 255, 184], [0, 92, 255], + [184, 255, 0], [0, 133, 255], [255, 214, 0], [25, 194, 194], + [102, 255, 0], [92, 0, 255]] + + def __init__(self, **kwargs): + super(ADE20KDataset, self).__init__( + img_suffix='.jpg', + seg_map_suffix='.png', + reduce_zero_label=True, + **kwargs) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/builder.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/builder.py new file mode 100644 index 00000000..6cf8b4d9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/builder.py @@ -0,0 +1,169 @@ +import copy +import platform +import random +from functools import partial + +import numpy as np +from annotator.mmpkg.mmcv.parallel import collate +from annotator.mmpkg.mmcv.runner import get_dist_info +from annotator.mmpkg.mmcv.utils import Registry, build_from_cfg +from annotator.mmpkg.mmcv.utils.parrots_wrapper import DataLoader, PoolDataLoader +from torch.utils.data import DistributedSampler + +if platform.system() != 'Windows': + # https://github.com/pytorch/pytorch/issues/973 + import resource + rlimit = resource.getrlimit(resource.RLIMIT_NOFILE) + hard_limit = rlimit[1] + soft_limit = min(4096, hard_limit) + resource.setrlimit(resource.RLIMIT_NOFILE, (soft_limit, hard_limit)) + +DATASETS = Registry('dataset') +PIPELINES = Registry('pipeline') + + +def _concat_dataset(cfg, default_args=None): + """Build :obj:`ConcatDataset by.""" + from .dataset_wrappers import ConcatDataset + img_dir = cfg['img_dir'] + ann_dir = cfg.get('ann_dir', None) + split = cfg.get('split', None) + num_img_dir = len(img_dir) if isinstance(img_dir, (list, tuple)) else 1 + if ann_dir is not None: + num_ann_dir = len(ann_dir) if isinstance(ann_dir, (list, tuple)) else 1 + else: + num_ann_dir = 0 + if split is not None: + num_split = len(split) if isinstance(split, (list, tuple)) else 1 + else: + num_split = 0 + if num_img_dir > 1: + assert num_img_dir == num_ann_dir or num_ann_dir == 0 + assert num_img_dir == num_split or num_split == 0 + else: + assert num_split == num_ann_dir or num_ann_dir <= 1 + num_dset = max(num_split, num_img_dir) + + datasets = [] + for i in range(num_dset): + data_cfg = copy.deepcopy(cfg) + if isinstance(img_dir, (list, tuple)): + data_cfg['img_dir'] = img_dir[i] + if isinstance(ann_dir, (list, tuple)): + data_cfg['ann_dir'] = ann_dir[i] + if isinstance(split, (list, tuple)): + data_cfg['split'] = split[i] + datasets.append(build_dataset(data_cfg, default_args)) + + return ConcatDataset(datasets) + + +def build_dataset(cfg, default_args=None): + """Build datasets.""" + from .dataset_wrappers import ConcatDataset, RepeatDataset + if isinstance(cfg, (list, tuple)): + dataset = ConcatDataset([build_dataset(c, default_args) for c in cfg]) + elif cfg['type'] == 'RepeatDataset': + dataset = RepeatDataset( + build_dataset(cfg['dataset'], default_args), cfg['times']) + elif isinstance(cfg.get('img_dir'), (list, tuple)) or isinstance( + cfg.get('split', None), (list, tuple)): + dataset = _concat_dataset(cfg, default_args) + else: + dataset = build_from_cfg(cfg, DATASETS, default_args) + + return dataset + + +def build_dataloader(dataset, + samples_per_gpu, + workers_per_gpu, + num_gpus=1, + dist=True, + shuffle=True, + seed=None, + drop_last=False, + pin_memory=True, + dataloader_type='PoolDataLoader', + **kwargs): + """Build PyTorch DataLoader. + + In distributed training, each GPU/process has a dataloader. + In non-distributed training, there is only one dataloader for all GPUs. + + Args: + dataset (Dataset): A PyTorch dataset. + samples_per_gpu (int): Number of training samples on each GPU, i.e., + batch size of each GPU. + workers_per_gpu (int): How many subprocesses to use for data loading + for each GPU. + num_gpus (int): Number of GPUs. Only used in non-distributed training. + dist (bool): Distributed training/test or not. Default: True. + shuffle (bool): Whether to shuffle the data at every epoch. + Default: True. + seed (int | None): Seed to be used. Default: None. + drop_last (bool): Whether to drop the last incomplete batch in epoch. + Default: False + pin_memory (bool): Whether to use pin_memory in DataLoader. + Default: True + dataloader_type (str): Type of dataloader. Default: 'PoolDataLoader' + kwargs: any keyword argument to be used to initialize DataLoader + + Returns: + DataLoader: A PyTorch dataloader. + """ + rank, world_size = get_dist_info() + if dist: + sampler = DistributedSampler( + dataset, world_size, rank, shuffle=shuffle) + shuffle = False + batch_size = samples_per_gpu + num_workers = workers_per_gpu + else: + sampler = None + batch_size = num_gpus * samples_per_gpu + num_workers = num_gpus * workers_per_gpu + + init_fn = partial( + worker_init_fn, num_workers=num_workers, rank=rank, + seed=seed) if seed is not None else None + + assert dataloader_type in ( + 'DataLoader', + 'PoolDataLoader'), f'unsupported dataloader {dataloader_type}' + + if dataloader_type == 'PoolDataLoader': + dataloader = PoolDataLoader + elif dataloader_type == 'DataLoader': + dataloader = DataLoader + + data_loader = dataloader( + dataset, + batch_size=batch_size, + sampler=sampler, + num_workers=num_workers, + collate_fn=partial(collate, samples_per_gpu=samples_per_gpu), + pin_memory=pin_memory, + shuffle=shuffle, + worker_init_fn=init_fn, + drop_last=drop_last, + **kwargs) + + return data_loader + + +def worker_init_fn(worker_id, num_workers, rank, seed): + """Worker init func for dataloader. + + The seed of each worker equals to num_worker * rank + worker_id + user_seed + + Args: + worker_id (int): Worker id. + num_workers (int): Number of workers. + rank (int): The rank of current process. + seed (int): The random seed to use. + """ + + worker_seed = num_workers * rank + worker_id + seed + np.random.seed(worker_seed) + random.seed(worker_seed) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/chase_db1.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/chase_db1.py new file mode 100644 index 00000000..8bc29bea --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/chase_db1.py @@ -0,0 +1,27 @@ +import os.path as osp + +from .builder import DATASETS +from .custom import CustomDataset + + +@DATASETS.register_module() +class ChaseDB1Dataset(CustomDataset): + """Chase_db1 dataset. + + In segmentation map annotation for Chase_db1, 0 stands for background, + which is included in 2 categories. ``reduce_zero_label`` is fixed to False. + The ``img_suffix`` is fixed to '.png' and ``seg_map_suffix`` is fixed to + '_1stHO.png'. + """ + + CLASSES = ('background', 'vessel') + + PALETTE = [[120, 120, 120], [6, 230, 230]] + + def __init__(self, **kwargs): + super(ChaseDB1Dataset, self).__init__( + img_suffix='.png', + seg_map_suffix='_1stHO.png', + reduce_zero_label=False, + **kwargs) + assert osp.exists(self.img_dir) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/cityscapes.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/cityscapes.py new file mode 100644 index 00000000..38f80e80 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/cityscapes.py @@ -0,0 +1,217 @@ +import os.path as osp +import tempfile + +import annotator.mmpkg.mmcv as mmcv +import numpy as np +from annotator.mmpkg.mmcv.utils import print_log +from PIL import Image + +from .builder import DATASETS +from .custom import CustomDataset + + +@DATASETS.register_module() +class CityscapesDataset(CustomDataset): + """Cityscapes dataset. + + The ``img_suffix`` is fixed to '_leftImg8bit.png' and ``seg_map_suffix`` is + fixed to '_gtFine_labelTrainIds.png' for Cityscapes dataset. + """ + + CLASSES = ('road', 'sidewalk', 'building', 'wall', 'fence', 'pole', + 'traffic light', 'traffic sign', 'vegetation', 'terrain', 'sky', + 'person', 'rider', 'car', 'truck', 'bus', 'train', 'motorcycle', + 'bicycle') + + PALETTE = [[128, 64, 128], [244, 35, 232], [70, 70, 70], [102, 102, 156], + [190, 153, 153], [153, 153, 153], [250, 170, 30], [220, 220, 0], + [107, 142, 35], [152, 251, 152], [70, 130, 180], [220, 20, 60], + [255, 0, 0], [0, 0, 142], [0, 0, 70], [0, 60, 100], + [0, 80, 100], [0, 0, 230], [119, 11, 32]] + + def __init__(self, **kwargs): + super(CityscapesDataset, self).__init__( + img_suffix='_leftImg8bit.png', + seg_map_suffix='_gtFine_labelTrainIds.png', + **kwargs) + + @staticmethod + def _convert_to_label_id(result): + """Convert trainId to id for cityscapes.""" + if isinstance(result, str): + result = np.load(result) + import cityscapesscripts.helpers.labels as CSLabels + result_copy = result.copy() + for trainId, label in CSLabels.trainId2label.items(): + result_copy[result == trainId] = label.id + + return result_copy + + def results2img(self, results, imgfile_prefix, to_label_id): + """Write the segmentation results to images. + + Args: + results (list[list | tuple | ndarray]): Testing results of the + dataset. + imgfile_prefix (str): The filename prefix of the png files. + If the prefix is "somepath/xxx", + the png files will be named "somepath/xxx.png". + to_label_id (bool): whether convert output to label_id for + submission + + Returns: + list[str: str]: result txt files which contains corresponding + semantic segmentation images. + """ + mmcv.mkdir_or_exist(imgfile_prefix) + result_files = [] + prog_bar = mmcv.ProgressBar(len(self)) + for idx in range(len(self)): + result = results[idx] + if to_label_id: + result = self._convert_to_label_id(result) + filename = self.img_infos[idx]['filename'] + basename = osp.splitext(osp.basename(filename))[0] + + png_filename = osp.join(imgfile_prefix, f'{basename}.png') + + output = Image.fromarray(result.astype(np.uint8)).convert('P') + import cityscapesscripts.helpers.labels as CSLabels + palette = np.zeros((len(CSLabels.id2label), 3), dtype=np.uint8) + for label_id, label in CSLabels.id2label.items(): + palette[label_id] = label.color + + output.putpalette(palette) + output.save(png_filename) + result_files.append(png_filename) + prog_bar.update() + + return result_files + + def format_results(self, results, imgfile_prefix=None, to_label_id=True): + """Format the results into dir (standard format for Cityscapes + evaluation). + + Args: + results (list): Testing results of the dataset. + imgfile_prefix (str | None): The prefix of images files. It + includes the file path and the prefix of filename, e.g., + "a/b/prefix". If not specified, a temp file will be created. + Default: None. + to_label_id (bool): whether convert output to label_id for + submission. Default: False + + Returns: + tuple: (result_files, tmp_dir), result_files is a list containing + the image paths, tmp_dir is the temporal directory created + for saving json/png files when img_prefix is not specified. + """ + + assert isinstance(results, list), 'results must be a list' + assert len(results) == len(self), ( + 'The length of results is not equal to the dataset len: ' + f'{len(results)} != {len(self)}') + + if imgfile_prefix is None: + tmp_dir = tempfile.TemporaryDirectory() + imgfile_prefix = tmp_dir.name + else: + tmp_dir = None + result_files = self.results2img(results, imgfile_prefix, to_label_id) + + return result_files, tmp_dir + + def evaluate(self, + results, + metric='mIoU', + logger=None, + imgfile_prefix=None, + efficient_test=False): + """Evaluation in Cityscapes/default protocol. + + Args: + results (list): Testing results of the dataset. + metric (str | list[str]): Metrics to be evaluated. + logger (logging.Logger | None | str): Logger used for printing + related information during evaluation. Default: None. + imgfile_prefix (str | None): The prefix of output image file, + for cityscapes evaluation only. It includes the file path and + the prefix of filename, e.g., "a/b/prefix". + If results are evaluated with cityscapes protocol, it would be + the prefix of output png files. The output files would be + png images under folder "a/b/prefix/xxx.png", where "xxx" is + the image name of cityscapes. If not specified, a temp file + will be created for evaluation. + Default: None. + + Returns: + dict[str, float]: Cityscapes/default metrics. + """ + + eval_results = dict() + metrics = metric.copy() if isinstance(metric, list) else [metric] + if 'cityscapes' in metrics: + eval_results.update( + self._evaluate_cityscapes(results, logger, imgfile_prefix)) + metrics.remove('cityscapes') + if len(metrics) > 0: + eval_results.update( + super(CityscapesDataset, + self).evaluate(results, metrics, logger, efficient_test)) + + return eval_results + + def _evaluate_cityscapes(self, results, logger, imgfile_prefix): + """Evaluation in Cityscapes protocol. + + Args: + results (list): Testing results of the dataset. + logger (logging.Logger | str | None): Logger used for printing + related information during evaluation. Default: None. + imgfile_prefix (str | None): The prefix of output image file + + Returns: + dict[str: float]: Cityscapes evaluation results. + """ + try: + import cityscapesscripts.evaluation.evalPixelLevelSemanticLabeling as CSEval # noqa + except ImportError: + raise ImportError('Please run "pip install cityscapesscripts" to ' + 'install cityscapesscripts first.') + msg = 'Evaluating in Cityscapes style' + if logger is None: + msg = '\n' + msg + print_log(msg, logger=logger) + + result_files, tmp_dir = self.format_results(results, imgfile_prefix) + + if tmp_dir is None: + result_dir = imgfile_prefix + else: + result_dir = tmp_dir.name + + eval_results = dict() + print_log(f'Evaluating results under {result_dir} ...', logger=logger) + + CSEval.args.evalInstLevelScore = True + CSEval.args.predictionPath = osp.abspath(result_dir) + CSEval.args.evalPixelAccuracy = True + CSEval.args.JSONOutput = False + + seg_map_list = [] + pred_list = [] + + # when evaluating with official cityscapesscripts, + # **_gtFine_labelIds.png is used + for seg_map in mmcv.scandir( + self.ann_dir, 'gtFine_labelIds.png', recursive=True): + seg_map_list.append(osp.join(self.ann_dir, seg_map)) + pred_list.append(CSEval.getPrediction(CSEval.args, seg_map)) + + eval_results.update( + CSEval.evaluateImgLists(pred_list, seg_map_list, CSEval.args)) + + if tmp_dir is not None: + tmp_dir.cleanup() + + return eval_results diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/custom.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/custom.py new file mode 100644 index 00000000..3a626976 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/custom.py @@ -0,0 +1,403 @@ +import os +import os.path as osp +from collections import OrderedDict +from functools import reduce + +import annotator.mmpkg.mmcv as mmcv +import numpy as np +from annotator.mmpkg.mmcv.utils import print_log +from torch.utils.data import Dataset + +from annotator.mmpkg.mmseg.core import eval_metrics +from annotator.mmpkg.mmseg.utils import get_root_logger +from .builder import DATASETS +from .pipelines import Compose + + +@DATASETS.register_module() +class CustomDataset(Dataset): + """Custom dataset for semantic segmentation. An example of file structure + is as followed. + + .. code-block:: none + + ├── data + │ ├── my_dataset + │ │ ├── img_dir + │ │ │ ├── train + │ │ │ │ ├── xxx{img_suffix} + │ │ │ │ ├── yyy{img_suffix} + │ │ │ │ ├── zzz{img_suffix} + │ │ │ ├── val + │ │ ├── ann_dir + │ │ │ ├── train + │ │ │ │ ├── xxx{seg_map_suffix} + │ │ │ │ ├── yyy{seg_map_suffix} + │ │ │ │ ├── zzz{seg_map_suffix} + │ │ │ ├── val + + The img/gt_semantic_seg pair of CustomDataset should be of the same + except suffix. A valid img/gt_semantic_seg filename pair should be like + ``xxx{img_suffix}`` and ``xxx{seg_map_suffix}`` (extension is also included + in the suffix). If split is given, then ``xxx`` is specified in txt file. + Otherwise, all files in ``img_dir/``and ``ann_dir`` will be loaded. + Please refer to ``docs/tutorials/new_dataset.md`` for more details. + + + Args: + pipeline (list[dict]): Processing pipeline + img_dir (str): Path to image directory + img_suffix (str): Suffix of images. Default: '.jpg' + ann_dir (str, optional): Path to annotation directory. Default: None + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + split (str, optional): Split txt file. If split is specified, only + file with suffix in the splits will be loaded. Otherwise, all + images in img_dir/ann_dir will be loaded. Default: None + data_root (str, optional): Data root for img_dir/ann_dir. Default: + None. + test_mode (bool): If test_mode=True, gt wouldn't be loaded. + ignore_index (int): The label index to be ignored. Default: 255 + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default: False + classes (str | Sequence[str], optional): Specify classes to load. + If is None, ``cls.CLASSES`` will be used. Default: None. + palette (Sequence[Sequence[int]]] | np.ndarray | None): + The palette of segmentation map. If None is given, and + self.PALETTE is None, random palette will be generated. + Default: None + """ + + CLASSES = None + + PALETTE = None + + def __init__(self, + pipeline, + img_dir, + img_suffix='.jpg', + ann_dir=None, + seg_map_suffix='.png', + split=None, + data_root=None, + test_mode=False, + ignore_index=255, + reduce_zero_label=False, + classes=None, + palette=None): + self.pipeline = Compose(pipeline) + self.img_dir = img_dir + self.img_suffix = img_suffix + self.ann_dir = ann_dir + self.seg_map_suffix = seg_map_suffix + self.split = split + self.data_root = data_root + self.test_mode = test_mode + self.ignore_index = ignore_index + self.reduce_zero_label = reduce_zero_label + self.label_map = None + self.CLASSES, self.PALETTE = self.get_classes_and_palette( + classes, palette) + + # join paths if data_root is specified + if self.data_root is not None: + if not osp.isabs(self.img_dir): + self.img_dir = osp.join(self.data_root, self.img_dir) + if not (self.ann_dir is None or osp.isabs(self.ann_dir)): + self.ann_dir = osp.join(self.data_root, self.ann_dir) + if not (self.split is None or osp.isabs(self.split)): + self.split = osp.join(self.data_root, self.split) + + # load annotations + self.img_infos = self.load_annotations(self.img_dir, self.img_suffix, + self.ann_dir, + self.seg_map_suffix, self.split) + + def __len__(self): + """Total number of samples of data.""" + return len(self.img_infos) + + def load_annotations(self, img_dir, img_suffix, ann_dir, seg_map_suffix, + split): + """Load annotation from directory. + + Args: + img_dir (str): Path to image directory + img_suffix (str): Suffix of images. + ann_dir (str|None): Path to annotation directory. + seg_map_suffix (str|None): Suffix of segmentation maps. + split (str|None): Split txt file. If split is specified, only file + with suffix in the splits will be loaded. Otherwise, all images + in img_dir/ann_dir will be loaded. Default: None + + Returns: + list[dict]: All image info of dataset. + """ + + img_infos = [] + if split is not None: + with open(split) as f: + for line in f: + img_name = line.strip() + img_info = dict(filename=img_name + img_suffix) + if ann_dir is not None: + seg_map = img_name + seg_map_suffix + img_info['ann'] = dict(seg_map=seg_map) + img_infos.append(img_info) + else: + for img in mmcv.scandir(img_dir, img_suffix, recursive=True): + img_info = dict(filename=img) + if ann_dir is not None: + seg_map = img.replace(img_suffix, seg_map_suffix) + img_info['ann'] = dict(seg_map=seg_map) + img_infos.append(img_info) + + print_log(f'Loaded {len(img_infos)} images', logger=get_root_logger()) + return img_infos + + def get_ann_info(self, idx): + """Get annotation by index. + + Args: + idx (int): Index of data. + + Returns: + dict: Annotation info of specified index. + """ + + return self.img_infos[idx]['ann'] + + def pre_pipeline(self, results): + """Prepare results dict for pipeline.""" + results['seg_fields'] = [] + results['img_prefix'] = self.img_dir + results['seg_prefix'] = self.ann_dir + if self.custom_classes: + results['label_map'] = self.label_map + + def __getitem__(self, idx): + """Get training/test data after pipeline. + + Args: + idx (int): Index of data. + + Returns: + dict: Training/test data (with annotation if `test_mode` is set + False). + """ + + if self.test_mode: + return self.prepare_test_img(idx) + else: + return self.prepare_train_img(idx) + + def prepare_train_img(self, idx): + """Get training data and annotations after pipeline. + + Args: + idx (int): Index of data. + + Returns: + dict: Training data and annotation after pipeline with new keys + introduced by pipeline. + """ + + img_info = self.img_infos[idx] + ann_info = self.get_ann_info(idx) + results = dict(img_info=img_info, ann_info=ann_info) + self.pre_pipeline(results) + return self.pipeline(results) + + def prepare_test_img(self, idx): + """Get testing data after pipeline. + + Args: + idx (int): Index of data. + + Returns: + dict: Testing data after pipeline with new keys introduced by + pipeline. + """ + + img_info = self.img_infos[idx] + results = dict(img_info=img_info) + self.pre_pipeline(results) + return self.pipeline(results) + + def format_results(self, results, **kwargs): + """Place holder to format result to dataset specific output.""" + + def get_gt_seg_maps(self, efficient_test=False): + """Get ground truth segmentation maps for evaluation.""" + gt_seg_maps = [] + for img_info in self.img_infos: + seg_map = osp.join(self.ann_dir, img_info['ann']['seg_map']) + if efficient_test: + gt_seg_map = seg_map + else: + gt_seg_map = mmcv.imread( + seg_map, flag='unchanged', backend='pillow') + gt_seg_maps.append(gt_seg_map) + return gt_seg_maps + + def get_classes_and_palette(self, classes=None, palette=None): + """Get class names of current dataset. + + Args: + classes (Sequence[str] | str | None): If classes is None, use + default CLASSES defined by builtin dataset. If classes is a + string, take it as a file name. The file contains the name of + classes where each line contains one class name. If classes is + a tuple or list, override the CLASSES defined by the dataset. + palette (Sequence[Sequence[int]]] | np.ndarray | None): + The palette of segmentation map. If None is given, random + palette will be generated. Default: None + """ + if classes is None: + self.custom_classes = False + return self.CLASSES, self.PALETTE + + self.custom_classes = True + if isinstance(classes, str): + # take it as a file path + class_names = mmcv.list_from_file(classes) + elif isinstance(classes, (tuple, list)): + class_names = classes + else: + raise ValueError(f'Unsupported type {type(classes)} of classes.') + + if self.CLASSES: + if not set(classes).issubset(self.CLASSES): + raise ValueError('classes is not a subset of CLASSES.') + + # dictionary, its keys are the old label ids and its values + # are the new label ids. + # used for changing pixel labels in load_annotations. + self.label_map = {} + for i, c in enumerate(self.CLASSES): + if c not in class_names: + self.label_map[i] = -1 + else: + self.label_map[i] = classes.index(c) + + palette = self.get_palette_for_custom_classes(class_names, palette) + + return class_names, palette + + def get_palette_for_custom_classes(self, class_names, palette=None): + + if self.label_map is not None: + # return subset of palette + palette = [] + for old_id, new_id in sorted( + self.label_map.items(), key=lambda x: x[1]): + if new_id != -1: + palette.append(self.PALETTE[old_id]) + palette = type(self.PALETTE)(palette) + + elif palette is None: + if self.PALETTE is None: + palette = np.random.randint(0, 255, size=(len(class_names), 3)) + else: + palette = self.PALETTE + + return palette + + def evaluate(self, + results, + metric='mIoU', + logger=None, + efficient_test=False, + **kwargs): + """Evaluate the dataset. + + Args: + results (list): Testing results of the dataset. + metric (str | list[str]): Metrics to be evaluated. 'mIoU', + 'mDice' and 'mFscore' are supported. + logger (logging.Logger | None | str): Logger used for printing + related information during evaluation. Default: None. + + Returns: + dict[str, float]: Default metrics. + """ + + if isinstance(metric, str): + metric = [metric] + allowed_metrics = ['mIoU', 'mDice', 'mFscore'] + if not set(metric).issubset(set(allowed_metrics)): + raise KeyError('metric {} is not supported'.format(metric)) + eval_results = {} + gt_seg_maps = self.get_gt_seg_maps(efficient_test) + if self.CLASSES is None: + num_classes = len( + reduce(np.union1d, [np.unique(_) for _ in gt_seg_maps])) + else: + num_classes = len(self.CLASSES) + ret_metrics = eval_metrics( + results, + gt_seg_maps, + num_classes, + self.ignore_index, + metric, + label_map=self.label_map, + reduce_zero_label=self.reduce_zero_label) + + if self.CLASSES is None: + class_names = tuple(range(num_classes)) + else: + class_names = self.CLASSES + + # summary table + ret_metrics_summary = OrderedDict({ + ret_metric: np.round(np.nanmean(ret_metric_value) * 100, 2) + for ret_metric, ret_metric_value in ret_metrics.items() + }) + + # each class table + ret_metrics.pop('aAcc', None) + ret_metrics_class = OrderedDict({ + ret_metric: np.round(ret_metric_value * 100, 2) + for ret_metric, ret_metric_value in ret_metrics.items() + }) + ret_metrics_class.update({'Class': class_names}) + ret_metrics_class.move_to_end('Class', last=False) + + try: + from prettytable import PrettyTable + # for logger + class_table_data = PrettyTable() + for key, val in ret_metrics_class.items(): + class_table_data.add_column(key, val) + + summary_table_data = PrettyTable() + for key, val in ret_metrics_summary.items(): + if key == 'aAcc': + summary_table_data.add_column(key, [val]) + else: + summary_table_data.add_column('m' + key, [val]) + + print_log('per class results:', logger) + print_log('\n' + class_table_data.get_string(), logger=logger) + print_log('Summary:', logger) + print_log('\n' + summary_table_data.get_string(), logger=logger) + except ImportError: # prettytable is not installed + pass + + # each metric dict + for key, value in ret_metrics_summary.items(): + if key == 'aAcc': + eval_results[key] = value / 100.0 + else: + eval_results['m' + key] = value / 100.0 + + ret_metrics_class.pop('Class', None) + for key, value in ret_metrics_class.items(): + eval_results.update({ + key + '.' + str(name): value[idx] / 100.0 + for idx, name in enumerate(class_names) + }) + + if mmcv.is_list_of(results, str): + for file_name in results: + os.remove(file_name) + return eval_results diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/dataset_wrappers.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/dataset_wrappers.py new file mode 100644 index 00000000..d6a5e957 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/dataset_wrappers.py @@ -0,0 +1,50 @@ +from torch.utils.data.dataset import ConcatDataset as _ConcatDataset + +from .builder import DATASETS + + +@DATASETS.register_module() +class ConcatDataset(_ConcatDataset): + """A wrapper of concatenated dataset. + + Same as :obj:`torch.utils.data.dataset.ConcatDataset`, but + concat the group flag for image aspect ratio. + + Args: + datasets (list[:obj:`Dataset`]): A list of datasets. + """ + + def __init__(self, datasets): + super(ConcatDataset, self).__init__(datasets) + self.CLASSES = datasets[0].CLASSES + self.PALETTE = datasets[0].PALETTE + + +@DATASETS.register_module() +class RepeatDataset(object): + """A wrapper of repeated dataset. + + The length of repeated dataset will be `times` larger than the original + dataset. This is useful when the data loading time is long but the dataset + is small. Using RepeatDataset can reduce the data loading time between + epochs. + + Args: + dataset (:obj:`Dataset`): The dataset to be repeated. + times (int): Repeat times. + """ + + def __init__(self, dataset, times): + self.dataset = dataset + self.times = times + self.CLASSES = dataset.CLASSES + self.PALETTE = dataset.PALETTE + self._ori_len = len(self.dataset) + + def __getitem__(self, idx): + """Get item from original dataset.""" + return self.dataset[idx % self._ori_len] + + def __len__(self): + """The length is multiplied by ``times``""" + return self.times * self._ori_len diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/drive.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/drive.py new file mode 100644 index 00000000..3cbfda8a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/drive.py @@ -0,0 +1,27 @@ +import os.path as osp + +from .builder import DATASETS +from .custom import CustomDataset + + +@DATASETS.register_module() +class DRIVEDataset(CustomDataset): + """DRIVE dataset. + + In segmentation map annotation for DRIVE, 0 stands for background, which is + included in 2 categories. ``reduce_zero_label`` is fixed to False. The + ``img_suffix`` is fixed to '.png' and ``seg_map_suffix`` is fixed to + '_manual1.png'. + """ + + CLASSES = ('background', 'vessel') + + PALETTE = [[120, 120, 120], [6, 230, 230]] + + def __init__(self, **kwargs): + super(DRIVEDataset, self).__init__( + img_suffix='.png', + seg_map_suffix='_manual1.png', + reduce_zero_label=False, + **kwargs) + assert osp.exists(self.img_dir) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/hrf.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/hrf.py new file mode 100644 index 00000000..923203b5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/hrf.py @@ -0,0 +1,27 @@ +import os.path as osp + +from .builder import DATASETS +from .custom import CustomDataset + + +@DATASETS.register_module() +class HRFDataset(CustomDataset): + """HRF dataset. + + In segmentation map annotation for HRF, 0 stands for background, which is + included in 2 categories. ``reduce_zero_label`` is fixed to False. The + ``img_suffix`` is fixed to '.png' and ``seg_map_suffix`` is fixed to + '.png'. + """ + + CLASSES = ('background', 'vessel') + + PALETTE = [[120, 120, 120], [6, 230, 230]] + + def __init__(self, **kwargs): + super(HRFDataset, self).__init__( + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) + assert osp.exists(self.img_dir) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pascal_context.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pascal_context.py new file mode 100644 index 00000000..541a63c6 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pascal_context.py @@ -0,0 +1,103 @@ +import os.path as osp + +from .builder import DATASETS +from .custom import CustomDataset + + +@DATASETS.register_module() +class PascalContextDataset(CustomDataset): + """PascalContext dataset. + + In segmentation map annotation for PascalContext, 0 stands for background, + which is included in 60 categories. ``reduce_zero_label`` is fixed to + False. The ``img_suffix`` is fixed to '.jpg' and ``seg_map_suffix`` is + fixed to '.png'. + + Args: + split (str): Split txt file for PascalContext. + """ + + CLASSES = ('background', 'aeroplane', 'bag', 'bed', 'bedclothes', 'bench', + 'bicycle', 'bird', 'boat', 'book', 'bottle', 'building', 'bus', + 'cabinet', 'car', 'cat', 'ceiling', 'chair', 'cloth', + 'computer', 'cow', 'cup', 'curtain', 'dog', 'door', 'fence', + 'floor', 'flower', 'food', 'grass', 'ground', 'horse', + 'keyboard', 'light', 'motorbike', 'mountain', 'mouse', 'person', + 'plate', 'platform', 'pottedplant', 'road', 'rock', 'sheep', + 'shelves', 'sidewalk', 'sign', 'sky', 'snow', 'sofa', 'table', + 'track', 'train', 'tree', 'truck', 'tvmonitor', 'wall', 'water', + 'window', 'wood') + + PALETTE = [[120, 120, 120], [180, 120, 120], [6, 230, 230], [80, 50, 50], + [4, 200, 3], [120, 120, 80], [140, 140, 140], [204, 5, 255], + [230, 230, 230], [4, 250, 7], [224, 5, 255], [235, 255, 7], + [150, 5, 61], [120, 120, 70], [8, 255, 51], [255, 6, 82], + [143, 255, 140], [204, 255, 4], [255, 51, 7], [204, 70, 3], + [0, 102, 200], [61, 230, 250], [255, 6, 51], [11, 102, 255], + [255, 7, 71], [255, 9, 224], [9, 7, 230], [220, 220, 220], + [255, 9, 92], [112, 9, 255], [8, 255, 214], [7, 255, 224], + [255, 184, 6], [10, 255, 71], [255, 41, 10], [7, 255, 255], + [224, 255, 8], [102, 8, 255], [255, 61, 6], [255, 194, 7], + [255, 122, 8], [0, 255, 20], [255, 8, 41], [255, 5, 153], + [6, 51, 255], [235, 12, 255], [160, 150, 20], [0, 163, 255], + [140, 140, 140], [250, 10, 15], [20, 255, 0], [31, 255, 0], + [255, 31, 0], [255, 224, 0], [153, 255, 0], [0, 0, 255], + [255, 71, 0], [0, 235, 255], [0, 173, 255], [31, 0, 255]] + + def __init__(self, split, **kwargs): + super(PascalContextDataset, self).__init__( + img_suffix='.jpg', + seg_map_suffix='.png', + split=split, + reduce_zero_label=False, + **kwargs) + assert osp.exists(self.img_dir) and self.split is not None + + +@DATASETS.register_module() +class PascalContextDataset59(CustomDataset): + """PascalContext dataset. + + In segmentation map annotation for PascalContext, 0 stands for background, + which is included in 60 categories. ``reduce_zero_label`` is fixed to + False. The ``img_suffix`` is fixed to '.jpg' and ``seg_map_suffix`` is + fixed to '.png'. + + Args: + split (str): Split txt file for PascalContext. + """ + + CLASSES = ('aeroplane', 'bag', 'bed', 'bedclothes', 'bench', 'bicycle', + 'bird', 'boat', 'book', 'bottle', 'building', 'bus', 'cabinet', + 'car', 'cat', 'ceiling', 'chair', 'cloth', 'computer', 'cow', + 'cup', 'curtain', 'dog', 'door', 'fence', 'floor', 'flower', + 'food', 'grass', 'ground', 'horse', 'keyboard', 'light', + 'motorbike', 'mountain', 'mouse', 'person', 'plate', 'platform', + 'pottedplant', 'road', 'rock', 'sheep', 'shelves', 'sidewalk', + 'sign', 'sky', 'snow', 'sofa', 'table', 'track', 'train', + 'tree', 'truck', 'tvmonitor', 'wall', 'water', 'window', 'wood') + + PALETTE = [[180, 120, 120], [6, 230, 230], [80, 50, 50], [4, 200, 3], + [120, 120, 80], [140, 140, 140], [204, 5, 255], [230, 230, 230], + [4, 250, 7], [224, 5, 255], [235, 255, 7], [150, 5, 61], + [120, 120, 70], [8, 255, 51], [255, 6, 82], [143, 255, 140], + [204, 255, 4], [255, 51, 7], [204, 70, 3], [0, 102, 200], + [61, 230, 250], [255, 6, 51], [11, 102, 255], [255, 7, 71], + [255, 9, 224], [9, 7, 230], [220, 220, 220], [255, 9, 92], + [112, 9, 255], [8, 255, 214], [7, 255, 224], [255, 184, 6], + [10, 255, 71], [255, 41, 10], [7, 255, 255], [224, 255, 8], + [102, 8, 255], [255, 61, 6], [255, 194, 7], [255, 122, 8], + [0, 255, 20], [255, 8, 41], [255, 5, 153], [6, 51, 255], + [235, 12, 255], [160, 150, 20], [0, 163, 255], [140, 140, 140], + [250, 10, 15], [20, 255, 0], [31, 255, 0], [255, 31, 0], + [255, 224, 0], [153, 255, 0], [0, 0, 255], [255, 71, 0], + [0, 235, 255], [0, 173, 255], [31, 0, 255]] + + def __init__(self, split, **kwargs): + super(PascalContextDataset59, self).__init__( + img_suffix='.jpg', + seg_map_suffix='.png', + split=split, + reduce_zero_label=True, + **kwargs) + assert osp.exists(self.img_dir) and self.split is not None diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/__init__.py new file mode 100644 index 00000000..8b9046b0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/__init__.py @@ -0,0 +1,16 @@ +from .compose import Compose +from .formating import (Collect, ImageToTensor, ToDataContainer, ToTensor, + Transpose, to_tensor) +from .loading import LoadAnnotations, LoadImageFromFile +from .test_time_aug import MultiScaleFlipAug +from .transforms import (CLAHE, AdjustGamma, Normalize, Pad, + PhotoMetricDistortion, RandomCrop, RandomFlip, + RandomRotate, Rerange, Resize, RGB2Gray, SegRescale) + +__all__ = [ + 'Compose', 'to_tensor', 'ToTensor', 'ImageToTensor', 'ToDataContainer', + 'Transpose', 'Collect', 'LoadAnnotations', 'LoadImageFromFile', + 'MultiScaleFlipAug', 'Resize', 'RandomFlip', 'Pad', 'RandomCrop', + 'Normalize', 'SegRescale', 'PhotoMetricDistortion', 'RandomRotate', + 'AdjustGamma', 'CLAHE', 'Rerange', 'RGB2Gray' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/compose.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/compose.py new file mode 100644 index 00000000..1683e533 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/compose.py @@ -0,0 +1,51 @@ +import collections + +from annotator.mmpkg.mmcv.utils import build_from_cfg + +from ..builder import PIPELINES + + +@PIPELINES.register_module() +class Compose(object): + """Compose multiple transforms sequentially. + + Args: + transforms (Sequence[dict | callable]): Sequence of transform object or + config dict to be composed. + """ + + def __init__(self, transforms): + assert isinstance(transforms, collections.abc.Sequence) + self.transforms = [] + for transform in transforms: + if isinstance(transform, dict): + transform = build_from_cfg(transform, PIPELINES) + self.transforms.append(transform) + elif callable(transform): + self.transforms.append(transform) + else: + raise TypeError('transform must be callable or a dict') + + def __call__(self, data): + """Call function to apply transforms sequentially. + + Args: + data (dict): A result dict contains the data to transform. + + Returns: + dict: Transformed data. + """ + + for t in self.transforms: + data = t(data) + if data is None: + return None + return data + + def __repr__(self): + format_string = self.__class__.__name__ + '(' + for t in self.transforms: + format_string += '\n' + format_string += f' {t}' + format_string += '\n)' + return format_string diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/formating.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/formating.py new file mode 100644 index 00000000..82e2e08f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/formating.py @@ -0,0 +1,288 @@ +from collections.abc import Sequence + +import annotator.mmpkg.mmcv as mmcv +import numpy as np +import torch +from annotator.mmpkg.mmcv.parallel import DataContainer as DC + +from ..builder import PIPELINES + + +def to_tensor(data): + """Convert objects of various python types to :obj:`torch.Tensor`. + + Supported types are: :class:`numpy.ndarray`, :class:`torch.Tensor`, + :class:`Sequence`, :class:`int` and :class:`float`. + + Args: + data (torch.Tensor | numpy.ndarray | Sequence | int | float): Data to + be converted. + """ + + if isinstance(data, torch.Tensor): + return data + elif isinstance(data, np.ndarray): + return torch.from_numpy(data) + elif isinstance(data, Sequence) and not mmcv.is_str(data): + return torch.tensor(data) + elif isinstance(data, int): + return torch.LongTensor([data]) + elif isinstance(data, float): + return torch.FloatTensor([data]) + else: + raise TypeError(f'type {type(data)} cannot be converted to tensor.') + + +@PIPELINES.register_module() +class ToTensor(object): + """Convert some results to :obj:`torch.Tensor` by given keys. + + Args: + keys (Sequence[str]): Keys that need to be converted to Tensor. + """ + + def __init__(self, keys): + self.keys = keys + + def __call__(self, results): + """Call function to convert data in results to :obj:`torch.Tensor`. + + Args: + results (dict): Result dict contains the data to convert. + + Returns: + dict: The result dict contains the data converted + to :obj:`torch.Tensor`. + """ + + for key in self.keys: + results[key] = to_tensor(results[key]) + return results + + def __repr__(self): + return self.__class__.__name__ + f'(keys={self.keys})' + + +@PIPELINES.register_module() +class ImageToTensor(object): + """Convert image to :obj:`torch.Tensor` by given keys. + + The dimension order of input image is (H, W, C). The pipeline will convert + it to (C, H, W). If only 2 dimension (H, W) is given, the output would be + (1, H, W). + + Args: + keys (Sequence[str]): Key of images to be converted to Tensor. + """ + + def __init__(self, keys): + self.keys = keys + + def __call__(self, results): + """Call function to convert image in results to :obj:`torch.Tensor` and + transpose the channel order. + + Args: + results (dict): Result dict contains the image data to convert. + + Returns: + dict: The result dict contains the image converted + to :obj:`torch.Tensor` and transposed to (C, H, W) order. + """ + + for key in self.keys: + img = results[key] + if len(img.shape) < 3: + img = np.expand_dims(img, -1) + results[key] = to_tensor(img.transpose(2, 0, 1)) + return results + + def __repr__(self): + return self.__class__.__name__ + f'(keys={self.keys})' + + +@PIPELINES.register_module() +class Transpose(object): + """Transpose some results by given keys. + + Args: + keys (Sequence[str]): Keys of results to be transposed. + order (Sequence[int]): Order of transpose. + """ + + def __init__(self, keys, order): + self.keys = keys + self.order = order + + def __call__(self, results): + """Call function to convert image in results to :obj:`torch.Tensor` and + transpose the channel order. + + Args: + results (dict): Result dict contains the image data to convert. + + Returns: + dict: The result dict contains the image converted + to :obj:`torch.Tensor` and transposed to (C, H, W) order. + """ + + for key in self.keys: + results[key] = results[key].transpose(self.order) + return results + + def __repr__(self): + return self.__class__.__name__ + \ + f'(keys={self.keys}, order={self.order})' + + +@PIPELINES.register_module() +class ToDataContainer(object): + """Convert results to :obj:`mmcv.DataContainer` by given fields. + + Args: + fields (Sequence[dict]): Each field is a dict like + ``dict(key='xxx', **kwargs)``. The ``key`` in result will + be converted to :obj:`mmcv.DataContainer` with ``**kwargs``. + Default: ``(dict(key='img', stack=True), + dict(key='gt_semantic_seg'))``. + """ + + def __init__(self, + fields=(dict(key='img', + stack=True), dict(key='gt_semantic_seg'))): + self.fields = fields + + def __call__(self, results): + """Call function to convert data in results to + :obj:`mmcv.DataContainer`. + + Args: + results (dict): Result dict contains the data to convert. + + Returns: + dict: The result dict contains the data converted to + :obj:`mmcv.DataContainer`. + """ + + for field in self.fields: + field = field.copy() + key = field.pop('key') + results[key] = DC(results[key], **field) + return results + + def __repr__(self): + return self.__class__.__name__ + f'(fields={self.fields})' + + +@PIPELINES.register_module() +class DefaultFormatBundle(object): + """Default formatting bundle. + + It simplifies the pipeline of formatting common fields, including "img" + and "gt_semantic_seg". These fields are formatted as follows. + + - img: (1)transpose, (2)to tensor, (3)to DataContainer (stack=True) + - gt_semantic_seg: (1)unsqueeze dim-0 (2)to tensor, + (3)to DataContainer (stack=True) + """ + + def __call__(self, results): + """Call function to transform and format common fields in results. + + Args: + results (dict): Result dict contains the data to convert. + + Returns: + dict: The result dict contains the data that is formatted with + default bundle. + """ + + if 'img' in results: + img = results['img'] + if len(img.shape) < 3: + img = np.expand_dims(img, -1) + img = np.ascontiguousarray(img.transpose(2, 0, 1)) + results['img'] = DC(to_tensor(img), stack=True) + if 'gt_semantic_seg' in results: + # convert to long + results['gt_semantic_seg'] = DC( + to_tensor(results['gt_semantic_seg'][None, + ...].astype(np.int64)), + stack=True) + return results + + def __repr__(self): + return self.__class__.__name__ + + +@PIPELINES.register_module() +class Collect(object): + """Collect data from the loader relevant to the specific task. + + This is usually the last stage of the data loader pipeline. Typically keys + is set to some subset of "img", "gt_semantic_seg". + + The "img_meta" item is always populated. The contents of the "img_meta" + dictionary depends on "meta_keys". By default this includes: + + - "img_shape": shape of the image input to the network as a tuple + (h, w, c). Note that images may be zero padded on the bottom/right + if the batch tensor is larger than this shape. + + - "scale_factor": a float indicating the preprocessing scale + + - "flip": a boolean indicating if image flip transform was used + + - "filename": path to the image file + + - "ori_shape": original shape of the image as a tuple (h, w, c) + + - "pad_shape": image shape after padding + + - "img_norm_cfg": a dict of normalization information: + - mean - per channel mean subtraction + - std - per channel std divisor + - to_rgb - bool indicating if bgr was converted to rgb + + Args: + keys (Sequence[str]): Keys of results to be collected in ``data``. + meta_keys (Sequence[str], optional): Meta keys to be converted to + ``mmcv.DataContainer`` and collected in ``data[img_metas]``. + Default: ``('filename', 'ori_filename', 'ori_shape', 'img_shape', + 'pad_shape', 'scale_factor', 'flip', 'flip_direction', + 'img_norm_cfg')`` + """ + + def __init__(self, + keys, + meta_keys=('filename', 'ori_filename', 'ori_shape', + 'img_shape', 'pad_shape', 'scale_factor', 'flip', + 'flip_direction', 'img_norm_cfg')): + self.keys = keys + self.meta_keys = meta_keys + + def __call__(self, results): + """Call function to collect keys in results. The keys in ``meta_keys`` + will be converted to :obj:mmcv.DataContainer. + + Args: + results (dict): Result dict contains the data to collect. + + Returns: + dict: The result dict contains the following keys + - keys in``self.keys`` + - ``img_metas`` + """ + + data = {} + img_meta = {} + for key in self.meta_keys: + img_meta[key] = results[key] + data['img_metas'] = DC(img_meta, cpu_only=True) + for key in self.keys: + data[key] = results[key] + return data + + def __repr__(self): + return self.__class__.__name__ + \ + f'(keys={self.keys}, meta_keys={self.meta_keys})' diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/loading.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/loading.py new file mode 100644 index 00000000..3ad8c2cb --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/loading.py @@ -0,0 +1,153 @@ +import os.path as osp + +import annotator.mmpkg.mmcv as mmcv +import numpy as np + +from ..builder import PIPELINES + + +@PIPELINES.register_module() +class LoadImageFromFile(object): + """Load an image from file. + + Required keys are "img_prefix" and "img_info" (a dict that must contain the + key "filename"). Added or updated keys are "filename", "img", "img_shape", + "ori_shape" (same as `img_shape`), "pad_shape" (same as `img_shape`), + "scale_factor" (1.0) and "img_norm_cfg" (means=0 and stds=1). + + Args: + to_float32 (bool): Whether to convert the loaded image to a float32 + numpy array. If set to False, the loaded image is an uint8 array. + Defaults to False. + color_type (str): The flag argument for :func:`mmcv.imfrombytes`. + Defaults to 'color'. + file_client_args (dict): Arguments to instantiate a FileClient. + See :class:`mmcv.fileio.FileClient` for details. + Defaults to ``dict(backend='disk')``. + imdecode_backend (str): Backend for :func:`mmcv.imdecode`. Default: + 'cv2' + """ + + def __init__(self, + to_float32=False, + color_type='color', + file_client_args=dict(backend='disk'), + imdecode_backend='cv2'): + self.to_float32 = to_float32 + self.color_type = color_type + self.file_client_args = file_client_args.copy() + self.file_client = None + self.imdecode_backend = imdecode_backend + + def __call__(self, results): + """Call functions to load image and get image meta information. + + Args: + results (dict): Result dict from :obj:`mmseg.CustomDataset`. + + Returns: + dict: The dict contains loaded image and meta information. + """ + + if self.file_client is None: + self.file_client = mmcv.FileClient(**self.file_client_args) + + if results.get('img_prefix') is not None: + filename = osp.join(results['img_prefix'], + results['img_info']['filename']) + else: + filename = results['img_info']['filename'] + img_bytes = self.file_client.get(filename) + img = mmcv.imfrombytes( + img_bytes, flag=self.color_type, backend=self.imdecode_backend) + if self.to_float32: + img = img.astype(np.float32) + + results['filename'] = filename + results['ori_filename'] = results['img_info']['filename'] + results['img'] = img + results['img_shape'] = img.shape + results['ori_shape'] = img.shape + # Set initial values for default meta_keys + results['pad_shape'] = img.shape + results['scale_factor'] = 1.0 + num_channels = 1 if len(img.shape) < 3 else img.shape[2] + results['img_norm_cfg'] = dict( + mean=np.zeros(num_channels, dtype=np.float32), + std=np.ones(num_channels, dtype=np.float32), + to_rgb=False) + return results + + def __repr__(self): + repr_str = self.__class__.__name__ + repr_str += f'(to_float32={self.to_float32},' + repr_str += f"color_type='{self.color_type}'," + repr_str += f"imdecode_backend='{self.imdecode_backend}')" + return repr_str + + +@PIPELINES.register_module() +class LoadAnnotations(object): + """Load annotations for semantic segmentation. + + Args: + reduce_zero_label (bool): Whether reduce all label value by 1. + Usually used for datasets where 0 is background label. + Default: False. + file_client_args (dict): Arguments to instantiate a FileClient. + See :class:`mmcv.fileio.FileClient` for details. + Defaults to ``dict(backend='disk')``. + imdecode_backend (str): Backend for :func:`mmcv.imdecode`. Default: + 'pillow' + """ + + def __init__(self, + reduce_zero_label=False, + file_client_args=dict(backend='disk'), + imdecode_backend='pillow'): + self.reduce_zero_label = reduce_zero_label + self.file_client_args = file_client_args.copy() + self.file_client = None + self.imdecode_backend = imdecode_backend + + def __call__(self, results): + """Call function to load multiple types annotations. + + Args: + results (dict): Result dict from :obj:`mmseg.CustomDataset`. + + Returns: + dict: The dict contains loaded semantic segmentation annotations. + """ + + if self.file_client is None: + self.file_client = mmcv.FileClient(**self.file_client_args) + + if results.get('seg_prefix', None) is not None: + filename = osp.join(results['seg_prefix'], + results['ann_info']['seg_map']) + else: + filename = results['ann_info']['seg_map'] + img_bytes = self.file_client.get(filename) + gt_semantic_seg = mmcv.imfrombytes( + img_bytes, flag='unchanged', + backend=self.imdecode_backend).squeeze().astype(np.uint8) + # modify if custom classes + if results.get('label_map', None) is not None: + for old_id, new_id in results['label_map'].items(): + gt_semantic_seg[gt_semantic_seg == old_id] = new_id + # reduce zero_label + if self.reduce_zero_label: + # avoid using underflow conversion + gt_semantic_seg[gt_semantic_seg == 0] = 255 + gt_semantic_seg = gt_semantic_seg - 1 + gt_semantic_seg[gt_semantic_seg == 254] = 255 + results['gt_semantic_seg'] = gt_semantic_seg + results['seg_fields'].append('gt_semantic_seg') + return results + + def __repr__(self): + repr_str = self.__class__.__name__ + repr_str += f'(reduce_zero_label={self.reduce_zero_label},' + repr_str += f"imdecode_backend='{self.imdecode_backend}')" + return repr_str diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/test_time_aug.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/test_time_aug.py new file mode 100644 index 00000000..fb781d92 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/test_time_aug.py @@ -0,0 +1,133 @@ +import warnings + +import annotator.mmpkg.mmcv as mmcv + +from ..builder import PIPELINES +from .compose import Compose + + +@PIPELINES.register_module() +class MultiScaleFlipAug(object): + """Test-time augmentation with multiple scales and flipping. + + An example configuration is as followed: + + .. code-block:: + + img_scale=(2048, 1024), + img_ratios=[0.5, 1.0], + flip=True, + transforms=[ + dict(type='Resize', keep_ratio=True), + dict(type='RandomFlip'), + dict(type='Normalize', **img_norm_cfg), + dict(type='Pad', size_divisor=32), + dict(type='ImageToTensor', keys=['img']), + dict(type='Collect', keys=['img']), + ] + + After MultiScaleFLipAug with above configuration, the results are wrapped + into lists of the same length as followed: + + .. code-block:: + + dict( + img=[...], + img_shape=[...], + scale=[(1024, 512), (1024, 512), (2048, 1024), (2048, 1024)] + flip=[False, True, False, True] + ... + ) + + Args: + transforms (list[dict]): Transforms to apply in each augmentation. + img_scale (None | tuple | list[tuple]): Images scales for resizing. + img_ratios (float | list[float]): Image ratios for resizing + flip (bool): Whether apply flip augmentation. Default: False. + flip_direction (str | list[str]): Flip augmentation directions, + options are "horizontal" and "vertical". If flip_direction is list, + multiple flip augmentations will be applied. + It has no effect when flip == False. Default: "horizontal". + """ + + def __init__(self, + transforms, + img_scale, + img_ratios=None, + flip=False, + flip_direction='horizontal'): + self.transforms = Compose(transforms) + if img_ratios is not None: + img_ratios = img_ratios if isinstance(img_ratios, + list) else [img_ratios] + assert mmcv.is_list_of(img_ratios, float) + if img_scale is None: + # mode 1: given img_scale=None and a range of image ratio + self.img_scale = None + assert mmcv.is_list_of(img_ratios, float) + elif isinstance(img_scale, tuple) and mmcv.is_list_of( + img_ratios, float): + assert len(img_scale) == 2 + # mode 2: given a scale and a range of image ratio + self.img_scale = [(int(img_scale[0] * ratio), + int(img_scale[1] * ratio)) + for ratio in img_ratios] + else: + # mode 3: given multiple scales + self.img_scale = img_scale if isinstance(img_scale, + list) else [img_scale] + assert mmcv.is_list_of(self.img_scale, tuple) or self.img_scale is None + self.flip = flip + self.img_ratios = img_ratios + self.flip_direction = flip_direction if isinstance( + flip_direction, list) else [flip_direction] + assert mmcv.is_list_of(self.flip_direction, str) + if not self.flip and self.flip_direction != ['horizontal']: + warnings.warn( + 'flip_direction has no effect when flip is set to False') + if (self.flip + and not any([t['type'] == 'RandomFlip' for t in transforms])): + warnings.warn( + 'flip has no effect when RandomFlip is not in transforms') + + def __call__(self, results): + """Call function to apply test time augment transforms on results. + + Args: + results (dict): Result dict contains the data to transform. + + Returns: + dict[str: list]: The augmented data, where each value is wrapped + into a list. + """ + + aug_data = [] + if self.img_scale is None and mmcv.is_list_of(self.img_ratios, float): + h, w = results['img'].shape[:2] + img_scale = [(int(w * ratio), int(h * ratio)) + for ratio in self.img_ratios] + else: + img_scale = self.img_scale + flip_aug = [False, True] if self.flip else [False] + for scale in img_scale: + for flip in flip_aug: + for direction in self.flip_direction: + _results = results.copy() + _results['scale'] = scale + _results['flip'] = flip + _results['flip_direction'] = direction + data = self.transforms(_results) + aug_data.append(data) + # list of dict to dict of list + aug_data_dict = {key: [] for key in aug_data[0]} + for data in aug_data: + for key, val in data.items(): + aug_data_dict[key].append(val) + return aug_data_dict + + def __repr__(self): + repr_str = self.__class__.__name__ + repr_str += f'(transforms={self.transforms}, ' + repr_str += f'img_scale={self.img_scale}, flip={self.flip})' + repr_str += f'flip_direction={self.flip_direction}' + return repr_str diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/transforms.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/transforms.py new file mode 100644 index 00000000..842763db --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/pipelines/transforms.py @@ -0,0 +1,889 @@ +import annotator.mmpkg.mmcv as mmcv +import numpy as np +from annotator.mmpkg.mmcv.utils import deprecated_api_warning, is_tuple_of +from numpy import random + +from ..builder import PIPELINES + + +@PIPELINES.register_module() +class Resize(object): + """Resize images & seg. + + This transform resizes the input image to some scale. If the input dict + contains the key "scale", then the scale in the input dict is used, + otherwise the specified scale in the init method is used. + + ``img_scale`` can be None, a tuple (single-scale) or a list of tuple + (multi-scale). There are 4 multiscale modes: + + - ``ratio_range is not None``: + 1. When img_scale is None, img_scale is the shape of image in results + (img_scale = results['img'].shape[:2]) and the image is resized based + on the original size. (mode 1) + 2. When img_scale is a tuple (single-scale), randomly sample a ratio from + the ratio range and multiply it with the image scale. (mode 2) + + - ``ratio_range is None and multiscale_mode == "range"``: randomly sample a + scale from the a range. (mode 3) + + - ``ratio_range is None and multiscale_mode == "value"``: randomly sample a + scale from multiple scales. (mode 4) + + Args: + img_scale (tuple or list[tuple]): Images scales for resizing. + multiscale_mode (str): Either "range" or "value". + ratio_range (tuple[float]): (min_ratio, max_ratio) + keep_ratio (bool): Whether to keep the aspect ratio when resizing the + image. + """ + + def __init__(self, + img_scale=None, + multiscale_mode='range', + ratio_range=None, + keep_ratio=True): + if img_scale is None: + self.img_scale = None + else: + if isinstance(img_scale, list): + self.img_scale = img_scale + else: + self.img_scale = [img_scale] + assert mmcv.is_list_of(self.img_scale, tuple) + + if ratio_range is not None: + # mode 1: given img_scale=None and a range of image ratio + # mode 2: given a scale and a range of image ratio + assert self.img_scale is None or len(self.img_scale) == 1 + else: + # mode 3 and 4: given multiple scales or a range of scales + assert multiscale_mode in ['value', 'range'] + + self.multiscale_mode = multiscale_mode + self.ratio_range = ratio_range + self.keep_ratio = keep_ratio + + @staticmethod + def random_select(img_scales): + """Randomly select an img_scale from given candidates. + + Args: + img_scales (list[tuple]): Images scales for selection. + + Returns: + (tuple, int): Returns a tuple ``(img_scale, scale_dix)``, + where ``img_scale`` is the selected image scale and + ``scale_idx`` is the selected index in the given candidates. + """ + + assert mmcv.is_list_of(img_scales, tuple) + scale_idx = np.random.randint(len(img_scales)) + img_scale = img_scales[scale_idx] + return img_scale, scale_idx + + @staticmethod + def random_sample(img_scales): + """Randomly sample an img_scale when ``multiscale_mode=='range'``. + + Args: + img_scales (list[tuple]): Images scale range for sampling. + There must be two tuples in img_scales, which specify the lower + and upper bound of image scales. + + Returns: + (tuple, None): Returns a tuple ``(img_scale, None)``, where + ``img_scale`` is sampled scale and None is just a placeholder + to be consistent with :func:`random_select`. + """ + + assert mmcv.is_list_of(img_scales, tuple) and len(img_scales) == 2 + img_scale_long = [max(s) for s in img_scales] + img_scale_short = [min(s) for s in img_scales] + long_edge = np.random.randint( + min(img_scale_long), + max(img_scale_long) + 1) + short_edge = np.random.randint( + min(img_scale_short), + max(img_scale_short) + 1) + img_scale = (long_edge, short_edge) + return img_scale, None + + @staticmethod + def random_sample_ratio(img_scale, ratio_range): + """Randomly sample an img_scale when ``ratio_range`` is specified. + + A ratio will be randomly sampled from the range specified by + ``ratio_range``. Then it would be multiplied with ``img_scale`` to + generate sampled scale. + + Args: + img_scale (tuple): Images scale base to multiply with ratio. + ratio_range (tuple[float]): The minimum and maximum ratio to scale + the ``img_scale``. + + Returns: + (tuple, None): Returns a tuple ``(scale, None)``, where + ``scale`` is sampled ratio multiplied with ``img_scale`` and + None is just a placeholder to be consistent with + :func:`random_select`. + """ + + assert isinstance(img_scale, tuple) and len(img_scale) == 2 + min_ratio, max_ratio = ratio_range + assert min_ratio <= max_ratio + ratio = np.random.random_sample() * (max_ratio - min_ratio) + min_ratio + scale = int(img_scale[0] * ratio), int(img_scale[1] * ratio) + return scale, None + + def _random_scale(self, results): + """Randomly sample an img_scale according to ``ratio_range`` and + ``multiscale_mode``. + + If ``ratio_range`` is specified, a ratio will be sampled and be + multiplied with ``img_scale``. + If multiple scales are specified by ``img_scale``, a scale will be + sampled according to ``multiscale_mode``. + Otherwise, single scale will be used. + + Args: + results (dict): Result dict from :obj:`dataset`. + + Returns: + dict: Two new keys 'scale` and 'scale_idx` are added into + ``results``, which would be used by subsequent pipelines. + """ + + if self.ratio_range is not None: + if self.img_scale is None: + h, w = results['img'].shape[:2] + scale, scale_idx = self.random_sample_ratio((w, h), + self.ratio_range) + else: + scale, scale_idx = self.random_sample_ratio( + self.img_scale[0], self.ratio_range) + elif len(self.img_scale) == 1: + scale, scale_idx = self.img_scale[0], 0 + elif self.multiscale_mode == 'range': + scale, scale_idx = self.random_sample(self.img_scale) + elif self.multiscale_mode == 'value': + scale, scale_idx = self.random_select(self.img_scale) + else: + raise NotImplementedError + + results['scale'] = scale + results['scale_idx'] = scale_idx + + def _resize_img(self, results): + """Resize images with ``results['scale']``.""" + if self.keep_ratio: + img, scale_factor = mmcv.imrescale( + results['img'], results['scale'], return_scale=True) + # the w_scale and h_scale has minor difference + # a real fix should be done in the mmcv.imrescale in the future + new_h, new_w = img.shape[:2] + h, w = results['img'].shape[:2] + w_scale = new_w / w + h_scale = new_h / h + else: + img, w_scale, h_scale = mmcv.imresize( + results['img'], results['scale'], return_scale=True) + scale_factor = np.array([w_scale, h_scale, w_scale, h_scale], + dtype=np.float32) + results['img'] = img + results['img_shape'] = img.shape + results['pad_shape'] = img.shape # in case that there is no padding + results['scale_factor'] = scale_factor + results['keep_ratio'] = self.keep_ratio + + def _resize_seg(self, results): + """Resize semantic segmentation map with ``results['scale']``.""" + for key in results.get('seg_fields', []): + if self.keep_ratio: + gt_seg = mmcv.imrescale( + results[key], results['scale'], interpolation='nearest') + else: + gt_seg = mmcv.imresize( + results[key], results['scale'], interpolation='nearest') + results[key] = gt_seg + + def __call__(self, results): + """Call function to resize images, bounding boxes, masks, semantic + segmentation map. + + Args: + results (dict): Result dict from loading pipeline. + + Returns: + dict: Resized results, 'img_shape', 'pad_shape', 'scale_factor', + 'keep_ratio' keys are added into result dict. + """ + + if 'scale' not in results: + self._random_scale(results) + self._resize_img(results) + self._resize_seg(results) + return results + + def __repr__(self): + repr_str = self.__class__.__name__ + repr_str += (f'(img_scale={self.img_scale}, ' + f'multiscale_mode={self.multiscale_mode}, ' + f'ratio_range={self.ratio_range}, ' + f'keep_ratio={self.keep_ratio})') + return repr_str + + +@PIPELINES.register_module() +class RandomFlip(object): + """Flip the image & seg. + + If the input dict contains the key "flip", then the flag will be used, + otherwise it will be randomly decided by a ratio specified in the init + method. + + Args: + prob (float, optional): The flipping probability. Default: None. + direction(str, optional): The flipping direction. Options are + 'horizontal' and 'vertical'. Default: 'horizontal'. + """ + + @deprecated_api_warning({'flip_ratio': 'prob'}, cls_name='RandomFlip') + def __init__(self, prob=None, direction='horizontal'): + self.prob = prob + self.direction = direction + if prob is not None: + assert prob >= 0 and prob <= 1 + assert direction in ['horizontal', 'vertical'] + + def __call__(self, results): + """Call function to flip bounding boxes, masks, semantic segmentation + maps. + + Args: + results (dict): Result dict from loading pipeline. + + Returns: + dict: Flipped results, 'flip', 'flip_direction' keys are added into + result dict. + """ + + if 'flip' not in results: + flip = True if np.random.rand() < self.prob else False + results['flip'] = flip + if 'flip_direction' not in results: + results['flip_direction'] = self.direction + if results['flip']: + # flip image + results['img'] = mmcv.imflip( + results['img'], direction=results['flip_direction']) + + # flip segs + for key in results.get('seg_fields', []): + # use copy() to make numpy stride positive + results[key] = mmcv.imflip( + results[key], direction=results['flip_direction']).copy() + return results + + def __repr__(self): + return self.__class__.__name__ + f'(prob={self.prob})' + + +@PIPELINES.register_module() +class Pad(object): + """Pad the image & mask. + + There are two padding modes: (1) pad to a fixed size and (2) pad to the + minimum size that is divisible by some number. + Added keys are "pad_shape", "pad_fixed_size", "pad_size_divisor", + + Args: + size (tuple, optional): Fixed padding size. + size_divisor (int, optional): The divisor of padded size. + pad_val (float, optional): Padding value. Default: 0. + seg_pad_val (float, optional): Padding value of segmentation map. + Default: 255. + """ + + def __init__(self, + size=None, + size_divisor=None, + pad_val=0, + seg_pad_val=255): + self.size = size + self.size_divisor = size_divisor + self.pad_val = pad_val + self.seg_pad_val = seg_pad_val + # only one of size and size_divisor should be valid + assert size is not None or size_divisor is not None + assert size is None or size_divisor is None + + def _pad_img(self, results): + """Pad images according to ``self.size``.""" + if self.size is not None: + padded_img = mmcv.impad( + results['img'], shape=self.size, pad_val=self.pad_val) + elif self.size_divisor is not None: + padded_img = mmcv.impad_to_multiple( + results['img'], self.size_divisor, pad_val=self.pad_val) + results['img'] = padded_img + results['pad_shape'] = padded_img.shape + results['pad_fixed_size'] = self.size + results['pad_size_divisor'] = self.size_divisor + + def _pad_seg(self, results): + """Pad masks according to ``results['pad_shape']``.""" + for key in results.get('seg_fields', []): + results[key] = mmcv.impad( + results[key], + shape=results['pad_shape'][:2], + pad_val=self.seg_pad_val) + + def __call__(self, results): + """Call function to pad images, masks, semantic segmentation maps. + + Args: + results (dict): Result dict from loading pipeline. + + Returns: + dict: Updated result dict. + """ + + self._pad_img(results) + self._pad_seg(results) + return results + + def __repr__(self): + repr_str = self.__class__.__name__ + repr_str += f'(size={self.size}, size_divisor={self.size_divisor}, ' \ + f'pad_val={self.pad_val})' + return repr_str + + +@PIPELINES.register_module() +class Normalize(object): + """Normalize the image. + + Added key is "img_norm_cfg". + + Args: + mean (sequence): Mean values of 3 channels. + std (sequence): Std values of 3 channels. + to_rgb (bool): Whether to convert the image from BGR to RGB, + default is true. + """ + + def __init__(self, mean, std, to_rgb=True): + self.mean = np.array(mean, dtype=np.float32) + self.std = np.array(std, dtype=np.float32) + self.to_rgb = to_rgb + + def __call__(self, results): + """Call function to normalize images. + + Args: + results (dict): Result dict from loading pipeline. + + Returns: + dict: Normalized results, 'img_norm_cfg' key is added into + result dict. + """ + + results['img'] = mmcv.imnormalize(results['img'], self.mean, self.std, + self.to_rgb) + results['img_norm_cfg'] = dict( + mean=self.mean, std=self.std, to_rgb=self.to_rgb) + return results + + def __repr__(self): + repr_str = self.__class__.__name__ + repr_str += f'(mean={self.mean}, std={self.std}, to_rgb=' \ + f'{self.to_rgb})' + return repr_str + + +@PIPELINES.register_module() +class Rerange(object): + """Rerange the image pixel value. + + Args: + min_value (float or int): Minimum value of the reranged image. + Default: 0. + max_value (float or int): Maximum value of the reranged image. + Default: 255. + """ + + def __init__(self, min_value=0, max_value=255): + assert isinstance(min_value, float) or isinstance(min_value, int) + assert isinstance(max_value, float) or isinstance(max_value, int) + assert min_value < max_value + self.min_value = min_value + self.max_value = max_value + + def __call__(self, results): + """Call function to rerange images. + + Args: + results (dict): Result dict from loading pipeline. + Returns: + dict: Reranged results. + """ + + img = results['img'] + img_min_value = np.min(img) + img_max_value = np.max(img) + + assert img_min_value < img_max_value + # rerange to [0, 1] + img = (img - img_min_value) / (img_max_value - img_min_value) + # rerange to [min_value, max_value] + img = img * (self.max_value - self.min_value) + self.min_value + results['img'] = img + + return results + + def __repr__(self): + repr_str = self.__class__.__name__ + repr_str += f'(min_value={self.min_value}, max_value={self.max_value})' + return repr_str + + +@PIPELINES.register_module() +class CLAHE(object): + """Use CLAHE method to process the image. + + See `ZUIDERVELD,K. Contrast Limited Adaptive Histogram Equalization[J]. + Graphics Gems, 1994:474-485.` for more information. + + Args: + clip_limit (float): Threshold for contrast limiting. Default: 40.0. + tile_grid_size (tuple[int]): Size of grid for histogram equalization. + Input image will be divided into equally sized rectangular tiles. + It defines the number of tiles in row and column. Default: (8, 8). + """ + + def __init__(self, clip_limit=40.0, tile_grid_size=(8, 8)): + assert isinstance(clip_limit, (float, int)) + self.clip_limit = clip_limit + assert is_tuple_of(tile_grid_size, int) + assert len(tile_grid_size) == 2 + self.tile_grid_size = tile_grid_size + + def __call__(self, results): + """Call function to Use CLAHE method process images. + + Args: + results (dict): Result dict from loading pipeline. + + Returns: + dict: Processed results. + """ + + for i in range(results['img'].shape[2]): + results['img'][:, :, i] = mmcv.clahe( + np.array(results['img'][:, :, i], dtype=np.uint8), + self.clip_limit, self.tile_grid_size) + + return results + + def __repr__(self): + repr_str = self.__class__.__name__ + repr_str += f'(clip_limit={self.clip_limit}, '\ + f'tile_grid_size={self.tile_grid_size})' + return repr_str + + +@PIPELINES.register_module() +class RandomCrop(object): + """Random crop the image & seg. + + Args: + crop_size (tuple): Expected size after cropping, (h, w). + cat_max_ratio (float): The maximum ratio that single category could + occupy. + """ + + def __init__(self, crop_size, cat_max_ratio=1., ignore_index=255): + assert crop_size[0] > 0 and crop_size[1] > 0 + self.crop_size = crop_size + self.cat_max_ratio = cat_max_ratio + self.ignore_index = ignore_index + + def get_crop_bbox(self, img): + """Randomly get a crop bounding box.""" + margin_h = max(img.shape[0] - self.crop_size[0], 0) + margin_w = max(img.shape[1] - self.crop_size[1], 0) + offset_h = np.random.randint(0, margin_h + 1) + offset_w = np.random.randint(0, margin_w + 1) + crop_y1, crop_y2 = offset_h, offset_h + self.crop_size[0] + crop_x1, crop_x2 = offset_w, offset_w + self.crop_size[1] + + return crop_y1, crop_y2, crop_x1, crop_x2 + + def crop(self, img, crop_bbox): + """Crop from ``img``""" + crop_y1, crop_y2, crop_x1, crop_x2 = crop_bbox + img = img[crop_y1:crop_y2, crop_x1:crop_x2, ...] + return img + + def __call__(self, results): + """Call function to randomly crop images, semantic segmentation maps. + + Args: + results (dict): Result dict from loading pipeline. + + Returns: + dict: Randomly cropped results, 'img_shape' key in result dict is + updated according to crop size. + """ + + img = results['img'] + crop_bbox = self.get_crop_bbox(img) + if self.cat_max_ratio < 1.: + # Repeat 10 times + for _ in range(10): + seg_temp = self.crop(results['gt_semantic_seg'], crop_bbox) + labels, cnt = np.unique(seg_temp, return_counts=True) + cnt = cnt[labels != self.ignore_index] + if len(cnt) > 1 and np.max(cnt) / np.sum( + cnt) < self.cat_max_ratio: + break + crop_bbox = self.get_crop_bbox(img) + + # crop the image + img = self.crop(img, crop_bbox) + img_shape = img.shape + results['img'] = img + results['img_shape'] = img_shape + + # crop semantic seg + for key in results.get('seg_fields', []): + results[key] = self.crop(results[key], crop_bbox) + + return results + + def __repr__(self): + return self.__class__.__name__ + f'(crop_size={self.crop_size})' + + +@PIPELINES.register_module() +class RandomRotate(object): + """Rotate the image & seg. + + Args: + prob (float): The rotation probability. + degree (float, tuple[float]): Range of degrees to select from. If + degree is a number instead of tuple like (min, max), + the range of degree will be (``-degree``, ``+degree``) + pad_val (float, optional): Padding value of image. Default: 0. + seg_pad_val (float, optional): Padding value of segmentation map. + Default: 255. + center (tuple[float], optional): Center point (w, h) of the rotation in + the source image. If not specified, the center of the image will be + used. Default: None. + auto_bound (bool): Whether to adjust the image size to cover the whole + rotated image. Default: False + """ + + def __init__(self, + prob, + degree, + pad_val=0, + seg_pad_val=255, + center=None, + auto_bound=False): + self.prob = prob + assert prob >= 0 and prob <= 1 + if isinstance(degree, (float, int)): + assert degree > 0, f'degree {degree} should be positive' + self.degree = (-degree, degree) + else: + self.degree = degree + assert len(self.degree) == 2, f'degree {self.degree} should be a ' \ + f'tuple of (min, max)' + self.pal_val = pad_val + self.seg_pad_val = seg_pad_val + self.center = center + self.auto_bound = auto_bound + + def __call__(self, results): + """Call function to rotate image, semantic segmentation maps. + + Args: + results (dict): Result dict from loading pipeline. + + Returns: + dict: Rotated results. + """ + + rotate = True if np.random.rand() < self.prob else False + degree = np.random.uniform(min(*self.degree), max(*self.degree)) + if rotate: + # rotate image + results['img'] = mmcv.imrotate( + results['img'], + angle=degree, + border_value=self.pal_val, + center=self.center, + auto_bound=self.auto_bound) + + # rotate segs + for key in results.get('seg_fields', []): + results[key] = mmcv.imrotate( + results[key], + angle=degree, + border_value=self.seg_pad_val, + center=self.center, + auto_bound=self.auto_bound, + interpolation='nearest') + return results + + def __repr__(self): + repr_str = self.__class__.__name__ + repr_str += f'(prob={self.prob}, ' \ + f'degree={self.degree}, ' \ + f'pad_val={self.pal_val}, ' \ + f'seg_pad_val={self.seg_pad_val}, ' \ + f'center={self.center}, ' \ + f'auto_bound={self.auto_bound})' + return repr_str + + +@PIPELINES.register_module() +class RGB2Gray(object): + """Convert RGB image to grayscale image. + + This transform calculate the weighted mean of input image channels with + ``weights`` and then expand the channels to ``out_channels``. When + ``out_channels`` is None, the number of output channels is the same as + input channels. + + Args: + out_channels (int): Expected number of output channels after + transforming. Default: None. + weights (tuple[float]): The weights to calculate the weighted mean. + Default: (0.299, 0.587, 0.114). + """ + + def __init__(self, out_channels=None, weights=(0.299, 0.587, 0.114)): + assert out_channels is None or out_channels > 0 + self.out_channels = out_channels + assert isinstance(weights, tuple) + for item in weights: + assert isinstance(item, (float, int)) + self.weights = weights + + def __call__(self, results): + """Call function to convert RGB image to grayscale image. + + Args: + results (dict): Result dict from loading pipeline. + + Returns: + dict: Result dict with grayscale image. + """ + img = results['img'] + assert len(img.shape) == 3 + assert img.shape[2] == len(self.weights) + weights = np.array(self.weights).reshape((1, 1, -1)) + img = (img * weights).sum(2, keepdims=True) + if self.out_channels is None: + img = img.repeat(weights.shape[2], axis=2) + else: + img = img.repeat(self.out_channels, axis=2) + + results['img'] = img + results['img_shape'] = img.shape + + return results + + def __repr__(self): + repr_str = self.__class__.__name__ + repr_str += f'(out_channels={self.out_channels}, ' \ + f'weights={self.weights})' + return repr_str + + +@PIPELINES.register_module() +class AdjustGamma(object): + """Using gamma correction to process the image. + + Args: + gamma (float or int): Gamma value used in gamma correction. + Default: 1.0. + """ + + def __init__(self, gamma=1.0): + assert isinstance(gamma, float) or isinstance(gamma, int) + assert gamma > 0 + self.gamma = gamma + inv_gamma = 1.0 / gamma + self.table = np.array([(i / 255.0)**inv_gamma * 255 + for i in np.arange(256)]).astype('uint8') + + def __call__(self, results): + """Call function to process the image with gamma correction. + + Args: + results (dict): Result dict from loading pipeline. + + Returns: + dict: Processed results. + """ + + results['img'] = mmcv.lut_transform( + np.array(results['img'], dtype=np.uint8), self.table) + + return results + + def __repr__(self): + return self.__class__.__name__ + f'(gamma={self.gamma})' + + +@PIPELINES.register_module() +class SegRescale(object): + """Rescale semantic segmentation maps. + + Args: + scale_factor (float): The scale factor of the final output. + """ + + def __init__(self, scale_factor=1): + self.scale_factor = scale_factor + + def __call__(self, results): + """Call function to scale the semantic segmentation map. + + Args: + results (dict): Result dict from loading pipeline. + + Returns: + dict: Result dict with semantic segmentation map scaled. + """ + for key in results.get('seg_fields', []): + if self.scale_factor != 1: + results[key] = mmcv.imrescale( + results[key], self.scale_factor, interpolation='nearest') + return results + + def __repr__(self): + return self.__class__.__name__ + f'(scale_factor={self.scale_factor})' + + +@PIPELINES.register_module() +class PhotoMetricDistortion(object): + """Apply photometric distortion to image sequentially, every transformation + is applied with a probability of 0.5. The position of random contrast is in + second or second to last. + + 1. random brightness + 2. random contrast (mode 0) + 3. convert color from BGR to HSV + 4. random saturation + 5. random hue + 6. convert color from HSV to BGR + 7. random contrast (mode 1) + + Args: + brightness_delta (int): delta of brightness. + contrast_range (tuple): range of contrast. + saturation_range (tuple): range of saturation. + hue_delta (int): delta of hue. + """ + + def __init__(self, + brightness_delta=32, + contrast_range=(0.5, 1.5), + saturation_range=(0.5, 1.5), + hue_delta=18): + self.brightness_delta = brightness_delta + self.contrast_lower, self.contrast_upper = contrast_range + self.saturation_lower, self.saturation_upper = saturation_range + self.hue_delta = hue_delta + + def convert(self, img, alpha=1, beta=0): + """Multiple with alpha and add beat with clip.""" + img = img.astype(np.float32) * alpha + beta + img = np.clip(img, 0, 255) + return img.astype(np.uint8) + + def brightness(self, img): + """Brightness distortion.""" + if random.randint(2): + return self.convert( + img, + beta=random.uniform(-self.brightness_delta, + self.brightness_delta)) + return img + + def contrast(self, img): + """Contrast distortion.""" + if random.randint(2): + return self.convert( + img, + alpha=random.uniform(self.contrast_lower, self.contrast_upper)) + return img + + def saturation(self, img): + """Saturation distortion.""" + if random.randint(2): + img = mmcv.bgr2hsv(img) + img[:, :, 1] = self.convert( + img[:, :, 1], + alpha=random.uniform(self.saturation_lower, + self.saturation_upper)) + img = mmcv.hsv2bgr(img) + return img + + def hue(self, img): + """Hue distortion.""" + if random.randint(2): + img = mmcv.bgr2hsv(img) + img[:, :, + 0] = (img[:, :, 0].astype(int) + + random.randint(-self.hue_delta, self.hue_delta)) % 180 + img = mmcv.hsv2bgr(img) + return img + + def __call__(self, results): + """Call function to perform photometric distortion on images. + + Args: + results (dict): Result dict from loading pipeline. + + Returns: + dict: Result dict with images distorted. + """ + + img = results['img'] + # random brightness + img = self.brightness(img) + + # mode == 0 --> do random contrast first + # mode == 1 --> do random contrast last + mode = random.randint(2) + if mode == 1: + img = self.contrast(img) + + # random saturation + img = self.saturation(img) + + # random hue + img = self.hue(img) + + # random contrast + if mode == 0: + img = self.contrast(img) + + results['img'] = img + return results + + def __repr__(self): + repr_str = self.__class__.__name__ + repr_str += (f'(brightness_delta={self.brightness_delta}, ' + f'contrast_range=({self.contrast_lower}, ' + f'{self.contrast_upper}), ' + f'saturation_range=({self.saturation_lower}, ' + f'{self.saturation_upper}), ' + f'hue_delta={self.hue_delta})') + return repr_str diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/stare.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/stare.py new file mode 100644 index 00000000..cbd14e09 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/stare.py @@ -0,0 +1,27 @@ +import os.path as osp + +from .builder import DATASETS +from .custom import CustomDataset + + +@DATASETS.register_module() +class STAREDataset(CustomDataset): + """STARE dataset. + + In segmentation map annotation for STARE, 0 stands for background, which is + included in 2 categories. ``reduce_zero_label`` is fixed to False. The + ``img_suffix`` is fixed to '.png' and ``seg_map_suffix`` is fixed to + '.ah.png'. + """ + + CLASSES = ('background', 'vessel') + + PALETTE = [[120, 120, 120], [6, 230, 230]] + + def __init__(self, **kwargs): + super(STAREDataset, self).__init__( + img_suffix='.png', + seg_map_suffix='.ah.png', + reduce_zero_label=False, + **kwargs) + assert osp.exists(self.img_dir) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/voc.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/voc.py new file mode 100644 index 00000000..a8855203 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/datasets/voc.py @@ -0,0 +1,29 @@ +import os.path as osp + +from .builder import DATASETS +from .custom import CustomDataset + + +@DATASETS.register_module() +class PascalVOCDataset(CustomDataset): + """Pascal VOC dataset. + + Args: + split (str): Split txt file for Pascal VOC. + """ + + CLASSES = ('background', 'aeroplane', 'bicycle', 'bird', 'boat', 'bottle', + 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', + 'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', + 'train', 'tvmonitor') + + PALETTE = [[0, 0, 0], [128, 0, 0], [0, 128, 0], [128, 128, 0], [0, 0, 128], + [128, 0, 128], [0, 128, 128], [128, 128, 128], [64, 0, 0], + [192, 0, 0], [64, 128, 0], [192, 128, 0], [64, 0, 128], + [192, 0, 128], [64, 128, 128], [192, 128, 128], [0, 64, 0], + [128, 64, 0], [0, 192, 0], [128, 192, 0], [0, 64, 128]] + + def __init__(self, split, **kwargs): + super(PascalVOCDataset, self).__init__( + img_suffix='.jpg', seg_map_suffix='.png', split=split, **kwargs) + assert osp.exists(self.img_dir) and self.split is not None diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/__init__.py new file mode 100644 index 00000000..3cf93f8b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/__init__.py @@ -0,0 +1,12 @@ +from .backbones import * # noqa: F401,F403 +from .builder import (BACKBONES, HEADS, LOSSES, SEGMENTORS, build_backbone, + build_head, build_loss, build_segmentor) +from .decode_heads import * # noqa: F401,F403 +from .losses import * # noqa: F401,F403 +from .necks import * # noqa: F401,F403 +from .segmentors import * # noqa: F401,F403 + +__all__ = [ + 'BACKBONES', 'HEADS', 'LOSSES', 'SEGMENTORS', 'build_backbone', + 'build_head', 'build_loss', 'build_segmentor' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/__init__.py new file mode 100644 index 00000000..a1116c00 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/__init__.py @@ -0,0 +1,16 @@ +from .cgnet import CGNet +# from .fast_scnn import FastSCNN +from .hrnet import HRNet +from .mobilenet_v2 import MobileNetV2 +from .mobilenet_v3 import MobileNetV3 +from .resnest import ResNeSt +from .resnet import ResNet, ResNetV1c, ResNetV1d +from .resnext import ResNeXt +from .unet import UNet +from .vit import VisionTransformer + +__all__ = [ + 'ResNet', 'ResNetV1c', 'ResNetV1d', 'ResNeXt', 'HRNet', + 'ResNeSt', 'MobileNetV2', 'UNet', 'CGNet', 'MobileNetV3', + 'VisionTransformer' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/cgnet.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/cgnet.py new file mode 100644 index 00000000..45c235e2 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/cgnet.py @@ -0,0 +1,367 @@ +import torch +import torch.nn as nn +import torch.utils.checkpoint as cp +from annotator.mmpkg.mmcv.cnn import (ConvModule, build_conv_layer, build_norm_layer, + constant_init, kaiming_init) +from annotator.mmpkg.mmcv.runner import load_checkpoint +from annotator.mmpkg.mmcv.utils.parrots_wrapper import _BatchNorm + +from annotator.mmpkg.mmseg.utils import get_root_logger +from ..builder import BACKBONES + + +class GlobalContextExtractor(nn.Module): + """Global Context Extractor for CGNet. + + This class is employed to refine the joint feature of both local feature + and surrounding context. + + Args: + channel (int): Number of input feature channels. + reduction (int): Reductions for global context extractor. Default: 16. + with_cp (bool): Use checkpoint or not. Using checkpoint will save some + memory while slowing down the training speed. Default: False. + """ + + def __init__(self, channel, reduction=16, with_cp=False): + super(GlobalContextExtractor, self).__init__() + self.channel = channel + self.reduction = reduction + assert reduction >= 1 and channel >= reduction + self.with_cp = with_cp + self.avg_pool = nn.AdaptiveAvgPool2d(1) + self.fc = nn.Sequential( + nn.Linear(channel, channel // reduction), nn.ReLU(inplace=True), + nn.Linear(channel // reduction, channel), nn.Sigmoid()) + + def forward(self, x): + + def _inner_forward(x): + num_batch, num_channel = x.size()[:2] + y = self.avg_pool(x).view(num_batch, num_channel) + y = self.fc(y).view(num_batch, num_channel, 1, 1) + return x * y + + if self.with_cp and x.requires_grad: + out = cp.checkpoint(_inner_forward, x) + else: + out = _inner_forward(x) + + return out + + +class ContextGuidedBlock(nn.Module): + """Context Guided Block for CGNet. + + This class consists of four components: local feature extractor, + surrounding feature extractor, joint feature extractor and global + context extractor. + + Args: + in_channels (int): Number of input feature channels. + out_channels (int): Number of output feature channels. + dilation (int): Dilation rate for surrounding context extractor. + Default: 2. + reduction (int): Reduction for global context extractor. Default: 16. + skip_connect (bool): Add input to output or not. Default: True. + downsample (bool): Downsample the input to 1/2 or not. Default: False. + conv_cfg (dict): Config dict for convolution layer. + Default: None, which means using conv2d. + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='BN', requires_grad=True). + act_cfg (dict): Config dict for activation layer. + Default: dict(type='PReLU'). + with_cp (bool): Use checkpoint or not. Using checkpoint will save some + memory while slowing down the training speed. Default: False. + """ + + def __init__(self, + in_channels, + out_channels, + dilation=2, + reduction=16, + skip_connect=True, + downsample=False, + conv_cfg=None, + norm_cfg=dict(type='BN', requires_grad=True), + act_cfg=dict(type='PReLU'), + with_cp=False): + super(ContextGuidedBlock, self).__init__() + self.with_cp = with_cp + self.downsample = downsample + + channels = out_channels if downsample else out_channels // 2 + if 'type' in act_cfg and act_cfg['type'] == 'PReLU': + act_cfg['num_parameters'] = channels + kernel_size = 3 if downsample else 1 + stride = 2 if downsample else 1 + padding = (kernel_size - 1) // 2 + + self.conv1x1 = ConvModule( + in_channels, + channels, + kernel_size, + stride, + padding, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + + self.f_loc = build_conv_layer( + conv_cfg, + channels, + channels, + kernel_size=3, + padding=1, + groups=channels, + bias=False) + self.f_sur = build_conv_layer( + conv_cfg, + channels, + channels, + kernel_size=3, + padding=dilation, + groups=channels, + dilation=dilation, + bias=False) + + self.bn = build_norm_layer(norm_cfg, 2 * channels)[1] + self.activate = nn.PReLU(2 * channels) + + if downsample: + self.bottleneck = build_conv_layer( + conv_cfg, + 2 * channels, + out_channels, + kernel_size=1, + bias=False) + + self.skip_connect = skip_connect and not downsample + self.f_glo = GlobalContextExtractor(out_channels, reduction, with_cp) + + def forward(self, x): + + def _inner_forward(x): + out = self.conv1x1(x) + loc = self.f_loc(out) + sur = self.f_sur(out) + + joi_feat = torch.cat([loc, sur], 1) # the joint feature + joi_feat = self.bn(joi_feat) + joi_feat = self.activate(joi_feat) + if self.downsample: + joi_feat = self.bottleneck(joi_feat) # channel = out_channels + # f_glo is employed to refine the joint feature + out = self.f_glo(joi_feat) + + if self.skip_connect: + return x + out + else: + return out + + if self.with_cp and x.requires_grad: + out = cp.checkpoint(_inner_forward, x) + else: + out = _inner_forward(x) + + return out + + +class InputInjection(nn.Module): + """Downsampling module for CGNet.""" + + def __init__(self, num_downsampling): + super(InputInjection, self).__init__() + self.pool = nn.ModuleList() + for i in range(num_downsampling): + self.pool.append(nn.AvgPool2d(3, stride=2, padding=1)) + + def forward(self, x): + for pool in self.pool: + x = pool(x) + return x + + +@BACKBONES.register_module() +class CGNet(nn.Module): + """CGNet backbone. + + A Light-weight Context Guided Network for Semantic Segmentation + arXiv: https://arxiv.org/abs/1811.08201 + + Args: + in_channels (int): Number of input image channels. Normally 3. + num_channels (tuple[int]): Numbers of feature channels at each stages. + Default: (32, 64, 128). + num_blocks (tuple[int]): Numbers of CG blocks at stage 1 and stage 2. + Default: (3, 21). + dilations (tuple[int]): Dilation rate for surrounding context + extractors at stage 1 and stage 2. Default: (2, 4). + reductions (tuple[int]): Reductions for global context extractors at + stage 1 and stage 2. Default: (8, 16). + conv_cfg (dict): Config dict for convolution layer. + Default: None, which means using conv2d. + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='BN', requires_grad=True). + act_cfg (dict): Config dict for activation layer. + Default: dict(type='PReLU'). + norm_eval (bool): Whether to set norm layers to eval mode, namely, + freeze running stats (mean and var). Note: Effect on Batch Norm + and its variants only. Default: False. + with_cp (bool): Use checkpoint or not. Using checkpoint will save some + memory while slowing down the training speed. Default: False. + """ + + def __init__(self, + in_channels=3, + num_channels=(32, 64, 128), + num_blocks=(3, 21), + dilations=(2, 4), + reductions=(8, 16), + conv_cfg=None, + norm_cfg=dict(type='BN', requires_grad=True), + act_cfg=dict(type='PReLU'), + norm_eval=False, + with_cp=False): + + super(CGNet, self).__init__() + self.in_channels = in_channels + self.num_channels = num_channels + assert isinstance(self.num_channels, tuple) and len( + self.num_channels) == 3 + self.num_blocks = num_blocks + assert isinstance(self.num_blocks, tuple) and len(self.num_blocks) == 2 + self.dilations = dilations + assert isinstance(self.dilations, tuple) and len(self.dilations) == 2 + self.reductions = reductions + assert isinstance(self.reductions, tuple) and len(self.reductions) == 2 + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + if 'type' in self.act_cfg and self.act_cfg['type'] == 'PReLU': + self.act_cfg['num_parameters'] = num_channels[0] + self.norm_eval = norm_eval + self.with_cp = with_cp + + cur_channels = in_channels + self.stem = nn.ModuleList() + for i in range(3): + self.stem.append( + ConvModule( + cur_channels, + num_channels[0], + 3, + 2 if i == 0 else 1, + padding=1, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg)) + cur_channels = num_channels[0] + + self.inject_2x = InputInjection(1) # down-sample for Input, factor=2 + self.inject_4x = InputInjection(2) # down-sample for Input, factor=4 + + cur_channels += in_channels + self.norm_prelu_0 = nn.Sequential( + build_norm_layer(norm_cfg, cur_channels)[1], + nn.PReLU(cur_channels)) + + # stage 1 + self.level1 = nn.ModuleList() + for i in range(num_blocks[0]): + self.level1.append( + ContextGuidedBlock( + cur_channels if i == 0 else num_channels[1], + num_channels[1], + dilations[0], + reductions[0], + downsample=(i == 0), + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg, + with_cp=with_cp)) # CG block + + cur_channels = 2 * num_channels[1] + in_channels + self.norm_prelu_1 = nn.Sequential( + build_norm_layer(norm_cfg, cur_channels)[1], + nn.PReLU(cur_channels)) + + # stage 2 + self.level2 = nn.ModuleList() + for i in range(num_blocks[1]): + self.level2.append( + ContextGuidedBlock( + cur_channels if i == 0 else num_channels[2], + num_channels[2], + dilations[1], + reductions[1], + downsample=(i == 0), + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg, + with_cp=with_cp)) # CG block + + cur_channels = 2 * num_channels[2] + self.norm_prelu_2 = nn.Sequential( + build_norm_layer(norm_cfg, cur_channels)[1], + nn.PReLU(cur_channels)) + + def forward(self, x): + output = [] + + # stage 0 + inp_2x = self.inject_2x(x) + inp_4x = self.inject_4x(x) + for layer in self.stem: + x = layer(x) + x = self.norm_prelu_0(torch.cat([x, inp_2x], 1)) + output.append(x) + + # stage 1 + for i, layer in enumerate(self.level1): + x = layer(x) + if i == 0: + down1 = x + x = self.norm_prelu_1(torch.cat([x, down1, inp_4x], 1)) + output.append(x) + + # stage 2 + for i, layer in enumerate(self.level2): + x = layer(x) + if i == 0: + down2 = x + x = self.norm_prelu_2(torch.cat([down2, x], 1)) + output.append(x) + + return output + + def init_weights(self, pretrained=None): + """Initialize the weights in backbone. + + Args: + pretrained (str, optional): Path to pre-trained weights. + Defaults to None. + """ + if isinstance(pretrained, str): + logger = get_root_logger() + load_checkpoint(self, pretrained, strict=False, logger=logger) + elif pretrained is None: + for m in self.modules(): + if isinstance(m, (nn.Conv2d, nn.Linear)): + kaiming_init(m) + elif isinstance(m, (_BatchNorm, nn.GroupNorm)): + constant_init(m, 1) + elif isinstance(m, nn.PReLU): + constant_init(m, 0) + else: + raise TypeError('pretrained must be a str or None') + + def train(self, mode=True): + """Convert the model into training mode will keeping the normalization + layer freezed.""" + super(CGNet, self).train(mode) + if mode and self.norm_eval: + for m in self.modules(): + # trick: eval have effect on BatchNorm only + if isinstance(m, _BatchNorm): + m.eval() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/fast_scnn.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/fast_scnn.py new file mode 100644 index 00000000..41711441 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/fast_scnn.py @@ -0,0 +1,375 @@ +import torch +import torch.nn as nn +from annotator.mmpkg.mmcv.cnn import (ConvModule, DepthwiseSeparableConvModule, constant_init, + kaiming_init) +from torch.nn.modules.batchnorm import _BatchNorm + +from annotator.mmpkg.mmseg.models.decode_heads.psp_head import PPM +from annotator.mmpkg.mmseg.ops import resize +from ..builder import BACKBONES +from ..utils.inverted_residual import InvertedResidual + + +class LearningToDownsample(nn.Module): + """Learning to downsample module. + + Args: + in_channels (int): Number of input channels. + dw_channels (tuple[int]): Number of output channels of the first and + the second depthwise conv (dwconv) layers. + out_channels (int): Number of output channels of the whole + 'learning to downsample' module. + conv_cfg (dict | None): Config of conv layers. Default: None + norm_cfg (dict | None): Config of norm layers. Default: + dict(type='BN') + act_cfg (dict): Config of activation layers. Default: + dict(type='ReLU') + """ + + def __init__(self, + in_channels, + dw_channels, + out_channels, + conv_cfg=None, + norm_cfg=dict(type='BN'), + act_cfg=dict(type='ReLU')): + super(LearningToDownsample, self).__init__() + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + dw_channels1 = dw_channels[0] + dw_channels2 = dw_channels[1] + + self.conv = ConvModule( + in_channels, + dw_channels1, + 3, + stride=2, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + self.dsconv1 = DepthwiseSeparableConvModule( + dw_channels1, + dw_channels2, + kernel_size=3, + stride=2, + padding=1, + norm_cfg=self.norm_cfg) + self.dsconv2 = DepthwiseSeparableConvModule( + dw_channels2, + out_channels, + kernel_size=3, + stride=2, + padding=1, + norm_cfg=self.norm_cfg) + + def forward(self, x): + x = self.conv(x) + x = self.dsconv1(x) + x = self.dsconv2(x) + return x + + +class GlobalFeatureExtractor(nn.Module): + """Global feature extractor module. + + Args: + in_channels (int): Number of input channels of the GFE module. + Default: 64 + block_channels (tuple[int]): Tuple of ints. Each int specifies the + number of output channels of each Inverted Residual module. + Default: (64, 96, 128) + out_channels(int): Number of output channels of the GFE module. + Default: 128 + expand_ratio (int): Adjusts number of channels of the hidden layer + in InvertedResidual by this amount. + Default: 6 + num_blocks (tuple[int]): Tuple of ints. Each int specifies the + number of times each Inverted Residual module is repeated. + The repeated Inverted Residual modules are called a 'group'. + Default: (3, 3, 3) + strides (tuple[int]): Tuple of ints. Each int specifies + the downsampling factor of each 'group'. + Default: (2, 2, 1) + pool_scales (tuple[int]): Tuple of ints. Each int specifies + the parameter required in 'global average pooling' within PPM. + Default: (1, 2, 3, 6) + conv_cfg (dict | None): Config of conv layers. Default: None + norm_cfg (dict | None): Config of norm layers. Default: + dict(type='BN') + act_cfg (dict): Config of activation layers. Default: + dict(type='ReLU') + align_corners (bool): align_corners argument of F.interpolate. + Default: False + """ + + def __init__(self, + in_channels=64, + block_channels=(64, 96, 128), + out_channels=128, + expand_ratio=6, + num_blocks=(3, 3, 3), + strides=(2, 2, 1), + pool_scales=(1, 2, 3, 6), + conv_cfg=None, + norm_cfg=dict(type='BN'), + act_cfg=dict(type='ReLU'), + align_corners=False): + super(GlobalFeatureExtractor, self).__init__() + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + assert len(block_channels) == len(num_blocks) == 3 + self.bottleneck1 = self._make_layer(in_channels, block_channels[0], + num_blocks[0], strides[0], + expand_ratio) + self.bottleneck2 = self._make_layer(block_channels[0], + block_channels[1], num_blocks[1], + strides[1], expand_ratio) + self.bottleneck3 = self._make_layer(block_channels[1], + block_channels[2], num_blocks[2], + strides[2], expand_ratio) + self.ppm = PPM( + pool_scales, + block_channels[2], + block_channels[2] // 4, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg, + align_corners=align_corners) + self.out = ConvModule( + block_channels[2] * 2, + out_channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + def _make_layer(self, + in_channels, + out_channels, + blocks, + stride=1, + expand_ratio=6): + layers = [ + InvertedResidual( + in_channels, + out_channels, + stride, + expand_ratio, + norm_cfg=self.norm_cfg) + ] + for i in range(1, blocks): + layers.append( + InvertedResidual( + out_channels, + out_channels, + 1, + expand_ratio, + norm_cfg=self.norm_cfg)) + return nn.Sequential(*layers) + + def forward(self, x): + x = self.bottleneck1(x) + x = self.bottleneck2(x) + x = self.bottleneck3(x) + x = torch.cat([x, *self.ppm(x)], dim=1) + x = self.out(x) + return x + + +class FeatureFusionModule(nn.Module): + """Feature fusion module. + + Args: + higher_in_channels (int): Number of input channels of the + higher-resolution branch. + lower_in_channels (int): Number of input channels of the + lower-resolution branch. + out_channels (int): Number of output channels. + conv_cfg (dict | None): Config of conv layers. Default: None + norm_cfg (dict | None): Config of norm layers. Default: + dict(type='BN') + act_cfg (dict): Config of activation layers. Default: + dict(type='ReLU') + align_corners (bool): align_corners argument of F.interpolate. + Default: False + """ + + def __init__(self, + higher_in_channels, + lower_in_channels, + out_channels, + conv_cfg=None, + norm_cfg=dict(type='BN'), + act_cfg=dict(type='ReLU'), + align_corners=False): + super(FeatureFusionModule, self).__init__() + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + self.align_corners = align_corners + self.dwconv = ConvModule( + lower_in_channels, + out_channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + self.conv_lower_res = ConvModule( + out_channels, + out_channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=None) + self.conv_higher_res = ConvModule( + higher_in_channels, + out_channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=None) + self.relu = nn.ReLU(True) + + def forward(self, higher_res_feature, lower_res_feature): + lower_res_feature = resize( + lower_res_feature, + size=higher_res_feature.size()[2:], + mode='bilinear', + align_corners=self.align_corners) + lower_res_feature = self.dwconv(lower_res_feature) + lower_res_feature = self.conv_lower_res(lower_res_feature) + + higher_res_feature = self.conv_higher_res(higher_res_feature) + out = higher_res_feature + lower_res_feature + return self.relu(out) + + +@BACKBONES.register_module() +class FastSCNN(nn.Module): + """Fast-SCNN Backbone. + + Args: + in_channels (int): Number of input image channels. Default: 3. + downsample_dw_channels (tuple[int]): Number of output channels after + the first conv layer & the second conv layer in + Learning-To-Downsample (LTD) module. + Default: (32, 48). + global_in_channels (int): Number of input channels of + Global Feature Extractor(GFE). + Equal to number of output channels of LTD. + Default: 64. + global_block_channels (tuple[int]): Tuple of integers that describe + the output channels for each of the MobileNet-v2 bottleneck + residual blocks in GFE. + Default: (64, 96, 128). + global_block_strides (tuple[int]): Tuple of integers + that describe the strides (downsampling factors) for each of the + MobileNet-v2 bottleneck residual blocks in GFE. + Default: (2, 2, 1). + global_out_channels (int): Number of output channels of GFE. + Default: 128. + higher_in_channels (int): Number of input channels of the higher + resolution branch in FFM. + Equal to global_in_channels. + Default: 64. + lower_in_channels (int): Number of input channels of the lower + resolution branch in FFM. + Equal to global_out_channels. + Default: 128. + fusion_out_channels (int): Number of output channels of FFM. + Default: 128. + out_indices (tuple): Tuple of indices of list + [higher_res_features, lower_res_features, fusion_output]. + Often set to (0,1,2) to enable aux. heads. + Default: (0, 1, 2). + conv_cfg (dict | None): Config of conv layers. Default: None + norm_cfg (dict | None): Config of norm layers. Default: + dict(type='BN') + act_cfg (dict): Config of activation layers. Default: + dict(type='ReLU') + align_corners (bool): align_corners argument of F.interpolate. + Default: False + """ + + def __init__(self, + in_channels=3, + downsample_dw_channels=(32, 48), + global_in_channels=64, + global_block_channels=(64, 96, 128), + global_block_strides=(2, 2, 1), + global_out_channels=128, + higher_in_channels=64, + lower_in_channels=128, + fusion_out_channels=128, + out_indices=(0, 1, 2), + conv_cfg=None, + norm_cfg=dict(type='BN'), + act_cfg=dict(type='ReLU'), + align_corners=False): + + super(FastSCNN, self).__init__() + if global_in_channels != higher_in_channels: + raise AssertionError('Global Input Channels must be the same \ + with Higher Input Channels!') + elif global_out_channels != lower_in_channels: + raise AssertionError('Global Output Channels must be the same \ + with Lower Input Channels!') + + self.in_channels = in_channels + self.downsample_dw_channels1 = downsample_dw_channels[0] + self.downsample_dw_channels2 = downsample_dw_channels[1] + self.global_in_channels = global_in_channels + self.global_block_channels = global_block_channels + self.global_block_strides = global_block_strides + self.global_out_channels = global_out_channels + self.higher_in_channels = higher_in_channels + self.lower_in_channels = lower_in_channels + self.fusion_out_channels = fusion_out_channels + self.out_indices = out_indices + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + self.align_corners = align_corners + self.learning_to_downsample = LearningToDownsample( + in_channels, + downsample_dw_channels, + global_in_channels, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + self.global_feature_extractor = GlobalFeatureExtractor( + global_in_channels, + global_block_channels, + global_out_channels, + strides=self.global_block_strides, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg, + align_corners=self.align_corners) + self.feature_fusion = FeatureFusionModule( + higher_in_channels, + lower_in_channels, + fusion_out_channels, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg, + align_corners=self.align_corners) + + def init_weights(self, pretrained=None): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + kaiming_init(m) + elif isinstance(m, (_BatchNorm, nn.GroupNorm)): + constant_init(m, 1) + + def forward(self, x): + higher_res_features = self.learning_to_downsample(x) + lower_res_features = self.global_feature_extractor(higher_res_features) + fusion_output = self.feature_fusion(higher_res_features, + lower_res_features) + + outs = [higher_res_features, lower_res_features, fusion_output] + outs = [outs[i] for i in self.out_indices] + return tuple(outs) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/hrnet.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/hrnet.py new file mode 100644 index 00000000..8d77fd6e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/hrnet.py @@ -0,0 +1,555 @@ +import torch.nn as nn +from annotator.mmpkg.mmcv.cnn import (build_conv_layer, build_norm_layer, constant_init, + kaiming_init) +from annotator.mmpkg.mmcv.runner import load_checkpoint +from annotator.mmpkg.mmcv.utils.parrots_wrapper import _BatchNorm + +from annotator.mmpkg.mmseg.ops import Upsample, resize +from annotator.mmpkg.mmseg.utils import get_root_logger +from ..builder import BACKBONES +from .resnet import BasicBlock, Bottleneck + + +class HRModule(nn.Module): + """High-Resolution Module for HRNet. + + In this module, every branch has 4 BasicBlocks/Bottlenecks. Fusion/Exchange + is in this module. + """ + + def __init__(self, + num_branches, + blocks, + num_blocks, + in_channels, + num_channels, + multiscale_output=True, + with_cp=False, + conv_cfg=None, + norm_cfg=dict(type='BN', requires_grad=True)): + super(HRModule, self).__init__() + self._check_branches(num_branches, num_blocks, in_channels, + num_channels) + + self.in_channels = in_channels + self.num_branches = num_branches + + self.multiscale_output = multiscale_output + self.norm_cfg = norm_cfg + self.conv_cfg = conv_cfg + self.with_cp = with_cp + self.branches = self._make_branches(num_branches, blocks, num_blocks, + num_channels) + self.fuse_layers = self._make_fuse_layers() + self.relu = nn.ReLU(inplace=False) + + def _check_branches(self, num_branches, num_blocks, in_channels, + num_channels): + """Check branches configuration.""" + if num_branches != len(num_blocks): + error_msg = f'NUM_BRANCHES({num_branches}) <> NUM_BLOCKS(' \ + f'{len(num_blocks)})' + raise ValueError(error_msg) + + if num_branches != len(num_channels): + error_msg = f'NUM_BRANCHES({num_branches}) <> NUM_CHANNELS(' \ + f'{len(num_channels)})' + raise ValueError(error_msg) + + if num_branches != len(in_channels): + error_msg = f'NUM_BRANCHES({num_branches}) <> NUM_INCHANNELS(' \ + f'{len(in_channels)})' + raise ValueError(error_msg) + + def _make_one_branch(self, + branch_index, + block, + num_blocks, + num_channels, + stride=1): + """Build one branch.""" + downsample = None + if stride != 1 or \ + self.in_channels[branch_index] != \ + num_channels[branch_index] * block.expansion: + downsample = nn.Sequential( + build_conv_layer( + self.conv_cfg, + self.in_channels[branch_index], + num_channels[branch_index] * block.expansion, + kernel_size=1, + stride=stride, + bias=False), + build_norm_layer(self.norm_cfg, num_channels[branch_index] * + block.expansion)[1]) + + layers = [] + layers.append( + block( + self.in_channels[branch_index], + num_channels[branch_index], + stride, + downsample=downsample, + with_cp=self.with_cp, + norm_cfg=self.norm_cfg, + conv_cfg=self.conv_cfg)) + self.in_channels[branch_index] = \ + num_channels[branch_index] * block.expansion + for i in range(1, num_blocks[branch_index]): + layers.append( + block( + self.in_channels[branch_index], + num_channels[branch_index], + with_cp=self.with_cp, + norm_cfg=self.norm_cfg, + conv_cfg=self.conv_cfg)) + + return nn.Sequential(*layers) + + def _make_branches(self, num_branches, block, num_blocks, num_channels): + """Build multiple branch.""" + branches = [] + + for i in range(num_branches): + branches.append( + self._make_one_branch(i, block, num_blocks, num_channels)) + + return nn.ModuleList(branches) + + def _make_fuse_layers(self): + """Build fuse layer.""" + if self.num_branches == 1: + return None + + num_branches = self.num_branches + in_channels = self.in_channels + fuse_layers = [] + num_out_branches = num_branches if self.multiscale_output else 1 + for i in range(num_out_branches): + fuse_layer = [] + for j in range(num_branches): + if j > i: + fuse_layer.append( + nn.Sequential( + build_conv_layer( + self.conv_cfg, + in_channels[j], + in_channels[i], + kernel_size=1, + stride=1, + padding=0, + bias=False), + build_norm_layer(self.norm_cfg, in_channels[i])[1], + # we set align_corners=False for HRNet + Upsample( + scale_factor=2**(j - i), + mode='bilinear', + align_corners=False))) + elif j == i: + fuse_layer.append(None) + else: + conv_downsamples = [] + for k in range(i - j): + if k == i - j - 1: + conv_downsamples.append( + nn.Sequential( + build_conv_layer( + self.conv_cfg, + in_channels[j], + in_channels[i], + kernel_size=3, + stride=2, + padding=1, + bias=False), + build_norm_layer(self.norm_cfg, + in_channels[i])[1])) + else: + conv_downsamples.append( + nn.Sequential( + build_conv_layer( + self.conv_cfg, + in_channels[j], + in_channels[j], + kernel_size=3, + stride=2, + padding=1, + bias=False), + build_norm_layer(self.norm_cfg, + in_channels[j])[1], + nn.ReLU(inplace=False))) + fuse_layer.append(nn.Sequential(*conv_downsamples)) + fuse_layers.append(nn.ModuleList(fuse_layer)) + + return nn.ModuleList(fuse_layers) + + def forward(self, x): + """Forward function.""" + if self.num_branches == 1: + return [self.branches[0](x[0])] + + for i in range(self.num_branches): + x[i] = self.branches[i](x[i]) + + x_fuse = [] + for i in range(len(self.fuse_layers)): + y = 0 + for j in range(self.num_branches): + if i == j: + y += x[j] + elif j > i: + y = y + resize( + self.fuse_layers[i][j](x[j]), + size=x[i].shape[2:], + mode='bilinear', + align_corners=False) + else: + y += self.fuse_layers[i][j](x[j]) + x_fuse.append(self.relu(y)) + return x_fuse + + +@BACKBONES.register_module() +class HRNet(nn.Module): + """HRNet backbone. + + High-Resolution Representations for Labeling Pixels and Regions + arXiv: https://arxiv.org/abs/1904.04514 + + Args: + extra (dict): detailed configuration for each stage of HRNet. + in_channels (int): Number of input image channels. Normally 3. + conv_cfg (dict): dictionary to construct and config conv layer. + norm_cfg (dict): dictionary to construct and config norm layer. + norm_eval (bool): Whether to set norm layers to eval mode, namely, + freeze running stats (mean and var). Note: Effect on Batch Norm + and its variants only. + with_cp (bool): Use checkpoint or not. Using checkpoint will save some + memory while slowing down the training speed. + zero_init_residual (bool): whether to use zero init for last norm layer + in resblocks to let them behave as identity. + + Example: + >>> from annotator.mmpkg.mmseg.models import HRNet + >>> import torch + >>> extra = dict( + >>> stage1=dict( + >>> num_modules=1, + >>> num_branches=1, + >>> block='BOTTLENECK', + >>> num_blocks=(4, ), + >>> num_channels=(64, )), + >>> stage2=dict( + >>> num_modules=1, + >>> num_branches=2, + >>> block='BASIC', + >>> num_blocks=(4, 4), + >>> num_channels=(32, 64)), + >>> stage3=dict( + >>> num_modules=4, + >>> num_branches=3, + >>> block='BASIC', + >>> num_blocks=(4, 4, 4), + >>> num_channels=(32, 64, 128)), + >>> stage4=dict( + >>> num_modules=3, + >>> num_branches=4, + >>> block='BASIC', + >>> num_blocks=(4, 4, 4, 4), + >>> num_channels=(32, 64, 128, 256))) + >>> self = HRNet(extra, in_channels=1) + >>> self.eval() + >>> inputs = torch.rand(1, 1, 32, 32) + >>> level_outputs = self.forward(inputs) + >>> for level_out in level_outputs: + ... print(tuple(level_out.shape)) + (1, 32, 8, 8) + (1, 64, 4, 4) + (1, 128, 2, 2) + (1, 256, 1, 1) + """ + + blocks_dict = {'BASIC': BasicBlock, 'BOTTLENECK': Bottleneck} + + def __init__(self, + extra, + in_channels=3, + conv_cfg=None, + norm_cfg=dict(type='BN', requires_grad=True), + norm_eval=False, + with_cp=False, + zero_init_residual=False): + super(HRNet, self).__init__() + self.extra = extra + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.norm_eval = norm_eval + self.with_cp = with_cp + self.zero_init_residual = zero_init_residual + + # stem net + self.norm1_name, norm1 = build_norm_layer(self.norm_cfg, 64, postfix=1) + self.norm2_name, norm2 = build_norm_layer(self.norm_cfg, 64, postfix=2) + + self.conv1 = build_conv_layer( + self.conv_cfg, + in_channels, + 64, + kernel_size=3, + stride=2, + padding=1, + bias=False) + + self.add_module(self.norm1_name, norm1) + self.conv2 = build_conv_layer( + self.conv_cfg, + 64, + 64, + kernel_size=3, + stride=2, + padding=1, + bias=False) + + self.add_module(self.norm2_name, norm2) + self.relu = nn.ReLU(inplace=True) + + # stage 1 + self.stage1_cfg = self.extra['stage1'] + num_channels = self.stage1_cfg['num_channels'][0] + block_type = self.stage1_cfg['block'] + num_blocks = self.stage1_cfg['num_blocks'][0] + + block = self.blocks_dict[block_type] + stage1_out_channels = num_channels * block.expansion + self.layer1 = self._make_layer(block, 64, num_channels, num_blocks) + + # stage 2 + self.stage2_cfg = self.extra['stage2'] + num_channels = self.stage2_cfg['num_channels'] + block_type = self.stage2_cfg['block'] + + block = self.blocks_dict[block_type] + num_channels = [channel * block.expansion for channel in num_channels] + self.transition1 = self._make_transition_layer([stage1_out_channels], + num_channels) + self.stage2, pre_stage_channels = self._make_stage( + self.stage2_cfg, num_channels) + + # stage 3 + self.stage3_cfg = self.extra['stage3'] + num_channels = self.stage3_cfg['num_channels'] + block_type = self.stage3_cfg['block'] + + block = self.blocks_dict[block_type] + num_channels = [channel * block.expansion for channel in num_channels] + self.transition2 = self._make_transition_layer(pre_stage_channels, + num_channels) + self.stage3, pre_stage_channels = self._make_stage( + self.stage3_cfg, num_channels) + + # stage 4 + self.stage4_cfg = self.extra['stage4'] + num_channels = self.stage4_cfg['num_channels'] + block_type = self.stage4_cfg['block'] + + block = self.blocks_dict[block_type] + num_channels = [channel * block.expansion for channel in num_channels] + self.transition3 = self._make_transition_layer(pre_stage_channels, + num_channels) + self.stage4, pre_stage_channels = self._make_stage( + self.stage4_cfg, num_channels) + + @property + def norm1(self): + """nn.Module: the normalization layer named "norm1" """ + return getattr(self, self.norm1_name) + + @property + def norm2(self): + """nn.Module: the normalization layer named "norm2" """ + return getattr(self, self.norm2_name) + + def _make_transition_layer(self, num_channels_pre_layer, + num_channels_cur_layer): + """Make transition layer.""" + num_branches_cur = len(num_channels_cur_layer) + num_branches_pre = len(num_channels_pre_layer) + + transition_layers = [] + for i in range(num_branches_cur): + if i < num_branches_pre: + if num_channels_cur_layer[i] != num_channels_pre_layer[i]: + transition_layers.append( + nn.Sequential( + build_conv_layer( + self.conv_cfg, + num_channels_pre_layer[i], + num_channels_cur_layer[i], + kernel_size=3, + stride=1, + padding=1, + bias=False), + build_norm_layer(self.norm_cfg, + num_channels_cur_layer[i])[1], + nn.ReLU(inplace=True))) + else: + transition_layers.append(None) + else: + conv_downsamples = [] + for j in range(i + 1 - num_branches_pre): + in_channels = num_channels_pre_layer[-1] + out_channels = num_channels_cur_layer[i] \ + if j == i - num_branches_pre else in_channels + conv_downsamples.append( + nn.Sequential( + build_conv_layer( + self.conv_cfg, + in_channels, + out_channels, + kernel_size=3, + stride=2, + padding=1, + bias=False), + build_norm_layer(self.norm_cfg, out_channels)[1], + nn.ReLU(inplace=True))) + transition_layers.append(nn.Sequential(*conv_downsamples)) + + return nn.ModuleList(transition_layers) + + def _make_layer(self, block, inplanes, planes, blocks, stride=1): + """Make each layer.""" + downsample = None + if stride != 1 or inplanes != planes * block.expansion: + downsample = nn.Sequential( + build_conv_layer( + self.conv_cfg, + inplanes, + planes * block.expansion, + kernel_size=1, + stride=stride, + bias=False), + build_norm_layer(self.norm_cfg, planes * block.expansion)[1]) + + layers = [] + layers.append( + block( + inplanes, + planes, + stride, + downsample=downsample, + with_cp=self.with_cp, + norm_cfg=self.norm_cfg, + conv_cfg=self.conv_cfg)) + inplanes = planes * block.expansion + for i in range(1, blocks): + layers.append( + block( + inplanes, + planes, + with_cp=self.with_cp, + norm_cfg=self.norm_cfg, + conv_cfg=self.conv_cfg)) + + return nn.Sequential(*layers) + + def _make_stage(self, layer_config, in_channels, multiscale_output=True): + """Make each stage.""" + num_modules = layer_config['num_modules'] + num_branches = layer_config['num_branches'] + num_blocks = layer_config['num_blocks'] + num_channels = layer_config['num_channels'] + block = self.blocks_dict[layer_config['block']] + + hr_modules = [] + for i in range(num_modules): + # multi_scale_output is only used for the last module + if not multiscale_output and i == num_modules - 1: + reset_multiscale_output = False + else: + reset_multiscale_output = True + + hr_modules.append( + HRModule( + num_branches, + block, + num_blocks, + in_channels, + num_channels, + reset_multiscale_output, + with_cp=self.with_cp, + norm_cfg=self.norm_cfg, + conv_cfg=self.conv_cfg)) + + return nn.Sequential(*hr_modules), in_channels + + def init_weights(self, pretrained=None): + """Initialize the weights in backbone. + + Args: + pretrained (str, optional): Path to pre-trained weights. + Defaults to None. + """ + if isinstance(pretrained, str): + logger = get_root_logger() + load_checkpoint(self, pretrained, strict=False, logger=logger) + elif pretrained is None: + for m in self.modules(): + if isinstance(m, nn.Conv2d): + kaiming_init(m) + elif isinstance(m, (_BatchNorm, nn.GroupNorm)): + constant_init(m, 1) + + if self.zero_init_residual: + for m in self.modules(): + if isinstance(m, Bottleneck): + constant_init(m.norm3, 0) + elif isinstance(m, BasicBlock): + constant_init(m.norm2, 0) + else: + raise TypeError('pretrained must be a str or None') + + def forward(self, x): + """Forward function.""" + + x = self.conv1(x) + x = self.norm1(x) + x = self.relu(x) + x = self.conv2(x) + x = self.norm2(x) + x = self.relu(x) + x = self.layer1(x) + + x_list = [] + for i in range(self.stage2_cfg['num_branches']): + if self.transition1[i] is not None: + x_list.append(self.transition1[i](x)) + else: + x_list.append(x) + y_list = self.stage2(x_list) + + x_list = [] + for i in range(self.stage3_cfg['num_branches']): + if self.transition2[i] is not None: + x_list.append(self.transition2[i](y_list[-1])) + else: + x_list.append(y_list[i]) + y_list = self.stage3(x_list) + + x_list = [] + for i in range(self.stage4_cfg['num_branches']): + if self.transition3[i] is not None: + x_list.append(self.transition3[i](y_list[-1])) + else: + x_list.append(y_list[i]) + y_list = self.stage4(x_list) + + return y_list + + def train(self, mode=True): + """Convert the model into training mode will keeping the normalization + layer freezed.""" + super(HRNet, self).train(mode) + if mode and self.norm_eval: + for m in self.modules(): + # trick: eval have effect on BatchNorm only + if isinstance(m, _BatchNorm): + m.eval() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/mobilenet_v2.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/mobilenet_v2.py new file mode 100644 index 00000000..7b5b6cd6 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/mobilenet_v2.py @@ -0,0 +1,180 @@ +import logging + +import torch.nn as nn +from annotator.mmpkg.mmcv.cnn import ConvModule, constant_init, kaiming_init +from annotator.mmpkg.mmcv.runner import load_checkpoint +from torch.nn.modules.batchnorm import _BatchNorm + +from ..builder import BACKBONES +from ..utils import InvertedResidual, make_divisible + + +@BACKBONES.register_module() +class MobileNetV2(nn.Module): + """MobileNetV2 backbone. + + Args: + widen_factor (float): Width multiplier, multiply number of + channels in each layer by this amount. Default: 1.0. + strides (Sequence[int], optional): Strides of the first block of each + layer. If not specified, default config in ``arch_setting`` will + be used. + dilations (Sequence[int]): Dilation of each layer. + out_indices (None or Sequence[int]): Output from which stages. + Default: (7, ). + frozen_stages (int): Stages to be frozen (all param fixed). + Default: -1, which means not freezing any parameters. + conv_cfg (dict): Config dict for convolution layer. + Default: None, which means using conv2d. + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='BN'). + act_cfg (dict): Config dict for activation layer. + Default: dict(type='ReLU6'). + norm_eval (bool): Whether to set norm layers to eval mode, namely, + freeze running stats (mean and var). Note: Effect on Batch Norm + and its variants only. Default: False. + with_cp (bool): Use checkpoint or not. Using checkpoint will save some + memory while slowing down the training speed. Default: False. + """ + + # Parameters to build layers. 3 parameters are needed to construct a + # layer, from left to right: expand_ratio, channel, num_blocks. + arch_settings = [[1, 16, 1], [6, 24, 2], [6, 32, 3], [6, 64, 4], + [6, 96, 3], [6, 160, 3], [6, 320, 1]] + + def __init__(self, + widen_factor=1., + strides=(1, 2, 2, 2, 1, 2, 1), + dilations=(1, 1, 1, 1, 1, 1, 1), + out_indices=(1, 2, 4, 6), + frozen_stages=-1, + conv_cfg=None, + norm_cfg=dict(type='BN'), + act_cfg=dict(type='ReLU6'), + norm_eval=False, + with_cp=False): + super(MobileNetV2, self).__init__() + self.widen_factor = widen_factor + self.strides = strides + self.dilations = dilations + assert len(strides) == len(dilations) == len(self.arch_settings) + self.out_indices = out_indices + for index in out_indices: + if index not in range(0, 7): + raise ValueError('the item in out_indices must in ' + f'range(0, 8). But received {index}') + + if frozen_stages not in range(-1, 7): + raise ValueError('frozen_stages must be in range(-1, 7). ' + f'But received {frozen_stages}') + self.out_indices = out_indices + self.frozen_stages = frozen_stages + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + self.norm_eval = norm_eval + self.with_cp = with_cp + + self.in_channels = make_divisible(32 * widen_factor, 8) + + self.conv1 = ConvModule( + in_channels=3, + out_channels=self.in_channels, + kernel_size=3, + stride=2, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + self.layers = [] + + for i, layer_cfg in enumerate(self.arch_settings): + expand_ratio, channel, num_blocks = layer_cfg + stride = self.strides[i] + dilation = self.dilations[i] + out_channels = make_divisible(channel * widen_factor, 8) + inverted_res_layer = self.make_layer( + out_channels=out_channels, + num_blocks=num_blocks, + stride=stride, + dilation=dilation, + expand_ratio=expand_ratio) + layer_name = f'layer{i + 1}' + self.add_module(layer_name, inverted_res_layer) + self.layers.append(layer_name) + + def make_layer(self, out_channels, num_blocks, stride, dilation, + expand_ratio): + """Stack InvertedResidual blocks to build a layer for MobileNetV2. + + Args: + out_channels (int): out_channels of block. + num_blocks (int): Number of blocks. + stride (int): Stride of the first block. + dilation (int): Dilation of the first block. + expand_ratio (int): Expand the number of channels of the + hidden layer in InvertedResidual by this ratio. + """ + layers = [] + for i in range(num_blocks): + layers.append( + InvertedResidual( + self.in_channels, + out_channels, + stride if i == 0 else 1, + expand_ratio=expand_ratio, + dilation=dilation if i == 0 else 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg, + with_cp=self.with_cp)) + self.in_channels = out_channels + + return nn.Sequential(*layers) + + def init_weights(self, pretrained=None): + if isinstance(pretrained, str): + logger = logging.getLogger() + load_checkpoint(self, pretrained, strict=False, logger=logger) + elif pretrained is None: + for m in self.modules(): + if isinstance(m, nn.Conv2d): + kaiming_init(m) + elif isinstance(m, (_BatchNorm, nn.GroupNorm)): + constant_init(m, 1) + else: + raise TypeError('pretrained must be a str or None') + + def forward(self, x): + x = self.conv1(x) + + outs = [] + for i, layer_name in enumerate(self.layers): + layer = getattr(self, layer_name) + x = layer(x) + if i in self.out_indices: + outs.append(x) + + if len(outs) == 1: + return outs[0] + else: + return tuple(outs) + + def _freeze_stages(self): + if self.frozen_stages >= 0: + for param in self.conv1.parameters(): + param.requires_grad = False + for i in range(1, self.frozen_stages + 1): + layer = getattr(self, f'layer{i}') + layer.eval() + for param in layer.parameters(): + param.requires_grad = False + + def train(self, mode=True): + super(MobileNetV2, self).train(mode) + self._freeze_stages() + if mode and self.norm_eval: + for m in self.modules(): + if isinstance(m, _BatchNorm): + m.eval() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/mobilenet_v3.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/mobilenet_v3.py new file mode 100644 index 00000000..e3c22bdd --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/mobilenet_v3.py @@ -0,0 +1,255 @@ +import logging + +import annotator.mmpkg.mmcv as mmcv +import torch.nn as nn +from annotator.mmpkg.mmcv.cnn import ConvModule, constant_init, kaiming_init +from annotator.mmpkg.mmcv.cnn.bricks import Conv2dAdaptivePadding +from annotator.mmpkg.mmcv.runner import load_checkpoint +from torch.nn.modules.batchnorm import _BatchNorm + +from ..builder import BACKBONES +from ..utils import InvertedResidualV3 as InvertedResidual + + +@BACKBONES.register_module() +class MobileNetV3(nn.Module): + """MobileNetV3 backbone. + + This backbone is the improved implementation of `Searching for MobileNetV3 + `_. + + Args: + arch (str): Architecture of mobilnetv3, from {'small', 'large'}. + Default: 'small'. + conv_cfg (dict): Config dict for convolution layer. + Default: None, which means using conv2d. + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='BN'). + out_indices (tuple[int]): Output from which layer. + Default: (0, 1, 12). + frozen_stages (int): Stages to be frozen (all param fixed). + Default: -1, which means not freezing any parameters. + norm_eval (bool): Whether to set norm layers to eval mode, namely, + freeze running stats (mean and var). Note: Effect on Batch Norm + and its variants only. Default: False. + with_cp (bool): Use checkpoint or not. Using checkpoint will save + some memory while slowing down the training speed. + Default: False. + """ + # Parameters to build each block: + # [kernel size, mid channels, out channels, with_se, act type, stride] + arch_settings = { + 'small': [[3, 16, 16, True, 'ReLU', 2], # block0 layer1 os=4 + [3, 72, 24, False, 'ReLU', 2], # block1 layer2 os=8 + [3, 88, 24, False, 'ReLU', 1], + [5, 96, 40, True, 'HSwish', 2], # block2 layer4 os=16 + [5, 240, 40, True, 'HSwish', 1], + [5, 240, 40, True, 'HSwish', 1], + [5, 120, 48, True, 'HSwish', 1], # block3 layer7 os=16 + [5, 144, 48, True, 'HSwish', 1], + [5, 288, 96, True, 'HSwish', 2], # block4 layer9 os=32 + [5, 576, 96, True, 'HSwish', 1], + [5, 576, 96, True, 'HSwish', 1]], + 'large': [[3, 16, 16, False, 'ReLU', 1], # block0 layer1 os=2 + [3, 64, 24, False, 'ReLU', 2], # block1 layer2 os=4 + [3, 72, 24, False, 'ReLU', 1], + [5, 72, 40, True, 'ReLU', 2], # block2 layer4 os=8 + [5, 120, 40, True, 'ReLU', 1], + [5, 120, 40, True, 'ReLU', 1], + [3, 240, 80, False, 'HSwish', 2], # block3 layer7 os=16 + [3, 200, 80, False, 'HSwish', 1], + [3, 184, 80, False, 'HSwish', 1], + [3, 184, 80, False, 'HSwish', 1], + [3, 480, 112, True, 'HSwish', 1], # block4 layer11 os=16 + [3, 672, 112, True, 'HSwish', 1], + [5, 672, 160, True, 'HSwish', 2], # block5 layer13 os=32 + [5, 960, 160, True, 'HSwish', 1], + [5, 960, 160, True, 'HSwish', 1]] + } # yapf: disable + + def __init__(self, + arch='small', + conv_cfg=None, + norm_cfg=dict(type='BN'), + out_indices=(0, 1, 12), + frozen_stages=-1, + reduction_factor=1, + norm_eval=False, + with_cp=False): + super(MobileNetV3, self).__init__() + assert arch in self.arch_settings + assert isinstance(reduction_factor, int) and reduction_factor > 0 + assert mmcv.is_tuple_of(out_indices, int) + for index in out_indices: + if index not in range(0, len(self.arch_settings[arch]) + 2): + raise ValueError( + 'the item in out_indices must in ' + f'range(0, {len(self.arch_settings[arch])+2}). ' + f'But received {index}') + + if frozen_stages not in range(-1, len(self.arch_settings[arch]) + 2): + raise ValueError('frozen_stages must be in range(-1, ' + f'{len(self.arch_settings[arch])+2}). ' + f'But received {frozen_stages}') + self.arch = arch + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.out_indices = out_indices + self.frozen_stages = frozen_stages + self.reduction_factor = reduction_factor + self.norm_eval = norm_eval + self.with_cp = with_cp + self.layers = self._make_layer() + + def _make_layer(self): + layers = [] + + # build the first layer (layer0) + in_channels = 16 + layer = ConvModule( + in_channels=3, + out_channels=in_channels, + kernel_size=3, + stride=2, + padding=1, + conv_cfg=dict(type='Conv2dAdaptivePadding'), + norm_cfg=self.norm_cfg, + act_cfg=dict(type='HSwish')) + self.add_module('layer0', layer) + layers.append('layer0') + + layer_setting = self.arch_settings[self.arch] + for i, params in enumerate(layer_setting): + (kernel_size, mid_channels, out_channels, with_se, act, + stride) = params + + if self.arch == 'large' and i >= 12 or self.arch == 'small' and \ + i >= 8: + mid_channels = mid_channels // self.reduction_factor + out_channels = out_channels // self.reduction_factor + + if with_se: + se_cfg = dict( + channels=mid_channels, + ratio=4, + act_cfg=(dict(type='ReLU'), + dict(type='HSigmoid', bias=3.0, divisor=6.0))) + else: + se_cfg = None + + layer = InvertedResidual( + in_channels=in_channels, + out_channels=out_channels, + mid_channels=mid_channels, + kernel_size=kernel_size, + stride=stride, + se_cfg=se_cfg, + with_expand_conv=(in_channels != mid_channels), + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=dict(type=act), + with_cp=self.with_cp) + in_channels = out_channels + layer_name = 'layer{}'.format(i + 1) + self.add_module(layer_name, layer) + layers.append(layer_name) + + # build the last layer + # block5 layer12 os=32 for small model + # block6 layer16 os=32 for large model + layer = ConvModule( + in_channels=in_channels, + out_channels=576 if self.arch == 'small' else 960, + kernel_size=1, + stride=1, + dilation=4, + padding=0, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=dict(type='HSwish')) + layer_name = 'layer{}'.format(len(layer_setting) + 1) + self.add_module(layer_name, layer) + layers.append(layer_name) + + # next, convert backbone MobileNetV3 to a semantic segmentation version + if self.arch == 'small': + self.layer4.depthwise_conv.conv.stride = (1, 1) + self.layer9.depthwise_conv.conv.stride = (1, 1) + for i in range(4, len(layers)): + layer = getattr(self, layers[i]) + if isinstance(layer, InvertedResidual): + modified_module = layer.depthwise_conv.conv + else: + modified_module = layer.conv + + if i < 9: + modified_module.dilation = (2, 2) + pad = 2 + else: + modified_module.dilation = (4, 4) + pad = 4 + + if not isinstance(modified_module, Conv2dAdaptivePadding): + # Adjust padding + pad *= (modified_module.kernel_size[0] - 1) // 2 + modified_module.padding = (pad, pad) + else: + self.layer7.depthwise_conv.conv.stride = (1, 1) + self.layer13.depthwise_conv.conv.stride = (1, 1) + for i in range(7, len(layers)): + layer = getattr(self, layers[i]) + if isinstance(layer, InvertedResidual): + modified_module = layer.depthwise_conv.conv + else: + modified_module = layer.conv + + if i < 13: + modified_module.dilation = (2, 2) + pad = 2 + else: + modified_module.dilation = (4, 4) + pad = 4 + + if not isinstance(modified_module, Conv2dAdaptivePadding): + # Adjust padding + pad *= (modified_module.kernel_size[0] - 1) // 2 + modified_module.padding = (pad, pad) + + return layers + + def init_weights(self, pretrained=None): + if isinstance(pretrained, str): + logger = logging.getLogger() + load_checkpoint(self, pretrained, strict=False, logger=logger) + elif pretrained is None: + for m in self.modules(): + if isinstance(m, nn.Conv2d): + kaiming_init(m) + elif isinstance(m, nn.BatchNorm2d): + constant_init(m, 1) + else: + raise TypeError('pretrained must be a str or None') + + def forward(self, x): + outs = [] + for i, layer_name in enumerate(self.layers): + layer = getattr(self, layer_name) + x = layer(x) + if i in self.out_indices: + outs.append(x) + return outs + + def _freeze_stages(self): + for i in range(self.frozen_stages + 1): + layer = getattr(self, f'layer{i}') + layer.eval() + for param in layer.parameters(): + param.requires_grad = False + + def train(self, mode=True): + super(MobileNetV3, self).train(mode) + self._freeze_stages() + if mode and self.norm_eval: + for m in self.modules(): + if isinstance(m, _BatchNorm): + m.eval() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/resnest.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/resnest.py new file mode 100644 index 00000000..076ef621 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/resnest.py @@ -0,0 +1,314 @@ +import math + +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.checkpoint as cp +from annotator.mmpkg.mmcv.cnn import build_conv_layer, build_norm_layer + +from ..builder import BACKBONES +from ..utils import ResLayer +from .resnet import Bottleneck as _Bottleneck +from .resnet import ResNetV1d + + +class RSoftmax(nn.Module): + """Radix Softmax module in ``SplitAttentionConv2d``. + + Args: + radix (int): Radix of input. + groups (int): Groups of input. + """ + + def __init__(self, radix, groups): + super().__init__() + self.radix = radix + self.groups = groups + + def forward(self, x): + batch = x.size(0) + if self.radix > 1: + x = x.view(batch, self.groups, self.radix, -1).transpose(1, 2) + x = F.softmax(x, dim=1) + x = x.reshape(batch, -1) + else: + x = torch.sigmoid(x) + return x + + +class SplitAttentionConv2d(nn.Module): + """Split-Attention Conv2d in ResNeSt. + + Args: + in_channels (int): Same as nn.Conv2d. + out_channels (int): Same as nn.Conv2d. + kernel_size (int | tuple[int]): Same as nn.Conv2d. + stride (int | tuple[int]): Same as nn.Conv2d. + padding (int | tuple[int]): Same as nn.Conv2d. + dilation (int | tuple[int]): Same as nn.Conv2d. + groups (int): Same as nn.Conv2d. + radix (int): Radix of SpltAtConv2d. Default: 2 + reduction_factor (int): Reduction factor of inter_channels. Default: 4. + conv_cfg (dict): Config dict for convolution layer. Default: None, + which means using conv2d. + norm_cfg (dict): Config dict for normalization layer. Default: None. + dcn (dict): Config dict for DCN. Default: None. + """ + + def __init__(self, + in_channels, + channels, + kernel_size, + stride=1, + padding=0, + dilation=1, + groups=1, + radix=2, + reduction_factor=4, + conv_cfg=None, + norm_cfg=dict(type='BN'), + dcn=None): + super(SplitAttentionConv2d, self).__init__() + inter_channels = max(in_channels * radix // reduction_factor, 32) + self.radix = radix + self.groups = groups + self.channels = channels + self.with_dcn = dcn is not None + self.dcn = dcn + fallback_on_stride = False + if self.with_dcn: + fallback_on_stride = self.dcn.pop('fallback_on_stride', False) + if self.with_dcn and not fallback_on_stride: + assert conv_cfg is None, 'conv_cfg must be None for DCN' + conv_cfg = dcn + self.conv = build_conv_layer( + conv_cfg, + in_channels, + channels * radix, + kernel_size, + stride=stride, + padding=padding, + dilation=dilation, + groups=groups * radix, + bias=False) + self.norm0_name, norm0 = build_norm_layer( + norm_cfg, channels * radix, postfix=0) + self.add_module(self.norm0_name, norm0) + self.relu = nn.ReLU(inplace=True) + self.fc1 = build_conv_layer( + None, channels, inter_channels, 1, groups=self.groups) + self.norm1_name, norm1 = build_norm_layer( + norm_cfg, inter_channels, postfix=1) + self.add_module(self.norm1_name, norm1) + self.fc2 = build_conv_layer( + None, inter_channels, channels * radix, 1, groups=self.groups) + self.rsoftmax = RSoftmax(radix, groups) + + @property + def norm0(self): + """nn.Module: the normalization layer named "norm0" """ + return getattr(self, self.norm0_name) + + @property + def norm1(self): + """nn.Module: the normalization layer named "norm1" """ + return getattr(self, self.norm1_name) + + def forward(self, x): + x = self.conv(x) + x = self.norm0(x) + x = self.relu(x) + + batch, rchannel = x.shape[:2] + batch = x.size(0) + if self.radix > 1: + splits = x.view(batch, self.radix, -1, *x.shape[2:]) + gap = splits.sum(dim=1) + else: + gap = x + gap = F.adaptive_avg_pool2d(gap, 1) + gap = self.fc1(gap) + + gap = self.norm1(gap) + gap = self.relu(gap) + + atten = self.fc2(gap) + atten = self.rsoftmax(atten).view(batch, -1, 1, 1) + + if self.radix > 1: + attens = atten.view(batch, self.radix, -1, *atten.shape[2:]) + out = torch.sum(attens * splits, dim=1) + else: + out = atten * x + return out.contiguous() + + +class Bottleneck(_Bottleneck): + """Bottleneck block for ResNeSt. + + Args: + inplane (int): Input planes of this block. + planes (int): Middle planes of this block. + groups (int): Groups of conv2. + width_per_group (int): Width per group of conv2. 64x4d indicates + ``groups=64, width_per_group=4`` and 32x8d indicates + ``groups=32, width_per_group=8``. + radix (int): Radix of SpltAtConv2d. Default: 2 + reduction_factor (int): Reduction factor of inter_channels in + SplitAttentionConv2d. Default: 4. + avg_down_stride (bool): Whether to use average pool for stride in + Bottleneck. Default: True. + kwargs (dict): Key word arguments for base class. + """ + expansion = 4 + + def __init__(self, + inplanes, + planes, + groups=1, + base_width=4, + base_channels=64, + radix=2, + reduction_factor=4, + avg_down_stride=True, + **kwargs): + """Bottleneck block for ResNeSt.""" + super(Bottleneck, self).__init__(inplanes, planes, **kwargs) + + if groups == 1: + width = self.planes + else: + width = math.floor(self.planes * + (base_width / base_channels)) * groups + + self.avg_down_stride = avg_down_stride and self.conv2_stride > 1 + + self.norm1_name, norm1 = build_norm_layer( + self.norm_cfg, width, postfix=1) + self.norm3_name, norm3 = build_norm_layer( + self.norm_cfg, self.planes * self.expansion, postfix=3) + + self.conv1 = build_conv_layer( + self.conv_cfg, + self.inplanes, + width, + kernel_size=1, + stride=self.conv1_stride, + bias=False) + self.add_module(self.norm1_name, norm1) + self.with_modulated_dcn = False + self.conv2 = SplitAttentionConv2d( + width, + width, + kernel_size=3, + stride=1 if self.avg_down_stride else self.conv2_stride, + padding=self.dilation, + dilation=self.dilation, + groups=groups, + radix=radix, + reduction_factor=reduction_factor, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + dcn=self.dcn) + delattr(self, self.norm2_name) + + if self.avg_down_stride: + self.avd_layer = nn.AvgPool2d(3, self.conv2_stride, padding=1) + + self.conv3 = build_conv_layer( + self.conv_cfg, + width, + self.planes * self.expansion, + kernel_size=1, + bias=False) + self.add_module(self.norm3_name, norm3) + + def forward(self, x): + + def _inner_forward(x): + identity = x + + out = self.conv1(x) + out = self.norm1(out) + out = self.relu(out) + + if self.with_plugins: + out = self.forward_plugin(out, self.after_conv1_plugin_names) + + out = self.conv2(out) + + if self.avg_down_stride: + out = self.avd_layer(out) + + if self.with_plugins: + out = self.forward_plugin(out, self.after_conv2_plugin_names) + + out = self.conv3(out) + out = self.norm3(out) + + if self.with_plugins: + out = self.forward_plugin(out, self.after_conv3_plugin_names) + + if self.downsample is not None: + identity = self.downsample(x) + + out += identity + + return out + + if self.with_cp and x.requires_grad: + out = cp.checkpoint(_inner_forward, x) + else: + out = _inner_forward(x) + + out = self.relu(out) + + return out + + +@BACKBONES.register_module() +class ResNeSt(ResNetV1d): + """ResNeSt backbone. + + Args: + groups (int): Number of groups of Bottleneck. Default: 1 + base_width (int): Base width of Bottleneck. Default: 4 + radix (int): Radix of SpltAtConv2d. Default: 2 + reduction_factor (int): Reduction factor of inter_channels in + SplitAttentionConv2d. Default: 4. + avg_down_stride (bool): Whether to use average pool for stride in + Bottleneck. Default: True. + kwargs (dict): Keyword arguments for ResNet. + """ + + arch_settings = { + 50: (Bottleneck, (3, 4, 6, 3)), + 101: (Bottleneck, (3, 4, 23, 3)), + 152: (Bottleneck, (3, 8, 36, 3)), + 200: (Bottleneck, (3, 24, 36, 3)) + } + + def __init__(self, + groups=1, + base_width=4, + radix=2, + reduction_factor=4, + avg_down_stride=True, + **kwargs): + self.groups = groups + self.base_width = base_width + self.radix = radix + self.reduction_factor = reduction_factor + self.avg_down_stride = avg_down_stride + super(ResNeSt, self).__init__(**kwargs) + + def make_res_layer(self, **kwargs): + """Pack all blocks in a stage into a ``ResLayer``.""" + return ResLayer( + groups=self.groups, + base_width=self.base_width, + base_channels=self.base_channels, + radix=self.radix, + reduction_factor=self.reduction_factor, + avg_down_stride=self.avg_down_stride, + **kwargs) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/resnet.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/resnet.py new file mode 100644 index 00000000..b3304dc5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/resnet.py @@ -0,0 +1,688 @@ +import torch.nn as nn +import torch.utils.checkpoint as cp +from annotator.mmpkg.mmcv.cnn import (build_conv_layer, build_norm_layer, build_plugin_layer, + constant_init, kaiming_init) +from annotator.mmpkg.mmcv.runner import load_checkpoint +from annotator.mmpkg.mmcv.utils.parrots_wrapper import _BatchNorm + +from annotator.mmpkg.mmseg.utils import get_root_logger +from ..builder import BACKBONES +from ..utils import ResLayer + + +class BasicBlock(nn.Module): + """Basic block for ResNet.""" + + expansion = 1 + + def __init__(self, + inplanes, + planes, + stride=1, + dilation=1, + downsample=None, + style='pytorch', + with_cp=False, + conv_cfg=None, + norm_cfg=dict(type='BN'), + dcn=None, + plugins=None): + super(BasicBlock, self).__init__() + assert dcn is None, 'Not implemented yet.' + assert plugins is None, 'Not implemented yet.' + + self.norm1_name, norm1 = build_norm_layer(norm_cfg, planes, postfix=1) + self.norm2_name, norm2 = build_norm_layer(norm_cfg, planes, postfix=2) + + self.conv1 = build_conv_layer( + conv_cfg, + inplanes, + planes, + 3, + stride=stride, + padding=dilation, + dilation=dilation, + bias=False) + self.add_module(self.norm1_name, norm1) + self.conv2 = build_conv_layer( + conv_cfg, planes, planes, 3, padding=1, bias=False) + self.add_module(self.norm2_name, norm2) + + self.relu = nn.ReLU(inplace=True) + self.downsample = downsample + self.stride = stride + self.dilation = dilation + self.with_cp = with_cp + + @property + def norm1(self): + """nn.Module: normalization layer after the first convolution layer""" + return getattr(self, self.norm1_name) + + @property + def norm2(self): + """nn.Module: normalization layer after the second convolution layer""" + return getattr(self, self.norm2_name) + + def forward(self, x): + """Forward function.""" + + def _inner_forward(x): + identity = x + + out = self.conv1(x) + out = self.norm1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.norm2(out) + + if self.downsample is not None: + identity = self.downsample(x) + + out += identity + + return out + + if self.with_cp and x.requires_grad: + out = cp.checkpoint(_inner_forward, x) + else: + out = _inner_forward(x) + + out = self.relu(out) + + return out + + +class Bottleneck(nn.Module): + """Bottleneck block for ResNet. + + If style is "pytorch", the stride-two layer is the 3x3 conv layer, if it is + "caffe", the stride-two layer is the first 1x1 conv layer. + """ + + expansion = 4 + + def __init__(self, + inplanes, + planes, + stride=1, + dilation=1, + downsample=None, + style='pytorch', + with_cp=False, + conv_cfg=None, + norm_cfg=dict(type='BN'), + dcn=None, + plugins=None): + super(Bottleneck, self).__init__() + assert style in ['pytorch', 'caffe'] + assert dcn is None or isinstance(dcn, dict) + assert plugins is None or isinstance(plugins, list) + if plugins is not None: + allowed_position = ['after_conv1', 'after_conv2', 'after_conv3'] + assert all(p['position'] in allowed_position for p in plugins) + + self.inplanes = inplanes + self.planes = planes + self.stride = stride + self.dilation = dilation + self.style = style + self.with_cp = with_cp + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.dcn = dcn + self.with_dcn = dcn is not None + self.plugins = plugins + self.with_plugins = plugins is not None + + if self.with_plugins: + # collect plugins for conv1/conv2/conv3 + self.after_conv1_plugins = [ + plugin['cfg'] for plugin in plugins + if plugin['position'] == 'after_conv1' + ] + self.after_conv2_plugins = [ + plugin['cfg'] for plugin in plugins + if plugin['position'] == 'after_conv2' + ] + self.after_conv3_plugins = [ + plugin['cfg'] for plugin in plugins + if plugin['position'] == 'after_conv3' + ] + + if self.style == 'pytorch': + self.conv1_stride = 1 + self.conv2_stride = stride + else: + self.conv1_stride = stride + self.conv2_stride = 1 + + self.norm1_name, norm1 = build_norm_layer(norm_cfg, planes, postfix=1) + self.norm2_name, norm2 = build_norm_layer(norm_cfg, planes, postfix=2) + self.norm3_name, norm3 = build_norm_layer( + norm_cfg, planes * self.expansion, postfix=3) + + self.conv1 = build_conv_layer( + conv_cfg, + inplanes, + planes, + kernel_size=1, + stride=self.conv1_stride, + bias=False) + self.add_module(self.norm1_name, norm1) + fallback_on_stride = False + if self.with_dcn: + fallback_on_stride = dcn.pop('fallback_on_stride', False) + if not self.with_dcn or fallback_on_stride: + self.conv2 = build_conv_layer( + conv_cfg, + planes, + planes, + kernel_size=3, + stride=self.conv2_stride, + padding=dilation, + dilation=dilation, + bias=False) + else: + assert self.conv_cfg is None, 'conv_cfg must be None for DCN' + self.conv2 = build_conv_layer( + dcn, + planes, + planes, + kernel_size=3, + stride=self.conv2_stride, + padding=dilation, + dilation=dilation, + bias=False) + + self.add_module(self.norm2_name, norm2) + self.conv3 = build_conv_layer( + conv_cfg, + planes, + planes * self.expansion, + kernel_size=1, + bias=False) + self.add_module(self.norm3_name, norm3) + + self.relu = nn.ReLU(inplace=True) + self.downsample = downsample + + if self.with_plugins: + self.after_conv1_plugin_names = self.make_block_plugins( + planes, self.after_conv1_plugins) + self.after_conv2_plugin_names = self.make_block_plugins( + planes, self.after_conv2_plugins) + self.after_conv3_plugin_names = self.make_block_plugins( + planes * self.expansion, self.after_conv3_plugins) + + def make_block_plugins(self, in_channels, plugins): + """make plugins for block. + + Args: + in_channels (int): Input channels of plugin. + plugins (list[dict]): List of plugins cfg to build. + + Returns: + list[str]: List of the names of plugin. + """ + assert isinstance(plugins, list) + plugin_names = [] + for plugin in plugins: + plugin = plugin.copy() + name, layer = build_plugin_layer( + plugin, + in_channels=in_channels, + postfix=plugin.pop('postfix', '')) + assert not hasattr(self, name), f'duplicate plugin {name}' + self.add_module(name, layer) + plugin_names.append(name) + return plugin_names + + def forward_plugin(self, x, plugin_names): + """Forward function for plugins.""" + out = x + for name in plugin_names: + out = getattr(self, name)(x) + return out + + @property + def norm1(self): + """nn.Module: normalization layer after the first convolution layer""" + return getattr(self, self.norm1_name) + + @property + def norm2(self): + """nn.Module: normalization layer after the second convolution layer""" + return getattr(self, self.norm2_name) + + @property + def norm3(self): + """nn.Module: normalization layer after the third convolution layer""" + return getattr(self, self.norm3_name) + + def forward(self, x): + """Forward function.""" + + def _inner_forward(x): + identity = x + + out = self.conv1(x) + out = self.norm1(out) + out = self.relu(out) + + if self.with_plugins: + out = self.forward_plugin(out, self.after_conv1_plugin_names) + + out = self.conv2(out) + out = self.norm2(out) + out = self.relu(out) + + if self.with_plugins: + out = self.forward_plugin(out, self.after_conv2_plugin_names) + + out = self.conv3(out) + out = self.norm3(out) + + if self.with_plugins: + out = self.forward_plugin(out, self.after_conv3_plugin_names) + + if self.downsample is not None: + identity = self.downsample(x) + + out += identity + + return out + + if self.with_cp and x.requires_grad: + out = cp.checkpoint(_inner_forward, x) + else: + out = _inner_forward(x) + + out = self.relu(out) + + return out + + +@BACKBONES.register_module() +class ResNet(nn.Module): + """ResNet backbone. + + Args: + depth (int): Depth of resnet, from {18, 34, 50, 101, 152}. + in_channels (int): Number of input image channels. Default" 3. + stem_channels (int): Number of stem channels. Default: 64. + base_channels (int): Number of base channels of res layer. Default: 64. + num_stages (int): Resnet stages, normally 4. + strides (Sequence[int]): Strides of the first block of each stage. + dilations (Sequence[int]): Dilation of each stage. + out_indices (Sequence[int]): Output from which stages. + style (str): `pytorch` or `caffe`. If set to "pytorch", the stride-two + layer is the 3x3 conv layer, otherwise the stride-two layer is + the first 1x1 conv layer. + deep_stem (bool): Replace 7x7 conv in input stem with 3 3x3 conv + avg_down (bool): Use AvgPool instead of stride conv when + downsampling in the bottleneck. + frozen_stages (int): Stages to be frozen (stop grad and set eval mode). + -1 means not freezing any parameters. + norm_cfg (dict): Dictionary to construct and config norm layer. + norm_eval (bool): Whether to set norm layers to eval mode, namely, + freeze running stats (mean and var). Note: Effect on Batch Norm + and its variants only. + plugins (list[dict]): List of plugins for stages, each dict contains: + + - cfg (dict, required): Cfg dict to build plugin. + + - position (str, required): Position inside block to insert plugin, + options: 'after_conv1', 'after_conv2', 'after_conv3'. + + - stages (tuple[bool], optional): Stages to apply plugin, length + should be same as 'num_stages' + multi_grid (Sequence[int]|None): Multi grid dilation rates of last + stage. Default: None + contract_dilation (bool): Whether contract first dilation of each layer + Default: False + with_cp (bool): Use checkpoint or not. Using checkpoint will save some + memory while slowing down the training speed. + zero_init_residual (bool): Whether to use zero init for last norm layer + in resblocks to let them behave as identity. + + Example: + >>> from annotator.mmpkg.mmseg.models import ResNet + >>> import torch + >>> self = ResNet(depth=18) + >>> self.eval() + >>> inputs = torch.rand(1, 3, 32, 32) + >>> level_outputs = self.forward(inputs) + >>> for level_out in level_outputs: + ... print(tuple(level_out.shape)) + (1, 64, 8, 8) + (1, 128, 4, 4) + (1, 256, 2, 2) + (1, 512, 1, 1) + """ + + arch_settings = { + 18: (BasicBlock, (2, 2, 2, 2)), + 34: (BasicBlock, (3, 4, 6, 3)), + 50: (Bottleneck, (3, 4, 6, 3)), + 101: (Bottleneck, (3, 4, 23, 3)), + 152: (Bottleneck, (3, 8, 36, 3)) + } + + def __init__(self, + depth, + in_channels=3, + stem_channels=64, + base_channels=64, + num_stages=4, + strides=(1, 2, 2, 2), + dilations=(1, 1, 1, 1), + out_indices=(0, 1, 2, 3), + style='pytorch', + deep_stem=False, + avg_down=False, + frozen_stages=-1, + conv_cfg=None, + norm_cfg=dict(type='BN', requires_grad=True), + norm_eval=False, + dcn=None, + stage_with_dcn=(False, False, False, False), + plugins=None, + multi_grid=None, + contract_dilation=False, + with_cp=False, + zero_init_residual=True): + super(ResNet, self).__init__() + if depth not in self.arch_settings: + raise KeyError(f'invalid depth {depth} for resnet') + self.depth = depth + self.stem_channels = stem_channels + self.base_channels = base_channels + self.num_stages = num_stages + assert num_stages >= 1 and num_stages <= 4 + self.strides = strides + self.dilations = dilations + assert len(strides) == len(dilations) == num_stages + self.out_indices = out_indices + assert max(out_indices) < num_stages + self.style = style + self.deep_stem = deep_stem + self.avg_down = avg_down + self.frozen_stages = frozen_stages + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.with_cp = with_cp + self.norm_eval = norm_eval + self.dcn = dcn + self.stage_with_dcn = stage_with_dcn + if dcn is not None: + assert len(stage_with_dcn) == num_stages + self.plugins = plugins + self.multi_grid = multi_grid + self.contract_dilation = contract_dilation + self.zero_init_residual = zero_init_residual + self.block, stage_blocks = self.arch_settings[depth] + self.stage_blocks = stage_blocks[:num_stages] + self.inplanes = stem_channels + + self._make_stem_layer(in_channels, stem_channels) + + self.res_layers = [] + for i, num_blocks in enumerate(self.stage_blocks): + stride = strides[i] + dilation = dilations[i] + dcn = self.dcn if self.stage_with_dcn[i] else None + if plugins is not None: + stage_plugins = self.make_stage_plugins(plugins, i) + else: + stage_plugins = None + # multi grid is applied to last layer only + stage_multi_grid = multi_grid if i == len( + self.stage_blocks) - 1 else None + planes = base_channels * 2**i + res_layer = self.make_res_layer( + block=self.block, + inplanes=self.inplanes, + planes=planes, + num_blocks=num_blocks, + stride=stride, + dilation=dilation, + style=self.style, + avg_down=self.avg_down, + with_cp=with_cp, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + dcn=dcn, + plugins=stage_plugins, + multi_grid=stage_multi_grid, + contract_dilation=contract_dilation) + self.inplanes = planes * self.block.expansion + layer_name = f'layer{i+1}' + self.add_module(layer_name, res_layer) + self.res_layers.append(layer_name) + + self._freeze_stages() + + self.feat_dim = self.block.expansion * base_channels * 2**( + len(self.stage_blocks) - 1) + + def make_stage_plugins(self, plugins, stage_idx): + """make plugins for ResNet 'stage_idx'th stage . + + Currently we support to insert 'context_block', + 'empirical_attention_block', 'nonlocal_block' into the backbone like + ResNet/ResNeXt. They could be inserted after conv1/conv2/conv3 of + Bottleneck. + + An example of plugins format could be : + >>> plugins=[ + ... dict(cfg=dict(type='xxx', arg1='xxx'), + ... stages=(False, True, True, True), + ... position='after_conv2'), + ... dict(cfg=dict(type='yyy'), + ... stages=(True, True, True, True), + ... position='after_conv3'), + ... dict(cfg=dict(type='zzz', postfix='1'), + ... stages=(True, True, True, True), + ... position='after_conv3'), + ... dict(cfg=dict(type='zzz', postfix='2'), + ... stages=(True, True, True, True), + ... position='after_conv3') + ... ] + >>> self = ResNet(depth=18) + >>> stage_plugins = self.make_stage_plugins(plugins, 0) + >>> assert len(stage_plugins) == 3 + + Suppose 'stage_idx=0', the structure of blocks in the stage would be: + conv1-> conv2->conv3->yyy->zzz1->zzz2 + Suppose 'stage_idx=1', the structure of blocks in the stage would be: + conv1-> conv2->xxx->conv3->yyy->zzz1->zzz2 + + If stages is missing, the plugin would be applied to all stages. + + Args: + plugins (list[dict]): List of plugins cfg to build. The postfix is + required if multiple same type plugins are inserted. + stage_idx (int): Index of stage to build + + Returns: + list[dict]: Plugins for current stage + """ + stage_plugins = [] + for plugin in plugins: + plugin = plugin.copy() + stages = plugin.pop('stages', None) + assert stages is None or len(stages) == self.num_stages + # whether to insert plugin into current stage + if stages is None or stages[stage_idx]: + stage_plugins.append(plugin) + + return stage_plugins + + def make_res_layer(self, **kwargs): + """Pack all blocks in a stage into a ``ResLayer``.""" + return ResLayer(**kwargs) + + @property + def norm1(self): + """nn.Module: the normalization layer named "norm1" """ + return getattr(self, self.norm1_name) + + def _make_stem_layer(self, in_channels, stem_channels): + """Make stem layer for ResNet.""" + if self.deep_stem: + self.stem = nn.Sequential( + build_conv_layer( + self.conv_cfg, + in_channels, + stem_channels // 2, + kernel_size=3, + stride=2, + padding=1, + bias=False), + build_norm_layer(self.norm_cfg, stem_channels // 2)[1], + nn.ReLU(inplace=True), + build_conv_layer( + self.conv_cfg, + stem_channels // 2, + stem_channels // 2, + kernel_size=3, + stride=1, + padding=1, + bias=False), + build_norm_layer(self.norm_cfg, stem_channels // 2)[1], + nn.ReLU(inplace=True), + build_conv_layer( + self.conv_cfg, + stem_channels // 2, + stem_channels, + kernel_size=3, + stride=1, + padding=1, + bias=False), + build_norm_layer(self.norm_cfg, stem_channels)[1], + nn.ReLU(inplace=True)) + else: + self.conv1 = build_conv_layer( + self.conv_cfg, + in_channels, + stem_channels, + kernel_size=7, + stride=2, + padding=3, + bias=False) + self.norm1_name, norm1 = build_norm_layer( + self.norm_cfg, stem_channels, postfix=1) + self.add_module(self.norm1_name, norm1) + self.relu = nn.ReLU(inplace=True) + self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) + + def _freeze_stages(self): + """Freeze stages param and norm stats.""" + if self.frozen_stages >= 0: + if self.deep_stem: + self.stem.eval() + for param in self.stem.parameters(): + param.requires_grad = False + else: + self.norm1.eval() + for m in [self.conv1, self.norm1]: + for param in m.parameters(): + param.requires_grad = False + + for i in range(1, self.frozen_stages + 1): + m = getattr(self, f'layer{i}') + m.eval() + for param in m.parameters(): + param.requires_grad = False + + def init_weights(self, pretrained=None): + """Initialize the weights in backbone. + + Args: + pretrained (str, optional): Path to pre-trained weights. + Defaults to None. + """ + if isinstance(pretrained, str): + logger = get_root_logger() + load_checkpoint(self, pretrained, strict=False, logger=logger) + elif pretrained is None: + for m in self.modules(): + if isinstance(m, nn.Conv2d): + kaiming_init(m) + elif isinstance(m, (_BatchNorm, nn.GroupNorm)): + constant_init(m, 1) + + if self.dcn is not None: + for m in self.modules(): + if isinstance(m, Bottleneck) and hasattr( + m, 'conv2_offset'): + constant_init(m.conv2_offset, 0) + + if self.zero_init_residual: + for m in self.modules(): + if isinstance(m, Bottleneck): + constant_init(m.norm3, 0) + elif isinstance(m, BasicBlock): + constant_init(m.norm2, 0) + else: + raise TypeError('pretrained must be a str or None') + + def forward(self, x): + """Forward function.""" + if self.deep_stem: + x = self.stem(x) + else: + x = self.conv1(x) + x = self.norm1(x) + x = self.relu(x) + x = self.maxpool(x) + outs = [] + for i, layer_name in enumerate(self.res_layers): + res_layer = getattr(self, layer_name) + x = res_layer(x) + if i in self.out_indices: + outs.append(x) + return tuple(outs) + + def train(self, mode=True): + """Convert the model into training mode while keep normalization layer + freezed.""" + super(ResNet, self).train(mode) + self._freeze_stages() + if mode and self.norm_eval: + for m in self.modules(): + # trick: eval have effect on BatchNorm only + if isinstance(m, _BatchNorm): + m.eval() + + +@BACKBONES.register_module() +class ResNetV1c(ResNet): + """ResNetV1c variant described in [1]_. + + Compared with default ResNet(ResNetV1b), ResNetV1c replaces the 7x7 conv + in the input stem with three 3x3 convs. + + References: + .. [1] https://arxiv.org/pdf/1812.01187.pdf + """ + + def __init__(self, **kwargs): + super(ResNetV1c, self).__init__( + deep_stem=True, avg_down=False, **kwargs) + + +@BACKBONES.register_module() +class ResNetV1d(ResNet): + """ResNetV1d variant described in [1]_. + + Compared with default ResNet(ResNetV1b), ResNetV1d replaces the 7x7 conv in + the input stem with three 3x3 convs. And in the downsampling block, a 2x2 + avg_pool with stride 2 is added before conv, whose stride is changed to 1. + """ + + def __init__(self, **kwargs): + super(ResNetV1d, self).__init__( + deep_stem=True, avg_down=True, **kwargs) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/resnext.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/resnext.py new file mode 100644 index 00000000..be0194da --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/resnext.py @@ -0,0 +1,145 @@ +import math + +from annotator.mmpkg.mmcv.cnn import build_conv_layer, build_norm_layer + +from ..builder import BACKBONES +from ..utils import ResLayer +from .resnet import Bottleneck as _Bottleneck +from .resnet import ResNet + + +class Bottleneck(_Bottleneck): + """Bottleneck block for ResNeXt. + + If style is "pytorch", the stride-two layer is the 3x3 conv layer, if it is + "caffe", the stride-two layer is the first 1x1 conv layer. + """ + + def __init__(self, + inplanes, + planes, + groups=1, + base_width=4, + base_channels=64, + **kwargs): + super(Bottleneck, self).__init__(inplanes, planes, **kwargs) + + if groups == 1: + width = self.planes + else: + width = math.floor(self.planes * + (base_width / base_channels)) * groups + + self.norm1_name, norm1 = build_norm_layer( + self.norm_cfg, width, postfix=1) + self.norm2_name, norm2 = build_norm_layer( + self.norm_cfg, width, postfix=2) + self.norm3_name, norm3 = build_norm_layer( + self.norm_cfg, self.planes * self.expansion, postfix=3) + + self.conv1 = build_conv_layer( + self.conv_cfg, + self.inplanes, + width, + kernel_size=1, + stride=self.conv1_stride, + bias=False) + self.add_module(self.norm1_name, norm1) + fallback_on_stride = False + self.with_modulated_dcn = False + if self.with_dcn: + fallback_on_stride = self.dcn.pop('fallback_on_stride', False) + if not self.with_dcn or fallback_on_stride: + self.conv2 = build_conv_layer( + self.conv_cfg, + width, + width, + kernel_size=3, + stride=self.conv2_stride, + padding=self.dilation, + dilation=self.dilation, + groups=groups, + bias=False) + else: + assert self.conv_cfg is None, 'conv_cfg must be None for DCN' + self.conv2 = build_conv_layer( + self.dcn, + width, + width, + kernel_size=3, + stride=self.conv2_stride, + padding=self.dilation, + dilation=self.dilation, + groups=groups, + bias=False) + + self.add_module(self.norm2_name, norm2) + self.conv3 = build_conv_layer( + self.conv_cfg, + width, + self.planes * self.expansion, + kernel_size=1, + bias=False) + self.add_module(self.norm3_name, norm3) + + +@BACKBONES.register_module() +class ResNeXt(ResNet): + """ResNeXt backbone. + + Args: + depth (int): Depth of resnet, from {18, 34, 50, 101, 152}. + in_channels (int): Number of input image channels. Normally 3. + num_stages (int): Resnet stages, normally 4. + groups (int): Group of resnext. + base_width (int): Base width of resnext. + strides (Sequence[int]): Strides of the first block of each stage. + dilations (Sequence[int]): Dilation of each stage. + out_indices (Sequence[int]): Output from which stages. + style (str): `pytorch` or `caffe`. If set to "pytorch", the stride-two + layer is the 3x3 conv layer, otherwise the stride-two layer is + the first 1x1 conv layer. + frozen_stages (int): Stages to be frozen (all param fixed). -1 means + not freezing any parameters. + norm_cfg (dict): dictionary to construct and config norm layer. + norm_eval (bool): Whether to set norm layers to eval mode, namely, + freeze running stats (mean and var). Note: Effect on Batch Norm + and its variants only. + with_cp (bool): Use checkpoint or not. Using checkpoint will save some + memory while slowing down the training speed. + zero_init_residual (bool): whether to use zero init for last norm layer + in resblocks to let them behave as identity. + + Example: + >>> from annotator.mmpkg.mmseg.models import ResNeXt + >>> import torch + >>> self = ResNeXt(depth=50) + >>> self.eval() + >>> inputs = torch.rand(1, 3, 32, 32) + >>> level_outputs = self.forward(inputs) + >>> for level_out in level_outputs: + ... print(tuple(level_out.shape)) + (1, 256, 8, 8) + (1, 512, 4, 4) + (1, 1024, 2, 2) + (1, 2048, 1, 1) + """ + + arch_settings = { + 50: (Bottleneck, (3, 4, 6, 3)), + 101: (Bottleneck, (3, 4, 23, 3)), + 152: (Bottleneck, (3, 8, 36, 3)) + } + + def __init__(self, groups=1, base_width=4, **kwargs): + self.groups = groups + self.base_width = base_width + super(ResNeXt, self).__init__(**kwargs) + + def make_res_layer(self, **kwargs): + """Pack all blocks in a stage into a ``ResLayer``""" + return ResLayer( + groups=self.groups, + base_width=self.base_width, + base_channels=self.base_channels, + **kwargs) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/unet.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/unet.py new file mode 100644 index 00000000..3d19902b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/unet.py @@ -0,0 +1,429 @@ +import torch.nn as nn +import torch.utils.checkpoint as cp +from annotator.mmpkg.mmcv.cnn import (UPSAMPLE_LAYERS, ConvModule, build_activation_layer, + build_norm_layer, constant_init, kaiming_init) +from annotator.mmpkg.mmcv.runner import load_checkpoint +from annotator.mmpkg.mmcv.utils.parrots_wrapper import _BatchNorm + +from annotator.mmpkg.mmseg.utils import get_root_logger +from ..builder import BACKBONES +from ..utils import UpConvBlock + + +class BasicConvBlock(nn.Module): + """Basic convolutional block for UNet. + + This module consists of several plain convolutional layers. + + Args: + in_channels (int): Number of input channels. + out_channels (int): Number of output channels. + num_convs (int): Number of convolutional layers. Default: 2. + stride (int): Whether use stride convolution to downsample + the input feature map. If stride=2, it only uses stride convolution + in the first convolutional layer to downsample the input feature + map. Options are 1 or 2. Default: 1. + dilation (int): Whether use dilated convolution to expand the + receptive field. Set dilation rate of each convolutional layer and + the dilation rate of the first convolutional layer is always 1. + Default: 1. + with_cp (bool): Use checkpoint or not. Using checkpoint will save some + memory while slowing down the training speed. Default: False. + conv_cfg (dict | None): Config dict for convolution layer. + Default: None. + norm_cfg (dict | None): Config dict for normalization layer. + Default: dict(type='BN'). + act_cfg (dict | None): Config dict for activation layer in ConvModule. + Default: dict(type='ReLU'). + dcn (bool): Use deformable convolution in convolutional layer or not. + Default: None. + plugins (dict): plugins for convolutional layers. Default: None. + """ + + def __init__(self, + in_channels, + out_channels, + num_convs=2, + stride=1, + dilation=1, + with_cp=False, + conv_cfg=None, + norm_cfg=dict(type='BN'), + act_cfg=dict(type='ReLU'), + dcn=None, + plugins=None): + super(BasicConvBlock, self).__init__() + assert dcn is None, 'Not implemented yet.' + assert plugins is None, 'Not implemented yet.' + + self.with_cp = with_cp + convs = [] + for i in range(num_convs): + convs.append( + ConvModule( + in_channels=in_channels if i == 0 else out_channels, + out_channels=out_channels, + kernel_size=3, + stride=stride if i == 0 else 1, + dilation=1 if i == 0 else dilation, + padding=1 if i == 0 else dilation, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg)) + + self.convs = nn.Sequential(*convs) + + def forward(self, x): + """Forward function.""" + + if self.with_cp and x.requires_grad: + out = cp.checkpoint(self.convs, x) + else: + out = self.convs(x) + return out + + +@UPSAMPLE_LAYERS.register_module() +class DeconvModule(nn.Module): + """Deconvolution upsample module in decoder for UNet (2X upsample). + + This module uses deconvolution to upsample feature map in the decoder + of UNet. + + Args: + in_channels (int): Number of input channels. + out_channels (int): Number of output channels. + with_cp (bool): Use checkpoint or not. Using checkpoint will save some + memory while slowing down the training speed. Default: False. + norm_cfg (dict | None): Config dict for normalization layer. + Default: dict(type='BN'). + act_cfg (dict | None): Config dict for activation layer in ConvModule. + Default: dict(type='ReLU'). + kernel_size (int): Kernel size of the convolutional layer. Default: 4. + """ + + def __init__(self, + in_channels, + out_channels, + with_cp=False, + norm_cfg=dict(type='BN'), + act_cfg=dict(type='ReLU'), + *, + kernel_size=4, + scale_factor=2): + super(DeconvModule, self).__init__() + + assert (kernel_size - scale_factor >= 0) and\ + (kernel_size - scale_factor) % 2 == 0,\ + f'kernel_size should be greater than or equal to scale_factor '\ + f'and (kernel_size - scale_factor) should be even numbers, '\ + f'while the kernel size is {kernel_size} and scale_factor is '\ + f'{scale_factor}.' + + stride = scale_factor + padding = (kernel_size - scale_factor) // 2 + self.with_cp = with_cp + deconv = nn.ConvTranspose2d( + in_channels, + out_channels, + kernel_size=kernel_size, + stride=stride, + padding=padding) + + norm_name, norm = build_norm_layer(norm_cfg, out_channels) + activate = build_activation_layer(act_cfg) + self.deconv_upsamping = nn.Sequential(deconv, norm, activate) + + def forward(self, x): + """Forward function.""" + + if self.with_cp and x.requires_grad: + out = cp.checkpoint(self.deconv_upsamping, x) + else: + out = self.deconv_upsamping(x) + return out + + +@UPSAMPLE_LAYERS.register_module() +class InterpConv(nn.Module): + """Interpolation upsample module in decoder for UNet. + + This module uses interpolation to upsample feature map in the decoder + of UNet. It consists of one interpolation upsample layer and one + convolutional layer. It can be one interpolation upsample layer followed + by one convolutional layer (conv_first=False) or one convolutional layer + followed by one interpolation upsample layer (conv_first=True). + + Args: + in_channels (int): Number of input channels. + out_channels (int): Number of output channels. + with_cp (bool): Use checkpoint or not. Using checkpoint will save some + memory while slowing down the training speed. Default: False. + norm_cfg (dict | None): Config dict for normalization layer. + Default: dict(type='BN'). + act_cfg (dict | None): Config dict for activation layer in ConvModule. + Default: dict(type='ReLU'). + conv_cfg (dict | None): Config dict for convolution layer. + Default: None. + conv_first (bool): Whether convolutional layer or interpolation + upsample layer first. Default: False. It means interpolation + upsample layer followed by one convolutional layer. + kernel_size (int): Kernel size of the convolutional layer. Default: 1. + stride (int): Stride of the convolutional layer. Default: 1. + padding (int): Padding of the convolutional layer. Default: 1. + upsample_cfg (dict): Interpolation config of the upsample layer. + Default: dict( + scale_factor=2, mode='bilinear', align_corners=False). + """ + + def __init__(self, + in_channels, + out_channels, + with_cp=False, + norm_cfg=dict(type='BN'), + act_cfg=dict(type='ReLU'), + *, + conv_cfg=None, + conv_first=False, + kernel_size=1, + stride=1, + padding=0, + upsample_cfg=dict( + scale_factor=2, mode='bilinear', align_corners=False)): + super(InterpConv, self).__init__() + + self.with_cp = with_cp + conv = ConvModule( + in_channels, + out_channels, + kernel_size=kernel_size, + stride=stride, + padding=padding, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + upsample = nn.Upsample(**upsample_cfg) + if conv_first: + self.interp_upsample = nn.Sequential(conv, upsample) + else: + self.interp_upsample = nn.Sequential(upsample, conv) + + def forward(self, x): + """Forward function.""" + + if self.with_cp and x.requires_grad: + out = cp.checkpoint(self.interp_upsample, x) + else: + out = self.interp_upsample(x) + return out + + +@BACKBONES.register_module() +class UNet(nn.Module): + """UNet backbone. + U-Net: Convolutional Networks for Biomedical Image Segmentation. + https://arxiv.org/pdf/1505.04597.pdf + + Args: + in_channels (int): Number of input image channels. Default" 3. + base_channels (int): Number of base channels of each stage. + The output channels of the first stage. Default: 64. + num_stages (int): Number of stages in encoder, normally 5. Default: 5. + strides (Sequence[int 1 | 2]): Strides of each stage in encoder. + len(strides) is equal to num_stages. Normally the stride of the + first stage in encoder is 1. If strides[i]=2, it uses stride + convolution to downsample in the correspondence encoder stage. + Default: (1, 1, 1, 1, 1). + enc_num_convs (Sequence[int]): Number of convolutional layers in the + convolution block of the correspondence encoder stage. + Default: (2, 2, 2, 2, 2). + dec_num_convs (Sequence[int]): Number of convolutional layers in the + convolution block of the correspondence decoder stage. + Default: (2, 2, 2, 2). + downsamples (Sequence[int]): Whether use MaxPool to downsample the + feature map after the first stage of encoder + (stages: [1, num_stages)). If the correspondence encoder stage use + stride convolution (strides[i]=2), it will never use MaxPool to + downsample, even downsamples[i-1]=True. + Default: (True, True, True, True). + enc_dilations (Sequence[int]): Dilation rate of each stage in encoder. + Default: (1, 1, 1, 1, 1). + dec_dilations (Sequence[int]): Dilation rate of each stage in decoder. + Default: (1, 1, 1, 1). + with_cp (bool): Use checkpoint or not. Using checkpoint will save some + memory while slowing down the training speed. Default: False. + conv_cfg (dict | None): Config dict for convolution layer. + Default: None. + norm_cfg (dict | None): Config dict for normalization layer. + Default: dict(type='BN'). + act_cfg (dict | None): Config dict for activation layer in ConvModule. + Default: dict(type='ReLU'). + upsample_cfg (dict): The upsample config of the upsample module in + decoder. Default: dict(type='InterpConv'). + norm_eval (bool): Whether to set norm layers to eval mode, namely, + freeze running stats (mean and var). Note: Effect on Batch Norm + and its variants only. Default: False. + dcn (bool): Use deformable convolution in convolutional layer or not. + Default: None. + plugins (dict): plugins for convolutional layers. Default: None. + + Notice: + The input image size should be divisible by the whole downsample rate + of the encoder. More detail of the whole downsample rate can be found + in UNet._check_input_divisible. + + """ + + def __init__(self, + in_channels=3, + base_channels=64, + num_stages=5, + strides=(1, 1, 1, 1, 1), + enc_num_convs=(2, 2, 2, 2, 2), + dec_num_convs=(2, 2, 2, 2), + downsamples=(True, True, True, True), + enc_dilations=(1, 1, 1, 1, 1), + dec_dilations=(1, 1, 1, 1), + with_cp=False, + conv_cfg=None, + norm_cfg=dict(type='BN'), + act_cfg=dict(type='ReLU'), + upsample_cfg=dict(type='InterpConv'), + norm_eval=False, + dcn=None, + plugins=None): + super(UNet, self).__init__() + assert dcn is None, 'Not implemented yet.' + assert plugins is None, 'Not implemented yet.' + assert len(strides) == num_stages, \ + 'The length of strides should be equal to num_stages, '\ + f'while the strides is {strides}, the length of '\ + f'strides is {len(strides)}, and the num_stages is '\ + f'{num_stages}.' + assert len(enc_num_convs) == num_stages, \ + 'The length of enc_num_convs should be equal to num_stages, '\ + f'while the enc_num_convs is {enc_num_convs}, the length of '\ + f'enc_num_convs is {len(enc_num_convs)}, and the num_stages is '\ + f'{num_stages}.' + assert len(dec_num_convs) == (num_stages-1), \ + 'The length of dec_num_convs should be equal to (num_stages-1), '\ + f'while the dec_num_convs is {dec_num_convs}, the length of '\ + f'dec_num_convs is {len(dec_num_convs)}, and the num_stages is '\ + f'{num_stages}.' + assert len(downsamples) == (num_stages-1), \ + 'The length of downsamples should be equal to (num_stages-1), '\ + f'while the downsamples is {downsamples}, the length of '\ + f'downsamples is {len(downsamples)}, and the num_stages is '\ + f'{num_stages}.' + assert len(enc_dilations) == num_stages, \ + 'The length of enc_dilations should be equal to num_stages, '\ + f'while the enc_dilations is {enc_dilations}, the length of '\ + f'enc_dilations is {len(enc_dilations)}, and the num_stages is '\ + f'{num_stages}.' + assert len(dec_dilations) == (num_stages-1), \ + 'The length of dec_dilations should be equal to (num_stages-1), '\ + f'while the dec_dilations is {dec_dilations}, the length of '\ + f'dec_dilations is {len(dec_dilations)}, and the num_stages is '\ + f'{num_stages}.' + self.num_stages = num_stages + self.strides = strides + self.downsamples = downsamples + self.norm_eval = norm_eval + self.base_channels = base_channels + + self.encoder = nn.ModuleList() + self.decoder = nn.ModuleList() + + for i in range(num_stages): + enc_conv_block = [] + if i != 0: + if strides[i] == 1 and downsamples[i - 1]: + enc_conv_block.append(nn.MaxPool2d(kernel_size=2)) + upsample = (strides[i] != 1 or downsamples[i - 1]) + self.decoder.append( + UpConvBlock( + conv_block=BasicConvBlock, + in_channels=base_channels * 2**i, + skip_channels=base_channels * 2**(i - 1), + out_channels=base_channels * 2**(i - 1), + num_convs=dec_num_convs[i - 1], + stride=1, + dilation=dec_dilations[i - 1], + with_cp=with_cp, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg, + upsample_cfg=upsample_cfg if upsample else None, + dcn=None, + plugins=None)) + + enc_conv_block.append( + BasicConvBlock( + in_channels=in_channels, + out_channels=base_channels * 2**i, + num_convs=enc_num_convs[i], + stride=strides[i], + dilation=enc_dilations[i], + with_cp=with_cp, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg, + dcn=None, + plugins=None)) + self.encoder.append((nn.Sequential(*enc_conv_block))) + in_channels = base_channels * 2**i + + def forward(self, x): + self._check_input_divisible(x) + enc_outs = [] + for enc in self.encoder: + x = enc(x) + enc_outs.append(x) + dec_outs = [x] + for i in reversed(range(len(self.decoder))): + x = self.decoder[i](enc_outs[i], x) + dec_outs.append(x) + + return dec_outs + + def train(self, mode=True): + """Convert the model into training mode while keep normalization layer + freezed.""" + super(UNet, self).train(mode) + if mode and self.norm_eval: + for m in self.modules(): + # trick: eval have effect on BatchNorm only + if isinstance(m, _BatchNorm): + m.eval() + + def _check_input_divisible(self, x): + h, w = x.shape[-2:] + whole_downsample_rate = 1 + for i in range(1, self.num_stages): + if self.strides[i] == 2 or self.downsamples[i - 1]: + whole_downsample_rate *= 2 + assert (h % whole_downsample_rate == 0) \ + and (w % whole_downsample_rate == 0),\ + f'The input image size {(h, w)} should be divisible by the whole '\ + f'downsample rate {whole_downsample_rate}, when num_stages is '\ + f'{self.num_stages}, strides is {self.strides}, and downsamples '\ + f'is {self.downsamples}.' + + def init_weights(self, pretrained=None): + """Initialize the weights in backbone. + + Args: + pretrained (str, optional): Path to pre-trained weights. + Defaults to None. + """ + if isinstance(pretrained, str): + logger = get_root_logger() + load_checkpoint(self, pretrained, strict=False, logger=logger) + elif pretrained is None: + for m in self.modules(): + if isinstance(m, nn.Conv2d): + kaiming_init(m) + elif isinstance(m, (_BatchNorm, nn.GroupNorm)): + constant_init(m, 1) + else: + raise TypeError('pretrained must be a str or None') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/vit.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/vit.py new file mode 100644 index 00000000..ab1a3937 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/backbones/vit.py @@ -0,0 +1,459 @@ +"""Modified from https://github.com/rwightman/pytorch-image- +models/blob/master/timm/models/vision_transformer.py.""" + +import math + +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.checkpoint as cp +from annotator.mmpkg.mmcv.cnn import (Conv2d, Linear, build_activation_layer, build_norm_layer, + constant_init, kaiming_init, normal_init) +from annotator.mmpkg.mmcv.runner import _load_checkpoint +from annotator.mmpkg.mmcv.utils.parrots_wrapper import _BatchNorm + +from annotator.mmpkg.mmseg.utils import get_root_logger +from ..builder import BACKBONES +from ..utils import DropPath, trunc_normal_ + + +class Mlp(nn.Module): + """MLP layer for Encoder block. + + Args: + in_features(int): Input dimension for the first fully + connected layer. + hidden_features(int): Output dimension for the first fully + connected layer. + out_features(int): Output dementsion for the second fully + connected layer. + act_cfg(dict): Config dict for activation layer. + Default: dict(type='GELU'). + drop(float): Drop rate for the dropout layer. Dropout rate has + to be between 0 and 1. Default: 0. + """ + + def __init__(self, + in_features, + hidden_features=None, + out_features=None, + act_cfg=dict(type='GELU'), + drop=0.): + super(Mlp, self).__init__() + out_features = out_features or in_features + hidden_features = hidden_features or in_features + self.fc1 = Linear(in_features, hidden_features) + self.act = build_activation_layer(act_cfg) + self.fc2 = Linear(hidden_features, out_features) + self.drop = nn.Dropout(drop) + + def forward(self, x): + x = self.fc1(x) + x = self.act(x) + x = self.drop(x) + x = self.fc2(x) + x = self.drop(x) + return x + + +class Attention(nn.Module): + """Attention layer for Encoder block. + + Args: + dim (int): Dimension for the input vector. + num_heads (int): Number of parallel attention heads. + qkv_bias (bool): Enable bias for qkv if True. Default: False. + qk_scale (float): Override default qk scale of head_dim ** -0.5 if set. + attn_drop (float): Drop rate for attention output weights. + Default: 0. + proj_drop (float): Drop rate for output weights. Default: 0. + """ + + def __init__(self, + dim, + num_heads=8, + qkv_bias=False, + qk_scale=None, + attn_drop=0., + proj_drop=0.): + super(Attention, self).__init__() + self.num_heads = num_heads + head_dim = dim // num_heads + self.scale = qk_scale or head_dim**-0.5 + + self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias) + self.attn_drop = nn.Dropout(attn_drop) + self.proj = Linear(dim, dim) + self.proj_drop = nn.Dropout(proj_drop) + + def forward(self, x): + b, n, c = x.shape + qkv = self.qkv(x).reshape(b, n, 3, self.num_heads, + c // self.num_heads).permute(2, 0, 3, 1, 4) + q, k, v = qkv[0], qkv[1], qkv[2] + + attn = (q @ k.transpose(-2, -1)) * self.scale + attn = attn.softmax(dim=-1) + attn = self.attn_drop(attn) + + x = (attn @ v).transpose(1, 2).reshape(b, n, c) + x = self.proj(x) + x = self.proj_drop(x) + return x + + +class Block(nn.Module): + """Implements encoder block with residual connection. + + Args: + dim (int): The feature dimension. + num_heads (int): Number of parallel attention heads. + mlp_ratio (int): Ratio of mlp hidden dim to embedding dim. + qk_scale (float): Override default qk scale of head_dim ** -0.5 if set. + drop (float): Drop rate for mlp output weights. Default: 0. + attn_drop (float): Drop rate for attention output weights. + Default: 0. + proj_drop (float): Drop rate for attn layer output weights. + Default: 0. + drop_path (float): Drop rate for paths of model. + Default: 0. + act_cfg (dict): Config dict for activation layer. + Default: dict(type='GELU'). + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='LN', requires_grad=True). + with_cp (bool): Use checkpoint or not. Using checkpoint will save some + memory while slowing down the training speed. Default: False. + """ + + def __init__(self, + dim, + num_heads, + mlp_ratio=4, + qkv_bias=False, + qk_scale=None, + drop=0., + attn_drop=0., + proj_drop=0., + drop_path=0., + act_cfg=dict(type='GELU'), + norm_cfg=dict(type='LN', eps=1e-6), + with_cp=False): + super(Block, self).__init__() + self.with_cp = with_cp + _, self.norm1 = build_norm_layer(norm_cfg, dim) + self.attn = Attention(dim, num_heads, qkv_bias, qk_scale, attn_drop, + proj_drop) + self.drop_path = DropPath( + drop_path) if drop_path > 0. else nn.Identity() + _, self.norm2 = build_norm_layer(norm_cfg, dim) + mlp_hidden_dim = int(dim * mlp_ratio) + self.mlp = Mlp( + in_features=dim, + hidden_features=mlp_hidden_dim, + act_cfg=act_cfg, + drop=drop) + + def forward(self, x): + + def _inner_forward(x): + out = x + self.drop_path(self.attn(self.norm1(x))) + out = out + self.drop_path(self.mlp(self.norm2(out))) + return out + + if self.with_cp and x.requires_grad: + out = cp.checkpoint(_inner_forward, x) + else: + out = _inner_forward(x) + + return out + + +class PatchEmbed(nn.Module): + """Image to Patch Embedding. + + Args: + img_size (int | tuple): Input image size. + default: 224. + patch_size (int): Width and height for a patch. + default: 16. + in_channels (int): Input channels for images. Default: 3. + embed_dim (int): The embedding dimension. Default: 768. + """ + + def __init__(self, + img_size=224, + patch_size=16, + in_channels=3, + embed_dim=768): + super(PatchEmbed, self).__init__() + if isinstance(img_size, int): + self.img_size = (img_size, img_size) + elif isinstance(img_size, tuple): + self.img_size = img_size + else: + raise TypeError('img_size must be type of int or tuple') + h, w = self.img_size + self.patch_size = (patch_size, patch_size) + self.num_patches = (h // patch_size) * (w // patch_size) + self.proj = Conv2d( + in_channels, embed_dim, kernel_size=patch_size, stride=patch_size) + + def forward(self, x): + return self.proj(x).flatten(2).transpose(1, 2) + + +@BACKBONES.register_module() +class VisionTransformer(nn.Module): + """Vision transformer backbone. + + A PyTorch impl of : `An Image is Worth 16x16 Words: Transformers for + Image Recognition at Scale` - https://arxiv.org/abs/2010.11929 + + Args: + img_size (tuple): input image size. Default: (224, 224). + patch_size (int, tuple): patch size. Default: 16. + in_channels (int): number of input channels. Default: 3. + embed_dim (int): embedding dimension. Default: 768. + depth (int): depth of transformer. Default: 12. + num_heads (int): number of attention heads. Default: 12. + mlp_ratio (int): ratio of mlp hidden dim to embedding dim. + Default: 4. + out_indices (list | tuple | int): Output from which stages. + Default: -1. + qkv_bias (bool): enable bias for qkv if True. Default: True. + qk_scale (float): override default qk scale of head_dim ** -0.5 if set. + drop_rate (float): dropout rate. Default: 0. + attn_drop_rate (float): attention dropout rate. Default: 0. + drop_path_rate (float): Rate of DropPath. Default: 0. + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='LN', eps=1e-6, requires_grad=True). + act_cfg (dict): Config dict for activation layer. + Default: dict(type='GELU'). + norm_eval (bool): Whether to set norm layers to eval mode, namely, + freeze running stats (mean and var). Note: Effect on Batch Norm + and its variants only. Default: False. + final_norm (bool): Whether to add a additional layer to normalize + final feature map. Default: False. + interpolate_mode (str): Select the interpolate mode for position + embeding vector resize. Default: bicubic. + with_cls_token (bool): If concatenating class token into image tokens + as transformer input. Default: True. + with_cp (bool): Use checkpoint or not. Using checkpoint + will save some memory while slowing down the training speed. + Default: False. + """ + + def __init__(self, + img_size=(224, 224), + patch_size=16, + in_channels=3, + embed_dim=768, + depth=12, + num_heads=12, + mlp_ratio=4, + out_indices=11, + qkv_bias=True, + qk_scale=None, + drop_rate=0., + attn_drop_rate=0., + drop_path_rate=0., + norm_cfg=dict(type='LN', eps=1e-6, requires_grad=True), + act_cfg=dict(type='GELU'), + norm_eval=False, + final_norm=False, + with_cls_token=True, + interpolate_mode='bicubic', + with_cp=False): + super(VisionTransformer, self).__init__() + self.img_size = img_size + self.patch_size = patch_size + self.features = self.embed_dim = embed_dim + self.patch_embed = PatchEmbed( + img_size=img_size, + patch_size=patch_size, + in_channels=in_channels, + embed_dim=embed_dim) + + self.with_cls_token = with_cls_token + self.cls_token = nn.Parameter(torch.zeros(1, 1, self.embed_dim)) + self.pos_embed = nn.Parameter( + torch.zeros(1, self.patch_embed.num_patches + 1, embed_dim)) + self.pos_drop = nn.Dropout(p=drop_rate) + + if isinstance(out_indices, int): + self.out_indices = [out_indices] + elif isinstance(out_indices, list) or isinstance(out_indices, tuple): + self.out_indices = out_indices + else: + raise TypeError('out_indices must be type of int, list or tuple') + + dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth) + ] # stochastic depth decay rule + self.blocks = nn.ModuleList([ + Block( + dim=embed_dim, + num_heads=num_heads, + mlp_ratio=mlp_ratio, + qkv_bias=qkv_bias, + qk_scale=qk_scale, + drop=dpr[i], + attn_drop=attn_drop_rate, + act_cfg=act_cfg, + norm_cfg=norm_cfg, + with_cp=with_cp) for i in range(depth) + ]) + + self.interpolate_mode = interpolate_mode + self.final_norm = final_norm + if final_norm: + _, self.norm = build_norm_layer(norm_cfg, embed_dim) + + self.norm_eval = norm_eval + self.with_cp = with_cp + + def init_weights(self, pretrained=None): + if isinstance(pretrained, str): + logger = get_root_logger() + checkpoint = _load_checkpoint(pretrained, logger=logger) + if 'state_dict' in checkpoint: + state_dict = checkpoint['state_dict'] + else: + state_dict = checkpoint + + if 'pos_embed' in state_dict.keys(): + if self.pos_embed.shape != state_dict['pos_embed'].shape: + logger.info(msg=f'Resize the pos_embed shape from \ +{state_dict["pos_embed"].shape} to {self.pos_embed.shape}') + h, w = self.img_size + pos_size = int( + math.sqrt(state_dict['pos_embed'].shape[1] - 1)) + state_dict['pos_embed'] = self.resize_pos_embed( + state_dict['pos_embed'], (h, w), (pos_size, pos_size), + self.patch_size, self.interpolate_mode) + + self.load_state_dict(state_dict, False) + + elif pretrained is None: + # We only implement the 'jax_impl' initialization implemented at + # https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/vision_transformer.py#L353 # noqa: E501 + trunc_normal_(self.pos_embed, std=.02) + trunc_normal_(self.cls_token, std=.02) + for n, m in self.named_modules(): + if isinstance(m, Linear): + trunc_normal_(m.weight, std=.02) + if m.bias is not None: + if 'mlp' in n: + normal_init(m.bias, std=1e-6) + else: + constant_init(m.bias, 0) + elif isinstance(m, Conv2d): + kaiming_init(m.weight, mode='fan_in') + if m.bias is not None: + constant_init(m.bias, 0) + elif isinstance(m, (_BatchNorm, nn.GroupNorm, nn.LayerNorm)): + constant_init(m.bias, 0) + constant_init(m.weight, 1.0) + else: + raise TypeError('pretrained must be a str or None') + + def _pos_embeding(self, img, patched_img, pos_embed): + """Positiong embeding method. + + Resize the pos_embed, if the input image size doesn't match + the training size. + Args: + img (torch.Tensor): The inference image tensor, the shape + must be [B, C, H, W]. + patched_img (torch.Tensor): The patched image, it should be + shape of [B, L1, C]. + pos_embed (torch.Tensor): The pos_embed weighs, it should be + shape of [B, L2, c]. + Return: + torch.Tensor: The pos encoded image feature. + """ + assert patched_img.ndim == 3 and pos_embed.ndim == 3, \ + 'the shapes of patched_img and pos_embed must be [B, L, C]' + x_len, pos_len = patched_img.shape[1], pos_embed.shape[1] + if x_len != pos_len: + if pos_len == (self.img_size[0] // self.patch_size) * ( + self.img_size[1] // self.patch_size) + 1: + pos_h = self.img_size[0] // self.patch_size + pos_w = self.img_size[1] // self.patch_size + else: + raise ValueError( + 'Unexpected shape of pos_embed, got {}.'.format( + pos_embed.shape)) + pos_embed = self.resize_pos_embed(pos_embed, img.shape[2:], + (pos_h, pos_w), self.patch_size, + self.interpolate_mode) + return self.pos_drop(patched_img + pos_embed) + + @staticmethod + def resize_pos_embed(pos_embed, input_shpae, pos_shape, patch_size, mode): + """Resize pos_embed weights. + + Resize pos_embed using bicubic interpolate method. + Args: + pos_embed (torch.Tensor): pos_embed weights. + input_shpae (tuple): Tuple for (input_h, intput_w). + pos_shape (tuple): Tuple for (pos_h, pos_w). + patch_size (int): Patch size. + Return: + torch.Tensor: The resized pos_embed of shape [B, L_new, C] + """ + assert pos_embed.ndim == 3, 'shape of pos_embed must be [B, L, C]' + input_h, input_w = input_shpae + pos_h, pos_w = pos_shape + cls_token_weight = pos_embed[:, 0] + pos_embed_weight = pos_embed[:, (-1 * pos_h * pos_w):] + pos_embed_weight = pos_embed_weight.reshape( + 1, pos_h, pos_w, pos_embed.shape[2]).permute(0, 3, 1, 2) + pos_embed_weight = F.interpolate( + pos_embed_weight, + size=[input_h // patch_size, input_w // patch_size], + align_corners=False, + mode=mode) + cls_token_weight = cls_token_weight.unsqueeze(1) + pos_embed_weight = torch.flatten(pos_embed_weight, 2).transpose(1, 2) + pos_embed = torch.cat((cls_token_weight, pos_embed_weight), dim=1) + return pos_embed + + def forward(self, inputs): + B = inputs.shape[0] + + x = self.patch_embed(inputs) + + cls_tokens = self.cls_token.expand(B, -1, -1) + x = torch.cat((cls_tokens, x), dim=1) + x = self._pos_embeding(inputs, x, self.pos_embed) + + if not self.with_cls_token: + # Remove class token for transformer input + x = x[:, 1:] + + outs = [] + for i, blk in enumerate(self.blocks): + x = blk(x) + if i == len(self.blocks) - 1: + if self.final_norm: + x = self.norm(x) + if i in self.out_indices: + if self.with_cls_token: + # Remove class token and reshape token for decoder head + out = x[:, 1:] + else: + out = x + B, _, C = out.shape + out = out.reshape(B, inputs.shape[2] // self.patch_size, + inputs.shape[3] // self.patch_size, + C).permute(0, 3, 1, 2) + outs.append(out) + + return tuple(outs) + + def train(self, mode=True): + super(VisionTransformer, self).train(mode) + if mode and self.norm_eval: + for m in self.modules(): + if isinstance(m, nn.LayerNorm): + m.eval() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/builder.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/builder.py new file mode 100644 index 00000000..fd29ff66 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/builder.py @@ -0,0 +1,46 @@ +import warnings + +from annotator.mmpkg.mmcv.cnn import MODELS as MMCV_MODELS +from annotator.mmpkg.mmcv.utils import Registry + +MODELS = Registry('models', parent=MMCV_MODELS) + +BACKBONES = MODELS +NECKS = MODELS +HEADS = MODELS +LOSSES = MODELS +SEGMENTORS = MODELS + + +def build_backbone(cfg): + """Build backbone.""" + return BACKBONES.build(cfg) + + +def build_neck(cfg): + """Build neck.""" + return NECKS.build(cfg) + + +def build_head(cfg): + """Build head.""" + return HEADS.build(cfg) + + +def build_loss(cfg): + """Build loss.""" + return LOSSES.build(cfg) + + +def build_segmentor(cfg, train_cfg=None, test_cfg=None): + """Build segmentor.""" + if train_cfg is not None or test_cfg is not None: + warnings.warn( + 'train_cfg and test_cfg is deprecated, ' + 'please specify them in model', UserWarning) + assert cfg.get('train_cfg') is None or train_cfg is None, \ + 'train_cfg specified in both outer field and model field ' + assert cfg.get('test_cfg') is None or test_cfg is None, \ + 'test_cfg specified in both outer field and model field ' + return SEGMENTORS.build( + cfg, default_args=dict(train_cfg=train_cfg, test_cfg=test_cfg)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/__init__.py new file mode 100644 index 00000000..ac66d3cf --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/__init__.py @@ -0,0 +1,28 @@ +from .ann_head import ANNHead +from .apc_head import APCHead +from .aspp_head import ASPPHead +from .cc_head import CCHead +from .da_head import DAHead +from .dm_head import DMHead +from .dnl_head import DNLHead +from .ema_head import EMAHead +from .enc_head import EncHead +from .fcn_head import FCNHead +from .fpn_head import FPNHead +from .gc_head import GCHead +from .lraspp_head import LRASPPHead +from .nl_head import NLHead +from .ocr_head import OCRHead +# from .point_head import PointHead +from .psa_head import PSAHead +from .psp_head import PSPHead +from .sep_aspp_head import DepthwiseSeparableASPPHead +from .sep_fcn_head import DepthwiseSeparableFCNHead +from .uper_head import UPerHead + +__all__ = [ + 'FCNHead', 'PSPHead', 'ASPPHead', 'PSAHead', 'NLHead', 'GCHead', 'CCHead', + 'UPerHead', 'DepthwiseSeparableASPPHead', 'ANNHead', 'DAHead', 'OCRHead', + 'EncHead', 'DepthwiseSeparableFCNHead', 'FPNHead', 'EMAHead', 'DNLHead', + 'APCHead', 'DMHead', 'LRASPPHead' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/ann_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/ann_head.py new file mode 100644 index 00000000..958c88e0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/ann_head.py @@ -0,0 +1,245 @@ +import torch +import torch.nn as nn +from annotator.mmpkg.mmcv.cnn import ConvModule + +from ..builder import HEADS +from ..utils import SelfAttentionBlock as _SelfAttentionBlock +from .decode_head import BaseDecodeHead + + +class PPMConcat(nn.ModuleList): + """Pyramid Pooling Module that only concat the features of each layer. + + Args: + pool_scales (tuple[int]): Pooling scales used in Pooling Pyramid + Module. + """ + + def __init__(self, pool_scales=(1, 3, 6, 8)): + super(PPMConcat, self).__init__( + [nn.AdaptiveAvgPool2d(pool_scale) for pool_scale in pool_scales]) + + def forward(self, feats): + """Forward function.""" + ppm_outs = [] + for ppm in self: + ppm_out = ppm(feats) + ppm_outs.append(ppm_out.view(*feats.shape[:2], -1)) + concat_outs = torch.cat(ppm_outs, dim=2) + return concat_outs + + +class SelfAttentionBlock(_SelfAttentionBlock): + """Make a ANN used SelfAttentionBlock. + + Args: + low_in_channels (int): Input channels of lower level feature, + which is the key feature for self-attention. + high_in_channels (int): Input channels of higher level feature, + which is the query feature for self-attention. + channels (int): Output channels of key/query transform. + out_channels (int): Output channels. + share_key_query (bool): Whether share projection weight between key + and query projection. + query_scale (int): The scale of query feature map. + key_pool_scales (tuple[int]): Pooling scales used in Pooling Pyramid + Module of key feature. + conv_cfg (dict|None): Config of conv layers. + norm_cfg (dict|None): Config of norm layers. + act_cfg (dict|None): Config of activation layers. + """ + + def __init__(self, low_in_channels, high_in_channels, channels, + out_channels, share_key_query, query_scale, key_pool_scales, + conv_cfg, norm_cfg, act_cfg): + key_psp = PPMConcat(key_pool_scales) + if query_scale > 1: + query_downsample = nn.MaxPool2d(kernel_size=query_scale) + else: + query_downsample = None + super(SelfAttentionBlock, self).__init__( + key_in_channels=low_in_channels, + query_in_channels=high_in_channels, + channels=channels, + out_channels=out_channels, + share_key_query=share_key_query, + query_downsample=query_downsample, + key_downsample=key_psp, + key_query_num_convs=1, + key_query_norm=True, + value_out_num_convs=1, + value_out_norm=False, + matmul_norm=True, + with_out=True, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + + +class AFNB(nn.Module): + """Asymmetric Fusion Non-local Block(AFNB) + + Args: + low_in_channels (int): Input channels of lower level feature, + which is the key feature for self-attention. + high_in_channels (int): Input channels of higher level feature, + which is the query feature for self-attention. + channels (int): Output channels of key/query transform. + out_channels (int): Output channels. + and query projection. + query_scales (tuple[int]): The scales of query feature map. + Default: (1,) + key_pool_scales (tuple[int]): Pooling scales used in Pooling Pyramid + Module of key feature. + conv_cfg (dict|None): Config of conv layers. + norm_cfg (dict|None): Config of norm layers. + act_cfg (dict|None): Config of activation layers. + """ + + def __init__(self, low_in_channels, high_in_channels, channels, + out_channels, query_scales, key_pool_scales, conv_cfg, + norm_cfg, act_cfg): + super(AFNB, self).__init__() + self.stages = nn.ModuleList() + for query_scale in query_scales: + self.stages.append( + SelfAttentionBlock( + low_in_channels=low_in_channels, + high_in_channels=high_in_channels, + channels=channels, + out_channels=out_channels, + share_key_query=False, + query_scale=query_scale, + key_pool_scales=key_pool_scales, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg)) + self.bottleneck = ConvModule( + out_channels + high_in_channels, + out_channels, + 1, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=None) + + def forward(self, low_feats, high_feats): + """Forward function.""" + priors = [stage(high_feats, low_feats) for stage in self.stages] + context = torch.stack(priors, dim=0).sum(dim=0) + output = self.bottleneck(torch.cat([context, high_feats], 1)) + return output + + +class APNB(nn.Module): + """Asymmetric Pyramid Non-local Block (APNB) + + Args: + in_channels (int): Input channels of key/query feature, + which is the key feature for self-attention. + channels (int): Output channels of key/query transform. + out_channels (int): Output channels. + query_scales (tuple[int]): The scales of query feature map. + Default: (1,) + key_pool_scales (tuple[int]): Pooling scales used in Pooling Pyramid + Module of key feature. + conv_cfg (dict|None): Config of conv layers. + norm_cfg (dict|None): Config of norm layers. + act_cfg (dict|None): Config of activation layers. + """ + + def __init__(self, in_channels, channels, out_channels, query_scales, + key_pool_scales, conv_cfg, norm_cfg, act_cfg): + super(APNB, self).__init__() + self.stages = nn.ModuleList() + for query_scale in query_scales: + self.stages.append( + SelfAttentionBlock( + low_in_channels=in_channels, + high_in_channels=in_channels, + channels=channels, + out_channels=out_channels, + share_key_query=True, + query_scale=query_scale, + key_pool_scales=key_pool_scales, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg)) + self.bottleneck = ConvModule( + 2 * in_channels, + out_channels, + 1, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + + def forward(self, feats): + """Forward function.""" + priors = [stage(feats, feats) for stage in self.stages] + context = torch.stack(priors, dim=0).sum(dim=0) + output = self.bottleneck(torch.cat([context, feats], 1)) + return output + + +@HEADS.register_module() +class ANNHead(BaseDecodeHead): + """Asymmetric Non-local Neural Networks for Semantic Segmentation. + + This head is the implementation of `ANNNet + `_. + + Args: + project_channels (int): Projection channels for Nonlocal. + query_scales (tuple[int]): The scales of query feature map. + Default: (1,) + key_pool_scales (tuple[int]): The pooling scales of key feature map. + Default: (1, 3, 6, 8). + """ + + def __init__(self, + project_channels, + query_scales=(1, ), + key_pool_scales=(1, 3, 6, 8), + **kwargs): + super(ANNHead, self).__init__( + input_transform='multiple_select', **kwargs) + assert len(self.in_channels) == 2 + low_in_channels, high_in_channels = self.in_channels + self.project_channels = project_channels + self.fusion = AFNB( + low_in_channels=low_in_channels, + high_in_channels=high_in_channels, + out_channels=high_in_channels, + channels=project_channels, + query_scales=query_scales, + key_pool_scales=key_pool_scales, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + self.bottleneck = ConvModule( + high_in_channels, + self.channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + self.context = APNB( + in_channels=self.channels, + out_channels=self.channels, + channels=project_channels, + query_scales=query_scales, + key_pool_scales=key_pool_scales, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + def forward(self, inputs): + """Forward function.""" + low_feats, high_feats = self._transform_inputs(inputs) + output = self.fusion(low_feats, high_feats) + output = self.dropout(output) + output = self.bottleneck(output) + output = self.context(output) + output = self.cls_seg(output) + + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/apc_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/apc_head.py new file mode 100644 index 00000000..4f363dba --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/apc_head.py @@ -0,0 +1,158 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +from annotator.mmpkg.mmcv.cnn import ConvModule + +from annotator.mmpkg.mmseg.ops import resize +from ..builder import HEADS +from .decode_head import BaseDecodeHead + + +class ACM(nn.Module): + """Adaptive Context Module used in APCNet. + + Args: + pool_scale (int): Pooling scale used in Adaptive Context + Module to extract region features. + fusion (bool): Add one conv to fuse residual feature. + in_channels (int): Input channels. + channels (int): Channels after modules, before conv_seg. + conv_cfg (dict | None): Config of conv layers. + norm_cfg (dict | None): Config of norm layers. + act_cfg (dict): Config of activation layers. + """ + + def __init__(self, pool_scale, fusion, in_channels, channels, conv_cfg, + norm_cfg, act_cfg): + super(ACM, self).__init__() + self.pool_scale = pool_scale + self.fusion = fusion + self.in_channels = in_channels + self.channels = channels + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + self.pooled_redu_conv = ConvModule( + self.in_channels, + self.channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + self.input_redu_conv = ConvModule( + self.in_channels, + self.channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + self.global_info = ConvModule( + self.channels, + self.channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + self.gla = nn.Conv2d(self.channels, self.pool_scale**2, 1, 1, 0) + + self.residual_conv = ConvModule( + self.channels, + self.channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + if self.fusion: + self.fusion_conv = ConvModule( + self.channels, + self.channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + def forward(self, x): + """Forward function.""" + pooled_x = F.adaptive_avg_pool2d(x, self.pool_scale) + # [batch_size, channels, h, w] + x = self.input_redu_conv(x) + # [batch_size, channels, pool_scale, pool_scale] + pooled_x = self.pooled_redu_conv(pooled_x) + batch_size = x.size(0) + # [batch_size, pool_scale * pool_scale, channels] + pooled_x = pooled_x.view(batch_size, self.channels, + -1).permute(0, 2, 1).contiguous() + # [batch_size, h * w, pool_scale * pool_scale] + affinity_matrix = self.gla(x + resize( + self.global_info(F.adaptive_avg_pool2d(x, 1)), size=x.shape[2:]) + ).permute(0, 2, 3, 1).reshape( + batch_size, -1, self.pool_scale**2) + affinity_matrix = F.sigmoid(affinity_matrix) + # [batch_size, h * w, channels] + z_out = torch.matmul(affinity_matrix, pooled_x) + # [batch_size, channels, h * w] + z_out = z_out.permute(0, 2, 1).contiguous() + # [batch_size, channels, h, w] + z_out = z_out.view(batch_size, self.channels, x.size(2), x.size(3)) + z_out = self.residual_conv(z_out) + z_out = F.relu(z_out + x) + if self.fusion: + z_out = self.fusion_conv(z_out) + + return z_out + + +@HEADS.register_module() +class APCHead(BaseDecodeHead): + """Adaptive Pyramid Context Network for Semantic Segmentation. + + This head is the implementation of + `APCNet `_. + + Args: + pool_scales (tuple[int]): Pooling scales used in Adaptive Context + Module. Default: (1, 2, 3, 6). + fusion (bool): Add one conv to fuse residual feature. + """ + + def __init__(self, pool_scales=(1, 2, 3, 6), fusion=True, **kwargs): + super(APCHead, self).__init__(**kwargs) + assert isinstance(pool_scales, (list, tuple)) + self.pool_scales = pool_scales + self.fusion = fusion + acm_modules = [] + for pool_scale in self.pool_scales: + acm_modules.append( + ACM(pool_scale, + self.fusion, + self.in_channels, + self.channels, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg)) + self.acm_modules = nn.ModuleList(acm_modules) + self.bottleneck = ConvModule( + self.in_channels + len(pool_scales) * self.channels, + self.channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + def forward(self, inputs): + """Forward function.""" + x = self._transform_inputs(inputs) + acm_outs = [x] + for acm_module in self.acm_modules: + acm_outs.append(acm_module(x)) + acm_outs = torch.cat(acm_outs, dim=1) + output = self.bottleneck(acm_outs) + output = self.cls_seg(output) + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/aspp_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/aspp_head.py new file mode 100644 index 00000000..3c0aadb2 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/aspp_head.py @@ -0,0 +1,107 @@ +import torch +import torch.nn as nn +from annotator.mmpkg.mmcv.cnn import ConvModule + +from annotator.mmpkg.mmseg.ops import resize +from ..builder import HEADS +from .decode_head import BaseDecodeHead + + +class ASPPModule(nn.ModuleList): + """Atrous Spatial Pyramid Pooling (ASPP) Module. + + Args: + dilations (tuple[int]): Dilation rate of each layer. + in_channels (int): Input channels. + channels (int): Channels after modules, before conv_seg. + conv_cfg (dict|None): Config of conv layers. + norm_cfg (dict|None): Config of norm layers. + act_cfg (dict): Config of activation layers. + """ + + def __init__(self, dilations, in_channels, channels, conv_cfg, norm_cfg, + act_cfg): + super(ASPPModule, self).__init__() + self.dilations = dilations + self.in_channels = in_channels + self.channels = channels + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + for dilation in dilations: + self.append( + ConvModule( + self.in_channels, + self.channels, + 1 if dilation == 1 else 3, + dilation=dilation, + padding=0 if dilation == 1 else dilation, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg)) + + def forward(self, x): + """Forward function.""" + aspp_outs = [] + for aspp_module in self: + aspp_outs.append(aspp_module(x)) + + return aspp_outs + + +@HEADS.register_module() +class ASPPHead(BaseDecodeHead): + """Rethinking Atrous Convolution for Semantic Image Segmentation. + + This head is the implementation of `DeepLabV3 + `_. + + Args: + dilations (tuple[int]): Dilation rates for ASPP module. + Default: (1, 6, 12, 18). + """ + + def __init__(self, dilations=(1, 6, 12, 18), **kwargs): + super(ASPPHead, self).__init__(**kwargs) + assert isinstance(dilations, (list, tuple)) + self.dilations = dilations + self.image_pool = nn.Sequential( + nn.AdaptiveAvgPool2d(1), + ConvModule( + self.in_channels, + self.channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg)) + self.aspp_modules = ASPPModule( + dilations, + self.in_channels, + self.channels, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + self.bottleneck = ConvModule( + (len(dilations) + 1) * self.channels, + self.channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + def forward(self, inputs): + """Forward function.""" + x = self._transform_inputs(inputs) + aspp_outs = [ + resize( + self.image_pool(x), + size=x.size()[2:], + mode='bilinear', + align_corners=self.align_corners) + ] + aspp_outs.extend(self.aspp_modules(x)) + aspp_outs = torch.cat(aspp_outs, dim=1) + output = self.bottleneck(aspp_outs) + output = self.cls_seg(output) + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/cascade_decode_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/cascade_decode_head.py new file mode 100644 index 00000000..d02122ca --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/cascade_decode_head.py @@ -0,0 +1,57 @@ +from abc import ABCMeta, abstractmethod + +from .decode_head import BaseDecodeHead + + +class BaseCascadeDecodeHead(BaseDecodeHead, metaclass=ABCMeta): + """Base class for cascade decode head used in + :class:`CascadeEncoderDecoder.""" + + def __init__(self, *args, **kwargs): + super(BaseCascadeDecodeHead, self).__init__(*args, **kwargs) + + @abstractmethod + def forward(self, inputs, prev_output): + """Placeholder of forward function.""" + pass + + def forward_train(self, inputs, prev_output, img_metas, gt_semantic_seg, + train_cfg): + """Forward function for training. + Args: + inputs (list[Tensor]): List of multi-level img features. + prev_output (Tensor): The output of previous decode head. + img_metas (list[dict]): List of image info dict where each dict + has: 'img_shape', 'scale_factor', 'flip', and may also contain + 'filename', 'ori_shape', 'pad_shape', and 'img_norm_cfg'. + For details on the values of these keys see + `mmseg/datasets/pipelines/formatting.py:Collect`. + gt_semantic_seg (Tensor): Semantic segmentation masks + used if the architecture supports semantic segmentation task. + train_cfg (dict): The training config. + + Returns: + dict[str, Tensor]: a dictionary of loss components + """ + seg_logits = self.forward(inputs, prev_output) + losses = self.losses(seg_logits, gt_semantic_seg) + + return losses + + def forward_test(self, inputs, prev_output, img_metas, test_cfg): + """Forward function for testing. + + Args: + inputs (list[Tensor]): List of multi-level img features. + prev_output (Tensor): The output of previous decode head. + img_metas (list[dict]): List of image info dict where each dict + has: 'img_shape', 'scale_factor', 'flip', and may also contain + 'filename', 'ori_shape', 'pad_shape', and 'img_norm_cfg'. + For details on the values of these keys see + `mmseg/datasets/pipelines/formatting.py:Collect`. + test_cfg (dict): The testing config. + + Returns: + Tensor: Output segmentation map. + """ + return self.forward(inputs, prev_output) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/cc_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/cc_head.py new file mode 100644 index 00000000..1f4f5b05 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/cc_head.py @@ -0,0 +1,45 @@ +import torch + +from ..builder import HEADS +from .fcn_head import FCNHead + +try: + try: + from mmcv.ops import CrissCrossAttention + except ImportError: + from annotator.mmpkg.mmcv.ops import CrissCrossAttention +except ModuleNotFoundError: + CrissCrossAttention = None + + +@HEADS.register_module() +class CCHead(FCNHead): + """CCNet: Criss-Cross Attention for Semantic Segmentation. + + This head is the implementation of `CCNet + `_. + + Args: + recurrence (int): Number of recurrence of Criss Cross Attention + module. Default: 2. + """ + + def __init__(self, recurrence=2, **kwargs): + if CrissCrossAttention is None: + raise RuntimeError('Please install mmcv-full for ' + 'CrissCrossAttention ops') + super(CCHead, self).__init__(num_convs=2, **kwargs) + self.recurrence = recurrence + self.cca = CrissCrossAttention(self.channels) + + def forward(self, inputs): + """Forward function.""" + x = self._transform_inputs(inputs) + output = self.convs[0](x) + for _ in range(self.recurrence): + output = self.cca(output) + output = self.convs[1](output) + if self.concat_input: + output = self.conv_cat(torch.cat([x, output], dim=1)) + output = self.cls_seg(output) + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/da_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/da_head.py new file mode 100644 index 00000000..b0b76165 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/da_head.py @@ -0,0 +1,178 @@ +import torch +import torch.nn.functional as F +from annotator.mmpkg.mmcv.cnn import ConvModule, Scale +from torch import nn + +from annotator.mmpkg.mmseg.core import add_prefix +from ..builder import HEADS +from ..utils import SelfAttentionBlock as _SelfAttentionBlock +from .decode_head import BaseDecodeHead + + +class PAM(_SelfAttentionBlock): + """Position Attention Module (PAM) + + Args: + in_channels (int): Input channels of key/query feature. + channels (int): Output channels of key/query transform. + """ + + def __init__(self, in_channels, channels): + super(PAM, self).__init__( + key_in_channels=in_channels, + query_in_channels=in_channels, + channels=channels, + out_channels=in_channels, + share_key_query=False, + query_downsample=None, + key_downsample=None, + key_query_num_convs=1, + key_query_norm=False, + value_out_num_convs=1, + value_out_norm=False, + matmul_norm=False, + with_out=False, + conv_cfg=None, + norm_cfg=None, + act_cfg=None) + + self.gamma = Scale(0) + + def forward(self, x): + """Forward function.""" + out = super(PAM, self).forward(x, x) + + out = self.gamma(out) + x + return out + + +class CAM(nn.Module): + """Channel Attention Module (CAM)""" + + def __init__(self): + super(CAM, self).__init__() + self.gamma = Scale(0) + + def forward(self, x): + """Forward function.""" + batch_size, channels, height, width = x.size() + proj_query = x.view(batch_size, channels, -1) + proj_key = x.view(batch_size, channels, -1).permute(0, 2, 1) + energy = torch.bmm(proj_query, proj_key) + energy_new = torch.max( + energy, -1, keepdim=True)[0].expand_as(energy) - energy + attention = F.softmax(energy_new, dim=-1) + proj_value = x.view(batch_size, channels, -1) + + out = torch.bmm(attention, proj_value) + out = out.view(batch_size, channels, height, width) + + out = self.gamma(out) + x + return out + + +@HEADS.register_module() +class DAHead(BaseDecodeHead): + """Dual Attention Network for Scene Segmentation. + + This head is the implementation of `DANet + `_. + + Args: + pam_channels (int): The channels of Position Attention Module(PAM). + """ + + def __init__(self, pam_channels, **kwargs): + super(DAHead, self).__init__(**kwargs) + self.pam_channels = pam_channels + self.pam_in_conv = ConvModule( + self.in_channels, + self.channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + self.pam = PAM(self.channels, pam_channels) + self.pam_out_conv = ConvModule( + self.channels, + self.channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + self.pam_conv_seg = nn.Conv2d( + self.channels, self.num_classes, kernel_size=1) + + self.cam_in_conv = ConvModule( + self.in_channels, + self.channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + self.cam = CAM() + self.cam_out_conv = ConvModule( + self.channels, + self.channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + self.cam_conv_seg = nn.Conv2d( + self.channels, self.num_classes, kernel_size=1) + + def pam_cls_seg(self, feat): + """PAM feature classification.""" + if self.dropout is not None: + feat = self.dropout(feat) + output = self.pam_conv_seg(feat) + return output + + def cam_cls_seg(self, feat): + """CAM feature classification.""" + if self.dropout is not None: + feat = self.dropout(feat) + output = self.cam_conv_seg(feat) + return output + + def forward(self, inputs): + """Forward function.""" + x = self._transform_inputs(inputs) + pam_feat = self.pam_in_conv(x) + pam_feat = self.pam(pam_feat) + pam_feat = self.pam_out_conv(pam_feat) + pam_out = self.pam_cls_seg(pam_feat) + + cam_feat = self.cam_in_conv(x) + cam_feat = self.cam(cam_feat) + cam_feat = self.cam_out_conv(cam_feat) + cam_out = self.cam_cls_seg(cam_feat) + + feat_sum = pam_feat + cam_feat + pam_cam_out = self.cls_seg(feat_sum) + + return pam_cam_out, pam_out, cam_out + + def forward_test(self, inputs, img_metas, test_cfg): + """Forward function for testing, only ``pam_cam`` is used.""" + return self.forward(inputs)[0] + + def losses(self, seg_logit, seg_label): + """Compute ``pam_cam``, ``pam``, ``cam`` loss.""" + pam_cam_seg_logit, pam_seg_logit, cam_seg_logit = seg_logit + loss = dict() + loss.update( + add_prefix( + super(DAHead, self).losses(pam_cam_seg_logit, seg_label), + 'pam_cam')) + loss.update( + add_prefix( + super(DAHead, self).losses(pam_seg_logit, seg_label), 'pam')) + loss.update( + add_prefix( + super(DAHead, self).losses(cam_seg_logit, seg_label), 'cam')) + return loss diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/decode_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/decode_head.py new file mode 100644 index 00000000..a74c89f2 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/decode_head.py @@ -0,0 +1,234 @@ +from abc import ABCMeta, abstractmethod + +import torch +import torch.nn as nn +from annotator.mmpkg.mmcv.cnn import normal_init +from annotator.mmpkg.mmcv.runner import auto_fp16, force_fp32 + +from annotator.mmpkg.mmseg.core import build_pixel_sampler +from annotator.mmpkg.mmseg.ops import resize +from ..builder import build_loss +from ..losses import accuracy + + +class BaseDecodeHead(nn.Module, metaclass=ABCMeta): + """Base class for BaseDecodeHead. + + Args: + in_channels (int|Sequence[int]): Input channels. + channels (int): Channels after modules, before conv_seg. + num_classes (int): Number of classes. + dropout_ratio (float): Ratio of dropout layer. Default: 0.1. + conv_cfg (dict|None): Config of conv layers. Default: None. + norm_cfg (dict|None): Config of norm layers. Default: None. + act_cfg (dict): Config of activation layers. + Default: dict(type='ReLU') + in_index (int|Sequence[int]): Input feature index. Default: -1 + input_transform (str|None): Transformation type of input features. + Options: 'resize_concat', 'multiple_select', None. + 'resize_concat': Multiple feature maps will be resize to the + same size as first one and than concat together. + Usually used in FCN head of HRNet. + 'multiple_select': Multiple feature maps will be bundle into + a list and passed into decode head. + None: Only one select feature map is allowed. + Default: None. + loss_decode (dict): Config of decode loss. + Default: dict(type='CrossEntropyLoss'). + ignore_index (int | None): The label index to be ignored. When using + masked BCE loss, ignore_index should be set to None. Default: 255 + sampler (dict|None): The config of segmentation map sampler. + Default: None. + align_corners (bool): align_corners argument of F.interpolate. + Default: False. + """ + + def __init__(self, + in_channels, + channels, + *, + num_classes, + dropout_ratio=0.1, + conv_cfg=None, + norm_cfg=None, + act_cfg=dict(type='ReLU'), + in_index=-1, + input_transform=None, + loss_decode=dict( + type='CrossEntropyLoss', + use_sigmoid=False, + loss_weight=1.0), + ignore_index=255, + sampler=None, + align_corners=False): + super(BaseDecodeHead, self).__init__() + self._init_inputs(in_channels, in_index, input_transform) + self.channels = channels + self.num_classes = num_classes + self.dropout_ratio = dropout_ratio + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + self.in_index = in_index + self.loss_decode = build_loss(loss_decode) + self.ignore_index = ignore_index + self.align_corners = align_corners + if sampler is not None: + self.sampler = build_pixel_sampler(sampler, context=self) + else: + self.sampler = None + + self.conv_seg = nn.Conv2d(channels, num_classes, kernel_size=1) + if dropout_ratio > 0: + self.dropout = nn.Dropout2d(dropout_ratio) + else: + self.dropout = None + self.fp16_enabled = False + + def extra_repr(self): + """Extra repr.""" + s = f'input_transform={self.input_transform}, ' \ + f'ignore_index={self.ignore_index}, ' \ + f'align_corners={self.align_corners}' + return s + + def _init_inputs(self, in_channels, in_index, input_transform): + """Check and initialize input transforms. + + The in_channels, in_index and input_transform must match. + Specifically, when input_transform is None, only single feature map + will be selected. So in_channels and in_index must be of type int. + When input_transform + + Args: + in_channels (int|Sequence[int]): Input channels. + in_index (int|Sequence[int]): Input feature index. + input_transform (str|None): Transformation type of input features. + Options: 'resize_concat', 'multiple_select', None. + 'resize_concat': Multiple feature maps will be resize to the + same size as first one and than concat together. + Usually used in FCN head of HRNet. + 'multiple_select': Multiple feature maps will be bundle into + a list and passed into decode head. + None: Only one select feature map is allowed. + """ + + if input_transform is not None: + assert input_transform in ['resize_concat', 'multiple_select'] + self.input_transform = input_transform + self.in_index = in_index + if input_transform is not None: + assert isinstance(in_channels, (list, tuple)) + assert isinstance(in_index, (list, tuple)) + assert len(in_channels) == len(in_index) + if input_transform == 'resize_concat': + self.in_channels = sum(in_channels) + else: + self.in_channels = in_channels + else: + assert isinstance(in_channels, int) + assert isinstance(in_index, int) + self.in_channels = in_channels + + def init_weights(self): + """Initialize weights of classification layer.""" + normal_init(self.conv_seg, mean=0, std=0.01) + + def _transform_inputs(self, inputs): + """Transform inputs for decoder. + + Args: + inputs (list[Tensor]): List of multi-level img features. + + Returns: + Tensor: The transformed inputs + """ + + if self.input_transform == 'resize_concat': + inputs = [inputs[i] for i in self.in_index] + upsampled_inputs = [ + resize( + input=x, + size=inputs[0].shape[2:], + mode='bilinear', + align_corners=self.align_corners) for x in inputs + ] + inputs = torch.cat(upsampled_inputs, dim=1) + elif self.input_transform == 'multiple_select': + inputs = [inputs[i] for i in self.in_index] + else: + inputs = inputs[self.in_index] + + return inputs + + @auto_fp16() + @abstractmethod + def forward(self, inputs): + """Placeholder of forward function.""" + pass + + def forward_train(self, inputs, img_metas, gt_semantic_seg, train_cfg): + """Forward function for training. + Args: + inputs (list[Tensor]): List of multi-level img features. + img_metas (list[dict]): List of image info dict where each dict + has: 'img_shape', 'scale_factor', 'flip', and may also contain + 'filename', 'ori_shape', 'pad_shape', and 'img_norm_cfg'. + For details on the values of these keys see + `mmseg/datasets/pipelines/formatting.py:Collect`. + gt_semantic_seg (Tensor): Semantic segmentation masks + used if the architecture supports semantic segmentation task. + train_cfg (dict): The training config. + + Returns: + dict[str, Tensor]: a dictionary of loss components + """ + seg_logits = self.forward(inputs) + losses = self.losses(seg_logits, gt_semantic_seg) + return losses + + def forward_test(self, inputs, img_metas, test_cfg): + """Forward function for testing. + + Args: + inputs (list[Tensor]): List of multi-level img features. + img_metas (list[dict]): List of image info dict where each dict + has: 'img_shape', 'scale_factor', 'flip', and may also contain + 'filename', 'ori_shape', 'pad_shape', and 'img_norm_cfg'. + For details on the values of these keys see + `mmseg/datasets/pipelines/formatting.py:Collect`. + test_cfg (dict): The testing config. + + Returns: + Tensor: Output segmentation map. + """ + return self.forward(inputs) + + def cls_seg(self, feat): + """Classify each pixel.""" + if self.dropout is not None: + feat = self.dropout(feat) + output = self.conv_seg(feat) + return output + + @force_fp32(apply_to=('seg_logit', )) + def losses(self, seg_logit, seg_label): + """Compute segmentation loss.""" + loss = dict() + seg_logit = resize( + input=seg_logit, + size=seg_label.shape[2:], + mode='bilinear', + align_corners=self.align_corners) + if self.sampler is not None: + seg_weight = self.sampler.sample(seg_logit, seg_label) + else: + seg_weight = None + seg_label = seg_label.squeeze(1) + loss['loss_seg'] = self.loss_decode( + seg_logit, + seg_label, + weight=seg_weight, + ignore_index=self.ignore_index) + loss['acc_seg'] = accuracy(seg_logit, seg_label) + return loss diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/dm_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/dm_head.py new file mode 100644 index 00000000..de6d0f63 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/dm_head.py @@ -0,0 +1,140 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +from annotator.mmpkg.mmcv.cnn import ConvModule, build_activation_layer, build_norm_layer + +from ..builder import HEADS +from .decode_head import BaseDecodeHead + + +class DCM(nn.Module): + """Dynamic Convolutional Module used in DMNet. + + Args: + filter_size (int): The filter size of generated convolution kernel + used in Dynamic Convolutional Module. + fusion (bool): Add one conv to fuse DCM output feature. + in_channels (int): Input channels. + channels (int): Channels after modules, before conv_seg. + conv_cfg (dict | None): Config of conv layers. + norm_cfg (dict | None): Config of norm layers. + act_cfg (dict): Config of activation layers. + """ + + def __init__(self, filter_size, fusion, in_channels, channels, conv_cfg, + norm_cfg, act_cfg): + super(DCM, self).__init__() + self.filter_size = filter_size + self.fusion = fusion + self.in_channels = in_channels + self.channels = channels + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + self.filter_gen_conv = nn.Conv2d(self.in_channels, self.channels, 1, 1, + 0) + + self.input_redu_conv = ConvModule( + self.in_channels, + self.channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + if self.norm_cfg is not None: + self.norm = build_norm_layer(self.norm_cfg, self.channels)[1] + else: + self.norm = None + self.activate = build_activation_layer(self.act_cfg) + + if self.fusion: + self.fusion_conv = ConvModule( + self.channels, + self.channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + def forward(self, x): + """Forward function.""" + generated_filter = self.filter_gen_conv( + F.adaptive_avg_pool2d(x, self.filter_size)) + x = self.input_redu_conv(x) + b, c, h, w = x.shape + # [1, b * c, h, w], c = self.channels + x = x.view(1, b * c, h, w) + # [b * c, 1, filter_size, filter_size] + generated_filter = generated_filter.view(b * c, 1, self.filter_size, + self.filter_size) + pad = (self.filter_size - 1) // 2 + if (self.filter_size - 1) % 2 == 0: + p2d = (pad, pad, pad, pad) + else: + p2d = (pad + 1, pad, pad + 1, pad) + x = F.pad(input=x, pad=p2d, mode='constant', value=0) + # [1, b * c, h, w] + output = F.conv2d(input=x, weight=generated_filter, groups=b * c) + # [b, c, h, w] + output = output.view(b, c, h, w) + if self.norm is not None: + output = self.norm(output) + output = self.activate(output) + + if self.fusion: + output = self.fusion_conv(output) + + return output + + +@HEADS.register_module() +class DMHead(BaseDecodeHead): + """Dynamic Multi-scale Filters for Semantic Segmentation. + + This head is the implementation of + `DMNet `_. + + Args: + filter_sizes (tuple[int]): The size of generated convolutional filters + used in Dynamic Convolutional Module. Default: (1, 3, 5, 7). + fusion (bool): Add one conv to fuse DCM output feature. + """ + + def __init__(self, filter_sizes=(1, 3, 5, 7), fusion=False, **kwargs): + super(DMHead, self).__init__(**kwargs) + assert isinstance(filter_sizes, (list, tuple)) + self.filter_sizes = filter_sizes + self.fusion = fusion + dcm_modules = [] + for filter_size in self.filter_sizes: + dcm_modules.append( + DCM(filter_size, + self.fusion, + self.in_channels, + self.channels, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg)) + self.dcm_modules = nn.ModuleList(dcm_modules) + self.bottleneck = ConvModule( + self.in_channels + len(filter_sizes) * self.channels, + self.channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + def forward(self, inputs): + """Forward function.""" + x = self._transform_inputs(inputs) + dcm_outs = [x] + for dcm_module in self.dcm_modules: + dcm_outs.append(dcm_module(x)) + dcm_outs = torch.cat(dcm_outs, dim=1) + output = self.bottleneck(dcm_outs) + output = self.cls_seg(output) + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/dnl_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/dnl_head.py new file mode 100644 index 00000000..b3bb1de1 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/dnl_head.py @@ -0,0 +1,131 @@ +import torch +from annotator.mmpkg.mmcv.cnn import NonLocal2d +from torch import nn + +from ..builder import HEADS +from .fcn_head import FCNHead + + +class DisentangledNonLocal2d(NonLocal2d): + """Disentangled Non-Local Blocks. + + Args: + temperature (float): Temperature to adjust attention. Default: 0.05 + """ + + def __init__(self, *arg, temperature, **kwargs): + super().__init__(*arg, **kwargs) + self.temperature = temperature + self.conv_mask = nn.Conv2d(self.in_channels, 1, kernel_size=1) + + def embedded_gaussian(self, theta_x, phi_x): + """Embedded gaussian with temperature.""" + + # NonLocal2d pairwise_weight: [N, HxW, HxW] + pairwise_weight = torch.matmul(theta_x, phi_x) + if self.use_scale: + # theta_x.shape[-1] is `self.inter_channels` + pairwise_weight /= theta_x.shape[-1]**0.5 + pairwise_weight /= self.temperature + pairwise_weight = pairwise_weight.softmax(dim=-1) + return pairwise_weight + + def forward(self, x): + # x: [N, C, H, W] + n = x.size(0) + + # g_x: [N, HxW, C] + g_x = self.g(x).view(n, self.inter_channels, -1) + g_x = g_x.permute(0, 2, 1) + + # theta_x: [N, HxW, C], phi_x: [N, C, HxW] + if self.mode == 'gaussian': + theta_x = x.view(n, self.in_channels, -1) + theta_x = theta_x.permute(0, 2, 1) + if self.sub_sample: + phi_x = self.phi(x).view(n, self.in_channels, -1) + else: + phi_x = x.view(n, self.in_channels, -1) + elif self.mode == 'concatenation': + theta_x = self.theta(x).view(n, self.inter_channels, -1, 1) + phi_x = self.phi(x).view(n, self.inter_channels, 1, -1) + else: + theta_x = self.theta(x).view(n, self.inter_channels, -1) + theta_x = theta_x.permute(0, 2, 1) + phi_x = self.phi(x).view(n, self.inter_channels, -1) + + # subtract mean + theta_x -= theta_x.mean(dim=-2, keepdim=True) + phi_x -= phi_x.mean(dim=-1, keepdim=True) + + pairwise_func = getattr(self, self.mode) + # pairwise_weight: [N, HxW, HxW] + pairwise_weight = pairwise_func(theta_x, phi_x) + + # y: [N, HxW, C] + y = torch.matmul(pairwise_weight, g_x) + # y: [N, C, H, W] + y = y.permute(0, 2, 1).contiguous().reshape(n, self.inter_channels, + *x.size()[2:]) + + # unary_mask: [N, 1, HxW] + unary_mask = self.conv_mask(x) + unary_mask = unary_mask.view(n, 1, -1) + unary_mask = unary_mask.softmax(dim=-1) + # unary_x: [N, 1, C] + unary_x = torch.matmul(unary_mask, g_x) + # unary_x: [N, C, 1, 1] + unary_x = unary_x.permute(0, 2, 1).contiguous().reshape( + n, self.inter_channels, 1, 1) + + output = x + self.conv_out(y + unary_x) + + return output + + +@HEADS.register_module() +class DNLHead(FCNHead): + """Disentangled Non-Local Neural Networks. + + This head is the implementation of `DNLNet + `_. + + Args: + reduction (int): Reduction factor of projection transform. Default: 2. + use_scale (bool): Whether to scale pairwise_weight by + sqrt(1/inter_channels). Default: False. + mode (str): The nonlocal mode. Options are 'embedded_gaussian', + 'dot_product'. Default: 'embedded_gaussian.'. + temperature (float): Temperature to adjust attention. Default: 0.05 + """ + + def __init__(self, + reduction=2, + use_scale=True, + mode='embedded_gaussian', + temperature=0.05, + **kwargs): + super(DNLHead, self).__init__(num_convs=2, **kwargs) + self.reduction = reduction + self.use_scale = use_scale + self.mode = mode + self.temperature = temperature + self.dnl_block = DisentangledNonLocal2d( + in_channels=self.channels, + reduction=self.reduction, + use_scale=self.use_scale, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + mode=self.mode, + temperature=self.temperature) + + def forward(self, inputs): + """Forward function.""" + x = self._transform_inputs(inputs) + output = self.convs[0](x) + output = self.dnl_block(output) + output = self.convs[1](output) + if self.concat_input: + output = self.conv_cat(torch.cat([x, output], dim=1)) + output = self.cls_seg(output) + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/ema_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/ema_head.py new file mode 100644 index 00000000..aaebae7b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/ema_head.py @@ -0,0 +1,168 @@ +import math + +import torch +import torch.distributed as dist +import torch.nn as nn +import torch.nn.functional as F +from annotator.mmpkg.mmcv.cnn import ConvModule + +from ..builder import HEADS +from .decode_head import BaseDecodeHead + + +def reduce_mean(tensor): + """Reduce mean when distributed training.""" + if not (dist.is_available() and dist.is_initialized()): + return tensor + tensor = tensor.clone() + dist.all_reduce(tensor.div_(dist.get_world_size()), op=dist.ReduceOp.SUM) + return tensor + + +class EMAModule(nn.Module): + """Expectation Maximization Attention Module used in EMANet. + + Args: + channels (int): Channels of the whole module. + num_bases (int): Number of bases. + num_stages (int): Number of the EM iterations. + """ + + def __init__(self, channels, num_bases, num_stages, momentum): + super(EMAModule, self).__init__() + assert num_stages >= 1, 'num_stages must be at least 1!' + self.num_bases = num_bases + self.num_stages = num_stages + self.momentum = momentum + + bases = torch.zeros(1, channels, self.num_bases) + bases.normal_(0, math.sqrt(2. / self.num_bases)) + # [1, channels, num_bases] + bases = F.normalize(bases, dim=1, p=2) + self.register_buffer('bases', bases) + + def forward(self, feats): + """Forward function.""" + batch_size, channels, height, width = feats.size() + # [batch_size, channels, height*width] + feats = feats.view(batch_size, channels, height * width) + # [batch_size, channels, num_bases] + bases = self.bases.repeat(batch_size, 1, 1) + + with torch.no_grad(): + for i in range(self.num_stages): + # [batch_size, height*width, num_bases] + attention = torch.einsum('bcn,bck->bnk', feats, bases) + attention = F.softmax(attention, dim=2) + # l1 norm + attention_normed = F.normalize(attention, dim=1, p=1) + # [batch_size, channels, num_bases] + bases = torch.einsum('bcn,bnk->bck', feats, attention_normed) + # l2 norm + bases = F.normalize(bases, dim=1, p=2) + + feats_recon = torch.einsum('bck,bnk->bcn', bases, attention) + feats_recon = feats_recon.view(batch_size, channels, height, width) + + if self.training: + bases = bases.mean(dim=0, keepdim=True) + bases = reduce_mean(bases) + # l2 norm + bases = F.normalize(bases, dim=1, p=2) + self.bases = (1 - + self.momentum) * self.bases + self.momentum * bases + + return feats_recon + + +@HEADS.register_module() +class EMAHead(BaseDecodeHead): + """Expectation Maximization Attention Networks for Semantic Segmentation. + + This head is the implementation of `EMANet + `_. + + Args: + ema_channels (int): EMA module channels + num_bases (int): Number of bases. + num_stages (int): Number of the EM iterations. + concat_input (bool): Whether concat the input and output of convs + before classification layer. Default: True + momentum (float): Momentum to update the base. Default: 0.1. + """ + + def __init__(self, + ema_channels, + num_bases, + num_stages, + concat_input=True, + momentum=0.1, + **kwargs): + super(EMAHead, self).__init__(**kwargs) + self.ema_channels = ema_channels + self.num_bases = num_bases + self.num_stages = num_stages + self.concat_input = concat_input + self.momentum = momentum + self.ema_module = EMAModule(self.ema_channels, self.num_bases, + self.num_stages, self.momentum) + + self.ema_in_conv = ConvModule( + self.in_channels, + self.ema_channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + # project (0, inf) -> (-inf, inf) + self.ema_mid_conv = ConvModule( + self.ema_channels, + self.ema_channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=None, + act_cfg=None) + for param in self.ema_mid_conv.parameters(): + param.requires_grad = False + + self.ema_out_conv = ConvModule( + self.ema_channels, + self.ema_channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=None) + self.bottleneck = ConvModule( + self.ema_channels, + self.channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + if self.concat_input: + self.conv_cat = ConvModule( + self.in_channels + self.channels, + self.channels, + kernel_size=3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + def forward(self, inputs): + """Forward function.""" + x = self._transform_inputs(inputs) + feats = self.ema_in_conv(x) + identity = feats + feats = self.ema_mid_conv(feats) + recon = self.ema_module(feats) + recon = F.relu(recon, inplace=True) + recon = self.ema_out_conv(recon) + output = F.relu(identity + recon, inplace=True) + output = self.bottleneck(output) + if self.concat_input: + output = self.conv_cat(torch.cat([x, output], dim=1)) + output = self.cls_seg(output) + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/enc_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/enc_head.py new file mode 100644 index 00000000..4c2a22a9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/enc_head.py @@ -0,0 +1,187 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +from annotator.mmpkg.mmcv.cnn import ConvModule, build_norm_layer + +from annotator.mmpkg.mmseg.ops import Encoding, resize +from ..builder import HEADS, build_loss +from .decode_head import BaseDecodeHead + + +class EncModule(nn.Module): + """Encoding Module used in EncNet. + + Args: + in_channels (int): Input channels. + num_codes (int): Number of code words. + conv_cfg (dict|None): Config of conv layers. + norm_cfg (dict|None): Config of norm layers. + act_cfg (dict): Config of activation layers. + """ + + def __init__(self, in_channels, num_codes, conv_cfg, norm_cfg, act_cfg): + super(EncModule, self).__init__() + self.encoding_project = ConvModule( + in_channels, + in_channels, + 1, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + # TODO: resolve this hack + # change to 1d + if norm_cfg is not None: + encoding_norm_cfg = norm_cfg.copy() + if encoding_norm_cfg['type'] in ['BN', 'IN']: + encoding_norm_cfg['type'] += '1d' + else: + encoding_norm_cfg['type'] = encoding_norm_cfg['type'].replace( + '2d', '1d') + else: + # fallback to BN1d + encoding_norm_cfg = dict(type='BN1d') + self.encoding = nn.Sequential( + Encoding(channels=in_channels, num_codes=num_codes), + build_norm_layer(encoding_norm_cfg, num_codes)[1], + nn.ReLU(inplace=True)) + self.fc = nn.Sequential( + nn.Linear(in_channels, in_channels), nn.Sigmoid()) + + def forward(self, x): + """Forward function.""" + encoding_projection = self.encoding_project(x) + encoding_feat = self.encoding(encoding_projection).mean(dim=1) + batch_size, channels, _, _ = x.size() + gamma = self.fc(encoding_feat) + y = gamma.view(batch_size, channels, 1, 1) + output = F.relu_(x + x * y) + return encoding_feat, output + + +@HEADS.register_module() +class EncHead(BaseDecodeHead): + """Context Encoding for Semantic Segmentation. + + This head is the implementation of `EncNet + `_. + + Args: + num_codes (int): Number of code words. Default: 32. + use_se_loss (bool): Whether use Semantic Encoding Loss (SE-loss) to + regularize the training. Default: True. + add_lateral (bool): Whether use lateral connection to fuse features. + Default: False. + loss_se_decode (dict): Config of decode loss. + Default: dict(type='CrossEntropyLoss', use_sigmoid=True). + """ + + def __init__(self, + num_codes=32, + use_se_loss=True, + add_lateral=False, + loss_se_decode=dict( + type='CrossEntropyLoss', + use_sigmoid=True, + loss_weight=0.2), + **kwargs): + super(EncHead, self).__init__( + input_transform='multiple_select', **kwargs) + self.use_se_loss = use_se_loss + self.add_lateral = add_lateral + self.num_codes = num_codes + self.bottleneck = ConvModule( + self.in_channels[-1], + self.channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + if add_lateral: + self.lateral_convs = nn.ModuleList() + for in_channels in self.in_channels[:-1]: # skip the last one + self.lateral_convs.append( + ConvModule( + in_channels, + self.channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg)) + self.fusion = ConvModule( + len(self.in_channels) * self.channels, + self.channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + self.enc_module = EncModule( + self.channels, + num_codes=num_codes, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + if self.use_se_loss: + self.loss_se_decode = build_loss(loss_se_decode) + self.se_layer = nn.Linear(self.channels, self.num_classes) + + def forward(self, inputs): + """Forward function.""" + inputs = self._transform_inputs(inputs) + feat = self.bottleneck(inputs[-1]) + if self.add_lateral: + laterals = [ + resize( + lateral_conv(inputs[i]), + size=feat.shape[2:], + mode='bilinear', + align_corners=self.align_corners) + for i, lateral_conv in enumerate(self.lateral_convs) + ] + feat = self.fusion(torch.cat([feat, *laterals], 1)) + encode_feat, output = self.enc_module(feat) + output = self.cls_seg(output) + if self.use_se_loss: + se_output = self.se_layer(encode_feat) + return output, se_output + else: + return output + + def forward_test(self, inputs, img_metas, test_cfg): + """Forward function for testing, ignore se_loss.""" + if self.use_se_loss: + return self.forward(inputs)[0] + else: + return self.forward(inputs) + + @staticmethod + def _convert_to_onehot_labels(seg_label, num_classes): + """Convert segmentation label to onehot. + + Args: + seg_label (Tensor): Segmentation label of shape (N, H, W). + num_classes (int): Number of classes. + + Returns: + Tensor: Onehot labels of shape (N, num_classes). + """ + + batch_size = seg_label.size(0) + onehot_labels = seg_label.new_zeros((batch_size, num_classes)) + for i in range(batch_size): + hist = seg_label[i].float().histc( + bins=num_classes, min=0, max=num_classes - 1) + onehot_labels[i] = hist > 0 + return onehot_labels + + def losses(self, seg_logit, seg_label): + """Compute segmentation and semantic encoding loss.""" + seg_logit, se_seg_logit = seg_logit + loss = dict() + loss.update(super(EncHead, self).losses(seg_logit, seg_label)) + se_loss = self.loss_se_decode( + se_seg_logit, + self._convert_to_onehot_labels(seg_label, self.num_classes)) + loss['loss_se'] = se_loss + return loss diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/fcn_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/fcn_head.py new file mode 100644 index 00000000..c4583c57 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/fcn_head.py @@ -0,0 +1,81 @@ +import torch +import torch.nn as nn +from annotator.mmpkg.mmcv.cnn import ConvModule + +from ..builder import HEADS +from .decode_head import BaseDecodeHead + + +@HEADS.register_module() +class FCNHead(BaseDecodeHead): + """Fully Convolution Networks for Semantic Segmentation. + + This head is implemented of `FCNNet `_. + + Args: + num_convs (int): Number of convs in the head. Default: 2. + kernel_size (int): The kernel size for convs in the head. Default: 3. + concat_input (bool): Whether concat the input and output of convs + before classification layer. + dilation (int): The dilation rate for convs in the head. Default: 1. + """ + + def __init__(self, + num_convs=2, + kernel_size=3, + concat_input=True, + dilation=1, + **kwargs): + assert num_convs >= 0 and dilation > 0 and isinstance(dilation, int) + self.num_convs = num_convs + self.concat_input = concat_input + self.kernel_size = kernel_size + super(FCNHead, self).__init__(**kwargs) + if num_convs == 0: + assert self.in_channels == self.channels + + conv_padding = (kernel_size // 2) * dilation + convs = [] + convs.append( + ConvModule( + self.in_channels, + self.channels, + kernel_size=kernel_size, + padding=conv_padding, + dilation=dilation, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg)) + for i in range(num_convs - 1): + convs.append( + ConvModule( + self.channels, + self.channels, + kernel_size=kernel_size, + padding=conv_padding, + dilation=dilation, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg)) + if num_convs == 0: + self.convs = nn.Identity() + else: + self.convs = nn.Sequential(*convs) + if self.concat_input: + self.conv_cat = ConvModule( + self.in_channels + self.channels, + self.channels, + kernel_size=kernel_size, + padding=kernel_size // 2, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + def forward(self, inputs): + """Forward function.""" + x = self._transform_inputs(inputs) + output = self.convs(x) + if self.concat_input: + output = self.conv_cat(torch.cat([x, output], dim=1)) + output = self.cls_seg(output) + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/fpn_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/fpn_head.py new file mode 100644 index 00000000..1a9ba39e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/fpn_head.py @@ -0,0 +1,68 @@ +import numpy as np +import torch.nn as nn +from annotator.mmpkg.mmcv.cnn import ConvModule + +from annotator.mmpkg.mmseg.ops import resize +from ..builder import HEADS +from .decode_head import BaseDecodeHead + + +@HEADS.register_module() +class FPNHead(BaseDecodeHead): + """Panoptic Feature Pyramid Networks. + + This head is the implementation of `Semantic FPN + `_. + + Args: + feature_strides (tuple[int]): The strides for input feature maps. + stack_lateral. All strides suppose to be power of 2. The first + one is of largest resolution. + """ + + def __init__(self, feature_strides, **kwargs): + super(FPNHead, self).__init__( + input_transform='multiple_select', **kwargs) + assert len(feature_strides) == len(self.in_channels) + assert min(feature_strides) == feature_strides[0] + self.feature_strides = feature_strides + + self.scale_heads = nn.ModuleList() + for i in range(len(feature_strides)): + head_length = max( + 1, + int(np.log2(feature_strides[i]) - np.log2(feature_strides[0]))) + scale_head = [] + for k in range(head_length): + scale_head.append( + ConvModule( + self.in_channels[i] if k == 0 else self.channels, + self.channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg)) + if feature_strides[i] != feature_strides[0]: + scale_head.append( + nn.Upsample( + scale_factor=2, + mode='bilinear', + align_corners=self.align_corners)) + self.scale_heads.append(nn.Sequential(*scale_head)) + + def forward(self, inputs): + + x = self._transform_inputs(inputs) + + output = self.scale_heads[0](x[0]) + for i in range(1, len(self.feature_strides)): + # non inplace + output = output + resize( + self.scale_heads[i](x[i]), + size=output.shape[2:], + mode='bilinear', + align_corners=self.align_corners) + + output = self.cls_seg(output) + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/gc_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/gc_head.py new file mode 100644 index 00000000..6342811f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/gc_head.py @@ -0,0 +1,47 @@ +import torch +from annotator.mmpkg.mmcv.cnn import ContextBlock + +from ..builder import HEADS +from .fcn_head import FCNHead + + +@HEADS.register_module() +class GCHead(FCNHead): + """GCNet: Non-local Networks Meet Squeeze-Excitation Networks and Beyond. + + This head is the implementation of `GCNet + `_. + + Args: + ratio (float): Multiplier of channels ratio. Default: 1/4. + pooling_type (str): The pooling type of context aggregation. + Options are 'att', 'avg'. Default: 'avg'. + fusion_types (tuple[str]): The fusion type for feature fusion. + Options are 'channel_add', 'channel_mul'. Default: ('channel_add',) + """ + + def __init__(self, + ratio=1 / 4., + pooling_type='att', + fusion_types=('channel_add', ), + **kwargs): + super(GCHead, self).__init__(num_convs=2, **kwargs) + self.ratio = ratio + self.pooling_type = pooling_type + self.fusion_types = fusion_types + self.gc_block = ContextBlock( + in_channels=self.channels, + ratio=self.ratio, + pooling_type=self.pooling_type, + fusion_types=self.fusion_types) + + def forward(self, inputs): + """Forward function.""" + x = self._transform_inputs(inputs) + output = self.convs[0](x) + output = self.gc_block(output) + output = self.convs[1](output) + if self.concat_input: + output = self.conv_cat(torch.cat([x, output], dim=1)) + output = self.cls_seg(output) + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/lraspp_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/lraspp_head.py new file mode 100644 index 00000000..b29d80e7 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/lraspp_head.py @@ -0,0 +1,90 @@ +import torch +import torch.nn as nn +from annotator.mmpkg.mmcv import is_tuple_of +from annotator.mmpkg.mmcv.cnn import ConvModule + +from annotator.mmpkg.mmseg.ops import resize +from ..builder import HEADS +from .decode_head import BaseDecodeHead + + +@HEADS.register_module() +class LRASPPHead(BaseDecodeHead): + """Lite R-ASPP (LRASPP) head is proposed in Searching for MobileNetV3. + + This head is the improved implementation of `Searching for MobileNetV3 + `_. + + Args: + branch_channels (tuple[int]): The number of output channels in every + each branch. Default: (32, 64). + """ + + def __init__(self, branch_channels=(32, 64), **kwargs): + super(LRASPPHead, self).__init__(**kwargs) + if self.input_transform != 'multiple_select': + raise ValueError('in Lite R-ASPP (LRASPP) head, input_transform ' + f'must be \'multiple_select\'. But received ' + f'\'{self.input_transform}\'') + assert is_tuple_of(branch_channels, int) + assert len(branch_channels) == len(self.in_channels) - 1 + self.branch_channels = branch_channels + + self.convs = nn.Sequential() + self.conv_ups = nn.Sequential() + for i in range(len(branch_channels)): + self.convs.add_module( + f'conv{i}', + nn.Conv2d( + self.in_channels[i], branch_channels[i], 1, bias=False)) + self.conv_ups.add_module( + f'conv_up{i}', + ConvModule( + self.channels + branch_channels[i], + self.channels, + 1, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg, + bias=False)) + + self.conv_up_input = nn.Conv2d(self.channels, self.channels, 1) + + self.aspp_conv = ConvModule( + self.in_channels[-1], + self.channels, + 1, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg, + bias=False) + self.image_pool = nn.Sequential( + nn.AvgPool2d(kernel_size=49, stride=(16, 20)), + ConvModule( + self.in_channels[2], + self.channels, + 1, + act_cfg=dict(type='Sigmoid'), + bias=False)) + + def forward(self, inputs): + """Forward function.""" + inputs = self._transform_inputs(inputs) + + x = inputs[-1] + + x = self.aspp_conv(x) * resize( + self.image_pool(x), + size=x.size()[2:], + mode='bilinear', + align_corners=self.align_corners) + x = self.conv_up_input(x) + + for i in range(len(self.branch_channels) - 1, -1, -1): + x = resize( + x, + size=inputs[i].size()[2:], + mode='bilinear', + align_corners=self.align_corners) + x = torch.cat([x, self.convs[i](inputs[i])], 1) + x = self.conv_ups[i](x) + + return self.cls_seg(x) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/nl_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/nl_head.py new file mode 100644 index 00000000..5990df1b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/nl_head.py @@ -0,0 +1,49 @@ +import torch +from annotator.mmpkg.mmcv.cnn import NonLocal2d + +from ..builder import HEADS +from .fcn_head import FCNHead + + +@HEADS.register_module() +class NLHead(FCNHead): + """Non-local Neural Networks. + + This head is the implementation of `NLNet + `_. + + Args: + reduction (int): Reduction factor of projection transform. Default: 2. + use_scale (bool): Whether to scale pairwise_weight by + sqrt(1/inter_channels). Default: True. + mode (str): The nonlocal mode. Options are 'embedded_gaussian', + 'dot_product'. Default: 'embedded_gaussian.'. + """ + + def __init__(self, + reduction=2, + use_scale=True, + mode='embedded_gaussian', + **kwargs): + super(NLHead, self).__init__(num_convs=2, **kwargs) + self.reduction = reduction + self.use_scale = use_scale + self.mode = mode + self.nl_block = NonLocal2d( + in_channels=self.channels, + reduction=self.reduction, + use_scale=self.use_scale, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + mode=self.mode) + + def forward(self, inputs): + """Forward function.""" + x = self._transform_inputs(inputs) + output = self.convs[0](x) + output = self.nl_block(output) + output = self.convs[1](output) + if self.concat_input: + output = self.conv_cat(torch.cat([x, output], dim=1)) + output = self.cls_seg(output) + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/ocr_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/ocr_head.py new file mode 100644 index 00000000..c46d10e5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/ocr_head.py @@ -0,0 +1,127 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +from annotator.mmpkg.mmcv.cnn import ConvModule + +from annotator.mmpkg.mmseg.ops import resize +from ..builder import HEADS +from ..utils import SelfAttentionBlock as _SelfAttentionBlock +from .cascade_decode_head import BaseCascadeDecodeHead + + +class SpatialGatherModule(nn.Module): + """Aggregate the context features according to the initial predicted + probability distribution. + + Employ the soft-weighted method to aggregate the context. + """ + + def __init__(self, scale): + super(SpatialGatherModule, self).__init__() + self.scale = scale + + def forward(self, feats, probs): + """Forward function.""" + batch_size, num_classes, height, width = probs.size() + channels = feats.size(1) + probs = probs.view(batch_size, num_classes, -1) + feats = feats.view(batch_size, channels, -1) + # [batch_size, height*width, num_classes] + feats = feats.permute(0, 2, 1) + # [batch_size, channels, height*width] + probs = F.softmax(self.scale * probs, dim=2) + # [batch_size, channels, num_classes] + ocr_context = torch.matmul(probs, feats) + ocr_context = ocr_context.permute(0, 2, 1).contiguous().unsqueeze(3) + return ocr_context + + +class ObjectAttentionBlock(_SelfAttentionBlock): + """Make a OCR used SelfAttentionBlock.""" + + def __init__(self, in_channels, channels, scale, conv_cfg, norm_cfg, + act_cfg): + if scale > 1: + query_downsample = nn.MaxPool2d(kernel_size=scale) + else: + query_downsample = None + super(ObjectAttentionBlock, self).__init__( + key_in_channels=in_channels, + query_in_channels=in_channels, + channels=channels, + out_channels=in_channels, + share_key_query=False, + query_downsample=query_downsample, + key_downsample=None, + key_query_num_convs=2, + key_query_norm=True, + value_out_num_convs=1, + value_out_norm=True, + matmul_norm=True, + with_out=True, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + self.bottleneck = ConvModule( + in_channels * 2, + in_channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + def forward(self, query_feats, key_feats): + """Forward function.""" + context = super(ObjectAttentionBlock, + self).forward(query_feats, key_feats) + output = self.bottleneck(torch.cat([context, query_feats], dim=1)) + if self.query_downsample is not None: + output = resize(query_feats) + + return output + + +@HEADS.register_module() +class OCRHead(BaseCascadeDecodeHead): + """Object-Contextual Representations for Semantic Segmentation. + + This head is the implementation of `OCRNet + `_. + + Args: + ocr_channels (int): The intermediate channels of OCR block. + scale (int): The scale of probability map in SpatialGatherModule in + Default: 1. + """ + + def __init__(self, ocr_channels, scale=1, **kwargs): + super(OCRHead, self).__init__(**kwargs) + self.ocr_channels = ocr_channels + self.scale = scale + self.object_context_block = ObjectAttentionBlock( + self.channels, + self.ocr_channels, + self.scale, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + self.spatial_gather_module = SpatialGatherModule(self.scale) + + self.bottleneck = ConvModule( + self.in_channels, + self.channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + def forward(self, inputs, prev_output): + """Forward function.""" + x = self._transform_inputs(inputs) + feats = self.bottleneck(x) + context = self.spatial_gather_module(feats, prev_output) + object_context = self.object_context_block(feats, context) + output = self.cls_seg(object_context) + + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/point_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/point_head.py new file mode 100644 index 00000000..c6782763 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/point_head.py @@ -0,0 +1,354 @@ +# Modified from https://github.com/facebookresearch/detectron2/tree/master/projects/PointRend/point_head/point_head.py # noqa + +import torch +import torch.nn as nn + +try: + from mmcv.cnn import ConvModule, normal_init + from mmcv.ops import point_sample +except ImportError: + from annotator.mmpkg.mmcv.cnn import ConvModule, normal_init + from annotator.mmpkg.mmcv.ops import point_sample + +from annotator.mmpkg.mmseg.models.builder import HEADS +from annotator.mmpkg.mmseg.ops import resize +from ..losses import accuracy +from .cascade_decode_head import BaseCascadeDecodeHead + + +def calculate_uncertainty(seg_logits): + """Estimate uncertainty based on seg logits. + + For each location of the prediction ``seg_logits`` we estimate + uncertainty as the difference between top first and top second + predicted logits. + + Args: + seg_logits (Tensor): Semantic segmentation logits, + shape (batch_size, num_classes, height, width). + + Returns: + scores (Tensor): T uncertainty scores with the most uncertain + locations having the highest uncertainty score, shape ( + batch_size, 1, height, width) + """ + top2_scores = torch.topk(seg_logits, k=2, dim=1)[0] + return (top2_scores[:, 1] - top2_scores[:, 0]).unsqueeze(1) + + +@HEADS.register_module() +class PointHead(BaseCascadeDecodeHead): + """A mask point head use in PointRend. + + ``PointHead`` use shared multi-layer perceptron (equivalent to + nn.Conv1d) to predict the logit of input points. The fine-grained feature + and coarse feature will be concatenate together for predication. + + Args: + num_fcs (int): Number of fc layers in the head. Default: 3. + in_channels (int): Number of input channels. Default: 256. + fc_channels (int): Number of fc channels. Default: 256. + num_classes (int): Number of classes for logits. Default: 80. + class_agnostic (bool): Whether use class agnostic classification. + If so, the output channels of logits will be 1. Default: False. + coarse_pred_each_layer (bool): Whether concatenate coarse feature with + the output of each fc layer. Default: True. + conv_cfg (dict|None): Dictionary to construct and config conv layer. + Default: dict(type='Conv1d')) + norm_cfg (dict|None): Dictionary to construct and config norm layer. + Default: None. + loss_point (dict): Dictionary to construct and config loss layer of + point head. Default: dict(type='CrossEntropyLoss', use_mask=True, + loss_weight=1.0). + """ + + def __init__(self, + num_fcs=3, + coarse_pred_each_layer=True, + conv_cfg=dict(type='Conv1d'), + norm_cfg=None, + act_cfg=dict(type='ReLU', inplace=False), + **kwargs): + super(PointHead, self).__init__( + input_transform='multiple_select', + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg, + **kwargs) + + self.num_fcs = num_fcs + self.coarse_pred_each_layer = coarse_pred_each_layer + + fc_in_channels = sum(self.in_channels) + self.num_classes + fc_channels = self.channels + self.fcs = nn.ModuleList() + for k in range(num_fcs): + fc = ConvModule( + fc_in_channels, + fc_channels, + kernel_size=1, + stride=1, + padding=0, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + self.fcs.append(fc) + fc_in_channels = fc_channels + fc_in_channels += self.num_classes if self.coarse_pred_each_layer \ + else 0 + self.fc_seg = nn.Conv1d( + fc_in_channels, + self.num_classes, + kernel_size=1, + stride=1, + padding=0) + if self.dropout_ratio > 0: + self.dropout = nn.Dropout(self.dropout_ratio) + delattr(self, 'conv_seg') + + def init_weights(self): + """Initialize weights of classification layer.""" + normal_init(self.fc_seg, std=0.001) + + def cls_seg(self, feat): + """Classify each pixel with fc.""" + if self.dropout is not None: + feat = self.dropout(feat) + output = self.fc_seg(feat) + return output + + def forward(self, fine_grained_point_feats, coarse_point_feats): + x = torch.cat([fine_grained_point_feats, coarse_point_feats], dim=1) + for fc in self.fcs: + x = fc(x) + if self.coarse_pred_each_layer: + x = torch.cat((x, coarse_point_feats), dim=1) + return self.cls_seg(x) + + def _get_fine_grained_point_feats(self, x, points): + """Sample from fine grained features. + + Args: + x (list[Tensor]): Feature pyramid from by neck or backbone. + points (Tensor): Point coordinates, shape (batch_size, + num_points, 2). + + Returns: + fine_grained_feats (Tensor): Sampled fine grained feature, + shape (batch_size, sum(channels of x), num_points). + """ + + fine_grained_feats_list = [ + point_sample(_, points, align_corners=self.align_corners) + for _ in x + ] + if len(fine_grained_feats_list) > 1: + fine_grained_feats = torch.cat(fine_grained_feats_list, dim=1) + else: + fine_grained_feats = fine_grained_feats_list[0] + + return fine_grained_feats + + def _get_coarse_point_feats(self, prev_output, points): + """Sample from fine grained features. + + Args: + prev_output (list[Tensor]): Prediction of previous decode head. + points (Tensor): Point coordinates, shape (batch_size, + num_points, 2). + + Returns: + coarse_feats (Tensor): Sampled coarse feature, shape (batch_size, + num_classes, num_points). + """ + + coarse_feats = point_sample( + prev_output, points, align_corners=self.align_corners) + + return coarse_feats + + def forward_train(self, inputs, prev_output, img_metas, gt_semantic_seg, + train_cfg): + """Forward function for training. + Args: + inputs (list[Tensor]): List of multi-level img features. + prev_output (Tensor): The output of previous decode head. + img_metas (list[dict]): List of image info dict where each dict + has: 'img_shape', 'scale_factor', 'flip', and may also contain + 'filename', 'ori_shape', 'pad_shape', and 'img_norm_cfg'. + For details on the values of these keys see + `mmseg/datasets/pipelines/formatting.py:Collect`. + gt_semantic_seg (Tensor): Semantic segmentation masks + used if the architecture supports semantic segmentation task. + train_cfg (dict): The training config. + + Returns: + dict[str, Tensor]: a dictionary of loss components + """ + x = self._transform_inputs(inputs) + with torch.no_grad(): + points = self.get_points_train( + prev_output, calculate_uncertainty, cfg=train_cfg) + fine_grained_point_feats = self._get_fine_grained_point_feats( + x, points) + coarse_point_feats = self._get_coarse_point_feats(prev_output, points) + point_logits = self.forward(fine_grained_point_feats, + coarse_point_feats) + point_label = point_sample( + gt_semantic_seg.float(), + points, + mode='nearest', + align_corners=self.align_corners) + point_label = point_label.squeeze(1).long() + + losses = self.losses(point_logits, point_label) + + return losses + + def forward_test(self, inputs, prev_output, img_metas, test_cfg): + """Forward function for testing. + + Args: + inputs (list[Tensor]): List of multi-level img features. + prev_output (Tensor): The output of previous decode head. + img_metas (list[dict]): List of image info dict where each dict + has: 'img_shape', 'scale_factor', 'flip', and may also contain + 'filename', 'ori_shape', 'pad_shape', and 'img_norm_cfg'. + For details on the values of these keys see + `mmseg/datasets/pipelines/formatting.py:Collect`. + test_cfg (dict): The testing config. + + Returns: + Tensor: Output segmentation map. + """ + + x = self._transform_inputs(inputs) + refined_seg_logits = prev_output.clone() + for _ in range(test_cfg.subdivision_steps): + refined_seg_logits = resize( + refined_seg_logits, + scale_factor=test_cfg.scale_factor, + mode='bilinear', + align_corners=self.align_corners) + batch_size, channels, height, width = refined_seg_logits.shape + point_indices, points = self.get_points_test( + refined_seg_logits, calculate_uncertainty, cfg=test_cfg) + fine_grained_point_feats = self._get_fine_grained_point_feats( + x, points) + coarse_point_feats = self._get_coarse_point_feats( + prev_output, points) + point_logits = self.forward(fine_grained_point_feats, + coarse_point_feats) + + point_indices = point_indices.unsqueeze(1).expand(-1, channels, -1) + refined_seg_logits = refined_seg_logits.reshape( + batch_size, channels, height * width) + refined_seg_logits = refined_seg_logits.scatter_( + 2, point_indices, point_logits) + refined_seg_logits = refined_seg_logits.view( + batch_size, channels, height, width) + + return refined_seg_logits + + def losses(self, point_logits, point_label): + """Compute segmentation loss.""" + loss = dict() + loss['loss_point'] = self.loss_decode( + point_logits, point_label, ignore_index=self.ignore_index) + loss['acc_point'] = accuracy(point_logits, point_label) + return loss + + def get_points_train(self, seg_logits, uncertainty_func, cfg): + """Sample points for training. + + Sample points in [0, 1] x [0, 1] coordinate space based on their + uncertainty. The uncertainties are calculated for each point using + 'uncertainty_func' function that takes point's logit prediction as + input. + + Args: + seg_logits (Tensor): Semantic segmentation logits, shape ( + batch_size, num_classes, height, width). + uncertainty_func (func): uncertainty calculation function. + cfg (dict): Training config of point head. + + Returns: + point_coords (Tensor): A tensor of shape (batch_size, num_points, + 2) that contains the coordinates of ``num_points`` sampled + points. + """ + num_points = cfg.num_points + oversample_ratio = cfg.oversample_ratio + importance_sample_ratio = cfg.importance_sample_ratio + assert oversample_ratio >= 1 + assert 0 <= importance_sample_ratio <= 1 + batch_size = seg_logits.shape[0] + num_sampled = int(num_points * oversample_ratio) + point_coords = torch.rand( + batch_size, num_sampled, 2, device=seg_logits.device) + point_logits = point_sample(seg_logits, point_coords) + # It is crucial to calculate uncertainty based on the sampled + # prediction value for the points. Calculating uncertainties of the + # coarse predictions first and sampling them for points leads to + # incorrect results. To illustrate this: assume uncertainty func( + # logits)=-abs(logits), a sampled point between two coarse + # predictions with -1 and 1 logits has 0 logits, and therefore 0 + # uncertainty value. However, if we calculate uncertainties for the + # coarse predictions first, both will have -1 uncertainty, + # and sampled point will get -1 uncertainty. + point_uncertainties = uncertainty_func(point_logits) + num_uncertain_points = int(importance_sample_ratio * num_points) + num_random_points = num_points - num_uncertain_points + idx = torch.topk( + point_uncertainties[:, 0, :], k=num_uncertain_points, dim=1)[1] + shift = num_sampled * torch.arange( + batch_size, dtype=torch.long, device=seg_logits.device) + idx += shift[:, None] + point_coords = point_coords.view(-1, 2)[idx.view(-1), :].view( + batch_size, num_uncertain_points, 2) + if num_random_points > 0: + rand_point_coords = torch.rand( + batch_size, num_random_points, 2, device=seg_logits.device) + point_coords = torch.cat((point_coords, rand_point_coords), dim=1) + return point_coords + + def get_points_test(self, seg_logits, uncertainty_func, cfg): + """Sample points for testing. + + Find ``num_points`` most uncertain points from ``uncertainty_map``. + + Args: + seg_logits (Tensor): A tensor of shape (batch_size, num_classes, + height, width) for class-specific or class-agnostic prediction. + uncertainty_func (func): uncertainty calculation function. + cfg (dict): Testing config of point head. + + Returns: + point_indices (Tensor): A tensor of shape (batch_size, num_points) + that contains indices from [0, height x width) of the most + uncertain points. + point_coords (Tensor): A tensor of shape (batch_size, num_points, + 2) that contains [0, 1] x [0, 1] normalized coordinates of the + most uncertain points from the ``height x width`` grid . + """ + + num_points = cfg.subdivision_num_points + uncertainty_map = uncertainty_func(seg_logits) + batch_size, _, height, width = uncertainty_map.shape + h_step = 1.0 / height + w_step = 1.0 / width + + uncertainty_map = uncertainty_map.view(batch_size, height * width) + num_points = min(height * width, num_points) + point_indices = uncertainty_map.topk(num_points, dim=1)[1] + point_coords = torch.zeros( + batch_size, + num_points, + 2, + dtype=torch.float, + device=seg_logits.device) + point_coords[:, :, 0] = w_step / 2.0 + (point_indices % + width).float() * w_step + point_coords[:, :, 1] = h_step / 2.0 + (point_indices // + width).float() * h_step + return point_indices, point_coords diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/psa_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/psa_head.py new file mode 100644 index 00000000..ba6fe3a8 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/psa_head.py @@ -0,0 +1,199 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +from annotator.mmpkg.mmcv.cnn import ConvModule + +from annotator.mmpkg.mmseg.ops import resize +from ..builder import HEADS +from .decode_head import BaseDecodeHead + +try: + try: + from mmcv.ops import PSAMask + except ImportError: + from annotator.mmpkg.mmcv.ops import PSAMask +except ModuleNotFoundError: + PSAMask = None + + +@HEADS.register_module() +class PSAHead(BaseDecodeHead): + """Point-wise Spatial Attention Network for Scene Parsing. + + This head is the implementation of `PSANet + `_. + + Args: + mask_size (tuple[int]): The PSA mask size. It usually equals input + size. + psa_type (str): The type of psa module. Options are 'collect', + 'distribute', 'bi-direction'. Default: 'bi-direction' + compact (bool): Whether use compact map for 'collect' mode. + Default: True. + shrink_factor (int): The downsample factors of psa mask. Default: 2. + normalization_factor (float): The normalize factor of attention. + psa_softmax (bool): Whether use softmax for attention. + """ + + def __init__(self, + mask_size, + psa_type='bi-direction', + compact=False, + shrink_factor=2, + normalization_factor=1.0, + psa_softmax=True, + **kwargs): + if PSAMask is None: + raise RuntimeError('Please install mmcv-full for PSAMask ops') + super(PSAHead, self).__init__(**kwargs) + assert psa_type in ['collect', 'distribute', 'bi-direction'] + self.psa_type = psa_type + self.compact = compact + self.shrink_factor = shrink_factor + self.mask_size = mask_size + mask_h, mask_w = mask_size + self.psa_softmax = psa_softmax + if normalization_factor is None: + normalization_factor = mask_h * mask_w + self.normalization_factor = normalization_factor + + self.reduce = ConvModule( + self.in_channels, + self.channels, + kernel_size=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + self.attention = nn.Sequential( + ConvModule( + self.channels, + self.channels, + kernel_size=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg), + nn.Conv2d( + self.channels, mask_h * mask_w, kernel_size=1, bias=False)) + if psa_type == 'bi-direction': + self.reduce_p = ConvModule( + self.in_channels, + self.channels, + kernel_size=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + self.attention_p = nn.Sequential( + ConvModule( + self.channels, + self.channels, + kernel_size=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg), + nn.Conv2d( + self.channels, mask_h * mask_w, kernel_size=1, bias=False)) + self.psamask_collect = PSAMask('collect', mask_size) + self.psamask_distribute = PSAMask('distribute', mask_size) + else: + self.psamask = PSAMask(psa_type, mask_size) + self.proj = ConvModule( + self.channels * (2 if psa_type == 'bi-direction' else 1), + self.in_channels, + kernel_size=1, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + self.bottleneck = ConvModule( + self.in_channels * 2, + self.channels, + kernel_size=3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + def forward(self, inputs): + """Forward function.""" + x = self._transform_inputs(inputs) + identity = x + align_corners = self.align_corners + if self.psa_type in ['collect', 'distribute']: + out = self.reduce(x) + n, c, h, w = out.size() + if self.shrink_factor != 1: + if h % self.shrink_factor and w % self.shrink_factor: + h = (h - 1) // self.shrink_factor + 1 + w = (w - 1) // self.shrink_factor + 1 + align_corners = True + else: + h = h // self.shrink_factor + w = w // self.shrink_factor + align_corners = False + out = resize( + out, + size=(h, w), + mode='bilinear', + align_corners=align_corners) + y = self.attention(out) + if self.compact: + if self.psa_type == 'collect': + y = y.view(n, h * w, + h * w).transpose(1, 2).view(n, h * w, h, w) + else: + y = self.psamask(y) + if self.psa_softmax: + y = F.softmax(y, dim=1) + out = torch.bmm( + out.view(n, c, h * w), y.view(n, h * w, h * w)).view( + n, c, h, w) * (1.0 / self.normalization_factor) + else: + x_col = self.reduce(x) + x_dis = self.reduce_p(x) + n, c, h, w = x_col.size() + if self.shrink_factor != 1: + if h % self.shrink_factor and w % self.shrink_factor: + h = (h - 1) // self.shrink_factor + 1 + w = (w - 1) // self.shrink_factor + 1 + align_corners = True + else: + h = h // self.shrink_factor + w = w // self.shrink_factor + align_corners = False + x_col = resize( + x_col, + size=(h, w), + mode='bilinear', + align_corners=align_corners) + x_dis = resize( + x_dis, + size=(h, w), + mode='bilinear', + align_corners=align_corners) + y_col = self.attention(x_col) + y_dis = self.attention_p(x_dis) + if self.compact: + y_dis = y_dis.view(n, h * w, + h * w).transpose(1, 2).view(n, h * w, h, w) + else: + y_col = self.psamask_collect(y_col) + y_dis = self.psamask_distribute(y_dis) + if self.psa_softmax: + y_col = F.softmax(y_col, dim=1) + y_dis = F.softmax(y_dis, dim=1) + x_col = torch.bmm( + x_col.view(n, c, h * w), y_col.view(n, h * w, h * w)).view( + n, c, h, w) * (1.0 / self.normalization_factor) + x_dis = torch.bmm( + x_dis.view(n, c, h * w), y_dis.view(n, h * w, h * w)).view( + n, c, h, w) * (1.0 / self.normalization_factor) + out = torch.cat([x_col, x_dis], 1) + out = self.proj(out) + out = resize( + out, + size=identity.shape[2:], + mode='bilinear', + align_corners=align_corners) + out = self.bottleneck(torch.cat((identity, out), dim=1)) + out = self.cls_seg(out) + return out diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/psp_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/psp_head.py new file mode 100644 index 00000000..2a88d807 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/psp_head.py @@ -0,0 +1,101 @@ +import torch +import torch.nn as nn +from annotator.mmpkg.mmcv.cnn import ConvModule + +from annotator.mmpkg.mmseg.ops import resize +from ..builder import HEADS +from .decode_head import BaseDecodeHead + + +class PPM(nn.ModuleList): + """Pooling Pyramid Module used in PSPNet. + + Args: + pool_scales (tuple[int]): Pooling scales used in Pooling Pyramid + Module. + in_channels (int): Input channels. + channels (int): Channels after modules, before conv_seg. + conv_cfg (dict|None): Config of conv layers. + norm_cfg (dict|None): Config of norm layers. + act_cfg (dict): Config of activation layers. + align_corners (bool): align_corners argument of F.interpolate. + """ + + def __init__(self, pool_scales, in_channels, channels, conv_cfg, norm_cfg, + act_cfg, align_corners): + super(PPM, self).__init__() + self.pool_scales = pool_scales + self.align_corners = align_corners + self.in_channels = in_channels + self.channels = channels + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + for pool_scale in pool_scales: + self.append( + nn.Sequential( + nn.AdaptiveAvgPool2d(pool_scale), + ConvModule( + self.in_channels, + self.channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg))) + + def forward(self, x): + """Forward function.""" + ppm_outs = [] + for ppm in self: + ppm_out = ppm(x) + upsampled_ppm_out = resize( + ppm_out, + size=x.size()[2:], + mode='bilinear', + align_corners=self.align_corners) + ppm_outs.append(upsampled_ppm_out) + return ppm_outs + + +@HEADS.register_module() +class PSPHead(BaseDecodeHead): + """Pyramid Scene Parsing Network. + + This head is the implementation of + `PSPNet `_. + + Args: + pool_scales (tuple[int]): Pooling scales used in Pooling Pyramid + Module. Default: (1, 2, 3, 6). + """ + + def __init__(self, pool_scales=(1, 2, 3, 6), **kwargs): + super(PSPHead, self).__init__(**kwargs) + assert isinstance(pool_scales, (list, tuple)) + self.pool_scales = pool_scales + self.psp_modules = PPM( + self.pool_scales, + self.in_channels, + self.channels, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg, + align_corners=self.align_corners) + self.bottleneck = ConvModule( + self.in_channels + len(pool_scales) * self.channels, + self.channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + def forward(self, inputs): + """Forward function.""" + x = self._transform_inputs(inputs) + psp_outs = [x] + psp_outs.extend(self.psp_modules(x)) + psp_outs = torch.cat(psp_outs, dim=1) + output = self.bottleneck(psp_outs) + output = self.cls_seg(output) + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/sep_aspp_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/sep_aspp_head.py new file mode 100644 index 00000000..a2397069 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/sep_aspp_head.py @@ -0,0 +1,101 @@ +import torch +import torch.nn as nn +from annotator.mmpkg.mmcv.cnn import ConvModule, DepthwiseSeparableConvModule + +from annotator.mmpkg.mmseg.ops import resize +from ..builder import HEADS +from .aspp_head import ASPPHead, ASPPModule + + +class DepthwiseSeparableASPPModule(ASPPModule): + """Atrous Spatial Pyramid Pooling (ASPP) Module with depthwise separable + conv.""" + + def __init__(self, **kwargs): + super(DepthwiseSeparableASPPModule, self).__init__(**kwargs) + for i, dilation in enumerate(self.dilations): + if dilation > 1: + self[i] = DepthwiseSeparableConvModule( + self.in_channels, + self.channels, + 3, + dilation=dilation, + padding=dilation, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + +@HEADS.register_module() +class DepthwiseSeparableASPPHead(ASPPHead): + """Encoder-Decoder with Atrous Separable Convolution for Semantic Image + Segmentation. + + This head is the implementation of `DeepLabV3+ + `_. + + Args: + c1_in_channels (int): The input channels of c1 decoder. If is 0, + the no decoder will be used. + c1_channels (int): The intermediate channels of c1 decoder. + """ + + def __init__(self, c1_in_channels, c1_channels, **kwargs): + super(DepthwiseSeparableASPPHead, self).__init__(**kwargs) + assert c1_in_channels >= 0 + self.aspp_modules = DepthwiseSeparableASPPModule( + dilations=self.dilations, + in_channels=self.in_channels, + channels=self.channels, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + if c1_in_channels > 0: + self.c1_bottleneck = ConvModule( + c1_in_channels, + c1_channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + else: + self.c1_bottleneck = None + self.sep_bottleneck = nn.Sequential( + DepthwiseSeparableConvModule( + self.channels + c1_channels, + self.channels, + 3, + padding=1, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg), + DepthwiseSeparableConvModule( + self.channels, + self.channels, + 3, + padding=1, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg)) + + def forward(self, inputs): + """Forward function.""" + x = self._transform_inputs(inputs) + aspp_outs = [ + resize( + self.image_pool(x), + size=x.size()[2:], + mode='bilinear', + align_corners=self.align_corners) + ] + aspp_outs.extend(self.aspp_modules(x)) + aspp_outs = torch.cat(aspp_outs, dim=1) + output = self.bottleneck(aspp_outs) + if self.c1_bottleneck is not None: + c1_output = self.c1_bottleneck(inputs[0]) + output = resize( + input=output, + size=c1_output.shape[2:], + mode='bilinear', + align_corners=self.align_corners) + output = torch.cat([output, c1_output], dim=1) + output = self.sep_bottleneck(output) + output = self.cls_seg(output) + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/sep_fcn_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/sep_fcn_head.py new file mode 100644 index 00000000..3ea198ab --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/sep_fcn_head.py @@ -0,0 +1,51 @@ +from annotator.mmpkg.mmcv.cnn import DepthwiseSeparableConvModule + +from ..builder import HEADS +from .fcn_head import FCNHead + + +@HEADS.register_module() +class DepthwiseSeparableFCNHead(FCNHead): + """Depthwise-Separable Fully Convolutional Network for Semantic + Segmentation. + + This head is implemented according to Fast-SCNN paper. + Args: + in_channels(int): Number of output channels of FFM. + channels(int): Number of middle-stage channels in the decode head. + concat_input(bool): Whether to concatenate original decode input into + the result of several consecutive convolution layers. + Default: True. + num_classes(int): Used to determine the dimension of + final prediction tensor. + in_index(int): Correspond with 'out_indices' in FastSCNN backbone. + norm_cfg (dict | None): Config of norm layers. + align_corners (bool): align_corners argument of F.interpolate. + Default: False. + loss_decode(dict): Config of loss type and some + relevant additional options. + """ + + def __init__(self, **kwargs): + super(DepthwiseSeparableFCNHead, self).__init__(**kwargs) + self.convs[0] = DepthwiseSeparableConvModule( + self.in_channels, + self.channels, + kernel_size=self.kernel_size, + padding=self.kernel_size // 2, + norm_cfg=self.norm_cfg) + for i in range(1, self.num_convs): + self.convs[i] = DepthwiseSeparableConvModule( + self.channels, + self.channels, + kernel_size=self.kernel_size, + padding=self.kernel_size // 2, + norm_cfg=self.norm_cfg) + + if self.concat_input: + self.conv_cat = DepthwiseSeparableConvModule( + self.in_channels + self.channels, + self.channels, + kernel_size=self.kernel_size, + padding=self.kernel_size // 2, + norm_cfg=self.norm_cfg) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/uper_head.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/uper_head.py new file mode 100644 index 00000000..95247357 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/decode_heads/uper_head.py @@ -0,0 +1,126 @@ +import torch +import torch.nn as nn +from annotator.mmpkg.mmcv.cnn import ConvModule + +from annotator.mmpkg.mmseg.ops import resize +from ..builder import HEADS +from .decode_head import BaseDecodeHead +from .psp_head import PPM + + +@HEADS.register_module() +class UPerHead(BaseDecodeHead): + """Unified Perceptual Parsing for Scene Understanding. + + This head is the implementation of `UPerNet + `_. + + Args: + pool_scales (tuple[int]): Pooling scales used in Pooling Pyramid + Module applied on the last feature. Default: (1, 2, 3, 6). + """ + + def __init__(self, pool_scales=(1, 2, 3, 6), **kwargs): + super(UPerHead, self).__init__( + input_transform='multiple_select', **kwargs) + # PSP Module + self.psp_modules = PPM( + pool_scales, + self.in_channels[-1], + self.channels, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg, + align_corners=self.align_corners) + self.bottleneck = ConvModule( + self.in_channels[-1] + len(pool_scales) * self.channels, + self.channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + # FPN Module + self.lateral_convs = nn.ModuleList() + self.fpn_convs = nn.ModuleList() + for in_channels in self.in_channels[:-1]: # skip the top layer + l_conv = ConvModule( + in_channels, + self.channels, + 1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg, + inplace=False) + fpn_conv = ConvModule( + self.channels, + self.channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg, + inplace=False) + self.lateral_convs.append(l_conv) + self.fpn_convs.append(fpn_conv) + + self.fpn_bottleneck = ConvModule( + len(self.in_channels) * self.channels, + self.channels, + 3, + padding=1, + conv_cfg=self.conv_cfg, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + + def psp_forward(self, inputs): + """Forward function of PSP module.""" + x = inputs[-1] + psp_outs = [x] + psp_outs.extend(self.psp_modules(x)) + psp_outs = torch.cat(psp_outs, dim=1) + output = self.bottleneck(psp_outs) + + return output + + def forward(self, inputs): + """Forward function.""" + + inputs = self._transform_inputs(inputs) + + # build laterals + laterals = [ + lateral_conv(inputs[i]) + for i, lateral_conv in enumerate(self.lateral_convs) + ] + + laterals.append(self.psp_forward(inputs)) + + # build top-down path + used_backbone_levels = len(laterals) + for i in range(used_backbone_levels - 1, 0, -1): + prev_shape = laterals[i - 1].shape[2:] + laterals[i - 1] += resize( + laterals[i], + size=prev_shape, + mode='bilinear', + align_corners=self.align_corners) + + # build outputs + fpn_outs = [ + self.fpn_convs[i](laterals[i]) + for i in range(used_backbone_levels - 1) + ] + # append psp feature + fpn_outs.append(laterals[-1]) + + for i in range(used_backbone_levels - 1, 0, -1): + fpn_outs[i] = resize( + fpn_outs[i], + size=fpn_outs[0].shape[2:], + mode='bilinear', + align_corners=self.align_corners) + fpn_outs = torch.cat(fpn_outs, dim=1) + output = self.fpn_bottleneck(fpn_outs) + output = self.cls_seg(output) + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/__init__.py new file mode 100644 index 00000000..beca7204 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/__init__.py @@ -0,0 +1,12 @@ +from .accuracy import Accuracy, accuracy +from .cross_entropy_loss import (CrossEntropyLoss, binary_cross_entropy, + cross_entropy, mask_cross_entropy) +from .dice_loss import DiceLoss +from .lovasz_loss import LovaszLoss +from .utils import reduce_loss, weight_reduce_loss, weighted_loss + +__all__ = [ + 'accuracy', 'Accuracy', 'cross_entropy', 'binary_cross_entropy', + 'mask_cross_entropy', 'CrossEntropyLoss', 'reduce_loss', + 'weight_reduce_loss', 'weighted_loss', 'LovaszLoss', 'DiceLoss' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/accuracy.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/accuracy.py new file mode 100644 index 00000000..c0fd2e7e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/accuracy.py @@ -0,0 +1,78 @@ +import torch.nn as nn + + +def accuracy(pred, target, topk=1, thresh=None): + """Calculate accuracy according to the prediction and target. + + Args: + pred (torch.Tensor): The model prediction, shape (N, num_class, ...) + target (torch.Tensor): The target of each prediction, shape (N, , ...) + topk (int | tuple[int], optional): If the predictions in ``topk`` + matches the target, the predictions will be regarded as + correct ones. Defaults to 1. + thresh (float, optional): If not None, predictions with scores under + this threshold are considered incorrect. Default to None. + + Returns: + float | tuple[float]: If the input ``topk`` is a single integer, + the function will return a single float as accuracy. If + ``topk`` is a tuple containing multiple integers, the + function will return a tuple containing accuracies of + each ``topk`` number. + """ + assert isinstance(topk, (int, tuple)) + if isinstance(topk, int): + topk = (topk, ) + return_single = True + else: + return_single = False + + maxk = max(topk) + if pred.size(0) == 0: + accu = [pred.new_tensor(0.) for i in range(len(topk))] + return accu[0] if return_single else accu + assert pred.ndim == target.ndim + 1 + assert pred.size(0) == target.size(0) + assert maxk <= pred.size(1), \ + f'maxk {maxk} exceeds pred dimension {pred.size(1)}' + pred_value, pred_label = pred.topk(maxk, dim=1) + # transpose to shape (maxk, N, ...) + pred_label = pred_label.transpose(0, 1) + correct = pred_label.eq(target.unsqueeze(0).expand_as(pred_label)) + if thresh is not None: + # Only prediction values larger than thresh are counted as correct + correct = correct & (pred_value > thresh).t() + res = [] + for k in topk: + correct_k = correct[:k].reshape(-1).float().sum(0, keepdim=True) + res.append(correct_k.mul_(100.0 / target.numel())) + return res[0] if return_single else res + + +class Accuracy(nn.Module): + """Accuracy calculation module.""" + + def __init__(self, topk=(1, ), thresh=None): + """Module to calculate the accuracy. + + Args: + topk (tuple, optional): The criterion used to calculate the + accuracy. Defaults to (1,). + thresh (float, optional): If not None, predictions with scores + under this threshold are considered incorrect. Default to None. + """ + super().__init__() + self.topk = topk + self.thresh = thresh + + def forward(self, pred, target): + """Forward function to calculate accuracy. + + Args: + pred (torch.Tensor): Prediction of models. + target (torch.Tensor): Target for each prediction. + + Returns: + tuple[float]: The accuracies under different topk criterions. + """ + return accuracy(pred, target, self.topk, self.thresh) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/cross_entropy_loss.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/cross_entropy_loss.py new file mode 100644 index 00000000..42c0790c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/cross_entropy_loss.py @@ -0,0 +1,198 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F + +from ..builder import LOSSES +from .utils import get_class_weight, weight_reduce_loss + + +def cross_entropy(pred, + label, + weight=None, + class_weight=None, + reduction='mean', + avg_factor=None, + ignore_index=-100): + """The wrapper function for :func:`F.cross_entropy`""" + # class_weight is a manual rescaling weight given to each class. + # If given, has to be a Tensor of size C element-wise losses + loss = F.cross_entropy( + pred, + label, + weight=class_weight, + reduction='none', + ignore_index=ignore_index) + + # apply weights and do the reduction + if weight is not None: + weight = weight.float() + loss = weight_reduce_loss( + loss, weight=weight, reduction=reduction, avg_factor=avg_factor) + + return loss + + +def _expand_onehot_labels(labels, label_weights, target_shape, ignore_index): + """Expand onehot labels to match the size of prediction.""" + bin_labels = labels.new_zeros(target_shape) + valid_mask = (labels >= 0) & (labels != ignore_index) + inds = torch.nonzero(valid_mask, as_tuple=True) + + if inds[0].numel() > 0: + if labels.dim() == 3: + bin_labels[inds[0], labels[valid_mask], inds[1], inds[2]] = 1 + else: + bin_labels[inds[0], labels[valid_mask]] = 1 + + valid_mask = valid_mask.unsqueeze(1).expand(target_shape).float() + if label_weights is None: + bin_label_weights = valid_mask + else: + bin_label_weights = label_weights.unsqueeze(1).expand(target_shape) + bin_label_weights *= valid_mask + + return bin_labels, bin_label_weights + + +def binary_cross_entropy(pred, + label, + weight=None, + reduction='mean', + avg_factor=None, + class_weight=None, + ignore_index=255): + """Calculate the binary CrossEntropy loss. + + Args: + pred (torch.Tensor): The prediction with shape (N, 1). + label (torch.Tensor): The learning label of the prediction. + weight (torch.Tensor, optional): Sample-wise loss weight. + reduction (str, optional): The method used to reduce the loss. + Options are "none", "mean" and "sum". + avg_factor (int, optional): Average factor that is used to average + the loss. Defaults to None. + class_weight (list[float], optional): The weight for each class. + ignore_index (int | None): The label index to be ignored. Default: 255 + + Returns: + torch.Tensor: The calculated loss + """ + if pred.dim() != label.dim(): + assert (pred.dim() == 2 and label.dim() == 1) or ( + pred.dim() == 4 and label.dim() == 3), \ + 'Only pred shape [N, C], label shape [N] or pred shape [N, C, ' \ + 'H, W], label shape [N, H, W] are supported' + label, weight = _expand_onehot_labels(label, weight, pred.shape, + ignore_index) + + # weighted element-wise losses + if weight is not None: + weight = weight.float() + loss = F.binary_cross_entropy_with_logits( + pred, label.float(), pos_weight=class_weight, reduction='none') + # do the reduction for the weighted loss + loss = weight_reduce_loss( + loss, weight, reduction=reduction, avg_factor=avg_factor) + + return loss + + +def mask_cross_entropy(pred, + target, + label, + reduction='mean', + avg_factor=None, + class_weight=None, + ignore_index=None): + """Calculate the CrossEntropy loss for masks. + + Args: + pred (torch.Tensor): The prediction with shape (N, C), C is the number + of classes. + target (torch.Tensor): The learning label of the prediction. + label (torch.Tensor): ``label`` indicates the class label of the mask' + corresponding object. This will be used to select the mask in the + of the class which the object belongs to when the mask prediction + if not class-agnostic. + reduction (str, optional): The method used to reduce the loss. + Options are "none", "mean" and "sum". + avg_factor (int, optional): Average factor that is used to average + the loss. Defaults to None. + class_weight (list[float], optional): The weight for each class. + ignore_index (None): Placeholder, to be consistent with other loss. + Default: None. + + Returns: + torch.Tensor: The calculated loss + """ + assert ignore_index is None, 'BCE loss does not support ignore_index' + # TODO: handle these two reserved arguments + assert reduction == 'mean' and avg_factor is None + num_rois = pred.size()[0] + inds = torch.arange(0, num_rois, dtype=torch.long, device=pred.device) + pred_slice = pred[inds, label].squeeze(1) + return F.binary_cross_entropy_with_logits( + pred_slice, target, weight=class_weight, reduction='mean')[None] + + +@LOSSES.register_module() +class CrossEntropyLoss(nn.Module): + """CrossEntropyLoss. + + Args: + use_sigmoid (bool, optional): Whether the prediction uses sigmoid + of softmax. Defaults to False. + use_mask (bool, optional): Whether to use mask cross entropy loss. + Defaults to False. + reduction (str, optional): . Defaults to 'mean'. + Options are "none", "mean" and "sum". + class_weight (list[float] | str, optional): Weight of each class. If in + str format, read them from a file. Defaults to None. + loss_weight (float, optional): Weight of the loss. Defaults to 1.0. + """ + + def __init__(self, + use_sigmoid=False, + use_mask=False, + reduction='mean', + class_weight=None, + loss_weight=1.0): + super(CrossEntropyLoss, self).__init__() + assert (use_sigmoid is False) or (use_mask is False) + self.use_sigmoid = use_sigmoid + self.use_mask = use_mask + self.reduction = reduction + self.loss_weight = loss_weight + self.class_weight = get_class_weight(class_weight) + + if self.use_sigmoid: + self.cls_criterion = binary_cross_entropy + elif self.use_mask: + self.cls_criterion = mask_cross_entropy + else: + self.cls_criterion = cross_entropy + + def forward(self, + cls_score, + label, + weight=None, + avg_factor=None, + reduction_override=None, + **kwargs): + """Forward function.""" + assert reduction_override in (None, 'none', 'mean', 'sum') + reduction = ( + reduction_override if reduction_override else self.reduction) + if self.class_weight is not None: + class_weight = cls_score.new_tensor(self.class_weight) + else: + class_weight = None + loss_cls = self.loss_weight * self.cls_criterion( + cls_score, + label, + weight, + class_weight=class_weight, + reduction=reduction, + avg_factor=avg_factor, + **kwargs) + return loss_cls diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/dice_loss.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/dice_loss.py new file mode 100644 index 00000000..27a77b96 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/dice_loss.py @@ -0,0 +1,119 @@ +"""Modified from https://github.com/LikeLy-Journey/SegmenTron/blob/master/ +segmentron/solver/loss.py (Apache-2.0 License)""" +import torch +import torch.nn as nn +import torch.nn.functional as F + +from ..builder import LOSSES +from .utils import get_class_weight, weighted_loss + + +@weighted_loss +def dice_loss(pred, + target, + valid_mask, + smooth=1, + exponent=2, + class_weight=None, + ignore_index=255): + assert pred.shape[0] == target.shape[0] + total_loss = 0 + num_classes = pred.shape[1] + for i in range(num_classes): + if i != ignore_index: + dice_loss = binary_dice_loss( + pred[:, i], + target[..., i], + valid_mask=valid_mask, + smooth=smooth, + exponent=exponent) + if class_weight is not None: + dice_loss *= class_weight[i] + total_loss += dice_loss + return total_loss / num_classes + + +@weighted_loss +def binary_dice_loss(pred, target, valid_mask, smooth=1, exponent=2, **kwards): + assert pred.shape[0] == target.shape[0] + pred = pred.reshape(pred.shape[0], -1) + target = target.reshape(target.shape[0], -1) + valid_mask = valid_mask.reshape(valid_mask.shape[0], -1) + + num = torch.sum(torch.mul(pred, target) * valid_mask, dim=1) * 2 + smooth + den = torch.sum(pred.pow(exponent) + target.pow(exponent), dim=1) + smooth + + return 1 - num / den + + +@LOSSES.register_module() +class DiceLoss(nn.Module): + """DiceLoss. + + This loss is proposed in `V-Net: Fully Convolutional Neural Networks for + Volumetric Medical Image Segmentation `_. + + Args: + loss_type (str, optional): Binary or multi-class loss. + Default: 'multi_class'. Options are "binary" and "multi_class". + smooth (float): A float number to smooth loss, and avoid NaN error. + Default: 1 + exponent (float): An float number to calculate denominator + value: \\sum{x^exponent} + \\sum{y^exponent}. Default: 2. + reduction (str, optional): The method used to reduce the loss. Options + are "none", "mean" and "sum". This parameter only works when + per_image is True. Default: 'mean'. + class_weight (list[float] | str, optional): Weight of each class. If in + str format, read them from a file. Defaults to None. + loss_weight (float, optional): Weight of the loss. Default to 1.0. + ignore_index (int | None): The label index to be ignored. Default: 255. + """ + + def __init__(self, + smooth=1, + exponent=2, + reduction='mean', + class_weight=None, + loss_weight=1.0, + ignore_index=255, + **kwards): + super(DiceLoss, self).__init__() + self.smooth = smooth + self.exponent = exponent + self.reduction = reduction + self.class_weight = get_class_weight(class_weight) + self.loss_weight = loss_weight + self.ignore_index = ignore_index + + def forward(self, + pred, + target, + avg_factor=None, + reduction_override=None, + **kwards): + assert reduction_override in (None, 'none', 'mean', 'sum') + reduction = ( + reduction_override if reduction_override else self.reduction) + if self.class_weight is not None: + class_weight = pred.new_tensor(self.class_weight) + else: + class_weight = None + + pred = F.softmax(pred, dim=1) + num_classes = pred.shape[1] + one_hot_target = F.one_hot( + torch.clamp(target.long(), 0, num_classes - 1), + num_classes=num_classes) + valid_mask = (target != self.ignore_index).long() + + loss = self.loss_weight * dice_loss( + pred, + one_hot_target, + valid_mask=valid_mask, + reduction=reduction, + avg_factor=avg_factor, + smooth=self.smooth, + exponent=self.exponent, + class_weight=class_weight, + ignore_index=self.ignore_index) + return loss diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/lovasz_loss.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/lovasz_loss.py new file mode 100644 index 00000000..50f0f70f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/lovasz_loss.py @@ -0,0 +1,303 @@ +"""Modified from https://github.com/bermanmaxim/LovaszSoftmax/blob/master/pytor +ch/lovasz_losses.py Lovasz-Softmax and Jaccard hinge loss in PyTorch Maxim +Berman 2018 ESAT-PSI KU Leuven (MIT License)""" + +import annotator.mmpkg.mmcv as mmcv +import torch +import torch.nn as nn +import torch.nn.functional as F + +from ..builder import LOSSES +from .utils import get_class_weight, weight_reduce_loss + + +def lovasz_grad(gt_sorted): + """Computes gradient of the Lovasz extension w.r.t sorted errors. + + See Alg. 1 in paper. + """ + p = len(gt_sorted) + gts = gt_sorted.sum() + intersection = gts - gt_sorted.float().cumsum(0) + union = gts + (1 - gt_sorted).float().cumsum(0) + jaccard = 1. - intersection / union + if p > 1: # cover 1-pixel case + jaccard[1:p] = jaccard[1:p] - jaccard[0:-1] + return jaccard + + +def flatten_binary_logits(logits, labels, ignore_index=None): + """Flattens predictions in the batch (binary case) Remove labels equal to + 'ignore_index'.""" + logits = logits.view(-1) + labels = labels.view(-1) + if ignore_index is None: + return logits, labels + valid = (labels != ignore_index) + vlogits = logits[valid] + vlabels = labels[valid] + return vlogits, vlabels + + +def flatten_probs(probs, labels, ignore_index=None): + """Flattens predictions in the batch.""" + if probs.dim() == 3: + # assumes output of a sigmoid layer + B, H, W = probs.size() + probs = probs.view(B, 1, H, W) + B, C, H, W = probs.size() + probs = probs.permute(0, 2, 3, 1).contiguous().view(-1, C) # B*H*W, C=P,C + labels = labels.view(-1) + if ignore_index is None: + return probs, labels + valid = (labels != ignore_index) + vprobs = probs[valid.nonzero().squeeze()] + vlabels = labels[valid] + return vprobs, vlabels + + +def lovasz_hinge_flat(logits, labels): + """Binary Lovasz hinge loss. + + Args: + logits (torch.Tensor): [P], logits at each prediction + (between -infty and +infty). + labels (torch.Tensor): [P], binary ground truth labels (0 or 1). + + Returns: + torch.Tensor: The calculated loss. + """ + if len(labels) == 0: + # only void pixels, the gradients should be 0 + return logits.sum() * 0. + signs = 2. * labels.float() - 1. + errors = (1. - logits * signs) + errors_sorted, perm = torch.sort(errors, dim=0, descending=True) + perm = perm.data + gt_sorted = labels[perm] + grad = lovasz_grad(gt_sorted) + loss = torch.dot(F.relu(errors_sorted), grad) + return loss + + +def lovasz_hinge(logits, + labels, + classes='present', + per_image=False, + class_weight=None, + reduction='mean', + avg_factor=None, + ignore_index=255): + """Binary Lovasz hinge loss. + + Args: + logits (torch.Tensor): [B, H, W], logits at each pixel + (between -infty and +infty). + labels (torch.Tensor): [B, H, W], binary ground truth masks (0 or 1). + classes (str | list[int], optional): Placeholder, to be consistent with + other loss. Default: None. + per_image (bool, optional): If per_image is True, compute the loss per + image instead of per batch. Default: False. + class_weight (list[float], optional): Placeholder, to be consistent + with other loss. Default: None. + reduction (str, optional): The method used to reduce the loss. Options + are "none", "mean" and "sum". This parameter only works when + per_image is True. Default: 'mean'. + avg_factor (int, optional): Average factor that is used to average + the loss. This parameter only works when per_image is True. + Default: None. + ignore_index (int | None): The label index to be ignored. Default: 255. + + Returns: + torch.Tensor: The calculated loss. + """ + if per_image: + loss = [ + lovasz_hinge_flat(*flatten_binary_logits( + logit.unsqueeze(0), label.unsqueeze(0), ignore_index)) + for logit, label in zip(logits, labels) + ] + loss = weight_reduce_loss( + torch.stack(loss), None, reduction, avg_factor) + else: + loss = lovasz_hinge_flat( + *flatten_binary_logits(logits, labels, ignore_index)) + return loss + + +def lovasz_softmax_flat(probs, labels, classes='present', class_weight=None): + """Multi-class Lovasz-Softmax loss. + + Args: + probs (torch.Tensor): [P, C], class probabilities at each prediction + (between 0 and 1). + labels (torch.Tensor): [P], ground truth labels (between 0 and C - 1). + classes (str | list[int], optional): Classes chosen to calculate loss. + 'all' for all classes, 'present' for classes present in labels, or + a list of classes to average. Default: 'present'. + class_weight (list[float], optional): The weight for each class. + Default: None. + + Returns: + torch.Tensor: The calculated loss. + """ + if probs.numel() == 0: + # only void pixels, the gradients should be 0 + return probs * 0. + C = probs.size(1) + losses = [] + class_to_sum = list(range(C)) if classes in ['all', 'present'] else classes + for c in class_to_sum: + fg = (labels == c).float() # foreground for class c + if (classes == 'present' and fg.sum() == 0): + continue + if C == 1: + if len(classes) > 1: + raise ValueError('Sigmoid output possible only with 1 class') + class_pred = probs[:, 0] + else: + class_pred = probs[:, c] + errors = (fg - class_pred).abs() + errors_sorted, perm = torch.sort(errors, 0, descending=True) + perm = perm.data + fg_sorted = fg[perm] + loss = torch.dot(errors_sorted, lovasz_grad(fg_sorted)) + if class_weight is not None: + loss *= class_weight[c] + losses.append(loss) + return torch.stack(losses).mean() + + +def lovasz_softmax(probs, + labels, + classes='present', + per_image=False, + class_weight=None, + reduction='mean', + avg_factor=None, + ignore_index=255): + """Multi-class Lovasz-Softmax loss. + + Args: + probs (torch.Tensor): [B, C, H, W], class probabilities at each + prediction (between 0 and 1). + labels (torch.Tensor): [B, H, W], ground truth labels (between 0 and + C - 1). + classes (str | list[int], optional): Classes chosen to calculate loss. + 'all' for all classes, 'present' for classes present in labels, or + a list of classes to average. Default: 'present'. + per_image (bool, optional): If per_image is True, compute the loss per + image instead of per batch. Default: False. + class_weight (list[float], optional): The weight for each class. + Default: None. + reduction (str, optional): The method used to reduce the loss. Options + are "none", "mean" and "sum". This parameter only works when + per_image is True. Default: 'mean'. + avg_factor (int, optional): Average factor that is used to average + the loss. This parameter only works when per_image is True. + Default: None. + ignore_index (int | None): The label index to be ignored. Default: 255. + + Returns: + torch.Tensor: The calculated loss. + """ + + if per_image: + loss = [ + lovasz_softmax_flat( + *flatten_probs( + prob.unsqueeze(0), label.unsqueeze(0), ignore_index), + classes=classes, + class_weight=class_weight) + for prob, label in zip(probs, labels) + ] + loss = weight_reduce_loss( + torch.stack(loss), None, reduction, avg_factor) + else: + loss = lovasz_softmax_flat( + *flatten_probs(probs, labels, ignore_index), + classes=classes, + class_weight=class_weight) + return loss + + +@LOSSES.register_module() +class LovaszLoss(nn.Module): + """LovaszLoss. + + This loss is proposed in `The Lovasz-Softmax loss: A tractable surrogate + for the optimization of the intersection-over-union measure in neural + networks `_. + + Args: + loss_type (str, optional): Binary or multi-class loss. + Default: 'multi_class'. Options are "binary" and "multi_class". + classes (str | list[int], optional): Classes chosen to calculate loss. + 'all' for all classes, 'present' for classes present in labels, or + a list of classes to average. Default: 'present'. + per_image (bool, optional): If per_image is True, compute the loss per + image instead of per batch. Default: False. + reduction (str, optional): The method used to reduce the loss. Options + are "none", "mean" and "sum". This parameter only works when + per_image is True. Default: 'mean'. + class_weight (list[float] | str, optional): Weight of each class. If in + str format, read them from a file. Defaults to None. + loss_weight (float, optional): Weight of the loss. Defaults to 1.0. + """ + + def __init__(self, + loss_type='multi_class', + classes='present', + per_image=False, + reduction='mean', + class_weight=None, + loss_weight=1.0): + super(LovaszLoss, self).__init__() + assert loss_type in ('binary', 'multi_class'), "loss_type should be \ + 'binary' or 'multi_class'." + + if loss_type == 'binary': + self.cls_criterion = lovasz_hinge + else: + self.cls_criterion = lovasz_softmax + assert classes in ('all', 'present') or mmcv.is_list_of(classes, int) + if not per_image: + assert reduction == 'none', "reduction should be 'none' when \ + per_image is False." + + self.classes = classes + self.per_image = per_image + self.reduction = reduction + self.loss_weight = loss_weight + self.class_weight = get_class_weight(class_weight) + + def forward(self, + cls_score, + label, + weight=None, + avg_factor=None, + reduction_override=None, + **kwargs): + """Forward function.""" + assert reduction_override in (None, 'none', 'mean', 'sum') + reduction = ( + reduction_override if reduction_override else self.reduction) + if self.class_weight is not None: + class_weight = cls_score.new_tensor(self.class_weight) + else: + class_weight = None + + # if multi-class loss, transform logits to probs + if self.cls_criterion == lovasz_softmax: + cls_score = F.softmax(cls_score, dim=1) + + loss_cls = self.loss_weight * self.cls_criterion( + cls_score, + label, + self.classes, + self.per_image, + class_weight=class_weight, + reduction=reduction, + avg_factor=avg_factor, + **kwargs) + return loss_cls diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/utils.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/utils.py new file mode 100644 index 00000000..2afb477a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/losses/utils.py @@ -0,0 +1,121 @@ +import functools + +import annotator.mmpkg.mmcv as mmcv +import numpy as np +import torch.nn.functional as F + + +def get_class_weight(class_weight): + """Get class weight for loss function. + + Args: + class_weight (list[float] | str | None): If class_weight is a str, + take it as a file name and read from it. + """ + if isinstance(class_weight, str): + # take it as a file path + if class_weight.endswith('.npy'): + class_weight = np.load(class_weight) + else: + # pkl, json or yaml + class_weight = mmcv.load(class_weight) + + return class_weight + + +def reduce_loss(loss, reduction): + """Reduce loss as specified. + + Args: + loss (Tensor): Elementwise loss tensor. + reduction (str): Options are "none", "mean" and "sum". + + Return: + Tensor: Reduced loss tensor. + """ + reduction_enum = F._Reduction.get_enum(reduction) + # none: 0, elementwise_mean:1, sum: 2 + if reduction_enum == 0: + return loss + elif reduction_enum == 1: + return loss.mean() + elif reduction_enum == 2: + return loss.sum() + + +def weight_reduce_loss(loss, weight=None, reduction='mean', avg_factor=None): + """Apply element-wise weight and reduce loss. + + Args: + loss (Tensor): Element-wise loss. + weight (Tensor): Element-wise weights. + reduction (str): Same as built-in losses of PyTorch. + avg_factor (float): Avarage factor when computing the mean of losses. + + Returns: + Tensor: Processed loss values. + """ + # if weight is specified, apply element-wise weight + if weight is not None: + assert weight.dim() == loss.dim() + if weight.dim() > 1: + assert weight.size(1) == 1 or weight.size(1) == loss.size(1) + loss = loss * weight + + # if avg_factor is not specified, just reduce the loss + if avg_factor is None: + loss = reduce_loss(loss, reduction) + else: + # if reduction is mean, then average the loss by avg_factor + if reduction == 'mean': + loss = loss.sum() / avg_factor + # if reduction is 'none', then do nothing, otherwise raise an error + elif reduction != 'none': + raise ValueError('avg_factor can not be used with reduction="sum"') + return loss + + +def weighted_loss(loss_func): + """Create a weighted version of a given loss function. + + To use this decorator, the loss function must have the signature like + `loss_func(pred, target, **kwargs)`. The function only needs to compute + element-wise loss without any reduction. This decorator will add weight + and reduction arguments to the function. The decorated function will have + the signature like `loss_func(pred, target, weight=None, reduction='mean', + avg_factor=None, **kwargs)`. + + :Example: + + >>> import torch + >>> @weighted_loss + >>> def l1_loss(pred, target): + >>> return (pred - target).abs() + + >>> pred = torch.Tensor([0, 2, 3]) + >>> target = torch.Tensor([1, 1, 1]) + >>> weight = torch.Tensor([1, 0, 1]) + + >>> l1_loss(pred, target) + tensor(1.3333) + >>> l1_loss(pred, target, weight) + tensor(1.) + >>> l1_loss(pred, target, reduction='none') + tensor([1., 1., 2.]) + >>> l1_loss(pred, target, weight, avg_factor=2) + tensor(1.5000) + """ + + @functools.wraps(loss_func) + def wrapper(pred, + target, + weight=None, + reduction='mean', + avg_factor=None, + **kwargs): + # get element-wise loss + loss = loss_func(pred, target, **kwargs) + loss = weight_reduce_loss(loss, weight, reduction, avg_factor) + return loss + + return wrapper diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/necks/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/necks/__init__.py new file mode 100644 index 00000000..9b9d3d5b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/necks/__init__.py @@ -0,0 +1,4 @@ +from .fpn import FPN +from .multilevel_neck import MultiLevelNeck + +__all__ = ['FPN', 'MultiLevelNeck'] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/necks/fpn.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/necks/fpn.py new file mode 100644 index 00000000..ba47bbe1 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/necks/fpn.py @@ -0,0 +1,212 @@ +import torch.nn as nn +import torch.nn.functional as F +from annotator.mmpkg.mmcv.cnn import ConvModule, xavier_init + +from ..builder import NECKS + + +@NECKS.register_module() +class FPN(nn.Module): + """Feature Pyramid Network. + + This is an implementation of - Feature Pyramid Networks for Object + Detection (https://arxiv.org/abs/1612.03144) + + Args: + in_channels (List[int]): Number of input channels per scale. + out_channels (int): Number of output channels (used at each scale) + num_outs (int): Number of output scales. + start_level (int): Index of the start input backbone level used to + build the feature pyramid. Default: 0. + end_level (int): Index of the end input backbone level (exclusive) to + build the feature pyramid. Default: -1, which means the last level. + add_extra_convs (bool | str): If bool, it decides whether to add conv + layers on top of the original feature maps. Default to False. + If True, its actual mode is specified by `extra_convs_on_inputs`. + If str, it specifies the source feature map of the extra convs. + Only the following options are allowed + + - 'on_input': Last feat map of neck inputs (i.e. backbone feature). + - 'on_lateral': Last feature map after lateral convs. + - 'on_output': The last output feature map after fpn convs. + extra_convs_on_inputs (bool, deprecated): Whether to apply extra convs + on the original feature from the backbone. If True, + it is equivalent to `add_extra_convs='on_input'`. If False, it is + equivalent to set `add_extra_convs='on_output'`. Default to True. + relu_before_extra_convs (bool): Whether to apply relu before the extra + conv. Default: False. + no_norm_on_lateral (bool): Whether to apply norm on lateral. + Default: False. + conv_cfg (dict): Config dict for convolution layer. Default: None. + norm_cfg (dict): Config dict for normalization layer. Default: None. + act_cfg (str): Config dict for activation layer in ConvModule. + Default: None. + upsample_cfg (dict): Config dict for interpolate layer. + Default: `dict(mode='nearest')` + + Example: + >>> import torch + >>> in_channels = [2, 3, 5, 7] + >>> scales = [340, 170, 84, 43] + >>> inputs = [torch.rand(1, c, s, s) + ... for c, s in zip(in_channels, scales)] + >>> self = FPN(in_channels, 11, len(in_channels)).eval() + >>> outputs = self.forward(inputs) + >>> for i in range(len(outputs)): + ... print(f'outputs[{i}].shape = {outputs[i].shape}') + outputs[0].shape = torch.Size([1, 11, 340, 340]) + outputs[1].shape = torch.Size([1, 11, 170, 170]) + outputs[2].shape = torch.Size([1, 11, 84, 84]) + outputs[3].shape = torch.Size([1, 11, 43, 43]) + """ + + def __init__(self, + in_channels, + out_channels, + num_outs, + start_level=0, + end_level=-1, + add_extra_convs=False, + extra_convs_on_inputs=False, + relu_before_extra_convs=False, + no_norm_on_lateral=False, + conv_cfg=None, + norm_cfg=None, + act_cfg=None, + upsample_cfg=dict(mode='nearest')): + super(FPN, self).__init__() + assert isinstance(in_channels, list) + self.in_channels = in_channels + self.out_channels = out_channels + self.num_ins = len(in_channels) + self.num_outs = num_outs + self.relu_before_extra_convs = relu_before_extra_convs + self.no_norm_on_lateral = no_norm_on_lateral + self.fp16_enabled = False + self.upsample_cfg = upsample_cfg.copy() + + if end_level == -1: + self.backbone_end_level = self.num_ins + assert num_outs >= self.num_ins - start_level + else: + # if end_level < inputs, no extra level is allowed + self.backbone_end_level = end_level + assert end_level <= len(in_channels) + assert num_outs == end_level - start_level + self.start_level = start_level + self.end_level = end_level + self.add_extra_convs = add_extra_convs + assert isinstance(add_extra_convs, (str, bool)) + if isinstance(add_extra_convs, str): + # Extra_convs_source choices: 'on_input', 'on_lateral', 'on_output' + assert add_extra_convs in ('on_input', 'on_lateral', 'on_output') + elif add_extra_convs: # True + if extra_convs_on_inputs: + # For compatibility with previous release + # TODO: deprecate `extra_convs_on_inputs` + self.add_extra_convs = 'on_input' + else: + self.add_extra_convs = 'on_output' + + self.lateral_convs = nn.ModuleList() + self.fpn_convs = nn.ModuleList() + + for i in range(self.start_level, self.backbone_end_level): + l_conv = ConvModule( + in_channels[i], + out_channels, + 1, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg if not self.no_norm_on_lateral else None, + act_cfg=act_cfg, + inplace=False) + fpn_conv = ConvModule( + out_channels, + out_channels, + 3, + padding=1, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg, + inplace=False) + + self.lateral_convs.append(l_conv) + self.fpn_convs.append(fpn_conv) + + # add extra conv layers (e.g., RetinaNet) + extra_levels = num_outs - self.backbone_end_level + self.start_level + if self.add_extra_convs and extra_levels >= 1: + for i in range(extra_levels): + if i == 0 and self.add_extra_convs == 'on_input': + in_channels = self.in_channels[self.backbone_end_level - 1] + else: + in_channels = out_channels + extra_fpn_conv = ConvModule( + in_channels, + out_channels, + 3, + stride=2, + padding=1, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg, + inplace=False) + self.fpn_convs.append(extra_fpn_conv) + + # default init_weights for conv(msra) and norm in ConvModule + def init_weights(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + xavier_init(m, distribution='uniform') + + def forward(self, inputs): + assert len(inputs) == len(self.in_channels) + + # build laterals + laterals = [ + lateral_conv(inputs[i + self.start_level]) + for i, lateral_conv in enumerate(self.lateral_convs) + ] + + # build top-down path + used_backbone_levels = len(laterals) + for i in range(used_backbone_levels - 1, 0, -1): + # In some cases, fixing `scale factor` (e.g. 2) is preferred, but + # it cannot co-exist with `size` in `F.interpolate`. + if 'scale_factor' in self.upsample_cfg: + laterals[i - 1] += F.interpolate(laterals[i], + **self.upsample_cfg) + else: + prev_shape = laterals[i - 1].shape[2:] + laterals[i - 1] += F.interpolate( + laterals[i], size=prev_shape, **self.upsample_cfg) + + # build outputs + # part 1: from original levels + outs = [ + self.fpn_convs[i](laterals[i]) for i in range(used_backbone_levels) + ] + # part 2: add extra levels + if self.num_outs > len(outs): + # use max pool to get more levels on top of outputs + # (e.g., Faster R-CNN, Mask R-CNN) + if not self.add_extra_convs: + for i in range(self.num_outs - used_backbone_levels): + outs.append(F.max_pool2d(outs[-1], 1, stride=2)) + # add conv layers on top of original feature maps (RetinaNet) + else: + if self.add_extra_convs == 'on_input': + extra_source = inputs[self.backbone_end_level - 1] + elif self.add_extra_convs == 'on_lateral': + extra_source = laterals[-1] + elif self.add_extra_convs == 'on_output': + extra_source = outs[-1] + else: + raise NotImplementedError + outs.append(self.fpn_convs[used_backbone_levels](extra_source)) + for i in range(used_backbone_levels + 1, self.num_outs): + if self.relu_before_extra_convs: + outs.append(self.fpn_convs[i](F.relu(outs[-1]))) + else: + outs.append(self.fpn_convs[i](outs[-1])) + return tuple(outs) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/necks/multilevel_neck.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/necks/multilevel_neck.py new file mode 100644 index 00000000..0b86c073 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/necks/multilevel_neck.py @@ -0,0 +1,70 @@ +import torch.nn as nn +import torch.nn.functional as F +from annotator.mmpkg.mmcv.cnn import ConvModule + +from ..builder import NECKS + + +@NECKS.register_module() +class MultiLevelNeck(nn.Module): + """MultiLevelNeck. + + A neck structure connect vit backbone and decoder_heads. + Args: + in_channels (List[int]): Number of input channels per scale. + out_channels (int): Number of output channels (used at each scale). + scales (List[int]): Scale factors for each input feature map. + norm_cfg (dict): Config dict for normalization layer. Default: None. + act_cfg (dict): Config dict for activation layer in ConvModule. + Default: None. + """ + + def __init__(self, + in_channels, + out_channels, + scales=[0.5, 1, 2, 4], + norm_cfg=None, + act_cfg=None): + super(MultiLevelNeck, self).__init__() + assert isinstance(in_channels, list) + self.in_channels = in_channels + self.out_channels = out_channels + self.scales = scales + self.num_outs = len(scales) + self.lateral_convs = nn.ModuleList() + self.convs = nn.ModuleList() + for in_channel in in_channels: + self.lateral_convs.append( + ConvModule( + in_channel, + out_channels, + kernel_size=1, + norm_cfg=norm_cfg, + act_cfg=act_cfg)) + for _ in range(self.num_outs): + self.convs.append( + ConvModule( + out_channels, + out_channels, + kernel_size=3, + padding=1, + stride=1, + norm_cfg=norm_cfg, + act_cfg=act_cfg)) + + def forward(self, inputs): + assert len(inputs) == len(self.in_channels) + print(inputs[0].shape) + inputs = [ + lateral_conv(inputs[i]) + for i, lateral_conv in enumerate(self.lateral_convs) + ] + # for len(inputs) not equal to self.num_outs + if len(inputs) == 1: + inputs = [inputs[0] for _ in range(self.num_outs)] + outs = [] + for i in range(self.num_outs): + x_resize = F.interpolate( + inputs[i], scale_factor=self.scales[i], mode='bilinear') + outs.append(self.convs[i](x_resize)) + return tuple(outs) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/segmentors/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/segmentors/__init__.py new file mode 100644 index 00000000..dca2f094 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/segmentors/__init__.py @@ -0,0 +1,5 @@ +from .base import BaseSegmentor +from .cascade_encoder_decoder import CascadeEncoderDecoder +from .encoder_decoder import EncoderDecoder + +__all__ = ['BaseSegmentor', 'EncoderDecoder', 'CascadeEncoderDecoder'] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/segmentors/base.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/segmentors/base.py new file mode 100644 index 00000000..a12d8beb --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/segmentors/base.py @@ -0,0 +1,273 @@ +import logging +import warnings +from abc import ABCMeta, abstractmethod +from collections import OrderedDict + +import annotator.mmpkg.mmcv as mmcv +import numpy as np +import torch +import torch.distributed as dist +import torch.nn as nn +from annotator.mmpkg.mmcv.runner import auto_fp16 + + +class BaseSegmentor(nn.Module): + """Base class for segmentors.""" + + __metaclass__ = ABCMeta + + def __init__(self): + super(BaseSegmentor, self).__init__() + self.fp16_enabled = False + + @property + def with_neck(self): + """bool: whether the segmentor has neck""" + return hasattr(self, 'neck') and self.neck is not None + + @property + def with_auxiliary_head(self): + """bool: whether the segmentor has auxiliary head""" + return hasattr(self, + 'auxiliary_head') and self.auxiliary_head is not None + + @property + def with_decode_head(self): + """bool: whether the segmentor has decode head""" + return hasattr(self, 'decode_head') and self.decode_head is not None + + @abstractmethod + def extract_feat(self, imgs): + """Placeholder for extract features from images.""" + pass + + @abstractmethod + def encode_decode(self, img, img_metas): + """Placeholder for encode images with backbone and decode into a + semantic segmentation map of the same size as input.""" + pass + + @abstractmethod + def forward_train(self, imgs, img_metas, **kwargs): + """Placeholder for Forward function for training.""" + pass + + @abstractmethod + def simple_test(self, img, img_meta, **kwargs): + """Placeholder for single image test.""" + pass + + @abstractmethod + def aug_test(self, imgs, img_metas, **kwargs): + """Placeholder for augmentation test.""" + pass + + def init_weights(self, pretrained=None): + """Initialize the weights in segmentor. + + Args: + pretrained (str, optional): Path to pre-trained weights. + Defaults to None. + """ + if pretrained is not None: + logger = logging.getLogger() + logger.info(f'load model from: {pretrained}') + + def forward_test(self, imgs, img_metas, **kwargs): + """ + Args: + imgs (List[Tensor]): the outer list indicates test-time + augmentations and inner Tensor should have a shape NxCxHxW, + which contains all images in the batch. + img_metas (List[List[dict]]): the outer list indicates test-time + augs (multiscale, flip, etc.) and the inner list indicates + images in a batch. + """ + for var, name in [(imgs, 'imgs'), (img_metas, 'img_metas')]: + if not isinstance(var, list): + raise TypeError(f'{name} must be a list, but got ' + f'{type(var)}') + + num_augs = len(imgs) + if num_augs != len(img_metas): + raise ValueError(f'num of augmentations ({len(imgs)}) != ' + f'num of image meta ({len(img_metas)})') + # all images in the same aug batch all of the same ori_shape and pad + # shape + for img_meta in img_metas: + ori_shapes = [_['ori_shape'] for _ in img_meta] + assert all(shape == ori_shapes[0] for shape in ori_shapes) + img_shapes = [_['img_shape'] for _ in img_meta] + assert all(shape == img_shapes[0] for shape in img_shapes) + pad_shapes = [_['pad_shape'] for _ in img_meta] + assert all(shape == pad_shapes[0] for shape in pad_shapes) + + if num_augs == 1: + return self.simple_test(imgs[0], img_metas[0], **kwargs) + else: + return self.aug_test(imgs, img_metas, **kwargs) + + @auto_fp16(apply_to=('img', )) + def forward(self, img, img_metas, return_loss=True, **kwargs): + """Calls either :func:`forward_train` or :func:`forward_test` depending + on whether ``return_loss`` is ``True``. + + Note this setting will change the expected inputs. When + ``return_loss=True``, img and img_meta are single-nested (i.e. Tensor + and List[dict]), and when ``resturn_loss=False``, img and img_meta + should be double nested (i.e. List[Tensor], List[List[dict]]), with + the outer list indicating test time augmentations. + """ + if return_loss: + return self.forward_train(img, img_metas, **kwargs) + else: + return self.forward_test(img, img_metas, **kwargs) + + def train_step(self, data_batch, optimizer, **kwargs): + """The iteration step during training. + + This method defines an iteration step during training, except for the + back propagation and optimizer updating, which are done in an optimizer + hook. Note that in some complicated cases or models, the whole process + including back propagation and optimizer updating is also defined in + this method, such as GAN. + + Args: + data (dict): The output of dataloader. + optimizer (:obj:`torch.optim.Optimizer` | dict): The optimizer of + runner is passed to ``train_step()``. This argument is unused + and reserved. + + Returns: + dict: It should contain at least 3 keys: ``loss``, ``log_vars``, + ``num_samples``. + ``loss`` is a tensor for back propagation, which can be a + weighted sum of multiple losses. + ``log_vars`` contains all the variables to be sent to the + logger. + ``num_samples`` indicates the batch size (when the model is + DDP, it means the batch size on each GPU), which is used for + averaging the logs. + """ + losses = self(**data_batch) + loss, log_vars = self._parse_losses(losses) + + outputs = dict( + loss=loss, + log_vars=log_vars, + num_samples=len(data_batch['img_metas'])) + + return outputs + + def val_step(self, data_batch, **kwargs): + """The iteration step during validation. + + This method shares the same signature as :func:`train_step`, but used + during val epochs. Note that the evaluation after training epochs is + not implemented with this method, but an evaluation hook. + """ + output = self(**data_batch, **kwargs) + return output + + @staticmethod + def _parse_losses(losses): + """Parse the raw outputs (losses) of the network. + + Args: + losses (dict): Raw output of the network, which usually contain + losses and other necessary information. + + Returns: + tuple[Tensor, dict]: (loss, log_vars), loss is the loss tensor + which may be a weighted sum of all losses, log_vars contains + all the variables to be sent to the logger. + """ + log_vars = OrderedDict() + for loss_name, loss_value in losses.items(): + if isinstance(loss_value, torch.Tensor): + log_vars[loss_name] = loss_value.mean() + elif isinstance(loss_value, list): + log_vars[loss_name] = sum(_loss.mean() for _loss in loss_value) + else: + raise TypeError( + f'{loss_name} is not a tensor or list of tensors') + + loss = sum(_value for _key, _value in log_vars.items() + if 'loss' in _key) + + log_vars['loss'] = loss + for loss_name, loss_value in log_vars.items(): + # reduce loss when distributed training + if dist.is_available() and dist.is_initialized(): + loss_value = loss_value.data.clone() + dist.all_reduce(loss_value.div_(dist.get_world_size())) + log_vars[loss_name] = loss_value.item() + + return loss, log_vars + + def show_result(self, + img, + result, + palette=None, + win_name='', + show=False, + wait_time=0, + out_file=None, + opacity=0.5): + """Draw `result` over `img`. + + Args: + img (str or Tensor): The image to be displayed. + result (Tensor): The semantic segmentation results to draw over + `img`. + palette (list[list[int]]] | np.ndarray | None): The palette of + segmentation map. If None is given, random palette will be + generated. Default: None + win_name (str): The window name. + wait_time (int): Value of waitKey param. + Default: 0. + show (bool): Whether to show the image. + Default: False. + out_file (str or None): The filename to write the image. + Default: None. + opacity(float): Opacity of painted segmentation map. + Default 0.5. + Must be in (0, 1] range. + Returns: + img (Tensor): Only if not `show` or `out_file` + """ + img = mmcv.imread(img) + img = img.copy() + seg = result[0] + if palette is None: + if self.PALETTE is None: + palette = np.random.randint( + 0, 255, size=(len(self.CLASSES), 3)) + else: + palette = self.PALETTE + palette = np.array(palette) + assert palette.shape[0] == len(self.CLASSES) + assert palette.shape[1] == 3 + assert len(palette.shape) == 2 + assert 0 < opacity <= 1.0 + color_seg = np.zeros((seg.shape[0], seg.shape[1], 3), dtype=np.uint8) + for label, color in enumerate(palette): + color_seg[seg == label, :] = color + # convert to BGR + color_seg = color_seg[..., ::-1] + + img = img * (1 - opacity) + color_seg * opacity + img = img.astype(np.uint8) + # if out_file specified, do not show image in window + if out_file is not None: + show = False + + if show: + mmcv.imshow(img, win_name, wait_time) + if out_file is not None: + mmcv.imwrite(img, out_file) + + if not (show or out_file): + warnings.warn('show==False and out_file is not specified, only ' + 'result image will be returned') + return img diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/segmentors/cascade_encoder_decoder.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/segmentors/cascade_encoder_decoder.py new file mode 100644 index 00000000..74547f0f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/segmentors/cascade_encoder_decoder.py @@ -0,0 +1,98 @@ +from torch import nn + +from annotator.mmpkg.mmseg.core import add_prefix +from annotator.mmpkg.mmseg.ops import resize +from .. import builder +from ..builder import SEGMENTORS +from .encoder_decoder import EncoderDecoder + + +@SEGMENTORS.register_module() +class CascadeEncoderDecoder(EncoderDecoder): + """Cascade Encoder Decoder segmentors. + + CascadeEncoderDecoder almost the same as EncoderDecoder, while decoders of + CascadeEncoderDecoder are cascaded. The output of previous decoder_head + will be the input of next decoder_head. + """ + + def __init__(self, + num_stages, + backbone, + decode_head, + neck=None, + auxiliary_head=None, + train_cfg=None, + test_cfg=None, + pretrained=None): + self.num_stages = num_stages + super(CascadeEncoderDecoder, self).__init__( + backbone=backbone, + decode_head=decode_head, + neck=neck, + auxiliary_head=auxiliary_head, + train_cfg=train_cfg, + test_cfg=test_cfg, + pretrained=pretrained) + + def _init_decode_head(self, decode_head): + """Initialize ``decode_head``""" + assert isinstance(decode_head, list) + assert len(decode_head) == self.num_stages + self.decode_head = nn.ModuleList() + for i in range(self.num_stages): + self.decode_head.append(builder.build_head(decode_head[i])) + self.align_corners = self.decode_head[-1].align_corners + self.num_classes = self.decode_head[-1].num_classes + + def init_weights(self, pretrained=None): + """Initialize the weights in backbone and heads. + + Args: + pretrained (str, optional): Path to pre-trained weights. + Defaults to None. + """ + self.backbone.init_weights(pretrained=pretrained) + for i in range(self.num_stages): + self.decode_head[i].init_weights() + if self.with_auxiliary_head: + if isinstance(self.auxiliary_head, nn.ModuleList): + for aux_head in self.auxiliary_head: + aux_head.init_weights() + else: + self.auxiliary_head.init_weights() + + def encode_decode(self, img, img_metas): + """Encode images with backbone and decode into a semantic segmentation + map of the same size as input.""" + x = self.extract_feat(img) + out = self.decode_head[0].forward_test(x, img_metas, self.test_cfg) + for i in range(1, self.num_stages): + out = self.decode_head[i].forward_test(x, out, img_metas, + self.test_cfg) + out = resize( + input=out, + size=img.shape[2:], + mode='bilinear', + align_corners=self.align_corners) + return out + + def _decode_head_forward_train(self, x, img_metas, gt_semantic_seg): + """Run forward function and calculate loss for decode head in + training.""" + losses = dict() + + loss_decode = self.decode_head[0].forward_train( + x, img_metas, gt_semantic_seg, self.train_cfg) + + losses.update(add_prefix(loss_decode, 'decode_0')) + + for i in range(1, self.num_stages): + # forward test again, maybe unnecessary for most methods. + prev_outputs = self.decode_head[i - 1].forward_test( + x, img_metas, self.test_cfg) + loss_decode = self.decode_head[i].forward_train( + x, prev_outputs, img_metas, gt_semantic_seg, self.train_cfg) + losses.update(add_prefix(loss_decode, f'decode_{i}')) + + return losses diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/segmentors/encoder_decoder.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/segmentors/encoder_decoder.py new file mode 100644 index 00000000..30c25f35 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/segmentors/encoder_decoder.py @@ -0,0 +1,298 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F + +from annotator.mmpkg.mmseg.core import add_prefix +from annotator.mmpkg.mmseg.ops import resize +from .. import builder +from ..builder import SEGMENTORS +from .base import BaseSegmentor + + +@SEGMENTORS.register_module() +class EncoderDecoder(BaseSegmentor): + """Encoder Decoder segmentors. + + EncoderDecoder typically consists of backbone, decode_head, auxiliary_head. + Note that auxiliary_head is only used for deep supervision during training, + which could be dumped during inference. + """ + + def __init__(self, + backbone, + decode_head, + neck=None, + auxiliary_head=None, + train_cfg=None, + test_cfg=None, + pretrained=None): + super(EncoderDecoder, self).__init__() + self.backbone = builder.build_backbone(backbone) + if neck is not None: + self.neck = builder.build_neck(neck) + self._init_decode_head(decode_head) + self._init_auxiliary_head(auxiliary_head) + + self.train_cfg = train_cfg + self.test_cfg = test_cfg + + self.init_weights(pretrained=pretrained) + + assert self.with_decode_head + + def _init_decode_head(self, decode_head): + """Initialize ``decode_head``""" + self.decode_head = builder.build_head(decode_head) + self.align_corners = self.decode_head.align_corners + self.num_classes = self.decode_head.num_classes + + def _init_auxiliary_head(self, auxiliary_head): + """Initialize ``auxiliary_head``""" + if auxiliary_head is not None: + if isinstance(auxiliary_head, list): + self.auxiliary_head = nn.ModuleList() + for head_cfg in auxiliary_head: + self.auxiliary_head.append(builder.build_head(head_cfg)) + else: + self.auxiliary_head = builder.build_head(auxiliary_head) + + def init_weights(self, pretrained=None): + """Initialize the weights in backbone and heads. + + Args: + pretrained (str, optional): Path to pre-trained weights. + Defaults to None. + """ + + super(EncoderDecoder, self).init_weights(pretrained) + self.backbone.init_weights(pretrained=pretrained) + self.decode_head.init_weights() + if self.with_auxiliary_head: + if isinstance(self.auxiliary_head, nn.ModuleList): + for aux_head in self.auxiliary_head: + aux_head.init_weights() + else: + self.auxiliary_head.init_weights() + + def extract_feat(self, img): + """Extract features from images.""" + x = self.backbone(img) + if self.with_neck: + x = self.neck(x) + return x + + def encode_decode(self, img, img_metas): + """Encode images with backbone and decode into a semantic segmentation + map of the same size as input.""" + x = self.extract_feat(img) + out = self._decode_head_forward_test(x, img_metas) + out = resize( + input=out, + size=img.shape[2:], + mode='bilinear', + align_corners=self.align_corners) + return out + + def _decode_head_forward_train(self, x, img_metas, gt_semantic_seg): + """Run forward function and calculate loss for decode head in + training.""" + losses = dict() + loss_decode = self.decode_head.forward_train(x, img_metas, + gt_semantic_seg, + self.train_cfg) + + losses.update(add_prefix(loss_decode, 'decode')) + return losses + + def _decode_head_forward_test(self, x, img_metas): + """Run forward function and calculate loss for decode head in + inference.""" + seg_logits = self.decode_head.forward_test(x, img_metas, self.test_cfg) + return seg_logits + + def _auxiliary_head_forward_train(self, x, img_metas, gt_semantic_seg): + """Run forward function and calculate loss for auxiliary head in + training.""" + losses = dict() + if isinstance(self.auxiliary_head, nn.ModuleList): + for idx, aux_head in enumerate(self.auxiliary_head): + loss_aux = aux_head.forward_train(x, img_metas, + gt_semantic_seg, + self.train_cfg) + losses.update(add_prefix(loss_aux, f'aux_{idx}')) + else: + loss_aux = self.auxiliary_head.forward_train( + x, img_metas, gt_semantic_seg, self.train_cfg) + losses.update(add_prefix(loss_aux, 'aux')) + + return losses + + def forward_dummy(self, img): + """Dummy forward function.""" + seg_logit = self.encode_decode(img, None) + + return seg_logit + + def forward_train(self, img, img_metas, gt_semantic_seg): + """Forward function for training. + + Args: + img (Tensor): Input images. + img_metas (list[dict]): List of image info dict where each dict + has: 'img_shape', 'scale_factor', 'flip', and may also contain + 'filename', 'ori_shape', 'pad_shape', and 'img_norm_cfg'. + For details on the values of these keys see + `mmseg/datasets/pipelines/formatting.py:Collect`. + gt_semantic_seg (Tensor): Semantic segmentation masks + used if the architecture supports semantic segmentation task. + + Returns: + dict[str, Tensor]: a dictionary of loss components + """ + + x = self.extract_feat(img) + + losses = dict() + + loss_decode = self._decode_head_forward_train(x, img_metas, + gt_semantic_seg) + losses.update(loss_decode) + + if self.with_auxiliary_head: + loss_aux = self._auxiliary_head_forward_train( + x, img_metas, gt_semantic_seg) + losses.update(loss_aux) + + return losses + + # TODO refactor + def slide_inference(self, img, img_meta, rescale): + """Inference by sliding-window with overlap. + + If h_crop > h_img or w_crop > w_img, the small patch will be used to + decode without padding. + """ + + h_stride, w_stride = self.test_cfg.stride + h_crop, w_crop = self.test_cfg.crop_size + batch_size, _, h_img, w_img = img.size() + num_classes = self.num_classes + h_grids = max(h_img - h_crop + h_stride - 1, 0) // h_stride + 1 + w_grids = max(w_img - w_crop + w_stride - 1, 0) // w_stride + 1 + preds = img.new_zeros((batch_size, num_classes, h_img, w_img)) + count_mat = img.new_zeros((batch_size, 1, h_img, w_img)) + for h_idx in range(h_grids): + for w_idx in range(w_grids): + y1 = h_idx * h_stride + x1 = w_idx * w_stride + y2 = min(y1 + h_crop, h_img) + x2 = min(x1 + w_crop, w_img) + y1 = max(y2 - h_crop, 0) + x1 = max(x2 - w_crop, 0) + crop_img = img[:, :, y1:y2, x1:x2] + crop_seg_logit = self.encode_decode(crop_img, img_meta) + preds += F.pad(crop_seg_logit, + (int(x1), int(preds.shape[3] - x2), int(y1), + int(preds.shape[2] - y2))) + + count_mat[:, :, y1:y2, x1:x2] += 1 + assert (count_mat == 0).sum() == 0 + if torch.onnx.is_in_onnx_export(): + # cast count_mat to constant while exporting to ONNX + count_mat = torch.from_numpy( + count_mat.cpu().detach().numpy()).to(device=img.device) + preds = preds / count_mat + if rescale: + preds = resize( + preds, + size=img_meta[0]['ori_shape'][:2], + mode='bilinear', + align_corners=self.align_corners, + warning=False) + return preds + + def whole_inference(self, img, img_meta, rescale): + """Inference with full image.""" + + seg_logit = self.encode_decode(img, img_meta) + if rescale: + # support dynamic shape for onnx + if torch.onnx.is_in_onnx_export(): + size = img.shape[2:] + else: + size = img_meta[0]['ori_shape'][:2] + seg_logit = resize( + seg_logit, + size=size, + mode='bilinear', + align_corners=self.align_corners, + warning=False) + + return seg_logit + + def inference(self, img, img_meta, rescale): + """Inference with slide/whole style. + + Args: + img (Tensor): The input image of shape (N, 3, H, W). + img_meta (dict): Image info dict where each dict has: 'img_shape', + 'scale_factor', 'flip', and may also contain + 'filename', 'ori_shape', 'pad_shape', and 'img_norm_cfg'. + For details on the values of these keys see + `mmseg/datasets/pipelines/formatting.py:Collect`. + rescale (bool): Whether rescale back to original shape. + + Returns: + Tensor: The output segmentation map. + """ + + assert self.test_cfg.mode in ['slide', 'whole'] + ori_shape = img_meta[0]['ori_shape'] + assert all(_['ori_shape'] == ori_shape for _ in img_meta) + if self.test_cfg.mode == 'slide': + seg_logit = self.slide_inference(img, img_meta, rescale) + else: + seg_logit = self.whole_inference(img, img_meta, rescale) + output = F.softmax(seg_logit, dim=1) + flip = img_meta[0]['flip'] + if flip: + flip_direction = img_meta[0]['flip_direction'] + assert flip_direction in ['horizontal', 'vertical'] + if flip_direction == 'horizontal': + output = output.flip(dims=(3, )) + elif flip_direction == 'vertical': + output = output.flip(dims=(2, )) + + return output + + def simple_test(self, img, img_meta, rescale=True): + """Simple test with single image.""" + seg_logit = self.inference(img, img_meta, rescale) + seg_pred = seg_logit.argmax(dim=1) + if torch.onnx.is_in_onnx_export(): + # our inference backend only support 4D output + seg_pred = seg_pred.unsqueeze(0) + return seg_pred + seg_pred = seg_pred.cpu().numpy() + # unravel batch dim + seg_pred = list(seg_pred) + return seg_pred + + def aug_test(self, imgs, img_metas, rescale=True): + """Test with augmentations. + + Only rescale=True is supported. + """ + # aug_test rescale all imgs back to ori_shape for now + assert rescale + # to save memory, we get augmented seg logit inplace + seg_logit = self.inference(imgs[0], img_metas[0], rescale) + for i in range(1, len(imgs)): + cur_seg_logit = self.inference(imgs[i], img_metas[i], rescale) + seg_logit += cur_seg_logit + seg_logit /= len(imgs) + seg_pred = seg_logit.argmax(dim=1) + seg_pred = seg_pred.cpu().numpy() + # unravel batch dim + seg_pred = list(seg_pred) + return seg_pred diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/__init__.py new file mode 100644 index 00000000..3d3bdd34 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/__init__.py @@ -0,0 +1,13 @@ +from .drop import DropPath +from .inverted_residual import InvertedResidual, InvertedResidualV3 +from .make_divisible import make_divisible +from .res_layer import ResLayer +from .se_layer import SELayer +from .self_attention_block import SelfAttentionBlock +from .up_conv_block import UpConvBlock +from .weight_init import trunc_normal_ + +__all__ = [ + 'ResLayer', 'SelfAttentionBlock', 'make_divisible', 'InvertedResidual', + 'UpConvBlock', 'InvertedResidualV3', 'SELayer', 'DropPath', 'trunc_normal_' +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/drop.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/drop.py new file mode 100644 index 00000000..4520b0ff --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/drop.py @@ -0,0 +1,31 @@ +"""Modified from https://github.com/rwightman/pytorch-image- +models/blob/master/timm/models/layers/drop.py.""" + +import torch +from torch import nn + + +class DropPath(nn.Module): + """Drop paths (Stochastic Depth) per sample (when applied in main path of + residual blocks). + + Args: + drop_prob (float): Drop rate for paths of model. Dropout rate has + to be between 0 and 1. Default: 0. + """ + + def __init__(self, drop_prob=0.): + super(DropPath, self).__init__() + self.drop_prob = drop_prob + self.keep_prob = 1 - drop_prob + + def forward(self, x): + if self.drop_prob == 0. or not self.training: + return x + shape = (x.shape[0], ) + (1, ) * ( + x.ndim - 1) # work with diff dim tensors, not just 2D ConvNets + random_tensor = self.keep_prob + torch.rand( + shape, dtype=x.dtype, device=x.device) + random_tensor.floor_() # binarize + output = x.div(self.keep_prob) * random_tensor + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/inverted_residual.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/inverted_residual.py new file mode 100644 index 00000000..2df5ebd7 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/inverted_residual.py @@ -0,0 +1,208 @@ +from annotator.mmpkg.mmcv.cnn import ConvModule +from torch import nn +from torch.utils import checkpoint as cp + +from .se_layer import SELayer + + +class InvertedResidual(nn.Module): + """InvertedResidual block for MobileNetV2. + + Args: + in_channels (int): The input channels of the InvertedResidual block. + out_channels (int): The output channels of the InvertedResidual block. + stride (int): Stride of the middle (first) 3x3 convolution. + expand_ratio (int): Adjusts number of channels of the hidden layer + in InvertedResidual by this amount. + dilation (int): Dilation rate of depthwise conv. Default: 1 + conv_cfg (dict): Config dict for convolution layer. + Default: None, which means using conv2d. + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='BN'). + act_cfg (dict): Config dict for activation layer. + Default: dict(type='ReLU6'). + with_cp (bool): Use checkpoint or not. Using checkpoint will save some + memory while slowing down the training speed. Default: False. + + Returns: + Tensor: The output tensor. + """ + + def __init__(self, + in_channels, + out_channels, + stride, + expand_ratio, + dilation=1, + conv_cfg=None, + norm_cfg=dict(type='BN'), + act_cfg=dict(type='ReLU6'), + with_cp=False): + super(InvertedResidual, self).__init__() + self.stride = stride + assert stride in [1, 2], f'stride must in [1, 2]. ' \ + f'But received {stride}.' + self.with_cp = with_cp + self.use_res_connect = self.stride == 1 and in_channels == out_channels + hidden_dim = int(round(in_channels * expand_ratio)) + + layers = [] + if expand_ratio != 1: + layers.append( + ConvModule( + in_channels=in_channels, + out_channels=hidden_dim, + kernel_size=1, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg)) + layers.extend([ + ConvModule( + in_channels=hidden_dim, + out_channels=hidden_dim, + kernel_size=3, + stride=stride, + padding=dilation, + dilation=dilation, + groups=hidden_dim, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg), + ConvModule( + in_channels=hidden_dim, + out_channels=out_channels, + kernel_size=1, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=None) + ]) + self.conv = nn.Sequential(*layers) + + def forward(self, x): + + def _inner_forward(x): + if self.use_res_connect: + return x + self.conv(x) + else: + return self.conv(x) + + if self.with_cp and x.requires_grad: + out = cp.checkpoint(_inner_forward, x) + else: + out = _inner_forward(x) + + return out + + +class InvertedResidualV3(nn.Module): + """Inverted Residual Block for MobileNetV3. + + Args: + in_channels (int): The input channels of this Module. + out_channels (int): The output channels of this Module. + mid_channels (int): The input channels of the depthwise convolution. + kernel_size (int): The kernel size of the depthwise convolution. + Default: 3. + stride (int): The stride of the depthwise convolution. Default: 1. + se_cfg (dict): Config dict for se layer. Default: None, which means no + se layer. + with_expand_conv (bool): Use expand conv or not. If set False, + mid_channels must be the same with in_channels. Default: True. + conv_cfg (dict): Config dict for convolution layer. Default: None, + which means using conv2d. + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='BN'). + act_cfg (dict): Config dict for activation layer. + Default: dict(type='ReLU'). + with_cp (bool): Use checkpoint or not. Using checkpoint will save some + memory while slowing down the training speed. Default: False. + + Returns: + Tensor: The output tensor. + """ + + def __init__(self, + in_channels, + out_channels, + mid_channels, + kernel_size=3, + stride=1, + se_cfg=None, + with_expand_conv=True, + conv_cfg=None, + norm_cfg=dict(type='BN'), + act_cfg=dict(type='ReLU'), + with_cp=False): + super(InvertedResidualV3, self).__init__() + self.with_res_shortcut = (stride == 1 and in_channels == out_channels) + assert stride in [1, 2] + self.with_cp = with_cp + self.with_se = se_cfg is not None + self.with_expand_conv = with_expand_conv + + if self.with_se: + assert isinstance(se_cfg, dict) + if not self.with_expand_conv: + assert mid_channels == in_channels + + if self.with_expand_conv: + self.expand_conv = ConvModule( + in_channels=in_channels, + out_channels=mid_channels, + kernel_size=1, + stride=1, + padding=0, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + self.depthwise_conv = ConvModule( + in_channels=mid_channels, + out_channels=mid_channels, + kernel_size=kernel_size, + stride=stride, + padding=kernel_size // 2, + groups=mid_channels, + conv_cfg=dict( + type='Conv2dAdaptivePadding') if stride == 2 else conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + + if self.with_se: + self.se = SELayer(**se_cfg) + + self.linear_conv = ConvModule( + in_channels=mid_channels, + out_channels=out_channels, + kernel_size=1, + stride=1, + padding=0, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=None) + + def forward(self, x): + + def _inner_forward(x): + out = x + + if self.with_expand_conv: + out = self.expand_conv(out) + + out = self.depthwise_conv(out) + + if self.with_se: + out = self.se(out) + + out = self.linear_conv(out) + + if self.with_res_shortcut: + return x + out + else: + return out + + if self.with_cp and x.requires_grad: + out = cp.checkpoint(_inner_forward, x) + else: + out = _inner_forward(x) + + return out diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/make_divisible.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/make_divisible.py new file mode 100644 index 00000000..75ad7560 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/make_divisible.py @@ -0,0 +1,27 @@ +def make_divisible(value, divisor, min_value=None, min_ratio=0.9): + """Make divisible function. + + This function rounds the channel number to the nearest value that can be + divisible by the divisor. It is taken from the original tf repo. It ensures + that all layers have a channel number that is divisible by divisor. It can + be seen here: https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py # noqa + + Args: + value (int): The original channel number. + divisor (int): The divisor to fully divide the channel number. + min_value (int): The minimum value of the output channel. + Default: None, means that the minimum value equal to the divisor. + min_ratio (float): The minimum ratio of the rounded channel number to + the original channel number. Default: 0.9. + + Returns: + int: The modified output channel number. + """ + + if min_value is None: + min_value = divisor + new_value = max(min_value, int(value + divisor / 2) // divisor * divisor) + # Make sure that round down does not go down by more than (1-min_ratio). + if new_value < min_ratio * value: + new_value += divisor + return new_value diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/res_layer.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/res_layer.py new file mode 100644 index 00000000..d41075a5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/res_layer.py @@ -0,0 +1,94 @@ +from annotator.mmpkg.mmcv.cnn import build_conv_layer, build_norm_layer +from torch import nn as nn + + +class ResLayer(nn.Sequential): + """ResLayer to build ResNet style backbone. + + Args: + block (nn.Module): block used to build ResLayer. + inplanes (int): inplanes of block. + planes (int): planes of block. + num_blocks (int): number of blocks. + stride (int): stride of the first block. Default: 1 + avg_down (bool): Use AvgPool instead of stride conv when + downsampling in the bottleneck. Default: False + conv_cfg (dict): dictionary to construct and config conv layer. + Default: None + norm_cfg (dict): dictionary to construct and config norm layer. + Default: dict(type='BN') + multi_grid (int | None): Multi grid dilation rates of last + stage. Default: None + contract_dilation (bool): Whether contract first dilation of each layer + Default: False + """ + + def __init__(self, + block, + inplanes, + planes, + num_blocks, + stride=1, + dilation=1, + avg_down=False, + conv_cfg=None, + norm_cfg=dict(type='BN'), + multi_grid=None, + contract_dilation=False, + **kwargs): + self.block = block + + downsample = None + if stride != 1 or inplanes != planes * block.expansion: + downsample = [] + conv_stride = stride + if avg_down: + conv_stride = 1 + downsample.append( + nn.AvgPool2d( + kernel_size=stride, + stride=stride, + ceil_mode=True, + count_include_pad=False)) + downsample.extend([ + build_conv_layer( + conv_cfg, + inplanes, + planes * block.expansion, + kernel_size=1, + stride=conv_stride, + bias=False), + build_norm_layer(norm_cfg, planes * block.expansion)[1] + ]) + downsample = nn.Sequential(*downsample) + + layers = [] + if multi_grid is None: + if dilation > 1 and contract_dilation: + first_dilation = dilation // 2 + else: + first_dilation = dilation + else: + first_dilation = multi_grid[0] + layers.append( + block( + inplanes=inplanes, + planes=planes, + stride=stride, + dilation=first_dilation, + downsample=downsample, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + **kwargs)) + inplanes = planes * block.expansion + for i in range(1, num_blocks): + layers.append( + block( + inplanes=inplanes, + planes=planes, + stride=1, + dilation=dilation if multi_grid is None else multi_grid[i], + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + **kwargs)) + super(ResLayer, self).__init__(*layers) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/se_layer.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/se_layer.py new file mode 100644 index 00000000..42ab005e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/se_layer.py @@ -0,0 +1,57 @@ +import annotator.mmpkg.mmcv as mmcv +import torch.nn as nn +from annotator.mmpkg.mmcv.cnn import ConvModule + +from .make_divisible import make_divisible + + +class SELayer(nn.Module): + """Squeeze-and-Excitation Module. + + Args: + channels (int): The input (and output) channels of the SE layer. + ratio (int): Squeeze ratio in SELayer, the intermediate channel will be + ``int(channels/ratio)``. Default: 16. + conv_cfg (None or dict): Config dict for convolution layer. + Default: None, which means using conv2d. + act_cfg (dict or Sequence[dict]): Config dict for activation layer. + If act_cfg is a dict, two activation layers will be configured + by this dict. If act_cfg is a sequence of dicts, the first + activation layer will be configured by the first dict and the + second activation layer will be configured by the second dict. + Default: (dict(type='ReLU'), dict(type='HSigmoid', bias=3.0, + divisor=6.0)). + """ + + def __init__(self, + channels, + ratio=16, + conv_cfg=None, + act_cfg=(dict(type='ReLU'), + dict(type='HSigmoid', bias=3.0, divisor=6.0))): + super(SELayer, self).__init__() + if isinstance(act_cfg, dict): + act_cfg = (act_cfg, act_cfg) + assert len(act_cfg) == 2 + assert mmcv.is_tuple_of(act_cfg, dict) + self.global_avgpool = nn.AdaptiveAvgPool2d(1) + self.conv1 = ConvModule( + in_channels=channels, + out_channels=make_divisible(channels // ratio, 8), + kernel_size=1, + stride=1, + conv_cfg=conv_cfg, + act_cfg=act_cfg[0]) + self.conv2 = ConvModule( + in_channels=make_divisible(channels // ratio, 8), + out_channels=channels, + kernel_size=1, + stride=1, + conv_cfg=conv_cfg, + act_cfg=act_cfg[1]) + + def forward(self, x): + out = self.global_avgpool(x) + out = self.conv1(out) + out = self.conv2(out) + return x * out diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/self_attention_block.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/self_attention_block.py new file mode 100644 index 00000000..a342e2b2 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/self_attention_block.py @@ -0,0 +1,159 @@ +import torch +from annotator.mmpkg.mmcv.cnn import ConvModule, constant_init +from torch import nn as nn +from torch.nn import functional as F + + +class SelfAttentionBlock(nn.Module): + """General self-attention block/non-local block. + + Please refer to https://arxiv.org/abs/1706.03762 for details about key, + query and value. + + Args: + key_in_channels (int): Input channels of key feature. + query_in_channels (int): Input channels of query feature. + channels (int): Output channels of key/query transform. + out_channels (int): Output channels. + share_key_query (bool): Whether share projection weight between key + and query projection. + query_downsample (nn.Module): Query downsample module. + key_downsample (nn.Module): Key downsample module. + key_query_num_convs (int): Number of convs for key/query projection. + value_num_convs (int): Number of convs for value projection. + matmul_norm (bool): Whether normalize attention map with sqrt of + channels + with_out (bool): Whether use out projection. + conv_cfg (dict|None): Config of conv layers. + norm_cfg (dict|None): Config of norm layers. + act_cfg (dict|None): Config of activation layers. + """ + + def __init__(self, key_in_channels, query_in_channels, channels, + out_channels, share_key_query, query_downsample, + key_downsample, key_query_num_convs, value_out_num_convs, + key_query_norm, value_out_norm, matmul_norm, with_out, + conv_cfg, norm_cfg, act_cfg): + super(SelfAttentionBlock, self).__init__() + if share_key_query: + assert key_in_channels == query_in_channels + self.key_in_channels = key_in_channels + self.query_in_channels = query_in_channels + self.out_channels = out_channels + self.channels = channels + self.share_key_query = share_key_query + self.conv_cfg = conv_cfg + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + self.key_project = self.build_project( + key_in_channels, + channels, + num_convs=key_query_num_convs, + use_conv_module=key_query_norm, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + if share_key_query: + self.query_project = self.key_project + else: + self.query_project = self.build_project( + query_in_channels, + channels, + num_convs=key_query_num_convs, + use_conv_module=key_query_norm, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + self.value_project = self.build_project( + key_in_channels, + channels if with_out else out_channels, + num_convs=value_out_num_convs, + use_conv_module=value_out_norm, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + if with_out: + self.out_project = self.build_project( + channels, + out_channels, + num_convs=value_out_num_convs, + use_conv_module=value_out_norm, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + else: + self.out_project = None + + self.query_downsample = query_downsample + self.key_downsample = key_downsample + self.matmul_norm = matmul_norm + + self.init_weights() + + def init_weights(self): + """Initialize weight of later layer.""" + if self.out_project is not None: + if not isinstance(self.out_project, ConvModule): + constant_init(self.out_project, 0) + + def build_project(self, in_channels, channels, num_convs, use_conv_module, + conv_cfg, norm_cfg, act_cfg): + """Build projection layer for key/query/value/out.""" + if use_conv_module: + convs = [ + ConvModule( + in_channels, + channels, + 1, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + ] + for _ in range(num_convs - 1): + convs.append( + ConvModule( + channels, + channels, + 1, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg)) + else: + convs = [nn.Conv2d(in_channels, channels, 1)] + for _ in range(num_convs - 1): + convs.append(nn.Conv2d(channels, channels, 1)) + if len(convs) > 1: + convs = nn.Sequential(*convs) + else: + convs = convs[0] + return convs + + def forward(self, query_feats, key_feats): + """Forward function.""" + batch_size = query_feats.size(0) + query = self.query_project(query_feats) + if self.query_downsample is not None: + query = self.query_downsample(query) + query = query.reshape(*query.shape[:2], -1) + query = query.permute(0, 2, 1).contiguous() + + key = self.key_project(key_feats) + value = self.value_project(key_feats) + if self.key_downsample is not None: + key = self.key_downsample(key) + value = self.key_downsample(value) + key = key.reshape(*key.shape[:2], -1) + value = value.reshape(*value.shape[:2], -1) + value = value.permute(0, 2, 1).contiguous() + + sim_map = torch.matmul(query, key) + if self.matmul_norm: + sim_map = (self.channels**-.5) * sim_map + sim_map = F.softmax(sim_map, dim=-1) + + context = torch.matmul(sim_map, value) + context = context.permute(0, 2, 1).contiguous() + context = context.reshape(batch_size, -1, *query_feats.shape[2:]) + if self.out_project is not None: + context = self.out_project(context) + return context diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/up_conv_block.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/up_conv_block.py new file mode 100644 index 00000000..86328011 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/up_conv_block.py @@ -0,0 +1,101 @@ +import torch +import torch.nn as nn +from annotator.mmpkg.mmcv.cnn import ConvModule, build_upsample_layer + + +class UpConvBlock(nn.Module): + """Upsample convolution block in decoder for UNet. + + This upsample convolution block consists of one upsample module + followed by one convolution block. The upsample module expands the + high-level low-resolution feature map and the convolution block fuses + the upsampled high-level low-resolution feature map and the low-level + high-resolution feature map from encoder. + + Args: + conv_block (nn.Sequential): Sequential of convolutional layers. + in_channels (int): Number of input channels of the high-level + skip_channels (int): Number of input channels of the low-level + high-resolution feature map from encoder. + out_channels (int): Number of output channels. + num_convs (int): Number of convolutional layers in the conv_block. + Default: 2. + stride (int): Stride of convolutional layer in conv_block. Default: 1. + dilation (int): Dilation rate of convolutional layer in conv_block. + Default: 1. + with_cp (bool): Use checkpoint or not. Using checkpoint will save some + memory while slowing down the training speed. Default: False. + conv_cfg (dict | None): Config dict for convolution layer. + Default: None. + norm_cfg (dict | None): Config dict for normalization layer. + Default: dict(type='BN'). + act_cfg (dict | None): Config dict for activation layer in ConvModule. + Default: dict(type='ReLU'). + upsample_cfg (dict): The upsample config of the upsample module in + decoder. Default: dict(type='InterpConv'). If the size of + high-level feature map is the same as that of skip feature map + (low-level feature map from encoder), it does not need upsample the + high-level feature map and the upsample_cfg is None. + dcn (bool): Use deformable convolution in convolutional layer or not. + Default: None. + plugins (dict): plugins for convolutional layers. Default: None. + """ + + def __init__(self, + conv_block, + in_channels, + skip_channels, + out_channels, + num_convs=2, + stride=1, + dilation=1, + with_cp=False, + conv_cfg=None, + norm_cfg=dict(type='BN'), + act_cfg=dict(type='ReLU'), + upsample_cfg=dict(type='InterpConv'), + dcn=None, + plugins=None): + super(UpConvBlock, self).__init__() + assert dcn is None, 'Not implemented yet.' + assert plugins is None, 'Not implemented yet.' + + self.conv_block = conv_block( + in_channels=2 * skip_channels, + out_channels=out_channels, + num_convs=num_convs, + stride=stride, + dilation=dilation, + with_cp=with_cp, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg, + dcn=None, + plugins=None) + if upsample_cfg is not None: + self.upsample = build_upsample_layer( + cfg=upsample_cfg, + in_channels=in_channels, + out_channels=skip_channels, + with_cp=with_cp, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + else: + self.upsample = ConvModule( + in_channels, + skip_channels, + kernel_size=1, + stride=1, + padding=0, + conv_cfg=conv_cfg, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + + def forward(self, skip, x): + """Forward function.""" + + x = self.upsample(x) + out = torch.cat([skip, x], dim=1) + out = self.conv_block(out) + + return out diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/weight_init.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/weight_init.py new file mode 100644 index 00000000..38141ba3 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/models/utils/weight_init.py @@ -0,0 +1,62 @@ +"""Modified from https://github.com/rwightman/pytorch-image- +models/blob/master/timm/models/layers/drop.py.""" + +import math +import warnings + +import torch + + +def _no_grad_trunc_normal_(tensor, mean, std, a, b): + """Reference: https://people.sc.fsu.edu/~jburkardt/presentations + /truncated_normal.pdf""" + + def norm_cdf(x): + # Computes standard normal cumulative distribution function + return (1. + math.erf(x / math.sqrt(2.))) / 2. + + if (mean < a - 2 * std) or (mean > b + 2 * std): + warnings.warn( + 'mean is more than 2 std from [a, b] in nn.init.trunc_normal_. ' + 'The distribution of values may be incorrect.', + stacklevel=2) + + with torch.no_grad(): + # Values are generated by using a truncated uniform distribution and + # then using the inverse CDF for the normal distribution. + # Get upper and lower cdf values + lower_bound = norm_cdf((a - mean) / std) + upper_bound = norm_cdf((b - mean) / std) + + # Uniformly fill tensor with values from [l, u], then translate to + # [2l-1, 2u-1]. + tensor.uniform_(2 * lower_bound - 1, 2 * upper_bound - 1) + + # Use inverse cdf transform for normal distribution to get truncated + # standard normal + tensor.erfinv_() + + # Transform to proper mean, std + tensor.mul_(std * math.sqrt(2.)) + tensor.add_(mean) + + # Clamp to ensure it's in the proper range + tensor.clamp_(min=a, max=b) + return tensor + + +def trunc_normal_(tensor, mean=0., std=1., a=-2., b=2.): + r"""Fills the input Tensor with values drawn from a truncated + normal distribution. The values are effectively drawn from the + normal distribution :math:`\mathcal{N}(\text{mean}, \text{std}^2)` + with values outside :math:`[a, b]` redrawn until they are within + the bounds. The method used for generating the random values works + best when :math:`a \leq \text{mean} \leq b`. + Args: + tensor (``torch.Tensor``): an n-dimensional `torch.Tensor` + mean (float): the mean of the normal distribution + std (float): the standard deviation of the normal distribution + a (float): the minimum cutoff value + b (float): the maximum cutoff value + """ + return _no_grad_trunc_normal_(tensor, mean, std, a, b) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/ops/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/ops/__init__.py new file mode 100644 index 00000000..bec51c75 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/ops/__init__.py @@ -0,0 +1,4 @@ +from .encoding import Encoding +from .wrappers import Upsample, resize + +__all__ = ['Upsample', 'resize', 'Encoding'] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/ops/encoding.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/ops/encoding.py new file mode 100644 index 00000000..7eb3629a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/ops/encoding.py @@ -0,0 +1,74 @@ +import torch +from torch import nn +from torch.nn import functional as F + + +class Encoding(nn.Module): + """Encoding Layer: a learnable residual encoder. + + Input is of shape (batch_size, channels, height, width). + Output is of shape (batch_size, num_codes, channels). + + Args: + channels: dimension of the features or feature channels + num_codes: number of code words + """ + + def __init__(self, channels, num_codes): + super(Encoding, self).__init__() + # init codewords and smoothing factor + self.channels, self.num_codes = channels, num_codes + std = 1. / ((num_codes * channels)**0.5) + # [num_codes, channels] + self.codewords = nn.Parameter( + torch.empty(num_codes, channels, + dtype=torch.float).uniform_(-std, std), + requires_grad=True) + # [num_codes] + self.scale = nn.Parameter( + torch.empty(num_codes, dtype=torch.float).uniform_(-1, 0), + requires_grad=True) + + @staticmethod + def scaled_l2(x, codewords, scale): + num_codes, channels = codewords.size() + batch_size = x.size(0) + reshaped_scale = scale.view((1, 1, num_codes)) + expanded_x = x.unsqueeze(2).expand( + (batch_size, x.size(1), num_codes, channels)) + reshaped_codewords = codewords.view((1, 1, num_codes, channels)) + + scaled_l2_norm = reshaped_scale * ( + expanded_x - reshaped_codewords).pow(2).sum(dim=3) + return scaled_l2_norm + + @staticmethod + def aggregate(assignment_weights, x, codewords): + num_codes, channels = codewords.size() + reshaped_codewords = codewords.view((1, 1, num_codes, channels)) + batch_size = x.size(0) + + expanded_x = x.unsqueeze(2).expand( + (batch_size, x.size(1), num_codes, channels)) + encoded_feat = (assignment_weights.unsqueeze(3) * + (expanded_x - reshaped_codewords)).sum(dim=1) + return encoded_feat + + def forward(self, x): + assert x.dim() == 4 and x.size(1) == self.channels + # [batch_size, channels, height, width] + batch_size = x.size(0) + # [batch_size, height x width, channels] + x = x.view(batch_size, self.channels, -1).transpose(1, 2).contiguous() + # assignment_weights: [batch_size, channels, num_codes] + assignment_weights = F.softmax( + self.scaled_l2(x, self.codewords, self.scale), dim=2) + # aggregate + encoded_feat = self.aggregate(assignment_weights, x, self.codewords) + return encoded_feat + + def __repr__(self): + repr_str = self.__class__.__name__ + repr_str += f'(Nx{self.channels}xHxW =>Nx{self.num_codes}' \ + f'x{self.channels})' + return repr_str diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/ops/wrappers.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/ops/wrappers.py new file mode 100644 index 00000000..0ed9a0cb --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/ops/wrappers.py @@ -0,0 +1,50 @@ +import warnings + +import torch.nn as nn +import torch.nn.functional as F + + +def resize(input, + size=None, + scale_factor=None, + mode='nearest', + align_corners=None, + warning=True): + if warning: + if size is not None and align_corners: + input_h, input_w = tuple(int(x) for x in input.shape[2:]) + output_h, output_w = tuple(int(x) for x in size) + if output_h > input_h or output_w > output_h: + if ((output_h > 1 and output_w > 1 and input_h > 1 + and input_w > 1) and (output_h - 1) % (input_h - 1) + and (output_w - 1) % (input_w - 1)): + warnings.warn( + f'When align_corners={align_corners}, ' + 'the output would more aligned if ' + f'input size {(input_h, input_w)} is `x+1` and ' + f'out size {(output_h, output_w)} is `nx+1`') + return F.interpolate(input, size, scale_factor, mode, align_corners) + + +class Upsample(nn.Module): + + def __init__(self, + size=None, + scale_factor=None, + mode='nearest', + align_corners=None): + super(Upsample, self).__init__() + self.size = size + if isinstance(scale_factor, tuple): + self.scale_factor = tuple(float(factor) for factor in scale_factor) + else: + self.scale_factor = float(scale_factor) if scale_factor else None + self.mode = mode + self.align_corners = align_corners + + def forward(self, x): + if not self.size: + size = [int(t * self.scale_factor) for t in x.shape[-2:]] + else: + size = self.size + return resize(x, size, None, self.mode, self.align_corners) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/utils/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/utils/__init__.py new file mode 100644 index 00000000..ac489e2d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/utils/__init__.py @@ -0,0 +1,4 @@ +from .collect_env import collect_env +from .logger import get_root_logger + +__all__ = ['get_root_logger', 'collect_env'] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/utils/collect_env.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/utils/collect_env.py new file mode 100644 index 00000000..015d5a6b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/utils/collect_env.py @@ -0,0 +1,17 @@ +from annotator.mmpkg.mmcv.utils import collect_env as collect_base_env +from annotator.mmpkg.mmcv.utils import get_git_hash + +import annotator.mmpkg.mmseg as mmseg + + +def collect_env(): + """Collect the information of the running environments.""" + env_info = collect_base_env() + env_info['MMSegmentation'] = f'{mmseg.__version__}+{get_git_hash()[:7]}' + + return env_info + + +if __name__ == '__main__': + for name, val in collect_env().items(): + print('{}: {}'.format(name, val)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/utils/logger.py b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/utils/logger.py new file mode 100644 index 00000000..0c377333 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/mmpkg/mmseg/utils/logger.py @@ -0,0 +1,27 @@ +import logging + +from annotator.mmpkg.mmcv.utils import get_logger + + +def get_root_logger(log_file=None, log_level=logging.INFO): + """Get the root logger. + + The logger will be initialized if it has not been initialized. By default a + StreamHandler will be added. If `log_file` is specified, a FileHandler will + also be added. The name of the root logger is the top-level package name, + e.g., "mmseg". + + Args: + log_file (str | None): The log filename. If specified, a FileHandler + will be added to the root logger. + log_level (int): The root logger level. Note that only the process of + rank 0 is affected, while other processes will set the level to + "Error" and be silent most of the time. + + Returns: + logging.Logger: The root logger. + """ + + logger = get_logger(name='mmseg', log_file=log_file, log_level=log_level) + + return logger diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/LICENSE b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/LICENSE new file mode 100644 index 00000000..16a9d56a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Caroline Chan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/__init__.py new file mode 100644 index 00000000..74a94e17 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/__init__.py @@ -0,0 +1,81 @@ +import os +import types +import torch +import numpy as np + +from einops import rearrange +from .models.NNET import NNET +from modules import devices +from annotator.annotator_path import models_path +import torchvision.transforms as transforms + + +# load model +def load_checkpoint(fpath, model): + ckpt = torch.load(fpath, map_location='cpu')['model'] + + load_dict = {} + for k, v in ckpt.items(): + if k.startswith('module.'): + k_ = k.replace('module.', '') + load_dict[k_] = v + else: + load_dict[k] = v + + model.load_state_dict(load_dict) + return model + + +class NormalBaeDetector: + model_dir = os.path.join(models_path, "normal_bae") + + def __init__(self): + self.model = None + self.device = devices.get_device_for("controlnet") + + def load_model(self): + remote_model_path = "https://huggingface.co/lllyasviel/Annotators/resolve/main/scannet.pt" + modelpath = os.path.join(self.model_dir, "scannet.pt") + if not os.path.exists(modelpath): + from basicsr.utils.download_util import load_file_from_url + load_file_from_url(remote_model_path, model_dir=self.model_dir) + args = types.SimpleNamespace() + args.mode = 'client' + args.architecture = 'BN' + args.pretrained = 'scannet' + args.sampling_ratio = 0.4 + args.importance_ratio = 0.7 + model = NNET(args) + model = load_checkpoint(modelpath, model) + model.eval() + self.model = model.to(self.device) + self.norm = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) + + def unload_model(self): + if self.model is not None: + self.model.cpu() + + def __call__(self, input_image): + if self.model is None: + self.load_model() + + self.model.to(self.device) + assert input_image.ndim == 3 + image_normal = input_image + with torch.no_grad(): + image_normal = torch.from_numpy(image_normal).float().to(self.device) + image_normal = image_normal / 255.0 + image_normal = rearrange(image_normal, 'h w c -> 1 c h w') + image_normal = self.norm(image_normal) + + normal = self.model(image_normal) + normal = normal[0][-1][:, :3] + # d = torch.sum(normal ** 2.0, dim=1, keepdim=True) ** 0.5 + # d = torch.maximum(d, torch.ones_like(d) * 1e-5) + # normal /= d + normal = ((normal + 1) * 0.5).clip(0, 1) + + normal = rearrange(normal[0], 'c h w -> h w c').cpu().numpy() + normal_image = (normal * 255.0).clip(0, 255).astype(np.uint8) + + return normal_image diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/NNET.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/NNET.py new file mode 100644 index 00000000..3ddbc50c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/NNET.py @@ -0,0 +1,22 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F + +from .submodules.encoder import Encoder +from .submodules.decoder import Decoder + + +class NNET(nn.Module): + def __init__(self, args): + super(NNET, self).__init__() + self.encoder = Encoder() + self.decoder = Decoder(args) + + def get_1x_lr_params(self): # lr/10 learning rate + return self.encoder.parameters() + + def get_10x_lr_params(self): # lr learning rate + return self.decoder.parameters() + + def forward(self, img, **kwargs): + return self.decoder(self.encoder(img), **kwargs) \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/baseline.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/baseline.py new file mode 100644 index 00000000..602d0fbd --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/baseline.py @@ -0,0 +1,85 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F + +from .submodules.submodules import UpSampleBN, norm_normalize + + +# This is the baseline encoder-decoder we used in the ablation study +class NNET(nn.Module): + def __init__(self, args=None): + super(NNET, self).__init__() + self.encoder = Encoder() + self.decoder = Decoder(num_classes=4) + + def forward(self, x, **kwargs): + out = self.decoder(self.encoder(x), **kwargs) + + # Bilinearly upsample the output to match the input resolution + up_out = F.interpolate(out, size=[x.size(2), x.size(3)], mode='bilinear', align_corners=False) + + # L2-normalize the first three channels / ensure positive value for concentration parameters (kappa) + up_out = norm_normalize(up_out) + return up_out + + def get_1x_lr_params(self): # lr/10 learning rate + return self.encoder.parameters() + + def get_10x_lr_params(self): # lr learning rate + modules = [self.decoder] + for m in modules: + yield from m.parameters() + + +# Encoder +class Encoder(nn.Module): + def __init__(self): + super(Encoder, self).__init__() + + basemodel_name = 'tf_efficientnet_b5_ap' + basemodel = torch.hub.load('rwightman/gen-efficientnet-pytorch', basemodel_name, pretrained=True) + + # Remove last layer + basemodel.global_pool = nn.Identity() + basemodel.classifier = nn.Identity() + + self.original_model = basemodel + + def forward(self, x): + features = [x] + for k, v in self.original_model._modules.items(): + if (k == 'blocks'): + for ki, vi in v._modules.items(): + features.append(vi(features[-1])) + else: + features.append(v(features[-1])) + return features + + +# Decoder (no pixel-wise MLP, no uncertainty-guided sampling) +class Decoder(nn.Module): + def __init__(self, num_classes=4): + super(Decoder, self).__init__() + self.conv2 = nn.Conv2d(2048, 2048, kernel_size=1, stride=1, padding=0) + self.up1 = UpSampleBN(skip_input=2048 + 176, output_features=1024) + self.up2 = UpSampleBN(skip_input=1024 + 64, output_features=512) + self.up3 = UpSampleBN(skip_input=512 + 40, output_features=256) + self.up4 = UpSampleBN(skip_input=256 + 24, output_features=128) + self.conv3 = nn.Conv2d(128, num_classes, kernel_size=3, stride=1, padding=1) + + def forward(self, features): + x_block0, x_block1, x_block2, x_block3, x_block4 = features[4], features[5], features[6], features[8], features[11] + x_d0 = self.conv2(x_block4) + x_d1 = self.up1(x_d0, x_block3) + x_d2 = self.up2(x_d1, x_block2) + x_d3 = self.up3(x_d2, x_block1) + x_d4 = self.up4(x_d3, x_block0) + out = self.conv3(x_d4) + return out + + +if __name__ == '__main__': + model = Baseline() + x = torch.rand(2, 3, 480, 640) + out = model(x) + print(out.shape) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/decoder.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/decoder.py new file mode 100644 index 00000000..993203d1 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/decoder.py @@ -0,0 +1,202 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +from .submodules import UpSampleBN, UpSampleGN, norm_normalize, sample_points + + +class Decoder(nn.Module): + def __init__(self, args): + super(Decoder, self).__init__() + + # hyper-parameter for sampling + self.sampling_ratio = args.sampling_ratio + self.importance_ratio = args.importance_ratio + + # feature-map + self.conv2 = nn.Conv2d(2048, 2048, kernel_size=1, stride=1, padding=0) + if args.architecture == 'BN': + self.up1 = UpSampleBN(skip_input=2048 + 176, output_features=1024) + self.up2 = UpSampleBN(skip_input=1024 + 64, output_features=512) + self.up3 = UpSampleBN(skip_input=512 + 40, output_features=256) + self.up4 = UpSampleBN(skip_input=256 + 24, output_features=128) + + elif args.architecture == 'GN': + self.up1 = UpSampleGN(skip_input=2048 + 176, output_features=1024) + self.up2 = UpSampleGN(skip_input=1024 + 64, output_features=512) + self.up3 = UpSampleGN(skip_input=512 + 40, output_features=256) + self.up4 = UpSampleGN(skip_input=256 + 24, output_features=128) + + else: + raise Exception('invalid architecture') + + # produces 1/8 res output + self.out_conv_res8 = nn.Conv2d(512, 4, kernel_size=3, stride=1, padding=1) + + # produces 1/4 res output + self.out_conv_res4 = nn.Sequential( + nn.Conv1d(512 + 4, 128, kernel_size=1), nn.ReLU(), + nn.Conv1d(128, 128, kernel_size=1), nn.ReLU(), + nn.Conv1d(128, 128, kernel_size=1), nn.ReLU(), + nn.Conv1d(128, 4, kernel_size=1), + ) + + # produces 1/2 res output + self.out_conv_res2 = nn.Sequential( + nn.Conv1d(256 + 4, 128, kernel_size=1), nn.ReLU(), + nn.Conv1d(128, 128, kernel_size=1), nn.ReLU(), + nn.Conv1d(128, 128, kernel_size=1), nn.ReLU(), + nn.Conv1d(128, 4, kernel_size=1), + ) + + # produces 1/1 res output + self.out_conv_res1 = nn.Sequential( + nn.Conv1d(128 + 4, 128, kernel_size=1), nn.ReLU(), + nn.Conv1d(128, 128, kernel_size=1), nn.ReLU(), + nn.Conv1d(128, 128, kernel_size=1), nn.ReLU(), + nn.Conv1d(128, 4, kernel_size=1), + ) + + def forward(self, features, gt_norm_mask=None, mode='test'): + x_block0, x_block1, x_block2, x_block3, x_block4 = features[4], features[5], features[6], features[8], features[11] + + # generate feature-map + + x_d0 = self.conv2(x_block4) # x_d0 : [2, 2048, 15, 20] 1/32 res + x_d1 = self.up1(x_d0, x_block3) # x_d1 : [2, 1024, 30, 40] 1/16 res + x_d2 = self.up2(x_d1, x_block2) # x_d2 : [2, 512, 60, 80] 1/8 res + x_d3 = self.up3(x_d2, x_block1) # x_d3: [2, 256, 120, 160] 1/4 res + x_d4 = self.up4(x_d3, x_block0) # x_d4: [2, 128, 240, 320] 1/2 res + + # 1/8 res output + out_res8 = self.out_conv_res8(x_d2) # out_res8: [2, 4, 60, 80] 1/8 res output + out_res8 = norm_normalize(out_res8) # out_res8: [2, 4, 60, 80] 1/8 res output + + ################################################################################################################ + # out_res4 + ################################################################################################################ + + if mode == 'train': + # upsampling ... out_res8: [2, 4, 60, 80] -> out_res8_res4: [2, 4, 120, 160] + out_res8_res4 = F.interpolate(out_res8, scale_factor=2, mode='bilinear', align_corners=True) + B, _, H, W = out_res8_res4.shape + + # samples: [B, 1, N, 2] + point_coords_res4, rows_int, cols_int = sample_points(out_res8_res4.detach(), gt_norm_mask, + sampling_ratio=self.sampling_ratio, + beta=self.importance_ratio) + + # output (needed for evaluation / visualization) + out_res4 = out_res8_res4 + + # grid_sample feature-map + feat_res4 = F.grid_sample(x_d2, point_coords_res4, mode='bilinear', align_corners=True) # (B, 512, 1, N) + init_pred = F.grid_sample(out_res8, point_coords_res4, mode='bilinear', align_corners=True) # (B, 4, 1, N) + feat_res4 = torch.cat([feat_res4, init_pred], dim=1) # (B, 512+4, 1, N) + + # prediction (needed to compute loss) + samples_pred_res4 = self.out_conv_res4(feat_res4[:, :, 0, :]) # (B, 4, N) + samples_pred_res4 = norm_normalize(samples_pred_res4) # (B, 4, N) - normalized + + for i in range(B): + out_res4[i, :, rows_int[i, :], cols_int[i, :]] = samples_pred_res4[i, :, :] + + else: + # grid_sample feature-map + feat_map = F.interpolate(x_d2, scale_factor=2, mode='bilinear', align_corners=True) + init_pred = F.interpolate(out_res8, scale_factor=2, mode='bilinear', align_corners=True) + feat_map = torch.cat([feat_map, init_pred], dim=1) # (B, 512+4, H, W) + B, _, H, W = feat_map.shape + + # try all pixels + out_res4 = self.out_conv_res4(feat_map.view(B, 512 + 4, -1)) # (B, 4, N) + out_res4 = norm_normalize(out_res4) # (B, 4, N) - normalized + out_res4 = out_res4.view(B, 4, H, W) + samples_pred_res4 = point_coords_res4 = None + + ################################################################################################################ + # out_res2 + ################################################################################################################ + + if mode == 'train': + + # upsampling ... out_res4: [2, 4, 120, 160] -> out_res4_res2: [2, 4, 240, 320] + out_res4_res2 = F.interpolate(out_res4, scale_factor=2, mode='bilinear', align_corners=True) + B, _, H, W = out_res4_res2.shape + + # samples: [B, 1, N, 2] + point_coords_res2, rows_int, cols_int = sample_points(out_res4_res2.detach(), gt_norm_mask, + sampling_ratio=self.sampling_ratio, + beta=self.importance_ratio) + + # output (needed for evaluation / visualization) + out_res2 = out_res4_res2 + + # grid_sample feature-map + feat_res2 = F.grid_sample(x_d3, point_coords_res2, mode='bilinear', align_corners=True) # (B, 256, 1, N) + init_pred = F.grid_sample(out_res4, point_coords_res2, mode='bilinear', align_corners=True) # (B, 4, 1, N) + feat_res2 = torch.cat([feat_res2, init_pred], dim=1) # (B, 256+4, 1, N) + + # prediction (needed to compute loss) + samples_pred_res2 = self.out_conv_res2(feat_res2[:, :, 0, :]) # (B, 4, N) + samples_pred_res2 = norm_normalize(samples_pred_res2) # (B, 4, N) - normalized + + for i in range(B): + out_res2[i, :, rows_int[i, :], cols_int[i, :]] = samples_pred_res2[i, :, :] + + else: + # grid_sample feature-map + feat_map = F.interpolate(x_d3, scale_factor=2, mode='bilinear', align_corners=True) + init_pred = F.interpolate(out_res4, scale_factor=2, mode='bilinear', align_corners=True) + feat_map = torch.cat([feat_map, init_pred], dim=1) # (B, 512+4, H, W) + B, _, H, W = feat_map.shape + + out_res2 = self.out_conv_res2(feat_map.view(B, 256 + 4, -1)) # (B, 4, N) + out_res2 = norm_normalize(out_res2) # (B, 4, N) - normalized + out_res2 = out_res2.view(B, 4, H, W) + samples_pred_res2 = point_coords_res2 = None + + ################################################################################################################ + # out_res1 + ################################################################################################################ + + if mode == 'train': + # upsampling ... out_res4: [2, 4, 120, 160] -> out_res4_res2: [2, 4, 240, 320] + out_res2_res1 = F.interpolate(out_res2, scale_factor=2, mode='bilinear', align_corners=True) + B, _, H, W = out_res2_res1.shape + + # samples: [B, 1, N, 2] + point_coords_res1, rows_int, cols_int = sample_points(out_res2_res1.detach(), gt_norm_mask, + sampling_ratio=self.sampling_ratio, + beta=self.importance_ratio) + + # output (needed for evaluation / visualization) + out_res1 = out_res2_res1 + + # grid_sample feature-map + feat_res1 = F.grid_sample(x_d4, point_coords_res1, mode='bilinear', align_corners=True) # (B, 128, 1, N) + init_pred = F.grid_sample(out_res2, point_coords_res1, mode='bilinear', align_corners=True) # (B, 4, 1, N) + feat_res1 = torch.cat([feat_res1, init_pred], dim=1) # (B, 128+4, 1, N) + + # prediction (needed to compute loss) + samples_pred_res1 = self.out_conv_res1(feat_res1[:, :, 0, :]) # (B, 4, N) + samples_pred_res1 = norm_normalize(samples_pred_res1) # (B, 4, N) - normalized + + for i in range(B): + out_res1[i, :, rows_int[i, :], cols_int[i, :]] = samples_pred_res1[i, :, :] + + else: + # grid_sample feature-map + feat_map = F.interpolate(x_d4, scale_factor=2, mode='bilinear', align_corners=True) + init_pred = F.interpolate(out_res2, scale_factor=2, mode='bilinear', align_corners=True) + feat_map = torch.cat([feat_map, init_pred], dim=1) # (B, 512+4, H, W) + B, _, H, W = feat_map.shape + + out_res1 = self.out_conv_res1(feat_map.view(B, 128 + 4, -1)) # (B, 4, N) + out_res1 = norm_normalize(out_res1) # (B, 4, N) - normalized + out_res1 = out_res1.view(B, 4, H, W) + samples_pred_res1 = point_coords_res1 = None + + return [out_res8, out_res4, out_res2, out_res1], \ + [out_res8, samples_pred_res4, samples_pred_res2, samples_pred_res1], \ + [None, point_coords_res4, point_coords_res2, point_coords_res1] + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/.gitignore b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/.gitignore new file mode 100644 index 00000000..f04e5fff --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/.gitignore @@ -0,0 +1,109 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# pytorch stuff +*.pth +*.onnx +*.pb + +trained_models/ +.fuse_hidden* diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/BENCHMARK.md b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/BENCHMARK.md new file mode 100644 index 00000000..6ead7171 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/BENCHMARK.md @@ -0,0 +1,555 @@ +# Model Performance Benchmarks + +All benchmarks run as per: + +``` +python onnx_export.py --model mobilenetv3_100 ./mobilenetv3_100.onnx +python onnx_optimize.py ./mobilenetv3_100.onnx --output mobilenetv3_100-opt.onnx +python onnx_to_caffe.py ./mobilenetv3_100.onnx --c2-prefix mobilenetv3 +python onnx_to_caffe.py ./mobilenetv3_100-opt.onnx --c2-prefix mobilenetv3-opt +python caffe2_benchmark.py --c2-init ./mobilenetv3.init.pb --c2-predict ./mobilenetv3.predict.pb +python caffe2_benchmark.py --c2-init ./mobilenetv3-opt.init.pb --c2-predict ./mobilenetv3-opt.predict.pb +``` + +## EfficientNet-B0 + +### Unoptimized +``` +Main run finished. Milliseconds per iter: 49.2862. Iters per second: 20.2897 +Time per operator type: + 29.7378 ms. 60.5145%. Conv + 12.1785 ms. 24.7824%. Sigmoid + 3.62811 ms. 7.38297%. SpatialBN + 2.98444 ms. 6.07314%. Mul + 0.326902 ms. 0.665225%. AveragePool + 0.197317 ms. 0.401528%. FC + 0.0852877 ms. 0.173555%. Add + 0.0032607 ms. 0.00663532%. Squeeze + 49.1416 ms in Total +FLOP per operator type: + 0.76907 GFLOP. 95.2696%. Conv + 0.0269508 GFLOP. 3.33857%. SpatialBN + 0.00846444 GFLOP. 1.04855%. Mul + 0.002561 GFLOP. 0.317248%. FC + 0.000210112 GFLOP. 0.0260279%. Add + 0.807256 GFLOP in Total +Feature Memory Read per operator type: + 58.5253 MB. 43.0891%. Mul + 43.2015 MB. 31.807%. Conv + 27.2869 MB. 20.0899%. SpatialBN + 5.12912 MB. 3.77631%. FC + 1.6809 MB. 1.23756%. Add + 135.824 MB in Total +Feature Memory Written per operator type: + 33.8578 MB. 38.1965%. Mul + 26.9881 MB. 30.4465%. Conv + 26.9508 MB. 30.4044%. SpatialBN + 0.840448 MB. 0.948147%. Add + 0.004 MB. 0.00451258%. FC + 88.6412 MB in Total +Parameter Memory per operator type: + 15.8248 MB. 74.9391%. Conv + 5.124 MB. 24.265%. FC + 0.168064 MB. 0.795877%. SpatialBN + 0 MB. 0%. Add + 0 MB. 0%. Mul + 21.1168 MB in Total +``` +### Optimized +``` +Main run finished. Milliseconds per iter: 46.0838. Iters per second: 21.6996 +Time per operator type: + 29.776 ms. 65.002%. Conv + 12.2803 ms. 26.8084%. Sigmoid + 3.15073 ms. 6.87815%. Mul + 0.328651 ms. 0.717456%. AveragePool + 0.186237 ms. 0.406563%. FC + 0.0832429 ms. 0.181722%. Add + 0.0026184 ms. 0.00571606%. Squeeze + 45.8078 ms in Total +FLOP per operator type: + 0.76907 GFLOP. 98.5601%. Conv + 0.00846444 GFLOP. 1.08476%. Mul + 0.002561 GFLOP. 0.328205%. FC + 0.000210112 GFLOP. 0.0269269%. Add + 0.780305 GFLOP in Total +Feature Memory Read per operator type: + 58.5253 MB. 53.8803%. Mul + 43.2855 MB. 39.8501%. Conv + 5.12912 MB. 4.72204%. FC + 1.6809 MB. 1.54749%. Add + 108.621 MB in Total +Feature Memory Written per operator type: + 33.8578 MB. 54.8834%. Mul + 26.9881 MB. 43.7477%. Conv + 0.840448 MB. 1.36237%. Add + 0.004 MB. 0.00648399%. FC + 61.6904 MB in Total +Parameter Memory per operator type: + 15.8248 MB. 75.5403%. Conv + 5.124 MB. 24.4597%. FC + 0 MB. 0%. Add + 0 MB. 0%. Mul + 20.9488 MB in Total +``` + +## EfficientNet-B1 +### Optimized +``` +Main run finished. Milliseconds per iter: 71.8102. Iters per second: 13.9256 +Time per operator type: + 45.7915 ms. 66.3206%. Conv + 17.8718 ms. 25.8841%. Sigmoid + 4.44132 ms. 6.43244%. Mul + 0.51001 ms. 0.738658%. AveragePool + 0.233283 ms. 0.337868%. Add + 0.194986 ms. 0.282402%. FC + 0.00268255 ms. 0.00388519%. Squeeze + 69.0456 ms in Total +FLOP per operator type: + 1.37105 GFLOP. 98.7673%. Conv + 0.0138759 GFLOP. 0.99959%. Mul + 0.002561 GFLOP. 0.184489%. FC + 0.000674432 GFLOP. 0.0485847%. Add + 1.38816 GFLOP in Total +Feature Memory Read per operator type: + 94.624 MB. 54.0789%. Mul + 69.8255 MB. 39.9062%. Conv + 5.39546 MB. 3.08357%. Add + 5.12912 MB. 2.93136%. FC + 174.974 MB in Total +Feature Memory Written per operator type: + 55.5035 MB. 54.555%. Mul + 43.5333 MB. 42.7894%. Conv + 2.69773 MB. 2.65163%. Add + 0.004 MB. 0.00393165%. FC + 101.739 MB in Total +Parameter Memory per operator type: + 25.7479 MB. 83.4024%. Conv + 5.124 MB. 16.5976%. FC + 0 MB. 0%. Add + 0 MB. 0%. Mul + 30.8719 MB in Total +``` + +## EfficientNet-B2 +### Optimized +``` +Main run finished. Milliseconds per iter: 92.28. Iters per second: 10.8366 +Time per operator type: + 61.4627 ms. 67.5845%. Conv + 22.7458 ms. 25.0113%. Sigmoid + 5.59931 ms. 6.15701%. Mul + 0.642567 ms. 0.706568%. AveragePool + 0.272795 ms. 0.299965%. Add + 0.216178 ms. 0.237709%. FC + 0.00268895 ms. 0.00295677%. Squeeze + 90.942 ms in Total +FLOP per operator type: + 1.98431 GFLOP. 98.9343%. Conv + 0.0177039 GFLOP. 0.882686%. Mul + 0.002817 GFLOP. 0.140451%. FC + 0.000853984 GFLOP. 0.0425782%. Add + 2.00568 GFLOP in Total +Feature Memory Read per operator type: + 120.609 MB. 54.9637%. Mul + 86.3512 MB. 39.3519%. Conv + 6.83187 MB. 3.11341%. Add + 5.64163 MB. 2.571%. FC + 219.433 MB in Total +Feature Memory Written per operator type: + 70.8155 MB. 54.6573%. Mul + 55.3273 MB. 42.7031%. Conv + 3.41594 MB. 2.63651%. Add + 0.004 MB. 0.00308731%. FC + 129.563 MB in Total +Parameter Memory per operator type: + 30.4721 MB. 84.3913%. Conv + 5.636 MB. 15.6087%. FC + 0 MB. 0%. Add + 0 MB. 0%. Mul + 36.1081 MB in Total +``` + +## MixNet-M +### Optimized +``` +Main run finished. Milliseconds per iter: 63.1122. Iters per second: 15.8448 +Time per operator type: + 48.1139 ms. 75.2052%. Conv + 7.1341 ms. 11.1511%. Sigmoid + 2.63706 ms. 4.12189%. SpatialBN + 1.73186 ms. 2.70701%. Mul + 1.38707 ms. 2.16809%. Split + 1.29322 ms. 2.02139%. Concat + 1.00093 ms. 1.56452%. Relu + 0.235309 ms. 0.367803%. Add + 0.221579 ms. 0.346343%. FC + 0.219315 ms. 0.342803%. AveragePool + 0.00250145 ms. 0.00390993%. Squeeze + 63.9768 ms in Total +FLOP per operator type: + 0.675273 GFLOP. 95.5827%. Conv + 0.0221072 GFLOP. 3.12921%. SpatialBN + 0.00538445 GFLOP. 0.762152%. Mul + 0.003073 GFLOP. 0.434973%. FC + 0.000642488 GFLOP. 0.0909421%. Add + 0 GFLOP. 0%. Concat + 0 GFLOP. 0%. Relu + 0.70648 GFLOP in Total +Feature Memory Read per operator type: + 46.8424 MB. 30.502%. Conv + 36.8626 MB. 24.0036%. Mul + 22.3152 MB. 14.5309%. SpatialBN + 22.1074 MB. 14.3955%. Concat + 14.1496 MB. 9.21372%. Relu + 6.15414 MB. 4.00735%. FC + 5.1399 MB. 3.34692%. Add + 153.571 MB in Total +Feature Memory Written per operator type: + 32.7672 MB. 28.4331%. Conv + 22.1072 MB. 19.1831%. Concat + 22.1072 MB. 19.1831%. SpatialBN + 21.5378 MB. 18.689%. Mul + 14.1496 MB. 12.2781%. Relu + 2.56995 MB. 2.23003%. Add + 0.004 MB. 0.00347092%. FC + 115.243 MB in Total +Parameter Memory per operator type: + 13.7059 MB. 68.674%. Conv + 6.148 MB. 30.8049%. FC + 0.104 MB. 0.521097%. SpatialBN + 0 MB. 0%. Add + 0 MB. 0%. Concat + 0 MB. 0%. Mul + 0 MB. 0%. Relu + 19.9579 MB in Total +``` + +## TF MobileNet-V3 Large 1.0 + +### Optimized +``` +Main run finished. Milliseconds per iter: 22.0495. Iters per second: 45.3525 +Time per operator type: + 17.437 ms. 80.0087%. Conv + 1.27662 ms. 5.8577%. Add + 1.12759 ms. 5.17387%. Div + 0.701155 ms. 3.21721%. Mul + 0.562654 ms. 2.58171%. Relu + 0.431144 ms. 1.97828%. Clip + 0.156902 ms. 0.719936%. FC + 0.0996858 ms. 0.457402%. AveragePool + 0.00112455 ms. 0.00515993%. Flatten + 21.7939 ms in Total +FLOP per operator type: + 0.43062 GFLOP. 98.1484%. Conv + 0.002561 GFLOP. 0.583713%. FC + 0.00210867 GFLOP. 0.480616%. Mul + 0.00193868 GFLOP. 0.441871%. Add + 0.00151532 GFLOP. 0.345377%. Div + 0 GFLOP. 0%. Relu + 0.438743 GFLOP in Total +Feature Memory Read per operator type: + 34.7967 MB. 43.9391%. Conv + 14.496 MB. 18.3046%. Mul + 9.44828 MB. 11.9307%. Add + 9.26157 MB. 11.6949%. Relu + 6.0614 MB. 7.65395%. Div + 5.12912 MB. 6.47673%. FC + 79.193 MB in Total +Feature Memory Written per operator type: + 17.6247 MB. 35.8656%. Conv + 9.26157 MB. 18.847%. Relu + 8.43469 MB. 17.1643%. Mul + 7.75472 MB. 15.7806%. Add + 6.06128 MB. 12.3345%. Div + 0.004 MB. 0.00813985%. FC + 49.1409 MB in Total +Parameter Memory per operator type: + 16.6851 MB. 76.5052%. Conv + 5.124 MB. 23.4948%. FC + 0 MB. 0%. Add + 0 MB. 0%. Div + 0 MB. 0%. Mul + 0 MB. 0%. Relu + 21.8091 MB in Total +``` + +## MobileNet-V3 (RW) + +### Unoptimized +``` +Main run finished. Milliseconds per iter: 24.8316. Iters per second: 40.2712 +Time per operator type: + 15.9266 ms. 69.2624%. Conv + 2.36551 ms. 10.2873%. SpatialBN + 1.39102 ms. 6.04936%. Add + 1.30327 ms. 5.66773%. Div + 0.737014 ms. 3.20517%. Mul + 0.639697 ms. 2.78195%. Relu + 0.375681 ms. 1.63378%. Clip + 0.153126 ms. 0.665921%. FC + 0.0993787 ms. 0.432184%. AveragePool + 0.0032632 ms. 0.0141912%. Squeeze + 22.9946 ms in Total +FLOP per operator type: + 0.430616 GFLOP. 94.4041%. Conv + 0.0175992 GFLOP. 3.85829%. SpatialBN + 0.002561 GFLOP. 0.561449%. FC + 0.00210961 GFLOP. 0.46249%. Mul + 0.00173891 GFLOP. 0.381223%. Add + 0.00151626 GFLOP. 0.33241%. Div + 0 GFLOP. 0%. Relu + 0.456141 GFLOP in Total +Feature Memory Read per operator type: + 34.7354 MB. 36.4363%. Conv + 17.7944 MB. 18.6658%. SpatialBN + 14.5035 MB. 15.2137%. Mul + 9.25778 MB. 9.71113%. Relu + 7.84641 MB. 8.23064%. Add + 6.06516 MB. 6.36216%. Div + 5.12912 MB. 5.38029%. FC + 95.3317 MB in Total +Feature Memory Written per operator type: + 17.6246 MB. 26.7264%. Conv + 17.5992 MB. 26.6878%. SpatialBN + 9.25778 MB. 14.0387%. Relu + 8.43843 MB. 12.7962%. Mul + 6.95565 MB. 10.5477%. Add + 6.06502 MB. 9.19713%. Div + 0.004 MB. 0.00606568%. FC + 65.9447 MB in Total +Parameter Memory per operator type: + 16.6778 MB. 76.1564%. Conv + 5.124 MB. 23.3979%. FC + 0.0976 MB. 0.445674%. SpatialBN + 0 MB. 0%. Add + 0 MB. 0%. Div + 0 MB. 0%. Mul + 0 MB. 0%. Relu + 21.8994 MB in Total + +``` +### Optimized + +``` +Main run finished. Milliseconds per iter: 22.0981. Iters per second: 45.2527 +Time per operator type: + 17.146 ms. 78.8965%. Conv + 1.38453 ms. 6.37084%. Add + 1.30991 ms. 6.02749%. Div + 0.685417 ms. 3.15391%. Mul + 0.532589 ms. 2.45068%. Relu + 0.418263 ms. 1.92461%. Clip + 0.15128 ms. 0.696106%. FC + 0.102065 ms. 0.469648%. AveragePool + 0.0022143 ms. 0.010189%. Squeeze + 21.7323 ms in Total +FLOP per operator type: + 0.430616 GFLOP. 98.1927%. Conv + 0.002561 GFLOP. 0.583981%. FC + 0.00210961 GFLOP. 0.481051%. Mul + 0.00173891 GFLOP. 0.396522%. Add + 0.00151626 GFLOP. 0.34575%. Div + 0 GFLOP. 0%. Relu + 0.438542 GFLOP in Total +Feature Memory Read per operator type: + 34.7842 MB. 44.833%. Conv + 14.5035 MB. 18.6934%. Mul + 9.25778 MB. 11.9323%. Relu + 7.84641 MB. 10.1132%. Add + 6.06516 MB. 7.81733%. Div + 5.12912 MB. 6.61087%. FC + 77.5861 MB in Total +Feature Memory Written per operator type: + 17.6246 MB. 36.4556%. Conv + 9.25778 MB. 19.1492%. Relu + 8.43843 MB. 17.4544%. Mul + 6.95565 MB. 14.3874%. Add + 6.06502 MB. 12.5452%. Div + 0.004 MB. 0.00827378%. FC + 48.3455 MB in Total +Parameter Memory per operator type: + 16.6778 MB. 76.4973%. Conv + 5.124 MB. 23.5027%. FC + 0 MB. 0%. Add + 0 MB. 0%. Div + 0 MB. 0%. Mul + 0 MB. 0%. Relu + 21.8018 MB in Total + +``` + +## MnasNet-A1 + +### Unoptimized +``` +Main run finished. Milliseconds per iter: 30.0892. Iters per second: 33.2345 +Time per operator type: + 24.4656 ms. 79.0905%. Conv + 4.14958 ms. 13.4144%. SpatialBN + 1.60598 ms. 5.19169%. Relu + 0.295219 ms. 0.95436%. Mul + 0.187609 ms. 0.606486%. FC + 0.120556 ms. 0.389724%. AveragePool + 0.09036 ms. 0.292109%. Add + 0.015727 ms. 0.050841%. Sigmoid + 0.00306205 ms. 0.00989875%. Squeeze + 30.9337 ms in Total +FLOP per operator type: + 0.620598 GFLOP. 95.6434%. Conv + 0.0248873 GFLOP. 3.8355%. SpatialBN + 0.002561 GFLOP. 0.394688%. FC + 0.000597408 GFLOP. 0.0920695%. Mul + 0.000222656 GFLOP. 0.0343146%. Add + 0 GFLOP. 0%. Relu + 0.648867 GFLOP in Total +Feature Memory Read per operator type: + 35.5457 MB. 38.4109%. Conv + 25.1552 MB. 27.1829%. SpatialBN + 22.5235 MB. 24.339%. Relu + 5.12912 MB. 5.54256%. FC + 2.40586 MB. 2.59978%. Mul + 1.78125 MB. 1.92483%. Add + 92.5406 MB in Total +Feature Memory Written per operator type: + 24.9042 MB. 32.9424%. Conv + 24.8873 MB. 32.92%. SpatialBN + 22.5235 MB. 29.7932%. Relu + 2.38963 MB. 3.16092%. Mul + 0.890624 MB. 1.17809%. Add + 0.004 MB. 0.00529106%. FC + 75.5993 MB in Total +Parameter Memory per operator type: + 10.2732 MB. 66.1459%. Conv + 5.124 MB. 32.9917%. FC + 0.133952 MB. 0.86247%. SpatialBN + 0 MB. 0%. Add + 0 MB. 0%. Mul + 0 MB. 0%. Relu + 15.5312 MB in Total +``` + +### Optimized +``` +Main run finished. Milliseconds per iter: 24.2367. Iters per second: 41.2597 +Time per operator type: + 22.0547 ms. 91.1375%. Conv + 1.49096 ms. 6.16116%. Relu + 0.253417 ms. 1.0472%. Mul + 0.18506 ms. 0.76473%. FC + 0.112942 ms. 0.466717%. AveragePool + 0.086769 ms. 0.358559%. Add + 0.0127889 ms. 0.0528479%. Sigmoid + 0.0027346 ms. 0.0113003%. Squeeze + 24.1994 ms in Total +FLOP per operator type: + 0.620598 GFLOP. 99.4581%. Conv + 0.002561 GFLOP. 0.41043%. FC + 0.000597408 GFLOP. 0.0957417%. Mul + 0.000222656 GFLOP. 0.0356832%. Add + 0 GFLOP. 0%. Relu + 0.623979 GFLOP in Total +Feature Memory Read per operator type: + 35.6127 MB. 52.7968%. Conv + 22.5235 MB. 33.3917%. Relu + 5.12912 MB. 7.60406%. FC + 2.40586 MB. 3.56675%. Mul + 1.78125 MB. 2.64075%. Add + 67.4524 MB in Total +Feature Memory Written per operator type: + 24.9042 MB. 49.1092%. Conv + 22.5235 MB. 44.4145%. Relu + 2.38963 MB. 4.71216%. Mul + 0.890624 MB. 1.75624%. Add + 0.004 MB. 0.00788768%. FC + 50.712 MB in Total +Parameter Memory per operator type: + 10.2732 MB. 66.7213%. Conv + 5.124 MB. 33.2787%. FC + 0 MB. 0%. Add + 0 MB. 0%. Mul + 0 MB. 0%. Relu + 15.3972 MB in Total +``` +## MnasNet-B1 + +### Unoptimized +``` +Main run finished. Milliseconds per iter: 28.3109. Iters per second: 35.322 +Time per operator type: + 29.1121 ms. 83.3081%. Conv + 4.14959 ms. 11.8746%. SpatialBN + 1.35823 ms. 3.88675%. Relu + 0.186188 ms. 0.532802%. FC + 0.116244 ms. 0.332647%. Add + 0.018641 ms. 0.0533437%. AveragePool + 0.0040904 ms. 0.0117052%. Squeeze + 34.9451 ms in Total +FLOP per operator type: + 0.626272 GFLOP. 96.2088%. Conv + 0.0218266 GFLOP. 3.35303%. SpatialBN + 0.002561 GFLOP. 0.393424%. FC + 0.000291648 GFLOP. 0.0448034%. Add + 0 GFLOP. 0%. Relu + 0.650951 GFLOP in Total +Feature Memory Read per operator type: + 34.4354 MB. 41.3788%. Conv + 22.1299 MB. 26.5921%. SpatialBN + 19.1923 MB. 23.0622%. Relu + 5.12912 MB. 6.16333%. FC + 2.33318 MB. 2.80364%. Add + 83.2199 MB in Total +Feature Memory Written per operator type: + 21.8266 MB. 34.0955%. Conv + 21.8266 MB. 34.0955%. SpatialBN + 19.1923 MB. 29.9805%. Relu + 1.16659 MB. 1.82234%. Add + 0.004 MB. 0.00624844%. FC + 64.016 MB in Total +Parameter Memory per operator type: + 12.2576 MB. 69.9104%. Conv + 5.124 MB. 29.2245%. FC + 0.15168 MB. 0.865099%. SpatialBN + 0 MB. 0%. Add + 0 MB. 0%. Relu + 17.5332 MB in Total +``` + +### Optimized +``` +Main run finished. Milliseconds per iter: 26.6364. Iters per second: 37.5426 +Time per operator type: + 24.9888 ms. 94.0962%. Conv + 1.26147 ms. 4.75011%. Relu + 0.176234 ms. 0.663619%. FC + 0.113309 ms. 0.426672%. Add + 0.0138708 ms. 0.0522311%. AveragePool + 0.00295685 ms. 0.0111341%. Squeeze + 26.5566 ms in Total +FLOP per operator type: + 0.626272 GFLOP. 99.5466%. Conv + 0.002561 GFLOP. 0.407074%. FC + 0.000291648 GFLOP. 0.0463578%. Add + 0 GFLOP. 0%. Relu + 0.629124 GFLOP in Total +Feature Memory Read per operator type: + 34.5112 MB. 56.4224%. Conv + 19.1923 MB. 31.3775%. Relu + 5.12912 MB. 8.3856%. FC + 2.33318 MB. 3.81452%. Add + 61.1658 MB in Total +Feature Memory Written per operator type: + 21.8266 MB. 51.7346%. Conv + 19.1923 MB. 45.4908%. Relu + 1.16659 MB. 2.76513%. Add + 0.004 MB. 0.00948104%. FC + 42.1895 MB in Total +Parameter Memory per operator type: + 12.2576 MB. 70.5205%. Conv + 5.124 MB. 29.4795%. FC + 0 MB. 0%. Add + 0 MB. 0%. Relu + 17.3816 MB in Total +``` diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/LICENSE b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/LICENSE new file mode 100644 index 00000000..80e7d155 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 Ross Wightman + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/README.md b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/README.md new file mode 100644 index 00000000..46336828 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/README.md @@ -0,0 +1,323 @@ +# (Generic) EfficientNets for PyTorch + +A 'generic' implementation of EfficientNet, MixNet, MobileNetV3, etc. that covers most of the compute/parameter efficient architectures derived from the MobileNet V1/V2 block sequence, including those found via automated neural architecture search. + +All models are implemented by GenEfficientNet or MobileNetV3 classes, with string based architecture definitions to configure the block layouts (idea from [here](https://github.com/tensorflow/tpu/blob/master/models/official/mnasnet/mnasnet_models.py)) + +## What's New + +### Aug 19, 2020 +* Add updated PyTorch trained EfficientNet-B3 weights trained by myself with `timm` (82.1 top-1) +* Add PyTorch trained EfficientNet-Lite0 contributed by [@hal-314](https://github.com/hal-314) (75.5 top-1) +* Update ONNX and Caffe2 export / utility scripts to work with latest PyTorch / ONNX +* ONNX runtime based validation script added +* activations (mostly) brought in sync with `timm` equivalents + + +### April 5, 2020 +* Add some newly trained MobileNet-V2 models trained with latest h-params, rand augment. They compare quite favourably to EfficientNet-Lite + * 3.5M param MobileNet-V2 100 @ 73% + * 4.5M param MobileNet-V2 110d @ 75% + * 6.1M param MobileNet-V2 140 @ 76.5% + * 5.8M param MobileNet-V2 120d @ 77.3% + +### March 23, 2020 + * Add EfficientNet-Lite models w/ weights ported from [Tensorflow TPU](https://github.com/tensorflow/tpu/tree/master/models/official/efficientnet/lite) + * Add PyTorch trained MobileNet-V3 Large weights with 75.77% top-1 + * IMPORTANT CHANGE (if training from scratch) - weight init changed to better match Tensorflow impl, set `fix_group_fanout=False` in `initialize_weight_goog` for old behavior + +### Feb 12, 2020 + * Add EfficientNet-L2 and B0-B7 NoisyStudent weights ported from [Tensorflow TPU](https://github.com/tensorflow/tpu/tree/master/models/official/efficientnet) + * Port new EfficientNet-B8 (RandAugment) weights from TF TPU, these are different than the B8 AdvProp, different input normalization. + * Add RandAugment PyTorch trained EfficientNet-ES (EdgeTPU-Small) weights with 78.1 top-1. Trained by [Andrew Lavin](https://github.com/andravin) + +### Jan 22, 2020 + * Update weights for EfficientNet B0, B2, B3 and MixNet-XL with latest RandAugment trained weights. Trained with (https://github.com/rwightman/pytorch-image-models) + * Fix torchscript compatibility for PyTorch 1.4, add torchscript support for MixedConv2d using ModuleDict + * Test models, torchscript, onnx export with PyTorch 1.4 -- no issues + +### Nov 22, 2019 + * New top-1 high! Ported official TF EfficientNet AdvProp (https://arxiv.org/abs/1911.09665) weights and B8 model spec. Created a new set of `ap` models since they use a different + preprocessing (Inception mean/std) from the original EfficientNet base/AA/RA weights. + +### Nov 15, 2019 + * Ported official TF MobileNet-V3 float32 large/small/minimalistic weights + * Modifications to MobileNet-V3 model and components to support some additional config needed for differences between TF MobileNet-V3 and mine + +### Oct 30, 2019 + * Many of the models will now work with torch.jit.script, MixNet being the biggest exception + * Improved interface for enabling torchscript or ONNX export compatible modes (via config) + * Add JIT optimized mem-efficient Swish/Mish autograd.fn in addition to memory-efficient autgrad.fn + * Activation factory to select best version of activation by name or override one globally + * Add pretrained checkpoint load helper that handles input conv and classifier changes + +### Oct 27, 2019 + * Add CondConv EfficientNet variants ported from https://github.com/tensorflow/tpu/tree/master/models/official/efficientnet/condconv + * Add RandAug weights for TF EfficientNet B5 and B7 from https://github.com/tensorflow/tpu/tree/master/models/official/efficientnet + * Bring over MixNet-XL model and depth scaling algo from my pytorch-image-models code base + * Switch activations and global pooling to modules + * Add memory-efficient Swish/Mish impl + * Add as_sequential() method to all models and allow as an argument in entrypoint fns + * Move MobileNetV3 into own file since it has a different head + * Remove ChamNet, MobileNet V2/V1 since they will likely never be used here + +## Models + +Implemented models include: + * EfficientNet NoisyStudent (B0-B7, L2) (https://arxiv.org/abs/1911.04252) + * EfficientNet AdvProp (B0-B8) (https://arxiv.org/abs/1911.09665) + * EfficientNet (B0-B8) (https://arxiv.org/abs/1905.11946) + * EfficientNet-EdgeTPU (S, M, L) (https://ai.googleblog.com/2019/08/efficientnet-edgetpu-creating.html) + * EfficientNet-CondConv (https://arxiv.org/abs/1904.04971) + * EfficientNet-Lite (https://github.com/tensorflow/tpu/tree/master/models/official/efficientnet/lite) + * MixNet (https://arxiv.org/abs/1907.09595) + * MNASNet B1, A1 (Squeeze-Excite), and Small (https://arxiv.org/abs/1807.11626) + * MobileNet-V3 (https://arxiv.org/abs/1905.02244) + * FBNet-C (https://arxiv.org/abs/1812.03443) + * Single-Path NAS (https://arxiv.org/abs/1904.02877) + +I originally implemented and trained some these models with code [here](https://github.com/rwightman/pytorch-image-models), this repository contains just the GenEfficientNet models, validation, and associated ONNX/Caffe2 export code. + +## Pretrained + +I've managed to train several of the models to accuracies close to or above the originating papers and official impl. My training code is here: https://github.com/rwightman/pytorch-image-models + + +|Model | Prec@1 (Err) | Prec@5 (Err) | Param#(M) | MAdds(M) | Image Scaling | Resolution | Crop | +|---|---|---|---|---|---|---|---| +| efficientnet_b3 | 82.240 (17.760) | 96.116 (3.884) | 12.23 | TBD | bicubic | 320 | 1.0 | +| efficientnet_b3 | 82.076 (17.924) | 96.020 (3.980) | 12.23 | TBD | bicubic | 300 | 0.904 | +| mixnet_xl | 81.074 (18.926) | 95.282 (4.718) | 11.90 | TBD | bicubic | 256 | 1.0 | +| efficientnet_b2 | 80.612 (19.388) | 95.318 (4.682) | 9.1 | TBD | bicubic | 288 | 1.0 | +| mixnet_xl | 80.476 (19.524) | 94.936 (5.064) | 11.90 | TBD | bicubic | 224 | 0.875 | +| efficientnet_b2 | 80.288 (19.712) | 95.166 (4.834) | 9.1 | 1003 | bicubic | 260 | 0.890 | +| mixnet_l | 78.976 (21.024 | 94.184 (5.816) | 7.33 | TBD | bicubic | 224 | 0.875 | +| efficientnet_b1 | 78.692 (21.308) | 94.086 (5.914) | 7.8 | 694 | bicubic | 240 | 0.882 | +| efficientnet_es | 78.066 (21.934) | 93.926 (6.074) | 5.44 | TBD | bicubic | 224 | 0.875 | +| efficientnet_b0 | 77.698 (22.302) | 93.532 (6.468) | 5.3 | 390 | bicubic | 224 | 0.875 | +| mobilenetv2_120d | 77.294 (22.706 | 93.502 (6.498) | 5.8 | TBD | bicubic | 224 | 0.875 | +| mixnet_m | 77.256 (22.744) | 93.418 (6.582) | 5.01 | 353 | bicubic | 224 | 0.875 | +| mobilenetv2_140 | 76.524 (23.476) | 92.990 (7.010) | 6.1 | TBD | bicubic | 224 | 0.875 | +| mixnet_s | 75.988 (24.012) | 92.794 (7.206) | 4.13 | TBD | bicubic | 224 | 0.875 | +| mobilenetv3_large_100 | 75.766 (24.234) | 92.542 (7.458) | 5.5 | TBD | bicubic | 224 | 0.875 | +| mobilenetv3_rw | 75.634 (24.366) | 92.708 (7.292) | 5.5 | 219 | bicubic | 224 | 0.875 | +| efficientnet_lite0 | 75.472 (24.528) | 92.520 (7.480) | 4.65 | TBD | bicubic | 224 | 0.875 | +| mnasnet_a1 | 75.448 (24.552) | 92.604 (7.396) | 3.9 | 312 | bicubic | 224 | 0.875 | +| fbnetc_100 | 75.124 (24.876) | 92.386 (7.614) | 5.6 | 385 | bilinear | 224 | 0.875 | +| mobilenetv2_110d | 75.052 (24.948) | 92.180 (7.820) | 4.5 | TBD | bicubic | 224 | 0.875 | +| mnasnet_b1 | 74.658 (25.342) | 92.114 (7.886) | 4.4 | 315 | bicubic | 224 | 0.875 | +| spnasnet_100 | 74.084 (25.916) | 91.818 (8.182) | 4.4 | TBD | bilinear | 224 | 0.875 | +| mobilenetv2_100 | 72.978 (27.022) | 91.016 (8.984) | 3.5 | TBD | bicubic | 224 | 0.875 | + + +More pretrained models to come... + + +## Ported Weights + +The weights ported from Tensorflow checkpoints for the EfficientNet models do pretty much match accuracy in Tensorflow once a SAME convolution padding equivalent is added, and the same crop factors, image scaling, etc (see table) are used via cmd line args. + +**IMPORTANT:** +* Tensorflow ported weights for EfficientNet AdvProp (AP), EfficientNet EdgeTPU, EfficientNet-CondConv, EfficientNet-Lite, and MobileNet-V3 models use Inception style (0.5, 0.5, 0.5) for mean and std. +* Enabling the Tensorflow preprocessing pipeline with `--tf-preprocessing` at validation time will improve scores by 0.1-0.5%, very close to original TF impl. + +To run validation for tf_efficientnet_b5: +`python validate.py /path/to/imagenet/validation/ --model tf_efficientnet_b5 -b 64 --img-size 456 --crop-pct 0.934 --interpolation bicubic` + +To run validation w/ TF preprocessing for tf_efficientnet_b5: +`python validate.py /path/to/imagenet/validation/ --model tf_efficientnet_b5 -b 64 --img-size 456 --tf-preprocessing` + +To run validation for a model with Inception preprocessing, ie EfficientNet-B8 AdvProp: +`python validate.py /path/to/imagenet/validation/ --model tf_efficientnet_b8_ap -b 48 --num-gpu 2 --img-size 672 --crop-pct 0.954 --mean 0.5 --std 0.5` + +|Model | Prec@1 (Err) | Prec@5 (Err) | Param # | Image Scaling | Image Size | Crop | +|---|---|---|---|---|---|---| +| tf_efficientnet_l2_ns *tfp | 88.352 (11.648) | 98.652 (1.348) | 480 | bicubic | 800 | N/A | +| tf_efficientnet_l2_ns | TBD | TBD | 480 | bicubic | 800 | 0.961 | +| tf_efficientnet_l2_ns_475 | 88.234 (11.766) | 98.546 (1.454) | 480 | bicubic | 475 | 0.936 | +| tf_efficientnet_l2_ns_475 *tfp | 88.172 (11.828) | 98.566 (1.434) | 480 | bicubic | 475 | N/A | +| tf_efficientnet_b7_ns *tfp | 86.844 (13.156) | 98.084 (1.916) | 66.35 | bicubic | 600 | N/A | +| tf_efficientnet_b7_ns | 86.840 (13.160) | 98.094 (1.906) | 66.35 | bicubic | 600 | N/A | +| tf_efficientnet_b6_ns | 86.452 (13.548) | 97.882 (2.118) | 43.04 | bicubic | 528 | N/A | +| tf_efficientnet_b6_ns *tfp | 86.444 (13.556) | 97.880 (2.120) | 43.04 | bicubic | 528 | N/A | +| tf_efficientnet_b5_ns *tfp | 86.064 (13.936) | 97.746 (2.254) | 30.39 | bicubic | 456 | N/A | +| tf_efficientnet_b5_ns | 86.088 (13.912) | 97.752 (2.248) | 30.39 | bicubic | 456 | N/A | +| tf_efficientnet_b8_ap *tfp | 85.436 (14.564) | 97.272 (2.728) | 87.4 | bicubic | 672 | N/A | +| tf_efficientnet_b8 *tfp | 85.384 (14.616) | 97.394 (2.606) | 87.4 | bicubic | 672 | N/A | +| tf_efficientnet_b8 | 85.370 (14.630) | 97.390 (2.610) | 87.4 | bicubic | 672 | 0.954 | +| tf_efficientnet_b8_ap | 85.368 (14.632) | 97.294 (2.706) | 87.4 | bicubic | 672 | 0.954 | +| tf_efficientnet_b4_ns *tfp | 85.298 (14.702) | 97.504 (2.496) | 19.34 | bicubic | 380 | N/A | +| tf_efficientnet_b4_ns | 85.162 (14.838) | 97.470 (2.530) | 19.34 | bicubic | 380 | 0.922 | +| tf_efficientnet_b7_ap *tfp | 85.154 (14.846) | 97.244 (2.756) | 66.35 | bicubic | 600 | N/A | +| tf_efficientnet_b7_ap | 85.118 (14.882) | 97.252 (2.748) | 66.35 | bicubic | 600 | 0.949 | +| tf_efficientnet_b7 *tfp | 84.940 (15.060) | 97.214 (2.786) | 66.35 | bicubic | 600 | N/A | +| tf_efficientnet_b7 | 84.932 (15.068) | 97.208 (2.792) | 66.35 | bicubic | 600 | 0.949 | +| tf_efficientnet_b6_ap | 84.786 (15.214) | 97.138 (2.862) | 43.04 | bicubic | 528 | 0.942 | +| tf_efficientnet_b6_ap *tfp | 84.760 (15.240) | 97.124 (2.876) | 43.04 | bicubic | 528 | N/A | +| tf_efficientnet_b5_ap *tfp | 84.276 (15.724) | 96.932 (3.068) | 30.39 | bicubic | 456 | N/A | +| tf_efficientnet_b5_ap | 84.254 (15.746) | 96.976 (3.024) | 30.39 | bicubic | 456 | 0.934 | +| tf_efficientnet_b6 *tfp | 84.140 (15.860) | 96.852 (3.148) | 43.04 | bicubic | 528 | N/A | +| tf_efficientnet_b6 | 84.110 (15.890) | 96.886 (3.114) | 43.04 | bicubic | 528 | 0.942 | +| tf_efficientnet_b3_ns *tfp | 84.054 (15.946) | 96.918 (3.082) | 12.23 | bicubic | 300 | N/A | +| tf_efficientnet_b3_ns | 84.048 (15.952) | 96.910 (3.090) | 12.23 | bicubic | 300 | .904 | +| tf_efficientnet_b5 *tfp | 83.822 (16.178) | 96.756 (3.244) | 30.39 | bicubic | 456 | N/A | +| tf_efficientnet_b5 | 83.812 (16.188) | 96.748 (3.252) | 30.39 | bicubic | 456 | 0.934 | +| tf_efficientnet_b4_ap *tfp | 83.278 (16.722) | 96.376 (3.624) | 19.34 | bicubic | 380 | N/A | +| tf_efficientnet_b4_ap | 83.248 (16.752) | 96.388 (3.612) | 19.34 | bicubic | 380 | 0.922 | +| tf_efficientnet_b4 | 83.022 (16.978) | 96.300 (3.700) | 19.34 | bicubic | 380 | 0.922 | +| tf_efficientnet_b4 *tfp | 82.948 (17.052) | 96.308 (3.692) | 19.34 | bicubic | 380 | N/A | +| tf_efficientnet_b2_ns *tfp | 82.436 (17.564) | 96.268 (3.732) | 9.11 | bicubic | 260 | N/A | +| tf_efficientnet_b2_ns | 82.380 (17.620) | 96.248 (3.752) | 9.11 | bicubic | 260 | 0.89 | +| tf_efficientnet_b3_ap *tfp | 81.882 (18.118) | 95.662 (4.338) | 12.23 | bicubic | 300 | N/A | +| tf_efficientnet_b3_ap | 81.828 (18.172) | 95.624 (4.376) | 12.23 | bicubic | 300 | 0.904 | +| tf_efficientnet_b3 | 81.636 (18.364) | 95.718 (4.282) | 12.23 | bicubic | 300 | 0.904 | +| tf_efficientnet_b3 *tfp | 81.576 (18.424) | 95.662 (4.338) | 12.23 | bicubic | 300 | N/A | +| tf_efficientnet_lite4 | 81.528 (18.472) | 95.668 (4.332) | 13.00 | bilinear | 380 | 0.92 | +| tf_efficientnet_b1_ns *tfp | 81.514 (18.486) | 95.776 (4.224) | 7.79 | bicubic | 240 | N/A | +| tf_efficientnet_lite4 *tfp | 81.502 (18.498) | 95.676 (4.324) | 13.00 | bilinear | 380 | N/A | +| tf_efficientnet_b1_ns | 81.388 (18.612) | 95.738 (4.262) | 7.79 | bicubic | 240 | 0.88 | +| tf_efficientnet_el | 80.534 (19.466) | 95.190 (4.810) | 10.59 | bicubic | 300 | 0.904 | +| tf_efficientnet_el *tfp | 80.476 (19.524) | 95.200 (4.800) | 10.59 | bicubic | 300 | N/A | +| tf_efficientnet_b2_ap *tfp | 80.420 (19.580) | 95.040 (4.960) | 9.11 | bicubic | 260 | N/A | +| tf_efficientnet_b2_ap | 80.306 (19.694) | 95.028 (4.972) | 9.11 | bicubic | 260 | 0.890 | +| tf_efficientnet_b2 *tfp | 80.188 (19.812) | 94.974 (5.026) | 9.11 | bicubic | 260 | N/A | +| tf_efficientnet_b2 | 80.086 (19.914) | 94.908 (5.092) | 9.11 | bicubic | 260 | 0.890 | +| tf_efficientnet_lite3 | 79.812 (20.188) | 94.914 (5.086) | 8.20 | bilinear | 300 | 0.904 | +| tf_efficientnet_lite3 *tfp | 79.734 (20.266) | 94.838 (5.162) | 8.20 | bilinear | 300 | N/A | +| tf_efficientnet_b1_ap *tfp | 79.532 (20.468) | 94.378 (5.622) | 7.79 | bicubic | 240 | N/A | +| tf_efficientnet_cc_b1_8e *tfp | 79.464 (20.536)| 94.492 (5.508) | 39.7 | bicubic | 240 | 0.88 | +| tf_efficientnet_cc_b1_8e | 79.298 (20.702) | 94.364 (5.636) | 39.7 | bicubic | 240 | 0.88 | +| tf_efficientnet_b1_ap | 79.278 (20.722) | 94.308 (5.692) | 7.79 | bicubic | 240 | 0.88 | +| tf_efficientnet_b1 *tfp | 79.172 (20.828) | 94.450 (5.550) | 7.79 | bicubic | 240 | N/A | +| tf_efficientnet_em *tfp | 78.958 (21.042) | 94.458 (5.542) | 6.90 | bicubic | 240 | N/A | +| tf_efficientnet_b0_ns *tfp | 78.806 (21.194) | 94.496 (5.504) | 5.29 | bicubic | 224 | N/A | +| tf_mixnet_l *tfp | 78.846 (21.154) | 94.212 (5.788) | 7.33 | bilinear | 224 | N/A | +| tf_efficientnet_b1 | 78.826 (21.174) | 94.198 (5.802) | 7.79 | bicubic | 240 | 0.88 | +| tf_mixnet_l | 78.770 (21.230) | 94.004 (5.996) | 7.33 | bicubic | 224 | 0.875 | +| tf_efficientnet_em | 78.742 (21.258) | 94.332 (5.668) | 6.90 | bicubic | 240 | 0.875 | +| tf_efficientnet_b0_ns | 78.658 (21.342) | 94.376 (5.624) | 5.29 | bicubic | 224 | 0.875 | +| tf_efficientnet_cc_b0_8e *tfp | 78.314 (21.686) | 93.790 (6.210) | 24.0 | bicubic | 224 | 0.875 | +| tf_efficientnet_cc_b0_8e | 77.908 (22.092) | 93.656 (6.344) | 24.0 | bicubic | 224 | 0.875 | +| tf_efficientnet_cc_b0_4e *tfp | 77.746 (22.254) | 93.552 (6.448) | 13.3 | bicubic | 224 | 0.875 | +| tf_efficientnet_cc_b0_4e | 77.304 (22.696) | 93.332 (6.668) | 13.3 | bicubic | 224 | 0.875 | +| tf_efficientnet_es *tfp | 77.616 (22.384) | 93.750 (6.250) | 5.44 | bicubic | 224 | N/A | +| tf_efficientnet_lite2 *tfp | 77.544 (22.456) | 93.800 (6.200) | 6.09 | bilinear | 260 | N/A | +| tf_efficientnet_lite2 | 77.460 (22.540) | 93.746 (6.254) | 6.09 | bicubic | 260 | 0.89 | +| tf_efficientnet_b0_ap *tfp | 77.514 (22.486) | 93.576 (6.424) | 5.29 | bicubic | 224 | N/A | +| tf_efficientnet_es | 77.264 (22.736) | 93.600 (6.400) | 5.44 | bicubic | 224 | N/A | +| tf_efficientnet_b0 *tfp | 77.258 (22.742) | 93.478 (6.522) | 5.29 | bicubic | 224 | N/A | +| tf_efficientnet_b0_ap | 77.084 (22.916) | 93.254 (6.746) | 5.29 | bicubic | 224 | 0.875 | +| tf_mixnet_m *tfp | 77.072 (22.928) | 93.368 (6.632) | 5.01 | bilinear | 224 | N/A | +| tf_mixnet_m | 76.950 (23.050) | 93.156 (6.844) | 5.01 | bicubic | 224 | 0.875 | +| tf_efficientnet_b0 | 76.848 (23.152) | 93.228 (6.772) | 5.29 | bicubic | 224 | 0.875 | +| tf_efficientnet_lite1 *tfp | 76.764 (23.236) | 93.326 (6.674) | 5.42 | bilinear | 240 | N/A | +| tf_efficientnet_lite1 | 76.638 (23.362) | 93.232 (6.768) | 5.42 | bicubic | 240 | 0.882 | +| tf_mixnet_s *tfp | 75.800 (24.200) | 92.788 (7.212) | 4.13 | bilinear | 224 | N/A | +| tf_mobilenetv3_large_100 *tfp | 75.768 (24.232) | 92.710 (7.290) | 5.48 | bilinear | 224 | N/A | +| tf_mixnet_s | 75.648 (24.352) | 92.636 (7.364) | 4.13 | bicubic | 224 | 0.875 | +| tf_mobilenetv3_large_100 | 75.516 (24.484) | 92.600 (7.400) | 5.48 | bilinear | 224 | 0.875 | +| tf_efficientnet_lite0 *tfp | 75.074 (24.926) | 92.314 (7.686) | 4.65 | bilinear | 224 | N/A | +| tf_efficientnet_lite0 | 74.842 (25.158) | 92.170 (7.830) | 4.65 | bicubic | 224 | 0.875 | +| tf_mobilenetv3_large_075 *tfp | 73.730 (26.270) | 91.616 (8.384) | 3.99 | bilinear | 224 |N/A | +| tf_mobilenetv3_large_075 | 73.442 (26.558) | 91.352 (8.648) | 3.99 | bilinear | 224 | 0.875 | +| tf_mobilenetv3_large_minimal_100 *tfp | 72.678 (27.322) | 90.860 (9.140) | 3.92 | bilinear | 224 | N/A | +| tf_mobilenetv3_large_minimal_100 | 72.244 (27.756) | 90.636 (9.364) | 3.92 | bilinear | 224 | 0.875 | +| tf_mobilenetv3_small_100 *tfp | 67.918 (32.082) | 87.958 (12.042 | 2.54 | bilinear | 224 | N/A | +| tf_mobilenetv3_small_100 | 67.918 (32.082) | 87.662 (12.338) | 2.54 | bilinear | 224 | 0.875 | +| tf_mobilenetv3_small_075 *tfp | 66.142 (33.858) | 86.498 (13.502) | 2.04 | bilinear | 224 | N/A | +| tf_mobilenetv3_small_075 | 65.718 (34.282) | 86.136 (13.864) | 2.04 | bilinear | 224 | 0.875 | +| tf_mobilenetv3_small_minimal_100 *tfp | 63.378 (36.622) | 84.802 (15.198) | 2.04 | bilinear | 224 | N/A | +| tf_mobilenetv3_small_minimal_100 | 62.898 (37.102) | 84.230 (15.770) | 2.04 | bilinear | 224 | 0.875 | + + +*tfp models validated with `tf-preprocessing` pipeline + +Google tf and tflite weights ported from official Tensorflow repositories +* https://github.com/tensorflow/tpu/tree/master/models/official/mnasnet +* https://github.com/tensorflow/tpu/tree/master/models/official/efficientnet +* https://github.com/tensorflow/models/tree/master/research/slim/nets/mobilenet + +## Usage + +### Environment + +All development and testing has been done in Conda Python 3 environments on Linux x86-64 systems, specifically Python 3.6.x, 3.7.x, 3.8.x. + +Users have reported that a Python 3 Anaconda install in Windows works. I have not verified this myself. + +PyTorch versions 1.4, 1.5, 1.6 have been tested with this code. + +I've tried to keep the dependencies minimal, the setup is as per the PyTorch default install instructions for Conda: +``` +conda create -n torch-env +conda activate torch-env +conda install -c pytorch pytorch torchvision cudatoolkit=10.2 +``` + +### PyTorch Hub + +Models can be accessed via the PyTorch Hub API + +``` +>>> torch.hub.list('rwightman/gen-efficientnet-pytorch') +['efficientnet_b0', ...] +>>> model = torch.hub.load('rwightman/gen-efficientnet-pytorch', 'efficientnet_b0', pretrained=True) +>>> model.eval() +>>> output = model(torch.randn(1,3,224,224)) +``` + +### Pip +This package can be installed via pip. + +Install (after conda env/install): +``` +pip install geffnet +``` + +Eval use: +``` +>>> import geffnet +>>> m = geffnet.create_model('mobilenetv3_large_100', pretrained=True) +>>> m.eval() +``` + +Train use: +``` +>>> import geffnet +>>> # models can also be created by using the entrypoint directly +>>> m = geffnet.efficientnet_b2(pretrained=True, drop_rate=0.25, drop_connect_rate=0.2) +>>> m.train() +``` + +Create in a nn.Sequential container, for fast.ai, etc: +``` +>>> import geffnet +>>> m = geffnet.mixnet_l(pretrained=True, drop_rate=0.25, drop_connect_rate=0.2, as_sequential=True) +``` + +### Exporting + +Scripts are included to +* export models to ONNX (`onnx_export.py`) +* optimized ONNX graph (`onnx_optimize.py` or `onnx_validate.py` w/ `--onnx-output-opt` arg) +* validate with ONNX runtime (`onnx_validate.py`) +* convert ONNX model to Caffe2 (`onnx_to_caffe.py`) +* validate in Caffe2 (`caffe2_validate.py`) +* benchmark in Caffe2 w/ FLOPs, parameters output (`caffe2_benchmark.py`) + +As an example, to export the MobileNet-V3 pretrained model and then run an Imagenet validation: +``` +python onnx_export.py --model mobilenetv3_large_100 ./mobilenetv3_100.onnx +python onnx_validate.py /imagenet/validation/ --onnx-input ./mobilenetv3_100.onnx +``` + +These scripts were tested to be working as of PyTorch 1.6 and ONNX 1.7 w/ ONNX runtime 1.4. Caffe2 compatible +export now requires additional args mentioned in the export script (not needed in earlier versions). + +#### Export Notes +1. The TF ported weights with the 'SAME' conv padding activated cannot be exported to ONNX unless `_EXPORTABLE` flag in `config.py` is set to True. Use `config.set_exportable(True)` as in the `onnx_export.py` script. +2. TF ported models with 'SAME' padding will have the padding fixed at export time to the resolution used for export. Even though dynamic padding is supported in opset >= 11, I can't get it working. +3. ONNX optimize facility doesn't work reliably in PyTorch 1.6 / ONNX 1.7. Fortunately, the onnxruntime based inference is working very well now and includes on the fly optimization. +3. ONNX / Caffe2 export/import frequently breaks with different PyTorch and ONNX version releases. Please check their respective issue trackers before filing issues here. + + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/caffe2_benchmark.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/caffe2_benchmark.py new file mode 100644 index 00000000..93f28a1e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/caffe2_benchmark.py @@ -0,0 +1,65 @@ +""" Caffe2 validation script + +This script runs Caffe2 benchmark on exported ONNX model. +It is a useful tool for reporting model FLOPS. + +Copyright 2020 Ross Wightman +""" +import argparse +from caffe2.python import core, workspace, model_helper +from caffe2.proto import caffe2_pb2 + + +parser = argparse.ArgumentParser(description='Caffe2 Model Benchmark') +parser.add_argument('--c2-prefix', default='', type=str, metavar='NAME', + help='caffe2 model pb name prefix') +parser.add_argument('--c2-init', default='', type=str, metavar='PATH', + help='caffe2 model init .pb') +parser.add_argument('--c2-predict', default='', type=str, metavar='PATH', + help='caffe2 model predict .pb') +parser.add_argument('-b', '--batch-size', default=1, type=int, + metavar='N', help='mini-batch size (default: 1)') +parser.add_argument('--img-size', default=224, type=int, + metavar='N', help='Input image dimension, uses model default if empty') + + +def main(): + args = parser.parse_args() + args.gpu_id = 0 + if args.c2_prefix: + args.c2_init = args.c2_prefix + '.init.pb' + args.c2_predict = args.c2_prefix + '.predict.pb' + + model = model_helper.ModelHelper(name="le_net", init_params=False) + + # Bring in the init net from init_net.pb + init_net_proto = caffe2_pb2.NetDef() + with open(args.c2_init, "rb") as f: + init_net_proto.ParseFromString(f.read()) + model.param_init_net = core.Net(init_net_proto) + + # bring in the predict net from predict_net.pb + predict_net_proto = caffe2_pb2.NetDef() + with open(args.c2_predict, "rb") as f: + predict_net_proto.ParseFromString(f.read()) + model.net = core.Net(predict_net_proto) + + # CUDA performance not impressive + #device_opts = core.DeviceOption(caffe2_pb2.PROTO_CUDA, args.gpu_id) + #model.net.RunAllOnGPU(gpu_id=args.gpu_id, use_cudnn=True) + #model.param_init_net.RunAllOnGPU(gpu_id=args.gpu_id, use_cudnn=True) + + input_blob = model.net.external_inputs[0] + model.param_init_net.GaussianFill( + [], + input_blob.GetUnscopedName(), + shape=(args.batch_size, 3, args.img_size, args.img_size), + mean=0.0, + std=1.0) + workspace.RunNetOnce(model.param_init_net) + workspace.CreateNet(model.net, overwrite=True) + workspace.BenchmarkNet(model.net.Proto().name, 5, 20, True) + + +if __name__ == '__main__': + main() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/caffe2_validate.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/caffe2_validate.py new file mode 100644 index 00000000..7cfaab38 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/caffe2_validate.py @@ -0,0 +1,138 @@ +""" Caffe2 validation script + +This script is created to verify exported ONNX models running in Caffe2 +It utilizes the same PyTorch dataloader/processing pipeline for a +fair comparison against the originals. + +Copyright 2020 Ross Wightman +""" +import argparse +import numpy as np +from caffe2.python import core, workspace, model_helper +from caffe2.proto import caffe2_pb2 +from data import create_loader, resolve_data_config, Dataset +from utils import AverageMeter +import time + +parser = argparse.ArgumentParser(description='Caffe2 ImageNet Validation') +parser.add_argument('data', metavar='DIR', + help='path to dataset') +parser.add_argument('--c2-prefix', default='', type=str, metavar='NAME', + help='caffe2 model pb name prefix') +parser.add_argument('--c2-init', default='', type=str, metavar='PATH', + help='caffe2 model init .pb') +parser.add_argument('--c2-predict', default='', type=str, metavar='PATH', + help='caffe2 model predict .pb') +parser.add_argument('-j', '--workers', default=2, type=int, metavar='N', + help='number of data loading workers (default: 2)') +parser.add_argument('-b', '--batch-size', default=256, type=int, + metavar='N', help='mini-batch size (default: 256)') +parser.add_argument('--img-size', default=None, type=int, + metavar='N', help='Input image dimension, uses model default if empty') +parser.add_argument('--mean', type=float, nargs='+', default=None, metavar='MEAN', + help='Override mean pixel value of dataset') +parser.add_argument('--std', type=float, nargs='+', default=None, metavar='STD', + help='Override std deviation of of dataset') +parser.add_argument('--crop-pct', type=float, default=None, metavar='PCT', + help='Override default crop pct of 0.875') +parser.add_argument('--interpolation', default='', type=str, metavar='NAME', + help='Image resize interpolation type (overrides model)') +parser.add_argument('--tf-preprocessing', dest='tf_preprocessing', action='store_true', + help='use tensorflow mnasnet preporcessing') +parser.add_argument('--print-freq', '-p', default=10, type=int, + metavar='N', help='print frequency (default: 10)') + + +def main(): + args = parser.parse_args() + args.gpu_id = 0 + if args.c2_prefix: + args.c2_init = args.c2_prefix + '.init.pb' + args.c2_predict = args.c2_prefix + '.predict.pb' + + model = model_helper.ModelHelper(name="validation_net", init_params=False) + + # Bring in the init net from init_net.pb + init_net_proto = caffe2_pb2.NetDef() + with open(args.c2_init, "rb") as f: + init_net_proto.ParseFromString(f.read()) + model.param_init_net = core.Net(init_net_proto) + + # bring in the predict net from predict_net.pb + predict_net_proto = caffe2_pb2.NetDef() + with open(args.c2_predict, "rb") as f: + predict_net_proto.ParseFromString(f.read()) + model.net = core.Net(predict_net_proto) + + data_config = resolve_data_config(None, args) + loader = create_loader( + Dataset(args.data, load_bytes=args.tf_preprocessing), + input_size=data_config['input_size'], + batch_size=args.batch_size, + use_prefetcher=False, + interpolation=data_config['interpolation'], + mean=data_config['mean'], + std=data_config['std'], + num_workers=args.workers, + crop_pct=data_config['crop_pct'], + tensorflow_preprocessing=args.tf_preprocessing) + + # this is so obvious, wonderful interface + input_blob = model.net.external_inputs[0] + output_blob = model.net.external_outputs[0] + + if True: + device_opts = None + else: + # CUDA is crashing, no idea why, awesome error message, give it a try for kicks + device_opts = core.DeviceOption(caffe2_pb2.PROTO_CUDA, args.gpu_id) + model.net.RunAllOnGPU(gpu_id=args.gpu_id, use_cudnn=True) + model.param_init_net.RunAllOnGPU(gpu_id=args.gpu_id, use_cudnn=True) + + model.param_init_net.GaussianFill( + [], input_blob.GetUnscopedName(), + shape=(1,) + data_config['input_size'], mean=0.0, std=1.0) + workspace.RunNetOnce(model.param_init_net) + workspace.CreateNet(model.net, overwrite=True) + + batch_time = AverageMeter() + top1 = AverageMeter() + top5 = AverageMeter() + end = time.time() + for i, (input, target) in enumerate(loader): + # run the net and return prediction + caffe2_in = input.data.numpy() + workspace.FeedBlob(input_blob, caffe2_in, device_opts) + workspace.RunNet(model.net, num_iter=1) + output = workspace.FetchBlob(output_blob) + + # measure accuracy and record loss + prec1, prec5 = accuracy_np(output.data, target.numpy()) + top1.update(prec1.item(), input.size(0)) + top5.update(prec5.item(), input.size(0)) + + # measure elapsed time + batch_time.update(time.time() - end) + end = time.time() + + if i % args.print_freq == 0: + print('Test: [{0}/{1}]\t' + 'Time {batch_time.val:.3f} ({batch_time.avg:.3f}, {rate_avg:.3f}/s, {ms_avg:.3f} ms/sample) \t' + 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})\t' + 'Prec@5 {top5.val:.3f} ({top5.avg:.3f})'.format( + i, len(loader), batch_time=batch_time, rate_avg=input.size(0) / batch_time.avg, + ms_avg=100 * batch_time.avg / input.size(0), top1=top1, top5=top5)) + + print(' * Prec@1 {top1.avg:.3f} ({top1a:.3f}) Prec@5 {top5.avg:.3f} ({top5a:.3f})'.format( + top1=top1, top1a=100-top1.avg, top5=top5, top5a=100.-top5.avg)) + + +def accuracy_np(output, target): + max_indices = np.argsort(output, axis=1)[:, ::-1] + top5 = 100 * np.equal(max_indices[:, :5], target[:, np.newaxis]).sum(axis=1).mean() + top1 = 100 * np.equal(max_indices[:, 0], target).mean() + return top1, top5 + + +if __name__ == '__main__': + main() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/__init__.py new file mode 100644 index 00000000..2e441a58 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/__init__.py @@ -0,0 +1,5 @@ +from .gen_efficientnet import * +from .mobilenetv3 import * +from .model_factory import create_model +from .config import is_exportable, is_scriptable, set_exportable, set_scriptable +from .activations import * \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/activations/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/activations/__init__.py new file mode 100644 index 00000000..813421a7 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/activations/__init__.py @@ -0,0 +1,137 @@ +from geffnet import config +from geffnet.activations.activations_me import * +from geffnet.activations.activations_jit import * +from geffnet.activations.activations import * +import torch + +_has_silu = 'silu' in dir(torch.nn.functional) + +_ACT_FN_DEFAULT = dict( + silu=F.silu if _has_silu else swish, + swish=F.silu if _has_silu else swish, + mish=mish, + relu=F.relu, + relu6=F.relu6, + sigmoid=sigmoid, + tanh=tanh, + hard_sigmoid=hard_sigmoid, + hard_swish=hard_swish, +) + +_ACT_FN_JIT = dict( + silu=F.silu if _has_silu else swish_jit, + swish=F.silu if _has_silu else swish_jit, + mish=mish_jit, +) + +_ACT_FN_ME = dict( + silu=F.silu if _has_silu else swish_me, + swish=F.silu if _has_silu else swish_me, + mish=mish_me, + hard_swish=hard_swish_me, + hard_sigmoid_jit=hard_sigmoid_me, +) + +_ACT_LAYER_DEFAULT = dict( + silu=nn.SiLU if _has_silu else Swish, + swish=nn.SiLU if _has_silu else Swish, + mish=Mish, + relu=nn.ReLU, + relu6=nn.ReLU6, + sigmoid=Sigmoid, + tanh=Tanh, + hard_sigmoid=HardSigmoid, + hard_swish=HardSwish, +) + +_ACT_LAYER_JIT = dict( + silu=nn.SiLU if _has_silu else SwishJit, + swish=nn.SiLU if _has_silu else SwishJit, + mish=MishJit, +) + +_ACT_LAYER_ME = dict( + silu=nn.SiLU if _has_silu else SwishMe, + swish=nn.SiLU if _has_silu else SwishMe, + mish=MishMe, + hard_swish=HardSwishMe, + hard_sigmoid=HardSigmoidMe +) + +_OVERRIDE_FN = dict() +_OVERRIDE_LAYER = dict() + + +def add_override_act_fn(name, fn): + global _OVERRIDE_FN + _OVERRIDE_FN[name] = fn + + +def update_override_act_fn(overrides): + assert isinstance(overrides, dict) + global _OVERRIDE_FN + _OVERRIDE_FN.update(overrides) + + +def clear_override_act_fn(): + global _OVERRIDE_FN + _OVERRIDE_FN = dict() + + +def add_override_act_layer(name, fn): + _OVERRIDE_LAYER[name] = fn + + +def update_override_act_layer(overrides): + assert isinstance(overrides, dict) + global _OVERRIDE_LAYER + _OVERRIDE_LAYER.update(overrides) + + +def clear_override_act_layer(): + global _OVERRIDE_LAYER + _OVERRIDE_LAYER = dict() + + +def get_act_fn(name='relu'): + """ Activation Function Factory + Fetching activation fns by name with this function allows export or torch script friendly + functions to be returned dynamically based on current config. + """ + if name in _OVERRIDE_FN: + return _OVERRIDE_FN[name] + use_me = not (config.is_exportable() or config.is_scriptable() or config.is_no_jit()) + if use_me and name in _ACT_FN_ME: + # If not exporting or scripting the model, first look for a memory optimized version + # activation with custom autograd, then fallback to jit scripted, then a Python or Torch builtin + return _ACT_FN_ME[name] + if config.is_exportable() and name in ('silu', 'swish'): + # FIXME PyTorch SiLU doesn't ONNX export, this is a temp hack + return swish + use_jit = not (config.is_exportable() or config.is_no_jit()) + # NOTE: export tracing should work with jit scripted components, but I keep running into issues + if use_jit and name in _ACT_FN_JIT: # jit scripted models should be okay for export/scripting + return _ACT_FN_JIT[name] + return _ACT_FN_DEFAULT[name] + + +def get_act_layer(name='relu'): + """ Activation Layer Factory + Fetching activation layers by name with this function allows export or torch script friendly + functions to be returned dynamically based on current config. + """ + if name in _OVERRIDE_LAYER: + return _OVERRIDE_LAYER[name] + use_me = not (config.is_exportable() or config.is_scriptable() or config.is_no_jit()) + if use_me and name in _ACT_LAYER_ME: + return _ACT_LAYER_ME[name] + if config.is_exportable() and name in ('silu', 'swish'): + # FIXME PyTorch SiLU doesn't ONNX export, this is a temp hack + return Swish + use_jit = not (config.is_exportable() or config.is_no_jit()) + # NOTE: export tracing should work with jit scripted components, but I keep running into issues + if use_jit and name in _ACT_FN_JIT: # jit scripted models should be okay for export/scripting + return _ACT_LAYER_JIT[name] + return _ACT_LAYER_DEFAULT[name] + + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/activations/activations.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/activations/activations.py new file mode 100644 index 00000000..bdea692d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/activations/activations.py @@ -0,0 +1,102 @@ +""" Activations + +A collection of activations fn and modules with a common interface so that they can +easily be swapped. All have an `inplace` arg even if not used. + +Copyright 2020 Ross Wightman +""" +from torch import nn as nn +from torch.nn import functional as F + + +def swish(x, inplace: bool = False): + """Swish - Described originally as SiLU (https://arxiv.org/abs/1702.03118v3) + and also as Swish (https://arxiv.org/abs/1710.05941). + + TODO Rename to SiLU with addition to PyTorch + """ + return x.mul_(x.sigmoid()) if inplace else x.mul(x.sigmoid()) + + +class Swish(nn.Module): + def __init__(self, inplace: bool = False): + super(Swish, self).__init__() + self.inplace = inplace + + def forward(self, x): + return swish(x, self.inplace) + + +def mish(x, inplace: bool = False): + """Mish: A Self Regularized Non-Monotonic Neural Activation Function - https://arxiv.org/abs/1908.08681 + """ + return x.mul(F.softplus(x).tanh()) + + +class Mish(nn.Module): + def __init__(self, inplace: bool = False): + super(Mish, self).__init__() + self.inplace = inplace + + def forward(self, x): + return mish(x, self.inplace) + + +def sigmoid(x, inplace: bool = False): + return x.sigmoid_() if inplace else x.sigmoid() + + +# PyTorch has this, but not with a consistent inplace argmument interface +class Sigmoid(nn.Module): + def __init__(self, inplace: bool = False): + super(Sigmoid, self).__init__() + self.inplace = inplace + + def forward(self, x): + return x.sigmoid_() if self.inplace else x.sigmoid() + + +def tanh(x, inplace: bool = False): + return x.tanh_() if inplace else x.tanh() + + +# PyTorch has this, but not with a consistent inplace argmument interface +class Tanh(nn.Module): + def __init__(self, inplace: bool = False): + super(Tanh, self).__init__() + self.inplace = inplace + + def forward(self, x): + return x.tanh_() if self.inplace else x.tanh() + + +def hard_swish(x, inplace: bool = False): + inner = F.relu6(x + 3.).div_(6.) + return x.mul_(inner) if inplace else x.mul(inner) + + +class HardSwish(nn.Module): + def __init__(self, inplace: bool = False): + super(HardSwish, self).__init__() + self.inplace = inplace + + def forward(self, x): + return hard_swish(x, self.inplace) + + +def hard_sigmoid(x, inplace: bool = False): + if inplace: + return x.add_(3.).clamp_(0., 6.).div_(6.) + else: + return F.relu6(x + 3.) / 6. + + +class HardSigmoid(nn.Module): + def __init__(self, inplace: bool = False): + super(HardSigmoid, self).__init__() + self.inplace = inplace + + def forward(self, x): + return hard_sigmoid(x, self.inplace) + + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/activations/activations_jit.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/activations/activations_jit.py new file mode 100644 index 00000000..7176b05e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/activations/activations_jit.py @@ -0,0 +1,79 @@ +""" Activations (jit) + +A collection of jit-scripted activations fn and modules with a common interface so that they can +easily be swapped. All have an `inplace` arg even if not used. + +All jit scripted activations are lacking in-place variations on purpose, scripted kernel fusion does not +currently work across in-place op boundaries, thus performance is equal to or less than the non-scripted +versions if they contain in-place ops. + +Copyright 2020 Ross Wightman +""" + +import torch +from torch import nn as nn +from torch.nn import functional as F + +__all__ = ['swish_jit', 'SwishJit', 'mish_jit', 'MishJit', + 'hard_sigmoid_jit', 'HardSigmoidJit', 'hard_swish_jit', 'HardSwishJit'] + + +@torch.jit.script +def swish_jit(x, inplace: bool = False): + """Swish - Described originally as SiLU (https://arxiv.org/abs/1702.03118v3) + and also as Swish (https://arxiv.org/abs/1710.05941). + + TODO Rename to SiLU with addition to PyTorch + """ + return x.mul(x.sigmoid()) + + +@torch.jit.script +def mish_jit(x, _inplace: bool = False): + """Mish: A Self Regularized Non-Monotonic Neural Activation Function - https://arxiv.org/abs/1908.08681 + """ + return x.mul(F.softplus(x).tanh()) + + +class SwishJit(nn.Module): + def __init__(self, inplace: bool = False): + super(SwishJit, self).__init__() + + def forward(self, x): + return swish_jit(x) + + +class MishJit(nn.Module): + def __init__(self, inplace: bool = False): + super(MishJit, self).__init__() + + def forward(self, x): + return mish_jit(x) + + +@torch.jit.script +def hard_sigmoid_jit(x, inplace: bool = False): + # return F.relu6(x + 3.) / 6. + return (x + 3).clamp(min=0, max=6).div(6.) # clamp seems ever so slightly faster? + + +class HardSigmoidJit(nn.Module): + def __init__(self, inplace: bool = False): + super(HardSigmoidJit, self).__init__() + + def forward(self, x): + return hard_sigmoid_jit(x) + + +@torch.jit.script +def hard_swish_jit(x, inplace: bool = False): + # return x * (F.relu6(x + 3.) / 6) + return x * (x + 3).clamp(min=0, max=6).div(6.) # clamp seems ever so slightly faster? + + +class HardSwishJit(nn.Module): + def __init__(self, inplace: bool = False): + super(HardSwishJit, self).__init__() + + def forward(self, x): + return hard_swish_jit(x) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/activations/activations_me.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/activations/activations_me.py new file mode 100644 index 00000000..e91df5a5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/activations/activations_me.py @@ -0,0 +1,174 @@ +""" Activations (memory-efficient w/ custom autograd) + +A collection of activations fn and modules with a common interface so that they can +easily be swapped. All have an `inplace` arg even if not used. + +These activations are not compatible with jit scripting or ONNX export of the model, please use either +the JIT or basic versions of the activations. + +Copyright 2020 Ross Wightman +""" + +import torch +from torch import nn as nn +from torch.nn import functional as F + + +__all__ = ['swish_me', 'SwishMe', 'mish_me', 'MishMe', + 'hard_sigmoid_me', 'HardSigmoidMe', 'hard_swish_me', 'HardSwishMe'] + + +@torch.jit.script +def swish_jit_fwd(x): + return x.mul(torch.sigmoid(x)) + + +@torch.jit.script +def swish_jit_bwd(x, grad_output): + x_sigmoid = torch.sigmoid(x) + return grad_output * (x_sigmoid * (1 + x * (1 - x_sigmoid))) + + +class SwishJitAutoFn(torch.autograd.Function): + """ torch.jit.script optimised Swish w/ memory-efficient checkpoint + Inspired by conversation btw Jeremy Howard & Adam Pazske + https://twitter.com/jeremyphoward/status/1188251041835315200 + + Swish - Described originally as SiLU (https://arxiv.org/abs/1702.03118v3) + and also as Swish (https://arxiv.org/abs/1710.05941). + + TODO Rename to SiLU with addition to PyTorch + """ + + @staticmethod + def forward(ctx, x): + ctx.save_for_backward(x) + return swish_jit_fwd(x) + + @staticmethod + def backward(ctx, grad_output): + x = ctx.saved_tensors[0] + return swish_jit_bwd(x, grad_output) + + +def swish_me(x, inplace=False): + return SwishJitAutoFn.apply(x) + + +class SwishMe(nn.Module): + def __init__(self, inplace: bool = False): + super(SwishMe, self).__init__() + + def forward(self, x): + return SwishJitAutoFn.apply(x) + + +@torch.jit.script +def mish_jit_fwd(x): + return x.mul(torch.tanh(F.softplus(x))) + + +@torch.jit.script +def mish_jit_bwd(x, grad_output): + x_sigmoid = torch.sigmoid(x) + x_tanh_sp = F.softplus(x).tanh() + return grad_output.mul(x_tanh_sp + x * x_sigmoid * (1 - x_tanh_sp * x_tanh_sp)) + + +class MishJitAutoFn(torch.autograd.Function): + """ Mish: A Self Regularized Non-Monotonic Neural Activation Function - https://arxiv.org/abs/1908.08681 + A memory efficient, jit scripted variant of Mish + """ + @staticmethod + def forward(ctx, x): + ctx.save_for_backward(x) + return mish_jit_fwd(x) + + @staticmethod + def backward(ctx, grad_output): + x = ctx.saved_tensors[0] + return mish_jit_bwd(x, grad_output) + + +def mish_me(x, inplace=False): + return MishJitAutoFn.apply(x) + + +class MishMe(nn.Module): + def __init__(self, inplace: bool = False): + super(MishMe, self).__init__() + + def forward(self, x): + return MishJitAutoFn.apply(x) + + +@torch.jit.script +def hard_sigmoid_jit_fwd(x, inplace: bool = False): + return (x + 3).clamp(min=0, max=6).div(6.) + + +@torch.jit.script +def hard_sigmoid_jit_bwd(x, grad_output): + m = torch.ones_like(x) * ((x >= -3.) & (x <= 3.)) / 6. + return grad_output * m + + +class HardSigmoidJitAutoFn(torch.autograd.Function): + @staticmethod + def forward(ctx, x): + ctx.save_for_backward(x) + return hard_sigmoid_jit_fwd(x) + + @staticmethod + def backward(ctx, grad_output): + x = ctx.saved_tensors[0] + return hard_sigmoid_jit_bwd(x, grad_output) + + +def hard_sigmoid_me(x, inplace: bool = False): + return HardSigmoidJitAutoFn.apply(x) + + +class HardSigmoidMe(nn.Module): + def __init__(self, inplace: bool = False): + super(HardSigmoidMe, self).__init__() + + def forward(self, x): + return HardSigmoidJitAutoFn.apply(x) + + +@torch.jit.script +def hard_swish_jit_fwd(x): + return x * (x + 3).clamp(min=0, max=6).div(6.) + + +@torch.jit.script +def hard_swish_jit_bwd(x, grad_output): + m = torch.ones_like(x) * (x >= 3.) + m = torch.where((x >= -3.) & (x <= 3.), x / 3. + .5, m) + return grad_output * m + + +class HardSwishJitAutoFn(torch.autograd.Function): + """A memory efficient, jit-scripted HardSwish activation""" + @staticmethod + def forward(ctx, x): + ctx.save_for_backward(x) + return hard_swish_jit_fwd(x) + + @staticmethod + def backward(ctx, grad_output): + x = ctx.saved_tensors[0] + return hard_swish_jit_bwd(x, grad_output) + + +def hard_swish_me(x, inplace=False): + return HardSwishJitAutoFn.apply(x) + + +class HardSwishMe(nn.Module): + def __init__(self, inplace: bool = False): + super(HardSwishMe, self).__init__() + + def forward(self, x): + return HardSwishJitAutoFn.apply(x) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/config.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/config.py new file mode 100644 index 00000000..27d5307f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/config.py @@ -0,0 +1,123 @@ +""" Global layer config state +""" +from typing import Any, Optional + +__all__ = [ + 'is_exportable', 'is_scriptable', 'is_no_jit', 'layer_config_kwargs', + 'set_exportable', 'set_scriptable', 'set_no_jit', 'set_layer_config' +] + +# Set to True if prefer to have layers with no jit optimization (includes activations) +_NO_JIT = False + +# Set to True if prefer to have activation layers with no jit optimization +# NOTE not currently used as no difference between no_jit and no_activation jit as only layers obeying +# the jit flags so far are activations. This will change as more layers are updated and/or added. +_NO_ACTIVATION_JIT = False + +# Set to True if exporting a model with Same padding via ONNX +_EXPORTABLE = False + +# Set to True if wanting to use torch.jit.script on a model +_SCRIPTABLE = False + + +def is_no_jit(): + return _NO_JIT + + +class set_no_jit: + def __init__(self, mode: bool) -> None: + global _NO_JIT + self.prev = _NO_JIT + _NO_JIT = mode + + def __enter__(self) -> None: + pass + + def __exit__(self, *args: Any) -> bool: + global _NO_JIT + _NO_JIT = self.prev + return False + + +def is_exportable(): + return _EXPORTABLE + + +class set_exportable: + def __init__(self, mode: bool) -> None: + global _EXPORTABLE + self.prev = _EXPORTABLE + _EXPORTABLE = mode + + def __enter__(self) -> None: + pass + + def __exit__(self, *args: Any) -> bool: + global _EXPORTABLE + _EXPORTABLE = self.prev + return False + + +def is_scriptable(): + return _SCRIPTABLE + + +class set_scriptable: + def __init__(self, mode: bool) -> None: + global _SCRIPTABLE + self.prev = _SCRIPTABLE + _SCRIPTABLE = mode + + def __enter__(self) -> None: + pass + + def __exit__(self, *args: Any) -> bool: + global _SCRIPTABLE + _SCRIPTABLE = self.prev + return False + + +class set_layer_config: + """ Layer config context manager that allows setting all layer config flags at once. + If a flag arg is None, it will not change the current value. + """ + def __init__( + self, + scriptable: Optional[bool] = None, + exportable: Optional[bool] = None, + no_jit: Optional[bool] = None, + no_activation_jit: Optional[bool] = None): + global _SCRIPTABLE + global _EXPORTABLE + global _NO_JIT + global _NO_ACTIVATION_JIT + self.prev = _SCRIPTABLE, _EXPORTABLE, _NO_JIT, _NO_ACTIVATION_JIT + if scriptable is not None: + _SCRIPTABLE = scriptable + if exportable is not None: + _EXPORTABLE = exportable + if no_jit is not None: + _NO_JIT = no_jit + if no_activation_jit is not None: + _NO_ACTIVATION_JIT = no_activation_jit + + def __enter__(self) -> None: + pass + + def __exit__(self, *args: Any) -> bool: + global _SCRIPTABLE + global _EXPORTABLE + global _NO_JIT + global _NO_ACTIVATION_JIT + _SCRIPTABLE, _EXPORTABLE, _NO_JIT, _NO_ACTIVATION_JIT = self.prev + return False + + +def layer_config_kwargs(kwargs): + """ Consume config kwargs and return contextmgr obj """ + return set_layer_config( + scriptable=kwargs.pop('scriptable', None), + exportable=kwargs.pop('exportable', None), + no_jit=kwargs.pop('no_jit', None)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/conv2d_layers.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/conv2d_layers.py new file mode 100644 index 00000000..d8467460 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/conv2d_layers.py @@ -0,0 +1,304 @@ +""" Conv2D w/ SAME padding, CondConv, MixedConv + +A collection of conv layers and padding helpers needed by EfficientNet, MixNet, and +MobileNetV3 models that maintain weight compatibility with original Tensorflow models. + +Copyright 2020 Ross Wightman +""" +import collections.abc +import math +from functools import partial +from itertools import repeat +from typing import Tuple, Optional + +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F + +from .config import * + + +# From PyTorch internals +def _ntuple(n): + def parse(x): + if isinstance(x, collections.abc.Iterable): + return x + return tuple(repeat(x, n)) + return parse + + +_single = _ntuple(1) +_pair = _ntuple(2) +_triple = _ntuple(3) +_quadruple = _ntuple(4) + + +def _is_static_pad(kernel_size, stride=1, dilation=1, **_): + return stride == 1 and (dilation * (kernel_size - 1)) % 2 == 0 + + +def _get_padding(kernel_size, stride=1, dilation=1, **_): + padding = ((stride - 1) + dilation * (kernel_size - 1)) // 2 + return padding + + +def _calc_same_pad(i: int, k: int, s: int, d: int): + return max((-(i // -s) - 1) * s + (k - 1) * d + 1 - i, 0) + + +def _same_pad_arg(input_size, kernel_size, stride, dilation): + ih, iw = input_size + kh, kw = kernel_size + pad_h = _calc_same_pad(ih, kh, stride[0], dilation[0]) + pad_w = _calc_same_pad(iw, kw, stride[1], dilation[1]) + return [pad_w // 2, pad_w - pad_w // 2, pad_h // 2, pad_h - pad_h // 2] + + +def _split_channels(num_chan, num_groups): + split = [num_chan // num_groups for _ in range(num_groups)] + split[0] += num_chan - sum(split) + return split + + +def conv2d_same( + x, weight: torch.Tensor, bias: Optional[torch.Tensor] = None, stride: Tuple[int, int] = (1, 1), + padding: Tuple[int, int] = (0, 0), dilation: Tuple[int, int] = (1, 1), groups: int = 1): + ih, iw = x.size()[-2:] + kh, kw = weight.size()[-2:] + pad_h = _calc_same_pad(ih, kh, stride[0], dilation[0]) + pad_w = _calc_same_pad(iw, kw, stride[1], dilation[1]) + x = F.pad(x, [pad_w // 2, pad_w - pad_w // 2, pad_h // 2, pad_h - pad_h // 2]) + return F.conv2d(x, weight, bias, stride, (0, 0), dilation, groups) + + +class Conv2dSame(nn.Conv2d): + """ Tensorflow like 'SAME' convolution wrapper for 2D convolutions + """ + + # pylint: disable=unused-argument + def __init__(self, in_channels, out_channels, kernel_size, stride=1, + padding=0, dilation=1, groups=1, bias=True): + super(Conv2dSame, self).__init__( + in_channels, out_channels, kernel_size, stride, 0, dilation, groups, bias) + + def forward(self, x): + return conv2d_same(x, self.weight, self.bias, self.stride, self.padding, self.dilation, self.groups) + + +class Conv2dSameExport(nn.Conv2d): + """ ONNX export friendly Tensorflow like 'SAME' convolution wrapper for 2D convolutions + + NOTE: This does not currently work with torch.jit.script + """ + + # pylint: disable=unused-argument + def __init__(self, in_channels, out_channels, kernel_size, stride=1, + padding=0, dilation=1, groups=1, bias=True): + super(Conv2dSameExport, self).__init__( + in_channels, out_channels, kernel_size, stride, 0, dilation, groups, bias) + self.pad = None + self.pad_input_size = (0, 0) + + def forward(self, x): + input_size = x.size()[-2:] + if self.pad is None: + pad_arg = _same_pad_arg(input_size, self.weight.size()[-2:], self.stride, self.dilation) + self.pad = nn.ZeroPad2d(pad_arg) + self.pad_input_size = input_size + + if self.pad is not None: + x = self.pad(x) + return F.conv2d( + x, self.weight, self.bias, self.stride, self.padding, self.dilation, self.groups) + + +def get_padding_value(padding, kernel_size, **kwargs): + dynamic = False + if isinstance(padding, str): + # for any string padding, the padding will be calculated for you, one of three ways + padding = padding.lower() + if padding == 'same': + # TF compatible 'SAME' padding, has a performance and GPU memory allocation impact + if _is_static_pad(kernel_size, **kwargs): + # static case, no extra overhead + padding = _get_padding(kernel_size, **kwargs) + else: + # dynamic padding + padding = 0 + dynamic = True + elif padding == 'valid': + # 'VALID' padding, same as padding=0 + padding = 0 + else: + # Default to PyTorch style 'same'-ish symmetric padding + padding = _get_padding(kernel_size, **kwargs) + return padding, dynamic + + +def create_conv2d_pad(in_chs, out_chs, kernel_size, **kwargs): + padding = kwargs.pop('padding', '') + kwargs.setdefault('bias', False) + padding, is_dynamic = get_padding_value(padding, kernel_size, **kwargs) + if is_dynamic: + if is_exportable(): + assert not is_scriptable() + return Conv2dSameExport(in_chs, out_chs, kernel_size, **kwargs) + else: + return Conv2dSame(in_chs, out_chs, kernel_size, **kwargs) + else: + return nn.Conv2d(in_chs, out_chs, kernel_size, padding=padding, **kwargs) + + +class MixedConv2d(nn.ModuleDict): + """ Mixed Grouped Convolution + Based on MDConv and GroupedConv in MixNet impl: + https://github.com/tensorflow/tpu/blob/master/models/official/mnasnet/mixnet/custom_layers.py + """ + + def __init__(self, in_channels, out_channels, kernel_size=3, + stride=1, padding='', dilation=1, depthwise=False, **kwargs): + super(MixedConv2d, self).__init__() + + kernel_size = kernel_size if isinstance(kernel_size, list) else [kernel_size] + num_groups = len(kernel_size) + in_splits = _split_channels(in_channels, num_groups) + out_splits = _split_channels(out_channels, num_groups) + self.in_channels = sum(in_splits) + self.out_channels = sum(out_splits) + for idx, (k, in_ch, out_ch) in enumerate(zip(kernel_size, in_splits, out_splits)): + conv_groups = out_ch if depthwise else 1 + self.add_module( + str(idx), + create_conv2d_pad( + in_ch, out_ch, k, stride=stride, + padding=padding, dilation=dilation, groups=conv_groups, **kwargs) + ) + self.splits = in_splits + + def forward(self, x): + x_split = torch.split(x, self.splits, 1) + x_out = [conv(x_split[i]) for i, conv in enumerate(self.values())] + x = torch.cat(x_out, 1) + return x + + +def get_condconv_initializer(initializer, num_experts, expert_shape): + def condconv_initializer(weight): + """CondConv initializer function.""" + num_params = np.prod(expert_shape) + if (len(weight.shape) != 2 or weight.shape[0] != num_experts or + weight.shape[1] != num_params): + raise (ValueError( + 'CondConv variables must have shape [num_experts, num_params]')) + for i in range(num_experts): + initializer(weight[i].view(expert_shape)) + return condconv_initializer + + +class CondConv2d(nn.Module): + """ Conditional Convolution + Inspired by: https://github.com/tensorflow/tpu/blob/master/models/official/efficientnet/condconv/condconv_layers.py + + Grouped convolution hackery for parallel execution of the per-sample kernel filters inspired by this discussion: + https://github.com/pytorch/pytorch/issues/17983 + """ + __constants__ = ['bias', 'in_channels', 'out_channels', 'dynamic_padding'] + + def __init__(self, in_channels, out_channels, kernel_size=3, + stride=1, padding='', dilation=1, groups=1, bias=False, num_experts=4): + super(CondConv2d, self).__init__() + + self.in_channels = in_channels + self.out_channels = out_channels + self.kernel_size = _pair(kernel_size) + self.stride = _pair(stride) + padding_val, is_padding_dynamic = get_padding_value( + padding, kernel_size, stride=stride, dilation=dilation) + self.dynamic_padding = is_padding_dynamic # if in forward to work with torchscript + self.padding = _pair(padding_val) + self.dilation = _pair(dilation) + self.groups = groups + self.num_experts = num_experts + + self.weight_shape = (self.out_channels, self.in_channels // self.groups) + self.kernel_size + weight_num_param = 1 + for wd in self.weight_shape: + weight_num_param *= wd + self.weight = torch.nn.Parameter(torch.Tensor(self.num_experts, weight_num_param)) + + if bias: + self.bias_shape = (self.out_channels,) + self.bias = torch.nn.Parameter(torch.Tensor(self.num_experts, self.out_channels)) + else: + self.register_parameter('bias', None) + + self.reset_parameters() + + def reset_parameters(self): + init_weight = get_condconv_initializer( + partial(nn.init.kaiming_uniform_, a=math.sqrt(5)), self.num_experts, self.weight_shape) + init_weight(self.weight) + if self.bias is not None: + fan_in = np.prod(self.weight_shape[1:]) + bound = 1 / math.sqrt(fan_in) + init_bias = get_condconv_initializer( + partial(nn.init.uniform_, a=-bound, b=bound), self.num_experts, self.bias_shape) + init_bias(self.bias) + + def forward(self, x, routing_weights): + B, C, H, W = x.shape + weight = torch.matmul(routing_weights, self.weight) + new_weight_shape = (B * self.out_channels, self.in_channels // self.groups) + self.kernel_size + weight = weight.view(new_weight_shape) + bias = None + if self.bias is not None: + bias = torch.matmul(routing_weights, self.bias) + bias = bias.view(B * self.out_channels) + # move batch elements with channels so each batch element can be efficiently convolved with separate kernel + x = x.view(1, B * C, H, W) + if self.dynamic_padding: + out = conv2d_same( + x, weight, bias, stride=self.stride, padding=self.padding, + dilation=self.dilation, groups=self.groups * B) + else: + out = F.conv2d( + x, weight, bias, stride=self.stride, padding=self.padding, + dilation=self.dilation, groups=self.groups * B) + out = out.permute([1, 0, 2, 3]).view(B, self.out_channels, out.shape[-2], out.shape[-1]) + + # Literal port (from TF definition) + # x = torch.split(x, 1, 0) + # weight = torch.split(weight, 1, 0) + # if self.bias is not None: + # bias = torch.matmul(routing_weights, self.bias) + # bias = torch.split(bias, 1, 0) + # else: + # bias = [None] * B + # out = [] + # for xi, wi, bi in zip(x, weight, bias): + # wi = wi.view(*self.weight_shape) + # if bi is not None: + # bi = bi.view(*self.bias_shape) + # out.append(self.conv_fn( + # xi, wi, bi, stride=self.stride, padding=self.padding, + # dilation=self.dilation, groups=self.groups)) + # out = torch.cat(out, 0) + return out + + +def select_conv2d(in_chs, out_chs, kernel_size, **kwargs): + assert 'groups' not in kwargs # only use 'depthwise' bool arg + if isinstance(kernel_size, list): + assert 'num_experts' not in kwargs # MixNet + CondConv combo not supported currently + # We're going to use only lists for defining the MixedConv2d kernel groups, + # ints, tuples, other iterables will continue to pass to normal conv and specify h, w. + m = MixedConv2d(in_chs, out_chs, kernel_size, **kwargs) + else: + depthwise = kwargs.pop('depthwise', False) + groups = out_chs if depthwise else 1 + if 'num_experts' in kwargs and kwargs['num_experts'] > 0: + m = CondConv2d(in_chs, out_chs, kernel_size, groups=groups, **kwargs) + else: + m = create_conv2d_pad(in_chs, out_chs, kernel_size, groups=groups, **kwargs) + return m diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/efficientnet_builder.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/efficientnet_builder.py new file mode 100644 index 00000000..95dd63d4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/efficientnet_builder.py @@ -0,0 +1,683 @@ +""" EfficientNet / MobileNetV3 Blocks and Builder + +Copyright 2020 Ross Wightman +""" +import re +from copy import deepcopy + +from .conv2d_layers import * +from geffnet.activations import * + +__all__ = ['get_bn_args_tf', 'resolve_bn_args', 'resolve_se_args', 'resolve_act_layer', 'make_divisible', + 'round_channels', 'drop_connect', 'SqueezeExcite', 'ConvBnAct', 'DepthwiseSeparableConv', + 'InvertedResidual', 'CondConvResidual', 'EdgeResidual', 'EfficientNetBuilder', 'decode_arch_def', + 'initialize_weight_default', 'initialize_weight_goog', 'BN_MOMENTUM_TF_DEFAULT', 'BN_EPS_TF_DEFAULT' +] + +# Defaults used for Google/Tensorflow training of mobile networks /w RMSprop as per +# papers and TF reference implementations. PT momentum equiv for TF decay is (1 - TF decay) +# NOTE: momentum varies btw .99 and .9997 depending on source +# .99 in official TF TPU impl +# .9997 (/w .999 in search space) for paper +# +# PyTorch defaults are momentum = .1, eps = 1e-5 +# +BN_MOMENTUM_TF_DEFAULT = 1 - 0.99 +BN_EPS_TF_DEFAULT = 1e-3 +_BN_ARGS_TF = dict(momentum=BN_MOMENTUM_TF_DEFAULT, eps=BN_EPS_TF_DEFAULT) + + +def get_bn_args_tf(): + return _BN_ARGS_TF.copy() + + +def resolve_bn_args(kwargs): + bn_args = get_bn_args_tf() if kwargs.pop('bn_tf', False) else {} + bn_momentum = kwargs.pop('bn_momentum', None) + if bn_momentum is not None: + bn_args['momentum'] = bn_momentum + bn_eps = kwargs.pop('bn_eps', None) + if bn_eps is not None: + bn_args['eps'] = bn_eps + return bn_args + + +_SE_ARGS_DEFAULT = dict( + gate_fn=sigmoid, + act_layer=None, # None == use containing block's activation layer + reduce_mid=False, + divisor=1) + + +def resolve_se_args(kwargs, in_chs, act_layer=None): + se_kwargs = kwargs.copy() if kwargs is not None else {} + # fill in args that aren't specified with the defaults + for k, v in _SE_ARGS_DEFAULT.items(): + se_kwargs.setdefault(k, v) + # some models, like MobilNetV3, calculate SE reduction chs from the containing block's mid_ch instead of in_ch + if not se_kwargs.pop('reduce_mid'): + se_kwargs['reduced_base_chs'] = in_chs + # act_layer override, if it remains None, the containing block's act_layer will be used + if se_kwargs['act_layer'] is None: + assert act_layer is not None + se_kwargs['act_layer'] = act_layer + return se_kwargs + + +def resolve_act_layer(kwargs, default='relu'): + act_layer = kwargs.pop('act_layer', default) + if isinstance(act_layer, str): + act_layer = get_act_layer(act_layer) + return act_layer + + +def make_divisible(v: int, divisor: int = 8, min_value: int = None): + min_value = min_value or divisor + new_v = max(min_value, int(v + divisor / 2) // divisor * divisor) + if new_v < 0.9 * v: # ensure round down does not go down by more than 10%. + new_v += divisor + return new_v + + +def round_channels(channels, multiplier=1.0, divisor=8, channel_min=None): + """Round number of filters based on depth multiplier.""" + if not multiplier: + return channels + channels *= multiplier + return make_divisible(channels, divisor, channel_min) + + +def drop_connect(inputs, training: bool = False, drop_connect_rate: float = 0.): + """Apply drop connect.""" + if not training: + return inputs + + keep_prob = 1 - drop_connect_rate + random_tensor = keep_prob + torch.rand( + (inputs.size()[0], 1, 1, 1), dtype=inputs.dtype, device=inputs.device) + random_tensor.floor_() # binarize + output = inputs.div(keep_prob) * random_tensor + return output + + +class SqueezeExcite(nn.Module): + + def __init__(self, in_chs, se_ratio=0.25, reduced_base_chs=None, act_layer=nn.ReLU, gate_fn=sigmoid, divisor=1): + super(SqueezeExcite, self).__init__() + reduced_chs = make_divisible((reduced_base_chs or in_chs) * se_ratio, divisor) + self.conv_reduce = nn.Conv2d(in_chs, reduced_chs, 1, bias=True) + self.act1 = act_layer(inplace=True) + self.conv_expand = nn.Conv2d(reduced_chs, in_chs, 1, bias=True) + self.gate_fn = gate_fn + + def forward(self, x): + x_se = x.mean((2, 3), keepdim=True) + x_se = self.conv_reduce(x_se) + x_se = self.act1(x_se) + x_se = self.conv_expand(x_se) + x = x * self.gate_fn(x_se) + return x + + +class ConvBnAct(nn.Module): + def __init__(self, in_chs, out_chs, kernel_size, + stride=1, pad_type='', act_layer=nn.ReLU, norm_layer=nn.BatchNorm2d, norm_kwargs=None): + super(ConvBnAct, self).__init__() + assert stride in [1, 2] + norm_kwargs = norm_kwargs or {} + self.conv = select_conv2d(in_chs, out_chs, kernel_size, stride=stride, padding=pad_type) + self.bn1 = norm_layer(out_chs, **norm_kwargs) + self.act1 = act_layer(inplace=True) + + def forward(self, x): + x = self.conv(x) + x = self.bn1(x) + x = self.act1(x) + return x + + +class DepthwiseSeparableConv(nn.Module): + """ DepthwiseSeparable block + Used for DS convs in MobileNet-V1 and in the place of IR blocks with an expansion + factor of 1.0. This is an alternative to having a IR with optional first pw conv. + """ + def __init__(self, in_chs, out_chs, dw_kernel_size=3, + stride=1, pad_type='', act_layer=nn.ReLU, noskip=False, + pw_kernel_size=1, pw_act=False, se_ratio=0., se_kwargs=None, + norm_layer=nn.BatchNorm2d, norm_kwargs=None, drop_connect_rate=0.): + super(DepthwiseSeparableConv, self).__init__() + assert stride in [1, 2] + norm_kwargs = norm_kwargs or {} + self.has_residual = (stride == 1 and in_chs == out_chs) and not noskip + self.drop_connect_rate = drop_connect_rate + + self.conv_dw = select_conv2d( + in_chs, in_chs, dw_kernel_size, stride=stride, padding=pad_type, depthwise=True) + self.bn1 = norm_layer(in_chs, **norm_kwargs) + self.act1 = act_layer(inplace=True) + + # Squeeze-and-excitation + if se_ratio is not None and se_ratio > 0.: + se_kwargs = resolve_se_args(se_kwargs, in_chs, act_layer) + self.se = SqueezeExcite(in_chs, se_ratio=se_ratio, **se_kwargs) + else: + self.se = nn.Identity() + + self.conv_pw = select_conv2d(in_chs, out_chs, pw_kernel_size, padding=pad_type) + self.bn2 = norm_layer(out_chs, **norm_kwargs) + self.act2 = act_layer(inplace=True) if pw_act else nn.Identity() + + def forward(self, x): + residual = x + + x = self.conv_dw(x) + x = self.bn1(x) + x = self.act1(x) + + x = self.se(x) + + x = self.conv_pw(x) + x = self.bn2(x) + x = self.act2(x) + + if self.has_residual: + if self.drop_connect_rate > 0.: + x = drop_connect(x, self.training, self.drop_connect_rate) + x += residual + return x + + +class InvertedResidual(nn.Module): + """ Inverted residual block w/ optional SE""" + + def __init__(self, in_chs, out_chs, dw_kernel_size=3, + stride=1, pad_type='', act_layer=nn.ReLU, noskip=False, + exp_ratio=1.0, exp_kernel_size=1, pw_kernel_size=1, + se_ratio=0., se_kwargs=None, norm_layer=nn.BatchNorm2d, norm_kwargs=None, + conv_kwargs=None, drop_connect_rate=0.): + super(InvertedResidual, self).__init__() + norm_kwargs = norm_kwargs or {} + conv_kwargs = conv_kwargs or {} + mid_chs: int = make_divisible(in_chs * exp_ratio) + self.has_residual = (in_chs == out_chs and stride == 1) and not noskip + self.drop_connect_rate = drop_connect_rate + + # Point-wise expansion + self.conv_pw = select_conv2d(in_chs, mid_chs, exp_kernel_size, padding=pad_type, **conv_kwargs) + self.bn1 = norm_layer(mid_chs, **norm_kwargs) + self.act1 = act_layer(inplace=True) + + # Depth-wise convolution + self.conv_dw = select_conv2d( + mid_chs, mid_chs, dw_kernel_size, stride=stride, padding=pad_type, depthwise=True, **conv_kwargs) + self.bn2 = norm_layer(mid_chs, **norm_kwargs) + self.act2 = act_layer(inplace=True) + + # Squeeze-and-excitation + if se_ratio is not None and se_ratio > 0.: + se_kwargs = resolve_se_args(se_kwargs, in_chs, act_layer) + self.se = SqueezeExcite(mid_chs, se_ratio=se_ratio, **se_kwargs) + else: + self.se = nn.Identity() # for jit.script compat + + # Point-wise linear projection + self.conv_pwl = select_conv2d(mid_chs, out_chs, pw_kernel_size, padding=pad_type, **conv_kwargs) + self.bn3 = norm_layer(out_chs, **norm_kwargs) + + def forward(self, x): + residual = x + + # Point-wise expansion + x = self.conv_pw(x) + x = self.bn1(x) + x = self.act1(x) + + # Depth-wise convolution + x = self.conv_dw(x) + x = self.bn2(x) + x = self.act2(x) + + # Squeeze-and-excitation + x = self.se(x) + + # Point-wise linear projection + x = self.conv_pwl(x) + x = self.bn3(x) + + if self.has_residual: + if self.drop_connect_rate > 0.: + x = drop_connect(x, self.training, self.drop_connect_rate) + x += residual + return x + + +class CondConvResidual(InvertedResidual): + """ Inverted residual block w/ CondConv routing""" + + def __init__(self, in_chs, out_chs, dw_kernel_size=3, + stride=1, pad_type='', act_layer=nn.ReLU, noskip=False, + exp_ratio=1.0, exp_kernel_size=1, pw_kernel_size=1, + se_ratio=0., se_kwargs=None, norm_layer=nn.BatchNorm2d, norm_kwargs=None, + num_experts=0, drop_connect_rate=0.): + + self.num_experts = num_experts + conv_kwargs = dict(num_experts=self.num_experts) + + super(CondConvResidual, self).__init__( + in_chs, out_chs, dw_kernel_size=dw_kernel_size, stride=stride, pad_type=pad_type, + act_layer=act_layer, noskip=noskip, exp_ratio=exp_ratio, exp_kernel_size=exp_kernel_size, + pw_kernel_size=pw_kernel_size, se_ratio=se_ratio, se_kwargs=se_kwargs, + norm_layer=norm_layer, norm_kwargs=norm_kwargs, conv_kwargs=conv_kwargs, + drop_connect_rate=drop_connect_rate) + + self.routing_fn = nn.Linear(in_chs, self.num_experts) + + def forward(self, x): + residual = x + + # CondConv routing + pooled_inputs = F.adaptive_avg_pool2d(x, 1).flatten(1) + routing_weights = torch.sigmoid(self.routing_fn(pooled_inputs)) + + # Point-wise expansion + x = self.conv_pw(x, routing_weights) + x = self.bn1(x) + x = self.act1(x) + + # Depth-wise convolution + x = self.conv_dw(x, routing_weights) + x = self.bn2(x) + x = self.act2(x) + + # Squeeze-and-excitation + x = self.se(x) + + # Point-wise linear projection + x = self.conv_pwl(x, routing_weights) + x = self.bn3(x) + + if self.has_residual: + if self.drop_connect_rate > 0.: + x = drop_connect(x, self.training, self.drop_connect_rate) + x += residual + return x + + +class EdgeResidual(nn.Module): + """ EdgeTPU Residual block with expansion convolution followed by pointwise-linear w/ stride""" + + def __init__(self, in_chs, out_chs, exp_kernel_size=3, exp_ratio=1.0, fake_in_chs=0, + stride=1, pad_type='', act_layer=nn.ReLU, noskip=False, pw_kernel_size=1, + se_ratio=0., se_kwargs=None, norm_layer=nn.BatchNorm2d, norm_kwargs=None, drop_connect_rate=0.): + super(EdgeResidual, self).__init__() + norm_kwargs = norm_kwargs or {} + mid_chs = make_divisible(fake_in_chs * exp_ratio) if fake_in_chs > 0 else make_divisible(in_chs * exp_ratio) + self.has_residual = (in_chs == out_chs and stride == 1) and not noskip + self.drop_connect_rate = drop_connect_rate + + # Expansion convolution + self.conv_exp = select_conv2d(in_chs, mid_chs, exp_kernel_size, padding=pad_type) + self.bn1 = norm_layer(mid_chs, **norm_kwargs) + self.act1 = act_layer(inplace=True) + + # Squeeze-and-excitation + if se_ratio is not None and se_ratio > 0.: + se_kwargs = resolve_se_args(se_kwargs, in_chs, act_layer) + self.se = SqueezeExcite(mid_chs, se_ratio=se_ratio, **se_kwargs) + else: + self.se = nn.Identity() + + # Point-wise linear projection + self.conv_pwl = select_conv2d(mid_chs, out_chs, pw_kernel_size, stride=stride, padding=pad_type) + self.bn2 = nn.BatchNorm2d(out_chs, **norm_kwargs) + + def forward(self, x): + residual = x + + # Expansion convolution + x = self.conv_exp(x) + x = self.bn1(x) + x = self.act1(x) + + # Squeeze-and-excitation + x = self.se(x) + + # Point-wise linear projection + x = self.conv_pwl(x) + x = self.bn2(x) + + if self.has_residual: + if self.drop_connect_rate > 0.: + x = drop_connect(x, self.training, self.drop_connect_rate) + x += residual + + return x + + +class EfficientNetBuilder: + """ Build Trunk Blocks for Efficient/Mobile Networks + + This ended up being somewhat of a cross between + https://github.com/tensorflow/tpu/blob/master/models/official/mnasnet/mnasnet_models.py + and + https://github.com/facebookresearch/maskrcnn-benchmark/blob/master/maskrcnn_benchmark/modeling/backbone/fbnet_builder.py + + """ + + def __init__(self, channel_multiplier=1.0, channel_divisor=8, channel_min=None, + pad_type='', act_layer=None, se_kwargs=None, + norm_layer=nn.BatchNorm2d, norm_kwargs=None, drop_connect_rate=0.): + self.channel_multiplier = channel_multiplier + self.channel_divisor = channel_divisor + self.channel_min = channel_min + self.pad_type = pad_type + self.act_layer = act_layer + self.se_kwargs = se_kwargs + self.norm_layer = norm_layer + self.norm_kwargs = norm_kwargs + self.drop_connect_rate = drop_connect_rate + + # updated during build + self.in_chs = None + self.block_idx = 0 + self.block_count = 0 + + def _round_channels(self, chs): + return round_channels(chs, self.channel_multiplier, self.channel_divisor, self.channel_min) + + def _make_block(self, ba): + bt = ba.pop('block_type') + ba['in_chs'] = self.in_chs + ba['out_chs'] = self._round_channels(ba['out_chs']) + if 'fake_in_chs' in ba and ba['fake_in_chs']: + # FIXME this is a hack to work around mismatch in origin impl input filters for EdgeTPU + ba['fake_in_chs'] = self._round_channels(ba['fake_in_chs']) + ba['norm_layer'] = self.norm_layer + ba['norm_kwargs'] = self.norm_kwargs + ba['pad_type'] = self.pad_type + # block act fn overrides the model default + ba['act_layer'] = ba['act_layer'] if ba['act_layer'] is not None else self.act_layer + assert ba['act_layer'] is not None + if bt == 'ir': + ba['drop_connect_rate'] = self.drop_connect_rate * self.block_idx / self.block_count + ba['se_kwargs'] = self.se_kwargs + if ba.get('num_experts', 0) > 0: + block = CondConvResidual(**ba) + else: + block = InvertedResidual(**ba) + elif bt == 'ds' or bt == 'dsa': + ba['drop_connect_rate'] = self.drop_connect_rate * self.block_idx / self.block_count + ba['se_kwargs'] = self.se_kwargs + block = DepthwiseSeparableConv(**ba) + elif bt == 'er': + ba['drop_connect_rate'] = self.drop_connect_rate * self.block_idx / self.block_count + ba['se_kwargs'] = self.se_kwargs + block = EdgeResidual(**ba) + elif bt == 'cn': + block = ConvBnAct(**ba) + else: + assert False, 'Uknkown block type (%s) while building model.' % bt + self.in_chs = ba['out_chs'] # update in_chs for arg of next block + return block + + def _make_stack(self, stack_args): + blocks = [] + # each stack (stage) contains a list of block arguments + for i, ba in enumerate(stack_args): + if i >= 1: + # only the first block in any stack can have a stride > 1 + ba['stride'] = 1 + block = self._make_block(ba) + blocks.append(block) + self.block_idx += 1 # incr global idx (across all stacks) + return nn.Sequential(*blocks) + + def __call__(self, in_chs, block_args): + """ Build the blocks + Args: + in_chs: Number of input-channels passed to first block + block_args: A list of lists, outer list defines stages, inner + list contains strings defining block configuration(s) + Return: + List of block stacks (each stack wrapped in nn.Sequential) + """ + self.in_chs = in_chs + self.block_count = sum([len(x) for x in block_args]) + self.block_idx = 0 + blocks = [] + # outer list of block_args defines the stacks ('stages' by some conventions) + for stack_idx, stack in enumerate(block_args): + assert isinstance(stack, list) + stack = self._make_stack(stack) + blocks.append(stack) + return blocks + + +def _parse_ksize(ss): + if ss.isdigit(): + return int(ss) + else: + return [int(k) for k in ss.split('.')] + + +def _decode_block_str(block_str): + """ Decode block definition string + + Gets a list of block arg (dicts) through a string notation of arguments. + E.g. ir_r2_k3_s2_e1_i32_o16_se0.25_noskip + + All args can exist in any order with the exception of the leading string which + is assumed to indicate the block type. + + leading string - block type ( + ir = InvertedResidual, ds = DepthwiseSep, dsa = DeptwhiseSep with pw act, cn = ConvBnAct) + r - number of repeat blocks, + k - kernel size, + s - strides (1-9), + e - expansion ratio, + c - output channels, + se - squeeze/excitation ratio + n - activation fn ('re', 'r6', 'hs', or 'sw') + Args: + block_str: a string representation of block arguments. + Returns: + A list of block args (dicts) + Raises: + ValueError: if the string def not properly specified (TODO) + """ + assert isinstance(block_str, str) + ops = block_str.split('_') + block_type = ops[0] # take the block type off the front + ops = ops[1:] + options = {} + noskip = False + for op in ops: + # string options being checked on individual basis, combine if they grow + if op == 'noskip': + noskip = True + elif op.startswith('n'): + # activation fn + key = op[0] + v = op[1:] + if v == 're': + value = get_act_layer('relu') + elif v == 'r6': + value = get_act_layer('relu6') + elif v == 'hs': + value = get_act_layer('hard_swish') + elif v == 'sw': + value = get_act_layer('swish') + else: + continue + options[key] = value + else: + # all numeric options + splits = re.split(r'(\d.*)', op) + if len(splits) >= 2: + key, value = splits[:2] + options[key] = value + + # if act_layer is None, the model default (passed to model init) will be used + act_layer = options['n'] if 'n' in options else None + exp_kernel_size = _parse_ksize(options['a']) if 'a' in options else 1 + pw_kernel_size = _parse_ksize(options['p']) if 'p' in options else 1 + fake_in_chs = int(options['fc']) if 'fc' in options else 0 # FIXME hack to deal with in_chs issue in TPU def + + num_repeat = int(options['r']) + # each type of block has different valid arguments, fill accordingly + if block_type == 'ir': + block_args = dict( + block_type=block_type, + dw_kernel_size=_parse_ksize(options['k']), + exp_kernel_size=exp_kernel_size, + pw_kernel_size=pw_kernel_size, + out_chs=int(options['c']), + exp_ratio=float(options['e']), + se_ratio=float(options['se']) if 'se' in options else None, + stride=int(options['s']), + act_layer=act_layer, + noskip=noskip, + ) + if 'cc' in options: + block_args['num_experts'] = int(options['cc']) + elif block_type == 'ds' or block_type == 'dsa': + block_args = dict( + block_type=block_type, + dw_kernel_size=_parse_ksize(options['k']), + pw_kernel_size=pw_kernel_size, + out_chs=int(options['c']), + se_ratio=float(options['se']) if 'se' in options else None, + stride=int(options['s']), + act_layer=act_layer, + pw_act=block_type == 'dsa', + noskip=block_type == 'dsa' or noskip, + ) + elif block_type == 'er': + block_args = dict( + block_type=block_type, + exp_kernel_size=_parse_ksize(options['k']), + pw_kernel_size=pw_kernel_size, + out_chs=int(options['c']), + exp_ratio=float(options['e']), + fake_in_chs=fake_in_chs, + se_ratio=float(options['se']) if 'se' in options else None, + stride=int(options['s']), + act_layer=act_layer, + noskip=noskip, + ) + elif block_type == 'cn': + block_args = dict( + block_type=block_type, + kernel_size=int(options['k']), + out_chs=int(options['c']), + stride=int(options['s']), + act_layer=act_layer, + ) + else: + assert False, 'Unknown block type (%s)' % block_type + + return block_args, num_repeat + + +def _scale_stage_depth(stack_args, repeats, depth_multiplier=1.0, depth_trunc='ceil'): + """ Per-stage depth scaling + Scales the block repeats in each stage. This depth scaling impl maintains + compatibility with the EfficientNet scaling method, while allowing sensible + scaling for other models that may have multiple block arg definitions in each stage. + """ + + # We scale the total repeat count for each stage, there may be multiple + # block arg defs per stage so we need to sum. + num_repeat = sum(repeats) + if depth_trunc == 'round': + # Truncating to int by rounding allows stages with few repeats to remain + # proportionally smaller for longer. This is a good choice when stage definitions + # include single repeat stages that we'd prefer to keep that way as long as possible + num_repeat_scaled = max(1, round(num_repeat * depth_multiplier)) + else: + # The default for EfficientNet truncates repeats to int via 'ceil'. + # Any multiplier > 1.0 will result in an increased depth for every stage. + num_repeat_scaled = int(math.ceil(num_repeat * depth_multiplier)) + + # Proportionally distribute repeat count scaling to each block definition in the stage. + # Allocation is done in reverse as it results in the first block being less likely to be scaled. + # The first block makes less sense to repeat in most of the arch definitions. + repeats_scaled = [] + for r in repeats[::-1]: + rs = max(1, round((r / num_repeat * num_repeat_scaled))) + repeats_scaled.append(rs) + num_repeat -= r + num_repeat_scaled -= rs + repeats_scaled = repeats_scaled[::-1] + + # Apply the calculated scaling to each block arg in the stage + sa_scaled = [] + for ba, rep in zip(stack_args, repeats_scaled): + sa_scaled.extend([deepcopy(ba) for _ in range(rep)]) + return sa_scaled + + +def decode_arch_def(arch_def, depth_multiplier=1.0, depth_trunc='ceil', experts_multiplier=1, fix_first_last=False): + arch_args = [] + for stack_idx, block_strings in enumerate(arch_def): + assert isinstance(block_strings, list) + stack_args = [] + repeats = [] + for block_str in block_strings: + assert isinstance(block_str, str) + ba, rep = _decode_block_str(block_str) + if ba.get('num_experts', 0) > 0 and experts_multiplier > 1: + ba['num_experts'] *= experts_multiplier + stack_args.append(ba) + repeats.append(rep) + if fix_first_last and (stack_idx == 0 or stack_idx == len(arch_def) - 1): + arch_args.append(_scale_stage_depth(stack_args, repeats, 1.0, depth_trunc)) + else: + arch_args.append(_scale_stage_depth(stack_args, repeats, depth_multiplier, depth_trunc)) + return arch_args + + +def initialize_weight_goog(m, n='', fix_group_fanout=True): + # weight init as per Tensorflow Official impl + # https://github.com/tensorflow/tpu/blob/master/models/official/mnasnet/mnasnet_model.py + if isinstance(m, CondConv2d): + fan_out = m.kernel_size[0] * m.kernel_size[1] * m.out_channels + if fix_group_fanout: + fan_out //= m.groups + init_weight_fn = get_condconv_initializer( + lambda w: w.data.normal_(0, math.sqrt(2.0 / fan_out)), m.num_experts, m.weight_shape) + init_weight_fn(m.weight) + if m.bias is not None: + m.bias.data.zero_() + elif isinstance(m, nn.Conv2d): + fan_out = m.kernel_size[0] * m.kernel_size[1] * m.out_channels + if fix_group_fanout: + fan_out //= m.groups + m.weight.data.normal_(0, math.sqrt(2.0 / fan_out)) + if m.bias is not None: + m.bias.data.zero_() + elif isinstance(m, nn.BatchNorm2d): + m.weight.data.fill_(1.0) + m.bias.data.zero_() + elif isinstance(m, nn.Linear): + fan_out = m.weight.size(0) # fan-out + fan_in = 0 + if 'routing_fn' in n: + fan_in = m.weight.size(1) + init_range = 1.0 / math.sqrt(fan_in + fan_out) + m.weight.data.uniform_(-init_range, init_range) + m.bias.data.zero_() + + +def initialize_weight_default(m, n=''): + if isinstance(m, CondConv2d): + init_fn = get_condconv_initializer(partial( + nn.init.kaiming_normal_, mode='fan_out', nonlinearity='relu'), m.num_experts, m.weight_shape) + init_fn(m.weight) + elif isinstance(m, nn.Conv2d): + nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') + elif isinstance(m, nn.BatchNorm2d): + m.weight.data.fill_(1.0) + m.bias.data.zero_() + elif isinstance(m, nn.Linear): + nn.init.kaiming_uniform_(m.weight, mode='fan_in', nonlinearity='linear') diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/gen_efficientnet.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/gen_efficientnet.py new file mode 100644 index 00000000..cd170d4c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/gen_efficientnet.py @@ -0,0 +1,1450 @@ +""" Generic Efficient Networks + +A generic MobileNet class with building blocks to support a variety of models: + +* EfficientNet (B0-B8, L2 + Tensorflow pretrained AutoAug/RandAug/AdvProp/NoisyStudent ports) + - EfficientNet: Rethinking Model Scaling for CNNs - https://arxiv.org/abs/1905.11946 + - CondConv: Conditionally Parameterized Convolutions for Efficient Inference - https://arxiv.org/abs/1904.04971 + - Adversarial Examples Improve Image Recognition - https://arxiv.org/abs/1911.09665 + - Self-training with Noisy Student improves ImageNet classification - https://arxiv.org/abs/1911.04252 + +* EfficientNet-Lite + +* MixNet (Small, Medium, and Large) + - MixConv: Mixed Depthwise Convolutional Kernels - https://arxiv.org/abs/1907.09595 + +* MNasNet B1, A1 (SE), Small + - MnasNet: Platform-Aware Neural Architecture Search for Mobile - https://arxiv.org/abs/1807.11626 + +* FBNet-C + - FBNet: Hardware-Aware Efficient ConvNet Design via Differentiable NAS - https://arxiv.org/abs/1812.03443 + +* Single-Path NAS Pixel1 + - Single-Path NAS: Designing Hardware-Efficient ConvNets - https://arxiv.org/abs/1904.02877 + +* And likely more... + +Hacked together by / Copyright 2020 Ross Wightman +""" +import torch.nn as nn +import torch.nn.functional as F + +from .config import layer_config_kwargs, is_scriptable +from .conv2d_layers import select_conv2d +from .helpers import load_pretrained +from .efficientnet_builder import * + +__all__ = ['GenEfficientNet', 'mnasnet_050', 'mnasnet_075', 'mnasnet_100', 'mnasnet_b1', 'mnasnet_140', + 'semnasnet_050', 'semnasnet_075', 'semnasnet_100', 'mnasnet_a1', 'semnasnet_140', 'mnasnet_small', + 'mobilenetv2_100', 'mobilenetv2_140', 'mobilenetv2_110d', 'mobilenetv2_120d', + 'fbnetc_100', 'spnasnet_100', 'efficientnet_b0', 'efficientnet_b1', 'efficientnet_b2', 'efficientnet_b3', + 'efficientnet_b4', 'efficientnet_b5', 'efficientnet_b6', 'efficientnet_b7', 'efficientnet_b8', + 'efficientnet_l2', 'efficientnet_es', 'efficientnet_em', 'efficientnet_el', + 'efficientnet_cc_b0_4e', 'efficientnet_cc_b0_8e', 'efficientnet_cc_b1_8e', + 'efficientnet_lite0', 'efficientnet_lite1', 'efficientnet_lite2', 'efficientnet_lite3', 'efficientnet_lite4', + 'tf_efficientnet_b0', 'tf_efficientnet_b1', 'tf_efficientnet_b2', 'tf_efficientnet_b3', + 'tf_efficientnet_b4', 'tf_efficientnet_b5', 'tf_efficientnet_b6', 'tf_efficientnet_b7', 'tf_efficientnet_b8', + 'tf_efficientnet_b0_ap', 'tf_efficientnet_b1_ap', 'tf_efficientnet_b2_ap', 'tf_efficientnet_b3_ap', + 'tf_efficientnet_b4_ap', 'tf_efficientnet_b5_ap', 'tf_efficientnet_b6_ap', 'tf_efficientnet_b7_ap', + 'tf_efficientnet_b8_ap', 'tf_efficientnet_b0_ns', 'tf_efficientnet_b1_ns', 'tf_efficientnet_b2_ns', + 'tf_efficientnet_b3_ns', 'tf_efficientnet_b4_ns', 'tf_efficientnet_b5_ns', 'tf_efficientnet_b6_ns', + 'tf_efficientnet_b7_ns', 'tf_efficientnet_l2_ns', 'tf_efficientnet_l2_ns_475', + 'tf_efficientnet_es', 'tf_efficientnet_em', 'tf_efficientnet_el', + 'tf_efficientnet_cc_b0_4e', 'tf_efficientnet_cc_b0_8e', 'tf_efficientnet_cc_b1_8e', + 'tf_efficientnet_lite0', 'tf_efficientnet_lite1', 'tf_efficientnet_lite2', 'tf_efficientnet_lite3', + 'tf_efficientnet_lite4', + 'mixnet_s', 'mixnet_m', 'mixnet_l', 'mixnet_xl', 'tf_mixnet_s', 'tf_mixnet_m', 'tf_mixnet_l'] + + +model_urls = { + 'mnasnet_050': None, + 'mnasnet_075': None, + 'mnasnet_100': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/mnasnet_b1-74cb7081.pth', + 'mnasnet_140': None, + 'mnasnet_small': None, + + 'semnasnet_050': None, + 'semnasnet_075': None, + 'semnasnet_100': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/mnasnet_a1-d9418771.pth', + 'semnasnet_140': None, + + 'mobilenetv2_100': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/mobilenetv2_100_ra-b33bc2c4.pth', + 'mobilenetv2_110d': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/mobilenetv2_110d_ra-77090ade.pth', + 'mobilenetv2_120d': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/mobilenetv2_120d_ra-5987e2ed.pth', + 'mobilenetv2_140': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/mobilenetv2_140_ra-21a4e913.pth', + + 'fbnetc_100': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/fbnetc_100-c345b898.pth', + 'spnasnet_100': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/spnasnet_100-048bc3f4.pth', + + 'efficientnet_b0': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/efficientnet_b0_ra-3dd342df.pth', + 'efficientnet_b1': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/efficientnet_b1-533bc792.pth', + 'efficientnet_b2': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/efficientnet_b2_ra-bcdf34b7.pth', + 'efficientnet_b3': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/efficientnet_b3_ra2-cf984f9c.pth', + 'efficientnet_b4': None, + 'efficientnet_b5': None, + 'efficientnet_b6': None, + 'efficientnet_b7': None, + 'efficientnet_b8': None, + 'efficientnet_l2': None, + + 'efficientnet_es': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/efficientnet_es_ra-f111e99c.pth', + 'efficientnet_em': None, + 'efficientnet_el': None, + + 'efficientnet_cc_b0_4e': None, + 'efficientnet_cc_b0_8e': None, + 'efficientnet_cc_b1_8e': None, + + 'efficientnet_lite0': 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/efficientnet_lite0_ra-37913777.pth', + 'efficientnet_lite1': None, + 'efficientnet_lite2': None, + 'efficientnet_lite3': None, + 'efficientnet_lite4': None, + + 'tf_efficientnet_b0': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b0_aa-827b6e33.pth', + 'tf_efficientnet_b1': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b1_aa-ea7a6ee0.pth', + 'tf_efficientnet_b2': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b2_aa-60c94f97.pth', + 'tf_efficientnet_b3': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b3_aa-84b4657e.pth', + 'tf_efficientnet_b4': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b4_aa-818f208c.pth', + 'tf_efficientnet_b5': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b5_ra-9a3e5369.pth', + 'tf_efficientnet_b6': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b6_aa-80ba17e4.pth', + 'tf_efficientnet_b7': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b7_ra-6c08e654.pth', + 'tf_efficientnet_b8': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b8_ra-572d5dd9.pth', + + 'tf_efficientnet_b0_ap': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b0_ap-f262efe1.pth', + 'tf_efficientnet_b1_ap': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b1_ap-44ef0a3d.pth', + 'tf_efficientnet_b2_ap': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b2_ap-2f8e7636.pth', + 'tf_efficientnet_b3_ap': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b3_ap-aad25bdd.pth', + 'tf_efficientnet_b4_ap': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b4_ap-dedb23e6.pth', + 'tf_efficientnet_b5_ap': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b5_ap-9e82fae8.pth', + 'tf_efficientnet_b6_ap': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b6_ap-4ffb161f.pth', + 'tf_efficientnet_b7_ap': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b7_ap-ddb28fec.pth', + 'tf_efficientnet_b8_ap': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b8_ap-00e169fa.pth', + + 'tf_efficientnet_b0_ns': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b0_ns-c0e6a31c.pth', + 'tf_efficientnet_b1_ns': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b1_ns-99dd0c41.pth', + 'tf_efficientnet_b2_ns': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b2_ns-00306e48.pth', + 'tf_efficientnet_b3_ns': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b3_ns-9d44bf68.pth', + 'tf_efficientnet_b4_ns': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b4_ns-d6313a46.pth', + 'tf_efficientnet_b5_ns': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b5_ns-6f26d0cf.pth', + 'tf_efficientnet_b6_ns': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b6_ns-51548356.pth', + 'tf_efficientnet_b7_ns': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_b7_ns-1dbc32de.pth', + 'tf_efficientnet_l2_ns_475': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_l2_ns_475-bebbd00a.pth', + 'tf_efficientnet_l2_ns': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_l2_ns-df73bb44.pth', + + 'tf_efficientnet_es': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_es-ca1afbfe.pth', + 'tf_efficientnet_em': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_em-e78cfe58.pth', + 'tf_efficientnet_el': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_el-5143854e.pth', + + 'tf_efficientnet_cc_b0_4e': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_cc_b0_4e-4362b6b2.pth', + 'tf_efficientnet_cc_b0_8e': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_cc_b0_8e-66184a25.pth', + 'tf_efficientnet_cc_b1_8e': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_cc_b1_8e-f7c79ae1.pth', + + 'tf_efficientnet_lite0': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_lite0-0aa007d2.pth', + 'tf_efficientnet_lite1': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_lite1-bde8b488.pth', + 'tf_efficientnet_lite2': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_lite2-dcccb7df.pth', + 'tf_efficientnet_lite3': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_lite3-b733e338.pth', + 'tf_efficientnet_lite4': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_efficientnet_lite4-741542c3.pth', + + 'mixnet_s': 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/mixnet_s-a907afbc.pth', + 'mixnet_m': 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/mixnet_m-4647fc68.pth', + 'mixnet_l': 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/mixnet_l-5a9a2ed8.pth', + 'mixnet_xl': 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/mixnet_xl_ra-aac3c00c.pth', + + 'tf_mixnet_s': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_mixnet_s-89d3354b.pth', + 'tf_mixnet_m': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_mixnet_m-0f4d8805.pth', + 'tf_mixnet_l': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_mixnet_l-6c92e0c8.pth', +} + + +class GenEfficientNet(nn.Module): + """ Generic EfficientNets + + An implementation of mobile optimized networks that covers: + * EfficientNet (B0-B8, L2, CondConv, EdgeTPU) + * MixNet (Small, Medium, and Large, XL) + * MNASNet A1, B1, and small + * FBNet C + * Single-Path NAS Pixel1 + """ + + def __init__(self, block_args, num_classes=1000, in_chans=3, num_features=1280, stem_size=32, fix_stem=False, + channel_multiplier=1.0, channel_divisor=8, channel_min=None, + pad_type='', act_layer=nn.ReLU, drop_rate=0., drop_connect_rate=0., + se_kwargs=None, norm_layer=nn.BatchNorm2d, norm_kwargs=None, + weight_init='goog'): + super(GenEfficientNet, self).__init__() + self.drop_rate = drop_rate + + if not fix_stem: + stem_size = round_channels(stem_size, channel_multiplier, channel_divisor, channel_min) + self.conv_stem = select_conv2d(in_chans, stem_size, 3, stride=2, padding=pad_type) + self.bn1 = norm_layer(stem_size, **norm_kwargs) + self.act1 = act_layer(inplace=True) + in_chs = stem_size + + builder = EfficientNetBuilder( + channel_multiplier, channel_divisor, channel_min, + pad_type, act_layer, se_kwargs, norm_layer, norm_kwargs, drop_connect_rate) + self.blocks = nn.Sequential(*builder(in_chs, block_args)) + in_chs = builder.in_chs + + self.conv_head = select_conv2d(in_chs, num_features, 1, padding=pad_type) + self.bn2 = norm_layer(num_features, **norm_kwargs) + self.act2 = act_layer(inplace=True) + self.global_pool = nn.AdaptiveAvgPool2d(1) + self.classifier = nn.Linear(num_features, num_classes) + + for n, m in self.named_modules(): + if weight_init == 'goog': + initialize_weight_goog(m, n) + else: + initialize_weight_default(m, n) + + def features(self, x): + x = self.conv_stem(x) + x = self.bn1(x) + x = self.act1(x) + x = self.blocks(x) + x = self.conv_head(x) + x = self.bn2(x) + x = self.act2(x) + return x + + def as_sequential(self): + layers = [self.conv_stem, self.bn1, self.act1] + layers.extend(self.blocks) + layers.extend([ + self.conv_head, self.bn2, self.act2, + self.global_pool, nn.Flatten(), nn.Dropout(self.drop_rate), self.classifier]) + return nn.Sequential(*layers) + + def forward(self, x): + x = self.features(x) + x = self.global_pool(x) + x = x.flatten(1) + if self.drop_rate > 0.: + x = F.dropout(x, p=self.drop_rate, training=self.training) + return self.classifier(x) + + +def _create_model(model_kwargs, variant, pretrained=False): + as_sequential = model_kwargs.pop('as_sequential', False) + model = GenEfficientNet(**model_kwargs) + if pretrained: + load_pretrained(model, model_urls[variant]) + if as_sequential: + model = model.as_sequential() + return model + + +def _gen_mnasnet_a1(variant, channel_multiplier=1.0, pretrained=False, **kwargs): + """Creates a mnasnet-a1 model. + + Ref impl: https://github.com/tensorflow/tpu/tree/master/models/official/mnasnet + Paper: https://arxiv.org/pdf/1807.11626.pdf. + + Args: + channel_multiplier: multiplier to number of channels per layer. + """ + arch_def = [ + # stage 0, 112x112 in + ['ds_r1_k3_s1_e1_c16_noskip'], + # stage 1, 112x112 in + ['ir_r2_k3_s2_e6_c24'], + # stage 2, 56x56 in + ['ir_r3_k5_s2_e3_c40_se0.25'], + # stage 3, 28x28 in + ['ir_r4_k3_s2_e6_c80'], + # stage 4, 14x14in + ['ir_r2_k3_s1_e6_c112_se0.25'], + # stage 5, 14x14in + ['ir_r3_k5_s2_e6_c160_se0.25'], + # stage 6, 7x7 in + ['ir_r1_k3_s1_e6_c320'], + ] + with layer_config_kwargs(kwargs): + model_kwargs = dict( + block_args=decode_arch_def(arch_def), + stem_size=32, + channel_multiplier=channel_multiplier, + act_layer=resolve_act_layer(kwargs, 'relu'), + norm_kwargs=resolve_bn_args(kwargs), + **kwargs + ) + model = _create_model(model_kwargs, variant, pretrained) + return model + + +def _gen_mnasnet_b1(variant, channel_multiplier=1.0, pretrained=False, **kwargs): + """Creates a mnasnet-b1 model. + + Ref impl: https://github.com/tensorflow/tpu/tree/master/models/official/mnasnet + Paper: https://arxiv.org/pdf/1807.11626.pdf. + + Args: + channel_multiplier: multiplier to number of channels per layer. + """ + arch_def = [ + # stage 0, 112x112 in + ['ds_r1_k3_s1_c16_noskip'], + # stage 1, 112x112 in + ['ir_r3_k3_s2_e3_c24'], + # stage 2, 56x56 in + ['ir_r3_k5_s2_e3_c40'], + # stage 3, 28x28 in + ['ir_r3_k5_s2_e6_c80'], + # stage 4, 14x14in + ['ir_r2_k3_s1_e6_c96'], + # stage 5, 14x14in + ['ir_r4_k5_s2_e6_c192'], + # stage 6, 7x7 in + ['ir_r1_k3_s1_e6_c320_noskip'] + ] + with layer_config_kwargs(kwargs): + model_kwargs = dict( + block_args=decode_arch_def(arch_def), + stem_size=32, + channel_multiplier=channel_multiplier, + act_layer=resolve_act_layer(kwargs, 'relu'), + norm_kwargs=resolve_bn_args(kwargs), + **kwargs + ) + model = _create_model(model_kwargs, variant, pretrained) + return model + + +def _gen_mnasnet_small(variant, channel_multiplier=1.0, pretrained=False, **kwargs): + """Creates a mnasnet-b1 model. + + Ref impl: https://github.com/tensorflow/tpu/tree/master/models/official/mnasnet + Paper: https://arxiv.org/pdf/1807.11626.pdf. + + Args: + channel_multiplier: multiplier to number of channels per layer. + """ + arch_def = [ + ['ds_r1_k3_s1_c8'], + ['ir_r1_k3_s2_e3_c16'], + ['ir_r2_k3_s2_e6_c16'], + ['ir_r4_k5_s2_e6_c32_se0.25'], + ['ir_r3_k3_s1_e6_c32_se0.25'], + ['ir_r3_k5_s2_e6_c88_se0.25'], + ['ir_r1_k3_s1_e6_c144'] + ] + with layer_config_kwargs(kwargs): + model_kwargs = dict( + block_args=decode_arch_def(arch_def), + stem_size=8, + channel_multiplier=channel_multiplier, + act_layer=resolve_act_layer(kwargs, 'relu'), + norm_kwargs=resolve_bn_args(kwargs), + **kwargs + ) + model = _create_model(model_kwargs, variant, pretrained) + return model + + +def _gen_mobilenet_v2( + variant, channel_multiplier=1.0, depth_multiplier=1.0, fix_stem_head=False, pretrained=False, **kwargs): + """ Generate MobileNet-V2 network + Ref impl: https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet_v2.py + Paper: https://arxiv.org/abs/1801.04381 + """ + arch_def = [ + ['ds_r1_k3_s1_c16'], + ['ir_r2_k3_s2_e6_c24'], + ['ir_r3_k3_s2_e6_c32'], + ['ir_r4_k3_s2_e6_c64'], + ['ir_r3_k3_s1_e6_c96'], + ['ir_r3_k3_s2_e6_c160'], + ['ir_r1_k3_s1_e6_c320'], + ] + with layer_config_kwargs(kwargs): + model_kwargs = dict( + block_args=decode_arch_def(arch_def, depth_multiplier=depth_multiplier, fix_first_last=fix_stem_head), + num_features=1280 if fix_stem_head else round_channels(1280, channel_multiplier, 8, None), + stem_size=32, + fix_stem=fix_stem_head, + channel_multiplier=channel_multiplier, + norm_kwargs=resolve_bn_args(kwargs), + act_layer=nn.ReLU6, + **kwargs + ) + model = _create_model(model_kwargs, variant, pretrained) + return model + + +def _gen_fbnetc(variant, channel_multiplier=1.0, pretrained=False, **kwargs): + """ FBNet-C + + Paper: https://arxiv.org/abs/1812.03443 + Ref Impl: https://github.com/facebookresearch/maskrcnn-benchmark/blob/master/maskrcnn_benchmark/modeling/backbone/fbnet_modeldef.py + + NOTE: the impl above does not relate to the 'C' variant here, that was derived from paper, + it was used to confirm some building block details + """ + arch_def = [ + ['ir_r1_k3_s1_e1_c16'], + ['ir_r1_k3_s2_e6_c24', 'ir_r2_k3_s1_e1_c24'], + ['ir_r1_k5_s2_e6_c32', 'ir_r1_k5_s1_e3_c32', 'ir_r1_k5_s1_e6_c32', 'ir_r1_k3_s1_e6_c32'], + ['ir_r1_k5_s2_e6_c64', 'ir_r1_k5_s1_e3_c64', 'ir_r2_k5_s1_e6_c64'], + ['ir_r3_k5_s1_e6_c112', 'ir_r1_k5_s1_e3_c112'], + ['ir_r4_k5_s2_e6_c184'], + ['ir_r1_k3_s1_e6_c352'], + ] + with layer_config_kwargs(kwargs): + model_kwargs = dict( + block_args=decode_arch_def(arch_def), + stem_size=16, + num_features=1984, # paper suggests this, but is not 100% clear + channel_multiplier=channel_multiplier, + act_layer=resolve_act_layer(kwargs, 'relu'), + norm_kwargs=resolve_bn_args(kwargs), + **kwargs + ) + model = _create_model(model_kwargs, variant, pretrained) + return model + + +def _gen_spnasnet(variant, channel_multiplier=1.0, pretrained=False, **kwargs): + """Creates the Single-Path NAS model from search targeted for Pixel1 phone. + + Paper: https://arxiv.org/abs/1904.02877 + + Args: + channel_multiplier: multiplier to number of channels per layer. + """ + arch_def = [ + # stage 0, 112x112 in + ['ds_r1_k3_s1_c16_noskip'], + # stage 1, 112x112 in + ['ir_r3_k3_s2_e3_c24'], + # stage 2, 56x56 in + ['ir_r1_k5_s2_e6_c40', 'ir_r3_k3_s1_e3_c40'], + # stage 3, 28x28 in + ['ir_r1_k5_s2_e6_c80', 'ir_r3_k3_s1_e3_c80'], + # stage 4, 14x14in + ['ir_r1_k5_s1_e6_c96', 'ir_r3_k5_s1_e3_c96'], + # stage 5, 14x14in + ['ir_r4_k5_s2_e6_c192'], + # stage 6, 7x7 in + ['ir_r1_k3_s1_e6_c320_noskip'] + ] + with layer_config_kwargs(kwargs): + model_kwargs = dict( + block_args=decode_arch_def(arch_def), + stem_size=32, + channel_multiplier=channel_multiplier, + act_layer=resolve_act_layer(kwargs, 'relu'), + norm_kwargs=resolve_bn_args(kwargs), + **kwargs + ) + model = _create_model(model_kwargs, variant, pretrained) + return model + + +def _gen_efficientnet(variant, channel_multiplier=1.0, depth_multiplier=1.0, pretrained=False, **kwargs): + """Creates an EfficientNet model. + + Ref impl: https://github.com/tensorflow/tpu/blob/master/models/official/efficientnet/efficientnet_model.py + Paper: https://arxiv.org/abs/1905.11946 + + EfficientNet params + name: (channel_multiplier, depth_multiplier, resolution, dropout_rate) + 'efficientnet-b0': (1.0, 1.0, 224, 0.2), + 'efficientnet-b1': (1.0, 1.1, 240, 0.2), + 'efficientnet-b2': (1.1, 1.2, 260, 0.3), + 'efficientnet-b3': (1.2, 1.4, 300, 0.3), + 'efficientnet-b4': (1.4, 1.8, 380, 0.4), + 'efficientnet-b5': (1.6, 2.2, 456, 0.4), + 'efficientnet-b6': (1.8, 2.6, 528, 0.5), + 'efficientnet-b7': (2.0, 3.1, 600, 0.5), + 'efficientnet-b8': (2.2, 3.6, 672, 0.5), + + Args: + channel_multiplier: multiplier to number of channels per layer + depth_multiplier: multiplier to number of repeats per stage + + """ + arch_def = [ + ['ds_r1_k3_s1_e1_c16_se0.25'], + ['ir_r2_k3_s2_e6_c24_se0.25'], + ['ir_r2_k5_s2_e6_c40_se0.25'], + ['ir_r3_k3_s2_e6_c80_se0.25'], + ['ir_r3_k5_s1_e6_c112_se0.25'], + ['ir_r4_k5_s2_e6_c192_se0.25'], + ['ir_r1_k3_s1_e6_c320_se0.25'], + ] + with layer_config_kwargs(kwargs): + model_kwargs = dict( + block_args=decode_arch_def(arch_def, depth_multiplier), + num_features=round_channels(1280, channel_multiplier, 8, None), + stem_size=32, + channel_multiplier=channel_multiplier, + act_layer=resolve_act_layer(kwargs, 'swish'), + norm_kwargs=resolve_bn_args(kwargs), + **kwargs, + ) + model = _create_model(model_kwargs, variant, pretrained) + return model + + +def _gen_efficientnet_edge(variant, channel_multiplier=1.0, depth_multiplier=1.0, pretrained=False, **kwargs): + arch_def = [ + # NOTE `fc` is present to override a mismatch between stem channels and in chs not + # present in other models + ['er_r1_k3_s1_e4_c24_fc24_noskip'], + ['er_r2_k3_s2_e8_c32'], + ['er_r4_k3_s2_e8_c48'], + ['ir_r5_k5_s2_e8_c96'], + ['ir_r4_k5_s1_e8_c144'], + ['ir_r2_k5_s2_e8_c192'], + ] + with layer_config_kwargs(kwargs): + model_kwargs = dict( + block_args=decode_arch_def(arch_def, depth_multiplier), + num_features=round_channels(1280, channel_multiplier, 8, None), + stem_size=32, + channel_multiplier=channel_multiplier, + act_layer=resolve_act_layer(kwargs, 'relu'), + norm_kwargs=resolve_bn_args(kwargs), + **kwargs, + ) + model = _create_model(model_kwargs, variant, pretrained) + return model + + +def _gen_efficientnet_condconv( + variant, channel_multiplier=1.0, depth_multiplier=1.0, experts_multiplier=1, pretrained=False, **kwargs): + """Creates an efficientnet-condconv model.""" + arch_def = [ + ['ds_r1_k3_s1_e1_c16_se0.25'], + ['ir_r2_k3_s2_e6_c24_se0.25'], + ['ir_r2_k5_s2_e6_c40_se0.25'], + ['ir_r3_k3_s2_e6_c80_se0.25'], + ['ir_r3_k5_s1_e6_c112_se0.25_cc4'], + ['ir_r4_k5_s2_e6_c192_se0.25_cc4'], + ['ir_r1_k3_s1_e6_c320_se0.25_cc4'], + ] + with layer_config_kwargs(kwargs): + model_kwargs = dict( + block_args=decode_arch_def(arch_def, depth_multiplier, experts_multiplier=experts_multiplier), + num_features=round_channels(1280, channel_multiplier, 8, None), + stem_size=32, + channel_multiplier=channel_multiplier, + act_layer=resolve_act_layer(kwargs, 'swish'), + norm_kwargs=resolve_bn_args(kwargs), + **kwargs, + ) + model = _create_model(model_kwargs, variant, pretrained) + return model + + +def _gen_efficientnet_lite(variant, channel_multiplier=1.0, depth_multiplier=1.0, pretrained=False, **kwargs): + """Creates an EfficientNet-Lite model. + + Ref impl: https://github.com/tensorflow/tpu/tree/master/models/official/efficientnet/lite + Paper: https://arxiv.org/abs/1905.11946 + + EfficientNet params + name: (channel_multiplier, depth_multiplier, resolution, dropout_rate) + 'efficientnet-lite0': (1.0, 1.0, 224, 0.2), + 'efficientnet-lite1': (1.0, 1.1, 240, 0.2), + 'efficientnet-lite2': (1.1, 1.2, 260, 0.3), + 'efficientnet-lite3': (1.2, 1.4, 280, 0.3), + 'efficientnet-lite4': (1.4, 1.8, 300, 0.3), + + Args: + channel_multiplier: multiplier to number of channels per layer + depth_multiplier: multiplier to number of repeats per stage + """ + arch_def = [ + ['ds_r1_k3_s1_e1_c16'], + ['ir_r2_k3_s2_e6_c24'], + ['ir_r2_k5_s2_e6_c40'], + ['ir_r3_k3_s2_e6_c80'], + ['ir_r3_k5_s1_e6_c112'], + ['ir_r4_k5_s2_e6_c192'], + ['ir_r1_k3_s1_e6_c320'], + ] + with layer_config_kwargs(kwargs): + model_kwargs = dict( + block_args=decode_arch_def(arch_def, depth_multiplier, fix_first_last=True), + num_features=1280, + stem_size=32, + fix_stem=True, + channel_multiplier=channel_multiplier, + act_layer=nn.ReLU6, + norm_kwargs=resolve_bn_args(kwargs), + **kwargs, + ) + model = _create_model(model_kwargs, variant, pretrained) + return model + + +def _gen_mixnet_s(variant, channel_multiplier=1.0, pretrained=False, **kwargs): + """Creates a MixNet Small model. + + Ref impl: https://github.com/tensorflow/tpu/tree/master/models/official/mnasnet/mixnet + Paper: https://arxiv.org/abs/1907.09595 + """ + arch_def = [ + # stage 0, 112x112 in + ['ds_r1_k3_s1_e1_c16'], # relu + # stage 1, 112x112 in + ['ir_r1_k3_a1.1_p1.1_s2_e6_c24', 'ir_r1_k3_a1.1_p1.1_s1_e3_c24'], # relu + # stage 2, 56x56 in + ['ir_r1_k3.5.7_s2_e6_c40_se0.5_nsw', 'ir_r3_k3.5_a1.1_p1.1_s1_e6_c40_se0.5_nsw'], # swish + # stage 3, 28x28 in + ['ir_r1_k3.5.7_p1.1_s2_e6_c80_se0.25_nsw', 'ir_r2_k3.5_p1.1_s1_e6_c80_se0.25_nsw'], # swish + # stage 4, 14x14in + ['ir_r1_k3.5.7_a1.1_p1.1_s1_e6_c120_se0.5_nsw', 'ir_r2_k3.5.7.9_a1.1_p1.1_s1_e3_c120_se0.5_nsw'], # swish + # stage 5, 14x14in + ['ir_r1_k3.5.7.9.11_s2_e6_c200_se0.5_nsw', 'ir_r2_k3.5.7.9_p1.1_s1_e6_c200_se0.5_nsw'], # swish + # 7x7 + ] + with layer_config_kwargs(kwargs): + model_kwargs = dict( + block_args=decode_arch_def(arch_def), + num_features=1536, + stem_size=16, + channel_multiplier=channel_multiplier, + act_layer=resolve_act_layer(kwargs, 'relu'), + norm_kwargs=resolve_bn_args(kwargs), + **kwargs + ) + model = _create_model(model_kwargs, variant, pretrained) + return model + + +def _gen_mixnet_m(variant, channel_multiplier=1.0, depth_multiplier=1.0, pretrained=False, **kwargs): + """Creates a MixNet Medium-Large model. + + Ref impl: https://github.com/tensorflow/tpu/tree/master/models/official/mnasnet/mixnet + Paper: https://arxiv.org/abs/1907.09595 + """ + arch_def = [ + # stage 0, 112x112 in + ['ds_r1_k3_s1_e1_c24'], # relu + # stage 1, 112x112 in + ['ir_r1_k3.5.7_a1.1_p1.1_s2_e6_c32', 'ir_r1_k3_a1.1_p1.1_s1_e3_c32'], # relu + # stage 2, 56x56 in + ['ir_r1_k3.5.7.9_s2_e6_c40_se0.5_nsw', 'ir_r3_k3.5_a1.1_p1.1_s1_e6_c40_se0.5_nsw'], # swish + # stage 3, 28x28 in + ['ir_r1_k3.5.7_s2_e6_c80_se0.25_nsw', 'ir_r3_k3.5.7.9_a1.1_p1.1_s1_e6_c80_se0.25_nsw'], # swish + # stage 4, 14x14in + ['ir_r1_k3_s1_e6_c120_se0.5_nsw', 'ir_r3_k3.5.7.9_a1.1_p1.1_s1_e3_c120_se0.5_nsw'], # swish + # stage 5, 14x14in + ['ir_r1_k3.5.7.9_s2_e6_c200_se0.5_nsw', 'ir_r3_k3.5.7.9_p1.1_s1_e6_c200_se0.5_nsw'], # swish + # 7x7 + ] + with layer_config_kwargs(kwargs): + model_kwargs = dict( + block_args=decode_arch_def(arch_def, depth_multiplier, depth_trunc='round'), + num_features=1536, + stem_size=24, + channel_multiplier=channel_multiplier, + act_layer=resolve_act_layer(kwargs, 'relu'), + norm_kwargs=resolve_bn_args(kwargs), + **kwargs + ) + model = _create_model(model_kwargs, variant, pretrained) + return model + + +def mnasnet_050(pretrained=False, **kwargs): + """ MNASNet B1, depth multiplier of 0.5. """ + model = _gen_mnasnet_b1('mnasnet_050', 0.5, pretrained=pretrained, **kwargs) + return model + + +def mnasnet_075(pretrained=False, **kwargs): + """ MNASNet B1, depth multiplier of 0.75. """ + model = _gen_mnasnet_b1('mnasnet_075', 0.75, pretrained=pretrained, **kwargs) + return model + + +def mnasnet_100(pretrained=False, **kwargs): + """ MNASNet B1, depth multiplier of 1.0. """ + model = _gen_mnasnet_b1('mnasnet_100', 1.0, pretrained=pretrained, **kwargs) + return model + + +def mnasnet_b1(pretrained=False, **kwargs): + """ MNASNet B1, depth multiplier of 1.0. """ + return mnasnet_100(pretrained, **kwargs) + + +def mnasnet_140(pretrained=False, **kwargs): + """ MNASNet B1, depth multiplier of 1.4 """ + model = _gen_mnasnet_b1('mnasnet_140', 1.4, pretrained=pretrained, **kwargs) + return model + + +def semnasnet_050(pretrained=False, **kwargs): + """ MNASNet A1 (w/ SE), depth multiplier of 0.5 """ + model = _gen_mnasnet_a1('semnasnet_050', 0.5, pretrained=pretrained, **kwargs) + return model + + +def semnasnet_075(pretrained=False, **kwargs): + """ MNASNet A1 (w/ SE), depth multiplier of 0.75. """ + model = _gen_mnasnet_a1('semnasnet_075', 0.75, pretrained=pretrained, **kwargs) + return model + + +def semnasnet_100(pretrained=False, **kwargs): + """ MNASNet A1 (w/ SE), depth multiplier of 1.0. """ + model = _gen_mnasnet_a1('semnasnet_100', 1.0, pretrained=pretrained, **kwargs) + return model + + +def mnasnet_a1(pretrained=False, **kwargs): + """ MNASNet A1 (w/ SE), depth multiplier of 1.0. """ + return semnasnet_100(pretrained, **kwargs) + + +def semnasnet_140(pretrained=False, **kwargs): + """ MNASNet A1 (w/ SE), depth multiplier of 1.4. """ + model = _gen_mnasnet_a1('semnasnet_140', 1.4, pretrained=pretrained, **kwargs) + return model + + +def mnasnet_small(pretrained=False, **kwargs): + """ MNASNet Small, depth multiplier of 1.0. """ + model = _gen_mnasnet_small('mnasnet_small', 1.0, pretrained=pretrained, **kwargs) + return model + + +def mobilenetv2_100(pretrained=False, **kwargs): + """ MobileNet V2 w/ 1.0 channel multiplier """ + model = _gen_mobilenet_v2('mobilenetv2_100', 1.0, pretrained=pretrained, **kwargs) + return model + + +def mobilenetv2_140(pretrained=False, **kwargs): + """ MobileNet V2 w/ 1.4 channel multiplier """ + model = _gen_mobilenet_v2('mobilenetv2_140', 1.4, pretrained=pretrained, **kwargs) + return model + + +def mobilenetv2_110d(pretrained=False, **kwargs): + """ MobileNet V2 w/ 1.1 channel, 1.2 depth multipliers""" + model = _gen_mobilenet_v2( + 'mobilenetv2_110d', 1.1, depth_multiplier=1.2, fix_stem_head=True, pretrained=pretrained, **kwargs) + return model + + +def mobilenetv2_120d(pretrained=False, **kwargs): + """ MobileNet V2 w/ 1.2 channel, 1.4 depth multipliers """ + model = _gen_mobilenet_v2( + 'mobilenetv2_120d', 1.2, depth_multiplier=1.4, fix_stem_head=True, pretrained=pretrained, **kwargs) + return model + + +def fbnetc_100(pretrained=False, **kwargs): + """ FBNet-C """ + if pretrained: + # pretrained model trained with non-default BN epsilon + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + model = _gen_fbnetc('fbnetc_100', 1.0, pretrained=pretrained, **kwargs) + return model + + +def spnasnet_100(pretrained=False, **kwargs): + """ Single-Path NAS Pixel1""" + model = _gen_spnasnet('spnasnet_100', 1.0, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_b0(pretrained=False, **kwargs): + """ EfficientNet-B0 """ + # NOTE for train set drop_rate=0.2, drop_connect_rate=0.2 + model = _gen_efficientnet( + 'efficientnet_b0', channel_multiplier=1.0, depth_multiplier=1.0, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_b1(pretrained=False, **kwargs): + """ EfficientNet-B1 """ + # NOTE for train set drop_rate=0.2, drop_connect_rate=0.2 + model = _gen_efficientnet( + 'efficientnet_b1', channel_multiplier=1.0, depth_multiplier=1.1, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_b2(pretrained=False, **kwargs): + """ EfficientNet-B2 """ + # NOTE for train set drop_rate=0.3, drop_connect_rate=0.2 + model = _gen_efficientnet( + 'efficientnet_b2', channel_multiplier=1.1, depth_multiplier=1.2, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_b3(pretrained=False, **kwargs): + """ EfficientNet-B3 """ + # NOTE for train set drop_rate=0.3, drop_connect_rate=0.2 + model = _gen_efficientnet( + 'efficientnet_b3', channel_multiplier=1.2, depth_multiplier=1.4, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_b4(pretrained=False, **kwargs): + """ EfficientNet-B4 """ + # NOTE for train set drop_rate=0.4, drop_connect_rate=0.2 + model = _gen_efficientnet( + 'efficientnet_b4', channel_multiplier=1.4, depth_multiplier=1.8, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_b5(pretrained=False, **kwargs): + """ EfficientNet-B5 """ + # NOTE for train set drop_rate=0.4, drop_connect_rate=0.2 + model = _gen_efficientnet( + 'efficientnet_b5', channel_multiplier=1.6, depth_multiplier=2.2, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_b6(pretrained=False, **kwargs): + """ EfficientNet-B6 """ + # NOTE for train set drop_rate=0.5, drop_connect_rate=0.2 + model = _gen_efficientnet( + 'efficientnet_b6', channel_multiplier=1.8, depth_multiplier=2.6, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_b7(pretrained=False, **kwargs): + """ EfficientNet-B7 """ + # NOTE for train set drop_rate=0.5, drop_connect_rate=0.2 + model = _gen_efficientnet( + 'efficientnet_b7', channel_multiplier=2.0, depth_multiplier=3.1, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_b8(pretrained=False, **kwargs): + """ EfficientNet-B8 """ + # NOTE for train set drop_rate=0.5, drop_connect_rate=0.2 + model = _gen_efficientnet( + 'efficientnet_b8', channel_multiplier=2.2, depth_multiplier=3.6, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_l2(pretrained=False, **kwargs): + """ EfficientNet-L2. """ + # NOTE for train, drop_rate should be 0.5 + model = _gen_efficientnet( + 'efficientnet_l2', channel_multiplier=4.3, depth_multiplier=5.3, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_es(pretrained=False, **kwargs): + """ EfficientNet-Edge Small. """ + model = _gen_efficientnet_edge( + 'efficientnet_es', channel_multiplier=1.0, depth_multiplier=1.0, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_em(pretrained=False, **kwargs): + """ EfficientNet-Edge-Medium. """ + model = _gen_efficientnet_edge( + 'efficientnet_em', channel_multiplier=1.0, depth_multiplier=1.1, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_el(pretrained=False, **kwargs): + """ EfficientNet-Edge-Large. """ + model = _gen_efficientnet_edge( + 'efficientnet_el', channel_multiplier=1.2, depth_multiplier=1.4, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_cc_b0_4e(pretrained=False, **kwargs): + """ EfficientNet-CondConv-B0 w/ 8 Experts """ + # NOTE for train set drop_rate=0.25, drop_connect_rate=0.2 + model = _gen_efficientnet_condconv( + 'efficientnet_cc_b0_4e', channel_multiplier=1.0, depth_multiplier=1.0, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_cc_b0_8e(pretrained=False, **kwargs): + """ EfficientNet-CondConv-B0 w/ 8 Experts """ + # NOTE for train set drop_rate=0.25, drop_connect_rate=0.2 + model = _gen_efficientnet_condconv( + 'efficientnet_cc_b0_8e', channel_multiplier=1.0, depth_multiplier=1.0, experts_multiplier=2, + pretrained=pretrained, **kwargs) + return model + + +def efficientnet_cc_b1_8e(pretrained=False, **kwargs): + """ EfficientNet-CondConv-B1 w/ 8 Experts """ + # NOTE for train set drop_rate=0.25, drop_connect_rate=0.2 + model = _gen_efficientnet_condconv( + 'efficientnet_cc_b1_8e', channel_multiplier=1.0, depth_multiplier=1.1, experts_multiplier=2, + pretrained=pretrained, **kwargs) + return model + + +def efficientnet_lite0(pretrained=False, **kwargs): + """ EfficientNet-Lite0 """ + model = _gen_efficientnet_lite( + 'efficientnet_lite0', channel_multiplier=1.0, depth_multiplier=1.0, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_lite1(pretrained=False, **kwargs): + """ EfficientNet-Lite1 """ + model = _gen_efficientnet_lite( + 'efficientnet_lite1', channel_multiplier=1.0, depth_multiplier=1.1, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_lite2(pretrained=False, **kwargs): + """ EfficientNet-Lite2 """ + model = _gen_efficientnet_lite( + 'efficientnet_lite2', channel_multiplier=1.1, depth_multiplier=1.2, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_lite3(pretrained=False, **kwargs): + """ EfficientNet-Lite3 """ + model = _gen_efficientnet_lite( + 'efficientnet_lite3', channel_multiplier=1.2, depth_multiplier=1.4, pretrained=pretrained, **kwargs) + return model + + +def efficientnet_lite4(pretrained=False, **kwargs): + """ EfficientNet-Lite4 """ + model = _gen_efficientnet_lite( + 'efficientnet_lite4', channel_multiplier=1.4, depth_multiplier=1.8, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b0(pretrained=False, **kwargs): + """ EfficientNet-B0 AutoAug. Tensorflow compatible variant """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b0', channel_multiplier=1.0, depth_multiplier=1.0, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b1(pretrained=False, **kwargs): + """ EfficientNet-B1 AutoAug. Tensorflow compatible variant """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b1', channel_multiplier=1.0, depth_multiplier=1.1, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b2(pretrained=False, **kwargs): + """ EfficientNet-B2 AutoAug. Tensorflow compatible variant """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b2', channel_multiplier=1.1, depth_multiplier=1.2, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b3(pretrained=False, **kwargs): + """ EfficientNet-B3 AutoAug. Tensorflow compatible variant """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b3', channel_multiplier=1.2, depth_multiplier=1.4, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b4(pretrained=False, **kwargs): + """ EfficientNet-B4 AutoAug. Tensorflow compatible variant """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b4', channel_multiplier=1.4, depth_multiplier=1.8, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b5(pretrained=False, **kwargs): + """ EfficientNet-B5 RandAug. Tensorflow compatible variant """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b5', channel_multiplier=1.6, depth_multiplier=2.2, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b6(pretrained=False, **kwargs): + """ EfficientNet-B6 AutoAug. Tensorflow compatible variant """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b6', channel_multiplier=1.8, depth_multiplier=2.6, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b7(pretrained=False, **kwargs): + """ EfficientNet-B7 RandAug. Tensorflow compatible variant """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b7', channel_multiplier=2.0, depth_multiplier=3.1, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b8(pretrained=False, **kwargs): + """ EfficientNet-B8 RandAug. Tensorflow compatible variant """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b8', channel_multiplier=2.2, depth_multiplier=3.6, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b0_ap(pretrained=False, **kwargs): + """ EfficientNet-B0 AdvProp. Tensorflow compatible variant + Paper: Adversarial Examples Improve Image Recognition (https://arxiv.org/abs/1911.09665) + """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b0_ap', channel_multiplier=1.0, depth_multiplier=1.0, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b1_ap(pretrained=False, **kwargs): + """ EfficientNet-B1 AdvProp. Tensorflow compatible variant + Paper: Adversarial Examples Improve Image Recognition (https://arxiv.org/abs/1911.09665) + """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b1_ap', channel_multiplier=1.0, depth_multiplier=1.1, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b2_ap(pretrained=False, **kwargs): + """ EfficientNet-B2 AdvProp. Tensorflow compatible variant + Paper: Adversarial Examples Improve Image Recognition (https://arxiv.org/abs/1911.09665) + """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b2_ap', channel_multiplier=1.1, depth_multiplier=1.2, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b3_ap(pretrained=False, **kwargs): + """ EfficientNet-B3 AdvProp. Tensorflow compatible variant + Paper: Adversarial Examples Improve Image Recognition (https://arxiv.org/abs/1911.09665) + """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b3_ap', channel_multiplier=1.2, depth_multiplier=1.4, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b4_ap(pretrained=False, **kwargs): + """ EfficientNet-B4 AdvProp. Tensorflow compatible variant + Paper: Adversarial Examples Improve Image Recognition (https://arxiv.org/abs/1911.09665) + """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b4_ap', channel_multiplier=1.4, depth_multiplier=1.8, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b5_ap(pretrained=False, **kwargs): + """ EfficientNet-B5 AdvProp. Tensorflow compatible variant + Paper: Adversarial Examples Improve Image Recognition (https://arxiv.org/abs/1911.09665) + """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b5_ap', channel_multiplier=1.6, depth_multiplier=2.2, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b6_ap(pretrained=False, **kwargs): + """ EfficientNet-B6 AdvProp. Tensorflow compatible variant + Paper: Adversarial Examples Improve Image Recognition (https://arxiv.org/abs/1911.09665) + """ + # NOTE for train, drop_rate should be 0.5 + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b6_ap', channel_multiplier=1.8, depth_multiplier=2.6, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b7_ap(pretrained=False, **kwargs): + """ EfficientNet-B7 AdvProp. Tensorflow compatible variant + Paper: Adversarial Examples Improve Image Recognition (https://arxiv.org/abs/1911.09665) + """ + # NOTE for train, drop_rate should be 0.5 + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b7_ap', channel_multiplier=2.0, depth_multiplier=3.1, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b8_ap(pretrained=False, **kwargs): + """ EfficientNet-B8 AdvProp. Tensorflow compatible variant + Paper: Adversarial Examples Improve Image Recognition (https://arxiv.org/abs/1911.09665) + """ + # NOTE for train, drop_rate should be 0.5 + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b8_ap', channel_multiplier=2.2, depth_multiplier=3.6, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b0_ns(pretrained=False, **kwargs): + """ EfficientNet-B0 NoisyStudent. Tensorflow compatible variant + Paper: Self-training with Noisy Student improves ImageNet classification (https://arxiv.org/abs/1911.04252) + """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b0_ns', channel_multiplier=1.0, depth_multiplier=1.0, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b1_ns(pretrained=False, **kwargs): + """ EfficientNet-B1 NoisyStudent. Tensorflow compatible variant + Paper: Self-training with Noisy Student improves ImageNet classification (https://arxiv.org/abs/1911.04252) + """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b1_ns', channel_multiplier=1.0, depth_multiplier=1.1, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b2_ns(pretrained=False, **kwargs): + """ EfficientNet-B2 NoisyStudent. Tensorflow compatible variant + Paper: Self-training with Noisy Student improves ImageNet classification (https://arxiv.org/abs/1911.04252) + """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b2_ns', channel_multiplier=1.1, depth_multiplier=1.2, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b3_ns(pretrained=False, **kwargs): + """ EfficientNet-B3 NoisyStudent. Tensorflow compatible variant + Paper: Self-training with Noisy Student improves ImageNet classification (https://arxiv.org/abs/1911.04252) + """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b3_ns', channel_multiplier=1.2, depth_multiplier=1.4, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b4_ns(pretrained=False, **kwargs): + """ EfficientNet-B4 NoisyStudent. Tensorflow compatible variant + Paper: Self-training with Noisy Student improves ImageNet classification (https://arxiv.org/abs/1911.04252) + """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b4_ns', channel_multiplier=1.4, depth_multiplier=1.8, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b5_ns(pretrained=False, **kwargs): + """ EfficientNet-B5 NoisyStudent. Tensorflow compatible variant + Paper: Self-training with Noisy Student improves ImageNet classification (https://arxiv.org/abs/1911.04252) + """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b5_ns', channel_multiplier=1.6, depth_multiplier=2.2, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b6_ns(pretrained=False, **kwargs): + """ EfficientNet-B6 NoisyStudent. Tensorflow compatible variant + Paper: Self-training with Noisy Student improves ImageNet classification (https://arxiv.org/abs/1911.04252) + """ + # NOTE for train, drop_rate should be 0.5 + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b6_ns', channel_multiplier=1.8, depth_multiplier=2.6, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_b7_ns(pretrained=False, **kwargs): + """ EfficientNet-B7 NoisyStudent. Tensorflow compatible variant + Paper: Self-training with Noisy Student improves ImageNet classification (https://arxiv.org/abs/1911.04252) + """ + # NOTE for train, drop_rate should be 0.5 + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_b7_ns', channel_multiplier=2.0, depth_multiplier=3.1, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_l2_ns_475(pretrained=False, **kwargs): + """ EfficientNet-L2 NoisyStudent @ 475x475. Tensorflow compatible variant + Paper: Self-training with Noisy Student improves ImageNet classification (https://arxiv.org/abs/1911.04252) + """ + # NOTE for train, drop_rate should be 0.5 + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_l2_ns_475', channel_multiplier=4.3, depth_multiplier=5.3, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_l2_ns(pretrained=False, **kwargs): + """ EfficientNet-L2 NoisyStudent. Tensorflow compatible variant + Paper: Self-training with Noisy Student improves ImageNet classification (https://arxiv.org/abs/1911.04252) + """ + # NOTE for train, drop_rate should be 0.5 + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet( + 'tf_efficientnet_l2_ns', channel_multiplier=4.3, depth_multiplier=5.3, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_es(pretrained=False, **kwargs): + """ EfficientNet-Edge Small. Tensorflow compatible variant """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet_edge( + 'tf_efficientnet_es', channel_multiplier=1.0, depth_multiplier=1.0, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_em(pretrained=False, **kwargs): + """ EfficientNet-Edge-Medium. Tensorflow compatible variant """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet_edge( + 'tf_efficientnet_em', channel_multiplier=1.0, depth_multiplier=1.1, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_el(pretrained=False, **kwargs): + """ EfficientNet-Edge-Large. Tensorflow compatible variant """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet_edge( + 'tf_efficientnet_el', channel_multiplier=1.2, depth_multiplier=1.4, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_cc_b0_4e(pretrained=False, **kwargs): + """ EfficientNet-CondConv-B0 w/ 4 Experts """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet_condconv( + 'tf_efficientnet_cc_b0_4e', channel_multiplier=1.0, depth_multiplier=1.0, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_cc_b0_8e(pretrained=False, **kwargs): + """ EfficientNet-CondConv-B0 w/ 8 Experts """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet_condconv( + 'tf_efficientnet_cc_b0_8e', channel_multiplier=1.0, depth_multiplier=1.0, experts_multiplier=2, + pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_cc_b1_8e(pretrained=False, **kwargs): + """ EfficientNet-CondConv-B1 w/ 8 Experts """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet_condconv( + 'tf_efficientnet_cc_b1_8e', channel_multiplier=1.0, depth_multiplier=1.1, experts_multiplier=2, + pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_lite0(pretrained=False, **kwargs): + """ EfficientNet-Lite0. Tensorflow compatible variant """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet_lite( + 'tf_efficientnet_lite0', channel_multiplier=1.0, depth_multiplier=1.0, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_lite1(pretrained=False, **kwargs): + """ EfficientNet-Lite1. Tensorflow compatible variant """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet_lite( + 'tf_efficientnet_lite1', channel_multiplier=1.0, depth_multiplier=1.1, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_lite2(pretrained=False, **kwargs): + """ EfficientNet-Lite2. Tensorflow compatible variant """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet_lite( + 'tf_efficientnet_lite2', channel_multiplier=1.1, depth_multiplier=1.2, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_lite3(pretrained=False, **kwargs): + """ EfficientNet-Lite3. Tensorflow compatible variant """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet_lite( + 'tf_efficientnet_lite3', channel_multiplier=1.2, depth_multiplier=1.4, pretrained=pretrained, **kwargs) + return model + + +def tf_efficientnet_lite4(pretrained=False, **kwargs): + """ EfficientNet-Lite4. Tensorflow compatible variant """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_efficientnet_lite( + 'tf_efficientnet_lite4', channel_multiplier=1.4, depth_multiplier=1.8, pretrained=pretrained, **kwargs) + return model + + +def mixnet_s(pretrained=False, **kwargs): + """Creates a MixNet Small model. + """ + # NOTE for train set drop_rate=0.2 + model = _gen_mixnet_s( + 'mixnet_s', channel_multiplier=1.0, pretrained=pretrained, **kwargs) + return model + + +def mixnet_m(pretrained=False, **kwargs): + """Creates a MixNet Medium model. + """ + # NOTE for train set drop_rate=0.25 + model = _gen_mixnet_m( + 'mixnet_m', channel_multiplier=1.0, pretrained=pretrained, **kwargs) + return model + + +def mixnet_l(pretrained=False, **kwargs): + """Creates a MixNet Large model. + """ + # NOTE for train set drop_rate=0.25 + model = _gen_mixnet_m( + 'mixnet_l', channel_multiplier=1.3, pretrained=pretrained, **kwargs) + return model + + +def mixnet_xl(pretrained=False, **kwargs): + """Creates a MixNet Extra-Large model. + Not a paper spec, experimental def by RW w/ depth scaling. + """ + # NOTE for train set drop_rate=0.25, drop_connect_rate=0.2 + model = _gen_mixnet_m( + 'mixnet_xl', channel_multiplier=1.6, depth_multiplier=1.2, pretrained=pretrained, **kwargs) + return model + + +def mixnet_xxl(pretrained=False, **kwargs): + """Creates a MixNet Double Extra Large model. + Not a paper spec, experimental def by RW w/ depth scaling. + """ + # NOTE for train set drop_rate=0.3, drop_connect_rate=0.2 + model = _gen_mixnet_m( + 'mixnet_xxl', channel_multiplier=2.4, depth_multiplier=1.3, pretrained=pretrained, **kwargs) + return model + + +def tf_mixnet_s(pretrained=False, **kwargs): + """Creates a MixNet Small model. Tensorflow compatible variant + """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_mixnet_s( + 'tf_mixnet_s', channel_multiplier=1.0, pretrained=pretrained, **kwargs) + return model + + +def tf_mixnet_m(pretrained=False, **kwargs): + """Creates a MixNet Medium model. Tensorflow compatible variant + """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_mixnet_m( + 'tf_mixnet_m', channel_multiplier=1.0, pretrained=pretrained, **kwargs) + return model + + +def tf_mixnet_l(pretrained=False, **kwargs): + """Creates a MixNet Large model. Tensorflow compatible variant + """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_mixnet_m( + 'tf_mixnet_l', channel_multiplier=1.3, pretrained=pretrained, **kwargs) + return model diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/helpers.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/helpers.py new file mode 100644 index 00000000..3f83a07d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/helpers.py @@ -0,0 +1,71 @@ +""" Checkpoint loading / state_dict helpers +Copyright 2020 Ross Wightman +""" +import torch +import os +from collections import OrderedDict +try: + from torch.hub import load_state_dict_from_url +except ImportError: + from torch.utils.model_zoo import load_url as load_state_dict_from_url + + +def load_checkpoint(model, checkpoint_path): + if checkpoint_path and os.path.isfile(checkpoint_path): + print("=> Loading checkpoint '{}'".format(checkpoint_path)) + checkpoint = torch.load(checkpoint_path) + if isinstance(checkpoint, dict) and 'state_dict' in checkpoint: + new_state_dict = OrderedDict() + for k, v in checkpoint['state_dict'].items(): + if k.startswith('module'): + name = k[7:] # remove `module.` + else: + name = k + new_state_dict[name] = v + model.load_state_dict(new_state_dict) + else: + model.load_state_dict(checkpoint) + print("=> Loaded checkpoint '{}'".format(checkpoint_path)) + else: + print("=> Error: No checkpoint found at '{}'".format(checkpoint_path)) + raise FileNotFoundError() + + +def load_pretrained(model, url, filter_fn=None, strict=True): + if not url: + print("=> Warning: Pretrained model URL is empty, using random initialization.") + return + + state_dict = load_state_dict_from_url(url, progress=False, map_location='cpu') + + input_conv = 'conv_stem' + classifier = 'classifier' + in_chans = getattr(model, input_conv).weight.shape[1] + num_classes = getattr(model, classifier).weight.shape[0] + + input_conv_weight = input_conv + '.weight' + pretrained_in_chans = state_dict[input_conv_weight].shape[1] + if in_chans != pretrained_in_chans: + if in_chans == 1: + print('=> Converting pretrained input conv {} from {} to 1 channel'.format( + input_conv_weight, pretrained_in_chans)) + conv1_weight = state_dict[input_conv_weight] + state_dict[input_conv_weight] = conv1_weight.sum(dim=1, keepdim=True) + else: + print('=> Discarding pretrained input conv {} since input channel count != {}'.format( + input_conv_weight, pretrained_in_chans)) + del state_dict[input_conv_weight] + strict = False + + classifier_weight = classifier + '.weight' + pretrained_num_classes = state_dict[classifier_weight].shape[0] + if num_classes != pretrained_num_classes: + print('=> Discarding pretrained classifier since num_classes != {}'.format(pretrained_num_classes)) + del state_dict[classifier_weight] + del state_dict[classifier + '.bias'] + strict = False + + if filter_fn is not None: + state_dict = filter_fn(state_dict) + + model.load_state_dict(state_dict, strict=strict) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/mobilenetv3.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/mobilenetv3.py new file mode 100644 index 00000000..b5966c28 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/mobilenetv3.py @@ -0,0 +1,364 @@ +""" MobileNet-V3 + +A PyTorch impl of MobileNet-V3, compatible with TF weights from official impl. + +Paper: Searching for MobileNetV3 - https://arxiv.org/abs/1905.02244 + +Hacked together by / Copyright 2020 Ross Wightman +""" +import torch.nn as nn +import torch.nn.functional as F + +from .activations import get_act_fn, get_act_layer, HardSwish +from .config import layer_config_kwargs +from .conv2d_layers import select_conv2d +from .helpers import load_pretrained +from .efficientnet_builder import * + +__all__ = ['mobilenetv3_rw', 'mobilenetv3_large_075', 'mobilenetv3_large_100', 'mobilenetv3_large_minimal_100', + 'mobilenetv3_small_075', 'mobilenetv3_small_100', 'mobilenetv3_small_minimal_100', + 'tf_mobilenetv3_large_075', 'tf_mobilenetv3_large_100', 'tf_mobilenetv3_large_minimal_100', + 'tf_mobilenetv3_small_075', 'tf_mobilenetv3_small_100', 'tf_mobilenetv3_small_minimal_100'] + +model_urls = { + 'mobilenetv3_rw': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/mobilenetv3_100-35495452.pth', + 'mobilenetv3_large_075': None, + 'mobilenetv3_large_100': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/mobilenetv3_large_100_ra-f55367f5.pth', + 'mobilenetv3_large_minimal_100': None, + 'mobilenetv3_small_075': None, + 'mobilenetv3_small_100': None, + 'mobilenetv3_small_minimal_100': None, + 'tf_mobilenetv3_large_075': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_mobilenetv3_large_075-150ee8b0.pth', + 'tf_mobilenetv3_large_100': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_mobilenetv3_large_100-427764d5.pth', + 'tf_mobilenetv3_large_minimal_100': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_mobilenetv3_large_minimal_100-8596ae28.pth', + 'tf_mobilenetv3_small_075': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_mobilenetv3_small_075-da427f52.pth', + 'tf_mobilenetv3_small_100': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_mobilenetv3_small_100-37f49e2b.pth', + 'tf_mobilenetv3_small_minimal_100': + 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/tf_mobilenetv3_small_minimal_100-922a7843.pth', +} + + +class MobileNetV3(nn.Module): + """ MobileNet-V3 + + A this model utilizes the MobileNet-v3 specific 'efficient head', where global pooling is done before the + head convolution without a final batch-norm layer before the classifier. + + Paper: https://arxiv.org/abs/1905.02244 + """ + + def __init__(self, block_args, num_classes=1000, in_chans=3, stem_size=16, num_features=1280, head_bias=True, + channel_multiplier=1.0, pad_type='', act_layer=HardSwish, drop_rate=0., drop_connect_rate=0., + se_kwargs=None, norm_layer=nn.BatchNorm2d, norm_kwargs=None, weight_init='goog'): + super(MobileNetV3, self).__init__() + self.drop_rate = drop_rate + + stem_size = round_channels(stem_size, channel_multiplier) + self.conv_stem = select_conv2d(in_chans, stem_size, 3, stride=2, padding=pad_type) + self.bn1 = nn.BatchNorm2d(stem_size, **norm_kwargs) + self.act1 = act_layer(inplace=True) + in_chs = stem_size + + builder = EfficientNetBuilder( + channel_multiplier, pad_type=pad_type, act_layer=act_layer, se_kwargs=se_kwargs, + norm_layer=norm_layer, norm_kwargs=norm_kwargs, drop_connect_rate=drop_connect_rate) + self.blocks = nn.Sequential(*builder(in_chs, block_args)) + in_chs = builder.in_chs + + self.global_pool = nn.AdaptiveAvgPool2d(1) + self.conv_head = select_conv2d(in_chs, num_features, 1, padding=pad_type, bias=head_bias) + self.act2 = act_layer(inplace=True) + self.classifier = nn.Linear(num_features, num_classes) + + for m in self.modules(): + if weight_init == 'goog': + initialize_weight_goog(m) + else: + initialize_weight_default(m) + + def as_sequential(self): + layers = [self.conv_stem, self.bn1, self.act1] + layers.extend(self.blocks) + layers.extend([ + self.global_pool, self.conv_head, self.act2, + nn.Flatten(), nn.Dropout(self.drop_rate), self.classifier]) + return nn.Sequential(*layers) + + def features(self, x): + x = self.conv_stem(x) + x = self.bn1(x) + x = self.act1(x) + x = self.blocks(x) + x = self.global_pool(x) + x = self.conv_head(x) + x = self.act2(x) + return x + + def forward(self, x): + x = self.features(x) + x = x.flatten(1) + if self.drop_rate > 0.: + x = F.dropout(x, p=self.drop_rate, training=self.training) + return self.classifier(x) + + +def _create_model(model_kwargs, variant, pretrained=False): + as_sequential = model_kwargs.pop('as_sequential', False) + model = MobileNetV3(**model_kwargs) + if pretrained and model_urls[variant]: + load_pretrained(model, model_urls[variant]) + if as_sequential: + model = model.as_sequential() + return model + + +def _gen_mobilenet_v3_rw(variant, channel_multiplier=1.0, pretrained=False, **kwargs): + """Creates a MobileNet-V3 model (RW variant). + + Paper: https://arxiv.org/abs/1905.02244 + + This was my first attempt at reproducing the MobileNet-V3 from paper alone. It came close to the + eventual Tensorflow reference impl but has a few differences: + 1. This model has no bias on the head convolution + 2. This model forces no residual (noskip) on the first DWS block, this is different than MnasNet + 3. This model always uses ReLU for the SE activation layer, other models in the family inherit their act layer + from their parent block + 4. This model does not enforce divisible by 8 limitation on the SE reduction channel count + + Overall the changes are fairly minor and result in a very small parameter count difference and no + top-1/5 + + Args: + channel_multiplier: multiplier to number of channels per layer. + """ + arch_def = [ + # stage 0, 112x112 in + ['ds_r1_k3_s1_e1_c16_nre_noskip'], # relu + # stage 1, 112x112 in + ['ir_r1_k3_s2_e4_c24_nre', 'ir_r1_k3_s1_e3_c24_nre'], # relu + # stage 2, 56x56 in + ['ir_r3_k5_s2_e3_c40_se0.25_nre'], # relu + # stage 3, 28x28 in + ['ir_r1_k3_s2_e6_c80', 'ir_r1_k3_s1_e2.5_c80', 'ir_r2_k3_s1_e2.3_c80'], # hard-swish + # stage 4, 14x14in + ['ir_r2_k3_s1_e6_c112_se0.25'], # hard-swish + # stage 5, 14x14in + ['ir_r3_k5_s2_e6_c160_se0.25'], # hard-swish + # stage 6, 7x7 in + ['cn_r1_k1_s1_c960'], # hard-swish + ] + with layer_config_kwargs(kwargs): + model_kwargs = dict( + block_args=decode_arch_def(arch_def), + head_bias=False, # one of my mistakes + channel_multiplier=channel_multiplier, + act_layer=resolve_act_layer(kwargs, 'hard_swish'), + se_kwargs=dict(gate_fn=get_act_fn('hard_sigmoid'), reduce_mid=True), + norm_kwargs=resolve_bn_args(kwargs), + **kwargs, + ) + model = _create_model(model_kwargs, variant, pretrained) + return model + + +def _gen_mobilenet_v3(variant, channel_multiplier=1.0, pretrained=False, **kwargs): + """Creates a MobileNet-V3 large/small/minimal models. + + Ref impl: https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet_v3.py + Paper: https://arxiv.org/abs/1905.02244 + + Args: + channel_multiplier: multiplier to number of channels per layer. + """ + if 'small' in variant: + num_features = 1024 + if 'minimal' in variant: + act_layer = 'relu' + arch_def = [ + # stage 0, 112x112 in + ['ds_r1_k3_s2_e1_c16'], + # stage 1, 56x56 in + ['ir_r1_k3_s2_e4.5_c24', 'ir_r1_k3_s1_e3.67_c24'], + # stage 2, 28x28 in + ['ir_r1_k3_s2_e4_c40', 'ir_r2_k3_s1_e6_c40'], + # stage 3, 14x14 in + ['ir_r2_k3_s1_e3_c48'], + # stage 4, 14x14in + ['ir_r3_k3_s2_e6_c96'], + # stage 6, 7x7 in + ['cn_r1_k1_s1_c576'], + ] + else: + act_layer = 'hard_swish' + arch_def = [ + # stage 0, 112x112 in + ['ds_r1_k3_s2_e1_c16_se0.25_nre'], # relu + # stage 1, 56x56 in + ['ir_r1_k3_s2_e4.5_c24_nre', 'ir_r1_k3_s1_e3.67_c24_nre'], # relu + # stage 2, 28x28 in + ['ir_r1_k5_s2_e4_c40_se0.25', 'ir_r2_k5_s1_e6_c40_se0.25'], # hard-swish + # stage 3, 14x14 in + ['ir_r2_k5_s1_e3_c48_se0.25'], # hard-swish + # stage 4, 14x14in + ['ir_r3_k5_s2_e6_c96_se0.25'], # hard-swish + # stage 6, 7x7 in + ['cn_r1_k1_s1_c576'], # hard-swish + ] + else: + num_features = 1280 + if 'minimal' in variant: + act_layer = 'relu' + arch_def = [ + # stage 0, 112x112 in + ['ds_r1_k3_s1_e1_c16'], + # stage 1, 112x112 in + ['ir_r1_k3_s2_e4_c24', 'ir_r1_k3_s1_e3_c24'], + # stage 2, 56x56 in + ['ir_r3_k3_s2_e3_c40'], + # stage 3, 28x28 in + ['ir_r1_k3_s2_e6_c80', 'ir_r1_k3_s1_e2.5_c80', 'ir_r2_k3_s1_e2.3_c80'], + # stage 4, 14x14in + ['ir_r2_k3_s1_e6_c112'], + # stage 5, 14x14in + ['ir_r3_k3_s2_e6_c160'], + # stage 6, 7x7 in + ['cn_r1_k1_s1_c960'], + ] + else: + act_layer = 'hard_swish' + arch_def = [ + # stage 0, 112x112 in + ['ds_r1_k3_s1_e1_c16_nre'], # relu + # stage 1, 112x112 in + ['ir_r1_k3_s2_e4_c24_nre', 'ir_r1_k3_s1_e3_c24_nre'], # relu + # stage 2, 56x56 in + ['ir_r3_k5_s2_e3_c40_se0.25_nre'], # relu + # stage 3, 28x28 in + ['ir_r1_k3_s2_e6_c80', 'ir_r1_k3_s1_e2.5_c80', 'ir_r2_k3_s1_e2.3_c80'], # hard-swish + # stage 4, 14x14in + ['ir_r2_k3_s1_e6_c112_se0.25'], # hard-swish + # stage 5, 14x14in + ['ir_r3_k5_s2_e6_c160_se0.25'], # hard-swish + # stage 6, 7x7 in + ['cn_r1_k1_s1_c960'], # hard-swish + ] + with layer_config_kwargs(kwargs): + model_kwargs = dict( + block_args=decode_arch_def(arch_def), + num_features=num_features, + stem_size=16, + channel_multiplier=channel_multiplier, + act_layer=resolve_act_layer(kwargs, act_layer), + se_kwargs=dict( + act_layer=get_act_layer('relu'), gate_fn=get_act_fn('hard_sigmoid'), reduce_mid=True, divisor=8), + norm_kwargs=resolve_bn_args(kwargs), + **kwargs, + ) + model = _create_model(model_kwargs, variant, pretrained) + return model + + +def mobilenetv3_rw(pretrained=False, **kwargs): + """ MobileNet-V3 RW + Attn: See note in gen function for this variant. + """ + # NOTE for train set drop_rate=0.2 + if pretrained: + # pretrained model trained with non-default BN epsilon + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + model = _gen_mobilenet_v3_rw('mobilenetv3_rw', 1.0, pretrained=pretrained, **kwargs) + return model + + +def mobilenetv3_large_075(pretrained=False, **kwargs): + """ MobileNet V3 Large 0.75""" + # NOTE for train set drop_rate=0.2 + model = _gen_mobilenet_v3('mobilenetv3_large_075', 0.75, pretrained=pretrained, **kwargs) + return model + + +def mobilenetv3_large_100(pretrained=False, **kwargs): + """ MobileNet V3 Large 1.0 """ + # NOTE for train set drop_rate=0.2 + model = _gen_mobilenet_v3('mobilenetv3_large_100', 1.0, pretrained=pretrained, **kwargs) + return model + + +def mobilenetv3_large_minimal_100(pretrained=False, **kwargs): + """ MobileNet V3 Large (Minimalistic) 1.0 """ + # NOTE for train set drop_rate=0.2 + model = _gen_mobilenet_v3('mobilenetv3_large_minimal_100', 1.0, pretrained=pretrained, **kwargs) + return model + + +def mobilenetv3_small_075(pretrained=False, **kwargs): + """ MobileNet V3 Small 0.75 """ + model = _gen_mobilenet_v3('mobilenetv3_small_075', 0.75, pretrained=pretrained, **kwargs) + return model + + +def mobilenetv3_small_100(pretrained=False, **kwargs): + """ MobileNet V3 Small 1.0 """ + model = _gen_mobilenet_v3('mobilenetv3_small_100', 1.0, pretrained=pretrained, **kwargs) + return model + + +def mobilenetv3_small_minimal_100(pretrained=False, **kwargs): + """ MobileNet V3 Small (Minimalistic) 1.0 """ + model = _gen_mobilenet_v3('mobilenetv3_small_minimal_100', 1.0, pretrained=pretrained, **kwargs) + return model + + +def tf_mobilenetv3_large_075(pretrained=False, **kwargs): + """ MobileNet V3 Large 0.75. Tensorflow compat variant. """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_mobilenet_v3('tf_mobilenetv3_large_075', 0.75, pretrained=pretrained, **kwargs) + return model + + +def tf_mobilenetv3_large_100(pretrained=False, **kwargs): + """ MobileNet V3 Large 1.0. Tensorflow compat variant. """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_mobilenet_v3('tf_mobilenetv3_large_100', 1.0, pretrained=pretrained, **kwargs) + return model + + +def tf_mobilenetv3_large_minimal_100(pretrained=False, **kwargs): + """ MobileNet V3 Large Minimalistic 1.0. Tensorflow compat variant. """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_mobilenet_v3('tf_mobilenetv3_large_minimal_100', 1.0, pretrained=pretrained, **kwargs) + return model + + +def tf_mobilenetv3_small_075(pretrained=False, **kwargs): + """ MobileNet V3 Small 0.75. Tensorflow compat variant. """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_mobilenet_v3('tf_mobilenetv3_small_075', 0.75, pretrained=pretrained, **kwargs) + return model + + +def tf_mobilenetv3_small_100(pretrained=False, **kwargs): + """ MobileNet V3 Small 1.0. Tensorflow compat variant.""" + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_mobilenet_v3('tf_mobilenetv3_small_100', 1.0, pretrained=pretrained, **kwargs) + return model + + +def tf_mobilenetv3_small_minimal_100(pretrained=False, **kwargs): + """ MobileNet V3 Small Minimalistic 1.0. Tensorflow compat variant. """ + kwargs['bn_eps'] = BN_EPS_TF_DEFAULT + kwargs['pad_type'] = 'same' + model = _gen_mobilenet_v3('tf_mobilenetv3_small_minimal_100', 1.0, pretrained=pretrained, **kwargs) + return model diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/model_factory.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/model_factory.py new file mode 100644 index 00000000..4d46ea8b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/model_factory.py @@ -0,0 +1,27 @@ +from .config import set_layer_config +from .helpers import load_checkpoint + +from .gen_efficientnet import * +from .mobilenetv3 import * + + +def create_model( + model_name='mnasnet_100', + pretrained=None, + num_classes=1000, + in_chans=3, + checkpoint_path='', + **kwargs): + + model_kwargs = dict(num_classes=num_classes, in_chans=in_chans, pretrained=pretrained, **kwargs) + + if model_name in globals(): + create_fn = globals()[model_name] + model = create_fn(**model_kwargs) + else: + raise RuntimeError('Unknown model (%s)' % model_name) + + if checkpoint_path and not pretrained: + load_checkpoint(model, checkpoint_path) + + return model diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/version.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/version.py new file mode 100644 index 00000000..a6221b3d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/geffnet/version.py @@ -0,0 +1 @@ +__version__ = '1.0.2' diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/hubconf.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/hubconf.py new file mode 100644 index 00000000..45b17b99 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/hubconf.py @@ -0,0 +1,84 @@ +dependencies = ['torch', 'math'] + +from geffnet import efficientnet_b0 +from geffnet import efficientnet_b1 +from geffnet import efficientnet_b2 +from geffnet import efficientnet_b3 + +from geffnet import efficientnet_es + +from geffnet import efficientnet_lite0 + +from geffnet import mixnet_s +from geffnet import mixnet_m +from geffnet import mixnet_l +from geffnet import mixnet_xl + +from geffnet import mobilenetv2_100 +from geffnet import mobilenetv2_110d +from geffnet import mobilenetv2_120d +from geffnet import mobilenetv2_140 + +from geffnet import mobilenetv3_large_100 +from geffnet import mobilenetv3_rw +from geffnet import mnasnet_a1 +from geffnet import mnasnet_b1 +from geffnet import fbnetc_100 +from geffnet import spnasnet_100 + +from geffnet import tf_efficientnet_b0 +from geffnet import tf_efficientnet_b1 +from geffnet import tf_efficientnet_b2 +from geffnet import tf_efficientnet_b3 +from geffnet import tf_efficientnet_b4 +from geffnet import tf_efficientnet_b5 +from geffnet import tf_efficientnet_b6 +from geffnet import tf_efficientnet_b7 +from geffnet import tf_efficientnet_b8 + +from geffnet import tf_efficientnet_b0_ap +from geffnet import tf_efficientnet_b1_ap +from geffnet import tf_efficientnet_b2_ap +from geffnet import tf_efficientnet_b3_ap +from geffnet import tf_efficientnet_b4_ap +from geffnet import tf_efficientnet_b5_ap +from geffnet import tf_efficientnet_b6_ap +from geffnet import tf_efficientnet_b7_ap +from geffnet import tf_efficientnet_b8_ap + +from geffnet import tf_efficientnet_b0_ns +from geffnet import tf_efficientnet_b1_ns +from geffnet import tf_efficientnet_b2_ns +from geffnet import tf_efficientnet_b3_ns +from geffnet import tf_efficientnet_b4_ns +from geffnet import tf_efficientnet_b5_ns +from geffnet import tf_efficientnet_b6_ns +from geffnet import tf_efficientnet_b7_ns +from geffnet import tf_efficientnet_l2_ns_475 +from geffnet import tf_efficientnet_l2_ns + +from geffnet import tf_efficientnet_es +from geffnet import tf_efficientnet_em +from geffnet import tf_efficientnet_el + +from geffnet import tf_efficientnet_cc_b0_4e +from geffnet import tf_efficientnet_cc_b0_8e +from geffnet import tf_efficientnet_cc_b1_8e + +from geffnet import tf_efficientnet_lite0 +from geffnet import tf_efficientnet_lite1 +from geffnet import tf_efficientnet_lite2 +from geffnet import tf_efficientnet_lite3 +from geffnet import tf_efficientnet_lite4 + +from geffnet import tf_mixnet_s +from geffnet import tf_mixnet_m +from geffnet import tf_mixnet_l + +from geffnet import tf_mobilenetv3_large_075 +from geffnet import tf_mobilenetv3_large_100 +from geffnet import tf_mobilenetv3_large_minimal_100 +from geffnet import tf_mobilenetv3_small_075 +from geffnet import tf_mobilenetv3_small_100 +from geffnet import tf_mobilenetv3_small_minimal_100 + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/onnx_export.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/onnx_export.py new file mode 100644 index 00000000..7a5162ce --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/onnx_export.py @@ -0,0 +1,120 @@ +""" ONNX export script + +Export PyTorch models as ONNX graphs. + +This export script originally started as an adaptation of code snippets found at +https://pytorch.org/tutorials/advanced/super_resolution_with_onnxruntime.html + +The default parameters work with PyTorch 1.6 and ONNX 1.7 and produce an optimal ONNX graph +for hosting in the ONNX runtime (see onnx_validate.py). To export an ONNX model compatible +with caffe2 (see caffe2_benchmark.py and caffe2_validate.py), the --keep-init and --aten-fallback +flags are currently required. + +Older versions of PyTorch/ONNX (tested PyTorch 1.4, ONNX 1.5) do not need extra flags for +caffe2 compatibility, but they produce a model that isn't as fast running on ONNX runtime. + +Most new release of PyTorch and ONNX cause some sort of breakage in the export / usage of ONNX models. +Please do your research and search ONNX and PyTorch issue tracker before asking me. Thanks. + +Copyright 2020 Ross Wightman +""" +import argparse +import torch +import numpy as np + +import onnx +import geffnet + +parser = argparse.ArgumentParser(description='PyTorch ImageNet Validation') +parser.add_argument('output', metavar='ONNX_FILE', + help='output model filename') +parser.add_argument('--model', '-m', metavar='MODEL', default='mobilenetv3_large_100', + help='model architecture (default: mobilenetv3_large_100)') +parser.add_argument('--opset', type=int, default=10, + help='ONNX opset to use (default: 10)') +parser.add_argument('--keep-init', action='store_true', default=False, + help='Keep initializers as input. Needed for Caffe2 compatible export in newer PyTorch/ONNX.') +parser.add_argument('--aten-fallback', action='store_true', default=False, + help='Fallback to ATEN ops. Helps fix AdaptiveAvgPool issue with Caffe2 in newer PyTorch/ONNX.') +parser.add_argument('--dynamic-size', action='store_true', default=False, + help='Export model width dynamic width/height. Not recommended for "tf" models with SAME padding.') +parser.add_argument('-b', '--batch-size', default=1, type=int, + metavar='N', help='mini-batch size (default: 1)') +parser.add_argument('--img-size', default=None, type=int, + metavar='N', help='Input image dimension, uses model default if empty') +parser.add_argument('--mean', type=float, nargs='+', default=None, metavar='MEAN', + help='Override mean pixel value of dataset') +parser.add_argument('--std', type=float, nargs='+', default=None, metavar='STD', + help='Override std deviation of of dataset') +parser.add_argument('--num-classes', type=int, default=1000, + help='Number classes in dataset') +parser.add_argument('--checkpoint', default='', type=str, metavar='PATH', + help='path to checkpoint (default: none)') + + +def main(): + args = parser.parse_args() + + args.pretrained = True + if args.checkpoint: + args.pretrained = False + + print("==> Creating PyTorch {} model".format(args.model)) + # NOTE exportable=True flag disables autofn/jit scripted activations and uses Conv2dSameExport layers + # for models using SAME padding + model = geffnet.create_model( + args.model, + num_classes=args.num_classes, + in_chans=3, + pretrained=args.pretrained, + checkpoint_path=args.checkpoint, + exportable=True) + + model.eval() + + example_input = torch.randn((args.batch_size, 3, args.img_size or 224, args.img_size or 224), requires_grad=True) + + # Run model once before export trace, sets padding for models with Conv2dSameExport. This means + # that the padding for models with Conv2dSameExport (most models with tf_ prefix) is fixed for + # the input img_size specified in this script. + # Opset >= 11 should allow for dynamic padding, however I cannot get it to work due to + # issues in the tracing of the dynamic padding or errors attempting to export the model after jit + # scripting it (an approach that should work). Perhaps in a future PyTorch or ONNX versions... + model(example_input) + + print("==> Exporting model to ONNX format at '{}'".format(args.output)) + input_names = ["input0"] + output_names = ["output0"] + dynamic_axes = {'input0': {0: 'batch'}, 'output0': {0: 'batch'}} + if args.dynamic_size: + dynamic_axes['input0'][2] = 'height' + dynamic_axes['input0'][3] = 'width' + if args.aten_fallback: + export_type = torch.onnx.OperatorExportTypes.ONNX_ATEN_FALLBACK + else: + export_type = torch.onnx.OperatorExportTypes.ONNX + + torch_out = torch.onnx._export( + model, example_input, args.output, export_params=True, verbose=True, input_names=input_names, + output_names=output_names, keep_initializers_as_inputs=args.keep_init, dynamic_axes=dynamic_axes, + opset_version=args.opset, operator_export_type=export_type) + + print("==> Loading and checking exported model from '{}'".format(args.output)) + onnx_model = onnx.load(args.output) + onnx.checker.check_model(onnx_model) # assuming throw on error + print("==> Passed") + + if args.keep_init and args.aten_fallback: + import caffe2.python.onnx.backend as onnx_caffe2 + # Caffe2 loading only works properly in newer PyTorch/ONNX combos when + # keep_initializers_as_inputs and aten_fallback are set to True. + print("==> Loading model into Caffe2 backend and comparing forward pass.".format(args.output)) + caffe2_backend = onnx_caffe2.prepare(onnx_model) + B = {onnx_model.graph.input[0].name: x.data.numpy()} + c2_out = caffe2_backend.run(B)[0] + np.testing.assert_almost_equal(torch_out.data.numpy(), c2_out, decimal=5) + print("==> Passed") + + +if __name__ == '__main__': + main() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/onnx_optimize.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/onnx_optimize.py new file mode 100644 index 00000000..ee20bbf9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/onnx_optimize.py @@ -0,0 +1,84 @@ +""" ONNX optimization script + +Run ONNX models through the optimizer to prune unneeded nodes, fuse batchnorm layers into conv, etc. + +NOTE: This isn't working consistently in recent PyTorch/ONNX combos (ie PyTorch 1.6 and ONNX 1.7), +it seems time to switch to using the onnxruntime online optimizer (can also be saved for offline). + +Copyright 2020 Ross Wightman +""" +import argparse +import warnings + +import onnx +from onnx import optimizer + + +parser = argparse.ArgumentParser(description="Optimize ONNX model") + +parser.add_argument("model", help="The ONNX model") +parser.add_argument("--output", required=True, help="The optimized model output filename") + + +def traverse_graph(graph, prefix=''): + content = [] + indent = prefix + ' ' + graphs = [] + num_nodes = 0 + for node in graph.node: + pn, gs = onnx.helper.printable_node(node, indent, subgraphs=True) + assert isinstance(gs, list) + content.append(pn) + graphs.extend(gs) + num_nodes += 1 + for g in graphs: + g_count, g_str = traverse_graph(g) + content.append('\n' + g_str) + num_nodes += g_count + return num_nodes, '\n'.join(content) + + +def main(): + args = parser.parse_args() + onnx_model = onnx.load(args.model) + num_original_nodes, original_graph_str = traverse_graph(onnx_model.graph) + + # Optimizer passes to perform + passes = [ + #'eliminate_deadend', + 'eliminate_identity', + 'eliminate_nop_dropout', + 'eliminate_nop_pad', + 'eliminate_nop_transpose', + 'eliminate_unused_initializer', + 'extract_constant_to_initializer', + 'fuse_add_bias_into_conv', + 'fuse_bn_into_conv', + 'fuse_consecutive_concats', + 'fuse_consecutive_reduce_unsqueeze', + 'fuse_consecutive_squeezes', + 'fuse_consecutive_transposes', + #'fuse_matmul_add_bias_into_gemm', + 'fuse_pad_into_conv', + #'fuse_transpose_into_gemm', + #'lift_lexical_references', + ] + + # Apply the optimization on the original serialized model + # WARNING I've had issues with optimizer in recent versions of PyTorch / ONNX causing + # 'duplicate definition of name' errors, see: https://github.com/onnx/onnx/issues/2401 + # It may be better to rely on onnxruntime optimizations, see onnx_validate.py script. + warnings.warn("I've had issues with optimizer in recent versions of PyTorch / ONNX." + "Try onnxruntime optimization if this doesn't work.") + optimized_model = optimizer.optimize(onnx_model, passes) + + num_optimized_nodes, optimzied_graph_str = traverse_graph(optimized_model.graph) + print('==> The model after optimization:\n{}\n'.format(optimzied_graph_str)) + print('==> The optimized model has {} nodes, the original had {}.'.format(num_optimized_nodes, num_original_nodes)) + + # Save the ONNX model + onnx.save(optimized_model, args.output) + + +if __name__ == "__main__": + main() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/onnx_to_caffe.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/onnx_to_caffe.py new file mode 100644 index 00000000..44399aaf --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/onnx_to_caffe.py @@ -0,0 +1,27 @@ +import argparse + +import onnx +from caffe2.python.onnx.backend import Caffe2Backend + + +parser = argparse.ArgumentParser(description="Convert ONNX to Caffe2") + +parser.add_argument("model", help="The ONNX model") +parser.add_argument("--c2-prefix", required=True, + help="The output file prefix for the caffe2 model init and predict file. ") + + +def main(): + args = parser.parse_args() + onnx_model = onnx.load(args.model) + caffe2_init, caffe2_predict = Caffe2Backend.onnx_graph_to_caffe2_net(onnx_model) + caffe2_init_str = caffe2_init.SerializeToString() + with open(args.c2_prefix + '.init.pb', "wb") as f: + f.write(caffe2_init_str) + caffe2_predict_str = caffe2_predict.SerializeToString() + with open(args.c2_prefix + '.predict.pb', "wb") as f: + f.write(caffe2_predict_str) + + +if __name__ == "__main__": + main() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/onnx_validate.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/onnx_validate.py new file mode 100644 index 00000000..ab3e4fb1 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/onnx_validate.py @@ -0,0 +1,112 @@ +""" ONNX-runtime validation script + +This script was created to verify accuracy and performance of exported ONNX +models running with the onnxruntime. It utilizes the PyTorch dataloader/processing +pipeline for a fair comparison against the originals. + +Copyright 2020 Ross Wightman +""" +import argparse +import numpy as np +import onnxruntime +from data import create_loader, resolve_data_config, Dataset +from utils import AverageMeter +import time + +parser = argparse.ArgumentParser(description='Caffe2 ImageNet Validation') +parser.add_argument('data', metavar='DIR', + help='path to dataset') +parser.add_argument('--onnx-input', default='', type=str, metavar='PATH', + help='path to onnx model/weights file') +parser.add_argument('--onnx-output-opt', default='', type=str, metavar='PATH', + help='path to output optimized onnx graph') +parser.add_argument('--profile', action='store_true', default=False, + help='Enable profiler output.') +parser.add_argument('-j', '--workers', default=2, type=int, metavar='N', + help='number of data loading workers (default: 2)') +parser.add_argument('-b', '--batch-size', default=256, type=int, + metavar='N', help='mini-batch size (default: 256)') +parser.add_argument('--img-size', default=None, type=int, + metavar='N', help='Input image dimension, uses model default if empty') +parser.add_argument('--mean', type=float, nargs='+', default=None, metavar='MEAN', + help='Override mean pixel value of dataset') +parser.add_argument('--std', type=float, nargs='+', default=None, metavar='STD', + help='Override std deviation of of dataset') +parser.add_argument('--crop-pct', type=float, default=None, metavar='PCT', + help='Override default crop pct of 0.875') +parser.add_argument('--interpolation', default='', type=str, metavar='NAME', + help='Image resize interpolation type (overrides model)') +parser.add_argument('--tf-preprocessing', dest='tf_preprocessing', action='store_true', + help='use tensorflow mnasnet preporcessing') +parser.add_argument('--print-freq', '-p', default=10, type=int, + metavar='N', help='print frequency (default: 10)') + + +def main(): + args = parser.parse_args() + args.gpu_id = 0 + + # Set graph optimization level + sess_options = onnxruntime.SessionOptions() + sess_options.graph_optimization_level = onnxruntime.GraphOptimizationLevel.ORT_ENABLE_ALL + if args.profile: + sess_options.enable_profiling = True + if args.onnx_output_opt: + sess_options.optimized_model_filepath = args.onnx_output_opt + + session = onnxruntime.InferenceSession(args.onnx_input, sess_options) + + data_config = resolve_data_config(None, args) + loader = create_loader( + Dataset(args.data, load_bytes=args.tf_preprocessing), + input_size=data_config['input_size'], + batch_size=args.batch_size, + use_prefetcher=False, + interpolation=data_config['interpolation'], + mean=data_config['mean'], + std=data_config['std'], + num_workers=args.workers, + crop_pct=data_config['crop_pct'], + tensorflow_preprocessing=args.tf_preprocessing) + + input_name = session.get_inputs()[0].name + + batch_time = AverageMeter() + top1 = AverageMeter() + top5 = AverageMeter() + end = time.time() + for i, (input, target) in enumerate(loader): + # run the net and return prediction + output = session.run([], {input_name: input.data.numpy()}) + output = output[0] + + # measure accuracy and record loss + prec1, prec5 = accuracy_np(output, target.numpy()) + top1.update(prec1.item(), input.size(0)) + top5.update(prec5.item(), input.size(0)) + + # measure elapsed time + batch_time.update(time.time() - end) + end = time.time() + + if i % args.print_freq == 0: + print('Test: [{0}/{1}]\t' + 'Time {batch_time.val:.3f} ({batch_time.avg:.3f}, {rate_avg:.3f}/s, {ms_avg:.3f} ms/sample) \t' + 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})\t' + 'Prec@5 {top5.val:.3f} ({top5.avg:.3f})'.format( + i, len(loader), batch_time=batch_time, rate_avg=input.size(0) / batch_time.avg, + ms_avg=100 * batch_time.avg / input.size(0), top1=top1, top5=top5)) + + print(' * Prec@1 {top1.avg:.3f} ({top1a:.3f}) Prec@5 {top5.avg:.3f} ({top5a:.3f})'.format( + top1=top1, top1a=100-top1.avg, top5=top5, top5a=100.-top5.avg)) + + +def accuracy_np(output, target): + max_indices = np.argsort(output, axis=1)[:, ::-1] + top5 = 100 * np.equal(max_indices[:, :5], target[:, np.newaxis]).sum(axis=1).mean() + top1 = 100 * np.equal(max_indices[:, 0], target).mean() + return top1, top5 + + +if __name__ == '__main__': + main() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/requirements.txt b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/requirements.txt new file mode 100644 index 00000000..ac3ffc13 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/requirements.txt @@ -0,0 +1,2 @@ +torch>=1.2.0 +torchvision>=0.4.0 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/setup.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/setup.py new file mode 100644 index 00000000..023e4c30 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/setup.py @@ -0,0 +1,47 @@ +""" Setup +""" +from setuptools import setup, find_packages +from codecs import open +from os import path + +here = path.abspath(path.dirname(__file__)) + +# Get the long description from the README file +with open(path.join(here, 'README.md'), encoding='utf-8') as f: + long_description = f.read() + +exec(open('geffnet/version.py').read()) +setup( + name='geffnet', + version=__version__, + description='(Generic) EfficientNets for PyTorch', + long_description=long_description, + long_description_content_type='text/markdown', + url='https://github.com/rwightman/gen-efficientnet-pytorch', + author='Ross Wightman', + author_email='hello@rwightman.com', + classifiers=[ + # How mature is this project? Common values are + # 3 - Alpha + # 4 - Beta + # 5 - Production/Stable + 'Development Status :: 3 - Alpha', + 'Intended Audience :: Education', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: Apache Software License', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Topic :: Scientific/Engineering', + 'Topic :: Scientific/Engineering :: Artificial Intelligence', + 'Topic :: Software Development', + 'Topic :: Software Development :: Libraries', + 'Topic :: Software Development :: Libraries :: Python Modules', + ], + + # Note that this is a string of words separated by whitespace, not a list. + keywords='pytorch pretrained models efficientnet mixnet mobilenetv3 mnasnet', + packages=find_packages(exclude=['data']), + install_requires=['torch >= 1.4', 'torchvision'], + python_requires='>=3.6', +) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/utils.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/utils.py new file mode 100644 index 00000000..d327e8bd --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/utils.py @@ -0,0 +1,52 @@ +import os + + +class AverageMeter: + """Computes and stores the average and current value""" + def __init__(self): + self.reset() + + def reset(self): + self.val = 0 + self.avg = 0 + self.sum = 0 + self.count = 0 + + def update(self, val, n=1): + self.val = val + self.sum += val * n + self.count += n + self.avg = self.sum / self.count + + +def accuracy(output, target, topk=(1,)): + """Computes the precision@k for the specified values of k""" + maxk = max(topk) + batch_size = target.size(0) + + _, pred = output.topk(maxk, 1, True, True) + pred = pred.t() + correct = pred.eq(target.view(1, -1).expand_as(pred)) + + res = [] + for k in topk: + correct_k = correct[:k].reshape(-1).float().sum(0) + res.append(correct_k.mul_(100.0 / batch_size)) + return res + + +def get_outdir(path, *paths, inc=False): + outdir = os.path.join(path, *paths) + if not os.path.exists(outdir): + os.makedirs(outdir) + elif inc: + count = 1 + outdir_inc = outdir + '-' + str(count) + while os.path.exists(outdir_inc): + count = count + 1 + outdir_inc = outdir + '-' + str(count) + assert count < 100 + outdir = outdir_inc + os.makedirs(outdir) + return outdir + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/validate.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/validate.py new file mode 100644 index 00000000..5fd44fbb --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/efficientnet_repo/validate.py @@ -0,0 +1,166 @@ +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import argparse +import time +import torch +import torch.nn as nn +import torch.nn.parallel +from contextlib import suppress + +import geffnet +from data import Dataset, create_loader, resolve_data_config +from utils import accuracy, AverageMeter + +has_native_amp = False +try: + if getattr(torch.cuda.amp, 'autocast') is not None: + has_native_amp = True +except AttributeError: + pass + +torch.backends.cudnn.benchmark = True + +parser = argparse.ArgumentParser(description='PyTorch ImageNet Validation') +parser.add_argument('data', metavar='DIR', + help='path to dataset') +parser.add_argument('--model', '-m', metavar='MODEL', default='spnasnet1_00', + help='model architecture (default: dpn92)') +parser.add_argument('-j', '--workers', default=4, type=int, metavar='N', + help='number of data loading workers (default: 2)') +parser.add_argument('-b', '--batch-size', default=256, type=int, + metavar='N', help='mini-batch size (default: 256)') +parser.add_argument('--img-size', default=None, type=int, + metavar='N', help='Input image dimension, uses model default if empty') +parser.add_argument('--mean', type=float, nargs='+', default=None, metavar='MEAN', + help='Override mean pixel value of dataset') +parser.add_argument('--std', type=float, nargs='+', default=None, metavar='STD', + help='Override std deviation of of dataset') +parser.add_argument('--crop-pct', type=float, default=None, metavar='PCT', + help='Override default crop pct of 0.875') +parser.add_argument('--interpolation', default='', type=str, metavar='NAME', + help='Image resize interpolation type (overrides model)') +parser.add_argument('--num-classes', type=int, default=1000, + help='Number classes in dataset') +parser.add_argument('--print-freq', '-p', default=10, type=int, + metavar='N', help='print frequency (default: 10)') +parser.add_argument('--checkpoint', default='', type=str, metavar='PATH', + help='path to latest checkpoint (default: none)') +parser.add_argument('--pretrained', dest='pretrained', action='store_true', + help='use pre-trained model') +parser.add_argument('--torchscript', dest='torchscript', action='store_true', + help='convert model torchscript for inference') +parser.add_argument('--num-gpu', type=int, default=1, + help='Number of GPUS to use') +parser.add_argument('--tf-preprocessing', dest='tf_preprocessing', action='store_true', + help='use tensorflow mnasnet preporcessing') +parser.add_argument('--no-cuda', dest='no_cuda', action='store_true', + help='') +parser.add_argument('--channels-last', action='store_true', default=False, + help='Use channels_last memory layout') +parser.add_argument('--amp', action='store_true', default=False, + help='Use native Torch AMP mixed precision.') + + +def main(): + args = parser.parse_args() + + if not args.checkpoint and not args.pretrained: + args.pretrained = True + + amp_autocast = suppress # do nothing + if args.amp: + if not has_native_amp: + print("Native Torch AMP is not available (requires torch >= 1.6), using FP32.") + else: + amp_autocast = torch.cuda.amp.autocast + + # create model + model = geffnet.create_model( + args.model, + num_classes=args.num_classes, + in_chans=3, + pretrained=args.pretrained, + checkpoint_path=args.checkpoint, + scriptable=args.torchscript) + + if args.channels_last: + model = model.to(memory_format=torch.channels_last) + + if args.torchscript: + torch.jit.optimized_execution(True) + model = torch.jit.script(model) + + print('Model %s created, param count: %d' % + (args.model, sum([m.numel() for m in model.parameters()]))) + + data_config = resolve_data_config(model, args) + + criterion = nn.CrossEntropyLoss() + + if not args.no_cuda: + if args.num_gpu > 1: + model = torch.nn.DataParallel(model, device_ids=list(range(args.num_gpu))).cuda() + else: + model = model.cuda() + criterion = criterion.cuda() + + loader = create_loader( + Dataset(args.data, load_bytes=args.tf_preprocessing), + input_size=data_config['input_size'], + batch_size=args.batch_size, + use_prefetcher=not args.no_cuda, + interpolation=data_config['interpolation'], + mean=data_config['mean'], + std=data_config['std'], + num_workers=args.workers, + crop_pct=data_config['crop_pct'], + tensorflow_preprocessing=args.tf_preprocessing) + + batch_time = AverageMeter() + losses = AverageMeter() + top1 = AverageMeter() + top5 = AverageMeter() + + model.eval() + end = time.time() + with torch.no_grad(): + for i, (input, target) in enumerate(loader): + if not args.no_cuda: + target = target.cuda() + input = input.cuda() + if args.channels_last: + input = input.contiguous(memory_format=torch.channels_last) + + # compute output + with amp_autocast(): + output = model(input) + loss = criterion(output, target) + + # measure accuracy and record loss + prec1, prec5 = accuracy(output.data, target, topk=(1, 5)) + losses.update(loss.item(), input.size(0)) + top1.update(prec1.item(), input.size(0)) + top5.update(prec5.item(), input.size(0)) + + # measure elapsed time + batch_time.update(time.time() - end) + end = time.time() + + if i % args.print_freq == 0: + print('Test: [{0}/{1}]\t' + 'Time {batch_time.val:.3f} ({batch_time.avg:.3f}, {rate_avg:.3f}/s) \t' + 'Loss {loss.val:.4f} ({loss.avg:.4f})\t' + 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})\t' + 'Prec@5 {top5.val:.3f} ({top5.avg:.3f})'.format( + i, len(loader), batch_time=batch_time, + rate_avg=input.size(0) / batch_time.avg, + loss=losses, top1=top1, top5=top5)) + + print(' * Prec@1 {top1.avg:.3f} ({top1a:.3f}) Prec@5 {top5.avg:.3f} ({top5a:.3f})'.format( + top1=top1, top1a=100-top1.avg, top5=top5, top5a=100.-top5.avg)) + + +if __name__ == '__main__': + main() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/encoder.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/encoder.py new file mode 100644 index 00000000..7f7149ca --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/encoder.py @@ -0,0 +1,34 @@ +import os +import torch +import torch.nn as nn +import torch.nn.functional as F + + +class Encoder(nn.Module): + def __init__(self): + super(Encoder, self).__init__() + + basemodel_name = 'tf_efficientnet_b5_ap' + print('Loading base model ()...'.format(basemodel_name), end='') + repo_path = os.path.join(os.path.dirname(__file__), 'efficientnet_repo') + basemodel = torch.hub.load(repo_path, basemodel_name, pretrained=False, source='local') + print('Done.') + + # Remove last layer + print('Removing last two layers (global_pool & classifier).') + basemodel.global_pool = nn.Identity() + basemodel.classifier = nn.Identity() + + self.original_model = basemodel + + def forward(self, x): + features = [x] + for k, v in self.original_model._modules.items(): + if (k == 'blocks'): + for ki, vi in v._modules.items(): + features.append(vi(features[-1])) + else: + features.append(v(features[-1])) + return features + + diff --git a/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/submodules.py b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/submodules.py new file mode 100644 index 00000000..40973335 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/normalbae/models/submodules/submodules.py @@ -0,0 +1,140 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F + + +######################################################################################################################## + + +# Upsample + BatchNorm +class UpSampleBN(nn.Module): + def __init__(self, skip_input, output_features): + super(UpSampleBN, self).__init__() + + self._net = nn.Sequential(nn.Conv2d(skip_input, output_features, kernel_size=3, stride=1, padding=1), + nn.BatchNorm2d(output_features), + nn.LeakyReLU(), + nn.Conv2d(output_features, output_features, kernel_size=3, stride=1, padding=1), + nn.BatchNorm2d(output_features), + nn.LeakyReLU()) + + def forward(self, x, concat_with): + up_x = F.interpolate(x, size=[concat_with.size(2), concat_with.size(3)], mode='bilinear', align_corners=True) + f = torch.cat([up_x, concat_with], dim=1) + return self._net(f) + + +# Upsample + GroupNorm + Weight Standardization +class UpSampleGN(nn.Module): + def __init__(self, skip_input, output_features): + super(UpSampleGN, self).__init__() + + self._net = nn.Sequential(Conv2d(skip_input, output_features, kernel_size=3, stride=1, padding=1), + nn.GroupNorm(8, output_features), + nn.LeakyReLU(), + Conv2d(output_features, output_features, kernel_size=3, stride=1, padding=1), + nn.GroupNorm(8, output_features), + nn.LeakyReLU()) + + def forward(self, x, concat_with): + up_x = F.interpolate(x, size=[concat_with.size(2), concat_with.size(3)], mode='bilinear', align_corners=True) + f = torch.cat([up_x, concat_with], dim=1) + return self._net(f) + + +# Conv2d with weight standardization +class Conv2d(nn.Conv2d): + def __init__(self, in_channels, out_channels, kernel_size, stride=1, + padding=0, dilation=1, groups=1, bias=True): + super(Conv2d, self).__init__(in_channels, out_channels, kernel_size, stride, + padding, dilation, groups, bias) + + def forward(self, x): + weight = self.weight + weight_mean = weight.mean(dim=1, keepdim=True).mean(dim=2, + keepdim=True).mean(dim=3, keepdim=True) + weight = weight - weight_mean + std = weight.view(weight.size(0), -1).std(dim=1).view(-1, 1, 1, 1) + 1e-5 + weight = weight / std.expand_as(weight) + return F.conv2d(x, weight, self.bias, self.stride, + self.padding, self.dilation, self.groups) + + +# normalize +def norm_normalize(norm_out): + min_kappa = 0.01 + norm_x, norm_y, norm_z, kappa = torch.split(norm_out, 1, dim=1) + norm = torch.sqrt(norm_x ** 2.0 + norm_y ** 2.0 + norm_z ** 2.0) + 1e-10 + kappa = F.elu(kappa) + 1.0 + min_kappa + final_out = torch.cat([norm_x / norm, norm_y / norm, norm_z / norm, kappa], dim=1) + return final_out + + +# uncertainty-guided sampling (only used during training) +@torch.no_grad() +def sample_points(init_normal, gt_norm_mask, sampling_ratio, beta): + device = init_normal.device + B, _, H, W = init_normal.shape + N = int(sampling_ratio * H * W) + beta = beta + + # uncertainty map + uncertainty_map = -1 * init_normal[:, 3, :, :] # B, H, W + + # gt_invalid_mask (B, H, W) + if gt_norm_mask is not None: + gt_invalid_mask = F.interpolate(gt_norm_mask.float(), size=[H, W], mode='nearest') + gt_invalid_mask = gt_invalid_mask[:, 0, :, :] < 0.5 + uncertainty_map[gt_invalid_mask] = -1e4 + + # (B, H*W) + _, idx = uncertainty_map.view(B, -1).sort(1, descending=True) + + # importance sampling + if int(beta * N) > 0: + importance = idx[:, :int(beta * N)] # B, beta*N + + # remaining + remaining = idx[:, int(beta * N):] # B, H*W - beta*N + + # coverage + num_coverage = N - int(beta * N) + + if num_coverage <= 0: + samples = importance + else: + coverage_list = [] + for i in range(B): + idx_c = torch.randperm(remaining.size()[1]) # shuffles "H*W - beta*N" + coverage_list.append(remaining[i, :][idx_c[:num_coverage]].view(1, -1)) # 1, N-beta*N + coverage = torch.cat(coverage_list, dim=0) # B, N-beta*N + samples = torch.cat((importance, coverage), dim=1) # B, N + + else: + # remaining + remaining = idx[:, :] # B, H*W + + # coverage + num_coverage = N + + coverage_list = [] + for i in range(B): + idx_c = torch.randperm(remaining.size()[1]) # shuffles "H*W - beta*N" + coverage_list.append(remaining[i, :][idx_c[:num_coverage]].view(1, -1)) # 1, N-beta*N + coverage = torch.cat(coverage_list, dim=0) # B, N-beta*N + samples = coverage + + # point coordinates + rows_int = samples // W # 0 for first row, H-1 for last row + rows_float = rows_int / float(H-1) # 0 to 1.0 + rows_float = (rows_float * 2.0) - 1.0 # -1.0 to 1.0 + + cols_int = samples % W # 0 for first column, W-1 for last column + cols_float = cols_int / float(W-1) # 0 to 1.0 + cols_float = (cols_float * 2.0) - 1.0 # -1.0 to 1.0 + + point_coords = torch.zeros(B, 1, N, 2) + point_coords[:, 0, :, 0] = cols_float # x coord + point_coords[:, 0, :, 1] = rows_float # y coord + point_coords = point_coords.to(device) + return point_coords, rows_int, cols_int \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/LICENSE b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/LICENSE new file mode 100644 index 00000000..16a9d56a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Caroline Chan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/__init__.py new file mode 100644 index 00000000..49eb9ec3 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/__init__.py @@ -0,0 +1,45 @@ +import os +from modules import devices +from annotator.annotator_path import models_path +from .api import make_detectron2_model, semantic_run + + +class OneformerDetector: + model_dir = os.path.join(models_path, "oneformer") + configs = { + "coco": { + "name": "150_16_swin_l_oneformer_coco_100ep.pth", + "config": 'configs/coco/oneformer_swin_large_IN21k_384_bs16_100ep.yaml' + }, + "ade20k": { + "name": "250_16_swin_l_oneformer_ade20k_160k.pth", + "config": 'configs/ade20k/oneformer_swin_large_IN21k_384_bs16_160k.yaml' + } + } + + def __init__(self, config): + self.model = None + self.metadata = None + self.config = config + self.device = devices.get_device_for("controlnet") + + def load_model(self): + remote_model_path = "https://huggingface.co/lllyasviel/Annotators/resolve/main/" + self.config["name"] + modelpath = os.path.join(self.model_dir, self.config["name"]) + if not os.path.exists(modelpath): + from basicsr.utils.download_util import load_file_from_url + load_file_from_url(remote_model_path, model_dir=self.model_dir) + config = os.path.join(os.path.dirname(__file__), self.config["config"]) + model, self.metadata = make_detectron2_model(config, modelpath) + self.model = model + + def unload_model(self): + if self.model is not None: + self.model.model.cpu() + + def __call__(self, img): + if self.model is None: + self.load_model() + + self.model.model.to(self.device) + return semantic_run(img, self.model, self.metadata) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/api.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/api.py new file mode 100644 index 00000000..59e4439f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/api.py @@ -0,0 +1,39 @@ +import os +os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" + +import torch + +from annotator.oneformer.detectron2.config import get_cfg +from annotator.oneformer.detectron2.projects.deeplab import add_deeplab_config +from annotator.oneformer.detectron2.data import MetadataCatalog + +from annotator.oneformer.oneformer import ( + add_oneformer_config, + add_common_config, + add_swin_config, + add_dinat_config, +) + +from annotator.oneformer.oneformer.demo.defaults import DefaultPredictor +from annotator.oneformer.oneformer.demo.visualizer import Visualizer, ColorMode + + +def make_detectron2_model(config_path, ckpt_path): + cfg = get_cfg() + add_deeplab_config(cfg) + add_common_config(cfg) + add_swin_config(cfg) + add_oneformer_config(cfg) + add_dinat_config(cfg) + cfg.merge_from_file(config_path) + cfg.MODEL.WEIGHTS = ckpt_path + cfg.freeze() + metadata = MetadataCatalog.get(cfg.DATASETS.TEST_PANOPTIC[0] if len(cfg.DATASETS.TEST_PANOPTIC) else "__unused") + return DefaultPredictor(cfg), metadata + + +def semantic_run(img, predictor, metadata): + predictions = predictor(img[:, :, ::-1], "semantic") # Predictor of OneFormer must use BGR image !!! + visualizer_map = Visualizer(img, is_img=False, metadata=metadata, instance_mode=ColorMode.IMAGE) + out_map = visualizer_map.draw_sem_seg(predictions["sem_seg"].argmax(dim=0).cpu(), alpha=1, is_text=False).get_image() + return out_map diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/ade20k/Base-ADE20K-UnifiedSegmentation.yaml b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/ade20k/Base-ADE20K-UnifiedSegmentation.yaml new file mode 100644 index 00000000..31eab45b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/ade20k/Base-ADE20K-UnifiedSegmentation.yaml @@ -0,0 +1,68 @@ +MODEL: + BACKBONE: + FREEZE_AT: 0 + NAME: "build_resnet_backbone" + WEIGHTS: "detectron2://ImageNetPretrained/torchvision/R-50.pkl" + PIXEL_MEAN: [123.675, 116.280, 103.530] + PIXEL_STD: [58.395, 57.120, 57.375] + RESNETS: + DEPTH: 50 + STEM_TYPE: "basic" # not used + STEM_OUT_CHANNELS: 64 + STRIDE_IN_1X1: False + OUT_FEATURES: ["res2", "res3", "res4", "res5"] + # NORM: "SyncBN" + RES5_MULTI_GRID: [1, 1, 1] # not used +DATASETS: + TRAIN: ("ade20k_panoptic_train",) + TEST_PANOPTIC: ("ade20k_panoptic_val",) + TEST_INSTANCE: ("ade20k_instance_val",) + TEST_SEMANTIC: ("ade20k_sem_seg_val",) +SOLVER: + IMS_PER_BATCH: 16 + BASE_LR: 0.0001 + MAX_ITER: 160000 + WARMUP_FACTOR: 1.0 + WARMUP_ITERS: 0 + WEIGHT_DECAY: 0.05 + OPTIMIZER: "ADAMW" + LR_SCHEDULER_NAME: "WarmupPolyLR" + BACKBONE_MULTIPLIER: 0.1 + CLIP_GRADIENTS: + ENABLED: True + CLIP_TYPE: "full_model" + CLIP_VALUE: 0.01 + NORM_TYPE: 2.0 + AMP: + ENABLED: True +INPUT: + MIN_SIZE_TRAIN: !!python/object/apply:eval ["[int(x * 0.1 * 512) for x in range(5, 21)]"] + MIN_SIZE_TRAIN_SAMPLING: "choice" + MIN_SIZE_TEST: 512 + MAX_SIZE_TRAIN: 2048 + MAX_SIZE_TEST: 2048 + CROP: + ENABLED: True + TYPE: "absolute" + SIZE: (512, 512) + SINGLE_CATEGORY_MAX_AREA: 1.0 + COLOR_AUG_SSD: True + SIZE_DIVISIBILITY: 512 # used in dataset mapper + FORMAT: "RGB" + DATASET_MAPPER_NAME: "oneformer_unified" + MAX_SEQ_LEN: 77 + TASK_SEQ_LEN: 77 + TASK_PROB: + SEMANTIC: 0.33 + INSTANCE: 0.66 +TEST: + EVAL_PERIOD: 5000 + AUG: + ENABLED: False + MIN_SIZES: [256, 384, 512, 640, 768, 896] + MAX_SIZE: 3584 + FLIP: True +DATALOADER: + FILTER_EMPTY_ANNOTATIONS: True + NUM_WORKERS: 4 +VERSION: 2 \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/ade20k/oneformer_R50_bs16_160k.yaml b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/ade20k/oneformer_R50_bs16_160k.yaml new file mode 100644 index 00000000..770ffc81 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/ade20k/oneformer_R50_bs16_160k.yaml @@ -0,0 +1,58 @@ +_BASE_: Base-ADE20K-UnifiedSegmentation.yaml +MODEL: + META_ARCHITECTURE: "OneFormer" + SEM_SEG_HEAD: + NAME: "OneFormerHead" + IGNORE_VALUE: 255 + NUM_CLASSES: 150 + LOSS_WEIGHT: 1.0 + CONVS_DIM: 256 + MASK_DIM: 256 + NORM: "GN" + # pixel decoder + PIXEL_DECODER_NAME: "MSDeformAttnPixelDecoder" + IN_FEATURES: ["res2", "res3", "res4", "res5"] + DEFORMABLE_TRANSFORMER_ENCODER_IN_FEATURES: ["res3", "res4", "res5"] + COMMON_STRIDE: 4 + TRANSFORMER_ENC_LAYERS: 6 + ONE_FORMER: + TRANSFORMER_DECODER_NAME: "ContrastiveMultiScaleMaskedTransformerDecoder" + TRANSFORMER_IN_FEATURE: "multi_scale_pixel_decoder" + DEEP_SUPERVISION: True + NO_OBJECT_WEIGHT: 0.1 + CLASS_WEIGHT: 2.0 + MASK_WEIGHT: 5.0 + DICE_WEIGHT: 5.0 + CONTRASTIVE_WEIGHT: 0.5 + CONTRASTIVE_TEMPERATURE: 0.07 + HIDDEN_DIM: 256 + NUM_OBJECT_QUERIES: 150 + USE_TASK_NORM: True + NHEADS: 8 + DROPOUT: 0.1 + DIM_FEEDFORWARD: 2048 + ENC_LAYERS: 0 + PRE_NORM: False + ENFORCE_INPUT_PROJ: False + SIZE_DIVISIBILITY: 32 + CLASS_DEC_LAYERS: 2 + DEC_LAYERS: 10 # 9 decoder layers, add one for the loss on learnable query + TRAIN_NUM_POINTS: 12544 + OVERSAMPLE_RATIO: 3.0 + IMPORTANCE_SAMPLE_RATIO: 0.75 + TEXT_ENCODER: + WIDTH: 256 + CONTEXT_LENGTH: 77 + NUM_LAYERS: 6 + VOCAB_SIZE: 49408 + PROJ_NUM_LAYERS: 2 + N_CTX: 16 + TEST: + SEMANTIC_ON: True + INSTANCE_ON: True + PANOPTIC_ON: True + OVERLAP_THRESHOLD: 0.8 + OBJECT_MASK_THRESHOLD: 0.8 + TASK: "panoptic" +TEST: + DETECTIONS_PER_IMAGE: 150 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/ade20k/oneformer_swin_large_IN21k_384_bs16_160k.yaml b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/ade20k/oneformer_swin_large_IN21k_384_bs16_160k.yaml new file mode 100644 index 00000000..69c44ade --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/ade20k/oneformer_swin_large_IN21k_384_bs16_160k.yaml @@ -0,0 +1,40 @@ +_BASE_: oneformer_R50_bs16_160k.yaml +MODEL: + BACKBONE: + NAME: "D2SwinTransformer" + SWIN: + EMBED_DIM: 192 + DEPTHS: [2, 2, 18, 2] + NUM_HEADS: [6, 12, 24, 48] + WINDOW_SIZE: 12 + APE: False + DROP_PATH_RATE: 0.3 + PATCH_NORM: True + PRETRAIN_IMG_SIZE: 384 + WEIGHTS: "swin_large_patch4_window12_384_22k.pkl" + PIXEL_MEAN: [123.675, 116.280, 103.530] + PIXEL_STD: [58.395, 57.120, 57.375] + ONE_FORMER: + NUM_OBJECT_QUERIES: 250 +INPUT: + MIN_SIZE_TRAIN: !!python/object/apply:eval ["[int(x * 0.1 * 640) for x in range(5, 21)]"] + MIN_SIZE_TRAIN_SAMPLING: "choice" + MIN_SIZE_TEST: 640 + MAX_SIZE_TRAIN: 2560 + MAX_SIZE_TEST: 2560 + CROP: + ENABLED: True + TYPE: "absolute" + SIZE: (640, 640) + SINGLE_CATEGORY_MAX_AREA: 1.0 + COLOR_AUG_SSD: True + SIZE_DIVISIBILITY: 640 # used in dataset mapper + FORMAT: "RGB" +TEST: + DETECTIONS_PER_IMAGE: 250 + EVAL_PERIOD: 5000 + AUG: + ENABLED: False + MIN_SIZES: [320, 480, 640, 800, 960, 1120] + MAX_SIZE: 4480 + FLIP: True diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/coco/Base-COCO-UnifiedSegmentation.yaml b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/coco/Base-COCO-UnifiedSegmentation.yaml new file mode 100644 index 00000000..ccd24f34 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/coco/Base-COCO-UnifiedSegmentation.yaml @@ -0,0 +1,54 @@ +MODEL: + BACKBONE: + FREEZE_AT: 0 + NAME: "build_resnet_backbone" + WEIGHTS: "detectron2://ImageNetPretrained/torchvision/R-50.pkl" + PIXEL_MEAN: [123.675, 116.280, 103.530] + PIXEL_STD: [58.395, 57.120, 57.375] + RESNETS: + DEPTH: 50 + STEM_TYPE: "basic" # not used + STEM_OUT_CHANNELS: 64 + STRIDE_IN_1X1: False + OUT_FEATURES: ["res2", "res3", "res4", "res5"] + # NORM: "SyncBN" + RES5_MULTI_GRID: [1, 1, 1] # not used +DATASETS: + TRAIN: ("coco_2017_train_panoptic_with_sem_seg",) + TEST_PANOPTIC: ("coco_2017_val_panoptic_with_sem_seg",) # to evaluate instance and semantic performance as well + TEST_INSTANCE: ("coco_2017_val",) + TEST_SEMANTIC: ("coco_2017_val_panoptic_with_sem_seg",) +SOLVER: + IMS_PER_BATCH: 16 + BASE_LR: 0.0001 + STEPS: (327778, 355092) + MAX_ITER: 368750 + WARMUP_FACTOR: 1.0 + WARMUP_ITERS: 10 + WEIGHT_DECAY: 0.05 + OPTIMIZER: "ADAMW" + BACKBONE_MULTIPLIER: 0.1 + CLIP_GRADIENTS: + ENABLED: True + CLIP_TYPE: "full_model" + CLIP_VALUE: 0.01 + NORM_TYPE: 2.0 + AMP: + ENABLED: True +INPUT: + IMAGE_SIZE: 1024 + MIN_SCALE: 0.1 + MAX_SCALE: 2.0 + FORMAT: "RGB" + DATASET_MAPPER_NAME: "coco_unified_lsj" + MAX_SEQ_LEN: 77 + TASK_SEQ_LEN: 77 + TASK_PROB: + SEMANTIC: 0.33 + INSTANCE: 0.66 +TEST: + EVAL_PERIOD: 5000 +DATALOADER: + FILTER_EMPTY_ANNOTATIONS: True + NUM_WORKERS: 4 +VERSION: 2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/coco/oneformer_R50_bs16_50ep.yaml b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/coco/oneformer_R50_bs16_50ep.yaml new file mode 100644 index 00000000..f768c8fa --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/coco/oneformer_R50_bs16_50ep.yaml @@ -0,0 +1,59 @@ +_BASE_: Base-COCO-UnifiedSegmentation.yaml +MODEL: + META_ARCHITECTURE: "OneFormer" + SEM_SEG_HEAD: + NAME: "OneFormerHead" + IGNORE_VALUE: 255 + NUM_CLASSES: 133 + LOSS_WEIGHT: 1.0 + CONVS_DIM: 256 + MASK_DIM: 256 + NORM: "GN" + # pixel decoder + PIXEL_DECODER_NAME: "MSDeformAttnPixelDecoder" + IN_FEATURES: ["res2", "res3", "res4", "res5"] + DEFORMABLE_TRANSFORMER_ENCODER_IN_FEATURES: ["res3", "res4", "res5"] + COMMON_STRIDE: 4 + TRANSFORMER_ENC_LAYERS: 6 + ONE_FORMER: + TRANSFORMER_DECODER_NAME: "ContrastiveMultiScaleMaskedTransformerDecoder" + TRANSFORMER_IN_FEATURE: "multi_scale_pixel_decoder" + DEEP_SUPERVISION: True + NO_OBJECT_WEIGHT: 0.1 + CLASS_WEIGHT: 2.0 + MASK_WEIGHT: 5.0 + DICE_WEIGHT: 5.0 + CONTRASTIVE_WEIGHT: 0.5 + CONTRASTIVE_TEMPERATURE: 0.07 + HIDDEN_DIM: 256 + NUM_OBJECT_QUERIES: 150 + USE_TASK_NORM: True + NHEADS: 8 + DROPOUT: 0.1 + DIM_FEEDFORWARD: 2048 + ENC_LAYERS: 0 + PRE_NORM: False + ENFORCE_INPUT_PROJ: False + SIZE_DIVISIBILITY: 32 + CLASS_DEC_LAYERS: 2 + DEC_LAYERS: 10 # 9 decoder layers, add one for the loss on learnable query + TRAIN_NUM_POINTS: 12544 + OVERSAMPLE_RATIO: 3.0 + IMPORTANCE_SAMPLE_RATIO: 0.75 + TEXT_ENCODER: + WIDTH: 256 + CONTEXT_LENGTH: 77 + NUM_LAYERS: 6 + VOCAB_SIZE: 49408 + PROJ_NUM_LAYERS: 2 + N_CTX: 16 + TEST: + SEMANTIC_ON: True + INSTANCE_ON: True + PANOPTIC_ON: True + DETECTION_ON: False + OVERLAP_THRESHOLD: 0.8 + OBJECT_MASK_THRESHOLD: 0.8 + TASK: "panoptic" +TEST: + DETECTIONS_PER_IMAGE: 150 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/coco/oneformer_swin_large_IN21k_384_bs16_100ep.yaml b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/coco/oneformer_swin_large_IN21k_384_bs16_100ep.yaml new file mode 100644 index 00000000..faae6553 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/configs/coco/oneformer_swin_large_IN21k_384_bs16_100ep.yaml @@ -0,0 +1,25 @@ +_BASE_: oneformer_R50_bs16_50ep.yaml +MODEL: + BACKBONE: + NAME: "D2SwinTransformer" + SWIN: + EMBED_DIM: 192 + DEPTHS: [2, 2, 18, 2] + NUM_HEADS: [6, 12, 24, 48] + WINDOW_SIZE: 12 + APE: False + DROP_PATH_RATE: 0.3 + PATCH_NORM: True + PRETRAIN_IMG_SIZE: 384 + WEIGHTS: "swin_large_patch4_window12_384_22k.pkl" + PIXEL_MEAN: [123.675, 116.280, 103.530] + PIXEL_STD: [58.395, 57.120, 57.375] + ONE_FORMER: + NUM_OBJECT_QUERIES: 150 +SOLVER: + STEPS: (655556, 735184) + MAX_ITER: 737500 + AMP: + ENABLED: False +TEST: + DETECTIONS_PER_IMAGE: 150 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/__init__.py new file mode 100644 index 00000000..bdd994b4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/__init__.py @@ -0,0 +1,10 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +from .utils.env import setup_environment + +setup_environment() + + +# This line will be programatically read/write by setup.py. +# Leave them at the bottom of this file and don't touch them. +__version__ = "0.6" diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/checkpoint/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/checkpoint/__init__.py new file mode 100644 index 00000000..99da0469 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/checkpoint/__init__.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. +# File: + + +from . import catalog as _UNUSED # register the handler +from .detection_checkpoint import DetectionCheckpointer +from fvcore.common.checkpoint import Checkpointer, PeriodicCheckpointer + +__all__ = ["Checkpointer", "PeriodicCheckpointer", "DetectionCheckpointer"] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/checkpoint/c2_model_loading.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/checkpoint/c2_model_loading.py new file mode 100644 index 00000000..c6de2a3c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/checkpoint/c2_model_loading.py @@ -0,0 +1,412 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import copy +import logging +import re +from typing import Dict, List +import torch +from tabulate import tabulate + + +def convert_basic_c2_names(original_keys): + """ + Apply some basic name conversion to names in C2 weights. + It only deals with typical backbone models. + + Args: + original_keys (list[str]): + Returns: + list[str]: The same number of strings matching those in original_keys. + """ + layer_keys = copy.deepcopy(original_keys) + layer_keys = [ + {"pred_b": "linear_b", "pred_w": "linear_w"}.get(k, k) for k in layer_keys + ] # some hard-coded mappings + + layer_keys = [k.replace("_", ".") for k in layer_keys] + layer_keys = [re.sub("\\.b$", ".bias", k) for k in layer_keys] + layer_keys = [re.sub("\\.w$", ".weight", k) for k in layer_keys] + # Uniform both bn and gn names to "norm" + layer_keys = [re.sub("bn\\.s$", "norm.weight", k) for k in layer_keys] + layer_keys = [re.sub("bn\\.bias$", "norm.bias", k) for k in layer_keys] + layer_keys = [re.sub("bn\\.rm", "norm.running_mean", k) for k in layer_keys] + layer_keys = [re.sub("bn\\.running.mean$", "norm.running_mean", k) for k in layer_keys] + layer_keys = [re.sub("bn\\.riv$", "norm.running_var", k) for k in layer_keys] + layer_keys = [re.sub("bn\\.running.var$", "norm.running_var", k) for k in layer_keys] + layer_keys = [re.sub("bn\\.gamma$", "norm.weight", k) for k in layer_keys] + layer_keys = [re.sub("bn\\.beta$", "norm.bias", k) for k in layer_keys] + layer_keys = [re.sub("gn\\.s$", "norm.weight", k) for k in layer_keys] + layer_keys = [re.sub("gn\\.bias$", "norm.bias", k) for k in layer_keys] + + # stem + layer_keys = [re.sub("^res\\.conv1\\.norm\\.", "conv1.norm.", k) for k in layer_keys] + # to avoid mis-matching with "conv1" in other components (e.g. detection head) + layer_keys = [re.sub("^conv1\\.", "stem.conv1.", k) for k in layer_keys] + + # layer1-4 is used by torchvision, however we follow the C2 naming strategy (res2-5) + # layer_keys = [re.sub("^res2.", "layer1.", k) for k in layer_keys] + # layer_keys = [re.sub("^res3.", "layer2.", k) for k in layer_keys] + # layer_keys = [re.sub("^res4.", "layer3.", k) for k in layer_keys] + # layer_keys = [re.sub("^res5.", "layer4.", k) for k in layer_keys] + + # blocks + layer_keys = [k.replace(".branch1.", ".shortcut.") for k in layer_keys] + layer_keys = [k.replace(".branch2a.", ".conv1.") for k in layer_keys] + layer_keys = [k.replace(".branch2b.", ".conv2.") for k in layer_keys] + layer_keys = [k.replace(".branch2c.", ".conv3.") for k in layer_keys] + + # DensePose substitutions + layer_keys = [re.sub("^body.conv.fcn", "body_conv_fcn", k) for k in layer_keys] + layer_keys = [k.replace("AnnIndex.lowres", "ann_index_lowres") for k in layer_keys] + layer_keys = [k.replace("Index.UV.lowres", "index_uv_lowres") for k in layer_keys] + layer_keys = [k.replace("U.lowres", "u_lowres") for k in layer_keys] + layer_keys = [k.replace("V.lowres", "v_lowres") for k in layer_keys] + return layer_keys + + +def convert_c2_detectron_names(weights): + """ + Map Caffe2 Detectron weight names to Detectron2 names. + + Args: + weights (dict): name -> tensor + + Returns: + dict: detectron2 names -> tensor + dict: detectron2 names -> C2 names + """ + logger = logging.getLogger(__name__) + logger.info("Renaming Caffe2 weights ......") + original_keys = sorted(weights.keys()) + layer_keys = copy.deepcopy(original_keys) + + layer_keys = convert_basic_c2_names(layer_keys) + + # -------------------------------------------------------------------------- + # RPN hidden representation conv + # -------------------------------------------------------------------------- + # FPN case + # In the C2 model, the RPN hidden layer conv is defined for FPN level 2 and then + # shared for all other levels, hence the appearance of "fpn2" + layer_keys = [ + k.replace("conv.rpn.fpn2", "proposal_generator.rpn_head.conv") for k in layer_keys + ] + # Non-FPN case + layer_keys = [k.replace("conv.rpn", "proposal_generator.rpn_head.conv") for k in layer_keys] + + # -------------------------------------------------------------------------- + # RPN box transformation conv + # -------------------------------------------------------------------------- + # FPN case (see note above about "fpn2") + layer_keys = [ + k.replace("rpn.bbox.pred.fpn2", "proposal_generator.rpn_head.anchor_deltas") + for k in layer_keys + ] + layer_keys = [ + k.replace("rpn.cls.logits.fpn2", "proposal_generator.rpn_head.objectness_logits") + for k in layer_keys + ] + # Non-FPN case + layer_keys = [ + k.replace("rpn.bbox.pred", "proposal_generator.rpn_head.anchor_deltas") for k in layer_keys + ] + layer_keys = [ + k.replace("rpn.cls.logits", "proposal_generator.rpn_head.objectness_logits") + for k in layer_keys + ] + + # -------------------------------------------------------------------------- + # Fast R-CNN box head + # -------------------------------------------------------------------------- + layer_keys = [re.sub("^bbox\\.pred", "bbox_pred", k) for k in layer_keys] + layer_keys = [re.sub("^cls\\.score", "cls_score", k) for k in layer_keys] + layer_keys = [re.sub("^fc6\\.", "box_head.fc1.", k) for k in layer_keys] + layer_keys = [re.sub("^fc7\\.", "box_head.fc2.", k) for k in layer_keys] + # 4conv1fc head tensor names: head_conv1_w, head_conv1_gn_s + layer_keys = [re.sub("^head\\.conv", "box_head.conv", k) for k in layer_keys] + + # -------------------------------------------------------------------------- + # FPN lateral and output convolutions + # -------------------------------------------------------------------------- + def fpn_map(name): + """ + Look for keys with the following patterns: + 1) Starts with "fpn.inner." + Example: "fpn.inner.res2.2.sum.lateral.weight" + Meaning: These are lateral pathway convolutions + 2) Starts with "fpn.res" + Example: "fpn.res2.2.sum.weight" + Meaning: These are FPN output convolutions + """ + splits = name.split(".") + norm = ".norm" if "norm" in splits else "" + if name.startswith("fpn.inner."): + # splits example: ['fpn', 'inner', 'res2', '2', 'sum', 'lateral', 'weight'] + stage = int(splits[2][len("res") :]) + return "fpn_lateral{}{}.{}".format(stage, norm, splits[-1]) + elif name.startswith("fpn.res"): + # splits example: ['fpn', 'res2', '2', 'sum', 'weight'] + stage = int(splits[1][len("res") :]) + return "fpn_output{}{}.{}".format(stage, norm, splits[-1]) + return name + + layer_keys = [fpn_map(k) for k in layer_keys] + + # -------------------------------------------------------------------------- + # Mask R-CNN mask head + # -------------------------------------------------------------------------- + # roi_heads.StandardROIHeads case + layer_keys = [k.replace(".[mask].fcn", "mask_head.mask_fcn") for k in layer_keys] + layer_keys = [re.sub("^\\.mask\\.fcn", "mask_head.mask_fcn", k) for k in layer_keys] + layer_keys = [k.replace("mask.fcn.logits", "mask_head.predictor") for k in layer_keys] + # roi_heads.Res5ROIHeads case + layer_keys = [k.replace("conv5.mask", "mask_head.deconv") for k in layer_keys] + + # -------------------------------------------------------------------------- + # Keypoint R-CNN head + # -------------------------------------------------------------------------- + # interestingly, the keypoint head convs have blob names that are simply "conv_fcnX" + layer_keys = [k.replace("conv.fcn", "roi_heads.keypoint_head.conv_fcn") for k in layer_keys] + layer_keys = [ + k.replace("kps.score.lowres", "roi_heads.keypoint_head.score_lowres") for k in layer_keys + ] + layer_keys = [k.replace("kps.score.", "roi_heads.keypoint_head.score.") for k in layer_keys] + + # -------------------------------------------------------------------------- + # Done with replacements + # -------------------------------------------------------------------------- + assert len(set(layer_keys)) == len(layer_keys) + assert len(original_keys) == len(layer_keys) + + new_weights = {} + new_keys_to_original_keys = {} + for orig, renamed in zip(original_keys, layer_keys): + new_keys_to_original_keys[renamed] = orig + if renamed.startswith("bbox_pred.") or renamed.startswith("mask_head.predictor."): + # remove the meaningless prediction weight for background class + new_start_idx = 4 if renamed.startswith("bbox_pred.") else 1 + new_weights[renamed] = weights[orig][new_start_idx:] + logger.info( + "Remove prediction weight for background class in {}. The shape changes from " + "{} to {}.".format( + renamed, tuple(weights[orig].shape), tuple(new_weights[renamed].shape) + ) + ) + elif renamed.startswith("cls_score."): + # move weights of bg class from original index 0 to last index + logger.info( + "Move classification weights for background class in {} from index 0 to " + "index {}.".format(renamed, weights[orig].shape[0] - 1) + ) + new_weights[renamed] = torch.cat([weights[orig][1:], weights[orig][:1]]) + else: + new_weights[renamed] = weights[orig] + + return new_weights, new_keys_to_original_keys + + +# Note the current matching is not symmetric. +# it assumes model_state_dict will have longer names. +def align_and_update_state_dicts(model_state_dict, ckpt_state_dict, c2_conversion=True): + """ + Match names between the two state-dict, and returns a new chkpt_state_dict with names + converted to match model_state_dict with heuristics. The returned dict can be later + loaded with fvcore checkpointer. + If `c2_conversion==True`, `ckpt_state_dict` is assumed to be a Caffe2 + model and will be renamed at first. + + Strategy: suppose that the models that we will create will have prefixes appended + to each of its keys, for example due to an extra level of nesting that the original + pre-trained weights from ImageNet won't contain. For example, model.state_dict() + might return backbone[0].body.res2.conv1.weight, while the pre-trained model contains + res2.conv1.weight. We thus want to match both parameters together. + For that, we look for each model weight, look among all loaded keys if there is one + that is a suffix of the current weight name, and use it if that's the case. + If multiple matches exist, take the one with longest size + of the corresponding name. For example, for the same model as before, the pretrained + weight file can contain both res2.conv1.weight, as well as conv1.weight. In this case, + we want to match backbone[0].body.conv1.weight to conv1.weight, and + backbone[0].body.res2.conv1.weight to res2.conv1.weight. + """ + model_keys = sorted(model_state_dict.keys()) + if c2_conversion: + ckpt_state_dict, original_keys = convert_c2_detectron_names(ckpt_state_dict) + # original_keys: the name in the original dict (before renaming) + else: + original_keys = {x: x for x in ckpt_state_dict.keys()} + ckpt_keys = sorted(ckpt_state_dict.keys()) + + def match(a, b): + # Matched ckpt_key should be a complete (starts with '.') suffix. + # For example, roi_heads.mesh_head.whatever_conv1 does not match conv1, + # but matches whatever_conv1 or mesh_head.whatever_conv1. + return a == b or a.endswith("." + b) + + # get a matrix of string matches, where each (i, j) entry correspond to the size of the + # ckpt_key string, if it matches + match_matrix = [len(j) if match(i, j) else 0 for i in model_keys for j in ckpt_keys] + match_matrix = torch.as_tensor(match_matrix).view(len(model_keys), len(ckpt_keys)) + # use the matched one with longest size in case of multiple matches + max_match_size, idxs = match_matrix.max(1) + # remove indices that correspond to no-match + idxs[max_match_size == 0] = -1 + + logger = logging.getLogger(__name__) + # matched_pairs (matched checkpoint key --> matched model key) + matched_keys = {} + result_state_dict = {} + for idx_model, idx_ckpt in enumerate(idxs.tolist()): + if idx_ckpt == -1: + continue + key_model = model_keys[idx_model] + key_ckpt = ckpt_keys[idx_ckpt] + value_ckpt = ckpt_state_dict[key_ckpt] + shape_in_model = model_state_dict[key_model].shape + + if shape_in_model != value_ckpt.shape: + logger.warning( + "Shape of {} in checkpoint is {}, while shape of {} in model is {}.".format( + key_ckpt, value_ckpt.shape, key_model, shape_in_model + ) + ) + logger.warning( + "{} will not be loaded. Please double check and see if this is desired.".format( + key_ckpt + ) + ) + continue + + assert key_model not in result_state_dict + result_state_dict[key_model] = value_ckpt + if key_ckpt in matched_keys: # already added to matched_keys + logger.error( + "Ambiguity found for {} in checkpoint!" + "It matches at least two keys in the model ({} and {}).".format( + key_ckpt, key_model, matched_keys[key_ckpt] + ) + ) + raise ValueError("Cannot match one checkpoint key to multiple keys in the model.") + + matched_keys[key_ckpt] = key_model + + # logging: + matched_model_keys = sorted(matched_keys.values()) + if len(matched_model_keys) == 0: + logger.warning("No weights in checkpoint matched with model.") + return ckpt_state_dict + common_prefix = _longest_common_prefix(matched_model_keys) + rev_matched_keys = {v: k for k, v in matched_keys.items()} + original_keys = {k: original_keys[rev_matched_keys[k]] for k in matched_model_keys} + + model_key_groups = _group_keys_by_module(matched_model_keys, original_keys) + table = [] + memo = set() + for key_model in matched_model_keys: + if key_model in memo: + continue + if key_model in model_key_groups: + group = model_key_groups[key_model] + memo |= set(group) + shapes = [tuple(model_state_dict[k].shape) for k in group] + table.append( + ( + _longest_common_prefix([k[len(common_prefix) :] for k in group]) + "*", + _group_str([original_keys[k] for k in group]), + " ".join([str(x).replace(" ", "") for x in shapes]), + ) + ) + else: + key_checkpoint = original_keys[key_model] + shape = str(tuple(model_state_dict[key_model].shape)) + table.append((key_model[len(common_prefix) :], key_checkpoint, shape)) + table_str = tabulate( + table, tablefmt="pipe", headers=["Names in Model", "Names in Checkpoint", "Shapes"] + ) + logger.info( + "Following weights matched with " + + (f"submodule {common_prefix[:-1]}" if common_prefix else "model") + + ":\n" + + table_str + ) + + unmatched_ckpt_keys = [k for k in ckpt_keys if k not in set(matched_keys.keys())] + for k in unmatched_ckpt_keys: + result_state_dict[k] = ckpt_state_dict[k] + return result_state_dict + + +def _group_keys_by_module(keys: List[str], original_names: Dict[str, str]): + """ + Params in the same submodule are grouped together. + + Args: + keys: names of all parameters + original_names: mapping from parameter name to their name in the checkpoint + + Returns: + dict[name -> all other names in the same group] + """ + + def _submodule_name(key): + pos = key.rfind(".") + if pos < 0: + return None + prefix = key[: pos + 1] + return prefix + + all_submodules = [_submodule_name(k) for k in keys] + all_submodules = [x for x in all_submodules if x] + all_submodules = sorted(all_submodules, key=len) + + ret = {} + for prefix in all_submodules: + group = [k for k in keys if k.startswith(prefix)] + if len(group) <= 1: + continue + original_name_lcp = _longest_common_prefix_str([original_names[k] for k in group]) + if len(original_name_lcp) == 0: + # don't group weights if original names don't share prefix + continue + + for k in group: + if k in ret: + continue + ret[k] = group + return ret + + +def _longest_common_prefix(names: List[str]) -> str: + """ + ["abc.zfg", "abc.zef"] -> "abc." + """ + names = [n.split(".") for n in names] + m1, m2 = min(names), max(names) + ret = [a for a, b in zip(m1, m2) if a == b] + ret = ".".join(ret) + "." if len(ret) else "" + return ret + + +def _longest_common_prefix_str(names: List[str]) -> str: + m1, m2 = min(names), max(names) + lcp = [] + for a, b in zip(m1, m2): + if a == b: + lcp.append(a) + else: + break + lcp = "".join(lcp) + return lcp + + +def _group_str(names: List[str]) -> str: + """ + Turn "common1", "common2", "common3" into "common{1,2,3}" + """ + lcp = _longest_common_prefix_str(names) + rest = [x[len(lcp) :] for x in names] + rest = "{" + ",".join(rest) + "}" + ret = lcp + rest + + # add some simplification for BN specifically + ret = ret.replace("bn_{beta,running_mean,running_var,gamma}", "bn_*") + ret = ret.replace("bn_beta,bn_running_mean,bn_running_var,bn_gamma", "bn_*") + return ret diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/checkpoint/catalog.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/checkpoint/catalog.py new file mode 100644 index 00000000..b5641858 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/checkpoint/catalog.py @@ -0,0 +1,115 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import logging + +from annotator.oneformer.detectron2.utils.file_io import PathHandler, PathManager + + +class ModelCatalog(object): + """ + Store mappings from names to third-party models. + """ + + S3_C2_DETECTRON_PREFIX = "https://dl.fbaipublicfiles.com/detectron" + + # MSRA models have STRIDE_IN_1X1=True. False otherwise. + # NOTE: all BN models here have fused BN into an affine layer. + # As a result, you should only load them to a model with "FrozenBN". + # Loading them to a model with regular BN or SyncBN is wrong. + # Even when loaded to FrozenBN, it is still different from affine by an epsilon, + # which should be negligible for training. + # NOTE: all models here uses PIXEL_STD=[1,1,1] + # NOTE: Most of the BN models here are no longer used. We use the + # re-converted pre-trained models under detectron2 model zoo instead. + C2_IMAGENET_MODELS = { + "MSRA/R-50": "ImageNetPretrained/MSRA/R-50.pkl", + "MSRA/R-101": "ImageNetPretrained/MSRA/R-101.pkl", + "FAIR/R-50-GN": "ImageNetPretrained/47261647/R-50-GN.pkl", + "FAIR/R-101-GN": "ImageNetPretrained/47592356/R-101-GN.pkl", + "FAIR/X-101-32x8d": "ImageNetPretrained/20171220/X-101-32x8d.pkl", + "FAIR/X-101-64x4d": "ImageNetPretrained/FBResNeXt/X-101-64x4d.pkl", + "FAIR/X-152-32x8d-IN5k": "ImageNetPretrained/25093814/X-152-32x8d-IN5k.pkl", + } + + C2_DETECTRON_PATH_FORMAT = ( + "{prefix}/{url}/output/train/{dataset}/{type}/model_final.pkl" # noqa B950 + ) + + C2_DATASET_COCO = "coco_2014_train%3Acoco_2014_valminusminival" + C2_DATASET_COCO_KEYPOINTS = "keypoints_coco_2014_train%3Akeypoints_coco_2014_valminusminival" + + # format: {model_name} -> part of the url + C2_DETECTRON_MODELS = { + "35857197/e2e_faster_rcnn_R-50-C4_1x": "35857197/12_2017_baselines/e2e_faster_rcnn_R-50-C4_1x.yaml.01_33_49.iAX0mXvW", # noqa B950 + "35857345/e2e_faster_rcnn_R-50-FPN_1x": "35857345/12_2017_baselines/e2e_faster_rcnn_R-50-FPN_1x.yaml.01_36_30.cUF7QR7I", # noqa B950 + "35857890/e2e_faster_rcnn_R-101-FPN_1x": "35857890/12_2017_baselines/e2e_faster_rcnn_R-101-FPN_1x.yaml.01_38_50.sNxI7sX7", # noqa B950 + "36761737/e2e_faster_rcnn_X-101-32x8d-FPN_1x": "36761737/12_2017_baselines/e2e_faster_rcnn_X-101-32x8d-FPN_1x.yaml.06_31_39.5MIHi1fZ", # noqa B950 + "35858791/e2e_mask_rcnn_R-50-C4_1x": "35858791/12_2017_baselines/e2e_mask_rcnn_R-50-C4_1x.yaml.01_45_57.ZgkA7hPB", # noqa B950 + "35858933/e2e_mask_rcnn_R-50-FPN_1x": "35858933/12_2017_baselines/e2e_mask_rcnn_R-50-FPN_1x.yaml.01_48_14.DzEQe4wC", # noqa B950 + "35861795/e2e_mask_rcnn_R-101-FPN_1x": "35861795/12_2017_baselines/e2e_mask_rcnn_R-101-FPN_1x.yaml.02_31_37.KqyEK4tT", # noqa B950 + "36761843/e2e_mask_rcnn_X-101-32x8d-FPN_1x": "36761843/12_2017_baselines/e2e_mask_rcnn_X-101-32x8d-FPN_1x.yaml.06_35_59.RZotkLKI", # noqa B950 + "48616381/e2e_mask_rcnn_R-50-FPN_2x_gn": "GN/48616381/04_2018_gn_baselines/e2e_mask_rcnn_R-50-FPN_2x_gn_0416.13_23_38.bTlTI97Q", # noqa B950 + "37697547/e2e_keypoint_rcnn_R-50-FPN_1x": "37697547/12_2017_baselines/e2e_keypoint_rcnn_R-50-FPN_1x.yaml.08_42_54.kdzV35ao", # noqa B950 + "35998355/rpn_R-50-C4_1x": "35998355/12_2017_baselines/rpn_R-50-C4_1x.yaml.08_00_43.njH5oD9L", # noqa B950 + "35998814/rpn_R-50-FPN_1x": "35998814/12_2017_baselines/rpn_R-50-FPN_1x.yaml.08_06_03.Axg0r179", # noqa B950 + "36225147/fast_R-50-FPN_1x": "36225147/12_2017_baselines/fast_rcnn_R-50-FPN_1x.yaml.08_39_09.L3obSdQ2", # noqa B950 + } + + @staticmethod + def get(name): + if name.startswith("Caffe2Detectron/COCO"): + return ModelCatalog._get_c2_detectron_baseline(name) + if name.startswith("ImageNetPretrained/"): + return ModelCatalog._get_c2_imagenet_pretrained(name) + raise RuntimeError("model not present in the catalog: {}".format(name)) + + @staticmethod + def _get_c2_imagenet_pretrained(name): + prefix = ModelCatalog.S3_C2_DETECTRON_PREFIX + name = name[len("ImageNetPretrained/") :] + name = ModelCatalog.C2_IMAGENET_MODELS[name] + url = "/".join([prefix, name]) + return url + + @staticmethod + def _get_c2_detectron_baseline(name): + name = name[len("Caffe2Detectron/COCO/") :] + url = ModelCatalog.C2_DETECTRON_MODELS[name] + if "keypoint_rcnn" in name: + dataset = ModelCatalog.C2_DATASET_COCO_KEYPOINTS + else: + dataset = ModelCatalog.C2_DATASET_COCO + + if "35998355/rpn_R-50-C4_1x" in name: + # this one model is somehow different from others .. + type = "rpn" + else: + type = "generalized_rcnn" + + # Detectron C2 models are stored in the structure defined in `C2_DETECTRON_PATH_FORMAT`. + url = ModelCatalog.C2_DETECTRON_PATH_FORMAT.format( + prefix=ModelCatalog.S3_C2_DETECTRON_PREFIX, url=url, type=type, dataset=dataset + ) + return url + + +class ModelCatalogHandler(PathHandler): + """ + Resolve URL like catalog://. + """ + + PREFIX = "catalog://" + + def _get_supported_prefixes(self): + return [self.PREFIX] + + def _get_local_path(self, path, **kwargs): + logger = logging.getLogger(__name__) + catalog_path = ModelCatalog.get(path[len(self.PREFIX) :]) + logger.info("Catalog entry {} points to {}".format(path, catalog_path)) + return PathManager.get_local_path(catalog_path, **kwargs) + + def _open(self, path, mode="r", **kwargs): + return PathManager.open(self._get_local_path(path), mode, **kwargs) + + +PathManager.register_handler(ModelCatalogHandler()) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/checkpoint/detection_checkpoint.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/checkpoint/detection_checkpoint.py new file mode 100644 index 00000000..7d411e54 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/checkpoint/detection_checkpoint.py @@ -0,0 +1,145 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import logging +import os +import pickle +from urllib.parse import parse_qs, urlparse +import torch +from fvcore.common.checkpoint import Checkpointer +from torch.nn.parallel import DistributedDataParallel + +import annotator.oneformer.detectron2.utils.comm as comm +from annotator.oneformer.detectron2.utils.file_io import PathManager + +from .c2_model_loading import align_and_update_state_dicts + + +class DetectionCheckpointer(Checkpointer): + """ + Same as :class:`Checkpointer`, but is able to: + 1. handle models in detectron & detectron2 model zoo, and apply conversions for legacy models. + 2. correctly load checkpoints that are only available on the master worker + """ + + def __init__(self, model, save_dir="", *, save_to_disk=None, **checkpointables): + is_main_process = comm.is_main_process() + super().__init__( + model, + save_dir, + save_to_disk=is_main_process if save_to_disk is None else save_to_disk, + **checkpointables, + ) + self.path_manager = PathManager + self._parsed_url_during_load = None + + def load(self, path, *args, **kwargs): + assert self._parsed_url_during_load is None + need_sync = False + logger = logging.getLogger(__name__) + logger.info("[DetectionCheckpointer] Loading from {} ...".format(path)) + + if path and isinstance(self.model, DistributedDataParallel): + path = self.path_manager.get_local_path(path) + has_file = os.path.isfile(path) + all_has_file = comm.all_gather(has_file) + if not all_has_file[0]: + raise OSError(f"File {path} not found on main worker.") + if not all(all_has_file): + logger.warning( + f"Not all workers can read checkpoint {path}. " + "Training may fail to fully resume." + ) + # TODO: broadcast the checkpoint file contents from main + # worker, and load from it instead. + need_sync = True + if not has_file: + path = None # don't load if not readable + + if path: + parsed_url = urlparse(path) + self._parsed_url_during_load = parsed_url + path = parsed_url._replace(query="").geturl() # remove query from filename + path = self.path_manager.get_local_path(path) + + self.logger.setLevel('CRITICAL') + ret = super().load(path, *args, **kwargs) + + if need_sync: + logger.info("Broadcasting model states from main worker ...") + self.model._sync_params_and_buffers() + self._parsed_url_during_load = None # reset to None + return ret + + def _load_file(self, filename): + if filename.endswith(".pkl"): + with PathManager.open(filename, "rb") as f: + data = pickle.load(f, encoding="latin1") + if "model" in data and "__author__" in data: + # file is in Detectron2 model zoo format + self.logger.info("Reading a file from '{}'".format(data["__author__"])) + return data + else: + # assume file is from Caffe2 / Detectron1 model zoo + if "blobs" in data: + # Detection models have "blobs", but ImageNet models don't + data = data["blobs"] + data = {k: v for k, v in data.items() if not k.endswith("_momentum")} + return {"model": data, "__author__": "Caffe2", "matching_heuristics": True} + elif filename.endswith(".pyth"): + # assume file is from pycls; no one else seems to use the ".pyth" extension + with PathManager.open(filename, "rb") as f: + data = torch.load(f) + assert ( + "model_state" in data + ), f"Cannot load .pyth file {filename}; pycls checkpoints must contain 'model_state'." + model_state = { + k: v + for k, v in data["model_state"].items() + if not k.endswith("num_batches_tracked") + } + return {"model": model_state, "__author__": "pycls", "matching_heuristics": True} + + loaded = self._torch_load(filename) + if "model" not in loaded: + loaded = {"model": loaded} + assert self._parsed_url_during_load is not None, "`_load_file` must be called inside `load`" + parsed_url = self._parsed_url_during_load + queries = parse_qs(parsed_url.query) + if queries.pop("matching_heuristics", "False") == ["True"]: + loaded["matching_heuristics"] = True + if len(queries) > 0: + raise ValueError( + f"Unsupported query remaining: f{queries}, orginal filename: {parsed_url.geturl()}" + ) + return loaded + + def _torch_load(self, f): + return super()._load_file(f) + + def _load_model(self, checkpoint): + if checkpoint.get("matching_heuristics", False): + self._convert_ndarray_to_tensor(checkpoint["model"]) + # convert weights by name-matching heuristics + checkpoint["model"] = align_and_update_state_dicts( + self.model.state_dict(), + checkpoint["model"], + c2_conversion=checkpoint.get("__author__", None) == "Caffe2", + ) + # for non-caffe2 models, use standard ways to load it + incompatible = super()._load_model(checkpoint) + + model_buffers = dict(self.model.named_buffers(recurse=False)) + for k in ["pixel_mean", "pixel_std"]: + # Ignore missing key message about pixel_mean/std. + # Though they may be missing in old checkpoints, they will be correctly + # initialized from config anyway. + if k in model_buffers: + try: + incompatible.missing_keys.remove(k) + except ValueError: + pass + for k in incompatible.unexpected_keys[:]: + # Ignore unexpected keys about cell anchors. They exist in old checkpoints + # but now they are non-persistent buffers and will not be in new checkpoints. + if "anchor_generator.cell_anchors" in k: + incompatible.unexpected_keys.remove(k) + return incompatible diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/__init__.py new file mode 100644 index 00000000..a78ed118 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/__init__.py @@ -0,0 +1,24 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from .compat import downgrade_config, upgrade_config +from .config import CfgNode, get_cfg, global_cfg, set_global_cfg, configurable +from .instantiate import instantiate +from .lazy import LazyCall, LazyConfig + +__all__ = [ + "CfgNode", + "get_cfg", + "global_cfg", + "set_global_cfg", + "downgrade_config", + "upgrade_config", + "configurable", + "instantiate", + "LazyCall", + "LazyConfig", +] + + +from annotator.oneformer.detectron2.utils.env import fixup_module_metadata + +fixup_module_metadata(__name__, globals(), __all__) +del fixup_module_metadata diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/compat.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/compat.py new file mode 100644 index 00000000..11a08c43 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/compat.py @@ -0,0 +1,229 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +""" +Backward compatibility of configs. + +Instructions to bump version: ++ It's not needed to bump version if new keys are added. + It's only needed when backward-incompatible changes happen + (i.e., some existing keys disappear, or the meaning of a key changes) ++ To bump version, do the following: + 1. Increment _C.VERSION in defaults.py + 2. Add a converter in this file. + + Each ConverterVX has a function "upgrade" which in-place upgrades config from X-1 to X, + and a function "downgrade" which in-place downgrades config from X to X-1 + + In each function, VERSION is left unchanged. + + Each converter assumes that its input has the relevant keys + (i.e., the input is not a partial config). + 3. Run the tests (test_config.py) to make sure the upgrade & downgrade + functions are consistent. +""" + +import logging +from typing import List, Optional, Tuple + +from .config import CfgNode as CN +from .defaults import _C + +__all__ = ["upgrade_config", "downgrade_config"] + + +def upgrade_config(cfg: CN, to_version: Optional[int] = None) -> CN: + """ + Upgrade a config from its current version to a newer version. + + Args: + cfg (CfgNode): + to_version (int): defaults to the latest version. + """ + cfg = cfg.clone() + if to_version is None: + to_version = _C.VERSION + + assert cfg.VERSION <= to_version, "Cannot upgrade from v{} to v{}!".format( + cfg.VERSION, to_version + ) + for k in range(cfg.VERSION, to_version): + converter = globals()["ConverterV" + str(k + 1)] + converter.upgrade(cfg) + cfg.VERSION = k + 1 + return cfg + + +def downgrade_config(cfg: CN, to_version: int) -> CN: + """ + Downgrade a config from its current version to an older version. + + Args: + cfg (CfgNode): + to_version (int): + + Note: + A general downgrade of arbitrary configs is not always possible due to the + different functionalities in different versions. + The purpose of downgrade is only to recover the defaults in old versions, + allowing it to load an old partial yaml config. + Therefore, the implementation only needs to fill in the default values + in the old version when a general downgrade is not possible. + """ + cfg = cfg.clone() + assert cfg.VERSION >= to_version, "Cannot downgrade from v{} to v{}!".format( + cfg.VERSION, to_version + ) + for k in range(cfg.VERSION, to_version, -1): + converter = globals()["ConverterV" + str(k)] + converter.downgrade(cfg) + cfg.VERSION = k - 1 + return cfg + + +def guess_version(cfg: CN, filename: str) -> int: + """ + Guess the version of a partial config where the VERSION field is not specified. + Returns the version, or the latest if cannot make a guess. + + This makes it easier for users to migrate. + """ + logger = logging.getLogger(__name__) + + def _has(name: str) -> bool: + cur = cfg + for n in name.split("."): + if n not in cur: + return False + cur = cur[n] + return True + + # Most users' partial configs have "MODEL.WEIGHT", so guess on it + ret = None + if _has("MODEL.WEIGHT") or _has("TEST.AUG_ON"): + ret = 1 + + if ret is not None: + logger.warning("Config '{}' has no VERSION. Assuming it to be v{}.".format(filename, ret)) + else: + ret = _C.VERSION + logger.warning( + "Config '{}' has no VERSION. Assuming it to be compatible with latest v{}.".format( + filename, ret + ) + ) + return ret + + +def _rename(cfg: CN, old: str, new: str) -> None: + old_keys = old.split(".") + new_keys = new.split(".") + + def _set(key_seq: List[str], val: str) -> None: + cur = cfg + for k in key_seq[:-1]: + if k not in cur: + cur[k] = CN() + cur = cur[k] + cur[key_seq[-1]] = val + + def _get(key_seq: List[str]) -> CN: + cur = cfg + for k in key_seq: + cur = cur[k] + return cur + + def _del(key_seq: List[str]) -> None: + cur = cfg + for k in key_seq[:-1]: + cur = cur[k] + del cur[key_seq[-1]] + if len(cur) == 0 and len(key_seq) > 1: + _del(key_seq[:-1]) + + _set(new_keys, _get(old_keys)) + _del(old_keys) + + +class _RenameConverter: + """ + A converter that handles simple rename. + """ + + RENAME: List[Tuple[str, str]] = [] # list of tuples of (old name, new name) + + @classmethod + def upgrade(cls, cfg: CN) -> None: + for old, new in cls.RENAME: + _rename(cfg, old, new) + + @classmethod + def downgrade(cls, cfg: CN) -> None: + for old, new in cls.RENAME[::-1]: + _rename(cfg, new, old) + + +class ConverterV1(_RenameConverter): + RENAME = [("MODEL.RPN_HEAD.NAME", "MODEL.RPN.HEAD_NAME")] + + +class ConverterV2(_RenameConverter): + """ + A large bulk of rename, before public release. + """ + + RENAME = [ + ("MODEL.WEIGHT", "MODEL.WEIGHTS"), + ("MODEL.PANOPTIC_FPN.SEMANTIC_LOSS_SCALE", "MODEL.SEM_SEG_HEAD.LOSS_WEIGHT"), + ("MODEL.PANOPTIC_FPN.RPN_LOSS_SCALE", "MODEL.RPN.LOSS_WEIGHT"), + ("MODEL.PANOPTIC_FPN.INSTANCE_LOSS_SCALE", "MODEL.PANOPTIC_FPN.INSTANCE_LOSS_WEIGHT"), + ("MODEL.PANOPTIC_FPN.COMBINE_ON", "MODEL.PANOPTIC_FPN.COMBINE.ENABLED"), + ( + "MODEL.PANOPTIC_FPN.COMBINE_OVERLAP_THRESHOLD", + "MODEL.PANOPTIC_FPN.COMBINE.OVERLAP_THRESH", + ), + ( + "MODEL.PANOPTIC_FPN.COMBINE_STUFF_AREA_LIMIT", + "MODEL.PANOPTIC_FPN.COMBINE.STUFF_AREA_LIMIT", + ), + ( + "MODEL.PANOPTIC_FPN.COMBINE_INSTANCES_CONFIDENCE_THRESHOLD", + "MODEL.PANOPTIC_FPN.COMBINE.INSTANCES_CONFIDENCE_THRESH", + ), + ("MODEL.ROI_HEADS.SCORE_THRESH", "MODEL.ROI_HEADS.SCORE_THRESH_TEST"), + ("MODEL.ROI_HEADS.NMS", "MODEL.ROI_HEADS.NMS_THRESH_TEST"), + ("MODEL.RETINANET.INFERENCE_SCORE_THRESHOLD", "MODEL.RETINANET.SCORE_THRESH_TEST"), + ("MODEL.RETINANET.INFERENCE_TOPK_CANDIDATES", "MODEL.RETINANET.TOPK_CANDIDATES_TEST"), + ("MODEL.RETINANET.INFERENCE_NMS_THRESHOLD", "MODEL.RETINANET.NMS_THRESH_TEST"), + ("TEST.DETECTIONS_PER_IMG", "TEST.DETECTIONS_PER_IMAGE"), + ("TEST.AUG_ON", "TEST.AUG.ENABLED"), + ("TEST.AUG_MIN_SIZES", "TEST.AUG.MIN_SIZES"), + ("TEST.AUG_MAX_SIZE", "TEST.AUG.MAX_SIZE"), + ("TEST.AUG_FLIP", "TEST.AUG.FLIP"), + ] + + @classmethod + def upgrade(cls, cfg: CN) -> None: + super().upgrade(cfg) + + if cfg.MODEL.META_ARCHITECTURE == "RetinaNet": + _rename( + cfg, "MODEL.RETINANET.ANCHOR_ASPECT_RATIOS", "MODEL.ANCHOR_GENERATOR.ASPECT_RATIOS" + ) + _rename(cfg, "MODEL.RETINANET.ANCHOR_SIZES", "MODEL.ANCHOR_GENERATOR.SIZES") + del cfg["MODEL"]["RPN"]["ANCHOR_SIZES"] + del cfg["MODEL"]["RPN"]["ANCHOR_ASPECT_RATIOS"] + else: + _rename(cfg, "MODEL.RPN.ANCHOR_ASPECT_RATIOS", "MODEL.ANCHOR_GENERATOR.ASPECT_RATIOS") + _rename(cfg, "MODEL.RPN.ANCHOR_SIZES", "MODEL.ANCHOR_GENERATOR.SIZES") + del cfg["MODEL"]["RETINANET"]["ANCHOR_SIZES"] + del cfg["MODEL"]["RETINANET"]["ANCHOR_ASPECT_RATIOS"] + del cfg["MODEL"]["RETINANET"]["ANCHOR_STRIDES"] + + @classmethod + def downgrade(cls, cfg: CN) -> None: + super().downgrade(cfg) + + _rename(cfg, "MODEL.ANCHOR_GENERATOR.ASPECT_RATIOS", "MODEL.RPN.ANCHOR_ASPECT_RATIOS") + _rename(cfg, "MODEL.ANCHOR_GENERATOR.SIZES", "MODEL.RPN.ANCHOR_SIZES") + cfg.MODEL.RETINANET.ANCHOR_ASPECT_RATIOS = cfg.MODEL.RPN.ANCHOR_ASPECT_RATIOS + cfg.MODEL.RETINANET.ANCHOR_SIZES = cfg.MODEL.RPN.ANCHOR_SIZES + cfg.MODEL.RETINANET.ANCHOR_STRIDES = [] # this is not used anywhere in any version diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/config.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/config.py new file mode 100644 index 00000000..c5b13034 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/config.py @@ -0,0 +1,265 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +import functools +import inspect +import logging +from fvcore.common.config import CfgNode as _CfgNode + +from annotator.oneformer.detectron2.utils.file_io import PathManager + + +class CfgNode(_CfgNode): + """ + The same as `fvcore.common.config.CfgNode`, but different in: + + 1. Use unsafe yaml loading by default. + Note that this may lead to arbitrary code execution: you must not + load a config file from untrusted sources before manually inspecting + the content of the file. + 2. Support config versioning. + When attempting to merge an old config, it will convert the old config automatically. + + .. automethod:: clone + .. automethod:: freeze + .. automethod:: defrost + .. automethod:: is_frozen + .. automethod:: load_yaml_with_base + .. automethod:: merge_from_list + .. automethod:: merge_from_other_cfg + """ + + @classmethod + def _open_cfg(cls, filename): + return PathManager.open(filename, "r") + + # Note that the default value of allow_unsafe is changed to True + def merge_from_file(self, cfg_filename: str, allow_unsafe: bool = True) -> None: + """ + Load content from the given config file and merge it into self. + + Args: + cfg_filename: config filename + allow_unsafe: allow unsafe yaml syntax + """ + assert PathManager.isfile(cfg_filename), f"Config file '{cfg_filename}' does not exist!" + loaded_cfg = self.load_yaml_with_base(cfg_filename, allow_unsafe=allow_unsafe) + loaded_cfg = type(self)(loaded_cfg) + + # defaults.py needs to import CfgNode + from .defaults import _C + + latest_ver = _C.VERSION + assert ( + latest_ver == self.VERSION + ), "CfgNode.merge_from_file is only allowed on a config object of latest version!" + + logger = logging.getLogger(__name__) + + loaded_ver = loaded_cfg.get("VERSION", None) + if loaded_ver is None: + from .compat import guess_version + + loaded_ver = guess_version(loaded_cfg, cfg_filename) + assert loaded_ver <= self.VERSION, "Cannot merge a v{} config into a v{} config.".format( + loaded_ver, self.VERSION + ) + + if loaded_ver == self.VERSION: + self.merge_from_other_cfg(loaded_cfg) + else: + # compat.py needs to import CfgNode + from .compat import upgrade_config, downgrade_config + + logger.warning( + "Loading an old v{} config file '{}' by automatically upgrading to v{}. " + "See docs/CHANGELOG.md for instructions to update your files.".format( + loaded_ver, cfg_filename, self.VERSION + ) + ) + # To convert, first obtain a full config at an old version + old_self = downgrade_config(self, to_version=loaded_ver) + old_self.merge_from_other_cfg(loaded_cfg) + new_config = upgrade_config(old_self) + self.clear() + self.update(new_config) + + def dump(self, *args, **kwargs): + """ + Returns: + str: a yaml string representation of the config + """ + # to make it show up in docs + return super().dump(*args, **kwargs) + + +global_cfg = CfgNode() + + +def get_cfg() -> CfgNode: + """ + Get a copy of the default config. + + Returns: + a detectron2 CfgNode instance. + """ + from .defaults import _C + + return _C.clone() + + +def set_global_cfg(cfg: CfgNode) -> None: + """ + Let the global config point to the given cfg. + + Assume that the given "cfg" has the key "KEY", after calling + `set_global_cfg(cfg)`, the key can be accessed by: + :: + from annotator.oneformer.detectron2.config import global_cfg + print(global_cfg.KEY) + + By using a hacky global config, you can access these configs anywhere, + without having to pass the config object or the values deep into the code. + This is a hacky feature introduced for quick prototyping / research exploration. + """ + global global_cfg + global_cfg.clear() + global_cfg.update(cfg) + + +def configurable(init_func=None, *, from_config=None): + """ + Decorate a function or a class's __init__ method so that it can be called + with a :class:`CfgNode` object using a :func:`from_config` function that translates + :class:`CfgNode` to arguments. + + Examples: + :: + # Usage 1: Decorator on __init__: + class A: + @configurable + def __init__(self, a, b=2, c=3): + pass + + @classmethod + def from_config(cls, cfg): # 'cfg' must be the first argument + # Returns kwargs to be passed to __init__ + return {"a": cfg.A, "b": cfg.B} + + a1 = A(a=1, b=2) # regular construction + a2 = A(cfg) # construct with a cfg + a3 = A(cfg, b=3, c=4) # construct with extra overwrite + + # Usage 2: Decorator on any function. Needs an extra from_config argument: + @configurable(from_config=lambda cfg: {"a: cfg.A, "b": cfg.B}) + def a_func(a, b=2, c=3): + pass + + a1 = a_func(a=1, b=2) # regular call + a2 = a_func(cfg) # call with a cfg + a3 = a_func(cfg, b=3, c=4) # call with extra overwrite + + Args: + init_func (callable): a class's ``__init__`` method in usage 1. The + class must have a ``from_config`` classmethod which takes `cfg` as + the first argument. + from_config (callable): the from_config function in usage 2. It must take `cfg` + as its first argument. + """ + + if init_func is not None: + assert ( + inspect.isfunction(init_func) + and from_config is None + and init_func.__name__ == "__init__" + ), "Incorrect use of @configurable. Check API documentation for examples." + + @functools.wraps(init_func) + def wrapped(self, *args, **kwargs): + try: + from_config_func = type(self).from_config + except AttributeError as e: + raise AttributeError( + "Class with @configurable must have a 'from_config' classmethod." + ) from e + if not inspect.ismethod(from_config_func): + raise TypeError("Class with @configurable must have a 'from_config' classmethod.") + + if _called_with_cfg(*args, **kwargs): + explicit_args = _get_args_from_config(from_config_func, *args, **kwargs) + init_func(self, **explicit_args) + else: + init_func(self, *args, **kwargs) + + return wrapped + + else: + if from_config is None: + return configurable # @configurable() is made equivalent to @configurable + assert inspect.isfunction( + from_config + ), "from_config argument of configurable must be a function!" + + def wrapper(orig_func): + @functools.wraps(orig_func) + def wrapped(*args, **kwargs): + if _called_with_cfg(*args, **kwargs): + explicit_args = _get_args_from_config(from_config, *args, **kwargs) + return orig_func(**explicit_args) + else: + return orig_func(*args, **kwargs) + + wrapped.from_config = from_config + return wrapped + + return wrapper + + +def _get_args_from_config(from_config_func, *args, **kwargs): + """ + Use `from_config` to obtain explicit arguments. + + Returns: + dict: arguments to be used for cls.__init__ + """ + signature = inspect.signature(from_config_func) + if list(signature.parameters.keys())[0] != "cfg": + if inspect.isfunction(from_config_func): + name = from_config_func.__name__ + else: + name = f"{from_config_func.__self__}.from_config" + raise TypeError(f"{name} must take 'cfg' as the first argument!") + support_var_arg = any( + param.kind in [param.VAR_POSITIONAL, param.VAR_KEYWORD] + for param in signature.parameters.values() + ) + if support_var_arg: # forward all arguments to from_config, if from_config accepts them + ret = from_config_func(*args, **kwargs) + else: + # forward supported arguments to from_config + supported_arg_names = set(signature.parameters.keys()) + extra_kwargs = {} + for name in list(kwargs.keys()): + if name not in supported_arg_names: + extra_kwargs[name] = kwargs.pop(name) + ret = from_config_func(*args, **kwargs) + # forward the other arguments to __init__ + ret.update(extra_kwargs) + return ret + + +def _called_with_cfg(*args, **kwargs): + """ + Returns: + bool: whether the arguments contain CfgNode and should be considered + forwarded to from_config. + """ + from omegaconf import DictConfig + + if len(args) and isinstance(args[0], (_CfgNode, DictConfig)): + return True + if isinstance(kwargs.pop("cfg", None), (_CfgNode, DictConfig)): + return True + # `from_config`'s first argument is forced to be "cfg". + # So the above check covers all cases. + return False diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/defaults.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/defaults.py new file mode 100644 index 00000000..ffb79e76 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/defaults.py @@ -0,0 +1,650 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from .config import CfgNode as CN + +# NOTE: given the new config system +# (https://detectron2.readthedocs.io/en/latest/tutorials/lazyconfigs.html), +# we will stop adding new functionalities to default CfgNode. + +# ----------------------------------------------------------------------------- +# Convention about Training / Test specific parameters +# ----------------------------------------------------------------------------- +# Whenever an argument can be either used for training or for testing, the +# corresponding name will be post-fixed by a _TRAIN for a training parameter, +# or _TEST for a test-specific parameter. +# For example, the number of images during training will be +# IMAGES_PER_BATCH_TRAIN, while the number of images for testing will be +# IMAGES_PER_BATCH_TEST + +# ----------------------------------------------------------------------------- +# Config definition +# ----------------------------------------------------------------------------- + +_C = CN() + +# The version number, to upgrade from old configs to new ones if any +# changes happen. It's recommended to keep a VERSION in your config file. +_C.VERSION = 2 + +_C.MODEL = CN() +_C.MODEL.LOAD_PROPOSALS = False +_C.MODEL.MASK_ON = False +_C.MODEL.KEYPOINT_ON = False +_C.MODEL.DEVICE = "cuda" +_C.MODEL.META_ARCHITECTURE = "GeneralizedRCNN" + +# Path (a file path, or URL like detectron2://.., https://..) to a checkpoint file +# to be loaded to the model. You can find available models in the model zoo. +_C.MODEL.WEIGHTS = "" + +# Values to be used for image normalization (BGR order, since INPUT.FORMAT defaults to BGR). +# To train on images of different number of channels, just set different mean & std. +# Default values are the mean pixel value from ImageNet: [103.53, 116.28, 123.675] +_C.MODEL.PIXEL_MEAN = [103.530, 116.280, 123.675] +# When using pre-trained models in Detectron1 or any MSRA models, +# std has been absorbed into its conv1 weights, so the std needs to be set 1. +# Otherwise, you can use [57.375, 57.120, 58.395] (ImageNet std) +_C.MODEL.PIXEL_STD = [1.0, 1.0, 1.0] + + +# ----------------------------------------------------------------------------- +# INPUT +# ----------------------------------------------------------------------------- +_C.INPUT = CN() +# By default, {MIN,MAX}_SIZE options are used in transforms.ResizeShortestEdge. +# Please refer to ResizeShortestEdge for detailed definition. +# Size of the smallest side of the image during training +_C.INPUT.MIN_SIZE_TRAIN = (800,) +# Sample size of smallest side by choice or random selection from range give by +# INPUT.MIN_SIZE_TRAIN +_C.INPUT.MIN_SIZE_TRAIN_SAMPLING = "choice" +# Maximum size of the side of the image during training +_C.INPUT.MAX_SIZE_TRAIN = 1333 +# Size of the smallest side of the image during testing. Set to zero to disable resize in testing. +_C.INPUT.MIN_SIZE_TEST = 800 +# Maximum size of the side of the image during testing +_C.INPUT.MAX_SIZE_TEST = 1333 +# Mode for flipping images used in data augmentation during training +# choose one of ["horizontal, "vertical", "none"] +_C.INPUT.RANDOM_FLIP = "horizontal" + +# `True` if cropping is used for data augmentation during training +_C.INPUT.CROP = CN({"ENABLED": False}) +# Cropping type. See documentation of `detectron2.data.transforms.RandomCrop` for explanation. +_C.INPUT.CROP.TYPE = "relative_range" +# Size of crop in range (0, 1] if CROP.TYPE is "relative" or "relative_range" and in number of +# pixels if CROP.TYPE is "absolute" +_C.INPUT.CROP.SIZE = [0.9, 0.9] + + +# Whether the model needs RGB, YUV, HSV etc. +# Should be one of the modes defined here, as we use PIL to read the image: +# https://pillow.readthedocs.io/en/stable/handbook/concepts.html#concept-modes +# with BGR being the one exception. One can set image format to BGR, we will +# internally use RGB for conversion and flip the channels over +_C.INPUT.FORMAT = "BGR" +# The ground truth mask format that the model will use. +# Mask R-CNN supports either "polygon" or "bitmask" as ground truth. +_C.INPUT.MASK_FORMAT = "polygon" # alternative: "bitmask" + + +# ----------------------------------------------------------------------------- +# Dataset +# ----------------------------------------------------------------------------- +_C.DATASETS = CN() +# List of the dataset names for training. Must be registered in DatasetCatalog +# Samples from these datasets will be merged and used as one dataset. +_C.DATASETS.TRAIN = () +# List of the pre-computed proposal files for training, which must be consistent +# with datasets listed in DATASETS.TRAIN. +_C.DATASETS.PROPOSAL_FILES_TRAIN = () +# Number of top scoring precomputed proposals to keep for training +_C.DATASETS.PRECOMPUTED_PROPOSAL_TOPK_TRAIN = 2000 +# List of the dataset names for testing. Must be registered in DatasetCatalog +_C.DATASETS.TEST = () +# List of the pre-computed proposal files for test, which must be consistent +# with datasets listed in DATASETS.TEST. +_C.DATASETS.PROPOSAL_FILES_TEST = () +# Number of top scoring precomputed proposals to keep for test +_C.DATASETS.PRECOMPUTED_PROPOSAL_TOPK_TEST = 1000 + +# ----------------------------------------------------------------------------- +# DataLoader +# ----------------------------------------------------------------------------- +_C.DATALOADER = CN() +# Number of data loading threads +_C.DATALOADER.NUM_WORKERS = 4 +# If True, each batch should contain only images for which the aspect ratio +# is compatible. This groups portrait images together, and landscape images +# are not batched with portrait images. +_C.DATALOADER.ASPECT_RATIO_GROUPING = True +# Options: TrainingSampler, RepeatFactorTrainingSampler +_C.DATALOADER.SAMPLER_TRAIN = "TrainingSampler" +# Repeat threshold for RepeatFactorTrainingSampler +_C.DATALOADER.REPEAT_THRESHOLD = 0.0 +# Tf True, when working on datasets that have instance annotations, the +# training dataloader will filter out images without associated annotations +_C.DATALOADER.FILTER_EMPTY_ANNOTATIONS = True + +# ---------------------------------------------------------------------------- # +# Backbone options +# ---------------------------------------------------------------------------- # +_C.MODEL.BACKBONE = CN() + +_C.MODEL.BACKBONE.NAME = "build_resnet_backbone" +# Freeze the first several stages so they are not trained. +# There are 5 stages in ResNet. The first is a convolution, and the following +# stages are each group of residual blocks. +_C.MODEL.BACKBONE.FREEZE_AT = 2 + + +# ---------------------------------------------------------------------------- # +# FPN options +# ---------------------------------------------------------------------------- # +_C.MODEL.FPN = CN() +# Names of the input feature maps to be used by FPN +# They must have contiguous power of 2 strides +# e.g., ["res2", "res3", "res4", "res5"] +_C.MODEL.FPN.IN_FEATURES = [] +_C.MODEL.FPN.OUT_CHANNELS = 256 + +# Options: "" (no norm), "GN" +_C.MODEL.FPN.NORM = "" + +# Types for fusing the FPN top-down and lateral features. Can be either "sum" or "avg" +_C.MODEL.FPN.FUSE_TYPE = "sum" + + +# ---------------------------------------------------------------------------- # +# Proposal generator options +# ---------------------------------------------------------------------------- # +_C.MODEL.PROPOSAL_GENERATOR = CN() +# Current proposal generators include "RPN", "RRPN" and "PrecomputedProposals" +_C.MODEL.PROPOSAL_GENERATOR.NAME = "RPN" +# Proposal height and width both need to be greater than MIN_SIZE +# (a the scale used during training or inference) +_C.MODEL.PROPOSAL_GENERATOR.MIN_SIZE = 0 + + +# ---------------------------------------------------------------------------- # +# Anchor generator options +# ---------------------------------------------------------------------------- # +_C.MODEL.ANCHOR_GENERATOR = CN() +# The generator can be any name in the ANCHOR_GENERATOR registry +_C.MODEL.ANCHOR_GENERATOR.NAME = "DefaultAnchorGenerator" +# Anchor sizes (i.e. sqrt of area) in absolute pixels w.r.t. the network input. +# Format: list[list[float]]. SIZES[i] specifies the list of sizes to use for +# IN_FEATURES[i]; len(SIZES) must be equal to len(IN_FEATURES) or 1. +# When len(SIZES) == 1, SIZES[0] is used for all IN_FEATURES. +_C.MODEL.ANCHOR_GENERATOR.SIZES = [[32, 64, 128, 256, 512]] +# Anchor aspect ratios. For each area given in `SIZES`, anchors with different aspect +# ratios are generated by an anchor generator. +# Format: list[list[float]]. ASPECT_RATIOS[i] specifies the list of aspect ratios (H/W) +# to use for IN_FEATURES[i]; len(ASPECT_RATIOS) == len(IN_FEATURES) must be true, +# or len(ASPECT_RATIOS) == 1 is true and aspect ratio list ASPECT_RATIOS[0] is used +# for all IN_FEATURES. +_C.MODEL.ANCHOR_GENERATOR.ASPECT_RATIOS = [[0.5, 1.0, 2.0]] +# Anchor angles. +# list[list[float]], the angle in degrees, for each input feature map. +# ANGLES[i] specifies the list of angles for IN_FEATURES[i]. +_C.MODEL.ANCHOR_GENERATOR.ANGLES = [[-90, 0, 90]] +# Relative offset between the center of the first anchor and the top-left corner of the image +# Value has to be in [0, 1). Recommend to use 0.5, which means half stride. +# The value is not expected to affect model accuracy. +_C.MODEL.ANCHOR_GENERATOR.OFFSET = 0.0 + +# ---------------------------------------------------------------------------- # +# RPN options +# ---------------------------------------------------------------------------- # +_C.MODEL.RPN = CN() +_C.MODEL.RPN.HEAD_NAME = "StandardRPNHead" # used by RPN_HEAD_REGISTRY + +# Names of the input feature maps to be used by RPN +# e.g., ["p2", "p3", "p4", "p5", "p6"] for FPN +_C.MODEL.RPN.IN_FEATURES = ["res4"] +# Remove RPN anchors that go outside the image by BOUNDARY_THRESH pixels +# Set to -1 or a large value, e.g. 100000, to disable pruning anchors +_C.MODEL.RPN.BOUNDARY_THRESH = -1 +# IOU overlap ratios [BG_IOU_THRESHOLD, FG_IOU_THRESHOLD] +# Minimum overlap required between an anchor and ground-truth box for the +# (anchor, gt box) pair to be a positive example (IoU >= FG_IOU_THRESHOLD +# ==> positive RPN example: 1) +# Maximum overlap allowed between an anchor and ground-truth box for the +# (anchor, gt box) pair to be a negative examples (IoU < BG_IOU_THRESHOLD +# ==> negative RPN example: 0) +# Anchors with overlap in between (BG_IOU_THRESHOLD <= IoU < FG_IOU_THRESHOLD) +# are ignored (-1) +_C.MODEL.RPN.IOU_THRESHOLDS = [0.3, 0.7] +_C.MODEL.RPN.IOU_LABELS = [0, -1, 1] +# Number of regions per image used to train RPN +_C.MODEL.RPN.BATCH_SIZE_PER_IMAGE = 256 +# Target fraction of foreground (positive) examples per RPN minibatch +_C.MODEL.RPN.POSITIVE_FRACTION = 0.5 +# Options are: "smooth_l1", "giou", "diou", "ciou" +_C.MODEL.RPN.BBOX_REG_LOSS_TYPE = "smooth_l1" +_C.MODEL.RPN.BBOX_REG_LOSS_WEIGHT = 1.0 +# Weights on (dx, dy, dw, dh) for normalizing RPN anchor regression targets +_C.MODEL.RPN.BBOX_REG_WEIGHTS = (1.0, 1.0, 1.0, 1.0) +# The transition point from L1 to L2 loss. Set to 0.0 to make the loss simply L1. +_C.MODEL.RPN.SMOOTH_L1_BETA = 0.0 +_C.MODEL.RPN.LOSS_WEIGHT = 1.0 +# Number of top scoring RPN proposals to keep before applying NMS +# When FPN is used, this is *per FPN level* (not total) +_C.MODEL.RPN.PRE_NMS_TOPK_TRAIN = 12000 +_C.MODEL.RPN.PRE_NMS_TOPK_TEST = 6000 +# Number of top scoring RPN proposals to keep after applying NMS +# When FPN is used, this limit is applied per level and then again to the union +# of proposals from all levels +# NOTE: When FPN is used, the meaning of this config is different from Detectron1. +# It means per-batch topk in Detectron1, but per-image topk here. +# See the "find_top_rpn_proposals" function for details. +_C.MODEL.RPN.POST_NMS_TOPK_TRAIN = 2000 +_C.MODEL.RPN.POST_NMS_TOPK_TEST = 1000 +# NMS threshold used on RPN proposals +_C.MODEL.RPN.NMS_THRESH = 0.7 +# Set this to -1 to use the same number of output channels as input channels. +_C.MODEL.RPN.CONV_DIMS = [-1] + +# ---------------------------------------------------------------------------- # +# ROI HEADS options +# ---------------------------------------------------------------------------- # +_C.MODEL.ROI_HEADS = CN() +_C.MODEL.ROI_HEADS.NAME = "Res5ROIHeads" +# Number of foreground classes +_C.MODEL.ROI_HEADS.NUM_CLASSES = 80 +# Names of the input feature maps to be used by ROI heads +# Currently all heads (box, mask, ...) use the same input feature map list +# e.g., ["p2", "p3", "p4", "p5"] is commonly used for FPN +_C.MODEL.ROI_HEADS.IN_FEATURES = ["res4"] +# IOU overlap ratios [IOU_THRESHOLD] +# Overlap threshold for an RoI to be considered background (if < IOU_THRESHOLD) +# Overlap threshold for an RoI to be considered foreground (if >= IOU_THRESHOLD) +_C.MODEL.ROI_HEADS.IOU_THRESHOLDS = [0.5] +_C.MODEL.ROI_HEADS.IOU_LABELS = [0, 1] +# RoI minibatch size *per image* (number of regions of interest [ROIs]) during training +# Total number of RoIs per training minibatch = +# ROI_HEADS.BATCH_SIZE_PER_IMAGE * SOLVER.IMS_PER_BATCH +# E.g., a common configuration is: 512 * 16 = 8192 +_C.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = 512 +# Target fraction of RoI minibatch that is labeled foreground (i.e. class > 0) +_C.MODEL.ROI_HEADS.POSITIVE_FRACTION = 0.25 + +# Only used on test mode + +# Minimum score threshold (assuming scores in a [0, 1] range); a value chosen to +# balance obtaining high recall with not having too many low precision +# detections that will slow down inference post processing steps (like NMS) +# A default threshold of 0.0 increases AP by ~0.2-0.3 but significantly slows down +# inference. +_C.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.05 +# Overlap threshold used for non-maximum suppression (suppress boxes with +# IoU >= this threshold) +_C.MODEL.ROI_HEADS.NMS_THRESH_TEST = 0.5 +# If True, augment proposals with ground-truth boxes before sampling proposals to +# train ROI heads. +_C.MODEL.ROI_HEADS.PROPOSAL_APPEND_GT = True + +# ---------------------------------------------------------------------------- # +# Box Head +# ---------------------------------------------------------------------------- # +_C.MODEL.ROI_BOX_HEAD = CN() +# C4 don't use head name option +# Options for non-C4 models: FastRCNNConvFCHead, +_C.MODEL.ROI_BOX_HEAD.NAME = "" +# Options are: "smooth_l1", "giou", "diou", "ciou" +_C.MODEL.ROI_BOX_HEAD.BBOX_REG_LOSS_TYPE = "smooth_l1" +# The final scaling coefficient on the box regression loss, used to balance the magnitude of its +# gradients with other losses in the model. See also `MODEL.ROI_KEYPOINT_HEAD.LOSS_WEIGHT`. +_C.MODEL.ROI_BOX_HEAD.BBOX_REG_LOSS_WEIGHT = 1.0 +# Default weights on (dx, dy, dw, dh) for normalizing bbox regression targets +# These are empirically chosen to approximately lead to unit variance targets +_C.MODEL.ROI_BOX_HEAD.BBOX_REG_WEIGHTS = (10.0, 10.0, 5.0, 5.0) +# The transition point from L1 to L2 loss. Set to 0.0 to make the loss simply L1. +_C.MODEL.ROI_BOX_HEAD.SMOOTH_L1_BETA = 0.0 +_C.MODEL.ROI_BOX_HEAD.POOLER_RESOLUTION = 14 +_C.MODEL.ROI_BOX_HEAD.POOLER_SAMPLING_RATIO = 0 +# Type of pooling operation applied to the incoming feature map for each RoI +_C.MODEL.ROI_BOX_HEAD.POOLER_TYPE = "ROIAlignV2" + +_C.MODEL.ROI_BOX_HEAD.NUM_FC = 0 +# Hidden layer dimension for FC layers in the RoI box head +_C.MODEL.ROI_BOX_HEAD.FC_DIM = 1024 +_C.MODEL.ROI_BOX_HEAD.NUM_CONV = 0 +# Channel dimension for Conv layers in the RoI box head +_C.MODEL.ROI_BOX_HEAD.CONV_DIM = 256 +# Normalization method for the convolution layers. +# Options: "" (no norm), "GN", "SyncBN". +_C.MODEL.ROI_BOX_HEAD.NORM = "" +# Whether to use class agnostic for bbox regression +_C.MODEL.ROI_BOX_HEAD.CLS_AGNOSTIC_BBOX_REG = False +# If true, RoI heads use bounding boxes predicted by the box head rather than proposal boxes. +_C.MODEL.ROI_BOX_HEAD.TRAIN_ON_PRED_BOXES = False + +# Federated loss can be used to improve the training of LVIS +_C.MODEL.ROI_BOX_HEAD.USE_FED_LOSS = False +# Sigmoid cross entrophy is used with federated loss +_C.MODEL.ROI_BOX_HEAD.USE_SIGMOID_CE = False +# The power value applied to image_count when calcualting frequency weight +_C.MODEL.ROI_BOX_HEAD.FED_LOSS_FREQ_WEIGHT_POWER = 0.5 +# Number of classes to keep in total +_C.MODEL.ROI_BOX_HEAD.FED_LOSS_NUM_CLASSES = 50 + +# ---------------------------------------------------------------------------- # +# Cascaded Box Head +# ---------------------------------------------------------------------------- # +_C.MODEL.ROI_BOX_CASCADE_HEAD = CN() +# The number of cascade stages is implicitly defined by the length of the following two configs. +_C.MODEL.ROI_BOX_CASCADE_HEAD.BBOX_REG_WEIGHTS = ( + (10.0, 10.0, 5.0, 5.0), + (20.0, 20.0, 10.0, 10.0), + (30.0, 30.0, 15.0, 15.0), +) +_C.MODEL.ROI_BOX_CASCADE_HEAD.IOUS = (0.5, 0.6, 0.7) + + +# ---------------------------------------------------------------------------- # +# Mask Head +# ---------------------------------------------------------------------------- # +_C.MODEL.ROI_MASK_HEAD = CN() +_C.MODEL.ROI_MASK_HEAD.NAME = "MaskRCNNConvUpsampleHead" +_C.MODEL.ROI_MASK_HEAD.POOLER_RESOLUTION = 14 +_C.MODEL.ROI_MASK_HEAD.POOLER_SAMPLING_RATIO = 0 +_C.MODEL.ROI_MASK_HEAD.NUM_CONV = 0 # The number of convs in the mask head +_C.MODEL.ROI_MASK_HEAD.CONV_DIM = 256 +# Normalization method for the convolution layers. +# Options: "" (no norm), "GN", "SyncBN". +_C.MODEL.ROI_MASK_HEAD.NORM = "" +# Whether to use class agnostic for mask prediction +_C.MODEL.ROI_MASK_HEAD.CLS_AGNOSTIC_MASK = False +# Type of pooling operation applied to the incoming feature map for each RoI +_C.MODEL.ROI_MASK_HEAD.POOLER_TYPE = "ROIAlignV2" + + +# ---------------------------------------------------------------------------- # +# Keypoint Head +# ---------------------------------------------------------------------------- # +_C.MODEL.ROI_KEYPOINT_HEAD = CN() +_C.MODEL.ROI_KEYPOINT_HEAD.NAME = "KRCNNConvDeconvUpsampleHead" +_C.MODEL.ROI_KEYPOINT_HEAD.POOLER_RESOLUTION = 14 +_C.MODEL.ROI_KEYPOINT_HEAD.POOLER_SAMPLING_RATIO = 0 +_C.MODEL.ROI_KEYPOINT_HEAD.CONV_DIMS = tuple(512 for _ in range(8)) +_C.MODEL.ROI_KEYPOINT_HEAD.NUM_KEYPOINTS = 17 # 17 is the number of keypoints in COCO. + +# Images with too few (or no) keypoints are excluded from training. +_C.MODEL.ROI_KEYPOINT_HEAD.MIN_KEYPOINTS_PER_IMAGE = 1 +# Normalize by the total number of visible keypoints in the minibatch if True. +# Otherwise, normalize by the total number of keypoints that could ever exist +# in the minibatch. +# The keypoint softmax loss is only calculated on visible keypoints. +# Since the number of visible keypoints can vary significantly between +# minibatches, this has the effect of up-weighting the importance of +# minibatches with few visible keypoints. (Imagine the extreme case of +# only one visible keypoint versus N: in the case of N, each one +# contributes 1/N to the gradient compared to the single keypoint +# determining the gradient direction). Instead, we can normalize the +# loss by the total number of keypoints, if it were the case that all +# keypoints were visible in a full minibatch. (Returning to the example, +# this means that the one visible keypoint contributes as much as each +# of the N keypoints.) +_C.MODEL.ROI_KEYPOINT_HEAD.NORMALIZE_LOSS_BY_VISIBLE_KEYPOINTS = True +# Multi-task loss weight to use for keypoints +# Recommended values: +# - use 1.0 if NORMALIZE_LOSS_BY_VISIBLE_KEYPOINTS is True +# - use 4.0 if NORMALIZE_LOSS_BY_VISIBLE_KEYPOINTS is False +_C.MODEL.ROI_KEYPOINT_HEAD.LOSS_WEIGHT = 1.0 +# Type of pooling operation applied to the incoming feature map for each RoI +_C.MODEL.ROI_KEYPOINT_HEAD.POOLER_TYPE = "ROIAlignV2" + +# ---------------------------------------------------------------------------- # +# Semantic Segmentation Head +# ---------------------------------------------------------------------------- # +_C.MODEL.SEM_SEG_HEAD = CN() +_C.MODEL.SEM_SEG_HEAD.NAME = "SemSegFPNHead" +_C.MODEL.SEM_SEG_HEAD.IN_FEATURES = ["p2", "p3", "p4", "p5"] +# Label in the semantic segmentation ground truth that is ignored, i.e., no loss is calculated for +# the correposnding pixel. +_C.MODEL.SEM_SEG_HEAD.IGNORE_VALUE = 255 +# Number of classes in the semantic segmentation head +_C.MODEL.SEM_SEG_HEAD.NUM_CLASSES = 54 +# Number of channels in the 3x3 convs inside semantic-FPN heads. +_C.MODEL.SEM_SEG_HEAD.CONVS_DIM = 128 +# Outputs from semantic-FPN heads are up-scaled to the COMMON_STRIDE stride. +_C.MODEL.SEM_SEG_HEAD.COMMON_STRIDE = 4 +# Normalization method for the convolution layers. Options: "" (no norm), "GN". +_C.MODEL.SEM_SEG_HEAD.NORM = "GN" +_C.MODEL.SEM_SEG_HEAD.LOSS_WEIGHT = 1.0 + +_C.MODEL.PANOPTIC_FPN = CN() +# Scaling of all losses from instance detection / segmentation head. +_C.MODEL.PANOPTIC_FPN.INSTANCE_LOSS_WEIGHT = 1.0 + +# options when combining instance & semantic segmentation outputs +_C.MODEL.PANOPTIC_FPN.COMBINE = CN({"ENABLED": True}) # "COMBINE.ENABLED" is deprecated & not used +_C.MODEL.PANOPTIC_FPN.COMBINE.OVERLAP_THRESH = 0.5 +_C.MODEL.PANOPTIC_FPN.COMBINE.STUFF_AREA_LIMIT = 4096 +_C.MODEL.PANOPTIC_FPN.COMBINE.INSTANCES_CONFIDENCE_THRESH = 0.5 + + +# ---------------------------------------------------------------------------- # +# RetinaNet Head +# ---------------------------------------------------------------------------- # +_C.MODEL.RETINANET = CN() + +# This is the number of foreground classes. +_C.MODEL.RETINANET.NUM_CLASSES = 80 + +_C.MODEL.RETINANET.IN_FEATURES = ["p3", "p4", "p5", "p6", "p7"] + +# Convolutions to use in the cls and bbox tower +# NOTE: this doesn't include the last conv for logits +_C.MODEL.RETINANET.NUM_CONVS = 4 + +# IoU overlap ratio [bg, fg] for labeling anchors. +# Anchors with < bg are labeled negative (0) +# Anchors with >= bg and < fg are ignored (-1) +# Anchors with >= fg are labeled positive (1) +_C.MODEL.RETINANET.IOU_THRESHOLDS = [0.4, 0.5] +_C.MODEL.RETINANET.IOU_LABELS = [0, -1, 1] + +# Prior prob for rare case (i.e. foreground) at the beginning of training. +# This is used to set the bias for the logits layer of the classifier subnet. +# This improves training stability in the case of heavy class imbalance. +_C.MODEL.RETINANET.PRIOR_PROB = 0.01 + +# Inference cls score threshold, only anchors with score > INFERENCE_TH are +# considered for inference (to improve speed) +_C.MODEL.RETINANET.SCORE_THRESH_TEST = 0.05 +# Select topk candidates before NMS +_C.MODEL.RETINANET.TOPK_CANDIDATES_TEST = 1000 +_C.MODEL.RETINANET.NMS_THRESH_TEST = 0.5 + +# Weights on (dx, dy, dw, dh) for normalizing Retinanet anchor regression targets +_C.MODEL.RETINANET.BBOX_REG_WEIGHTS = (1.0, 1.0, 1.0, 1.0) + +# Loss parameters +_C.MODEL.RETINANET.FOCAL_LOSS_GAMMA = 2.0 +_C.MODEL.RETINANET.FOCAL_LOSS_ALPHA = 0.25 +_C.MODEL.RETINANET.SMOOTH_L1_LOSS_BETA = 0.1 +# Options are: "smooth_l1", "giou", "diou", "ciou" +_C.MODEL.RETINANET.BBOX_REG_LOSS_TYPE = "smooth_l1" + +# One of BN, SyncBN, FrozenBN, GN +# Only supports GN until unshared norm is implemented +_C.MODEL.RETINANET.NORM = "" + + +# ---------------------------------------------------------------------------- # +# ResNe[X]t options (ResNets = {ResNet, ResNeXt} +# Note that parts of a resnet may be used for both the backbone and the head +# These options apply to both +# ---------------------------------------------------------------------------- # +_C.MODEL.RESNETS = CN() + +_C.MODEL.RESNETS.DEPTH = 50 +_C.MODEL.RESNETS.OUT_FEATURES = ["res4"] # res4 for C4 backbone, res2..5 for FPN backbone + +# Number of groups to use; 1 ==> ResNet; > 1 ==> ResNeXt +_C.MODEL.RESNETS.NUM_GROUPS = 1 + +# Options: FrozenBN, GN, "SyncBN", "BN" +_C.MODEL.RESNETS.NORM = "FrozenBN" + +# Baseline width of each group. +# Scaling this parameters will scale the width of all bottleneck layers. +_C.MODEL.RESNETS.WIDTH_PER_GROUP = 64 + +# Place the stride 2 conv on the 1x1 filter +# Use True only for the original MSRA ResNet; use False for C2 and Torch models +_C.MODEL.RESNETS.STRIDE_IN_1X1 = True + +# Apply dilation in stage "res5" +_C.MODEL.RESNETS.RES5_DILATION = 1 + +# Output width of res2. Scaling this parameters will scale the width of all 1x1 convs in ResNet +# For R18 and R34, this needs to be set to 64 +_C.MODEL.RESNETS.RES2_OUT_CHANNELS = 256 +_C.MODEL.RESNETS.STEM_OUT_CHANNELS = 64 + +# Apply Deformable Convolution in stages +# Specify if apply deform_conv on Res2, Res3, Res4, Res5 +_C.MODEL.RESNETS.DEFORM_ON_PER_STAGE = [False, False, False, False] +# Use True to use modulated deform_conv (DeformableV2, https://arxiv.org/abs/1811.11168); +# Use False for DeformableV1. +_C.MODEL.RESNETS.DEFORM_MODULATED = False +# Number of groups in deformable conv. +_C.MODEL.RESNETS.DEFORM_NUM_GROUPS = 1 + + +# ---------------------------------------------------------------------------- # +# Solver +# ---------------------------------------------------------------------------- # +_C.SOLVER = CN() + +# Options: WarmupMultiStepLR, WarmupCosineLR. +# See detectron2/solver/build.py for definition. +_C.SOLVER.LR_SCHEDULER_NAME = "WarmupMultiStepLR" + +_C.SOLVER.MAX_ITER = 40000 + +_C.SOLVER.BASE_LR = 0.001 +# The end lr, only used by WarmupCosineLR +_C.SOLVER.BASE_LR_END = 0.0 + +_C.SOLVER.MOMENTUM = 0.9 + +_C.SOLVER.NESTEROV = False + +_C.SOLVER.WEIGHT_DECAY = 0.0001 +# The weight decay that's applied to parameters of normalization layers +# (typically the affine transformation) +_C.SOLVER.WEIGHT_DECAY_NORM = 0.0 + +_C.SOLVER.GAMMA = 0.1 +# The iteration number to decrease learning rate by GAMMA. +_C.SOLVER.STEPS = (30000,) +# Number of decays in WarmupStepWithFixedGammaLR schedule +_C.SOLVER.NUM_DECAYS = 3 + +_C.SOLVER.WARMUP_FACTOR = 1.0 / 1000 +_C.SOLVER.WARMUP_ITERS = 1000 +_C.SOLVER.WARMUP_METHOD = "linear" +# Whether to rescale the interval for the learning schedule after warmup +_C.SOLVER.RESCALE_INTERVAL = False + +# Save a checkpoint after every this number of iterations +_C.SOLVER.CHECKPOINT_PERIOD = 5000 + +# Number of images per batch across all machines. This is also the number +# of training images per step (i.e. per iteration). If we use 16 GPUs +# and IMS_PER_BATCH = 32, each GPU will see 2 images per batch. +# May be adjusted automatically if REFERENCE_WORLD_SIZE is set. +_C.SOLVER.IMS_PER_BATCH = 16 + +# The reference number of workers (GPUs) this config is meant to train with. +# It takes no effect when set to 0. +# With a non-zero value, it will be used by DefaultTrainer to compute a desired +# per-worker batch size, and then scale the other related configs (total batch size, +# learning rate, etc) to match the per-worker batch size. +# See documentation of `DefaultTrainer.auto_scale_workers` for details: +_C.SOLVER.REFERENCE_WORLD_SIZE = 0 + +# Detectron v1 (and previous detection code) used a 2x higher LR and 0 WD for +# biases. This is not useful (at least for recent models). You should avoid +# changing these and they exist only to reproduce Detectron v1 training if +# desired. +_C.SOLVER.BIAS_LR_FACTOR = 1.0 +_C.SOLVER.WEIGHT_DECAY_BIAS = None # None means following WEIGHT_DECAY + +# Gradient clipping +_C.SOLVER.CLIP_GRADIENTS = CN({"ENABLED": False}) +# Type of gradient clipping, currently 2 values are supported: +# - "value": the absolute values of elements of each gradients are clipped +# - "norm": the norm of the gradient for each parameter is clipped thus +# affecting all elements in the parameter +_C.SOLVER.CLIP_GRADIENTS.CLIP_TYPE = "value" +# Maximum absolute value used for clipping gradients +_C.SOLVER.CLIP_GRADIENTS.CLIP_VALUE = 1.0 +# Floating point number p for L-p norm to be used with the "norm" +# gradient clipping type; for L-inf, please specify .inf +_C.SOLVER.CLIP_GRADIENTS.NORM_TYPE = 2.0 + +# Enable automatic mixed precision for training +# Note that this does not change model's inference behavior. +# To use AMP in inference, run inference under autocast() +_C.SOLVER.AMP = CN({"ENABLED": False}) + +# ---------------------------------------------------------------------------- # +# Specific test options +# ---------------------------------------------------------------------------- # +_C.TEST = CN() +# For end-to-end tests to verify the expected accuracy. +# Each item is [task, metric, value, tolerance] +# e.g.: [['bbox', 'AP', 38.5, 0.2]] +_C.TEST.EXPECTED_RESULTS = [] +# The period (in terms of steps) to evaluate the model during training. +# Set to 0 to disable. +_C.TEST.EVAL_PERIOD = 0 +# The sigmas used to calculate keypoint OKS. See http://cocodataset.org/#keypoints-eval +# When empty, it will use the defaults in COCO. +# Otherwise it should be a list[float] with the same length as ROI_KEYPOINT_HEAD.NUM_KEYPOINTS. +_C.TEST.KEYPOINT_OKS_SIGMAS = [] +# Maximum number of detections to return per image during inference (100 is +# based on the limit established for the COCO dataset). +_C.TEST.DETECTIONS_PER_IMAGE = 100 + +_C.TEST.AUG = CN({"ENABLED": False}) +_C.TEST.AUG.MIN_SIZES = (400, 500, 600, 700, 800, 900, 1000, 1100, 1200) +_C.TEST.AUG.MAX_SIZE = 4000 +_C.TEST.AUG.FLIP = True + +_C.TEST.PRECISE_BN = CN({"ENABLED": False}) +_C.TEST.PRECISE_BN.NUM_ITER = 200 + +# ---------------------------------------------------------------------------- # +# Misc options +# ---------------------------------------------------------------------------- # +# Directory where output files are written +_C.OUTPUT_DIR = "./output" +# Set seed to negative to fully randomize everything. +# Set seed to positive to use a fixed seed. Note that a fixed seed increases +# reproducibility but does not guarantee fully deterministic behavior. +# Disabling all parallelism further increases reproducibility. +_C.SEED = -1 +# Benchmark different cudnn algorithms. +# If input images have very different sizes, this option will have large overhead +# for about 10k iterations. It usually hurts total time, but can benefit for certain models. +# If input images have the same or similar sizes, benchmark is often helpful. +_C.CUDNN_BENCHMARK = False +# The period (in terms of steps) for minibatch visualization at train time. +# Set to 0 to disable. +_C.VIS_PERIOD = 0 + +# global config is for quick hack purposes. +# You can set them in command line or config files, +# and access it with: +# +# from annotator.oneformer.detectron2.config import global_cfg +# print(global_cfg.HACK) +# +# Do not commit any configs into it. +_C.GLOBAL = CN() +_C.GLOBAL.HACK = 1.0 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/instantiate.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/instantiate.py new file mode 100644 index 00000000..26d191b0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/instantiate.py @@ -0,0 +1,88 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +import collections.abc as abc +import dataclasses +import logging +from typing import Any + +from annotator.oneformer.detectron2.utils.registry import _convert_target_to_string, locate + +__all__ = ["dump_dataclass", "instantiate"] + + +def dump_dataclass(obj: Any): + """ + Dump a dataclass recursively into a dict that can be later instantiated. + + Args: + obj: a dataclass object + + Returns: + dict + """ + assert dataclasses.is_dataclass(obj) and not isinstance( + obj, type + ), "dump_dataclass() requires an instance of a dataclass." + ret = {"_target_": _convert_target_to_string(type(obj))} + for f in dataclasses.fields(obj): + v = getattr(obj, f.name) + if dataclasses.is_dataclass(v): + v = dump_dataclass(v) + if isinstance(v, (list, tuple)): + v = [dump_dataclass(x) if dataclasses.is_dataclass(x) else x for x in v] + ret[f.name] = v + return ret + + +def instantiate(cfg): + """ + Recursively instantiate objects defined in dictionaries by + "_target_" and arguments. + + Args: + cfg: a dict-like object with "_target_" that defines the caller, and + other keys that define the arguments + + Returns: + object instantiated by cfg + """ + from omegaconf import ListConfig, DictConfig, OmegaConf + + if isinstance(cfg, ListConfig): + lst = [instantiate(x) for x in cfg] + return ListConfig(lst, flags={"allow_objects": True}) + if isinstance(cfg, list): + # Specialize for list, because many classes take + # list[objects] as arguments, such as ResNet, DatasetMapper + return [instantiate(x) for x in cfg] + + # If input is a DictConfig backed by dataclasses (i.e. omegaconf's structured config), + # instantiate it to the actual dataclass. + if isinstance(cfg, DictConfig) and dataclasses.is_dataclass(cfg._metadata.object_type): + return OmegaConf.to_object(cfg) + + if isinstance(cfg, abc.Mapping) and "_target_" in cfg: + # conceptually equivalent to hydra.utils.instantiate(cfg) with _convert_=all, + # but faster: https://github.com/facebookresearch/hydra/issues/1200 + cfg = {k: instantiate(v) for k, v in cfg.items()} + cls = cfg.pop("_target_") + cls = instantiate(cls) + + if isinstance(cls, str): + cls_name = cls + cls = locate(cls_name) + assert cls is not None, cls_name + else: + try: + cls_name = cls.__module__ + "." + cls.__qualname__ + except Exception: + # target could be anything, so the above could fail + cls_name = str(cls) + assert callable(cls), f"_target_ {cls} does not define a callable object" + try: + return cls(**cfg) + except TypeError: + logger = logging.getLogger(__name__) + logger.error(f"Error when instantiating {cls_name}!") + raise + return cfg # return as-is if don't know what to do diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/lazy.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/lazy.py new file mode 100644 index 00000000..72a3e5c0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/config/lazy.py @@ -0,0 +1,435 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +import ast +import builtins +import collections.abc as abc +import importlib +import inspect +import logging +import os +import uuid +from contextlib import contextmanager +from copy import deepcopy +from dataclasses import is_dataclass +from typing import List, Tuple, Union +import yaml +from omegaconf import DictConfig, ListConfig, OmegaConf, SCMode + +from annotator.oneformer.detectron2.utils.file_io import PathManager +from annotator.oneformer.detectron2.utils.registry import _convert_target_to_string + +__all__ = ["LazyCall", "LazyConfig"] + + +class LazyCall: + """ + Wrap a callable so that when it's called, the call will not be executed, + but returns a dict that describes the call. + + LazyCall object has to be called with only keyword arguments. Positional + arguments are not yet supported. + + Examples: + :: + from annotator.oneformer.detectron2.config import instantiate, LazyCall + + layer_cfg = LazyCall(nn.Conv2d)(in_channels=32, out_channels=32) + layer_cfg.out_channels = 64 # can edit it afterwards + layer = instantiate(layer_cfg) + """ + + def __init__(self, target): + if not (callable(target) or isinstance(target, (str, abc.Mapping))): + raise TypeError( + f"target of LazyCall must be a callable or defines a callable! Got {target}" + ) + self._target = target + + def __call__(self, **kwargs): + if is_dataclass(self._target): + # omegaconf object cannot hold dataclass type + # https://github.com/omry/omegaconf/issues/784 + target = _convert_target_to_string(self._target) + else: + target = self._target + kwargs["_target_"] = target + + return DictConfig(content=kwargs, flags={"allow_objects": True}) + + +def _visit_dict_config(cfg, func): + """ + Apply func recursively to all DictConfig in cfg. + """ + if isinstance(cfg, DictConfig): + func(cfg) + for v in cfg.values(): + _visit_dict_config(v, func) + elif isinstance(cfg, ListConfig): + for v in cfg: + _visit_dict_config(v, func) + + +def _validate_py_syntax(filename): + # see also https://github.com/open-mmlab/mmcv/blob/master/mmcv/utils/config.py + with PathManager.open(filename, "r") as f: + content = f.read() + try: + ast.parse(content) + except SyntaxError as e: + raise SyntaxError(f"Config file {filename} has syntax error!") from e + + +def _cast_to_config(obj): + # if given a dict, return DictConfig instead + if isinstance(obj, dict): + return DictConfig(obj, flags={"allow_objects": True}) + return obj + + +_CFG_PACKAGE_NAME = "detectron2._cfg_loader" +""" +A namespace to put all imported config into. +""" + + +def _random_package_name(filename): + # generate a random package name when loading config files + return _CFG_PACKAGE_NAME + str(uuid.uuid4())[:4] + "." + os.path.basename(filename) + + +@contextmanager +def _patch_import(): + """ + Enhance relative import statements in config files, so that they: + 1. locate files purely based on relative location, regardless of packages. + e.g. you can import file without having __init__ + 2. do not cache modules globally; modifications of module states has no side effect + 3. support other storage system through PathManager, so config files can be in the cloud + 4. imported dict are turned into omegaconf.DictConfig automatically + """ + old_import = builtins.__import__ + + def find_relative_file(original_file, relative_import_path, level): + # NOTE: "from . import x" is not handled. Because then it's unclear + # if such import should produce `x` as a python module or DictConfig. + # This can be discussed further if needed. + relative_import_err = """ +Relative import of directories is not allowed within config files. +Within a config file, relative import can only import other config files. +""".replace( + "\n", " " + ) + if not len(relative_import_path): + raise ImportError(relative_import_err) + + cur_file = os.path.dirname(original_file) + for _ in range(level - 1): + cur_file = os.path.dirname(cur_file) + cur_name = relative_import_path.lstrip(".") + for part in cur_name.split("."): + cur_file = os.path.join(cur_file, part) + if not cur_file.endswith(".py"): + cur_file += ".py" + if not PathManager.isfile(cur_file): + cur_file_no_suffix = cur_file[: -len(".py")] + if PathManager.isdir(cur_file_no_suffix): + raise ImportError(f"Cannot import from {cur_file_no_suffix}." + relative_import_err) + else: + raise ImportError( + f"Cannot import name {relative_import_path} from " + f"{original_file}: {cur_file} does not exist." + ) + return cur_file + + def new_import(name, globals=None, locals=None, fromlist=(), level=0): + if ( + # Only deal with relative imports inside config files + level != 0 + and globals is not None + and (globals.get("__package__", "") or "").startswith(_CFG_PACKAGE_NAME) + ): + cur_file = find_relative_file(globals["__file__"], name, level) + _validate_py_syntax(cur_file) + spec = importlib.machinery.ModuleSpec( + _random_package_name(cur_file), None, origin=cur_file + ) + module = importlib.util.module_from_spec(spec) + module.__file__ = cur_file + with PathManager.open(cur_file) as f: + content = f.read() + exec(compile(content, cur_file, "exec"), module.__dict__) + for name in fromlist: # turn imported dict into DictConfig automatically + val = _cast_to_config(module.__dict__[name]) + module.__dict__[name] = val + return module + return old_import(name, globals, locals, fromlist=fromlist, level=level) + + builtins.__import__ = new_import + yield new_import + builtins.__import__ = old_import + + +class LazyConfig: + """ + Provide methods to save, load, and overrides an omegaconf config object + which may contain definition of lazily-constructed objects. + """ + + @staticmethod + def load_rel(filename: str, keys: Union[None, str, Tuple[str, ...]] = None): + """ + Similar to :meth:`load()`, but load path relative to the caller's + source file. + + This has the same functionality as a relative import, except that this method + accepts filename as a string, so more characters are allowed in the filename. + """ + caller_frame = inspect.stack()[1] + caller_fname = caller_frame[0].f_code.co_filename + assert caller_fname != "", "load_rel Unable to find caller" + caller_dir = os.path.dirname(caller_fname) + filename = os.path.join(caller_dir, filename) + return LazyConfig.load(filename, keys) + + @staticmethod + def load(filename: str, keys: Union[None, str, Tuple[str, ...]] = None): + """ + Load a config file. + + Args: + filename: absolute path or relative path w.r.t. the current working directory + keys: keys to load and return. If not given, return all keys + (whose values are config objects) in a dict. + """ + has_keys = keys is not None + filename = filename.replace("/./", "/") # redundant + if os.path.splitext(filename)[1] not in [".py", ".yaml", ".yml"]: + raise ValueError(f"Config file {filename} has to be a python or yaml file.") + if filename.endswith(".py"): + _validate_py_syntax(filename) + + with _patch_import(): + # Record the filename + module_namespace = { + "__file__": filename, + "__package__": _random_package_name(filename), + } + with PathManager.open(filename) as f: + content = f.read() + # Compile first with filename to: + # 1. make filename appears in stacktrace + # 2. make load_rel able to find its parent's (possibly remote) location + exec(compile(content, filename, "exec"), module_namespace) + + ret = module_namespace + else: + with PathManager.open(filename) as f: + obj = yaml.unsafe_load(f) + ret = OmegaConf.create(obj, flags={"allow_objects": True}) + + if has_keys: + if isinstance(keys, str): + return _cast_to_config(ret[keys]) + else: + return tuple(_cast_to_config(ret[a]) for a in keys) + else: + if filename.endswith(".py"): + # when not specified, only load those that are config objects + ret = DictConfig( + { + name: _cast_to_config(value) + for name, value in ret.items() + if isinstance(value, (DictConfig, ListConfig, dict)) + and not name.startswith("_") + }, + flags={"allow_objects": True}, + ) + return ret + + @staticmethod + def save(cfg, filename: str): + """ + Save a config object to a yaml file. + Note that when the config dictionary contains complex objects (e.g. lambda), + it can't be saved to yaml. In that case we will print an error and + attempt to save to a pkl file instead. + + Args: + cfg: an omegaconf config object + filename: yaml file name to save the config file + """ + logger = logging.getLogger(__name__) + try: + cfg = deepcopy(cfg) + except Exception: + pass + else: + # if it's deep-copyable, then... + def _replace_type_by_name(x): + if "_target_" in x and callable(x._target_): + try: + x._target_ = _convert_target_to_string(x._target_) + except AttributeError: + pass + + # not necessary, but makes yaml looks nicer + _visit_dict_config(cfg, _replace_type_by_name) + + save_pkl = False + try: + dict = OmegaConf.to_container( + cfg, + # Do not resolve interpolation when saving, i.e. do not turn ${a} into + # actual values when saving. + resolve=False, + # Save structures (dataclasses) in a format that can be instantiated later. + # Without this option, the type information of the dataclass will be erased. + structured_config_mode=SCMode.INSTANTIATE, + ) + dumped = yaml.dump(dict, default_flow_style=None, allow_unicode=True, width=9999) + with PathManager.open(filename, "w") as f: + f.write(dumped) + + try: + _ = yaml.unsafe_load(dumped) # test that it is loadable + except Exception: + logger.warning( + "The config contains objects that cannot serialize to a valid yaml. " + f"{filename} is human-readable but cannot be loaded." + ) + save_pkl = True + except Exception: + logger.exception("Unable to serialize the config to yaml. Error:") + save_pkl = True + + if save_pkl: + new_filename = filename + ".pkl" + # try: + # # retry by pickle + # with PathManager.open(new_filename, "wb") as f: + # cloudpickle.dump(cfg, f) + # logger.warning(f"Config is saved using cloudpickle at {new_filename}.") + # except Exception: + # pass + + @staticmethod + def apply_overrides(cfg, overrides: List[str]): + """ + In-place override contents of cfg. + + Args: + cfg: an omegaconf config object + overrides: list of strings in the format of "a=b" to override configs. + See https://hydra.cc/docs/next/advanced/override_grammar/basic/ + for syntax. + + Returns: + the cfg object + """ + + def safe_update(cfg, key, value): + parts = key.split(".") + for idx in range(1, len(parts)): + prefix = ".".join(parts[:idx]) + v = OmegaConf.select(cfg, prefix, default=None) + if v is None: + break + if not OmegaConf.is_config(v): + raise KeyError( + f"Trying to update key {key}, but {prefix} " + f"is not a config, but has type {type(v)}." + ) + OmegaConf.update(cfg, key, value, merge=True) + + try: + from hydra.core.override_parser.overrides_parser import OverridesParser + + has_hydra = True + except ImportError: + has_hydra = False + + if has_hydra: + parser = OverridesParser.create() + overrides = parser.parse_overrides(overrides) + for o in overrides: + key = o.key_or_group + value = o.value() + if o.is_delete(): + # TODO support this + raise NotImplementedError("deletion is not yet a supported override") + safe_update(cfg, key, value) + else: + # Fallback. Does not support all the features and error checking like hydra. + for o in overrides: + key, value = o.split("=") + try: + value = eval(value, {}) + except NameError: + pass + safe_update(cfg, key, value) + return cfg + + # @staticmethod + # def to_py(cfg, prefix: str = "cfg."): + # """ + # Try to convert a config object into Python-like psuedo code. + # + # Note that perfect conversion is not always possible. So the returned + # results are mainly meant to be human-readable, and not meant to be executed. + # + # Args: + # cfg: an omegaconf config object + # prefix: root name for the resulting code (default: "cfg.") + # + # + # Returns: + # str of formatted Python code + # """ + # import black + # + # cfg = OmegaConf.to_container(cfg, resolve=True) + # + # def _to_str(obj, prefix=None, inside_call=False): + # if prefix is None: + # prefix = [] + # if isinstance(obj, abc.Mapping) and "_target_" in obj: + # # Dict representing a function call + # target = _convert_target_to_string(obj.pop("_target_")) + # args = [] + # for k, v in sorted(obj.items()): + # args.append(f"{k}={_to_str(v, inside_call=True)}") + # args = ", ".join(args) + # call = f"{target}({args})" + # return "".join(prefix) + call + # elif isinstance(obj, abc.Mapping) and not inside_call: + # # Dict that is not inside a call is a list of top-level config objects that we + # # render as one object per line with dot separated prefixes + # key_list = [] + # for k, v in sorted(obj.items()): + # if isinstance(v, abc.Mapping) and "_target_" not in v: + # key_list.append(_to_str(v, prefix=prefix + [k + "."])) + # else: + # key = "".join(prefix) + k + # key_list.append(f"{key}={_to_str(v)}") + # return "\n".join(key_list) + # elif isinstance(obj, abc.Mapping): + # # Dict that is inside a call is rendered as a regular dict + # return ( + # "{" + # + ",".join( + # f"{repr(k)}: {_to_str(v, inside_call=inside_call)}" + # for k, v in sorted(obj.items()) + # ) + # + "}" + # ) + # elif isinstance(obj, list): + # return "[" + ",".join(_to_str(x, inside_call=inside_call) for x in obj) + "]" + # else: + # return repr(obj) + # + # py_str = _to_str(cfg, prefix=[prefix]) + # try: + # return black.format_str(py_str, mode=black.Mode()) + # except black.InvalidInput: + # return py_str diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/__init__.py new file mode 100644 index 00000000..259f669b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/__init__.py @@ -0,0 +1,19 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from . import transforms # isort:skip + +from .build import ( + build_batch_data_loader, + build_detection_test_loader, + build_detection_train_loader, + get_detection_dataset_dicts, + load_proposals_into_dataset, + print_instances_class_histogram, +) +from .catalog import DatasetCatalog, MetadataCatalog, Metadata +from .common import DatasetFromList, MapDataset, ToIterableDataset +from .dataset_mapper import DatasetMapper + +# ensure the builtin datasets are registered +from . import datasets, samplers # isort:skip + +__all__ = [k for k in globals().keys() if not k.startswith("_")] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/benchmark.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/benchmark.py new file mode 100644 index 00000000..bfd65058 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/benchmark.py @@ -0,0 +1,225 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import logging +import numpy as np +from itertools import count +from typing import List, Tuple +import torch +import tqdm +from fvcore.common.timer import Timer + +from annotator.oneformer.detectron2.utils import comm + +from .build import build_batch_data_loader +from .common import DatasetFromList, MapDataset +from .samplers import TrainingSampler + +logger = logging.getLogger(__name__) + + +class _EmptyMapDataset(torch.utils.data.Dataset): + """ + Map anything to emptiness. + """ + + def __init__(self, dataset): + self.ds = dataset + + def __len__(self): + return len(self.ds) + + def __getitem__(self, idx): + _ = self.ds[idx] + return [0] + + +def iter_benchmark( + iterator, num_iter: int, warmup: int = 5, max_time_seconds: float = 60 +) -> Tuple[float, List[float]]: + """ + Benchmark an iterator/iterable for `num_iter` iterations with an extra + `warmup` iterations of warmup. + End early if `max_time_seconds` time is spent on iterations. + + Returns: + float: average time (seconds) per iteration + list[float]: time spent on each iteration. Sometimes useful for further analysis. + """ + num_iter, warmup = int(num_iter), int(warmup) + + iterator = iter(iterator) + for _ in range(warmup): + next(iterator) + timer = Timer() + all_times = [] + for curr_iter in tqdm.trange(num_iter): + start = timer.seconds() + if start > max_time_seconds: + num_iter = curr_iter + break + next(iterator) + all_times.append(timer.seconds() - start) + avg = timer.seconds() / num_iter + return avg, all_times + + +class DataLoaderBenchmark: + """ + Some common benchmarks that help understand perf bottleneck of a standard dataloader + made of dataset, mapper and sampler. + """ + + def __init__( + self, + dataset, + *, + mapper, + sampler=None, + total_batch_size, + num_workers=0, + max_time_seconds: int = 90, + ): + """ + Args: + max_time_seconds (int): maximum time to spent for each benchmark + other args: same as in `build.py:build_detection_train_loader` + """ + if isinstance(dataset, list): + dataset = DatasetFromList(dataset, copy=False, serialize=True) + if sampler is None: + sampler = TrainingSampler(len(dataset)) + + self.dataset = dataset + self.mapper = mapper + self.sampler = sampler + self.total_batch_size = total_batch_size + self.num_workers = num_workers + self.per_gpu_batch_size = self.total_batch_size // comm.get_world_size() + + self.max_time_seconds = max_time_seconds + + def _benchmark(self, iterator, num_iter, warmup, msg=None): + avg, all_times = iter_benchmark(iterator, num_iter, warmup, self.max_time_seconds) + if msg is not None: + self._log_time(msg, avg, all_times) + return avg, all_times + + def _log_time(self, msg, avg, all_times, distributed=False): + percentiles = [np.percentile(all_times, k, interpolation="nearest") for k in [1, 5, 95, 99]] + if not distributed: + logger.info( + f"{msg}: avg={1.0/avg:.1f} it/s, " + f"p1={percentiles[0]:.2g}s, p5={percentiles[1]:.2g}s, " + f"p95={percentiles[2]:.2g}s, p99={percentiles[3]:.2g}s." + ) + return + avg_per_gpu = comm.all_gather(avg) + percentiles_per_gpu = comm.all_gather(percentiles) + if comm.get_rank() > 0: + return + for idx, avg, percentiles in zip(count(), avg_per_gpu, percentiles_per_gpu): + logger.info( + f"GPU{idx} {msg}: avg={1.0/avg:.1f} it/s, " + f"p1={percentiles[0]:.2g}s, p5={percentiles[1]:.2g}s, " + f"p95={percentiles[2]:.2g}s, p99={percentiles[3]:.2g}s." + ) + + def benchmark_dataset(self, num_iter, warmup=5): + """ + Benchmark the speed of taking raw samples from the dataset. + """ + + def loader(): + while True: + for k in self.sampler: + yield self.dataset[k] + + self._benchmark(loader(), num_iter, warmup, "Dataset Alone") + + def benchmark_mapper(self, num_iter, warmup=5): + """ + Benchmark the speed of taking raw samples from the dataset and map + them in a single process. + """ + + def loader(): + while True: + for k in self.sampler: + yield self.mapper(self.dataset[k]) + + self._benchmark(loader(), num_iter, warmup, "Single Process Mapper (sec/sample)") + + def benchmark_workers(self, num_iter, warmup=10): + """ + Benchmark the dataloader by tuning num_workers to [0, 1, self.num_workers]. + """ + candidates = [0, 1] + if self.num_workers not in candidates: + candidates.append(self.num_workers) + + dataset = MapDataset(self.dataset, self.mapper) + for n in candidates: + loader = build_batch_data_loader( + dataset, + self.sampler, + self.total_batch_size, + num_workers=n, + ) + self._benchmark( + iter(loader), + num_iter * max(n, 1), + warmup * max(n, 1), + f"DataLoader ({n} workers, bs={self.per_gpu_batch_size})", + ) + del loader + + def benchmark_IPC(self, num_iter, warmup=10): + """ + Benchmark the dataloader where each worker outputs nothing. This + eliminates the IPC overhead compared to the regular dataloader. + + PyTorch multiprocessing's IPC only optimizes for torch tensors. + Large numpy arrays or other data structure may incur large IPC overhead. + """ + n = self.num_workers + dataset = _EmptyMapDataset(MapDataset(self.dataset, self.mapper)) + loader = build_batch_data_loader( + dataset, self.sampler, self.total_batch_size, num_workers=n + ) + self._benchmark( + iter(loader), + num_iter * max(n, 1), + warmup * max(n, 1), + f"DataLoader ({n} workers, bs={self.per_gpu_batch_size}) w/o comm", + ) + + def benchmark_distributed(self, num_iter, warmup=10): + """ + Benchmark the dataloader in each distributed worker, and log results of + all workers. This helps understand the final performance as well as + the variances among workers. + + It also prints startup time (first iter) of the dataloader. + """ + gpu = comm.get_world_size() + dataset = MapDataset(self.dataset, self.mapper) + n = self.num_workers + loader = build_batch_data_loader( + dataset, self.sampler, self.total_batch_size, num_workers=n + ) + + timer = Timer() + loader = iter(loader) + next(loader) + startup_time = timer.seconds() + logger.info("Dataloader startup time: {:.2f} seconds".format(startup_time)) + + comm.synchronize() + + avg, all_times = self._benchmark(loader, num_iter * max(n, 1), warmup * max(n, 1)) + del loader + self._log_time( + f"DataLoader ({gpu} GPUs x {n} workers, total bs={self.total_batch_size})", + avg, + all_times, + True, + ) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/build.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/build.py new file mode 100644 index 00000000..d03137a9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/build.py @@ -0,0 +1,556 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import itertools +import logging +import numpy as np +import operator +import pickle +from typing import Any, Callable, Dict, List, Optional, Union +import torch +import torch.utils.data as torchdata +from tabulate import tabulate +from termcolor import colored + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.structures import BoxMode +from annotator.oneformer.detectron2.utils.comm import get_world_size +from annotator.oneformer.detectron2.utils.env import seed_all_rng +from annotator.oneformer.detectron2.utils.file_io import PathManager +from annotator.oneformer.detectron2.utils.logger import _log_api_usage, log_first_n + +from .catalog import DatasetCatalog, MetadataCatalog +from .common import AspectRatioGroupedDataset, DatasetFromList, MapDataset, ToIterableDataset +from .dataset_mapper import DatasetMapper +from .detection_utils import check_metadata_consistency +from .samplers import ( + InferenceSampler, + RandomSubsetTrainingSampler, + RepeatFactorTrainingSampler, + TrainingSampler, +) + +""" +This file contains the default logic to build a dataloader for training or testing. +""" + +__all__ = [ + "build_batch_data_loader", + "build_detection_train_loader", + "build_detection_test_loader", + "get_detection_dataset_dicts", + "load_proposals_into_dataset", + "print_instances_class_histogram", +] + + +def filter_images_with_only_crowd_annotations(dataset_dicts): + """ + Filter out images with none annotations or only crowd annotations + (i.e., images without non-crowd annotations). + A common training-time preprocessing on COCO dataset. + + Args: + dataset_dicts (list[dict]): annotations in Detectron2 Dataset format. + + Returns: + list[dict]: the same format, but filtered. + """ + num_before = len(dataset_dicts) + + def valid(anns): + for ann in anns: + if ann.get("iscrowd", 0) == 0: + return True + return False + + dataset_dicts = [x for x in dataset_dicts if valid(x["annotations"])] + num_after = len(dataset_dicts) + logger = logging.getLogger(__name__) + logger.info( + "Removed {} images with no usable annotations. {} images left.".format( + num_before - num_after, num_after + ) + ) + return dataset_dicts + + +def filter_images_with_few_keypoints(dataset_dicts, min_keypoints_per_image): + """ + Filter out images with too few number of keypoints. + + Args: + dataset_dicts (list[dict]): annotations in Detectron2 Dataset format. + + Returns: + list[dict]: the same format as dataset_dicts, but filtered. + """ + num_before = len(dataset_dicts) + + def visible_keypoints_in_image(dic): + # Each keypoints field has the format [x1, y1, v1, ...], where v is visibility + annotations = dic["annotations"] + return sum( + (np.array(ann["keypoints"][2::3]) > 0).sum() + for ann in annotations + if "keypoints" in ann + ) + + dataset_dicts = [ + x for x in dataset_dicts if visible_keypoints_in_image(x) >= min_keypoints_per_image + ] + num_after = len(dataset_dicts) + logger = logging.getLogger(__name__) + logger.info( + "Removed {} images with fewer than {} keypoints.".format( + num_before - num_after, min_keypoints_per_image + ) + ) + return dataset_dicts + + +def load_proposals_into_dataset(dataset_dicts, proposal_file): + """ + Load precomputed object proposals into the dataset. + + The proposal file should be a pickled dict with the following keys: + + - "ids": list[int] or list[str], the image ids + - "boxes": list[np.ndarray], each is an Nx4 array of boxes corresponding to the image id + - "objectness_logits": list[np.ndarray], each is an N sized array of objectness scores + corresponding to the boxes. + - "bbox_mode": the BoxMode of the boxes array. Defaults to ``BoxMode.XYXY_ABS``. + + Args: + dataset_dicts (list[dict]): annotations in Detectron2 Dataset format. + proposal_file (str): file path of pre-computed proposals, in pkl format. + + Returns: + list[dict]: the same format as dataset_dicts, but added proposal field. + """ + logger = logging.getLogger(__name__) + logger.info("Loading proposals from: {}".format(proposal_file)) + + with PathManager.open(proposal_file, "rb") as f: + proposals = pickle.load(f, encoding="latin1") + + # Rename the key names in D1 proposal files + rename_keys = {"indexes": "ids", "scores": "objectness_logits"} + for key in rename_keys: + if key in proposals: + proposals[rename_keys[key]] = proposals.pop(key) + + # Fetch the indexes of all proposals that are in the dataset + # Convert image_id to str since they could be int. + img_ids = set({str(record["image_id"]) for record in dataset_dicts}) + id_to_index = {str(id): i for i, id in enumerate(proposals["ids"]) if str(id) in img_ids} + + # Assuming default bbox_mode of precomputed proposals are 'XYXY_ABS' + bbox_mode = BoxMode(proposals["bbox_mode"]) if "bbox_mode" in proposals else BoxMode.XYXY_ABS + + for record in dataset_dicts: + # Get the index of the proposal + i = id_to_index[str(record["image_id"])] + + boxes = proposals["boxes"][i] + objectness_logits = proposals["objectness_logits"][i] + # Sort the proposals in descending order of the scores + inds = objectness_logits.argsort()[::-1] + record["proposal_boxes"] = boxes[inds] + record["proposal_objectness_logits"] = objectness_logits[inds] + record["proposal_bbox_mode"] = bbox_mode + + return dataset_dicts + + +def print_instances_class_histogram(dataset_dicts, class_names): + """ + Args: + dataset_dicts (list[dict]): list of dataset dicts. + class_names (list[str]): list of class names (zero-indexed). + """ + num_classes = len(class_names) + hist_bins = np.arange(num_classes + 1) + histogram = np.zeros((num_classes,), dtype=np.int) + for entry in dataset_dicts: + annos = entry["annotations"] + classes = np.asarray( + [x["category_id"] for x in annos if not x.get("iscrowd", 0)], dtype=np.int + ) + if len(classes): + assert classes.min() >= 0, f"Got an invalid category_id={classes.min()}" + assert ( + classes.max() < num_classes + ), f"Got an invalid category_id={classes.max()} for a dataset of {num_classes} classes" + histogram += np.histogram(classes, bins=hist_bins)[0] + + N_COLS = min(6, len(class_names) * 2) + + def short_name(x): + # make long class names shorter. useful for lvis + if len(x) > 13: + return x[:11] + ".." + return x + + data = list( + itertools.chain(*[[short_name(class_names[i]), int(v)] for i, v in enumerate(histogram)]) + ) + total_num_instances = sum(data[1::2]) + data.extend([None] * (N_COLS - (len(data) % N_COLS))) + if num_classes > 1: + data.extend(["total", total_num_instances]) + data = itertools.zip_longest(*[data[i::N_COLS] for i in range(N_COLS)]) + table = tabulate( + data, + headers=["category", "#instances"] * (N_COLS // 2), + tablefmt="pipe", + numalign="left", + stralign="center", + ) + log_first_n( + logging.INFO, + "Distribution of instances among all {} categories:\n".format(num_classes) + + colored(table, "cyan"), + key="message", + ) + + +def get_detection_dataset_dicts( + names, + filter_empty=True, + min_keypoints=0, + proposal_files=None, + check_consistency=True, +): + """ + Load and prepare dataset dicts for instance detection/segmentation and semantic segmentation. + + Args: + names (str or list[str]): a dataset name or a list of dataset names + filter_empty (bool): whether to filter out images without instance annotations + min_keypoints (int): filter out images with fewer keypoints than + `min_keypoints`. Set to 0 to do nothing. + proposal_files (list[str]): if given, a list of object proposal files + that match each dataset in `names`. + check_consistency (bool): whether to check if datasets have consistent metadata. + + Returns: + list[dict]: a list of dicts following the standard dataset dict format. + """ + if isinstance(names, str): + names = [names] + assert len(names), names + dataset_dicts = [DatasetCatalog.get(dataset_name) for dataset_name in names] + + if isinstance(dataset_dicts[0], torchdata.Dataset): + if len(dataset_dicts) > 1: + # ConcatDataset does not work for iterable style dataset. + # We could support concat for iterable as well, but it's often + # not a good idea to concat iterables anyway. + return torchdata.ConcatDataset(dataset_dicts) + return dataset_dicts[0] + + for dataset_name, dicts in zip(names, dataset_dicts): + assert len(dicts), "Dataset '{}' is empty!".format(dataset_name) + + if proposal_files is not None: + assert len(names) == len(proposal_files) + # load precomputed proposals from proposal files + dataset_dicts = [ + load_proposals_into_dataset(dataset_i_dicts, proposal_file) + for dataset_i_dicts, proposal_file in zip(dataset_dicts, proposal_files) + ] + + dataset_dicts = list(itertools.chain.from_iterable(dataset_dicts)) + + has_instances = "annotations" in dataset_dicts[0] + if filter_empty and has_instances: + dataset_dicts = filter_images_with_only_crowd_annotations(dataset_dicts) + if min_keypoints > 0 and has_instances: + dataset_dicts = filter_images_with_few_keypoints(dataset_dicts, min_keypoints) + + if check_consistency and has_instances: + try: + class_names = MetadataCatalog.get(names[0]).thing_classes + check_metadata_consistency("thing_classes", names) + print_instances_class_histogram(dataset_dicts, class_names) + except AttributeError: # class names are not available for this dataset + pass + + assert len(dataset_dicts), "No valid data found in {}.".format(",".join(names)) + return dataset_dicts + + +def build_batch_data_loader( + dataset, + sampler, + total_batch_size, + *, + aspect_ratio_grouping=False, + num_workers=0, + collate_fn=None, +): + """ + Build a batched dataloader. The main differences from `torch.utils.data.DataLoader` are: + 1. support aspect ratio grouping options + 2. use no "batch collation", because this is common for detection training + + Args: + dataset (torch.utils.data.Dataset): a pytorch map-style or iterable dataset. + sampler (torch.utils.data.sampler.Sampler or None): a sampler that produces indices. + Must be provided iff. ``dataset`` is a map-style dataset. + total_batch_size, aspect_ratio_grouping, num_workers, collate_fn: see + :func:`build_detection_train_loader`. + + Returns: + iterable[list]. Length of each list is the batch size of the current + GPU. Each element in the list comes from the dataset. + """ + world_size = get_world_size() + assert ( + total_batch_size > 0 and total_batch_size % world_size == 0 + ), "Total batch size ({}) must be divisible by the number of gpus ({}).".format( + total_batch_size, world_size + ) + batch_size = total_batch_size // world_size + + if isinstance(dataset, torchdata.IterableDataset): + assert sampler is None, "sampler must be None if dataset is IterableDataset" + else: + dataset = ToIterableDataset(dataset, sampler) + + if aspect_ratio_grouping: + data_loader = torchdata.DataLoader( + dataset, + num_workers=num_workers, + collate_fn=operator.itemgetter(0), # don't batch, but yield individual elements + worker_init_fn=worker_init_reset_seed, + ) # yield individual mapped dict + data_loader = AspectRatioGroupedDataset(data_loader, batch_size) + if collate_fn is None: + return data_loader + return MapDataset(data_loader, collate_fn) + else: + return torchdata.DataLoader( + dataset, + batch_size=batch_size, + drop_last=True, + num_workers=num_workers, + collate_fn=trivial_batch_collator if collate_fn is None else collate_fn, + worker_init_fn=worker_init_reset_seed, + ) + + +def _train_loader_from_config(cfg, mapper=None, *, dataset=None, sampler=None): + if dataset is None: + dataset = get_detection_dataset_dicts( + cfg.DATASETS.TRAIN, + filter_empty=cfg.DATALOADER.FILTER_EMPTY_ANNOTATIONS, + min_keypoints=cfg.MODEL.ROI_KEYPOINT_HEAD.MIN_KEYPOINTS_PER_IMAGE + if cfg.MODEL.KEYPOINT_ON + else 0, + proposal_files=cfg.DATASETS.PROPOSAL_FILES_TRAIN if cfg.MODEL.LOAD_PROPOSALS else None, + ) + _log_api_usage("dataset." + cfg.DATASETS.TRAIN[0]) + + if mapper is None: + mapper = DatasetMapper(cfg, True) + + if sampler is None: + sampler_name = cfg.DATALOADER.SAMPLER_TRAIN + logger = logging.getLogger(__name__) + if isinstance(dataset, torchdata.IterableDataset): + logger.info("Not using any sampler since the dataset is IterableDataset.") + sampler = None + else: + logger.info("Using training sampler {}".format(sampler_name)) + if sampler_name == "TrainingSampler": + sampler = TrainingSampler(len(dataset)) + elif sampler_name == "RepeatFactorTrainingSampler": + repeat_factors = RepeatFactorTrainingSampler.repeat_factors_from_category_frequency( + dataset, cfg.DATALOADER.REPEAT_THRESHOLD + ) + sampler = RepeatFactorTrainingSampler(repeat_factors) + elif sampler_name == "RandomSubsetTrainingSampler": + sampler = RandomSubsetTrainingSampler( + len(dataset), cfg.DATALOADER.RANDOM_SUBSET_RATIO + ) + else: + raise ValueError("Unknown training sampler: {}".format(sampler_name)) + + return { + "dataset": dataset, + "sampler": sampler, + "mapper": mapper, + "total_batch_size": cfg.SOLVER.IMS_PER_BATCH, + "aspect_ratio_grouping": cfg.DATALOADER.ASPECT_RATIO_GROUPING, + "num_workers": cfg.DATALOADER.NUM_WORKERS, + } + + +@configurable(from_config=_train_loader_from_config) +def build_detection_train_loader( + dataset, + *, + mapper, + sampler=None, + total_batch_size, + aspect_ratio_grouping=True, + num_workers=0, + collate_fn=None, +): + """ + Build a dataloader for object detection with some default features. + + Args: + dataset (list or torch.utils.data.Dataset): a list of dataset dicts, + or a pytorch dataset (either map-style or iterable). It can be obtained + by using :func:`DatasetCatalog.get` or :func:`get_detection_dataset_dicts`. + mapper (callable): a callable which takes a sample (dict) from dataset and + returns the format to be consumed by the model. + When using cfg, the default choice is ``DatasetMapper(cfg, is_train=True)``. + sampler (torch.utils.data.sampler.Sampler or None): a sampler that produces + indices to be applied on ``dataset``. + If ``dataset`` is map-style, the default sampler is a :class:`TrainingSampler`, + which coordinates an infinite random shuffle sequence across all workers. + Sampler must be None if ``dataset`` is iterable. + total_batch_size (int): total batch size across all workers. + aspect_ratio_grouping (bool): whether to group images with similar + aspect ratio for efficiency. When enabled, it requires each + element in dataset be a dict with keys "width" and "height". + num_workers (int): number of parallel data loading workers + collate_fn: a function that determines how to do batching, same as the argument of + `torch.utils.data.DataLoader`. Defaults to do no collation and return a list of + data. No collation is OK for small batch size and simple data structures. + If your batch size is large and each sample contains too many small tensors, + it's more efficient to collate them in data loader. + + Returns: + torch.utils.data.DataLoader: + a dataloader. Each output from it is a ``list[mapped_element]`` of length + ``total_batch_size / num_workers``, where ``mapped_element`` is produced + by the ``mapper``. + """ + if isinstance(dataset, list): + dataset = DatasetFromList(dataset, copy=False) + if mapper is not None: + dataset = MapDataset(dataset, mapper) + + if isinstance(dataset, torchdata.IterableDataset): + assert sampler is None, "sampler must be None if dataset is IterableDataset" + else: + if sampler is None: + sampler = TrainingSampler(len(dataset)) + assert isinstance(sampler, torchdata.Sampler), f"Expect a Sampler but got {type(sampler)}" + return build_batch_data_loader( + dataset, + sampler, + total_batch_size, + aspect_ratio_grouping=aspect_ratio_grouping, + num_workers=num_workers, + collate_fn=collate_fn, + ) + + +def _test_loader_from_config(cfg, dataset_name, mapper=None): + """ + Uses the given `dataset_name` argument (instead of the names in cfg), because the + standard practice is to evaluate each test set individually (not combining them). + """ + if isinstance(dataset_name, str): + dataset_name = [dataset_name] + + dataset = get_detection_dataset_dicts( + dataset_name, + filter_empty=False, + proposal_files=[ + cfg.DATASETS.PROPOSAL_FILES_TEST[list(cfg.DATASETS.TEST).index(x)] for x in dataset_name + ] + if cfg.MODEL.LOAD_PROPOSALS + else None, + ) + if mapper is None: + mapper = DatasetMapper(cfg, False) + return { + "dataset": dataset, + "mapper": mapper, + "num_workers": cfg.DATALOADER.NUM_WORKERS, + "sampler": InferenceSampler(len(dataset)) + if not isinstance(dataset, torchdata.IterableDataset) + else None, + } + + +@configurable(from_config=_test_loader_from_config) +def build_detection_test_loader( + dataset: Union[List[Any], torchdata.Dataset], + *, + mapper: Callable[[Dict[str, Any]], Any], + sampler: Optional[torchdata.Sampler] = None, + batch_size: int = 1, + num_workers: int = 0, + collate_fn: Optional[Callable[[List[Any]], Any]] = None, +) -> torchdata.DataLoader: + """ + Similar to `build_detection_train_loader`, with default batch size = 1, + and sampler = :class:`InferenceSampler`. This sampler coordinates all workers + to produce the exact set of all samples. + + Args: + dataset: a list of dataset dicts, + or a pytorch dataset (either map-style or iterable). They can be obtained + by using :func:`DatasetCatalog.get` or :func:`get_detection_dataset_dicts`. + mapper: a callable which takes a sample (dict) from dataset + and returns the format to be consumed by the model. + When using cfg, the default choice is ``DatasetMapper(cfg, is_train=False)``. + sampler: a sampler that produces + indices to be applied on ``dataset``. Default to :class:`InferenceSampler`, + which splits the dataset across all workers. Sampler must be None + if `dataset` is iterable. + batch_size: the batch size of the data loader to be created. + Default to 1 image per worker since this is the standard when reporting + inference time in papers. + num_workers: number of parallel data loading workers + collate_fn: same as the argument of `torch.utils.data.DataLoader`. + Defaults to do no collation and return a list of data. + + Returns: + DataLoader: a torch DataLoader, that loads the given detection + dataset, with test-time transformation and batching. + + Examples: + :: + data_loader = build_detection_test_loader( + DatasetRegistry.get("my_test"), + mapper=DatasetMapper(...)) + + # or, instantiate with a CfgNode: + data_loader = build_detection_test_loader(cfg, "my_test") + """ + if isinstance(dataset, list): + dataset = DatasetFromList(dataset, copy=False) + if mapper is not None: + dataset = MapDataset(dataset, mapper) + if isinstance(dataset, torchdata.IterableDataset): + assert sampler is None, "sampler must be None if dataset is IterableDataset" + else: + if sampler is None: + sampler = InferenceSampler(len(dataset)) + return torchdata.DataLoader( + dataset, + batch_size=batch_size, + sampler=sampler, + drop_last=False, + num_workers=num_workers, + collate_fn=trivial_batch_collator if collate_fn is None else collate_fn, + ) + + +def trivial_batch_collator(batch): + """ + A batch collator that does nothing. + """ + return batch + + +def worker_init_reset_seed(worker_id): + initial_seed = torch.initial_seed() % 2**31 + seed_all_rng(initial_seed + worker_id) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/catalog.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/catalog.py new file mode 100644 index 00000000..4f5209b5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/catalog.py @@ -0,0 +1,236 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import copy +import logging +import types +from collections import UserDict +from typing import List + +from annotator.oneformer.detectron2.utils.logger import log_first_n + +__all__ = ["DatasetCatalog", "MetadataCatalog", "Metadata"] + + +class _DatasetCatalog(UserDict): + """ + A global dictionary that stores information about the datasets and how to obtain them. + + It contains a mapping from strings + (which are names that identify a dataset, e.g. "coco_2014_train") + to a function which parses the dataset and returns the samples in the + format of `list[dict]`. + + The returned dicts should be in Detectron2 Dataset format (See DATASETS.md for details) + if used with the data loader functionalities in `data/build.py,data/detection_transform.py`. + + The purpose of having this catalog is to make it easy to choose + different datasets, by just using the strings in the config. + """ + + def register(self, name, func): + """ + Args: + name (str): the name that identifies a dataset, e.g. "coco_2014_train". + func (callable): a callable which takes no arguments and returns a list of dicts. + It must return the same results if called multiple times. + """ + assert callable(func), "You must register a function with `DatasetCatalog.register`!" + assert name not in self, "Dataset '{}' is already registered!".format(name) + self[name] = func + + def get(self, name): + """ + Call the registered function and return its results. + + Args: + name (str): the name that identifies a dataset, e.g. "coco_2014_train". + + Returns: + list[dict]: dataset annotations. + """ + try: + f = self[name] + except KeyError as e: + raise KeyError( + "Dataset '{}' is not registered! Available datasets are: {}".format( + name, ", ".join(list(self.keys())) + ) + ) from e + return f() + + def list(self) -> List[str]: + """ + List all registered datasets. + + Returns: + list[str] + """ + return list(self.keys()) + + def remove(self, name): + """ + Alias of ``pop``. + """ + self.pop(name) + + def __str__(self): + return "DatasetCatalog(registered datasets: {})".format(", ".join(self.keys())) + + __repr__ = __str__ + + +DatasetCatalog = _DatasetCatalog() +DatasetCatalog.__doc__ = ( + _DatasetCatalog.__doc__ + + """ + .. automethod:: detectron2.data.catalog.DatasetCatalog.register + .. automethod:: detectron2.data.catalog.DatasetCatalog.get +""" +) + + +class Metadata(types.SimpleNamespace): + """ + A class that supports simple attribute setter/getter. + It is intended for storing metadata of a dataset and make it accessible globally. + + Examples: + :: + # somewhere when you load the data: + MetadataCatalog.get("mydataset").thing_classes = ["person", "dog"] + + # somewhere when you print statistics or visualize: + classes = MetadataCatalog.get("mydataset").thing_classes + """ + + # the name of the dataset + # set default to N/A so that `self.name` in the errors will not trigger getattr again + name: str = "N/A" + + _RENAMED = { + "class_names": "thing_classes", + "dataset_id_to_contiguous_id": "thing_dataset_id_to_contiguous_id", + "stuff_class_names": "stuff_classes", + } + + def __getattr__(self, key): + if key in self._RENAMED: + log_first_n( + logging.WARNING, + "Metadata '{}' was renamed to '{}'!".format(key, self._RENAMED[key]), + n=10, + ) + return getattr(self, self._RENAMED[key]) + + # "name" exists in every metadata + if len(self.__dict__) > 1: + raise AttributeError( + "Attribute '{}' does not exist in the metadata of dataset '{}'. Available " + "keys are {}.".format(key, self.name, str(self.__dict__.keys())) + ) + else: + raise AttributeError( + f"Attribute '{key}' does not exist in the metadata of dataset '{self.name}': " + "metadata is empty." + ) + + def __setattr__(self, key, val): + if key in self._RENAMED: + log_first_n( + logging.WARNING, + "Metadata '{}' was renamed to '{}'!".format(key, self._RENAMED[key]), + n=10, + ) + setattr(self, self._RENAMED[key], val) + + # Ensure that metadata of the same name stays consistent + try: + oldval = getattr(self, key) + assert oldval == val, ( + "Attribute '{}' in the metadata of '{}' cannot be set " + "to a different value!\n{} != {}".format(key, self.name, oldval, val) + ) + except AttributeError: + super().__setattr__(key, val) + + def as_dict(self): + """ + Returns all the metadata as a dict. + Note that modifications to the returned dict will not reflect on the Metadata object. + """ + return copy.copy(self.__dict__) + + def set(self, **kwargs): + """ + Set multiple metadata with kwargs. + """ + for k, v in kwargs.items(): + setattr(self, k, v) + return self + + def get(self, key, default=None): + """ + Access an attribute and return its value if exists. + Otherwise return default. + """ + try: + return getattr(self, key) + except AttributeError: + return default + + +class _MetadataCatalog(UserDict): + """ + MetadataCatalog is a global dictionary that provides access to + :class:`Metadata` of a given dataset. + + The metadata associated with a certain name is a singleton: once created, the + metadata will stay alive and will be returned by future calls to ``get(name)``. + + It's like global variables, so don't abuse it. + It's meant for storing knowledge that's constant and shared across the execution + of the program, e.g.: the class names in COCO. + """ + + def get(self, name): + """ + Args: + name (str): name of a dataset (e.g. coco_2014_train). + + Returns: + Metadata: The :class:`Metadata` instance associated with this name, + or create an empty one if none is available. + """ + assert len(name) + r = super().get(name, None) + if r is None: + r = self[name] = Metadata(name=name) + return r + + def list(self): + """ + List all registered metadata. + + Returns: + list[str]: keys (names of datasets) of all registered metadata + """ + return list(self.keys()) + + def remove(self, name): + """ + Alias of ``pop``. + """ + self.pop(name) + + def __str__(self): + return "MetadataCatalog(registered metadata: {})".format(", ".join(self.keys())) + + __repr__ = __str__ + + +MetadataCatalog = _MetadataCatalog() +MetadataCatalog.__doc__ = ( + _MetadataCatalog.__doc__ + + """ + .. automethod:: detectron2.data.catalog.MetadataCatalog.get +""" +) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/common.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/common.py new file mode 100644 index 00000000..aa69a6a6 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/common.py @@ -0,0 +1,301 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import contextlib +import copy +import itertools +import logging +import numpy as np +import pickle +import random +from typing import Callable, Union +import torch +import torch.utils.data as data +from torch.utils.data.sampler import Sampler + +from annotator.oneformer.detectron2.utils.serialize import PicklableWrapper + +__all__ = ["MapDataset", "DatasetFromList", "AspectRatioGroupedDataset", "ToIterableDataset"] + +logger = logging.getLogger(__name__) + + +def _shard_iterator_dataloader_worker(iterable): + # Shard the iterable if we're currently inside pytorch dataloader worker. + worker_info = data.get_worker_info() + if worker_info is None or worker_info.num_workers == 1: + # do nothing + yield from iterable + else: + yield from itertools.islice(iterable, worker_info.id, None, worker_info.num_workers) + + +class _MapIterableDataset(data.IterableDataset): + """ + Map a function over elements in an IterableDataset. + + Similar to pytorch's MapIterDataPipe, but support filtering when map_func + returns None. + + This class is not public-facing. Will be called by `MapDataset`. + """ + + def __init__(self, dataset, map_func): + self._dataset = dataset + self._map_func = PicklableWrapper(map_func) # wrap so that a lambda will work + + def __len__(self): + return len(self._dataset) + + def __iter__(self): + for x in map(self._map_func, self._dataset): + if x is not None: + yield x + + +class MapDataset(data.Dataset): + """ + Map a function over the elements in a dataset. + """ + + def __init__(self, dataset, map_func): + """ + Args: + dataset: a dataset where map function is applied. Can be either + map-style or iterable dataset. When given an iterable dataset, + the returned object will also be an iterable dataset. + map_func: a callable which maps the element in dataset. map_func can + return None to skip the data (e.g. in case of errors). + How None is handled depends on the style of `dataset`. + If `dataset` is map-style, it randomly tries other elements. + If `dataset` is iterable, it skips the data and tries the next. + """ + self._dataset = dataset + self._map_func = PicklableWrapper(map_func) # wrap so that a lambda will work + + self._rng = random.Random(42) + self._fallback_candidates = set(range(len(dataset))) + + def __new__(cls, dataset, map_func): + is_iterable = isinstance(dataset, data.IterableDataset) + if is_iterable: + return _MapIterableDataset(dataset, map_func) + else: + return super().__new__(cls) + + def __getnewargs__(self): + return self._dataset, self._map_func + + def __len__(self): + return len(self._dataset) + + def __getitem__(self, idx): + retry_count = 0 + cur_idx = int(idx) + + while True: + data = self._map_func(self._dataset[cur_idx]) + if data is not None: + self._fallback_candidates.add(cur_idx) + return data + + # _map_func fails for this idx, use a random new index from the pool + retry_count += 1 + self._fallback_candidates.discard(cur_idx) + cur_idx = self._rng.sample(self._fallback_candidates, k=1)[0] + + if retry_count >= 3: + logger = logging.getLogger(__name__) + logger.warning( + "Failed to apply `_map_func` for idx: {}, retry count: {}".format( + idx, retry_count + ) + ) + + +class _TorchSerializedList(object): + """ + A list-like object whose items are serialized and stored in a torch tensor. When + launching a process that uses TorchSerializedList with "fork" start method, + the subprocess can read the same buffer without triggering copy-on-access. When + launching a process that uses TorchSerializedList with "spawn/forkserver" start + method, the list will be pickled by a special ForkingPickler registered by PyTorch + that moves data to shared memory. In both cases, this allows parent and child + processes to share RAM for the list data, hence avoids the issue in + https://github.com/pytorch/pytorch/issues/13246. + + See also https://ppwwyyxx.com/blog/2022/Demystify-RAM-Usage-in-Multiprocess-DataLoader/ + on how it works. + """ + + def __init__(self, lst: list): + self._lst = lst + + def _serialize(data): + buffer = pickle.dumps(data, protocol=-1) + return np.frombuffer(buffer, dtype=np.uint8) + + logger.info( + "Serializing {} elements to byte tensors and concatenating them all ...".format( + len(self._lst) + ) + ) + self._lst = [_serialize(x) for x in self._lst] + self._addr = np.asarray([len(x) for x in self._lst], dtype=np.int64) + self._addr = torch.from_numpy(np.cumsum(self._addr)) + self._lst = torch.from_numpy(np.concatenate(self._lst)) + logger.info("Serialized dataset takes {:.2f} MiB".format(len(self._lst) / 1024**2)) + + def __len__(self): + return len(self._addr) + + def __getitem__(self, idx): + start_addr = 0 if idx == 0 else self._addr[idx - 1].item() + end_addr = self._addr[idx].item() + bytes = memoryview(self._lst[start_addr:end_addr].numpy()) + + # @lint-ignore PYTHONPICKLEISBAD + return pickle.loads(bytes) + + +_DEFAULT_DATASET_FROM_LIST_SERIALIZE_METHOD = _TorchSerializedList + + +@contextlib.contextmanager +def set_default_dataset_from_list_serialize_method(new): + """ + Context manager for using custom serialize function when creating DatasetFromList + """ + + global _DEFAULT_DATASET_FROM_LIST_SERIALIZE_METHOD + orig = _DEFAULT_DATASET_FROM_LIST_SERIALIZE_METHOD + _DEFAULT_DATASET_FROM_LIST_SERIALIZE_METHOD = new + yield + _DEFAULT_DATASET_FROM_LIST_SERIALIZE_METHOD = orig + + +class DatasetFromList(data.Dataset): + """ + Wrap a list to a torch Dataset. It produces elements of the list as data. + """ + + def __init__( + self, + lst: list, + copy: bool = True, + serialize: Union[bool, Callable] = True, + ): + """ + Args: + lst (list): a list which contains elements to produce. + copy (bool): whether to deepcopy the element when producing it, + so that the result can be modified in place without affecting the + source in the list. + serialize (bool or callable): whether to serialize the stroage to other + backend. If `True`, the default serialize method will be used, if given + a callable, the callable will be used as serialize method. + """ + self._lst = lst + self._copy = copy + if not isinstance(serialize, (bool, Callable)): + raise TypeError(f"Unsupported type for argument `serailzie`: {serialize}") + self._serialize = serialize is not False + + if self._serialize: + serialize_method = ( + serialize + if isinstance(serialize, Callable) + else _DEFAULT_DATASET_FROM_LIST_SERIALIZE_METHOD + ) + logger.info(f"Serializing the dataset using: {serialize_method}") + self._lst = serialize_method(self._lst) + + def __len__(self): + return len(self._lst) + + def __getitem__(self, idx): + if self._copy and not self._serialize: + return copy.deepcopy(self._lst[idx]) + else: + return self._lst[idx] + + +class ToIterableDataset(data.IterableDataset): + """ + Convert an old indices-based (also called map-style) dataset + to an iterable-style dataset. + """ + + def __init__(self, dataset: data.Dataset, sampler: Sampler, shard_sampler: bool = True): + """ + Args: + dataset: an old-style dataset with ``__getitem__`` + sampler: a cheap iterable that produces indices to be applied on ``dataset``. + shard_sampler: whether to shard the sampler based on the current pytorch data loader + worker id. When an IterableDataset is forked by pytorch's DataLoader into multiple + workers, it is responsible for sharding its data based on worker id so that workers + don't produce identical data. + + Most samplers (like our TrainingSampler) do not shard based on dataloader worker id + and this argument should be set to True. But certain samplers may be already + sharded, in that case this argument should be set to False. + """ + assert not isinstance(dataset, data.IterableDataset), dataset + assert isinstance(sampler, Sampler), sampler + self.dataset = dataset + self.sampler = sampler + self.shard_sampler = shard_sampler + + def __iter__(self): + if not self.shard_sampler: + sampler = self.sampler + else: + # With map-style dataset, `DataLoader(dataset, sampler)` runs the + # sampler in main process only. But `DataLoader(ToIterableDataset(dataset, sampler))` + # will run sampler in every of the N worker. So we should only keep 1/N of the ids on + # each worker. The assumption is that sampler is cheap to iterate so it's fine to + # discard ids in workers. + sampler = _shard_iterator_dataloader_worker(self.sampler) + for idx in sampler: + yield self.dataset[idx] + + def __len__(self): + return len(self.sampler) + + +class AspectRatioGroupedDataset(data.IterableDataset): + """ + Batch data that have similar aspect ratio together. + In this implementation, images whose aspect ratio < (or >) 1 will + be batched together. + This improves training speed because the images then need less padding + to form a batch. + + It assumes the underlying dataset produces dicts with "width" and "height" keys. + It will then produce a list of original dicts with length = batch_size, + all with similar aspect ratios. + """ + + def __init__(self, dataset, batch_size): + """ + Args: + dataset: an iterable. Each element must be a dict with keys + "width" and "height", which will be used to batch data. + batch_size (int): + """ + self.dataset = dataset + self.batch_size = batch_size + self._buckets = [[] for _ in range(2)] + # Hard-coded two aspect ratio groups: w > h and w < h. + # Can add support for more aspect ratio groups, but doesn't seem useful + + def __iter__(self): + for d in self.dataset: + w, h = d["width"], d["height"] + bucket_id = 0 if w > h else 1 + bucket = self._buckets[bucket_id] + bucket.append(d) + if len(bucket) == self.batch_size: + data = bucket[:] + # Clear bucket first, because code after yield is not + # guaranteed to execute + del bucket[:] + yield data diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/dataset_mapper.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/dataset_mapper.py new file mode 100644 index 00000000..3bb6bb10 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/dataset_mapper.py @@ -0,0 +1,191 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import copy +import logging +import numpy as np +from typing import List, Optional, Union +import torch + +from annotator.oneformer.detectron2.config import configurable + +from . import detection_utils as utils +from . import transforms as T + +""" +This file contains the default mapping that's applied to "dataset dicts". +""" + +__all__ = ["DatasetMapper"] + + +class DatasetMapper: + """ + A callable which takes a dataset dict in Detectron2 Dataset format, + and map it into a format used by the model. + + This is the default callable to be used to map your dataset dict into training data. + You may need to follow it to implement your own one for customized logic, + such as a different way to read or transform images. + See :doc:`/tutorials/data_loading` for details. + + The callable currently does the following: + + 1. Read the image from "file_name" + 2. Applies cropping/geometric transforms to the image and annotations + 3. Prepare data and annotations to Tensor and :class:`Instances` + """ + + @configurable + def __init__( + self, + is_train: bool, + *, + augmentations: List[Union[T.Augmentation, T.Transform]], + image_format: str, + use_instance_mask: bool = False, + use_keypoint: bool = False, + instance_mask_format: str = "polygon", + keypoint_hflip_indices: Optional[np.ndarray] = None, + precomputed_proposal_topk: Optional[int] = None, + recompute_boxes: bool = False, + ): + """ + NOTE: this interface is experimental. + + Args: + is_train: whether it's used in training or inference + augmentations: a list of augmentations or deterministic transforms to apply + image_format: an image format supported by :func:`detection_utils.read_image`. + use_instance_mask: whether to process instance segmentation annotations, if available + use_keypoint: whether to process keypoint annotations if available + instance_mask_format: one of "polygon" or "bitmask". Process instance segmentation + masks into this format. + keypoint_hflip_indices: see :func:`detection_utils.create_keypoint_hflip_indices` + precomputed_proposal_topk: if given, will load pre-computed + proposals from dataset_dict and keep the top k proposals for each image. + recompute_boxes: whether to overwrite bounding box annotations + by computing tight bounding boxes from instance mask annotations. + """ + if recompute_boxes: + assert use_instance_mask, "recompute_boxes requires instance masks" + # fmt: off + self.is_train = is_train + self.augmentations = T.AugmentationList(augmentations) + self.image_format = image_format + self.use_instance_mask = use_instance_mask + self.instance_mask_format = instance_mask_format + self.use_keypoint = use_keypoint + self.keypoint_hflip_indices = keypoint_hflip_indices + self.proposal_topk = precomputed_proposal_topk + self.recompute_boxes = recompute_boxes + # fmt: on + logger = logging.getLogger(__name__) + mode = "training" if is_train else "inference" + logger.info(f"[DatasetMapper] Augmentations used in {mode}: {augmentations}") + + @classmethod + def from_config(cls, cfg, is_train: bool = True): + augs = utils.build_augmentation(cfg, is_train) + if cfg.INPUT.CROP.ENABLED and is_train: + augs.insert(0, T.RandomCrop(cfg.INPUT.CROP.TYPE, cfg.INPUT.CROP.SIZE)) + recompute_boxes = cfg.MODEL.MASK_ON + else: + recompute_boxes = False + + ret = { + "is_train": is_train, + "augmentations": augs, + "image_format": cfg.INPUT.FORMAT, + "use_instance_mask": cfg.MODEL.MASK_ON, + "instance_mask_format": cfg.INPUT.MASK_FORMAT, + "use_keypoint": cfg.MODEL.KEYPOINT_ON, + "recompute_boxes": recompute_boxes, + } + + if cfg.MODEL.KEYPOINT_ON: + ret["keypoint_hflip_indices"] = utils.create_keypoint_hflip_indices(cfg.DATASETS.TRAIN) + + if cfg.MODEL.LOAD_PROPOSALS: + ret["precomputed_proposal_topk"] = ( + cfg.DATASETS.PRECOMPUTED_PROPOSAL_TOPK_TRAIN + if is_train + else cfg.DATASETS.PRECOMPUTED_PROPOSAL_TOPK_TEST + ) + return ret + + def _transform_annotations(self, dataset_dict, transforms, image_shape): + # USER: Modify this if you want to keep them for some reason. + for anno in dataset_dict["annotations"]: + if not self.use_instance_mask: + anno.pop("segmentation", None) + if not self.use_keypoint: + anno.pop("keypoints", None) + + # USER: Implement additional transformations if you have other types of data + annos = [ + utils.transform_instance_annotations( + obj, transforms, image_shape, keypoint_hflip_indices=self.keypoint_hflip_indices + ) + for obj in dataset_dict.pop("annotations") + if obj.get("iscrowd", 0) == 0 + ] + instances = utils.annotations_to_instances( + annos, image_shape, mask_format=self.instance_mask_format + ) + + # After transforms such as cropping are applied, the bounding box may no longer + # tightly bound the object. As an example, imagine a triangle object + # [(0,0), (2,0), (0,2)] cropped by a box [(1,0),(2,2)] (XYXY format). The tight + # bounding box of the cropped triangle should be [(1,0),(2,1)], which is not equal to + # the intersection of original bounding box and the cropping box. + if self.recompute_boxes: + instances.gt_boxes = instances.gt_masks.get_bounding_boxes() + dataset_dict["instances"] = utils.filter_empty_instances(instances) + + def __call__(self, dataset_dict): + """ + Args: + dataset_dict (dict): Metadata of one image, in Detectron2 Dataset format. + + Returns: + dict: a format that builtin models in detectron2 accept + """ + dataset_dict = copy.deepcopy(dataset_dict) # it will be modified by code below + # USER: Write your own image loading if it's not from a file + image = utils.read_image(dataset_dict["file_name"], format=self.image_format) + utils.check_image_size(dataset_dict, image) + + # USER: Remove if you don't do semantic/panoptic segmentation. + if "sem_seg_file_name" in dataset_dict: + sem_seg_gt = utils.read_image(dataset_dict.pop("sem_seg_file_name"), "L").squeeze(2) + else: + sem_seg_gt = None + + aug_input = T.AugInput(image, sem_seg=sem_seg_gt) + transforms = self.augmentations(aug_input) + image, sem_seg_gt = aug_input.image, aug_input.sem_seg + + image_shape = image.shape[:2] # h, w + # Pytorch's dataloader is efficient on torch.Tensor due to shared-memory, + # but not efficient on large generic data structures due to the use of pickle & mp.Queue. + # Therefore it's important to use torch.Tensor. + dataset_dict["image"] = torch.as_tensor(np.ascontiguousarray(image.transpose(2, 0, 1))) + if sem_seg_gt is not None: + dataset_dict["sem_seg"] = torch.as_tensor(sem_seg_gt.astype("long")) + + # USER: Remove if you don't use pre-computed proposals. + # Most users would not need this feature. + if self.proposal_topk is not None: + utils.transform_proposals( + dataset_dict, image_shape, transforms, proposal_topk=self.proposal_topk + ) + + if not self.is_train: + # USER: Modify this if you want to keep them for some reason. + dataset_dict.pop("annotations", None) + dataset_dict.pop("sem_seg_file_name", None) + return dataset_dict + + if "annotations" in dataset_dict: + self._transform_annotations(dataset_dict, transforms, image_shape) + + return dataset_dict diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/README.md b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/README.md new file mode 100644 index 00000000..9fb3e4f7 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/README.md @@ -0,0 +1,9 @@ + + +### Common Datasets + +The dataset implemented here do not need to load the data into the final format. +It should provide the minimal data structure needed to use the dataset, so it can be very efficient. + +For example, for an image dataset, just provide the file names and labels, but don't read the images. +Let the downstream decide how to read. diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/__init__.py new file mode 100644 index 00000000..a44bedc1 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/__init__.py @@ -0,0 +1,9 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from .coco import load_coco_json, load_sem_seg, register_coco_instances, convert_to_coco_json +from .coco_panoptic import register_coco_panoptic, register_coco_panoptic_separated +from .lvis import load_lvis_json, register_lvis_instances, get_lvis_instances_meta +from .pascal_voc import load_voc_instances, register_pascal_voc +from . import builtin as _builtin # ensure the builtin datasets are registered + + +__all__ = [k for k in globals().keys() if not k.startswith("_")] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/builtin.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/builtin.py new file mode 100644 index 00000000..39bbb1fe --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/builtin.py @@ -0,0 +1,259 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + + +""" +This file registers pre-defined datasets at hard-coded paths, and their metadata. + +We hard-code metadata for common datasets. This will enable: +1. Consistency check when loading the datasets +2. Use models on these standard datasets directly and run demos, + without having to download the dataset annotations + +We hard-code some paths to the dataset that's assumed to +exist in "./datasets/". + +Users SHOULD NOT use this file to create new dataset / metadata for new dataset. +To add new dataset, refer to the tutorial "docs/DATASETS.md". +""" + +import os + +from annotator.oneformer.detectron2.data import DatasetCatalog, MetadataCatalog + +from .builtin_meta import ADE20K_SEM_SEG_CATEGORIES, _get_builtin_metadata +from .cityscapes import load_cityscapes_instances, load_cityscapes_semantic +from .cityscapes_panoptic import register_all_cityscapes_panoptic +from .coco import load_sem_seg, register_coco_instances +from .coco_panoptic import register_coco_panoptic, register_coco_panoptic_separated +from .lvis import get_lvis_instances_meta, register_lvis_instances +from .pascal_voc import register_pascal_voc + +# ==== Predefined datasets and splits for COCO ========== + +_PREDEFINED_SPLITS_COCO = {} +_PREDEFINED_SPLITS_COCO["coco"] = { + "coco_2014_train": ("coco/train2014", "coco/annotations/instances_train2014.json"), + "coco_2014_val": ("coco/val2014", "coco/annotations/instances_val2014.json"), + "coco_2014_minival": ("coco/val2014", "coco/annotations/instances_minival2014.json"), + "coco_2014_valminusminival": ( + "coco/val2014", + "coco/annotations/instances_valminusminival2014.json", + ), + "coco_2017_train": ("coco/train2017", "coco/annotations/instances_train2017.json"), + "coco_2017_val": ("coco/val2017", "coco/annotations/instances_val2017.json"), + "coco_2017_test": ("coco/test2017", "coco/annotations/image_info_test2017.json"), + "coco_2017_test-dev": ("coco/test2017", "coco/annotations/image_info_test-dev2017.json"), + "coco_2017_val_100": ("coco/val2017", "coco/annotations/instances_val2017_100.json"), +} + +_PREDEFINED_SPLITS_COCO["coco_person"] = { + "keypoints_coco_2014_train": ( + "coco/train2014", + "coco/annotations/person_keypoints_train2014.json", + ), + "keypoints_coco_2014_val": ("coco/val2014", "coco/annotations/person_keypoints_val2014.json"), + "keypoints_coco_2014_minival": ( + "coco/val2014", + "coco/annotations/person_keypoints_minival2014.json", + ), + "keypoints_coco_2014_valminusminival": ( + "coco/val2014", + "coco/annotations/person_keypoints_valminusminival2014.json", + ), + "keypoints_coco_2017_train": ( + "coco/train2017", + "coco/annotations/person_keypoints_train2017.json", + ), + "keypoints_coco_2017_val": ("coco/val2017", "coco/annotations/person_keypoints_val2017.json"), + "keypoints_coco_2017_val_100": ( + "coco/val2017", + "coco/annotations/person_keypoints_val2017_100.json", + ), +} + + +_PREDEFINED_SPLITS_COCO_PANOPTIC = { + "coco_2017_train_panoptic": ( + # This is the original panoptic annotation directory + "coco/panoptic_train2017", + "coco/annotations/panoptic_train2017.json", + # This directory contains semantic annotations that are + # converted from panoptic annotations. + # It is used by PanopticFPN. + # You can use the script at detectron2/datasets/prepare_panoptic_fpn.py + # to create these directories. + "coco/panoptic_stuff_train2017", + ), + "coco_2017_val_panoptic": ( + "coco/panoptic_val2017", + "coco/annotations/panoptic_val2017.json", + "coco/panoptic_stuff_val2017", + ), + "coco_2017_val_100_panoptic": ( + "coco/panoptic_val2017_100", + "coco/annotations/panoptic_val2017_100.json", + "coco/panoptic_stuff_val2017_100", + ), +} + + +def register_all_coco(root): + for dataset_name, splits_per_dataset in _PREDEFINED_SPLITS_COCO.items(): + for key, (image_root, json_file) in splits_per_dataset.items(): + # Assume pre-defined datasets live in `./datasets`. + register_coco_instances( + key, + _get_builtin_metadata(dataset_name), + os.path.join(root, json_file) if "://" not in json_file else json_file, + os.path.join(root, image_root), + ) + + for ( + prefix, + (panoptic_root, panoptic_json, semantic_root), + ) in _PREDEFINED_SPLITS_COCO_PANOPTIC.items(): + prefix_instances = prefix[: -len("_panoptic")] + instances_meta = MetadataCatalog.get(prefix_instances) + image_root, instances_json = instances_meta.image_root, instances_meta.json_file + # The "separated" version of COCO panoptic segmentation dataset, + # e.g. used by Panoptic FPN + register_coco_panoptic_separated( + prefix, + _get_builtin_metadata("coco_panoptic_separated"), + image_root, + os.path.join(root, panoptic_root), + os.path.join(root, panoptic_json), + os.path.join(root, semantic_root), + instances_json, + ) + # The "standard" version of COCO panoptic segmentation dataset, + # e.g. used by Panoptic-DeepLab + register_coco_panoptic( + prefix, + _get_builtin_metadata("coco_panoptic_standard"), + image_root, + os.path.join(root, panoptic_root), + os.path.join(root, panoptic_json), + instances_json, + ) + + +# ==== Predefined datasets and splits for LVIS ========== + + +_PREDEFINED_SPLITS_LVIS = { + "lvis_v1": { + "lvis_v1_train": ("coco/", "lvis/lvis_v1_train.json"), + "lvis_v1_val": ("coco/", "lvis/lvis_v1_val.json"), + "lvis_v1_test_dev": ("coco/", "lvis/lvis_v1_image_info_test_dev.json"), + "lvis_v1_test_challenge": ("coco/", "lvis/lvis_v1_image_info_test_challenge.json"), + }, + "lvis_v0.5": { + "lvis_v0.5_train": ("coco/", "lvis/lvis_v0.5_train.json"), + "lvis_v0.5_val": ("coco/", "lvis/lvis_v0.5_val.json"), + "lvis_v0.5_val_rand_100": ("coco/", "lvis/lvis_v0.5_val_rand_100.json"), + "lvis_v0.5_test": ("coco/", "lvis/lvis_v0.5_image_info_test.json"), + }, + "lvis_v0.5_cocofied": { + "lvis_v0.5_train_cocofied": ("coco/", "lvis/lvis_v0.5_train_cocofied.json"), + "lvis_v0.5_val_cocofied": ("coco/", "lvis/lvis_v0.5_val_cocofied.json"), + }, +} + + +def register_all_lvis(root): + for dataset_name, splits_per_dataset in _PREDEFINED_SPLITS_LVIS.items(): + for key, (image_root, json_file) in splits_per_dataset.items(): + register_lvis_instances( + key, + get_lvis_instances_meta(dataset_name), + os.path.join(root, json_file) if "://" not in json_file else json_file, + os.path.join(root, image_root), + ) + + +# ==== Predefined splits for raw cityscapes images =========== +_RAW_CITYSCAPES_SPLITS = { + "cityscapes_fine_{task}_train": ("cityscapes/leftImg8bit/train/", "cityscapes/gtFine/train/"), + "cityscapes_fine_{task}_val": ("cityscapes/leftImg8bit/val/", "cityscapes/gtFine/val/"), + "cityscapes_fine_{task}_test": ("cityscapes/leftImg8bit/test/", "cityscapes/gtFine/test/"), +} + + +def register_all_cityscapes(root): + for key, (image_dir, gt_dir) in _RAW_CITYSCAPES_SPLITS.items(): + meta = _get_builtin_metadata("cityscapes") + image_dir = os.path.join(root, image_dir) + gt_dir = os.path.join(root, gt_dir) + + inst_key = key.format(task="instance_seg") + DatasetCatalog.register( + inst_key, + lambda x=image_dir, y=gt_dir: load_cityscapes_instances( + x, y, from_json=True, to_polygons=True + ), + ) + MetadataCatalog.get(inst_key).set( + image_dir=image_dir, gt_dir=gt_dir, evaluator_type="cityscapes_instance", **meta + ) + + sem_key = key.format(task="sem_seg") + DatasetCatalog.register( + sem_key, lambda x=image_dir, y=gt_dir: load_cityscapes_semantic(x, y) + ) + MetadataCatalog.get(sem_key).set( + image_dir=image_dir, + gt_dir=gt_dir, + evaluator_type="cityscapes_sem_seg", + ignore_label=255, + **meta, + ) + + +# ==== Predefined splits for PASCAL VOC =========== +def register_all_pascal_voc(root): + SPLITS = [ + ("voc_2007_trainval", "VOC2007", "trainval"), + ("voc_2007_train", "VOC2007", "train"), + ("voc_2007_val", "VOC2007", "val"), + ("voc_2007_test", "VOC2007", "test"), + ("voc_2012_trainval", "VOC2012", "trainval"), + ("voc_2012_train", "VOC2012", "train"), + ("voc_2012_val", "VOC2012", "val"), + ] + for name, dirname, split in SPLITS: + year = 2007 if "2007" in name else 2012 + register_pascal_voc(name, os.path.join(root, dirname), split, year) + MetadataCatalog.get(name).evaluator_type = "pascal_voc" + + +def register_all_ade20k(root): + root = os.path.join(root, "ADEChallengeData2016") + for name, dirname in [("train", "training"), ("val", "validation")]: + image_dir = os.path.join(root, "images", dirname) + gt_dir = os.path.join(root, "annotations_detectron2", dirname) + name = f"ade20k_sem_seg_{name}" + DatasetCatalog.register( + name, lambda x=image_dir, y=gt_dir: load_sem_seg(y, x, gt_ext="png", image_ext="jpg") + ) + MetadataCatalog.get(name).set( + stuff_classes=ADE20K_SEM_SEG_CATEGORIES[:], + image_root=image_dir, + sem_seg_root=gt_dir, + evaluator_type="sem_seg", + ignore_label=255, + ) + + +# True for open source; +# Internally at fb, we register them elsewhere +if __name__.endswith(".builtin"): + # Assume pre-defined datasets live in `./datasets`. + _root = os.path.expanduser(os.getenv("DETECTRON2_DATASETS", "datasets")) + register_all_coco(_root) + register_all_lvis(_root) + register_all_cityscapes(_root) + register_all_cityscapes_panoptic(_root) + register_all_pascal_voc(_root) + register_all_ade20k(_root) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/builtin_meta.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/builtin_meta.py new file mode 100644 index 00000000..63c7a1a3 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/builtin_meta.py @@ -0,0 +1,350 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +""" +Note: +For your custom dataset, there is no need to hard-code metadata anywhere in the code. +For example, for COCO-format dataset, metadata will be obtained automatically +when calling `load_coco_json`. For other dataset, metadata may also be obtained in other ways +during loading. + +However, we hard-coded metadata for a few common dataset here. +The only goal is to allow users who don't have these dataset to use pre-trained models. +Users don't have to download a COCO json (which contains metadata), in order to visualize a +COCO model (with correct class names and colors). +""" + + +# All coco categories, together with their nice-looking visualization colors +# It's from https://github.com/cocodataset/panopticapi/blob/master/panoptic_coco_categories.json +COCO_CATEGORIES = [ + {"color": [220, 20, 60], "isthing": 1, "id": 1, "name": "person"}, + {"color": [119, 11, 32], "isthing": 1, "id": 2, "name": "bicycle"}, + {"color": [0, 0, 142], "isthing": 1, "id": 3, "name": "car"}, + {"color": [0, 0, 230], "isthing": 1, "id": 4, "name": "motorcycle"}, + {"color": [106, 0, 228], "isthing": 1, "id": 5, "name": "airplane"}, + {"color": [0, 60, 100], "isthing": 1, "id": 6, "name": "bus"}, + {"color": [0, 80, 100], "isthing": 1, "id": 7, "name": "train"}, + {"color": [0, 0, 70], "isthing": 1, "id": 8, "name": "truck"}, + {"color": [0, 0, 192], "isthing": 1, "id": 9, "name": "boat"}, + {"color": [250, 170, 30], "isthing": 1, "id": 10, "name": "traffic light"}, + {"color": [100, 170, 30], "isthing": 1, "id": 11, "name": "fire hydrant"}, + {"color": [220, 220, 0], "isthing": 1, "id": 13, "name": "stop sign"}, + {"color": [175, 116, 175], "isthing": 1, "id": 14, "name": "parking meter"}, + {"color": [250, 0, 30], "isthing": 1, "id": 15, "name": "bench"}, + {"color": [165, 42, 42], "isthing": 1, "id": 16, "name": "bird"}, + {"color": [255, 77, 255], "isthing": 1, "id": 17, "name": "cat"}, + {"color": [0, 226, 252], "isthing": 1, "id": 18, "name": "dog"}, + {"color": [182, 182, 255], "isthing": 1, "id": 19, "name": "horse"}, + {"color": [0, 82, 0], "isthing": 1, "id": 20, "name": "sheep"}, + {"color": [120, 166, 157], "isthing": 1, "id": 21, "name": "cow"}, + {"color": [110, 76, 0], "isthing": 1, "id": 22, "name": "elephant"}, + {"color": [174, 57, 255], "isthing": 1, "id": 23, "name": "bear"}, + {"color": [199, 100, 0], "isthing": 1, "id": 24, "name": "zebra"}, + {"color": [72, 0, 118], "isthing": 1, "id": 25, "name": "giraffe"}, + {"color": [255, 179, 240], "isthing": 1, "id": 27, "name": "backpack"}, + {"color": [0, 125, 92], "isthing": 1, "id": 28, "name": "umbrella"}, + {"color": [209, 0, 151], "isthing": 1, "id": 31, "name": "handbag"}, + {"color": [188, 208, 182], "isthing": 1, "id": 32, "name": "tie"}, + {"color": [0, 220, 176], "isthing": 1, "id": 33, "name": "suitcase"}, + {"color": [255, 99, 164], "isthing": 1, "id": 34, "name": "frisbee"}, + {"color": [92, 0, 73], "isthing": 1, "id": 35, "name": "skis"}, + {"color": [133, 129, 255], "isthing": 1, "id": 36, "name": "snowboard"}, + {"color": [78, 180, 255], "isthing": 1, "id": 37, "name": "sports ball"}, + {"color": [0, 228, 0], "isthing": 1, "id": 38, "name": "kite"}, + {"color": [174, 255, 243], "isthing": 1, "id": 39, "name": "baseball bat"}, + {"color": [45, 89, 255], "isthing": 1, "id": 40, "name": "baseball glove"}, + {"color": [134, 134, 103], "isthing": 1, "id": 41, "name": "skateboard"}, + {"color": [145, 148, 174], "isthing": 1, "id": 42, "name": "surfboard"}, + {"color": [255, 208, 186], "isthing": 1, "id": 43, "name": "tennis racket"}, + {"color": [197, 226, 255], "isthing": 1, "id": 44, "name": "bottle"}, + {"color": [171, 134, 1], "isthing": 1, "id": 46, "name": "wine glass"}, + {"color": [109, 63, 54], "isthing": 1, "id": 47, "name": "cup"}, + {"color": [207, 138, 255], "isthing": 1, "id": 48, "name": "fork"}, + {"color": [151, 0, 95], "isthing": 1, "id": 49, "name": "knife"}, + {"color": [9, 80, 61], "isthing": 1, "id": 50, "name": "spoon"}, + {"color": [84, 105, 51], "isthing": 1, "id": 51, "name": "bowl"}, + {"color": [74, 65, 105], "isthing": 1, "id": 52, "name": "banana"}, + {"color": [166, 196, 102], "isthing": 1, "id": 53, "name": "apple"}, + {"color": [208, 195, 210], "isthing": 1, "id": 54, "name": "sandwich"}, + {"color": [255, 109, 65], "isthing": 1, "id": 55, "name": "orange"}, + {"color": [0, 143, 149], "isthing": 1, "id": 56, "name": "broccoli"}, + {"color": [179, 0, 194], "isthing": 1, "id": 57, "name": "carrot"}, + {"color": [209, 99, 106], "isthing": 1, "id": 58, "name": "hot dog"}, + {"color": [5, 121, 0], "isthing": 1, "id": 59, "name": "pizza"}, + {"color": [227, 255, 205], "isthing": 1, "id": 60, "name": "donut"}, + {"color": [147, 186, 208], "isthing": 1, "id": 61, "name": "cake"}, + {"color": [153, 69, 1], "isthing": 1, "id": 62, "name": "chair"}, + {"color": [3, 95, 161], "isthing": 1, "id": 63, "name": "couch"}, + {"color": [163, 255, 0], "isthing": 1, "id": 64, "name": "potted plant"}, + {"color": [119, 0, 170], "isthing": 1, "id": 65, "name": "bed"}, + {"color": [0, 182, 199], "isthing": 1, "id": 67, "name": "dining table"}, + {"color": [0, 165, 120], "isthing": 1, "id": 70, "name": "toilet"}, + {"color": [183, 130, 88], "isthing": 1, "id": 72, "name": "tv"}, + {"color": [95, 32, 0], "isthing": 1, "id": 73, "name": "laptop"}, + {"color": [130, 114, 135], "isthing": 1, "id": 74, "name": "mouse"}, + {"color": [110, 129, 133], "isthing": 1, "id": 75, "name": "remote"}, + {"color": [166, 74, 118], "isthing": 1, "id": 76, "name": "keyboard"}, + {"color": [219, 142, 185], "isthing": 1, "id": 77, "name": "cell phone"}, + {"color": [79, 210, 114], "isthing": 1, "id": 78, "name": "microwave"}, + {"color": [178, 90, 62], "isthing": 1, "id": 79, "name": "oven"}, + {"color": [65, 70, 15], "isthing": 1, "id": 80, "name": "toaster"}, + {"color": [127, 167, 115], "isthing": 1, "id": 81, "name": "sink"}, + {"color": [59, 105, 106], "isthing": 1, "id": 82, "name": "refrigerator"}, + {"color": [142, 108, 45], "isthing": 1, "id": 84, "name": "book"}, + {"color": [196, 172, 0], "isthing": 1, "id": 85, "name": "clock"}, + {"color": [95, 54, 80], "isthing": 1, "id": 86, "name": "vase"}, + {"color": [128, 76, 255], "isthing": 1, "id": 87, "name": "scissors"}, + {"color": [201, 57, 1], "isthing": 1, "id": 88, "name": "teddy bear"}, + {"color": [246, 0, 122], "isthing": 1, "id": 89, "name": "hair drier"}, + {"color": [191, 162, 208], "isthing": 1, "id": 90, "name": "toothbrush"}, + {"color": [255, 255, 128], "isthing": 0, "id": 92, "name": "banner"}, + {"color": [147, 211, 203], "isthing": 0, "id": 93, "name": "blanket"}, + {"color": [150, 100, 100], "isthing": 0, "id": 95, "name": "bridge"}, + {"color": [168, 171, 172], "isthing": 0, "id": 100, "name": "cardboard"}, + {"color": [146, 112, 198], "isthing": 0, "id": 107, "name": "counter"}, + {"color": [210, 170, 100], "isthing": 0, "id": 109, "name": "curtain"}, + {"color": [92, 136, 89], "isthing": 0, "id": 112, "name": "door-stuff"}, + {"color": [218, 88, 184], "isthing": 0, "id": 118, "name": "floor-wood"}, + {"color": [241, 129, 0], "isthing": 0, "id": 119, "name": "flower"}, + {"color": [217, 17, 255], "isthing": 0, "id": 122, "name": "fruit"}, + {"color": [124, 74, 181], "isthing": 0, "id": 125, "name": "gravel"}, + {"color": [70, 70, 70], "isthing": 0, "id": 128, "name": "house"}, + {"color": [255, 228, 255], "isthing": 0, "id": 130, "name": "light"}, + {"color": [154, 208, 0], "isthing": 0, "id": 133, "name": "mirror-stuff"}, + {"color": [193, 0, 92], "isthing": 0, "id": 138, "name": "net"}, + {"color": [76, 91, 113], "isthing": 0, "id": 141, "name": "pillow"}, + {"color": [255, 180, 195], "isthing": 0, "id": 144, "name": "platform"}, + {"color": [106, 154, 176], "isthing": 0, "id": 145, "name": "playingfield"}, + {"color": [230, 150, 140], "isthing": 0, "id": 147, "name": "railroad"}, + {"color": [60, 143, 255], "isthing": 0, "id": 148, "name": "river"}, + {"color": [128, 64, 128], "isthing": 0, "id": 149, "name": "road"}, + {"color": [92, 82, 55], "isthing": 0, "id": 151, "name": "roof"}, + {"color": [254, 212, 124], "isthing": 0, "id": 154, "name": "sand"}, + {"color": [73, 77, 174], "isthing": 0, "id": 155, "name": "sea"}, + {"color": [255, 160, 98], "isthing": 0, "id": 156, "name": "shelf"}, + {"color": [255, 255, 255], "isthing": 0, "id": 159, "name": "snow"}, + {"color": [104, 84, 109], "isthing": 0, "id": 161, "name": "stairs"}, + {"color": [169, 164, 131], "isthing": 0, "id": 166, "name": "tent"}, + {"color": [225, 199, 255], "isthing": 0, "id": 168, "name": "towel"}, + {"color": [137, 54, 74], "isthing": 0, "id": 171, "name": "wall-brick"}, + {"color": [135, 158, 223], "isthing": 0, "id": 175, "name": "wall-stone"}, + {"color": [7, 246, 231], "isthing": 0, "id": 176, "name": "wall-tile"}, + {"color": [107, 255, 200], "isthing": 0, "id": 177, "name": "wall-wood"}, + {"color": [58, 41, 149], "isthing": 0, "id": 178, "name": "water-other"}, + {"color": [183, 121, 142], "isthing": 0, "id": 180, "name": "window-blind"}, + {"color": [255, 73, 97], "isthing": 0, "id": 181, "name": "window-other"}, + {"color": [107, 142, 35], "isthing": 0, "id": 184, "name": "tree-merged"}, + {"color": [190, 153, 153], "isthing": 0, "id": 185, "name": "fence-merged"}, + {"color": [146, 139, 141], "isthing": 0, "id": 186, "name": "ceiling-merged"}, + {"color": [70, 130, 180], "isthing": 0, "id": 187, "name": "sky-other-merged"}, + {"color": [134, 199, 156], "isthing": 0, "id": 188, "name": "cabinet-merged"}, + {"color": [209, 226, 140], "isthing": 0, "id": 189, "name": "table-merged"}, + {"color": [96, 36, 108], "isthing": 0, "id": 190, "name": "floor-other-merged"}, + {"color": [96, 96, 96], "isthing": 0, "id": 191, "name": "pavement-merged"}, + {"color": [64, 170, 64], "isthing": 0, "id": 192, "name": "mountain-merged"}, + {"color": [152, 251, 152], "isthing": 0, "id": 193, "name": "grass-merged"}, + {"color": [208, 229, 228], "isthing": 0, "id": 194, "name": "dirt-merged"}, + {"color": [206, 186, 171], "isthing": 0, "id": 195, "name": "paper-merged"}, + {"color": [152, 161, 64], "isthing": 0, "id": 196, "name": "food-other-merged"}, + {"color": [116, 112, 0], "isthing": 0, "id": 197, "name": "building-other-merged"}, + {"color": [0, 114, 143], "isthing": 0, "id": 198, "name": "rock-merged"}, + {"color": [102, 102, 156], "isthing": 0, "id": 199, "name": "wall-other-merged"}, + {"color": [250, 141, 255], "isthing": 0, "id": 200, "name": "rug-merged"}, +] + +# fmt: off +COCO_PERSON_KEYPOINT_NAMES = ( + "nose", + "left_eye", "right_eye", + "left_ear", "right_ear", + "left_shoulder", "right_shoulder", + "left_elbow", "right_elbow", + "left_wrist", "right_wrist", + "left_hip", "right_hip", + "left_knee", "right_knee", + "left_ankle", "right_ankle", +) +# fmt: on + +# Pairs of keypoints that should be exchanged under horizontal flipping +COCO_PERSON_KEYPOINT_FLIP_MAP = ( + ("left_eye", "right_eye"), + ("left_ear", "right_ear"), + ("left_shoulder", "right_shoulder"), + ("left_elbow", "right_elbow"), + ("left_wrist", "right_wrist"), + ("left_hip", "right_hip"), + ("left_knee", "right_knee"), + ("left_ankle", "right_ankle"), +) + +# rules for pairs of keypoints to draw a line between, and the line color to use. +KEYPOINT_CONNECTION_RULES = [ + # face + ("left_ear", "left_eye", (102, 204, 255)), + ("right_ear", "right_eye", (51, 153, 255)), + ("left_eye", "nose", (102, 0, 204)), + ("nose", "right_eye", (51, 102, 255)), + # upper-body + ("left_shoulder", "right_shoulder", (255, 128, 0)), + ("left_shoulder", "left_elbow", (153, 255, 204)), + ("right_shoulder", "right_elbow", (128, 229, 255)), + ("left_elbow", "left_wrist", (153, 255, 153)), + ("right_elbow", "right_wrist", (102, 255, 224)), + # lower-body + ("left_hip", "right_hip", (255, 102, 0)), + ("left_hip", "left_knee", (255, 255, 77)), + ("right_hip", "right_knee", (153, 255, 204)), + ("left_knee", "left_ankle", (191, 255, 128)), + ("right_knee", "right_ankle", (255, 195, 77)), +] + +# All Cityscapes categories, together with their nice-looking visualization colors +# It's from https://github.com/mcordts/cityscapesScripts/blob/master/cityscapesscripts/helpers/labels.py # noqa +CITYSCAPES_CATEGORIES = [ + {"color": (128, 64, 128), "isthing": 0, "id": 7, "trainId": 0, "name": "road"}, + {"color": (244, 35, 232), "isthing": 0, "id": 8, "trainId": 1, "name": "sidewalk"}, + {"color": (70, 70, 70), "isthing": 0, "id": 11, "trainId": 2, "name": "building"}, + {"color": (102, 102, 156), "isthing": 0, "id": 12, "trainId": 3, "name": "wall"}, + {"color": (190, 153, 153), "isthing": 0, "id": 13, "trainId": 4, "name": "fence"}, + {"color": (153, 153, 153), "isthing": 0, "id": 17, "trainId": 5, "name": "pole"}, + {"color": (250, 170, 30), "isthing": 0, "id": 19, "trainId": 6, "name": "traffic light"}, + {"color": (220, 220, 0), "isthing": 0, "id": 20, "trainId": 7, "name": "traffic sign"}, + {"color": (107, 142, 35), "isthing": 0, "id": 21, "trainId": 8, "name": "vegetation"}, + {"color": (152, 251, 152), "isthing": 0, "id": 22, "trainId": 9, "name": "terrain"}, + {"color": (70, 130, 180), "isthing": 0, "id": 23, "trainId": 10, "name": "sky"}, + {"color": (220, 20, 60), "isthing": 1, "id": 24, "trainId": 11, "name": "person"}, + {"color": (255, 0, 0), "isthing": 1, "id": 25, "trainId": 12, "name": "rider"}, + {"color": (0, 0, 142), "isthing": 1, "id": 26, "trainId": 13, "name": "car"}, + {"color": (0, 0, 70), "isthing": 1, "id": 27, "trainId": 14, "name": "truck"}, + {"color": (0, 60, 100), "isthing": 1, "id": 28, "trainId": 15, "name": "bus"}, + {"color": (0, 80, 100), "isthing": 1, "id": 31, "trainId": 16, "name": "train"}, + {"color": (0, 0, 230), "isthing": 1, "id": 32, "trainId": 17, "name": "motorcycle"}, + {"color": (119, 11, 32), "isthing": 1, "id": 33, "trainId": 18, "name": "bicycle"}, +] + +# fmt: off +ADE20K_SEM_SEG_CATEGORIES = [ + "wall", "building", "sky", "floor", "tree", "ceiling", "road, route", "bed", "window ", "grass", "cabinet", "sidewalk, pavement", "person", "earth, ground", "door", "table", "mountain, mount", "plant", "curtain", "chair", "car", "water", "painting, picture", "sofa", "shelf", "house", "sea", "mirror", "rug", "field", "armchair", "seat", "fence", "desk", "rock, stone", "wardrobe, closet, press", "lamp", "tub", "rail", "cushion", "base, pedestal, stand", "box", "column, pillar", "signboard, sign", "chest of drawers, chest, bureau, dresser", "counter", "sand", "sink", "skyscraper", "fireplace", "refrigerator, icebox", "grandstand, covered stand", "path", "stairs", "runway", "case, display case, showcase, vitrine", "pool table, billiard table, snooker table", "pillow", "screen door, screen", "stairway, staircase", "river", "bridge, span", "bookcase", "blind, screen", "coffee table", "toilet, can, commode, crapper, pot, potty, stool, throne", "flower", "book", "hill", "bench", "countertop", "stove", "palm, palm tree", "kitchen island", "computer", "swivel chair", "boat", "bar", "arcade machine", "hovel, hut, hutch, shack, shanty", "bus", "towel", "light", "truck", "tower", "chandelier", "awning, sunshade, sunblind", "street lamp", "booth", "tv", "plane", "dirt track", "clothes", "pole", "land, ground, soil", "bannister, banister, balustrade, balusters, handrail", "escalator, moving staircase, moving stairway", "ottoman, pouf, pouffe, puff, hassock", "bottle", "buffet, counter, sideboard", "poster, posting, placard, notice, bill, card", "stage", "van", "ship", "fountain", "conveyer belt, conveyor belt, conveyer, conveyor, transporter", "canopy", "washer, automatic washer, washing machine", "plaything, toy", "pool", "stool", "barrel, cask", "basket, handbasket", "falls", "tent", "bag", "minibike, motorbike", "cradle", "oven", "ball", "food, solid food", "step, stair", "tank, storage tank", "trade name", "microwave", "pot", "animal", "bicycle", "lake", "dishwasher", "screen", "blanket, cover", "sculpture", "hood, exhaust hood", "sconce", "vase", "traffic light", "tray", "trash can", "fan", "pier", "crt screen", "plate", "monitor", "bulletin board", "shower", "radiator", "glass, drinking glass", "clock", "flag", # noqa +] +# After processed by `prepare_ade20k_sem_seg.py`, id 255 means ignore +# fmt: on + + +def _get_coco_instances_meta(): + thing_ids = [k["id"] for k in COCO_CATEGORIES if k["isthing"] == 1] + thing_colors = [k["color"] for k in COCO_CATEGORIES if k["isthing"] == 1] + assert len(thing_ids) == 80, len(thing_ids) + # Mapping from the incontiguous COCO category id to an id in [0, 79] + thing_dataset_id_to_contiguous_id = {k: i for i, k in enumerate(thing_ids)} + thing_classes = [k["name"] for k in COCO_CATEGORIES if k["isthing"] == 1] + ret = { + "thing_dataset_id_to_contiguous_id": thing_dataset_id_to_contiguous_id, + "thing_classes": thing_classes, + "thing_colors": thing_colors, + } + return ret + + +def _get_coco_panoptic_separated_meta(): + """ + Returns metadata for "separated" version of the panoptic segmentation dataset. + """ + stuff_ids = [k["id"] for k in COCO_CATEGORIES if k["isthing"] == 0] + assert len(stuff_ids) == 53, len(stuff_ids) + + # For semantic segmentation, this mapping maps from contiguous stuff id + # (in [0, 53], used in models) to ids in the dataset (used for processing results) + # The id 0 is mapped to an extra category "thing". + stuff_dataset_id_to_contiguous_id = {k: i + 1 for i, k in enumerate(stuff_ids)} + # When converting COCO panoptic annotations to semantic annotations + # We label the "thing" category to 0 + stuff_dataset_id_to_contiguous_id[0] = 0 + + # 54 names for COCO stuff categories (including "things") + stuff_classes = ["things"] + [ + k["name"].replace("-other", "").replace("-merged", "") + for k in COCO_CATEGORIES + if k["isthing"] == 0 + ] + + # NOTE: I randomly picked a color for things + stuff_colors = [[82, 18, 128]] + [k["color"] for k in COCO_CATEGORIES if k["isthing"] == 0] + ret = { + "stuff_dataset_id_to_contiguous_id": stuff_dataset_id_to_contiguous_id, + "stuff_classes": stuff_classes, + "stuff_colors": stuff_colors, + } + ret.update(_get_coco_instances_meta()) + return ret + + +def _get_builtin_metadata(dataset_name): + if dataset_name == "coco": + return _get_coco_instances_meta() + if dataset_name == "coco_panoptic_separated": + return _get_coco_panoptic_separated_meta() + elif dataset_name == "coco_panoptic_standard": + meta = {} + # The following metadata maps contiguous id from [0, #thing categories + + # #stuff categories) to their names and colors. We have to replica of the + # same name and color under "thing_*" and "stuff_*" because the current + # visualization function in D2 handles thing and class classes differently + # due to some heuristic used in Panoptic FPN. We keep the same naming to + # enable reusing existing visualization functions. + thing_classes = [k["name"] for k in COCO_CATEGORIES] + thing_colors = [k["color"] for k in COCO_CATEGORIES] + stuff_classes = [k["name"] for k in COCO_CATEGORIES] + stuff_colors = [k["color"] for k in COCO_CATEGORIES] + + meta["thing_classes"] = thing_classes + meta["thing_colors"] = thing_colors + meta["stuff_classes"] = stuff_classes + meta["stuff_colors"] = stuff_colors + + # Convert category id for training: + # category id: like semantic segmentation, it is the class id for each + # pixel. Since there are some classes not used in evaluation, the category + # id is not always contiguous and thus we have two set of category ids: + # - original category id: category id in the original dataset, mainly + # used for evaluation. + # - contiguous category id: [0, #classes), in order to train the linear + # softmax classifier. + thing_dataset_id_to_contiguous_id = {} + stuff_dataset_id_to_contiguous_id = {} + + for i, cat in enumerate(COCO_CATEGORIES): + if cat["isthing"]: + thing_dataset_id_to_contiguous_id[cat["id"]] = i + else: + stuff_dataset_id_to_contiguous_id[cat["id"]] = i + + meta["thing_dataset_id_to_contiguous_id"] = thing_dataset_id_to_contiguous_id + meta["stuff_dataset_id_to_contiguous_id"] = stuff_dataset_id_to_contiguous_id + + return meta + elif dataset_name == "coco_person": + return { + "thing_classes": ["person"], + "keypoint_names": COCO_PERSON_KEYPOINT_NAMES, + "keypoint_flip_map": COCO_PERSON_KEYPOINT_FLIP_MAP, + "keypoint_connection_rules": KEYPOINT_CONNECTION_RULES, + } + elif dataset_name == "cityscapes": + # fmt: off + CITYSCAPES_THING_CLASSES = [ + "person", "rider", "car", "truck", + "bus", "train", "motorcycle", "bicycle", + ] + CITYSCAPES_STUFF_CLASSES = [ + "road", "sidewalk", "building", "wall", "fence", "pole", "traffic light", + "traffic sign", "vegetation", "terrain", "sky", "person", "rider", "car", + "truck", "bus", "train", "motorcycle", "bicycle", + ] + # fmt: on + return { + "thing_classes": CITYSCAPES_THING_CLASSES, + "stuff_classes": CITYSCAPES_STUFF_CLASSES, + } + raise KeyError("No built-in metadata for dataset {}".format(dataset_name)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/cityscapes.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/cityscapes.py new file mode 100644 index 00000000..f646be9d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/cityscapes.py @@ -0,0 +1,329 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import functools +import json +import logging +import multiprocessing as mp +import numpy as np +import os +from itertools import chain +import annotator.oneformer.pycocotools.mask as mask_util +from PIL import Image + +from annotator.oneformer.detectron2.structures import BoxMode +from annotator.oneformer.detectron2.utils.comm import get_world_size +from annotator.oneformer.detectron2.utils.file_io import PathManager +from annotator.oneformer.detectron2.utils.logger import setup_logger + +try: + import cv2 # noqa +except ImportError: + # OpenCV is an optional dependency at the moment + pass + + +logger = logging.getLogger(__name__) + + +def _get_cityscapes_files(image_dir, gt_dir): + files = [] + # scan through the directory + cities = PathManager.ls(image_dir) + logger.info(f"{len(cities)} cities found in '{image_dir}'.") + for city in cities: + city_img_dir = os.path.join(image_dir, city) + city_gt_dir = os.path.join(gt_dir, city) + for basename in PathManager.ls(city_img_dir): + image_file = os.path.join(city_img_dir, basename) + + suffix = "leftImg8bit.png" + assert basename.endswith(suffix), basename + basename = basename[: -len(suffix)] + + instance_file = os.path.join(city_gt_dir, basename + "gtFine_instanceIds.png") + label_file = os.path.join(city_gt_dir, basename + "gtFine_labelIds.png") + json_file = os.path.join(city_gt_dir, basename + "gtFine_polygons.json") + + files.append((image_file, instance_file, label_file, json_file)) + assert len(files), "No images found in {}".format(image_dir) + for f in files[0]: + assert PathManager.isfile(f), f + return files + + +def load_cityscapes_instances(image_dir, gt_dir, from_json=True, to_polygons=True): + """ + Args: + image_dir (str): path to the raw dataset. e.g., "~/cityscapes/leftImg8bit/train". + gt_dir (str): path to the raw annotations. e.g., "~/cityscapes/gtFine/train". + from_json (bool): whether to read annotations from the raw json file or the png files. + to_polygons (bool): whether to represent the segmentation as polygons + (COCO's format) instead of masks (cityscapes's format). + + Returns: + list[dict]: a list of dicts in Detectron2 standard format. (See + `Using Custom Datasets `_ ) + """ + if from_json: + assert to_polygons, ( + "Cityscapes's json annotations are in polygon format. " + "Converting to mask format is not supported now." + ) + files = _get_cityscapes_files(image_dir, gt_dir) + + logger.info("Preprocessing cityscapes annotations ...") + # This is still not fast: all workers will execute duplicate works and will + # take up to 10m on a 8GPU server. + pool = mp.Pool(processes=max(mp.cpu_count() // get_world_size() // 2, 4)) + + ret = pool.map( + functools.partial(_cityscapes_files_to_dict, from_json=from_json, to_polygons=to_polygons), + files, + ) + logger.info("Loaded {} images from {}".format(len(ret), image_dir)) + + # Map cityscape ids to contiguous ids + from cityscapesscripts.helpers.labels import labels + + labels = [l for l in labels if l.hasInstances and not l.ignoreInEval] + dataset_id_to_contiguous_id = {l.id: idx for idx, l in enumerate(labels)} + for dict_per_image in ret: + for anno in dict_per_image["annotations"]: + anno["category_id"] = dataset_id_to_contiguous_id[anno["category_id"]] + return ret + + +def load_cityscapes_semantic(image_dir, gt_dir): + """ + Args: + image_dir (str): path to the raw dataset. e.g., "~/cityscapes/leftImg8bit/train". + gt_dir (str): path to the raw annotations. e.g., "~/cityscapes/gtFine/train". + + Returns: + list[dict]: a list of dict, each has "file_name" and + "sem_seg_file_name". + """ + ret = [] + # gt_dir is small and contain many small files. make sense to fetch to local first + gt_dir = PathManager.get_local_path(gt_dir) + for image_file, _, label_file, json_file in _get_cityscapes_files(image_dir, gt_dir): + label_file = label_file.replace("labelIds", "labelTrainIds") + + with PathManager.open(json_file, "r") as f: + jsonobj = json.load(f) + ret.append( + { + "file_name": image_file, + "sem_seg_file_name": label_file, + "height": jsonobj["imgHeight"], + "width": jsonobj["imgWidth"], + } + ) + assert len(ret), f"No images found in {image_dir}!" + assert PathManager.isfile( + ret[0]["sem_seg_file_name"] + ), "Please generate labelTrainIds.png with cityscapesscripts/preparation/createTrainIdLabelImgs.py" # noqa + return ret + + +def _cityscapes_files_to_dict(files, from_json, to_polygons): + """ + Parse cityscapes annotation files to a instance segmentation dataset dict. + + Args: + files (tuple): consists of (image_file, instance_id_file, label_id_file, json_file) + from_json (bool): whether to read annotations from the raw json file or the png files. + to_polygons (bool): whether to represent the segmentation as polygons + (COCO's format) instead of masks (cityscapes's format). + + Returns: + A dict in Detectron2 Dataset format. + """ + from cityscapesscripts.helpers.labels import id2label, name2label + + image_file, instance_id_file, _, json_file = files + + annos = [] + + if from_json: + from shapely.geometry import MultiPolygon, Polygon + + with PathManager.open(json_file, "r") as f: + jsonobj = json.load(f) + ret = { + "file_name": image_file, + "image_id": os.path.basename(image_file), + "height": jsonobj["imgHeight"], + "width": jsonobj["imgWidth"], + } + + # `polygons_union` contains the union of all valid polygons. + polygons_union = Polygon() + + # CityscapesScripts draw the polygons in sequential order + # and each polygon *overwrites* existing ones. See + # (https://github.com/mcordts/cityscapesScripts/blob/master/cityscapesscripts/preparation/json2instanceImg.py) # noqa + # We use reverse order, and each polygon *avoids* early ones. + # This will resolve the ploygon overlaps in the same way as CityscapesScripts. + for obj in jsonobj["objects"][::-1]: + if "deleted" in obj: # cityscapes data format specific + continue + label_name = obj["label"] + + try: + label = name2label[label_name] + except KeyError: + if label_name.endswith("group"): # crowd area + label = name2label[label_name[: -len("group")]] + else: + raise + if label.id < 0: # cityscapes data format + continue + + # Cityscapes's raw annotations uses integer coordinates + # Therefore +0.5 here + poly_coord = np.asarray(obj["polygon"], dtype="f4") + 0.5 + # CityscapesScript uses PIL.ImageDraw.polygon to rasterize + # polygons for evaluation. This function operates in integer space + # and draws each pixel whose center falls into the polygon. + # Therefore it draws a polygon which is 0.5 "fatter" in expectation. + # We therefore dilate the input polygon by 0.5 as our input. + poly = Polygon(poly_coord).buffer(0.5, resolution=4) + + if not label.hasInstances or label.ignoreInEval: + # even if we won't store the polygon it still contributes to overlaps resolution + polygons_union = polygons_union.union(poly) + continue + + # Take non-overlapping part of the polygon + poly_wo_overlaps = poly.difference(polygons_union) + if poly_wo_overlaps.is_empty: + continue + polygons_union = polygons_union.union(poly) + + anno = {} + anno["iscrowd"] = label_name.endswith("group") + anno["category_id"] = label.id + + if isinstance(poly_wo_overlaps, Polygon): + poly_list = [poly_wo_overlaps] + elif isinstance(poly_wo_overlaps, MultiPolygon): + poly_list = poly_wo_overlaps.geoms + else: + raise NotImplementedError("Unknown geometric structure {}".format(poly_wo_overlaps)) + + poly_coord = [] + for poly_el in poly_list: + # COCO API can work only with exterior boundaries now, hence we store only them. + # TODO: store both exterior and interior boundaries once other parts of the + # codebase support holes in polygons. + poly_coord.append(list(chain(*poly_el.exterior.coords))) + anno["segmentation"] = poly_coord + (xmin, ymin, xmax, ymax) = poly_wo_overlaps.bounds + + anno["bbox"] = (xmin, ymin, xmax, ymax) + anno["bbox_mode"] = BoxMode.XYXY_ABS + + annos.append(anno) + else: + # See also the official annotation parsing scripts at + # https://github.com/mcordts/cityscapesScripts/blob/master/cityscapesscripts/evaluation/instances2dict.py # noqa + with PathManager.open(instance_id_file, "rb") as f: + inst_image = np.asarray(Image.open(f), order="F") + # ids < 24 are stuff labels (filtering them first is about 5% faster) + flattened_ids = np.unique(inst_image[inst_image >= 24]) + + ret = { + "file_name": image_file, + "image_id": os.path.basename(image_file), + "height": inst_image.shape[0], + "width": inst_image.shape[1], + } + + for instance_id in flattened_ids: + # For non-crowd annotations, instance_id // 1000 is the label_id + # Crowd annotations have <1000 instance ids + label_id = instance_id // 1000 if instance_id >= 1000 else instance_id + label = id2label[label_id] + if not label.hasInstances or label.ignoreInEval: + continue + + anno = {} + anno["iscrowd"] = instance_id < 1000 + anno["category_id"] = label.id + + mask = np.asarray(inst_image == instance_id, dtype=np.uint8, order="F") + + inds = np.nonzero(mask) + ymin, ymax = inds[0].min(), inds[0].max() + xmin, xmax = inds[1].min(), inds[1].max() + anno["bbox"] = (xmin, ymin, xmax, ymax) + if xmax <= xmin or ymax <= ymin: + continue + anno["bbox_mode"] = BoxMode.XYXY_ABS + if to_polygons: + # This conversion comes from D4809743 and D5171122, + # when Mask-RCNN was first developed. + contours = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[ + -2 + ] + polygons = [c.reshape(-1).tolist() for c in contours if len(c) >= 3] + # opencv's can produce invalid polygons + if len(polygons) == 0: + continue + anno["segmentation"] = polygons + else: + anno["segmentation"] = mask_util.encode(mask[:, :, None])[0] + annos.append(anno) + ret["annotations"] = annos + return ret + + +if __name__ == "__main__": + """ + Test the cityscapes dataset loader. + + Usage: + python -m detectron2.data.datasets.cityscapes \ + cityscapes/leftImg8bit/train cityscapes/gtFine/train + """ + import argparse + + parser = argparse.ArgumentParser() + parser.add_argument("image_dir") + parser.add_argument("gt_dir") + parser.add_argument("--type", choices=["instance", "semantic"], default="instance") + args = parser.parse_args() + from annotator.oneformer.detectron2.data.catalog import Metadata + from annotator.oneformer.detectron2.utils.visualizer import Visualizer + from cityscapesscripts.helpers.labels import labels + + logger = setup_logger(name=__name__) + + dirname = "cityscapes-data-vis" + os.makedirs(dirname, exist_ok=True) + + if args.type == "instance": + dicts = load_cityscapes_instances( + args.image_dir, args.gt_dir, from_json=True, to_polygons=True + ) + logger.info("Done loading {} samples.".format(len(dicts))) + + thing_classes = [k.name for k in labels if k.hasInstances and not k.ignoreInEval] + meta = Metadata().set(thing_classes=thing_classes) + + else: + dicts = load_cityscapes_semantic(args.image_dir, args.gt_dir) + logger.info("Done loading {} samples.".format(len(dicts))) + + stuff_classes = [k.name for k in labels if k.trainId != 255] + stuff_colors = [k.color for k in labels if k.trainId != 255] + meta = Metadata().set(stuff_classes=stuff_classes, stuff_colors=stuff_colors) + + for d in dicts: + img = np.array(Image.open(PathManager.open(d["file_name"], "rb"))) + visualizer = Visualizer(img, metadata=meta) + vis = visualizer.draw_dataset_dict(d) + # cv2.imshow("a", vis.get_image()[:, :, ::-1]) + # cv2.waitKey() + fpath = os.path.join(dirname, os.path.basename(d["file_name"])) + vis.save(fpath) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/cityscapes_panoptic.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/cityscapes_panoptic.py new file mode 100644 index 00000000..7ce9ec48 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/cityscapes_panoptic.py @@ -0,0 +1,187 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import json +import logging +import os + +from annotator.oneformer.detectron2.data import DatasetCatalog, MetadataCatalog +from annotator.oneformer.detectron2.data.datasets.builtin_meta import CITYSCAPES_CATEGORIES +from annotator.oneformer.detectron2.utils.file_io import PathManager + +""" +This file contains functions to register the Cityscapes panoptic dataset to the DatasetCatalog. +""" + + +logger = logging.getLogger(__name__) + + +def get_cityscapes_panoptic_files(image_dir, gt_dir, json_info): + files = [] + # scan through the directory + cities = PathManager.ls(image_dir) + logger.info(f"{len(cities)} cities found in '{image_dir}'.") + image_dict = {} + for city in cities: + city_img_dir = os.path.join(image_dir, city) + for basename in PathManager.ls(city_img_dir): + image_file = os.path.join(city_img_dir, basename) + + suffix = "_leftImg8bit.png" + assert basename.endswith(suffix), basename + basename = os.path.basename(basename)[: -len(suffix)] + + image_dict[basename] = image_file + + for ann in json_info["annotations"]: + image_file = image_dict.get(ann["image_id"], None) + assert image_file is not None, "No image {} found for annotation {}".format( + ann["image_id"], ann["file_name"] + ) + label_file = os.path.join(gt_dir, ann["file_name"]) + segments_info = ann["segments_info"] + + files.append((image_file, label_file, segments_info)) + + assert len(files), "No images found in {}".format(image_dir) + assert PathManager.isfile(files[0][0]), files[0][0] + assert PathManager.isfile(files[0][1]), files[0][1] + return files + + +def load_cityscapes_panoptic(image_dir, gt_dir, gt_json, meta): + """ + Args: + image_dir (str): path to the raw dataset. e.g., "~/cityscapes/leftImg8bit/train". + gt_dir (str): path to the raw annotations. e.g., + "~/cityscapes/gtFine/cityscapes_panoptic_train". + gt_json (str): path to the json file. e.g., + "~/cityscapes/gtFine/cityscapes_panoptic_train.json". + meta (dict): dictionary containing "thing_dataset_id_to_contiguous_id" + and "stuff_dataset_id_to_contiguous_id" to map category ids to + contiguous ids for training. + + Returns: + list[dict]: a list of dicts in Detectron2 standard format. (See + `Using Custom Datasets `_ ) + """ + + def _convert_category_id(segment_info, meta): + if segment_info["category_id"] in meta["thing_dataset_id_to_contiguous_id"]: + segment_info["category_id"] = meta["thing_dataset_id_to_contiguous_id"][ + segment_info["category_id"] + ] + else: + segment_info["category_id"] = meta["stuff_dataset_id_to_contiguous_id"][ + segment_info["category_id"] + ] + return segment_info + + assert os.path.exists( + gt_json + ), "Please run `python cityscapesscripts/preparation/createPanopticImgs.py` to generate label files." # noqa + with open(gt_json) as f: + json_info = json.load(f) + files = get_cityscapes_panoptic_files(image_dir, gt_dir, json_info) + ret = [] + for image_file, label_file, segments_info in files: + sem_label_file = ( + image_file.replace("leftImg8bit", "gtFine").split(".")[0] + "_labelTrainIds.png" + ) + segments_info = [_convert_category_id(x, meta) for x in segments_info] + ret.append( + { + "file_name": image_file, + "image_id": "_".join( + os.path.splitext(os.path.basename(image_file))[0].split("_")[:3] + ), + "sem_seg_file_name": sem_label_file, + "pan_seg_file_name": label_file, + "segments_info": segments_info, + } + ) + assert len(ret), f"No images found in {image_dir}!" + assert PathManager.isfile( + ret[0]["sem_seg_file_name"] + ), "Please generate labelTrainIds.png with cityscapesscripts/preparation/createTrainIdLabelImgs.py" # noqa + assert PathManager.isfile( + ret[0]["pan_seg_file_name"] + ), "Please generate panoptic annotation with python cityscapesscripts/preparation/createPanopticImgs.py" # noqa + return ret + + +_RAW_CITYSCAPES_PANOPTIC_SPLITS = { + "cityscapes_fine_panoptic_train": ( + "cityscapes/leftImg8bit/train", + "cityscapes/gtFine/cityscapes_panoptic_train", + "cityscapes/gtFine/cityscapes_panoptic_train.json", + ), + "cityscapes_fine_panoptic_val": ( + "cityscapes/leftImg8bit/val", + "cityscapes/gtFine/cityscapes_panoptic_val", + "cityscapes/gtFine/cityscapes_panoptic_val.json", + ), + # "cityscapes_fine_panoptic_test": not supported yet +} + + +def register_all_cityscapes_panoptic(root): + meta = {} + # The following metadata maps contiguous id from [0, #thing categories + + # #stuff categories) to their names and colors. We have to replica of the + # same name and color under "thing_*" and "stuff_*" because the current + # visualization function in D2 handles thing and class classes differently + # due to some heuristic used in Panoptic FPN. We keep the same naming to + # enable reusing existing visualization functions. + thing_classes = [k["name"] for k in CITYSCAPES_CATEGORIES] + thing_colors = [k["color"] for k in CITYSCAPES_CATEGORIES] + stuff_classes = [k["name"] for k in CITYSCAPES_CATEGORIES] + stuff_colors = [k["color"] for k in CITYSCAPES_CATEGORIES] + + meta["thing_classes"] = thing_classes + meta["thing_colors"] = thing_colors + meta["stuff_classes"] = stuff_classes + meta["stuff_colors"] = stuff_colors + + # There are three types of ids in cityscapes panoptic segmentation: + # (1) category id: like semantic segmentation, it is the class id for each + # pixel. Since there are some classes not used in evaluation, the category + # id is not always contiguous and thus we have two set of category ids: + # - original category id: category id in the original dataset, mainly + # used for evaluation. + # - contiguous category id: [0, #classes), in order to train the classifier + # (2) instance id: this id is used to differentiate different instances from + # the same category. For "stuff" classes, the instance id is always 0; for + # "thing" classes, the instance id starts from 1 and 0 is reserved for + # ignored instances (e.g. crowd annotation). + # (3) panoptic id: this is the compact id that encode both category and + # instance id by: category_id * 1000 + instance_id. + thing_dataset_id_to_contiguous_id = {} + stuff_dataset_id_to_contiguous_id = {} + + for k in CITYSCAPES_CATEGORIES: + if k["isthing"] == 1: + thing_dataset_id_to_contiguous_id[k["id"]] = k["trainId"] + else: + stuff_dataset_id_to_contiguous_id[k["id"]] = k["trainId"] + + meta["thing_dataset_id_to_contiguous_id"] = thing_dataset_id_to_contiguous_id + meta["stuff_dataset_id_to_contiguous_id"] = stuff_dataset_id_to_contiguous_id + + for key, (image_dir, gt_dir, gt_json) in _RAW_CITYSCAPES_PANOPTIC_SPLITS.items(): + image_dir = os.path.join(root, image_dir) + gt_dir = os.path.join(root, gt_dir) + gt_json = os.path.join(root, gt_json) + + DatasetCatalog.register( + key, lambda x=image_dir, y=gt_dir, z=gt_json: load_cityscapes_panoptic(x, y, z, meta) + ) + MetadataCatalog.get(key).set( + panoptic_root=gt_dir, + image_root=image_dir, + panoptic_json=gt_json, + gt_dir=gt_dir.replace("cityscapes_panoptic_", ""), + evaluator_type="cityscapes_panoptic_seg", + ignore_label=255, + label_divisor=1000, + **meta, + ) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/coco.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/coco.py new file mode 100644 index 00000000..1a7cdba8 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/coco.py @@ -0,0 +1,539 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import contextlib +import datetime +import io +import json +import logging +import numpy as np +import os +import shutil +import annotator.oneformer.pycocotools.mask as mask_util +from fvcore.common.timer import Timer +from iopath.common.file_io import file_lock +from PIL import Image + +from annotator.oneformer.detectron2.structures import Boxes, BoxMode, PolygonMasks, RotatedBoxes +from annotator.oneformer.detectron2.utils.file_io import PathManager + +from .. import DatasetCatalog, MetadataCatalog + +""" +This file contains functions to parse COCO-format annotations into dicts in "Detectron2 format". +""" + + +logger = logging.getLogger(__name__) + +__all__ = ["load_coco_json", "load_sem_seg", "convert_to_coco_json", "register_coco_instances"] + + +def load_coco_json(json_file, image_root, dataset_name=None, extra_annotation_keys=None): + """ + Load a json file with COCO's instances annotation format. + Currently supports instance detection, instance segmentation, + and person keypoints annotations. + + Args: + json_file (str): full path to the json file in COCO instances annotation format. + image_root (str or path-like): the directory where the images in this json file exists. + dataset_name (str or None): the name of the dataset (e.g., coco_2017_train). + When provided, this function will also do the following: + + * Put "thing_classes" into the metadata associated with this dataset. + * Map the category ids into a contiguous range (needed by standard dataset format), + and add "thing_dataset_id_to_contiguous_id" to the metadata associated + with this dataset. + + This option should usually be provided, unless users need to load + the original json content and apply more processing manually. + extra_annotation_keys (list[str]): list of per-annotation keys that should also be + loaded into the dataset dict (besides "iscrowd", "bbox", "keypoints", + "category_id", "segmentation"). The values for these keys will be returned as-is. + For example, the densepose annotations are loaded in this way. + + Returns: + list[dict]: a list of dicts in Detectron2 standard dataset dicts format (See + `Using Custom Datasets `_ ) when `dataset_name` is not None. + If `dataset_name` is None, the returned `category_ids` may be + incontiguous and may not conform to the Detectron2 standard format. + + Notes: + 1. This function does not read the image files. + The results do not have the "image" field. + """ + from annotator.oneformer.pycocotools.coco import COCO + + timer = Timer() + json_file = PathManager.get_local_path(json_file) + with contextlib.redirect_stdout(io.StringIO()): + coco_api = COCO(json_file) + if timer.seconds() > 1: + logger.info("Loading {} takes {:.2f} seconds.".format(json_file, timer.seconds())) + + id_map = None + if dataset_name is not None: + meta = MetadataCatalog.get(dataset_name) + cat_ids = sorted(coco_api.getCatIds()) + cats = coco_api.loadCats(cat_ids) + # The categories in a custom json file may not be sorted. + thing_classes = [c["name"] for c in sorted(cats, key=lambda x: x["id"])] + meta.thing_classes = thing_classes + + # In COCO, certain category ids are artificially removed, + # and by convention they are always ignored. + # We deal with COCO's id issue and translate + # the category ids to contiguous ids in [0, 80). + + # It works by looking at the "categories" field in the json, therefore + # if users' own json also have incontiguous ids, we'll + # apply this mapping as well but print a warning. + if not (min(cat_ids) == 1 and max(cat_ids) == len(cat_ids)): + if "coco" not in dataset_name: + logger.warning( + """ +Category ids in annotations are not in [1, #categories]! We'll apply a mapping for you. +""" + ) + id_map = {v: i for i, v in enumerate(cat_ids)} + meta.thing_dataset_id_to_contiguous_id = id_map + + # sort indices for reproducible results + img_ids = sorted(coco_api.imgs.keys()) + # imgs is a list of dicts, each looks something like: + # {'license': 4, + # 'url': 'http://farm6.staticflickr.com/5454/9413846304_881d5e5c3b_z.jpg', + # 'file_name': 'COCO_val2014_000000001268.jpg', + # 'height': 427, + # 'width': 640, + # 'date_captured': '2013-11-17 05:57:24', + # 'id': 1268} + imgs = coco_api.loadImgs(img_ids) + # anns is a list[list[dict]], where each dict is an annotation + # record for an object. The inner list enumerates the objects in an image + # and the outer list enumerates over images. Example of anns[0]: + # [{'segmentation': [[192.81, + # 247.09, + # ... + # 219.03, + # 249.06]], + # 'area': 1035.749, + # 'iscrowd': 0, + # 'image_id': 1268, + # 'bbox': [192.81, 224.8, 74.73, 33.43], + # 'category_id': 16, + # 'id': 42986}, + # ...] + anns = [coco_api.imgToAnns[img_id] for img_id in img_ids] + total_num_valid_anns = sum([len(x) for x in anns]) + total_num_anns = len(coco_api.anns) + if total_num_valid_anns < total_num_anns: + logger.warning( + f"{json_file} contains {total_num_anns} annotations, but only " + f"{total_num_valid_anns} of them match to images in the file." + ) + + if "minival" not in json_file: + # The popular valminusminival & minival annotations for COCO2014 contain this bug. + # However the ratio of buggy annotations there is tiny and does not affect accuracy. + # Therefore we explicitly white-list them. + ann_ids = [ann["id"] for anns_per_image in anns for ann in anns_per_image] + assert len(set(ann_ids)) == len(ann_ids), "Annotation ids in '{}' are not unique!".format( + json_file + ) + + imgs_anns = list(zip(imgs, anns)) + logger.info("Loaded {} images in COCO format from {}".format(len(imgs_anns), json_file)) + + dataset_dicts = [] + + ann_keys = ["iscrowd", "bbox", "keypoints", "category_id"] + (extra_annotation_keys or []) + + num_instances_without_valid_segmentation = 0 + + for (img_dict, anno_dict_list) in imgs_anns: + record = {} + record["file_name"] = os.path.join(image_root, img_dict["file_name"]) + record["height"] = img_dict["height"] + record["width"] = img_dict["width"] + image_id = record["image_id"] = img_dict["id"] + + objs = [] + for anno in anno_dict_list: + # Check that the image_id in this annotation is the same as + # the image_id we're looking at. + # This fails only when the data parsing logic or the annotation file is buggy. + + # The original COCO valminusminival2014 & minival2014 annotation files + # actually contains bugs that, together with certain ways of using COCO API, + # can trigger this assertion. + assert anno["image_id"] == image_id + + assert anno.get("ignore", 0) == 0, '"ignore" in COCO json file is not supported.' + + obj = {key: anno[key] for key in ann_keys if key in anno} + if "bbox" in obj and len(obj["bbox"]) == 0: + raise ValueError( + f"One annotation of image {image_id} contains empty 'bbox' value! " + "This json does not have valid COCO format." + ) + + segm = anno.get("segmentation", None) + if segm: # either list[list[float]] or dict(RLE) + if isinstance(segm, dict): + if isinstance(segm["counts"], list): + # convert to compressed RLE + segm = mask_util.frPyObjects(segm, *segm["size"]) + else: + # filter out invalid polygons (< 3 points) + segm = [poly for poly in segm if len(poly) % 2 == 0 and len(poly) >= 6] + if len(segm) == 0: + num_instances_without_valid_segmentation += 1 + continue # ignore this instance + obj["segmentation"] = segm + + keypts = anno.get("keypoints", None) + if keypts: # list[int] + for idx, v in enumerate(keypts): + if idx % 3 != 2: + # COCO's segmentation coordinates are floating points in [0, H or W], + # but keypoint coordinates are integers in [0, H-1 or W-1] + # Therefore we assume the coordinates are "pixel indices" and + # add 0.5 to convert to floating point coordinates. + keypts[idx] = v + 0.5 + obj["keypoints"] = keypts + + obj["bbox_mode"] = BoxMode.XYWH_ABS + if id_map: + annotation_category_id = obj["category_id"] + try: + obj["category_id"] = id_map[annotation_category_id] + except KeyError as e: + raise KeyError( + f"Encountered category_id={annotation_category_id} " + "but this id does not exist in 'categories' of the json file." + ) from e + objs.append(obj) + record["annotations"] = objs + dataset_dicts.append(record) + + if num_instances_without_valid_segmentation > 0: + logger.warning( + "Filtered out {} instances without valid segmentation. ".format( + num_instances_without_valid_segmentation + ) + + "There might be issues in your dataset generation process. Please " + "check https://detectron2.readthedocs.io/en/latest/tutorials/datasets.html carefully" + ) + return dataset_dicts + + +def load_sem_seg(gt_root, image_root, gt_ext="png", image_ext="jpg"): + """ + Load semantic segmentation datasets. All files under "gt_root" with "gt_ext" extension are + treated as ground truth annotations and all files under "image_root" with "image_ext" extension + as input images. Ground truth and input images are matched using file paths relative to + "gt_root" and "image_root" respectively without taking into account file extensions. + This works for COCO as well as some other datasets. + + Args: + gt_root (str): full path to ground truth semantic segmentation files. Semantic segmentation + annotations are stored as images with integer values in pixels that represent + corresponding semantic labels. + image_root (str): the directory where the input images are. + gt_ext (str): file extension for ground truth annotations. + image_ext (str): file extension for input images. + + Returns: + list[dict]: + a list of dicts in detectron2 standard format without instance-level + annotation. + + Notes: + 1. This function does not read the image and ground truth files. + The results do not have the "image" and "sem_seg" fields. + """ + + # We match input images with ground truth based on their relative filepaths (without file + # extensions) starting from 'image_root' and 'gt_root' respectively. + def file2id(folder_path, file_path): + # extract relative path starting from `folder_path` + image_id = os.path.normpath(os.path.relpath(file_path, start=folder_path)) + # remove file extension + image_id = os.path.splitext(image_id)[0] + return image_id + + input_files = sorted( + (os.path.join(image_root, f) for f in PathManager.ls(image_root) if f.endswith(image_ext)), + key=lambda file_path: file2id(image_root, file_path), + ) + gt_files = sorted( + (os.path.join(gt_root, f) for f in PathManager.ls(gt_root) if f.endswith(gt_ext)), + key=lambda file_path: file2id(gt_root, file_path), + ) + + assert len(gt_files) > 0, "No annotations found in {}.".format(gt_root) + + # Use the intersection, so that val2017_100 annotations can run smoothly with val2017 images + if len(input_files) != len(gt_files): + logger.warn( + "Directory {} and {} has {} and {} files, respectively.".format( + image_root, gt_root, len(input_files), len(gt_files) + ) + ) + input_basenames = [os.path.basename(f)[: -len(image_ext)] for f in input_files] + gt_basenames = [os.path.basename(f)[: -len(gt_ext)] for f in gt_files] + intersect = list(set(input_basenames) & set(gt_basenames)) + # sort, otherwise each worker may obtain a list[dict] in different order + intersect = sorted(intersect) + logger.warn("Will use their intersection of {} files.".format(len(intersect))) + input_files = [os.path.join(image_root, f + image_ext) for f in intersect] + gt_files = [os.path.join(gt_root, f + gt_ext) for f in intersect] + + logger.info( + "Loaded {} images with semantic segmentation from {}".format(len(input_files), image_root) + ) + + dataset_dicts = [] + for (img_path, gt_path) in zip(input_files, gt_files): + record = {} + record["file_name"] = img_path + record["sem_seg_file_name"] = gt_path + dataset_dicts.append(record) + + return dataset_dicts + + +def convert_to_coco_dict(dataset_name): + """ + Convert an instance detection/segmentation or keypoint detection dataset + in detectron2's standard format into COCO json format. + + Generic dataset description can be found here: + https://detectron2.readthedocs.io/tutorials/datasets.html#register-a-dataset + + COCO data format description can be found here: + http://cocodataset.org/#format-data + + Args: + dataset_name (str): + name of the source dataset + Must be registered in DatastCatalog and in detectron2's standard format. + Must have corresponding metadata "thing_classes" + Returns: + coco_dict: serializable dict in COCO json format + """ + + dataset_dicts = DatasetCatalog.get(dataset_name) + metadata = MetadataCatalog.get(dataset_name) + + # unmap the category mapping ids for COCO + if hasattr(metadata, "thing_dataset_id_to_contiguous_id"): + reverse_id_mapping = {v: k for k, v in metadata.thing_dataset_id_to_contiguous_id.items()} + reverse_id_mapper = lambda contiguous_id: reverse_id_mapping[contiguous_id] # noqa + else: + reverse_id_mapper = lambda contiguous_id: contiguous_id # noqa + + categories = [ + {"id": reverse_id_mapper(id), "name": name} + for id, name in enumerate(metadata.thing_classes) + ] + + logger.info("Converting dataset dicts into COCO format") + coco_images = [] + coco_annotations = [] + + for image_id, image_dict in enumerate(dataset_dicts): + coco_image = { + "id": image_dict.get("image_id", image_id), + "width": int(image_dict["width"]), + "height": int(image_dict["height"]), + "file_name": str(image_dict["file_name"]), + } + coco_images.append(coco_image) + + anns_per_image = image_dict.get("annotations", []) + for annotation in anns_per_image: + # create a new dict with only COCO fields + coco_annotation = {} + + # COCO requirement: XYWH box format for axis-align and XYWHA for rotated + bbox = annotation["bbox"] + if isinstance(bbox, np.ndarray): + if bbox.ndim != 1: + raise ValueError(f"bbox has to be 1-dimensional. Got shape={bbox.shape}.") + bbox = bbox.tolist() + if len(bbox) not in [4, 5]: + raise ValueError(f"bbox has to has length 4 or 5. Got {bbox}.") + from_bbox_mode = annotation["bbox_mode"] + to_bbox_mode = BoxMode.XYWH_ABS if len(bbox) == 4 else BoxMode.XYWHA_ABS + bbox = BoxMode.convert(bbox, from_bbox_mode, to_bbox_mode) + + # COCO requirement: instance area + if "segmentation" in annotation: + # Computing areas for instances by counting the pixels + segmentation = annotation["segmentation"] + # TODO: check segmentation type: RLE, BinaryMask or Polygon + if isinstance(segmentation, list): + polygons = PolygonMasks([segmentation]) + area = polygons.area()[0].item() + elif isinstance(segmentation, dict): # RLE + area = mask_util.area(segmentation).item() + else: + raise TypeError(f"Unknown segmentation type {type(segmentation)}!") + else: + # Computing areas using bounding boxes + if to_bbox_mode == BoxMode.XYWH_ABS: + bbox_xy = BoxMode.convert(bbox, to_bbox_mode, BoxMode.XYXY_ABS) + area = Boxes([bbox_xy]).area()[0].item() + else: + area = RotatedBoxes([bbox]).area()[0].item() + + if "keypoints" in annotation: + keypoints = annotation["keypoints"] # list[int] + for idx, v in enumerate(keypoints): + if idx % 3 != 2: + # COCO's segmentation coordinates are floating points in [0, H or W], + # but keypoint coordinates are integers in [0, H-1 or W-1] + # For COCO format consistency we substract 0.5 + # https://github.com/facebookresearch/detectron2/pull/175#issuecomment-551202163 + keypoints[idx] = v - 0.5 + if "num_keypoints" in annotation: + num_keypoints = annotation["num_keypoints"] + else: + num_keypoints = sum(kp > 0 for kp in keypoints[2::3]) + + # COCO requirement: + # linking annotations to images + # "id" field must start with 1 + coco_annotation["id"] = len(coco_annotations) + 1 + coco_annotation["image_id"] = coco_image["id"] + coco_annotation["bbox"] = [round(float(x), 3) for x in bbox] + coco_annotation["area"] = float(area) + coco_annotation["iscrowd"] = int(annotation.get("iscrowd", 0)) + coco_annotation["category_id"] = int(reverse_id_mapper(annotation["category_id"])) + + # Add optional fields + if "keypoints" in annotation: + coco_annotation["keypoints"] = keypoints + coco_annotation["num_keypoints"] = num_keypoints + + if "segmentation" in annotation: + seg = coco_annotation["segmentation"] = annotation["segmentation"] + if isinstance(seg, dict): # RLE + counts = seg["counts"] + if not isinstance(counts, str): + # make it json-serializable + seg["counts"] = counts.decode("ascii") + + coco_annotations.append(coco_annotation) + + logger.info( + "Conversion finished, " + f"#images: {len(coco_images)}, #annotations: {len(coco_annotations)}" + ) + + info = { + "date_created": str(datetime.datetime.now()), + "description": "Automatically generated COCO json file for Detectron2.", + } + coco_dict = {"info": info, "images": coco_images, "categories": categories, "licenses": None} + if len(coco_annotations) > 0: + coco_dict["annotations"] = coco_annotations + return coco_dict + + +def convert_to_coco_json(dataset_name, output_file, allow_cached=True): + """ + Converts dataset into COCO format and saves it to a json file. + dataset_name must be registered in DatasetCatalog and in detectron2's standard format. + + Args: + dataset_name: + reference from the config file to the catalogs + must be registered in DatasetCatalog and in detectron2's standard format + output_file: path of json file that will be saved to + allow_cached: if json file is already present then skip conversion + """ + + # TODO: The dataset or the conversion script *may* change, + # a checksum would be useful for validating the cached data + + PathManager.mkdirs(os.path.dirname(output_file)) + with file_lock(output_file): + if PathManager.exists(output_file) and allow_cached: + logger.warning( + f"Using previously cached COCO format annotations at '{output_file}'. " + "You need to clear the cache file if your dataset has been modified." + ) + else: + logger.info(f"Converting annotations of dataset '{dataset_name}' to COCO format ...)") + coco_dict = convert_to_coco_dict(dataset_name) + + logger.info(f"Caching COCO format annotations at '{output_file}' ...") + tmp_file = output_file + ".tmp" + with PathManager.open(tmp_file, "w") as f: + json.dump(coco_dict, f) + shutil.move(tmp_file, output_file) + + +def register_coco_instances(name, metadata, json_file, image_root): + """ + Register a dataset in COCO's json annotation format for + instance detection, instance segmentation and keypoint detection. + (i.e., Type 1 and 2 in http://cocodataset.org/#format-data. + `instances*.json` and `person_keypoints*.json` in the dataset). + + This is an example of how to register a new dataset. + You can do something similar to this function, to register new datasets. + + Args: + name (str): the name that identifies a dataset, e.g. "coco_2014_train". + metadata (dict): extra metadata associated with this dataset. You can + leave it as an empty dict. + json_file (str): path to the json instance annotation file. + image_root (str or path-like): directory which contains all the images. + """ + assert isinstance(name, str), name + assert isinstance(json_file, (str, os.PathLike)), json_file + assert isinstance(image_root, (str, os.PathLike)), image_root + # 1. register a function which returns dicts + DatasetCatalog.register(name, lambda: load_coco_json(json_file, image_root, name)) + + # 2. Optionally, add metadata about this dataset, + # since they might be useful in evaluation, visualization or logging + MetadataCatalog.get(name).set( + json_file=json_file, image_root=image_root, evaluator_type="coco", **metadata + ) + + +if __name__ == "__main__": + """ + Test the COCO json dataset loader. + + Usage: + python -m detectron2.data.datasets.coco \ + path/to/json path/to/image_root dataset_name + + "dataset_name" can be "coco_2014_minival_100", or other + pre-registered ones + """ + from annotator.oneformer.detectron2.utils.logger import setup_logger + from annotator.oneformer.detectron2.utils.visualizer import Visualizer + import annotator.oneformer.detectron2.data.datasets # noqa # add pre-defined metadata + import sys + + logger = setup_logger(name=__name__) + assert sys.argv[3] in DatasetCatalog.list() + meta = MetadataCatalog.get(sys.argv[3]) + + dicts = load_coco_json(sys.argv[1], sys.argv[2], sys.argv[3]) + logger.info("Done loading {} samples.".format(len(dicts))) + + dirname = "coco-data-vis" + os.makedirs(dirname, exist_ok=True) + for d in dicts: + img = np.array(Image.open(d["file_name"])) + visualizer = Visualizer(img, metadata=meta) + vis = visualizer.draw_dataset_dict(d) + fpath = os.path.join(dirname, os.path.basename(d["file_name"])) + vis.save(fpath) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/coco_panoptic.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/coco_panoptic.py new file mode 100644 index 00000000..a7180df5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/coco_panoptic.py @@ -0,0 +1,228 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import copy +import json +import os + +from annotator.oneformer.detectron2.data import DatasetCatalog, MetadataCatalog +from annotator.oneformer.detectron2.utils.file_io import PathManager + +from .coco import load_coco_json, load_sem_seg + +__all__ = ["register_coco_panoptic", "register_coco_panoptic_separated"] + + +def load_coco_panoptic_json(json_file, image_dir, gt_dir, meta): + """ + Args: + image_dir (str): path to the raw dataset. e.g., "~/coco/train2017". + gt_dir (str): path to the raw annotations. e.g., "~/coco/panoptic_train2017". + json_file (str): path to the json file. e.g., "~/coco/annotations/panoptic_train2017.json". + + Returns: + list[dict]: a list of dicts in Detectron2 standard format. (See + `Using Custom Datasets `_ ) + """ + + def _convert_category_id(segment_info, meta): + if segment_info["category_id"] in meta["thing_dataset_id_to_contiguous_id"]: + segment_info["category_id"] = meta["thing_dataset_id_to_contiguous_id"][ + segment_info["category_id"] + ] + segment_info["isthing"] = True + else: + segment_info["category_id"] = meta["stuff_dataset_id_to_contiguous_id"][ + segment_info["category_id"] + ] + segment_info["isthing"] = False + return segment_info + + with PathManager.open(json_file) as f: + json_info = json.load(f) + + ret = [] + for ann in json_info["annotations"]: + image_id = int(ann["image_id"]) + # TODO: currently we assume image and label has the same filename but + # different extension, and images have extension ".jpg" for COCO. Need + # to make image extension a user-provided argument if we extend this + # function to support other COCO-like datasets. + image_file = os.path.join(image_dir, os.path.splitext(ann["file_name"])[0] + ".jpg") + label_file = os.path.join(gt_dir, ann["file_name"]) + segments_info = [_convert_category_id(x, meta) for x in ann["segments_info"]] + ret.append( + { + "file_name": image_file, + "image_id": image_id, + "pan_seg_file_name": label_file, + "segments_info": segments_info, + } + ) + assert len(ret), f"No images found in {image_dir}!" + assert PathManager.isfile(ret[0]["file_name"]), ret[0]["file_name"] + assert PathManager.isfile(ret[0]["pan_seg_file_name"]), ret[0]["pan_seg_file_name"] + return ret + + +def register_coco_panoptic( + name, metadata, image_root, panoptic_root, panoptic_json, instances_json=None +): + """ + Register a "standard" version of COCO panoptic segmentation dataset named `name`. + The dictionaries in this registered dataset follows detectron2's standard format. + Hence it's called "standard". + + Args: + name (str): the name that identifies a dataset, + e.g. "coco_2017_train_panoptic" + metadata (dict): extra metadata associated with this dataset. + image_root (str): directory which contains all the images + panoptic_root (str): directory which contains panoptic annotation images in COCO format + panoptic_json (str): path to the json panoptic annotation file in COCO format + sem_seg_root (none): not used, to be consistent with + `register_coco_panoptic_separated`. + instances_json (str): path to the json instance annotation file + """ + panoptic_name = name + DatasetCatalog.register( + panoptic_name, + lambda: load_coco_panoptic_json(panoptic_json, image_root, panoptic_root, metadata), + ) + MetadataCatalog.get(panoptic_name).set( + panoptic_root=panoptic_root, + image_root=image_root, + panoptic_json=panoptic_json, + json_file=instances_json, + evaluator_type="coco_panoptic_seg", + ignore_label=255, + label_divisor=1000, + **metadata, + ) + + +def register_coco_panoptic_separated( + name, metadata, image_root, panoptic_root, panoptic_json, sem_seg_root, instances_json +): + """ + Register a "separated" version of COCO panoptic segmentation dataset named `name`. + The annotations in this registered dataset will contain both instance annotations and + semantic annotations, each with its own contiguous ids. Hence it's called "separated". + + It follows the setting used by the PanopticFPN paper: + + 1. The instance annotations directly come from polygons in the COCO + instances annotation task, rather than from the masks in the COCO panoptic annotations. + + The two format have small differences: + Polygons in the instance annotations may have overlaps. + The mask annotations are produced by labeling the overlapped polygons + with depth ordering. + + 2. The semantic annotations are converted from panoptic annotations, where + all "things" are assigned a semantic id of 0. + All semantic categories will therefore have ids in contiguous + range [1, #stuff_categories]. + + This function will also register a pure semantic segmentation dataset + named ``name + '_stuffonly'``. + + Args: + name (str): the name that identifies a dataset, + e.g. "coco_2017_train_panoptic" + metadata (dict): extra metadata associated with this dataset. + image_root (str): directory which contains all the images + panoptic_root (str): directory which contains panoptic annotation images + panoptic_json (str): path to the json panoptic annotation file + sem_seg_root (str): directory which contains all the ground truth segmentation annotations. + instances_json (str): path to the json instance annotation file + """ + panoptic_name = name + "_separated" + DatasetCatalog.register( + panoptic_name, + lambda: merge_to_panoptic( + load_coco_json(instances_json, image_root, panoptic_name), + load_sem_seg(sem_seg_root, image_root), + ), + ) + MetadataCatalog.get(panoptic_name).set( + panoptic_root=panoptic_root, + image_root=image_root, + panoptic_json=panoptic_json, + sem_seg_root=sem_seg_root, + json_file=instances_json, # TODO rename + evaluator_type="coco_panoptic_seg", + ignore_label=255, + **metadata, + ) + + semantic_name = name + "_stuffonly" + DatasetCatalog.register(semantic_name, lambda: load_sem_seg(sem_seg_root, image_root)) + MetadataCatalog.get(semantic_name).set( + sem_seg_root=sem_seg_root, + image_root=image_root, + evaluator_type="sem_seg", + ignore_label=255, + **metadata, + ) + + +def merge_to_panoptic(detection_dicts, sem_seg_dicts): + """ + Create dataset dicts for panoptic segmentation, by + merging two dicts using "file_name" field to match their entries. + + Args: + detection_dicts (list[dict]): lists of dicts for object detection or instance segmentation. + sem_seg_dicts (list[dict]): lists of dicts for semantic segmentation. + + Returns: + list[dict] (one per input image): Each dict contains all (key, value) pairs from dicts in + both detection_dicts and sem_seg_dicts that correspond to the same image. + The function assumes that the same key in different dicts has the same value. + """ + results = [] + sem_seg_file_to_entry = {x["file_name"]: x for x in sem_seg_dicts} + assert len(sem_seg_file_to_entry) > 0 + + for det_dict in detection_dicts: + dic = copy.copy(det_dict) + dic.update(sem_seg_file_to_entry[dic["file_name"]]) + results.append(dic) + return results + + +if __name__ == "__main__": + """ + Test the COCO panoptic dataset loader. + + Usage: + python -m detectron2.data.datasets.coco_panoptic \ + path/to/image_root path/to/panoptic_root path/to/panoptic_json dataset_name 10 + + "dataset_name" can be "coco_2017_train_panoptic", or other + pre-registered ones + """ + from annotator.oneformer.detectron2.utils.logger import setup_logger + from annotator.oneformer.detectron2.utils.visualizer import Visualizer + import annotator.oneformer.detectron2.data.datasets # noqa # add pre-defined metadata + import sys + from PIL import Image + import numpy as np + + logger = setup_logger(name=__name__) + assert sys.argv[4] in DatasetCatalog.list() + meta = MetadataCatalog.get(sys.argv[4]) + + dicts = load_coco_panoptic_json(sys.argv[3], sys.argv[1], sys.argv[2], meta.as_dict()) + logger.info("Done loading {} samples.".format(len(dicts))) + + dirname = "coco-data-vis" + os.makedirs(dirname, exist_ok=True) + num_imgs_to_vis = int(sys.argv[5]) + for i, d in enumerate(dicts): + img = np.array(Image.open(d["file_name"])) + visualizer = Visualizer(img, metadata=meta) + vis = visualizer.draw_dataset_dict(d) + fpath = os.path.join(dirname, os.path.basename(d["file_name"])) + vis.save(fpath) + if i + 1 >= num_imgs_to_vis: + break diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/lvis.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/lvis.py new file mode 100644 index 00000000..6e1e6ecc --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/lvis.py @@ -0,0 +1,241 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import logging +import os +from fvcore.common.timer import Timer + +from annotator.oneformer.detectron2.data import DatasetCatalog, MetadataCatalog +from annotator.oneformer.detectron2.structures import BoxMode +from annotator.oneformer.detectron2.utils.file_io import PathManager + +from .builtin_meta import _get_coco_instances_meta +from .lvis_v0_5_categories import LVIS_CATEGORIES as LVIS_V0_5_CATEGORIES +from .lvis_v1_categories import LVIS_CATEGORIES as LVIS_V1_CATEGORIES +from .lvis_v1_category_image_count import LVIS_CATEGORY_IMAGE_COUNT as LVIS_V1_CATEGORY_IMAGE_COUNT + +""" +This file contains functions to parse LVIS-format annotations into dicts in the +"Detectron2 format". +""" + +logger = logging.getLogger(__name__) + +__all__ = ["load_lvis_json", "register_lvis_instances", "get_lvis_instances_meta"] + + +def register_lvis_instances(name, metadata, json_file, image_root): + """ + Register a dataset in LVIS's json annotation format for instance detection and segmentation. + + Args: + name (str): a name that identifies the dataset, e.g. "lvis_v0.5_train". + metadata (dict): extra metadata associated with this dataset. It can be an empty dict. + json_file (str): path to the json instance annotation file. + image_root (str or path-like): directory which contains all the images. + """ + DatasetCatalog.register(name, lambda: load_lvis_json(json_file, image_root, name)) + MetadataCatalog.get(name).set( + json_file=json_file, image_root=image_root, evaluator_type="lvis", **metadata + ) + + +def load_lvis_json(json_file, image_root, dataset_name=None, extra_annotation_keys=None): + """ + Load a json file in LVIS's annotation format. + + Args: + json_file (str): full path to the LVIS json annotation file. + image_root (str): the directory where the images in this json file exists. + dataset_name (str): the name of the dataset (e.g., "lvis_v0.5_train"). + If provided, this function will put "thing_classes" into the metadata + associated with this dataset. + extra_annotation_keys (list[str]): list of per-annotation keys that should also be + loaded into the dataset dict (besides "bbox", "bbox_mode", "category_id", + "segmentation"). The values for these keys will be returned as-is. + + Returns: + list[dict]: a list of dicts in Detectron2 standard format. (See + `Using Custom Datasets `_ ) + + Notes: + 1. This function does not read the image files. + The results do not have the "image" field. + """ + from lvis import LVIS + + json_file = PathManager.get_local_path(json_file) + + timer = Timer() + lvis_api = LVIS(json_file) + if timer.seconds() > 1: + logger.info("Loading {} takes {:.2f} seconds.".format(json_file, timer.seconds())) + + if dataset_name is not None: + meta = get_lvis_instances_meta(dataset_name) + MetadataCatalog.get(dataset_name).set(**meta) + + # sort indices for reproducible results + img_ids = sorted(lvis_api.imgs.keys()) + # imgs is a list of dicts, each looks something like: + # {'license': 4, + # 'url': 'http://farm6.staticflickr.com/5454/9413846304_881d5e5c3b_z.jpg', + # 'file_name': 'COCO_val2014_000000001268.jpg', + # 'height': 427, + # 'width': 640, + # 'date_captured': '2013-11-17 05:57:24', + # 'id': 1268} + imgs = lvis_api.load_imgs(img_ids) + # anns is a list[list[dict]], where each dict is an annotation + # record for an object. The inner list enumerates the objects in an image + # and the outer list enumerates over images. Example of anns[0]: + # [{'segmentation': [[192.81, + # 247.09, + # ... + # 219.03, + # 249.06]], + # 'area': 1035.749, + # 'image_id': 1268, + # 'bbox': [192.81, 224.8, 74.73, 33.43], + # 'category_id': 16, + # 'id': 42986}, + # ...] + anns = [lvis_api.img_ann_map[img_id] for img_id in img_ids] + + # Sanity check that each annotation has a unique id + ann_ids = [ann["id"] for anns_per_image in anns for ann in anns_per_image] + assert len(set(ann_ids)) == len(ann_ids), "Annotation ids in '{}' are not unique".format( + json_file + ) + + imgs_anns = list(zip(imgs, anns)) + + logger.info("Loaded {} images in the LVIS format from {}".format(len(imgs_anns), json_file)) + + if extra_annotation_keys: + logger.info( + "The following extra annotation keys will be loaded: {} ".format(extra_annotation_keys) + ) + else: + extra_annotation_keys = [] + + def get_file_name(img_root, img_dict): + # Determine the path including the split folder ("train2017", "val2017", "test2017") from + # the coco_url field. Example: + # 'coco_url': 'http://images.cocodataset.org/train2017/000000155379.jpg' + split_folder, file_name = img_dict["coco_url"].split("/")[-2:] + return os.path.join(img_root + split_folder, file_name) + + dataset_dicts = [] + + for (img_dict, anno_dict_list) in imgs_anns: + record = {} + record["file_name"] = get_file_name(image_root, img_dict) + record["height"] = img_dict["height"] + record["width"] = img_dict["width"] + record["not_exhaustive_category_ids"] = img_dict.get("not_exhaustive_category_ids", []) + record["neg_category_ids"] = img_dict.get("neg_category_ids", []) + image_id = record["image_id"] = img_dict["id"] + + objs = [] + for anno in anno_dict_list: + # Check that the image_id in this annotation is the same as + # the image_id we're looking at. + # This fails only when the data parsing logic or the annotation file is buggy. + assert anno["image_id"] == image_id + obj = {"bbox": anno["bbox"], "bbox_mode": BoxMode.XYWH_ABS} + # LVIS data loader can be used to load COCO dataset categories. In this case `meta` + # variable will have a field with COCO-specific category mapping. + if dataset_name is not None and "thing_dataset_id_to_contiguous_id" in meta: + obj["category_id"] = meta["thing_dataset_id_to_contiguous_id"][anno["category_id"]] + else: + obj["category_id"] = anno["category_id"] - 1 # Convert 1-indexed to 0-indexed + segm = anno["segmentation"] # list[list[float]] + # filter out invalid polygons (< 3 points) + valid_segm = [poly for poly in segm if len(poly) % 2 == 0 and len(poly) >= 6] + assert len(segm) == len( + valid_segm + ), "Annotation contains an invalid polygon with < 3 points" + assert len(segm) > 0 + obj["segmentation"] = segm + for extra_ann_key in extra_annotation_keys: + obj[extra_ann_key] = anno[extra_ann_key] + objs.append(obj) + record["annotations"] = objs + dataset_dicts.append(record) + + return dataset_dicts + + +def get_lvis_instances_meta(dataset_name): + """ + Load LVIS metadata. + + Args: + dataset_name (str): LVIS dataset name without the split name (e.g., "lvis_v0.5"). + + Returns: + dict: LVIS metadata with keys: thing_classes + """ + if "cocofied" in dataset_name: + return _get_coco_instances_meta() + if "v0.5" in dataset_name: + return _get_lvis_instances_meta_v0_5() + elif "v1" in dataset_name: + return _get_lvis_instances_meta_v1() + raise ValueError("No built-in metadata for dataset {}".format(dataset_name)) + + +def _get_lvis_instances_meta_v0_5(): + assert len(LVIS_V0_5_CATEGORIES) == 1230 + cat_ids = [k["id"] for k in LVIS_V0_5_CATEGORIES] + assert min(cat_ids) == 1 and max(cat_ids) == len( + cat_ids + ), "Category ids are not in [1, #categories], as expected" + # Ensure that the category list is sorted by id + lvis_categories = sorted(LVIS_V0_5_CATEGORIES, key=lambda x: x["id"]) + thing_classes = [k["synonyms"][0] for k in lvis_categories] + meta = {"thing_classes": thing_classes} + return meta + + +def _get_lvis_instances_meta_v1(): + assert len(LVIS_V1_CATEGORIES) == 1203 + cat_ids = [k["id"] for k in LVIS_V1_CATEGORIES] + assert min(cat_ids) == 1 and max(cat_ids) == len( + cat_ids + ), "Category ids are not in [1, #categories], as expected" + # Ensure that the category list is sorted by id + lvis_categories = sorted(LVIS_V1_CATEGORIES, key=lambda x: x["id"]) + thing_classes = [k["synonyms"][0] for k in lvis_categories] + meta = {"thing_classes": thing_classes, "class_image_count": LVIS_V1_CATEGORY_IMAGE_COUNT} + return meta + + +if __name__ == "__main__": + """ + Test the LVIS json dataset loader. + + Usage: + python -m detectron2.data.datasets.lvis \ + path/to/json path/to/image_root dataset_name vis_limit + """ + import sys + import numpy as np + from annotator.oneformer.detectron2.utils.logger import setup_logger + from PIL import Image + import annotator.oneformer.detectron2.data.datasets # noqa # add pre-defined metadata + from annotator.oneformer.detectron2.utils.visualizer import Visualizer + + logger = setup_logger(name=__name__) + meta = MetadataCatalog.get(sys.argv[3]) + + dicts = load_lvis_json(sys.argv[1], sys.argv[2], sys.argv[3]) + logger.info("Done loading {} samples.".format(len(dicts))) + + dirname = "lvis-data-vis" + os.makedirs(dirname, exist_ok=True) + for d in dicts[: int(sys.argv[4])]: + img = np.array(Image.open(d["file_name"])) + visualizer = Visualizer(img, metadata=meta) + vis = visualizer.draw_dataset_dict(d) + fpath = os.path.join(dirname, os.path.basename(d["file_name"])) + vis.save(fpath) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/lvis_v0_5_categories.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/lvis_v0_5_categories.py new file mode 100644 index 00000000..d3dab619 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/lvis_v0_5_categories.py @@ -0,0 +1,13 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# Autogen with +# with open("lvis_v0.5_val.json", "r") as f: +# a = json.load(f) +# c = a["categories"] +# for x in c: +# del x["image_count"] +# del x["instance_count"] +# LVIS_CATEGORIES = repr(c) + " # noqa" + +# fmt: off +LVIS_CATEGORIES = [{'frequency': 'r', 'id': 1, 'synset': 'acorn.n.01', 'synonyms': ['acorn'], 'def': 'nut from an oak tree', 'name': 'acorn'}, {'frequency': 'c', 'id': 2, 'synset': 'aerosol.n.02', 'synonyms': ['aerosol_can', 'spray_can'], 'def': 'a dispenser that holds a substance under pressure', 'name': 'aerosol_can'}, {'frequency': 'f', 'id': 3, 'synset': 'air_conditioner.n.01', 'synonyms': ['air_conditioner'], 'def': 'a machine that keeps air cool and dry', 'name': 'air_conditioner'}, {'frequency': 'f', 'id': 4, 'synset': 'airplane.n.01', 'synonyms': ['airplane', 'aeroplane'], 'def': 'an aircraft that has a fixed wing and is powered by propellers or jets', 'name': 'airplane'}, {'frequency': 'c', 'id': 5, 'synset': 'alarm_clock.n.01', 'synonyms': ['alarm_clock'], 'def': 'a clock that wakes a sleeper at some preset time', 'name': 'alarm_clock'}, {'frequency': 'c', 'id': 6, 'synset': 'alcohol.n.01', 'synonyms': ['alcohol', 'alcoholic_beverage'], 'def': 'a liquor or brew containing alcohol as the active agent', 'name': 'alcohol'}, {'frequency': 'r', 'id': 7, 'synset': 'alligator.n.02', 'synonyms': ['alligator', 'gator'], 'def': 'amphibious reptiles related to crocodiles but with shorter broader snouts', 'name': 'alligator'}, {'frequency': 'c', 'id': 8, 'synset': 'almond.n.02', 'synonyms': ['almond'], 'def': 'oval-shaped edible seed of the almond tree', 'name': 'almond'}, {'frequency': 'c', 'id': 9, 'synset': 'ambulance.n.01', 'synonyms': ['ambulance'], 'def': 'a vehicle that takes people to and from hospitals', 'name': 'ambulance'}, {'frequency': 'r', 'id': 10, 'synset': 'amplifier.n.01', 'synonyms': ['amplifier'], 'def': 'electronic equipment that increases strength of signals', 'name': 'amplifier'}, {'frequency': 'c', 'id': 11, 'synset': 'anklet.n.03', 'synonyms': ['anklet', 'ankle_bracelet'], 'def': 'an ornament worn around the ankle', 'name': 'anklet'}, {'frequency': 'f', 'id': 12, 'synset': 'antenna.n.01', 'synonyms': ['antenna', 'aerial', 'transmitting_aerial'], 'def': 'an electrical device that sends or receives radio or television signals', 'name': 'antenna'}, {'frequency': 'f', 'id': 13, 'synset': 'apple.n.01', 'synonyms': ['apple'], 'def': 'fruit with red or yellow or green skin and sweet to tart crisp whitish flesh', 'name': 'apple'}, {'frequency': 'r', 'id': 14, 'synset': 'apple_juice.n.01', 'synonyms': ['apple_juice'], 'def': 'the juice of apples', 'name': 'apple_juice'}, {'frequency': 'r', 'id': 15, 'synset': 'applesauce.n.01', 'synonyms': ['applesauce'], 'def': 'puree of stewed apples usually sweetened and spiced', 'name': 'applesauce'}, {'frequency': 'r', 'id': 16, 'synset': 'apricot.n.02', 'synonyms': ['apricot'], 'def': 'downy yellow to rosy-colored fruit resembling a small peach', 'name': 'apricot'}, {'frequency': 'f', 'id': 17, 'synset': 'apron.n.01', 'synonyms': ['apron'], 'def': 'a garment of cloth that is tied about the waist and worn to protect clothing', 'name': 'apron'}, {'frequency': 'c', 'id': 18, 'synset': 'aquarium.n.01', 'synonyms': ['aquarium', 'fish_tank'], 'def': 'a tank/pool/bowl filled with water for keeping live fish and underwater animals', 'name': 'aquarium'}, {'frequency': 'c', 'id': 19, 'synset': 'armband.n.02', 'synonyms': ['armband'], 'def': 'a band worn around the upper arm', 'name': 'armband'}, {'frequency': 'f', 'id': 20, 'synset': 'armchair.n.01', 'synonyms': ['armchair'], 'def': 'chair with a support on each side for arms', 'name': 'armchair'}, {'frequency': 'r', 'id': 21, 'synset': 'armoire.n.01', 'synonyms': ['armoire'], 'def': 'a large wardrobe or cabinet', 'name': 'armoire'}, {'frequency': 'r', 'id': 22, 'synset': 'armor.n.01', 'synonyms': ['armor', 'armour'], 'def': 'protective covering made of metal and used in combat', 'name': 'armor'}, {'frequency': 'c', 'id': 23, 'synset': 'artichoke.n.02', 'synonyms': ['artichoke'], 'def': 'a thistlelike flower head with edible fleshy leaves and heart', 'name': 'artichoke'}, {'frequency': 'f', 'id': 24, 'synset': 'ashcan.n.01', 'synonyms': ['trash_can', 'garbage_can', 'wastebin', 'dustbin', 'trash_barrel', 'trash_bin'], 'def': 'a bin that holds rubbish until it is collected', 'name': 'trash_can'}, {'frequency': 'c', 'id': 25, 'synset': 'ashtray.n.01', 'synonyms': ['ashtray'], 'def': "a receptacle for the ash from smokers' cigars or cigarettes", 'name': 'ashtray'}, {'frequency': 'c', 'id': 26, 'synset': 'asparagus.n.02', 'synonyms': ['asparagus'], 'def': 'edible young shoots of the asparagus plant', 'name': 'asparagus'}, {'frequency': 'c', 'id': 27, 'synset': 'atomizer.n.01', 'synonyms': ['atomizer', 'atomiser', 'spray', 'sprayer', 'nebulizer', 'nebuliser'], 'def': 'a dispenser that turns a liquid (such as perfume) into a fine mist', 'name': 'atomizer'}, {'frequency': 'c', 'id': 28, 'synset': 'avocado.n.01', 'synonyms': ['avocado'], 'def': 'a pear-shaped fruit with green or blackish skin and rich yellowish pulp enclosing a single large seed', 'name': 'avocado'}, {'frequency': 'c', 'id': 29, 'synset': 'award.n.02', 'synonyms': ['award', 'accolade'], 'def': 'a tangible symbol signifying approval or distinction', 'name': 'award'}, {'frequency': 'f', 'id': 30, 'synset': 'awning.n.01', 'synonyms': ['awning'], 'def': 'a canopy made of canvas to shelter people or things from rain or sun', 'name': 'awning'}, {'frequency': 'r', 'id': 31, 'synset': 'ax.n.01', 'synonyms': ['ax', 'axe'], 'def': 'an edge tool with a heavy bladed head mounted across a handle', 'name': 'ax'}, {'frequency': 'f', 'id': 32, 'synset': 'baby_buggy.n.01', 'synonyms': ['baby_buggy', 'baby_carriage', 'perambulator', 'pram', 'stroller'], 'def': 'a small vehicle with four wheels in which a baby or child is pushed around', 'name': 'baby_buggy'}, {'frequency': 'c', 'id': 33, 'synset': 'backboard.n.01', 'synonyms': ['basketball_backboard'], 'def': 'a raised vertical board with basket attached; used to play basketball', 'name': 'basketball_backboard'}, {'frequency': 'f', 'id': 34, 'synset': 'backpack.n.01', 'synonyms': ['backpack', 'knapsack', 'packsack', 'rucksack', 'haversack'], 'def': 'a bag carried by a strap on your back or shoulder', 'name': 'backpack'}, {'frequency': 'f', 'id': 35, 'synset': 'bag.n.04', 'synonyms': ['handbag', 'purse', 'pocketbook'], 'def': 'a container used for carrying money and small personal items or accessories', 'name': 'handbag'}, {'frequency': 'f', 'id': 36, 'synset': 'bag.n.06', 'synonyms': ['suitcase', 'baggage', 'luggage'], 'def': 'cases used to carry belongings when traveling', 'name': 'suitcase'}, {'frequency': 'c', 'id': 37, 'synset': 'bagel.n.01', 'synonyms': ['bagel', 'beigel'], 'def': 'glazed yeast-raised doughnut-shaped roll with hard crust', 'name': 'bagel'}, {'frequency': 'r', 'id': 38, 'synset': 'bagpipe.n.01', 'synonyms': ['bagpipe'], 'def': 'a tubular wind instrument; the player blows air into a bag and squeezes it out', 'name': 'bagpipe'}, {'frequency': 'r', 'id': 39, 'synset': 'baguet.n.01', 'synonyms': ['baguet', 'baguette'], 'def': 'narrow French stick loaf', 'name': 'baguet'}, {'frequency': 'r', 'id': 40, 'synset': 'bait.n.02', 'synonyms': ['bait', 'lure'], 'def': 'something used to lure fish or other animals into danger so they can be trapped or killed', 'name': 'bait'}, {'frequency': 'f', 'id': 41, 'synset': 'ball.n.06', 'synonyms': ['ball'], 'def': 'a spherical object used as a plaything', 'name': 'ball'}, {'frequency': 'r', 'id': 42, 'synset': 'ballet_skirt.n.01', 'synonyms': ['ballet_skirt', 'tutu'], 'def': 'very short skirt worn by ballerinas', 'name': 'ballet_skirt'}, {'frequency': 'f', 'id': 43, 'synset': 'balloon.n.01', 'synonyms': ['balloon'], 'def': 'large tough nonrigid bag filled with gas or heated air', 'name': 'balloon'}, {'frequency': 'c', 'id': 44, 'synset': 'bamboo.n.02', 'synonyms': ['bamboo'], 'def': 'woody tropical grass having hollow woody stems', 'name': 'bamboo'}, {'frequency': 'f', 'id': 45, 'synset': 'banana.n.02', 'synonyms': ['banana'], 'def': 'elongated crescent-shaped yellow fruit with soft sweet flesh', 'name': 'banana'}, {'frequency': 'r', 'id': 46, 'synset': 'band_aid.n.01', 'synonyms': ['Band_Aid'], 'def': 'trade name for an adhesive bandage to cover small cuts or blisters', 'name': 'Band_Aid'}, {'frequency': 'c', 'id': 47, 'synset': 'bandage.n.01', 'synonyms': ['bandage'], 'def': 'a piece of soft material that covers and protects an injured part of the body', 'name': 'bandage'}, {'frequency': 'c', 'id': 48, 'synset': 'bandanna.n.01', 'synonyms': ['bandanna', 'bandana'], 'def': 'large and brightly colored handkerchief; often used as a neckerchief', 'name': 'bandanna'}, {'frequency': 'r', 'id': 49, 'synset': 'banjo.n.01', 'synonyms': ['banjo'], 'def': 'a stringed instrument of the guitar family with a long neck and circular body', 'name': 'banjo'}, {'frequency': 'f', 'id': 50, 'synset': 'banner.n.01', 'synonyms': ['banner', 'streamer'], 'def': 'long strip of cloth or paper used for decoration or advertising', 'name': 'banner'}, {'frequency': 'r', 'id': 51, 'synset': 'barbell.n.01', 'synonyms': ['barbell'], 'def': 'a bar to which heavy discs are attached at each end; used in weightlifting', 'name': 'barbell'}, {'frequency': 'r', 'id': 52, 'synset': 'barge.n.01', 'synonyms': ['barge'], 'def': 'a flatbottom boat for carrying heavy loads (especially on canals)', 'name': 'barge'}, {'frequency': 'f', 'id': 53, 'synset': 'barrel.n.02', 'synonyms': ['barrel', 'cask'], 'def': 'a cylindrical container that holds liquids', 'name': 'barrel'}, {'frequency': 'c', 'id': 54, 'synset': 'barrette.n.01', 'synonyms': ['barrette'], 'def': "a pin for holding women's hair in place", 'name': 'barrette'}, {'frequency': 'c', 'id': 55, 'synset': 'barrow.n.03', 'synonyms': ['barrow', 'garden_cart', 'lawn_cart', 'wheelbarrow'], 'def': 'a cart for carrying small loads; has handles and one or more wheels', 'name': 'barrow'}, {'frequency': 'f', 'id': 56, 'synset': 'base.n.03', 'synonyms': ['baseball_base'], 'def': 'a place that the runner must touch before scoring', 'name': 'baseball_base'}, {'frequency': 'f', 'id': 57, 'synset': 'baseball.n.02', 'synonyms': ['baseball'], 'def': 'a ball used in playing baseball', 'name': 'baseball'}, {'frequency': 'f', 'id': 58, 'synset': 'baseball_bat.n.01', 'synonyms': ['baseball_bat'], 'def': 'an implement used in baseball by the batter', 'name': 'baseball_bat'}, {'frequency': 'f', 'id': 59, 'synset': 'baseball_cap.n.01', 'synonyms': ['baseball_cap', 'jockey_cap', 'golf_cap'], 'def': 'a cap with a bill', 'name': 'baseball_cap'}, {'frequency': 'f', 'id': 60, 'synset': 'baseball_glove.n.01', 'synonyms': ['baseball_glove', 'baseball_mitt'], 'def': 'the handwear used by fielders in playing baseball', 'name': 'baseball_glove'}, {'frequency': 'f', 'id': 61, 'synset': 'basket.n.01', 'synonyms': ['basket', 'handbasket'], 'def': 'a container that is usually woven and has handles', 'name': 'basket'}, {'frequency': 'c', 'id': 62, 'synset': 'basket.n.03', 'synonyms': ['basketball_hoop'], 'def': 'metal hoop supporting a net through which players try to throw the basketball', 'name': 'basketball_hoop'}, {'frequency': 'c', 'id': 63, 'synset': 'basketball.n.02', 'synonyms': ['basketball'], 'def': 'an inflated ball used in playing basketball', 'name': 'basketball'}, {'frequency': 'r', 'id': 64, 'synset': 'bass_horn.n.01', 'synonyms': ['bass_horn', 'sousaphone', 'tuba'], 'def': 'the lowest brass wind instrument', 'name': 'bass_horn'}, {'frequency': 'r', 'id': 65, 'synset': 'bat.n.01', 'synonyms': ['bat_(animal)'], 'def': 'nocturnal mouselike mammal with forelimbs modified to form membranous wings', 'name': 'bat_(animal)'}, {'frequency': 'f', 'id': 66, 'synset': 'bath_mat.n.01', 'synonyms': ['bath_mat'], 'def': 'a heavy towel or mat to stand on while drying yourself after a bath', 'name': 'bath_mat'}, {'frequency': 'f', 'id': 67, 'synset': 'bath_towel.n.01', 'synonyms': ['bath_towel'], 'def': 'a large towel; to dry yourself after a bath', 'name': 'bath_towel'}, {'frequency': 'c', 'id': 68, 'synset': 'bathrobe.n.01', 'synonyms': ['bathrobe'], 'def': 'a loose-fitting robe of towelling; worn after a bath or swim', 'name': 'bathrobe'}, {'frequency': 'f', 'id': 69, 'synset': 'bathtub.n.01', 'synonyms': ['bathtub', 'bathing_tub'], 'def': 'a large open container that you fill with water and use to wash the body', 'name': 'bathtub'}, {'frequency': 'r', 'id': 70, 'synset': 'batter.n.02', 'synonyms': ['batter_(food)'], 'def': 'a liquid or semiliquid mixture, as of flour, eggs, and milk, used in cooking', 'name': 'batter_(food)'}, {'frequency': 'c', 'id': 71, 'synset': 'battery.n.02', 'synonyms': ['battery'], 'def': 'a portable device that produces electricity', 'name': 'battery'}, {'frequency': 'r', 'id': 72, 'synset': 'beach_ball.n.01', 'synonyms': ['beachball'], 'def': 'large and light ball; for play at the seaside', 'name': 'beachball'}, {'frequency': 'c', 'id': 73, 'synset': 'bead.n.01', 'synonyms': ['bead'], 'def': 'a small ball with a hole through the middle used for ornamentation, jewellery, etc.', 'name': 'bead'}, {'frequency': 'r', 'id': 74, 'synset': 'beaker.n.01', 'synonyms': ['beaker'], 'def': 'a flatbottomed jar made of glass or plastic; used for chemistry', 'name': 'beaker'}, {'frequency': 'c', 'id': 75, 'synset': 'bean_curd.n.01', 'synonyms': ['bean_curd', 'tofu'], 'def': 'cheeselike food made of curdled soybean milk', 'name': 'bean_curd'}, {'frequency': 'c', 'id': 76, 'synset': 'beanbag.n.01', 'synonyms': ['beanbag'], 'def': 'a bag filled with dried beans or similar items; used in games or to sit on', 'name': 'beanbag'}, {'frequency': 'f', 'id': 77, 'synset': 'beanie.n.01', 'synonyms': ['beanie', 'beany'], 'def': 'a small skullcap; formerly worn by schoolboys and college freshmen', 'name': 'beanie'}, {'frequency': 'f', 'id': 78, 'synset': 'bear.n.01', 'synonyms': ['bear'], 'def': 'large carnivorous or omnivorous mammals with shaggy coats and claws', 'name': 'bear'}, {'frequency': 'f', 'id': 79, 'synset': 'bed.n.01', 'synonyms': ['bed'], 'def': 'a piece of furniture that provides a place to sleep', 'name': 'bed'}, {'frequency': 'c', 'id': 80, 'synset': 'bedspread.n.01', 'synonyms': ['bedspread', 'bedcover', 'bed_covering', 'counterpane', 'spread'], 'def': 'decorative cover for a bed', 'name': 'bedspread'}, {'frequency': 'f', 'id': 81, 'synset': 'beef.n.01', 'synonyms': ['cow'], 'def': 'cattle that are reared for their meat', 'name': 'cow'}, {'frequency': 'c', 'id': 82, 'synset': 'beef.n.02', 'synonyms': ['beef_(food)', 'boeuf_(food)'], 'def': 'meat from an adult domestic bovine', 'name': 'beef_(food)'}, {'frequency': 'r', 'id': 83, 'synset': 'beeper.n.01', 'synonyms': ['beeper', 'pager'], 'def': 'an device that beeps when the person carrying it is being paged', 'name': 'beeper'}, {'frequency': 'f', 'id': 84, 'synset': 'beer_bottle.n.01', 'synonyms': ['beer_bottle'], 'def': 'a bottle that holds beer', 'name': 'beer_bottle'}, {'frequency': 'c', 'id': 85, 'synset': 'beer_can.n.01', 'synonyms': ['beer_can'], 'def': 'a can that holds beer', 'name': 'beer_can'}, {'frequency': 'r', 'id': 86, 'synset': 'beetle.n.01', 'synonyms': ['beetle'], 'def': 'insect with hard wing covers', 'name': 'beetle'}, {'frequency': 'f', 'id': 87, 'synset': 'bell.n.01', 'synonyms': ['bell'], 'def': 'a hollow device made of metal that makes a ringing sound when struck', 'name': 'bell'}, {'frequency': 'f', 'id': 88, 'synset': 'bell_pepper.n.02', 'synonyms': ['bell_pepper', 'capsicum'], 'def': 'large bell-shaped sweet pepper in green or red or yellow or orange or black varieties', 'name': 'bell_pepper'}, {'frequency': 'f', 'id': 89, 'synset': 'belt.n.02', 'synonyms': ['belt'], 'def': 'a band to tie or buckle around the body (usually at the waist)', 'name': 'belt'}, {'frequency': 'f', 'id': 90, 'synset': 'belt_buckle.n.01', 'synonyms': ['belt_buckle'], 'def': 'the buckle used to fasten a belt', 'name': 'belt_buckle'}, {'frequency': 'f', 'id': 91, 'synset': 'bench.n.01', 'synonyms': ['bench'], 'def': 'a long seat for more than one person', 'name': 'bench'}, {'frequency': 'c', 'id': 92, 'synset': 'beret.n.01', 'synonyms': ['beret'], 'def': 'a cap with no brim or bill; made of soft cloth', 'name': 'beret'}, {'frequency': 'c', 'id': 93, 'synset': 'bib.n.02', 'synonyms': ['bib'], 'def': 'a napkin tied under the chin of a child while eating', 'name': 'bib'}, {'frequency': 'r', 'id': 94, 'synset': 'bible.n.01', 'synonyms': ['Bible'], 'def': 'the sacred writings of the Christian religions', 'name': 'Bible'}, {'frequency': 'f', 'id': 95, 'synset': 'bicycle.n.01', 'synonyms': ['bicycle', 'bike_(bicycle)'], 'def': 'a wheeled vehicle that has two wheels and is moved by foot pedals', 'name': 'bicycle'}, {'frequency': 'f', 'id': 96, 'synset': 'bill.n.09', 'synonyms': ['visor', 'vizor'], 'def': 'a brim that projects to the front to shade the eyes', 'name': 'visor'}, {'frequency': 'c', 'id': 97, 'synset': 'binder.n.03', 'synonyms': ['binder', 'ring-binder'], 'def': 'holds loose papers or magazines', 'name': 'binder'}, {'frequency': 'c', 'id': 98, 'synset': 'binoculars.n.01', 'synonyms': ['binoculars', 'field_glasses', 'opera_glasses'], 'def': 'an optical instrument designed for simultaneous use by both eyes', 'name': 'binoculars'}, {'frequency': 'f', 'id': 99, 'synset': 'bird.n.01', 'synonyms': ['bird'], 'def': 'animal characterized by feathers and wings', 'name': 'bird'}, {'frequency': 'r', 'id': 100, 'synset': 'bird_feeder.n.01', 'synonyms': ['birdfeeder'], 'def': 'an outdoor device that supplies food for wild birds', 'name': 'birdfeeder'}, {'frequency': 'r', 'id': 101, 'synset': 'birdbath.n.01', 'synonyms': ['birdbath'], 'def': 'an ornamental basin (usually in a garden) for birds to bathe in', 'name': 'birdbath'}, {'frequency': 'c', 'id': 102, 'synset': 'birdcage.n.01', 'synonyms': ['birdcage'], 'def': 'a cage in which a bird can be kept', 'name': 'birdcage'}, {'frequency': 'c', 'id': 103, 'synset': 'birdhouse.n.01', 'synonyms': ['birdhouse'], 'def': 'a shelter for birds', 'name': 'birdhouse'}, {'frequency': 'f', 'id': 104, 'synset': 'birthday_cake.n.01', 'synonyms': ['birthday_cake'], 'def': 'decorated cake served at a birthday party', 'name': 'birthday_cake'}, {'frequency': 'r', 'id': 105, 'synset': 'birthday_card.n.01', 'synonyms': ['birthday_card'], 'def': 'a card expressing a birthday greeting', 'name': 'birthday_card'}, {'frequency': 'r', 'id': 106, 'synset': 'biscuit.n.01', 'synonyms': ['biscuit_(bread)'], 'def': 'small round bread leavened with baking-powder or soda', 'name': 'biscuit_(bread)'}, {'frequency': 'r', 'id': 107, 'synset': 'black_flag.n.01', 'synonyms': ['pirate_flag'], 'def': 'a flag usually bearing a white skull and crossbones on a black background', 'name': 'pirate_flag'}, {'frequency': 'c', 'id': 108, 'synset': 'black_sheep.n.02', 'synonyms': ['black_sheep'], 'def': 'sheep with a black coat', 'name': 'black_sheep'}, {'frequency': 'c', 'id': 109, 'synset': 'blackboard.n.01', 'synonyms': ['blackboard', 'chalkboard'], 'def': 'sheet of slate; for writing with chalk', 'name': 'blackboard'}, {'frequency': 'f', 'id': 110, 'synset': 'blanket.n.01', 'synonyms': ['blanket'], 'def': 'bedding that keeps a person warm in bed', 'name': 'blanket'}, {'frequency': 'c', 'id': 111, 'synset': 'blazer.n.01', 'synonyms': ['blazer', 'sport_jacket', 'sport_coat', 'sports_jacket', 'sports_coat'], 'def': 'lightweight jacket; often striped in the colors of a club or school', 'name': 'blazer'}, {'frequency': 'f', 'id': 112, 'synset': 'blender.n.01', 'synonyms': ['blender', 'liquidizer', 'liquidiser'], 'def': 'an electrically powered mixer that mix or chop or liquefy foods', 'name': 'blender'}, {'frequency': 'r', 'id': 113, 'synset': 'blimp.n.02', 'synonyms': ['blimp'], 'def': 'a small nonrigid airship used for observation or as a barrage balloon', 'name': 'blimp'}, {'frequency': 'c', 'id': 114, 'synset': 'blinker.n.01', 'synonyms': ['blinker', 'flasher'], 'def': 'a light that flashes on and off; used as a signal or to send messages', 'name': 'blinker'}, {'frequency': 'c', 'id': 115, 'synset': 'blueberry.n.02', 'synonyms': ['blueberry'], 'def': 'sweet edible dark-blue berries of blueberry plants', 'name': 'blueberry'}, {'frequency': 'r', 'id': 116, 'synset': 'boar.n.02', 'synonyms': ['boar'], 'def': 'an uncastrated male hog', 'name': 'boar'}, {'frequency': 'r', 'id': 117, 'synset': 'board.n.09', 'synonyms': ['gameboard'], 'def': 'a flat portable surface (usually rectangular) designed for board games', 'name': 'gameboard'}, {'frequency': 'f', 'id': 118, 'synset': 'boat.n.01', 'synonyms': ['boat', 'ship_(boat)'], 'def': 'a vessel for travel on water', 'name': 'boat'}, {'frequency': 'c', 'id': 119, 'synset': 'bobbin.n.01', 'synonyms': ['bobbin', 'spool', 'reel'], 'def': 'a thing around which thread/tape/film or other flexible materials can be wound', 'name': 'bobbin'}, {'frequency': 'r', 'id': 120, 'synset': 'bobby_pin.n.01', 'synonyms': ['bobby_pin', 'hairgrip'], 'def': 'a flat wire hairpin used to hold bobbed hair in place', 'name': 'bobby_pin'}, {'frequency': 'c', 'id': 121, 'synset': 'boiled_egg.n.01', 'synonyms': ['boiled_egg', 'coddled_egg'], 'def': 'egg cooked briefly in the shell in gently boiling water', 'name': 'boiled_egg'}, {'frequency': 'r', 'id': 122, 'synset': 'bolo_tie.n.01', 'synonyms': ['bolo_tie', 'bolo', 'bola_tie', 'bola'], 'def': 'a cord fastened around the neck with an ornamental clasp and worn as a necktie', 'name': 'bolo_tie'}, {'frequency': 'c', 'id': 123, 'synset': 'bolt.n.03', 'synonyms': ['deadbolt'], 'def': 'the part of a lock that is engaged or withdrawn with a key', 'name': 'deadbolt'}, {'frequency': 'f', 'id': 124, 'synset': 'bolt.n.06', 'synonyms': ['bolt'], 'def': 'a screw that screws into a nut to form a fastener', 'name': 'bolt'}, {'frequency': 'r', 'id': 125, 'synset': 'bonnet.n.01', 'synonyms': ['bonnet'], 'def': 'a hat tied under the chin', 'name': 'bonnet'}, {'frequency': 'f', 'id': 126, 'synset': 'book.n.01', 'synonyms': ['book'], 'def': 'a written work or composition that has been published', 'name': 'book'}, {'frequency': 'r', 'id': 127, 'synset': 'book_bag.n.01', 'synonyms': ['book_bag'], 'def': 'a bag in which students carry their books', 'name': 'book_bag'}, {'frequency': 'c', 'id': 128, 'synset': 'bookcase.n.01', 'synonyms': ['bookcase'], 'def': 'a piece of furniture with shelves for storing books', 'name': 'bookcase'}, {'frequency': 'c', 'id': 129, 'synset': 'booklet.n.01', 'synonyms': ['booklet', 'brochure', 'leaflet', 'pamphlet'], 'def': 'a small book usually having a paper cover', 'name': 'booklet'}, {'frequency': 'r', 'id': 130, 'synset': 'bookmark.n.01', 'synonyms': ['bookmark', 'bookmarker'], 'def': 'a marker (a piece of paper or ribbon) placed between the pages of a book', 'name': 'bookmark'}, {'frequency': 'r', 'id': 131, 'synset': 'boom.n.04', 'synonyms': ['boom_microphone', 'microphone_boom'], 'def': 'a pole carrying an overhead microphone projected over a film or tv set', 'name': 'boom_microphone'}, {'frequency': 'f', 'id': 132, 'synset': 'boot.n.01', 'synonyms': ['boot'], 'def': 'footwear that covers the whole foot and lower leg', 'name': 'boot'}, {'frequency': 'f', 'id': 133, 'synset': 'bottle.n.01', 'synonyms': ['bottle'], 'def': 'a glass or plastic vessel used for storing drinks or other liquids', 'name': 'bottle'}, {'frequency': 'c', 'id': 134, 'synset': 'bottle_opener.n.01', 'synonyms': ['bottle_opener'], 'def': 'an opener for removing caps or corks from bottles', 'name': 'bottle_opener'}, {'frequency': 'c', 'id': 135, 'synset': 'bouquet.n.01', 'synonyms': ['bouquet'], 'def': 'an arrangement of flowers that is usually given as a present', 'name': 'bouquet'}, {'frequency': 'r', 'id': 136, 'synset': 'bow.n.04', 'synonyms': ['bow_(weapon)'], 'def': 'a weapon for shooting arrows', 'name': 'bow_(weapon)'}, {'frequency': 'f', 'id': 137, 'synset': 'bow.n.08', 'synonyms': ['bow_(decorative_ribbons)'], 'def': 'a decorative interlacing of ribbons', 'name': 'bow_(decorative_ribbons)'}, {'frequency': 'f', 'id': 138, 'synset': 'bow_tie.n.01', 'synonyms': ['bow-tie', 'bowtie'], 'def': "a man's tie that ties in a bow", 'name': 'bow-tie'}, {'frequency': 'f', 'id': 139, 'synset': 'bowl.n.03', 'synonyms': ['bowl'], 'def': 'a dish that is round and open at the top for serving foods', 'name': 'bowl'}, {'frequency': 'r', 'id': 140, 'synset': 'bowl.n.08', 'synonyms': ['pipe_bowl'], 'def': 'a small round container that is open at the top for holding tobacco', 'name': 'pipe_bowl'}, {'frequency': 'c', 'id': 141, 'synset': 'bowler_hat.n.01', 'synonyms': ['bowler_hat', 'bowler', 'derby_hat', 'derby', 'plug_hat'], 'def': 'a felt hat that is round and hard with a narrow brim', 'name': 'bowler_hat'}, {'frequency': 'r', 'id': 142, 'synset': 'bowling_ball.n.01', 'synonyms': ['bowling_ball'], 'def': 'a large ball with finger holes used in the sport of bowling', 'name': 'bowling_ball'}, {'frequency': 'r', 'id': 143, 'synset': 'bowling_pin.n.01', 'synonyms': ['bowling_pin'], 'def': 'a club-shaped wooden object used in bowling', 'name': 'bowling_pin'}, {'frequency': 'r', 'id': 144, 'synset': 'boxing_glove.n.01', 'synonyms': ['boxing_glove'], 'def': 'large glove coverings the fists of a fighter worn for the sport of boxing', 'name': 'boxing_glove'}, {'frequency': 'c', 'id': 145, 'synset': 'brace.n.06', 'synonyms': ['suspenders'], 'def': 'elastic straps that hold trousers up (usually used in the plural)', 'name': 'suspenders'}, {'frequency': 'f', 'id': 146, 'synset': 'bracelet.n.02', 'synonyms': ['bracelet', 'bangle'], 'def': 'jewelry worn around the wrist for decoration', 'name': 'bracelet'}, {'frequency': 'r', 'id': 147, 'synset': 'brass.n.07', 'synonyms': ['brass_plaque'], 'def': 'a memorial made of brass', 'name': 'brass_plaque'}, {'frequency': 'c', 'id': 148, 'synset': 'brassiere.n.01', 'synonyms': ['brassiere', 'bra', 'bandeau'], 'def': 'an undergarment worn by women to support their breasts', 'name': 'brassiere'}, {'frequency': 'c', 'id': 149, 'synset': 'bread-bin.n.01', 'synonyms': ['bread-bin', 'breadbox'], 'def': 'a container used to keep bread or cake in', 'name': 'bread-bin'}, {'frequency': 'r', 'id': 150, 'synset': 'breechcloth.n.01', 'synonyms': ['breechcloth', 'breechclout', 'loincloth'], 'def': 'a garment that provides covering for the loins', 'name': 'breechcloth'}, {'frequency': 'c', 'id': 151, 'synset': 'bridal_gown.n.01', 'synonyms': ['bridal_gown', 'wedding_gown', 'wedding_dress'], 'def': 'a gown worn by the bride at a wedding', 'name': 'bridal_gown'}, {'frequency': 'c', 'id': 152, 'synset': 'briefcase.n.01', 'synonyms': ['briefcase'], 'def': 'a case with a handle; for carrying papers or files or books', 'name': 'briefcase'}, {'frequency': 'c', 'id': 153, 'synset': 'bristle_brush.n.01', 'synonyms': ['bristle_brush'], 'def': 'a brush that is made with the short stiff hairs of an animal or plant', 'name': 'bristle_brush'}, {'frequency': 'f', 'id': 154, 'synset': 'broccoli.n.01', 'synonyms': ['broccoli'], 'def': 'plant with dense clusters of tight green flower buds', 'name': 'broccoli'}, {'frequency': 'r', 'id': 155, 'synset': 'brooch.n.01', 'synonyms': ['broach'], 'def': 'a decorative pin worn by women', 'name': 'broach'}, {'frequency': 'c', 'id': 156, 'synset': 'broom.n.01', 'synonyms': ['broom'], 'def': 'bundle of straws or twigs attached to a long handle; used for cleaning', 'name': 'broom'}, {'frequency': 'c', 'id': 157, 'synset': 'brownie.n.03', 'synonyms': ['brownie'], 'def': 'square or bar of very rich chocolate cake usually with nuts', 'name': 'brownie'}, {'frequency': 'c', 'id': 158, 'synset': 'brussels_sprouts.n.01', 'synonyms': ['brussels_sprouts'], 'def': 'the small edible cabbage-like buds growing along a stalk', 'name': 'brussels_sprouts'}, {'frequency': 'r', 'id': 159, 'synset': 'bubble_gum.n.01', 'synonyms': ['bubble_gum'], 'def': 'a kind of chewing gum that can be blown into bubbles', 'name': 'bubble_gum'}, {'frequency': 'f', 'id': 160, 'synset': 'bucket.n.01', 'synonyms': ['bucket', 'pail'], 'def': 'a roughly cylindrical vessel that is open at the top', 'name': 'bucket'}, {'frequency': 'r', 'id': 161, 'synset': 'buggy.n.01', 'synonyms': ['horse_buggy'], 'def': 'a small lightweight carriage; drawn by a single horse', 'name': 'horse_buggy'}, {'frequency': 'c', 'id': 162, 'synset': 'bull.n.11', 'synonyms': ['bull'], 'def': 'mature male cow', 'name': 'bull'}, {'frequency': 'r', 'id': 163, 'synset': 'bulldog.n.01', 'synonyms': ['bulldog'], 'def': 'a thickset short-haired dog with a large head and strong undershot lower jaw', 'name': 'bulldog'}, {'frequency': 'r', 'id': 164, 'synset': 'bulldozer.n.01', 'synonyms': ['bulldozer', 'dozer'], 'def': 'large powerful tractor; a large blade in front flattens areas of ground', 'name': 'bulldozer'}, {'frequency': 'c', 'id': 165, 'synset': 'bullet_train.n.01', 'synonyms': ['bullet_train'], 'def': 'a high-speed passenger train', 'name': 'bullet_train'}, {'frequency': 'c', 'id': 166, 'synset': 'bulletin_board.n.02', 'synonyms': ['bulletin_board', 'notice_board'], 'def': 'a board that hangs on a wall; displays announcements', 'name': 'bulletin_board'}, {'frequency': 'r', 'id': 167, 'synset': 'bulletproof_vest.n.01', 'synonyms': ['bulletproof_vest'], 'def': 'a vest capable of resisting the impact of a bullet', 'name': 'bulletproof_vest'}, {'frequency': 'c', 'id': 168, 'synset': 'bullhorn.n.01', 'synonyms': ['bullhorn', 'megaphone'], 'def': 'a portable loudspeaker with built-in microphone and amplifier', 'name': 'bullhorn'}, {'frequency': 'r', 'id': 169, 'synset': 'bully_beef.n.01', 'synonyms': ['corned_beef', 'corn_beef'], 'def': 'beef cured or pickled in brine', 'name': 'corned_beef'}, {'frequency': 'f', 'id': 170, 'synset': 'bun.n.01', 'synonyms': ['bun', 'roll'], 'def': 'small rounded bread either plain or sweet', 'name': 'bun'}, {'frequency': 'c', 'id': 171, 'synset': 'bunk_bed.n.01', 'synonyms': ['bunk_bed'], 'def': 'beds built one above the other', 'name': 'bunk_bed'}, {'frequency': 'f', 'id': 172, 'synset': 'buoy.n.01', 'synonyms': ['buoy'], 'def': 'a float attached by rope to the seabed to mark channels in a harbor or underwater hazards', 'name': 'buoy'}, {'frequency': 'r', 'id': 173, 'synset': 'burrito.n.01', 'synonyms': ['burrito'], 'def': 'a flour tortilla folded around a filling', 'name': 'burrito'}, {'frequency': 'f', 'id': 174, 'synset': 'bus.n.01', 'synonyms': ['bus_(vehicle)', 'autobus', 'charabanc', 'double-decker', 'motorbus', 'motorcoach'], 'def': 'a vehicle carrying many passengers; used for public transport', 'name': 'bus_(vehicle)'}, {'frequency': 'c', 'id': 175, 'synset': 'business_card.n.01', 'synonyms': ['business_card'], 'def': "a card on which are printed the person's name and business affiliation", 'name': 'business_card'}, {'frequency': 'c', 'id': 176, 'synset': 'butcher_knife.n.01', 'synonyms': ['butcher_knife'], 'def': 'a large sharp knife for cutting or trimming meat', 'name': 'butcher_knife'}, {'frequency': 'c', 'id': 177, 'synset': 'butter.n.01', 'synonyms': ['butter'], 'def': 'an edible emulsion of fat globules made by churning milk or cream; for cooking and table use', 'name': 'butter'}, {'frequency': 'c', 'id': 178, 'synset': 'butterfly.n.01', 'synonyms': ['butterfly'], 'def': 'insect typically having a slender body with knobbed antennae and broad colorful wings', 'name': 'butterfly'}, {'frequency': 'f', 'id': 179, 'synset': 'button.n.01', 'synonyms': ['button'], 'def': 'a round fastener sewn to shirts and coats etc to fit through buttonholes', 'name': 'button'}, {'frequency': 'f', 'id': 180, 'synset': 'cab.n.03', 'synonyms': ['cab_(taxi)', 'taxi', 'taxicab'], 'def': 'a car that takes passengers where they want to go in exchange for money', 'name': 'cab_(taxi)'}, {'frequency': 'r', 'id': 181, 'synset': 'cabana.n.01', 'synonyms': ['cabana'], 'def': 'a small tent used as a dressing room beside the sea or a swimming pool', 'name': 'cabana'}, {'frequency': 'r', 'id': 182, 'synset': 'cabin_car.n.01', 'synonyms': ['cabin_car', 'caboose'], 'def': 'a car on a freight train for use of the train crew; usually the last car on the train', 'name': 'cabin_car'}, {'frequency': 'f', 'id': 183, 'synset': 'cabinet.n.01', 'synonyms': ['cabinet'], 'def': 'a piece of furniture resembling a cupboard with doors and shelves and drawers', 'name': 'cabinet'}, {'frequency': 'r', 'id': 184, 'synset': 'cabinet.n.03', 'synonyms': ['locker', 'storage_locker'], 'def': 'a storage compartment for clothes and valuables; usually it has a lock', 'name': 'locker'}, {'frequency': 'f', 'id': 185, 'synset': 'cake.n.03', 'synonyms': ['cake'], 'def': 'baked goods made from or based on a mixture of flour, sugar, eggs, and fat', 'name': 'cake'}, {'frequency': 'c', 'id': 186, 'synset': 'calculator.n.02', 'synonyms': ['calculator'], 'def': 'a small machine that is used for mathematical calculations', 'name': 'calculator'}, {'frequency': 'f', 'id': 187, 'synset': 'calendar.n.02', 'synonyms': ['calendar'], 'def': 'a list or register of events (appointments/social events/court cases, etc)', 'name': 'calendar'}, {'frequency': 'c', 'id': 188, 'synset': 'calf.n.01', 'synonyms': ['calf'], 'def': 'young of domestic cattle', 'name': 'calf'}, {'frequency': 'c', 'id': 189, 'synset': 'camcorder.n.01', 'synonyms': ['camcorder'], 'def': 'a portable television camera and videocassette recorder', 'name': 'camcorder'}, {'frequency': 'c', 'id': 190, 'synset': 'camel.n.01', 'synonyms': ['camel'], 'def': 'cud-chewing mammal used as a draft or saddle animal in desert regions', 'name': 'camel'}, {'frequency': 'f', 'id': 191, 'synset': 'camera.n.01', 'synonyms': ['camera'], 'def': 'equipment for taking photographs', 'name': 'camera'}, {'frequency': 'c', 'id': 192, 'synset': 'camera_lens.n.01', 'synonyms': ['camera_lens'], 'def': 'a lens that focuses the image in a camera', 'name': 'camera_lens'}, {'frequency': 'c', 'id': 193, 'synset': 'camper.n.02', 'synonyms': ['camper_(vehicle)', 'camping_bus', 'motor_home'], 'def': 'a recreational vehicle equipped for camping out while traveling', 'name': 'camper_(vehicle)'}, {'frequency': 'f', 'id': 194, 'synset': 'can.n.01', 'synonyms': ['can', 'tin_can'], 'def': 'airtight sealed metal container for food or drink or paint etc.', 'name': 'can'}, {'frequency': 'c', 'id': 195, 'synset': 'can_opener.n.01', 'synonyms': ['can_opener', 'tin_opener'], 'def': 'a device for cutting cans open', 'name': 'can_opener'}, {'frequency': 'r', 'id': 196, 'synset': 'candelabrum.n.01', 'synonyms': ['candelabrum', 'candelabra'], 'def': 'branched candlestick; ornamental; has several lights', 'name': 'candelabrum'}, {'frequency': 'f', 'id': 197, 'synset': 'candle.n.01', 'synonyms': ['candle', 'candlestick'], 'def': 'stick of wax with a wick in the middle', 'name': 'candle'}, {'frequency': 'f', 'id': 198, 'synset': 'candlestick.n.01', 'synonyms': ['candle_holder'], 'def': 'a holder with sockets for candles', 'name': 'candle_holder'}, {'frequency': 'r', 'id': 199, 'synset': 'candy_bar.n.01', 'synonyms': ['candy_bar'], 'def': 'a candy shaped as a bar', 'name': 'candy_bar'}, {'frequency': 'c', 'id': 200, 'synset': 'candy_cane.n.01', 'synonyms': ['candy_cane'], 'def': 'a hard candy in the shape of a rod (usually with stripes)', 'name': 'candy_cane'}, {'frequency': 'c', 'id': 201, 'synset': 'cane.n.01', 'synonyms': ['walking_cane'], 'def': 'a stick that people can lean on to help them walk', 'name': 'walking_cane'}, {'frequency': 'c', 'id': 202, 'synset': 'canister.n.02', 'synonyms': ['canister', 'cannister'], 'def': 'metal container for storing dry foods such as tea or flour', 'name': 'canister'}, {'frequency': 'r', 'id': 203, 'synset': 'cannon.n.02', 'synonyms': ['cannon'], 'def': 'heavy gun fired from a tank', 'name': 'cannon'}, {'frequency': 'c', 'id': 204, 'synset': 'canoe.n.01', 'synonyms': ['canoe'], 'def': 'small and light boat; pointed at both ends; propelled with a paddle', 'name': 'canoe'}, {'frequency': 'r', 'id': 205, 'synset': 'cantaloup.n.02', 'synonyms': ['cantaloup', 'cantaloupe'], 'def': 'the fruit of a cantaloup vine; small to medium-sized melon with yellowish flesh', 'name': 'cantaloup'}, {'frequency': 'r', 'id': 206, 'synset': 'canteen.n.01', 'synonyms': ['canteen'], 'def': 'a flask for carrying water; used by soldiers or travelers', 'name': 'canteen'}, {'frequency': 'c', 'id': 207, 'synset': 'cap.n.01', 'synonyms': ['cap_(headwear)'], 'def': 'a tight-fitting headwear', 'name': 'cap_(headwear)'}, {'frequency': 'f', 'id': 208, 'synset': 'cap.n.02', 'synonyms': ['bottle_cap', 'cap_(container_lid)'], 'def': 'a top (as for a bottle)', 'name': 'bottle_cap'}, {'frequency': 'r', 'id': 209, 'synset': 'cape.n.02', 'synonyms': ['cape'], 'def': 'a sleeveless garment like a cloak but shorter', 'name': 'cape'}, {'frequency': 'c', 'id': 210, 'synset': 'cappuccino.n.01', 'synonyms': ['cappuccino', 'coffee_cappuccino'], 'def': 'equal parts of espresso and steamed milk', 'name': 'cappuccino'}, {'frequency': 'f', 'id': 211, 'synset': 'car.n.01', 'synonyms': ['car_(automobile)', 'auto_(automobile)', 'automobile'], 'def': 'a motor vehicle with four wheels', 'name': 'car_(automobile)'}, {'frequency': 'f', 'id': 212, 'synset': 'car.n.02', 'synonyms': ['railcar_(part_of_a_train)', 'railway_car_(part_of_a_train)', 'railroad_car_(part_of_a_train)'], 'def': 'a wheeled vehicle adapted to the rails of railroad', 'name': 'railcar_(part_of_a_train)'}, {'frequency': 'r', 'id': 213, 'synset': 'car.n.04', 'synonyms': ['elevator_car'], 'def': 'where passengers ride up and down', 'name': 'elevator_car'}, {'frequency': 'r', 'id': 214, 'synset': 'car_battery.n.01', 'synonyms': ['car_battery', 'automobile_battery'], 'def': 'a battery in a motor vehicle', 'name': 'car_battery'}, {'frequency': 'c', 'id': 215, 'synset': 'card.n.02', 'synonyms': ['identity_card'], 'def': 'a card certifying the identity of the bearer', 'name': 'identity_card'}, {'frequency': 'c', 'id': 216, 'synset': 'card.n.03', 'synonyms': ['card'], 'def': 'a rectangular piece of paper used to send messages (e.g. greetings or pictures)', 'name': 'card'}, {'frequency': 'r', 'id': 217, 'synset': 'cardigan.n.01', 'synonyms': ['cardigan'], 'def': 'knitted jacket that is fastened up the front with buttons or a zipper', 'name': 'cardigan'}, {'frequency': 'r', 'id': 218, 'synset': 'cargo_ship.n.01', 'synonyms': ['cargo_ship', 'cargo_vessel'], 'def': 'a ship designed to carry cargo', 'name': 'cargo_ship'}, {'frequency': 'r', 'id': 219, 'synset': 'carnation.n.01', 'synonyms': ['carnation'], 'def': 'plant with pink to purple-red spice-scented usually double flowers', 'name': 'carnation'}, {'frequency': 'c', 'id': 220, 'synset': 'carriage.n.02', 'synonyms': ['horse_carriage'], 'def': 'a vehicle with wheels drawn by one or more horses', 'name': 'horse_carriage'}, {'frequency': 'f', 'id': 221, 'synset': 'carrot.n.01', 'synonyms': ['carrot'], 'def': 'deep orange edible root of the cultivated carrot plant', 'name': 'carrot'}, {'frequency': 'c', 'id': 222, 'synset': 'carryall.n.01', 'synonyms': ['tote_bag'], 'def': 'a capacious bag or basket', 'name': 'tote_bag'}, {'frequency': 'c', 'id': 223, 'synset': 'cart.n.01', 'synonyms': ['cart'], 'def': 'a heavy open wagon usually having two wheels and drawn by an animal', 'name': 'cart'}, {'frequency': 'c', 'id': 224, 'synset': 'carton.n.02', 'synonyms': ['carton'], 'def': 'a box made of cardboard; opens by flaps on top', 'name': 'carton'}, {'frequency': 'c', 'id': 225, 'synset': 'cash_register.n.01', 'synonyms': ['cash_register', 'register_(for_cash_transactions)'], 'def': 'a cashbox with an adding machine to register transactions', 'name': 'cash_register'}, {'frequency': 'r', 'id': 226, 'synset': 'casserole.n.01', 'synonyms': ['casserole'], 'def': 'food cooked and served in a casserole', 'name': 'casserole'}, {'frequency': 'r', 'id': 227, 'synset': 'cassette.n.01', 'synonyms': ['cassette'], 'def': 'a container that holds a magnetic tape used for recording or playing sound or video', 'name': 'cassette'}, {'frequency': 'c', 'id': 228, 'synset': 'cast.n.05', 'synonyms': ['cast', 'plaster_cast', 'plaster_bandage'], 'def': 'bandage consisting of a firm covering that immobilizes broken bones while they heal', 'name': 'cast'}, {'frequency': 'f', 'id': 229, 'synset': 'cat.n.01', 'synonyms': ['cat'], 'def': 'a domestic house cat', 'name': 'cat'}, {'frequency': 'c', 'id': 230, 'synset': 'cauliflower.n.02', 'synonyms': ['cauliflower'], 'def': 'edible compact head of white undeveloped flowers', 'name': 'cauliflower'}, {'frequency': 'r', 'id': 231, 'synset': 'caviar.n.01', 'synonyms': ['caviar', 'caviare'], 'def': "salted roe of sturgeon or other large fish; usually served as an hors d'oeuvre", 'name': 'caviar'}, {'frequency': 'c', 'id': 232, 'synset': 'cayenne.n.02', 'synonyms': ['cayenne_(spice)', 'cayenne_pepper_(spice)', 'red_pepper_(spice)'], 'def': 'ground pods and seeds of pungent red peppers of the genus Capsicum', 'name': 'cayenne_(spice)'}, {'frequency': 'c', 'id': 233, 'synset': 'cd_player.n.01', 'synonyms': ['CD_player'], 'def': 'electronic equipment for playing compact discs (CDs)', 'name': 'CD_player'}, {'frequency': 'c', 'id': 234, 'synset': 'celery.n.01', 'synonyms': ['celery'], 'def': 'widely cultivated herb with aromatic leaf stalks that are eaten raw or cooked', 'name': 'celery'}, {'frequency': 'f', 'id': 235, 'synset': 'cellular_telephone.n.01', 'synonyms': ['cellular_telephone', 'cellular_phone', 'cellphone', 'mobile_phone', 'smart_phone'], 'def': 'a hand-held mobile telephone', 'name': 'cellular_telephone'}, {'frequency': 'r', 'id': 236, 'synset': 'chain_mail.n.01', 'synonyms': ['chain_mail', 'ring_mail', 'chain_armor', 'chain_armour', 'ring_armor', 'ring_armour'], 'def': '(Middle Ages) flexible armor made of interlinked metal rings', 'name': 'chain_mail'}, {'frequency': 'f', 'id': 237, 'synset': 'chair.n.01', 'synonyms': ['chair'], 'def': 'a seat for one person, with a support for the back', 'name': 'chair'}, {'frequency': 'r', 'id': 238, 'synset': 'chaise_longue.n.01', 'synonyms': ['chaise_longue', 'chaise', 'daybed'], 'def': 'a long chair; for reclining', 'name': 'chaise_longue'}, {'frequency': 'r', 'id': 239, 'synset': 'champagne.n.01', 'synonyms': ['champagne'], 'def': 'a white sparkling wine produced in Champagne or resembling that produced there', 'name': 'champagne'}, {'frequency': 'f', 'id': 240, 'synset': 'chandelier.n.01', 'synonyms': ['chandelier'], 'def': 'branched lighting fixture; often ornate; hangs from the ceiling', 'name': 'chandelier'}, {'frequency': 'r', 'id': 241, 'synset': 'chap.n.04', 'synonyms': ['chap'], 'def': 'leather leggings without a seat; worn over trousers by cowboys to protect their legs', 'name': 'chap'}, {'frequency': 'r', 'id': 242, 'synset': 'checkbook.n.01', 'synonyms': ['checkbook', 'chequebook'], 'def': 'a book issued to holders of checking accounts', 'name': 'checkbook'}, {'frequency': 'r', 'id': 243, 'synset': 'checkerboard.n.01', 'synonyms': ['checkerboard'], 'def': 'a board having 64 squares of two alternating colors', 'name': 'checkerboard'}, {'frequency': 'c', 'id': 244, 'synset': 'cherry.n.03', 'synonyms': ['cherry'], 'def': 'a red fruit with a single hard stone', 'name': 'cherry'}, {'frequency': 'r', 'id': 245, 'synset': 'chessboard.n.01', 'synonyms': ['chessboard'], 'def': 'a checkerboard used to play chess', 'name': 'chessboard'}, {'frequency': 'r', 'id': 246, 'synset': 'chest_of_drawers.n.01', 'synonyms': ['chest_of_drawers_(furniture)', 'bureau_(furniture)', 'chest_(furniture)'], 'def': 'furniture with drawers for keeping clothes', 'name': 'chest_of_drawers_(furniture)'}, {'frequency': 'c', 'id': 247, 'synset': 'chicken.n.02', 'synonyms': ['chicken_(animal)'], 'def': 'a domestic fowl bred for flesh or eggs', 'name': 'chicken_(animal)'}, {'frequency': 'c', 'id': 248, 'synset': 'chicken_wire.n.01', 'synonyms': ['chicken_wire'], 'def': 'a galvanized wire network with a hexagonal mesh; used to build fences', 'name': 'chicken_wire'}, {'frequency': 'r', 'id': 249, 'synset': 'chickpea.n.01', 'synonyms': ['chickpea', 'garbanzo'], 'def': 'the seed of the chickpea plant; usually dried', 'name': 'chickpea'}, {'frequency': 'r', 'id': 250, 'synset': 'chihuahua.n.03', 'synonyms': ['Chihuahua'], 'def': 'an old breed of tiny short-haired dog with protruding eyes from Mexico', 'name': 'Chihuahua'}, {'frequency': 'r', 'id': 251, 'synset': 'chili.n.02', 'synonyms': ['chili_(vegetable)', 'chili_pepper_(vegetable)', 'chilli_(vegetable)', 'chilly_(vegetable)', 'chile_(vegetable)'], 'def': 'very hot and finely tapering pepper of special pungency', 'name': 'chili_(vegetable)'}, {'frequency': 'r', 'id': 252, 'synset': 'chime.n.01', 'synonyms': ['chime', 'gong'], 'def': 'an instrument consisting of a set of bells that are struck with a hammer', 'name': 'chime'}, {'frequency': 'r', 'id': 253, 'synset': 'chinaware.n.01', 'synonyms': ['chinaware'], 'def': 'dishware made of high quality porcelain', 'name': 'chinaware'}, {'frequency': 'c', 'id': 254, 'synset': 'chip.n.04', 'synonyms': ['crisp_(potato_chip)', 'potato_chip'], 'def': 'a thin crisp slice of potato fried in deep fat', 'name': 'crisp_(potato_chip)'}, {'frequency': 'r', 'id': 255, 'synset': 'chip.n.06', 'synonyms': ['poker_chip'], 'def': 'a small disk-shaped counter used to represent money when gambling', 'name': 'poker_chip'}, {'frequency': 'c', 'id': 256, 'synset': 'chocolate_bar.n.01', 'synonyms': ['chocolate_bar'], 'def': 'a bar of chocolate candy', 'name': 'chocolate_bar'}, {'frequency': 'c', 'id': 257, 'synset': 'chocolate_cake.n.01', 'synonyms': ['chocolate_cake'], 'def': 'cake containing chocolate', 'name': 'chocolate_cake'}, {'frequency': 'r', 'id': 258, 'synset': 'chocolate_milk.n.01', 'synonyms': ['chocolate_milk'], 'def': 'milk flavored with chocolate syrup', 'name': 'chocolate_milk'}, {'frequency': 'r', 'id': 259, 'synset': 'chocolate_mousse.n.01', 'synonyms': ['chocolate_mousse'], 'def': 'dessert mousse made with chocolate', 'name': 'chocolate_mousse'}, {'frequency': 'f', 'id': 260, 'synset': 'choker.n.03', 'synonyms': ['choker', 'collar', 'neckband'], 'def': 'necklace that fits tightly around the neck', 'name': 'choker'}, {'frequency': 'f', 'id': 261, 'synset': 'chopping_board.n.01', 'synonyms': ['chopping_board', 'cutting_board', 'chopping_block'], 'def': 'a wooden board where meats or vegetables can be cut', 'name': 'chopping_board'}, {'frequency': 'c', 'id': 262, 'synset': 'chopstick.n.01', 'synonyms': ['chopstick'], 'def': 'one of a pair of slender sticks used as oriental tableware to eat food with', 'name': 'chopstick'}, {'frequency': 'f', 'id': 263, 'synset': 'christmas_tree.n.05', 'synonyms': ['Christmas_tree'], 'def': 'an ornamented evergreen used as a Christmas decoration', 'name': 'Christmas_tree'}, {'frequency': 'c', 'id': 264, 'synset': 'chute.n.02', 'synonyms': ['slide'], 'def': 'sloping channel through which things can descend', 'name': 'slide'}, {'frequency': 'r', 'id': 265, 'synset': 'cider.n.01', 'synonyms': ['cider', 'cyder'], 'def': 'a beverage made from juice pressed from apples', 'name': 'cider'}, {'frequency': 'r', 'id': 266, 'synset': 'cigar_box.n.01', 'synonyms': ['cigar_box'], 'def': 'a box for holding cigars', 'name': 'cigar_box'}, {'frequency': 'c', 'id': 267, 'synset': 'cigarette.n.01', 'synonyms': ['cigarette'], 'def': 'finely ground tobacco wrapped in paper; for smoking', 'name': 'cigarette'}, {'frequency': 'c', 'id': 268, 'synset': 'cigarette_case.n.01', 'synonyms': ['cigarette_case', 'cigarette_pack'], 'def': 'a small flat case for holding cigarettes', 'name': 'cigarette_case'}, {'frequency': 'f', 'id': 269, 'synset': 'cistern.n.02', 'synonyms': ['cistern', 'water_tank'], 'def': 'a tank that holds the water used to flush a toilet', 'name': 'cistern'}, {'frequency': 'r', 'id': 270, 'synset': 'clarinet.n.01', 'synonyms': ['clarinet'], 'def': 'a single-reed instrument with a straight tube', 'name': 'clarinet'}, {'frequency': 'r', 'id': 271, 'synset': 'clasp.n.01', 'synonyms': ['clasp'], 'def': 'a fastener (as a buckle or hook) that is used to hold two things together', 'name': 'clasp'}, {'frequency': 'c', 'id': 272, 'synset': 'cleansing_agent.n.01', 'synonyms': ['cleansing_agent', 'cleanser', 'cleaner'], 'def': 'a preparation used in cleaning something', 'name': 'cleansing_agent'}, {'frequency': 'r', 'id': 273, 'synset': 'clementine.n.01', 'synonyms': ['clementine'], 'def': 'a variety of mandarin orange', 'name': 'clementine'}, {'frequency': 'c', 'id': 274, 'synset': 'clip.n.03', 'synonyms': ['clip'], 'def': 'any of various small fasteners used to hold loose articles together', 'name': 'clip'}, {'frequency': 'c', 'id': 275, 'synset': 'clipboard.n.01', 'synonyms': ['clipboard'], 'def': 'a small writing board with a clip at the top for holding papers', 'name': 'clipboard'}, {'frequency': 'f', 'id': 276, 'synset': 'clock.n.01', 'synonyms': ['clock', 'timepiece', 'timekeeper'], 'def': 'a timepiece that shows the time of day', 'name': 'clock'}, {'frequency': 'f', 'id': 277, 'synset': 'clock_tower.n.01', 'synonyms': ['clock_tower'], 'def': 'a tower with a large clock visible high up on an outside face', 'name': 'clock_tower'}, {'frequency': 'c', 'id': 278, 'synset': 'clothes_hamper.n.01', 'synonyms': ['clothes_hamper', 'laundry_basket', 'clothes_basket'], 'def': 'a hamper that holds dirty clothes to be washed or wet clothes to be dried', 'name': 'clothes_hamper'}, {'frequency': 'c', 'id': 279, 'synset': 'clothespin.n.01', 'synonyms': ['clothespin', 'clothes_peg'], 'def': 'wood or plastic fastener; for holding clothes on a clothesline', 'name': 'clothespin'}, {'frequency': 'r', 'id': 280, 'synset': 'clutch_bag.n.01', 'synonyms': ['clutch_bag'], 'def': "a woman's strapless purse that is carried in the hand", 'name': 'clutch_bag'}, {'frequency': 'f', 'id': 281, 'synset': 'coaster.n.03', 'synonyms': ['coaster'], 'def': 'a covering (plate or mat) that protects the surface of a table', 'name': 'coaster'}, {'frequency': 'f', 'id': 282, 'synset': 'coat.n.01', 'synonyms': ['coat'], 'def': 'an outer garment that has sleeves and covers the body from shoulder down', 'name': 'coat'}, {'frequency': 'c', 'id': 283, 'synset': 'coat_hanger.n.01', 'synonyms': ['coat_hanger', 'clothes_hanger', 'dress_hanger'], 'def': "a hanger that is shaped like a person's shoulders", 'name': 'coat_hanger'}, {'frequency': 'r', 'id': 284, 'synset': 'coatrack.n.01', 'synonyms': ['coatrack', 'hatrack'], 'def': 'a rack with hooks for temporarily holding coats and hats', 'name': 'coatrack'}, {'frequency': 'c', 'id': 285, 'synset': 'cock.n.04', 'synonyms': ['cock', 'rooster'], 'def': 'adult male chicken', 'name': 'cock'}, {'frequency': 'c', 'id': 286, 'synset': 'coconut.n.02', 'synonyms': ['coconut', 'cocoanut'], 'def': 'large hard-shelled brown oval nut with a fibrous husk', 'name': 'coconut'}, {'frequency': 'r', 'id': 287, 'synset': 'coffee_filter.n.01', 'synonyms': ['coffee_filter'], 'def': 'filter (usually of paper) that passes the coffee and retains the coffee grounds', 'name': 'coffee_filter'}, {'frequency': 'f', 'id': 288, 'synset': 'coffee_maker.n.01', 'synonyms': ['coffee_maker', 'coffee_machine'], 'def': 'a kitchen appliance for brewing coffee automatically', 'name': 'coffee_maker'}, {'frequency': 'f', 'id': 289, 'synset': 'coffee_table.n.01', 'synonyms': ['coffee_table', 'cocktail_table'], 'def': 'low table where magazines can be placed and coffee or cocktails are served', 'name': 'coffee_table'}, {'frequency': 'c', 'id': 290, 'synset': 'coffeepot.n.01', 'synonyms': ['coffeepot'], 'def': 'tall pot in which coffee is brewed', 'name': 'coffeepot'}, {'frequency': 'r', 'id': 291, 'synset': 'coil.n.05', 'synonyms': ['coil'], 'def': 'tubing that is wound in a spiral', 'name': 'coil'}, {'frequency': 'c', 'id': 292, 'synset': 'coin.n.01', 'synonyms': ['coin'], 'def': 'a flat metal piece (usually a disc) used as money', 'name': 'coin'}, {'frequency': 'r', 'id': 293, 'synset': 'colander.n.01', 'synonyms': ['colander', 'cullender'], 'def': 'bowl-shaped strainer; used to wash or drain foods', 'name': 'colander'}, {'frequency': 'c', 'id': 294, 'synset': 'coleslaw.n.01', 'synonyms': ['coleslaw', 'slaw'], 'def': 'basically shredded cabbage', 'name': 'coleslaw'}, {'frequency': 'r', 'id': 295, 'synset': 'coloring_material.n.01', 'synonyms': ['coloring_material', 'colouring_material'], 'def': 'any material used for its color', 'name': 'coloring_material'}, {'frequency': 'r', 'id': 296, 'synset': 'combination_lock.n.01', 'synonyms': ['combination_lock'], 'def': 'lock that can be opened only by turning dials in a special sequence', 'name': 'combination_lock'}, {'frequency': 'c', 'id': 297, 'synset': 'comforter.n.04', 'synonyms': ['pacifier', 'teething_ring'], 'def': 'device used for an infant to suck or bite on', 'name': 'pacifier'}, {'frequency': 'r', 'id': 298, 'synset': 'comic_book.n.01', 'synonyms': ['comic_book'], 'def': 'a magazine devoted to comic strips', 'name': 'comic_book'}, {'frequency': 'f', 'id': 299, 'synset': 'computer_keyboard.n.01', 'synonyms': ['computer_keyboard', 'keyboard_(computer)'], 'def': 'a keyboard that is a data input device for computers', 'name': 'computer_keyboard'}, {'frequency': 'r', 'id': 300, 'synset': 'concrete_mixer.n.01', 'synonyms': ['concrete_mixer', 'cement_mixer'], 'def': 'a machine with a large revolving drum in which cement/concrete is mixed', 'name': 'concrete_mixer'}, {'frequency': 'f', 'id': 301, 'synset': 'cone.n.01', 'synonyms': ['cone', 'traffic_cone'], 'def': 'a cone-shaped object used to direct traffic', 'name': 'cone'}, {'frequency': 'f', 'id': 302, 'synset': 'control.n.09', 'synonyms': ['control', 'controller'], 'def': 'a mechanism that controls the operation of a machine', 'name': 'control'}, {'frequency': 'r', 'id': 303, 'synset': 'convertible.n.01', 'synonyms': ['convertible_(automobile)'], 'def': 'a car that has top that can be folded or removed', 'name': 'convertible_(automobile)'}, {'frequency': 'r', 'id': 304, 'synset': 'convertible.n.03', 'synonyms': ['sofa_bed'], 'def': 'a sofa that can be converted into a bed', 'name': 'sofa_bed'}, {'frequency': 'c', 'id': 305, 'synset': 'cookie.n.01', 'synonyms': ['cookie', 'cooky', 'biscuit_(cookie)'], 'def': "any of various small flat sweet cakes (`biscuit' is the British term)", 'name': 'cookie'}, {'frequency': 'r', 'id': 306, 'synset': 'cookie_jar.n.01', 'synonyms': ['cookie_jar', 'cooky_jar'], 'def': 'a jar in which cookies are kept (and sometimes money is hidden)', 'name': 'cookie_jar'}, {'frequency': 'r', 'id': 307, 'synset': 'cooking_utensil.n.01', 'synonyms': ['cooking_utensil'], 'def': 'a kitchen utensil made of material that does not melt easily; used for cooking', 'name': 'cooking_utensil'}, {'frequency': 'f', 'id': 308, 'synset': 'cooler.n.01', 'synonyms': ['cooler_(for_food)', 'ice_chest'], 'def': 'an insulated box for storing food often with ice', 'name': 'cooler_(for_food)'}, {'frequency': 'c', 'id': 309, 'synset': 'cork.n.04', 'synonyms': ['cork_(bottle_plug)', 'bottle_cork'], 'def': 'the plug in the mouth of a bottle (especially a wine bottle)', 'name': 'cork_(bottle_plug)'}, {'frequency': 'r', 'id': 310, 'synset': 'corkboard.n.01', 'synonyms': ['corkboard'], 'def': 'a sheet consisting of cork granules', 'name': 'corkboard'}, {'frequency': 'r', 'id': 311, 'synset': 'corkscrew.n.01', 'synonyms': ['corkscrew', 'bottle_screw'], 'def': 'a bottle opener that pulls corks', 'name': 'corkscrew'}, {'frequency': 'c', 'id': 312, 'synset': 'corn.n.03', 'synonyms': ['edible_corn', 'corn', 'maize'], 'def': 'ears of corn that can be prepared and served for human food', 'name': 'edible_corn'}, {'frequency': 'r', 'id': 313, 'synset': 'cornbread.n.01', 'synonyms': ['cornbread'], 'def': 'bread made primarily of cornmeal', 'name': 'cornbread'}, {'frequency': 'c', 'id': 314, 'synset': 'cornet.n.01', 'synonyms': ['cornet', 'horn', 'trumpet'], 'def': 'a brass musical instrument with a narrow tube and a flared bell and many valves', 'name': 'cornet'}, {'frequency': 'c', 'id': 315, 'synset': 'cornice.n.01', 'synonyms': ['cornice', 'valance', 'valance_board', 'pelmet'], 'def': 'a decorative framework to conceal curtain fixtures at the top of a window casing', 'name': 'cornice'}, {'frequency': 'r', 'id': 316, 'synset': 'cornmeal.n.01', 'synonyms': ['cornmeal'], 'def': 'coarsely ground corn', 'name': 'cornmeal'}, {'frequency': 'r', 'id': 317, 'synset': 'corset.n.01', 'synonyms': ['corset', 'girdle'], 'def': "a woman's close-fitting foundation garment", 'name': 'corset'}, {'frequency': 'r', 'id': 318, 'synset': 'cos.n.02', 'synonyms': ['romaine_lettuce'], 'def': 'lettuce with long dark-green leaves in a loosely packed elongated head', 'name': 'romaine_lettuce'}, {'frequency': 'c', 'id': 319, 'synset': 'costume.n.04', 'synonyms': ['costume'], 'def': 'the attire characteristic of a country or a time or a social class', 'name': 'costume'}, {'frequency': 'r', 'id': 320, 'synset': 'cougar.n.01', 'synonyms': ['cougar', 'puma', 'catamount', 'mountain_lion', 'panther'], 'def': 'large American feline resembling a lion', 'name': 'cougar'}, {'frequency': 'r', 'id': 321, 'synset': 'coverall.n.01', 'synonyms': ['coverall'], 'def': 'a loose-fitting protective garment that is worn over other clothing', 'name': 'coverall'}, {'frequency': 'r', 'id': 322, 'synset': 'cowbell.n.01', 'synonyms': ['cowbell'], 'def': 'a bell hung around the neck of cow so that the cow can be easily located', 'name': 'cowbell'}, {'frequency': 'f', 'id': 323, 'synset': 'cowboy_hat.n.01', 'synonyms': ['cowboy_hat', 'ten-gallon_hat'], 'def': 'a hat with a wide brim and a soft crown; worn by American ranch hands', 'name': 'cowboy_hat'}, {'frequency': 'r', 'id': 324, 'synset': 'crab.n.01', 'synonyms': ['crab_(animal)'], 'def': 'decapod having eyes on short stalks and a broad flattened shell and pincers', 'name': 'crab_(animal)'}, {'frequency': 'c', 'id': 325, 'synset': 'cracker.n.01', 'synonyms': ['cracker'], 'def': 'a thin crisp wafer', 'name': 'cracker'}, {'frequency': 'r', 'id': 326, 'synset': 'crape.n.01', 'synonyms': ['crape', 'crepe', 'French_pancake'], 'def': 'small very thin pancake', 'name': 'crape'}, {'frequency': 'f', 'id': 327, 'synset': 'crate.n.01', 'synonyms': ['crate'], 'def': 'a rugged box (usually made of wood); used for shipping', 'name': 'crate'}, {'frequency': 'r', 'id': 328, 'synset': 'crayon.n.01', 'synonyms': ['crayon', 'wax_crayon'], 'def': 'writing or drawing implement made of a colored stick of composition wax', 'name': 'crayon'}, {'frequency': 'r', 'id': 329, 'synset': 'cream_pitcher.n.01', 'synonyms': ['cream_pitcher'], 'def': 'a small pitcher for serving cream', 'name': 'cream_pitcher'}, {'frequency': 'r', 'id': 330, 'synset': 'credit_card.n.01', 'synonyms': ['credit_card', 'charge_card', 'debit_card'], 'def': 'a card, usually plastic, used to pay for goods and services', 'name': 'credit_card'}, {'frequency': 'c', 'id': 331, 'synset': 'crescent_roll.n.01', 'synonyms': ['crescent_roll', 'croissant'], 'def': 'very rich flaky crescent-shaped roll', 'name': 'crescent_roll'}, {'frequency': 'c', 'id': 332, 'synset': 'crib.n.01', 'synonyms': ['crib', 'cot'], 'def': 'baby bed with high sides made of slats', 'name': 'crib'}, {'frequency': 'c', 'id': 333, 'synset': 'crock.n.03', 'synonyms': ['crock_pot', 'earthenware_jar'], 'def': 'an earthen jar (made of baked clay)', 'name': 'crock_pot'}, {'frequency': 'f', 'id': 334, 'synset': 'crossbar.n.01', 'synonyms': ['crossbar'], 'def': 'a horizontal bar that goes across something', 'name': 'crossbar'}, {'frequency': 'r', 'id': 335, 'synset': 'crouton.n.01', 'synonyms': ['crouton'], 'def': 'a small piece of toasted or fried bread; served in soup or salads', 'name': 'crouton'}, {'frequency': 'r', 'id': 336, 'synset': 'crow.n.01', 'synonyms': ['crow'], 'def': 'black birds having a raucous call', 'name': 'crow'}, {'frequency': 'c', 'id': 337, 'synset': 'crown.n.04', 'synonyms': ['crown'], 'def': 'an ornamental jeweled headdress signifying sovereignty', 'name': 'crown'}, {'frequency': 'c', 'id': 338, 'synset': 'crucifix.n.01', 'synonyms': ['crucifix'], 'def': 'representation of the cross on which Jesus died', 'name': 'crucifix'}, {'frequency': 'c', 'id': 339, 'synset': 'cruise_ship.n.01', 'synonyms': ['cruise_ship', 'cruise_liner'], 'def': 'a passenger ship used commercially for pleasure cruises', 'name': 'cruise_ship'}, {'frequency': 'c', 'id': 340, 'synset': 'cruiser.n.01', 'synonyms': ['police_cruiser', 'patrol_car', 'police_car', 'squad_car'], 'def': 'a car in which policemen cruise the streets', 'name': 'police_cruiser'}, {'frequency': 'c', 'id': 341, 'synset': 'crumb.n.03', 'synonyms': ['crumb'], 'def': 'small piece of e.g. bread or cake', 'name': 'crumb'}, {'frequency': 'r', 'id': 342, 'synset': 'crutch.n.01', 'synonyms': ['crutch'], 'def': 'a wooden or metal staff that fits under the armpit and reaches to the ground', 'name': 'crutch'}, {'frequency': 'c', 'id': 343, 'synset': 'cub.n.03', 'synonyms': ['cub_(animal)'], 'def': 'the young of certain carnivorous mammals such as the bear or wolf or lion', 'name': 'cub_(animal)'}, {'frequency': 'r', 'id': 344, 'synset': 'cube.n.05', 'synonyms': ['cube', 'square_block'], 'def': 'a block in the (approximate) shape of a cube', 'name': 'cube'}, {'frequency': 'f', 'id': 345, 'synset': 'cucumber.n.02', 'synonyms': ['cucumber', 'cuke'], 'def': 'cylindrical green fruit with thin green rind and white flesh eaten as a vegetable', 'name': 'cucumber'}, {'frequency': 'c', 'id': 346, 'synset': 'cufflink.n.01', 'synonyms': ['cufflink'], 'def': 'jewelry consisting of linked buttons used to fasten the cuffs of a shirt', 'name': 'cufflink'}, {'frequency': 'f', 'id': 347, 'synset': 'cup.n.01', 'synonyms': ['cup'], 'def': 'a small open container usually used for drinking; usually has a handle', 'name': 'cup'}, {'frequency': 'c', 'id': 348, 'synset': 'cup.n.08', 'synonyms': ['trophy_cup'], 'def': 'a metal vessel with handles that is awarded as a trophy to a competition winner', 'name': 'trophy_cup'}, {'frequency': 'c', 'id': 349, 'synset': 'cupcake.n.01', 'synonyms': ['cupcake'], 'def': 'small cake baked in a muffin tin', 'name': 'cupcake'}, {'frequency': 'r', 'id': 350, 'synset': 'curler.n.01', 'synonyms': ['hair_curler', 'hair_roller', 'hair_crimper'], 'def': 'a cylindrical tube around which the hair is wound to curl it', 'name': 'hair_curler'}, {'frequency': 'r', 'id': 351, 'synset': 'curling_iron.n.01', 'synonyms': ['curling_iron'], 'def': 'a cylindrical home appliance that heats hair that has been curled around it', 'name': 'curling_iron'}, {'frequency': 'f', 'id': 352, 'synset': 'curtain.n.01', 'synonyms': ['curtain', 'drapery'], 'def': 'hanging cloth used as a blind (especially for a window)', 'name': 'curtain'}, {'frequency': 'f', 'id': 353, 'synset': 'cushion.n.03', 'synonyms': ['cushion'], 'def': 'a soft bag filled with air or padding such as feathers or foam rubber', 'name': 'cushion'}, {'frequency': 'r', 'id': 354, 'synset': 'custard.n.01', 'synonyms': ['custard'], 'def': 'sweetened mixture of milk and eggs baked or boiled or frozen', 'name': 'custard'}, {'frequency': 'c', 'id': 355, 'synset': 'cutter.n.06', 'synonyms': ['cutting_tool'], 'def': 'a cutting implement; a tool for cutting', 'name': 'cutting_tool'}, {'frequency': 'r', 'id': 356, 'synset': 'cylinder.n.04', 'synonyms': ['cylinder'], 'def': 'a cylindrical container', 'name': 'cylinder'}, {'frequency': 'r', 'id': 357, 'synset': 'cymbal.n.01', 'synonyms': ['cymbal'], 'def': 'a percussion instrument consisting of a concave brass disk', 'name': 'cymbal'}, {'frequency': 'r', 'id': 358, 'synset': 'dachshund.n.01', 'synonyms': ['dachshund', 'dachsie', 'badger_dog'], 'def': 'small long-bodied short-legged breed of dog having a short sleek coat and long drooping ears', 'name': 'dachshund'}, {'frequency': 'r', 'id': 359, 'synset': 'dagger.n.01', 'synonyms': ['dagger'], 'def': 'a short knife with a pointed blade used for piercing or stabbing', 'name': 'dagger'}, {'frequency': 'r', 'id': 360, 'synset': 'dartboard.n.01', 'synonyms': ['dartboard'], 'def': 'a circular board of wood or cork used as the target in the game of darts', 'name': 'dartboard'}, {'frequency': 'r', 'id': 361, 'synset': 'date.n.08', 'synonyms': ['date_(fruit)'], 'def': 'sweet edible fruit of the date palm with a single long woody seed', 'name': 'date_(fruit)'}, {'frequency': 'f', 'id': 362, 'synset': 'deck_chair.n.01', 'synonyms': ['deck_chair', 'beach_chair'], 'def': 'a folding chair for use outdoors; a wooden frame supports a length of canvas', 'name': 'deck_chair'}, {'frequency': 'c', 'id': 363, 'synset': 'deer.n.01', 'synonyms': ['deer', 'cervid'], 'def': "distinguished from Bovidae by the male's having solid deciduous antlers", 'name': 'deer'}, {'frequency': 'c', 'id': 364, 'synset': 'dental_floss.n.01', 'synonyms': ['dental_floss', 'floss'], 'def': 'a soft thread for cleaning the spaces between the teeth', 'name': 'dental_floss'}, {'frequency': 'f', 'id': 365, 'synset': 'desk.n.01', 'synonyms': ['desk'], 'def': 'a piece of furniture with a writing surface and usually drawers or other compartments', 'name': 'desk'}, {'frequency': 'r', 'id': 366, 'synset': 'detergent.n.01', 'synonyms': ['detergent'], 'def': 'a surface-active chemical widely used in industry and laundering', 'name': 'detergent'}, {'frequency': 'c', 'id': 367, 'synset': 'diaper.n.01', 'synonyms': ['diaper'], 'def': 'garment consisting of a folded cloth drawn up between the legs and fastened at the waist', 'name': 'diaper'}, {'frequency': 'r', 'id': 368, 'synset': 'diary.n.01', 'synonyms': ['diary', 'journal'], 'def': 'a daily written record of (usually personal) experiences and observations', 'name': 'diary'}, {'frequency': 'r', 'id': 369, 'synset': 'die.n.01', 'synonyms': ['die', 'dice'], 'def': 'a small cube with 1 to 6 spots on the six faces; used in gambling', 'name': 'die'}, {'frequency': 'r', 'id': 370, 'synset': 'dinghy.n.01', 'synonyms': ['dinghy', 'dory', 'rowboat'], 'def': 'a small boat of shallow draft with seats and oars with which it is propelled', 'name': 'dinghy'}, {'frequency': 'f', 'id': 371, 'synset': 'dining_table.n.01', 'synonyms': ['dining_table'], 'def': 'a table at which meals are served', 'name': 'dining_table'}, {'frequency': 'r', 'id': 372, 'synset': 'dinner_jacket.n.01', 'synonyms': ['tux', 'tuxedo'], 'def': 'semiformal evening dress for men', 'name': 'tux'}, {'frequency': 'c', 'id': 373, 'synset': 'dish.n.01', 'synonyms': ['dish'], 'def': 'a piece of dishware normally used as a container for holding or serving food', 'name': 'dish'}, {'frequency': 'c', 'id': 374, 'synset': 'dish.n.05', 'synonyms': ['dish_antenna'], 'def': 'directional antenna consisting of a parabolic reflector', 'name': 'dish_antenna'}, {'frequency': 'c', 'id': 375, 'synset': 'dishrag.n.01', 'synonyms': ['dishrag', 'dishcloth'], 'def': 'a cloth for washing dishes', 'name': 'dishrag'}, {'frequency': 'c', 'id': 376, 'synset': 'dishtowel.n.01', 'synonyms': ['dishtowel', 'tea_towel'], 'def': 'a towel for drying dishes', 'name': 'dishtowel'}, {'frequency': 'f', 'id': 377, 'synset': 'dishwasher.n.01', 'synonyms': ['dishwasher', 'dishwashing_machine'], 'def': 'a machine for washing dishes', 'name': 'dishwasher'}, {'frequency': 'r', 'id': 378, 'synset': 'dishwasher_detergent.n.01', 'synonyms': ['dishwasher_detergent', 'dishwashing_detergent', 'dishwashing_liquid'], 'def': 'a low-sudsing detergent designed for use in dishwashers', 'name': 'dishwasher_detergent'}, {'frequency': 'r', 'id': 379, 'synset': 'diskette.n.01', 'synonyms': ['diskette', 'floppy', 'floppy_disk'], 'def': 'a small plastic magnetic disk enclosed in a stiff envelope used to store data', 'name': 'diskette'}, {'frequency': 'c', 'id': 380, 'synset': 'dispenser.n.01', 'synonyms': ['dispenser'], 'def': 'a container so designed that the contents can be used in prescribed amounts', 'name': 'dispenser'}, {'frequency': 'c', 'id': 381, 'synset': 'dixie_cup.n.01', 'synonyms': ['Dixie_cup', 'paper_cup'], 'def': 'a disposable cup made of paper; for holding drinks', 'name': 'Dixie_cup'}, {'frequency': 'f', 'id': 382, 'synset': 'dog.n.01', 'synonyms': ['dog'], 'def': 'a common domesticated dog', 'name': 'dog'}, {'frequency': 'f', 'id': 383, 'synset': 'dog_collar.n.01', 'synonyms': ['dog_collar'], 'def': 'a collar for a dog', 'name': 'dog_collar'}, {'frequency': 'c', 'id': 384, 'synset': 'doll.n.01', 'synonyms': ['doll'], 'def': 'a toy replica of a HUMAN (NOT AN ANIMAL)', 'name': 'doll'}, {'frequency': 'r', 'id': 385, 'synset': 'dollar.n.02', 'synonyms': ['dollar', 'dollar_bill', 'one_dollar_bill'], 'def': 'a piece of paper money worth one dollar', 'name': 'dollar'}, {'frequency': 'r', 'id': 386, 'synset': 'dolphin.n.02', 'synonyms': ['dolphin'], 'def': 'any of various small toothed whales with a beaklike snout; larger than porpoises', 'name': 'dolphin'}, {'frequency': 'c', 'id': 387, 'synset': 'domestic_ass.n.01', 'synonyms': ['domestic_ass', 'donkey'], 'def': 'domestic beast of burden descended from the African wild ass; patient but stubborn', 'name': 'domestic_ass'}, {'frequency': 'r', 'id': 388, 'synset': 'domino.n.03', 'synonyms': ['eye_mask'], 'def': 'a mask covering the upper part of the face but with holes for the eyes', 'name': 'eye_mask'}, {'frequency': 'r', 'id': 389, 'synset': 'doorbell.n.01', 'synonyms': ['doorbell', 'buzzer'], 'def': 'a button at an outer door that gives a ringing or buzzing signal when pushed', 'name': 'doorbell'}, {'frequency': 'f', 'id': 390, 'synset': 'doorknob.n.01', 'synonyms': ['doorknob', 'doorhandle'], 'def': "a knob used to open a door (often called `doorhandle' in Great Britain)", 'name': 'doorknob'}, {'frequency': 'c', 'id': 391, 'synset': 'doormat.n.02', 'synonyms': ['doormat', 'welcome_mat'], 'def': 'a mat placed outside an exterior door for wiping the shoes before entering', 'name': 'doormat'}, {'frequency': 'f', 'id': 392, 'synset': 'doughnut.n.02', 'synonyms': ['doughnut', 'donut'], 'def': 'a small ring-shaped friedcake', 'name': 'doughnut'}, {'frequency': 'r', 'id': 393, 'synset': 'dove.n.01', 'synonyms': ['dove'], 'def': 'any of numerous small pigeons', 'name': 'dove'}, {'frequency': 'r', 'id': 394, 'synset': 'dragonfly.n.01', 'synonyms': ['dragonfly'], 'def': 'slender-bodied non-stinging insect having iridescent wings that are outspread at rest', 'name': 'dragonfly'}, {'frequency': 'f', 'id': 395, 'synset': 'drawer.n.01', 'synonyms': ['drawer'], 'def': 'a boxlike container in a piece of furniture; made so as to slide in and out', 'name': 'drawer'}, {'frequency': 'c', 'id': 396, 'synset': 'drawers.n.01', 'synonyms': ['underdrawers', 'boxers', 'boxershorts'], 'def': 'underpants worn by men', 'name': 'underdrawers'}, {'frequency': 'f', 'id': 397, 'synset': 'dress.n.01', 'synonyms': ['dress', 'frock'], 'def': 'a one-piece garment for a woman; has skirt and bodice', 'name': 'dress'}, {'frequency': 'c', 'id': 398, 'synset': 'dress_hat.n.01', 'synonyms': ['dress_hat', 'high_hat', 'opera_hat', 'silk_hat', 'top_hat'], 'def': "a man's hat with a tall crown; usually covered with silk or with beaver fur", 'name': 'dress_hat'}, {'frequency': 'c', 'id': 399, 'synset': 'dress_suit.n.01', 'synonyms': ['dress_suit'], 'def': 'formalwear consisting of full evening dress for men', 'name': 'dress_suit'}, {'frequency': 'c', 'id': 400, 'synset': 'dresser.n.05', 'synonyms': ['dresser'], 'def': 'a cabinet with shelves', 'name': 'dresser'}, {'frequency': 'c', 'id': 401, 'synset': 'drill.n.01', 'synonyms': ['drill'], 'def': 'a tool with a sharp rotating point for making holes in hard materials', 'name': 'drill'}, {'frequency': 'r', 'id': 402, 'synset': 'drinking_fountain.n.01', 'synonyms': ['drinking_fountain'], 'def': 'a public fountain to provide a jet of drinking water', 'name': 'drinking_fountain'}, {'frequency': 'r', 'id': 403, 'synset': 'drone.n.04', 'synonyms': ['drone'], 'def': 'an aircraft without a pilot that is operated by remote control', 'name': 'drone'}, {'frequency': 'r', 'id': 404, 'synset': 'dropper.n.01', 'synonyms': ['dropper', 'eye_dropper'], 'def': 'pipet consisting of a small tube with a vacuum bulb at one end for drawing liquid in and releasing it a drop at a time', 'name': 'dropper'}, {'frequency': 'c', 'id': 405, 'synset': 'drum.n.01', 'synonyms': ['drum_(musical_instrument)'], 'def': 'a musical percussion instrument; usually consists of a hollow cylinder with a membrane stretched across each end', 'name': 'drum_(musical_instrument)'}, {'frequency': 'r', 'id': 406, 'synset': 'drumstick.n.02', 'synonyms': ['drumstick'], 'def': 'a stick used for playing a drum', 'name': 'drumstick'}, {'frequency': 'f', 'id': 407, 'synset': 'duck.n.01', 'synonyms': ['duck'], 'def': 'small web-footed broad-billed swimming bird', 'name': 'duck'}, {'frequency': 'r', 'id': 408, 'synset': 'duckling.n.02', 'synonyms': ['duckling'], 'def': 'young duck', 'name': 'duckling'}, {'frequency': 'c', 'id': 409, 'synset': 'duct_tape.n.01', 'synonyms': ['duct_tape'], 'def': 'a wide silvery adhesive tape', 'name': 'duct_tape'}, {'frequency': 'f', 'id': 410, 'synset': 'duffel_bag.n.01', 'synonyms': ['duffel_bag', 'duffle_bag', 'duffel', 'duffle'], 'def': 'a large cylindrical bag of heavy cloth', 'name': 'duffel_bag'}, {'frequency': 'r', 'id': 411, 'synset': 'dumbbell.n.01', 'synonyms': ['dumbbell'], 'def': 'an exercising weight with two ball-like ends connected by a short handle', 'name': 'dumbbell'}, {'frequency': 'c', 'id': 412, 'synset': 'dumpster.n.01', 'synonyms': ['dumpster'], 'def': 'a container designed to receive and transport and dump waste', 'name': 'dumpster'}, {'frequency': 'r', 'id': 413, 'synset': 'dustpan.n.02', 'synonyms': ['dustpan'], 'def': 'a short-handled receptacle into which dust can be swept', 'name': 'dustpan'}, {'frequency': 'r', 'id': 414, 'synset': 'dutch_oven.n.02', 'synonyms': ['Dutch_oven'], 'def': 'iron or earthenware cooking pot; used for stews', 'name': 'Dutch_oven'}, {'frequency': 'c', 'id': 415, 'synset': 'eagle.n.01', 'synonyms': ['eagle'], 'def': 'large birds of prey noted for their broad wings and strong soaring flight', 'name': 'eagle'}, {'frequency': 'f', 'id': 416, 'synset': 'earphone.n.01', 'synonyms': ['earphone', 'earpiece', 'headphone'], 'def': 'device for listening to audio that is held over or inserted into the ear', 'name': 'earphone'}, {'frequency': 'r', 'id': 417, 'synset': 'earplug.n.01', 'synonyms': ['earplug'], 'def': 'a soft plug that is inserted into the ear canal to block sound', 'name': 'earplug'}, {'frequency': 'f', 'id': 418, 'synset': 'earring.n.01', 'synonyms': ['earring'], 'def': 'jewelry to ornament the ear', 'name': 'earring'}, {'frequency': 'c', 'id': 419, 'synset': 'easel.n.01', 'synonyms': ['easel'], 'def': "an upright tripod for displaying something (usually an artist's canvas)", 'name': 'easel'}, {'frequency': 'r', 'id': 420, 'synset': 'eclair.n.01', 'synonyms': ['eclair'], 'def': 'oblong cream puff', 'name': 'eclair'}, {'frequency': 'r', 'id': 421, 'synset': 'eel.n.01', 'synonyms': ['eel'], 'def': 'an elongate fish with fatty flesh', 'name': 'eel'}, {'frequency': 'f', 'id': 422, 'synset': 'egg.n.02', 'synonyms': ['egg', 'eggs'], 'def': 'oval reproductive body of a fowl (especially a hen) used as food', 'name': 'egg'}, {'frequency': 'r', 'id': 423, 'synset': 'egg_roll.n.01', 'synonyms': ['egg_roll', 'spring_roll'], 'def': 'minced vegetables and meat wrapped in a pancake and fried', 'name': 'egg_roll'}, {'frequency': 'c', 'id': 424, 'synset': 'egg_yolk.n.01', 'synonyms': ['egg_yolk', 'yolk_(egg)'], 'def': 'the yellow spherical part of an egg', 'name': 'egg_yolk'}, {'frequency': 'c', 'id': 425, 'synset': 'eggbeater.n.02', 'synonyms': ['eggbeater', 'eggwhisk'], 'def': 'a mixer for beating eggs or whipping cream', 'name': 'eggbeater'}, {'frequency': 'c', 'id': 426, 'synset': 'eggplant.n.01', 'synonyms': ['eggplant', 'aubergine'], 'def': 'egg-shaped vegetable having a shiny skin typically dark purple', 'name': 'eggplant'}, {'frequency': 'r', 'id': 427, 'synset': 'electric_chair.n.01', 'synonyms': ['electric_chair'], 'def': 'a chair-shaped instrument of execution by electrocution', 'name': 'electric_chair'}, {'frequency': 'f', 'id': 428, 'synset': 'electric_refrigerator.n.01', 'synonyms': ['refrigerator'], 'def': 'a refrigerator in which the coolant is pumped around by an electric motor', 'name': 'refrigerator'}, {'frequency': 'f', 'id': 429, 'synset': 'elephant.n.01', 'synonyms': ['elephant'], 'def': 'a common elephant', 'name': 'elephant'}, {'frequency': 'r', 'id': 430, 'synset': 'elk.n.01', 'synonyms': ['elk', 'moose'], 'def': 'large northern deer with enormous flattened antlers in the male', 'name': 'elk'}, {'frequency': 'c', 'id': 431, 'synset': 'envelope.n.01', 'synonyms': ['envelope'], 'def': 'a flat (usually rectangular) container for a letter, thin package, etc.', 'name': 'envelope'}, {'frequency': 'c', 'id': 432, 'synset': 'eraser.n.01', 'synonyms': ['eraser'], 'def': 'an implement used to erase something', 'name': 'eraser'}, {'frequency': 'r', 'id': 433, 'synset': 'escargot.n.01', 'synonyms': ['escargot'], 'def': 'edible snail usually served in the shell with a sauce of melted butter and garlic', 'name': 'escargot'}, {'frequency': 'r', 'id': 434, 'synset': 'eyepatch.n.01', 'synonyms': ['eyepatch'], 'def': 'a protective cloth covering for an injured eye', 'name': 'eyepatch'}, {'frequency': 'r', 'id': 435, 'synset': 'falcon.n.01', 'synonyms': ['falcon'], 'def': 'birds of prey having long pointed powerful wings adapted for swift flight', 'name': 'falcon'}, {'frequency': 'f', 'id': 436, 'synset': 'fan.n.01', 'synonyms': ['fan'], 'def': 'a device for creating a current of air by movement of a surface or surfaces', 'name': 'fan'}, {'frequency': 'f', 'id': 437, 'synset': 'faucet.n.01', 'synonyms': ['faucet', 'spigot', 'tap'], 'def': 'a regulator for controlling the flow of a liquid from a reservoir', 'name': 'faucet'}, {'frequency': 'r', 'id': 438, 'synset': 'fedora.n.01', 'synonyms': ['fedora'], 'def': 'a hat made of felt with a creased crown', 'name': 'fedora'}, {'frequency': 'r', 'id': 439, 'synset': 'ferret.n.02', 'synonyms': ['ferret'], 'def': 'domesticated albino variety of the European polecat bred for hunting rats and rabbits', 'name': 'ferret'}, {'frequency': 'c', 'id': 440, 'synset': 'ferris_wheel.n.01', 'synonyms': ['Ferris_wheel'], 'def': 'a large wheel with suspended seats that remain upright as the wheel rotates', 'name': 'Ferris_wheel'}, {'frequency': 'r', 'id': 441, 'synset': 'ferry.n.01', 'synonyms': ['ferry', 'ferryboat'], 'def': 'a boat that transports people or vehicles across a body of water and operates on a regular schedule', 'name': 'ferry'}, {'frequency': 'r', 'id': 442, 'synset': 'fig.n.04', 'synonyms': ['fig_(fruit)'], 'def': 'fleshy sweet pear-shaped yellowish or purple fruit eaten fresh or preserved or dried', 'name': 'fig_(fruit)'}, {'frequency': 'c', 'id': 443, 'synset': 'fighter.n.02', 'synonyms': ['fighter_jet', 'fighter_aircraft', 'attack_aircraft'], 'def': 'a high-speed military or naval airplane designed to destroy enemy targets', 'name': 'fighter_jet'}, {'frequency': 'f', 'id': 444, 'synset': 'figurine.n.01', 'synonyms': ['figurine'], 'def': 'a small carved or molded figure', 'name': 'figurine'}, {'frequency': 'c', 'id': 445, 'synset': 'file.n.03', 'synonyms': ['file_cabinet', 'filing_cabinet'], 'def': 'office furniture consisting of a container for keeping papers in order', 'name': 'file_cabinet'}, {'frequency': 'r', 'id': 446, 'synset': 'file.n.04', 'synonyms': ['file_(tool)'], 'def': 'a steel hand tool with small sharp teeth on some or all of its surfaces; used for smoothing wood or metal', 'name': 'file_(tool)'}, {'frequency': 'f', 'id': 447, 'synset': 'fire_alarm.n.02', 'synonyms': ['fire_alarm', 'smoke_alarm'], 'def': 'an alarm that is tripped off by fire or smoke', 'name': 'fire_alarm'}, {'frequency': 'c', 'id': 448, 'synset': 'fire_engine.n.01', 'synonyms': ['fire_engine', 'fire_truck'], 'def': 'large trucks that carry firefighters and equipment to the site of a fire', 'name': 'fire_engine'}, {'frequency': 'c', 'id': 449, 'synset': 'fire_extinguisher.n.01', 'synonyms': ['fire_extinguisher', 'extinguisher'], 'def': 'a manually operated device for extinguishing small fires', 'name': 'fire_extinguisher'}, {'frequency': 'c', 'id': 450, 'synset': 'fire_hose.n.01', 'synonyms': ['fire_hose'], 'def': 'a large hose that carries water from a fire hydrant to the site of the fire', 'name': 'fire_hose'}, {'frequency': 'f', 'id': 451, 'synset': 'fireplace.n.01', 'synonyms': ['fireplace'], 'def': 'an open recess in a wall at the base of a chimney where a fire can be built', 'name': 'fireplace'}, {'frequency': 'f', 'id': 452, 'synset': 'fireplug.n.01', 'synonyms': ['fireplug', 'fire_hydrant', 'hydrant'], 'def': 'an upright hydrant for drawing water to use in fighting a fire', 'name': 'fireplug'}, {'frequency': 'c', 'id': 453, 'synset': 'fish.n.01', 'synonyms': ['fish'], 'def': 'any of various mostly cold-blooded aquatic vertebrates usually having scales and breathing through gills', 'name': 'fish'}, {'frequency': 'r', 'id': 454, 'synset': 'fish.n.02', 'synonyms': ['fish_(food)'], 'def': 'the flesh of fish used as food', 'name': 'fish_(food)'}, {'frequency': 'r', 'id': 455, 'synset': 'fishbowl.n.02', 'synonyms': ['fishbowl', 'goldfish_bowl'], 'def': 'a transparent bowl in which small fish are kept', 'name': 'fishbowl'}, {'frequency': 'r', 'id': 456, 'synset': 'fishing_boat.n.01', 'synonyms': ['fishing_boat', 'fishing_vessel'], 'def': 'a vessel for fishing', 'name': 'fishing_boat'}, {'frequency': 'c', 'id': 457, 'synset': 'fishing_rod.n.01', 'synonyms': ['fishing_rod', 'fishing_pole'], 'def': 'a rod that is used in fishing to extend the fishing line', 'name': 'fishing_rod'}, {'frequency': 'f', 'id': 458, 'synset': 'flag.n.01', 'synonyms': ['flag'], 'def': 'emblem usually consisting of a rectangular piece of cloth of distinctive design (do not include pole)', 'name': 'flag'}, {'frequency': 'f', 'id': 459, 'synset': 'flagpole.n.02', 'synonyms': ['flagpole', 'flagstaff'], 'def': 'a tall staff or pole on which a flag is raised', 'name': 'flagpole'}, {'frequency': 'c', 'id': 460, 'synset': 'flamingo.n.01', 'synonyms': ['flamingo'], 'def': 'large pink web-footed bird with down-bent bill', 'name': 'flamingo'}, {'frequency': 'c', 'id': 461, 'synset': 'flannel.n.01', 'synonyms': ['flannel'], 'def': 'a soft light woolen fabric; used for clothing', 'name': 'flannel'}, {'frequency': 'r', 'id': 462, 'synset': 'flash.n.10', 'synonyms': ['flash', 'flashbulb'], 'def': 'a lamp for providing momentary light to take a photograph', 'name': 'flash'}, {'frequency': 'c', 'id': 463, 'synset': 'flashlight.n.01', 'synonyms': ['flashlight', 'torch'], 'def': 'a small portable battery-powered electric lamp', 'name': 'flashlight'}, {'frequency': 'r', 'id': 464, 'synset': 'fleece.n.03', 'synonyms': ['fleece'], 'def': 'a soft bulky fabric with deep pile; used chiefly for clothing', 'name': 'fleece'}, {'frequency': 'f', 'id': 465, 'synset': 'flip-flop.n.02', 'synonyms': ['flip-flop_(sandal)'], 'def': 'a backless sandal held to the foot by a thong between two toes', 'name': 'flip-flop_(sandal)'}, {'frequency': 'c', 'id': 466, 'synset': 'flipper.n.01', 'synonyms': ['flipper_(footwear)', 'fin_(footwear)'], 'def': 'a shoe to aid a person in swimming', 'name': 'flipper_(footwear)'}, {'frequency': 'f', 'id': 467, 'synset': 'flower_arrangement.n.01', 'synonyms': ['flower_arrangement', 'floral_arrangement'], 'def': 'a decorative arrangement of flowers', 'name': 'flower_arrangement'}, {'frequency': 'c', 'id': 468, 'synset': 'flute.n.02', 'synonyms': ['flute_glass', 'champagne_flute'], 'def': 'a tall narrow wineglass', 'name': 'flute_glass'}, {'frequency': 'r', 'id': 469, 'synset': 'foal.n.01', 'synonyms': ['foal'], 'def': 'a young horse', 'name': 'foal'}, {'frequency': 'c', 'id': 470, 'synset': 'folding_chair.n.01', 'synonyms': ['folding_chair'], 'def': 'a chair that can be folded flat for storage', 'name': 'folding_chair'}, {'frequency': 'c', 'id': 471, 'synset': 'food_processor.n.01', 'synonyms': ['food_processor'], 'def': 'a kitchen appliance for shredding, blending, chopping, or slicing food', 'name': 'food_processor'}, {'frequency': 'c', 'id': 472, 'synset': 'football.n.02', 'synonyms': ['football_(American)'], 'def': 'the inflated oblong ball used in playing American football', 'name': 'football_(American)'}, {'frequency': 'r', 'id': 473, 'synset': 'football_helmet.n.01', 'synonyms': ['football_helmet'], 'def': 'a padded helmet with a face mask to protect the head of football players', 'name': 'football_helmet'}, {'frequency': 'c', 'id': 474, 'synset': 'footstool.n.01', 'synonyms': ['footstool', 'footrest'], 'def': 'a low seat or a stool to rest the feet of a seated person', 'name': 'footstool'}, {'frequency': 'f', 'id': 475, 'synset': 'fork.n.01', 'synonyms': ['fork'], 'def': 'cutlery used for serving and eating food', 'name': 'fork'}, {'frequency': 'r', 'id': 476, 'synset': 'forklift.n.01', 'synonyms': ['forklift'], 'def': 'an industrial vehicle with a power operated fork in front that can be inserted under loads to lift and move them', 'name': 'forklift'}, {'frequency': 'r', 'id': 477, 'synset': 'freight_car.n.01', 'synonyms': ['freight_car'], 'def': 'a railway car that carries freight', 'name': 'freight_car'}, {'frequency': 'r', 'id': 478, 'synset': 'french_toast.n.01', 'synonyms': ['French_toast'], 'def': 'bread slice dipped in egg and milk and fried', 'name': 'French_toast'}, {'frequency': 'c', 'id': 479, 'synset': 'freshener.n.01', 'synonyms': ['freshener', 'air_freshener'], 'def': 'anything that freshens', 'name': 'freshener'}, {'frequency': 'f', 'id': 480, 'synset': 'frisbee.n.01', 'synonyms': ['frisbee'], 'def': 'a light, plastic disk propelled with a flip of the wrist for recreation or competition', 'name': 'frisbee'}, {'frequency': 'c', 'id': 481, 'synset': 'frog.n.01', 'synonyms': ['frog', 'toad', 'toad_frog'], 'def': 'a tailless stout-bodied amphibians with long hind limbs for leaping', 'name': 'frog'}, {'frequency': 'c', 'id': 482, 'synset': 'fruit_juice.n.01', 'synonyms': ['fruit_juice'], 'def': 'drink produced by squeezing or crushing fruit', 'name': 'fruit_juice'}, {'frequency': 'r', 'id': 483, 'synset': 'fruit_salad.n.01', 'synonyms': ['fruit_salad'], 'def': 'salad composed of fruits', 'name': 'fruit_salad'}, {'frequency': 'c', 'id': 484, 'synset': 'frying_pan.n.01', 'synonyms': ['frying_pan', 'frypan', 'skillet'], 'def': 'a pan used for frying foods', 'name': 'frying_pan'}, {'frequency': 'r', 'id': 485, 'synset': 'fudge.n.01', 'synonyms': ['fudge'], 'def': 'soft creamy candy', 'name': 'fudge'}, {'frequency': 'r', 'id': 486, 'synset': 'funnel.n.02', 'synonyms': ['funnel'], 'def': 'a cone-shaped utensil used to channel a substance into a container with a small mouth', 'name': 'funnel'}, {'frequency': 'c', 'id': 487, 'synset': 'futon.n.01', 'synonyms': ['futon'], 'def': 'a pad that is used for sleeping on the floor or on a raised frame', 'name': 'futon'}, {'frequency': 'r', 'id': 488, 'synset': 'gag.n.02', 'synonyms': ['gag', 'muzzle'], 'def': "restraint put into a person's mouth to prevent speaking or shouting", 'name': 'gag'}, {'frequency': 'r', 'id': 489, 'synset': 'garbage.n.03', 'synonyms': ['garbage'], 'def': 'a receptacle where waste can be discarded', 'name': 'garbage'}, {'frequency': 'c', 'id': 490, 'synset': 'garbage_truck.n.01', 'synonyms': ['garbage_truck'], 'def': 'a truck for collecting domestic refuse', 'name': 'garbage_truck'}, {'frequency': 'c', 'id': 491, 'synset': 'garden_hose.n.01', 'synonyms': ['garden_hose'], 'def': 'a hose used for watering a lawn or garden', 'name': 'garden_hose'}, {'frequency': 'c', 'id': 492, 'synset': 'gargle.n.01', 'synonyms': ['gargle', 'mouthwash'], 'def': 'a medicated solution used for gargling and rinsing the mouth', 'name': 'gargle'}, {'frequency': 'r', 'id': 493, 'synset': 'gargoyle.n.02', 'synonyms': ['gargoyle'], 'def': 'an ornament consisting of a grotesquely carved figure of a person or animal', 'name': 'gargoyle'}, {'frequency': 'c', 'id': 494, 'synset': 'garlic.n.02', 'synonyms': ['garlic', 'ail'], 'def': 'aromatic bulb used as seasoning', 'name': 'garlic'}, {'frequency': 'r', 'id': 495, 'synset': 'gasmask.n.01', 'synonyms': ['gasmask', 'respirator', 'gas_helmet'], 'def': 'a protective face mask with a filter', 'name': 'gasmask'}, {'frequency': 'r', 'id': 496, 'synset': 'gazelle.n.01', 'synonyms': ['gazelle'], 'def': 'small swift graceful antelope of Africa and Asia having lustrous eyes', 'name': 'gazelle'}, {'frequency': 'c', 'id': 497, 'synset': 'gelatin.n.02', 'synonyms': ['gelatin', 'jelly'], 'def': 'an edible jelly made with gelatin and used as a dessert or salad base or a coating for foods', 'name': 'gelatin'}, {'frequency': 'r', 'id': 498, 'synset': 'gem.n.02', 'synonyms': ['gemstone'], 'def': 'a crystalline rock that can be cut and polished for jewelry', 'name': 'gemstone'}, {'frequency': 'c', 'id': 499, 'synset': 'giant_panda.n.01', 'synonyms': ['giant_panda', 'panda', 'panda_bear'], 'def': 'large black-and-white herbivorous mammal of bamboo forests of China and Tibet', 'name': 'giant_panda'}, {'frequency': 'c', 'id': 500, 'synset': 'gift_wrap.n.01', 'synonyms': ['gift_wrap'], 'def': 'attractive wrapping paper suitable for wrapping gifts', 'name': 'gift_wrap'}, {'frequency': 'c', 'id': 501, 'synset': 'ginger.n.03', 'synonyms': ['ginger', 'gingerroot'], 'def': 'the root of the common ginger plant; used fresh as a seasoning', 'name': 'ginger'}, {'frequency': 'f', 'id': 502, 'synset': 'giraffe.n.01', 'synonyms': ['giraffe'], 'def': 'tall animal having a spotted coat and small horns and very long neck and legs', 'name': 'giraffe'}, {'frequency': 'c', 'id': 503, 'synset': 'girdle.n.02', 'synonyms': ['cincture', 'sash', 'waistband', 'waistcloth'], 'def': 'a band of material around the waist that strengthens a skirt or trousers', 'name': 'cincture'}, {'frequency': 'f', 'id': 504, 'synset': 'glass.n.02', 'synonyms': ['glass_(drink_container)', 'drinking_glass'], 'def': 'a container for holding liquids while drinking', 'name': 'glass_(drink_container)'}, {'frequency': 'c', 'id': 505, 'synset': 'globe.n.03', 'synonyms': ['globe'], 'def': 'a sphere on which a map (especially of the earth) is represented', 'name': 'globe'}, {'frequency': 'f', 'id': 506, 'synset': 'glove.n.02', 'synonyms': ['glove'], 'def': 'handwear covering the hand', 'name': 'glove'}, {'frequency': 'c', 'id': 507, 'synset': 'goat.n.01', 'synonyms': ['goat'], 'def': 'a common goat', 'name': 'goat'}, {'frequency': 'f', 'id': 508, 'synset': 'goggles.n.01', 'synonyms': ['goggles'], 'def': 'tight-fitting spectacles worn to protect the eyes', 'name': 'goggles'}, {'frequency': 'r', 'id': 509, 'synset': 'goldfish.n.01', 'synonyms': ['goldfish'], 'def': 'small golden or orange-red freshwater fishes used as pond or aquarium pets', 'name': 'goldfish'}, {'frequency': 'r', 'id': 510, 'synset': 'golf_club.n.02', 'synonyms': ['golf_club', 'golf-club'], 'def': 'golf equipment used by a golfer to hit a golf ball', 'name': 'golf_club'}, {'frequency': 'c', 'id': 511, 'synset': 'golfcart.n.01', 'synonyms': ['golfcart'], 'def': 'a small motor vehicle in which golfers can ride between shots', 'name': 'golfcart'}, {'frequency': 'r', 'id': 512, 'synset': 'gondola.n.02', 'synonyms': ['gondola_(boat)'], 'def': 'long narrow flat-bottomed boat propelled by sculling; traditionally used on canals of Venice', 'name': 'gondola_(boat)'}, {'frequency': 'c', 'id': 513, 'synset': 'goose.n.01', 'synonyms': ['goose'], 'def': 'loud, web-footed long-necked aquatic birds usually larger than ducks', 'name': 'goose'}, {'frequency': 'r', 'id': 514, 'synset': 'gorilla.n.01', 'synonyms': ['gorilla'], 'def': 'largest ape', 'name': 'gorilla'}, {'frequency': 'r', 'id': 515, 'synset': 'gourd.n.02', 'synonyms': ['gourd'], 'def': 'any of numerous inedible fruits with hard rinds', 'name': 'gourd'}, {'frequency': 'r', 'id': 516, 'synset': 'gown.n.04', 'synonyms': ['surgical_gown', 'scrubs_(surgical_clothing)'], 'def': 'protective garment worn by surgeons during operations', 'name': 'surgical_gown'}, {'frequency': 'f', 'id': 517, 'synset': 'grape.n.01', 'synonyms': ['grape'], 'def': 'any of various juicy fruit with green or purple skins; grow in clusters', 'name': 'grape'}, {'frequency': 'r', 'id': 518, 'synset': 'grasshopper.n.01', 'synonyms': ['grasshopper'], 'def': 'plant-eating insect with hind legs adapted for leaping', 'name': 'grasshopper'}, {'frequency': 'c', 'id': 519, 'synset': 'grater.n.01', 'synonyms': ['grater'], 'def': 'utensil with sharp perforations for shredding foods (as vegetables or cheese)', 'name': 'grater'}, {'frequency': 'c', 'id': 520, 'synset': 'gravestone.n.01', 'synonyms': ['gravestone', 'headstone', 'tombstone'], 'def': 'a stone that is used to mark a grave', 'name': 'gravestone'}, {'frequency': 'r', 'id': 521, 'synset': 'gravy_boat.n.01', 'synonyms': ['gravy_boat', 'gravy_holder'], 'def': 'a dish (often boat-shaped) for serving gravy or sauce', 'name': 'gravy_boat'}, {'frequency': 'c', 'id': 522, 'synset': 'green_bean.n.02', 'synonyms': ['green_bean'], 'def': 'a common bean plant cultivated for its slender green edible pods', 'name': 'green_bean'}, {'frequency': 'c', 'id': 523, 'synset': 'green_onion.n.01', 'synonyms': ['green_onion', 'spring_onion', 'scallion'], 'def': 'a young onion before the bulb has enlarged', 'name': 'green_onion'}, {'frequency': 'r', 'id': 524, 'synset': 'griddle.n.01', 'synonyms': ['griddle'], 'def': 'cooking utensil consisting of a flat heated surface on which food is cooked', 'name': 'griddle'}, {'frequency': 'r', 'id': 525, 'synset': 'grillroom.n.01', 'synonyms': ['grillroom', 'grill_(restaurant)'], 'def': 'a restaurant where food is cooked on a grill', 'name': 'grillroom'}, {'frequency': 'r', 'id': 526, 'synset': 'grinder.n.04', 'synonyms': ['grinder_(tool)'], 'def': 'a machine tool that polishes metal', 'name': 'grinder_(tool)'}, {'frequency': 'r', 'id': 527, 'synset': 'grits.n.01', 'synonyms': ['grits', 'hominy_grits'], 'def': 'coarsely ground corn boiled as a breakfast dish', 'name': 'grits'}, {'frequency': 'c', 'id': 528, 'synset': 'grizzly.n.01', 'synonyms': ['grizzly', 'grizzly_bear'], 'def': 'powerful brownish-yellow bear of the uplands of western North America', 'name': 'grizzly'}, {'frequency': 'c', 'id': 529, 'synset': 'grocery_bag.n.01', 'synonyms': ['grocery_bag'], 'def': "a sack for holding customer's groceries", 'name': 'grocery_bag'}, {'frequency': 'r', 'id': 530, 'synset': 'guacamole.n.01', 'synonyms': ['guacamole'], 'def': 'a dip made of mashed avocado mixed with chopped onions and other seasonings', 'name': 'guacamole'}, {'frequency': 'f', 'id': 531, 'synset': 'guitar.n.01', 'synonyms': ['guitar'], 'def': 'a stringed instrument usually having six strings; played by strumming or plucking', 'name': 'guitar'}, {'frequency': 'c', 'id': 532, 'synset': 'gull.n.02', 'synonyms': ['gull', 'seagull'], 'def': 'mostly white aquatic bird having long pointed wings and short legs', 'name': 'gull'}, {'frequency': 'c', 'id': 533, 'synset': 'gun.n.01', 'synonyms': ['gun'], 'def': 'a weapon that discharges a bullet at high velocity from a metal tube', 'name': 'gun'}, {'frequency': 'r', 'id': 534, 'synset': 'hair_spray.n.01', 'synonyms': ['hair_spray'], 'def': 'substance sprayed on the hair to hold it in place', 'name': 'hair_spray'}, {'frequency': 'c', 'id': 535, 'synset': 'hairbrush.n.01', 'synonyms': ['hairbrush'], 'def': "a brush used to groom a person's hair", 'name': 'hairbrush'}, {'frequency': 'c', 'id': 536, 'synset': 'hairnet.n.01', 'synonyms': ['hairnet'], 'def': 'a small net that someone wears over their hair to keep it in place', 'name': 'hairnet'}, {'frequency': 'c', 'id': 537, 'synset': 'hairpin.n.01', 'synonyms': ['hairpin'], 'def': "a double pronged pin used to hold women's hair in place", 'name': 'hairpin'}, {'frequency': 'f', 'id': 538, 'synset': 'ham.n.01', 'synonyms': ['ham', 'jambon', 'gammon'], 'def': 'meat cut from the thigh of a hog (usually smoked)', 'name': 'ham'}, {'frequency': 'c', 'id': 539, 'synset': 'hamburger.n.01', 'synonyms': ['hamburger', 'beefburger', 'burger'], 'def': 'a sandwich consisting of a patty of minced beef served on a bun', 'name': 'hamburger'}, {'frequency': 'c', 'id': 540, 'synset': 'hammer.n.02', 'synonyms': ['hammer'], 'def': 'a hand tool with a heavy head and a handle; used to deliver an impulsive force by striking', 'name': 'hammer'}, {'frequency': 'r', 'id': 541, 'synset': 'hammock.n.02', 'synonyms': ['hammock'], 'def': 'a hanging bed of canvas or rope netting (usually suspended between two trees)', 'name': 'hammock'}, {'frequency': 'r', 'id': 542, 'synset': 'hamper.n.02', 'synonyms': ['hamper'], 'def': 'a basket usually with a cover', 'name': 'hamper'}, {'frequency': 'r', 'id': 543, 'synset': 'hamster.n.01', 'synonyms': ['hamster'], 'def': 'short-tailed burrowing rodent with large cheek pouches', 'name': 'hamster'}, {'frequency': 'c', 'id': 544, 'synset': 'hand_blower.n.01', 'synonyms': ['hair_dryer'], 'def': 'a hand-held electric blower that can blow warm air onto the hair', 'name': 'hair_dryer'}, {'frequency': 'r', 'id': 545, 'synset': 'hand_glass.n.01', 'synonyms': ['hand_glass', 'hand_mirror'], 'def': 'a mirror intended to be held in the hand', 'name': 'hand_glass'}, {'frequency': 'f', 'id': 546, 'synset': 'hand_towel.n.01', 'synonyms': ['hand_towel', 'face_towel'], 'def': 'a small towel used to dry the hands or face', 'name': 'hand_towel'}, {'frequency': 'c', 'id': 547, 'synset': 'handcart.n.01', 'synonyms': ['handcart', 'pushcart', 'hand_truck'], 'def': 'wheeled vehicle that can be pushed by a person', 'name': 'handcart'}, {'frequency': 'r', 'id': 548, 'synset': 'handcuff.n.01', 'synonyms': ['handcuff'], 'def': 'shackle that consists of a metal loop that can be locked around the wrist', 'name': 'handcuff'}, {'frequency': 'c', 'id': 549, 'synset': 'handkerchief.n.01', 'synonyms': ['handkerchief'], 'def': 'a square piece of cloth used for wiping the eyes or nose or as a costume accessory', 'name': 'handkerchief'}, {'frequency': 'f', 'id': 550, 'synset': 'handle.n.01', 'synonyms': ['handle', 'grip', 'handgrip'], 'def': 'the appendage to an object that is designed to be held in order to use or move it', 'name': 'handle'}, {'frequency': 'r', 'id': 551, 'synset': 'handsaw.n.01', 'synonyms': ['handsaw', "carpenter's_saw"], 'def': 'a saw used with one hand for cutting wood', 'name': 'handsaw'}, {'frequency': 'r', 'id': 552, 'synset': 'hardback.n.01', 'synonyms': ['hardback_book', 'hardcover_book'], 'def': 'a book with cardboard or cloth or leather covers', 'name': 'hardback_book'}, {'frequency': 'r', 'id': 553, 'synset': 'harmonium.n.01', 'synonyms': ['harmonium', 'organ_(musical_instrument)', 'reed_organ_(musical_instrument)'], 'def': 'a free-reed instrument in which air is forced through the reeds by bellows', 'name': 'harmonium'}, {'frequency': 'f', 'id': 554, 'synset': 'hat.n.01', 'synonyms': ['hat'], 'def': 'headwear that protects the head from bad weather, sun, or worn for fashion', 'name': 'hat'}, {'frequency': 'r', 'id': 555, 'synset': 'hatbox.n.01', 'synonyms': ['hatbox'], 'def': 'a round piece of luggage for carrying hats', 'name': 'hatbox'}, {'frequency': 'r', 'id': 556, 'synset': 'hatch.n.03', 'synonyms': ['hatch'], 'def': 'a movable barrier covering a hatchway', 'name': 'hatch'}, {'frequency': 'c', 'id': 557, 'synset': 'head_covering.n.01', 'synonyms': ['veil'], 'def': 'a garment that covers the head and face', 'name': 'veil'}, {'frequency': 'f', 'id': 558, 'synset': 'headband.n.01', 'synonyms': ['headband'], 'def': 'a band worn around or over the head', 'name': 'headband'}, {'frequency': 'f', 'id': 559, 'synset': 'headboard.n.01', 'synonyms': ['headboard'], 'def': 'a vertical board or panel forming the head of a bedstead', 'name': 'headboard'}, {'frequency': 'f', 'id': 560, 'synset': 'headlight.n.01', 'synonyms': ['headlight', 'headlamp'], 'def': 'a powerful light with reflector; attached to the front of an automobile or locomotive', 'name': 'headlight'}, {'frequency': 'c', 'id': 561, 'synset': 'headscarf.n.01', 'synonyms': ['headscarf'], 'def': 'a kerchief worn over the head and tied under the chin', 'name': 'headscarf'}, {'frequency': 'r', 'id': 562, 'synset': 'headset.n.01', 'synonyms': ['headset'], 'def': 'receiver consisting of a pair of headphones', 'name': 'headset'}, {'frequency': 'c', 'id': 563, 'synset': 'headstall.n.01', 'synonyms': ['headstall_(for_horses)', 'headpiece_(for_horses)'], 'def': "the band that is the part of a bridle that fits around a horse's head", 'name': 'headstall_(for_horses)'}, {'frequency': 'r', 'id': 564, 'synset': 'hearing_aid.n.02', 'synonyms': ['hearing_aid'], 'def': 'an acoustic device used to direct sound to the ear of a hearing-impaired person', 'name': 'hearing_aid'}, {'frequency': 'c', 'id': 565, 'synset': 'heart.n.02', 'synonyms': ['heart'], 'def': 'a muscular organ; its contractions move the blood through the body', 'name': 'heart'}, {'frequency': 'c', 'id': 566, 'synset': 'heater.n.01', 'synonyms': ['heater', 'warmer'], 'def': 'device that heats water or supplies warmth to a room', 'name': 'heater'}, {'frequency': 'c', 'id': 567, 'synset': 'helicopter.n.01', 'synonyms': ['helicopter'], 'def': 'an aircraft without wings that obtains its lift from the rotation of overhead blades', 'name': 'helicopter'}, {'frequency': 'f', 'id': 568, 'synset': 'helmet.n.02', 'synonyms': ['helmet'], 'def': 'a protective headgear made of hard material to resist blows', 'name': 'helmet'}, {'frequency': 'r', 'id': 569, 'synset': 'heron.n.02', 'synonyms': ['heron'], 'def': 'grey or white wading bird with long neck and long legs and (usually) long bill', 'name': 'heron'}, {'frequency': 'c', 'id': 570, 'synset': 'highchair.n.01', 'synonyms': ['highchair', 'feeding_chair'], 'def': 'a chair for feeding a very young child', 'name': 'highchair'}, {'frequency': 'f', 'id': 571, 'synset': 'hinge.n.01', 'synonyms': ['hinge'], 'def': 'a joint that holds two parts together so that one can swing relative to the other', 'name': 'hinge'}, {'frequency': 'r', 'id': 572, 'synset': 'hippopotamus.n.01', 'synonyms': ['hippopotamus'], 'def': 'massive thick-skinned animal living in or around rivers of tropical Africa', 'name': 'hippopotamus'}, {'frequency': 'r', 'id': 573, 'synset': 'hockey_stick.n.01', 'synonyms': ['hockey_stick'], 'def': 'sports implement consisting of a stick used by hockey players to move the puck', 'name': 'hockey_stick'}, {'frequency': 'c', 'id': 574, 'synset': 'hog.n.03', 'synonyms': ['hog', 'pig'], 'def': 'domestic swine', 'name': 'hog'}, {'frequency': 'f', 'id': 575, 'synset': 'home_plate.n.01', 'synonyms': ['home_plate_(baseball)', 'home_base_(baseball)'], 'def': '(baseball) a rubber slab where the batter stands; it must be touched by a base runner in order to score', 'name': 'home_plate_(baseball)'}, {'frequency': 'c', 'id': 576, 'synset': 'honey.n.01', 'synonyms': ['honey'], 'def': 'a sweet yellow liquid produced by bees', 'name': 'honey'}, {'frequency': 'f', 'id': 577, 'synset': 'hood.n.06', 'synonyms': ['fume_hood', 'exhaust_hood'], 'def': 'metal covering leading to a vent that exhausts smoke or fumes', 'name': 'fume_hood'}, {'frequency': 'f', 'id': 578, 'synset': 'hook.n.05', 'synonyms': ['hook'], 'def': 'a curved or bent implement for suspending or pulling something', 'name': 'hook'}, {'frequency': 'f', 'id': 579, 'synset': 'horse.n.01', 'synonyms': ['horse'], 'def': 'a common horse', 'name': 'horse'}, {'frequency': 'f', 'id': 580, 'synset': 'hose.n.03', 'synonyms': ['hose', 'hosepipe'], 'def': 'a flexible pipe for conveying a liquid or gas', 'name': 'hose'}, {'frequency': 'r', 'id': 581, 'synset': 'hot-air_balloon.n.01', 'synonyms': ['hot-air_balloon'], 'def': 'balloon for travel through the air in a basket suspended below a large bag of heated air', 'name': 'hot-air_balloon'}, {'frequency': 'r', 'id': 582, 'synset': 'hot_plate.n.01', 'synonyms': ['hotplate'], 'def': 'a portable electric appliance for heating or cooking or keeping food warm', 'name': 'hotplate'}, {'frequency': 'c', 'id': 583, 'synset': 'hot_sauce.n.01', 'synonyms': ['hot_sauce'], 'def': 'a pungent peppery sauce', 'name': 'hot_sauce'}, {'frequency': 'r', 'id': 584, 'synset': 'hourglass.n.01', 'synonyms': ['hourglass'], 'def': 'a sandglass timer that runs for sixty minutes', 'name': 'hourglass'}, {'frequency': 'r', 'id': 585, 'synset': 'houseboat.n.01', 'synonyms': ['houseboat'], 'def': 'a barge that is designed and equipped for use as a dwelling', 'name': 'houseboat'}, {'frequency': 'r', 'id': 586, 'synset': 'hummingbird.n.01', 'synonyms': ['hummingbird'], 'def': 'tiny American bird having brilliant iridescent plumage and long slender bills', 'name': 'hummingbird'}, {'frequency': 'r', 'id': 587, 'synset': 'hummus.n.01', 'synonyms': ['hummus', 'humus', 'hommos', 'hoummos', 'humous'], 'def': 'a thick spread made from mashed chickpeas', 'name': 'hummus'}, {'frequency': 'c', 'id': 588, 'synset': 'ice_bear.n.01', 'synonyms': ['polar_bear'], 'def': 'white bear of Arctic regions', 'name': 'polar_bear'}, {'frequency': 'c', 'id': 589, 'synset': 'ice_cream.n.01', 'synonyms': ['icecream'], 'def': 'frozen dessert containing cream and sugar and flavoring', 'name': 'icecream'}, {'frequency': 'r', 'id': 590, 'synset': 'ice_lolly.n.01', 'synonyms': ['popsicle'], 'def': 'ice cream or water ice on a small wooden stick', 'name': 'popsicle'}, {'frequency': 'c', 'id': 591, 'synset': 'ice_maker.n.01', 'synonyms': ['ice_maker'], 'def': 'an appliance included in some electric refrigerators for making ice cubes', 'name': 'ice_maker'}, {'frequency': 'r', 'id': 592, 'synset': 'ice_pack.n.01', 'synonyms': ['ice_pack', 'ice_bag'], 'def': 'a waterproof bag filled with ice: applied to the body (especially the head) to cool or reduce swelling', 'name': 'ice_pack'}, {'frequency': 'r', 'id': 593, 'synset': 'ice_skate.n.01', 'synonyms': ['ice_skate'], 'def': 'skate consisting of a boot with a steel blade fitted to the sole', 'name': 'ice_skate'}, {'frequency': 'r', 'id': 594, 'synset': 'ice_tea.n.01', 'synonyms': ['ice_tea', 'iced_tea'], 'def': 'strong tea served over ice', 'name': 'ice_tea'}, {'frequency': 'c', 'id': 595, 'synset': 'igniter.n.01', 'synonyms': ['igniter', 'ignitor', 'lighter'], 'def': 'a substance or device used to start a fire', 'name': 'igniter'}, {'frequency': 'r', 'id': 596, 'synset': 'incense.n.01', 'synonyms': ['incense'], 'def': 'a substance that produces a fragrant odor when burned', 'name': 'incense'}, {'frequency': 'r', 'id': 597, 'synset': 'inhaler.n.01', 'synonyms': ['inhaler', 'inhalator'], 'def': 'a dispenser that produces a chemical vapor to be inhaled through mouth or nose', 'name': 'inhaler'}, {'frequency': 'c', 'id': 598, 'synset': 'ipod.n.01', 'synonyms': ['iPod'], 'def': 'a pocket-sized device used to play music files', 'name': 'iPod'}, {'frequency': 'c', 'id': 599, 'synset': 'iron.n.04', 'synonyms': ['iron_(for_clothing)', 'smoothing_iron_(for_clothing)'], 'def': 'home appliance consisting of a flat metal base that is heated and used to smooth cloth', 'name': 'iron_(for_clothing)'}, {'frequency': 'r', 'id': 600, 'synset': 'ironing_board.n.01', 'synonyms': ['ironing_board'], 'def': 'narrow padded board on collapsible supports; used for ironing clothes', 'name': 'ironing_board'}, {'frequency': 'f', 'id': 601, 'synset': 'jacket.n.01', 'synonyms': ['jacket'], 'def': 'a waist-length coat', 'name': 'jacket'}, {'frequency': 'r', 'id': 602, 'synset': 'jam.n.01', 'synonyms': ['jam'], 'def': 'preserve of crushed fruit', 'name': 'jam'}, {'frequency': 'f', 'id': 603, 'synset': 'jean.n.01', 'synonyms': ['jean', 'blue_jean', 'denim'], 'def': '(usually plural) close-fitting trousers of heavy denim for manual work or casual wear', 'name': 'jean'}, {'frequency': 'c', 'id': 604, 'synset': 'jeep.n.01', 'synonyms': ['jeep', 'landrover'], 'def': 'a car suitable for traveling over rough terrain', 'name': 'jeep'}, {'frequency': 'r', 'id': 605, 'synset': 'jelly_bean.n.01', 'synonyms': ['jelly_bean', 'jelly_egg'], 'def': 'sugar-glazed jellied candy', 'name': 'jelly_bean'}, {'frequency': 'f', 'id': 606, 'synset': 'jersey.n.03', 'synonyms': ['jersey', 'T-shirt', 'tee_shirt'], 'def': 'a close-fitting pullover shirt', 'name': 'jersey'}, {'frequency': 'c', 'id': 607, 'synset': 'jet.n.01', 'synonyms': ['jet_plane', 'jet-propelled_plane'], 'def': 'an airplane powered by one or more jet engines', 'name': 'jet_plane'}, {'frequency': 'c', 'id': 608, 'synset': 'jewelry.n.01', 'synonyms': ['jewelry', 'jewellery'], 'def': 'an adornment (as a bracelet or ring or necklace) made of precious metals and set with gems (or imitation gems)', 'name': 'jewelry'}, {'frequency': 'r', 'id': 609, 'synset': 'joystick.n.02', 'synonyms': ['joystick'], 'def': 'a control device for computers consisting of a vertical handle that can move freely in two directions', 'name': 'joystick'}, {'frequency': 'r', 'id': 610, 'synset': 'jump_suit.n.01', 'synonyms': ['jumpsuit'], 'def': "one-piece garment fashioned after a parachutist's uniform", 'name': 'jumpsuit'}, {'frequency': 'c', 'id': 611, 'synset': 'kayak.n.01', 'synonyms': ['kayak'], 'def': 'a small canoe consisting of a light frame made watertight with animal skins', 'name': 'kayak'}, {'frequency': 'r', 'id': 612, 'synset': 'keg.n.02', 'synonyms': ['keg'], 'def': 'small cask or barrel', 'name': 'keg'}, {'frequency': 'r', 'id': 613, 'synset': 'kennel.n.01', 'synonyms': ['kennel', 'doghouse'], 'def': 'outbuilding that serves as a shelter for a dog', 'name': 'kennel'}, {'frequency': 'c', 'id': 614, 'synset': 'kettle.n.01', 'synonyms': ['kettle', 'boiler'], 'def': 'a metal pot for stewing or boiling; usually has a lid', 'name': 'kettle'}, {'frequency': 'f', 'id': 615, 'synset': 'key.n.01', 'synonyms': ['key'], 'def': 'metal instrument used to unlock a lock', 'name': 'key'}, {'frequency': 'r', 'id': 616, 'synset': 'keycard.n.01', 'synonyms': ['keycard'], 'def': 'a plastic card used to gain access typically to a door', 'name': 'keycard'}, {'frequency': 'r', 'id': 617, 'synset': 'kilt.n.01', 'synonyms': ['kilt'], 'def': 'a knee-length pleated tartan skirt worn by men as part of the traditional dress in the Highlands of northern Scotland', 'name': 'kilt'}, {'frequency': 'c', 'id': 618, 'synset': 'kimono.n.01', 'synonyms': ['kimono'], 'def': 'a loose robe; imitated from robes originally worn by Japanese', 'name': 'kimono'}, {'frequency': 'f', 'id': 619, 'synset': 'kitchen_sink.n.01', 'synonyms': ['kitchen_sink'], 'def': 'a sink in a kitchen', 'name': 'kitchen_sink'}, {'frequency': 'c', 'id': 620, 'synset': 'kitchen_table.n.01', 'synonyms': ['kitchen_table'], 'def': 'a table in the kitchen', 'name': 'kitchen_table'}, {'frequency': 'f', 'id': 621, 'synset': 'kite.n.03', 'synonyms': ['kite'], 'def': 'plaything consisting of a light frame covered with tissue paper; flown in wind at end of a string', 'name': 'kite'}, {'frequency': 'c', 'id': 622, 'synset': 'kitten.n.01', 'synonyms': ['kitten', 'kitty'], 'def': 'young domestic cat', 'name': 'kitten'}, {'frequency': 'c', 'id': 623, 'synset': 'kiwi.n.03', 'synonyms': ['kiwi_fruit'], 'def': 'fuzzy brown egg-shaped fruit with slightly tart green flesh', 'name': 'kiwi_fruit'}, {'frequency': 'f', 'id': 624, 'synset': 'knee_pad.n.01', 'synonyms': ['knee_pad'], 'def': 'protective garment consisting of a pad worn by football or baseball or hockey players', 'name': 'knee_pad'}, {'frequency': 'f', 'id': 625, 'synset': 'knife.n.01', 'synonyms': ['knife'], 'def': 'tool with a blade and point used as a cutting instrument', 'name': 'knife'}, {'frequency': 'r', 'id': 626, 'synset': 'knight.n.02', 'synonyms': ['knight_(chess_piece)', 'horse_(chess_piece)'], 'def': 'a chess game piece shaped to resemble the head of a horse', 'name': 'knight_(chess_piece)'}, {'frequency': 'r', 'id': 627, 'synset': 'knitting_needle.n.01', 'synonyms': ['knitting_needle'], 'def': 'needle consisting of a slender rod with pointed ends; usually used in pairs', 'name': 'knitting_needle'}, {'frequency': 'f', 'id': 628, 'synset': 'knob.n.02', 'synonyms': ['knob'], 'def': 'a round handle often found on a door', 'name': 'knob'}, {'frequency': 'r', 'id': 629, 'synset': 'knocker.n.05', 'synonyms': ['knocker_(on_a_door)', 'doorknocker'], 'def': 'a device (usually metal and ornamental) attached by a hinge to a door', 'name': 'knocker_(on_a_door)'}, {'frequency': 'r', 'id': 630, 'synset': 'koala.n.01', 'synonyms': ['koala', 'koala_bear'], 'def': 'sluggish tailless Australian marsupial with grey furry ears and coat', 'name': 'koala'}, {'frequency': 'r', 'id': 631, 'synset': 'lab_coat.n.01', 'synonyms': ['lab_coat', 'laboratory_coat'], 'def': 'a light coat worn to protect clothing from substances used while working in a laboratory', 'name': 'lab_coat'}, {'frequency': 'f', 'id': 632, 'synset': 'ladder.n.01', 'synonyms': ['ladder'], 'def': 'steps consisting of two parallel members connected by rungs', 'name': 'ladder'}, {'frequency': 'c', 'id': 633, 'synset': 'ladle.n.01', 'synonyms': ['ladle'], 'def': 'a spoon-shaped vessel with a long handle frequently used to transfer liquids', 'name': 'ladle'}, {'frequency': 'r', 'id': 634, 'synset': 'ladybug.n.01', 'synonyms': ['ladybug', 'ladybeetle', 'ladybird_beetle'], 'def': 'small round bright-colored and spotted beetle, typically red and black', 'name': 'ladybug'}, {'frequency': 'c', 'id': 635, 'synset': 'lamb.n.01', 'synonyms': ['lamb_(animal)'], 'def': 'young sheep', 'name': 'lamb_(animal)'}, {'frequency': 'r', 'id': 636, 'synset': 'lamb_chop.n.01', 'synonyms': ['lamb-chop', 'lambchop'], 'def': 'chop cut from a lamb', 'name': 'lamb-chop'}, {'frequency': 'f', 'id': 637, 'synset': 'lamp.n.02', 'synonyms': ['lamp'], 'def': 'a piece of furniture holding one or more electric light bulbs', 'name': 'lamp'}, {'frequency': 'f', 'id': 638, 'synset': 'lamppost.n.01', 'synonyms': ['lamppost'], 'def': 'a metal post supporting an outdoor lamp (such as a streetlight)', 'name': 'lamppost'}, {'frequency': 'f', 'id': 639, 'synset': 'lampshade.n.01', 'synonyms': ['lampshade'], 'def': 'a protective ornamental shade used to screen a light bulb from direct view', 'name': 'lampshade'}, {'frequency': 'c', 'id': 640, 'synset': 'lantern.n.01', 'synonyms': ['lantern'], 'def': 'light in a transparent protective case', 'name': 'lantern'}, {'frequency': 'f', 'id': 641, 'synset': 'lanyard.n.02', 'synonyms': ['lanyard', 'laniard'], 'def': 'a cord worn around the neck to hold a knife or whistle, etc.', 'name': 'lanyard'}, {'frequency': 'f', 'id': 642, 'synset': 'laptop.n.01', 'synonyms': ['laptop_computer', 'notebook_computer'], 'def': 'a portable computer small enough to use in your lap', 'name': 'laptop_computer'}, {'frequency': 'r', 'id': 643, 'synset': 'lasagna.n.01', 'synonyms': ['lasagna', 'lasagne'], 'def': 'baked dish of layers of lasagna pasta with sauce and cheese and meat or vegetables', 'name': 'lasagna'}, {'frequency': 'c', 'id': 644, 'synset': 'latch.n.02', 'synonyms': ['latch'], 'def': 'a bar that can be lowered or slid into a groove to fasten a door or gate', 'name': 'latch'}, {'frequency': 'r', 'id': 645, 'synset': 'lawn_mower.n.01', 'synonyms': ['lawn_mower'], 'def': 'garden tool for mowing grass on lawns', 'name': 'lawn_mower'}, {'frequency': 'r', 'id': 646, 'synset': 'leather.n.01', 'synonyms': ['leather'], 'def': 'an animal skin made smooth and flexible by removing the hair and then tanning', 'name': 'leather'}, {'frequency': 'c', 'id': 647, 'synset': 'legging.n.01', 'synonyms': ['legging_(clothing)', 'leging_(clothing)', 'leg_covering'], 'def': 'a garment covering the leg (usually extending from the knee to the ankle)', 'name': 'legging_(clothing)'}, {'frequency': 'c', 'id': 648, 'synset': 'lego.n.01', 'synonyms': ['Lego', 'Lego_set'], 'def': "a child's plastic construction set for making models from blocks", 'name': 'Lego'}, {'frequency': 'f', 'id': 649, 'synset': 'lemon.n.01', 'synonyms': ['lemon'], 'def': 'yellow oval fruit with juicy acidic flesh', 'name': 'lemon'}, {'frequency': 'r', 'id': 650, 'synset': 'lemonade.n.01', 'synonyms': ['lemonade'], 'def': 'sweetened beverage of diluted lemon juice', 'name': 'lemonade'}, {'frequency': 'f', 'id': 651, 'synset': 'lettuce.n.02', 'synonyms': ['lettuce'], 'def': 'leafy plant commonly eaten in salad or on sandwiches', 'name': 'lettuce'}, {'frequency': 'f', 'id': 652, 'synset': 'license_plate.n.01', 'synonyms': ['license_plate', 'numberplate'], 'def': "a plate mounted on the front and back of car and bearing the car's registration number", 'name': 'license_plate'}, {'frequency': 'f', 'id': 653, 'synset': 'life_buoy.n.01', 'synonyms': ['life_buoy', 'lifesaver', 'life_belt', 'life_ring'], 'def': 'a ring-shaped life preserver used to prevent drowning (NOT a life-jacket or vest)', 'name': 'life_buoy'}, {'frequency': 'f', 'id': 654, 'synset': 'life_jacket.n.01', 'synonyms': ['life_jacket', 'life_vest'], 'def': 'life preserver consisting of a sleeveless jacket of buoyant or inflatable design', 'name': 'life_jacket'}, {'frequency': 'f', 'id': 655, 'synset': 'light_bulb.n.01', 'synonyms': ['lightbulb'], 'def': 'glass bulb or tube shaped electric device that emits light (DO NOT MARK LAMPS AS A WHOLE)', 'name': 'lightbulb'}, {'frequency': 'r', 'id': 656, 'synset': 'lightning_rod.n.02', 'synonyms': ['lightning_rod', 'lightning_conductor'], 'def': 'a metallic conductor that is attached to a high point and leads to the ground', 'name': 'lightning_rod'}, {'frequency': 'c', 'id': 657, 'synset': 'lime.n.06', 'synonyms': ['lime'], 'def': 'the green acidic fruit of any of various lime trees', 'name': 'lime'}, {'frequency': 'r', 'id': 658, 'synset': 'limousine.n.01', 'synonyms': ['limousine'], 'def': 'long luxurious car; usually driven by a chauffeur', 'name': 'limousine'}, {'frequency': 'r', 'id': 659, 'synset': 'linen.n.02', 'synonyms': ['linen_paper'], 'def': 'a high-quality paper made of linen fibers or with a linen finish', 'name': 'linen_paper'}, {'frequency': 'c', 'id': 660, 'synset': 'lion.n.01', 'synonyms': ['lion'], 'def': 'large gregarious predatory cat of Africa and India', 'name': 'lion'}, {'frequency': 'c', 'id': 661, 'synset': 'lip_balm.n.01', 'synonyms': ['lip_balm'], 'def': 'a balm applied to the lips', 'name': 'lip_balm'}, {'frequency': 'c', 'id': 662, 'synset': 'lipstick.n.01', 'synonyms': ['lipstick', 'lip_rouge'], 'def': 'makeup that is used to color the lips', 'name': 'lipstick'}, {'frequency': 'r', 'id': 663, 'synset': 'liquor.n.01', 'synonyms': ['liquor', 'spirits', 'hard_liquor', 'liqueur', 'cordial'], 'def': 'an alcoholic beverage that is distilled rather than fermented', 'name': 'liquor'}, {'frequency': 'r', 'id': 664, 'synset': 'lizard.n.01', 'synonyms': ['lizard'], 'def': 'a reptile with usually two pairs of legs and a tapering tail', 'name': 'lizard'}, {'frequency': 'r', 'id': 665, 'synset': 'loafer.n.02', 'synonyms': ['Loafer_(type_of_shoe)'], 'def': 'a low leather step-in shoe', 'name': 'Loafer_(type_of_shoe)'}, {'frequency': 'f', 'id': 666, 'synset': 'log.n.01', 'synonyms': ['log'], 'def': 'a segment of the trunk of a tree when stripped of branches', 'name': 'log'}, {'frequency': 'c', 'id': 667, 'synset': 'lollipop.n.02', 'synonyms': ['lollipop'], 'def': 'hard candy on a stick', 'name': 'lollipop'}, {'frequency': 'c', 'id': 668, 'synset': 'lotion.n.01', 'synonyms': ['lotion'], 'def': 'any of various cosmetic preparations that are applied to the skin', 'name': 'lotion'}, {'frequency': 'f', 'id': 669, 'synset': 'loudspeaker.n.01', 'synonyms': ['speaker_(stero_equipment)'], 'def': 'electronic device that produces sound often as part of a stereo system', 'name': 'speaker_(stero_equipment)'}, {'frequency': 'c', 'id': 670, 'synset': 'love_seat.n.01', 'synonyms': ['loveseat'], 'def': 'small sofa that seats two people', 'name': 'loveseat'}, {'frequency': 'r', 'id': 671, 'synset': 'machine_gun.n.01', 'synonyms': ['machine_gun'], 'def': 'a rapidly firing automatic gun', 'name': 'machine_gun'}, {'frequency': 'f', 'id': 672, 'synset': 'magazine.n.02', 'synonyms': ['magazine'], 'def': 'a paperback periodic publication', 'name': 'magazine'}, {'frequency': 'f', 'id': 673, 'synset': 'magnet.n.01', 'synonyms': ['magnet'], 'def': 'a device that attracts iron and produces a magnetic field', 'name': 'magnet'}, {'frequency': 'r', 'id': 674, 'synset': 'mail_slot.n.01', 'synonyms': ['mail_slot'], 'def': 'a slot (usually in a door) through which mail can be delivered', 'name': 'mail_slot'}, {'frequency': 'c', 'id': 675, 'synset': 'mailbox.n.01', 'synonyms': ['mailbox_(at_home)', 'letter_box_(at_home)'], 'def': 'a private box for delivery of mail', 'name': 'mailbox_(at_home)'}, {'frequency': 'r', 'id': 676, 'synset': 'mallet.n.01', 'synonyms': ['mallet'], 'def': 'a sports implement with a long handle and a hammer-like head used to hit a ball', 'name': 'mallet'}, {'frequency': 'r', 'id': 677, 'synset': 'mammoth.n.01', 'synonyms': ['mammoth'], 'def': 'any of numerous extinct elephants widely distributed in the Pleistocene', 'name': 'mammoth'}, {'frequency': 'c', 'id': 678, 'synset': 'mandarin.n.05', 'synonyms': ['mandarin_orange'], 'def': 'a somewhat flat reddish-orange loose skinned citrus of China', 'name': 'mandarin_orange'}, {'frequency': 'c', 'id': 679, 'synset': 'manger.n.01', 'synonyms': ['manger', 'trough'], 'def': 'a container (usually in a barn or stable) from which cattle or horses feed', 'name': 'manger'}, {'frequency': 'f', 'id': 680, 'synset': 'manhole.n.01', 'synonyms': ['manhole'], 'def': 'a hole (usually with a flush cover) through which a person can gain access to an underground structure', 'name': 'manhole'}, {'frequency': 'c', 'id': 681, 'synset': 'map.n.01', 'synonyms': ['map'], 'def': "a diagrammatic representation of the earth's surface (or part of it)", 'name': 'map'}, {'frequency': 'c', 'id': 682, 'synset': 'marker.n.03', 'synonyms': ['marker'], 'def': 'a writing implement for making a mark', 'name': 'marker'}, {'frequency': 'r', 'id': 683, 'synset': 'martini.n.01', 'synonyms': ['martini'], 'def': 'a cocktail made of gin (or vodka) with dry vermouth', 'name': 'martini'}, {'frequency': 'r', 'id': 684, 'synset': 'mascot.n.01', 'synonyms': ['mascot'], 'def': 'a person or animal that is adopted by a team or other group as a symbolic figure', 'name': 'mascot'}, {'frequency': 'c', 'id': 685, 'synset': 'mashed_potato.n.01', 'synonyms': ['mashed_potato'], 'def': 'potato that has been peeled and boiled and then mashed', 'name': 'mashed_potato'}, {'frequency': 'r', 'id': 686, 'synset': 'masher.n.02', 'synonyms': ['masher'], 'def': 'a kitchen utensil used for mashing (e.g. potatoes)', 'name': 'masher'}, {'frequency': 'f', 'id': 687, 'synset': 'mask.n.04', 'synonyms': ['mask', 'facemask'], 'def': 'a protective covering worn over the face', 'name': 'mask'}, {'frequency': 'f', 'id': 688, 'synset': 'mast.n.01', 'synonyms': ['mast'], 'def': 'a vertical spar for supporting sails', 'name': 'mast'}, {'frequency': 'c', 'id': 689, 'synset': 'mat.n.03', 'synonyms': ['mat_(gym_equipment)', 'gym_mat'], 'def': 'sports equipment consisting of a piece of thick padding on the floor for gymnastics', 'name': 'mat_(gym_equipment)'}, {'frequency': 'r', 'id': 690, 'synset': 'matchbox.n.01', 'synonyms': ['matchbox'], 'def': 'a box for holding matches', 'name': 'matchbox'}, {'frequency': 'f', 'id': 691, 'synset': 'mattress.n.01', 'synonyms': ['mattress'], 'def': 'a thick pad filled with resilient material used as a bed or part of a bed', 'name': 'mattress'}, {'frequency': 'c', 'id': 692, 'synset': 'measuring_cup.n.01', 'synonyms': ['measuring_cup'], 'def': 'graduated cup used to measure liquid or granular ingredients', 'name': 'measuring_cup'}, {'frequency': 'c', 'id': 693, 'synset': 'measuring_stick.n.01', 'synonyms': ['measuring_stick', 'ruler_(measuring_stick)', 'measuring_rod'], 'def': 'measuring instrument having a sequence of marks at regular intervals', 'name': 'measuring_stick'}, {'frequency': 'c', 'id': 694, 'synset': 'meatball.n.01', 'synonyms': ['meatball'], 'def': 'ground meat formed into a ball and fried or simmered in broth', 'name': 'meatball'}, {'frequency': 'c', 'id': 695, 'synset': 'medicine.n.02', 'synonyms': ['medicine'], 'def': 'something that treats or prevents or alleviates the symptoms of disease', 'name': 'medicine'}, {'frequency': 'r', 'id': 696, 'synset': 'melon.n.01', 'synonyms': ['melon'], 'def': 'fruit of the gourd family having a hard rind and sweet juicy flesh', 'name': 'melon'}, {'frequency': 'f', 'id': 697, 'synset': 'microphone.n.01', 'synonyms': ['microphone'], 'def': 'device for converting sound waves into electrical energy', 'name': 'microphone'}, {'frequency': 'r', 'id': 698, 'synset': 'microscope.n.01', 'synonyms': ['microscope'], 'def': 'magnifier of the image of small objects', 'name': 'microscope'}, {'frequency': 'f', 'id': 699, 'synset': 'microwave.n.02', 'synonyms': ['microwave_oven'], 'def': 'kitchen appliance that cooks food by passing an electromagnetic wave through it', 'name': 'microwave_oven'}, {'frequency': 'r', 'id': 700, 'synset': 'milestone.n.01', 'synonyms': ['milestone', 'milepost'], 'def': 'stone post at side of a road to show distances', 'name': 'milestone'}, {'frequency': 'c', 'id': 701, 'synset': 'milk.n.01', 'synonyms': ['milk'], 'def': 'a white nutritious liquid secreted by mammals and used as food by human beings', 'name': 'milk'}, {'frequency': 'f', 'id': 702, 'synset': 'minivan.n.01', 'synonyms': ['minivan'], 'def': 'a small box-shaped passenger van', 'name': 'minivan'}, {'frequency': 'r', 'id': 703, 'synset': 'mint.n.05', 'synonyms': ['mint_candy'], 'def': 'a candy that is flavored with a mint oil', 'name': 'mint_candy'}, {'frequency': 'f', 'id': 704, 'synset': 'mirror.n.01', 'synonyms': ['mirror'], 'def': 'polished surface that forms images by reflecting light', 'name': 'mirror'}, {'frequency': 'c', 'id': 705, 'synset': 'mitten.n.01', 'synonyms': ['mitten'], 'def': 'glove that encases the thumb separately and the other four fingers together', 'name': 'mitten'}, {'frequency': 'c', 'id': 706, 'synset': 'mixer.n.04', 'synonyms': ['mixer_(kitchen_tool)', 'stand_mixer'], 'def': 'a kitchen utensil that is used for mixing foods', 'name': 'mixer_(kitchen_tool)'}, {'frequency': 'c', 'id': 707, 'synset': 'money.n.03', 'synonyms': ['money'], 'def': 'the official currency issued by a government or national bank', 'name': 'money'}, {'frequency': 'f', 'id': 708, 'synset': 'monitor.n.04', 'synonyms': ['monitor_(computer_equipment) computer_monitor'], 'def': 'a computer monitor', 'name': 'monitor_(computer_equipment) computer_monitor'}, {'frequency': 'c', 'id': 709, 'synset': 'monkey.n.01', 'synonyms': ['monkey'], 'def': 'any of various long-tailed primates', 'name': 'monkey'}, {'frequency': 'f', 'id': 710, 'synset': 'motor.n.01', 'synonyms': ['motor'], 'def': 'machine that converts other forms of energy into mechanical energy and so imparts motion', 'name': 'motor'}, {'frequency': 'f', 'id': 711, 'synset': 'motor_scooter.n.01', 'synonyms': ['motor_scooter', 'scooter'], 'def': 'a wheeled vehicle with small wheels and a low-powered engine', 'name': 'motor_scooter'}, {'frequency': 'r', 'id': 712, 'synset': 'motor_vehicle.n.01', 'synonyms': ['motor_vehicle', 'automotive_vehicle'], 'def': 'a self-propelled wheeled vehicle that does not run on rails', 'name': 'motor_vehicle'}, {'frequency': 'r', 'id': 713, 'synset': 'motorboat.n.01', 'synonyms': ['motorboat', 'powerboat'], 'def': 'a boat propelled by an internal-combustion engine', 'name': 'motorboat'}, {'frequency': 'f', 'id': 714, 'synset': 'motorcycle.n.01', 'synonyms': ['motorcycle'], 'def': 'a motor vehicle with two wheels and a strong frame', 'name': 'motorcycle'}, {'frequency': 'f', 'id': 715, 'synset': 'mound.n.01', 'synonyms': ['mound_(baseball)', "pitcher's_mound"], 'def': '(baseball) the slight elevation on which the pitcher stands', 'name': 'mound_(baseball)'}, {'frequency': 'r', 'id': 716, 'synset': 'mouse.n.01', 'synonyms': ['mouse_(animal_rodent)'], 'def': 'a small rodent with pointed snouts and small ears on elongated bodies with slender usually hairless tails', 'name': 'mouse_(animal_rodent)'}, {'frequency': 'f', 'id': 717, 'synset': 'mouse.n.04', 'synonyms': ['mouse_(computer_equipment)', 'computer_mouse'], 'def': 'a computer input device that controls an on-screen pointer', 'name': 'mouse_(computer_equipment)'}, {'frequency': 'f', 'id': 718, 'synset': 'mousepad.n.01', 'synonyms': ['mousepad'], 'def': 'a small portable pad that provides an operating surface for a computer mouse', 'name': 'mousepad'}, {'frequency': 'c', 'id': 719, 'synset': 'muffin.n.01', 'synonyms': ['muffin'], 'def': 'a sweet quick bread baked in a cup-shaped pan', 'name': 'muffin'}, {'frequency': 'f', 'id': 720, 'synset': 'mug.n.04', 'synonyms': ['mug'], 'def': 'with handle and usually cylindrical', 'name': 'mug'}, {'frequency': 'f', 'id': 721, 'synset': 'mushroom.n.02', 'synonyms': ['mushroom'], 'def': 'a common mushroom', 'name': 'mushroom'}, {'frequency': 'r', 'id': 722, 'synset': 'music_stool.n.01', 'synonyms': ['music_stool', 'piano_stool'], 'def': 'a stool for piano players; usually adjustable in height', 'name': 'music_stool'}, {'frequency': 'r', 'id': 723, 'synset': 'musical_instrument.n.01', 'synonyms': ['musical_instrument', 'instrument_(musical)'], 'def': 'any of various devices or contrivances that can be used to produce musical tones or sounds', 'name': 'musical_instrument'}, {'frequency': 'r', 'id': 724, 'synset': 'nailfile.n.01', 'synonyms': ['nailfile'], 'def': 'a small flat file for shaping the nails', 'name': 'nailfile'}, {'frequency': 'r', 'id': 725, 'synset': 'nameplate.n.01', 'synonyms': ['nameplate'], 'def': 'a plate bearing a name', 'name': 'nameplate'}, {'frequency': 'f', 'id': 726, 'synset': 'napkin.n.01', 'synonyms': ['napkin', 'table_napkin', 'serviette'], 'def': 'a small piece of table linen or paper that is used to wipe the mouth and to cover the lap in order to protect clothing', 'name': 'napkin'}, {'frequency': 'r', 'id': 727, 'synset': 'neckerchief.n.01', 'synonyms': ['neckerchief'], 'def': 'a kerchief worn around the neck', 'name': 'neckerchief'}, {'frequency': 'f', 'id': 728, 'synset': 'necklace.n.01', 'synonyms': ['necklace'], 'def': 'jewelry consisting of a cord or chain (often bearing gems) worn about the neck as an ornament', 'name': 'necklace'}, {'frequency': 'f', 'id': 729, 'synset': 'necktie.n.01', 'synonyms': ['necktie', 'tie_(necktie)'], 'def': 'neckwear consisting of a long narrow piece of material worn under a collar and tied in knot at the front', 'name': 'necktie'}, {'frequency': 'r', 'id': 730, 'synset': 'needle.n.03', 'synonyms': ['needle'], 'def': 'a sharp pointed implement (usually metal)', 'name': 'needle'}, {'frequency': 'c', 'id': 731, 'synset': 'nest.n.01', 'synonyms': ['nest'], 'def': 'a structure in which animals lay eggs or give birth to their young', 'name': 'nest'}, {'frequency': 'r', 'id': 732, 'synset': 'newsstand.n.01', 'synonyms': ['newsstand'], 'def': 'a stall where newspapers and other periodicals are sold', 'name': 'newsstand'}, {'frequency': 'c', 'id': 733, 'synset': 'nightwear.n.01', 'synonyms': ['nightshirt', 'nightwear', 'sleepwear', 'nightclothes'], 'def': 'garments designed to be worn in bed', 'name': 'nightshirt'}, {'frequency': 'r', 'id': 734, 'synset': 'nosebag.n.01', 'synonyms': ['nosebag_(for_animals)', 'feedbag'], 'def': 'a canvas bag that is used to feed an animal (such as a horse); covers the muzzle and fastens at the top of the head', 'name': 'nosebag_(for_animals)'}, {'frequency': 'r', 'id': 735, 'synset': 'noseband.n.01', 'synonyms': ['noseband_(for_animals)', 'nosepiece_(for_animals)'], 'def': "a strap that is the part of a bridle that goes over the animal's nose", 'name': 'noseband_(for_animals)'}, {'frequency': 'f', 'id': 736, 'synset': 'notebook.n.01', 'synonyms': ['notebook'], 'def': 'a book with blank pages for recording notes or memoranda', 'name': 'notebook'}, {'frequency': 'c', 'id': 737, 'synset': 'notepad.n.01', 'synonyms': ['notepad'], 'def': 'a pad of paper for keeping notes', 'name': 'notepad'}, {'frequency': 'c', 'id': 738, 'synset': 'nut.n.03', 'synonyms': ['nut'], 'def': 'a small metal block (usually square or hexagonal) with internal screw thread to be fitted onto a bolt', 'name': 'nut'}, {'frequency': 'r', 'id': 739, 'synset': 'nutcracker.n.01', 'synonyms': ['nutcracker'], 'def': 'a hand tool used to crack nuts open', 'name': 'nutcracker'}, {'frequency': 'c', 'id': 740, 'synset': 'oar.n.01', 'synonyms': ['oar'], 'def': 'an implement used to propel or steer a boat', 'name': 'oar'}, {'frequency': 'r', 'id': 741, 'synset': 'octopus.n.01', 'synonyms': ['octopus_(food)'], 'def': 'tentacles of octopus prepared as food', 'name': 'octopus_(food)'}, {'frequency': 'r', 'id': 742, 'synset': 'octopus.n.02', 'synonyms': ['octopus_(animal)'], 'def': 'bottom-living cephalopod having a soft oval body with eight long tentacles', 'name': 'octopus_(animal)'}, {'frequency': 'c', 'id': 743, 'synset': 'oil_lamp.n.01', 'synonyms': ['oil_lamp', 'kerosene_lamp', 'kerosine_lamp'], 'def': 'a lamp that burns oil (as kerosine) for light', 'name': 'oil_lamp'}, {'frequency': 'c', 'id': 744, 'synset': 'olive_oil.n.01', 'synonyms': ['olive_oil'], 'def': 'oil from olives', 'name': 'olive_oil'}, {'frequency': 'r', 'id': 745, 'synset': 'omelet.n.01', 'synonyms': ['omelet', 'omelette'], 'def': 'beaten eggs cooked until just set; may be folded around e.g. ham or cheese or jelly', 'name': 'omelet'}, {'frequency': 'f', 'id': 746, 'synset': 'onion.n.01', 'synonyms': ['onion'], 'def': 'the bulb of an onion plant', 'name': 'onion'}, {'frequency': 'f', 'id': 747, 'synset': 'orange.n.01', 'synonyms': ['orange_(fruit)'], 'def': 'orange (FRUIT of an orange tree)', 'name': 'orange_(fruit)'}, {'frequency': 'c', 'id': 748, 'synset': 'orange_juice.n.01', 'synonyms': ['orange_juice'], 'def': 'bottled or freshly squeezed juice of oranges', 'name': 'orange_juice'}, {'frequency': 'r', 'id': 749, 'synset': 'oregano.n.01', 'synonyms': ['oregano', 'marjoram'], 'def': 'aromatic Eurasian perennial herb used in cooking and baking', 'name': 'oregano'}, {'frequency': 'c', 'id': 750, 'synset': 'ostrich.n.02', 'synonyms': ['ostrich'], 'def': 'fast-running African flightless bird with two-toed feet; largest living bird', 'name': 'ostrich'}, {'frequency': 'c', 'id': 751, 'synset': 'ottoman.n.03', 'synonyms': ['ottoman', 'pouf', 'pouffe', 'hassock'], 'def': 'thick cushion used as a seat', 'name': 'ottoman'}, {'frequency': 'c', 'id': 752, 'synset': 'overall.n.01', 'synonyms': ['overalls_(clothing)'], 'def': 'work clothing consisting of denim trousers usually with a bib and shoulder straps', 'name': 'overalls_(clothing)'}, {'frequency': 'c', 'id': 753, 'synset': 'owl.n.01', 'synonyms': ['owl'], 'def': 'nocturnal bird of prey with hawk-like beak and claws and large head with front-facing eyes', 'name': 'owl'}, {'frequency': 'c', 'id': 754, 'synset': 'packet.n.03', 'synonyms': ['packet'], 'def': 'a small package or bundle', 'name': 'packet'}, {'frequency': 'r', 'id': 755, 'synset': 'pad.n.03', 'synonyms': ['inkpad', 'inking_pad', 'stamp_pad'], 'def': 'absorbent material saturated with ink used to transfer ink evenly to a rubber stamp', 'name': 'inkpad'}, {'frequency': 'c', 'id': 756, 'synset': 'pad.n.04', 'synonyms': ['pad'], 'def': 'a flat mass of soft material used for protection, stuffing, or comfort', 'name': 'pad'}, {'frequency': 'c', 'id': 757, 'synset': 'paddle.n.04', 'synonyms': ['paddle', 'boat_paddle'], 'def': 'a short light oar used without an oarlock to propel a canoe or small boat', 'name': 'paddle'}, {'frequency': 'c', 'id': 758, 'synset': 'padlock.n.01', 'synonyms': ['padlock'], 'def': 'a detachable, portable lock', 'name': 'padlock'}, {'frequency': 'r', 'id': 759, 'synset': 'paintbox.n.01', 'synonyms': ['paintbox'], 'def': "a box containing a collection of cubes or tubes of artists' paint", 'name': 'paintbox'}, {'frequency': 'c', 'id': 760, 'synset': 'paintbrush.n.01', 'synonyms': ['paintbrush'], 'def': 'a brush used as an applicator to apply paint', 'name': 'paintbrush'}, {'frequency': 'f', 'id': 761, 'synset': 'painting.n.01', 'synonyms': ['painting'], 'def': 'graphic art consisting of an artistic composition made by applying paints to a surface', 'name': 'painting'}, {'frequency': 'c', 'id': 762, 'synset': 'pajama.n.02', 'synonyms': ['pajamas', 'pyjamas'], 'def': 'loose-fitting nightclothes worn for sleeping or lounging', 'name': 'pajamas'}, {'frequency': 'c', 'id': 763, 'synset': 'palette.n.02', 'synonyms': ['palette', 'pallet'], 'def': 'board that provides a flat surface on which artists mix paints and the range of colors used', 'name': 'palette'}, {'frequency': 'f', 'id': 764, 'synset': 'pan.n.01', 'synonyms': ['pan_(for_cooking)', 'cooking_pan'], 'def': 'cooking utensil consisting of a wide metal vessel', 'name': 'pan_(for_cooking)'}, {'frequency': 'r', 'id': 765, 'synset': 'pan.n.03', 'synonyms': ['pan_(metal_container)'], 'def': 'shallow container made of metal', 'name': 'pan_(metal_container)'}, {'frequency': 'c', 'id': 766, 'synset': 'pancake.n.01', 'synonyms': ['pancake'], 'def': 'a flat cake of thin batter fried on both sides on a griddle', 'name': 'pancake'}, {'frequency': 'r', 'id': 767, 'synset': 'pantyhose.n.01', 'synonyms': ['pantyhose'], 'def': "a woman's tights consisting of underpants and stockings", 'name': 'pantyhose'}, {'frequency': 'r', 'id': 768, 'synset': 'papaya.n.02', 'synonyms': ['papaya'], 'def': 'large oval melon-like tropical fruit with yellowish flesh', 'name': 'papaya'}, {'frequency': 'r', 'id': 769, 'synset': 'paper_clip.n.01', 'synonyms': ['paperclip'], 'def': 'a wire or plastic clip for holding sheets of paper together', 'name': 'paperclip'}, {'frequency': 'f', 'id': 770, 'synset': 'paper_plate.n.01', 'synonyms': ['paper_plate'], 'def': 'a disposable plate made of cardboard', 'name': 'paper_plate'}, {'frequency': 'f', 'id': 771, 'synset': 'paper_towel.n.01', 'synonyms': ['paper_towel'], 'def': 'a disposable towel made of absorbent paper', 'name': 'paper_towel'}, {'frequency': 'r', 'id': 772, 'synset': 'paperback_book.n.01', 'synonyms': ['paperback_book', 'paper-back_book', 'softback_book', 'soft-cover_book'], 'def': 'a book with paper covers', 'name': 'paperback_book'}, {'frequency': 'r', 'id': 773, 'synset': 'paperweight.n.01', 'synonyms': ['paperweight'], 'def': 'a weight used to hold down a stack of papers', 'name': 'paperweight'}, {'frequency': 'c', 'id': 774, 'synset': 'parachute.n.01', 'synonyms': ['parachute'], 'def': 'rescue equipment consisting of a device that fills with air and retards your fall', 'name': 'parachute'}, {'frequency': 'r', 'id': 775, 'synset': 'parakeet.n.01', 'synonyms': ['parakeet', 'parrakeet', 'parroket', 'paraquet', 'paroquet', 'parroquet'], 'def': 'any of numerous small slender long-tailed parrots', 'name': 'parakeet'}, {'frequency': 'c', 'id': 776, 'synset': 'parasail.n.01', 'synonyms': ['parasail_(sports)'], 'def': 'parachute that will lift a person up into the air when it is towed by a motorboat or a car', 'name': 'parasail_(sports)'}, {'frequency': 'r', 'id': 777, 'synset': 'parchment.n.01', 'synonyms': ['parchment'], 'def': 'a superior paper resembling sheepskin', 'name': 'parchment'}, {'frequency': 'r', 'id': 778, 'synset': 'parka.n.01', 'synonyms': ['parka', 'anorak'], 'def': "a kind of heavy jacket (`windcheater' is a British term)", 'name': 'parka'}, {'frequency': 'f', 'id': 779, 'synset': 'parking_meter.n.01', 'synonyms': ['parking_meter'], 'def': 'a coin-operated timer located next to a parking space', 'name': 'parking_meter'}, {'frequency': 'c', 'id': 780, 'synset': 'parrot.n.01', 'synonyms': ['parrot'], 'def': 'usually brightly colored tropical birds with short hooked beaks and the ability to mimic sounds', 'name': 'parrot'}, {'frequency': 'c', 'id': 781, 'synset': 'passenger_car.n.01', 'synonyms': ['passenger_car_(part_of_a_train)', 'coach_(part_of_a_train)'], 'def': 'a railcar where passengers ride', 'name': 'passenger_car_(part_of_a_train)'}, {'frequency': 'r', 'id': 782, 'synset': 'passenger_ship.n.01', 'synonyms': ['passenger_ship'], 'def': 'a ship built to carry passengers', 'name': 'passenger_ship'}, {'frequency': 'r', 'id': 783, 'synset': 'passport.n.02', 'synonyms': ['passport'], 'def': 'a document issued by a country to a citizen allowing that person to travel abroad and re-enter the home country', 'name': 'passport'}, {'frequency': 'f', 'id': 784, 'synset': 'pastry.n.02', 'synonyms': ['pastry'], 'def': 'any of various baked foods made of dough or batter', 'name': 'pastry'}, {'frequency': 'r', 'id': 785, 'synset': 'patty.n.01', 'synonyms': ['patty_(food)'], 'def': 'small flat mass of chopped food', 'name': 'patty_(food)'}, {'frequency': 'c', 'id': 786, 'synset': 'pea.n.01', 'synonyms': ['pea_(food)'], 'def': 'seed of a pea plant used for food', 'name': 'pea_(food)'}, {'frequency': 'c', 'id': 787, 'synset': 'peach.n.03', 'synonyms': ['peach'], 'def': 'downy juicy fruit with sweet yellowish or whitish flesh', 'name': 'peach'}, {'frequency': 'c', 'id': 788, 'synset': 'peanut_butter.n.01', 'synonyms': ['peanut_butter'], 'def': 'a spread made from ground peanuts', 'name': 'peanut_butter'}, {'frequency': 'c', 'id': 789, 'synset': 'pear.n.01', 'synonyms': ['pear'], 'def': 'sweet juicy gritty-textured fruit available in many varieties', 'name': 'pear'}, {'frequency': 'r', 'id': 790, 'synset': 'peeler.n.03', 'synonyms': ['peeler_(tool_for_fruit_and_vegetables)'], 'def': 'a device for peeling vegetables or fruits', 'name': 'peeler_(tool_for_fruit_and_vegetables)'}, {'frequency': 'r', 'id': 791, 'synset': 'pegboard.n.01', 'synonyms': ['pegboard'], 'def': 'a board perforated with regularly spaced holes into which pegs can be fitted', 'name': 'pegboard'}, {'frequency': 'c', 'id': 792, 'synset': 'pelican.n.01', 'synonyms': ['pelican'], 'def': 'large long-winged warm-water seabird having a large bill with a distensible pouch for fish', 'name': 'pelican'}, {'frequency': 'f', 'id': 793, 'synset': 'pen.n.01', 'synonyms': ['pen'], 'def': 'a writing implement with a point from which ink flows', 'name': 'pen'}, {'frequency': 'c', 'id': 794, 'synset': 'pencil.n.01', 'synonyms': ['pencil'], 'def': 'a thin cylindrical pointed writing implement made of wood and graphite', 'name': 'pencil'}, {'frequency': 'r', 'id': 795, 'synset': 'pencil_box.n.01', 'synonyms': ['pencil_box', 'pencil_case'], 'def': 'a box for holding pencils', 'name': 'pencil_box'}, {'frequency': 'r', 'id': 796, 'synset': 'pencil_sharpener.n.01', 'synonyms': ['pencil_sharpener'], 'def': 'a rotary implement for sharpening the point on pencils', 'name': 'pencil_sharpener'}, {'frequency': 'r', 'id': 797, 'synset': 'pendulum.n.01', 'synonyms': ['pendulum'], 'def': 'an apparatus consisting of an object mounted so that it swings freely under the influence of gravity', 'name': 'pendulum'}, {'frequency': 'c', 'id': 798, 'synset': 'penguin.n.01', 'synonyms': ['penguin'], 'def': 'short-legged flightless birds of cold southern regions having webbed feet and wings modified as flippers', 'name': 'penguin'}, {'frequency': 'r', 'id': 799, 'synset': 'pennant.n.02', 'synonyms': ['pennant'], 'def': 'a flag longer than it is wide (and often tapering)', 'name': 'pennant'}, {'frequency': 'r', 'id': 800, 'synset': 'penny.n.02', 'synonyms': ['penny_(coin)'], 'def': 'a coin worth one-hundredth of the value of the basic unit', 'name': 'penny_(coin)'}, {'frequency': 'c', 'id': 801, 'synset': 'pepper.n.03', 'synonyms': ['pepper', 'peppercorn'], 'def': 'pungent seasoning from the berry of the common pepper plant; whole or ground', 'name': 'pepper'}, {'frequency': 'c', 'id': 802, 'synset': 'pepper_mill.n.01', 'synonyms': ['pepper_mill', 'pepper_grinder'], 'def': 'a mill for grinding pepper', 'name': 'pepper_mill'}, {'frequency': 'c', 'id': 803, 'synset': 'perfume.n.02', 'synonyms': ['perfume'], 'def': 'a toiletry that emits and diffuses a fragrant odor', 'name': 'perfume'}, {'frequency': 'r', 'id': 804, 'synset': 'persimmon.n.02', 'synonyms': ['persimmon'], 'def': 'orange fruit resembling a plum; edible when fully ripe', 'name': 'persimmon'}, {'frequency': 'f', 'id': 805, 'synset': 'person.n.01', 'synonyms': ['baby', 'child', 'boy', 'girl', 'man', 'woman', 'person', 'human'], 'def': 'a human being', 'name': 'baby'}, {'frequency': 'r', 'id': 806, 'synset': 'pet.n.01', 'synonyms': ['pet'], 'def': 'a domesticated animal kept for companionship or amusement', 'name': 'pet'}, {'frequency': 'r', 'id': 807, 'synset': 'petfood.n.01', 'synonyms': ['petfood', 'pet-food'], 'def': 'food prepared for animal pets', 'name': 'petfood'}, {'frequency': 'r', 'id': 808, 'synset': 'pew.n.01', 'synonyms': ['pew_(church_bench)', 'church_bench'], 'def': 'long bench with backs; used in church by the congregation', 'name': 'pew_(church_bench)'}, {'frequency': 'r', 'id': 809, 'synset': 'phonebook.n.01', 'synonyms': ['phonebook', 'telephone_book', 'telephone_directory'], 'def': 'a directory containing an alphabetical list of telephone subscribers and their telephone numbers', 'name': 'phonebook'}, {'frequency': 'c', 'id': 810, 'synset': 'phonograph_record.n.01', 'synonyms': ['phonograph_record', 'phonograph_recording', 'record_(phonograph_recording)'], 'def': 'sound recording consisting of a typically black disk with a continuous groove', 'name': 'phonograph_record'}, {'frequency': 'c', 'id': 811, 'synset': 'piano.n.01', 'synonyms': ['piano'], 'def': 'a keyboard instrument that is played by depressing keys that cause hammers to strike tuned strings and produce sounds', 'name': 'piano'}, {'frequency': 'f', 'id': 812, 'synset': 'pickle.n.01', 'synonyms': ['pickle'], 'def': 'vegetables (especially cucumbers) preserved in brine or vinegar', 'name': 'pickle'}, {'frequency': 'f', 'id': 813, 'synset': 'pickup.n.01', 'synonyms': ['pickup_truck'], 'def': 'a light truck with an open body and low sides and a tailboard', 'name': 'pickup_truck'}, {'frequency': 'c', 'id': 814, 'synset': 'pie.n.01', 'synonyms': ['pie'], 'def': 'dish baked in pastry-lined pan often with a pastry top', 'name': 'pie'}, {'frequency': 'c', 'id': 815, 'synset': 'pigeon.n.01', 'synonyms': ['pigeon'], 'def': 'wild and domesticated birds having a heavy body and short legs', 'name': 'pigeon'}, {'frequency': 'r', 'id': 816, 'synset': 'piggy_bank.n.01', 'synonyms': ['piggy_bank', 'penny_bank'], 'def': "a child's coin bank (often shaped like a pig)", 'name': 'piggy_bank'}, {'frequency': 'f', 'id': 817, 'synset': 'pillow.n.01', 'synonyms': ['pillow'], 'def': 'a cushion to support the head of a sleeping person', 'name': 'pillow'}, {'frequency': 'r', 'id': 818, 'synset': 'pin.n.09', 'synonyms': ['pin_(non_jewelry)'], 'def': 'a small slender (often pointed) piece of wood or metal used to support or fasten or attach things', 'name': 'pin_(non_jewelry)'}, {'frequency': 'f', 'id': 819, 'synset': 'pineapple.n.02', 'synonyms': ['pineapple'], 'def': 'large sweet fleshy tropical fruit with a tuft of stiff leaves', 'name': 'pineapple'}, {'frequency': 'c', 'id': 820, 'synset': 'pinecone.n.01', 'synonyms': ['pinecone'], 'def': 'the seed-producing cone of a pine tree', 'name': 'pinecone'}, {'frequency': 'r', 'id': 821, 'synset': 'ping-pong_ball.n.01', 'synonyms': ['ping-pong_ball'], 'def': 'light hollow ball used in playing table tennis', 'name': 'ping-pong_ball'}, {'frequency': 'r', 'id': 822, 'synset': 'pinwheel.n.03', 'synonyms': ['pinwheel'], 'def': 'a toy consisting of vanes of colored paper or plastic that is pinned to a stick and spins when it is pointed into the wind', 'name': 'pinwheel'}, {'frequency': 'r', 'id': 823, 'synset': 'pipe.n.01', 'synonyms': ['tobacco_pipe'], 'def': 'a tube with a small bowl at one end; used for smoking tobacco', 'name': 'tobacco_pipe'}, {'frequency': 'f', 'id': 824, 'synset': 'pipe.n.02', 'synonyms': ['pipe', 'piping'], 'def': 'a long tube made of metal or plastic that is used to carry water or oil or gas etc.', 'name': 'pipe'}, {'frequency': 'r', 'id': 825, 'synset': 'pistol.n.01', 'synonyms': ['pistol', 'handgun'], 'def': 'a firearm that is held and fired with one hand', 'name': 'pistol'}, {'frequency': 'r', 'id': 826, 'synset': 'pita.n.01', 'synonyms': ['pita_(bread)', 'pocket_bread'], 'def': 'usually small round bread that can open into a pocket for filling', 'name': 'pita_(bread)'}, {'frequency': 'f', 'id': 827, 'synset': 'pitcher.n.02', 'synonyms': ['pitcher_(vessel_for_liquid)', 'ewer'], 'def': 'an open vessel with a handle and a spout for pouring', 'name': 'pitcher_(vessel_for_liquid)'}, {'frequency': 'r', 'id': 828, 'synset': 'pitchfork.n.01', 'synonyms': ['pitchfork'], 'def': 'a long-handled hand tool with sharp widely spaced prongs for lifting and pitching hay', 'name': 'pitchfork'}, {'frequency': 'f', 'id': 829, 'synset': 'pizza.n.01', 'synonyms': ['pizza'], 'def': 'Italian open pie made of thin bread dough spread with a spiced mixture of e.g. tomato sauce and cheese', 'name': 'pizza'}, {'frequency': 'f', 'id': 830, 'synset': 'place_mat.n.01', 'synonyms': ['place_mat'], 'def': 'a mat placed on a table for an individual place setting', 'name': 'place_mat'}, {'frequency': 'f', 'id': 831, 'synset': 'plate.n.04', 'synonyms': ['plate'], 'def': 'dish on which food is served or from which food is eaten', 'name': 'plate'}, {'frequency': 'c', 'id': 832, 'synset': 'platter.n.01', 'synonyms': ['platter'], 'def': 'a large shallow dish used for serving food', 'name': 'platter'}, {'frequency': 'r', 'id': 833, 'synset': 'playing_card.n.01', 'synonyms': ['playing_card'], 'def': 'one of a pack of cards that are used to play card games', 'name': 'playing_card'}, {'frequency': 'r', 'id': 834, 'synset': 'playpen.n.01', 'synonyms': ['playpen'], 'def': 'a portable enclosure in which babies may be left to play', 'name': 'playpen'}, {'frequency': 'c', 'id': 835, 'synset': 'pliers.n.01', 'synonyms': ['pliers', 'plyers'], 'def': 'a gripping hand tool with two hinged arms and (usually) serrated jaws', 'name': 'pliers'}, {'frequency': 'r', 'id': 836, 'synset': 'plow.n.01', 'synonyms': ['plow_(farm_equipment)', 'plough_(farm_equipment)'], 'def': 'a farm tool having one or more heavy blades to break the soil and cut a furrow prior to sowing', 'name': 'plow_(farm_equipment)'}, {'frequency': 'r', 'id': 837, 'synset': 'pocket_watch.n.01', 'synonyms': ['pocket_watch'], 'def': 'a watch that is carried in a small watch pocket', 'name': 'pocket_watch'}, {'frequency': 'c', 'id': 838, 'synset': 'pocketknife.n.01', 'synonyms': ['pocketknife'], 'def': 'a knife with a blade that folds into the handle; suitable for carrying in the pocket', 'name': 'pocketknife'}, {'frequency': 'c', 'id': 839, 'synset': 'poker.n.01', 'synonyms': ['poker_(fire_stirring_tool)', 'stove_poker', 'fire_hook'], 'def': 'fire iron consisting of a metal rod with a handle; used to stir a fire', 'name': 'poker_(fire_stirring_tool)'}, {'frequency': 'f', 'id': 840, 'synset': 'pole.n.01', 'synonyms': ['pole', 'post'], 'def': 'a long (usually round) rod of wood or metal or plastic', 'name': 'pole'}, {'frequency': 'r', 'id': 841, 'synset': 'police_van.n.01', 'synonyms': ['police_van', 'police_wagon', 'paddy_wagon', 'patrol_wagon'], 'def': 'van used by police to transport prisoners', 'name': 'police_van'}, {'frequency': 'f', 'id': 842, 'synset': 'polo_shirt.n.01', 'synonyms': ['polo_shirt', 'sport_shirt'], 'def': 'a shirt with short sleeves designed for comfort and casual wear', 'name': 'polo_shirt'}, {'frequency': 'r', 'id': 843, 'synset': 'poncho.n.01', 'synonyms': ['poncho'], 'def': 'a blanket-like cloak with a hole in the center for the head', 'name': 'poncho'}, {'frequency': 'c', 'id': 844, 'synset': 'pony.n.05', 'synonyms': ['pony'], 'def': 'any of various breeds of small gentle horses usually less than five feet high at the shoulder', 'name': 'pony'}, {'frequency': 'r', 'id': 845, 'synset': 'pool_table.n.01', 'synonyms': ['pool_table', 'billiard_table', 'snooker_table'], 'def': 'game equipment consisting of a heavy table on which pool is played', 'name': 'pool_table'}, {'frequency': 'f', 'id': 846, 'synset': 'pop.n.02', 'synonyms': ['pop_(soda)', 'soda_(pop)', 'tonic', 'soft_drink'], 'def': 'a sweet drink containing carbonated water and flavoring', 'name': 'pop_(soda)'}, {'frequency': 'r', 'id': 847, 'synset': 'portrait.n.02', 'synonyms': ['portrait', 'portrayal'], 'def': 'any likeness of a person, in any medium', 'name': 'portrait'}, {'frequency': 'c', 'id': 848, 'synset': 'postbox.n.01', 'synonyms': ['postbox_(public)', 'mailbox_(public)'], 'def': 'public box for deposit of mail', 'name': 'postbox_(public)'}, {'frequency': 'c', 'id': 849, 'synset': 'postcard.n.01', 'synonyms': ['postcard', 'postal_card', 'mailing-card'], 'def': 'a card for sending messages by post without an envelope', 'name': 'postcard'}, {'frequency': 'f', 'id': 850, 'synset': 'poster.n.01', 'synonyms': ['poster', 'placard'], 'def': 'a sign posted in a public place as an advertisement', 'name': 'poster'}, {'frequency': 'f', 'id': 851, 'synset': 'pot.n.01', 'synonyms': ['pot'], 'def': 'metal or earthenware cooking vessel that is usually round and deep; often has a handle and lid', 'name': 'pot'}, {'frequency': 'f', 'id': 852, 'synset': 'pot.n.04', 'synonyms': ['flowerpot'], 'def': 'a container in which plants are cultivated', 'name': 'flowerpot'}, {'frequency': 'f', 'id': 853, 'synset': 'potato.n.01', 'synonyms': ['potato'], 'def': 'an edible tuber native to South America', 'name': 'potato'}, {'frequency': 'c', 'id': 854, 'synset': 'potholder.n.01', 'synonyms': ['potholder'], 'def': 'an insulated pad for holding hot pots', 'name': 'potholder'}, {'frequency': 'c', 'id': 855, 'synset': 'pottery.n.01', 'synonyms': ['pottery', 'clayware'], 'def': 'ceramic ware made from clay and baked in a kiln', 'name': 'pottery'}, {'frequency': 'c', 'id': 856, 'synset': 'pouch.n.01', 'synonyms': ['pouch'], 'def': 'a small or medium size container for holding or carrying things', 'name': 'pouch'}, {'frequency': 'r', 'id': 857, 'synset': 'power_shovel.n.01', 'synonyms': ['power_shovel', 'excavator', 'digger'], 'def': 'a machine for excavating', 'name': 'power_shovel'}, {'frequency': 'c', 'id': 858, 'synset': 'prawn.n.01', 'synonyms': ['prawn', 'shrimp'], 'def': 'any of various edible decapod crustaceans', 'name': 'prawn'}, {'frequency': 'f', 'id': 859, 'synset': 'printer.n.03', 'synonyms': ['printer', 'printing_machine'], 'def': 'a machine that prints', 'name': 'printer'}, {'frequency': 'c', 'id': 860, 'synset': 'projectile.n.01', 'synonyms': ['projectile_(weapon)', 'missile'], 'def': 'a weapon that is forcibly thrown or projected at a targets', 'name': 'projectile_(weapon)'}, {'frequency': 'c', 'id': 861, 'synset': 'projector.n.02', 'synonyms': ['projector'], 'def': 'an optical instrument that projects an enlarged image onto a screen', 'name': 'projector'}, {'frequency': 'f', 'id': 862, 'synset': 'propeller.n.01', 'synonyms': ['propeller', 'propellor'], 'def': 'a mechanical device that rotates to push against air or water', 'name': 'propeller'}, {'frequency': 'r', 'id': 863, 'synset': 'prune.n.01', 'synonyms': ['prune'], 'def': 'dried plum', 'name': 'prune'}, {'frequency': 'r', 'id': 864, 'synset': 'pudding.n.01', 'synonyms': ['pudding'], 'def': 'any of various soft thick unsweetened baked dishes', 'name': 'pudding'}, {'frequency': 'r', 'id': 865, 'synset': 'puffer.n.02', 'synonyms': ['puffer_(fish)', 'pufferfish', 'blowfish', 'globefish'], 'def': 'fishes whose elongated spiny body can inflate itself with water or air to form a globe', 'name': 'puffer_(fish)'}, {'frequency': 'r', 'id': 866, 'synset': 'puffin.n.01', 'synonyms': ['puffin'], 'def': 'seabirds having short necks and brightly colored compressed bills', 'name': 'puffin'}, {'frequency': 'r', 'id': 867, 'synset': 'pug.n.01', 'synonyms': ['pug-dog'], 'def': 'small compact smooth-coated breed of Asiatic origin having a tightly curled tail and broad flat wrinkled muzzle', 'name': 'pug-dog'}, {'frequency': 'c', 'id': 868, 'synset': 'pumpkin.n.02', 'synonyms': ['pumpkin'], 'def': 'usually large pulpy deep-yellow round fruit of the squash family maturing in late summer or early autumn', 'name': 'pumpkin'}, {'frequency': 'r', 'id': 869, 'synset': 'punch.n.03', 'synonyms': ['puncher'], 'def': 'a tool for making holes or indentations', 'name': 'puncher'}, {'frequency': 'r', 'id': 870, 'synset': 'puppet.n.01', 'synonyms': ['puppet', 'marionette'], 'def': 'a small figure of a person operated from above with strings by a puppeteer', 'name': 'puppet'}, {'frequency': 'r', 'id': 871, 'synset': 'puppy.n.01', 'synonyms': ['puppy'], 'def': 'a young dog', 'name': 'puppy'}, {'frequency': 'r', 'id': 872, 'synset': 'quesadilla.n.01', 'synonyms': ['quesadilla'], 'def': 'a tortilla that is filled with cheese and heated', 'name': 'quesadilla'}, {'frequency': 'r', 'id': 873, 'synset': 'quiche.n.02', 'synonyms': ['quiche'], 'def': 'a tart filled with rich unsweetened custard; often contains other ingredients (as cheese or ham or seafood or vegetables)', 'name': 'quiche'}, {'frequency': 'f', 'id': 874, 'synset': 'quilt.n.01', 'synonyms': ['quilt', 'comforter'], 'def': 'bedding made of two layers of cloth filled with stuffing and stitched together', 'name': 'quilt'}, {'frequency': 'c', 'id': 875, 'synset': 'rabbit.n.01', 'synonyms': ['rabbit'], 'def': 'any of various burrowing animals of the family Leporidae having long ears and short tails', 'name': 'rabbit'}, {'frequency': 'r', 'id': 876, 'synset': 'racer.n.02', 'synonyms': ['race_car', 'racing_car'], 'def': 'a fast car that competes in races', 'name': 'race_car'}, {'frequency': 'c', 'id': 877, 'synset': 'racket.n.04', 'synonyms': ['racket', 'racquet'], 'def': 'a sports implement used to strike a ball in various games', 'name': 'racket'}, {'frequency': 'r', 'id': 878, 'synset': 'radar.n.01', 'synonyms': ['radar'], 'def': 'measuring instrument in which the echo of a pulse of microwave radiation is used to detect and locate distant objects', 'name': 'radar'}, {'frequency': 'c', 'id': 879, 'synset': 'radiator.n.03', 'synonyms': ['radiator'], 'def': 'a mechanism consisting of a metal honeycomb through which hot fluids circulate', 'name': 'radiator'}, {'frequency': 'c', 'id': 880, 'synset': 'radio_receiver.n.01', 'synonyms': ['radio_receiver', 'radio_set', 'radio', 'tuner_(radio)'], 'def': 'an electronic receiver that detects and demodulates and amplifies transmitted radio signals', 'name': 'radio_receiver'}, {'frequency': 'c', 'id': 881, 'synset': 'radish.n.03', 'synonyms': ['radish', 'daikon'], 'def': 'pungent edible root of any of various cultivated radish plants', 'name': 'radish'}, {'frequency': 'c', 'id': 882, 'synset': 'raft.n.01', 'synonyms': ['raft'], 'def': 'a flat float (usually made of logs or planks) that can be used for transport or as a platform for swimmers', 'name': 'raft'}, {'frequency': 'r', 'id': 883, 'synset': 'rag_doll.n.01', 'synonyms': ['rag_doll'], 'def': 'a cloth doll that is stuffed and (usually) painted', 'name': 'rag_doll'}, {'frequency': 'c', 'id': 884, 'synset': 'raincoat.n.01', 'synonyms': ['raincoat', 'waterproof_jacket'], 'def': 'a water-resistant coat', 'name': 'raincoat'}, {'frequency': 'c', 'id': 885, 'synset': 'ram.n.05', 'synonyms': ['ram_(animal)'], 'def': 'uncastrated adult male sheep', 'name': 'ram_(animal)'}, {'frequency': 'c', 'id': 886, 'synset': 'raspberry.n.02', 'synonyms': ['raspberry'], 'def': 'red or black edible aggregate berries usually smaller than the related blackberries', 'name': 'raspberry'}, {'frequency': 'r', 'id': 887, 'synset': 'rat.n.01', 'synonyms': ['rat'], 'def': 'any of various long-tailed rodents similar to but larger than a mouse', 'name': 'rat'}, {'frequency': 'c', 'id': 888, 'synset': 'razorblade.n.01', 'synonyms': ['razorblade'], 'def': 'a blade that has very sharp edge', 'name': 'razorblade'}, {'frequency': 'c', 'id': 889, 'synset': 'reamer.n.01', 'synonyms': ['reamer_(juicer)', 'juicer', 'juice_reamer'], 'def': 'a squeezer with a conical ridged center that is used for squeezing juice from citrus fruit', 'name': 'reamer_(juicer)'}, {'frequency': 'f', 'id': 890, 'synset': 'rearview_mirror.n.01', 'synonyms': ['rearview_mirror'], 'def': 'car mirror that reflects the view out of the rear window', 'name': 'rearview_mirror'}, {'frequency': 'c', 'id': 891, 'synset': 'receipt.n.02', 'synonyms': ['receipt'], 'def': 'an acknowledgment (usually tangible) that payment has been made', 'name': 'receipt'}, {'frequency': 'c', 'id': 892, 'synset': 'recliner.n.01', 'synonyms': ['recliner', 'reclining_chair', 'lounger_(chair)'], 'def': 'an armchair whose back can be lowered and foot can be raised to allow the sitter to recline in it', 'name': 'recliner'}, {'frequency': 'r', 'id': 893, 'synset': 'record_player.n.01', 'synonyms': ['record_player', 'phonograph_(record_player)', 'turntable'], 'def': 'machine in which rotating records cause a stylus to vibrate and the vibrations are amplified acoustically or electronically', 'name': 'record_player'}, {'frequency': 'r', 'id': 894, 'synset': 'red_cabbage.n.02', 'synonyms': ['red_cabbage'], 'def': 'compact head of purplish-red leaves', 'name': 'red_cabbage'}, {'frequency': 'f', 'id': 895, 'synset': 'reflector.n.01', 'synonyms': ['reflector'], 'def': 'device that reflects light, radiation, etc.', 'name': 'reflector'}, {'frequency': 'f', 'id': 896, 'synset': 'remote_control.n.01', 'synonyms': ['remote_control'], 'def': 'a device that can be used to control a machine or apparatus from a distance', 'name': 'remote_control'}, {'frequency': 'c', 'id': 897, 'synset': 'rhinoceros.n.01', 'synonyms': ['rhinoceros'], 'def': 'massive powerful herbivorous odd-toed ungulate of southeast Asia and Africa having very thick skin and one or two horns on the snout', 'name': 'rhinoceros'}, {'frequency': 'r', 'id': 898, 'synset': 'rib.n.03', 'synonyms': ['rib_(food)'], 'def': 'cut of meat including one or more ribs', 'name': 'rib_(food)'}, {'frequency': 'r', 'id': 899, 'synset': 'rifle.n.01', 'synonyms': ['rifle'], 'def': 'a shoulder firearm with a long barrel', 'name': 'rifle'}, {'frequency': 'f', 'id': 900, 'synset': 'ring.n.08', 'synonyms': ['ring'], 'def': 'jewelry consisting of a circlet of precious metal (often set with jewels) worn on the finger', 'name': 'ring'}, {'frequency': 'r', 'id': 901, 'synset': 'river_boat.n.01', 'synonyms': ['river_boat'], 'def': 'a boat used on rivers or to ply a river', 'name': 'river_boat'}, {'frequency': 'r', 'id': 902, 'synset': 'road_map.n.02', 'synonyms': ['road_map'], 'def': '(NOT A ROAD) a MAP showing roads (for automobile travel)', 'name': 'road_map'}, {'frequency': 'c', 'id': 903, 'synset': 'robe.n.01', 'synonyms': ['robe'], 'def': 'any loose flowing garment', 'name': 'robe'}, {'frequency': 'c', 'id': 904, 'synset': 'rocking_chair.n.01', 'synonyms': ['rocking_chair'], 'def': 'a chair mounted on rockers', 'name': 'rocking_chair'}, {'frequency': 'r', 'id': 905, 'synset': 'roller_skate.n.01', 'synonyms': ['roller_skate'], 'def': 'a shoe with pairs of rollers (small hard wheels) fixed to the sole', 'name': 'roller_skate'}, {'frequency': 'r', 'id': 906, 'synset': 'rollerblade.n.01', 'synonyms': ['Rollerblade'], 'def': 'an in-line variant of a roller skate', 'name': 'Rollerblade'}, {'frequency': 'c', 'id': 907, 'synset': 'rolling_pin.n.01', 'synonyms': ['rolling_pin'], 'def': 'utensil consisting of a cylinder (usually of wood) with a handle at each end; used to roll out dough', 'name': 'rolling_pin'}, {'frequency': 'r', 'id': 908, 'synset': 'root_beer.n.01', 'synonyms': ['root_beer'], 'def': 'carbonated drink containing extracts of roots and herbs', 'name': 'root_beer'}, {'frequency': 'c', 'id': 909, 'synset': 'router.n.02', 'synonyms': ['router_(computer_equipment)'], 'def': 'a device that forwards data packets between computer networks', 'name': 'router_(computer_equipment)'}, {'frequency': 'f', 'id': 910, 'synset': 'rubber_band.n.01', 'synonyms': ['rubber_band', 'elastic_band'], 'def': 'a narrow band of elastic rubber used to hold things (such as papers) together', 'name': 'rubber_band'}, {'frequency': 'c', 'id': 911, 'synset': 'runner.n.08', 'synonyms': ['runner_(carpet)'], 'def': 'a long narrow carpet', 'name': 'runner_(carpet)'}, {'frequency': 'f', 'id': 912, 'synset': 'sack.n.01', 'synonyms': ['plastic_bag', 'paper_bag'], 'def': "a bag made of paper or plastic for holding customer's purchases", 'name': 'plastic_bag'}, {'frequency': 'f', 'id': 913, 'synset': 'saddle.n.01', 'synonyms': ['saddle_(on_an_animal)'], 'def': 'a seat for the rider of a horse or camel', 'name': 'saddle_(on_an_animal)'}, {'frequency': 'f', 'id': 914, 'synset': 'saddle_blanket.n.01', 'synonyms': ['saddle_blanket', 'saddlecloth', 'horse_blanket'], 'def': 'stable gear consisting of a blanket placed under the saddle', 'name': 'saddle_blanket'}, {'frequency': 'c', 'id': 915, 'synset': 'saddlebag.n.01', 'synonyms': ['saddlebag'], 'def': 'a large bag (or pair of bags) hung over a saddle', 'name': 'saddlebag'}, {'frequency': 'r', 'id': 916, 'synset': 'safety_pin.n.01', 'synonyms': ['safety_pin'], 'def': 'a pin in the form of a clasp; has a guard so the point of the pin will not stick the user', 'name': 'safety_pin'}, {'frequency': 'c', 'id': 917, 'synset': 'sail.n.01', 'synonyms': ['sail'], 'def': 'a large piece of fabric by means of which wind is used to propel a sailing vessel', 'name': 'sail'}, {'frequency': 'c', 'id': 918, 'synset': 'salad.n.01', 'synonyms': ['salad'], 'def': 'food mixtures either arranged on a plate or tossed and served with a moist dressing; usually consisting of or including greens', 'name': 'salad'}, {'frequency': 'r', 'id': 919, 'synset': 'salad_plate.n.01', 'synonyms': ['salad_plate', 'salad_bowl'], 'def': 'a plate or bowl for individual servings of salad', 'name': 'salad_plate'}, {'frequency': 'r', 'id': 920, 'synset': 'salami.n.01', 'synonyms': ['salami'], 'def': 'highly seasoned fatty sausage of pork and beef usually dried', 'name': 'salami'}, {'frequency': 'r', 'id': 921, 'synset': 'salmon.n.01', 'synonyms': ['salmon_(fish)'], 'def': 'any of various large food and game fishes of northern waters', 'name': 'salmon_(fish)'}, {'frequency': 'r', 'id': 922, 'synset': 'salmon.n.03', 'synonyms': ['salmon_(food)'], 'def': 'flesh of any of various marine or freshwater fish of the family Salmonidae', 'name': 'salmon_(food)'}, {'frequency': 'r', 'id': 923, 'synset': 'salsa.n.01', 'synonyms': ['salsa'], 'def': 'spicy sauce of tomatoes and onions and chili peppers to accompany Mexican foods', 'name': 'salsa'}, {'frequency': 'f', 'id': 924, 'synset': 'saltshaker.n.01', 'synonyms': ['saltshaker'], 'def': 'a shaker with a perforated top for sprinkling salt', 'name': 'saltshaker'}, {'frequency': 'f', 'id': 925, 'synset': 'sandal.n.01', 'synonyms': ['sandal_(type_of_shoe)'], 'def': 'a shoe consisting of a sole fastened by straps to the foot', 'name': 'sandal_(type_of_shoe)'}, {'frequency': 'f', 'id': 926, 'synset': 'sandwich.n.01', 'synonyms': ['sandwich'], 'def': 'two (or more) slices of bread with a filling between them', 'name': 'sandwich'}, {'frequency': 'r', 'id': 927, 'synset': 'satchel.n.01', 'synonyms': ['satchel'], 'def': 'luggage consisting of a small case with a flat bottom and (usually) a shoulder strap', 'name': 'satchel'}, {'frequency': 'r', 'id': 928, 'synset': 'saucepan.n.01', 'synonyms': ['saucepan'], 'def': 'a deep pan with a handle; used for stewing or boiling', 'name': 'saucepan'}, {'frequency': 'f', 'id': 929, 'synset': 'saucer.n.02', 'synonyms': ['saucer'], 'def': 'a small shallow dish for holding a cup at the table', 'name': 'saucer'}, {'frequency': 'f', 'id': 930, 'synset': 'sausage.n.01', 'synonyms': ['sausage'], 'def': 'highly seasoned minced meat stuffed in casings', 'name': 'sausage'}, {'frequency': 'r', 'id': 931, 'synset': 'sawhorse.n.01', 'synonyms': ['sawhorse', 'sawbuck'], 'def': 'a framework for holding wood that is being sawed', 'name': 'sawhorse'}, {'frequency': 'r', 'id': 932, 'synset': 'sax.n.02', 'synonyms': ['saxophone'], 'def': "a wind instrument with a `J'-shaped form typically made of brass", 'name': 'saxophone'}, {'frequency': 'f', 'id': 933, 'synset': 'scale.n.07', 'synonyms': ['scale_(measuring_instrument)'], 'def': 'a measuring instrument for weighing; shows amount of mass', 'name': 'scale_(measuring_instrument)'}, {'frequency': 'r', 'id': 934, 'synset': 'scarecrow.n.01', 'synonyms': ['scarecrow', 'strawman'], 'def': 'an effigy in the shape of a man to frighten birds away from seeds', 'name': 'scarecrow'}, {'frequency': 'f', 'id': 935, 'synset': 'scarf.n.01', 'synonyms': ['scarf'], 'def': 'a garment worn around the head or neck or shoulders for warmth or decoration', 'name': 'scarf'}, {'frequency': 'c', 'id': 936, 'synset': 'school_bus.n.01', 'synonyms': ['school_bus'], 'def': 'a bus used to transport children to or from school', 'name': 'school_bus'}, {'frequency': 'f', 'id': 937, 'synset': 'scissors.n.01', 'synonyms': ['scissors'], 'def': 'a tool having two crossed pivoting blades with looped handles', 'name': 'scissors'}, {'frequency': 'c', 'id': 938, 'synset': 'scoreboard.n.01', 'synonyms': ['scoreboard'], 'def': 'a large board for displaying the score of a contest (and some other information)', 'name': 'scoreboard'}, {'frequency': 'c', 'id': 939, 'synset': 'scrambled_eggs.n.01', 'synonyms': ['scrambled_eggs'], 'def': 'eggs beaten and cooked to a soft firm consistency while stirring', 'name': 'scrambled_eggs'}, {'frequency': 'r', 'id': 940, 'synset': 'scraper.n.01', 'synonyms': ['scraper'], 'def': 'any of various hand tools for scraping', 'name': 'scraper'}, {'frequency': 'r', 'id': 941, 'synset': 'scratcher.n.03', 'synonyms': ['scratcher'], 'def': 'a device used for scratching', 'name': 'scratcher'}, {'frequency': 'c', 'id': 942, 'synset': 'screwdriver.n.01', 'synonyms': ['screwdriver'], 'def': 'a hand tool for driving screws; has a tip that fits into the head of a screw', 'name': 'screwdriver'}, {'frequency': 'c', 'id': 943, 'synset': 'scrub_brush.n.01', 'synonyms': ['scrubbing_brush'], 'def': 'a brush with short stiff bristles for heavy cleaning', 'name': 'scrubbing_brush'}, {'frequency': 'c', 'id': 944, 'synset': 'sculpture.n.01', 'synonyms': ['sculpture'], 'def': 'a three-dimensional work of art', 'name': 'sculpture'}, {'frequency': 'r', 'id': 945, 'synset': 'seabird.n.01', 'synonyms': ['seabird', 'seafowl'], 'def': 'a bird that frequents coastal waters and the open ocean: gulls; pelicans; gannets; cormorants; albatrosses; petrels; etc.', 'name': 'seabird'}, {'frequency': 'r', 'id': 946, 'synset': 'seahorse.n.02', 'synonyms': ['seahorse'], 'def': 'small fish with horse-like heads bent sharply downward and curled tails', 'name': 'seahorse'}, {'frequency': 'r', 'id': 947, 'synset': 'seaplane.n.01', 'synonyms': ['seaplane', 'hydroplane'], 'def': 'an airplane that can land on or take off from water', 'name': 'seaplane'}, {'frequency': 'c', 'id': 948, 'synset': 'seashell.n.01', 'synonyms': ['seashell'], 'def': 'the shell of a marine organism', 'name': 'seashell'}, {'frequency': 'r', 'id': 949, 'synset': 'seedling.n.01', 'synonyms': ['seedling'], 'def': 'young plant or tree grown from a seed', 'name': 'seedling'}, {'frequency': 'c', 'id': 950, 'synset': 'serving_dish.n.01', 'synonyms': ['serving_dish'], 'def': 'a dish used for serving food', 'name': 'serving_dish'}, {'frequency': 'r', 'id': 951, 'synset': 'sewing_machine.n.01', 'synonyms': ['sewing_machine'], 'def': 'a textile machine used as a home appliance for sewing', 'name': 'sewing_machine'}, {'frequency': 'r', 'id': 952, 'synset': 'shaker.n.03', 'synonyms': ['shaker'], 'def': 'a container in which something can be shaken', 'name': 'shaker'}, {'frequency': 'c', 'id': 953, 'synset': 'shampoo.n.01', 'synonyms': ['shampoo'], 'def': 'cleansing agent consisting of soaps or detergents used for washing the hair', 'name': 'shampoo'}, {'frequency': 'r', 'id': 954, 'synset': 'shark.n.01', 'synonyms': ['shark'], 'def': 'typically large carnivorous fishes with sharpe teeth', 'name': 'shark'}, {'frequency': 'r', 'id': 955, 'synset': 'sharpener.n.01', 'synonyms': ['sharpener'], 'def': 'any implement that is used to make something (an edge or a point) sharper', 'name': 'sharpener'}, {'frequency': 'r', 'id': 956, 'synset': 'sharpie.n.03', 'synonyms': ['Sharpie'], 'def': 'a pen with indelible ink that will write on any surface', 'name': 'Sharpie'}, {'frequency': 'r', 'id': 957, 'synset': 'shaver.n.03', 'synonyms': ['shaver_(electric)', 'electric_shaver', 'electric_razor'], 'def': 'a razor powered by an electric motor', 'name': 'shaver_(electric)'}, {'frequency': 'c', 'id': 958, 'synset': 'shaving_cream.n.01', 'synonyms': ['shaving_cream', 'shaving_soap'], 'def': 'toiletry consisting that forms a rich lather for softening the beard before shaving', 'name': 'shaving_cream'}, {'frequency': 'r', 'id': 959, 'synset': 'shawl.n.01', 'synonyms': ['shawl'], 'def': 'cloak consisting of an oblong piece of cloth used to cover the head and shoulders', 'name': 'shawl'}, {'frequency': 'r', 'id': 960, 'synset': 'shears.n.01', 'synonyms': ['shears'], 'def': 'large scissors with strong blades', 'name': 'shears'}, {'frequency': 'f', 'id': 961, 'synset': 'sheep.n.01', 'synonyms': ['sheep'], 'def': 'woolly usually horned ruminant mammal related to the goat', 'name': 'sheep'}, {'frequency': 'r', 'id': 962, 'synset': 'shepherd_dog.n.01', 'synonyms': ['shepherd_dog', 'sheepdog'], 'def': 'any of various usually long-haired breeds of dog reared to herd and guard sheep', 'name': 'shepherd_dog'}, {'frequency': 'r', 'id': 963, 'synset': 'sherbert.n.01', 'synonyms': ['sherbert', 'sherbet'], 'def': 'a frozen dessert made primarily of fruit juice and sugar', 'name': 'sherbert'}, {'frequency': 'r', 'id': 964, 'synset': 'shield.n.02', 'synonyms': ['shield'], 'def': 'armor carried on the arm to intercept blows', 'name': 'shield'}, {'frequency': 'f', 'id': 965, 'synset': 'shirt.n.01', 'synonyms': ['shirt'], 'def': 'a garment worn on the upper half of the body', 'name': 'shirt'}, {'frequency': 'f', 'id': 966, 'synset': 'shoe.n.01', 'synonyms': ['shoe', 'sneaker_(type_of_shoe)', 'tennis_shoe'], 'def': 'common footwear covering the foot', 'name': 'shoe'}, {'frequency': 'c', 'id': 967, 'synset': 'shopping_bag.n.01', 'synonyms': ['shopping_bag'], 'def': 'a bag made of plastic or strong paper (often with handles); used to transport goods after shopping', 'name': 'shopping_bag'}, {'frequency': 'c', 'id': 968, 'synset': 'shopping_cart.n.01', 'synonyms': ['shopping_cart'], 'def': 'a handcart that holds groceries or other goods while shopping', 'name': 'shopping_cart'}, {'frequency': 'f', 'id': 969, 'synset': 'short_pants.n.01', 'synonyms': ['short_pants', 'shorts_(clothing)', 'trunks_(clothing)'], 'def': 'trousers that end at or above the knee', 'name': 'short_pants'}, {'frequency': 'r', 'id': 970, 'synset': 'shot_glass.n.01', 'synonyms': ['shot_glass'], 'def': 'a small glass adequate to hold a single swallow of whiskey', 'name': 'shot_glass'}, {'frequency': 'c', 'id': 971, 'synset': 'shoulder_bag.n.01', 'synonyms': ['shoulder_bag'], 'def': 'a large handbag that can be carried by a strap looped over the shoulder', 'name': 'shoulder_bag'}, {'frequency': 'c', 'id': 972, 'synset': 'shovel.n.01', 'synonyms': ['shovel'], 'def': 'a hand tool for lifting loose material such as snow, dirt, etc.', 'name': 'shovel'}, {'frequency': 'f', 'id': 973, 'synset': 'shower.n.01', 'synonyms': ['shower_head'], 'def': 'a plumbing fixture that sprays water over you', 'name': 'shower_head'}, {'frequency': 'f', 'id': 974, 'synset': 'shower_curtain.n.01', 'synonyms': ['shower_curtain'], 'def': 'a curtain that keeps water from splashing out of the shower area', 'name': 'shower_curtain'}, {'frequency': 'r', 'id': 975, 'synset': 'shredder.n.01', 'synonyms': ['shredder_(for_paper)'], 'def': 'a device that shreds documents', 'name': 'shredder_(for_paper)'}, {'frequency': 'r', 'id': 976, 'synset': 'sieve.n.01', 'synonyms': ['sieve', 'screen_(sieve)'], 'def': 'a strainer for separating lumps from powdered material or grading particles', 'name': 'sieve'}, {'frequency': 'f', 'id': 977, 'synset': 'signboard.n.01', 'synonyms': ['signboard'], 'def': 'structure displaying a board on which advertisements can be posted', 'name': 'signboard'}, {'frequency': 'c', 'id': 978, 'synset': 'silo.n.01', 'synonyms': ['silo'], 'def': 'a cylindrical tower used for storing goods', 'name': 'silo'}, {'frequency': 'f', 'id': 979, 'synset': 'sink.n.01', 'synonyms': ['sink'], 'def': 'plumbing fixture consisting of a water basin fixed to a wall or floor and having a drainpipe', 'name': 'sink'}, {'frequency': 'f', 'id': 980, 'synset': 'skateboard.n.01', 'synonyms': ['skateboard'], 'def': 'a board with wheels that is ridden in a standing or crouching position and propelled by foot', 'name': 'skateboard'}, {'frequency': 'c', 'id': 981, 'synset': 'skewer.n.01', 'synonyms': ['skewer'], 'def': 'a long pin for holding meat in position while it is being roasted', 'name': 'skewer'}, {'frequency': 'f', 'id': 982, 'synset': 'ski.n.01', 'synonyms': ['ski'], 'def': 'sports equipment for skiing on snow', 'name': 'ski'}, {'frequency': 'f', 'id': 983, 'synset': 'ski_boot.n.01', 'synonyms': ['ski_boot'], 'def': 'a stiff boot that is fastened to a ski with a ski binding', 'name': 'ski_boot'}, {'frequency': 'f', 'id': 984, 'synset': 'ski_parka.n.01', 'synonyms': ['ski_parka', 'ski_jacket'], 'def': 'a parka to be worn while skiing', 'name': 'ski_parka'}, {'frequency': 'f', 'id': 985, 'synset': 'ski_pole.n.01', 'synonyms': ['ski_pole'], 'def': 'a pole with metal points used as an aid in skiing', 'name': 'ski_pole'}, {'frequency': 'f', 'id': 986, 'synset': 'skirt.n.02', 'synonyms': ['skirt'], 'def': 'a garment hanging from the waist; worn mainly by girls and women', 'name': 'skirt'}, {'frequency': 'c', 'id': 987, 'synset': 'sled.n.01', 'synonyms': ['sled', 'sledge', 'sleigh'], 'def': 'a vehicle or flat object for transportation over snow by sliding or pulled by dogs, etc.', 'name': 'sled'}, {'frequency': 'c', 'id': 988, 'synset': 'sleeping_bag.n.01', 'synonyms': ['sleeping_bag'], 'def': 'large padded bag designed to be slept in outdoors', 'name': 'sleeping_bag'}, {'frequency': 'r', 'id': 989, 'synset': 'sling.n.05', 'synonyms': ['sling_(bandage)', 'triangular_bandage'], 'def': 'bandage to support an injured forearm; slung over the shoulder or neck', 'name': 'sling_(bandage)'}, {'frequency': 'c', 'id': 990, 'synset': 'slipper.n.01', 'synonyms': ['slipper_(footwear)', 'carpet_slipper_(footwear)'], 'def': 'low footwear that can be slipped on and off easily; usually worn indoors', 'name': 'slipper_(footwear)'}, {'frequency': 'r', 'id': 991, 'synset': 'smoothie.n.02', 'synonyms': ['smoothie'], 'def': 'a thick smooth drink consisting of fresh fruit pureed with ice cream or yoghurt or milk', 'name': 'smoothie'}, {'frequency': 'r', 'id': 992, 'synset': 'snake.n.01', 'synonyms': ['snake', 'serpent'], 'def': 'limbless scaly elongate reptile; some are venomous', 'name': 'snake'}, {'frequency': 'f', 'id': 993, 'synset': 'snowboard.n.01', 'synonyms': ['snowboard'], 'def': 'a board that resembles a broad ski or a small surfboard; used in a standing position to slide down snow-covered slopes', 'name': 'snowboard'}, {'frequency': 'c', 'id': 994, 'synset': 'snowman.n.01', 'synonyms': ['snowman'], 'def': 'a figure of a person made of packed snow', 'name': 'snowman'}, {'frequency': 'c', 'id': 995, 'synset': 'snowmobile.n.01', 'synonyms': ['snowmobile'], 'def': 'tracked vehicle for travel on snow having skis in front', 'name': 'snowmobile'}, {'frequency': 'f', 'id': 996, 'synset': 'soap.n.01', 'synonyms': ['soap'], 'def': 'a cleansing agent made from the salts of vegetable or animal fats', 'name': 'soap'}, {'frequency': 'f', 'id': 997, 'synset': 'soccer_ball.n.01', 'synonyms': ['soccer_ball'], 'def': "an inflated ball used in playing soccer (called `football' outside of the United States)", 'name': 'soccer_ball'}, {'frequency': 'f', 'id': 998, 'synset': 'sock.n.01', 'synonyms': ['sock'], 'def': 'cloth covering for the foot; worn inside the shoe; reaches to between the ankle and the knee', 'name': 'sock'}, {'frequency': 'r', 'id': 999, 'synset': 'soda_fountain.n.02', 'synonyms': ['soda_fountain'], 'def': 'an apparatus for dispensing soda water', 'name': 'soda_fountain'}, {'frequency': 'r', 'id': 1000, 'synset': 'soda_water.n.01', 'synonyms': ['carbonated_water', 'club_soda', 'seltzer', 'sparkling_water'], 'def': 'effervescent beverage artificially charged with carbon dioxide', 'name': 'carbonated_water'}, {'frequency': 'f', 'id': 1001, 'synset': 'sofa.n.01', 'synonyms': ['sofa', 'couch', 'lounge'], 'def': 'an upholstered seat for more than one person', 'name': 'sofa'}, {'frequency': 'r', 'id': 1002, 'synset': 'softball.n.01', 'synonyms': ['softball'], 'def': 'ball used in playing softball', 'name': 'softball'}, {'frequency': 'c', 'id': 1003, 'synset': 'solar_array.n.01', 'synonyms': ['solar_array', 'solar_battery', 'solar_panel'], 'def': 'electrical device consisting of a large array of connected solar cells', 'name': 'solar_array'}, {'frequency': 'r', 'id': 1004, 'synset': 'sombrero.n.02', 'synonyms': ['sombrero'], 'def': 'a straw hat with a tall crown and broad brim; worn in American southwest and in Mexico', 'name': 'sombrero'}, {'frequency': 'c', 'id': 1005, 'synset': 'soup.n.01', 'synonyms': ['soup'], 'def': 'liquid food especially of meat or fish or vegetable stock often containing pieces of solid food', 'name': 'soup'}, {'frequency': 'r', 'id': 1006, 'synset': 'soup_bowl.n.01', 'synonyms': ['soup_bowl'], 'def': 'a bowl for serving soup', 'name': 'soup_bowl'}, {'frequency': 'c', 'id': 1007, 'synset': 'soupspoon.n.01', 'synonyms': ['soupspoon'], 'def': 'a spoon with a rounded bowl for eating soup', 'name': 'soupspoon'}, {'frequency': 'c', 'id': 1008, 'synset': 'sour_cream.n.01', 'synonyms': ['sour_cream', 'soured_cream'], 'def': 'soured light cream', 'name': 'sour_cream'}, {'frequency': 'r', 'id': 1009, 'synset': 'soya_milk.n.01', 'synonyms': ['soya_milk', 'soybean_milk', 'soymilk'], 'def': 'a milk substitute containing soybean flour and water; used in some infant formulas and in making tofu', 'name': 'soya_milk'}, {'frequency': 'r', 'id': 1010, 'synset': 'space_shuttle.n.01', 'synonyms': ['space_shuttle'], 'def': "a reusable spacecraft with wings for a controlled descent through the Earth's atmosphere", 'name': 'space_shuttle'}, {'frequency': 'r', 'id': 1011, 'synset': 'sparkler.n.02', 'synonyms': ['sparkler_(fireworks)'], 'def': 'a firework that burns slowly and throws out a shower of sparks', 'name': 'sparkler_(fireworks)'}, {'frequency': 'f', 'id': 1012, 'synset': 'spatula.n.02', 'synonyms': ['spatula'], 'def': 'a hand tool with a thin flexible blade used to mix or spread soft substances', 'name': 'spatula'}, {'frequency': 'r', 'id': 1013, 'synset': 'spear.n.01', 'synonyms': ['spear', 'lance'], 'def': 'a long pointed rod used as a tool or weapon', 'name': 'spear'}, {'frequency': 'f', 'id': 1014, 'synset': 'spectacles.n.01', 'synonyms': ['spectacles', 'specs', 'eyeglasses', 'glasses'], 'def': 'optical instrument consisting of a frame that holds a pair of lenses for correcting defective vision', 'name': 'spectacles'}, {'frequency': 'c', 'id': 1015, 'synset': 'spice_rack.n.01', 'synonyms': ['spice_rack'], 'def': 'a rack for displaying containers filled with spices', 'name': 'spice_rack'}, {'frequency': 'r', 'id': 1016, 'synset': 'spider.n.01', 'synonyms': ['spider'], 'def': 'predatory arachnid with eight legs, two poison fangs, two feelers, and usually two silk-spinning organs at the back end of the body', 'name': 'spider'}, {'frequency': 'c', 'id': 1017, 'synset': 'sponge.n.01', 'synonyms': ['sponge'], 'def': 'a porous mass usable to absorb water typically used for cleaning', 'name': 'sponge'}, {'frequency': 'f', 'id': 1018, 'synset': 'spoon.n.01', 'synonyms': ['spoon'], 'def': 'a piece of cutlery with a shallow bowl-shaped container and a handle', 'name': 'spoon'}, {'frequency': 'c', 'id': 1019, 'synset': 'sportswear.n.01', 'synonyms': ['sportswear', 'athletic_wear', 'activewear'], 'def': 'attire worn for sport or for casual wear', 'name': 'sportswear'}, {'frequency': 'c', 'id': 1020, 'synset': 'spotlight.n.02', 'synonyms': ['spotlight'], 'def': 'a lamp that produces a strong beam of light to illuminate a restricted area; used to focus attention of a stage performer', 'name': 'spotlight'}, {'frequency': 'r', 'id': 1021, 'synset': 'squirrel.n.01', 'synonyms': ['squirrel'], 'def': 'a kind of arboreal rodent having a long bushy tail', 'name': 'squirrel'}, {'frequency': 'c', 'id': 1022, 'synset': 'stapler.n.01', 'synonyms': ['stapler_(stapling_machine)'], 'def': 'a machine that inserts staples into sheets of paper in order to fasten them together', 'name': 'stapler_(stapling_machine)'}, {'frequency': 'r', 'id': 1023, 'synset': 'starfish.n.01', 'synonyms': ['starfish', 'sea_star'], 'def': 'echinoderms characterized by five arms extending from a central disk', 'name': 'starfish'}, {'frequency': 'f', 'id': 1024, 'synset': 'statue.n.01', 'synonyms': ['statue_(sculpture)'], 'def': 'a sculpture representing a human or animal', 'name': 'statue_(sculpture)'}, {'frequency': 'c', 'id': 1025, 'synset': 'steak.n.01', 'synonyms': ['steak_(food)'], 'def': 'a slice of meat cut from the fleshy part of an animal or large fish', 'name': 'steak_(food)'}, {'frequency': 'r', 'id': 1026, 'synset': 'steak_knife.n.01', 'synonyms': ['steak_knife'], 'def': 'a sharp table knife used in eating steak', 'name': 'steak_knife'}, {'frequency': 'r', 'id': 1027, 'synset': 'steamer.n.02', 'synonyms': ['steamer_(kitchen_appliance)'], 'def': 'a cooking utensil that can be used to cook food by steaming it', 'name': 'steamer_(kitchen_appliance)'}, {'frequency': 'f', 'id': 1028, 'synset': 'steering_wheel.n.01', 'synonyms': ['steering_wheel'], 'def': 'a handwheel that is used for steering', 'name': 'steering_wheel'}, {'frequency': 'r', 'id': 1029, 'synset': 'stencil.n.01', 'synonyms': ['stencil'], 'def': 'a sheet of material (metal, plastic, etc.) that has been perforated with a pattern; ink or paint can pass through the perforations to create the printed pattern on the surface below', 'name': 'stencil'}, {'frequency': 'r', 'id': 1030, 'synset': 'step_ladder.n.01', 'synonyms': ['stepladder'], 'def': 'a folding portable ladder hinged at the top', 'name': 'stepladder'}, {'frequency': 'c', 'id': 1031, 'synset': 'step_stool.n.01', 'synonyms': ['step_stool'], 'def': 'a stool that has one or two steps that fold under the seat', 'name': 'step_stool'}, {'frequency': 'c', 'id': 1032, 'synset': 'stereo.n.01', 'synonyms': ['stereo_(sound_system)'], 'def': 'electronic device for playing audio', 'name': 'stereo_(sound_system)'}, {'frequency': 'r', 'id': 1033, 'synset': 'stew.n.02', 'synonyms': ['stew'], 'def': 'food prepared by stewing especially meat or fish with vegetables', 'name': 'stew'}, {'frequency': 'r', 'id': 1034, 'synset': 'stirrer.n.02', 'synonyms': ['stirrer'], 'def': 'an implement used for stirring', 'name': 'stirrer'}, {'frequency': 'f', 'id': 1035, 'synset': 'stirrup.n.01', 'synonyms': ['stirrup'], 'def': "support consisting of metal loops into which rider's feet go", 'name': 'stirrup'}, {'frequency': 'c', 'id': 1036, 'synset': 'stocking.n.01', 'synonyms': ['stockings_(leg_wear)'], 'def': 'close-fitting hosiery to cover the foot and leg; come in matched pairs', 'name': 'stockings_(leg_wear)'}, {'frequency': 'f', 'id': 1037, 'synset': 'stool.n.01', 'synonyms': ['stool'], 'def': 'a simple seat without a back or arms', 'name': 'stool'}, {'frequency': 'f', 'id': 1038, 'synset': 'stop_sign.n.01', 'synonyms': ['stop_sign'], 'def': 'a traffic sign to notify drivers that they must come to a complete stop', 'name': 'stop_sign'}, {'frequency': 'f', 'id': 1039, 'synset': 'stoplight.n.01', 'synonyms': ['brake_light'], 'def': 'a red light on the rear of a motor vehicle that signals when the brakes are applied', 'name': 'brake_light'}, {'frequency': 'f', 'id': 1040, 'synset': 'stove.n.01', 'synonyms': ['stove', 'kitchen_stove', 'range_(kitchen_appliance)', 'kitchen_range', 'cooking_stove'], 'def': 'a kitchen appliance used for cooking food', 'name': 'stove'}, {'frequency': 'c', 'id': 1041, 'synset': 'strainer.n.01', 'synonyms': ['strainer'], 'def': 'a filter to retain larger pieces while smaller pieces and liquids pass through', 'name': 'strainer'}, {'frequency': 'f', 'id': 1042, 'synset': 'strap.n.01', 'synonyms': ['strap'], 'def': 'an elongated strip of material for binding things together or holding', 'name': 'strap'}, {'frequency': 'f', 'id': 1043, 'synset': 'straw.n.04', 'synonyms': ['straw_(for_drinking)', 'drinking_straw'], 'def': 'a thin paper or plastic tube used to suck liquids into the mouth', 'name': 'straw_(for_drinking)'}, {'frequency': 'f', 'id': 1044, 'synset': 'strawberry.n.01', 'synonyms': ['strawberry'], 'def': 'sweet fleshy red fruit', 'name': 'strawberry'}, {'frequency': 'f', 'id': 1045, 'synset': 'street_sign.n.01', 'synonyms': ['street_sign'], 'def': 'a sign visible from the street', 'name': 'street_sign'}, {'frequency': 'f', 'id': 1046, 'synset': 'streetlight.n.01', 'synonyms': ['streetlight', 'street_lamp'], 'def': 'a lamp supported on a lamppost; for illuminating a street', 'name': 'streetlight'}, {'frequency': 'r', 'id': 1047, 'synset': 'string_cheese.n.01', 'synonyms': ['string_cheese'], 'def': 'cheese formed in long strings twisted together', 'name': 'string_cheese'}, {'frequency': 'r', 'id': 1048, 'synset': 'stylus.n.02', 'synonyms': ['stylus'], 'def': 'a pointed tool for writing or drawing or engraving', 'name': 'stylus'}, {'frequency': 'r', 'id': 1049, 'synset': 'subwoofer.n.01', 'synonyms': ['subwoofer'], 'def': 'a loudspeaker that is designed to reproduce very low bass frequencies', 'name': 'subwoofer'}, {'frequency': 'r', 'id': 1050, 'synset': 'sugar_bowl.n.01', 'synonyms': ['sugar_bowl'], 'def': 'a dish in which sugar is served', 'name': 'sugar_bowl'}, {'frequency': 'r', 'id': 1051, 'synset': 'sugarcane.n.01', 'synonyms': ['sugarcane_(plant)'], 'def': 'juicy canes whose sap is a source of molasses and commercial sugar; fresh canes are sometimes chewed for the juice', 'name': 'sugarcane_(plant)'}, {'frequency': 'c', 'id': 1052, 'synset': 'suit.n.01', 'synonyms': ['suit_(clothing)'], 'def': 'a set of garments (usually including a jacket and trousers or skirt) for outerwear all of the same fabric and color', 'name': 'suit_(clothing)'}, {'frequency': 'c', 'id': 1053, 'synset': 'sunflower.n.01', 'synonyms': ['sunflower'], 'def': 'any plant of the genus Helianthus having large flower heads with dark disk florets and showy yellow rays', 'name': 'sunflower'}, {'frequency': 'f', 'id': 1054, 'synset': 'sunglasses.n.01', 'synonyms': ['sunglasses'], 'def': 'spectacles that are darkened or polarized to protect the eyes from the glare of the sun', 'name': 'sunglasses'}, {'frequency': 'c', 'id': 1055, 'synset': 'sunhat.n.01', 'synonyms': ['sunhat'], 'def': 'a hat with a broad brim that protects the face from direct exposure to the sun', 'name': 'sunhat'}, {'frequency': 'r', 'id': 1056, 'synset': 'sunscreen.n.01', 'synonyms': ['sunscreen', 'sunblock'], 'def': 'a cream spread on the skin; contains a chemical to filter out ultraviolet light and so protect from sunburn', 'name': 'sunscreen'}, {'frequency': 'f', 'id': 1057, 'synset': 'surfboard.n.01', 'synonyms': ['surfboard'], 'def': 'a narrow buoyant board for riding surf', 'name': 'surfboard'}, {'frequency': 'c', 'id': 1058, 'synset': 'sushi.n.01', 'synonyms': ['sushi'], 'def': 'rice (with raw fish) wrapped in seaweed', 'name': 'sushi'}, {'frequency': 'c', 'id': 1059, 'synset': 'swab.n.02', 'synonyms': ['mop'], 'def': 'cleaning implement consisting of absorbent material fastened to a handle; for cleaning floors', 'name': 'mop'}, {'frequency': 'c', 'id': 1060, 'synset': 'sweat_pants.n.01', 'synonyms': ['sweat_pants'], 'def': 'loose-fitting trousers with elastic cuffs; worn by athletes', 'name': 'sweat_pants'}, {'frequency': 'c', 'id': 1061, 'synset': 'sweatband.n.02', 'synonyms': ['sweatband'], 'def': 'a band of material tied around the forehead or wrist to absorb sweat', 'name': 'sweatband'}, {'frequency': 'f', 'id': 1062, 'synset': 'sweater.n.01', 'synonyms': ['sweater'], 'def': 'a crocheted or knitted garment covering the upper part of the body', 'name': 'sweater'}, {'frequency': 'f', 'id': 1063, 'synset': 'sweatshirt.n.01', 'synonyms': ['sweatshirt'], 'def': 'cotton knit pullover with long sleeves worn during athletic activity', 'name': 'sweatshirt'}, {'frequency': 'c', 'id': 1064, 'synset': 'sweet_potato.n.02', 'synonyms': ['sweet_potato'], 'def': 'the edible tuberous root of the sweet potato vine', 'name': 'sweet_potato'}, {'frequency': 'f', 'id': 1065, 'synset': 'swimsuit.n.01', 'synonyms': ['swimsuit', 'swimwear', 'bathing_suit', 'swimming_costume', 'bathing_costume', 'swimming_trunks', 'bathing_trunks'], 'def': 'garment worn for swimming', 'name': 'swimsuit'}, {'frequency': 'c', 'id': 1066, 'synset': 'sword.n.01', 'synonyms': ['sword'], 'def': 'a cutting or thrusting weapon that has a long metal blade', 'name': 'sword'}, {'frequency': 'r', 'id': 1067, 'synset': 'syringe.n.01', 'synonyms': ['syringe'], 'def': 'a medical instrument used to inject or withdraw fluids', 'name': 'syringe'}, {'frequency': 'r', 'id': 1068, 'synset': 'tabasco.n.02', 'synonyms': ['Tabasco_sauce'], 'def': 'very spicy sauce (trade name Tabasco) made from fully-aged red peppers', 'name': 'Tabasco_sauce'}, {'frequency': 'r', 'id': 1069, 'synset': 'table-tennis_table.n.01', 'synonyms': ['table-tennis_table', 'ping-pong_table'], 'def': 'a table used for playing table tennis', 'name': 'table-tennis_table'}, {'frequency': 'f', 'id': 1070, 'synset': 'table.n.02', 'synonyms': ['table'], 'def': 'a piece of furniture having a smooth flat top that is usually supported by one or more vertical legs', 'name': 'table'}, {'frequency': 'c', 'id': 1071, 'synset': 'table_lamp.n.01', 'synonyms': ['table_lamp'], 'def': 'a lamp that sits on a table', 'name': 'table_lamp'}, {'frequency': 'f', 'id': 1072, 'synset': 'tablecloth.n.01', 'synonyms': ['tablecloth'], 'def': 'a covering spread over a dining table', 'name': 'tablecloth'}, {'frequency': 'r', 'id': 1073, 'synset': 'tachometer.n.01', 'synonyms': ['tachometer'], 'def': 'measuring instrument for indicating speed of rotation', 'name': 'tachometer'}, {'frequency': 'r', 'id': 1074, 'synset': 'taco.n.02', 'synonyms': ['taco'], 'def': 'a small tortilla cupped around a filling', 'name': 'taco'}, {'frequency': 'f', 'id': 1075, 'synset': 'tag.n.02', 'synonyms': ['tag'], 'def': 'a label associated with something for the purpose of identification or information', 'name': 'tag'}, {'frequency': 'f', 'id': 1076, 'synset': 'taillight.n.01', 'synonyms': ['taillight', 'rear_light'], 'def': 'lamp (usually red) mounted at the rear of a motor vehicle', 'name': 'taillight'}, {'frequency': 'r', 'id': 1077, 'synset': 'tambourine.n.01', 'synonyms': ['tambourine'], 'def': 'a shallow drum with a single drumhead and with metallic disks in the sides', 'name': 'tambourine'}, {'frequency': 'r', 'id': 1078, 'synset': 'tank.n.01', 'synonyms': ['army_tank', 'armored_combat_vehicle', 'armoured_combat_vehicle'], 'def': 'an enclosed armored military vehicle; has a cannon and moves on caterpillar treads', 'name': 'army_tank'}, {'frequency': 'c', 'id': 1079, 'synset': 'tank.n.02', 'synonyms': ['tank_(storage_vessel)', 'storage_tank'], 'def': 'a large (usually metallic) vessel for holding gases or liquids', 'name': 'tank_(storage_vessel)'}, {'frequency': 'f', 'id': 1080, 'synset': 'tank_top.n.01', 'synonyms': ['tank_top_(clothing)'], 'def': 'a tight-fitting sleeveless shirt with wide shoulder straps and low neck and no front opening', 'name': 'tank_top_(clothing)'}, {'frequency': 'c', 'id': 1081, 'synset': 'tape.n.01', 'synonyms': ['tape_(sticky_cloth_or_paper)'], 'def': 'a long thin piece of cloth or paper as used for binding or fastening', 'name': 'tape_(sticky_cloth_or_paper)'}, {'frequency': 'c', 'id': 1082, 'synset': 'tape.n.04', 'synonyms': ['tape_measure', 'measuring_tape'], 'def': 'measuring instrument consisting of a narrow strip (cloth or metal) marked in inches or centimeters and used for measuring lengths', 'name': 'tape_measure'}, {'frequency': 'c', 'id': 1083, 'synset': 'tapestry.n.02', 'synonyms': ['tapestry'], 'def': 'a heavy textile with a woven design; used for curtains and upholstery', 'name': 'tapestry'}, {'frequency': 'f', 'id': 1084, 'synset': 'tarpaulin.n.01', 'synonyms': ['tarp'], 'def': 'waterproofed canvas', 'name': 'tarp'}, {'frequency': 'c', 'id': 1085, 'synset': 'tartan.n.01', 'synonyms': ['tartan', 'plaid'], 'def': 'a cloth having a crisscross design', 'name': 'tartan'}, {'frequency': 'c', 'id': 1086, 'synset': 'tassel.n.01', 'synonyms': ['tassel'], 'def': 'adornment consisting of a bunch of cords fastened at one end', 'name': 'tassel'}, {'frequency': 'r', 'id': 1087, 'synset': 'tea_bag.n.01', 'synonyms': ['tea_bag'], 'def': 'a measured amount of tea in a bag for an individual serving of tea', 'name': 'tea_bag'}, {'frequency': 'c', 'id': 1088, 'synset': 'teacup.n.02', 'synonyms': ['teacup'], 'def': 'a cup from which tea is drunk', 'name': 'teacup'}, {'frequency': 'c', 'id': 1089, 'synset': 'teakettle.n.01', 'synonyms': ['teakettle'], 'def': 'kettle for boiling water to make tea', 'name': 'teakettle'}, {'frequency': 'c', 'id': 1090, 'synset': 'teapot.n.01', 'synonyms': ['teapot'], 'def': 'pot for brewing tea; usually has a spout and handle', 'name': 'teapot'}, {'frequency': 'f', 'id': 1091, 'synset': 'teddy.n.01', 'synonyms': ['teddy_bear'], 'def': "plaything consisting of a child's toy bear (usually plush and stuffed with soft materials)", 'name': 'teddy_bear'}, {'frequency': 'f', 'id': 1092, 'synset': 'telephone.n.01', 'synonyms': ['telephone', 'phone', 'telephone_set'], 'def': 'electronic device for communicating by voice over long distances', 'name': 'telephone'}, {'frequency': 'c', 'id': 1093, 'synset': 'telephone_booth.n.01', 'synonyms': ['telephone_booth', 'phone_booth', 'call_box', 'telephone_box', 'telephone_kiosk'], 'def': 'booth for using a telephone', 'name': 'telephone_booth'}, {'frequency': 'f', 'id': 1094, 'synset': 'telephone_pole.n.01', 'synonyms': ['telephone_pole', 'telegraph_pole', 'telegraph_post'], 'def': 'tall pole supporting telephone wires', 'name': 'telephone_pole'}, {'frequency': 'r', 'id': 1095, 'synset': 'telephoto_lens.n.01', 'synonyms': ['telephoto_lens', 'zoom_lens'], 'def': 'a camera lens that magnifies the image', 'name': 'telephoto_lens'}, {'frequency': 'c', 'id': 1096, 'synset': 'television_camera.n.01', 'synonyms': ['television_camera', 'tv_camera'], 'def': 'television equipment for capturing and recording video', 'name': 'television_camera'}, {'frequency': 'f', 'id': 1097, 'synset': 'television_receiver.n.01', 'synonyms': ['television_set', 'tv', 'tv_set'], 'def': 'an electronic device that receives television signals and displays them on a screen', 'name': 'television_set'}, {'frequency': 'f', 'id': 1098, 'synset': 'tennis_ball.n.01', 'synonyms': ['tennis_ball'], 'def': 'ball about the size of a fist used in playing tennis', 'name': 'tennis_ball'}, {'frequency': 'f', 'id': 1099, 'synset': 'tennis_racket.n.01', 'synonyms': ['tennis_racket'], 'def': 'a racket used to play tennis', 'name': 'tennis_racket'}, {'frequency': 'r', 'id': 1100, 'synset': 'tequila.n.01', 'synonyms': ['tequila'], 'def': 'Mexican liquor made from fermented juices of an agave plant', 'name': 'tequila'}, {'frequency': 'c', 'id': 1101, 'synset': 'thermometer.n.01', 'synonyms': ['thermometer'], 'def': 'measuring instrument for measuring temperature', 'name': 'thermometer'}, {'frequency': 'c', 'id': 1102, 'synset': 'thermos.n.01', 'synonyms': ['thermos_bottle'], 'def': 'vacuum flask that preserves temperature of hot or cold drinks', 'name': 'thermos_bottle'}, {'frequency': 'c', 'id': 1103, 'synset': 'thermostat.n.01', 'synonyms': ['thermostat'], 'def': 'a regulator for automatically regulating temperature by starting or stopping the supply of heat', 'name': 'thermostat'}, {'frequency': 'r', 'id': 1104, 'synset': 'thimble.n.02', 'synonyms': ['thimble'], 'def': 'a small metal cap to protect the finger while sewing; can be used as a small container', 'name': 'thimble'}, {'frequency': 'c', 'id': 1105, 'synset': 'thread.n.01', 'synonyms': ['thread', 'yarn'], 'def': 'a fine cord of twisted fibers (of cotton or silk or wool or nylon etc.) used in sewing and weaving', 'name': 'thread'}, {'frequency': 'c', 'id': 1106, 'synset': 'thumbtack.n.01', 'synonyms': ['thumbtack', 'drawing_pin', 'pushpin'], 'def': 'a tack for attaching papers to a bulletin board or drawing board', 'name': 'thumbtack'}, {'frequency': 'c', 'id': 1107, 'synset': 'tiara.n.01', 'synonyms': ['tiara'], 'def': 'a jeweled headdress worn by women on formal occasions', 'name': 'tiara'}, {'frequency': 'c', 'id': 1108, 'synset': 'tiger.n.02', 'synonyms': ['tiger'], 'def': 'large feline of forests in most of Asia having a tawny coat with black stripes', 'name': 'tiger'}, {'frequency': 'c', 'id': 1109, 'synset': 'tights.n.01', 'synonyms': ['tights_(clothing)', 'leotards'], 'def': 'skintight knit hose covering the body from the waist to the feet worn by acrobats and dancers and as stockings by women and girls', 'name': 'tights_(clothing)'}, {'frequency': 'c', 'id': 1110, 'synset': 'timer.n.01', 'synonyms': ['timer', 'stopwatch'], 'def': 'a timepiece that measures a time interval and signals its end', 'name': 'timer'}, {'frequency': 'f', 'id': 1111, 'synset': 'tinfoil.n.01', 'synonyms': ['tinfoil'], 'def': 'foil made of tin or an alloy of tin and lead', 'name': 'tinfoil'}, {'frequency': 'r', 'id': 1112, 'synset': 'tinsel.n.01', 'synonyms': ['tinsel'], 'def': 'a showy decoration that is basically valueless', 'name': 'tinsel'}, {'frequency': 'f', 'id': 1113, 'synset': 'tissue.n.02', 'synonyms': ['tissue_paper'], 'def': 'a soft thin (usually translucent) paper', 'name': 'tissue_paper'}, {'frequency': 'c', 'id': 1114, 'synset': 'toast.n.01', 'synonyms': ['toast_(food)'], 'def': 'slice of bread that has been toasted', 'name': 'toast_(food)'}, {'frequency': 'f', 'id': 1115, 'synset': 'toaster.n.02', 'synonyms': ['toaster'], 'def': 'a kitchen appliance (usually electric) for toasting bread', 'name': 'toaster'}, {'frequency': 'c', 'id': 1116, 'synset': 'toaster_oven.n.01', 'synonyms': ['toaster_oven'], 'def': 'kitchen appliance consisting of a small electric oven for toasting or warming food', 'name': 'toaster_oven'}, {'frequency': 'f', 'id': 1117, 'synset': 'toilet.n.02', 'synonyms': ['toilet'], 'def': 'a plumbing fixture for defecation and urination', 'name': 'toilet'}, {'frequency': 'f', 'id': 1118, 'synset': 'toilet_tissue.n.01', 'synonyms': ['toilet_tissue', 'toilet_paper', 'bathroom_tissue'], 'def': 'a soft thin absorbent paper for use in toilets', 'name': 'toilet_tissue'}, {'frequency': 'f', 'id': 1119, 'synset': 'tomato.n.01', 'synonyms': ['tomato'], 'def': 'mildly acid red or yellow pulpy fruit eaten as a vegetable', 'name': 'tomato'}, {'frequency': 'c', 'id': 1120, 'synset': 'tongs.n.01', 'synonyms': ['tongs'], 'def': 'any of various devices for taking hold of objects; usually have two hinged legs with handles above and pointed hooks below', 'name': 'tongs'}, {'frequency': 'c', 'id': 1121, 'synset': 'toolbox.n.01', 'synonyms': ['toolbox'], 'def': 'a box or chest or cabinet for holding hand tools', 'name': 'toolbox'}, {'frequency': 'f', 'id': 1122, 'synset': 'toothbrush.n.01', 'synonyms': ['toothbrush'], 'def': 'small brush; has long handle; used to clean teeth', 'name': 'toothbrush'}, {'frequency': 'f', 'id': 1123, 'synset': 'toothpaste.n.01', 'synonyms': ['toothpaste'], 'def': 'a dentifrice in the form of a paste', 'name': 'toothpaste'}, {'frequency': 'c', 'id': 1124, 'synset': 'toothpick.n.01', 'synonyms': ['toothpick'], 'def': 'pick consisting of a small strip of wood or plastic; used to pick food from between the teeth', 'name': 'toothpick'}, {'frequency': 'c', 'id': 1125, 'synset': 'top.n.09', 'synonyms': ['cover'], 'def': 'covering for a hole (especially a hole in the top of a container)', 'name': 'cover'}, {'frequency': 'c', 'id': 1126, 'synset': 'tortilla.n.01', 'synonyms': ['tortilla'], 'def': 'thin unleavened pancake made from cornmeal or wheat flour', 'name': 'tortilla'}, {'frequency': 'c', 'id': 1127, 'synset': 'tow_truck.n.01', 'synonyms': ['tow_truck'], 'def': 'a truck equipped to hoist and pull wrecked cars (or to remove cars from no-parking zones)', 'name': 'tow_truck'}, {'frequency': 'f', 'id': 1128, 'synset': 'towel.n.01', 'synonyms': ['towel'], 'def': 'a rectangular piece of absorbent cloth (or paper) for drying or wiping', 'name': 'towel'}, {'frequency': 'f', 'id': 1129, 'synset': 'towel_rack.n.01', 'synonyms': ['towel_rack', 'towel_rail', 'towel_bar'], 'def': 'a rack consisting of one or more bars on which towels can be hung', 'name': 'towel_rack'}, {'frequency': 'f', 'id': 1130, 'synset': 'toy.n.03', 'synonyms': ['toy'], 'def': 'a device regarded as providing amusement', 'name': 'toy'}, {'frequency': 'c', 'id': 1131, 'synset': 'tractor.n.01', 'synonyms': ['tractor_(farm_equipment)'], 'def': 'a wheeled vehicle with large wheels; used in farming and other applications', 'name': 'tractor_(farm_equipment)'}, {'frequency': 'f', 'id': 1132, 'synset': 'traffic_light.n.01', 'synonyms': ['traffic_light'], 'def': 'a device to control vehicle traffic often consisting of three or more lights', 'name': 'traffic_light'}, {'frequency': 'r', 'id': 1133, 'synset': 'trail_bike.n.01', 'synonyms': ['dirt_bike'], 'def': 'a lightweight motorcycle equipped with rugged tires and suspension for off-road use', 'name': 'dirt_bike'}, {'frequency': 'c', 'id': 1134, 'synset': 'trailer_truck.n.01', 'synonyms': ['trailer_truck', 'tractor_trailer', 'trucking_rig', 'articulated_lorry', 'semi_truck'], 'def': 'a truck consisting of a tractor and trailer together', 'name': 'trailer_truck'}, {'frequency': 'f', 'id': 1135, 'synset': 'train.n.01', 'synonyms': ['train_(railroad_vehicle)', 'railroad_train'], 'def': 'public or private transport provided by a line of railway cars coupled together and drawn by a locomotive', 'name': 'train_(railroad_vehicle)'}, {'frequency': 'r', 'id': 1136, 'synset': 'trampoline.n.01', 'synonyms': ['trampoline'], 'def': 'gymnastic apparatus consisting of a strong canvas sheet attached with springs to a metal frame', 'name': 'trampoline'}, {'frequency': 'f', 'id': 1137, 'synset': 'tray.n.01', 'synonyms': ['tray'], 'def': 'an open receptacle for holding or displaying or serving articles or food', 'name': 'tray'}, {'frequency': 'r', 'id': 1138, 'synset': 'tree_house.n.01', 'synonyms': ['tree_house'], 'def': '(NOT A TREE) a PLAYHOUSE built in the branches of a tree', 'name': 'tree_house'}, {'frequency': 'r', 'id': 1139, 'synset': 'trench_coat.n.01', 'synonyms': ['trench_coat'], 'def': 'a military style raincoat; belted with deep pockets', 'name': 'trench_coat'}, {'frequency': 'r', 'id': 1140, 'synset': 'triangle.n.05', 'synonyms': ['triangle_(musical_instrument)'], 'def': 'a percussion instrument consisting of a metal bar bent in the shape of an open triangle', 'name': 'triangle_(musical_instrument)'}, {'frequency': 'r', 'id': 1141, 'synset': 'tricycle.n.01', 'synonyms': ['tricycle'], 'def': 'a vehicle with three wheels that is moved by foot pedals', 'name': 'tricycle'}, {'frequency': 'c', 'id': 1142, 'synset': 'tripod.n.01', 'synonyms': ['tripod'], 'def': 'a three-legged rack used for support', 'name': 'tripod'}, {'frequency': 'f', 'id': 1143, 'synset': 'trouser.n.01', 'synonyms': ['trousers', 'pants_(clothing)'], 'def': 'a garment extending from the waist to the knee or ankle, covering each leg separately', 'name': 'trousers'}, {'frequency': 'f', 'id': 1144, 'synset': 'truck.n.01', 'synonyms': ['truck'], 'def': 'an automotive vehicle suitable for hauling', 'name': 'truck'}, {'frequency': 'r', 'id': 1145, 'synset': 'truffle.n.03', 'synonyms': ['truffle_(chocolate)', 'chocolate_truffle'], 'def': 'creamy chocolate candy', 'name': 'truffle_(chocolate)'}, {'frequency': 'c', 'id': 1146, 'synset': 'trunk.n.02', 'synonyms': ['trunk'], 'def': 'luggage consisting of a large strong case used when traveling or for storage', 'name': 'trunk'}, {'frequency': 'r', 'id': 1147, 'synset': 'tub.n.02', 'synonyms': ['vat'], 'def': 'a large open vessel for holding or storing liquids', 'name': 'vat'}, {'frequency': 'c', 'id': 1148, 'synset': 'turban.n.01', 'synonyms': ['turban'], 'def': 'a traditional headdress consisting of a long scarf wrapped around the head', 'name': 'turban'}, {'frequency': 'r', 'id': 1149, 'synset': 'turkey.n.01', 'synonyms': ['turkey_(bird)'], 'def': 'large gallinaceous bird with fan-shaped tail; widely domesticated for food', 'name': 'turkey_(bird)'}, {'frequency': 'c', 'id': 1150, 'synset': 'turkey.n.04', 'synonyms': ['turkey_(food)'], 'def': 'flesh of large domesticated fowl usually roasted', 'name': 'turkey_(food)'}, {'frequency': 'r', 'id': 1151, 'synset': 'turnip.n.01', 'synonyms': ['turnip'], 'def': 'widely cultivated plant having a large fleshy edible white or yellow root', 'name': 'turnip'}, {'frequency': 'c', 'id': 1152, 'synset': 'turtle.n.02', 'synonyms': ['turtle'], 'def': 'any of various aquatic and land reptiles having a bony shell and flipper-like limbs for swimming', 'name': 'turtle'}, {'frequency': 'r', 'id': 1153, 'synset': 'turtleneck.n.01', 'synonyms': ['turtleneck_(clothing)', 'polo-neck'], 'def': 'a sweater or jersey with a high close-fitting collar', 'name': 'turtleneck_(clothing)'}, {'frequency': 'r', 'id': 1154, 'synset': 'typewriter.n.01', 'synonyms': ['typewriter'], 'def': 'hand-operated character printer for printing written messages one character at a time', 'name': 'typewriter'}, {'frequency': 'f', 'id': 1155, 'synset': 'umbrella.n.01', 'synonyms': ['umbrella'], 'def': 'a lightweight handheld collapsible canopy', 'name': 'umbrella'}, {'frequency': 'c', 'id': 1156, 'synset': 'underwear.n.01', 'synonyms': ['underwear', 'underclothes', 'underclothing', 'underpants'], 'def': 'undergarment worn next to the skin and under the outer garments', 'name': 'underwear'}, {'frequency': 'r', 'id': 1157, 'synset': 'unicycle.n.01', 'synonyms': ['unicycle'], 'def': 'a vehicle with a single wheel that is driven by pedals', 'name': 'unicycle'}, {'frequency': 'c', 'id': 1158, 'synset': 'urinal.n.01', 'synonyms': ['urinal'], 'def': 'a plumbing fixture (usually attached to the wall) used by men to urinate', 'name': 'urinal'}, {'frequency': 'r', 'id': 1159, 'synset': 'urn.n.01', 'synonyms': ['urn'], 'def': 'a large vase that usually has a pedestal or feet', 'name': 'urn'}, {'frequency': 'c', 'id': 1160, 'synset': 'vacuum.n.04', 'synonyms': ['vacuum_cleaner'], 'def': 'an electrical home appliance that cleans by suction', 'name': 'vacuum_cleaner'}, {'frequency': 'c', 'id': 1161, 'synset': 'valve.n.03', 'synonyms': ['valve'], 'def': 'control consisting of a mechanical device for controlling the flow of a fluid', 'name': 'valve'}, {'frequency': 'f', 'id': 1162, 'synset': 'vase.n.01', 'synonyms': ['vase'], 'def': 'an open jar of glass or porcelain used as an ornament or to hold flowers', 'name': 'vase'}, {'frequency': 'c', 'id': 1163, 'synset': 'vending_machine.n.01', 'synonyms': ['vending_machine'], 'def': 'a slot machine for selling goods', 'name': 'vending_machine'}, {'frequency': 'f', 'id': 1164, 'synset': 'vent.n.01', 'synonyms': ['vent', 'blowhole', 'air_vent'], 'def': 'a hole for the escape of gas or air', 'name': 'vent'}, {'frequency': 'c', 'id': 1165, 'synset': 'videotape.n.01', 'synonyms': ['videotape'], 'def': 'a video recording made on magnetic tape', 'name': 'videotape'}, {'frequency': 'r', 'id': 1166, 'synset': 'vinegar.n.01', 'synonyms': ['vinegar'], 'def': 'sour-tasting liquid produced usually by oxidation of the alcohol in wine or cider and used as a condiment or food preservative', 'name': 'vinegar'}, {'frequency': 'r', 'id': 1167, 'synset': 'violin.n.01', 'synonyms': ['violin', 'fiddle'], 'def': 'bowed stringed instrument that is the highest member of the violin family', 'name': 'violin'}, {'frequency': 'r', 'id': 1168, 'synset': 'vodka.n.01', 'synonyms': ['vodka'], 'def': 'unaged colorless liquor originating in Russia', 'name': 'vodka'}, {'frequency': 'r', 'id': 1169, 'synset': 'volleyball.n.02', 'synonyms': ['volleyball'], 'def': 'an inflated ball used in playing volleyball', 'name': 'volleyball'}, {'frequency': 'r', 'id': 1170, 'synset': 'vulture.n.01', 'synonyms': ['vulture'], 'def': 'any of various large birds of prey having naked heads and weak claws and feeding chiefly on carrion', 'name': 'vulture'}, {'frequency': 'c', 'id': 1171, 'synset': 'waffle.n.01', 'synonyms': ['waffle'], 'def': 'pancake batter baked in a waffle iron', 'name': 'waffle'}, {'frequency': 'r', 'id': 1172, 'synset': 'waffle_iron.n.01', 'synonyms': ['waffle_iron'], 'def': 'a kitchen appliance for baking waffles', 'name': 'waffle_iron'}, {'frequency': 'c', 'id': 1173, 'synset': 'wagon.n.01', 'synonyms': ['wagon'], 'def': 'any of various kinds of wheeled vehicles drawn by an animal or a tractor', 'name': 'wagon'}, {'frequency': 'c', 'id': 1174, 'synset': 'wagon_wheel.n.01', 'synonyms': ['wagon_wheel'], 'def': 'a wheel of a wagon', 'name': 'wagon_wheel'}, {'frequency': 'c', 'id': 1175, 'synset': 'walking_stick.n.01', 'synonyms': ['walking_stick'], 'def': 'a stick carried in the hand for support in walking', 'name': 'walking_stick'}, {'frequency': 'c', 'id': 1176, 'synset': 'wall_clock.n.01', 'synonyms': ['wall_clock'], 'def': 'a clock mounted on a wall', 'name': 'wall_clock'}, {'frequency': 'f', 'id': 1177, 'synset': 'wall_socket.n.01', 'synonyms': ['wall_socket', 'wall_plug', 'electric_outlet', 'electrical_outlet', 'outlet', 'electric_receptacle'], 'def': 'receptacle providing a place in a wiring system where current can be taken to run electrical devices', 'name': 'wall_socket'}, {'frequency': 'c', 'id': 1178, 'synset': 'wallet.n.01', 'synonyms': ['wallet', 'billfold'], 'def': 'a pocket-size case for holding papers and paper money', 'name': 'wallet'}, {'frequency': 'r', 'id': 1179, 'synset': 'walrus.n.01', 'synonyms': ['walrus'], 'def': 'either of two large northern marine mammals having ivory tusks and tough hide over thick blubber', 'name': 'walrus'}, {'frequency': 'r', 'id': 1180, 'synset': 'wardrobe.n.01', 'synonyms': ['wardrobe'], 'def': 'a tall piece of furniture that provides storage space for clothes; has a door and rails or hooks for hanging clothes', 'name': 'wardrobe'}, {'frequency': 'r', 'id': 1181, 'synset': 'wasabi.n.02', 'synonyms': ['wasabi'], 'def': 'the thick green root of the wasabi plant that the Japanese use in cooking and that tastes like strong horseradish', 'name': 'wasabi'}, {'frequency': 'c', 'id': 1182, 'synset': 'washer.n.03', 'synonyms': ['automatic_washer', 'washing_machine'], 'def': 'a home appliance for washing clothes and linens automatically', 'name': 'automatic_washer'}, {'frequency': 'f', 'id': 1183, 'synset': 'watch.n.01', 'synonyms': ['watch', 'wristwatch'], 'def': 'a small, portable timepiece', 'name': 'watch'}, {'frequency': 'f', 'id': 1184, 'synset': 'water_bottle.n.01', 'synonyms': ['water_bottle'], 'def': 'a bottle for holding water', 'name': 'water_bottle'}, {'frequency': 'c', 'id': 1185, 'synset': 'water_cooler.n.01', 'synonyms': ['water_cooler'], 'def': 'a device for cooling and dispensing drinking water', 'name': 'water_cooler'}, {'frequency': 'c', 'id': 1186, 'synset': 'water_faucet.n.01', 'synonyms': ['water_faucet', 'water_tap', 'tap_(water_faucet)'], 'def': 'a faucet for drawing water from a pipe or cask', 'name': 'water_faucet'}, {'frequency': 'r', 'id': 1187, 'synset': 'water_filter.n.01', 'synonyms': ['water_filter'], 'def': 'a filter to remove impurities from the water supply', 'name': 'water_filter'}, {'frequency': 'r', 'id': 1188, 'synset': 'water_heater.n.01', 'synonyms': ['water_heater', 'hot-water_heater'], 'def': 'a heater and storage tank to supply heated water', 'name': 'water_heater'}, {'frequency': 'r', 'id': 1189, 'synset': 'water_jug.n.01', 'synonyms': ['water_jug'], 'def': 'a jug that holds water', 'name': 'water_jug'}, {'frequency': 'r', 'id': 1190, 'synset': 'water_pistol.n.01', 'synonyms': ['water_gun', 'squirt_gun'], 'def': 'plaything consisting of a toy pistol that squirts water', 'name': 'water_gun'}, {'frequency': 'c', 'id': 1191, 'synset': 'water_scooter.n.01', 'synonyms': ['water_scooter', 'sea_scooter', 'jet_ski'], 'def': 'a motorboat resembling a motor scooter (NOT A SURFBOARD OR WATER SKI)', 'name': 'water_scooter'}, {'frequency': 'c', 'id': 1192, 'synset': 'water_ski.n.01', 'synonyms': ['water_ski'], 'def': 'broad ski for skimming over water towed by a speedboat (DO NOT MARK WATER)', 'name': 'water_ski'}, {'frequency': 'c', 'id': 1193, 'synset': 'water_tower.n.01', 'synonyms': ['water_tower'], 'def': 'a large reservoir for water', 'name': 'water_tower'}, {'frequency': 'c', 'id': 1194, 'synset': 'watering_can.n.01', 'synonyms': ['watering_can'], 'def': 'a container with a handle and a spout with a perforated nozzle; used to sprinkle water over plants', 'name': 'watering_can'}, {'frequency': 'c', 'id': 1195, 'synset': 'watermelon.n.02', 'synonyms': ['watermelon'], 'def': 'large oblong or roundish melon with a hard green rind and sweet watery red or occasionally yellowish pulp', 'name': 'watermelon'}, {'frequency': 'f', 'id': 1196, 'synset': 'weathervane.n.01', 'synonyms': ['weathervane', 'vane_(weathervane)', 'wind_vane'], 'def': 'mechanical device attached to an elevated structure; rotates freely to show the direction of the wind', 'name': 'weathervane'}, {'frequency': 'c', 'id': 1197, 'synset': 'webcam.n.01', 'synonyms': ['webcam'], 'def': 'a digital camera designed to take digital photographs and transmit them over the internet', 'name': 'webcam'}, {'frequency': 'c', 'id': 1198, 'synset': 'wedding_cake.n.01', 'synonyms': ['wedding_cake', 'bridecake'], 'def': 'a rich cake with two or more tiers and covered with frosting and decorations; served at a wedding reception', 'name': 'wedding_cake'}, {'frequency': 'c', 'id': 1199, 'synset': 'wedding_ring.n.01', 'synonyms': ['wedding_ring', 'wedding_band'], 'def': 'a ring given to the bride and/or groom at the wedding', 'name': 'wedding_ring'}, {'frequency': 'f', 'id': 1200, 'synset': 'wet_suit.n.01', 'synonyms': ['wet_suit'], 'def': 'a close-fitting garment made of a permeable material; worn in cold water to retain body heat', 'name': 'wet_suit'}, {'frequency': 'f', 'id': 1201, 'synset': 'wheel.n.01', 'synonyms': ['wheel'], 'def': 'a circular frame with spokes (or a solid disc) that can rotate on a shaft or axle', 'name': 'wheel'}, {'frequency': 'c', 'id': 1202, 'synset': 'wheelchair.n.01', 'synonyms': ['wheelchair'], 'def': 'a movable chair mounted on large wheels', 'name': 'wheelchair'}, {'frequency': 'c', 'id': 1203, 'synset': 'whipped_cream.n.01', 'synonyms': ['whipped_cream'], 'def': 'cream that has been beaten until light and fluffy', 'name': 'whipped_cream'}, {'frequency': 'r', 'id': 1204, 'synset': 'whiskey.n.01', 'synonyms': ['whiskey'], 'def': 'a liquor made from fermented mash of grain', 'name': 'whiskey'}, {'frequency': 'r', 'id': 1205, 'synset': 'whistle.n.03', 'synonyms': ['whistle'], 'def': 'a small wind instrument that produces a whistling sound by blowing into it', 'name': 'whistle'}, {'frequency': 'r', 'id': 1206, 'synset': 'wick.n.02', 'synonyms': ['wick'], 'def': 'a loosely woven cord in a candle or oil lamp that is lit on fire', 'name': 'wick'}, {'frequency': 'c', 'id': 1207, 'synset': 'wig.n.01', 'synonyms': ['wig'], 'def': 'hairpiece covering the head and made of real or synthetic hair', 'name': 'wig'}, {'frequency': 'c', 'id': 1208, 'synset': 'wind_chime.n.01', 'synonyms': ['wind_chime'], 'def': 'a decorative arrangement of pieces of metal or glass or pottery that hang together loosely so the wind can cause them to tinkle', 'name': 'wind_chime'}, {'frequency': 'c', 'id': 1209, 'synset': 'windmill.n.01', 'synonyms': ['windmill'], 'def': 'a mill that is powered by the wind', 'name': 'windmill'}, {'frequency': 'c', 'id': 1210, 'synset': 'window_box.n.01', 'synonyms': ['window_box_(for_plants)'], 'def': 'a container for growing plants on a windowsill', 'name': 'window_box_(for_plants)'}, {'frequency': 'f', 'id': 1211, 'synset': 'windshield_wiper.n.01', 'synonyms': ['windshield_wiper', 'windscreen_wiper', 'wiper_(for_windshield/screen)'], 'def': 'a mechanical device that cleans the windshield', 'name': 'windshield_wiper'}, {'frequency': 'c', 'id': 1212, 'synset': 'windsock.n.01', 'synonyms': ['windsock', 'air_sock', 'air-sleeve', 'wind_sleeve', 'wind_cone'], 'def': 'a truncated cloth cone mounted on a mast/pole; shows wind direction', 'name': 'windsock'}, {'frequency': 'f', 'id': 1213, 'synset': 'wine_bottle.n.01', 'synonyms': ['wine_bottle'], 'def': 'a bottle for holding wine', 'name': 'wine_bottle'}, {'frequency': 'r', 'id': 1214, 'synset': 'wine_bucket.n.01', 'synonyms': ['wine_bucket', 'wine_cooler'], 'def': 'a bucket of ice used to chill a bottle of wine', 'name': 'wine_bucket'}, {'frequency': 'f', 'id': 1215, 'synset': 'wineglass.n.01', 'synonyms': ['wineglass'], 'def': 'a glass that has a stem and in which wine is served', 'name': 'wineglass'}, {'frequency': 'r', 'id': 1216, 'synset': 'wing_chair.n.01', 'synonyms': ['wing_chair'], 'def': 'easy chair having wings on each side of a high back', 'name': 'wing_chair'}, {'frequency': 'c', 'id': 1217, 'synset': 'winker.n.02', 'synonyms': ['blinder_(for_horses)'], 'def': 'blinds that prevent a horse from seeing something on either side', 'name': 'blinder_(for_horses)'}, {'frequency': 'c', 'id': 1218, 'synset': 'wok.n.01', 'synonyms': ['wok'], 'def': 'pan with a convex bottom; used for frying in Chinese cooking', 'name': 'wok'}, {'frequency': 'r', 'id': 1219, 'synset': 'wolf.n.01', 'synonyms': ['wolf'], 'def': 'a wild carnivorous mammal of the dog family, living and hunting in packs', 'name': 'wolf'}, {'frequency': 'c', 'id': 1220, 'synset': 'wooden_spoon.n.02', 'synonyms': ['wooden_spoon'], 'def': 'a spoon made of wood', 'name': 'wooden_spoon'}, {'frequency': 'c', 'id': 1221, 'synset': 'wreath.n.01', 'synonyms': ['wreath'], 'def': 'an arrangement of flowers, leaves, or stems fastened in a ring', 'name': 'wreath'}, {'frequency': 'c', 'id': 1222, 'synset': 'wrench.n.03', 'synonyms': ['wrench', 'spanner'], 'def': 'a hand tool that is used to hold or twist a nut or bolt', 'name': 'wrench'}, {'frequency': 'c', 'id': 1223, 'synset': 'wristband.n.01', 'synonyms': ['wristband'], 'def': 'band consisting of a part of a sleeve that covers the wrist', 'name': 'wristband'}, {'frequency': 'f', 'id': 1224, 'synset': 'wristlet.n.01', 'synonyms': ['wristlet', 'wrist_band'], 'def': 'a band or bracelet worn around the wrist', 'name': 'wristlet'}, {'frequency': 'r', 'id': 1225, 'synset': 'yacht.n.01', 'synonyms': ['yacht'], 'def': 'an expensive vessel propelled by sail or power and used for cruising or racing', 'name': 'yacht'}, {'frequency': 'r', 'id': 1226, 'synset': 'yak.n.02', 'synonyms': ['yak'], 'def': 'large long-haired wild ox of Tibet often domesticated', 'name': 'yak'}, {'frequency': 'c', 'id': 1227, 'synset': 'yogurt.n.01', 'synonyms': ['yogurt', 'yoghurt', 'yoghourt'], 'def': 'a custard-like food made from curdled milk', 'name': 'yogurt'}, {'frequency': 'r', 'id': 1228, 'synset': 'yoke.n.07', 'synonyms': ['yoke_(animal_equipment)'], 'def': 'gear joining two animals at the neck; NOT egg yolk', 'name': 'yoke_(animal_equipment)'}, {'frequency': 'f', 'id': 1229, 'synset': 'zebra.n.01', 'synonyms': ['zebra'], 'def': 'any of several fleet black-and-white striped African equines', 'name': 'zebra'}, {'frequency': 'c', 'id': 1230, 'synset': 'zucchini.n.02', 'synonyms': ['zucchini', 'courgette'], 'def': 'small cucumber-shaped vegetable marrow; typically dark green', 'name': 'zucchini'}] # noqa +# fmt: on diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/lvis_v1_categories.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/lvis_v1_categories.py new file mode 100644 index 00000000..7374e696 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/lvis_v1_categories.py @@ -0,0 +1,16 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# Autogen with +# with open("lvis_v1_val.json", "r") as f: +# a = json.load(f) +# c = a["categories"] +# for x in c: +# del x["image_count"] +# del x["instance_count"] +# LVIS_CATEGORIES = repr(c) + " # noqa" +# with open("/tmp/lvis_categories.py", "wt") as f: +# f.write(f"LVIS_CATEGORIES = {LVIS_CATEGORIES}") +# Then paste the contents of that file below + +# fmt: off +LVIS_CATEGORIES = [{'frequency': 'c', 'synset': 'aerosol.n.02', 'synonyms': ['aerosol_can', 'spray_can'], 'id': 1, 'def': 'a dispenser that holds a substance under pressure', 'name': 'aerosol_can'}, {'frequency': 'f', 'synset': 'air_conditioner.n.01', 'synonyms': ['air_conditioner'], 'id': 2, 'def': 'a machine that keeps air cool and dry', 'name': 'air_conditioner'}, {'frequency': 'f', 'synset': 'airplane.n.01', 'synonyms': ['airplane', 'aeroplane'], 'id': 3, 'def': 'an aircraft that has a fixed wing and is powered by propellers or jets', 'name': 'airplane'}, {'frequency': 'f', 'synset': 'alarm_clock.n.01', 'synonyms': ['alarm_clock'], 'id': 4, 'def': 'a clock that wakes a sleeper at some preset time', 'name': 'alarm_clock'}, {'frequency': 'c', 'synset': 'alcohol.n.01', 'synonyms': ['alcohol', 'alcoholic_beverage'], 'id': 5, 'def': 'a liquor or brew containing alcohol as the active agent', 'name': 'alcohol'}, {'frequency': 'c', 'synset': 'alligator.n.02', 'synonyms': ['alligator', 'gator'], 'id': 6, 'def': 'amphibious reptiles related to crocodiles but with shorter broader snouts', 'name': 'alligator'}, {'frequency': 'c', 'synset': 'almond.n.02', 'synonyms': ['almond'], 'id': 7, 'def': 'oval-shaped edible seed of the almond tree', 'name': 'almond'}, {'frequency': 'c', 'synset': 'ambulance.n.01', 'synonyms': ['ambulance'], 'id': 8, 'def': 'a vehicle that takes people to and from hospitals', 'name': 'ambulance'}, {'frequency': 'c', 'synset': 'amplifier.n.01', 'synonyms': ['amplifier'], 'id': 9, 'def': 'electronic equipment that increases strength of signals', 'name': 'amplifier'}, {'frequency': 'c', 'synset': 'anklet.n.03', 'synonyms': ['anklet', 'ankle_bracelet'], 'id': 10, 'def': 'an ornament worn around the ankle', 'name': 'anklet'}, {'frequency': 'f', 'synset': 'antenna.n.01', 'synonyms': ['antenna', 'aerial', 'transmitting_aerial'], 'id': 11, 'def': 'an electrical device that sends or receives radio or television signals', 'name': 'antenna'}, {'frequency': 'f', 'synset': 'apple.n.01', 'synonyms': ['apple'], 'id': 12, 'def': 'fruit with red or yellow or green skin and sweet to tart crisp whitish flesh', 'name': 'apple'}, {'frequency': 'r', 'synset': 'applesauce.n.01', 'synonyms': ['applesauce'], 'id': 13, 'def': 'puree of stewed apples usually sweetened and spiced', 'name': 'applesauce'}, {'frequency': 'r', 'synset': 'apricot.n.02', 'synonyms': ['apricot'], 'id': 14, 'def': 'downy yellow to rosy-colored fruit resembling a small peach', 'name': 'apricot'}, {'frequency': 'f', 'synset': 'apron.n.01', 'synonyms': ['apron'], 'id': 15, 'def': 'a garment of cloth that is tied about the waist and worn to protect clothing', 'name': 'apron'}, {'frequency': 'c', 'synset': 'aquarium.n.01', 'synonyms': ['aquarium', 'fish_tank'], 'id': 16, 'def': 'a tank/pool/bowl filled with water for keeping live fish and underwater animals', 'name': 'aquarium'}, {'frequency': 'r', 'synset': 'arctic.n.02', 'synonyms': ['arctic_(type_of_shoe)', 'galosh', 'golosh', 'rubber_(type_of_shoe)', 'gumshoe'], 'id': 17, 'def': 'a waterproof overshoe that protects shoes from water or snow', 'name': 'arctic_(type_of_shoe)'}, {'frequency': 'c', 'synset': 'armband.n.02', 'synonyms': ['armband'], 'id': 18, 'def': 'a band worn around the upper arm', 'name': 'armband'}, {'frequency': 'f', 'synset': 'armchair.n.01', 'synonyms': ['armchair'], 'id': 19, 'def': 'chair with a support on each side for arms', 'name': 'armchair'}, {'frequency': 'r', 'synset': 'armoire.n.01', 'synonyms': ['armoire'], 'id': 20, 'def': 'a large wardrobe or cabinet', 'name': 'armoire'}, {'frequency': 'r', 'synset': 'armor.n.01', 'synonyms': ['armor', 'armour'], 'id': 21, 'def': 'protective covering made of metal and used in combat', 'name': 'armor'}, {'frequency': 'c', 'synset': 'artichoke.n.02', 'synonyms': ['artichoke'], 'id': 22, 'def': 'a thistlelike flower head with edible fleshy leaves and heart', 'name': 'artichoke'}, {'frequency': 'f', 'synset': 'ashcan.n.01', 'synonyms': ['trash_can', 'garbage_can', 'wastebin', 'dustbin', 'trash_barrel', 'trash_bin'], 'id': 23, 'def': 'a bin that holds rubbish until it is collected', 'name': 'trash_can'}, {'frequency': 'c', 'synset': 'ashtray.n.01', 'synonyms': ['ashtray'], 'id': 24, 'def': "a receptacle for the ash from smokers' cigars or cigarettes", 'name': 'ashtray'}, {'frequency': 'c', 'synset': 'asparagus.n.02', 'synonyms': ['asparagus'], 'id': 25, 'def': 'edible young shoots of the asparagus plant', 'name': 'asparagus'}, {'frequency': 'c', 'synset': 'atomizer.n.01', 'synonyms': ['atomizer', 'atomiser', 'spray', 'sprayer', 'nebulizer', 'nebuliser'], 'id': 26, 'def': 'a dispenser that turns a liquid (such as perfume) into a fine mist', 'name': 'atomizer'}, {'frequency': 'f', 'synset': 'avocado.n.01', 'synonyms': ['avocado'], 'id': 27, 'def': 'a pear-shaped fruit with green or blackish skin and rich yellowish pulp enclosing a single large seed', 'name': 'avocado'}, {'frequency': 'c', 'synset': 'award.n.02', 'synonyms': ['award', 'accolade'], 'id': 28, 'def': 'a tangible symbol signifying approval or distinction', 'name': 'award'}, {'frequency': 'f', 'synset': 'awning.n.01', 'synonyms': ['awning'], 'id': 29, 'def': 'a canopy made of canvas to shelter people or things from rain or sun', 'name': 'awning'}, {'frequency': 'r', 'synset': 'ax.n.01', 'synonyms': ['ax', 'axe'], 'id': 30, 'def': 'an edge tool with a heavy bladed head mounted across a handle', 'name': 'ax'}, {'frequency': 'r', 'synset': 'baboon.n.01', 'synonyms': ['baboon'], 'id': 31, 'def': 'large terrestrial monkeys having doglike muzzles', 'name': 'baboon'}, {'frequency': 'f', 'synset': 'baby_buggy.n.01', 'synonyms': ['baby_buggy', 'baby_carriage', 'perambulator', 'pram', 'stroller'], 'id': 32, 'def': 'a small vehicle with four wheels in which a baby or child is pushed around', 'name': 'baby_buggy'}, {'frequency': 'c', 'synset': 'backboard.n.01', 'synonyms': ['basketball_backboard'], 'id': 33, 'def': 'a raised vertical board with basket attached; used to play basketball', 'name': 'basketball_backboard'}, {'frequency': 'f', 'synset': 'backpack.n.01', 'synonyms': ['backpack', 'knapsack', 'packsack', 'rucksack', 'haversack'], 'id': 34, 'def': 'a bag carried by a strap on your back or shoulder', 'name': 'backpack'}, {'frequency': 'f', 'synset': 'bag.n.04', 'synonyms': ['handbag', 'purse', 'pocketbook'], 'id': 35, 'def': 'a container used for carrying money and small personal items or accessories', 'name': 'handbag'}, {'frequency': 'f', 'synset': 'bag.n.06', 'synonyms': ['suitcase', 'baggage', 'luggage'], 'id': 36, 'def': 'cases used to carry belongings when traveling', 'name': 'suitcase'}, {'frequency': 'c', 'synset': 'bagel.n.01', 'synonyms': ['bagel', 'beigel'], 'id': 37, 'def': 'glazed yeast-raised doughnut-shaped roll with hard crust', 'name': 'bagel'}, {'frequency': 'r', 'synset': 'bagpipe.n.01', 'synonyms': ['bagpipe'], 'id': 38, 'def': 'a tubular wind instrument; the player blows air into a bag and squeezes it out', 'name': 'bagpipe'}, {'frequency': 'r', 'synset': 'baguet.n.01', 'synonyms': ['baguet', 'baguette'], 'id': 39, 'def': 'narrow French stick loaf', 'name': 'baguet'}, {'frequency': 'r', 'synset': 'bait.n.02', 'synonyms': ['bait', 'lure'], 'id': 40, 'def': 'something used to lure fish or other animals into danger so they can be trapped or killed', 'name': 'bait'}, {'frequency': 'f', 'synset': 'ball.n.06', 'synonyms': ['ball'], 'id': 41, 'def': 'a spherical object used as a plaything', 'name': 'ball'}, {'frequency': 'r', 'synset': 'ballet_skirt.n.01', 'synonyms': ['ballet_skirt', 'tutu'], 'id': 42, 'def': 'very short skirt worn by ballerinas', 'name': 'ballet_skirt'}, {'frequency': 'f', 'synset': 'balloon.n.01', 'synonyms': ['balloon'], 'id': 43, 'def': 'large tough nonrigid bag filled with gas or heated air', 'name': 'balloon'}, {'frequency': 'c', 'synset': 'bamboo.n.02', 'synonyms': ['bamboo'], 'id': 44, 'def': 'woody tropical grass having hollow woody stems', 'name': 'bamboo'}, {'frequency': 'f', 'synset': 'banana.n.02', 'synonyms': ['banana'], 'id': 45, 'def': 'elongated crescent-shaped yellow fruit with soft sweet flesh', 'name': 'banana'}, {'frequency': 'c', 'synset': 'band_aid.n.01', 'synonyms': ['Band_Aid'], 'id': 46, 'def': 'trade name for an adhesive bandage to cover small cuts or blisters', 'name': 'Band_Aid'}, {'frequency': 'c', 'synset': 'bandage.n.01', 'synonyms': ['bandage'], 'id': 47, 'def': 'a piece of soft material that covers and protects an injured part of the body', 'name': 'bandage'}, {'frequency': 'f', 'synset': 'bandanna.n.01', 'synonyms': ['bandanna', 'bandana'], 'id': 48, 'def': 'large and brightly colored handkerchief; often used as a neckerchief', 'name': 'bandanna'}, {'frequency': 'r', 'synset': 'banjo.n.01', 'synonyms': ['banjo'], 'id': 49, 'def': 'a stringed instrument of the guitar family with a long neck and circular body', 'name': 'banjo'}, {'frequency': 'f', 'synset': 'banner.n.01', 'synonyms': ['banner', 'streamer'], 'id': 50, 'def': 'long strip of cloth or paper used for decoration or advertising', 'name': 'banner'}, {'frequency': 'r', 'synset': 'barbell.n.01', 'synonyms': ['barbell'], 'id': 51, 'def': 'a bar to which heavy discs are attached at each end; used in weightlifting', 'name': 'barbell'}, {'frequency': 'r', 'synset': 'barge.n.01', 'synonyms': ['barge'], 'id': 52, 'def': 'a flatbottom boat for carrying heavy loads (especially on canals)', 'name': 'barge'}, {'frequency': 'f', 'synset': 'barrel.n.02', 'synonyms': ['barrel', 'cask'], 'id': 53, 'def': 'a cylindrical container that holds liquids', 'name': 'barrel'}, {'frequency': 'c', 'synset': 'barrette.n.01', 'synonyms': ['barrette'], 'id': 54, 'def': "a pin for holding women's hair in place", 'name': 'barrette'}, {'frequency': 'c', 'synset': 'barrow.n.03', 'synonyms': ['barrow', 'garden_cart', 'lawn_cart', 'wheelbarrow'], 'id': 55, 'def': 'a cart for carrying small loads; has handles and one or more wheels', 'name': 'barrow'}, {'frequency': 'f', 'synset': 'base.n.03', 'synonyms': ['baseball_base'], 'id': 56, 'def': 'a place that the runner must touch before scoring', 'name': 'baseball_base'}, {'frequency': 'f', 'synset': 'baseball.n.02', 'synonyms': ['baseball'], 'id': 57, 'def': 'a ball used in playing baseball', 'name': 'baseball'}, {'frequency': 'f', 'synset': 'baseball_bat.n.01', 'synonyms': ['baseball_bat'], 'id': 58, 'def': 'an implement used in baseball by the batter', 'name': 'baseball_bat'}, {'frequency': 'f', 'synset': 'baseball_cap.n.01', 'synonyms': ['baseball_cap', 'jockey_cap', 'golf_cap'], 'id': 59, 'def': 'a cap with a bill', 'name': 'baseball_cap'}, {'frequency': 'f', 'synset': 'baseball_glove.n.01', 'synonyms': ['baseball_glove', 'baseball_mitt'], 'id': 60, 'def': 'the handwear used by fielders in playing baseball', 'name': 'baseball_glove'}, {'frequency': 'f', 'synset': 'basket.n.01', 'synonyms': ['basket', 'handbasket'], 'id': 61, 'def': 'a container that is usually woven and has handles', 'name': 'basket'}, {'frequency': 'c', 'synset': 'basketball.n.02', 'synonyms': ['basketball'], 'id': 62, 'def': 'an inflated ball used in playing basketball', 'name': 'basketball'}, {'frequency': 'r', 'synset': 'bass_horn.n.01', 'synonyms': ['bass_horn', 'sousaphone', 'tuba'], 'id': 63, 'def': 'the lowest brass wind instrument', 'name': 'bass_horn'}, {'frequency': 'c', 'synset': 'bat.n.01', 'synonyms': ['bat_(animal)'], 'id': 64, 'def': 'nocturnal mouselike mammal with forelimbs modified to form membranous wings', 'name': 'bat_(animal)'}, {'frequency': 'f', 'synset': 'bath_mat.n.01', 'synonyms': ['bath_mat'], 'id': 65, 'def': 'a heavy towel or mat to stand on while drying yourself after a bath', 'name': 'bath_mat'}, {'frequency': 'f', 'synset': 'bath_towel.n.01', 'synonyms': ['bath_towel'], 'id': 66, 'def': 'a large towel; to dry yourself after a bath', 'name': 'bath_towel'}, {'frequency': 'c', 'synset': 'bathrobe.n.01', 'synonyms': ['bathrobe'], 'id': 67, 'def': 'a loose-fitting robe of towelling; worn after a bath or swim', 'name': 'bathrobe'}, {'frequency': 'f', 'synset': 'bathtub.n.01', 'synonyms': ['bathtub', 'bathing_tub'], 'id': 68, 'def': 'a large open container that you fill with water and use to wash the body', 'name': 'bathtub'}, {'frequency': 'r', 'synset': 'batter.n.02', 'synonyms': ['batter_(food)'], 'id': 69, 'def': 'a liquid or semiliquid mixture, as of flour, eggs, and milk, used in cooking', 'name': 'batter_(food)'}, {'frequency': 'c', 'synset': 'battery.n.02', 'synonyms': ['battery'], 'id': 70, 'def': 'a portable device that produces electricity', 'name': 'battery'}, {'frequency': 'r', 'synset': 'beach_ball.n.01', 'synonyms': ['beachball'], 'id': 71, 'def': 'large and light ball; for play at the seaside', 'name': 'beachball'}, {'frequency': 'c', 'synset': 'bead.n.01', 'synonyms': ['bead'], 'id': 72, 'def': 'a small ball with a hole through the middle used for ornamentation, jewellery, etc.', 'name': 'bead'}, {'frequency': 'c', 'synset': 'bean_curd.n.01', 'synonyms': ['bean_curd', 'tofu'], 'id': 73, 'def': 'cheeselike food made of curdled soybean milk', 'name': 'bean_curd'}, {'frequency': 'c', 'synset': 'beanbag.n.01', 'synonyms': ['beanbag'], 'id': 74, 'def': 'a bag filled with dried beans or similar items; used in games or to sit on', 'name': 'beanbag'}, {'frequency': 'f', 'synset': 'beanie.n.01', 'synonyms': ['beanie', 'beany'], 'id': 75, 'def': 'a small skullcap; formerly worn by schoolboys and college freshmen', 'name': 'beanie'}, {'frequency': 'f', 'synset': 'bear.n.01', 'synonyms': ['bear'], 'id': 76, 'def': 'large carnivorous or omnivorous mammals with shaggy coats and claws', 'name': 'bear'}, {'frequency': 'f', 'synset': 'bed.n.01', 'synonyms': ['bed'], 'id': 77, 'def': 'a piece of furniture that provides a place to sleep', 'name': 'bed'}, {'frequency': 'r', 'synset': 'bedpan.n.01', 'synonyms': ['bedpan'], 'id': 78, 'def': 'a shallow vessel used by a bedridden patient for defecation and urination', 'name': 'bedpan'}, {'frequency': 'f', 'synset': 'bedspread.n.01', 'synonyms': ['bedspread', 'bedcover', 'bed_covering', 'counterpane', 'spread'], 'id': 79, 'def': 'decorative cover for a bed', 'name': 'bedspread'}, {'frequency': 'f', 'synset': 'beef.n.01', 'synonyms': ['cow'], 'id': 80, 'def': 'cattle/cow', 'name': 'cow'}, {'frequency': 'f', 'synset': 'beef.n.02', 'synonyms': ['beef_(food)', 'boeuf_(food)'], 'id': 81, 'def': 'meat from an adult domestic bovine', 'name': 'beef_(food)'}, {'frequency': 'r', 'synset': 'beeper.n.01', 'synonyms': ['beeper', 'pager'], 'id': 82, 'def': 'an device that beeps when the person carrying it is being paged', 'name': 'beeper'}, {'frequency': 'f', 'synset': 'beer_bottle.n.01', 'synonyms': ['beer_bottle'], 'id': 83, 'def': 'a bottle that holds beer', 'name': 'beer_bottle'}, {'frequency': 'c', 'synset': 'beer_can.n.01', 'synonyms': ['beer_can'], 'id': 84, 'def': 'a can that holds beer', 'name': 'beer_can'}, {'frequency': 'r', 'synset': 'beetle.n.01', 'synonyms': ['beetle'], 'id': 85, 'def': 'insect with hard wing covers', 'name': 'beetle'}, {'frequency': 'f', 'synset': 'bell.n.01', 'synonyms': ['bell'], 'id': 86, 'def': 'a hollow device made of metal that makes a ringing sound when struck', 'name': 'bell'}, {'frequency': 'f', 'synset': 'bell_pepper.n.02', 'synonyms': ['bell_pepper', 'capsicum'], 'id': 87, 'def': 'large bell-shaped sweet pepper in green or red or yellow or orange or black varieties', 'name': 'bell_pepper'}, {'frequency': 'f', 'synset': 'belt.n.02', 'synonyms': ['belt'], 'id': 88, 'def': 'a band to tie or buckle around the body (usually at the waist)', 'name': 'belt'}, {'frequency': 'f', 'synset': 'belt_buckle.n.01', 'synonyms': ['belt_buckle'], 'id': 89, 'def': 'the buckle used to fasten a belt', 'name': 'belt_buckle'}, {'frequency': 'f', 'synset': 'bench.n.01', 'synonyms': ['bench'], 'id': 90, 'def': 'a long seat for more than one person', 'name': 'bench'}, {'frequency': 'c', 'synset': 'beret.n.01', 'synonyms': ['beret'], 'id': 91, 'def': 'a cap with no brim or bill; made of soft cloth', 'name': 'beret'}, {'frequency': 'c', 'synset': 'bib.n.02', 'synonyms': ['bib'], 'id': 92, 'def': 'a napkin tied under the chin of a child while eating', 'name': 'bib'}, {'frequency': 'r', 'synset': 'bible.n.01', 'synonyms': ['Bible'], 'id': 93, 'def': 'the sacred writings of the Christian religions', 'name': 'Bible'}, {'frequency': 'f', 'synset': 'bicycle.n.01', 'synonyms': ['bicycle', 'bike_(bicycle)'], 'id': 94, 'def': 'a wheeled vehicle that has two wheels and is moved by foot pedals', 'name': 'bicycle'}, {'frequency': 'f', 'synset': 'bill.n.09', 'synonyms': ['visor', 'vizor'], 'id': 95, 'def': 'a brim that projects to the front to shade the eyes', 'name': 'visor'}, {'frequency': 'f', 'synset': 'billboard.n.01', 'synonyms': ['billboard'], 'id': 96, 'def': 'large outdoor signboard', 'name': 'billboard'}, {'frequency': 'c', 'synset': 'binder.n.03', 'synonyms': ['binder', 'ring-binder'], 'id': 97, 'def': 'holds loose papers or magazines', 'name': 'binder'}, {'frequency': 'c', 'synset': 'binoculars.n.01', 'synonyms': ['binoculars', 'field_glasses', 'opera_glasses'], 'id': 98, 'def': 'an optical instrument designed for simultaneous use by both eyes', 'name': 'binoculars'}, {'frequency': 'f', 'synset': 'bird.n.01', 'synonyms': ['bird'], 'id': 99, 'def': 'animal characterized by feathers and wings', 'name': 'bird'}, {'frequency': 'c', 'synset': 'bird_feeder.n.01', 'synonyms': ['birdfeeder'], 'id': 100, 'def': 'an outdoor device that supplies food for wild birds', 'name': 'birdfeeder'}, {'frequency': 'c', 'synset': 'birdbath.n.01', 'synonyms': ['birdbath'], 'id': 101, 'def': 'an ornamental basin (usually in a garden) for birds to bathe in', 'name': 'birdbath'}, {'frequency': 'c', 'synset': 'birdcage.n.01', 'synonyms': ['birdcage'], 'id': 102, 'def': 'a cage in which a bird can be kept', 'name': 'birdcage'}, {'frequency': 'c', 'synset': 'birdhouse.n.01', 'synonyms': ['birdhouse'], 'id': 103, 'def': 'a shelter for birds', 'name': 'birdhouse'}, {'frequency': 'f', 'synset': 'birthday_cake.n.01', 'synonyms': ['birthday_cake'], 'id': 104, 'def': 'decorated cake served at a birthday party', 'name': 'birthday_cake'}, {'frequency': 'r', 'synset': 'birthday_card.n.01', 'synonyms': ['birthday_card'], 'id': 105, 'def': 'a card expressing a birthday greeting', 'name': 'birthday_card'}, {'frequency': 'r', 'synset': 'black_flag.n.01', 'synonyms': ['pirate_flag'], 'id': 106, 'def': 'a flag usually bearing a white skull and crossbones on a black background', 'name': 'pirate_flag'}, {'frequency': 'c', 'synset': 'black_sheep.n.02', 'synonyms': ['black_sheep'], 'id': 107, 'def': 'sheep with a black coat', 'name': 'black_sheep'}, {'frequency': 'c', 'synset': 'blackberry.n.01', 'synonyms': ['blackberry'], 'id': 108, 'def': 'large sweet black or very dark purple edible aggregate fruit', 'name': 'blackberry'}, {'frequency': 'f', 'synset': 'blackboard.n.01', 'synonyms': ['blackboard', 'chalkboard'], 'id': 109, 'def': 'sheet of slate; for writing with chalk', 'name': 'blackboard'}, {'frequency': 'f', 'synset': 'blanket.n.01', 'synonyms': ['blanket'], 'id': 110, 'def': 'bedding that keeps a person warm in bed', 'name': 'blanket'}, {'frequency': 'c', 'synset': 'blazer.n.01', 'synonyms': ['blazer', 'sport_jacket', 'sport_coat', 'sports_jacket', 'sports_coat'], 'id': 111, 'def': 'lightweight jacket; often striped in the colors of a club or school', 'name': 'blazer'}, {'frequency': 'f', 'synset': 'blender.n.01', 'synonyms': ['blender', 'liquidizer', 'liquidiser'], 'id': 112, 'def': 'an electrically powered mixer that mix or chop or liquefy foods', 'name': 'blender'}, {'frequency': 'r', 'synset': 'blimp.n.02', 'synonyms': ['blimp'], 'id': 113, 'def': 'a small nonrigid airship used for observation or as a barrage balloon', 'name': 'blimp'}, {'frequency': 'f', 'synset': 'blinker.n.01', 'synonyms': ['blinker', 'flasher'], 'id': 114, 'def': 'a light that flashes on and off; used as a signal or to send messages', 'name': 'blinker'}, {'frequency': 'f', 'synset': 'blouse.n.01', 'synonyms': ['blouse'], 'id': 115, 'def': 'a top worn by women', 'name': 'blouse'}, {'frequency': 'f', 'synset': 'blueberry.n.02', 'synonyms': ['blueberry'], 'id': 116, 'def': 'sweet edible dark-blue berries of blueberry plants', 'name': 'blueberry'}, {'frequency': 'r', 'synset': 'board.n.09', 'synonyms': ['gameboard'], 'id': 117, 'def': 'a flat portable surface (usually rectangular) designed for board games', 'name': 'gameboard'}, {'frequency': 'f', 'synset': 'boat.n.01', 'synonyms': ['boat', 'ship_(boat)'], 'id': 118, 'def': 'a vessel for travel on water', 'name': 'boat'}, {'frequency': 'r', 'synset': 'bob.n.05', 'synonyms': ['bob', 'bobber', 'bobfloat'], 'id': 119, 'def': 'a small float usually made of cork; attached to a fishing line', 'name': 'bob'}, {'frequency': 'c', 'synset': 'bobbin.n.01', 'synonyms': ['bobbin', 'spool', 'reel'], 'id': 120, 'def': 'a thing around which thread/tape/film or other flexible materials can be wound', 'name': 'bobbin'}, {'frequency': 'c', 'synset': 'bobby_pin.n.01', 'synonyms': ['bobby_pin', 'hairgrip'], 'id': 121, 'def': 'a flat wire hairpin used to hold bobbed hair in place', 'name': 'bobby_pin'}, {'frequency': 'c', 'synset': 'boiled_egg.n.01', 'synonyms': ['boiled_egg', 'coddled_egg'], 'id': 122, 'def': 'egg cooked briefly in the shell in gently boiling water', 'name': 'boiled_egg'}, {'frequency': 'r', 'synset': 'bolo_tie.n.01', 'synonyms': ['bolo_tie', 'bolo', 'bola_tie', 'bola'], 'id': 123, 'def': 'a cord fastened around the neck with an ornamental clasp and worn as a necktie', 'name': 'bolo_tie'}, {'frequency': 'c', 'synset': 'bolt.n.03', 'synonyms': ['deadbolt'], 'id': 124, 'def': 'the part of a lock that is engaged or withdrawn with a key', 'name': 'deadbolt'}, {'frequency': 'f', 'synset': 'bolt.n.06', 'synonyms': ['bolt'], 'id': 125, 'def': 'a screw that screws into a nut to form a fastener', 'name': 'bolt'}, {'frequency': 'r', 'synset': 'bonnet.n.01', 'synonyms': ['bonnet'], 'id': 126, 'def': 'a hat tied under the chin', 'name': 'bonnet'}, {'frequency': 'f', 'synset': 'book.n.01', 'synonyms': ['book'], 'id': 127, 'def': 'a written work or composition that has been published', 'name': 'book'}, {'frequency': 'c', 'synset': 'bookcase.n.01', 'synonyms': ['bookcase'], 'id': 128, 'def': 'a piece of furniture with shelves for storing books', 'name': 'bookcase'}, {'frequency': 'c', 'synset': 'booklet.n.01', 'synonyms': ['booklet', 'brochure', 'leaflet', 'pamphlet'], 'id': 129, 'def': 'a small book usually having a paper cover', 'name': 'booklet'}, {'frequency': 'r', 'synset': 'bookmark.n.01', 'synonyms': ['bookmark', 'bookmarker'], 'id': 130, 'def': 'a marker (a piece of paper or ribbon) placed between the pages of a book', 'name': 'bookmark'}, {'frequency': 'r', 'synset': 'boom.n.04', 'synonyms': ['boom_microphone', 'microphone_boom'], 'id': 131, 'def': 'a pole carrying an overhead microphone projected over a film or tv set', 'name': 'boom_microphone'}, {'frequency': 'f', 'synset': 'boot.n.01', 'synonyms': ['boot'], 'id': 132, 'def': 'footwear that covers the whole foot and lower leg', 'name': 'boot'}, {'frequency': 'f', 'synset': 'bottle.n.01', 'synonyms': ['bottle'], 'id': 133, 'def': 'a glass or plastic vessel used for storing drinks or other liquids', 'name': 'bottle'}, {'frequency': 'c', 'synset': 'bottle_opener.n.01', 'synonyms': ['bottle_opener'], 'id': 134, 'def': 'an opener for removing caps or corks from bottles', 'name': 'bottle_opener'}, {'frequency': 'c', 'synset': 'bouquet.n.01', 'synonyms': ['bouquet'], 'id': 135, 'def': 'an arrangement of flowers that is usually given as a present', 'name': 'bouquet'}, {'frequency': 'r', 'synset': 'bow.n.04', 'synonyms': ['bow_(weapon)'], 'id': 136, 'def': 'a weapon for shooting arrows', 'name': 'bow_(weapon)'}, {'frequency': 'f', 'synset': 'bow.n.08', 'synonyms': ['bow_(decorative_ribbons)'], 'id': 137, 'def': 'a decorative interlacing of ribbons', 'name': 'bow_(decorative_ribbons)'}, {'frequency': 'f', 'synset': 'bow_tie.n.01', 'synonyms': ['bow-tie', 'bowtie'], 'id': 138, 'def': "a man's tie that ties in a bow", 'name': 'bow-tie'}, {'frequency': 'f', 'synset': 'bowl.n.03', 'synonyms': ['bowl'], 'id': 139, 'def': 'a dish that is round and open at the top for serving foods', 'name': 'bowl'}, {'frequency': 'r', 'synset': 'bowl.n.08', 'synonyms': ['pipe_bowl'], 'id': 140, 'def': 'a small round container that is open at the top for holding tobacco', 'name': 'pipe_bowl'}, {'frequency': 'c', 'synset': 'bowler_hat.n.01', 'synonyms': ['bowler_hat', 'bowler', 'derby_hat', 'derby', 'plug_hat'], 'id': 141, 'def': 'a felt hat that is round and hard with a narrow brim', 'name': 'bowler_hat'}, {'frequency': 'r', 'synset': 'bowling_ball.n.01', 'synonyms': ['bowling_ball'], 'id': 142, 'def': 'a large ball with finger holes used in the sport of bowling', 'name': 'bowling_ball'}, {'frequency': 'f', 'synset': 'box.n.01', 'synonyms': ['box'], 'id': 143, 'def': 'a (usually rectangular) container; may have a lid', 'name': 'box'}, {'frequency': 'r', 'synset': 'boxing_glove.n.01', 'synonyms': ['boxing_glove'], 'id': 144, 'def': 'large glove coverings the fists of a fighter worn for the sport of boxing', 'name': 'boxing_glove'}, {'frequency': 'c', 'synset': 'brace.n.06', 'synonyms': ['suspenders'], 'id': 145, 'def': 'elastic straps that hold trousers up (usually used in the plural)', 'name': 'suspenders'}, {'frequency': 'f', 'synset': 'bracelet.n.02', 'synonyms': ['bracelet', 'bangle'], 'id': 146, 'def': 'jewelry worn around the wrist for decoration', 'name': 'bracelet'}, {'frequency': 'r', 'synset': 'brass.n.07', 'synonyms': ['brass_plaque'], 'id': 147, 'def': 'a memorial made of brass', 'name': 'brass_plaque'}, {'frequency': 'c', 'synset': 'brassiere.n.01', 'synonyms': ['brassiere', 'bra', 'bandeau'], 'id': 148, 'def': 'an undergarment worn by women to support their breasts', 'name': 'brassiere'}, {'frequency': 'c', 'synset': 'bread-bin.n.01', 'synonyms': ['bread-bin', 'breadbox'], 'id': 149, 'def': 'a container used to keep bread or cake in', 'name': 'bread-bin'}, {'frequency': 'f', 'synset': 'bread.n.01', 'synonyms': ['bread'], 'id': 150, 'def': 'food made from dough of flour or meal and usually raised with yeast or baking powder and then baked', 'name': 'bread'}, {'frequency': 'r', 'synset': 'breechcloth.n.01', 'synonyms': ['breechcloth', 'breechclout', 'loincloth'], 'id': 151, 'def': 'a garment that provides covering for the loins', 'name': 'breechcloth'}, {'frequency': 'f', 'synset': 'bridal_gown.n.01', 'synonyms': ['bridal_gown', 'wedding_gown', 'wedding_dress'], 'id': 152, 'def': 'a gown worn by the bride at a wedding', 'name': 'bridal_gown'}, {'frequency': 'c', 'synset': 'briefcase.n.01', 'synonyms': ['briefcase'], 'id': 153, 'def': 'a case with a handle; for carrying papers or files or books', 'name': 'briefcase'}, {'frequency': 'f', 'synset': 'broccoli.n.01', 'synonyms': ['broccoli'], 'id': 154, 'def': 'plant with dense clusters of tight green flower buds', 'name': 'broccoli'}, {'frequency': 'r', 'synset': 'brooch.n.01', 'synonyms': ['broach'], 'id': 155, 'def': 'a decorative pin worn by women', 'name': 'broach'}, {'frequency': 'c', 'synset': 'broom.n.01', 'synonyms': ['broom'], 'id': 156, 'def': 'bundle of straws or twigs attached to a long handle; used for cleaning', 'name': 'broom'}, {'frequency': 'c', 'synset': 'brownie.n.03', 'synonyms': ['brownie'], 'id': 157, 'def': 'square or bar of very rich chocolate cake usually with nuts', 'name': 'brownie'}, {'frequency': 'c', 'synset': 'brussels_sprouts.n.01', 'synonyms': ['brussels_sprouts'], 'id': 158, 'def': 'the small edible cabbage-like buds growing along a stalk', 'name': 'brussels_sprouts'}, {'frequency': 'r', 'synset': 'bubble_gum.n.01', 'synonyms': ['bubble_gum'], 'id': 159, 'def': 'a kind of chewing gum that can be blown into bubbles', 'name': 'bubble_gum'}, {'frequency': 'f', 'synset': 'bucket.n.01', 'synonyms': ['bucket', 'pail'], 'id': 160, 'def': 'a roughly cylindrical vessel that is open at the top', 'name': 'bucket'}, {'frequency': 'r', 'synset': 'buggy.n.01', 'synonyms': ['horse_buggy'], 'id': 161, 'def': 'a small lightweight carriage; drawn by a single horse', 'name': 'horse_buggy'}, {'frequency': 'c', 'synset': 'bull.n.11', 'synonyms': ['horned_cow'], 'id': 162, 'def': 'a cow with horns', 'name': 'bull'}, {'frequency': 'c', 'synset': 'bulldog.n.01', 'synonyms': ['bulldog'], 'id': 163, 'def': 'a thickset short-haired dog with a large head and strong undershot lower jaw', 'name': 'bulldog'}, {'frequency': 'r', 'synset': 'bulldozer.n.01', 'synonyms': ['bulldozer', 'dozer'], 'id': 164, 'def': 'large powerful tractor; a large blade in front flattens areas of ground', 'name': 'bulldozer'}, {'frequency': 'c', 'synset': 'bullet_train.n.01', 'synonyms': ['bullet_train'], 'id': 165, 'def': 'a high-speed passenger train', 'name': 'bullet_train'}, {'frequency': 'c', 'synset': 'bulletin_board.n.02', 'synonyms': ['bulletin_board', 'notice_board'], 'id': 166, 'def': 'a board that hangs on a wall; displays announcements', 'name': 'bulletin_board'}, {'frequency': 'r', 'synset': 'bulletproof_vest.n.01', 'synonyms': ['bulletproof_vest'], 'id': 167, 'def': 'a vest capable of resisting the impact of a bullet', 'name': 'bulletproof_vest'}, {'frequency': 'c', 'synset': 'bullhorn.n.01', 'synonyms': ['bullhorn', 'megaphone'], 'id': 168, 'def': 'a portable loudspeaker with built-in microphone and amplifier', 'name': 'bullhorn'}, {'frequency': 'f', 'synset': 'bun.n.01', 'synonyms': ['bun', 'roll'], 'id': 169, 'def': 'small rounded bread either plain or sweet', 'name': 'bun'}, {'frequency': 'c', 'synset': 'bunk_bed.n.01', 'synonyms': ['bunk_bed'], 'id': 170, 'def': 'beds built one above the other', 'name': 'bunk_bed'}, {'frequency': 'f', 'synset': 'buoy.n.01', 'synonyms': ['buoy'], 'id': 171, 'def': 'a float attached by rope to the seabed to mark channels in a harbor or underwater hazards', 'name': 'buoy'}, {'frequency': 'r', 'synset': 'burrito.n.01', 'synonyms': ['burrito'], 'id': 172, 'def': 'a flour tortilla folded around a filling', 'name': 'burrito'}, {'frequency': 'f', 'synset': 'bus.n.01', 'synonyms': ['bus_(vehicle)', 'autobus', 'charabanc', 'double-decker', 'motorbus', 'motorcoach'], 'id': 173, 'def': 'a vehicle carrying many passengers; used for public transport', 'name': 'bus_(vehicle)'}, {'frequency': 'c', 'synset': 'business_card.n.01', 'synonyms': ['business_card'], 'id': 174, 'def': "a card on which are printed the person's name and business affiliation", 'name': 'business_card'}, {'frequency': 'f', 'synset': 'butter.n.01', 'synonyms': ['butter'], 'id': 175, 'def': 'an edible emulsion of fat globules made by churning milk or cream; for cooking and table use', 'name': 'butter'}, {'frequency': 'c', 'synset': 'butterfly.n.01', 'synonyms': ['butterfly'], 'id': 176, 'def': 'insect typically having a slender body with knobbed antennae and broad colorful wings', 'name': 'butterfly'}, {'frequency': 'f', 'synset': 'button.n.01', 'synonyms': ['button'], 'id': 177, 'def': 'a round fastener sewn to shirts and coats etc to fit through buttonholes', 'name': 'button'}, {'frequency': 'f', 'synset': 'cab.n.03', 'synonyms': ['cab_(taxi)', 'taxi', 'taxicab'], 'id': 178, 'def': 'a car that takes passengers where they want to go in exchange for money', 'name': 'cab_(taxi)'}, {'frequency': 'r', 'synset': 'cabana.n.01', 'synonyms': ['cabana'], 'id': 179, 'def': 'a small tent used as a dressing room beside the sea or a swimming pool', 'name': 'cabana'}, {'frequency': 'c', 'synset': 'cabin_car.n.01', 'synonyms': ['cabin_car', 'caboose'], 'id': 180, 'def': 'a car on a freight train for use of the train crew; usually the last car on the train', 'name': 'cabin_car'}, {'frequency': 'f', 'synset': 'cabinet.n.01', 'synonyms': ['cabinet'], 'id': 181, 'def': 'a piece of furniture resembling a cupboard with doors and shelves and drawers', 'name': 'cabinet'}, {'frequency': 'r', 'synset': 'cabinet.n.03', 'synonyms': ['locker', 'storage_locker'], 'id': 182, 'def': 'a storage compartment for clothes and valuables; usually it has a lock', 'name': 'locker'}, {'frequency': 'f', 'synset': 'cake.n.03', 'synonyms': ['cake'], 'id': 183, 'def': 'baked goods made from or based on a mixture of flour, sugar, eggs, and fat', 'name': 'cake'}, {'frequency': 'c', 'synset': 'calculator.n.02', 'synonyms': ['calculator'], 'id': 184, 'def': 'a small machine that is used for mathematical calculations', 'name': 'calculator'}, {'frequency': 'f', 'synset': 'calendar.n.02', 'synonyms': ['calendar'], 'id': 185, 'def': 'a list or register of events (appointments/social events/court cases, etc)', 'name': 'calendar'}, {'frequency': 'c', 'synset': 'calf.n.01', 'synonyms': ['calf'], 'id': 186, 'def': 'young of domestic cattle', 'name': 'calf'}, {'frequency': 'c', 'synset': 'camcorder.n.01', 'synonyms': ['camcorder'], 'id': 187, 'def': 'a portable television camera and videocassette recorder', 'name': 'camcorder'}, {'frequency': 'c', 'synset': 'camel.n.01', 'synonyms': ['camel'], 'id': 188, 'def': 'cud-chewing mammal used as a draft or saddle animal in desert regions', 'name': 'camel'}, {'frequency': 'f', 'synset': 'camera.n.01', 'synonyms': ['camera'], 'id': 189, 'def': 'equipment for taking photographs', 'name': 'camera'}, {'frequency': 'c', 'synset': 'camera_lens.n.01', 'synonyms': ['camera_lens'], 'id': 190, 'def': 'a lens that focuses the image in a camera', 'name': 'camera_lens'}, {'frequency': 'c', 'synset': 'camper.n.02', 'synonyms': ['camper_(vehicle)', 'camping_bus', 'motor_home'], 'id': 191, 'def': 'a recreational vehicle equipped for camping out while traveling', 'name': 'camper_(vehicle)'}, {'frequency': 'f', 'synset': 'can.n.01', 'synonyms': ['can', 'tin_can'], 'id': 192, 'def': 'airtight sealed metal container for food or drink or paint etc.', 'name': 'can'}, {'frequency': 'c', 'synset': 'can_opener.n.01', 'synonyms': ['can_opener', 'tin_opener'], 'id': 193, 'def': 'a device for cutting cans open', 'name': 'can_opener'}, {'frequency': 'f', 'synset': 'candle.n.01', 'synonyms': ['candle', 'candlestick'], 'id': 194, 'def': 'stick of wax with a wick in the middle', 'name': 'candle'}, {'frequency': 'f', 'synset': 'candlestick.n.01', 'synonyms': ['candle_holder'], 'id': 195, 'def': 'a holder with sockets for candles', 'name': 'candle_holder'}, {'frequency': 'r', 'synset': 'candy_bar.n.01', 'synonyms': ['candy_bar'], 'id': 196, 'def': 'a candy shaped as a bar', 'name': 'candy_bar'}, {'frequency': 'c', 'synset': 'candy_cane.n.01', 'synonyms': ['candy_cane'], 'id': 197, 'def': 'a hard candy in the shape of a rod (usually with stripes)', 'name': 'candy_cane'}, {'frequency': 'c', 'synset': 'cane.n.01', 'synonyms': ['walking_cane'], 'id': 198, 'def': 'a stick that people can lean on to help them walk', 'name': 'walking_cane'}, {'frequency': 'c', 'synset': 'canister.n.02', 'synonyms': ['canister', 'cannister'], 'id': 199, 'def': 'metal container for storing dry foods such as tea or flour', 'name': 'canister'}, {'frequency': 'c', 'synset': 'canoe.n.01', 'synonyms': ['canoe'], 'id': 200, 'def': 'small and light boat; pointed at both ends; propelled with a paddle', 'name': 'canoe'}, {'frequency': 'c', 'synset': 'cantaloup.n.02', 'synonyms': ['cantaloup', 'cantaloupe'], 'id': 201, 'def': 'the fruit of a cantaloup vine; small to medium-sized melon with yellowish flesh', 'name': 'cantaloup'}, {'frequency': 'r', 'synset': 'canteen.n.01', 'synonyms': ['canteen'], 'id': 202, 'def': 'a flask for carrying water; used by soldiers or travelers', 'name': 'canteen'}, {'frequency': 'f', 'synset': 'cap.n.01', 'synonyms': ['cap_(headwear)'], 'id': 203, 'def': 'a tight-fitting headwear', 'name': 'cap_(headwear)'}, {'frequency': 'f', 'synset': 'cap.n.02', 'synonyms': ['bottle_cap', 'cap_(container_lid)'], 'id': 204, 'def': 'a top (as for a bottle)', 'name': 'bottle_cap'}, {'frequency': 'c', 'synset': 'cape.n.02', 'synonyms': ['cape'], 'id': 205, 'def': 'a sleeveless garment like a cloak but shorter', 'name': 'cape'}, {'frequency': 'c', 'synset': 'cappuccino.n.01', 'synonyms': ['cappuccino', 'coffee_cappuccino'], 'id': 206, 'def': 'equal parts of espresso and steamed milk', 'name': 'cappuccino'}, {'frequency': 'f', 'synset': 'car.n.01', 'synonyms': ['car_(automobile)', 'auto_(automobile)', 'automobile'], 'id': 207, 'def': 'a motor vehicle with four wheels', 'name': 'car_(automobile)'}, {'frequency': 'f', 'synset': 'car.n.02', 'synonyms': ['railcar_(part_of_a_train)', 'railway_car_(part_of_a_train)', 'railroad_car_(part_of_a_train)'], 'id': 208, 'def': 'a wheeled vehicle adapted to the rails of railroad (mark each individual railcar separately)', 'name': 'railcar_(part_of_a_train)'}, {'frequency': 'r', 'synset': 'car.n.04', 'synonyms': ['elevator_car'], 'id': 209, 'def': 'where passengers ride up and down', 'name': 'elevator_car'}, {'frequency': 'r', 'synset': 'car_battery.n.01', 'synonyms': ['car_battery', 'automobile_battery'], 'id': 210, 'def': 'a battery in a motor vehicle', 'name': 'car_battery'}, {'frequency': 'c', 'synset': 'card.n.02', 'synonyms': ['identity_card'], 'id': 211, 'def': 'a card certifying the identity of the bearer', 'name': 'identity_card'}, {'frequency': 'c', 'synset': 'card.n.03', 'synonyms': ['card'], 'id': 212, 'def': 'a rectangular piece of paper used to send messages (e.g. greetings or pictures)', 'name': 'card'}, {'frequency': 'c', 'synset': 'cardigan.n.01', 'synonyms': ['cardigan'], 'id': 213, 'def': 'knitted jacket that is fastened up the front with buttons or a zipper', 'name': 'cardigan'}, {'frequency': 'r', 'synset': 'cargo_ship.n.01', 'synonyms': ['cargo_ship', 'cargo_vessel'], 'id': 214, 'def': 'a ship designed to carry cargo', 'name': 'cargo_ship'}, {'frequency': 'r', 'synset': 'carnation.n.01', 'synonyms': ['carnation'], 'id': 215, 'def': 'plant with pink to purple-red spice-scented usually double flowers', 'name': 'carnation'}, {'frequency': 'c', 'synset': 'carriage.n.02', 'synonyms': ['horse_carriage'], 'id': 216, 'def': 'a vehicle with wheels drawn by one or more horses', 'name': 'horse_carriage'}, {'frequency': 'f', 'synset': 'carrot.n.01', 'synonyms': ['carrot'], 'id': 217, 'def': 'deep orange edible root of the cultivated carrot plant', 'name': 'carrot'}, {'frequency': 'f', 'synset': 'carryall.n.01', 'synonyms': ['tote_bag'], 'id': 218, 'def': 'a capacious bag or basket', 'name': 'tote_bag'}, {'frequency': 'c', 'synset': 'cart.n.01', 'synonyms': ['cart'], 'id': 219, 'def': 'a heavy open wagon usually having two wheels and drawn by an animal', 'name': 'cart'}, {'frequency': 'c', 'synset': 'carton.n.02', 'synonyms': ['carton'], 'id': 220, 'def': 'a container made of cardboard for holding food or drink', 'name': 'carton'}, {'frequency': 'c', 'synset': 'cash_register.n.01', 'synonyms': ['cash_register', 'register_(for_cash_transactions)'], 'id': 221, 'def': 'a cashbox with an adding machine to register transactions', 'name': 'cash_register'}, {'frequency': 'r', 'synset': 'casserole.n.01', 'synonyms': ['casserole'], 'id': 222, 'def': 'food cooked and served in a casserole', 'name': 'casserole'}, {'frequency': 'r', 'synset': 'cassette.n.01', 'synonyms': ['cassette'], 'id': 223, 'def': 'a container that holds a magnetic tape used for recording or playing sound or video', 'name': 'cassette'}, {'frequency': 'c', 'synset': 'cast.n.05', 'synonyms': ['cast', 'plaster_cast', 'plaster_bandage'], 'id': 224, 'def': 'bandage consisting of a firm covering that immobilizes broken bones while they heal', 'name': 'cast'}, {'frequency': 'f', 'synset': 'cat.n.01', 'synonyms': ['cat'], 'id': 225, 'def': 'a domestic house cat', 'name': 'cat'}, {'frequency': 'f', 'synset': 'cauliflower.n.02', 'synonyms': ['cauliflower'], 'id': 226, 'def': 'edible compact head of white undeveloped flowers', 'name': 'cauliflower'}, {'frequency': 'c', 'synset': 'cayenne.n.02', 'synonyms': ['cayenne_(spice)', 'cayenne_pepper_(spice)', 'red_pepper_(spice)'], 'id': 227, 'def': 'ground pods and seeds of pungent red peppers of the genus Capsicum', 'name': 'cayenne_(spice)'}, {'frequency': 'c', 'synset': 'cd_player.n.01', 'synonyms': ['CD_player'], 'id': 228, 'def': 'electronic equipment for playing compact discs (CDs)', 'name': 'CD_player'}, {'frequency': 'f', 'synset': 'celery.n.01', 'synonyms': ['celery'], 'id': 229, 'def': 'widely cultivated herb with aromatic leaf stalks that are eaten raw or cooked', 'name': 'celery'}, {'frequency': 'f', 'synset': 'cellular_telephone.n.01', 'synonyms': ['cellular_telephone', 'cellular_phone', 'cellphone', 'mobile_phone', 'smart_phone'], 'id': 230, 'def': 'a hand-held mobile telephone', 'name': 'cellular_telephone'}, {'frequency': 'r', 'synset': 'chain_mail.n.01', 'synonyms': ['chain_mail', 'ring_mail', 'chain_armor', 'chain_armour', 'ring_armor', 'ring_armour'], 'id': 231, 'def': '(Middle Ages) flexible armor made of interlinked metal rings', 'name': 'chain_mail'}, {'frequency': 'f', 'synset': 'chair.n.01', 'synonyms': ['chair'], 'id': 232, 'def': 'a seat for one person, with a support for the back', 'name': 'chair'}, {'frequency': 'r', 'synset': 'chaise_longue.n.01', 'synonyms': ['chaise_longue', 'chaise', 'daybed'], 'id': 233, 'def': 'a long chair; for reclining', 'name': 'chaise_longue'}, {'frequency': 'r', 'synset': 'chalice.n.01', 'synonyms': ['chalice'], 'id': 234, 'def': 'a bowl-shaped drinking vessel; especially the Eucharistic cup', 'name': 'chalice'}, {'frequency': 'f', 'synset': 'chandelier.n.01', 'synonyms': ['chandelier'], 'id': 235, 'def': 'branched lighting fixture; often ornate; hangs from the ceiling', 'name': 'chandelier'}, {'frequency': 'r', 'synset': 'chap.n.04', 'synonyms': ['chap'], 'id': 236, 'def': 'leather leggings without a seat; worn over trousers by cowboys to protect their legs', 'name': 'chap'}, {'frequency': 'r', 'synset': 'checkbook.n.01', 'synonyms': ['checkbook', 'chequebook'], 'id': 237, 'def': 'a book issued to holders of checking accounts', 'name': 'checkbook'}, {'frequency': 'r', 'synset': 'checkerboard.n.01', 'synonyms': ['checkerboard'], 'id': 238, 'def': 'a board having 64 squares of two alternating colors', 'name': 'checkerboard'}, {'frequency': 'c', 'synset': 'cherry.n.03', 'synonyms': ['cherry'], 'id': 239, 'def': 'a red fruit with a single hard stone', 'name': 'cherry'}, {'frequency': 'r', 'synset': 'chessboard.n.01', 'synonyms': ['chessboard'], 'id': 240, 'def': 'a checkerboard used to play chess', 'name': 'chessboard'}, {'frequency': 'c', 'synset': 'chicken.n.02', 'synonyms': ['chicken_(animal)'], 'id': 241, 'def': 'a domestic fowl bred for flesh or eggs', 'name': 'chicken_(animal)'}, {'frequency': 'c', 'synset': 'chickpea.n.01', 'synonyms': ['chickpea', 'garbanzo'], 'id': 242, 'def': 'the seed of the chickpea plant; usually dried', 'name': 'chickpea'}, {'frequency': 'c', 'synset': 'chili.n.02', 'synonyms': ['chili_(vegetable)', 'chili_pepper_(vegetable)', 'chilli_(vegetable)', 'chilly_(vegetable)', 'chile_(vegetable)'], 'id': 243, 'def': 'very hot and finely tapering pepper of special pungency', 'name': 'chili_(vegetable)'}, {'frequency': 'r', 'synset': 'chime.n.01', 'synonyms': ['chime', 'gong'], 'id': 244, 'def': 'an instrument consisting of a set of bells that are struck with a hammer', 'name': 'chime'}, {'frequency': 'r', 'synset': 'chinaware.n.01', 'synonyms': ['chinaware'], 'id': 245, 'def': 'dishware made of high quality porcelain', 'name': 'chinaware'}, {'frequency': 'c', 'synset': 'chip.n.04', 'synonyms': ['crisp_(potato_chip)', 'potato_chip'], 'id': 246, 'def': 'a thin crisp slice of potato fried in deep fat', 'name': 'crisp_(potato_chip)'}, {'frequency': 'r', 'synset': 'chip.n.06', 'synonyms': ['poker_chip'], 'id': 247, 'def': 'a small disk-shaped counter used to represent money when gambling', 'name': 'poker_chip'}, {'frequency': 'c', 'synset': 'chocolate_bar.n.01', 'synonyms': ['chocolate_bar'], 'id': 248, 'def': 'a bar of chocolate candy', 'name': 'chocolate_bar'}, {'frequency': 'c', 'synset': 'chocolate_cake.n.01', 'synonyms': ['chocolate_cake'], 'id': 249, 'def': 'cake containing chocolate', 'name': 'chocolate_cake'}, {'frequency': 'r', 'synset': 'chocolate_milk.n.01', 'synonyms': ['chocolate_milk'], 'id': 250, 'def': 'milk flavored with chocolate syrup', 'name': 'chocolate_milk'}, {'frequency': 'r', 'synset': 'chocolate_mousse.n.01', 'synonyms': ['chocolate_mousse'], 'id': 251, 'def': 'dessert mousse made with chocolate', 'name': 'chocolate_mousse'}, {'frequency': 'f', 'synset': 'choker.n.03', 'synonyms': ['choker', 'collar', 'neckband'], 'id': 252, 'def': 'shirt collar, animal collar, or tight-fitting necklace', 'name': 'choker'}, {'frequency': 'f', 'synset': 'chopping_board.n.01', 'synonyms': ['chopping_board', 'cutting_board', 'chopping_block'], 'id': 253, 'def': 'a wooden board where meats or vegetables can be cut', 'name': 'chopping_board'}, {'frequency': 'f', 'synset': 'chopstick.n.01', 'synonyms': ['chopstick'], 'id': 254, 'def': 'one of a pair of slender sticks used as oriental tableware to eat food with', 'name': 'chopstick'}, {'frequency': 'f', 'synset': 'christmas_tree.n.05', 'synonyms': ['Christmas_tree'], 'id': 255, 'def': 'an ornamented evergreen used as a Christmas decoration', 'name': 'Christmas_tree'}, {'frequency': 'c', 'synset': 'chute.n.02', 'synonyms': ['slide'], 'id': 256, 'def': 'sloping channel through which things can descend', 'name': 'slide'}, {'frequency': 'r', 'synset': 'cider.n.01', 'synonyms': ['cider', 'cyder'], 'id': 257, 'def': 'a beverage made from juice pressed from apples', 'name': 'cider'}, {'frequency': 'r', 'synset': 'cigar_box.n.01', 'synonyms': ['cigar_box'], 'id': 258, 'def': 'a box for holding cigars', 'name': 'cigar_box'}, {'frequency': 'f', 'synset': 'cigarette.n.01', 'synonyms': ['cigarette'], 'id': 259, 'def': 'finely ground tobacco wrapped in paper; for smoking', 'name': 'cigarette'}, {'frequency': 'c', 'synset': 'cigarette_case.n.01', 'synonyms': ['cigarette_case', 'cigarette_pack'], 'id': 260, 'def': 'a small flat case for holding cigarettes', 'name': 'cigarette_case'}, {'frequency': 'f', 'synset': 'cistern.n.02', 'synonyms': ['cistern', 'water_tank'], 'id': 261, 'def': 'a tank that holds the water used to flush a toilet', 'name': 'cistern'}, {'frequency': 'r', 'synset': 'clarinet.n.01', 'synonyms': ['clarinet'], 'id': 262, 'def': 'a single-reed instrument with a straight tube', 'name': 'clarinet'}, {'frequency': 'c', 'synset': 'clasp.n.01', 'synonyms': ['clasp'], 'id': 263, 'def': 'a fastener (as a buckle or hook) that is used to hold two things together', 'name': 'clasp'}, {'frequency': 'c', 'synset': 'cleansing_agent.n.01', 'synonyms': ['cleansing_agent', 'cleanser', 'cleaner'], 'id': 264, 'def': 'a preparation used in cleaning something', 'name': 'cleansing_agent'}, {'frequency': 'r', 'synset': 'cleat.n.02', 'synonyms': ['cleat_(for_securing_rope)'], 'id': 265, 'def': 'a fastener (usually with two projecting horns) around which a rope can be secured', 'name': 'cleat_(for_securing_rope)'}, {'frequency': 'r', 'synset': 'clementine.n.01', 'synonyms': ['clementine'], 'id': 266, 'def': 'a variety of mandarin orange', 'name': 'clementine'}, {'frequency': 'c', 'synset': 'clip.n.03', 'synonyms': ['clip'], 'id': 267, 'def': 'any of various small fasteners used to hold loose articles together', 'name': 'clip'}, {'frequency': 'c', 'synset': 'clipboard.n.01', 'synonyms': ['clipboard'], 'id': 268, 'def': 'a small writing board with a clip at the top for holding papers', 'name': 'clipboard'}, {'frequency': 'r', 'synset': 'clipper.n.03', 'synonyms': ['clippers_(for_plants)'], 'id': 269, 'def': 'shears for cutting grass or shrubbery (often used in the plural)', 'name': 'clippers_(for_plants)'}, {'frequency': 'r', 'synset': 'cloak.n.02', 'synonyms': ['cloak'], 'id': 270, 'def': 'a loose outer garment', 'name': 'cloak'}, {'frequency': 'f', 'synset': 'clock.n.01', 'synonyms': ['clock', 'timepiece', 'timekeeper'], 'id': 271, 'def': 'a timepiece that shows the time of day', 'name': 'clock'}, {'frequency': 'f', 'synset': 'clock_tower.n.01', 'synonyms': ['clock_tower'], 'id': 272, 'def': 'a tower with a large clock visible high up on an outside face', 'name': 'clock_tower'}, {'frequency': 'c', 'synset': 'clothes_hamper.n.01', 'synonyms': ['clothes_hamper', 'laundry_basket', 'clothes_basket'], 'id': 273, 'def': 'a hamper that holds dirty clothes to be washed or wet clothes to be dried', 'name': 'clothes_hamper'}, {'frequency': 'c', 'synset': 'clothespin.n.01', 'synonyms': ['clothespin', 'clothes_peg'], 'id': 274, 'def': 'wood or plastic fastener; for holding clothes on a clothesline', 'name': 'clothespin'}, {'frequency': 'r', 'synset': 'clutch_bag.n.01', 'synonyms': ['clutch_bag'], 'id': 275, 'def': "a woman's strapless purse that is carried in the hand", 'name': 'clutch_bag'}, {'frequency': 'f', 'synset': 'coaster.n.03', 'synonyms': ['coaster'], 'id': 276, 'def': 'a covering (plate or mat) that protects the surface of a table', 'name': 'coaster'}, {'frequency': 'f', 'synset': 'coat.n.01', 'synonyms': ['coat'], 'id': 277, 'def': 'an outer garment that has sleeves and covers the body from shoulder down', 'name': 'coat'}, {'frequency': 'c', 'synset': 'coat_hanger.n.01', 'synonyms': ['coat_hanger', 'clothes_hanger', 'dress_hanger'], 'id': 278, 'def': "a hanger that is shaped like a person's shoulders", 'name': 'coat_hanger'}, {'frequency': 'c', 'synset': 'coatrack.n.01', 'synonyms': ['coatrack', 'hatrack'], 'id': 279, 'def': 'a rack with hooks for temporarily holding coats and hats', 'name': 'coatrack'}, {'frequency': 'c', 'synset': 'cock.n.04', 'synonyms': ['cock', 'rooster'], 'id': 280, 'def': 'adult male chicken', 'name': 'cock'}, {'frequency': 'r', 'synset': 'cockroach.n.01', 'synonyms': ['cockroach'], 'id': 281, 'def': 'any of numerous chiefly nocturnal insects; some are domestic pests', 'name': 'cockroach'}, {'frequency': 'r', 'synset': 'cocoa.n.01', 'synonyms': ['cocoa_(beverage)', 'hot_chocolate_(beverage)', 'drinking_chocolate'], 'id': 282, 'def': 'a beverage made from cocoa powder and milk and sugar; usually drunk hot', 'name': 'cocoa_(beverage)'}, {'frequency': 'c', 'synset': 'coconut.n.02', 'synonyms': ['coconut', 'cocoanut'], 'id': 283, 'def': 'large hard-shelled brown oval nut with a fibrous husk', 'name': 'coconut'}, {'frequency': 'f', 'synset': 'coffee_maker.n.01', 'synonyms': ['coffee_maker', 'coffee_machine'], 'id': 284, 'def': 'a kitchen appliance for brewing coffee automatically', 'name': 'coffee_maker'}, {'frequency': 'f', 'synset': 'coffee_table.n.01', 'synonyms': ['coffee_table', 'cocktail_table'], 'id': 285, 'def': 'low table where magazines can be placed and coffee or cocktails are served', 'name': 'coffee_table'}, {'frequency': 'c', 'synset': 'coffeepot.n.01', 'synonyms': ['coffeepot'], 'id': 286, 'def': 'tall pot in which coffee is brewed', 'name': 'coffeepot'}, {'frequency': 'r', 'synset': 'coil.n.05', 'synonyms': ['coil'], 'id': 287, 'def': 'tubing that is wound in a spiral', 'name': 'coil'}, {'frequency': 'c', 'synset': 'coin.n.01', 'synonyms': ['coin'], 'id': 288, 'def': 'a flat metal piece (usually a disc) used as money', 'name': 'coin'}, {'frequency': 'c', 'synset': 'colander.n.01', 'synonyms': ['colander', 'cullender'], 'id': 289, 'def': 'bowl-shaped strainer; used to wash or drain foods', 'name': 'colander'}, {'frequency': 'c', 'synset': 'coleslaw.n.01', 'synonyms': ['coleslaw', 'slaw'], 'id': 290, 'def': 'basically shredded cabbage', 'name': 'coleslaw'}, {'frequency': 'r', 'synset': 'coloring_material.n.01', 'synonyms': ['coloring_material', 'colouring_material'], 'id': 291, 'def': 'any material used for its color', 'name': 'coloring_material'}, {'frequency': 'r', 'synset': 'combination_lock.n.01', 'synonyms': ['combination_lock'], 'id': 292, 'def': 'lock that can be opened only by turning dials in a special sequence', 'name': 'combination_lock'}, {'frequency': 'c', 'synset': 'comforter.n.04', 'synonyms': ['pacifier', 'teething_ring'], 'id': 293, 'def': 'device used for an infant to suck or bite on', 'name': 'pacifier'}, {'frequency': 'r', 'synset': 'comic_book.n.01', 'synonyms': ['comic_book'], 'id': 294, 'def': 'a magazine devoted to comic strips', 'name': 'comic_book'}, {'frequency': 'r', 'synset': 'compass.n.01', 'synonyms': ['compass'], 'id': 295, 'def': 'navigational instrument for finding directions', 'name': 'compass'}, {'frequency': 'f', 'synset': 'computer_keyboard.n.01', 'synonyms': ['computer_keyboard', 'keyboard_(computer)'], 'id': 296, 'def': 'a keyboard that is a data input device for computers', 'name': 'computer_keyboard'}, {'frequency': 'f', 'synset': 'condiment.n.01', 'synonyms': ['condiment'], 'id': 297, 'def': 'a preparation (a sauce or relish or spice) to enhance flavor or enjoyment', 'name': 'condiment'}, {'frequency': 'f', 'synset': 'cone.n.01', 'synonyms': ['cone', 'traffic_cone'], 'id': 298, 'def': 'a cone-shaped object used to direct traffic', 'name': 'cone'}, {'frequency': 'f', 'synset': 'control.n.09', 'synonyms': ['control', 'controller'], 'id': 299, 'def': 'a mechanism that controls the operation of a machine', 'name': 'control'}, {'frequency': 'r', 'synset': 'convertible.n.01', 'synonyms': ['convertible_(automobile)'], 'id': 300, 'def': 'a car that has top that can be folded or removed', 'name': 'convertible_(automobile)'}, {'frequency': 'r', 'synset': 'convertible.n.03', 'synonyms': ['sofa_bed'], 'id': 301, 'def': 'a sofa that can be converted into a bed', 'name': 'sofa_bed'}, {'frequency': 'r', 'synset': 'cooker.n.01', 'synonyms': ['cooker'], 'id': 302, 'def': 'a utensil for cooking', 'name': 'cooker'}, {'frequency': 'f', 'synset': 'cookie.n.01', 'synonyms': ['cookie', 'cooky', 'biscuit_(cookie)'], 'id': 303, 'def': "any of various small flat sweet cakes (`biscuit' is the British term)", 'name': 'cookie'}, {'frequency': 'r', 'synset': 'cooking_utensil.n.01', 'synonyms': ['cooking_utensil'], 'id': 304, 'def': 'a kitchen utensil made of material that does not melt easily; used for cooking', 'name': 'cooking_utensil'}, {'frequency': 'f', 'synset': 'cooler.n.01', 'synonyms': ['cooler_(for_food)', 'ice_chest'], 'id': 305, 'def': 'an insulated box for storing food often with ice', 'name': 'cooler_(for_food)'}, {'frequency': 'f', 'synset': 'cork.n.04', 'synonyms': ['cork_(bottle_plug)', 'bottle_cork'], 'id': 306, 'def': 'the plug in the mouth of a bottle (especially a wine bottle)', 'name': 'cork_(bottle_plug)'}, {'frequency': 'r', 'synset': 'corkboard.n.01', 'synonyms': ['corkboard'], 'id': 307, 'def': 'a sheet consisting of cork granules', 'name': 'corkboard'}, {'frequency': 'c', 'synset': 'corkscrew.n.01', 'synonyms': ['corkscrew', 'bottle_screw'], 'id': 308, 'def': 'a bottle opener that pulls corks', 'name': 'corkscrew'}, {'frequency': 'f', 'synset': 'corn.n.03', 'synonyms': ['edible_corn', 'corn', 'maize'], 'id': 309, 'def': 'ears or kernels of corn that can be prepared and served for human food (only mark individual ears or kernels)', 'name': 'edible_corn'}, {'frequency': 'r', 'synset': 'cornbread.n.01', 'synonyms': ['cornbread'], 'id': 310, 'def': 'bread made primarily of cornmeal', 'name': 'cornbread'}, {'frequency': 'c', 'synset': 'cornet.n.01', 'synonyms': ['cornet', 'horn', 'trumpet'], 'id': 311, 'def': 'a brass musical instrument with a narrow tube and a flared bell and many valves', 'name': 'cornet'}, {'frequency': 'c', 'synset': 'cornice.n.01', 'synonyms': ['cornice', 'valance', 'valance_board', 'pelmet'], 'id': 312, 'def': 'a decorative framework to conceal curtain fixtures at the top of a window casing', 'name': 'cornice'}, {'frequency': 'r', 'synset': 'cornmeal.n.01', 'synonyms': ['cornmeal'], 'id': 313, 'def': 'coarsely ground corn', 'name': 'cornmeal'}, {'frequency': 'c', 'synset': 'corset.n.01', 'synonyms': ['corset', 'girdle'], 'id': 314, 'def': "a woman's close-fitting foundation garment", 'name': 'corset'}, {'frequency': 'c', 'synset': 'costume.n.04', 'synonyms': ['costume'], 'id': 315, 'def': 'the attire characteristic of a country or a time or a social class', 'name': 'costume'}, {'frequency': 'r', 'synset': 'cougar.n.01', 'synonyms': ['cougar', 'puma', 'catamount', 'mountain_lion', 'panther'], 'id': 316, 'def': 'large American feline resembling a lion', 'name': 'cougar'}, {'frequency': 'r', 'synset': 'coverall.n.01', 'synonyms': ['coverall'], 'id': 317, 'def': 'a loose-fitting protective garment that is worn over other clothing', 'name': 'coverall'}, {'frequency': 'c', 'synset': 'cowbell.n.01', 'synonyms': ['cowbell'], 'id': 318, 'def': 'a bell hung around the neck of cow so that the cow can be easily located', 'name': 'cowbell'}, {'frequency': 'f', 'synset': 'cowboy_hat.n.01', 'synonyms': ['cowboy_hat', 'ten-gallon_hat'], 'id': 319, 'def': 'a hat with a wide brim and a soft crown; worn by American ranch hands', 'name': 'cowboy_hat'}, {'frequency': 'c', 'synset': 'crab.n.01', 'synonyms': ['crab_(animal)'], 'id': 320, 'def': 'decapod having eyes on short stalks and a broad flattened shell and pincers', 'name': 'crab_(animal)'}, {'frequency': 'r', 'synset': 'crab.n.05', 'synonyms': ['crabmeat'], 'id': 321, 'def': 'the edible flesh of any of various crabs', 'name': 'crabmeat'}, {'frequency': 'c', 'synset': 'cracker.n.01', 'synonyms': ['cracker'], 'id': 322, 'def': 'a thin crisp wafer', 'name': 'cracker'}, {'frequency': 'r', 'synset': 'crape.n.01', 'synonyms': ['crape', 'crepe', 'French_pancake'], 'id': 323, 'def': 'small very thin pancake', 'name': 'crape'}, {'frequency': 'f', 'synset': 'crate.n.01', 'synonyms': ['crate'], 'id': 324, 'def': 'a rugged box (usually made of wood); used for shipping', 'name': 'crate'}, {'frequency': 'c', 'synset': 'crayon.n.01', 'synonyms': ['crayon', 'wax_crayon'], 'id': 325, 'def': 'writing or drawing implement made of a colored stick of composition wax', 'name': 'crayon'}, {'frequency': 'r', 'synset': 'cream_pitcher.n.01', 'synonyms': ['cream_pitcher'], 'id': 326, 'def': 'a small pitcher for serving cream', 'name': 'cream_pitcher'}, {'frequency': 'c', 'synset': 'crescent_roll.n.01', 'synonyms': ['crescent_roll', 'croissant'], 'id': 327, 'def': 'very rich flaky crescent-shaped roll', 'name': 'crescent_roll'}, {'frequency': 'c', 'synset': 'crib.n.01', 'synonyms': ['crib', 'cot'], 'id': 328, 'def': 'baby bed with high sides made of slats', 'name': 'crib'}, {'frequency': 'c', 'synset': 'crock.n.03', 'synonyms': ['crock_pot', 'earthenware_jar'], 'id': 329, 'def': 'an earthen jar (made of baked clay) or a modern electric crockpot', 'name': 'crock_pot'}, {'frequency': 'f', 'synset': 'crossbar.n.01', 'synonyms': ['crossbar'], 'id': 330, 'def': 'a horizontal bar that goes across something', 'name': 'crossbar'}, {'frequency': 'r', 'synset': 'crouton.n.01', 'synonyms': ['crouton'], 'id': 331, 'def': 'a small piece of toasted or fried bread; served in soup or salads', 'name': 'crouton'}, {'frequency': 'c', 'synset': 'crow.n.01', 'synonyms': ['crow'], 'id': 332, 'def': 'black birds having a raucous call', 'name': 'crow'}, {'frequency': 'r', 'synset': 'crowbar.n.01', 'synonyms': ['crowbar', 'wrecking_bar', 'pry_bar'], 'id': 333, 'def': 'a heavy iron lever with one end forged into a wedge', 'name': 'crowbar'}, {'frequency': 'c', 'synset': 'crown.n.04', 'synonyms': ['crown'], 'id': 334, 'def': 'an ornamental jeweled headdress signifying sovereignty', 'name': 'crown'}, {'frequency': 'c', 'synset': 'crucifix.n.01', 'synonyms': ['crucifix'], 'id': 335, 'def': 'representation of the cross on which Jesus died', 'name': 'crucifix'}, {'frequency': 'c', 'synset': 'cruise_ship.n.01', 'synonyms': ['cruise_ship', 'cruise_liner'], 'id': 336, 'def': 'a passenger ship used commercially for pleasure cruises', 'name': 'cruise_ship'}, {'frequency': 'c', 'synset': 'cruiser.n.01', 'synonyms': ['police_cruiser', 'patrol_car', 'police_car', 'squad_car'], 'id': 337, 'def': 'a car in which policemen cruise the streets', 'name': 'police_cruiser'}, {'frequency': 'f', 'synset': 'crumb.n.03', 'synonyms': ['crumb'], 'id': 338, 'def': 'small piece of e.g. bread or cake', 'name': 'crumb'}, {'frequency': 'c', 'synset': 'crutch.n.01', 'synonyms': ['crutch'], 'id': 339, 'def': 'a wooden or metal staff that fits under the armpit and reaches to the ground', 'name': 'crutch'}, {'frequency': 'c', 'synset': 'cub.n.03', 'synonyms': ['cub_(animal)'], 'id': 340, 'def': 'the young of certain carnivorous mammals such as the bear or wolf or lion', 'name': 'cub_(animal)'}, {'frequency': 'c', 'synset': 'cube.n.05', 'synonyms': ['cube', 'square_block'], 'id': 341, 'def': 'a block in the (approximate) shape of a cube', 'name': 'cube'}, {'frequency': 'f', 'synset': 'cucumber.n.02', 'synonyms': ['cucumber', 'cuke'], 'id': 342, 'def': 'cylindrical green fruit with thin green rind and white flesh eaten as a vegetable', 'name': 'cucumber'}, {'frequency': 'c', 'synset': 'cufflink.n.01', 'synonyms': ['cufflink'], 'id': 343, 'def': 'jewelry consisting of linked buttons used to fasten the cuffs of a shirt', 'name': 'cufflink'}, {'frequency': 'f', 'synset': 'cup.n.01', 'synonyms': ['cup'], 'id': 344, 'def': 'a small open container usually used for drinking; usually has a handle', 'name': 'cup'}, {'frequency': 'c', 'synset': 'cup.n.08', 'synonyms': ['trophy_cup'], 'id': 345, 'def': 'a metal award or cup-shaped vessel with handles that is awarded as a trophy to a competition winner', 'name': 'trophy_cup'}, {'frequency': 'f', 'synset': 'cupboard.n.01', 'synonyms': ['cupboard', 'closet'], 'id': 346, 'def': 'a small room (or recess) or cabinet used for storage space', 'name': 'cupboard'}, {'frequency': 'f', 'synset': 'cupcake.n.01', 'synonyms': ['cupcake'], 'id': 347, 'def': 'small cake baked in a muffin tin', 'name': 'cupcake'}, {'frequency': 'r', 'synset': 'curler.n.01', 'synonyms': ['hair_curler', 'hair_roller', 'hair_crimper'], 'id': 348, 'def': 'a cylindrical tube around which the hair is wound to curl it', 'name': 'hair_curler'}, {'frequency': 'r', 'synset': 'curling_iron.n.01', 'synonyms': ['curling_iron'], 'id': 349, 'def': 'a cylindrical home appliance that heats hair that has been curled around it', 'name': 'curling_iron'}, {'frequency': 'f', 'synset': 'curtain.n.01', 'synonyms': ['curtain', 'drapery'], 'id': 350, 'def': 'hanging cloth used as a blind (especially for a window)', 'name': 'curtain'}, {'frequency': 'f', 'synset': 'cushion.n.03', 'synonyms': ['cushion'], 'id': 351, 'def': 'a soft bag filled with air or padding such as feathers or foam rubber', 'name': 'cushion'}, {'frequency': 'r', 'synset': 'cylinder.n.04', 'synonyms': ['cylinder'], 'id': 352, 'def': 'a cylindrical container', 'name': 'cylinder'}, {'frequency': 'r', 'synset': 'cymbal.n.01', 'synonyms': ['cymbal'], 'id': 353, 'def': 'a percussion instrument consisting of a concave brass disk', 'name': 'cymbal'}, {'frequency': 'r', 'synset': 'dagger.n.01', 'synonyms': ['dagger'], 'id': 354, 'def': 'a short knife with a pointed blade used for piercing or stabbing', 'name': 'dagger'}, {'frequency': 'r', 'synset': 'dalmatian.n.02', 'synonyms': ['dalmatian'], 'id': 355, 'def': 'a large breed having a smooth white coat with black or brown spots', 'name': 'dalmatian'}, {'frequency': 'c', 'synset': 'dartboard.n.01', 'synonyms': ['dartboard'], 'id': 356, 'def': 'a circular board of wood or cork used as the target in the game of darts', 'name': 'dartboard'}, {'frequency': 'r', 'synset': 'date.n.08', 'synonyms': ['date_(fruit)'], 'id': 357, 'def': 'sweet edible fruit of the date palm with a single long woody seed', 'name': 'date_(fruit)'}, {'frequency': 'f', 'synset': 'deck_chair.n.01', 'synonyms': ['deck_chair', 'beach_chair'], 'id': 358, 'def': 'a folding chair for use outdoors; a wooden frame supports a length of canvas', 'name': 'deck_chair'}, {'frequency': 'c', 'synset': 'deer.n.01', 'synonyms': ['deer', 'cervid'], 'id': 359, 'def': "distinguished from Bovidae by the male's having solid deciduous antlers", 'name': 'deer'}, {'frequency': 'c', 'synset': 'dental_floss.n.01', 'synonyms': ['dental_floss', 'floss'], 'id': 360, 'def': 'a soft thread for cleaning the spaces between the teeth', 'name': 'dental_floss'}, {'frequency': 'f', 'synset': 'desk.n.01', 'synonyms': ['desk'], 'id': 361, 'def': 'a piece of furniture with a writing surface and usually drawers or other compartments', 'name': 'desk'}, {'frequency': 'r', 'synset': 'detergent.n.01', 'synonyms': ['detergent'], 'id': 362, 'def': 'a surface-active chemical widely used in industry and laundering', 'name': 'detergent'}, {'frequency': 'c', 'synset': 'diaper.n.01', 'synonyms': ['diaper'], 'id': 363, 'def': 'garment consisting of a folded cloth drawn up between the legs and fastened at the waist', 'name': 'diaper'}, {'frequency': 'r', 'synset': 'diary.n.01', 'synonyms': ['diary', 'journal'], 'id': 364, 'def': 'yearly planner book', 'name': 'diary'}, {'frequency': 'r', 'synset': 'die.n.01', 'synonyms': ['die', 'dice'], 'id': 365, 'def': 'a small cube with 1 to 6 spots on the six faces; used in gambling', 'name': 'die'}, {'frequency': 'r', 'synset': 'dinghy.n.01', 'synonyms': ['dinghy', 'dory', 'rowboat'], 'id': 366, 'def': 'a small boat of shallow draft with seats and oars with which it is propelled', 'name': 'dinghy'}, {'frequency': 'f', 'synset': 'dining_table.n.01', 'synonyms': ['dining_table'], 'id': 367, 'def': 'a table at which meals are served', 'name': 'dining_table'}, {'frequency': 'r', 'synset': 'dinner_jacket.n.01', 'synonyms': ['tux', 'tuxedo'], 'id': 368, 'def': 'semiformal evening dress for men', 'name': 'tux'}, {'frequency': 'f', 'synset': 'dish.n.01', 'synonyms': ['dish'], 'id': 369, 'def': 'a piece of dishware normally used as a container for holding or serving food', 'name': 'dish'}, {'frequency': 'c', 'synset': 'dish.n.05', 'synonyms': ['dish_antenna'], 'id': 370, 'def': 'directional antenna consisting of a parabolic reflector', 'name': 'dish_antenna'}, {'frequency': 'c', 'synset': 'dishrag.n.01', 'synonyms': ['dishrag', 'dishcloth'], 'id': 371, 'def': 'a cloth for washing dishes or cleaning in general', 'name': 'dishrag'}, {'frequency': 'f', 'synset': 'dishtowel.n.01', 'synonyms': ['dishtowel', 'tea_towel'], 'id': 372, 'def': 'a towel for drying dishes', 'name': 'dishtowel'}, {'frequency': 'f', 'synset': 'dishwasher.n.01', 'synonyms': ['dishwasher', 'dishwashing_machine'], 'id': 373, 'def': 'a machine for washing dishes', 'name': 'dishwasher'}, {'frequency': 'r', 'synset': 'dishwasher_detergent.n.01', 'synonyms': ['dishwasher_detergent', 'dishwashing_detergent', 'dishwashing_liquid', 'dishsoap'], 'id': 374, 'def': 'dishsoap or dish detergent designed for use in dishwashers', 'name': 'dishwasher_detergent'}, {'frequency': 'f', 'synset': 'dispenser.n.01', 'synonyms': ['dispenser'], 'id': 375, 'def': 'a container so designed that the contents can be used in prescribed amounts', 'name': 'dispenser'}, {'frequency': 'r', 'synset': 'diving_board.n.01', 'synonyms': ['diving_board'], 'id': 376, 'def': 'a springboard from which swimmers can dive', 'name': 'diving_board'}, {'frequency': 'f', 'synset': 'dixie_cup.n.01', 'synonyms': ['Dixie_cup', 'paper_cup'], 'id': 377, 'def': 'a disposable cup made of paper; for holding drinks', 'name': 'Dixie_cup'}, {'frequency': 'f', 'synset': 'dog.n.01', 'synonyms': ['dog'], 'id': 378, 'def': 'a common domesticated dog', 'name': 'dog'}, {'frequency': 'f', 'synset': 'dog_collar.n.01', 'synonyms': ['dog_collar'], 'id': 379, 'def': 'a collar for a dog', 'name': 'dog_collar'}, {'frequency': 'f', 'synset': 'doll.n.01', 'synonyms': ['doll'], 'id': 380, 'def': 'a toy replica of a HUMAN (NOT AN ANIMAL)', 'name': 'doll'}, {'frequency': 'r', 'synset': 'dollar.n.02', 'synonyms': ['dollar', 'dollar_bill', 'one_dollar_bill'], 'id': 381, 'def': 'a piece of paper money worth one dollar', 'name': 'dollar'}, {'frequency': 'r', 'synset': 'dollhouse.n.01', 'synonyms': ['dollhouse', "doll's_house"], 'id': 382, 'def': "a house so small that it is likened to a child's plaything", 'name': 'dollhouse'}, {'frequency': 'c', 'synset': 'dolphin.n.02', 'synonyms': ['dolphin'], 'id': 383, 'def': 'any of various small toothed whales with a beaklike snout; larger than porpoises', 'name': 'dolphin'}, {'frequency': 'c', 'synset': 'domestic_ass.n.01', 'synonyms': ['domestic_ass', 'donkey'], 'id': 384, 'def': 'domestic beast of burden descended from the African wild ass; patient but stubborn', 'name': 'domestic_ass'}, {'frequency': 'f', 'synset': 'doorknob.n.01', 'synonyms': ['doorknob', 'doorhandle'], 'id': 385, 'def': "a knob used to open a door (often called `doorhandle' in Great Britain)", 'name': 'doorknob'}, {'frequency': 'c', 'synset': 'doormat.n.02', 'synonyms': ['doormat', 'welcome_mat'], 'id': 386, 'def': 'a mat placed outside an exterior door for wiping the shoes before entering', 'name': 'doormat'}, {'frequency': 'f', 'synset': 'doughnut.n.02', 'synonyms': ['doughnut', 'donut'], 'id': 387, 'def': 'a small ring-shaped friedcake', 'name': 'doughnut'}, {'frequency': 'r', 'synset': 'dove.n.01', 'synonyms': ['dove'], 'id': 388, 'def': 'any of numerous small pigeons', 'name': 'dove'}, {'frequency': 'r', 'synset': 'dragonfly.n.01', 'synonyms': ['dragonfly'], 'id': 389, 'def': 'slender-bodied non-stinging insect having iridescent wings that are outspread at rest', 'name': 'dragonfly'}, {'frequency': 'f', 'synset': 'drawer.n.01', 'synonyms': ['drawer'], 'id': 390, 'def': 'a boxlike container in a piece of furniture; made so as to slide in and out', 'name': 'drawer'}, {'frequency': 'c', 'synset': 'drawers.n.01', 'synonyms': ['underdrawers', 'boxers', 'boxershorts'], 'id': 391, 'def': 'underpants worn by men', 'name': 'underdrawers'}, {'frequency': 'f', 'synset': 'dress.n.01', 'synonyms': ['dress', 'frock'], 'id': 392, 'def': 'a one-piece garment for a woman; has skirt and bodice', 'name': 'dress'}, {'frequency': 'c', 'synset': 'dress_hat.n.01', 'synonyms': ['dress_hat', 'high_hat', 'opera_hat', 'silk_hat', 'top_hat'], 'id': 393, 'def': "a man's hat with a tall crown; usually covered with silk or with beaver fur", 'name': 'dress_hat'}, {'frequency': 'f', 'synset': 'dress_suit.n.01', 'synonyms': ['dress_suit'], 'id': 394, 'def': 'formalwear consisting of full evening dress for men', 'name': 'dress_suit'}, {'frequency': 'f', 'synset': 'dresser.n.05', 'synonyms': ['dresser'], 'id': 395, 'def': 'a cabinet with shelves', 'name': 'dresser'}, {'frequency': 'c', 'synset': 'drill.n.01', 'synonyms': ['drill'], 'id': 396, 'def': 'a tool with a sharp rotating point for making holes in hard materials', 'name': 'drill'}, {'frequency': 'r', 'synset': 'drone.n.04', 'synonyms': ['drone'], 'id': 397, 'def': 'an aircraft without a pilot that is operated by remote control', 'name': 'drone'}, {'frequency': 'r', 'synset': 'dropper.n.01', 'synonyms': ['dropper', 'eye_dropper'], 'id': 398, 'def': 'pipet consisting of a small tube with a vacuum bulb at one end for drawing liquid in and releasing it a drop at a time', 'name': 'dropper'}, {'frequency': 'c', 'synset': 'drum.n.01', 'synonyms': ['drum_(musical_instrument)'], 'id': 399, 'def': 'a musical percussion instrument; usually consists of a hollow cylinder with a membrane stretched across each end', 'name': 'drum_(musical_instrument)'}, {'frequency': 'r', 'synset': 'drumstick.n.02', 'synonyms': ['drumstick'], 'id': 400, 'def': 'a stick used for playing a drum', 'name': 'drumstick'}, {'frequency': 'f', 'synset': 'duck.n.01', 'synonyms': ['duck'], 'id': 401, 'def': 'small web-footed broad-billed swimming bird', 'name': 'duck'}, {'frequency': 'c', 'synset': 'duckling.n.02', 'synonyms': ['duckling'], 'id': 402, 'def': 'young duck', 'name': 'duckling'}, {'frequency': 'c', 'synset': 'duct_tape.n.01', 'synonyms': ['duct_tape'], 'id': 403, 'def': 'a wide silvery adhesive tape', 'name': 'duct_tape'}, {'frequency': 'f', 'synset': 'duffel_bag.n.01', 'synonyms': ['duffel_bag', 'duffle_bag', 'duffel', 'duffle'], 'id': 404, 'def': 'a large cylindrical bag of heavy cloth (does not include suitcases)', 'name': 'duffel_bag'}, {'frequency': 'r', 'synset': 'dumbbell.n.01', 'synonyms': ['dumbbell'], 'id': 405, 'def': 'an exercising weight with two ball-like ends connected by a short handle', 'name': 'dumbbell'}, {'frequency': 'c', 'synset': 'dumpster.n.01', 'synonyms': ['dumpster'], 'id': 406, 'def': 'a container designed to receive and transport and dump waste', 'name': 'dumpster'}, {'frequency': 'r', 'synset': 'dustpan.n.02', 'synonyms': ['dustpan'], 'id': 407, 'def': 'a short-handled receptacle into which dust can be swept', 'name': 'dustpan'}, {'frequency': 'c', 'synset': 'eagle.n.01', 'synonyms': ['eagle'], 'id': 408, 'def': 'large birds of prey noted for their broad wings and strong soaring flight', 'name': 'eagle'}, {'frequency': 'f', 'synset': 'earphone.n.01', 'synonyms': ['earphone', 'earpiece', 'headphone'], 'id': 409, 'def': 'device for listening to audio that is held over or inserted into the ear', 'name': 'earphone'}, {'frequency': 'r', 'synset': 'earplug.n.01', 'synonyms': ['earplug'], 'id': 410, 'def': 'a soft plug that is inserted into the ear canal to block sound', 'name': 'earplug'}, {'frequency': 'f', 'synset': 'earring.n.01', 'synonyms': ['earring'], 'id': 411, 'def': 'jewelry to ornament the ear', 'name': 'earring'}, {'frequency': 'c', 'synset': 'easel.n.01', 'synonyms': ['easel'], 'id': 412, 'def': "an upright tripod for displaying something (usually an artist's canvas)", 'name': 'easel'}, {'frequency': 'r', 'synset': 'eclair.n.01', 'synonyms': ['eclair'], 'id': 413, 'def': 'oblong cream puff', 'name': 'eclair'}, {'frequency': 'r', 'synset': 'eel.n.01', 'synonyms': ['eel'], 'id': 414, 'def': 'an elongate fish with fatty flesh', 'name': 'eel'}, {'frequency': 'f', 'synset': 'egg.n.02', 'synonyms': ['egg', 'eggs'], 'id': 415, 'def': 'oval reproductive body of a fowl (especially a hen) used as food', 'name': 'egg'}, {'frequency': 'r', 'synset': 'egg_roll.n.01', 'synonyms': ['egg_roll', 'spring_roll'], 'id': 416, 'def': 'minced vegetables and meat wrapped in a pancake and fried', 'name': 'egg_roll'}, {'frequency': 'c', 'synset': 'egg_yolk.n.01', 'synonyms': ['egg_yolk', 'yolk_(egg)'], 'id': 417, 'def': 'the yellow spherical part of an egg', 'name': 'egg_yolk'}, {'frequency': 'c', 'synset': 'eggbeater.n.02', 'synonyms': ['eggbeater', 'eggwhisk'], 'id': 418, 'def': 'a mixer for beating eggs or whipping cream', 'name': 'eggbeater'}, {'frequency': 'c', 'synset': 'eggplant.n.01', 'synonyms': ['eggplant', 'aubergine'], 'id': 419, 'def': 'egg-shaped vegetable having a shiny skin typically dark purple', 'name': 'eggplant'}, {'frequency': 'r', 'synset': 'electric_chair.n.01', 'synonyms': ['electric_chair'], 'id': 420, 'def': 'a chair-shaped instrument of execution by electrocution', 'name': 'electric_chair'}, {'frequency': 'f', 'synset': 'electric_refrigerator.n.01', 'synonyms': ['refrigerator'], 'id': 421, 'def': 'a refrigerator in which the coolant is pumped around by an electric motor', 'name': 'refrigerator'}, {'frequency': 'f', 'synset': 'elephant.n.01', 'synonyms': ['elephant'], 'id': 422, 'def': 'a common elephant', 'name': 'elephant'}, {'frequency': 'c', 'synset': 'elk.n.01', 'synonyms': ['elk', 'moose'], 'id': 423, 'def': 'large northern deer with enormous flattened antlers in the male', 'name': 'elk'}, {'frequency': 'c', 'synset': 'envelope.n.01', 'synonyms': ['envelope'], 'id': 424, 'def': 'a flat (usually rectangular) container for a letter, thin package, etc.', 'name': 'envelope'}, {'frequency': 'c', 'synset': 'eraser.n.01', 'synonyms': ['eraser'], 'id': 425, 'def': 'an implement used to erase something', 'name': 'eraser'}, {'frequency': 'r', 'synset': 'escargot.n.01', 'synonyms': ['escargot'], 'id': 426, 'def': 'edible snail usually served in the shell with a sauce of melted butter and garlic', 'name': 'escargot'}, {'frequency': 'r', 'synset': 'eyepatch.n.01', 'synonyms': ['eyepatch'], 'id': 427, 'def': 'a protective cloth covering for an injured eye', 'name': 'eyepatch'}, {'frequency': 'r', 'synset': 'falcon.n.01', 'synonyms': ['falcon'], 'id': 428, 'def': 'birds of prey having long pointed powerful wings adapted for swift flight', 'name': 'falcon'}, {'frequency': 'f', 'synset': 'fan.n.01', 'synonyms': ['fan'], 'id': 429, 'def': 'a device for creating a current of air by movement of a surface or surfaces', 'name': 'fan'}, {'frequency': 'f', 'synset': 'faucet.n.01', 'synonyms': ['faucet', 'spigot', 'tap'], 'id': 430, 'def': 'a regulator for controlling the flow of a liquid from a reservoir', 'name': 'faucet'}, {'frequency': 'r', 'synset': 'fedora.n.01', 'synonyms': ['fedora'], 'id': 431, 'def': 'a hat made of felt with a creased crown', 'name': 'fedora'}, {'frequency': 'r', 'synset': 'ferret.n.02', 'synonyms': ['ferret'], 'id': 432, 'def': 'domesticated albino variety of the European polecat bred for hunting rats and rabbits', 'name': 'ferret'}, {'frequency': 'c', 'synset': 'ferris_wheel.n.01', 'synonyms': ['Ferris_wheel'], 'id': 433, 'def': 'a large wheel with suspended seats that remain upright as the wheel rotates', 'name': 'Ferris_wheel'}, {'frequency': 'c', 'synset': 'ferry.n.01', 'synonyms': ['ferry', 'ferryboat'], 'id': 434, 'def': 'a boat that transports people or vehicles across a body of water and operates on a regular schedule', 'name': 'ferry'}, {'frequency': 'r', 'synset': 'fig.n.04', 'synonyms': ['fig_(fruit)'], 'id': 435, 'def': 'fleshy sweet pear-shaped yellowish or purple fruit eaten fresh or preserved or dried', 'name': 'fig_(fruit)'}, {'frequency': 'c', 'synset': 'fighter.n.02', 'synonyms': ['fighter_jet', 'fighter_aircraft', 'attack_aircraft'], 'id': 436, 'def': 'a high-speed military or naval airplane designed to destroy enemy targets', 'name': 'fighter_jet'}, {'frequency': 'f', 'synset': 'figurine.n.01', 'synonyms': ['figurine'], 'id': 437, 'def': 'a small carved or molded figure', 'name': 'figurine'}, {'frequency': 'c', 'synset': 'file.n.03', 'synonyms': ['file_cabinet', 'filing_cabinet'], 'id': 438, 'def': 'office furniture consisting of a container for keeping papers in order', 'name': 'file_cabinet'}, {'frequency': 'r', 'synset': 'file.n.04', 'synonyms': ['file_(tool)'], 'id': 439, 'def': 'a steel hand tool with small sharp teeth on some or all of its surfaces; used for smoothing wood or metal', 'name': 'file_(tool)'}, {'frequency': 'f', 'synset': 'fire_alarm.n.02', 'synonyms': ['fire_alarm', 'smoke_alarm'], 'id': 440, 'def': 'an alarm that is tripped off by fire or smoke', 'name': 'fire_alarm'}, {'frequency': 'f', 'synset': 'fire_engine.n.01', 'synonyms': ['fire_engine', 'fire_truck'], 'id': 441, 'def': 'large trucks that carry firefighters and equipment to the site of a fire', 'name': 'fire_engine'}, {'frequency': 'f', 'synset': 'fire_extinguisher.n.01', 'synonyms': ['fire_extinguisher', 'extinguisher'], 'id': 442, 'def': 'a manually operated device for extinguishing small fires', 'name': 'fire_extinguisher'}, {'frequency': 'c', 'synset': 'fire_hose.n.01', 'synonyms': ['fire_hose'], 'id': 443, 'def': 'a large hose that carries water from a fire hydrant to the site of the fire', 'name': 'fire_hose'}, {'frequency': 'f', 'synset': 'fireplace.n.01', 'synonyms': ['fireplace'], 'id': 444, 'def': 'an open recess in a wall at the base of a chimney where a fire can be built', 'name': 'fireplace'}, {'frequency': 'f', 'synset': 'fireplug.n.01', 'synonyms': ['fireplug', 'fire_hydrant', 'hydrant'], 'id': 445, 'def': 'an upright hydrant for drawing water to use in fighting a fire', 'name': 'fireplug'}, {'frequency': 'r', 'synset': 'first-aid_kit.n.01', 'synonyms': ['first-aid_kit'], 'id': 446, 'def': 'kit consisting of a set of bandages and medicines for giving first aid', 'name': 'first-aid_kit'}, {'frequency': 'f', 'synset': 'fish.n.01', 'synonyms': ['fish'], 'id': 447, 'def': 'any of various mostly cold-blooded aquatic vertebrates usually having scales and breathing through gills', 'name': 'fish'}, {'frequency': 'c', 'synset': 'fish.n.02', 'synonyms': ['fish_(food)'], 'id': 448, 'def': 'the flesh of fish used as food', 'name': 'fish_(food)'}, {'frequency': 'r', 'synset': 'fishbowl.n.02', 'synonyms': ['fishbowl', 'goldfish_bowl'], 'id': 449, 'def': 'a transparent bowl in which small fish are kept', 'name': 'fishbowl'}, {'frequency': 'c', 'synset': 'fishing_rod.n.01', 'synonyms': ['fishing_rod', 'fishing_pole'], 'id': 450, 'def': 'a rod that is used in fishing to extend the fishing line', 'name': 'fishing_rod'}, {'frequency': 'f', 'synset': 'flag.n.01', 'synonyms': ['flag'], 'id': 451, 'def': 'emblem usually consisting of a rectangular piece of cloth of distinctive design (do not include pole)', 'name': 'flag'}, {'frequency': 'f', 'synset': 'flagpole.n.02', 'synonyms': ['flagpole', 'flagstaff'], 'id': 452, 'def': 'a tall staff or pole on which a flag is raised', 'name': 'flagpole'}, {'frequency': 'c', 'synset': 'flamingo.n.01', 'synonyms': ['flamingo'], 'id': 453, 'def': 'large pink web-footed bird with down-bent bill', 'name': 'flamingo'}, {'frequency': 'c', 'synset': 'flannel.n.01', 'synonyms': ['flannel'], 'id': 454, 'def': 'a soft light woolen fabric; used for clothing', 'name': 'flannel'}, {'frequency': 'c', 'synset': 'flap.n.01', 'synonyms': ['flap'], 'id': 455, 'def': 'any broad thin covering attached at one edge, such as a mud flap next to a wheel or a flap on an airplane wing', 'name': 'flap'}, {'frequency': 'r', 'synset': 'flash.n.10', 'synonyms': ['flash', 'flashbulb'], 'id': 456, 'def': 'a lamp for providing momentary light to take a photograph', 'name': 'flash'}, {'frequency': 'c', 'synset': 'flashlight.n.01', 'synonyms': ['flashlight', 'torch'], 'id': 457, 'def': 'a small portable battery-powered electric lamp', 'name': 'flashlight'}, {'frequency': 'r', 'synset': 'fleece.n.03', 'synonyms': ['fleece'], 'id': 458, 'def': 'a soft bulky fabric with deep pile; used chiefly for clothing', 'name': 'fleece'}, {'frequency': 'f', 'synset': 'flip-flop.n.02', 'synonyms': ['flip-flop_(sandal)'], 'id': 459, 'def': 'a backless sandal held to the foot by a thong between two toes', 'name': 'flip-flop_(sandal)'}, {'frequency': 'c', 'synset': 'flipper.n.01', 'synonyms': ['flipper_(footwear)', 'fin_(footwear)'], 'id': 460, 'def': 'a shoe to aid a person in swimming', 'name': 'flipper_(footwear)'}, {'frequency': 'f', 'synset': 'flower_arrangement.n.01', 'synonyms': ['flower_arrangement', 'floral_arrangement'], 'id': 461, 'def': 'a decorative arrangement of flowers', 'name': 'flower_arrangement'}, {'frequency': 'c', 'synset': 'flute.n.02', 'synonyms': ['flute_glass', 'champagne_flute'], 'id': 462, 'def': 'a tall narrow wineglass', 'name': 'flute_glass'}, {'frequency': 'c', 'synset': 'foal.n.01', 'synonyms': ['foal'], 'id': 463, 'def': 'a young horse', 'name': 'foal'}, {'frequency': 'c', 'synset': 'folding_chair.n.01', 'synonyms': ['folding_chair'], 'id': 464, 'def': 'a chair that can be folded flat for storage', 'name': 'folding_chair'}, {'frequency': 'c', 'synset': 'food_processor.n.01', 'synonyms': ['food_processor'], 'id': 465, 'def': 'a kitchen appliance for shredding, blending, chopping, or slicing food', 'name': 'food_processor'}, {'frequency': 'c', 'synset': 'football.n.02', 'synonyms': ['football_(American)'], 'id': 466, 'def': 'the inflated oblong ball used in playing American football', 'name': 'football_(American)'}, {'frequency': 'r', 'synset': 'football_helmet.n.01', 'synonyms': ['football_helmet'], 'id': 467, 'def': 'a padded helmet with a face mask to protect the head of football players', 'name': 'football_helmet'}, {'frequency': 'c', 'synset': 'footstool.n.01', 'synonyms': ['footstool', 'footrest'], 'id': 468, 'def': 'a low seat or a stool to rest the feet of a seated person', 'name': 'footstool'}, {'frequency': 'f', 'synset': 'fork.n.01', 'synonyms': ['fork'], 'id': 469, 'def': 'cutlery used for serving and eating food', 'name': 'fork'}, {'frequency': 'c', 'synset': 'forklift.n.01', 'synonyms': ['forklift'], 'id': 470, 'def': 'an industrial vehicle with a power operated fork in front that can be inserted under loads to lift and move them', 'name': 'forklift'}, {'frequency': 'c', 'synset': 'freight_car.n.01', 'synonyms': ['freight_car'], 'id': 471, 'def': 'a railway car that carries freight', 'name': 'freight_car'}, {'frequency': 'c', 'synset': 'french_toast.n.01', 'synonyms': ['French_toast'], 'id': 472, 'def': 'bread slice dipped in egg and milk and fried', 'name': 'French_toast'}, {'frequency': 'c', 'synset': 'freshener.n.01', 'synonyms': ['freshener', 'air_freshener'], 'id': 473, 'def': 'anything that freshens air by removing or covering odor', 'name': 'freshener'}, {'frequency': 'f', 'synset': 'frisbee.n.01', 'synonyms': ['frisbee'], 'id': 474, 'def': 'a light, plastic disk propelled with a flip of the wrist for recreation or competition', 'name': 'frisbee'}, {'frequency': 'c', 'synset': 'frog.n.01', 'synonyms': ['frog', 'toad', 'toad_frog'], 'id': 475, 'def': 'a tailless stout-bodied amphibians with long hind limbs for leaping', 'name': 'frog'}, {'frequency': 'c', 'synset': 'fruit_juice.n.01', 'synonyms': ['fruit_juice'], 'id': 476, 'def': 'drink produced by squeezing or crushing fruit', 'name': 'fruit_juice'}, {'frequency': 'f', 'synset': 'frying_pan.n.01', 'synonyms': ['frying_pan', 'frypan', 'skillet'], 'id': 477, 'def': 'a pan used for frying foods', 'name': 'frying_pan'}, {'frequency': 'r', 'synset': 'fudge.n.01', 'synonyms': ['fudge'], 'id': 478, 'def': 'soft creamy candy', 'name': 'fudge'}, {'frequency': 'r', 'synset': 'funnel.n.02', 'synonyms': ['funnel'], 'id': 479, 'def': 'a cone-shaped utensil used to channel a substance into a container with a small mouth', 'name': 'funnel'}, {'frequency': 'r', 'synset': 'futon.n.01', 'synonyms': ['futon'], 'id': 480, 'def': 'a pad that is used for sleeping on the floor or on a raised frame', 'name': 'futon'}, {'frequency': 'r', 'synset': 'gag.n.02', 'synonyms': ['gag', 'muzzle'], 'id': 481, 'def': "restraint put into a person's mouth to prevent speaking or shouting", 'name': 'gag'}, {'frequency': 'r', 'synset': 'garbage.n.03', 'synonyms': ['garbage'], 'id': 482, 'def': 'a receptacle where waste can be discarded', 'name': 'garbage'}, {'frequency': 'c', 'synset': 'garbage_truck.n.01', 'synonyms': ['garbage_truck'], 'id': 483, 'def': 'a truck for collecting domestic refuse', 'name': 'garbage_truck'}, {'frequency': 'c', 'synset': 'garden_hose.n.01', 'synonyms': ['garden_hose'], 'id': 484, 'def': 'a hose used for watering a lawn or garden', 'name': 'garden_hose'}, {'frequency': 'c', 'synset': 'gargle.n.01', 'synonyms': ['gargle', 'mouthwash'], 'id': 485, 'def': 'a medicated solution used for gargling and rinsing the mouth', 'name': 'gargle'}, {'frequency': 'r', 'synset': 'gargoyle.n.02', 'synonyms': ['gargoyle'], 'id': 486, 'def': 'an ornament consisting of a grotesquely carved figure of a person or animal', 'name': 'gargoyle'}, {'frequency': 'c', 'synset': 'garlic.n.02', 'synonyms': ['garlic', 'ail'], 'id': 487, 'def': 'aromatic bulb used as seasoning', 'name': 'garlic'}, {'frequency': 'r', 'synset': 'gasmask.n.01', 'synonyms': ['gasmask', 'respirator', 'gas_helmet'], 'id': 488, 'def': 'a protective face mask with a filter', 'name': 'gasmask'}, {'frequency': 'c', 'synset': 'gazelle.n.01', 'synonyms': ['gazelle'], 'id': 489, 'def': 'small swift graceful antelope of Africa and Asia having lustrous eyes', 'name': 'gazelle'}, {'frequency': 'c', 'synset': 'gelatin.n.02', 'synonyms': ['gelatin', 'jelly'], 'id': 490, 'def': 'an edible jelly made with gelatin and used as a dessert or salad base or a coating for foods', 'name': 'gelatin'}, {'frequency': 'r', 'synset': 'gem.n.02', 'synonyms': ['gemstone'], 'id': 491, 'def': 'a crystalline rock that can be cut and polished for jewelry', 'name': 'gemstone'}, {'frequency': 'r', 'synset': 'generator.n.02', 'synonyms': ['generator'], 'id': 492, 'def': 'engine that converts mechanical energy into electrical energy by electromagnetic induction', 'name': 'generator'}, {'frequency': 'c', 'synset': 'giant_panda.n.01', 'synonyms': ['giant_panda', 'panda', 'panda_bear'], 'id': 493, 'def': 'large black-and-white herbivorous mammal of bamboo forests of China and Tibet', 'name': 'giant_panda'}, {'frequency': 'c', 'synset': 'gift_wrap.n.01', 'synonyms': ['gift_wrap'], 'id': 494, 'def': 'attractive wrapping paper suitable for wrapping gifts', 'name': 'gift_wrap'}, {'frequency': 'c', 'synset': 'ginger.n.03', 'synonyms': ['ginger', 'gingerroot'], 'id': 495, 'def': 'the root of the common ginger plant; used fresh as a seasoning', 'name': 'ginger'}, {'frequency': 'f', 'synset': 'giraffe.n.01', 'synonyms': ['giraffe'], 'id': 496, 'def': 'tall animal having a spotted coat and small horns and very long neck and legs', 'name': 'giraffe'}, {'frequency': 'c', 'synset': 'girdle.n.02', 'synonyms': ['cincture', 'sash', 'waistband', 'waistcloth'], 'id': 497, 'def': 'a band of material around the waist that strengthens a skirt or trousers', 'name': 'cincture'}, {'frequency': 'f', 'synset': 'glass.n.02', 'synonyms': ['glass_(drink_container)', 'drinking_glass'], 'id': 498, 'def': 'a container for holding liquids while drinking', 'name': 'glass_(drink_container)'}, {'frequency': 'c', 'synset': 'globe.n.03', 'synonyms': ['globe'], 'id': 499, 'def': 'a sphere on which a map (especially of the earth) is represented', 'name': 'globe'}, {'frequency': 'f', 'synset': 'glove.n.02', 'synonyms': ['glove'], 'id': 500, 'def': 'handwear covering the hand', 'name': 'glove'}, {'frequency': 'c', 'synset': 'goat.n.01', 'synonyms': ['goat'], 'id': 501, 'def': 'a common goat', 'name': 'goat'}, {'frequency': 'f', 'synset': 'goggles.n.01', 'synonyms': ['goggles'], 'id': 502, 'def': 'tight-fitting spectacles worn to protect the eyes', 'name': 'goggles'}, {'frequency': 'r', 'synset': 'goldfish.n.01', 'synonyms': ['goldfish'], 'id': 503, 'def': 'small golden or orange-red freshwater fishes used as pond or aquarium pets', 'name': 'goldfish'}, {'frequency': 'c', 'synset': 'golf_club.n.02', 'synonyms': ['golf_club', 'golf-club'], 'id': 504, 'def': 'golf equipment used by a golfer to hit a golf ball', 'name': 'golf_club'}, {'frequency': 'c', 'synset': 'golfcart.n.01', 'synonyms': ['golfcart'], 'id': 505, 'def': 'a small motor vehicle in which golfers can ride between shots', 'name': 'golfcart'}, {'frequency': 'r', 'synset': 'gondola.n.02', 'synonyms': ['gondola_(boat)'], 'id': 506, 'def': 'long narrow flat-bottomed boat propelled by sculling; traditionally used on canals of Venice', 'name': 'gondola_(boat)'}, {'frequency': 'c', 'synset': 'goose.n.01', 'synonyms': ['goose'], 'id': 507, 'def': 'loud, web-footed long-necked aquatic birds usually larger than ducks', 'name': 'goose'}, {'frequency': 'r', 'synset': 'gorilla.n.01', 'synonyms': ['gorilla'], 'id': 508, 'def': 'largest ape', 'name': 'gorilla'}, {'frequency': 'r', 'synset': 'gourd.n.02', 'synonyms': ['gourd'], 'id': 509, 'def': 'any of numerous inedible fruits with hard rinds', 'name': 'gourd'}, {'frequency': 'f', 'synset': 'grape.n.01', 'synonyms': ['grape'], 'id': 510, 'def': 'any of various juicy fruit with green or purple skins; grow in clusters', 'name': 'grape'}, {'frequency': 'c', 'synset': 'grater.n.01', 'synonyms': ['grater'], 'id': 511, 'def': 'utensil with sharp perforations for shredding foods (as vegetables or cheese)', 'name': 'grater'}, {'frequency': 'c', 'synset': 'gravestone.n.01', 'synonyms': ['gravestone', 'headstone', 'tombstone'], 'id': 512, 'def': 'a stone that is used to mark a grave', 'name': 'gravestone'}, {'frequency': 'r', 'synset': 'gravy_boat.n.01', 'synonyms': ['gravy_boat', 'gravy_holder'], 'id': 513, 'def': 'a dish (often boat-shaped) for serving gravy or sauce', 'name': 'gravy_boat'}, {'frequency': 'f', 'synset': 'green_bean.n.02', 'synonyms': ['green_bean'], 'id': 514, 'def': 'a common bean plant cultivated for its slender green edible pods', 'name': 'green_bean'}, {'frequency': 'f', 'synset': 'green_onion.n.01', 'synonyms': ['green_onion', 'spring_onion', 'scallion'], 'id': 515, 'def': 'a young onion before the bulb has enlarged', 'name': 'green_onion'}, {'frequency': 'r', 'synset': 'griddle.n.01', 'synonyms': ['griddle'], 'id': 516, 'def': 'cooking utensil consisting of a flat heated surface on which food is cooked', 'name': 'griddle'}, {'frequency': 'f', 'synset': 'grill.n.02', 'synonyms': ['grill', 'grille', 'grillwork', 'radiator_grille'], 'id': 517, 'def': 'a framework of metal bars used as a partition or a grate', 'name': 'grill'}, {'frequency': 'r', 'synset': 'grits.n.01', 'synonyms': ['grits', 'hominy_grits'], 'id': 518, 'def': 'coarsely ground corn boiled as a breakfast dish', 'name': 'grits'}, {'frequency': 'c', 'synset': 'grizzly.n.01', 'synonyms': ['grizzly', 'grizzly_bear'], 'id': 519, 'def': 'powerful brownish-yellow bear of the uplands of western North America', 'name': 'grizzly'}, {'frequency': 'c', 'synset': 'grocery_bag.n.01', 'synonyms': ['grocery_bag'], 'id': 520, 'def': "a sack for holding customer's groceries", 'name': 'grocery_bag'}, {'frequency': 'f', 'synset': 'guitar.n.01', 'synonyms': ['guitar'], 'id': 521, 'def': 'a stringed instrument usually having six strings; played by strumming or plucking', 'name': 'guitar'}, {'frequency': 'c', 'synset': 'gull.n.02', 'synonyms': ['gull', 'seagull'], 'id': 522, 'def': 'mostly white aquatic bird having long pointed wings and short legs', 'name': 'gull'}, {'frequency': 'c', 'synset': 'gun.n.01', 'synonyms': ['gun'], 'id': 523, 'def': 'a weapon that discharges a bullet at high velocity from a metal tube', 'name': 'gun'}, {'frequency': 'f', 'synset': 'hairbrush.n.01', 'synonyms': ['hairbrush'], 'id': 524, 'def': "a brush used to groom a person's hair", 'name': 'hairbrush'}, {'frequency': 'c', 'synset': 'hairnet.n.01', 'synonyms': ['hairnet'], 'id': 525, 'def': 'a small net that someone wears over their hair to keep it in place', 'name': 'hairnet'}, {'frequency': 'c', 'synset': 'hairpin.n.01', 'synonyms': ['hairpin'], 'id': 526, 'def': "a double pronged pin used to hold women's hair in place", 'name': 'hairpin'}, {'frequency': 'r', 'synset': 'halter.n.03', 'synonyms': ['halter_top'], 'id': 527, 'def': "a woman's top that fastens behind the back and neck leaving the back and arms uncovered", 'name': 'halter_top'}, {'frequency': 'f', 'synset': 'ham.n.01', 'synonyms': ['ham', 'jambon', 'gammon'], 'id': 528, 'def': 'meat cut from the thigh of a hog (usually smoked)', 'name': 'ham'}, {'frequency': 'c', 'synset': 'hamburger.n.01', 'synonyms': ['hamburger', 'beefburger', 'burger'], 'id': 529, 'def': 'a sandwich consisting of a patty of minced beef served on a bun', 'name': 'hamburger'}, {'frequency': 'c', 'synset': 'hammer.n.02', 'synonyms': ['hammer'], 'id': 530, 'def': 'a hand tool with a heavy head and a handle; used to deliver an impulsive force by striking', 'name': 'hammer'}, {'frequency': 'c', 'synset': 'hammock.n.02', 'synonyms': ['hammock'], 'id': 531, 'def': 'a hanging bed of canvas or rope netting (usually suspended between two trees)', 'name': 'hammock'}, {'frequency': 'r', 'synset': 'hamper.n.02', 'synonyms': ['hamper'], 'id': 532, 'def': 'a basket usually with a cover', 'name': 'hamper'}, {'frequency': 'c', 'synset': 'hamster.n.01', 'synonyms': ['hamster'], 'id': 533, 'def': 'short-tailed burrowing rodent with large cheek pouches', 'name': 'hamster'}, {'frequency': 'f', 'synset': 'hand_blower.n.01', 'synonyms': ['hair_dryer'], 'id': 534, 'def': 'a hand-held electric blower that can blow warm air onto the hair', 'name': 'hair_dryer'}, {'frequency': 'r', 'synset': 'hand_glass.n.01', 'synonyms': ['hand_glass', 'hand_mirror'], 'id': 535, 'def': 'a mirror intended to be held in the hand', 'name': 'hand_glass'}, {'frequency': 'f', 'synset': 'hand_towel.n.01', 'synonyms': ['hand_towel', 'face_towel'], 'id': 536, 'def': 'a small towel used to dry the hands or face', 'name': 'hand_towel'}, {'frequency': 'c', 'synset': 'handcart.n.01', 'synonyms': ['handcart', 'pushcart', 'hand_truck'], 'id': 537, 'def': 'wheeled vehicle that can be pushed by a person', 'name': 'handcart'}, {'frequency': 'r', 'synset': 'handcuff.n.01', 'synonyms': ['handcuff'], 'id': 538, 'def': 'shackle that consists of a metal loop that can be locked around the wrist', 'name': 'handcuff'}, {'frequency': 'c', 'synset': 'handkerchief.n.01', 'synonyms': ['handkerchief'], 'id': 539, 'def': 'a square piece of cloth used for wiping the eyes or nose or as a costume accessory', 'name': 'handkerchief'}, {'frequency': 'f', 'synset': 'handle.n.01', 'synonyms': ['handle', 'grip', 'handgrip'], 'id': 540, 'def': 'the appendage to an object that is designed to be held in order to use or move it', 'name': 'handle'}, {'frequency': 'r', 'synset': 'handsaw.n.01', 'synonyms': ['handsaw', "carpenter's_saw"], 'id': 541, 'def': 'a saw used with one hand for cutting wood', 'name': 'handsaw'}, {'frequency': 'r', 'synset': 'hardback.n.01', 'synonyms': ['hardback_book', 'hardcover_book'], 'id': 542, 'def': 'a book with cardboard or cloth or leather covers', 'name': 'hardback_book'}, {'frequency': 'r', 'synset': 'harmonium.n.01', 'synonyms': ['harmonium', 'organ_(musical_instrument)', 'reed_organ_(musical_instrument)'], 'id': 543, 'def': 'a free-reed instrument in which air is forced through the reeds by bellows', 'name': 'harmonium'}, {'frequency': 'f', 'synset': 'hat.n.01', 'synonyms': ['hat'], 'id': 544, 'def': 'headwear that protects the head from bad weather, sun, or worn for fashion', 'name': 'hat'}, {'frequency': 'r', 'synset': 'hatbox.n.01', 'synonyms': ['hatbox'], 'id': 545, 'def': 'a round piece of luggage for carrying hats', 'name': 'hatbox'}, {'frequency': 'c', 'synset': 'head_covering.n.01', 'synonyms': ['veil'], 'id': 546, 'def': 'a garment that covers the head OR face', 'name': 'veil'}, {'frequency': 'f', 'synset': 'headband.n.01', 'synonyms': ['headband'], 'id': 547, 'def': 'a band worn around or over the head', 'name': 'headband'}, {'frequency': 'f', 'synset': 'headboard.n.01', 'synonyms': ['headboard'], 'id': 548, 'def': 'a vertical board or panel forming the head of a bedstead', 'name': 'headboard'}, {'frequency': 'f', 'synset': 'headlight.n.01', 'synonyms': ['headlight', 'headlamp'], 'id': 549, 'def': 'a powerful light with reflector; attached to the front of an automobile or locomotive', 'name': 'headlight'}, {'frequency': 'c', 'synset': 'headscarf.n.01', 'synonyms': ['headscarf'], 'id': 550, 'def': 'a kerchief worn over the head and tied under the chin', 'name': 'headscarf'}, {'frequency': 'r', 'synset': 'headset.n.01', 'synonyms': ['headset'], 'id': 551, 'def': 'receiver consisting of a pair of headphones', 'name': 'headset'}, {'frequency': 'c', 'synset': 'headstall.n.01', 'synonyms': ['headstall_(for_horses)', 'headpiece_(for_horses)'], 'id': 552, 'def': "the band that is the part of a bridle that fits around a horse's head", 'name': 'headstall_(for_horses)'}, {'frequency': 'c', 'synset': 'heart.n.02', 'synonyms': ['heart'], 'id': 553, 'def': 'a muscular organ; its contractions move the blood through the body', 'name': 'heart'}, {'frequency': 'c', 'synset': 'heater.n.01', 'synonyms': ['heater', 'warmer'], 'id': 554, 'def': 'device that heats water or supplies warmth to a room', 'name': 'heater'}, {'frequency': 'c', 'synset': 'helicopter.n.01', 'synonyms': ['helicopter'], 'id': 555, 'def': 'an aircraft without wings that obtains its lift from the rotation of overhead blades', 'name': 'helicopter'}, {'frequency': 'f', 'synset': 'helmet.n.02', 'synonyms': ['helmet'], 'id': 556, 'def': 'a protective headgear made of hard material to resist blows', 'name': 'helmet'}, {'frequency': 'r', 'synset': 'heron.n.02', 'synonyms': ['heron'], 'id': 557, 'def': 'grey or white wading bird with long neck and long legs and (usually) long bill', 'name': 'heron'}, {'frequency': 'c', 'synset': 'highchair.n.01', 'synonyms': ['highchair', 'feeding_chair'], 'id': 558, 'def': 'a chair for feeding a very young child', 'name': 'highchair'}, {'frequency': 'f', 'synset': 'hinge.n.01', 'synonyms': ['hinge'], 'id': 559, 'def': 'a joint that holds two parts together so that one can swing relative to the other', 'name': 'hinge'}, {'frequency': 'r', 'synset': 'hippopotamus.n.01', 'synonyms': ['hippopotamus'], 'id': 560, 'def': 'massive thick-skinned animal living in or around rivers of tropical Africa', 'name': 'hippopotamus'}, {'frequency': 'r', 'synset': 'hockey_stick.n.01', 'synonyms': ['hockey_stick'], 'id': 561, 'def': 'sports implement consisting of a stick used by hockey players to move the puck', 'name': 'hockey_stick'}, {'frequency': 'c', 'synset': 'hog.n.03', 'synonyms': ['hog', 'pig'], 'id': 562, 'def': 'domestic swine', 'name': 'hog'}, {'frequency': 'f', 'synset': 'home_plate.n.01', 'synonyms': ['home_plate_(baseball)', 'home_base_(baseball)'], 'id': 563, 'def': '(baseball) a rubber slab where the batter stands; it must be touched by a base runner in order to score', 'name': 'home_plate_(baseball)'}, {'frequency': 'c', 'synset': 'honey.n.01', 'synonyms': ['honey'], 'id': 564, 'def': 'a sweet yellow liquid produced by bees', 'name': 'honey'}, {'frequency': 'f', 'synset': 'hood.n.06', 'synonyms': ['fume_hood', 'exhaust_hood'], 'id': 565, 'def': 'metal covering leading to a vent that exhausts smoke or fumes', 'name': 'fume_hood'}, {'frequency': 'f', 'synset': 'hook.n.05', 'synonyms': ['hook'], 'id': 566, 'def': 'a curved or bent implement for suspending or pulling something', 'name': 'hook'}, {'frequency': 'r', 'synset': 'hookah.n.01', 'synonyms': ['hookah', 'narghile', 'nargileh', 'sheesha', 'shisha', 'water_pipe'], 'id': 567, 'def': 'a tobacco pipe with a long flexible tube connected to a container where the smoke is cooled by passing through water', 'name': 'hookah'}, {'frequency': 'r', 'synset': 'hornet.n.01', 'synonyms': ['hornet'], 'id': 568, 'def': 'large stinging wasp', 'name': 'hornet'}, {'frequency': 'f', 'synset': 'horse.n.01', 'synonyms': ['horse'], 'id': 569, 'def': 'a common horse', 'name': 'horse'}, {'frequency': 'f', 'synset': 'hose.n.03', 'synonyms': ['hose', 'hosepipe'], 'id': 570, 'def': 'a flexible pipe for conveying a liquid or gas', 'name': 'hose'}, {'frequency': 'r', 'synset': 'hot-air_balloon.n.01', 'synonyms': ['hot-air_balloon'], 'id': 571, 'def': 'balloon for travel through the air in a basket suspended below a large bag of heated air', 'name': 'hot-air_balloon'}, {'frequency': 'r', 'synset': 'hot_plate.n.01', 'synonyms': ['hotplate'], 'id': 572, 'def': 'a portable electric appliance for heating or cooking or keeping food warm', 'name': 'hotplate'}, {'frequency': 'c', 'synset': 'hot_sauce.n.01', 'synonyms': ['hot_sauce'], 'id': 573, 'def': 'a pungent peppery sauce', 'name': 'hot_sauce'}, {'frequency': 'r', 'synset': 'hourglass.n.01', 'synonyms': ['hourglass'], 'id': 574, 'def': 'a sandglass timer that runs for sixty minutes', 'name': 'hourglass'}, {'frequency': 'r', 'synset': 'houseboat.n.01', 'synonyms': ['houseboat'], 'id': 575, 'def': 'a barge that is designed and equipped for use as a dwelling', 'name': 'houseboat'}, {'frequency': 'c', 'synset': 'hummingbird.n.01', 'synonyms': ['hummingbird'], 'id': 576, 'def': 'tiny American bird having brilliant iridescent plumage and long slender bills', 'name': 'hummingbird'}, {'frequency': 'r', 'synset': 'hummus.n.01', 'synonyms': ['hummus', 'humus', 'hommos', 'hoummos', 'humous'], 'id': 577, 'def': 'a thick spread made from mashed chickpeas', 'name': 'hummus'}, {'frequency': 'f', 'synset': 'ice_bear.n.01', 'synonyms': ['polar_bear'], 'id': 578, 'def': 'white bear of Arctic regions', 'name': 'polar_bear'}, {'frequency': 'c', 'synset': 'ice_cream.n.01', 'synonyms': ['icecream'], 'id': 579, 'def': 'frozen dessert containing cream and sugar and flavoring', 'name': 'icecream'}, {'frequency': 'r', 'synset': 'ice_lolly.n.01', 'synonyms': ['popsicle'], 'id': 580, 'def': 'ice cream or water ice on a small wooden stick', 'name': 'popsicle'}, {'frequency': 'c', 'synset': 'ice_maker.n.01', 'synonyms': ['ice_maker'], 'id': 581, 'def': 'an appliance included in some electric refrigerators for making ice cubes', 'name': 'ice_maker'}, {'frequency': 'r', 'synset': 'ice_pack.n.01', 'synonyms': ['ice_pack', 'ice_bag'], 'id': 582, 'def': 'a waterproof bag filled with ice: applied to the body (especially the head) to cool or reduce swelling', 'name': 'ice_pack'}, {'frequency': 'r', 'synset': 'ice_skate.n.01', 'synonyms': ['ice_skate'], 'id': 583, 'def': 'skate consisting of a boot with a steel blade fitted to the sole', 'name': 'ice_skate'}, {'frequency': 'c', 'synset': 'igniter.n.01', 'synonyms': ['igniter', 'ignitor', 'lighter'], 'id': 584, 'def': 'a substance or device used to start a fire', 'name': 'igniter'}, {'frequency': 'r', 'synset': 'inhaler.n.01', 'synonyms': ['inhaler', 'inhalator'], 'id': 585, 'def': 'a dispenser that produces a chemical vapor to be inhaled through mouth or nose', 'name': 'inhaler'}, {'frequency': 'f', 'synset': 'ipod.n.01', 'synonyms': ['iPod'], 'id': 586, 'def': 'a pocket-sized device used to play music files', 'name': 'iPod'}, {'frequency': 'c', 'synset': 'iron.n.04', 'synonyms': ['iron_(for_clothing)', 'smoothing_iron_(for_clothing)'], 'id': 587, 'def': 'home appliance consisting of a flat metal base that is heated and used to smooth cloth', 'name': 'iron_(for_clothing)'}, {'frequency': 'c', 'synset': 'ironing_board.n.01', 'synonyms': ['ironing_board'], 'id': 588, 'def': 'narrow padded board on collapsible supports; used for ironing clothes', 'name': 'ironing_board'}, {'frequency': 'f', 'synset': 'jacket.n.01', 'synonyms': ['jacket'], 'id': 589, 'def': 'a waist-length coat', 'name': 'jacket'}, {'frequency': 'c', 'synset': 'jam.n.01', 'synonyms': ['jam'], 'id': 590, 'def': 'preserve of crushed fruit', 'name': 'jam'}, {'frequency': 'f', 'synset': 'jar.n.01', 'synonyms': ['jar'], 'id': 591, 'def': 'a vessel (usually cylindrical) with a wide mouth and without handles', 'name': 'jar'}, {'frequency': 'f', 'synset': 'jean.n.01', 'synonyms': ['jean', 'blue_jean', 'denim'], 'id': 592, 'def': '(usually plural) close-fitting trousers of heavy denim for manual work or casual wear', 'name': 'jean'}, {'frequency': 'c', 'synset': 'jeep.n.01', 'synonyms': ['jeep', 'landrover'], 'id': 593, 'def': 'a car suitable for traveling over rough terrain', 'name': 'jeep'}, {'frequency': 'r', 'synset': 'jelly_bean.n.01', 'synonyms': ['jelly_bean', 'jelly_egg'], 'id': 594, 'def': 'sugar-glazed jellied candy', 'name': 'jelly_bean'}, {'frequency': 'f', 'synset': 'jersey.n.03', 'synonyms': ['jersey', 'T-shirt', 'tee_shirt'], 'id': 595, 'def': 'a close-fitting pullover shirt', 'name': 'jersey'}, {'frequency': 'c', 'synset': 'jet.n.01', 'synonyms': ['jet_plane', 'jet-propelled_plane'], 'id': 596, 'def': 'an airplane powered by one or more jet engines', 'name': 'jet_plane'}, {'frequency': 'r', 'synset': 'jewel.n.01', 'synonyms': ['jewel', 'gem', 'precious_stone'], 'id': 597, 'def': 'a precious or semiprecious stone incorporated into a piece of jewelry', 'name': 'jewel'}, {'frequency': 'c', 'synset': 'jewelry.n.01', 'synonyms': ['jewelry', 'jewellery'], 'id': 598, 'def': 'an adornment (as a bracelet or ring or necklace) made of precious metals and set with gems (or imitation gems)', 'name': 'jewelry'}, {'frequency': 'r', 'synset': 'joystick.n.02', 'synonyms': ['joystick'], 'id': 599, 'def': 'a control device for computers consisting of a vertical handle that can move freely in two directions', 'name': 'joystick'}, {'frequency': 'c', 'synset': 'jump_suit.n.01', 'synonyms': ['jumpsuit'], 'id': 600, 'def': "one-piece garment fashioned after a parachutist's uniform", 'name': 'jumpsuit'}, {'frequency': 'c', 'synset': 'kayak.n.01', 'synonyms': ['kayak'], 'id': 601, 'def': 'a small canoe consisting of a light frame made watertight with animal skins', 'name': 'kayak'}, {'frequency': 'r', 'synset': 'keg.n.02', 'synonyms': ['keg'], 'id': 602, 'def': 'small cask or barrel', 'name': 'keg'}, {'frequency': 'r', 'synset': 'kennel.n.01', 'synonyms': ['kennel', 'doghouse'], 'id': 603, 'def': 'outbuilding that serves as a shelter for a dog', 'name': 'kennel'}, {'frequency': 'c', 'synset': 'kettle.n.01', 'synonyms': ['kettle', 'boiler'], 'id': 604, 'def': 'a metal pot for stewing or boiling; usually has a lid', 'name': 'kettle'}, {'frequency': 'f', 'synset': 'key.n.01', 'synonyms': ['key'], 'id': 605, 'def': 'metal instrument used to unlock a lock', 'name': 'key'}, {'frequency': 'r', 'synset': 'keycard.n.01', 'synonyms': ['keycard'], 'id': 606, 'def': 'a plastic card used to gain access typically to a door', 'name': 'keycard'}, {'frequency': 'c', 'synset': 'kilt.n.01', 'synonyms': ['kilt'], 'id': 607, 'def': 'a knee-length pleated tartan skirt worn by men as part of the traditional dress in the Highlands of northern Scotland', 'name': 'kilt'}, {'frequency': 'c', 'synset': 'kimono.n.01', 'synonyms': ['kimono'], 'id': 608, 'def': 'a loose robe; imitated from robes originally worn by Japanese', 'name': 'kimono'}, {'frequency': 'f', 'synset': 'kitchen_sink.n.01', 'synonyms': ['kitchen_sink'], 'id': 609, 'def': 'a sink in a kitchen', 'name': 'kitchen_sink'}, {'frequency': 'r', 'synset': 'kitchen_table.n.01', 'synonyms': ['kitchen_table'], 'id': 610, 'def': 'a table in the kitchen', 'name': 'kitchen_table'}, {'frequency': 'f', 'synset': 'kite.n.03', 'synonyms': ['kite'], 'id': 611, 'def': 'plaything consisting of a light frame covered with tissue paper; flown in wind at end of a string', 'name': 'kite'}, {'frequency': 'c', 'synset': 'kitten.n.01', 'synonyms': ['kitten', 'kitty'], 'id': 612, 'def': 'young domestic cat', 'name': 'kitten'}, {'frequency': 'c', 'synset': 'kiwi.n.03', 'synonyms': ['kiwi_fruit'], 'id': 613, 'def': 'fuzzy brown egg-shaped fruit with slightly tart green flesh', 'name': 'kiwi_fruit'}, {'frequency': 'f', 'synset': 'knee_pad.n.01', 'synonyms': ['knee_pad'], 'id': 614, 'def': 'protective garment consisting of a pad worn by football or baseball or hockey players', 'name': 'knee_pad'}, {'frequency': 'f', 'synset': 'knife.n.01', 'synonyms': ['knife'], 'id': 615, 'def': 'tool with a blade and point used as a cutting instrument', 'name': 'knife'}, {'frequency': 'r', 'synset': 'knitting_needle.n.01', 'synonyms': ['knitting_needle'], 'id': 616, 'def': 'needle consisting of a slender rod with pointed ends; usually used in pairs', 'name': 'knitting_needle'}, {'frequency': 'f', 'synset': 'knob.n.02', 'synonyms': ['knob'], 'id': 617, 'def': 'a round handle often found on a door', 'name': 'knob'}, {'frequency': 'r', 'synset': 'knocker.n.05', 'synonyms': ['knocker_(on_a_door)', 'doorknocker'], 'id': 618, 'def': 'a device (usually metal and ornamental) attached by a hinge to a door', 'name': 'knocker_(on_a_door)'}, {'frequency': 'r', 'synset': 'koala.n.01', 'synonyms': ['koala', 'koala_bear'], 'id': 619, 'def': 'sluggish tailless Australian marsupial with grey furry ears and coat', 'name': 'koala'}, {'frequency': 'r', 'synset': 'lab_coat.n.01', 'synonyms': ['lab_coat', 'laboratory_coat'], 'id': 620, 'def': 'a light coat worn to protect clothing from substances used while working in a laboratory', 'name': 'lab_coat'}, {'frequency': 'f', 'synset': 'ladder.n.01', 'synonyms': ['ladder'], 'id': 621, 'def': 'steps consisting of two parallel members connected by rungs', 'name': 'ladder'}, {'frequency': 'c', 'synset': 'ladle.n.01', 'synonyms': ['ladle'], 'id': 622, 'def': 'a spoon-shaped vessel with a long handle frequently used to transfer liquids', 'name': 'ladle'}, {'frequency': 'c', 'synset': 'ladybug.n.01', 'synonyms': ['ladybug', 'ladybeetle', 'ladybird_beetle'], 'id': 623, 'def': 'small round bright-colored and spotted beetle, typically red and black', 'name': 'ladybug'}, {'frequency': 'f', 'synset': 'lamb.n.01', 'synonyms': ['lamb_(animal)'], 'id': 624, 'def': 'young sheep', 'name': 'lamb_(animal)'}, {'frequency': 'r', 'synset': 'lamb_chop.n.01', 'synonyms': ['lamb-chop', 'lambchop'], 'id': 625, 'def': 'chop cut from a lamb', 'name': 'lamb-chop'}, {'frequency': 'f', 'synset': 'lamp.n.02', 'synonyms': ['lamp'], 'id': 626, 'def': 'a piece of furniture holding one or more electric light bulbs', 'name': 'lamp'}, {'frequency': 'f', 'synset': 'lamppost.n.01', 'synonyms': ['lamppost'], 'id': 627, 'def': 'a metal post supporting an outdoor lamp (such as a streetlight)', 'name': 'lamppost'}, {'frequency': 'f', 'synset': 'lampshade.n.01', 'synonyms': ['lampshade'], 'id': 628, 'def': 'a protective ornamental shade used to screen a light bulb from direct view', 'name': 'lampshade'}, {'frequency': 'c', 'synset': 'lantern.n.01', 'synonyms': ['lantern'], 'id': 629, 'def': 'light in a transparent protective case', 'name': 'lantern'}, {'frequency': 'f', 'synset': 'lanyard.n.02', 'synonyms': ['lanyard', 'laniard'], 'id': 630, 'def': 'a cord worn around the neck to hold a knife or whistle, etc.', 'name': 'lanyard'}, {'frequency': 'f', 'synset': 'laptop.n.01', 'synonyms': ['laptop_computer', 'notebook_computer'], 'id': 631, 'def': 'a portable computer small enough to use in your lap', 'name': 'laptop_computer'}, {'frequency': 'r', 'synset': 'lasagna.n.01', 'synonyms': ['lasagna', 'lasagne'], 'id': 632, 'def': 'baked dish of layers of lasagna pasta with sauce and cheese and meat or vegetables', 'name': 'lasagna'}, {'frequency': 'f', 'synset': 'latch.n.02', 'synonyms': ['latch'], 'id': 633, 'def': 'a bar that can be lowered or slid into a groove to fasten a door or gate', 'name': 'latch'}, {'frequency': 'r', 'synset': 'lawn_mower.n.01', 'synonyms': ['lawn_mower'], 'id': 634, 'def': 'garden tool for mowing grass on lawns', 'name': 'lawn_mower'}, {'frequency': 'r', 'synset': 'leather.n.01', 'synonyms': ['leather'], 'id': 635, 'def': 'an animal skin made smooth and flexible by removing the hair and then tanning', 'name': 'leather'}, {'frequency': 'c', 'synset': 'legging.n.01', 'synonyms': ['legging_(clothing)', 'leging_(clothing)', 'leg_covering'], 'id': 636, 'def': 'a garment covering the leg (usually extending from the knee to the ankle)', 'name': 'legging_(clothing)'}, {'frequency': 'c', 'synset': 'lego.n.01', 'synonyms': ['Lego', 'Lego_set'], 'id': 637, 'def': "a child's plastic construction set for making models from blocks", 'name': 'Lego'}, {'frequency': 'r', 'synset': 'legume.n.02', 'synonyms': ['legume'], 'id': 638, 'def': 'the fruit or seed of bean or pea plants', 'name': 'legume'}, {'frequency': 'f', 'synset': 'lemon.n.01', 'synonyms': ['lemon'], 'id': 639, 'def': 'yellow oval fruit with juicy acidic flesh', 'name': 'lemon'}, {'frequency': 'r', 'synset': 'lemonade.n.01', 'synonyms': ['lemonade'], 'id': 640, 'def': 'sweetened beverage of diluted lemon juice', 'name': 'lemonade'}, {'frequency': 'f', 'synset': 'lettuce.n.02', 'synonyms': ['lettuce'], 'id': 641, 'def': 'leafy plant commonly eaten in salad or on sandwiches', 'name': 'lettuce'}, {'frequency': 'f', 'synset': 'license_plate.n.01', 'synonyms': ['license_plate', 'numberplate'], 'id': 642, 'def': "a plate mounted on the front and back of car and bearing the car's registration number", 'name': 'license_plate'}, {'frequency': 'f', 'synset': 'life_buoy.n.01', 'synonyms': ['life_buoy', 'lifesaver', 'life_belt', 'life_ring'], 'id': 643, 'def': 'a ring-shaped life preserver used to prevent drowning (NOT a life-jacket or vest)', 'name': 'life_buoy'}, {'frequency': 'f', 'synset': 'life_jacket.n.01', 'synonyms': ['life_jacket', 'life_vest'], 'id': 644, 'def': 'life preserver consisting of a sleeveless jacket of buoyant or inflatable design', 'name': 'life_jacket'}, {'frequency': 'f', 'synset': 'light_bulb.n.01', 'synonyms': ['lightbulb'], 'id': 645, 'def': 'lightblub/source of light', 'name': 'lightbulb'}, {'frequency': 'r', 'synset': 'lightning_rod.n.02', 'synonyms': ['lightning_rod', 'lightning_conductor'], 'id': 646, 'def': 'a metallic conductor that is attached to a high point and leads to the ground', 'name': 'lightning_rod'}, {'frequency': 'f', 'synset': 'lime.n.06', 'synonyms': ['lime'], 'id': 647, 'def': 'the green acidic fruit of any of various lime trees', 'name': 'lime'}, {'frequency': 'r', 'synset': 'limousine.n.01', 'synonyms': ['limousine'], 'id': 648, 'def': 'long luxurious car; usually driven by a chauffeur', 'name': 'limousine'}, {'frequency': 'c', 'synset': 'lion.n.01', 'synonyms': ['lion'], 'id': 649, 'def': 'large gregarious predatory cat of Africa and India', 'name': 'lion'}, {'frequency': 'c', 'synset': 'lip_balm.n.01', 'synonyms': ['lip_balm'], 'id': 650, 'def': 'a balm applied to the lips', 'name': 'lip_balm'}, {'frequency': 'r', 'synset': 'liquor.n.01', 'synonyms': ['liquor', 'spirits', 'hard_liquor', 'liqueur', 'cordial'], 'id': 651, 'def': 'liquor or beer', 'name': 'liquor'}, {'frequency': 'c', 'synset': 'lizard.n.01', 'synonyms': ['lizard'], 'id': 652, 'def': 'a reptile with usually two pairs of legs and a tapering tail', 'name': 'lizard'}, {'frequency': 'f', 'synset': 'log.n.01', 'synonyms': ['log'], 'id': 653, 'def': 'a segment of the trunk of a tree when stripped of branches', 'name': 'log'}, {'frequency': 'c', 'synset': 'lollipop.n.02', 'synonyms': ['lollipop'], 'id': 654, 'def': 'hard candy on a stick', 'name': 'lollipop'}, {'frequency': 'f', 'synset': 'loudspeaker.n.01', 'synonyms': ['speaker_(stero_equipment)'], 'id': 655, 'def': 'electronic device that produces sound often as part of a stereo system', 'name': 'speaker_(stero_equipment)'}, {'frequency': 'c', 'synset': 'love_seat.n.01', 'synonyms': ['loveseat'], 'id': 656, 'def': 'small sofa that seats two people', 'name': 'loveseat'}, {'frequency': 'r', 'synset': 'machine_gun.n.01', 'synonyms': ['machine_gun'], 'id': 657, 'def': 'a rapidly firing automatic gun', 'name': 'machine_gun'}, {'frequency': 'f', 'synset': 'magazine.n.02', 'synonyms': ['magazine'], 'id': 658, 'def': 'a paperback periodic publication', 'name': 'magazine'}, {'frequency': 'f', 'synset': 'magnet.n.01', 'synonyms': ['magnet'], 'id': 659, 'def': 'a device that attracts iron and produces a magnetic field', 'name': 'magnet'}, {'frequency': 'c', 'synset': 'mail_slot.n.01', 'synonyms': ['mail_slot'], 'id': 660, 'def': 'a slot (usually in a door) through which mail can be delivered', 'name': 'mail_slot'}, {'frequency': 'f', 'synset': 'mailbox.n.01', 'synonyms': ['mailbox_(at_home)', 'letter_box_(at_home)'], 'id': 661, 'def': 'a private box for delivery of mail', 'name': 'mailbox_(at_home)'}, {'frequency': 'r', 'synset': 'mallard.n.01', 'synonyms': ['mallard'], 'id': 662, 'def': 'wild dabbling duck from which domestic ducks are descended', 'name': 'mallard'}, {'frequency': 'r', 'synset': 'mallet.n.01', 'synonyms': ['mallet'], 'id': 663, 'def': 'a sports implement with a long handle and a hammer-like head used to hit a ball', 'name': 'mallet'}, {'frequency': 'r', 'synset': 'mammoth.n.01', 'synonyms': ['mammoth'], 'id': 664, 'def': 'any of numerous extinct elephants widely distributed in the Pleistocene', 'name': 'mammoth'}, {'frequency': 'r', 'synset': 'manatee.n.01', 'synonyms': ['manatee'], 'id': 665, 'def': 'sirenian mammal of tropical coastal waters of America', 'name': 'manatee'}, {'frequency': 'c', 'synset': 'mandarin.n.05', 'synonyms': ['mandarin_orange'], 'id': 666, 'def': 'a somewhat flat reddish-orange loose skinned citrus of China', 'name': 'mandarin_orange'}, {'frequency': 'c', 'synset': 'manger.n.01', 'synonyms': ['manger', 'trough'], 'id': 667, 'def': 'a container (usually in a barn or stable) from which cattle or horses feed', 'name': 'manger'}, {'frequency': 'f', 'synset': 'manhole.n.01', 'synonyms': ['manhole'], 'id': 668, 'def': 'a hole (usually with a flush cover) through which a person can gain access to an underground structure', 'name': 'manhole'}, {'frequency': 'f', 'synset': 'map.n.01', 'synonyms': ['map'], 'id': 669, 'def': "a diagrammatic representation of the earth's surface (or part of it)", 'name': 'map'}, {'frequency': 'f', 'synset': 'marker.n.03', 'synonyms': ['marker'], 'id': 670, 'def': 'a writing implement for making a mark', 'name': 'marker'}, {'frequency': 'r', 'synset': 'martini.n.01', 'synonyms': ['martini'], 'id': 671, 'def': 'a cocktail made of gin (or vodka) with dry vermouth', 'name': 'martini'}, {'frequency': 'r', 'synset': 'mascot.n.01', 'synonyms': ['mascot'], 'id': 672, 'def': 'a person or animal that is adopted by a team or other group as a symbolic figure', 'name': 'mascot'}, {'frequency': 'c', 'synset': 'mashed_potato.n.01', 'synonyms': ['mashed_potato'], 'id': 673, 'def': 'potato that has been peeled and boiled and then mashed', 'name': 'mashed_potato'}, {'frequency': 'r', 'synset': 'masher.n.02', 'synonyms': ['masher'], 'id': 674, 'def': 'a kitchen utensil used for mashing (e.g. potatoes)', 'name': 'masher'}, {'frequency': 'f', 'synset': 'mask.n.04', 'synonyms': ['mask', 'facemask'], 'id': 675, 'def': 'a protective covering worn over the face', 'name': 'mask'}, {'frequency': 'f', 'synset': 'mast.n.01', 'synonyms': ['mast'], 'id': 676, 'def': 'a vertical spar for supporting sails', 'name': 'mast'}, {'frequency': 'c', 'synset': 'mat.n.03', 'synonyms': ['mat_(gym_equipment)', 'gym_mat'], 'id': 677, 'def': 'sports equipment consisting of a piece of thick padding on the floor for gymnastics', 'name': 'mat_(gym_equipment)'}, {'frequency': 'r', 'synset': 'matchbox.n.01', 'synonyms': ['matchbox'], 'id': 678, 'def': 'a box for holding matches', 'name': 'matchbox'}, {'frequency': 'f', 'synset': 'mattress.n.01', 'synonyms': ['mattress'], 'id': 679, 'def': 'a thick pad filled with resilient material used as a bed or part of a bed', 'name': 'mattress'}, {'frequency': 'c', 'synset': 'measuring_cup.n.01', 'synonyms': ['measuring_cup'], 'id': 680, 'def': 'graduated cup used to measure liquid or granular ingredients', 'name': 'measuring_cup'}, {'frequency': 'c', 'synset': 'measuring_stick.n.01', 'synonyms': ['measuring_stick', 'ruler_(measuring_stick)', 'measuring_rod'], 'id': 681, 'def': 'measuring instrument having a sequence of marks at regular intervals', 'name': 'measuring_stick'}, {'frequency': 'c', 'synset': 'meatball.n.01', 'synonyms': ['meatball'], 'id': 682, 'def': 'ground meat formed into a ball and fried or simmered in broth', 'name': 'meatball'}, {'frequency': 'c', 'synset': 'medicine.n.02', 'synonyms': ['medicine'], 'id': 683, 'def': 'something that treats or prevents or alleviates the symptoms of disease', 'name': 'medicine'}, {'frequency': 'c', 'synset': 'melon.n.01', 'synonyms': ['melon'], 'id': 684, 'def': 'fruit of the gourd family having a hard rind and sweet juicy flesh', 'name': 'melon'}, {'frequency': 'f', 'synset': 'microphone.n.01', 'synonyms': ['microphone'], 'id': 685, 'def': 'device for converting sound waves into electrical energy', 'name': 'microphone'}, {'frequency': 'r', 'synset': 'microscope.n.01', 'synonyms': ['microscope'], 'id': 686, 'def': 'magnifier of the image of small objects', 'name': 'microscope'}, {'frequency': 'f', 'synset': 'microwave.n.02', 'synonyms': ['microwave_oven'], 'id': 687, 'def': 'kitchen appliance that cooks food by passing an electromagnetic wave through it', 'name': 'microwave_oven'}, {'frequency': 'r', 'synset': 'milestone.n.01', 'synonyms': ['milestone', 'milepost'], 'id': 688, 'def': 'stone post at side of a road to show distances', 'name': 'milestone'}, {'frequency': 'f', 'synset': 'milk.n.01', 'synonyms': ['milk'], 'id': 689, 'def': 'a white nutritious liquid secreted by mammals and used as food by human beings', 'name': 'milk'}, {'frequency': 'r', 'synset': 'milk_can.n.01', 'synonyms': ['milk_can'], 'id': 690, 'def': 'can for transporting milk', 'name': 'milk_can'}, {'frequency': 'r', 'synset': 'milkshake.n.01', 'synonyms': ['milkshake'], 'id': 691, 'def': 'frothy drink of milk and flavoring and sometimes fruit or ice cream', 'name': 'milkshake'}, {'frequency': 'f', 'synset': 'minivan.n.01', 'synonyms': ['minivan'], 'id': 692, 'def': 'a small box-shaped passenger van', 'name': 'minivan'}, {'frequency': 'r', 'synset': 'mint.n.05', 'synonyms': ['mint_candy'], 'id': 693, 'def': 'a candy that is flavored with a mint oil', 'name': 'mint_candy'}, {'frequency': 'f', 'synset': 'mirror.n.01', 'synonyms': ['mirror'], 'id': 694, 'def': 'polished surface that forms images by reflecting light', 'name': 'mirror'}, {'frequency': 'c', 'synset': 'mitten.n.01', 'synonyms': ['mitten'], 'id': 695, 'def': 'glove that encases the thumb separately and the other four fingers together', 'name': 'mitten'}, {'frequency': 'c', 'synset': 'mixer.n.04', 'synonyms': ['mixer_(kitchen_tool)', 'stand_mixer'], 'id': 696, 'def': 'a kitchen utensil that is used for mixing foods', 'name': 'mixer_(kitchen_tool)'}, {'frequency': 'c', 'synset': 'money.n.03', 'synonyms': ['money'], 'id': 697, 'def': 'the official currency issued by a government or national bank', 'name': 'money'}, {'frequency': 'f', 'synset': 'monitor.n.04', 'synonyms': ['monitor_(computer_equipment) computer_monitor'], 'id': 698, 'def': 'a computer monitor', 'name': 'monitor_(computer_equipment) computer_monitor'}, {'frequency': 'c', 'synset': 'monkey.n.01', 'synonyms': ['monkey'], 'id': 699, 'def': 'any of various long-tailed primates', 'name': 'monkey'}, {'frequency': 'f', 'synset': 'motor.n.01', 'synonyms': ['motor'], 'id': 700, 'def': 'machine that converts other forms of energy into mechanical energy and so imparts motion', 'name': 'motor'}, {'frequency': 'f', 'synset': 'motor_scooter.n.01', 'synonyms': ['motor_scooter', 'scooter'], 'id': 701, 'def': 'a wheeled vehicle with small wheels and a low-powered engine', 'name': 'motor_scooter'}, {'frequency': 'r', 'synset': 'motor_vehicle.n.01', 'synonyms': ['motor_vehicle', 'automotive_vehicle'], 'id': 702, 'def': 'a self-propelled wheeled vehicle that does not run on rails', 'name': 'motor_vehicle'}, {'frequency': 'f', 'synset': 'motorcycle.n.01', 'synonyms': ['motorcycle'], 'id': 703, 'def': 'a motor vehicle with two wheels and a strong frame', 'name': 'motorcycle'}, {'frequency': 'f', 'synset': 'mound.n.01', 'synonyms': ['mound_(baseball)', "pitcher's_mound"], 'id': 704, 'def': '(baseball) the slight elevation on which the pitcher stands', 'name': 'mound_(baseball)'}, {'frequency': 'f', 'synset': 'mouse.n.04', 'synonyms': ['mouse_(computer_equipment)', 'computer_mouse'], 'id': 705, 'def': 'a computer input device that controls an on-screen pointer (does not include trackpads / touchpads)', 'name': 'mouse_(computer_equipment)'}, {'frequency': 'f', 'synset': 'mousepad.n.01', 'synonyms': ['mousepad'], 'id': 706, 'def': 'a small portable pad that provides an operating surface for a computer mouse', 'name': 'mousepad'}, {'frequency': 'c', 'synset': 'muffin.n.01', 'synonyms': ['muffin'], 'id': 707, 'def': 'a sweet quick bread baked in a cup-shaped pan', 'name': 'muffin'}, {'frequency': 'f', 'synset': 'mug.n.04', 'synonyms': ['mug'], 'id': 708, 'def': 'with handle and usually cylindrical', 'name': 'mug'}, {'frequency': 'f', 'synset': 'mushroom.n.02', 'synonyms': ['mushroom'], 'id': 709, 'def': 'a common mushroom', 'name': 'mushroom'}, {'frequency': 'r', 'synset': 'music_stool.n.01', 'synonyms': ['music_stool', 'piano_stool'], 'id': 710, 'def': 'a stool for piano players; usually adjustable in height', 'name': 'music_stool'}, {'frequency': 'c', 'synset': 'musical_instrument.n.01', 'synonyms': ['musical_instrument', 'instrument_(musical)'], 'id': 711, 'def': 'any of various devices or contrivances that can be used to produce musical tones or sounds', 'name': 'musical_instrument'}, {'frequency': 'r', 'synset': 'nailfile.n.01', 'synonyms': ['nailfile'], 'id': 712, 'def': 'a small flat file for shaping the nails', 'name': 'nailfile'}, {'frequency': 'f', 'synset': 'napkin.n.01', 'synonyms': ['napkin', 'table_napkin', 'serviette'], 'id': 713, 'def': 'a small piece of table linen or paper that is used to wipe the mouth and to cover the lap in order to protect clothing', 'name': 'napkin'}, {'frequency': 'r', 'synset': 'neckerchief.n.01', 'synonyms': ['neckerchief'], 'id': 714, 'def': 'a kerchief worn around the neck', 'name': 'neckerchief'}, {'frequency': 'f', 'synset': 'necklace.n.01', 'synonyms': ['necklace'], 'id': 715, 'def': 'jewelry consisting of a cord or chain (often bearing gems) worn about the neck as an ornament', 'name': 'necklace'}, {'frequency': 'f', 'synset': 'necktie.n.01', 'synonyms': ['necktie', 'tie_(necktie)'], 'id': 716, 'def': 'neckwear consisting of a long narrow piece of material worn under a collar and tied in knot at the front', 'name': 'necktie'}, {'frequency': 'c', 'synset': 'needle.n.03', 'synonyms': ['needle'], 'id': 717, 'def': 'a sharp pointed implement (usually metal)', 'name': 'needle'}, {'frequency': 'c', 'synset': 'nest.n.01', 'synonyms': ['nest'], 'id': 718, 'def': 'a structure in which animals lay eggs or give birth to their young', 'name': 'nest'}, {'frequency': 'f', 'synset': 'newspaper.n.01', 'synonyms': ['newspaper', 'paper_(newspaper)'], 'id': 719, 'def': 'a daily or weekly publication on folded sheets containing news, articles, and advertisements', 'name': 'newspaper'}, {'frequency': 'c', 'synset': 'newsstand.n.01', 'synonyms': ['newsstand'], 'id': 720, 'def': 'a stall where newspapers and other periodicals are sold', 'name': 'newsstand'}, {'frequency': 'c', 'synset': 'nightwear.n.01', 'synonyms': ['nightshirt', 'nightwear', 'sleepwear', 'nightclothes'], 'id': 721, 'def': 'garments designed to be worn in bed', 'name': 'nightshirt'}, {'frequency': 'r', 'synset': 'nosebag.n.01', 'synonyms': ['nosebag_(for_animals)', 'feedbag'], 'id': 722, 'def': 'a canvas bag that is used to feed an animal (such as a horse); covers the muzzle and fastens at the top of the head', 'name': 'nosebag_(for_animals)'}, {'frequency': 'c', 'synset': 'noseband.n.01', 'synonyms': ['noseband_(for_animals)', 'nosepiece_(for_animals)'], 'id': 723, 'def': "a strap that is the part of a bridle that goes over the animal's nose", 'name': 'noseband_(for_animals)'}, {'frequency': 'f', 'synset': 'notebook.n.01', 'synonyms': ['notebook'], 'id': 724, 'def': 'a book with blank pages for recording notes or memoranda', 'name': 'notebook'}, {'frequency': 'c', 'synset': 'notepad.n.01', 'synonyms': ['notepad'], 'id': 725, 'def': 'a pad of paper for keeping notes', 'name': 'notepad'}, {'frequency': 'f', 'synset': 'nut.n.03', 'synonyms': ['nut'], 'id': 726, 'def': 'a small metal block (usually square or hexagonal) with internal screw thread to be fitted onto a bolt', 'name': 'nut'}, {'frequency': 'r', 'synset': 'nutcracker.n.01', 'synonyms': ['nutcracker'], 'id': 727, 'def': 'a hand tool used to crack nuts open', 'name': 'nutcracker'}, {'frequency': 'f', 'synset': 'oar.n.01', 'synonyms': ['oar'], 'id': 728, 'def': 'an implement used to propel or steer a boat', 'name': 'oar'}, {'frequency': 'r', 'synset': 'octopus.n.01', 'synonyms': ['octopus_(food)'], 'id': 729, 'def': 'tentacles of octopus prepared as food', 'name': 'octopus_(food)'}, {'frequency': 'r', 'synset': 'octopus.n.02', 'synonyms': ['octopus_(animal)'], 'id': 730, 'def': 'bottom-living cephalopod having a soft oval body with eight long tentacles', 'name': 'octopus_(animal)'}, {'frequency': 'c', 'synset': 'oil_lamp.n.01', 'synonyms': ['oil_lamp', 'kerosene_lamp', 'kerosine_lamp'], 'id': 731, 'def': 'a lamp that burns oil (as kerosine) for light', 'name': 'oil_lamp'}, {'frequency': 'c', 'synset': 'olive_oil.n.01', 'synonyms': ['olive_oil'], 'id': 732, 'def': 'oil from olives', 'name': 'olive_oil'}, {'frequency': 'r', 'synset': 'omelet.n.01', 'synonyms': ['omelet', 'omelette'], 'id': 733, 'def': 'beaten eggs cooked until just set; may be folded around e.g. ham or cheese or jelly', 'name': 'omelet'}, {'frequency': 'f', 'synset': 'onion.n.01', 'synonyms': ['onion'], 'id': 734, 'def': 'the bulb of an onion plant', 'name': 'onion'}, {'frequency': 'f', 'synset': 'orange.n.01', 'synonyms': ['orange_(fruit)'], 'id': 735, 'def': 'orange (FRUIT of an orange tree)', 'name': 'orange_(fruit)'}, {'frequency': 'c', 'synset': 'orange_juice.n.01', 'synonyms': ['orange_juice'], 'id': 736, 'def': 'bottled or freshly squeezed juice of oranges', 'name': 'orange_juice'}, {'frequency': 'c', 'synset': 'ostrich.n.02', 'synonyms': ['ostrich'], 'id': 737, 'def': 'fast-running African flightless bird with two-toed feet; largest living bird', 'name': 'ostrich'}, {'frequency': 'f', 'synset': 'ottoman.n.03', 'synonyms': ['ottoman', 'pouf', 'pouffe', 'hassock'], 'id': 738, 'def': 'a thick standalone cushion used as a seat or footrest, often next to a chair', 'name': 'ottoman'}, {'frequency': 'f', 'synset': 'oven.n.01', 'synonyms': ['oven'], 'id': 739, 'def': 'kitchen appliance used for baking or roasting', 'name': 'oven'}, {'frequency': 'c', 'synset': 'overall.n.01', 'synonyms': ['overalls_(clothing)'], 'id': 740, 'def': 'work clothing consisting of denim trousers usually with a bib and shoulder straps', 'name': 'overalls_(clothing)'}, {'frequency': 'c', 'synset': 'owl.n.01', 'synonyms': ['owl'], 'id': 741, 'def': 'nocturnal bird of prey with hawk-like beak and claws and large head with front-facing eyes', 'name': 'owl'}, {'frequency': 'c', 'synset': 'packet.n.03', 'synonyms': ['packet'], 'id': 742, 'def': 'a small package or bundle', 'name': 'packet'}, {'frequency': 'r', 'synset': 'pad.n.03', 'synonyms': ['inkpad', 'inking_pad', 'stamp_pad'], 'id': 743, 'def': 'absorbent material saturated with ink used to transfer ink evenly to a rubber stamp', 'name': 'inkpad'}, {'frequency': 'c', 'synset': 'pad.n.04', 'synonyms': ['pad'], 'id': 744, 'def': 'mostly arm/knee pads labeled', 'name': 'pad'}, {'frequency': 'f', 'synset': 'paddle.n.04', 'synonyms': ['paddle', 'boat_paddle'], 'id': 745, 'def': 'a short light oar used without an oarlock to propel a canoe or small boat', 'name': 'paddle'}, {'frequency': 'c', 'synset': 'padlock.n.01', 'synonyms': ['padlock'], 'id': 746, 'def': 'a detachable, portable lock', 'name': 'padlock'}, {'frequency': 'c', 'synset': 'paintbrush.n.01', 'synonyms': ['paintbrush'], 'id': 747, 'def': 'a brush used as an applicator to apply paint', 'name': 'paintbrush'}, {'frequency': 'f', 'synset': 'painting.n.01', 'synonyms': ['painting'], 'id': 748, 'def': 'graphic art consisting of an artistic composition made by applying paints to a surface', 'name': 'painting'}, {'frequency': 'f', 'synset': 'pajama.n.02', 'synonyms': ['pajamas', 'pyjamas'], 'id': 749, 'def': 'loose-fitting nightclothes worn for sleeping or lounging', 'name': 'pajamas'}, {'frequency': 'c', 'synset': 'palette.n.02', 'synonyms': ['palette', 'pallet'], 'id': 750, 'def': 'board that provides a flat surface on which artists mix paints and the range of colors used', 'name': 'palette'}, {'frequency': 'f', 'synset': 'pan.n.01', 'synonyms': ['pan_(for_cooking)', 'cooking_pan'], 'id': 751, 'def': 'cooking utensil consisting of a wide metal vessel', 'name': 'pan_(for_cooking)'}, {'frequency': 'r', 'synset': 'pan.n.03', 'synonyms': ['pan_(metal_container)'], 'id': 752, 'def': 'shallow container made of metal', 'name': 'pan_(metal_container)'}, {'frequency': 'c', 'synset': 'pancake.n.01', 'synonyms': ['pancake'], 'id': 753, 'def': 'a flat cake of thin batter fried on both sides on a griddle', 'name': 'pancake'}, {'frequency': 'r', 'synset': 'pantyhose.n.01', 'synonyms': ['pantyhose'], 'id': 754, 'def': "a woman's tights consisting of underpants and stockings", 'name': 'pantyhose'}, {'frequency': 'r', 'synset': 'papaya.n.02', 'synonyms': ['papaya'], 'id': 755, 'def': 'large oval melon-like tropical fruit with yellowish flesh', 'name': 'papaya'}, {'frequency': 'f', 'synset': 'paper_plate.n.01', 'synonyms': ['paper_plate'], 'id': 756, 'def': 'a disposable plate made of cardboard', 'name': 'paper_plate'}, {'frequency': 'f', 'synset': 'paper_towel.n.01', 'synonyms': ['paper_towel'], 'id': 757, 'def': 'a disposable towel made of absorbent paper', 'name': 'paper_towel'}, {'frequency': 'r', 'synset': 'paperback_book.n.01', 'synonyms': ['paperback_book', 'paper-back_book', 'softback_book', 'soft-cover_book'], 'id': 758, 'def': 'a book with paper covers', 'name': 'paperback_book'}, {'frequency': 'r', 'synset': 'paperweight.n.01', 'synonyms': ['paperweight'], 'id': 759, 'def': 'a weight used to hold down a stack of papers', 'name': 'paperweight'}, {'frequency': 'c', 'synset': 'parachute.n.01', 'synonyms': ['parachute'], 'id': 760, 'def': 'rescue equipment consisting of a device that fills with air and retards your fall', 'name': 'parachute'}, {'frequency': 'c', 'synset': 'parakeet.n.01', 'synonyms': ['parakeet', 'parrakeet', 'parroket', 'paraquet', 'paroquet', 'parroquet'], 'id': 761, 'def': 'any of numerous small slender long-tailed parrots', 'name': 'parakeet'}, {'frequency': 'c', 'synset': 'parasail.n.01', 'synonyms': ['parasail_(sports)'], 'id': 762, 'def': 'parachute that will lift a person up into the air when it is towed by a motorboat or a car', 'name': 'parasail_(sports)'}, {'frequency': 'c', 'synset': 'parasol.n.01', 'synonyms': ['parasol', 'sunshade'], 'id': 763, 'def': 'a handheld collapsible source of shade', 'name': 'parasol'}, {'frequency': 'r', 'synset': 'parchment.n.01', 'synonyms': ['parchment'], 'id': 764, 'def': 'a superior paper resembling sheepskin', 'name': 'parchment'}, {'frequency': 'c', 'synset': 'parka.n.01', 'synonyms': ['parka', 'anorak'], 'id': 765, 'def': "a kind of heavy jacket (`windcheater' is a British term)", 'name': 'parka'}, {'frequency': 'f', 'synset': 'parking_meter.n.01', 'synonyms': ['parking_meter'], 'id': 766, 'def': 'a coin-operated timer located next to a parking space', 'name': 'parking_meter'}, {'frequency': 'c', 'synset': 'parrot.n.01', 'synonyms': ['parrot'], 'id': 767, 'def': 'usually brightly colored tropical birds with short hooked beaks and the ability to mimic sounds', 'name': 'parrot'}, {'frequency': 'c', 'synset': 'passenger_car.n.01', 'synonyms': ['passenger_car_(part_of_a_train)', 'coach_(part_of_a_train)'], 'id': 768, 'def': 'a railcar where passengers ride', 'name': 'passenger_car_(part_of_a_train)'}, {'frequency': 'r', 'synset': 'passenger_ship.n.01', 'synonyms': ['passenger_ship'], 'id': 769, 'def': 'a ship built to carry passengers', 'name': 'passenger_ship'}, {'frequency': 'c', 'synset': 'passport.n.02', 'synonyms': ['passport'], 'id': 770, 'def': 'a document issued by a country to a citizen allowing that person to travel abroad and re-enter the home country', 'name': 'passport'}, {'frequency': 'f', 'synset': 'pastry.n.02', 'synonyms': ['pastry'], 'id': 771, 'def': 'any of various baked foods made of dough or batter', 'name': 'pastry'}, {'frequency': 'r', 'synset': 'patty.n.01', 'synonyms': ['patty_(food)'], 'id': 772, 'def': 'small flat mass of chopped food', 'name': 'patty_(food)'}, {'frequency': 'c', 'synset': 'pea.n.01', 'synonyms': ['pea_(food)'], 'id': 773, 'def': 'seed of a pea plant used for food', 'name': 'pea_(food)'}, {'frequency': 'c', 'synset': 'peach.n.03', 'synonyms': ['peach'], 'id': 774, 'def': 'downy juicy fruit with sweet yellowish or whitish flesh', 'name': 'peach'}, {'frequency': 'c', 'synset': 'peanut_butter.n.01', 'synonyms': ['peanut_butter'], 'id': 775, 'def': 'a spread made from ground peanuts', 'name': 'peanut_butter'}, {'frequency': 'f', 'synset': 'pear.n.01', 'synonyms': ['pear'], 'id': 776, 'def': 'sweet juicy gritty-textured fruit available in many varieties', 'name': 'pear'}, {'frequency': 'c', 'synset': 'peeler.n.03', 'synonyms': ['peeler_(tool_for_fruit_and_vegetables)'], 'id': 777, 'def': 'a device for peeling vegetables or fruits', 'name': 'peeler_(tool_for_fruit_and_vegetables)'}, {'frequency': 'r', 'synset': 'peg.n.04', 'synonyms': ['wooden_leg', 'pegleg'], 'id': 778, 'def': 'a prosthesis that replaces a missing leg', 'name': 'wooden_leg'}, {'frequency': 'r', 'synset': 'pegboard.n.01', 'synonyms': ['pegboard'], 'id': 779, 'def': 'a board perforated with regularly spaced holes into which pegs can be fitted', 'name': 'pegboard'}, {'frequency': 'c', 'synset': 'pelican.n.01', 'synonyms': ['pelican'], 'id': 780, 'def': 'large long-winged warm-water seabird having a large bill with a distensible pouch for fish', 'name': 'pelican'}, {'frequency': 'f', 'synset': 'pen.n.01', 'synonyms': ['pen'], 'id': 781, 'def': 'a writing implement with a point from which ink flows', 'name': 'pen'}, {'frequency': 'f', 'synset': 'pencil.n.01', 'synonyms': ['pencil'], 'id': 782, 'def': 'a thin cylindrical pointed writing implement made of wood and graphite', 'name': 'pencil'}, {'frequency': 'r', 'synset': 'pencil_box.n.01', 'synonyms': ['pencil_box', 'pencil_case'], 'id': 783, 'def': 'a box for holding pencils', 'name': 'pencil_box'}, {'frequency': 'r', 'synset': 'pencil_sharpener.n.01', 'synonyms': ['pencil_sharpener'], 'id': 784, 'def': 'a rotary implement for sharpening the point on pencils', 'name': 'pencil_sharpener'}, {'frequency': 'r', 'synset': 'pendulum.n.01', 'synonyms': ['pendulum'], 'id': 785, 'def': 'an apparatus consisting of an object mounted so that it swings freely under the influence of gravity', 'name': 'pendulum'}, {'frequency': 'c', 'synset': 'penguin.n.01', 'synonyms': ['penguin'], 'id': 786, 'def': 'short-legged flightless birds of cold southern regions having webbed feet and wings modified as flippers', 'name': 'penguin'}, {'frequency': 'r', 'synset': 'pennant.n.02', 'synonyms': ['pennant'], 'id': 787, 'def': 'a flag longer than it is wide (and often tapering)', 'name': 'pennant'}, {'frequency': 'r', 'synset': 'penny.n.02', 'synonyms': ['penny_(coin)'], 'id': 788, 'def': 'a coin worth one-hundredth of the value of the basic unit', 'name': 'penny_(coin)'}, {'frequency': 'f', 'synset': 'pepper.n.03', 'synonyms': ['pepper', 'peppercorn'], 'id': 789, 'def': 'pungent seasoning from the berry of the common pepper plant; whole or ground', 'name': 'pepper'}, {'frequency': 'c', 'synset': 'pepper_mill.n.01', 'synonyms': ['pepper_mill', 'pepper_grinder'], 'id': 790, 'def': 'a mill for grinding pepper', 'name': 'pepper_mill'}, {'frequency': 'c', 'synset': 'perfume.n.02', 'synonyms': ['perfume'], 'id': 791, 'def': 'a toiletry that emits and diffuses a fragrant odor', 'name': 'perfume'}, {'frequency': 'r', 'synset': 'persimmon.n.02', 'synonyms': ['persimmon'], 'id': 792, 'def': 'orange fruit resembling a plum; edible when fully ripe', 'name': 'persimmon'}, {'frequency': 'f', 'synset': 'person.n.01', 'synonyms': ['person', 'baby', 'child', 'boy', 'girl', 'man', 'woman', 'human'], 'id': 793, 'def': 'a human being', 'name': 'person'}, {'frequency': 'c', 'synset': 'pet.n.01', 'synonyms': ['pet'], 'id': 794, 'def': 'a domesticated animal kept for companionship or amusement', 'name': 'pet'}, {'frequency': 'c', 'synset': 'pew.n.01', 'synonyms': ['pew_(church_bench)', 'church_bench'], 'id': 795, 'def': 'long bench with backs; used in church by the congregation', 'name': 'pew_(church_bench)'}, {'frequency': 'r', 'synset': 'phonebook.n.01', 'synonyms': ['phonebook', 'telephone_book', 'telephone_directory'], 'id': 796, 'def': 'a directory containing an alphabetical list of telephone subscribers and their telephone numbers', 'name': 'phonebook'}, {'frequency': 'c', 'synset': 'phonograph_record.n.01', 'synonyms': ['phonograph_record', 'phonograph_recording', 'record_(phonograph_recording)'], 'id': 797, 'def': 'sound recording consisting of a typically black disk with a continuous groove', 'name': 'phonograph_record'}, {'frequency': 'f', 'synset': 'piano.n.01', 'synonyms': ['piano'], 'id': 798, 'def': 'a keyboard instrument that is played by depressing keys that cause hammers to strike tuned strings and produce sounds', 'name': 'piano'}, {'frequency': 'f', 'synset': 'pickle.n.01', 'synonyms': ['pickle'], 'id': 799, 'def': 'vegetables (especially cucumbers) preserved in brine or vinegar', 'name': 'pickle'}, {'frequency': 'f', 'synset': 'pickup.n.01', 'synonyms': ['pickup_truck'], 'id': 800, 'def': 'a light truck with an open body and low sides and a tailboard', 'name': 'pickup_truck'}, {'frequency': 'c', 'synset': 'pie.n.01', 'synonyms': ['pie'], 'id': 801, 'def': 'dish baked in pastry-lined pan often with a pastry top', 'name': 'pie'}, {'frequency': 'c', 'synset': 'pigeon.n.01', 'synonyms': ['pigeon'], 'id': 802, 'def': 'wild and domesticated birds having a heavy body and short legs', 'name': 'pigeon'}, {'frequency': 'r', 'synset': 'piggy_bank.n.01', 'synonyms': ['piggy_bank', 'penny_bank'], 'id': 803, 'def': "a child's coin bank (often shaped like a pig)", 'name': 'piggy_bank'}, {'frequency': 'f', 'synset': 'pillow.n.01', 'synonyms': ['pillow'], 'id': 804, 'def': 'a cushion to support the head of a sleeping person', 'name': 'pillow'}, {'frequency': 'r', 'synset': 'pin.n.09', 'synonyms': ['pin_(non_jewelry)'], 'id': 805, 'def': 'a small slender (often pointed) piece of wood or metal used to support or fasten or attach things', 'name': 'pin_(non_jewelry)'}, {'frequency': 'f', 'synset': 'pineapple.n.02', 'synonyms': ['pineapple'], 'id': 806, 'def': 'large sweet fleshy tropical fruit with a tuft of stiff leaves', 'name': 'pineapple'}, {'frequency': 'c', 'synset': 'pinecone.n.01', 'synonyms': ['pinecone'], 'id': 807, 'def': 'the seed-producing cone of a pine tree', 'name': 'pinecone'}, {'frequency': 'r', 'synset': 'ping-pong_ball.n.01', 'synonyms': ['ping-pong_ball'], 'id': 808, 'def': 'light hollow ball used in playing table tennis', 'name': 'ping-pong_ball'}, {'frequency': 'r', 'synset': 'pinwheel.n.03', 'synonyms': ['pinwheel'], 'id': 809, 'def': 'a toy consisting of vanes of colored paper or plastic that is pinned to a stick and spins when it is pointed into the wind', 'name': 'pinwheel'}, {'frequency': 'r', 'synset': 'pipe.n.01', 'synonyms': ['tobacco_pipe'], 'id': 810, 'def': 'a tube with a small bowl at one end; used for smoking tobacco', 'name': 'tobacco_pipe'}, {'frequency': 'f', 'synset': 'pipe.n.02', 'synonyms': ['pipe', 'piping'], 'id': 811, 'def': 'a long tube made of metal or plastic that is used to carry water or oil or gas etc.', 'name': 'pipe'}, {'frequency': 'r', 'synset': 'pistol.n.01', 'synonyms': ['pistol', 'handgun'], 'id': 812, 'def': 'a firearm that is held and fired with one hand', 'name': 'pistol'}, {'frequency': 'c', 'synset': 'pita.n.01', 'synonyms': ['pita_(bread)', 'pocket_bread'], 'id': 813, 'def': 'usually small round bread that can open into a pocket for filling', 'name': 'pita_(bread)'}, {'frequency': 'f', 'synset': 'pitcher.n.02', 'synonyms': ['pitcher_(vessel_for_liquid)', 'ewer'], 'id': 814, 'def': 'an open vessel with a handle and a spout for pouring', 'name': 'pitcher_(vessel_for_liquid)'}, {'frequency': 'r', 'synset': 'pitchfork.n.01', 'synonyms': ['pitchfork'], 'id': 815, 'def': 'a long-handled hand tool with sharp widely spaced prongs for lifting and pitching hay', 'name': 'pitchfork'}, {'frequency': 'f', 'synset': 'pizza.n.01', 'synonyms': ['pizza'], 'id': 816, 'def': 'Italian open pie made of thin bread dough spread with a spiced mixture of e.g. tomato sauce and cheese', 'name': 'pizza'}, {'frequency': 'f', 'synset': 'place_mat.n.01', 'synonyms': ['place_mat'], 'id': 817, 'def': 'a mat placed on a table for an individual place setting', 'name': 'place_mat'}, {'frequency': 'f', 'synset': 'plate.n.04', 'synonyms': ['plate'], 'id': 818, 'def': 'dish on which food is served or from which food is eaten', 'name': 'plate'}, {'frequency': 'c', 'synset': 'platter.n.01', 'synonyms': ['platter'], 'id': 819, 'def': 'a large shallow dish used for serving food', 'name': 'platter'}, {'frequency': 'r', 'synset': 'playpen.n.01', 'synonyms': ['playpen'], 'id': 820, 'def': 'a portable enclosure in which babies may be left to play', 'name': 'playpen'}, {'frequency': 'c', 'synset': 'pliers.n.01', 'synonyms': ['pliers', 'plyers'], 'id': 821, 'def': 'a gripping hand tool with two hinged arms and (usually) serrated jaws', 'name': 'pliers'}, {'frequency': 'r', 'synset': 'plow.n.01', 'synonyms': ['plow_(farm_equipment)', 'plough_(farm_equipment)'], 'id': 822, 'def': 'a farm tool having one or more heavy blades to break the soil and cut a furrow prior to sowing', 'name': 'plow_(farm_equipment)'}, {'frequency': 'r', 'synset': 'plume.n.02', 'synonyms': ['plume'], 'id': 823, 'def': 'a feather or cluster of feathers worn as an ornament', 'name': 'plume'}, {'frequency': 'r', 'synset': 'pocket_watch.n.01', 'synonyms': ['pocket_watch'], 'id': 824, 'def': 'a watch that is carried in a small watch pocket', 'name': 'pocket_watch'}, {'frequency': 'c', 'synset': 'pocketknife.n.01', 'synonyms': ['pocketknife'], 'id': 825, 'def': 'a knife with a blade that folds into the handle; suitable for carrying in the pocket', 'name': 'pocketknife'}, {'frequency': 'c', 'synset': 'poker.n.01', 'synonyms': ['poker_(fire_stirring_tool)', 'stove_poker', 'fire_hook'], 'id': 826, 'def': 'fire iron consisting of a metal rod with a handle; used to stir a fire', 'name': 'poker_(fire_stirring_tool)'}, {'frequency': 'f', 'synset': 'pole.n.01', 'synonyms': ['pole', 'post'], 'id': 827, 'def': 'a long (usually round) rod of wood or metal or plastic', 'name': 'pole'}, {'frequency': 'f', 'synset': 'polo_shirt.n.01', 'synonyms': ['polo_shirt', 'sport_shirt'], 'id': 828, 'def': 'a shirt with short sleeves designed for comfort and casual wear', 'name': 'polo_shirt'}, {'frequency': 'r', 'synset': 'poncho.n.01', 'synonyms': ['poncho'], 'id': 829, 'def': 'a blanket-like cloak with a hole in the center for the head', 'name': 'poncho'}, {'frequency': 'c', 'synset': 'pony.n.05', 'synonyms': ['pony'], 'id': 830, 'def': 'any of various breeds of small gentle horses usually less than five feet high at the shoulder', 'name': 'pony'}, {'frequency': 'r', 'synset': 'pool_table.n.01', 'synonyms': ['pool_table', 'billiard_table', 'snooker_table'], 'id': 831, 'def': 'game equipment consisting of a heavy table on which pool is played', 'name': 'pool_table'}, {'frequency': 'f', 'synset': 'pop.n.02', 'synonyms': ['pop_(soda)', 'soda_(pop)', 'tonic', 'soft_drink'], 'id': 832, 'def': 'a sweet drink containing carbonated water and flavoring', 'name': 'pop_(soda)'}, {'frequency': 'c', 'synset': 'postbox.n.01', 'synonyms': ['postbox_(public)', 'mailbox_(public)'], 'id': 833, 'def': 'public box for deposit of mail', 'name': 'postbox_(public)'}, {'frequency': 'c', 'synset': 'postcard.n.01', 'synonyms': ['postcard', 'postal_card', 'mailing-card'], 'id': 834, 'def': 'a card for sending messages by post without an envelope', 'name': 'postcard'}, {'frequency': 'f', 'synset': 'poster.n.01', 'synonyms': ['poster', 'placard'], 'id': 835, 'def': 'a sign posted in a public place as an advertisement', 'name': 'poster'}, {'frequency': 'f', 'synset': 'pot.n.01', 'synonyms': ['pot'], 'id': 836, 'def': 'metal or earthenware cooking vessel that is usually round and deep; often has a handle and lid', 'name': 'pot'}, {'frequency': 'f', 'synset': 'pot.n.04', 'synonyms': ['flowerpot'], 'id': 837, 'def': 'a container in which plants are cultivated', 'name': 'flowerpot'}, {'frequency': 'f', 'synset': 'potato.n.01', 'synonyms': ['potato'], 'id': 838, 'def': 'an edible tuber native to South America', 'name': 'potato'}, {'frequency': 'c', 'synset': 'potholder.n.01', 'synonyms': ['potholder'], 'id': 839, 'def': 'an insulated pad for holding hot pots', 'name': 'potholder'}, {'frequency': 'c', 'synset': 'pottery.n.01', 'synonyms': ['pottery', 'clayware'], 'id': 840, 'def': 'ceramic ware made from clay and baked in a kiln', 'name': 'pottery'}, {'frequency': 'c', 'synset': 'pouch.n.01', 'synonyms': ['pouch'], 'id': 841, 'def': 'a small or medium size container for holding or carrying things', 'name': 'pouch'}, {'frequency': 'c', 'synset': 'power_shovel.n.01', 'synonyms': ['power_shovel', 'excavator', 'digger'], 'id': 842, 'def': 'a machine for excavating', 'name': 'power_shovel'}, {'frequency': 'c', 'synset': 'prawn.n.01', 'synonyms': ['prawn', 'shrimp'], 'id': 843, 'def': 'any of various edible decapod crustaceans', 'name': 'prawn'}, {'frequency': 'c', 'synset': 'pretzel.n.01', 'synonyms': ['pretzel'], 'id': 844, 'def': 'glazed and salted cracker typically in the shape of a loose knot', 'name': 'pretzel'}, {'frequency': 'f', 'synset': 'printer.n.03', 'synonyms': ['printer', 'printing_machine'], 'id': 845, 'def': 'a machine that prints', 'name': 'printer'}, {'frequency': 'c', 'synset': 'projectile.n.01', 'synonyms': ['projectile_(weapon)', 'missile'], 'id': 846, 'def': 'a weapon that is forcibly thrown or projected at a targets', 'name': 'projectile_(weapon)'}, {'frequency': 'c', 'synset': 'projector.n.02', 'synonyms': ['projector'], 'id': 847, 'def': 'an optical instrument that projects an enlarged image onto a screen', 'name': 'projector'}, {'frequency': 'f', 'synset': 'propeller.n.01', 'synonyms': ['propeller', 'propellor'], 'id': 848, 'def': 'a mechanical device that rotates to push against air or water', 'name': 'propeller'}, {'frequency': 'r', 'synset': 'prune.n.01', 'synonyms': ['prune'], 'id': 849, 'def': 'dried plum', 'name': 'prune'}, {'frequency': 'r', 'synset': 'pudding.n.01', 'synonyms': ['pudding'], 'id': 850, 'def': 'any of various soft thick unsweetened baked dishes', 'name': 'pudding'}, {'frequency': 'r', 'synset': 'puffer.n.02', 'synonyms': ['puffer_(fish)', 'pufferfish', 'blowfish', 'globefish'], 'id': 851, 'def': 'fishes whose elongated spiny body can inflate itself with water or air to form a globe', 'name': 'puffer_(fish)'}, {'frequency': 'r', 'synset': 'puffin.n.01', 'synonyms': ['puffin'], 'id': 852, 'def': 'seabirds having short necks and brightly colored compressed bills', 'name': 'puffin'}, {'frequency': 'r', 'synset': 'pug.n.01', 'synonyms': ['pug-dog'], 'id': 853, 'def': 'small compact smooth-coated breed of Asiatic origin having a tightly curled tail and broad flat wrinkled muzzle', 'name': 'pug-dog'}, {'frequency': 'c', 'synset': 'pumpkin.n.02', 'synonyms': ['pumpkin'], 'id': 854, 'def': 'usually large pulpy deep-yellow round fruit of the squash family maturing in late summer or early autumn', 'name': 'pumpkin'}, {'frequency': 'r', 'synset': 'punch.n.03', 'synonyms': ['puncher'], 'id': 855, 'def': 'a tool for making holes or indentations', 'name': 'puncher'}, {'frequency': 'r', 'synset': 'puppet.n.01', 'synonyms': ['puppet', 'marionette'], 'id': 856, 'def': 'a small figure of a person operated from above with strings by a puppeteer', 'name': 'puppet'}, {'frequency': 'c', 'synset': 'puppy.n.01', 'synonyms': ['puppy'], 'id': 857, 'def': 'a young dog', 'name': 'puppy'}, {'frequency': 'r', 'synset': 'quesadilla.n.01', 'synonyms': ['quesadilla'], 'id': 858, 'def': 'a tortilla that is filled with cheese and heated', 'name': 'quesadilla'}, {'frequency': 'r', 'synset': 'quiche.n.02', 'synonyms': ['quiche'], 'id': 859, 'def': 'a tart filled with rich unsweetened custard; often contains other ingredients (as cheese or ham or seafood or vegetables)', 'name': 'quiche'}, {'frequency': 'f', 'synset': 'quilt.n.01', 'synonyms': ['quilt', 'comforter'], 'id': 860, 'def': 'bedding made of two layers of cloth filled with stuffing and stitched together', 'name': 'quilt'}, {'frequency': 'c', 'synset': 'rabbit.n.01', 'synonyms': ['rabbit'], 'id': 861, 'def': 'any of various burrowing animals of the family Leporidae having long ears and short tails', 'name': 'rabbit'}, {'frequency': 'r', 'synset': 'racer.n.02', 'synonyms': ['race_car', 'racing_car'], 'id': 862, 'def': 'a fast car that competes in races', 'name': 'race_car'}, {'frequency': 'c', 'synset': 'racket.n.04', 'synonyms': ['racket', 'racquet'], 'id': 863, 'def': 'a sports implement used to strike a ball in various games', 'name': 'racket'}, {'frequency': 'r', 'synset': 'radar.n.01', 'synonyms': ['radar'], 'id': 864, 'def': 'measuring instrument in which the echo of a pulse of microwave radiation is used to detect and locate distant objects', 'name': 'radar'}, {'frequency': 'f', 'synset': 'radiator.n.03', 'synonyms': ['radiator'], 'id': 865, 'def': 'a mechanism consisting of a metal honeycomb through which hot fluids circulate', 'name': 'radiator'}, {'frequency': 'c', 'synset': 'radio_receiver.n.01', 'synonyms': ['radio_receiver', 'radio_set', 'radio', 'tuner_(radio)'], 'id': 866, 'def': 'an electronic receiver that detects and demodulates and amplifies transmitted radio signals', 'name': 'radio_receiver'}, {'frequency': 'c', 'synset': 'radish.n.03', 'synonyms': ['radish', 'daikon'], 'id': 867, 'def': 'pungent edible root of any of various cultivated radish plants', 'name': 'radish'}, {'frequency': 'c', 'synset': 'raft.n.01', 'synonyms': ['raft'], 'id': 868, 'def': 'a flat float (usually made of logs or planks) that can be used for transport or as a platform for swimmers', 'name': 'raft'}, {'frequency': 'r', 'synset': 'rag_doll.n.01', 'synonyms': ['rag_doll'], 'id': 869, 'def': 'a cloth doll that is stuffed and (usually) painted', 'name': 'rag_doll'}, {'frequency': 'c', 'synset': 'raincoat.n.01', 'synonyms': ['raincoat', 'waterproof_jacket'], 'id': 870, 'def': 'a water-resistant coat', 'name': 'raincoat'}, {'frequency': 'c', 'synset': 'ram.n.05', 'synonyms': ['ram_(animal)'], 'id': 871, 'def': 'uncastrated adult male sheep', 'name': 'ram_(animal)'}, {'frequency': 'c', 'synset': 'raspberry.n.02', 'synonyms': ['raspberry'], 'id': 872, 'def': 'red or black edible aggregate berries usually smaller than the related blackberries', 'name': 'raspberry'}, {'frequency': 'r', 'synset': 'rat.n.01', 'synonyms': ['rat'], 'id': 873, 'def': 'any of various long-tailed rodents similar to but larger than a mouse', 'name': 'rat'}, {'frequency': 'c', 'synset': 'razorblade.n.01', 'synonyms': ['razorblade'], 'id': 874, 'def': 'a blade that has very sharp edge', 'name': 'razorblade'}, {'frequency': 'c', 'synset': 'reamer.n.01', 'synonyms': ['reamer_(juicer)', 'juicer', 'juice_reamer'], 'id': 875, 'def': 'a squeezer with a conical ridged center that is used for squeezing juice from citrus fruit', 'name': 'reamer_(juicer)'}, {'frequency': 'f', 'synset': 'rearview_mirror.n.01', 'synonyms': ['rearview_mirror'], 'id': 876, 'def': 'vehicle mirror (side or rearview)', 'name': 'rearview_mirror'}, {'frequency': 'c', 'synset': 'receipt.n.02', 'synonyms': ['receipt'], 'id': 877, 'def': 'an acknowledgment (usually tangible) that payment has been made', 'name': 'receipt'}, {'frequency': 'c', 'synset': 'recliner.n.01', 'synonyms': ['recliner', 'reclining_chair', 'lounger_(chair)'], 'id': 878, 'def': 'an armchair whose back can be lowered and foot can be raised to allow the sitter to recline in it', 'name': 'recliner'}, {'frequency': 'c', 'synset': 'record_player.n.01', 'synonyms': ['record_player', 'phonograph_(record_player)', 'turntable'], 'id': 879, 'def': 'machine in which rotating records cause a stylus to vibrate and the vibrations are amplified acoustically or electronically', 'name': 'record_player'}, {'frequency': 'f', 'synset': 'reflector.n.01', 'synonyms': ['reflector'], 'id': 880, 'def': 'device that reflects light, radiation, etc.', 'name': 'reflector'}, {'frequency': 'f', 'synset': 'remote_control.n.01', 'synonyms': ['remote_control'], 'id': 881, 'def': 'a device that can be used to control a machine or apparatus from a distance', 'name': 'remote_control'}, {'frequency': 'c', 'synset': 'rhinoceros.n.01', 'synonyms': ['rhinoceros'], 'id': 882, 'def': 'massive powerful herbivorous odd-toed ungulate of southeast Asia and Africa having very thick skin and one or two horns on the snout', 'name': 'rhinoceros'}, {'frequency': 'r', 'synset': 'rib.n.03', 'synonyms': ['rib_(food)'], 'id': 883, 'def': 'cut of meat including one or more ribs', 'name': 'rib_(food)'}, {'frequency': 'c', 'synset': 'rifle.n.01', 'synonyms': ['rifle'], 'id': 884, 'def': 'a shoulder firearm with a long barrel', 'name': 'rifle'}, {'frequency': 'f', 'synset': 'ring.n.08', 'synonyms': ['ring'], 'id': 885, 'def': 'jewelry consisting of a circlet of precious metal (often set with jewels) worn on the finger', 'name': 'ring'}, {'frequency': 'r', 'synset': 'river_boat.n.01', 'synonyms': ['river_boat'], 'id': 886, 'def': 'a boat used on rivers or to ply a river', 'name': 'river_boat'}, {'frequency': 'r', 'synset': 'road_map.n.02', 'synonyms': ['road_map'], 'id': 887, 'def': '(NOT A ROAD) a MAP showing roads (for automobile travel)', 'name': 'road_map'}, {'frequency': 'c', 'synset': 'robe.n.01', 'synonyms': ['robe'], 'id': 888, 'def': 'any loose flowing garment', 'name': 'robe'}, {'frequency': 'c', 'synset': 'rocking_chair.n.01', 'synonyms': ['rocking_chair'], 'id': 889, 'def': 'a chair mounted on rockers', 'name': 'rocking_chair'}, {'frequency': 'r', 'synset': 'rodent.n.01', 'synonyms': ['rodent'], 'id': 890, 'def': 'relatively small placental mammals having a single pair of constantly growing incisor teeth specialized for gnawing', 'name': 'rodent'}, {'frequency': 'r', 'synset': 'roller_skate.n.01', 'synonyms': ['roller_skate'], 'id': 891, 'def': 'a shoe with pairs of rollers (small hard wheels) fixed to the sole', 'name': 'roller_skate'}, {'frequency': 'r', 'synset': 'rollerblade.n.01', 'synonyms': ['Rollerblade'], 'id': 892, 'def': 'an in-line variant of a roller skate', 'name': 'Rollerblade'}, {'frequency': 'c', 'synset': 'rolling_pin.n.01', 'synonyms': ['rolling_pin'], 'id': 893, 'def': 'utensil consisting of a cylinder (usually of wood) with a handle at each end; used to roll out dough', 'name': 'rolling_pin'}, {'frequency': 'r', 'synset': 'root_beer.n.01', 'synonyms': ['root_beer'], 'id': 894, 'def': 'carbonated drink containing extracts of roots and herbs', 'name': 'root_beer'}, {'frequency': 'c', 'synset': 'router.n.02', 'synonyms': ['router_(computer_equipment)'], 'id': 895, 'def': 'a device that forwards data packets between computer networks', 'name': 'router_(computer_equipment)'}, {'frequency': 'f', 'synset': 'rubber_band.n.01', 'synonyms': ['rubber_band', 'elastic_band'], 'id': 896, 'def': 'a narrow band of elastic rubber used to hold things (such as papers) together', 'name': 'rubber_band'}, {'frequency': 'c', 'synset': 'runner.n.08', 'synonyms': ['runner_(carpet)'], 'id': 897, 'def': 'a long narrow carpet', 'name': 'runner_(carpet)'}, {'frequency': 'f', 'synset': 'sack.n.01', 'synonyms': ['plastic_bag', 'paper_bag'], 'id': 898, 'def': "a bag made of paper or plastic for holding customer's purchases", 'name': 'plastic_bag'}, {'frequency': 'f', 'synset': 'saddle.n.01', 'synonyms': ['saddle_(on_an_animal)'], 'id': 899, 'def': 'a seat for the rider of a horse or camel', 'name': 'saddle_(on_an_animal)'}, {'frequency': 'f', 'synset': 'saddle_blanket.n.01', 'synonyms': ['saddle_blanket', 'saddlecloth', 'horse_blanket'], 'id': 900, 'def': 'stable gear consisting of a blanket placed under the saddle', 'name': 'saddle_blanket'}, {'frequency': 'c', 'synset': 'saddlebag.n.01', 'synonyms': ['saddlebag'], 'id': 901, 'def': 'a large bag (or pair of bags) hung over a saddle', 'name': 'saddlebag'}, {'frequency': 'r', 'synset': 'safety_pin.n.01', 'synonyms': ['safety_pin'], 'id': 902, 'def': 'a pin in the form of a clasp; has a guard so the point of the pin will not stick the user', 'name': 'safety_pin'}, {'frequency': 'f', 'synset': 'sail.n.01', 'synonyms': ['sail'], 'id': 903, 'def': 'a large piece of fabric by means of which wind is used to propel a sailing vessel', 'name': 'sail'}, {'frequency': 'f', 'synset': 'salad.n.01', 'synonyms': ['salad'], 'id': 904, 'def': 'food mixtures either arranged on a plate or tossed and served with a moist dressing; usually consisting of or including greens', 'name': 'salad'}, {'frequency': 'r', 'synset': 'salad_plate.n.01', 'synonyms': ['salad_plate', 'salad_bowl'], 'id': 905, 'def': 'a plate or bowl for individual servings of salad', 'name': 'salad_plate'}, {'frequency': 'c', 'synset': 'salami.n.01', 'synonyms': ['salami'], 'id': 906, 'def': 'highly seasoned fatty sausage of pork and beef usually dried', 'name': 'salami'}, {'frequency': 'c', 'synset': 'salmon.n.01', 'synonyms': ['salmon_(fish)'], 'id': 907, 'def': 'any of various large food and game fishes of northern waters', 'name': 'salmon_(fish)'}, {'frequency': 'r', 'synset': 'salmon.n.03', 'synonyms': ['salmon_(food)'], 'id': 908, 'def': 'flesh of any of various marine or freshwater fish of the family Salmonidae', 'name': 'salmon_(food)'}, {'frequency': 'c', 'synset': 'salsa.n.01', 'synonyms': ['salsa'], 'id': 909, 'def': 'spicy sauce of tomatoes and onions and chili peppers to accompany Mexican foods', 'name': 'salsa'}, {'frequency': 'f', 'synset': 'saltshaker.n.01', 'synonyms': ['saltshaker'], 'id': 910, 'def': 'a shaker with a perforated top for sprinkling salt', 'name': 'saltshaker'}, {'frequency': 'f', 'synset': 'sandal.n.01', 'synonyms': ['sandal_(type_of_shoe)'], 'id': 911, 'def': 'a shoe consisting of a sole fastened by straps to the foot', 'name': 'sandal_(type_of_shoe)'}, {'frequency': 'f', 'synset': 'sandwich.n.01', 'synonyms': ['sandwich'], 'id': 912, 'def': 'two (or more) slices of bread with a filling between them', 'name': 'sandwich'}, {'frequency': 'r', 'synset': 'satchel.n.01', 'synonyms': ['satchel'], 'id': 913, 'def': 'luggage consisting of a small case with a flat bottom and (usually) a shoulder strap', 'name': 'satchel'}, {'frequency': 'r', 'synset': 'saucepan.n.01', 'synonyms': ['saucepan'], 'id': 914, 'def': 'a deep pan with a handle; used for stewing or boiling', 'name': 'saucepan'}, {'frequency': 'f', 'synset': 'saucer.n.02', 'synonyms': ['saucer'], 'id': 915, 'def': 'a small shallow dish for holding a cup at the table', 'name': 'saucer'}, {'frequency': 'f', 'synset': 'sausage.n.01', 'synonyms': ['sausage'], 'id': 916, 'def': 'highly seasoned minced meat stuffed in casings', 'name': 'sausage'}, {'frequency': 'r', 'synset': 'sawhorse.n.01', 'synonyms': ['sawhorse', 'sawbuck'], 'id': 917, 'def': 'a framework for holding wood that is being sawed', 'name': 'sawhorse'}, {'frequency': 'r', 'synset': 'sax.n.02', 'synonyms': ['saxophone'], 'id': 918, 'def': "a wind instrument with a `J'-shaped form typically made of brass", 'name': 'saxophone'}, {'frequency': 'f', 'synset': 'scale.n.07', 'synonyms': ['scale_(measuring_instrument)'], 'id': 919, 'def': 'a measuring instrument for weighing; shows amount of mass', 'name': 'scale_(measuring_instrument)'}, {'frequency': 'r', 'synset': 'scarecrow.n.01', 'synonyms': ['scarecrow', 'strawman'], 'id': 920, 'def': 'an effigy in the shape of a man to frighten birds away from seeds', 'name': 'scarecrow'}, {'frequency': 'f', 'synset': 'scarf.n.01', 'synonyms': ['scarf'], 'id': 921, 'def': 'a garment worn around the head or neck or shoulders for warmth or decoration', 'name': 'scarf'}, {'frequency': 'c', 'synset': 'school_bus.n.01', 'synonyms': ['school_bus'], 'id': 922, 'def': 'a bus used to transport children to or from school', 'name': 'school_bus'}, {'frequency': 'f', 'synset': 'scissors.n.01', 'synonyms': ['scissors'], 'id': 923, 'def': 'a tool having two crossed pivoting blades with looped handles', 'name': 'scissors'}, {'frequency': 'f', 'synset': 'scoreboard.n.01', 'synonyms': ['scoreboard'], 'id': 924, 'def': 'a large board for displaying the score of a contest (and some other information)', 'name': 'scoreboard'}, {'frequency': 'r', 'synset': 'scraper.n.01', 'synonyms': ['scraper'], 'id': 925, 'def': 'any of various hand tools for scraping', 'name': 'scraper'}, {'frequency': 'c', 'synset': 'screwdriver.n.01', 'synonyms': ['screwdriver'], 'id': 926, 'def': 'a hand tool for driving screws; has a tip that fits into the head of a screw', 'name': 'screwdriver'}, {'frequency': 'f', 'synset': 'scrub_brush.n.01', 'synonyms': ['scrubbing_brush'], 'id': 927, 'def': 'a brush with short stiff bristles for heavy cleaning', 'name': 'scrubbing_brush'}, {'frequency': 'c', 'synset': 'sculpture.n.01', 'synonyms': ['sculpture'], 'id': 928, 'def': 'a three-dimensional work of art', 'name': 'sculpture'}, {'frequency': 'c', 'synset': 'seabird.n.01', 'synonyms': ['seabird', 'seafowl'], 'id': 929, 'def': 'a bird that frequents coastal waters and the open ocean: gulls; pelicans; gannets; cormorants; albatrosses; petrels; etc.', 'name': 'seabird'}, {'frequency': 'c', 'synset': 'seahorse.n.02', 'synonyms': ['seahorse'], 'id': 930, 'def': 'small fish with horse-like heads bent sharply downward and curled tails', 'name': 'seahorse'}, {'frequency': 'r', 'synset': 'seaplane.n.01', 'synonyms': ['seaplane', 'hydroplane'], 'id': 931, 'def': 'an airplane that can land on or take off from water', 'name': 'seaplane'}, {'frequency': 'c', 'synset': 'seashell.n.01', 'synonyms': ['seashell'], 'id': 932, 'def': 'the shell of a marine organism', 'name': 'seashell'}, {'frequency': 'c', 'synset': 'sewing_machine.n.01', 'synonyms': ['sewing_machine'], 'id': 933, 'def': 'a textile machine used as a home appliance for sewing', 'name': 'sewing_machine'}, {'frequency': 'c', 'synset': 'shaker.n.03', 'synonyms': ['shaker'], 'id': 934, 'def': 'a container in which something can be shaken', 'name': 'shaker'}, {'frequency': 'c', 'synset': 'shampoo.n.01', 'synonyms': ['shampoo'], 'id': 935, 'def': 'cleansing agent consisting of soaps or detergents used for washing the hair', 'name': 'shampoo'}, {'frequency': 'c', 'synset': 'shark.n.01', 'synonyms': ['shark'], 'id': 936, 'def': 'typically large carnivorous fishes with sharpe teeth', 'name': 'shark'}, {'frequency': 'r', 'synset': 'sharpener.n.01', 'synonyms': ['sharpener'], 'id': 937, 'def': 'any implement that is used to make something (an edge or a point) sharper', 'name': 'sharpener'}, {'frequency': 'r', 'synset': 'sharpie.n.03', 'synonyms': ['Sharpie'], 'id': 938, 'def': 'a pen with indelible ink that will write on any surface', 'name': 'Sharpie'}, {'frequency': 'r', 'synset': 'shaver.n.03', 'synonyms': ['shaver_(electric)', 'electric_shaver', 'electric_razor'], 'id': 939, 'def': 'a razor powered by an electric motor', 'name': 'shaver_(electric)'}, {'frequency': 'c', 'synset': 'shaving_cream.n.01', 'synonyms': ['shaving_cream', 'shaving_soap'], 'id': 940, 'def': 'toiletry consisting that forms a rich lather for softening the beard before shaving', 'name': 'shaving_cream'}, {'frequency': 'r', 'synset': 'shawl.n.01', 'synonyms': ['shawl'], 'id': 941, 'def': 'cloak consisting of an oblong piece of cloth used to cover the head and shoulders', 'name': 'shawl'}, {'frequency': 'r', 'synset': 'shears.n.01', 'synonyms': ['shears'], 'id': 942, 'def': 'large scissors with strong blades', 'name': 'shears'}, {'frequency': 'f', 'synset': 'sheep.n.01', 'synonyms': ['sheep'], 'id': 943, 'def': 'woolly usually horned ruminant mammal related to the goat', 'name': 'sheep'}, {'frequency': 'r', 'synset': 'shepherd_dog.n.01', 'synonyms': ['shepherd_dog', 'sheepdog'], 'id': 944, 'def': 'any of various usually long-haired breeds of dog reared to herd and guard sheep', 'name': 'shepherd_dog'}, {'frequency': 'r', 'synset': 'sherbert.n.01', 'synonyms': ['sherbert', 'sherbet'], 'id': 945, 'def': 'a frozen dessert made primarily of fruit juice and sugar', 'name': 'sherbert'}, {'frequency': 'c', 'synset': 'shield.n.02', 'synonyms': ['shield'], 'id': 946, 'def': 'armor carried on the arm to intercept blows', 'name': 'shield'}, {'frequency': 'f', 'synset': 'shirt.n.01', 'synonyms': ['shirt'], 'id': 947, 'def': 'a garment worn on the upper half of the body', 'name': 'shirt'}, {'frequency': 'f', 'synset': 'shoe.n.01', 'synonyms': ['shoe', 'sneaker_(type_of_shoe)', 'tennis_shoe'], 'id': 948, 'def': 'common footwear covering the foot', 'name': 'shoe'}, {'frequency': 'f', 'synset': 'shopping_bag.n.01', 'synonyms': ['shopping_bag'], 'id': 949, 'def': 'a bag made of plastic or strong paper (often with handles); used to transport goods after shopping', 'name': 'shopping_bag'}, {'frequency': 'c', 'synset': 'shopping_cart.n.01', 'synonyms': ['shopping_cart'], 'id': 950, 'def': 'a handcart that holds groceries or other goods while shopping', 'name': 'shopping_cart'}, {'frequency': 'f', 'synset': 'short_pants.n.01', 'synonyms': ['short_pants', 'shorts_(clothing)', 'trunks_(clothing)'], 'id': 951, 'def': 'trousers that end at or above the knee', 'name': 'short_pants'}, {'frequency': 'r', 'synset': 'shot_glass.n.01', 'synonyms': ['shot_glass'], 'id': 952, 'def': 'a small glass adequate to hold a single swallow of whiskey', 'name': 'shot_glass'}, {'frequency': 'f', 'synset': 'shoulder_bag.n.01', 'synonyms': ['shoulder_bag'], 'id': 953, 'def': 'a large handbag that can be carried by a strap looped over the shoulder', 'name': 'shoulder_bag'}, {'frequency': 'c', 'synset': 'shovel.n.01', 'synonyms': ['shovel'], 'id': 954, 'def': 'a hand tool for lifting loose material such as snow, dirt, etc.', 'name': 'shovel'}, {'frequency': 'f', 'synset': 'shower.n.01', 'synonyms': ['shower_head'], 'id': 955, 'def': 'a plumbing fixture that sprays water over you', 'name': 'shower_head'}, {'frequency': 'r', 'synset': 'shower_cap.n.01', 'synonyms': ['shower_cap'], 'id': 956, 'def': 'a tight cap worn to keep hair dry while showering', 'name': 'shower_cap'}, {'frequency': 'f', 'synset': 'shower_curtain.n.01', 'synonyms': ['shower_curtain'], 'id': 957, 'def': 'a curtain that keeps water from splashing out of the shower area', 'name': 'shower_curtain'}, {'frequency': 'r', 'synset': 'shredder.n.01', 'synonyms': ['shredder_(for_paper)'], 'id': 958, 'def': 'a device that shreds documents', 'name': 'shredder_(for_paper)'}, {'frequency': 'f', 'synset': 'signboard.n.01', 'synonyms': ['signboard'], 'id': 959, 'def': 'structure displaying a board on which advertisements can be posted', 'name': 'signboard'}, {'frequency': 'c', 'synset': 'silo.n.01', 'synonyms': ['silo'], 'id': 960, 'def': 'a cylindrical tower used for storing goods', 'name': 'silo'}, {'frequency': 'f', 'synset': 'sink.n.01', 'synonyms': ['sink'], 'id': 961, 'def': 'plumbing fixture consisting of a water basin fixed to a wall or floor and having a drainpipe', 'name': 'sink'}, {'frequency': 'f', 'synset': 'skateboard.n.01', 'synonyms': ['skateboard'], 'id': 962, 'def': 'a board with wheels that is ridden in a standing or crouching position and propelled by foot', 'name': 'skateboard'}, {'frequency': 'c', 'synset': 'skewer.n.01', 'synonyms': ['skewer'], 'id': 963, 'def': 'a long pin for holding meat in position while it is being roasted', 'name': 'skewer'}, {'frequency': 'f', 'synset': 'ski.n.01', 'synonyms': ['ski'], 'id': 964, 'def': 'sports equipment for skiing on snow', 'name': 'ski'}, {'frequency': 'f', 'synset': 'ski_boot.n.01', 'synonyms': ['ski_boot'], 'id': 965, 'def': 'a stiff boot that is fastened to a ski with a ski binding', 'name': 'ski_boot'}, {'frequency': 'f', 'synset': 'ski_parka.n.01', 'synonyms': ['ski_parka', 'ski_jacket'], 'id': 966, 'def': 'a parka to be worn while skiing', 'name': 'ski_parka'}, {'frequency': 'f', 'synset': 'ski_pole.n.01', 'synonyms': ['ski_pole'], 'id': 967, 'def': 'a pole with metal points used as an aid in skiing', 'name': 'ski_pole'}, {'frequency': 'f', 'synset': 'skirt.n.02', 'synonyms': ['skirt'], 'id': 968, 'def': 'a garment hanging from the waist; worn mainly by girls and women', 'name': 'skirt'}, {'frequency': 'r', 'synset': 'skullcap.n.01', 'synonyms': ['skullcap'], 'id': 969, 'def': 'rounded brimless cap fitting the crown of the head', 'name': 'skullcap'}, {'frequency': 'c', 'synset': 'sled.n.01', 'synonyms': ['sled', 'sledge', 'sleigh'], 'id': 970, 'def': 'a vehicle or flat object for transportation over snow by sliding or pulled by dogs, etc.', 'name': 'sled'}, {'frequency': 'c', 'synset': 'sleeping_bag.n.01', 'synonyms': ['sleeping_bag'], 'id': 971, 'def': 'large padded bag designed to be slept in outdoors', 'name': 'sleeping_bag'}, {'frequency': 'r', 'synset': 'sling.n.05', 'synonyms': ['sling_(bandage)', 'triangular_bandage'], 'id': 972, 'def': 'bandage to support an injured forearm; slung over the shoulder or neck', 'name': 'sling_(bandage)'}, {'frequency': 'c', 'synset': 'slipper.n.01', 'synonyms': ['slipper_(footwear)', 'carpet_slipper_(footwear)'], 'id': 973, 'def': 'low footwear that can be slipped on and off easily; usually worn indoors', 'name': 'slipper_(footwear)'}, {'frequency': 'r', 'synset': 'smoothie.n.02', 'synonyms': ['smoothie'], 'id': 974, 'def': 'a thick smooth drink consisting of fresh fruit pureed with ice cream or yoghurt or milk', 'name': 'smoothie'}, {'frequency': 'r', 'synset': 'snake.n.01', 'synonyms': ['snake', 'serpent'], 'id': 975, 'def': 'limbless scaly elongate reptile; some are venomous', 'name': 'snake'}, {'frequency': 'f', 'synset': 'snowboard.n.01', 'synonyms': ['snowboard'], 'id': 976, 'def': 'a board that resembles a broad ski or a small surfboard; used in a standing position to slide down snow-covered slopes', 'name': 'snowboard'}, {'frequency': 'c', 'synset': 'snowman.n.01', 'synonyms': ['snowman'], 'id': 977, 'def': 'a figure of a person made of packed snow', 'name': 'snowman'}, {'frequency': 'c', 'synset': 'snowmobile.n.01', 'synonyms': ['snowmobile'], 'id': 978, 'def': 'tracked vehicle for travel on snow having skis in front', 'name': 'snowmobile'}, {'frequency': 'f', 'synset': 'soap.n.01', 'synonyms': ['soap'], 'id': 979, 'def': 'a cleansing agent made from the salts of vegetable or animal fats', 'name': 'soap'}, {'frequency': 'f', 'synset': 'soccer_ball.n.01', 'synonyms': ['soccer_ball'], 'id': 980, 'def': "an inflated ball used in playing soccer (called `football' outside of the United States)", 'name': 'soccer_ball'}, {'frequency': 'f', 'synset': 'sock.n.01', 'synonyms': ['sock'], 'id': 981, 'def': 'cloth covering for the foot; worn inside the shoe; reaches to between the ankle and the knee', 'name': 'sock'}, {'frequency': 'f', 'synset': 'sofa.n.01', 'synonyms': ['sofa', 'couch', 'lounge'], 'id': 982, 'def': 'an upholstered seat for more than one person', 'name': 'sofa'}, {'frequency': 'r', 'synset': 'softball.n.01', 'synonyms': ['softball'], 'id': 983, 'def': 'ball used in playing softball', 'name': 'softball'}, {'frequency': 'c', 'synset': 'solar_array.n.01', 'synonyms': ['solar_array', 'solar_battery', 'solar_panel'], 'id': 984, 'def': 'electrical device consisting of a large array of connected solar cells', 'name': 'solar_array'}, {'frequency': 'r', 'synset': 'sombrero.n.02', 'synonyms': ['sombrero'], 'id': 985, 'def': 'a straw hat with a tall crown and broad brim; worn in American southwest and in Mexico', 'name': 'sombrero'}, {'frequency': 'f', 'synset': 'soup.n.01', 'synonyms': ['soup'], 'id': 986, 'def': 'liquid food especially of meat or fish or vegetable stock often containing pieces of solid food', 'name': 'soup'}, {'frequency': 'r', 'synset': 'soup_bowl.n.01', 'synonyms': ['soup_bowl'], 'id': 987, 'def': 'a bowl for serving soup', 'name': 'soup_bowl'}, {'frequency': 'c', 'synset': 'soupspoon.n.01', 'synonyms': ['soupspoon'], 'id': 988, 'def': 'a spoon with a rounded bowl for eating soup', 'name': 'soupspoon'}, {'frequency': 'c', 'synset': 'sour_cream.n.01', 'synonyms': ['sour_cream', 'soured_cream'], 'id': 989, 'def': 'soured light cream', 'name': 'sour_cream'}, {'frequency': 'r', 'synset': 'soya_milk.n.01', 'synonyms': ['soya_milk', 'soybean_milk', 'soymilk'], 'id': 990, 'def': 'a milk substitute containing soybean flour and water; used in some infant formulas and in making tofu', 'name': 'soya_milk'}, {'frequency': 'r', 'synset': 'space_shuttle.n.01', 'synonyms': ['space_shuttle'], 'id': 991, 'def': "a reusable spacecraft with wings for a controlled descent through the Earth's atmosphere", 'name': 'space_shuttle'}, {'frequency': 'r', 'synset': 'sparkler.n.02', 'synonyms': ['sparkler_(fireworks)'], 'id': 992, 'def': 'a firework that burns slowly and throws out a shower of sparks', 'name': 'sparkler_(fireworks)'}, {'frequency': 'f', 'synset': 'spatula.n.02', 'synonyms': ['spatula'], 'id': 993, 'def': 'a hand tool with a thin flexible blade used to mix or spread soft substances', 'name': 'spatula'}, {'frequency': 'r', 'synset': 'spear.n.01', 'synonyms': ['spear', 'lance'], 'id': 994, 'def': 'a long pointed rod used as a tool or weapon', 'name': 'spear'}, {'frequency': 'f', 'synset': 'spectacles.n.01', 'synonyms': ['spectacles', 'specs', 'eyeglasses', 'glasses'], 'id': 995, 'def': 'optical instrument consisting of a frame that holds a pair of lenses for correcting defective vision', 'name': 'spectacles'}, {'frequency': 'c', 'synset': 'spice_rack.n.01', 'synonyms': ['spice_rack'], 'id': 996, 'def': 'a rack for displaying containers filled with spices', 'name': 'spice_rack'}, {'frequency': 'c', 'synset': 'spider.n.01', 'synonyms': ['spider'], 'id': 997, 'def': 'predatory arachnid with eight legs, two poison fangs, two feelers, and usually two silk-spinning organs at the back end of the body', 'name': 'spider'}, {'frequency': 'r', 'synset': 'spiny_lobster.n.02', 'synonyms': ['crawfish', 'crayfish'], 'id': 998, 'def': 'large edible marine crustacean having a spiny carapace but lacking the large pincers of true lobsters', 'name': 'crawfish'}, {'frequency': 'c', 'synset': 'sponge.n.01', 'synonyms': ['sponge'], 'id': 999, 'def': 'a porous mass usable to absorb water typically used for cleaning', 'name': 'sponge'}, {'frequency': 'f', 'synset': 'spoon.n.01', 'synonyms': ['spoon'], 'id': 1000, 'def': 'a piece of cutlery with a shallow bowl-shaped container and a handle', 'name': 'spoon'}, {'frequency': 'c', 'synset': 'sportswear.n.01', 'synonyms': ['sportswear', 'athletic_wear', 'activewear'], 'id': 1001, 'def': 'attire worn for sport or for casual wear', 'name': 'sportswear'}, {'frequency': 'c', 'synset': 'spotlight.n.02', 'synonyms': ['spotlight'], 'id': 1002, 'def': 'a lamp that produces a strong beam of light to illuminate a restricted area; used to focus attention of a stage performer', 'name': 'spotlight'}, {'frequency': 'r', 'synset': 'squid.n.01', 'synonyms': ['squid_(food)', 'calamari', 'calamary'], 'id': 1003, 'def': '(Italian cuisine) squid prepared as food', 'name': 'squid_(food)'}, {'frequency': 'c', 'synset': 'squirrel.n.01', 'synonyms': ['squirrel'], 'id': 1004, 'def': 'a kind of arboreal rodent having a long bushy tail', 'name': 'squirrel'}, {'frequency': 'r', 'synset': 'stagecoach.n.01', 'synonyms': ['stagecoach'], 'id': 1005, 'def': 'a large coach-and-four formerly used to carry passengers and mail on regular routes between towns', 'name': 'stagecoach'}, {'frequency': 'c', 'synset': 'stapler.n.01', 'synonyms': ['stapler_(stapling_machine)'], 'id': 1006, 'def': 'a machine that inserts staples into sheets of paper in order to fasten them together', 'name': 'stapler_(stapling_machine)'}, {'frequency': 'c', 'synset': 'starfish.n.01', 'synonyms': ['starfish', 'sea_star'], 'id': 1007, 'def': 'echinoderms characterized by five arms extending from a central disk', 'name': 'starfish'}, {'frequency': 'f', 'synset': 'statue.n.01', 'synonyms': ['statue_(sculpture)'], 'id': 1008, 'def': 'a sculpture representing a human or animal', 'name': 'statue_(sculpture)'}, {'frequency': 'c', 'synset': 'steak.n.01', 'synonyms': ['steak_(food)'], 'id': 1009, 'def': 'a slice of meat cut from the fleshy part of an animal or large fish', 'name': 'steak_(food)'}, {'frequency': 'r', 'synset': 'steak_knife.n.01', 'synonyms': ['steak_knife'], 'id': 1010, 'def': 'a sharp table knife used in eating steak', 'name': 'steak_knife'}, {'frequency': 'f', 'synset': 'steering_wheel.n.01', 'synonyms': ['steering_wheel'], 'id': 1011, 'def': 'a handwheel that is used for steering', 'name': 'steering_wheel'}, {'frequency': 'r', 'synset': 'step_ladder.n.01', 'synonyms': ['stepladder'], 'id': 1012, 'def': 'a folding portable ladder hinged at the top', 'name': 'stepladder'}, {'frequency': 'c', 'synset': 'step_stool.n.01', 'synonyms': ['step_stool'], 'id': 1013, 'def': 'a stool that has one or two steps that fold under the seat', 'name': 'step_stool'}, {'frequency': 'c', 'synset': 'stereo.n.01', 'synonyms': ['stereo_(sound_system)'], 'id': 1014, 'def': 'electronic device for playing audio', 'name': 'stereo_(sound_system)'}, {'frequency': 'r', 'synset': 'stew.n.02', 'synonyms': ['stew'], 'id': 1015, 'def': 'food prepared by stewing especially meat or fish with vegetables', 'name': 'stew'}, {'frequency': 'r', 'synset': 'stirrer.n.02', 'synonyms': ['stirrer'], 'id': 1016, 'def': 'an implement used for stirring', 'name': 'stirrer'}, {'frequency': 'f', 'synset': 'stirrup.n.01', 'synonyms': ['stirrup'], 'id': 1017, 'def': "support consisting of metal loops into which rider's feet go", 'name': 'stirrup'}, {'frequency': 'f', 'synset': 'stool.n.01', 'synonyms': ['stool'], 'id': 1018, 'def': 'a simple seat without a back or arms', 'name': 'stool'}, {'frequency': 'f', 'synset': 'stop_sign.n.01', 'synonyms': ['stop_sign'], 'id': 1019, 'def': 'a traffic sign to notify drivers that they must come to a complete stop', 'name': 'stop_sign'}, {'frequency': 'f', 'synset': 'stoplight.n.01', 'synonyms': ['brake_light'], 'id': 1020, 'def': 'a red light on the rear of a motor vehicle that signals when the brakes are applied', 'name': 'brake_light'}, {'frequency': 'f', 'synset': 'stove.n.01', 'synonyms': ['stove', 'kitchen_stove', 'range_(kitchen_appliance)', 'kitchen_range', 'cooking_stove'], 'id': 1021, 'def': 'a kitchen appliance used for cooking food', 'name': 'stove'}, {'frequency': 'c', 'synset': 'strainer.n.01', 'synonyms': ['strainer'], 'id': 1022, 'def': 'a filter to retain larger pieces while smaller pieces and liquids pass through', 'name': 'strainer'}, {'frequency': 'f', 'synset': 'strap.n.01', 'synonyms': ['strap'], 'id': 1023, 'def': 'an elongated strip of material for binding things together or holding', 'name': 'strap'}, {'frequency': 'f', 'synset': 'straw.n.04', 'synonyms': ['straw_(for_drinking)', 'drinking_straw'], 'id': 1024, 'def': 'a thin paper or plastic tube used to suck liquids into the mouth', 'name': 'straw_(for_drinking)'}, {'frequency': 'f', 'synset': 'strawberry.n.01', 'synonyms': ['strawberry'], 'id': 1025, 'def': 'sweet fleshy red fruit', 'name': 'strawberry'}, {'frequency': 'f', 'synset': 'street_sign.n.01', 'synonyms': ['street_sign'], 'id': 1026, 'def': 'a sign visible from the street', 'name': 'street_sign'}, {'frequency': 'f', 'synset': 'streetlight.n.01', 'synonyms': ['streetlight', 'street_lamp'], 'id': 1027, 'def': 'a lamp supported on a lamppost; for illuminating a street', 'name': 'streetlight'}, {'frequency': 'r', 'synset': 'string_cheese.n.01', 'synonyms': ['string_cheese'], 'id': 1028, 'def': 'cheese formed in long strings twisted together', 'name': 'string_cheese'}, {'frequency': 'r', 'synset': 'stylus.n.02', 'synonyms': ['stylus'], 'id': 1029, 'def': 'a pointed tool for writing or drawing or engraving, including pens', 'name': 'stylus'}, {'frequency': 'r', 'synset': 'subwoofer.n.01', 'synonyms': ['subwoofer'], 'id': 1030, 'def': 'a loudspeaker that is designed to reproduce very low bass frequencies', 'name': 'subwoofer'}, {'frequency': 'r', 'synset': 'sugar_bowl.n.01', 'synonyms': ['sugar_bowl'], 'id': 1031, 'def': 'a dish in which sugar is served', 'name': 'sugar_bowl'}, {'frequency': 'r', 'synset': 'sugarcane.n.01', 'synonyms': ['sugarcane_(plant)'], 'id': 1032, 'def': 'juicy canes whose sap is a source of molasses and commercial sugar; fresh canes are sometimes chewed for the juice', 'name': 'sugarcane_(plant)'}, {'frequency': 'f', 'synset': 'suit.n.01', 'synonyms': ['suit_(clothing)'], 'id': 1033, 'def': 'a set of garments (usually including a jacket and trousers or skirt) for outerwear all of the same fabric and color', 'name': 'suit_(clothing)'}, {'frequency': 'c', 'synset': 'sunflower.n.01', 'synonyms': ['sunflower'], 'id': 1034, 'def': 'any plant of the genus Helianthus having large flower heads with dark disk florets and showy yellow rays', 'name': 'sunflower'}, {'frequency': 'f', 'synset': 'sunglasses.n.01', 'synonyms': ['sunglasses'], 'id': 1035, 'def': 'spectacles that are darkened or polarized to protect the eyes from the glare of the sun', 'name': 'sunglasses'}, {'frequency': 'c', 'synset': 'sunhat.n.01', 'synonyms': ['sunhat'], 'id': 1036, 'def': 'a hat with a broad brim that protects the face from direct exposure to the sun', 'name': 'sunhat'}, {'frequency': 'f', 'synset': 'surfboard.n.01', 'synonyms': ['surfboard'], 'id': 1037, 'def': 'a narrow buoyant board for riding surf', 'name': 'surfboard'}, {'frequency': 'c', 'synset': 'sushi.n.01', 'synonyms': ['sushi'], 'id': 1038, 'def': 'rice (with raw fish) wrapped in seaweed', 'name': 'sushi'}, {'frequency': 'c', 'synset': 'swab.n.02', 'synonyms': ['mop'], 'id': 1039, 'def': 'cleaning implement consisting of absorbent material fastened to a handle; for cleaning floors', 'name': 'mop'}, {'frequency': 'c', 'synset': 'sweat_pants.n.01', 'synonyms': ['sweat_pants'], 'id': 1040, 'def': 'loose-fitting trousers with elastic cuffs; worn by athletes', 'name': 'sweat_pants'}, {'frequency': 'c', 'synset': 'sweatband.n.02', 'synonyms': ['sweatband'], 'id': 1041, 'def': 'a band of material tied around the forehead or wrist to absorb sweat', 'name': 'sweatband'}, {'frequency': 'f', 'synset': 'sweater.n.01', 'synonyms': ['sweater'], 'id': 1042, 'def': 'a crocheted or knitted garment covering the upper part of the body', 'name': 'sweater'}, {'frequency': 'f', 'synset': 'sweatshirt.n.01', 'synonyms': ['sweatshirt'], 'id': 1043, 'def': 'cotton knit pullover with long sleeves worn during athletic activity', 'name': 'sweatshirt'}, {'frequency': 'c', 'synset': 'sweet_potato.n.02', 'synonyms': ['sweet_potato'], 'id': 1044, 'def': 'the edible tuberous root of the sweet potato vine', 'name': 'sweet_potato'}, {'frequency': 'f', 'synset': 'swimsuit.n.01', 'synonyms': ['swimsuit', 'swimwear', 'bathing_suit', 'swimming_costume', 'bathing_costume', 'swimming_trunks', 'bathing_trunks'], 'id': 1045, 'def': 'garment worn for swimming', 'name': 'swimsuit'}, {'frequency': 'c', 'synset': 'sword.n.01', 'synonyms': ['sword'], 'id': 1046, 'def': 'a cutting or thrusting weapon that has a long metal blade', 'name': 'sword'}, {'frequency': 'r', 'synset': 'syringe.n.01', 'synonyms': ['syringe'], 'id': 1047, 'def': 'a medical instrument used to inject or withdraw fluids', 'name': 'syringe'}, {'frequency': 'r', 'synset': 'tabasco.n.02', 'synonyms': ['Tabasco_sauce'], 'id': 1048, 'def': 'very spicy sauce (trade name Tabasco) made from fully-aged red peppers', 'name': 'Tabasco_sauce'}, {'frequency': 'r', 'synset': 'table-tennis_table.n.01', 'synonyms': ['table-tennis_table', 'ping-pong_table'], 'id': 1049, 'def': 'a table used for playing table tennis', 'name': 'table-tennis_table'}, {'frequency': 'f', 'synset': 'table.n.02', 'synonyms': ['table'], 'id': 1050, 'def': 'a piece of furniture having a smooth flat top that is usually supported by one or more vertical legs', 'name': 'table'}, {'frequency': 'c', 'synset': 'table_lamp.n.01', 'synonyms': ['table_lamp'], 'id': 1051, 'def': 'a lamp that sits on a table', 'name': 'table_lamp'}, {'frequency': 'f', 'synset': 'tablecloth.n.01', 'synonyms': ['tablecloth'], 'id': 1052, 'def': 'a covering spread over a dining table', 'name': 'tablecloth'}, {'frequency': 'r', 'synset': 'tachometer.n.01', 'synonyms': ['tachometer'], 'id': 1053, 'def': 'measuring instrument for indicating speed of rotation', 'name': 'tachometer'}, {'frequency': 'r', 'synset': 'taco.n.02', 'synonyms': ['taco'], 'id': 1054, 'def': 'a small tortilla cupped around a filling', 'name': 'taco'}, {'frequency': 'f', 'synset': 'tag.n.02', 'synonyms': ['tag'], 'id': 1055, 'def': 'a label associated with something for the purpose of identification or information', 'name': 'tag'}, {'frequency': 'f', 'synset': 'taillight.n.01', 'synonyms': ['taillight', 'rear_light'], 'id': 1056, 'def': 'lamp (usually red) mounted at the rear of a motor vehicle', 'name': 'taillight'}, {'frequency': 'r', 'synset': 'tambourine.n.01', 'synonyms': ['tambourine'], 'id': 1057, 'def': 'a shallow drum with a single drumhead and with metallic disks in the sides', 'name': 'tambourine'}, {'frequency': 'r', 'synset': 'tank.n.01', 'synonyms': ['army_tank', 'armored_combat_vehicle', 'armoured_combat_vehicle'], 'id': 1058, 'def': 'an enclosed armored military vehicle; has a cannon and moves on caterpillar treads', 'name': 'army_tank'}, {'frequency': 'f', 'synset': 'tank.n.02', 'synonyms': ['tank_(storage_vessel)', 'storage_tank'], 'id': 1059, 'def': 'a large (usually metallic) vessel for holding gases or liquids', 'name': 'tank_(storage_vessel)'}, {'frequency': 'f', 'synset': 'tank_top.n.01', 'synonyms': ['tank_top_(clothing)'], 'id': 1060, 'def': 'a tight-fitting sleeveless shirt with wide shoulder straps and low neck and no front opening', 'name': 'tank_top_(clothing)'}, {'frequency': 'f', 'synset': 'tape.n.01', 'synonyms': ['tape_(sticky_cloth_or_paper)'], 'id': 1061, 'def': 'a long thin piece of cloth or paper as used for binding or fastening', 'name': 'tape_(sticky_cloth_or_paper)'}, {'frequency': 'c', 'synset': 'tape.n.04', 'synonyms': ['tape_measure', 'measuring_tape'], 'id': 1062, 'def': 'measuring instrument consisting of a narrow strip (cloth or metal) marked in inches or centimeters and used for measuring lengths', 'name': 'tape_measure'}, {'frequency': 'c', 'synset': 'tapestry.n.02', 'synonyms': ['tapestry'], 'id': 1063, 'def': 'a heavy textile with a woven design; used for curtains and upholstery', 'name': 'tapestry'}, {'frequency': 'f', 'synset': 'tarpaulin.n.01', 'synonyms': ['tarp'], 'id': 1064, 'def': 'waterproofed canvas', 'name': 'tarp'}, {'frequency': 'c', 'synset': 'tartan.n.01', 'synonyms': ['tartan', 'plaid'], 'id': 1065, 'def': 'a cloth having a crisscross design', 'name': 'tartan'}, {'frequency': 'c', 'synset': 'tassel.n.01', 'synonyms': ['tassel'], 'id': 1066, 'def': 'adornment consisting of a bunch of cords fastened at one end', 'name': 'tassel'}, {'frequency': 'c', 'synset': 'tea_bag.n.01', 'synonyms': ['tea_bag'], 'id': 1067, 'def': 'a measured amount of tea in a bag for an individual serving of tea', 'name': 'tea_bag'}, {'frequency': 'c', 'synset': 'teacup.n.02', 'synonyms': ['teacup'], 'id': 1068, 'def': 'a cup from which tea is drunk', 'name': 'teacup'}, {'frequency': 'c', 'synset': 'teakettle.n.01', 'synonyms': ['teakettle'], 'id': 1069, 'def': 'kettle for boiling water to make tea', 'name': 'teakettle'}, {'frequency': 'f', 'synset': 'teapot.n.01', 'synonyms': ['teapot'], 'id': 1070, 'def': 'pot for brewing tea; usually has a spout and handle', 'name': 'teapot'}, {'frequency': 'f', 'synset': 'teddy.n.01', 'synonyms': ['teddy_bear'], 'id': 1071, 'def': "plaything consisting of a child's toy bear (usually plush and stuffed with soft materials)", 'name': 'teddy_bear'}, {'frequency': 'f', 'synset': 'telephone.n.01', 'synonyms': ['telephone', 'phone', 'telephone_set'], 'id': 1072, 'def': 'electronic device for communicating by voice over long distances (includes wired and wireless/cell phones)', 'name': 'telephone'}, {'frequency': 'c', 'synset': 'telephone_booth.n.01', 'synonyms': ['telephone_booth', 'phone_booth', 'call_box', 'telephone_box', 'telephone_kiosk'], 'id': 1073, 'def': 'booth for using a telephone', 'name': 'telephone_booth'}, {'frequency': 'f', 'synset': 'telephone_pole.n.01', 'synonyms': ['telephone_pole', 'telegraph_pole', 'telegraph_post'], 'id': 1074, 'def': 'tall pole supporting telephone wires', 'name': 'telephone_pole'}, {'frequency': 'r', 'synset': 'telephoto_lens.n.01', 'synonyms': ['telephoto_lens', 'zoom_lens'], 'id': 1075, 'def': 'a camera lens that magnifies the image', 'name': 'telephoto_lens'}, {'frequency': 'c', 'synset': 'television_camera.n.01', 'synonyms': ['television_camera', 'tv_camera'], 'id': 1076, 'def': 'television equipment for capturing and recording video', 'name': 'television_camera'}, {'frequency': 'f', 'synset': 'television_receiver.n.01', 'synonyms': ['television_set', 'tv', 'tv_set'], 'id': 1077, 'def': 'an electronic device that receives television signals and displays them on a screen', 'name': 'television_set'}, {'frequency': 'f', 'synset': 'tennis_ball.n.01', 'synonyms': ['tennis_ball'], 'id': 1078, 'def': 'ball about the size of a fist used in playing tennis', 'name': 'tennis_ball'}, {'frequency': 'f', 'synset': 'tennis_racket.n.01', 'synonyms': ['tennis_racket'], 'id': 1079, 'def': 'a racket used to play tennis', 'name': 'tennis_racket'}, {'frequency': 'r', 'synset': 'tequila.n.01', 'synonyms': ['tequila'], 'id': 1080, 'def': 'Mexican liquor made from fermented juices of an agave plant', 'name': 'tequila'}, {'frequency': 'c', 'synset': 'thermometer.n.01', 'synonyms': ['thermometer'], 'id': 1081, 'def': 'measuring instrument for measuring temperature', 'name': 'thermometer'}, {'frequency': 'c', 'synset': 'thermos.n.01', 'synonyms': ['thermos_bottle'], 'id': 1082, 'def': 'vacuum flask that preserves temperature of hot or cold drinks', 'name': 'thermos_bottle'}, {'frequency': 'f', 'synset': 'thermostat.n.01', 'synonyms': ['thermostat'], 'id': 1083, 'def': 'a regulator for automatically regulating temperature by starting or stopping the supply of heat', 'name': 'thermostat'}, {'frequency': 'r', 'synset': 'thimble.n.02', 'synonyms': ['thimble'], 'id': 1084, 'def': 'a small metal cap to protect the finger while sewing; can be used as a small container', 'name': 'thimble'}, {'frequency': 'c', 'synset': 'thread.n.01', 'synonyms': ['thread', 'yarn'], 'id': 1085, 'def': 'a fine cord of twisted fibers (of cotton or silk or wool or nylon etc.) used in sewing and weaving', 'name': 'thread'}, {'frequency': 'c', 'synset': 'thumbtack.n.01', 'synonyms': ['thumbtack', 'drawing_pin', 'pushpin'], 'id': 1086, 'def': 'a tack for attaching papers to a bulletin board or drawing board', 'name': 'thumbtack'}, {'frequency': 'c', 'synset': 'tiara.n.01', 'synonyms': ['tiara'], 'id': 1087, 'def': 'a jeweled headdress worn by women on formal occasions', 'name': 'tiara'}, {'frequency': 'c', 'synset': 'tiger.n.02', 'synonyms': ['tiger'], 'id': 1088, 'def': 'large feline of forests in most of Asia having a tawny coat with black stripes', 'name': 'tiger'}, {'frequency': 'c', 'synset': 'tights.n.01', 'synonyms': ['tights_(clothing)', 'leotards'], 'id': 1089, 'def': 'skintight knit hose covering the body from the waist to the feet worn by acrobats and dancers and as stockings by women and girls', 'name': 'tights_(clothing)'}, {'frequency': 'c', 'synset': 'timer.n.01', 'synonyms': ['timer', 'stopwatch'], 'id': 1090, 'def': 'a timepiece that measures a time interval and signals its end', 'name': 'timer'}, {'frequency': 'f', 'synset': 'tinfoil.n.01', 'synonyms': ['tinfoil'], 'id': 1091, 'def': 'foil made of tin or an alloy of tin and lead', 'name': 'tinfoil'}, {'frequency': 'c', 'synset': 'tinsel.n.01', 'synonyms': ['tinsel'], 'id': 1092, 'def': 'a showy decoration that is basically valueless', 'name': 'tinsel'}, {'frequency': 'f', 'synset': 'tissue.n.02', 'synonyms': ['tissue_paper'], 'id': 1093, 'def': 'a soft thin (usually translucent) paper', 'name': 'tissue_paper'}, {'frequency': 'c', 'synset': 'toast.n.01', 'synonyms': ['toast_(food)'], 'id': 1094, 'def': 'slice of bread that has been toasted', 'name': 'toast_(food)'}, {'frequency': 'f', 'synset': 'toaster.n.02', 'synonyms': ['toaster'], 'id': 1095, 'def': 'a kitchen appliance (usually electric) for toasting bread', 'name': 'toaster'}, {'frequency': 'f', 'synset': 'toaster_oven.n.01', 'synonyms': ['toaster_oven'], 'id': 1096, 'def': 'kitchen appliance consisting of a small electric oven for toasting or warming food', 'name': 'toaster_oven'}, {'frequency': 'f', 'synset': 'toilet.n.02', 'synonyms': ['toilet'], 'id': 1097, 'def': 'a plumbing fixture for defecation and urination', 'name': 'toilet'}, {'frequency': 'f', 'synset': 'toilet_tissue.n.01', 'synonyms': ['toilet_tissue', 'toilet_paper', 'bathroom_tissue'], 'id': 1098, 'def': 'a soft thin absorbent paper for use in toilets', 'name': 'toilet_tissue'}, {'frequency': 'f', 'synset': 'tomato.n.01', 'synonyms': ['tomato'], 'id': 1099, 'def': 'mildly acid red or yellow pulpy fruit eaten as a vegetable', 'name': 'tomato'}, {'frequency': 'f', 'synset': 'tongs.n.01', 'synonyms': ['tongs'], 'id': 1100, 'def': 'any of various devices for taking hold of objects; usually have two hinged legs with handles above and pointed hooks below', 'name': 'tongs'}, {'frequency': 'c', 'synset': 'toolbox.n.01', 'synonyms': ['toolbox'], 'id': 1101, 'def': 'a box or chest or cabinet for holding hand tools', 'name': 'toolbox'}, {'frequency': 'f', 'synset': 'toothbrush.n.01', 'synonyms': ['toothbrush'], 'id': 1102, 'def': 'small brush; has long handle; used to clean teeth', 'name': 'toothbrush'}, {'frequency': 'f', 'synset': 'toothpaste.n.01', 'synonyms': ['toothpaste'], 'id': 1103, 'def': 'a dentifrice in the form of a paste', 'name': 'toothpaste'}, {'frequency': 'f', 'synset': 'toothpick.n.01', 'synonyms': ['toothpick'], 'id': 1104, 'def': 'pick consisting of a small strip of wood or plastic; used to pick food from between the teeth', 'name': 'toothpick'}, {'frequency': 'f', 'synset': 'top.n.09', 'synonyms': ['cover'], 'id': 1105, 'def': 'covering for a hole (especially a hole in the top of a container)', 'name': 'cover'}, {'frequency': 'c', 'synset': 'tortilla.n.01', 'synonyms': ['tortilla'], 'id': 1106, 'def': 'thin unleavened pancake made from cornmeal or wheat flour', 'name': 'tortilla'}, {'frequency': 'c', 'synset': 'tow_truck.n.01', 'synonyms': ['tow_truck'], 'id': 1107, 'def': 'a truck equipped to hoist and pull wrecked cars (or to remove cars from no-parking zones)', 'name': 'tow_truck'}, {'frequency': 'f', 'synset': 'towel.n.01', 'synonyms': ['towel'], 'id': 1108, 'def': 'a rectangular piece of absorbent cloth (or paper) for drying or wiping', 'name': 'towel'}, {'frequency': 'f', 'synset': 'towel_rack.n.01', 'synonyms': ['towel_rack', 'towel_rail', 'towel_bar'], 'id': 1109, 'def': 'a rack consisting of one or more bars on which towels can be hung', 'name': 'towel_rack'}, {'frequency': 'f', 'synset': 'toy.n.03', 'synonyms': ['toy'], 'id': 1110, 'def': 'a device regarded as providing amusement', 'name': 'toy'}, {'frequency': 'c', 'synset': 'tractor.n.01', 'synonyms': ['tractor_(farm_equipment)'], 'id': 1111, 'def': 'a wheeled vehicle with large wheels; used in farming and other applications', 'name': 'tractor_(farm_equipment)'}, {'frequency': 'f', 'synset': 'traffic_light.n.01', 'synonyms': ['traffic_light'], 'id': 1112, 'def': 'a device to control vehicle traffic often consisting of three or more lights', 'name': 'traffic_light'}, {'frequency': 'c', 'synset': 'trail_bike.n.01', 'synonyms': ['dirt_bike'], 'id': 1113, 'def': 'a lightweight motorcycle equipped with rugged tires and suspension for off-road use', 'name': 'dirt_bike'}, {'frequency': 'f', 'synset': 'trailer_truck.n.01', 'synonyms': ['trailer_truck', 'tractor_trailer', 'trucking_rig', 'articulated_lorry', 'semi_truck'], 'id': 1114, 'def': 'a truck consisting of a tractor and trailer together', 'name': 'trailer_truck'}, {'frequency': 'f', 'synset': 'train.n.01', 'synonyms': ['train_(railroad_vehicle)', 'railroad_train'], 'id': 1115, 'def': 'public or private transport provided by a line of railway cars coupled together and drawn by a locomotive', 'name': 'train_(railroad_vehicle)'}, {'frequency': 'r', 'synset': 'trampoline.n.01', 'synonyms': ['trampoline'], 'id': 1116, 'def': 'gymnastic apparatus consisting of a strong canvas sheet attached with springs to a metal frame', 'name': 'trampoline'}, {'frequency': 'f', 'synset': 'tray.n.01', 'synonyms': ['tray'], 'id': 1117, 'def': 'an open receptacle for holding or displaying or serving articles or food', 'name': 'tray'}, {'frequency': 'r', 'synset': 'trench_coat.n.01', 'synonyms': ['trench_coat'], 'id': 1118, 'def': 'a military style raincoat; belted with deep pockets', 'name': 'trench_coat'}, {'frequency': 'r', 'synset': 'triangle.n.05', 'synonyms': ['triangle_(musical_instrument)'], 'id': 1119, 'def': 'a percussion instrument consisting of a metal bar bent in the shape of an open triangle', 'name': 'triangle_(musical_instrument)'}, {'frequency': 'c', 'synset': 'tricycle.n.01', 'synonyms': ['tricycle'], 'id': 1120, 'def': 'a vehicle with three wheels that is moved by foot pedals', 'name': 'tricycle'}, {'frequency': 'f', 'synset': 'tripod.n.01', 'synonyms': ['tripod'], 'id': 1121, 'def': 'a three-legged rack used for support', 'name': 'tripod'}, {'frequency': 'f', 'synset': 'trouser.n.01', 'synonyms': ['trousers', 'pants_(clothing)'], 'id': 1122, 'def': 'a garment extending from the waist to the knee or ankle, covering each leg separately', 'name': 'trousers'}, {'frequency': 'f', 'synset': 'truck.n.01', 'synonyms': ['truck'], 'id': 1123, 'def': 'an automotive vehicle suitable for hauling', 'name': 'truck'}, {'frequency': 'r', 'synset': 'truffle.n.03', 'synonyms': ['truffle_(chocolate)', 'chocolate_truffle'], 'id': 1124, 'def': 'creamy chocolate candy', 'name': 'truffle_(chocolate)'}, {'frequency': 'c', 'synset': 'trunk.n.02', 'synonyms': ['trunk'], 'id': 1125, 'def': 'luggage consisting of a large strong case used when traveling or for storage', 'name': 'trunk'}, {'frequency': 'r', 'synset': 'tub.n.02', 'synonyms': ['vat'], 'id': 1126, 'def': 'a large vessel for holding or storing liquids', 'name': 'vat'}, {'frequency': 'c', 'synset': 'turban.n.01', 'synonyms': ['turban'], 'id': 1127, 'def': 'a traditional headdress consisting of a long scarf wrapped around the head', 'name': 'turban'}, {'frequency': 'c', 'synset': 'turkey.n.04', 'synonyms': ['turkey_(food)'], 'id': 1128, 'def': 'flesh of large domesticated fowl usually roasted', 'name': 'turkey_(food)'}, {'frequency': 'r', 'synset': 'turnip.n.01', 'synonyms': ['turnip'], 'id': 1129, 'def': 'widely cultivated plant having a large fleshy edible white or yellow root', 'name': 'turnip'}, {'frequency': 'c', 'synset': 'turtle.n.02', 'synonyms': ['turtle'], 'id': 1130, 'def': 'any of various aquatic and land reptiles having a bony shell and flipper-like limbs for swimming', 'name': 'turtle'}, {'frequency': 'c', 'synset': 'turtleneck.n.01', 'synonyms': ['turtleneck_(clothing)', 'polo-neck'], 'id': 1131, 'def': 'a sweater or jersey with a high close-fitting collar', 'name': 'turtleneck_(clothing)'}, {'frequency': 'c', 'synset': 'typewriter.n.01', 'synonyms': ['typewriter'], 'id': 1132, 'def': 'hand-operated character printer for printing written messages one character at a time', 'name': 'typewriter'}, {'frequency': 'f', 'synset': 'umbrella.n.01', 'synonyms': ['umbrella'], 'id': 1133, 'def': 'a lightweight handheld collapsible canopy', 'name': 'umbrella'}, {'frequency': 'f', 'synset': 'underwear.n.01', 'synonyms': ['underwear', 'underclothes', 'underclothing', 'underpants'], 'id': 1134, 'def': 'undergarment worn next to the skin and under the outer garments', 'name': 'underwear'}, {'frequency': 'r', 'synset': 'unicycle.n.01', 'synonyms': ['unicycle'], 'id': 1135, 'def': 'a vehicle with a single wheel that is driven by pedals', 'name': 'unicycle'}, {'frequency': 'f', 'synset': 'urinal.n.01', 'synonyms': ['urinal'], 'id': 1136, 'def': 'a plumbing fixture (usually attached to the wall) used by men to urinate', 'name': 'urinal'}, {'frequency': 'c', 'synset': 'urn.n.01', 'synonyms': ['urn'], 'id': 1137, 'def': 'a large vase that usually has a pedestal or feet', 'name': 'urn'}, {'frequency': 'c', 'synset': 'vacuum.n.04', 'synonyms': ['vacuum_cleaner'], 'id': 1138, 'def': 'an electrical home appliance that cleans by suction', 'name': 'vacuum_cleaner'}, {'frequency': 'f', 'synset': 'vase.n.01', 'synonyms': ['vase'], 'id': 1139, 'def': 'an open jar of glass or porcelain used as an ornament or to hold flowers', 'name': 'vase'}, {'frequency': 'c', 'synset': 'vending_machine.n.01', 'synonyms': ['vending_machine'], 'id': 1140, 'def': 'a slot machine for selling goods', 'name': 'vending_machine'}, {'frequency': 'f', 'synset': 'vent.n.01', 'synonyms': ['vent', 'blowhole', 'air_vent'], 'id': 1141, 'def': 'a hole for the escape of gas or air', 'name': 'vent'}, {'frequency': 'f', 'synset': 'vest.n.01', 'synonyms': ['vest', 'waistcoat'], 'id': 1142, 'def': "a man's sleeveless garment worn underneath a coat", 'name': 'vest'}, {'frequency': 'c', 'synset': 'videotape.n.01', 'synonyms': ['videotape'], 'id': 1143, 'def': 'a video recording made on magnetic tape', 'name': 'videotape'}, {'frequency': 'r', 'synset': 'vinegar.n.01', 'synonyms': ['vinegar'], 'id': 1144, 'def': 'sour-tasting liquid produced usually by oxidation of the alcohol in wine or cider and used as a condiment or food preservative', 'name': 'vinegar'}, {'frequency': 'r', 'synset': 'violin.n.01', 'synonyms': ['violin', 'fiddle'], 'id': 1145, 'def': 'bowed stringed instrument that is the highest member of the violin family', 'name': 'violin'}, {'frequency': 'r', 'synset': 'vodka.n.01', 'synonyms': ['vodka'], 'id': 1146, 'def': 'unaged colorless liquor originating in Russia', 'name': 'vodka'}, {'frequency': 'c', 'synset': 'volleyball.n.02', 'synonyms': ['volleyball'], 'id': 1147, 'def': 'an inflated ball used in playing volleyball', 'name': 'volleyball'}, {'frequency': 'r', 'synset': 'vulture.n.01', 'synonyms': ['vulture'], 'id': 1148, 'def': 'any of various large birds of prey having naked heads and weak claws and feeding chiefly on carrion', 'name': 'vulture'}, {'frequency': 'c', 'synset': 'waffle.n.01', 'synonyms': ['waffle'], 'id': 1149, 'def': 'pancake batter baked in a waffle iron', 'name': 'waffle'}, {'frequency': 'r', 'synset': 'waffle_iron.n.01', 'synonyms': ['waffle_iron'], 'id': 1150, 'def': 'a kitchen appliance for baking waffles', 'name': 'waffle_iron'}, {'frequency': 'c', 'synset': 'wagon.n.01', 'synonyms': ['wagon'], 'id': 1151, 'def': 'any of various kinds of wheeled vehicles drawn by an animal or a tractor', 'name': 'wagon'}, {'frequency': 'c', 'synset': 'wagon_wheel.n.01', 'synonyms': ['wagon_wheel'], 'id': 1152, 'def': 'a wheel of a wagon', 'name': 'wagon_wheel'}, {'frequency': 'c', 'synset': 'walking_stick.n.01', 'synonyms': ['walking_stick'], 'id': 1153, 'def': 'a stick carried in the hand for support in walking', 'name': 'walking_stick'}, {'frequency': 'c', 'synset': 'wall_clock.n.01', 'synonyms': ['wall_clock'], 'id': 1154, 'def': 'a clock mounted on a wall', 'name': 'wall_clock'}, {'frequency': 'f', 'synset': 'wall_socket.n.01', 'synonyms': ['wall_socket', 'wall_plug', 'electric_outlet', 'electrical_outlet', 'outlet', 'electric_receptacle'], 'id': 1155, 'def': 'receptacle providing a place in a wiring system where current can be taken to run electrical devices', 'name': 'wall_socket'}, {'frequency': 'f', 'synset': 'wallet.n.01', 'synonyms': ['wallet', 'billfold'], 'id': 1156, 'def': 'a pocket-size case for holding papers and paper money', 'name': 'wallet'}, {'frequency': 'r', 'synset': 'walrus.n.01', 'synonyms': ['walrus'], 'id': 1157, 'def': 'either of two large northern marine mammals having ivory tusks and tough hide over thick blubber', 'name': 'walrus'}, {'frequency': 'r', 'synset': 'wardrobe.n.01', 'synonyms': ['wardrobe'], 'id': 1158, 'def': 'a tall piece of furniture that provides storage space for clothes; has a door and rails or hooks for hanging clothes', 'name': 'wardrobe'}, {'frequency': 'r', 'synset': 'washbasin.n.01', 'synonyms': ['washbasin', 'basin_(for_washing)', 'washbowl', 'washstand', 'handbasin'], 'id': 1159, 'def': 'a bathroom sink that is permanently installed and connected to a water supply and drainpipe; where you can wash your hands and face', 'name': 'washbasin'}, {'frequency': 'c', 'synset': 'washer.n.03', 'synonyms': ['automatic_washer', 'washing_machine'], 'id': 1160, 'def': 'a home appliance for washing clothes and linens automatically', 'name': 'automatic_washer'}, {'frequency': 'f', 'synset': 'watch.n.01', 'synonyms': ['watch', 'wristwatch'], 'id': 1161, 'def': 'a small, portable timepiece', 'name': 'watch'}, {'frequency': 'f', 'synset': 'water_bottle.n.01', 'synonyms': ['water_bottle'], 'id': 1162, 'def': 'a bottle for holding water', 'name': 'water_bottle'}, {'frequency': 'c', 'synset': 'water_cooler.n.01', 'synonyms': ['water_cooler'], 'id': 1163, 'def': 'a device for cooling and dispensing drinking water', 'name': 'water_cooler'}, {'frequency': 'c', 'synset': 'water_faucet.n.01', 'synonyms': ['water_faucet', 'water_tap', 'tap_(water_faucet)'], 'id': 1164, 'def': 'a faucet for drawing water from a pipe or cask', 'name': 'water_faucet'}, {'frequency': 'r', 'synset': 'water_heater.n.01', 'synonyms': ['water_heater', 'hot-water_heater'], 'id': 1165, 'def': 'a heater and storage tank to supply heated water', 'name': 'water_heater'}, {'frequency': 'c', 'synset': 'water_jug.n.01', 'synonyms': ['water_jug'], 'id': 1166, 'def': 'a jug that holds water', 'name': 'water_jug'}, {'frequency': 'r', 'synset': 'water_pistol.n.01', 'synonyms': ['water_gun', 'squirt_gun'], 'id': 1167, 'def': 'plaything consisting of a toy pistol that squirts water', 'name': 'water_gun'}, {'frequency': 'c', 'synset': 'water_scooter.n.01', 'synonyms': ['water_scooter', 'sea_scooter', 'jet_ski'], 'id': 1168, 'def': 'a motorboat resembling a motor scooter (NOT A SURFBOARD OR WATER SKI)', 'name': 'water_scooter'}, {'frequency': 'c', 'synset': 'water_ski.n.01', 'synonyms': ['water_ski'], 'id': 1169, 'def': 'broad ski for skimming over water towed by a speedboat (DO NOT MARK WATER)', 'name': 'water_ski'}, {'frequency': 'c', 'synset': 'water_tower.n.01', 'synonyms': ['water_tower'], 'id': 1170, 'def': 'a large reservoir for water', 'name': 'water_tower'}, {'frequency': 'c', 'synset': 'watering_can.n.01', 'synonyms': ['watering_can'], 'id': 1171, 'def': 'a container with a handle and a spout with a perforated nozzle; used to sprinkle water over plants', 'name': 'watering_can'}, {'frequency': 'f', 'synset': 'watermelon.n.02', 'synonyms': ['watermelon'], 'id': 1172, 'def': 'large oblong or roundish melon with a hard green rind and sweet watery red or occasionally yellowish pulp', 'name': 'watermelon'}, {'frequency': 'f', 'synset': 'weathervane.n.01', 'synonyms': ['weathervane', 'vane_(weathervane)', 'wind_vane'], 'id': 1173, 'def': 'mechanical device attached to an elevated structure; rotates freely to show the direction of the wind', 'name': 'weathervane'}, {'frequency': 'c', 'synset': 'webcam.n.01', 'synonyms': ['webcam'], 'id': 1174, 'def': 'a digital camera designed to take digital photographs and transmit them over the internet', 'name': 'webcam'}, {'frequency': 'c', 'synset': 'wedding_cake.n.01', 'synonyms': ['wedding_cake', 'bridecake'], 'id': 1175, 'def': 'a rich cake with two or more tiers and covered with frosting and decorations; served at a wedding reception', 'name': 'wedding_cake'}, {'frequency': 'c', 'synset': 'wedding_ring.n.01', 'synonyms': ['wedding_ring', 'wedding_band'], 'id': 1176, 'def': 'a ring given to the bride and/or groom at the wedding', 'name': 'wedding_ring'}, {'frequency': 'f', 'synset': 'wet_suit.n.01', 'synonyms': ['wet_suit'], 'id': 1177, 'def': 'a close-fitting garment made of a permeable material; worn in cold water to retain body heat', 'name': 'wet_suit'}, {'frequency': 'f', 'synset': 'wheel.n.01', 'synonyms': ['wheel'], 'id': 1178, 'def': 'a circular frame with spokes (or a solid disc) that can rotate on a shaft or axle', 'name': 'wheel'}, {'frequency': 'c', 'synset': 'wheelchair.n.01', 'synonyms': ['wheelchair'], 'id': 1179, 'def': 'a movable chair mounted on large wheels', 'name': 'wheelchair'}, {'frequency': 'c', 'synset': 'whipped_cream.n.01', 'synonyms': ['whipped_cream'], 'id': 1180, 'def': 'cream that has been beaten until light and fluffy', 'name': 'whipped_cream'}, {'frequency': 'c', 'synset': 'whistle.n.03', 'synonyms': ['whistle'], 'id': 1181, 'def': 'a small wind instrument that produces a whistling sound by blowing into it', 'name': 'whistle'}, {'frequency': 'c', 'synset': 'wig.n.01', 'synonyms': ['wig'], 'id': 1182, 'def': 'hairpiece covering the head and made of real or synthetic hair', 'name': 'wig'}, {'frequency': 'c', 'synset': 'wind_chime.n.01', 'synonyms': ['wind_chime'], 'id': 1183, 'def': 'a decorative arrangement of pieces of metal or glass or pottery that hang together loosely so the wind can cause them to tinkle', 'name': 'wind_chime'}, {'frequency': 'c', 'synset': 'windmill.n.01', 'synonyms': ['windmill'], 'id': 1184, 'def': 'A mill or turbine that is powered by wind', 'name': 'windmill'}, {'frequency': 'c', 'synset': 'window_box.n.01', 'synonyms': ['window_box_(for_plants)'], 'id': 1185, 'def': 'a container for growing plants on a windowsill', 'name': 'window_box_(for_plants)'}, {'frequency': 'f', 'synset': 'windshield_wiper.n.01', 'synonyms': ['windshield_wiper', 'windscreen_wiper', 'wiper_(for_windshield/screen)'], 'id': 1186, 'def': 'a mechanical device that cleans the windshield', 'name': 'windshield_wiper'}, {'frequency': 'c', 'synset': 'windsock.n.01', 'synonyms': ['windsock', 'air_sock', 'air-sleeve', 'wind_sleeve', 'wind_cone'], 'id': 1187, 'def': 'a truncated cloth cone mounted on a mast/pole; shows wind direction', 'name': 'windsock'}, {'frequency': 'f', 'synset': 'wine_bottle.n.01', 'synonyms': ['wine_bottle'], 'id': 1188, 'def': 'a bottle for holding wine', 'name': 'wine_bottle'}, {'frequency': 'c', 'synset': 'wine_bucket.n.01', 'synonyms': ['wine_bucket', 'wine_cooler'], 'id': 1189, 'def': 'a bucket of ice used to chill a bottle of wine', 'name': 'wine_bucket'}, {'frequency': 'f', 'synset': 'wineglass.n.01', 'synonyms': ['wineglass'], 'id': 1190, 'def': 'a glass that has a stem and in which wine is served', 'name': 'wineglass'}, {'frequency': 'f', 'synset': 'winker.n.02', 'synonyms': ['blinder_(for_horses)'], 'id': 1191, 'def': 'blinds that prevent a horse from seeing something on either side', 'name': 'blinder_(for_horses)'}, {'frequency': 'c', 'synset': 'wok.n.01', 'synonyms': ['wok'], 'id': 1192, 'def': 'pan with a convex bottom; used for frying in Chinese cooking', 'name': 'wok'}, {'frequency': 'r', 'synset': 'wolf.n.01', 'synonyms': ['wolf'], 'id': 1193, 'def': 'a wild carnivorous mammal of the dog family, living and hunting in packs', 'name': 'wolf'}, {'frequency': 'c', 'synset': 'wooden_spoon.n.02', 'synonyms': ['wooden_spoon'], 'id': 1194, 'def': 'a spoon made of wood', 'name': 'wooden_spoon'}, {'frequency': 'c', 'synset': 'wreath.n.01', 'synonyms': ['wreath'], 'id': 1195, 'def': 'an arrangement of flowers, leaves, or stems fastened in a ring', 'name': 'wreath'}, {'frequency': 'c', 'synset': 'wrench.n.03', 'synonyms': ['wrench', 'spanner'], 'id': 1196, 'def': 'a hand tool that is used to hold or twist a nut or bolt', 'name': 'wrench'}, {'frequency': 'f', 'synset': 'wristband.n.01', 'synonyms': ['wristband'], 'id': 1197, 'def': 'band consisting of a part of a sleeve that covers the wrist', 'name': 'wristband'}, {'frequency': 'f', 'synset': 'wristlet.n.01', 'synonyms': ['wristlet', 'wrist_band'], 'id': 1198, 'def': 'a band or bracelet worn around the wrist', 'name': 'wristlet'}, {'frequency': 'c', 'synset': 'yacht.n.01', 'synonyms': ['yacht'], 'id': 1199, 'def': 'an expensive vessel propelled by sail or power and used for cruising or racing', 'name': 'yacht'}, {'frequency': 'c', 'synset': 'yogurt.n.01', 'synonyms': ['yogurt', 'yoghurt', 'yoghourt'], 'id': 1200, 'def': 'a custard-like food made from curdled milk', 'name': 'yogurt'}, {'frequency': 'c', 'synset': 'yoke.n.07', 'synonyms': ['yoke_(animal_equipment)'], 'id': 1201, 'def': 'gear joining two animals at the neck; NOT egg yolk', 'name': 'yoke_(animal_equipment)'}, {'frequency': 'f', 'synset': 'zebra.n.01', 'synonyms': ['zebra'], 'id': 1202, 'def': 'any of several fleet black-and-white striped African equines', 'name': 'zebra'}, {'frequency': 'c', 'synset': 'zucchini.n.02', 'synonyms': ['zucchini', 'courgette'], 'id': 1203, 'def': 'small cucumber-shaped vegetable marrow; typically dark green', 'name': 'zucchini'}] # noqa +# fmt: on diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/lvis_v1_category_image_count.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/lvis_v1_category_image_count.py new file mode 100644 index 00000000..31bf0cfc --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/lvis_v1_category_image_count.py @@ -0,0 +1,20 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# Autogen with +# with open("lvis_v1_train.json", "r") as f: +# a = json.load(f) +# c = a["categories"] +# for x in c: +# del x["name"] +# del x["instance_count"] +# del x["def"] +# del x["synonyms"] +# del x["frequency"] +# del x["synset"] +# LVIS_CATEGORY_IMAGE_COUNT = repr(c) + " # noqa" +# with open("/tmp/lvis_category_image_count.py", "wt") as f: +# f.write(f"LVIS_CATEGORY_IMAGE_COUNT = {LVIS_CATEGORY_IMAGE_COUNT}") +# Then paste the contents of that file below + +# fmt: off +LVIS_CATEGORY_IMAGE_COUNT = [{'id': 1, 'image_count': 64}, {'id': 2, 'image_count': 364}, {'id': 3, 'image_count': 1911}, {'id': 4, 'image_count': 149}, {'id': 5, 'image_count': 29}, {'id': 6, 'image_count': 26}, {'id': 7, 'image_count': 59}, {'id': 8, 'image_count': 22}, {'id': 9, 'image_count': 12}, {'id': 10, 'image_count': 28}, {'id': 11, 'image_count': 505}, {'id': 12, 'image_count': 1207}, {'id': 13, 'image_count': 4}, {'id': 14, 'image_count': 10}, {'id': 15, 'image_count': 500}, {'id': 16, 'image_count': 33}, {'id': 17, 'image_count': 3}, {'id': 18, 'image_count': 44}, {'id': 19, 'image_count': 561}, {'id': 20, 'image_count': 8}, {'id': 21, 'image_count': 9}, {'id': 22, 'image_count': 33}, {'id': 23, 'image_count': 1883}, {'id': 24, 'image_count': 98}, {'id': 25, 'image_count': 70}, {'id': 26, 'image_count': 46}, {'id': 27, 'image_count': 117}, {'id': 28, 'image_count': 41}, {'id': 29, 'image_count': 1395}, {'id': 30, 'image_count': 7}, {'id': 31, 'image_count': 1}, {'id': 32, 'image_count': 314}, {'id': 33, 'image_count': 31}, {'id': 34, 'image_count': 1905}, {'id': 35, 'image_count': 1859}, {'id': 36, 'image_count': 1623}, {'id': 37, 'image_count': 47}, {'id': 38, 'image_count': 3}, {'id': 39, 'image_count': 3}, {'id': 40, 'image_count': 1}, {'id': 41, 'image_count': 305}, {'id': 42, 'image_count': 6}, {'id': 43, 'image_count': 210}, {'id': 44, 'image_count': 36}, {'id': 45, 'image_count': 1787}, {'id': 46, 'image_count': 17}, {'id': 47, 'image_count': 51}, {'id': 48, 'image_count': 138}, {'id': 49, 'image_count': 3}, {'id': 50, 'image_count': 1470}, {'id': 51, 'image_count': 3}, {'id': 52, 'image_count': 2}, {'id': 53, 'image_count': 186}, {'id': 54, 'image_count': 76}, {'id': 55, 'image_count': 26}, {'id': 56, 'image_count': 303}, {'id': 57, 'image_count': 738}, {'id': 58, 'image_count': 1799}, {'id': 59, 'image_count': 1934}, {'id': 60, 'image_count': 1609}, {'id': 61, 'image_count': 1622}, {'id': 62, 'image_count': 41}, {'id': 63, 'image_count': 4}, {'id': 64, 'image_count': 11}, {'id': 65, 'image_count': 270}, {'id': 66, 'image_count': 349}, {'id': 67, 'image_count': 42}, {'id': 68, 'image_count': 823}, {'id': 69, 'image_count': 6}, {'id': 70, 'image_count': 48}, {'id': 71, 'image_count': 3}, {'id': 72, 'image_count': 42}, {'id': 73, 'image_count': 24}, {'id': 74, 'image_count': 16}, {'id': 75, 'image_count': 605}, {'id': 76, 'image_count': 646}, {'id': 77, 'image_count': 1765}, {'id': 78, 'image_count': 2}, {'id': 79, 'image_count': 125}, {'id': 80, 'image_count': 1420}, {'id': 81, 'image_count': 140}, {'id': 82, 'image_count': 4}, {'id': 83, 'image_count': 322}, {'id': 84, 'image_count': 60}, {'id': 85, 'image_count': 2}, {'id': 86, 'image_count': 231}, {'id': 87, 'image_count': 333}, {'id': 88, 'image_count': 1941}, {'id': 89, 'image_count': 367}, {'id': 90, 'image_count': 1922}, {'id': 91, 'image_count': 18}, {'id': 92, 'image_count': 81}, {'id': 93, 'image_count': 1}, {'id': 94, 'image_count': 1852}, {'id': 95, 'image_count': 430}, {'id': 96, 'image_count': 247}, {'id': 97, 'image_count': 94}, {'id': 98, 'image_count': 21}, {'id': 99, 'image_count': 1821}, {'id': 100, 'image_count': 16}, {'id': 101, 'image_count': 12}, {'id': 102, 'image_count': 25}, {'id': 103, 'image_count': 41}, {'id': 104, 'image_count': 244}, {'id': 105, 'image_count': 7}, {'id': 106, 'image_count': 1}, {'id': 107, 'image_count': 40}, {'id': 108, 'image_count': 40}, {'id': 109, 'image_count': 104}, {'id': 110, 'image_count': 1671}, {'id': 111, 'image_count': 49}, {'id': 112, 'image_count': 243}, {'id': 113, 'image_count': 2}, {'id': 114, 'image_count': 242}, {'id': 115, 'image_count': 271}, {'id': 116, 'image_count': 104}, {'id': 117, 'image_count': 8}, {'id': 118, 'image_count': 1758}, {'id': 119, 'image_count': 1}, {'id': 120, 'image_count': 48}, {'id': 121, 'image_count': 14}, {'id': 122, 'image_count': 40}, {'id': 123, 'image_count': 1}, {'id': 124, 'image_count': 37}, {'id': 125, 'image_count': 1510}, {'id': 126, 'image_count': 6}, {'id': 127, 'image_count': 1903}, {'id': 128, 'image_count': 70}, {'id': 129, 'image_count': 86}, {'id': 130, 'image_count': 7}, {'id': 131, 'image_count': 5}, {'id': 132, 'image_count': 1406}, {'id': 133, 'image_count': 1901}, {'id': 134, 'image_count': 15}, {'id': 135, 'image_count': 28}, {'id': 136, 'image_count': 6}, {'id': 137, 'image_count': 494}, {'id': 138, 'image_count': 234}, {'id': 139, 'image_count': 1922}, {'id': 140, 'image_count': 1}, {'id': 141, 'image_count': 35}, {'id': 142, 'image_count': 5}, {'id': 143, 'image_count': 1828}, {'id': 144, 'image_count': 8}, {'id': 145, 'image_count': 63}, {'id': 146, 'image_count': 1668}, {'id': 147, 'image_count': 4}, {'id': 148, 'image_count': 95}, {'id': 149, 'image_count': 17}, {'id': 150, 'image_count': 1567}, {'id': 151, 'image_count': 2}, {'id': 152, 'image_count': 103}, {'id': 153, 'image_count': 50}, {'id': 154, 'image_count': 1309}, {'id': 155, 'image_count': 6}, {'id': 156, 'image_count': 92}, {'id': 157, 'image_count': 19}, {'id': 158, 'image_count': 37}, {'id': 159, 'image_count': 4}, {'id': 160, 'image_count': 709}, {'id': 161, 'image_count': 9}, {'id': 162, 'image_count': 82}, {'id': 163, 'image_count': 15}, {'id': 164, 'image_count': 3}, {'id': 165, 'image_count': 61}, {'id': 166, 'image_count': 51}, {'id': 167, 'image_count': 5}, {'id': 168, 'image_count': 13}, {'id': 169, 'image_count': 642}, {'id': 170, 'image_count': 24}, {'id': 171, 'image_count': 255}, {'id': 172, 'image_count': 9}, {'id': 173, 'image_count': 1808}, {'id': 174, 'image_count': 31}, {'id': 175, 'image_count': 158}, {'id': 176, 'image_count': 80}, {'id': 177, 'image_count': 1884}, {'id': 178, 'image_count': 158}, {'id': 179, 'image_count': 2}, {'id': 180, 'image_count': 12}, {'id': 181, 'image_count': 1659}, {'id': 182, 'image_count': 7}, {'id': 183, 'image_count': 834}, {'id': 184, 'image_count': 57}, {'id': 185, 'image_count': 174}, {'id': 186, 'image_count': 95}, {'id': 187, 'image_count': 27}, {'id': 188, 'image_count': 22}, {'id': 189, 'image_count': 1391}, {'id': 190, 'image_count': 90}, {'id': 191, 'image_count': 40}, {'id': 192, 'image_count': 445}, {'id': 193, 'image_count': 21}, {'id': 194, 'image_count': 1132}, {'id': 195, 'image_count': 177}, {'id': 196, 'image_count': 4}, {'id': 197, 'image_count': 17}, {'id': 198, 'image_count': 84}, {'id': 199, 'image_count': 55}, {'id': 200, 'image_count': 30}, {'id': 201, 'image_count': 25}, {'id': 202, 'image_count': 2}, {'id': 203, 'image_count': 125}, {'id': 204, 'image_count': 1135}, {'id': 205, 'image_count': 19}, {'id': 206, 'image_count': 72}, {'id': 207, 'image_count': 1926}, {'id': 208, 'image_count': 159}, {'id': 209, 'image_count': 7}, {'id': 210, 'image_count': 1}, {'id': 211, 'image_count': 13}, {'id': 212, 'image_count': 35}, {'id': 213, 'image_count': 18}, {'id': 214, 'image_count': 8}, {'id': 215, 'image_count': 6}, {'id': 216, 'image_count': 35}, {'id': 217, 'image_count': 1222}, {'id': 218, 'image_count': 103}, {'id': 219, 'image_count': 28}, {'id': 220, 'image_count': 63}, {'id': 221, 'image_count': 28}, {'id': 222, 'image_count': 5}, {'id': 223, 'image_count': 7}, {'id': 224, 'image_count': 14}, {'id': 225, 'image_count': 1918}, {'id': 226, 'image_count': 133}, {'id': 227, 'image_count': 16}, {'id': 228, 'image_count': 27}, {'id': 229, 'image_count': 110}, {'id': 230, 'image_count': 1895}, {'id': 231, 'image_count': 4}, {'id': 232, 'image_count': 1927}, {'id': 233, 'image_count': 8}, {'id': 234, 'image_count': 1}, {'id': 235, 'image_count': 263}, {'id': 236, 'image_count': 10}, {'id': 237, 'image_count': 2}, {'id': 238, 'image_count': 3}, {'id': 239, 'image_count': 87}, {'id': 240, 'image_count': 9}, {'id': 241, 'image_count': 71}, {'id': 242, 'image_count': 13}, {'id': 243, 'image_count': 18}, {'id': 244, 'image_count': 2}, {'id': 245, 'image_count': 5}, {'id': 246, 'image_count': 45}, {'id': 247, 'image_count': 1}, {'id': 248, 'image_count': 23}, {'id': 249, 'image_count': 32}, {'id': 250, 'image_count': 4}, {'id': 251, 'image_count': 1}, {'id': 252, 'image_count': 858}, {'id': 253, 'image_count': 661}, {'id': 254, 'image_count': 168}, {'id': 255, 'image_count': 210}, {'id': 256, 'image_count': 65}, {'id': 257, 'image_count': 4}, {'id': 258, 'image_count': 2}, {'id': 259, 'image_count': 159}, {'id': 260, 'image_count': 31}, {'id': 261, 'image_count': 811}, {'id': 262, 'image_count': 1}, {'id': 263, 'image_count': 42}, {'id': 264, 'image_count': 27}, {'id': 265, 'image_count': 2}, {'id': 266, 'image_count': 5}, {'id': 267, 'image_count': 95}, {'id': 268, 'image_count': 32}, {'id': 269, 'image_count': 1}, {'id': 270, 'image_count': 1}, {'id': 271, 'image_count': 1844}, {'id': 272, 'image_count': 897}, {'id': 273, 'image_count': 31}, {'id': 274, 'image_count': 23}, {'id': 275, 'image_count': 1}, {'id': 276, 'image_count': 202}, {'id': 277, 'image_count': 746}, {'id': 278, 'image_count': 44}, {'id': 279, 'image_count': 14}, {'id': 280, 'image_count': 26}, {'id': 281, 'image_count': 1}, {'id': 282, 'image_count': 2}, {'id': 283, 'image_count': 25}, {'id': 284, 'image_count': 238}, {'id': 285, 'image_count': 592}, {'id': 286, 'image_count': 26}, {'id': 287, 'image_count': 5}, {'id': 288, 'image_count': 42}, {'id': 289, 'image_count': 13}, {'id': 290, 'image_count': 46}, {'id': 291, 'image_count': 1}, {'id': 292, 'image_count': 8}, {'id': 293, 'image_count': 34}, {'id': 294, 'image_count': 5}, {'id': 295, 'image_count': 1}, {'id': 296, 'image_count': 1871}, {'id': 297, 'image_count': 717}, {'id': 298, 'image_count': 1010}, {'id': 299, 'image_count': 679}, {'id': 300, 'image_count': 3}, {'id': 301, 'image_count': 4}, {'id': 302, 'image_count': 1}, {'id': 303, 'image_count': 166}, {'id': 304, 'image_count': 2}, {'id': 305, 'image_count': 266}, {'id': 306, 'image_count': 101}, {'id': 307, 'image_count': 6}, {'id': 308, 'image_count': 14}, {'id': 309, 'image_count': 133}, {'id': 310, 'image_count': 2}, {'id': 311, 'image_count': 38}, {'id': 312, 'image_count': 95}, {'id': 313, 'image_count': 1}, {'id': 314, 'image_count': 12}, {'id': 315, 'image_count': 49}, {'id': 316, 'image_count': 5}, {'id': 317, 'image_count': 5}, {'id': 318, 'image_count': 16}, {'id': 319, 'image_count': 216}, {'id': 320, 'image_count': 12}, {'id': 321, 'image_count': 1}, {'id': 322, 'image_count': 54}, {'id': 323, 'image_count': 5}, {'id': 324, 'image_count': 245}, {'id': 325, 'image_count': 12}, {'id': 326, 'image_count': 7}, {'id': 327, 'image_count': 35}, {'id': 328, 'image_count': 36}, {'id': 329, 'image_count': 32}, {'id': 330, 'image_count': 1027}, {'id': 331, 'image_count': 10}, {'id': 332, 'image_count': 12}, {'id': 333, 'image_count': 1}, {'id': 334, 'image_count': 67}, {'id': 335, 'image_count': 71}, {'id': 336, 'image_count': 30}, {'id': 337, 'image_count': 48}, {'id': 338, 'image_count': 249}, {'id': 339, 'image_count': 13}, {'id': 340, 'image_count': 29}, {'id': 341, 'image_count': 14}, {'id': 342, 'image_count': 236}, {'id': 343, 'image_count': 15}, {'id': 344, 'image_count': 1521}, {'id': 345, 'image_count': 25}, {'id': 346, 'image_count': 249}, {'id': 347, 'image_count': 139}, {'id': 348, 'image_count': 2}, {'id': 349, 'image_count': 2}, {'id': 350, 'image_count': 1890}, {'id': 351, 'image_count': 1240}, {'id': 352, 'image_count': 1}, {'id': 353, 'image_count': 9}, {'id': 354, 'image_count': 1}, {'id': 355, 'image_count': 3}, {'id': 356, 'image_count': 11}, {'id': 357, 'image_count': 4}, {'id': 358, 'image_count': 236}, {'id': 359, 'image_count': 44}, {'id': 360, 'image_count': 19}, {'id': 361, 'image_count': 1100}, {'id': 362, 'image_count': 7}, {'id': 363, 'image_count': 69}, {'id': 364, 'image_count': 2}, {'id': 365, 'image_count': 8}, {'id': 366, 'image_count': 5}, {'id': 367, 'image_count': 227}, {'id': 368, 'image_count': 6}, {'id': 369, 'image_count': 106}, {'id': 370, 'image_count': 81}, {'id': 371, 'image_count': 17}, {'id': 372, 'image_count': 134}, {'id': 373, 'image_count': 312}, {'id': 374, 'image_count': 8}, {'id': 375, 'image_count': 271}, {'id': 376, 'image_count': 2}, {'id': 377, 'image_count': 103}, {'id': 378, 'image_count': 1938}, {'id': 379, 'image_count': 574}, {'id': 380, 'image_count': 120}, {'id': 381, 'image_count': 2}, {'id': 382, 'image_count': 2}, {'id': 383, 'image_count': 13}, {'id': 384, 'image_count': 29}, {'id': 385, 'image_count': 1710}, {'id': 386, 'image_count': 66}, {'id': 387, 'image_count': 1008}, {'id': 388, 'image_count': 1}, {'id': 389, 'image_count': 3}, {'id': 390, 'image_count': 1942}, {'id': 391, 'image_count': 19}, {'id': 392, 'image_count': 1488}, {'id': 393, 'image_count': 46}, {'id': 394, 'image_count': 106}, {'id': 395, 'image_count': 115}, {'id': 396, 'image_count': 19}, {'id': 397, 'image_count': 2}, {'id': 398, 'image_count': 1}, {'id': 399, 'image_count': 28}, {'id': 400, 'image_count': 9}, {'id': 401, 'image_count': 192}, {'id': 402, 'image_count': 12}, {'id': 403, 'image_count': 21}, {'id': 404, 'image_count': 247}, {'id': 405, 'image_count': 6}, {'id': 406, 'image_count': 64}, {'id': 407, 'image_count': 7}, {'id': 408, 'image_count': 40}, {'id': 409, 'image_count': 542}, {'id': 410, 'image_count': 2}, {'id': 411, 'image_count': 1898}, {'id': 412, 'image_count': 36}, {'id': 413, 'image_count': 4}, {'id': 414, 'image_count': 1}, {'id': 415, 'image_count': 191}, {'id': 416, 'image_count': 6}, {'id': 417, 'image_count': 41}, {'id': 418, 'image_count': 39}, {'id': 419, 'image_count': 46}, {'id': 420, 'image_count': 1}, {'id': 421, 'image_count': 1451}, {'id': 422, 'image_count': 1878}, {'id': 423, 'image_count': 11}, {'id': 424, 'image_count': 82}, {'id': 425, 'image_count': 18}, {'id': 426, 'image_count': 1}, {'id': 427, 'image_count': 7}, {'id': 428, 'image_count': 3}, {'id': 429, 'image_count': 575}, {'id': 430, 'image_count': 1907}, {'id': 431, 'image_count': 8}, {'id': 432, 'image_count': 4}, {'id': 433, 'image_count': 32}, {'id': 434, 'image_count': 11}, {'id': 435, 'image_count': 4}, {'id': 436, 'image_count': 54}, {'id': 437, 'image_count': 202}, {'id': 438, 'image_count': 32}, {'id': 439, 'image_count': 3}, {'id': 440, 'image_count': 130}, {'id': 441, 'image_count': 119}, {'id': 442, 'image_count': 141}, {'id': 443, 'image_count': 29}, {'id': 444, 'image_count': 525}, {'id': 445, 'image_count': 1323}, {'id': 446, 'image_count': 2}, {'id': 447, 'image_count': 113}, {'id': 448, 'image_count': 16}, {'id': 449, 'image_count': 7}, {'id': 450, 'image_count': 35}, {'id': 451, 'image_count': 1908}, {'id': 452, 'image_count': 353}, {'id': 453, 'image_count': 18}, {'id': 454, 'image_count': 14}, {'id': 455, 'image_count': 77}, {'id': 456, 'image_count': 8}, {'id': 457, 'image_count': 37}, {'id': 458, 'image_count': 1}, {'id': 459, 'image_count': 346}, {'id': 460, 'image_count': 19}, {'id': 461, 'image_count': 1779}, {'id': 462, 'image_count': 23}, {'id': 463, 'image_count': 25}, {'id': 464, 'image_count': 67}, {'id': 465, 'image_count': 19}, {'id': 466, 'image_count': 28}, {'id': 467, 'image_count': 4}, {'id': 468, 'image_count': 27}, {'id': 469, 'image_count': 1861}, {'id': 470, 'image_count': 11}, {'id': 471, 'image_count': 13}, {'id': 472, 'image_count': 13}, {'id': 473, 'image_count': 32}, {'id': 474, 'image_count': 1767}, {'id': 475, 'image_count': 42}, {'id': 476, 'image_count': 17}, {'id': 477, 'image_count': 128}, {'id': 478, 'image_count': 1}, {'id': 479, 'image_count': 9}, {'id': 480, 'image_count': 10}, {'id': 481, 'image_count': 4}, {'id': 482, 'image_count': 9}, {'id': 483, 'image_count': 18}, {'id': 484, 'image_count': 41}, {'id': 485, 'image_count': 28}, {'id': 486, 'image_count': 3}, {'id': 487, 'image_count': 65}, {'id': 488, 'image_count': 9}, {'id': 489, 'image_count': 23}, {'id': 490, 'image_count': 24}, {'id': 491, 'image_count': 1}, {'id': 492, 'image_count': 2}, {'id': 493, 'image_count': 59}, {'id': 494, 'image_count': 48}, {'id': 495, 'image_count': 17}, {'id': 496, 'image_count': 1877}, {'id': 497, 'image_count': 18}, {'id': 498, 'image_count': 1920}, {'id': 499, 'image_count': 50}, {'id': 500, 'image_count': 1890}, {'id': 501, 'image_count': 99}, {'id': 502, 'image_count': 1530}, {'id': 503, 'image_count': 3}, {'id': 504, 'image_count': 11}, {'id': 505, 'image_count': 19}, {'id': 506, 'image_count': 3}, {'id': 507, 'image_count': 63}, {'id': 508, 'image_count': 5}, {'id': 509, 'image_count': 6}, {'id': 510, 'image_count': 233}, {'id': 511, 'image_count': 54}, {'id': 512, 'image_count': 36}, {'id': 513, 'image_count': 10}, {'id': 514, 'image_count': 124}, {'id': 515, 'image_count': 101}, {'id': 516, 'image_count': 3}, {'id': 517, 'image_count': 363}, {'id': 518, 'image_count': 3}, {'id': 519, 'image_count': 30}, {'id': 520, 'image_count': 18}, {'id': 521, 'image_count': 199}, {'id': 522, 'image_count': 97}, {'id': 523, 'image_count': 32}, {'id': 524, 'image_count': 121}, {'id': 525, 'image_count': 16}, {'id': 526, 'image_count': 12}, {'id': 527, 'image_count': 2}, {'id': 528, 'image_count': 214}, {'id': 529, 'image_count': 48}, {'id': 530, 'image_count': 26}, {'id': 531, 'image_count': 13}, {'id': 532, 'image_count': 4}, {'id': 533, 'image_count': 11}, {'id': 534, 'image_count': 123}, {'id': 535, 'image_count': 7}, {'id': 536, 'image_count': 200}, {'id': 537, 'image_count': 91}, {'id': 538, 'image_count': 9}, {'id': 539, 'image_count': 72}, {'id': 540, 'image_count': 1886}, {'id': 541, 'image_count': 4}, {'id': 542, 'image_count': 1}, {'id': 543, 'image_count': 1}, {'id': 544, 'image_count': 1932}, {'id': 545, 'image_count': 4}, {'id': 546, 'image_count': 56}, {'id': 547, 'image_count': 854}, {'id': 548, 'image_count': 755}, {'id': 549, 'image_count': 1843}, {'id': 550, 'image_count': 96}, {'id': 551, 'image_count': 7}, {'id': 552, 'image_count': 74}, {'id': 553, 'image_count': 66}, {'id': 554, 'image_count': 57}, {'id': 555, 'image_count': 44}, {'id': 556, 'image_count': 1905}, {'id': 557, 'image_count': 4}, {'id': 558, 'image_count': 90}, {'id': 559, 'image_count': 1635}, {'id': 560, 'image_count': 8}, {'id': 561, 'image_count': 5}, {'id': 562, 'image_count': 50}, {'id': 563, 'image_count': 545}, {'id': 564, 'image_count': 20}, {'id': 565, 'image_count': 193}, {'id': 566, 'image_count': 285}, {'id': 567, 'image_count': 3}, {'id': 568, 'image_count': 1}, {'id': 569, 'image_count': 1904}, {'id': 570, 'image_count': 294}, {'id': 571, 'image_count': 3}, {'id': 572, 'image_count': 5}, {'id': 573, 'image_count': 24}, {'id': 574, 'image_count': 2}, {'id': 575, 'image_count': 2}, {'id': 576, 'image_count': 16}, {'id': 577, 'image_count': 8}, {'id': 578, 'image_count': 154}, {'id': 579, 'image_count': 66}, {'id': 580, 'image_count': 1}, {'id': 581, 'image_count': 24}, {'id': 582, 'image_count': 1}, {'id': 583, 'image_count': 4}, {'id': 584, 'image_count': 75}, {'id': 585, 'image_count': 6}, {'id': 586, 'image_count': 126}, {'id': 587, 'image_count': 24}, {'id': 588, 'image_count': 22}, {'id': 589, 'image_count': 1872}, {'id': 590, 'image_count': 16}, {'id': 591, 'image_count': 423}, {'id': 592, 'image_count': 1927}, {'id': 593, 'image_count': 38}, {'id': 594, 'image_count': 3}, {'id': 595, 'image_count': 1945}, {'id': 596, 'image_count': 35}, {'id': 597, 'image_count': 1}, {'id': 598, 'image_count': 13}, {'id': 599, 'image_count': 9}, {'id': 600, 'image_count': 14}, {'id': 601, 'image_count': 37}, {'id': 602, 'image_count': 3}, {'id': 603, 'image_count': 4}, {'id': 604, 'image_count': 100}, {'id': 605, 'image_count': 195}, {'id': 606, 'image_count': 1}, {'id': 607, 'image_count': 12}, {'id': 608, 'image_count': 24}, {'id': 609, 'image_count': 489}, {'id': 610, 'image_count': 10}, {'id': 611, 'image_count': 1689}, {'id': 612, 'image_count': 42}, {'id': 613, 'image_count': 81}, {'id': 614, 'image_count': 894}, {'id': 615, 'image_count': 1868}, {'id': 616, 'image_count': 7}, {'id': 617, 'image_count': 1567}, {'id': 618, 'image_count': 10}, {'id': 619, 'image_count': 8}, {'id': 620, 'image_count': 7}, {'id': 621, 'image_count': 629}, {'id': 622, 'image_count': 89}, {'id': 623, 'image_count': 15}, {'id': 624, 'image_count': 134}, {'id': 625, 'image_count': 4}, {'id': 626, 'image_count': 1802}, {'id': 627, 'image_count': 595}, {'id': 628, 'image_count': 1210}, {'id': 629, 'image_count': 48}, {'id': 630, 'image_count': 418}, {'id': 631, 'image_count': 1846}, {'id': 632, 'image_count': 5}, {'id': 633, 'image_count': 221}, {'id': 634, 'image_count': 10}, {'id': 635, 'image_count': 7}, {'id': 636, 'image_count': 76}, {'id': 637, 'image_count': 22}, {'id': 638, 'image_count': 10}, {'id': 639, 'image_count': 341}, {'id': 640, 'image_count': 1}, {'id': 641, 'image_count': 705}, {'id': 642, 'image_count': 1900}, {'id': 643, 'image_count': 188}, {'id': 644, 'image_count': 227}, {'id': 645, 'image_count': 861}, {'id': 646, 'image_count': 6}, {'id': 647, 'image_count': 115}, {'id': 648, 'image_count': 5}, {'id': 649, 'image_count': 43}, {'id': 650, 'image_count': 14}, {'id': 651, 'image_count': 6}, {'id': 652, 'image_count': 15}, {'id': 653, 'image_count': 1167}, {'id': 654, 'image_count': 15}, {'id': 655, 'image_count': 994}, {'id': 656, 'image_count': 28}, {'id': 657, 'image_count': 2}, {'id': 658, 'image_count': 338}, {'id': 659, 'image_count': 334}, {'id': 660, 'image_count': 15}, {'id': 661, 'image_count': 102}, {'id': 662, 'image_count': 1}, {'id': 663, 'image_count': 8}, {'id': 664, 'image_count': 1}, {'id': 665, 'image_count': 1}, {'id': 666, 'image_count': 28}, {'id': 667, 'image_count': 91}, {'id': 668, 'image_count': 260}, {'id': 669, 'image_count': 131}, {'id': 670, 'image_count': 128}, {'id': 671, 'image_count': 3}, {'id': 672, 'image_count': 10}, {'id': 673, 'image_count': 39}, {'id': 674, 'image_count': 2}, {'id': 675, 'image_count': 925}, {'id': 676, 'image_count': 354}, {'id': 677, 'image_count': 31}, {'id': 678, 'image_count': 10}, {'id': 679, 'image_count': 215}, {'id': 680, 'image_count': 71}, {'id': 681, 'image_count': 43}, {'id': 682, 'image_count': 28}, {'id': 683, 'image_count': 34}, {'id': 684, 'image_count': 16}, {'id': 685, 'image_count': 273}, {'id': 686, 'image_count': 2}, {'id': 687, 'image_count': 999}, {'id': 688, 'image_count': 4}, {'id': 689, 'image_count': 107}, {'id': 690, 'image_count': 2}, {'id': 691, 'image_count': 1}, {'id': 692, 'image_count': 454}, {'id': 693, 'image_count': 9}, {'id': 694, 'image_count': 1901}, {'id': 695, 'image_count': 61}, {'id': 696, 'image_count': 91}, {'id': 697, 'image_count': 46}, {'id': 698, 'image_count': 1402}, {'id': 699, 'image_count': 74}, {'id': 700, 'image_count': 421}, {'id': 701, 'image_count': 226}, {'id': 702, 'image_count': 10}, {'id': 703, 'image_count': 1720}, {'id': 704, 'image_count': 261}, {'id': 705, 'image_count': 1337}, {'id': 706, 'image_count': 293}, {'id': 707, 'image_count': 62}, {'id': 708, 'image_count': 814}, {'id': 709, 'image_count': 407}, {'id': 710, 'image_count': 6}, {'id': 711, 'image_count': 16}, {'id': 712, 'image_count': 7}, {'id': 713, 'image_count': 1791}, {'id': 714, 'image_count': 2}, {'id': 715, 'image_count': 1915}, {'id': 716, 'image_count': 1940}, {'id': 717, 'image_count': 13}, {'id': 718, 'image_count': 16}, {'id': 719, 'image_count': 448}, {'id': 720, 'image_count': 12}, {'id': 721, 'image_count': 18}, {'id': 722, 'image_count': 4}, {'id': 723, 'image_count': 71}, {'id': 724, 'image_count': 189}, {'id': 725, 'image_count': 74}, {'id': 726, 'image_count': 103}, {'id': 727, 'image_count': 3}, {'id': 728, 'image_count': 110}, {'id': 729, 'image_count': 5}, {'id': 730, 'image_count': 9}, {'id': 731, 'image_count': 15}, {'id': 732, 'image_count': 25}, {'id': 733, 'image_count': 7}, {'id': 734, 'image_count': 647}, {'id': 735, 'image_count': 824}, {'id': 736, 'image_count': 100}, {'id': 737, 'image_count': 47}, {'id': 738, 'image_count': 121}, {'id': 739, 'image_count': 731}, {'id': 740, 'image_count': 73}, {'id': 741, 'image_count': 49}, {'id': 742, 'image_count': 23}, {'id': 743, 'image_count': 4}, {'id': 744, 'image_count': 62}, {'id': 745, 'image_count': 118}, {'id': 746, 'image_count': 99}, {'id': 747, 'image_count': 40}, {'id': 748, 'image_count': 1036}, {'id': 749, 'image_count': 105}, {'id': 750, 'image_count': 21}, {'id': 751, 'image_count': 229}, {'id': 752, 'image_count': 7}, {'id': 753, 'image_count': 72}, {'id': 754, 'image_count': 9}, {'id': 755, 'image_count': 10}, {'id': 756, 'image_count': 328}, {'id': 757, 'image_count': 468}, {'id': 758, 'image_count': 1}, {'id': 759, 'image_count': 2}, {'id': 760, 'image_count': 24}, {'id': 761, 'image_count': 11}, {'id': 762, 'image_count': 72}, {'id': 763, 'image_count': 17}, {'id': 764, 'image_count': 10}, {'id': 765, 'image_count': 17}, {'id': 766, 'image_count': 489}, {'id': 767, 'image_count': 47}, {'id': 768, 'image_count': 93}, {'id': 769, 'image_count': 1}, {'id': 770, 'image_count': 12}, {'id': 771, 'image_count': 228}, {'id': 772, 'image_count': 5}, {'id': 773, 'image_count': 76}, {'id': 774, 'image_count': 71}, {'id': 775, 'image_count': 30}, {'id': 776, 'image_count': 109}, {'id': 777, 'image_count': 14}, {'id': 778, 'image_count': 1}, {'id': 779, 'image_count': 8}, {'id': 780, 'image_count': 26}, {'id': 781, 'image_count': 339}, {'id': 782, 'image_count': 153}, {'id': 783, 'image_count': 2}, {'id': 784, 'image_count': 3}, {'id': 785, 'image_count': 8}, {'id': 786, 'image_count': 47}, {'id': 787, 'image_count': 8}, {'id': 788, 'image_count': 6}, {'id': 789, 'image_count': 116}, {'id': 790, 'image_count': 69}, {'id': 791, 'image_count': 13}, {'id': 792, 'image_count': 6}, {'id': 793, 'image_count': 1928}, {'id': 794, 'image_count': 79}, {'id': 795, 'image_count': 14}, {'id': 796, 'image_count': 7}, {'id': 797, 'image_count': 20}, {'id': 798, 'image_count': 114}, {'id': 799, 'image_count': 221}, {'id': 800, 'image_count': 502}, {'id': 801, 'image_count': 62}, {'id': 802, 'image_count': 87}, {'id': 803, 'image_count': 4}, {'id': 804, 'image_count': 1912}, {'id': 805, 'image_count': 7}, {'id': 806, 'image_count': 186}, {'id': 807, 'image_count': 18}, {'id': 808, 'image_count': 4}, {'id': 809, 'image_count': 3}, {'id': 810, 'image_count': 7}, {'id': 811, 'image_count': 1413}, {'id': 812, 'image_count': 7}, {'id': 813, 'image_count': 12}, {'id': 814, 'image_count': 248}, {'id': 815, 'image_count': 4}, {'id': 816, 'image_count': 1881}, {'id': 817, 'image_count': 529}, {'id': 818, 'image_count': 1932}, {'id': 819, 'image_count': 50}, {'id': 820, 'image_count': 3}, {'id': 821, 'image_count': 28}, {'id': 822, 'image_count': 10}, {'id': 823, 'image_count': 5}, {'id': 824, 'image_count': 5}, {'id': 825, 'image_count': 18}, {'id': 826, 'image_count': 14}, {'id': 827, 'image_count': 1890}, {'id': 828, 'image_count': 660}, {'id': 829, 'image_count': 8}, {'id': 830, 'image_count': 25}, {'id': 831, 'image_count': 10}, {'id': 832, 'image_count': 218}, {'id': 833, 'image_count': 36}, {'id': 834, 'image_count': 16}, {'id': 835, 'image_count': 808}, {'id': 836, 'image_count': 479}, {'id': 837, 'image_count': 1404}, {'id': 838, 'image_count': 307}, {'id': 839, 'image_count': 57}, {'id': 840, 'image_count': 28}, {'id': 841, 'image_count': 80}, {'id': 842, 'image_count': 11}, {'id': 843, 'image_count': 92}, {'id': 844, 'image_count': 20}, {'id': 845, 'image_count': 194}, {'id': 846, 'image_count': 23}, {'id': 847, 'image_count': 52}, {'id': 848, 'image_count': 673}, {'id': 849, 'image_count': 2}, {'id': 850, 'image_count': 2}, {'id': 851, 'image_count': 1}, {'id': 852, 'image_count': 2}, {'id': 853, 'image_count': 8}, {'id': 854, 'image_count': 80}, {'id': 855, 'image_count': 3}, {'id': 856, 'image_count': 3}, {'id': 857, 'image_count': 15}, {'id': 858, 'image_count': 2}, {'id': 859, 'image_count': 10}, {'id': 860, 'image_count': 386}, {'id': 861, 'image_count': 65}, {'id': 862, 'image_count': 3}, {'id': 863, 'image_count': 35}, {'id': 864, 'image_count': 5}, {'id': 865, 'image_count': 180}, {'id': 866, 'image_count': 99}, {'id': 867, 'image_count': 49}, {'id': 868, 'image_count': 28}, {'id': 869, 'image_count': 1}, {'id': 870, 'image_count': 52}, {'id': 871, 'image_count': 36}, {'id': 872, 'image_count': 70}, {'id': 873, 'image_count': 6}, {'id': 874, 'image_count': 29}, {'id': 875, 'image_count': 24}, {'id': 876, 'image_count': 1115}, {'id': 877, 'image_count': 61}, {'id': 878, 'image_count': 18}, {'id': 879, 'image_count': 18}, {'id': 880, 'image_count': 665}, {'id': 881, 'image_count': 1096}, {'id': 882, 'image_count': 29}, {'id': 883, 'image_count': 8}, {'id': 884, 'image_count': 14}, {'id': 885, 'image_count': 1622}, {'id': 886, 'image_count': 2}, {'id': 887, 'image_count': 3}, {'id': 888, 'image_count': 32}, {'id': 889, 'image_count': 55}, {'id': 890, 'image_count': 1}, {'id': 891, 'image_count': 10}, {'id': 892, 'image_count': 10}, {'id': 893, 'image_count': 47}, {'id': 894, 'image_count': 3}, {'id': 895, 'image_count': 29}, {'id': 896, 'image_count': 342}, {'id': 897, 'image_count': 25}, {'id': 898, 'image_count': 1469}, {'id': 899, 'image_count': 521}, {'id': 900, 'image_count': 347}, {'id': 901, 'image_count': 35}, {'id': 902, 'image_count': 7}, {'id': 903, 'image_count': 207}, {'id': 904, 'image_count': 108}, {'id': 905, 'image_count': 2}, {'id': 906, 'image_count': 34}, {'id': 907, 'image_count': 12}, {'id': 908, 'image_count': 10}, {'id': 909, 'image_count': 13}, {'id': 910, 'image_count': 361}, {'id': 911, 'image_count': 1023}, {'id': 912, 'image_count': 782}, {'id': 913, 'image_count': 2}, {'id': 914, 'image_count': 5}, {'id': 915, 'image_count': 247}, {'id': 916, 'image_count': 221}, {'id': 917, 'image_count': 4}, {'id': 918, 'image_count': 8}, {'id': 919, 'image_count': 158}, {'id': 920, 'image_count': 3}, {'id': 921, 'image_count': 752}, {'id': 922, 'image_count': 64}, {'id': 923, 'image_count': 707}, {'id': 924, 'image_count': 143}, {'id': 925, 'image_count': 1}, {'id': 926, 'image_count': 49}, {'id': 927, 'image_count': 126}, {'id': 928, 'image_count': 76}, {'id': 929, 'image_count': 11}, {'id': 930, 'image_count': 11}, {'id': 931, 'image_count': 4}, {'id': 932, 'image_count': 39}, {'id': 933, 'image_count': 11}, {'id': 934, 'image_count': 13}, {'id': 935, 'image_count': 91}, {'id': 936, 'image_count': 14}, {'id': 937, 'image_count': 5}, {'id': 938, 'image_count': 3}, {'id': 939, 'image_count': 10}, {'id': 940, 'image_count': 18}, {'id': 941, 'image_count': 9}, {'id': 942, 'image_count': 6}, {'id': 943, 'image_count': 951}, {'id': 944, 'image_count': 2}, {'id': 945, 'image_count': 1}, {'id': 946, 'image_count': 19}, {'id': 947, 'image_count': 1942}, {'id': 948, 'image_count': 1916}, {'id': 949, 'image_count': 139}, {'id': 950, 'image_count': 43}, {'id': 951, 'image_count': 1969}, {'id': 952, 'image_count': 5}, {'id': 953, 'image_count': 134}, {'id': 954, 'image_count': 74}, {'id': 955, 'image_count': 381}, {'id': 956, 'image_count': 1}, {'id': 957, 'image_count': 381}, {'id': 958, 'image_count': 6}, {'id': 959, 'image_count': 1826}, {'id': 960, 'image_count': 28}, {'id': 961, 'image_count': 1635}, {'id': 962, 'image_count': 1967}, {'id': 963, 'image_count': 16}, {'id': 964, 'image_count': 1926}, {'id': 965, 'image_count': 1789}, {'id': 966, 'image_count': 401}, {'id': 967, 'image_count': 1968}, {'id': 968, 'image_count': 1167}, {'id': 969, 'image_count': 1}, {'id': 970, 'image_count': 56}, {'id': 971, 'image_count': 17}, {'id': 972, 'image_count': 1}, {'id': 973, 'image_count': 58}, {'id': 974, 'image_count': 9}, {'id': 975, 'image_count': 8}, {'id': 976, 'image_count': 1124}, {'id': 977, 'image_count': 31}, {'id': 978, 'image_count': 16}, {'id': 979, 'image_count': 491}, {'id': 980, 'image_count': 432}, {'id': 981, 'image_count': 1945}, {'id': 982, 'image_count': 1899}, {'id': 983, 'image_count': 5}, {'id': 984, 'image_count': 28}, {'id': 985, 'image_count': 7}, {'id': 986, 'image_count': 146}, {'id': 987, 'image_count': 1}, {'id': 988, 'image_count': 25}, {'id': 989, 'image_count': 22}, {'id': 990, 'image_count': 1}, {'id': 991, 'image_count': 10}, {'id': 992, 'image_count': 9}, {'id': 993, 'image_count': 308}, {'id': 994, 'image_count': 4}, {'id': 995, 'image_count': 1969}, {'id': 996, 'image_count': 45}, {'id': 997, 'image_count': 12}, {'id': 998, 'image_count': 1}, {'id': 999, 'image_count': 85}, {'id': 1000, 'image_count': 1127}, {'id': 1001, 'image_count': 11}, {'id': 1002, 'image_count': 60}, {'id': 1003, 'image_count': 1}, {'id': 1004, 'image_count': 16}, {'id': 1005, 'image_count': 1}, {'id': 1006, 'image_count': 65}, {'id': 1007, 'image_count': 13}, {'id': 1008, 'image_count': 655}, {'id': 1009, 'image_count': 51}, {'id': 1010, 'image_count': 1}, {'id': 1011, 'image_count': 673}, {'id': 1012, 'image_count': 5}, {'id': 1013, 'image_count': 36}, {'id': 1014, 'image_count': 54}, {'id': 1015, 'image_count': 5}, {'id': 1016, 'image_count': 8}, {'id': 1017, 'image_count': 305}, {'id': 1018, 'image_count': 297}, {'id': 1019, 'image_count': 1053}, {'id': 1020, 'image_count': 223}, {'id': 1021, 'image_count': 1037}, {'id': 1022, 'image_count': 63}, {'id': 1023, 'image_count': 1881}, {'id': 1024, 'image_count': 507}, {'id': 1025, 'image_count': 333}, {'id': 1026, 'image_count': 1911}, {'id': 1027, 'image_count': 1765}, {'id': 1028, 'image_count': 1}, {'id': 1029, 'image_count': 5}, {'id': 1030, 'image_count': 1}, {'id': 1031, 'image_count': 9}, {'id': 1032, 'image_count': 2}, {'id': 1033, 'image_count': 151}, {'id': 1034, 'image_count': 82}, {'id': 1035, 'image_count': 1931}, {'id': 1036, 'image_count': 41}, {'id': 1037, 'image_count': 1895}, {'id': 1038, 'image_count': 24}, {'id': 1039, 'image_count': 22}, {'id': 1040, 'image_count': 35}, {'id': 1041, 'image_count': 69}, {'id': 1042, 'image_count': 962}, {'id': 1043, 'image_count': 588}, {'id': 1044, 'image_count': 21}, {'id': 1045, 'image_count': 825}, {'id': 1046, 'image_count': 52}, {'id': 1047, 'image_count': 5}, {'id': 1048, 'image_count': 5}, {'id': 1049, 'image_count': 5}, {'id': 1050, 'image_count': 1860}, {'id': 1051, 'image_count': 56}, {'id': 1052, 'image_count': 1582}, {'id': 1053, 'image_count': 7}, {'id': 1054, 'image_count': 2}, {'id': 1055, 'image_count': 1562}, {'id': 1056, 'image_count': 1885}, {'id': 1057, 'image_count': 1}, {'id': 1058, 'image_count': 5}, {'id': 1059, 'image_count': 137}, {'id': 1060, 'image_count': 1094}, {'id': 1061, 'image_count': 134}, {'id': 1062, 'image_count': 29}, {'id': 1063, 'image_count': 22}, {'id': 1064, 'image_count': 522}, {'id': 1065, 'image_count': 50}, {'id': 1066, 'image_count': 68}, {'id': 1067, 'image_count': 16}, {'id': 1068, 'image_count': 40}, {'id': 1069, 'image_count': 35}, {'id': 1070, 'image_count': 135}, {'id': 1071, 'image_count': 1413}, {'id': 1072, 'image_count': 772}, {'id': 1073, 'image_count': 50}, {'id': 1074, 'image_count': 1015}, {'id': 1075, 'image_count': 1}, {'id': 1076, 'image_count': 65}, {'id': 1077, 'image_count': 1900}, {'id': 1078, 'image_count': 1302}, {'id': 1079, 'image_count': 1977}, {'id': 1080, 'image_count': 2}, {'id': 1081, 'image_count': 29}, {'id': 1082, 'image_count': 36}, {'id': 1083, 'image_count': 138}, {'id': 1084, 'image_count': 4}, {'id': 1085, 'image_count': 67}, {'id': 1086, 'image_count': 26}, {'id': 1087, 'image_count': 25}, {'id': 1088, 'image_count': 33}, {'id': 1089, 'image_count': 37}, {'id': 1090, 'image_count': 50}, {'id': 1091, 'image_count': 270}, {'id': 1092, 'image_count': 12}, {'id': 1093, 'image_count': 316}, {'id': 1094, 'image_count': 41}, {'id': 1095, 'image_count': 224}, {'id': 1096, 'image_count': 105}, {'id': 1097, 'image_count': 1925}, {'id': 1098, 'image_count': 1021}, {'id': 1099, 'image_count': 1213}, {'id': 1100, 'image_count': 172}, {'id': 1101, 'image_count': 28}, {'id': 1102, 'image_count': 745}, {'id': 1103, 'image_count': 187}, {'id': 1104, 'image_count': 147}, {'id': 1105, 'image_count': 136}, {'id': 1106, 'image_count': 34}, {'id': 1107, 'image_count': 41}, {'id': 1108, 'image_count': 636}, {'id': 1109, 'image_count': 570}, {'id': 1110, 'image_count': 1149}, {'id': 1111, 'image_count': 61}, {'id': 1112, 'image_count': 1890}, {'id': 1113, 'image_count': 18}, {'id': 1114, 'image_count': 143}, {'id': 1115, 'image_count': 1517}, {'id': 1116, 'image_count': 7}, {'id': 1117, 'image_count': 943}, {'id': 1118, 'image_count': 6}, {'id': 1119, 'image_count': 1}, {'id': 1120, 'image_count': 11}, {'id': 1121, 'image_count': 101}, {'id': 1122, 'image_count': 1909}, {'id': 1123, 'image_count': 800}, {'id': 1124, 'image_count': 1}, {'id': 1125, 'image_count': 44}, {'id': 1126, 'image_count': 3}, {'id': 1127, 'image_count': 44}, {'id': 1128, 'image_count': 31}, {'id': 1129, 'image_count': 7}, {'id': 1130, 'image_count': 20}, {'id': 1131, 'image_count': 11}, {'id': 1132, 'image_count': 13}, {'id': 1133, 'image_count': 1924}, {'id': 1134, 'image_count': 113}, {'id': 1135, 'image_count': 2}, {'id': 1136, 'image_count': 139}, {'id': 1137, 'image_count': 12}, {'id': 1138, 'image_count': 37}, {'id': 1139, 'image_count': 1866}, {'id': 1140, 'image_count': 47}, {'id': 1141, 'image_count': 1468}, {'id': 1142, 'image_count': 729}, {'id': 1143, 'image_count': 24}, {'id': 1144, 'image_count': 1}, {'id': 1145, 'image_count': 10}, {'id': 1146, 'image_count': 3}, {'id': 1147, 'image_count': 14}, {'id': 1148, 'image_count': 4}, {'id': 1149, 'image_count': 29}, {'id': 1150, 'image_count': 4}, {'id': 1151, 'image_count': 70}, {'id': 1152, 'image_count': 46}, {'id': 1153, 'image_count': 14}, {'id': 1154, 'image_count': 48}, {'id': 1155, 'image_count': 1855}, {'id': 1156, 'image_count': 113}, {'id': 1157, 'image_count': 1}, {'id': 1158, 'image_count': 1}, {'id': 1159, 'image_count': 10}, {'id': 1160, 'image_count': 54}, {'id': 1161, 'image_count': 1923}, {'id': 1162, 'image_count': 630}, {'id': 1163, 'image_count': 31}, {'id': 1164, 'image_count': 69}, {'id': 1165, 'image_count': 7}, {'id': 1166, 'image_count': 11}, {'id': 1167, 'image_count': 1}, {'id': 1168, 'image_count': 30}, {'id': 1169, 'image_count': 50}, {'id': 1170, 'image_count': 45}, {'id': 1171, 'image_count': 28}, {'id': 1172, 'image_count': 114}, {'id': 1173, 'image_count': 193}, {'id': 1174, 'image_count': 21}, {'id': 1175, 'image_count': 91}, {'id': 1176, 'image_count': 31}, {'id': 1177, 'image_count': 1469}, {'id': 1178, 'image_count': 1924}, {'id': 1179, 'image_count': 87}, {'id': 1180, 'image_count': 77}, {'id': 1181, 'image_count': 11}, {'id': 1182, 'image_count': 47}, {'id': 1183, 'image_count': 21}, {'id': 1184, 'image_count': 47}, {'id': 1185, 'image_count': 70}, {'id': 1186, 'image_count': 1838}, {'id': 1187, 'image_count': 19}, {'id': 1188, 'image_count': 531}, {'id': 1189, 'image_count': 11}, {'id': 1190, 'image_count': 941}, {'id': 1191, 'image_count': 113}, {'id': 1192, 'image_count': 26}, {'id': 1193, 'image_count': 5}, {'id': 1194, 'image_count': 56}, {'id': 1195, 'image_count': 73}, {'id': 1196, 'image_count': 32}, {'id': 1197, 'image_count': 128}, {'id': 1198, 'image_count': 623}, {'id': 1199, 'image_count': 12}, {'id': 1200, 'image_count': 52}, {'id': 1201, 'image_count': 11}, {'id': 1202, 'image_count': 1674}, {'id': 1203, 'image_count': 81}] # noqa +# fmt: on diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/pascal_voc.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/pascal_voc.py new file mode 100644 index 00000000..919cc492 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/pascal_voc.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +import numpy as np +import os +import xml.etree.ElementTree as ET +from typing import List, Tuple, Union + +from annotator.oneformer.detectron2.data import DatasetCatalog, MetadataCatalog +from annotator.oneformer.detectron2.structures import BoxMode +from annotator.oneformer.detectron2.utils.file_io import PathManager + +__all__ = ["load_voc_instances", "register_pascal_voc"] + + +# fmt: off +CLASS_NAMES = ( + "aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", + "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", + "pottedplant", "sheep", "sofa", "train", "tvmonitor" +) +# fmt: on + + +def load_voc_instances(dirname: str, split: str, class_names: Union[List[str], Tuple[str, ...]]): + """ + Load Pascal VOC detection annotations to Detectron2 format. + + Args: + dirname: Contain "Annotations", "ImageSets", "JPEGImages" + split (str): one of "train", "test", "val", "trainval" + class_names: list or tuple of class names + """ + with PathManager.open(os.path.join(dirname, "ImageSets", "Main", split + ".txt")) as f: + fileids = np.loadtxt(f, dtype=np.str) + + # Needs to read many small annotation files. Makes sense at local + annotation_dirname = PathManager.get_local_path(os.path.join(dirname, "Annotations/")) + dicts = [] + for fileid in fileids: + anno_file = os.path.join(annotation_dirname, fileid + ".xml") + jpeg_file = os.path.join(dirname, "JPEGImages", fileid + ".jpg") + + with PathManager.open(anno_file) as f: + tree = ET.parse(f) + + r = { + "file_name": jpeg_file, + "image_id": fileid, + "height": int(tree.findall("./size/height")[0].text), + "width": int(tree.findall("./size/width")[0].text), + } + instances = [] + + for obj in tree.findall("object"): + cls = obj.find("name").text + # We include "difficult" samples in training. + # Based on limited experiments, they don't hurt accuracy. + # difficult = int(obj.find("difficult").text) + # if difficult == 1: + # continue + bbox = obj.find("bndbox") + bbox = [float(bbox.find(x).text) for x in ["xmin", "ymin", "xmax", "ymax"]] + # Original annotations are integers in the range [1, W or H] + # Assuming they mean 1-based pixel indices (inclusive), + # a box with annotation (xmin=1, xmax=W) covers the whole image. + # In coordinate space this is represented by (xmin=0, xmax=W) + bbox[0] -= 1.0 + bbox[1] -= 1.0 + instances.append( + {"category_id": class_names.index(cls), "bbox": bbox, "bbox_mode": BoxMode.XYXY_ABS} + ) + r["annotations"] = instances + dicts.append(r) + return dicts + + +def register_pascal_voc(name, dirname, split, year, class_names=CLASS_NAMES): + DatasetCatalog.register(name, lambda: load_voc_instances(dirname, split, class_names)) + MetadataCatalog.get(name).set( + thing_classes=list(class_names), dirname=dirname, year=year, split=split + ) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/register_coco.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/register_coco.py new file mode 100644 index 00000000..e564438d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/datasets/register_coco.py @@ -0,0 +1,3 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from .coco import register_coco_instances # noqa +from .coco_panoptic import register_coco_panoptic_separated # noqa diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/detection_utils.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/detection_utils.py new file mode 100644 index 00000000..b00ca912 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/detection_utils.py @@ -0,0 +1,659 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +""" +Common data processing utilities that are used in a +typical object detection data pipeline. +""" +import logging +import numpy as np +from typing import List, Union +import annotator.oneformer.pycocotools.mask as mask_util +import torch +from PIL import Image + +from annotator.oneformer.detectron2.structures import ( + BitMasks, + Boxes, + BoxMode, + Instances, + Keypoints, + PolygonMasks, + RotatedBoxes, + polygons_to_bitmask, +) +from annotator.oneformer.detectron2.utils.file_io import PathManager + +from . import transforms as T +from .catalog import MetadataCatalog + +__all__ = [ + "SizeMismatchError", + "convert_image_to_rgb", + "check_image_size", + "transform_proposals", + "transform_instance_annotations", + "annotations_to_instances", + "annotations_to_instances_rotated", + "build_augmentation", + "build_transform_gen", + "create_keypoint_hflip_indices", + "filter_empty_instances", + "read_image", +] + + +class SizeMismatchError(ValueError): + """ + When loaded image has difference width/height compared with annotation. + """ + + +# https://en.wikipedia.org/wiki/YUV#SDTV_with_BT.601 +_M_RGB2YUV = [[0.299, 0.587, 0.114], [-0.14713, -0.28886, 0.436], [0.615, -0.51499, -0.10001]] +_M_YUV2RGB = [[1.0, 0.0, 1.13983], [1.0, -0.39465, -0.58060], [1.0, 2.03211, 0.0]] + +# https://www.exiv2.org/tags.html +_EXIF_ORIENT = 274 # exif 'Orientation' tag + + +def convert_PIL_to_numpy(image, format): + """ + Convert PIL image to numpy array of target format. + + Args: + image (PIL.Image): a PIL image + format (str): the format of output image + + Returns: + (np.ndarray): also see `read_image` + """ + if format is not None: + # PIL only supports RGB, so convert to RGB and flip channels over below + conversion_format = format + if format in ["BGR", "YUV-BT.601"]: + conversion_format = "RGB" + image = image.convert(conversion_format) + image = np.asarray(image) + # PIL squeezes out the channel dimension for "L", so make it HWC + if format == "L": + image = np.expand_dims(image, -1) + + # handle formats not supported by PIL + elif format == "BGR": + # flip channels if needed + image = image[:, :, ::-1] + elif format == "YUV-BT.601": + image = image / 255.0 + image = np.dot(image, np.array(_M_RGB2YUV).T) + + return image + + +def convert_image_to_rgb(image, format): + """ + Convert an image from given format to RGB. + + Args: + image (np.ndarray or Tensor): an HWC image + format (str): the format of input image, also see `read_image` + + Returns: + (np.ndarray): (H,W,3) RGB image in 0-255 range, can be either float or uint8 + """ + if isinstance(image, torch.Tensor): + image = image.cpu().numpy() + if format == "BGR": + image = image[:, :, [2, 1, 0]] + elif format == "YUV-BT.601": + image = np.dot(image, np.array(_M_YUV2RGB).T) + image = image * 255.0 + else: + if format == "L": + image = image[:, :, 0] + image = image.astype(np.uint8) + image = np.asarray(Image.fromarray(image, mode=format).convert("RGB")) + return image + + +def _apply_exif_orientation(image): + """ + Applies the exif orientation correctly. + + This code exists per the bug: + https://github.com/python-pillow/Pillow/issues/3973 + with the function `ImageOps.exif_transpose`. The Pillow source raises errors with + various methods, especially `tobytes` + + Function based on: + https://github.com/wkentaro/labelme/blob/v4.5.4/labelme/utils/image.py#L59 + https://github.com/python-pillow/Pillow/blob/7.1.2/src/PIL/ImageOps.py#L527 + + Args: + image (PIL.Image): a PIL image + + Returns: + (PIL.Image): the PIL image with exif orientation applied, if applicable + """ + if not hasattr(image, "getexif"): + return image + + try: + exif = image.getexif() + except Exception: # https://github.com/facebookresearch/detectron2/issues/1885 + exif = None + + if exif is None: + return image + + orientation = exif.get(_EXIF_ORIENT) + + method = { + 2: Image.FLIP_LEFT_RIGHT, + 3: Image.ROTATE_180, + 4: Image.FLIP_TOP_BOTTOM, + 5: Image.TRANSPOSE, + 6: Image.ROTATE_270, + 7: Image.TRANSVERSE, + 8: Image.ROTATE_90, + }.get(orientation) + + if method is not None: + return image.transpose(method) + return image + + +def read_image(file_name, format=None): + """ + Read an image into the given format. + Will apply rotation and flipping if the image has such exif information. + + Args: + file_name (str): image file path + format (str): one of the supported image modes in PIL, or "BGR" or "YUV-BT.601". + + Returns: + image (np.ndarray): + an HWC image in the given format, which is 0-255, uint8 for + supported image modes in PIL or "BGR"; float (0-1 for Y) for YUV-BT.601. + """ + with PathManager.open(file_name, "rb") as f: + image = Image.open(f) + + # work around this bug: https://github.com/python-pillow/Pillow/issues/3973 + image = _apply_exif_orientation(image) + return convert_PIL_to_numpy(image, format) + + +def check_image_size(dataset_dict, image): + """ + Raise an error if the image does not match the size specified in the dict. + """ + if "width" in dataset_dict or "height" in dataset_dict: + image_wh = (image.shape[1], image.shape[0]) + expected_wh = (dataset_dict["width"], dataset_dict["height"]) + if not image_wh == expected_wh: + raise SizeMismatchError( + "Mismatched image shape{}, got {}, expect {}.".format( + " for image " + dataset_dict["file_name"] + if "file_name" in dataset_dict + else "", + image_wh, + expected_wh, + ) + + " Please check the width/height in your annotation." + ) + + # To ensure bbox always remap to original image size + if "width" not in dataset_dict: + dataset_dict["width"] = image.shape[1] + if "height" not in dataset_dict: + dataset_dict["height"] = image.shape[0] + + +def transform_proposals(dataset_dict, image_shape, transforms, *, proposal_topk, min_box_size=0): + """ + Apply transformations to the proposals in dataset_dict, if any. + + Args: + dataset_dict (dict): a dict read from the dataset, possibly + contains fields "proposal_boxes", "proposal_objectness_logits", "proposal_bbox_mode" + image_shape (tuple): height, width + transforms (TransformList): + proposal_topk (int): only keep top-K scoring proposals + min_box_size (int): proposals with either side smaller than this + threshold are removed + + The input dict is modified in-place, with abovementioned keys removed. A new + key "proposals" will be added. Its value is an `Instances` + object which contains the transformed proposals in its field + "proposal_boxes" and "objectness_logits". + """ + if "proposal_boxes" in dataset_dict: + # Transform proposal boxes + boxes = transforms.apply_box( + BoxMode.convert( + dataset_dict.pop("proposal_boxes"), + dataset_dict.pop("proposal_bbox_mode"), + BoxMode.XYXY_ABS, + ) + ) + boxes = Boxes(boxes) + objectness_logits = torch.as_tensor( + dataset_dict.pop("proposal_objectness_logits").astype("float32") + ) + + boxes.clip(image_shape) + keep = boxes.nonempty(threshold=min_box_size) + boxes = boxes[keep] + objectness_logits = objectness_logits[keep] + + proposals = Instances(image_shape) + proposals.proposal_boxes = boxes[:proposal_topk] + proposals.objectness_logits = objectness_logits[:proposal_topk] + dataset_dict["proposals"] = proposals + + +def get_bbox(annotation): + """ + Get bbox from data + Args: + annotation (dict): dict of instance annotations for a single instance. + Returns: + bbox (ndarray): x1, y1, x2, y2 coordinates + """ + # bbox is 1d (per-instance bounding box) + bbox = BoxMode.convert(annotation["bbox"], annotation["bbox_mode"], BoxMode.XYXY_ABS) + return bbox + + +def transform_instance_annotations( + annotation, transforms, image_size, *, keypoint_hflip_indices=None +): + """ + Apply transforms to box, segmentation and keypoints annotations of a single instance. + + It will use `transforms.apply_box` for the box, and + `transforms.apply_coords` for segmentation polygons & keypoints. + If you need anything more specially designed for each data structure, + you'll need to implement your own version of this function or the transforms. + + Args: + annotation (dict): dict of instance annotations for a single instance. + It will be modified in-place. + transforms (TransformList or list[Transform]): + image_size (tuple): the height, width of the transformed image + keypoint_hflip_indices (ndarray[int]): see `create_keypoint_hflip_indices`. + + Returns: + dict: + the same input dict with fields "bbox", "segmentation", "keypoints" + transformed according to `transforms`. + The "bbox_mode" field will be set to XYXY_ABS. + """ + if isinstance(transforms, (tuple, list)): + transforms = T.TransformList(transforms) + # bbox is 1d (per-instance bounding box) + bbox = BoxMode.convert(annotation["bbox"], annotation["bbox_mode"], BoxMode.XYXY_ABS) + # clip transformed bbox to image size + bbox = transforms.apply_box(np.array([bbox]))[0].clip(min=0) + annotation["bbox"] = np.minimum(bbox, list(image_size + image_size)[::-1]) + annotation["bbox_mode"] = BoxMode.XYXY_ABS + + if "segmentation" in annotation: + # each instance contains 1 or more polygons + segm = annotation["segmentation"] + if isinstance(segm, list): + # polygons + polygons = [np.asarray(p).reshape(-1, 2) for p in segm] + annotation["segmentation"] = [ + p.reshape(-1) for p in transforms.apply_polygons(polygons) + ] + elif isinstance(segm, dict): + # RLE + mask = mask_util.decode(segm) + mask = transforms.apply_segmentation(mask) + assert tuple(mask.shape[:2]) == image_size + annotation["segmentation"] = mask + else: + raise ValueError( + "Cannot transform segmentation of type '{}'!" + "Supported types are: polygons as list[list[float] or ndarray]," + " COCO-style RLE as a dict.".format(type(segm)) + ) + + if "keypoints" in annotation: + keypoints = transform_keypoint_annotations( + annotation["keypoints"], transforms, image_size, keypoint_hflip_indices + ) + annotation["keypoints"] = keypoints + + return annotation + + +def transform_keypoint_annotations(keypoints, transforms, image_size, keypoint_hflip_indices=None): + """ + Transform keypoint annotations of an image. + If a keypoint is transformed out of image boundary, it will be marked "unlabeled" (visibility=0) + + Args: + keypoints (list[float]): Nx3 float in Detectron2's Dataset format. + Each point is represented by (x, y, visibility). + transforms (TransformList): + image_size (tuple): the height, width of the transformed image + keypoint_hflip_indices (ndarray[int]): see `create_keypoint_hflip_indices`. + When `transforms` includes horizontal flip, will use the index + mapping to flip keypoints. + """ + # (N*3,) -> (N, 3) + keypoints = np.asarray(keypoints, dtype="float64").reshape(-1, 3) + keypoints_xy = transforms.apply_coords(keypoints[:, :2]) + + # Set all out-of-boundary points to "unlabeled" + inside = (keypoints_xy >= np.array([0, 0])) & (keypoints_xy <= np.array(image_size[::-1])) + inside = inside.all(axis=1) + keypoints[:, :2] = keypoints_xy + keypoints[:, 2][~inside] = 0 + + # This assumes that HorizFlipTransform is the only one that does flip + do_hflip = sum(isinstance(t, T.HFlipTransform) for t in transforms.transforms) % 2 == 1 + + # Alternative way: check if probe points was horizontally flipped. + # probe = np.asarray([[0.0, 0.0], [image_width, 0.0]]) + # probe_aug = transforms.apply_coords(probe.copy()) + # do_hflip = np.sign(probe[1][0] - probe[0][0]) != np.sign(probe_aug[1][0] - probe_aug[0][0]) # noqa + + # If flipped, swap each keypoint with its opposite-handed equivalent + if do_hflip: + if keypoint_hflip_indices is None: + raise ValueError("Cannot flip keypoints without providing flip indices!") + if len(keypoints) != len(keypoint_hflip_indices): + raise ValueError( + "Keypoint data has {} points, but metadata " + "contains {} points!".format(len(keypoints), len(keypoint_hflip_indices)) + ) + keypoints = keypoints[np.asarray(keypoint_hflip_indices, dtype=np.int32), :] + + # Maintain COCO convention that if visibility == 0 (unlabeled), then x, y = 0 + keypoints[keypoints[:, 2] == 0] = 0 + return keypoints + + +def annotations_to_instances(annos, image_size, mask_format="polygon"): + """ + Create an :class:`Instances` object used by the models, + from instance annotations in the dataset dict. + + Args: + annos (list[dict]): a list of instance annotations in one image, each + element for one instance. + image_size (tuple): height, width + + Returns: + Instances: + It will contain fields "gt_boxes", "gt_classes", + "gt_masks", "gt_keypoints", if they can be obtained from `annos`. + This is the format that builtin models expect. + """ + boxes = ( + np.stack( + [BoxMode.convert(obj["bbox"], obj["bbox_mode"], BoxMode.XYXY_ABS) for obj in annos] + ) + if len(annos) + else np.zeros((0, 4)) + ) + target = Instances(image_size) + target.gt_boxes = Boxes(boxes) + + classes = [int(obj["category_id"]) for obj in annos] + classes = torch.tensor(classes, dtype=torch.int64) + target.gt_classes = classes + + if len(annos) and "segmentation" in annos[0]: + segms = [obj["segmentation"] for obj in annos] + if mask_format == "polygon": + try: + masks = PolygonMasks(segms) + except ValueError as e: + raise ValueError( + "Failed to use mask_format=='polygon' from the given annotations!" + ) from e + else: + assert mask_format == "bitmask", mask_format + masks = [] + for segm in segms: + if isinstance(segm, list): + # polygon + masks.append(polygons_to_bitmask(segm, *image_size)) + elif isinstance(segm, dict): + # COCO RLE + masks.append(mask_util.decode(segm)) + elif isinstance(segm, np.ndarray): + assert segm.ndim == 2, "Expect segmentation of 2 dimensions, got {}.".format( + segm.ndim + ) + # mask array + masks.append(segm) + else: + raise ValueError( + "Cannot convert segmentation of type '{}' to BitMasks!" + "Supported types are: polygons as list[list[float] or ndarray]," + " COCO-style RLE as a dict, or a binary segmentation mask " + " in a 2D numpy array of shape HxW.".format(type(segm)) + ) + # torch.from_numpy does not support array with negative stride. + masks = BitMasks( + torch.stack([torch.from_numpy(np.ascontiguousarray(x)) for x in masks]) + ) + target.gt_masks = masks + + if len(annos) and "keypoints" in annos[0]: + kpts = [obj.get("keypoints", []) for obj in annos] + target.gt_keypoints = Keypoints(kpts) + + return target + + +def annotations_to_instances_rotated(annos, image_size): + """ + Create an :class:`Instances` object used by the models, + from instance annotations in the dataset dict. + Compared to `annotations_to_instances`, this function is for rotated boxes only + + Args: + annos (list[dict]): a list of instance annotations in one image, each + element for one instance. + image_size (tuple): height, width + + Returns: + Instances: + Containing fields "gt_boxes", "gt_classes", + if they can be obtained from `annos`. + This is the format that builtin models expect. + """ + boxes = [obj["bbox"] for obj in annos] + target = Instances(image_size) + boxes = target.gt_boxes = RotatedBoxes(boxes) + boxes.clip(image_size) + + classes = [obj["category_id"] for obj in annos] + classes = torch.tensor(classes, dtype=torch.int64) + target.gt_classes = classes + + return target + + +def filter_empty_instances( + instances, by_box=True, by_mask=True, box_threshold=1e-5, return_mask=False +): + """ + Filter out empty instances in an `Instances` object. + + Args: + instances (Instances): + by_box (bool): whether to filter out instances with empty boxes + by_mask (bool): whether to filter out instances with empty masks + box_threshold (float): minimum width and height to be considered non-empty + return_mask (bool): whether to return boolean mask of filtered instances + + Returns: + Instances: the filtered instances. + tensor[bool], optional: boolean mask of filtered instances + """ + assert by_box or by_mask + r = [] + if by_box: + r.append(instances.gt_boxes.nonempty(threshold=box_threshold)) + if instances.has("gt_masks") and by_mask: + r.append(instances.gt_masks.nonempty()) + + # TODO: can also filter visible keypoints + + if not r: + return instances + m = r[0] + for x in r[1:]: + m = m & x + if return_mask: + return instances[m], m + return instances[m] + + +def create_keypoint_hflip_indices(dataset_names: Union[str, List[str]]) -> List[int]: + """ + Args: + dataset_names: list of dataset names + + Returns: + list[int]: a list of size=#keypoints, storing the + horizontally-flipped keypoint indices. + """ + if isinstance(dataset_names, str): + dataset_names = [dataset_names] + + check_metadata_consistency("keypoint_names", dataset_names) + check_metadata_consistency("keypoint_flip_map", dataset_names) + + meta = MetadataCatalog.get(dataset_names[0]) + names = meta.keypoint_names + # TODO flip -> hflip + flip_map = dict(meta.keypoint_flip_map) + flip_map.update({v: k for k, v in flip_map.items()}) + flipped_names = [i if i not in flip_map else flip_map[i] for i in names] + flip_indices = [names.index(i) for i in flipped_names] + return flip_indices + + +def get_fed_loss_cls_weights(dataset_names: Union[str, List[str]], freq_weight_power=1.0): + """ + Get frequency weight for each class sorted by class id. + We now calcualte freqency weight using image_count to the power freq_weight_power. + + Args: + dataset_names: list of dataset names + freq_weight_power: power value + """ + if isinstance(dataset_names, str): + dataset_names = [dataset_names] + + check_metadata_consistency("class_image_count", dataset_names) + + meta = MetadataCatalog.get(dataset_names[0]) + class_freq_meta = meta.class_image_count + class_freq = torch.tensor( + [c["image_count"] for c in sorted(class_freq_meta, key=lambda x: x["id"])] + ) + class_freq_weight = class_freq.float() ** freq_weight_power + return class_freq_weight + + +def gen_crop_transform_with_instance(crop_size, image_size, instance): + """ + Generate a CropTransform so that the cropping region contains + the center of the given instance. + + Args: + crop_size (tuple): h, w in pixels + image_size (tuple): h, w + instance (dict): an annotation dict of one instance, in Detectron2's + dataset format. + """ + crop_size = np.asarray(crop_size, dtype=np.int32) + bbox = BoxMode.convert(instance["bbox"], instance["bbox_mode"], BoxMode.XYXY_ABS) + center_yx = (bbox[1] + bbox[3]) * 0.5, (bbox[0] + bbox[2]) * 0.5 + assert ( + image_size[0] >= center_yx[0] and image_size[1] >= center_yx[1] + ), "The annotation bounding box is outside of the image!" + assert ( + image_size[0] >= crop_size[0] and image_size[1] >= crop_size[1] + ), "Crop size is larger than image size!" + + min_yx = np.maximum(np.floor(center_yx).astype(np.int32) - crop_size, 0) + max_yx = np.maximum(np.asarray(image_size, dtype=np.int32) - crop_size, 0) + max_yx = np.minimum(max_yx, np.ceil(center_yx).astype(np.int32)) + + y0 = np.random.randint(min_yx[0], max_yx[0] + 1) + x0 = np.random.randint(min_yx[1], max_yx[1] + 1) + return T.CropTransform(x0, y0, crop_size[1], crop_size[0]) + + +def check_metadata_consistency(key, dataset_names): + """ + Check that the datasets have consistent metadata. + + Args: + key (str): a metadata key + dataset_names (list[str]): a list of dataset names + + Raises: + AttributeError: if the key does not exist in the metadata + ValueError: if the given datasets do not have the same metadata values defined by key + """ + if len(dataset_names) == 0: + return + logger = logging.getLogger(__name__) + entries_per_dataset = [getattr(MetadataCatalog.get(d), key) for d in dataset_names] + for idx, entry in enumerate(entries_per_dataset): + if entry != entries_per_dataset[0]: + logger.error( + "Metadata '{}' for dataset '{}' is '{}'".format(key, dataset_names[idx], str(entry)) + ) + logger.error( + "Metadata '{}' for dataset '{}' is '{}'".format( + key, dataset_names[0], str(entries_per_dataset[0]) + ) + ) + raise ValueError("Datasets have different metadata '{}'!".format(key)) + + +def build_augmentation(cfg, is_train): + """ + Create a list of default :class:`Augmentation` from config. + Now it includes resizing and flipping. + + Returns: + list[Augmentation] + """ + if is_train: + min_size = cfg.INPUT.MIN_SIZE_TRAIN + max_size = cfg.INPUT.MAX_SIZE_TRAIN + sample_style = cfg.INPUT.MIN_SIZE_TRAIN_SAMPLING + else: + min_size = cfg.INPUT.MIN_SIZE_TEST + max_size = cfg.INPUT.MAX_SIZE_TEST + sample_style = "choice" + augmentation = [T.ResizeShortestEdge(min_size, max_size, sample_style)] + if is_train and cfg.INPUT.RANDOM_FLIP != "none": + augmentation.append( + T.RandomFlip( + horizontal=cfg.INPUT.RANDOM_FLIP == "horizontal", + vertical=cfg.INPUT.RANDOM_FLIP == "vertical", + ) + ) + return augmentation + + +build_transform_gen = build_augmentation +""" +Alias for backward-compatibility. +""" diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/samplers/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/samplers/__init__.py new file mode 100644 index 00000000..85c9f1a9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/samplers/__init__.py @@ -0,0 +1,17 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from .distributed_sampler import ( + InferenceSampler, + RandomSubsetTrainingSampler, + RepeatFactorTrainingSampler, + TrainingSampler, +) + +from .grouped_batch_sampler import GroupedBatchSampler + +__all__ = [ + "GroupedBatchSampler", + "TrainingSampler", + "RandomSubsetTrainingSampler", + "InferenceSampler", + "RepeatFactorTrainingSampler", +] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/samplers/distributed_sampler.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/samplers/distributed_sampler.py new file mode 100644 index 00000000..cd4724ea --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/samplers/distributed_sampler.py @@ -0,0 +1,278 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import itertools +import logging +import math +from collections import defaultdict +from typing import Optional +import torch +from torch.utils.data.sampler import Sampler + +from annotator.oneformer.detectron2.utils import comm + +logger = logging.getLogger(__name__) + + +class TrainingSampler(Sampler): + """ + In training, we only care about the "infinite stream" of training data. + So this sampler produces an infinite stream of indices and + all workers cooperate to correctly shuffle the indices and sample different indices. + + The samplers in each worker effectively produces `indices[worker_id::num_workers]` + where `indices` is an infinite stream of indices consisting of + `shuffle(range(size)) + shuffle(range(size)) + ...` (if shuffle is True) + or `range(size) + range(size) + ...` (if shuffle is False) + + Note that this sampler does not shard based on pytorch DataLoader worker id. + A sampler passed to pytorch DataLoader is used only with map-style dataset + and will not be executed inside workers. + But if this sampler is used in a way that it gets execute inside a dataloader + worker, then extra work needs to be done to shard its outputs based on worker id. + This is required so that workers don't produce identical data. + :class:`ToIterableDataset` implements this logic. + This note is true for all samplers in detectron2. + """ + + def __init__(self, size: int, shuffle: bool = True, seed: Optional[int] = None): + """ + Args: + size (int): the total number of data of the underlying dataset to sample from + shuffle (bool): whether to shuffle the indices or not + seed (int): the initial seed of the shuffle. Must be the same + across all workers. If None, will use a random seed shared + among workers (require synchronization among all workers). + """ + if not isinstance(size, int): + raise TypeError(f"TrainingSampler(size=) expects an int. Got type {type(size)}.") + if size <= 0: + raise ValueError(f"TrainingSampler(size=) expects a positive int. Got {size}.") + self._size = size + self._shuffle = shuffle + if seed is None: + seed = comm.shared_random_seed() + self._seed = int(seed) + + self._rank = comm.get_rank() + self._world_size = comm.get_world_size() + + def __iter__(self): + start = self._rank + yield from itertools.islice(self._infinite_indices(), start, None, self._world_size) + + def _infinite_indices(self): + g = torch.Generator() + g.manual_seed(self._seed) + while True: + if self._shuffle: + yield from torch.randperm(self._size, generator=g).tolist() + else: + yield from torch.arange(self._size).tolist() + + +class RandomSubsetTrainingSampler(TrainingSampler): + """ + Similar to TrainingSampler, but only sample a random subset of indices. + This is useful when you want to estimate the accuracy vs data-number curves by + training the model with different subset_ratio. + """ + + def __init__( + self, + size: int, + subset_ratio: float, + shuffle: bool = True, + seed_shuffle: Optional[int] = None, + seed_subset: Optional[int] = None, + ): + """ + Args: + size (int): the total number of data of the underlying dataset to sample from + subset_ratio (float): the ratio of subset data to sample from the underlying dataset + shuffle (bool): whether to shuffle the indices or not + seed_shuffle (int): the initial seed of the shuffle. Must be the same + across all workers. If None, will use a random seed shared + among workers (require synchronization among all workers). + seed_subset (int): the seed to randomize the subset to be sampled. + Must be the same across all workers. If None, will use a random seed shared + among workers (require synchronization among all workers). + """ + super().__init__(size=size, shuffle=shuffle, seed=seed_shuffle) + + assert 0.0 < subset_ratio <= 1.0 + self._size_subset = int(size * subset_ratio) + assert self._size_subset > 0 + if seed_subset is None: + seed_subset = comm.shared_random_seed() + self._seed_subset = int(seed_subset) + + # randomly generate the subset indexes to be sampled from + g = torch.Generator() + g.manual_seed(self._seed_subset) + indexes_randperm = torch.randperm(self._size, generator=g) + self._indexes_subset = indexes_randperm[: self._size_subset] + + logger.info("Using RandomSubsetTrainingSampler......") + logger.info(f"Randomly sample {self._size_subset} data from the original {self._size} data") + + def _infinite_indices(self): + g = torch.Generator() + g.manual_seed(self._seed) # self._seed equals seed_shuffle from __init__() + while True: + if self._shuffle: + # generate a random permutation to shuffle self._indexes_subset + randperm = torch.randperm(self._size_subset, generator=g) + yield from self._indexes_subset[randperm].tolist() + else: + yield from self._indexes_subset.tolist() + + +class RepeatFactorTrainingSampler(Sampler): + """ + Similar to TrainingSampler, but a sample may appear more times than others based + on its "repeat factor". This is suitable for training on class imbalanced datasets like LVIS. + """ + + def __init__(self, repeat_factors, *, shuffle=True, seed=None): + """ + Args: + repeat_factors (Tensor): a float vector, the repeat factor for each indice. When it's + full of ones, it is equivalent to ``TrainingSampler(len(repeat_factors), ...)``. + shuffle (bool): whether to shuffle the indices or not + seed (int): the initial seed of the shuffle. Must be the same + across all workers. If None, will use a random seed shared + among workers (require synchronization among all workers). + """ + self._shuffle = shuffle + if seed is None: + seed = comm.shared_random_seed() + self._seed = int(seed) + + self._rank = comm.get_rank() + self._world_size = comm.get_world_size() + + # Split into whole number (_int_part) and fractional (_frac_part) parts. + self._int_part = torch.trunc(repeat_factors) + self._frac_part = repeat_factors - self._int_part + + @staticmethod + def repeat_factors_from_category_frequency(dataset_dicts, repeat_thresh): + """ + Compute (fractional) per-image repeat factors based on category frequency. + The repeat factor for an image is a function of the frequency of the rarest + category labeled in that image. The "frequency of category c" in [0, 1] is defined + as the fraction of images in the training set (without repeats) in which category c + appears. + See :paper:`lvis` (>= v2) Appendix B.2. + + Args: + dataset_dicts (list[dict]): annotations in Detectron2 dataset format. + repeat_thresh (float): frequency threshold below which data is repeated. + If the frequency is half of `repeat_thresh`, the image will be + repeated twice. + + Returns: + torch.Tensor: + the i-th element is the repeat factor for the dataset image at index i. + """ + # 1. For each category c, compute the fraction of images that contain it: f(c) + category_freq = defaultdict(int) + for dataset_dict in dataset_dicts: # For each image (without repeats) + cat_ids = {ann["category_id"] for ann in dataset_dict["annotations"]} + for cat_id in cat_ids: + category_freq[cat_id] += 1 + num_images = len(dataset_dicts) + for k, v in category_freq.items(): + category_freq[k] = v / num_images + + # 2. For each category c, compute the category-level repeat factor: + # r(c) = max(1, sqrt(t / f(c))) + category_rep = { + cat_id: max(1.0, math.sqrt(repeat_thresh / cat_freq)) + for cat_id, cat_freq in category_freq.items() + } + + # 3. For each image I, compute the image-level repeat factor: + # r(I) = max_{c in I} r(c) + rep_factors = [] + for dataset_dict in dataset_dicts: + cat_ids = {ann["category_id"] for ann in dataset_dict["annotations"]} + rep_factor = max({category_rep[cat_id] for cat_id in cat_ids}, default=1.0) + rep_factors.append(rep_factor) + + return torch.tensor(rep_factors, dtype=torch.float32) + + def _get_epoch_indices(self, generator): + """ + Create a list of dataset indices (with repeats) to use for one epoch. + + Args: + generator (torch.Generator): pseudo random number generator used for + stochastic rounding. + + Returns: + torch.Tensor: list of dataset indices to use in one epoch. Each index + is repeated based on its calculated repeat factor. + """ + # Since repeat factors are fractional, we use stochastic rounding so + # that the target repeat factor is achieved in expectation over the + # course of training + rands = torch.rand(len(self._frac_part), generator=generator) + rep_factors = self._int_part + (rands < self._frac_part).float() + # Construct a list of indices in which we repeat images as specified + indices = [] + for dataset_index, rep_factor in enumerate(rep_factors): + indices.extend([dataset_index] * int(rep_factor.item())) + return torch.tensor(indices, dtype=torch.int64) + + def __iter__(self): + start = self._rank + yield from itertools.islice(self._infinite_indices(), start, None, self._world_size) + + def _infinite_indices(self): + g = torch.Generator() + g.manual_seed(self._seed) + while True: + # Sample indices with repeats determined by stochastic rounding; each + # "epoch" may have a slightly different size due to the rounding. + indices = self._get_epoch_indices(g) + if self._shuffle: + randperm = torch.randperm(len(indices), generator=g) + yield from indices[randperm].tolist() + else: + yield from indices.tolist() + + +class InferenceSampler(Sampler): + """ + Produce indices for inference across all workers. + Inference needs to run on the __exact__ set of samples, + therefore when the total number of samples is not divisible by the number of workers, + this sampler produces different number of samples on different workers. + """ + + def __init__(self, size: int): + """ + Args: + size (int): the total number of data of the underlying dataset to sample from + """ + self._size = size + assert size > 0 + self._rank = comm.get_rank() + self._world_size = comm.get_world_size() + self._local_indices = self._get_local_indices(size, self._world_size, self._rank) + + @staticmethod + def _get_local_indices(total_size, world_size, rank): + shard_size = total_size // world_size + left = total_size % world_size + shard_sizes = [shard_size + int(r < left) for r in range(world_size)] + + begin = sum(shard_sizes[:rank]) + end = min(sum(shard_sizes[: rank + 1]), total_size) + return range(begin, end) + + def __iter__(self): + yield from self._local_indices + + def __len__(self): + return len(self._local_indices) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/samplers/grouped_batch_sampler.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/samplers/grouped_batch_sampler.py new file mode 100644 index 00000000..5b247730 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/samplers/grouped_batch_sampler.py @@ -0,0 +1,47 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import numpy as np +from torch.utils.data.sampler import BatchSampler, Sampler + + +class GroupedBatchSampler(BatchSampler): + """ + Wraps another sampler to yield a mini-batch of indices. + It enforces that the batch only contain elements from the same group. + It also tries to provide mini-batches which follows an ordering which is + as close as possible to the ordering from the original sampler. + """ + + def __init__(self, sampler, group_ids, batch_size): + """ + Args: + sampler (Sampler): Base sampler. + group_ids (list[int]): If the sampler produces indices in range [0, N), + `group_ids` must be a list of `N` ints which contains the group id of each sample. + The group ids must be a set of integers in the range [0, num_groups). + batch_size (int): Size of mini-batch. + """ + if not isinstance(sampler, Sampler): + raise ValueError( + "sampler should be an instance of " + "torch.utils.data.Sampler, but got sampler={}".format(sampler) + ) + self.sampler = sampler + self.group_ids = np.asarray(group_ids) + assert self.group_ids.ndim == 1 + self.batch_size = batch_size + groups = np.unique(self.group_ids).tolist() + + # buffer the indices of each group until batch size is reached + self.buffer_per_group = {k: [] for k in groups} + + def __iter__(self): + for idx in self.sampler: + group_id = self.group_ids[idx] + group_buffer = self.buffer_per_group[group_id] + group_buffer.append(idx) + if len(group_buffer) == self.batch_size: + yield group_buffer[:] # yield a copy of the list + del group_buffer[:] + + def __len__(self): + raise NotImplementedError("len() of GroupedBatchSampler is not well-defined.") diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/transforms/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/transforms/__init__.py new file mode 100644 index 00000000..e91c6cdf --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/transforms/__init__.py @@ -0,0 +1,14 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from fvcore.transforms.transform import Transform, TransformList # order them first +from fvcore.transforms.transform import * +from .transform import * +from .augmentation import * +from .augmentation_impl import * + +__all__ = [k for k in globals().keys() if not k.startswith("_")] + + +from annotator.oneformer.detectron2.utils.env import fixup_module_metadata + +fixup_module_metadata(__name__, globals(), __all__) +del fixup_module_metadata diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/transforms/augmentation.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/transforms/augmentation.py new file mode 100644 index 00000000..63dd41ae --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/transforms/augmentation.py @@ -0,0 +1,380 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +import inspect +import numpy as np +import pprint +from typing import Any, List, Optional, Tuple, Union +from fvcore.transforms.transform import Transform, TransformList + +""" +See "Data Augmentation" tutorial for an overview of the system: +https://detectron2.readthedocs.io/tutorials/augmentation.html +""" + + +__all__ = [ + "Augmentation", + "AugmentationList", + "AugInput", + "TransformGen", + "apply_transform_gens", + "StandardAugInput", + "apply_augmentations", +] + + +def _check_img_dtype(img): + assert isinstance(img, np.ndarray), "[Augmentation] Needs an numpy array, but got a {}!".format( + type(img) + ) + assert not isinstance(img.dtype, np.integer) or ( + img.dtype == np.uint8 + ), "[Augmentation] Got image of type {}, use uint8 or floating points instead!".format( + img.dtype + ) + assert img.ndim in [2, 3], img.ndim + + +def _get_aug_input_args(aug, aug_input) -> List[Any]: + """ + Get the arguments to be passed to ``aug.get_transform`` from the input ``aug_input``. + """ + if aug.input_args is None: + # Decide what attributes are needed automatically + prms = list(inspect.signature(aug.get_transform).parameters.items()) + # The default behavior is: if there is one parameter, then its "image" + # (work automatically for majority of use cases, and also avoid BC breaking), + # Otherwise, use the argument names. + if len(prms) == 1: + names = ("image",) + else: + names = [] + for name, prm in prms: + if prm.kind in ( + inspect.Parameter.VAR_POSITIONAL, + inspect.Parameter.VAR_KEYWORD, + ): + raise TypeError( + f""" \ +The default implementation of `{type(aug)}.__call__` does not allow \ +`{type(aug)}.get_transform` to use variable-length arguments (*args, **kwargs)! \ +If arguments are unknown, reimplement `__call__` instead. \ +""" + ) + names.append(name) + aug.input_args = tuple(names) + + args = [] + for f in aug.input_args: + try: + args.append(getattr(aug_input, f)) + except AttributeError as e: + raise AttributeError( + f"{type(aug)}.get_transform needs input attribute '{f}', " + f"but it is not an attribute of {type(aug_input)}!" + ) from e + return args + + +class Augmentation: + """ + Augmentation defines (often random) policies/strategies to generate :class:`Transform` + from data. It is often used for pre-processing of input data. + + A "policy" that generates a :class:`Transform` may, in the most general case, + need arbitrary information from input data in order to determine what transforms + to apply. Therefore, each :class:`Augmentation` instance defines the arguments + needed by its :meth:`get_transform` method. When called with the positional arguments, + the :meth:`get_transform` method executes the policy. + + Note that :class:`Augmentation` defines the policies to create a :class:`Transform`, + but not how to execute the actual transform operations to those data. + Its :meth:`__call__` method will use :meth:`AugInput.transform` to execute the transform. + + The returned `Transform` object is meant to describe deterministic transformation, which means + it can be re-applied on associated data, e.g. the geometry of an image and its segmentation + masks need to be transformed together. + (If such re-application is not needed, then determinism is not a crucial requirement.) + """ + + input_args: Optional[Tuple[str]] = None + """ + Stores the attribute names needed by :meth:`get_transform`, e.g. ``("image", "sem_seg")``. + By default, it is just a tuple of argument names in :meth:`self.get_transform`, which often only + contain "image". As long as the argument name convention is followed, there is no need for + users to touch this attribute. + """ + + def _init(self, params=None): + if params: + for k, v in params.items(): + if k != "self" and not k.startswith("_"): + setattr(self, k, v) + + def get_transform(self, *args) -> Transform: + """ + Execute the policy based on input data, and decide what transform to apply to inputs. + + Args: + args: Any fixed-length positional arguments. By default, the name of the arguments + should exist in the :class:`AugInput` to be used. + + Returns: + Transform: Returns the deterministic transform to apply to the input. + + Examples: + :: + class MyAug: + # if a policy needs to know both image and semantic segmentation + def get_transform(image, sem_seg) -> T.Transform: + pass + tfm: Transform = MyAug().get_transform(image, sem_seg) + new_image = tfm.apply_image(image) + + Notes: + Users can freely use arbitrary new argument names in custom + :meth:`get_transform` method, as long as they are available in the + input data. In detectron2 we use the following convention: + + * image: (H,W) or (H,W,C) ndarray of type uint8 in range [0, 255], or + floating point in range [0, 1] or [0, 255]. + * boxes: (N,4) ndarray of float32. It represents the instance bounding boxes + of N instances. Each is in XYXY format in unit of absolute coordinates. + * sem_seg: (H,W) ndarray of type uint8. Each element is an integer label of pixel. + + We do not specify convention for other types and do not include builtin + :class:`Augmentation` that uses other types in detectron2. + """ + raise NotImplementedError + + def __call__(self, aug_input) -> Transform: + """ + Augment the given `aug_input` **in-place**, and return the transform that's used. + + This method will be called to apply the augmentation. In most augmentation, it + is enough to use the default implementation, which calls :meth:`get_transform` + using the inputs. But a subclass can overwrite it to have more complicated logic. + + Args: + aug_input (AugInput): an object that has attributes needed by this augmentation + (defined by ``self.get_transform``). Its ``transform`` method will be called + to in-place transform it. + + Returns: + Transform: the transform that is applied on the input. + """ + args = _get_aug_input_args(self, aug_input) + tfm = self.get_transform(*args) + assert isinstance(tfm, (Transform, TransformList)), ( + f"{type(self)}.get_transform must return an instance of Transform! " + f"Got {type(tfm)} instead." + ) + aug_input.transform(tfm) + return tfm + + def _rand_range(self, low=1.0, high=None, size=None): + """ + Uniform float random number between low and high. + """ + if high is None: + low, high = 0, low + if size is None: + size = [] + return np.random.uniform(low, high, size) + + def __repr__(self): + """ + Produce something like: + "MyAugmentation(field1={self.field1}, field2={self.field2})" + """ + try: + sig = inspect.signature(self.__init__) + classname = type(self).__name__ + argstr = [] + for name, param in sig.parameters.items(): + assert ( + param.kind != param.VAR_POSITIONAL and param.kind != param.VAR_KEYWORD + ), "The default __repr__ doesn't support *args or **kwargs" + assert hasattr(self, name), ( + "Attribute {} not found! " + "Default __repr__ only works if attributes match the constructor.".format(name) + ) + attr = getattr(self, name) + default = param.default + if default is attr: + continue + attr_str = pprint.pformat(attr) + if "\n" in attr_str: + # don't show it if pformat decides to use >1 lines + attr_str = "..." + argstr.append("{}={}".format(name, attr_str)) + return "{}({})".format(classname, ", ".join(argstr)) + except AssertionError: + return super().__repr__() + + __str__ = __repr__ + + +class _TransformToAug(Augmentation): + def __init__(self, tfm: Transform): + self.tfm = tfm + + def get_transform(self, *args): + return self.tfm + + def __repr__(self): + return repr(self.tfm) + + __str__ = __repr__ + + +def _transform_to_aug(tfm_or_aug): + """ + Wrap Transform into Augmentation. + Private, used internally to implement augmentations. + """ + assert isinstance(tfm_or_aug, (Transform, Augmentation)), tfm_or_aug + if isinstance(tfm_or_aug, Augmentation): + return tfm_or_aug + else: + return _TransformToAug(tfm_or_aug) + + +class AugmentationList(Augmentation): + """ + Apply a sequence of augmentations. + + It has ``__call__`` method to apply the augmentations. + + Note that :meth:`get_transform` method is impossible (will throw error if called) + for :class:`AugmentationList`, because in order to apply a sequence of augmentations, + the kth augmentation must be applied first, to provide inputs needed by the (k+1)th + augmentation. + """ + + def __init__(self, augs): + """ + Args: + augs (list[Augmentation or Transform]): + """ + super().__init__() + self.augs = [_transform_to_aug(x) for x in augs] + + def __call__(self, aug_input) -> TransformList: + tfms = [] + for x in self.augs: + tfm = x(aug_input) + tfms.append(tfm) + return TransformList(tfms) + + def __repr__(self): + msgs = [str(x) for x in self.augs] + return "AugmentationList[{}]".format(", ".join(msgs)) + + __str__ = __repr__ + + +class AugInput: + """ + Input that can be used with :meth:`Augmentation.__call__`. + This is a standard implementation for the majority of use cases. + This class provides the standard attributes **"image", "boxes", "sem_seg"** + defined in :meth:`__init__` and they may be needed by different augmentations. + Most augmentation policies do not need attributes beyond these three. + + After applying augmentations to these attributes (using :meth:`AugInput.transform`), + the returned transforms can then be used to transform other data structures that users have. + + Examples: + :: + input = AugInput(image, boxes=boxes) + tfms = augmentation(input) + transformed_image = input.image + transformed_boxes = input.boxes + transformed_other_data = tfms.apply_other(other_data) + + An extended project that works with new data types may implement augmentation policies + that need other inputs. An algorithm may need to transform inputs in a way different + from the standard approach defined in this class. In those rare situations, users can + implement a class similar to this class, that satify the following condition: + + * The input must provide access to these data in the form of attribute access + (``getattr``). For example, if an :class:`Augmentation` to be applied needs "image" + and "sem_seg" arguments, its input must have the attribute "image" and "sem_seg". + * The input must have a ``transform(tfm: Transform) -> None`` method which + in-place transforms all its attributes. + """ + + # TODO maybe should support more builtin data types here + def __init__( + self, + image: np.ndarray, + *, + boxes: Optional[np.ndarray] = None, + sem_seg: Optional[np.ndarray] = None, + ): + """ + Args: + image (ndarray): (H,W) or (H,W,C) ndarray of type uint8 in range [0, 255], or + floating point in range [0, 1] or [0, 255]. The meaning of C is up + to users. + boxes (ndarray or None): Nx4 float32 boxes in XYXY_ABS mode + sem_seg (ndarray or None): HxW uint8 semantic segmentation mask. Each element + is an integer label of pixel. + """ + _check_img_dtype(image) + self.image = image + self.boxes = boxes + self.sem_seg = sem_seg + + def transform(self, tfm: Transform) -> None: + """ + In-place transform all attributes of this class. + + By "in-place", it means after calling this method, accessing an attribute such + as ``self.image`` will return transformed data. + """ + self.image = tfm.apply_image(self.image) + if self.boxes is not None: + self.boxes = tfm.apply_box(self.boxes) + if self.sem_seg is not None: + self.sem_seg = tfm.apply_segmentation(self.sem_seg) + + def apply_augmentations( + self, augmentations: List[Union[Augmentation, Transform]] + ) -> TransformList: + """ + Equivalent of ``AugmentationList(augmentations)(self)`` + """ + return AugmentationList(augmentations)(self) + + +def apply_augmentations(augmentations: List[Union[Transform, Augmentation]], inputs): + """ + Use ``T.AugmentationList(augmentations)(inputs)`` instead. + """ + if isinstance(inputs, np.ndarray): + # handle the common case of image-only Augmentation, also for backward compatibility + image_only = True + inputs = AugInput(inputs) + else: + image_only = False + tfms = inputs.apply_augmentations(augmentations) + return inputs.image if image_only else inputs, tfms + + +apply_transform_gens = apply_augmentations +""" +Alias for backward-compatibility. +""" + +TransformGen = Augmentation +""" +Alias for Augmentation, since it is something that generates :class:`Transform`s +""" + +StandardAugInput = AugInput +""" +Alias for compatibility. It's not worth the complexity to have two classes. +""" diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/transforms/augmentation_impl.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/transforms/augmentation_impl.py new file mode 100644 index 00000000..965f0a94 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/transforms/augmentation_impl.py @@ -0,0 +1,736 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. +""" +Implement many useful :class:`Augmentation`. +""" +import numpy as np +import sys +from numpy import random +from typing import Tuple +import torch +from fvcore.transforms.transform import ( + BlendTransform, + CropTransform, + HFlipTransform, + NoOpTransform, + PadTransform, + Transform, + TransformList, + VFlipTransform, +) +from PIL import Image + +from annotator.oneformer.detectron2.structures import Boxes, pairwise_iou + +from .augmentation import Augmentation, _transform_to_aug +from .transform import ExtentTransform, ResizeTransform, RotationTransform + +__all__ = [ + "FixedSizeCrop", + "RandomApply", + "RandomBrightness", + "RandomContrast", + "RandomCrop", + "RandomExtent", + "RandomFlip", + "RandomSaturation", + "RandomLighting", + "RandomRotation", + "Resize", + "ResizeScale", + "ResizeShortestEdge", + "RandomCrop_CategoryAreaConstraint", + "RandomResize", + "MinIoURandomCrop", +] + + +class RandomApply(Augmentation): + """ + Randomly apply an augmentation with a given probability. + """ + + def __init__(self, tfm_or_aug, prob=0.5): + """ + Args: + tfm_or_aug (Transform, Augmentation): the transform or augmentation + to be applied. It can either be a `Transform` or `Augmentation` + instance. + prob (float): probability between 0.0 and 1.0 that + the wrapper transformation is applied + """ + super().__init__() + self.aug = _transform_to_aug(tfm_or_aug) + assert 0.0 <= prob <= 1.0, f"Probablity must be between 0.0 and 1.0 (given: {prob})" + self.prob = prob + + def get_transform(self, *args): + do = self._rand_range() < self.prob + if do: + return self.aug.get_transform(*args) + else: + return NoOpTransform() + + def __call__(self, aug_input): + do = self._rand_range() < self.prob + if do: + return self.aug(aug_input) + else: + return NoOpTransform() + + +class RandomFlip(Augmentation): + """ + Flip the image horizontally or vertically with the given probability. + """ + + def __init__(self, prob=0.5, *, horizontal=True, vertical=False): + """ + Args: + prob (float): probability of flip. + horizontal (boolean): whether to apply horizontal flipping + vertical (boolean): whether to apply vertical flipping + """ + super().__init__() + + if horizontal and vertical: + raise ValueError("Cannot do both horiz and vert. Please use two Flip instead.") + if not horizontal and not vertical: + raise ValueError("At least one of horiz or vert has to be True!") + self._init(locals()) + + def get_transform(self, image): + h, w = image.shape[:2] + do = self._rand_range() < self.prob + if do: + if self.horizontal: + return HFlipTransform(w) + elif self.vertical: + return VFlipTransform(h) + else: + return NoOpTransform() + + +class Resize(Augmentation): + """Resize image to a fixed target size""" + + def __init__(self, shape, interp=Image.BILINEAR): + """ + Args: + shape: (h, w) tuple or a int + interp: PIL interpolation method + """ + if isinstance(shape, int): + shape = (shape, shape) + shape = tuple(shape) + self._init(locals()) + + def get_transform(self, image): + return ResizeTransform( + image.shape[0], image.shape[1], self.shape[0], self.shape[1], self.interp + ) + + +class ResizeShortestEdge(Augmentation): + """ + Resize the image while keeping the aspect ratio unchanged. + It attempts to scale the shorter edge to the given `short_edge_length`, + as long as the longer edge does not exceed `max_size`. + If `max_size` is reached, then downscale so that the longer edge does not exceed max_size. + """ + + @torch.jit.unused + def __init__( + self, short_edge_length, max_size=sys.maxsize, sample_style="range", interp=Image.BILINEAR + ): + """ + Args: + short_edge_length (list[int]): If ``sample_style=="range"``, + a [min, max] interval from which to sample the shortest edge length. + If ``sample_style=="choice"``, a list of shortest edge lengths to sample from. + max_size (int): maximum allowed longest edge length. + sample_style (str): either "range" or "choice". + """ + super().__init__() + assert sample_style in ["range", "choice"], sample_style + + self.is_range = sample_style == "range" + if isinstance(short_edge_length, int): + short_edge_length = (short_edge_length, short_edge_length) + if self.is_range: + assert len(short_edge_length) == 2, ( + "short_edge_length must be two values using 'range' sample style." + f" Got {short_edge_length}!" + ) + self._init(locals()) + + @torch.jit.unused + def get_transform(self, image): + h, w = image.shape[:2] + if self.is_range: + size = np.random.randint(self.short_edge_length[0], self.short_edge_length[1] + 1) + else: + size = np.random.choice(self.short_edge_length) + if size == 0: + return NoOpTransform() + + newh, neww = ResizeShortestEdge.get_output_shape(h, w, size, self.max_size) + return ResizeTransform(h, w, newh, neww, self.interp) + + @staticmethod + def get_output_shape( + oldh: int, oldw: int, short_edge_length: int, max_size: int + ) -> Tuple[int, int]: + """ + Compute the output size given input size and target short edge length. + """ + h, w = oldh, oldw + size = short_edge_length * 1.0 + scale = size / min(h, w) + if h < w: + newh, neww = size, scale * w + else: + newh, neww = scale * h, size + if max(newh, neww) > max_size: + scale = max_size * 1.0 / max(newh, neww) + newh = newh * scale + neww = neww * scale + neww = int(neww + 0.5) + newh = int(newh + 0.5) + return (newh, neww) + + +class ResizeScale(Augmentation): + """ + Takes target size as input and randomly scales the given target size between `min_scale` + and `max_scale`. It then scales the input image such that it fits inside the scaled target + box, keeping the aspect ratio constant. + This implements the resize part of the Google's 'resize_and_crop' data augmentation: + https://github.com/tensorflow/tpu/blob/master/models/official/detection/utils/input_utils.py#L127 + """ + + def __init__( + self, + min_scale: float, + max_scale: float, + target_height: int, + target_width: int, + interp: int = Image.BILINEAR, + ): + """ + Args: + min_scale: minimum image scale range. + max_scale: maximum image scale range. + target_height: target image height. + target_width: target image width. + interp: image interpolation method. + """ + super().__init__() + self._init(locals()) + + def _get_resize(self, image: np.ndarray, scale: float) -> Transform: + input_size = image.shape[:2] + + # Compute new target size given a scale. + target_size = (self.target_height, self.target_width) + target_scale_size = np.multiply(target_size, scale) + + # Compute actual rescaling applied to input image and output size. + output_scale = np.minimum( + target_scale_size[0] / input_size[0], target_scale_size[1] / input_size[1] + ) + output_size = np.round(np.multiply(input_size, output_scale)).astype(int) + + return ResizeTransform( + input_size[0], input_size[1], output_size[0], output_size[1], self.interp + ) + + def get_transform(self, image: np.ndarray) -> Transform: + random_scale = np.random.uniform(self.min_scale, self.max_scale) + return self._get_resize(image, random_scale) + + +class RandomRotation(Augmentation): + """ + This method returns a copy of this image, rotated the given + number of degrees counter clockwise around the given center. + """ + + def __init__(self, angle, expand=True, center=None, sample_style="range", interp=None): + """ + Args: + angle (list[float]): If ``sample_style=="range"``, + a [min, max] interval from which to sample the angle (in degrees). + If ``sample_style=="choice"``, a list of angles to sample from + expand (bool): choose if the image should be resized to fit the whole + rotated image (default), or simply cropped + center (list[[float, float]]): If ``sample_style=="range"``, + a [[minx, miny], [maxx, maxy]] relative interval from which to sample the center, + [0, 0] being the top left of the image and [1, 1] the bottom right. + If ``sample_style=="choice"``, a list of centers to sample from + Default: None, which means that the center of rotation is the center of the image + center has no effect if expand=True because it only affects shifting + """ + super().__init__() + assert sample_style in ["range", "choice"], sample_style + self.is_range = sample_style == "range" + if isinstance(angle, (float, int)): + angle = (angle, angle) + if center is not None and isinstance(center[0], (float, int)): + center = (center, center) + self._init(locals()) + + def get_transform(self, image): + h, w = image.shape[:2] + center = None + if self.is_range: + angle = np.random.uniform(self.angle[0], self.angle[1]) + if self.center is not None: + center = ( + np.random.uniform(self.center[0][0], self.center[1][0]), + np.random.uniform(self.center[0][1], self.center[1][1]), + ) + else: + angle = np.random.choice(self.angle) + if self.center is not None: + center = np.random.choice(self.center) + + if center is not None: + center = (w * center[0], h * center[1]) # Convert to absolute coordinates + + if angle % 360 == 0: + return NoOpTransform() + + return RotationTransform(h, w, angle, expand=self.expand, center=center, interp=self.interp) + + +class FixedSizeCrop(Augmentation): + """ + If `crop_size` is smaller than the input image size, then it uses a random crop of + the crop size. If `crop_size` is larger than the input image size, then it pads + the right and the bottom of the image to the crop size if `pad` is True, otherwise + it returns the smaller image. + """ + + def __init__( + self, + crop_size: Tuple[int], + pad: bool = True, + pad_value: float = 128.0, + seg_pad_value: int = 255, + ): + """ + Args: + crop_size: target image (height, width). + pad: if True, will pad images smaller than `crop_size` up to `crop_size` + pad_value: the padding value to the image. + seg_pad_value: the padding value to the segmentation mask. + """ + super().__init__() + self._init(locals()) + + def _get_crop(self, image: np.ndarray) -> Transform: + # Compute the image scale and scaled size. + input_size = image.shape[:2] + output_size = self.crop_size + + # Add random crop if the image is scaled up. + max_offset = np.subtract(input_size, output_size) + max_offset = np.maximum(max_offset, 0) + offset = np.multiply(max_offset, np.random.uniform(0.0, 1.0)) + offset = np.round(offset).astype(int) + return CropTransform( + offset[1], offset[0], output_size[1], output_size[0], input_size[1], input_size[0] + ) + + def _get_pad(self, image: np.ndarray) -> Transform: + # Compute the image scale and scaled size. + input_size = image.shape[:2] + output_size = self.crop_size + + # Add padding if the image is scaled down. + pad_size = np.subtract(output_size, input_size) + pad_size = np.maximum(pad_size, 0) + original_size = np.minimum(input_size, output_size) + return PadTransform( + 0, + 0, + pad_size[1], + pad_size[0], + original_size[1], + original_size[0], + self.pad_value, + self.seg_pad_value, + ) + + def get_transform(self, image: np.ndarray) -> TransformList: + transforms = [self._get_crop(image)] + if self.pad: + transforms.append(self._get_pad(image)) + return TransformList(transforms) + + +class RandomCrop(Augmentation): + """ + Randomly crop a rectangle region out of an image. + """ + + def __init__(self, crop_type: str, crop_size): + """ + Args: + crop_type (str): one of "relative_range", "relative", "absolute", "absolute_range". + crop_size (tuple[float, float]): two floats, explained below. + + - "relative": crop a (H * crop_size[0], W * crop_size[1]) region from an input image of + size (H, W). crop size should be in (0, 1] + - "relative_range": uniformly sample two values from [crop_size[0], 1] + and [crop_size[1]], 1], and use them as in "relative" crop type. + - "absolute" crop a (crop_size[0], crop_size[1]) region from input image. + crop_size must be smaller than the input image size. + - "absolute_range", for an input of size (H, W), uniformly sample H_crop in + [crop_size[0], min(H, crop_size[1])] and W_crop in [crop_size[0], min(W, crop_size[1])]. + Then crop a region (H_crop, W_crop). + """ + # TODO style of relative_range and absolute_range are not consistent: + # one takes (h, w) but another takes (min, max) + super().__init__() + assert crop_type in ["relative_range", "relative", "absolute", "absolute_range"] + self._init(locals()) + + def get_transform(self, image): + h, w = image.shape[:2] + croph, cropw = self.get_crop_size((h, w)) + assert h >= croph and w >= cropw, "Shape computation in {} has bugs.".format(self) + h0 = np.random.randint(h - croph + 1) + w0 = np.random.randint(w - cropw + 1) + return CropTransform(w0, h0, cropw, croph) + + def get_crop_size(self, image_size): + """ + Args: + image_size (tuple): height, width + + Returns: + crop_size (tuple): height, width in absolute pixels + """ + h, w = image_size + if self.crop_type == "relative": + ch, cw = self.crop_size + return int(h * ch + 0.5), int(w * cw + 0.5) + elif self.crop_type == "relative_range": + crop_size = np.asarray(self.crop_size, dtype=np.float32) + ch, cw = crop_size + np.random.rand(2) * (1 - crop_size) + return int(h * ch + 0.5), int(w * cw + 0.5) + elif self.crop_type == "absolute": + return (min(self.crop_size[0], h), min(self.crop_size[1], w)) + elif self.crop_type == "absolute_range": + assert self.crop_size[0] <= self.crop_size[1] + ch = np.random.randint(min(h, self.crop_size[0]), min(h, self.crop_size[1]) + 1) + cw = np.random.randint(min(w, self.crop_size[0]), min(w, self.crop_size[1]) + 1) + return ch, cw + else: + raise NotImplementedError("Unknown crop type {}".format(self.crop_type)) + + +class RandomCrop_CategoryAreaConstraint(Augmentation): + """ + Similar to :class:`RandomCrop`, but find a cropping window such that no single category + occupies a ratio of more than `single_category_max_area` in semantic segmentation ground + truth, which can cause unstability in training. The function attempts to find such a valid + cropping window for at most 10 times. + """ + + def __init__( + self, + crop_type: str, + crop_size, + single_category_max_area: float = 1.0, + ignored_category: int = None, + ): + """ + Args: + crop_type, crop_size: same as in :class:`RandomCrop` + single_category_max_area: the maximum allowed area ratio of a + category. Set to 1.0 to disable + ignored_category: allow this category in the semantic segmentation + ground truth to exceed the area ratio. Usually set to the category + that's ignored in training. + """ + self.crop_aug = RandomCrop(crop_type, crop_size) + self._init(locals()) + + def get_transform(self, image, sem_seg): + if self.single_category_max_area >= 1.0: + return self.crop_aug.get_transform(image) + else: + h, w = sem_seg.shape + for _ in range(10): + crop_size = self.crop_aug.get_crop_size((h, w)) + y0 = np.random.randint(h - crop_size[0] + 1) + x0 = np.random.randint(w - crop_size[1] + 1) + sem_seg_temp = sem_seg[y0 : y0 + crop_size[0], x0 : x0 + crop_size[1]] + labels, cnt = np.unique(sem_seg_temp, return_counts=True) + if self.ignored_category is not None: + cnt = cnt[labels != self.ignored_category] + if len(cnt) > 1 and np.max(cnt) < np.sum(cnt) * self.single_category_max_area: + break + crop_tfm = CropTransform(x0, y0, crop_size[1], crop_size[0]) + return crop_tfm + + +class RandomExtent(Augmentation): + """ + Outputs an image by cropping a random "subrect" of the source image. + + The subrect can be parameterized to include pixels outside the source image, + in which case they will be set to zeros (i.e. black). The size of the output + image will vary with the size of the random subrect. + """ + + def __init__(self, scale_range, shift_range): + """ + Args: + output_size (h, w): Dimensions of output image + scale_range (l, h): Range of input-to-output size scaling factor + shift_range (x, y): Range of shifts of the cropped subrect. The rect + is shifted by [w / 2 * Uniform(-x, x), h / 2 * Uniform(-y, y)], + where (w, h) is the (width, height) of the input image. Set each + component to zero to crop at the image's center. + """ + super().__init__() + self._init(locals()) + + def get_transform(self, image): + img_h, img_w = image.shape[:2] + + # Initialize src_rect to fit the input image. + src_rect = np.array([-0.5 * img_w, -0.5 * img_h, 0.5 * img_w, 0.5 * img_h]) + + # Apply a random scaling to the src_rect. + src_rect *= np.random.uniform(self.scale_range[0], self.scale_range[1]) + + # Apply a random shift to the coordinates origin. + src_rect[0::2] += self.shift_range[0] * img_w * (np.random.rand() - 0.5) + src_rect[1::2] += self.shift_range[1] * img_h * (np.random.rand() - 0.5) + + # Map src_rect coordinates into image coordinates (center at corner). + src_rect[0::2] += 0.5 * img_w + src_rect[1::2] += 0.5 * img_h + + return ExtentTransform( + src_rect=(src_rect[0], src_rect[1], src_rect[2], src_rect[3]), + output_size=(int(src_rect[3] - src_rect[1]), int(src_rect[2] - src_rect[0])), + ) + + +class RandomContrast(Augmentation): + """ + Randomly transforms image contrast. + + Contrast intensity is uniformly sampled in (intensity_min, intensity_max). + - intensity < 1 will reduce contrast + - intensity = 1 will preserve the input image + - intensity > 1 will increase contrast + + See: https://pillow.readthedocs.io/en/3.0.x/reference/ImageEnhance.html + """ + + def __init__(self, intensity_min, intensity_max): + """ + Args: + intensity_min (float): Minimum augmentation + intensity_max (float): Maximum augmentation + """ + super().__init__() + self._init(locals()) + + def get_transform(self, image): + w = np.random.uniform(self.intensity_min, self.intensity_max) + return BlendTransform(src_image=image.mean(), src_weight=1 - w, dst_weight=w) + + +class RandomBrightness(Augmentation): + """ + Randomly transforms image brightness. + + Brightness intensity is uniformly sampled in (intensity_min, intensity_max). + - intensity < 1 will reduce brightness + - intensity = 1 will preserve the input image + - intensity > 1 will increase brightness + + See: https://pillow.readthedocs.io/en/3.0.x/reference/ImageEnhance.html + """ + + def __init__(self, intensity_min, intensity_max): + """ + Args: + intensity_min (float): Minimum augmentation + intensity_max (float): Maximum augmentation + """ + super().__init__() + self._init(locals()) + + def get_transform(self, image): + w = np.random.uniform(self.intensity_min, self.intensity_max) + return BlendTransform(src_image=0, src_weight=1 - w, dst_weight=w) + + +class RandomSaturation(Augmentation): + """ + Randomly transforms saturation of an RGB image. + Input images are assumed to have 'RGB' channel order. + + Saturation intensity is uniformly sampled in (intensity_min, intensity_max). + - intensity < 1 will reduce saturation (make the image more grayscale) + - intensity = 1 will preserve the input image + - intensity > 1 will increase saturation + + See: https://pillow.readthedocs.io/en/3.0.x/reference/ImageEnhance.html + """ + + def __init__(self, intensity_min, intensity_max): + """ + Args: + intensity_min (float): Minimum augmentation (1 preserves input). + intensity_max (float): Maximum augmentation (1 preserves input). + """ + super().__init__() + self._init(locals()) + + def get_transform(self, image): + assert image.shape[-1] == 3, "RandomSaturation only works on RGB images" + w = np.random.uniform(self.intensity_min, self.intensity_max) + grayscale = image.dot([0.299, 0.587, 0.114])[:, :, np.newaxis] + return BlendTransform(src_image=grayscale, src_weight=1 - w, dst_weight=w) + + +class RandomLighting(Augmentation): + """ + The "lighting" augmentation described in AlexNet, using fixed PCA over ImageNet. + Input images are assumed to have 'RGB' channel order. + + The degree of color jittering is randomly sampled via a normal distribution, + with standard deviation given by the scale parameter. + """ + + def __init__(self, scale): + """ + Args: + scale (float): Standard deviation of principal component weighting. + """ + super().__init__() + self._init(locals()) + self.eigen_vecs = np.array( + [[-0.5675, 0.7192, 0.4009], [-0.5808, -0.0045, -0.8140], [-0.5836, -0.6948, 0.4203]] + ) + self.eigen_vals = np.array([0.2175, 0.0188, 0.0045]) + + def get_transform(self, image): + assert image.shape[-1] == 3, "RandomLighting only works on RGB images" + weights = np.random.normal(scale=self.scale, size=3) + return BlendTransform( + src_image=self.eigen_vecs.dot(weights * self.eigen_vals), src_weight=1.0, dst_weight=1.0 + ) + + +class RandomResize(Augmentation): + """Randomly resize image to a target size in shape_list""" + + def __init__(self, shape_list, interp=Image.BILINEAR): + """ + Args: + shape_list: a list of shapes in (h, w) + interp: PIL interpolation method + """ + self.shape_list = shape_list + self._init(locals()) + + def get_transform(self, image): + shape_idx = np.random.randint(low=0, high=len(self.shape_list)) + h, w = self.shape_list[shape_idx] + return ResizeTransform(image.shape[0], image.shape[1], h, w, self.interp) + + +class MinIoURandomCrop(Augmentation): + """Random crop the image & bboxes, the cropped patches have minimum IoU + requirement with original image & bboxes, the IoU threshold is randomly + selected from min_ious. + + Args: + min_ious (tuple): minimum IoU threshold for all intersections with + bounding boxes + min_crop_size (float): minimum crop's size (i.e. h,w := a*h, a*w, + where a >= min_crop_size) + mode_trials: number of trials for sampling min_ious threshold + crop_trials: number of trials for sampling crop_size after cropping + """ + + def __init__( + self, + min_ious=(0.1, 0.3, 0.5, 0.7, 0.9), + min_crop_size=0.3, + mode_trials=1000, + crop_trials=50, + ): + self.min_ious = min_ious + self.sample_mode = (1, *min_ious, 0) + self.min_crop_size = min_crop_size + self.mode_trials = mode_trials + self.crop_trials = crop_trials + + def get_transform(self, image, boxes): + """Call function to crop images and bounding boxes with minimum IoU + constraint. + + Args: + boxes: ground truth boxes in (x1, y1, x2, y2) format + """ + if boxes is None: + return NoOpTransform() + h, w, c = image.shape + for _ in range(self.mode_trials): + mode = random.choice(self.sample_mode) + self.mode = mode + if mode == 1: + return NoOpTransform() + + min_iou = mode + for _ in range(self.crop_trials): + new_w = random.uniform(self.min_crop_size * w, w) + new_h = random.uniform(self.min_crop_size * h, h) + + # h / w in [0.5, 2] + if new_h / new_w < 0.5 or new_h / new_w > 2: + continue + + left = random.uniform(w - new_w) + top = random.uniform(h - new_h) + + patch = np.array((int(left), int(top), int(left + new_w), int(top + new_h))) + # Line or point crop is not allowed + if patch[2] == patch[0] or patch[3] == patch[1]: + continue + overlaps = pairwise_iou( + Boxes(patch.reshape(-1, 4)), Boxes(boxes.reshape(-1, 4)) + ).reshape(-1) + if len(overlaps) > 0 and overlaps.min() < min_iou: + continue + + # center of boxes should inside the crop img + # only adjust boxes and instance masks when the gt is not empty + if len(overlaps) > 0: + # adjust boxes + def is_center_of_bboxes_in_patch(boxes, patch): + center = (boxes[:, :2] + boxes[:, 2:]) / 2 + mask = ( + (center[:, 0] > patch[0]) + * (center[:, 1] > patch[1]) + * (center[:, 0] < patch[2]) + * (center[:, 1] < patch[3]) + ) + return mask + + mask = is_center_of_bboxes_in_patch(boxes, patch) + if not mask.any(): + continue + return CropTransform(int(left), int(top), int(new_w), int(new_h)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/transforms/transform.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/transforms/transform.py new file mode 100644 index 00000000..de44b991 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/data/transforms/transform.py @@ -0,0 +1,351 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +""" +See "Data Augmentation" tutorial for an overview of the system: +https://detectron2.readthedocs.io/tutorials/augmentation.html +""" + +import numpy as np +import torch +import torch.nn.functional as F +from fvcore.transforms.transform import ( + CropTransform, + HFlipTransform, + NoOpTransform, + Transform, + TransformList, +) +from PIL import Image + +try: + import cv2 # noqa +except ImportError: + # OpenCV is an optional dependency at the moment + pass + +__all__ = [ + "ExtentTransform", + "ResizeTransform", + "RotationTransform", + "ColorTransform", + "PILColorTransform", +] + + +class ExtentTransform(Transform): + """ + Extracts a subregion from the source image and scales it to the output size. + + The fill color is used to map pixels from the source rect that fall outside + the source image. + + See: https://pillow.readthedocs.io/en/latest/PIL.html#PIL.ImageTransform.ExtentTransform + """ + + def __init__(self, src_rect, output_size, interp=Image.LINEAR, fill=0): + """ + Args: + src_rect (x0, y0, x1, y1): src coordinates + output_size (h, w): dst image size + interp: PIL interpolation methods + fill: Fill color used when src_rect extends outside image + """ + super().__init__() + self._set_attributes(locals()) + + def apply_image(self, img, interp=None): + h, w = self.output_size + if len(img.shape) > 2 and img.shape[2] == 1: + pil_image = Image.fromarray(img[:, :, 0], mode="L") + else: + pil_image = Image.fromarray(img) + pil_image = pil_image.transform( + size=(w, h), + method=Image.EXTENT, + data=self.src_rect, + resample=interp if interp else self.interp, + fill=self.fill, + ) + ret = np.asarray(pil_image) + if len(img.shape) > 2 and img.shape[2] == 1: + ret = np.expand_dims(ret, -1) + return ret + + def apply_coords(self, coords): + # Transform image center from source coordinates into output coordinates + # and then map the new origin to the corner of the output image. + h, w = self.output_size + x0, y0, x1, y1 = self.src_rect + new_coords = coords.astype(np.float32) + new_coords[:, 0] -= 0.5 * (x0 + x1) + new_coords[:, 1] -= 0.5 * (y0 + y1) + new_coords[:, 0] *= w / (x1 - x0) + new_coords[:, 1] *= h / (y1 - y0) + new_coords[:, 0] += 0.5 * w + new_coords[:, 1] += 0.5 * h + return new_coords + + def apply_segmentation(self, segmentation): + segmentation = self.apply_image(segmentation, interp=Image.NEAREST) + return segmentation + + +class ResizeTransform(Transform): + """ + Resize the image to a target size. + """ + + def __init__(self, h, w, new_h, new_w, interp=None): + """ + Args: + h, w (int): original image size + new_h, new_w (int): new image size + interp: PIL interpolation methods, defaults to bilinear. + """ + # TODO decide on PIL vs opencv + super().__init__() + if interp is None: + interp = Image.BILINEAR + self._set_attributes(locals()) + + def apply_image(self, img, interp=None): + assert img.shape[:2] == (self.h, self.w) + assert len(img.shape) <= 4 + interp_method = interp if interp is not None else self.interp + + if img.dtype == np.uint8: + if len(img.shape) > 2 and img.shape[2] == 1: + pil_image = Image.fromarray(img[:, :, 0], mode="L") + else: + pil_image = Image.fromarray(img) + pil_image = pil_image.resize((self.new_w, self.new_h), interp_method) + ret = np.asarray(pil_image) + if len(img.shape) > 2 and img.shape[2] == 1: + ret = np.expand_dims(ret, -1) + else: + # PIL only supports uint8 + if any(x < 0 for x in img.strides): + img = np.ascontiguousarray(img) + img = torch.from_numpy(img) + shape = list(img.shape) + shape_4d = shape[:2] + [1] * (4 - len(shape)) + shape[2:] + img = img.view(shape_4d).permute(2, 3, 0, 1) # hw(c) -> nchw + _PIL_RESIZE_TO_INTERPOLATE_MODE = { + Image.NEAREST: "nearest", + Image.BILINEAR: "bilinear", + Image.BICUBIC: "bicubic", + } + mode = _PIL_RESIZE_TO_INTERPOLATE_MODE[interp_method] + align_corners = None if mode == "nearest" else False + img = F.interpolate( + img, (self.new_h, self.new_w), mode=mode, align_corners=align_corners + ) + shape[:2] = (self.new_h, self.new_w) + ret = img.permute(2, 3, 0, 1).view(shape).numpy() # nchw -> hw(c) + + return ret + + def apply_coords(self, coords): + coords[:, 0] = coords[:, 0] * (self.new_w * 1.0 / self.w) + coords[:, 1] = coords[:, 1] * (self.new_h * 1.0 / self.h) + return coords + + def apply_segmentation(self, segmentation): + segmentation = self.apply_image(segmentation, interp=Image.NEAREST) + return segmentation + + def inverse(self): + return ResizeTransform(self.new_h, self.new_w, self.h, self.w, self.interp) + + +class RotationTransform(Transform): + """ + This method returns a copy of this image, rotated the given + number of degrees counter clockwise around its center. + """ + + def __init__(self, h, w, angle, expand=True, center=None, interp=None): + """ + Args: + h, w (int): original image size + angle (float): degrees for rotation + expand (bool): choose if the image should be resized to fit the whole + rotated image (default), or simply cropped + center (tuple (width, height)): coordinates of the rotation center + if left to None, the center will be fit to the center of each image + center has no effect if expand=True because it only affects shifting + interp: cv2 interpolation method, default cv2.INTER_LINEAR + """ + super().__init__() + image_center = np.array((w / 2, h / 2)) + if center is None: + center = image_center + if interp is None: + interp = cv2.INTER_LINEAR + abs_cos, abs_sin = (abs(np.cos(np.deg2rad(angle))), abs(np.sin(np.deg2rad(angle)))) + if expand: + # find the new width and height bounds + bound_w, bound_h = np.rint( + [h * abs_sin + w * abs_cos, h * abs_cos + w * abs_sin] + ).astype(int) + else: + bound_w, bound_h = w, h + + self._set_attributes(locals()) + self.rm_coords = self.create_rotation_matrix() + # Needed because of this problem https://github.com/opencv/opencv/issues/11784 + self.rm_image = self.create_rotation_matrix(offset=-0.5) + + def apply_image(self, img, interp=None): + """ + img should be a numpy array, formatted as Height * Width * Nchannels + """ + if len(img) == 0 or self.angle % 360 == 0: + return img + assert img.shape[:2] == (self.h, self.w) + interp = interp if interp is not None else self.interp + return cv2.warpAffine(img, self.rm_image, (self.bound_w, self.bound_h), flags=interp) + + def apply_coords(self, coords): + """ + coords should be a N * 2 array-like, containing N couples of (x, y) points + """ + coords = np.asarray(coords, dtype=float) + if len(coords) == 0 or self.angle % 360 == 0: + return coords + return cv2.transform(coords[:, np.newaxis, :], self.rm_coords)[:, 0, :] + + def apply_segmentation(self, segmentation): + segmentation = self.apply_image(segmentation, interp=cv2.INTER_NEAREST) + return segmentation + + def create_rotation_matrix(self, offset=0): + center = (self.center[0] + offset, self.center[1] + offset) + rm = cv2.getRotationMatrix2D(tuple(center), self.angle, 1) + if self.expand: + # Find the coordinates of the center of rotation in the new image + # The only point for which we know the future coordinates is the center of the image + rot_im_center = cv2.transform(self.image_center[None, None, :] + offset, rm)[0, 0, :] + new_center = np.array([self.bound_w / 2, self.bound_h / 2]) + offset - rot_im_center + # shift the rotation center to the new coordinates + rm[:, 2] += new_center + return rm + + def inverse(self): + """ + The inverse is to rotate it back with expand, and crop to get the original shape. + """ + if not self.expand: # Not possible to inverse if a part of the image is lost + raise NotImplementedError() + rotation = RotationTransform( + self.bound_h, self.bound_w, -self.angle, True, None, self.interp + ) + crop = CropTransform( + (rotation.bound_w - self.w) // 2, (rotation.bound_h - self.h) // 2, self.w, self.h + ) + return TransformList([rotation, crop]) + + +class ColorTransform(Transform): + """ + Generic wrapper for any photometric transforms. + These transformations should only affect the color space and + not the coordinate space of the image (e.g. annotation + coordinates such as bounding boxes should not be changed) + """ + + def __init__(self, op): + """ + Args: + op (Callable): operation to be applied to the image, + which takes in an ndarray and returns an ndarray. + """ + if not callable(op): + raise ValueError("op parameter should be callable") + super().__init__() + self._set_attributes(locals()) + + def apply_image(self, img): + return self.op(img) + + def apply_coords(self, coords): + return coords + + def inverse(self): + return NoOpTransform() + + def apply_segmentation(self, segmentation): + return segmentation + + +class PILColorTransform(ColorTransform): + """ + Generic wrapper for PIL Photometric image transforms, + which affect the color space and not the coordinate + space of the image + """ + + def __init__(self, op): + """ + Args: + op (Callable): operation to be applied to the image, + which takes in a PIL Image and returns a transformed + PIL Image. + For reference on possible operations see: + - https://pillow.readthedocs.io/en/stable/ + """ + if not callable(op): + raise ValueError("op parameter should be callable") + super().__init__(op) + + def apply_image(self, img): + img = Image.fromarray(img) + return np.asarray(super().apply_image(img)) + + +def HFlip_rotated_box(transform, rotated_boxes): + """ + Apply the horizontal flip transform on rotated boxes. + + Args: + rotated_boxes (ndarray): Nx5 floating point array of + (x_center, y_center, width, height, angle_degrees) format + in absolute coordinates. + """ + # Transform x_center + rotated_boxes[:, 0] = transform.width - rotated_boxes[:, 0] + # Transform angle + rotated_boxes[:, 4] = -rotated_boxes[:, 4] + return rotated_boxes + + +def Resize_rotated_box(transform, rotated_boxes): + """ + Apply the resizing transform on rotated boxes. For details of how these (approximation) + formulas are derived, please refer to :meth:`RotatedBoxes.scale`. + + Args: + rotated_boxes (ndarray): Nx5 floating point array of + (x_center, y_center, width, height, angle_degrees) format + in absolute coordinates. + """ + scale_factor_x = transform.new_w * 1.0 / transform.w + scale_factor_y = transform.new_h * 1.0 / transform.h + rotated_boxes[:, 0] *= scale_factor_x + rotated_boxes[:, 1] *= scale_factor_y + theta = rotated_boxes[:, 4] * np.pi / 180.0 + c = np.cos(theta) + s = np.sin(theta) + rotated_boxes[:, 2] *= np.sqrt(np.square(scale_factor_x * c) + np.square(scale_factor_y * s)) + rotated_boxes[:, 3] *= np.sqrt(np.square(scale_factor_x * s) + np.square(scale_factor_y * c)) + rotated_boxes[:, 4] = np.arctan2(scale_factor_x * s, scale_factor_y * c) * 180 / np.pi + + return rotated_boxes + + +HFlipTransform.register_type("rotated_box", HFlip_rotated_box) +ResizeTransform.register_type("rotated_box", Resize_rotated_box) + +# not necessary any more with latest fvcore +NoOpTransform.register_type("rotated_box", lambda t, x: x) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/__init__.py new file mode 100644 index 00000000..08a61572 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/__init__.py @@ -0,0 +1,12 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +from .launch import * +from .train_loop import * + +__all__ = [k for k in globals().keys() if not k.startswith("_")] + + +# prefer to let hooks and defaults live in separate namespaces (therefore not in __all__) +# but still make them available here +from .hooks import * +from .defaults import * diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/defaults.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/defaults.py new file mode 100644 index 00000000..51d49148 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/defaults.py @@ -0,0 +1,715 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +""" +This file contains components with some default boilerplate logic user may need +in training / testing. They will not work for everyone, but many users may find them useful. + +The behavior of functions/classes in this file is subject to change, +since they are meant to represent the "common default behavior" people need in their projects. +""" + +import argparse +import logging +import os +import sys +import weakref +from collections import OrderedDict +from typing import Optional +import torch +from fvcore.nn.precise_bn import get_bn_modules +from omegaconf import OmegaConf +from torch.nn.parallel import DistributedDataParallel + +import annotator.oneformer.detectron2.data.transforms as T +from annotator.oneformer.detectron2.checkpoint import DetectionCheckpointer +from annotator.oneformer.detectron2.config import CfgNode, LazyConfig +from annotator.oneformer.detectron2.data import ( + MetadataCatalog, + build_detection_test_loader, + build_detection_train_loader, +) +from annotator.oneformer.detectron2.evaluation import ( + DatasetEvaluator, + inference_on_dataset, + print_csv_format, + verify_results, +) +from annotator.oneformer.detectron2.modeling import build_model +from annotator.oneformer.detectron2.solver import build_lr_scheduler, build_optimizer +from annotator.oneformer.detectron2.utils import comm +from annotator.oneformer.detectron2.utils.collect_env import collect_env_info +from annotator.oneformer.detectron2.utils.env import seed_all_rng +from annotator.oneformer.detectron2.utils.events import CommonMetricPrinter, JSONWriter, TensorboardXWriter +from annotator.oneformer.detectron2.utils.file_io import PathManager +from annotator.oneformer.detectron2.utils.logger import setup_logger + +from . import hooks +from .train_loop import AMPTrainer, SimpleTrainer, TrainerBase + +__all__ = [ + "create_ddp_model", + "default_argument_parser", + "default_setup", + "default_writers", + "DefaultPredictor", + "DefaultTrainer", +] + + +def create_ddp_model(model, *, fp16_compression=False, **kwargs): + """ + Create a DistributedDataParallel model if there are >1 processes. + + Args: + model: a torch.nn.Module + fp16_compression: add fp16 compression hooks to the ddp object. + See more at https://pytorch.org/docs/stable/ddp_comm_hooks.html#torch.distributed.algorithms.ddp_comm_hooks.default_hooks.fp16_compress_hook + kwargs: other arguments of :module:`torch.nn.parallel.DistributedDataParallel`. + """ # noqa + if comm.get_world_size() == 1: + return model + if "device_ids" not in kwargs: + kwargs["device_ids"] = [comm.get_local_rank()] + ddp = DistributedDataParallel(model, **kwargs) + if fp16_compression: + from torch.distributed.algorithms.ddp_comm_hooks import default as comm_hooks + + ddp.register_comm_hook(state=None, hook=comm_hooks.fp16_compress_hook) + return ddp + + +def default_argument_parser(epilog=None): + """ + Create a parser with some common arguments used by detectron2 users. + + Args: + epilog (str): epilog passed to ArgumentParser describing the usage. + + Returns: + argparse.ArgumentParser: + """ + parser = argparse.ArgumentParser( + epilog=epilog + or f""" +Examples: + +Run on single machine: + $ {sys.argv[0]} --num-gpus 8 --config-file cfg.yaml + +Change some config options: + $ {sys.argv[0]} --config-file cfg.yaml MODEL.WEIGHTS /path/to/weight.pth SOLVER.BASE_LR 0.001 + +Run on multiple machines: + (machine0)$ {sys.argv[0]} --machine-rank 0 --num-machines 2 --dist-url [--other-flags] + (machine1)$ {sys.argv[0]} --machine-rank 1 --num-machines 2 --dist-url [--other-flags] +""", + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + parser.add_argument("--config-file", default="", metavar="FILE", help="path to config file") + parser.add_argument( + "--resume", + action="store_true", + help="Whether to attempt to resume from the checkpoint directory. " + "See documentation of `DefaultTrainer.resume_or_load()` for what it means.", + ) + parser.add_argument("--eval-only", action="store_true", help="perform evaluation only") + parser.add_argument("--num-gpus", type=int, default=1, help="number of gpus *per machine*") + parser.add_argument("--num-machines", type=int, default=1, help="total number of machines") + parser.add_argument( + "--machine-rank", type=int, default=0, help="the rank of this machine (unique per machine)" + ) + + # PyTorch still may leave orphan processes in multi-gpu training. + # Therefore we use a deterministic way to obtain port, + # so that users are aware of orphan processes by seeing the port occupied. + port = 2**15 + 2**14 + hash(os.getuid() if sys.platform != "win32" else 1) % 2**14 + parser.add_argument( + "--dist-url", + default="tcp://127.0.0.1:{}".format(port), + help="initialization URL for pytorch distributed backend. See " + "https://pytorch.org/docs/stable/distributed.html for details.", + ) + parser.add_argument( + "opts", + help=""" +Modify config options at the end of the command. For Yacs configs, use +space-separated "PATH.KEY VALUE" pairs. +For python-based LazyConfig, use "path.key=value". + """.strip(), + default=None, + nargs=argparse.REMAINDER, + ) + return parser + + +def _try_get_key(cfg, *keys, default=None): + """ + Try select keys from cfg until the first key that exists. Otherwise return default. + """ + if isinstance(cfg, CfgNode): + cfg = OmegaConf.create(cfg.dump()) + for k in keys: + none = object() + p = OmegaConf.select(cfg, k, default=none) + if p is not none: + return p + return default + + +def _highlight(code, filename): + try: + import pygments + except ImportError: + return code + + from pygments.lexers import Python3Lexer, YamlLexer + from pygments.formatters import Terminal256Formatter + + lexer = Python3Lexer() if filename.endswith(".py") else YamlLexer() + code = pygments.highlight(code, lexer, Terminal256Formatter(style="monokai")) + return code + + +def default_setup(cfg, args): + """ + Perform some basic common setups at the beginning of a job, including: + + 1. Set up the detectron2 logger + 2. Log basic information about environment, cmdline arguments, and config + 3. Backup the config to the output directory + + Args: + cfg (CfgNode or omegaconf.DictConfig): the full config to be used + args (argparse.NameSpace): the command line arguments to be logged + """ + output_dir = _try_get_key(cfg, "OUTPUT_DIR", "output_dir", "train.output_dir") + if comm.is_main_process() and output_dir: + PathManager.mkdirs(output_dir) + + rank = comm.get_rank() + setup_logger(output_dir, distributed_rank=rank, name="fvcore") + logger = setup_logger(output_dir, distributed_rank=rank) + + logger.info("Rank of current process: {}. World size: {}".format(rank, comm.get_world_size())) + logger.info("Environment info:\n" + collect_env_info()) + + logger.info("Command line arguments: " + str(args)) + if hasattr(args, "config_file") and args.config_file != "": + logger.info( + "Contents of args.config_file={}:\n{}".format( + args.config_file, + _highlight(PathManager.open(args.config_file, "r").read(), args.config_file), + ) + ) + + if comm.is_main_process() and output_dir: + # Note: some of our scripts may expect the existence of + # config.yaml in output directory + path = os.path.join(output_dir, "config.yaml") + if isinstance(cfg, CfgNode): + logger.info("Running with full config:\n{}".format(_highlight(cfg.dump(), ".yaml"))) + with PathManager.open(path, "w") as f: + f.write(cfg.dump()) + else: + LazyConfig.save(cfg, path) + logger.info("Full config saved to {}".format(path)) + + # make sure each worker has a different, yet deterministic seed if specified + seed = _try_get_key(cfg, "SEED", "train.seed", default=-1) + seed_all_rng(None if seed < 0 else seed + rank) + + # cudnn benchmark has large overhead. It shouldn't be used considering the small size of + # typical validation set. + if not (hasattr(args, "eval_only") and args.eval_only): + torch.backends.cudnn.benchmark = _try_get_key( + cfg, "CUDNN_BENCHMARK", "train.cudnn_benchmark", default=False + ) + + +def default_writers(output_dir: str, max_iter: Optional[int] = None): + """ + Build a list of :class:`EventWriter` to be used. + It now consists of a :class:`CommonMetricPrinter`, + :class:`TensorboardXWriter` and :class:`JSONWriter`. + + Args: + output_dir: directory to store JSON metrics and tensorboard events + max_iter: the total number of iterations + + Returns: + list[EventWriter]: a list of :class:`EventWriter` objects. + """ + PathManager.mkdirs(output_dir) + return [ + # It may not always print what you want to see, since it prints "common" metrics only. + CommonMetricPrinter(max_iter), + JSONWriter(os.path.join(output_dir, "metrics.json")), + TensorboardXWriter(output_dir), + ] + + +class DefaultPredictor: + """ + Create a simple end-to-end predictor with the given config that runs on + single device for a single input image. + + Compared to using the model directly, this class does the following additions: + + 1. Load checkpoint from `cfg.MODEL.WEIGHTS`. + 2. Always take BGR image as the input and apply conversion defined by `cfg.INPUT.FORMAT`. + 3. Apply resizing defined by `cfg.INPUT.{MIN,MAX}_SIZE_TEST`. + 4. Take one input image and produce a single output, instead of a batch. + + This is meant for simple demo purposes, so it does the above steps automatically. + This is not meant for benchmarks or running complicated inference logic. + If you'd like to do anything more complicated, please refer to its source code as + examples to build and use the model manually. + + Attributes: + metadata (Metadata): the metadata of the underlying dataset, obtained from + cfg.DATASETS.TEST. + + Examples: + :: + pred = DefaultPredictor(cfg) + inputs = cv2.imread("input.jpg") + outputs = pred(inputs) + """ + + def __init__(self, cfg): + self.cfg = cfg.clone() # cfg can be modified by model + self.model = build_model(self.cfg) + self.model.eval() + if len(cfg.DATASETS.TEST): + self.metadata = MetadataCatalog.get(cfg.DATASETS.TEST[0]) + + checkpointer = DetectionCheckpointer(self.model) + checkpointer.load(cfg.MODEL.WEIGHTS) + + self.aug = T.ResizeShortestEdge( + [cfg.INPUT.MIN_SIZE_TEST, cfg.INPUT.MIN_SIZE_TEST], cfg.INPUT.MAX_SIZE_TEST + ) + + self.input_format = cfg.INPUT.FORMAT + assert self.input_format in ["RGB", "BGR"], self.input_format + + def __call__(self, original_image): + """ + Args: + original_image (np.ndarray): an image of shape (H, W, C) (in BGR order). + + Returns: + predictions (dict): + the output of the model for one image only. + See :doc:`/tutorials/models` for details about the format. + """ + with torch.no_grad(): # https://github.com/sphinx-doc/sphinx/issues/4258 + # Apply pre-processing to image. + if self.input_format == "RGB": + # whether the model expects BGR inputs or RGB + original_image = original_image[:, :, ::-1] + height, width = original_image.shape[:2] + image = self.aug.get_transform(original_image).apply_image(original_image) + image = torch.as_tensor(image.astype("float32").transpose(2, 0, 1)) + + inputs = {"image": image, "height": height, "width": width} + predictions = self.model([inputs])[0] + return predictions + + +class DefaultTrainer(TrainerBase): + """ + A trainer with default training logic. It does the following: + + 1. Create a :class:`SimpleTrainer` using model, optimizer, dataloader + defined by the given config. Create a LR scheduler defined by the config. + 2. Load the last checkpoint or `cfg.MODEL.WEIGHTS`, if exists, when + `resume_or_load` is called. + 3. Register a few common hooks defined by the config. + + It is created to simplify the **standard model training workflow** and reduce code boilerplate + for users who only need the standard training workflow, with standard features. + It means this class makes *many assumptions* about your training logic that + may easily become invalid in a new research. In fact, any assumptions beyond those made in the + :class:`SimpleTrainer` are too much for research. + + The code of this class has been annotated about restrictive assumptions it makes. + When they do not work for you, you're encouraged to: + + 1. Overwrite methods of this class, OR: + 2. Use :class:`SimpleTrainer`, which only does minimal SGD training and + nothing else. You can then add your own hooks if needed. OR: + 3. Write your own training loop similar to `tools/plain_train_net.py`. + + See the :doc:`/tutorials/training` tutorials for more details. + + Note that the behavior of this class, like other functions/classes in + this file, is not stable, since it is meant to represent the "common default behavior". + It is only guaranteed to work well with the standard models and training workflow in detectron2. + To obtain more stable behavior, write your own training logic with other public APIs. + + Examples: + :: + trainer = DefaultTrainer(cfg) + trainer.resume_or_load() # load last checkpoint or MODEL.WEIGHTS + trainer.train() + + Attributes: + scheduler: + checkpointer (DetectionCheckpointer): + cfg (CfgNode): + """ + + def __init__(self, cfg): + """ + Args: + cfg (CfgNode): + """ + super().__init__() + logger = logging.getLogger("detectron2") + if not logger.isEnabledFor(logging.INFO): # setup_logger is not called for d2 + setup_logger() + cfg = DefaultTrainer.auto_scale_workers(cfg, comm.get_world_size()) + + # Assume these objects must be constructed in this order. + model = self.build_model(cfg) + optimizer = self.build_optimizer(cfg, model) + data_loader = self.build_train_loader(cfg) + + model = create_ddp_model(model, broadcast_buffers=False) + self._trainer = (AMPTrainer if cfg.SOLVER.AMP.ENABLED else SimpleTrainer)( + model, data_loader, optimizer + ) + + self.scheduler = self.build_lr_scheduler(cfg, optimizer) + self.checkpointer = DetectionCheckpointer( + # Assume you want to save checkpoints together with logs/statistics + model, + cfg.OUTPUT_DIR, + trainer=weakref.proxy(self), + ) + self.start_iter = 0 + self.max_iter = cfg.SOLVER.MAX_ITER + self.cfg = cfg + + self.register_hooks(self.build_hooks()) + + def resume_or_load(self, resume=True): + """ + If `resume==True` and `cfg.OUTPUT_DIR` contains the last checkpoint (defined by + a `last_checkpoint` file), resume from the file. Resuming means loading all + available states (eg. optimizer and scheduler) and update iteration counter + from the checkpoint. ``cfg.MODEL.WEIGHTS`` will not be used. + + Otherwise, this is considered as an independent training. The method will load model + weights from the file `cfg.MODEL.WEIGHTS` (but will not load other states) and start + from iteration 0. + + Args: + resume (bool): whether to do resume or not + """ + self.checkpointer.resume_or_load(self.cfg.MODEL.WEIGHTS, resume=resume) + if resume and self.checkpointer.has_checkpoint(): + # The checkpoint stores the training iteration that just finished, thus we start + # at the next iteration + self.start_iter = self.iter + 1 + + def build_hooks(self): + """ + Build a list of default hooks, including timing, evaluation, + checkpointing, lr scheduling, precise BN, writing events. + + Returns: + list[HookBase]: + """ + cfg = self.cfg.clone() + cfg.defrost() + cfg.DATALOADER.NUM_WORKERS = 0 # save some memory and time for PreciseBN + + ret = [ + hooks.IterationTimer(), + hooks.LRScheduler(), + hooks.PreciseBN( + # Run at the same freq as (but before) evaluation. + cfg.TEST.EVAL_PERIOD, + self.model, + # Build a new data loader to not affect training + self.build_train_loader(cfg), + cfg.TEST.PRECISE_BN.NUM_ITER, + ) + if cfg.TEST.PRECISE_BN.ENABLED and get_bn_modules(self.model) + else None, + ] + + # Do PreciseBN before checkpointer, because it updates the model and need to + # be saved by checkpointer. + # This is not always the best: if checkpointing has a different frequency, + # some checkpoints may have more precise statistics than others. + if comm.is_main_process(): + ret.append(hooks.PeriodicCheckpointer(self.checkpointer, cfg.SOLVER.CHECKPOINT_PERIOD)) + + def test_and_save_results(): + self._last_eval_results = self.test(self.cfg, self.model) + return self._last_eval_results + + # Do evaluation after checkpointer, because then if it fails, + # we can use the saved checkpoint to debug. + ret.append(hooks.EvalHook(cfg.TEST.EVAL_PERIOD, test_and_save_results)) + + if comm.is_main_process(): + # Here the default print/log frequency of each writer is used. + # run writers in the end, so that evaluation metrics are written + ret.append(hooks.PeriodicWriter(self.build_writers(), period=20)) + return ret + + def build_writers(self): + """ + Build a list of writers to be used using :func:`default_writers()`. + If you'd like a different list of writers, you can overwrite it in + your trainer. + + Returns: + list[EventWriter]: a list of :class:`EventWriter` objects. + """ + return default_writers(self.cfg.OUTPUT_DIR, self.max_iter) + + def train(self): + """ + Run training. + + Returns: + OrderedDict of results, if evaluation is enabled. Otherwise None. + """ + super().train(self.start_iter, self.max_iter) + if len(self.cfg.TEST.EXPECTED_RESULTS) and comm.is_main_process(): + assert hasattr( + self, "_last_eval_results" + ), "No evaluation results obtained during training!" + verify_results(self.cfg, self._last_eval_results) + return self._last_eval_results + + def run_step(self): + self._trainer.iter = self.iter + self._trainer.run_step() + + def state_dict(self): + ret = super().state_dict() + ret["_trainer"] = self._trainer.state_dict() + return ret + + def load_state_dict(self, state_dict): + super().load_state_dict(state_dict) + self._trainer.load_state_dict(state_dict["_trainer"]) + + @classmethod + def build_model(cls, cfg): + """ + Returns: + torch.nn.Module: + + It now calls :func:`detectron2.modeling.build_model`. + Overwrite it if you'd like a different model. + """ + model = build_model(cfg) + logger = logging.getLogger(__name__) + logger.info("Model:\n{}".format(model)) + return model + + @classmethod + def build_optimizer(cls, cfg, model): + """ + Returns: + torch.optim.Optimizer: + + It now calls :func:`detectron2.solver.build_optimizer`. + Overwrite it if you'd like a different optimizer. + """ + return build_optimizer(cfg, model) + + @classmethod + def build_lr_scheduler(cls, cfg, optimizer): + """ + It now calls :func:`detectron2.solver.build_lr_scheduler`. + Overwrite it if you'd like a different scheduler. + """ + return build_lr_scheduler(cfg, optimizer) + + @classmethod + def build_train_loader(cls, cfg): + """ + Returns: + iterable + + It now calls :func:`detectron2.data.build_detection_train_loader`. + Overwrite it if you'd like a different data loader. + """ + return build_detection_train_loader(cfg) + + @classmethod + def build_test_loader(cls, cfg, dataset_name): + """ + Returns: + iterable + + It now calls :func:`detectron2.data.build_detection_test_loader`. + Overwrite it if you'd like a different data loader. + """ + return build_detection_test_loader(cfg, dataset_name) + + @classmethod + def build_evaluator(cls, cfg, dataset_name): + """ + Returns: + DatasetEvaluator or None + + It is not implemented by default. + """ + raise NotImplementedError( + """ +If you want DefaultTrainer to automatically run evaluation, +please implement `build_evaluator()` in subclasses (see train_net.py for example). +Alternatively, you can call evaluation functions yourself (see Colab balloon tutorial for example). +""" + ) + + @classmethod + def test(cls, cfg, model, evaluators=None): + """ + Evaluate the given model. The given model is expected to already contain + weights to evaluate. + + Args: + cfg (CfgNode): + model (nn.Module): + evaluators (list[DatasetEvaluator] or None): if None, will call + :meth:`build_evaluator`. Otherwise, must have the same length as + ``cfg.DATASETS.TEST``. + + Returns: + dict: a dict of result metrics + """ + logger = logging.getLogger(__name__) + if isinstance(evaluators, DatasetEvaluator): + evaluators = [evaluators] + if evaluators is not None: + assert len(cfg.DATASETS.TEST) == len(evaluators), "{} != {}".format( + len(cfg.DATASETS.TEST), len(evaluators) + ) + + results = OrderedDict() + for idx, dataset_name in enumerate(cfg.DATASETS.TEST): + data_loader = cls.build_test_loader(cfg, dataset_name) + # When evaluators are passed in as arguments, + # implicitly assume that evaluators can be created before data_loader. + if evaluators is not None: + evaluator = evaluators[idx] + else: + try: + evaluator = cls.build_evaluator(cfg, dataset_name) + except NotImplementedError: + logger.warn( + "No evaluator found. Use `DefaultTrainer.test(evaluators=)`, " + "or implement its `build_evaluator` method." + ) + results[dataset_name] = {} + continue + results_i = inference_on_dataset(model, data_loader, evaluator) + results[dataset_name] = results_i + if comm.is_main_process(): + assert isinstance( + results_i, dict + ), "Evaluator must return a dict on the main process. Got {} instead.".format( + results_i + ) + logger.info("Evaluation results for {} in csv format:".format(dataset_name)) + print_csv_format(results_i) + + if len(results) == 1: + results = list(results.values())[0] + return results + + @staticmethod + def auto_scale_workers(cfg, num_workers: int): + """ + When the config is defined for certain number of workers (according to + ``cfg.SOLVER.REFERENCE_WORLD_SIZE``) that's different from the number of + workers currently in use, returns a new cfg where the total batch size + is scaled so that the per-GPU batch size stays the same as the + original ``IMS_PER_BATCH // REFERENCE_WORLD_SIZE``. + + Other config options are also scaled accordingly: + * training steps and warmup steps are scaled inverse proportionally. + * learning rate are scaled proportionally, following :paper:`ImageNet in 1h`. + + For example, with the original config like the following: + + .. code-block:: yaml + + IMS_PER_BATCH: 16 + BASE_LR: 0.1 + REFERENCE_WORLD_SIZE: 8 + MAX_ITER: 5000 + STEPS: (4000,) + CHECKPOINT_PERIOD: 1000 + + When this config is used on 16 GPUs instead of the reference number 8, + calling this method will return a new config with: + + .. code-block:: yaml + + IMS_PER_BATCH: 32 + BASE_LR: 0.2 + REFERENCE_WORLD_SIZE: 16 + MAX_ITER: 2500 + STEPS: (2000,) + CHECKPOINT_PERIOD: 500 + + Note that both the original config and this new config can be trained on 16 GPUs. + It's up to user whether to enable this feature (by setting ``REFERENCE_WORLD_SIZE``). + + Returns: + CfgNode: a new config. Same as original if ``cfg.SOLVER.REFERENCE_WORLD_SIZE==0``. + """ + old_world_size = cfg.SOLVER.REFERENCE_WORLD_SIZE + if old_world_size == 0 or old_world_size == num_workers: + return cfg + cfg = cfg.clone() + frozen = cfg.is_frozen() + cfg.defrost() + + assert ( + cfg.SOLVER.IMS_PER_BATCH % old_world_size == 0 + ), "Invalid REFERENCE_WORLD_SIZE in config!" + scale = num_workers / old_world_size + bs = cfg.SOLVER.IMS_PER_BATCH = int(round(cfg.SOLVER.IMS_PER_BATCH * scale)) + lr = cfg.SOLVER.BASE_LR = cfg.SOLVER.BASE_LR * scale + max_iter = cfg.SOLVER.MAX_ITER = int(round(cfg.SOLVER.MAX_ITER / scale)) + warmup_iter = cfg.SOLVER.WARMUP_ITERS = int(round(cfg.SOLVER.WARMUP_ITERS / scale)) + cfg.SOLVER.STEPS = tuple(int(round(s / scale)) for s in cfg.SOLVER.STEPS) + cfg.TEST.EVAL_PERIOD = int(round(cfg.TEST.EVAL_PERIOD / scale)) + cfg.SOLVER.CHECKPOINT_PERIOD = int(round(cfg.SOLVER.CHECKPOINT_PERIOD / scale)) + cfg.SOLVER.REFERENCE_WORLD_SIZE = num_workers # maintain invariant + logger = logging.getLogger(__name__) + logger.info( + f"Auto-scaling the config to batch_size={bs}, learning_rate={lr}, " + f"max_iter={max_iter}, warmup={warmup_iter}." + ) + + if frozen: + cfg.freeze() + return cfg + + +# Access basic attributes from the underlying trainer +for _attr in ["model", "data_loader", "optimizer"]: + setattr( + DefaultTrainer, + _attr, + property( + # getter + lambda self, x=_attr: getattr(self._trainer, x), + # setter + lambda self, value, x=_attr: setattr(self._trainer, x, value), + ), + ) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/hooks.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/hooks.py new file mode 100644 index 00000000..7dd43ac7 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/hooks.py @@ -0,0 +1,690 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +import datetime +import itertools +import logging +import math +import operator +import os +import tempfile +import time +import warnings +from collections import Counter +import torch +from fvcore.common.checkpoint import Checkpointer +from fvcore.common.checkpoint import PeriodicCheckpointer as _PeriodicCheckpointer +from fvcore.common.param_scheduler import ParamScheduler +from fvcore.common.timer import Timer +from fvcore.nn.precise_bn import get_bn_modules, update_bn_stats + +import annotator.oneformer.detectron2.utils.comm as comm +from annotator.oneformer.detectron2.evaluation.testing import flatten_results_dict +from annotator.oneformer.detectron2.solver import LRMultiplier +from annotator.oneformer.detectron2.solver import LRScheduler as _LRScheduler +from annotator.oneformer.detectron2.utils.events import EventStorage, EventWriter +from annotator.oneformer.detectron2.utils.file_io import PathManager + +from .train_loop import HookBase + +__all__ = [ + "CallbackHook", + "IterationTimer", + "PeriodicWriter", + "PeriodicCheckpointer", + "BestCheckpointer", + "LRScheduler", + "AutogradProfiler", + "EvalHook", + "PreciseBN", + "TorchProfiler", + "TorchMemoryStats", +] + + +""" +Implement some common hooks. +""" + + +class CallbackHook(HookBase): + """ + Create a hook using callback functions provided by the user. + """ + + def __init__(self, *, before_train=None, after_train=None, before_step=None, after_step=None): + """ + Each argument is a function that takes one argument: the trainer. + """ + self._before_train = before_train + self._before_step = before_step + self._after_step = after_step + self._after_train = after_train + + def before_train(self): + if self._before_train: + self._before_train(self.trainer) + + def after_train(self): + if self._after_train: + self._after_train(self.trainer) + # The functions may be closures that hold reference to the trainer + # Therefore, delete them to avoid circular reference. + del self._before_train, self._after_train + del self._before_step, self._after_step + + def before_step(self): + if self._before_step: + self._before_step(self.trainer) + + def after_step(self): + if self._after_step: + self._after_step(self.trainer) + + +class IterationTimer(HookBase): + """ + Track the time spent for each iteration (each run_step call in the trainer). + Print a summary in the end of training. + + This hook uses the time between the call to its :meth:`before_step` + and :meth:`after_step` methods. + Under the convention that :meth:`before_step` of all hooks should only + take negligible amount of time, the :class:`IterationTimer` hook should be + placed at the beginning of the list of hooks to obtain accurate timing. + """ + + def __init__(self, warmup_iter=3): + """ + Args: + warmup_iter (int): the number of iterations at the beginning to exclude + from timing. + """ + self._warmup_iter = warmup_iter + self._step_timer = Timer() + self._start_time = time.perf_counter() + self._total_timer = Timer() + + def before_train(self): + self._start_time = time.perf_counter() + self._total_timer.reset() + self._total_timer.pause() + + def after_train(self): + logger = logging.getLogger(__name__) + total_time = time.perf_counter() - self._start_time + total_time_minus_hooks = self._total_timer.seconds() + hook_time = total_time - total_time_minus_hooks + + num_iter = self.trainer.storage.iter + 1 - self.trainer.start_iter - self._warmup_iter + + if num_iter > 0 and total_time_minus_hooks > 0: + # Speed is meaningful only after warmup + # NOTE this format is parsed by grep in some scripts + logger.info( + "Overall training speed: {} iterations in {} ({:.4f} s / it)".format( + num_iter, + str(datetime.timedelta(seconds=int(total_time_minus_hooks))), + total_time_minus_hooks / num_iter, + ) + ) + + logger.info( + "Total training time: {} ({} on hooks)".format( + str(datetime.timedelta(seconds=int(total_time))), + str(datetime.timedelta(seconds=int(hook_time))), + ) + ) + + def before_step(self): + self._step_timer.reset() + self._total_timer.resume() + + def after_step(self): + # +1 because we're in after_step, the current step is done + # but not yet counted + iter_done = self.trainer.storage.iter - self.trainer.start_iter + 1 + if iter_done >= self._warmup_iter: + sec = self._step_timer.seconds() + self.trainer.storage.put_scalars(time=sec) + else: + self._start_time = time.perf_counter() + self._total_timer.reset() + + self._total_timer.pause() + + +class PeriodicWriter(HookBase): + """ + Write events to EventStorage (by calling ``writer.write()``) periodically. + + It is executed every ``period`` iterations and after the last iteration. + Note that ``period`` does not affect how data is smoothed by each writer. + """ + + def __init__(self, writers, period=20): + """ + Args: + writers (list[EventWriter]): a list of EventWriter objects + period (int): + """ + self._writers = writers + for w in writers: + assert isinstance(w, EventWriter), w + self._period = period + + def after_step(self): + if (self.trainer.iter + 1) % self._period == 0 or ( + self.trainer.iter == self.trainer.max_iter - 1 + ): + for writer in self._writers: + writer.write() + + def after_train(self): + for writer in self._writers: + # If any new data is found (e.g. produced by other after_train), + # write them before closing + writer.write() + writer.close() + + +class PeriodicCheckpointer(_PeriodicCheckpointer, HookBase): + """ + Same as :class:`detectron2.checkpoint.PeriodicCheckpointer`, but as a hook. + + Note that when used as a hook, + it is unable to save additional data other than what's defined + by the given `checkpointer`. + + It is executed every ``period`` iterations and after the last iteration. + """ + + def before_train(self): + self.max_iter = self.trainer.max_iter + + def after_step(self): + # No way to use **kwargs + self.step(self.trainer.iter) + + +class BestCheckpointer(HookBase): + """ + Checkpoints best weights based off given metric. + + This hook should be used in conjunction to and executed after the hook + that produces the metric, e.g. `EvalHook`. + """ + + def __init__( + self, + eval_period: int, + checkpointer: Checkpointer, + val_metric: str, + mode: str = "max", + file_prefix: str = "model_best", + ) -> None: + """ + Args: + eval_period (int): the period `EvalHook` is set to run. + checkpointer: the checkpointer object used to save checkpoints. + val_metric (str): validation metric to track for best checkpoint, e.g. "bbox/AP50" + mode (str): one of {'max', 'min'}. controls whether the chosen val metric should be + maximized or minimized, e.g. for "bbox/AP50" it should be "max" + file_prefix (str): the prefix of checkpoint's filename, defaults to "model_best" + """ + self._logger = logging.getLogger(__name__) + self._period = eval_period + self._val_metric = val_metric + assert mode in [ + "max", + "min", + ], f'Mode "{mode}" to `BestCheckpointer` is unknown. It should be one of {"max", "min"}.' + if mode == "max": + self._compare = operator.gt + else: + self._compare = operator.lt + self._checkpointer = checkpointer + self._file_prefix = file_prefix + self.best_metric = None + self.best_iter = None + + def _update_best(self, val, iteration): + if math.isnan(val) or math.isinf(val): + return False + self.best_metric = val + self.best_iter = iteration + return True + + def _best_checking(self): + metric_tuple = self.trainer.storage.latest().get(self._val_metric) + if metric_tuple is None: + self._logger.warning( + f"Given val metric {self._val_metric} does not seem to be computed/stored." + "Will not be checkpointing based on it." + ) + return + else: + latest_metric, metric_iter = metric_tuple + + if self.best_metric is None: + if self._update_best(latest_metric, metric_iter): + additional_state = {"iteration": metric_iter} + self._checkpointer.save(f"{self._file_prefix}", **additional_state) + self._logger.info( + f"Saved first model at {self.best_metric:0.5f} @ {self.best_iter} steps" + ) + elif self._compare(latest_metric, self.best_metric): + additional_state = {"iteration": metric_iter} + self._checkpointer.save(f"{self._file_prefix}", **additional_state) + self._logger.info( + f"Saved best model as latest eval score for {self._val_metric} is " + f"{latest_metric:0.5f}, better than last best score " + f"{self.best_metric:0.5f} @ iteration {self.best_iter}." + ) + self._update_best(latest_metric, metric_iter) + else: + self._logger.info( + f"Not saving as latest eval score for {self._val_metric} is {latest_metric:0.5f}, " + f"not better than best score {self.best_metric:0.5f} @ iteration {self.best_iter}." + ) + + def after_step(self): + # same conditions as `EvalHook` + next_iter = self.trainer.iter + 1 + if ( + self._period > 0 + and next_iter % self._period == 0 + and next_iter != self.trainer.max_iter + ): + self._best_checking() + + def after_train(self): + # same conditions as `EvalHook` + if self.trainer.iter + 1 >= self.trainer.max_iter: + self._best_checking() + + +class LRScheduler(HookBase): + """ + A hook which executes a torch builtin LR scheduler and summarizes the LR. + It is executed after every iteration. + """ + + def __init__(self, optimizer=None, scheduler=None): + """ + Args: + optimizer (torch.optim.Optimizer): + scheduler (torch.optim.LRScheduler or fvcore.common.param_scheduler.ParamScheduler): + if a :class:`ParamScheduler` object, it defines the multiplier over the base LR + in the optimizer. + + If any argument is not given, will try to obtain it from the trainer. + """ + self._optimizer = optimizer + self._scheduler = scheduler + + def before_train(self): + self._optimizer = self._optimizer or self.trainer.optimizer + if isinstance(self.scheduler, ParamScheduler): + self._scheduler = LRMultiplier( + self._optimizer, + self.scheduler, + self.trainer.max_iter, + last_iter=self.trainer.iter - 1, + ) + self._best_param_group_id = LRScheduler.get_best_param_group_id(self._optimizer) + + @staticmethod + def get_best_param_group_id(optimizer): + # NOTE: some heuristics on what LR to summarize + # summarize the param group with most parameters + largest_group = max(len(g["params"]) for g in optimizer.param_groups) + + if largest_group == 1: + # If all groups have one parameter, + # then find the most common initial LR, and use it for summary + lr_count = Counter([g["lr"] for g in optimizer.param_groups]) + lr = lr_count.most_common()[0][0] + for i, g in enumerate(optimizer.param_groups): + if g["lr"] == lr: + return i + else: + for i, g in enumerate(optimizer.param_groups): + if len(g["params"]) == largest_group: + return i + + def after_step(self): + lr = self._optimizer.param_groups[self._best_param_group_id]["lr"] + self.trainer.storage.put_scalar("lr", lr, smoothing_hint=False) + self.scheduler.step() + + @property + def scheduler(self): + return self._scheduler or self.trainer.scheduler + + def state_dict(self): + if isinstance(self.scheduler, _LRScheduler): + return self.scheduler.state_dict() + return {} + + def load_state_dict(self, state_dict): + if isinstance(self.scheduler, _LRScheduler): + logger = logging.getLogger(__name__) + logger.info("Loading scheduler from state_dict ...") + self.scheduler.load_state_dict(state_dict) + + +class TorchProfiler(HookBase): + """ + A hook which runs `torch.profiler.profile`. + + Examples: + :: + hooks.TorchProfiler( + lambda trainer: 10 < trainer.iter < 20, self.cfg.OUTPUT_DIR + ) + + The above example will run the profiler for iteration 10~20 and dump + results to ``OUTPUT_DIR``. We did not profile the first few iterations + because they are typically slower than the rest. + The result files can be loaded in the ``chrome://tracing`` page in chrome browser, + and the tensorboard visualizations can be visualized using + ``tensorboard --logdir OUTPUT_DIR/log`` + """ + + def __init__(self, enable_predicate, output_dir, *, activities=None, save_tensorboard=True): + """ + Args: + enable_predicate (callable[trainer -> bool]): a function which takes a trainer, + and returns whether to enable the profiler. + It will be called once every step, and can be used to select which steps to profile. + output_dir (str): the output directory to dump tracing files. + activities (iterable): same as in `torch.profiler.profile`. + save_tensorboard (bool): whether to save tensorboard visualizations at (output_dir)/log/ + """ + self._enable_predicate = enable_predicate + self._activities = activities + self._output_dir = output_dir + self._save_tensorboard = save_tensorboard + + def before_step(self): + if self._enable_predicate(self.trainer): + if self._save_tensorboard: + on_trace_ready = torch.profiler.tensorboard_trace_handler( + os.path.join( + self._output_dir, + "log", + "profiler-tensorboard-iter{}".format(self.trainer.iter), + ), + f"worker{comm.get_rank()}", + ) + else: + on_trace_ready = None + self._profiler = torch.profiler.profile( + activities=self._activities, + on_trace_ready=on_trace_ready, + record_shapes=True, + profile_memory=True, + with_stack=True, + with_flops=True, + ) + self._profiler.__enter__() + else: + self._profiler = None + + def after_step(self): + if self._profiler is None: + return + self._profiler.__exit__(None, None, None) + if not self._save_tensorboard: + PathManager.mkdirs(self._output_dir) + out_file = os.path.join( + self._output_dir, "profiler-trace-iter{}.json".format(self.trainer.iter) + ) + if "://" not in out_file: + self._profiler.export_chrome_trace(out_file) + else: + # Support non-posix filesystems + with tempfile.TemporaryDirectory(prefix="detectron2_profiler") as d: + tmp_file = os.path.join(d, "tmp.json") + self._profiler.export_chrome_trace(tmp_file) + with open(tmp_file) as f: + content = f.read() + with PathManager.open(out_file, "w") as f: + f.write(content) + + +class AutogradProfiler(TorchProfiler): + """ + A hook which runs `torch.autograd.profiler.profile`. + + Examples: + :: + hooks.AutogradProfiler( + lambda trainer: 10 < trainer.iter < 20, self.cfg.OUTPUT_DIR + ) + + The above example will run the profiler for iteration 10~20 and dump + results to ``OUTPUT_DIR``. We did not profile the first few iterations + because they are typically slower than the rest. + The result files can be loaded in the ``chrome://tracing`` page in chrome browser. + + Note: + When used together with NCCL on older version of GPUs, + autograd profiler may cause deadlock because it unnecessarily allocates + memory on every device it sees. The memory management calls, if + interleaved with NCCL calls, lead to deadlock on GPUs that do not + support ``cudaLaunchCooperativeKernelMultiDevice``. + """ + + def __init__(self, enable_predicate, output_dir, *, use_cuda=True): + """ + Args: + enable_predicate (callable[trainer -> bool]): a function which takes a trainer, + and returns whether to enable the profiler. + It will be called once every step, and can be used to select which steps to profile. + output_dir (str): the output directory to dump tracing files. + use_cuda (bool): same as in `torch.autograd.profiler.profile`. + """ + warnings.warn("AutogradProfiler has been deprecated in favor of TorchProfiler.") + self._enable_predicate = enable_predicate + self._use_cuda = use_cuda + self._output_dir = output_dir + + def before_step(self): + if self._enable_predicate(self.trainer): + self._profiler = torch.autograd.profiler.profile(use_cuda=self._use_cuda) + self._profiler.__enter__() + else: + self._profiler = None + + +class EvalHook(HookBase): + """ + Run an evaluation function periodically, and at the end of training. + + It is executed every ``eval_period`` iterations and after the last iteration. + """ + + def __init__(self, eval_period, eval_function, eval_after_train=True): + """ + Args: + eval_period (int): the period to run `eval_function`. Set to 0 to + not evaluate periodically (but still evaluate after the last iteration + if `eval_after_train` is True). + eval_function (callable): a function which takes no arguments, and + returns a nested dict of evaluation metrics. + eval_after_train (bool): whether to evaluate after the last iteration + + Note: + This hook must be enabled in all or none workers. + If you would like only certain workers to perform evaluation, + give other workers a no-op function (`eval_function=lambda: None`). + """ + self._period = eval_period + self._func = eval_function + self._eval_after_train = eval_after_train + + def _do_eval(self): + results = self._func() + + if results: + assert isinstance( + results, dict + ), "Eval function must return a dict. Got {} instead.".format(results) + + flattened_results = flatten_results_dict(results) + for k, v in flattened_results.items(): + try: + v = float(v) + except Exception as e: + raise ValueError( + "[EvalHook] eval_function should return a nested dict of float. " + "Got '{}: {}' instead.".format(k, v) + ) from e + self.trainer.storage.put_scalars(**flattened_results, smoothing_hint=False) + + # Evaluation may take different time among workers. + # A barrier make them start the next iteration together. + comm.synchronize() + + def after_step(self): + next_iter = self.trainer.iter + 1 + if self._period > 0 and next_iter % self._period == 0: + # do the last eval in after_train + if next_iter != self.trainer.max_iter: + self._do_eval() + + def after_train(self): + # This condition is to prevent the eval from running after a failed training + if self._eval_after_train and self.trainer.iter + 1 >= self.trainer.max_iter: + self._do_eval() + # func is likely a closure that holds reference to the trainer + # therefore we clean it to avoid circular reference in the end + del self._func + + +class PreciseBN(HookBase): + """ + The standard implementation of BatchNorm uses EMA in inference, which is + sometimes suboptimal. + This class computes the true average of statistics rather than the moving average, + and put true averages to every BN layer in the given model. + + It is executed every ``period`` iterations and after the last iteration. + """ + + def __init__(self, period, model, data_loader, num_iter): + """ + Args: + period (int): the period this hook is run, or 0 to not run during training. + The hook will always run in the end of training. + model (nn.Module): a module whose all BN layers in training mode will be + updated by precise BN. + Note that user is responsible for ensuring the BN layers to be + updated are in training mode when this hook is triggered. + data_loader (iterable): it will produce data to be run by `model(data)`. + num_iter (int): number of iterations used to compute the precise + statistics. + """ + self._logger = logging.getLogger(__name__) + if len(get_bn_modules(model)) == 0: + self._logger.info( + "PreciseBN is disabled because model does not contain BN layers in training mode." + ) + self._disabled = True + return + + self._model = model + self._data_loader = data_loader + self._num_iter = num_iter + self._period = period + self._disabled = False + + self._data_iter = None + + def after_step(self): + next_iter = self.trainer.iter + 1 + is_final = next_iter == self.trainer.max_iter + if is_final or (self._period > 0 and next_iter % self._period == 0): + self.update_stats() + + def update_stats(self): + """ + Update the model with precise statistics. Users can manually call this method. + """ + if self._disabled: + return + + if self._data_iter is None: + self._data_iter = iter(self._data_loader) + + def data_loader(): + for num_iter in itertools.count(1): + if num_iter % 100 == 0: + self._logger.info( + "Running precise-BN ... {}/{} iterations.".format(num_iter, self._num_iter) + ) + # This way we can reuse the same iterator + yield next(self._data_iter) + + with EventStorage(): # capture events in a new storage to discard them + self._logger.info( + "Running precise-BN for {} iterations... ".format(self._num_iter) + + "Note that this could produce different statistics every time." + ) + update_bn_stats(self._model, data_loader(), self._num_iter) + + +class TorchMemoryStats(HookBase): + """ + Writes pytorch's cuda memory statistics periodically. + """ + + def __init__(self, period=20, max_runs=10): + """ + Args: + period (int): Output stats each 'period' iterations + max_runs (int): Stop the logging after 'max_runs' + """ + + self._logger = logging.getLogger(__name__) + self._period = period + self._max_runs = max_runs + self._runs = 0 + + def after_step(self): + if self._runs > self._max_runs: + return + + if (self.trainer.iter + 1) % self._period == 0 or ( + self.trainer.iter == self.trainer.max_iter - 1 + ): + if torch.cuda.is_available(): + max_reserved_mb = torch.cuda.max_memory_reserved() / 1024.0 / 1024.0 + reserved_mb = torch.cuda.memory_reserved() / 1024.0 / 1024.0 + max_allocated_mb = torch.cuda.max_memory_allocated() / 1024.0 / 1024.0 + allocated_mb = torch.cuda.memory_allocated() / 1024.0 / 1024.0 + + self._logger.info( + ( + " iter: {} " + " max_reserved_mem: {:.0f}MB " + " reserved_mem: {:.0f}MB " + " max_allocated_mem: {:.0f}MB " + " allocated_mem: {:.0f}MB " + ).format( + self.trainer.iter, + max_reserved_mb, + reserved_mb, + max_allocated_mb, + allocated_mb, + ) + ) + + self._runs += 1 + if self._runs == self._max_runs: + mem_summary = torch.cuda.memory_summary() + self._logger.info("\n" + mem_summary) + + torch.cuda.reset_peak_memory_stats() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/launch.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/launch.py new file mode 100644 index 00000000..0a2d6bcd --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/launch.py @@ -0,0 +1,123 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import logging +from datetime import timedelta +import torch +import torch.distributed as dist +import torch.multiprocessing as mp + +from annotator.oneformer.detectron2.utils import comm + +__all__ = ["DEFAULT_TIMEOUT", "launch"] + +DEFAULT_TIMEOUT = timedelta(minutes=30) + + +def _find_free_port(): + import socket + + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + # Binding to port 0 will cause the OS to find an available port for us + sock.bind(("", 0)) + port = sock.getsockname()[1] + sock.close() + # NOTE: there is still a chance the port could be taken by other processes. + return port + + +def launch( + main_func, + # Should be num_processes_per_machine, but kept for compatibility. + num_gpus_per_machine, + num_machines=1, + machine_rank=0, + dist_url=None, + args=(), + timeout=DEFAULT_TIMEOUT, +): + """ + Launch multi-process or distributed training. + This function must be called on all machines involved in the training. + It will spawn child processes (defined by ``num_gpus_per_machine``) on each machine. + + Args: + main_func: a function that will be called by `main_func(*args)` + num_gpus_per_machine (int): number of processes per machine. When + using GPUs, this should be the number of GPUs. + num_machines (int): the total number of machines + machine_rank (int): the rank of this machine + dist_url (str): url to connect to for distributed jobs, including protocol + e.g. "tcp://127.0.0.1:8686". + Can be set to "auto" to automatically select a free port on localhost + timeout (timedelta): timeout of the distributed workers + args (tuple): arguments passed to main_func + """ + world_size = num_machines * num_gpus_per_machine + if world_size > 1: + # https://github.com/pytorch/pytorch/pull/14391 + # TODO prctl in spawned processes + + if dist_url == "auto": + assert num_machines == 1, "dist_url=auto not supported in multi-machine jobs." + port = _find_free_port() + dist_url = f"tcp://127.0.0.1:{port}" + if num_machines > 1 and dist_url.startswith("file://"): + logger = logging.getLogger(__name__) + logger.warning( + "file:// is not a reliable init_method in multi-machine jobs. Prefer tcp://" + ) + + mp.start_processes( + _distributed_worker, + nprocs=num_gpus_per_machine, + args=( + main_func, + world_size, + num_gpus_per_machine, + machine_rank, + dist_url, + args, + timeout, + ), + daemon=False, + ) + else: + main_func(*args) + + +def _distributed_worker( + local_rank, + main_func, + world_size, + num_gpus_per_machine, + machine_rank, + dist_url, + args, + timeout=DEFAULT_TIMEOUT, +): + has_gpu = torch.cuda.is_available() + if has_gpu: + assert num_gpus_per_machine <= torch.cuda.device_count() + global_rank = machine_rank * num_gpus_per_machine + local_rank + try: + dist.init_process_group( + backend="NCCL" if has_gpu else "GLOO", + init_method=dist_url, + world_size=world_size, + rank=global_rank, + timeout=timeout, + ) + except Exception as e: + logger = logging.getLogger(__name__) + logger.error("Process group URL: {}".format(dist_url)) + raise e + + # Setup the local process group. + comm.create_local_process_group(num_gpus_per_machine) + if has_gpu: + torch.cuda.set_device(local_rank) + + # synchronize is needed here to prevent a possible timeout after calling init_process_group + # See: https://github.com/facebookresearch/maskrcnn-benchmark/issues/172 + comm.synchronize() + + main_func(*args) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/train_loop.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/train_loop.py new file mode 100644 index 00000000..0c24c5af --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/engine/train_loop.py @@ -0,0 +1,469 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +import logging +import numpy as np +import time +import weakref +from typing import List, Mapping, Optional +import torch +from torch.nn.parallel import DataParallel, DistributedDataParallel + +import annotator.oneformer.detectron2.utils.comm as comm +from annotator.oneformer.detectron2.utils.events import EventStorage, get_event_storage +from annotator.oneformer.detectron2.utils.logger import _log_api_usage + +__all__ = ["HookBase", "TrainerBase", "SimpleTrainer", "AMPTrainer"] + + +class HookBase: + """ + Base class for hooks that can be registered with :class:`TrainerBase`. + + Each hook can implement 4 methods. The way they are called is demonstrated + in the following snippet: + :: + hook.before_train() + for iter in range(start_iter, max_iter): + hook.before_step() + trainer.run_step() + hook.after_step() + iter += 1 + hook.after_train() + + Notes: + 1. In the hook method, users can access ``self.trainer`` to access more + properties about the context (e.g., model, current iteration, or config + if using :class:`DefaultTrainer`). + + 2. A hook that does something in :meth:`before_step` can often be + implemented equivalently in :meth:`after_step`. + If the hook takes non-trivial time, it is strongly recommended to + implement the hook in :meth:`after_step` instead of :meth:`before_step`. + The convention is that :meth:`before_step` should only take negligible time. + + Following this convention will allow hooks that do care about the difference + between :meth:`before_step` and :meth:`after_step` (e.g., timer) to + function properly. + + """ + + trainer: "TrainerBase" = None + """ + A weak reference to the trainer object. Set by the trainer when the hook is registered. + """ + + def before_train(self): + """ + Called before the first iteration. + """ + pass + + def after_train(self): + """ + Called after the last iteration. + """ + pass + + def before_step(self): + """ + Called before each iteration. + """ + pass + + def after_backward(self): + """ + Called after the backward pass of each iteration. + """ + pass + + def after_step(self): + """ + Called after each iteration. + """ + pass + + def state_dict(self): + """ + Hooks are stateless by default, but can be made checkpointable by + implementing `state_dict` and `load_state_dict`. + """ + return {} + + +class TrainerBase: + """ + Base class for iterative trainer with hooks. + + The only assumption we made here is: the training runs in a loop. + A subclass can implement what the loop is. + We made no assumptions about the existence of dataloader, optimizer, model, etc. + + Attributes: + iter(int): the current iteration. + + start_iter(int): The iteration to start with. + By convention the minimum possible value is 0. + + max_iter(int): The iteration to end training. + + storage(EventStorage): An EventStorage that's opened during the course of training. + """ + + def __init__(self) -> None: + self._hooks: List[HookBase] = [] + self.iter: int = 0 + self.start_iter: int = 0 + self.max_iter: int + self.storage: EventStorage + _log_api_usage("trainer." + self.__class__.__name__) + + def register_hooks(self, hooks: List[Optional[HookBase]]) -> None: + """ + Register hooks to the trainer. The hooks are executed in the order + they are registered. + + Args: + hooks (list[Optional[HookBase]]): list of hooks + """ + hooks = [h for h in hooks if h is not None] + for h in hooks: + assert isinstance(h, HookBase) + # To avoid circular reference, hooks and trainer cannot own each other. + # This normally does not matter, but will cause memory leak if the + # involved objects contain __del__: + # See http://engineering.hearsaysocial.com/2013/06/16/circular-references-in-python/ + h.trainer = weakref.proxy(self) + self._hooks.extend(hooks) + + def train(self, start_iter: int, max_iter: int): + """ + Args: + start_iter, max_iter (int): See docs above + """ + logger = logging.getLogger(__name__) + logger.info("Starting training from iteration {}".format(start_iter)) + + self.iter = self.start_iter = start_iter + self.max_iter = max_iter + + with EventStorage(start_iter) as self.storage: + try: + self.before_train() + for self.iter in range(start_iter, max_iter): + self.before_step() + self.run_step() + self.after_step() + # self.iter == max_iter can be used by `after_train` to + # tell whether the training successfully finished or failed + # due to exceptions. + self.iter += 1 + except Exception: + logger.exception("Exception during training:") + raise + finally: + self.after_train() + + def before_train(self): + for h in self._hooks: + h.before_train() + + def after_train(self): + self.storage.iter = self.iter + for h in self._hooks: + h.after_train() + + def before_step(self): + # Maintain the invariant that storage.iter == trainer.iter + # for the entire execution of each step + self.storage.iter = self.iter + + for h in self._hooks: + h.before_step() + + def after_backward(self): + for h in self._hooks: + h.after_backward() + + def after_step(self): + for h in self._hooks: + h.after_step() + + def run_step(self): + raise NotImplementedError + + def state_dict(self): + ret = {"iteration": self.iter} + hooks_state = {} + for h in self._hooks: + sd = h.state_dict() + if sd: + name = type(h).__qualname__ + if name in hooks_state: + # TODO handle repetitive stateful hooks + continue + hooks_state[name] = sd + if hooks_state: + ret["hooks"] = hooks_state + return ret + + def load_state_dict(self, state_dict): + logger = logging.getLogger(__name__) + self.iter = state_dict["iteration"] + for key, value in state_dict.get("hooks", {}).items(): + for h in self._hooks: + try: + name = type(h).__qualname__ + except AttributeError: + continue + if name == key: + h.load_state_dict(value) + break + else: + logger.warning(f"Cannot find the hook '{key}', its state_dict is ignored.") + + +class SimpleTrainer(TrainerBase): + """ + A simple trainer for the most common type of task: + single-cost single-optimizer single-data-source iterative optimization, + optionally using data-parallelism. + It assumes that every step, you: + + 1. Compute the loss with a data from the data_loader. + 2. Compute the gradients with the above loss. + 3. Update the model with the optimizer. + + All other tasks during training (checkpointing, logging, evaluation, LR schedule) + are maintained by hooks, which can be registered by :meth:`TrainerBase.register_hooks`. + + If you want to do anything fancier than this, + either subclass TrainerBase and implement your own `run_step`, + or write your own training loop. + """ + + def __init__(self, model, data_loader, optimizer, gather_metric_period=1): + """ + Args: + model: a torch Module. Takes a data from data_loader and returns a + dict of losses. + data_loader: an iterable. Contains data to be used to call model. + optimizer: a torch optimizer. + gather_metric_period: an int. Every gather_metric_period iterations + the metrics are gathered from all the ranks to rank 0 and logged. + """ + super().__init__() + + """ + We set the model to training mode in the trainer. + However it's valid to train a model that's in eval mode. + If you want your model (or a submodule of it) to behave + like evaluation during training, you can overwrite its train() method. + """ + model.train() + + self.model = model + self.data_loader = data_loader + # to access the data loader iterator, call `self._data_loader_iter` + self._data_loader_iter_obj = None + self.optimizer = optimizer + self.gather_metric_period = gather_metric_period + + def run_step(self): + """ + Implement the standard training logic described above. + """ + assert self.model.training, "[SimpleTrainer] model was changed to eval mode!" + start = time.perf_counter() + """ + If you want to do something with the data, you can wrap the dataloader. + """ + data = next(self._data_loader_iter) + data_time = time.perf_counter() - start + + """ + If you want to do something with the losses, you can wrap the model. + """ + loss_dict = self.model(data) + if isinstance(loss_dict, torch.Tensor): + losses = loss_dict + loss_dict = {"total_loss": loss_dict} + else: + losses = sum(loss_dict.values()) + + """ + If you need to accumulate gradients or do something similar, you can + wrap the optimizer with your custom `zero_grad()` method. + """ + self.optimizer.zero_grad() + losses.backward() + + self.after_backward() + + self._write_metrics(loss_dict, data_time) + + """ + If you need gradient clipping/scaling or other processing, you can + wrap the optimizer with your custom `step()` method. But it is + suboptimal as explained in https://arxiv.org/abs/2006.15704 Sec 3.2.4 + """ + self.optimizer.step() + + @property + def _data_loader_iter(self): + # only create the data loader iterator when it is used + if self._data_loader_iter_obj is None: + self._data_loader_iter_obj = iter(self.data_loader) + return self._data_loader_iter_obj + + def reset_data_loader(self, data_loader_builder): + """ + Delete and replace the current data loader with a new one, which will be created + by calling `data_loader_builder` (without argument). + """ + del self.data_loader + data_loader = data_loader_builder() + self.data_loader = data_loader + self._data_loader_iter_obj = None + + def _write_metrics( + self, + loss_dict: Mapping[str, torch.Tensor], + data_time: float, + prefix: str = "", + ) -> None: + if (self.iter + 1) % self.gather_metric_period == 0: + SimpleTrainer.write_metrics(loss_dict, data_time, prefix) + + @staticmethod + def write_metrics( + loss_dict: Mapping[str, torch.Tensor], + data_time: float, + prefix: str = "", + ) -> None: + """ + Args: + loss_dict (dict): dict of scalar losses + data_time (float): time taken by the dataloader iteration + prefix (str): prefix for logging keys + """ + metrics_dict = {k: v.detach().cpu().item() for k, v in loss_dict.items()} + metrics_dict["data_time"] = data_time + + # Gather metrics among all workers for logging + # This assumes we do DDP-style training, which is currently the only + # supported method in detectron2. + all_metrics_dict = comm.gather(metrics_dict) + + if comm.is_main_process(): + storage = get_event_storage() + + # data_time among workers can have high variance. The actual latency + # caused by data_time is the maximum among workers. + data_time = np.max([x.pop("data_time") for x in all_metrics_dict]) + storage.put_scalar("data_time", data_time) + + # average the rest metrics + metrics_dict = { + k: np.mean([x[k] for x in all_metrics_dict]) for k in all_metrics_dict[0].keys() + } + total_losses_reduced = sum(metrics_dict.values()) + if not np.isfinite(total_losses_reduced): + raise FloatingPointError( + f"Loss became infinite or NaN at iteration={storage.iter}!\n" + f"loss_dict = {metrics_dict}" + ) + + storage.put_scalar("{}total_loss".format(prefix), total_losses_reduced) + if len(metrics_dict) > 1: + storage.put_scalars(**metrics_dict) + + def state_dict(self): + ret = super().state_dict() + ret["optimizer"] = self.optimizer.state_dict() + return ret + + def load_state_dict(self, state_dict): + super().load_state_dict(state_dict) + self.optimizer.load_state_dict(state_dict["optimizer"]) + + +class AMPTrainer(SimpleTrainer): + """ + Like :class:`SimpleTrainer`, but uses PyTorch's native automatic mixed precision + in the training loop. + """ + + def __init__( + self, + model, + data_loader, + optimizer, + gather_metric_period=1, + grad_scaler=None, + precision: torch.dtype = torch.float16, + log_grad_scaler: bool = False, + ): + """ + Args: + model, data_loader, optimizer, gather_metric_period: same as in :class:`SimpleTrainer`. + grad_scaler: torch GradScaler to automatically scale gradients. + precision: torch.dtype as the target precision to cast to in computations + """ + unsupported = "AMPTrainer does not support single-process multi-device training!" + if isinstance(model, DistributedDataParallel): + assert not (model.device_ids and len(model.device_ids) > 1), unsupported + assert not isinstance(model, DataParallel), unsupported + + super().__init__(model, data_loader, optimizer, gather_metric_period) + + if grad_scaler is None: + from torch.cuda.amp import GradScaler + + grad_scaler = GradScaler() + self.grad_scaler = grad_scaler + self.precision = precision + self.log_grad_scaler = log_grad_scaler + + def run_step(self): + """ + Implement the AMP training logic. + """ + assert self.model.training, "[AMPTrainer] model was changed to eval mode!" + assert torch.cuda.is_available(), "[AMPTrainer] CUDA is required for AMP training!" + from torch.cuda.amp import autocast + + start = time.perf_counter() + data = next(self._data_loader_iter) + data_time = time.perf_counter() - start + + with autocast(dtype=self.precision): + loss_dict = self.model(data) + if isinstance(loss_dict, torch.Tensor): + losses = loss_dict + loss_dict = {"total_loss": loss_dict} + else: + losses = sum(loss_dict.values()) + + self.optimizer.zero_grad() + self.grad_scaler.scale(losses).backward() + + if self.log_grad_scaler: + storage = get_event_storage() + storage.put_scalar("[metric]grad_scaler", self.grad_scaler.get_scale()) + + self.after_backward() + + self._write_metrics(loss_dict, data_time) + + self.grad_scaler.step(self.optimizer) + self.grad_scaler.update() + + def state_dict(self): + ret = super().state_dict() + ret["grad_scaler"] = self.grad_scaler.state_dict() + return ret + + def load_state_dict(self, state_dict): + super().load_state_dict(state_dict) + self.grad_scaler.load_state_dict(state_dict["grad_scaler"]) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/__init__.py new file mode 100644 index 00000000..d96609e8 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/__init__.py @@ -0,0 +1,12 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from .cityscapes_evaluation import CityscapesInstanceEvaluator, CityscapesSemSegEvaluator +from .coco_evaluation import COCOEvaluator +from .rotated_coco_evaluation import RotatedCOCOEvaluator +from .evaluator import DatasetEvaluator, DatasetEvaluators, inference_context, inference_on_dataset +from .lvis_evaluation import LVISEvaluator +from .panoptic_evaluation import COCOPanopticEvaluator +from .pascal_voc_evaluation import PascalVOCDetectionEvaluator +from .sem_seg_evaluation import SemSegEvaluator +from .testing import print_csv_format, verify_results + +__all__ = [k for k in globals().keys() if not k.startswith("_")] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/cityscapes_evaluation.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/cityscapes_evaluation.py new file mode 100644 index 00000000..f5be637d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/cityscapes_evaluation.py @@ -0,0 +1,197 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import glob +import logging +import numpy as np +import os +import tempfile +from collections import OrderedDict +import torch +from PIL import Image + +from annotator.oneformer.detectron2.data import MetadataCatalog +from annotator.oneformer.detectron2.utils import comm +from annotator.oneformer.detectron2.utils.file_io import PathManager + +from .evaluator import DatasetEvaluator + + +class CityscapesEvaluator(DatasetEvaluator): + """ + Base class for evaluation using cityscapes API. + """ + + def __init__(self, dataset_name): + """ + Args: + dataset_name (str): the name of the dataset. + It must have the following metadata associated with it: + "thing_classes", "gt_dir". + """ + self._metadata = MetadataCatalog.get(dataset_name) + self._cpu_device = torch.device("cpu") + self._logger = logging.getLogger(__name__) + + def reset(self): + self._working_dir = tempfile.TemporaryDirectory(prefix="cityscapes_eval_") + self._temp_dir = self._working_dir.name + # All workers will write to the same results directory + # TODO this does not work in distributed training + assert ( + comm.get_local_size() == comm.get_world_size() + ), "CityscapesEvaluator currently do not work with multiple machines." + self._temp_dir = comm.all_gather(self._temp_dir)[0] + if self._temp_dir != self._working_dir.name: + self._working_dir.cleanup() + self._logger.info( + "Writing cityscapes results to temporary directory {} ...".format(self._temp_dir) + ) + + +class CityscapesInstanceEvaluator(CityscapesEvaluator): + """ + Evaluate instance segmentation results on cityscapes dataset using cityscapes API. + + Note: + * It does not work in multi-machine distributed training. + * It contains a synchronization, therefore has to be used on all ranks. + * Only the main process runs evaluation. + """ + + def process(self, inputs, outputs): + from cityscapesscripts.helpers.labels import name2label + + for input, output in zip(inputs, outputs): + file_name = input["file_name"] + basename = os.path.splitext(os.path.basename(file_name))[0] + pred_txt = os.path.join(self._temp_dir, basename + "_pred.txt") + + if "instances" in output: + output = output["instances"].to(self._cpu_device) + num_instances = len(output) + with open(pred_txt, "w") as fout: + for i in range(num_instances): + pred_class = output.pred_classes[i] + classes = self._metadata.thing_classes[pred_class] + class_id = name2label[classes].id + score = output.scores[i] + mask = output.pred_masks[i].numpy().astype("uint8") + png_filename = os.path.join( + self._temp_dir, basename + "_{}_{}.png".format(i, classes) + ) + + Image.fromarray(mask * 255).save(png_filename) + fout.write( + "{} {} {}\n".format(os.path.basename(png_filename), class_id, score) + ) + else: + # Cityscapes requires a prediction file for every ground truth image. + with open(pred_txt, "w") as fout: + pass + + def evaluate(self): + """ + Returns: + dict: has a key "segm", whose value is a dict of "AP" and "AP50". + """ + comm.synchronize() + if comm.get_rank() > 0: + return + import cityscapesscripts.evaluation.evalInstanceLevelSemanticLabeling as cityscapes_eval + + self._logger.info("Evaluating results under {} ...".format(self._temp_dir)) + + # set some global states in cityscapes evaluation API, before evaluating + cityscapes_eval.args.predictionPath = os.path.abspath(self._temp_dir) + cityscapes_eval.args.predictionWalk = None + cityscapes_eval.args.JSONOutput = False + cityscapes_eval.args.colorized = False + cityscapes_eval.args.gtInstancesFile = os.path.join(self._temp_dir, "gtInstances.json") + + # These lines are adopted from + # https://github.com/mcordts/cityscapesScripts/blob/master/cityscapesscripts/evaluation/evalInstanceLevelSemanticLabeling.py # noqa + gt_dir = PathManager.get_local_path(self._metadata.gt_dir) + groundTruthImgList = glob.glob(os.path.join(gt_dir, "*", "*_gtFine_instanceIds.png")) + assert len( + groundTruthImgList + ), "Cannot find any ground truth images to use for evaluation. Searched for: {}".format( + cityscapes_eval.args.groundTruthSearch + ) + predictionImgList = [] + for gt in groundTruthImgList: + predictionImgList.append(cityscapes_eval.getPrediction(gt, cityscapes_eval.args)) + results = cityscapes_eval.evaluateImgLists( + predictionImgList, groundTruthImgList, cityscapes_eval.args + )["averages"] + + ret = OrderedDict() + ret["segm"] = {"AP": results["allAp"] * 100, "AP50": results["allAp50%"] * 100} + self._working_dir.cleanup() + return ret + + +class CityscapesSemSegEvaluator(CityscapesEvaluator): + """ + Evaluate semantic segmentation results on cityscapes dataset using cityscapes API. + + Note: + * It does not work in multi-machine distributed training. + * It contains a synchronization, therefore has to be used on all ranks. + * Only the main process runs evaluation. + """ + + def process(self, inputs, outputs): + from cityscapesscripts.helpers.labels import trainId2label + + for input, output in zip(inputs, outputs): + file_name = input["file_name"] + basename = os.path.splitext(os.path.basename(file_name))[0] + pred_filename = os.path.join(self._temp_dir, basename + "_pred.png") + + output = output["sem_seg"].argmax(dim=0).to(self._cpu_device).numpy() + pred = 255 * np.ones(output.shape, dtype=np.uint8) + for train_id, label in trainId2label.items(): + if label.ignoreInEval: + continue + pred[output == train_id] = label.id + Image.fromarray(pred).save(pred_filename) + + def evaluate(self): + comm.synchronize() + if comm.get_rank() > 0: + return + # Load the Cityscapes eval script *after* setting the required env var, + # since the script reads CITYSCAPES_DATASET into global variables at load time. + import cityscapesscripts.evaluation.evalPixelLevelSemanticLabeling as cityscapes_eval + + self._logger.info("Evaluating results under {} ...".format(self._temp_dir)) + + # set some global states in cityscapes evaluation API, before evaluating + cityscapes_eval.args.predictionPath = os.path.abspath(self._temp_dir) + cityscapes_eval.args.predictionWalk = None + cityscapes_eval.args.JSONOutput = False + cityscapes_eval.args.colorized = False + + # These lines are adopted from + # https://github.com/mcordts/cityscapesScripts/blob/master/cityscapesscripts/evaluation/evalPixelLevelSemanticLabeling.py # noqa + gt_dir = PathManager.get_local_path(self._metadata.gt_dir) + groundTruthImgList = glob.glob(os.path.join(gt_dir, "*", "*_gtFine_labelIds.png")) + assert len( + groundTruthImgList + ), "Cannot find any ground truth images to use for evaluation. Searched for: {}".format( + cityscapes_eval.args.groundTruthSearch + ) + predictionImgList = [] + for gt in groundTruthImgList: + predictionImgList.append(cityscapes_eval.getPrediction(cityscapes_eval.args, gt)) + results = cityscapes_eval.evaluateImgLists( + predictionImgList, groundTruthImgList, cityscapes_eval.args + ) + ret = OrderedDict() + ret["sem_seg"] = { + "IoU": 100.0 * results["averageScoreClasses"], + "iIoU": 100.0 * results["averageScoreInstClasses"], + "IoU_sup": 100.0 * results["averageScoreCategories"], + "iIoU_sup": 100.0 * results["averageScoreInstCategories"], + } + self._working_dir.cleanup() + return ret diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/coco_evaluation.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/coco_evaluation.py new file mode 100644 index 00000000..fdc41798 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/coco_evaluation.py @@ -0,0 +1,722 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import contextlib +import copy +import io +import itertools +import json +import logging +import numpy as np +import os +import pickle +from collections import OrderedDict +import annotator.oneformer.pycocotools.mask as mask_util +import torch +from annotator.oneformer.pycocotools.coco import COCO +from annotator.oneformer.pycocotools.cocoeval import COCOeval +from tabulate import tabulate + +import annotator.oneformer.detectron2.utils.comm as comm +from annotator.oneformer.detectron2.config import CfgNode +from annotator.oneformer.detectron2.data import MetadataCatalog +from annotator.oneformer.detectron2.data.datasets.coco import convert_to_coco_json +from annotator.oneformer.detectron2.structures import Boxes, BoxMode, pairwise_iou +from annotator.oneformer.detectron2.utils.file_io import PathManager +from annotator.oneformer.detectron2.utils.logger import create_small_table + +from .evaluator import DatasetEvaluator + +try: + from annotator.oneformer.detectron2.evaluation.fast_eval_api import COCOeval_opt +except ImportError: + COCOeval_opt = COCOeval + + +class COCOEvaluator(DatasetEvaluator): + """ + Evaluate AR for object proposals, AP for instance detection/segmentation, AP + for keypoint detection outputs using COCO's metrics. + See http://cocodataset.org/#detection-eval and + http://cocodataset.org/#keypoints-eval to understand its metrics. + The metrics range from 0 to 100 (instead of 0 to 1), where a -1 or NaN means + the metric cannot be computed (e.g. due to no predictions made). + + In addition to COCO, this evaluator is able to support any bounding box detection, + instance segmentation, or keypoint detection dataset. + """ + + def __init__( + self, + dataset_name, + tasks=None, + distributed=True, + output_dir=None, + *, + max_dets_per_image=None, + use_fast_impl=True, + kpt_oks_sigmas=(), + allow_cached_coco=True, + ): + """ + Args: + dataset_name (str): name of the dataset to be evaluated. + It must have either the following corresponding metadata: + + "json_file": the path to the COCO format annotation + + Or it must be in detectron2's standard dataset format + so it can be converted to COCO format automatically. + tasks (tuple[str]): tasks that can be evaluated under the given + configuration. A task is one of "bbox", "segm", "keypoints". + By default, will infer this automatically from predictions. + distributed (True): if True, will collect results from all ranks and run evaluation + in the main process. + Otherwise, will only evaluate the results in the current process. + output_dir (str): optional, an output directory to dump all + results predicted on the dataset. The dump contains two files: + + 1. "instances_predictions.pth" a file that can be loaded with `torch.load` and + contains all the results in the format they are produced by the model. + 2. "coco_instances_results.json" a json file in COCO's result format. + max_dets_per_image (int): limit on the maximum number of detections per image. + By default in COCO, this limit is to 100, but this can be customized + to be greater, as is needed in evaluation metrics AP fixed and AP pool + (see https://arxiv.org/pdf/2102.01066.pdf) + This doesn't affect keypoint evaluation. + use_fast_impl (bool): use a fast but **unofficial** implementation to compute AP. + Although the results should be very close to the official implementation in COCO + API, it is still recommended to compute results with the official API for use in + papers. The faster implementation also uses more RAM. + kpt_oks_sigmas (list[float]): The sigmas used to calculate keypoint OKS. + See http://cocodataset.org/#keypoints-eval + When empty, it will use the defaults in COCO. + Otherwise it should be the same length as ROI_KEYPOINT_HEAD.NUM_KEYPOINTS. + allow_cached_coco (bool): Whether to use cached coco json from previous validation + runs. You should set this to False if you need to use different validation data. + Defaults to True. + """ + self._logger = logging.getLogger(__name__) + self._distributed = distributed + self._output_dir = output_dir + + if use_fast_impl and (COCOeval_opt is COCOeval): + self._logger.info("Fast COCO eval is not built. Falling back to official COCO eval.") + use_fast_impl = False + self._use_fast_impl = use_fast_impl + + # COCOeval requires the limit on the number of detections per image (maxDets) to be a list + # with at least 3 elements. The default maxDets in COCOeval is [1, 10, 100], in which the + # 3rd element (100) is used as the limit on the number of detections per image when + # evaluating AP. COCOEvaluator expects an integer for max_dets_per_image, so for COCOeval, + # we reformat max_dets_per_image into [1, 10, max_dets_per_image], based on the defaults. + if max_dets_per_image is None: + max_dets_per_image = [1, 10, 100] + else: + max_dets_per_image = [1, 10, max_dets_per_image] + self._max_dets_per_image = max_dets_per_image + + if tasks is not None and isinstance(tasks, CfgNode): + kpt_oks_sigmas = ( + tasks.TEST.KEYPOINT_OKS_SIGMAS if not kpt_oks_sigmas else kpt_oks_sigmas + ) + self._logger.warn( + "COCO Evaluator instantiated using config, this is deprecated behavior." + " Please pass in explicit arguments instead." + ) + self._tasks = None # Infering it from predictions should be better + else: + self._tasks = tasks + + self._cpu_device = torch.device("cpu") + + self._metadata = MetadataCatalog.get(dataset_name) + if not hasattr(self._metadata, "json_file"): + if output_dir is None: + raise ValueError( + "output_dir must be provided to COCOEvaluator " + "for datasets not in COCO format." + ) + self._logger.info(f"Trying to convert '{dataset_name}' to COCO format ...") + + cache_path = os.path.join(output_dir, f"{dataset_name}_coco_format.json") + self._metadata.json_file = cache_path + convert_to_coco_json(dataset_name, cache_path, allow_cached=allow_cached_coco) + + json_file = PathManager.get_local_path(self._metadata.json_file) + with contextlib.redirect_stdout(io.StringIO()): + self._coco_api = COCO(json_file) + + # Test set json files do not contain annotations (evaluation must be + # performed using the COCO evaluation server). + self._do_evaluation = "annotations" in self._coco_api.dataset + if self._do_evaluation: + self._kpt_oks_sigmas = kpt_oks_sigmas + + def reset(self): + self._predictions = [] + + def process(self, inputs, outputs): + """ + Args: + inputs: the inputs to a COCO model (e.g., GeneralizedRCNN). + It is a list of dict. Each dict corresponds to an image and + contains keys like "height", "width", "file_name", "image_id". + outputs: the outputs of a COCO model. It is a list of dicts with key + "instances" that contains :class:`Instances`. + """ + for input, output in zip(inputs, outputs): + prediction = {"image_id": input["image_id"]} + + if "instances" in output: + instances = output["instances"].to(self._cpu_device) + prediction["instances"] = instances_to_coco_json(instances, input["image_id"]) + if "proposals" in output: + prediction["proposals"] = output["proposals"].to(self._cpu_device) + if len(prediction) > 1: + self._predictions.append(prediction) + + def evaluate(self, img_ids=None): + """ + Args: + img_ids: a list of image IDs to evaluate on. Default to None for the whole dataset + """ + if self._distributed: + comm.synchronize() + predictions = comm.gather(self._predictions, dst=0) + predictions = list(itertools.chain(*predictions)) + + if not comm.is_main_process(): + return {} + else: + predictions = self._predictions + + if len(predictions) == 0: + self._logger.warning("[COCOEvaluator] Did not receive valid predictions.") + return {} + + if self._output_dir: + PathManager.mkdirs(self._output_dir) + file_path = os.path.join(self._output_dir, "instances_predictions.pth") + with PathManager.open(file_path, "wb") as f: + torch.save(predictions, f) + + self._results = OrderedDict() + if "proposals" in predictions[0]: + self._eval_box_proposals(predictions) + if "instances" in predictions[0]: + self._eval_predictions(predictions, img_ids=img_ids) + # Copy so the caller can do whatever with results + return copy.deepcopy(self._results) + + def _tasks_from_predictions(self, predictions): + """ + Get COCO API "tasks" (i.e. iou_type) from COCO-format predictions. + """ + tasks = {"bbox"} + for pred in predictions: + if "segmentation" in pred: + tasks.add("segm") + if "keypoints" in pred: + tasks.add("keypoints") + return sorted(tasks) + + def _eval_predictions(self, predictions, img_ids=None): + """ + Evaluate predictions. Fill self._results with the metrics of the tasks. + """ + self._logger.info("Preparing results for COCO format ...") + coco_results = list(itertools.chain(*[x["instances"] for x in predictions])) + tasks = self._tasks or self._tasks_from_predictions(coco_results) + + # unmap the category ids for COCO + if hasattr(self._metadata, "thing_dataset_id_to_contiguous_id"): + dataset_id_to_contiguous_id = self._metadata.thing_dataset_id_to_contiguous_id + all_contiguous_ids = list(dataset_id_to_contiguous_id.values()) + num_classes = len(all_contiguous_ids) + assert min(all_contiguous_ids) == 0 and max(all_contiguous_ids) == num_classes - 1 + + reverse_id_mapping = {v: k for k, v in dataset_id_to_contiguous_id.items()} + for result in coco_results: + category_id = result["category_id"] + assert category_id < num_classes, ( + f"A prediction has class={category_id}, " + f"but the dataset only has {num_classes} classes and " + f"predicted class id should be in [0, {num_classes - 1}]." + ) + result["category_id"] = reverse_id_mapping[category_id] + + if self._output_dir: + file_path = os.path.join(self._output_dir, "coco_instances_results.json") + self._logger.info("Saving results to {}".format(file_path)) + with PathManager.open(file_path, "w") as f: + f.write(json.dumps(coco_results)) + f.flush() + + if not self._do_evaluation: + self._logger.info("Annotations are not available for evaluation.") + return + + self._logger.info( + "Evaluating predictions with {} COCO API...".format( + "unofficial" if self._use_fast_impl else "official" + ) + ) + for task in sorted(tasks): + assert task in {"bbox", "segm", "keypoints"}, f"Got unknown task: {task}!" + coco_eval = ( + _evaluate_predictions_on_coco( + self._coco_api, + coco_results, + task, + kpt_oks_sigmas=self._kpt_oks_sigmas, + cocoeval_fn=COCOeval_opt if self._use_fast_impl else COCOeval, + img_ids=img_ids, + max_dets_per_image=self._max_dets_per_image, + ) + if len(coco_results) > 0 + else None # cocoapi does not handle empty results very well + ) + + res = self._derive_coco_results( + coco_eval, task, class_names=self._metadata.get("thing_classes") + ) + self._results[task] = res + + def _eval_box_proposals(self, predictions): + """ + Evaluate the box proposals in predictions. + Fill self._results with the metrics for "box_proposals" task. + """ + if self._output_dir: + # Saving generated box proposals to file. + # Predicted box_proposals are in XYXY_ABS mode. + bbox_mode = BoxMode.XYXY_ABS.value + ids, boxes, objectness_logits = [], [], [] + for prediction in predictions: + ids.append(prediction["image_id"]) + boxes.append(prediction["proposals"].proposal_boxes.tensor.numpy()) + objectness_logits.append(prediction["proposals"].objectness_logits.numpy()) + + proposal_data = { + "boxes": boxes, + "objectness_logits": objectness_logits, + "ids": ids, + "bbox_mode": bbox_mode, + } + with PathManager.open(os.path.join(self._output_dir, "box_proposals.pkl"), "wb") as f: + pickle.dump(proposal_data, f) + + if not self._do_evaluation: + self._logger.info("Annotations are not available for evaluation.") + return + + self._logger.info("Evaluating bbox proposals ...") + res = {} + areas = {"all": "", "small": "s", "medium": "m", "large": "l"} + for limit in [100, 1000]: + for area, suffix in areas.items(): + stats = _evaluate_box_proposals(predictions, self._coco_api, area=area, limit=limit) + key = "AR{}@{:d}".format(suffix, limit) + res[key] = float(stats["ar"].item() * 100) + self._logger.info("Proposal metrics: \n" + create_small_table(res)) + self._results["box_proposals"] = res + + def _derive_coco_results(self, coco_eval, iou_type, class_names=None): + """ + Derive the desired score numbers from summarized COCOeval. + + Args: + coco_eval (None or COCOEval): None represents no predictions from model. + iou_type (str): + class_names (None or list[str]): if provided, will use it to predict + per-category AP. + + Returns: + a dict of {metric name: score} + """ + + metrics = { + "bbox": ["AP", "AP50", "AP75", "APs", "APm", "APl"], + "segm": ["AP", "AP50", "AP75", "APs", "APm", "APl"], + "keypoints": ["AP", "AP50", "AP75", "APm", "APl"], + }[iou_type] + + if coco_eval is None: + self._logger.warn("No predictions from the model!") + return {metric: float("nan") for metric in metrics} + + # the standard metrics + results = { + metric: float(coco_eval.stats[idx] * 100 if coco_eval.stats[idx] >= 0 else "nan") + for idx, metric in enumerate(metrics) + } + self._logger.info( + "Evaluation results for {}: \n".format(iou_type) + create_small_table(results) + ) + if not np.isfinite(sum(results.values())): + self._logger.info("Some metrics cannot be computed and is shown as NaN.") + + if class_names is None or len(class_names) <= 1: + return results + # Compute per-category AP + # from https://github.com/facebookresearch/Detectron/blob/a6a835f5b8208c45d0dce217ce9bbda915f44df7/detectron/datasets/json_dataset_evaluator.py#L222-L252 # noqa + precisions = coco_eval.eval["precision"] + # precision has dims (iou, recall, cls, area range, max dets) + assert len(class_names) == precisions.shape[2] + + results_per_category = [] + for idx, name in enumerate(class_names): + # area range index 0: all area ranges + # max dets index -1: typically 100 per image + precision = precisions[:, :, idx, 0, -1] + precision = precision[precision > -1] + ap = np.mean(precision) if precision.size else float("nan") + results_per_category.append(("{}".format(name), float(ap * 100))) + + # tabulate it + N_COLS = min(6, len(results_per_category) * 2) + results_flatten = list(itertools.chain(*results_per_category)) + results_2d = itertools.zip_longest(*[results_flatten[i::N_COLS] for i in range(N_COLS)]) + table = tabulate( + results_2d, + tablefmt="pipe", + floatfmt=".3f", + headers=["category", "AP"] * (N_COLS // 2), + numalign="left", + ) + self._logger.info("Per-category {} AP: \n".format(iou_type) + table) + + results.update({"AP-" + name: ap for name, ap in results_per_category}) + return results + + +def instances_to_coco_json(instances, img_id): + """ + Dump an "Instances" object to a COCO-format json that's used for evaluation. + + Args: + instances (Instances): + img_id (int): the image id + + Returns: + list[dict]: list of json annotations in COCO format. + """ + num_instance = len(instances) + if num_instance == 0: + return [] + + boxes = instances.pred_boxes.tensor.numpy() + boxes = BoxMode.convert(boxes, BoxMode.XYXY_ABS, BoxMode.XYWH_ABS) + boxes = boxes.tolist() + scores = instances.scores.tolist() + classes = instances.pred_classes.tolist() + + has_mask = instances.has("pred_masks") + if has_mask: + # use RLE to encode the masks, because they are too large and takes memory + # since this evaluator stores outputs of the entire dataset + rles = [ + mask_util.encode(np.array(mask[:, :, None], order="F", dtype="uint8"))[0] + for mask in instances.pred_masks + ] + for rle in rles: + # "counts" is an array encoded by mask_util as a byte-stream. Python3's + # json writer which always produces strings cannot serialize a bytestream + # unless you decode it. Thankfully, utf-8 works out (which is also what + # the annotator.oneformer.pycocotools/_mask.pyx does). + rle["counts"] = rle["counts"].decode("utf-8") + + has_keypoints = instances.has("pred_keypoints") + if has_keypoints: + keypoints = instances.pred_keypoints + + results = [] + for k in range(num_instance): + result = { + "image_id": img_id, + "category_id": classes[k], + "bbox": boxes[k], + "score": scores[k], + } + if has_mask: + result["segmentation"] = rles[k] + if has_keypoints: + # In COCO annotations, + # keypoints coordinates are pixel indices. + # However our predictions are floating point coordinates. + # Therefore we subtract 0.5 to be consistent with the annotation format. + # This is the inverse of data loading logic in `datasets/coco.py`. + keypoints[k][:, :2] -= 0.5 + result["keypoints"] = keypoints[k].flatten().tolist() + results.append(result) + return results + + +# inspired from Detectron: +# https://github.com/facebookresearch/Detectron/blob/a6a835f5b8208c45d0dce217ce9bbda915f44df7/detectron/datasets/json_dataset_evaluator.py#L255 # noqa +def _evaluate_box_proposals(dataset_predictions, coco_api, thresholds=None, area="all", limit=None): + """ + Evaluate detection proposal recall metrics. This function is a much + faster alternative to the official COCO API recall evaluation code. However, + it produces slightly different results. + """ + # Record max overlap value for each gt box + # Return vector of overlap values + areas = { + "all": 0, + "small": 1, + "medium": 2, + "large": 3, + "96-128": 4, + "128-256": 5, + "256-512": 6, + "512-inf": 7, + } + area_ranges = [ + [0**2, 1e5**2], # all + [0**2, 32**2], # small + [32**2, 96**2], # medium + [96**2, 1e5**2], # large + [96**2, 128**2], # 96-128 + [128**2, 256**2], # 128-256 + [256**2, 512**2], # 256-512 + [512**2, 1e5**2], + ] # 512-inf + assert area in areas, "Unknown area range: {}".format(area) + area_range = area_ranges[areas[area]] + gt_overlaps = [] + num_pos = 0 + + for prediction_dict in dataset_predictions: + predictions = prediction_dict["proposals"] + + # sort predictions in descending order + # TODO maybe remove this and make it explicit in the documentation + inds = predictions.objectness_logits.sort(descending=True)[1] + predictions = predictions[inds] + + ann_ids = coco_api.getAnnIds(imgIds=prediction_dict["image_id"]) + anno = coco_api.loadAnns(ann_ids) + gt_boxes = [ + BoxMode.convert(obj["bbox"], BoxMode.XYWH_ABS, BoxMode.XYXY_ABS) + for obj in anno + if obj["iscrowd"] == 0 + ] + gt_boxes = torch.as_tensor(gt_boxes).reshape(-1, 4) # guard against no boxes + gt_boxes = Boxes(gt_boxes) + gt_areas = torch.as_tensor([obj["area"] for obj in anno if obj["iscrowd"] == 0]) + + if len(gt_boxes) == 0 or len(predictions) == 0: + continue + + valid_gt_inds = (gt_areas >= area_range[0]) & (gt_areas <= area_range[1]) + gt_boxes = gt_boxes[valid_gt_inds] + + num_pos += len(gt_boxes) + + if len(gt_boxes) == 0: + continue + + if limit is not None and len(predictions) > limit: + predictions = predictions[:limit] + + overlaps = pairwise_iou(predictions.proposal_boxes, gt_boxes) + + _gt_overlaps = torch.zeros(len(gt_boxes)) + for j in range(min(len(predictions), len(gt_boxes))): + # find which proposal box maximally covers each gt box + # and get the iou amount of coverage for each gt box + max_overlaps, argmax_overlaps = overlaps.max(dim=0) + + # find which gt box is 'best' covered (i.e. 'best' = most iou) + gt_ovr, gt_ind = max_overlaps.max(dim=0) + assert gt_ovr >= 0 + # find the proposal box that covers the best covered gt box + box_ind = argmax_overlaps[gt_ind] + # record the iou coverage of this gt box + _gt_overlaps[j] = overlaps[box_ind, gt_ind] + assert _gt_overlaps[j] == gt_ovr + # mark the proposal box and the gt box as used + overlaps[box_ind, :] = -1 + overlaps[:, gt_ind] = -1 + + # append recorded iou coverage level + gt_overlaps.append(_gt_overlaps) + gt_overlaps = ( + torch.cat(gt_overlaps, dim=0) if len(gt_overlaps) else torch.zeros(0, dtype=torch.float32) + ) + gt_overlaps, _ = torch.sort(gt_overlaps) + + if thresholds is None: + step = 0.05 + thresholds = torch.arange(0.5, 0.95 + 1e-5, step, dtype=torch.float32) + recalls = torch.zeros_like(thresholds) + # compute recall for each iou threshold + for i, t in enumerate(thresholds): + recalls[i] = (gt_overlaps >= t).float().sum() / float(num_pos) + # ar = 2 * np.trapz(recalls, thresholds) + ar = recalls.mean() + return { + "ar": ar, + "recalls": recalls, + "thresholds": thresholds, + "gt_overlaps": gt_overlaps, + "num_pos": num_pos, + } + + +def _evaluate_predictions_on_coco( + coco_gt, + coco_results, + iou_type, + kpt_oks_sigmas=None, + cocoeval_fn=COCOeval_opt, + img_ids=None, + max_dets_per_image=None, +): + """ + Evaluate the coco results using COCOEval API. + """ + assert len(coco_results) > 0 + + if iou_type == "segm": + coco_results = copy.deepcopy(coco_results) + # When evaluating mask AP, if the results contain bbox, cocoapi will + # use the box area as the area of the instance, instead of the mask area. + # This leads to a different definition of small/medium/large. + # We remove the bbox field to let mask AP use mask area. + for c in coco_results: + c.pop("bbox", None) + + coco_dt = coco_gt.loadRes(coco_results) + coco_eval = cocoeval_fn(coco_gt, coco_dt, iou_type) + # For COCO, the default max_dets_per_image is [1, 10, 100]. + if max_dets_per_image is None: + max_dets_per_image = [1, 10, 100] # Default from COCOEval + else: + assert ( + len(max_dets_per_image) >= 3 + ), "COCOeval requires maxDets (and max_dets_per_image) to have length at least 3" + # In the case that user supplies a custom input for max_dets_per_image, + # apply COCOevalMaxDets to evaluate AP with the custom input. + if max_dets_per_image[2] != 100: + coco_eval = COCOevalMaxDets(coco_gt, coco_dt, iou_type) + if iou_type != "keypoints": + coco_eval.params.maxDets = max_dets_per_image + + if img_ids is not None: + coco_eval.params.imgIds = img_ids + + if iou_type == "keypoints": + # Use the COCO default keypoint OKS sigmas unless overrides are specified + if kpt_oks_sigmas: + assert hasattr(coco_eval.params, "kpt_oks_sigmas"), "annotator.oneformer.pycocotools is too old!" + coco_eval.params.kpt_oks_sigmas = np.array(kpt_oks_sigmas) + # COCOAPI requires every detection and every gt to have keypoints, so + # we just take the first entry from both + num_keypoints_dt = len(coco_results[0]["keypoints"]) // 3 + num_keypoints_gt = len(next(iter(coco_gt.anns.values()))["keypoints"]) // 3 + num_keypoints_oks = len(coco_eval.params.kpt_oks_sigmas) + assert num_keypoints_oks == num_keypoints_dt == num_keypoints_gt, ( + f"[COCOEvaluator] Prediction contain {num_keypoints_dt} keypoints. " + f"Ground truth contains {num_keypoints_gt} keypoints. " + f"The length of cfg.TEST.KEYPOINT_OKS_SIGMAS is {num_keypoints_oks}. " + "They have to agree with each other. For meaning of OKS, please refer to " + "http://cocodataset.org/#keypoints-eval." + ) + + coco_eval.evaluate() + coco_eval.accumulate() + coco_eval.summarize() + + return coco_eval + + +class COCOevalMaxDets(COCOeval): + """ + Modified version of COCOeval for evaluating AP with a custom + maxDets (by default for COCO, maxDets is 100) + """ + + def summarize(self): + """ + Compute and display summary metrics for evaluation results given + a custom value for max_dets_per_image + """ + + def _summarize(ap=1, iouThr=None, areaRng="all", maxDets=100): + p = self.params + iStr = " {:<18} {} @[ IoU={:<9} | area={:>6s} | maxDets={:>3d} ] = {:0.3f}" + titleStr = "Average Precision" if ap == 1 else "Average Recall" + typeStr = "(AP)" if ap == 1 else "(AR)" + iouStr = ( + "{:0.2f}:{:0.2f}".format(p.iouThrs[0], p.iouThrs[-1]) + if iouThr is None + else "{:0.2f}".format(iouThr) + ) + + aind = [i for i, aRng in enumerate(p.areaRngLbl) if aRng == areaRng] + mind = [i for i, mDet in enumerate(p.maxDets) if mDet == maxDets] + if ap == 1: + # dimension of precision: [TxRxKxAxM] + s = self.eval["precision"] + # IoU + if iouThr is not None: + t = np.where(iouThr == p.iouThrs)[0] + s = s[t] + s = s[:, :, :, aind, mind] + else: + # dimension of recall: [TxKxAxM] + s = self.eval["recall"] + if iouThr is not None: + t = np.where(iouThr == p.iouThrs)[0] + s = s[t] + s = s[:, :, aind, mind] + if len(s[s > -1]) == 0: + mean_s = -1 + else: + mean_s = np.mean(s[s > -1]) + print(iStr.format(titleStr, typeStr, iouStr, areaRng, maxDets, mean_s)) + return mean_s + + def _summarizeDets(): + stats = np.zeros((12,)) + # Evaluate AP using the custom limit on maximum detections per image + stats[0] = _summarize(1, maxDets=self.params.maxDets[2]) + stats[1] = _summarize(1, iouThr=0.5, maxDets=self.params.maxDets[2]) + stats[2] = _summarize(1, iouThr=0.75, maxDets=self.params.maxDets[2]) + stats[3] = _summarize(1, areaRng="small", maxDets=self.params.maxDets[2]) + stats[4] = _summarize(1, areaRng="medium", maxDets=self.params.maxDets[2]) + stats[5] = _summarize(1, areaRng="large", maxDets=self.params.maxDets[2]) + stats[6] = _summarize(0, maxDets=self.params.maxDets[0]) + stats[7] = _summarize(0, maxDets=self.params.maxDets[1]) + stats[8] = _summarize(0, maxDets=self.params.maxDets[2]) + stats[9] = _summarize(0, areaRng="small", maxDets=self.params.maxDets[2]) + stats[10] = _summarize(0, areaRng="medium", maxDets=self.params.maxDets[2]) + stats[11] = _summarize(0, areaRng="large", maxDets=self.params.maxDets[2]) + return stats + + def _summarizeKps(): + stats = np.zeros((10,)) + stats[0] = _summarize(1, maxDets=20) + stats[1] = _summarize(1, maxDets=20, iouThr=0.5) + stats[2] = _summarize(1, maxDets=20, iouThr=0.75) + stats[3] = _summarize(1, maxDets=20, areaRng="medium") + stats[4] = _summarize(1, maxDets=20, areaRng="large") + stats[5] = _summarize(0, maxDets=20) + stats[6] = _summarize(0, maxDets=20, iouThr=0.5) + stats[7] = _summarize(0, maxDets=20, iouThr=0.75) + stats[8] = _summarize(0, maxDets=20, areaRng="medium") + stats[9] = _summarize(0, maxDets=20, areaRng="large") + return stats + + if not self.eval: + raise Exception("Please run accumulate() first") + iouType = self.params.iouType + if iouType == "segm" or iouType == "bbox": + summarize = _summarizeDets + elif iouType == "keypoints": + summarize = _summarizeKps + self.stats = summarize() + + def __str__(self): + self.summarize() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/evaluator.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/evaluator.py new file mode 100644 index 00000000..9cddc296 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/evaluator.py @@ -0,0 +1,224 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import datetime +import logging +import time +from collections import OrderedDict, abc +from contextlib import ExitStack, contextmanager +from typing import List, Union +import torch +from torch import nn + +from annotator.oneformer.detectron2.utils.comm import get_world_size, is_main_process +from annotator.oneformer.detectron2.utils.logger import log_every_n_seconds + + +class DatasetEvaluator: + """ + Base class for a dataset evaluator. + + The function :func:`inference_on_dataset` runs the model over + all samples in the dataset, and have a DatasetEvaluator to process the inputs/outputs. + + This class will accumulate information of the inputs/outputs (by :meth:`process`), + and produce evaluation results in the end (by :meth:`evaluate`). + """ + + def reset(self): + """ + Preparation for a new round of evaluation. + Should be called before starting a round of evaluation. + """ + pass + + def process(self, inputs, outputs): + """ + Process the pair of inputs and outputs. + If they contain batches, the pairs can be consumed one-by-one using `zip`: + + .. code-block:: python + + for input_, output in zip(inputs, outputs): + # do evaluation on single input/output pair + ... + + Args: + inputs (list): the inputs that's used to call the model. + outputs (list): the return value of `model(inputs)` + """ + pass + + def evaluate(self): + """ + Evaluate/summarize the performance, after processing all input/output pairs. + + Returns: + dict: + A new evaluator class can return a dict of arbitrary format + as long as the user can process the results. + In our train_net.py, we expect the following format: + + * key: the name of the task (e.g., bbox) + * value: a dict of {metric name: score}, e.g.: {"AP50": 80} + """ + pass + + +class DatasetEvaluators(DatasetEvaluator): + """ + Wrapper class to combine multiple :class:`DatasetEvaluator` instances. + + This class dispatches every evaluation call to + all of its :class:`DatasetEvaluator`. + """ + + def __init__(self, evaluators): + """ + Args: + evaluators (list): the evaluators to combine. + """ + super().__init__() + self._evaluators = evaluators + + def reset(self): + for evaluator in self._evaluators: + evaluator.reset() + + def process(self, inputs, outputs): + for evaluator in self._evaluators: + evaluator.process(inputs, outputs) + + def evaluate(self): + results = OrderedDict() + for evaluator in self._evaluators: + result = evaluator.evaluate() + if is_main_process() and result is not None: + for k, v in result.items(): + assert ( + k not in results + ), "Different evaluators produce results with the same key {}".format(k) + results[k] = v + return results + + +def inference_on_dataset( + model, data_loader, evaluator: Union[DatasetEvaluator, List[DatasetEvaluator], None] +): + """ + Run model on the data_loader and evaluate the metrics with evaluator. + Also benchmark the inference speed of `model.__call__` accurately. + The model will be used in eval mode. + + Args: + model (callable): a callable which takes an object from + `data_loader` and returns some outputs. + + If it's an nn.Module, it will be temporarily set to `eval` mode. + If you wish to evaluate a model in `training` mode instead, you can + wrap the given model and override its behavior of `.eval()` and `.train()`. + data_loader: an iterable object with a length. + The elements it generates will be the inputs to the model. + evaluator: the evaluator(s) to run. Use `None` if you only want to benchmark, + but don't want to do any evaluation. + + Returns: + The return value of `evaluator.evaluate()` + """ + num_devices = get_world_size() + logger = logging.getLogger(__name__) + logger.info("Start inference on {} batches".format(len(data_loader))) + + total = len(data_loader) # inference data loader must have a fixed length + if evaluator is None: + # create a no-op evaluator + evaluator = DatasetEvaluators([]) + if isinstance(evaluator, abc.MutableSequence): + evaluator = DatasetEvaluators(evaluator) + evaluator.reset() + + num_warmup = min(5, total - 1) + start_time = time.perf_counter() + total_data_time = 0 + total_compute_time = 0 + total_eval_time = 0 + with ExitStack() as stack: + if isinstance(model, nn.Module): + stack.enter_context(inference_context(model)) + stack.enter_context(torch.no_grad()) + + start_data_time = time.perf_counter() + for idx, inputs in enumerate(data_loader): + total_data_time += time.perf_counter() - start_data_time + if idx == num_warmup: + start_time = time.perf_counter() + total_data_time = 0 + total_compute_time = 0 + total_eval_time = 0 + + start_compute_time = time.perf_counter() + outputs = model(inputs) + if torch.cuda.is_available(): + torch.cuda.synchronize() + total_compute_time += time.perf_counter() - start_compute_time + + start_eval_time = time.perf_counter() + evaluator.process(inputs, outputs) + total_eval_time += time.perf_counter() - start_eval_time + + iters_after_start = idx + 1 - num_warmup * int(idx >= num_warmup) + data_seconds_per_iter = total_data_time / iters_after_start + compute_seconds_per_iter = total_compute_time / iters_after_start + eval_seconds_per_iter = total_eval_time / iters_after_start + total_seconds_per_iter = (time.perf_counter() - start_time) / iters_after_start + if idx >= num_warmup * 2 or compute_seconds_per_iter > 5: + eta = datetime.timedelta(seconds=int(total_seconds_per_iter * (total - idx - 1))) + log_every_n_seconds( + logging.INFO, + ( + f"Inference done {idx + 1}/{total}. " + f"Dataloading: {data_seconds_per_iter:.4f} s/iter. " + f"Inference: {compute_seconds_per_iter:.4f} s/iter. " + f"Eval: {eval_seconds_per_iter:.4f} s/iter. " + f"Total: {total_seconds_per_iter:.4f} s/iter. " + f"ETA={eta}" + ), + n=5, + ) + start_data_time = time.perf_counter() + + # Measure the time only for this worker (before the synchronization barrier) + total_time = time.perf_counter() - start_time + total_time_str = str(datetime.timedelta(seconds=total_time)) + # NOTE this format is parsed by grep + logger.info( + "Total inference time: {} ({:.6f} s / iter per device, on {} devices)".format( + total_time_str, total_time / (total - num_warmup), num_devices + ) + ) + total_compute_time_str = str(datetime.timedelta(seconds=int(total_compute_time))) + logger.info( + "Total inference pure compute time: {} ({:.6f} s / iter per device, on {} devices)".format( + total_compute_time_str, total_compute_time / (total - num_warmup), num_devices + ) + ) + + results = evaluator.evaluate() + # An evaluator may return None when not in main process. + # Replace it by an empty dict instead to make it easier for downstream code to handle + if results is None: + results = {} + return results + + +@contextmanager +def inference_context(model): + """ + A context where the model is temporarily changed to eval mode, + and restored to previous mode afterwards. + + Args: + model: a torch Module + """ + training_mode = model.training + model.eval() + yield + model.train(training_mode) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/fast_eval_api.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/fast_eval_api.py new file mode 100644 index 00000000..ad1a8f82 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/fast_eval_api.py @@ -0,0 +1,121 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import copy +import logging +import numpy as np +import time +from annotator.oneformer.pycocotools.cocoeval import COCOeval + +from annotator.oneformer.detectron2 import _C + +logger = logging.getLogger(__name__) + + +class COCOeval_opt(COCOeval): + """ + This is a slightly modified version of the original COCO API, where the functions evaluateImg() + and accumulate() are implemented in C++ to speedup evaluation + """ + + def evaluate(self): + """ + Run per image evaluation on given images and store results in self.evalImgs_cpp, a + datastructure that isn't readable from Python but is used by a c++ implementation of + accumulate(). Unlike the original COCO PythonAPI, we don't populate the datastructure + self.evalImgs because this datastructure is a computational bottleneck. + :return: None + """ + tic = time.time() + + p = self.params + # add backward compatibility if useSegm is specified in params + if p.useSegm is not None: + p.iouType = "segm" if p.useSegm == 1 else "bbox" + logger.info("Evaluate annotation type *{}*".format(p.iouType)) + p.imgIds = list(np.unique(p.imgIds)) + if p.useCats: + p.catIds = list(np.unique(p.catIds)) + p.maxDets = sorted(p.maxDets) + self.params = p + + self._prepare() # bottleneck + + # loop through images, area range, max detection number + catIds = p.catIds if p.useCats else [-1] + + if p.iouType == "segm" or p.iouType == "bbox": + computeIoU = self.computeIoU + elif p.iouType == "keypoints": + computeIoU = self.computeOks + self.ious = { + (imgId, catId): computeIoU(imgId, catId) for imgId in p.imgIds for catId in catIds + } # bottleneck + + maxDet = p.maxDets[-1] + + # <<<< Beginning of code differences with original COCO API + def convert_instances_to_cpp(instances, is_det=False): + # Convert annotations for a list of instances in an image to a format that's fast + # to access in C++ + instances_cpp = [] + for instance in instances: + instance_cpp = _C.InstanceAnnotation( + int(instance["id"]), + instance["score"] if is_det else instance.get("score", 0.0), + instance["area"], + bool(instance.get("iscrowd", 0)), + bool(instance.get("ignore", 0)), + ) + instances_cpp.append(instance_cpp) + return instances_cpp + + # Convert GT annotations, detections, and IOUs to a format that's fast to access in C++ + ground_truth_instances = [ + [convert_instances_to_cpp(self._gts[imgId, catId]) for catId in p.catIds] + for imgId in p.imgIds + ] + detected_instances = [ + [convert_instances_to_cpp(self._dts[imgId, catId], is_det=True) for catId in p.catIds] + for imgId in p.imgIds + ] + ious = [[self.ious[imgId, catId] for catId in catIds] for imgId in p.imgIds] + + if not p.useCats: + # For each image, flatten per-category lists into a single list + ground_truth_instances = [[[o for c in i for o in c]] for i in ground_truth_instances] + detected_instances = [[[o for c in i for o in c]] for i in detected_instances] + + # Call C++ implementation of self.evaluateImgs() + self._evalImgs_cpp = _C.COCOevalEvaluateImages( + p.areaRng, maxDet, p.iouThrs, ious, ground_truth_instances, detected_instances + ) + self._evalImgs = None + + self._paramsEval = copy.deepcopy(self.params) + toc = time.time() + logger.info("COCOeval_opt.evaluate() finished in {:0.2f} seconds.".format(toc - tic)) + # >>>> End of code differences with original COCO API + + def accumulate(self): + """ + Accumulate per image evaluation results and store the result in self.eval. Does not + support changing parameter settings from those used by self.evaluate() + """ + logger.info("Accumulating evaluation results...") + tic = time.time() + assert hasattr( + self, "_evalImgs_cpp" + ), "evaluate() must be called before accmulate() is called." + + self.eval = _C.COCOevalAccumulate(self._paramsEval, self._evalImgs_cpp) + + # recall is num_iou_thresholds X num_categories X num_area_ranges X num_max_detections + self.eval["recall"] = np.array(self.eval["recall"]).reshape( + self.eval["counts"][:1] + self.eval["counts"][2:] + ) + + # precision and scores are num_iou_thresholds X num_recall_thresholds X num_categories X + # num_area_ranges X num_max_detections + self.eval["precision"] = np.array(self.eval["precision"]).reshape(self.eval["counts"]) + self.eval["scores"] = np.array(self.eval["scores"]).reshape(self.eval["counts"]) + toc = time.time() + logger.info("COCOeval_opt.accumulate() finished in {:0.2f} seconds.".format(toc - tic)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/lvis_evaluation.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/lvis_evaluation.py new file mode 100644 index 00000000..7d712ef2 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/lvis_evaluation.py @@ -0,0 +1,380 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import copy +import itertools +import json +import logging +import os +import pickle +from collections import OrderedDict +import torch + +import annotator.oneformer.detectron2.utils.comm as comm +from annotator.oneformer.detectron2.config import CfgNode +from annotator.oneformer.detectron2.data import MetadataCatalog +from annotator.oneformer.detectron2.structures import Boxes, BoxMode, pairwise_iou +from annotator.oneformer.detectron2.utils.file_io import PathManager +from annotator.oneformer.detectron2.utils.logger import create_small_table + +from .coco_evaluation import instances_to_coco_json +from .evaluator import DatasetEvaluator + + +class LVISEvaluator(DatasetEvaluator): + """ + Evaluate object proposal and instance detection/segmentation outputs using + LVIS's metrics and evaluation API. + """ + + def __init__( + self, + dataset_name, + tasks=None, + distributed=True, + output_dir=None, + *, + max_dets_per_image=None, + ): + """ + Args: + dataset_name (str): name of the dataset to be evaluated. + It must have the following corresponding metadata: + "json_file": the path to the LVIS format annotation + tasks (tuple[str]): tasks that can be evaluated under the given + configuration. A task is one of "bbox", "segm". + By default, will infer this automatically from predictions. + distributed (True): if True, will collect results from all ranks for evaluation. + Otherwise, will evaluate the results in the current process. + output_dir (str): optional, an output directory to dump results. + max_dets_per_image (None or int): limit on maximum detections per image in evaluating AP + This limit, by default of the LVIS dataset, is 300. + """ + from lvis import LVIS + + self._logger = logging.getLogger(__name__) + + if tasks is not None and isinstance(tasks, CfgNode): + self._logger.warn( + "COCO Evaluator instantiated using config, this is deprecated behavior." + " Please pass in explicit arguments instead." + ) + self._tasks = None # Infering it from predictions should be better + else: + self._tasks = tasks + + self._distributed = distributed + self._output_dir = output_dir + self._max_dets_per_image = max_dets_per_image + + self._cpu_device = torch.device("cpu") + + self._metadata = MetadataCatalog.get(dataset_name) + json_file = PathManager.get_local_path(self._metadata.json_file) + self._lvis_api = LVIS(json_file) + # Test set json files do not contain annotations (evaluation must be + # performed using the LVIS evaluation server). + self._do_evaluation = len(self._lvis_api.get_ann_ids()) > 0 + + def reset(self): + self._predictions = [] + + def process(self, inputs, outputs): + """ + Args: + inputs: the inputs to a LVIS model (e.g., GeneralizedRCNN). + It is a list of dict. Each dict corresponds to an image and + contains keys like "height", "width", "file_name", "image_id". + outputs: the outputs of a LVIS model. It is a list of dicts with key + "instances" that contains :class:`Instances`. + """ + for input, output in zip(inputs, outputs): + prediction = {"image_id": input["image_id"]} + + if "instances" in output: + instances = output["instances"].to(self._cpu_device) + prediction["instances"] = instances_to_coco_json(instances, input["image_id"]) + if "proposals" in output: + prediction["proposals"] = output["proposals"].to(self._cpu_device) + self._predictions.append(prediction) + + def evaluate(self): + if self._distributed: + comm.synchronize() + predictions = comm.gather(self._predictions, dst=0) + predictions = list(itertools.chain(*predictions)) + + if not comm.is_main_process(): + return + else: + predictions = self._predictions + + if len(predictions) == 0: + self._logger.warning("[LVISEvaluator] Did not receive valid predictions.") + return {} + + if self._output_dir: + PathManager.mkdirs(self._output_dir) + file_path = os.path.join(self._output_dir, "instances_predictions.pth") + with PathManager.open(file_path, "wb") as f: + torch.save(predictions, f) + + self._results = OrderedDict() + if "proposals" in predictions[0]: + self._eval_box_proposals(predictions) + if "instances" in predictions[0]: + self._eval_predictions(predictions) + # Copy so the caller can do whatever with results + return copy.deepcopy(self._results) + + def _tasks_from_predictions(self, predictions): + for pred in predictions: + if "segmentation" in pred: + return ("bbox", "segm") + return ("bbox",) + + def _eval_predictions(self, predictions): + """ + Evaluate predictions. Fill self._results with the metrics of the tasks. + + Args: + predictions (list[dict]): list of outputs from the model + """ + self._logger.info("Preparing results in the LVIS format ...") + lvis_results = list(itertools.chain(*[x["instances"] for x in predictions])) + tasks = self._tasks or self._tasks_from_predictions(lvis_results) + + # LVIS evaluator can be used to evaluate results for COCO dataset categories. + # In this case `_metadata` variable will have a field with COCO-specific category mapping. + if hasattr(self._metadata, "thing_dataset_id_to_contiguous_id"): + reverse_id_mapping = { + v: k for k, v in self._metadata.thing_dataset_id_to_contiguous_id.items() + } + for result in lvis_results: + result["category_id"] = reverse_id_mapping[result["category_id"]] + else: + # unmap the category ids for LVIS (from 0-indexed to 1-indexed) + for result in lvis_results: + result["category_id"] += 1 + + if self._output_dir: + file_path = os.path.join(self._output_dir, "lvis_instances_results.json") + self._logger.info("Saving results to {}".format(file_path)) + with PathManager.open(file_path, "w") as f: + f.write(json.dumps(lvis_results)) + f.flush() + + if not self._do_evaluation: + self._logger.info("Annotations are not available for evaluation.") + return + + self._logger.info("Evaluating predictions ...") + for task in sorted(tasks): + res = _evaluate_predictions_on_lvis( + self._lvis_api, + lvis_results, + task, + max_dets_per_image=self._max_dets_per_image, + class_names=self._metadata.get("thing_classes"), + ) + self._results[task] = res + + def _eval_box_proposals(self, predictions): + """ + Evaluate the box proposals in predictions. + Fill self._results with the metrics for "box_proposals" task. + """ + if self._output_dir: + # Saving generated box proposals to file. + # Predicted box_proposals are in XYXY_ABS mode. + bbox_mode = BoxMode.XYXY_ABS.value + ids, boxes, objectness_logits = [], [], [] + for prediction in predictions: + ids.append(prediction["image_id"]) + boxes.append(prediction["proposals"].proposal_boxes.tensor.numpy()) + objectness_logits.append(prediction["proposals"].objectness_logits.numpy()) + + proposal_data = { + "boxes": boxes, + "objectness_logits": objectness_logits, + "ids": ids, + "bbox_mode": bbox_mode, + } + with PathManager.open(os.path.join(self._output_dir, "box_proposals.pkl"), "wb") as f: + pickle.dump(proposal_data, f) + + if not self._do_evaluation: + self._logger.info("Annotations are not available for evaluation.") + return + + self._logger.info("Evaluating bbox proposals ...") + res = {} + areas = {"all": "", "small": "s", "medium": "m", "large": "l"} + for limit in [100, 1000]: + for area, suffix in areas.items(): + stats = _evaluate_box_proposals(predictions, self._lvis_api, area=area, limit=limit) + key = "AR{}@{:d}".format(suffix, limit) + res[key] = float(stats["ar"].item() * 100) + self._logger.info("Proposal metrics: \n" + create_small_table(res)) + self._results["box_proposals"] = res + + +# inspired from Detectron: +# https://github.com/facebookresearch/Detectron/blob/a6a835f5b8208c45d0dce217ce9bbda915f44df7/detectron/datasets/json_dataset_evaluator.py#L255 # noqa +def _evaluate_box_proposals(dataset_predictions, lvis_api, thresholds=None, area="all", limit=None): + """ + Evaluate detection proposal recall metrics. This function is a much + faster alternative to the official LVIS API recall evaluation code. However, + it produces slightly different results. + """ + # Record max overlap value for each gt box + # Return vector of overlap values + areas = { + "all": 0, + "small": 1, + "medium": 2, + "large": 3, + "96-128": 4, + "128-256": 5, + "256-512": 6, + "512-inf": 7, + } + area_ranges = [ + [0**2, 1e5**2], # all + [0**2, 32**2], # small + [32**2, 96**2], # medium + [96**2, 1e5**2], # large + [96**2, 128**2], # 96-128 + [128**2, 256**2], # 128-256 + [256**2, 512**2], # 256-512 + [512**2, 1e5**2], + ] # 512-inf + assert area in areas, "Unknown area range: {}".format(area) + area_range = area_ranges[areas[area]] + gt_overlaps = [] + num_pos = 0 + + for prediction_dict in dataset_predictions: + predictions = prediction_dict["proposals"] + + # sort predictions in descending order + # TODO maybe remove this and make it explicit in the documentation + inds = predictions.objectness_logits.sort(descending=True)[1] + predictions = predictions[inds] + + ann_ids = lvis_api.get_ann_ids(img_ids=[prediction_dict["image_id"]]) + anno = lvis_api.load_anns(ann_ids) + gt_boxes = [ + BoxMode.convert(obj["bbox"], BoxMode.XYWH_ABS, BoxMode.XYXY_ABS) for obj in anno + ] + gt_boxes = torch.as_tensor(gt_boxes).reshape(-1, 4) # guard against no boxes + gt_boxes = Boxes(gt_boxes) + gt_areas = torch.as_tensor([obj["area"] for obj in anno]) + + if len(gt_boxes) == 0 or len(predictions) == 0: + continue + + valid_gt_inds = (gt_areas >= area_range[0]) & (gt_areas <= area_range[1]) + gt_boxes = gt_boxes[valid_gt_inds] + + num_pos += len(gt_boxes) + + if len(gt_boxes) == 0: + continue + + if limit is not None and len(predictions) > limit: + predictions = predictions[:limit] + + overlaps = pairwise_iou(predictions.proposal_boxes, gt_boxes) + + _gt_overlaps = torch.zeros(len(gt_boxes)) + for j in range(min(len(predictions), len(gt_boxes))): + # find which proposal box maximally covers each gt box + # and get the iou amount of coverage for each gt box + max_overlaps, argmax_overlaps = overlaps.max(dim=0) + + # find which gt box is 'best' covered (i.e. 'best' = most iou) + gt_ovr, gt_ind = max_overlaps.max(dim=0) + assert gt_ovr >= 0 + # find the proposal box that covers the best covered gt box + box_ind = argmax_overlaps[gt_ind] + # record the iou coverage of this gt box + _gt_overlaps[j] = overlaps[box_ind, gt_ind] + assert _gt_overlaps[j] == gt_ovr + # mark the proposal box and the gt box as used + overlaps[box_ind, :] = -1 + overlaps[:, gt_ind] = -1 + + # append recorded iou coverage level + gt_overlaps.append(_gt_overlaps) + gt_overlaps = ( + torch.cat(gt_overlaps, dim=0) if len(gt_overlaps) else torch.zeros(0, dtype=torch.float32) + ) + gt_overlaps, _ = torch.sort(gt_overlaps) + + if thresholds is None: + step = 0.05 + thresholds = torch.arange(0.5, 0.95 + 1e-5, step, dtype=torch.float32) + recalls = torch.zeros_like(thresholds) + # compute recall for each iou threshold + for i, t in enumerate(thresholds): + recalls[i] = (gt_overlaps >= t).float().sum() / float(num_pos) + # ar = 2 * np.trapz(recalls, thresholds) + ar = recalls.mean() + return { + "ar": ar, + "recalls": recalls, + "thresholds": thresholds, + "gt_overlaps": gt_overlaps, + "num_pos": num_pos, + } + + +def _evaluate_predictions_on_lvis( + lvis_gt, lvis_results, iou_type, max_dets_per_image=None, class_names=None +): + """ + Args: + iou_type (str): + max_dets_per_image (None or int): limit on maximum detections per image in evaluating AP + This limit, by default of the LVIS dataset, is 300. + class_names (None or list[str]): if provided, will use it to predict + per-category AP. + + Returns: + a dict of {metric name: score} + """ + metrics = { + "bbox": ["AP", "AP50", "AP75", "APs", "APm", "APl", "APr", "APc", "APf"], + "segm": ["AP", "AP50", "AP75", "APs", "APm", "APl", "APr", "APc", "APf"], + }[iou_type] + + logger = logging.getLogger(__name__) + + if len(lvis_results) == 0: # TODO: check if needed + logger.warn("No predictions from the model!") + return {metric: float("nan") for metric in metrics} + + if iou_type == "segm": + lvis_results = copy.deepcopy(lvis_results) + # When evaluating mask AP, if the results contain bbox, LVIS API will + # use the box area as the area of the instance, instead of the mask area. + # This leads to a different definition of small/medium/large. + # We remove the bbox field to let mask AP use mask area. + for c in lvis_results: + c.pop("bbox", None) + + if max_dets_per_image is None: + max_dets_per_image = 300 # Default for LVIS dataset + + from lvis import LVISEval, LVISResults + + logger.info(f"Evaluating with max detections per image = {max_dets_per_image}") + lvis_results = LVISResults(lvis_gt, lvis_results, max_dets=max_dets_per_image) + lvis_eval = LVISEval(lvis_gt, lvis_results, iou_type) + lvis_eval.run() + lvis_eval.print_results() + + # Pull the standard metrics from the LVIS results + results = lvis_eval.get_results() + results = {metric: float(results[metric] * 100) for metric in metrics} + logger.info("Evaluation results for {}: \n".format(iou_type) + create_small_table(results)) + return results diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/panoptic_evaluation.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/panoptic_evaluation.py new file mode 100644 index 00000000..bf77fe06 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/panoptic_evaluation.py @@ -0,0 +1,199 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import contextlib +import io +import itertools +import json +import logging +import numpy as np +import os +import tempfile +from collections import OrderedDict +from typing import Optional +from PIL import Image +from tabulate import tabulate + +from annotator.oneformer.detectron2.data import MetadataCatalog +from annotator.oneformer.detectron2.utils import comm +from annotator.oneformer.detectron2.utils.file_io import PathManager + +from .evaluator import DatasetEvaluator + +logger = logging.getLogger(__name__) + + +class COCOPanopticEvaluator(DatasetEvaluator): + """ + Evaluate Panoptic Quality metrics on COCO using PanopticAPI. + It saves panoptic segmentation prediction in `output_dir` + + It contains a synchronize call and has to be called from all workers. + """ + + def __init__(self, dataset_name: str, output_dir: Optional[str] = None): + """ + Args: + dataset_name: name of the dataset + output_dir: output directory to save results for evaluation. + """ + self._metadata = MetadataCatalog.get(dataset_name) + self._thing_contiguous_id_to_dataset_id = { + v: k for k, v in self._metadata.thing_dataset_id_to_contiguous_id.items() + } + self._stuff_contiguous_id_to_dataset_id = { + v: k for k, v in self._metadata.stuff_dataset_id_to_contiguous_id.items() + } + + self._output_dir = output_dir + if self._output_dir is not None: + PathManager.mkdirs(self._output_dir) + + def reset(self): + self._predictions = [] + + def _convert_category_id(self, segment_info): + isthing = segment_info.pop("isthing", None) + if isthing is None: + # the model produces panoptic category id directly. No more conversion needed + return segment_info + if isthing is True: + segment_info["category_id"] = self._thing_contiguous_id_to_dataset_id[ + segment_info["category_id"] + ] + else: + segment_info["category_id"] = self._stuff_contiguous_id_to_dataset_id[ + segment_info["category_id"] + ] + return segment_info + + def process(self, inputs, outputs): + from panopticapi.utils import id2rgb + + for input, output in zip(inputs, outputs): + panoptic_img, segments_info = output["panoptic_seg"] + panoptic_img = panoptic_img.cpu().numpy() + if segments_info is None: + # If "segments_info" is None, we assume "panoptic_img" is a + # H*W int32 image storing the panoptic_id in the format of + # category_id * label_divisor + instance_id. We reserve -1 for + # VOID label, and add 1 to panoptic_img since the official + # evaluation script uses 0 for VOID label. + label_divisor = self._metadata.label_divisor + segments_info = [] + for panoptic_label in np.unique(panoptic_img): + if panoptic_label == -1: + # VOID region. + continue + pred_class = panoptic_label // label_divisor + isthing = ( + pred_class in self._metadata.thing_dataset_id_to_contiguous_id.values() + ) + segments_info.append( + { + "id": int(panoptic_label) + 1, + "category_id": int(pred_class), + "isthing": bool(isthing), + } + ) + # Official evaluation script uses 0 for VOID label. + panoptic_img += 1 + + file_name = os.path.basename(input["file_name"]) + file_name_png = os.path.splitext(file_name)[0] + ".png" + with io.BytesIO() as out: + Image.fromarray(id2rgb(panoptic_img)).save(out, format="PNG") + segments_info = [self._convert_category_id(x) for x in segments_info] + self._predictions.append( + { + "image_id": input["image_id"], + "file_name": file_name_png, + "png_string": out.getvalue(), + "segments_info": segments_info, + } + ) + + def evaluate(self): + comm.synchronize() + + self._predictions = comm.gather(self._predictions) + self._predictions = list(itertools.chain(*self._predictions)) + if not comm.is_main_process(): + return + + # PanopticApi requires local files + gt_json = PathManager.get_local_path(self._metadata.panoptic_json) + gt_folder = PathManager.get_local_path(self._metadata.panoptic_root) + + with tempfile.TemporaryDirectory(prefix="panoptic_eval") as pred_dir: + logger.info("Writing all panoptic predictions to {} ...".format(pred_dir)) + for p in self._predictions: + with open(os.path.join(pred_dir, p["file_name"]), "wb") as f: + f.write(p.pop("png_string")) + + with open(gt_json, "r") as f: + json_data = json.load(f) + json_data["annotations"] = self._predictions + + output_dir = self._output_dir or pred_dir + predictions_json = os.path.join(output_dir, "predictions.json") + with PathManager.open(predictions_json, "w") as f: + f.write(json.dumps(json_data)) + + from panopticapi.evaluation import pq_compute + + with contextlib.redirect_stdout(io.StringIO()): + pq_res = pq_compute( + gt_json, + PathManager.get_local_path(predictions_json), + gt_folder=gt_folder, + pred_folder=pred_dir, + ) + + res = {} + res["PQ"] = 100 * pq_res["All"]["pq"] + res["SQ"] = 100 * pq_res["All"]["sq"] + res["RQ"] = 100 * pq_res["All"]["rq"] + res["PQ_th"] = 100 * pq_res["Things"]["pq"] + res["SQ_th"] = 100 * pq_res["Things"]["sq"] + res["RQ_th"] = 100 * pq_res["Things"]["rq"] + res["PQ_st"] = 100 * pq_res["Stuff"]["pq"] + res["SQ_st"] = 100 * pq_res["Stuff"]["sq"] + res["RQ_st"] = 100 * pq_res["Stuff"]["rq"] + + results = OrderedDict({"panoptic_seg": res}) + _print_panoptic_results(pq_res) + + return results + + +def _print_panoptic_results(pq_res): + headers = ["", "PQ", "SQ", "RQ", "#categories"] + data = [] + for name in ["All", "Things", "Stuff"]: + row = [name] + [pq_res[name][k] * 100 for k in ["pq", "sq", "rq"]] + [pq_res[name]["n"]] + data.append(row) + table = tabulate( + data, headers=headers, tablefmt="pipe", floatfmt=".3f", stralign="center", numalign="center" + ) + logger.info("Panoptic Evaluation Results:\n" + table) + + +if __name__ == "__main__": + from annotator.oneformer.detectron2.utils.logger import setup_logger + + logger = setup_logger() + import argparse + + parser = argparse.ArgumentParser() + parser.add_argument("--gt-json") + parser.add_argument("--gt-dir") + parser.add_argument("--pred-json") + parser.add_argument("--pred-dir") + args = parser.parse_args() + + from panopticapi.evaluation import pq_compute + + with contextlib.redirect_stdout(io.StringIO()): + pq_res = pq_compute( + args.gt_json, args.pred_json, gt_folder=args.gt_dir, pred_folder=args.pred_dir + ) + _print_panoptic_results(pq_res) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/pascal_voc_evaluation.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/pascal_voc_evaluation.py new file mode 100644 index 00000000..b2963e5d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/pascal_voc_evaluation.py @@ -0,0 +1,300 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +import logging +import numpy as np +import os +import tempfile +import xml.etree.ElementTree as ET +from collections import OrderedDict, defaultdict +from functools import lru_cache +import torch + +from annotator.oneformer.detectron2.data import MetadataCatalog +from annotator.oneformer.detectron2.utils import comm +from annotator.oneformer.detectron2.utils.file_io import PathManager + +from .evaluator import DatasetEvaluator + + +class PascalVOCDetectionEvaluator(DatasetEvaluator): + """ + Evaluate Pascal VOC style AP for Pascal VOC dataset. + It contains a synchronization, therefore has to be called from all ranks. + + Note that the concept of AP can be implemented in different ways and may not + produce identical results. This class mimics the implementation of the official + Pascal VOC Matlab API, and should produce similar but not identical results to the + official API. + """ + + def __init__(self, dataset_name): + """ + Args: + dataset_name (str): name of the dataset, e.g., "voc_2007_test" + """ + self._dataset_name = dataset_name + meta = MetadataCatalog.get(dataset_name) + + # Too many tiny files, download all to local for speed. + annotation_dir_local = PathManager.get_local_path( + os.path.join(meta.dirname, "Annotations/") + ) + self._anno_file_template = os.path.join(annotation_dir_local, "{}.xml") + self._image_set_path = os.path.join(meta.dirname, "ImageSets", "Main", meta.split + ".txt") + self._class_names = meta.thing_classes + assert meta.year in [2007, 2012], meta.year + self._is_2007 = meta.year == 2007 + self._cpu_device = torch.device("cpu") + self._logger = logging.getLogger(__name__) + + def reset(self): + self._predictions = defaultdict(list) # class name -> list of prediction strings + + def process(self, inputs, outputs): + for input, output in zip(inputs, outputs): + image_id = input["image_id"] + instances = output["instances"].to(self._cpu_device) + boxes = instances.pred_boxes.tensor.numpy() + scores = instances.scores.tolist() + classes = instances.pred_classes.tolist() + for box, score, cls in zip(boxes, scores, classes): + xmin, ymin, xmax, ymax = box + # The inverse of data loading logic in `datasets/pascal_voc.py` + xmin += 1 + ymin += 1 + self._predictions[cls].append( + f"{image_id} {score:.3f} {xmin:.1f} {ymin:.1f} {xmax:.1f} {ymax:.1f}" + ) + + def evaluate(self): + """ + Returns: + dict: has a key "segm", whose value is a dict of "AP", "AP50", and "AP75". + """ + all_predictions = comm.gather(self._predictions, dst=0) + if not comm.is_main_process(): + return + predictions = defaultdict(list) + for predictions_per_rank in all_predictions: + for clsid, lines in predictions_per_rank.items(): + predictions[clsid].extend(lines) + del all_predictions + + self._logger.info( + "Evaluating {} using {} metric. " + "Note that results do not use the official Matlab API.".format( + self._dataset_name, 2007 if self._is_2007 else 2012 + ) + ) + + with tempfile.TemporaryDirectory(prefix="pascal_voc_eval_") as dirname: + res_file_template = os.path.join(dirname, "{}.txt") + + aps = defaultdict(list) # iou -> ap per class + for cls_id, cls_name in enumerate(self._class_names): + lines = predictions.get(cls_id, [""]) + + with open(res_file_template.format(cls_name), "w") as f: + f.write("\n".join(lines)) + + for thresh in range(50, 100, 5): + rec, prec, ap = voc_eval( + res_file_template, + self._anno_file_template, + self._image_set_path, + cls_name, + ovthresh=thresh / 100.0, + use_07_metric=self._is_2007, + ) + aps[thresh].append(ap * 100) + + ret = OrderedDict() + mAP = {iou: np.mean(x) for iou, x in aps.items()} + ret["bbox"] = {"AP": np.mean(list(mAP.values())), "AP50": mAP[50], "AP75": mAP[75]} + return ret + + +############################################################################## +# +# Below code is modified from +# https://github.com/rbgirshick/py-faster-rcnn/blob/master/lib/datasets/voc_eval.py +# -------------------------------------------------------- +# Fast/er R-CNN +# Licensed under The MIT License [see LICENSE for details] +# Written by Bharath Hariharan +# -------------------------------------------------------- + +"""Python implementation of the PASCAL VOC devkit's AP evaluation code.""" + + +@lru_cache(maxsize=None) +def parse_rec(filename): + """Parse a PASCAL VOC xml file.""" + with PathManager.open(filename) as f: + tree = ET.parse(f) + objects = [] + for obj in tree.findall("object"): + obj_struct = {} + obj_struct["name"] = obj.find("name").text + obj_struct["pose"] = obj.find("pose").text + obj_struct["truncated"] = int(obj.find("truncated").text) + obj_struct["difficult"] = int(obj.find("difficult").text) + bbox = obj.find("bndbox") + obj_struct["bbox"] = [ + int(bbox.find("xmin").text), + int(bbox.find("ymin").text), + int(bbox.find("xmax").text), + int(bbox.find("ymax").text), + ] + objects.append(obj_struct) + + return objects + + +def voc_ap(rec, prec, use_07_metric=False): + """Compute VOC AP given precision and recall. If use_07_metric is true, uses + the VOC 07 11-point method (default:False). + """ + if use_07_metric: + # 11 point metric + ap = 0.0 + for t in np.arange(0.0, 1.1, 0.1): + if np.sum(rec >= t) == 0: + p = 0 + else: + p = np.max(prec[rec >= t]) + ap = ap + p / 11.0 + else: + # correct AP calculation + # first append sentinel values at the end + mrec = np.concatenate(([0.0], rec, [1.0])) + mpre = np.concatenate(([0.0], prec, [0.0])) + + # compute the precision envelope + for i in range(mpre.size - 1, 0, -1): + mpre[i - 1] = np.maximum(mpre[i - 1], mpre[i]) + + # to calculate area under PR curve, look for points + # where X axis (recall) changes value + i = np.where(mrec[1:] != mrec[:-1])[0] + + # and sum (\Delta recall) * prec + ap = np.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1]) + return ap + + +def voc_eval(detpath, annopath, imagesetfile, classname, ovthresh=0.5, use_07_metric=False): + """rec, prec, ap = voc_eval(detpath, + annopath, + imagesetfile, + classname, + [ovthresh], + [use_07_metric]) + + Top level function that does the PASCAL VOC evaluation. + + detpath: Path to detections + detpath.format(classname) should produce the detection results file. + annopath: Path to annotations + annopath.format(imagename) should be the xml annotations file. + imagesetfile: Text file containing the list of images, one image per line. + classname: Category name (duh) + [ovthresh]: Overlap threshold (default = 0.5) + [use_07_metric]: Whether to use VOC07's 11 point AP computation + (default False) + """ + # assumes detections are in detpath.format(classname) + # assumes annotations are in annopath.format(imagename) + # assumes imagesetfile is a text file with each line an image name + + # first load gt + # read list of images + with PathManager.open(imagesetfile, "r") as f: + lines = f.readlines() + imagenames = [x.strip() for x in lines] + + # load annots + recs = {} + for imagename in imagenames: + recs[imagename] = parse_rec(annopath.format(imagename)) + + # extract gt objects for this class + class_recs = {} + npos = 0 + for imagename in imagenames: + R = [obj for obj in recs[imagename] if obj["name"] == classname] + bbox = np.array([x["bbox"] for x in R]) + difficult = np.array([x["difficult"] for x in R]).astype(bool) + # difficult = np.array([False for x in R]).astype(bool) # treat all "difficult" as GT + det = [False] * len(R) + npos = npos + sum(~difficult) + class_recs[imagename] = {"bbox": bbox, "difficult": difficult, "det": det} + + # read dets + detfile = detpath.format(classname) + with open(detfile, "r") as f: + lines = f.readlines() + + splitlines = [x.strip().split(" ") for x in lines] + image_ids = [x[0] for x in splitlines] + confidence = np.array([float(x[1]) for x in splitlines]) + BB = np.array([[float(z) for z in x[2:]] for x in splitlines]).reshape(-1, 4) + + # sort by confidence + sorted_ind = np.argsort(-confidence) + BB = BB[sorted_ind, :] + image_ids = [image_ids[x] for x in sorted_ind] + + # go down dets and mark TPs and FPs + nd = len(image_ids) + tp = np.zeros(nd) + fp = np.zeros(nd) + for d in range(nd): + R = class_recs[image_ids[d]] + bb = BB[d, :].astype(float) + ovmax = -np.inf + BBGT = R["bbox"].astype(float) + + if BBGT.size > 0: + # compute overlaps + # intersection + ixmin = np.maximum(BBGT[:, 0], bb[0]) + iymin = np.maximum(BBGT[:, 1], bb[1]) + ixmax = np.minimum(BBGT[:, 2], bb[2]) + iymax = np.minimum(BBGT[:, 3], bb[3]) + iw = np.maximum(ixmax - ixmin + 1.0, 0.0) + ih = np.maximum(iymax - iymin + 1.0, 0.0) + inters = iw * ih + + # union + uni = ( + (bb[2] - bb[0] + 1.0) * (bb[3] - bb[1] + 1.0) + + (BBGT[:, 2] - BBGT[:, 0] + 1.0) * (BBGT[:, 3] - BBGT[:, 1] + 1.0) + - inters + ) + + overlaps = inters / uni + ovmax = np.max(overlaps) + jmax = np.argmax(overlaps) + + if ovmax > ovthresh: + if not R["difficult"][jmax]: + if not R["det"][jmax]: + tp[d] = 1.0 + R["det"][jmax] = 1 + else: + fp[d] = 1.0 + else: + fp[d] = 1.0 + + # compute precision recall + fp = np.cumsum(fp) + tp = np.cumsum(tp) + rec = tp / float(npos) + # avoid divide by zero in case the first detection matches a difficult + # ground truth + prec = tp / np.maximum(tp + fp, np.finfo(np.float64).eps) + ap = voc_ap(rec, prec, use_07_metric) + + return rec, prec, ap diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/rotated_coco_evaluation.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/rotated_coco_evaluation.py new file mode 100644 index 00000000..0d5306c3 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/rotated_coco_evaluation.py @@ -0,0 +1,207 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import itertools +import json +import numpy as np +import os +import torch +from annotator.oneformer.pycocotools.cocoeval import COCOeval, maskUtils + +from annotator.oneformer.detectron2.structures import BoxMode, RotatedBoxes, pairwise_iou_rotated +from annotator.oneformer.detectron2.utils.file_io import PathManager + +from .coco_evaluation import COCOEvaluator + + +class RotatedCOCOeval(COCOeval): + @staticmethod + def is_rotated(box_list): + if type(box_list) == np.ndarray: + return box_list.shape[1] == 5 + elif type(box_list) == list: + if box_list == []: # cannot decide the box_dim + return False + return np.all( + np.array( + [ + (len(obj) == 5) and ((type(obj) == list) or (type(obj) == np.ndarray)) + for obj in box_list + ] + ) + ) + return False + + @staticmethod + def boxlist_to_tensor(boxlist, output_box_dim): + if type(boxlist) == np.ndarray: + box_tensor = torch.from_numpy(boxlist) + elif type(boxlist) == list: + if boxlist == []: + return torch.zeros((0, output_box_dim), dtype=torch.float32) + else: + box_tensor = torch.FloatTensor(boxlist) + else: + raise Exception("Unrecognized boxlist type") + + input_box_dim = box_tensor.shape[1] + if input_box_dim != output_box_dim: + if input_box_dim == 4 and output_box_dim == 5: + box_tensor = BoxMode.convert(box_tensor, BoxMode.XYWH_ABS, BoxMode.XYWHA_ABS) + else: + raise Exception( + "Unable to convert from {}-dim box to {}-dim box".format( + input_box_dim, output_box_dim + ) + ) + return box_tensor + + def compute_iou_dt_gt(self, dt, gt, is_crowd): + if self.is_rotated(dt) or self.is_rotated(gt): + # TODO: take is_crowd into consideration + assert all(c == 0 for c in is_crowd) + dt = RotatedBoxes(self.boxlist_to_tensor(dt, output_box_dim=5)) + gt = RotatedBoxes(self.boxlist_to_tensor(gt, output_box_dim=5)) + return pairwise_iou_rotated(dt, gt) + else: + # This is the same as the classical COCO evaluation + return maskUtils.iou(dt, gt, is_crowd) + + def computeIoU(self, imgId, catId): + p = self.params + if p.useCats: + gt = self._gts[imgId, catId] + dt = self._dts[imgId, catId] + else: + gt = [_ for cId in p.catIds for _ in self._gts[imgId, cId]] + dt = [_ for cId in p.catIds for _ in self._dts[imgId, cId]] + if len(gt) == 0 and len(dt) == 0: + return [] + inds = np.argsort([-d["score"] for d in dt], kind="mergesort") + dt = [dt[i] for i in inds] + if len(dt) > p.maxDets[-1]: + dt = dt[0 : p.maxDets[-1]] + + assert p.iouType == "bbox", "unsupported iouType for iou computation" + + g = [g["bbox"] for g in gt] + d = [d["bbox"] for d in dt] + + # compute iou between each dt and gt region + iscrowd = [int(o["iscrowd"]) for o in gt] + + # Note: this function is copied from cocoeval.py in cocoapi + # and the major difference is here. + ious = self.compute_iou_dt_gt(d, g, iscrowd) + return ious + + +class RotatedCOCOEvaluator(COCOEvaluator): + """ + Evaluate object proposal/instance detection outputs using COCO-like metrics and APIs, + with rotated boxes support. + Note: this uses IOU only and does not consider angle differences. + """ + + def process(self, inputs, outputs): + """ + Args: + inputs: the inputs to a COCO model (e.g., GeneralizedRCNN). + It is a list of dict. Each dict corresponds to an image and + contains keys like "height", "width", "file_name", "image_id". + outputs: the outputs of a COCO model. It is a list of dicts with key + "instances" that contains :class:`Instances`. + """ + for input, output in zip(inputs, outputs): + prediction = {"image_id": input["image_id"]} + + if "instances" in output: + instances = output["instances"].to(self._cpu_device) + + prediction["instances"] = self.instances_to_json(instances, input["image_id"]) + if "proposals" in output: + prediction["proposals"] = output["proposals"].to(self._cpu_device) + self._predictions.append(prediction) + + def instances_to_json(self, instances, img_id): + num_instance = len(instances) + if num_instance == 0: + return [] + + boxes = instances.pred_boxes.tensor.numpy() + if boxes.shape[1] == 4: + boxes = BoxMode.convert(boxes, BoxMode.XYXY_ABS, BoxMode.XYWH_ABS) + boxes = boxes.tolist() + scores = instances.scores.tolist() + classes = instances.pred_classes.tolist() + + results = [] + for k in range(num_instance): + result = { + "image_id": img_id, + "category_id": classes[k], + "bbox": boxes[k], + "score": scores[k], + } + + results.append(result) + return results + + def _eval_predictions(self, predictions, img_ids=None): # img_ids: unused + """ + Evaluate predictions on the given tasks. + Fill self._results with the metrics of the tasks. + """ + self._logger.info("Preparing results for COCO format ...") + coco_results = list(itertools.chain(*[x["instances"] for x in predictions])) + + # unmap the category ids for COCO + if hasattr(self._metadata, "thing_dataset_id_to_contiguous_id"): + reverse_id_mapping = { + v: k for k, v in self._metadata.thing_dataset_id_to_contiguous_id.items() + } + for result in coco_results: + result["category_id"] = reverse_id_mapping[result["category_id"]] + + if self._output_dir: + file_path = os.path.join(self._output_dir, "coco_instances_results.json") + self._logger.info("Saving results to {}".format(file_path)) + with PathManager.open(file_path, "w") as f: + f.write(json.dumps(coco_results)) + f.flush() + + if not self._do_evaluation: + self._logger.info("Annotations are not available for evaluation.") + return + + self._logger.info("Evaluating predictions ...") + + assert self._tasks is None or set(self._tasks) == { + "bbox" + }, "[RotatedCOCOEvaluator] Only bbox evaluation is supported" + coco_eval = ( + self._evaluate_predictions_on_coco(self._coco_api, coco_results) + if len(coco_results) > 0 + else None # cocoapi does not handle empty results very well + ) + + task = "bbox" + res = self._derive_coco_results( + coco_eval, task, class_names=self._metadata.get("thing_classes") + ) + self._results[task] = res + + def _evaluate_predictions_on_coco(self, coco_gt, coco_results): + """ + Evaluate the coco results using COCOEval API. + """ + assert len(coco_results) > 0 + + coco_dt = coco_gt.loadRes(coco_results) + + # Only bbox is supported for now + coco_eval = RotatedCOCOeval(coco_gt, coco_dt, iouType="bbox") + + coco_eval.evaluate() + coco_eval.accumulate() + coco_eval.summarize() + + return coco_eval diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/sem_seg_evaluation.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/sem_seg_evaluation.py new file mode 100644 index 00000000..1c2f3f5a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/sem_seg_evaluation.py @@ -0,0 +1,265 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import itertools +import json +import logging +import numpy as np +import os +from collections import OrderedDict +from typing import Optional, Union +import annotator.oneformer.pycocotools.mask as mask_util +import torch +from PIL import Image + +from annotator.oneformer.detectron2.data import DatasetCatalog, MetadataCatalog +from annotator.oneformer.detectron2.utils.comm import all_gather, is_main_process, synchronize +from annotator.oneformer.detectron2.utils.file_io import PathManager + +from .evaluator import DatasetEvaluator + +_CV2_IMPORTED = True +try: + import cv2 # noqa +except ImportError: + # OpenCV is an optional dependency at the moment + _CV2_IMPORTED = False + + +def load_image_into_numpy_array( + filename: str, + copy: bool = False, + dtype: Optional[Union[np.dtype, str]] = None, +) -> np.ndarray: + with PathManager.open(filename, "rb") as f: + array = np.array(Image.open(f), copy=copy, dtype=dtype) + return array + + +class SemSegEvaluator(DatasetEvaluator): + """ + Evaluate semantic segmentation metrics. + """ + + def __init__( + self, + dataset_name, + distributed=True, + output_dir=None, + *, + sem_seg_loading_fn=load_image_into_numpy_array, + num_classes=None, + ignore_label=None, + ): + """ + Args: + dataset_name (str): name of the dataset to be evaluated. + distributed (bool): if True, will collect results from all ranks for evaluation. + Otherwise, will evaluate the results in the current process. + output_dir (str): an output directory to dump results. + sem_seg_loading_fn: function to read sem seg file and load into numpy array. + Default provided, but projects can customize. + num_classes, ignore_label: deprecated argument + """ + self._logger = logging.getLogger(__name__) + if num_classes is not None: + self._logger.warn( + "SemSegEvaluator(num_classes) is deprecated! It should be obtained from metadata." + ) + if ignore_label is not None: + self._logger.warn( + "SemSegEvaluator(ignore_label) is deprecated! It should be obtained from metadata." + ) + self._dataset_name = dataset_name + self._distributed = distributed + self._output_dir = output_dir + + self._cpu_device = torch.device("cpu") + + self.input_file_to_gt_file = { + dataset_record["file_name"]: dataset_record["sem_seg_file_name"] + for dataset_record in DatasetCatalog.get(dataset_name) + } + + meta = MetadataCatalog.get(dataset_name) + # Dict that maps contiguous training ids to COCO category ids + try: + c2d = meta.stuff_dataset_id_to_contiguous_id + self._contiguous_id_to_dataset_id = {v: k for k, v in c2d.items()} + except AttributeError: + self._contiguous_id_to_dataset_id = None + self._class_names = meta.stuff_classes + self.sem_seg_loading_fn = sem_seg_loading_fn + self._num_classes = len(meta.stuff_classes) + if num_classes is not None: + assert self._num_classes == num_classes, f"{self._num_classes} != {num_classes}" + self._ignore_label = ignore_label if ignore_label is not None else meta.ignore_label + + # This is because cv2.erode did not work for int datatype. Only works for uint8. + self._compute_boundary_iou = True + if not _CV2_IMPORTED: + self._compute_boundary_iou = False + self._logger.warn( + """Boundary IoU calculation requires OpenCV. B-IoU metrics are + not going to be computed because OpenCV is not available to import.""" + ) + if self._num_classes >= np.iinfo(np.uint8).max: + self._compute_boundary_iou = False + self._logger.warn( + f"""SemSegEvaluator(num_classes) is more than supported value for Boundary IoU calculation! + B-IoU metrics are not going to be computed. Max allowed value (exclusive) + for num_classes for calculating Boundary IoU is {np.iinfo(np.uint8).max}. + The number of classes of dataset {self._dataset_name} is {self._num_classes}""" + ) + + def reset(self): + self._conf_matrix = np.zeros((self._num_classes + 1, self._num_classes + 1), dtype=np.int64) + self._b_conf_matrix = np.zeros( + (self._num_classes + 1, self._num_classes + 1), dtype=np.int64 + ) + self._predictions = [] + + def process(self, inputs, outputs): + """ + Args: + inputs: the inputs to a model. + It is a list of dicts. Each dict corresponds to an image and + contains keys like "height", "width", "file_name". + outputs: the outputs of a model. It is either list of semantic segmentation predictions + (Tensor [H, W]) or list of dicts with key "sem_seg" that contains semantic + segmentation prediction in the same format. + """ + for input, output in zip(inputs, outputs): + output = output["sem_seg"].argmax(dim=0).to(self._cpu_device) + pred = np.array(output, dtype=np.int) + gt_filename = self.input_file_to_gt_file[input["file_name"]] + gt = self.sem_seg_loading_fn(gt_filename, dtype=np.int) + + gt[gt == self._ignore_label] = self._num_classes + + self._conf_matrix += np.bincount( + (self._num_classes + 1) * pred.reshape(-1) + gt.reshape(-1), + minlength=self._conf_matrix.size, + ).reshape(self._conf_matrix.shape) + + if self._compute_boundary_iou: + b_gt = self._mask_to_boundary(gt.astype(np.uint8)) + b_pred = self._mask_to_boundary(pred.astype(np.uint8)) + + self._b_conf_matrix += np.bincount( + (self._num_classes + 1) * b_pred.reshape(-1) + b_gt.reshape(-1), + minlength=self._conf_matrix.size, + ).reshape(self._conf_matrix.shape) + + self._predictions.extend(self.encode_json_sem_seg(pred, input["file_name"])) + + def evaluate(self): + """ + Evaluates standard semantic segmentation metrics (http://cocodataset.org/#stuff-eval): + + * Mean intersection-over-union averaged across classes (mIoU) + * Frequency Weighted IoU (fwIoU) + * Mean pixel accuracy averaged across classes (mACC) + * Pixel Accuracy (pACC) + """ + if self._distributed: + synchronize() + conf_matrix_list = all_gather(self._conf_matrix) + b_conf_matrix_list = all_gather(self._b_conf_matrix) + self._predictions = all_gather(self._predictions) + self._predictions = list(itertools.chain(*self._predictions)) + if not is_main_process(): + return + + self._conf_matrix = np.zeros_like(self._conf_matrix) + for conf_matrix in conf_matrix_list: + self._conf_matrix += conf_matrix + + self._b_conf_matrix = np.zeros_like(self._b_conf_matrix) + for b_conf_matrix in b_conf_matrix_list: + self._b_conf_matrix += b_conf_matrix + + if self._output_dir: + PathManager.mkdirs(self._output_dir) + file_path = os.path.join(self._output_dir, "sem_seg_predictions.json") + with PathManager.open(file_path, "w") as f: + f.write(json.dumps(self._predictions)) + + acc = np.full(self._num_classes, np.nan, dtype=np.float) + iou = np.full(self._num_classes, np.nan, dtype=np.float) + tp = self._conf_matrix.diagonal()[:-1].astype(np.float) + pos_gt = np.sum(self._conf_matrix[:-1, :-1], axis=0).astype(np.float) + class_weights = pos_gt / np.sum(pos_gt) + pos_pred = np.sum(self._conf_matrix[:-1, :-1], axis=1).astype(np.float) + acc_valid = pos_gt > 0 + acc[acc_valid] = tp[acc_valid] / pos_gt[acc_valid] + union = pos_gt + pos_pred - tp + iou_valid = np.logical_and(acc_valid, union > 0) + iou[iou_valid] = tp[iou_valid] / union[iou_valid] + macc = np.sum(acc[acc_valid]) / np.sum(acc_valid) + miou = np.sum(iou[iou_valid]) / np.sum(iou_valid) + fiou = np.sum(iou[iou_valid] * class_weights[iou_valid]) + pacc = np.sum(tp) / np.sum(pos_gt) + + if self._compute_boundary_iou: + b_iou = np.full(self._num_classes, np.nan, dtype=np.float) + b_tp = self._b_conf_matrix.diagonal()[:-1].astype(np.float) + b_pos_gt = np.sum(self._b_conf_matrix[:-1, :-1], axis=0).astype(np.float) + b_pos_pred = np.sum(self._b_conf_matrix[:-1, :-1], axis=1).astype(np.float) + b_union = b_pos_gt + b_pos_pred - b_tp + b_iou_valid = b_union > 0 + b_iou[b_iou_valid] = b_tp[b_iou_valid] / b_union[b_iou_valid] + + res = {} + res["mIoU"] = 100 * miou + res["fwIoU"] = 100 * fiou + for i, name in enumerate(self._class_names): + res[f"IoU-{name}"] = 100 * iou[i] + if self._compute_boundary_iou: + res[f"BoundaryIoU-{name}"] = 100 * b_iou[i] + res[f"min(IoU, B-Iou)-{name}"] = 100 * min(iou[i], b_iou[i]) + res["mACC"] = 100 * macc + res["pACC"] = 100 * pacc + for i, name in enumerate(self._class_names): + res[f"ACC-{name}"] = 100 * acc[i] + + if self._output_dir: + file_path = os.path.join(self._output_dir, "sem_seg_evaluation.pth") + with PathManager.open(file_path, "wb") as f: + torch.save(res, f) + results = OrderedDict({"sem_seg": res}) + self._logger.info(results) + return results + + def encode_json_sem_seg(self, sem_seg, input_file_name): + """ + Convert semantic segmentation to COCO stuff format with segments encoded as RLEs. + See http://cocodataset.org/#format-results + """ + json_list = [] + for label in np.unique(sem_seg): + if self._contiguous_id_to_dataset_id is not None: + assert ( + label in self._contiguous_id_to_dataset_id + ), "Label {} is not in the metadata info for {}".format(label, self._dataset_name) + dataset_id = self._contiguous_id_to_dataset_id[label] + else: + dataset_id = int(label) + mask = (sem_seg == label).astype(np.uint8) + mask_rle = mask_util.encode(np.array(mask[:, :, None], order="F"))[0] + mask_rle["counts"] = mask_rle["counts"].decode("utf-8") + json_list.append( + {"file_name": input_file_name, "category_id": dataset_id, "segmentation": mask_rle} + ) + return json_list + + def _mask_to_boundary(self, mask: np.ndarray, dilation_ratio=0.02): + assert mask.ndim == 2, "mask_to_boundary expects a 2-dimensional image" + h, w = mask.shape + diag_len = np.sqrt(h**2 + w**2) + dilation = max(1, int(round(dilation_ratio * diag_len))) + kernel = np.ones((3, 3), dtype=np.uint8) + + padded_mask = cv2.copyMakeBorder(mask, 1, 1, 1, 1, cv2.BORDER_CONSTANT, value=0) + eroded_mask_with_padding = cv2.erode(padded_mask, kernel, iterations=dilation) + eroded_mask = eroded_mask_with_padding[1:-1, 1:-1] + boundary = mask - eroded_mask + return boundary diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/testing.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/testing.py new file mode 100644 index 00000000..9e5ae625 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/evaluation/testing.py @@ -0,0 +1,85 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import logging +import numpy as np +import pprint +import sys +from collections.abc import Mapping + + +def print_csv_format(results): + """ + Print main metrics in a format similar to Detectron, + so that they are easy to copypaste into a spreadsheet. + + Args: + results (OrderedDict[dict]): task_name -> {metric -> score} + unordered dict can also be printed, but in arbitrary order + """ + assert isinstance(results, Mapping) or not len(results), results + logger = logging.getLogger(__name__) + for task, res in results.items(): + if isinstance(res, Mapping): + # Don't print "AP-category" metrics since they are usually not tracked. + important_res = [(k, v) for k, v in res.items() if "-" not in k] + logger.info("copypaste: Task: {}".format(task)) + logger.info("copypaste: " + ",".join([k[0] for k in important_res])) + logger.info("copypaste: " + ",".join(["{0:.4f}".format(k[1]) for k in important_res])) + else: + logger.info(f"copypaste: {task}={res}") + + +def verify_results(cfg, results): + """ + Args: + results (OrderedDict[dict]): task_name -> {metric -> score} + + Returns: + bool: whether the verification succeeds or not + """ + expected_results = cfg.TEST.EXPECTED_RESULTS + if not len(expected_results): + return True + + ok = True + for task, metric, expected, tolerance in expected_results: + actual = results[task].get(metric, None) + if actual is None: + ok = False + continue + if not np.isfinite(actual): + ok = False + continue + diff = abs(actual - expected) + if diff > tolerance: + ok = False + + logger = logging.getLogger(__name__) + if not ok: + logger.error("Result verification failed!") + logger.error("Expected Results: " + str(expected_results)) + logger.error("Actual Results: " + pprint.pformat(results)) + + sys.exit(1) + else: + logger.info("Results verification passed.") + return ok + + +def flatten_results_dict(results): + """ + Expand a hierarchical dict of scalars into a flat dict of scalars. + If results[k1][k2][k3] = v, the returned dict will have the entry + {"k1/k2/k3": v}. + + Args: + results (dict): + """ + r = {} + for k, v in results.items(): + if isinstance(v, Mapping): + v = flatten_results_dict(v) + for kk, vv in v.items(): + r[k + "/" + kk] = vv + else: + r[k] = v + return r diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/README.md b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/README.md new file mode 100644 index 00000000..c86ff625 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/README.md @@ -0,0 +1,15 @@ + +This directory contains code to prepare a detectron2 model for deployment. +Currently it supports exporting a detectron2 model to TorchScript, ONNX, or (deprecated) Caffe2 format. + +Please see [documentation](https://detectron2.readthedocs.io/tutorials/deployment.html) for its usage. + + +### Acknowledgements + +Thanks to Mobile Vision team at Facebook for developing the Caffe2 conversion tools. + +Thanks to Computing Platform Department - PAI team at Alibaba Group (@bddpqq, @chenbohua3) who +help export Detectron2 models to TorchScript. + +Thanks to ONNX Converter team at Microsoft who help export Detectron2 models to ONNX. diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/__init__.py new file mode 100644 index 00000000..5a58758f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/__init__.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- + +import warnings + +from .flatten import TracingAdapter +from .torchscript import dump_torchscript_IR, scripting_with_instances + +try: + from caffe2.proto import caffe2_pb2 as _tmp + from caffe2.python import core + + # caffe2 is optional +except ImportError: + pass +else: + from .api import * + + +# TODO: Update ONNX Opset version and run tests when a newer PyTorch is supported +STABLE_ONNX_OPSET_VERSION = 11 + + +def add_export_config(cfg): + warnings.warn( + "add_export_config has been deprecated and behaves as no-op function.", DeprecationWarning + ) + return cfg + + +__all__ = [k for k in globals().keys() if not k.startswith("_")] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/api.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/api.py new file mode 100644 index 00000000..cf1a27a4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/api.py @@ -0,0 +1,230 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import copy +import logging +import os +import torch +from caffe2.proto import caffe2_pb2 +from torch import nn + +from annotator.oneformer.detectron2.config import CfgNode +from annotator.oneformer.detectron2.utils.file_io import PathManager + +from .caffe2_inference import ProtobufDetectionModel +from .caffe2_modeling import META_ARCH_CAFFE2_EXPORT_TYPE_MAP, convert_batched_inputs_to_c2_format +from .shared import get_pb_arg_vali, get_pb_arg_vals, save_graph + +__all__ = [ + "Caffe2Model", + "Caffe2Tracer", +] + + +class Caffe2Tracer: + """ + Make a detectron2 model traceable with Caffe2 operators. + This class creates a traceable version of a detectron2 model which: + + 1. Rewrite parts of the model using ops in Caffe2. Note that some ops do + not have GPU implementation in Caffe2. + 2. Remove post-processing and only produce raw layer outputs + + After making a traceable model, the class provide methods to export such a + model to different deployment formats. + Exported graph produced by this class take two input tensors: + + 1. (1, C, H, W) float "data" which is an image (usually in [0, 255]). + (H, W) often has to be padded to multiple of 32 (depend on the model + architecture). + 2. 1x3 float "im_info", each row of which is (height, width, 1.0). + Height and width are true image shapes before padding. + + The class currently only supports models using builtin meta architectures. + Batch inference is not supported, and contributions are welcome. + """ + + def __init__(self, cfg: CfgNode, model: nn.Module, inputs): + """ + Args: + cfg (CfgNode): a detectron2 config used to construct caffe2-compatible model. + model (nn.Module): An original pytorch model. Must be among a few official models + in detectron2 that can be converted to become caffe2-compatible automatically. + Weights have to be already loaded to this model. + inputs: sample inputs that the given model takes for inference. + Will be used to trace the model. For most models, random inputs with + no detected objects will not work as they lead to wrong traces. + """ + assert isinstance(cfg, CfgNode), cfg + assert isinstance(model, torch.nn.Module), type(model) + + # TODO make it support custom models, by passing in c2 model directly + C2MetaArch = META_ARCH_CAFFE2_EXPORT_TYPE_MAP[cfg.MODEL.META_ARCHITECTURE] + self.traceable_model = C2MetaArch(cfg, copy.deepcopy(model)) + self.inputs = inputs + self.traceable_inputs = self.traceable_model.get_caffe2_inputs(inputs) + + def export_caffe2(self): + """ + Export the model to Caffe2's protobuf format. + The returned object can be saved with its :meth:`.save_protobuf()` method. + The result can be loaded and executed using Caffe2 runtime. + + Returns: + :class:`Caffe2Model` + """ + from .caffe2_export import export_caffe2_detection_model + + predict_net, init_net = export_caffe2_detection_model( + self.traceable_model, self.traceable_inputs + ) + return Caffe2Model(predict_net, init_net) + + def export_onnx(self): + """ + Export the model to ONNX format. + Note that the exported model contains custom ops only available in caffe2, therefore it + cannot be directly executed by other runtime (such as onnxruntime or TensorRT). + Post-processing or transformation passes may be applied on the model to accommodate + different runtimes, but we currently do not provide support for them. + + Returns: + onnx.ModelProto: an onnx model. + """ + from .caffe2_export import export_onnx_model as export_onnx_model_impl + + return export_onnx_model_impl(self.traceable_model, (self.traceable_inputs,)) + + def export_torchscript(self): + """ + Export the model to a ``torch.jit.TracedModule`` by tracing. + The returned object can be saved to a file by ``.save()``. + + Returns: + torch.jit.TracedModule: a torch TracedModule + """ + logger = logging.getLogger(__name__) + logger.info("Tracing the model with torch.jit.trace ...") + with torch.no_grad(): + return torch.jit.trace(self.traceable_model, (self.traceable_inputs,)) + + +class Caffe2Model(nn.Module): + """ + A wrapper around the traced model in Caffe2's protobuf format. + The exported graph has different inputs/outputs from the original Pytorch + model, as explained in :class:`Caffe2Tracer`. This class wraps around the + exported graph to simulate the same interface as the original Pytorch model. + It also provides functions to save/load models in Caffe2's format.' + + Examples: + :: + c2_model = Caffe2Tracer(cfg, torch_model, inputs).export_caffe2() + inputs = [{"image": img_tensor_CHW}] + outputs = c2_model(inputs) + orig_outputs = torch_model(inputs) + """ + + def __init__(self, predict_net, init_net): + super().__init__() + self.eval() # always in eval mode + self._predict_net = predict_net + self._init_net = init_net + self._predictor = None + + __init__.__HIDE_SPHINX_DOC__ = True + + @property + def predict_net(self): + """ + caffe2.core.Net: the underlying caffe2 predict net + """ + return self._predict_net + + @property + def init_net(self): + """ + caffe2.core.Net: the underlying caffe2 init net + """ + return self._init_net + + def save_protobuf(self, output_dir): + """ + Save the model as caffe2's protobuf format. + It saves the following files: + + * "model.pb": definition of the graph. Can be visualized with + tools like `netron `_. + * "model_init.pb": model parameters + * "model.pbtxt": human-readable definition of the graph. Not + needed for deployment. + + Args: + output_dir (str): the output directory to save protobuf files. + """ + logger = logging.getLogger(__name__) + logger.info("Saving model to {} ...".format(output_dir)) + if not PathManager.exists(output_dir): + PathManager.mkdirs(output_dir) + + with PathManager.open(os.path.join(output_dir, "model.pb"), "wb") as f: + f.write(self._predict_net.SerializeToString()) + with PathManager.open(os.path.join(output_dir, "model.pbtxt"), "w") as f: + f.write(str(self._predict_net)) + with PathManager.open(os.path.join(output_dir, "model_init.pb"), "wb") as f: + f.write(self._init_net.SerializeToString()) + + def save_graph(self, output_file, inputs=None): + """ + Save the graph as SVG format. + + Args: + output_file (str): a SVG file + inputs: optional inputs given to the model. + If given, the inputs will be used to run the graph to record + shape of every tensor. The shape information will be + saved together with the graph. + """ + from .caffe2_export import run_and_save_graph + + if inputs is None: + save_graph(self._predict_net, output_file, op_only=False) + else: + size_divisibility = get_pb_arg_vali(self._predict_net, "size_divisibility", 0) + device = get_pb_arg_vals(self._predict_net, "device", b"cpu").decode("ascii") + inputs = convert_batched_inputs_to_c2_format(inputs, size_divisibility, device) + inputs = [x.cpu().numpy() for x in inputs] + run_and_save_graph(self._predict_net, self._init_net, inputs, output_file) + + @staticmethod + def load_protobuf(dir): + """ + Args: + dir (str): a directory used to save Caffe2Model with + :meth:`save_protobuf`. + The files "model.pb" and "model_init.pb" are needed. + + Returns: + Caffe2Model: the caffe2 model loaded from this directory. + """ + predict_net = caffe2_pb2.NetDef() + with PathManager.open(os.path.join(dir, "model.pb"), "rb") as f: + predict_net.ParseFromString(f.read()) + + init_net = caffe2_pb2.NetDef() + with PathManager.open(os.path.join(dir, "model_init.pb"), "rb") as f: + init_net.ParseFromString(f.read()) + + return Caffe2Model(predict_net, init_net) + + def __call__(self, inputs): + """ + An interface that wraps around a Caffe2 model and mimics detectron2's models' + input/output format. See details about the format at :doc:`/tutorials/models`. + This is used to compare the outputs of caffe2 model with its original torch model. + + Due to the extra conversion between Pytorch/Caffe2, this method is not meant for + benchmark. Because of the conversion, this method also has dependency + on detectron2 in order to convert to detectron2's output format. + """ + if self._predictor is None: + self._predictor = ProtobufDetectionModel(self._predict_net, self._init_net) + return self._predictor(inputs) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/c10.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/c10.py new file mode 100644 index 00000000..fde3fb71 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/c10.py @@ -0,0 +1,557 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +import math +from typing import Dict +import torch +import torch.nn.functional as F + +from annotator.oneformer.detectron2.layers import ShapeSpec, cat +from annotator.oneformer.detectron2.layers.roi_align_rotated import ROIAlignRotated +from annotator.oneformer.detectron2.modeling import poolers +from annotator.oneformer.detectron2.modeling.proposal_generator import rpn +from annotator.oneformer.detectron2.modeling.roi_heads.mask_head import mask_rcnn_inference +from annotator.oneformer.detectron2.structures import Boxes, ImageList, Instances, Keypoints, RotatedBoxes + +from .shared import alias, to_device + + +""" +This file contains caffe2-compatible implementation of several detectron2 components. +""" + + +class Caffe2Boxes(Boxes): + """ + Representing a list of detectron2.structures.Boxes from minibatch, each box + is represented by a 5d vector (batch index + 4 coordinates), or a 6d vector + (batch index + 5 coordinates) for RotatedBoxes. + """ + + def __init__(self, tensor): + assert isinstance(tensor, torch.Tensor) + assert tensor.dim() == 2 and tensor.size(-1) in [4, 5, 6], tensor.size() + # TODO: make tensor immutable when dim is Nx5 for Boxes, + # and Nx6 for RotatedBoxes? + self.tensor = tensor + + +# TODO clean up this class, maybe just extend Instances +class InstancesList(object): + """ + Tensor representation of a list of Instances object for a batch of images. + + When dealing with a batch of images with Caffe2 ops, a list of bboxes + (instances) are usually represented by single Tensor with size + (sigma(Ni), 5) or (sigma(Ni), 4) plus a batch split Tensor. This class is + for providing common functions to convert between these two representations. + """ + + def __init__(self, im_info, indices, extra_fields=None): + # [N, 3] -> (H, W, Scale) + self.im_info = im_info + # [N,] -> indice of batch to which the instance belongs + self.indices = indices + # [N, ...] + self.batch_extra_fields = extra_fields or {} + + self.image_size = self.im_info + + def get_fields(self): + """like `get_fields` in the Instances object, + but return each field in tensor representations""" + ret = {} + for k, v in self.batch_extra_fields.items(): + # if isinstance(v, torch.Tensor): + # tensor_rep = v + # elif isinstance(v, (Boxes, Keypoints)): + # tensor_rep = v.tensor + # else: + # raise ValueError("Can't find tensor representation for: {}".format()) + ret[k] = v + return ret + + def has(self, name): + return name in self.batch_extra_fields + + def set(self, name, value): + # len(tensor) is a bad practice that generates ONNX constants during tracing. + # Although not a problem for the `assert` statement below, torch ONNX exporter + # still raises a misleading warning as it does not this call comes from `assert` + if isinstance(value, Boxes): + data_len = value.tensor.shape[0] + elif isinstance(value, torch.Tensor): + data_len = value.shape[0] + else: + data_len = len(value) + if len(self.batch_extra_fields): + assert ( + len(self) == data_len + ), "Adding a field of length {} to a Instances of length {}".format(data_len, len(self)) + self.batch_extra_fields[name] = value + + def __getattr__(self, name): + if name not in self.batch_extra_fields: + raise AttributeError("Cannot find field '{}' in the given Instances!".format(name)) + return self.batch_extra_fields[name] + + def __len__(self): + return len(self.indices) + + def flatten(self): + ret = [] + for _, v in self.batch_extra_fields.items(): + if isinstance(v, (Boxes, Keypoints)): + ret.append(v.tensor) + else: + ret.append(v) + return ret + + @staticmethod + def to_d2_instances_list(instances_list): + """ + Convert InstancesList to List[Instances]. The input `instances_list` can + also be a List[Instances], in this case this method is a non-op. + """ + if not isinstance(instances_list, InstancesList): + assert all(isinstance(x, Instances) for x in instances_list) + return instances_list + + ret = [] + for i, info in enumerate(instances_list.im_info): + instances = Instances(torch.Size([int(info[0].item()), int(info[1].item())])) + + ids = instances_list.indices == i + for k, v in instances_list.batch_extra_fields.items(): + if isinstance(v, torch.Tensor): + instances.set(k, v[ids]) + continue + elif isinstance(v, Boxes): + instances.set(k, v[ids, -4:]) + continue + + target_type, tensor_source = v + assert isinstance(tensor_source, torch.Tensor) + assert tensor_source.shape[0] == instances_list.indices.shape[0] + tensor_source = tensor_source[ids] + + if issubclass(target_type, Boxes): + instances.set(k, Boxes(tensor_source[:, -4:])) + elif issubclass(target_type, Keypoints): + instances.set(k, Keypoints(tensor_source)) + elif issubclass(target_type, torch.Tensor): + instances.set(k, tensor_source) + else: + raise ValueError("Can't handle targe type: {}".format(target_type)) + + ret.append(instances) + return ret + + +class Caffe2Compatible(object): + """ + A model can inherit this class to indicate that it can be traced and deployed with caffe2. + """ + + def _get_tensor_mode(self): + return self._tensor_mode + + def _set_tensor_mode(self, v): + self._tensor_mode = v + + tensor_mode = property(_get_tensor_mode, _set_tensor_mode) + """ + If true, the model expects C2-style tensor only inputs/outputs format. + """ + + +class Caffe2RPN(Caffe2Compatible, rpn.RPN): + @classmethod + def from_config(cls, cfg, input_shape: Dict[str, ShapeSpec]): + ret = super(Caffe2Compatible, cls).from_config(cfg, input_shape) + assert tuple(cfg.MODEL.RPN.BBOX_REG_WEIGHTS) == (1.0, 1.0, 1.0, 1.0) or tuple( + cfg.MODEL.RPN.BBOX_REG_WEIGHTS + ) == (1.0, 1.0, 1.0, 1.0, 1.0) + return ret + + def _generate_proposals( + self, images, objectness_logits_pred, anchor_deltas_pred, gt_instances=None + ): + assert isinstance(images, ImageList) + if self.tensor_mode: + im_info = images.image_sizes + else: + im_info = torch.tensor([[im_sz[0], im_sz[1], 1.0] for im_sz in images.image_sizes]).to( + images.tensor.device + ) + assert isinstance(im_info, torch.Tensor) + + rpn_rois_list = [] + rpn_roi_probs_list = [] + for scores, bbox_deltas, cell_anchors_tensor, feat_stride in zip( + objectness_logits_pred, + anchor_deltas_pred, + [b for (n, b) in self.anchor_generator.cell_anchors.named_buffers()], + self.anchor_generator.strides, + ): + scores = scores.detach() + bbox_deltas = bbox_deltas.detach() + + rpn_rois, rpn_roi_probs = torch.ops._caffe2.GenerateProposals( + scores, + bbox_deltas, + im_info, + cell_anchors_tensor, + spatial_scale=1.0 / feat_stride, + pre_nms_topN=self.pre_nms_topk[self.training], + post_nms_topN=self.post_nms_topk[self.training], + nms_thresh=self.nms_thresh, + min_size=self.min_box_size, + # correct_transform_coords=True, # deprecated argument + angle_bound_on=True, # Default + angle_bound_lo=-180, + angle_bound_hi=180, + clip_angle_thresh=1.0, # Default + legacy_plus_one=False, + ) + rpn_rois_list.append(rpn_rois) + rpn_roi_probs_list.append(rpn_roi_probs) + + # For FPN in D2, in RPN all proposals from different levels are concated + # together, ranked and picked by top post_nms_topk. Then in ROIPooler + # it calculates level_assignments and calls the RoIAlign from + # the corresponding level. + + if len(objectness_logits_pred) == 1: + rpn_rois = rpn_rois_list[0] + rpn_roi_probs = rpn_roi_probs_list[0] + else: + assert len(rpn_rois_list) == len(rpn_roi_probs_list) + rpn_post_nms_topN = self.post_nms_topk[self.training] + + device = rpn_rois_list[0].device + input_list = [to_device(x, "cpu") for x in (rpn_rois_list + rpn_roi_probs_list)] + + # TODO remove this after confirming rpn_max_level/rpn_min_level + # is not needed in CollectRpnProposals. + feature_strides = list(self.anchor_generator.strides) + rpn_min_level = int(math.log2(feature_strides[0])) + rpn_max_level = int(math.log2(feature_strides[-1])) + assert (rpn_max_level - rpn_min_level + 1) == len( + rpn_rois_list + ), "CollectRpnProposals requires continuous levels" + + rpn_rois = torch.ops._caffe2.CollectRpnProposals( + input_list, + # NOTE: in current implementation, rpn_max_level and rpn_min_level + # are not needed, only the subtraction of two matters and it + # can be infer from the number of inputs. Keep them now for + # consistency. + rpn_max_level=2 + len(rpn_rois_list) - 1, + rpn_min_level=2, + rpn_post_nms_topN=rpn_post_nms_topN, + ) + rpn_rois = to_device(rpn_rois, device) + rpn_roi_probs = [] + + proposals = self.c2_postprocess(im_info, rpn_rois, rpn_roi_probs, self.tensor_mode) + return proposals, {} + + def forward(self, images, features, gt_instances=None): + assert not self.training + features = [features[f] for f in self.in_features] + objectness_logits_pred, anchor_deltas_pred = self.rpn_head(features) + return self._generate_proposals( + images, + objectness_logits_pred, + anchor_deltas_pred, + gt_instances, + ) + + @staticmethod + def c2_postprocess(im_info, rpn_rois, rpn_roi_probs, tensor_mode): + proposals = InstancesList( + im_info=im_info, + indices=rpn_rois[:, 0], + extra_fields={ + "proposal_boxes": Caffe2Boxes(rpn_rois), + "objectness_logits": (torch.Tensor, rpn_roi_probs), + }, + ) + if not tensor_mode: + proposals = InstancesList.to_d2_instances_list(proposals) + else: + proposals = [proposals] + return proposals + + +class Caffe2ROIPooler(Caffe2Compatible, poolers.ROIPooler): + @staticmethod + def c2_preprocess(box_lists): + assert all(isinstance(x, Boxes) for x in box_lists) + if all(isinstance(x, Caffe2Boxes) for x in box_lists): + # input is pure-tensor based + assert len(box_lists) == 1 + pooler_fmt_boxes = box_lists[0].tensor + else: + pooler_fmt_boxes = poolers.convert_boxes_to_pooler_format(box_lists) + return pooler_fmt_boxes + + def forward(self, x, box_lists): + assert not self.training + + pooler_fmt_boxes = self.c2_preprocess(box_lists) + num_level_assignments = len(self.level_poolers) + + if num_level_assignments == 1: + if isinstance(self.level_poolers[0], ROIAlignRotated): + c2_roi_align = torch.ops._caffe2.RoIAlignRotated + aligned = True + else: + c2_roi_align = torch.ops._caffe2.RoIAlign + aligned = self.level_poolers[0].aligned + + x0 = x[0] + if x0.is_quantized: + x0 = x0.dequantize() + + out = c2_roi_align( + x0, + pooler_fmt_boxes, + order="NCHW", + spatial_scale=float(self.level_poolers[0].spatial_scale), + pooled_h=int(self.output_size[0]), + pooled_w=int(self.output_size[1]), + sampling_ratio=int(self.level_poolers[0].sampling_ratio), + aligned=aligned, + ) + return out + + device = pooler_fmt_boxes.device + assert ( + self.max_level - self.min_level + 1 == 4 + ), "Currently DistributeFpnProposals only support 4 levels" + fpn_outputs = torch.ops._caffe2.DistributeFpnProposals( + to_device(pooler_fmt_boxes, "cpu"), + roi_canonical_scale=self.canonical_box_size, + roi_canonical_level=self.canonical_level, + roi_max_level=self.max_level, + roi_min_level=self.min_level, + legacy_plus_one=False, + ) + fpn_outputs = [to_device(x, device) for x in fpn_outputs] + + rois_fpn_list = fpn_outputs[:-1] + rois_idx_restore_int32 = fpn_outputs[-1] + + roi_feat_fpn_list = [] + for roi_fpn, x_level, pooler in zip(rois_fpn_list, x, self.level_poolers): + if isinstance(pooler, ROIAlignRotated): + c2_roi_align = torch.ops._caffe2.RoIAlignRotated + aligned = True + else: + c2_roi_align = torch.ops._caffe2.RoIAlign + aligned = bool(pooler.aligned) + + if x_level.is_quantized: + x_level = x_level.dequantize() + + roi_feat_fpn = c2_roi_align( + x_level, + roi_fpn, + order="NCHW", + spatial_scale=float(pooler.spatial_scale), + pooled_h=int(self.output_size[0]), + pooled_w=int(self.output_size[1]), + sampling_ratio=int(pooler.sampling_ratio), + aligned=aligned, + ) + roi_feat_fpn_list.append(roi_feat_fpn) + + roi_feat_shuffled = cat(roi_feat_fpn_list, dim=0) + assert roi_feat_shuffled.numel() > 0 and rois_idx_restore_int32.numel() > 0, ( + "Caffe2 export requires tracing with a model checkpoint + input that can produce valid" + " detections. But no detections were obtained with the given checkpoint and input!" + ) + roi_feat = torch.ops._caffe2.BatchPermutation(roi_feat_shuffled, rois_idx_restore_int32) + return roi_feat + + +class Caffe2FastRCNNOutputsInference: + def __init__(self, tensor_mode): + self.tensor_mode = tensor_mode # whether the output is caffe2 tensor mode + + def __call__(self, box_predictor, predictions, proposals): + """equivalent to FastRCNNOutputLayers.inference""" + num_classes = box_predictor.num_classes + score_thresh = box_predictor.test_score_thresh + nms_thresh = box_predictor.test_nms_thresh + topk_per_image = box_predictor.test_topk_per_image + is_rotated = len(box_predictor.box2box_transform.weights) == 5 + + if is_rotated: + box_dim = 5 + assert box_predictor.box2box_transform.weights[4] == 1, ( + "The weights for Rotated BBoxTransform in C2 have only 4 dimensions," + + " thus enforcing the angle weight to be 1 for now" + ) + box2box_transform_weights = box_predictor.box2box_transform.weights[:4] + else: + box_dim = 4 + box2box_transform_weights = box_predictor.box2box_transform.weights + + class_logits, box_regression = predictions + if num_classes + 1 == class_logits.shape[1]: + class_prob = F.softmax(class_logits, -1) + else: + assert num_classes == class_logits.shape[1] + class_prob = F.sigmoid(class_logits) + # BoxWithNMSLimit will infer num_classes from the shape of the class_prob + # So append a zero column as placeholder for the background class + class_prob = torch.cat((class_prob, torch.zeros(class_prob.shape[0], 1)), dim=1) + + assert box_regression.shape[1] % box_dim == 0 + cls_agnostic_bbox_reg = box_regression.shape[1] // box_dim == 1 + + input_tensor_mode = proposals[0].proposal_boxes.tensor.shape[1] == box_dim + 1 + + proposal_boxes = proposals[0].proposal_boxes + if isinstance(proposal_boxes, Caffe2Boxes): + rois = Caffe2Boxes.cat([p.proposal_boxes for p in proposals]) + elif isinstance(proposal_boxes, RotatedBoxes): + rois = RotatedBoxes.cat([p.proposal_boxes for p in proposals]) + elif isinstance(proposal_boxes, Boxes): + rois = Boxes.cat([p.proposal_boxes for p in proposals]) + else: + raise NotImplementedError( + 'Expected proposals[0].proposal_boxes to be type "Boxes", ' + f"instead got {type(proposal_boxes)}" + ) + + device, dtype = rois.tensor.device, rois.tensor.dtype + if input_tensor_mode: + im_info = proposals[0].image_size + rois = rois.tensor + else: + im_info = torch.tensor( + [[sz[0], sz[1], 1.0] for sz in [x.image_size for x in proposals]] + ) + batch_ids = cat( + [ + torch.full((b, 1), i, dtype=dtype, device=device) + for i, b in enumerate(len(p) for p in proposals) + ], + dim=0, + ) + rois = torch.cat([batch_ids, rois.tensor], dim=1) + + roi_pred_bbox, roi_batch_splits = torch.ops._caffe2.BBoxTransform( + to_device(rois, "cpu"), + to_device(box_regression, "cpu"), + to_device(im_info, "cpu"), + weights=box2box_transform_weights, + apply_scale=True, + rotated=is_rotated, + angle_bound_on=True, + angle_bound_lo=-180, + angle_bound_hi=180, + clip_angle_thresh=1.0, + legacy_plus_one=False, + ) + roi_pred_bbox = to_device(roi_pred_bbox, device) + roi_batch_splits = to_device(roi_batch_splits, device) + + nms_outputs = torch.ops._caffe2.BoxWithNMSLimit( + to_device(class_prob, "cpu"), + to_device(roi_pred_bbox, "cpu"), + to_device(roi_batch_splits, "cpu"), + score_thresh=float(score_thresh), + nms=float(nms_thresh), + detections_per_im=int(topk_per_image), + soft_nms_enabled=False, + soft_nms_method="linear", + soft_nms_sigma=0.5, + soft_nms_min_score_thres=0.001, + rotated=is_rotated, + cls_agnostic_bbox_reg=cls_agnostic_bbox_reg, + input_boxes_include_bg_cls=False, + output_classes_include_bg_cls=False, + legacy_plus_one=False, + ) + roi_score_nms = to_device(nms_outputs[0], device) + roi_bbox_nms = to_device(nms_outputs[1], device) + roi_class_nms = to_device(nms_outputs[2], device) + roi_batch_splits_nms = to_device(nms_outputs[3], device) + roi_keeps_nms = to_device(nms_outputs[4], device) + roi_keeps_size_nms = to_device(nms_outputs[5], device) + if not self.tensor_mode: + roi_class_nms = roi_class_nms.to(torch.int64) + + roi_batch_ids = cat( + [ + torch.full((b, 1), i, dtype=dtype, device=device) + for i, b in enumerate(int(x.item()) for x in roi_batch_splits_nms) + ], + dim=0, + ) + + roi_class_nms = alias(roi_class_nms, "class_nms") + roi_score_nms = alias(roi_score_nms, "score_nms") + roi_bbox_nms = alias(roi_bbox_nms, "bbox_nms") + roi_batch_splits_nms = alias(roi_batch_splits_nms, "batch_splits_nms") + roi_keeps_nms = alias(roi_keeps_nms, "keeps_nms") + roi_keeps_size_nms = alias(roi_keeps_size_nms, "keeps_size_nms") + + results = InstancesList( + im_info=im_info, + indices=roi_batch_ids[:, 0], + extra_fields={ + "pred_boxes": Caffe2Boxes(roi_bbox_nms), + "scores": roi_score_nms, + "pred_classes": roi_class_nms, + }, + ) + + if not self.tensor_mode: + results = InstancesList.to_d2_instances_list(results) + batch_splits = roi_batch_splits_nms.int().tolist() + kept_indices = list(roi_keeps_nms.to(torch.int64).split(batch_splits)) + else: + results = [results] + kept_indices = [roi_keeps_nms] + + return results, kept_indices + + +class Caffe2MaskRCNNInference: + def __call__(self, pred_mask_logits, pred_instances): + """equivalent to mask_head.mask_rcnn_inference""" + if all(isinstance(x, InstancesList) for x in pred_instances): + assert len(pred_instances) == 1 + mask_probs_pred = pred_mask_logits.sigmoid() + mask_probs_pred = alias(mask_probs_pred, "mask_fcn_probs") + pred_instances[0].set("pred_masks", mask_probs_pred) + else: + mask_rcnn_inference(pred_mask_logits, pred_instances) + + +class Caffe2KeypointRCNNInference: + def __init__(self, use_heatmap_max_keypoint): + self.use_heatmap_max_keypoint = use_heatmap_max_keypoint + + def __call__(self, pred_keypoint_logits, pred_instances): + # just return the keypoint heatmap for now, + # there will be option to call HeatmapMaxKeypointOp + output = alias(pred_keypoint_logits, "kps_score") + if all(isinstance(x, InstancesList) for x in pred_instances): + assert len(pred_instances) == 1 + if self.use_heatmap_max_keypoint: + device = output.device + output = torch.ops._caffe2.HeatmapMaxKeypoint( + to_device(output, "cpu"), + pred_instances[0].pred_boxes.tensor, + should_output_softmax=True, # worth make it configerable? + ) + output = to_device(output, device) + output = alias(output, "keypoints_out") + pred_instances[0].set("pred_keypoints", output) + return pred_keypoint_logits diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/caffe2_export.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/caffe2_export.py new file mode 100644 index 00000000..d609c27c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/caffe2_export.py @@ -0,0 +1,203 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +import copy +import io +import logging +import numpy as np +from typing import List +import onnx +import onnx.optimizer +import torch +from caffe2.proto import caffe2_pb2 +from caffe2.python import core +from caffe2.python.onnx.backend import Caffe2Backend +from tabulate import tabulate +from termcolor import colored +from torch.onnx import OperatorExportTypes + +from .shared import ( + ScopedWS, + construct_init_net_from_params, + fuse_alias_placeholder, + fuse_copy_between_cpu_and_gpu, + get_params_from_init_net, + group_norm_replace_aten_with_caffe2, + infer_device_type, + remove_dead_end_ops, + remove_reshape_for_fc, + save_graph, +) + +logger = logging.getLogger(__name__) + + +def export_onnx_model(model, inputs): + """ + Trace and export a model to onnx format. + + Args: + model (nn.Module): + inputs (tuple[args]): the model will be called by `model(*inputs)` + + Returns: + an onnx model + """ + assert isinstance(model, torch.nn.Module) + + # make sure all modules are in eval mode, onnx may change the training state + # of the module if the states are not consistent + def _check_eval(module): + assert not module.training + + model.apply(_check_eval) + + # Export the model to ONNX + with torch.no_grad(): + with io.BytesIO() as f: + torch.onnx.export( + model, + inputs, + f, + operator_export_type=OperatorExportTypes.ONNX_ATEN_FALLBACK, + # verbose=True, # NOTE: uncomment this for debugging + # export_params=True, + ) + onnx_model = onnx.load_from_string(f.getvalue()) + + return onnx_model + + +def _op_stats(net_def): + type_count = {} + for t in [op.type for op in net_def.op]: + type_count[t] = type_count.get(t, 0) + 1 + type_count_list = sorted(type_count.items(), key=lambda kv: kv[0]) # alphabet + type_count_list = sorted(type_count_list, key=lambda kv: -kv[1]) # count + return "\n".join("{:>4}x {}".format(count, name) for name, count in type_count_list) + + +def _assign_device_option( + predict_net: caffe2_pb2.NetDef, init_net: caffe2_pb2.NetDef, tensor_inputs: List[torch.Tensor] +): + """ + ONNX exported network doesn't have concept of device, assign necessary + device option for each op in order to make it runable on GPU runtime. + """ + + def _get_device_type(torch_tensor): + assert torch_tensor.device.type in ["cpu", "cuda"] + assert torch_tensor.device.index == 0 + return torch_tensor.device.type + + def _assign_op_device_option(net_proto, net_ssa, blob_device_types): + for op, ssa_i in zip(net_proto.op, net_ssa): + if op.type in ["CopyCPUToGPU", "CopyGPUToCPU"]: + op.device_option.CopyFrom(core.DeviceOption(caffe2_pb2.CUDA, 0)) + else: + devices = [blob_device_types[b] for b in ssa_i[0] + ssa_i[1]] + assert all(d == devices[0] for d in devices) + if devices[0] == "cuda": + op.device_option.CopyFrom(core.DeviceOption(caffe2_pb2.CUDA, 0)) + + # update ops in predict_net + predict_net_input_device_types = { + (name, 0): _get_device_type(tensor) + for name, tensor in zip(predict_net.external_input, tensor_inputs) + } + predict_net_device_types = infer_device_type( + predict_net, known_status=predict_net_input_device_types, device_name_style="pytorch" + ) + predict_net_ssa, _ = core.get_ssa(predict_net) + _assign_op_device_option(predict_net, predict_net_ssa, predict_net_device_types) + + # update ops in init_net + init_net_ssa, versions = core.get_ssa(init_net) + init_net_output_device_types = { + (name, versions[name]): predict_net_device_types[(name, 0)] + for name in init_net.external_output + } + init_net_device_types = infer_device_type( + init_net, known_status=init_net_output_device_types, device_name_style="pytorch" + ) + _assign_op_device_option(init_net, init_net_ssa, init_net_device_types) + + +def export_caffe2_detection_model(model: torch.nn.Module, tensor_inputs: List[torch.Tensor]): + """ + Export a caffe2-compatible Detectron2 model to caffe2 format via ONNX. + + Arg: + model: a caffe2-compatible version of detectron2 model, defined in caffe2_modeling.py + tensor_inputs: a list of tensors that caffe2 model takes as input. + """ + model = copy.deepcopy(model) + assert isinstance(model, torch.nn.Module) + assert hasattr(model, "encode_additional_info") + + # Export via ONNX + logger.info( + "Exporting a {} model via ONNX ...".format(type(model).__name__) + + " Some warnings from ONNX are expected and are usually not to worry about." + ) + onnx_model = export_onnx_model(model, (tensor_inputs,)) + # Convert ONNX model to Caffe2 protobuf + init_net, predict_net = Caffe2Backend.onnx_graph_to_caffe2_net(onnx_model) + ops_table = [[op.type, op.input, op.output] for op in predict_net.op] + table = tabulate(ops_table, headers=["type", "input", "output"], tablefmt="pipe") + logger.info( + "ONNX export Done. Exported predict_net (before optimizations):\n" + colored(table, "cyan") + ) + + # Apply protobuf optimization + fuse_alias_placeholder(predict_net, init_net) + if any(t.device.type != "cpu" for t in tensor_inputs): + fuse_copy_between_cpu_and_gpu(predict_net) + remove_dead_end_ops(init_net) + _assign_device_option(predict_net, init_net, tensor_inputs) + params, device_options = get_params_from_init_net(init_net) + predict_net, params = remove_reshape_for_fc(predict_net, params) + init_net = construct_init_net_from_params(params, device_options) + group_norm_replace_aten_with_caffe2(predict_net) + + # Record necessary information for running the pb model in Detectron2 system. + model.encode_additional_info(predict_net, init_net) + + logger.info("Operators used in predict_net: \n{}".format(_op_stats(predict_net))) + logger.info("Operators used in init_net: \n{}".format(_op_stats(init_net))) + + return predict_net, init_net + + +def run_and_save_graph(predict_net, init_net, tensor_inputs, graph_save_path): + """ + Run the caffe2 model on given inputs, recording the shape and draw the graph. + + predict_net/init_net: caffe2 model. + tensor_inputs: a list of tensors that caffe2 model takes as input. + graph_save_path: path for saving graph of exported model. + """ + + logger.info("Saving graph of ONNX exported model to {} ...".format(graph_save_path)) + save_graph(predict_net, graph_save_path, op_only=False) + + # Run the exported Caffe2 net + logger.info("Running ONNX exported model ...") + with ScopedWS("__ws_tmp__", True) as ws: + ws.RunNetOnce(init_net) + initialized_blobs = set(ws.Blobs()) + uninitialized = [inp for inp in predict_net.external_input if inp not in initialized_blobs] + for name, blob in zip(uninitialized, tensor_inputs): + ws.FeedBlob(name, blob) + + try: + ws.RunNetOnce(predict_net) + except RuntimeError as e: + logger.warning("Encountered RuntimeError: \n{}".format(str(e))) + + ws_blobs = {b: ws.FetchBlob(b) for b in ws.Blobs()} + blob_sizes = {b: ws_blobs[b].shape for b in ws_blobs if isinstance(ws_blobs[b], np.ndarray)} + + logger.info("Saving graph with blob shapes to {} ...".format(graph_save_path)) + save_graph(predict_net, graph_save_path, op_only=False, blob_sizes=blob_sizes) + + return ws_blobs diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/caffe2_inference.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/caffe2_inference.py new file mode 100644 index 00000000..deb886c0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/caffe2_inference.py @@ -0,0 +1,161 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +import logging +import numpy as np +from itertools import count +import torch +from caffe2.proto import caffe2_pb2 +from caffe2.python import core + +from .caffe2_modeling import META_ARCH_CAFFE2_EXPORT_TYPE_MAP, convert_batched_inputs_to_c2_format +from .shared import ScopedWS, get_pb_arg_vali, get_pb_arg_vals, infer_device_type + +logger = logging.getLogger(__name__) + + +# ===== ref: mobile-vision predictor's 'Caffe2Wrapper' class ====== +class ProtobufModel(torch.nn.Module): + """ + Wrapper of a caffe2's protobuf model. + It works just like nn.Module, but running caffe2 under the hood. + Input/Output are tuple[tensor] that match the caffe2 net's external_input/output. + """ + + _ids = count(0) + + def __init__(self, predict_net, init_net): + logger.info(f"Initializing ProtobufModel for: {predict_net.name} ...") + super().__init__() + assert isinstance(predict_net, caffe2_pb2.NetDef) + assert isinstance(init_net, caffe2_pb2.NetDef) + # create unique temporary workspace for each instance + self.ws_name = "__tmp_ProtobufModel_{}__".format(next(self._ids)) + self.net = core.Net(predict_net) + + logger.info("Running init_net once to fill the parameters ...") + with ScopedWS(self.ws_name, is_reset=True, is_cleanup=False) as ws: + ws.RunNetOnce(init_net) + uninitialized_external_input = [] + for blob in self.net.Proto().external_input: + if blob not in ws.Blobs(): + uninitialized_external_input.append(blob) + ws.CreateBlob(blob) + ws.CreateNet(self.net) + + self._error_msgs = set() + self._input_blobs = uninitialized_external_input + + def _infer_output_devices(self, inputs): + """ + Returns: + list[str]: list of device for each external output + """ + + def _get_device_type(torch_tensor): + assert torch_tensor.device.type in ["cpu", "cuda"] + assert torch_tensor.device.index == 0 + return torch_tensor.device.type + + predict_net = self.net.Proto() + input_device_types = { + (name, 0): _get_device_type(tensor) for name, tensor in zip(self._input_blobs, inputs) + } + device_type_map = infer_device_type( + predict_net, known_status=input_device_types, device_name_style="pytorch" + ) + ssa, versions = core.get_ssa(predict_net) + versioned_outputs = [(name, versions[name]) for name in predict_net.external_output] + output_devices = [device_type_map[outp] for outp in versioned_outputs] + return output_devices + + def forward(self, inputs): + """ + Args: + inputs (tuple[torch.Tensor]) + + Returns: + tuple[torch.Tensor] + """ + assert len(inputs) == len(self._input_blobs), ( + f"Length of inputs ({len(inputs)}) " + f"doesn't match the required input blobs: {self._input_blobs}" + ) + + with ScopedWS(self.ws_name, is_reset=False, is_cleanup=False) as ws: + for b, tensor in zip(self._input_blobs, inputs): + ws.FeedBlob(b, tensor) + + try: + ws.RunNet(self.net.Proto().name) + except RuntimeError as e: + if not str(e) in self._error_msgs: + self._error_msgs.add(str(e)) + logger.warning("Encountered new RuntimeError: \n{}".format(str(e))) + logger.warning("Catch the error and use partial results.") + + c2_outputs = [ws.FetchBlob(b) for b in self.net.Proto().external_output] + # Remove outputs of current run, this is necessary in order to + # prevent fetching the result from previous run if the model fails + # in the middle. + for b in self.net.Proto().external_output: + # Needs to create uninitialized blob to make the net runable. + # This is "equivalent" to: ws.RemoveBlob(b) then ws.CreateBlob(b), + # but there'no such API. + ws.FeedBlob(b, f"{b}, a C++ native class of type nullptr (uninitialized).") + + # Cast output to torch.Tensor on the desired device + output_devices = ( + self._infer_output_devices(inputs) + if any(t.device.type != "cpu" for t in inputs) + else ["cpu" for _ in self.net.Proto().external_output] + ) + + outputs = [] + for name, c2_output, device in zip( + self.net.Proto().external_output, c2_outputs, output_devices + ): + if not isinstance(c2_output, np.ndarray): + raise RuntimeError( + "Invalid output for blob {}, received: {}".format(name, c2_output) + ) + outputs.append(torch.tensor(c2_output).to(device=device)) + return tuple(outputs) + + +class ProtobufDetectionModel(torch.nn.Module): + """ + A class works just like a pytorch meta arch in terms of inference, but running + caffe2 model under the hood. + """ + + def __init__(self, predict_net, init_net, *, convert_outputs=None): + """ + Args: + predict_net, init_net (core.Net): caffe2 nets + convert_outptus (callable): a function that converts caffe2 + outputs to the same format of the original pytorch model. + By default, use the one defined in the caffe2 meta_arch. + """ + super().__init__() + self.protobuf_model = ProtobufModel(predict_net, init_net) + self.size_divisibility = get_pb_arg_vali(predict_net, "size_divisibility", 0) + self.device = get_pb_arg_vals(predict_net, "device", b"cpu").decode("ascii") + + if convert_outputs is None: + meta_arch = get_pb_arg_vals(predict_net, "meta_architecture", b"GeneralizedRCNN") + meta_arch = META_ARCH_CAFFE2_EXPORT_TYPE_MAP[meta_arch.decode("ascii")] + self._convert_outputs = meta_arch.get_outputs_converter(predict_net, init_net) + else: + self._convert_outputs = convert_outputs + + def _convert_inputs(self, batched_inputs): + # currently all models convert inputs in the same way + return convert_batched_inputs_to_c2_format( + batched_inputs, self.size_divisibility, self.device + ) + + def forward(self, batched_inputs): + c2_inputs = self._convert_inputs(batched_inputs) + c2_results = self.protobuf_model(c2_inputs) + c2_results = dict(zip(self.protobuf_model.net.Proto().external_output, c2_results)) + return self._convert_outputs(batched_inputs, c2_inputs, c2_results) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/caffe2_modeling.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/caffe2_modeling.py new file mode 100644 index 00000000..e0128e46 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/caffe2_modeling.py @@ -0,0 +1,419 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +import functools +import io +import struct +import types +import torch + +from annotator.oneformer.detectron2.modeling import meta_arch +from annotator.oneformer.detectron2.modeling.box_regression import Box2BoxTransform +from annotator.oneformer.detectron2.modeling.roi_heads import keypoint_head +from annotator.oneformer.detectron2.structures import Boxes, ImageList, Instances, RotatedBoxes + +from .c10 import Caffe2Compatible +from .caffe2_patch import ROIHeadsPatcher, patch_generalized_rcnn +from .shared import ( + alias, + check_set_pb_arg, + get_pb_arg_floats, + get_pb_arg_valf, + get_pb_arg_vali, + get_pb_arg_vals, + mock_torch_nn_functional_interpolate, +) + + +def assemble_rcnn_outputs_by_name(image_sizes, tensor_outputs, force_mask_on=False): + """ + A function to assemble caffe2 model's outputs (i.e. Dict[str, Tensor]) + to detectron2's format (i.e. list of Instances instance). + This only works when the model follows the Caffe2 detectron's naming convention. + + Args: + image_sizes (List[List[int, int]]): [H, W] of every image. + tensor_outputs (Dict[str, Tensor]): external_output to its tensor. + + force_mask_on (Bool): if true, the it make sure there'll be pred_masks even + if the mask is not found from tensor_outputs (usually due to model crash) + """ + + results = [Instances(image_size) for image_size in image_sizes] + + batch_splits = tensor_outputs.get("batch_splits", None) + if batch_splits: + raise NotImplementedError() + assert len(image_sizes) == 1 + result = results[0] + + bbox_nms = tensor_outputs["bbox_nms"] + score_nms = tensor_outputs["score_nms"] + class_nms = tensor_outputs["class_nms"] + # Detection will always success because Conv support 0-batch + assert bbox_nms is not None + assert score_nms is not None + assert class_nms is not None + if bbox_nms.shape[1] == 5: + result.pred_boxes = RotatedBoxes(bbox_nms) + else: + result.pred_boxes = Boxes(bbox_nms) + result.scores = score_nms + result.pred_classes = class_nms.to(torch.int64) + + mask_fcn_probs = tensor_outputs.get("mask_fcn_probs", None) + if mask_fcn_probs is not None: + # finish the mask pred + mask_probs_pred = mask_fcn_probs + num_masks = mask_probs_pred.shape[0] + class_pred = result.pred_classes + indices = torch.arange(num_masks, device=class_pred.device) + mask_probs_pred = mask_probs_pred[indices, class_pred][:, None] + result.pred_masks = mask_probs_pred + elif force_mask_on: + # NOTE: there's no way to know the height/width of mask here, it won't be + # used anyway when batch size is 0, so just set them to 0. + result.pred_masks = torch.zeros([0, 1, 0, 0], dtype=torch.uint8) + + keypoints_out = tensor_outputs.get("keypoints_out", None) + kps_score = tensor_outputs.get("kps_score", None) + if keypoints_out is not None: + # keypoints_out: [N, 4, #kypoints], where 4 is in order of (x, y, score, prob) + keypoints_tensor = keypoints_out + # NOTE: it's possible that prob is not calculated if "should_output_softmax" + # is set to False in HeatmapMaxKeypoint, so just using raw score, seems + # it doesn't affect mAP. TODO: check more carefully. + keypoint_xyp = keypoints_tensor.transpose(1, 2)[:, :, [0, 1, 2]] + result.pred_keypoints = keypoint_xyp + elif kps_score is not None: + # keypoint heatmap to sparse data structure + pred_keypoint_logits = kps_score + keypoint_head.keypoint_rcnn_inference(pred_keypoint_logits, [result]) + + return results + + +def _cast_to_f32(f64): + return struct.unpack("f", struct.pack("f", f64))[0] + + +def set_caffe2_compatible_tensor_mode(model, enable=True): + def _fn(m): + if isinstance(m, Caffe2Compatible): + m.tensor_mode = enable + + model.apply(_fn) + + +def convert_batched_inputs_to_c2_format(batched_inputs, size_divisibility, device): + """ + See get_caffe2_inputs() below. + """ + assert all(isinstance(x, dict) for x in batched_inputs) + assert all(x["image"].dim() == 3 for x in batched_inputs) + + images = [x["image"] for x in batched_inputs] + images = ImageList.from_tensors(images, size_divisibility) + + im_info = [] + for input_per_image, image_size in zip(batched_inputs, images.image_sizes): + target_height = input_per_image.get("height", image_size[0]) + target_width = input_per_image.get("width", image_size[1]) # noqa + # NOTE: The scale inside im_info is kept as convention and for providing + # post-processing information if further processing is needed. For + # current Caffe2 model definitions that don't include post-processing inside + # the model, this number is not used. + # NOTE: There can be a slight difference between width and height + # scales, using a single number can results in numerical difference + # compared with D2's post-processing. + scale = target_height / image_size[0] + im_info.append([image_size[0], image_size[1], scale]) + im_info = torch.Tensor(im_info) + + return images.tensor.to(device), im_info.to(device) + + +class Caffe2MetaArch(Caffe2Compatible, torch.nn.Module): + """ + Base class for caffe2-compatible implementation of a meta architecture. + The forward is traceable and its traced graph can be converted to caffe2 + graph through ONNX. + """ + + def __init__(self, cfg, torch_model): + """ + Args: + cfg (CfgNode): + torch_model (nn.Module): the detectron2 model (meta_arch) to be + converted. + """ + super().__init__() + self._wrapped_model = torch_model + self.eval() + set_caffe2_compatible_tensor_mode(self, True) + + def get_caffe2_inputs(self, batched_inputs): + """ + Convert pytorch-style structured inputs to caffe2-style inputs that + are tuples of tensors. + + Args: + batched_inputs (list[dict]): inputs to a detectron2 model + in its standard format. Each dict has "image" (CHW tensor), and optionally + "height" and "width". + + Returns: + tuple[Tensor]: + tuple of tensors that will be the inputs to the + :meth:`forward` method. For existing models, the first + is an NCHW tensor (padded and batched); the second is + a im_info Nx3 tensor, where the rows are + (height, width, unused legacy parameter) + """ + return convert_batched_inputs_to_c2_format( + batched_inputs, + self._wrapped_model.backbone.size_divisibility, + self._wrapped_model.device, + ) + + def encode_additional_info(self, predict_net, init_net): + """ + Save extra metadata that will be used by inference in the output protobuf. + """ + pass + + def forward(self, inputs): + """ + Run the forward in caffe2-style. It has to use caffe2-compatible ops + and the method will be used for tracing. + + Args: + inputs (tuple[Tensor]): inputs defined by :meth:`get_caffe2_input`. + They will be the inputs of the converted caffe2 graph. + + Returns: + tuple[Tensor]: output tensors. They will be the outputs of the + converted caffe2 graph. + """ + raise NotImplementedError + + def _caffe2_preprocess_image(self, inputs): + """ + Caffe2 implementation of preprocess_image, which is called inside each MetaArch's forward. + It normalizes the input images, and the final caffe2 graph assumes the + inputs have been batched already. + """ + data, im_info = inputs + data = alias(data, "data") + im_info = alias(im_info, "im_info") + mean, std = self._wrapped_model.pixel_mean, self._wrapped_model.pixel_std + normalized_data = (data - mean) / std + normalized_data = alias(normalized_data, "normalized_data") + + # Pack (data, im_info) into ImageList which is recognized by self.inference. + images = ImageList(tensor=normalized_data, image_sizes=im_info) + return images + + @staticmethod + def get_outputs_converter(predict_net, init_net): + """ + Creates a function that converts outputs of the caffe2 model to + detectron2's standard format. + The function uses information in `predict_net` and `init_net` that are + available at inferene time. Therefore the function logic can be used in inference. + + The returned function has the following signature: + + def convert(batched_inputs, c2_inputs, c2_results) -> detectron2_outputs + + Where + + * batched_inputs (list[dict]): the original input format of the meta arch + * c2_inputs (tuple[Tensor]): the caffe2 inputs. + * c2_results (dict[str, Tensor]): the caffe2 output format, + corresponding to the outputs of the :meth:`forward` function. + * detectron2_outputs: the original output format of the meta arch. + + This function can be used to compare the outputs of the original meta arch and + the converted caffe2 graph. + + Returns: + callable: a callable of the above signature. + """ + raise NotImplementedError + + +class Caffe2GeneralizedRCNN(Caffe2MetaArch): + def __init__(self, cfg, torch_model): + assert isinstance(torch_model, meta_arch.GeneralizedRCNN) + torch_model = patch_generalized_rcnn(torch_model) + super().__init__(cfg, torch_model) + + try: + use_heatmap_max_keypoint = cfg.EXPORT_CAFFE2.USE_HEATMAP_MAX_KEYPOINT + except AttributeError: + use_heatmap_max_keypoint = False + self.roi_heads_patcher = ROIHeadsPatcher( + self._wrapped_model.roi_heads, use_heatmap_max_keypoint + ) + + def encode_additional_info(self, predict_net, init_net): + size_divisibility = self._wrapped_model.backbone.size_divisibility + check_set_pb_arg(predict_net, "size_divisibility", "i", size_divisibility) + check_set_pb_arg( + predict_net, "device", "s", str.encode(str(self._wrapped_model.device), "ascii") + ) + check_set_pb_arg(predict_net, "meta_architecture", "s", b"GeneralizedRCNN") + + @mock_torch_nn_functional_interpolate() + def forward(self, inputs): + if not self.tensor_mode: + return self._wrapped_model.inference(inputs) + images = self._caffe2_preprocess_image(inputs) + features = self._wrapped_model.backbone(images.tensor) + proposals, _ = self._wrapped_model.proposal_generator(images, features) + with self.roi_heads_patcher.mock_roi_heads(): + detector_results, _ = self._wrapped_model.roi_heads(images, features, proposals) + return tuple(detector_results[0].flatten()) + + @staticmethod + def get_outputs_converter(predict_net, init_net): + def f(batched_inputs, c2_inputs, c2_results): + _, im_info = c2_inputs + image_sizes = [[int(im[0]), int(im[1])] for im in im_info] + results = assemble_rcnn_outputs_by_name(image_sizes, c2_results) + return meta_arch.GeneralizedRCNN._postprocess(results, batched_inputs, image_sizes) + + return f + + +class Caffe2RetinaNet(Caffe2MetaArch): + def __init__(self, cfg, torch_model): + assert isinstance(torch_model, meta_arch.RetinaNet) + super().__init__(cfg, torch_model) + + @mock_torch_nn_functional_interpolate() + def forward(self, inputs): + assert self.tensor_mode + images = self._caffe2_preprocess_image(inputs) + + # explicitly return the images sizes to avoid removing "im_info" by ONNX + # since it's not used in the forward path + return_tensors = [images.image_sizes] + + features = self._wrapped_model.backbone(images.tensor) + features = [features[f] for f in self._wrapped_model.head_in_features] + for i, feature_i in enumerate(features): + features[i] = alias(feature_i, "feature_{}".format(i), is_backward=True) + return_tensors.append(features[i]) + + pred_logits, pred_anchor_deltas = self._wrapped_model.head(features) + for i, (box_cls_i, box_delta_i) in enumerate(zip(pred_logits, pred_anchor_deltas)): + return_tensors.append(alias(box_cls_i, "box_cls_{}".format(i))) + return_tensors.append(alias(box_delta_i, "box_delta_{}".format(i))) + + return tuple(return_tensors) + + def encode_additional_info(self, predict_net, init_net): + size_divisibility = self._wrapped_model.backbone.size_divisibility + check_set_pb_arg(predict_net, "size_divisibility", "i", size_divisibility) + check_set_pb_arg( + predict_net, "device", "s", str.encode(str(self._wrapped_model.device), "ascii") + ) + check_set_pb_arg(predict_net, "meta_architecture", "s", b"RetinaNet") + + # Inference parameters: + check_set_pb_arg( + predict_net, "score_threshold", "f", _cast_to_f32(self._wrapped_model.test_score_thresh) + ) + check_set_pb_arg( + predict_net, "topk_candidates", "i", self._wrapped_model.test_topk_candidates + ) + check_set_pb_arg( + predict_net, "nms_threshold", "f", _cast_to_f32(self._wrapped_model.test_nms_thresh) + ) + check_set_pb_arg( + predict_net, + "max_detections_per_image", + "i", + self._wrapped_model.max_detections_per_image, + ) + + check_set_pb_arg( + predict_net, + "bbox_reg_weights", + "floats", + [_cast_to_f32(w) for w in self._wrapped_model.box2box_transform.weights], + ) + self._encode_anchor_generator_cfg(predict_net) + + def _encode_anchor_generator_cfg(self, predict_net): + # serialize anchor_generator for future use + serialized_anchor_generator = io.BytesIO() + torch.save(self._wrapped_model.anchor_generator, serialized_anchor_generator) + # Ideally we can put anchor generating inside the model, then we don't + # need to store this information. + bytes = serialized_anchor_generator.getvalue() + check_set_pb_arg(predict_net, "serialized_anchor_generator", "s", bytes) + + @staticmethod + def get_outputs_converter(predict_net, init_net): + self = types.SimpleNamespace() + serialized_anchor_generator = io.BytesIO( + get_pb_arg_vals(predict_net, "serialized_anchor_generator", None) + ) + self.anchor_generator = torch.load(serialized_anchor_generator) + bbox_reg_weights = get_pb_arg_floats(predict_net, "bbox_reg_weights", None) + self.box2box_transform = Box2BoxTransform(weights=tuple(bbox_reg_weights)) + self.test_score_thresh = get_pb_arg_valf(predict_net, "score_threshold", None) + self.test_topk_candidates = get_pb_arg_vali(predict_net, "topk_candidates", None) + self.test_nms_thresh = get_pb_arg_valf(predict_net, "nms_threshold", None) + self.max_detections_per_image = get_pb_arg_vali( + predict_net, "max_detections_per_image", None + ) + + # hack to reuse inference code from RetinaNet + for meth in [ + "forward_inference", + "inference_single_image", + "_transpose_dense_predictions", + "_decode_multi_level_predictions", + "_decode_per_level_predictions", + ]: + setattr(self, meth, functools.partial(getattr(meta_arch.RetinaNet, meth), self)) + + def f(batched_inputs, c2_inputs, c2_results): + _, im_info = c2_inputs + image_sizes = [[int(im[0]), int(im[1])] for im in im_info] + dummy_images = ImageList( + torch.randn( + ( + len(im_info), + 3, + ) + + tuple(image_sizes[0]) + ), + image_sizes, + ) + + num_features = len([x for x in c2_results.keys() if x.startswith("box_cls_")]) + pred_logits = [c2_results["box_cls_{}".format(i)] for i in range(num_features)] + pred_anchor_deltas = [c2_results["box_delta_{}".format(i)] for i in range(num_features)] + + # For each feature level, feature should have the same batch size and + # spatial dimension as the box_cls and box_delta. + dummy_features = [x.clone()[:, 0:0, :, :] for x in pred_logits] + # self.num_classess can be inferred + self.num_classes = pred_logits[0].shape[1] // (pred_anchor_deltas[0].shape[1] // 4) + + results = self.forward_inference( + dummy_images, dummy_features, [pred_logits, pred_anchor_deltas] + ) + return meta_arch.GeneralizedRCNN._postprocess(results, batched_inputs, image_sizes) + + return f + + +META_ARCH_CAFFE2_EXPORT_TYPE_MAP = { + "GeneralizedRCNN": Caffe2GeneralizedRCNN, + "RetinaNet": Caffe2RetinaNet, +} diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/caffe2_patch.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/caffe2_patch.py new file mode 100644 index 00000000..9c197cac --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/caffe2_patch.py @@ -0,0 +1,152 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +import contextlib +from unittest import mock +import torch + +from annotator.oneformer.detectron2.modeling import poolers +from annotator.oneformer.detectron2.modeling.proposal_generator import rpn +from annotator.oneformer.detectron2.modeling.roi_heads import keypoint_head, mask_head +from annotator.oneformer.detectron2.modeling.roi_heads.fast_rcnn import FastRCNNOutputLayers + +from .c10 import ( + Caffe2Compatible, + Caffe2FastRCNNOutputsInference, + Caffe2KeypointRCNNInference, + Caffe2MaskRCNNInference, + Caffe2ROIPooler, + Caffe2RPN, +) + + +class GenericMixin(object): + pass + + +class Caffe2CompatibleConverter(object): + """ + A GenericUpdater which implements the `create_from` interface, by modifying + module object and assign it with another class replaceCls. + """ + + def __init__(self, replaceCls): + self.replaceCls = replaceCls + + def create_from(self, module): + # update module's class to the new class + assert isinstance(module, torch.nn.Module) + if issubclass(self.replaceCls, GenericMixin): + # replaceCls should act as mixin, create a new class on-the-fly + new_class = type( + "{}MixedWith{}".format(self.replaceCls.__name__, module.__class__.__name__), + (self.replaceCls, module.__class__), + {}, # {"new_method": lambda self: ...}, + ) + module.__class__ = new_class + else: + # replaceCls is complete class, this allow arbitrary class swap + module.__class__ = self.replaceCls + + # initialize Caffe2Compatible + if isinstance(module, Caffe2Compatible): + module.tensor_mode = False + + return module + + +def patch(model, target, updater, *args, **kwargs): + """ + recursively (post-order) update all modules with the target type and its + subclasses, make a initialization/composition/inheritance/... via the + updater.create_from. + """ + for name, module in model.named_children(): + model._modules[name] = patch(module, target, updater, *args, **kwargs) + if isinstance(model, target): + return updater.create_from(model, *args, **kwargs) + return model + + +def patch_generalized_rcnn(model): + ccc = Caffe2CompatibleConverter + model = patch(model, rpn.RPN, ccc(Caffe2RPN)) + model = patch(model, poolers.ROIPooler, ccc(Caffe2ROIPooler)) + + return model + + +@contextlib.contextmanager +def mock_fastrcnn_outputs_inference( + tensor_mode, check=True, box_predictor_type=FastRCNNOutputLayers +): + with mock.patch.object( + box_predictor_type, + "inference", + autospec=True, + side_effect=Caffe2FastRCNNOutputsInference(tensor_mode), + ) as mocked_func: + yield + if check: + assert mocked_func.call_count > 0 + + +@contextlib.contextmanager +def mock_mask_rcnn_inference(tensor_mode, patched_module, check=True): + with mock.patch( + "{}.mask_rcnn_inference".format(patched_module), side_effect=Caffe2MaskRCNNInference() + ) as mocked_func: + yield + if check: + assert mocked_func.call_count > 0 + + +@contextlib.contextmanager +def mock_keypoint_rcnn_inference(tensor_mode, patched_module, use_heatmap_max_keypoint, check=True): + with mock.patch( + "{}.keypoint_rcnn_inference".format(patched_module), + side_effect=Caffe2KeypointRCNNInference(use_heatmap_max_keypoint), + ) as mocked_func: + yield + if check: + assert mocked_func.call_count > 0 + + +class ROIHeadsPatcher: + def __init__(self, heads, use_heatmap_max_keypoint): + self.heads = heads + self.use_heatmap_max_keypoint = use_heatmap_max_keypoint + + @contextlib.contextmanager + def mock_roi_heads(self, tensor_mode=True): + """ + Patching several inference functions inside ROIHeads and its subclasses + + Args: + tensor_mode (bool): whether the inputs/outputs are caffe2's tensor + format or not. Default to True. + """ + # NOTE: this requries the `keypoint_rcnn_inference` and `mask_rcnn_inference` + # are called inside the same file as BaseXxxHead due to using mock.patch. + kpt_heads_mod = keypoint_head.BaseKeypointRCNNHead.__module__ + mask_head_mod = mask_head.BaseMaskRCNNHead.__module__ + + mock_ctx_managers = [ + mock_fastrcnn_outputs_inference( + tensor_mode=tensor_mode, + check=True, + box_predictor_type=type(self.heads.box_predictor), + ) + ] + if getattr(self.heads, "keypoint_on", False): + mock_ctx_managers += [ + mock_keypoint_rcnn_inference( + tensor_mode, kpt_heads_mod, self.use_heatmap_max_keypoint + ) + ] + if getattr(self.heads, "mask_on", False): + mock_ctx_managers += [mock_mask_rcnn_inference(tensor_mode, mask_head_mod)] + + with contextlib.ExitStack() as stack: # python 3.3+ + for mgr in mock_ctx_managers: + stack.enter_context(mgr) + yield diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/flatten.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/flatten.py new file mode 100644 index 00000000..3fcb2bf4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/flatten.py @@ -0,0 +1,330 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import collections +from dataclasses import dataclass +from typing import Callable, List, Optional, Tuple +import torch +from torch import nn + +from annotator.oneformer.detectron2.structures import Boxes, Instances, ROIMasks +from annotator.oneformer.detectron2.utils.registry import _convert_target_to_string, locate + +from .torchscript_patch import patch_builtin_len + + +@dataclass +class Schema: + """ + A Schema defines how to flatten a possibly hierarchical object into tuple of + primitive objects, so it can be used as inputs/outputs of PyTorch's tracing. + + PyTorch does not support tracing a function that produces rich output + structures (e.g. dict, Instances, Boxes). To trace such a function, we + flatten the rich object into tuple of tensors, and return this tuple of tensors + instead. Meanwhile, we also need to know how to "rebuild" the original object + from the flattened results, so we can evaluate the flattened results. + A Schema defines how to flatten an object, and while flattening it, it records + necessary schemas so that the object can be rebuilt using the flattened outputs. + + The flattened object and the schema object is returned by ``.flatten`` classmethod. + Then the original object can be rebuilt with the ``__call__`` method of schema. + + A Schema is a dataclass that can be serialized easily. + """ + + # inspired by FetchMapper in tensorflow/python/client/session.py + + @classmethod + def flatten(cls, obj): + raise NotImplementedError + + def __call__(self, values): + raise NotImplementedError + + @staticmethod + def _concat(values): + ret = () + sizes = [] + for v in values: + assert isinstance(v, tuple), "Flattened results must be a tuple" + ret = ret + v + sizes.append(len(v)) + return ret, sizes + + @staticmethod + def _split(values, sizes): + if len(sizes): + expected_len = sum(sizes) + assert ( + len(values) == expected_len + ), f"Values has length {len(values)} but expect length {expected_len}." + ret = [] + for k in range(len(sizes)): + begin, end = sum(sizes[:k]), sum(sizes[: k + 1]) + ret.append(values[begin:end]) + return ret + + +@dataclass +class ListSchema(Schema): + schemas: List[Schema] # the schemas that define how to flatten each element in the list + sizes: List[int] # the flattened length of each element + + def __call__(self, values): + values = self._split(values, self.sizes) + if len(values) != len(self.schemas): + raise ValueError( + f"Values has length {len(values)} but schemas " f"has length {len(self.schemas)}!" + ) + values = [m(v) for m, v in zip(self.schemas, values)] + return list(values) + + @classmethod + def flatten(cls, obj): + res = [flatten_to_tuple(k) for k in obj] + values, sizes = cls._concat([k[0] for k in res]) + return values, cls([k[1] for k in res], sizes) + + +@dataclass +class TupleSchema(ListSchema): + def __call__(self, values): + return tuple(super().__call__(values)) + + +@dataclass +class IdentitySchema(Schema): + def __call__(self, values): + return values[0] + + @classmethod + def flatten(cls, obj): + return (obj,), cls() + + +@dataclass +class DictSchema(ListSchema): + keys: List[str] + + def __call__(self, values): + values = super().__call__(values) + return dict(zip(self.keys, values)) + + @classmethod + def flatten(cls, obj): + for k in obj.keys(): + if not isinstance(k, str): + raise KeyError("Only support flattening dictionaries if keys are str.") + keys = sorted(obj.keys()) + values = [obj[k] for k in keys] + ret, schema = ListSchema.flatten(values) + return ret, cls(schema.schemas, schema.sizes, keys) + + +@dataclass +class InstancesSchema(DictSchema): + def __call__(self, values): + image_size, fields = values[-1], values[:-1] + fields = super().__call__(fields) + return Instances(image_size, **fields) + + @classmethod + def flatten(cls, obj): + ret, schema = super().flatten(obj.get_fields()) + size = obj.image_size + if not isinstance(size, torch.Tensor): + size = torch.tensor(size) + return ret + (size,), schema + + +@dataclass +class TensorWrapSchema(Schema): + """ + For classes that are simple wrapper of tensors, e.g. + Boxes, RotatedBoxes, BitMasks + """ + + class_name: str + + def __call__(self, values): + return locate(self.class_name)(values[0]) + + @classmethod + def flatten(cls, obj): + return (obj.tensor,), cls(_convert_target_to_string(type(obj))) + + +# if more custom structures needed in the future, can allow +# passing in extra schemas for custom types +def flatten_to_tuple(obj): + """ + Flatten an object so it can be used for PyTorch tracing. + Also returns how to rebuild the original object from the flattened outputs. + + Returns: + res (tuple): the flattened results that can be used as tracing outputs + schema: an object with a ``__call__`` method such that ``schema(res) == obj``. + It is a pure dataclass that can be serialized. + """ + schemas = [ + ((str, bytes), IdentitySchema), + (list, ListSchema), + (tuple, TupleSchema), + (collections.abc.Mapping, DictSchema), + (Instances, InstancesSchema), + ((Boxes, ROIMasks), TensorWrapSchema), + ] + for klass, schema in schemas: + if isinstance(obj, klass): + F = schema + break + else: + F = IdentitySchema + + return F.flatten(obj) + + +class TracingAdapter(nn.Module): + """ + A model may take rich input/output format (e.g. dict or custom classes), + but `torch.jit.trace` requires tuple of tensors as input/output. + This adapter flattens input/output format of a model so it becomes traceable. + + It also records the necessary schema to rebuild model's inputs/outputs from flattened + inputs/outputs. + + Example: + :: + outputs = model(inputs) # inputs/outputs may be rich structure + adapter = TracingAdapter(model, inputs) + + # can now trace the model, with adapter.flattened_inputs, or another + # tuple of tensors with the same length and meaning + traced = torch.jit.trace(adapter, adapter.flattened_inputs) + + # traced model can only produce flattened outputs (tuple of tensors) + flattened_outputs = traced(*adapter.flattened_inputs) + # adapter knows the schema to convert it back (new_outputs == outputs) + new_outputs = adapter.outputs_schema(flattened_outputs) + """ + + flattened_inputs: Tuple[torch.Tensor] = None + """ + Flattened version of inputs given to this class's constructor. + """ + + inputs_schema: Schema = None + """ + Schema of the inputs given to this class's constructor. + """ + + outputs_schema: Schema = None + """ + Schema of the output produced by calling the given model with inputs. + """ + + def __init__( + self, + model: nn.Module, + inputs, + inference_func: Optional[Callable] = None, + allow_non_tensor: bool = False, + ): + """ + Args: + model: an nn.Module + inputs: An input argument or a tuple of input arguments used to call model. + After flattening, it has to only consist of tensors. + inference_func: a callable that takes (model, *inputs), calls the + model with inputs, and return outputs. By default it + is ``lambda model, *inputs: model(*inputs)``. Can be override + if you need to call the model differently. + allow_non_tensor: allow inputs/outputs to contain non-tensor objects. + This option will filter out non-tensor objects to make the + model traceable, but ``inputs_schema``/``outputs_schema`` cannot be + used anymore because inputs/outputs cannot be rebuilt from pure tensors. + This is useful when you're only interested in the single trace of + execution (e.g. for flop count), but not interested in + generalizing the traced graph to new inputs. + """ + super().__init__() + if isinstance(model, (nn.parallel.distributed.DistributedDataParallel, nn.DataParallel)): + model = model.module + self.model = model + if not isinstance(inputs, tuple): + inputs = (inputs,) + self.inputs = inputs + self.allow_non_tensor = allow_non_tensor + + if inference_func is None: + inference_func = lambda model, *inputs: model(*inputs) # noqa + self.inference_func = inference_func + + self.flattened_inputs, self.inputs_schema = flatten_to_tuple(inputs) + + if all(isinstance(x, torch.Tensor) for x in self.flattened_inputs): + return + if self.allow_non_tensor: + self.flattened_inputs = tuple( + [x for x in self.flattened_inputs if isinstance(x, torch.Tensor)] + ) + self.inputs_schema = None + else: + for input in self.flattened_inputs: + if not isinstance(input, torch.Tensor): + raise ValueError( + "Inputs for tracing must only contain tensors. " + f"Got a {type(input)} instead." + ) + + def forward(self, *args: torch.Tensor): + with torch.no_grad(), patch_builtin_len(): + if self.inputs_schema is not None: + inputs_orig_format = self.inputs_schema(args) + else: + if len(args) != len(self.flattened_inputs) or any( + x is not y for x, y in zip(args, self.flattened_inputs) + ): + raise ValueError( + "TracingAdapter does not contain valid inputs_schema." + " So it cannot generalize to other inputs and must be" + " traced with `.flattened_inputs`." + ) + inputs_orig_format = self.inputs + + outputs = self.inference_func(self.model, *inputs_orig_format) + flattened_outputs, schema = flatten_to_tuple(outputs) + + flattened_output_tensors = tuple( + [x for x in flattened_outputs if isinstance(x, torch.Tensor)] + ) + if len(flattened_output_tensors) < len(flattened_outputs): + if self.allow_non_tensor: + flattened_outputs = flattened_output_tensors + self.outputs_schema = None + else: + raise ValueError( + "Model cannot be traced because some model outputs " + "cannot flatten to tensors." + ) + else: # schema is valid + if self.outputs_schema is None: + self.outputs_schema = schema + else: + assert self.outputs_schema == schema, ( + "Model should always return outputs with the same " + "structure so it can be traced!" + ) + return flattened_outputs + + def _create_wrapper(self, traced_model): + """ + Return a function that has an input/output interface the same as the + original model, but it calls the given traced model under the hood. + """ + + def forward(*args): + flattened_inputs, _ = flatten_to_tuple(args) + flattened_outputs = traced_model(*flattened_inputs) + return self.outputs_schema(flattened_outputs) + + return forward diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/shared.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/shared.py new file mode 100644 index 00000000..53ba9335 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/shared.py @@ -0,0 +1,1039 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +import collections +import copy +import functools +import logging +import numpy as np +import os +from typing import Any, Callable, Dict, List, Optional, Tuple, Union +from unittest import mock +import caffe2.python.utils as putils +import torch +import torch.nn.functional as F +from caffe2.proto import caffe2_pb2 +from caffe2.python import core, net_drawer, workspace +from torch.nn.functional import interpolate as interp + +logger = logging.getLogger(__name__) + + +# ==== torch/utils_toffee/cast.py ======================================= + + +def to_device(t, device_str): + """ + This function is a replacement of .to(another_device) such that it allows the + casting to be traced properly by explicitly calling the underlying copy ops. + It also avoids introducing unncessary op when casting to the same device. + """ + src = t.device + dst = torch.device(device_str) + + if src == dst: + return t + elif src.type == "cuda" and dst.type == "cpu": + return torch.ops._caffe2.CopyGPUToCPU(t) + elif src.type == "cpu" and dst.type == "cuda": + return torch.ops._caffe2.CopyCPUToGPU(t) + else: + raise RuntimeError("Can't cast tensor from device {} to device {}".format(src, dst)) + + +# ==== torch/utils_toffee/interpolate.py ======================================= + + +# Note: borrowed from vision/detection/fair/detectron/detectron/modeling/detector.py +def BilinearInterpolation(tensor_in, up_scale): + assert up_scale % 2 == 0, "Scale should be even" + + def upsample_filt(size): + factor = (size + 1) // 2 + if size % 2 == 1: + center = factor - 1 + else: + center = factor - 0.5 + + og = np.ogrid[:size, :size] + return (1 - abs(og[0] - center) / factor) * (1 - abs(og[1] - center) / factor) + + kernel_size = int(up_scale) * 2 + bil_filt = upsample_filt(kernel_size) + + dim = int(tensor_in.shape[1]) + kernel = np.zeros((dim, dim, kernel_size, kernel_size), dtype=np.float32) + kernel[range(dim), range(dim), :, :] = bil_filt + + tensor_out = F.conv_transpose2d( + tensor_in, + weight=to_device(torch.Tensor(kernel), tensor_in.device), + bias=None, + stride=int(up_scale), + padding=int(up_scale / 2), + ) + + return tensor_out + + +# NOTE: ONNX is incompatible with traced torch.nn.functional.interpolate if +# using dynamic `scale_factor` rather than static `size`. (T43166860) +# NOTE: Caffe2 Int8 conversion might not be able to quantize `size` properly. +def onnx_compatibale_interpolate( + input, size=None, scale_factor=None, mode="nearest", align_corners=None +): + # NOTE: The input dimensions are interpreted in the form: + # `mini-batch x channels x [optional depth] x [optional height] x width`. + if size is None and scale_factor is not None: + if input.dim() == 4: + if isinstance(scale_factor, (int, float)): + height_scale, width_scale = (scale_factor, scale_factor) + else: + assert isinstance(scale_factor, (tuple, list)) + assert len(scale_factor) == 2 + height_scale, width_scale = scale_factor + + assert not align_corners, "No matching C2 op for align_corners == True" + if mode == "nearest": + return torch.ops._caffe2.ResizeNearest( + input, order="NCHW", width_scale=width_scale, height_scale=height_scale + ) + elif mode == "bilinear": + logger.warning( + "Use F.conv_transpose2d for bilinear interpolate" + " because there's no such C2 op, this may cause significant" + " slowdown and the boundary pixels won't be as same as" + " using F.interpolate due to padding." + ) + assert height_scale == width_scale + return BilinearInterpolation(input, up_scale=height_scale) + logger.warning("Output size is not static, it might cause ONNX conversion issue") + + return interp(input, size, scale_factor, mode, align_corners) + + +def mock_torch_nn_functional_interpolate(): + def decorator(func): + @functools.wraps(func) + def _mock_torch_nn_functional_interpolate(*args, **kwargs): + if torch.onnx.is_in_onnx_export(): + with mock.patch( + "torch.nn.functional.interpolate", side_effect=onnx_compatibale_interpolate + ): + return func(*args, **kwargs) + else: + return func(*args, **kwargs) + + return _mock_torch_nn_functional_interpolate + + return decorator + + +# ==== torch/utils_caffe2/ws_utils.py ========================================== + + +class ScopedWS(object): + def __init__(self, ws_name, is_reset, is_cleanup=False): + self.ws_name = ws_name + self.is_reset = is_reset + self.is_cleanup = is_cleanup + self.org_ws = "" + + def __enter__(self): + self.org_ws = workspace.CurrentWorkspace() + if self.ws_name is not None: + workspace.SwitchWorkspace(self.ws_name, True) + if self.is_reset: + workspace.ResetWorkspace() + + return workspace + + def __exit__(self, *args): + if self.is_cleanup: + workspace.ResetWorkspace() + if self.ws_name is not None: + workspace.SwitchWorkspace(self.org_ws) + + +def fetch_any_blob(name): + bb = None + try: + bb = workspace.FetchBlob(name) + except TypeError: + bb = workspace.FetchInt8Blob(name) + except Exception as e: + logger.error("Get blob {} error: {}".format(name, e)) + + return bb + + +# ==== torch/utils_caffe2/protobuf.py ========================================== + + +def get_pb_arg(pb, arg_name): + for x in pb.arg: + if x.name == arg_name: + return x + return None + + +def get_pb_arg_valf(pb, arg_name, default_val): + arg = get_pb_arg(pb, arg_name) + return arg.f if arg is not None else default_val + + +def get_pb_arg_floats(pb, arg_name, default_val): + arg = get_pb_arg(pb, arg_name) + return list(map(float, arg.floats)) if arg is not None else default_val + + +def get_pb_arg_ints(pb, arg_name, default_val): + arg = get_pb_arg(pb, arg_name) + return list(map(int, arg.ints)) if arg is not None else default_val + + +def get_pb_arg_vali(pb, arg_name, default_val): + arg = get_pb_arg(pb, arg_name) + return arg.i if arg is not None else default_val + + +def get_pb_arg_vals(pb, arg_name, default_val): + arg = get_pb_arg(pb, arg_name) + return arg.s if arg is not None else default_val + + +def get_pb_arg_valstrings(pb, arg_name, default_val): + arg = get_pb_arg(pb, arg_name) + return list(arg.strings) if arg is not None else default_val + + +def check_set_pb_arg(pb, arg_name, arg_attr, arg_value, allow_override=False): + arg = get_pb_arg(pb, arg_name) + if arg is None: + arg = putils.MakeArgument(arg_name, arg_value) + assert hasattr(arg, arg_attr) + pb.arg.extend([arg]) + if allow_override and getattr(arg, arg_attr) != arg_value: + logger.warning( + "Override argument {}: {} -> {}".format(arg_name, getattr(arg, arg_attr), arg_value) + ) + setattr(arg, arg_attr, arg_value) + else: + assert arg is not None + assert getattr(arg, arg_attr) == arg_value, "Existing value {}, new value {}".format( + getattr(arg, arg_attr), arg_value + ) + + +def _create_const_fill_op_from_numpy(name, tensor, device_option=None): + assert type(tensor) == np.ndarray + kTypeNameMapper = { + np.dtype("float32"): "GivenTensorFill", + np.dtype("int32"): "GivenTensorIntFill", + np.dtype("int64"): "GivenTensorInt64Fill", + np.dtype("uint8"): "GivenTensorStringFill", + } + + args_dict = {} + if tensor.dtype == np.dtype("uint8"): + args_dict.update({"values": [str(tensor.data)], "shape": [1]}) + else: + args_dict.update({"values": tensor, "shape": tensor.shape}) + + if device_option is not None: + args_dict["device_option"] = device_option + + return core.CreateOperator(kTypeNameMapper[tensor.dtype], [], [name], **args_dict) + + +def _create_const_fill_op_from_c2_int8_tensor(name, int8_tensor): + assert type(int8_tensor) == workspace.Int8Tensor + kTypeNameMapper = { + np.dtype("int32"): "Int8GivenIntTensorFill", + np.dtype("uint8"): "Int8GivenTensorFill", + } + + tensor = int8_tensor.data + assert tensor.dtype in [np.dtype("uint8"), np.dtype("int32")] + values = tensor.tobytes() if tensor.dtype == np.dtype("uint8") else tensor + + return core.CreateOperator( + kTypeNameMapper[tensor.dtype], + [], + [name], + values=values, + shape=tensor.shape, + Y_scale=int8_tensor.scale, + Y_zero_point=int8_tensor.zero_point, + ) + + +def create_const_fill_op( + name: str, + blob: Union[np.ndarray, workspace.Int8Tensor], + device_option: Optional[caffe2_pb2.DeviceOption] = None, +) -> caffe2_pb2.OperatorDef: + """ + Given a blob object, return the Caffe2 operator that creates this blob + as constant. Currently support NumPy tensor and Caffe2 Int8Tensor. + """ + + tensor_type = type(blob) + assert tensor_type in [ + np.ndarray, + workspace.Int8Tensor, + ], 'Error when creating const fill op for "{}", unsupported blob type: {}'.format( + name, type(blob) + ) + + if tensor_type == np.ndarray: + return _create_const_fill_op_from_numpy(name, blob, device_option) + elif tensor_type == workspace.Int8Tensor: + assert device_option is None + return _create_const_fill_op_from_c2_int8_tensor(name, blob) + + +def construct_init_net_from_params( + params: Dict[str, Any], device_options: Optional[Dict[str, caffe2_pb2.DeviceOption]] = None +) -> caffe2_pb2.NetDef: + """ + Construct the init_net from params dictionary + """ + init_net = caffe2_pb2.NetDef() + device_options = device_options or {} + for name, blob in params.items(): + if isinstance(blob, str): + logger.warning( + ( + "Blob {} with type {} is not supported in generating init net," + " skipped.".format(name, type(blob)) + ) + ) + continue + init_net.op.extend( + [create_const_fill_op(name, blob, device_option=device_options.get(name, None))] + ) + init_net.external_output.append(name) + return init_net + + +def get_producer_map(ssa): + """ + Return dict from versioned blob to (i, j), + where i is index of producer op, j is the index of output of that op. + """ + producer_map = {} + for i in range(len(ssa)): + outputs = ssa[i][1] + for j, outp in enumerate(outputs): + producer_map[outp] = (i, j) + return producer_map + + +def get_consumer_map(ssa): + """ + Return dict from versioned blob to list of (i, j), + where i is index of consumer op, j is the index of input of that op. + """ + consumer_map = collections.defaultdict(list) + for i in range(len(ssa)): + inputs = ssa[i][0] + for j, inp in enumerate(inputs): + consumer_map[inp].append((i, j)) + return consumer_map + + +def get_params_from_init_net( + init_net: caffe2_pb2.NetDef, +) -> [Dict[str, Any], Dict[str, caffe2_pb2.DeviceOption]]: + """ + Take the output blobs from init_net by running it. + Outputs: + params: dict from blob name to numpy array + device_options: dict from blob name to the device option of its creating op + """ + # NOTE: this assumes that the params is determined by producer op with the + # only exception be CopyGPUToCPU which is CUDA op but returns CPU tensor. + def _get_device_option(producer_op): + if producer_op.type == "CopyGPUToCPU": + return caffe2_pb2.DeviceOption() + else: + return producer_op.device_option + + with ScopedWS("__get_params_from_init_net__", is_reset=True, is_cleanup=True) as ws: + ws.RunNetOnce(init_net) + params = {b: fetch_any_blob(b) for b in init_net.external_output} + ssa, versions = core.get_ssa(init_net) + producer_map = get_producer_map(ssa) + device_options = { + b: _get_device_option(init_net.op[producer_map[(b, versions[b])][0]]) + for b in init_net.external_output + } + return params, device_options + + +def _updater_raise(op, input_types, output_types): + raise RuntimeError( + "Failed to apply updater for op {} given input_types {} and" + " output_types {}".format(op, input_types, output_types) + ) + + +def _generic_status_identifier( + predict_net: caffe2_pb2.NetDef, + status_updater: Callable, + known_status: Dict[Tuple[str, int], Any], +) -> Dict[Tuple[str, int], Any]: + """ + Statically infer the status of each blob, the status can be such as device type + (CPU/GPU), layout (NCHW/NHWC), data type (float32/int8), etc. "Blob" here + is versioned blob (Tuple[str, int]) in the format compatible with ssa. + Inputs: + predict_net: the caffe2 network + status_updater: a callable, given an op and the status of its input/output, + it returns the updated status of input/output. `None` is used for + representing unknown status. + known_status: a dict containing known status, used as initialization. + Outputs: + A dict mapping from versioned blob to its status + """ + ssa, versions = core.get_ssa(predict_net) + versioned_ext_input = [(b, 0) for b in predict_net.external_input] + versioned_ext_output = [(b, versions[b]) for b in predict_net.external_output] + all_versioned_blobs = set().union(*[set(x[0] + x[1]) for x in ssa]) + + allowed_vbs = all_versioned_blobs.union(versioned_ext_input).union(versioned_ext_output) + assert all(k in allowed_vbs for k in known_status) + assert all(v is not None for v in known_status.values()) + _known_status = copy.deepcopy(known_status) + + def _check_and_update(key, value): + assert value is not None + if key in _known_status: + if not _known_status[key] == value: + raise RuntimeError( + "Confilict status for {}, existing status {}, new status {}".format( + key, _known_status[key], value + ) + ) + _known_status[key] = value + + def _update_i(op, ssa_i): + versioned_inputs = ssa_i[0] + versioned_outputs = ssa_i[1] + + inputs_status = [_known_status.get(b, None) for b in versioned_inputs] + outputs_status = [_known_status.get(b, None) for b in versioned_outputs] + + new_inputs_status, new_outputs_status = status_updater(op, inputs_status, outputs_status) + + for versioned_blob, status in zip( + versioned_inputs + versioned_outputs, new_inputs_status + new_outputs_status + ): + if status is not None: + _check_and_update(versioned_blob, status) + + for op, ssa_i in zip(predict_net.op, ssa): + _update_i(op, ssa_i) + for op, ssa_i in zip(reversed(predict_net.op), reversed(ssa)): + _update_i(op, ssa_i) + + # NOTE: This strictly checks all the blob from predict_net must be assgined + # a known status. However sometimes it's impossible (eg. having deadend op), + # we may relax this constraint if + for k in all_versioned_blobs: + if k not in _known_status: + raise NotImplementedError( + "Can not infer the status for {}. Currently only support the case where" + " a single forward and backward pass can identify status for all blobs.".format(k) + ) + + return _known_status + + +def infer_device_type( + predict_net: caffe2_pb2.NetDef, + known_status: Dict[Tuple[str, int], Any], + device_name_style: str = "caffe2", +) -> Dict[Tuple[str, int], str]: + """Return the device type ("cpu" or "gpu"/"cuda") of each (versioned) blob""" + + assert device_name_style in ["caffe2", "pytorch"] + _CPU_STR = "cpu" + _GPU_STR = "gpu" if device_name_style == "caffe2" else "cuda" + + def _copy_cpu_to_gpu_updater(op, input_types, output_types): + if input_types[0] == _GPU_STR or output_types[0] == _CPU_STR: + _updater_raise(op, input_types, output_types) + return ([_CPU_STR], [_GPU_STR]) + + def _copy_gpu_to_cpu_updater(op, input_types, output_types): + if input_types[0] == _CPU_STR or output_types[0] == _GPU_STR: + _updater_raise(op, input_types, output_types) + return ([_GPU_STR], [_CPU_STR]) + + def _other_ops_updater(op, input_types, output_types): + non_none_types = [x for x in input_types + output_types if x is not None] + if len(non_none_types) > 0: + the_type = non_none_types[0] + if not all(x == the_type for x in non_none_types): + _updater_raise(op, input_types, output_types) + else: + the_type = None + return ([the_type for _ in op.input], [the_type for _ in op.output]) + + def _device_updater(op, *args, **kwargs): + return { + "CopyCPUToGPU": _copy_cpu_to_gpu_updater, + "CopyGPUToCPU": _copy_gpu_to_cpu_updater, + }.get(op.type, _other_ops_updater)(op, *args, **kwargs) + + return _generic_status_identifier(predict_net, _device_updater, known_status) + + +# ==== torch/utils_caffe2/vis.py =============================================== + + +def _modify_blob_names(ops, blob_rename_f): + ret = [] + + def _replace_list(blob_list, replaced_list): + del blob_list[:] + blob_list.extend(replaced_list) + + for x in ops: + cur = copy.deepcopy(x) + _replace_list(cur.input, list(map(blob_rename_f, cur.input))) + _replace_list(cur.output, list(map(blob_rename_f, cur.output))) + ret.append(cur) + + return ret + + +def _rename_blob(name, blob_sizes, blob_ranges): + def _list_to_str(bsize): + ret = ", ".join([str(x) for x in bsize]) + ret = "[" + ret + "]" + return ret + + ret = name + if blob_sizes is not None and name in blob_sizes: + ret += "\n" + _list_to_str(blob_sizes[name]) + if blob_ranges is not None and name in blob_ranges: + ret += "\n" + _list_to_str(blob_ranges[name]) + + return ret + + +# graph_name could not contain word 'graph' +def save_graph(net, file_name, graph_name="net", op_only=True, blob_sizes=None, blob_ranges=None): + blob_rename_f = functools.partial(_rename_blob, blob_sizes=blob_sizes, blob_ranges=blob_ranges) + return save_graph_base(net, file_name, graph_name, op_only, blob_rename_f) + + +def save_graph_base(net, file_name, graph_name="net", op_only=True, blob_rename_func=None): + graph = None + ops = net.op + if blob_rename_func is not None: + ops = _modify_blob_names(ops, blob_rename_func) + if not op_only: + graph = net_drawer.GetPydotGraph(ops, graph_name, rankdir="TB") + else: + graph = net_drawer.GetPydotGraphMinimal( + ops, graph_name, rankdir="TB", minimal_dependency=True + ) + + try: + par_dir = os.path.dirname(file_name) + if not os.path.exists(par_dir): + os.makedirs(par_dir) + + format = os.path.splitext(os.path.basename(file_name))[-1] + if format == ".png": + graph.write_png(file_name) + elif format == ".pdf": + graph.write_pdf(file_name) + elif format == ".svg": + graph.write_svg(file_name) + else: + print("Incorrect format {}".format(format)) + except Exception as e: + print("Error when writing graph to image {}".format(e)) + + return graph + + +# ==== torch/utils_toffee/aten_to_caffe2.py ==================================== + + +def group_norm_replace_aten_with_caffe2(predict_net: caffe2_pb2.NetDef): + """ + For ONNX exported model, GroupNorm will be represented as ATen op, + this can be a drop in replacement from ATen to GroupNorm + """ + count = 0 + for op in predict_net.op: + if op.type == "ATen": + op_name = get_pb_arg_vals(op, "operator", None) # return byte in py3 + if op_name and op_name.decode() == "group_norm": + op.arg.remove(get_pb_arg(op, "operator")) + + if get_pb_arg_vali(op, "cudnn_enabled", None): + op.arg.remove(get_pb_arg(op, "cudnn_enabled")) + + num_groups = get_pb_arg_vali(op, "num_groups", None) + if num_groups is not None: + op.arg.remove(get_pb_arg(op, "num_groups")) + check_set_pb_arg(op, "group", "i", num_groups) + + op.type = "GroupNorm" + count += 1 + if count > 1: + logger.info("Replaced {} ATen operator to GroupNormOp".format(count)) + + +# ==== torch/utils_toffee/alias.py ============================================= + + +def alias(x, name, is_backward=False): + if not torch.onnx.is_in_onnx_export(): + return x + assert isinstance(x, torch.Tensor) + return torch.ops._caffe2.AliasWithName(x, name, is_backward=is_backward) + + +def fuse_alias_placeholder(predict_net, init_net): + """Remove AliasWithName placeholder and rename the input/output of it""" + # First we finish all the re-naming + for i, op in enumerate(predict_net.op): + if op.type == "AliasWithName": + assert len(op.input) == 1 + assert len(op.output) == 1 + name = get_pb_arg_vals(op, "name", None).decode() + is_backward = bool(get_pb_arg_vali(op, "is_backward", 0)) + rename_op_input(predict_net, init_net, i, 0, name, from_producer=is_backward) + rename_op_output(predict_net, i, 0, name) + + # Remove AliasWithName, should be very safe since it's a non-op + new_ops = [] + for op in predict_net.op: + if op.type != "AliasWithName": + new_ops.append(op) + else: + # safety check + assert op.input == op.output + assert op.input[0] == op.arg[0].s.decode() + del predict_net.op[:] + predict_net.op.extend(new_ops) + + +# ==== torch/utils_caffe2/graph_transform.py =================================== + + +class IllegalGraphTransformError(ValueError): + """When a graph transform function call can't be executed.""" + + +def _rename_versioned_blob_in_proto( + proto: caffe2_pb2.NetDef, + old_name: str, + new_name: str, + version: int, + ssa: List[Tuple[List[Tuple[str, int]], List[Tuple[str, int]]]], + start_versions: Dict[str, int], + end_versions: Dict[str, int], +): + """In given proto, rename all blobs with matched version""" + # Operater list + for op, i_th_ssa in zip(proto.op, ssa): + versioned_inputs, versioned_outputs = i_th_ssa + for i in range(len(op.input)): + if versioned_inputs[i] == (old_name, version): + op.input[i] = new_name + for i in range(len(op.output)): + if versioned_outputs[i] == (old_name, version): + op.output[i] = new_name + # external_input + if start_versions.get(old_name, 0) == version: + for i in range(len(proto.external_input)): + if proto.external_input[i] == old_name: + proto.external_input[i] = new_name + # external_output + if end_versions.get(old_name, 0) == version: + for i in range(len(proto.external_output)): + if proto.external_output[i] == old_name: + proto.external_output[i] = new_name + + +def rename_op_input( + predict_net: caffe2_pb2.NetDef, + init_net: caffe2_pb2.NetDef, + op_id: int, + input_id: int, + new_name: str, + from_producer: bool = False, +): + """ + Rename the op_id-th operator in predict_net, change it's input_id-th input's + name to the new_name. It also does automatic re-route and change + external_input and init_net if necessary. + - It requires the input is only consumed by this op. + - This function modifies predict_net and init_net in-place. + - When from_producer is enable, this also updates other operators that consumes + the same input. Be cautious because may trigger unintended behavior. + """ + assert isinstance(predict_net, caffe2_pb2.NetDef) + assert isinstance(init_net, caffe2_pb2.NetDef) + + init_net_ssa, init_net_versions = core.get_ssa(init_net) + predict_net_ssa, predict_net_versions = core.get_ssa( + predict_net, copy.deepcopy(init_net_versions) + ) + + versioned_inputs, versioned_outputs = predict_net_ssa[op_id] + old_name, version = versioned_inputs[input_id] + + if from_producer: + producer_map = get_producer_map(predict_net_ssa) + if not (old_name, version) in producer_map: + raise NotImplementedError( + "Can't find producer, the input {} is probably from" + " init_net, this is not supported yet.".format(old_name) + ) + producer = producer_map[(old_name, version)] + rename_op_output(predict_net, producer[0], producer[1], new_name) + return + + def contain_targets(op_ssa): + return (old_name, version) in op_ssa[0] + + is_consumer = [contain_targets(op_ssa) for op_ssa in predict_net_ssa] + if sum(is_consumer) > 1: + raise IllegalGraphTransformError( + ( + "Input '{}' of operator(#{}) are consumed by other ops, please use" + + " rename_op_output on the producer instead. Offending op: \n{}" + ).format(old_name, op_id, predict_net.op[op_id]) + ) + + # update init_net + _rename_versioned_blob_in_proto( + init_net, old_name, new_name, version, init_net_ssa, {}, init_net_versions + ) + # update predict_net + _rename_versioned_blob_in_proto( + predict_net, + old_name, + new_name, + version, + predict_net_ssa, + init_net_versions, + predict_net_versions, + ) + + +def rename_op_output(predict_net: caffe2_pb2.NetDef, op_id: int, output_id: int, new_name: str): + """ + Rename the op_id-th operator in predict_net, change it's output_id-th input's + name to the new_name. It also does automatic re-route and change + external_output and if necessary. + - It allows multiple consumers of its output. + - This function modifies predict_net in-place, doesn't need init_net. + """ + assert isinstance(predict_net, caffe2_pb2.NetDef) + + ssa, blob_versions = core.get_ssa(predict_net) + + versioned_inputs, versioned_outputs = ssa[op_id] + old_name, version = versioned_outputs[output_id] + + # update predict_net + _rename_versioned_blob_in_proto( + predict_net, old_name, new_name, version, ssa, {}, blob_versions + ) + + +def get_sub_graph_external_input_output( + predict_net: caffe2_pb2.NetDef, sub_graph_op_indices: List[int] +) -> Tuple[List[Tuple[str, int]], List[Tuple[str, int]]]: + """ + Return the list of external input/output of sub-graph, + each element is tuple of the name and corresponding version in predict_net. + + external input/output is defined the same way as caffe2 NetDef. + """ + ssa, versions = core.get_ssa(predict_net) + + all_inputs = [] + all_outputs = [] + for op_id in sub_graph_op_indices: + all_inputs += [inp for inp in ssa[op_id][0] if inp not in all_inputs] + all_outputs += list(ssa[op_id][1]) # ssa output won't repeat + + # for versioned blobs, external inputs are just those blob in all_inputs + # but not in all_outputs + ext_inputs = [inp for inp in all_inputs if inp not in all_outputs] + + # external outputs are essentially outputs of this subgraph that are used + # outside of this sub-graph (including predict_net.external_output) + all_other_inputs = sum( + (ssa[i][0] for i in range(len(ssa)) if i not in sub_graph_op_indices), + [(outp, versions[outp]) for outp in predict_net.external_output], + ) + ext_outputs = [outp for outp in all_outputs if outp in set(all_other_inputs)] + + return ext_inputs, ext_outputs + + +class DiGraph: + """A DAG representation of caffe2 graph, each vertice is a versioned blob.""" + + def __init__(self): + self.vertices = set() + self.graph = collections.defaultdict(list) + + def add_edge(self, u, v): + self.graph[u].append(v) + self.vertices.add(u) + self.vertices.add(v) + + # grab from https://www.geeksforgeeks.org/find-paths-given-source-destination/ + def get_all_paths(self, s, d): + visited = {k: False for k in self.vertices} + path = [] + all_paths = [] + + def _get_all_paths_util(graph, u, d, visited, path): + visited[u] = True + path.append(u) + if u == d: + all_paths.append(copy.deepcopy(path)) + else: + for i in graph[u]: + if not visited[i]: + _get_all_paths_util(graph, i, d, visited, path) + path.pop() + visited[u] = False + + _get_all_paths_util(self.graph, s, d, visited, path) + return all_paths + + @staticmethod + def from_ssa(ssa): + graph = DiGraph() + for op_id in range(len(ssa)): + for inp in ssa[op_id][0]: + for outp in ssa[op_id][1]: + graph.add_edge(inp, outp) + return graph + + +def _get_dependency_chain(ssa, versioned_target, versioned_source): + """ + Return the index list of relevant operator to produce target blob from source blob, + if there's no dependency, return empty list. + """ + + # finding all paths between nodes can be O(N!), thus we can only search + # in the subgraph using the op starting from the first consumer of source blob + # to the producer of the target blob. + consumer_map = get_consumer_map(ssa) + producer_map = get_producer_map(ssa) + start_op = min(x[0] for x in consumer_map[versioned_source]) - 15 + end_op = ( + producer_map[versioned_target][0] + 15 if versioned_target in producer_map else start_op + ) + sub_graph_ssa = ssa[start_op : end_op + 1] + if len(sub_graph_ssa) > 30: + logger.warning( + "Subgraph bebetween {} and {} is large (from op#{} to op#{}), it" + " might take non-trival time to find all paths between them.".format( + versioned_source, versioned_target, start_op, end_op + ) + ) + + dag = DiGraph.from_ssa(sub_graph_ssa) + paths = dag.get_all_paths(versioned_source, versioned_target) # include two ends + ops_in_paths = [[producer_map[blob][0] for blob in path[1:]] for path in paths] + return sorted(set().union(*[set(ops) for ops in ops_in_paths])) + + +def identify_reshape_sub_graph(predict_net: caffe2_pb2.NetDef) -> List[List[int]]: + """ + Idenfity the reshape sub-graph in a protobuf. + The reshape sub-graph is defined as matching the following pattern: + + (input_blob) -> Op_1 -> ... -> Op_N -> (new_shape) -─┐ + └-------------------------------------------> Reshape -> (output_blob) + + Return: + List of sub-graphs, each sub-graph is represented as a list of indices + of the relavent ops, [Op_1, Op_2, ..., Op_N, Reshape] + """ + + ssa, _ = core.get_ssa(predict_net) + + ret = [] + for i, op in enumerate(predict_net.op): + if op.type == "Reshape": + assert len(op.input) == 2 + input_ssa = ssa[i][0] + data_source = input_ssa[0] + shape_source = input_ssa[1] + op_indices = _get_dependency_chain(ssa, shape_source, data_source) + ret.append(op_indices + [i]) + return ret + + +def remove_reshape_for_fc(predict_net, params): + """ + In PyTorch nn.Linear has to take 2D tensor, this often leads to reshape + a 4D tensor to 2D by calling .view(). However this (dynamic) reshaping + doesn't work well with ONNX and Int8 tools, and cause using extra + ops (eg. ExpandDims) that might not be available on mobile. + Luckily Caffe2 supports 4D tensor for FC, so we can remove those reshape + after exporting ONNX model. + """ + from caffe2.python import core + + # find all reshape sub-graph that can be removed, which is now all Reshape + # sub-graph whose output is only consumed by FC. + # TODO: to make it safer, we may need the actually value to better determine + # if a Reshape before FC is removable. + reshape_sub_graphs = identify_reshape_sub_graph(predict_net) + sub_graphs_to_remove = [] + for reshape_sub_graph in reshape_sub_graphs: + reshape_op_id = reshape_sub_graph[-1] + assert predict_net.op[reshape_op_id].type == "Reshape" + ssa, _ = core.get_ssa(predict_net) + reshape_output = ssa[reshape_op_id][1][0] + consumers = [i for i in range(len(ssa)) if reshape_output in ssa[i][0]] + if all(predict_net.op[consumer].type == "FC" for consumer in consumers): + # safety check if the sub-graph is isolated, for this reshape sub-graph, + # it means it has one non-param external input and one external output. + ext_inputs, ext_outputs = get_sub_graph_external_input_output( + predict_net, reshape_sub_graph + ) + non_params_ext_inputs = [inp for inp in ext_inputs if inp[1] != 0] + if len(non_params_ext_inputs) == 1 and len(ext_outputs) == 1: + sub_graphs_to_remove.append(reshape_sub_graph) + + # perform removing subgraph by: + # 1: rename the Reshape's output to its input, then the graph can be + # seen as in-place itentify, meaning whose external input/output are the same. + # 2: simply remove those ops. + remove_op_ids = [] + params_to_remove = [] + for sub_graph in sub_graphs_to_remove: + logger.info( + "Remove Reshape sub-graph:\n{}".format( + "".join(["(#{:>4})\n{}".format(i, predict_net.op[i]) for i in sub_graph]) + ) + ) + reshape_op_id = sub_graph[-1] + new_reshap_output = predict_net.op[reshape_op_id].input[0] + rename_op_output(predict_net, reshape_op_id, 0, new_reshap_output) + ext_inputs, ext_outputs = get_sub_graph_external_input_output(predict_net, sub_graph) + non_params_ext_inputs = [inp for inp in ext_inputs if inp[1] != 0] + params_ext_inputs = [inp for inp in ext_inputs if inp[1] == 0] + assert len(non_params_ext_inputs) == 1 and len(ext_outputs) == 1 + assert ext_outputs[0][0] == non_params_ext_inputs[0][0] + assert ext_outputs[0][1] == non_params_ext_inputs[0][1] + 1 + remove_op_ids.extend(sub_graph) + params_to_remove.extend(params_ext_inputs) + + predict_net = copy.deepcopy(predict_net) + new_ops = [op for i, op in enumerate(predict_net.op) if i not in remove_op_ids] + del predict_net.op[:] + predict_net.op.extend(new_ops) + for versioned_params in params_to_remove: + name = versioned_params[0] + logger.info("Remove params: {} from init_net and predict_net.external_input".format(name)) + del params[name] + predict_net.external_input.remove(name) + + return predict_net, params + + +def fuse_copy_between_cpu_and_gpu(predict_net: caffe2_pb2.NetDef): + """ + In-place fuse extra copy ops between cpu/gpu for the following case: + a -CopyAToB-> b -CopyBToA> c1 -NextOp1-> d1 + -CopyBToA> c2 -NextOp2-> d2 + The fused network will look like: + a -NextOp1-> d1 + -NextOp2-> d2 + """ + + _COPY_OPS = ["CopyCPUToGPU", "CopyGPUToCPU"] + + def _fuse_once(predict_net): + ssa, blob_versions = core.get_ssa(predict_net) + consumer_map = get_consumer_map(ssa) + versioned_external_output = [ + (name, blob_versions[name]) for name in predict_net.external_output + ] + + for op_id, op in enumerate(predict_net.op): + if op.type in _COPY_OPS: + fw_copy_versioned_output = ssa[op_id][1][0] + consumer_ids = [x[0] for x in consumer_map[fw_copy_versioned_output]] + reverse_op_type = _COPY_OPS[1 - _COPY_OPS.index(op.type)] + + is_fusable = ( + len(consumer_ids) > 0 + and fw_copy_versioned_output not in versioned_external_output + and all( + predict_net.op[_op_id].type == reverse_op_type + and ssa[_op_id][1][0] not in versioned_external_output + for _op_id in consumer_ids + ) + ) + + if is_fusable: + for rv_copy_op_id in consumer_ids: + # making each NextOp uses "a" directly and removing Copy ops + rs_copy_versioned_output = ssa[rv_copy_op_id][1][0] + next_op_id, inp_id = consumer_map[rs_copy_versioned_output][0] + predict_net.op[next_op_id].input[inp_id] = op.input[0] + # remove CopyOps + new_ops = [ + op + for i, op in enumerate(predict_net.op) + if i != op_id and i not in consumer_ids + ] + del predict_net.op[:] + predict_net.op.extend(new_ops) + return True + + return False + + # _fuse_once returns False is nothing can be fused + while _fuse_once(predict_net): + pass + + +def remove_dead_end_ops(net_def: caffe2_pb2.NetDef): + """remove ops if its output is not used or not in external_output""" + ssa, versions = core.get_ssa(net_def) + versioned_external_output = [(name, versions[name]) for name in net_def.external_output] + consumer_map = get_consumer_map(ssa) + removed_op_ids = set() + + def _is_dead_end(versioned_blob): + return not ( + versioned_blob in versioned_external_output + or ( + len(consumer_map[versioned_blob]) > 0 + and all(x[0] not in removed_op_ids for x in consumer_map[versioned_blob]) + ) + ) + + for i, ssa_i in reversed(list(enumerate(ssa))): + versioned_outputs = ssa_i[1] + if all(_is_dead_end(outp) for outp in versioned_outputs): + removed_op_ids.add(i) + + # simply removing those deadend ops should have no effect to external_output + new_ops = [op for i, op in enumerate(net_def.op) if i not in removed_op_ids] + del net_def.op[:] + net_def.op.extend(new_ops) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/torchscript.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/torchscript.py new file mode 100644 index 00000000..8ce1c81e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/torchscript.py @@ -0,0 +1,132 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +import os +import torch + +from annotator.oneformer.detectron2.utils.file_io import PathManager + +from .torchscript_patch import freeze_training_mode, patch_instances + +__all__ = ["scripting_with_instances", "dump_torchscript_IR"] + + +def scripting_with_instances(model, fields): + """ + Run :func:`torch.jit.script` on a model that uses the :class:`Instances` class. Since + attributes of :class:`Instances` are "dynamically" added in eager mode,it is difficult + for scripting to support it out of the box. This function is made to support scripting + a model that uses :class:`Instances`. It does the following: + + 1. Create a scriptable ``new_Instances`` class which behaves similarly to ``Instances``, + but with all attributes been "static". + The attributes need to be statically declared in the ``fields`` argument. + 2. Register ``new_Instances``, and force scripting compiler to + use it when trying to compile ``Instances``. + + After this function, the process will be reverted. User should be able to script another model + using different fields. + + Example: + Assume that ``Instances`` in the model consist of two attributes named + ``proposal_boxes`` and ``objectness_logits`` with type :class:`Boxes` and + :class:`Tensor` respectively during inference. You can call this function like: + :: + fields = {"proposal_boxes": Boxes, "objectness_logits": torch.Tensor} + torchscipt_model = scripting_with_instances(model, fields) + + Note: + It only support models in evaluation mode. + + Args: + model (nn.Module): The input model to be exported by scripting. + fields (Dict[str, type]): Attribute names and corresponding type that + ``Instances`` will use in the model. Note that all attributes used in ``Instances`` + need to be added, regardless of whether they are inputs/outputs of the model. + Data type not defined in detectron2 is not supported for now. + + Returns: + torch.jit.ScriptModule: the model in torchscript format + """ + assert ( + not model.training + ), "Currently we only support exporting models in evaluation mode to torchscript" + + with freeze_training_mode(model), patch_instances(fields): + scripted_model = torch.jit.script(model) + return scripted_model + + +# alias for old name +export_torchscript_with_instances = scripting_with_instances + + +def dump_torchscript_IR(model, dir): + """ + Dump IR of a TracedModule/ScriptModule/Function in various format (code, graph, + inlined graph). Useful for debugging. + + Args: + model (TracedModule/ScriptModule/ScriptFUnction): traced or scripted module + dir (str): output directory to dump files. + """ + dir = os.path.expanduser(dir) + PathManager.mkdirs(dir) + + def _get_script_mod(mod): + if isinstance(mod, torch.jit.TracedModule): + return mod._actual_script_module + return mod + + # Dump pretty-printed code: https://pytorch.org/docs/stable/jit.html#inspecting-code + with PathManager.open(os.path.join(dir, "model_ts_code.txt"), "w") as f: + + def get_code(mod): + # Try a few ways to get code using private attributes. + try: + # This contains more information than just `mod.code` + return _get_script_mod(mod)._c.code + except AttributeError: + pass + try: + return mod.code + except AttributeError: + return None + + def dump_code(prefix, mod): + code = get_code(mod) + name = prefix or "root model" + if code is None: + f.write(f"Could not found code for {name} (type={mod.original_name})\n") + f.write("\n") + else: + f.write(f"\nCode for {name}, type={mod.original_name}:\n") + f.write(code) + f.write("\n") + f.write("-" * 80) + + for name, m in mod.named_children(): + dump_code(prefix + "." + name, m) + + if isinstance(model, torch.jit.ScriptFunction): + f.write(get_code(model)) + else: + dump_code("", model) + + def _get_graph(model): + try: + # Recursively dump IR of all modules + return _get_script_mod(model)._c.dump_to_str(True, False, False) + except AttributeError: + return model.graph.str() + + with PathManager.open(os.path.join(dir, "model_ts_IR.txt"), "w") as f: + f.write(_get_graph(model)) + + # Dump IR of the entire graph (all submodules inlined) + with PathManager.open(os.path.join(dir, "model_ts_IR_inlined.txt"), "w") as f: + f.write(str(model.inlined_graph)) + + if not isinstance(model, torch.jit.ScriptFunction): + # Dump the model structure in pytorch style + with PathManager.open(os.path.join(dir, "model.txt"), "w") as f: + f.write(str(model)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/torchscript_patch.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/torchscript_patch.py new file mode 100644 index 00000000..24c69b25 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/export/torchscript_patch.py @@ -0,0 +1,406 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +import os +import sys +import tempfile +from contextlib import ExitStack, contextmanager +from copy import deepcopy +from unittest import mock +import torch +from torch import nn + +# need some explicit imports due to https://github.com/pytorch/pytorch/issues/38964 +import annotator.oneformer.detectron2 # noqa F401 +from annotator.oneformer.detectron2.structures import Boxes, Instances +from annotator.oneformer.detectron2.utils.env import _import_file + +_counter = 0 + + +def _clear_jit_cache(): + from torch.jit._recursive import concrete_type_store + from torch.jit._state import _jit_caching_layer + + concrete_type_store.type_store.clear() # for modules + _jit_caching_layer.clear() # for free functions + + +def _add_instances_conversion_methods(newInstances): + """ + Add from_instances methods to the scripted Instances class. + """ + cls_name = newInstances.__name__ + + @torch.jit.unused + def from_instances(instances: Instances): + """ + Create scripted Instances from original Instances + """ + fields = instances.get_fields() + image_size = instances.image_size + ret = newInstances(image_size) + for name, val in fields.items(): + assert hasattr(ret, f"_{name}"), f"No attribute named {name} in {cls_name}" + setattr(ret, name, deepcopy(val)) + return ret + + newInstances.from_instances = from_instances + + +@contextmanager +def patch_instances(fields): + """ + A contextmanager, under which the Instances class in detectron2 is replaced + by a statically-typed scriptable class, defined by `fields`. + See more in `scripting_with_instances`. + """ + + with tempfile.TemporaryDirectory(prefix="detectron2") as dir, tempfile.NamedTemporaryFile( + mode="w", encoding="utf-8", suffix=".py", dir=dir, delete=False + ) as f: + try: + # Objects that use Instances should not reuse previously-compiled + # results in cache, because `Instances` could be a new class each time. + _clear_jit_cache() + + cls_name, s = _gen_instance_module(fields) + f.write(s) + f.flush() + f.close() + + module = _import(f.name) + new_instances = getattr(module, cls_name) + _ = torch.jit.script(new_instances) + # let torchscript think Instances was scripted already + Instances.__torch_script_class__ = True + # let torchscript find new_instances when looking for the jit type of Instances + Instances._jit_override_qualname = torch._jit_internal._qualified_name(new_instances) + + _add_instances_conversion_methods(new_instances) + yield new_instances + finally: + try: + del Instances.__torch_script_class__ + del Instances._jit_override_qualname + except AttributeError: + pass + sys.modules.pop(module.__name__) + + +def _gen_instance_class(fields): + """ + Args: + fields (dict[name: type]) + """ + + class _FieldType: + def __init__(self, name, type_): + assert isinstance(name, str), f"Field name must be str, got {name}" + self.name = name + self.type_ = type_ + self.annotation = f"{type_.__module__}.{type_.__name__}" + + fields = [_FieldType(k, v) for k, v in fields.items()] + + def indent(level, s): + return " " * 4 * level + s + + lines = [] + + global _counter + _counter += 1 + + cls_name = "ScriptedInstances{}".format(_counter) + + field_names = tuple(x.name for x in fields) + extra_args = ", ".join([f"{f.name}: Optional[{f.annotation}] = None" for f in fields]) + lines.append( + f""" +class {cls_name}: + def __init__(self, image_size: Tuple[int, int], {extra_args}): + self.image_size = image_size + self._field_names = {field_names} +""" + ) + + for f in fields: + lines.append( + indent(2, f"self._{f.name} = torch.jit.annotate(Optional[{f.annotation}], {f.name})") + ) + + for f in fields: + lines.append( + f""" + @property + def {f.name}(self) -> {f.annotation}: + # has to use a local for type refinement + # https://pytorch.org/docs/stable/jit_language_reference.html#optional-type-refinement + t = self._{f.name} + assert t is not None, "{f.name} is None and cannot be accessed!" + return t + + @{f.name}.setter + def {f.name}(self, value: {f.annotation}) -> None: + self._{f.name} = value +""" + ) + + # support method `__len__` + lines.append( + """ + def __len__(self) -> int: +""" + ) + for f in fields: + lines.append( + f""" + t = self._{f.name} + if t is not None: + return len(t) +""" + ) + lines.append( + """ + raise NotImplementedError("Empty Instances does not support __len__!") +""" + ) + + # support method `has` + lines.append( + """ + def has(self, name: str) -> bool: +""" + ) + for f in fields: + lines.append( + f""" + if name == "{f.name}": + return self._{f.name} is not None +""" + ) + lines.append( + """ + return False +""" + ) + + # support method `to` + none_args = ", None" * len(fields) + lines.append( + f""" + def to(self, device: torch.device) -> "{cls_name}": + ret = {cls_name}(self.image_size{none_args}) +""" + ) + for f in fields: + if hasattr(f.type_, "to"): + lines.append( + f""" + t = self._{f.name} + if t is not None: + ret._{f.name} = t.to(device) +""" + ) + else: + # For now, ignore fields that cannot be moved to devices. + # Maybe can support other tensor-like classes (e.g. __torch_function__) + pass + lines.append( + """ + return ret +""" + ) + + # support method `getitem` + none_args = ", None" * len(fields) + lines.append( + f""" + def __getitem__(self, item) -> "{cls_name}": + ret = {cls_name}(self.image_size{none_args}) +""" + ) + for f in fields: + lines.append( + f""" + t = self._{f.name} + if t is not None: + ret._{f.name} = t[item] +""" + ) + lines.append( + """ + return ret +""" + ) + + # support method `cat` + # this version does not contain checks that all instances have same size and fields + none_args = ", None" * len(fields) + lines.append( + f""" + def cat(self, instances: List["{cls_name}"]) -> "{cls_name}": + ret = {cls_name}(self.image_size{none_args}) +""" + ) + for f in fields: + lines.append( + f""" + t = self._{f.name} + if t is not None: + values: List[{f.annotation}] = [x.{f.name} for x in instances] + if torch.jit.isinstance(t, torch.Tensor): + ret._{f.name} = torch.cat(values, dim=0) + else: + ret._{f.name} = t.cat(values) +""" + ) + lines.append( + """ + return ret""" + ) + + # support method `get_fields()` + lines.append( + """ + def get_fields(self) -> Dict[str, Tensor]: + ret = {} + """ + ) + for f in fields: + if f.type_ == Boxes: + stmt = "t.tensor" + elif f.type_ == torch.Tensor: + stmt = "t" + else: + stmt = f'assert False, "unsupported type {str(f.type_)}"' + lines.append( + f""" + t = self._{f.name} + if t is not None: + ret["{f.name}"] = {stmt} + """ + ) + lines.append( + """ + return ret""" + ) + return cls_name, os.linesep.join(lines) + + +def _gen_instance_module(fields): + # TODO: find a more automatic way to enable import of other classes + s = """ +from copy import deepcopy +import torch +from torch import Tensor +import typing +from typing import * + +import annotator.oneformer.detectron2 +from annotator.oneformer.detectron2.structures import Boxes, Instances + +""" + + cls_name, cls_def = _gen_instance_class(fields) + s += cls_def + return cls_name, s + + +def _import(path): + return _import_file( + "{}{}".format(sys.modules[__name__].__name__, _counter), path, make_importable=True + ) + + +@contextmanager +def patch_builtin_len(modules=()): + """ + Patch the builtin len() function of a few detectron2 modules + to use __len__ instead, because __len__ does not convert values to + integers and therefore is friendly to tracing. + + Args: + modules (list[stsr]): names of extra modules to patch len(), in + addition to those in detectron2. + """ + + def _new_len(obj): + return obj.__len__() + + with ExitStack() as stack: + MODULES = [ + "detectron2.modeling.roi_heads.fast_rcnn", + "detectron2.modeling.roi_heads.mask_head", + "detectron2.modeling.roi_heads.keypoint_head", + ] + list(modules) + ctxs = [stack.enter_context(mock.patch(mod + ".len")) for mod in MODULES] + for m in ctxs: + m.side_effect = _new_len + yield + + +def patch_nonscriptable_classes(): + """ + Apply patches on a few nonscriptable detectron2 classes. + Should not have side-effects on eager usage. + """ + # __prepare_scriptable__ can also be added to models for easier maintenance. + # But it complicates the clean model code. + + from annotator.oneformer.detectron2.modeling.backbone import ResNet, FPN + + # Due to https://github.com/pytorch/pytorch/issues/36061, + # we change backbone to use ModuleList for scripting. + # (note: this changes param names in state_dict) + + def prepare_resnet(self): + ret = deepcopy(self) + ret.stages = nn.ModuleList(ret.stages) + for k in self.stage_names: + delattr(ret, k) + return ret + + ResNet.__prepare_scriptable__ = prepare_resnet + + def prepare_fpn(self): + ret = deepcopy(self) + ret.lateral_convs = nn.ModuleList(ret.lateral_convs) + ret.output_convs = nn.ModuleList(ret.output_convs) + for name, _ in self.named_children(): + if name.startswith("fpn_"): + delattr(ret, name) + return ret + + FPN.__prepare_scriptable__ = prepare_fpn + + # Annotate some attributes to be constants for the purpose of scripting, + # even though they are not constants in eager mode. + from annotator.oneformer.detectron2.modeling.roi_heads import StandardROIHeads + + if hasattr(StandardROIHeads, "__annotations__"): + # copy first to avoid editing annotations of base class + StandardROIHeads.__annotations__ = deepcopy(StandardROIHeads.__annotations__) + StandardROIHeads.__annotations__["mask_on"] = torch.jit.Final[bool] + StandardROIHeads.__annotations__["keypoint_on"] = torch.jit.Final[bool] + + +# These patches are not supposed to have side-effects. +patch_nonscriptable_classes() + + +@contextmanager +def freeze_training_mode(model): + """ + A context manager that annotates the "training" attribute of every submodule + to constant, so that the training codepath in these modules can be + meta-compiled away. Upon exiting, the annotations are reverted. + """ + classes = {type(x) for x in model.modules()} + # __constants__ is the old way to annotate constants and not compatible + # with __annotations__ . + classes = {x for x in classes if not hasattr(x, "__constants__")} + for cls in classes: + cls.__annotations__["training"] = torch.jit.Final[bool] + yield + for cls in classes: + cls.__annotations__["training"] = bool diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/__init__.py new file mode 100644 index 00000000..761a3d1c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/__init__.py @@ -0,0 +1,26 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from .batch_norm import FrozenBatchNorm2d, get_norm, NaiveSyncBatchNorm, CycleBatchNormList +from .deform_conv import DeformConv, ModulatedDeformConv +from .mask_ops import paste_masks_in_image +from .nms import batched_nms, batched_nms_rotated, nms, nms_rotated +from .roi_align import ROIAlign, roi_align +from .roi_align_rotated import ROIAlignRotated, roi_align_rotated +from .shape_spec import ShapeSpec +from .wrappers import ( + BatchNorm2d, + Conv2d, + ConvTranspose2d, + cat, + interpolate, + Linear, + nonzero_tuple, + cross_entropy, + empty_input_loss_func_wrapper, + shapes_to_tensor, + move_device_like, +) +from .blocks import CNNBlockBase, DepthwiseSeparableConv2d +from .aspp import ASPP +from .losses import ciou_loss, diou_loss + +__all__ = [k for k in globals().keys() if not k.startswith("_")] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/aspp.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/aspp.py new file mode 100644 index 00000000..14861aa9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/aspp.py @@ -0,0 +1,144 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +from copy import deepcopy +import fvcore.nn.weight_init as weight_init +import torch +from torch import nn +from torch.nn import functional as F + +from .batch_norm import get_norm +from .blocks import DepthwiseSeparableConv2d +from .wrappers import Conv2d + + +class ASPP(nn.Module): + """ + Atrous Spatial Pyramid Pooling (ASPP). + """ + + def __init__( + self, + in_channels, + out_channels, + dilations, + *, + norm, + activation, + pool_kernel_size=None, + dropout: float = 0.0, + use_depthwise_separable_conv=False, + ): + """ + Args: + in_channels (int): number of input channels for ASPP. + out_channels (int): number of output channels. + dilations (list): a list of 3 dilations in ASPP. + norm (str or callable): normalization for all conv layers. + See :func:`layers.get_norm` for supported format. norm is + applied to all conv layers except the conv following + global average pooling. + activation (callable): activation function. + pool_kernel_size (tuple, list): the average pooling size (kh, kw) + for image pooling layer in ASPP. If set to None, it always + performs global average pooling. If not None, it must be + divisible by the shape of inputs in forward(). It is recommended + to use a fixed input feature size in training, and set this + option to match this size, so that it performs global average + pooling in training, and the size of the pooling window stays + consistent in inference. + dropout (float): apply dropout on the output of ASPP. It is used in + the official DeepLab implementation with a rate of 0.1: + https://github.com/tensorflow/models/blob/21b73d22f3ed05b650e85ac50849408dd36de32e/research/deeplab/model.py#L532 # noqa + use_depthwise_separable_conv (bool): use DepthwiseSeparableConv2d + for 3x3 convs in ASPP, proposed in :paper:`DeepLabV3+`. + """ + super(ASPP, self).__init__() + assert len(dilations) == 3, "ASPP expects 3 dilations, got {}".format(len(dilations)) + self.pool_kernel_size = pool_kernel_size + self.dropout = dropout + use_bias = norm == "" + self.convs = nn.ModuleList() + # conv 1x1 + self.convs.append( + Conv2d( + in_channels, + out_channels, + kernel_size=1, + bias=use_bias, + norm=get_norm(norm, out_channels), + activation=deepcopy(activation), + ) + ) + weight_init.c2_xavier_fill(self.convs[-1]) + # atrous convs + for dilation in dilations: + if use_depthwise_separable_conv: + self.convs.append( + DepthwiseSeparableConv2d( + in_channels, + out_channels, + kernel_size=3, + padding=dilation, + dilation=dilation, + norm1=norm, + activation1=deepcopy(activation), + norm2=norm, + activation2=deepcopy(activation), + ) + ) + else: + self.convs.append( + Conv2d( + in_channels, + out_channels, + kernel_size=3, + padding=dilation, + dilation=dilation, + bias=use_bias, + norm=get_norm(norm, out_channels), + activation=deepcopy(activation), + ) + ) + weight_init.c2_xavier_fill(self.convs[-1]) + # image pooling + # We do not add BatchNorm because the spatial resolution is 1x1, + # the original TF implementation has BatchNorm. + if pool_kernel_size is None: + image_pooling = nn.Sequential( + nn.AdaptiveAvgPool2d(1), + Conv2d(in_channels, out_channels, 1, bias=True, activation=deepcopy(activation)), + ) + else: + image_pooling = nn.Sequential( + nn.AvgPool2d(kernel_size=pool_kernel_size, stride=1), + Conv2d(in_channels, out_channels, 1, bias=True, activation=deepcopy(activation)), + ) + weight_init.c2_xavier_fill(image_pooling[1]) + self.convs.append(image_pooling) + + self.project = Conv2d( + 5 * out_channels, + out_channels, + kernel_size=1, + bias=use_bias, + norm=get_norm(norm, out_channels), + activation=deepcopy(activation), + ) + weight_init.c2_xavier_fill(self.project) + + def forward(self, x): + size = x.shape[-2:] + if self.pool_kernel_size is not None: + if size[0] % self.pool_kernel_size[0] or size[1] % self.pool_kernel_size[1]: + raise ValueError( + "`pool_kernel_size` must be divisible by the shape of inputs. " + "Input size: {} `pool_kernel_size`: {}".format(size, self.pool_kernel_size) + ) + res = [] + for conv in self.convs: + res.append(conv(x)) + res[-1] = F.interpolate(res[-1], size=size, mode="bilinear", align_corners=False) + res = torch.cat(res, dim=1) + res = self.project(res) + res = F.dropout(res, self.dropout, training=self.training) if self.dropout > 0 else res + return res diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/batch_norm.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/batch_norm.py new file mode 100644 index 00000000..32a1e054 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/batch_norm.py @@ -0,0 +1,300 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import torch +import torch.distributed as dist +from fvcore.nn.distributed import differentiable_all_reduce +from torch import nn +from torch.nn import functional as F + +from annotator.oneformer.detectron2.utils import comm, env + +from .wrappers import BatchNorm2d + + +class FrozenBatchNorm2d(nn.Module): + """ + BatchNorm2d where the batch statistics and the affine parameters are fixed. + + It contains non-trainable buffers called + "weight" and "bias", "running_mean", "running_var", + initialized to perform identity transformation. + + The pre-trained backbone models from Caffe2 only contain "weight" and "bias", + which are computed from the original four parameters of BN. + The affine transform `x * weight + bias` will perform the equivalent + computation of `(x - running_mean) / sqrt(running_var) * weight + bias`. + When loading a backbone model from Caffe2, "running_mean" and "running_var" + will be left unchanged as identity transformation. + + Other pre-trained backbone models may contain all 4 parameters. + + The forward is implemented by `F.batch_norm(..., training=False)`. + """ + + _version = 3 + + def __init__(self, num_features, eps=1e-5): + super().__init__() + self.num_features = num_features + self.eps = eps + self.register_buffer("weight", torch.ones(num_features)) + self.register_buffer("bias", torch.zeros(num_features)) + self.register_buffer("running_mean", torch.zeros(num_features)) + self.register_buffer("running_var", torch.ones(num_features) - eps) + + def forward(self, x): + if x.requires_grad: + # When gradients are needed, F.batch_norm will use extra memory + # because its backward op computes gradients for weight/bias as well. + scale = self.weight * (self.running_var + self.eps).rsqrt() + bias = self.bias - self.running_mean * scale + scale = scale.reshape(1, -1, 1, 1) + bias = bias.reshape(1, -1, 1, 1) + out_dtype = x.dtype # may be half + return x * scale.to(out_dtype) + bias.to(out_dtype) + else: + # When gradients are not needed, F.batch_norm is a single fused op + # and provide more optimization opportunities. + return F.batch_norm( + x, + self.running_mean, + self.running_var, + self.weight, + self.bias, + training=False, + eps=self.eps, + ) + + def _load_from_state_dict( + self, state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs + ): + version = local_metadata.get("version", None) + + if version is None or version < 2: + # No running_mean/var in early versions + # This will silent the warnings + if prefix + "running_mean" not in state_dict: + state_dict[prefix + "running_mean"] = torch.zeros_like(self.running_mean) + if prefix + "running_var" not in state_dict: + state_dict[prefix + "running_var"] = torch.ones_like(self.running_var) + + super()._load_from_state_dict( + state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs + ) + + def __repr__(self): + return "FrozenBatchNorm2d(num_features={}, eps={})".format(self.num_features, self.eps) + + @classmethod + def convert_frozen_batchnorm(cls, module): + """ + Convert all BatchNorm/SyncBatchNorm in module into FrozenBatchNorm. + + Args: + module (torch.nn.Module): + + Returns: + If module is BatchNorm/SyncBatchNorm, returns a new module. + Otherwise, in-place convert module and return it. + + Similar to convert_sync_batchnorm in + https://github.com/pytorch/pytorch/blob/master/torch/nn/modules/batchnorm.py + """ + bn_module = nn.modules.batchnorm + bn_module = (bn_module.BatchNorm2d, bn_module.SyncBatchNorm) + res = module + if isinstance(module, bn_module): + res = cls(module.num_features) + if module.affine: + res.weight.data = module.weight.data.clone().detach() + res.bias.data = module.bias.data.clone().detach() + res.running_mean.data = module.running_mean.data + res.running_var.data = module.running_var.data + res.eps = module.eps + else: + for name, child in module.named_children(): + new_child = cls.convert_frozen_batchnorm(child) + if new_child is not child: + res.add_module(name, new_child) + return res + + +def get_norm(norm, out_channels): + """ + Args: + norm (str or callable): either one of BN, SyncBN, FrozenBN, GN; + or a callable that takes a channel number and returns + the normalization layer as a nn.Module. + + Returns: + nn.Module or None: the normalization layer + """ + if norm is None: + return None + if isinstance(norm, str): + if len(norm) == 0: + return None + norm = { + "BN": BatchNorm2d, + # Fixed in https://github.com/pytorch/pytorch/pull/36382 + "SyncBN": NaiveSyncBatchNorm if env.TORCH_VERSION <= (1, 5) else nn.SyncBatchNorm, + "FrozenBN": FrozenBatchNorm2d, + "GN": lambda channels: nn.GroupNorm(32, channels), + # for debugging: + "nnSyncBN": nn.SyncBatchNorm, + "naiveSyncBN": NaiveSyncBatchNorm, + # expose stats_mode N as an option to caller, required for zero-len inputs + "naiveSyncBN_N": lambda channels: NaiveSyncBatchNorm(channels, stats_mode="N"), + "LN": lambda channels: LayerNorm(channels), + }[norm] + return norm(out_channels) + + +class NaiveSyncBatchNorm(BatchNorm2d): + """ + In PyTorch<=1.5, ``nn.SyncBatchNorm`` has incorrect gradient + when the batch size on each worker is different. + (e.g., when scale augmentation is used, or when it is applied to mask head). + + This is a slower but correct alternative to `nn.SyncBatchNorm`. + + Note: + There isn't a single definition of Sync BatchNorm. + + When ``stats_mode==""``, this module computes overall statistics by using + statistics of each worker with equal weight. The result is true statistics + of all samples (as if they are all on one worker) only when all workers + have the same (N, H, W). This mode does not support inputs with zero batch size. + + When ``stats_mode=="N"``, this module computes overall statistics by weighting + the statistics of each worker by their ``N``. The result is true statistics + of all samples (as if they are all on one worker) only when all workers + have the same (H, W). It is slower than ``stats_mode==""``. + + Even though the result of this module may not be the true statistics of all samples, + it may still be reasonable because it might be preferrable to assign equal weights + to all workers, regardless of their (H, W) dimension, instead of putting larger weight + on larger images. From preliminary experiments, little difference is found between such + a simplified implementation and an accurate computation of overall mean & variance. + """ + + def __init__(self, *args, stats_mode="", **kwargs): + super().__init__(*args, **kwargs) + assert stats_mode in ["", "N"] + self._stats_mode = stats_mode + + def forward(self, input): + if comm.get_world_size() == 1 or not self.training: + return super().forward(input) + + B, C = input.shape[0], input.shape[1] + + half_input = input.dtype == torch.float16 + if half_input: + # fp16 does not have good enough numerics for the reduction here + input = input.float() + mean = torch.mean(input, dim=[0, 2, 3]) + meansqr = torch.mean(input * input, dim=[0, 2, 3]) + + if self._stats_mode == "": + assert B > 0, 'SyncBatchNorm(stats_mode="") does not support zero batch size.' + vec = torch.cat([mean, meansqr], dim=0) + vec = differentiable_all_reduce(vec) * (1.0 / dist.get_world_size()) + mean, meansqr = torch.split(vec, C) + momentum = self.momentum + else: + if B == 0: + vec = torch.zeros([2 * C + 1], device=mean.device, dtype=mean.dtype) + vec = vec + input.sum() # make sure there is gradient w.r.t input + else: + vec = torch.cat( + [mean, meansqr, torch.ones([1], device=mean.device, dtype=mean.dtype)], dim=0 + ) + vec = differentiable_all_reduce(vec * B) + + total_batch = vec[-1].detach() + momentum = total_batch.clamp(max=1) * self.momentum # no update if total_batch is 0 + mean, meansqr, _ = torch.split(vec / total_batch.clamp(min=1), C) # avoid div-by-zero + + var = meansqr - mean * mean + invstd = torch.rsqrt(var + self.eps) + scale = self.weight * invstd + bias = self.bias - mean * scale + scale = scale.reshape(1, -1, 1, 1) + bias = bias.reshape(1, -1, 1, 1) + + self.running_mean += momentum * (mean.detach() - self.running_mean) + self.running_var += momentum * (var.detach() - self.running_var) + ret = input * scale + bias + if half_input: + ret = ret.half() + return ret + + +class CycleBatchNormList(nn.ModuleList): + """ + Implement domain-specific BatchNorm by cycling. + + When a BatchNorm layer is used for multiple input domains or input + features, it might need to maintain a separate test-time statistics + for each domain. See Sec 5.2 in :paper:`rethinking-batchnorm`. + + This module implements it by using N separate BN layers + and it cycles through them every time a forward() is called. + + NOTE: The caller of this module MUST guarantee to always call + this module by multiple of N times. Otherwise its test-time statistics + will be incorrect. + """ + + def __init__(self, length: int, bn_class=nn.BatchNorm2d, **kwargs): + """ + Args: + length: number of BatchNorm layers to cycle. + bn_class: the BatchNorm class to use + kwargs: arguments of the BatchNorm class, such as num_features. + """ + self._affine = kwargs.pop("affine", True) + super().__init__([bn_class(**kwargs, affine=False) for k in range(length)]) + if self._affine: + # shared affine, domain-specific BN + channels = self[0].num_features + self.weight = nn.Parameter(torch.ones(channels)) + self.bias = nn.Parameter(torch.zeros(channels)) + self._pos = 0 + + def forward(self, x): + ret = self[self._pos](x) + self._pos = (self._pos + 1) % len(self) + + if self._affine: + w = self.weight.reshape(1, -1, 1, 1) + b = self.bias.reshape(1, -1, 1, 1) + return ret * w + b + else: + return ret + + def extra_repr(self): + return f"affine={self._affine}" + + +class LayerNorm(nn.Module): + """ + A LayerNorm variant, popularized by Transformers, that performs point-wise mean and + variance normalization over the channel dimension for inputs that have shape + (batch_size, channels, height, width). + https://github.com/facebookresearch/ConvNeXt/blob/d1fa8f6fef0a165b27399986cc2bdacc92777e40/models/convnext.py#L119 # noqa B950 + """ + + def __init__(self, normalized_shape, eps=1e-6): + super().__init__() + self.weight = nn.Parameter(torch.ones(normalized_shape)) + self.bias = nn.Parameter(torch.zeros(normalized_shape)) + self.eps = eps + self.normalized_shape = (normalized_shape,) + + def forward(self, x): + u = x.mean(1, keepdim=True) + s = (x - u).pow(2).mean(1, keepdim=True) + x = (x - u) / torch.sqrt(s + self.eps) + x = self.weight[:, None, None] * x + self.bias[:, None, None] + return x diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/blocks.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/blocks.py new file mode 100644 index 00000000..1995a4bf --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/blocks.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +import fvcore.nn.weight_init as weight_init +from torch import nn + +from .batch_norm import FrozenBatchNorm2d, get_norm +from .wrappers import Conv2d + + +""" +CNN building blocks. +""" + + +class CNNBlockBase(nn.Module): + """ + A CNN block is assumed to have input channels, output channels and a stride. + The input and output of `forward()` method must be NCHW tensors. + The method can perform arbitrary computation but must match the given + channels and stride specification. + + Attribute: + in_channels (int): + out_channels (int): + stride (int): + """ + + def __init__(self, in_channels, out_channels, stride): + """ + The `__init__` method of any subclass should also contain these arguments. + + Args: + in_channels (int): + out_channels (int): + stride (int): + """ + super().__init__() + self.in_channels = in_channels + self.out_channels = out_channels + self.stride = stride + + def freeze(self): + """ + Make this block not trainable. + This method sets all parameters to `requires_grad=False`, + and convert all BatchNorm layers to FrozenBatchNorm + + Returns: + the block itself + """ + for p in self.parameters(): + p.requires_grad = False + FrozenBatchNorm2d.convert_frozen_batchnorm(self) + return self + + +class DepthwiseSeparableConv2d(nn.Module): + """ + A kxk depthwise convolution + a 1x1 convolution. + + In :paper:`xception`, norm & activation are applied on the second conv. + :paper:`mobilenet` uses norm & activation on both convs. + """ + + def __init__( + self, + in_channels, + out_channels, + kernel_size=3, + padding=1, + dilation=1, + *, + norm1=None, + activation1=None, + norm2=None, + activation2=None, + ): + """ + Args: + norm1, norm2 (str or callable): normalization for the two conv layers. + activation1, activation2 (callable(Tensor) -> Tensor): activation + function for the two conv layers. + """ + super().__init__() + self.depthwise = Conv2d( + in_channels, + in_channels, + kernel_size=kernel_size, + padding=padding, + dilation=dilation, + groups=in_channels, + bias=not norm1, + norm=get_norm(norm1, in_channels), + activation=activation1, + ) + self.pointwise = Conv2d( + in_channels, + out_channels, + kernel_size=1, + bias=not norm2, + norm=get_norm(norm2, out_channels), + activation=activation2, + ) + + # default initialization + weight_init.c2_msra_fill(self.depthwise) + weight_init.c2_msra_fill(self.pointwise) + + def forward(self, x): + return self.pointwise(self.depthwise(x)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/README.md b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/README.md new file mode 100644 index 00000000..778ed3da --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/README.md @@ -0,0 +1,7 @@ + + +To add a new Op: + +1. Create a new directory +2. Implement new ops there +3. Delcare its Python interface in `vision.cpp`. diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/ROIAlignRotated/ROIAlignRotated.h b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/ROIAlignRotated/ROIAlignRotated.h new file mode 100644 index 00000000..03f42110 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/ROIAlignRotated/ROIAlignRotated.h @@ -0,0 +1,115 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +#pragma once +#include + +namespace detectron2 { + +at::Tensor ROIAlignRotated_forward_cpu( + const at::Tensor& input, + const at::Tensor& rois, + const float spatial_scale, + const int pooled_height, + const int pooled_width, + const int sampling_ratio); + +at::Tensor ROIAlignRotated_backward_cpu( + const at::Tensor& grad, + const at::Tensor& rois, + const float spatial_scale, + const int pooled_height, + const int pooled_width, + const int batch_size, + const int channels, + const int height, + const int width, + const int sampling_ratio); + +#if defined(WITH_CUDA) || defined(WITH_HIP) +at::Tensor ROIAlignRotated_forward_cuda( + const at::Tensor& input, + const at::Tensor& rois, + const float spatial_scale, + const int pooled_height, + const int pooled_width, + const int sampling_ratio); + +at::Tensor ROIAlignRotated_backward_cuda( + const at::Tensor& grad, + const at::Tensor& rois, + const float spatial_scale, + const int pooled_height, + const int pooled_width, + const int batch_size, + const int channels, + const int height, + const int width, + const int sampling_ratio); +#endif + +// Interface for Python +inline at::Tensor ROIAlignRotated_forward( + const at::Tensor& input, + const at::Tensor& rois, + const double spatial_scale, + const int64_t pooled_height, + const int64_t pooled_width, + const int64_t sampling_ratio) { + if (input.is_cuda()) { +#if defined(WITH_CUDA) || defined(WITH_HIP) + return ROIAlignRotated_forward_cuda( + input, + rois, + spatial_scale, + pooled_height, + pooled_width, + sampling_ratio); +#else + AT_ERROR("Detectron2 is not compiled with GPU support!"); +#endif + } + return ROIAlignRotated_forward_cpu( + input, rois, spatial_scale, pooled_height, pooled_width, sampling_ratio); +} + +inline at::Tensor ROIAlignRotated_backward( + const at::Tensor& grad, + const at::Tensor& rois, + const double spatial_scale, + const int64_t pooled_height, + const int64_t pooled_width, + const int64_t batch_size, + const int64_t channels, + const int64_t height, + const int64_t width, + const int64_t sampling_ratio) { + if (grad.is_cuda()) { +#if defined(WITH_CUDA) || defined(WITH_HIP) + return ROIAlignRotated_backward_cuda( + grad, + rois, + spatial_scale, + pooled_height, + pooled_width, + batch_size, + channels, + height, + width, + sampling_ratio); +#else + AT_ERROR("Detectron2 is not compiled with GPU support!"); +#endif + } + return ROIAlignRotated_backward_cpu( + grad, + rois, + spatial_scale, + pooled_height, + pooled_width, + batch_size, + channels, + height, + width, + sampling_ratio); +} + +} // namespace detectron2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/ROIAlignRotated/ROIAlignRotated_cpu.cpp b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/ROIAlignRotated/ROIAlignRotated_cpu.cpp new file mode 100644 index 00000000..2a3d3056 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/ROIAlignRotated/ROIAlignRotated_cpu.cpp @@ -0,0 +1,522 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +#include +#include "ROIAlignRotated.h" + +// Note: this implementation originates from the Caffe2 ROIAlignRotated Op +// and PyTorch ROIAlign (non-rotated) Op implementations. +// The key difference between this implementation and those ones is +// we don't do "legacy offset" in this version, as there aren't many previous +// works, if any, using the "legacy" ROIAlignRotated Op. +// This would make the interface a bit cleaner. + +namespace detectron2 { + +namespace { +template +struct PreCalc { + int pos1; + int pos2; + int pos3; + int pos4; + T w1; + T w2; + T w3; + T w4; +}; + +template +void pre_calc_for_bilinear_interpolate( + const int height, + const int width, + const int pooled_height, + const int pooled_width, + const int iy_upper, + const int ix_upper, + T roi_start_h, + T roi_start_w, + T bin_size_h, + T bin_size_w, + int roi_bin_grid_h, + int roi_bin_grid_w, + T roi_center_h, + T roi_center_w, + T cos_theta, + T sin_theta, + std::vector>& pre_calc) { + int pre_calc_index = 0; + for (int ph = 0; ph < pooled_height; ph++) { + for (int pw = 0; pw < pooled_width; pw++) { + for (int iy = 0; iy < iy_upper; iy++) { + const T yy = roi_start_h + ph * bin_size_h + + static_cast(iy + .5f) * bin_size_h / + static_cast(roi_bin_grid_h); // e.g., 0.5, 1.5 + for (int ix = 0; ix < ix_upper; ix++) { + const T xx = roi_start_w + pw * bin_size_w + + static_cast(ix + .5f) * bin_size_w / + static_cast(roi_bin_grid_w); + + // Rotate by theta around the center and translate + // In image space, (y, x) is the order for Right Handed System, + // and this is essentially multiplying the point by a rotation matrix + // to rotate it counterclockwise through angle theta. + T y = yy * cos_theta - xx * sin_theta + roi_center_h; + T x = yy * sin_theta + xx * cos_theta + roi_center_w; + // deal with: inverse elements are out of feature map boundary + if (y < -1.0 || y > height || x < -1.0 || x > width) { + // empty + PreCalc pc; + pc.pos1 = 0; + pc.pos2 = 0; + pc.pos3 = 0; + pc.pos4 = 0; + pc.w1 = 0; + pc.w2 = 0; + pc.w3 = 0; + pc.w4 = 0; + pre_calc[pre_calc_index] = pc; + pre_calc_index += 1; + continue; + } + + if (y < 0) { + y = 0; + } + if (x < 0) { + x = 0; + } + + int y_low = (int)y; + int x_low = (int)x; + int y_high; + int x_high; + + if (y_low >= height - 1) { + y_high = y_low = height - 1; + y = (T)y_low; + } else { + y_high = y_low + 1; + } + + if (x_low >= width - 1) { + x_high = x_low = width - 1; + x = (T)x_low; + } else { + x_high = x_low + 1; + } + + T ly = y - y_low; + T lx = x - x_low; + T hy = 1. - ly, hx = 1. - lx; + T w1 = hy * hx, w2 = hy * lx, w3 = ly * hx, w4 = ly * lx; + + // save weights and indices + PreCalc pc; + pc.pos1 = y_low * width + x_low; + pc.pos2 = y_low * width + x_high; + pc.pos3 = y_high * width + x_low; + pc.pos4 = y_high * width + x_high; + pc.w1 = w1; + pc.w2 = w2; + pc.w3 = w3; + pc.w4 = w4; + pre_calc[pre_calc_index] = pc; + + pre_calc_index += 1; + } + } + } + } +} + +template +void bilinear_interpolate_gradient( + const int height, + const int width, + T y, + T x, + T& w1, + T& w2, + T& w3, + T& w4, + int& x_low, + int& x_high, + int& y_low, + int& y_high) { + // deal with cases that inverse elements are out of feature map boundary + if (y < -1.0 || y > height || x < -1.0 || x > width) { + // empty + w1 = w2 = w3 = w4 = 0.; + x_low = x_high = y_low = y_high = -1; + return; + } + + if (y < 0) { + y = 0; + } + + if (x < 0) { + x = 0; + } + + y_low = (int)y; + x_low = (int)x; + + if (y_low >= height - 1) { + y_high = y_low = height - 1; + y = (T)y_low; + } else { + y_high = y_low + 1; + } + + if (x_low >= width - 1) { + x_high = x_low = width - 1; + x = (T)x_low; + } else { + x_high = x_low + 1; + } + + T ly = y - y_low; + T lx = x - x_low; + T hy = 1. - ly, hx = 1. - lx; + + // reference in forward + // T v1 = input[y_low * width + x_low]; + // T v2 = input[y_low * width + x_high]; + // T v3 = input[y_high * width + x_low]; + // T v4 = input[y_high * width + x_high]; + // T val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4); + + w1 = hy * hx, w2 = hy * lx, w3 = ly * hx, w4 = ly * lx; + + return; +} + +template +inline void add(T* address, const T& val) { + *address += val; +} + +} // namespace + +template +void ROIAlignRotatedForward( + const int nthreads, + const T* input, + const T& spatial_scale, + const int channels, + const int height, + const int width, + const int pooled_height, + const int pooled_width, + const int sampling_ratio, + const T* rois, + T* output) { + int n_rois = nthreads / channels / pooled_width / pooled_height; + // (n, c, ph, pw) is an element in the pooled output + // can be parallelized using omp + // #pragma omp parallel for num_threads(32) + for (int n = 0; n < n_rois; n++) { + int index_n = n * channels * pooled_width * pooled_height; + + const T* current_roi = rois + n * 6; + int roi_batch_ind = current_roi[0]; + + // Do not use rounding; this implementation detail is critical + // ROIAlignRotated supports align == true, i.e., continuous coordinate + // by default, thus the 0.5 offset + T offset = (T)0.5; + T roi_center_w = current_roi[1] * spatial_scale - offset; + T roi_center_h = current_roi[2] * spatial_scale - offset; + T roi_width = current_roi[3] * spatial_scale; + T roi_height = current_roi[4] * spatial_scale; + T theta = current_roi[5] * M_PI / 180.0; + T cos_theta = cos(theta); + T sin_theta = sin(theta); + + AT_ASSERTM( + roi_width >= 0 && roi_height >= 0, + "ROIs in ROIAlignRotated do not have non-negative size!"); + + T bin_size_h = static_cast(roi_height) / static_cast(pooled_height); + T bin_size_w = static_cast(roi_width) / static_cast(pooled_width); + + // We use roi_bin_grid to sample the grid and mimic integral + int roi_bin_grid_h = (sampling_ratio > 0) + ? sampling_ratio + : ceil(roi_height / pooled_height); // e.g., = 2 + int roi_bin_grid_w = + (sampling_ratio > 0) ? sampling_ratio : ceil(roi_width / pooled_width); + + // We do average (integral) pooling inside a bin + const T count = std::max(roi_bin_grid_h * roi_bin_grid_w, 1); // e.g. = 4 + + // we want to precalculate indices and weights shared by all channels, + // this is the key point of optimization + std::vector> pre_calc( + roi_bin_grid_h * roi_bin_grid_w * pooled_width * pooled_height); + + // roi_start_h and roi_start_w are computed wrt the center of RoI (x, y). + // Appropriate translation needs to be applied after. + T roi_start_h = -roi_height / 2.0; + T roi_start_w = -roi_width / 2.0; + + pre_calc_for_bilinear_interpolate( + height, + width, + pooled_height, + pooled_width, + roi_bin_grid_h, + roi_bin_grid_w, + roi_start_h, + roi_start_w, + bin_size_h, + bin_size_w, + roi_bin_grid_h, + roi_bin_grid_w, + roi_center_h, + roi_center_w, + cos_theta, + sin_theta, + pre_calc); + + for (int c = 0; c < channels; c++) { + int index_n_c = index_n + c * pooled_width * pooled_height; + const T* offset_input = + input + (roi_batch_ind * channels + c) * height * width; + int pre_calc_index = 0; + + for (int ph = 0; ph < pooled_height; ph++) { + for (int pw = 0; pw < pooled_width; pw++) { + int index = index_n_c + ph * pooled_width + pw; + + T output_val = 0.; + for (int iy = 0; iy < roi_bin_grid_h; iy++) { + for (int ix = 0; ix < roi_bin_grid_w; ix++) { + PreCalc pc = pre_calc[pre_calc_index]; + output_val += pc.w1 * offset_input[pc.pos1] + + pc.w2 * offset_input[pc.pos2] + + pc.w3 * offset_input[pc.pos3] + pc.w4 * offset_input[pc.pos4]; + + pre_calc_index += 1; + } + } + output_val /= count; + + output[index] = output_val; + } // for pw + } // for ph + } // for c + } // for n +} + +template +void ROIAlignRotatedBackward( + const int nthreads, + // may not be contiguous. should index using n_stride, etc + const T* grad_output, + const T& spatial_scale, + const int channels, + const int height, + const int width, + const int pooled_height, + const int pooled_width, + const int sampling_ratio, + T* grad_input, + const T* rois, + const int n_stride, + const int c_stride, + const int h_stride, + const int w_stride) { + for (int index = 0; index < nthreads; index++) { + // (n, c, ph, pw) is an element in the pooled output + int pw = index % pooled_width; + int ph = (index / pooled_width) % pooled_height; + int c = (index / pooled_width / pooled_height) % channels; + int n = index / pooled_width / pooled_height / channels; + + const T* current_roi = rois + n * 6; + int roi_batch_ind = current_roi[0]; + + // Do not use rounding; this implementation detail is critical + // ROIAlignRotated supports align == true, i.e., continuous coordinate + // by default, thus the 0.5 offset + T offset = (T)0.5; + T roi_center_w = current_roi[1] * spatial_scale - offset; + T roi_center_h = current_roi[2] * spatial_scale - offset; + T roi_width = current_roi[3] * spatial_scale; + T roi_height = current_roi[4] * spatial_scale; + T theta = current_roi[5] * M_PI / 180.0; + T cos_theta = cos(theta); + T sin_theta = sin(theta); + + AT_ASSERTM( + roi_width >= 0 && roi_height >= 0, + "ROIs in ROIAlignRotated do not have non-negative size!"); + + T bin_size_h = static_cast(roi_height) / static_cast(pooled_height); + T bin_size_w = static_cast(roi_width) / static_cast(pooled_width); + + T* offset_grad_input = + grad_input + ((roi_batch_ind * channels + c) * height * width); + + int output_offset = n * n_stride + c * c_stride; + const T* offset_grad_output = grad_output + output_offset; + const T grad_output_this_bin = + offset_grad_output[ph * h_stride + pw * w_stride]; + + // We use roi_bin_grid to sample the grid and mimic integral + int roi_bin_grid_h = (sampling_ratio > 0) + ? sampling_ratio + : ceil(roi_height / pooled_height); // e.g., = 2 + int roi_bin_grid_w = + (sampling_ratio > 0) ? sampling_ratio : ceil(roi_width / pooled_width); + + // roi_start_h and roi_start_w are computed wrt the center of RoI (x, y). + // Appropriate translation needs to be applied after. + T roi_start_h = -roi_height / 2.0; + T roi_start_w = -roi_width / 2.0; + + // We do average (integral) pooling inside a bin + const T count = roi_bin_grid_h * roi_bin_grid_w; // e.g. = 4 + + for (int iy = 0; iy < roi_bin_grid_h; iy++) { + const T yy = roi_start_h + ph * bin_size_h + + static_cast(iy + .5f) * bin_size_h / + static_cast(roi_bin_grid_h); // e.g., 0.5, 1.5 + for (int ix = 0; ix < roi_bin_grid_w; ix++) { + const T xx = roi_start_w + pw * bin_size_w + + static_cast(ix + .5f) * bin_size_w / + static_cast(roi_bin_grid_w); + + // Rotate by theta around the center and translate + T y = yy * cos_theta - xx * sin_theta + roi_center_h; + T x = yy * sin_theta + xx * cos_theta + roi_center_w; + + T w1, w2, w3, w4; + int x_low, x_high, y_low, y_high; + + bilinear_interpolate_gradient( + height, width, y, x, w1, w2, w3, w4, x_low, x_high, y_low, y_high); + + T g1 = grad_output_this_bin * w1 / count; + T g2 = grad_output_this_bin * w2 / count; + T g3 = grad_output_this_bin * w3 / count; + T g4 = grad_output_this_bin * w4 / count; + + if (x_low >= 0 && x_high >= 0 && y_low >= 0 && y_high >= 0) { + // atomic add is not needed for now since it is single threaded + add(offset_grad_input + y_low * width + x_low, static_cast(g1)); + add(offset_grad_input + y_low * width + x_high, static_cast(g2)); + add(offset_grad_input + y_high * width + x_low, static_cast(g3)); + add(offset_grad_input + y_high * width + x_high, static_cast(g4)); + } // if + } // ix + } // iy + } // for +} // ROIAlignRotatedBackward + +at::Tensor ROIAlignRotated_forward_cpu( + const at::Tensor& input, + const at::Tensor& rois, + const float spatial_scale, + const int pooled_height, + const int pooled_width, + const int sampling_ratio) { + AT_ASSERTM(input.device().is_cpu(), "input must be a CPU tensor"); + AT_ASSERTM(rois.device().is_cpu(), "rois must be a CPU tensor"); + + at::TensorArg input_t{input, "input", 1}, rois_t{rois, "rois", 2}; + + at::CheckedFrom c = "ROIAlign_forward_cpu"; + at::checkAllSameType(c, {input_t, rois_t}); + + auto num_rois = rois.size(0); + auto channels = input.size(1); + auto height = input.size(2); + auto width = input.size(3); + + at::Tensor output = at::zeros( + {num_rois, channels, pooled_height, pooled_width}, input.options()); + + auto output_size = num_rois * pooled_height * pooled_width * channels; + + if (output.numel() == 0) { + return output; + } + + auto input_ = input.contiguous(), rois_ = rois.contiguous(); + AT_DISPATCH_FLOATING_TYPES_AND_HALF( + input.scalar_type(), "ROIAlignRotated_forward", [&] { + ROIAlignRotatedForward( + output_size, + input_.data_ptr(), + spatial_scale, + channels, + height, + width, + pooled_height, + pooled_width, + sampling_ratio, + rois_.data_ptr(), + output.data_ptr()); + }); + return output; +} + +at::Tensor ROIAlignRotated_backward_cpu( + const at::Tensor& grad, + const at::Tensor& rois, + const float spatial_scale, + const int pooled_height, + const int pooled_width, + const int batch_size, + const int channels, + const int height, + const int width, + const int sampling_ratio) { + AT_ASSERTM(grad.device().is_cpu(), "grad must be a CPU tensor"); + AT_ASSERTM(rois.device().is_cpu(), "rois must be a CPU tensor"); + + at::TensorArg grad_t{grad, "grad", 1}, rois_t{rois, "rois", 2}; + + at::CheckedFrom c = "ROIAlignRotated_backward_cpu"; + at::checkAllSameType(c, {grad_t, rois_t}); + + at::Tensor grad_input = + at::zeros({batch_size, channels, height, width}, grad.options()); + + // handle possibly empty gradients + if (grad.numel() == 0) { + return grad_input; + } + + // get stride values to ensure indexing into gradients is correct. + int n_stride = grad.stride(0); + int c_stride = grad.stride(1); + int h_stride = grad.stride(2); + int w_stride = grad.stride(3); + + auto rois_ = rois.contiguous(); + AT_DISPATCH_FLOATING_TYPES_AND_HALF( + grad.scalar_type(), "ROIAlignRotated_forward", [&] { + ROIAlignRotatedBackward( + grad.numel(), + grad.data_ptr(), + spatial_scale, + channels, + height, + width, + pooled_height, + pooled_width, + sampling_ratio, + grad_input.data_ptr(), + rois_.data_ptr(), + n_stride, + c_stride, + h_stride, + w_stride); + }); + return grad_input; +} + +} // namespace detectron2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/ROIAlignRotated/ROIAlignRotated_cuda.cu b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/ROIAlignRotated/ROIAlignRotated_cuda.cu new file mode 100644 index 00000000..fca18651 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/ROIAlignRotated/ROIAlignRotated_cuda.cu @@ -0,0 +1,443 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +#include +#include +#include +#include + +// TODO make it in a common file +#define CUDA_1D_KERNEL_LOOP(i, n) \ + for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < n; \ + i += blockDim.x * gridDim.x) + +// Note: this implementation originates from the Caffe2 ROIAlignRotated Op +// and PyTorch ROIAlign (non-rotated) Op implementations. +// The key difference between this implementation and those ones is +// we don't do "legacy offset" in this version, as there aren't many previous +// works, if any, using the "legacy" ROIAlignRotated Op. +// This would make the interface a bit cleaner. + +namespace detectron2 { + +namespace { + +template +__device__ T bilinear_interpolate( + const T* input, + const int height, + const int width, + T y, + T x) { + // deal with cases that inverse elements are out of feature map boundary + if (y < -1.0 || y > height || x < -1.0 || x > width) { + // empty + return 0; + } + + if (y < 0) { + y = 0; + } + + if (x < 0) { + x = 0; + } + + int y_low = (int)y; + int x_low = (int)x; + int y_high; + int x_high; + + if (y_low >= height - 1) { + y_high = y_low = height - 1; + y = (T)y_low; + } else { + y_high = y_low + 1; + } + + if (x_low >= width - 1) { + x_high = x_low = width - 1; + x = (T)x_low; + } else { + x_high = x_low + 1; + } + + T ly = y - y_low; + T lx = x - x_low; + T hy = 1. - ly, hx = 1. - lx; + // do bilinear interpolation + T v1 = input[y_low * width + x_low]; + T v2 = input[y_low * width + x_high]; + T v3 = input[y_high * width + x_low]; + T v4 = input[y_high * width + x_high]; + T w1 = hy * hx, w2 = hy * lx, w3 = ly * hx, w4 = ly * lx; + + T val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4); + + return val; +} + +template +__device__ void bilinear_interpolate_gradient( + const int height, + const int width, + T y, + T x, + T& w1, + T& w2, + T& w3, + T& w4, + int& x_low, + int& x_high, + int& y_low, + int& y_high) { + // deal with cases that inverse elements are out of feature map boundary + if (y < -1.0 || y > height || x < -1.0 || x > width) { + // empty + w1 = w2 = w3 = w4 = 0.; + x_low = x_high = y_low = y_high = -1; + return; + } + + if (y < 0) { + y = 0; + } + + if (x < 0) { + x = 0; + } + + y_low = (int)y; + x_low = (int)x; + + if (y_low >= height - 1) { + y_high = y_low = height - 1; + y = (T)y_low; + } else { + y_high = y_low + 1; + } + + if (x_low >= width - 1) { + x_high = x_low = width - 1; + x = (T)x_low; + } else { + x_high = x_low + 1; + } + + T ly = y - y_low; + T lx = x - x_low; + T hy = 1. - ly, hx = 1. - lx; + + // reference in forward + // T v1 = input[y_low * width + x_low]; + // T v2 = input[y_low * width + x_high]; + // T v3 = input[y_high * width + x_low]; + // T v4 = input[y_high * width + x_high]; + // T val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4); + + w1 = hy * hx, w2 = hy * lx, w3 = ly * hx, w4 = ly * lx; + + return; +} + +} // namespace + +template +__global__ void RoIAlignRotatedForward( + const int nthreads, + const T* input, + const T spatial_scale, + const int channels, + const int height, + const int width, + const int pooled_height, + const int pooled_width, + const int sampling_ratio, + const T* rois, + T* top_data) { + CUDA_1D_KERNEL_LOOP(index, nthreads) { + // (n, c, ph, pw) is an element in the pooled output + int pw = index % pooled_width; + int ph = (index / pooled_width) % pooled_height; + int c = (index / pooled_width / pooled_height) % channels; + int n = index / pooled_width / pooled_height / channels; + + const T* current_roi = rois + n * 6; + int roi_batch_ind = current_roi[0]; + + // Do not use rounding; this implementation detail is critical + // ROIAlignRotated supports align == true, i.e., continuous coordinate + // by default, thus the 0.5 offset + T offset = (T)0.5; + T roi_center_w = current_roi[1] * spatial_scale - offset; + T roi_center_h = current_roi[2] * spatial_scale - offset; + T roi_width = current_roi[3] * spatial_scale; + T roi_height = current_roi[4] * spatial_scale; + T theta = current_roi[5] * M_PI / 180.0; + T cos_theta = cos(theta); + T sin_theta = sin(theta); + + T bin_size_h = static_cast(roi_height) / static_cast(pooled_height); + T bin_size_w = static_cast(roi_width) / static_cast(pooled_width); + + const T* offset_input = + input + (roi_batch_ind * channels + c) * height * width; + + // We use roi_bin_grid to sample the grid and mimic integral + int roi_bin_grid_h = (sampling_ratio > 0) + ? sampling_ratio + : ceil(roi_height / pooled_height); // e.g., = 2 + int roi_bin_grid_w = + (sampling_ratio > 0) ? sampling_ratio : ceil(roi_width / pooled_width); + + // roi_start_h and roi_start_w are computed wrt the center of RoI (x, y). + // Appropriate translation needs to be applied after. + T roi_start_h = -roi_height / 2.0; + T roi_start_w = -roi_width / 2.0; + + // We do average (inte gral) pooling inside a bin + const T count = max(roi_bin_grid_h * roi_bin_grid_w, 1); // e.g. = 4 + + T output_val = 0.; + for (int iy = 0; iy < roi_bin_grid_h; iy++) // e.g., iy = 0, 1 + { + const T yy = roi_start_h + ph * bin_size_h + + static_cast(iy + .5f) * bin_size_h / + static_cast(roi_bin_grid_h); // e.g., 0.5, 1.5 + for (int ix = 0; ix < roi_bin_grid_w; ix++) { + const T xx = roi_start_w + pw * bin_size_w + + static_cast(ix + .5f) * bin_size_w / + static_cast(roi_bin_grid_w); + + // Rotate by theta around the center and translate + T y = yy * cos_theta - xx * sin_theta + roi_center_h; + T x = yy * sin_theta + xx * cos_theta + roi_center_w; + + T val = bilinear_interpolate(offset_input, height, width, y, x); + output_val += val; + } + } + output_val /= count; + + top_data[index] = output_val; + } +} + +template +__global__ void RoIAlignRotatedBackwardFeature( + const int nthreads, + const T* top_diff, + const int num_rois, + const T spatial_scale, + const int channels, + const int height, + const int width, + const int pooled_height, + const int pooled_width, + const int sampling_ratio, + T* bottom_diff, + const T* rois) { + CUDA_1D_KERNEL_LOOP(index, nthreads) { + // (n, c, ph, pw) is an element in the pooled output + int pw = index % pooled_width; + int ph = (index / pooled_width) % pooled_height; + int c = (index / pooled_width / pooled_height) % channels; + int n = index / pooled_width / pooled_height / channels; + + const T* current_roi = rois + n * 6; + int roi_batch_ind = current_roi[0]; + + // Do not use rounding; this implementation detail is critical + // ROIAlignRotated supports align == true, i.e., continuous coordinate + // by default, thus the 0.5 offset + T offset = (T)0.5; + T roi_center_w = current_roi[1] * spatial_scale - offset; + T roi_center_h = current_roi[2] * spatial_scale - offset; + T roi_width = current_roi[3] * spatial_scale; + T roi_height = current_roi[4] * spatial_scale; + T theta = current_roi[5] * M_PI / 180.0; + T cos_theta = cos(theta); + T sin_theta = sin(theta); + + T bin_size_h = static_cast(roi_height) / static_cast(pooled_height); + T bin_size_w = static_cast(roi_width) / static_cast(pooled_width); + + T* offset_bottom_diff = + bottom_diff + (roi_batch_ind * channels + c) * height * width; + + int top_offset = (n * channels + c) * pooled_height * pooled_width; + const T* offset_top_diff = top_diff + top_offset; + const T top_diff_this_bin = offset_top_diff[ph * pooled_width + pw]; + + // We use roi_bin_grid to sample the grid and mimic integral + int roi_bin_grid_h = (sampling_ratio > 0) + ? sampling_ratio + : ceil(roi_height / pooled_height); // e.g., = 2 + int roi_bin_grid_w = + (sampling_ratio > 0) ? sampling_ratio : ceil(roi_width / pooled_width); + + // roi_start_h and roi_start_w are computed wrt the center of RoI (x, y). + // Appropriate translation needs to be applied after. + T roi_start_h = -roi_height / 2.0; + T roi_start_w = -roi_width / 2.0; + + // We do average (integral) pooling inside a bin + const T count = roi_bin_grid_h * roi_bin_grid_w; // e.g. = 4 + + for (int iy = 0; iy < roi_bin_grid_h; iy++) // e.g., iy = 0, 1 + { + const T yy = roi_start_h + ph * bin_size_h + + static_cast(iy + .5f) * bin_size_h / + static_cast(roi_bin_grid_h); // e.g., 0.5, 1.5 + for (int ix = 0; ix < roi_bin_grid_w; ix++) { + const T xx = roi_start_w + pw * bin_size_w + + static_cast(ix + .5f) * bin_size_w / + static_cast(roi_bin_grid_w); + + // Rotate by theta around the center and translate + T y = yy * cos_theta - xx * sin_theta + roi_center_h; + T x = yy * sin_theta + xx * cos_theta + roi_center_w; + + T w1, w2, w3, w4; + int x_low, x_high, y_low, y_high; + + bilinear_interpolate_gradient( + height, width, y, x, w1, w2, w3, w4, x_low, x_high, y_low, y_high); + + T g1 = top_diff_this_bin * w1 / count; + T g2 = top_diff_this_bin * w2 / count; + T g3 = top_diff_this_bin * w3 / count; + T g4 = top_diff_this_bin * w4 / count; + + if (x_low >= 0 && x_high >= 0 && y_low >= 0 && y_high >= 0) { + atomicAdd( + offset_bottom_diff + y_low * width + x_low, static_cast(g1)); + atomicAdd( + offset_bottom_diff + y_low * width + x_high, static_cast(g2)); + atomicAdd( + offset_bottom_diff + y_high * width + x_low, static_cast(g3)); + atomicAdd( + offset_bottom_diff + y_high * width + x_high, static_cast(g4)); + } // if + } // ix + } // iy + } // CUDA_1D_KERNEL_LOOP +} // RoIAlignRotatedBackward + +at::Tensor ROIAlignRotated_forward_cuda( + const at::Tensor& input, + const at::Tensor& rois, + const float spatial_scale, + const int pooled_height, + const int pooled_width, + const int sampling_ratio) { + AT_ASSERTM(input.device().is_cuda(), "input must be a CUDA tensor"); + AT_ASSERTM(rois.device().is_cuda(), "rois must be a CUDA tensor"); + at::TensorArg input_t{input, "input", 1}, rois_t{rois, "rois", 2}; + + at::CheckedFrom c = "ROIAlignRotated_forward_cuda"; + at::checkAllSameGPU(c, {input_t, rois_t}); + at::checkAllSameType(c, {input_t, rois_t}); + at::cuda::CUDAGuard device_guard(input.device()); + + auto num_rois = rois.size(0); + auto channels = input.size(1); + auto height = input.size(2); + auto width = input.size(3); + + auto output = at::empty( + {num_rois, channels, pooled_height, pooled_width}, input.options()); + auto output_size = num_rois * pooled_height * pooled_width * channels; + cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + + dim3 grid(std::min( + at::cuda::ATenCeilDiv( + static_cast(output_size), static_cast(512)), + static_cast(4096))); + dim3 block(512); + + if (output.numel() == 0) { + AT_CUDA_CHECK(cudaGetLastError()); + return output; + } + + auto input_ = input.contiguous(), rois_ = rois.contiguous(); + AT_DISPATCH_FLOATING_TYPES( + input.scalar_type(), "ROIAlignRotated_forward", [&] { + RoIAlignRotatedForward<<>>( + output_size, + input_.data_ptr(), + spatial_scale, + channels, + height, + width, + pooled_height, + pooled_width, + sampling_ratio, + rois_.data_ptr(), + output.data_ptr()); + }); + cudaDeviceSynchronize(); + AT_CUDA_CHECK(cudaGetLastError()); + return output; +} + +// TODO remove the dependency on input and use instead its sizes -> save memory +at::Tensor ROIAlignRotated_backward_cuda( + const at::Tensor& grad, + const at::Tensor& rois, + const float spatial_scale, + const int pooled_height, + const int pooled_width, + const int batch_size, + const int channels, + const int height, + const int width, + const int sampling_ratio) { + AT_ASSERTM(grad.device().is_cuda(), "grad must be a CUDA tensor"); + AT_ASSERTM(rois.device().is_cuda(), "rois must be a CUDA tensor"); + + at::TensorArg grad_t{grad, "grad", 1}, rois_t{rois, "rois", 2}; + at::CheckedFrom c = "ROIAlign_backward_cuda"; + at::checkAllSameGPU(c, {grad_t, rois_t}); + at::checkAllSameType(c, {grad_t, rois_t}); + at::cuda::CUDAGuard device_guard(grad.device()); + + auto num_rois = rois.size(0); + auto grad_input = + at::zeros({batch_size, channels, height, width}, grad.options()); + + cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + + dim3 grid(std::min( + at::cuda::ATenCeilDiv( + static_cast(grad.numel()), static_cast(512)), + static_cast(4096))); + dim3 block(512); + + // handle possibly empty gradients + if (grad.numel() == 0) { + AT_CUDA_CHECK(cudaGetLastError()); + return grad_input; + } + + auto grad_ = grad.contiguous(), rois_ = rois.contiguous(); + AT_DISPATCH_FLOATING_TYPES( + grad.scalar_type(), "ROIAlignRotated_backward", [&] { + RoIAlignRotatedBackwardFeature<<>>( + grad.numel(), + grad_.data_ptr(), + num_rois, + spatial_scale, + channels, + height, + width, + pooled_height, + pooled_width, + sampling_ratio, + grad_input.data_ptr(), + rois_.data_ptr()); + }); + AT_CUDA_CHECK(cudaGetLastError()); + return grad_input; +} + +} // namespace detectron2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/box_iou_rotated/box_iou_rotated.h b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/box_iou_rotated/box_iou_rotated.h new file mode 100644 index 00000000..3bf383b8 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/box_iou_rotated/box_iou_rotated.h @@ -0,0 +1,35 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +#pragma once +#include + +namespace detectron2 { + +at::Tensor box_iou_rotated_cpu( + const at::Tensor& boxes1, + const at::Tensor& boxes2); + +#if defined(WITH_CUDA) || defined(WITH_HIP) +at::Tensor box_iou_rotated_cuda( + const at::Tensor& boxes1, + const at::Tensor& boxes2); +#endif + +// Interface for Python +// inline is needed to prevent multiple function definitions when this header is +// included by different cpps +inline at::Tensor box_iou_rotated( + const at::Tensor& boxes1, + const at::Tensor& boxes2) { + assert(boxes1.device().is_cuda() == boxes2.device().is_cuda()); + if (boxes1.device().is_cuda()) { +#if defined(WITH_CUDA) || defined(WITH_HIP) + return box_iou_rotated_cuda(boxes1.contiguous(), boxes2.contiguous()); +#else + AT_ERROR("Detectron2 is not compiled with GPU support!"); +#endif + } + + return box_iou_rotated_cpu(boxes1.contiguous(), boxes2.contiguous()); +} + +} // namespace detectron2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/box_iou_rotated/box_iou_rotated_cpu.cpp b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/box_iou_rotated/box_iou_rotated_cpu.cpp new file mode 100644 index 00000000..c843487b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/box_iou_rotated/box_iou_rotated_cpu.cpp @@ -0,0 +1,39 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +#include "box_iou_rotated.h" +#include "box_iou_rotated_utils.h" + +namespace detectron2 { + +template +void box_iou_rotated_cpu_kernel( + const at::Tensor& boxes1, + const at::Tensor& boxes2, + at::Tensor& ious) { + auto num_boxes1 = boxes1.size(0); + auto num_boxes2 = boxes2.size(0); + + for (int i = 0; i < num_boxes1; i++) { + for (int j = 0; j < num_boxes2; j++) { + ious[i * num_boxes2 + j] = single_box_iou_rotated( + boxes1[i].data_ptr(), boxes2[j].data_ptr()); + } + } +} + +at::Tensor box_iou_rotated_cpu( + // input must be contiguous: + const at::Tensor& boxes1, + const at::Tensor& boxes2) { + auto num_boxes1 = boxes1.size(0); + auto num_boxes2 = boxes2.size(0); + at::Tensor ious = + at::empty({num_boxes1 * num_boxes2}, boxes1.options().dtype(at::kFloat)); + + box_iou_rotated_cpu_kernel(boxes1, boxes2, ious); + + // reshape from 1d array to 2d array + auto shape = std::vector{num_boxes1, num_boxes2}; + return ious.reshape(shape); +} + +} // namespace detectron2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/box_iou_rotated/box_iou_rotated_cuda.cu b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/box_iou_rotated/box_iou_rotated_cuda.cu new file mode 100644 index 00000000..952710e5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/box_iou_rotated/box_iou_rotated_cuda.cu @@ -0,0 +1,130 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +#include +#include +#include +#include +#include "box_iou_rotated_utils.h" + +namespace detectron2 { + +// 2D block with 32 * 16 = 512 threads per block +const int BLOCK_DIM_X = 32; +const int BLOCK_DIM_Y = 16; + +template +__global__ void box_iou_rotated_cuda_kernel( + const int n_boxes1, + const int n_boxes2, + const T* dev_boxes1, + const T* dev_boxes2, + T* dev_ious) { + const int row_start = blockIdx.x * blockDim.x; + const int col_start = blockIdx.y * blockDim.y; + + const int row_size = min(n_boxes1 - row_start, blockDim.x); + const int col_size = min(n_boxes2 - col_start, blockDim.y); + + __shared__ float block_boxes1[BLOCK_DIM_X * 5]; + __shared__ float block_boxes2[BLOCK_DIM_Y * 5]; + + // It's safe to copy using threadIdx.x since BLOCK_DIM_X >= BLOCK_DIM_Y + if (threadIdx.x < row_size && threadIdx.y == 0) { + block_boxes1[threadIdx.x * 5 + 0] = + dev_boxes1[(row_start + threadIdx.x) * 5 + 0]; + block_boxes1[threadIdx.x * 5 + 1] = + dev_boxes1[(row_start + threadIdx.x) * 5 + 1]; + block_boxes1[threadIdx.x * 5 + 2] = + dev_boxes1[(row_start + threadIdx.x) * 5 + 2]; + block_boxes1[threadIdx.x * 5 + 3] = + dev_boxes1[(row_start + threadIdx.x) * 5 + 3]; + block_boxes1[threadIdx.x * 5 + 4] = + dev_boxes1[(row_start + threadIdx.x) * 5 + 4]; + } + + if (threadIdx.x < col_size && threadIdx.y == 0) { + block_boxes2[threadIdx.x * 5 + 0] = + dev_boxes2[(col_start + threadIdx.x) * 5 + 0]; + block_boxes2[threadIdx.x * 5 + 1] = + dev_boxes2[(col_start + threadIdx.x) * 5 + 1]; + block_boxes2[threadIdx.x * 5 + 2] = + dev_boxes2[(col_start + threadIdx.x) * 5 + 2]; + block_boxes2[threadIdx.x * 5 + 3] = + dev_boxes2[(col_start + threadIdx.x) * 5 + 3]; + block_boxes2[threadIdx.x * 5 + 4] = + dev_boxes2[(col_start + threadIdx.x) * 5 + 4]; + } + __syncthreads(); + + if (threadIdx.x < row_size && threadIdx.y < col_size) { + int offset = (row_start + threadIdx.x) * n_boxes2 + col_start + threadIdx.y; + dev_ious[offset] = single_box_iou_rotated( + block_boxes1 + threadIdx.x * 5, block_boxes2 + threadIdx.y * 5); + } +} + +at::Tensor box_iou_rotated_cuda( + // input must be contiguous + const at::Tensor& boxes1, + const at::Tensor& boxes2) { + using scalar_t = float; + AT_ASSERTM( + boxes1.scalar_type() == at::kFloat, "boxes1 must be a float tensor"); + AT_ASSERTM( + boxes2.scalar_type() == at::kFloat, "boxes2 must be a float tensor"); + AT_ASSERTM(boxes1.is_cuda(), "boxes1 must be a CUDA tensor"); + AT_ASSERTM(boxes2.is_cuda(), "boxes2 must be a CUDA tensor"); + at::cuda::CUDAGuard device_guard(boxes1.device()); + + auto num_boxes1 = boxes1.size(0); + auto num_boxes2 = boxes2.size(0); + + at::Tensor ious = + at::empty({num_boxes1 * num_boxes2}, boxes1.options().dtype(at::kFloat)); + + bool transpose = false; + if (num_boxes1 > 0 && num_boxes2 > 0) { + scalar_t *data1 = boxes1.data_ptr(), + *data2 = boxes2.data_ptr(); + + if (num_boxes2 > 65535 * BLOCK_DIM_Y) { + AT_ASSERTM( + num_boxes1 <= 65535 * BLOCK_DIM_Y, + "Too many boxes for box_iou_rotated_cuda!"); + // x dim is allowed to be large, but y dim cannot, + // so we transpose the two to avoid "invalid configuration argument" + // error. We assume one of them is small. Otherwise the result is hard to + // fit in memory anyway. + std::swap(num_boxes1, num_boxes2); + std::swap(data1, data2); + transpose = true; + } + + const int blocks_x = + at::cuda::ATenCeilDiv(static_cast(num_boxes1), BLOCK_DIM_X); + const int blocks_y = + at::cuda::ATenCeilDiv(static_cast(num_boxes2), BLOCK_DIM_Y); + + dim3 blocks(blocks_x, blocks_y); + dim3 threads(BLOCK_DIM_X, BLOCK_DIM_Y); + cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + + box_iou_rotated_cuda_kernel<<>>( + num_boxes1, + num_boxes2, + data1, + data2, + (scalar_t*)ious.data_ptr()); + + AT_CUDA_CHECK(cudaGetLastError()); + } + + // reshape from 1d array to 2d array + auto shape = std::vector{num_boxes1, num_boxes2}; + if (transpose) { + return ious.view(shape).t(); + } else { + return ious.view(shape); + } +} + +} // namespace detectron2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/box_iou_rotated/box_iou_rotated_utils.h b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/box_iou_rotated/box_iou_rotated_utils.h new file mode 100644 index 00000000..b54a5dde --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/box_iou_rotated/box_iou_rotated_utils.h @@ -0,0 +1,370 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +#pragma once + +#include +#include + +#if defined(__CUDACC__) || __HCC__ == 1 || __HIP__ == 1 +// Designates functions callable from the host (CPU) and the device (GPU) +#define HOST_DEVICE __host__ __device__ +#define HOST_DEVICE_INLINE HOST_DEVICE __forceinline__ +#else +#include +#define HOST_DEVICE +#define HOST_DEVICE_INLINE HOST_DEVICE inline +#endif + +namespace detectron2 { + +namespace { + +template +struct RotatedBox { + T x_ctr, y_ctr, w, h, a; +}; + +template +struct Point { + T x, y; + HOST_DEVICE_INLINE Point(const T& px = 0, const T& py = 0) : x(px), y(py) {} + HOST_DEVICE_INLINE Point operator+(const Point& p) const { + return Point(x + p.x, y + p.y); + } + HOST_DEVICE_INLINE Point& operator+=(const Point& p) { + x += p.x; + y += p.y; + return *this; + } + HOST_DEVICE_INLINE Point operator-(const Point& p) const { + return Point(x - p.x, y - p.y); + } + HOST_DEVICE_INLINE Point operator*(const T coeff) const { + return Point(x * coeff, y * coeff); + } +}; + +template +HOST_DEVICE_INLINE T dot_2d(const Point& A, const Point& B) { + return A.x * B.x + A.y * B.y; +} + +// R: result type. can be different from input type +template +HOST_DEVICE_INLINE R cross_2d(const Point& A, const Point& B) { + return static_cast(A.x) * static_cast(B.y) - + static_cast(B.x) * static_cast(A.y); +} + +template +HOST_DEVICE_INLINE void get_rotated_vertices( + const RotatedBox& box, + Point (&pts)[4]) { + // M_PI / 180. == 0.01745329251 + double theta = box.a * 0.01745329251; + T cosTheta2 = (T)cos(theta) * 0.5f; + T sinTheta2 = (T)sin(theta) * 0.5f; + + // y: top --> down; x: left --> right + pts[0].x = box.x_ctr + sinTheta2 * box.h + cosTheta2 * box.w; + pts[0].y = box.y_ctr + cosTheta2 * box.h - sinTheta2 * box.w; + pts[1].x = box.x_ctr - sinTheta2 * box.h + cosTheta2 * box.w; + pts[1].y = box.y_ctr - cosTheta2 * box.h - sinTheta2 * box.w; + pts[2].x = 2 * box.x_ctr - pts[0].x; + pts[2].y = 2 * box.y_ctr - pts[0].y; + pts[3].x = 2 * box.x_ctr - pts[1].x; + pts[3].y = 2 * box.y_ctr - pts[1].y; +} + +template +HOST_DEVICE_INLINE int get_intersection_points( + const Point (&pts1)[4], + const Point (&pts2)[4], + Point (&intersections)[24]) { + // Line vector + // A line from p1 to p2 is: p1 + (p2-p1)*t, t=[0,1] + Point vec1[4], vec2[4]; + for (int i = 0; i < 4; i++) { + vec1[i] = pts1[(i + 1) % 4] - pts1[i]; + vec2[i] = pts2[(i + 1) % 4] - pts2[i]; + } + + // When computing the intersection area, it doesn't hurt if we have + // more (duplicated/approximate) intersections/vertices than needed, + // while it can cause drastic difference if we miss an intersection/vertex. + // Therefore, we add an epsilon to relax the comparisons between + // the float point numbers that decide the intersection points. + double EPS = 1e-5; + + // Line test - test all line combos for intersection + int num = 0; // number of intersections + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + // Solve for 2x2 Ax=b + T det = cross_2d(vec2[j], vec1[i]); + + // This takes care of parallel lines + if (fabs(det) <= 1e-14) { + continue; + } + + auto vec12 = pts2[j] - pts1[i]; + + T t1 = cross_2d(vec2[j], vec12) / det; + T t2 = cross_2d(vec1[i], vec12) / det; + + if (t1 > -EPS && t1 < 1.0f + EPS && t2 > -EPS && t2 < 1.0f + EPS) { + intersections[num++] = pts1[i] + vec1[i] * t1; + } + } + } + + // Check for vertices of rect1 inside rect2 + { + const auto& AB = vec2[0]; + const auto& DA = vec2[3]; + auto ABdotAB = dot_2d(AB, AB); + auto ADdotAD = dot_2d(DA, DA); + for (int i = 0; i < 4; i++) { + // assume ABCD is the rectangle, and P is the point to be judged + // P is inside ABCD iff. P's projection on AB lies within AB + // and P's projection on AD lies within AD + + auto AP = pts1[i] - pts2[0]; + + auto APdotAB = dot_2d(AP, AB); + auto APdotAD = -dot_2d(AP, DA); + + if ((APdotAB > -EPS) && (APdotAD > -EPS) && (APdotAB < ABdotAB + EPS) && + (APdotAD < ADdotAD + EPS)) { + intersections[num++] = pts1[i]; + } + } + } + + // Reverse the check - check for vertices of rect2 inside rect1 + { + const auto& AB = vec1[0]; + const auto& DA = vec1[3]; + auto ABdotAB = dot_2d(AB, AB); + auto ADdotAD = dot_2d(DA, DA); + for (int i = 0; i < 4; i++) { + auto AP = pts2[i] - pts1[0]; + + auto APdotAB = dot_2d(AP, AB); + auto APdotAD = -dot_2d(AP, DA); + + if ((APdotAB > -EPS) && (APdotAD > -EPS) && (APdotAB < ABdotAB + EPS) && + (APdotAD < ADdotAD + EPS)) { + intersections[num++] = pts2[i]; + } + } + } + + return num; +} + +template +HOST_DEVICE_INLINE int convex_hull_graham( + const Point (&p)[24], + const int& num_in, + Point (&q)[24], + bool shift_to_zero = false) { + assert(num_in >= 2); + + // Step 1: + // Find point with minimum y + // if more than 1 points have the same minimum y, + // pick the one with the minimum x. + int t = 0; + for (int i = 1; i < num_in; i++) { + if (p[i].y < p[t].y || (p[i].y == p[t].y && p[i].x < p[t].x)) { + t = i; + } + } + auto& start = p[t]; // starting point + + // Step 2: + // Subtract starting point from every points (for sorting in the next step) + for (int i = 0; i < num_in; i++) { + q[i] = p[i] - start; + } + + // Swap the starting point to position 0 + auto tmp = q[0]; + q[0] = q[t]; + q[t] = tmp; + + // Step 3: + // Sort point 1 ~ num_in according to their relative cross-product values + // (essentially sorting according to angles) + // If the angles are the same, sort according to their distance to origin + T dist[24]; +#if defined(__CUDACC__) || __HCC__ == 1 || __HIP__ == 1 + // compute distance to origin before sort, and sort them together with the + // points + for (int i = 0; i < num_in; i++) { + dist[i] = dot_2d(q[i], q[i]); + } + + // CUDA version + // In the future, we can potentially use thrust + // for sorting here to improve speed (though not guaranteed) + for (int i = 1; i < num_in - 1; i++) { + for (int j = i + 1; j < num_in; j++) { + T crossProduct = cross_2d(q[i], q[j]); + if ((crossProduct < -1e-6) || + (fabs(crossProduct) < 1e-6 && dist[i] > dist[j])) { + auto q_tmp = q[i]; + q[i] = q[j]; + q[j] = q_tmp; + auto dist_tmp = dist[i]; + dist[i] = dist[j]; + dist[j] = dist_tmp; + } + } + } +#else + // CPU version + std::sort( + q + 1, q + num_in, [](const Point& A, const Point& B) -> bool { + T temp = cross_2d(A, B); + if (fabs(temp) < 1e-6) { + return dot_2d(A, A) < dot_2d(B, B); + } else { + return temp > 0; + } + }); + // compute distance to origin after sort, since the points are now different. + for (int i = 0; i < num_in; i++) { + dist[i] = dot_2d(q[i], q[i]); + } +#endif + + // Step 4: + // Make sure there are at least 2 points (that don't overlap with each other) + // in the stack + int k; // index of the non-overlapped second point + for (k = 1; k < num_in; k++) { + if (dist[k] > 1e-8) { + break; + } + } + if (k == num_in) { + // We reach the end, which means the convex hull is just one point + q[0] = p[t]; + return 1; + } + q[1] = q[k]; + int m = 2; // 2 points in the stack + // Step 5: + // Finally we can start the scanning process. + // When a non-convex relationship between the 3 points is found + // (either concave shape or duplicated points), + // we pop the previous point from the stack + // until the 3-point relationship is convex again, or + // until the stack only contains two points + for (int i = k + 1; i < num_in; i++) { + while (m > 1) { + auto q1 = q[i] - q[m - 2], q2 = q[m - 1] - q[m - 2]; + // cross_2d() uses FMA and therefore computes round(round(q1.x*q2.y) - + // q2.x*q1.y) So it may not return 0 even when q1==q2. Therefore we + // compare round(q1.x*q2.y) and round(q2.x*q1.y) directly. (round means + // round to nearest floating point). + if (q1.x * q2.y >= q2.x * q1.y) + m--; + else + break; + } + // Using double also helps, but float can solve the issue for now. + // while (m > 1 && cross_2d(q[i] - q[m - 2], q[m - 1] - q[m - 2]) + // >= 0) { + // m--; + // } + q[m++] = q[i]; + } + + // Step 6 (Optional): + // In general sense we need the original coordinates, so we + // need to shift the points back (reverting Step 2) + // But if we're only interested in getting the area/perimeter of the shape + // We can simply return. + if (!shift_to_zero) { + for (int i = 0; i < m; i++) { + q[i] += start; + } + } + + return m; +} + +template +HOST_DEVICE_INLINE T polygon_area(const Point (&q)[24], const int& m) { + if (m <= 2) { + return 0; + } + + T area = 0; + for (int i = 1; i < m - 1; i++) { + area += fabs(cross_2d(q[i] - q[0], q[i + 1] - q[0])); + } + + return area / 2.0; +} + +template +HOST_DEVICE_INLINE T rotated_boxes_intersection( + const RotatedBox& box1, + const RotatedBox& box2) { + // There are up to 4 x 4 + 4 + 4 = 24 intersections (including dups) returned + // from rotated_rect_intersection_pts + Point intersectPts[24], orderedPts[24]; + + Point pts1[4]; + Point pts2[4]; + get_rotated_vertices(box1, pts1); + get_rotated_vertices(box2, pts2); + + int num = get_intersection_points(pts1, pts2, intersectPts); + + if (num <= 2) { + return 0.0; + } + + // Convex Hull to order the intersection points in clockwise order and find + // the contour area. + int num_convex = convex_hull_graham(intersectPts, num, orderedPts, true); + return polygon_area(orderedPts, num_convex); +} + +} // namespace + +template +HOST_DEVICE_INLINE T +single_box_iou_rotated(T const* const box1_raw, T const* const box2_raw) { + // shift center to the middle point to achieve higher precision in result + RotatedBox box1, box2; + auto center_shift_x = (box1_raw[0] + box2_raw[0]) / 2.0; + auto center_shift_y = (box1_raw[1] + box2_raw[1]) / 2.0; + box1.x_ctr = box1_raw[0] - center_shift_x; + box1.y_ctr = box1_raw[1] - center_shift_y; + box1.w = box1_raw[2]; + box1.h = box1_raw[3]; + box1.a = box1_raw[4]; + box2.x_ctr = box2_raw[0] - center_shift_x; + box2.y_ctr = box2_raw[1] - center_shift_y; + box2.w = box2_raw[2]; + box2.h = box2_raw[3]; + box2.a = box2_raw[4]; + + T area1 = box1.w * box1.h; + T area2 = box2.w * box2.h; + if (area1 < 1e-14 || area2 < 1e-14) { + return 0.f; + } + + T intersection = rotated_boxes_intersection(box1, box2); + T iou = intersection / (area1 + area2 - intersection); + return iou; +} + +} // namespace detectron2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/cocoeval/cocoeval.cpp b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/cocoeval/cocoeval.cpp new file mode 100644 index 00000000..0a5b7b90 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/cocoeval/cocoeval.cpp @@ -0,0 +1,507 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +#include "cocoeval.h" +#include +#include +#include +#include + +using namespace pybind11::literals; + +namespace detectron2 { + +namespace COCOeval { + +// Sort detections from highest score to lowest, such that +// detection_instances[detection_sorted_indices[t]] >= +// detection_instances[detection_sorted_indices[t+1]]. Use stable_sort to match +// original COCO API +void SortInstancesByDetectionScore( + const std::vector& detection_instances, + std::vector* detection_sorted_indices) { + detection_sorted_indices->resize(detection_instances.size()); + std::iota( + detection_sorted_indices->begin(), detection_sorted_indices->end(), 0); + std::stable_sort( + detection_sorted_indices->begin(), + detection_sorted_indices->end(), + [&detection_instances](size_t j1, size_t j2) { + return detection_instances[j1].score > detection_instances[j2].score; + }); +} + +// Partition the ground truth objects based on whether or not to ignore them +// based on area +void SortInstancesByIgnore( + const std::array& area_range, + const std::vector& ground_truth_instances, + std::vector* ground_truth_sorted_indices, + std::vector* ignores) { + ignores->clear(); + ignores->reserve(ground_truth_instances.size()); + for (auto o : ground_truth_instances) { + ignores->push_back( + o.ignore || o.area < area_range[0] || o.area > area_range[1]); + } + + ground_truth_sorted_indices->resize(ground_truth_instances.size()); + std::iota( + ground_truth_sorted_indices->begin(), + ground_truth_sorted_indices->end(), + 0); + std::stable_sort( + ground_truth_sorted_indices->begin(), + ground_truth_sorted_indices->end(), + [&ignores](size_t j1, size_t j2) { + return (int)(*ignores)[j1] < (int)(*ignores)[j2]; + }); +} + +// For each IOU threshold, greedily match each detected instance to a ground +// truth instance (if possible) and store the results +void MatchDetectionsToGroundTruth( + const std::vector& detection_instances, + const std::vector& detection_sorted_indices, + const std::vector& ground_truth_instances, + const std::vector& ground_truth_sorted_indices, + const std::vector& ignores, + const std::vector>& ious, + const std::vector& iou_thresholds, + const std::array& area_range, + ImageEvaluation* results) { + // Initialize memory to store return data matches and ignore + const int num_iou_thresholds = iou_thresholds.size(); + const int num_ground_truth = ground_truth_sorted_indices.size(); + const int num_detections = detection_sorted_indices.size(); + std::vector ground_truth_matches( + num_iou_thresholds * num_ground_truth, 0); + std::vector& detection_matches = results->detection_matches; + std::vector& detection_ignores = results->detection_ignores; + std::vector& ground_truth_ignores = results->ground_truth_ignores; + detection_matches.resize(num_iou_thresholds * num_detections, 0); + detection_ignores.resize(num_iou_thresholds * num_detections, false); + ground_truth_ignores.resize(num_ground_truth); + for (auto g = 0; g < num_ground_truth; ++g) { + ground_truth_ignores[g] = ignores[ground_truth_sorted_indices[g]]; + } + + for (auto t = 0; t < num_iou_thresholds; ++t) { + for (auto d = 0; d < num_detections; ++d) { + // information about best match so far (match=-1 -> unmatched) + double best_iou = std::min(iou_thresholds[t], 1 - 1e-10); + int match = -1; + for (auto g = 0; g < num_ground_truth; ++g) { + // if this ground truth instance is already matched and not a + // crowd, it cannot be matched to another detection + if (ground_truth_matches[t * num_ground_truth + g] > 0 && + !ground_truth_instances[ground_truth_sorted_indices[g]].is_crowd) { + continue; + } + + // if detected instance matched to a regular ground truth + // instance, we can break on the first ground truth instance + // tagged as ignore (because they are sorted by the ignore tag) + if (match >= 0 && !ground_truth_ignores[match] && + ground_truth_ignores[g]) { + break; + } + + // if IOU overlap is the best so far, store the match appropriately + if (ious[d][ground_truth_sorted_indices[g]] >= best_iou) { + best_iou = ious[d][ground_truth_sorted_indices[g]]; + match = g; + } + } + // if match was made, store id of match for both detection and + // ground truth + if (match >= 0) { + detection_ignores[t * num_detections + d] = ground_truth_ignores[match]; + detection_matches[t * num_detections + d] = + ground_truth_instances[ground_truth_sorted_indices[match]].id; + ground_truth_matches[t * num_ground_truth + match] = + detection_instances[detection_sorted_indices[d]].id; + } + + // set unmatched detections outside of area range to ignore + const InstanceAnnotation& detection = + detection_instances[detection_sorted_indices[d]]; + detection_ignores[t * num_detections + d] = + detection_ignores[t * num_detections + d] || + (detection_matches[t * num_detections + d] == 0 && + (detection.area < area_range[0] || detection.area > area_range[1])); + } + } + + // store detection score results + results->detection_scores.resize(detection_sorted_indices.size()); + for (size_t d = 0; d < detection_sorted_indices.size(); ++d) { + results->detection_scores[d] = + detection_instances[detection_sorted_indices[d]].score; + } +} + +std::vector EvaluateImages( + const std::vector>& area_ranges, + int max_detections, + const std::vector& iou_thresholds, + const ImageCategoryInstances>& image_category_ious, + const ImageCategoryInstances& + image_category_ground_truth_instances, + const ImageCategoryInstances& + image_category_detection_instances) { + const int num_area_ranges = area_ranges.size(); + const int num_images = image_category_ground_truth_instances.size(); + const int num_categories = + image_category_ious.size() > 0 ? image_category_ious[0].size() : 0; + std::vector detection_sorted_indices; + std::vector ground_truth_sorted_indices; + std::vector ignores; + std::vector results_all( + num_images * num_area_ranges * num_categories); + + // Store results for each image, category, and area range combination. Results + // for each IOU threshold are packed into the same ImageEvaluation object + for (auto i = 0; i < num_images; ++i) { + for (auto c = 0; c < num_categories; ++c) { + const std::vector& ground_truth_instances = + image_category_ground_truth_instances[i][c]; + const std::vector& detection_instances = + image_category_detection_instances[i][c]; + + SortInstancesByDetectionScore( + detection_instances, &detection_sorted_indices); + if ((int)detection_sorted_indices.size() > max_detections) { + detection_sorted_indices.resize(max_detections); + } + + for (size_t a = 0; a < area_ranges.size(); ++a) { + SortInstancesByIgnore( + area_ranges[a], + ground_truth_instances, + &ground_truth_sorted_indices, + &ignores); + + MatchDetectionsToGroundTruth( + detection_instances, + detection_sorted_indices, + ground_truth_instances, + ground_truth_sorted_indices, + ignores, + image_category_ious[i][c], + iou_thresholds, + area_ranges[a], + &results_all + [c * num_area_ranges * num_images + a * num_images + i]); + } + } + } + + return results_all; +} + +// Convert a python list to a vector +template +std::vector list_to_vec(const py::list& l) { + std::vector v(py::len(l)); + for (int i = 0; i < (int)py::len(l); ++i) { + v[i] = l[i].cast(); + } + return v; +} + +// Helper function to Accumulate() +// Considers the evaluation results applicable to a particular category, area +// range, and max_detections parameter setting, which begin at +// evaluations[evaluation_index]. Extracts a sorted list of length n of all +// applicable detection instances concatenated across all images in the dataset, +// which are represented by the outputs evaluation_indices, detection_scores, +// image_detection_indices, and detection_sorted_indices--all of which are +// length n. evaluation_indices[i] stores the applicable index into +// evaluations[] for instance i, which has detection score detection_score[i], +// and is the image_detection_indices[i]'th of the list of detections +// for the image containing i. detection_sorted_indices[] defines a sorted +// permutation of the 3 other outputs +int BuildSortedDetectionList( + const std::vector& evaluations, + const int64_t evaluation_index, + const int64_t num_images, + const int max_detections, + std::vector* evaluation_indices, + std::vector* detection_scores, + std::vector* detection_sorted_indices, + std::vector* image_detection_indices) { + assert(evaluations.size() >= evaluation_index + num_images); + + // Extract a list of object instances of the applicable category, area + // range, and max detections requirements such that they can be sorted + image_detection_indices->clear(); + evaluation_indices->clear(); + detection_scores->clear(); + image_detection_indices->reserve(num_images * max_detections); + evaluation_indices->reserve(num_images * max_detections); + detection_scores->reserve(num_images * max_detections); + int num_valid_ground_truth = 0; + for (auto i = 0; i < num_images; ++i) { + const ImageEvaluation& evaluation = evaluations[evaluation_index + i]; + + for (int d = 0; + d < (int)evaluation.detection_scores.size() && d < max_detections; + ++d) { // detected instances + evaluation_indices->push_back(evaluation_index + i); + image_detection_indices->push_back(d); + detection_scores->push_back(evaluation.detection_scores[d]); + } + for (auto ground_truth_ignore : evaluation.ground_truth_ignores) { + if (!ground_truth_ignore) { + ++num_valid_ground_truth; + } + } + } + + // Sort detections by decreasing score, using stable sort to match + // python implementation + detection_sorted_indices->resize(detection_scores->size()); + std::iota( + detection_sorted_indices->begin(), detection_sorted_indices->end(), 0); + std::stable_sort( + detection_sorted_indices->begin(), + detection_sorted_indices->end(), + [&detection_scores](size_t j1, size_t j2) { + return (*detection_scores)[j1] > (*detection_scores)[j2]; + }); + + return num_valid_ground_truth; +} + +// Helper function to Accumulate() +// Compute a precision recall curve given a sorted list of detected instances +// encoded in evaluations, evaluation_indices, detection_scores, +// detection_sorted_indices, image_detection_indices (see +// BuildSortedDetectionList()). Using vectors precisions and recalls +// and temporary storage, output the results into precisions_out, recalls_out, +// and scores_out, which are large buffers containing many precion/recall curves +// for all possible parameter settings, with precisions_out_index and +// recalls_out_index defining the applicable indices to store results. +void ComputePrecisionRecallCurve( + const int64_t precisions_out_index, + const int64_t precisions_out_stride, + const int64_t recalls_out_index, + const std::vector& recall_thresholds, + const int iou_threshold_index, + const int num_iou_thresholds, + const int num_valid_ground_truth, + const std::vector& evaluations, + const std::vector& evaluation_indices, + const std::vector& detection_scores, + const std::vector& detection_sorted_indices, + const std::vector& image_detection_indices, + std::vector* precisions, + std::vector* recalls, + std::vector* precisions_out, + std::vector* scores_out, + std::vector* recalls_out) { + assert(recalls_out->size() > recalls_out_index); + + // Compute precision/recall for each instance in the sorted list of detections + int64_t true_positives_sum = 0, false_positives_sum = 0; + precisions->clear(); + recalls->clear(); + precisions->reserve(detection_sorted_indices.size()); + recalls->reserve(detection_sorted_indices.size()); + assert(!evaluations.empty() || detection_sorted_indices.empty()); + for (auto detection_sorted_index : detection_sorted_indices) { + const ImageEvaluation& evaluation = + evaluations[evaluation_indices[detection_sorted_index]]; + const auto num_detections = + evaluation.detection_matches.size() / num_iou_thresholds; + const auto detection_index = iou_threshold_index * num_detections + + image_detection_indices[detection_sorted_index]; + assert(evaluation.detection_matches.size() > detection_index); + assert(evaluation.detection_ignores.size() > detection_index); + const int64_t detection_match = + evaluation.detection_matches[detection_index]; + const bool detection_ignores = + evaluation.detection_ignores[detection_index]; + const auto true_positive = detection_match > 0 && !detection_ignores; + const auto false_positive = detection_match == 0 && !detection_ignores; + if (true_positive) { + ++true_positives_sum; + } + if (false_positive) { + ++false_positives_sum; + } + + const double recall = + static_cast(true_positives_sum) / num_valid_ground_truth; + recalls->push_back(recall); + const int64_t num_valid_detections = + true_positives_sum + false_positives_sum; + const double precision = num_valid_detections > 0 + ? static_cast(true_positives_sum) / num_valid_detections + : 0.0; + precisions->push_back(precision); + } + + (*recalls_out)[recalls_out_index] = !recalls->empty() ? recalls->back() : 0; + + for (int64_t i = static_cast(precisions->size()) - 1; i > 0; --i) { + if ((*precisions)[i] > (*precisions)[i - 1]) { + (*precisions)[i - 1] = (*precisions)[i]; + } + } + + // Sample the per instance precision/recall list at each recall threshold + for (size_t r = 0; r < recall_thresholds.size(); ++r) { + // first index in recalls >= recall_thresholds[r] + std::vector::iterator low = std::lower_bound( + recalls->begin(), recalls->end(), recall_thresholds[r]); + size_t precisions_index = low - recalls->begin(); + + const auto results_ind = precisions_out_index + r * precisions_out_stride; + assert(results_ind < precisions_out->size()); + assert(results_ind < scores_out->size()); + if (precisions_index < precisions->size()) { + (*precisions_out)[results_ind] = (*precisions)[precisions_index]; + (*scores_out)[results_ind] = + detection_scores[detection_sorted_indices[precisions_index]]; + } else { + (*precisions_out)[results_ind] = 0; + (*scores_out)[results_ind] = 0; + } + } +} +py::dict Accumulate( + const py::object& params, + const std::vector& evaluations) { + const std::vector recall_thresholds = + list_to_vec(params.attr("recThrs")); + const std::vector max_detections = + list_to_vec(params.attr("maxDets")); + const int num_iou_thresholds = py::len(params.attr("iouThrs")); + const int num_recall_thresholds = py::len(params.attr("recThrs")); + const int num_categories = params.attr("useCats").cast() == 1 + ? py::len(params.attr("catIds")) + : 1; + const int num_area_ranges = py::len(params.attr("areaRng")); + const int num_max_detections = py::len(params.attr("maxDets")); + const int num_images = py::len(params.attr("imgIds")); + + std::vector precisions_out( + num_iou_thresholds * num_recall_thresholds * num_categories * + num_area_ranges * num_max_detections, + -1); + std::vector recalls_out( + num_iou_thresholds * num_categories * num_area_ranges * + num_max_detections, + -1); + std::vector scores_out( + num_iou_thresholds * num_recall_thresholds * num_categories * + num_area_ranges * num_max_detections, + -1); + + // Consider the list of all detected instances in the entire dataset in one + // large list. evaluation_indices, detection_scores, + // image_detection_indices, and detection_sorted_indices all have the same + // length as this list, such that each entry corresponds to one detected + // instance + std::vector evaluation_indices; // indices into evaluations[] + std::vector detection_scores; // detection scores of each instance + std::vector detection_sorted_indices; // sorted indices of all + // instances in the dataset + std::vector + image_detection_indices; // indices into the list of detected instances in + // the same image as each instance + std::vector precisions, recalls; + + for (auto c = 0; c < num_categories; ++c) { + for (auto a = 0; a < num_area_ranges; ++a) { + for (auto m = 0; m < num_max_detections; ++m) { + // The COCO PythonAPI assumes evaluations[] (the return value of + // COCOeval::EvaluateImages() is one long list storing results for each + // combination of category, area range, and image id, with categories in + // the outermost loop and images in the innermost loop. + const int64_t evaluations_index = + c * num_area_ranges * num_images + a * num_images; + int num_valid_ground_truth = BuildSortedDetectionList( + evaluations, + evaluations_index, + num_images, + max_detections[m], + &evaluation_indices, + &detection_scores, + &detection_sorted_indices, + &image_detection_indices); + + if (num_valid_ground_truth == 0) { + continue; + } + + for (auto t = 0; t < num_iou_thresholds; ++t) { + // recalls_out is a flattened vectors representing a + // num_iou_thresholds X num_categories X num_area_ranges X + // num_max_detections matrix + const int64_t recalls_out_index = + t * num_categories * num_area_ranges * num_max_detections + + c * num_area_ranges * num_max_detections + + a * num_max_detections + m; + + // precisions_out and scores_out are flattened vectors + // representing a num_iou_thresholds X num_recall_thresholds X + // num_categories X num_area_ranges X num_max_detections matrix + const int64_t precisions_out_stride = + num_categories * num_area_ranges * num_max_detections; + const int64_t precisions_out_index = t * num_recall_thresholds * + num_categories * num_area_ranges * num_max_detections + + c * num_area_ranges * num_max_detections + + a * num_max_detections + m; + + ComputePrecisionRecallCurve( + precisions_out_index, + precisions_out_stride, + recalls_out_index, + recall_thresholds, + t, + num_iou_thresholds, + num_valid_ground_truth, + evaluations, + evaluation_indices, + detection_scores, + detection_sorted_indices, + image_detection_indices, + &precisions, + &recalls, + &precisions_out, + &scores_out, + &recalls_out); + } + } + } + } + + time_t rawtime; + struct tm local_time; + std::array buffer; + time(&rawtime); +#ifdef _WIN32 + localtime_s(&local_time, &rawtime); +#else + localtime_r(&rawtime, &local_time); +#endif + strftime( + buffer.data(), 200, "%Y-%m-%d %H:%num_max_detections:%S", &local_time); + return py::dict( + "params"_a = params, + "counts"_a = std::vector( + {num_iou_thresholds, + num_recall_thresholds, + num_categories, + num_area_ranges, + num_max_detections}), + "date"_a = buffer, + "precision"_a = precisions_out, + "recall"_a = recalls_out, + "scores"_a = scores_out); +} + +} // namespace COCOeval + +} // namespace detectron2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/cocoeval/cocoeval.h b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/cocoeval/cocoeval.h new file mode 100644 index 00000000..db246e49 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/cocoeval/cocoeval.h @@ -0,0 +1,88 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +#pragma once + +#include +#include +#include +#include +#include + +namespace py = pybind11; + +namespace detectron2 { + +namespace COCOeval { + +// Annotation data for a single object instance in an image +struct InstanceAnnotation { + InstanceAnnotation( + uint64_t id, + double score, + double area, + bool is_crowd, + bool ignore) + : id{id}, score{score}, area{area}, is_crowd{is_crowd}, ignore{ignore} {} + uint64_t id; + double score = 0.; + double area = 0.; + bool is_crowd = false; + bool ignore = false; +}; + +// Stores intermediate results for evaluating detection results for a single +// image that has D detected instances and G ground truth instances. This stores +// matches between detected and ground truth instances +struct ImageEvaluation { + // For each of the D detected instances, the id of the matched ground truth + // instance, or 0 if unmatched + std::vector detection_matches; + + // The detection score of each of the D detected instances + std::vector detection_scores; + + // Marks whether or not each of G instances was ignored from evaluation (e.g., + // because it's outside area_range) + std::vector ground_truth_ignores; + + // Marks whether or not each of D instances was ignored from evaluation (e.g., + // because it's outside aRng) + std::vector detection_ignores; +}; + +template +using ImageCategoryInstances = std::vector>>; + +// C++ implementation of COCO API cocoeval.py::COCOeval.evaluateImg(). For each +// combination of image, category, area range settings, and IOU thresholds to +// evaluate, it matches detected instances to ground truth instances and stores +// the results into a vector of ImageEvaluation results, which will be +// interpreted by the COCOeval::Accumulate() function to produce precion-recall +// curves. The parameters of nested vectors have the following semantics: +// image_category_ious[i][c][d][g] is the intersection over union of the d'th +// detected instance and g'th ground truth instance of +// category category_ids[c] in image image_ids[i] +// image_category_ground_truth_instances[i][c] is a vector of ground truth +// instances in image image_ids[i] of category category_ids[c] +// image_category_detection_instances[i][c] is a vector of detected +// instances in image image_ids[i] of category category_ids[c] +std::vector EvaluateImages( + const std::vector>& area_ranges, // vector of 2-tuples + int max_detections, + const std::vector& iou_thresholds, + const ImageCategoryInstances>& image_category_ious, + const ImageCategoryInstances& + image_category_ground_truth_instances, + const ImageCategoryInstances& + image_category_detection_instances); + +// C++ implementation of COCOeval.accumulate(), which generates precision +// recall curves for each set of category, IOU threshold, detection area range, +// and max number of detections parameters. It is assumed that the parameter +// evaluations is the return value of the functon COCOeval::EvaluateImages(), +// which was called with the same parameter settings params +py::dict Accumulate( + const py::object& params, + const std::vector& evalutations); + +} // namespace COCOeval +} // namespace detectron2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/cuda_version.cu b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/cuda_version.cu new file mode 100644 index 00000000..6dfe1b90 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/cuda_version.cu @@ -0,0 +1,26 @@ +// Copyright (c) Facebook, Inc. and its affiliates. + +#include + +namespace detectron2 { +int get_cudart_version() { +// Not a ROCM platform: Either HIP is not used, or +// it is used, but platform is not ROCM (i.e. it is CUDA) +#if !defined(__HIP_PLATFORM_HCC__) + return CUDART_VERSION; +#else + int version = 0; + +#if HIP_VERSION_MAJOR != 0 + // Create a convention similar to that of CUDA, as assumed by other + // parts of the code. + + version = HIP_VERSION_MINOR; + version += (HIP_VERSION_MAJOR * 100); +#else + hipRuntimeGetVersion(&version); +#endif + return version; +#endif +} +} // namespace detectron2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/deformable/deform_conv.h b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/deformable/deform_conv.h new file mode 100644 index 00000000..965c1bfd --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/deformable/deform_conv.h @@ -0,0 +1,377 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +#pragma once +#include + +namespace detectron2 { + +#if defined(WITH_CUDA) || defined(WITH_HIP) +int deform_conv_forward_cuda( + at::Tensor input, + at::Tensor weight, + at::Tensor offset, + at::Tensor output, + at::Tensor columns, + at::Tensor ones, + int kW, + int kH, + int dW, + int dH, + int padW, + int padH, + int dilationW, + int dilationH, + int group, + int deformable_group, + int im2col_step); + +int deform_conv_backward_input_cuda( + at::Tensor input, + at::Tensor offset, + at::Tensor gradOutput, + at::Tensor gradInput, + at::Tensor gradOffset, + at::Tensor weight, + at::Tensor columns, + int kW, + int kH, + int dW, + int dH, + int padW, + int padH, + int dilationW, + int dilationH, + int group, + int deformable_group, + int im2col_step); + +int deform_conv_backward_parameters_cuda( + at::Tensor input, + at::Tensor offset, + at::Tensor gradOutput, + at::Tensor gradWeight, // at::Tensor gradBias, + at::Tensor columns, + at::Tensor ones, + int kW, + int kH, + int dW, + int dH, + int padW, + int padH, + int dilationW, + int dilationH, + int group, + int deformable_group, + float scale, + int im2col_step); + +void modulated_deform_conv_cuda_forward( + at::Tensor input, + at::Tensor weight, + at::Tensor bias, + at::Tensor ones, + at::Tensor offset, + at::Tensor mask, + at::Tensor output, + at::Tensor columns, + int kernel_h, + int kernel_w, + const int stride_h, + const int stride_w, + const int pad_h, + const int pad_w, + const int dilation_h, + const int dilation_w, + const int group, + const int deformable_group, + const bool with_bias); + +void modulated_deform_conv_cuda_backward( + at::Tensor input, + at::Tensor weight, + at::Tensor bias, + at::Tensor ones, + at::Tensor offset, + at::Tensor mask, + at::Tensor columns, + at::Tensor grad_input, + at::Tensor grad_weight, + at::Tensor grad_bias, + at::Tensor grad_offset, + at::Tensor grad_mask, + at::Tensor grad_output, + int kernel_h, + int kernel_w, + int stride_h, + int stride_w, + int pad_h, + int pad_w, + int dilation_h, + int dilation_w, + int group, + int deformable_group, + const bool with_bias); + +#endif + +inline int deform_conv_forward( + at::Tensor input, + at::Tensor weight, + at::Tensor offset, + at::Tensor output, + at::Tensor columns, + at::Tensor ones, + int kW, + int kH, + int dW, + int dH, + int padW, + int padH, + int dilationW, + int dilationH, + int group, + int deformable_group, + int im2col_step) { + if (input.is_cuda()) { +#if defined(WITH_CUDA) || defined(WITH_HIP) + TORCH_CHECK(weight.is_cuda(), "weight tensor is not on GPU!"); + TORCH_CHECK(offset.is_cuda(), "offset tensor is not on GPU!"); + return deform_conv_forward_cuda( + input, + weight, + offset, + output, + columns, + ones, + kW, + kH, + dW, + dH, + padW, + padH, + dilationW, + dilationH, + group, + deformable_group, + im2col_step); +#else + AT_ERROR("Detectron2 is not compiled with GPU support!"); +#endif + } + AT_ERROR("This operator is not implemented on CPU"); +} + +inline int deform_conv_backward_input( + at::Tensor input, + at::Tensor offset, + at::Tensor gradOutput, + at::Tensor gradInput, + at::Tensor gradOffset, + at::Tensor weight, + at::Tensor columns, + int kW, + int kH, + int dW, + int dH, + int padW, + int padH, + int dilationW, + int dilationH, + int group, + int deformable_group, + int im2col_step) { + if (gradOutput.is_cuda()) { +#if defined(WITH_CUDA) || defined(WITH_HIP) + TORCH_CHECK(input.is_cuda(), "input tensor is not on GPU!"); + TORCH_CHECK(weight.is_cuda(), "weight tensor is not on GPU!"); + TORCH_CHECK(offset.is_cuda(), "offset tensor is not on GPU!"); + return deform_conv_backward_input_cuda( + input, + offset, + gradOutput, + gradInput, + gradOffset, + weight, + columns, + kW, + kH, + dW, + dH, + padW, + padH, + dilationW, + dilationH, + group, + deformable_group, + im2col_step); +#else + AT_ERROR("Detectron2 is not compiled with GPU support!"); +#endif + } + AT_ERROR("This operator is not implemented on CPU"); +} + +inline int deform_conv_backward_filter( + at::Tensor input, + at::Tensor offset, + at::Tensor gradOutput, + at::Tensor gradWeight, // at::Tensor gradBias, + at::Tensor columns, + at::Tensor ones, + int kW, + int kH, + int dW, + int dH, + int padW, + int padH, + int dilationW, + int dilationH, + int group, + int deformable_group, + float scale, + int im2col_step) { + if (gradOutput.is_cuda()) { +#if defined(WITH_CUDA) || defined(WITH_HIP) + TORCH_CHECK(input.is_cuda(), "input tensor is not on GPU!"); + TORCH_CHECK(offset.is_cuda(), "offset tensor is not on GPU!"); + return deform_conv_backward_parameters_cuda( + input, + offset, + gradOutput, + gradWeight, + columns, + ones, + kW, + kH, + dW, + dH, + padW, + padH, + dilationW, + dilationH, + group, + deformable_group, + scale, + im2col_step); +#else + AT_ERROR("Detectron2 is not compiled with GPU support!"); +#endif + } + AT_ERROR("This operator is not implemented on CPU"); +} + +inline void modulated_deform_conv_forward( + at::Tensor input, + at::Tensor weight, + at::Tensor bias, + at::Tensor ones, + at::Tensor offset, + at::Tensor mask, + at::Tensor output, + at::Tensor columns, + int kernel_h, + int kernel_w, + const int stride_h, + const int stride_w, + const int pad_h, + const int pad_w, + const int dilation_h, + const int dilation_w, + const int group, + const int deformable_group, + const bool with_bias) { + if (input.is_cuda()) { +#if defined(WITH_CUDA) || defined(WITH_HIP) + TORCH_CHECK(weight.is_cuda(), "weight tensor is not on GPU!"); + TORCH_CHECK(bias.is_cuda(), "bias tensor is not on GPU!"); + TORCH_CHECK(offset.is_cuda(), "offset tensor is not on GPU!"); + return modulated_deform_conv_cuda_forward( + input, + weight, + bias, + ones, + offset, + mask, + output, + columns, + kernel_h, + kernel_w, + stride_h, + stride_w, + pad_h, + pad_w, + dilation_h, + dilation_w, + group, + deformable_group, + with_bias); +#else + AT_ERROR("Detectron2 is not compiled with GPU support!"); +#endif + } + AT_ERROR("This operator is not implemented on CPU"); +} + +inline void modulated_deform_conv_backward( + at::Tensor input, + at::Tensor weight, + at::Tensor bias, + at::Tensor ones, + at::Tensor offset, + at::Tensor mask, + at::Tensor columns, + at::Tensor grad_input, + at::Tensor grad_weight, + at::Tensor grad_bias, + at::Tensor grad_offset, + at::Tensor grad_mask, + at::Tensor grad_output, + int kernel_h, + int kernel_w, + int stride_h, + int stride_w, + int pad_h, + int pad_w, + int dilation_h, + int dilation_w, + int group, + int deformable_group, + const bool with_bias) { + if (grad_output.is_cuda()) { +#if defined(WITH_CUDA) || defined(WITH_HIP) + TORCH_CHECK(input.is_cuda(), "input tensor is not on GPU!"); + TORCH_CHECK(weight.is_cuda(), "weight tensor is not on GPU!"); + TORCH_CHECK(bias.is_cuda(), "bias tensor is not on GPU!"); + TORCH_CHECK(offset.is_cuda(), "offset tensor is not on GPU!"); + return modulated_deform_conv_cuda_backward( + input, + weight, + bias, + ones, + offset, + mask, + columns, + grad_input, + grad_weight, + grad_bias, + grad_offset, + grad_mask, + grad_output, + kernel_h, + kernel_w, + stride_h, + stride_w, + pad_h, + pad_w, + dilation_h, + dilation_w, + group, + deformable_group, + with_bias); +#else + AT_ERROR("Detectron2 is not compiled with GPU support!"); +#endif + } + AT_ERROR("This operator is not implemented on CPU"); +} + +} // namespace detectron2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/deformable/deform_conv_cuda.cu b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/deformable/deform_conv_cuda.cu new file mode 100644 index 00000000..2072bb85 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/deformable/deform_conv_cuda.cu @@ -0,0 +1,1223 @@ +// Copyright (c) Facebook, Inc. and its affiliates. + +// modified from +// https://github.com/open-mmlab/mmdetection/blob/master/mmdet/ops/dcn/src/deform_conv_cuda.cpp +// Original license: Apache 2.0 + +// modify from +// https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/blob/mmdetection/mmdet/ops/dcn/src/deform_conv_cuda.c +// Original license: Apache 2.0 + +#include + +#include "deform_conv.h" + +#include +#include + +namespace detectron2 { + +void deformable_im2col( + const at::Tensor data_im, + const at::Tensor data_offset, + const int channels, + const int height, + const int width, + const int ksize_h, + const int ksize_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int parallel_imgs, + const int deformable_group, + at::Tensor data_col); + +void deformable_col2im( + const at::Tensor data_col, + const at::Tensor data_offset, + const int channels, + const int height, + const int width, + const int ksize_h, + const int ksize_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int parallel_imgs, + const int deformable_group, + at::Tensor grad_im); + +void deformable_col2im_coord( + const at::Tensor data_col, + const at::Tensor data_im, + const at::Tensor data_offset, + const int channels, + const int height, + const int width, + const int ksize_h, + const int ksize_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int parallel_imgs, + const int deformable_group, + at::Tensor grad_offset); + +void modulated_deformable_im2col_cuda( + const at::Tensor data_im, + const at::Tensor data_offset, + const at::Tensor data_mask, + const int batch_size, + const int channels, + const int height_im, + const int width_im, + const int height_col, + const int width_col, + const int kernel_h, + const int kenerl_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int deformable_group, + at::Tensor data_col); + +void modulated_deformable_col2im_cuda( + const at::Tensor data_col, + const at::Tensor data_offset, + const at::Tensor data_mask, + const int batch_size, + const int channels, + const int height_im, + const int width_im, + const int height_col, + const int width_col, + const int kernel_h, + const int kenerl_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int deformable_group, + at::Tensor grad_im); + +void modulated_deformable_col2im_coord_cuda( + const at::Tensor data_col, + const at::Tensor data_im, + const at::Tensor data_offset, + const at::Tensor data_mask, + const int batch_size, + const int channels, + const int height_im, + const int width_im, + const int height_col, + const int width_col, + const int kernel_h, + const int kenerl_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int deformable_group, + at::Tensor grad_offset, + at::Tensor grad_mask); + +void shape_check( + at::Tensor input, + at::Tensor offset, + at::Tensor* gradOutput, + at::Tensor weight, + int kH, + int kW, + int dH, + int dW, + int padH, + int padW, + int dilationH, + int dilationW, + int group, + int deformable_group) { + TORCH_CHECK( + weight.ndimension() == 4, + "4D weight tensor (nOutputPlane,nInputPlane,kH,kW) expected, " + "but got: %s", + weight.ndimension()); + + TORCH_CHECK(weight.is_contiguous(), "weight tensor has to be contiguous"); + + TORCH_CHECK( + kW > 0 && kH > 0, + "kernel size should be greater than zero, but got kH: %d kW: %d", + kH, + kW); + + TORCH_CHECK( + (weight.size(2) == kH && weight.size(3) == kW), + "kernel size should be consistent with weight, ", + "but got kH: %d kW: %d weight.size(2): %d, weight.size(3): %d", + kH, + kW, + weight.size(2), + weight.size(3)); + + TORCH_CHECK( + dW > 0 && dH > 0, + "stride should be greater than zero, but got dH: %d dW: %d", + dH, + dW); + + TORCH_CHECK( + dilationW > 0 && dilationH > 0, + "dilation should be greater than 0, but got dilationH: %d dilationW: %d", + dilationH, + dilationW); + + int ndim = input.ndimension(); + int dimf = 0; + int dimh = 1; + int dimw = 2; + + if (ndim == 4) { + dimf++; + dimh++; + dimw++; + } + + TORCH_CHECK( + ndim == 3 || ndim == 4, + "3D or 4D input tensor expected but got: %s", + ndim); + + long nInputPlane = weight.size(1) * group; + long inputHeight = input.size(dimh); + long inputWidth = input.size(dimw); + long nOutputPlane = weight.size(0); + long outputHeight = + (inputHeight + 2 * padH - (dilationH * (kH - 1) + 1)) / dH + 1; + long outputWidth = + (inputWidth + 2 * padW - (dilationW * (kW - 1) + 1)) / dW + 1; + + TORCH_CHECK( + nInputPlane % deformable_group == 0, + "input channels must divide deformable group size"); + + if (outputWidth < 1 || outputHeight < 1) + AT_ERROR( + "Given input size: (%ld x %ld x %ld). " + "Calculated output size: (%ld x %ld x %ld). Output size is too small", + nInputPlane, + inputHeight, + inputWidth, + nOutputPlane, + outputHeight, + outputWidth); + + TORCH_CHECK( + input.size(1) == nInputPlane, + "invalid number of input planes, expected: %d, but got: %d", + nInputPlane, + input.size(1)); + + TORCH_CHECK( + (inputHeight + 2 * padH >= kH && inputWidth + 2 * padW >= kW), + "input image is smaller than kernel"); + + TORCH_CHECK( + (offset.size(2) == outputHeight && offset.size(3) == outputWidth), + "invalid spatial size of offset, expected height: %d width: %d, but " + "got height: %d width: %d", + outputHeight, + outputWidth, + offset.size(2), + offset.size(3)); + + TORCH_CHECK( + (offset.size(1) == deformable_group * 2 * kH * kW), + "invalid number of channels of offset"); + + if (gradOutput != NULL) { + TORCH_CHECK( + gradOutput->size(dimf) == nOutputPlane, + "invalid number of gradOutput planes, expected: %d, but got: %d", + nOutputPlane, + gradOutput->size(dimf)); + + TORCH_CHECK( + (gradOutput->size(dimh) == outputHeight && + gradOutput->size(dimw) == outputWidth), + "invalid size of gradOutput, expected height: %d width: %d , but " + "got height: %d width: %d", + outputHeight, + outputWidth, + gradOutput->size(dimh), + gradOutput->size(dimw)); + } +} + +int deform_conv_forward_cuda( + at::Tensor input, + at::Tensor weight, + at::Tensor offset, + at::Tensor output, + at::Tensor columns, + at::Tensor ones, + int kW, + int kH, + int dW, + int dH, + int padW, + int padH, + int dilationW, + int dilationH, + int group, + int deformable_group, + int im2col_step) { + // todo: resize columns to include im2col: done + // todo: add im2col_step as input + // todo: add new output buffer and transpose it to output (or directly + // transpose output) todo: possibly change data indexing because of + // parallel_imgs + + shape_check( + input, + offset, + NULL, + weight, + kH, + kW, + dH, + dW, + padH, + padW, + dilationH, + dilationW, + group, + deformable_group); + + input = input.contiguous(); + offset = offset.contiguous(); + weight = weight.contiguous(); + + int batch = 1; + if (input.ndimension() == 3) { + // Force batch + batch = 0; + input.unsqueeze_(0); + offset.unsqueeze_(0); + } + + // todo: assert batchsize dividable by im2col_step + + long batchSize = input.size(0); + long nInputPlane = input.size(1); + long inputHeight = input.size(2); + long inputWidth = input.size(3); + + long nOutputPlane = weight.size(0); + + long outputWidth = + (inputWidth + 2 * padW - (dilationW * (kW - 1) + 1)) / dW + 1; + long outputHeight = + (inputHeight + 2 * padH - (dilationH * (kH - 1) + 1)) / dH + 1; + + TORCH_CHECK((offset.size(0) == batchSize), "invalid batch size of offset"); + + output = output.view( + {batchSize / im2col_step, + im2col_step, + nOutputPlane, + outputHeight, + outputWidth}); + columns = at::zeros( + {nInputPlane * kW * kH, im2col_step * outputHeight * outputWidth}, + input.options()); + + if (ones.ndimension() != 2 || + ones.size(0) * ones.size(1) < outputHeight * outputWidth) { + ones = at::ones({outputHeight, outputWidth}, input.options()); + } + + input = input.view( + {batchSize / im2col_step, + im2col_step, + nInputPlane, + inputHeight, + inputWidth}); + offset = offset.view( + {batchSize / im2col_step, + im2col_step, + deformable_group * 2 * kH * kW, + outputHeight, + outputWidth}); + + at::Tensor output_buffer = at::zeros( + {batchSize / im2col_step, + nOutputPlane, + im2col_step * outputHeight, + outputWidth}, + output.options()); + + output_buffer = output_buffer.view( + {output_buffer.size(0), + group, + output_buffer.size(1) / group, + output_buffer.size(2), + output_buffer.size(3)}); + + for (int elt = 0; elt < batchSize / im2col_step; elt++) { + deformable_im2col( + input[elt], + offset[elt], + nInputPlane, + inputHeight, + inputWidth, + kH, + kW, + padH, + padW, + dH, + dW, + dilationH, + dilationW, + im2col_step, + deformable_group, + columns); + + columns = columns.view({group, columns.size(0) / group, columns.size(1)}); + weight = weight.view( + {group, + weight.size(0) / group, + weight.size(1), + weight.size(2), + weight.size(3)}); + + for (int g = 0; g < group; g++) { + output_buffer[elt][g] = output_buffer[elt][g] + .flatten(1) + .addmm_(weight[g].flatten(1), columns[g]) + .view_as(output_buffer[elt][g]); + } + } + + output_buffer = output_buffer.view( + {output_buffer.size(0), + output_buffer.size(1) * output_buffer.size(2), + output_buffer.size(3), + output_buffer.size(4)}); + + output_buffer = output_buffer.view( + {batchSize / im2col_step, + nOutputPlane, + im2col_step, + outputHeight, + outputWidth}); + output_buffer.transpose_(1, 2); + output.copy_(output_buffer); + output = output.view({batchSize, nOutputPlane, outputHeight, outputWidth}); + + input = input.view({batchSize, nInputPlane, inputHeight, inputWidth}); + offset = offset.view( + {batchSize, deformable_group * 2 * kH * kW, outputHeight, outputWidth}); + + if (batch == 0) { + output = output.view({nOutputPlane, outputHeight, outputWidth}); + input = input.view({nInputPlane, inputHeight, inputWidth}); + offset = offset.view({offset.size(1), offset.size(2), offset.size(3)}); + } + + return 1; +} + +int deform_conv_backward_input_cuda( + at::Tensor input, + at::Tensor offset, + at::Tensor gradOutput, + at::Tensor gradInput, + at::Tensor gradOffset, + at::Tensor weight, + at::Tensor columns, + int kW, + int kH, + int dW, + int dH, + int padW, + int padH, + int dilationW, + int dilationH, + int group, + int deformable_group, + int im2col_step) { + shape_check( + input, + offset, + &gradOutput, + weight, + kH, + kW, + dH, + dW, + padH, + padW, + dilationH, + dilationW, + group, + deformable_group); + + input = input.contiguous(); + offset = offset.contiguous(); + gradOutput = gradOutput.contiguous(); + weight = weight.contiguous(); + + int batch = 1; + + if (input.ndimension() == 3) { + // Force batch + batch = 0; + input = input.view({1, input.size(0), input.size(1), input.size(2)}); + offset = offset.view({1, offset.size(0), offset.size(1), offset.size(2)}); + gradOutput = gradOutput.view( + {1, gradOutput.size(0), gradOutput.size(1), gradOutput.size(2)}); + } + + long batchSize = input.size(0); + long nInputPlane = input.size(1); + long inputHeight = input.size(2); + long inputWidth = input.size(3); + + long nOutputPlane = weight.size(0); + + long outputWidth = + (inputWidth + 2 * padW - (dilationW * (kW - 1) + 1)) / dW + 1; + long outputHeight = + (inputHeight + 2 * padH - (dilationH * (kH - 1) + 1)) / dH + 1; + + TORCH_CHECK((offset.size(0) == batchSize), 3, "invalid batch size of offset"); + gradInput = gradInput.view({batchSize, nInputPlane, inputHeight, inputWidth}); + columns = at::zeros( + {nInputPlane * kW * kH, im2col_step * outputHeight * outputWidth}, + input.options()); + + // change order of grad output + gradOutput = gradOutput.view( + {batchSize / im2col_step, + im2col_step, + nOutputPlane, + outputHeight, + outputWidth}); + gradOutput.transpose_(1, 2); + + gradInput = gradInput.view( + {batchSize / im2col_step, + im2col_step, + nInputPlane, + inputHeight, + inputWidth}); + input = input.view( + {batchSize / im2col_step, + im2col_step, + nInputPlane, + inputHeight, + inputWidth}); + gradOffset = gradOffset.view( + {batchSize / im2col_step, + im2col_step, + deformable_group * 2 * kH * kW, + outputHeight, + outputWidth}); + offset = offset.view( + {batchSize / im2col_step, + im2col_step, + deformable_group * 2 * kH * kW, + outputHeight, + outputWidth}); + + for (int elt = 0; elt < batchSize / im2col_step; elt++) { + // divide into groups + columns = columns.view({group, columns.size(0) / group, columns.size(1)}); + weight = weight.view( + {group, + weight.size(0) / group, + weight.size(1), + weight.size(2), + weight.size(3)}); + gradOutput = gradOutput.view( + {gradOutput.size(0), + group, + gradOutput.size(1) / group, + gradOutput.size(2), + gradOutput.size(3), + gradOutput.size(4)}); + + for (int g = 0; g < group; g++) { + columns[g] = columns[g].addmm_( + weight[g].flatten(1).transpose(0, 1), + gradOutput[elt][g].flatten(1), + 0.0f, + 1.0f); + } + + columns = + columns.view({columns.size(0) * columns.size(1), columns.size(2)}); + gradOutput = gradOutput.view( + {gradOutput.size(0), + gradOutput.size(1) * gradOutput.size(2), + gradOutput.size(3), + gradOutput.size(4), + gradOutput.size(5)}); + + deformable_col2im_coord( + columns, + input[elt], + offset[elt], + nInputPlane, + inputHeight, + inputWidth, + kH, + kW, + padH, + padW, + dH, + dW, + dilationH, + dilationW, + im2col_step, + deformable_group, + gradOffset[elt]); + + deformable_col2im( + columns, + offset[elt], + nInputPlane, + inputHeight, + inputWidth, + kH, + kW, + padH, + padW, + dH, + dW, + dilationH, + dilationW, + im2col_step, + deformable_group, + gradInput[elt]); + } + + gradOutput.transpose_(1, 2); + gradOutput = + gradOutput.view({batchSize, nOutputPlane, outputHeight, outputWidth}); + + gradInput = gradInput.view({batchSize, nInputPlane, inputHeight, inputWidth}); + input = input.view({batchSize, nInputPlane, inputHeight, inputWidth}); + gradOffset = gradOffset.view( + {batchSize, deformable_group * 2 * kH * kW, outputHeight, outputWidth}); + offset = offset.view( + {batchSize, deformable_group * 2 * kH * kW, outputHeight, outputWidth}); + + if (batch == 0) { + gradOutput = gradOutput.view({nOutputPlane, outputHeight, outputWidth}); + input = input.view({nInputPlane, inputHeight, inputWidth}); + gradInput = gradInput.view({nInputPlane, inputHeight, inputWidth}); + offset = offset.view({offset.size(1), offset.size(2), offset.size(3)}); + gradOffset = + gradOffset.view({offset.size(1), offset.size(2), offset.size(3)}); + } + + return 1; +} + +int deform_conv_backward_parameters_cuda( + at::Tensor input, + at::Tensor offset, + at::Tensor gradOutput, + at::Tensor gradWeight, // at::Tensor gradBias, + at::Tensor columns, + at::Tensor ones, + int kW, + int kH, + int dW, + int dH, + int padW, + int padH, + int dilationW, + int dilationH, + int group, + int deformable_group, + float scale, + int im2col_step) { + // todo: transpose and reshape outGrad + // todo: reshape columns + // todo: add im2col_step as input + + shape_check( + input, + offset, + &gradOutput, + gradWeight, + kH, + kW, + dH, + dW, + padH, + padW, + dilationH, + dilationW, + group, + deformable_group); + + input = input.contiguous(); + offset = offset.contiguous(); + gradOutput = gradOutput.contiguous(); + + int batch = 1; + + if (input.ndimension() == 3) { + // Force batch + batch = 0; + input = input.view( + at::IntList({1, input.size(0), input.size(1), input.size(2)})); + gradOutput = gradOutput.view( + {1, gradOutput.size(0), gradOutput.size(1), gradOutput.size(2)}); + } + + long batchSize = input.size(0); + long nInputPlane = input.size(1); + long inputHeight = input.size(2); + long inputWidth = input.size(3); + + long nOutputPlane = gradWeight.size(0); + + long outputWidth = + (inputWidth + 2 * padW - (dilationW * (kW - 1) + 1)) / dW + 1; + long outputHeight = + (inputHeight + 2 * padH - (dilationH * (kH - 1) + 1)) / dH + 1; + + TORCH_CHECK((offset.size(0) == batchSize), "invalid batch size of offset"); + + columns = at::zeros( + {nInputPlane * kW * kH, im2col_step * outputHeight * outputWidth}, + input.options()); + + gradOutput = gradOutput.view( + {batchSize / im2col_step, + im2col_step, + nOutputPlane, + outputHeight, + outputWidth}); + gradOutput.transpose_(1, 2); + + at::Tensor gradOutputBuffer = at::zeros_like(gradOutput); + gradOutputBuffer = gradOutputBuffer.view( + {batchSize / im2col_step, + nOutputPlane, + im2col_step, + outputHeight, + outputWidth}); + gradOutputBuffer.copy_(gradOutput); + // gradOutput is not contiguous, so we do reshape (instead of view) next + gradOutputBuffer = gradOutputBuffer.reshape( + {batchSize / im2col_step, + nOutputPlane, + im2col_step * outputHeight, + outputWidth}); + + gradOutput.transpose_(1, 2); + gradOutput = + gradOutput.view({batchSize, nOutputPlane, outputHeight, outputWidth}); + + input = input.view( + {batchSize / im2col_step, + im2col_step, + nInputPlane, + inputHeight, + inputWidth}); + offset = offset.view( + {batchSize / im2col_step, + im2col_step, + deformable_group * 2 * kH * kW, + outputHeight, + outputWidth}); + + for (int elt = 0; elt < batchSize / im2col_step; elt++) { + deformable_im2col( + input[elt], + offset[elt], + nInputPlane, + inputHeight, + inputWidth, + kH, + kW, + padH, + padW, + dH, + dW, + dilationH, + dilationW, + im2col_step, + deformable_group, + columns); + + // divide into group + gradOutputBuffer = gradOutputBuffer.view( + {gradOutputBuffer.size(0), + group, + gradOutputBuffer.size(1) / group, + gradOutputBuffer.size(2), + gradOutputBuffer.size(3)}); + columns = columns.view({group, columns.size(0) / group, columns.size(1)}); + gradWeight = gradWeight.view( + {group, + gradWeight.size(0) / group, + gradWeight.size(1), + gradWeight.size(2), + gradWeight.size(3)}); + + for (int g = 0; g < group; g++) { + gradWeight[g] = gradWeight[g] + .flatten(1) + .addmm_( + gradOutputBuffer[elt][g].flatten(1), + columns[g].transpose(1, 0), + 1.0, + scale) + .view_as(gradWeight[g]); + } + gradOutputBuffer = gradOutputBuffer.view( + {gradOutputBuffer.size(0), + gradOutputBuffer.size(1) * gradOutputBuffer.size(2), + gradOutputBuffer.size(3), + gradOutputBuffer.size(4)}); + columns = + columns.view({columns.size(0) * columns.size(1), columns.size(2)}); + gradWeight = gradWeight.view( + {gradWeight.size(0) * gradWeight.size(1), + gradWeight.size(2), + gradWeight.size(3), + gradWeight.size(4)}); + } + + input = input.view({batchSize, nInputPlane, inputHeight, inputWidth}); + offset = offset.view( + {batchSize, deformable_group * 2 * kH * kW, outputHeight, outputWidth}); + + if (batch == 0) { + gradOutput = gradOutput.view({nOutputPlane, outputHeight, outputWidth}); + input = input.view({nInputPlane, inputHeight, inputWidth}); + } + + return 1; +} + +void modulated_deform_conv_cuda_forward( + at::Tensor input, + at::Tensor weight, + at::Tensor bias, + at::Tensor ones, + at::Tensor offset, + at::Tensor mask, + at::Tensor output, + at::Tensor columns, + int kernel_h, + int kernel_w, + const int stride_h, + const int stride_w, + const int pad_h, + const int pad_w, + const int dilation_h, + const int dilation_w, + const int group, + const int deformable_group, + const bool with_bias) { + shape_check( + input, + offset, + NULL, + weight, + kernel_h, + kernel_w, + stride_h, + stride_w, + pad_h, + pad_w, + dilation_h, + dilation_w, + group, + deformable_group); + + TORCH_CHECK(input.is_contiguous(), "input tensor has to be contiguous"); + TORCH_CHECK(weight.is_contiguous(), "weight tensor has to be contiguous"); + + const int batch = input.size(0); + const int channels = input.size(1); + const int height = input.size(2); + const int width = input.size(3); + + const int channels_out = weight.size(0); + const int channels_kernel = weight.size(1); + const int kernel_h_ = weight.size(2); + const int kernel_w_ = weight.size(3); + + if (kernel_h_ != kernel_h || kernel_w_ != kernel_w) + AT_ERROR( + "Input shape and kernel shape wont match: (%d x %d vs %d x %d).", + kernel_h_, + kernel_w, + kernel_h_, + kernel_w_); + if (channels != channels_kernel * group) + AT_ERROR( + "Input shape and kernel channels wont match: (%d vs %d).", + channels, + channels_kernel * group); + + const int height_out = + (height + 2 * pad_h - (dilation_h * (kernel_h - 1) + 1)) / stride_h + 1; + const int width_out = + (width + 2 * pad_w - (dilation_w * (kernel_w - 1) + 1)) / stride_w + 1; + + // mask shape check + TORCH_CHECK( + (mask.size(2) == height_out && mask.size(3) == width_out), + "invalid spatial size of mask, expected height: %d width: %d, but " + "got height: %d width: %d", + height_out, + width_out, + mask.size(2), + mask.size(3)); + + TORCH_CHECK( + (mask.size(1) == deformable_group * kernel_h * kernel_w), + "invalid number of channels of mask"); + + if (ones.ndimension() != 2 || + ones.size(0) * ones.size(1) < height_out * width_out) { + // Resize plane and fill with ones... + ones = at::ones({height_out, width_out}, input.options()); + } + + // resize output + output = output.view({batch, channels_out, height_out, width_out}).zero_(); + // resize temporary columns + columns = at::zeros( + {channels * kernel_h * kernel_w, 1 * height_out * width_out}, + input.options()); + + output = output.view( + {output.size(0), + group, + output.size(1) / group, + output.size(2), + output.size(3)}); + + for (int b = 0; b < batch; b++) { + modulated_deformable_im2col_cuda( + input[b], + offset[b], + mask[b], + 1, + channels, + height, + width, + height_out, + width_out, + kernel_h, + kernel_w, + pad_h, + pad_w, + stride_h, + stride_w, + dilation_h, + dilation_w, + deformable_group, + columns); + + // divide into group + weight = weight.view( + {group, + weight.size(0) / group, + weight.size(1), + weight.size(2), + weight.size(3)}); + columns = columns.view({group, columns.size(0) / group, columns.size(1)}); + + for (int g = 0; g < group; g++) { + output[b][g] = output[b][g] + .flatten(1) + .addmm_(weight[g].flatten(1), columns[g]) + .view_as(output[b][g]); + } + + weight = weight.view( + {weight.size(0) * weight.size(1), + weight.size(2), + weight.size(3), + weight.size(4)}); + columns = + columns.view({columns.size(0) * columns.size(1), columns.size(2)}); + } + + output = output.view( + {output.size(0), + output.size(1) * output.size(2), + output.size(3), + output.size(4)}); + + if (with_bias) { + output += bias.view({1, bias.size(0), 1, 1}); + } +} + +void modulated_deform_conv_cuda_backward( + at::Tensor input, + at::Tensor weight, + at::Tensor bias, + at::Tensor ones, + at::Tensor offset, + at::Tensor mask, + at::Tensor columns, + at::Tensor grad_input, + at::Tensor grad_weight, + at::Tensor grad_bias, + at::Tensor grad_offset, + at::Tensor grad_mask, + at::Tensor grad_output, + int kernel_h, + int kernel_w, + int stride_h, + int stride_w, + int pad_h, + int pad_w, + int dilation_h, + int dilation_w, + int group, + int deformable_group, + const bool with_bias) { + shape_check( + input, + offset, + &grad_output, + weight, + kernel_h, + kernel_w, + stride_h, + stride_w, + pad_h, + pad_w, + dilation_h, + dilation_w, + group, + deformable_group); + + TORCH_CHECK(input.is_contiguous(), "input tensor has to be contiguous"); + TORCH_CHECK(weight.is_contiguous(), "weight tensor has to be contiguous"); + + const int batch = input.size(0); + const int channels = input.size(1); + const int height = input.size(2); + const int width = input.size(3); + + const int channels_kernel = weight.size(1); + const int kernel_h_ = weight.size(2); + const int kernel_w_ = weight.size(3); + if (kernel_h_ != kernel_h || kernel_w_ != kernel_w) + AT_ERROR( + "Input shape and kernel shape wont match: (%d x %d vs %d x %d).", + kernel_h_, + kernel_w, + kernel_h_, + kernel_w_); + if (channels != channels_kernel * group) + AT_ERROR( + "Input shape and kernel channels wont match: (%d vs %d).", + channels, + channels_kernel * group); + + const int height_out = + (height + 2 * pad_h - (dilation_h * (kernel_h - 1) + 1)) / stride_h + 1; + const int width_out = + (width + 2 * pad_w - (dilation_w * (kernel_w - 1) + 1)) / stride_w + 1; + + // mask shape check + TORCH_CHECK( + (mask.size(2) == height_out && mask.size(3) == width_out), + "invalid spatial size of mask, expected height: %d width: %d, but " + "got height: %d width: %d", + height_out, + width_out, + mask.size(2), + mask.size(3)); + + TORCH_CHECK( + (mask.size(1) == deformable_group * kernel_h * kernel_w), + "invalid number of channels of mask"); + + if (ones.ndimension() != 2 || + ones.size(0) * ones.size(1) < height_out * width_out) { + // Resize plane and fill with ones... + ones = at::ones({height_out, width_out}, input.options()); + } + + grad_input = grad_input.view({batch, channels, height, width}); + columns = at::zeros( + {channels * kernel_h * kernel_w, height_out * width_out}, + input.options()); + + grad_output = grad_output.view( + {grad_output.size(0), + group, + grad_output.size(1) / group, + grad_output.size(2), + grad_output.size(3)}); + + for (int b = 0; b < batch; b++) { + // divide int group + columns = columns.view({group, columns.size(0) / group, columns.size(1)}); + weight = weight.view( + {group, + weight.size(0) / group, + weight.size(1), + weight.size(2), + weight.size(3)}); + + for (int g = 0; g < group; g++) { + columns[g].addmm_( + weight[g].flatten(1).transpose(0, 1), + grad_output[b][g].flatten(1), + 0.0f, + 1.0f); + } + + columns = + columns.view({columns.size(0) * columns.size(1), columns.size(2)}); + weight = weight.view( + {weight.size(0) * weight.size(1), + weight.size(2), + weight.size(3), + weight.size(4)}); + + // gradient w.r.t. input coordinate data + modulated_deformable_col2im_coord_cuda( + columns, + input[b], + offset[b], + mask[b], + 1, + channels, + height, + width, + height_out, + width_out, + kernel_h, + kernel_w, + pad_h, + pad_w, + stride_h, + stride_w, + dilation_h, + dilation_w, + deformable_group, + grad_offset[b], + grad_mask[b]); + // gradient w.r.t. input data + modulated_deformable_col2im_cuda( + columns, + offset[b], + mask[b], + 1, + channels, + height, + width, + height_out, + width_out, + kernel_h, + kernel_w, + pad_h, + pad_w, + stride_h, + stride_w, + dilation_h, + dilation_w, + deformable_group, + grad_input[b]); + + // gradient w.r.t. weight, dWeight should accumulate across the batch and + // group + modulated_deformable_im2col_cuda( + input[b], + offset[b], + mask[b], + 1, + channels, + height, + width, + height_out, + width_out, + kernel_h, + kernel_w, + pad_h, + pad_w, + stride_h, + stride_w, + dilation_h, + dilation_w, + deformable_group, + columns); + + columns = columns.view({group, columns.size(0) / group, columns.size(1)}); + grad_weight = grad_weight.view( + {group, + grad_weight.size(0) / group, + grad_weight.size(1), + grad_weight.size(2), + grad_weight.size(3)}); + if (with_bias) + grad_bias = grad_bias.view({group, grad_bias.size(0) / group}); + + for (int g = 0; g < group; g++) { + grad_weight[g] = + grad_weight[g] + .flatten(1) + .addmm_(grad_output[b][g].flatten(1), columns[g].transpose(0, 1)) + .view_as(grad_weight[g]); + if (with_bias) { + grad_bias[g] = + grad_bias[g] + .view({-1, 1}) + .addmm_(grad_output[b][g].flatten(1), ones.view({-1, 1})) + .view(-1); + } + } + + columns = + columns.view({columns.size(0) * columns.size(1), columns.size(2)}); + grad_weight = grad_weight.view( + {grad_weight.size(0) * grad_weight.size(1), + grad_weight.size(2), + grad_weight.size(3), + grad_weight.size(4)}); + if (with_bias) + grad_bias = grad_bias.view({grad_bias.size(0) * grad_bias.size(1)}); + } + grad_output = grad_output.view( + {grad_output.size(0) * grad_output.size(1), + grad_output.size(2), + grad_output.size(3), + grad_output.size(4)}); +} + +} // namespace detectron2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/deformable/deform_conv_cuda_kernel.cu b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/deformable/deform_conv_cuda_kernel.cu new file mode 100644 index 00000000..f299c7ad --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/deformable/deform_conv_cuda_kernel.cu @@ -0,0 +1,1288 @@ +// Copyright (c) Facebook, Inc. and its affiliates. + +// modified from +// https://github.com/open-mmlab/mmdetection/blob/master/mmdet/ops/dcn/src/deform_conv_cuda_kernel.cu +// Original license: Apache 2.0 +// clang-format off + +// modify from +// https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/blob/mmdetection/mmdet/ops/dcn/src/deform_conv_cuda_kernel.cu + +/*! + ******************* BEGIN Caffe Copyright Notice and Disclaimer ***************** + * + * COPYRIGHT + * + * All contributions by the University of California: + * Copyright (c) 2014-2017 The Regents of the University of California (Regents) + * All rights reserved. + * + * All other contributions: + * Copyright (c) 2014-2017, the respective contributors + * All rights reserved. + * + * Caffe uses a shared copyright model: each contributor holds copyright over + * their contributions to Caffe. The project versioning records all such + * contribution and copyright details. If a contributor wants to further mark + * their specific copyright on a particular contribution, they should indicate + * their copyright solely in the commit message of the change when it is + * committed. + * + * LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + *AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + *IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + *DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + *SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + *CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + *OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + *OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * CONTRIBUTION AGREEMENT + * + * By contributing to the BVLC/caffe repository through pull-request, comment, + * or otherwise, the contributor releases their content to the + * license and copyright terms herein. + * + ***************** END Caffe Copyright Notice and Disclaimer ********************* + * + * Copyright (c) 2018 Microsoft + * Licensed under The MIT License [see LICENSE for details] + * \file modulated_deformable_im2col.cuh + * \brief Function definitions of converting an image to + * column matrix based on kernel, padding, dilation, and offset. + * These functions are mainly used in deformable convolution operators. + * \ref: https://arxiv.org/abs/1703.06211 + * \author Yuwen Xiong, Haozhi Qi, Jifeng Dai, Xizhou Zhu, Han Hu, Dazhi Cheng + */ + +#include +#include +#include +#include +#include +#include + +using namespace at; + +#define CUDA_KERNEL_LOOP(i, n) \ + for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < (n); \ + i += blockDim.x * gridDim.x) + + +namespace { + +const int CUDA_NUM_THREADS = 1024; +const int kMaxGridNum = 65535; + +inline int GET_BLOCKS(const int N) { + return std::min(kMaxGridNum, (N + CUDA_NUM_THREADS - 1) / CUDA_NUM_THREADS); +} + +} + +template +__device__ scalar_t deformable_im2col_bilinear( + const scalar_t* bottom_data, + const int data_width, + const int height, + const int width, + scalar_t h, + scalar_t w) { + int h_low = floor(h); + int w_low = floor(w); + int h_high = h_low + 1; + int w_high = w_low + 1; + + scalar_t lh = h - h_low; + scalar_t lw = w - w_low; + scalar_t hh = 1 - lh, hw = 1 - lw; + + scalar_t v1 = 0; + if (h_low >= 0 && w_low >= 0) + v1 = bottom_data[h_low * data_width + w_low]; + scalar_t v2 = 0; + if (h_low >= 0 && w_high <= width - 1) + v2 = bottom_data[h_low * data_width + w_high]; + scalar_t v3 = 0; + if (h_high <= height - 1 && w_low >= 0) + v3 = bottom_data[h_high * data_width + w_low]; + scalar_t v4 = 0; + if (h_high <= height - 1 && w_high <= width - 1) + v4 = bottom_data[h_high * data_width + w_high]; + + scalar_t w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw; + + scalar_t val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4); + return val; +} + +template +__device__ scalar_t get_gradient_weight( + scalar_t argmax_h, + scalar_t argmax_w, + const int h, + const int w, + const int height, + const int width) { + if (argmax_h <= -1 || argmax_h >= height || argmax_w <= -1 || + argmax_w >= width) { + // empty + return 0; + } + + int argmax_h_low = floor(argmax_h); + int argmax_w_low = floor(argmax_w); + int argmax_h_high = argmax_h_low + 1; + int argmax_w_high = argmax_w_low + 1; + + scalar_t weight = 0; + if (h == argmax_h_low && w == argmax_w_low) + weight = (h + 1 - argmax_h) * (w + 1 - argmax_w); + if (h == argmax_h_low && w == argmax_w_high) + weight = (h + 1 - argmax_h) * (argmax_w + 1 - w); + if (h == argmax_h_high && w == argmax_w_low) + weight = (argmax_h + 1 - h) * (w + 1 - argmax_w); + if (h == argmax_h_high && w == argmax_w_high) + weight = (argmax_h + 1 - h) * (argmax_w + 1 - w); + return weight; +} + +template +__device__ scalar_t get_coordinate_weight( + scalar_t argmax_h, + scalar_t argmax_w, + const int height, + const int width, + const scalar_t* im_data, + const int data_width, + const int bp_dir) { + if (argmax_h <= -1 || argmax_h >= height || argmax_w <= -1 || + argmax_w >= width) { + // empty + return 0; + } + + int argmax_h_low = floor(argmax_h); + int argmax_w_low = floor(argmax_w); + int argmax_h_high = argmax_h_low + 1; + int argmax_w_high = argmax_w_low + 1; + + scalar_t weight = 0; + + if (bp_dir == 0) { + if (argmax_h_low >= 0 && argmax_w_low >= 0) + weight += -1 * (argmax_w_low + 1 - argmax_w) * + im_data[argmax_h_low * data_width + argmax_w_low]; + if (argmax_h_low >= 0 && argmax_w_high <= width - 1) + weight += -1 * (argmax_w - argmax_w_low) * + im_data[argmax_h_low * data_width + argmax_w_high]; + if (argmax_h_high <= height - 1 && argmax_w_low >= 0) + weight += (argmax_w_low + 1 - argmax_w) * + im_data[argmax_h_high * data_width + argmax_w_low]; + if (argmax_h_high <= height - 1 && argmax_w_high <= width - 1) + weight += (argmax_w - argmax_w_low) * + im_data[argmax_h_high * data_width + argmax_w_high]; + } else if (bp_dir == 1) { + if (argmax_h_low >= 0 && argmax_w_low >= 0) + weight += -1 * (argmax_h_low + 1 - argmax_h) * + im_data[argmax_h_low * data_width + argmax_w_low]; + if (argmax_h_low >= 0 && argmax_w_high <= width - 1) + weight += (argmax_h_low + 1 - argmax_h) * + im_data[argmax_h_low * data_width + argmax_w_high]; + if (argmax_h_high <= height - 1 && argmax_w_low >= 0) + weight += -1 * (argmax_h - argmax_h_low) * + im_data[argmax_h_high * data_width + argmax_w_low]; + if (argmax_h_high <= height - 1 && argmax_w_high <= width - 1) + weight += (argmax_h - argmax_h_low) * + im_data[argmax_h_high * data_width + argmax_w_high]; + } + + return weight; +} + +template +__global__ void deformable_im2col_gpu_kernel( + const int n, + const scalar_t* data_im, + const scalar_t* data_offset, + const int height, + const int width, + const int kernel_h, + const int kernel_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int channel_per_deformable_group, + const int batch_size, + const int num_channels, + const int deformable_group, + const int height_col, + const int width_col, + scalar_t* data_col) { + CUDA_KERNEL_LOOP(index, n) { + // index index of output matrix + const int w_col = index % width_col; + const int h_col = (index / width_col) % height_col; + const int b_col = (index / width_col / height_col) % batch_size; + const int c_im = (index / width_col / height_col) / batch_size; + const int c_col = c_im * kernel_h * kernel_w; + + // compute deformable group index + const int deformable_group_index = c_im / channel_per_deformable_group; + + const int h_in = h_col * stride_h - pad_h; + const int w_in = w_col * stride_w - pad_w; + scalar_t* data_col_ptr = data_col + + ((c_col * batch_size + b_col) * height_col + h_col) * width_col + w_col; + // const scalar_t* data_im_ptr = data_im + ((b_col * num_channels + c_im) * + // height + h_in) * width + w_in; + const scalar_t* data_im_ptr = + data_im + (b_col * num_channels + c_im) * height * width; + const scalar_t* data_offset_ptr = data_offset + + (b_col * deformable_group + deformable_group_index) * 2 * kernel_h * + kernel_w * height_col * width_col; + + for (int i = 0; i < kernel_h; ++i) { + for (int j = 0; j < kernel_w; ++j) { + const int data_offset_h_ptr = + ((2 * (i * kernel_w + j)) * height_col + h_col) * width_col + w_col; + const int data_offset_w_ptr = + ((2 * (i * kernel_w + j) + 1) * height_col + h_col) * width_col + + w_col; + const scalar_t offset_h = data_offset_ptr[data_offset_h_ptr]; + const scalar_t offset_w = data_offset_ptr[data_offset_w_ptr]; + scalar_t val = static_cast(0); + const scalar_t h_im = h_in + i * dilation_h + offset_h; + const scalar_t w_im = w_in + j * dilation_w + offset_w; + if (h_im > -1 && w_im > -1 && h_im < height && w_im < width) { + // const scalar_t map_h = i * dilation_h + offset_h; + // const scalar_t map_w = j * dilation_w + offset_w; + // const int cur_height = height - h_in; + // const int cur_width = width - w_in; + // val = deformable_im2col_bilinear(data_im_ptr, width, cur_height, + // cur_width, map_h, map_w); + val = deformable_im2col_bilinear( + data_im_ptr, width, height, width, h_im, w_im); + } + *data_col_ptr = val; + data_col_ptr += batch_size * height_col * width_col; + } + } + } +} + + +template +__global__ void deformable_col2im_gpu_kernel( + const int n, + const scalar_t* data_col, + const scalar_t* data_offset, + const int channels, + const int height, + const int width, + const int kernel_h, + const int kernel_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int channel_per_deformable_group, + const int batch_size, + const int deformable_group, + const int height_col, + const int width_col, + scalar_t* grad_im) { + CUDA_KERNEL_LOOP(index, n) { + const int j = (index / width_col / height_col / batch_size) % kernel_w; + const int i = + (index / width_col / height_col / batch_size / kernel_w) % kernel_h; + const int c = + index / width_col / height_col / batch_size / kernel_w / kernel_h; + // compute the start and end of the output + + const int deformable_group_index = c / channel_per_deformable_group; + + int w_out = index % width_col; + int h_out = (index / width_col) % height_col; + int b = (index / width_col / height_col) % batch_size; + int w_in = w_out * stride_w - pad_w; + int h_in = h_out * stride_h - pad_h; + + const scalar_t* data_offset_ptr = data_offset + + (b * deformable_group + deformable_group_index) * 2 * kernel_h * + kernel_w * height_col * width_col; + const int data_offset_h_ptr = + ((2 * (i * kernel_w + j)) * height_col + h_out) * width_col + w_out; + const int data_offset_w_ptr = + ((2 * (i * kernel_w + j) + 1) * height_col + h_out) * width_col + w_out; + const scalar_t offset_h = data_offset_ptr[data_offset_h_ptr]; + const scalar_t offset_w = data_offset_ptr[data_offset_w_ptr]; + const scalar_t cur_inv_h_data = h_in + i * dilation_h + offset_h; + const scalar_t cur_inv_w_data = w_in + j * dilation_w + offset_w; + + const scalar_t cur_top_grad = data_col[index]; + const int cur_h = (int)cur_inv_h_data; + const int cur_w = (int)cur_inv_w_data; + for (int dy = -2; dy <= 2; dy++) { + for (int dx = -2; dx <= 2; dx++) { + if (cur_h + dy >= 0 && cur_h + dy < height && cur_w + dx >= 0 && + cur_w + dx < width && abs(cur_inv_h_data - (cur_h + dy)) < 1 && + abs(cur_inv_w_data - (cur_w + dx)) < 1) { + int cur_bottom_grad_pos = + ((b * channels + c) * height + cur_h + dy) * width + cur_w + dx; + scalar_t weight = get_gradient_weight( + cur_inv_h_data, + cur_inv_w_data, + cur_h + dy, + cur_w + dx, + height, + width); + atomicAdd(grad_im + cur_bottom_grad_pos, weight * cur_top_grad); + } + } + } + } +} + + +template +__global__ void deformable_col2im_coord_gpu_kernel( + const int n, + const scalar_t* data_col, + const scalar_t* data_im, + const scalar_t* data_offset, + const int channels, + const int height, + const int width, + const int kernel_h, + const int kernel_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int channel_per_deformable_group, + const int batch_size, + const int offset_channels, + const int deformable_group, + const int height_col, + const int width_col, + scalar_t* grad_offset) { + CUDA_KERNEL_LOOP(index, n) { + scalar_t val = 0; + int w = index % width_col; + int h = (index / width_col) % height_col; + int c = (index / width_col / height_col) % offset_channels; + int b = (index / width_col / height_col) / offset_channels; + // compute the start and end of the output + + const int deformable_group_index = c / (2 * kernel_h * kernel_w); + const int col_step = kernel_h * kernel_w; + int cnt = 0; + const scalar_t* data_col_ptr = data_col + + deformable_group_index * channel_per_deformable_group * batch_size * + width_col * height_col; + const scalar_t* data_im_ptr = data_im + + (b * deformable_group + deformable_group_index) * + channel_per_deformable_group / kernel_h / kernel_w * height * width; + const scalar_t* data_offset_ptr = data_offset + + (b * deformable_group + deformable_group_index) * 2 * kernel_h * + kernel_w * height_col * width_col; + + const int offset_c = c - deformable_group_index * 2 * kernel_h * kernel_w; + + for (int col_c = (offset_c / 2); col_c < channel_per_deformable_group; + col_c += col_step) { + const int col_pos = + (((col_c * batch_size + b) * height_col) + h) * width_col + w; + const int bp_dir = offset_c % 2; + + int j = (col_pos / width_col / height_col / batch_size) % kernel_w; + int i = + (col_pos / width_col / height_col / batch_size / kernel_w) % kernel_h; + int w_out = col_pos % width_col; + int h_out = (col_pos / width_col) % height_col; + int w_in = w_out * stride_w - pad_w; + int h_in = h_out * stride_h - pad_h; + const int data_offset_h_ptr = + (((2 * (i * kernel_w + j)) * height_col + h_out) * width_col + w_out); + const int data_offset_w_ptr = + (((2 * (i * kernel_w + j) + 1) * height_col + h_out) * width_col + + w_out); + const scalar_t offset_h = data_offset_ptr[data_offset_h_ptr]; + const scalar_t offset_w = data_offset_ptr[data_offset_w_ptr]; + scalar_t inv_h = h_in + i * dilation_h + offset_h; + scalar_t inv_w = w_in + j * dilation_w + offset_w; + if (inv_h <= -1 || inv_w <= -1 || inv_h >= height || inv_w >= width) { + inv_h = inv_w = -2; + } + const scalar_t weight = get_coordinate_weight( + inv_h, + inv_w, + height, + width, + data_im_ptr + cnt * height * width, + width, + bp_dir); + val += weight * data_col_ptr[col_pos]; + cnt += 1; + } + + grad_offset[index] = val; + } +} + + +namespace detectron2 { + +void deformable_im2col( + const at::Tensor data_im, + const at::Tensor data_offset, + const int channels, + const int height, + const int width, + const int ksize_h, + const int ksize_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int parallel_imgs, + const int deformable_group, + at::Tensor data_col) { + // num_axes should be smaller than block size + // todo: check parallel_imgs is correctly passed in + int height_col = + (height + 2 * pad_h - (dilation_h * (ksize_h - 1) + 1)) / stride_h + 1; + int width_col = + (width + 2 * pad_w - (dilation_w * (ksize_w - 1) + 1)) / stride_w + 1; + int num_kernels = channels * height_col * width_col * parallel_imgs; + int channel_per_deformable_group = channels / deformable_group; + + at::cuda::CUDAGuard device_guard(data_im.device()); + cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + + AT_DISPATCH_FLOATING_TYPES_AND_HALF( + data_im.scalar_type(), "deformable_im2col_gpu", ([&] { + const scalar_t* data_im_ = data_im.data_ptr(); + const scalar_t* data_offset_ = data_offset.data_ptr(); + scalar_t* data_col_ = data_col.data_ptr(); + + deformable_im2col_gpu_kernel<<< + GET_BLOCKS(num_kernels), + CUDA_NUM_THREADS, + 0, + stream>>>( + num_kernels, + data_im_, + data_offset_, + height, + width, + ksize_h, + ksize_w, + pad_h, + pad_w, + stride_h, + stride_w, + dilation_h, + dilation_w, + channel_per_deformable_group, + parallel_imgs, + channels, + deformable_group, + height_col, + width_col, + data_col_); + })); + + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) { + printf("error in deformable_im2col: %s\n", cudaGetErrorString(err)); + } +} + + +void deformable_col2im( + const at::Tensor data_col, + const at::Tensor data_offset, + const int channels, + const int height, + const int width, + const int ksize_h, + const int ksize_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int parallel_imgs, + const int deformable_group, + at::Tensor grad_im) { + // todo: make sure parallel_imgs is passed in correctly + int height_col = + (height + 2 * pad_h - (dilation_h * (ksize_h - 1) + 1)) / stride_h + 1; + int width_col = + (width + 2 * pad_w - (dilation_w * (ksize_w - 1) + 1)) / stride_w + 1; + int num_kernels = + channels * ksize_h * ksize_w * height_col * width_col * parallel_imgs; + int channel_per_deformable_group = channels / deformable_group; + + at::cuda::CUDAGuard device_guard(data_col.device()); + cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + + AT_DISPATCH_FLOATING_TYPES_AND_HALF( + data_col.scalar_type(), "deformable_col2im_gpu", ([&] { + const scalar_t* data_col_ = data_col.data_ptr(); + const scalar_t* data_offset_ = data_offset.data_ptr(); + scalar_t* grad_im_ = grad_im.data_ptr(); + + deformable_col2im_gpu_kernel<<< + GET_BLOCKS(num_kernels), + CUDA_NUM_THREADS, + 0, + stream>>>( + num_kernels, + data_col_, + data_offset_, + channels, + height, + width, + ksize_h, + ksize_w, + pad_h, + pad_w, + stride_h, + stride_w, + dilation_h, + dilation_w, + channel_per_deformable_group, + parallel_imgs, + deformable_group, + height_col, + width_col, + grad_im_); + })); + + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) { + printf("error in deformable_col2im: %s\n", cudaGetErrorString(err)); + } +} + + +void deformable_col2im_coord( + const at::Tensor data_col, + const at::Tensor data_im, + const at::Tensor data_offset, + const int channels, + const int height, + const int width, + const int ksize_h, + const int ksize_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int parallel_imgs, + const int deformable_group, + at::Tensor grad_offset) { + int height_col = + (height + 2 * pad_h - (dilation_h * (ksize_h - 1) + 1)) / stride_h + 1; + int width_col = + (width + 2 * pad_w - (dilation_w * (ksize_w - 1) + 1)) / stride_w + 1; + int num_kernels = height_col * width_col * 2 * ksize_h * ksize_w * + deformable_group * parallel_imgs; + int channel_per_deformable_group = + channels * ksize_h * ksize_w / deformable_group; + + at::cuda::CUDAGuard device_guard(data_col.device()); + cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + + AT_DISPATCH_FLOATING_TYPES_AND_HALF( + data_col.scalar_type(), "deformable_col2im_coord_gpu", ([&] { + const scalar_t* data_col_ = data_col.data_ptr(); + const scalar_t* data_im_ = data_im.data_ptr(); + const scalar_t* data_offset_ = data_offset.data_ptr(); + scalar_t* grad_offset_ = grad_offset.data_ptr(); + + deformable_col2im_coord_gpu_kernel<<< + GET_BLOCKS(num_kernels), + CUDA_NUM_THREADS, + 0, + stream>>>( + num_kernels, + data_col_, + data_im_, + data_offset_, + channels, + height, + width, + ksize_h, + ksize_w, + pad_h, + pad_w, + stride_h, + stride_w, + dilation_h, + dilation_w, + channel_per_deformable_group, + parallel_imgs, + 2 * ksize_h * ksize_w * deformable_group, + deformable_group, + height_col, + width_col, + grad_offset_); + })); +} + +} // namespace detectron2 + + +template +__device__ scalar_t dmcn_im2col_bilinear( + const scalar_t* bottom_data, + const int data_width, + const int height, + const int width, + scalar_t h, + scalar_t w) { + int h_low = floor(h); + int w_low = floor(w); + int h_high = h_low + 1; + int w_high = w_low + 1; + + scalar_t lh = h - h_low; + scalar_t lw = w - w_low; + scalar_t hh = 1 - lh, hw = 1 - lw; + + scalar_t v1 = 0; + if (h_low >= 0 && w_low >= 0) + v1 = bottom_data[h_low * data_width + w_low]; + scalar_t v2 = 0; + if (h_low >= 0 && w_high <= width - 1) + v2 = bottom_data[h_low * data_width + w_high]; + scalar_t v3 = 0; + if (h_high <= height - 1 && w_low >= 0) + v3 = bottom_data[h_high * data_width + w_low]; + scalar_t v4 = 0; + if (h_high <= height - 1 && w_high <= width - 1) + v4 = bottom_data[h_high * data_width + w_high]; + + scalar_t w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw; + + scalar_t val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4); + return val; +} + +template +__device__ scalar_t dmcn_get_gradient_weight( + scalar_t argmax_h, + scalar_t argmax_w, + const int h, + const int w, + const int height, + const int width) { + if (argmax_h <= -1 || argmax_h >= height || argmax_w <= -1 || + argmax_w >= width) { + // empty + return 0; + } + + int argmax_h_low = floor(argmax_h); + int argmax_w_low = floor(argmax_w); + int argmax_h_high = argmax_h_low + 1; + int argmax_w_high = argmax_w_low + 1; + + scalar_t weight = 0; + if (h == argmax_h_low && w == argmax_w_low) + weight = (h + 1 - argmax_h) * (w + 1 - argmax_w); + if (h == argmax_h_low && w == argmax_w_high) + weight = (h + 1 - argmax_h) * (argmax_w + 1 - w); + if (h == argmax_h_high && w == argmax_w_low) + weight = (argmax_h + 1 - h) * (w + 1 - argmax_w); + if (h == argmax_h_high && w == argmax_w_high) + weight = (argmax_h + 1 - h) * (argmax_w + 1 - w); + return weight; +} + +template +__device__ scalar_t dmcn_get_coordinate_weight( + scalar_t argmax_h, + scalar_t argmax_w, + const int height, + const int width, + const scalar_t* im_data, + const int data_width, + const int bp_dir) { + if (argmax_h <= -1 || argmax_h >= height || argmax_w <= -1 || + argmax_w >= width) { + // empty + return 0; + } + + int argmax_h_low = floor(argmax_h); + int argmax_w_low = floor(argmax_w); + int argmax_h_high = argmax_h_low + 1; + int argmax_w_high = argmax_w_low + 1; + + scalar_t weight = 0; + + if (bp_dir == 0) { + if (argmax_h_low >= 0 && argmax_w_low >= 0) + weight += -1 * (argmax_w_low + 1 - argmax_w) * + im_data[argmax_h_low * data_width + argmax_w_low]; + if (argmax_h_low >= 0 && argmax_w_high <= width - 1) + weight += -1 * (argmax_w - argmax_w_low) * + im_data[argmax_h_low * data_width + argmax_w_high]; + if (argmax_h_high <= height - 1 && argmax_w_low >= 0) + weight += (argmax_w_low + 1 - argmax_w) * + im_data[argmax_h_high * data_width + argmax_w_low]; + if (argmax_h_high <= height - 1 && argmax_w_high <= width - 1) + weight += (argmax_w - argmax_w_low) * + im_data[argmax_h_high * data_width + argmax_w_high]; + } else if (bp_dir == 1) { + if (argmax_h_low >= 0 && argmax_w_low >= 0) + weight += -1 * (argmax_h_low + 1 - argmax_h) * + im_data[argmax_h_low * data_width + argmax_w_low]; + if (argmax_h_low >= 0 && argmax_w_high <= width - 1) + weight += (argmax_h_low + 1 - argmax_h) * + im_data[argmax_h_low * data_width + argmax_w_high]; + if (argmax_h_high <= height - 1 && argmax_w_low >= 0) + weight += -1 * (argmax_h - argmax_h_low) * + im_data[argmax_h_high * data_width + argmax_w_low]; + if (argmax_h_high <= height - 1 && argmax_w_high <= width - 1) + weight += (argmax_h - argmax_h_low) * + im_data[argmax_h_high * data_width + argmax_w_high]; + } + + return weight; +} + +template +__global__ void modulated_deformable_im2col_gpu_kernel( + const int n, + const scalar_t* data_im, + const scalar_t* data_offset, + const scalar_t* data_mask, + const int height, + const int width, + const int kernel_h, + const int kernel_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int channel_per_deformable_group, + const int batch_size, + const int num_channels, + const int deformable_group, + const int height_col, + const int width_col, + scalar_t* data_col) { + CUDA_KERNEL_LOOP(index, n) { + // index index of output matrix + const int w_col = index % width_col; + const int h_col = (index / width_col) % height_col; + const int b_col = (index / width_col / height_col) % batch_size; + const int c_im = (index / width_col / height_col) / batch_size; + const int c_col = c_im * kernel_h * kernel_w; + + // compute deformable group index + const int deformable_group_index = c_im / channel_per_deformable_group; + + const int h_in = h_col * stride_h - pad_h; + const int w_in = w_col * stride_w - pad_w; + + scalar_t* data_col_ptr = data_col + + ((c_col * batch_size + b_col) * height_col + h_col) * width_col + w_col; + // const float* data_im_ptr = data_im + ((b_col * num_channels + c_im) * + // height + h_in) * width + w_in; + const scalar_t* data_im_ptr = + data_im + (b_col * num_channels + c_im) * height * width; + const scalar_t* data_offset_ptr = data_offset + + (b_col * deformable_group + deformable_group_index) * 2 * kernel_h * + kernel_w * height_col * width_col; + + const scalar_t* data_mask_ptr = data_mask + + (b_col * deformable_group + deformable_group_index) * kernel_h * + kernel_w * height_col * width_col; + + for (int i = 0; i < kernel_h; ++i) { + for (int j = 0; j < kernel_w; ++j) { + const int data_offset_h_ptr = + ((2 * (i * kernel_w + j)) * height_col + h_col) * width_col + w_col; + const int data_offset_w_ptr = + ((2 * (i * kernel_w + j) + 1) * height_col + h_col) * width_col + + w_col; + const int data_mask_hw_ptr = + ((i * kernel_w + j) * height_col + h_col) * width_col + w_col; + const scalar_t offset_h = data_offset_ptr[data_offset_h_ptr]; + const scalar_t offset_w = data_offset_ptr[data_offset_w_ptr]; + const scalar_t mask = data_mask_ptr[data_mask_hw_ptr]; + scalar_t val = static_cast(0); + const scalar_t h_im = h_in + i * dilation_h + offset_h; + const scalar_t w_im = w_in + j * dilation_w + offset_w; + // if (h_im >= 0 && w_im >= 0 && h_im < height && w_im < width) { + if (h_im > -1 && w_im > -1 && h_im < height && w_im < width) { + // const float map_h = i * dilation_h + offset_h; + // const float map_w = j * dilation_w + offset_w; + // const int cur_height = height - h_in; + // const int cur_width = width - w_in; + // val = dmcn_im2col_bilinear(data_im_ptr, width, cur_height, + // cur_width, map_h, map_w); + val = dmcn_im2col_bilinear( + data_im_ptr, width, height, width, h_im, w_im); + } + *data_col_ptr = val * mask; + data_col_ptr += batch_size * height_col * width_col; + // data_col_ptr += height_col * width_col; + } + } + } +} + +template +__global__ void modulated_deformable_col2im_gpu_kernel( + const int n, + const scalar_t* data_col, + const scalar_t* data_offset, + const scalar_t* data_mask, + const int channels, + const int height, + const int width, + const int kernel_h, + const int kernel_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int channel_per_deformable_group, + const int batch_size, + const int deformable_group, + const int height_col, + const int width_col, + scalar_t* grad_im) { + CUDA_KERNEL_LOOP(index, n) { + const int j = (index / width_col / height_col / batch_size) % kernel_w; + const int i = + (index / width_col / height_col / batch_size / kernel_w) % kernel_h; + const int c = + index / width_col / height_col / batch_size / kernel_w / kernel_h; + // compute the start and end of the output + + const int deformable_group_index = c / channel_per_deformable_group; + + int w_out = index % width_col; + int h_out = (index / width_col) % height_col; + int b = (index / width_col / height_col) % batch_size; + int w_in = w_out * stride_w - pad_w; + int h_in = h_out * stride_h - pad_h; + + const scalar_t* data_offset_ptr = data_offset + + (b * deformable_group + deformable_group_index) * 2 * kernel_h * + kernel_w * height_col * width_col; + const scalar_t* data_mask_ptr = data_mask + + (b * deformable_group + deformable_group_index) * kernel_h * kernel_w * + height_col * width_col; + const int data_offset_h_ptr = + ((2 * (i * kernel_w + j)) * height_col + h_out) * width_col + w_out; + const int data_offset_w_ptr = + ((2 * (i * kernel_w + j) + 1) * height_col + h_out) * width_col + w_out; + const int data_mask_hw_ptr = + ((i * kernel_w + j) * height_col + h_out) * width_col + w_out; + const scalar_t offset_h = data_offset_ptr[data_offset_h_ptr]; + const scalar_t offset_w = data_offset_ptr[data_offset_w_ptr]; + const scalar_t mask = data_mask_ptr[data_mask_hw_ptr]; + const scalar_t cur_inv_h_data = h_in + i * dilation_h + offset_h; + const scalar_t cur_inv_w_data = w_in + j * dilation_w + offset_w; + + const scalar_t cur_top_grad = data_col[index] * mask; + const int cur_h = (int)cur_inv_h_data; + const int cur_w = (int)cur_inv_w_data; + for (int dy = -2; dy <= 2; dy++) { + for (int dx = -2; dx <= 2; dx++) { + if (cur_h + dy >= 0 && cur_h + dy < height && cur_w + dx >= 0 && + cur_w + dx < width && abs(cur_inv_h_data - (cur_h + dy)) < 1 && + abs(cur_inv_w_data - (cur_w + dx)) < 1) { + int cur_bottom_grad_pos = + ((b * channels + c) * height + cur_h + dy) * width + cur_w + dx; + scalar_t weight = dmcn_get_gradient_weight( + cur_inv_h_data, + cur_inv_w_data, + cur_h + dy, + cur_w + dx, + height, + width); + atomicAdd(grad_im + cur_bottom_grad_pos, weight * cur_top_grad); + } + } + } + } +} + +template +__global__ void modulated_deformable_col2im_coord_gpu_kernel( + const int n, + const scalar_t* data_col, + const scalar_t* data_im, + const scalar_t* data_offset, + const scalar_t* data_mask, + const int channels, + const int height, + const int width, + const int kernel_h, + const int kernel_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int channel_per_deformable_group, + const int batch_size, + const int offset_channels, + const int deformable_group, + const int height_col, + const int width_col, + scalar_t* grad_offset, + scalar_t* grad_mask) { + CUDA_KERNEL_LOOP(index, n) { + scalar_t val = 0, mval = 0; + int w = index % width_col; + int h = (index / width_col) % height_col; + int c = (index / width_col / height_col) % offset_channels; + int b = (index / width_col / height_col) / offset_channels; + // compute the start and end of the output + + const int deformable_group_index = c / (2 * kernel_h * kernel_w); + const int col_step = kernel_h * kernel_w; + int cnt = 0; + const scalar_t* data_col_ptr = data_col + + deformable_group_index * channel_per_deformable_group * batch_size * + width_col * height_col; + const scalar_t* data_im_ptr = data_im + + (b * deformable_group + deformable_group_index) * + channel_per_deformable_group / kernel_h / kernel_w * height * width; + const scalar_t* data_offset_ptr = data_offset + + (b * deformable_group + deformable_group_index) * 2 * kernel_h * + kernel_w * height_col * width_col; + const scalar_t* data_mask_ptr = data_mask + + (b * deformable_group + deformable_group_index) * kernel_h * kernel_w * + height_col * width_col; + + const int offset_c = c - deformable_group_index * 2 * kernel_h * kernel_w; + + for (int col_c = (offset_c / 2); col_c < channel_per_deformable_group; + col_c += col_step) { + const int col_pos = + (((col_c * batch_size + b) * height_col) + h) * width_col + w; + const int bp_dir = offset_c % 2; + + int j = (col_pos / width_col / height_col / batch_size) % kernel_w; + int i = + (col_pos / width_col / height_col / batch_size / kernel_w) % kernel_h; + int w_out = col_pos % width_col; + int h_out = (col_pos / width_col) % height_col; + int w_in = w_out * stride_w - pad_w; + int h_in = h_out * stride_h - pad_h; + const int data_offset_h_ptr = + (((2 * (i * kernel_w + j)) * height_col + h_out) * width_col + w_out); + const int data_offset_w_ptr = + (((2 * (i * kernel_w + j) + 1) * height_col + h_out) * width_col + + w_out); + const int data_mask_hw_ptr = + (((i * kernel_w + j) * height_col + h_out) * width_col + w_out); + const scalar_t offset_h = data_offset_ptr[data_offset_h_ptr]; + const scalar_t offset_w = data_offset_ptr[data_offset_w_ptr]; + const scalar_t mask = data_mask_ptr[data_mask_hw_ptr]; + scalar_t inv_h = h_in + i * dilation_h + offset_h; + scalar_t inv_w = w_in + j * dilation_w + offset_w; + if (inv_h <= -1 || inv_w <= -1 || inv_h >= height || inv_w >= width) { + inv_h = inv_w = -2; + } else { + mval += data_col_ptr[col_pos] * + dmcn_im2col_bilinear( + data_im_ptr + cnt * height * width, + width, + height, + width, + inv_h, + inv_w); + } + const scalar_t weight = dmcn_get_coordinate_weight( + inv_h, + inv_w, + height, + width, + data_im_ptr + cnt * height * width, + width, + bp_dir); + val += weight * data_col_ptr[col_pos] * mask; + cnt += 1; + } + // KERNEL_ASSIGN(grad_offset[index], offset_req, val); + grad_offset[index] = val; + if (offset_c % 2 == 0) + // KERNEL_ASSIGN(grad_mask[(((b * deformable_group + + // deformable_group_index) * kernel_h * kernel_w + offset_c / 2) * + // height_col + h) * width_col + w], mask_req, mval); + grad_mask + [(((b * deformable_group + deformable_group_index) * kernel_h * + kernel_w + + offset_c / 2) * + height_col + + h) * + width_col + + w] = mval; + } +} + + +namespace detectron2 { + +void modulated_deformable_im2col_cuda( + const at::Tensor data_im, + const at::Tensor data_offset, + const at::Tensor data_mask, + const int batch_size, + const int channels, + const int height_im, + const int width_im, + const int height_col, + const int width_col, + const int kernel_h, + const int kenerl_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int deformable_group, + at::Tensor data_col) { + // num_axes should be smaller than block size + const int channel_per_deformable_group = channels / deformable_group; + const int num_kernels = channels * batch_size * height_col * width_col; + + at::cuda::CUDAGuard device_guard(data_im.device()); + cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + + AT_DISPATCH_FLOATING_TYPES_AND_HALF( + data_im.scalar_type(), "modulated_deformable_im2col_gpu", ([&] { + const scalar_t* data_im_ = data_im.data_ptr(); + const scalar_t* data_offset_ = data_offset.data_ptr(); + const scalar_t* data_mask_ = data_mask.data_ptr(); + scalar_t* data_col_ = data_col.data_ptr(); + + modulated_deformable_im2col_gpu_kernel<<< + GET_BLOCKS(num_kernels), + CUDA_NUM_THREADS, + 0, + stream>>>( + num_kernels, + data_im_, + data_offset_, + data_mask_, + height_im, + width_im, + kernel_h, + kenerl_w, + pad_h, + pad_w, + stride_h, + stride_w, + dilation_h, + dilation_w, + channel_per_deformable_group, + batch_size, + channels, + deformable_group, + height_col, + width_col, + data_col_); + })); + + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) { + printf( + "error in modulated_deformable_im2col_cuda: %s\n", + cudaGetErrorString(err)); + } +} + +void modulated_deformable_col2im_cuda( + const at::Tensor data_col, + const at::Tensor data_offset, + const at::Tensor data_mask, + const int batch_size, + const int channels, + const int height_im, + const int width_im, + const int height_col, + const int width_col, + const int kernel_h, + const int kernel_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int deformable_group, + at::Tensor grad_im) { + const int channel_per_deformable_group = channels / deformable_group; + const int num_kernels = + channels * kernel_h * kernel_w * batch_size * height_col * width_col; + + at::cuda::CUDAGuard device_guard(data_col.device()); + cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + + AT_DISPATCH_FLOATING_TYPES_AND_HALF( + data_col.scalar_type(), "modulated_deformable_col2im_gpu", ([&] { + const scalar_t* data_col_ = data_col.data_ptr(); + const scalar_t* data_offset_ = data_offset.data_ptr(); + const scalar_t* data_mask_ = data_mask.data_ptr(); + scalar_t* grad_im_ = grad_im.data_ptr(); + + modulated_deformable_col2im_gpu_kernel<<< + GET_BLOCKS(num_kernels), + CUDA_NUM_THREADS, + 0, + stream>>>( + num_kernels, + data_col_, + data_offset_, + data_mask_, + channels, + height_im, + width_im, + kernel_h, + kernel_w, + pad_h, + pad_w, + stride_h, + stride_w, + dilation_h, + dilation_w, + channel_per_deformable_group, + batch_size, + deformable_group, + height_col, + width_col, + grad_im_); + })); + + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) { + printf( + "error in modulated_deformable_col2im_cuda: %s\n", + cudaGetErrorString(err)); + } +} + +void modulated_deformable_col2im_coord_cuda( + const at::Tensor data_col, + const at::Tensor data_im, + const at::Tensor data_offset, + const at::Tensor data_mask, + const int batch_size, + const int channels, + const int height_im, + const int width_im, + const int height_col, + const int width_col, + const int kernel_h, + const int kernel_w, + const int pad_h, + const int pad_w, + const int stride_h, + const int stride_w, + const int dilation_h, + const int dilation_w, + const int deformable_group, + at::Tensor grad_offset, + at::Tensor grad_mask) { + const int num_kernels = batch_size * height_col * width_col * 2 * kernel_h * + kernel_w * deformable_group; + const int channel_per_deformable_group = + channels * kernel_h * kernel_w / deformable_group; + + at::cuda::CUDAGuard device_guard(data_col.device()); + cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + + AT_DISPATCH_FLOATING_TYPES_AND_HALF( + data_col.scalar_type(), "modulated_deformable_col2im_coord_gpu", ([&] { + const scalar_t* data_col_ = data_col.data_ptr(); + const scalar_t* data_im_ = data_im.data_ptr(); + const scalar_t* data_offset_ = data_offset.data_ptr(); + const scalar_t* data_mask_ = data_mask.data_ptr(); + scalar_t* grad_offset_ = grad_offset.data_ptr(); + scalar_t* grad_mask_ = grad_mask.data_ptr(); + + modulated_deformable_col2im_coord_gpu_kernel<<< + GET_BLOCKS(num_kernels), + CUDA_NUM_THREADS, + 0, + stream>>>( + num_kernels, + data_col_, + data_im_, + data_offset_, + data_mask_, + channels, + height_im, + width_im, + kernel_h, + kernel_w, + pad_h, + pad_w, + stride_h, + stride_w, + dilation_h, + dilation_w, + channel_per_deformable_group, + batch_size, + 2 * kernel_h * kernel_w * deformable_group, + deformable_group, + height_col, + width_col, + grad_offset_, + grad_mask_); + })); + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) { + printf( + "error in modulated_deformable_col2im_coord_cuda: %s\n", + cudaGetErrorString(err)); + } +} + +} // namespace detectron2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/nms_rotated/nms_rotated.h b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/nms_rotated/nms_rotated.h new file mode 100644 index 00000000..12aca388 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/nms_rotated/nms_rotated.h @@ -0,0 +1,39 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +#pragma once +#include + +namespace detectron2 { + +at::Tensor nms_rotated_cpu( + const at::Tensor& dets, + const at::Tensor& scores, + const double iou_threshold); + +#if defined(WITH_CUDA) || defined(WITH_HIP) +at::Tensor nms_rotated_cuda( + const at::Tensor& dets, + const at::Tensor& scores, + const double iou_threshold); +#endif + +// Interface for Python +// inline is needed to prevent multiple function definitions when this header is +// included by different cpps +inline at::Tensor nms_rotated( + const at::Tensor& dets, + const at::Tensor& scores, + const double iou_threshold) { + assert(dets.device().is_cuda() == scores.device().is_cuda()); + if (dets.device().is_cuda()) { +#if defined(WITH_CUDA) || defined(WITH_HIP) + return nms_rotated_cuda( + dets.contiguous(), scores.contiguous(), iou_threshold); +#else + AT_ERROR("Detectron2 is not compiled with GPU support!"); +#endif + } + + return nms_rotated_cpu(dets.contiguous(), scores.contiguous(), iou_threshold); +} + +} // namespace detectron2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/nms_rotated/nms_rotated_cpu.cpp b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/nms_rotated/nms_rotated_cpu.cpp new file mode 100644 index 00000000..d7556e64 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/nms_rotated/nms_rotated_cpu.cpp @@ -0,0 +1,75 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +#include "../box_iou_rotated/box_iou_rotated_utils.h" +#include "nms_rotated.h" + +namespace detectron2 { + +template +at::Tensor nms_rotated_cpu_kernel( + const at::Tensor& dets, + const at::Tensor& scores, + const double iou_threshold) { + // nms_rotated_cpu_kernel is modified from torchvision's nms_cpu_kernel, + // however, the code in this function is much shorter because + // we delegate the IoU computation for rotated boxes to + // the single_box_iou_rotated function in box_iou_rotated_utils.h + AT_ASSERTM(dets.device().is_cpu(), "dets must be a CPU tensor"); + AT_ASSERTM(scores.device().is_cpu(), "scores must be a CPU tensor"); + AT_ASSERTM( + dets.scalar_type() == scores.scalar_type(), + "dets should have the same type as scores"); + + if (dets.numel() == 0) { + return at::empty({0}, dets.options().dtype(at::kLong)); + } + + auto order_t = std::get<1>(scores.sort(0, /* descending=*/true)); + + auto ndets = dets.size(0); + at::Tensor suppressed_t = at::zeros({ndets}, dets.options().dtype(at::kByte)); + at::Tensor keep_t = at::zeros({ndets}, dets.options().dtype(at::kLong)); + + auto suppressed = suppressed_t.data_ptr(); + auto keep = keep_t.data_ptr(); + auto order = order_t.data_ptr(); + + int64_t num_to_keep = 0; + + for (int64_t _i = 0; _i < ndets; _i++) { + auto i = order[_i]; + if (suppressed[i] == 1) { + continue; + } + + keep[num_to_keep++] = i; + + for (int64_t _j = _i + 1; _j < ndets; _j++) { + auto j = order[_j]; + if (suppressed[j] == 1) { + continue; + } + + auto ovr = single_box_iou_rotated( + dets[i].data_ptr(), dets[j].data_ptr()); + if (ovr >= iou_threshold) { + suppressed[j] = 1; + } + } + } + return keep_t.narrow(/*dim=*/0, /*start=*/0, /*length=*/num_to_keep); +} + +at::Tensor nms_rotated_cpu( + // input must be contiguous + const at::Tensor& dets, + const at::Tensor& scores, + const double iou_threshold) { + auto result = at::empty({0}, dets.options()); + + AT_DISPATCH_FLOATING_TYPES(dets.scalar_type(), "nms_rotated", [&] { + result = nms_rotated_cpu_kernel(dets, scores, iou_threshold); + }); + return result; +} + +} // namespace detectron2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/nms_rotated/nms_rotated_cuda.cu b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/nms_rotated/nms_rotated_cuda.cu new file mode 100644 index 00000000..2a3db5c6 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/nms_rotated/nms_rotated_cuda.cu @@ -0,0 +1,145 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +#include +#include +#include +#include +#ifdef WITH_CUDA +#include "../box_iou_rotated/box_iou_rotated_utils.h" +#endif +// TODO avoid this when pytorch supports "same directory" hipification +#ifdef WITH_HIP +#include "box_iou_rotated/box_iou_rotated_utils.h" +#endif + +using namespace detectron2; + +namespace { +int const threadsPerBlock = sizeof(unsigned long long) * 8; +} + +template +__global__ void nms_rotated_cuda_kernel( + const int n_boxes, + const double iou_threshold, + const T* dev_boxes, + unsigned long long* dev_mask) { + // nms_rotated_cuda_kernel is modified from torchvision's nms_cuda_kernel + + const int row_start = blockIdx.y; + const int col_start = blockIdx.x; + + // if (row_start > col_start) return; + + const int row_size = + min(n_boxes - row_start * threadsPerBlock, threadsPerBlock); + const int col_size = + min(n_boxes - col_start * threadsPerBlock, threadsPerBlock); + + // Compared to nms_cuda_kernel, where each box is represented with 4 values + // (x1, y1, x2, y2), each rotated box is represented with 5 values + // (x_center, y_center, width, height, angle_degrees) here. + __shared__ T block_boxes[threadsPerBlock * 5]; + if (threadIdx.x < col_size) { + block_boxes[threadIdx.x * 5 + 0] = + dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 0]; + block_boxes[threadIdx.x * 5 + 1] = + dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 1]; + block_boxes[threadIdx.x * 5 + 2] = + dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 2]; + block_boxes[threadIdx.x * 5 + 3] = + dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 3]; + block_boxes[threadIdx.x * 5 + 4] = + dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 4]; + } + __syncthreads(); + + if (threadIdx.x < row_size) { + const int cur_box_idx = threadsPerBlock * row_start + threadIdx.x; + const T* cur_box = dev_boxes + cur_box_idx * 5; + int i = 0; + unsigned long long t = 0; + int start = 0; + if (row_start == col_start) { + start = threadIdx.x + 1; + } + for (i = start; i < col_size; i++) { + // Instead of devIoU used by original horizontal nms, here + // we use the single_box_iou_rotated function from box_iou_rotated_utils.h + if (single_box_iou_rotated(cur_box, block_boxes + i * 5) > + iou_threshold) { + t |= 1ULL << i; + } + } + const int col_blocks = at::cuda::ATenCeilDiv(n_boxes, threadsPerBlock); + dev_mask[cur_box_idx * col_blocks + col_start] = t; + } +} + +namespace detectron2 { + +at::Tensor nms_rotated_cuda( + // input must be contiguous + const at::Tensor& dets, + const at::Tensor& scores, + double iou_threshold) { + // using scalar_t = float; + AT_ASSERTM(dets.is_cuda(), "dets must be a CUDA tensor"); + AT_ASSERTM(scores.is_cuda(), "scores must be a CUDA tensor"); + at::cuda::CUDAGuard device_guard(dets.device()); + + auto order_t = std::get<1>(scores.sort(0, /* descending=*/true)); + auto dets_sorted = dets.index_select(0, order_t); + + auto dets_num = dets.size(0); + + const int col_blocks = + at::cuda::ATenCeilDiv(static_cast(dets_num), threadsPerBlock); + + at::Tensor mask = + at::empty({dets_num * col_blocks}, dets.options().dtype(at::kLong)); + + dim3 blocks(col_blocks, col_blocks); + dim3 threads(threadsPerBlock); + cudaStream_t stream = at::cuda::getCurrentCUDAStream(); + + AT_DISPATCH_FLOATING_TYPES( + dets_sorted.scalar_type(), "nms_rotated_kernel_cuda", [&] { + nms_rotated_cuda_kernel<<>>( + dets_num, + iou_threshold, + dets_sorted.data_ptr(), + (unsigned long long*)mask.data_ptr()); + }); + + at::Tensor mask_cpu = mask.to(at::kCPU); + unsigned long long* mask_host = + (unsigned long long*)mask_cpu.data_ptr(); + + std::vector remv(col_blocks); + memset(&remv[0], 0, sizeof(unsigned long long) * col_blocks); + + at::Tensor keep = + at::empty({dets_num}, dets.options().dtype(at::kLong).device(at::kCPU)); + int64_t* keep_out = keep.data_ptr(); + + int num_to_keep = 0; + for (int i = 0; i < dets_num; i++) { + int nblock = i / threadsPerBlock; + int inblock = i % threadsPerBlock; + + if (!(remv[nblock] & (1ULL << inblock))) { + keep_out[num_to_keep++] = i; + unsigned long long* p = mask_host + i * col_blocks; + for (int j = nblock; j < col_blocks; j++) { + remv[j] |= p[j]; + } + } + } + + AT_CUDA_CHECK(cudaGetLastError()); + return order_t.index( + {keep.narrow(/*dim=*/0, /*start=*/0, /*length=*/num_to_keep) + .to(order_t.device(), keep.scalar_type())}); +} + +} // namespace detectron2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/vision.cpp b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/vision.cpp new file mode 100644 index 00000000..c9a2cd4f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/csrc/vision.cpp @@ -0,0 +1,117 @@ +// Copyright (c) Facebook, Inc. and its affiliates. + +#include +#include "ROIAlignRotated/ROIAlignRotated.h" +#include "box_iou_rotated/box_iou_rotated.h" +#include "cocoeval/cocoeval.h" +#include "deformable/deform_conv.h" +#include "nms_rotated/nms_rotated.h" + +namespace detectron2 { + +#if defined(WITH_CUDA) || defined(WITH_HIP) +extern int get_cudart_version(); +#endif + +std::string get_cuda_version() { +#if defined(WITH_CUDA) || defined(WITH_HIP) + std::ostringstream oss; + +#if defined(WITH_CUDA) + oss << "CUDA "; +#else + oss << "HIP "; +#endif + + // copied from + // https://github.com/pytorch/pytorch/blob/master/aten/src/ATen/cuda/detail/CUDAHooks.cpp#L231 + auto printCudaStyleVersion = [&](int v) { + oss << (v / 1000) << "." << (v / 10 % 100); + if (v % 10 != 0) { + oss << "." << (v % 10); + } + }; + printCudaStyleVersion(get_cudart_version()); + return oss.str(); +#else // neither CUDA nor HIP + return std::string("not available"); +#endif +} + +bool has_cuda() { +#if defined(WITH_CUDA) + return true; +#else + return false; +#endif +} + +// similar to +// https://github.com/pytorch/pytorch/blob/master/aten/src/ATen/Version.cpp +std::string get_compiler_version() { + std::ostringstream ss; +#if defined(__GNUC__) +#ifndef __clang__ + +#if ((__GNUC__ <= 4) && (__GNUC_MINOR__ <= 8)) +#error "GCC >= 4.9 is required!" +#endif + + { ss << "GCC " << __GNUC__ << "." << __GNUC_MINOR__; } +#endif +#endif + +#if defined(__clang_major__) + { + ss << "clang " << __clang_major__ << "." << __clang_minor__ << "." + << __clang_patchlevel__; + } +#endif + +#if defined(_MSC_VER) + { ss << "MSVC " << _MSC_FULL_VER; } +#endif + return ss.str(); +} + +PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) { + m.def("get_compiler_version", &get_compiler_version, "get_compiler_version"); + m.def("get_cuda_version", &get_cuda_version, "get_cuda_version"); + m.def("has_cuda", &has_cuda, "has_cuda"); + + m.def("deform_conv_forward", &deform_conv_forward, "deform_conv_forward"); + m.def( + "deform_conv_backward_input", + &deform_conv_backward_input, + "deform_conv_backward_input"); + m.def( + "deform_conv_backward_filter", + &deform_conv_backward_filter, + "deform_conv_backward_filter"); + m.def( + "modulated_deform_conv_forward", + &modulated_deform_conv_forward, + "modulated_deform_conv_forward"); + m.def( + "modulated_deform_conv_backward", + &modulated_deform_conv_backward, + "modulated_deform_conv_backward"); + + m.def("COCOevalAccumulate", &COCOeval::Accumulate, "COCOeval::Accumulate"); + m.def( + "COCOevalEvaluateImages", + &COCOeval::EvaluateImages, + "COCOeval::EvaluateImages"); + pybind11::class_(m, "InstanceAnnotation") + .def(pybind11::init()); + pybind11::class_(m, "ImageEvaluation") + .def(pybind11::init<>()); +} + +TORCH_LIBRARY(detectron2, m) { + m.def("nms_rotated", &nms_rotated); + m.def("box_iou_rotated", &box_iou_rotated); + m.def("roi_align_rotated_forward", &ROIAlignRotated_forward); + m.def("roi_align_rotated_backward", &ROIAlignRotated_backward); +} +} // namespace detectron2 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/deform_conv.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/deform_conv.py new file mode 100644 index 00000000..49547238 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/deform_conv.py @@ -0,0 +1,514 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import math +from functools import lru_cache +import torch +from torch import nn +from torch.autograd import Function +from torch.autograd.function import once_differentiable +from torch.nn.modules.utils import _pair +from torchvision.ops import deform_conv2d + +from annotator.oneformer.detectron2.utils.develop import create_dummy_class, create_dummy_func + +from .wrappers import _NewEmptyTensorOp + + +class _DeformConv(Function): + @staticmethod + def forward( + ctx, + input, + offset, + weight, + stride=1, + padding=0, + dilation=1, + groups=1, + deformable_groups=1, + im2col_step=64, + ): + if input is not None and input.dim() != 4: + raise ValueError( + "Expected 4D tensor as input, got {}D tensor instead.".format(input.dim()) + ) + ctx.stride = _pair(stride) + ctx.padding = _pair(padding) + ctx.dilation = _pair(dilation) + ctx.groups = groups + ctx.deformable_groups = deformable_groups + ctx.im2col_step = im2col_step + + ctx.save_for_backward(input, offset, weight) + + output = input.new_empty( + _DeformConv._output_size(input, weight, ctx.padding, ctx.dilation, ctx.stride) + ) + + ctx.bufs_ = [input.new_empty(0), input.new_empty(0)] # columns, ones + + if not input.is_cuda: + # TODO: let torchvision support full features of our deformconv. + if deformable_groups != 1: + raise NotImplementedError( + "Deformable Conv with deformable_groups != 1 is not supported on CPUs!" + ) + return deform_conv2d( + input, offset, weight, stride=stride, padding=padding, dilation=dilation + ) + else: + cur_im2col_step = _DeformConv._cal_im2col_step(input.shape[0], ctx.im2col_step) + assert (input.shape[0] % cur_im2col_step) == 0, "im2col step must divide batchsize" + + _C.deform_conv_forward( + input, + weight, + offset, + output, + ctx.bufs_[0], + ctx.bufs_[1], + weight.size(3), + weight.size(2), + ctx.stride[1], + ctx.stride[0], + ctx.padding[1], + ctx.padding[0], + ctx.dilation[1], + ctx.dilation[0], + ctx.groups, + ctx.deformable_groups, + cur_im2col_step, + ) + return output + + @staticmethod + @once_differentiable + def backward(ctx, grad_output): + input, offset, weight = ctx.saved_tensors + + grad_input = grad_offset = grad_weight = None + + if not grad_output.is_cuda: + raise NotImplementedError("Deformable Conv is not supported on CPUs!") + else: + cur_im2col_step = _DeformConv._cal_im2col_step(input.shape[0], ctx.im2col_step) + assert (input.shape[0] % cur_im2col_step) == 0, "im2col step must divide batchsize" + + if ctx.needs_input_grad[0] or ctx.needs_input_grad[1]: + grad_input = torch.zeros_like(input) + grad_offset = torch.zeros_like(offset) + _C.deform_conv_backward_input( + input, + offset, + grad_output, + grad_input, + grad_offset, + weight, + ctx.bufs_[0], + weight.size(3), + weight.size(2), + ctx.stride[1], + ctx.stride[0], + ctx.padding[1], + ctx.padding[0], + ctx.dilation[1], + ctx.dilation[0], + ctx.groups, + ctx.deformable_groups, + cur_im2col_step, + ) + + if ctx.needs_input_grad[2]: + grad_weight = torch.zeros_like(weight) + _C.deform_conv_backward_filter( + input, + offset, + grad_output, + grad_weight, + ctx.bufs_[0], + ctx.bufs_[1], + weight.size(3), + weight.size(2), + ctx.stride[1], + ctx.stride[0], + ctx.padding[1], + ctx.padding[0], + ctx.dilation[1], + ctx.dilation[0], + ctx.groups, + ctx.deformable_groups, + 1, + cur_im2col_step, + ) + + return grad_input, grad_offset, grad_weight, None, None, None, None, None, None + + @staticmethod + def _output_size(input, weight, padding, dilation, stride): + channels = weight.size(0) + output_size = (input.size(0), channels) + for d in range(input.dim() - 2): + in_size = input.size(d + 2) + pad = padding[d] + kernel = dilation[d] * (weight.size(d + 2) - 1) + 1 + stride_ = stride[d] + output_size += ((in_size + (2 * pad) - kernel) // stride_ + 1,) + if not all(map(lambda s: s > 0, output_size)): + raise ValueError( + "convolution input is too small (output would be {})".format( + "x".join(map(str, output_size)) + ) + ) + return output_size + + @staticmethod + @lru_cache(maxsize=128) + def _cal_im2col_step(input_size, default_size): + """ + Calculate proper im2col step size, which should be divisible by input_size and not larger + than prefer_size. Meanwhile the step size should be as large as possible to be more + efficient. So we choose the largest one among all divisors of input_size which are smaller + than prefer_size. + :param input_size: input batch size . + :param default_size: default preferred im2col step size. + :return: the largest proper step size. + """ + if input_size <= default_size: + return input_size + best_step = 1 + for step in range(2, min(int(math.sqrt(input_size)) + 1, default_size)): + if input_size % step == 0: + if input_size // step <= default_size: + return input_size // step + best_step = step + + return best_step + + +class _ModulatedDeformConv(Function): + @staticmethod + def forward( + ctx, + input, + offset, + mask, + weight, + bias=None, + stride=1, + padding=0, + dilation=1, + groups=1, + deformable_groups=1, + ): + ctx.stride = stride + ctx.padding = padding + ctx.dilation = dilation + ctx.groups = groups + ctx.deformable_groups = deformable_groups + ctx.with_bias = bias is not None + if not ctx.with_bias: + bias = input.new_empty(1) # fake tensor + if not input.is_cuda: + raise NotImplementedError("Deformable Conv is not supported on CPUs!") + if ( + weight.requires_grad + or mask.requires_grad + or offset.requires_grad + or input.requires_grad + ): + ctx.save_for_backward(input, offset, mask, weight, bias) + output = input.new_empty(_ModulatedDeformConv._infer_shape(ctx, input, weight)) + ctx._bufs = [input.new_empty(0), input.new_empty(0)] + _C.modulated_deform_conv_forward( + input, + weight, + bias, + ctx._bufs[0], + offset, + mask, + output, + ctx._bufs[1], + weight.shape[2], + weight.shape[3], + ctx.stride, + ctx.stride, + ctx.padding, + ctx.padding, + ctx.dilation, + ctx.dilation, + ctx.groups, + ctx.deformable_groups, + ctx.with_bias, + ) + return output + + @staticmethod + @once_differentiable + def backward(ctx, grad_output): + if not grad_output.is_cuda: + raise NotImplementedError("Deformable Conv is not supported on CPUs!") + input, offset, mask, weight, bias = ctx.saved_tensors + grad_input = torch.zeros_like(input) + grad_offset = torch.zeros_like(offset) + grad_mask = torch.zeros_like(mask) + grad_weight = torch.zeros_like(weight) + grad_bias = torch.zeros_like(bias) + _C.modulated_deform_conv_backward( + input, + weight, + bias, + ctx._bufs[0], + offset, + mask, + ctx._bufs[1], + grad_input, + grad_weight, + grad_bias, + grad_offset, + grad_mask, + grad_output, + weight.shape[2], + weight.shape[3], + ctx.stride, + ctx.stride, + ctx.padding, + ctx.padding, + ctx.dilation, + ctx.dilation, + ctx.groups, + ctx.deformable_groups, + ctx.with_bias, + ) + if not ctx.with_bias: + grad_bias = None + + return ( + grad_input, + grad_offset, + grad_mask, + grad_weight, + grad_bias, + None, + None, + None, + None, + None, + ) + + @staticmethod + def _infer_shape(ctx, input, weight): + n = input.size(0) + channels_out = weight.size(0) + height, width = input.shape[2:4] + kernel_h, kernel_w = weight.shape[2:4] + height_out = ( + height + 2 * ctx.padding - (ctx.dilation * (kernel_h - 1) + 1) + ) // ctx.stride + 1 + width_out = ( + width + 2 * ctx.padding - (ctx.dilation * (kernel_w - 1) + 1) + ) // ctx.stride + 1 + return n, channels_out, height_out, width_out + + +deform_conv = _DeformConv.apply +modulated_deform_conv = _ModulatedDeformConv.apply + + +class DeformConv(nn.Module): + def __init__( + self, + in_channels, + out_channels, + kernel_size, + stride=1, + padding=0, + dilation=1, + groups=1, + deformable_groups=1, + bias=False, + norm=None, + activation=None, + ): + """ + Deformable convolution from :paper:`deformconv`. + + Arguments are similar to :class:`Conv2D`. Extra arguments: + + Args: + deformable_groups (int): number of groups used in deformable convolution. + norm (nn.Module, optional): a normalization layer + activation (callable(Tensor) -> Tensor): a callable activation function + """ + super(DeformConv, self).__init__() + + assert not bias + assert in_channels % groups == 0, "in_channels {} cannot be divisible by groups {}".format( + in_channels, groups + ) + assert ( + out_channels % groups == 0 + ), "out_channels {} cannot be divisible by groups {}".format(out_channels, groups) + + self.in_channels = in_channels + self.out_channels = out_channels + self.kernel_size = _pair(kernel_size) + self.stride = _pair(stride) + self.padding = _pair(padding) + self.dilation = _pair(dilation) + self.groups = groups + self.deformable_groups = deformable_groups + self.norm = norm + self.activation = activation + + self.weight = nn.Parameter( + torch.Tensor(out_channels, in_channels // self.groups, *self.kernel_size) + ) + self.bias = None + + nn.init.kaiming_uniform_(self.weight, nonlinearity="relu") + + def forward(self, x, offset): + if x.numel() == 0: + # When input is empty, we want to return a empty tensor with "correct" shape, + # So that the following operations will not panic + # if they check for the shape of the tensor. + # This computes the height and width of the output tensor + output_shape = [ + (i + 2 * p - (di * (k - 1) + 1)) // s + 1 + for i, p, di, k, s in zip( + x.shape[-2:], self.padding, self.dilation, self.kernel_size, self.stride + ) + ] + output_shape = [x.shape[0], self.weight.shape[0]] + output_shape + return _NewEmptyTensorOp.apply(x, output_shape) + + x = deform_conv( + x, + offset, + self.weight, + self.stride, + self.padding, + self.dilation, + self.groups, + self.deformable_groups, + ) + if self.norm is not None: + x = self.norm(x) + if self.activation is not None: + x = self.activation(x) + return x + + def extra_repr(self): + tmpstr = "in_channels=" + str(self.in_channels) + tmpstr += ", out_channels=" + str(self.out_channels) + tmpstr += ", kernel_size=" + str(self.kernel_size) + tmpstr += ", stride=" + str(self.stride) + tmpstr += ", padding=" + str(self.padding) + tmpstr += ", dilation=" + str(self.dilation) + tmpstr += ", groups=" + str(self.groups) + tmpstr += ", deformable_groups=" + str(self.deformable_groups) + tmpstr += ", bias=False" + return tmpstr + + +class ModulatedDeformConv(nn.Module): + def __init__( + self, + in_channels, + out_channels, + kernel_size, + stride=1, + padding=0, + dilation=1, + groups=1, + deformable_groups=1, + bias=True, + norm=None, + activation=None, + ): + """ + Modulated deformable convolution from :paper:`deformconv2`. + + Arguments are similar to :class:`Conv2D`. Extra arguments: + + Args: + deformable_groups (int): number of groups used in deformable convolution. + norm (nn.Module, optional): a normalization layer + activation (callable(Tensor) -> Tensor): a callable activation function + """ + super(ModulatedDeformConv, self).__init__() + self.in_channels = in_channels + self.out_channels = out_channels + self.kernel_size = _pair(kernel_size) + self.stride = stride + self.padding = padding + self.dilation = dilation + self.groups = groups + self.deformable_groups = deformable_groups + self.with_bias = bias + self.norm = norm + self.activation = activation + + self.weight = nn.Parameter( + torch.Tensor(out_channels, in_channels // groups, *self.kernel_size) + ) + if bias: + self.bias = nn.Parameter(torch.Tensor(out_channels)) + else: + self.bias = None + + nn.init.kaiming_uniform_(self.weight, nonlinearity="relu") + if self.bias is not None: + nn.init.constant_(self.bias, 0) + + def forward(self, x, offset, mask): + if x.numel() == 0: + output_shape = [ + (i + 2 * p - (di * (k - 1) + 1)) // s + 1 + for i, p, di, k, s in zip( + x.shape[-2:], self.padding, self.dilation, self.kernel_size, self.stride + ) + ] + output_shape = [x.shape[0], self.weight.shape[0]] + output_shape + return _NewEmptyTensorOp.apply(x, output_shape) + + x = modulated_deform_conv( + x, + offset, + mask, + self.weight, + self.bias, + self.stride, + self.padding, + self.dilation, + self.groups, + self.deformable_groups, + ) + if self.norm is not None: + x = self.norm(x) + if self.activation is not None: + x = self.activation(x) + return x + + def extra_repr(self): + tmpstr = "in_channels=" + str(self.in_channels) + tmpstr += ", out_channels=" + str(self.out_channels) + tmpstr += ", kernel_size=" + str(self.kernel_size) + tmpstr += ", stride=" + str(self.stride) + tmpstr += ", padding=" + str(self.padding) + tmpstr += ", dilation=" + str(self.dilation) + tmpstr += ", groups=" + str(self.groups) + tmpstr += ", deformable_groups=" + str(self.deformable_groups) + tmpstr += ", bias=" + str(self.with_bias) + return tmpstr + + +try: + from annotator.oneformer.detectron2 import _C +except ImportError: + # TODO: register ops natively so there is no need to import _C. + _msg = "detectron2 is not compiled successfully, please build following the instructions!" + _args = ("detectron2._C", _msg) + DeformConv = create_dummy_class("DeformConv", *_args) + ModulatedDeformConv = create_dummy_class("ModulatedDeformConv", *_args) + deform_conv = create_dummy_func("deform_conv", *_args) + modulated_deform_conv = create_dummy_func("modulated_deform_conv", *_args) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/losses.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/losses.py new file mode 100644 index 00000000..850a852a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/losses.py @@ -0,0 +1,133 @@ +import math +import torch + + +def diou_loss( + boxes1: torch.Tensor, + boxes2: torch.Tensor, + reduction: str = "none", + eps: float = 1e-7, +) -> torch.Tensor: + """ + Distance Intersection over Union Loss (Zhaohui Zheng et. al) + https://arxiv.org/abs/1911.08287 + Args: + boxes1, boxes2 (Tensor): box locations in XYXY format, shape (N, 4) or (4,). + reduction: 'none' | 'mean' | 'sum' + 'none': No reduction will be applied to the output. + 'mean': The output will be averaged. + 'sum': The output will be summed. + eps (float): small number to prevent division by zero + """ + + x1, y1, x2, y2 = boxes1.unbind(dim=-1) + x1g, y1g, x2g, y2g = boxes2.unbind(dim=-1) + + # TODO: use torch._assert_async() when pytorch 1.8 support is dropped + assert (x2 >= x1).all(), "bad box: x1 larger than x2" + assert (y2 >= y1).all(), "bad box: y1 larger than y2" + + # Intersection keypoints + xkis1 = torch.max(x1, x1g) + ykis1 = torch.max(y1, y1g) + xkis2 = torch.min(x2, x2g) + ykis2 = torch.min(y2, y2g) + + intsct = torch.zeros_like(x1) + mask = (ykis2 > ykis1) & (xkis2 > xkis1) + intsct[mask] = (xkis2[mask] - xkis1[mask]) * (ykis2[mask] - ykis1[mask]) + union = (x2 - x1) * (y2 - y1) + (x2g - x1g) * (y2g - y1g) - intsct + eps + iou = intsct / union + + # smallest enclosing box + xc1 = torch.min(x1, x1g) + yc1 = torch.min(y1, y1g) + xc2 = torch.max(x2, x2g) + yc2 = torch.max(y2, y2g) + diag_len = ((xc2 - xc1) ** 2) + ((yc2 - yc1) ** 2) + eps + + # centers of boxes + x_p = (x2 + x1) / 2 + y_p = (y2 + y1) / 2 + x_g = (x1g + x2g) / 2 + y_g = (y1g + y2g) / 2 + distance = ((x_p - x_g) ** 2) + ((y_p - y_g) ** 2) + + # Eqn. (7) + loss = 1 - iou + (distance / diag_len) + if reduction == "mean": + loss = loss.mean() if loss.numel() > 0 else 0.0 * loss.sum() + elif reduction == "sum": + loss = loss.sum() + + return loss + + +def ciou_loss( + boxes1: torch.Tensor, + boxes2: torch.Tensor, + reduction: str = "none", + eps: float = 1e-7, +) -> torch.Tensor: + """ + Complete Intersection over Union Loss (Zhaohui Zheng et. al) + https://arxiv.org/abs/1911.08287 + Args: + boxes1, boxes2 (Tensor): box locations in XYXY format, shape (N, 4) or (4,). + reduction: 'none' | 'mean' | 'sum' + 'none': No reduction will be applied to the output. + 'mean': The output will be averaged. + 'sum': The output will be summed. + eps (float): small number to prevent division by zero + """ + + x1, y1, x2, y2 = boxes1.unbind(dim=-1) + x1g, y1g, x2g, y2g = boxes2.unbind(dim=-1) + + # TODO: use torch._assert_async() when pytorch 1.8 support is dropped + assert (x2 >= x1).all(), "bad box: x1 larger than x2" + assert (y2 >= y1).all(), "bad box: y1 larger than y2" + + # Intersection keypoints + xkis1 = torch.max(x1, x1g) + ykis1 = torch.max(y1, y1g) + xkis2 = torch.min(x2, x2g) + ykis2 = torch.min(y2, y2g) + + intsct = torch.zeros_like(x1) + mask = (ykis2 > ykis1) & (xkis2 > xkis1) + intsct[mask] = (xkis2[mask] - xkis1[mask]) * (ykis2[mask] - ykis1[mask]) + union = (x2 - x1) * (y2 - y1) + (x2g - x1g) * (y2g - y1g) - intsct + eps + iou = intsct / union + + # smallest enclosing box + xc1 = torch.min(x1, x1g) + yc1 = torch.min(y1, y1g) + xc2 = torch.max(x2, x2g) + yc2 = torch.max(y2, y2g) + diag_len = ((xc2 - xc1) ** 2) + ((yc2 - yc1) ** 2) + eps + + # centers of boxes + x_p = (x2 + x1) / 2 + y_p = (y2 + y1) / 2 + x_g = (x1g + x2g) / 2 + y_g = (y1g + y2g) / 2 + distance = ((x_p - x_g) ** 2) + ((y_p - y_g) ** 2) + + # width and height of boxes + w_pred = x2 - x1 + h_pred = y2 - y1 + w_gt = x2g - x1g + h_gt = y2g - y1g + v = (4 / (math.pi**2)) * torch.pow((torch.atan(w_gt / h_gt) - torch.atan(w_pred / h_pred)), 2) + with torch.no_grad(): + alpha = v / (1 - iou + v + eps) + + # Eqn. (10) + loss = 1 - iou + (distance / diag_len) + alpha * v + if reduction == "mean": + loss = loss.mean() if loss.numel() > 0 else 0.0 * loss.sum() + elif reduction == "sum": + loss = loss.sum() + + return loss diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/mask_ops.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/mask_ops.py new file mode 100644 index 00000000..990d04ab --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/mask_ops.py @@ -0,0 +1,275 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import numpy as np +from typing import Tuple +import torch +from PIL import Image +from torch.nn import functional as F + +__all__ = ["paste_masks_in_image"] + + +BYTES_PER_FLOAT = 4 +# TODO: This memory limit may be too much or too little. It would be better to +# determine it based on available resources. +GPU_MEM_LIMIT = 1024**3 # 1 GB memory limit + + +def _do_paste_mask(masks, boxes, img_h: int, img_w: int, skip_empty: bool = True): + """ + Args: + masks: N, 1, H, W + boxes: N, 4 + img_h, img_w (int): + skip_empty (bool): only paste masks within the region that + tightly bound all boxes, and returns the results this region only. + An important optimization for CPU. + + Returns: + if skip_empty == False, a mask of shape (N, img_h, img_w) + if skip_empty == True, a mask of shape (N, h', w'), and the slice + object for the corresponding region. + """ + # On GPU, paste all masks together (up to chunk size) + # by using the entire image to sample the masks + # Compared to pasting them one by one, + # this has more operations but is faster on COCO-scale dataset. + device = masks.device + + if skip_empty and not torch.jit.is_scripting(): + x0_int, y0_int = torch.clamp(boxes.min(dim=0).values.floor()[:2] - 1, min=0).to( + dtype=torch.int32 + ) + x1_int = torch.clamp(boxes[:, 2].max().ceil() + 1, max=img_w).to(dtype=torch.int32) + y1_int = torch.clamp(boxes[:, 3].max().ceil() + 1, max=img_h).to(dtype=torch.int32) + else: + x0_int, y0_int = 0, 0 + x1_int, y1_int = img_w, img_h + x0, y0, x1, y1 = torch.split(boxes, 1, dim=1) # each is Nx1 + + N = masks.shape[0] + + img_y = torch.arange(y0_int, y1_int, device=device, dtype=torch.float32) + 0.5 + img_x = torch.arange(x0_int, x1_int, device=device, dtype=torch.float32) + 0.5 + img_y = (img_y - y0) / (y1 - y0) * 2 - 1 + img_x = (img_x - x0) / (x1 - x0) * 2 - 1 + # img_x, img_y have shapes (N, w), (N, h) + + gx = img_x[:, None, :].expand(N, img_y.size(1), img_x.size(1)) + gy = img_y[:, :, None].expand(N, img_y.size(1), img_x.size(1)) + grid = torch.stack([gx, gy], dim=3) + + if not torch.jit.is_scripting(): + if not masks.dtype.is_floating_point: + masks = masks.float() + img_masks = F.grid_sample(masks, grid.to(masks.dtype), align_corners=False) + + if skip_empty and not torch.jit.is_scripting(): + return img_masks[:, 0], (slice(y0_int, y1_int), slice(x0_int, x1_int)) + else: + return img_masks[:, 0], () + + +# Annotate boxes as Tensor (but not Boxes) in order to use scripting +@torch.jit.script_if_tracing +def paste_masks_in_image( + masks: torch.Tensor, boxes: torch.Tensor, image_shape: Tuple[int, int], threshold: float = 0.5 +): + """ + Paste a set of masks that are of a fixed resolution (e.g., 28 x 28) into an image. + The location, height, and width for pasting each mask is determined by their + corresponding bounding boxes in boxes. + + Note: + This is a complicated but more accurate implementation. In actual deployment, it is + often enough to use a faster but less accurate implementation. + See :func:`paste_mask_in_image_old` in this file for an alternative implementation. + + Args: + masks (tensor): Tensor of shape (Bimg, Hmask, Wmask), where Bimg is the number of + detected object instances in the image and Hmask, Wmask are the mask width and mask + height of the predicted mask (e.g., Hmask = Wmask = 28). Values are in [0, 1]. + boxes (Boxes or Tensor): A Boxes of length Bimg or Tensor of shape (Bimg, 4). + boxes[i] and masks[i] correspond to the same object instance. + image_shape (tuple): height, width + threshold (float): A threshold in [0, 1] for converting the (soft) masks to + binary masks. + + Returns: + img_masks (Tensor): A tensor of shape (Bimg, Himage, Wimage), where Bimg is the + number of detected object instances and Himage, Wimage are the image width + and height. img_masks[i] is a binary mask for object instance i. + """ + + assert masks.shape[-1] == masks.shape[-2], "Only square mask predictions are supported" + N = len(masks) + if N == 0: + return masks.new_empty((0,) + image_shape, dtype=torch.uint8) + if not isinstance(boxes, torch.Tensor): + boxes = boxes.tensor + device = boxes.device + assert len(boxes) == N, boxes.shape + + img_h, img_w = image_shape + + # The actual implementation split the input into chunks, + # and paste them chunk by chunk. + if device.type == "cpu" or torch.jit.is_scripting(): + # CPU is most efficient when they are pasted one by one with skip_empty=True + # so that it performs minimal number of operations. + num_chunks = N + else: + # GPU benefits from parallelism for larger chunks, but may have memory issue + # int(img_h) because shape may be tensors in tracing + num_chunks = int(np.ceil(N * int(img_h) * int(img_w) * BYTES_PER_FLOAT / GPU_MEM_LIMIT)) + assert ( + num_chunks <= N + ), "Default GPU_MEM_LIMIT in mask_ops.py is too small; try increasing it" + chunks = torch.chunk(torch.arange(N, device=device), num_chunks) + + img_masks = torch.zeros( + N, img_h, img_w, device=device, dtype=torch.bool if threshold >= 0 else torch.uint8 + ) + for inds in chunks: + masks_chunk, spatial_inds = _do_paste_mask( + masks[inds, None, :, :], boxes[inds], img_h, img_w, skip_empty=device.type == "cpu" + ) + + if threshold >= 0: + masks_chunk = (masks_chunk >= threshold).to(dtype=torch.bool) + else: + # for visualization and debugging + masks_chunk = (masks_chunk * 255).to(dtype=torch.uint8) + + if torch.jit.is_scripting(): # Scripting does not use the optimized codepath + img_masks[inds] = masks_chunk + else: + img_masks[(inds,) + spatial_inds] = masks_chunk + return img_masks + + +# The below are the original paste function (from Detectron1) which has +# larger quantization error. +# It is faster on CPU, while the aligned one is faster on GPU thanks to grid_sample. + + +def paste_mask_in_image_old(mask, box, img_h, img_w, threshold): + """ + Paste a single mask in an image. + This is a per-box implementation of :func:`paste_masks_in_image`. + This function has larger quantization error due to incorrect pixel + modeling and is not used any more. + + Args: + mask (Tensor): A tensor of shape (Hmask, Wmask) storing the mask of a single + object instance. Values are in [0, 1]. + box (Tensor): A tensor of shape (4, ) storing the x0, y0, x1, y1 box corners + of the object instance. + img_h, img_w (int): Image height and width. + threshold (float): Mask binarization threshold in [0, 1]. + + Returns: + im_mask (Tensor): + The resized and binarized object mask pasted into the original + image plane (a tensor of shape (img_h, img_w)). + """ + # Conversion from continuous box coordinates to discrete pixel coordinates + # via truncation (cast to int32). This determines which pixels to paste the + # mask onto. + box = box.to(dtype=torch.int32) # Continuous to discrete coordinate conversion + # An example (1D) box with continuous coordinates (x0=0.7, x1=4.3) will map to + # a discrete coordinates (x0=0, x1=4). Note that box is mapped to 5 = x1 - x0 + 1 + # pixels (not x1 - x0 pixels). + samples_w = box[2] - box[0] + 1 # Number of pixel samples, *not* geometric width + samples_h = box[3] - box[1] + 1 # Number of pixel samples, *not* geometric height + + # Resample the mask from it's original grid to the new samples_w x samples_h grid + mask = Image.fromarray(mask.cpu().numpy()) + mask = mask.resize((samples_w, samples_h), resample=Image.BILINEAR) + mask = np.array(mask, copy=False) + + if threshold >= 0: + mask = np.array(mask > threshold, dtype=np.uint8) + mask = torch.from_numpy(mask) + else: + # for visualization and debugging, we also + # allow it to return an unmodified mask + mask = torch.from_numpy(mask * 255).to(torch.uint8) + + im_mask = torch.zeros((img_h, img_w), dtype=torch.uint8) + x_0 = max(box[0], 0) + x_1 = min(box[2] + 1, img_w) + y_0 = max(box[1], 0) + y_1 = min(box[3] + 1, img_h) + + im_mask[y_0:y_1, x_0:x_1] = mask[ + (y_0 - box[1]) : (y_1 - box[1]), (x_0 - box[0]) : (x_1 - box[0]) + ] + return im_mask + + +# Our pixel modeling requires extrapolation for any continuous +# coordinate < 0.5 or > length - 0.5. When sampling pixels on the masks, +# we would like this extrapolation to be an interpolation between boundary values and zero, +# instead of using absolute zero or boundary values. +# Therefore `paste_mask_in_image_old` is often used with zero padding around the masks like this: +# masks, scale = pad_masks(masks[:, 0, :, :], 1) +# boxes = scale_boxes(boxes.tensor, scale) + + +def pad_masks(masks, padding): + """ + Args: + masks (tensor): A tensor of shape (B, M, M) representing B masks. + padding (int): Number of cells to pad on all sides. + + Returns: + The padded masks and the scale factor of the padding size / original size. + """ + B = masks.shape[0] + M = masks.shape[-1] + pad2 = 2 * padding + scale = float(M + pad2) / M + padded_masks = masks.new_zeros((B, M + pad2, M + pad2)) + padded_masks[:, padding:-padding, padding:-padding] = masks + return padded_masks, scale + + +def scale_boxes(boxes, scale): + """ + Args: + boxes (tensor): A tensor of shape (B, 4) representing B boxes with 4 + coords representing the corners x0, y0, x1, y1, + scale (float): The box scaling factor. + + Returns: + Scaled boxes. + """ + w_half = (boxes[:, 2] - boxes[:, 0]) * 0.5 + h_half = (boxes[:, 3] - boxes[:, 1]) * 0.5 + x_c = (boxes[:, 2] + boxes[:, 0]) * 0.5 + y_c = (boxes[:, 3] + boxes[:, 1]) * 0.5 + + w_half *= scale + h_half *= scale + + scaled_boxes = torch.zeros_like(boxes) + scaled_boxes[:, 0] = x_c - w_half + scaled_boxes[:, 2] = x_c + w_half + scaled_boxes[:, 1] = y_c - h_half + scaled_boxes[:, 3] = y_c + h_half + return scaled_boxes + + +@torch.jit.script_if_tracing +def _paste_masks_tensor_shape( + masks: torch.Tensor, + boxes: torch.Tensor, + image_shape: Tuple[torch.Tensor, torch.Tensor], + threshold: float = 0.5, +): + """ + A wrapper of paste_masks_in_image where image_shape is Tensor. + During tracing, shapes might be tensors instead of ints. The Tensor->int + conversion should be scripted rather than traced. + """ + return paste_masks_in_image(masks, boxes, (int(image_shape[0]), int(image_shape[1])), threshold) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/nms.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/nms.py new file mode 100644 index 00000000..1019e7f4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/nms.py @@ -0,0 +1,144 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +import torch +from torchvision.ops import boxes as box_ops +from torchvision.ops import nms # noqa . for compatibility + + +def batched_nms( + boxes: torch.Tensor, scores: torch.Tensor, idxs: torch.Tensor, iou_threshold: float +): + """ + Same as torchvision.ops.boxes.batched_nms, but with float(). + """ + assert boxes.shape[-1] == 4 + # Note: Torchvision already has a strategy (https://github.com/pytorch/vision/issues/1311) + # to decide whether to use coordinate trick or for loop to implement batched_nms. So we + # just call it directly. + # Fp16 does not have enough range for batched NMS, so adding float(). + return box_ops.batched_nms(boxes.float(), scores, idxs, iou_threshold) + + +# Note: this function (nms_rotated) might be moved into +# torchvision/ops/boxes.py in the future +def nms_rotated(boxes: torch.Tensor, scores: torch.Tensor, iou_threshold: float): + """ + Performs non-maximum suppression (NMS) on the rotated boxes according + to their intersection-over-union (IoU). + + Rotated NMS iteratively removes lower scoring rotated boxes which have an + IoU greater than iou_threshold with another (higher scoring) rotated box. + + Note that RotatedBox (5, 3, 4, 2, -90) covers exactly the same region as + RotatedBox (5, 3, 4, 2, 90) does, and their IoU will be 1. However, they + can be representing completely different objects in certain tasks, e.g., OCR. + + As for the question of whether rotated-NMS should treat them as faraway boxes + even though their IOU is 1, it depends on the application and/or ground truth annotation. + + As an extreme example, consider a single character v and the square box around it. + + If the angle is 0 degree, the object (text) would be read as 'v'; + + If the angle is 90 degrees, the object (text) would become '>'; + + If the angle is 180 degrees, the object (text) would become '^'; + + If the angle is 270/-90 degrees, the object (text) would become '<' + + All of these cases have IoU of 1 to each other, and rotated NMS that only + uses IoU as criterion would only keep one of them with the highest score - + which, practically, still makes sense in most cases because typically + only one of theses orientations is the correct one. Also, it does not matter + as much if the box is only used to classify the object (instead of transcribing + them with a sequential OCR recognition model) later. + + On the other hand, when we use IoU to filter proposals that are close to the + ground truth during training, we should definitely take the angle into account if + we know the ground truth is labeled with the strictly correct orientation (as in, + upside-down words are annotated with -180 degrees even though they can be covered + with a 0/90/-90 degree box, etc.) + + The way the original dataset is annotated also matters. For example, if the dataset + is a 4-point polygon dataset that does not enforce ordering of vertices/orientation, + we can estimate a minimum rotated bounding box to this polygon, but there's no way + we can tell the correct angle with 100% confidence (as shown above, there could be 4 different + rotated boxes, with angles differed by 90 degrees to each other, covering the exactly + same region). In that case we have to just use IoU to determine the box + proximity (as many detection benchmarks (even for text) do) unless there're other + assumptions we can make (like width is always larger than height, or the object is not + rotated by more than 90 degrees CCW/CW, etc.) + + In summary, not considering angles in rotated NMS seems to be a good option for now, + but we should be aware of its implications. + + Args: + boxes (Tensor[N, 5]): Rotated boxes to perform NMS on. They are expected to be in + (x_center, y_center, width, height, angle_degrees) format. + scores (Tensor[N]): Scores for each one of the rotated boxes + iou_threshold (float): Discards all overlapping rotated boxes with IoU < iou_threshold + + Returns: + keep (Tensor): int64 tensor with the indices of the elements that have been kept + by Rotated NMS, sorted in decreasing order of scores + """ + return torch.ops.detectron2.nms_rotated(boxes, scores, iou_threshold) + + +# Note: this function (batched_nms_rotated) might be moved into +# torchvision/ops/boxes.py in the future + + +@torch.jit.script_if_tracing +def batched_nms_rotated( + boxes: torch.Tensor, scores: torch.Tensor, idxs: torch.Tensor, iou_threshold: float +): + """ + Performs non-maximum suppression in a batched fashion. + + Each index value correspond to a category, and NMS + will not be applied between elements of different categories. + + Args: + boxes (Tensor[N, 5]): + boxes where NMS will be performed. They + are expected to be in (x_ctr, y_ctr, width, height, angle_degrees) format + scores (Tensor[N]): + scores for each one of the boxes + idxs (Tensor[N]): + indices of the categories for each one of the boxes. + iou_threshold (float): + discards all overlapping boxes + with IoU < iou_threshold + + Returns: + Tensor: + int64 tensor with the indices of the elements that have been kept + by NMS, sorted in decreasing order of scores + """ + assert boxes.shape[-1] == 5 + + if boxes.numel() == 0: + return torch.empty((0,), dtype=torch.int64, device=boxes.device) + boxes = boxes.float() # fp16 does not have enough range for batched NMS + # Strategy: in order to perform NMS independently per class, + # we add an offset to all the boxes. The offset is dependent + # only on the class idx, and is large enough so that boxes + # from different classes do not overlap + + # Note that batched_nms in torchvision/ops/boxes.py only uses max_coordinate, + # which won't handle negative coordinates correctly. + # Here by using min_coordinate we can make sure the negative coordinates are + # correctly handled. + max_coordinate = ( + torch.max(boxes[:, 0], boxes[:, 1]) + torch.max(boxes[:, 2], boxes[:, 3]) / 2 + ).max() + min_coordinate = ( + torch.min(boxes[:, 0], boxes[:, 1]) - torch.max(boxes[:, 2], boxes[:, 3]) / 2 + ).min() + offsets = idxs.to(boxes) * (max_coordinate - min_coordinate + 1) + boxes_for_nms = boxes.clone() # avoid modifying the original values in boxes + boxes_for_nms[:, :2] += offsets[:, None] + keep = nms_rotated(boxes_for_nms, scores, iou_threshold) + return keep diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/roi_align.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/roi_align.py new file mode 100644 index 00000000..163462e1 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/roi_align.py @@ -0,0 +1,74 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from torch import nn +from torchvision.ops import roi_align + + +# NOTE: torchvision's RoIAlign has a different default aligned=False +class ROIAlign(nn.Module): + def __init__(self, output_size, spatial_scale, sampling_ratio, aligned=True): + """ + Args: + output_size (tuple): h, w + spatial_scale (float): scale the input boxes by this number + sampling_ratio (int): number of inputs samples to take for each output + sample. 0 to take samples densely. + aligned (bool): if False, use the legacy implementation in + Detectron. If True, align the results more perfectly. + + Note: + The meaning of aligned=True: + + Given a continuous coordinate c, its two neighboring pixel indices (in our + pixel model) are computed by floor(c - 0.5) and ceil(c - 0.5). For example, + c=1.3 has pixel neighbors with discrete indices [0] and [1] (which are sampled + from the underlying signal at continuous coordinates 0.5 and 1.5). But the original + roi_align (aligned=False) does not subtract the 0.5 when computing neighboring + pixel indices and therefore it uses pixels with a slightly incorrect alignment + (relative to our pixel model) when performing bilinear interpolation. + + With `aligned=True`, + we first appropriately scale the ROI and then shift it by -0.5 + prior to calling roi_align. This produces the correct neighbors; see + detectron2/tests/test_roi_align.py for verification. + + The difference does not make a difference to the model's performance if + ROIAlign is used together with conv layers. + """ + super().__init__() + self.output_size = output_size + self.spatial_scale = spatial_scale + self.sampling_ratio = sampling_ratio + self.aligned = aligned + + from torchvision import __version__ + + version = tuple(int(x) for x in __version__.split(".")[:2]) + # https://github.com/pytorch/vision/pull/2438 + assert version >= (0, 7), "Require torchvision >= 0.7" + + def forward(self, input, rois): + """ + Args: + input: NCHW images + rois: Bx5 boxes. First column is the index into N. The other 4 columns are xyxy. + """ + assert rois.dim() == 2 and rois.size(1) == 5 + if input.is_quantized: + input = input.dequantize() + return roi_align( + input, + rois.to(dtype=input.dtype), + self.output_size, + self.spatial_scale, + self.sampling_ratio, + self.aligned, + ) + + def __repr__(self): + tmpstr = self.__class__.__name__ + "(" + tmpstr += "output_size=" + str(self.output_size) + tmpstr += ", spatial_scale=" + str(self.spatial_scale) + tmpstr += ", sampling_ratio=" + str(self.sampling_ratio) + tmpstr += ", aligned=" + str(self.aligned) + tmpstr += ")" + return tmpstr diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/roi_align_rotated.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/roi_align_rotated.py new file mode 100644 index 00000000..2a523992 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/roi_align_rotated.py @@ -0,0 +1,100 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import torch +from torch import nn +from torch.autograd import Function +from torch.autograd.function import once_differentiable +from torch.nn.modules.utils import _pair + + +class _ROIAlignRotated(Function): + @staticmethod + def forward(ctx, input, roi, output_size, spatial_scale, sampling_ratio): + ctx.save_for_backward(roi) + ctx.output_size = _pair(output_size) + ctx.spatial_scale = spatial_scale + ctx.sampling_ratio = sampling_ratio + ctx.input_shape = input.size() + output = torch.ops.detectron2.roi_align_rotated_forward( + input, roi, spatial_scale, output_size[0], output_size[1], sampling_ratio + ) + return output + + @staticmethod + @once_differentiable + def backward(ctx, grad_output): + (rois,) = ctx.saved_tensors + output_size = ctx.output_size + spatial_scale = ctx.spatial_scale + sampling_ratio = ctx.sampling_ratio + bs, ch, h, w = ctx.input_shape + grad_input = torch.ops.detectron2.roi_align_rotated_backward( + grad_output, + rois, + spatial_scale, + output_size[0], + output_size[1], + bs, + ch, + h, + w, + sampling_ratio, + ) + return grad_input, None, None, None, None, None + + +roi_align_rotated = _ROIAlignRotated.apply + + +class ROIAlignRotated(nn.Module): + def __init__(self, output_size, spatial_scale, sampling_ratio): + """ + Args: + output_size (tuple): h, w + spatial_scale (float): scale the input boxes by this number + sampling_ratio (int): number of inputs samples to take for each output + sample. 0 to take samples densely. + + Note: + ROIAlignRotated supports continuous coordinate by default: + Given a continuous coordinate c, its two neighboring pixel indices (in our + pixel model) are computed by floor(c - 0.5) and ceil(c - 0.5). For example, + c=1.3 has pixel neighbors with discrete indices [0] and [1] (which are sampled + from the underlying signal at continuous coordinates 0.5 and 1.5). + """ + super(ROIAlignRotated, self).__init__() + self.output_size = output_size + self.spatial_scale = spatial_scale + self.sampling_ratio = sampling_ratio + + def forward(self, input, rois): + """ + Args: + input: NCHW images + rois: Bx6 boxes. First column is the index into N. + The other 5 columns are (x_ctr, y_ctr, width, height, angle_degrees). + """ + assert rois.dim() == 2 and rois.size(1) == 6 + orig_dtype = input.dtype + if orig_dtype == torch.float16: + input = input.float() + rois = rois.float() + output_size = _pair(self.output_size) + + # Scripting for Autograd is currently unsupported. + # This is a quick fix without having to rewrite code on the C++ side + if torch.jit.is_scripting() or torch.jit.is_tracing(): + return torch.ops.detectron2.roi_align_rotated_forward( + input, rois, self.spatial_scale, output_size[0], output_size[1], self.sampling_ratio + ).to(dtype=orig_dtype) + + return roi_align_rotated( + input, rois, self.output_size, self.spatial_scale, self.sampling_ratio + ).to(dtype=orig_dtype) + + def __repr__(self): + tmpstr = self.__class__.__name__ + "(" + tmpstr += "output_size=" + str(self.output_size) + tmpstr += ", spatial_scale=" + str(self.spatial_scale) + tmpstr += ", sampling_ratio=" + str(self.sampling_ratio) + tmpstr += ")" + return tmpstr diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/rotated_boxes.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/rotated_boxes.py new file mode 100644 index 00000000..03f73b3b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/rotated_boxes.py @@ -0,0 +1,21 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from __future__ import absolute_import, division, print_function, unicode_literals +import torch + + +def pairwise_iou_rotated(boxes1, boxes2): + """ + Return intersection-over-union (Jaccard index) of boxes. + + Both sets of boxes are expected to be in + (x_center, y_center, width, height, angle) format. + + Arguments: + boxes1 (Tensor[N, 5]) + boxes2 (Tensor[M, 5]) + + Returns: + iou (Tensor[N, M]): the NxM matrix containing the pairwise + IoU values for every element in boxes1 and boxes2 + """ + return torch.ops.detectron2.box_iou_rotated(boxes1, boxes2) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/shape_spec.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/shape_spec.py new file mode 100644 index 00000000..8dac3c59 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/shape_spec.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. +from dataclasses import dataclass +from typing import Optional + + +@dataclass +class ShapeSpec: + """ + A simple structure that contains basic shape specification about a tensor. + It is often used as the auxiliary inputs/outputs of models, + to complement the lack of shape inference ability among pytorch modules. + """ + + channels: Optional[int] = None + height: Optional[int] = None + width: Optional[int] = None + stride: Optional[int] = None diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/wrappers.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/wrappers.py new file mode 100644 index 00000000..4367f9ab --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/layers/wrappers.py @@ -0,0 +1,162 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +""" +Wrappers around on some nn functions, mainly to support empty tensors. + +Ideally, add support directly in PyTorch to empty tensors in those functions. + +These can be removed once https://github.com/pytorch/pytorch/issues/12013 +is implemented +""" + +import warnings +from typing import List, Optional +import torch +from torch.nn import functional as F + +from annotator.oneformer.detectron2.utils.env import TORCH_VERSION + + +def shapes_to_tensor(x: List[int], device: Optional[torch.device] = None) -> torch.Tensor: + """ + Turn a list of integer scalars or integer Tensor scalars into a vector, + in a way that's both traceable and scriptable. + + In tracing, `x` should be a list of scalar Tensor, so the output can trace to the inputs. + In scripting or eager, `x` should be a list of int. + """ + if torch.jit.is_scripting(): + return torch.as_tensor(x, device=device) + if torch.jit.is_tracing(): + assert all( + [isinstance(t, torch.Tensor) for t in x] + ), "Shape should be tensor during tracing!" + # as_tensor should not be used in tracing because it records a constant + ret = torch.stack(x) + if ret.device != device: # avoid recording a hard-coded device if not necessary + ret = ret.to(device=device) + return ret + return torch.as_tensor(x, device=device) + + +def check_if_dynamo_compiling(): + if TORCH_VERSION >= (1, 14): + from torch._dynamo import is_compiling + + return is_compiling() + else: + return False + + +def cat(tensors: List[torch.Tensor], dim: int = 0): + """ + Efficient version of torch.cat that avoids a copy if there is only a single element in a list + """ + assert isinstance(tensors, (list, tuple)) + if len(tensors) == 1: + return tensors[0] + return torch.cat(tensors, dim) + + +def empty_input_loss_func_wrapper(loss_func): + def wrapped_loss_func(input, target, *, reduction="mean", **kwargs): + """ + Same as `loss_func`, but returns 0 (instead of nan) for empty inputs. + """ + if target.numel() == 0 and reduction == "mean": + return input.sum() * 0.0 # connect the gradient + return loss_func(input, target, reduction=reduction, **kwargs) + + return wrapped_loss_func + + +cross_entropy = empty_input_loss_func_wrapper(F.cross_entropy) + + +class _NewEmptyTensorOp(torch.autograd.Function): + @staticmethod + def forward(ctx, x, new_shape): + ctx.shape = x.shape + return x.new_empty(new_shape) + + @staticmethod + def backward(ctx, grad): + shape = ctx.shape + return _NewEmptyTensorOp.apply(grad, shape), None + + +class Conv2d(torch.nn.Conv2d): + """ + A wrapper around :class:`torch.nn.Conv2d` to support empty inputs and more features. + """ + + def __init__(self, *args, **kwargs): + """ + Extra keyword arguments supported in addition to those in `torch.nn.Conv2d`: + + Args: + norm (nn.Module, optional): a normalization layer + activation (callable(Tensor) -> Tensor): a callable activation function + + It assumes that norm layer is used before activation. + """ + norm = kwargs.pop("norm", None) + activation = kwargs.pop("activation", None) + super().__init__(*args, **kwargs) + + self.norm = norm + self.activation = activation + + def forward(self, x): + # torchscript does not support SyncBatchNorm yet + # https://github.com/pytorch/pytorch/issues/40507 + # and we skip these codes in torchscript since: + # 1. currently we only support torchscript in evaluation mode + # 2. features needed by exporting module to torchscript are added in PyTorch 1.6 or + # later version, `Conv2d` in these PyTorch versions has already supported empty inputs. + if not torch.jit.is_scripting(): + # Dynamo doesn't support context managers yet + is_dynamo_compiling = check_if_dynamo_compiling() + if not is_dynamo_compiling: + with warnings.catch_warnings(record=True): + if x.numel() == 0 and self.training: + # https://github.com/pytorch/pytorch/issues/12013 + assert not isinstance( + self.norm, torch.nn.SyncBatchNorm + ), "SyncBatchNorm does not support empty inputs!" + + x = F.conv2d( + x, self.weight, self.bias, self.stride, self.padding, self.dilation, self.groups + ) + if self.norm is not None: + x = self.norm(x) + if self.activation is not None: + x = self.activation(x) + return x + + +ConvTranspose2d = torch.nn.ConvTranspose2d +BatchNorm2d = torch.nn.BatchNorm2d +interpolate = F.interpolate +Linear = torch.nn.Linear + + +def nonzero_tuple(x): + """ + A 'as_tuple=True' version of torch.nonzero to support torchscript. + because of https://github.com/pytorch/pytorch/issues/38718 + """ + if torch.jit.is_scripting(): + if x.dim() == 0: + return x.unsqueeze(0).nonzero().unbind(1) + return x.nonzero().unbind(1) + else: + return x.nonzero(as_tuple=True) + + +@torch.jit.script_if_tracing +def move_device_like(src: torch.Tensor, dst: torch.Tensor) -> torch.Tensor: + """ + Tracing friendly way to cast tensor to another tensor's device. Device will be treated + as constant during tracing, scripting the casting process as whole can workaround this issue. + """ + return src.to(dst.device) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/model_zoo/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/model_zoo/__init__.py new file mode 100644 index 00000000..62042081 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/model_zoo/__init__.py @@ -0,0 +1,10 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +""" +Model Zoo API for Detectron2: a collection of functions to create common model architectures +listed in `MODEL_ZOO.md `_, +and optionally load their pre-trained weights. +""" + +from .model_zoo import get, get_config_file, get_checkpoint_url, get_config + +__all__ = ["get_checkpoint_url", "get", "get_config_file", "get_config"] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/model_zoo/model_zoo.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/model_zoo/model_zoo.py new file mode 100644 index 00000000..74e11b29 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/model_zoo/model_zoo.py @@ -0,0 +1,213 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import os +from typing import Optional +import pkg_resources +import torch + +from annotator.oneformer.detectron2.checkpoint import DetectionCheckpointer +from annotator.oneformer.detectron2.config import CfgNode, LazyConfig, get_cfg, instantiate +from annotator.oneformer.detectron2.modeling import build_model + + +class _ModelZooUrls(object): + """ + Mapping from names to officially released Detectron2 pre-trained models. + """ + + S3_PREFIX = "https://dl.fbaipublicfiles.com/detectron2/" + + # format: {config_path.yaml} -> model_id/model_final_{commit}.pkl + CONFIG_PATH_TO_URL_SUFFIX = { + # COCO Detection with Faster R-CNN + "COCO-Detection/faster_rcnn_R_50_C4_1x": "137257644/model_final_721ade.pkl", + "COCO-Detection/faster_rcnn_R_50_DC5_1x": "137847829/model_final_51d356.pkl", + "COCO-Detection/faster_rcnn_R_50_FPN_1x": "137257794/model_final_b275ba.pkl", + "COCO-Detection/faster_rcnn_R_50_C4_3x": "137849393/model_final_f97cb7.pkl", + "COCO-Detection/faster_rcnn_R_50_DC5_3x": "137849425/model_final_68d202.pkl", + "COCO-Detection/faster_rcnn_R_50_FPN_3x": "137849458/model_final_280758.pkl", + "COCO-Detection/faster_rcnn_R_101_C4_3x": "138204752/model_final_298dad.pkl", + "COCO-Detection/faster_rcnn_R_101_DC5_3x": "138204841/model_final_3e0943.pkl", + "COCO-Detection/faster_rcnn_R_101_FPN_3x": "137851257/model_final_f6e8b1.pkl", + "COCO-Detection/faster_rcnn_X_101_32x8d_FPN_3x": "139173657/model_final_68b088.pkl", + # COCO Detection with RetinaNet + "COCO-Detection/retinanet_R_50_FPN_1x": "190397773/model_final_bfca0b.pkl", + "COCO-Detection/retinanet_R_50_FPN_3x": "190397829/model_final_5bd44e.pkl", + "COCO-Detection/retinanet_R_101_FPN_3x": "190397697/model_final_971ab9.pkl", + # COCO Detection with RPN and Fast R-CNN + "COCO-Detection/rpn_R_50_C4_1x": "137258005/model_final_450694.pkl", + "COCO-Detection/rpn_R_50_FPN_1x": "137258492/model_final_02ce48.pkl", + "COCO-Detection/fast_rcnn_R_50_FPN_1x": "137635226/model_final_e5f7ce.pkl", + # COCO Instance Segmentation Baselines with Mask R-CNN + "COCO-InstanceSegmentation/mask_rcnn_R_50_C4_1x": "137259246/model_final_9243eb.pkl", + "COCO-InstanceSegmentation/mask_rcnn_R_50_DC5_1x": "137260150/model_final_4f86c3.pkl", + "COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x": "137260431/model_final_a54504.pkl", + "COCO-InstanceSegmentation/mask_rcnn_R_50_C4_3x": "137849525/model_final_4ce675.pkl", + "COCO-InstanceSegmentation/mask_rcnn_R_50_DC5_3x": "137849551/model_final_84107b.pkl", + "COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x": "137849600/model_final_f10217.pkl", + "COCO-InstanceSegmentation/mask_rcnn_R_101_C4_3x": "138363239/model_final_a2914c.pkl", + "COCO-InstanceSegmentation/mask_rcnn_R_101_DC5_3x": "138363294/model_final_0464b7.pkl", + "COCO-InstanceSegmentation/mask_rcnn_R_101_FPN_3x": "138205316/model_final_a3ec72.pkl", + "COCO-InstanceSegmentation/mask_rcnn_X_101_32x8d_FPN_3x": "139653917/model_final_2d9806.pkl", # noqa + # New baselines using Large-Scale Jitter and Longer Training Schedule + "new_baselines/mask_rcnn_R_50_FPN_100ep_LSJ": "42047764/model_final_bb69de.pkl", + "new_baselines/mask_rcnn_R_50_FPN_200ep_LSJ": "42047638/model_final_89a8d3.pkl", + "new_baselines/mask_rcnn_R_50_FPN_400ep_LSJ": "42019571/model_final_14d201.pkl", + "new_baselines/mask_rcnn_R_101_FPN_100ep_LSJ": "42025812/model_final_4f7b58.pkl", + "new_baselines/mask_rcnn_R_101_FPN_200ep_LSJ": "42131867/model_final_0bb7ae.pkl", + "new_baselines/mask_rcnn_R_101_FPN_400ep_LSJ": "42073830/model_final_f96b26.pkl", + "new_baselines/mask_rcnn_regnetx_4gf_dds_FPN_100ep_LSJ": "42047771/model_final_b7fbab.pkl", # noqa + "new_baselines/mask_rcnn_regnetx_4gf_dds_FPN_200ep_LSJ": "42132721/model_final_5d87c1.pkl", # noqa + "new_baselines/mask_rcnn_regnetx_4gf_dds_FPN_400ep_LSJ": "42025447/model_final_f1362d.pkl", # noqa + "new_baselines/mask_rcnn_regnety_4gf_dds_FPN_100ep_LSJ": "42047784/model_final_6ba57e.pkl", # noqa + "new_baselines/mask_rcnn_regnety_4gf_dds_FPN_200ep_LSJ": "42047642/model_final_27b9c1.pkl", # noqa + "new_baselines/mask_rcnn_regnety_4gf_dds_FPN_400ep_LSJ": "42045954/model_final_ef3a80.pkl", # noqa + # COCO Person Keypoint Detection Baselines with Keypoint R-CNN + "COCO-Keypoints/keypoint_rcnn_R_50_FPN_1x": "137261548/model_final_04e291.pkl", + "COCO-Keypoints/keypoint_rcnn_R_50_FPN_3x": "137849621/model_final_a6e10b.pkl", + "COCO-Keypoints/keypoint_rcnn_R_101_FPN_3x": "138363331/model_final_997cc7.pkl", + "COCO-Keypoints/keypoint_rcnn_X_101_32x8d_FPN_3x": "139686956/model_final_5ad38f.pkl", + # COCO Panoptic Segmentation Baselines with Panoptic FPN + "COCO-PanopticSegmentation/panoptic_fpn_R_50_1x": "139514544/model_final_dbfeb4.pkl", + "COCO-PanopticSegmentation/panoptic_fpn_R_50_3x": "139514569/model_final_c10459.pkl", + "COCO-PanopticSegmentation/panoptic_fpn_R_101_3x": "139514519/model_final_cafdb1.pkl", + # LVIS Instance Segmentation Baselines with Mask R-CNN + "LVISv0.5-InstanceSegmentation/mask_rcnn_R_50_FPN_1x": "144219072/model_final_571f7c.pkl", # noqa + "LVISv0.5-InstanceSegmentation/mask_rcnn_R_101_FPN_1x": "144219035/model_final_824ab5.pkl", # noqa + "LVISv0.5-InstanceSegmentation/mask_rcnn_X_101_32x8d_FPN_1x": "144219108/model_final_5e3439.pkl", # noqa + # Cityscapes & Pascal VOC Baselines + "Cityscapes/mask_rcnn_R_50_FPN": "142423278/model_final_af9cf5.pkl", + "PascalVOC-Detection/faster_rcnn_R_50_C4": "142202221/model_final_b1acc2.pkl", + # Other Settings + "Misc/mask_rcnn_R_50_FPN_1x_dconv_c3-c5": "138602867/model_final_65c703.pkl", + "Misc/mask_rcnn_R_50_FPN_3x_dconv_c3-c5": "144998336/model_final_821d0b.pkl", + "Misc/cascade_mask_rcnn_R_50_FPN_1x": "138602847/model_final_e9d89b.pkl", + "Misc/cascade_mask_rcnn_R_50_FPN_3x": "144998488/model_final_480dd8.pkl", + "Misc/mask_rcnn_R_50_FPN_3x_syncbn": "169527823/model_final_3b3c51.pkl", + "Misc/mask_rcnn_R_50_FPN_3x_gn": "138602888/model_final_dc5d9e.pkl", + "Misc/scratch_mask_rcnn_R_50_FPN_3x_gn": "138602908/model_final_01ca85.pkl", + "Misc/scratch_mask_rcnn_R_50_FPN_9x_gn": "183808979/model_final_da7b4c.pkl", + "Misc/scratch_mask_rcnn_R_50_FPN_9x_syncbn": "184226666/model_final_5ce33e.pkl", + "Misc/panoptic_fpn_R_101_dconv_cascade_gn_3x": "139797668/model_final_be35db.pkl", + "Misc/cascade_mask_rcnn_X_152_32x8d_FPN_IN5k_gn_dconv": "18131413/model_0039999_e76410.pkl", # noqa + # D1 Comparisons + "Detectron1-Comparisons/faster_rcnn_R_50_FPN_noaug_1x": "137781054/model_final_7ab50c.pkl", # noqa + "Detectron1-Comparisons/mask_rcnn_R_50_FPN_noaug_1x": "137781281/model_final_62ca52.pkl", # noqa + "Detectron1-Comparisons/keypoint_rcnn_R_50_FPN_1x": "137781195/model_final_cce136.pkl", + } + + @staticmethod + def query(config_path: str) -> Optional[str]: + """ + Args: + config_path: relative config filename + """ + name = config_path.replace(".yaml", "").replace(".py", "") + if name in _ModelZooUrls.CONFIG_PATH_TO_URL_SUFFIX: + suffix = _ModelZooUrls.CONFIG_PATH_TO_URL_SUFFIX[name] + return _ModelZooUrls.S3_PREFIX + name + "/" + suffix + return None + + +def get_checkpoint_url(config_path): + """ + Returns the URL to the model trained using the given config + + Args: + config_path (str): config file name relative to detectron2's "configs/" + directory, e.g., "COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml" + + Returns: + str: a URL to the model + """ + url = _ModelZooUrls.query(config_path) + if url is None: + raise RuntimeError("Pretrained model for {} is not available!".format(config_path)) + return url + + +def get_config_file(config_path): + """ + Returns path to a builtin config file. + + Args: + config_path (str): config file name relative to detectron2's "configs/" + directory, e.g., "COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml" + + Returns: + str: the real path to the config file. + """ + cfg_file = pkg_resources.resource_filename( + "detectron2.model_zoo", os.path.join("configs", config_path) + ) + if not os.path.exists(cfg_file): + raise RuntimeError("{} not available in Model Zoo!".format(config_path)) + return cfg_file + + +def get_config(config_path, trained: bool = False): + """ + Returns a config object for a model in model zoo. + + Args: + config_path (str): config file name relative to detectron2's "configs/" + directory, e.g., "COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml" + trained (bool): If True, will set ``MODEL.WEIGHTS`` to trained model zoo weights. + If False, the checkpoint specified in the config file's ``MODEL.WEIGHTS`` is used + instead; this will typically (though not always) initialize a subset of weights using + an ImageNet pre-trained model, while randomly initializing the other weights. + + Returns: + CfgNode or omegaconf.DictConfig: a config object + """ + cfg_file = get_config_file(config_path) + if cfg_file.endswith(".yaml"): + cfg = get_cfg() + cfg.merge_from_file(cfg_file) + if trained: + cfg.MODEL.WEIGHTS = get_checkpoint_url(config_path) + return cfg + elif cfg_file.endswith(".py"): + cfg = LazyConfig.load(cfg_file) + if trained: + url = get_checkpoint_url(config_path) + if "train" in cfg and "init_checkpoint" in cfg.train: + cfg.train.init_checkpoint = url + else: + raise NotImplementedError + return cfg + + +def get(config_path, trained: bool = False, device: Optional[str] = None): + """ + Get a model specified by relative path under Detectron2's official ``configs/`` directory. + + Args: + config_path (str): config file name relative to detectron2's "configs/" + directory, e.g., "COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml" + trained (bool): see :func:`get_config`. + device (str or None): overwrite the device in config, if given. + + Returns: + nn.Module: a detectron2 model. Will be in training mode. + + Example: + :: + from annotator.oneformer.detectron2 import model_zoo + model = model_zoo.get("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml", trained=True) + """ + cfg = get_config(config_path, trained) + if device is None and not torch.cuda.is_available(): + device = "cpu" + if device is not None and isinstance(cfg, CfgNode): + cfg.MODEL.DEVICE = device + + if isinstance(cfg, CfgNode): + model = build_model(cfg) + DetectionCheckpointer(model).load(cfg.MODEL.WEIGHTS) + else: + model = instantiate(cfg.model) + if device is not None: + model = model.to(device) + if "train" in cfg and "init_checkpoint" in cfg.train: + DetectionCheckpointer(model).load(cfg.train.init_checkpoint) + return model diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/__init__.py new file mode 100644 index 00000000..ce9ddac2 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/__init__.py @@ -0,0 +1,64 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from annotator.oneformer.detectron2.layers import ShapeSpec + +from .anchor_generator import build_anchor_generator, ANCHOR_GENERATOR_REGISTRY +from .backbone import ( + BACKBONE_REGISTRY, + FPN, + Backbone, + ResNet, + ResNetBlockBase, + build_backbone, + build_resnet_backbone, + make_stage, + ViT, + SimpleFeaturePyramid, + get_vit_lr_decay_rate, + MViT, + SwinTransformer, +) +from .meta_arch import ( + META_ARCH_REGISTRY, + SEM_SEG_HEADS_REGISTRY, + GeneralizedRCNN, + PanopticFPN, + ProposalNetwork, + RetinaNet, + SemanticSegmentor, + build_model, + build_sem_seg_head, + FCOS, +) +from .postprocessing import detector_postprocess +from .proposal_generator import ( + PROPOSAL_GENERATOR_REGISTRY, + build_proposal_generator, + RPN_HEAD_REGISTRY, + build_rpn_head, +) +from .roi_heads import ( + ROI_BOX_HEAD_REGISTRY, + ROI_HEADS_REGISTRY, + ROI_KEYPOINT_HEAD_REGISTRY, + ROI_MASK_HEAD_REGISTRY, + ROIHeads, + StandardROIHeads, + BaseMaskRCNNHead, + BaseKeypointRCNNHead, + FastRCNNOutputLayers, + build_box_head, + build_keypoint_head, + build_mask_head, + build_roi_heads, +) +from .test_time_augmentation import DatasetMapperTTA, GeneralizedRCNNWithTTA +from .mmdet_wrapper import MMDetBackbone, MMDetDetector + +_EXCLUDE = {"ShapeSpec"} +__all__ = [k for k in globals().keys() if k not in _EXCLUDE and not k.startswith("_")] + + +from annotator.oneformer.detectron2.utils.env import fixup_module_metadata + +fixup_module_metadata(__name__, globals(), __all__) +del fixup_module_metadata diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/anchor_generator.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/anchor_generator.py new file mode 100644 index 00000000..04127c4a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/anchor_generator.py @@ -0,0 +1,386 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import collections +import math +from typing import List +import torch +from torch import nn + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.layers import ShapeSpec, move_device_like +from annotator.oneformer.detectron2.structures import Boxes, RotatedBoxes +from annotator.oneformer.detectron2.utils.registry import Registry + +ANCHOR_GENERATOR_REGISTRY = Registry("ANCHOR_GENERATOR") +ANCHOR_GENERATOR_REGISTRY.__doc__ = """ +Registry for modules that creates object detection anchors for feature maps. + +The registered object will be called with `obj(cfg, input_shape)`. +""" + + +class BufferList(nn.Module): + """ + Similar to nn.ParameterList, but for buffers + """ + + def __init__(self, buffers): + super().__init__() + for i, buffer in enumerate(buffers): + # Use non-persistent buffer so the values are not saved in checkpoint + self.register_buffer(str(i), buffer, persistent=False) + + def __len__(self): + return len(self._buffers) + + def __iter__(self): + return iter(self._buffers.values()) + + +def _create_grid_offsets( + size: List[int], stride: int, offset: float, target_device_tensor: torch.Tensor +): + grid_height, grid_width = size + shifts_x = move_device_like( + torch.arange(offset * stride, grid_width * stride, step=stride, dtype=torch.float32), + target_device_tensor, + ) + shifts_y = move_device_like( + torch.arange(offset * stride, grid_height * stride, step=stride, dtype=torch.float32), + target_device_tensor, + ) + + shift_y, shift_x = torch.meshgrid(shifts_y, shifts_x) + shift_x = shift_x.reshape(-1) + shift_y = shift_y.reshape(-1) + return shift_x, shift_y + + +def _broadcast_params(params, num_features, name): + """ + If one size (or aspect ratio) is specified and there are multiple feature + maps, we "broadcast" anchors of that single size (or aspect ratio) + over all feature maps. + + If params is list[float], or list[list[float]] with len(params) == 1, repeat + it num_features time. + + Returns: + list[list[float]]: param for each feature + """ + assert isinstance( + params, collections.abc.Sequence + ), f"{name} in anchor generator has to be a list! Got {params}." + assert len(params), f"{name} in anchor generator cannot be empty!" + if not isinstance(params[0], collections.abc.Sequence): # params is list[float] + return [params] * num_features + if len(params) == 1: + return list(params) * num_features + assert len(params) == num_features, ( + f"Got {name} of length {len(params)} in anchor generator, " + f"but the number of input features is {num_features}!" + ) + return params + + +@ANCHOR_GENERATOR_REGISTRY.register() +class DefaultAnchorGenerator(nn.Module): + """ + Compute anchors in the standard ways described in + "Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks". + """ + + box_dim: torch.jit.Final[int] = 4 + """ + the dimension of each anchor box. + """ + + @configurable + def __init__(self, *, sizes, aspect_ratios, strides, offset=0.5): + """ + This interface is experimental. + + Args: + sizes (list[list[float]] or list[float]): + If ``sizes`` is list[list[float]], ``sizes[i]`` is the list of anchor sizes + (i.e. sqrt of anchor area) to use for the i-th feature map. + If ``sizes`` is list[float], ``sizes`` is used for all feature maps. + Anchor sizes are given in absolute lengths in units of + the input image; they do not dynamically scale if the input image size changes. + aspect_ratios (list[list[float]] or list[float]): list of aspect ratios + (i.e. height / width) to use for anchors. Same "broadcast" rule for `sizes` applies. + strides (list[int]): stride of each input feature. + offset (float): Relative offset between the center of the first anchor and the top-left + corner of the image. Value has to be in [0, 1). + Recommend to use 0.5, which means half stride. + """ + super().__init__() + + self.strides = strides + self.num_features = len(self.strides) + sizes = _broadcast_params(sizes, self.num_features, "sizes") + aspect_ratios = _broadcast_params(aspect_ratios, self.num_features, "aspect_ratios") + self.cell_anchors = self._calculate_anchors(sizes, aspect_ratios) + + self.offset = offset + assert 0.0 <= self.offset < 1.0, self.offset + + @classmethod + def from_config(cls, cfg, input_shape: List[ShapeSpec]): + return { + "sizes": cfg.MODEL.ANCHOR_GENERATOR.SIZES, + "aspect_ratios": cfg.MODEL.ANCHOR_GENERATOR.ASPECT_RATIOS, + "strides": [x.stride for x in input_shape], + "offset": cfg.MODEL.ANCHOR_GENERATOR.OFFSET, + } + + def _calculate_anchors(self, sizes, aspect_ratios): + cell_anchors = [ + self.generate_cell_anchors(s, a).float() for s, a in zip(sizes, aspect_ratios) + ] + return BufferList(cell_anchors) + + @property + @torch.jit.unused + def num_cell_anchors(self): + """ + Alias of `num_anchors`. + """ + return self.num_anchors + + @property + @torch.jit.unused + def num_anchors(self): + """ + Returns: + list[int]: Each int is the number of anchors at every pixel + location, on that feature map. + For example, if at every pixel we use anchors of 3 aspect + ratios and 5 sizes, the number of anchors is 15. + (See also ANCHOR_GENERATOR.SIZES and ANCHOR_GENERATOR.ASPECT_RATIOS in config) + + In standard RPN models, `num_anchors` on every feature map is the same. + """ + return [len(cell_anchors) for cell_anchors in self.cell_anchors] + + def _grid_anchors(self, grid_sizes: List[List[int]]): + """ + Returns: + list[Tensor]: #featuremap tensors, each is (#locations x #cell_anchors) x 4 + """ + anchors = [] + # buffers() not supported by torchscript. use named_buffers() instead + buffers: List[torch.Tensor] = [x[1] for x in self.cell_anchors.named_buffers()] + for size, stride, base_anchors in zip(grid_sizes, self.strides, buffers): + shift_x, shift_y = _create_grid_offsets(size, stride, self.offset, base_anchors) + shifts = torch.stack((shift_x, shift_y, shift_x, shift_y), dim=1) + + anchors.append((shifts.view(-1, 1, 4) + base_anchors.view(1, -1, 4)).reshape(-1, 4)) + + return anchors + + def generate_cell_anchors(self, sizes=(32, 64, 128, 256, 512), aspect_ratios=(0.5, 1, 2)): + """ + Generate a tensor storing canonical anchor boxes, which are all anchor + boxes of different sizes and aspect_ratios centered at (0, 0). + We can later build the set of anchors for a full feature map by + shifting and tiling these tensors (see `meth:_grid_anchors`). + + Args: + sizes (tuple[float]): + aspect_ratios (tuple[float]]): + + Returns: + Tensor of shape (len(sizes) * len(aspect_ratios), 4) storing anchor boxes + in XYXY format. + """ + + # This is different from the anchor generator defined in the original Faster R-CNN + # code or Detectron. They yield the same AP, however the old version defines cell + # anchors in a less natural way with a shift relative to the feature grid and + # quantization that results in slightly different sizes for different aspect ratios. + # See also https://github.com/facebookresearch/Detectron/issues/227 + + anchors = [] + for size in sizes: + area = size**2.0 + for aspect_ratio in aspect_ratios: + # s * s = w * h + # a = h / w + # ... some algebra ... + # w = sqrt(s * s / a) + # h = a * w + w = math.sqrt(area / aspect_ratio) + h = aspect_ratio * w + x0, y0, x1, y1 = -w / 2.0, -h / 2.0, w / 2.0, h / 2.0 + anchors.append([x0, y0, x1, y1]) + return torch.tensor(anchors) + + def forward(self, features: List[torch.Tensor]): + """ + Args: + features (list[Tensor]): list of backbone feature maps on which to generate anchors. + + Returns: + list[Boxes]: a list of Boxes containing all the anchors for each feature map + (i.e. the cell anchors repeated over all locations in the feature map). + The number of anchors of each feature map is Hi x Wi x num_cell_anchors, + where Hi, Wi are resolution of the feature map divided by anchor stride. + """ + grid_sizes = [feature_map.shape[-2:] for feature_map in features] + anchors_over_all_feature_maps = self._grid_anchors(grid_sizes) + return [Boxes(x) for x in anchors_over_all_feature_maps] + + +@ANCHOR_GENERATOR_REGISTRY.register() +class RotatedAnchorGenerator(nn.Module): + """ + Compute rotated anchors used by Rotated RPN (RRPN), described in + "Arbitrary-Oriented Scene Text Detection via Rotation Proposals". + """ + + box_dim: int = 5 + """ + the dimension of each anchor box. + """ + + @configurable + def __init__(self, *, sizes, aspect_ratios, strides, angles, offset=0.5): + """ + This interface is experimental. + + Args: + sizes (list[list[float]] or list[float]): + If sizes is list[list[float]], sizes[i] is the list of anchor sizes + (i.e. sqrt of anchor area) to use for the i-th feature map. + If sizes is list[float], the sizes are used for all feature maps. + Anchor sizes are given in absolute lengths in units of + the input image; they do not dynamically scale if the input image size changes. + aspect_ratios (list[list[float]] or list[float]): list of aspect ratios + (i.e. height / width) to use for anchors. Same "broadcast" rule for `sizes` applies. + strides (list[int]): stride of each input feature. + angles (list[list[float]] or list[float]): list of angles (in degrees CCW) + to use for anchors. Same "broadcast" rule for `sizes` applies. + offset (float): Relative offset between the center of the first anchor and the top-left + corner of the image. Value has to be in [0, 1). + Recommend to use 0.5, which means half stride. + """ + super().__init__() + + self.strides = strides + self.num_features = len(self.strides) + sizes = _broadcast_params(sizes, self.num_features, "sizes") + aspect_ratios = _broadcast_params(aspect_ratios, self.num_features, "aspect_ratios") + angles = _broadcast_params(angles, self.num_features, "angles") + self.cell_anchors = self._calculate_anchors(sizes, aspect_ratios, angles) + + self.offset = offset + assert 0.0 <= self.offset < 1.0, self.offset + + @classmethod + def from_config(cls, cfg, input_shape: List[ShapeSpec]): + return { + "sizes": cfg.MODEL.ANCHOR_GENERATOR.SIZES, + "aspect_ratios": cfg.MODEL.ANCHOR_GENERATOR.ASPECT_RATIOS, + "strides": [x.stride for x in input_shape], + "offset": cfg.MODEL.ANCHOR_GENERATOR.OFFSET, + "angles": cfg.MODEL.ANCHOR_GENERATOR.ANGLES, + } + + def _calculate_anchors(self, sizes, aspect_ratios, angles): + cell_anchors = [ + self.generate_cell_anchors(size, aspect_ratio, angle).float() + for size, aspect_ratio, angle in zip(sizes, aspect_ratios, angles) + ] + return BufferList(cell_anchors) + + @property + def num_cell_anchors(self): + """ + Alias of `num_anchors`. + """ + return self.num_anchors + + @property + def num_anchors(self): + """ + Returns: + list[int]: Each int is the number of anchors at every pixel + location, on that feature map. + For example, if at every pixel we use anchors of 3 aspect + ratios, 2 sizes and 5 angles, the number of anchors is 30. + (See also ANCHOR_GENERATOR.SIZES, ANCHOR_GENERATOR.ASPECT_RATIOS + and ANCHOR_GENERATOR.ANGLES in config) + + In standard RRPN models, `num_anchors` on every feature map is the same. + """ + return [len(cell_anchors) for cell_anchors in self.cell_anchors] + + def _grid_anchors(self, grid_sizes): + anchors = [] + for size, stride, base_anchors in zip(grid_sizes, self.strides, self.cell_anchors): + shift_x, shift_y = _create_grid_offsets(size, stride, self.offset, base_anchors) + zeros = torch.zeros_like(shift_x) + shifts = torch.stack((shift_x, shift_y, zeros, zeros, zeros), dim=1) + + anchors.append((shifts.view(-1, 1, 5) + base_anchors.view(1, -1, 5)).reshape(-1, 5)) + + return anchors + + def generate_cell_anchors( + self, + sizes=(32, 64, 128, 256, 512), + aspect_ratios=(0.5, 1, 2), + angles=(-90, -60, -30, 0, 30, 60, 90), + ): + """ + Generate a tensor storing canonical anchor boxes, which are all anchor + boxes of different sizes, aspect_ratios, angles centered at (0, 0). + We can later build the set of anchors for a full feature map by + shifting and tiling these tensors (see `meth:_grid_anchors`). + + Args: + sizes (tuple[float]): + aspect_ratios (tuple[float]]): + angles (tuple[float]]): + + Returns: + Tensor of shape (len(sizes) * len(aspect_ratios) * len(angles), 5) + storing anchor boxes in (x_ctr, y_ctr, w, h, angle) format. + """ + anchors = [] + for size in sizes: + area = size**2.0 + for aspect_ratio in aspect_ratios: + # s * s = w * h + # a = h / w + # ... some algebra ... + # w = sqrt(s * s / a) + # h = a * w + w = math.sqrt(area / aspect_ratio) + h = aspect_ratio * w + anchors.extend([0, 0, w, h, a] for a in angles) + + return torch.tensor(anchors) + + def forward(self, features): + """ + Args: + features (list[Tensor]): list of backbone feature maps on which to generate anchors. + + Returns: + list[RotatedBoxes]: a list of Boxes containing all the anchors for each feature map + (i.e. the cell anchors repeated over all locations in the feature map). + The number of anchors of each feature map is Hi x Wi x num_cell_anchors, + where Hi, Wi are resolution of the feature map divided by anchor stride. + """ + grid_sizes = [feature_map.shape[-2:] for feature_map in features] + anchors_over_all_feature_maps = self._grid_anchors(grid_sizes) + return [RotatedBoxes(x) for x in anchors_over_all_feature_maps] + + +def build_anchor_generator(cfg, input_shape): + """ + Built an anchor generator from `cfg.MODEL.ANCHOR_GENERATOR.NAME`. + """ + anchor_generator = cfg.MODEL.ANCHOR_GENERATOR.NAME + return ANCHOR_GENERATOR_REGISTRY.get(anchor_generator)(cfg, input_shape) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/__init__.py new file mode 100644 index 00000000..5b3358a4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/__init__.py @@ -0,0 +1,20 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from .build import build_backbone, BACKBONE_REGISTRY # noqa F401 isort:skip + +from .backbone import Backbone +from .fpn import FPN +from .regnet import RegNet +from .resnet import ( + BasicStem, + ResNet, + ResNetBlockBase, + build_resnet_backbone, + make_stage, + BottleneckBlock, +) +from .vit import ViT, SimpleFeaturePyramid, get_vit_lr_decay_rate +from .mvit import MViT +from .swin import SwinTransformer + +__all__ = [k for k in globals().keys() if not k.startswith("_")] +# TODO can expose more resnet blocks after careful consideration diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/backbone.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/backbone.py new file mode 100644 index 00000000..04f3c3c0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/backbone.py @@ -0,0 +1,74 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from abc import ABCMeta, abstractmethod +from typing import Dict +import torch.nn as nn + +from annotator.oneformer.detectron2.layers import ShapeSpec + +__all__ = ["Backbone"] + + +class Backbone(nn.Module, metaclass=ABCMeta): + """ + Abstract base class for network backbones. + """ + + def __init__(self): + """ + The `__init__` method of any subclass can specify its own set of arguments. + """ + super().__init__() + + @abstractmethod + def forward(self): + """ + Subclasses must override this method, but adhere to the same return type. + + Returns: + dict[str->Tensor]: mapping from feature name (e.g., "res2") to tensor + """ + pass + + @property + def size_divisibility(self) -> int: + """ + Some backbones require the input height and width to be divisible by a + specific integer. This is typically true for encoder / decoder type networks + with lateral connection (e.g., FPN) for which feature maps need to match + dimension in the "bottom up" and "top down" paths. Set to 0 if no specific + input size divisibility is required. + """ + return 0 + + @property + def padding_constraints(self) -> Dict[str, int]: + """ + This property is a generalization of size_divisibility. Some backbones and training + recipes require specific padding constraints, such as enforcing divisibility by a specific + integer (e.g., FPN) or padding to a square (e.g., ViTDet with large-scale jitter + in :paper:vitdet). `padding_constraints` contains these optional items like: + { + "size_divisibility": int, + "square_size": int, + # Future options are possible + } + `size_divisibility` will read from here if presented and `square_size` indicates the + square padding size if `square_size` > 0. + + TODO: use type of Dict[str, int] to avoid torchscipt issues. The type of padding_constraints + could be generalized as TypedDict (Python 3.8+) to support more types in the future. + """ + return {} + + def output_shape(self): + """ + Returns: + dict[str->ShapeSpec] + """ + # this is a backward-compatible default + return { + name: ShapeSpec( + channels=self._out_feature_channels[name], stride=self._out_feature_strides[name] + ) + for name in self._out_features + } diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/build.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/build.py new file mode 100644 index 00000000..63a4aace --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/build.py @@ -0,0 +1,33 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from annotator.oneformer.detectron2.layers import ShapeSpec +from annotator.oneformer.detectron2.utils.registry import Registry + +from .backbone import Backbone + +BACKBONE_REGISTRY = Registry("BACKBONE") +BACKBONE_REGISTRY.__doc__ = """ +Registry for backbones, which extract feature maps from images + +The registered object must be a callable that accepts two arguments: + +1. A :class:`detectron2.config.CfgNode` +2. A :class:`detectron2.layers.ShapeSpec`, which contains the input shape specification. + +Registered object must return instance of :class:`Backbone`. +""" + + +def build_backbone(cfg, input_shape=None): + """ + Build a backbone from `cfg.MODEL.BACKBONE.NAME`. + + Returns: + an instance of :class:`Backbone` + """ + if input_shape is None: + input_shape = ShapeSpec(channels=len(cfg.MODEL.PIXEL_MEAN)) + + backbone_name = cfg.MODEL.BACKBONE.NAME + backbone = BACKBONE_REGISTRY.get(backbone_name)(cfg, input_shape) + assert isinstance(backbone, Backbone) + return backbone diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/fpn.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/fpn.py new file mode 100644 index 00000000..a5a9e8ce --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/fpn.py @@ -0,0 +1,268 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import math +import fvcore.nn.weight_init as weight_init +import torch +import torch.nn.functional as F +from torch import nn + +from annotator.oneformer.detectron2.layers import Conv2d, ShapeSpec, get_norm + +from .backbone import Backbone +from .build import BACKBONE_REGISTRY +from .resnet import build_resnet_backbone + +__all__ = ["build_resnet_fpn_backbone", "build_retinanet_resnet_fpn_backbone", "FPN"] + + +class FPN(Backbone): + """ + This module implements :paper:`FPN`. + It creates pyramid features built on top of some input feature maps. + """ + + _fuse_type: torch.jit.Final[str] + + def __init__( + self, + bottom_up, + in_features, + out_channels, + norm="", + top_block=None, + fuse_type="sum", + square_pad=0, + ): + """ + Args: + bottom_up (Backbone): module representing the bottom up subnetwork. + Must be a subclass of :class:`Backbone`. The multi-scale feature + maps generated by the bottom up network, and listed in `in_features`, + are used to generate FPN levels. + in_features (list[str]): names of the input feature maps coming + from the backbone to which FPN is attached. For example, if the + backbone produces ["res2", "res3", "res4"], any *contiguous* sublist + of these may be used; order must be from high to low resolution. + out_channels (int): number of channels in the output feature maps. + norm (str): the normalization to use. + top_block (nn.Module or None): if provided, an extra operation will + be performed on the output of the last (smallest resolution) + FPN output, and the result will extend the result list. The top_block + further downsamples the feature map. It must have an attribute + "num_levels", meaning the number of extra FPN levels added by + this block, and "in_feature", which is a string representing + its input feature (e.g., p5). + fuse_type (str): types for fusing the top down features and the lateral + ones. It can be "sum" (default), which sums up element-wise; or "avg", + which takes the element-wise mean of the two. + square_pad (int): If > 0, require input images to be padded to specific square size. + """ + super(FPN, self).__init__() + assert isinstance(bottom_up, Backbone) + assert in_features, in_features + + # Feature map strides and channels from the bottom up network (e.g. ResNet) + input_shapes = bottom_up.output_shape() + strides = [input_shapes[f].stride for f in in_features] + in_channels_per_feature = [input_shapes[f].channels for f in in_features] + + _assert_strides_are_log2_contiguous(strides) + lateral_convs = [] + output_convs = [] + + use_bias = norm == "" + for idx, in_channels in enumerate(in_channels_per_feature): + lateral_norm = get_norm(norm, out_channels) + output_norm = get_norm(norm, out_channels) + + lateral_conv = Conv2d( + in_channels, out_channels, kernel_size=1, bias=use_bias, norm=lateral_norm + ) + output_conv = Conv2d( + out_channels, + out_channels, + kernel_size=3, + stride=1, + padding=1, + bias=use_bias, + norm=output_norm, + ) + weight_init.c2_xavier_fill(lateral_conv) + weight_init.c2_xavier_fill(output_conv) + stage = int(math.log2(strides[idx])) + self.add_module("fpn_lateral{}".format(stage), lateral_conv) + self.add_module("fpn_output{}".format(stage), output_conv) + + lateral_convs.append(lateral_conv) + output_convs.append(output_conv) + # Place convs into top-down order (from low to high resolution) + # to make the top-down computation in forward clearer. + self.lateral_convs = lateral_convs[::-1] + self.output_convs = output_convs[::-1] + self.top_block = top_block + self.in_features = tuple(in_features) + self.bottom_up = bottom_up + # Return feature names are "p", like ["p2", "p3", ..., "p6"] + self._out_feature_strides = {"p{}".format(int(math.log2(s))): s for s in strides} + # top block output feature maps. + if self.top_block is not None: + for s in range(stage, stage + self.top_block.num_levels): + self._out_feature_strides["p{}".format(s + 1)] = 2 ** (s + 1) + + self._out_features = list(self._out_feature_strides.keys()) + self._out_feature_channels = {k: out_channels for k in self._out_features} + self._size_divisibility = strides[-1] + self._square_pad = square_pad + assert fuse_type in {"avg", "sum"} + self._fuse_type = fuse_type + + @property + def size_divisibility(self): + return self._size_divisibility + + @property + def padding_constraints(self): + return {"square_size": self._square_pad} + + def forward(self, x): + """ + Args: + input (dict[str->Tensor]): mapping feature map name (e.g., "res5") to + feature map tensor for each feature level in high to low resolution order. + + Returns: + dict[str->Tensor]: + mapping from feature map name to FPN feature map tensor + in high to low resolution order. Returned feature names follow the FPN + paper convention: "p", where stage has stride = 2 ** stage e.g., + ["p2", "p3", ..., "p6"]. + """ + bottom_up_features = self.bottom_up(x) + results = [] + prev_features = self.lateral_convs[0](bottom_up_features[self.in_features[-1]]) + results.append(self.output_convs[0](prev_features)) + + # Reverse feature maps into top-down order (from low to high resolution) + for idx, (lateral_conv, output_conv) in enumerate( + zip(self.lateral_convs, self.output_convs) + ): + # Slicing of ModuleList is not supported https://github.com/pytorch/pytorch/issues/47336 + # Therefore we loop over all modules but skip the first one + if idx > 0: + features = self.in_features[-idx - 1] + features = bottom_up_features[features] + top_down_features = F.interpolate(prev_features, scale_factor=2.0, mode="nearest") + lateral_features = lateral_conv(features) + prev_features = lateral_features + top_down_features + if self._fuse_type == "avg": + prev_features /= 2 + results.insert(0, output_conv(prev_features)) + + if self.top_block is not None: + if self.top_block.in_feature in bottom_up_features: + top_block_in_feature = bottom_up_features[self.top_block.in_feature] + else: + top_block_in_feature = results[self._out_features.index(self.top_block.in_feature)] + results.extend(self.top_block(top_block_in_feature)) + assert len(self._out_features) == len(results) + return {f: res for f, res in zip(self._out_features, results)} + + def output_shape(self): + return { + name: ShapeSpec( + channels=self._out_feature_channels[name], stride=self._out_feature_strides[name] + ) + for name in self._out_features + } + + +def _assert_strides_are_log2_contiguous(strides): + """ + Assert that each stride is 2x times its preceding stride, i.e. "contiguous in log2". + """ + for i, stride in enumerate(strides[1:], 1): + assert stride == 2 * strides[i - 1], "Strides {} {} are not log2 contiguous".format( + stride, strides[i - 1] + ) + + +class LastLevelMaxPool(nn.Module): + """ + This module is used in the original FPN to generate a downsampled + P6 feature from P5. + """ + + def __init__(self): + super().__init__() + self.num_levels = 1 + self.in_feature = "p5" + + def forward(self, x): + return [F.max_pool2d(x, kernel_size=1, stride=2, padding=0)] + + +class LastLevelP6P7(nn.Module): + """ + This module is used in RetinaNet to generate extra layers, P6 and P7 from + C5 feature. + """ + + def __init__(self, in_channels, out_channels, in_feature="res5"): + super().__init__() + self.num_levels = 2 + self.in_feature = in_feature + self.p6 = nn.Conv2d(in_channels, out_channels, 3, 2, 1) + self.p7 = nn.Conv2d(out_channels, out_channels, 3, 2, 1) + for module in [self.p6, self.p7]: + weight_init.c2_xavier_fill(module) + + def forward(self, c5): + p6 = self.p6(c5) + p7 = self.p7(F.relu(p6)) + return [p6, p7] + + +@BACKBONE_REGISTRY.register() +def build_resnet_fpn_backbone(cfg, input_shape: ShapeSpec): + """ + Args: + cfg: a detectron2 CfgNode + + Returns: + backbone (Backbone): backbone module, must be a subclass of :class:`Backbone`. + """ + bottom_up = build_resnet_backbone(cfg, input_shape) + in_features = cfg.MODEL.FPN.IN_FEATURES + out_channels = cfg.MODEL.FPN.OUT_CHANNELS + backbone = FPN( + bottom_up=bottom_up, + in_features=in_features, + out_channels=out_channels, + norm=cfg.MODEL.FPN.NORM, + top_block=LastLevelMaxPool(), + fuse_type=cfg.MODEL.FPN.FUSE_TYPE, + ) + return backbone + + +@BACKBONE_REGISTRY.register() +def build_retinanet_resnet_fpn_backbone(cfg, input_shape: ShapeSpec): + """ + Args: + cfg: a detectron2 CfgNode + + Returns: + backbone (Backbone): backbone module, must be a subclass of :class:`Backbone`. + """ + bottom_up = build_resnet_backbone(cfg, input_shape) + in_features = cfg.MODEL.FPN.IN_FEATURES + out_channels = cfg.MODEL.FPN.OUT_CHANNELS + in_channels_p6p7 = bottom_up.output_shape()["res5"].channels + backbone = FPN( + bottom_up=bottom_up, + in_features=in_features, + out_channels=out_channels, + norm=cfg.MODEL.FPN.NORM, + top_block=LastLevelP6P7(in_channels_p6p7, out_channels), + fuse_type=cfg.MODEL.FPN.FUSE_TYPE, + ) + return backbone diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/mvit.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/mvit.py new file mode 100644 index 00000000..50667a8a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/mvit.py @@ -0,0 +1,448 @@ +import logging +import numpy as np +import torch +import torch.nn as nn + +from .backbone import Backbone +from .utils import ( + PatchEmbed, + add_decomposed_rel_pos, + get_abs_pos, + window_partition, + window_unpartition, +) + +logger = logging.getLogger(__name__) + + +__all__ = ["MViT"] + + +def attention_pool(x, pool, norm=None): + # (B, H, W, C) -> (B, C, H, W) + x = x.permute(0, 3, 1, 2) + x = pool(x) + # (B, C, H1, W1) -> (B, H1, W1, C) + x = x.permute(0, 2, 3, 1) + if norm: + x = norm(x) + + return x + + +class MultiScaleAttention(nn.Module): + """Multiscale Multi-head Attention block.""" + + def __init__( + self, + dim, + dim_out, + num_heads, + qkv_bias=True, + norm_layer=nn.LayerNorm, + pool_kernel=(3, 3), + stride_q=1, + stride_kv=1, + residual_pooling=True, + window_size=0, + use_rel_pos=False, + rel_pos_zero_init=True, + input_size=None, + ): + """ + Args: + dim (int): Number of input channels. + dim_out (int): Number of output channels. + num_heads (int): Number of attention heads. + qkv_bias (bool: If True, add a learnable bias to query, key, value. + norm_layer (nn.Module): Normalization layer. + pool_kernel (tuple): kernel size for qkv pooling layers. + stride_q (int): stride size for q pooling layer. + stride_kv (int): stride size for kv pooling layer. + residual_pooling (bool): If true, enable residual pooling. + use_rel_pos (bool): If True, add relative postional embeddings to the attention map. + rel_pos_zero_init (bool): If True, zero initialize relative positional parameters. + input_size (int or None): Input resolution. + """ + super().__init__() + self.num_heads = num_heads + head_dim = dim_out // num_heads + self.scale = head_dim**-0.5 + + self.qkv = nn.Linear(dim, dim_out * 3, bias=qkv_bias) + self.proj = nn.Linear(dim_out, dim_out) + + # qkv pooling + pool_padding = [k // 2 for k in pool_kernel] + dim_conv = dim_out // num_heads + self.pool_q = nn.Conv2d( + dim_conv, + dim_conv, + pool_kernel, + stride=stride_q, + padding=pool_padding, + groups=dim_conv, + bias=False, + ) + self.norm_q = norm_layer(dim_conv) + self.pool_k = nn.Conv2d( + dim_conv, + dim_conv, + pool_kernel, + stride=stride_kv, + padding=pool_padding, + groups=dim_conv, + bias=False, + ) + self.norm_k = norm_layer(dim_conv) + self.pool_v = nn.Conv2d( + dim_conv, + dim_conv, + pool_kernel, + stride=stride_kv, + padding=pool_padding, + groups=dim_conv, + bias=False, + ) + self.norm_v = norm_layer(dim_conv) + + self.window_size = window_size + if window_size: + self.q_win_size = window_size // stride_q + self.kv_win_size = window_size // stride_kv + self.residual_pooling = residual_pooling + + self.use_rel_pos = use_rel_pos + if self.use_rel_pos: + # initialize relative positional embeddings + assert input_size[0] == input_size[1] + size = input_size[0] + rel_dim = 2 * max(size // stride_q, size // stride_kv) - 1 + self.rel_pos_h = nn.Parameter(torch.zeros(rel_dim, head_dim)) + self.rel_pos_w = nn.Parameter(torch.zeros(rel_dim, head_dim)) + + if not rel_pos_zero_init: + nn.init.trunc_normal_(self.rel_pos_h, std=0.02) + nn.init.trunc_normal_(self.rel_pos_w, std=0.02) + + def forward(self, x): + B, H, W, _ = x.shape + # qkv with shape (3, B, nHead, H, W, C) + qkv = self.qkv(x).reshape(B, H, W, 3, self.num_heads, -1).permute(3, 0, 4, 1, 2, 5) + # q, k, v with shape (B * nHead, H, W, C) + q, k, v = qkv.reshape(3, B * self.num_heads, H, W, -1).unbind(0) + + q = attention_pool(q, self.pool_q, self.norm_q) + k = attention_pool(k, self.pool_k, self.norm_k) + v = attention_pool(v, self.pool_v, self.norm_v) + + ori_q = q + if self.window_size: + q, q_hw_pad = window_partition(q, self.q_win_size) + k, kv_hw_pad = window_partition(k, self.kv_win_size) + v, _ = window_partition(v, self.kv_win_size) + q_hw = (self.q_win_size, self.q_win_size) + kv_hw = (self.kv_win_size, self.kv_win_size) + else: + q_hw = q.shape[1:3] + kv_hw = k.shape[1:3] + + q = q.view(q.shape[0], np.prod(q_hw), -1) + k = k.view(k.shape[0], np.prod(kv_hw), -1) + v = v.view(v.shape[0], np.prod(kv_hw), -1) + + attn = (q * self.scale) @ k.transpose(-2, -1) + + if self.use_rel_pos: + attn = add_decomposed_rel_pos(attn, q, self.rel_pos_h, self.rel_pos_w, q_hw, kv_hw) + + attn = attn.softmax(dim=-1) + x = attn @ v + + x = x.view(x.shape[0], q_hw[0], q_hw[1], -1) + + if self.window_size: + x = window_unpartition(x, self.q_win_size, q_hw_pad, ori_q.shape[1:3]) + + if self.residual_pooling: + x += ori_q + + H, W = x.shape[1], x.shape[2] + x = x.view(B, self.num_heads, H, W, -1).permute(0, 2, 3, 1, 4).reshape(B, H, W, -1) + x = self.proj(x) + + return x + + +class MultiScaleBlock(nn.Module): + """Multiscale Transformer blocks""" + + def __init__( + self, + dim, + dim_out, + num_heads, + mlp_ratio=4.0, + qkv_bias=True, + drop_path=0.0, + norm_layer=nn.LayerNorm, + act_layer=nn.GELU, + qkv_pool_kernel=(3, 3), + stride_q=1, + stride_kv=1, + residual_pooling=True, + window_size=0, + use_rel_pos=False, + rel_pos_zero_init=True, + input_size=None, + ): + """ + Args: + dim (int): Number of input channels. + dim_out (int): Number of output channels. + num_heads (int): Number of attention heads in the MViT block. + mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. + qkv_bias (bool): If True, add a learnable bias to query, key, value. + drop_path (float): Stochastic depth rate. + norm_layer (nn.Module): Normalization layer. + act_layer (nn.Module): Activation layer. + qkv_pool_kernel (tuple): kernel size for qkv pooling layers. + stride_q (int): stride size for q pooling layer. + stride_kv (int): stride size for kv pooling layer. + residual_pooling (bool): If true, enable residual pooling. + window_size (int): Window size for window attention blocks. If it equals 0, then not + use window attention. + use_rel_pos (bool): If True, add relative postional embeddings to the attention map. + rel_pos_zero_init (bool): If True, zero initialize relative positional parameters. + input_size (int or None): Input resolution. + """ + super().__init__() + self.norm1 = norm_layer(dim) + self.attn = MultiScaleAttention( + dim, + dim_out, + num_heads=num_heads, + qkv_bias=qkv_bias, + norm_layer=norm_layer, + pool_kernel=qkv_pool_kernel, + stride_q=stride_q, + stride_kv=stride_kv, + residual_pooling=residual_pooling, + window_size=window_size, + use_rel_pos=use_rel_pos, + rel_pos_zero_init=rel_pos_zero_init, + input_size=input_size, + ) + + from timm.models.layers import DropPath, Mlp + + self.drop_path = DropPath(drop_path) if drop_path > 0.0 else nn.Identity() + self.norm2 = norm_layer(dim_out) + self.mlp = Mlp( + in_features=dim_out, + hidden_features=int(dim_out * mlp_ratio), + out_features=dim_out, + act_layer=act_layer, + ) + + if dim != dim_out: + self.proj = nn.Linear(dim, dim_out) + + if stride_q > 1: + kernel_skip = stride_q + 1 + padding_skip = int(kernel_skip // 2) + self.pool_skip = nn.MaxPool2d(kernel_skip, stride_q, padding_skip, ceil_mode=False) + + def forward(self, x): + x_norm = self.norm1(x) + x_block = self.attn(x_norm) + + if hasattr(self, "proj"): + x = self.proj(x_norm) + if hasattr(self, "pool_skip"): + x = attention_pool(x, self.pool_skip) + + x = x + self.drop_path(x_block) + x = x + self.drop_path(self.mlp(self.norm2(x))) + + return x + + +class MViT(Backbone): + """ + This module implements Multiscale Vision Transformer (MViT) backbone in :paper:'mvitv2'. + """ + + def __init__( + self, + img_size=224, + patch_kernel=(7, 7), + patch_stride=(4, 4), + patch_padding=(3, 3), + in_chans=3, + embed_dim=96, + depth=16, + num_heads=1, + last_block_indexes=(0, 2, 11, 15), + qkv_pool_kernel=(3, 3), + adaptive_kv_stride=4, + adaptive_window_size=56, + residual_pooling=True, + mlp_ratio=4.0, + qkv_bias=True, + drop_path_rate=0.0, + norm_layer=nn.LayerNorm, + act_layer=nn.GELU, + use_abs_pos=False, + use_rel_pos=True, + rel_pos_zero_init=True, + use_act_checkpoint=False, + pretrain_img_size=224, + pretrain_use_cls_token=True, + out_features=("scale2", "scale3", "scale4", "scale5"), + ): + """ + Args: + img_size (int): Input image size. + patch_kernel (tuple): kernel size for patch embedding. + patch_stride (tuple): stride size for patch embedding. + patch_padding (tuple): padding size for patch embedding. + in_chans (int): Number of input image channels. + embed_dim (int): Patch embedding dimension. + depth (int): Depth of MViT. + num_heads (int): Number of base attention heads in each MViT block. + last_block_indexes (tuple): Block indexes for last blocks in each stage. + qkv_pool_kernel (tuple): kernel size for qkv pooling layers. + adaptive_kv_stride (int): adaptive stride size for kv pooling. + adaptive_window_size (int): adaptive window size for window attention blocks. + residual_pooling (bool): If true, enable residual pooling. + mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. + qkv_bias (bool): If True, add a learnable bias to query, key, value. + drop_path_rate (float): Stochastic depth rate. + norm_layer (nn.Module): Normalization layer. + act_layer (nn.Module): Activation layer. + use_abs_pos (bool): If True, use absolute positional embeddings. + use_rel_pos (bool): If True, add relative postional embeddings to the attention map. + rel_pos_zero_init (bool): If True, zero initialize relative positional parameters. + window_size (int): Window size for window attention blocks. + use_act_checkpoint (bool): If True, use activation checkpointing. + pretrain_img_size (int): input image size for pretraining models. + pretrain_use_cls_token (bool): If True, pretrainig models use class token. + out_features (tuple): name of the feature maps from each stage. + """ + super().__init__() + self.pretrain_use_cls_token = pretrain_use_cls_token + + self.patch_embed = PatchEmbed( + kernel_size=patch_kernel, + stride=patch_stride, + padding=patch_padding, + in_chans=in_chans, + embed_dim=embed_dim, + ) + + if use_abs_pos: + # Initialize absoluate positional embedding with pretrain image size. + num_patches = (pretrain_img_size // patch_stride[0]) * ( + pretrain_img_size // patch_stride[1] + ) + num_positions = (num_patches + 1) if pretrain_use_cls_token else num_patches + self.pos_embed = nn.Parameter(torch.zeros(1, num_positions, embed_dim)) + else: + self.pos_embed = None + + # stochastic depth decay rule + dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)] + dim_out = embed_dim + stride_kv = adaptive_kv_stride + window_size = adaptive_window_size + input_size = (img_size // patch_stride[0], img_size // patch_stride[1]) + stage = 2 + stride = patch_stride[0] + self._out_feature_strides = {} + self._out_feature_channels = {} + self.blocks = nn.ModuleList() + for i in range(depth): + # Multiply stride_kv by 2 if it's the last block of stage2 and stage3. + if i == last_block_indexes[1] or i == last_block_indexes[2]: + stride_kv_ = stride_kv * 2 + else: + stride_kv_ = stride_kv + # hybrid window attention: global attention in last three stages. + window_size_ = 0 if i in last_block_indexes[1:] else window_size + block = MultiScaleBlock( + dim=embed_dim, + dim_out=dim_out, + num_heads=num_heads, + mlp_ratio=mlp_ratio, + qkv_bias=qkv_bias, + drop_path=dpr[i], + norm_layer=norm_layer, + qkv_pool_kernel=qkv_pool_kernel, + stride_q=2 if i - 1 in last_block_indexes else 1, + stride_kv=stride_kv_, + residual_pooling=residual_pooling, + window_size=window_size_, + use_rel_pos=use_rel_pos, + rel_pos_zero_init=rel_pos_zero_init, + input_size=input_size, + ) + if use_act_checkpoint: + # TODO: use torch.utils.checkpoint + from fairscale.nn.checkpoint import checkpoint_wrapper + + block = checkpoint_wrapper(block) + self.blocks.append(block) + + embed_dim = dim_out + if i in last_block_indexes: + name = f"scale{stage}" + if name in out_features: + self._out_feature_channels[name] = dim_out + self._out_feature_strides[name] = stride + self.add_module(f"{name}_norm", norm_layer(dim_out)) + + dim_out *= 2 + num_heads *= 2 + stride_kv = max(stride_kv // 2, 1) + stride *= 2 + stage += 1 + if i - 1 in last_block_indexes: + window_size = window_size // 2 + input_size = [s // 2 for s in input_size] + + self._out_features = out_features + self._last_block_indexes = last_block_indexes + + if self.pos_embed is not None: + nn.init.trunc_normal_(self.pos_embed, std=0.02) + + self.apply(self._init_weights) + + def _init_weights(self, m): + if isinstance(m, nn.Linear): + nn.init.trunc_normal_(m.weight, std=0.02) + if isinstance(m, nn.Linear) and m.bias is not None: + nn.init.constant_(m.bias, 0) + elif isinstance(m, nn.LayerNorm): + nn.init.constant_(m.bias, 0) + nn.init.constant_(m.weight, 1.0) + + def forward(self, x): + x = self.patch_embed(x) + + if self.pos_embed is not None: + x = x + get_abs_pos(self.pos_embed, self.pretrain_use_cls_token, x.shape[1:3]) + + outputs = {} + stage = 2 + for i, blk in enumerate(self.blocks): + x = blk(x) + if i in self._last_block_indexes: + name = f"scale{stage}" + if name in self._out_features: + x_out = getattr(self, f"{name}_norm")(x) + outputs[name] = x_out.permute(0, 3, 1, 2) + stage += 1 + + return outputs diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/regnet.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/regnet.py new file mode 100644 index 00000000..a9d5b1c8 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/regnet.py @@ -0,0 +1,452 @@ +# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved +""" +Implementation of RegNet models from :paper:`dds` and :paper:`scaling`. + +This code is adapted from https://github.com/facebookresearch/pycls with minimal modifications. +Some code duplication exists between RegNet and ResNets (e.g., ResStem) in order to simplify +model loading. +""" + +import numpy as np +from torch import nn + +from annotator.oneformer.detectron2.layers import CNNBlockBase, ShapeSpec, get_norm + +from .backbone import Backbone + +__all__ = [ + "AnyNet", + "RegNet", + "ResStem", + "SimpleStem", + "VanillaBlock", + "ResBasicBlock", + "ResBottleneckBlock", +] + + +def conv2d(w_in, w_out, k, *, stride=1, groups=1, bias=False): + """Helper for building a conv2d layer.""" + assert k % 2 == 1, "Only odd size kernels supported to avoid padding issues." + s, p, g, b = stride, (k - 1) // 2, groups, bias + return nn.Conv2d(w_in, w_out, k, stride=s, padding=p, groups=g, bias=b) + + +def gap2d(): + """Helper for building a global average pooling layer.""" + return nn.AdaptiveAvgPool2d((1, 1)) + + +def pool2d(k, *, stride=1): + """Helper for building a pool2d layer.""" + assert k % 2 == 1, "Only odd size kernels supported to avoid padding issues." + return nn.MaxPool2d(k, stride=stride, padding=(k - 1) // 2) + + +def init_weights(m): + """Performs ResNet-style weight initialization.""" + if isinstance(m, nn.Conv2d): + # Note that there is no bias due to BN + fan_out = m.kernel_size[0] * m.kernel_size[1] * m.out_channels + m.weight.data.normal_(mean=0.0, std=np.sqrt(2.0 / fan_out)) + elif isinstance(m, nn.BatchNorm2d): + m.weight.data.fill_(1.0) + m.bias.data.zero_() + elif isinstance(m, nn.Linear): + m.weight.data.normal_(mean=0.0, std=0.01) + m.bias.data.zero_() + + +class ResStem(CNNBlockBase): + """ResNet stem for ImageNet: 7x7, BN, AF, MaxPool.""" + + def __init__(self, w_in, w_out, norm, activation_class): + super().__init__(w_in, w_out, 4) + self.conv = conv2d(w_in, w_out, 7, stride=2) + self.bn = get_norm(norm, w_out) + self.af = activation_class() + self.pool = pool2d(3, stride=2) + + def forward(self, x): + for layer in self.children(): + x = layer(x) + return x + + +class SimpleStem(CNNBlockBase): + """Simple stem for ImageNet: 3x3, BN, AF.""" + + def __init__(self, w_in, w_out, norm, activation_class): + super().__init__(w_in, w_out, 2) + self.conv = conv2d(w_in, w_out, 3, stride=2) + self.bn = get_norm(norm, w_out) + self.af = activation_class() + + def forward(self, x): + for layer in self.children(): + x = layer(x) + return x + + +class SE(nn.Module): + """Squeeze-and-Excitation (SE) block: AvgPool, FC, Act, FC, Sigmoid.""" + + def __init__(self, w_in, w_se, activation_class): + super().__init__() + self.avg_pool = gap2d() + self.f_ex = nn.Sequential( + conv2d(w_in, w_se, 1, bias=True), + activation_class(), + conv2d(w_se, w_in, 1, bias=True), + nn.Sigmoid(), + ) + + def forward(self, x): + return x * self.f_ex(self.avg_pool(x)) + + +class VanillaBlock(CNNBlockBase): + """Vanilla block: [3x3 conv, BN, Relu] x2.""" + + def __init__(self, w_in, w_out, stride, norm, activation_class, _params): + super().__init__(w_in, w_out, stride) + self.a = conv2d(w_in, w_out, 3, stride=stride) + self.a_bn = get_norm(norm, w_out) + self.a_af = activation_class() + self.b = conv2d(w_out, w_out, 3) + self.b_bn = get_norm(norm, w_out) + self.b_af = activation_class() + + def forward(self, x): + for layer in self.children(): + x = layer(x) + return x + + +class BasicTransform(nn.Module): + """Basic transformation: [3x3 conv, BN, Relu] x2.""" + + def __init__(self, w_in, w_out, stride, norm, activation_class, _params): + super().__init__() + self.a = conv2d(w_in, w_out, 3, stride=stride) + self.a_bn = get_norm(norm, w_out) + self.a_af = activation_class() + self.b = conv2d(w_out, w_out, 3) + self.b_bn = get_norm(norm, w_out) + self.b_bn.final_bn = True + + def forward(self, x): + for layer in self.children(): + x = layer(x) + return x + + +class ResBasicBlock(CNNBlockBase): + """Residual basic block: x + f(x), f = basic transform.""" + + def __init__(self, w_in, w_out, stride, norm, activation_class, params): + super().__init__(w_in, w_out, stride) + self.proj, self.bn = None, None + if (w_in != w_out) or (stride != 1): + self.proj = conv2d(w_in, w_out, 1, stride=stride) + self.bn = get_norm(norm, w_out) + self.f = BasicTransform(w_in, w_out, stride, norm, activation_class, params) + self.af = activation_class() + + def forward(self, x): + x_p = self.bn(self.proj(x)) if self.proj else x + return self.af(x_p + self.f(x)) + + +class BottleneckTransform(nn.Module): + """Bottleneck transformation: 1x1, 3x3 [+SE], 1x1.""" + + def __init__(self, w_in, w_out, stride, norm, activation_class, params): + super().__init__() + w_b = int(round(w_out * params["bot_mul"])) + w_se = int(round(w_in * params["se_r"])) + groups = w_b // params["group_w"] + self.a = conv2d(w_in, w_b, 1) + self.a_bn = get_norm(norm, w_b) + self.a_af = activation_class() + self.b = conv2d(w_b, w_b, 3, stride=stride, groups=groups) + self.b_bn = get_norm(norm, w_b) + self.b_af = activation_class() + self.se = SE(w_b, w_se, activation_class) if w_se else None + self.c = conv2d(w_b, w_out, 1) + self.c_bn = get_norm(norm, w_out) + self.c_bn.final_bn = True + + def forward(self, x): + for layer in self.children(): + x = layer(x) + return x + + +class ResBottleneckBlock(CNNBlockBase): + """Residual bottleneck block: x + f(x), f = bottleneck transform.""" + + def __init__(self, w_in, w_out, stride, norm, activation_class, params): + super().__init__(w_in, w_out, stride) + self.proj, self.bn = None, None + if (w_in != w_out) or (stride != 1): + self.proj = conv2d(w_in, w_out, 1, stride=stride) + self.bn = get_norm(norm, w_out) + self.f = BottleneckTransform(w_in, w_out, stride, norm, activation_class, params) + self.af = activation_class() + + def forward(self, x): + x_p = self.bn(self.proj(x)) if self.proj else x + return self.af(x_p + self.f(x)) + + +class AnyStage(nn.Module): + """AnyNet stage (sequence of blocks w/ the same output shape).""" + + def __init__(self, w_in, w_out, stride, d, block_class, norm, activation_class, params): + super().__init__() + for i in range(d): + block = block_class(w_in, w_out, stride, norm, activation_class, params) + self.add_module("b{}".format(i + 1), block) + stride, w_in = 1, w_out + + def forward(self, x): + for block in self.children(): + x = block(x) + return x + + +class AnyNet(Backbone): + """AnyNet model. See :paper:`dds`.""" + + def __init__( + self, + *, + stem_class, + stem_width, + block_class, + depths, + widths, + group_widths, + strides, + bottleneck_ratios, + se_ratio, + activation_class, + freeze_at=0, + norm="BN", + out_features=None, + ): + """ + Args: + stem_class (callable): A callable taking 4 arguments (channels in, channels out, + normalization, callable returning an activation function) that returns another + callable implementing the stem module. + stem_width (int): The number of output channels that the stem produces. + block_class (callable): A callable taking 6 arguments (channels in, channels out, + stride, normalization, callable returning an activation function, a dict of + block-specific parameters) that returns another callable implementing the repeated + block module. + depths (list[int]): Number of blocks in each stage. + widths (list[int]): For each stage, the number of output channels of each block. + group_widths (list[int]): For each stage, the number of channels per group in group + convolution, if the block uses group convolution. + strides (list[int]): The stride that each network stage applies to its input. + bottleneck_ratios (list[float]): For each stage, the ratio of the number of bottleneck + channels to the number of block input channels (or, equivalently, output channels), + if the block uses a bottleneck. + se_ratio (float): The ratio of the number of channels used inside the squeeze-excitation + (SE) module to it number of input channels, if SE the block uses SE. + activation_class (callable): A callable taking no arguments that returns another + callable implementing an activation function. + freeze_at (int): The number of stages at the beginning to freeze. + see :meth:`freeze` for detailed explanation. + norm (str or callable): normalization for all conv layers. + See :func:`layers.get_norm` for supported format. + out_features (list[str]): name of the layers whose outputs should + be returned in forward. RegNet's use "stem" and "s1", "s2", etc for the stages after + the stem. If None, will return the output of the last layer. + """ + super().__init__() + self.stem = stem_class(3, stem_width, norm, activation_class) + + current_stride = self.stem.stride + self._out_feature_strides = {"stem": current_stride} + self._out_feature_channels = {"stem": self.stem.out_channels} + self.stages_and_names = [] + prev_w = stem_width + + for i, (d, w, s, b, g) in enumerate( + zip(depths, widths, strides, bottleneck_ratios, group_widths) + ): + params = {"bot_mul": b, "group_w": g, "se_r": se_ratio} + stage = AnyStage(prev_w, w, s, d, block_class, norm, activation_class, params) + name = "s{}".format(i + 1) + self.add_module(name, stage) + self.stages_and_names.append((stage, name)) + self._out_feature_strides[name] = current_stride = int( + current_stride * np.prod([k.stride for k in stage.children()]) + ) + self._out_feature_channels[name] = list(stage.children())[-1].out_channels + prev_w = w + + self.apply(init_weights) + + if out_features is None: + out_features = [name] + self._out_features = out_features + assert len(self._out_features) + children = [x[0] for x in self.named_children()] + for out_feature in self._out_features: + assert out_feature in children, "Available children: {} does not include {}".format( + ", ".join(children), out_feature + ) + self.freeze(freeze_at) + + def forward(self, x): + """ + Args: + x: Tensor of shape (N,C,H,W). H, W must be a multiple of ``self.size_divisibility``. + + Returns: + dict[str->Tensor]: names and the corresponding features + """ + assert x.dim() == 4, f"Model takes an input of shape (N, C, H, W). Got {x.shape} instead!" + outputs = {} + x = self.stem(x) + if "stem" in self._out_features: + outputs["stem"] = x + for stage, name in self.stages_and_names: + x = stage(x) + if name in self._out_features: + outputs[name] = x + return outputs + + def output_shape(self): + return { + name: ShapeSpec( + channels=self._out_feature_channels[name], stride=self._out_feature_strides[name] + ) + for name in self._out_features + } + + def freeze(self, freeze_at=0): + """ + Freeze the first several stages of the model. Commonly used in fine-tuning. + + Layers that produce the same feature map spatial size are defined as one + "stage" by :paper:`FPN`. + + Args: + freeze_at (int): number of stages to freeze. + `1` means freezing the stem. `2` means freezing the stem and + one residual stage, etc. + + Returns: + nn.Module: this model itself + """ + if freeze_at >= 1: + self.stem.freeze() + for idx, (stage, _) in enumerate(self.stages_and_names, start=2): + if freeze_at >= idx: + for block in stage.children(): + block.freeze() + return self + + +def adjust_block_compatibility(ws, bs, gs): + """Adjusts the compatibility of widths, bottlenecks, and groups.""" + assert len(ws) == len(bs) == len(gs) + assert all(w > 0 and b > 0 and g > 0 for w, b, g in zip(ws, bs, gs)) + vs = [int(max(1, w * b)) for w, b in zip(ws, bs)] + gs = [int(min(g, v)) for g, v in zip(gs, vs)] + ms = [np.lcm(g, b) if b > 1 else g for g, b in zip(gs, bs)] + vs = [max(m, int(round(v / m) * m)) for v, m in zip(vs, ms)] + ws = [int(v / b) for v, b in zip(vs, bs)] + assert all(w * b % g == 0 for w, b, g in zip(ws, bs, gs)) + return ws, bs, gs + + +def generate_regnet_parameters(w_a, w_0, w_m, d, q=8): + """Generates per stage widths and depths from RegNet parameters.""" + assert w_a >= 0 and w_0 > 0 and w_m > 1 and w_0 % q == 0 + # Generate continuous per-block ws + ws_cont = np.arange(d) * w_a + w_0 + # Generate quantized per-block ws + ks = np.round(np.log(ws_cont / w_0) / np.log(w_m)) + ws_all = w_0 * np.power(w_m, ks) + ws_all = np.round(np.divide(ws_all, q)).astype(int) * q + # Generate per stage ws and ds (assumes ws_all are sorted) + ws, ds = np.unique(ws_all, return_counts=True) + # Compute number of actual stages and total possible stages + num_stages, total_stages = len(ws), ks.max() + 1 + # Convert numpy arrays to lists and return + ws, ds, ws_all, ws_cont = (x.tolist() for x in (ws, ds, ws_all, ws_cont)) + return ws, ds, num_stages, total_stages, ws_all, ws_cont + + +class RegNet(AnyNet): + """RegNet model. See :paper:`dds`.""" + + def __init__( + self, + *, + stem_class, + stem_width, + block_class, + depth, + w_a, + w_0, + w_m, + group_width, + stride=2, + bottleneck_ratio=1.0, + se_ratio=0.0, + activation_class=None, + freeze_at=0, + norm="BN", + out_features=None, + ): + """ + Build a RegNet from the parameterization described in :paper:`dds` Section 3.3. + + Args: + See :class:`AnyNet` for arguments that are not listed here. + depth (int): Total number of blocks in the RegNet. + w_a (float): Factor by which block width would increase prior to quantizing block widths + by stage. See :paper:`dds` Section 3.3. + w_0 (int): Initial block width. See :paper:`dds` Section 3.3. + w_m (float): Parameter controlling block width quantization. + See :paper:`dds` Section 3.3. + group_width (int): Number of channels per group in group convolution, if the block uses + group convolution. + bottleneck_ratio (float): The ratio of the number of bottleneck channels to the number + of block input channels (or, equivalently, output channels), if the block uses a + bottleneck. + stride (int): The stride that each network stage applies to its input. + """ + ws, ds = generate_regnet_parameters(w_a, w_0, w_m, depth)[0:2] + ss = [stride for _ in ws] + bs = [bottleneck_ratio for _ in ws] + gs = [group_width for _ in ws] + ws, bs, gs = adjust_block_compatibility(ws, bs, gs) + + def default_activation_class(): + return nn.ReLU(inplace=True) + + super().__init__( + stem_class=stem_class, + stem_width=stem_width, + block_class=block_class, + depths=ds, + widths=ws, + strides=ss, + group_widths=gs, + bottleneck_ratios=bs, + se_ratio=se_ratio, + activation_class=default_activation_class + if activation_class is None + else activation_class, + freeze_at=freeze_at, + norm=norm, + out_features=out_features, + ) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/resnet.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/resnet.py new file mode 100644 index 00000000..34d6edf2 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/resnet.py @@ -0,0 +1,694 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import numpy as np +import fvcore.nn.weight_init as weight_init +import torch +import torch.nn.functional as F +from torch import nn + +from annotator.oneformer.detectron2.layers import ( + CNNBlockBase, + Conv2d, + DeformConv, + ModulatedDeformConv, + ShapeSpec, + get_norm, +) + +from .backbone import Backbone +from .build import BACKBONE_REGISTRY + +__all__ = [ + "ResNetBlockBase", + "BasicBlock", + "BottleneckBlock", + "DeformBottleneckBlock", + "BasicStem", + "ResNet", + "make_stage", + "build_resnet_backbone", +] + + +class BasicBlock(CNNBlockBase): + """ + The basic residual block for ResNet-18 and ResNet-34 defined in :paper:`ResNet`, + with two 3x3 conv layers and a projection shortcut if needed. + """ + + def __init__(self, in_channels, out_channels, *, stride=1, norm="BN"): + """ + Args: + in_channels (int): Number of input channels. + out_channels (int): Number of output channels. + stride (int): Stride for the first conv. + norm (str or callable): normalization for all conv layers. + See :func:`layers.get_norm` for supported format. + """ + super().__init__(in_channels, out_channels, stride) + + if in_channels != out_channels: + self.shortcut = Conv2d( + in_channels, + out_channels, + kernel_size=1, + stride=stride, + bias=False, + norm=get_norm(norm, out_channels), + ) + else: + self.shortcut = None + + self.conv1 = Conv2d( + in_channels, + out_channels, + kernel_size=3, + stride=stride, + padding=1, + bias=False, + norm=get_norm(norm, out_channels), + ) + + self.conv2 = Conv2d( + out_channels, + out_channels, + kernel_size=3, + stride=1, + padding=1, + bias=False, + norm=get_norm(norm, out_channels), + ) + + for layer in [self.conv1, self.conv2, self.shortcut]: + if layer is not None: # shortcut can be None + weight_init.c2_msra_fill(layer) + + def forward(self, x): + out = self.conv1(x) + out = F.relu_(out) + out = self.conv2(out) + + if self.shortcut is not None: + shortcut = self.shortcut(x) + else: + shortcut = x + + out += shortcut + out = F.relu_(out) + return out + + +class BottleneckBlock(CNNBlockBase): + """ + The standard bottleneck residual block used by ResNet-50, 101 and 152 + defined in :paper:`ResNet`. It contains 3 conv layers with kernels + 1x1, 3x3, 1x1, and a projection shortcut if needed. + """ + + def __init__( + self, + in_channels, + out_channels, + *, + bottleneck_channels, + stride=1, + num_groups=1, + norm="BN", + stride_in_1x1=False, + dilation=1, + ): + """ + Args: + bottleneck_channels (int): number of output channels for the 3x3 + "bottleneck" conv layers. + num_groups (int): number of groups for the 3x3 conv layer. + norm (str or callable): normalization for all conv layers. + See :func:`layers.get_norm` for supported format. + stride_in_1x1 (bool): when stride>1, whether to put stride in the + first 1x1 convolution or the bottleneck 3x3 convolution. + dilation (int): the dilation rate of the 3x3 conv layer. + """ + super().__init__(in_channels, out_channels, stride) + + if in_channels != out_channels: + self.shortcut = Conv2d( + in_channels, + out_channels, + kernel_size=1, + stride=stride, + bias=False, + norm=get_norm(norm, out_channels), + ) + else: + self.shortcut = None + + # The original MSRA ResNet models have stride in the first 1x1 conv + # The subsequent fb.torch.resnet and Caffe2 ResNe[X]t implementations have + # stride in the 3x3 conv + stride_1x1, stride_3x3 = (stride, 1) if stride_in_1x1 else (1, stride) + + self.conv1 = Conv2d( + in_channels, + bottleneck_channels, + kernel_size=1, + stride=stride_1x1, + bias=False, + norm=get_norm(norm, bottleneck_channels), + ) + + self.conv2 = Conv2d( + bottleneck_channels, + bottleneck_channels, + kernel_size=3, + stride=stride_3x3, + padding=1 * dilation, + bias=False, + groups=num_groups, + dilation=dilation, + norm=get_norm(norm, bottleneck_channels), + ) + + self.conv3 = Conv2d( + bottleneck_channels, + out_channels, + kernel_size=1, + bias=False, + norm=get_norm(norm, out_channels), + ) + + for layer in [self.conv1, self.conv2, self.conv3, self.shortcut]: + if layer is not None: # shortcut can be None + weight_init.c2_msra_fill(layer) + + # Zero-initialize the last normalization in each residual branch, + # so that at the beginning, the residual branch starts with zeros, + # and each residual block behaves like an identity. + # See Sec 5.1 in "Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour": + # "For BN layers, the learnable scaling coefficient γ is initialized + # to be 1, except for each residual block's last BN + # where γ is initialized to be 0." + + # nn.init.constant_(self.conv3.norm.weight, 0) + # TODO this somehow hurts performance when training GN models from scratch. + # Add it as an option when we need to use this code to train a backbone. + + def forward(self, x): + out = self.conv1(x) + out = F.relu_(out) + + out = self.conv2(out) + out = F.relu_(out) + + out = self.conv3(out) + + if self.shortcut is not None: + shortcut = self.shortcut(x) + else: + shortcut = x + + out += shortcut + out = F.relu_(out) + return out + + +class DeformBottleneckBlock(CNNBlockBase): + """ + Similar to :class:`BottleneckBlock`, but with :paper:`deformable conv ` + in the 3x3 convolution. + """ + + def __init__( + self, + in_channels, + out_channels, + *, + bottleneck_channels, + stride=1, + num_groups=1, + norm="BN", + stride_in_1x1=False, + dilation=1, + deform_modulated=False, + deform_num_groups=1, + ): + super().__init__(in_channels, out_channels, stride) + self.deform_modulated = deform_modulated + + if in_channels != out_channels: + self.shortcut = Conv2d( + in_channels, + out_channels, + kernel_size=1, + stride=stride, + bias=False, + norm=get_norm(norm, out_channels), + ) + else: + self.shortcut = None + + stride_1x1, stride_3x3 = (stride, 1) if stride_in_1x1 else (1, stride) + + self.conv1 = Conv2d( + in_channels, + bottleneck_channels, + kernel_size=1, + stride=stride_1x1, + bias=False, + norm=get_norm(norm, bottleneck_channels), + ) + + if deform_modulated: + deform_conv_op = ModulatedDeformConv + # offset channels are 2 or 3 (if with modulated) * kernel_size * kernel_size + offset_channels = 27 + else: + deform_conv_op = DeformConv + offset_channels = 18 + + self.conv2_offset = Conv2d( + bottleneck_channels, + offset_channels * deform_num_groups, + kernel_size=3, + stride=stride_3x3, + padding=1 * dilation, + dilation=dilation, + ) + self.conv2 = deform_conv_op( + bottleneck_channels, + bottleneck_channels, + kernel_size=3, + stride=stride_3x3, + padding=1 * dilation, + bias=False, + groups=num_groups, + dilation=dilation, + deformable_groups=deform_num_groups, + norm=get_norm(norm, bottleneck_channels), + ) + + self.conv3 = Conv2d( + bottleneck_channels, + out_channels, + kernel_size=1, + bias=False, + norm=get_norm(norm, out_channels), + ) + + for layer in [self.conv1, self.conv2, self.conv3, self.shortcut]: + if layer is not None: # shortcut can be None + weight_init.c2_msra_fill(layer) + + nn.init.constant_(self.conv2_offset.weight, 0) + nn.init.constant_(self.conv2_offset.bias, 0) + + def forward(self, x): + out = self.conv1(x) + out = F.relu_(out) + + if self.deform_modulated: + offset_mask = self.conv2_offset(out) + offset_x, offset_y, mask = torch.chunk(offset_mask, 3, dim=1) + offset = torch.cat((offset_x, offset_y), dim=1) + mask = mask.sigmoid() + out = self.conv2(out, offset, mask) + else: + offset = self.conv2_offset(out) + out = self.conv2(out, offset) + out = F.relu_(out) + + out = self.conv3(out) + + if self.shortcut is not None: + shortcut = self.shortcut(x) + else: + shortcut = x + + out += shortcut + out = F.relu_(out) + return out + + +class BasicStem(CNNBlockBase): + """ + The standard ResNet stem (layers before the first residual block), + with a conv, relu and max_pool. + """ + + def __init__(self, in_channels=3, out_channels=64, norm="BN"): + """ + Args: + norm (str or callable): norm after the first conv layer. + See :func:`layers.get_norm` for supported format. + """ + super().__init__(in_channels, out_channels, 4) + self.in_channels = in_channels + self.conv1 = Conv2d( + in_channels, + out_channels, + kernel_size=7, + stride=2, + padding=3, + bias=False, + norm=get_norm(norm, out_channels), + ) + weight_init.c2_msra_fill(self.conv1) + + def forward(self, x): + x = self.conv1(x) + x = F.relu_(x) + x = F.max_pool2d(x, kernel_size=3, stride=2, padding=1) + return x + + +class ResNet(Backbone): + """ + Implement :paper:`ResNet`. + """ + + def __init__(self, stem, stages, num_classes=None, out_features=None, freeze_at=0): + """ + Args: + stem (nn.Module): a stem module + stages (list[list[CNNBlockBase]]): several (typically 4) stages, + each contains multiple :class:`CNNBlockBase`. + num_classes (None or int): if None, will not perform classification. + Otherwise, will create a linear layer. + out_features (list[str]): name of the layers whose outputs should + be returned in forward. Can be anything in "stem", "linear", or "res2" ... + If None, will return the output of the last layer. + freeze_at (int): The number of stages at the beginning to freeze. + see :meth:`freeze` for detailed explanation. + """ + super().__init__() + self.stem = stem + self.num_classes = num_classes + + current_stride = self.stem.stride + self._out_feature_strides = {"stem": current_stride} + self._out_feature_channels = {"stem": self.stem.out_channels} + + self.stage_names, self.stages = [], [] + + if out_features is not None: + # Avoid keeping unused layers in this module. They consume extra memory + # and may cause allreduce to fail + num_stages = max( + [{"res2": 1, "res3": 2, "res4": 3, "res5": 4}.get(f, 0) for f in out_features] + ) + stages = stages[:num_stages] + for i, blocks in enumerate(stages): + assert len(blocks) > 0, len(blocks) + for block in blocks: + assert isinstance(block, CNNBlockBase), block + + name = "res" + str(i + 2) + stage = nn.Sequential(*blocks) + + self.add_module(name, stage) + self.stage_names.append(name) + self.stages.append(stage) + + self._out_feature_strides[name] = current_stride = int( + current_stride * np.prod([k.stride for k in blocks]) + ) + self._out_feature_channels[name] = curr_channels = blocks[-1].out_channels + self.stage_names = tuple(self.stage_names) # Make it static for scripting + + if num_classes is not None: + self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) + self.linear = nn.Linear(curr_channels, num_classes) + + # Sec 5.1 in "Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour": + # "The 1000-way fully-connected layer is initialized by + # drawing weights from a zero-mean Gaussian with standard deviation of 0.01." + nn.init.normal_(self.linear.weight, std=0.01) + name = "linear" + + if out_features is None: + out_features = [name] + self._out_features = out_features + assert len(self._out_features) + children = [x[0] for x in self.named_children()] + for out_feature in self._out_features: + assert out_feature in children, "Available children: {}".format(", ".join(children)) + self.freeze(freeze_at) + + def forward(self, x): + """ + Args: + x: Tensor of shape (N,C,H,W). H, W must be a multiple of ``self.size_divisibility``. + + Returns: + dict[str->Tensor]: names and the corresponding features + """ + assert x.dim() == 4, f"ResNet takes an input of shape (N, C, H, W). Got {x.shape} instead!" + outputs = {} + x = self.stem(x) + if "stem" in self._out_features: + outputs["stem"] = x + for name, stage in zip(self.stage_names, self.stages): + x = stage(x) + if name in self._out_features: + outputs[name] = x + if self.num_classes is not None: + x = self.avgpool(x) + x = torch.flatten(x, 1) + x = self.linear(x) + if "linear" in self._out_features: + outputs["linear"] = x + return outputs + + def output_shape(self): + return { + name: ShapeSpec( + channels=self._out_feature_channels[name], stride=self._out_feature_strides[name] + ) + for name in self._out_features + } + + def freeze(self, freeze_at=0): + """ + Freeze the first several stages of the ResNet. Commonly used in + fine-tuning. + + Layers that produce the same feature map spatial size are defined as one + "stage" by :paper:`FPN`. + + Args: + freeze_at (int): number of stages to freeze. + `1` means freezing the stem. `2` means freezing the stem and + one residual stage, etc. + + Returns: + nn.Module: this ResNet itself + """ + if freeze_at >= 1: + self.stem.freeze() + for idx, stage in enumerate(self.stages, start=2): + if freeze_at >= idx: + for block in stage.children(): + block.freeze() + return self + + @staticmethod + def make_stage(block_class, num_blocks, *, in_channels, out_channels, **kwargs): + """ + Create a list of blocks of the same type that forms one ResNet stage. + + Args: + block_class (type): a subclass of CNNBlockBase that's used to create all blocks in this + stage. A module of this type must not change spatial resolution of inputs unless its + stride != 1. + num_blocks (int): number of blocks in this stage + in_channels (int): input channels of the entire stage. + out_channels (int): output channels of **every block** in the stage. + kwargs: other arguments passed to the constructor of + `block_class`. If the argument name is "xx_per_block", the + argument is a list of values to be passed to each block in the + stage. Otherwise, the same argument is passed to every block + in the stage. + + Returns: + list[CNNBlockBase]: a list of block module. + + Examples: + :: + stage = ResNet.make_stage( + BottleneckBlock, 3, in_channels=16, out_channels=64, + bottleneck_channels=16, num_groups=1, + stride_per_block=[2, 1, 1], + dilations_per_block=[1, 1, 2] + ) + + Usually, layers that produce the same feature map spatial size are defined as one + "stage" (in :paper:`FPN`). Under such definition, ``stride_per_block[1:]`` should + all be 1. + """ + blocks = [] + for i in range(num_blocks): + curr_kwargs = {} + for k, v in kwargs.items(): + if k.endswith("_per_block"): + assert len(v) == num_blocks, ( + f"Argument '{k}' of make_stage should have the " + f"same length as num_blocks={num_blocks}." + ) + newk = k[: -len("_per_block")] + assert newk not in kwargs, f"Cannot call make_stage with both {k} and {newk}!" + curr_kwargs[newk] = v[i] + else: + curr_kwargs[k] = v + + blocks.append( + block_class(in_channels=in_channels, out_channels=out_channels, **curr_kwargs) + ) + in_channels = out_channels + return blocks + + @staticmethod + def make_default_stages(depth, block_class=None, **kwargs): + """ + Created list of ResNet stages from pre-defined depth (one of 18, 34, 50, 101, 152). + If it doesn't create the ResNet variant you need, please use :meth:`make_stage` + instead for fine-grained customization. + + Args: + depth (int): depth of ResNet + block_class (type): the CNN block class. Has to accept + `bottleneck_channels` argument for depth > 50. + By default it is BasicBlock or BottleneckBlock, based on the + depth. + kwargs: + other arguments to pass to `make_stage`. Should not contain + stride and channels, as they are predefined for each depth. + + Returns: + list[list[CNNBlockBase]]: modules in all stages; see arguments of + :class:`ResNet.__init__`. + """ + num_blocks_per_stage = { + 18: [2, 2, 2, 2], + 34: [3, 4, 6, 3], + 50: [3, 4, 6, 3], + 101: [3, 4, 23, 3], + 152: [3, 8, 36, 3], + }[depth] + if block_class is None: + block_class = BasicBlock if depth < 50 else BottleneckBlock + if depth < 50: + in_channels = [64, 64, 128, 256] + out_channels = [64, 128, 256, 512] + else: + in_channels = [64, 256, 512, 1024] + out_channels = [256, 512, 1024, 2048] + ret = [] + for (n, s, i, o) in zip(num_blocks_per_stage, [1, 2, 2, 2], in_channels, out_channels): + if depth >= 50: + kwargs["bottleneck_channels"] = o // 4 + ret.append( + ResNet.make_stage( + block_class=block_class, + num_blocks=n, + stride_per_block=[s] + [1] * (n - 1), + in_channels=i, + out_channels=o, + **kwargs, + ) + ) + return ret + + +ResNetBlockBase = CNNBlockBase +""" +Alias for backward compatibiltiy. +""" + + +def make_stage(*args, **kwargs): + """ + Deprecated alias for backward compatibiltiy. + """ + return ResNet.make_stage(*args, **kwargs) + + +@BACKBONE_REGISTRY.register() +def build_resnet_backbone(cfg, input_shape): + """ + Create a ResNet instance from config. + + Returns: + ResNet: a :class:`ResNet` instance. + """ + # need registration of new blocks/stems? + norm = cfg.MODEL.RESNETS.NORM + stem = BasicStem( + in_channels=input_shape.channels, + out_channels=cfg.MODEL.RESNETS.STEM_OUT_CHANNELS, + norm=norm, + ) + + # fmt: off + freeze_at = cfg.MODEL.BACKBONE.FREEZE_AT + out_features = cfg.MODEL.RESNETS.OUT_FEATURES + depth = cfg.MODEL.RESNETS.DEPTH + num_groups = cfg.MODEL.RESNETS.NUM_GROUPS + width_per_group = cfg.MODEL.RESNETS.WIDTH_PER_GROUP + bottleneck_channels = num_groups * width_per_group + in_channels = cfg.MODEL.RESNETS.STEM_OUT_CHANNELS + out_channels = cfg.MODEL.RESNETS.RES2_OUT_CHANNELS + stride_in_1x1 = cfg.MODEL.RESNETS.STRIDE_IN_1X1 + res5_dilation = cfg.MODEL.RESNETS.RES5_DILATION + deform_on_per_stage = cfg.MODEL.RESNETS.DEFORM_ON_PER_STAGE + deform_modulated = cfg.MODEL.RESNETS.DEFORM_MODULATED + deform_num_groups = cfg.MODEL.RESNETS.DEFORM_NUM_GROUPS + # fmt: on + assert res5_dilation in {1, 2}, "res5_dilation cannot be {}.".format(res5_dilation) + + num_blocks_per_stage = { + 18: [2, 2, 2, 2], + 34: [3, 4, 6, 3], + 50: [3, 4, 6, 3], + 101: [3, 4, 23, 3], + 152: [3, 8, 36, 3], + }[depth] + + if depth in [18, 34]: + assert out_channels == 64, "Must set MODEL.RESNETS.RES2_OUT_CHANNELS = 64 for R18/R34" + assert not any( + deform_on_per_stage + ), "MODEL.RESNETS.DEFORM_ON_PER_STAGE unsupported for R18/R34" + assert res5_dilation == 1, "Must set MODEL.RESNETS.RES5_DILATION = 1 for R18/R34" + assert num_groups == 1, "Must set MODEL.RESNETS.NUM_GROUPS = 1 for R18/R34" + + stages = [] + + for idx, stage_idx in enumerate(range(2, 6)): + # res5_dilation is used this way as a convention in R-FCN & Deformable Conv paper + dilation = res5_dilation if stage_idx == 5 else 1 + first_stride = 1 if idx == 0 or (stage_idx == 5 and dilation == 2) else 2 + stage_kargs = { + "num_blocks": num_blocks_per_stage[idx], + "stride_per_block": [first_stride] + [1] * (num_blocks_per_stage[idx] - 1), + "in_channels": in_channels, + "out_channels": out_channels, + "norm": norm, + } + # Use BasicBlock for R18 and R34. + if depth in [18, 34]: + stage_kargs["block_class"] = BasicBlock + else: + stage_kargs["bottleneck_channels"] = bottleneck_channels + stage_kargs["stride_in_1x1"] = stride_in_1x1 + stage_kargs["dilation"] = dilation + stage_kargs["num_groups"] = num_groups + if deform_on_per_stage[idx]: + stage_kargs["block_class"] = DeformBottleneckBlock + stage_kargs["deform_modulated"] = deform_modulated + stage_kargs["deform_num_groups"] = deform_num_groups + else: + stage_kargs["block_class"] = BottleneckBlock + blocks = ResNet.make_stage(**stage_kargs) + in_channels = out_channels + out_channels *= 2 + bottleneck_channels *= 2 + stages.append(blocks) + return ResNet(stem, stages, out_features=out_features, freeze_at=freeze_at) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/swin.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/swin.py new file mode 100644 index 00000000..d5a651d6 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/swin.py @@ -0,0 +1,695 @@ +# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved +""" +Implementation of Swin models from :paper:`swin`. + +This code is adapted from https://github.com/SwinTransformer/Swin-Transformer-Object-Detection/blob/master/mmdet/models/backbones/swin_transformer.py with minimal modifications. # noqa +-------------------------------------------------------- +Swin Transformer +Copyright (c) 2021 Microsoft +Licensed under The MIT License [see LICENSE for details] +Written by Ze Liu, Yutong Lin, Yixuan Wei +-------------------------------------------------------- +LICENSE: https://github.com/SwinTransformer/Swin-Transformer-Object-Detection/blob/461e003166a8083d0b620beacd4662a2df306bd6/LICENSE +""" + +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.checkpoint as checkpoint + +from annotator.oneformer.detectron2.modeling.backbone.backbone import Backbone + +_to_2tuple = nn.modules.utils._ntuple(2) + + +class Mlp(nn.Module): + """Multilayer perceptron.""" + + def __init__( + self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.0 + ): + super().__init__() + out_features = out_features or in_features + hidden_features = hidden_features or in_features + self.fc1 = nn.Linear(in_features, hidden_features) + self.act = act_layer() + self.fc2 = nn.Linear(hidden_features, out_features) + self.drop = nn.Dropout(drop) + + def forward(self, x): + x = self.fc1(x) + x = self.act(x) + x = self.drop(x) + x = self.fc2(x) + x = self.drop(x) + return x + + +def window_partition(x, window_size): + """ + Args: + x: (B, H, W, C) + window_size (int): window size + Returns: + windows: (num_windows*B, window_size, window_size, C) + """ + B, H, W, C = x.shape + x = x.view(B, H // window_size, window_size, W // window_size, window_size, C) + windows = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(-1, window_size, window_size, C) + return windows + + +def window_reverse(windows, window_size, H, W): + """ + Args: + windows: (num_windows*B, window_size, window_size, C) + window_size (int): Window size + H (int): Height of image + W (int): Width of image + Returns: + x: (B, H, W, C) + """ + B = int(windows.shape[0] / (H * W / window_size / window_size)) + x = windows.view(B, H // window_size, W // window_size, window_size, window_size, -1) + x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, H, W, -1) + return x + + +class WindowAttention(nn.Module): + """Window based multi-head self attention (W-MSA) module with relative position bias. + It supports both of shifted and non-shifted window. + Args: + dim (int): Number of input channels. + window_size (tuple[int]): The height and width of the window. + num_heads (int): Number of attention heads. + qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. + Default: True + qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set + attn_drop (float, optional): Dropout ratio of attention weight. Default: 0.0 + proj_drop (float, optional): Dropout ratio of output. Default: 0.0 + """ + + def __init__( + self, + dim, + window_size, + num_heads, + qkv_bias=True, + qk_scale=None, + attn_drop=0.0, + proj_drop=0.0, + ): + + super().__init__() + self.dim = dim + self.window_size = window_size # Wh, Ww + self.num_heads = num_heads + head_dim = dim // num_heads + self.scale = qk_scale or head_dim**-0.5 + + # define a parameter table of relative position bias + self.relative_position_bias_table = nn.Parameter( + torch.zeros((2 * window_size[0] - 1) * (2 * window_size[1] - 1), num_heads) + ) # 2*Wh-1 * 2*Ww-1, nH + + # get pair-wise relative position index for each token inside the window + coords_h = torch.arange(self.window_size[0]) + coords_w = torch.arange(self.window_size[1]) + coords = torch.stack(torch.meshgrid([coords_h, coords_w])) # 2, Wh, Ww + coords_flatten = torch.flatten(coords, 1) # 2, Wh*Ww + relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] # 2, Wh*Ww, Wh*Ww + relative_coords = relative_coords.permute(1, 2, 0).contiguous() # Wh*Ww, Wh*Ww, 2 + relative_coords[:, :, 0] += self.window_size[0] - 1 # shift to start from 0 + relative_coords[:, :, 1] += self.window_size[1] - 1 + relative_coords[:, :, 0] *= 2 * self.window_size[1] - 1 + relative_position_index = relative_coords.sum(-1) # Wh*Ww, Wh*Ww + self.register_buffer("relative_position_index", relative_position_index) + + self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias) + self.attn_drop = nn.Dropout(attn_drop) + self.proj = nn.Linear(dim, dim) + self.proj_drop = nn.Dropout(proj_drop) + + nn.init.trunc_normal_(self.relative_position_bias_table, std=0.02) + self.softmax = nn.Softmax(dim=-1) + + def forward(self, x, mask=None): + """Forward function. + Args: + x: input features with shape of (num_windows*B, N, C) + mask: (0/-inf) mask with shape of (num_windows, Wh*Ww, Wh*Ww) or None + """ + B_, N, C = x.shape + qkv = ( + self.qkv(x) + .reshape(B_, N, 3, self.num_heads, C // self.num_heads) + .permute(2, 0, 3, 1, 4) + ) + q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple) + + q = q * self.scale + attn = q @ k.transpose(-2, -1) + + relative_position_bias = self.relative_position_bias_table[ + self.relative_position_index.view(-1) + ].view( + self.window_size[0] * self.window_size[1], self.window_size[0] * self.window_size[1], -1 + ) # Wh*Ww,Wh*Ww,nH + relative_position_bias = relative_position_bias.permute( + 2, 0, 1 + ).contiguous() # nH, Wh*Ww, Wh*Ww + attn = attn + relative_position_bias.unsqueeze(0) + + if mask is not None: + nW = mask.shape[0] + attn = attn.view(B_ // nW, nW, self.num_heads, N, N) + mask.unsqueeze(1).unsqueeze(0) + attn = attn.view(-1, self.num_heads, N, N) + attn = self.softmax(attn) + else: + attn = self.softmax(attn) + + attn = self.attn_drop(attn) + + x = (attn @ v).transpose(1, 2).reshape(B_, N, C) + x = self.proj(x) + x = self.proj_drop(x) + return x + + +class SwinTransformerBlock(nn.Module): + """Swin Transformer Block. + Args: + dim (int): Number of input channels. + num_heads (int): Number of attention heads. + window_size (int): Window size. + shift_size (int): Shift size for SW-MSA. + mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. + qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True + qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set. + drop (float, optional): Dropout rate. Default: 0.0 + attn_drop (float, optional): Attention dropout rate. Default: 0.0 + drop_path (float, optional): Stochastic depth rate. Default: 0.0 + act_layer (nn.Module, optional): Activation layer. Default: nn.GELU + norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm + """ + + def __init__( + self, + dim, + num_heads, + window_size=7, + shift_size=0, + mlp_ratio=4.0, + qkv_bias=True, + qk_scale=None, + drop=0.0, + attn_drop=0.0, + drop_path=0.0, + act_layer=nn.GELU, + norm_layer=nn.LayerNorm, + ): + super().__init__() + self.dim = dim + self.num_heads = num_heads + self.window_size = window_size + self.shift_size = shift_size + self.mlp_ratio = mlp_ratio + assert 0 <= self.shift_size < self.window_size, "shift_size must in 0-window_size" + + self.norm1 = norm_layer(dim) + self.attn = WindowAttention( + dim, + window_size=_to_2tuple(self.window_size), + num_heads=num_heads, + qkv_bias=qkv_bias, + qk_scale=qk_scale, + attn_drop=attn_drop, + proj_drop=drop, + ) + + if drop_path > 0.0: + from timm.models.layers import DropPath + + self.drop_path = DropPath(drop_path) + else: + self.drop_path = nn.Identity() + self.norm2 = norm_layer(dim) + mlp_hidden_dim = int(dim * mlp_ratio) + self.mlp = Mlp( + in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop + ) + + self.H = None + self.W = None + + def forward(self, x, mask_matrix): + """Forward function. + Args: + x: Input feature, tensor size (B, H*W, C). + H, W: Spatial resolution of the input feature. + mask_matrix: Attention mask for cyclic shift. + """ + B, L, C = x.shape + H, W = self.H, self.W + assert L == H * W, "input feature has wrong size" + + shortcut = x + x = self.norm1(x) + x = x.view(B, H, W, C) + + # pad feature maps to multiples of window size + pad_l = pad_t = 0 + pad_r = (self.window_size - W % self.window_size) % self.window_size + pad_b = (self.window_size - H % self.window_size) % self.window_size + x = F.pad(x, (0, 0, pad_l, pad_r, pad_t, pad_b)) + _, Hp, Wp, _ = x.shape + + # cyclic shift + if self.shift_size > 0: + shifted_x = torch.roll(x, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2)) + attn_mask = mask_matrix + else: + shifted_x = x + attn_mask = None + + # partition windows + x_windows = window_partition( + shifted_x, self.window_size + ) # nW*B, window_size, window_size, C + x_windows = x_windows.view( + -1, self.window_size * self.window_size, C + ) # nW*B, window_size*window_size, C + + # W-MSA/SW-MSA + attn_windows = self.attn(x_windows, mask=attn_mask) # nW*B, window_size*window_size, C + + # merge windows + attn_windows = attn_windows.view(-1, self.window_size, self.window_size, C) + shifted_x = window_reverse(attn_windows, self.window_size, Hp, Wp) # B H' W' C + + # reverse cyclic shift + if self.shift_size > 0: + x = torch.roll(shifted_x, shifts=(self.shift_size, self.shift_size), dims=(1, 2)) + else: + x = shifted_x + + if pad_r > 0 or pad_b > 0: + x = x[:, :H, :W, :].contiguous() + + x = x.view(B, H * W, C) + + # FFN + x = shortcut + self.drop_path(x) + x = x + self.drop_path(self.mlp(self.norm2(x))) + + return x + + +class PatchMerging(nn.Module): + """Patch Merging Layer + Args: + dim (int): Number of input channels. + norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm + """ + + def __init__(self, dim, norm_layer=nn.LayerNorm): + super().__init__() + self.dim = dim + self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False) + self.norm = norm_layer(4 * dim) + + def forward(self, x, H, W): + """Forward function. + Args: + x: Input feature, tensor size (B, H*W, C). + H, W: Spatial resolution of the input feature. + """ + B, L, C = x.shape + assert L == H * W, "input feature has wrong size" + + x = x.view(B, H, W, C) + + # padding + pad_input = (H % 2 == 1) or (W % 2 == 1) + if pad_input: + x = F.pad(x, (0, 0, 0, W % 2, 0, H % 2)) + + x0 = x[:, 0::2, 0::2, :] # B H/2 W/2 C + x1 = x[:, 1::2, 0::2, :] # B H/2 W/2 C + x2 = x[:, 0::2, 1::2, :] # B H/2 W/2 C + x3 = x[:, 1::2, 1::2, :] # B H/2 W/2 C + x = torch.cat([x0, x1, x2, x3], -1) # B H/2 W/2 4*C + x = x.view(B, -1, 4 * C) # B H/2*W/2 4*C + + x = self.norm(x) + x = self.reduction(x) + + return x + + +class BasicLayer(nn.Module): + """A basic Swin Transformer layer for one stage. + Args: + dim (int): Number of feature channels + depth (int): Depths of this stage. + num_heads (int): Number of attention head. + window_size (int): Local window size. Default: 7. + mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. Default: 4. + qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True + qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set. + drop (float, optional): Dropout rate. Default: 0.0 + attn_drop (float, optional): Attention dropout rate. Default: 0.0 + drop_path (float | tuple[float], optional): Stochastic depth rate. Default: 0.0 + norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm + downsample (nn.Module | None, optional): Downsample layer at the end of the layer. + Default: None + use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False. + """ + + def __init__( + self, + dim, + depth, + num_heads, + window_size=7, + mlp_ratio=4.0, + qkv_bias=True, + qk_scale=None, + drop=0.0, + attn_drop=0.0, + drop_path=0.0, + norm_layer=nn.LayerNorm, + downsample=None, + use_checkpoint=False, + ): + super().__init__() + self.window_size = window_size + self.shift_size = window_size // 2 + self.depth = depth + self.use_checkpoint = use_checkpoint + + # build blocks + self.blocks = nn.ModuleList( + [ + SwinTransformerBlock( + dim=dim, + num_heads=num_heads, + window_size=window_size, + shift_size=0 if (i % 2 == 0) else window_size // 2, + mlp_ratio=mlp_ratio, + qkv_bias=qkv_bias, + qk_scale=qk_scale, + drop=drop, + attn_drop=attn_drop, + drop_path=drop_path[i] if isinstance(drop_path, list) else drop_path, + norm_layer=norm_layer, + ) + for i in range(depth) + ] + ) + + # patch merging layer + if downsample is not None: + self.downsample = downsample(dim=dim, norm_layer=norm_layer) + else: + self.downsample = None + + def forward(self, x, H, W): + """Forward function. + Args: + x: Input feature, tensor size (B, H*W, C). + H, W: Spatial resolution of the input feature. + """ + + # calculate attention mask for SW-MSA + Hp = int(np.ceil(H / self.window_size)) * self.window_size + Wp = int(np.ceil(W / self.window_size)) * self.window_size + img_mask = torch.zeros((1, Hp, Wp, 1), device=x.device) # 1 Hp Wp 1 + h_slices = ( + slice(0, -self.window_size), + slice(-self.window_size, -self.shift_size), + slice(-self.shift_size, None), + ) + w_slices = ( + slice(0, -self.window_size), + slice(-self.window_size, -self.shift_size), + slice(-self.shift_size, None), + ) + cnt = 0 + for h in h_slices: + for w in w_slices: + img_mask[:, h, w, :] = cnt + cnt += 1 + + mask_windows = window_partition( + img_mask, self.window_size + ) # nW, window_size, window_size, 1 + mask_windows = mask_windows.view(-1, self.window_size * self.window_size) + attn_mask = mask_windows.unsqueeze(1) - mask_windows.unsqueeze(2) + attn_mask = attn_mask.masked_fill(attn_mask != 0, float(-100.0)).masked_fill( + attn_mask == 0, float(0.0) + ) + + for blk in self.blocks: + blk.H, blk.W = H, W + if self.use_checkpoint: + x = checkpoint.checkpoint(blk, x, attn_mask) + else: + x = blk(x, attn_mask) + if self.downsample is not None: + x_down = self.downsample(x, H, W) + Wh, Ww = (H + 1) // 2, (W + 1) // 2 + return x, H, W, x_down, Wh, Ww + else: + return x, H, W, x, H, W + + +class PatchEmbed(nn.Module): + """Image to Patch Embedding + Args: + patch_size (int): Patch token size. Default: 4. + in_chans (int): Number of input image channels. Default: 3. + embed_dim (int): Number of linear projection output channels. Default: 96. + norm_layer (nn.Module, optional): Normalization layer. Default: None + """ + + def __init__(self, patch_size=4, in_chans=3, embed_dim=96, norm_layer=None): + super().__init__() + patch_size = _to_2tuple(patch_size) + self.patch_size = patch_size + + self.in_chans = in_chans + self.embed_dim = embed_dim + + self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size) + if norm_layer is not None: + self.norm = norm_layer(embed_dim) + else: + self.norm = None + + def forward(self, x): + """Forward function.""" + # padding + _, _, H, W = x.size() + if W % self.patch_size[1] != 0: + x = F.pad(x, (0, self.patch_size[1] - W % self.patch_size[1])) + if H % self.patch_size[0] != 0: + x = F.pad(x, (0, 0, 0, self.patch_size[0] - H % self.patch_size[0])) + + x = self.proj(x) # B C Wh Ww + if self.norm is not None: + Wh, Ww = x.size(2), x.size(3) + x = x.flatten(2).transpose(1, 2) + x = self.norm(x) + x = x.transpose(1, 2).view(-1, self.embed_dim, Wh, Ww) + + return x + + +class SwinTransformer(Backbone): + """Swin Transformer backbone. + A PyTorch impl of : `Swin Transformer: Hierarchical Vision Transformer using Shifted + Windows` - https://arxiv.org/pdf/2103.14030 + Args: + pretrain_img_size (int): Input image size for training the pretrained model, + used in absolute postion embedding. Default 224. + patch_size (int | tuple(int)): Patch size. Default: 4. + in_chans (int): Number of input image channels. Default: 3. + embed_dim (int): Number of linear projection output channels. Default: 96. + depths (tuple[int]): Depths of each Swin Transformer stage. + num_heads (tuple[int]): Number of attention head of each stage. + window_size (int): Window size. Default: 7. + mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. Default: 4. + qkv_bias (bool): If True, add a learnable bias to query, key, value. Default: True + qk_scale (float): Override default qk scale of head_dim ** -0.5 if set. + drop_rate (float): Dropout rate. + attn_drop_rate (float): Attention dropout rate. Default: 0. + drop_path_rate (float): Stochastic depth rate. Default: 0.2. + norm_layer (nn.Module): Normalization layer. Default: nn.LayerNorm. + ape (bool): If True, add absolute position embedding to the patch embedding. Default: False. + patch_norm (bool): If True, add normalization after patch embedding. Default: True. + out_indices (Sequence[int]): Output from which stages. + frozen_stages (int): Stages to be frozen (stop grad and set eval mode). + -1 means not freezing any parameters. + use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False. + """ + + def __init__( + self, + pretrain_img_size=224, + patch_size=4, + in_chans=3, + embed_dim=96, + depths=(2, 2, 6, 2), + num_heads=(3, 6, 12, 24), + window_size=7, + mlp_ratio=4.0, + qkv_bias=True, + qk_scale=None, + drop_rate=0.0, + attn_drop_rate=0.0, + drop_path_rate=0.2, + norm_layer=nn.LayerNorm, + ape=False, + patch_norm=True, + out_indices=(0, 1, 2, 3), + frozen_stages=-1, + use_checkpoint=False, + ): + super().__init__() + + self.pretrain_img_size = pretrain_img_size + self.num_layers = len(depths) + self.embed_dim = embed_dim + self.ape = ape + self.patch_norm = patch_norm + self.out_indices = out_indices + self.frozen_stages = frozen_stages + + # split image into non-overlapping patches + self.patch_embed = PatchEmbed( + patch_size=patch_size, + in_chans=in_chans, + embed_dim=embed_dim, + norm_layer=norm_layer if self.patch_norm else None, + ) + + # absolute position embedding + if self.ape: + pretrain_img_size = _to_2tuple(pretrain_img_size) + patch_size = _to_2tuple(patch_size) + patches_resolution = [ + pretrain_img_size[0] // patch_size[0], + pretrain_img_size[1] // patch_size[1], + ] + + self.absolute_pos_embed = nn.Parameter( + torch.zeros(1, embed_dim, patches_resolution[0], patches_resolution[1]) + ) + nn.init.trunc_normal_(self.absolute_pos_embed, std=0.02) + + self.pos_drop = nn.Dropout(p=drop_rate) + + # stochastic depth + dpr = [ + x.item() for x in torch.linspace(0, drop_path_rate, sum(depths)) + ] # stochastic depth decay rule + + # build layers + self.layers = nn.ModuleList() + for i_layer in range(self.num_layers): + layer = BasicLayer( + dim=int(embed_dim * 2**i_layer), + depth=depths[i_layer], + num_heads=num_heads[i_layer], + window_size=window_size, + mlp_ratio=mlp_ratio, + qkv_bias=qkv_bias, + qk_scale=qk_scale, + drop=drop_rate, + attn_drop=attn_drop_rate, + drop_path=dpr[sum(depths[:i_layer]) : sum(depths[: i_layer + 1])], + norm_layer=norm_layer, + downsample=PatchMerging if (i_layer < self.num_layers - 1) else None, + use_checkpoint=use_checkpoint, + ) + self.layers.append(layer) + + num_features = [int(embed_dim * 2**i) for i in range(self.num_layers)] + self.num_features = num_features + + # add a norm layer for each output + for i_layer in out_indices: + layer = norm_layer(num_features[i_layer]) + layer_name = f"norm{i_layer}" + self.add_module(layer_name, layer) + + self._freeze_stages() + self._out_features = ["p{}".format(i) for i in self.out_indices] + self._out_feature_channels = { + "p{}".format(i): self.embed_dim * 2**i for i in self.out_indices + } + self._out_feature_strides = {"p{}".format(i): 2 ** (i + 2) for i in self.out_indices} + self._size_devisibility = 32 + + self.apply(self._init_weights) + + def _freeze_stages(self): + if self.frozen_stages >= 0: + self.patch_embed.eval() + for param in self.patch_embed.parameters(): + param.requires_grad = False + + if self.frozen_stages >= 1 and self.ape: + self.absolute_pos_embed.requires_grad = False + + if self.frozen_stages >= 2: + self.pos_drop.eval() + for i in range(0, self.frozen_stages - 1): + m = self.layers[i] + m.eval() + for param in m.parameters(): + param.requires_grad = False + + def _init_weights(self, m): + if isinstance(m, nn.Linear): + nn.init.trunc_normal_(m.weight, std=0.02) + if isinstance(m, nn.Linear) and m.bias is not None: + nn.init.constant_(m.bias, 0) + elif isinstance(m, nn.LayerNorm): + nn.init.constant_(m.bias, 0) + nn.init.constant_(m.weight, 1.0) + + @property + def size_divisibility(self): + return self._size_divisibility + + def forward(self, x): + """Forward function.""" + x = self.patch_embed(x) + + Wh, Ww = x.size(2), x.size(3) + if self.ape: + # interpolate the position embedding to the corresponding size + absolute_pos_embed = F.interpolate( + self.absolute_pos_embed, size=(Wh, Ww), mode="bicubic" + ) + x = (x + absolute_pos_embed).flatten(2).transpose(1, 2) # B Wh*Ww C + else: + x = x.flatten(2).transpose(1, 2) + x = self.pos_drop(x) + + outs = {} + for i in range(self.num_layers): + layer = self.layers[i] + x_out, H, W, x, Wh, Ww = layer(x, Wh, Ww) + + if i in self.out_indices: + norm_layer = getattr(self, f"norm{i}") + x_out = norm_layer(x_out) + + out = x_out.view(-1, H, W, self.num_features[i]).permute(0, 3, 1, 2).contiguous() + outs["p{}".format(i)] = out + + return outs diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/utils.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/utils.py new file mode 100644 index 00000000..2b89a4c3 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/utils.py @@ -0,0 +1,186 @@ +# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved +import math +import torch +import torch.nn as nn +import torch.nn.functional as F + +__all__ = [ + "window_partition", + "window_unpartition", + "add_decomposed_rel_pos", + "get_abs_pos", + "PatchEmbed", +] + + +def window_partition(x, window_size): + """ + Partition into non-overlapping windows with padding if needed. + Args: + x (tensor): input tokens with [B, H, W, C]. + window_size (int): window size. + + Returns: + windows: windows after partition with [B * num_windows, window_size, window_size, C]. + (Hp, Wp): padded height and width before partition + """ + B, H, W, C = x.shape + + pad_h = (window_size - H % window_size) % window_size + pad_w = (window_size - W % window_size) % window_size + if pad_h > 0 or pad_w > 0: + x = F.pad(x, (0, 0, 0, pad_w, 0, pad_h)) + Hp, Wp = H + pad_h, W + pad_w + + x = x.view(B, Hp // window_size, window_size, Wp // window_size, window_size, C) + windows = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(-1, window_size, window_size, C) + return windows, (Hp, Wp) + + +def window_unpartition(windows, window_size, pad_hw, hw): + """ + Window unpartition into original sequences and removing padding. + Args: + x (tensor): input tokens with [B * num_windows, window_size, window_size, C]. + window_size (int): window size. + pad_hw (Tuple): padded height and width (Hp, Wp). + hw (Tuple): original height and width (H, W) before padding. + + Returns: + x: unpartitioned sequences with [B, H, W, C]. + """ + Hp, Wp = pad_hw + H, W = hw + B = windows.shape[0] // (Hp * Wp // window_size // window_size) + x = windows.view(B, Hp // window_size, Wp // window_size, window_size, window_size, -1) + x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, Hp, Wp, -1) + + if Hp > H or Wp > W: + x = x[:, :H, :W, :].contiguous() + return x + + +def get_rel_pos(q_size, k_size, rel_pos): + """ + Get relative positional embeddings according to the relative positions of + query and key sizes. + Args: + q_size (int): size of query q. + k_size (int): size of key k. + rel_pos (Tensor): relative position embeddings (L, C). + + Returns: + Extracted positional embeddings according to relative positions. + """ + max_rel_dist = int(2 * max(q_size, k_size) - 1) + # Interpolate rel pos if needed. + if rel_pos.shape[0] != max_rel_dist: + # Interpolate rel pos. + rel_pos_resized = F.interpolate( + rel_pos.reshape(1, rel_pos.shape[0], -1).permute(0, 2, 1), + size=max_rel_dist, + mode="linear", + ) + rel_pos_resized = rel_pos_resized.reshape(-1, max_rel_dist).permute(1, 0) + else: + rel_pos_resized = rel_pos + + # Scale the coords with short length if shapes for q and k are different. + q_coords = torch.arange(q_size)[:, None] * max(k_size / q_size, 1.0) + k_coords = torch.arange(k_size)[None, :] * max(q_size / k_size, 1.0) + relative_coords = (q_coords - k_coords) + (k_size - 1) * max(q_size / k_size, 1.0) + + return rel_pos_resized[relative_coords.long()] + + +def add_decomposed_rel_pos(attn, q, rel_pos_h, rel_pos_w, q_size, k_size): + """ + Calculate decomposed Relative Positional Embeddings from :paper:`mvitv2`. + https://github.com/facebookresearch/mvit/blob/19786631e330df9f3622e5402b4a419a263a2c80/mvit/models/attention.py # noqa B950 + Args: + attn (Tensor): attention map. + q (Tensor): query q in the attention layer with shape (B, q_h * q_w, C). + rel_pos_h (Tensor): relative position embeddings (Lh, C) for height axis. + rel_pos_w (Tensor): relative position embeddings (Lw, C) for width axis. + q_size (Tuple): spatial sequence size of query q with (q_h, q_w). + k_size (Tuple): spatial sequence size of key k with (k_h, k_w). + + Returns: + attn (Tensor): attention map with added relative positional embeddings. + """ + q_h, q_w = q_size + k_h, k_w = k_size + Rh = get_rel_pos(q_h, k_h, rel_pos_h) + Rw = get_rel_pos(q_w, k_w, rel_pos_w) + + B, _, dim = q.shape + r_q = q.reshape(B, q_h, q_w, dim) + rel_h = torch.einsum("bhwc,hkc->bhwk", r_q, Rh) + rel_w = torch.einsum("bhwc,wkc->bhwk", r_q, Rw) + + attn = ( + attn.view(B, q_h, q_w, k_h, k_w) + rel_h[:, :, :, :, None] + rel_w[:, :, :, None, :] + ).view(B, q_h * q_w, k_h * k_w) + + return attn + + +def get_abs_pos(abs_pos, has_cls_token, hw): + """ + Calculate absolute positional embeddings. If needed, resize embeddings and remove cls_token + dimension for the original embeddings. + Args: + abs_pos (Tensor): absolute positional embeddings with (1, num_position, C). + has_cls_token (bool): If true, has 1 embedding in abs_pos for cls token. + hw (Tuple): size of input image tokens. + + Returns: + Absolute positional embeddings after processing with shape (1, H, W, C) + """ + h, w = hw + if has_cls_token: + abs_pos = abs_pos[:, 1:] + xy_num = abs_pos.shape[1] + size = int(math.sqrt(xy_num)) + assert size * size == xy_num + + if size != h or size != w: + new_abs_pos = F.interpolate( + abs_pos.reshape(1, size, size, -1).permute(0, 3, 1, 2), + size=(h, w), + mode="bicubic", + align_corners=False, + ) + + return new_abs_pos.permute(0, 2, 3, 1) + else: + return abs_pos.reshape(1, h, w, -1) + + +class PatchEmbed(nn.Module): + """ + Image to Patch Embedding. + """ + + def __init__( + self, kernel_size=(16, 16), stride=(16, 16), padding=(0, 0), in_chans=3, embed_dim=768 + ): + """ + Args: + kernel_size (Tuple): kernel size of the projection layer. + stride (Tuple): stride of the projection layer. + padding (Tuple): padding size of the projection layer. + in_chans (int): Number of input image channels. + embed_dim (int): embed_dim (int): Patch embedding dimension. + """ + super().__init__() + + self.proj = nn.Conv2d( + in_chans, embed_dim, kernel_size=kernel_size, stride=stride, padding=padding + ) + + def forward(self, x): + x = self.proj(x) + # B C H W -> B H W C + x = x.permute(0, 2, 3, 1) + return x diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/vit.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/vit.py new file mode 100644 index 00000000..07b5e207 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/backbone/vit.py @@ -0,0 +1,524 @@ +import logging +import math +import fvcore.nn.weight_init as weight_init +import torch +import torch.nn as nn + +from annotator.oneformer.detectron2.layers import CNNBlockBase, Conv2d, get_norm +from annotator.oneformer.detectron2.modeling.backbone.fpn import _assert_strides_are_log2_contiguous + +from .backbone import Backbone +from .utils import ( + PatchEmbed, + add_decomposed_rel_pos, + get_abs_pos, + window_partition, + window_unpartition, +) + +logger = logging.getLogger(__name__) + + +__all__ = ["ViT", "SimpleFeaturePyramid", "get_vit_lr_decay_rate"] + + +class Attention(nn.Module): + """Multi-head Attention block with relative position embeddings.""" + + def __init__( + self, + dim, + num_heads=8, + qkv_bias=True, + use_rel_pos=False, + rel_pos_zero_init=True, + input_size=None, + ): + """ + Args: + dim (int): Number of input channels. + num_heads (int): Number of attention heads. + qkv_bias (bool: If True, add a learnable bias to query, key, value. + rel_pos (bool): If True, add relative positional embeddings to the attention map. + rel_pos_zero_init (bool): If True, zero initialize relative positional parameters. + input_size (int or None): Input resolution for calculating the relative positional + parameter size. + """ + super().__init__() + self.num_heads = num_heads + head_dim = dim // num_heads + self.scale = head_dim**-0.5 + + self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias) + self.proj = nn.Linear(dim, dim) + + self.use_rel_pos = use_rel_pos + if self.use_rel_pos: + # initialize relative positional embeddings + self.rel_pos_h = nn.Parameter(torch.zeros(2 * input_size[0] - 1, head_dim)) + self.rel_pos_w = nn.Parameter(torch.zeros(2 * input_size[1] - 1, head_dim)) + + if not rel_pos_zero_init: + nn.init.trunc_normal_(self.rel_pos_h, std=0.02) + nn.init.trunc_normal_(self.rel_pos_w, std=0.02) + + def forward(self, x): + B, H, W, _ = x.shape + # qkv with shape (3, B, nHead, H * W, C) + qkv = self.qkv(x).reshape(B, H * W, 3, self.num_heads, -1).permute(2, 0, 3, 1, 4) + # q, k, v with shape (B * nHead, H * W, C) + q, k, v = qkv.reshape(3, B * self.num_heads, H * W, -1).unbind(0) + + attn = (q * self.scale) @ k.transpose(-2, -1) + + if self.use_rel_pos: + attn = add_decomposed_rel_pos(attn, q, self.rel_pos_h, self.rel_pos_w, (H, W), (H, W)) + + attn = attn.softmax(dim=-1) + x = (attn @ v).view(B, self.num_heads, H, W, -1).permute(0, 2, 3, 1, 4).reshape(B, H, W, -1) + x = self.proj(x) + + return x + + +class ResBottleneckBlock(CNNBlockBase): + """ + The standard bottleneck residual block without the last activation layer. + It contains 3 conv layers with kernels 1x1, 3x3, 1x1. + """ + + def __init__( + self, + in_channels, + out_channels, + bottleneck_channels, + norm="LN", + act_layer=nn.GELU, + ): + """ + Args: + in_channels (int): Number of input channels. + out_channels (int): Number of output channels. + bottleneck_channels (int): number of output channels for the 3x3 + "bottleneck" conv layers. + norm (str or callable): normalization for all conv layers. + See :func:`layers.get_norm` for supported format. + act_layer (callable): activation for all conv layers. + """ + super().__init__(in_channels, out_channels, 1) + + self.conv1 = Conv2d(in_channels, bottleneck_channels, 1, bias=False) + self.norm1 = get_norm(norm, bottleneck_channels) + self.act1 = act_layer() + + self.conv2 = Conv2d( + bottleneck_channels, + bottleneck_channels, + 3, + padding=1, + bias=False, + ) + self.norm2 = get_norm(norm, bottleneck_channels) + self.act2 = act_layer() + + self.conv3 = Conv2d(bottleneck_channels, out_channels, 1, bias=False) + self.norm3 = get_norm(norm, out_channels) + + for layer in [self.conv1, self.conv2, self.conv3]: + weight_init.c2_msra_fill(layer) + for layer in [self.norm1, self.norm2]: + layer.weight.data.fill_(1.0) + layer.bias.data.zero_() + # zero init last norm layer. + self.norm3.weight.data.zero_() + self.norm3.bias.data.zero_() + + def forward(self, x): + out = x + for layer in self.children(): + out = layer(out) + + out = x + out + return out + + +class Block(nn.Module): + """Transformer blocks with support of window attention and residual propagation blocks""" + + def __init__( + self, + dim, + num_heads, + mlp_ratio=4.0, + qkv_bias=True, + drop_path=0.0, + norm_layer=nn.LayerNorm, + act_layer=nn.GELU, + use_rel_pos=False, + rel_pos_zero_init=True, + window_size=0, + use_residual_block=False, + input_size=None, + ): + """ + Args: + dim (int): Number of input channels. + num_heads (int): Number of attention heads in each ViT block. + mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. + qkv_bias (bool): If True, add a learnable bias to query, key, value. + drop_path (float): Stochastic depth rate. + norm_layer (nn.Module): Normalization layer. + act_layer (nn.Module): Activation layer. + use_rel_pos (bool): If True, add relative positional embeddings to the attention map. + rel_pos_zero_init (bool): If True, zero initialize relative positional parameters. + window_size (int): Window size for window attention blocks. If it equals 0, then not + use window attention. + use_residual_block (bool): If True, use a residual block after the MLP block. + input_size (int or None): Input resolution for calculating the relative positional + parameter size. + """ + super().__init__() + self.norm1 = norm_layer(dim) + self.attn = Attention( + dim, + num_heads=num_heads, + qkv_bias=qkv_bias, + use_rel_pos=use_rel_pos, + rel_pos_zero_init=rel_pos_zero_init, + input_size=input_size if window_size == 0 else (window_size, window_size), + ) + + from timm.models.layers import DropPath, Mlp + + self.drop_path = DropPath(drop_path) if drop_path > 0.0 else nn.Identity() + self.norm2 = norm_layer(dim) + self.mlp = Mlp(in_features=dim, hidden_features=int(dim * mlp_ratio), act_layer=act_layer) + + self.window_size = window_size + + self.use_residual_block = use_residual_block + if use_residual_block: + # Use a residual block with bottleneck channel as dim // 2 + self.residual = ResBottleneckBlock( + in_channels=dim, + out_channels=dim, + bottleneck_channels=dim // 2, + norm="LN", + act_layer=act_layer, + ) + + def forward(self, x): + shortcut = x + x = self.norm1(x) + # Window partition + if self.window_size > 0: + H, W = x.shape[1], x.shape[2] + x, pad_hw = window_partition(x, self.window_size) + + x = self.attn(x) + # Reverse window partition + if self.window_size > 0: + x = window_unpartition(x, self.window_size, pad_hw, (H, W)) + + x = shortcut + self.drop_path(x) + x = x + self.drop_path(self.mlp(self.norm2(x))) + + if self.use_residual_block: + x = self.residual(x.permute(0, 3, 1, 2)).permute(0, 2, 3, 1) + + return x + + +class ViT(Backbone): + """ + This module implements Vision Transformer (ViT) backbone in :paper:`vitdet`. + "Exploring Plain Vision Transformer Backbones for Object Detection", + https://arxiv.org/abs/2203.16527 + """ + + def __init__( + self, + img_size=1024, + patch_size=16, + in_chans=3, + embed_dim=768, + depth=12, + num_heads=12, + mlp_ratio=4.0, + qkv_bias=True, + drop_path_rate=0.0, + norm_layer=nn.LayerNorm, + act_layer=nn.GELU, + use_abs_pos=True, + use_rel_pos=False, + rel_pos_zero_init=True, + window_size=0, + window_block_indexes=(), + residual_block_indexes=(), + use_act_checkpoint=False, + pretrain_img_size=224, + pretrain_use_cls_token=True, + out_feature="last_feat", + ): + """ + Args: + img_size (int): Input image size. + patch_size (int): Patch size. + in_chans (int): Number of input image channels. + embed_dim (int): Patch embedding dimension. + depth (int): Depth of ViT. + num_heads (int): Number of attention heads in each ViT block. + mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. + qkv_bias (bool): If True, add a learnable bias to query, key, value. + drop_path_rate (float): Stochastic depth rate. + norm_layer (nn.Module): Normalization layer. + act_layer (nn.Module): Activation layer. + use_abs_pos (bool): If True, use absolute positional embeddings. + use_rel_pos (bool): If True, add relative positional embeddings to the attention map. + rel_pos_zero_init (bool): If True, zero initialize relative positional parameters. + window_size (int): Window size for window attention blocks. + window_block_indexes (list): Indexes for blocks using window attention. + residual_block_indexes (list): Indexes for blocks using conv propagation. + use_act_checkpoint (bool): If True, use activation checkpointing. + pretrain_img_size (int): input image size for pretraining models. + pretrain_use_cls_token (bool): If True, pretrainig models use class token. + out_feature (str): name of the feature from the last block. + """ + super().__init__() + self.pretrain_use_cls_token = pretrain_use_cls_token + + self.patch_embed = PatchEmbed( + kernel_size=(patch_size, patch_size), + stride=(patch_size, patch_size), + in_chans=in_chans, + embed_dim=embed_dim, + ) + + if use_abs_pos: + # Initialize absolute positional embedding with pretrain image size. + num_patches = (pretrain_img_size // patch_size) * (pretrain_img_size // patch_size) + num_positions = (num_patches + 1) if pretrain_use_cls_token else num_patches + self.pos_embed = nn.Parameter(torch.zeros(1, num_positions, embed_dim)) + else: + self.pos_embed = None + + # stochastic depth decay rule + dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)] + + self.blocks = nn.ModuleList() + for i in range(depth): + block = Block( + dim=embed_dim, + num_heads=num_heads, + mlp_ratio=mlp_ratio, + qkv_bias=qkv_bias, + drop_path=dpr[i], + norm_layer=norm_layer, + act_layer=act_layer, + use_rel_pos=use_rel_pos, + rel_pos_zero_init=rel_pos_zero_init, + window_size=window_size if i in window_block_indexes else 0, + use_residual_block=i in residual_block_indexes, + input_size=(img_size // patch_size, img_size // patch_size), + ) + if use_act_checkpoint: + # TODO: use torch.utils.checkpoint + from fairscale.nn.checkpoint import checkpoint_wrapper + + block = checkpoint_wrapper(block) + self.blocks.append(block) + + self._out_feature_channels = {out_feature: embed_dim} + self._out_feature_strides = {out_feature: patch_size} + self._out_features = [out_feature] + + if self.pos_embed is not None: + nn.init.trunc_normal_(self.pos_embed, std=0.02) + + self.apply(self._init_weights) + + def _init_weights(self, m): + if isinstance(m, nn.Linear): + nn.init.trunc_normal_(m.weight, std=0.02) + if isinstance(m, nn.Linear) and m.bias is not None: + nn.init.constant_(m.bias, 0) + elif isinstance(m, nn.LayerNorm): + nn.init.constant_(m.bias, 0) + nn.init.constant_(m.weight, 1.0) + + def forward(self, x): + x = self.patch_embed(x) + if self.pos_embed is not None: + x = x + get_abs_pos( + self.pos_embed, self.pretrain_use_cls_token, (x.shape[1], x.shape[2]) + ) + + for blk in self.blocks: + x = blk(x) + + outputs = {self._out_features[0]: x.permute(0, 3, 1, 2)} + return outputs + + +class SimpleFeaturePyramid(Backbone): + """ + This module implements SimpleFeaturePyramid in :paper:`vitdet`. + It creates pyramid features built on top of the input feature map. + """ + + def __init__( + self, + net, + in_feature, + out_channels, + scale_factors, + top_block=None, + norm="LN", + square_pad=0, + ): + """ + Args: + net (Backbone): module representing the subnetwork backbone. + Must be a subclass of :class:`Backbone`. + in_feature (str): names of the input feature maps coming + from the net. + out_channels (int): number of channels in the output feature maps. + scale_factors (list[float]): list of scaling factors to upsample or downsample + the input features for creating pyramid features. + top_block (nn.Module or None): if provided, an extra operation will + be performed on the output of the last (smallest resolution) + pyramid output, and the result will extend the result list. The top_block + further downsamples the feature map. It must have an attribute + "num_levels", meaning the number of extra pyramid levels added by + this block, and "in_feature", which is a string representing + its input feature (e.g., p5). + norm (str): the normalization to use. + square_pad (int): If > 0, require input images to be padded to specific square size. + """ + super(SimpleFeaturePyramid, self).__init__() + assert isinstance(net, Backbone) + + self.scale_factors = scale_factors + + input_shapes = net.output_shape() + strides = [int(input_shapes[in_feature].stride / scale) for scale in scale_factors] + _assert_strides_are_log2_contiguous(strides) + + dim = input_shapes[in_feature].channels + self.stages = [] + use_bias = norm == "" + for idx, scale in enumerate(scale_factors): + out_dim = dim + if scale == 4.0: + layers = [ + nn.ConvTranspose2d(dim, dim // 2, kernel_size=2, stride=2), + get_norm(norm, dim // 2), + nn.GELU(), + nn.ConvTranspose2d(dim // 2, dim // 4, kernel_size=2, stride=2), + ] + out_dim = dim // 4 + elif scale == 2.0: + layers = [nn.ConvTranspose2d(dim, dim // 2, kernel_size=2, stride=2)] + out_dim = dim // 2 + elif scale == 1.0: + layers = [] + elif scale == 0.5: + layers = [nn.MaxPool2d(kernel_size=2, stride=2)] + else: + raise NotImplementedError(f"scale_factor={scale} is not supported yet.") + + layers.extend( + [ + Conv2d( + out_dim, + out_channels, + kernel_size=1, + bias=use_bias, + norm=get_norm(norm, out_channels), + ), + Conv2d( + out_channels, + out_channels, + kernel_size=3, + padding=1, + bias=use_bias, + norm=get_norm(norm, out_channels), + ), + ] + ) + layers = nn.Sequential(*layers) + + stage = int(math.log2(strides[idx])) + self.add_module(f"simfp_{stage}", layers) + self.stages.append(layers) + + self.net = net + self.in_feature = in_feature + self.top_block = top_block + # Return feature names are "p", like ["p2", "p3", ..., "p6"] + self._out_feature_strides = {"p{}".format(int(math.log2(s))): s for s in strides} + # top block output feature maps. + if self.top_block is not None: + for s in range(stage, stage + self.top_block.num_levels): + self._out_feature_strides["p{}".format(s + 1)] = 2 ** (s + 1) + + self._out_features = list(self._out_feature_strides.keys()) + self._out_feature_channels = {k: out_channels for k in self._out_features} + self._size_divisibility = strides[-1] + self._square_pad = square_pad + + @property + def padding_constraints(self): + return { + "size_divisiblity": self._size_divisibility, + "square_size": self._square_pad, + } + + def forward(self, x): + """ + Args: + x: Tensor of shape (N,C,H,W). H, W must be a multiple of ``self.size_divisibility``. + + Returns: + dict[str->Tensor]: + mapping from feature map name to pyramid feature map tensor + in high to low resolution order. Returned feature names follow the FPN + convention: "p", where stage has stride = 2 ** stage e.g., + ["p2", "p3", ..., "p6"]. + """ + bottom_up_features = self.net(x) + features = bottom_up_features[self.in_feature] + results = [] + + for stage in self.stages: + results.append(stage(features)) + + if self.top_block is not None: + if self.top_block.in_feature in bottom_up_features: + top_block_in_feature = bottom_up_features[self.top_block.in_feature] + else: + top_block_in_feature = results[self._out_features.index(self.top_block.in_feature)] + results.extend(self.top_block(top_block_in_feature)) + assert len(self._out_features) == len(results) + return {f: res for f, res in zip(self._out_features, results)} + + +def get_vit_lr_decay_rate(name, lr_decay_rate=1.0, num_layers=12): + """ + Calculate lr decay rate for different ViT blocks. + Args: + name (string): parameter name. + lr_decay_rate (float): base lr decay rate. + num_layers (int): number of ViT blocks. + + Returns: + lr decay rate for the given parameter. + """ + layer_id = num_layers + 1 + if name.startswith("backbone"): + if ".pos_embed" in name or ".patch_embed" in name: + layer_id = 0 + elif ".blocks." in name and ".residual." not in name: + layer_id = int(name[name.find(".blocks.") :].split(".")[2]) + 1 + + return lr_decay_rate ** (num_layers + 1 - layer_id) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/box_regression.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/box_regression.py new file mode 100644 index 00000000..3cd5668d --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/box_regression.py @@ -0,0 +1,369 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import math +from typing import List, Tuple, Union +import torch +from fvcore.nn import giou_loss, smooth_l1_loss +from torch.nn import functional as F + +from annotator.oneformer.detectron2.layers import cat, ciou_loss, diou_loss +from annotator.oneformer.detectron2.structures import Boxes + +# Value for clamping large dw and dh predictions. The heuristic is that we clamp +# such that dw and dh are no larger than what would transform a 16px box into a +# 1000px box (based on a small anchor, 16px, and a typical image size, 1000px). +_DEFAULT_SCALE_CLAMP = math.log(1000.0 / 16) + + +__all__ = ["Box2BoxTransform", "Box2BoxTransformRotated", "Box2BoxTransformLinear"] + + +@torch.jit.script +class Box2BoxTransform(object): + """ + The box-to-box transform defined in R-CNN. The transformation is parameterized + by 4 deltas: (dx, dy, dw, dh). The transformation scales the box's width and height + by exp(dw), exp(dh) and shifts a box's center by the offset (dx * width, dy * height). + """ + + def __init__( + self, weights: Tuple[float, float, float, float], scale_clamp: float = _DEFAULT_SCALE_CLAMP + ): + """ + Args: + weights (4-element tuple): Scaling factors that are applied to the + (dx, dy, dw, dh) deltas. In Fast R-CNN, these were originally set + such that the deltas have unit variance; now they are treated as + hyperparameters of the system. + scale_clamp (float): When predicting deltas, the predicted box scaling + factors (dw and dh) are clamped such that they are <= scale_clamp. + """ + self.weights = weights + self.scale_clamp = scale_clamp + + def get_deltas(self, src_boxes, target_boxes): + """ + Get box regression transformation deltas (dx, dy, dw, dh) that can be used + to transform the `src_boxes` into the `target_boxes`. That is, the relation + ``target_boxes == self.apply_deltas(deltas, src_boxes)`` is true (unless + any delta is too large and is clamped). + + Args: + src_boxes (Tensor): source boxes, e.g., object proposals + target_boxes (Tensor): target of the transformation, e.g., ground-truth + boxes. + """ + assert isinstance(src_boxes, torch.Tensor), type(src_boxes) + assert isinstance(target_boxes, torch.Tensor), type(target_boxes) + + src_widths = src_boxes[:, 2] - src_boxes[:, 0] + src_heights = src_boxes[:, 3] - src_boxes[:, 1] + src_ctr_x = src_boxes[:, 0] + 0.5 * src_widths + src_ctr_y = src_boxes[:, 1] + 0.5 * src_heights + + target_widths = target_boxes[:, 2] - target_boxes[:, 0] + target_heights = target_boxes[:, 3] - target_boxes[:, 1] + target_ctr_x = target_boxes[:, 0] + 0.5 * target_widths + target_ctr_y = target_boxes[:, 1] + 0.5 * target_heights + + wx, wy, ww, wh = self.weights + dx = wx * (target_ctr_x - src_ctr_x) / src_widths + dy = wy * (target_ctr_y - src_ctr_y) / src_heights + dw = ww * torch.log(target_widths / src_widths) + dh = wh * torch.log(target_heights / src_heights) + + deltas = torch.stack((dx, dy, dw, dh), dim=1) + assert (src_widths > 0).all().item(), "Input boxes to Box2BoxTransform are not valid!" + return deltas + + def apply_deltas(self, deltas, boxes): + """ + Apply transformation `deltas` (dx, dy, dw, dh) to `boxes`. + + Args: + deltas (Tensor): transformation deltas of shape (N, k*4), where k >= 1. + deltas[i] represents k potentially different class-specific + box transformations for the single box boxes[i]. + boxes (Tensor): boxes to transform, of shape (N, 4) + """ + deltas = deltas.float() # ensure fp32 for decoding precision + boxes = boxes.to(deltas.dtype) + + widths = boxes[:, 2] - boxes[:, 0] + heights = boxes[:, 3] - boxes[:, 1] + ctr_x = boxes[:, 0] + 0.5 * widths + ctr_y = boxes[:, 1] + 0.5 * heights + + wx, wy, ww, wh = self.weights + dx = deltas[:, 0::4] / wx + dy = deltas[:, 1::4] / wy + dw = deltas[:, 2::4] / ww + dh = deltas[:, 3::4] / wh + + # Prevent sending too large values into torch.exp() + dw = torch.clamp(dw, max=self.scale_clamp) + dh = torch.clamp(dh, max=self.scale_clamp) + + pred_ctr_x = dx * widths[:, None] + ctr_x[:, None] + pred_ctr_y = dy * heights[:, None] + ctr_y[:, None] + pred_w = torch.exp(dw) * widths[:, None] + pred_h = torch.exp(dh) * heights[:, None] + + x1 = pred_ctr_x - 0.5 * pred_w + y1 = pred_ctr_y - 0.5 * pred_h + x2 = pred_ctr_x + 0.5 * pred_w + y2 = pred_ctr_y + 0.5 * pred_h + pred_boxes = torch.stack((x1, y1, x2, y2), dim=-1) + return pred_boxes.reshape(deltas.shape) + + +@torch.jit.script +class Box2BoxTransformRotated(object): + """ + The box-to-box transform defined in Rotated R-CNN. The transformation is parameterized + by 5 deltas: (dx, dy, dw, dh, da). The transformation scales the box's width and height + by exp(dw), exp(dh), shifts a box's center by the offset (dx * width, dy * height), + and rotate a box's angle by da (radians). + Note: angles of deltas are in radians while angles of boxes are in degrees. + """ + + def __init__( + self, + weights: Tuple[float, float, float, float, float], + scale_clamp: float = _DEFAULT_SCALE_CLAMP, + ): + """ + Args: + weights (5-element tuple): Scaling factors that are applied to the + (dx, dy, dw, dh, da) deltas. These are treated as + hyperparameters of the system. + scale_clamp (float): When predicting deltas, the predicted box scaling + factors (dw and dh) are clamped such that they are <= scale_clamp. + """ + self.weights = weights + self.scale_clamp = scale_clamp + + def get_deltas(self, src_boxes, target_boxes): + """ + Get box regression transformation deltas (dx, dy, dw, dh, da) that can be used + to transform the `src_boxes` into the `target_boxes`. That is, the relation + ``target_boxes == self.apply_deltas(deltas, src_boxes)`` is true (unless + any delta is too large and is clamped). + + Args: + src_boxes (Tensor): Nx5 source boxes, e.g., object proposals + target_boxes (Tensor): Nx5 target of the transformation, e.g., ground-truth + boxes. + """ + assert isinstance(src_boxes, torch.Tensor), type(src_boxes) + assert isinstance(target_boxes, torch.Tensor), type(target_boxes) + + src_ctr_x, src_ctr_y, src_widths, src_heights, src_angles = torch.unbind(src_boxes, dim=1) + + target_ctr_x, target_ctr_y, target_widths, target_heights, target_angles = torch.unbind( + target_boxes, dim=1 + ) + + wx, wy, ww, wh, wa = self.weights + dx = wx * (target_ctr_x - src_ctr_x) / src_widths + dy = wy * (target_ctr_y - src_ctr_y) / src_heights + dw = ww * torch.log(target_widths / src_widths) + dh = wh * torch.log(target_heights / src_heights) + # Angles of deltas are in radians while angles of boxes are in degrees. + # the conversion to radians serve as a way to normalize the values + da = target_angles - src_angles + da = (da + 180.0) % 360.0 - 180.0 # make it in [-180, 180) + da *= wa * math.pi / 180.0 + + deltas = torch.stack((dx, dy, dw, dh, da), dim=1) + assert ( + (src_widths > 0).all().item() + ), "Input boxes to Box2BoxTransformRotated are not valid!" + return deltas + + def apply_deltas(self, deltas, boxes): + """ + Apply transformation `deltas` (dx, dy, dw, dh, da) to `boxes`. + + Args: + deltas (Tensor): transformation deltas of shape (N, k*5). + deltas[i] represents box transformation for the single box boxes[i]. + boxes (Tensor): boxes to transform, of shape (N, 5) + """ + assert deltas.shape[1] % 5 == 0 and boxes.shape[1] == 5 + + boxes = boxes.to(deltas.dtype).unsqueeze(2) + + ctr_x = boxes[:, 0] + ctr_y = boxes[:, 1] + widths = boxes[:, 2] + heights = boxes[:, 3] + angles = boxes[:, 4] + + wx, wy, ww, wh, wa = self.weights + + dx = deltas[:, 0::5] / wx + dy = deltas[:, 1::5] / wy + dw = deltas[:, 2::5] / ww + dh = deltas[:, 3::5] / wh + da = deltas[:, 4::5] / wa + + # Prevent sending too large values into torch.exp() + dw = torch.clamp(dw, max=self.scale_clamp) + dh = torch.clamp(dh, max=self.scale_clamp) + + pred_boxes = torch.zeros_like(deltas) + pred_boxes[:, 0::5] = dx * widths + ctr_x # x_ctr + pred_boxes[:, 1::5] = dy * heights + ctr_y # y_ctr + pred_boxes[:, 2::5] = torch.exp(dw) * widths # width + pred_boxes[:, 3::5] = torch.exp(dh) * heights # height + + # Following original RRPN implementation, + # angles of deltas are in radians while angles of boxes are in degrees. + pred_angle = da * 180.0 / math.pi + angles + pred_angle = (pred_angle + 180.0) % 360.0 - 180.0 # make it in [-180, 180) + + pred_boxes[:, 4::5] = pred_angle + + return pred_boxes + + +class Box2BoxTransformLinear(object): + """ + The linear box-to-box transform defined in FCOS. The transformation is parameterized + by the distance from the center of (square) src box to 4 edges of the target box. + """ + + def __init__(self, normalize_by_size=True): + """ + Args: + normalize_by_size: normalize deltas by the size of src (anchor) boxes. + """ + self.normalize_by_size = normalize_by_size + + def get_deltas(self, src_boxes, target_boxes): + """ + Get box regression transformation deltas (dx1, dy1, dx2, dy2) that can be used + to transform the `src_boxes` into the `target_boxes`. That is, the relation + ``target_boxes == self.apply_deltas(deltas, src_boxes)`` is true. + The center of src must be inside target boxes. + + Args: + src_boxes (Tensor): square source boxes, e.g., anchors + target_boxes (Tensor): target of the transformation, e.g., ground-truth + boxes. + """ + assert isinstance(src_boxes, torch.Tensor), type(src_boxes) + assert isinstance(target_boxes, torch.Tensor), type(target_boxes) + + src_ctr_x = 0.5 * (src_boxes[:, 0] + src_boxes[:, 2]) + src_ctr_y = 0.5 * (src_boxes[:, 1] + src_boxes[:, 3]) + + target_l = src_ctr_x - target_boxes[:, 0] + target_t = src_ctr_y - target_boxes[:, 1] + target_r = target_boxes[:, 2] - src_ctr_x + target_b = target_boxes[:, 3] - src_ctr_y + + deltas = torch.stack((target_l, target_t, target_r, target_b), dim=1) + if self.normalize_by_size: + stride_w = src_boxes[:, 2] - src_boxes[:, 0] + stride_h = src_boxes[:, 3] - src_boxes[:, 1] + strides = torch.stack([stride_w, stride_h, stride_w, stride_h], axis=1) + deltas = deltas / strides + + return deltas + + def apply_deltas(self, deltas, boxes): + """ + Apply transformation `deltas` (dx1, dy1, dx2, dy2) to `boxes`. + + Args: + deltas (Tensor): transformation deltas of shape (N, k*4), where k >= 1. + deltas[i] represents k potentially different class-specific + box transformations for the single box boxes[i]. + boxes (Tensor): boxes to transform, of shape (N, 4) + """ + # Ensure the output is a valid box. See Sec 2.1 of https://arxiv.org/abs/2006.09214 + deltas = F.relu(deltas) + boxes = boxes.to(deltas.dtype) + + ctr_x = 0.5 * (boxes[:, 0] + boxes[:, 2]) + ctr_y = 0.5 * (boxes[:, 1] + boxes[:, 3]) + if self.normalize_by_size: + stride_w = boxes[:, 2] - boxes[:, 0] + stride_h = boxes[:, 3] - boxes[:, 1] + strides = torch.stack([stride_w, stride_h, stride_w, stride_h], axis=1) + deltas = deltas * strides + + l = deltas[:, 0::4] + t = deltas[:, 1::4] + r = deltas[:, 2::4] + b = deltas[:, 3::4] + + pred_boxes = torch.zeros_like(deltas) + pred_boxes[:, 0::4] = ctr_x[:, None] - l # x1 + pred_boxes[:, 1::4] = ctr_y[:, None] - t # y1 + pred_boxes[:, 2::4] = ctr_x[:, None] + r # x2 + pred_boxes[:, 3::4] = ctr_y[:, None] + b # y2 + return pred_boxes + + +def _dense_box_regression_loss( + anchors: List[Union[Boxes, torch.Tensor]], + box2box_transform: Box2BoxTransform, + pred_anchor_deltas: List[torch.Tensor], + gt_boxes: List[torch.Tensor], + fg_mask: torch.Tensor, + box_reg_loss_type="smooth_l1", + smooth_l1_beta=0.0, +): + """ + Compute loss for dense multi-level box regression. + Loss is accumulated over ``fg_mask``. + + Args: + anchors: #lvl anchor boxes, each is (HixWixA, 4) + pred_anchor_deltas: #lvl predictions, each is (N, HixWixA, 4) + gt_boxes: N ground truth boxes, each has shape (R, 4) (R = sum(Hi * Wi * A)) + fg_mask: the foreground boolean mask of shape (N, R) to compute loss on + box_reg_loss_type (str): Loss type to use. Supported losses: "smooth_l1", "giou", + "diou", "ciou". + smooth_l1_beta (float): beta parameter for the smooth L1 regression loss. Default to + use L1 loss. Only used when `box_reg_loss_type` is "smooth_l1" + """ + if isinstance(anchors[0], Boxes): + anchors = type(anchors[0]).cat(anchors).tensor # (R, 4) + else: + anchors = cat(anchors) + if box_reg_loss_type == "smooth_l1": + gt_anchor_deltas = [box2box_transform.get_deltas(anchors, k) for k in gt_boxes] + gt_anchor_deltas = torch.stack(gt_anchor_deltas) # (N, R, 4) + loss_box_reg = smooth_l1_loss( + cat(pred_anchor_deltas, dim=1)[fg_mask], + gt_anchor_deltas[fg_mask], + beta=smooth_l1_beta, + reduction="sum", + ) + elif box_reg_loss_type == "giou": + pred_boxes = [ + box2box_transform.apply_deltas(k, anchors) for k in cat(pred_anchor_deltas, dim=1) + ] + loss_box_reg = giou_loss( + torch.stack(pred_boxes)[fg_mask], torch.stack(gt_boxes)[fg_mask], reduction="sum" + ) + elif box_reg_loss_type == "diou": + pred_boxes = [ + box2box_transform.apply_deltas(k, anchors) for k in cat(pred_anchor_deltas, dim=1) + ] + loss_box_reg = diou_loss( + torch.stack(pred_boxes)[fg_mask], torch.stack(gt_boxes)[fg_mask], reduction="sum" + ) + elif box_reg_loss_type == "ciou": + pred_boxes = [ + box2box_transform.apply_deltas(k, anchors) for k in cat(pred_anchor_deltas, dim=1) + ] + loss_box_reg = ciou_loss( + torch.stack(pred_boxes)[fg_mask], torch.stack(gt_boxes)[fg_mask], reduction="sum" + ) + else: + raise ValueError(f"Invalid dense box regression loss type '{box_reg_loss_type}'") + return loss_box_reg diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/matcher.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/matcher.py new file mode 100644 index 00000000..2504d17a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/matcher.py @@ -0,0 +1,127 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from typing import List +import torch + +from annotator.oneformer.detectron2.layers import nonzero_tuple + + +# TODO: the name is too general +class Matcher(object): + """ + This class assigns to each predicted "element" (e.g., a box) a ground-truth + element. Each predicted element will have exactly zero or one matches; each + ground-truth element may be matched to zero or more predicted elements. + + The matching is determined by the MxN match_quality_matrix, that characterizes + how well each (ground-truth, prediction)-pair match each other. For example, + if the elements are boxes, this matrix may contain box intersection-over-union + overlap values. + + The matcher returns (a) a vector of length N containing the index of the + ground-truth element m in [0, M) that matches to prediction n in [0, N). + (b) a vector of length N containing the labels for each prediction. + """ + + def __init__( + self, thresholds: List[float], labels: List[int], allow_low_quality_matches: bool = False + ): + """ + Args: + thresholds (list): a list of thresholds used to stratify predictions + into levels. + labels (list): a list of values to label predictions belonging at + each level. A label can be one of {-1, 0, 1} signifying + {ignore, negative class, positive class}, respectively. + allow_low_quality_matches (bool): if True, produce additional matches + for predictions with maximum match quality lower than high_threshold. + See set_low_quality_matches_ for more details. + + For example, + thresholds = [0.3, 0.5] + labels = [0, -1, 1] + All predictions with iou < 0.3 will be marked with 0 and + thus will be considered as false positives while training. + All predictions with 0.3 <= iou < 0.5 will be marked with -1 and + thus will be ignored. + All predictions with 0.5 <= iou will be marked with 1 and + thus will be considered as true positives. + """ + # Add -inf and +inf to first and last position in thresholds + thresholds = thresholds[:] + assert thresholds[0] > 0 + thresholds.insert(0, -float("inf")) + thresholds.append(float("inf")) + # Currently torchscript does not support all + generator + assert all([low <= high for (low, high) in zip(thresholds[:-1], thresholds[1:])]) + assert all([l in [-1, 0, 1] for l in labels]) + assert len(labels) == len(thresholds) - 1 + self.thresholds = thresholds + self.labels = labels + self.allow_low_quality_matches = allow_low_quality_matches + + def __call__(self, match_quality_matrix): + """ + Args: + match_quality_matrix (Tensor[float]): an MxN tensor, containing the + pairwise quality between M ground-truth elements and N predicted + elements. All elements must be >= 0 (due to the us of `torch.nonzero` + for selecting indices in :meth:`set_low_quality_matches_`). + + Returns: + matches (Tensor[int64]): a vector of length N, where matches[i] is a matched + ground-truth index in [0, M) + match_labels (Tensor[int8]): a vector of length N, where pred_labels[i] indicates + whether a prediction is a true or false positive or ignored + """ + assert match_quality_matrix.dim() == 2 + if match_quality_matrix.numel() == 0: + default_matches = match_quality_matrix.new_full( + (match_quality_matrix.size(1),), 0, dtype=torch.int64 + ) + # When no gt boxes exist, we define IOU = 0 and therefore set labels + # to `self.labels[0]`, which usually defaults to background class 0 + # To choose to ignore instead, can make labels=[-1,0,-1,1] + set appropriate thresholds + default_match_labels = match_quality_matrix.new_full( + (match_quality_matrix.size(1),), self.labels[0], dtype=torch.int8 + ) + return default_matches, default_match_labels + + assert torch.all(match_quality_matrix >= 0) + + # match_quality_matrix is M (gt) x N (predicted) + # Max over gt elements (dim 0) to find best gt candidate for each prediction + matched_vals, matches = match_quality_matrix.max(dim=0) + + match_labels = matches.new_full(matches.size(), 1, dtype=torch.int8) + + for (l, low, high) in zip(self.labels, self.thresholds[:-1], self.thresholds[1:]): + low_high = (matched_vals >= low) & (matched_vals < high) + match_labels[low_high] = l + + if self.allow_low_quality_matches: + self.set_low_quality_matches_(match_labels, match_quality_matrix) + + return matches, match_labels + + def set_low_quality_matches_(self, match_labels, match_quality_matrix): + """ + Produce additional matches for predictions that have only low-quality matches. + Specifically, for each ground-truth G find the set of predictions that have + maximum overlap with it (including ties); for each prediction in that set, if + it is unmatched, then match it to the ground-truth G. + + This function implements the RPN assignment case (i) in Sec. 3.1.2 of + :paper:`Faster R-CNN`. + """ + # For each gt, find the prediction with which it has highest quality + highest_quality_foreach_gt, _ = match_quality_matrix.max(dim=1) + # Find the highest quality match available, even if it is low, including ties. + # Note that the matches qualities must be positive due to the use of + # `torch.nonzero`. + _, pred_inds_with_highest_quality = nonzero_tuple( + match_quality_matrix == highest_quality_foreach_gt[:, None] + ) + # If an anchor was labeled positive only due to a low-quality match + # with gt_A, but it has larger overlap with gt_B, it's matched index will still be gt_B. + # This follows the implementation in Detectron, and is found to have no significant impact. + match_labels[pred_inds_with_highest_quality] = 1 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/__init__.py new file mode 100644 index 00000000..6b066815 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/__init__.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +from .build import META_ARCH_REGISTRY, build_model # isort:skip + +from .panoptic_fpn import PanopticFPN + +# import all the meta_arch, so they will be registered +from .rcnn import GeneralizedRCNN, ProposalNetwork +from .dense_detector import DenseDetector +from .retinanet import RetinaNet +from .fcos import FCOS +from .semantic_seg import SEM_SEG_HEADS_REGISTRY, SemanticSegmentor, build_sem_seg_head + + +__all__ = list(globals().keys()) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/build.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/build.py new file mode 100644 index 00000000..52229b11 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/build.py @@ -0,0 +1,24 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import torch + +from annotator.oneformer.detectron2.utils.logger import _log_api_usage +from annotator.oneformer.detectron2.utils.registry import Registry + +META_ARCH_REGISTRY = Registry("META_ARCH") # noqa F401 isort:skip +META_ARCH_REGISTRY.__doc__ = """ +Registry for meta-architectures, i.e. the whole model. + +The registered object will be called with `obj(cfg)` +and expected to return a `nn.Module` object. +""" + + +def build_model(cfg): + """ + Build the whole model architecture, defined by ``cfg.MODEL.META_ARCHITECTURE``. + Note that it does not load any weights from ``cfg``. + """ + meta_arch = cfg.MODEL.META_ARCHITECTURE + model = META_ARCH_REGISTRY.get(meta_arch)(cfg) + _log_api_usage("modeling.meta_arch." + meta_arch) + return model diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/dense_detector.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/dense_detector.py new file mode 100644 index 00000000..461c370f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/dense_detector.py @@ -0,0 +1,294 @@ +import numpy as np +from typing import Dict, List, Optional, Tuple +import torch +from torch import Tensor, nn + +from annotator.oneformer.detectron2.data.detection_utils import convert_image_to_rgb +from annotator.oneformer.detectron2.layers import move_device_like +from annotator.oneformer.detectron2.modeling import Backbone +from annotator.oneformer.detectron2.structures import Boxes, ImageList, Instances +from annotator.oneformer.detectron2.utils.events import get_event_storage + +from ..postprocessing import detector_postprocess + + +def permute_to_N_HWA_K(tensor, K: int): + """ + Transpose/reshape a tensor from (N, (Ai x K), H, W) to (N, (HxWxAi), K) + """ + assert tensor.dim() == 4, tensor.shape + N, _, H, W = tensor.shape + tensor = tensor.view(N, -1, K, H, W) + tensor = tensor.permute(0, 3, 4, 1, 2) + tensor = tensor.reshape(N, -1, K) # Size=(N,HWA,K) + return tensor + + +class DenseDetector(nn.Module): + """ + Base class for dense detector. We define a dense detector as a fully-convolutional model that + makes per-pixel (i.e. dense) predictions. + """ + + def __init__( + self, + backbone: Backbone, + head: nn.Module, + head_in_features: Optional[List[str]] = None, + *, + pixel_mean, + pixel_std, + ): + """ + Args: + backbone: backbone module + head: head module + head_in_features: backbone features to use in head. Default to all backbone features. + pixel_mean (Tuple[float]): + Values to be used for image normalization (BGR order). + To train on images of different number of channels, set different mean & std. + Default values are the mean pixel value from ImageNet: [103.53, 116.28, 123.675] + pixel_std (Tuple[float]): + When using pre-trained models in Detectron1 or any MSRA models, + std has been absorbed into its conv1 weights, so the std needs to be set 1. + Otherwise, you can use [57.375, 57.120, 58.395] (ImageNet std) + """ + super().__init__() + + self.backbone = backbone + self.head = head + if head_in_features is None: + shapes = self.backbone.output_shape() + self.head_in_features = sorted(shapes.keys(), key=lambda x: shapes[x].stride) + else: + self.head_in_features = head_in_features + self.register_buffer("pixel_mean", torch.tensor(pixel_mean).view(-1, 1, 1), False) + self.register_buffer("pixel_std", torch.tensor(pixel_std).view(-1, 1, 1), False) + + @property + def device(self): + return self.pixel_mean.device + + def _move_to_current_device(self, x): + return move_device_like(x, self.pixel_mean) + + def forward(self, batched_inputs: List[Dict[str, Tensor]]): + """ + Args: + batched_inputs: a list, batched outputs of :class:`DatasetMapper` . + Each item in the list contains the inputs for one image. + For now, each item in the list is a dict that contains: + + * image: Tensor, image in (C, H, W) format. + * instances: Instances + + Other information that's included in the original dicts, such as: + + * "height", "width" (int): the output resolution of the model, used in inference. + See :meth:`postprocess` for details. + + Returns: + In training, dict[str, Tensor]: mapping from a named loss to a tensor storing the + loss. Used during training only. In inference, the standard output format, described + in :doc:`/tutorials/models`. + """ + images = self.preprocess_image(batched_inputs) + features = self.backbone(images.tensor) + features = [features[f] for f in self.head_in_features] + predictions = self.head(features) + + if self.training: + assert not torch.jit.is_scripting(), "Not supported" + assert "instances" in batched_inputs[0], "Instance annotations are missing in training!" + gt_instances = [x["instances"].to(self.device) for x in batched_inputs] + return self.forward_training(images, features, predictions, gt_instances) + else: + results = self.forward_inference(images, features, predictions) + if torch.jit.is_scripting(): + return results + + processed_results = [] + for results_per_image, input_per_image, image_size in zip( + results, batched_inputs, images.image_sizes + ): + height = input_per_image.get("height", image_size[0]) + width = input_per_image.get("width", image_size[1]) + r = detector_postprocess(results_per_image, height, width) + processed_results.append({"instances": r}) + return processed_results + + def forward_training(self, images, features, predictions, gt_instances): + raise NotImplementedError() + + def preprocess_image(self, batched_inputs: List[Dict[str, Tensor]]): + """ + Normalize, pad and batch the input images. + """ + images = [self._move_to_current_device(x["image"]) for x in batched_inputs] + images = [(x - self.pixel_mean) / self.pixel_std for x in images] + images = ImageList.from_tensors( + images, + self.backbone.size_divisibility, + padding_constraints=self.backbone.padding_constraints, + ) + return images + + def _transpose_dense_predictions( + self, predictions: List[List[Tensor]], dims_per_anchor: List[int] + ) -> List[List[Tensor]]: + """ + Transpose the dense per-level predictions. + + Args: + predictions: a list of outputs, each is a list of per-level + predictions with shape (N, Ai x K, Hi, Wi), where N is the + number of images, Ai is the number of anchors per location on + level i, K is the dimension of predictions per anchor. + dims_per_anchor: the value of K for each predictions. e.g. 4 for + box prediction, #classes for classification prediction. + + Returns: + List[List[Tensor]]: each prediction is transposed to (N, Hi x Wi x Ai, K). + """ + assert len(predictions) == len(dims_per_anchor) + res: List[List[Tensor]] = [] + for pred, dim_per_anchor in zip(predictions, dims_per_anchor): + pred = [permute_to_N_HWA_K(x, dim_per_anchor) for x in pred] + res.append(pred) + return res + + def _ema_update(self, name: str, value: float, initial_value: float, momentum: float = 0.9): + """ + Apply EMA update to `self.name` using `value`. + + This is mainly used for loss normalizer. In Detectron1, loss is normalized by number + of foreground samples in the batch. When batch size is 1 per GPU, #foreground has a + large variance and using it lead to lower performance. Therefore we maintain an EMA of + #foreground to stabilize the normalizer. + + Args: + name: name of the normalizer + value: the new value to update + initial_value: the initial value to start with + momentum: momentum of EMA + + Returns: + float: the updated EMA value + """ + if hasattr(self, name): + old = getattr(self, name) + else: + old = initial_value + new = old * momentum + value * (1 - momentum) + setattr(self, name, new) + return new + + def _decode_per_level_predictions( + self, + anchors: Boxes, + pred_scores: Tensor, + pred_deltas: Tensor, + score_thresh: float, + topk_candidates: int, + image_size: Tuple[int, int], + ) -> Instances: + """ + Decode boxes and classification predictions of one featuer level, by + the following steps: + 1. filter the predictions based on score threshold and top K scores. + 2. transform the box regression outputs + 3. return the predicted scores, classes and boxes + + Args: + anchors: Boxes, anchor for this feature level + pred_scores: HxWxA,K + pred_deltas: HxWxA,4 + + Returns: + Instances: with field "scores", "pred_boxes", "pred_classes". + """ + # Apply two filtering to make NMS faster. + # 1. Keep boxes with confidence score higher than threshold + keep_idxs = pred_scores > score_thresh + pred_scores = pred_scores[keep_idxs] + topk_idxs = torch.nonzero(keep_idxs) # Kx2 + + # 2. Keep top k top scoring boxes only + topk_idxs_size = topk_idxs.shape[0] + if isinstance(topk_idxs_size, Tensor): + # It's a tensor in tracing + num_topk = torch.clamp(topk_idxs_size, max=topk_candidates) + else: + num_topk = min(topk_idxs_size, topk_candidates) + pred_scores, idxs = pred_scores.topk(num_topk) + topk_idxs = topk_idxs[idxs] + + anchor_idxs, classes_idxs = topk_idxs.unbind(dim=1) + + pred_boxes = self.box2box_transform.apply_deltas( + pred_deltas[anchor_idxs], anchors.tensor[anchor_idxs] + ) + return Instances( + image_size, pred_boxes=Boxes(pred_boxes), scores=pred_scores, pred_classes=classes_idxs + ) + + def _decode_multi_level_predictions( + self, + anchors: List[Boxes], + pred_scores: List[Tensor], + pred_deltas: List[Tensor], + score_thresh: float, + topk_candidates: int, + image_size: Tuple[int, int], + ) -> Instances: + """ + Run `_decode_per_level_predictions` for all feature levels and concat the results. + """ + predictions = [ + self._decode_per_level_predictions( + anchors_i, + box_cls_i, + box_reg_i, + self.test_score_thresh, + self.test_topk_candidates, + image_size, + ) + # Iterate over every feature level + for box_cls_i, box_reg_i, anchors_i in zip(pred_scores, pred_deltas, anchors) + ] + return predictions[0].cat(predictions) # 'Instances.cat' is not scriptale but this is + + def visualize_training(self, batched_inputs, results): + """ + A function used to visualize ground truth images and final network predictions. + It shows ground truth bounding boxes on the original image and up to 20 + predicted object bounding boxes on the original image. + + Args: + batched_inputs (list): a list that contains input to the model. + results (List[Instances]): a list of #images elements returned by forward_inference(). + """ + from annotator.oneformer.detectron2.utils.visualizer import Visualizer + + assert len(batched_inputs) == len( + results + ), "Cannot visualize inputs and results of different sizes" + storage = get_event_storage() + max_boxes = 20 + + image_index = 0 # only visualize a single image + img = batched_inputs[image_index]["image"] + img = convert_image_to_rgb(img.permute(1, 2, 0), self.input_format) + v_gt = Visualizer(img, None) + v_gt = v_gt.overlay_instances(boxes=batched_inputs[image_index]["instances"].gt_boxes) + anno_img = v_gt.get_image() + processed_results = detector_postprocess(results[image_index], img.shape[0], img.shape[1]) + predicted_boxes = processed_results.pred_boxes.tensor.detach().cpu().numpy() + + v_pred = Visualizer(img, None) + v_pred = v_pred.overlay_instances(boxes=predicted_boxes[0:max_boxes]) + prop_img = v_pred.get_image() + vis_img = np.vstack((anno_img, prop_img)) + vis_img = vis_img.transpose(2, 0, 1) + vis_name = f"Top: GT bounding boxes; Bottom: {max_boxes} Highest Scoring Results" + storage.put_image(vis_name, vis_img) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/fcos.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/fcos.py new file mode 100644 index 00000000..150726a4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/fcos.py @@ -0,0 +1,328 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +import logging +from typing import List, Optional, Tuple +import torch +from fvcore.nn import sigmoid_focal_loss_jit +from torch import nn +from torch.nn import functional as F + +from annotator.oneformer.detectron2.layers import ShapeSpec, batched_nms +from annotator.oneformer.detectron2.structures import Boxes, ImageList, Instances, pairwise_point_box_distance +from annotator.oneformer.detectron2.utils.events import get_event_storage + +from ..anchor_generator import DefaultAnchorGenerator +from ..backbone import Backbone +from ..box_regression import Box2BoxTransformLinear, _dense_box_regression_loss +from .dense_detector import DenseDetector +from .retinanet import RetinaNetHead + +__all__ = ["FCOS"] + +logger = logging.getLogger(__name__) + + +class FCOS(DenseDetector): + """ + Implement FCOS in :paper:`fcos`. + """ + + def __init__( + self, + *, + backbone: Backbone, + head: nn.Module, + head_in_features: Optional[List[str]] = None, + box2box_transform=None, + num_classes, + center_sampling_radius: float = 1.5, + focal_loss_alpha=0.25, + focal_loss_gamma=2.0, + test_score_thresh=0.2, + test_topk_candidates=1000, + test_nms_thresh=0.6, + max_detections_per_image=100, + pixel_mean, + pixel_std, + ): + """ + Args: + center_sampling_radius: radius of the "center" of a groundtruth box, + within which all anchor points are labeled positive. + Other arguments mean the same as in :class:`RetinaNet`. + """ + super().__init__( + backbone, head, head_in_features, pixel_mean=pixel_mean, pixel_std=pixel_std + ) + + self.num_classes = num_classes + + # FCOS uses one anchor point per location. + # We represent the anchor point by a box whose size equals the anchor stride. + feature_shapes = backbone.output_shape() + fpn_strides = [feature_shapes[k].stride for k in self.head_in_features] + self.anchor_generator = DefaultAnchorGenerator( + sizes=[[k] for k in fpn_strides], aspect_ratios=[1.0], strides=fpn_strides + ) + + # FCOS parameterizes box regression by a linear transform, + # where predictions are normalized by anchor stride (equal to anchor size). + if box2box_transform is None: + box2box_transform = Box2BoxTransformLinear(normalize_by_size=True) + self.box2box_transform = box2box_transform + + self.center_sampling_radius = float(center_sampling_radius) + + # Loss parameters: + self.focal_loss_alpha = focal_loss_alpha + self.focal_loss_gamma = focal_loss_gamma + + # Inference parameters: + self.test_score_thresh = test_score_thresh + self.test_topk_candidates = test_topk_candidates + self.test_nms_thresh = test_nms_thresh + self.max_detections_per_image = max_detections_per_image + + def forward_training(self, images, features, predictions, gt_instances): + # Transpose the Hi*Wi*A dimension to the middle: + pred_logits, pred_anchor_deltas, pred_centerness = self._transpose_dense_predictions( + predictions, [self.num_classes, 4, 1] + ) + anchors = self.anchor_generator(features) + gt_labels, gt_boxes = self.label_anchors(anchors, gt_instances) + return self.losses( + anchors, pred_logits, gt_labels, pred_anchor_deltas, gt_boxes, pred_centerness + ) + + @torch.no_grad() + def _match_anchors(self, gt_boxes: Boxes, anchors: List[Boxes]): + """ + Match ground-truth boxes to a set of multi-level anchors. + + Args: + gt_boxes: Ground-truth boxes from instances of an image. + anchors: List of anchors for each feature map (of different scales). + + Returns: + torch.Tensor + A tensor of shape `(M, R)`, given `M` ground-truth boxes and total + `R` anchor points from all feature levels, indicating the quality + of match between m-th box and r-th anchor. Higher value indicates + better match. + """ + # Naming convention: (M = ground-truth boxes, R = anchor points) + # Anchor points are represented as square boxes of size = stride. + num_anchors_per_level = [len(x) for x in anchors] + anchors = Boxes.cat(anchors) # (R, 4) + anchor_centers = anchors.get_centers() # (R, 2) + anchor_sizes = anchors.tensor[:, 2] - anchors.tensor[:, 0] # (R, ) + + lower_bound = anchor_sizes * 4 + lower_bound[: num_anchors_per_level[0]] = 0 + upper_bound = anchor_sizes * 8 + upper_bound[-num_anchors_per_level[-1] :] = float("inf") + + gt_centers = gt_boxes.get_centers() + + # FCOS with center sampling: anchor point must be close enough to + # ground-truth box center. + center_dists = (anchor_centers[None, :, :] - gt_centers[:, None, :]).abs_() + sampling_regions = self.center_sampling_radius * anchor_sizes[None, :] + + match_quality_matrix = center_dists.max(dim=2).values < sampling_regions + + pairwise_dist = pairwise_point_box_distance(anchor_centers, gt_boxes) + pairwise_dist = pairwise_dist.permute(1, 0, 2) # (M, R, 4) + + # The original FCOS anchor matching rule: anchor point must be inside GT. + match_quality_matrix &= pairwise_dist.min(dim=2).values > 0 + + # Multilevel anchor matching in FCOS: each anchor is only responsible + # for certain scale range. + pairwise_dist = pairwise_dist.max(dim=2).values + match_quality_matrix &= (pairwise_dist > lower_bound[None, :]) & ( + pairwise_dist < upper_bound[None, :] + ) + # Match the GT box with minimum area, if there are multiple GT matches. + gt_areas = gt_boxes.area() # (M, ) + + match_quality_matrix = match_quality_matrix.to(torch.float32) + match_quality_matrix *= 1e8 - gt_areas[:, None] + return match_quality_matrix # (M, R) + + @torch.no_grad() + def label_anchors(self, anchors: List[Boxes], gt_instances: List[Instances]): + """ + Same interface as :meth:`RetinaNet.label_anchors`, but implemented with FCOS + anchor matching rule. + + Unlike RetinaNet, there are no ignored anchors. + """ + + gt_labels, matched_gt_boxes = [], [] + + for inst in gt_instances: + if len(inst) > 0: + match_quality_matrix = self._match_anchors(inst.gt_boxes, anchors) + + # Find matched ground-truth box per anchor. Un-matched anchors are + # assigned -1. This is equivalent to using an anchor matcher as used + # in R-CNN/RetinaNet: `Matcher(thresholds=[1e-5], labels=[0, 1])` + match_quality, matched_idxs = match_quality_matrix.max(dim=0) + matched_idxs[match_quality < 1e-5] = -1 + + matched_gt_boxes_i = inst.gt_boxes.tensor[matched_idxs.clip(min=0)] + gt_labels_i = inst.gt_classes[matched_idxs.clip(min=0)] + + # Anchors with matched_idxs = -1 are labeled background. + gt_labels_i[matched_idxs < 0] = self.num_classes + else: + matched_gt_boxes_i = torch.zeros_like(Boxes.cat(anchors).tensor) + gt_labels_i = torch.full( + (len(matched_gt_boxes_i),), + fill_value=self.num_classes, + dtype=torch.long, + device=matched_gt_boxes_i.device, + ) + + gt_labels.append(gt_labels_i) + matched_gt_boxes.append(matched_gt_boxes_i) + + return gt_labels, matched_gt_boxes + + def losses( + self, anchors, pred_logits, gt_labels, pred_anchor_deltas, gt_boxes, pred_centerness + ): + """ + This method is almost identical to :meth:`RetinaNet.losses`, with an extra + "loss_centerness" in the returned dict. + """ + num_images = len(gt_labels) + gt_labels = torch.stack(gt_labels) # (M, R) + + pos_mask = (gt_labels >= 0) & (gt_labels != self.num_classes) + num_pos_anchors = pos_mask.sum().item() + get_event_storage().put_scalar("num_pos_anchors", num_pos_anchors / num_images) + normalizer = self._ema_update("loss_normalizer", max(num_pos_anchors, 1), 300) + + # classification and regression loss + gt_labels_target = F.one_hot(gt_labels, num_classes=self.num_classes + 1)[ + :, :, :-1 + ] # no loss for the last (background) class + loss_cls = sigmoid_focal_loss_jit( + torch.cat(pred_logits, dim=1), + gt_labels_target.to(pred_logits[0].dtype), + alpha=self.focal_loss_alpha, + gamma=self.focal_loss_gamma, + reduction="sum", + ) + + loss_box_reg = _dense_box_regression_loss( + anchors, + self.box2box_transform, + pred_anchor_deltas, + gt_boxes, + pos_mask, + box_reg_loss_type="giou", + ) + + ctrness_targets = self.compute_ctrness_targets(anchors, gt_boxes) # (M, R) + pred_centerness = torch.cat(pred_centerness, dim=1).squeeze(dim=2) # (M, R) + ctrness_loss = F.binary_cross_entropy_with_logits( + pred_centerness[pos_mask], ctrness_targets[pos_mask], reduction="sum" + ) + return { + "loss_fcos_cls": loss_cls / normalizer, + "loss_fcos_loc": loss_box_reg / normalizer, + "loss_fcos_ctr": ctrness_loss / normalizer, + } + + def compute_ctrness_targets(self, anchors: List[Boxes], gt_boxes: List[torch.Tensor]): + anchors = Boxes.cat(anchors).tensor # Rx4 + reg_targets = [self.box2box_transform.get_deltas(anchors, m) for m in gt_boxes] + reg_targets = torch.stack(reg_targets, dim=0) # NxRx4 + if len(reg_targets) == 0: + return reg_targets.new_zeros(len(reg_targets)) + left_right = reg_targets[:, :, [0, 2]] + top_bottom = reg_targets[:, :, [1, 3]] + ctrness = (left_right.min(dim=-1)[0] / left_right.max(dim=-1)[0]) * ( + top_bottom.min(dim=-1)[0] / top_bottom.max(dim=-1)[0] + ) + return torch.sqrt(ctrness) + + def forward_inference( + self, + images: ImageList, + features: List[torch.Tensor], + predictions: List[List[torch.Tensor]], + ): + pred_logits, pred_anchor_deltas, pred_centerness = self._transpose_dense_predictions( + predictions, [self.num_classes, 4, 1] + ) + anchors = self.anchor_generator(features) + + results: List[Instances] = [] + for img_idx, image_size in enumerate(images.image_sizes): + scores_per_image = [ + # Multiply and sqrt centerness & classification scores + # (See eqn. 4 in https://arxiv.org/abs/2006.09214) + torch.sqrt(x[img_idx].sigmoid_() * y[img_idx].sigmoid_()) + for x, y in zip(pred_logits, pred_centerness) + ] + deltas_per_image = [x[img_idx] for x in pred_anchor_deltas] + results_per_image = self.inference_single_image( + anchors, scores_per_image, deltas_per_image, image_size + ) + results.append(results_per_image) + return results + + def inference_single_image( + self, + anchors: List[Boxes], + box_cls: List[torch.Tensor], + box_delta: List[torch.Tensor], + image_size: Tuple[int, int], + ): + """ + Identical to :meth:`RetinaNet.inference_single_image. + """ + pred = self._decode_multi_level_predictions( + anchors, + box_cls, + box_delta, + self.test_score_thresh, + self.test_topk_candidates, + image_size, + ) + keep = batched_nms( + pred.pred_boxes.tensor, pred.scores, pred.pred_classes, self.test_nms_thresh + ) + return pred[keep[: self.max_detections_per_image]] + + +class FCOSHead(RetinaNetHead): + """ + The head used in :paper:`fcos`. It adds an additional centerness + prediction branch on top of :class:`RetinaNetHead`. + """ + + def __init__(self, *, input_shape: List[ShapeSpec], conv_dims: List[int], **kwargs): + super().__init__(input_shape=input_shape, conv_dims=conv_dims, num_anchors=1, **kwargs) + # Unlike original FCOS, we do not add an additional learnable scale layer + # because it's found to have no benefits after normalizing regression targets by stride. + self._num_features = len(input_shape) + self.ctrness = nn.Conv2d(conv_dims[-1], 1, kernel_size=3, stride=1, padding=1) + torch.nn.init.normal_(self.ctrness.weight, std=0.01) + torch.nn.init.constant_(self.ctrness.bias, 0) + + def forward(self, features): + assert len(features) == self._num_features + logits = [] + bbox_reg = [] + ctrness = [] + for feature in features: + logits.append(self.cls_score(self.cls_subnet(feature))) + bbox_feature = self.bbox_subnet(feature) + bbox_reg.append(self.bbox_pred(bbox_feature)) + ctrness.append(self.ctrness(bbox_feature)) + return logits, bbox_reg, ctrness diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/panoptic_fpn.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/panoptic_fpn.py new file mode 100644 index 00000000..1ca5f19a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/panoptic_fpn.py @@ -0,0 +1,269 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +import logging +from typing import Dict, List +import torch +from torch import nn + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.structures import ImageList + +from ..postprocessing import detector_postprocess, sem_seg_postprocess +from .build import META_ARCH_REGISTRY +from .rcnn import GeneralizedRCNN +from .semantic_seg import build_sem_seg_head + +__all__ = ["PanopticFPN"] + + +@META_ARCH_REGISTRY.register() +class PanopticFPN(GeneralizedRCNN): + """ + Implement the paper :paper:`PanopticFPN`. + """ + + @configurable + def __init__( + self, + *, + sem_seg_head: nn.Module, + combine_overlap_thresh: float = 0.5, + combine_stuff_area_thresh: float = 4096, + combine_instances_score_thresh: float = 0.5, + **kwargs, + ): + """ + NOTE: this interface is experimental. + + Args: + sem_seg_head: a module for the semantic segmentation head. + combine_overlap_thresh: combine masks into one instances if + they have enough overlap + combine_stuff_area_thresh: ignore stuff areas smaller than this threshold + combine_instances_score_thresh: ignore instances whose score is + smaller than this threshold + + Other arguments are the same as :class:`GeneralizedRCNN`. + """ + super().__init__(**kwargs) + self.sem_seg_head = sem_seg_head + # options when combining instance & semantic outputs + self.combine_overlap_thresh = combine_overlap_thresh + self.combine_stuff_area_thresh = combine_stuff_area_thresh + self.combine_instances_score_thresh = combine_instances_score_thresh + + @classmethod + def from_config(cls, cfg): + ret = super().from_config(cfg) + ret.update( + { + "combine_overlap_thresh": cfg.MODEL.PANOPTIC_FPN.COMBINE.OVERLAP_THRESH, + "combine_stuff_area_thresh": cfg.MODEL.PANOPTIC_FPN.COMBINE.STUFF_AREA_LIMIT, + "combine_instances_score_thresh": cfg.MODEL.PANOPTIC_FPN.COMBINE.INSTANCES_CONFIDENCE_THRESH, # noqa + } + ) + ret["sem_seg_head"] = build_sem_seg_head(cfg, ret["backbone"].output_shape()) + logger = logging.getLogger(__name__) + if not cfg.MODEL.PANOPTIC_FPN.COMBINE.ENABLED: + logger.warning( + "PANOPTIC_FPN.COMBINED.ENABLED is no longer used. " + " model.inference(do_postprocess=) should be used to toggle postprocessing." + ) + if cfg.MODEL.PANOPTIC_FPN.INSTANCE_LOSS_WEIGHT != 1.0: + w = cfg.MODEL.PANOPTIC_FPN.INSTANCE_LOSS_WEIGHT + logger.warning( + "PANOPTIC_FPN.INSTANCE_LOSS_WEIGHT should be replaced by weights on each ROI head." + ) + + def update_weight(x): + if isinstance(x, dict): + return {k: v * w for k, v in x.items()} + else: + return x * w + + roi_heads = ret["roi_heads"] + roi_heads.box_predictor.loss_weight = update_weight(roi_heads.box_predictor.loss_weight) + roi_heads.mask_head.loss_weight = update_weight(roi_heads.mask_head.loss_weight) + return ret + + def forward(self, batched_inputs): + """ + Args: + batched_inputs: a list, batched outputs of :class:`DatasetMapper`. + Each item in the list contains the inputs for one image. + + For now, each item in the list is a dict that contains: + + * "image": Tensor, image in (C, H, W) format. + * "instances": Instances + * "sem_seg": semantic segmentation ground truth. + * Other information that's included in the original dicts, such as: + "height", "width" (int): the output resolution of the model, used in inference. + See :meth:`postprocess` for details. + + Returns: + list[dict]: + each dict has the results for one image. The dict contains the following keys: + + * "instances": see :meth:`GeneralizedRCNN.forward` for its format. + * "sem_seg": see :meth:`SemanticSegmentor.forward` for its format. + * "panoptic_seg": See the return value of + :func:`combine_semantic_and_instance_outputs` for its format. + """ + if not self.training: + return self.inference(batched_inputs) + images = self.preprocess_image(batched_inputs) + features = self.backbone(images.tensor) + + assert "sem_seg" in batched_inputs[0] + gt_sem_seg = [x["sem_seg"].to(self.device) for x in batched_inputs] + gt_sem_seg = ImageList.from_tensors( + gt_sem_seg, + self.backbone.size_divisibility, + self.sem_seg_head.ignore_value, + self.backbone.padding_constraints, + ).tensor + sem_seg_results, sem_seg_losses = self.sem_seg_head(features, gt_sem_seg) + + gt_instances = [x["instances"].to(self.device) for x in batched_inputs] + proposals, proposal_losses = self.proposal_generator(images, features, gt_instances) + detector_results, detector_losses = self.roi_heads( + images, features, proposals, gt_instances + ) + + losses = sem_seg_losses + losses.update(proposal_losses) + losses.update(detector_losses) + return losses + + def inference(self, batched_inputs: List[Dict[str, torch.Tensor]], do_postprocess: bool = True): + """ + Run inference on the given inputs. + + Args: + batched_inputs (list[dict]): same as in :meth:`forward` + do_postprocess (bool): whether to apply post-processing on the outputs. + + Returns: + When do_postprocess=True, see docs in :meth:`forward`. + Otherwise, returns a (list[Instances], list[Tensor]) that contains + the raw detector outputs, and raw semantic segmentation outputs. + """ + images = self.preprocess_image(batched_inputs) + features = self.backbone(images.tensor) + sem_seg_results, sem_seg_losses = self.sem_seg_head(features, None) + proposals, _ = self.proposal_generator(images, features, None) + detector_results, _ = self.roi_heads(images, features, proposals, None) + + if do_postprocess: + processed_results = [] + for sem_seg_result, detector_result, input_per_image, image_size in zip( + sem_seg_results, detector_results, batched_inputs, images.image_sizes + ): + height = input_per_image.get("height", image_size[0]) + width = input_per_image.get("width", image_size[1]) + sem_seg_r = sem_seg_postprocess(sem_seg_result, image_size, height, width) + detector_r = detector_postprocess(detector_result, height, width) + + processed_results.append({"sem_seg": sem_seg_r, "instances": detector_r}) + + panoptic_r = combine_semantic_and_instance_outputs( + detector_r, + sem_seg_r.argmax(dim=0), + self.combine_overlap_thresh, + self.combine_stuff_area_thresh, + self.combine_instances_score_thresh, + ) + processed_results[-1]["panoptic_seg"] = panoptic_r + return processed_results + else: + return detector_results, sem_seg_results + + +def combine_semantic_and_instance_outputs( + instance_results, + semantic_results, + overlap_threshold, + stuff_area_thresh, + instances_score_thresh, +): + """ + Implement a simple combining logic following + "combine_semantic_and_instance_predictions.py" in panopticapi + to produce panoptic segmentation outputs. + + Args: + instance_results: output of :func:`detector_postprocess`. + semantic_results: an (H, W) tensor, each element is the contiguous semantic + category id + + Returns: + panoptic_seg (Tensor): of shape (height, width) where the values are ids for each segment. + segments_info (list[dict]): Describe each segment in `panoptic_seg`. + Each dict contains keys "id", "category_id", "isthing". + """ + panoptic_seg = torch.zeros_like(semantic_results, dtype=torch.int32) + + # sort instance outputs by scores + sorted_inds = torch.argsort(-instance_results.scores) + + current_segment_id = 0 + segments_info = [] + + instance_masks = instance_results.pred_masks.to(dtype=torch.bool, device=panoptic_seg.device) + + # Add instances one-by-one, check for overlaps with existing ones + for inst_id in sorted_inds: + score = instance_results.scores[inst_id].item() + if score < instances_score_thresh: + break + mask = instance_masks[inst_id] # H,W + mask_area = mask.sum().item() + + if mask_area == 0: + continue + + intersect = (mask > 0) & (panoptic_seg > 0) + intersect_area = intersect.sum().item() + + if intersect_area * 1.0 / mask_area > overlap_threshold: + continue + + if intersect_area > 0: + mask = mask & (panoptic_seg == 0) + + current_segment_id += 1 + panoptic_seg[mask] = current_segment_id + segments_info.append( + { + "id": current_segment_id, + "isthing": True, + "score": score, + "category_id": instance_results.pred_classes[inst_id].item(), + "instance_id": inst_id.item(), + } + ) + + # Add semantic results to remaining empty areas + semantic_labels = torch.unique(semantic_results).cpu().tolist() + for semantic_label in semantic_labels: + if semantic_label == 0: # 0 is a special "thing" class + continue + mask = (semantic_results == semantic_label) & (panoptic_seg == 0) + mask_area = mask.sum().item() + if mask_area < stuff_area_thresh: + continue + + current_segment_id += 1 + panoptic_seg[mask] = current_segment_id + segments_info.append( + { + "id": current_segment_id, + "isthing": False, + "category_id": semantic_label, + "area": mask_area, + } + ) + + return panoptic_seg, segments_info diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/rcnn.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/rcnn.py new file mode 100644 index 00000000..7cacf065 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/rcnn.py @@ -0,0 +1,341 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import logging +import numpy as np +from typing import Dict, List, Optional, Tuple +import torch +from torch import nn + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.data.detection_utils import convert_image_to_rgb +from annotator.oneformer.detectron2.layers import move_device_like +from annotator.oneformer.detectron2.structures import ImageList, Instances +from annotator.oneformer.detectron2.utils.events import get_event_storage +from annotator.oneformer.detectron2.utils.logger import log_first_n + +from ..backbone import Backbone, build_backbone +from ..postprocessing import detector_postprocess +from ..proposal_generator import build_proposal_generator +from ..roi_heads import build_roi_heads +from .build import META_ARCH_REGISTRY + +__all__ = ["GeneralizedRCNN", "ProposalNetwork"] + + +@META_ARCH_REGISTRY.register() +class GeneralizedRCNN(nn.Module): + """ + Generalized R-CNN. Any models that contains the following three components: + 1. Per-image feature extraction (aka backbone) + 2. Region proposal generation + 3. Per-region feature extraction and prediction + """ + + @configurable + def __init__( + self, + *, + backbone: Backbone, + proposal_generator: nn.Module, + roi_heads: nn.Module, + pixel_mean: Tuple[float], + pixel_std: Tuple[float], + input_format: Optional[str] = None, + vis_period: int = 0, + ): + """ + Args: + backbone: a backbone module, must follow detectron2's backbone interface + proposal_generator: a module that generates proposals using backbone features + roi_heads: a ROI head that performs per-region computation + pixel_mean, pixel_std: list or tuple with #channels element, representing + the per-channel mean and std to be used to normalize the input image + input_format: describe the meaning of channels of input. Needed by visualization + vis_period: the period to run visualization. Set to 0 to disable. + """ + super().__init__() + self.backbone = backbone + self.proposal_generator = proposal_generator + self.roi_heads = roi_heads + + self.input_format = input_format + self.vis_period = vis_period + if vis_period > 0: + assert input_format is not None, "input_format is required for visualization!" + + self.register_buffer("pixel_mean", torch.tensor(pixel_mean).view(-1, 1, 1), False) + self.register_buffer("pixel_std", torch.tensor(pixel_std).view(-1, 1, 1), False) + assert ( + self.pixel_mean.shape == self.pixel_std.shape + ), f"{self.pixel_mean} and {self.pixel_std} have different shapes!" + + @classmethod + def from_config(cls, cfg): + backbone = build_backbone(cfg) + return { + "backbone": backbone, + "proposal_generator": build_proposal_generator(cfg, backbone.output_shape()), + "roi_heads": build_roi_heads(cfg, backbone.output_shape()), + "input_format": cfg.INPUT.FORMAT, + "vis_period": cfg.VIS_PERIOD, + "pixel_mean": cfg.MODEL.PIXEL_MEAN, + "pixel_std": cfg.MODEL.PIXEL_STD, + } + + @property + def device(self): + return self.pixel_mean.device + + def _move_to_current_device(self, x): + return move_device_like(x, self.pixel_mean) + + def visualize_training(self, batched_inputs, proposals): + """ + A function used to visualize images and proposals. It shows ground truth + bounding boxes on the original image and up to 20 top-scoring predicted + object proposals on the original image. Users can implement different + visualization functions for different models. + + Args: + batched_inputs (list): a list that contains input to the model. + proposals (list): a list that contains predicted proposals. Both + batched_inputs and proposals should have the same length. + """ + from annotator.oneformer.detectron2.utils.visualizer import Visualizer + + storage = get_event_storage() + max_vis_prop = 20 + + for input, prop in zip(batched_inputs, proposals): + img = input["image"] + img = convert_image_to_rgb(img.permute(1, 2, 0), self.input_format) + v_gt = Visualizer(img, None) + v_gt = v_gt.overlay_instances(boxes=input["instances"].gt_boxes) + anno_img = v_gt.get_image() + box_size = min(len(prop.proposal_boxes), max_vis_prop) + v_pred = Visualizer(img, None) + v_pred = v_pred.overlay_instances( + boxes=prop.proposal_boxes[0:box_size].tensor.cpu().numpy() + ) + prop_img = v_pred.get_image() + vis_img = np.concatenate((anno_img, prop_img), axis=1) + vis_img = vis_img.transpose(2, 0, 1) + vis_name = "Left: GT bounding boxes; Right: Predicted proposals" + storage.put_image(vis_name, vis_img) + break # only visualize one image in a batch + + def forward(self, batched_inputs: List[Dict[str, torch.Tensor]]): + """ + Args: + batched_inputs: a list, batched outputs of :class:`DatasetMapper` . + Each item in the list contains the inputs for one image. + For now, each item in the list is a dict that contains: + + * image: Tensor, image in (C, H, W) format. + * instances (optional): groundtruth :class:`Instances` + * proposals (optional): :class:`Instances`, precomputed proposals. + + Other information that's included in the original dicts, such as: + + * "height", "width" (int): the output resolution of the model, used in inference. + See :meth:`postprocess` for details. + + Returns: + list[dict]: + Each dict is the output for one input image. + The dict contains one key "instances" whose value is a :class:`Instances`. + The :class:`Instances` object has the following keys: + "pred_boxes", "pred_classes", "scores", "pred_masks", "pred_keypoints" + """ + if not self.training: + return self.inference(batched_inputs) + + images = self.preprocess_image(batched_inputs) + if "instances" in batched_inputs[0]: + gt_instances = [x["instances"].to(self.device) for x in batched_inputs] + else: + gt_instances = None + + features = self.backbone(images.tensor) + + if self.proposal_generator is not None: + proposals, proposal_losses = self.proposal_generator(images, features, gt_instances) + else: + assert "proposals" in batched_inputs[0] + proposals = [x["proposals"].to(self.device) for x in batched_inputs] + proposal_losses = {} + + _, detector_losses = self.roi_heads(images, features, proposals, gt_instances) + if self.vis_period > 0: + storage = get_event_storage() + if storage.iter % self.vis_period == 0: + self.visualize_training(batched_inputs, proposals) + + losses = {} + losses.update(detector_losses) + losses.update(proposal_losses) + return losses + + def inference( + self, + batched_inputs: List[Dict[str, torch.Tensor]], + detected_instances: Optional[List[Instances]] = None, + do_postprocess: bool = True, + ): + """ + Run inference on the given inputs. + + Args: + batched_inputs (list[dict]): same as in :meth:`forward` + detected_instances (None or list[Instances]): if not None, it + contains an `Instances` object per image. The `Instances` + object contains "pred_boxes" and "pred_classes" which are + known boxes in the image. + The inference will then skip the detection of bounding boxes, + and only predict other per-ROI outputs. + do_postprocess (bool): whether to apply post-processing on the outputs. + + Returns: + When do_postprocess=True, same as in :meth:`forward`. + Otherwise, a list[Instances] containing raw network outputs. + """ + assert not self.training + + images = self.preprocess_image(batched_inputs) + features = self.backbone(images.tensor) + + if detected_instances is None: + if self.proposal_generator is not None: + proposals, _ = self.proposal_generator(images, features, None) + else: + assert "proposals" in batched_inputs[0] + proposals = [x["proposals"].to(self.device) for x in batched_inputs] + + results, _ = self.roi_heads(images, features, proposals, None) + else: + detected_instances = [x.to(self.device) for x in detected_instances] + results = self.roi_heads.forward_with_given_boxes(features, detected_instances) + + if do_postprocess: + assert not torch.jit.is_scripting(), "Scripting is not supported for postprocess." + return GeneralizedRCNN._postprocess(results, batched_inputs, images.image_sizes) + return results + + def preprocess_image(self, batched_inputs: List[Dict[str, torch.Tensor]]): + """ + Normalize, pad and batch the input images. + """ + images = [self._move_to_current_device(x["image"]) for x in batched_inputs] + images = [(x - self.pixel_mean) / self.pixel_std for x in images] + images = ImageList.from_tensors( + images, + self.backbone.size_divisibility, + padding_constraints=self.backbone.padding_constraints, + ) + return images + + @staticmethod + def _postprocess(instances, batched_inputs: List[Dict[str, torch.Tensor]], image_sizes): + """ + Rescale the output instances to the target size. + """ + # note: private function; subject to changes + processed_results = [] + for results_per_image, input_per_image, image_size in zip( + instances, batched_inputs, image_sizes + ): + height = input_per_image.get("height", image_size[0]) + width = input_per_image.get("width", image_size[1]) + r = detector_postprocess(results_per_image, height, width) + processed_results.append({"instances": r}) + return processed_results + + +@META_ARCH_REGISTRY.register() +class ProposalNetwork(nn.Module): + """ + A meta architecture that only predicts object proposals. + """ + + @configurable + def __init__( + self, + *, + backbone: Backbone, + proposal_generator: nn.Module, + pixel_mean: Tuple[float], + pixel_std: Tuple[float], + ): + """ + Args: + backbone: a backbone module, must follow detectron2's backbone interface + proposal_generator: a module that generates proposals using backbone features + pixel_mean, pixel_std: list or tuple with #channels element, representing + the per-channel mean and std to be used to normalize the input image + """ + super().__init__() + self.backbone = backbone + self.proposal_generator = proposal_generator + self.register_buffer("pixel_mean", torch.tensor(pixel_mean).view(-1, 1, 1), False) + self.register_buffer("pixel_std", torch.tensor(pixel_std).view(-1, 1, 1), False) + + @classmethod + def from_config(cls, cfg): + backbone = build_backbone(cfg) + return { + "backbone": backbone, + "proposal_generator": build_proposal_generator(cfg, backbone.output_shape()), + "pixel_mean": cfg.MODEL.PIXEL_MEAN, + "pixel_std": cfg.MODEL.PIXEL_STD, + } + + @property + def device(self): + return self.pixel_mean.device + + def _move_to_current_device(self, x): + return move_device_like(x, self.pixel_mean) + + def forward(self, batched_inputs): + """ + Args: + Same as in :class:`GeneralizedRCNN.forward` + + Returns: + list[dict]: + Each dict is the output for one input image. + The dict contains one key "proposals" whose value is a + :class:`Instances` with keys "proposal_boxes" and "objectness_logits". + """ + images = [self._move_to_current_device(x["image"]) for x in batched_inputs] + images = [(x - self.pixel_mean) / self.pixel_std for x in images] + images = ImageList.from_tensors( + images, + self.backbone.size_divisibility, + padding_constraints=self.backbone.padding_constraints, + ) + features = self.backbone(images.tensor) + + if "instances" in batched_inputs[0]: + gt_instances = [x["instances"].to(self.device) for x in batched_inputs] + elif "targets" in batched_inputs[0]: + log_first_n( + logging.WARN, "'targets' in the model inputs is now renamed to 'instances'!", n=10 + ) + gt_instances = [x["targets"].to(self.device) for x in batched_inputs] + else: + gt_instances = None + proposals, proposal_losses = self.proposal_generator(images, features, gt_instances) + # In training, the proposals are not useful at all but we generate them anyway. + # This makes RPN-only models about 5% slower. + if self.training: + return proposal_losses + + processed_results = [] + for results_per_image, input_per_image, image_size in zip( + proposals, batched_inputs, images.image_sizes + ): + height = input_per_image.get("height", image_size[0]) + width = input_per_image.get("width", image_size[1]) + r = detector_postprocess(results_per_image, height, width) + processed_results.append({"proposals": r}) + return processed_results diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/retinanet.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/retinanet.py new file mode 100644 index 00000000..46e0fda4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/retinanet.py @@ -0,0 +1,439 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import logging +import math +from typing import List, Tuple +import torch +from fvcore.nn import sigmoid_focal_loss_jit +from torch import Tensor, nn +from torch.nn import functional as F + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.layers import CycleBatchNormList, ShapeSpec, batched_nms, cat, get_norm +from annotator.oneformer.detectron2.structures import Boxes, ImageList, Instances, pairwise_iou +from annotator.oneformer.detectron2.utils.events import get_event_storage + +from ..anchor_generator import build_anchor_generator +from ..backbone import Backbone, build_backbone +from ..box_regression import Box2BoxTransform, _dense_box_regression_loss +from ..matcher import Matcher +from .build import META_ARCH_REGISTRY +from .dense_detector import DenseDetector, permute_to_N_HWA_K # noqa + +__all__ = ["RetinaNet"] + + +logger = logging.getLogger(__name__) + + +@META_ARCH_REGISTRY.register() +class RetinaNet(DenseDetector): + """ + Implement RetinaNet in :paper:`RetinaNet`. + """ + + @configurable + def __init__( + self, + *, + backbone: Backbone, + head: nn.Module, + head_in_features, + anchor_generator, + box2box_transform, + anchor_matcher, + num_classes, + focal_loss_alpha=0.25, + focal_loss_gamma=2.0, + smooth_l1_beta=0.0, + box_reg_loss_type="smooth_l1", + test_score_thresh=0.05, + test_topk_candidates=1000, + test_nms_thresh=0.5, + max_detections_per_image=100, + pixel_mean, + pixel_std, + vis_period=0, + input_format="BGR", + ): + """ + NOTE: this interface is experimental. + + Args: + backbone: a backbone module, must follow detectron2's backbone interface + head (nn.Module): a module that predicts logits and regression deltas + for each level from a list of per-level features + head_in_features (Tuple[str]): Names of the input feature maps to be used in head + anchor_generator (nn.Module): a module that creates anchors from a + list of features. Usually an instance of :class:`AnchorGenerator` + box2box_transform (Box2BoxTransform): defines the transform from anchors boxes to + instance boxes + anchor_matcher (Matcher): label the anchors by matching them with ground truth. + num_classes (int): number of classes. Used to label background proposals. + + # Loss parameters: + focal_loss_alpha (float): focal_loss_alpha + focal_loss_gamma (float): focal_loss_gamma + smooth_l1_beta (float): smooth_l1_beta + box_reg_loss_type (str): Options are "smooth_l1", "giou", "diou", "ciou" + + # Inference parameters: + test_score_thresh (float): Inference cls score threshold, only anchors with + score > INFERENCE_TH are considered for inference (to improve speed) + test_topk_candidates (int): Select topk candidates before NMS + test_nms_thresh (float): Overlap threshold used for non-maximum suppression + (suppress boxes with IoU >= this threshold) + max_detections_per_image (int): + Maximum number of detections to return per image during inference + (100 is based on the limit established for the COCO dataset). + + pixel_mean, pixel_std: see :class:`DenseDetector`. + """ + super().__init__( + backbone, head, head_in_features, pixel_mean=pixel_mean, pixel_std=pixel_std + ) + self.num_classes = num_classes + + # Anchors + self.anchor_generator = anchor_generator + self.box2box_transform = box2box_transform + self.anchor_matcher = anchor_matcher + + # Loss parameters: + self.focal_loss_alpha = focal_loss_alpha + self.focal_loss_gamma = focal_loss_gamma + self.smooth_l1_beta = smooth_l1_beta + self.box_reg_loss_type = box_reg_loss_type + # Inference parameters: + self.test_score_thresh = test_score_thresh + self.test_topk_candidates = test_topk_candidates + self.test_nms_thresh = test_nms_thresh + self.max_detections_per_image = max_detections_per_image + # Vis parameters + self.vis_period = vis_period + self.input_format = input_format + + @classmethod + def from_config(cls, cfg): + backbone = build_backbone(cfg) + backbone_shape = backbone.output_shape() + feature_shapes = [backbone_shape[f] for f in cfg.MODEL.RETINANET.IN_FEATURES] + head = RetinaNetHead(cfg, feature_shapes) + anchor_generator = build_anchor_generator(cfg, feature_shapes) + return { + "backbone": backbone, + "head": head, + "anchor_generator": anchor_generator, + "box2box_transform": Box2BoxTransform(weights=cfg.MODEL.RETINANET.BBOX_REG_WEIGHTS), + "anchor_matcher": Matcher( + cfg.MODEL.RETINANET.IOU_THRESHOLDS, + cfg.MODEL.RETINANET.IOU_LABELS, + allow_low_quality_matches=True, + ), + "pixel_mean": cfg.MODEL.PIXEL_MEAN, + "pixel_std": cfg.MODEL.PIXEL_STD, + "num_classes": cfg.MODEL.RETINANET.NUM_CLASSES, + "head_in_features": cfg.MODEL.RETINANET.IN_FEATURES, + # Loss parameters: + "focal_loss_alpha": cfg.MODEL.RETINANET.FOCAL_LOSS_ALPHA, + "focal_loss_gamma": cfg.MODEL.RETINANET.FOCAL_LOSS_GAMMA, + "smooth_l1_beta": cfg.MODEL.RETINANET.SMOOTH_L1_LOSS_BETA, + "box_reg_loss_type": cfg.MODEL.RETINANET.BBOX_REG_LOSS_TYPE, + # Inference parameters: + "test_score_thresh": cfg.MODEL.RETINANET.SCORE_THRESH_TEST, + "test_topk_candidates": cfg.MODEL.RETINANET.TOPK_CANDIDATES_TEST, + "test_nms_thresh": cfg.MODEL.RETINANET.NMS_THRESH_TEST, + "max_detections_per_image": cfg.TEST.DETECTIONS_PER_IMAGE, + # Vis parameters + "vis_period": cfg.VIS_PERIOD, + "input_format": cfg.INPUT.FORMAT, + } + + def forward_training(self, images, features, predictions, gt_instances): + # Transpose the Hi*Wi*A dimension to the middle: + pred_logits, pred_anchor_deltas = self._transpose_dense_predictions( + predictions, [self.num_classes, 4] + ) + anchors = self.anchor_generator(features) + gt_labels, gt_boxes = self.label_anchors(anchors, gt_instances) + return self.losses(anchors, pred_logits, gt_labels, pred_anchor_deltas, gt_boxes) + + def losses(self, anchors, pred_logits, gt_labels, pred_anchor_deltas, gt_boxes): + """ + Args: + anchors (list[Boxes]): a list of #feature level Boxes + gt_labels, gt_boxes: see output of :meth:`RetinaNet.label_anchors`. + Their shapes are (N, R) and (N, R, 4), respectively, where R is + the total number of anchors across levels, i.e. sum(Hi x Wi x Ai) + pred_logits, pred_anchor_deltas: both are list[Tensor]. Each element in the + list corresponds to one level and has shape (N, Hi * Wi * Ai, K or 4). + Where K is the number of classes used in `pred_logits`. + + Returns: + dict[str, Tensor]: + mapping from a named loss to a scalar tensor storing the loss. + Used during training only. The dict keys are: "loss_cls" and "loss_box_reg" + """ + num_images = len(gt_labels) + gt_labels = torch.stack(gt_labels) # (N, R) + + valid_mask = gt_labels >= 0 + pos_mask = (gt_labels >= 0) & (gt_labels != self.num_classes) + num_pos_anchors = pos_mask.sum().item() + get_event_storage().put_scalar("num_pos_anchors", num_pos_anchors / num_images) + normalizer = self._ema_update("loss_normalizer", max(num_pos_anchors, 1), 100) + + # classification and regression loss + gt_labels_target = F.one_hot(gt_labels[valid_mask], num_classes=self.num_classes + 1)[ + :, :-1 + ] # no loss for the last (background) class + loss_cls = sigmoid_focal_loss_jit( + cat(pred_logits, dim=1)[valid_mask], + gt_labels_target.to(pred_logits[0].dtype), + alpha=self.focal_loss_alpha, + gamma=self.focal_loss_gamma, + reduction="sum", + ) + + loss_box_reg = _dense_box_regression_loss( + anchors, + self.box2box_transform, + pred_anchor_deltas, + gt_boxes, + pos_mask, + box_reg_loss_type=self.box_reg_loss_type, + smooth_l1_beta=self.smooth_l1_beta, + ) + + return { + "loss_cls": loss_cls / normalizer, + "loss_box_reg": loss_box_reg / normalizer, + } + + @torch.no_grad() + def label_anchors(self, anchors, gt_instances): + """ + Args: + anchors (list[Boxes]): A list of #feature level Boxes. + The Boxes contains anchors of this image on the specific feature level. + gt_instances (list[Instances]): a list of N `Instances`s. The i-th + `Instances` contains the ground-truth per-instance annotations + for the i-th input image. + + Returns: + list[Tensor]: List of #img tensors. i-th element is a vector of labels whose length is + the total number of anchors across all feature maps (sum(Hi * Wi * A)). + Label values are in {-1, 0, ..., K}, with -1 means ignore, and K means background. + + list[Tensor]: i-th element is a Rx4 tensor, where R is the total number of anchors + across feature maps. The values are the matched gt boxes for each anchor. + Values are undefined for those anchors not labeled as foreground. + """ + anchors = Boxes.cat(anchors) # Rx4 + + gt_labels = [] + matched_gt_boxes = [] + for gt_per_image in gt_instances: + match_quality_matrix = pairwise_iou(gt_per_image.gt_boxes, anchors) + matched_idxs, anchor_labels = self.anchor_matcher(match_quality_matrix) + del match_quality_matrix + + if len(gt_per_image) > 0: + matched_gt_boxes_i = gt_per_image.gt_boxes.tensor[matched_idxs] + + gt_labels_i = gt_per_image.gt_classes[matched_idxs] + # Anchors with label 0 are treated as background. + gt_labels_i[anchor_labels == 0] = self.num_classes + # Anchors with label -1 are ignored. + gt_labels_i[anchor_labels == -1] = -1 + else: + matched_gt_boxes_i = torch.zeros_like(anchors.tensor) + gt_labels_i = torch.zeros_like(matched_idxs) + self.num_classes + + gt_labels.append(gt_labels_i) + matched_gt_boxes.append(matched_gt_boxes_i) + + return gt_labels, matched_gt_boxes + + def forward_inference( + self, images: ImageList, features: List[Tensor], predictions: List[List[Tensor]] + ): + pred_logits, pred_anchor_deltas = self._transpose_dense_predictions( + predictions, [self.num_classes, 4] + ) + anchors = self.anchor_generator(features) + + results: List[Instances] = [] + for img_idx, image_size in enumerate(images.image_sizes): + scores_per_image = [x[img_idx].sigmoid_() for x in pred_logits] + deltas_per_image = [x[img_idx] for x in pred_anchor_deltas] + results_per_image = self.inference_single_image( + anchors, scores_per_image, deltas_per_image, image_size + ) + results.append(results_per_image) + return results + + def inference_single_image( + self, + anchors: List[Boxes], + box_cls: List[Tensor], + box_delta: List[Tensor], + image_size: Tuple[int, int], + ): + """ + Single-image inference. Return bounding-box detection results by thresholding + on scores and applying non-maximum suppression (NMS). + + Arguments: + anchors (list[Boxes]): list of #feature levels. Each entry contains + a Boxes object, which contains all the anchors in that feature level. + box_cls (list[Tensor]): list of #feature levels. Each entry contains + tensor of size (H x W x A, K) + box_delta (list[Tensor]): Same shape as 'box_cls' except that K becomes 4. + image_size (tuple(H, W)): a tuple of the image height and width. + + Returns: + Same as `inference`, but for only one image. + """ + pred = self._decode_multi_level_predictions( + anchors, + box_cls, + box_delta, + self.test_score_thresh, + self.test_topk_candidates, + image_size, + ) + keep = batched_nms( # per-class NMS + pred.pred_boxes.tensor, pred.scores, pred.pred_classes, self.test_nms_thresh + ) + return pred[keep[: self.max_detections_per_image]] + + +class RetinaNetHead(nn.Module): + """ + The head used in RetinaNet for object classification and box regression. + It has two subnets for the two tasks, with a common structure but separate parameters. + """ + + @configurable + def __init__( + self, + *, + input_shape: List[ShapeSpec], + num_classes, + num_anchors, + conv_dims: List[int], + norm="", + prior_prob=0.01, + ): + """ + NOTE: this interface is experimental. + + Args: + input_shape (List[ShapeSpec]): input shape + num_classes (int): number of classes. Used to label background proposals. + num_anchors (int): number of generated anchors + conv_dims (List[int]): dimensions for each convolution layer + norm (str or callable): + Normalization for conv layers except for the two output layers. + See :func:`detectron2.layers.get_norm` for supported types. + prior_prob (float): Prior weight for computing bias + """ + super().__init__() + + self._num_features = len(input_shape) + if norm == "BN" or norm == "SyncBN": + logger.info( + f"Using domain-specific {norm} in RetinaNetHead with len={self._num_features}." + ) + bn_class = nn.BatchNorm2d if norm == "BN" else nn.SyncBatchNorm + + def norm(c): + return CycleBatchNormList( + length=self._num_features, bn_class=bn_class, num_features=c + ) + + else: + norm_name = str(type(get_norm(norm, 32))) + if "BN" in norm_name: + logger.warning( + f"Shared BatchNorm (type={norm_name}) may not work well in RetinaNetHead." + ) + + cls_subnet = [] + bbox_subnet = [] + for in_channels, out_channels in zip( + [input_shape[0].channels] + list(conv_dims), conv_dims + ): + cls_subnet.append( + nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=1, padding=1) + ) + if norm: + cls_subnet.append(get_norm(norm, out_channels)) + cls_subnet.append(nn.ReLU()) + bbox_subnet.append( + nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=1, padding=1) + ) + if norm: + bbox_subnet.append(get_norm(norm, out_channels)) + bbox_subnet.append(nn.ReLU()) + + self.cls_subnet = nn.Sequential(*cls_subnet) + self.bbox_subnet = nn.Sequential(*bbox_subnet) + self.cls_score = nn.Conv2d( + conv_dims[-1], num_anchors * num_classes, kernel_size=3, stride=1, padding=1 + ) + self.bbox_pred = nn.Conv2d( + conv_dims[-1], num_anchors * 4, kernel_size=3, stride=1, padding=1 + ) + + # Initialization + for modules in [self.cls_subnet, self.bbox_subnet, self.cls_score, self.bbox_pred]: + for layer in modules.modules(): + if isinstance(layer, nn.Conv2d): + torch.nn.init.normal_(layer.weight, mean=0, std=0.01) + torch.nn.init.constant_(layer.bias, 0) + + # Use prior in model initialization to improve stability + bias_value = -(math.log((1 - prior_prob) / prior_prob)) + torch.nn.init.constant_(self.cls_score.bias, bias_value) + + @classmethod + def from_config(cls, cfg, input_shape: List[ShapeSpec]): + num_anchors = build_anchor_generator(cfg, input_shape).num_cell_anchors + assert ( + len(set(num_anchors)) == 1 + ), "Using different number of anchors between levels is not currently supported!" + num_anchors = num_anchors[0] + + return { + "input_shape": input_shape, + "num_classes": cfg.MODEL.RETINANET.NUM_CLASSES, + "conv_dims": [input_shape[0].channels] * cfg.MODEL.RETINANET.NUM_CONVS, + "prior_prob": cfg.MODEL.RETINANET.PRIOR_PROB, + "norm": cfg.MODEL.RETINANET.NORM, + "num_anchors": num_anchors, + } + + def forward(self, features: List[Tensor]): + """ + Arguments: + features (list[Tensor]): FPN feature map tensors in high to low resolution. + Each tensor in the list correspond to different feature levels. + + Returns: + logits (list[Tensor]): #lvl tensors, each has shape (N, AxK, Hi, Wi). + The tensor predicts the classification probability + at each spatial position for each of the A anchors and K object + classes. + bbox_reg (list[Tensor]): #lvl tensors, each has shape (N, Ax4, Hi, Wi). + The tensor predicts 4-vector (dx,dy,dw,dh) box + regression values for every anchor. These values are the + relative offset between the anchor and the ground truth box. + """ + assert len(features) == self._num_features + logits = [] + bbox_reg = [] + for feature in features: + logits.append(self.cls_score(self.cls_subnet(feature))) + bbox_reg.append(self.bbox_pred(self.bbox_subnet(feature))) + return logits, bbox_reg diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/semantic_seg.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/semantic_seg.py new file mode 100644 index 00000000..b4be8686 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/meta_arch/semantic_seg.py @@ -0,0 +1,267 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import numpy as np +from typing import Callable, Dict, Optional, Tuple, Union +import fvcore.nn.weight_init as weight_init +import torch +from torch import nn +from torch.nn import functional as F + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.layers import Conv2d, ShapeSpec, get_norm +from annotator.oneformer.detectron2.structures import ImageList +from annotator.oneformer.detectron2.utils.registry import Registry + +from ..backbone import Backbone, build_backbone +from ..postprocessing import sem_seg_postprocess +from .build import META_ARCH_REGISTRY + +__all__ = [ + "SemanticSegmentor", + "SEM_SEG_HEADS_REGISTRY", + "SemSegFPNHead", + "build_sem_seg_head", +] + + +SEM_SEG_HEADS_REGISTRY = Registry("SEM_SEG_HEADS") +SEM_SEG_HEADS_REGISTRY.__doc__ = """ +Registry for semantic segmentation heads, which make semantic segmentation predictions +from feature maps. +""" + + +@META_ARCH_REGISTRY.register() +class SemanticSegmentor(nn.Module): + """ + Main class for semantic segmentation architectures. + """ + + @configurable + def __init__( + self, + *, + backbone: Backbone, + sem_seg_head: nn.Module, + pixel_mean: Tuple[float], + pixel_std: Tuple[float], + ): + """ + Args: + backbone: a backbone module, must follow detectron2's backbone interface + sem_seg_head: a module that predicts semantic segmentation from backbone features + pixel_mean, pixel_std: list or tuple with #channels element, representing + the per-channel mean and std to be used to normalize the input image + """ + super().__init__() + self.backbone = backbone + self.sem_seg_head = sem_seg_head + self.register_buffer("pixel_mean", torch.tensor(pixel_mean).view(-1, 1, 1), False) + self.register_buffer("pixel_std", torch.tensor(pixel_std).view(-1, 1, 1), False) + + @classmethod + def from_config(cls, cfg): + backbone = build_backbone(cfg) + sem_seg_head = build_sem_seg_head(cfg, backbone.output_shape()) + return { + "backbone": backbone, + "sem_seg_head": sem_seg_head, + "pixel_mean": cfg.MODEL.PIXEL_MEAN, + "pixel_std": cfg.MODEL.PIXEL_STD, + } + + @property + def device(self): + return self.pixel_mean.device + + def forward(self, batched_inputs): + """ + Args: + batched_inputs: a list, batched outputs of :class:`DatasetMapper`. + Each item in the list contains the inputs for one image. + + For now, each item in the list is a dict that contains: + + * "image": Tensor, image in (C, H, W) format. + * "sem_seg": semantic segmentation ground truth + * Other information that's included in the original dicts, such as: + "height", "width" (int): the output resolution of the model (may be different + from input resolution), used in inference. + + + Returns: + list[dict]: + Each dict is the output for one input image. + The dict contains one key "sem_seg" whose value is a + Tensor that represents the + per-pixel segmentation prediced by the head. + The prediction has shape KxHxW that represents the logits of + each class for each pixel. + """ + images = [x["image"].to(self.device) for x in batched_inputs] + images = [(x - self.pixel_mean) / self.pixel_std for x in images] + images = ImageList.from_tensors( + images, + self.backbone.size_divisibility, + padding_constraints=self.backbone.padding_constraints, + ) + + features = self.backbone(images.tensor) + + if "sem_seg" in batched_inputs[0]: + targets = [x["sem_seg"].to(self.device) for x in batched_inputs] + targets = ImageList.from_tensors( + targets, + self.backbone.size_divisibility, + self.sem_seg_head.ignore_value, + self.backbone.padding_constraints, + ).tensor + else: + targets = None + results, losses = self.sem_seg_head(features, targets) + + if self.training: + return losses + + processed_results = [] + for result, input_per_image, image_size in zip(results, batched_inputs, images.image_sizes): + height = input_per_image.get("height", image_size[0]) + width = input_per_image.get("width", image_size[1]) + r = sem_seg_postprocess(result, image_size, height, width) + processed_results.append({"sem_seg": r}) + return processed_results + + +def build_sem_seg_head(cfg, input_shape): + """ + Build a semantic segmentation head from `cfg.MODEL.SEM_SEG_HEAD.NAME`. + """ + name = cfg.MODEL.SEM_SEG_HEAD.NAME + return SEM_SEG_HEADS_REGISTRY.get(name)(cfg, input_shape) + + +@SEM_SEG_HEADS_REGISTRY.register() +class SemSegFPNHead(nn.Module): + """ + A semantic segmentation head described in :paper:`PanopticFPN`. + It takes a list of FPN features as input, and applies a sequence of + 3x3 convs and upsampling to scale all of them to the stride defined by + ``common_stride``. Then these features are added and used to make final + predictions by another 1x1 conv layer. + """ + + @configurable + def __init__( + self, + input_shape: Dict[str, ShapeSpec], + *, + num_classes: int, + conv_dims: int, + common_stride: int, + loss_weight: float = 1.0, + norm: Optional[Union[str, Callable]] = None, + ignore_value: int = -1, + ): + """ + NOTE: this interface is experimental. + + Args: + input_shape: shapes (channels and stride) of the input features + num_classes: number of classes to predict + conv_dims: number of output channels for the intermediate conv layers. + common_stride: the common stride that all features will be upscaled to + loss_weight: loss weight + norm (str or callable): normalization for all conv layers + ignore_value: category id to be ignored during training. + """ + super().__init__() + input_shape = sorted(input_shape.items(), key=lambda x: x[1].stride) + if not len(input_shape): + raise ValueError("SemSegFPNHead(input_shape=) cannot be empty!") + self.in_features = [k for k, v in input_shape] + feature_strides = [v.stride for k, v in input_shape] + feature_channels = [v.channels for k, v in input_shape] + + self.ignore_value = ignore_value + self.common_stride = common_stride + self.loss_weight = loss_weight + + self.scale_heads = [] + for in_feature, stride, channels in zip( + self.in_features, feature_strides, feature_channels + ): + head_ops = [] + head_length = max(1, int(np.log2(stride) - np.log2(self.common_stride))) + for k in range(head_length): + norm_module = get_norm(norm, conv_dims) + conv = Conv2d( + channels if k == 0 else conv_dims, + conv_dims, + kernel_size=3, + stride=1, + padding=1, + bias=not norm, + norm=norm_module, + activation=F.relu, + ) + weight_init.c2_msra_fill(conv) + head_ops.append(conv) + if stride != self.common_stride: + head_ops.append( + nn.Upsample(scale_factor=2, mode="bilinear", align_corners=False) + ) + self.scale_heads.append(nn.Sequential(*head_ops)) + self.add_module(in_feature, self.scale_heads[-1]) + self.predictor = Conv2d(conv_dims, num_classes, kernel_size=1, stride=1, padding=0) + weight_init.c2_msra_fill(self.predictor) + + @classmethod + def from_config(cls, cfg, input_shape: Dict[str, ShapeSpec]): + return { + "input_shape": { + k: v for k, v in input_shape.items() if k in cfg.MODEL.SEM_SEG_HEAD.IN_FEATURES + }, + "ignore_value": cfg.MODEL.SEM_SEG_HEAD.IGNORE_VALUE, + "num_classes": cfg.MODEL.SEM_SEG_HEAD.NUM_CLASSES, + "conv_dims": cfg.MODEL.SEM_SEG_HEAD.CONVS_DIM, + "common_stride": cfg.MODEL.SEM_SEG_HEAD.COMMON_STRIDE, + "norm": cfg.MODEL.SEM_SEG_HEAD.NORM, + "loss_weight": cfg.MODEL.SEM_SEG_HEAD.LOSS_WEIGHT, + } + + def forward(self, features, targets=None): + """ + Returns: + In training, returns (None, dict of losses) + In inference, returns (CxHxW logits, {}) + """ + x = self.layers(features) + if self.training: + return None, self.losses(x, targets) + else: + x = F.interpolate( + x, scale_factor=self.common_stride, mode="bilinear", align_corners=False + ) + return x, {} + + def layers(self, features): + for i, f in enumerate(self.in_features): + if i == 0: + x = self.scale_heads[i](features[f]) + else: + x = x + self.scale_heads[i](features[f]) + x = self.predictor(x) + return x + + def losses(self, predictions, targets): + predictions = predictions.float() # https://github.com/pytorch/pytorch/issues/48163 + predictions = F.interpolate( + predictions, + scale_factor=self.common_stride, + mode="bilinear", + align_corners=False, + ) + loss = F.cross_entropy( + predictions, targets, reduction="mean", ignore_index=self.ignore_value + ) + losses = {"loss_sem_seg": loss * self.loss_weight} + return losses diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/mmdet_wrapper.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/mmdet_wrapper.py new file mode 100644 index 00000000..5a60958c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/mmdet_wrapper.py @@ -0,0 +1,273 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import itertools +import logging +import numpy as np +from collections import OrderedDict +from collections.abc import Mapping +from typing import Dict, List, Optional, Tuple, Union +import torch +from omegaconf import DictConfig, OmegaConf +from torch import Tensor, nn + +from annotator.oneformer.detectron2.layers import ShapeSpec +from annotator.oneformer.detectron2.structures import BitMasks, Boxes, ImageList, Instances +from annotator.oneformer.detectron2.utils.events import get_event_storage + +from .backbone import Backbone + +logger = logging.getLogger(__name__) + + +def _to_container(cfg): + """ + mmdet will assert the type of dict/list. + So convert omegaconf objects to dict/list. + """ + if isinstance(cfg, DictConfig): + cfg = OmegaConf.to_container(cfg, resolve=True) + from mmcv.utils import ConfigDict + + return ConfigDict(cfg) + + +class MMDetBackbone(Backbone): + """ + Wrapper of mmdetection backbones to use in detectron2. + + mmdet backbones produce list/tuple of tensors, while detectron2 backbones + produce a dict of tensors. This class wraps the given backbone to produce + output in detectron2's convention, so it can be used in place of detectron2 + backbones. + """ + + def __init__( + self, + backbone: Union[nn.Module, Mapping], + neck: Union[nn.Module, Mapping, None] = None, + *, + output_shapes: List[ShapeSpec], + output_names: Optional[List[str]] = None, + ): + """ + Args: + backbone: either a backbone module or a mmdet config dict that defines a + backbone. The backbone takes a 4D image tensor and returns a + sequence of tensors. + neck: either a backbone module or a mmdet config dict that defines a + neck. The neck takes outputs of backbone and returns a + sequence of tensors. If None, no neck is used. + output_shapes: shape for every output of the backbone (or neck, if given). + stride and channels are often needed. + output_names: names for every output of the backbone (or neck, if given). + By default, will use "out0", "out1", ... + """ + super().__init__() + if isinstance(backbone, Mapping): + from mmdet.models import build_backbone + + backbone = build_backbone(_to_container(backbone)) + self.backbone = backbone + + if isinstance(neck, Mapping): + from mmdet.models import build_neck + + neck = build_neck(_to_container(neck)) + self.neck = neck + + # "Neck" weights, if any, are part of neck itself. This is the interface + # of mmdet so we follow it. Reference: + # https://github.com/open-mmlab/mmdetection/blob/master/mmdet/models/detectors/two_stage.py + logger.info("Initializing mmdet backbone weights...") + self.backbone.init_weights() + # train() in mmdet modules is non-trivial, and has to be explicitly + # called. Reference: + # https://github.com/open-mmlab/mmdetection/blob/master/mmdet/models/backbones/resnet.py + self.backbone.train() + if self.neck is not None: + logger.info("Initializing mmdet neck weights ...") + if isinstance(self.neck, nn.Sequential): + for m in self.neck: + m.init_weights() + else: + self.neck.init_weights() + self.neck.train() + + self._output_shapes = output_shapes + if not output_names: + output_names = [f"out{i}" for i in range(len(output_shapes))] + self._output_names = output_names + + def forward(self, x) -> Dict[str, Tensor]: + outs = self.backbone(x) + if self.neck is not None: + outs = self.neck(outs) + assert isinstance( + outs, (list, tuple) + ), "mmdet backbone should return a list/tuple of tensors!" + if len(outs) != len(self._output_shapes): + raise ValueError( + "Length of output_shapes does not match outputs from the mmdet backbone: " + f"{len(outs)} != {len(self._output_shapes)}" + ) + return {k: v for k, v in zip(self._output_names, outs)} + + def output_shape(self) -> Dict[str, ShapeSpec]: + return {k: v for k, v in zip(self._output_names, self._output_shapes)} + + +class MMDetDetector(nn.Module): + """ + Wrapper of a mmdetection detector model, for detection and instance segmentation. + Input/output formats of this class follow detectron2's convention, so a + mmdetection model can be trained and evaluated in detectron2. + """ + + def __init__( + self, + detector: Union[nn.Module, Mapping], + *, + # Default is 32 regardless of model: + # https://github.com/open-mmlab/mmdetection/tree/master/configs/_base_/datasets + size_divisibility=32, + pixel_mean: Tuple[float], + pixel_std: Tuple[float], + ): + """ + Args: + detector: a mmdet detector, or a mmdet config dict that defines a detector. + size_divisibility: pad input images to multiple of this number + pixel_mean: per-channel mean to normalize input image + pixel_std: per-channel stddev to normalize input image + """ + super().__init__() + if isinstance(detector, Mapping): + from mmdet.models import build_detector + + detector = build_detector(_to_container(detector)) + self.detector = detector + self.detector.init_weights() + self.size_divisibility = size_divisibility + + self.register_buffer("pixel_mean", torch.tensor(pixel_mean).view(-1, 1, 1), False) + self.register_buffer("pixel_std", torch.tensor(pixel_std).view(-1, 1, 1), False) + assert ( + self.pixel_mean.shape == self.pixel_std.shape + ), f"{self.pixel_mean} and {self.pixel_std} have different shapes!" + + def forward(self, batched_inputs: List[Dict[str, torch.Tensor]]): + images = [x["image"].to(self.device) for x in batched_inputs] + images = [(x - self.pixel_mean) / self.pixel_std for x in images] + images = ImageList.from_tensors(images, size_divisibility=self.size_divisibility).tensor + metas = [] + rescale = {"height" in x for x in batched_inputs} + if len(rescale) != 1: + raise ValueError("Some inputs have original height/width, but some don't!") + rescale = list(rescale)[0] + output_shapes = [] + for input in batched_inputs: + meta = {} + c, h, w = input["image"].shape + meta["img_shape"] = meta["ori_shape"] = (h, w, c) + if rescale: + scale_factor = np.array( + [w / input["width"], h / input["height"]] * 2, dtype="float32" + ) + ori_shape = (input["height"], input["width"]) + output_shapes.append(ori_shape) + meta["ori_shape"] = ori_shape + (c,) + else: + scale_factor = 1.0 + output_shapes.append((h, w)) + meta["scale_factor"] = scale_factor + meta["flip"] = False + padh, padw = images.shape[-2:] + meta["pad_shape"] = (padh, padw, c) + metas.append(meta) + + if self.training: + gt_instances = [x["instances"].to(self.device) for x in batched_inputs] + if gt_instances[0].has("gt_masks"): + from mmdet.core import PolygonMasks as mm_PolygonMasks, BitmapMasks as mm_BitMasks + + def convert_mask(m, shape): + # mmdet mask format + if isinstance(m, BitMasks): + return mm_BitMasks(m.tensor.cpu().numpy(), shape[0], shape[1]) + else: + return mm_PolygonMasks(m.polygons, shape[0], shape[1]) + + gt_masks = [convert_mask(x.gt_masks, x.image_size) for x in gt_instances] + losses_and_metrics = self.detector.forward_train( + images, + metas, + [x.gt_boxes.tensor for x in gt_instances], + [x.gt_classes for x in gt_instances], + gt_masks=gt_masks, + ) + else: + losses_and_metrics = self.detector.forward_train( + images, + metas, + [x.gt_boxes.tensor for x in gt_instances], + [x.gt_classes for x in gt_instances], + ) + return _parse_losses(losses_and_metrics) + else: + results = self.detector.simple_test(images, metas, rescale=rescale) + results = [ + {"instances": _convert_mmdet_result(r, shape)} + for r, shape in zip(results, output_shapes) + ] + return results + + @property + def device(self): + return self.pixel_mean.device + + +# Reference: show_result() in +# https://github.com/open-mmlab/mmdetection/blob/master/mmdet/models/detectors/base.py +def _convert_mmdet_result(result, shape: Tuple[int, int]) -> Instances: + if isinstance(result, tuple): + bbox_result, segm_result = result + if isinstance(segm_result, tuple): + segm_result = segm_result[0] + else: + bbox_result, segm_result = result, None + + bboxes = torch.from_numpy(np.vstack(bbox_result)) # Nx5 + bboxes, scores = bboxes[:, :4], bboxes[:, -1] + labels = [ + torch.full((bbox.shape[0],), i, dtype=torch.int32) for i, bbox in enumerate(bbox_result) + ] + labels = torch.cat(labels) + inst = Instances(shape) + inst.pred_boxes = Boxes(bboxes) + inst.scores = scores + inst.pred_classes = labels + + if segm_result is not None and len(labels) > 0: + segm_result = list(itertools.chain(*segm_result)) + segm_result = [torch.from_numpy(x) if isinstance(x, np.ndarray) else x for x in segm_result] + segm_result = torch.stack(segm_result, dim=0) + inst.pred_masks = segm_result + return inst + + +# reference: https://github.com/open-mmlab/mmdetection/blob/master/mmdet/models/detectors/base.py +def _parse_losses(losses: Dict[str, Tensor]) -> Dict[str, Tensor]: + log_vars = OrderedDict() + for loss_name, loss_value in losses.items(): + if isinstance(loss_value, torch.Tensor): + log_vars[loss_name] = loss_value.mean() + elif isinstance(loss_value, list): + log_vars[loss_name] = sum(_loss.mean() for _loss in loss_value) + else: + raise TypeError(f"{loss_name} is not a tensor or list of tensors") + + if "loss" not in loss_name: + # put metrics to storage; don't return them + storage = get_event_storage() + value = log_vars.pop(loss_name).cpu().item() + storage.put_scalar(loss_name, value) + return log_vars diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/poolers.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/poolers.py new file mode 100644 index 00000000..109ab47e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/poolers.py @@ -0,0 +1,263 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import math +from typing import List, Optional +import torch +from torch import nn +from torchvision.ops import RoIPool + +from annotator.oneformer.detectron2.layers import ROIAlign, ROIAlignRotated, cat, nonzero_tuple, shapes_to_tensor +from annotator.oneformer.detectron2.structures import Boxes +from annotator.oneformer.detectron2.utils.tracing import assert_fx_safe, is_fx_tracing + +""" +To export ROIPooler to torchscript, in this file, variables that should be annotated with +`Union[List[Boxes], List[RotatedBoxes]]` are only annotated with `List[Boxes]`. + +TODO: Correct these annotations when torchscript support `Union`. +https://github.com/pytorch/pytorch/issues/41412 +""" + +__all__ = ["ROIPooler"] + + +def assign_boxes_to_levels( + box_lists: List[Boxes], + min_level: int, + max_level: int, + canonical_box_size: int, + canonical_level: int, +): + """ + Map each box in `box_lists` to a feature map level index and return the assignment + vector. + + Args: + box_lists (list[Boxes] | list[RotatedBoxes]): A list of N Boxes or N RotatedBoxes, + where N is the number of images in the batch. + min_level (int): Smallest feature map level index. The input is considered index 0, + the output of stage 1 is index 1, and so. + max_level (int): Largest feature map level index. + canonical_box_size (int): A canonical box size in pixels (sqrt(box area)). + canonical_level (int): The feature map level index on which a canonically-sized box + should be placed. + + Returns: + A tensor of length M, where M is the total number of boxes aggregated over all + N batch images. The memory layout corresponds to the concatenation of boxes + from all images. Each element is the feature map index, as an offset from + `self.min_level`, for the corresponding box (so value i means the box is at + `self.min_level + i`). + """ + box_sizes = torch.sqrt(cat([boxes.area() for boxes in box_lists])) + # Eqn.(1) in FPN paper + level_assignments = torch.floor( + canonical_level + torch.log2(box_sizes / canonical_box_size + 1e-8) + ) + # clamp level to (min, max), in case the box size is too large or too small + # for the available feature maps + level_assignments = torch.clamp(level_assignments, min=min_level, max=max_level) + return level_assignments.to(torch.int64) - min_level + + +# script the module to avoid hardcoded device type +@torch.jit.script_if_tracing +def _convert_boxes_to_pooler_format(boxes: torch.Tensor, sizes: torch.Tensor) -> torch.Tensor: + sizes = sizes.to(device=boxes.device) + indices = torch.repeat_interleave( + torch.arange(len(sizes), dtype=boxes.dtype, device=boxes.device), sizes + ) + return cat([indices[:, None], boxes], dim=1) + + +def convert_boxes_to_pooler_format(box_lists: List[Boxes]): + """ + Convert all boxes in `box_lists` to the low-level format used by ROI pooling ops + (see description under Returns). + + Args: + box_lists (list[Boxes] | list[RotatedBoxes]): + A list of N Boxes or N RotatedBoxes, where N is the number of images in the batch. + + Returns: + When input is list[Boxes]: + A tensor of shape (M, 5), where M is the total number of boxes aggregated over all + N batch images. + The 5 columns are (batch index, x0, y0, x1, y1), where batch index + is the index in [0, N) identifying which batch image the box with corners at + (x0, y0, x1, y1) comes from. + When input is list[RotatedBoxes]: + A tensor of shape (M, 6), where M is the total number of boxes aggregated over all + N batch images. + The 6 columns are (batch index, x_ctr, y_ctr, width, height, angle_degrees), + where batch index is the index in [0, N) identifying which batch image the + rotated box (x_ctr, y_ctr, width, height, angle_degrees) comes from. + """ + boxes = torch.cat([x.tensor for x in box_lists], dim=0) + # __len__ returns Tensor in tracing. + sizes = shapes_to_tensor([x.__len__() for x in box_lists]) + return _convert_boxes_to_pooler_format(boxes, sizes) + + +@torch.jit.script_if_tracing +def _create_zeros( + batch_target: Optional[torch.Tensor], + channels: int, + height: int, + width: int, + like_tensor: torch.Tensor, +) -> torch.Tensor: + batches = batch_target.shape[0] if batch_target is not None else 0 + sizes = (batches, channels, height, width) + return torch.zeros(sizes, dtype=like_tensor.dtype, device=like_tensor.device) + + +class ROIPooler(nn.Module): + """ + Region of interest feature map pooler that supports pooling from one or more + feature maps. + """ + + def __init__( + self, + output_size, + scales, + sampling_ratio, + pooler_type, + canonical_box_size=224, + canonical_level=4, + ): + """ + Args: + output_size (int, tuple[int] or list[int]): output size of the pooled region, + e.g., 14 x 14. If tuple or list is given, the length must be 2. + scales (list[float]): The scale for each low-level pooling op relative to + the input image. For a feature map with stride s relative to the input + image, scale is defined as 1/s. The stride must be power of 2. + When there are multiple scales, they must form a pyramid, i.e. they must be + a monotically decreasing geometric sequence with a factor of 1/2. + sampling_ratio (int): The `sampling_ratio` parameter for the ROIAlign op. + pooler_type (string): Name of the type of pooling operation that should be applied. + For instance, "ROIPool" or "ROIAlignV2". + canonical_box_size (int): A canonical box size in pixels (sqrt(box area)). The default + is heuristically defined as 224 pixels in the FPN paper (based on ImageNet + pre-training). + canonical_level (int): The feature map level index from which a canonically-sized box + should be placed. The default is defined as level 4 (stride=16) in the FPN paper, + i.e., a box of size 224x224 will be placed on the feature with stride=16. + The box placement for all boxes will be determined from their sizes w.r.t + canonical_box_size. For example, a box whose area is 4x that of a canonical box + should be used to pool features from feature level ``canonical_level+1``. + + Note that the actual input feature maps given to this module may not have + sufficiently many levels for the input boxes. If the boxes are too large or too + small for the input feature maps, the closest level will be used. + """ + super().__init__() + + if isinstance(output_size, int): + output_size = (output_size, output_size) + assert len(output_size) == 2 + assert isinstance(output_size[0], int) and isinstance(output_size[1], int) + self.output_size = output_size + + if pooler_type == "ROIAlign": + self.level_poolers = nn.ModuleList( + ROIAlign( + output_size, spatial_scale=scale, sampling_ratio=sampling_ratio, aligned=False + ) + for scale in scales + ) + elif pooler_type == "ROIAlignV2": + self.level_poolers = nn.ModuleList( + ROIAlign( + output_size, spatial_scale=scale, sampling_ratio=sampling_ratio, aligned=True + ) + for scale in scales + ) + elif pooler_type == "ROIPool": + self.level_poolers = nn.ModuleList( + RoIPool(output_size, spatial_scale=scale) for scale in scales + ) + elif pooler_type == "ROIAlignRotated": + self.level_poolers = nn.ModuleList( + ROIAlignRotated(output_size, spatial_scale=scale, sampling_ratio=sampling_ratio) + for scale in scales + ) + else: + raise ValueError("Unknown pooler type: {}".format(pooler_type)) + + # Map scale (defined as 1 / stride) to its feature map level under the + # assumption that stride is a power of 2. + min_level = -(math.log2(scales[0])) + max_level = -(math.log2(scales[-1])) + assert math.isclose(min_level, int(min_level)) and math.isclose( + max_level, int(max_level) + ), "Featuremap stride is not power of 2!" + self.min_level = int(min_level) + self.max_level = int(max_level) + assert ( + len(scales) == self.max_level - self.min_level + 1 + ), "[ROIPooler] Sizes of input featuremaps do not form a pyramid!" + assert 0 <= self.min_level and self.min_level <= self.max_level + self.canonical_level = canonical_level + assert canonical_box_size > 0 + self.canonical_box_size = canonical_box_size + + def forward(self, x: List[torch.Tensor], box_lists: List[Boxes]): + """ + Args: + x (list[Tensor]): A list of feature maps of NCHW shape, with scales matching those + used to construct this module. + box_lists (list[Boxes] | list[RotatedBoxes]): + A list of N Boxes or N RotatedBoxes, where N is the number of images in the batch. + The box coordinates are defined on the original image and + will be scaled by the `scales` argument of :class:`ROIPooler`. + + Returns: + Tensor: + A tensor of shape (M, C, output_size, output_size) where M is the total number of + boxes aggregated over all N batch images and C is the number of channels in `x`. + """ + num_level_assignments = len(self.level_poolers) + + if not is_fx_tracing(): + torch._assert( + isinstance(x, list) and isinstance(box_lists, list), + "Arguments to pooler must be lists", + ) + assert_fx_safe( + len(x) == num_level_assignments, + "unequal value, num_level_assignments={}, but x is list of {} Tensors".format( + num_level_assignments, len(x) + ), + ) + assert_fx_safe( + len(box_lists) == x[0].size(0), + "unequal value, x[0] batch dim 0 is {}, but box_list has length {}".format( + x[0].size(0), len(box_lists) + ), + ) + if len(box_lists) == 0: + return _create_zeros(None, x[0].shape[1], *self.output_size, x[0]) + + pooler_fmt_boxes = convert_boxes_to_pooler_format(box_lists) + + if num_level_assignments == 1: + return self.level_poolers[0](x[0], pooler_fmt_boxes) + + level_assignments = assign_boxes_to_levels( + box_lists, self.min_level, self.max_level, self.canonical_box_size, self.canonical_level + ) + + num_channels = x[0].shape[1] + output_size = self.output_size[0] + + output = _create_zeros(pooler_fmt_boxes, num_channels, output_size, output_size, x[0]) + + for level, pooler in enumerate(self.level_poolers): + inds = nonzero_tuple(level_assignments == level)[0] + pooler_fmt_boxes_level = pooler_fmt_boxes[inds] + # Use index_put_ instead of advance indexing, to avoid pytorch/issues/49852 + output.index_put_((inds,), pooler(x[level], pooler_fmt_boxes_level)) + + return output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/postprocessing.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/postprocessing.py new file mode 100644 index 00000000..82bbad25 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/postprocessing.py @@ -0,0 +1,100 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import torch +from torch.nn import functional as F + +from annotator.oneformer.detectron2.structures import Instances, ROIMasks + + +# perhaps should rename to "resize_instance" +def detector_postprocess( + results: Instances, output_height: int, output_width: int, mask_threshold: float = 0.5 +): + """ + Resize the output instances. + The input images are often resized when entering an object detector. + As a result, we often need the outputs of the detector in a different + resolution from its inputs. + + This function will resize the raw outputs of an R-CNN detector + to produce outputs according to the desired output resolution. + + Args: + results (Instances): the raw outputs from the detector. + `results.image_size` contains the input image resolution the detector sees. + This object might be modified in-place. + output_height, output_width: the desired output resolution. + Returns: + Instances: the resized output from the model, based on the output resolution + """ + if isinstance(output_width, torch.Tensor): + # This shape might (but not necessarily) be tensors during tracing. + # Converts integer tensors to float temporaries to ensure true + # division is performed when computing scale_x and scale_y. + output_width_tmp = output_width.float() + output_height_tmp = output_height.float() + new_size = torch.stack([output_height, output_width]) + else: + new_size = (output_height, output_width) + output_width_tmp = output_width + output_height_tmp = output_height + + scale_x, scale_y = ( + output_width_tmp / results.image_size[1], + output_height_tmp / results.image_size[0], + ) + results = Instances(new_size, **results.get_fields()) + + if results.has("pred_boxes"): + output_boxes = results.pred_boxes + elif results.has("proposal_boxes"): + output_boxes = results.proposal_boxes + else: + output_boxes = None + assert output_boxes is not None, "Predictions must contain boxes!" + + output_boxes.scale(scale_x, scale_y) + output_boxes.clip(results.image_size) + + results = results[output_boxes.nonempty()] + + if results.has("pred_masks"): + if isinstance(results.pred_masks, ROIMasks): + roi_masks = results.pred_masks + else: + # pred_masks is a tensor of shape (N, 1, M, M) + roi_masks = ROIMasks(results.pred_masks[:, 0, :, :]) + results.pred_masks = roi_masks.to_bitmasks( + results.pred_boxes, output_height, output_width, mask_threshold + ).tensor # TODO return ROIMasks/BitMask object in the future + + if results.has("pred_keypoints"): + results.pred_keypoints[:, :, 0] *= scale_x + results.pred_keypoints[:, :, 1] *= scale_y + + return results + + +def sem_seg_postprocess(result, img_size, output_height, output_width): + """ + Return semantic segmentation predictions in the original resolution. + + The input images are often resized when entering semantic segmentor. Moreover, in same + cases, they also padded inside segmentor to be divisible by maximum network stride. + As a result, we often need the predictions of the segmentor in a different + resolution from its inputs. + + Args: + result (Tensor): semantic segmentation prediction logits. A tensor of shape (C, H, W), + where C is the number of classes, and H, W are the height and width of the prediction. + img_size (tuple): image size that segmentor is taking as input. + output_height, output_width: the desired output resolution. + + Returns: + semantic segmentation prediction (Tensor): A tensor of the shape + (C, output_height, output_width) that contains per-pixel soft predictions. + """ + result = result[:, : img_size[0], : img_size[1]].expand(1, -1, -1, -1) + result = F.interpolate( + result, size=(output_height, output_width), mode="bilinear", align_corners=False + )[0] + return result diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/__init__.py new file mode 100644 index 00000000..3f4e4df7 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/__init__.py @@ -0,0 +1,5 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from .build import PROPOSAL_GENERATOR_REGISTRY, build_proposal_generator +from .rpn import RPN_HEAD_REGISTRY, build_rpn_head, RPN, StandardRPNHead + +__all__ = list(globals().keys()) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/build.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/build.py new file mode 100644 index 00000000..255cd4d0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/build.py @@ -0,0 +1,24 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from annotator.oneformer.detectron2.utils.registry import Registry + +PROPOSAL_GENERATOR_REGISTRY = Registry("PROPOSAL_GENERATOR") +PROPOSAL_GENERATOR_REGISTRY.__doc__ = """ +Registry for proposal generator, which produces object proposals from feature maps. + +The registered object will be called with `obj(cfg, input_shape)`. +The call should return a `nn.Module` object. +""" + +from . import rpn, rrpn # noqa F401 isort:skip + + +def build_proposal_generator(cfg, input_shape): + """ + Build a proposal generator from `cfg.MODEL.PROPOSAL_GENERATOR.NAME`. + The name can be "PrecomputedProposals" to use no proposal generator. + """ + name = cfg.MODEL.PROPOSAL_GENERATOR.NAME + if name == "PrecomputedProposals": + return None + + return PROPOSAL_GENERATOR_REGISTRY.get(name)(cfg, input_shape) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/proposal_utils.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/proposal_utils.py new file mode 100644 index 00000000..b5579f43 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/proposal_utils.py @@ -0,0 +1,205 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import logging +import math +from typing import List, Tuple, Union +import torch + +from annotator.oneformer.detectron2.layers import batched_nms, cat, move_device_like +from annotator.oneformer.detectron2.structures import Boxes, Instances + +logger = logging.getLogger(__name__) + + +def _is_tracing(): + # (fixed in TORCH_VERSION >= 1.9) + if torch.jit.is_scripting(): + # https://github.com/pytorch/pytorch/issues/47379 + return False + else: + return torch.jit.is_tracing() + + +def find_top_rpn_proposals( + proposals: List[torch.Tensor], + pred_objectness_logits: List[torch.Tensor], + image_sizes: List[Tuple[int, int]], + nms_thresh: float, + pre_nms_topk: int, + post_nms_topk: int, + min_box_size: float, + training: bool, +): + """ + For each feature map, select the `pre_nms_topk` highest scoring proposals, + apply NMS, clip proposals, and remove small boxes. Return the `post_nms_topk` + highest scoring proposals among all the feature maps for each image. + + Args: + proposals (list[Tensor]): A list of L tensors. Tensor i has shape (N, Hi*Wi*A, 4). + All proposal predictions on the feature maps. + pred_objectness_logits (list[Tensor]): A list of L tensors. Tensor i has shape (N, Hi*Wi*A). + image_sizes (list[tuple]): sizes (h, w) for each image + nms_thresh (float): IoU threshold to use for NMS + pre_nms_topk (int): number of top k scoring proposals to keep before applying NMS. + When RPN is run on multiple feature maps (as in FPN) this number is per + feature map. + post_nms_topk (int): number of top k scoring proposals to keep after applying NMS. + When RPN is run on multiple feature maps (as in FPN) this number is total, + over all feature maps. + min_box_size (float): minimum proposal box side length in pixels (absolute units + wrt input images). + training (bool): True if proposals are to be used in training, otherwise False. + This arg exists only to support a legacy bug; look for the "NB: Legacy bug ..." + comment. + + Returns: + list[Instances]: list of N Instances. The i-th Instances + stores post_nms_topk object proposals for image i, sorted by their + objectness score in descending order. + """ + num_images = len(image_sizes) + device = ( + proposals[0].device + if torch.jit.is_scripting() + else ("cpu" if torch.jit.is_tracing() else proposals[0].device) + ) + + # 1. Select top-k anchor for every level and every image + topk_scores = [] # #lvl Tensor, each of shape N x topk + topk_proposals = [] + level_ids = [] # #lvl Tensor, each of shape (topk,) + batch_idx = move_device_like(torch.arange(num_images, device=device), proposals[0]) + for level_id, (proposals_i, logits_i) in enumerate(zip(proposals, pred_objectness_logits)): + Hi_Wi_A = logits_i.shape[1] + if isinstance(Hi_Wi_A, torch.Tensor): # it's a tensor in tracing + num_proposals_i = torch.clamp(Hi_Wi_A, max=pre_nms_topk) + else: + num_proposals_i = min(Hi_Wi_A, pre_nms_topk) + + topk_scores_i, topk_idx = logits_i.topk(num_proposals_i, dim=1) + + # each is N x topk + topk_proposals_i = proposals_i[batch_idx[:, None], topk_idx] # N x topk x 4 + + topk_proposals.append(topk_proposals_i) + topk_scores.append(topk_scores_i) + level_ids.append( + move_device_like( + torch.full((num_proposals_i,), level_id, dtype=torch.int64, device=device), + proposals[0], + ) + ) + + # 2. Concat all levels together + topk_scores = cat(topk_scores, dim=1) + topk_proposals = cat(topk_proposals, dim=1) + level_ids = cat(level_ids, dim=0) + + # 3. For each image, run a per-level NMS, and choose topk results. + results: List[Instances] = [] + for n, image_size in enumerate(image_sizes): + boxes = Boxes(topk_proposals[n]) + scores_per_img = topk_scores[n] + lvl = level_ids + + valid_mask = torch.isfinite(boxes.tensor).all(dim=1) & torch.isfinite(scores_per_img) + if not valid_mask.all(): + if training: + raise FloatingPointError( + "Predicted boxes or scores contain Inf/NaN. Training has diverged." + ) + boxes = boxes[valid_mask] + scores_per_img = scores_per_img[valid_mask] + lvl = lvl[valid_mask] + boxes.clip(image_size) + + # filter empty boxes + keep = boxes.nonempty(threshold=min_box_size) + if _is_tracing() or keep.sum().item() != len(boxes): + boxes, scores_per_img, lvl = boxes[keep], scores_per_img[keep], lvl[keep] + + keep = batched_nms(boxes.tensor, scores_per_img, lvl, nms_thresh) + # In Detectron1, there was different behavior during training vs. testing. + # (https://github.com/facebookresearch/Detectron/issues/459) + # During training, topk is over the proposals from *all* images in the training batch. + # During testing, it is over the proposals for each image separately. + # As a result, the training behavior becomes batch-dependent, + # and the configuration "POST_NMS_TOPK_TRAIN" end up relying on the batch size. + # This bug is addressed in Detectron2 to make the behavior independent of batch size. + keep = keep[:post_nms_topk] # keep is already sorted + + res = Instances(image_size) + res.proposal_boxes = boxes[keep] + res.objectness_logits = scores_per_img[keep] + results.append(res) + return results + + +def add_ground_truth_to_proposals( + gt: Union[List[Instances], List[Boxes]], proposals: List[Instances] +) -> List[Instances]: + """ + Call `add_ground_truth_to_proposals_single_image` for all images. + + Args: + gt(Union[List[Instances], List[Boxes]): list of N elements. Element i is a Instances + representing the ground-truth for image i. + proposals (list[Instances]): list of N elements. Element i is a Instances + representing the proposals for image i. + + Returns: + list[Instances]: list of N Instances. Each is the proposals for the image, + with field "proposal_boxes" and "objectness_logits". + """ + assert gt is not None + + if len(proposals) != len(gt): + raise ValueError("proposals and gt should have the same length as the number of images!") + if len(proposals) == 0: + return proposals + + return [ + add_ground_truth_to_proposals_single_image(gt_i, proposals_i) + for gt_i, proposals_i in zip(gt, proposals) + ] + + +def add_ground_truth_to_proposals_single_image( + gt: Union[Instances, Boxes], proposals: Instances +) -> Instances: + """ + Augment `proposals` with `gt`. + + Args: + Same as `add_ground_truth_to_proposals`, but with gt and proposals + per image. + + Returns: + Same as `add_ground_truth_to_proposals`, but for only one image. + """ + if isinstance(gt, Boxes): + # convert Boxes to Instances + gt = Instances(proposals.image_size, gt_boxes=gt) + + gt_boxes = gt.gt_boxes + device = proposals.objectness_logits.device + # Assign all ground-truth boxes an objectness logit corresponding to + # P(object) = sigmoid(logit) =~ 1. + gt_logit_value = math.log((1.0 - 1e-10) / (1 - (1.0 - 1e-10))) + gt_logits = gt_logit_value * torch.ones(len(gt_boxes), device=device) + + # Concatenating gt_boxes with proposals requires them to have the same fields + gt_proposal = Instances(proposals.image_size, **gt.get_fields()) + gt_proposal.proposal_boxes = gt_boxes + gt_proposal.objectness_logits = gt_logits + + for key in proposals.get_fields().keys(): + assert gt_proposal.has( + key + ), "The attribute '{}' in `proposals` does not exist in `gt`".format(key) + + # NOTE: Instances.cat only use fields from the first item. Extra fields in latter items + # will be thrown away. + new_proposals = Instances.cat([proposals, gt_proposal]) + + return new_proposals diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/rpn.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/rpn.py new file mode 100644 index 00000000..e37860dd --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/rpn.py @@ -0,0 +1,533 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from typing import Dict, List, Optional, Tuple, Union +import torch +import torch.nn.functional as F +from torch import nn + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.layers import Conv2d, ShapeSpec, cat +from annotator.oneformer.detectron2.structures import Boxes, ImageList, Instances, pairwise_iou +from annotator.oneformer.detectron2.utils.events import get_event_storage +from annotator.oneformer.detectron2.utils.memory import retry_if_cuda_oom +from annotator.oneformer.detectron2.utils.registry import Registry + +from ..anchor_generator import build_anchor_generator +from ..box_regression import Box2BoxTransform, _dense_box_regression_loss +from ..matcher import Matcher +from ..sampling import subsample_labels +from .build import PROPOSAL_GENERATOR_REGISTRY +from .proposal_utils import find_top_rpn_proposals + +RPN_HEAD_REGISTRY = Registry("RPN_HEAD") +RPN_HEAD_REGISTRY.__doc__ = """ +Registry for RPN heads, which take feature maps and perform +objectness classification and bounding box regression for anchors. + +The registered object will be called with `obj(cfg, input_shape)`. +The call should return a `nn.Module` object. +""" + + +""" +Shape shorthand in this module: + + N: number of images in the minibatch + L: number of feature maps per image on which RPN is run + A: number of cell anchors (must be the same for all feature maps) + Hi, Wi: height and width of the i-th feature map + B: size of the box parameterization + +Naming convention: + + objectness: refers to the binary classification of an anchor as object vs. not object. + + deltas: refers to the 4-d (dx, dy, dw, dh) deltas that parameterize the box2box + transform (see :class:`box_regression.Box2BoxTransform`), or 5d for rotated boxes. + + pred_objectness_logits: predicted objectness scores in [-inf, +inf]; use + sigmoid(pred_objectness_logits) to estimate P(object). + + gt_labels: ground-truth binary classification labels for objectness + + pred_anchor_deltas: predicted box2box transform deltas + + gt_anchor_deltas: ground-truth box2box transform deltas +""" + + +def build_rpn_head(cfg, input_shape): + """ + Build an RPN head defined by `cfg.MODEL.RPN.HEAD_NAME`. + """ + name = cfg.MODEL.RPN.HEAD_NAME + return RPN_HEAD_REGISTRY.get(name)(cfg, input_shape) + + +@RPN_HEAD_REGISTRY.register() +class StandardRPNHead(nn.Module): + """ + Standard RPN classification and regression heads described in :paper:`Faster R-CNN`. + Uses a 3x3 conv to produce a shared hidden state from which one 1x1 conv predicts + objectness logits for each anchor and a second 1x1 conv predicts bounding-box deltas + specifying how to deform each anchor into an object proposal. + """ + + @configurable + def __init__( + self, *, in_channels: int, num_anchors: int, box_dim: int = 4, conv_dims: List[int] = (-1,) + ): + """ + NOTE: this interface is experimental. + + Args: + in_channels (int): number of input feature channels. When using multiple + input features, they must have the same number of channels. + num_anchors (int): number of anchors to predict for *each spatial position* + on the feature map. The total number of anchors for each + feature map will be `num_anchors * H * W`. + box_dim (int): dimension of a box, which is also the number of box regression + predictions to make for each anchor. An axis aligned box has + box_dim=4, while a rotated box has box_dim=5. + conv_dims (list[int]): a list of integers representing the output channels + of N conv layers. Set it to -1 to use the same number of output channels + as input channels. + """ + super().__init__() + cur_channels = in_channels + # Keeping the old variable names and structure for backwards compatiblity. + # Otherwise the old checkpoints will fail to load. + if len(conv_dims) == 1: + out_channels = cur_channels if conv_dims[0] == -1 else conv_dims[0] + # 3x3 conv for the hidden representation + self.conv = self._get_rpn_conv(cur_channels, out_channels) + cur_channels = out_channels + else: + self.conv = nn.Sequential() + for k, conv_dim in enumerate(conv_dims): + out_channels = cur_channels if conv_dim == -1 else conv_dim + if out_channels <= 0: + raise ValueError( + f"Conv output channels should be greater than 0. Got {out_channels}" + ) + conv = self._get_rpn_conv(cur_channels, out_channels) + self.conv.add_module(f"conv{k}", conv) + cur_channels = out_channels + # 1x1 conv for predicting objectness logits + self.objectness_logits = nn.Conv2d(cur_channels, num_anchors, kernel_size=1, stride=1) + # 1x1 conv for predicting box2box transform deltas + self.anchor_deltas = nn.Conv2d(cur_channels, num_anchors * box_dim, kernel_size=1, stride=1) + + # Keeping the order of weights initialization same for backwards compatiblility. + for layer in self.modules(): + if isinstance(layer, nn.Conv2d): + nn.init.normal_(layer.weight, std=0.01) + nn.init.constant_(layer.bias, 0) + + def _get_rpn_conv(self, in_channels, out_channels): + return Conv2d( + in_channels, + out_channels, + kernel_size=3, + stride=1, + padding=1, + activation=nn.ReLU(), + ) + + @classmethod + def from_config(cls, cfg, input_shape): + # Standard RPN is shared across levels: + in_channels = [s.channels for s in input_shape] + assert len(set(in_channels)) == 1, "Each level must have the same channel!" + in_channels = in_channels[0] + + # RPNHead should take the same input as anchor generator + # NOTE: it assumes that creating an anchor generator does not have unwanted side effect. + anchor_generator = build_anchor_generator(cfg, input_shape) + num_anchors = anchor_generator.num_anchors + box_dim = anchor_generator.box_dim + assert ( + len(set(num_anchors)) == 1 + ), "Each level must have the same number of anchors per spatial position" + return { + "in_channels": in_channels, + "num_anchors": num_anchors[0], + "box_dim": box_dim, + "conv_dims": cfg.MODEL.RPN.CONV_DIMS, + } + + def forward(self, features: List[torch.Tensor]): + """ + Args: + features (list[Tensor]): list of feature maps + + Returns: + list[Tensor]: A list of L elements. + Element i is a tensor of shape (N, A, Hi, Wi) representing + the predicted objectness logits for all anchors. A is the number of cell anchors. + list[Tensor]: A list of L elements. Element i is a tensor of shape + (N, A*box_dim, Hi, Wi) representing the predicted "deltas" used to transform anchors + to proposals. + """ + pred_objectness_logits = [] + pred_anchor_deltas = [] + for x in features: + t = self.conv(x) + pred_objectness_logits.append(self.objectness_logits(t)) + pred_anchor_deltas.append(self.anchor_deltas(t)) + return pred_objectness_logits, pred_anchor_deltas + + +@PROPOSAL_GENERATOR_REGISTRY.register() +class RPN(nn.Module): + """ + Region Proposal Network, introduced by :paper:`Faster R-CNN`. + """ + + @configurable + def __init__( + self, + *, + in_features: List[str], + head: nn.Module, + anchor_generator: nn.Module, + anchor_matcher: Matcher, + box2box_transform: Box2BoxTransform, + batch_size_per_image: int, + positive_fraction: float, + pre_nms_topk: Tuple[float, float], + post_nms_topk: Tuple[float, float], + nms_thresh: float = 0.7, + min_box_size: float = 0.0, + anchor_boundary_thresh: float = -1.0, + loss_weight: Union[float, Dict[str, float]] = 1.0, + box_reg_loss_type: str = "smooth_l1", + smooth_l1_beta: float = 0.0, + ): + """ + NOTE: this interface is experimental. + + Args: + in_features (list[str]): list of names of input features to use + head (nn.Module): a module that predicts logits and regression deltas + for each level from a list of per-level features + anchor_generator (nn.Module): a module that creates anchors from a + list of features. Usually an instance of :class:`AnchorGenerator` + anchor_matcher (Matcher): label the anchors by matching them with ground truth. + box2box_transform (Box2BoxTransform): defines the transform from anchors boxes to + instance boxes + batch_size_per_image (int): number of anchors per image to sample for training + positive_fraction (float): fraction of foreground anchors to sample for training + pre_nms_topk (tuple[float]): (train, test) that represents the + number of top k proposals to select before NMS, in + training and testing. + post_nms_topk (tuple[float]): (train, test) that represents the + number of top k proposals to select after NMS, in + training and testing. + nms_thresh (float): NMS threshold used to de-duplicate the predicted proposals + min_box_size (float): remove proposal boxes with any side smaller than this threshold, + in the unit of input image pixels + anchor_boundary_thresh (float): legacy option + loss_weight (float|dict): weights to use for losses. Can be single float for weighting + all rpn losses together, or a dict of individual weightings. Valid dict keys are: + "loss_rpn_cls" - applied to classification loss + "loss_rpn_loc" - applied to box regression loss + box_reg_loss_type (str): Loss type to use. Supported losses: "smooth_l1", "giou". + smooth_l1_beta (float): beta parameter for the smooth L1 regression loss. Default to + use L1 loss. Only used when `box_reg_loss_type` is "smooth_l1" + """ + super().__init__() + self.in_features = in_features + self.rpn_head = head + self.anchor_generator = anchor_generator + self.anchor_matcher = anchor_matcher + self.box2box_transform = box2box_transform + self.batch_size_per_image = batch_size_per_image + self.positive_fraction = positive_fraction + # Map from self.training state to train/test settings + self.pre_nms_topk = {True: pre_nms_topk[0], False: pre_nms_topk[1]} + self.post_nms_topk = {True: post_nms_topk[0], False: post_nms_topk[1]} + self.nms_thresh = nms_thresh + self.min_box_size = float(min_box_size) + self.anchor_boundary_thresh = anchor_boundary_thresh + if isinstance(loss_weight, float): + loss_weight = {"loss_rpn_cls": loss_weight, "loss_rpn_loc": loss_weight} + self.loss_weight = loss_weight + self.box_reg_loss_type = box_reg_loss_type + self.smooth_l1_beta = smooth_l1_beta + + @classmethod + def from_config(cls, cfg, input_shape: Dict[str, ShapeSpec]): + in_features = cfg.MODEL.RPN.IN_FEATURES + ret = { + "in_features": in_features, + "min_box_size": cfg.MODEL.PROPOSAL_GENERATOR.MIN_SIZE, + "nms_thresh": cfg.MODEL.RPN.NMS_THRESH, + "batch_size_per_image": cfg.MODEL.RPN.BATCH_SIZE_PER_IMAGE, + "positive_fraction": cfg.MODEL.RPN.POSITIVE_FRACTION, + "loss_weight": { + "loss_rpn_cls": cfg.MODEL.RPN.LOSS_WEIGHT, + "loss_rpn_loc": cfg.MODEL.RPN.BBOX_REG_LOSS_WEIGHT * cfg.MODEL.RPN.LOSS_WEIGHT, + }, + "anchor_boundary_thresh": cfg.MODEL.RPN.BOUNDARY_THRESH, + "box2box_transform": Box2BoxTransform(weights=cfg.MODEL.RPN.BBOX_REG_WEIGHTS), + "box_reg_loss_type": cfg.MODEL.RPN.BBOX_REG_LOSS_TYPE, + "smooth_l1_beta": cfg.MODEL.RPN.SMOOTH_L1_BETA, + } + + ret["pre_nms_topk"] = (cfg.MODEL.RPN.PRE_NMS_TOPK_TRAIN, cfg.MODEL.RPN.PRE_NMS_TOPK_TEST) + ret["post_nms_topk"] = (cfg.MODEL.RPN.POST_NMS_TOPK_TRAIN, cfg.MODEL.RPN.POST_NMS_TOPK_TEST) + + ret["anchor_generator"] = build_anchor_generator(cfg, [input_shape[f] for f in in_features]) + ret["anchor_matcher"] = Matcher( + cfg.MODEL.RPN.IOU_THRESHOLDS, cfg.MODEL.RPN.IOU_LABELS, allow_low_quality_matches=True + ) + ret["head"] = build_rpn_head(cfg, [input_shape[f] for f in in_features]) + return ret + + def _subsample_labels(self, label): + """ + Randomly sample a subset of positive and negative examples, and overwrite + the label vector to the ignore value (-1) for all elements that are not + included in the sample. + + Args: + labels (Tensor): a vector of -1, 0, 1. Will be modified in-place and returned. + """ + pos_idx, neg_idx = subsample_labels( + label, self.batch_size_per_image, self.positive_fraction, 0 + ) + # Fill with the ignore label (-1), then set positive and negative labels + label.fill_(-1) + label.scatter_(0, pos_idx, 1) + label.scatter_(0, neg_idx, 0) + return label + + @torch.jit.unused + @torch.no_grad() + def label_and_sample_anchors( + self, anchors: List[Boxes], gt_instances: List[Instances] + ) -> Tuple[List[torch.Tensor], List[torch.Tensor]]: + """ + Args: + anchors (list[Boxes]): anchors for each feature map. + gt_instances: the ground-truth instances for each image. + + Returns: + list[Tensor]: + List of #img tensors. i-th element is a vector of labels whose length is + the total number of anchors across all feature maps R = sum(Hi * Wi * A). + Label values are in {-1, 0, 1}, with meanings: -1 = ignore; 0 = negative + class; 1 = positive class. + list[Tensor]: + i-th element is a Rx4 tensor. The values are the matched gt boxes for each + anchor. Values are undefined for those anchors not labeled as 1. + """ + anchors = Boxes.cat(anchors) + + gt_boxes = [x.gt_boxes for x in gt_instances] + image_sizes = [x.image_size for x in gt_instances] + del gt_instances + + gt_labels = [] + matched_gt_boxes = [] + for image_size_i, gt_boxes_i in zip(image_sizes, gt_boxes): + """ + image_size_i: (h, w) for the i-th image + gt_boxes_i: ground-truth boxes for i-th image + """ + + match_quality_matrix = retry_if_cuda_oom(pairwise_iou)(gt_boxes_i, anchors) + matched_idxs, gt_labels_i = retry_if_cuda_oom(self.anchor_matcher)(match_quality_matrix) + # Matching is memory-expensive and may result in CPU tensors. But the result is small + gt_labels_i = gt_labels_i.to(device=gt_boxes_i.device) + del match_quality_matrix + + if self.anchor_boundary_thresh >= 0: + # Discard anchors that go out of the boundaries of the image + # NOTE: This is legacy functionality that is turned off by default in Detectron2 + anchors_inside_image = anchors.inside_box(image_size_i, self.anchor_boundary_thresh) + gt_labels_i[~anchors_inside_image] = -1 + + # A vector of labels (-1, 0, 1) for each anchor + gt_labels_i = self._subsample_labels(gt_labels_i) + + if len(gt_boxes_i) == 0: + # These values won't be used anyway since the anchor is labeled as background + matched_gt_boxes_i = torch.zeros_like(anchors.tensor) + else: + # TODO wasted indexing computation for ignored boxes + matched_gt_boxes_i = gt_boxes_i[matched_idxs].tensor + + gt_labels.append(gt_labels_i) # N,AHW + matched_gt_boxes.append(matched_gt_boxes_i) + return gt_labels, matched_gt_boxes + + @torch.jit.unused + def losses( + self, + anchors: List[Boxes], + pred_objectness_logits: List[torch.Tensor], + gt_labels: List[torch.Tensor], + pred_anchor_deltas: List[torch.Tensor], + gt_boxes: List[torch.Tensor], + ) -> Dict[str, torch.Tensor]: + """ + Return the losses from a set of RPN predictions and their associated ground-truth. + + Args: + anchors (list[Boxes or RotatedBoxes]): anchors for each feature map, each + has shape (Hi*Wi*A, B), where B is box dimension (4 or 5). + pred_objectness_logits (list[Tensor]): A list of L elements. + Element i is a tensor of shape (N, Hi*Wi*A) representing + the predicted objectness logits for all anchors. + gt_labels (list[Tensor]): Output of :meth:`label_and_sample_anchors`. + pred_anchor_deltas (list[Tensor]): A list of L elements. Element i is a tensor of shape + (N, Hi*Wi*A, 4 or 5) representing the predicted "deltas" used to transform anchors + to proposals. + gt_boxes (list[Tensor]): Output of :meth:`label_and_sample_anchors`. + + Returns: + dict[loss name -> loss value]: A dict mapping from loss name to loss value. + Loss names are: `loss_rpn_cls` for objectness classification and + `loss_rpn_loc` for proposal localization. + """ + num_images = len(gt_labels) + gt_labels = torch.stack(gt_labels) # (N, sum(Hi*Wi*Ai)) + + # Log the number of positive/negative anchors per-image that's used in training + pos_mask = gt_labels == 1 + num_pos_anchors = pos_mask.sum().item() + num_neg_anchors = (gt_labels == 0).sum().item() + storage = get_event_storage() + storage.put_scalar("rpn/num_pos_anchors", num_pos_anchors / num_images) + storage.put_scalar("rpn/num_neg_anchors", num_neg_anchors / num_images) + + localization_loss = _dense_box_regression_loss( + anchors, + self.box2box_transform, + pred_anchor_deltas, + gt_boxes, + pos_mask, + box_reg_loss_type=self.box_reg_loss_type, + smooth_l1_beta=self.smooth_l1_beta, + ) + + valid_mask = gt_labels >= 0 + objectness_loss = F.binary_cross_entropy_with_logits( + cat(pred_objectness_logits, dim=1)[valid_mask], + gt_labels[valid_mask].to(torch.float32), + reduction="sum", + ) + normalizer = self.batch_size_per_image * num_images + losses = { + "loss_rpn_cls": objectness_loss / normalizer, + # The original Faster R-CNN paper uses a slightly different normalizer + # for loc loss. But it doesn't matter in practice + "loss_rpn_loc": localization_loss / normalizer, + } + losses = {k: v * self.loss_weight.get(k, 1.0) for k, v in losses.items()} + return losses + + def forward( + self, + images: ImageList, + features: Dict[str, torch.Tensor], + gt_instances: Optional[List[Instances]] = None, + ): + """ + Args: + images (ImageList): input images of length `N` + features (dict[str, Tensor]): input data as a mapping from feature + map name to tensor. Axis 0 represents the number of images `N` in + the input data; axes 1-3 are channels, height, and width, which may + vary between feature maps (e.g., if a feature pyramid is used). + gt_instances (list[Instances], optional): a length `N` list of `Instances`s. + Each `Instances` stores ground-truth instances for the corresponding image. + + Returns: + proposals: list[Instances]: contains fields "proposal_boxes", "objectness_logits" + loss: dict[Tensor] or None + """ + features = [features[f] for f in self.in_features] + anchors = self.anchor_generator(features) + + pred_objectness_logits, pred_anchor_deltas = self.rpn_head(features) + # Transpose the Hi*Wi*A dimension to the middle: + pred_objectness_logits = [ + # (N, A, Hi, Wi) -> (N, Hi, Wi, A) -> (N, Hi*Wi*A) + score.permute(0, 2, 3, 1).flatten(1) + for score in pred_objectness_logits + ] + pred_anchor_deltas = [ + # (N, A*B, Hi, Wi) -> (N, A, B, Hi, Wi) -> (N, Hi, Wi, A, B) -> (N, Hi*Wi*A, B) + x.view(x.shape[0], -1, self.anchor_generator.box_dim, x.shape[-2], x.shape[-1]) + .permute(0, 3, 4, 1, 2) + .flatten(1, -2) + for x in pred_anchor_deltas + ] + + if self.training: + assert gt_instances is not None, "RPN requires gt_instances in training!" + gt_labels, gt_boxes = self.label_and_sample_anchors(anchors, gt_instances) + losses = self.losses( + anchors, pred_objectness_logits, gt_labels, pred_anchor_deltas, gt_boxes + ) + else: + losses = {} + proposals = self.predict_proposals( + anchors, pred_objectness_logits, pred_anchor_deltas, images.image_sizes + ) + return proposals, losses + + def predict_proposals( + self, + anchors: List[Boxes], + pred_objectness_logits: List[torch.Tensor], + pred_anchor_deltas: List[torch.Tensor], + image_sizes: List[Tuple[int, int]], + ): + """ + Decode all the predicted box regression deltas to proposals. Find the top proposals + by applying NMS and removing boxes that are too small. + + Returns: + proposals (list[Instances]): list of N Instances. The i-th Instances + stores post_nms_topk object proposals for image i, sorted by their + objectness score in descending order. + """ + # The proposals are treated as fixed for joint training with roi heads. + # This approach ignores the derivative w.r.t. the proposal boxes’ coordinates that + # are also network responses. + with torch.no_grad(): + pred_proposals = self._decode_proposals(anchors, pred_anchor_deltas) + return find_top_rpn_proposals( + pred_proposals, + pred_objectness_logits, + image_sizes, + self.nms_thresh, + self.pre_nms_topk[self.training], + self.post_nms_topk[self.training], + self.min_box_size, + self.training, + ) + + def _decode_proposals(self, anchors: List[Boxes], pred_anchor_deltas: List[torch.Tensor]): + """ + Transform anchors into proposals by applying the predicted anchor deltas. + + Returns: + proposals (list[Tensor]): A list of L tensors. Tensor i has shape + (N, Hi*Wi*A, B) + """ + N = pred_anchor_deltas[0].shape[0] + proposals = [] + # For each feature map + for anchors_i, pred_anchor_deltas_i in zip(anchors, pred_anchor_deltas): + B = anchors_i.tensor.size(1) + pred_anchor_deltas_i = pred_anchor_deltas_i.reshape(-1, B) + # Expand anchors to shape (N*Hi*Wi*A, B) + anchors_i = anchors_i.tensor.unsqueeze(0).expand(N, -1, -1).reshape(-1, B) + proposals_i = self.box2box_transform.apply_deltas(pred_anchor_deltas_i, anchors_i) + # Append feature map proposals with shape (N, Hi*Wi*A, B) + proposals.append(proposals_i.view(N, -1, B)) + return proposals diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/rrpn.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/rrpn.py new file mode 100644 index 00000000..8535dcd9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/proposal_generator/rrpn.py @@ -0,0 +1,209 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import itertools +import logging +from typing import Dict, List +import torch + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.layers import ShapeSpec, batched_nms_rotated, cat +from annotator.oneformer.detectron2.structures import Instances, RotatedBoxes, pairwise_iou_rotated +from annotator.oneformer.detectron2.utils.memory import retry_if_cuda_oom + +from ..box_regression import Box2BoxTransformRotated +from .build import PROPOSAL_GENERATOR_REGISTRY +from .proposal_utils import _is_tracing +from .rpn import RPN + +logger = logging.getLogger(__name__) + + +def find_top_rrpn_proposals( + proposals, + pred_objectness_logits, + image_sizes, + nms_thresh, + pre_nms_topk, + post_nms_topk, + min_box_size, + training, +): + """ + For each feature map, select the `pre_nms_topk` highest scoring proposals, + apply NMS, clip proposals, and remove small boxes. Return the `post_nms_topk` + highest scoring proposals among all the feature maps if `training` is True, + otherwise, returns the highest `post_nms_topk` scoring proposals for each + feature map. + + Args: + proposals (list[Tensor]): A list of L tensors. Tensor i has shape (N, Hi*Wi*A, 5). + All proposal predictions on the feature maps. + pred_objectness_logits (list[Tensor]): A list of L tensors. Tensor i has shape (N, Hi*Wi*A). + image_sizes (list[tuple]): sizes (h, w) for each image + nms_thresh (float): IoU threshold to use for NMS + pre_nms_topk (int): number of top k scoring proposals to keep before applying NMS. + When RRPN is run on multiple feature maps (as in FPN) this number is per + feature map. + post_nms_topk (int): number of top k scoring proposals to keep after applying NMS. + When RRPN is run on multiple feature maps (as in FPN) this number is total, + over all feature maps. + min_box_size(float): minimum proposal box side length in pixels (absolute units wrt + input images). + training (bool): True if proposals are to be used in training, otherwise False. + This arg exists only to support a legacy bug; look for the "NB: Legacy bug ..." + comment. + + Returns: + proposals (list[Instances]): list of N Instances. The i-th Instances + stores post_nms_topk object proposals for image i. + """ + num_images = len(image_sizes) + device = proposals[0].device + + # 1. Select top-k anchor for every level and every image + topk_scores = [] # #lvl Tensor, each of shape N x topk + topk_proposals = [] + level_ids = [] # #lvl Tensor, each of shape (topk,) + batch_idx = torch.arange(num_images, device=device) + for level_id, proposals_i, logits_i in zip( + itertools.count(), proposals, pred_objectness_logits + ): + Hi_Wi_A = logits_i.shape[1] + if isinstance(Hi_Wi_A, torch.Tensor): # it's a tensor in tracing + num_proposals_i = torch.clamp(Hi_Wi_A, max=pre_nms_topk) + else: + num_proposals_i = min(Hi_Wi_A, pre_nms_topk) + + topk_scores_i, topk_idx = logits_i.topk(num_proposals_i, dim=1) + + # each is N x topk + topk_proposals_i = proposals_i[batch_idx[:, None], topk_idx] # N x topk x 5 + + topk_proposals.append(topk_proposals_i) + topk_scores.append(topk_scores_i) + level_ids.append(torch.full((num_proposals_i,), level_id, dtype=torch.int64, device=device)) + + # 2. Concat all levels together + topk_scores = cat(topk_scores, dim=1) + topk_proposals = cat(topk_proposals, dim=1) + level_ids = cat(level_ids, dim=0) + + # 3. For each image, run a per-level NMS, and choose topk results. + results = [] + for n, image_size in enumerate(image_sizes): + boxes = RotatedBoxes(topk_proposals[n]) + scores_per_img = topk_scores[n] + lvl = level_ids + + valid_mask = torch.isfinite(boxes.tensor).all(dim=1) & torch.isfinite(scores_per_img) + if not valid_mask.all(): + if training: + raise FloatingPointError( + "Predicted boxes or scores contain Inf/NaN. Training has diverged." + ) + boxes = boxes[valid_mask] + scores_per_img = scores_per_img[valid_mask] + lvl = lvl[valid_mask] + boxes.clip(image_size) + + # filter empty boxes + keep = boxes.nonempty(threshold=min_box_size) + if _is_tracing() or keep.sum().item() != len(boxes): + boxes, scores_per_img, lvl = (boxes[keep], scores_per_img[keep], lvl[keep]) + + keep = batched_nms_rotated(boxes.tensor, scores_per_img, lvl, nms_thresh) + # In Detectron1, there was different behavior during training vs. testing. + # (https://github.com/facebookresearch/Detectron/issues/459) + # During training, topk is over the proposals from *all* images in the training batch. + # During testing, it is over the proposals for each image separately. + # As a result, the training behavior becomes batch-dependent, + # and the configuration "POST_NMS_TOPK_TRAIN" end up relying on the batch size. + # This bug is addressed in Detectron2 to make the behavior independent of batch size. + keep = keep[:post_nms_topk] + + res = Instances(image_size) + res.proposal_boxes = boxes[keep] + res.objectness_logits = scores_per_img[keep] + results.append(res) + return results + + +@PROPOSAL_GENERATOR_REGISTRY.register() +class RRPN(RPN): + """ + Rotated Region Proposal Network described in :paper:`RRPN`. + """ + + @configurable + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + if self.anchor_boundary_thresh >= 0: + raise NotImplementedError( + "anchor_boundary_thresh is a legacy option not implemented for RRPN." + ) + + @classmethod + def from_config(cls, cfg, input_shape: Dict[str, ShapeSpec]): + ret = super().from_config(cfg, input_shape) + ret["box2box_transform"] = Box2BoxTransformRotated(weights=cfg.MODEL.RPN.BBOX_REG_WEIGHTS) + return ret + + @torch.no_grad() + def label_and_sample_anchors(self, anchors: List[RotatedBoxes], gt_instances: List[Instances]): + """ + Args: + anchors (list[RotatedBoxes]): anchors for each feature map. + gt_instances: the ground-truth instances for each image. + + Returns: + list[Tensor]: + List of #img tensors. i-th element is a vector of labels whose length is + the total number of anchors across feature maps. Label values are in {-1, 0, 1}, + with meanings: -1 = ignore; 0 = negative class; 1 = positive class. + list[Tensor]: + i-th element is a Nx5 tensor, where N is the total number of anchors across + feature maps. The values are the matched gt boxes for each anchor. + Values are undefined for those anchors not labeled as 1. + """ + anchors = RotatedBoxes.cat(anchors) + + gt_boxes = [x.gt_boxes for x in gt_instances] + del gt_instances + + gt_labels = [] + matched_gt_boxes = [] + for gt_boxes_i in gt_boxes: + """ + gt_boxes_i: ground-truth boxes for i-th image + """ + match_quality_matrix = retry_if_cuda_oom(pairwise_iou_rotated)(gt_boxes_i, anchors) + matched_idxs, gt_labels_i = retry_if_cuda_oom(self.anchor_matcher)(match_quality_matrix) + # Matching is memory-expensive and may result in CPU tensors. But the result is small + gt_labels_i = gt_labels_i.to(device=gt_boxes_i.device) + + # A vector of labels (-1, 0, 1) for each anchor + gt_labels_i = self._subsample_labels(gt_labels_i) + + if len(gt_boxes_i) == 0: + # These values won't be used anyway since the anchor is labeled as background + matched_gt_boxes_i = torch.zeros_like(anchors.tensor) + else: + # TODO wasted indexing computation for ignored boxes + matched_gt_boxes_i = gt_boxes_i[matched_idxs].tensor + + gt_labels.append(gt_labels_i) # N,AHW + matched_gt_boxes.append(matched_gt_boxes_i) + return gt_labels, matched_gt_boxes + + @torch.no_grad() + def predict_proposals(self, anchors, pred_objectness_logits, pred_anchor_deltas, image_sizes): + pred_proposals = self._decode_proposals(anchors, pred_anchor_deltas) + return find_top_rrpn_proposals( + pred_proposals, + pred_objectness_logits, + image_sizes, + self.nms_thresh, + self.pre_nms_topk[self.training], + self.post_nms_topk[self.training], + self.min_box_size, + self.training, + ) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/__init__.py new file mode 100644 index 00000000..d13e9c57 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/__init__.py @@ -0,0 +1,29 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from .box_head import ROI_BOX_HEAD_REGISTRY, build_box_head, FastRCNNConvFCHead +from .keypoint_head import ( + ROI_KEYPOINT_HEAD_REGISTRY, + build_keypoint_head, + BaseKeypointRCNNHead, + KRCNNConvDeconvUpsampleHead, +) +from .mask_head import ( + ROI_MASK_HEAD_REGISTRY, + build_mask_head, + BaseMaskRCNNHead, + MaskRCNNConvUpsampleHead, +) +from .roi_heads import ( + ROI_HEADS_REGISTRY, + ROIHeads, + Res5ROIHeads, + StandardROIHeads, + build_roi_heads, + select_foreground_proposals, +) +from .cascade_rcnn import CascadeROIHeads +from .rotated_fast_rcnn import RROIHeads +from .fast_rcnn import FastRCNNOutputLayers + +from . import cascade_rcnn # isort:skip + +__all__ = list(globals().keys()) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/box_head.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/box_head.py new file mode 100644 index 00000000..1e598af4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/box_head.py @@ -0,0 +1,118 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import numpy as np +from typing import List +import fvcore.nn.weight_init as weight_init +import torch +from torch import nn + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.layers import Conv2d, ShapeSpec, get_norm +from annotator.oneformer.detectron2.utils.registry import Registry + +__all__ = ["FastRCNNConvFCHead", "build_box_head", "ROI_BOX_HEAD_REGISTRY"] + +ROI_BOX_HEAD_REGISTRY = Registry("ROI_BOX_HEAD") +ROI_BOX_HEAD_REGISTRY.__doc__ = """ +Registry for box heads, which make box predictions from per-region features. + +The registered object will be called with `obj(cfg, input_shape)`. +""" + + +# To get torchscript support, we make the head a subclass of `nn.Sequential`. +# Therefore, to add new layers in this head class, please make sure they are +# added in the order they will be used in forward(). +@ROI_BOX_HEAD_REGISTRY.register() +class FastRCNNConvFCHead(nn.Sequential): + """ + A head with several 3x3 conv layers (each followed by norm & relu) and then + several fc layers (each followed by relu). + """ + + @configurable + def __init__( + self, input_shape: ShapeSpec, *, conv_dims: List[int], fc_dims: List[int], conv_norm="" + ): + """ + NOTE: this interface is experimental. + + Args: + input_shape (ShapeSpec): shape of the input feature. + conv_dims (list[int]): the output dimensions of the conv layers + fc_dims (list[int]): the output dimensions of the fc layers + conv_norm (str or callable): normalization for the conv layers. + See :func:`detectron2.layers.get_norm` for supported types. + """ + super().__init__() + assert len(conv_dims) + len(fc_dims) > 0 + + self._output_size = (input_shape.channels, input_shape.height, input_shape.width) + + self.conv_norm_relus = [] + for k, conv_dim in enumerate(conv_dims): + conv = Conv2d( + self._output_size[0], + conv_dim, + kernel_size=3, + padding=1, + bias=not conv_norm, + norm=get_norm(conv_norm, conv_dim), + activation=nn.ReLU(), + ) + self.add_module("conv{}".format(k + 1), conv) + self.conv_norm_relus.append(conv) + self._output_size = (conv_dim, self._output_size[1], self._output_size[2]) + + self.fcs = [] + for k, fc_dim in enumerate(fc_dims): + if k == 0: + self.add_module("flatten", nn.Flatten()) + fc = nn.Linear(int(np.prod(self._output_size)), fc_dim) + self.add_module("fc{}".format(k + 1), fc) + self.add_module("fc_relu{}".format(k + 1), nn.ReLU()) + self.fcs.append(fc) + self._output_size = fc_dim + + for layer in self.conv_norm_relus: + weight_init.c2_msra_fill(layer) + for layer in self.fcs: + weight_init.c2_xavier_fill(layer) + + @classmethod + def from_config(cls, cfg, input_shape): + num_conv = cfg.MODEL.ROI_BOX_HEAD.NUM_CONV + conv_dim = cfg.MODEL.ROI_BOX_HEAD.CONV_DIM + num_fc = cfg.MODEL.ROI_BOX_HEAD.NUM_FC + fc_dim = cfg.MODEL.ROI_BOX_HEAD.FC_DIM + return { + "input_shape": input_shape, + "conv_dims": [conv_dim] * num_conv, + "fc_dims": [fc_dim] * num_fc, + "conv_norm": cfg.MODEL.ROI_BOX_HEAD.NORM, + } + + def forward(self, x): + for layer in self: + x = layer(x) + return x + + @property + @torch.jit.unused + def output_shape(self): + """ + Returns: + ShapeSpec: the output feature shape + """ + o = self._output_size + if isinstance(o, int): + return ShapeSpec(channels=o) + else: + return ShapeSpec(channels=o[0], height=o[1], width=o[2]) + + +def build_box_head(cfg, input_shape): + """ + Build a box head defined by `cfg.MODEL.ROI_BOX_HEAD.NAME`. + """ + name = cfg.MODEL.ROI_BOX_HEAD.NAME + return ROI_BOX_HEAD_REGISTRY.get(name)(cfg, input_shape) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/cascade_rcnn.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/cascade_rcnn.py new file mode 100644 index 00000000..69b837be --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/cascade_rcnn.py @@ -0,0 +1,299 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from typing import List +import torch +from torch import nn +from torch.autograd.function import Function + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.layers import ShapeSpec +from annotator.oneformer.detectron2.structures import Boxes, Instances, pairwise_iou +from annotator.oneformer.detectron2.utils.events import get_event_storage + +from ..box_regression import Box2BoxTransform +from ..matcher import Matcher +from ..poolers import ROIPooler +from .box_head import build_box_head +from .fast_rcnn import FastRCNNOutputLayers, fast_rcnn_inference +from .roi_heads import ROI_HEADS_REGISTRY, StandardROIHeads + + +class _ScaleGradient(Function): + @staticmethod + def forward(ctx, input, scale): + ctx.scale = scale + return input + + @staticmethod + def backward(ctx, grad_output): + return grad_output * ctx.scale, None + + +@ROI_HEADS_REGISTRY.register() +class CascadeROIHeads(StandardROIHeads): + """ + The ROI heads that implement :paper:`Cascade R-CNN`. + """ + + @configurable + def __init__( + self, + *, + box_in_features: List[str], + box_pooler: ROIPooler, + box_heads: List[nn.Module], + box_predictors: List[nn.Module], + proposal_matchers: List[Matcher], + **kwargs, + ): + """ + NOTE: this interface is experimental. + + Args: + box_pooler (ROIPooler): pooler that extracts region features from given boxes + box_heads (list[nn.Module]): box head for each cascade stage + box_predictors (list[nn.Module]): box predictor for each cascade stage + proposal_matchers (list[Matcher]): matcher with different IoU thresholds to + match boxes with ground truth for each stage. The first matcher matches + RPN proposals with ground truth, the other matchers use boxes predicted + by the previous stage as proposals and match them with ground truth. + """ + assert "proposal_matcher" not in kwargs, ( + "CascadeROIHeads takes 'proposal_matchers=' for each stage instead " + "of one 'proposal_matcher='." + ) + # The first matcher matches RPN proposals with ground truth, done in the base class + kwargs["proposal_matcher"] = proposal_matchers[0] + num_stages = self.num_cascade_stages = len(box_heads) + box_heads = nn.ModuleList(box_heads) + box_predictors = nn.ModuleList(box_predictors) + assert len(box_predictors) == num_stages, f"{len(box_predictors)} != {num_stages}!" + assert len(proposal_matchers) == num_stages, f"{len(proposal_matchers)} != {num_stages}!" + super().__init__( + box_in_features=box_in_features, + box_pooler=box_pooler, + box_head=box_heads, + box_predictor=box_predictors, + **kwargs, + ) + self.proposal_matchers = proposal_matchers + + @classmethod + def from_config(cls, cfg, input_shape): + ret = super().from_config(cfg, input_shape) + ret.pop("proposal_matcher") + return ret + + @classmethod + def _init_box_head(cls, cfg, input_shape): + # fmt: off + in_features = cfg.MODEL.ROI_HEADS.IN_FEATURES + pooler_resolution = cfg.MODEL.ROI_BOX_HEAD.POOLER_RESOLUTION + pooler_scales = tuple(1.0 / input_shape[k].stride for k in in_features) + sampling_ratio = cfg.MODEL.ROI_BOX_HEAD.POOLER_SAMPLING_RATIO + pooler_type = cfg.MODEL.ROI_BOX_HEAD.POOLER_TYPE + cascade_bbox_reg_weights = cfg.MODEL.ROI_BOX_CASCADE_HEAD.BBOX_REG_WEIGHTS + cascade_ious = cfg.MODEL.ROI_BOX_CASCADE_HEAD.IOUS + assert len(cascade_bbox_reg_weights) == len(cascade_ious) + assert cfg.MODEL.ROI_BOX_HEAD.CLS_AGNOSTIC_BBOX_REG, \ + "CascadeROIHeads only support class-agnostic regression now!" + assert cascade_ious[0] == cfg.MODEL.ROI_HEADS.IOU_THRESHOLDS[0] + # fmt: on + + in_channels = [input_shape[f].channels for f in in_features] + # Check all channel counts are equal + assert len(set(in_channels)) == 1, in_channels + in_channels = in_channels[0] + + box_pooler = ROIPooler( + output_size=pooler_resolution, + scales=pooler_scales, + sampling_ratio=sampling_ratio, + pooler_type=pooler_type, + ) + pooled_shape = ShapeSpec( + channels=in_channels, width=pooler_resolution, height=pooler_resolution + ) + + box_heads, box_predictors, proposal_matchers = [], [], [] + for match_iou, bbox_reg_weights in zip(cascade_ious, cascade_bbox_reg_weights): + box_head = build_box_head(cfg, pooled_shape) + box_heads.append(box_head) + box_predictors.append( + FastRCNNOutputLayers( + cfg, + box_head.output_shape, + box2box_transform=Box2BoxTransform(weights=bbox_reg_weights), + ) + ) + proposal_matchers.append(Matcher([match_iou], [0, 1], allow_low_quality_matches=False)) + return { + "box_in_features": in_features, + "box_pooler": box_pooler, + "box_heads": box_heads, + "box_predictors": box_predictors, + "proposal_matchers": proposal_matchers, + } + + def forward(self, images, features, proposals, targets=None): + del images + if self.training: + proposals = self.label_and_sample_proposals(proposals, targets) + + if self.training: + # Need targets to box head + losses = self._forward_box(features, proposals, targets) + losses.update(self._forward_mask(features, proposals)) + losses.update(self._forward_keypoint(features, proposals)) + return proposals, losses + else: + pred_instances = self._forward_box(features, proposals) + pred_instances = self.forward_with_given_boxes(features, pred_instances) + return pred_instances, {} + + def _forward_box(self, features, proposals, targets=None): + """ + Args: + features, targets: the same as in + Same as in :meth:`ROIHeads.forward`. + proposals (list[Instances]): the per-image object proposals with + their matching ground truth. + Each has fields "proposal_boxes", and "objectness_logits", + "gt_classes", "gt_boxes". + """ + features = [features[f] for f in self.box_in_features] + head_outputs = [] # (predictor, predictions, proposals) + prev_pred_boxes = None + image_sizes = [x.image_size for x in proposals] + for k in range(self.num_cascade_stages): + if k > 0: + # The output boxes of the previous stage are used to create the input + # proposals of the next stage. + proposals = self._create_proposals_from_boxes(prev_pred_boxes, image_sizes) + if self.training: + proposals = self._match_and_label_boxes(proposals, k, targets) + predictions = self._run_stage(features, proposals, k) + prev_pred_boxes = self.box_predictor[k].predict_boxes(predictions, proposals) + head_outputs.append((self.box_predictor[k], predictions, proposals)) + + if self.training: + losses = {} + storage = get_event_storage() + for stage, (predictor, predictions, proposals) in enumerate(head_outputs): + with storage.name_scope("stage{}".format(stage)): + stage_losses = predictor.losses(predictions, proposals) + losses.update({k + "_stage{}".format(stage): v for k, v in stage_losses.items()}) + return losses + else: + # Each is a list[Tensor] of length #image. Each tensor is Ri x (K+1) + scores_per_stage = [h[0].predict_probs(h[1], h[2]) for h in head_outputs] + + # Average the scores across heads + scores = [ + sum(list(scores_per_image)) * (1.0 / self.num_cascade_stages) + for scores_per_image in zip(*scores_per_stage) + ] + # Use the boxes of the last head + predictor, predictions, proposals = head_outputs[-1] + boxes = predictor.predict_boxes(predictions, proposals) + pred_instances, _ = fast_rcnn_inference( + boxes, + scores, + image_sizes, + predictor.test_score_thresh, + predictor.test_nms_thresh, + predictor.test_topk_per_image, + ) + return pred_instances + + @torch.no_grad() + def _match_and_label_boxes(self, proposals, stage, targets): + """ + Match proposals with groundtruth using the matcher at the given stage. + Label the proposals as foreground or background based on the match. + + Args: + proposals (list[Instances]): One Instances for each image, with + the field "proposal_boxes". + stage (int): the current stage + targets (list[Instances]): the ground truth instances + + Returns: + list[Instances]: the same proposals, but with fields "gt_classes" and "gt_boxes" + """ + num_fg_samples, num_bg_samples = [], [] + for proposals_per_image, targets_per_image in zip(proposals, targets): + match_quality_matrix = pairwise_iou( + targets_per_image.gt_boxes, proposals_per_image.proposal_boxes + ) + # proposal_labels are 0 or 1 + matched_idxs, proposal_labels = self.proposal_matchers[stage](match_quality_matrix) + if len(targets_per_image) > 0: + gt_classes = targets_per_image.gt_classes[matched_idxs] + # Label unmatched proposals (0 label from matcher) as background (label=num_classes) + gt_classes[proposal_labels == 0] = self.num_classes + gt_boxes = targets_per_image.gt_boxes[matched_idxs] + else: + gt_classes = torch.zeros_like(matched_idxs) + self.num_classes + gt_boxes = Boxes( + targets_per_image.gt_boxes.tensor.new_zeros((len(proposals_per_image), 4)) + ) + proposals_per_image.gt_classes = gt_classes + proposals_per_image.gt_boxes = gt_boxes + + num_fg_samples.append((proposal_labels == 1).sum().item()) + num_bg_samples.append(proposal_labels.numel() - num_fg_samples[-1]) + + # Log the number of fg/bg samples in each stage + storage = get_event_storage() + storage.put_scalar( + "stage{}/roi_head/num_fg_samples".format(stage), + sum(num_fg_samples) / len(num_fg_samples), + ) + storage.put_scalar( + "stage{}/roi_head/num_bg_samples".format(stage), + sum(num_bg_samples) / len(num_bg_samples), + ) + return proposals + + def _run_stage(self, features, proposals, stage): + """ + Args: + features (list[Tensor]): #lvl input features to ROIHeads + proposals (list[Instances]): #image Instances, with the field "proposal_boxes" + stage (int): the current stage + + Returns: + Same output as `FastRCNNOutputLayers.forward()`. + """ + box_features = self.box_pooler(features, [x.proposal_boxes for x in proposals]) + # The original implementation averages the losses among heads, + # but scale up the parameter gradients of the heads. + # This is equivalent to adding the losses among heads, + # but scale down the gradients on features. + if self.training: + box_features = _ScaleGradient.apply(box_features, 1.0 / self.num_cascade_stages) + box_features = self.box_head[stage](box_features) + return self.box_predictor[stage](box_features) + + def _create_proposals_from_boxes(self, boxes, image_sizes): + """ + Args: + boxes (list[Tensor]): per-image predicted boxes, each of shape Ri x 4 + image_sizes (list[tuple]): list of image shapes in (h, w) + + Returns: + list[Instances]: per-image proposals with the given boxes. + """ + # Just like RPN, the proposals should not have gradients + boxes = [Boxes(b.detach()) for b in boxes] + proposals = [] + for boxes_per_image, image_size in zip(boxes, image_sizes): + boxes_per_image.clip(image_size) + if self.training: + # do not filter empty boxes at inference time, + # because the scores from each stage need to be aligned and added later + boxes_per_image = boxes_per_image[boxes_per_image.nonempty()] + prop = Instances(image_size) + prop.proposal_boxes = boxes_per_image + proposals.append(prop) + return proposals diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/fast_rcnn.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/fast_rcnn.py new file mode 100644 index 00000000..a81c58ea --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/fast_rcnn.py @@ -0,0 +1,569 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import logging +from typing import Callable, Dict, List, Optional, Tuple, Union +import torch +from torch import nn +from torch.nn import functional as F + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.data.detection_utils import get_fed_loss_cls_weights +from annotator.oneformer.detectron2.layers import ShapeSpec, batched_nms, cat, cross_entropy, nonzero_tuple +from annotator.oneformer.detectron2.modeling.box_regression import Box2BoxTransform, _dense_box_regression_loss +from annotator.oneformer.detectron2.structures import Boxes, Instances +from annotator.oneformer.detectron2.utils.events import get_event_storage + +__all__ = ["fast_rcnn_inference", "FastRCNNOutputLayers"] + + +logger = logging.getLogger(__name__) + +""" +Shape shorthand in this module: + + N: number of images in the minibatch + R: number of ROIs, combined over all images, in the minibatch + Ri: number of ROIs in image i + K: number of foreground classes. E.g.,there are 80 foreground classes in COCO. + +Naming convention: + + deltas: refers to the 4-d (dx, dy, dw, dh) deltas that parameterize the box2box + transform (see :class:`box_regression.Box2BoxTransform`). + + pred_class_logits: predicted class scores in [-inf, +inf]; use + softmax(pred_class_logits) to estimate P(class). + + gt_classes: ground-truth classification labels in [0, K], where [0, K) represent + foreground object classes and K represents the background class. + + pred_proposal_deltas: predicted box2box transform deltas for transforming proposals + to detection box predictions. + + gt_proposal_deltas: ground-truth box2box transform deltas +""" + + +def fast_rcnn_inference( + boxes: List[torch.Tensor], + scores: List[torch.Tensor], + image_shapes: List[Tuple[int, int]], + score_thresh: float, + nms_thresh: float, + topk_per_image: int, +): + """ + Call `fast_rcnn_inference_single_image` for all images. + + Args: + boxes (list[Tensor]): A list of Tensors of predicted class-specific or class-agnostic + boxes for each image. Element i has shape (Ri, K * 4) if doing + class-specific regression, or (Ri, 4) if doing class-agnostic + regression, where Ri is the number of predicted objects for image i. + This is compatible with the output of :meth:`FastRCNNOutputLayers.predict_boxes`. + scores (list[Tensor]): A list of Tensors of predicted class scores for each image. + Element i has shape (Ri, K + 1), where Ri is the number of predicted objects + for image i. Compatible with the output of :meth:`FastRCNNOutputLayers.predict_probs`. + image_shapes (list[tuple]): A list of (width, height) tuples for each image in the batch. + score_thresh (float): Only return detections with a confidence score exceeding this + threshold. + nms_thresh (float): The threshold to use for box non-maximum suppression. Value in [0, 1]. + topk_per_image (int): The number of top scoring detections to return. Set < 0 to return + all detections. + + Returns: + instances: (list[Instances]): A list of N instances, one for each image in the batch, + that stores the topk most confidence detections. + kept_indices: (list[Tensor]): A list of 1D tensor of length of N, each element indicates + the corresponding boxes/scores index in [0, Ri) from the input, for image i. + """ + result_per_image = [ + fast_rcnn_inference_single_image( + boxes_per_image, scores_per_image, image_shape, score_thresh, nms_thresh, topk_per_image + ) + for scores_per_image, boxes_per_image, image_shape in zip(scores, boxes, image_shapes) + ] + return [x[0] for x in result_per_image], [x[1] for x in result_per_image] + + +def _log_classification_stats(pred_logits, gt_classes, prefix="fast_rcnn"): + """ + Log the classification metrics to EventStorage. + + Args: + pred_logits: Rx(K+1) logits. The last column is for background class. + gt_classes: R labels + """ + num_instances = gt_classes.numel() + if num_instances == 0: + return + pred_classes = pred_logits.argmax(dim=1) + bg_class_ind = pred_logits.shape[1] - 1 + + fg_inds = (gt_classes >= 0) & (gt_classes < bg_class_ind) + num_fg = fg_inds.nonzero().numel() + fg_gt_classes = gt_classes[fg_inds] + fg_pred_classes = pred_classes[fg_inds] + + num_false_negative = (fg_pred_classes == bg_class_ind).nonzero().numel() + num_accurate = (pred_classes == gt_classes).nonzero().numel() + fg_num_accurate = (fg_pred_classes == fg_gt_classes).nonzero().numel() + + storage = get_event_storage() + storage.put_scalar(f"{prefix}/cls_accuracy", num_accurate / num_instances) + if num_fg > 0: + storage.put_scalar(f"{prefix}/fg_cls_accuracy", fg_num_accurate / num_fg) + storage.put_scalar(f"{prefix}/false_negative", num_false_negative / num_fg) + + +def fast_rcnn_inference_single_image( + boxes, + scores, + image_shape: Tuple[int, int], + score_thresh: float, + nms_thresh: float, + topk_per_image: int, +): + """ + Single-image inference. Return bounding-box detection results by thresholding + on scores and applying non-maximum suppression (NMS). + + Args: + Same as `fast_rcnn_inference`, but with boxes, scores, and image shapes + per image. + + Returns: + Same as `fast_rcnn_inference`, but for only one image. + """ + valid_mask = torch.isfinite(boxes).all(dim=1) & torch.isfinite(scores).all(dim=1) + if not valid_mask.all(): + boxes = boxes[valid_mask] + scores = scores[valid_mask] + + scores = scores[:, :-1] + num_bbox_reg_classes = boxes.shape[1] // 4 + # Convert to Boxes to use the `clip` function ... + boxes = Boxes(boxes.reshape(-1, 4)) + boxes.clip(image_shape) + boxes = boxes.tensor.view(-1, num_bbox_reg_classes, 4) # R x C x 4 + + # 1. Filter results based on detection scores. It can make NMS more efficient + # by filtering out low-confidence detections. + filter_mask = scores > score_thresh # R x K + # R' x 2. First column contains indices of the R predictions; + # Second column contains indices of classes. + filter_inds = filter_mask.nonzero() + if num_bbox_reg_classes == 1: + boxes = boxes[filter_inds[:, 0], 0] + else: + boxes = boxes[filter_mask] + scores = scores[filter_mask] + + # 2. Apply NMS for each class independently. + keep = batched_nms(boxes, scores, filter_inds[:, 1], nms_thresh) + if topk_per_image >= 0: + keep = keep[:topk_per_image] + boxes, scores, filter_inds = boxes[keep], scores[keep], filter_inds[keep] + + result = Instances(image_shape) + result.pred_boxes = Boxes(boxes) + result.scores = scores + result.pred_classes = filter_inds[:, 1] + return result, filter_inds[:, 0] + + +class FastRCNNOutputLayers(nn.Module): + """ + Two linear layers for predicting Fast R-CNN outputs: + + 1. proposal-to-detection box regression deltas + 2. classification scores + """ + + @configurable + def __init__( + self, + input_shape: ShapeSpec, + *, + box2box_transform, + num_classes: int, + test_score_thresh: float = 0.0, + test_nms_thresh: float = 0.5, + test_topk_per_image: int = 100, + cls_agnostic_bbox_reg: bool = False, + smooth_l1_beta: float = 0.0, + box_reg_loss_type: str = "smooth_l1", + loss_weight: Union[float, Dict[str, float]] = 1.0, + use_fed_loss: bool = False, + use_sigmoid_ce: bool = False, + get_fed_loss_cls_weights: Optional[Callable] = None, + fed_loss_num_classes: int = 50, + ): + """ + NOTE: this interface is experimental. + + Args: + input_shape (ShapeSpec): shape of the input feature to this module + box2box_transform (Box2BoxTransform or Box2BoxTransformRotated): + num_classes (int): number of foreground classes + test_score_thresh (float): threshold to filter predictions results. + test_nms_thresh (float): NMS threshold for prediction results. + test_topk_per_image (int): number of top predictions to produce per image. + cls_agnostic_bbox_reg (bool): whether to use class agnostic for bbox regression + smooth_l1_beta (float): transition point from L1 to L2 loss. Only used if + `box_reg_loss_type` is "smooth_l1" + box_reg_loss_type (str): Box regression loss type. One of: "smooth_l1", "giou", + "diou", "ciou" + loss_weight (float|dict): weights to use for losses. Can be single float for weighting + all losses, or a dict of individual weightings. Valid dict keys are: + * "loss_cls": applied to classification loss + * "loss_box_reg": applied to box regression loss + use_fed_loss (bool): whether to use federated loss which samples additional negative + classes to calculate the loss + use_sigmoid_ce (bool): whether to calculate the loss using weighted average of binary + cross entropy with logits. This could be used together with federated loss + get_fed_loss_cls_weights (Callable): a callable which takes dataset name and frequency + weight power, and returns the probabilities to sample negative classes for + federated loss. The implementation can be found in + detectron2/data/detection_utils.py + fed_loss_num_classes (int): number of federated classes to keep in total + """ + super().__init__() + if isinstance(input_shape, int): # some backward compatibility + input_shape = ShapeSpec(channels=input_shape) + self.num_classes = num_classes + input_size = input_shape.channels * (input_shape.width or 1) * (input_shape.height or 1) + # prediction layer for num_classes foreground classes and one background class (hence + 1) + self.cls_score = nn.Linear(input_size, num_classes + 1) + num_bbox_reg_classes = 1 if cls_agnostic_bbox_reg else num_classes + box_dim = len(box2box_transform.weights) + self.bbox_pred = nn.Linear(input_size, num_bbox_reg_classes * box_dim) + + nn.init.normal_(self.cls_score.weight, std=0.01) + nn.init.normal_(self.bbox_pred.weight, std=0.001) + for l in [self.cls_score, self.bbox_pred]: + nn.init.constant_(l.bias, 0) + + self.box2box_transform = box2box_transform + self.smooth_l1_beta = smooth_l1_beta + self.test_score_thresh = test_score_thresh + self.test_nms_thresh = test_nms_thresh + self.test_topk_per_image = test_topk_per_image + self.box_reg_loss_type = box_reg_loss_type + if isinstance(loss_weight, float): + loss_weight = {"loss_cls": loss_weight, "loss_box_reg": loss_weight} + self.loss_weight = loss_weight + self.use_fed_loss = use_fed_loss + self.use_sigmoid_ce = use_sigmoid_ce + self.fed_loss_num_classes = fed_loss_num_classes + + if self.use_fed_loss: + assert self.use_sigmoid_ce, "Please use sigmoid cross entropy loss with federated loss" + fed_loss_cls_weights = get_fed_loss_cls_weights() + assert ( + len(fed_loss_cls_weights) == self.num_classes + ), "Please check the provided fed_loss_cls_weights. Their size should match num_classes" + self.register_buffer("fed_loss_cls_weights", fed_loss_cls_weights) + + @classmethod + def from_config(cls, cfg, input_shape): + return { + "input_shape": input_shape, + "box2box_transform": Box2BoxTransform(weights=cfg.MODEL.ROI_BOX_HEAD.BBOX_REG_WEIGHTS), + # fmt: off + "num_classes" : cfg.MODEL.ROI_HEADS.NUM_CLASSES, + "cls_agnostic_bbox_reg" : cfg.MODEL.ROI_BOX_HEAD.CLS_AGNOSTIC_BBOX_REG, + "smooth_l1_beta" : cfg.MODEL.ROI_BOX_HEAD.SMOOTH_L1_BETA, + "test_score_thresh" : cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST, + "test_nms_thresh" : cfg.MODEL.ROI_HEADS.NMS_THRESH_TEST, + "test_topk_per_image" : cfg.TEST.DETECTIONS_PER_IMAGE, + "box_reg_loss_type" : cfg.MODEL.ROI_BOX_HEAD.BBOX_REG_LOSS_TYPE, + "loss_weight" : {"loss_box_reg": cfg.MODEL.ROI_BOX_HEAD.BBOX_REG_LOSS_WEIGHT}, # noqa + "use_fed_loss" : cfg.MODEL.ROI_BOX_HEAD.USE_FED_LOSS, + "use_sigmoid_ce" : cfg.MODEL.ROI_BOX_HEAD.USE_SIGMOID_CE, + "get_fed_loss_cls_weights" : lambda: get_fed_loss_cls_weights(dataset_names=cfg.DATASETS.TRAIN, freq_weight_power=cfg.MODEL.ROI_BOX_HEAD.FED_LOSS_FREQ_WEIGHT_POWER), # noqa + "fed_loss_num_classes" : cfg.MODEL.ROI_BOX_HEAD.FED_LOSS_NUM_CLASSES, + # fmt: on + } + + def forward(self, x): + """ + Args: + x: per-region features of shape (N, ...) for N bounding boxes to predict. + + Returns: + (Tensor, Tensor): + First tensor: shape (N,K+1), scores for each of the N box. Each row contains the + scores for K object categories and 1 background class. + + Second tensor: bounding box regression deltas for each box. Shape is shape (N,Kx4), + or (N,4) for class-agnostic regression. + """ + if x.dim() > 2: + x = torch.flatten(x, start_dim=1) + scores = self.cls_score(x) + proposal_deltas = self.bbox_pred(x) + return scores, proposal_deltas + + def losses(self, predictions, proposals): + """ + Args: + predictions: return values of :meth:`forward()`. + proposals (list[Instances]): proposals that match the features that were used + to compute predictions. The fields ``proposal_boxes``, ``gt_boxes``, + ``gt_classes`` are expected. + + Returns: + Dict[str, Tensor]: dict of losses + """ + scores, proposal_deltas = predictions + + # parse classification outputs + gt_classes = ( + cat([p.gt_classes for p in proposals], dim=0) if len(proposals) else torch.empty(0) + ) + _log_classification_stats(scores, gt_classes) + + # parse box regression outputs + if len(proposals): + proposal_boxes = cat([p.proposal_boxes.tensor for p in proposals], dim=0) # Nx4 + assert not proposal_boxes.requires_grad, "Proposals should not require gradients!" + # If "gt_boxes" does not exist, the proposals must be all negative and + # should not be included in regression loss computation. + # Here we just use proposal_boxes as an arbitrary placeholder because its + # value won't be used in self.box_reg_loss(). + gt_boxes = cat( + [(p.gt_boxes if p.has("gt_boxes") else p.proposal_boxes).tensor for p in proposals], + dim=0, + ) + else: + proposal_boxes = gt_boxes = torch.empty((0, 4), device=proposal_deltas.device) + + if self.use_sigmoid_ce: + loss_cls = self.sigmoid_cross_entropy_loss(scores, gt_classes) + else: + loss_cls = cross_entropy(scores, gt_classes, reduction="mean") + + losses = { + "loss_cls": loss_cls, + "loss_box_reg": self.box_reg_loss( + proposal_boxes, gt_boxes, proposal_deltas, gt_classes + ), + } + return {k: v * self.loss_weight.get(k, 1.0) for k, v in losses.items()} + + # Implementation from https://github.com/xingyizhou/CenterNet2/blob/master/projects/CenterNet2/centernet/modeling/roi_heads/fed_loss.py # noqa + # with slight modifications + def get_fed_loss_classes(self, gt_classes, num_fed_loss_classes, num_classes, weight): + """ + Args: + gt_classes: a long tensor of shape R that contains the gt class label of each proposal. + num_fed_loss_classes: minimum number of classes to keep when calculating federated loss. + Will sample negative classes if number of unique gt_classes is smaller than this value. + num_classes: number of foreground classes + weight: probabilities used to sample negative classes + + Returns: + Tensor: + classes to keep when calculating the federated loss, including both unique gt + classes and sampled negative classes. + """ + unique_gt_classes = torch.unique(gt_classes) + prob = unique_gt_classes.new_ones(num_classes + 1).float() + prob[-1] = 0 + if len(unique_gt_classes) < num_fed_loss_classes: + prob[:num_classes] = weight.float().clone() + prob[unique_gt_classes] = 0 + sampled_negative_classes = torch.multinomial( + prob, num_fed_loss_classes - len(unique_gt_classes), replacement=False + ) + fed_loss_classes = torch.cat([unique_gt_classes, sampled_negative_classes]) + else: + fed_loss_classes = unique_gt_classes + return fed_loss_classes + + # Implementation from https://github.com/xingyizhou/CenterNet2/blob/master/projects/CenterNet2/centernet/modeling/roi_heads/custom_fast_rcnn.py#L113 # noqa + # with slight modifications + def sigmoid_cross_entropy_loss(self, pred_class_logits, gt_classes): + """ + Args: + pred_class_logits: shape (N, K+1), scores for each of the N box. Each row contains the + scores for K object categories and 1 background class + gt_classes: a long tensor of shape R that contains the gt class label of each proposal. + """ + if pred_class_logits.numel() == 0: + return pred_class_logits.new_zeros([1])[0] + + N = pred_class_logits.shape[0] + K = pred_class_logits.shape[1] - 1 + + target = pred_class_logits.new_zeros(N, K + 1) + target[range(len(gt_classes)), gt_classes] = 1 + target = target[:, :K] + + cls_loss = F.binary_cross_entropy_with_logits( + pred_class_logits[:, :-1], target, reduction="none" + ) + + if self.use_fed_loss: + fed_loss_classes = self.get_fed_loss_classes( + gt_classes, + num_fed_loss_classes=self.fed_loss_num_classes, + num_classes=K, + weight=self.fed_loss_cls_weights, + ) + fed_loss_classes_mask = fed_loss_classes.new_zeros(K + 1) + fed_loss_classes_mask[fed_loss_classes] = 1 + fed_loss_classes_mask = fed_loss_classes_mask[:K] + weight = fed_loss_classes_mask.view(1, K).expand(N, K).float() + else: + weight = 1 + + loss = torch.sum(cls_loss * weight) / N + return loss + + def box_reg_loss(self, proposal_boxes, gt_boxes, pred_deltas, gt_classes): + """ + Args: + proposal_boxes/gt_boxes are tensors with the same shape (R, 4 or 5). + pred_deltas has shape (R, 4 or 5), or (R, num_classes * (4 or 5)). + gt_classes is a long tensor of shape R, the gt class label of each proposal. + R shall be the number of proposals. + """ + box_dim = proposal_boxes.shape[1] # 4 or 5 + # Regression loss is only computed for foreground proposals (those matched to a GT) + fg_inds = nonzero_tuple((gt_classes >= 0) & (gt_classes < self.num_classes))[0] + if pred_deltas.shape[1] == box_dim: # cls-agnostic regression + fg_pred_deltas = pred_deltas[fg_inds] + else: + fg_pred_deltas = pred_deltas.view(-1, self.num_classes, box_dim)[ + fg_inds, gt_classes[fg_inds] + ] + + loss_box_reg = _dense_box_regression_loss( + [proposal_boxes[fg_inds]], + self.box2box_transform, + [fg_pred_deltas.unsqueeze(0)], + [gt_boxes[fg_inds]], + ..., + self.box_reg_loss_type, + self.smooth_l1_beta, + ) + + # The reg loss is normalized using the total number of regions (R), not the number + # of foreground regions even though the box regression loss is only defined on + # foreground regions. Why? Because doing so gives equal training influence to + # each foreground example. To see how, consider two different minibatches: + # (1) Contains a single foreground region + # (2) Contains 100 foreground regions + # If we normalize by the number of foreground regions, the single example in + # minibatch (1) will be given 100 times as much influence as each foreground + # example in minibatch (2). Normalizing by the total number of regions, R, + # means that the single example in minibatch (1) and each of the 100 examples + # in minibatch (2) are given equal influence. + return loss_box_reg / max(gt_classes.numel(), 1.0) # return 0 if empty + + def inference(self, predictions: Tuple[torch.Tensor, torch.Tensor], proposals: List[Instances]): + """ + Args: + predictions: return values of :meth:`forward()`. + proposals (list[Instances]): proposals that match the features that were + used to compute predictions. The ``proposal_boxes`` field is expected. + + Returns: + list[Instances]: same as `fast_rcnn_inference`. + list[Tensor]: same as `fast_rcnn_inference`. + """ + boxes = self.predict_boxes(predictions, proposals) + scores = self.predict_probs(predictions, proposals) + image_shapes = [x.image_size for x in proposals] + return fast_rcnn_inference( + boxes, + scores, + image_shapes, + self.test_score_thresh, + self.test_nms_thresh, + self.test_topk_per_image, + ) + + def predict_boxes_for_gt_classes(self, predictions, proposals): + """ + Args: + predictions: return values of :meth:`forward()`. + proposals (list[Instances]): proposals that match the features that were used + to compute predictions. The fields ``proposal_boxes``, ``gt_classes`` are expected. + + Returns: + list[Tensor]: + A list of Tensors of predicted boxes for GT classes in case of + class-specific box head. Element i of the list has shape (Ri, B), where Ri is + the number of proposals for image i and B is the box dimension (4 or 5) + """ + if not len(proposals): + return [] + scores, proposal_deltas = predictions + proposal_boxes = cat([p.proposal_boxes.tensor for p in proposals], dim=0) + N, B = proposal_boxes.shape + predict_boxes = self.box2box_transform.apply_deltas( + proposal_deltas, proposal_boxes + ) # Nx(KxB) + + K = predict_boxes.shape[1] // B + if K > 1: + gt_classes = torch.cat([p.gt_classes for p in proposals], dim=0) + # Some proposals are ignored or have a background class. Their gt_classes + # cannot be used as index. + gt_classes = gt_classes.clamp_(0, K - 1) + + predict_boxes = predict_boxes.view(N, K, B)[ + torch.arange(N, dtype=torch.long, device=predict_boxes.device), gt_classes + ] + num_prop_per_image = [len(p) for p in proposals] + return predict_boxes.split(num_prop_per_image) + + def predict_boxes( + self, predictions: Tuple[torch.Tensor, torch.Tensor], proposals: List[Instances] + ): + """ + Args: + predictions: return values of :meth:`forward()`. + proposals (list[Instances]): proposals that match the features that were + used to compute predictions. The ``proposal_boxes`` field is expected. + + Returns: + list[Tensor]: + A list of Tensors of predicted class-specific or class-agnostic boxes + for each image. Element i has shape (Ri, K * B) or (Ri, B), where Ri is + the number of proposals for image i and B is the box dimension (4 or 5) + """ + if not len(proposals): + return [] + _, proposal_deltas = predictions + num_prop_per_image = [len(p) for p in proposals] + proposal_boxes = cat([p.proposal_boxes.tensor for p in proposals], dim=0) + predict_boxes = self.box2box_transform.apply_deltas( + proposal_deltas, + proposal_boxes, + ) # Nx(KxB) + return predict_boxes.split(num_prop_per_image) + + def predict_probs( + self, predictions: Tuple[torch.Tensor, torch.Tensor], proposals: List[Instances] + ): + """ + Args: + predictions: return values of :meth:`forward()`. + proposals (list[Instances]): proposals that match the features that were + used to compute predictions. + + Returns: + list[Tensor]: + A list of Tensors of predicted class probabilities for each image. + Element i has shape (Ri, K + 1), where Ri is the number of proposals for image i. + """ + scores, _ = predictions + num_inst_per_image = [len(p) for p in proposals] + if self.use_sigmoid_ce: + probs = scores.sigmoid() + else: + probs = F.softmax(scores, dim=-1) + return probs.split(num_inst_per_image, dim=0) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/keypoint_head.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/keypoint_head.py new file mode 100644 index 00000000..bcf92dc8 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/keypoint_head.py @@ -0,0 +1,272 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from typing import List +import torch +from torch import nn +from torch.nn import functional as F + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.layers import Conv2d, ConvTranspose2d, cat, interpolate +from annotator.oneformer.detectron2.structures import Instances, heatmaps_to_keypoints +from annotator.oneformer.detectron2.utils.events import get_event_storage +from annotator.oneformer.detectron2.utils.registry import Registry + +_TOTAL_SKIPPED = 0 + + +__all__ = [ + "ROI_KEYPOINT_HEAD_REGISTRY", + "build_keypoint_head", + "BaseKeypointRCNNHead", + "KRCNNConvDeconvUpsampleHead", +] + + +ROI_KEYPOINT_HEAD_REGISTRY = Registry("ROI_KEYPOINT_HEAD") +ROI_KEYPOINT_HEAD_REGISTRY.__doc__ = """ +Registry for keypoint heads, which make keypoint predictions from per-region features. + +The registered object will be called with `obj(cfg, input_shape)`. +""" + + +def build_keypoint_head(cfg, input_shape): + """ + Build a keypoint head from `cfg.MODEL.ROI_KEYPOINT_HEAD.NAME`. + """ + name = cfg.MODEL.ROI_KEYPOINT_HEAD.NAME + return ROI_KEYPOINT_HEAD_REGISTRY.get(name)(cfg, input_shape) + + +def keypoint_rcnn_loss(pred_keypoint_logits, instances, normalizer): + """ + Arguments: + pred_keypoint_logits (Tensor): A tensor of shape (N, K, S, S) where N is the total number + of instances in the batch, K is the number of keypoints, and S is the side length + of the keypoint heatmap. The values are spatial logits. + instances (list[Instances]): A list of M Instances, where M is the batch size. + These instances are predictions from the model + that are in 1:1 correspondence with pred_keypoint_logits. + Each Instances should contain a `gt_keypoints` field containing a `structures.Keypoint` + instance. + normalizer (float): Normalize the loss by this amount. + If not specified, we normalize by the number of visible keypoints in the minibatch. + + Returns a scalar tensor containing the loss. + """ + heatmaps = [] + valid = [] + + keypoint_side_len = pred_keypoint_logits.shape[2] + for instances_per_image in instances: + if len(instances_per_image) == 0: + continue + keypoints = instances_per_image.gt_keypoints + heatmaps_per_image, valid_per_image = keypoints.to_heatmap( + instances_per_image.proposal_boxes.tensor, keypoint_side_len + ) + heatmaps.append(heatmaps_per_image.view(-1)) + valid.append(valid_per_image.view(-1)) + + if len(heatmaps): + keypoint_targets = cat(heatmaps, dim=0) + valid = cat(valid, dim=0).to(dtype=torch.uint8) + valid = torch.nonzero(valid).squeeze(1) + + # torch.mean (in binary_cross_entropy_with_logits) doesn't + # accept empty tensors, so handle it separately + if len(heatmaps) == 0 or valid.numel() == 0: + global _TOTAL_SKIPPED + _TOTAL_SKIPPED += 1 + storage = get_event_storage() + storage.put_scalar("kpts_num_skipped_batches", _TOTAL_SKIPPED, smoothing_hint=False) + return pred_keypoint_logits.sum() * 0 + + N, K, H, W = pred_keypoint_logits.shape + pred_keypoint_logits = pred_keypoint_logits.view(N * K, H * W) + + keypoint_loss = F.cross_entropy( + pred_keypoint_logits[valid], keypoint_targets[valid], reduction="sum" + ) + + # If a normalizer isn't specified, normalize by the number of visible keypoints in the minibatch + if normalizer is None: + normalizer = valid.numel() + keypoint_loss /= normalizer + + return keypoint_loss + + +def keypoint_rcnn_inference(pred_keypoint_logits: torch.Tensor, pred_instances: List[Instances]): + """ + Post process each predicted keypoint heatmap in `pred_keypoint_logits` into (x, y, score) + and add it to the `pred_instances` as a `pred_keypoints` field. + + Args: + pred_keypoint_logits (Tensor): A tensor of shape (R, K, S, S) where R is the total number + of instances in the batch, K is the number of keypoints, and S is the side length of + the keypoint heatmap. The values are spatial logits. + pred_instances (list[Instances]): A list of N Instances, where N is the number of images. + + Returns: + None. Each element in pred_instances will contain extra "pred_keypoints" and + "pred_keypoint_heatmaps" fields. "pred_keypoints" is a tensor of shape + (#instance, K, 3) where the last dimension corresponds to (x, y, score). + The scores are larger than 0. "pred_keypoint_heatmaps" contains the raw + keypoint logits as passed to this function. + """ + # flatten all bboxes from all images together (list[Boxes] -> Rx4 tensor) + bboxes_flat = cat([b.pred_boxes.tensor for b in pred_instances], dim=0) + + pred_keypoint_logits = pred_keypoint_logits.detach() + keypoint_results = heatmaps_to_keypoints(pred_keypoint_logits, bboxes_flat.detach()) + num_instances_per_image = [len(i) for i in pred_instances] + keypoint_results = keypoint_results[:, :, [0, 1, 3]].split(num_instances_per_image, dim=0) + heatmap_results = pred_keypoint_logits.split(num_instances_per_image, dim=0) + + for keypoint_results_per_image, heatmap_results_per_image, instances_per_image in zip( + keypoint_results, heatmap_results, pred_instances + ): + # keypoint_results_per_image is (num instances)x(num keypoints)x(x, y, score) + # heatmap_results_per_image is (num instances)x(num keypoints)x(side)x(side) + instances_per_image.pred_keypoints = keypoint_results_per_image + instances_per_image.pred_keypoint_heatmaps = heatmap_results_per_image + + +class BaseKeypointRCNNHead(nn.Module): + """ + Implement the basic Keypoint R-CNN losses and inference logic described in + Sec. 5 of :paper:`Mask R-CNN`. + """ + + @configurable + def __init__(self, *, num_keypoints, loss_weight=1.0, loss_normalizer=1.0): + """ + NOTE: this interface is experimental. + + Args: + num_keypoints (int): number of keypoints to predict + loss_weight (float): weight to multiple on the keypoint loss + loss_normalizer (float or str): + If float, divide the loss by `loss_normalizer * #images`. + If 'visible', the loss is normalized by the total number of + visible keypoints across images. + """ + super().__init__() + self.num_keypoints = num_keypoints + self.loss_weight = loss_weight + assert loss_normalizer == "visible" or isinstance(loss_normalizer, float), loss_normalizer + self.loss_normalizer = loss_normalizer + + @classmethod + def from_config(cls, cfg, input_shape): + ret = { + "loss_weight": cfg.MODEL.ROI_KEYPOINT_HEAD.LOSS_WEIGHT, + "num_keypoints": cfg.MODEL.ROI_KEYPOINT_HEAD.NUM_KEYPOINTS, + } + normalize_by_visible = ( + cfg.MODEL.ROI_KEYPOINT_HEAD.NORMALIZE_LOSS_BY_VISIBLE_KEYPOINTS + ) # noqa + if not normalize_by_visible: + batch_size_per_image = cfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE + positive_sample_fraction = cfg.MODEL.ROI_HEADS.POSITIVE_FRACTION + ret["loss_normalizer"] = ( + ret["num_keypoints"] * batch_size_per_image * positive_sample_fraction + ) + else: + ret["loss_normalizer"] = "visible" + return ret + + def forward(self, x, instances: List[Instances]): + """ + Args: + x: input 4D region feature(s) provided by :class:`ROIHeads`. + instances (list[Instances]): contains the boxes & labels corresponding + to the input features. + Exact format is up to its caller to decide. + Typically, this is the foreground instances in training, with + "proposal_boxes" field and other gt annotations. + In inference, it contains boxes that are already predicted. + + Returns: + A dict of losses if in training. The predicted "instances" if in inference. + """ + x = self.layers(x) + if self.training: + num_images = len(instances) + normalizer = ( + None if self.loss_normalizer == "visible" else num_images * self.loss_normalizer + ) + return { + "loss_keypoint": keypoint_rcnn_loss(x, instances, normalizer=normalizer) + * self.loss_weight + } + else: + keypoint_rcnn_inference(x, instances) + return instances + + def layers(self, x): + """ + Neural network layers that makes predictions from regional input features. + """ + raise NotImplementedError + + +# To get torchscript support, we make the head a subclass of `nn.Sequential`. +# Therefore, to add new layers in this head class, please make sure they are +# added in the order they will be used in forward(). +@ROI_KEYPOINT_HEAD_REGISTRY.register() +class KRCNNConvDeconvUpsampleHead(BaseKeypointRCNNHead, nn.Sequential): + """ + A standard keypoint head containing a series of 3x3 convs, followed by + a transpose convolution and bilinear interpolation for upsampling. + It is described in Sec. 5 of :paper:`Mask R-CNN`. + """ + + @configurable + def __init__(self, input_shape, *, num_keypoints, conv_dims, **kwargs): + """ + NOTE: this interface is experimental. + + Args: + input_shape (ShapeSpec): shape of the input feature + conv_dims: an iterable of output channel counts for each conv in the head + e.g. (512, 512, 512) for three convs outputting 512 channels. + """ + super().__init__(num_keypoints=num_keypoints, **kwargs) + + # default up_scale to 2.0 (this can be made an option) + up_scale = 2.0 + in_channels = input_shape.channels + + for idx, layer_channels in enumerate(conv_dims, 1): + module = Conv2d(in_channels, layer_channels, 3, stride=1, padding=1) + self.add_module("conv_fcn{}".format(idx), module) + self.add_module("conv_fcn_relu{}".format(idx), nn.ReLU()) + in_channels = layer_channels + + deconv_kernel = 4 + self.score_lowres = ConvTranspose2d( + in_channels, num_keypoints, deconv_kernel, stride=2, padding=deconv_kernel // 2 - 1 + ) + self.up_scale = up_scale + + for name, param in self.named_parameters(): + if "bias" in name: + nn.init.constant_(param, 0) + elif "weight" in name: + # Caffe2 implementation uses MSRAFill, which in fact + # corresponds to kaiming_normal_ in PyTorch + nn.init.kaiming_normal_(param, mode="fan_out", nonlinearity="relu") + + @classmethod + def from_config(cls, cfg, input_shape): + ret = super().from_config(cfg, input_shape) + ret["input_shape"] = input_shape + ret["conv_dims"] = cfg.MODEL.ROI_KEYPOINT_HEAD.CONV_DIMS + return ret + + def layers(self, x): + for layer in self: + x = layer(x) + x = interpolate(x, scale_factor=self.up_scale, mode="bilinear", align_corners=False) + return x diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/mask_head.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/mask_head.py new file mode 100644 index 00000000..1b5465e4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/mask_head.py @@ -0,0 +1,298 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from typing import List +import fvcore.nn.weight_init as weight_init +import torch +from torch import nn +from torch.nn import functional as F + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.layers import Conv2d, ConvTranspose2d, ShapeSpec, cat, get_norm +from annotator.oneformer.detectron2.layers.wrappers import move_device_like +from annotator.oneformer.detectron2.structures import Instances +from annotator.oneformer.detectron2.utils.events import get_event_storage +from annotator.oneformer.detectron2.utils.registry import Registry + +__all__ = [ + "BaseMaskRCNNHead", + "MaskRCNNConvUpsampleHead", + "build_mask_head", + "ROI_MASK_HEAD_REGISTRY", +] + + +ROI_MASK_HEAD_REGISTRY = Registry("ROI_MASK_HEAD") +ROI_MASK_HEAD_REGISTRY.__doc__ = """ +Registry for mask heads, which predicts instance masks given +per-region features. + +The registered object will be called with `obj(cfg, input_shape)`. +""" + + +@torch.jit.unused +def mask_rcnn_loss(pred_mask_logits: torch.Tensor, instances: List[Instances], vis_period: int = 0): + """ + Compute the mask prediction loss defined in the Mask R-CNN paper. + + Args: + pred_mask_logits (Tensor): A tensor of shape (B, C, Hmask, Wmask) or (B, 1, Hmask, Wmask) + for class-specific or class-agnostic, where B is the total number of predicted masks + in all images, C is the number of foreground classes, and Hmask, Wmask are the height + and width of the mask predictions. The values are logits. + instances (list[Instances]): A list of N Instances, where N is the number of images + in the batch. These instances are in 1:1 + correspondence with the pred_mask_logits. The ground-truth labels (class, box, mask, + ...) associated with each instance are stored in fields. + vis_period (int): the period (in steps) to dump visualization. + + Returns: + mask_loss (Tensor): A scalar tensor containing the loss. + """ + cls_agnostic_mask = pred_mask_logits.size(1) == 1 + total_num_masks = pred_mask_logits.size(0) + mask_side_len = pred_mask_logits.size(2) + assert pred_mask_logits.size(2) == pred_mask_logits.size(3), "Mask prediction must be square!" + + gt_classes = [] + gt_masks = [] + for instances_per_image in instances: + if len(instances_per_image) == 0: + continue + if not cls_agnostic_mask: + gt_classes_per_image = instances_per_image.gt_classes.to(dtype=torch.int64) + gt_classes.append(gt_classes_per_image) + + gt_masks_per_image = instances_per_image.gt_masks.crop_and_resize( + instances_per_image.proposal_boxes.tensor, mask_side_len + ).to(device=pred_mask_logits.device) + # A tensor of shape (N, M, M), N=#instances in the image; M=mask_side_len + gt_masks.append(gt_masks_per_image) + + if len(gt_masks) == 0: + return pred_mask_logits.sum() * 0 + + gt_masks = cat(gt_masks, dim=0) + + if cls_agnostic_mask: + pred_mask_logits = pred_mask_logits[:, 0] + else: + indices = torch.arange(total_num_masks) + gt_classes = cat(gt_classes, dim=0) + pred_mask_logits = pred_mask_logits[indices, gt_classes] + + if gt_masks.dtype == torch.bool: + gt_masks_bool = gt_masks + else: + # Here we allow gt_masks to be float as well (depend on the implementation of rasterize()) + gt_masks_bool = gt_masks > 0.5 + gt_masks = gt_masks.to(dtype=torch.float32) + + # Log the training accuracy (using gt classes and 0.5 threshold) + mask_incorrect = (pred_mask_logits > 0.0) != gt_masks_bool + mask_accuracy = 1 - (mask_incorrect.sum().item() / max(mask_incorrect.numel(), 1.0)) + num_positive = gt_masks_bool.sum().item() + false_positive = (mask_incorrect & ~gt_masks_bool).sum().item() / max( + gt_masks_bool.numel() - num_positive, 1.0 + ) + false_negative = (mask_incorrect & gt_masks_bool).sum().item() / max(num_positive, 1.0) + + storage = get_event_storage() + storage.put_scalar("mask_rcnn/accuracy", mask_accuracy) + storage.put_scalar("mask_rcnn/false_positive", false_positive) + storage.put_scalar("mask_rcnn/false_negative", false_negative) + if vis_period > 0 and storage.iter % vis_period == 0: + pred_masks = pred_mask_logits.sigmoid() + vis_masks = torch.cat([pred_masks, gt_masks], axis=2) + name = "Left: mask prediction; Right: mask GT" + for idx, vis_mask in enumerate(vis_masks): + vis_mask = torch.stack([vis_mask] * 3, axis=0) + storage.put_image(name + f" ({idx})", vis_mask) + + mask_loss = F.binary_cross_entropy_with_logits(pred_mask_logits, gt_masks, reduction="mean") + return mask_loss + + +def mask_rcnn_inference(pred_mask_logits: torch.Tensor, pred_instances: List[Instances]): + """ + Convert pred_mask_logits to estimated foreground probability masks while also + extracting only the masks for the predicted classes in pred_instances. For each + predicted box, the mask of the same class is attached to the instance by adding a + new "pred_masks" field to pred_instances. + + Args: + pred_mask_logits (Tensor): A tensor of shape (B, C, Hmask, Wmask) or (B, 1, Hmask, Wmask) + for class-specific or class-agnostic, where B is the total number of predicted masks + in all images, C is the number of foreground classes, and Hmask, Wmask are the height + and width of the mask predictions. The values are logits. + pred_instances (list[Instances]): A list of N Instances, where N is the number of images + in the batch. Each Instances must have field "pred_classes". + + Returns: + None. pred_instances will contain an extra "pred_masks" field storing a mask of size (Hmask, + Wmask) for predicted class. Note that the masks are returned as a soft (non-quantized) + masks the resolution predicted by the network; post-processing steps, such as resizing + the predicted masks to the original image resolution and/or binarizing them, is left + to the caller. + """ + cls_agnostic_mask = pred_mask_logits.size(1) == 1 + + if cls_agnostic_mask: + mask_probs_pred = pred_mask_logits.sigmoid() + else: + # Select masks corresponding to the predicted classes + num_masks = pred_mask_logits.shape[0] + class_pred = cat([i.pred_classes for i in pred_instances]) + device = ( + class_pred.device + if torch.jit.is_scripting() + else ("cpu" if torch.jit.is_tracing() else class_pred.device) + ) + indices = move_device_like(torch.arange(num_masks, device=device), class_pred) + mask_probs_pred = pred_mask_logits[indices, class_pred][:, None].sigmoid() + # mask_probs_pred.shape: (B, 1, Hmask, Wmask) + + num_boxes_per_image = [len(i) for i in pred_instances] + mask_probs_pred = mask_probs_pred.split(num_boxes_per_image, dim=0) + + for prob, instances in zip(mask_probs_pred, pred_instances): + instances.pred_masks = prob # (1, Hmask, Wmask) + + +class BaseMaskRCNNHead(nn.Module): + """ + Implement the basic Mask R-CNN losses and inference logic described in :paper:`Mask R-CNN` + """ + + @configurable + def __init__(self, *, loss_weight: float = 1.0, vis_period: int = 0): + """ + NOTE: this interface is experimental. + + Args: + loss_weight (float): multiplier of the loss + vis_period (int): visualization period + """ + super().__init__() + self.vis_period = vis_period + self.loss_weight = loss_weight + + @classmethod + def from_config(cls, cfg, input_shape): + return {"vis_period": cfg.VIS_PERIOD} + + def forward(self, x, instances: List[Instances]): + """ + Args: + x: input region feature(s) provided by :class:`ROIHeads`. + instances (list[Instances]): contains the boxes & labels corresponding + to the input features. + Exact format is up to its caller to decide. + Typically, this is the foreground instances in training, with + "proposal_boxes" field and other gt annotations. + In inference, it contains boxes that are already predicted. + + Returns: + A dict of losses in training. The predicted "instances" in inference. + """ + x = self.layers(x) + if self.training: + return {"loss_mask": mask_rcnn_loss(x, instances, self.vis_period) * self.loss_weight} + else: + mask_rcnn_inference(x, instances) + return instances + + def layers(self, x): + """ + Neural network layers that makes predictions from input features. + """ + raise NotImplementedError + + +# To get torchscript support, we make the head a subclass of `nn.Sequential`. +# Therefore, to add new layers in this head class, please make sure they are +# added in the order they will be used in forward(). +@ROI_MASK_HEAD_REGISTRY.register() +class MaskRCNNConvUpsampleHead(BaseMaskRCNNHead, nn.Sequential): + """ + A mask head with several conv layers, plus an upsample layer (with `ConvTranspose2d`). + Predictions are made with a final 1x1 conv layer. + """ + + @configurable + def __init__(self, input_shape: ShapeSpec, *, num_classes, conv_dims, conv_norm="", **kwargs): + """ + NOTE: this interface is experimental. + + Args: + input_shape (ShapeSpec): shape of the input feature + num_classes (int): the number of foreground classes (i.e. background is not + included). 1 if using class agnostic prediction. + conv_dims (list[int]): a list of N>0 integers representing the output dimensions + of N-1 conv layers and the last upsample layer. + conv_norm (str or callable): normalization for the conv layers. + See :func:`detectron2.layers.get_norm` for supported types. + """ + super().__init__(**kwargs) + assert len(conv_dims) >= 1, "conv_dims have to be non-empty!" + + self.conv_norm_relus = [] + + cur_channels = input_shape.channels + for k, conv_dim in enumerate(conv_dims[:-1]): + conv = Conv2d( + cur_channels, + conv_dim, + kernel_size=3, + stride=1, + padding=1, + bias=not conv_norm, + norm=get_norm(conv_norm, conv_dim), + activation=nn.ReLU(), + ) + self.add_module("mask_fcn{}".format(k + 1), conv) + self.conv_norm_relus.append(conv) + cur_channels = conv_dim + + self.deconv = ConvTranspose2d( + cur_channels, conv_dims[-1], kernel_size=2, stride=2, padding=0 + ) + self.add_module("deconv_relu", nn.ReLU()) + cur_channels = conv_dims[-1] + + self.predictor = Conv2d(cur_channels, num_classes, kernel_size=1, stride=1, padding=0) + + for layer in self.conv_norm_relus + [self.deconv]: + weight_init.c2_msra_fill(layer) + # use normal distribution initialization for mask prediction layer + nn.init.normal_(self.predictor.weight, std=0.001) + if self.predictor.bias is not None: + nn.init.constant_(self.predictor.bias, 0) + + @classmethod + def from_config(cls, cfg, input_shape): + ret = super().from_config(cfg, input_shape) + conv_dim = cfg.MODEL.ROI_MASK_HEAD.CONV_DIM + num_conv = cfg.MODEL.ROI_MASK_HEAD.NUM_CONV + ret.update( + conv_dims=[conv_dim] * (num_conv + 1), # +1 for ConvTranspose + conv_norm=cfg.MODEL.ROI_MASK_HEAD.NORM, + input_shape=input_shape, + ) + if cfg.MODEL.ROI_MASK_HEAD.CLS_AGNOSTIC_MASK: + ret["num_classes"] = 1 + else: + ret["num_classes"] = cfg.MODEL.ROI_HEADS.NUM_CLASSES + return ret + + def layers(self, x): + for layer in self: + x = layer(x) + return x + + +def build_mask_head(cfg, input_shape): + """ + Build a mask head defined by `cfg.MODEL.ROI_MASK_HEAD.NAME`. + """ + name = cfg.MODEL.ROI_MASK_HEAD.NAME + return ROI_MASK_HEAD_REGISTRY.get(name)(cfg, input_shape) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/roi_heads.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/roi_heads.py new file mode 100644 index 00000000..d554a387 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/roi_heads.py @@ -0,0 +1,877 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import inspect +import logging +import numpy as np +from typing import Dict, List, Optional, Tuple +import torch +from torch import nn + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.layers import ShapeSpec, nonzero_tuple +from annotator.oneformer.detectron2.structures import Boxes, ImageList, Instances, pairwise_iou +from annotator.oneformer.detectron2.utils.events import get_event_storage +from annotator.oneformer.detectron2.utils.registry import Registry + +from ..backbone.resnet import BottleneckBlock, ResNet +from ..matcher import Matcher +from ..poolers import ROIPooler +from ..proposal_generator.proposal_utils import add_ground_truth_to_proposals +from ..sampling import subsample_labels +from .box_head import build_box_head +from .fast_rcnn import FastRCNNOutputLayers +from .keypoint_head import build_keypoint_head +from .mask_head import build_mask_head + +ROI_HEADS_REGISTRY = Registry("ROI_HEADS") +ROI_HEADS_REGISTRY.__doc__ = """ +Registry for ROI heads in a generalized R-CNN model. +ROIHeads take feature maps and region proposals, and +perform per-region computation. + +The registered object will be called with `obj(cfg, input_shape)`. +The call is expected to return an :class:`ROIHeads`. +""" + +logger = logging.getLogger(__name__) + + +def build_roi_heads(cfg, input_shape): + """ + Build ROIHeads defined by `cfg.MODEL.ROI_HEADS.NAME`. + """ + name = cfg.MODEL.ROI_HEADS.NAME + return ROI_HEADS_REGISTRY.get(name)(cfg, input_shape) + + +def select_foreground_proposals( + proposals: List[Instances], bg_label: int +) -> Tuple[List[Instances], List[torch.Tensor]]: + """ + Given a list of N Instances (for N images), each containing a `gt_classes` field, + return a list of Instances that contain only instances with `gt_classes != -1 && + gt_classes != bg_label`. + + Args: + proposals (list[Instances]): A list of N Instances, where N is the number of + images in the batch. + bg_label: label index of background class. + + Returns: + list[Instances]: N Instances, each contains only the selected foreground instances. + list[Tensor]: N boolean vector, correspond to the selection mask of + each Instances object. True for selected instances. + """ + assert isinstance(proposals, (list, tuple)) + assert isinstance(proposals[0], Instances) + assert proposals[0].has("gt_classes") + fg_proposals = [] + fg_selection_masks = [] + for proposals_per_image in proposals: + gt_classes = proposals_per_image.gt_classes + fg_selection_mask = (gt_classes != -1) & (gt_classes != bg_label) + fg_idxs = fg_selection_mask.nonzero().squeeze(1) + fg_proposals.append(proposals_per_image[fg_idxs]) + fg_selection_masks.append(fg_selection_mask) + return fg_proposals, fg_selection_masks + + +def select_proposals_with_visible_keypoints(proposals: List[Instances]) -> List[Instances]: + """ + Args: + proposals (list[Instances]): a list of N Instances, where N is the + number of images. + + Returns: + proposals: only contains proposals with at least one visible keypoint. + + Note that this is still slightly different from Detectron. + In Detectron, proposals for training keypoint head are re-sampled from + all the proposals with IOU>threshold & >=1 visible keypoint. + + Here, the proposals are first sampled from all proposals with + IOU>threshold, then proposals with no visible keypoint are filtered out. + This strategy seems to make no difference on Detectron and is easier to implement. + """ + ret = [] + all_num_fg = [] + for proposals_per_image in proposals: + # If empty/unannotated image (hard negatives), skip filtering for train + if len(proposals_per_image) == 0: + ret.append(proposals_per_image) + continue + gt_keypoints = proposals_per_image.gt_keypoints.tensor + # #fg x K x 3 + vis_mask = gt_keypoints[:, :, 2] >= 1 + xs, ys = gt_keypoints[:, :, 0], gt_keypoints[:, :, 1] + proposal_boxes = proposals_per_image.proposal_boxes.tensor.unsqueeze(dim=1) # #fg x 1 x 4 + kp_in_box = ( + (xs >= proposal_boxes[:, :, 0]) + & (xs <= proposal_boxes[:, :, 2]) + & (ys >= proposal_boxes[:, :, 1]) + & (ys <= proposal_boxes[:, :, 3]) + ) + selection = (kp_in_box & vis_mask).any(dim=1) + selection_idxs = nonzero_tuple(selection)[0] + all_num_fg.append(selection_idxs.numel()) + ret.append(proposals_per_image[selection_idxs]) + + storage = get_event_storage() + storage.put_scalar("keypoint_head/num_fg_samples", np.mean(all_num_fg)) + return ret + + +class ROIHeads(torch.nn.Module): + """ + ROIHeads perform all per-region computation in an R-CNN. + + It typically contains logic to + + 1. (in training only) match proposals with ground truth and sample them + 2. crop the regions and extract per-region features using proposals + 3. make per-region predictions with different heads + + It can have many variants, implemented as subclasses of this class. + This base class contains the logic to match/sample proposals. + But it is not necessary to inherit this class if the sampling logic is not needed. + """ + + @configurable + def __init__( + self, + *, + num_classes, + batch_size_per_image, + positive_fraction, + proposal_matcher, + proposal_append_gt=True, + ): + """ + NOTE: this interface is experimental. + + Args: + num_classes (int): number of foreground classes (i.e. background is not included) + batch_size_per_image (int): number of proposals to sample for training + positive_fraction (float): fraction of positive (foreground) proposals + to sample for training. + proposal_matcher (Matcher): matcher that matches proposals and ground truth + proposal_append_gt (bool): whether to include ground truth as proposals as well + """ + super().__init__() + self.batch_size_per_image = batch_size_per_image + self.positive_fraction = positive_fraction + self.num_classes = num_classes + self.proposal_matcher = proposal_matcher + self.proposal_append_gt = proposal_append_gt + + @classmethod + def from_config(cls, cfg): + return { + "batch_size_per_image": cfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE, + "positive_fraction": cfg.MODEL.ROI_HEADS.POSITIVE_FRACTION, + "num_classes": cfg.MODEL.ROI_HEADS.NUM_CLASSES, + "proposal_append_gt": cfg.MODEL.ROI_HEADS.PROPOSAL_APPEND_GT, + # Matcher to assign box proposals to gt boxes + "proposal_matcher": Matcher( + cfg.MODEL.ROI_HEADS.IOU_THRESHOLDS, + cfg.MODEL.ROI_HEADS.IOU_LABELS, + allow_low_quality_matches=False, + ), + } + + def _sample_proposals( + self, matched_idxs: torch.Tensor, matched_labels: torch.Tensor, gt_classes: torch.Tensor + ) -> Tuple[torch.Tensor, torch.Tensor]: + """ + Based on the matching between N proposals and M groundtruth, + sample the proposals and set their classification labels. + + Args: + matched_idxs (Tensor): a vector of length N, each is the best-matched + gt index in [0, M) for each proposal. + matched_labels (Tensor): a vector of length N, the matcher's label + (one of cfg.MODEL.ROI_HEADS.IOU_LABELS) for each proposal. + gt_classes (Tensor): a vector of length M. + + Returns: + Tensor: a vector of indices of sampled proposals. Each is in [0, N). + Tensor: a vector of the same length, the classification label for + each sampled proposal. Each sample is labeled as either a category in + [0, num_classes) or the background (num_classes). + """ + has_gt = gt_classes.numel() > 0 + # Get the corresponding GT for each proposal + if has_gt: + gt_classes = gt_classes[matched_idxs] + # Label unmatched proposals (0 label from matcher) as background (label=num_classes) + gt_classes[matched_labels == 0] = self.num_classes + # Label ignore proposals (-1 label) + gt_classes[matched_labels == -1] = -1 + else: + gt_classes = torch.zeros_like(matched_idxs) + self.num_classes + + sampled_fg_idxs, sampled_bg_idxs = subsample_labels( + gt_classes, self.batch_size_per_image, self.positive_fraction, self.num_classes + ) + + sampled_idxs = torch.cat([sampled_fg_idxs, sampled_bg_idxs], dim=0) + return sampled_idxs, gt_classes[sampled_idxs] + + @torch.no_grad() + def label_and_sample_proposals( + self, proposals: List[Instances], targets: List[Instances] + ) -> List[Instances]: + """ + Prepare some proposals to be used to train the ROI heads. + It performs box matching between `proposals` and `targets`, and assigns + training labels to the proposals. + It returns ``self.batch_size_per_image`` random samples from proposals and groundtruth + boxes, with a fraction of positives that is no larger than + ``self.positive_fraction``. + + Args: + See :meth:`ROIHeads.forward` + + Returns: + list[Instances]: + length `N` list of `Instances`s containing the proposals + sampled for training. Each `Instances` has the following fields: + + - proposal_boxes: the proposal boxes + - gt_boxes: the ground-truth box that the proposal is assigned to + (this is only meaningful if the proposal has a label > 0; if label = 0 + then the ground-truth box is random) + + Other fields such as "gt_classes", "gt_masks", that's included in `targets`. + """ + # Augment proposals with ground-truth boxes. + # In the case of learned proposals (e.g., RPN), when training starts + # the proposals will be low quality due to random initialization. + # It's possible that none of these initial + # proposals have high enough overlap with the gt objects to be used + # as positive examples for the second stage components (box head, + # cls head, mask head). Adding the gt boxes to the set of proposals + # ensures that the second stage components will have some positive + # examples from the start of training. For RPN, this augmentation improves + # convergence and empirically improves box AP on COCO by about 0.5 + # points (under one tested configuration). + if self.proposal_append_gt: + proposals = add_ground_truth_to_proposals(targets, proposals) + + proposals_with_gt = [] + + num_fg_samples = [] + num_bg_samples = [] + for proposals_per_image, targets_per_image in zip(proposals, targets): + has_gt = len(targets_per_image) > 0 + match_quality_matrix = pairwise_iou( + targets_per_image.gt_boxes, proposals_per_image.proposal_boxes + ) + matched_idxs, matched_labels = self.proposal_matcher(match_quality_matrix) + sampled_idxs, gt_classes = self._sample_proposals( + matched_idxs, matched_labels, targets_per_image.gt_classes + ) + + # Set target attributes of the sampled proposals: + proposals_per_image = proposals_per_image[sampled_idxs] + proposals_per_image.gt_classes = gt_classes + + if has_gt: + sampled_targets = matched_idxs[sampled_idxs] + # We index all the attributes of targets that start with "gt_" + # and have not been added to proposals yet (="gt_classes"). + # NOTE: here the indexing waste some compute, because heads + # like masks, keypoints, etc, will filter the proposals again, + # (by foreground/background, or number of keypoints in the image, etc) + # so we essentially index the data twice. + for (trg_name, trg_value) in targets_per_image.get_fields().items(): + if trg_name.startswith("gt_") and not proposals_per_image.has(trg_name): + proposals_per_image.set(trg_name, trg_value[sampled_targets]) + # If no GT is given in the image, we don't know what a dummy gt value can be. + # Therefore the returned proposals won't have any gt_* fields, except for a + # gt_classes full of background label. + + num_bg_samples.append((gt_classes == self.num_classes).sum().item()) + num_fg_samples.append(gt_classes.numel() - num_bg_samples[-1]) + proposals_with_gt.append(proposals_per_image) + + # Log the number of fg/bg samples that are selected for training ROI heads + storage = get_event_storage() + storage.put_scalar("roi_head/num_fg_samples", np.mean(num_fg_samples)) + storage.put_scalar("roi_head/num_bg_samples", np.mean(num_bg_samples)) + + return proposals_with_gt + + def forward( + self, + images: ImageList, + features: Dict[str, torch.Tensor], + proposals: List[Instances], + targets: Optional[List[Instances]] = None, + ) -> Tuple[List[Instances], Dict[str, torch.Tensor]]: + """ + Args: + images (ImageList): + features (dict[str,Tensor]): input data as a mapping from feature + map name to tensor. Axis 0 represents the number of images `N` in + the input data; axes 1-3 are channels, height, and width, which may + vary between feature maps (e.g., if a feature pyramid is used). + proposals (list[Instances]): length `N` list of `Instances`. The i-th + `Instances` contains object proposals for the i-th input image, + with fields "proposal_boxes" and "objectness_logits". + targets (list[Instances], optional): length `N` list of `Instances`. The i-th + `Instances` contains the ground-truth per-instance annotations + for the i-th input image. Specify `targets` during training only. + It may have the following fields: + + - gt_boxes: the bounding box of each instance. + - gt_classes: the label for each instance with a category ranging in [0, #class]. + - gt_masks: PolygonMasks or BitMasks, the ground-truth masks of each instance. + - gt_keypoints: NxKx3, the groud-truth keypoints for each instance. + + Returns: + list[Instances]: length `N` list of `Instances` containing the + detected instances. Returned during inference only; may be [] during training. + + dict[str->Tensor]: + mapping from a named loss to a tensor storing the loss. Used during training only. + """ + raise NotImplementedError() + + +@ROI_HEADS_REGISTRY.register() +class Res5ROIHeads(ROIHeads): + """ + The ROIHeads in a typical "C4" R-CNN model, where + the box and mask head share the cropping and + the per-region feature computation by a Res5 block. + See :paper:`ResNet` Appendix A. + """ + + @configurable + def __init__( + self, + *, + in_features: List[str], + pooler: ROIPooler, + res5: nn.Module, + box_predictor: nn.Module, + mask_head: Optional[nn.Module] = None, + **kwargs, + ): + """ + NOTE: this interface is experimental. + + Args: + in_features (list[str]): list of backbone feature map names to use for + feature extraction + pooler (ROIPooler): pooler to extra region features from backbone + res5 (nn.Sequential): a CNN to compute per-region features, to be used by + ``box_predictor`` and ``mask_head``. Typically this is a "res5" + block from a ResNet. + box_predictor (nn.Module): make box predictions from the feature. + Should have the same interface as :class:`FastRCNNOutputLayers`. + mask_head (nn.Module): transform features to make mask predictions + """ + super().__init__(**kwargs) + self.in_features = in_features + self.pooler = pooler + if isinstance(res5, (list, tuple)): + res5 = nn.Sequential(*res5) + self.res5 = res5 + self.box_predictor = box_predictor + self.mask_on = mask_head is not None + if self.mask_on: + self.mask_head = mask_head + + @classmethod + def from_config(cls, cfg, input_shape): + # fmt: off + ret = super().from_config(cfg) + in_features = ret["in_features"] = cfg.MODEL.ROI_HEADS.IN_FEATURES + pooler_resolution = cfg.MODEL.ROI_BOX_HEAD.POOLER_RESOLUTION + pooler_type = cfg.MODEL.ROI_BOX_HEAD.POOLER_TYPE + pooler_scales = (1.0 / input_shape[in_features[0]].stride, ) + sampling_ratio = cfg.MODEL.ROI_BOX_HEAD.POOLER_SAMPLING_RATIO + mask_on = cfg.MODEL.MASK_ON + # fmt: on + assert not cfg.MODEL.KEYPOINT_ON + assert len(in_features) == 1 + + ret["pooler"] = ROIPooler( + output_size=pooler_resolution, + scales=pooler_scales, + sampling_ratio=sampling_ratio, + pooler_type=pooler_type, + ) + + # Compatbility with old moco code. Might be useful. + # See notes in StandardROIHeads.from_config + if not inspect.ismethod(cls._build_res5_block): + logger.warning( + "The behavior of _build_res5_block may change. " + "Please do not depend on private methods." + ) + cls._build_res5_block = classmethod(cls._build_res5_block) + + ret["res5"], out_channels = cls._build_res5_block(cfg) + ret["box_predictor"] = FastRCNNOutputLayers( + cfg, ShapeSpec(channels=out_channels, height=1, width=1) + ) + + if mask_on: + ret["mask_head"] = build_mask_head( + cfg, + ShapeSpec(channels=out_channels, width=pooler_resolution, height=pooler_resolution), + ) + return ret + + @classmethod + def _build_res5_block(cls, cfg): + # fmt: off + stage_channel_factor = 2 ** 3 # res5 is 8x res2 + num_groups = cfg.MODEL.RESNETS.NUM_GROUPS + width_per_group = cfg.MODEL.RESNETS.WIDTH_PER_GROUP + bottleneck_channels = num_groups * width_per_group * stage_channel_factor + out_channels = cfg.MODEL.RESNETS.RES2_OUT_CHANNELS * stage_channel_factor + stride_in_1x1 = cfg.MODEL.RESNETS.STRIDE_IN_1X1 + norm = cfg.MODEL.RESNETS.NORM + assert not cfg.MODEL.RESNETS.DEFORM_ON_PER_STAGE[-1], \ + "Deformable conv is not yet supported in res5 head." + # fmt: on + + blocks = ResNet.make_stage( + BottleneckBlock, + 3, + stride_per_block=[2, 1, 1], + in_channels=out_channels // 2, + bottleneck_channels=bottleneck_channels, + out_channels=out_channels, + num_groups=num_groups, + norm=norm, + stride_in_1x1=stride_in_1x1, + ) + return nn.Sequential(*blocks), out_channels + + def _shared_roi_transform(self, features: List[torch.Tensor], boxes: List[Boxes]): + x = self.pooler(features, boxes) + return self.res5(x) + + def forward( + self, + images: ImageList, + features: Dict[str, torch.Tensor], + proposals: List[Instances], + targets: Optional[List[Instances]] = None, + ): + """ + See :meth:`ROIHeads.forward`. + """ + del images + + if self.training: + assert targets + proposals = self.label_and_sample_proposals(proposals, targets) + del targets + + proposal_boxes = [x.proposal_boxes for x in proposals] + box_features = self._shared_roi_transform( + [features[f] for f in self.in_features], proposal_boxes + ) + predictions = self.box_predictor(box_features.mean(dim=[2, 3])) + + if self.training: + del features + losses = self.box_predictor.losses(predictions, proposals) + if self.mask_on: + proposals, fg_selection_masks = select_foreground_proposals( + proposals, self.num_classes + ) + # Since the ROI feature transform is shared between boxes and masks, + # we don't need to recompute features. The mask loss is only defined + # on foreground proposals, so we need to select out the foreground + # features. + mask_features = box_features[torch.cat(fg_selection_masks, dim=0)] + del box_features + losses.update(self.mask_head(mask_features, proposals)) + return [], losses + else: + pred_instances, _ = self.box_predictor.inference(predictions, proposals) + pred_instances = self.forward_with_given_boxes(features, pred_instances) + return pred_instances, {} + + def forward_with_given_boxes( + self, features: Dict[str, torch.Tensor], instances: List[Instances] + ) -> List[Instances]: + """ + Use the given boxes in `instances` to produce other (non-box) per-ROI outputs. + + Args: + features: same as in `forward()` + instances (list[Instances]): instances to predict other outputs. Expect the keys + "pred_boxes" and "pred_classes" to exist. + + Returns: + instances (Instances): + the same `Instances` object, with extra + fields such as `pred_masks` or `pred_keypoints`. + """ + assert not self.training + assert instances[0].has("pred_boxes") and instances[0].has("pred_classes") + + if self.mask_on: + feature_list = [features[f] for f in self.in_features] + x = self._shared_roi_transform(feature_list, [x.pred_boxes for x in instances]) + return self.mask_head(x, instances) + else: + return instances + + +@ROI_HEADS_REGISTRY.register() +class StandardROIHeads(ROIHeads): + """ + It's "standard" in a sense that there is no ROI transform sharing + or feature sharing between tasks. + Each head independently processes the input features by each head's + own pooler and head. + + This class is used by most models, such as FPN and C5. + To implement more models, you can subclass it and implement a different + :meth:`forward()` or a head. + """ + + @configurable + def __init__( + self, + *, + box_in_features: List[str], + box_pooler: ROIPooler, + box_head: nn.Module, + box_predictor: nn.Module, + mask_in_features: Optional[List[str]] = None, + mask_pooler: Optional[ROIPooler] = None, + mask_head: Optional[nn.Module] = None, + keypoint_in_features: Optional[List[str]] = None, + keypoint_pooler: Optional[ROIPooler] = None, + keypoint_head: Optional[nn.Module] = None, + train_on_pred_boxes: bool = False, + **kwargs, + ): + """ + NOTE: this interface is experimental. + + Args: + box_in_features (list[str]): list of feature names to use for the box head. + box_pooler (ROIPooler): pooler to extra region features for box head + box_head (nn.Module): transform features to make box predictions + box_predictor (nn.Module): make box predictions from the feature. + Should have the same interface as :class:`FastRCNNOutputLayers`. + mask_in_features (list[str]): list of feature names to use for the mask + pooler or mask head. None if not using mask head. + mask_pooler (ROIPooler): pooler to extract region features from image features. + The mask head will then take region features to make predictions. + If None, the mask head will directly take the dict of image features + defined by `mask_in_features` + mask_head (nn.Module): transform features to make mask predictions + keypoint_in_features, keypoint_pooler, keypoint_head: similar to ``mask_*``. + train_on_pred_boxes (bool): whether to use proposal boxes or + predicted boxes from the box head to train other heads. + """ + super().__init__(**kwargs) + # keep self.in_features for backward compatibility + self.in_features = self.box_in_features = box_in_features + self.box_pooler = box_pooler + self.box_head = box_head + self.box_predictor = box_predictor + + self.mask_on = mask_in_features is not None + if self.mask_on: + self.mask_in_features = mask_in_features + self.mask_pooler = mask_pooler + self.mask_head = mask_head + + self.keypoint_on = keypoint_in_features is not None + if self.keypoint_on: + self.keypoint_in_features = keypoint_in_features + self.keypoint_pooler = keypoint_pooler + self.keypoint_head = keypoint_head + + self.train_on_pred_boxes = train_on_pred_boxes + + @classmethod + def from_config(cls, cfg, input_shape): + ret = super().from_config(cfg) + ret["train_on_pred_boxes"] = cfg.MODEL.ROI_BOX_HEAD.TRAIN_ON_PRED_BOXES + # Subclasses that have not been updated to use from_config style construction + # may have overridden _init_*_head methods. In this case, those overridden methods + # will not be classmethods and we need to avoid trying to call them here. + # We test for this with ismethod which only returns True for bound methods of cls. + # Such subclasses will need to handle calling their overridden _init_*_head methods. + if inspect.ismethod(cls._init_box_head): + ret.update(cls._init_box_head(cfg, input_shape)) + if inspect.ismethod(cls._init_mask_head): + ret.update(cls._init_mask_head(cfg, input_shape)) + if inspect.ismethod(cls._init_keypoint_head): + ret.update(cls._init_keypoint_head(cfg, input_shape)) + return ret + + @classmethod + def _init_box_head(cls, cfg, input_shape): + # fmt: off + in_features = cfg.MODEL.ROI_HEADS.IN_FEATURES + pooler_resolution = cfg.MODEL.ROI_BOX_HEAD.POOLER_RESOLUTION + pooler_scales = tuple(1.0 / input_shape[k].stride for k in in_features) + sampling_ratio = cfg.MODEL.ROI_BOX_HEAD.POOLER_SAMPLING_RATIO + pooler_type = cfg.MODEL.ROI_BOX_HEAD.POOLER_TYPE + # fmt: on + + # If StandardROIHeads is applied on multiple feature maps (as in FPN), + # then we share the same predictors and therefore the channel counts must be the same + in_channels = [input_shape[f].channels for f in in_features] + # Check all channel counts are equal + assert len(set(in_channels)) == 1, in_channels + in_channels = in_channels[0] + + box_pooler = ROIPooler( + output_size=pooler_resolution, + scales=pooler_scales, + sampling_ratio=sampling_ratio, + pooler_type=pooler_type, + ) + # Here we split "box head" and "box predictor", which is mainly due to historical reasons. + # They are used together so the "box predictor" layers should be part of the "box head". + # New subclasses of ROIHeads do not need "box predictor"s. + box_head = build_box_head( + cfg, ShapeSpec(channels=in_channels, height=pooler_resolution, width=pooler_resolution) + ) + box_predictor = FastRCNNOutputLayers(cfg, box_head.output_shape) + return { + "box_in_features": in_features, + "box_pooler": box_pooler, + "box_head": box_head, + "box_predictor": box_predictor, + } + + @classmethod + def _init_mask_head(cls, cfg, input_shape): + if not cfg.MODEL.MASK_ON: + return {} + # fmt: off + in_features = cfg.MODEL.ROI_HEADS.IN_FEATURES + pooler_resolution = cfg.MODEL.ROI_MASK_HEAD.POOLER_RESOLUTION + pooler_scales = tuple(1.0 / input_shape[k].stride for k in in_features) + sampling_ratio = cfg.MODEL.ROI_MASK_HEAD.POOLER_SAMPLING_RATIO + pooler_type = cfg.MODEL.ROI_MASK_HEAD.POOLER_TYPE + # fmt: on + + in_channels = [input_shape[f].channels for f in in_features][0] + + ret = {"mask_in_features": in_features} + ret["mask_pooler"] = ( + ROIPooler( + output_size=pooler_resolution, + scales=pooler_scales, + sampling_ratio=sampling_ratio, + pooler_type=pooler_type, + ) + if pooler_type + else None + ) + if pooler_type: + shape = ShapeSpec( + channels=in_channels, width=pooler_resolution, height=pooler_resolution + ) + else: + shape = {f: input_shape[f] for f in in_features} + ret["mask_head"] = build_mask_head(cfg, shape) + return ret + + @classmethod + def _init_keypoint_head(cls, cfg, input_shape): + if not cfg.MODEL.KEYPOINT_ON: + return {} + # fmt: off + in_features = cfg.MODEL.ROI_HEADS.IN_FEATURES + pooler_resolution = cfg.MODEL.ROI_KEYPOINT_HEAD.POOLER_RESOLUTION + pooler_scales = tuple(1.0 / input_shape[k].stride for k in in_features) # noqa + sampling_ratio = cfg.MODEL.ROI_KEYPOINT_HEAD.POOLER_SAMPLING_RATIO + pooler_type = cfg.MODEL.ROI_KEYPOINT_HEAD.POOLER_TYPE + # fmt: on + + in_channels = [input_shape[f].channels for f in in_features][0] + + ret = {"keypoint_in_features": in_features} + ret["keypoint_pooler"] = ( + ROIPooler( + output_size=pooler_resolution, + scales=pooler_scales, + sampling_ratio=sampling_ratio, + pooler_type=pooler_type, + ) + if pooler_type + else None + ) + if pooler_type: + shape = ShapeSpec( + channels=in_channels, width=pooler_resolution, height=pooler_resolution + ) + else: + shape = {f: input_shape[f] for f in in_features} + ret["keypoint_head"] = build_keypoint_head(cfg, shape) + return ret + + def forward( + self, + images: ImageList, + features: Dict[str, torch.Tensor], + proposals: List[Instances], + targets: Optional[List[Instances]] = None, + ) -> Tuple[List[Instances], Dict[str, torch.Tensor]]: + """ + See :class:`ROIHeads.forward`. + """ + del images + if self.training: + assert targets, "'targets' argument is required during training" + proposals = self.label_and_sample_proposals(proposals, targets) + del targets + + if self.training: + losses = self._forward_box(features, proposals) + # Usually the original proposals used by the box head are used by the mask, keypoint + # heads. But when `self.train_on_pred_boxes is True`, proposals will contain boxes + # predicted by the box head. + losses.update(self._forward_mask(features, proposals)) + losses.update(self._forward_keypoint(features, proposals)) + return proposals, losses + else: + pred_instances = self._forward_box(features, proposals) + # During inference cascaded prediction is used: the mask and keypoints heads are only + # applied to the top scoring box detections. + pred_instances = self.forward_with_given_boxes(features, pred_instances) + return pred_instances, {} + + def forward_with_given_boxes( + self, features: Dict[str, torch.Tensor], instances: List[Instances] + ) -> List[Instances]: + """ + Use the given boxes in `instances` to produce other (non-box) per-ROI outputs. + + This is useful for downstream tasks where a box is known, but need to obtain + other attributes (outputs of other heads). + Test-time augmentation also uses this. + + Args: + features: same as in `forward()` + instances (list[Instances]): instances to predict other outputs. Expect the keys + "pred_boxes" and "pred_classes" to exist. + + Returns: + list[Instances]: + the same `Instances` objects, with extra + fields such as `pred_masks` or `pred_keypoints`. + """ + assert not self.training + assert instances[0].has("pred_boxes") and instances[0].has("pred_classes") + + instances = self._forward_mask(features, instances) + instances = self._forward_keypoint(features, instances) + return instances + + def _forward_box(self, features: Dict[str, torch.Tensor], proposals: List[Instances]): + """ + Forward logic of the box prediction branch. If `self.train_on_pred_boxes is True`, + the function puts predicted boxes in the `proposal_boxes` field of `proposals` argument. + + Args: + features (dict[str, Tensor]): mapping from feature map names to tensor. + Same as in :meth:`ROIHeads.forward`. + proposals (list[Instances]): the per-image object proposals with + their matching ground truth. + Each has fields "proposal_boxes", and "objectness_logits", + "gt_classes", "gt_boxes". + + Returns: + In training, a dict of losses. + In inference, a list of `Instances`, the predicted instances. + """ + features = [features[f] for f in self.box_in_features] + box_features = self.box_pooler(features, [x.proposal_boxes for x in proposals]) + box_features = self.box_head(box_features) + predictions = self.box_predictor(box_features) + del box_features + + if self.training: + losses = self.box_predictor.losses(predictions, proposals) + # proposals is modified in-place below, so losses must be computed first. + if self.train_on_pred_boxes: + with torch.no_grad(): + pred_boxes = self.box_predictor.predict_boxes_for_gt_classes( + predictions, proposals + ) + for proposals_per_image, pred_boxes_per_image in zip(proposals, pred_boxes): + proposals_per_image.proposal_boxes = Boxes(pred_boxes_per_image) + return losses + else: + pred_instances, _ = self.box_predictor.inference(predictions, proposals) + return pred_instances + + def _forward_mask(self, features: Dict[str, torch.Tensor], instances: List[Instances]): + """ + Forward logic of the mask prediction branch. + + Args: + features (dict[str, Tensor]): mapping from feature map names to tensor. + Same as in :meth:`ROIHeads.forward`. + instances (list[Instances]): the per-image instances to train/predict masks. + In training, they can be the proposals. + In inference, they can be the boxes predicted by R-CNN box head. + + Returns: + In training, a dict of losses. + In inference, update `instances` with new fields "pred_masks" and return it. + """ + if not self.mask_on: + return {} if self.training else instances + + if self.training: + # head is only trained on positive proposals. + instances, _ = select_foreground_proposals(instances, self.num_classes) + + if self.mask_pooler is not None: + features = [features[f] for f in self.mask_in_features] + boxes = [x.proposal_boxes if self.training else x.pred_boxes for x in instances] + features = self.mask_pooler(features, boxes) + else: + features = {f: features[f] for f in self.mask_in_features} + return self.mask_head(features, instances) + + def _forward_keypoint(self, features: Dict[str, torch.Tensor], instances: List[Instances]): + """ + Forward logic of the keypoint prediction branch. + + Args: + features (dict[str, Tensor]): mapping from feature map names to tensor. + Same as in :meth:`ROIHeads.forward`. + instances (list[Instances]): the per-image instances to train/predict keypoints. + In training, they can be the proposals. + In inference, they can be the boxes predicted by R-CNN box head. + + Returns: + In training, a dict of losses. + In inference, update `instances` with new fields "pred_keypoints" and return it. + """ + if not self.keypoint_on: + return {} if self.training else instances + + if self.training: + # head is only trained on positive proposals with >=1 visible keypoints. + instances, _ = select_foreground_proposals(instances, self.num_classes) + instances = select_proposals_with_visible_keypoints(instances) + + if self.keypoint_pooler is not None: + features = [features[f] for f in self.keypoint_in_features] + boxes = [x.proposal_boxes if self.training else x.pred_boxes for x in instances] + features = self.keypoint_pooler(features, boxes) + else: + features = {f: features[f] for f in self.keypoint_in_features} + return self.keypoint_head(features, instances) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/rotated_fast_rcnn.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/rotated_fast_rcnn.py new file mode 100644 index 00000000..0d4cb8d5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/roi_heads/rotated_fast_rcnn.py @@ -0,0 +1,271 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import logging +import numpy as np +import torch + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.layers import ShapeSpec, batched_nms_rotated +from annotator.oneformer.detectron2.structures import Instances, RotatedBoxes, pairwise_iou_rotated +from annotator.oneformer.detectron2.utils.events import get_event_storage + +from ..box_regression import Box2BoxTransformRotated +from ..poolers import ROIPooler +from ..proposal_generator.proposal_utils import add_ground_truth_to_proposals +from .box_head import build_box_head +from .fast_rcnn import FastRCNNOutputLayers +from .roi_heads import ROI_HEADS_REGISTRY, StandardROIHeads + +logger = logging.getLogger(__name__) + +""" +Shape shorthand in this module: + + N: number of images in the minibatch + R: number of ROIs, combined over all images, in the minibatch + Ri: number of ROIs in image i + K: number of foreground classes. E.g.,there are 80 foreground classes in COCO. + +Naming convention: + + deltas: refers to the 5-d (dx, dy, dw, dh, da) deltas that parameterize the box2box + transform (see :class:`box_regression.Box2BoxTransformRotated`). + + pred_class_logits: predicted class scores in [-inf, +inf]; use + softmax(pred_class_logits) to estimate P(class). + + gt_classes: ground-truth classification labels in [0, K], where [0, K) represent + foreground object classes and K represents the background class. + + pred_proposal_deltas: predicted rotated box2box transform deltas for transforming proposals + to detection box predictions. + + gt_proposal_deltas: ground-truth rotated box2box transform deltas +""" + + +def fast_rcnn_inference_rotated( + boxes, scores, image_shapes, score_thresh, nms_thresh, topk_per_image +): + """ + Call `fast_rcnn_inference_single_image_rotated` for all images. + + Args: + boxes (list[Tensor]): A list of Tensors of predicted class-specific or class-agnostic + boxes for each image. Element i has shape (Ri, K * 5) if doing + class-specific regression, or (Ri, 5) if doing class-agnostic + regression, where Ri is the number of predicted objects for image i. + This is compatible with the output of :meth:`FastRCNNOutputLayers.predict_boxes`. + scores (list[Tensor]): A list of Tensors of predicted class scores for each image. + Element i has shape (Ri, K + 1), where Ri is the number of predicted objects + for image i. Compatible with the output of :meth:`FastRCNNOutputLayers.predict_probs`. + image_shapes (list[tuple]): A list of (width, height) tuples for each image in the batch. + score_thresh (float): Only return detections with a confidence score exceeding this + threshold. + nms_thresh (float): The threshold to use for box non-maximum suppression. Value in [0, 1]. + topk_per_image (int): The number of top scoring detections to return. Set < 0 to return + all detections. + + Returns: + instances: (list[Instances]): A list of N instances, one for each image in the batch, + that stores the topk most confidence detections. + kept_indices: (list[Tensor]): A list of 1D tensor of length of N, each element indicates + the corresponding boxes/scores index in [0, Ri) from the input, for image i. + """ + result_per_image = [ + fast_rcnn_inference_single_image_rotated( + boxes_per_image, scores_per_image, image_shape, score_thresh, nms_thresh, topk_per_image + ) + for scores_per_image, boxes_per_image, image_shape in zip(scores, boxes, image_shapes) + ] + return [x[0] for x in result_per_image], [x[1] for x in result_per_image] + + +@torch.no_grad() +def fast_rcnn_inference_single_image_rotated( + boxes, scores, image_shape, score_thresh, nms_thresh, topk_per_image +): + """ + Single-image inference. Return rotated bounding-box detection results by thresholding + on scores and applying rotated non-maximum suppression (Rotated NMS). + + Args: + Same as `fast_rcnn_inference_rotated`, but with rotated boxes, scores, and image shapes + per image. + + Returns: + Same as `fast_rcnn_inference_rotated`, but for only one image. + """ + valid_mask = torch.isfinite(boxes).all(dim=1) & torch.isfinite(scores).all(dim=1) + if not valid_mask.all(): + boxes = boxes[valid_mask] + scores = scores[valid_mask] + + B = 5 # box dimension + scores = scores[:, :-1] + num_bbox_reg_classes = boxes.shape[1] // B + # Convert to Boxes to use the `clip` function ... + boxes = RotatedBoxes(boxes.reshape(-1, B)) + boxes.clip(image_shape) + boxes = boxes.tensor.view(-1, num_bbox_reg_classes, B) # R x C x B + # Filter results based on detection scores + filter_mask = scores > score_thresh # R x K + # R' x 2. First column contains indices of the R predictions; + # Second column contains indices of classes. + filter_inds = filter_mask.nonzero() + if num_bbox_reg_classes == 1: + boxes = boxes[filter_inds[:, 0], 0] + else: + boxes = boxes[filter_mask] + scores = scores[filter_mask] + + # Apply per-class Rotated NMS + keep = batched_nms_rotated(boxes, scores, filter_inds[:, 1], nms_thresh) + if topk_per_image >= 0: + keep = keep[:topk_per_image] + boxes, scores, filter_inds = boxes[keep], scores[keep], filter_inds[keep] + + result = Instances(image_shape) + result.pred_boxes = RotatedBoxes(boxes) + result.scores = scores + result.pred_classes = filter_inds[:, 1] + + return result, filter_inds[:, 0] + + +class RotatedFastRCNNOutputLayers(FastRCNNOutputLayers): + """ + Two linear layers for predicting Rotated Fast R-CNN outputs. + """ + + @classmethod + def from_config(cls, cfg, input_shape): + args = super().from_config(cfg, input_shape) + args["box2box_transform"] = Box2BoxTransformRotated( + weights=cfg.MODEL.ROI_BOX_HEAD.BBOX_REG_WEIGHTS + ) + return args + + def inference(self, predictions, proposals): + """ + Returns: + list[Instances]: same as `fast_rcnn_inference_rotated`. + list[Tensor]: same as `fast_rcnn_inference_rotated`. + """ + boxes = self.predict_boxes(predictions, proposals) + scores = self.predict_probs(predictions, proposals) + image_shapes = [x.image_size for x in proposals] + + return fast_rcnn_inference_rotated( + boxes, + scores, + image_shapes, + self.test_score_thresh, + self.test_nms_thresh, + self.test_topk_per_image, + ) + + +@ROI_HEADS_REGISTRY.register() +class RROIHeads(StandardROIHeads): + """ + This class is used by Rotated Fast R-CNN to detect rotated boxes. + For now, it only supports box predictions but not mask or keypoints. + """ + + @configurable + def __init__(self, **kwargs): + """ + NOTE: this interface is experimental. + """ + super().__init__(**kwargs) + assert ( + not self.mask_on and not self.keypoint_on + ), "Mask/Keypoints not supported in Rotated ROIHeads." + assert not self.train_on_pred_boxes, "train_on_pred_boxes not implemented for RROIHeads!" + + @classmethod + def _init_box_head(cls, cfg, input_shape): + # fmt: off + in_features = cfg.MODEL.ROI_HEADS.IN_FEATURES + pooler_resolution = cfg.MODEL.ROI_BOX_HEAD.POOLER_RESOLUTION + pooler_scales = tuple(1.0 / input_shape[k].stride for k in in_features) + sampling_ratio = cfg.MODEL.ROI_BOX_HEAD.POOLER_SAMPLING_RATIO + pooler_type = cfg.MODEL.ROI_BOX_HEAD.POOLER_TYPE + # fmt: on + assert pooler_type in ["ROIAlignRotated"], pooler_type + # assume all channel counts are equal + in_channels = [input_shape[f].channels for f in in_features][0] + + box_pooler = ROIPooler( + output_size=pooler_resolution, + scales=pooler_scales, + sampling_ratio=sampling_ratio, + pooler_type=pooler_type, + ) + box_head = build_box_head( + cfg, ShapeSpec(channels=in_channels, height=pooler_resolution, width=pooler_resolution) + ) + # This line is the only difference v.s. StandardROIHeads + box_predictor = RotatedFastRCNNOutputLayers(cfg, box_head.output_shape) + return { + "box_in_features": in_features, + "box_pooler": box_pooler, + "box_head": box_head, + "box_predictor": box_predictor, + } + + @torch.no_grad() + def label_and_sample_proposals(self, proposals, targets): + """ + Prepare some proposals to be used to train the RROI heads. + It performs box matching between `proposals` and `targets`, and assigns + training labels to the proposals. + It returns `self.batch_size_per_image` random samples from proposals and groundtruth boxes, + with a fraction of positives that is no larger than `self.positive_sample_fraction. + + Args: + See :meth:`StandardROIHeads.forward` + + Returns: + list[Instances]: length `N` list of `Instances`s containing the proposals + sampled for training. Each `Instances` has the following fields: + - proposal_boxes: the rotated proposal boxes + - gt_boxes: the ground-truth rotated boxes that the proposal is assigned to + (this is only meaningful if the proposal has a label > 0; if label = 0 + then the ground-truth box is random) + - gt_classes: the ground-truth classification lable for each proposal + """ + if self.proposal_append_gt: + proposals = add_ground_truth_to_proposals(targets, proposals) + + proposals_with_gt = [] + + num_fg_samples = [] + num_bg_samples = [] + for proposals_per_image, targets_per_image in zip(proposals, targets): + has_gt = len(targets_per_image) > 0 + match_quality_matrix = pairwise_iou_rotated( + targets_per_image.gt_boxes, proposals_per_image.proposal_boxes + ) + matched_idxs, matched_labels = self.proposal_matcher(match_quality_matrix) + sampled_idxs, gt_classes = self._sample_proposals( + matched_idxs, matched_labels, targets_per_image.gt_classes + ) + + proposals_per_image = proposals_per_image[sampled_idxs] + proposals_per_image.gt_classes = gt_classes + + if has_gt: + sampled_targets = matched_idxs[sampled_idxs] + proposals_per_image.gt_boxes = targets_per_image.gt_boxes[sampled_targets] + + num_bg_samples.append((gt_classes == self.num_classes).sum().item()) + num_fg_samples.append(gt_classes.numel() - num_bg_samples[-1]) + proposals_with_gt.append(proposals_per_image) + + # Log the number of fg/bg samples that are selected for training ROI heads + storage = get_event_storage() + storage.put_scalar("roi_head/num_fg_samples", np.mean(num_fg_samples)) + storage.put_scalar("roi_head/num_bg_samples", np.mean(num_bg_samples)) + + return proposals_with_gt diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/sampling.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/sampling.py new file mode 100644 index 00000000..5c55fbf9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/sampling.py @@ -0,0 +1,54 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import torch + +from annotator.oneformer.detectron2.layers import nonzero_tuple + +__all__ = ["subsample_labels"] + + +def subsample_labels( + labels: torch.Tensor, num_samples: int, positive_fraction: float, bg_label: int +): + """ + Return `num_samples` (or fewer, if not enough found) + random samples from `labels` which is a mixture of positives & negatives. + It will try to return as many positives as possible without + exceeding `positive_fraction * num_samples`, and then try to + fill the remaining slots with negatives. + + Args: + labels (Tensor): (N, ) label vector with values: + * -1: ignore + * bg_label: background ("negative") class + * otherwise: one or more foreground ("positive") classes + num_samples (int): The total number of labels with value >= 0 to return. + Values that are not sampled will be filled with -1 (ignore). + positive_fraction (float): The number of subsampled labels with values > 0 + is `min(num_positives, int(positive_fraction * num_samples))`. The number + of negatives sampled is `min(num_negatives, num_samples - num_positives_sampled)`. + In order words, if there are not enough positives, the sample is filled with + negatives. If there are also not enough negatives, then as many elements are + sampled as is possible. + bg_label (int): label index of background ("negative") class. + + Returns: + pos_idx, neg_idx (Tensor): + 1D vector of indices. The total length of both is `num_samples` or fewer. + """ + positive = nonzero_tuple((labels != -1) & (labels != bg_label))[0] + negative = nonzero_tuple(labels == bg_label)[0] + + num_pos = int(num_samples * positive_fraction) + # protect against not enough positive examples + num_pos = min(positive.numel(), num_pos) + num_neg = num_samples - num_pos + # protect against not enough negative examples + num_neg = min(negative.numel(), num_neg) + + # randomly select positive and negative examples + perm1 = torch.randperm(positive.numel(), device=positive.device)[:num_pos] + perm2 = torch.randperm(negative.numel(), device=negative.device)[:num_neg] + + pos_idx = positive[perm1] + neg_idx = negative[perm2] + return pos_idx, neg_idx diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/test_time_augmentation.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/test_time_augmentation.py new file mode 100644 index 00000000..625f8ba9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/modeling/test_time_augmentation.py @@ -0,0 +1,307 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import copy +import numpy as np +from contextlib import contextmanager +from itertools import count +from typing import List +import torch +from fvcore.transforms import HFlipTransform, NoOpTransform +from torch import nn +from torch.nn.parallel import DistributedDataParallel + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.data.detection_utils import read_image +from annotator.oneformer.detectron2.data.transforms import ( + RandomFlip, + ResizeShortestEdge, + ResizeTransform, + apply_augmentations, +) +from annotator.oneformer.detectron2.structures import Boxes, Instances + +from .meta_arch import GeneralizedRCNN +from .postprocessing import detector_postprocess +from .roi_heads.fast_rcnn import fast_rcnn_inference_single_image + +__all__ = ["DatasetMapperTTA", "GeneralizedRCNNWithTTA"] + + +class DatasetMapperTTA: + """ + Implement test-time augmentation for detection data. + It is a callable which takes a dataset dict from a detection dataset, + and returns a list of dataset dicts where the images + are augmented from the input image by the transformations defined in the config. + This is used for test-time augmentation. + """ + + @configurable + def __init__(self, min_sizes: List[int], max_size: int, flip: bool): + """ + Args: + min_sizes: list of short-edge size to resize the image to + max_size: maximum height or width of resized images + flip: whether to apply flipping augmentation + """ + self.min_sizes = min_sizes + self.max_size = max_size + self.flip = flip + + @classmethod + def from_config(cls, cfg): + return { + "min_sizes": cfg.TEST.AUG.MIN_SIZES, + "max_size": cfg.TEST.AUG.MAX_SIZE, + "flip": cfg.TEST.AUG.FLIP, + } + + def __call__(self, dataset_dict): + """ + Args: + dict: a dict in standard model input format. See tutorials for details. + + Returns: + list[dict]: + a list of dicts, which contain augmented version of the input image. + The total number of dicts is ``len(min_sizes) * (2 if flip else 1)``. + Each dict has field "transforms" which is a TransformList, + containing the transforms that are used to generate this image. + """ + numpy_image = dataset_dict["image"].permute(1, 2, 0).numpy() + shape = numpy_image.shape + orig_shape = (dataset_dict["height"], dataset_dict["width"]) + if shape[:2] != orig_shape: + # It transforms the "original" image in the dataset to the input image + pre_tfm = ResizeTransform(orig_shape[0], orig_shape[1], shape[0], shape[1]) + else: + pre_tfm = NoOpTransform() + + # Create all combinations of augmentations to use + aug_candidates = [] # each element is a list[Augmentation] + for min_size in self.min_sizes: + resize = ResizeShortestEdge(min_size, self.max_size) + aug_candidates.append([resize]) # resize only + if self.flip: + flip = RandomFlip(prob=1.0) + aug_candidates.append([resize, flip]) # resize + flip + + # Apply all the augmentations + ret = [] + for aug in aug_candidates: + new_image, tfms = apply_augmentations(aug, np.copy(numpy_image)) + torch_image = torch.from_numpy(np.ascontiguousarray(new_image.transpose(2, 0, 1))) + + dic = copy.deepcopy(dataset_dict) + dic["transforms"] = pre_tfm + tfms + dic["image"] = torch_image + ret.append(dic) + return ret + + +class GeneralizedRCNNWithTTA(nn.Module): + """ + A GeneralizedRCNN with test-time augmentation enabled. + Its :meth:`__call__` method has the same interface as :meth:`GeneralizedRCNN.forward`. + """ + + def __init__(self, cfg, model, tta_mapper=None, batch_size=3): + """ + Args: + cfg (CfgNode): + model (GeneralizedRCNN): a GeneralizedRCNN to apply TTA on. + tta_mapper (callable): takes a dataset dict and returns a list of + augmented versions of the dataset dict. Defaults to + `DatasetMapperTTA(cfg)`. + batch_size (int): batch the augmented images into this batch size for inference. + """ + super().__init__() + if isinstance(model, DistributedDataParallel): + model = model.module + assert isinstance( + model, GeneralizedRCNN + ), "TTA is only supported on GeneralizedRCNN. Got a model of type {}".format(type(model)) + self.cfg = cfg.clone() + assert not self.cfg.MODEL.KEYPOINT_ON, "TTA for keypoint is not supported yet" + assert ( + not self.cfg.MODEL.LOAD_PROPOSALS + ), "TTA for pre-computed proposals is not supported yet" + + self.model = model + + if tta_mapper is None: + tta_mapper = DatasetMapperTTA(cfg) + self.tta_mapper = tta_mapper + self.batch_size = batch_size + + @contextmanager + def _turn_off_roi_heads(self, attrs): + """ + Open a context where some heads in `model.roi_heads` are temporarily turned off. + Args: + attr (list[str]): the attribute in `model.roi_heads` which can be used + to turn off a specific head, e.g., "mask_on", "keypoint_on". + """ + roi_heads = self.model.roi_heads + old = {} + for attr in attrs: + try: + old[attr] = getattr(roi_heads, attr) + except AttributeError: + # The head may not be implemented in certain ROIHeads + pass + + if len(old.keys()) == 0: + yield + else: + for attr in old.keys(): + setattr(roi_heads, attr, False) + yield + for attr in old.keys(): + setattr(roi_heads, attr, old[attr]) + + def _batch_inference(self, batched_inputs, detected_instances=None): + """ + Execute inference on a list of inputs, + using batch size = self.batch_size, instead of the length of the list. + + Inputs & outputs have the same format as :meth:`GeneralizedRCNN.inference` + """ + if detected_instances is None: + detected_instances = [None] * len(batched_inputs) + + outputs = [] + inputs, instances = [], [] + for idx, input, instance in zip(count(), batched_inputs, detected_instances): + inputs.append(input) + instances.append(instance) + if len(inputs) == self.batch_size or idx == len(batched_inputs) - 1: + outputs.extend( + self.model.inference( + inputs, + instances if instances[0] is not None else None, + do_postprocess=False, + ) + ) + inputs, instances = [], [] + return outputs + + def __call__(self, batched_inputs): + """ + Same input/output format as :meth:`GeneralizedRCNN.forward` + """ + + def _maybe_read_image(dataset_dict): + ret = copy.copy(dataset_dict) + if "image" not in ret: + image = read_image(ret.pop("file_name"), self.model.input_format) + image = torch.from_numpy(np.ascontiguousarray(image.transpose(2, 0, 1))) # CHW + ret["image"] = image + if "height" not in ret and "width" not in ret: + ret["height"] = image.shape[1] + ret["width"] = image.shape[2] + return ret + + return [self._inference_one_image(_maybe_read_image(x)) for x in batched_inputs] + + def _inference_one_image(self, input): + """ + Args: + input (dict): one dataset dict with "image" field being a CHW tensor + + Returns: + dict: one output dict + """ + orig_shape = (input["height"], input["width"]) + augmented_inputs, tfms = self._get_augmented_inputs(input) + # Detect boxes from all augmented versions + with self._turn_off_roi_heads(["mask_on", "keypoint_on"]): + # temporarily disable roi heads + all_boxes, all_scores, all_classes = self._get_augmented_boxes(augmented_inputs, tfms) + # merge all detected boxes to obtain final predictions for boxes + merged_instances = self._merge_detections(all_boxes, all_scores, all_classes, orig_shape) + + if self.cfg.MODEL.MASK_ON: + # Use the detected boxes to obtain masks + augmented_instances = self._rescale_detected_boxes( + augmented_inputs, merged_instances, tfms + ) + # run forward on the detected boxes + outputs = self._batch_inference(augmented_inputs, augmented_instances) + # Delete now useless variables to avoid being out of memory + del augmented_inputs, augmented_instances + # average the predictions + merged_instances.pred_masks = self._reduce_pred_masks(outputs, tfms) + merged_instances = detector_postprocess(merged_instances, *orig_shape) + return {"instances": merged_instances} + else: + return {"instances": merged_instances} + + def _get_augmented_inputs(self, input): + augmented_inputs = self.tta_mapper(input) + tfms = [x.pop("transforms") for x in augmented_inputs] + return augmented_inputs, tfms + + def _get_augmented_boxes(self, augmented_inputs, tfms): + # 1: forward with all augmented images + outputs = self._batch_inference(augmented_inputs) + # 2: union the results + all_boxes = [] + all_scores = [] + all_classes = [] + for output, tfm in zip(outputs, tfms): + # Need to inverse the transforms on boxes, to obtain results on original image + pred_boxes = output.pred_boxes.tensor + original_pred_boxes = tfm.inverse().apply_box(pred_boxes.cpu().numpy()) + all_boxes.append(torch.from_numpy(original_pred_boxes).to(pred_boxes.device)) + + all_scores.extend(output.scores) + all_classes.extend(output.pred_classes) + all_boxes = torch.cat(all_boxes, dim=0) + return all_boxes, all_scores, all_classes + + def _merge_detections(self, all_boxes, all_scores, all_classes, shape_hw): + # select from the union of all results + num_boxes = len(all_boxes) + num_classes = self.cfg.MODEL.ROI_HEADS.NUM_CLASSES + # +1 because fast_rcnn_inference expects background scores as well + all_scores_2d = torch.zeros(num_boxes, num_classes + 1, device=all_boxes.device) + for idx, cls, score in zip(count(), all_classes, all_scores): + all_scores_2d[idx, cls] = score + + merged_instances, _ = fast_rcnn_inference_single_image( + all_boxes, + all_scores_2d, + shape_hw, + 1e-8, + self.cfg.MODEL.ROI_HEADS.NMS_THRESH_TEST, + self.cfg.TEST.DETECTIONS_PER_IMAGE, + ) + + return merged_instances + + def _rescale_detected_boxes(self, augmented_inputs, merged_instances, tfms): + augmented_instances = [] + for input, tfm in zip(augmented_inputs, tfms): + # Transform the target box to the augmented image's coordinate space + pred_boxes = merged_instances.pred_boxes.tensor.cpu().numpy() + pred_boxes = torch.from_numpy(tfm.apply_box(pred_boxes)) + + aug_instances = Instances( + image_size=input["image"].shape[1:3], + pred_boxes=Boxes(pred_boxes), + pred_classes=merged_instances.pred_classes, + scores=merged_instances.scores, + ) + augmented_instances.append(aug_instances) + return augmented_instances + + def _reduce_pred_masks(self, outputs, tfms): + # Should apply inverse transforms on masks. + # We assume only resize & flip are used. pred_masks is a scale-invariant + # representation, so we handle flip specially + for output, tfm in zip(outputs, tfms): + if any(isinstance(t, HFlipTransform) for t in tfm.transforms): + output.pred_masks = output.pred_masks.flip(dims=[3]) + all_pred_masks = torch.stack([o.pred_masks for o in outputs], dim=0) + avg_pred_masks = torch.mean(all_pred_masks, dim=0) + return avg_pred_masks diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/README.md b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/README.md new file mode 100644 index 00000000..95afe7ff --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/README.md @@ -0,0 +1,2 @@ + +Projects live in the [`projects` directory](../../projects) under the root of this repository, but not here. diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/__init__.py new file mode 100644 index 00000000..b2d0540b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/__init__.py @@ -0,0 +1,34 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import importlib.abc +import importlib.util +from pathlib import Path + +__all__ = [] + +_PROJECTS = { + "point_rend": "PointRend", + "deeplab": "DeepLab", + "panoptic_deeplab": "Panoptic-DeepLab", +} +_PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent / "projects" + +if _PROJECT_ROOT.is_dir(): + # This is true only for in-place installation (pip install -e, setup.py develop), + # where setup(package_dir=) does not work: https://github.com/pypa/setuptools/issues/230 + + class _D2ProjectsFinder(importlib.abc.MetaPathFinder): + def find_spec(self, name, path, target=None): + if not name.startswith("detectron2.projects."): + return + project_name = name.split(".")[-1] + project_dir = _PROJECTS.get(project_name) + if not project_dir: + return + target_file = _PROJECT_ROOT / f"{project_dir}/{project_name}/__init__.py" + if not target_file.is_file(): + return + return importlib.util.spec_from_file_location(name, target_file) + + import sys + + sys.meta_path.append(_D2ProjectsFinder()) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/__init__.py new file mode 100644 index 00000000..dcd88ff0 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/__init__.py @@ -0,0 +1,5 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from .build_solver import build_lr_scheduler +from .config import add_deeplab_config +from .resnet import build_resnet_deeplab_backbone +from .semantic_seg import DeepLabV3Head, DeepLabV3PlusHead diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/build_solver.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/build_solver.py new file mode 100644 index 00000000..19ab2443 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/build_solver.py @@ -0,0 +1,27 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import torch + +from annotator.oneformer.detectron2.config import CfgNode +from annotator.oneformer.detectron2.solver import LRScheduler +from annotator.oneformer.detectron2.solver import build_lr_scheduler as build_d2_lr_scheduler + +from .lr_scheduler import WarmupPolyLR + + +def build_lr_scheduler(cfg: CfgNode, optimizer: torch.optim.Optimizer) -> LRScheduler: + """ + Build a LR scheduler from config. + """ + name = cfg.SOLVER.LR_SCHEDULER_NAME + if name == "WarmupPolyLR": + return WarmupPolyLR( + optimizer, + cfg.SOLVER.MAX_ITER, + warmup_factor=cfg.SOLVER.WARMUP_FACTOR, + warmup_iters=cfg.SOLVER.WARMUP_ITERS, + warmup_method=cfg.SOLVER.WARMUP_METHOD, + power=cfg.SOLVER.POLY_LR_POWER, + constant_ending=cfg.SOLVER.POLY_LR_CONSTANT_ENDING, + ) + else: + return build_d2_lr_scheduler(cfg, optimizer) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/config.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/config.py new file mode 100644 index 00000000..5f5e45a9 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/config.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + + +def add_deeplab_config(cfg): + """ + Add config for DeepLab. + """ + # We retry random cropping until no single category in semantic segmentation GT occupies more + # than `SINGLE_CATEGORY_MAX_AREA` part of the crop. + cfg.INPUT.CROP.SINGLE_CATEGORY_MAX_AREA = 1.0 + # Used for `poly` learning rate schedule. + cfg.SOLVER.POLY_LR_POWER = 0.9 + cfg.SOLVER.POLY_LR_CONSTANT_ENDING = 0.0 + # Loss type, choose from `cross_entropy`, `hard_pixel_mining`. + cfg.MODEL.SEM_SEG_HEAD.LOSS_TYPE = "hard_pixel_mining" + # DeepLab settings + cfg.MODEL.SEM_SEG_HEAD.PROJECT_FEATURES = ["res2"] + cfg.MODEL.SEM_SEG_HEAD.PROJECT_CHANNELS = [48] + cfg.MODEL.SEM_SEG_HEAD.ASPP_CHANNELS = 256 + cfg.MODEL.SEM_SEG_HEAD.ASPP_DILATIONS = [6, 12, 18] + cfg.MODEL.SEM_SEG_HEAD.ASPP_DROPOUT = 0.1 + cfg.MODEL.SEM_SEG_HEAD.USE_DEPTHWISE_SEPARABLE_CONV = False + # Backbone new configs + cfg.MODEL.RESNETS.RES4_DILATION = 1 + cfg.MODEL.RESNETS.RES5_MULTI_GRID = [1, 2, 4] + # ResNet stem type from: `basic`, `deeplab` + cfg.MODEL.RESNETS.STEM_TYPE = "deeplab" diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/loss.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/loss.py new file mode 100644 index 00000000..3a43087b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/loss.py @@ -0,0 +1,40 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import torch +import torch.nn as nn + + +class DeepLabCE(nn.Module): + """ + Hard pixel mining with cross entropy loss, for semantic segmentation. + This is used in TensorFlow DeepLab frameworks. + Paper: DeeperLab: Single-Shot Image Parser + Reference: https://github.com/tensorflow/models/blob/bd488858d610e44df69da6f89277e9de8a03722c/research/deeplab/utils/train_utils.py#L33 # noqa + Arguments: + ignore_label: Integer, label to ignore. + top_k_percent_pixels: Float, the value lies in [0.0, 1.0]. When its + value < 1.0, only compute the loss for the top k percent pixels + (e.g., the top 20% pixels). This is useful for hard pixel mining. + weight: Tensor, a manual rescaling weight given to each class. + """ + + def __init__(self, ignore_label=-1, top_k_percent_pixels=1.0, weight=None): + super(DeepLabCE, self).__init__() + self.top_k_percent_pixels = top_k_percent_pixels + self.ignore_label = ignore_label + self.criterion = nn.CrossEntropyLoss( + weight=weight, ignore_index=ignore_label, reduction="none" + ) + + def forward(self, logits, labels, weights=None): + if weights is None: + pixel_losses = self.criterion(logits, labels).contiguous().view(-1) + else: + # Apply per-pixel loss weights. + pixel_losses = self.criterion(logits, labels) * weights + pixel_losses = pixel_losses.contiguous().view(-1) + if self.top_k_percent_pixels == 1.0: + return pixel_losses.mean() + + top_k_pixels = int(self.top_k_percent_pixels * pixel_losses.numel()) + pixel_losses, _ = torch.topk(pixel_losses, top_k_pixels) + return pixel_losses.mean() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/lr_scheduler.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/lr_scheduler.py new file mode 100644 index 00000000..9e15b0e1 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/lr_scheduler.py @@ -0,0 +1,62 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import math +from typing import List +import torch + +from annotator.oneformer.detectron2.solver.lr_scheduler import LRScheduler, _get_warmup_factor_at_iter + +# NOTE: PyTorch's LR scheduler interface uses names that assume the LR changes +# only on epoch boundaries. We typically use iteration based schedules instead. +# As a result, "epoch" (e.g., as in self.last_epoch) should be understood to mean +# "iteration" instead. + +# FIXME: ideally this would be achieved with a CombinedLRScheduler, separating +# MultiStepLR with WarmupLR but the current LRScheduler design doesn't allow it. + + +class WarmupPolyLR(LRScheduler): + """ + Poly learning rate schedule used to train DeepLab. + Paper: DeepLab: Semantic Image Segmentation with Deep Convolutional Nets, + Atrous Convolution, and Fully Connected CRFs. + Reference: https://github.com/tensorflow/models/blob/21b73d22f3ed05b650e85ac50849408dd36de32e/research/deeplab/utils/train_utils.py#L337 # noqa + """ + + def __init__( + self, + optimizer: torch.optim.Optimizer, + max_iters: int, + warmup_factor: float = 0.001, + warmup_iters: int = 1000, + warmup_method: str = "linear", + last_epoch: int = -1, + power: float = 0.9, + constant_ending: float = 0.0, + ): + self.max_iters = max_iters + self.warmup_factor = warmup_factor + self.warmup_iters = warmup_iters + self.warmup_method = warmup_method + self.power = power + self.constant_ending = constant_ending + super().__init__(optimizer, last_epoch) + + def get_lr(self) -> List[float]: + warmup_factor = _get_warmup_factor_at_iter( + self.warmup_method, self.last_epoch, self.warmup_iters, self.warmup_factor + ) + if self.constant_ending > 0 and warmup_factor == 1.0: + # Constant ending lr. + if ( + math.pow((1.0 - self.last_epoch / self.max_iters), self.power) + < self.constant_ending + ): + return [base_lr * self.constant_ending for base_lr in self.base_lrs] + return [ + base_lr * warmup_factor * math.pow((1.0 - self.last_epoch / self.max_iters), self.power) + for base_lr in self.base_lrs + ] + + def _compute_values(self) -> List[float]: + # The new interface + return self.get_lr() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/resnet.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/resnet.py new file mode 100644 index 00000000..28455d12 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/resnet.py @@ -0,0 +1,158 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import fvcore.nn.weight_init as weight_init +import torch.nn.functional as F + +from annotator.oneformer.detectron2.layers import CNNBlockBase, Conv2d, get_norm +from annotator.oneformer.detectron2.modeling import BACKBONE_REGISTRY +from annotator.oneformer.detectron2.modeling.backbone.resnet import ( + BasicStem, + BottleneckBlock, + DeformBottleneckBlock, + ResNet, +) + + +class DeepLabStem(CNNBlockBase): + """ + The DeepLab ResNet stem (layers before the first residual block). + """ + + def __init__(self, in_channels=3, out_channels=128, norm="BN"): + """ + Args: + norm (str or callable): norm after the first conv layer. + See :func:`layers.get_norm` for supported format. + """ + super().__init__(in_channels, out_channels, 4) + self.in_channels = in_channels + self.conv1 = Conv2d( + in_channels, + out_channels // 2, + kernel_size=3, + stride=2, + padding=1, + bias=False, + norm=get_norm(norm, out_channels // 2), + ) + self.conv2 = Conv2d( + out_channels // 2, + out_channels // 2, + kernel_size=3, + stride=1, + padding=1, + bias=False, + norm=get_norm(norm, out_channels // 2), + ) + self.conv3 = Conv2d( + out_channels // 2, + out_channels, + kernel_size=3, + stride=1, + padding=1, + bias=False, + norm=get_norm(norm, out_channels), + ) + weight_init.c2_msra_fill(self.conv1) + weight_init.c2_msra_fill(self.conv2) + weight_init.c2_msra_fill(self.conv3) + + def forward(self, x): + x = self.conv1(x) + x = F.relu_(x) + x = self.conv2(x) + x = F.relu_(x) + x = self.conv3(x) + x = F.relu_(x) + x = F.max_pool2d(x, kernel_size=3, stride=2, padding=1) + return x + + +@BACKBONE_REGISTRY.register() +def build_resnet_deeplab_backbone(cfg, input_shape): + """ + Create a ResNet instance from config. + Returns: + ResNet: a :class:`ResNet` instance. + """ + # need registration of new blocks/stems? + norm = cfg.MODEL.RESNETS.NORM + if cfg.MODEL.RESNETS.STEM_TYPE == "basic": + stem = BasicStem( + in_channels=input_shape.channels, + out_channels=cfg.MODEL.RESNETS.STEM_OUT_CHANNELS, + norm=norm, + ) + elif cfg.MODEL.RESNETS.STEM_TYPE == "deeplab": + stem = DeepLabStem( + in_channels=input_shape.channels, + out_channels=cfg.MODEL.RESNETS.STEM_OUT_CHANNELS, + norm=norm, + ) + else: + raise ValueError("Unknown stem type: {}".format(cfg.MODEL.RESNETS.STEM_TYPE)) + + # fmt: off + freeze_at = cfg.MODEL.BACKBONE.FREEZE_AT + out_features = cfg.MODEL.RESNETS.OUT_FEATURES + depth = cfg.MODEL.RESNETS.DEPTH + num_groups = cfg.MODEL.RESNETS.NUM_GROUPS + width_per_group = cfg.MODEL.RESNETS.WIDTH_PER_GROUP + bottleneck_channels = num_groups * width_per_group + in_channels = cfg.MODEL.RESNETS.STEM_OUT_CHANNELS + out_channels = cfg.MODEL.RESNETS.RES2_OUT_CHANNELS + stride_in_1x1 = cfg.MODEL.RESNETS.STRIDE_IN_1X1 + res4_dilation = cfg.MODEL.RESNETS.RES4_DILATION + res5_dilation = cfg.MODEL.RESNETS.RES5_DILATION + deform_on_per_stage = cfg.MODEL.RESNETS.DEFORM_ON_PER_STAGE + deform_modulated = cfg.MODEL.RESNETS.DEFORM_MODULATED + deform_num_groups = cfg.MODEL.RESNETS.DEFORM_NUM_GROUPS + res5_multi_grid = cfg.MODEL.RESNETS.RES5_MULTI_GRID + # fmt: on + assert res4_dilation in {1, 2}, "res4_dilation cannot be {}.".format(res4_dilation) + assert res5_dilation in {1, 2, 4}, "res5_dilation cannot be {}.".format(res5_dilation) + if res4_dilation == 2: + # Always dilate res5 if res4 is dilated. + assert res5_dilation == 4 + + num_blocks_per_stage = {50: [3, 4, 6, 3], 101: [3, 4, 23, 3], 152: [3, 8, 36, 3]}[depth] + + stages = [] + + # Avoid creating variables without gradients + # It consumes extra memory and may cause allreduce to fail + out_stage_idx = [{"res2": 2, "res3": 3, "res4": 4, "res5": 5}[f] for f in out_features] + max_stage_idx = max(out_stage_idx) + for idx, stage_idx in enumerate(range(2, max_stage_idx + 1)): + if stage_idx == 4: + dilation = res4_dilation + elif stage_idx == 5: + dilation = res5_dilation + else: + dilation = 1 + first_stride = 1 if idx == 0 or dilation > 1 else 2 + stage_kargs = { + "num_blocks": num_blocks_per_stage[idx], + "stride_per_block": [first_stride] + [1] * (num_blocks_per_stage[idx] - 1), + "in_channels": in_channels, + "out_channels": out_channels, + "norm": norm, + } + stage_kargs["bottleneck_channels"] = bottleneck_channels + stage_kargs["stride_in_1x1"] = stride_in_1x1 + stage_kargs["dilation"] = dilation + stage_kargs["num_groups"] = num_groups + if deform_on_per_stage[idx]: + stage_kargs["block_class"] = DeformBottleneckBlock + stage_kargs["deform_modulated"] = deform_modulated + stage_kargs["deform_num_groups"] = deform_num_groups + else: + stage_kargs["block_class"] = BottleneckBlock + if stage_idx == 5: + stage_kargs.pop("dilation") + stage_kargs["dilation_per_block"] = [dilation * mg for mg in res5_multi_grid] + blocks = ResNet.make_stage(**stage_kargs) + in_channels = out_channels + out_channels *= 2 + bottleneck_channels *= 2 + stages.append(blocks) + return ResNet(stem, stages, out_features=out_features).freeze(freeze_at) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/semantic_seg.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/semantic_seg.py new file mode 100644 index 00000000..36c26433 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/projects/deeplab/semantic_seg.py @@ -0,0 +1,348 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from typing import Callable, Dict, List, Optional, Tuple, Union +import fvcore.nn.weight_init as weight_init +import torch +from torch import nn +from torch.nn import functional as F + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.layers import ASPP, Conv2d, DepthwiseSeparableConv2d, ShapeSpec, get_norm +from annotator.oneformer.detectron2.modeling import SEM_SEG_HEADS_REGISTRY + +from .loss import DeepLabCE + + +@SEM_SEG_HEADS_REGISTRY.register() +class DeepLabV3PlusHead(nn.Module): + """ + A semantic segmentation head described in :paper:`DeepLabV3+`. + """ + + @configurable + def __init__( + self, + input_shape: Dict[str, ShapeSpec], + *, + project_channels: List[int], + aspp_dilations: List[int], + aspp_dropout: float, + decoder_channels: List[int], + common_stride: int, + norm: Union[str, Callable], + train_size: Optional[Tuple], + loss_weight: float = 1.0, + loss_type: str = "cross_entropy", + ignore_value: int = -1, + num_classes: Optional[int] = None, + use_depthwise_separable_conv: bool = False, + ): + """ + NOTE: this interface is experimental. + + Args: + input_shape: shape of the input features. They will be ordered by stride + and the last one (with largest stride) is used as the input to the + decoder (i.e. the ASPP module); the rest are low-level feature for + the intermediate levels of decoder. + project_channels (list[int]): a list of low-level feature channels. + The length should be len(in_features) - 1. + aspp_dilations (list(int)): a list of 3 dilations in ASPP. + aspp_dropout (float): apply dropout on the output of ASPP. + decoder_channels (list[int]): a list of output channels of each + decoder stage. It should have the same length as "in_features" + (each element in "in_features" corresponds to one decoder stage). + common_stride (int): output stride of decoder. + norm (str or callable): normalization for all conv layers. + train_size (tuple): (height, width) of training images. + loss_weight (float): loss weight. + loss_type (str): type of loss function, 2 opptions: + (1) "cross_entropy" is the standard cross entropy loss. + (2) "hard_pixel_mining" is the loss in DeepLab that samples + top k% hardest pixels. + ignore_value (int): category to be ignored during training. + num_classes (int): number of classes, if set to None, the decoder + will not construct a predictor. + use_depthwise_separable_conv (bool): use DepthwiseSeparableConv2d + in ASPP and decoder. + """ + super().__init__() + input_shape = sorted(input_shape.items(), key=lambda x: x[1].stride) + + # fmt: off + self.in_features = [k for k, v in input_shape] # starting from "res2" to "res5" + in_channels = [x[1].channels for x in input_shape] + in_strides = [x[1].stride for x in input_shape] + aspp_channels = decoder_channels[-1] + self.ignore_value = ignore_value + self.common_stride = common_stride # output stride + self.loss_weight = loss_weight + self.loss_type = loss_type + self.decoder_only = num_classes is None + self.use_depthwise_separable_conv = use_depthwise_separable_conv + # fmt: on + + assert ( + len(project_channels) == len(self.in_features) - 1 + ), "Expected {} project_channels, got {}".format( + len(self.in_features) - 1, len(project_channels) + ) + assert len(decoder_channels) == len( + self.in_features + ), "Expected {} decoder_channels, got {}".format( + len(self.in_features), len(decoder_channels) + ) + self.decoder = nn.ModuleDict() + + use_bias = norm == "" + for idx, in_channel in enumerate(in_channels): + decoder_stage = nn.ModuleDict() + + if idx == len(self.in_features) - 1: + # ASPP module + if train_size is not None: + train_h, train_w = train_size + encoder_stride = in_strides[-1] + if train_h % encoder_stride or train_w % encoder_stride: + raise ValueError("Crop size need to be divisible by encoder stride.") + pool_h = train_h // encoder_stride + pool_w = train_w // encoder_stride + pool_kernel_size = (pool_h, pool_w) + else: + pool_kernel_size = None + project_conv = ASPP( + in_channel, + aspp_channels, + aspp_dilations, + norm=norm, + activation=F.relu, + pool_kernel_size=pool_kernel_size, + dropout=aspp_dropout, + use_depthwise_separable_conv=use_depthwise_separable_conv, + ) + fuse_conv = None + else: + project_conv = Conv2d( + in_channel, + project_channels[idx], + kernel_size=1, + bias=use_bias, + norm=get_norm(norm, project_channels[idx]), + activation=F.relu, + ) + weight_init.c2_xavier_fill(project_conv) + if use_depthwise_separable_conv: + # We use a single 5x5 DepthwiseSeparableConv2d to replace + # 2 3x3 Conv2d since they have the same receptive field, + # proposed in :paper:`Panoptic-DeepLab`. + fuse_conv = DepthwiseSeparableConv2d( + project_channels[idx] + decoder_channels[idx + 1], + decoder_channels[idx], + kernel_size=5, + padding=2, + norm1=norm, + activation1=F.relu, + norm2=norm, + activation2=F.relu, + ) + else: + fuse_conv = nn.Sequential( + Conv2d( + project_channels[idx] + decoder_channels[idx + 1], + decoder_channels[idx], + kernel_size=3, + padding=1, + bias=use_bias, + norm=get_norm(norm, decoder_channels[idx]), + activation=F.relu, + ), + Conv2d( + decoder_channels[idx], + decoder_channels[idx], + kernel_size=3, + padding=1, + bias=use_bias, + norm=get_norm(norm, decoder_channels[idx]), + activation=F.relu, + ), + ) + weight_init.c2_xavier_fill(fuse_conv[0]) + weight_init.c2_xavier_fill(fuse_conv[1]) + + decoder_stage["project_conv"] = project_conv + decoder_stage["fuse_conv"] = fuse_conv + + self.decoder[self.in_features[idx]] = decoder_stage + + if not self.decoder_only: + self.predictor = Conv2d( + decoder_channels[0], num_classes, kernel_size=1, stride=1, padding=0 + ) + nn.init.normal_(self.predictor.weight, 0, 0.001) + nn.init.constant_(self.predictor.bias, 0) + + if self.loss_type == "cross_entropy": + self.loss = nn.CrossEntropyLoss(reduction="mean", ignore_index=self.ignore_value) + elif self.loss_type == "hard_pixel_mining": + self.loss = DeepLabCE(ignore_label=self.ignore_value, top_k_percent_pixels=0.2) + else: + raise ValueError("Unexpected loss type: %s" % self.loss_type) + + @classmethod + def from_config(cls, cfg, input_shape): + if cfg.INPUT.CROP.ENABLED: + assert cfg.INPUT.CROP.TYPE == "absolute" + train_size = cfg.INPUT.CROP.SIZE + else: + train_size = None + decoder_channels = [cfg.MODEL.SEM_SEG_HEAD.CONVS_DIM] * ( + len(cfg.MODEL.SEM_SEG_HEAD.IN_FEATURES) - 1 + ) + [cfg.MODEL.SEM_SEG_HEAD.ASPP_CHANNELS] + ret = dict( + input_shape={ + k: v for k, v in input_shape.items() if k in cfg.MODEL.SEM_SEG_HEAD.IN_FEATURES + }, + project_channels=cfg.MODEL.SEM_SEG_HEAD.PROJECT_CHANNELS, + aspp_dilations=cfg.MODEL.SEM_SEG_HEAD.ASPP_DILATIONS, + aspp_dropout=cfg.MODEL.SEM_SEG_HEAD.ASPP_DROPOUT, + decoder_channels=decoder_channels, + common_stride=cfg.MODEL.SEM_SEG_HEAD.COMMON_STRIDE, + norm=cfg.MODEL.SEM_SEG_HEAD.NORM, + train_size=train_size, + loss_weight=cfg.MODEL.SEM_SEG_HEAD.LOSS_WEIGHT, + loss_type=cfg.MODEL.SEM_SEG_HEAD.LOSS_TYPE, + ignore_value=cfg.MODEL.SEM_SEG_HEAD.IGNORE_VALUE, + num_classes=cfg.MODEL.SEM_SEG_HEAD.NUM_CLASSES, + use_depthwise_separable_conv=cfg.MODEL.SEM_SEG_HEAD.USE_DEPTHWISE_SEPARABLE_CONV, + ) + return ret + + def forward(self, features, targets=None): + """ + Returns: + In training, returns (None, dict of losses) + In inference, returns (CxHxW logits, {}) + """ + y = self.layers(features) + if self.decoder_only: + # Output from self.layers() only contains decoder feature. + return y + if self.training: + return None, self.losses(y, targets) + else: + y = F.interpolate( + y, scale_factor=self.common_stride, mode="bilinear", align_corners=False + ) + return y, {} + + def layers(self, features): + # Reverse feature maps into top-down order (from low to high resolution) + for f in self.in_features[::-1]: + x = features[f] + proj_x = self.decoder[f]["project_conv"](x) + if self.decoder[f]["fuse_conv"] is None: + # This is aspp module + y = proj_x + else: + # Upsample y + y = F.interpolate(y, size=proj_x.size()[2:], mode="bilinear", align_corners=False) + y = torch.cat([proj_x, y], dim=1) + y = self.decoder[f]["fuse_conv"](y) + if not self.decoder_only: + y = self.predictor(y) + return y + + def losses(self, predictions, targets): + predictions = F.interpolate( + predictions, scale_factor=self.common_stride, mode="bilinear", align_corners=False + ) + loss = self.loss(predictions, targets) + losses = {"loss_sem_seg": loss * self.loss_weight} + return losses + + +@SEM_SEG_HEADS_REGISTRY.register() +class DeepLabV3Head(nn.Module): + """ + A semantic segmentation head described in :paper:`DeepLabV3`. + """ + + def __init__(self, cfg, input_shape: Dict[str, ShapeSpec]): + super().__init__() + + # fmt: off + self.in_features = cfg.MODEL.SEM_SEG_HEAD.IN_FEATURES + in_channels = [input_shape[f].channels for f in self.in_features] + aspp_channels = cfg.MODEL.SEM_SEG_HEAD.ASPP_CHANNELS + aspp_dilations = cfg.MODEL.SEM_SEG_HEAD.ASPP_DILATIONS + self.ignore_value = cfg.MODEL.SEM_SEG_HEAD.IGNORE_VALUE + num_classes = cfg.MODEL.SEM_SEG_HEAD.NUM_CLASSES + conv_dims = cfg.MODEL.SEM_SEG_HEAD.CONVS_DIM + self.common_stride = cfg.MODEL.SEM_SEG_HEAD.COMMON_STRIDE # output stride + norm = cfg.MODEL.SEM_SEG_HEAD.NORM + self.loss_weight = cfg.MODEL.SEM_SEG_HEAD.LOSS_WEIGHT + self.loss_type = cfg.MODEL.SEM_SEG_HEAD.LOSS_TYPE + train_crop_size = cfg.INPUT.CROP.SIZE + aspp_dropout = cfg.MODEL.SEM_SEG_HEAD.ASPP_DROPOUT + use_depthwise_separable_conv = cfg.MODEL.SEM_SEG_HEAD.USE_DEPTHWISE_SEPARABLE_CONV + # fmt: on + + assert len(self.in_features) == 1 + assert len(in_channels) == 1 + + # ASPP module + if cfg.INPUT.CROP.ENABLED: + assert cfg.INPUT.CROP.TYPE == "absolute" + train_crop_h, train_crop_w = train_crop_size + if train_crop_h % self.common_stride or train_crop_w % self.common_stride: + raise ValueError("Crop size need to be divisible by output stride.") + pool_h = train_crop_h // self.common_stride + pool_w = train_crop_w // self.common_stride + pool_kernel_size = (pool_h, pool_w) + else: + pool_kernel_size = None + self.aspp = ASPP( + in_channels[0], + aspp_channels, + aspp_dilations, + norm=norm, + activation=F.relu, + pool_kernel_size=pool_kernel_size, + dropout=aspp_dropout, + use_depthwise_separable_conv=use_depthwise_separable_conv, + ) + + self.predictor = Conv2d(conv_dims, num_classes, kernel_size=1, stride=1, padding=0) + nn.init.normal_(self.predictor.weight, 0, 0.001) + nn.init.constant_(self.predictor.bias, 0) + + if self.loss_type == "cross_entropy": + self.loss = nn.CrossEntropyLoss(reduction="mean", ignore_index=self.ignore_value) + elif self.loss_type == "hard_pixel_mining": + self.loss = DeepLabCE(ignore_label=self.ignore_value, top_k_percent_pixels=0.2) + else: + raise ValueError("Unexpected loss type: %s" % self.loss_type) + + def forward(self, features, targets=None): + """ + Returns: + In training, returns (None, dict of losses) + In inference, returns (CxHxW logits, {}) + """ + x = features[self.in_features[0]] + x = self.aspp(x) + x = self.predictor(x) + if self.training: + return None, self.losses(x, targets) + else: + x = F.interpolate( + x, scale_factor=self.common_stride, mode="bilinear", align_corners=False + ) + return x, {} + + def losses(self, predictions, targets): + predictions = F.interpolate( + predictions, scale_factor=self.common_stride, mode="bilinear", align_corners=False + ) + loss = self.loss(predictions, targets) + losses = {"loss_sem_seg": loss * self.loss_weight} + return losses diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/solver/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/solver/__init__.py new file mode 100644 index 00000000..7e36c64f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/solver/__init__.py @@ -0,0 +1,11 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from .build import build_lr_scheduler, build_optimizer, get_default_optimizer_params +from .lr_scheduler import ( + LRMultiplier, + LRScheduler, + WarmupCosineLR, + WarmupMultiStepLR, + WarmupParamScheduler, +) + +__all__ = [k for k in globals().keys() if not k.startswith("_")] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/solver/build.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/solver/build.py new file mode 100644 index 00000000..5e526df1 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/solver/build.py @@ -0,0 +1,310 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import copy +import itertools +import logging +from collections import defaultdict +from enum import Enum +from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Type, Union +import torch +from fvcore.common.param_scheduler import ( + CosineParamScheduler, + MultiStepParamScheduler, + StepWithFixedGammaParamScheduler, +) + +from annotator.oneformer.detectron2.config import CfgNode +from annotator.oneformer.detectron2.utils.env import TORCH_VERSION + +from .lr_scheduler import LRMultiplier, LRScheduler, WarmupParamScheduler + +_GradientClipperInput = Union[torch.Tensor, Iterable[torch.Tensor]] +_GradientClipper = Callable[[_GradientClipperInput], None] + + +class GradientClipType(Enum): + VALUE = "value" + NORM = "norm" + + +def _create_gradient_clipper(cfg: CfgNode) -> _GradientClipper: + """ + Creates gradient clipping closure to clip by value or by norm, + according to the provided config. + """ + cfg = copy.deepcopy(cfg) + + def clip_grad_norm(p: _GradientClipperInput): + torch.nn.utils.clip_grad_norm_(p, cfg.CLIP_VALUE, cfg.NORM_TYPE) + + def clip_grad_value(p: _GradientClipperInput): + torch.nn.utils.clip_grad_value_(p, cfg.CLIP_VALUE) + + _GRADIENT_CLIP_TYPE_TO_CLIPPER = { + GradientClipType.VALUE: clip_grad_value, + GradientClipType.NORM: clip_grad_norm, + } + return _GRADIENT_CLIP_TYPE_TO_CLIPPER[GradientClipType(cfg.CLIP_TYPE)] + + +def _generate_optimizer_class_with_gradient_clipping( + optimizer: Type[torch.optim.Optimizer], + *, + per_param_clipper: Optional[_GradientClipper] = None, + global_clipper: Optional[_GradientClipper] = None, +) -> Type[torch.optim.Optimizer]: + """ + Dynamically creates a new type that inherits the type of a given instance + and overrides the `step` method to add gradient clipping + """ + assert ( + per_param_clipper is None or global_clipper is None + ), "Not allowed to use both per-parameter clipping and global clipping" + + def optimizer_wgc_step(self, closure=None): + if per_param_clipper is not None: + for group in self.param_groups: + for p in group["params"]: + per_param_clipper(p) + else: + # global clipper for future use with detr + # (https://github.com/facebookresearch/detr/pull/287) + all_params = itertools.chain(*[g["params"] for g in self.param_groups]) + global_clipper(all_params) + super(type(self), self).step(closure) + + OptimizerWithGradientClip = type( + optimizer.__name__ + "WithGradientClip", + (optimizer,), + {"step": optimizer_wgc_step}, + ) + return OptimizerWithGradientClip + + +def maybe_add_gradient_clipping( + cfg: CfgNode, optimizer: Type[torch.optim.Optimizer] +) -> Type[torch.optim.Optimizer]: + """ + If gradient clipping is enabled through config options, wraps the existing + optimizer type to become a new dynamically created class OptimizerWithGradientClip + that inherits the given optimizer and overrides the `step` method to + include gradient clipping. + + Args: + cfg: CfgNode, configuration options + optimizer: type. A subclass of torch.optim.Optimizer + + Return: + type: either the input `optimizer` (if gradient clipping is disabled), or + a subclass of it with gradient clipping included in the `step` method. + """ + if not cfg.SOLVER.CLIP_GRADIENTS.ENABLED: + return optimizer + if isinstance(optimizer, torch.optim.Optimizer): + optimizer_type = type(optimizer) + else: + assert issubclass(optimizer, torch.optim.Optimizer), optimizer + optimizer_type = optimizer + + grad_clipper = _create_gradient_clipper(cfg.SOLVER.CLIP_GRADIENTS) + OptimizerWithGradientClip = _generate_optimizer_class_with_gradient_clipping( + optimizer_type, per_param_clipper=grad_clipper + ) + if isinstance(optimizer, torch.optim.Optimizer): + optimizer.__class__ = OptimizerWithGradientClip # a bit hacky, not recommended + return optimizer + else: + return OptimizerWithGradientClip + + +def build_optimizer(cfg: CfgNode, model: torch.nn.Module) -> torch.optim.Optimizer: + """ + Build an optimizer from config. + """ + params = get_default_optimizer_params( + model, + base_lr=cfg.SOLVER.BASE_LR, + weight_decay_norm=cfg.SOLVER.WEIGHT_DECAY_NORM, + bias_lr_factor=cfg.SOLVER.BIAS_LR_FACTOR, + weight_decay_bias=cfg.SOLVER.WEIGHT_DECAY_BIAS, + ) + sgd_args = { + "params": params, + "lr": cfg.SOLVER.BASE_LR, + "momentum": cfg.SOLVER.MOMENTUM, + "nesterov": cfg.SOLVER.NESTEROV, + "weight_decay": cfg.SOLVER.WEIGHT_DECAY, + } + if TORCH_VERSION >= (1, 12): + sgd_args["foreach"] = True + return maybe_add_gradient_clipping(cfg, torch.optim.SGD(**sgd_args)) + + +def get_default_optimizer_params( + model: torch.nn.Module, + base_lr: Optional[float] = None, + weight_decay: Optional[float] = None, + weight_decay_norm: Optional[float] = None, + bias_lr_factor: Optional[float] = 1.0, + weight_decay_bias: Optional[float] = None, + lr_factor_func: Optional[Callable] = None, + overrides: Optional[Dict[str, Dict[str, float]]] = None, +) -> List[Dict[str, Any]]: + """ + Get default param list for optimizer, with support for a few types of + overrides. If no overrides needed, this is equivalent to `model.parameters()`. + + Args: + base_lr: lr for every group by default. Can be omitted to use the one in optimizer. + weight_decay: weight decay for every group by default. Can be omitted to use the one + in optimizer. + weight_decay_norm: override weight decay for params in normalization layers + bias_lr_factor: multiplier of lr for bias parameters. + weight_decay_bias: override weight decay for bias parameters. + lr_factor_func: function to calculate lr decay rate by mapping the parameter names to + corresponding lr decay rate. Note that setting this option requires + also setting ``base_lr``. + overrides: if not `None`, provides values for optimizer hyperparameters + (LR, weight decay) for module parameters with a given name; e.g. + ``{"embedding": {"lr": 0.01, "weight_decay": 0.1}}`` will set the LR and + weight decay values for all module parameters named `embedding`. + + For common detection models, ``weight_decay_norm`` is the only option + needed to be set. ``bias_lr_factor,weight_decay_bias`` are legacy settings + from Detectron1 that are not found useful. + + Example: + :: + torch.optim.SGD(get_default_optimizer_params(model, weight_decay_norm=0), + lr=0.01, weight_decay=1e-4, momentum=0.9) + """ + if overrides is None: + overrides = {} + defaults = {} + if base_lr is not None: + defaults["lr"] = base_lr + if weight_decay is not None: + defaults["weight_decay"] = weight_decay + bias_overrides = {} + if bias_lr_factor is not None and bias_lr_factor != 1.0: + # NOTE: unlike Detectron v1, we now by default make bias hyperparameters + # exactly the same as regular weights. + if base_lr is None: + raise ValueError("bias_lr_factor requires base_lr") + bias_overrides["lr"] = base_lr * bias_lr_factor + if weight_decay_bias is not None: + bias_overrides["weight_decay"] = weight_decay_bias + if len(bias_overrides): + if "bias" in overrides: + raise ValueError("Conflicting overrides for 'bias'") + overrides["bias"] = bias_overrides + if lr_factor_func is not None: + if base_lr is None: + raise ValueError("lr_factor_func requires base_lr") + norm_module_types = ( + torch.nn.BatchNorm1d, + torch.nn.BatchNorm2d, + torch.nn.BatchNorm3d, + torch.nn.SyncBatchNorm, + # NaiveSyncBatchNorm inherits from BatchNorm2d + torch.nn.GroupNorm, + torch.nn.InstanceNorm1d, + torch.nn.InstanceNorm2d, + torch.nn.InstanceNorm3d, + torch.nn.LayerNorm, + torch.nn.LocalResponseNorm, + ) + params: List[Dict[str, Any]] = [] + memo: Set[torch.nn.parameter.Parameter] = set() + for module_name, module in model.named_modules(): + for module_param_name, value in module.named_parameters(recurse=False): + if not value.requires_grad: + continue + # Avoid duplicating parameters + if value in memo: + continue + memo.add(value) + + hyperparams = copy.copy(defaults) + if isinstance(module, norm_module_types) and weight_decay_norm is not None: + hyperparams["weight_decay"] = weight_decay_norm + if lr_factor_func is not None: + hyperparams["lr"] *= lr_factor_func(f"{module_name}.{module_param_name}") + + hyperparams.update(overrides.get(module_param_name, {})) + params.append({"params": [value], **hyperparams}) + return reduce_param_groups(params) + + +def _expand_param_groups(params: List[Dict[str, Any]]) -> List[Dict[str, Any]]: + # Transform parameter groups into per-parameter structure. + # Later items in `params` can overwrite parameters set in previous items. + ret = defaultdict(dict) + for item in params: + assert "params" in item + cur_params = {x: y for x, y in item.items() if x != "params"} + for param in item["params"]: + ret[param].update({"params": [param], **cur_params}) + return list(ret.values()) + + +def reduce_param_groups(params: List[Dict[str, Any]]) -> List[Dict[str, Any]]: + # Reorganize the parameter groups and merge duplicated groups. + # The number of parameter groups needs to be as small as possible in order + # to efficiently use the PyTorch multi-tensor optimizer. Therefore instead + # of using a parameter_group per single parameter, we reorganize the + # parameter groups and merge duplicated groups. This approach speeds + # up multi-tensor optimizer significantly. + params = _expand_param_groups(params) + groups = defaultdict(list) # re-group all parameter groups by their hyperparams + for item in params: + cur_params = tuple((x, y) for x, y in item.items() if x != "params") + groups[cur_params].extend(item["params"]) + ret = [] + for param_keys, param_values in groups.items(): + cur = {kv[0]: kv[1] for kv in param_keys} + cur["params"] = param_values + ret.append(cur) + return ret + + +def build_lr_scheduler(cfg: CfgNode, optimizer: torch.optim.Optimizer) -> LRScheduler: + """ + Build a LR scheduler from config. + """ + name = cfg.SOLVER.LR_SCHEDULER_NAME + + if name == "WarmupMultiStepLR": + steps = [x for x in cfg.SOLVER.STEPS if x <= cfg.SOLVER.MAX_ITER] + if len(steps) != len(cfg.SOLVER.STEPS): + logger = logging.getLogger(__name__) + logger.warning( + "SOLVER.STEPS contains values larger than SOLVER.MAX_ITER. " + "These values will be ignored." + ) + sched = MultiStepParamScheduler( + values=[cfg.SOLVER.GAMMA**k for k in range(len(steps) + 1)], + milestones=steps, + num_updates=cfg.SOLVER.MAX_ITER, + ) + elif name == "WarmupCosineLR": + end_value = cfg.SOLVER.BASE_LR_END / cfg.SOLVER.BASE_LR + assert end_value >= 0.0 and end_value <= 1.0, end_value + sched = CosineParamScheduler(1, end_value) + elif name == "WarmupStepWithFixedGammaLR": + sched = StepWithFixedGammaParamScheduler( + base_value=1.0, + gamma=cfg.SOLVER.GAMMA, + num_decays=cfg.SOLVER.NUM_DECAYS, + num_updates=cfg.SOLVER.MAX_ITER, + ) + else: + raise ValueError("Unknown LR scheduler: {}".format(name)) + + sched = WarmupParamScheduler( + sched, + cfg.SOLVER.WARMUP_FACTOR, + min(cfg.SOLVER.WARMUP_ITERS / cfg.SOLVER.MAX_ITER, 1.0), + cfg.SOLVER.WARMUP_METHOD, + cfg.SOLVER.RESCALE_INTERVAL, + ) + return LRMultiplier(optimizer, multiplier=sched, max_iter=cfg.SOLVER.MAX_ITER) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/solver/lr_scheduler.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/solver/lr_scheduler.py new file mode 100644 index 00000000..d6aed2bb --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/solver/lr_scheduler.py @@ -0,0 +1,246 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import logging +import math +from bisect import bisect_right +from typing import List +import torch +from fvcore.common.param_scheduler import ( + CompositeParamScheduler, + ConstantParamScheduler, + LinearParamScheduler, + ParamScheduler, +) + +try: + from torch.optim.lr_scheduler import LRScheduler +except ImportError: + from torch.optim.lr_scheduler import _LRScheduler as LRScheduler + +logger = logging.getLogger(__name__) + + +class WarmupParamScheduler(CompositeParamScheduler): + """ + Add an initial warmup stage to another scheduler. + """ + + def __init__( + self, + scheduler: ParamScheduler, + warmup_factor: float, + warmup_length: float, + warmup_method: str = "linear", + rescale_interval: bool = False, + ): + """ + Args: + scheduler: warmup will be added at the beginning of this scheduler + warmup_factor: the factor w.r.t the initial value of ``scheduler``, e.g. 0.001 + warmup_length: the relative length (in [0, 1]) of warmup steps w.r.t the entire + training, e.g. 0.01 + warmup_method: one of "linear" or "constant" + rescale_interval: whether we will rescale the interval of the scheduler after + warmup + """ + end_value = scheduler(warmup_length) # the value to reach when warmup ends + start_value = warmup_factor * scheduler(0.0) + if warmup_method == "constant": + warmup = ConstantParamScheduler(start_value) + elif warmup_method == "linear": + warmup = LinearParamScheduler(start_value, end_value) + else: + raise ValueError("Unknown warmup method: {}".format(warmup_method)) + super().__init__( + [warmup, scheduler], + interval_scaling=["rescaled", "rescaled" if rescale_interval else "fixed"], + lengths=[warmup_length, 1 - warmup_length], + ) + + +class LRMultiplier(LRScheduler): + """ + A LRScheduler which uses fvcore :class:`ParamScheduler` to multiply the + learning rate of each param in the optimizer. + Every step, the learning rate of each parameter becomes its initial value + multiplied by the output of the given :class:`ParamScheduler`. + + The absolute learning rate value of each parameter can be different. + This scheduler can be used as long as the relative scale among them do + not change during training. + + Examples: + :: + LRMultiplier( + opt, + WarmupParamScheduler( + MultiStepParamScheduler( + [1, 0.1, 0.01], + milestones=[60000, 80000], + num_updates=90000, + ), 0.001, 100 / 90000 + ), + max_iter=90000 + ) + """ + + # NOTES: in the most general case, every LR can use its own scheduler. + # Supporting this requires interaction with the optimizer when its parameter + # group is initialized. For example, classyvision implements its own optimizer + # that allows different schedulers for every parameter group. + # To avoid this complexity, we use this class to support the most common cases + # where the relative scale among all LRs stay unchanged during training. In this + # case we only need a total of one scheduler that defines the relative LR multiplier. + + def __init__( + self, + optimizer: torch.optim.Optimizer, + multiplier: ParamScheduler, + max_iter: int, + last_iter: int = -1, + ): + """ + Args: + optimizer, last_iter: See ``torch.optim.lr_scheduler.LRScheduler``. + ``last_iter`` is the same as ``last_epoch``. + multiplier: a fvcore ParamScheduler that defines the multiplier on + every LR of the optimizer + max_iter: the total number of training iterations + """ + if not isinstance(multiplier, ParamScheduler): + raise ValueError( + "_LRMultiplier(multiplier=) must be an instance of fvcore " + f"ParamScheduler. Got {multiplier} instead." + ) + self._multiplier = multiplier + self._max_iter = max_iter + super().__init__(optimizer, last_epoch=last_iter) + + def state_dict(self): + # fvcore schedulers are stateless. Only keep pytorch scheduler states + return {"base_lrs": self.base_lrs, "last_epoch": self.last_epoch} + + def get_lr(self) -> List[float]: + multiplier = self._multiplier(self.last_epoch / self._max_iter) + return [base_lr * multiplier for base_lr in self.base_lrs] + + +""" +Content below is no longer needed! +""" + +# NOTE: PyTorch's LR scheduler interface uses names that assume the LR changes +# only on epoch boundaries. We typically use iteration based schedules instead. +# As a result, "epoch" (e.g., as in self.last_epoch) should be understood to mean +# "iteration" instead. + +# FIXME: ideally this would be achieved with a CombinedLRScheduler, separating +# MultiStepLR with WarmupLR but the current LRScheduler design doesn't allow it. + + +class WarmupMultiStepLR(LRScheduler): + def __init__( + self, + optimizer: torch.optim.Optimizer, + milestones: List[int], + gamma: float = 0.1, + warmup_factor: float = 0.001, + warmup_iters: int = 1000, + warmup_method: str = "linear", + last_epoch: int = -1, + ): + logger.warning( + "WarmupMultiStepLR is deprecated! Use LRMultipilier with fvcore ParamScheduler instead!" + ) + if not list(milestones) == sorted(milestones): + raise ValueError( + "Milestones should be a list of" " increasing integers. Got {}", milestones + ) + self.milestones = milestones + self.gamma = gamma + self.warmup_factor = warmup_factor + self.warmup_iters = warmup_iters + self.warmup_method = warmup_method + super().__init__(optimizer, last_epoch) + + def get_lr(self) -> List[float]: + warmup_factor = _get_warmup_factor_at_iter( + self.warmup_method, self.last_epoch, self.warmup_iters, self.warmup_factor + ) + return [ + base_lr * warmup_factor * self.gamma ** bisect_right(self.milestones, self.last_epoch) + for base_lr in self.base_lrs + ] + + def _compute_values(self) -> List[float]: + # The new interface + return self.get_lr() + + +class WarmupCosineLR(LRScheduler): + def __init__( + self, + optimizer: torch.optim.Optimizer, + max_iters: int, + warmup_factor: float = 0.001, + warmup_iters: int = 1000, + warmup_method: str = "linear", + last_epoch: int = -1, + ): + logger.warning( + "WarmupCosineLR is deprecated! Use LRMultipilier with fvcore ParamScheduler instead!" + ) + self.max_iters = max_iters + self.warmup_factor = warmup_factor + self.warmup_iters = warmup_iters + self.warmup_method = warmup_method + super().__init__(optimizer, last_epoch) + + def get_lr(self) -> List[float]: + warmup_factor = _get_warmup_factor_at_iter( + self.warmup_method, self.last_epoch, self.warmup_iters, self.warmup_factor + ) + # Different definitions of half-cosine with warmup are possible. For + # simplicity we multiply the standard half-cosine schedule by the warmup + # factor. An alternative is to start the period of the cosine at warmup_iters + # instead of at 0. In the case that warmup_iters << max_iters the two are + # very close to each other. + return [ + base_lr + * warmup_factor + * 0.5 + * (1.0 + math.cos(math.pi * self.last_epoch / self.max_iters)) + for base_lr in self.base_lrs + ] + + def _compute_values(self) -> List[float]: + # The new interface + return self.get_lr() + + +def _get_warmup_factor_at_iter( + method: str, iter: int, warmup_iters: int, warmup_factor: float +) -> float: + """ + Return the learning rate warmup factor at a specific iteration. + See :paper:`ImageNet in 1h` for more details. + + Args: + method (str): warmup method; either "constant" or "linear". + iter (int): iteration at which to calculate the warmup factor. + warmup_iters (int): the number of warmup iterations. + warmup_factor (float): the base warmup factor (the meaning changes according + to the method used). + + Returns: + float: the effective warmup factor at the given iteration. + """ + if iter >= warmup_iters: + return 1.0 + + if method == "constant": + return warmup_factor + elif method == "linear": + alpha = iter / warmup_iters + return warmup_factor * (1 - alpha) + alpha + else: + raise ValueError("Unknown warmup method: {}".format(method)) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/__init__.py new file mode 100644 index 00000000..c2942fc5 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/__init__.py @@ -0,0 +1,17 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from .boxes import Boxes, BoxMode, pairwise_iou, pairwise_ioa, pairwise_point_box_distance +from .image_list import ImageList + +from .instances import Instances +from .keypoints import Keypoints, heatmaps_to_keypoints +from .masks import BitMasks, PolygonMasks, polygons_to_bitmask, ROIMasks +from .rotated_boxes import RotatedBoxes +from .rotated_boxes import pairwise_iou as pairwise_iou_rotated + +__all__ = [k for k in globals().keys() if not k.startswith("_")] + + +from annotator.oneformer.detectron2.utils.env import fixup_module_metadata + +fixup_module_metadata(__name__, globals(), __all__) +del fixup_module_metadata diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/boxes.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/boxes.py new file mode 100644 index 00000000..fd396f68 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/boxes.py @@ -0,0 +1,425 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import math +import numpy as np +from enum import IntEnum, unique +from typing import List, Tuple, Union +import torch +from torch import device + +_RawBoxType = Union[List[float], Tuple[float, ...], torch.Tensor, np.ndarray] + + +@unique +class BoxMode(IntEnum): + """ + Enum of different ways to represent a box. + """ + + XYXY_ABS = 0 + """ + (x0, y0, x1, y1) in absolute floating points coordinates. + The coordinates in range [0, width or height]. + """ + XYWH_ABS = 1 + """ + (x0, y0, w, h) in absolute floating points coordinates. + """ + XYXY_REL = 2 + """ + Not yet supported! + (x0, y0, x1, y1) in range [0, 1]. They are relative to the size of the image. + """ + XYWH_REL = 3 + """ + Not yet supported! + (x0, y0, w, h) in range [0, 1]. They are relative to the size of the image. + """ + XYWHA_ABS = 4 + """ + (xc, yc, w, h, a) in absolute floating points coordinates. + (xc, yc) is the center of the rotated box, and the angle a is in degrees ccw. + """ + + @staticmethod + def convert(box: _RawBoxType, from_mode: "BoxMode", to_mode: "BoxMode") -> _RawBoxType: + """ + Args: + box: can be a k-tuple, k-list or an Nxk array/tensor, where k = 4 or 5 + from_mode, to_mode (BoxMode) + + Returns: + The converted box of the same type. + """ + if from_mode == to_mode: + return box + + original_type = type(box) + is_numpy = isinstance(box, np.ndarray) + single_box = isinstance(box, (list, tuple)) + if single_box: + assert len(box) == 4 or len(box) == 5, ( + "BoxMode.convert takes either a k-tuple/list or an Nxk array/tensor," + " where k == 4 or 5" + ) + arr = torch.tensor(box)[None, :] + else: + # avoid modifying the input box + if is_numpy: + arr = torch.from_numpy(np.asarray(box)).clone() + else: + arr = box.clone() + + assert to_mode not in [BoxMode.XYXY_REL, BoxMode.XYWH_REL] and from_mode not in [ + BoxMode.XYXY_REL, + BoxMode.XYWH_REL, + ], "Relative mode not yet supported!" + + if from_mode == BoxMode.XYWHA_ABS and to_mode == BoxMode.XYXY_ABS: + assert ( + arr.shape[-1] == 5 + ), "The last dimension of input shape must be 5 for XYWHA format" + original_dtype = arr.dtype + arr = arr.double() + + w = arr[:, 2] + h = arr[:, 3] + a = arr[:, 4] + c = torch.abs(torch.cos(a * math.pi / 180.0)) + s = torch.abs(torch.sin(a * math.pi / 180.0)) + # This basically computes the horizontal bounding rectangle of the rotated box + new_w = c * w + s * h + new_h = c * h + s * w + + # convert center to top-left corner + arr[:, 0] -= new_w / 2.0 + arr[:, 1] -= new_h / 2.0 + # bottom-right corner + arr[:, 2] = arr[:, 0] + new_w + arr[:, 3] = arr[:, 1] + new_h + + arr = arr[:, :4].to(dtype=original_dtype) + elif from_mode == BoxMode.XYWH_ABS and to_mode == BoxMode.XYWHA_ABS: + original_dtype = arr.dtype + arr = arr.double() + arr[:, 0] += arr[:, 2] / 2.0 + arr[:, 1] += arr[:, 3] / 2.0 + angles = torch.zeros((arr.shape[0], 1), dtype=arr.dtype) + arr = torch.cat((arr, angles), axis=1).to(dtype=original_dtype) + else: + if to_mode == BoxMode.XYXY_ABS and from_mode == BoxMode.XYWH_ABS: + arr[:, 2] += arr[:, 0] + arr[:, 3] += arr[:, 1] + elif from_mode == BoxMode.XYXY_ABS and to_mode == BoxMode.XYWH_ABS: + arr[:, 2] -= arr[:, 0] + arr[:, 3] -= arr[:, 1] + else: + raise NotImplementedError( + "Conversion from BoxMode {} to {} is not supported yet".format( + from_mode, to_mode + ) + ) + + if single_box: + return original_type(arr.flatten().tolist()) + if is_numpy: + return arr.numpy() + else: + return arr + + +class Boxes: + """ + This structure stores a list of boxes as a Nx4 torch.Tensor. + It supports some common methods about boxes + (`area`, `clip`, `nonempty`, etc), + and also behaves like a Tensor + (support indexing, `to(device)`, `.device`, and iteration over all boxes) + + Attributes: + tensor (torch.Tensor): float matrix of Nx4. Each row is (x1, y1, x2, y2). + """ + + def __init__(self, tensor: torch.Tensor): + """ + Args: + tensor (Tensor[float]): a Nx4 matrix. Each row is (x1, y1, x2, y2). + """ + if not isinstance(tensor, torch.Tensor): + tensor = torch.as_tensor(tensor, dtype=torch.float32, device=torch.device("cpu")) + else: + tensor = tensor.to(torch.float32) + if tensor.numel() == 0: + # Use reshape, so we don't end up creating a new tensor that does not depend on + # the inputs (and consequently confuses jit) + tensor = tensor.reshape((-1, 4)).to(dtype=torch.float32) + assert tensor.dim() == 2 and tensor.size(-1) == 4, tensor.size() + + self.tensor = tensor + + def clone(self) -> "Boxes": + """ + Clone the Boxes. + + Returns: + Boxes + """ + return Boxes(self.tensor.clone()) + + def to(self, device: torch.device): + # Boxes are assumed float32 and does not support to(dtype) + return Boxes(self.tensor.to(device=device)) + + def area(self) -> torch.Tensor: + """ + Computes the area of all the boxes. + + Returns: + torch.Tensor: a vector with areas of each box. + """ + box = self.tensor + area = (box[:, 2] - box[:, 0]) * (box[:, 3] - box[:, 1]) + return area + + def clip(self, box_size: Tuple[int, int]) -> None: + """ + Clip (in place) the boxes by limiting x coordinates to the range [0, width] + and y coordinates to the range [0, height]. + + Args: + box_size (height, width): The clipping box's size. + """ + assert torch.isfinite(self.tensor).all(), "Box tensor contains infinite or NaN!" + h, w = box_size + x1 = self.tensor[:, 0].clamp(min=0, max=w) + y1 = self.tensor[:, 1].clamp(min=0, max=h) + x2 = self.tensor[:, 2].clamp(min=0, max=w) + y2 = self.tensor[:, 3].clamp(min=0, max=h) + self.tensor = torch.stack((x1, y1, x2, y2), dim=-1) + + def nonempty(self, threshold: float = 0.0) -> torch.Tensor: + """ + Find boxes that are non-empty. + A box is considered empty, if either of its side is no larger than threshold. + + Returns: + Tensor: + a binary vector which represents whether each box is empty + (False) or non-empty (True). + """ + box = self.tensor + widths = box[:, 2] - box[:, 0] + heights = box[:, 3] - box[:, 1] + keep = (widths > threshold) & (heights > threshold) + return keep + + def __getitem__(self, item) -> "Boxes": + """ + Args: + item: int, slice, or a BoolTensor + + Returns: + Boxes: Create a new :class:`Boxes` by indexing. + + The following usage are allowed: + + 1. `new_boxes = boxes[3]`: return a `Boxes` which contains only one box. + 2. `new_boxes = boxes[2:10]`: return a slice of boxes. + 3. `new_boxes = boxes[vector]`, where vector is a torch.BoolTensor + with `length = len(boxes)`. Nonzero elements in the vector will be selected. + + Note that the returned Boxes might share storage with this Boxes, + subject to Pytorch's indexing semantics. + """ + if isinstance(item, int): + return Boxes(self.tensor[item].view(1, -1)) + b = self.tensor[item] + assert b.dim() == 2, "Indexing on Boxes with {} failed to return a matrix!".format(item) + return Boxes(b) + + def __len__(self) -> int: + return self.tensor.shape[0] + + def __repr__(self) -> str: + return "Boxes(" + str(self.tensor) + ")" + + def inside_box(self, box_size: Tuple[int, int], boundary_threshold: int = 0) -> torch.Tensor: + """ + Args: + box_size (height, width): Size of the reference box. + boundary_threshold (int): Boxes that extend beyond the reference box + boundary by more than boundary_threshold are considered "outside". + + Returns: + a binary vector, indicating whether each box is inside the reference box. + """ + height, width = box_size + inds_inside = ( + (self.tensor[..., 0] >= -boundary_threshold) + & (self.tensor[..., 1] >= -boundary_threshold) + & (self.tensor[..., 2] < width + boundary_threshold) + & (self.tensor[..., 3] < height + boundary_threshold) + ) + return inds_inside + + def get_centers(self) -> torch.Tensor: + """ + Returns: + The box centers in a Nx2 array of (x, y). + """ + return (self.tensor[:, :2] + self.tensor[:, 2:]) / 2 + + def scale(self, scale_x: float, scale_y: float) -> None: + """ + Scale the box with horizontal and vertical scaling factors + """ + self.tensor[:, 0::2] *= scale_x + self.tensor[:, 1::2] *= scale_y + + @classmethod + def cat(cls, boxes_list: List["Boxes"]) -> "Boxes": + """ + Concatenates a list of Boxes into a single Boxes + + Arguments: + boxes_list (list[Boxes]) + + Returns: + Boxes: the concatenated Boxes + """ + assert isinstance(boxes_list, (list, tuple)) + if len(boxes_list) == 0: + return cls(torch.empty(0)) + assert all([isinstance(box, Boxes) for box in boxes_list]) + + # use torch.cat (v.s. layers.cat) so the returned boxes never share storage with input + cat_boxes = cls(torch.cat([b.tensor for b in boxes_list], dim=0)) + return cat_boxes + + @property + def device(self) -> device: + return self.tensor.device + + # type "Iterator[torch.Tensor]", yield, and iter() not supported by torchscript + # https://github.com/pytorch/pytorch/issues/18627 + @torch.jit.unused + def __iter__(self): + """ + Yield a box as a Tensor of shape (4,) at a time. + """ + yield from self.tensor + + +def pairwise_intersection(boxes1: Boxes, boxes2: Boxes) -> torch.Tensor: + """ + Given two lists of boxes of size N and M, + compute the intersection area between __all__ N x M pairs of boxes. + The box order must be (xmin, ymin, xmax, ymax) + + Args: + boxes1,boxes2 (Boxes): two `Boxes`. Contains N & M boxes, respectively. + + Returns: + Tensor: intersection, sized [N,M]. + """ + boxes1, boxes2 = boxes1.tensor, boxes2.tensor + width_height = torch.min(boxes1[:, None, 2:], boxes2[:, 2:]) - torch.max( + boxes1[:, None, :2], boxes2[:, :2] + ) # [N,M,2] + + width_height.clamp_(min=0) # [N,M,2] + intersection = width_height.prod(dim=2) # [N,M] + return intersection + + +# implementation from https://github.com/kuangliu/torchcv/blob/master/torchcv/utils/box.py +# with slight modifications +def pairwise_iou(boxes1: Boxes, boxes2: Boxes) -> torch.Tensor: + """ + Given two lists of boxes of size N and M, compute the IoU + (intersection over union) between **all** N x M pairs of boxes. + The box order must be (xmin, ymin, xmax, ymax). + + Args: + boxes1,boxes2 (Boxes): two `Boxes`. Contains N & M boxes, respectively. + + Returns: + Tensor: IoU, sized [N,M]. + """ + area1 = boxes1.area() # [N] + area2 = boxes2.area() # [M] + inter = pairwise_intersection(boxes1, boxes2) + + # handle empty boxes + iou = torch.where( + inter > 0, + inter / (area1[:, None] + area2 - inter), + torch.zeros(1, dtype=inter.dtype, device=inter.device), + ) + return iou + + +def pairwise_ioa(boxes1: Boxes, boxes2: Boxes) -> torch.Tensor: + """ + Similar to :func:`pariwise_iou` but compute the IoA (intersection over boxes2 area). + + Args: + boxes1,boxes2 (Boxes): two `Boxes`. Contains N & M boxes, respectively. + + Returns: + Tensor: IoA, sized [N,M]. + """ + area2 = boxes2.area() # [M] + inter = pairwise_intersection(boxes1, boxes2) + + # handle empty boxes + ioa = torch.where( + inter > 0, inter / area2, torch.zeros(1, dtype=inter.dtype, device=inter.device) + ) + return ioa + + +def pairwise_point_box_distance(points: torch.Tensor, boxes: Boxes): + """ + Pairwise distance between N points and M boxes. The distance between a + point and a box is represented by the distance from the point to 4 edges + of the box. Distances are all positive when the point is inside the box. + + Args: + points: Nx2 coordinates. Each row is (x, y) + boxes: M boxes + + Returns: + Tensor: distances of size (N, M, 4). The 4 values are distances from + the point to the left, top, right, bottom of the box. + """ + x, y = points.unsqueeze(dim=2).unbind(dim=1) # (N, 1) + x0, y0, x1, y1 = boxes.tensor.unsqueeze(dim=0).unbind(dim=2) # (1, M) + return torch.stack([x - x0, y - y0, x1 - x, y1 - y], dim=2) + + +def matched_pairwise_iou(boxes1: Boxes, boxes2: Boxes) -> torch.Tensor: + """ + Compute pairwise intersection over union (IOU) of two sets of matched + boxes that have the same number of boxes. + Similar to :func:`pairwise_iou`, but computes only diagonal elements of the matrix. + + Args: + boxes1 (Boxes): bounding boxes, sized [N,4]. + boxes2 (Boxes): same length as boxes1 + Returns: + Tensor: iou, sized [N]. + """ + assert len(boxes1) == len( + boxes2 + ), "boxlists should have the same" "number of entries, got {}, {}".format( + len(boxes1), len(boxes2) + ) + area1 = boxes1.area() # [N] + area2 = boxes2.area() # [N] + box1, box2 = boxes1.tensor, boxes2.tensor + lt = torch.max(box1[:, :2], box2[:, :2]) # [N,2] + rb = torch.min(box1[:, 2:], box2[:, 2:]) # [N,2] + wh = (rb - lt).clamp(min=0) # [N,2] + inter = wh[:, 0] * wh[:, 1] # [N] + iou = inter / (area1 + area2 - inter) # [N] + return iou diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/image_list.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/image_list.py new file mode 100644 index 00000000..86c8b951 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/image_list.py @@ -0,0 +1,129 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from __future__ import division +from typing import Any, Dict, List, Optional, Tuple +import torch +from torch import device +from torch.nn import functional as F + +from annotator.oneformer.detectron2.layers.wrappers import move_device_like, shapes_to_tensor + + +class ImageList(object): + """ + Structure that holds a list of images (of possibly + varying sizes) as a single tensor. + This works by padding the images to the same size. + The original sizes of each image is stored in `image_sizes`. + + Attributes: + image_sizes (list[tuple[int, int]]): each tuple is (h, w). + During tracing, it becomes list[Tensor] instead. + """ + + def __init__(self, tensor: torch.Tensor, image_sizes: List[Tuple[int, int]]): + """ + Arguments: + tensor (Tensor): of shape (N, H, W) or (N, C_1, ..., C_K, H, W) where K >= 1 + image_sizes (list[tuple[int, int]]): Each tuple is (h, w). It can + be smaller than (H, W) due to padding. + """ + self.tensor = tensor + self.image_sizes = image_sizes + + def __len__(self) -> int: + return len(self.image_sizes) + + def __getitem__(self, idx) -> torch.Tensor: + """ + Access the individual image in its original size. + + Args: + idx: int or slice + + Returns: + Tensor: an image of shape (H, W) or (C_1, ..., C_K, H, W) where K >= 1 + """ + size = self.image_sizes[idx] + return self.tensor[idx, ..., : size[0], : size[1]] + + @torch.jit.unused + def to(self, *args: Any, **kwargs: Any) -> "ImageList": + cast_tensor = self.tensor.to(*args, **kwargs) + return ImageList(cast_tensor, self.image_sizes) + + @property + def device(self) -> device: + return self.tensor.device + + @staticmethod + def from_tensors( + tensors: List[torch.Tensor], + size_divisibility: int = 0, + pad_value: float = 0.0, + padding_constraints: Optional[Dict[str, int]] = None, + ) -> "ImageList": + """ + Args: + tensors: a tuple or list of `torch.Tensor`, each of shape (Hi, Wi) or + (C_1, ..., C_K, Hi, Wi) where K >= 1. The Tensors will be padded + to the same shape with `pad_value`. + size_divisibility (int): If `size_divisibility > 0`, add padding to ensure + the common height and width is divisible by `size_divisibility`. + This depends on the model and many models need a divisibility of 32. + pad_value (float): value to pad. + padding_constraints (optional[Dict]): If given, it would follow the format as + {"size_divisibility": int, "square_size": int}, where `size_divisibility` will + overwrite the above one if presented and `square_size` indicates the + square padding size if `square_size` > 0. + Returns: + an `ImageList`. + """ + assert len(tensors) > 0 + assert isinstance(tensors, (tuple, list)) + for t in tensors: + assert isinstance(t, torch.Tensor), type(t) + assert t.shape[:-2] == tensors[0].shape[:-2], t.shape + + image_sizes = [(im.shape[-2], im.shape[-1]) for im in tensors] + image_sizes_tensor = [shapes_to_tensor(x) for x in image_sizes] + max_size = torch.stack(image_sizes_tensor).max(0).values + + if padding_constraints is not None: + square_size = padding_constraints.get("square_size", 0) + if square_size > 0: + # pad to square. + max_size[0] = max_size[1] = square_size + if "size_divisibility" in padding_constraints: + size_divisibility = padding_constraints["size_divisibility"] + if size_divisibility > 1: + stride = size_divisibility + # the last two dims are H,W, both subject to divisibility requirement + max_size = (max_size + (stride - 1)).div(stride, rounding_mode="floor") * stride + + # handle weirdness of scripting and tracing ... + if torch.jit.is_scripting(): + max_size: List[int] = max_size.to(dtype=torch.long).tolist() + else: + if torch.jit.is_tracing(): + image_sizes = image_sizes_tensor + + if len(tensors) == 1: + # This seems slightly (2%) faster. + # TODO: check whether it's faster for multiple images as well + image_size = image_sizes[0] + padding_size = [0, max_size[-1] - image_size[1], 0, max_size[-2] - image_size[0]] + batched_imgs = F.pad(tensors[0], padding_size, value=pad_value).unsqueeze_(0) + else: + # max_size can be a tensor in tracing mode, therefore convert to list + batch_shape = [len(tensors)] + list(tensors[0].shape[:-2]) + list(max_size) + device = ( + None if torch.jit.is_scripting() else ("cpu" if torch.jit.is_tracing() else None) + ) + batched_imgs = tensors[0].new_full(batch_shape, pad_value, device=device) + batched_imgs = move_device_like(batched_imgs, tensors[0]) + for i, img in enumerate(tensors): + # Use `batched_imgs` directly instead of `img, pad_img = zip(tensors, batched_imgs)` + # Tracing mode cannot capture `copy_()` of temporary locals + batched_imgs[i, ..., : img.shape[-2], : img.shape[-1]].copy_(img) + + return ImageList(batched_imgs.contiguous(), image_sizes) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/instances.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/instances.py new file mode 100644 index 00000000..c9579bce --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/instances.py @@ -0,0 +1,194 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import itertools +import warnings +from typing import Any, Dict, List, Tuple, Union +import torch + + +class Instances: + """ + This class represents a list of instances in an image. + It stores the attributes of instances (e.g., boxes, masks, labels, scores) as "fields". + All fields must have the same ``__len__`` which is the number of instances. + + All other (non-field) attributes of this class are considered private: + they must start with '_' and are not modifiable by a user. + + Some basic usage: + + 1. Set/get/check a field: + + .. code-block:: python + + instances.gt_boxes = Boxes(...) + print(instances.pred_masks) # a tensor of shape (N, H, W) + print('gt_masks' in instances) + + 2. ``len(instances)`` returns the number of instances + 3. Indexing: ``instances[indices]`` will apply the indexing on all the fields + and returns a new :class:`Instances`. + Typically, ``indices`` is a integer vector of indices, + or a binary mask of length ``num_instances`` + + .. code-block:: python + + category_3_detections = instances[instances.pred_classes == 3] + confident_detections = instances[instances.scores > 0.9] + """ + + def __init__(self, image_size: Tuple[int, int], **kwargs: Any): + """ + Args: + image_size (height, width): the spatial size of the image. + kwargs: fields to add to this `Instances`. + """ + self._image_size = image_size + self._fields: Dict[str, Any] = {} + for k, v in kwargs.items(): + self.set(k, v) + + @property + def image_size(self) -> Tuple[int, int]: + """ + Returns: + tuple: height, width + """ + return self._image_size + + def __setattr__(self, name: str, val: Any) -> None: + if name.startswith("_"): + super().__setattr__(name, val) + else: + self.set(name, val) + + def __getattr__(self, name: str) -> Any: + if name == "_fields" or name not in self._fields: + raise AttributeError("Cannot find field '{}' in the given Instances!".format(name)) + return self._fields[name] + + def set(self, name: str, value: Any) -> None: + """ + Set the field named `name` to `value`. + The length of `value` must be the number of instances, + and must agree with other existing fields in this object. + """ + with warnings.catch_warnings(record=True): + data_len = len(value) + if len(self._fields): + assert ( + len(self) == data_len + ), "Adding a field of length {} to a Instances of length {}".format(data_len, len(self)) + self._fields[name] = value + + def has(self, name: str) -> bool: + """ + Returns: + bool: whether the field called `name` exists. + """ + return name in self._fields + + def remove(self, name: str) -> None: + """ + Remove the field called `name`. + """ + del self._fields[name] + + def get(self, name: str) -> Any: + """ + Returns the field called `name`. + """ + return self._fields[name] + + def get_fields(self) -> Dict[str, Any]: + """ + Returns: + dict: a dict which maps names (str) to data of the fields + + Modifying the returned dict will modify this instance. + """ + return self._fields + + # Tensor-like methods + def to(self, *args: Any, **kwargs: Any) -> "Instances": + """ + Returns: + Instances: all fields are called with a `to(device)`, if the field has this method. + """ + ret = Instances(self._image_size) + for k, v in self._fields.items(): + if hasattr(v, "to"): + v = v.to(*args, **kwargs) + ret.set(k, v) + return ret + + def __getitem__(self, item: Union[int, slice, torch.BoolTensor]) -> "Instances": + """ + Args: + item: an index-like object and will be used to index all the fields. + + Returns: + If `item` is a string, return the data in the corresponding field. + Otherwise, returns an `Instances` where all fields are indexed by `item`. + """ + if type(item) == int: + if item >= len(self) or item < -len(self): + raise IndexError("Instances index out of range!") + else: + item = slice(item, None, len(self)) + + ret = Instances(self._image_size) + for k, v in self._fields.items(): + ret.set(k, v[item]) + return ret + + def __len__(self) -> int: + for v in self._fields.values(): + # use __len__ because len() has to be int and is not friendly to tracing + return v.__len__() + raise NotImplementedError("Empty Instances does not support __len__!") + + def __iter__(self): + raise NotImplementedError("`Instances` object is not iterable!") + + @staticmethod + def cat(instance_lists: List["Instances"]) -> "Instances": + """ + Args: + instance_lists (list[Instances]) + + Returns: + Instances + """ + assert all(isinstance(i, Instances) for i in instance_lists) + assert len(instance_lists) > 0 + if len(instance_lists) == 1: + return instance_lists[0] + + image_size = instance_lists[0].image_size + if not isinstance(image_size, torch.Tensor): # could be a tensor in tracing + for i in instance_lists[1:]: + assert i.image_size == image_size + ret = Instances(image_size) + for k in instance_lists[0]._fields.keys(): + values = [i.get(k) for i in instance_lists] + v0 = values[0] + if isinstance(v0, torch.Tensor): + values = torch.cat(values, dim=0) + elif isinstance(v0, list): + values = list(itertools.chain(*values)) + elif hasattr(type(v0), "cat"): + values = type(v0).cat(values) + else: + raise ValueError("Unsupported type {} for concatenation".format(type(v0))) + ret.set(k, values) + return ret + + def __str__(self) -> str: + s = self.__class__.__name__ + "(" + s += "num_instances={}, ".format(len(self)) + s += "image_height={}, ".format(self._image_size[0]) + s += "image_width={}, ".format(self._image_size[1]) + s += "fields=[{}])".format(", ".join((f"{k}: {v}" for k, v in self._fields.items()))) + return s + + __repr__ = __str__ diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/keypoints.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/keypoints.py new file mode 100644 index 00000000..b93ebed4 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/keypoints.py @@ -0,0 +1,235 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import numpy as np +from typing import Any, List, Tuple, Union +import torch +from torch.nn import functional as F + + +class Keypoints: + """ + Stores keypoint **annotation** data. GT Instances have a `gt_keypoints` property + containing the x,y location and visibility flag of each keypoint. This tensor has shape + (N, K, 3) where N is the number of instances and K is the number of keypoints per instance. + + The visibility flag follows the COCO format and must be one of three integers: + + * v=0: not labeled (in which case x=y=0) + * v=1: labeled but not visible + * v=2: labeled and visible + """ + + def __init__(self, keypoints: Union[torch.Tensor, np.ndarray, List[List[float]]]): + """ + Arguments: + keypoints: A Tensor, numpy array, or list of the x, y, and visibility of each keypoint. + The shape should be (N, K, 3) where N is the number of + instances, and K is the number of keypoints per instance. + """ + device = keypoints.device if isinstance(keypoints, torch.Tensor) else torch.device("cpu") + keypoints = torch.as_tensor(keypoints, dtype=torch.float32, device=device) + assert keypoints.dim() == 3 and keypoints.shape[2] == 3, keypoints.shape + self.tensor = keypoints + + def __len__(self) -> int: + return self.tensor.size(0) + + def to(self, *args: Any, **kwargs: Any) -> "Keypoints": + return type(self)(self.tensor.to(*args, **kwargs)) + + @property + def device(self) -> torch.device: + return self.tensor.device + + def to_heatmap(self, boxes: torch.Tensor, heatmap_size: int) -> torch.Tensor: + """ + Convert keypoint annotations to a heatmap of one-hot labels for training, + as described in :paper:`Mask R-CNN`. + + Arguments: + boxes: Nx4 tensor, the boxes to draw the keypoints to + + Returns: + heatmaps: + A tensor of shape (N, K), each element is integer spatial label + in the range [0, heatmap_size**2 - 1] for each keypoint in the input. + valid: + A tensor of shape (N, K) containing whether each keypoint is in the roi or not. + """ + return _keypoints_to_heatmap(self.tensor, boxes, heatmap_size) + + def __getitem__(self, item: Union[int, slice, torch.BoolTensor]) -> "Keypoints": + """ + Create a new `Keypoints` by indexing on this `Keypoints`. + + The following usage are allowed: + + 1. `new_kpts = kpts[3]`: return a `Keypoints` which contains only one instance. + 2. `new_kpts = kpts[2:10]`: return a slice of key points. + 3. `new_kpts = kpts[vector]`, where vector is a torch.ByteTensor + with `length = len(kpts)`. Nonzero elements in the vector will be selected. + + Note that the returned Keypoints might share storage with this Keypoints, + subject to Pytorch's indexing semantics. + """ + if isinstance(item, int): + return Keypoints([self.tensor[item]]) + return Keypoints(self.tensor[item]) + + def __repr__(self) -> str: + s = self.__class__.__name__ + "(" + s += "num_instances={})".format(len(self.tensor)) + return s + + @staticmethod + def cat(keypoints_list: List["Keypoints"]) -> "Keypoints": + """ + Concatenates a list of Keypoints into a single Keypoints + + Arguments: + keypoints_list (list[Keypoints]) + + Returns: + Keypoints: the concatenated Keypoints + """ + assert isinstance(keypoints_list, (list, tuple)) + assert len(keypoints_list) > 0 + assert all(isinstance(keypoints, Keypoints) for keypoints in keypoints_list) + + cat_kpts = type(keypoints_list[0])( + torch.cat([kpts.tensor for kpts in keypoints_list], dim=0) + ) + return cat_kpts + + +# TODO make this nicer, this is a direct translation from C2 (but removing the inner loop) +def _keypoints_to_heatmap( + keypoints: torch.Tensor, rois: torch.Tensor, heatmap_size: int +) -> Tuple[torch.Tensor, torch.Tensor]: + """ + Encode keypoint locations into a target heatmap for use in SoftmaxWithLoss across space. + + Maps keypoints from the half-open interval [x1, x2) on continuous image coordinates to the + closed interval [0, heatmap_size - 1] on discrete image coordinates. We use the + continuous-discrete conversion from Heckbert 1990 ("What is the coordinate of a pixel?"): + d = floor(c) and c = d + 0.5, where d is a discrete coordinate and c is a continuous coordinate. + + Arguments: + keypoints: tensor of keypoint locations in of shape (N, K, 3). + rois: Nx4 tensor of rois in xyxy format + heatmap_size: integer side length of square heatmap. + + Returns: + heatmaps: A tensor of shape (N, K) containing an integer spatial label + in the range [0, heatmap_size**2 - 1] for each keypoint in the input. + valid: A tensor of shape (N, K) containing whether each keypoint is in + the roi or not. + """ + + if rois.numel() == 0: + return rois.new().long(), rois.new().long() + offset_x = rois[:, 0] + offset_y = rois[:, 1] + scale_x = heatmap_size / (rois[:, 2] - rois[:, 0]) + scale_y = heatmap_size / (rois[:, 3] - rois[:, 1]) + + offset_x = offset_x[:, None] + offset_y = offset_y[:, None] + scale_x = scale_x[:, None] + scale_y = scale_y[:, None] + + x = keypoints[..., 0] + y = keypoints[..., 1] + + x_boundary_inds = x == rois[:, 2][:, None] + y_boundary_inds = y == rois[:, 3][:, None] + + x = (x - offset_x) * scale_x + x = x.floor().long() + y = (y - offset_y) * scale_y + y = y.floor().long() + + x[x_boundary_inds] = heatmap_size - 1 + y[y_boundary_inds] = heatmap_size - 1 + + valid_loc = (x >= 0) & (y >= 0) & (x < heatmap_size) & (y < heatmap_size) + vis = keypoints[..., 2] > 0 + valid = (valid_loc & vis).long() + + lin_ind = y * heatmap_size + x + heatmaps = lin_ind * valid + + return heatmaps, valid + + +@torch.jit.script_if_tracing +def heatmaps_to_keypoints(maps: torch.Tensor, rois: torch.Tensor) -> torch.Tensor: + """ + Extract predicted keypoint locations from heatmaps. + + Args: + maps (Tensor): (#ROIs, #keypoints, POOL_H, POOL_W). The predicted heatmap of logits for + each ROI and each keypoint. + rois (Tensor): (#ROIs, 4). The box of each ROI. + + Returns: + Tensor of shape (#ROIs, #keypoints, 4) with the last dimension corresponding to + (x, y, logit, score) for each keypoint. + + When converting discrete pixel indices in an NxN image to a continuous keypoint coordinate, + we maintain consistency with :meth:`Keypoints.to_heatmap` by using the conversion from + Heckbert 1990: c = d + 0.5, where d is a discrete coordinate and c is a continuous coordinate. + """ + + offset_x = rois[:, 0] + offset_y = rois[:, 1] + + widths = (rois[:, 2] - rois[:, 0]).clamp(min=1) + heights = (rois[:, 3] - rois[:, 1]).clamp(min=1) + widths_ceil = widths.ceil() + heights_ceil = heights.ceil() + + num_rois, num_keypoints = maps.shape[:2] + xy_preds = maps.new_zeros(rois.shape[0], num_keypoints, 4) + + width_corrections = widths / widths_ceil + height_corrections = heights / heights_ceil + + keypoints_idx = torch.arange(num_keypoints, device=maps.device) + + for i in range(num_rois): + outsize = (int(heights_ceil[i]), int(widths_ceil[i])) + roi_map = F.interpolate(maps[[i]], size=outsize, mode="bicubic", align_corners=False) + + # Although semantically equivalent, `reshape` is used instead of `squeeze` due + # to limitation during ONNX export of `squeeze` in scripting mode + roi_map = roi_map.reshape(roi_map.shape[1:]) # keypoints x H x W + + # softmax over the spatial region + max_score, _ = roi_map.view(num_keypoints, -1).max(1) + max_score = max_score.view(num_keypoints, 1, 1) + tmp_full_resolution = (roi_map - max_score).exp_() + tmp_pool_resolution = (maps[i] - max_score).exp_() + # Produce scores over the region H x W, but normalize with POOL_H x POOL_W, + # so that the scores of objects of different absolute sizes will be more comparable + roi_map_scores = tmp_full_resolution / tmp_pool_resolution.sum((1, 2), keepdim=True) + + w = roi_map.shape[2] + pos = roi_map.view(num_keypoints, -1).argmax(1) + + x_int = pos % w + y_int = (pos - x_int) // w + + assert ( + roi_map_scores[keypoints_idx, y_int, x_int] + == roi_map_scores.view(num_keypoints, -1).max(1)[0] + ).all() + + x = (x_int.float() + 0.5) * width_corrections[i] + y = (y_int.float() + 0.5) * height_corrections[i] + + xy_preds[i, :, 0] = x + offset_x[i] + xy_preds[i, :, 1] = y + offset_y[i] + xy_preds[i, :, 2] = roi_map[keypoints_idx, y_int, x_int] + xy_preds[i, :, 3] = roi_map_scores[keypoints_idx, y_int, x_int] + + return xy_preds diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/masks.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/masks.py new file mode 100644 index 00000000..995fee72 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/masks.py @@ -0,0 +1,534 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import copy +import itertools +import numpy as np +from typing import Any, Iterator, List, Union +import annotator.oneformer.pycocotools.mask as mask_util +import torch +from torch import device + +from annotator.oneformer.detectron2.layers.roi_align import ROIAlign +from annotator.oneformer.detectron2.utils.memory import retry_if_cuda_oom + +from .boxes import Boxes + + +def polygon_area(x, y): + # Using the shoelace formula + # https://stackoverflow.com/questions/24467972/calculate-area-of-polygon-given-x-y-coordinates + return 0.5 * np.abs(np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1))) + + +def polygons_to_bitmask(polygons: List[np.ndarray], height: int, width: int) -> np.ndarray: + """ + Args: + polygons (list[ndarray]): each array has shape (Nx2,) + height, width (int) + + Returns: + ndarray: a bool mask of shape (height, width) + """ + if len(polygons) == 0: + # COCOAPI does not support empty polygons + return np.zeros((height, width)).astype(bool) + rles = mask_util.frPyObjects(polygons, height, width) + rle = mask_util.merge(rles) + return mask_util.decode(rle).astype(bool) + + +def rasterize_polygons_within_box( + polygons: List[np.ndarray], box: np.ndarray, mask_size: int +) -> torch.Tensor: + """ + Rasterize the polygons into a mask image and + crop the mask content in the given box. + The cropped mask is resized to (mask_size, mask_size). + + This function is used when generating training targets for mask head in Mask R-CNN. + Given original ground-truth masks for an image, new ground-truth mask + training targets in the size of `mask_size x mask_size` + must be provided for each predicted box. This function will be called to + produce such targets. + + Args: + polygons (list[ndarray[float]]): a list of polygons, which represents an instance. + box: 4-element numpy array + mask_size (int): + + Returns: + Tensor: BoolTensor of shape (mask_size, mask_size) + """ + # 1. Shift the polygons w.r.t the boxes + w, h = box[2] - box[0], box[3] - box[1] + + polygons = copy.deepcopy(polygons) + for p in polygons: + p[0::2] = p[0::2] - box[0] + p[1::2] = p[1::2] - box[1] + + # 2. Rescale the polygons to the new box size + # max() to avoid division by small number + ratio_h = mask_size / max(h, 0.1) + ratio_w = mask_size / max(w, 0.1) + + if ratio_h == ratio_w: + for p in polygons: + p *= ratio_h + else: + for p in polygons: + p[0::2] *= ratio_w + p[1::2] *= ratio_h + + # 3. Rasterize the polygons with coco api + mask = polygons_to_bitmask(polygons, mask_size, mask_size) + mask = torch.from_numpy(mask) + return mask + + +class BitMasks: + """ + This class stores the segmentation masks for all objects in one image, in + the form of bitmaps. + + Attributes: + tensor: bool Tensor of N,H,W, representing N instances in the image. + """ + + def __init__(self, tensor: Union[torch.Tensor, np.ndarray]): + """ + Args: + tensor: bool Tensor of N,H,W, representing N instances in the image. + """ + if isinstance(tensor, torch.Tensor): + tensor = tensor.to(torch.bool) + else: + tensor = torch.as_tensor(tensor, dtype=torch.bool, device=torch.device("cpu")) + assert tensor.dim() == 3, tensor.size() + self.image_size = tensor.shape[1:] + self.tensor = tensor + + @torch.jit.unused + def to(self, *args: Any, **kwargs: Any) -> "BitMasks": + return BitMasks(self.tensor.to(*args, **kwargs)) + + @property + def device(self) -> torch.device: + return self.tensor.device + + @torch.jit.unused + def __getitem__(self, item: Union[int, slice, torch.BoolTensor]) -> "BitMasks": + """ + Returns: + BitMasks: Create a new :class:`BitMasks` by indexing. + + The following usage are allowed: + + 1. `new_masks = masks[3]`: return a `BitMasks` which contains only one mask. + 2. `new_masks = masks[2:10]`: return a slice of masks. + 3. `new_masks = masks[vector]`, where vector is a torch.BoolTensor + with `length = len(masks)`. Nonzero elements in the vector will be selected. + + Note that the returned object might share storage with this object, + subject to Pytorch's indexing semantics. + """ + if isinstance(item, int): + return BitMasks(self.tensor[item].unsqueeze(0)) + m = self.tensor[item] + assert m.dim() == 3, "Indexing on BitMasks with {} returns a tensor with shape {}!".format( + item, m.shape + ) + return BitMasks(m) + + @torch.jit.unused + def __iter__(self) -> torch.Tensor: + yield from self.tensor + + @torch.jit.unused + def __repr__(self) -> str: + s = self.__class__.__name__ + "(" + s += "num_instances={})".format(len(self.tensor)) + return s + + def __len__(self) -> int: + return self.tensor.shape[0] + + def nonempty(self) -> torch.Tensor: + """ + Find masks that are non-empty. + + Returns: + Tensor: a BoolTensor which represents + whether each mask is empty (False) or non-empty (True). + """ + return self.tensor.flatten(1).any(dim=1) + + @staticmethod + def from_polygon_masks( + polygon_masks: Union["PolygonMasks", List[List[np.ndarray]]], height: int, width: int + ) -> "BitMasks": + """ + Args: + polygon_masks (list[list[ndarray]] or PolygonMasks) + height, width (int) + """ + if isinstance(polygon_masks, PolygonMasks): + polygon_masks = polygon_masks.polygons + masks = [polygons_to_bitmask(p, height, width) for p in polygon_masks] + if len(masks): + return BitMasks(torch.stack([torch.from_numpy(x) for x in masks])) + else: + return BitMasks(torch.empty(0, height, width, dtype=torch.bool)) + + @staticmethod + def from_roi_masks(roi_masks: "ROIMasks", height: int, width: int) -> "BitMasks": + """ + Args: + roi_masks: + height, width (int): + """ + return roi_masks.to_bitmasks(height, width) + + def crop_and_resize(self, boxes: torch.Tensor, mask_size: int) -> torch.Tensor: + """ + Crop each bitmask by the given box, and resize results to (mask_size, mask_size). + This can be used to prepare training targets for Mask R-CNN. + It has less reconstruction error compared to rasterization with polygons. + However we observe no difference in accuracy, + but BitMasks requires more memory to store all the masks. + + Args: + boxes (Tensor): Nx4 tensor storing the boxes for each mask + mask_size (int): the size of the rasterized mask. + + Returns: + Tensor: + A bool tensor of shape (N, mask_size, mask_size), where + N is the number of predicted boxes for this image. + """ + assert len(boxes) == len(self), "{} != {}".format(len(boxes), len(self)) + device = self.tensor.device + + batch_inds = torch.arange(len(boxes), device=device).to(dtype=boxes.dtype)[:, None] + rois = torch.cat([batch_inds, boxes], dim=1) # Nx5 + + bit_masks = self.tensor.to(dtype=torch.float32) + rois = rois.to(device=device) + output = ( + ROIAlign((mask_size, mask_size), 1.0, 0, aligned=True) + .forward(bit_masks[:, None, :, :], rois) + .squeeze(1) + ) + output = output >= 0.5 + return output + + def get_bounding_boxes(self) -> Boxes: + """ + Returns: + Boxes: tight bounding boxes around bitmasks. + If a mask is empty, it's bounding box will be all zero. + """ + boxes = torch.zeros(self.tensor.shape[0], 4, dtype=torch.float32) + x_any = torch.any(self.tensor, dim=1) + y_any = torch.any(self.tensor, dim=2) + for idx in range(self.tensor.shape[0]): + x = torch.where(x_any[idx, :])[0] + y = torch.where(y_any[idx, :])[0] + if len(x) > 0 and len(y) > 0: + boxes[idx, :] = torch.as_tensor( + [x[0], y[0], x[-1] + 1, y[-1] + 1], dtype=torch.float32 + ) + return Boxes(boxes) + + @staticmethod + def cat(bitmasks_list: List["BitMasks"]) -> "BitMasks": + """ + Concatenates a list of BitMasks into a single BitMasks + + Arguments: + bitmasks_list (list[BitMasks]) + + Returns: + BitMasks: the concatenated BitMasks + """ + assert isinstance(bitmasks_list, (list, tuple)) + assert len(bitmasks_list) > 0 + assert all(isinstance(bitmask, BitMasks) for bitmask in bitmasks_list) + + cat_bitmasks = type(bitmasks_list[0])(torch.cat([bm.tensor for bm in bitmasks_list], dim=0)) + return cat_bitmasks + + +class PolygonMasks: + """ + This class stores the segmentation masks for all objects in one image, in the form of polygons. + + Attributes: + polygons: list[list[ndarray]]. Each ndarray is a float64 vector representing a polygon. + """ + + def __init__(self, polygons: List[List[Union[torch.Tensor, np.ndarray]]]): + """ + Arguments: + polygons (list[list[np.ndarray]]): The first + level of the list correspond to individual instances, + the second level to all the polygons that compose the + instance, and the third level to the polygon coordinates. + The third level array should have the format of + [x0, y0, x1, y1, ..., xn, yn] (n >= 3). + """ + if not isinstance(polygons, list): + raise ValueError( + "Cannot create PolygonMasks: Expect a list of list of polygons per image. " + "Got '{}' instead.".format(type(polygons)) + ) + + def _make_array(t: Union[torch.Tensor, np.ndarray]) -> np.ndarray: + # Use float64 for higher precision, because why not? + # Always put polygons on CPU (self.to is a no-op) since they + # are supposed to be small tensors. + # May need to change this assumption if GPU placement becomes useful + if isinstance(t, torch.Tensor): + t = t.cpu().numpy() + return np.asarray(t).astype("float64") + + def process_polygons( + polygons_per_instance: List[Union[torch.Tensor, np.ndarray]] + ) -> List[np.ndarray]: + if not isinstance(polygons_per_instance, list): + raise ValueError( + "Cannot create polygons: Expect a list of polygons per instance. " + "Got '{}' instead.".format(type(polygons_per_instance)) + ) + # transform each polygon to a numpy array + polygons_per_instance = [_make_array(p) for p in polygons_per_instance] + for polygon in polygons_per_instance: + if len(polygon) % 2 != 0 or len(polygon) < 6: + raise ValueError(f"Cannot create a polygon from {len(polygon)} coordinates.") + return polygons_per_instance + + self.polygons: List[List[np.ndarray]] = [ + process_polygons(polygons_per_instance) for polygons_per_instance in polygons + ] + + def to(self, *args: Any, **kwargs: Any) -> "PolygonMasks": + return self + + @property + def device(self) -> torch.device: + return torch.device("cpu") + + def get_bounding_boxes(self) -> Boxes: + """ + Returns: + Boxes: tight bounding boxes around polygon masks. + """ + boxes = torch.zeros(len(self.polygons), 4, dtype=torch.float32) + for idx, polygons_per_instance in enumerate(self.polygons): + minxy = torch.as_tensor([float("inf"), float("inf")], dtype=torch.float32) + maxxy = torch.zeros(2, dtype=torch.float32) + for polygon in polygons_per_instance: + coords = torch.from_numpy(polygon).view(-1, 2).to(dtype=torch.float32) + minxy = torch.min(minxy, torch.min(coords, dim=0).values) + maxxy = torch.max(maxxy, torch.max(coords, dim=0).values) + boxes[idx, :2] = minxy + boxes[idx, 2:] = maxxy + return Boxes(boxes) + + def nonempty(self) -> torch.Tensor: + """ + Find masks that are non-empty. + + Returns: + Tensor: + a BoolTensor which represents whether each mask is empty (False) or not (True). + """ + keep = [1 if len(polygon) > 0 else 0 for polygon in self.polygons] + return torch.from_numpy(np.asarray(keep, dtype=bool)) + + def __getitem__(self, item: Union[int, slice, List[int], torch.BoolTensor]) -> "PolygonMasks": + """ + Support indexing over the instances and return a `PolygonMasks` object. + `item` can be: + + 1. An integer. It will return an object with only one instance. + 2. A slice. It will return an object with the selected instances. + 3. A list[int]. It will return an object with the selected instances, + correpsonding to the indices in the list. + 4. A vector mask of type BoolTensor, whose length is num_instances. + It will return an object with the instances whose mask is nonzero. + """ + if isinstance(item, int): + selected_polygons = [self.polygons[item]] + elif isinstance(item, slice): + selected_polygons = self.polygons[item] + elif isinstance(item, list): + selected_polygons = [self.polygons[i] for i in item] + elif isinstance(item, torch.Tensor): + # Polygons is a list, so we have to move the indices back to CPU. + if item.dtype == torch.bool: + assert item.dim() == 1, item.shape + item = item.nonzero().squeeze(1).cpu().numpy().tolist() + elif item.dtype in [torch.int32, torch.int64]: + item = item.cpu().numpy().tolist() + else: + raise ValueError("Unsupported tensor dtype={} for indexing!".format(item.dtype)) + selected_polygons = [self.polygons[i] for i in item] + return PolygonMasks(selected_polygons) + + def __iter__(self) -> Iterator[List[np.ndarray]]: + """ + Yields: + list[ndarray]: the polygons for one instance. + Each Tensor is a float64 vector representing a polygon. + """ + return iter(self.polygons) + + def __repr__(self) -> str: + s = self.__class__.__name__ + "(" + s += "num_instances={})".format(len(self.polygons)) + return s + + def __len__(self) -> int: + return len(self.polygons) + + def crop_and_resize(self, boxes: torch.Tensor, mask_size: int) -> torch.Tensor: + """ + Crop each mask by the given box, and resize results to (mask_size, mask_size). + This can be used to prepare training targets for Mask R-CNN. + + Args: + boxes (Tensor): Nx4 tensor storing the boxes for each mask + mask_size (int): the size of the rasterized mask. + + Returns: + Tensor: A bool tensor of shape (N, mask_size, mask_size), where + N is the number of predicted boxes for this image. + """ + assert len(boxes) == len(self), "{} != {}".format(len(boxes), len(self)) + + device = boxes.device + # Put boxes on the CPU, as the polygon representation is not efficient GPU-wise + # (several small tensors for representing a single instance mask) + boxes = boxes.to(torch.device("cpu")) + + results = [ + rasterize_polygons_within_box(poly, box.numpy(), mask_size) + for poly, box in zip(self.polygons, boxes) + ] + """ + poly: list[list[float]], the polygons for one instance + box: a tensor of shape (4,) + """ + if len(results) == 0: + return torch.empty(0, mask_size, mask_size, dtype=torch.bool, device=device) + return torch.stack(results, dim=0).to(device=device) + + def area(self): + """ + Computes area of the mask. + Only works with Polygons, using the shoelace formula: + https://stackoverflow.com/questions/24467972/calculate-area-of-polygon-given-x-y-coordinates + + Returns: + Tensor: a vector, area for each instance + """ + + area = [] + for polygons_per_instance in self.polygons: + area_per_instance = 0 + for p in polygons_per_instance: + area_per_instance += polygon_area(p[0::2], p[1::2]) + area.append(area_per_instance) + + return torch.tensor(area) + + @staticmethod + def cat(polymasks_list: List["PolygonMasks"]) -> "PolygonMasks": + """ + Concatenates a list of PolygonMasks into a single PolygonMasks + + Arguments: + polymasks_list (list[PolygonMasks]) + + Returns: + PolygonMasks: the concatenated PolygonMasks + """ + assert isinstance(polymasks_list, (list, tuple)) + assert len(polymasks_list) > 0 + assert all(isinstance(polymask, PolygonMasks) for polymask in polymasks_list) + + cat_polymasks = type(polymasks_list[0])( + list(itertools.chain.from_iterable(pm.polygons for pm in polymasks_list)) + ) + return cat_polymasks + + +class ROIMasks: + """ + Represent masks by N smaller masks defined in some ROIs. Once ROI boxes are given, + full-image bitmask can be obtained by "pasting" the mask on the region defined + by the corresponding ROI box. + """ + + def __init__(self, tensor: torch.Tensor): + """ + Args: + tensor: (N, M, M) mask tensor that defines the mask within each ROI. + """ + if tensor.dim() != 3: + raise ValueError("ROIMasks must take a masks of 3 dimension.") + self.tensor = tensor + + def to(self, device: torch.device) -> "ROIMasks": + return ROIMasks(self.tensor.to(device)) + + @property + def device(self) -> device: + return self.tensor.device + + def __len__(self): + return self.tensor.shape[0] + + def __getitem__(self, item) -> "ROIMasks": + """ + Returns: + ROIMasks: Create a new :class:`ROIMasks` by indexing. + + The following usage are allowed: + + 1. `new_masks = masks[2:10]`: return a slice of masks. + 2. `new_masks = masks[vector]`, where vector is a torch.BoolTensor + with `length = len(masks)`. Nonzero elements in the vector will be selected. + + Note that the returned object might share storage with this object, + subject to Pytorch's indexing semantics. + """ + t = self.tensor[item] + if t.dim() != 3: + raise ValueError( + f"Indexing on ROIMasks with {item} returns a tensor with shape {t.shape}!" + ) + return ROIMasks(t) + + @torch.jit.unused + def __repr__(self) -> str: + s = self.__class__.__name__ + "(" + s += "num_instances={})".format(len(self.tensor)) + return s + + @torch.jit.unused + def to_bitmasks(self, boxes: torch.Tensor, height, width, threshold=0.5): + """ + Args: see documentation of :func:`paste_masks_in_image`. + """ + from annotator.oneformer.detectron2.layers.mask_ops import paste_masks_in_image, _paste_masks_tensor_shape + + if torch.jit.is_tracing(): + if isinstance(height, torch.Tensor): + paste_func = _paste_masks_tensor_shape + else: + paste_func = paste_masks_in_image + else: + paste_func = retry_if_cuda_oom(paste_masks_in_image) + bitmasks = paste_func(self.tensor, boxes.tensor, (height, width), threshold=threshold) + return BitMasks(bitmasks) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/rotated_boxes.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/rotated_boxes.py new file mode 100644 index 00000000..aacfc730 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/structures/rotated_boxes.py @@ -0,0 +1,505 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import math +from typing import List, Tuple +import torch + +from annotator.oneformer.detectron2.layers.rotated_boxes import pairwise_iou_rotated + +from .boxes import Boxes + + +class RotatedBoxes(Boxes): + """ + This structure stores a list of rotated boxes as a Nx5 torch.Tensor. + It supports some common methods about boxes + (`area`, `clip`, `nonempty`, etc), + and also behaves like a Tensor + (support indexing, `to(device)`, `.device`, and iteration over all boxes) + """ + + def __init__(self, tensor: torch.Tensor): + """ + Args: + tensor (Tensor[float]): a Nx5 matrix. Each row is + (x_center, y_center, width, height, angle), + in which angle is represented in degrees. + While there's no strict range restriction for it, + the recommended principal range is between [-180, 180) degrees. + + Assume we have a horizontal box B = (x_center, y_center, width, height), + where width is along the x-axis and height is along the y-axis. + The rotated box B_rot (x_center, y_center, width, height, angle) + can be seen as: + + 1. When angle == 0: + B_rot == B + 2. When angle > 0: + B_rot is obtained by rotating B w.r.t its center by :math:`|angle|` degrees CCW; + 3. When angle < 0: + B_rot is obtained by rotating B w.r.t its center by :math:`|angle|` degrees CW. + + Mathematically, since the right-handed coordinate system for image space + is (y, x), where y is top->down and x is left->right, the 4 vertices of the + rotated rectangle :math:`(yr_i, xr_i)` (i = 1, 2, 3, 4) can be obtained from + the vertices of the horizontal rectangle :math:`(y_i, x_i)` (i = 1, 2, 3, 4) + in the following way (:math:`\\theta = angle*\\pi/180` is the angle in radians, + :math:`(y_c, x_c)` is the center of the rectangle): + + .. math:: + + yr_i = \\cos(\\theta) (y_i - y_c) - \\sin(\\theta) (x_i - x_c) + y_c, + + xr_i = \\sin(\\theta) (y_i - y_c) + \\cos(\\theta) (x_i - x_c) + x_c, + + which is the standard rigid-body rotation transformation. + + Intuitively, the angle is + (1) the rotation angle from y-axis in image space + to the height vector (top->down in the box's local coordinate system) + of the box in CCW, and + (2) the rotation angle from x-axis in image space + to the width vector (left->right in the box's local coordinate system) + of the box in CCW. + + More intuitively, consider the following horizontal box ABCD represented + in (x1, y1, x2, y2): (3, 2, 7, 4), + covering the [3, 7] x [2, 4] region of the continuous coordinate system + which looks like this: + + .. code:: none + + O--------> x + | + | A---B + | | | + | D---C + | + v y + + Note that each capital letter represents one 0-dimensional geometric point + instead of a 'square pixel' here. + + In the example above, using (x, y) to represent a point we have: + + .. math:: + + O = (0, 0), A = (3, 2), B = (7, 2), C = (7, 4), D = (3, 4) + + We name vector AB = vector DC as the width vector in box's local coordinate system, and + vector AD = vector BC as the height vector in box's local coordinate system. Initially, + when angle = 0 degree, they're aligned with the positive directions of x-axis and y-axis + in the image space, respectively. + + For better illustration, we denote the center of the box as E, + + .. code:: none + + O--------> x + | + | A---B + | | E | + | D---C + | + v y + + where the center E = ((3+7)/2, (2+4)/2) = (5, 3). + + Also, + + .. math:: + + width = |AB| = |CD| = 7 - 3 = 4, + height = |AD| = |BC| = 4 - 2 = 2. + + Therefore, the corresponding representation for the same shape in rotated box in + (x_center, y_center, width, height, angle) format is: + + (5, 3, 4, 2, 0), + + Now, let's consider (5, 3, 4, 2, 90), which is rotated by 90 degrees + CCW (counter-clockwise) by definition. It looks like this: + + .. code:: none + + O--------> x + | B-C + | | | + | |E| + | | | + | A-D + v y + + The center E is still located at the same point (5, 3), while the vertices + ABCD are rotated by 90 degrees CCW with regard to E: + A = (4, 5), B = (4, 1), C = (6, 1), D = (6, 5) + + Here, 90 degrees can be seen as the CCW angle to rotate from y-axis to + vector AD or vector BC (the top->down height vector in box's local coordinate system), + or the CCW angle to rotate from x-axis to vector AB or vector DC (the left->right + width vector in box's local coordinate system). + + .. math:: + + width = |AB| = |CD| = 5 - 1 = 4, + height = |AD| = |BC| = 6 - 4 = 2. + + Next, how about (5, 3, 4, 2, -90), which is rotated by 90 degrees CW (clockwise) + by definition? It looks like this: + + .. code:: none + + O--------> x + | D-A + | | | + | |E| + | | | + | C-B + v y + + The center E is still located at the same point (5, 3), while the vertices + ABCD are rotated by 90 degrees CW with regard to E: + A = (6, 1), B = (6, 5), C = (4, 5), D = (4, 1) + + .. math:: + + width = |AB| = |CD| = 5 - 1 = 4, + height = |AD| = |BC| = 6 - 4 = 2. + + This covers exactly the same region as (5, 3, 4, 2, 90) does, and their IoU + will be 1. However, these two will generate different RoI Pooling results and + should not be treated as an identical box. + + On the other hand, it's easy to see that (X, Y, W, H, A) is identical to + (X, Y, W, H, A+360N), for any integer N. For example (5, 3, 4, 2, 270) would be + identical to (5, 3, 4, 2, -90), because rotating the shape 270 degrees CCW is + equivalent to rotating the same shape 90 degrees CW. + + We could rotate further to get (5, 3, 4, 2, 180), or (5, 3, 4, 2, -180): + + .. code:: none + + O--------> x + | + | C---D + | | E | + | B---A + | + v y + + .. math:: + + A = (7, 4), B = (3, 4), C = (3, 2), D = (7, 2), + + width = |AB| = |CD| = 7 - 3 = 4, + height = |AD| = |BC| = 4 - 2 = 2. + + Finally, this is a very inaccurate (heavily quantized) illustration of + how (5, 3, 4, 2, 60) looks like in case anyone wonders: + + .. code:: none + + O--------> x + | B\ + | / C + | /E / + | A / + | `D + v y + + It's still a rectangle with center of (5, 3), width of 4 and height of 2, + but its angle (and thus orientation) is somewhere between + (5, 3, 4, 2, 0) and (5, 3, 4, 2, 90). + """ + device = tensor.device if isinstance(tensor, torch.Tensor) else torch.device("cpu") + tensor = torch.as_tensor(tensor, dtype=torch.float32, device=device) + if tensor.numel() == 0: + # Use reshape, so we don't end up creating a new tensor that does not depend on + # the inputs (and consequently confuses jit) + tensor = tensor.reshape((0, 5)).to(dtype=torch.float32, device=device) + assert tensor.dim() == 2 and tensor.size(-1) == 5, tensor.size() + + self.tensor = tensor + + def clone(self) -> "RotatedBoxes": + """ + Clone the RotatedBoxes. + + Returns: + RotatedBoxes + """ + return RotatedBoxes(self.tensor.clone()) + + def to(self, device: torch.device): + # Boxes are assumed float32 and does not support to(dtype) + return RotatedBoxes(self.tensor.to(device=device)) + + def area(self) -> torch.Tensor: + """ + Computes the area of all the boxes. + + Returns: + torch.Tensor: a vector with areas of each box. + """ + box = self.tensor + area = box[:, 2] * box[:, 3] + return area + + # Avoid in-place operations so that we can torchscript; NOTE: this creates a new tensor + def normalize_angles(self) -> None: + """ + Restrict angles to the range of [-180, 180) degrees + """ + angle_tensor = (self.tensor[:, 4] + 180.0) % 360.0 - 180.0 + self.tensor = torch.cat((self.tensor[:, :4], angle_tensor[:, None]), dim=1) + + def clip(self, box_size: Tuple[int, int], clip_angle_threshold: float = 1.0) -> None: + """ + Clip (in place) the boxes by limiting x coordinates to the range [0, width] + and y coordinates to the range [0, height]. + + For RRPN: + Only clip boxes that are almost horizontal with a tolerance of + clip_angle_threshold to maintain backward compatibility. + + Rotated boxes beyond this threshold are not clipped for two reasons: + + 1. There are potentially multiple ways to clip a rotated box to make it + fit within the image. + 2. It's tricky to make the entire rectangular box fit within the image + and still be able to not leave out pixels of interest. + + Therefore we rely on ops like RoIAlignRotated to safely handle this. + + Args: + box_size (height, width): The clipping box's size. + clip_angle_threshold: + Iff. abs(normalized(angle)) <= clip_angle_threshold (in degrees), + we do the clipping as horizontal boxes. + """ + h, w = box_size + + # normalize angles to be within (-180, 180] degrees + self.normalize_angles() + + idx = torch.where(torch.abs(self.tensor[:, 4]) <= clip_angle_threshold)[0] + + # convert to (x1, y1, x2, y2) + x1 = self.tensor[idx, 0] - self.tensor[idx, 2] / 2.0 + y1 = self.tensor[idx, 1] - self.tensor[idx, 3] / 2.0 + x2 = self.tensor[idx, 0] + self.tensor[idx, 2] / 2.0 + y2 = self.tensor[idx, 1] + self.tensor[idx, 3] / 2.0 + + # clip + x1.clamp_(min=0, max=w) + y1.clamp_(min=0, max=h) + x2.clamp_(min=0, max=w) + y2.clamp_(min=0, max=h) + + # convert back to (xc, yc, w, h) + self.tensor[idx, 0] = (x1 + x2) / 2.0 + self.tensor[idx, 1] = (y1 + y2) / 2.0 + # make sure widths and heights do not increase due to numerical errors + self.tensor[idx, 2] = torch.min(self.tensor[idx, 2], x2 - x1) + self.tensor[idx, 3] = torch.min(self.tensor[idx, 3], y2 - y1) + + def nonempty(self, threshold: float = 0.0) -> torch.Tensor: + """ + Find boxes that are non-empty. + A box is considered empty, if either of its side is no larger than threshold. + + Returns: + Tensor: a binary vector which represents + whether each box is empty (False) or non-empty (True). + """ + box = self.tensor + widths = box[:, 2] + heights = box[:, 3] + keep = (widths > threshold) & (heights > threshold) + return keep + + def __getitem__(self, item) -> "RotatedBoxes": + """ + Returns: + RotatedBoxes: Create a new :class:`RotatedBoxes` by indexing. + + The following usage are allowed: + + 1. `new_boxes = boxes[3]`: return a `RotatedBoxes` which contains only one box. + 2. `new_boxes = boxes[2:10]`: return a slice of boxes. + 3. `new_boxes = boxes[vector]`, where vector is a torch.ByteTensor + with `length = len(boxes)`. Nonzero elements in the vector will be selected. + + Note that the returned RotatedBoxes might share storage with this RotatedBoxes, + subject to Pytorch's indexing semantics. + """ + if isinstance(item, int): + return RotatedBoxes(self.tensor[item].view(1, -1)) + b = self.tensor[item] + assert b.dim() == 2, "Indexing on RotatedBoxes with {} failed to return a matrix!".format( + item + ) + return RotatedBoxes(b) + + def __len__(self) -> int: + return self.tensor.shape[0] + + def __repr__(self) -> str: + return "RotatedBoxes(" + str(self.tensor) + ")" + + def inside_box(self, box_size: Tuple[int, int], boundary_threshold: int = 0) -> torch.Tensor: + """ + Args: + box_size (height, width): Size of the reference box covering + [0, width] x [0, height] + boundary_threshold (int): Boxes that extend beyond the reference box + boundary by more than boundary_threshold are considered "outside". + + For RRPN, it might not be necessary to call this function since it's common + for rotated box to extend to outside of the image boundaries + (the clip function only clips the near-horizontal boxes) + + Returns: + a binary vector, indicating whether each box is inside the reference box. + """ + height, width = box_size + + cnt_x = self.tensor[..., 0] + cnt_y = self.tensor[..., 1] + half_w = self.tensor[..., 2] / 2.0 + half_h = self.tensor[..., 3] / 2.0 + a = self.tensor[..., 4] + c = torch.abs(torch.cos(a * math.pi / 180.0)) + s = torch.abs(torch.sin(a * math.pi / 180.0)) + # This basically computes the horizontal bounding rectangle of the rotated box + max_rect_dx = c * half_w + s * half_h + max_rect_dy = c * half_h + s * half_w + + inds_inside = ( + (cnt_x - max_rect_dx >= -boundary_threshold) + & (cnt_y - max_rect_dy >= -boundary_threshold) + & (cnt_x + max_rect_dx < width + boundary_threshold) + & (cnt_y + max_rect_dy < height + boundary_threshold) + ) + + return inds_inside + + def get_centers(self) -> torch.Tensor: + """ + Returns: + The box centers in a Nx2 array of (x, y). + """ + return self.tensor[:, :2] + + def scale(self, scale_x: float, scale_y: float) -> None: + """ + Scale the rotated box with horizontal and vertical scaling factors + Note: when scale_factor_x != scale_factor_y, + the rotated box does not preserve the rectangular shape when the angle + is not a multiple of 90 degrees under resize transformation. + Instead, the shape is a parallelogram (that has skew) + Here we make an approximation by fitting a rotated rectangle to the parallelogram. + """ + self.tensor[:, 0] *= scale_x + self.tensor[:, 1] *= scale_y + theta = self.tensor[:, 4] * math.pi / 180.0 + c = torch.cos(theta) + s = torch.sin(theta) + + # In image space, y is top->down and x is left->right + # Consider the local coordintate system for the rotated box, + # where the box center is located at (0, 0), and the four vertices ABCD are + # A(-w / 2, -h / 2), B(w / 2, -h / 2), C(w / 2, h / 2), D(-w / 2, h / 2) + # the midpoint of the left edge AD of the rotated box E is: + # E = (A+D)/2 = (-w / 2, 0) + # the midpoint of the top edge AB of the rotated box F is: + # F(0, -h / 2) + # To get the old coordinates in the global system, apply the rotation transformation + # (Note: the right-handed coordinate system for image space is yOx): + # (old_x, old_y) = (s * y + c * x, c * y - s * x) + # E(old) = (s * 0 + c * (-w/2), c * 0 - s * (-w/2)) = (-c * w / 2, s * w / 2) + # F(old) = (s * (-h / 2) + c * 0, c * (-h / 2) - s * 0) = (-s * h / 2, -c * h / 2) + # After applying the scaling factor (sfx, sfy): + # E(new) = (-sfx * c * w / 2, sfy * s * w / 2) + # F(new) = (-sfx * s * h / 2, -sfy * c * h / 2) + # The new width after scaling tranformation becomes: + + # w(new) = |E(new) - O| * 2 + # = sqrt[(sfx * c * w / 2)^2 + (sfy * s * w / 2)^2] * 2 + # = sqrt[(sfx * c)^2 + (sfy * s)^2] * w + # i.e., scale_factor_w = sqrt[(sfx * c)^2 + (sfy * s)^2] + # + # For example, + # when angle = 0 or 180, |c| = 1, s = 0, scale_factor_w == scale_factor_x; + # when |angle| = 90, c = 0, |s| = 1, scale_factor_w == scale_factor_y + self.tensor[:, 2] *= torch.sqrt((scale_x * c) ** 2 + (scale_y * s) ** 2) + + # h(new) = |F(new) - O| * 2 + # = sqrt[(sfx * s * h / 2)^2 + (sfy * c * h / 2)^2] * 2 + # = sqrt[(sfx * s)^2 + (sfy * c)^2] * h + # i.e., scale_factor_h = sqrt[(sfx * s)^2 + (sfy * c)^2] + # + # For example, + # when angle = 0 or 180, |c| = 1, s = 0, scale_factor_h == scale_factor_y; + # when |angle| = 90, c = 0, |s| = 1, scale_factor_h == scale_factor_x + self.tensor[:, 3] *= torch.sqrt((scale_x * s) ** 2 + (scale_y * c) ** 2) + + # The angle is the rotation angle from y-axis in image space to the height + # vector (top->down in the box's local coordinate system) of the box in CCW. + # + # angle(new) = angle_yOx(O - F(new)) + # = angle_yOx( (sfx * s * h / 2, sfy * c * h / 2) ) + # = atan2(sfx * s * h / 2, sfy * c * h / 2) + # = atan2(sfx * s, sfy * c) + # + # For example, + # when sfx == sfy, angle(new) == atan2(s, c) == angle(old) + self.tensor[:, 4] = torch.atan2(scale_x * s, scale_y * c) * 180 / math.pi + + @classmethod + def cat(cls, boxes_list: List["RotatedBoxes"]) -> "RotatedBoxes": + """ + Concatenates a list of RotatedBoxes into a single RotatedBoxes + + Arguments: + boxes_list (list[RotatedBoxes]) + + Returns: + RotatedBoxes: the concatenated RotatedBoxes + """ + assert isinstance(boxes_list, (list, tuple)) + if len(boxes_list) == 0: + return cls(torch.empty(0)) + assert all([isinstance(box, RotatedBoxes) for box in boxes_list]) + + # use torch.cat (v.s. layers.cat) so the returned boxes never share storage with input + cat_boxes = cls(torch.cat([b.tensor for b in boxes_list], dim=0)) + return cat_boxes + + @property + def device(self) -> torch.device: + return self.tensor.device + + @torch.jit.unused + def __iter__(self): + """ + Yield a box as a Tensor of shape (5,) at a time. + """ + yield from self.tensor + + +def pairwise_iou(boxes1: RotatedBoxes, boxes2: RotatedBoxes) -> None: + """ + Given two lists of rotated boxes of size N and M, + compute the IoU (intersection over union) + between **all** N x M pairs of boxes. + The box order must be (x_center, y_center, width, height, angle). + + Args: + boxes1, boxes2 (RotatedBoxes): + two `RotatedBoxes`. Contains N & M rotated boxes, respectively. + + Returns: + Tensor: IoU, sized [N,M]. + """ + + return pairwise_iou_rotated(boxes1.tensor, boxes2.tensor) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/__init__.py new file mode 100644 index 00000000..21078ae8 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/__init__.py @@ -0,0 +1,15 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from .base_tracker import ( # noqa + BaseTracker, + build_tracker_head, + TRACKER_HEADS_REGISTRY, +) +from .bbox_iou_tracker import BBoxIOUTracker # noqa +from .hungarian_tracker import BaseHungarianTracker # noqa +from .iou_weighted_hungarian_bbox_iou_tracker import ( # noqa + IOUWeightedHungarianBBoxIOUTracker, +) +from .utils import create_prediction_pairs # noqa +from .vanilla_hungarian_bbox_iou_tracker import VanillaHungarianBBoxIOUTracker # noqa + +__all__ = [k for k in globals().keys() if not k.startswith("_")] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/base_tracker.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/base_tracker.py new file mode 100644 index 00000000..bec64074 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/base_tracker.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# Copyright 2004-present Facebook. All Rights Reserved. +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.utils.registry import Registry + +from ..config.config import CfgNode as CfgNode_ +from ..structures import Instances + +TRACKER_HEADS_REGISTRY = Registry("TRACKER_HEADS") +TRACKER_HEADS_REGISTRY.__doc__ = """ +Registry for tracking classes. +""" + + +class BaseTracker(object): + """ + A parent class for all trackers + """ + + @configurable + def __init__(self, **kwargs): + self._prev_instances = None # (D2)instances for previous frame + self._matched_idx = set() # indices in prev_instances found matching + self._matched_ID = set() # idendities in prev_instances found matching + self._untracked_prev_idx = set() # indices in prev_instances not found matching + self._id_count = 0 # used to assign new id + + @classmethod + def from_config(cls, cfg: CfgNode_): + raise NotImplementedError("Calling BaseTracker::from_config") + + def update(self, predictions: Instances) -> Instances: + """ + Args: + predictions: D2 Instances for predictions of the current frame + Return: + D2 Instances for predictions of the current frame with ID assigned + + _prev_instances and instances will have the following fields: + .pred_boxes (shape=[N, 4]) + .scores (shape=[N,]) + .pred_classes (shape=[N,]) + .pred_keypoints (shape=[N, M, 3], Optional) + .pred_masks (shape=List[2D_MASK], Optional) 2D_MASK: shape=[H, W] + .ID (shape=[N,]) + + N: # of detected bboxes + H and W: height and width of 2D mask + """ + raise NotImplementedError("Calling BaseTracker::update") + + +def build_tracker_head(cfg: CfgNode_) -> BaseTracker: + """ + Build a tracker head from `cfg.TRACKER_HEADS.TRACKER_NAME`. + + Args: + cfg: D2 CfgNode, config file with tracker information + Return: + tracker object + """ + name = cfg.TRACKER_HEADS.TRACKER_NAME + tracker_class = TRACKER_HEADS_REGISTRY.get(name) + return tracker_class(cfg) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/bbox_iou_tracker.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/bbox_iou_tracker.py new file mode 100644 index 00000000..2b7e2579 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/bbox_iou_tracker.py @@ -0,0 +1,276 @@ +#!/usr/bin/env python3 +# Copyright 2004-present Facebook. All Rights Reserved. +import copy +import numpy as np +from typing import List +import torch + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.structures import Boxes, Instances +from annotator.oneformer.detectron2.structures.boxes import pairwise_iou + +from ..config.config import CfgNode as CfgNode_ +from .base_tracker import TRACKER_HEADS_REGISTRY, BaseTracker + + +@TRACKER_HEADS_REGISTRY.register() +class BBoxIOUTracker(BaseTracker): + """ + A bounding box tracker to assign ID based on IoU between current and previous instances + """ + + @configurable + def __init__( + self, + *, + video_height: int, + video_width: int, + max_num_instances: int = 200, + max_lost_frame_count: int = 0, + min_box_rel_dim: float = 0.02, + min_instance_period: int = 1, + track_iou_threshold: float = 0.5, + **kwargs, + ): + """ + Args: + video_height: height the video frame + video_width: width of the video frame + max_num_instances: maximum number of id allowed to be tracked + max_lost_frame_count: maximum number of frame an id can lost tracking + exceed this number, an id is considered as lost + forever + min_box_rel_dim: a percentage, smaller than this dimension, a bbox is + removed from tracking + min_instance_period: an instance will be shown after this number of period + since its first showing up in the video + track_iou_threshold: iou threshold, below this number a bbox pair is removed + from tracking + """ + super().__init__(**kwargs) + self._video_height = video_height + self._video_width = video_width + self._max_num_instances = max_num_instances + self._max_lost_frame_count = max_lost_frame_count + self._min_box_rel_dim = min_box_rel_dim + self._min_instance_period = min_instance_period + self._track_iou_threshold = track_iou_threshold + + @classmethod + def from_config(cls, cfg: CfgNode_): + """ + Old style initialization using CfgNode + + Args: + cfg: D2 CfgNode, config file + Return: + dictionary storing arguments for __init__ method + """ + assert "VIDEO_HEIGHT" in cfg.TRACKER_HEADS + assert "VIDEO_WIDTH" in cfg.TRACKER_HEADS + video_height = cfg.TRACKER_HEADS.get("VIDEO_HEIGHT") + video_width = cfg.TRACKER_HEADS.get("VIDEO_WIDTH") + max_num_instances = cfg.TRACKER_HEADS.get("MAX_NUM_INSTANCES", 200) + max_lost_frame_count = cfg.TRACKER_HEADS.get("MAX_LOST_FRAME_COUNT", 0) + min_box_rel_dim = cfg.TRACKER_HEADS.get("MIN_BOX_REL_DIM", 0.02) + min_instance_period = cfg.TRACKER_HEADS.get("MIN_INSTANCE_PERIOD", 1) + track_iou_threshold = cfg.TRACKER_HEADS.get("TRACK_IOU_THRESHOLD", 0.5) + return { + "_target_": "detectron2.tracking.bbox_iou_tracker.BBoxIOUTracker", + "video_height": video_height, + "video_width": video_width, + "max_num_instances": max_num_instances, + "max_lost_frame_count": max_lost_frame_count, + "min_box_rel_dim": min_box_rel_dim, + "min_instance_period": min_instance_period, + "track_iou_threshold": track_iou_threshold, + } + + def update(self, instances: Instances) -> Instances: + """ + See BaseTracker description + """ + instances = self._initialize_extra_fields(instances) + if self._prev_instances is not None: + # calculate IoU of all bbox pairs + iou_all = pairwise_iou( + boxes1=instances.pred_boxes, + boxes2=self._prev_instances.pred_boxes, + ) + # sort IoU in descending order + bbox_pairs = self._create_prediction_pairs(instances, iou_all) + # assign previous ID to current bbox if IoU > track_iou_threshold + self._reset_fields() + for bbox_pair in bbox_pairs: + idx = bbox_pair["idx"] + prev_id = bbox_pair["prev_id"] + if ( + idx in self._matched_idx + or prev_id in self._matched_ID + or bbox_pair["IoU"] < self._track_iou_threshold + ): + continue + instances.ID[idx] = prev_id + instances.ID_period[idx] = bbox_pair["prev_period"] + 1 + instances.lost_frame_count[idx] = 0 + self._matched_idx.add(idx) + self._matched_ID.add(prev_id) + self._untracked_prev_idx.remove(bbox_pair["prev_idx"]) + instances = self._assign_new_id(instances) + instances = self._merge_untracked_instances(instances) + self._prev_instances = copy.deepcopy(instances) + return instances + + def _create_prediction_pairs(self, instances: Instances, iou_all: np.ndarray) -> List: + """ + For all instances in previous and current frames, create pairs. For each + pair, store index of the instance in current frame predcitions, index in + previous predictions, ID in previous predictions, IoU of the bboxes in this + pair, period in previous predictions. + + Args: + instances: D2 Instances, for predictions of the current frame + iou_all: IoU for all bboxes pairs + Return: + A list of IoU for all pairs + """ + bbox_pairs = [] + for i in range(len(instances)): + for j in range(len(self._prev_instances)): + bbox_pairs.append( + { + "idx": i, + "prev_idx": j, + "prev_id": self._prev_instances.ID[j], + "IoU": iou_all[i, j], + "prev_period": self._prev_instances.ID_period[j], + } + ) + return bbox_pairs + + def _initialize_extra_fields(self, instances: Instances) -> Instances: + """ + If input instances don't have ID, ID_period, lost_frame_count fields, + this method is used to initialize these fields. + + Args: + instances: D2 Instances, for predictions of the current frame + Return: + D2 Instances with extra fields added + """ + if not instances.has("ID"): + instances.set("ID", [None] * len(instances)) + if not instances.has("ID_period"): + instances.set("ID_period", [None] * len(instances)) + if not instances.has("lost_frame_count"): + instances.set("lost_frame_count", [None] * len(instances)) + if self._prev_instances is None: + instances.ID = list(range(len(instances))) + self._id_count += len(instances) + instances.ID_period = [1] * len(instances) + instances.lost_frame_count = [0] * len(instances) + return instances + + def _reset_fields(self): + """ + Before each uodate call, reset fields first + """ + self._matched_idx = set() + self._matched_ID = set() + self._untracked_prev_idx = set(range(len(self._prev_instances))) + + def _assign_new_id(self, instances: Instances) -> Instances: + """ + For each untracked instance, assign a new id + + Args: + instances: D2 Instances, for predictions of the current frame + Return: + D2 Instances with new ID assigned + """ + untracked_idx = set(range(len(instances))).difference(self._matched_idx) + for idx in untracked_idx: + instances.ID[idx] = self._id_count + self._id_count += 1 + instances.ID_period[idx] = 1 + instances.lost_frame_count[idx] = 0 + return instances + + def _merge_untracked_instances(self, instances: Instances) -> Instances: + """ + For untracked previous instances, under certain condition, still keep them + in tracking and merge with the current instances. + + Args: + instances: D2 Instances, for predictions of the current frame + Return: + D2 Instances merging current instances and instances from previous + frame decided to keep tracking + """ + untracked_instances = Instances( + image_size=instances.image_size, + pred_boxes=[], + pred_classes=[], + scores=[], + ID=[], + ID_period=[], + lost_frame_count=[], + ) + prev_bboxes = list(self._prev_instances.pred_boxes) + prev_classes = list(self._prev_instances.pred_classes) + prev_scores = list(self._prev_instances.scores) + prev_ID_period = self._prev_instances.ID_period + if instances.has("pred_masks"): + untracked_instances.set("pred_masks", []) + prev_masks = list(self._prev_instances.pred_masks) + if instances.has("pred_keypoints"): + untracked_instances.set("pred_keypoints", []) + prev_keypoints = list(self._prev_instances.pred_keypoints) + if instances.has("pred_keypoint_heatmaps"): + untracked_instances.set("pred_keypoint_heatmaps", []) + prev_keypoint_heatmaps = list(self._prev_instances.pred_keypoint_heatmaps) + for idx in self._untracked_prev_idx: + x_left, y_top, x_right, y_bot = prev_bboxes[idx] + if ( + (1.0 * (x_right - x_left) / self._video_width < self._min_box_rel_dim) + or (1.0 * (y_bot - y_top) / self._video_height < self._min_box_rel_dim) + or self._prev_instances.lost_frame_count[idx] >= self._max_lost_frame_count + or prev_ID_period[idx] <= self._min_instance_period + ): + continue + untracked_instances.pred_boxes.append(list(prev_bboxes[idx].numpy())) + untracked_instances.pred_classes.append(int(prev_classes[idx])) + untracked_instances.scores.append(float(prev_scores[idx])) + untracked_instances.ID.append(self._prev_instances.ID[idx]) + untracked_instances.ID_period.append(self._prev_instances.ID_period[idx]) + untracked_instances.lost_frame_count.append( + self._prev_instances.lost_frame_count[idx] + 1 + ) + if instances.has("pred_masks"): + untracked_instances.pred_masks.append(prev_masks[idx].numpy().astype(np.uint8)) + if instances.has("pred_keypoints"): + untracked_instances.pred_keypoints.append( + prev_keypoints[idx].numpy().astype(np.uint8) + ) + if instances.has("pred_keypoint_heatmaps"): + untracked_instances.pred_keypoint_heatmaps.append( + prev_keypoint_heatmaps[idx].numpy().astype(np.float32) + ) + untracked_instances.pred_boxes = Boxes(torch.FloatTensor(untracked_instances.pred_boxes)) + untracked_instances.pred_classes = torch.IntTensor(untracked_instances.pred_classes) + untracked_instances.scores = torch.FloatTensor(untracked_instances.scores) + if instances.has("pred_masks"): + untracked_instances.pred_masks = torch.IntTensor(untracked_instances.pred_masks) + if instances.has("pred_keypoints"): + untracked_instances.pred_keypoints = torch.IntTensor(untracked_instances.pred_keypoints) + if instances.has("pred_keypoint_heatmaps"): + untracked_instances.pred_keypoint_heatmaps = torch.FloatTensor( + untracked_instances.pred_keypoint_heatmaps + ) + + return Instances.cat( + [ + instances, + untracked_instances, + ] + ) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/hungarian_tracker.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/hungarian_tracker.py new file mode 100644 index 00000000..bb2b368c --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/hungarian_tracker.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python3 +# Copyright 2004-present Facebook. All Rights Reserved. +import copy +import numpy as np +from typing import Dict +import torch +from scipy.optimize import linear_sum_assignment + +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.structures import Boxes, Instances + +from ..config.config import CfgNode as CfgNode_ +from .base_tracker import BaseTracker + + +class BaseHungarianTracker(BaseTracker): + """ + A base class for all Hungarian trackers + """ + + @configurable + def __init__( + self, + video_height: int, + video_width: int, + max_num_instances: int = 200, + max_lost_frame_count: int = 0, + min_box_rel_dim: float = 0.02, + min_instance_period: int = 1, + **kwargs + ): + """ + Args: + video_height: height the video frame + video_width: width of the video frame + max_num_instances: maximum number of id allowed to be tracked + max_lost_frame_count: maximum number of frame an id can lost tracking + exceed this number, an id is considered as lost + forever + min_box_rel_dim: a percentage, smaller than this dimension, a bbox is + removed from tracking + min_instance_period: an instance will be shown after this number of period + since its first showing up in the video + """ + super().__init__(**kwargs) + self._video_height = video_height + self._video_width = video_width + self._max_num_instances = max_num_instances + self._max_lost_frame_count = max_lost_frame_count + self._min_box_rel_dim = min_box_rel_dim + self._min_instance_period = min_instance_period + + @classmethod + def from_config(cls, cfg: CfgNode_) -> Dict: + raise NotImplementedError("Calling HungarianTracker::from_config") + + def build_cost_matrix(self, instances: Instances, prev_instances: Instances) -> np.ndarray: + raise NotImplementedError("Calling HungarianTracker::build_matrix") + + def update(self, instances: Instances) -> Instances: + if instances.has("pred_keypoints"): + raise NotImplementedError("Need to add support for keypoints") + instances = self._initialize_extra_fields(instances) + if self._prev_instances is not None: + self._untracked_prev_idx = set(range(len(self._prev_instances))) + cost_matrix = self.build_cost_matrix(instances, self._prev_instances) + matched_idx, matched_prev_idx = linear_sum_assignment(cost_matrix) + instances = self._process_matched_idx(instances, matched_idx, matched_prev_idx) + instances = self._process_unmatched_idx(instances, matched_idx) + instances = self._process_unmatched_prev_idx(instances, matched_prev_idx) + self._prev_instances = copy.deepcopy(instances) + return instances + + def _initialize_extra_fields(self, instances: Instances) -> Instances: + """ + If input instances don't have ID, ID_period, lost_frame_count fields, + this method is used to initialize these fields. + + Args: + instances: D2 Instances, for predictions of the current frame + Return: + D2 Instances with extra fields added + """ + if not instances.has("ID"): + instances.set("ID", [None] * len(instances)) + if not instances.has("ID_period"): + instances.set("ID_period", [None] * len(instances)) + if not instances.has("lost_frame_count"): + instances.set("lost_frame_count", [None] * len(instances)) + if self._prev_instances is None: + instances.ID = list(range(len(instances))) + self._id_count += len(instances) + instances.ID_period = [1] * len(instances) + instances.lost_frame_count = [0] * len(instances) + return instances + + def _process_matched_idx( + self, instances: Instances, matched_idx: np.ndarray, matched_prev_idx: np.ndarray + ) -> Instances: + assert matched_idx.size == matched_prev_idx.size + for i in range(matched_idx.size): + instances.ID[matched_idx[i]] = self._prev_instances.ID[matched_prev_idx[i]] + instances.ID_period[matched_idx[i]] = ( + self._prev_instances.ID_period[matched_prev_idx[i]] + 1 + ) + instances.lost_frame_count[matched_idx[i]] = 0 + return instances + + def _process_unmatched_idx(self, instances: Instances, matched_idx: np.ndarray) -> Instances: + untracked_idx = set(range(len(instances))).difference(set(matched_idx)) + for idx in untracked_idx: + instances.ID[idx] = self._id_count + self._id_count += 1 + instances.ID_period[idx] = 1 + instances.lost_frame_count[idx] = 0 + return instances + + def _process_unmatched_prev_idx( + self, instances: Instances, matched_prev_idx: np.ndarray + ) -> Instances: + untracked_instances = Instances( + image_size=instances.image_size, + pred_boxes=[], + pred_masks=[], + pred_classes=[], + scores=[], + ID=[], + ID_period=[], + lost_frame_count=[], + ) + prev_bboxes = list(self._prev_instances.pred_boxes) + prev_classes = list(self._prev_instances.pred_classes) + prev_scores = list(self._prev_instances.scores) + prev_ID_period = self._prev_instances.ID_period + if instances.has("pred_masks"): + prev_masks = list(self._prev_instances.pred_masks) + untracked_prev_idx = set(range(len(self._prev_instances))).difference(set(matched_prev_idx)) + for idx in untracked_prev_idx: + x_left, y_top, x_right, y_bot = prev_bboxes[idx] + if ( + (1.0 * (x_right - x_left) / self._video_width < self._min_box_rel_dim) + or (1.0 * (y_bot - y_top) / self._video_height < self._min_box_rel_dim) + or self._prev_instances.lost_frame_count[idx] >= self._max_lost_frame_count + or prev_ID_period[idx] <= self._min_instance_period + ): + continue + untracked_instances.pred_boxes.append(list(prev_bboxes[idx].numpy())) + untracked_instances.pred_classes.append(int(prev_classes[idx])) + untracked_instances.scores.append(float(prev_scores[idx])) + untracked_instances.ID.append(self._prev_instances.ID[idx]) + untracked_instances.ID_period.append(self._prev_instances.ID_period[idx]) + untracked_instances.lost_frame_count.append( + self._prev_instances.lost_frame_count[idx] + 1 + ) + if instances.has("pred_masks"): + untracked_instances.pred_masks.append(prev_masks[idx].numpy().astype(np.uint8)) + + untracked_instances.pred_boxes = Boxes(torch.FloatTensor(untracked_instances.pred_boxes)) + untracked_instances.pred_classes = torch.IntTensor(untracked_instances.pred_classes) + untracked_instances.scores = torch.FloatTensor(untracked_instances.scores) + if instances.has("pred_masks"): + untracked_instances.pred_masks = torch.IntTensor(untracked_instances.pred_masks) + else: + untracked_instances.remove("pred_masks") + + return Instances.cat( + [ + instances, + untracked_instances, + ] + ) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/iou_weighted_hungarian_bbox_iou_tracker.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/iou_weighted_hungarian_bbox_iou_tracker.py new file mode 100644 index 00000000..e9b40f8a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/iou_weighted_hungarian_bbox_iou_tracker.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 +# Copyright 2004-present Facebook. All Rights Reserved. + +import numpy as np +from typing import List + +from annotator.oneformer.detectron2.config import CfgNode as CfgNode_ +from annotator.oneformer.detectron2.config import configurable + +from .base_tracker import TRACKER_HEADS_REGISTRY +from .vanilla_hungarian_bbox_iou_tracker import VanillaHungarianBBoxIOUTracker + + +@TRACKER_HEADS_REGISTRY.register() +class IOUWeightedHungarianBBoxIOUTracker(VanillaHungarianBBoxIOUTracker): + """ + A tracker using IoU as weight in Hungarian algorithm, also known + as Munkres or Kuhn-Munkres algorithm + """ + + @configurable + def __init__( + self, + *, + video_height: int, + video_width: int, + max_num_instances: int = 200, + max_lost_frame_count: int = 0, + min_box_rel_dim: float = 0.02, + min_instance_period: int = 1, + track_iou_threshold: float = 0.5, + **kwargs, + ): + """ + Args: + video_height: height the video frame + video_width: width of the video frame + max_num_instances: maximum number of id allowed to be tracked + max_lost_frame_count: maximum number of frame an id can lost tracking + exceed this number, an id is considered as lost + forever + min_box_rel_dim: a percentage, smaller than this dimension, a bbox is + removed from tracking + min_instance_period: an instance will be shown after this number of period + since its first showing up in the video + track_iou_threshold: iou threshold, below this number a bbox pair is removed + from tracking + """ + super().__init__( + video_height=video_height, + video_width=video_width, + max_num_instances=max_num_instances, + max_lost_frame_count=max_lost_frame_count, + min_box_rel_dim=min_box_rel_dim, + min_instance_period=min_instance_period, + track_iou_threshold=track_iou_threshold, + ) + + @classmethod + def from_config(cls, cfg: CfgNode_): + """ + Old style initialization using CfgNode + + Args: + cfg: D2 CfgNode, config file + Return: + dictionary storing arguments for __init__ method + """ + assert "VIDEO_HEIGHT" in cfg.TRACKER_HEADS + assert "VIDEO_WIDTH" in cfg.TRACKER_HEADS + video_height = cfg.TRACKER_HEADS.get("VIDEO_HEIGHT") + video_width = cfg.TRACKER_HEADS.get("VIDEO_WIDTH") + max_num_instances = cfg.TRACKER_HEADS.get("MAX_NUM_INSTANCES", 200) + max_lost_frame_count = cfg.TRACKER_HEADS.get("MAX_LOST_FRAME_COUNT", 0) + min_box_rel_dim = cfg.TRACKER_HEADS.get("MIN_BOX_REL_DIM", 0.02) + min_instance_period = cfg.TRACKER_HEADS.get("MIN_INSTANCE_PERIOD", 1) + track_iou_threshold = cfg.TRACKER_HEADS.get("TRACK_IOU_THRESHOLD", 0.5) + return { + "_target_": "detectron2.tracking.iou_weighted_hungarian_bbox_iou_tracker.IOUWeightedHungarianBBoxIOUTracker", # noqa + "video_height": video_height, + "video_width": video_width, + "max_num_instances": max_num_instances, + "max_lost_frame_count": max_lost_frame_count, + "min_box_rel_dim": min_box_rel_dim, + "min_instance_period": min_instance_period, + "track_iou_threshold": track_iou_threshold, + } + + def assign_cost_matrix_values(self, cost_matrix: np.ndarray, bbox_pairs: List) -> np.ndarray: + """ + Based on IoU for each pair of bbox, assign the associated value in cost matrix + + Args: + cost_matrix: np.ndarray, initialized 2D array with target dimensions + bbox_pairs: list of bbox pair, in each pair, iou value is stored + Return: + np.ndarray, cost_matrix with assigned values + """ + for pair in bbox_pairs: + # assign (-1 * IoU) for above threshold pairs, algorithms will minimize cost + cost_matrix[pair["idx"]][pair["prev_idx"]] = -1 * pair["IoU"] + return cost_matrix diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/utils.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/utils.py new file mode 100644 index 00000000..78d19984 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/utils.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +import numpy as np +from typing import List + +from annotator.oneformer.detectron2.structures import Instances + + +def create_prediction_pairs( + instances: Instances, + prev_instances: Instances, + iou_all: np.ndarray, + threshold: float = 0.5, +) -> List: + """ + Args: + instances: predictions from current frame + prev_instances: predictions from previous frame + iou_all: 2D numpy array containing iou for each bbox pair + threshold: below the threshold, doesn't consider the pair of bbox is valid + Return: + List of bbox pairs + """ + bbox_pairs = [] + for i in range(len(instances)): + for j in range(len(prev_instances)): + if iou_all[i, j] < threshold: + continue + bbox_pairs.append( + { + "idx": i, + "prev_idx": j, + "prev_id": prev_instances.ID[j], + "IoU": iou_all[i, j], + "prev_period": prev_instances.ID_period[j], + } + ) + return bbox_pairs + + +LARGE_COST_VALUE = 100000 diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/vanilla_hungarian_bbox_iou_tracker.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/vanilla_hungarian_bbox_iou_tracker.py new file mode 100644 index 00000000..eecfe2f3 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/tracking/vanilla_hungarian_bbox_iou_tracker.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python3 +# Copyright 2004-present Facebook. All Rights Reserved. + +import numpy as np +from typing import List + +from annotator.oneformer.detectron2.config import CfgNode as CfgNode_ +from annotator.oneformer.detectron2.config import configurable +from annotator.oneformer.detectron2.structures import Instances +from annotator.oneformer.detectron2.structures.boxes import pairwise_iou +from annotator.oneformer.detectron2.tracking.utils import LARGE_COST_VALUE, create_prediction_pairs + +from .base_tracker import TRACKER_HEADS_REGISTRY +from .hungarian_tracker import BaseHungarianTracker + + +@TRACKER_HEADS_REGISTRY.register() +class VanillaHungarianBBoxIOUTracker(BaseHungarianTracker): + """ + Hungarian algo based tracker using bbox iou as metric + """ + + @configurable + def __init__( + self, + *, + video_height: int, + video_width: int, + max_num_instances: int = 200, + max_lost_frame_count: int = 0, + min_box_rel_dim: float = 0.02, + min_instance_period: int = 1, + track_iou_threshold: float = 0.5, + **kwargs, + ): + """ + Args: + video_height: height the video frame + video_width: width of the video frame + max_num_instances: maximum number of id allowed to be tracked + max_lost_frame_count: maximum number of frame an id can lost tracking + exceed this number, an id is considered as lost + forever + min_box_rel_dim: a percentage, smaller than this dimension, a bbox is + removed from tracking + min_instance_period: an instance will be shown after this number of period + since its first showing up in the video + track_iou_threshold: iou threshold, below this number a bbox pair is removed + from tracking + """ + super().__init__( + video_height=video_height, + video_width=video_width, + max_num_instances=max_num_instances, + max_lost_frame_count=max_lost_frame_count, + min_box_rel_dim=min_box_rel_dim, + min_instance_period=min_instance_period, + ) + self._track_iou_threshold = track_iou_threshold + + @classmethod + def from_config(cls, cfg: CfgNode_): + """ + Old style initialization using CfgNode + + Args: + cfg: D2 CfgNode, config file + Return: + dictionary storing arguments for __init__ method + """ + assert "VIDEO_HEIGHT" in cfg.TRACKER_HEADS + assert "VIDEO_WIDTH" in cfg.TRACKER_HEADS + video_height = cfg.TRACKER_HEADS.get("VIDEO_HEIGHT") + video_width = cfg.TRACKER_HEADS.get("VIDEO_WIDTH") + max_num_instances = cfg.TRACKER_HEADS.get("MAX_NUM_INSTANCES", 200) + max_lost_frame_count = cfg.TRACKER_HEADS.get("MAX_LOST_FRAME_COUNT", 0) + min_box_rel_dim = cfg.TRACKER_HEADS.get("MIN_BOX_REL_DIM", 0.02) + min_instance_period = cfg.TRACKER_HEADS.get("MIN_INSTANCE_PERIOD", 1) + track_iou_threshold = cfg.TRACKER_HEADS.get("TRACK_IOU_THRESHOLD", 0.5) + return { + "_target_": "detectron2.tracking.vanilla_hungarian_bbox_iou_tracker.VanillaHungarianBBoxIOUTracker", # noqa + "video_height": video_height, + "video_width": video_width, + "max_num_instances": max_num_instances, + "max_lost_frame_count": max_lost_frame_count, + "min_box_rel_dim": min_box_rel_dim, + "min_instance_period": min_instance_period, + "track_iou_threshold": track_iou_threshold, + } + + def build_cost_matrix(self, instances: Instances, prev_instances: Instances) -> np.ndarray: + """ + Build the cost matrix for assignment problem + (https://en.wikipedia.org/wiki/Assignment_problem) + + Args: + instances: D2 Instances, for current frame predictions + prev_instances: D2 Instances, for previous frame predictions + + Return: + the cost matrix in numpy array + """ + assert instances is not None and prev_instances is not None + # calculate IoU of all bbox pairs + iou_all = pairwise_iou( + boxes1=instances.pred_boxes, + boxes2=self._prev_instances.pred_boxes, + ) + bbox_pairs = create_prediction_pairs( + instances, self._prev_instances, iou_all, threshold=self._track_iou_threshold + ) + # assign large cost value to make sure pair below IoU threshold won't be matched + cost_matrix = np.full((len(instances), len(prev_instances)), LARGE_COST_VALUE) + return self.assign_cost_matrix_values(cost_matrix, bbox_pairs) + + def assign_cost_matrix_values(self, cost_matrix: np.ndarray, bbox_pairs: List) -> np.ndarray: + """ + Based on IoU for each pair of bbox, assign the associated value in cost matrix + + Args: + cost_matrix: np.ndarray, initialized 2D array with target dimensions + bbox_pairs: list of bbox pair, in each pair, iou value is stored + Return: + np.ndarray, cost_matrix with assigned values + """ + for pair in bbox_pairs: + # assign -1 for IoU above threshold pairs, algorithms will minimize cost + cost_matrix[pair["idx"]][pair["prev_idx"]] = -1 + return cost_matrix diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/README.md b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/README.md new file mode 100644 index 00000000..9765b24a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/README.md @@ -0,0 +1,5 @@ +# Utility functions + +This folder contain utility functions that are not used in the +core library, but are useful for building models or training +code using the config system. diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/__init__.py new file mode 100644 index 00000000..9020c2df --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/__init__.py @@ -0,0 +1 @@ +# Copyright (c) Facebook, Inc. and its affiliates. diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/analysis.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/analysis.py new file mode 100644 index 00000000..d63e14bc --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/analysis.py @@ -0,0 +1,188 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# -*- coding: utf-8 -*- + +import typing +from typing import Any, List +import fvcore +from fvcore.nn import activation_count, flop_count, parameter_count, parameter_count_table +from torch import nn + +from annotator.oneformer.detectron2.export import TracingAdapter + +__all__ = [ + "activation_count_operators", + "flop_count_operators", + "parameter_count_table", + "parameter_count", + "FlopCountAnalysis", +] + +FLOPS_MODE = "flops" +ACTIVATIONS_MODE = "activations" + + +# Some extra ops to ignore from counting, including elementwise and reduction ops +_IGNORED_OPS = { + "aten::add", + "aten::add_", + "aten::argmax", + "aten::argsort", + "aten::batch_norm", + "aten::constant_pad_nd", + "aten::div", + "aten::div_", + "aten::exp", + "aten::log2", + "aten::max_pool2d", + "aten::meshgrid", + "aten::mul", + "aten::mul_", + "aten::neg", + "aten::nonzero_numpy", + "aten::reciprocal", + "aten::repeat_interleave", + "aten::rsub", + "aten::sigmoid", + "aten::sigmoid_", + "aten::softmax", + "aten::sort", + "aten::sqrt", + "aten::sub", + "torchvision::nms", # TODO estimate flop for nms +} + + +class FlopCountAnalysis(fvcore.nn.FlopCountAnalysis): + """ + Same as :class:`fvcore.nn.FlopCountAnalysis`, but supports detectron2 models. + """ + + def __init__(self, model, inputs): + """ + Args: + model (nn.Module): + inputs (Any): inputs of the given model. Does not have to be tuple of tensors. + """ + wrapper = TracingAdapter(model, inputs, allow_non_tensor=True) + super().__init__(wrapper, wrapper.flattened_inputs) + self.set_op_handle(**{k: None for k in _IGNORED_OPS}) + + +def flop_count_operators(model: nn.Module, inputs: list) -> typing.DefaultDict[str, float]: + """ + Implement operator-level flops counting using jit. + This is a wrapper of :func:`fvcore.nn.flop_count` and adds supports for standard + detection models in detectron2. + Please use :class:`FlopCountAnalysis` for more advanced functionalities. + + Note: + The function runs the input through the model to compute flops. + The flops of a detection model is often input-dependent, for example, + the flops of box & mask head depends on the number of proposals & + the number of detected objects. + Therefore, the flops counting using a single input may not accurately + reflect the computation cost of a model. It's recommended to average + across a number of inputs. + + Args: + model: a detectron2 model that takes `list[dict]` as input. + inputs (list[dict]): inputs to model, in detectron2's standard format. + Only "image" key will be used. + supported_ops (dict[str, Handle]): see documentation of :func:`fvcore.nn.flop_count` + + Returns: + Counter: Gflop count per operator + """ + old_train = model.training + model.eval() + ret = FlopCountAnalysis(model, inputs).by_operator() + model.train(old_train) + return {k: v / 1e9 for k, v in ret.items()} + + +def activation_count_operators( + model: nn.Module, inputs: list, **kwargs +) -> typing.DefaultDict[str, float]: + """ + Implement operator-level activations counting using jit. + This is a wrapper of fvcore.nn.activation_count, that supports standard detection models + in detectron2. + + Note: + The function runs the input through the model to compute activations. + The activations of a detection model is often input-dependent, for example, + the activations of box & mask head depends on the number of proposals & + the number of detected objects. + + Args: + model: a detectron2 model that takes `list[dict]` as input. + inputs (list[dict]): inputs to model, in detectron2's standard format. + Only "image" key will be used. + + Returns: + Counter: activation count per operator + """ + return _wrapper_count_operators(model=model, inputs=inputs, mode=ACTIVATIONS_MODE, **kwargs) + + +def _wrapper_count_operators( + model: nn.Module, inputs: list, mode: str, **kwargs +) -> typing.DefaultDict[str, float]: + # ignore some ops + supported_ops = {k: lambda *args, **kwargs: {} for k in _IGNORED_OPS} + supported_ops.update(kwargs.pop("supported_ops", {})) + kwargs["supported_ops"] = supported_ops + + assert len(inputs) == 1, "Please use batch size=1" + tensor_input = inputs[0]["image"] + inputs = [{"image": tensor_input}] # remove other keys, in case there are any + + old_train = model.training + if isinstance(model, (nn.parallel.distributed.DistributedDataParallel, nn.DataParallel)): + model = model.module + wrapper = TracingAdapter(model, inputs) + wrapper.eval() + if mode == FLOPS_MODE: + ret = flop_count(wrapper, (tensor_input,), **kwargs) + elif mode == ACTIVATIONS_MODE: + ret = activation_count(wrapper, (tensor_input,), **kwargs) + else: + raise NotImplementedError("Count for mode {} is not supported yet.".format(mode)) + # compatible with change in fvcore + if isinstance(ret, tuple): + ret = ret[0] + model.train(old_train) + return ret + + +def find_unused_parameters(model: nn.Module, inputs: Any) -> List[str]: + """ + Given a model, find parameters that do not contribute + to the loss. + + Args: + model: a model in training mode that returns losses + inputs: argument or a tuple of arguments. Inputs of the model + + Returns: + list[str]: the name of unused parameters + """ + assert model.training + for _, prm in model.named_parameters(): + prm.grad = None + + if isinstance(inputs, tuple): + losses = model(*inputs) + else: + losses = model(inputs) + + if isinstance(losses, dict): + losses = sum(losses.values()) + losses.backward() + + unused: List[str] = [] + for name, prm in model.named_parameters(): + if prm.grad is None: + unused.append(name) + prm.grad = None + return unused diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/collect_env.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/collect_env.py new file mode 100644 index 00000000..bb25d297 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/collect_env.py @@ -0,0 +1,246 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import importlib +import numpy as np +import os +import re +import subprocess +import sys +from collections import defaultdict +import PIL +import torch +import torchvision +from tabulate import tabulate + +__all__ = ["collect_env_info"] + + +def collect_torch_env(): + try: + import torch.__config__ + + return torch.__config__.show() + except ImportError: + # compatible with older versions of pytorch + from torch.utils.collect_env import get_pretty_env_info + + return get_pretty_env_info() + + +def get_env_module(): + var_name = "DETECTRON2_ENV_MODULE" + return var_name, os.environ.get(var_name, "") + + +def detect_compute_compatibility(CUDA_HOME, so_file): + try: + cuobjdump = os.path.join(CUDA_HOME, "bin", "cuobjdump") + if os.path.isfile(cuobjdump): + output = subprocess.check_output( + "'{}' --list-elf '{}'".format(cuobjdump, so_file), shell=True + ) + output = output.decode("utf-8").strip().split("\n") + arch = [] + for line in output: + line = re.findall(r"\.sm_([0-9]*)\.", line)[0] + arch.append(".".join(line)) + arch = sorted(set(arch)) + return ", ".join(arch) + else: + return so_file + "; cannot find cuobjdump" + except Exception: + # unhandled failure + return so_file + + +def collect_env_info(): + has_gpu = torch.cuda.is_available() # true for both CUDA & ROCM + torch_version = torch.__version__ + + # NOTE that CUDA_HOME/ROCM_HOME could be None even when CUDA runtime libs are functional + from torch.utils.cpp_extension import CUDA_HOME, ROCM_HOME + + has_rocm = False + if (getattr(torch.version, "hip", None) is not None) and (ROCM_HOME is not None): + has_rocm = True + has_cuda = has_gpu and (not has_rocm) + + data = [] + data.append(("sys.platform", sys.platform)) # check-template.yml depends on it + data.append(("Python", sys.version.replace("\n", ""))) + data.append(("numpy", np.__version__)) + + try: + import annotator.oneformer.detectron2 # noqa + + data.append( + ("detectron2", detectron2.__version__ + " @" + os.path.dirname(detectron2.__file__)) + ) + except ImportError: + data.append(("detectron2", "failed to import")) + except AttributeError: + data.append(("detectron2", "imported a wrong installation")) + + try: + import annotator.oneformer.detectron2._C as _C + except ImportError as e: + data.append(("detectron2._C", f"not built correctly: {e}")) + + # print system compilers when extension fails to build + if sys.platform != "win32": # don't know what to do for windows + try: + # this is how torch/utils/cpp_extensions.py choose compiler + cxx = os.environ.get("CXX", "c++") + cxx = subprocess.check_output("'{}' --version".format(cxx), shell=True) + cxx = cxx.decode("utf-8").strip().split("\n")[0] + except subprocess.SubprocessError: + cxx = "Not found" + data.append(("Compiler ($CXX)", cxx)) + + if has_cuda and CUDA_HOME is not None: + try: + nvcc = os.path.join(CUDA_HOME, "bin", "nvcc") + nvcc = subprocess.check_output("'{}' -V".format(nvcc), shell=True) + nvcc = nvcc.decode("utf-8").strip().split("\n")[-1] + except subprocess.SubprocessError: + nvcc = "Not found" + data.append(("CUDA compiler", nvcc)) + if has_cuda and sys.platform != "win32": + try: + so_file = importlib.util.find_spec("detectron2._C").origin + except (ImportError, AttributeError): + pass + else: + data.append( + ("detectron2 arch flags", detect_compute_compatibility(CUDA_HOME, so_file)) + ) + else: + # print compilers that are used to build extension + data.append(("Compiler", _C.get_compiler_version())) + data.append(("CUDA compiler", _C.get_cuda_version())) # cuda or hip + if has_cuda and getattr(_C, "has_cuda", lambda: True)(): + data.append( + ("detectron2 arch flags", detect_compute_compatibility(CUDA_HOME, _C.__file__)) + ) + + data.append(get_env_module()) + data.append(("PyTorch", torch_version + " @" + os.path.dirname(torch.__file__))) + data.append(("PyTorch debug build", torch.version.debug)) + try: + data.append(("torch._C._GLIBCXX_USE_CXX11_ABI", torch._C._GLIBCXX_USE_CXX11_ABI)) + except Exception: + pass + + if not has_gpu: + has_gpu_text = "No: torch.cuda.is_available() == False" + else: + has_gpu_text = "Yes" + data.append(("GPU available", has_gpu_text)) + if has_gpu: + devices = defaultdict(list) + for k in range(torch.cuda.device_count()): + cap = ".".join((str(x) for x in torch.cuda.get_device_capability(k))) + name = torch.cuda.get_device_name(k) + f" (arch={cap})" + devices[name].append(str(k)) + for name, devids in devices.items(): + data.append(("GPU " + ",".join(devids), name)) + + if has_rocm: + msg = " - invalid!" if not (ROCM_HOME and os.path.isdir(ROCM_HOME)) else "" + data.append(("ROCM_HOME", str(ROCM_HOME) + msg)) + else: + try: + from torch.utils.collect_env import get_nvidia_driver_version, run as _run + + data.append(("Driver version", get_nvidia_driver_version(_run))) + except Exception: + pass + msg = " - invalid!" if not (CUDA_HOME and os.path.isdir(CUDA_HOME)) else "" + data.append(("CUDA_HOME", str(CUDA_HOME) + msg)) + + cuda_arch_list = os.environ.get("TORCH_CUDA_ARCH_LIST", None) + if cuda_arch_list: + data.append(("TORCH_CUDA_ARCH_LIST", cuda_arch_list)) + data.append(("Pillow", PIL.__version__)) + + try: + data.append( + ( + "torchvision", + str(torchvision.__version__) + " @" + os.path.dirname(torchvision.__file__), + ) + ) + if has_cuda: + try: + torchvision_C = importlib.util.find_spec("torchvision._C").origin + msg = detect_compute_compatibility(CUDA_HOME, torchvision_C) + data.append(("torchvision arch flags", msg)) + except (ImportError, AttributeError): + data.append(("torchvision._C", "Not found")) + except AttributeError: + data.append(("torchvision", "unknown")) + + try: + import fvcore + + data.append(("fvcore", fvcore.__version__)) + except (ImportError, AttributeError): + pass + + try: + import iopath + + data.append(("iopath", iopath.__version__)) + except (ImportError, AttributeError): + pass + + try: + import cv2 + + data.append(("cv2", cv2.__version__)) + except (ImportError, AttributeError): + data.append(("cv2", "Not found")) + env_str = tabulate(data) + "\n" + env_str += collect_torch_env() + return env_str + + +def test_nccl_ops(): + num_gpu = torch.cuda.device_count() + if os.access("/tmp", os.W_OK): + import torch.multiprocessing as mp + + dist_url = "file:///tmp/nccl_tmp_file" + print("Testing NCCL connectivity ... this should not hang.") + mp.spawn(_test_nccl_worker, nprocs=num_gpu, args=(num_gpu, dist_url), daemon=False) + print("NCCL succeeded.") + + +def _test_nccl_worker(rank, num_gpu, dist_url): + import torch.distributed as dist + + dist.init_process_group(backend="NCCL", init_method=dist_url, rank=rank, world_size=num_gpu) + dist.barrier(device_ids=[rank]) + + +if __name__ == "__main__": + try: + from annotator.oneformer.detectron2.utils.collect_env import collect_env_info as f + + print(f()) + except ImportError: + print(collect_env_info()) + + if torch.cuda.is_available(): + num_gpu = torch.cuda.device_count() + for k in range(num_gpu): + device = f"cuda:{k}" + try: + x = torch.tensor([1, 2.0], dtype=torch.float32) + x = x.to(device) + except Exception as e: + print( + f"Unable to copy tensor to device={device}: {e}. " + "Your CUDA environment is broken." + ) + if num_gpu > 1: + test_nccl_ops() diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/colormap.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/colormap.py new file mode 100644 index 00000000..14ded165 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/colormap.py @@ -0,0 +1,158 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +""" +An awesome colormap for really neat visualizations. +Copied from Detectron, and removed gray colors. +""" + +import numpy as np +import random + +__all__ = ["colormap", "random_color", "random_colors"] + +# fmt: off +# RGB: +_COLORS = np.array( + [ + 0.000, 0.447, 0.741, + 0.850, 0.325, 0.098, + 0.929, 0.694, 0.125, + 0.494, 0.184, 0.556, + 0.466, 0.674, 0.188, + 0.301, 0.745, 0.933, + 0.635, 0.078, 0.184, + 0.300, 0.300, 0.300, + 0.600, 0.600, 0.600, + 1.000, 0.000, 0.000, + 1.000, 0.500, 0.000, + 0.749, 0.749, 0.000, + 0.000, 1.000, 0.000, + 0.000, 0.000, 1.000, + 0.667, 0.000, 1.000, + 0.333, 0.333, 0.000, + 0.333, 0.667, 0.000, + 0.333, 1.000, 0.000, + 0.667, 0.333, 0.000, + 0.667, 0.667, 0.000, + 0.667, 1.000, 0.000, + 1.000, 0.333, 0.000, + 1.000, 0.667, 0.000, + 1.000, 1.000, 0.000, + 0.000, 0.333, 0.500, + 0.000, 0.667, 0.500, + 0.000, 1.000, 0.500, + 0.333, 0.000, 0.500, + 0.333, 0.333, 0.500, + 0.333, 0.667, 0.500, + 0.333, 1.000, 0.500, + 0.667, 0.000, 0.500, + 0.667, 0.333, 0.500, + 0.667, 0.667, 0.500, + 0.667, 1.000, 0.500, + 1.000, 0.000, 0.500, + 1.000, 0.333, 0.500, + 1.000, 0.667, 0.500, + 1.000, 1.000, 0.500, + 0.000, 0.333, 1.000, + 0.000, 0.667, 1.000, + 0.000, 1.000, 1.000, + 0.333, 0.000, 1.000, + 0.333, 0.333, 1.000, + 0.333, 0.667, 1.000, + 0.333, 1.000, 1.000, + 0.667, 0.000, 1.000, + 0.667, 0.333, 1.000, + 0.667, 0.667, 1.000, + 0.667, 1.000, 1.000, + 1.000, 0.000, 1.000, + 1.000, 0.333, 1.000, + 1.000, 0.667, 1.000, + 0.333, 0.000, 0.000, + 0.500, 0.000, 0.000, + 0.667, 0.000, 0.000, + 0.833, 0.000, 0.000, + 1.000, 0.000, 0.000, + 0.000, 0.167, 0.000, + 0.000, 0.333, 0.000, + 0.000, 0.500, 0.000, + 0.000, 0.667, 0.000, + 0.000, 0.833, 0.000, + 0.000, 1.000, 0.000, + 0.000, 0.000, 0.167, + 0.000, 0.000, 0.333, + 0.000, 0.000, 0.500, + 0.000, 0.000, 0.667, + 0.000, 0.000, 0.833, + 0.000, 0.000, 1.000, + 0.000, 0.000, 0.000, + 0.143, 0.143, 0.143, + 0.857, 0.857, 0.857, + 1.000, 1.000, 1.000 + ] +).astype(np.float32).reshape(-1, 3) +# fmt: on + + +def colormap(rgb=False, maximum=255): + """ + Args: + rgb (bool): whether to return RGB colors or BGR colors. + maximum (int): either 255 or 1 + + Returns: + ndarray: a float32 array of Nx3 colors, in range [0, 255] or [0, 1] + """ + assert maximum in [255, 1], maximum + c = _COLORS * maximum + if not rgb: + c = c[:, ::-1] + return c + + +def random_color(rgb=False, maximum=255): + """ + Args: + rgb (bool): whether to return RGB colors or BGR colors. + maximum (int): either 255 or 1 + + Returns: + ndarray: a vector of 3 numbers + """ + idx = np.random.randint(0, len(_COLORS)) + ret = _COLORS[idx] * maximum + if not rgb: + ret = ret[::-1] + return ret + + +def random_colors(N, rgb=False, maximum=255): + """ + Args: + N (int): number of unique colors needed + rgb (bool): whether to return RGB colors or BGR colors. + maximum (int): either 255 or 1 + + Returns: + ndarray: a list of random_color + """ + indices = random.sample(range(len(_COLORS)), N) + ret = [_COLORS[i] * maximum for i in indices] + if not rgb: + ret = [x[::-1] for x in ret] + return ret + + +if __name__ == "__main__": + import cv2 + + size = 100 + H, W = 10, 10 + canvas = np.random.rand(H * size, W * size, 3).astype("float32") + for h in range(H): + for w in range(W): + idx = h * W + w + if idx >= len(_COLORS): + break + canvas[h * size : (h + 1) * size, w * size : (w + 1) * size] = _COLORS[idx] + cv2.imshow("a", canvas) + cv2.waitKey(0) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/comm.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/comm.py new file mode 100644 index 00000000..a9ea9a9f --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/comm.py @@ -0,0 +1,238 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +""" +This file contains primitives for multi-gpu communication. +This is useful when doing distributed training. +""" + +import functools +import numpy as np +import torch +import torch.distributed as dist + +_LOCAL_PROCESS_GROUP = None +_MISSING_LOCAL_PG_ERROR = ( + "Local process group is not yet created! Please use detectron2's `launch()` " + "to start processes and initialize pytorch process group. If you need to start " + "processes in other ways, please call comm.create_local_process_group(" + "num_workers_per_machine) after calling torch.distributed.init_process_group()." +) + + +def get_world_size() -> int: + if not dist.is_available(): + return 1 + if not dist.is_initialized(): + return 1 + return dist.get_world_size() + + +def get_rank() -> int: + if not dist.is_available(): + return 0 + if not dist.is_initialized(): + return 0 + return dist.get_rank() + + +@functools.lru_cache() +def create_local_process_group(num_workers_per_machine: int) -> None: + """ + Create a process group that contains ranks within the same machine. + + Detectron2's launch() in engine/launch.py will call this function. If you start + workers without launch(), you'll have to also call this. Otherwise utilities + like `get_local_rank()` will not work. + + This function contains a barrier. All processes must call it together. + + Args: + num_workers_per_machine: the number of worker processes per machine. Typically + the number of GPUs. + """ + global _LOCAL_PROCESS_GROUP + assert _LOCAL_PROCESS_GROUP is None + assert get_world_size() % num_workers_per_machine == 0 + num_machines = get_world_size() // num_workers_per_machine + machine_rank = get_rank() // num_workers_per_machine + for i in range(num_machines): + ranks_on_i = list(range(i * num_workers_per_machine, (i + 1) * num_workers_per_machine)) + pg = dist.new_group(ranks_on_i) + if i == machine_rank: + _LOCAL_PROCESS_GROUP = pg + + +def get_local_process_group(): + """ + Returns: + A torch process group which only includes processes that are on the same + machine as the current process. This group can be useful for communication + within a machine, e.g. a per-machine SyncBN. + """ + assert _LOCAL_PROCESS_GROUP is not None, _MISSING_LOCAL_PG_ERROR + return _LOCAL_PROCESS_GROUP + + +def get_local_rank() -> int: + """ + Returns: + The rank of the current process within the local (per-machine) process group. + """ + if not dist.is_available(): + return 0 + if not dist.is_initialized(): + return 0 + assert _LOCAL_PROCESS_GROUP is not None, _MISSING_LOCAL_PG_ERROR + return dist.get_rank(group=_LOCAL_PROCESS_GROUP) + + +def get_local_size() -> int: + """ + Returns: + The size of the per-machine process group, + i.e. the number of processes per machine. + """ + if not dist.is_available(): + return 1 + if not dist.is_initialized(): + return 1 + assert _LOCAL_PROCESS_GROUP is not None, _MISSING_LOCAL_PG_ERROR + return dist.get_world_size(group=_LOCAL_PROCESS_GROUP) + + +def is_main_process() -> bool: + return get_rank() == 0 + + +def synchronize(): + """ + Helper function to synchronize (barrier) among all processes when + using distributed training + """ + if not dist.is_available(): + return + if not dist.is_initialized(): + return + world_size = dist.get_world_size() + if world_size == 1: + return + if dist.get_backend() == dist.Backend.NCCL: + # This argument is needed to avoid warnings. + # It's valid only for NCCL backend. + dist.barrier(device_ids=[torch.cuda.current_device()]) + else: + dist.barrier() + + +@functools.lru_cache() +def _get_global_gloo_group(): + """ + Return a process group based on gloo backend, containing all the ranks + The result is cached. + """ + if dist.get_backend() == "nccl": + return dist.new_group(backend="gloo") + else: + return dist.group.WORLD + + +def all_gather(data, group=None): + """ + Run all_gather on arbitrary picklable data (not necessarily tensors). + + Args: + data: any picklable object + group: a torch process group. By default, will use a group which + contains all ranks on gloo backend. + + Returns: + list[data]: list of data gathered from each rank + """ + if get_world_size() == 1: + return [data] + if group is None: + group = _get_global_gloo_group() # use CPU group by default, to reduce GPU RAM usage. + world_size = dist.get_world_size(group) + if world_size == 1: + return [data] + + output = [None for _ in range(world_size)] + dist.all_gather_object(output, data, group=group) + return output + + +def gather(data, dst=0, group=None): + """ + Run gather on arbitrary picklable data (not necessarily tensors). + + Args: + data: any picklable object + dst (int): destination rank + group: a torch process group. By default, will use a group which + contains all ranks on gloo backend. + + Returns: + list[data]: on dst, a list of data gathered from each rank. Otherwise, + an empty list. + """ + if get_world_size() == 1: + return [data] + if group is None: + group = _get_global_gloo_group() + world_size = dist.get_world_size(group=group) + if world_size == 1: + return [data] + rank = dist.get_rank(group=group) + + if rank == dst: + output = [None for _ in range(world_size)] + dist.gather_object(data, output, dst=dst, group=group) + return output + else: + dist.gather_object(data, None, dst=dst, group=group) + return [] + + +def shared_random_seed(): + """ + Returns: + int: a random number that is the same across all workers. + If workers need a shared RNG, they can use this shared seed to + create one. + + All workers must call this function, otherwise it will deadlock. + """ + ints = np.random.randint(2**31) + all_ints = all_gather(ints) + return all_ints[0] + + +def reduce_dict(input_dict, average=True): + """ + Reduce the values in the dictionary from all processes so that process with rank + 0 has the reduced results. + + Args: + input_dict (dict): inputs to be reduced. All the values must be scalar CUDA Tensor. + average (bool): whether to do average or sum + + Returns: + a dict with the same keys as input_dict, after reduction. + """ + world_size = get_world_size() + if world_size < 2: + return input_dict + with torch.no_grad(): + names = [] + values = [] + # sort the keys so that they are consistent across processes + for k in sorted(input_dict.keys()): + names.append(k) + values.append(input_dict[k]) + values = torch.stack(values, dim=0) + dist.reduce(values, dst=0) + if dist.get_rank() == 0 and average: + # only main process gets accumulated, so only divide by + # world_size in this case + values /= world_size + reduced_dict = {k: v for k, v in zip(names, values)} + return reduced_dict diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/develop.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/develop.py new file mode 100644 index 00000000..e8416984 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/develop.py @@ -0,0 +1,59 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +""" Utilities for developers only. +These are not visible to users (not automatically imported). And should not +appeared in docs.""" +# adapted from https://github.com/tensorpack/tensorpack/blob/master/tensorpack/utils/develop.py + + +def create_dummy_class(klass, dependency, message=""): + """ + When a dependency of a class is not available, create a dummy class which throws ImportError + when used. + + Args: + klass (str): name of the class. + dependency (str): name of the dependency. + message: extra message to print + Returns: + class: a class object + """ + err = "Cannot import '{}', therefore '{}' is not available.".format(dependency, klass) + if message: + err = err + " " + message + + class _DummyMetaClass(type): + # throw error on class attribute access + def __getattr__(_, __): # noqa: B902 + raise ImportError(err) + + class _Dummy(object, metaclass=_DummyMetaClass): + # throw error on constructor + def __init__(self, *args, **kwargs): + raise ImportError(err) + + return _Dummy + + +def create_dummy_func(func, dependency, message=""): + """ + When a dependency of a function is not available, create a dummy function which throws + ImportError when used. + + Args: + func (str): name of the function. + dependency (str or list[str]): name(s) of the dependency. + message: extra message to print + Returns: + function: a function object + """ + err = "Cannot import '{}', therefore '{}' is not available.".format(dependency, func) + if message: + err = err + " " + message + + if isinstance(dependency, (list, tuple)): + dependency = ",".join(dependency) + + def _dummy(*args, **kwargs): + raise ImportError(err) + + return _dummy diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/env.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/env.py new file mode 100644 index 00000000..40634c17 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/env.py @@ -0,0 +1,170 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import importlib +import importlib.util +import logging +import numpy as np +import os +import random +import sys +from datetime import datetime +import torch + +__all__ = ["seed_all_rng"] + + +TORCH_VERSION = tuple(int(x) for x in torch.__version__.split(".")[:2]) +""" +PyTorch version as a tuple of 2 ints. Useful for comparison. +""" + + +DOC_BUILDING = os.getenv("_DOC_BUILDING", False) # set in docs/conf.py +""" +Whether we're building documentation. +""" + + +def seed_all_rng(seed=None): + """ + Set the random seed for the RNG in torch, numpy and python. + + Args: + seed (int): if None, will use a strong random seed. + """ + if seed is None: + seed = ( + os.getpid() + + int(datetime.now().strftime("%S%f")) + + int.from_bytes(os.urandom(2), "big") + ) + logger = logging.getLogger(__name__) + logger.info("Using a generated random seed {}".format(seed)) + np.random.seed(seed) + torch.manual_seed(seed) + random.seed(seed) + os.environ["PYTHONHASHSEED"] = str(seed) + + +# from https://stackoverflow.com/questions/67631/how-to-import-a-module-given-the-full-path +def _import_file(module_name, file_path, make_importable=False): + spec = importlib.util.spec_from_file_location(module_name, file_path) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + if make_importable: + sys.modules[module_name] = module + return module + + +def _configure_libraries(): + """ + Configurations for some libraries. + """ + # An environment option to disable `import cv2` globally, + # in case it leads to negative performance impact + disable_cv2 = int(os.environ.get("DETECTRON2_DISABLE_CV2", False)) + if disable_cv2: + sys.modules["cv2"] = None + else: + # Disable opencl in opencv since its interaction with cuda often has negative effects + # This envvar is supported after OpenCV 3.4.0 + os.environ["OPENCV_OPENCL_RUNTIME"] = "disabled" + try: + import cv2 + + if int(cv2.__version__.split(".")[0]) >= 3: + cv2.ocl.setUseOpenCL(False) + except ModuleNotFoundError: + # Other types of ImportError, if happened, should not be ignored. + # Because a failed opencv import could mess up address space + # https://github.com/skvark/opencv-python/issues/381 + pass + + def get_version(module, digit=2): + return tuple(map(int, module.__version__.split(".")[:digit])) + + # fmt: off + assert get_version(torch) >= (1, 4), "Requires torch>=1.4" + import fvcore + assert get_version(fvcore, 3) >= (0, 1, 2), "Requires fvcore>=0.1.2" + import yaml + assert get_version(yaml) >= (5, 1), "Requires pyyaml>=5.1" + # fmt: on + + +_ENV_SETUP_DONE = False + + +def setup_environment(): + """Perform environment setup work. The default setup is a no-op, but this + function allows the user to specify a Python source file or a module in + the $DETECTRON2_ENV_MODULE environment variable, that performs + custom setup work that may be necessary to their computing environment. + """ + global _ENV_SETUP_DONE + if _ENV_SETUP_DONE: + return + _ENV_SETUP_DONE = True + + _configure_libraries() + + custom_module_path = os.environ.get("DETECTRON2_ENV_MODULE") + + if custom_module_path: + setup_custom_environment(custom_module_path) + else: + # The default setup is a no-op + pass + + +def setup_custom_environment(custom_module): + """ + Load custom environment setup by importing a Python source file or a + module, and run the setup function. + """ + if custom_module.endswith(".py"): + module = _import_file("detectron2.utils.env.custom_module", custom_module) + else: + module = importlib.import_module(custom_module) + assert hasattr(module, "setup_environment") and callable(module.setup_environment), ( + "Custom environment module defined in {} does not have the " + "required callable attribute 'setup_environment'." + ).format(custom_module) + module.setup_environment() + + +def fixup_module_metadata(module_name, namespace, keys=None): + """ + Fix the __qualname__ of module members to be their exported api name, so + when they are referenced in docs, sphinx can find them. Reference: + https://github.com/python-trio/trio/blob/6754c74eacfad9cc5c92d5c24727a2f3b620624e/trio/_util.py#L216-L241 + """ + if not DOC_BUILDING: + return + seen_ids = set() + + def fix_one(qualname, name, obj): + # avoid infinite recursion (relevant when using + # typing.Generic, for example) + if id(obj) in seen_ids: + return + seen_ids.add(id(obj)) + + mod = getattr(obj, "__module__", None) + if mod is not None and (mod.startswith(module_name) or mod.startswith("fvcore.")): + obj.__module__ = module_name + # Modules, unlike everything else in Python, put fully-qualitied + # names into their __name__ attribute. We check for "." to avoid + # rewriting these. + if hasattr(obj, "__name__") and "." not in obj.__name__: + obj.__name__ = name + obj.__qualname__ = qualname + if isinstance(obj, type): + for attr_name, attr_value in obj.__dict__.items(): + fix_one(objname + "." + attr_name, attr_name, attr_value) + + if keys is None: + keys = namespace.keys() + for objname in keys: + if not objname.startswith("_"): + obj = namespace[objname] + fix_one(objname, objname, obj) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/events.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/events.py new file mode 100644 index 00000000..d9a68b6b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/events.py @@ -0,0 +1,534 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import datetime +import json +import logging +import os +import time +from collections import defaultdict +from contextlib import contextmanager +from typing import Optional +import torch +from fvcore.common.history_buffer import HistoryBuffer + +from annotator.oneformer.detectron2.utils.file_io import PathManager + +__all__ = [ + "get_event_storage", + "JSONWriter", + "TensorboardXWriter", + "CommonMetricPrinter", + "EventStorage", +] + +_CURRENT_STORAGE_STACK = [] + + +def get_event_storage(): + """ + Returns: + The :class:`EventStorage` object that's currently being used. + Throws an error if no :class:`EventStorage` is currently enabled. + """ + assert len( + _CURRENT_STORAGE_STACK + ), "get_event_storage() has to be called inside a 'with EventStorage(...)' context!" + return _CURRENT_STORAGE_STACK[-1] + + +class EventWriter: + """ + Base class for writers that obtain events from :class:`EventStorage` and process them. + """ + + def write(self): + raise NotImplementedError + + def close(self): + pass + + +class JSONWriter(EventWriter): + """ + Write scalars to a json file. + + It saves scalars as one json per line (instead of a big json) for easy parsing. + + Examples parsing such a json file: + :: + $ cat metrics.json | jq -s '.[0:2]' + [ + { + "data_time": 0.008433341979980469, + "iteration": 19, + "loss": 1.9228371381759644, + "loss_box_reg": 0.050025828182697296, + "loss_classifier": 0.5316952466964722, + "loss_mask": 0.7236229181289673, + "loss_rpn_box": 0.0856662318110466, + "loss_rpn_cls": 0.48198649287223816, + "lr": 0.007173333333333333, + "time": 0.25401854515075684 + }, + { + "data_time": 0.007216215133666992, + "iteration": 39, + "loss": 1.282649278640747, + "loss_box_reg": 0.06222952902317047, + "loss_classifier": 0.30682939291000366, + "loss_mask": 0.6970193982124329, + "loss_rpn_box": 0.038663312792778015, + "loss_rpn_cls": 0.1471673548221588, + "lr": 0.007706666666666667, + "time": 0.2490077018737793 + } + ] + + $ cat metrics.json | jq '.loss_mask' + 0.7126231789588928 + 0.689423680305481 + 0.6776131987571716 + ... + + """ + + def __init__(self, json_file, window_size=20): + """ + Args: + json_file (str): path to the json file. New data will be appended if the file exists. + window_size (int): the window size of median smoothing for the scalars whose + `smoothing_hint` are True. + """ + self._file_handle = PathManager.open(json_file, "a") + self._window_size = window_size + self._last_write = -1 + + def write(self): + storage = get_event_storage() + to_save = defaultdict(dict) + + for k, (v, iter) in storage.latest_with_smoothing_hint(self._window_size).items(): + # keep scalars that have not been written + if iter <= self._last_write: + continue + to_save[iter][k] = v + if len(to_save): + all_iters = sorted(to_save.keys()) + self._last_write = max(all_iters) + + for itr, scalars_per_iter in to_save.items(): + scalars_per_iter["iteration"] = itr + self._file_handle.write(json.dumps(scalars_per_iter, sort_keys=True) + "\n") + self._file_handle.flush() + try: + os.fsync(self._file_handle.fileno()) + except AttributeError: + pass + + def close(self): + self._file_handle.close() + + +class TensorboardXWriter(EventWriter): + """ + Write all scalars to a tensorboard file. + """ + + def __init__(self, log_dir: str, window_size: int = 20, **kwargs): + """ + Args: + log_dir (str): the directory to save the output events + window_size (int): the scalars will be median-smoothed by this window size + + kwargs: other arguments passed to `torch.utils.tensorboard.SummaryWriter(...)` + """ + self._window_size = window_size + from torch.utils.tensorboard import SummaryWriter + + self._writer = SummaryWriter(log_dir, **kwargs) + self._last_write = -1 + + def write(self): + storage = get_event_storage() + new_last_write = self._last_write + for k, (v, iter) in storage.latest_with_smoothing_hint(self._window_size).items(): + if iter > self._last_write: + self._writer.add_scalar(k, v, iter) + new_last_write = max(new_last_write, iter) + self._last_write = new_last_write + + # storage.put_{image,histogram} is only meant to be used by + # tensorboard writer. So we access its internal fields directly from here. + if len(storage._vis_data) >= 1: + for img_name, img, step_num in storage._vis_data: + self._writer.add_image(img_name, img, step_num) + # Storage stores all image data and rely on this writer to clear them. + # As a result it assumes only one writer will use its image data. + # An alternative design is to let storage store limited recent + # data (e.g. only the most recent image) that all writers can access. + # In that case a writer may not see all image data if its period is long. + storage.clear_images() + + if len(storage._histograms) >= 1: + for params in storage._histograms: + self._writer.add_histogram_raw(**params) + storage.clear_histograms() + + def close(self): + if hasattr(self, "_writer"): # doesn't exist when the code fails at import + self._writer.close() + + +class CommonMetricPrinter(EventWriter): + """ + Print **common** metrics to the terminal, including + iteration time, ETA, memory, all losses, and the learning rate. + It also applies smoothing using a window of 20 elements. + + It's meant to print common metrics in common ways. + To print something in more customized ways, please implement a similar printer by yourself. + """ + + def __init__(self, max_iter: Optional[int] = None, window_size: int = 20): + """ + Args: + max_iter: the maximum number of iterations to train. + Used to compute ETA. If not given, ETA will not be printed. + window_size (int): the losses will be median-smoothed by this window size + """ + self.logger = logging.getLogger(__name__) + self._max_iter = max_iter + self._window_size = window_size + self._last_write = None # (step, time) of last call to write(). Used to compute ETA + + def _get_eta(self, storage) -> Optional[str]: + if self._max_iter is None: + return "" + iteration = storage.iter + try: + eta_seconds = storage.history("time").median(1000) * (self._max_iter - iteration - 1) + storage.put_scalar("eta_seconds", eta_seconds, smoothing_hint=False) + return str(datetime.timedelta(seconds=int(eta_seconds))) + except KeyError: + # estimate eta on our own - more noisy + eta_string = None + if self._last_write is not None: + estimate_iter_time = (time.perf_counter() - self._last_write[1]) / ( + iteration - self._last_write[0] + ) + eta_seconds = estimate_iter_time * (self._max_iter - iteration - 1) + eta_string = str(datetime.timedelta(seconds=int(eta_seconds))) + self._last_write = (iteration, time.perf_counter()) + return eta_string + + def write(self): + storage = get_event_storage() + iteration = storage.iter + if iteration == self._max_iter: + # This hook only reports training progress (loss, ETA, etc) but not other data, + # therefore do not write anything after training succeeds, even if this method + # is called. + return + + try: + avg_data_time = storage.history("data_time").avg( + storage.count_samples("data_time", self._window_size) + ) + last_data_time = storage.history("data_time").latest() + except KeyError: + # they may not exist in the first few iterations (due to warmup) + # or when SimpleTrainer is not used + avg_data_time = None + last_data_time = None + try: + avg_iter_time = storage.history("time").global_avg() + last_iter_time = storage.history("time").latest() + except KeyError: + avg_iter_time = None + last_iter_time = None + try: + lr = "{:.5g}".format(storage.history("lr").latest()) + except KeyError: + lr = "N/A" + + eta_string = self._get_eta(storage) + + if torch.cuda.is_available(): + max_mem_mb = torch.cuda.max_memory_allocated() / 1024.0 / 1024.0 + else: + max_mem_mb = None + + # NOTE: max_mem is parsed by grep in "dev/parse_results.sh" + self.logger.info( + str.format( + " {eta}iter: {iter} {losses} {non_losses} {avg_time}{last_time}" + + "{avg_data_time}{last_data_time} lr: {lr} {memory}", + eta=f"eta: {eta_string} " if eta_string else "", + iter=iteration, + losses=" ".join( + [ + "{}: {:.4g}".format( + k, v.median(storage.count_samples(k, self._window_size)) + ) + for k, v in storage.histories().items() + if "loss" in k + ] + ), + non_losses=" ".join( + [ + "{}: {:.4g}".format( + k, v.median(storage.count_samples(k, self._window_size)) + ) + for k, v in storage.histories().items() + if "[metric]" in k + ] + ), + avg_time="time: {:.4f} ".format(avg_iter_time) + if avg_iter_time is not None + else "", + last_time="last_time: {:.4f} ".format(last_iter_time) + if last_iter_time is not None + else "", + avg_data_time="data_time: {:.4f} ".format(avg_data_time) + if avg_data_time is not None + else "", + last_data_time="last_data_time: {:.4f} ".format(last_data_time) + if last_data_time is not None + else "", + lr=lr, + memory="max_mem: {:.0f}M".format(max_mem_mb) if max_mem_mb is not None else "", + ) + ) + + +class EventStorage: + """ + The user-facing class that provides metric storage functionalities. + + In the future we may add support for storing / logging other types of data if needed. + """ + + def __init__(self, start_iter=0): + """ + Args: + start_iter (int): the iteration number to start with + """ + self._history = defaultdict(HistoryBuffer) + self._smoothing_hints = {} + self._latest_scalars = {} + self._iter = start_iter + self._current_prefix = "" + self._vis_data = [] + self._histograms = [] + + def put_image(self, img_name, img_tensor): + """ + Add an `img_tensor` associated with `img_name`, to be shown on + tensorboard. + + Args: + img_name (str): The name of the image to put into tensorboard. + img_tensor (torch.Tensor or numpy.array): An `uint8` or `float` + Tensor of shape `[channel, height, width]` where `channel` is + 3. The image format should be RGB. The elements in img_tensor + can either have values in [0, 1] (float32) or [0, 255] (uint8). + The `img_tensor` will be visualized in tensorboard. + """ + self._vis_data.append((img_name, img_tensor, self._iter)) + + def put_scalar(self, name, value, smoothing_hint=True): + """ + Add a scalar `value` to the `HistoryBuffer` associated with `name`. + + Args: + smoothing_hint (bool): a 'hint' on whether this scalar is noisy and should be + smoothed when logged. The hint will be accessible through + :meth:`EventStorage.smoothing_hints`. A writer may ignore the hint + and apply custom smoothing rule. + + It defaults to True because most scalars we save need to be smoothed to + provide any useful signal. + """ + name = self._current_prefix + name + history = self._history[name] + value = float(value) + history.update(value, self._iter) + self._latest_scalars[name] = (value, self._iter) + + existing_hint = self._smoothing_hints.get(name) + if existing_hint is not None: + assert ( + existing_hint == smoothing_hint + ), "Scalar {} was put with a different smoothing_hint!".format(name) + else: + self._smoothing_hints[name] = smoothing_hint + + def put_scalars(self, *, smoothing_hint=True, **kwargs): + """ + Put multiple scalars from keyword arguments. + + Examples: + + storage.put_scalars(loss=my_loss, accuracy=my_accuracy, smoothing_hint=True) + """ + for k, v in kwargs.items(): + self.put_scalar(k, v, smoothing_hint=smoothing_hint) + + def put_histogram(self, hist_name, hist_tensor, bins=1000): + """ + Create a histogram from a tensor. + + Args: + hist_name (str): The name of the histogram to put into tensorboard. + hist_tensor (torch.Tensor): A Tensor of arbitrary shape to be converted + into a histogram. + bins (int): Number of histogram bins. + """ + ht_min, ht_max = hist_tensor.min().item(), hist_tensor.max().item() + + # Create a histogram with PyTorch + hist_counts = torch.histc(hist_tensor, bins=bins) + hist_edges = torch.linspace(start=ht_min, end=ht_max, steps=bins + 1, dtype=torch.float32) + + # Parameter for the add_histogram_raw function of SummaryWriter + hist_params = dict( + tag=hist_name, + min=ht_min, + max=ht_max, + num=len(hist_tensor), + sum=float(hist_tensor.sum()), + sum_squares=float(torch.sum(hist_tensor**2)), + bucket_limits=hist_edges[1:].tolist(), + bucket_counts=hist_counts.tolist(), + global_step=self._iter, + ) + self._histograms.append(hist_params) + + def history(self, name): + """ + Returns: + HistoryBuffer: the scalar history for name + """ + ret = self._history.get(name, None) + if ret is None: + raise KeyError("No history metric available for {}!".format(name)) + return ret + + def histories(self): + """ + Returns: + dict[name -> HistoryBuffer]: the HistoryBuffer for all scalars + """ + return self._history + + def latest(self): + """ + Returns: + dict[str -> (float, int)]: mapping from the name of each scalar to the most + recent value and the iteration number its added. + """ + return self._latest_scalars + + def latest_with_smoothing_hint(self, window_size=20): + """ + Similar to :meth:`latest`, but the returned values + are either the un-smoothed original latest value, + or a median of the given window_size, + depend on whether the smoothing_hint is True. + + This provides a default behavior that other writers can use. + + Note: All scalars saved in the past `window_size` iterations are used for smoothing. + This is different from the `window_size` definition in HistoryBuffer. + Use :meth:`get_history_window_size` to get the `window_size` used in HistoryBuffer. + """ + result = {} + for k, (v, itr) in self._latest_scalars.items(): + result[k] = ( + self._history[k].median(self.count_samples(k, window_size)) + if self._smoothing_hints[k] + else v, + itr, + ) + return result + + def count_samples(self, name, window_size=20): + """ + Return the number of samples logged in the past `window_size` iterations. + """ + samples = 0 + data = self._history[name].values() + for _, iter_ in reversed(data): + if iter_ > data[-1][1] - window_size: + samples += 1 + else: + break + return samples + + def smoothing_hints(self): + """ + Returns: + dict[name -> bool]: the user-provided hint on whether the scalar + is noisy and needs smoothing. + """ + return self._smoothing_hints + + def step(self): + """ + User should either: (1) Call this function to increment storage.iter when needed. Or + (2) Set `storage.iter` to the correct iteration number before each iteration. + + The storage will then be able to associate the new data with an iteration number. + """ + self._iter += 1 + + @property + def iter(self): + """ + Returns: + int: The current iteration number. When used together with a trainer, + this is ensured to be the same as trainer.iter. + """ + return self._iter + + @iter.setter + def iter(self, val): + self._iter = int(val) + + @property + def iteration(self): + # for backward compatibility + return self._iter + + def __enter__(self): + _CURRENT_STORAGE_STACK.append(self) + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + assert _CURRENT_STORAGE_STACK[-1] == self + _CURRENT_STORAGE_STACK.pop() + + @contextmanager + def name_scope(self, name): + """ + Yields: + A context within which all the events added to this storage + will be prefixed by the name scope. + """ + old_prefix = self._current_prefix + self._current_prefix = name.rstrip("/") + "/" + yield + self._current_prefix = old_prefix + + def clear_images(self): + """ + Delete all the stored images for visualization. This should be called + after images are written to tensorboard. + """ + self._vis_data = [] + + def clear_histograms(self): + """ + Delete all the stored histograms for visualization. + This should be called after histograms are written to tensorboard. + """ + self._histograms = [] diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/file_io.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/file_io.py new file mode 100644 index 00000000..09f7dffd --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/file_io.py @@ -0,0 +1,39 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from iopath.common.file_io import HTTPURLHandler, OneDrivePathHandler, PathHandler +from iopath.common.file_io import PathManager as PathManagerBase + +__all__ = ["PathManager", "PathHandler"] + + +PathManager = PathManagerBase() +""" +This is a detectron2 project-specific PathManager. +We try to stay away from global PathManager in fvcore as it +introduces potential conflicts among other libraries. +""" + + +class Detectron2Handler(PathHandler): + """ + Resolve anything that's hosted under detectron2's namespace. + """ + + PREFIX = "detectron2://" + S3_DETECTRON2_PREFIX = "https://dl.fbaipublicfiles.com/detectron2/" + + def _get_supported_prefixes(self): + return [self.PREFIX] + + def _get_local_path(self, path, **kwargs): + name = path[len(self.PREFIX) :] + return PathManager.get_local_path(self.S3_DETECTRON2_PREFIX + name, **kwargs) + + def _open(self, path, mode="r", **kwargs): + return PathManager.open( + self.S3_DETECTRON2_PREFIX + path[len(self.PREFIX) :], mode, **kwargs + ) + + +PathManager.register_handler(HTTPURLHandler()) +PathManager.register_handler(OneDrivePathHandler()) +PathManager.register_handler(Detectron2Handler()) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/logger.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/logger.py new file mode 100644 index 00000000..d77d42cb --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/logger.py @@ -0,0 +1,237 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import atexit +import functools +import logging +import os +import sys +import time +from collections import Counter +import torch +from tabulate import tabulate +from termcolor import colored + +from annotator.oneformer.detectron2.utils.file_io import PathManager + +__all__ = ["setup_logger", "log_first_n", "log_every_n", "log_every_n_seconds"] + + +class _ColorfulFormatter(logging.Formatter): + def __init__(self, *args, **kwargs): + self._root_name = kwargs.pop("root_name") + "." + self._abbrev_name = kwargs.pop("abbrev_name", "") + if len(self._abbrev_name): + self._abbrev_name = self._abbrev_name + "." + super(_ColorfulFormatter, self).__init__(*args, **kwargs) + + def formatMessage(self, record): + record.name = record.name.replace(self._root_name, self._abbrev_name) + log = super(_ColorfulFormatter, self).formatMessage(record) + if record.levelno == logging.WARNING: + prefix = colored("WARNING", "red", attrs=["blink"]) + elif record.levelno == logging.ERROR or record.levelno == logging.CRITICAL: + prefix = colored("ERROR", "red", attrs=["blink", "underline"]) + else: + return log + return prefix + " " + log + + +@functools.lru_cache() # so that calling setup_logger multiple times won't add many handlers +def setup_logger( + output=None, distributed_rank=0, *, color=True, name="detectron2", abbrev_name=None +): + """ + Initialize the detectron2 logger and set its verbosity level to "DEBUG". + + Args: + output (str): a file name or a directory to save log. If None, will not save log file. + If ends with ".txt" or ".log", assumed to be a file name. + Otherwise, logs will be saved to `output/log.txt`. + name (str): the root module name of this logger + abbrev_name (str): an abbreviation of the module, to avoid long names in logs. + Set to "" to not log the root module in logs. + By default, will abbreviate "detectron2" to "d2" and leave other + modules unchanged. + + Returns: + logging.Logger: a logger + """ + logger = logging.getLogger(name) + logger.setLevel(logging.DEBUG) + logger.propagate = False + + if abbrev_name is None: + abbrev_name = "d2" if name == "detectron2" else name + + plain_formatter = logging.Formatter( + "[%(asctime)s] %(name)s %(levelname)s: %(message)s", datefmt="%m/%d %H:%M:%S" + ) + # stdout logging: master only + if distributed_rank == 0: + ch = logging.StreamHandler(stream=sys.stdout) + ch.setLevel(logging.DEBUG) + if color: + formatter = _ColorfulFormatter( + colored("[%(asctime)s %(name)s]: ", "green") + "%(message)s", + datefmt="%m/%d %H:%M:%S", + root_name=name, + abbrev_name=str(abbrev_name), + ) + else: + formatter = plain_formatter + ch.setFormatter(formatter) + logger.addHandler(ch) + + # file logging: all workers + if output is not None: + if output.endswith(".txt") or output.endswith(".log"): + filename = output + else: + filename = os.path.join(output, "log.txt") + if distributed_rank > 0: + filename = filename + ".rank{}".format(distributed_rank) + PathManager.mkdirs(os.path.dirname(filename)) + + fh = logging.StreamHandler(_cached_log_stream(filename)) + fh.setLevel(logging.DEBUG) + fh.setFormatter(plain_formatter) + logger.addHandler(fh) + + return logger + + +# cache the opened file object, so that different calls to `setup_logger` +# with the same file name can safely write to the same file. +@functools.lru_cache(maxsize=None) +def _cached_log_stream(filename): + # use 1K buffer if writing to cloud storage + io = PathManager.open(filename, "a", buffering=1024 if "://" in filename else -1) + atexit.register(io.close) + return io + + +""" +Below are some other convenient logging methods. +They are mainly adopted from +https://github.com/abseil/abseil-py/blob/master/absl/logging/__init__.py +""" + + +def _find_caller(): + """ + Returns: + str: module name of the caller + tuple: a hashable key to be used to identify different callers + """ + frame = sys._getframe(2) + while frame: + code = frame.f_code + if os.path.join("utils", "logger.") not in code.co_filename: + mod_name = frame.f_globals["__name__"] + if mod_name == "__main__": + mod_name = "detectron2" + return mod_name, (code.co_filename, frame.f_lineno, code.co_name) + frame = frame.f_back + + +_LOG_COUNTER = Counter() +_LOG_TIMER = {} + + +def log_first_n(lvl, msg, n=1, *, name=None, key="caller"): + """ + Log only for the first n times. + + Args: + lvl (int): the logging level + msg (str): + n (int): + name (str): name of the logger to use. Will use the caller's module by default. + key (str or tuple[str]): the string(s) can be one of "caller" or + "message", which defines how to identify duplicated logs. + For example, if called with `n=1, key="caller"`, this function + will only log the first call from the same caller, regardless of + the message content. + If called with `n=1, key="message"`, this function will log the + same content only once, even if they are called from different places. + If called with `n=1, key=("caller", "message")`, this function + will not log only if the same caller has logged the same message before. + """ + if isinstance(key, str): + key = (key,) + assert len(key) > 0 + + caller_module, caller_key = _find_caller() + hash_key = () + if "caller" in key: + hash_key = hash_key + caller_key + if "message" in key: + hash_key = hash_key + (msg,) + + _LOG_COUNTER[hash_key] += 1 + if _LOG_COUNTER[hash_key] <= n: + logging.getLogger(name or caller_module).log(lvl, msg) + + +def log_every_n(lvl, msg, n=1, *, name=None): + """ + Log once per n times. + + Args: + lvl (int): the logging level + msg (str): + n (int): + name (str): name of the logger to use. Will use the caller's module by default. + """ + caller_module, key = _find_caller() + _LOG_COUNTER[key] += 1 + if n == 1 or _LOG_COUNTER[key] % n == 1: + logging.getLogger(name or caller_module).log(lvl, msg) + + +def log_every_n_seconds(lvl, msg, n=1, *, name=None): + """ + Log no more than once per n seconds. + + Args: + lvl (int): the logging level + msg (str): + n (int): + name (str): name of the logger to use. Will use the caller's module by default. + """ + caller_module, key = _find_caller() + last_logged = _LOG_TIMER.get(key, None) + current_time = time.time() + if last_logged is None or current_time - last_logged >= n: + logging.getLogger(name or caller_module).log(lvl, msg) + _LOG_TIMER[key] = current_time + + +def create_small_table(small_dict): + """ + Create a small table using the keys of small_dict as headers. This is only + suitable for small dictionaries. + + Args: + small_dict (dict): a result dictionary of only a few items. + + Returns: + str: the table as a string. + """ + keys, values = tuple(zip(*small_dict.items())) + table = tabulate( + [values], + headers=keys, + tablefmt="pipe", + floatfmt=".3f", + stralign="center", + numalign="center", + ) + return table + + +def _log_api_usage(identifier: str): + """ + Internal function used to log the usage of different detectron2 components + inside facebook's infra. + """ + torch._C._log_api_usage_once("detectron2." + identifier) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/memory.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/memory.py new file mode 100644 index 00000000..bd494780 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/memory.py @@ -0,0 +1,84 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +import logging +from contextlib import contextmanager +from functools import wraps +import torch + +__all__ = ["retry_if_cuda_oom"] + + +@contextmanager +def _ignore_torch_cuda_oom(): + """ + A context which ignores CUDA OOM exception from pytorch. + """ + try: + yield + except RuntimeError as e: + # NOTE: the string may change? + if "CUDA out of memory. " in str(e): + pass + else: + raise + + +def retry_if_cuda_oom(func): + """ + Makes a function retry itself after encountering + pytorch's CUDA OOM error. + It will first retry after calling `torch.cuda.empty_cache()`. + + If that still fails, it will then retry by trying to convert inputs to CPUs. + In this case, it expects the function to dispatch to CPU implementation. + The return values may become CPU tensors as well and it's user's + responsibility to convert it back to CUDA tensor if needed. + + Args: + func: a stateless callable that takes tensor-like objects as arguments + + Returns: + a callable which retries `func` if OOM is encountered. + + Examples: + :: + output = retry_if_cuda_oom(some_torch_function)(input1, input2) + # output may be on CPU even if inputs are on GPU + + Note: + 1. When converting inputs to CPU, it will only look at each argument and check + if it has `.device` and `.to` for conversion. Nested structures of tensors + are not supported. + + 2. Since the function might be called more than once, it has to be + stateless. + """ + + def maybe_to_cpu(x): + try: + like_gpu_tensor = x.device.type == "cuda" and hasattr(x, "to") + except AttributeError: + like_gpu_tensor = False + if like_gpu_tensor: + return x.to(device="cpu") + else: + return x + + @wraps(func) + def wrapped(*args, **kwargs): + with _ignore_torch_cuda_oom(): + return func(*args, **kwargs) + + # Clear cache and retry + torch.cuda.empty_cache() + with _ignore_torch_cuda_oom(): + return func(*args, **kwargs) + + # Try on CPU. This slows down the code significantly, therefore print a notice. + logger = logging.getLogger(__name__) + logger.info("Attempting to copy inputs of {} to CPU due to CUDA OOM".format(str(func))) + new_args = (maybe_to_cpu(x) for x in args) + new_kwargs = {k: maybe_to_cpu(v) for k, v in kwargs.items()} + return func(*new_args, **new_kwargs) + + return wrapped diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/registry.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/registry.py new file mode 100644 index 00000000..4b01e900 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/registry.py @@ -0,0 +1,60 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +from typing import Any +import pydoc +from fvcore.common.registry import Registry # for backward compatibility. + +""" +``Registry`` and `locate` provide ways to map a string (typically found +in config files) to callable objects. +""" + +__all__ = ["Registry", "locate"] + + +def _convert_target_to_string(t: Any) -> str: + """ + Inverse of ``locate()``. + + Args: + t: any object with ``__module__`` and ``__qualname__`` + """ + module, qualname = t.__module__, t.__qualname__ + + # Compress the path to this object, e.g. ``module.submodule._impl.class`` + # may become ``module.submodule.class``, if the later also resolves to the same + # object. This simplifies the string, and also is less affected by moving the + # class implementation. + module_parts = module.split(".") + for k in range(1, len(module_parts)): + prefix = ".".join(module_parts[:k]) + candidate = f"{prefix}.{qualname}" + try: + if locate(candidate) is t: + return candidate + except ImportError: + pass + return f"{module}.{qualname}" + + +def locate(name: str) -> Any: + """ + Locate and return an object ``x`` using an input string ``{x.__module__}.{x.__qualname__}``, + such as "module.submodule.class_name". + + Raise Exception if it cannot be found. + """ + obj = pydoc.locate(name) + + # Some cases (e.g. torch.optim.sgd.SGD) not handled correctly + # by pydoc.locate. Try a private function from hydra. + if obj is None: + try: + # from hydra.utils import get_method - will print many errors + from hydra.utils import _locate + except ImportError as e: + raise ImportError(f"Cannot dynamically locate object {name}!") from e + else: + obj = _locate(name) # it raises if fails + + return obj diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/serialize.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/serialize.py new file mode 100644 index 00000000..ed450651 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/serialize.py @@ -0,0 +1,32 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# import cloudpickle + + +class PicklableWrapper(object): + """ + Wrap an object to make it more picklable, note that it uses + heavy weight serialization libraries that are slower than pickle. + It's best to use it only on closures (which are usually not picklable). + + This is a simplified version of + https://github.com/joblib/joblib/blob/master/joblib/externals/loky/cloudpickle_wrapper.py + """ + + def __init__(self, obj): + while isinstance(obj, PicklableWrapper): + # Wrapping an object twice is no-op + obj = obj._obj + self._obj = obj + + # def __reduce__(self): + # s = cloudpickle.dumps(self._obj) + # return cloudpickle.loads, (s,) + + def __call__(self, *args, **kwargs): + return self._obj(*args, **kwargs) + + def __getattr__(self, attr): + # Ensure that the wrapped object can be used seamlessly as the previous object. + if attr not in ["_obj"]: + return getattr(self._obj, attr) + return getattr(self, attr) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/testing.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/testing.py new file mode 100644 index 00000000..3c3f001a --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/testing.py @@ -0,0 +1,478 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import io +import numpy as np +import os +import re +import tempfile +import unittest +from typing import Callable +import torch +import torch.onnx.symbolic_helper as sym_help +from packaging import version +from torch._C import ListType +from torch.onnx import register_custom_op_symbolic + +from annotator.oneformer.detectron2 import model_zoo +from annotator.oneformer.detectron2.config import CfgNode, LazyConfig, instantiate +from annotator.oneformer.detectron2.data import DatasetCatalog +from annotator.oneformer.detectron2.data.detection_utils import read_image +from annotator.oneformer.detectron2.modeling import build_model +from annotator.oneformer.detectron2.structures import Boxes, Instances, ROIMasks +from annotator.oneformer.detectron2.utils.file_io import PathManager + + +""" +Internal utilities for tests. Don't use except for writing tests. +""" + + +def get_model_no_weights(config_path): + """ + Like model_zoo.get, but do not load any weights (even pretrained) + """ + cfg = model_zoo.get_config(config_path) + if isinstance(cfg, CfgNode): + if not torch.cuda.is_available(): + cfg.MODEL.DEVICE = "cpu" + return build_model(cfg) + else: + return instantiate(cfg.model) + + +def random_boxes(num_boxes, max_coord=100, device="cpu"): + """ + Create a random Nx4 boxes tensor, with coordinates < max_coord. + """ + boxes = torch.rand(num_boxes, 4, device=device) * (max_coord * 0.5) + boxes.clamp_(min=1.0) # tiny boxes cause numerical instability in box regression + # Note: the implementation of this function in torchvision is: + # boxes[:, 2:] += torch.rand(N, 2) * 100 + # but it does not guarantee non-negative widths/heights constraints: + # boxes[:, 2] >= boxes[:, 0] and boxes[:, 3] >= boxes[:, 1]: + boxes[:, 2:] += boxes[:, :2] + return boxes + + +def get_sample_coco_image(tensor=True): + """ + Args: + tensor (bool): if True, returns 3xHxW tensor. + else, returns a HxWx3 numpy array. + + Returns: + an image, in BGR color. + """ + try: + file_name = DatasetCatalog.get("coco_2017_val_100")[0]["file_name"] + if not PathManager.exists(file_name): + raise FileNotFoundError() + except IOError: + # for public CI to run + file_name = PathManager.get_local_path( + "http://images.cocodataset.org/train2017/000000000009.jpg" + ) + ret = read_image(file_name, format="BGR") + if tensor: + ret = torch.from_numpy(np.ascontiguousarray(ret.transpose(2, 0, 1))) + return ret + + +def convert_scripted_instances(instances): + """ + Convert a scripted Instances object to a regular :class:`Instances` object + """ + assert hasattr( + instances, "image_size" + ), f"Expect an Instances object, but got {type(instances)}!" + ret = Instances(instances.image_size) + for name in instances._field_names: + val = getattr(instances, "_" + name, None) + if val is not None: + ret.set(name, val) + return ret + + +def assert_instances_allclose(input, other, *, rtol=1e-5, msg="", size_as_tensor=False): + """ + Args: + input, other (Instances): + size_as_tensor: compare image_size of the Instances as tensors (instead of tuples). + Useful for comparing outputs of tracing. + """ + if not isinstance(input, Instances): + input = convert_scripted_instances(input) + if not isinstance(other, Instances): + other = convert_scripted_instances(other) + + if not msg: + msg = "Two Instances are different! " + else: + msg = msg.rstrip() + " " + + size_error_msg = msg + f"image_size is {input.image_size} vs. {other.image_size}!" + if size_as_tensor: + assert torch.equal( + torch.tensor(input.image_size), torch.tensor(other.image_size) + ), size_error_msg + else: + assert input.image_size == other.image_size, size_error_msg + fields = sorted(input.get_fields().keys()) + fields_other = sorted(other.get_fields().keys()) + assert fields == fields_other, msg + f"Fields are {fields} vs {fields_other}!" + + for f in fields: + val1, val2 = input.get(f), other.get(f) + if isinstance(val1, (Boxes, ROIMasks)): + # boxes in the range of O(100) and can have a larger tolerance + assert torch.allclose(val1.tensor, val2.tensor, atol=100 * rtol), ( + msg + f"Field {f} differs too much!" + ) + elif isinstance(val1, torch.Tensor): + if val1.dtype.is_floating_point: + mag = torch.abs(val1).max().cpu().item() + assert torch.allclose(val1, val2, atol=mag * rtol), ( + msg + f"Field {f} differs too much!" + ) + else: + assert torch.equal(val1, val2), msg + f"Field {f} is different!" + else: + raise ValueError(f"Don't know how to compare type {type(val1)}") + + +def reload_script_model(module): + """ + Save a jit module and load it back. + Similar to the `getExportImportCopy` function in torch/testing/ + """ + buffer = io.BytesIO() + torch.jit.save(module, buffer) + buffer.seek(0) + return torch.jit.load(buffer) + + +def reload_lazy_config(cfg): + """ + Save an object by LazyConfig.save and load it back. + This is used to test that a config still works the same after + serialization/deserialization. + """ + with tempfile.TemporaryDirectory(prefix="detectron2") as d: + fname = os.path.join(d, "d2_cfg_test.yaml") + LazyConfig.save(cfg, fname) + return LazyConfig.load(fname) + + +def min_torch_version(min_version: str) -> bool: + """ + Returns True when torch's version is at least `min_version`. + """ + try: + import torch + except ImportError: + return False + + installed_version = version.parse(torch.__version__.split("+")[0]) + min_version = version.parse(min_version) + return installed_version >= min_version + + +def has_dynamic_axes(onnx_model): + """ + Return True when all ONNX input/output have only dynamic axes for all ranks + """ + return all( + not dim.dim_param.isnumeric() + for inp in onnx_model.graph.input + for dim in inp.type.tensor_type.shape.dim + ) and all( + not dim.dim_param.isnumeric() + for out in onnx_model.graph.output + for dim in out.type.tensor_type.shape.dim + ) + + +def register_custom_op_onnx_export( + opname: str, symbolic_fn: Callable, opset_version: int, min_version: str +) -> None: + """ + Register `symbolic_fn` as PyTorch's symbolic `opname`-`opset_version` for ONNX export. + The registration is performed only when current PyTorch's version is < `min_version.` + IMPORTANT: symbolic must be manually unregistered after the caller function returns + """ + if min_torch_version(min_version): + return + register_custom_op_symbolic(opname, symbolic_fn, opset_version) + print(f"_register_custom_op_onnx_export({opname}, {opset_version}) succeeded.") + + +def unregister_custom_op_onnx_export(opname: str, opset_version: int, min_version: str) -> None: + """ + Unregister PyTorch's symbolic `opname`-`opset_version` for ONNX export. + The un-registration is performed only when PyTorch's version is < `min_version` + IMPORTANT: The symbolic must have been manually registered by the caller, otherwise + the incorrect symbolic may be unregistered instead. + """ + + # TODO: _unregister_custom_op_symbolic is introduced PyTorch>=1.10 + # Remove after PyTorch 1.10+ is used by ALL detectron2's CI + try: + from torch.onnx import unregister_custom_op_symbolic as _unregister_custom_op_symbolic + except ImportError: + + def _unregister_custom_op_symbolic(symbolic_name, opset_version): + import torch.onnx.symbolic_registry as sym_registry + from torch.onnx.symbolic_helper import _onnx_main_opset, _onnx_stable_opsets + + def _get_ns_op_name_from_custom_op(symbolic_name): + try: + from torch.onnx.utils import get_ns_op_name_from_custom_op + + ns, op_name = get_ns_op_name_from_custom_op(symbolic_name) + except ImportError as import_error: + if not bool( + re.match(r"^[a-zA-Z0-9-_]*::[a-zA-Z-_]+[a-zA-Z0-9-_]*$", symbolic_name) + ): + raise ValueError( + f"Invalid symbolic name {symbolic_name}. Must be `domain::name`" + ) from import_error + + ns, op_name = symbolic_name.split("::") + if ns == "onnx": + raise ValueError(f"{ns} domain cannot be modified.") from import_error + + if ns == "aten": + ns = "" + + return ns, op_name + + def _unregister_op(opname: str, domain: str, version: int): + try: + sym_registry.unregister_op(op_name, ns, ver) + except AttributeError as attribute_error: + if sym_registry.is_registered_op(opname, domain, version): + del sym_registry._registry[(domain, version)][opname] + if not sym_registry._registry[(domain, version)]: + del sym_registry._registry[(domain, version)] + else: + raise RuntimeError( + f"The opname {opname} is not registered." + ) from attribute_error + + ns, op_name = _get_ns_op_name_from_custom_op(symbolic_name) + for ver in _onnx_stable_opsets + [_onnx_main_opset]: + if ver >= opset_version: + _unregister_op(op_name, ns, ver) + + if min_torch_version(min_version): + return + _unregister_custom_op_symbolic(opname, opset_version) + print(f"_unregister_custom_op_onnx_export({opname}, {opset_version}) succeeded.") + + +skipIfOnCPUCI = unittest.skipIf( + os.environ.get("CI") and not torch.cuda.is_available(), + "The test is too slow on CPUs and will be executed on CircleCI's GPU jobs.", +) + + +def skipIfUnsupportedMinOpsetVersion(min_opset_version, current_opset_version=None): + """ + Skips tests for ONNX Opset versions older than min_opset_version. + """ + + def skip_dec(func): + def wrapper(self): + try: + opset_version = self.opset_version + except AttributeError: + opset_version = current_opset_version + if opset_version < min_opset_version: + raise unittest.SkipTest( + f"Unsupported opset_version {opset_version}" + f", required is {min_opset_version}" + ) + return func(self) + + return wrapper + + return skip_dec + + +def skipIfUnsupportedMinTorchVersion(min_version): + """ + Skips tests for PyTorch versions older than min_version. + """ + reason = f"module 'torch' has __version__ {torch.__version__}" f", required is: {min_version}" + return unittest.skipIf(not min_torch_version(min_version), reason) + + +# TODO: Remove after PyTorch 1.11.1+ is used by detectron2's CI +def _pytorch1111_symbolic_opset9_to(g, self, *args): + """aten::to() symbolic that must be used for testing with PyTorch < 1.11.1.""" + + def is_aten_to_device_only(args): + if len(args) == 4: + # aten::to(Tensor, Device, bool, bool, memory_format) + return ( + args[0].node().kind() == "prim::device" + or args[0].type().isSubtypeOf(ListType.ofInts()) + or ( + sym_help._is_value(args[0]) + and args[0].node().kind() == "onnx::Constant" + and isinstance(args[0].node()["value"], str) + ) + ) + elif len(args) == 5: + # aten::to(Tensor, Device, ScalarType, bool, bool, memory_format) + # When dtype is None, this is a aten::to(device) call + dtype = sym_help._get_const(args[1], "i", "dtype") + return dtype is None + elif len(args) in (6, 7): + # aten::to(Tensor, ScalarType, Layout, Device, bool, bool, memory_format) + # aten::to(Tensor, ScalarType, Layout, Device, bool, bool, bool, memory_format) + # When dtype is None, this is a aten::to(device) call + dtype = sym_help._get_const(args[0], "i", "dtype") + return dtype is None + return False + + # ONNX doesn't have a concept of a device, so we ignore device-only casts + if is_aten_to_device_only(args): + return self + + if len(args) == 4: + # TestONNXRuntime::test_ones_bool shows args[0] of aten::to can be onnx::Constant[Tensor] + # In this case, the constant value is a tensor not int, + # so sym_help._maybe_get_const(args[0], 'i') would not work. + dtype = args[0] + if sym_help._is_value(args[0]) and args[0].node().kind() == "onnx::Constant": + tval = args[0].node()["value"] + if isinstance(tval, torch.Tensor): + if len(tval.shape) == 0: + tval = tval.item() + dtype = int(tval) + else: + dtype = tval + + if sym_help._is_value(dtype) or isinstance(dtype, torch.Tensor): + # aten::to(Tensor, Tensor, bool, bool, memory_format) + dtype = args[0].type().scalarType() + return g.op("Cast", self, to_i=sym_help.cast_pytorch_to_onnx[dtype]) + else: + # aten::to(Tensor, ScalarType, bool, bool, memory_format) + # memory_format is ignored + return g.op("Cast", self, to_i=sym_help.scalar_type_to_onnx[dtype]) + elif len(args) == 5: + # aten::to(Tensor, Device, ScalarType, bool, bool, memory_format) + dtype = sym_help._get_const(args[1], "i", "dtype") + # memory_format is ignored + return g.op("Cast", self, to_i=sym_help.scalar_type_to_onnx[dtype]) + elif len(args) == 6: + # aten::to(Tensor, ScalarType, Layout, Device, bool, bool, memory_format) + dtype = sym_help._get_const(args[0], "i", "dtype") + # Layout, device and memory_format are ignored + return g.op("Cast", self, to_i=sym_help.scalar_type_to_onnx[dtype]) + elif len(args) == 7: + # aten::to(Tensor, ScalarType, Layout, Device, bool, bool, bool, memory_format) + dtype = sym_help._get_const(args[0], "i", "dtype") + # Layout, device and memory_format are ignored + return g.op("Cast", self, to_i=sym_help.scalar_type_to_onnx[dtype]) + else: + return sym_help._onnx_unsupported("Unknown aten::to signature") + + +# TODO: Remove after PyTorch 1.11.1+ is used by detectron2's CI +def _pytorch1111_symbolic_opset9_repeat_interleave(g, self, repeats, dim=None, output_size=None): + + # from torch.onnx.symbolic_helper import ScalarType + from torch.onnx.symbolic_opset9 import expand, unsqueeze + + input = self + # if dim is None flatten + # By default, use the flattened input array, and return a flat output array + if sym_help._is_none(dim): + input = sym_help._reshape_helper(g, self, g.op("Constant", value_t=torch.tensor([-1]))) + dim = 0 + else: + dim = sym_help._maybe_get_scalar(dim) + + repeats_dim = sym_help._get_tensor_rank(repeats) + repeats_sizes = sym_help._get_tensor_sizes(repeats) + input_sizes = sym_help._get_tensor_sizes(input) + if repeats_dim is None: + raise RuntimeError( + "Unsupported: ONNX export of repeat_interleave for unknown " "repeats rank." + ) + if repeats_sizes is None: + raise RuntimeError( + "Unsupported: ONNX export of repeat_interleave for unknown " "repeats size." + ) + if input_sizes is None: + raise RuntimeError( + "Unsupported: ONNX export of repeat_interleave for unknown " "input size." + ) + + input_sizes_temp = input_sizes.copy() + for idx, input_size in enumerate(input_sizes): + if input_size is None: + input_sizes[idx], input_sizes_temp[idx] = 0, -1 + + # Cases where repeats is an int or single value tensor + if repeats_dim == 0 or (repeats_dim == 1 and repeats_sizes[0] == 1): + if not sym_help._is_tensor(repeats): + repeats = g.op("Constant", value_t=torch.LongTensor(repeats)) + if input_sizes[dim] == 0: + return sym_help._onnx_opset_unsupported_detailed( + "repeat_interleave", + 9, + 13, + "Unsupported along dimension with unknown input size", + ) + else: + reps = input_sizes[dim] + repeats = expand(g, repeats, g.op("Constant", value_t=torch.tensor([reps])), None) + + # Cases where repeats is a 1 dim Tensor + elif repeats_dim == 1: + if input_sizes[dim] == 0: + return sym_help._onnx_opset_unsupported_detailed( + "repeat_interleave", + 9, + 13, + "Unsupported along dimension with unknown input size", + ) + if repeats_sizes[0] is None: + return sym_help._onnx_opset_unsupported_detailed( + "repeat_interleave", 9, 13, "Unsupported for cases with dynamic repeats" + ) + assert ( + repeats_sizes[0] == input_sizes[dim] + ), "repeats must have the same size as input along dim" + reps = repeats_sizes[0] + else: + raise RuntimeError("repeats must be 0-dim or 1-dim tensor") + + final_splits = list() + r_splits = sym_help._repeat_interleave_split_helper(g, repeats, reps, 0) + if isinstance(r_splits, torch._C.Value): + r_splits = [r_splits] + i_splits = sym_help._repeat_interleave_split_helper(g, input, reps, dim) + if isinstance(i_splits, torch._C.Value): + i_splits = [i_splits] + input_sizes[dim], input_sizes_temp[dim] = -1, 1 + for idx, r_split in enumerate(r_splits): + i_split = unsqueeze(g, i_splits[idx], dim + 1) + r_concat = [ + g.op("Constant", value_t=torch.LongTensor(input_sizes_temp[: dim + 1])), + r_split, + g.op("Constant", value_t=torch.LongTensor(input_sizes_temp[dim + 1 :])), + ] + r_concat = g.op("Concat", *r_concat, axis_i=0) + i_split = expand(g, i_split, r_concat, None) + i_split = sym_help._reshape_helper( + g, + i_split, + g.op("Constant", value_t=torch.LongTensor(input_sizes)), + allowzero=0, + ) + final_splits.append(i_split) + return g.op("Concat", *final_splits, axis_i=dim) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/tracing.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/tracing.py new file mode 100644 index 00000000..75661131 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/tracing.py @@ -0,0 +1,71 @@ +import inspect +import torch + +from annotator.oneformer.detectron2.utils.env import TORCH_VERSION + +try: + from torch.fx._symbolic_trace import is_fx_tracing as is_fx_tracing_current + + tracing_current_exists = True +except ImportError: + tracing_current_exists = False + +try: + from torch.fx._symbolic_trace import _orig_module_call + + tracing_legacy_exists = True +except ImportError: + tracing_legacy_exists = False + + +@torch.jit.ignore +def is_fx_tracing_legacy() -> bool: + """ + Returns a bool indicating whether torch.fx is currently symbolically tracing a module. + Can be useful for gating module logic that is incompatible with symbolic tracing. + """ + return torch.nn.Module.__call__ is not _orig_module_call + + +@torch.jit.ignore +def is_fx_tracing() -> bool: + """Returns whether execution is currently in + Torch FX tracing mode""" + if TORCH_VERSION >= (1, 10) and tracing_current_exists: + return is_fx_tracing_current() + elif tracing_legacy_exists: + return is_fx_tracing_legacy() + else: + # Can't find either current or legacy tracing indication code. + # Enabling this assert_fx_safe() call regardless of tracing status. + return False + + +@torch.jit.ignore +def assert_fx_safe(condition: bool, message: str) -> torch.Tensor: + """An FX-tracing safe version of assert. + Avoids erroneous type assertion triggering when types are masked inside + an fx.proxy.Proxy object during tracing. + Args: condition - either a boolean expression or a string representing + the condition to test. If this assert triggers an exception when tracing + due to dynamic control flow, try encasing the expression in quotation + marks and supplying it as a string.""" + # Must return a concrete tensor for compatibility with PyTorch <=1.8. + # If <=1.8 compatibility is not needed, return type can be converted to None + if not is_fx_tracing(): + try: + if isinstance(condition, str): + caller_frame = inspect.currentframe().f_back + torch._assert( + eval(condition, caller_frame.f_globals, caller_frame.f_locals), message + ) + return torch.ones(1) + else: + torch._assert(condition, message) + return torch.ones(1) + except torch.fx.proxy.TraceError as e: + print( + "Found a non-FX compatible assertion. Skipping the check. Failure is shown below" + + str(e) + ) + return torch.zeros(1) diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/video_visualizer.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/video_visualizer.py new file mode 100644 index 00000000..eaedfc48 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/video_visualizer.py @@ -0,0 +1,287 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import numpy as np +from typing import List +import annotator.oneformer.pycocotools.mask as mask_util + +from annotator.oneformer.detectron2.structures import Instances +from annotator.oneformer.detectron2.utils.visualizer import ( + ColorMode, + Visualizer, + _create_text_labels, + _PanopticPrediction, +) + +from .colormap import random_color, random_colors + + +class _DetectedInstance: + """ + Used to store data about detected objects in video frame, + in order to transfer color to objects in the future frames. + + Attributes: + label (int): + bbox (tuple[float]): + mask_rle (dict): + color (tuple[float]): RGB colors in range (0, 1) + ttl (int): time-to-live for the instance. For example, if ttl=2, + the instance color can be transferred to objects in the next two frames. + """ + + __slots__ = ["label", "bbox", "mask_rle", "color", "ttl"] + + def __init__(self, label, bbox, mask_rle, color, ttl): + self.label = label + self.bbox = bbox + self.mask_rle = mask_rle + self.color = color + self.ttl = ttl + + +class VideoVisualizer: + def __init__(self, metadata, instance_mode=ColorMode.IMAGE): + """ + Args: + metadata (MetadataCatalog): image metadata. + """ + self.metadata = metadata + self._old_instances = [] + assert instance_mode in [ + ColorMode.IMAGE, + ColorMode.IMAGE_BW, + ], "Other mode not supported yet." + self._instance_mode = instance_mode + self._max_num_instances = self.metadata.get("max_num_instances", 74) + self._assigned_colors = {} + self._color_pool = random_colors(self._max_num_instances, rgb=True, maximum=1) + self._color_idx_set = set(range(len(self._color_pool))) + + def draw_instance_predictions(self, frame, predictions): + """ + Draw instance-level prediction results on an image. + + Args: + frame (ndarray): an RGB image of shape (H, W, C), in the range [0, 255]. + predictions (Instances): the output of an instance detection/segmentation + model. Following fields will be used to draw: + "pred_boxes", "pred_classes", "scores", "pred_masks" (or "pred_masks_rle"). + + Returns: + output (VisImage): image object with visualizations. + """ + frame_visualizer = Visualizer(frame, self.metadata) + num_instances = len(predictions) + if num_instances == 0: + return frame_visualizer.output + + boxes = predictions.pred_boxes.tensor.numpy() if predictions.has("pred_boxes") else None + scores = predictions.scores if predictions.has("scores") else None + classes = predictions.pred_classes.numpy() if predictions.has("pred_classes") else None + keypoints = predictions.pred_keypoints if predictions.has("pred_keypoints") else None + colors = predictions.COLOR if predictions.has("COLOR") else [None] * len(predictions) + periods = predictions.ID_period if predictions.has("ID_period") else None + period_threshold = self.metadata.get("period_threshold", 0) + visibilities = ( + [True] * len(predictions) + if periods is None + else [x > period_threshold for x in periods] + ) + + if predictions.has("pred_masks"): + masks = predictions.pred_masks + # mask IOU is not yet enabled + # masks_rles = mask_util.encode(np.asarray(masks.permute(1, 2, 0), order="F")) + # assert len(masks_rles) == num_instances + else: + masks = None + + if not predictions.has("COLOR"): + if predictions.has("ID"): + colors = self._assign_colors_by_id(predictions) + else: + # ToDo: clean old assign color method and use a default tracker to assign id + detected = [ + _DetectedInstance(classes[i], boxes[i], mask_rle=None, color=colors[i], ttl=8) + for i in range(num_instances) + ] + colors = self._assign_colors(detected) + + labels = _create_text_labels(classes, scores, self.metadata.get("thing_classes", None)) + + if self._instance_mode == ColorMode.IMAGE_BW: + # any() returns uint8 tensor + frame_visualizer.output.reset_image( + frame_visualizer._create_grayscale_image( + (masks.any(dim=0) > 0).numpy() if masks is not None else None + ) + ) + alpha = 0.3 + else: + alpha = 0.5 + + labels = ( + None + if labels is None + else [y[0] for y in filter(lambda x: x[1], zip(labels, visibilities))] + ) # noqa + assigned_colors = ( + None + if colors is None + else [y[0] for y in filter(lambda x: x[1], zip(colors, visibilities))] + ) # noqa + frame_visualizer.overlay_instances( + boxes=None if masks is not None else boxes[visibilities], # boxes are a bit distracting + masks=None if masks is None else masks[visibilities], + labels=labels, + keypoints=None if keypoints is None else keypoints[visibilities], + assigned_colors=assigned_colors, + alpha=alpha, + ) + + return frame_visualizer.output + + def draw_sem_seg(self, frame, sem_seg, area_threshold=None): + """ + Args: + sem_seg (ndarray or Tensor): semantic segmentation of shape (H, W), + each value is the integer label. + area_threshold (Optional[int]): only draw segmentations larger than the threshold + """ + # don't need to do anything special + frame_visualizer = Visualizer(frame, self.metadata) + frame_visualizer.draw_sem_seg(sem_seg, area_threshold=None) + return frame_visualizer.output + + def draw_panoptic_seg_predictions( + self, frame, panoptic_seg, segments_info, area_threshold=None, alpha=0.5 + ): + frame_visualizer = Visualizer(frame, self.metadata) + pred = _PanopticPrediction(panoptic_seg, segments_info, self.metadata) + + if self._instance_mode == ColorMode.IMAGE_BW: + frame_visualizer.output.reset_image( + frame_visualizer._create_grayscale_image(pred.non_empty_mask()) + ) + + # draw mask for all semantic segments first i.e. "stuff" + for mask, sinfo in pred.semantic_masks(): + category_idx = sinfo["category_id"] + try: + mask_color = [x / 255 for x in self.metadata.stuff_colors[category_idx]] + except AttributeError: + mask_color = None + + frame_visualizer.draw_binary_mask( + mask, + color=mask_color, + text=self.metadata.stuff_classes[category_idx], + alpha=alpha, + area_threshold=area_threshold, + ) + + all_instances = list(pred.instance_masks()) + if len(all_instances) == 0: + return frame_visualizer.output + # draw mask for all instances second + masks, sinfo = list(zip(*all_instances)) + num_instances = len(masks) + masks_rles = mask_util.encode( + np.asarray(np.asarray(masks).transpose(1, 2, 0), dtype=np.uint8, order="F") + ) + assert len(masks_rles) == num_instances + + category_ids = [x["category_id"] for x in sinfo] + detected = [ + _DetectedInstance(category_ids[i], bbox=None, mask_rle=masks_rles[i], color=None, ttl=8) + for i in range(num_instances) + ] + colors = self._assign_colors(detected) + labels = [self.metadata.thing_classes[k] for k in category_ids] + + frame_visualizer.overlay_instances( + boxes=None, + masks=masks, + labels=labels, + keypoints=None, + assigned_colors=colors, + alpha=alpha, + ) + return frame_visualizer.output + + def _assign_colors(self, instances): + """ + Naive tracking heuristics to assign same color to the same instance, + will update the internal state of tracked instances. + + Returns: + list[tuple[float]]: list of colors. + """ + + # Compute iou with either boxes or masks: + is_crowd = np.zeros((len(instances),), dtype=bool) + if instances[0].bbox is None: + assert instances[0].mask_rle is not None + # use mask iou only when box iou is None + # because box seems good enough + rles_old = [x.mask_rle for x in self._old_instances] + rles_new = [x.mask_rle for x in instances] + ious = mask_util.iou(rles_old, rles_new, is_crowd) + threshold = 0.5 + else: + boxes_old = [x.bbox for x in self._old_instances] + boxes_new = [x.bbox for x in instances] + ious = mask_util.iou(boxes_old, boxes_new, is_crowd) + threshold = 0.6 + if len(ious) == 0: + ious = np.zeros((len(self._old_instances), len(instances)), dtype="float32") + + # Only allow matching instances of the same label: + for old_idx, old in enumerate(self._old_instances): + for new_idx, new in enumerate(instances): + if old.label != new.label: + ious[old_idx, new_idx] = 0 + + matched_new_per_old = np.asarray(ious).argmax(axis=1) + max_iou_per_old = np.asarray(ious).max(axis=1) + + # Try to find match for each old instance: + extra_instances = [] + for idx, inst in enumerate(self._old_instances): + if max_iou_per_old[idx] > threshold: + newidx = matched_new_per_old[idx] + if instances[newidx].color is None: + instances[newidx].color = inst.color + continue + # If an old instance does not match any new instances, + # keep it for the next frame in case it is just missed by the detector + inst.ttl -= 1 + if inst.ttl > 0: + extra_instances.append(inst) + + # Assign random color to newly-detected instances: + for inst in instances: + if inst.color is None: + inst.color = random_color(rgb=True, maximum=1) + self._old_instances = instances[:] + extra_instances + return [d.color for d in instances] + + def _assign_colors_by_id(self, instances: Instances) -> List: + colors = [] + untracked_ids = set(self._assigned_colors.keys()) + for id in instances.ID: + if id in self._assigned_colors: + colors.append(self._color_pool[self._assigned_colors[id]]) + untracked_ids.remove(id) + else: + assert ( + len(self._color_idx_set) >= 1 + ), f"Number of id exceeded maximum, \ + max = {self._max_num_instances}" + idx = self._color_idx_set.pop() + color = self._color_pool[idx] + self._assigned_colors[id] = idx + colors.append(color) + for id in untracked_ids: + self._color_idx_set.add(self._assigned_colors[id]) + del self._assigned_colors[id] + return colors diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/visualizer.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/visualizer.py new file mode 100644 index 00000000..48e91543 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/detectron2/utils/visualizer.py @@ -0,0 +1,1267 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +import colorsys +import logging +import math +import numpy as np +from enum import Enum, unique +import cv2 +import matplotlib as mpl +import matplotlib.colors as mplc +import matplotlib.figure as mplfigure +import annotator.oneformer.pycocotools.mask as mask_util +import torch +from matplotlib.backends.backend_agg import FigureCanvasAgg +from PIL import Image + +from annotator.oneformer.detectron2.data import MetadataCatalog +from annotator.oneformer.detectron2.structures import BitMasks, Boxes, BoxMode, Keypoints, PolygonMasks, RotatedBoxes +from annotator.oneformer.detectron2.utils.file_io import PathManager + +from .colormap import random_color + +logger = logging.getLogger(__name__) + +__all__ = ["ColorMode", "VisImage", "Visualizer"] + + +_SMALL_OBJECT_AREA_THRESH = 1000 +_LARGE_MASK_AREA_THRESH = 120000 +_OFF_WHITE = (1.0, 1.0, 240.0 / 255) +_BLACK = (0, 0, 0) +_RED = (1.0, 0, 0) + +_KEYPOINT_THRESHOLD = 0.05 + + +@unique +class ColorMode(Enum): + """ + Enum of different color modes to use for instance visualizations. + """ + + IMAGE = 0 + """ + Picks a random color for every instance and overlay segmentations with low opacity. + """ + SEGMENTATION = 1 + """ + Let instances of the same category have similar colors + (from metadata.thing_colors), and overlay them with + high opacity. This provides more attention on the quality of segmentation. + """ + IMAGE_BW = 2 + """ + Same as IMAGE, but convert all areas without masks to gray-scale. + Only available for drawing per-instance mask predictions. + """ + + +class GenericMask: + """ + Attribute: + polygons (list[ndarray]): list[ndarray]: polygons for this mask. + Each ndarray has format [x, y, x, y, ...] + mask (ndarray): a binary mask + """ + + def __init__(self, mask_or_polygons, height, width): + self._mask = self._polygons = self._has_holes = None + self.height = height + self.width = width + + m = mask_or_polygons + if isinstance(m, dict): + # RLEs + assert "counts" in m and "size" in m + if isinstance(m["counts"], list): # uncompressed RLEs + h, w = m["size"] + assert h == height and w == width + m = mask_util.frPyObjects(m, h, w) + self._mask = mask_util.decode(m)[:, :] + return + + if isinstance(m, list): # list[ndarray] + self._polygons = [np.asarray(x).reshape(-1) for x in m] + return + + if isinstance(m, np.ndarray): # assumed to be a binary mask + assert m.shape[1] != 2, m.shape + assert m.shape == ( + height, + width, + ), f"mask shape: {m.shape}, target dims: {height}, {width}" + self._mask = m.astype("uint8") + return + + raise ValueError("GenericMask cannot handle object {} of type '{}'".format(m, type(m))) + + @property + def mask(self): + if self._mask is None: + self._mask = self.polygons_to_mask(self._polygons) + return self._mask + + @property + def polygons(self): + if self._polygons is None: + self._polygons, self._has_holes = self.mask_to_polygons(self._mask) + return self._polygons + + @property + def has_holes(self): + if self._has_holes is None: + if self._mask is not None: + self._polygons, self._has_holes = self.mask_to_polygons(self._mask) + else: + self._has_holes = False # if original format is polygon, does not have holes + return self._has_holes + + def mask_to_polygons(self, mask): + # cv2.RETR_CCOMP flag retrieves all the contours and arranges them to a 2-level + # hierarchy. External contours (boundary) of the object are placed in hierarchy-1. + # Internal contours (holes) are placed in hierarchy-2. + # cv2.CHAIN_APPROX_NONE flag gets vertices of polygons from contours. + mask = np.ascontiguousarray(mask) # some versions of cv2 does not support incontiguous arr + res = cv2.findContours(mask.astype("uint8"), cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE) + hierarchy = res[-1] + if hierarchy is None: # empty mask + return [], False + has_holes = (hierarchy.reshape(-1, 4)[:, 3] >= 0).sum() > 0 + res = res[-2] + res = [x.flatten() for x in res] + # These coordinates from OpenCV are integers in range [0, W-1 or H-1]. + # We add 0.5 to turn them into real-value coordinate space. A better solution + # would be to first +0.5 and then dilate the returned polygon by 0.5. + res = [x + 0.5 for x in res if len(x) >= 6] + return res, has_holes + + def polygons_to_mask(self, polygons): + rle = mask_util.frPyObjects(polygons, self.height, self.width) + rle = mask_util.merge(rle) + return mask_util.decode(rle)[:, :] + + def area(self): + return self.mask.sum() + + def bbox(self): + p = mask_util.frPyObjects(self.polygons, self.height, self.width) + p = mask_util.merge(p) + bbox = mask_util.toBbox(p) + bbox[2] += bbox[0] + bbox[3] += bbox[1] + return bbox + + +class _PanopticPrediction: + """ + Unify different panoptic annotation/prediction formats + """ + + def __init__(self, panoptic_seg, segments_info, metadata=None): + if segments_info is None: + assert metadata is not None + # If "segments_info" is None, we assume "panoptic_img" is a + # H*W int32 image storing the panoptic_id in the format of + # category_id * label_divisor + instance_id. We reserve -1 for + # VOID label. + label_divisor = metadata.label_divisor + segments_info = [] + for panoptic_label in np.unique(panoptic_seg.numpy()): + if panoptic_label == -1: + # VOID region. + continue + pred_class = panoptic_label // label_divisor + isthing = pred_class in metadata.thing_dataset_id_to_contiguous_id.values() + segments_info.append( + { + "id": int(panoptic_label), + "category_id": int(pred_class), + "isthing": bool(isthing), + } + ) + del metadata + + self._seg = panoptic_seg + + self._sinfo = {s["id"]: s for s in segments_info} # seg id -> seg info + segment_ids, areas = torch.unique(panoptic_seg, sorted=True, return_counts=True) + areas = areas.numpy() + sorted_idxs = np.argsort(-areas) + self._seg_ids, self._seg_areas = segment_ids[sorted_idxs], areas[sorted_idxs] + self._seg_ids = self._seg_ids.tolist() + for sid, area in zip(self._seg_ids, self._seg_areas): + if sid in self._sinfo: + self._sinfo[sid]["area"] = float(area) + + def non_empty_mask(self): + """ + Returns: + (H, W) array, a mask for all pixels that have a prediction + """ + empty_ids = [] + for id in self._seg_ids: + if id not in self._sinfo: + empty_ids.append(id) + if len(empty_ids) == 0: + return np.zeros(self._seg.shape, dtype=np.uint8) + assert ( + len(empty_ids) == 1 + ), ">1 ids corresponds to no labels. This is currently not supported" + return (self._seg != empty_ids[0]).numpy().astype(bool) + + def semantic_masks(self): + for sid in self._seg_ids: + sinfo = self._sinfo.get(sid) + if sinfo is None or sinfo["isthing"]: + # Some pixels (e.g. id 0 in PanopticFPN) have no instance or semantic predictions. + continue + yield (self._seg == sid).numpy().astype(bool), sinfo + + def instance_masks(self): + for sid in self._seg_ids: + sinfo = self._sinfo.get(sid) + if sinfo is None or not sinfo["isthing"]: + continue + mask = (self._seg == sid).numpy().astype(bool) + if mask.sum() > 0: + yield mask, sinfo + + +def _create_text_labels(classes, scores, class_names, is_crowd=None): + """ + Args: + classes (list[int] or None): + scores (list[float] or None): + class_names (list[str] or None): + is_crowd (list[bool] or None): + + Returns: + list[str] or None + """ + labels = None + if classes is not None: + if class_names is not None and len(class_names) > 0: + labels = [class_names[i] for i in classes] + else: + labels = [str(i) for i in classes] + if scores is not None: + if labels is None: + labels = ["{:.0f}%".format(s * 100) for s in scores] + else: + labels = ["{} {:.0f}%".format(l, s * 100) for l, s in zip(labels, scores)] + if labels is not None and is_crowd is not None: + labels = [l + ("|crowd" if crowd else "") for l, crowd in zip(labels, is_crowd)] + return labels + + +class VisImage: + def __init__(self, img, scale=1.0): + """ + Args: + img (ndarray): an RGB image of shape (H, W, 3) in range [0, 255]. + scale (float): scale the input image + """ + self.img = img + self.scale = scale + self.width, self.height = img.shape[1], img.shape[0] + self._setup_figure(img) + + def _setup_figure(self, img): + """ + Args: + Same as in :meth:`__init__()`. + + Returns: + fig (matplotlib.pyplot.figure): top level container for all the image plot elements. + ax (matplotlib.pyplot.Axes): contains figure elements and sets the coordinate system. + """ + fig = mplfigure.Figure(frameon=False) + self.dpi = fig.get_dpi() + # add a small 1e-2 to avoid precision lost due to matplotlib's truncation + # (https://github.com/matplotlib/matplotlib/issues/15363) + fig.set_size_inches( + (self.width * self.scale + 1e-2) / self.dpi, + (self.height * self.scale + 1e-2) / self.dpi, + ) + self.canvas = FigureCanvasAgg(fig) + # self.canvas = mpl.backends.backend_cairo.FigureCanvasCairo(fig) + ax = fig.add_axes([0.0, 0.0, 1.0, 1.0]) + ax.axis("off") + self.fig = fig + self.ax = ax + self.reset_image(img) + + def reset_image(self, img): + """ + Args: + img: same as in __init__ + """ + img = img.astype("uint8") + self.ax.imshow(img, extent=(0, self.width, self.height, 0), interpolation="nearest") + + def save(self, filepath): + """ + Args: + filepath (str): a string that contains the absolute path, including the file name, where + the visualized image will be saved. + """ + self.fig.savefig(filepath) + + def get_image(self): + """ + Returns: + ndarray: + the visualized image of shape (H, W, 3) (RGB) in uint8 type. + The shape is scaled w.r.t the input image using the given `scale` argument. + """ + canvas = self.canvas + s, (width, height) = canvas.print_to_buffer() + # buf = io.BytesIO() # works for cairo backend + # canvas.print_rgba(buf) + # width, height = self.width, self.height + # s = buf.getvalue() + + buffer = np.frombuffer(s, dtype="uint8") + + img_rgba = buffer.reshape(height, width, 4) + rgb, alpha = np.split(img_rgba, [3], axis=2) + return rgb.astype("uint8") + + +class Visualizer: + """ + Visualizer that draws data about detection/segmentation on images. + + It contains methods like `draw_{text,box,circle,line,binary_mask,polygon}` + that draw primitive objects to images, as well as high-level wrappers like + `draw_{instance_predictions,sem_seg,panoptic_seg_predictions,dataset_dict}` + that draw composite data in some pre-defined style. + + Note that the exact visualization style for the high-level wrappers are subject to change. + Style such as color, opacity, label contents, visibility of labels, or even the visibility + of objects themselves (e.g. when the object is too small) may change according + to different heuristics, as long as the results still look visually reasonable. + + To obtain a consistent style, you can implement custom drawing functions with the + abovementioned primitive methods instead. If you need more customized visualization + styles, you can process the data yourself following their format documented in + tutorials (:doc:`/tutorials/models`, :doc:`/tutorials/datasets`). This class does not + intend to satisfy everyone's preference on drawing styles. + + This visualizer focuses on high rendering quality rather than performance. It is not + designed to be used for real-time applications. + """ + + # TODO implement a fast, rasterized version using OpenCV + + def __init__(self, img_rgb, metadata=None, scale=1.0, instance_mode=ColorMode.IMAGE): + """ + Args: + img_rgb: a numpy array of shape (H, W, C), where H and W correspond to + the height and width of the image respectively. C is the number of + color channels. The image is required to be in RGB format since that + is a requirement of the Matplotlib library. The image is also expected + to be in the range [0, 255]. + metadata (Metadata): dataset metadata (e.g. class names and colors) + instance_mode (ColorMode): defines one of the pre-defined style for drawing + instances on an image. + """ + self.img = np.asarray(img_rgb).clip(0, 255).astype(np.uint8) + if metadata is None: + metadata = MetadataCatalog.get("__nonexist__") + self.metadata = metadata + self.output = VisImage(self.img, scale=scale) + self.cpu_device = torch.device("cpu") + + # too small texts are useless, therefore clamp to 9 + self._default_font_size = max( + np.sqrt(self.output.height * self.output.width) // 90, 10 // scale + ) + self._instance_mode = instance_mode + self.keypoint_threshold = _KEYPOINT_THRESHOLD + + def draw_instance_predictions(self, predictions): + """ + Draw instance-level prediction results on an image. + + Args: + predictions (Instances): the output of an instance detection/segmentation + model. Following fields will be used to draw: + "pred_boxes", "pred_classes", "scores", "pred_masks" (or "pred_masks_rle"). + + Returns: + output (VisImage): image object with visualizations. + """ + boxes = predictions.pred_boxes if predictions.has("pred_boxes") else None + scores = predictions.scores if predictions.has("scores") else None + classes = predictions.pred_classes.tolist() if predictions.has("pred_classes") else None + labels = _create_text_labels(classes, scores, self.metadata.get("thing_classes", None)) + keypoints = predictions.pred_keypoints if predictions.has("pred_keypoints") else None + + if predictions.has("pred_masks"): + masks = np.asarray(predictions.pred_masks) + masks = [GenericMask(x, self.output.height, self.output.width) for x in masks] + else: + masks = None + + if self._instance_mode == ColorMode.SEGMENTATION and self.metadata.get("thing_colors"): + colors = [ + self._jitter([x / 255 for x in self.metadata.thing_colors[c]]) for c in classes + ] + alpha = 0.8 + else: + colors = None + alpha = 0.5 + + if self._instance_mode == ColorMode.IMAGE_BW: + self.output.reset_image( + self._create_grayscale_image( + (predictions.pred_masks.any(dim=0) > 0).numpy() + if predictions.has("pred_masks") + else None + ) + ) + alpha = 0.3 + + self.overlay_instances( + masks=masks, + boxes=boxes, + labels=labels, + keypoints=keypoints, + assigned_colors=colors, + alpha=alpha, + ) + return self.output + + def draw_sem_seg(self, sem_seg, area_threshold=None, alpha=0.8): + """ + Draw semantic segmentation predictions/labels. + + Args: + sem_seg (Tensor or ndarray): the segmentation of shape (H, W). + Each value is the integer label of the pixel. + area_threshold (int): segments with less than `area_threshold` are not drawn. + alpha (float): the larger it is, the more opaque the segmentations are. + + Returns: + output (VisImage): image object with visualizations. + """ + if isinstance(sem_seg, torch.Tensor): + sem_seg = sem_seg.numpy() + labels, areas = np.unique(sem_seg, return_counts=True) + sorted_idxs = np.argsort(-areas).tolist() + labels = labels[sorted_idxs] + for label in filter(lambda l: l < len(self.metadata.stuff_classes), labels): + try: + mask_color = [x / 255 for x in self.metadata.stuff_colors[label]] + except (AttributeError, IndexError): + mask_color = None + + binary_mask = (sem_seg == label).astype(np.uint8) + text = self.metadata.stuff_classes[label] + self.draw_binary_mask( + binary_mask, + color=mask_color, + edge_color=_OFF_WHITE, + text=text, + alpha=alpha, + area_threshold=area_threshold, + ) + return self.output + + def draw_panoptic_seg(self, panoptic_seg, segments_info, area_threshold=None, alpha=0.7): + """ + Draw panoptic prediction annotations or results. + + Args: + panoptic_seg (Tensor): of shape (height, width) where the values are ids for each + segment. + segments_info (list[dict] or None): Describe each segment in `panoptic_seg`. + If it is a ``list[dict]``, each dict contains keys "id", "category_id". + If None, category id of each pixel is computed by + ``pixel // metadata.label_divisor``. + area_threshold (int): stuff segments with less than `area_threshold` are not drawn. + + Returns: + output (VisImage): image object with visualizations. + """ + pred = _PanopticPrediction(panoptic_seg, segments_info, self.metadata) + + if self._instance_mode == ColorMode.IMAGE_BW: + self.output.reset_image(self._create_grayscale_image(pred.non_empty_mask())) + + # draw mask for all semantic segments first i.e. "stuff" + for mask, sinfo in pred.semantic_masks(): + category_idx = sinfo["category_id"] + try: + mask_color = [x / 255 for x in self.metadata.stuff_colors[category_idx]] + except AttributeError: + mask_color = None + + text = self.metadata.stuff_classes[category_idx] + self.draw_binary_mask( + mask, + color=mask_color, + edge_color=_OFF_WHITE, + text=text, + alpha=alpha, + area_threshold=area_threshold, + ) + + # draw mask for all instances second + all_instances = list(pred.instance_masks()) + if len(all_instances) == 0: + return self.output + masks, sinfo = list(zip(*all_instances)) + category_ids = [x["category_id"] for x in sinfo] + + try: + scores = [x["score"] for x in sinfo] + except KeyError: + scores = None + labels = _create_text_labels( + category_ids, scores, self.metadata.thing_classes, [x.get("iscrowd", 0) for x in sinfo] + ) + + try: + colors = [ + self._jitter([x / 255 for x in self.metadata.thing_colors[c]]) for c in category_ids + ] + except AttributeError: + colors = None + self.overlay_instances(masks=masks, labels=labels, assigned_colors=colors, alpha=alpha) + + return self.output + + draw_panoptic_seg_predictions = draw_panoptic_seg # backward compatibility + + def draw_dataset_dict(self, dic): + """ + Draw annotations/segmentations in Detectron2 Dataset format. + + Args: + dic (dict): annotation/segmentation data of one image, in Detectron2 Dataset format. + + Returns: + output (VisImage): image object with visualizations. + """ + annos = dic.get("annotations", None) + if annos: + if "segmentation" in annos[0]: + masks = [x["segmentation"] for x in annos] + else: + masks = None + if "keypoints" in annos[0]: + keypts = [x["keypoints"] for x in annos] + keypts = np.array(keypts).reshape(len(annos), -1, 3) + else: + keypts = None + + boxes = [ + BoxMode.convert(x["bbox"], x["bbox_mode"], BoxMode.XYXY_ABS) + if len(x["bbox"]) == 4 + else x["bbox"] + for x in annos + ] + + colors = None + category_ids = [x["category_id"] for x in annos] + if self._instance_mode == ColorMode.SEGMENTATION and self.metadata.get("thing_colors"): + colors = [ + self._jitter([x / 255 for x in self.metadata.thing_colors[c]]) + for c in category_ids + ] + names = self.metadata.get("thing_classes", None) + labels = _create_text_labels( + category_ids, + scores=None, + class_names=names, + is_crowd=[x.get("iscrowd", 0) for x in annos], + ) + self.overlay_instances( + labels=labels, boxes=boxes, masks=masks, keypoints=keypts, assigned_colors=colors + ) + + sem_seg = dic.get("sem_seg", None) + if sem_seg is None and "sem_seg_file_name" in dic: + with PathManager.open(dic["sem_seg_file_name"], "rb") as f: + sem_seg = Image.open(f) + sem_seg = np.asarray(sem_seg, dtype="uint8") + if sem_seg is not None: + self.draw_sem_seg(sem_seg, area_threshold=0, alpha=0.5) + + pan_seg = dic.get("pan_seg", None) + if pan_seg is None and "pan_seg_file_name" in dic: + with PathManager.open(dic["pan_seg_file_name"], "rb") as f: + pan_seg = Image.open(f) + pan_seg = np.asarray(pan_seg) + from panopticapi.utils import rgb2id + + pan_seg = rgb2id(pan_seg) + if pan_seg is not None: + segments_info = dic["segments_info"] + pan_seg = torch.tensor(pan_seg) + self.draw_panoptic_seg(pan_seg, segments_info, area_threshold=0, alpha=0.5) + return self.output + + def overlay_instances( + self, + *, + boxes=None, + labels=None, + masks=None, + keypoints=None, + assigned_colors=None, + alpha=0.5, + ): + """ + Args: + boxes (Boxes, RotatedBoxes or ndarray): either a :class:`Boxes`, + or an Nx4 numpy array of XYXY_ABS format for the N objects in a single image, + or a :class:`RotatedBoxes`, + or an Nx5 numpy array of (x_center, y_center, width, height, angle_degrees) format + for the N objects in a single image, + labels (list[str]): the text to be displayed for each instance. + masks (masks-like object): Supported types are: + + * :class:`detectron2.structures.PolygonMasks`, + :class:`detectron2.structures.BitMasks`. + * list[list[ndarray]]: contains the segmentation masks for all objects in one image. + The first level of the list corresponds to individual instances. The second + level to all the polygon that compose the instance, and the third level + to the polygon coordinates. The third level should have the format of + [x0, y0, x1, y1, ..., xn, yn] (n >= 3). + * list[ndarray]: each ndarray is a binary mask of shape (H, W). + * list[dict]: each dict is a COCO-style RLE. + keypoints (Keypoint or array like): an array-like object of shape (N, K, 3), + where the N is the number of instances and K is the number of keypoints. + The last dimension corresponds to (x, y, visibility or score). + assigned_colors (list[matplotlib.colors]): a list of colors, where each color + corresponds to each mask or box in the image. Refer to 'matplotlib.colors' + for full list of formats that the colors are accepted in. + Returns: + output (VisImage): image object with visualizations. + """ + num_instances = 0 + if boxes is not None: + boxes = self._convert_boxes(boxes) + num_instances = len(boxes) + if masks is not None: + masks = self._convert_masks(masks) + if num_instances: + assert len(masks) == num_instances + else: + num_instances = len(masks) + if keypoints is not None: + if num_instances: + assert len(keypoints) == num_instances + else: + num_instances = len(keypoints) + keypoints = self._convert_keypoints(keypoints) + if labels is not None: + assert len(labels) == num_instances + if assigned_colors is None: + assigned_colors = [random_color(rgb=True, maximum=1) for _ in range(num_instances)] + if num_instances == 0: + return self.output + if boxes is not None and boxes.shape[1] == 5: + return self.overlay_rotated_instances( + boxes=boxes, labels=labels, assigned_colors=assigned_colors + ) + + # Display in largest to smallest order to reduce occlusion. + areas = None + if boxes is not None: + areas = np.prod(boxes[:, 2:] - boxes[:, :2], axis=1) + elif masks is not None: + areas = np.asarray([x.area() for x in masks]) + + if areas is not None: + sorted_idxs = np.argsort(-areas).tolist() + # Re-order overlapped instances in descending order. + boxes = boxes[sorted_idxs] if boxes is not None else None + labels = [labels[k] for k in sorted_idxs] if labels is not None else None + masks = [masks[idx] for idx in sorted_idxs] if masks is not None else None + assigned_colors = [assigned_colors[idx] for idx in sorted_idxs] + keypoints = keypoints[sorted_idxs] if keypoints is not None else None + + for i in range(num_instances): + color = assigned_colors[i] + if boxes is not None: + self.draw_box(boxes[i], edge_color=color) + + if masks is not None: + for segment in masks[i].polygons: + self.draw_polygon(segment.reshape(-1, 2), color, alpha=alpha) + + if labels is not None: + # first get a box + if boxes is not None: + x0, y0, x1, y1 = boxes[i] + text_pos = (x0, y0) # if drawing boxes, put text on the box corner. + horiz_align = "left" + elif masks is not None: + # skip small mask without polygon + if len(masks[i].polygons) == 0: + continue + + x0, y0, x1, y1 = masks[i].bbox() + + # draw text in the center (defined by median) when box is not drawn + # median is less sensitive to outliers. + text_pos = np.median(masks[i].mask.nonzero(), axis=1)[::-1] + horiz_align = "center" + else: + continue # drawing the box confidence for keypoints isn't very useful. + # for small objects, draw text at the side to avoid occlusion + instance_area = (y1 - y0) * (x1 - x0) + if ( + instance_area < _SMALL_OBJECT_AREA_THRESH * self.output.scale + or y1 - y0 < 40 * self.output.scale + ): + if y1 >= self.output.height - 5: + text_pos = (x1, y0) + else: + text_pos = (x0, y1) + + height_ratio = (y1 - y0) / np.sqrt(self.output.height * self.output.width) + lighter_color = self._change_color_brightness(color, brightness_factor=0.7) + font_size = ( + np.clip((height_ratio - 0.02) / 0.08 + 1, 1.2, 2) + * 0.5 + * self._default_font_size + ) + self.draw_text( + labels[i], + text_pos, + color=lighter_color, + horizontal_alignment=horiz_align, + font_size=font_size, + ) + + # draw keypoints + if keypoints is not None: + for keypoints_per_instance in keypoints: + self.draw_and_connect_keypoints(keypoints_per_instance) + + return self.output + + def overlay_rotated_instances(self, boxes=None, labels=None, assigned_colors=None): + """ + Args: + boxes (ndarray): an Nx5 numpy array of + (x_center, y_center, width, height, angle_degrees) format + for the N objects in a single image. + labels (list[str]): the text to be displayed for each instance. + assigned_colors (list[matplotlib.colors]): a list of colors, where each color + corresponds to each mask or box in the image. Refer to 'matplotlib.colors' + for full list of formats that the colors are accepted in. + + Returns: + output (VisImage): image object with visualizations. + """ + num_instances = len(boxes) + + if assigned_colors is None: + assigned_colors = [random_color(rgb=True, maximum=1) for _ in range(num_instances)] + if num_instances == 0: + return self.output + + # Display in largest to smallest order to reduce occlusion. + if boxes is not None: + areas = boxes[:, 2] * boxes[:, 3] + + sorted_idxs = np.argsort(-areas).tolist() + # Re-order overlapped instances in descending order. + boxes = boxes[sorted_idxs] + labels = [labels[k] for k in sorted_idxs] if labels is not None else None + colors = [assigned_colors[idx] for idx in sorted_idxs] + + for i in range(num_instances): + self.draw_rotated_box_with_label( + boxes[i], edge_color=colors[i], label=labels[i] if labels is not None else None + ) + + return self.output + + def draw_and_connect_keypoints(self, keypoints): + """ + Draws keypoints of an instance and follows the rules for keypoint connections + to draw lines between appropriate keypoints. This follows color heuristics for + line color. + + Args: + keypoints (Tensor): a tensor of shape (K, 3), where K is the number of keypoints + and the last dimension corresponds to (x, y, probability). + + Returns: + output (VisImage): image object with visualizations. + """ + visible = {} + keypoint_names = self.metadata.get("keypoint_names") + for idx, keypoint in enumerate(keypoints): + + # draw keypoint + x, y, prob = keypoint + if prob > self.keypoint_threshold: + self.draw_circle((x, y), color=_RED) + if keypoint_names: + keypoint_name = keypoint_names[idx] + visible[keypoint_name] = (x, y) + + if self.metadata.get("keypoint_connection_rules"): + for kp0, kp1, color in self.metadata.keypoint_connection_rules: + if kp0 in visible and kp1 in visible: + x0, y0 = visible[kp0] + x1, y1 = visible[kp1] + color = tuple(x / 255.0 for x in color) + self.draw_line([x0, x1], [y0, y1], color=color) + + # draw lines from nose to mid-shoulder and mid-shoulder to mid-hip + # Note that this strategy is specific to person keypoints. + # For other keypoints, it should just do nothing + try: + ls_x, ls_y = visible["left_shoulder"] + rs_x, rs_y = visible["right_shoulder"] + mid_shoulder_x, mid_shoulder_y = (ls_x + rs_x) / 2, (ls_y + rs_y) / 2 + except KeyError: + pass + else: + # draw line from nose to mid-shoulder + nose_x, nose_y = visible.get("nose", (None, None)) + if nose_x is not None: + self.draw_line([nose_x, mid_shoulder_x], [nose_y, mid_shoulder_y], color=_RED) + + try: + # draw line from mid-shoulder to mid-hip + lh_x, lh_y = visible["left_hip"] + rh_x, rh_y = visible["right_hip"] + except KeyError: + pass + else: + mid_hip_x, mid_hip_y = (lh_x + rh_x) / 2, (lh_y + rh_y) / 2 + self.draw_line([mid_hip_x, mid_shoulder_x], [mid_hip_y, mid_shoulder_y], color=_RED) + return self.output + + """ + Primitive drawing functions: + """ + + def draw_text( + self, + text, + position, + *, + font_size=None, + color="g", + horizontal_alignment="center", + rotation=0, + ): + """ + Args: + text (str): class label + position (tuple): a tuple of the x and y coordinates to place text on image. + font_size (int, optional): font of the text. If not provided, a font size + proportional to the image width is calculated and used. + color: color of the text. Refer to `matplotlib.colors` for full list + of formats that are accepted. + horizontal_alignment (str): see `matplotlib.text.Text` + rotation: rotation angle in degrees CCW + + Returns: + output (VisImage): image object with text drawn. + """ + if not font_size: + font_size = self._default_font_size + + # since the text background is dark, we don't want the text to be dark + color = np.maximum(list(mplc.to_rgb(color)), 0.2) + color[np.argmax(color)] = max(0.8, np.max(color)) + + x, y = position + self.output.ax.text( + x, + y, + text, + size=font_size * self.output.scale, + family="sans-serif", + bbox={"facecolor": "black", "alpha": 0.8, "pad": 0.7, "edgecolor": "none"}, + verticalalignment="top", + horizontalalignment=horizontal_alignment, + color=color, + zorder=10, + rotation=rotation, + ) + return self.output + + def draw_box(self, box_coord, alpha=0.5, edge_color="g", line_style="-"): + """ + Args: + box_coord (tuple): a tuple containing x0, y0, x1, y1 coordinates, where x0 and y0 + are the coordinates of the image's top left corner. x1 and y1 are the + coordinates of the image's bottom right corner. + alpha (float): blending efficient. Smaller values lead to more transparent masks. + edge_color: color of the outline of the box. Refer to `matplotlib.colors` + for full list of formats that are accepted. + line_style (string): the string to use to create the outline of the boxes. + + Returns: + output (VisImage): image object with box drawn. + """ + x0, y0, x1, y1 = box_coord + width = x1 - x0 + height = y1 - y0 + + linewidth = max(self._default_font_size / 4, 1) + + self.output.ax.add_patch( + mpl.patches.Rectangle( + (x0, y0), + width, + height, + fill=False, + edgecolor=edge_color, + linewidth=linewidth * self.output.scale, + alpha=alpha, + linestyle=line_style, + ) + ) + return self.output + + def draw_rotated_box_with_label( + self, rotated_box, alpha=0.5, edge_color="g", line_style="-", label=None + ): + """ + Draw a rotated box with label on its top-left corner. + + Args: + rotated_box (tuple): a tuple containing (cnt_x, cnt_y, w, h, angle), + where cnt_x and cnt_y are the center coordinates of the box. + w and h are the width and height of the box. angle represents how + many degrees the box is rotated CCW with regard to the 0-degree box. + alpha (float): blending efficient. Smaller values lead to more transparent masks. + edge_color: color of the outline of the box. Refer to `matplotlib.colors` + for full list of formats that are accepted. + line_style (string): the string to use to create the outline of the boxes. + label (string): label for rotated box. It will not be rendered when set to None. + + Returns: + output (VisImage): image object with box drawn. + """ + cnt_x, cnt_y, w, h, angle = rotated_box + area = w * h + # use thinner lines when the box is small + linewidth = self._default_font_size / ( + 6 if area < _SMALL_OBJECT_AREA_THRESH * self.output.scale else 3 + ) + + theta = angle * math.pi / 180.0 + c = math.cos(theta) + s = math.sin(theta) + rect = [(-w / 2, h / 2), (-w / 2, -h / 2), (w / 2, -h / 2), (w / 2, h / 2)] + # x: left->right ; y: top->down + rotated_rect = [(s * yy + c * xx + cnt_x, c * yy - s * xx + cnt_y) for (xx, yy) in rect] + for k in range(4): + j = (k + 1) % 4 + self.draw_line( + [rotated_rect[k][0], rotated_rect[j][0]], + [rotated_rect[k][1], rotated_rect[j][1]], + color=edge_color, + linestyle="--" if k == 1 else line_style, + linewidth=linewidth, + ) + + if label is not None: + text_pos = rotated_rect[1] # topleft corner + + height_ratio = h / np.sqrt(self.output.height * self.output.width) + label_color = self._change_color_brightness(edge_color, brightness_factor=0.7) + font_size = ( + np.clip((height_ratio - 0.02) / 0.08 + 1, 1.2, 2) * 0.5 * self._default_font_size + ) + self.draw_text(label, text_pos, color=label_color, font_size=font_size, rotation=angle) + + return self.output + + def draw_circle(self, circle_coord, color, radius=3): + """ + Args: + circle_coord (list(int) or tuple(int)): contains the x and y coordinates + of the center of the circle. + color: color of the polygon. Refer to `matplotlib.colors` for a full list of + formats that are accepted. + radius (int): radius of the circle. + + Returns: + output (VisImage): image object with box drawn. + """ + x, y = circle_coord + self.output.ax.add_patch( + mpl.patches.Circle(circle_coord, radius=radius, fill=True, color=color) + ) + return self.output + + def draw_line(self, x_data, y_data, color, linestyle="-", linewidth=None): + """ + Args: + x_data (list[int]): a list containing x values of all the points being drawn. + Length of list should match the length of y_data. + y_data (list[int]): a list containing y values of all the points being drawn. + Length of list should match the length of x_data. + color: color of the line. Refer to `matplotlib.colors` for a full list of + formats that are accepted. + linestyle: style of the line. Refer to `matplotlib.lines.Line2D` + for a full list of formats that are accepted. + linewidth (float or None): width of the line. When it's None, + a default value will be computed and used. + + Returns: + output (VisImage): image object with line drawn. + """ + if linewidth is None: + linewidth = self._default_font_size / 3 + linewidth = max(linewidth, 1) + self.output.ax.add_line( + mpl.lines.Line2D( + x_data, + y_data, + linewidth=linewidth * self.output.scale, + color=color, + linestyle=linestyle, + ) + ) + return self.output + + def draw_binary_mask( + self, binary_mask, color=None, *, edge_color=None, text=None, alpha=0.5, area_threshold=10 + ): + """ + Args: + binary_mask (ndarray): numpy array of shape (H, W), where H is the image height and + W is the image width. Each value in the array is either a 0 or 1 value of uint8 + type. + color: color of the mask. Refer to `matplotlib.colors` for a full list of + formats that are accepted. If None, will pick a random color. + edge_color: color of the polygon edges. Refer to `matplotlib.colors` for a + full list of formats that are accepted. + text (str): if None, will be drawn on the object + alpha (float): blending efficient. Smaller values lead to more transparent masks. + area_threshold (float): a connected component smaller than this area will not be shown. + + Returns: + output (VisImage): image object with mask drawn. + """ + if color is None: + color = random_color(rgb=True, maximum=1) + color = mplc.to_rgb(color) + + has_valid_segment = False + binary_mask = binary_mask.astype("uint8") # opencv needs uint8 + mask = GenericMask(binary_mask, self.output.height, self.output.width) + shape2d = (binary_mask.shape[0], binary_mask.shape[1]) + + if not mask.has_holes: + # draw polygons for regular masks + for segment in mask.polygons: + area = mask_util.area(mask_util.frPyObjects([segment], shape2d[0], shape2d[1])) + if area < (area_threshold or 0): + continue + has_valid_segment = True + segment = segment.reshape(-1, 2) + self.draw_polygon(segment, color=color, edge_color=edge_color, alpha=alpha) + else: + # TODO: Use Path/PathPatch to draw vector graphics: + # https://stackoverflow.com/questions/8919719/how-to-plot-a-complex-polygon + rgba = np.zeros(shape2d + (4,), dtype="float32") + rgba[:, :, :3] = color + rgba[:, :, 3] = (mask.mask == 1).astype("float32") * alpha + has_valid_segment = True + self.output.ax.imshow(rgba, extent=(0, self.output.width, self.output.height, 0)) + + if text is not None and has_valid_segment: + lighter_color = self._change_color_brightness(color, brightness_factor=0.7) + self._draw_text_in_mask(binary_mask, text, lighter_color) + return self.output + + def draw_soft_mask(self, soft_mask, color=None, *, text=None, alpha=0.5): + """ + Args: + soft_mask (ndarray): float array of shape (H, W), each value in [0, 1]. + color: color of the mask. Refer to `matplotlib.colors` for a full list of + formats that are accepted. If None, will pick a random color. + text (str): if None, will be drawn on the object + alpha (float): blending efficient. Smaller values lead to more transparent masks. + + Returns: + output (VisImage): image object with mask drawn. + """ + if color is None: + color = random_color(rgb=True, maximum=1) + color = mplc.to_rgb(color) + + shape2d = (soft_mask.shape[0], soft_mask.shape[1]) + rgba = np.zeros(shape2d + (4,), dtype="float32") + rgba[:, :, :3] = color + rgba[:, :, 3] = soft_mask * alpha + self.output.ax.imshow(rgba, extent=(0, self.output.width, self.output.height, 0)) + + if text is not None: + lighter_color = self._change_color_brightness(color, brightness_factor=0.7) + binary_mask = (soft_mask > 0.5).astype("uint8") + self._draw_text_in_mask(binary_mask, text, lighter_color) + return self.output + + def draw_polygon(self, segment, color, edge_color=None, alpha=0.5): + """ + Args: + segment: numpy array of shape Nx2, containing all the points in the polygon. + color: color of the polygon. Refer to `matplotlib.colors` for a full list of + formats that are accepted. + edge_color: color of the polygon edges. Refer to `matplotlib.colors` for a + full list of formats that are accepted. If not provided, a darker shade + of the polygon color will be used instead. + alpha (float): blending efficient. Smaller values lead to more transparent masks. + + Returns: + output (VisImage): image object with polygon drawn. + """ + if edge_color is None: + # make edge color darker than the polygon color + if alpha > 0.8: + edge_color = self._change_color_brightness(color, brightness_factor=-0.7) + else: + edge_color = color + edge_color = mplc.to_rgb(edge_color) + (1,) + + polygon = mpl.patches.Polygon( + segment, + fill=True, + facecolor=mplc.to_rgb(color) + (alpha,), + edgecolor=edge_color, + linewidth=max(self._default_font_size // 15 * self.output.scale, 1), + ) + self.output.ax.add_patch(polygon) + return self.output + + """ + Internal methods: + """ + + def _jitter(self, color): + """ + Randomly modifies given color to produce a slightly different color than the color given. + + Args: + color (tuple[double]): a tuple of 3 elements, containing the RGB values of the color + picked. The values in the list are in the [0.0, 1.0] range. + + Returns: + jittered_color (tuple[double]): a tuple of 3 elements, containing the RGB values of the + color after being jittered. The values in the list are in the [0.0, 1.0] range. + """ + color = mplc.to_rgb(color) + vec = np.random.rand(3) + # better to do it in another color space + vec = vec / np.linalg.norm(vec) * 0.5 + res = np.clip(vec + color, 0, 1) + return tuple(res) + + def _create_grayscale_image(self, mask=None): + """ + Create a grayscale version of the original image. + The colors in masked area, if given, will be kept. + """ + img_bw = self.img.astype("f4").mean(axis=2) + img_bw = np.stack([img_bw] * 3, axis=2) + if mask is not None: + img_bw[mask] = self.img[mask] + return img_bw + + def _change_color_brightness(self, color, brightness_factor): + """ + Depending on the brightness_factor, gives a lighter or darker color i.e. a color with + less or more saturation than the original color. + + Args: + color: color of the polygon. Refer to `matplotlib.colors` for a full list of + formats that are accepted. + brightness_factor (float): a value in [-1.0, 1.0] range. A lightness factor of + 0 will correspond to no change, a factor in [-1.0, 0) range will result in + a darker color and a factor in (0, 1.0] range will result in a lighter color. + + Returns: + modified_color (tuple[double]): a tuple containing the RGB values of the + modified color. Each value in the tuple is in the [0.0, 1.0] range. + """ + assert brightness_factor >= -1.0 and brightness_factor <= 1.0 + color = mplc.to_rgb(color) + polygon_color = colorsys.rgb_to_hls(*mplc.to_rgb(color)) + modified_lightness = polygon_color[1] + (brightness_factor * polygon_color[1]) + modified_lightness = 0.0 if modified_lightness < 0.0 else modified_lightness + modified_lightness = 1.0 if modified_lightness > 1.0 else modified_lightness + modified_color = colorsys.hls_to_rgb(polygon_color[0], modified_lightness, polygon_color[2]) + return tuple(np.clip(modified_color, 0.0, 1.0)) + + def _convert_boxes(self, boxes): + """ + Convert different format of boxes to an NxB array, where B = 4 or 5 is the box dimension. + """ + if isinstance(boxes, Boxes) or isinstance(boxes, RotatedBoxes): + return boxes.tensor.detach().numpy() + else: + return np.asarray(boxes) + + def _convert_masks(self, masks_or_polygons): + """ + Convert different format of masks or polygons to a tuple of masks and polygons. + + Returns: + list[GenericMask]: + """ + + m = masks_or_polygons + if isinstance(m, PolygonMasks): + m = m.polygons + if isinstance(m, BitMasks): + m = m.tensor.numpy() + if isinstance(m, torch.Tensor): + m = m.numpy() + ret = [] + for x in m: + if isinstance(x, GenericMask): + ret.append(x) + else: + ret.append(GenericMask(x, self.output.height, self.output.width)) + return ret + + def _draw_text_in_mask(self, binary_mask, text, color): + """ + Find proper places to draw text given a binary mask. + """ + # TODO sometimes drawn on wrong objects. the heuristics here can improve. + _num_cc, cc_labels, stats, centroids = cv2.connectedComponentsWithStats(binary_mask, 8) + if stats[1:, -1].size == 0: + return + largest_component_id = np.argmax(stats[1:, -1]) + 1 + + # draw text on the largest component, as well as other very large components. + for cid in range(1, _num_cc): + if cid == largest_component_id or stats[cid, -1] > _LARGE_MASK_AREA_THRESH: + # median is more stable than centroid + # center = centroids[largest_component_id] + center = np.median((cc_labels == cid).nonzero(), axis=1)[::-1] + self.draw_text(text, center, color=color) + + def _convert_keypoints(self, keypoints): + if isinstance(keypoints, Keypoints): + keypoints = keypoints.tensor + keypoints = np.asarray(keypoints) + return keypoints + + def get_output(self): + """ + Returns: + output (VisImage): the image output containing the visualizations added + to the image. + """ + return self.output diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/__init__.py new file mode 100644 index 00000000..39ebcd38 --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/__init__.py @@ -0,0 +1,9 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from . import data # register all new datasets +from . import modeling + +# config +from .config import * + +# models +from .oneformer_model import OneFormer \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/config.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/config.py new file mode 100644 index 00000000..78879b1e --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/config.py @@ -0,0 +1,239 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. +from annotator.oneformer.detectron2.config import CfgNode as CN + +__all__ = ["add_common_config", "add_oneformer_config", "add_swin_config", + "add_dinat_config", "add_beit_adapter_config", "add_convnext_config"] + +def add_common_config(cfg): + """ + Add config for common configuration + """ + # data config + # select the dataset mapper + cfg.INPUT.DATASET_MAPPER_NAME = "oneformer_unified" + # Color augmentation + cfg.INPUT.COLOR_AUG_SSD = False + # We retry random cropping until no single category in semantic segmentation GT occupies more + # than `SINGLE_CATEGORY_MAX_AREA` part of the crop. + cfg.INPUT.CROP.SINGLE_CATEGORY_MAX_AREA = 1.0 + # Pad image and segmentation GT in dataset mapper. + cfg.INPUT.SIZE_DIVISIBILITY = -1 + + cfg.INPUT.TASK_SEQ_LEN = 77 + cfg.INPUT.MAX_SEQ_LEN = 77 + + cfg.INPUT.TASK_PROB = CN() + cfg.INPUT.TASK_PROB.SEMANTIC = 0.33 + cfg.INPUT.TASK_PROB.INSTANCE = 0.66 + + # test dataset + cfg.DATASETS.TEST_PANOPTIC = ("",) + cfg.DATASETS.TEST_INSTANCE = ("",) + cfg.DATASETS.TEST_SEMANTIC = ("",) + + # solver config + # weight decay on embedding + cfg.SOLVER.WEIGHT_DECAY_EMBED = 0.0 + # optimizer + cfg.SOLVER.OPTIMIZER = "ADAMW" + cfg.SOLVER.BACKBONE_MULTIPLIER = 0.1 + + # wandb + cfg.WANDB = CN() + cfg.WANDB.PROJECT = "unified_dense_recognition" + cfg.WANDB.NAME = None + + cfg.MODEL.IS_TRAIN = False + cfg.MODEL.IS_DEMO = True + + # text encoder config + cfg.MODEL.TEXT_ENCODER = CN() + + cfg.MODEL.TEXT_ENCODER.WIDTH = 256 + cfg.MODEL.TEXT_ENCODER.CONTEXT_LENGTH = 77 + cfg.MODEL.TEXT_ENCODER.NUM_LAYERS = 12 + cfg.MODEL.TEXT_ENCODER.VOCAB_SIZE = 49408 + cfg.MODEL.TEXT_ENCODER.PROJ_NUM_LAYERS = 2 + cfg.MODEL.TEXT_ENCODER.N_CTX = 16 + + # mask_former inference config + cfg.MODEL.TEST = CN() + cfg.MODEL.TEST.SEMANTIC_ON = True + cfg.MODEL.TEST.INSTANCE_ON = False + cfg.MODEL.TEST.PANOPTIC_ON = False + cfg.MODEL.TEST.DETECTION_ON = False + cfg.MODEL.TEST.OBJECT_MASK_THRESHOLD = 0.0 + cfg.MODEL.TEST.OVERLAP_THRESHOLD = 0.0 + cfg.MODEL.TEST.SEM_SEG_POSTPROCESSING_BEFORE_INFERENCE = False + cfg.MODEL.TEST.TASK = "panoptic" + + # TEST AUG Slide + cfg.TEST.AUG.IS_SLIDE = False + cfg.TEST.AUG.CROP_SIZE = (640, 640) + cfg.TEST.AUG.STRIDE = (426, 426) + cfg.TEST.AUG.SCALE = (2048, 640) + cfg.TEST.AUG.SETR_MULTI_SCALE = True + cfg.TEST.AUG.KEEP_RATIO = True + cfg.TEST.AUG.SIZE_DIVISOR = 32 + + # pixel decoder config + cfg.MODEL.SEM_SEG_HEAD.MASK_DIM = 256 + # adding transformer in pixel decoder + cfg.MODEL.SEM_SEG_HEAD.TRANSFORMER_ENC_LAYERS = 0 + # pixel decoder + cfg.MODEL.SEM_SEG_HEAD.PIXEL_DECODER_NAME = "BasePixelDecoder" + cfg.MODEL.SEM_SEG_HEAD.SEM_EMBED_DIM = 256 + cfg.MODEL.SEM_SEG_HEAD.INST_EMBED_DIM = 256 + + # LSJ aug + cfg.INPUT.IMAGE_SIZE = 1024 + cfg.INPUT.MIN_SCALE = 0.1 + cfg.INPUT.MAX_SCALE = 2.0 + + # MSDeformAttn encoder configs + cfg.MODEL.SEM_SEG_HEAD.DEFORMABLE_TRANSFORMER_ENCODER_IN_FEATURES = ["res3", "res4", "res5"] + cfg.MODEL.SEM_SEG_HEAD.DEFORMABLE_TRANSFORMER_ENCODER_N_POINTS = 4 + cfg.MODEL.SEM_SEG_HEAD.DEFORMABLE_TRANSFORMER_ENCODER_N_HEADS = 8 + +def add_oneformer_config(cfg): + """ + Add config for ONE_FORMER. + """ + + # mask_former model config + cfg.MODEL.ONE_FORMER = CN() + + # loss + cfg.MODEL.ONE_FORMER.DEEP_SUPERVISION = True + cfg.MODEL.ONE_FORMER.NO_OBJECT_WEIGHT = 0.1 + cfg.MODEL.ONE_FORMER.CLASS_WEIGHT = 1.0 + cfg.MODEL.ONE_FORMER.DICE_WEIGHT = 1.0 + cfg.MODEL.ONE_FORMER.MASK_WEIGHT = 20.0 + cfg.MODEL.ONE_FORMER.CONTRASTIVE_WEIGHT = 0.5 + cfg.MODEL.ONE_FORMER.CONTRASTIVE_TEMPERATURE = 0.07 + + # transformer config + cfg.MODEL.ONE_FORMER.NHEADS = 8 + cfg.MODEL.ONE_FORMER.DROPOUT = 0.1 + cfg.MODEL.ONE_FORMER.DIM_FEEDFORWARD = 2048 + cfg.MODEL.ONE_FORMER.ENC_LAYERS = 0 + cfg.MODEL.ONE_FORMER.CLASS_DEC_LAYERS = 2 + cfg.MODEL.ONE_FORMER.DEC_LAYERS = 6 + cfg.MODEL.ONE_FORMER.PRE_NORM = False + + cfg.MODEL.ONE_FORMER.HIDDEN_DIM = 256 + cfg.MODEL.ONE_FORMER.NUM_OBJECT_QUERIES = 120 + cfg.MODEL.ONE_FORMER.NUM_OBJECT_CTX = 16 + cfg.MODEL.ONE_FORMER.USE_TASK_NORM = True + + cfg.MODEL.ONE_FORMER.TRANSFORMER_IN_FEATURE = "res5" + cfg.MODEL.ONE_FORMER.ENFORCE_INPUT_PROJ = False + + # Sometimes `backbone.size_divisibility` is set to 0 for some backbone (e.g. ResNet) + # you can use this config to override + cfg.MODEL.ONE_FORMER.SIZE_DIVISIBILITY = 32 + + # transformer module + cfg.MODEL.ONE_FORMER.TRANSFORMER_DECODER_NAME = "ContrastiveMultiScaleMaskedTransformerDecoder" + + # point loss configs + # Number of points sampled during training for a mask point head. + cfg.MODEL.ONE_FORMER.TRAIN_NUM_POINTS = 112 * 112 + # Oversampling parameter for PointRend point sampling during training. Parameter `k` in the + # original paper. + cfg.MODEL.ONE_FORMER.OVERSAMPLE_RATIO = 3.0 + # Importance sampling parameter for PointRend point sampling during training. Parametr `beta` in + # the original paper. + cfg.MODEL.ONE_FORMER.IMPORTANCE_SAMPLE_RATIO = 0.75 + +def add_swin_config(cfg): + """ + Add config forSWIN Backbone. + """ + + # swin transformer backbone + cfg.MODEL.SWIN = CN() + cfg.MODEL.SWIN.PRETRAIN_IMG_SIZE = 224 + cfg.MODEL.SWIN.PATCH_SIZE = 4 + cfg.MODEL.SWIN.EMBED_DIM = 96 + cfg.MODEL.SWIN.DEPTHS = [2, 2, 6, 2] + cfg.MODEL.SWIN.NUM_HEADS = [3, 6, 12, 24] + cfg.MODEL.SWIN.WINDOW_SIZE = 7 + cfg.MODEL.SWIN.MLP_RATIO = 4.0 + cfg.MODEL.SWIN.QKV_BIAS = True + cfg.MODEL.SWIN.QK_SCALE = None + cfg.MODEL.SWIN.DROP_RATE = 0.0 + cfg.MODEL.SWIN.ATTN_DROP_RATE = 0.0 + cfg.MODEL.SWIN.DROP_PATH_RATE = 0.3 + cfg.MODEL.SWIN.APE = False + cfg.MODEL.SWIN.PATCH_NORM = True + cfg.MODEL.SWIN.OUT_FEATURES = ["res2", "res3", "res4", "res5"] + cfg.MODEL.SWIN.USE_CHECKPOINT = False + ## Semask additions + cfg.MODEL.SWIN.SEM_WINDOW_SIZE = 7 + cfg.MODEL.SWIN.NUM_SEM_BLOCKS = 1 + +def add_dinat_config(cfg): + """ + Add config for NAT Backbone. + """ + + # DINAT transformer backbone + cfg.MODEL.DiNAT = CN() + cfg.MODEL.DiNAT.DEPTHS = [3, 4, 18, 5] + cfg.MODEL.DiNAT.OUT_FEATURES = ["res2", "res3", "res4", "res5"] + cfg.MODEL.DiNAT.EMBED_DIM = 64 + cfg.MODEL.DiNAT.MLP_RATIO = 3.0 + cfg.MODEL.DiNAT.NUM_HEADS = [2, 4, 8, 16] + cfg.MODEL.DiNAT.DROP_PATH_RATE = 0.2 + cfg.MODEL.DiNAT.KERNEL_SIZE = 7 + cfg.MODEL.DiNAT.DILATIONS = [[1, 16, 1], [1, 4, 1, 8], [1, 2, 1, 3, 1, 4], [1, 2, 1, 2, 1]] + cfg.MODEL.DiNAT.OUT_INDICES = (0, 1, 2, 3) + cfg.MODEL.DiNAT.QKV_BIAS = True + cfg.MODEL.DiNAT.QK_SCALE = None + cfg.MODEL.DiNAT.DROP_RATE = 0 + cfg.MODEL.DiNAT.ATTN_DROP_RATE = 0. + cfg.MODEL.DiNAT.IN_PATCH_SIZE = 4 + +def add_convnext_config(cfg): + """ + Add config for ConvNeXt Backbone. + """ + + # swin transformer backbone + cfg.MODEL.CONVNEXT = CN() + cfg.MODEL.CONVNEXT.IN_CHANNELS = 3 + cfg.MODEL.CONVNEXT.DEPTHS = [3, 3, 27, 3] + cfg.MODEL.CONVNEXT.DIMS = [192, 384, 768, 1536] + cfg.MODEL.CONVNEXT.DROP_PATH_RATE = 0.4 + cfg.MODEL.CONVNEXT.LSIT = 1.0 + cfg.MODEL.CONVNEXT.OUT_INDICES = [0, 1, 2, 3] + cfg.MODEL.CONVNEXT.OUT_FEATURES = ["res2", "res3", "res4", "res5"] + +def add_beit_adapter_config(cfg): + """ + Add config for BEiT Adapter Backbone. + """ + + # beit adapter backbone + cfg.MODEL.BEiTAdapter = CN() + cfg.MODEL.BEiTAdapter.IMG_SIZE = 640 + cfg.MODEL.BEiTAdapter.PATCH_SIZE = 16 + cfg.MODEL.BEiTAdapter.EMBED_DIM = 1024 + cfg.MODEL.BEiTAdapter.DEPTH = 24 + cfg.MODEL.BEiTAdapter.NUM_HEADS = 16 + cfg.MODEL.BEiTAdapter.MLP_RATIO = 4 + cfg.MODEL.BEiTAdapter.QKV_BIAS = True + cfg.MODEL.BEiTAdapter.USE_ABS_POS_EMB = False + cfg.MODEL.BEiTAdapter.USE_REL_POS_BIAS = True + cfg.MODEL.BEiTAdapter.INIT_VALUES = 1e-6 + cfg.MODEL.BEiTAdapter.DROP_PATH_RATE = 0.3 + cfg.MODEL.BEiTAdapter.CONV_INPLANE = 64 + cfg.MODEL.BEiTAdapter.N_POINTS = 4 + cfg.MODEL.BEiTAdapter.DEFORM_NUM_HEADS = 16 + cfg.MODEL.BEiTAdapter.CFFN_RATIO = 0.25 + cfg.MODEL.BEiTAdapter.DEFORM_RATIO = 0.5 + cfg.MODEL.BEiTAdapter.WITH_CP = True + cfg.MODEL.BEiTAdapter.INTERACTION_INDEXES=[[0, 5], [6, 11], [12, 17], [18, 23]] + cfg.MODEL.BEiTAdapter.OUT_FEATURES = ["res2", "res3", "res4", "res5"] \ No newline at end of file diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/__init__.py b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/__init__.py new file mode 100644 index 00000000..63ba265b --- /dev/null +++ b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +from . import datasets diff --git a/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/bpe_simple_vocab_16e6.txt.gz b/extensions-builtin/sd_forge_controlnet/annotator/oneformer/oneformer/data/bpe_simple_vocab_16e6.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..7b5088a527f720063f044eb928eee315f63b2fc0 GIT binary patch literal 1356917 zcmV(nK=QvIiwFQl6I)*Z19ZK~vMkwgB)E^SaG(|_PzuTJUep5J0`N~DK81(h@F{(W zxN)TxRpd|fvY8l2bh9uNNe~1;Qsm*`zuHufsU3f;?gfyU@7){Weg+%V)YQIRE$xrC zeq4t3M~}HKs~`QZ|GE9oU+wSve|WU(*3Z-Ti~r@T|LxKj(`7Gim(u>Z7Onkry|nhf z{Z_R9$DcocaOtO_C?efA9V8_G0Eg*J8Fm z+xYK;eN$i5_?`6oQ_=8WTL0%e=^%gKm6r4`|-ox)!xtl zyS;qJALFq1Z|v_Y`?JA*_sK_{?a#`WKW}=D(f)F>zZm>OZ9y*c5i7M`I{VFM(PPQd z8@>1zn|`&**-T$V;DjxnW z?d1PrKW0ncVr{XY>GiM0idQ}CS!VkQ|NWbGc8z^V-+x_gqjfNRQC57H9mUCiw(>V= z>=U&#Pup_5MfwSQPW!%f=1H)h+x++N^Vmnd#eDIVTjM6+g!oVUD(tN_pjLOqz?A7SNq@B_P>Wd`j5Z*(|;>I|L*c;e>mFzY>V5t82B;!h<@sH zoa~it>+E1$zOw!DuUWCdjbF6`yI!VMe8YJwu2|m7)D}-a1Ec?Qu{X8fwI#NfJ1*1g zKk?$b>s#$e9=;5_FYsjFU-KB1IKz0Y-ahY&S6;bnc1IR}@!8k3$3|`bANVyb=W4$; z*yY;&C3~!Q`pai)k5cg}`a0so-pb6ApJ?`D*kKYuZ zzp+O@Y%|h=4Kt0?c|A~MR`D&J8@oTV9?>kpFz9TT_L$|Q`!m>w9G5+QQ0K0~<6>j_%bTsyuI=%?!=uRb z;HH&0Etg6+^cg1wSNi4mvR|{u||`YjttMNZ749c5Qcw z)0O_qc5hiOlT|Z>ukfP%ro{htqDFAKhUQCglW0lbWJ-umcD&Y>{shgP|-tfJszdMY_oPG znVNrq7n=C?mqCuzE?{~2<1dR(zl9%$wYu5L9k{WbOzPwow1-=jiNYzd7n3cT53N;M zeDE4$WBgzpa-}$nb{&UU)gC4{{YRUR&k#GS&|#2;*kFa%i!QnCC$IhH$KOAzH>-X1 z&%5@ku7{551_KR4VORGm8<9TZJ8mPlZ~^Ji!VlR0)nTG#&*r(2HEVG_UcX2K7HyC=FWfmz-hzb#v1K90d^+JL3e9Fd{x6lua`$(;EI)cX*>E2 zEzSTNZccY&{4@JDPWk0_xGh@|7}~PI|EJe^*?&f~aN(u1Grh?u9yomi?9$;@?tv#N z!%ht_wz$5GrTmQ_FqrUORjU&LOM7{m9Zowkl=_SETI{~&ZEX9JF0~s6Tj$>2=#Srg z{-*f!Grur)5M<+Er4;nF+vzg?J&(m`Z}7xzxw{!kF9!2>mG#~c?A{P=PJV4H+}QCY z7P-LS%((Qn(}%tChCjOcG5=2Ci&Njy{;XUuk6%14R8Tc4(pJd2_)V~@(fO^1fwir) z&v~}3KeKtXZ~0OVM{UE@H&b8#neVm7?z z6{{b{*Y5gmp^Ys5gezztmi_ZXuCtzT-68;=aL4ZcLZyc_b_=w0W_C86FuQzu+%m_V zHJz;;@Qx8lsZe0!so%m4epP(iUui(piJNC1Z?^d!M|tRx2aNbtC6XPknY}z82@xUe zmqO&BJsrN}OvX7!S0(%SJ0^Je%y)OAaBMiu`nqkO*ZkD*0=88iwPIJ97`H9=Jj&)b~(xj&pLn2w0*zABH3>!BiZ5pTy>g64w1D*hrJ+7?gH%SATuVbAR025iw?d%ZtB`n0{O9fGhE z>Hqq`PBvj9WK!<>6I;Ozt}kc&i{Ebr5YIS^D~i;$)l;^G+#8qZ`N9j<7H3(+szivC;i=_fQI7sX_DdE^gu2lCfVzTBef2PD=aZob-k_6i;F)C>Ii&DPMZ6yp5a_qN7w zZ1#8Q30j2@c61|Yp7A6-)`9-oqU}n5S=hp*Ksnv1YXB4W(`Jz$Fus>Y(NsB{{uZk+ zFw|Ctt#?^)q`y-r0!T)!^i6l;jKxW21WwLQnSHgNi`5dZ+eLqWtVK3p_Jxgw_O=8) zqTTYrpskT<0Xz^tZ8oLxL*FSO#AZw>3N9lv1?S7Izb zvN6w5b=}$uSLEW1l^sCVB{4FMTch-f$2 z*rinBiqA=Z*6W=gy}5{4cF`QoB;R9~=H3R1ppdX!)8Aih7xVG7XYI3b><}tcv}!}~ zlt0>wN^yQEIA>%ehc`5D)f_df$5tcyZD7k_fc)fb1jv994es&Iq1Eq^g7|&h`%|L0 zGjY1a0lv;i4(@^4*zrhb^UJue3I@wy$)8HM@JA^pfdJ1v%DJo;DE}PJl);T_}HuJVjERQ9R+8=R&AYCiRt|3 zd0W#Ln9jJiz9z}QweZ`Br5fK?Y zcAcP+^iC}LloN_`4braO-N&_WhnzKD)35jqECX`H6}0Ob2*MZ0(JzqimT-G3ciOj* zFa44W@FnSBG3|an;tbk@Pi?Ht4kO0U$nL2-Ae|&jjCHUFT(=?NKC#+?P21t&dhnEN zOTukfz?s|-Z7Oo6i?s#fVs?&R5w6#5No0(Siz0flyKO(;_1w+f{oq`@*|K+L@_c_B z(Lia_lKxuTal>_4j-ncH!F#`~LxA|o%wPa4Mq~VwHp$L(N>}@^pSQ4-TZWbPSQq9V zVf5F0Y%RDkf9uu?S%Zf_woaZ-mkFI)k)slmL~U@oglAguU-t83<>!P>kWdwiZ_j?m znH&*l%QCwwEgK7B%j_mgRY|u%P)j@Jb{z(lX}99*gT<>YJIH*i{9FtP;Y0}2`Qh6m zd+$f>>c~tEUJUkaCZ>}?gJL~+nSYF5PDYMclOnDX(avP=IgYv^i$%7(p8N^}aZ4%B z+S})irQC!&Ic!7Ph5BaU&0@!(wd~1_xJ3j}G%{Nd$HJGzR>jiWAu{F{&UOP(!49j1 zsTQSfi*0T%D-rSW771Ax|I%V@mS_B~-Vid)tN*1EQ-*j*rq?5#gq*qQ`Zm5zcWuTM zH6a{+w_0UBlN;Qw`+?Cm%!2mF#Wp4z5rv>M0!wC5b2ya>$+U{caM$L04uqZUCR(GxGqB>#HwtSwq5$C{R`<+G9H$MQ|DNM5yINk{!Q_S3{2c=_dsOZil;fJ6YS8!RRmDBSclDfw2y1M;JmgbDlTs zQIH3KVDHxmJ>6A_P_TSOE_1azJrm2ed)?YymJ?Ep$jY&KiCIPalDwJHQZZX})q)hy zlz!j-_1eY`;5- zmkwWWCmOYYLH>s0!*|3fx?#}6Q=g;zP4aw!HVbIIbnUOhz^V7H_}J_1%%N%My^ z{kpp|^!R@7B-A37w>JW={7NAZ9GI5%aksr*J?D2Rn?ApP8us%11 zEp^{v*D)m*J8+di@KDWr$$7#D?|>fcdRvgT!Zwr$66R621|=%9{u5zP9LE9NpAJ8{ z^%0rv3SNM>^lg}lab5|Y^mb|o;hqSpnn(uh3DO0`{X^A4S@;4Zv(=e|Wkk-}XMA}> z$qdi1qE2ZK#2^a(z|TO9f}ke~ak%Yjcy@>FHP>sFw~pmGU=1xVGy_{}5v~@>?2#kg zA_6HFi~8&)$VCS#Nn_$rHY)3mroIDOYJ-_lw+P=5AVf6Y(4CgHa$y?2BkMWGVaHaC zc=&!$qyS1mD|FP(AY5CE0~}uV1$Sac2~@&-dx4$%amguD)3R!jKKb4&g!uZfJ7SLH zR^p`ZC2?XHDWm`%#xj`Ov<^V6@!;-yV8T2rIkbnRir7uq{Sm(?=+AH3tHr~I{Q@%`cnVM^0&Vvf9 zT^RuyJmAW-%2js-{K6F)z5b*K5nY zwST0z=~BnD+0x>EDZ*ZZ4WSzgq#hn>Bo{1V$Xhrk|N69GprK4rv>e@&En-16{RT!@ zE?UKpq7s4h&`;$K#^oOM>?_d6^mWaV>`h>x^awO{4IO!LTn98 zCM)fY&}@b)UeEYV`f;-_w!!-7RUukGng31vB68^V>_E*;Zu=T32U$C~Lgp3f;@&DJ znIDSgnBkj~c(GO$pel;vwdcYEc4Jfm_-Gxk!dv^2pa`x?-HR?@j&f&*LSC&*4;XhB zaVspXO1VRS3bqnZSSP-qGt&+rH()X{1QR>Y8Kd?V7LYW+el}DwZ(;wP+K}tO6$l&-kU`CL>6UNqN3TK;o-E9?`f_c$z3w~zg)W;V z(#xLh+;(FwF)?E6s2m^^Awt=%oh*Ttg3H+ulOEFwmpe*dzb;NtY^;l z=34|e9%fG}iBuU$s(e9P#hnd+B9ck{Y~C#cS`Z+0ww4{f6bHK#f$tidWMAo^{20k% zroaVYupL3!RfURB#gO<8@Ra}2G2UZBjJa-#N=T=0ueQ#Dy*kj5&E2GTdm#Q!Clyx6 zxw690QSlq$-;@oF2%XKD-GZVEb_y1KYy(!}ad!{#!{Ucw6&Z5$K`v>D>w{8kdl7{c zngN^@FsA@iR&XJAye|>c$P4Bn>JiR3Nxt9T0U09e`V)S_eP>aT%bdP`dQ%`?fj!U; zx#+jw0PxF7^wU+uP@OWJxwKpnL+*06V~#Z8Zfa0Y=K(B*R)2Vfj}>5DE}lT&B1LEU zy(8A}2U3Jq1aRRd%81OKf+@{gAyfp){7}5p;_LmA9@^@KDSFE6w#=o#Wuh4&4ETTz z)XF|(=h9ILb|uMuX{SF3xiC5-9i1G`2_NDGg!0h`lU+p@t!G1T3~CC>m9vA5mQn3| z)D5glI|q-xO;1w8vxvu{8}fF@K_DUMQb83!7dbkC{o#c9@g_-=QHMplqC_?2xp0~G z)q;$T?~|S%SZ44U2q1j^Nuhs%O#q>6l?z)5neBEw5t&>vaQKFIJ1kJ&qO$R7voj~N zvpMi%=-jZtbwT{B_NNTRfA|tdM99pXNUGg0nC5UabFk)X{?Hq#0YIr|9MNzvI1Jr! zs(LU1_iq`?PW5lQo;WXG3*}0IQ21b90%DNDR9iXuNZyAiB*oIeOSf(e*CU|8-p!-< zXRLqXO4sm4ulTZ|!KJ>T`e-5ayzYq+r)B6O)&=Ht^1E6-k9m=vJ_D{N5fvF&s(c(O z6BDiUlQPYjx5pA zP2}0{7XK-H14z|?Q&J^ueBewsNf)f0XEEY`rw;Ig~iN0`35+)7HY43aQ@f09Giac z>mwz(Z#e^9(_P1F9^jp)#NTc$81L)sP6;q;H%ELD5UgaMG=uSDip*zB{L z-uD#IGiQHzWh|#smEOxNq35T9Rs3geifck@IkwWtzl-fEz8Lm%ZhDd9PBlm`n3eHQpo43sQdxfQldR*^aCaS z>B%EKb42sd1CRNPU$1R219XZygbVB5pQ`ElYMja%C0UV<5VlS8)pLHUg7WajVA>ps@XDsU_b3h2-{4^dfEp}k&^L2PUpnV@*3EY9KC=2 zp*JOR7)&|YzI_$Hc-vXx^*@JyThT|03=cF`e`IvcrLtLKWXk&v!Pg3aCc{XI68fB1 zngbdaRQ>!!w{hsu?{?XP=Y4E}KU<)Cs#jQkIrG+Rv7U%IV>!j&8iLIH25&I077X-L z)DqLv*b9MhA6&LDj3kgG#LT>`ZGuPns6r!$XO98ehW#+Jox+nkW*Ba>WP&>7&dq5@ zD}vsW-Paz)$li~W97bdWJO!DgJ!IqyEePm`kN#{&nx6C2APPIwG_IzOTg2Ks8?vyk z;b%G^;$+HRszK26HRE3>_z$vj&s>aWZlMe|!vc{oFXfS2k^Mh)*2i^rH zmIo6gPd`tj`d%CBO(;A0+;`<;YK5|I>kh`rmOPYd8L7##in4jH0+yZ4LG&^Z8u*fk zt6+u)+2Ce9wU~fl+T_4fr)S8m8D(w-`=a2x zq6lrTsT*DI2LN0)d^#vSD1s+&C+-jlR(*Z(q8*0%lsEsoHtOxlS>$P})QT!;qrH}zo zd#g1P9uS}7>4FXS<~O89CAM*t;ShMhocOM@`c3iaoAmAqszJhH1GcA>(Vn=rC*I_O zd(+y9-sW^7WRZY0EL=O%AI+a`TW(QXS+Wc30V0y+(G33PSrA+uC+r!mXt>_h(2D=> zk1VvKil%{R*=e$k!o9Y|$c}M5(T&|LE>Q$ZX!Rd#x339g@w^r7hi2BjB);W}Yz??a za7}UK=Z!-TxZDGVKAk<3O4}N=a*veSpb0br38&0A-gH~rh^&In-C-wa=Ml-Q*y+*3 z)h-)n)>{10?1BsGrSA%V0241hPhKMSr+Ly72}uegR1H2(4lC7iQziYP;$*qSw#=+5 zl^$BNbZ-})Ki#jvPE>b=y__$t?fj36Pd{UwB3WG9ZRDSoqI0CSm(C1Kr5pm_g&j|K zAoHc{~pv$zw9YV_Dt=AF<>>;<9eiOB#ZK^h4LLu!XlZYA3;=penOdMwV4UPo>6s z@&hi@k=cvu927Rv$37Ct*)JUUQVZH^-6jg6JtEh`okonl=(?zwfy0n0&bIeag|juT zRNpE>?s;du1t?V2*=WP8xag2)zxC#lw8YxU@d=*IlpF?*FC~uAzN-qMn)R-%GLxV7Po%!vj=M* zP;3=mvU?h7KeA`~RE=i7nS#;`W#gr&+BVZEbFp!cD#uMzJ zm>o=r+8uemnnU2XOQ)Ow26;vH(cE!9m<&0z4&JOB)Z9=%48(sdFxpR#MyT z?K(8hqWHckpr{e!uBoNj-)ubvr9ld0+$=N#m9~b-nTH@^@SWSv8qfuPQ2Ze6M4K67 zn+K3xzEI`KDLHExAX6hqMy6&frF;UE)xA?KIJQs7@I(KNAT3EsU1W}!V}NMmIOd#z z1-2LpO$D|@0g#<^6%f4Vkq-jvHLz*D4_C?E`%Urbr|G~XLOo03xfAuvl1%aW@6x8W zfvmOfD3RIOSLy`gr2r1N3yLk4WqpmqrauSrQbA)&^_+yfZP~G~wC0;_?rt+5UyIvZ z`A%%dDGs(fx=~c)#4U|pOtk0Nn$#IC?cYUD}Z6 zLNjy&Ck1vuI!FIdeEz5Og!kN)ht}nu*yB?6Q$BgaoFVdKB4{$%#hp8`LCOsVP&tn| z!Sb35$#;QrZII`>S@ol3&U zzItaflL(Ri`8a`dqJ|$7$P@U}v6nS28mRLq*&@8JiRNXddMYReHHjR@jZ!50i4Szh zAA>Od6JYrDB~=*MP#Q;s)dECI5vxU|n~nYcNbG{PcOJc|V@3ujnnicy)-L9mp*A8X zRwG6O2avvY4sYzr7fT%JdWh(?3F6O=hkxQtiz8 zDYTy0+m_a=7c#Y;vJ6C*`Q{h5R*WW|W6-kJISGgau2vqYOzjVA=6(jR{GCw~ba7_r zK!AW5jiUt0?w9iDj@-+{#{9lmf(+Dqc1zgsr90EXCxl|#>dG_JU3-$8+0c6R5A@5r z$085QQ{z#rTW368fg2x|_`QL@60XB`Awqnxk2;6S%iz|4o@D{28*?Zo?w0orEb`sa zuHVc@oEb}vp|!JZN3_f`2t%{uypDMThA@!m=<(ER%7p;it`x^Zzn};C55lJ#g*(6n z+}bRkK;;|~ZqTn3kxPfF=O%t&gr@_ch3M&_Gl0*^wBC8mP0T3nFaf**0dtdu;sFch z&EW(dzwaogZV7Qj_GSr~vhgw$@`!zlsdvP7quch~k2?T6S$Ik@kYDc0WqZ6p=jfHa z(-e#)E`?x?^++JFzi3iYLpY2xz!E)`OoGeq4Ly^)A4|{w^k4Dl(c#vwxfENWv~^{T zVMt0Z8RW&&Do923J&EhtSpW*xsh}ai4&d(PNeb2igqoBv`N>ytvRZv^4HU3S5^Ca* zB@G@5O!-+X#a+0;ovZK(sO5)>yk)9;Eq-Y9Nwld%eca7*Vve{4Y0aHp%jn&NrB z_CX?^dM}q<))S(To3w6h-vP74js-xoOP5^nRf2 zBt?L=PqfiJcDYnh*xuChcyv@8xuv4MrOu7?5W`7*%ME{-rGDlAK}c{|c4hBUtvb$I z5$HSVZ62!s&TnHhaoKL!2|)$0y*y^xv1m!@bAfcN*}`12G$Vj=0}|x*Sn{5qZDkkA z-=``Ic~HyLl~%PB`?^xR$Wr|$yW(q|!-M>iw1`8XH{h7C?Kz0HH9Fzs9$e&B1tQu7 zUs7-$RR}o2|E)xO{4(#VYdq$Ni<(uC)uTs;L29CqdqF+Pagb}VlYhdUO%~jXB$S46 zGFepq7P{M#EX}KV(DXuY<#JN=g2vJm#d|Y{PD}uo3q81>f3F11vdBQX*ERy)vO^rU z40F^X!tZtmLiWo2H1(? z`Vu@;W}93c^0c>%c1=3%e_s4K{|R<@Bm@xi(!yGt->Da+=^2Y=N#?AE%sN5ciezFZ zP+A|h8jqebXy*Lg(U&Xh??O?d1K*}JRc3{-%7Xzr)^=>Vw0>r*{w$&J48nq81tD2g)~SQRB$3gCS{-0n(LXpf6@jzXnY8iEdyB^)Ftw&Viw zy;UO?*g6^7-;lu`dinp|%~2gSI&V1mr8*COnYfm_Zh|5v%bWvPe4KjziVU03( z*n5akEHEMUG2}jOil*AO#Np0G!|inG!G{w2+&m|GI&z0lxyJ3Cc)|p3ok1&@iHO!A_lzAT*nM3o(}}IwUrg-T@!v4(>3Jxs=fqZ|N;i9LTcE!Z0@K1NC)o zg_{q$-YXS@OMTnuAF^g${Z_f^9j8h$m!)VMJ4z#r?N(yJw+pM7pa{&lpB$xFD)+n5 zn#ZNxPlW|EtRQ!8_e79Aj20#&Y zQI}zew}K}uS~cB)L;+qVWEXE(RQ5^wl^dC6aZW|j`O(q~$qnF(MIb*NXL8OQ>WX}N z=}bg;zs-_wXKgI;d&`4ZScF};amw6^t{2f2pyMracoeVIPt=w}q}1)ZQ1oju(G zDN|jYK_HHDz?#c_r_Nmqn}Ox)l%WY@NF2u~BK{{w@P1hQ@Q408)TEs$uDjcbLvuys z1JE3@%!E~P-!nwffXpm)otNyhz8KZB$=HB05vdl6Le3+C;tSf7V%gB$Is|M{$urgx zn;#`{-j7QJ?v#?*H1vl0I+Muw#~K1!^wwrDc1#qRai#ZYEV1BhonQGBc*+B1M3in< zDrj;-N9H>VwpwyKbD2gysH)h9E_Qt~)@w*Zc$?gqpq%ux&o<8zpbWH6r%0oQ+@3I8 zzuY5wCbFuVH55w@ilTI~zqAgh0E*LRe&Su1W`5Envwl#bR==GDWFP9fOchbHniIl2 zshI6(wJvj)Uetr2_J?{+YaPeG(p2SB7{#Mm;px7C*cj*;DT4m>mq zoD9hl{f2*nIT`vQNNr2Chz&C(XZ^dnQxKXC8VJdG=9FD+Q8vM3+(i_V4DkbfqtN!8 z+4izi04>p=vdV*OyXBPj9SH>%`ANw$dNEhwOPd?(^+03{L6Atlct(F!eExsZZyn*L z<+ajZ)FJ6a0+k~A6n+Nmg#gIE(?UhKel@I9TA}h|3Zcffi~0nOrofBBvi_7)rgJ*O zs(lN+ril)=pM;MVj;@2!pk(0NGGlt6*CH=gv_0RZ=ufJcBio^PsyIo)YJ17?cg_EX z?l$R&k$@drbj8;Cm#>c~3$7u!k8WEWk7pLHKxF7GGj8JSZ~Y7?!2g5a9m+*gL$gPt z>?n7jirZ9P5^timlUnA!g2WHFglg#$VrFY?*|GfD0JFS*qbqiugiT(k1IOk^& zW!SREndk_qNHHfedt82t_f-PHfF(O zaJ}jiZAdaLUT|h`Mu&-LYReR(2c2tf1A_U+xC+ksijT&jc9Htwu8Hn;pTomex$te?_L59TCKn&0x8kRgkK2UYJ&OK@-*4NQ*A)XG4j_7a-bEs`mnuty$fV&$H-{rcvPsZTi(mpBX;8}|m&`e7afd|x z4`jy!SRx**PpQfF)>kLYr5~u34XChMPv`&p#rM7|dzMtJ5PpPsW~eTBVCf*p9Cd7z zqgfgVHsS7}@jYwtZgU;1IYuzPWgxBg)E0D1iZXZoDBL$u3*PINm--B)Le+O8$0<@e zC~yy#=)F$zdB61OBEg=wA8EhndA_!`d4Vi)?vvYmm6$NZdBixZK=}@+#f`-p)FS(v zD4GH3ve0oRDG8oAKlbl|Yn*sHNC-Ke(oQaEFD;_K(9nQHb#<0R`Q*|k%IgRH=X+=8VH(aA#>{}pkT zozPoI*kwjG8`^11(n*XKZ(t1`_qt|*U`1pnP5%Y|7bN*O%?LY(HqUE<;{vB|2y;|Z z1THnNLMxoz77sgV(c1KF*Q-Xp&?uAI|rvJ*%PDv?X3}>sNpKwcE`a=ZpfRhKM-&c!~{JcWOJX+D$WP0RfN6QWl z#v<}eusYB$u$LTtO7u`(-pcwOSrNEAX-~=|D!!lFAAXPN4fnXR%MA69GU_c6H6~&~ zd*T*RFf;CLBF!W4qrB&Hw zTa5#a84bwj2DfpInDvf9;O-dM_PM#yP32KX`IAnz*>1hs2e`-}fzcmoy_Qrt@0Y}5 z4jMzUD#C{|422Vrnr$|{c-d09+6g|bR0^obV9l&)k5}8GE5*j*lHi$q zishH3|B!0q7%~#i0B)#+)~T+Fes=JcoQKwCQDXRj3Pi_RoAt(%RP%a*$0WUJ%_9anaz>UvJqxxyV%h+ z%Vur?q6}!$tjnxQ1rp$g3W`&Ex%Ow%j5q{6u`e+3=g=4Sda@U;EdBh@US{QnTR&!& zd=qkV35A9g-=q1&*<)bG`u#~-)beTtVg~zUXOg1JG-(NqBWo#sRTO{Ca|%({gJFdz z8AZp@)X{$;W{FZpG-tT=RrpA4k*ukuP^CYs!0!I_90dD}hRiuSeYzOSh&~VLIjpUV z`zPtb7(a@@l1O3ld6MG4)1zdz4IE1700Go0!9RWa1^ZTzGfIIYD+i^ePC^K49XUIo zzMgV;{0AELF584tUqz(~Q29R!&Ca0$^tv2#%1v#w4(1Wr-nc<4gHLV zCd1=2>;&9Dv^1U6dy8Ecz!D#eeXF*M_-bUoKWU{C^L^V`5 zFrpt|$1L{yj;l~02&(+TATW7wjvScND|KR3m;qjLYoq>>G)PY6ybj4|mr2Kdt64)v zN8SlrU?!TPH@R@si(WbtvrLmpY}+2;jeO(Fwt$*;;1IbjoBE&+jIU${x1$C+9O_%j zaJDd@6j*ynUj=cjzwb-8un8d$uu#3N$BVJ#>1!3PYY#ChITX-NydVg8B<2s+b%x9C z2zyR>z~2*s$gr+*%d{m&5(si(tKvH3Uqnx|g`i*iJ;=S!B^&3UI-thKV8hIz>X)X) zr6#aJ<-^2hq)?s1H&)3a@FX+ODiR;x(Ekxm4D_bBh`3q#HSM?Wfl^dtI2 zw1IPcSg zeoR71rg@j!*@05u+Dnw?pe6!`k5CbmFI8vEg=AcLpvqBHlw&$689#ZPStqO0X@GK+ zy!Io<_6ccEmmk*D4}Sn*2)YkGP|_r-i6#zibC0s z=`sNANH&#P<3k`%d(29ruT%PmIVMbV!_K8R;w3n>d=mPKiE}NP2zyrThf*{FCq+fB zgOap$PnaBNWI6*ItplFx5yX37tpw?^rac7YhaED&;O9nHH&9WXf;`7PF>(Y_o`QOm-lQh@y`JW-Az_ z>ETYpM@Dw+CpqINte`O@6=H)T(B`RF_2pQaT=2PO@MX(lUo{U@uzODPYfkKeg@Seh zi0-7EKsoHhOel37Hh+&bZHV&(@2Y6db*8u48f3Q1THnz8naSxXHqjb63e^L&!t8~# zuO$i2o08X3Lj;7RTJCNEvnqGK4*kSZpxa1L^1wpU&X9aLE-AO|L32WjV00Vr=i)Y| zyJ!VvjOsp0zANNAyPhmKx2@&lqJ+PU=N+Z<_RO8SDHTXBQDY7zhNz^5Mz?~%qeEvb z9$-WU&jImg=F#uOJo@7|fBLV*r@uZIYRk;-f`t5lxh}-W*W62%7;Rq2N@w$S5*+MA ztY!P!O@1lcl#_wM&0R3*o;V7F{@|6a0o%LsDOF)|6jX-bdz!D7h|@v6&r?4Kdtyl+ zMK@_vqLEI5YqVwdvmZKP`<{lVlNrEXKGmTdf%4#D4P!RJtoRDqOZm!_R8_p^vdvjj z-%}P3dyg$d*Mag~a+eU9qO1`r5pnAPyFpriwgOq+C@~WekiQ+&WgvSU0)Uevt!9*e z2W}8P8PmCYDl+@^5jFLz;y>uK(ILbWf`-xwq0Gh1!U;P;_oxbfbrKMU7%Lo|ZG@gqst)oU)*w$$Dw@q)kwA>>ZQ&ZoDy>WksAB1`EUJ)k%wQwvXU z2T^~TH43XAzEDd{`GaP`v#3NvuMdbBdd)B}98l}`*`~XqUmFg zC0GFw;fw6&@#PsMV#}vz2d|>mtZa}K!}8XU3yq1Y_U%o1mh=%}JEcRL98w7Feb05z zB*?s6t?qmOCo?9G#%C|fZG6suD zW5>9qXzX6Hde1T^SD>;763jVW=@?AVLqjCZOPDMs!k`|AxFdy-R_J!>Fnz?Z?q}{N zxnbH8Zgf)Er3_053T1eVq}N-UMx!PNknN&)O>c1HgSi{Ok+9abA{A7fyg4sc4Hi4y zYlOuF>C~Ejjm{wMCsf$F&_oW+Z;1G@!P8S=3`18PD2`pjxr_>-MKXA(!tuG95B-Wlpk_ znsa8>0y3CVG0qdaL<=m{@f6b{I9sS!Oa}0>>qw44H{v&+e@_+oF5Z2_{35TRQgtz` z)siFE)Ty5eL{hB7q(%!Pe3vzS?OIkA-6)yAu0eiB{xj>NtJL3>_NOHeRn@sE3)}v% z_@V7*6^Cn{a)B`S2;(+OhTj>3Z#vL$i&G*aZ$TFb-8t#{n-9Z20jhqe)ox*`znItG(O~jppDa>lc3{Brvd`m4uKuLLtemUnHN2Vt zgrDpU`ge7p^kYYuIS?eM3dd1HVH{2gT0-7DHZkW}p4gA|!Syv%tJAeACLjQ6JX^UHLIg2v-6LX{@5ja@r zmr;{qpXbc)p{Uh1_2)VbOY& zvdu$w5*Br4^YDlv#cgm#KrEc%tfwhHjD@4Mr3g6!kNfE3uEl84C3ggM zdh!Rg&xRhQzD1hpwjLuy6V8dNbS6Rv9Fdy4VDSzm>g|!pdZJB`ZY$0gqJghG8eorC zlz?%G`t4kuMhdq@2Y*r@_Xs*lk(57#@b*?>oHK=#Zo*Gd+XDefk@3hmp{X-QZksy% zeF$q+bI#?qqMHdzI434|AR=T=dj(G59`l)7@aZrPEryenc@)UDm-~qycRkP4X$g}Y zBbCr96p?k7(y)*yQti>!(dN1-CmU*;c6A&=GnTGOS`4E7CT$f#sADcZKm(7xYIslq zmce=(@@%j<1Qi#(X;c-S7H|fIrF2F^b?lzPNP8jkqX_(1ESd0(CIBI1H8bKAG^^hL zSf$=UbsZ2TRjD}Ix={>|Cf$ABPfTw>*D9iA+R$kR(-vMGO(h5Q0OMDl;Kd<}%7O`j z%sqP8i#%D(kt8T0@2nPHbhphf_j&A0MZ6i@X6P=gPP>!wc;|rBCMJ5YK21pj^|cqZ zM$uO06|Pa1WHn&lX}> z3%=IJ~FU1?lU-rZ;TmF%(xHFOz*>whAO z-fZ_m>ch;%9Woq4t3uP~Z_ceKSG9IwV@QcEPera@EexE6#6(^>A z+X)#QKYRE5w);yezlge#wHRm7RWwk@}dF)D@8$pq7wGirJ0@v0-Y6GJ#Cf zk$uYko~qo^^pA<;0?3QE>SkCGRCGa>!yqy9e@%o(URP&gu~H{3=zCLYRqzZ}U6UL; z-^Xy&4oSv4z>SpLK9FaO0hvM%t;4lBB&C#8ax-U)W2SnT%_j6w_A@NjOEV^1>A8xS zKIl81y|T$weE{sDV1D4o8|7Sp)??~kO%DiMzT+gb)nXk?h`JXW{jtBFPW(HxIys0h zbyP&3remeE>I~EXPmrn`$mWsiy|YBfquF~q&EiCy>lggX=Cq%G`klJ8e;Xd*FA=P# z$tiswY=GNu5t z8#32tm8|TUr|wEMS`}90nx?8E72Z03KiH0f%XD3M^)smqh;-j-NbOG^75Yrpo1+5A309>6tQT;>qc96l;tG z&0AeVBBK7@_loa*j|%56De`!u%SnoY66_M6fP&eERx8+! zQbz4?=P~97y`xrN1!na`0)TtB8DY4uq9mx(#*ll7h9(LK*EbEdfTBm9n&_TZe ztm@~=jP4=&a#ZrbXtX&5A)jlAVF0-HxiXr@`UNM~o}-c~kv-wNfOK}wDY)qKpb!*f z=mGa|5er2!)3h^@O1?hw)1XXJiX1hi?!9Ee{!)$P2#8O*5K;I8!r&465GC9ivFQix zNKjK+nd%QIoI(*goWPyBLIhnfe&W()FyDRl%Pbrl``DK=>BV9mO8sINMdfD}LAc*r zalOrw#ggoyu#a(*N}z@`yChU1x1&l#?Q3+}x9?b5QB&>KYIwqX%$&`PQB|AE^-M_z z+LTn_o-(=62-JM^R+u>yO)4nTjeW-di=yER?tubbI(@AqtyT5@%1}xtuCm z6P20d4|cEx#0cfoNFDn@=*@PP1;GU&Q6#6iTgqMGCmSfgZpTUgwhr;dK2Y$`2MS1x zf$4ToeeY2Yh%VyUqn++~QW}AI54r0hdwL}5uKVv7|1lZfxww)IGYY3dV^I=6C5I2W z;nVCun>mIwLuu<0S<&NEG?eanD2vGHvm+KK^{UXVJT*Hb%J%?|gjR};dX2YyL|K`9 zuZYx+sthSxjac-FJ_tXeXqBEwEfJ~7osDfmBckNQp0f-1J4Lrf``IIpT3BPa;}D`$ zF(ox7utuTmLY(#OlUiXXa#Ky-<+$)NL`yFFofvu<$1{`(mUP%cyO={M{iUdNVC`Exxs-t3+Ws_N3j|F& ziEY$>-rA>q)_T_F`57*k)O!BU;?v*Qok|C9cCeUbL@{Sz2Q{l|J5GiFEC3sd?PM;bry&W)~* z0KkZq{l?iVd$9QJ$1sMOYX4|CMm#)}_2n&2!5qApYf@9w?SbD6Y%pcNW13~-$KgC- zGMK`9yPTStizR7LyWAAI#AiRxaP@3-%#yC<3jRc{2C(B&T@`G~j%x$~$@I_+QORL$ zsi&S4anw~3a@Kuf^ zTW;Pi6dh`5q;n8l%-AD$oz5eNce2OJW6GJ@rrmKduwD|iZ4T&;Ey}^usr=He{TvvK zr4r=@7uXIhs+D4IhtzX`pXKCLkdHB&78rmy^_tDaS4pvqA=snu~%v zPD@CGX8ny=$Mpkn~yxv#}KBXWPr&zWNpSO6sen(qb4) zln@q#9a~J*N+0is60kv|O)E8EMHhNFgKzT!urib+38~gm<&7y2y*5uF-ln^-uap;+ zcsqnzh|k;7b4^|?<3t3EDE$WTTb((CSjjuVEP6e z?iio*IyA*oldn?+MK=9O`vI_22p2k7v&;+(5XHJ9vQtxA#1{SZ7VIo^0Yf9hPhSHL zaadXCpzTo5!9W;45dYCR=Tiv;c|V|Fu8UjrQ4dKr>J6T*=_!RJTsrzJNt%fMvOKqO z;_M{|m8sBJE+~;o!KzX8pU3*tP!I7l!pau0V8Guw+7Emy%_ask8~S3uFFyTsx=*d8 zRa2TylfD|pUG?ksiiE*$B?faqPU<9W0zVKnv6vktJkGxk0=R0TMc%5KUc4#AFWgup zGKoL;;U51QHAW6K^h51YM+$d7|CYU;N=nQ6M9SqPB5}5pRDcLl?BCgg+n?uHcV>yVYmzZaZka{x%X`5F`O=2FAUq=@Zm{e1e z+4l@zVIH*&@X)UMILFdgwa^k@M5P%~81w*lt1UG8;4n*t8qPl``}=SLpJeeclp-a3%cuY<~Flg`dc z?N;=AVXt1GaR#hkXZ!s~0@G*$IBgOnCWS6GZ2g!L?YCpyntVja z1l(ksXJ6Xw)Z9n`7g^w063D5O$ZcWKE+RJpJXa&WU>oXlSPbGwJ)=D8{9jHj#R&Wt zNHhB)lRn4LQM`GK*}|t?Esz`)f`K=X`Nr)Dnu#e~SE^gTP*jf5Q~0AUP6os(Liy{Z zmvTZ_G8B}LZrRk6hQM6%;9l=Vj-(h$An+<54i7zVBBj9*R+kDW)GSw2M))`%ySZFZ z9@{2cc_e<(h2`fbh$&+fH(VYeTZ-rjq>K-`MhppfuGef~ZeY(Hs4~ifBz%M$n zGG!Z)^QVa{!5>PCL1vztR&k1`6&`mBYQbL)-0_7aGC&HBb9T`gOw=VD&yaYl-~8#X ziqHSUR{rokTx-N-Q>+UWgKz^wJO`>*?!4cVNGmL|o4b4s5`W?s7btH(IRs98zwfDE zhvXQ&itX~deY9}=BhOLHzj;S*95It!&=k@+Hdz9|)buiRe1Kdus7tHGp}wk0T2^8OIV{WXgrq4Er!^*ZFHR5Z*?^tuns zB|F&dRSf)b3OS$9=Uw7sl++xkPZ8LO`Fuu5 znk1?Op2Ij9^Id$HGR;8u!gioA0V6!l#ZzcTXUp zI0oPMNBQ$5kbR0((Yp8h+`Xj12Sjc-#*L~8&uz`sD7(=$N zJ!{fBH%B`8Ox?6HW7~%(zOo9Lt&%v+Ok9qIZBAUgCX}!BK|<*TLGZ zy7+@H^zhy=|BfcjXH1`$0^^xFM(v36ADXnDDCoM~k;Pm}h?B7+f7>IA<3@Kahg$Kg2co18dA)st1>XR`x2&H6Y%F6gE`e)}V9%{7AdMaQ=E94DS8bZ&7Qd zNQ^66wa6YT-VRK%7a$Ym7Boy;?ilM^2898$I9nE2HZ9f563CU(rL!Bxt{lpDDSV>B zr*<=ROH`>7E}w=bKKriSt1*>5X@6_s5fz5?R#~O72NZs{i=0w%aB~{0}3nfh?LzLlnG@m`UFYHmCLZ2M?Q5IQSVD0hg0^VoJ4AblQ z3Z({UN1?O6X&NUHpq5Pqj@xs%h}W%2C1C6c76oQMb}hV4zle6%!2Fy*3|3EHij|g$wPDfh~K=wa>Klk zNjCM-$D1d7ofbLFGUjiTjQ`n5pE zwgQmtOU?RQ8Vg@lt`Aq1MOlKp*#T89{hKKf2Y(lABprrCl!|~;cn^?^{=}kgd|BS2 zE$W8S=_ra2X!0lp?U3p3i2 zRR|<+W<3wp697BTVg7G;M^A2y09{cwwVWG^on5zVvbSDqbnMWCffoA=MBK_sb zF`*;YPU8!HIqSVLRa>IS+2MK*S?&tF!j0M~$vZ4XdZCmofIy!{V7VQl3LYgSynbHn zqPS7w{Eqksjd!k~W%pJA-rA1Yg4gSLs0Zjsk5-5M3yd~L;v8~}tjs?-da)spm7{$R z58gn_awoy@ABnlBewi8`)8d$1T!Z|zzV)iBiMU^XXs19!Lt@%8KT~+gnghbcwtRVI z(~3VhD^x)Ui#=^GY;abfGp7gzyw$d&XT#XZ#apt&>_fg~AF`4!3QV)@j^g$%x4p0m zEBqP9wS5G&j1>4T_kP(oW+5tjw;H0ImcCL4kuo_Q;;vo;RDr{7=n<<>E=Zs8fNIhb zWB@P}e+@Z9(lnA&a9ZLb)_z=-Hc;|qqm2q zES|5`GZ2nwE&JoIiqHRsAF3++Kg#JLsjwzh7XObp>|>r-=!Rd}uZA&`84&=O*#4X| zm33k7{yQwrY|c-v^N8Ej1ekJofYp2Ca`zTVU%%vvVaK*N)W%_6rL9HfR6WLofPcvV zF2Zp4jFI=0eO3vriAtv{CuDD+vj(w&ep`>Ij{p-16-dg@NL@ZO6EX^%y2P05qOUwPupx@f7X1A!& z80wTwTgUXQk|PXRc=p4tCktdEw&r<@PUw_@3!yt@G|`;BQh1l5sF(~oQTUtfW<$bG zXDOARq=0MP@F<@QnGy}DO3wx65M6y`DFX#A!H_YJJR$n4)bE-;C+lwA%QS#4c=~gm zja21H?q~%{oh>ALs9=ly#n+_O#QfQcO#w^;;-fWYl>6(01_d8}QCBnl)^~0Kq&;vOmk0BwrdG97O#doXK06`#xmTM#~d!lCqfQOoj#T z75I#~5});(Qyk2Y0}QgPlJ7k`4D-SUKMijB z?pqk{q!8|g8*#k9Jf+=pX*r5K$S`-EuXR2_MU&GKN7~OshJwKS8V$~Dhz75CJIP!% zEyfxanIMEFr*g`Os|EoV^>BH#)aBNkw37*0%k%WLPe0>9*^*L2)&rQ-S=D)~(kzIa z#lt)<2rL;5`>o1oVq{tXkMR+OFt~Wzh%OH}Cg)|jWF6dxAWF)FJM)OIeByZfT{bK1 z7$5hrolvY&z*=?p_cR8Q|Tf-%%(83VhlTBodN8je@KhXNLnUxT<3{;&k$gYr360Vgx#N+IzFO8|LavqN3k@ z)JqWeH#Camu#W6x9hIaEW*g&o2tu;r@SHSvEscBTro|N;`gj0@Ob>$Zx$grcMA!i* zcX3206sp6<`(0*uVeUJROH6vtevW6A+8g$_knhuSbR^p{+Dn$bAF?R)4G_NB_rNCE zV&HH=@l0k#4^P6}4& z3mX+mOu14iHquDQu3%dni^G8_9Pe@ow|0e zE%bo(j(6+VocUp@f&KmP#f+i^-rLpb>#RtfwQC9Ixm{aMauI9Ugb?Ol1ddAXHSbe| zow<}kDf%3*Doh)Ds-exE$)Vc#o68lgnGQLT3S~#-r4dH;srY~&|7-LwF@U1R>0NcR znSCELB(+3T>a%!b+r1=-TR=915|=8im9VZjd|To) z_?jeP0l{xVKx>S_0U(; zoDh0nRqxWgprBXoWP|zoa@0fGqY&#ragKWJk;Kdj?ks;RYS0MhSCK};q*q|y`vOmN^X8C@8pbZl~kI9^(x^58t082p;%Xo5=|-W6Rok1d4laY7bhW*^T?t`4N|EB zkh*4K#w+5M0{kBbo`!PkB=nCcH(2n<>B`(r0vxslLE#!x>zbr|=XrcM%Z@CQfE9L?Xa~3x$vp5UIKGG-ltC>5pzp1GkzbA2( zq^2nd!xEuEG`Twi7I+0Eq`@v$-K9EK!NL%$QzfExXkBP$n>tHWw3W_cd7?{0-v;|M19fK1$2Pbpq&>tOH$*@l-PB)zMsS`7G zux0*KgJu6_j3F54@Kl;1m~KFKSwnGRu%rdGSGO~Ta(`Th0W}Jo>X74zVF94Fi7S{u zmI%HO-*Df8lyNL;^v&U>P7Yhi*9Q43W$|N8HDD z>e8(-;KHZ1=edTt_fS>bg<`47YX_E|f%6|qFsOpXz&DeH07&f|))CS-s+s4r06`mx z^IOVL#j?CU$Q8;hK6xjB@qk%_BB5!&3w5=ZzQ{ard(vM`p_+KDf+W$`7Wj`jYHn3@_us|q6-1I1mh>BaWHhElt&dE4#R{(r1s4x{%BUrUlyN!FWYePFS3sd z^-QIqd?*8aQ3EidkP=CI7nwdAUQmX2s}mpO7y=A*a{N%F^6+q(+< za0+0$`SaiA>=4t49gpNnSV;GSSOZ|qxaoGiSft4v0h~vY-?Ig!=Or5&vs1?~91YA6 z5Ue@rVwqtY%}k-OVvmV|X;R&ySf0bSbfe7e1kk#HaK)r;UN6%*o0#Ns&H!=K?opi% z5hpJe%s~@XsX4t5^rz;3=TKX* z3?jAP52z6NAxJZ;e0TGy@%cnz#Z|>2wZSy(Ga8wxo_s^>sS!TC+9|g>;*A^U)hcMA zq@FppHxwIRM=(S7+|AmQ!iaMdGCDVv^rt$?Ke;xUm-KB@ZtiFxBv#9!ORFKqHm+=n z%GKFAb*^37;>)o0^DqB@8UUCjWzt1{a|`($!eI!rNy`mGO=j;ADMKK7FFuGx$ckZz zjW**tL;uF1L-!v+8n6u!%LNl1F4P4;W!_xwbmcYR z=Eo(~3i~7*!W7X5U%`2C_-|J0Y(fWdOm(f(05zo7F*CHpO@hC4z=<=l5}t~?{{s8Y z1xqlusX7f*voPmcW{IRo|Dd+0=tAv9@8-S}r}=u-rcW_citmz#5IxJB*FJEZGOUy$IG7<$cbLV=HHpr21OJc?ltsfHZ=A57^$P=m7aI!?dE38Q0sZQd4={&1{7(}0V93<8#<3VVbDxuNok5*6%h3e3g%9MuPZxZx1cOmSou|-dZ z`e5dE5^wz(F4A_}Bgx{JJPbVdTvPKuz3fyjV4;SZdInQ(;;4fG5VfZz&dZJ-obMJs z83mYx&UddlYTm8jKqlvU1-#_`{@Y%-XU{5^oPBUgD z{r;k3^72jKNXuCPvy=*rMN@kc@Q5?%0qJ@c@<-S$Qi|DENUl`OdR(#C&n%L=!y79d z`7PqJZy<=<;XO}UfugmDT?he^ftjF2R!afRiA0>y4XLX$D*zC)?58R$h;ne-?LOLZ zwBW#dP=k1Q>dr@}ps&OmB6D-IW$60sr{(|SH^ryFbJb0#v_`{bRmq!FREIC?5|*Zy zF4P{jSHS}d9_(5W-jXMKLv46Eq2rXL5@SY_P{~zK9%K&HU$p-t3GGOlL5mFqH$P&Q zWldUN$*%IoLV#LZc8}9m?0M9YC?Mj+eN%k?7tUqK={kBDAz+7ugFoXEB1 zG6*^TrMJL=wgc%gqJI ztwmhh`&+8An5kFhuihv+P^l`0P5WZdjTdI^5V3sf7#<2%Zd*E;jF7M_S}6*DzxWQu z9{7m^;~%`^oUu|_-j53q+B78Bp9O})vx`(L5>^B)sJtp7KT0Ug*OiQbU}1XtY75=0 z1lwb_tIusmJu&@e(zA5E0bD}=q9ev6u+K2-zeef9p%iIQD|`Ug$J1g0-A@5DO;+)v zf{l=!y65D(QzQc@Jw(!G>0tI5g%+SgNh>MHKVtR>_}kTSMJZTvN|s+^QkF;Tn356+ z+^xJJd%Kmm8CA5Kg+T=Y-R(IpG8llAW&C1aC~KA;j(2+lkEX>TLZ#}aTkrH@^lJ*% zWLFqv*~I<)S~E;Y5-gF@Vnvpir&xy*1=-i5jeUyIf9q?()Rg%MP`m78ase`|xo8X) z#?nh>8Xle%W!tYlAZ>Fbx7%9Y6ZlDm05!}WtkvRR&w{efHcubsm3Ok6-=9W8ZRHL!#9qJ6!=%= z1^PL>_MGcjk9L?dk$MYg%n2m2f#|OVH}urdfDU>;nnZbCq+IuN#xX)$(Hj_r=OiFL zas~z{=YSGDO#MgFgUETqP`-jOl+}YJ&5`ySQz?9ot^1BG&wm|R=do~WCxEIHdgVx@ zJ(M)ahv+ZJ)suUaEVfzD{WQAi=#Lh*I7wI$u@b(af)ep7rHEd;sBk;N!lspryjR#Lp=b6tOs*+DlqI?6^Boqk9Ey`^Y zE5!r?@)c7Xket$qceA2+V~Gw%6V`bMGTk9aOs-vA?ie4Zcxv}ooN>dv;jzpE!LaNj zcv&2f(sw7@`qft&&|OOizO|Swz~OmnN{|$6gYz%FP6GtcH|>Mq+=gWpBeY$cVd=!k zU&=iG6G7&Q<%}*MC{|JnTzWFL(pALyr_rd6xd1@hmLwk;CD|u{qCYSG!rjz5oY^x} zPEWV@8`5Gh- zr(L6~%V|OAC`pZCQTu80z-|P+{gJDEn?lZ_ycMV(g3C^Gh6gqP=Q<$4(9B;Q!keM@WgW>}o zik1IvJO=~t^FSkH6O4V`SlEl^W7p4W30%dqV28nJgaYJjTQ!~hqV+iUq_^wi%xS$L zBE20MALmr56>|ehj@Re|BnCWjV7i~{{vwSIZJe~#eaPfXG|=zhZ4a%?BrzKEz?O3r z0Mxa`4GF}r*an@!iZx4TFJ`v$aFP?L8PnfULr+1_x83>&{ZmtgevxW5KTl;Q2nIKY zup3NTQ_=+De0tRP;yoeBA0KKuPapMn`Y1*Z;*X*AsR=@`g&JQ{!qV)y=RBQNoHd?T zF!tJVHWUfL#gdumWsYwD_*WQ^2L%&52TaH2GzBB5L2PI`5|v!Eu96xVD(_)XgqK>< z6f25upumhQJB`8=qp+fo?HlqGPW4a})|^Cd*+U~;8_s3qIlBWMIv9)|5f>_2?Snh# z!hV;X?VO12g@3H4?p@c*@#I}n_begITjJlfij{78bO@#%<+)=P;Gr9Q@3YD_nuK** zESXLZ2WHe>f^%1%u&V#r?4&pGU)r%jN?iU353L^lAwqm6?8 zLuQ0UMnq;tWlT4Q%9HgVqktdiN9v8dASMC?Nz4;TvvUvrtM^*I*LE-TL^BB&7w1%E zM!4^B4OCaL2iRILkeR~9(R+_UPoZCLLG_F8e)?YZ@%JZ=S5J3L2|aLi9QVhCS?b;^ zBJ4Pkjxm}J!!gi20-UxSrD!i=2NziS+-i`g=x7EF{n5Xs&o^*ODGY(OnhQq;7&vWR z+V-wpvN&^p!Eaj{iq|`J%sf-ibKwkeYY7g4A3@%wh4!^1#GX%o?miM}n*<~;T?D05 z7WBNP&h12&J_5Gts`CmL($g1z`|$_W7yk=%y6g?sR*%z`Oef^yN}*s3E^GLv$7apG zisOwQ9kpN1xc~wFDRcC#Jy1WHC;U{h&yfTchL&I-S=D2rO*nOa)g{yvRh^5CE!Mgj zMV7f8Sp?xP-2E7Nz8bVmfSW*=qDp9L_CjIkkxew8A;#4LU^pd@B#6ms_a#8Wd5x65 zzWPtVF?#oIjA`aFKvdK!VEf=hL3~@gYh7@r`)QhAixwgWmM&5k&qDecpC8id#2|Pj|$F`t=BA3VqlzCHhV7$ugA16;eSrjB6z|Rh0Jg0Yq&VAJsOXyLE{m!kQ;nU_Q0&TKh=z3-dR&+Ex2%uTkc!F zkEwQ;$JJ|w#Y3bKqAu8lWrz3#TT$g*lk=9!9%}H))pxR*SyWL99S5iuvo{yV3Jg=j zADU|kj!-BOT2SCF34;ImAHN-37j+6?(Cw4_dInhV`uV1r%b?19%ScKL;qAv2w-owJ zMCZdb;SxaOx6=~>NpQmRGB$u~Tj|+(E_`FHT)kKFi_B!7rk{#5cv>OWO{q zNW@v32r#LR1XB}OfNV@bHGl3$ELYf(SN1vNwwF3P`Dq$|JBao_bMzZR<%t#z@8BVp zJm;iA+J*yR(IzyZD2nhf;oJ`an`tw0^hVv>{z@_OIB+O|qy%(S0-Ib1T!~A6JwoaN zSO{-$VM*p;Xd=1ssX&v_o0lYZZmnoYE&^}|A<9{%+m}9mIv3PaGJ&|7MaR@9 zBVYm9tg4V5rJ!H19$K<4=s8rWu;n3vN^&6GUa9=j0!T}bd;lOY5c8fTvVpJQK&pga zi+}%Q`|Y2H&SM@iV>5l}FWMKqhLPx&&3Is=Ralt3sFp$t>NnukufBcx-cM~dl(2uP zv$UqC?4w)MCKfFGiq|D)66^s-dvy=Ml{C|Y08F18IZk~W`_NXqxRGS%Id?U1`2vX| zUP?`sL7mU^Whvf?qBTU1rWmeH)wzkkn4UEPBkp?)4mBr~G8Wa|Q2-;8jte#pS_>z6 zrfh&tV@|Kr{OC#?)ILw=@_29I?w+!*L^~n|bdLL%+AFOj`T&a;rw>>0Hd}6dptn=A zFptH$Bgy;1(LBrw<`2Z3==X(Ol9jpvh`T5#y^}c`=Pi_n8tr{aa>5ky(?8RC<WmT-RAWBhjm)*OR%& zb+6E**h#Z%(-#m}U{#+uAZLV^&BesM@hMxkuD zrdt5SH1-3;hqCj9nCyQ!=pP`w<^}Cl??d2U85vlN=hlvdRzFqT?MyJmQ?z z&uo@u>T`lB2<3RfNpqhgfdH6Or(#=K?wGKV(<~c$ia`m%R$#vcuMA_jEEnCk8d5>4 zd_6UG>!CD|KKi4&$HL)R&+d8p@(6My)ZHjopKVb+`Y3_^I2P<) zy$!4v;Z9(UUI4 zqPg&uhZba;f0@sCbgjnfQj>r%^jX>v0EcrvzTyCN=TOd!dkLMtjnce(O;z!QBDeZ& zqp)Gxj$FV-ZLpyW$AQHIw(ElXFxNVTH-83P2V^5vj5Oo=AIV@8i1|I!jkaT@f_E%v zA=w8fopskh50nY1Pa~;bF?C{d7wVQTK!deOfgYt|W ziyE$_0JhV(z_N0%^q0fyb5PABdI&6eqx)h%{WVHPYYctb-K{LS6EZgj3WecTy@u-W z2;F$_fcvTNikb8iOE(pFZz8chSnFL3jRD8vem}iZjFi(VaMT?0kAG8Mrys_CWCZf( zrpK5*V$uWL_F|vYZ!26p{bN}1v+L`Uqa1Oujkfwbyx)1>VIrCy&s45ZCk(8@g}&IIhuwOU&Cf3q@t?C;@-EN8^BX zu=X$>?XveL4$Ck*F5(DXsy2RAPZPe=m$BMU2jonRy+AtrC|NB@z1d<3p5(Q#tHqyk zqW^9oB}7K)_ol8gYL6)fBQ>CgpB<{}qO7z_Glh8fsN3_`)n9vnN=G}rC5)m{VvGZb z2}}ApY<3|(RTnS$s+Botr3I9V$eGx@p8N+MPq9zxK8bMfd`iiZdaS3P9nyhi{(m)lcHKJNXf zZt_MMFw3b@=jQV#nPdeCtqsEx8XzVx;KMP6c7vSuX;EXpIt(M9Q$ zCa60#lPOm#76PUv3%#{5wGn|zwE8-p6e{=d_1Oz8tj6>7Lk9#Mc`wN>K)ao}%V}3v zNm(FyI0)Z3gwR^OHaV^&3r;J8u0zeG{!#3YCS}^MB9ad>mF8K zB!-=`V*8@H?j`RE@ESR!YgO5SP<#5)m#Qz>|0xPcv1CGUz7BH%DzKAypq6kk)E7XK zDbJWJ!!kVc4WpuPbO36y*b2io%+9jc8psDxT>_$YI5;3Z?$8wwu3(BZyjE5Nam$Kr zw(qNckWL1$4|SvofPkLvp!TZ*6JzHmaFF?SgT%TL>oO&#K8W&Y;PB8|2m&-w@zYS>lXGW!pg0#o zGe!TgC(T&&CueF+f+D)_C(?&gK&aQC!3|1Z0RvOC+ycRE^`_Ke8 z^FGZPfQL8yrYCZ2VT?xQT=j6x9O_M1T$G+8AecH!&YMZw!{->TRaO@}aCdnk}L>}D|l%Q96cax_mCVOZoL%zwMPeVZTrPmHRwzpU%9&2n{25h9m z_Nw83i}r zfPmRvwq54tD4Jc&$HkE=hQ``nQ|gnxj~h__A+O^Q5G3H!VAWT5mxh#pZMe-00y8-e%Gla!RK_N$+jye`)Lg; zsUr|d81L>;WmHpAWP4S)YGFG{D@>BT9fYh0RcTz-C-MP?YZ>*4aWTZS3a$>2q%r9S znXyxZWxDWeHDm?%%TdJw*-Ew7E+1I%s07qZaS(P&J`_sMRVorcb>9 zKpJ1JzUHT7P8dLb9~f+PYqs3IMP+MI7H4xtuEI#&qXg13asijtfMlmk`=2c&EBi4JfB02P`ojX+dfc)`$KGG1v=79Uy=lF?G4*?4RVPV9ztD7K`Z} znH-5S4rhB5Qn9v%o}u7iA5IDF#rj&~AOXx-+To=QbYt@Q55%Yy1YnzXmKN=bxpLT6 z5|#EE#ZZ)$fHyH##CN_<1?|ysSz4kxFk`an#z{-aUX!DALw$3AN|7K&%ls(SsSW^8 zW#ShQmch=@Z5GaOsu+KgA-9r{geXwmjr|yYx!g+HvPMv2=q{2452y*C#Dh~#J$b%hbc0x8M z-ek-!;qKEwcugY!41Ml8Q3y8rcxTPkS#)_v4Hb&GYu8&uIckR>P>06YH3LPUZro?d zyBcb*y}z@jo5!|socKe3{JuUUrxYwlSo})$^+s6LqNR0v}(0_(5NN})PK%; zx6RIH;(^}|Dl=o_d14EOpnl?tCPJJ&t@S+_jPmSPCCQcF?w9m+2A^6YVrNWy_RlZ^$(X zC6pCu(N4A*ngodhdmSf$L^_bid#0B$;pNuvw6z=dNwWxbXQ+DHwFb$(?~;OgfTR!u#_VmQ?26$U9nq&_2rf?yRp9&7U1=Bt}d7K-@ax4 zSK z&wiS9sRAAa+u}Odhvy+nzRvIDlbacdMNFa^F4>^~Tq~bhQ62mAAG&|LqT&_`8vQu- z*HYB2CM3?WBX;z9?mW{^yb3)vN~j3LPS2jvy17dmAE(N8tov1EU9BK&dd#itdV21y z{l~c4PWoFA>aZReZO-$dFkJ4_OXl4LzqMZVV>AMH5_Nh~+met7W#GGk{yUT;9B0^F3Vg#@LC`&_bSyn$GR+d@)^Qgn4%8N{ zviq=q{BEMe$rkkCsloEI`>P_trlb8O=SIyjnqBKKS6Sx5;0@KKx@W#!G}gz&I4vJw zR8erHv`RK$VGvzaw|Xx?{7WnCB43xa%jz3;SOdi4w#gX{P-+GfB71@^ z0$aJ5-)+@&#Ox*mI}0sC$`D84cdqh8E9MO=hNn(M@~Hb#h3b8g>j+v%FL*8{OO3?W z*DR}P@9sa&@YHOSE8~Jh(nD(n_4&o0{rP|qq=w5sW_-_ZgjOhi%N4#RK5xar8Dw`~XFwA$ zLA!beOuNw^p*^yzC)aeB6Oqd`9s`(5u{47ixgro}jVgGo^eq7?zf*;WQm8+lTaN{Zkz!#kwx6*C*X76g4{LYcYsOc%hIHhz@4m z1e!^x4zC~|n7?9k)}?uaGs?I#^5U~EAH-_Kug67L+iJv$rPZ5EYzwm$3CmO9>dUR<^OYb{B_0YsRjXhbrSiS|>WGRr>FaBQX z{yF>efr@zSfk2e$y>OMeHV|Or>0zf4#FZwdBbIJrqI08mLdHkmtE|Vo#&V^vUJixR z2Fs!Ml`AIrW`J8BRt!#uDO{HQJ5kXqHW*b@j*+849!JDm(H zngXcY!u|7B49A*V*xC{aA-uY3#d~O#q0aGaJgf3(-3gBp4!d>0aO{inFA>K!M_b zYOf`t(7i~vaZvV#K-xUG>uBybuh`fp!j=jK2#8`W3m~{AHlN31-JiIbLzkrk%h6|! z31=9WA0aJE+%|nZ{jN8J=4BmquK0=!`sp9^pVgoK3;Pl{m;we6beXbHt4jqGruI}A z26fd{7hRq$5!~7;Xe@!30ypla@BfSH)A!O*2eFbH3W4w{MaA7>jlf~R<$B)LF0BdG zu~jxn3tGZFv$P-khARzKzjNpnwBE-7fprMd1P&Av$bigT58U*x^D_qQKoZMEYQ|gV zDqst^D?&chxBbvPN7Mnm6OUT#6zuLRCDu(U8GV!j{LY^c98*Oz9C;{5tB^^!d3?mN z>xwUXEtHEf1PYY|gi`xy)BNf@WlcM?zB`3Qz@8b;2u9k=7R#42>m9#+e^-6{8BQ}S zbK2qw?RYz$>(UfR|06*?6luR>ty0_`)q$$ZtZeb*QC%ZD=M{H9@)vpJsF$EYUk~e< zUTO$?TbQ}k7?hl|?9HwMaG`&>ua1F-v-qaT_FhEZ@3Ly7$$^*&i z2zjJPd>v`dpB++u5O`0*d#_yr<0;y8p|IJ`$91TKcn~B9;P!t2;3Sa~LzE(8Ok_N4 z0X7~IIQQy7BHKC(NJaf(AC4lxYxH<=mWB++MejLx1yK~WV4$#}hN^)=kIt{NXjq`P zpv6~nh2+^~E_DRH7NS|<&4#C9xvtB!L^yJ6Cxpi5sn0HLZNz9C|APvr2NPBscr1Sa zXnMAwCB2gl1V1lnB%DYm3CQo*Wn-EoW|n?v>ka>s{hRuc{7*|(G4-9JlII0UUlPGR z{gZVCb=>;ckk~gyYKFeb%07**Q5X*PaCf;?D`6`TWptz8Lju>_D%2gq$KkP11&3>! z@_Y`u{8-pfLuSlHTJY%}L6~Uj?3X&g`$uDFJDlFPo-MvhFx6oa?xmMp%l)YXMAUOb zw{)7AE)Y11g)0K1B~u87WZc*iaI+~XuR-9u?UDrBc`g9UV0mRb09d+24e;C30@1G- zwmgAS`kGJL&~D!VsM-rw@J1dZ76RvV0dCK86vrVn}xWxw07+1Ji0EUn1IP! zlQdm1&Du3M|3>wdujous?UJWp)0KWua+z>sKS_le`+T=oahu1mK7cg1RfMk@V@#Z6 zXid_6u#fx$wJjJlSk&^F8PwdOO}Ld4pL5;Ey(gNu1~1~+}P)7tVUXCF%k25M_KP-u0Al*Ep0y;+o zpxcvXUZB>m9T63pIwR&O_+RI}cUAZeMfqGvjg4cUbW?@>#Be|M+;wPk z_gh%A4o9OS3B-olQ1UTAky*kPDO@HBH%m4dSNK1naDU)S%N-1~Sk;dixikS2F0y5SnUdbcy8lMysW+ZaBdL)F*XeJjxJu&9_dS(AF{b=~zg||1{Jea!EUcQ+iq?d6Do6+w?u_oc7Ze zv%*L9aP`2&OSwJhj9Bw|etSR_dI~oW{BtZh=)P8Xud!^O0yLfb0P0`(N3iE!YmMV+ zWUVpb(}<0qUk~pEK<%vSa>=M^3bsO6*k>ij=2atoG56&9wA5G2v6w%2chqrhTyJ^X zxXDkvLDopC2USmOfUWKDkPwpcm+I`}A3$IgmTq!u4u;-1L#Cy9N><#-9sp^QkME!0 zpjx|d*SpHu7X70OPTV3e)sK5tAOd*xlzP3=PvEV7Y77T_v_`Jb<{tBs&F3C5wLKpp zS;C#h0f2$K9iZ$O0(-}K&dF^`(`W5L)(FM%E}7@KNouAttiHDWhJ)2MK%5GFrnkXfOugr6vmX;Rwu&-cyho8SCq`cdR| zrPx%J|HYrlT?Njupq3ZgG4bZTRoaSf8j>1PzbBr!|-eOB;r4j+De)>U& zL78BO4rUkvUCEN*%kH+b?a#b`b|KK;_`(1o$S;$F$l`d>MziGr{CeAwfJzFn8#Dh& z_1tHP!6phiDK#rUzR^e;GsF;QBjJ-D?O&=-|B#N8z0o;9{!@&PZXs?+?O0vg3wq*^ z5NX>)8jCN3Rc1MWzGFiJ@amIb`oKMQf#89?BAC7uW2+!y1bDoYCd0OSQ^%Y@UeG;* zpINQk_!O-K=-TI8mSw=lxAls0qtvYT^H|;?u$tpgs_8o0is01N|@6J;Q0oh$ysV7 z_Kguye7ZP5{=$tXe9rypx4JfI3j>T41p!;n3=kv+ic6aiLR&CvPJDIX{XD1u74Gg# zl;%$V{{N`H_7%MzkP9RN=%}N#cO7X)yUyIsMFpz2Lzg$eXA>*Os!jO0tI!1c;jy1)WNL0OWT$RB4F9%@W9)Pi6TSC&phwH!7wEcJf9A9X66i{IR zG`kNChlfZvBlsob0p*ZUr9pLdIk?MEC>6bSQw&ZUObobvj;qRKbp^iJBFQ~3S);k z{9f7NWWSsg0Q~m8&V^gegVY~lO$Kew*J3b;n({SjXOMa|)U5+9>h4&APi5nWZl>Pd zNY@5{M&>md0jhX~jO;q)*+wec=~9sQV59Yw&GSrFU~|NAgQ6aTCx3Vqlda+ymB%xfIwd0y1^w)*A!H0Mam*BvB z)dhA3YMRC_^q4XZt-l0#Rp4c#A82v5~aW8VpZ4RHP`9cdz_nKdV0e%0Ga#HP$TYD@IcE=6f9L z*I=ThVcU@@mKN>qJ)p-I&gcBugUX)QOFLD;V_y>d+cdUP-hx7*`ZxLyLnA{?%nr?- zqgBec`0d>_)!MfDHLvTM>OsYNi=}|KM*+)$cdH<5&lREBXa4{t-83}_MYLND&2u`! z7RTeK)yGsdT+}TkcI{<`yeO3ri-LEE{C8y2XKoxdgPCJalT?q8U0gm1QON`NQU%rM z+^Y?S!yH9)5j__w(q;^7%xSQvT*ApI%Mky&)gP#W17D;uLAN$txTH^{IdHLscTi}a zqW9*_;j@;tCXB}9mgaQfgV_M?&7HPim=MD{q z@0mca)TJsljek*n`j!9eb0~ba5C&FF=tYe+5i9k7{KI7jmGc1pVW<39NgM5+aEDY0 z)rY(aTK)()8&u%7Btf43d+-2>0=Lp+z`SHgbWRN}`_eMlbr8c-50fPSEoWBE8(L>_ z9rcmBLbG$pdJhBX%gS`HvDdsDuf;Df7Euq)8A0aE)(6(TICtvE07@hQtWqt25Y?3a zWCOF4TC$=^f%i#EsuN9@$aor)+&##| zL&mQI%$WrHPtR~<;5;_8^U$5f{xQb4=dPjJSl|>e4L*e2XdvnG5O5FMKv%meEFL9s zl{63JV5cK>2TOkJrS`s;+ZZkaXJ;psulamonj6y}FZ!A_Nm_;GPR?tzhq$_{Ge zP_kR8SBXjzLlqbB9y1HiZuV6p6D(rFYW5u1!(;Uc?kE+^W5PIvR_iG)wo)bLP_`F< zaMMG-&fsTDw{yxgru~>Q4G#91ClHM?9Q#F4_4n1sA1jP%Q>jqodazvx3iLtcApfK3 zsRpPGZ_#Jho3wQ8)V+i@+NIx^r^SKLP{_}7s^s3H#3D-FC$qnvwHKavffB~x%nb+PNGm!sZ> z_ix1r6L1mxt9L(zJE%jO3KgI)o4MY?1O)5Xxk%r?sy_b0Ujy2@Gp0;f(1+sVC2s-= z+d+vjq`&){>f=B70bB#V2iqR(6cEl{{pQx;OZ0-pIqH&37@!Izb<2LA$RJ&zcQyv>ne}&e zOCIyCccxw3_5|u%tjTf9#(qgjxV)-55CG>BT+$C z>mgZ|MksFwZjtP2E}4^Ye(yPAJ;4vtb4oK$uOU$pYZE$MGSPdf9Wmf(^^3p7Z=|-T zUErr4NkiJJdSU8wD}>_^2HDSTUI(p&r(_ibbcX+^kfx!$rxXMenX-Cj6}(Y|NITd! zN<)blOy%|hoA}h=c1ZUNXF4EL1+u)ULwTA-r00CtzJ>2}m4%Nsd7ve?-lUUw^4dMD zbzh@RhO~&UC}={!MXJ5nqYyr|j^{TXm{au!v#mOLB}PiN!lkYA^lhYR(wyz?A^+DN zxdnsn&U|6XcRi5#CBKhX4)BVHm+VYwDH2CB2)$Y%qM-2kOi zPL|2rBUux8ojni17^R=Z7QO?a9NRuIy$41g zrL-R`kOc;RY_L}B6`SvN@B=c5?vq|i)EUdK!w$R?!mOlbH#k9gyyl=ab{3dkH`LZB zDw!H8lQ=I5H`@(7nkVryS(KT;iXG*G7%cq$5#mg%EM9{T+qkDXdP z$&l7x(E*8B={Z{wh@rBq3k#A&GsD&;{qxtp=IeCJTyTx!Ci67)TVT1e6E^?ri-h)) zq@F$O#OU$o;}wLqTeB)*VDoa99rUbJga199>D`Xw1@cT9Vcke7I9=amaSUkXnj_)5 z@{7_4FYdzrB{Zd85T+dOo0N&2x-qEWlF>SCdMuqF?E1 zpWNirXT(_0P8ecmz_ebiEa=kd{_pad1@ivga)<&mfrzr^-k!r)yM)pO1Sl6S-){4) zf(<-$|7RFp4-f_Sgm+vs6q<10z~}+FC6o~p2!Hy%1<0{+sCw)Wj2(Cz@VUkx;WPrA6lSK_&eZq4N zx>S!ipsx^ZB7+USRL8>V6QyW%vp(rSQmb_(k%!WuOg4Jy=e00jOZP7zXB46h1}$zS zoXtq$oZ#!cK@p%(IP^mKe70}Kv3Yn3_(fhQokr~}7(+K697vG_QaZ#TYU?^(m=P+w zx^xct1wd-Y&J2Z=uJ3bP04fr8XY~(r3rGu0;(K&P=|c|mYSw`Ec8uD9P!0l!nw}hl z5CDNd6_)TZz<>*rU1L(3q`8kNa5_KGrUVK8I>o_Uv@(E{6;-UU?Kt&X`g2;^%dXct z!1aW7JA_*hxjfE2x|S{L2~sk081Ue0zs3`IVB09*dvM_kDFOYwLRYt~r&zMTas{{o zxw82s`>NmGP08v5{e4K%0=SYs*>{A~Y`*HbB%zA%F9MU*_)O$3_y$4V7F?3Rr;glS z1q58#6oBKH0@{~4ACfa2qCpQo91wvQ07~4hW3FDkP(55b+CycOMx*pDT8tY)92GWu z86{NuA+FKEV)fyhEC8Yi50ucu95fst=lTv`!(uG8q%1Xj57Go|kHXOiXHx+eiobqr z<}iw=MOgl<%4_lLRy0II2L8@J+xc!|ak>>0(AZgGp2FBcF(Hyk)H%j+sxcrQfo-)V?z>LFCd_XSrW)CqPxe05uom*oo)NVAywy!;k0bN&&sNSvDd&{~%|paxS%6@eN4ot4 z_%JC7{TpYOmKiv5i}7K7SR|N2<`RCmk3Om~M+4=jc%6CY($D?;(;omf26eR0OsBO2 zY|6T)ca6!<>`(f6yH)f?PHzm;r@UcIfshj(A%;{bX>FJ6NE=v zKA(^OCN+^(_3Ex`#-d<{*pCN|5h@COE?9*#)fG&C9fLbS_bp_A9j%39mLAZWR81oG zoPHiZyeFku^l!3>x7Yw^$6YW(XIiu8KDo+JM%dF}i~+bBoRMNZ`S~fotkDrq9(y6G z81RIi6TuMI#)N9L-{>x|_M*|X3BkBnF+n$NLcKLNvX_%@*AAR_zQF0nj&!6WKjGXB zefNrYq>1c?@d*Z;r(m5fSqf=GdC75Q(wmb zfOrZYb-Eg1K&vEB>TCbjC9NxnG2<8KpUls}w zhw91|ydm1xIyw~9p9?x;9-01rK~tZIt+e_l@|j%&sd7-w76lQ6@>{pn=mD0+mpyl+ zLm_lnHDn1x?Elwa!4*}1}k2DAiw-Qq4`q6SL` z|D*aJyfS)oVc*cE4X>u@h(P;|vO$nY;(s8iW_0Kisw59;vx5ud%HLcv9jg>w%hKV~ zkJF6mUubd|ZoX)lozn#~tc+vYv+osjtTkx`bp%JL%T5Sl5UDJ?0h_YP4RfLt!4uOL z7y=7O#cJVnPeQFPlnBAnZw@}yB|<|j$-^BkCb26(#u5GAO^E~5cu5fAz$R=NAEuOq zQf#4t1u-6Xg;h~8GIFa6k6k;VL%-y~!tXx*P8kPg)Iur}0plN^&O}4kH(g=BkzJWhz41{nxAUq(wnS&x{(9ka2#>i;@370RqKRU`!V52jFe5mFRR)cPK)^NeCM7Usw?w76*WsN;Hiee&=F>F#*)rI4s zCLI(<+p&hEn_hY+_BTgBlEqU=4Ra}Ueo9`!0nxB>?gg276`*`MiqSBb>7gQlGv|TI zqW2K0dsN^XyloGag|)jJ;b{W1Z40;=LHy}QAAh2FnIKI!E+B!r>jDyKmFF2}RURn| z6Gy8o^xDtaqWl#@&SZw2MU9+5yS`H;*sIL7%*fv`Rm2b{DVu6YwMzH4RIiM%bap6# zjDcKooYl7{3IZ1d`USTX#RNp+Lkg5C=k&1@?P1Z3wGU-Gq$o~ABec1%_7=nLHCB}q zHYP#60oG3}c8kBy`NCzqwdRfda<5pyM1-z`W8VwcaU-THtiiSd7t)1RIZE%pFOj14 z)nn@=nLJ>y4=4?6bj4qM-1;qab*a@=%QblK0eWPHMRRKg~id zpCJf=``Uo-9JvLc3v0N@W%jT@k+hiKtyCGe#CW9b)Cpq{!7-*#5Nr#BZ1g2fJ5^Zy zD7y?#)H>A2OW%`Bt#w8R<})rdG=2}(j^<;zQSB+qcFpRKlsN21`^ z58XN28$bcSOZFFjByr}@(a^lOw=+W@18q}_Q=tp;3%`P(+Bh^CV5%iBd*j@4Rgbwb z0PO)ApQpU;v6r)#?7{3=n$6N#+3C{RBRi;%mIqyTSg3>!UP3}VpvjkqqPHxO3r)5+ zbgmTnU3(;QOW?m1!vqGcwTl6cS|GuRR9xoMm#c3oQn^_%GiVAiRMTdHj+I=(o-PRW z&Si*Y{06zun@`NgaN4t{(v+}73@}eICkWGZD~pJ)ihJ*l8hPnhcjvcBcyN*D~K(%2#6KCqBixl?% zypsOf*RY4P|4XyE6Q(eN3l7;zv(-W-Zy5ZN(Ugp|X2o+!Fxg?cTmtM~sS({0^~it6 zoNA1aH-L&h-Ml5-fA$||--s&YU2*(h{eMA*O$%Jt`K2fzOmNz4o#TV!w%2(%cl}ES z4kDrT;#9QSe%U{{sNYP*f~}zUJ*p?EeV0DwqJxssi+{F)A5=q>v$i|E%5@yCU0_k1 zaGx(?Hh7Jp*Dj&gkbV!o^VwkwZ`mQdTj~EE-BKTr9hBO_%e+Co!(+xPq*}Lyp3p(~ ztj7*RNNBCd@kax?Ms&M9S`@^5hoUFk3vel6LqnOCR?d5{Z}&CO6BG+kJXEe_jk^?V z|M;Cs|BwO&;(?_t7q34AHCg&?j*)5;3*SXTc_YQ$*G5G zVztttXs3K+}0{TLzpVpZp4(G+0{--`?fTrO58WYS%b)KKX##p9R*|pMtS_73^0Hz;V z(-F&YZzuE0fwe4AMlOX)p|R|*DqdEDoM?evW<4Ro4j&((iC$4R-6@Jz7xBN7l~&g5 zw;n5z?E{_!R0!tIZPKrUAl<9q@+VsNPDoto3jB#eJAVQOj^wAL@mCME9KbuD`K$oq z0jC@4wzO-}DLKAADx0yUaFBH_XZq1}A8-H#o49nVoub(JbYs!`qeOt?=Q3a}Qo|dM z#B6zTNxAGnACXaCPaU3^J=w0wkEoJfAfz? z`A%RtuLUtA?a@9jdS3cWsOHgKgh+TPn3+WVJQO^`Au51O>__M7QYgGOIpTxd5EJIH zg8=EOn|`g;TAwd@)(GwEQH>JC%Mu)<2}=m!uK>%25biMj6Z|Cu`}ems%m$igmb2 ztpy`%RM`kKz=We40)mJL1|Xw&&RIi)D38+H1eOx*k3=|F zfU;jx=rRisq+sd8b58Ww*6`S2+;7P=3Ln&W*YN<*49X(U9c5^ma0bwRZq{vKHs#f~$rP6cd$^gn8jXA)^l|CTkO zol!=F3n41r&Qp4rr#!iT`qsH_U*}wdreeN3eeu7lPd^Fh^3Q>6dnIB>Dwm+YL4wOV ztZ9zDK&?ChLF@MLKNFw*6I^XlQT@`*>NLIBzGT*gc2AaaFZ5D*INvT{WSNK z!l!4IT@%@gHdM|)+-=hN-LLfbfFs|ru2JM^TDAsemDUsDz9l^ppb@V4zA&FV&GkKR z0jaDAI8{Hv?4mT5t58p#>RYJnVJu|9<%7laXA=79ngsY&^Zhx96~EJ!n6nQ5jzZ=e z)tA$uo!)7FgEbEJZwRooSvi1`w0^0@Fd9VJ7koH>8Q6{g3%6w*MWI%f z_SfiaMxZk_*$<$km|YG{&Bj4{Qd+#O!7Z#a%lo|6Z$KG`()go8L<+C#^Eom%6!KGL zlYTR1b3IUi7O<5q-T_sqgx*89O=E{NP($S!Kju;gQ|61G;1+-sTflKN-u`7$NaS4j zqMW53NiXCDsV}J9A*O(4I=TY@j9L zli0uRusnM|RQg5r$>pel83EMJLW|IE$OP3*L8h;6@!fu!9vtX{C5QmH!zp$|U2FOK z$_cEZOHJYeLSI_Sz$$F@l%FV>&@e_-?yqK=1cc9aWNEUL2^5)0RY?0>`*Yl@^L!L$ z^Pt=nWOz!+F8vTXfM?<&BskC!1s_lYi0MTek1xARSpjemnEE&*z%$uELzf^@?Owb2 zJ+sDe5Aj8qAV~4RKGtVPPutI{T}~+XXuCO5aC%R#;tx27Ymi!#cAKXp%#nLSR;)7h zrP==irz#D zWZ=jeEBVGJ+NW#z<39b5mxAlUar{*<>7=EE2fFN-(-Gld4V+{Jh$3KDy$Q209XVwrn~0*YWB>xFj7zS>dk-qR~V%yp1k*1Ffc zoUDAib25|!ibkU~)ZbzCzoy@ZBV$1c)02pES4 zJVZT7*CxhL9SIZz`0|2nZ7lMlEKz@lW)&EPk3XyM9~rmgCs1;?L$Ui;XTRwINn`y? zXZ!fk=U&cJ(c*CHTd-D@1yJ&IXlA3|wcore8;gmHh!$zIE5HnEX{fl*A2iHP+VQ>( z>zjSfNuCmr_u26#+p{U{Ox9?|0Wp`e1F^wc4MLUBGM?oQW&YMm`&mA?mNL;ON^x|} ztOTM4^tLcQ@C;6qX@6luU+^^xWpPp=8~v#3l^%3B3x3!We7<*k@`$dO#a(v0TI$f( z{;CS|4Xc~_40*0h)7!Ju?o6K5LzV;&pQv5p{9$ghfvw?!!0FHnW|L?{Zhe}ydkSYC zKSi$^{oZ2%L3O$z;q?5Jpjmm*tWQV zxMTrghjrFX#6rRnsV?H#zKhSkq;X=lg;=p)fIS4pzE|v@MMaVcNt7TcZnMTxYW=jl z!}ftB`8`KMAQ~v!|6b@A;>Wm+BDO$yd}ogd7<#_bb}^sHKqVH}A1dfa==1EgW^WpT z9$BQv%N}UF`)mA0^_PE{K6#*#<{fw&T@N*n*4_Jkeu~dR^bm)Fn)rj_a*kq>!eN?u z^@a4Dy^2(5QlEeCh&kwY?qILVm8gDQl-Gi`_E`h$U2_vM6MW}aBTXB!1P*><5|-!S z#n&B&6q_jP+o^|58$MJ8$r@BS--G%0eaRi8MAu}292Sb@`DstsvCNjN?emA}MSWW50_F$Prw#C~HO_iy z&Q{miPkkN6w8=ApJ(4|BpAE+;( z`P_G^PhP4Qi!3)7a>r!Bp75yTWm(zk8k9BFee#xVLg93U{a>*FNOPNCQ3K)P(ZjCZ z<-N7YGb1?IKn7;!gI^Ggo9*a(0y!WEN=mPfa^^f=t*y$u#^8d>1@deyFM$Pnk=)UX zobleR?|&g-mQ5mQ#M(G^?O@O1lG$}tETn#GVa zC23bYBdnPdlu^5Pd&Fl=QDN9D|F=+s`0rLiA;S^)F%(`VvfaYfcW#XF8cN4HT03 zg+dVu234~|sO8jKIFw(tnQy|_WTcMN+NJh-lE>N_0>0{Jf9W}alSpsQ#PNNpyItSML{b|2^DMe@v0EP}4q>iw=a-yH(`5fRtaT(Mw>9 zo@fF_gPEe0%#tILeAr zcEXQMou_sDrT!l+QM_L1gl76i^}l(11H|XX&Zx62Rf1kCO|F zmNTJZrvy(*cZGXvODQys5I`)jp~;&g&n%>SJ75*rL22PO$GwX{vSC!-=*fn# zl6SJtEh+E$4TDmjGnkT}PwuhS=2!#Fnw0ljda9;k_osf5pc+R756jvuDKq-nDq`Nr zF8&^qwIRIb5*I`9WTWrHJzyJ|;+`QW5A?Jdsw zF7K*P!H0+m&z?sfv;-t#%cK5Kx$skO^yFcEQ&RM3zwbpc_pz~Lw-4_hcY`-SCD# zHJz6gQ!x9J`hb`O+-fJmCLdbJ(5Tej?y(NtZ=urO9E*j5%+O5KH}62Afm;zInryqe zZR#uUAS&5aYkC~Ilv=UIj3*!z83q>DQ-7~S->wQ`wWEU6E>_Da)5__JI8n**P1pXJ zzCsjn$+*1?+2=wACpc~(6%h;WUE}+oC&?VJ0FD^USfS5eh3R>9c zQ9H5mn~oNWBF|D70`sd7n_$JFW_cCkW0DSSwxrh?1~4kan|rl6G}iG75>RD8_}w3^ z4j_B!w4Oz{&I1wkfPDk1+zJX3e%4eT7Gdr+c(I_*-nF<9B6E65c7x2l&(-WxMkV8v zERnV?&1I(31H5i~+?OCYiu$eWkwe5N=e{NY9AlSpk@hjh8BFZFlR^3Qo;LY8wF>=o z{wMlJe*C_lTIqnt>~ZVl2?WWlfV4Qn>nEao{e+rpZ$}LN&iDj=swnj1$A0%)9-m5n zv5H;^KF6|YvMbC-l+KcsF0ZQOFpcYrX^$E`vjdZvocgar2+%AP={u(6qgMDA zmTT6w?nTGBW|v)*$iPEI_xm5P*~`Fb%xW3xeohvr=N_FJmk zOo%$bxQ_=%23h<{|0ocyc>nDGtBHWLT~*{$C(gSt=zc5hvwC>Vs%h zpXmcSzrY0hcA^QumhLdEw?Ye>u4g-(lbwvTgI16oT=Xq4;u_~O#|ZY>-dwxQ6&dKE zsUEq`bv~F_AaDZITTfZ81Te7?tu?*Z8h;;F+e21K*#XBpWEwzg)XnL6l0%;RB5=u4 z$V^#vF5#0tg)M(Fm}*m;$U?Z|_IF?&CsO;y?zHEJmG)+8wAO>AR+63GR2ztR(G1iv z1D3u{l$R6BO40(aMR|+B{vYXU-D)VL`~3jMC;g$n{rCf51inw4n3dczrQm;H3(&^w z^T!UqmY_f82nDd@r_~?-#^d1&DxU!plvD{}J2%X}A+kqw3sEfq5D8NF0rq)MNg<(` zi36GjT0i$Q)OVMRa(76Yn$pw^xsw_!IsmUX>eZ`_o0Dq^E<0 zBC3#naKPAS2M~P)EB2hJHX!T0&hc;a9$+nx>y*ZY5_7QAK9886TGcksN=+*;EE>zP zU7nB3c>elE^))ga?Q$iDI1fC19@ehKis@0% z{==IKB85-PVRuXfA9X=*2E@tQfb@H*H|$sLnKh7m3FK}Vp+44LFY$ULnyj7+iZhK? zEa9C4AZY#V81psU5>HFJlz=G*NJrW~u}g3cT8}Tk0?VHaGx4rYUvY3B*5d=Q0`C8&-b^f^MDgfTBWBajDd%I z$RH@qzWjrJh5h^w{`+o!I+YT@yU-I>N<$+WM&Y|Xq%m}S4$X!(%=g-Owm3g2dVb3-`sy% ziPx~2e}TkY);JQa>Hmf2RJ~vjOcG%d0kLEM8m!dYt-5JAbXE*cRL&nql!Bn&nadvS z1fUxgdXx;5oN$F^=UYRPX7mG-CF2f&=TIM?wqaez}7kL>4e{w zo&(L7>~Dme($HbnDt#ntr;=u`=G-EA(J*aF{h6=yfYO#ZQR<{T4AH3%a`MlaYA;FW zNzLoc=LjzCBY@Gs?E}hyy(XJ?K?pl60T8GpSVES3f$c@06=+%NRmNC<$Plr*%>^3X zs8wa534h@4fXfNj+5Xnv|MMDw8&fNI%K4M<)M@;?3=8}U1v z!v^y5iWDevsxSVQ!1WOErN$}3mKY!K^Nz1NAp%$`3hRIV2+IH3Vab zU7m=d3Me!dJ%8y!j`!##0JsxZ^A!*^ITvn8ft>&RCHKApd|TRLD0E%3i=u5^MAd&M z=TKO8V6S$jVE=2E;lM89)l1o@gzfASG(l_ro<~?O!Zt!X@mcRkKil)PpCv1vIzkWf z-7DFH0=<0DoXT!ERIVlF&%*jzga0a#-A63%x3+5BdX>5f!nH`FepBSmbh}p{UqDL_ zVHCji-y*)vKF)?o3=Fm;G&MyjMw45Md-x(Gj_T<)9jdCUc9dAl)P4N4zT7y<~J^oNVNNP{(cj(1b`S+;~~2mDpx?@TSeYznvgd$bEPq8h}v z^lb;iuHeAbdPL)l-_h88I^w!L0!55z;)JIK@Bx7LQ7za-9GPk)%va5WS~r2J^JKLF zE)-WoLuE-fC^mioqiq8JKxWcXxS&f<%-9B4LtHxhh)~2xSda7+FbQ#G8qH{DicWd4 z`n2P`%-Of-n4IzyQFGyZ?@DWX!7~rSYK0rnCI!jfXR{k*H~j2;m_LN9HmWvfPEw~p zEcaQ445G`jw05jr7D= zqv3d{y2aG6i-aUzd44D}ThEf#)QK^FuNGxXUTV#|fuPvqd zf?9`=i?!u@KWrt7Gjtp#yQfi{~jiZ^{RyKO(^b z$k%k4CiRXrFj}!l9g4i_7pF$BVG&rWj9Ij5_S$jGu78syS^Cp91YYNr7KPCE8IrSR zp6q~5pmVmX*xsaLzEy9&OGz#*{i0TZ?tN;Z!)n>8tyemRw?0f*`W>7fA8=r|8ykB2 zP$!E1qoCX8_sY73jG^~G_TKIAY7sNocR5@@|E+{?QLiF4M_9*gNR~;5{SRn0{AuAg z*2-iPLG#6LuRi{;{BNJWn|>lOu&n@n7!hm-VOt)ypjo0qhMVSS|LG=sMp3r2OiYEt zbbwzA;+Fq>0Iw9@ED{MnHy0+vm>A6#>dFC z3!e~>@RH*IPt_j{Y~nEdu7m0G-Rh6uPQjABp$COkcm9k26EeyGch&>Td=Pt8S8kND zK@~#z>NL9mQ$Vc0vFDjoVKmUmV_A z=N9t>ExOf=pr=CDrD|kCc6Iuocu?2_2g$@-}+Ydt@K;$LIML~ZG<tB| z@TREq4hU<-uwfw;StIa0@QW}hB6-K(B839N-v_%()f_h<)Ag>KCYJcyk%j7z7@It> z26O?ot#X0Q&a12e!k)u=t!aJ$YY}s`4@!bzkrMfiq8|gWwZL&`Ymi(!h2zHjM5;an zY`HcT+^+*M2L`Ss?GxGY{@(XKLqfoJ_4|u~z!3l3g(tZ$^n=O?o;#5up`~`F?}O^( zw|)ee?cu*JCULDyO9frvl3CNrv~F+c#T}?s{}NdBKT#urOxCZ_7p#Rf!c7B=iHL^2 ziyu2{2Q}E$TYAD->ur-dEnwPR;Nj}vwI?;jlX}^2RF1*#1u8+e)`y6;rBxUC{AEf( zKe9tUg=Nw=y-j~~!EXZ=d441<4mKW|$4yn-?rj0aQO^ka2lXRxSgdhJG1tMOtFaEA zq6dL)D(2Zk2TO33S2qs;SkOw9Z|}2tChqAvcaiTj0$LOPemRz?^VTeDHP(=gvCsJC zH)##D#sX!K?70hdEU!JXKq;tf&FRJOVV=fa1q6BAi2Y>oeHw_cw$9Z5biK<~FTt<1 ziJ9B#o?ez6U}r;0QUu9s=uaMN&Q z8D{%(f1`biLxppP@c!h3iotpC z4;GImENo_QbPJs-FO2}TyoK}!K_u2Roc_G}Qu-0MC&bHpZa)iK68m7F5pfqZ=U#gm zxDnn3>ZGa)B(?33iNTmS16UZP#`>ILl%yKXmXyyKqHE9XPwd{@jQXKq^%vD&_^sk3 zT4S3!?SUW{jLD6fiDH$x7NTq1cU`N|HMf)Dmu7!p+J(v~{b8c1YzcJ%ynPSvi9Sy8 z#$jtMaj(Uas>V{c>XEGnwyxG<2jivsmH9c^jnEp_K#KCE68K4=Lf<=v2`|fEDTdjZ zs5$2pGKmJSzL1-Dk@{|d6u3f}PmukDg7uD`l;7;tH9HX#z*IDu$-4}Igw<3OfeonHykRkO7XDz9GJr%GY+W&RUkU2o0 zbRMo=4X!Az6qRd*?7K(Zdr11C-g1*;1qQOqxv$;=(Y3($pzy4;Ts+zQ9hy@)Lwqg9Xl)zoxPI6(J5!yr5?R&hHbtY&o&;DzVRD}E$i^xZz z5NV~5uohQlC&s<@l#(v&yhiQ!#dkjb+>^>`u|oPd;Mu)u#{e%Es3)O4_2)|w(Hi^3 zdVnp;<0Lu_$j)K%&U=q@xSgsdFWr(|4xlNb* zIK-jk+4#t*uDR^O81UootMnhIz1j{HzDs01GEg*=x3+%QvT&p+O*bXAM#9FWSuoRx zlJlf1R`ajHm$KB_x@|zFbWm#5(dJz+=+_c&0my=Okai!gV1CVWf`MyfWbNA^-?|B@ zlaoQv+>Y4oV4UHnjKCJ@o4-`+=}qv&uU7xfpD2eTp_$z@9ZE-)k=K1t=T^M4DNp+Q*-K`cXMpN5zRDBUEvF8mCWFZeQ0uTfM?_*GUu_dLa{|Oed6nmmBxm!KGZuD1He>4}jWkPj-M?g9D-}fc_qd!Bvws1YVVTU`k}vHe#VF_Y52ZB~Sx7 zl(y;fe_h38I~apjJQ#81BwAWQhG;U|N7S*jCBXX z3EQszn%-{7!3Bqm0{EVI05q$yId}qcM@^VonK9>sgb}eO)jOE_-jmWDZ0bNMpNFHf zNH%+tBpoum87&u`m`iuW80a91It1|0_3%rX#Ee|iNTKz74(j^%{k7Sh{^0R*iiOgS zqWc=1?3QT8d1?Yh>oxMqJ^wYqp?8o%Lt49=u+NYx6}JglU?tgGVagesme}Tua>_wR z2_Gv6^B`0e+?QX7yC(q4_fBv6Ya7V_j#Xc4+-i-({I0ZYu?AAok-DQZjOSzT5I}xcdXAeSNxmllhPW7n57*D=R;xr ztnzf#)5Jv96%o&v#CSJY7|FM_7=yDKp4Ud$ZT0u%O&s2s=$?MlmKiWc*64X|`ge~(~6-^Qh1pYOh99ZQ6& z9B)kj{yz*&a3<57tPmu=WplCawT}td&|Uj?!jNe=>5H0den1bMT>*#u+w?pRr2MrH zX-v1SR*xuSy81+mPs;9W`eKq0^n!-)U5YXY3Rc@;Okca-vmFybFU2~s zlgX){skxwlbTpzUbr&cHpgD7$R(4SU;4A2tR0FNVV{-J=Tirv`(RFq8qu>15LVIZl zlKhxz7)62tdW%w2Pzshs;U*4@e1CJS+( zW|YT70PO?zhZTJo(-#Up{uv5i3JFM@7a)#FOw;qh4o3rxRITU<&Y%tf{oIoYa4>_o-6xFEZc1;pi)|4Nty3)+)kd_<4K{SZ*RE!`G z0%lAx&{a!}NUcU9AQj8v@IO9>m`M%zkQg2rQijpG#p2Ct(1F&ZV?R70`l)-AeD8m0mHhRgGBZpZ?l0JZEnXaeT{=CNhSc9^?X2oT?#Gk`z zW1|naW_?{&FrdzgC1d=&7|Nb4Hz!zyQ=13_#^ePdD=+Y8UyC&{*#wx|Gg81mQo|iO zWcI8pSNk16DZ{P;vVvD7lZSQ9n*)<9RP=Tgi7$+80*%M?1s=e>I6`>4_u<_&1bgHh z`f$)#e`v-yqD;cmUkek-pH`oKqWiL;2SKo(^KT8n!IoLsG;WK`Bnsu{_M@NNl&Y}+ z$3$kYd)H0j%u|z42U5@~MmRZ+K2^|IApI{f4L^5<&>aODNY3tLWphOOL#-y& z>SqNg>L3xhG%>x!4boz>eF6@oTsIt8-o>EA3VXD>{@-4Yf!eTv(D#-y0jnQ`EI|du z`iVL!j>IX^M2HT_Y_d<^@HX6~((w4~ZJ|sU^28~5KE#x%?Y6r`8Yxjcs_p1y5atOrmnRbG70jxThm84f7=%|dH_#xUdxADsw{hzFj9I_V zS*9`zs_hB@miKNR#^$<35X#CV!5?0p1PHe!p73rT*sA^qMYE$Sd@T??c%lCIdN`*K zV!|t4wVeEcplM&7QY_9NE8KV9Q|GN4X z^$j*Ze8UlvS_CF5&AAE*RptP0AElvhhqoId0xuRymJmbCNH0%n-2W40 z(*&R~aWk#{4~wl^c4mT;eENqvRQ`cfl>4qPZ$x>rq(V*mXT^bpCI)pCOk{`&jmfM@ z&*-eOW-Vpm=|ov?v1@#pZvfsFZEf@l{3btx5aHNSu`zGnY1)y0$eIhrdjzF4|ItYq zW;>!`YkZa=@cHP6_b0lXp~LGPss_?+f%q9t1^FLVFs0vUkJx7qkLv7Byw$aLbvhDO zEy@S$)?Y?fxzT&FBUFKXNY3qA6tWAx{qCQB%Nxb+!ycIbYw%AS3JJw35rX*1J85eG z8qUs1cHE_!ZM_2FPF`{p9g+n2F9Xyilm|Hw9)e{UjpKi=zN%cZM*C7sn5jbQ9-c8i zYUNsDnX7l4s0KSoh*9*sM9bGx!u6>mq>0gm=H!+=V3GJ=Jw|j^O}7$|KZ`O5SU_}m z+|zRQ<1g)MFEBdv5I6*{(cX8c0mCT`^>%sE*7WC9b7I-xgT*d;LcN1)P#IIJi8jj? zfkqafg(coD>A0gs0{gsugZ1QDjUeQnJyLf_XXm5MoEVUq$o3eXTG>q=u110DS(9$> z?EI>asdhvY6oD6QwW}1?S{EL2kp%jmy7r-0afCes)UO#cecd`_^PohLc0uA#zx7N9 zmo%%WX<*)U*l2qFGIccby=Mcp*clFa(|^W-OV1>$J%a9XO5~OccagKS)rNY^qZf56 zcCjzK$p~b})?w*D0H0pUnN$le*e~p4Yb8=}Bt-B-iM4oQp46PSVTDC4MEIo9LmSOw z9qO$Oz{7;kctv)bY2=Al8RxCF3fMBduJ@pDGYU{(-)`!XRCpY-?7bz8ai0XnQ0J?q zjFB5IXqdhSUgs*6YWgty|9t0f@}RNS84jJaYBaQ|{Y&8jNQ#n#=)qlquXHxlPC0qK z`rpM{xC(L=?qNRqBSKCChj7bVA|dyx9Wk%-GMO`~Sn+q9(e1@W^!2Z5Wav@IoxPj$ zorQXPl79=$&?CT91;ARrL4OLm8FpCNCjw8V7^U;_NNQRkv2LjiEyO$jxO;b^i=P9Q z7OY*QSS(Sm7c9wPJw2~2zV8}|htpeM{xy>Nr%j-}crDld?&EJjfyX8Q3U150g;fFw zokI&J%LYM;Fe8a?IDPWTdBMzhe5T!YmPnq*g~FGOP7%c)v!2QiP`lhT^M@eWd8U`S zKG6-j-vI-W0vUqDD&>bMWNXIU1Ea{&1p8($Q*ty8q;%9a{5b3p`lq|X(GrA=#cy0f z2^Ir?z|gI*K&?4x`3Qk%H2|0bkICaJ@bL!)_x(#LX9m-YNb^ZA3E1o;5#moAqoUbT z{|)xQO?_ZEUu^d*I!7#kz+#XL_pCB;gZ?wv172%BLgUKo8@26pejn73r`(Iju~~H( zQR;;t;{S9bs zqmCZ4`|mB&Aa^Z*IjXQ)XO4;jDF^ zeu_uJZ5)Ow=e!PnKyB8)pcMM7*AGbNvf4`(P{+cjM^A{bdW5`|+YQg;2Q!L38Py3r zZWqo@!zr0NazO6E!s@7}-)=Is{injgcJ!aI=XU<$4@mB?$o{h&Sfqlu8O`3x3(I5*dGe zwBUTnquUiftQAK zkSiU1{^<`N|GgZ|JV+iZCE|WxeMwm+P4TdI@_~ zUurhb=0;_sM$PYLu>eC@MjlcBdXOV1Zk!A6DtbndX0Ye(ffxX3+=t(sA z6~k`L#5-y-dnT2$1)dyck!_!T-OsB}KZk}8{pfGGO++QcfeOOC9ih0J+Dlv*$2?`p z4K&Y438_&UKUQqVgCBmcLzTde{4<#pJ71t)(YXgMY0Yf)>Y%ILHKg#aWNA&baz4>y zhmQ{G3>#Ma+kWX}<}DS;zw{RQ1of*hUMIK0=!>Oh-i@ z@6V&JplSEawfzNfySUqP+`Z}L7Ul9~NJ;{vb{fp|qcp$;!on~UmE`8SD+yM6R_e&h>L~_JIcSisB zpdeVMZBInsyA$0ib&B@jC}t3-VEC@c&jc0sAX>LqI4!3O{xIHfuYIO~W0hV|!Y(LI zwpkslKHN&ttKS6V!Oq;leK$*Sz8Yr5V5M6p+4SC`NN~+|D!R4OeSn))=4k91eL-;R z`_|0uK`%!+ca`jl-ONLqadrircd(u;BXVp}G7=|y%OhZqwnShOsE^dz1jQPF+>Mj`a{>WIel@JzUO zw&^VFdJZ%O3*Ptvd!)Pd7S=B=U1@ksK|{-n0TQ9%$)a2&A4$3R{C9tZ5cs!h7Ru&O z)DEUJdjwBOAgEBe!<*c*T`X3##$kdu5liCNS}le zTe14+0X(t;5xyM2dfsng7?2@K$x&JHo(ermgG=k}4iQlsH7keN<}604idG51F@-f*_j>l0oWbA zRkyAmF?<@&=(w&`t-2W|KS@c)4+6<&7vUFM%!e{!!Fw&(e&|4uTky`t{zuivA6Z!e zt*I!8u_5*!1I1W;KI{>_UswaKI71rH3;C~q-36bqT7Tfl<{v1x%Gg9=NbF}tJg&7X zut{i)C?4X-hXxZ}t~2cMX1mM0CVtH{ON8tXel`~P!D$!`<@U-x8v3+t3mni768FdJ zs3A+&PL?~K`76xoj6#E=9uCag4y}V++X2=GlPJ0`n6adPJ>|8q6(8vQt;TRiZKX|W zm0nAl*a)cYv3AVeo#uhhB@n-Rc>5)1U>b-C-f#_~PaUduJ#^r#nYR*n;n~|T_{bbz zt|u@nK#7x%%~vYTuwUkROO%b{+oHu+72zIhMm~Bi#_Pkev^>)bD}KbVq1xE$Ewak5-Y3p zjNf9w(e~GVraA!Y!3EVCv4^&o{F3JK23t}J93A_N>_`$Wm*NoJim_@Bm3`}6N zuAz2(&^YCs2nb{S(q((#uFzeiiASwXw6EXq%w)(d{^YFCt8VopM3aX*P;L?z!@QIc zI{Bunm4~2o+TCBWW$lod@%~-^vii%UN?{`Gc3asj2EU8wnmN^E>Z&@s-sze>~-(QHH>1?e1bGu)5~Dld$Z zF`mALY!x-yhE8dUqoiEwG+i*CuCtn9cq;Xzhhk3RZ~ZOy_;wnzw>Re30g%N+D+%bY ziJGd@Tt9FsL$n?UrmdI`vD+Myi6}}4;&b72P2G$(sMdtnH?bt0LVs|k7fgEbP&*G} zAn4D(D;fR{R^fvfgw%VeV@N|S>mFMJ{~f){*l7GP(EJ+`2^lnk=%l^GBkxhg^%(0X z=A0wEWDX%R#<_{T?3nbrDW@pG4wy`OU6O{$5-l0ShIDMOn8tCPI%>IU=2Bm+CbdtR z@6W9ceIx?;OHO@GQ%zWMZQ#)^y&ZZGHPdv|&o@Po6~f;zy-L}_dKw`SWN;?aqSF=? z4CO2zvHKQj>%VReC^> zWd@m5!>eAQ4DO4d(sKwI*2ilUH{_9=f;D)ldwY)(qU*8%&t1e?Wlv_z( zaEL}=1`cuIC%k^)q+sp{NsI?3Y|3T z8!Q6Cyhl@N(S?dfLw{y`=!UZSe%pp>*6{qcK6Shz||{_3OoO`b0Apnu2RK+utBz=j(xh)X0DY7=C%xeSK^8oK)pFJ7E>4Nhk$0E3 zO8Xnrb`5I)aSbZrwiROj5brAz4$M{lRV`339OlR~9kVfo!#uFv)ss`Mo)!STHx<+6 zgP##F9D4OhHi8TU!Y0v6d$?-bBQtDwkS#;ekZY)3pVi>y5+09gk|S+7Xm?919$gp` zb3y4t4L@mhQ*dCMCy@zxrnEhJk=m#A5%Pe3G^+*w&Lgeh2Z@xH#%Vq9%^{~9J%Xm* zbDtDx?NvAoWJc+E?vfqeF&ELirYS^ZF|Z`&y^&Sv*Rm@8`f#j{s(Jw4A7;OuTeNU9 z#>H}sod{W5GG4yg<<}?;JfdKr7}B|rBb6krEn@A-8|H489-MdpQqr5C=^EgiQF>dPUU{%Sn^ z1HbnbtO>Wwkxoo{Ci+cn*8(B4uJLT7HX_T%7q#Ee26}oa~ z*q)y;mhm?R!OY(H?D;-K1G~)Z84BMcOEFzJ0)+ob2{W0hA$_d^`VnB4ENhWI%AQ4B z;CmSPRR@C!Rtx<4OfYN#s)5%kqOt`)Py$jbV?g8cKlo3K)yZ>n$kSeQ7wAfb_Weop zkETW|9L3a6=x*(i&oY&KR#S?vi8kf`^!G?spuTBGiW2AG3m`ENCDF`77JN%kIJHb7 zK?20C?Yt1BlCi7%ETWs;$OsMRybAJl=niHUNbR!tx68cEDe!3E60^W16wK^A&z_SP z;Wgbm%az4nbfll?UMmJs8W)VWsJv|p&ZAu555P}nz(}$NT>+0w-)r<{c~17OfznmT z946VQ49h_QSaMgvkPI49awW(fk5rddsGTvhe5%1`S#H4cW3QbCil@(LPS_p{%vJK% zkmNX~QBS+NfFU5!)?xpU0s`3n1yT|cmZ5)&hF>QcvK@1SB_J?hbz;)k;ozb47J(p_ zf7cIkOEaE^B;`s;aAQcSsjv|e9Y`68*7Y?UK+bgI>>WHrJppU;(8~#|T2mi>UcLX- z;k)kDNAjrT@#{gpPj8uqzz6E7rXJ-Az~^)o9wu|4hlCA5Tt9~L2*Tb1y51dUV%eX=f7Z^1m6sKg-D}^KA`E0|y zAZ_(xt=arD#d9e9^ikVPwquJh z079Ij1EJr0_~eu7lTWA@x9S}9P`D0RD`DvJPz3Qc@+b7`?89A%MFK$pUgR1&dtQBl zyt$$a{DHJ2#^^E8ga9DdS3o_kMUX}pL@gB9zNKf=)BbC#lVa>hZ)C5H>71M%GOBR3 z`NPybUE8SZ!L6peq2jm&2L{D_&fBoC)zxwl@ zGEKM@PW55GyIqzrFnI~{Gz{0Yf$wx2^fLQe$t3r&_yF=ms)EC=FQ}6d!*cq5p0rK?6z7!Hbrr%iUmsGX4j&TC0<$-8W1@BSK}SC|K(Vy-+DS2RnYK?}hDn z0%V3B8_8Rme~Mw%<{|oqOkuqZ$;eyiwgjj2+pq@;4=nO$(%KNycnW61UF{AOiwm3K zLY=S3CUL`6jU)#HO%1Uo8s? zK?ewgp*3vg(CMlrY^Lhrod_>!szGa!P~KhUcgg-z1!A4F;CD|Wt_jqoVF{(6yl8`N zK3_8G)Tf)b1$KDIgsLaNi3>(K0F$A=t(~cY{|r~K=CxB=5sEaB%ME#a8Ls>c$NW2A zDMaiD|4_4RJ^`lgG-=o!eQB^DQYx_wU4(TqDw zvU4I^7uBm;juSkcAcA+*(%!h_SWWL!fB5j3bSuvM^nM{r9Q@;)ATC-d^iXgUovOa1 zkzV#ZT`pjSxpeA8RE(7ek%?KE1drh3(T)IgnOp_-ymaS)Lq|)n?qHMH=~DZll-%7GCLDLcssT;WmxS{4xokLkK=c4yw8(@eC1c&ONLt6$*r{lC$ zdMQj=vCy8oQNBp@Q9%VI;b6T3Q{`yYd$hUy4owQdo_t!)1|g(1ci66i!fti z7iukSKia@)+dgTLFz2xGmFnW5Tf?AXMmB`XD{hkuYo!H0YOS22zUU%FYD40O#b+?l z;jln&g7aKR{tD}72i1}(VzY!Lf%~#(J^{7^`h>#^)>e0xR$nt35d~tXrS(7?n8GvB zz!qQumTsyBB680>K}Nh8!sx}$*ynsoVxkf~L!x+*REj2(=YU>VY&rKdrrNB^ir%K> zE$@GfEY3d3Af1q^dlFIdB!OH(*<)G<1de6xhnGG~$j}&}Odla_>|l)>H9zzJUO5kH>{qaUvo0OHRp3%!hCAaMMga z+MKSTp2`uV9o@T9P10`#kUueNw2uqLXupb{Ee%P%CJtjqxKE}^f~!T|+vM!EJc-E7 z@w@VH>SLbu>5^hrlstAkHKB7RkDC-x-Jsf%WI&O#kqScoaefSOqRBCO$@;_THWi+? z$waSC9!82VbD&VNK&YNupKtxvg(2YYKw` z@7o-#nDG$ShTqN+AahTT;ipL5@?#Z##rSAjT+g0M&F-D;mwqe^X{OXSEMoZApzOLh zXd2is{)gZe7OgJ%)4g7B$Q-4zV6SEiCjK3io|u115jDAVWk@2R%$|l`pyc4c>NZm8 zWd}5H9JpYcam`l)BTV(I8;boXeM_0n6ls@%?RkpO0)5r~r2U^sfh^g!(oTbM!;&igmJh-qZ)_aU(6MZyyhSnzI zK7bpA)BR`f|4G&Ay9&=KX^{(+{EpK9#n_m14FBc<$8zmfU=iSNb?NT%;G~YP@A3z_ z{sGNz=JQk-@Sf^B#xK#g$F#k*C`0Q+qnh|;| z-F4#7GalfzdjT7`B17;H^ zg)OovpI!YhB%@!Y{0>9UQgm6j(&BrAc4=(VSFy;NOSFM<{e@B0SlX_zOBRr!Zn<_58`crFa+>+Bms+Or z_>k-2zg7RupC<_VY`Z}7;EaR{ZVS&_pa#I>Um=xAHWP}Oc&cFf9&Q!7*0OeBk*8kn zvp^jq)xmtyp;mS(%fGLg10i7R>g1;cymhaRD*&YqZm7cga&YKT?&N8Vox4MS)qE0D zyaQHfTCiC+!>%VIBYL0?K^6G$cj%DR=PIMbEm&zS5Ay%9r`qh2qwuBkm1FDaX69~u z|K5|&mikc;$)&b9(FUKAWIFQkEbFiX3r-l@-UX=uLt#}vAp?Mvvw(%1>?8Kl(EuD2 zI-r8~Zq_q}1a;zRi_Ry+Y6!wQDo%3kR?VibEb=C-* z3J>SE> zJjWG;j9K<%Ek@c&EYLp$tX{%r2gAB(aY5)eh0|-#Y1bKPlUFvZ;?rH)?sg$tNKzyP zM&(AJ2{^m}AyG>z{NU7eq(zZcqr2ANnkl5`EXLbq`$9xX$R_A10^g<6V`2pv$v-3w zJ8BXsduq_GpTn3Ba`d{j8!?KLIDz=p*kNRvH4fx8;~s7-|cYC_RK>eZ$mAWVTXa7;Ge>aE|PweClNUC@4ju!&Ahx5-s1RF55sZHb73-l&}T+Oy1pv!KNpB%eV$ zh@oI(v2TrYxz_dgWR{tTrswP)VUQK`bX%=^iO{ga!2{|BudF~xa0GCk_nW}UtZIxANCleK|@ z-LXLSmS0rwlTFVPanSWN(r#M2CR2$XfWaL*QfDuI=E*f_f|f?Drl}>wXBJ=r1rWId zml>DvqIq7eZVIgL{1VV0P2Fo?*+uN=ahCfv%7_vaHD6G);5;dU18igY^Gqj5=y8)} z1h_r5-3r5dt1IZ@r1hdOG%vlg-n872o7Bl~EH)g0A_SGFyTX8_{Q5@KYUJ=Sr`;)u z9mP7@188vW8KUDK1dr4qQ;3c(Mh?j(kKk+tN~;Wk%_DU;6)bhoHdXL*dcN+j)qYia zR0jm|DrGea`JX9~s62a3<`E-qUszt|u6mYuN)@tij!QMx87F?We`K=RamqCMgB+^6 zcU|`*EYG4DyA_cJo_hjt-{_-?#p$-rj;6}DbQx16fmE|N%pW*^k|CDx#)ZO>=*^bQ=fAjD|v zCtz;S{|Ga0W)nag&T#Gwfbbk=XPebzFA$$T_OC>drw7th%4W7|JVi*K8z=Rcv%L z9m~pX%|dMe6eU)DKymKA{Nyq&ksiTAClYx%eM+wed4?s;n0-YLVY{)$ucV|Ck_}xl ze#CAb`!vsgr|rE)9Q4Z+>+Bc>0OWx@p3XNvfB7AlH9rS#9ENUejtx<|6K8Pf!j=eK z*)@qT_<^62i1cwg+Hd+{aKUs;Reek#X#bP;AQg2Fjmm)f0TuFW=rhn92c1XcZW-$^ zpORGV6K(Z7O?v|?&`mG12&#=GVU3UIa6KD>Q>hO_X7U))i>*V&`S{eM>|q2 zSdQ7mxu5oc)z+Eizo0P~k=+uOrp}hXPYdffa8?i6Cp%n-WAVM}=Tu&CP}Ms8P4%~b zs{^#cp23vNA8NLs0pQAo?N{6+%J(X^W7T=)3LpgtOi*3MjLY$TOBU#8IQnCWc=8)> zYv-nP^rc>NwhsWm&dqyIv8(i?sA=XK;XX$mPQTuHk?|$6XdN0L)~+MP&%9*?U8m5e z6^67A-7q@lUFhg@E1uy`-+!roPr|-gg5H7a7PHL`%E0$7>+eLAff&WW?w${1(e+Ko zOxQM|ONMR$1eKt_QAa6=J-H)>giWB3^D{hUqvB1bz5f{aFrStnl4&Z?MJdPG-d6A| zYWjX8@neVnFV%jta7(IJx;ISfh~Y^e-j)fpdRLmUbXZrN6fdp3FKLzMs!g~0+`SRY zffwer2IMvKM`l<)0F+{}Lv7(sc$_ZKnt?mmLXv2EYrzLN{1WBT5G8yTNP}$<8!VnE z9V-hhG@u#}rvh6(P}yGYQR^jpM5-S*&G!kR*pbiEyT%zJ}PqsUJq-F9QZcnP+t& zk^Xy3O-_2re%T{m$|ulF4UM~tZI6jz-);;XF=zX$MM@G|=9AX9TURdy_cOT?`nj@g zp`~bv+kx_54nu}S9{SekjkUpj9}4^HHmE`X@`fHP+;>MJkYJ?k0Pv2?PEaG%TEk4T z4V`l|#AhjO6S`Rp=g)N(=xd>r_0HnB6h7)BtB%kvS~ccj4M<&x4vksy^rS@gZO1jy zS&9Y{zT|CXQ@0o{v3?+RS`Sc&4osGP$QBKir>);6%ILaH@MNfYp<_Bf3tbsct^U9J z;5e#OqinH7yNv)mFY(4?Jkb=2W(7f-zC&0i%`?qg>g<|)OEw{;Yy)783Xb6aX{rqT zL}t)8nR+;eJ>=Xp5GfTz31N4PX`KDkI-j;jp8Hd8Kk0Nm2|Nq895zY4g$4lr#Mz*b z)4%!nhe}^i+-?GCWbr4wZ#0E;^g(^%twAG7VPRI4l)S7g zcXbsVbPT;OXGd%k1hN+)s;FSY3jj+dHGV(-+{yVZMQ&Dr1tni+J7ze5qpkM(f-bHw zKG4hR2i4OBlm&u$mn6k*VXkm{Tf$-*_zr3{4gMsiITR9sDV3PdhFZn8Ha^SsFh`|O zKp;PS--0q5($p1>(S5ZRlY7x-UhL~f81dnXbLy7T&2>MzBcN9KJgciah87~NS5OMt zmWBVZo#-*gfyIk=yHH$3ceWk^hx%aM<$pa|ohe;zR9YHci^vT1PEMb+=m8!8VnCh0 z0g48x)Hz#R*CKDdMm|b=+>lBm#)S!^)ympTmdQ4KZlTu0v7W*MJHrKH>r|dyi9@T6=dMMiuJ4fPd{aeZMhz-+%5lw z^;w2%M}lh41#&sdp|O-jvdVU=h5=C7tai~Hx*OFcPRIi+N?&HFc-o`HZ}+cVF)U83 zdiw;HIFZ^Ky114I*h`1p$c@fOB8srv{rfj+foTW{wn{hHwPu)i`XLN5fB623WSy7t z8n^`7eMC3rs^|SKDEIeXgC-~RDkK+zZ7WJMj`Rc>W^2qc&3<(=3O~e&iwGex1#3}% zIj?%_OUJAu=lU(NO%^qPhg5Y6a4dqril$2W?dug=G1}s+Fy?HashsY;{F^- z?TLyhdZ@G@z{;u<`A$;A8iS<~5X=9M|H78gV_qc3fC+0Bc!ON(JUvk_S<1HM`Llf* z0;hJhDlz<=;f5JZiVvRw;D9-Z6=NlPkr%7L)TChRFWq^vZfP>`snRDr~ZV>MTi1y+*NNJ1)^d zTLY)H7JCLyZI>R&k>8~| zA-YLWqj_leZGbJi0%SgWM%{-K0*YWaG7Lf6_th%IsN#tU!8-BDKF;gmkk`n!JcBzY zg=pM^@TNz}v88(IIwK=VSG%h@Uff|A)p;MXp*$`d}ht~5?RXBuJYTu%xx*CEFGRKZijs>_O! zNn!%XoFxY>`IBK-W=B>PjU?K=?SZXf_TijASY}8-`=txk^4L;l&0rCA0!?_K@Iu2yrfKEH+bgJHm$o;(rykvD6KEvNt?|*Qh0h#)F z^P&ll?;YHcuJ#7k)lQe^p`~N6W^*?gbJ-=ek<_N+;RbqK`pv#T94B5w54~Ymszn@? z717c?3MJdw4;?+D1_06|U9L=cy>>+p%z+})yfBm?0%%BWpS^Ey@WJR z*%O<9+QbpwqW!S2!aIoVAJ&h$ifr%pRv74387wmw25{PNi|K- zr-U{3c~9XkH%pnl$z|(yfxfJN-D{xp;fs$y1o-u6o3pVzbq;ju*tAJd)K3)7l4*bAFhq)dGfTSnKMzpj7cDqxQL>h|%${_-mAK+i<0AC5ir{g2W z8SiXu%8r247jNg1iBbE~?+S^q(}2$@oeq?`F1}m0+_KS{kadj}yuBZQxHoYp0p+N| zU4ddvrQL=7#Lxv5lM@RXYn`RYq7Kl8N(^-}ZD3hnNK>lK=P6+WU6u&?{NumaiR!Sn z^8i1(Y?cQcMT`?^Rp!Ek5oh|VN6XFfsNMfjg>Oq=M2Mz(+OXIU=`1Ib%C_Z0GESJ$ z|I8l6YOCQ~>xZVd+{v-hd~Hm<|FHeZ;<^bQt$`q>S%PqGkkbR?IYQ9qA3y*2&*}fG z@*5&XAu47CQtk}(f{5{~iblI^*ln{y@Kp$esd^`khgrj6*QT@O#wVFp#wE+&5$Wnj z1x|rhqYR8|o5K>@+-}niB}53mCm%KetPv)L&?>fT`hy42u5zq?$T$H{b~Q{uHAXu(VF(FW`{{2fJ;6b*PUF)yeoh6@n6*Y{ue8a zLAwnX##c20fg^;{6j_&G@d1;H9)O>{9biA6R{xbNY1N^6iqv@Rrxcp#nGy=4EI(|S zuRIn*MHS6AKkNz7dvbw($?{u1AZ>^4OB}`ECRqWIc_guLA&uB=@OA0J4jUM^6S?hQ zv9k;=&Sozqr!AoH6XUONM@|wK_28KEe6z&iyA?6sn4cD&1D|yvR~CP zTUVrlFvY5H8>v2;m1s#EC_yK(CgWBE^3bRNnG5kn- zy|rbz+zcUPmL?sGa1pxL7vY$QJ9d zdjAuToQuCN0L0fkE6T3v!5+HB@MD5q#W)w{;3ohQRj5$?*T3l~vL++~FerzNKHTcS ziJ{kSInD;x1gOLKU<3jGrY?d7thJ#SS$a9!M$L>Hw5|yN`siZMm$PX7oyP}^Pfc?&<$5jHZ5>-lu=oWm<7mL}l*_Nne4q7=}%@B#X)djB;zB!y=u9fZPW zGCL0YEm@N=K_TvYi_-$I0Vu|e%GK9!M4TTG?w{J+<%XLJVD9WJQ(!h{A^&Ev)qjk< z1FQgC%&LQ6+BX8aV$^jjO2t;3#?;oIL))b&Hy|b5E88DqI-Y$bv_{@lw;F1i?h5NX zD_g}dYt#su;?-UsE#J_{qV7VAmo*ojW>8NfJSxFKk^LEa&N z#vM`Nh|1~^4>=~&PjeCx-J%!x5XhRcat=gNYgT|Nu7Rk~PptJli5?MdBJvEF%T1TO zY6^0OudF#cVX`UXtk6s;4$|uWtL-YMIW!HWdGao6{K5q zn6}&)s3k6mH?oyL35LwJ>_b5p9OKNMcxUDBJK4#Gkbt-b6b-S+R2qve8InOAt8*Vs zSM(eP@_F}Q%G#bq0ST^{TRON7-FganmSzsNPR8iiq8(71s`KW2#zvUL&Em+rco-D1 zc91vd(v}wuF&eT$R1Xmwpdp1Q5b^}{dh7;+Coc60GbMIY>j43w?noy~Duu?@fm+sq^Dk*KEh|<)X4$dJ$OtV1KEaN z*XKGt+86b#tzy}{bMfM-2}0c-={Kp9{`f%$n*rp@!fl)rKI$zj8g57*U6*XobZJ^V zVMx5GPC_yxwSk8r_uZ~gW@3BZ9s*}$nlivw=N_47>V~3s)3B@UC=?i-3MeKmY5?z^ z^KzxREN-kFH@J~XNI8e_%wj)#d0qp}a|uMly4k7p#KedVr7NgXfcvI%+3kW-t zij}6?>k|XuVLnHHu-+}t35TEtLl(>I8yymWa@0GS0vmU?oo_=@DxpDZ$Y78n`H~EG zn>j@N8j`}&DMNqSbW5m1PePJj03tQ)V};KSHmVRFL}iGVe64!v;*a$Tifj~;$02fU zBw3WGsy5bA^PH5x#=`qk& zS^8Vj*GPA8p`&IPU5&Zx0&u)oAYDt^t2)DHMIX49pE?3rK=4Zg8MTz5{u^ExglXH= zhD*RIB$pSiduarn&YyIeFT&j~HHjtkYr}{&bV(pVi-tLDT5Y?Ye6hx2Ox8i(AqE3C zdbMkCxl-VBk(Ot56Hj?91#R1ys{n&E)Q3#1X(h~Y>O&86A>NRUiRwD2;Pdgri+yI! zS#QA|Kk4cd`+O884$zJCuJh9eJ`12cx|@CY1p%<2C$!0(eW&_PYSBF|@WWc`ki2^4(i3^&lL(jaVWHqzxS`w>fGE&`3>ulcK)<=y zR`8UaXjQ!k>^JPV@BnZ<)|CU8JtsO6|!r5oM2s(u{!ZdZ-Q)_o(h#n+qNhM!BwYs5R zgd?`gK9}cQ9N7|IdXF!#GcFjncIbp^bx)pI;GvVum`C{3Tvsf+c8O#?5Qk0_mdX## zI|W`L?j^)A;OXf{Gf;hjT%l~??!KXkHV~>G$Q;mv^HZ;<{!Zw;*wbwxVn$#RhuoG* zV{yAE`X19BJOB3Jfud}NHx>S9KnSUu;O(*N%UK0D?tS%&%%UwiM8~jFTcT|T%6Lt| z5t8=p!$1i0%Gfd<{<`|>zy51|UMp$n#_`Dg1qUzqVM;ei?`Pc5zwLzH!_ADt7w?3I z^AjT!27JkRadHTyngawXaI*H8YUCo`lwP@+Q@ZK>kNwxIt%AnS4oz|k*$h;5OXcG z1lUytiyQ4wkFz^SXFw&fCfy#hPc{od_;C5u5eE9}iOt z&n(!Z5QSvY?AA?-YSfC3j>M?BI_1{-1T9C~z(-9&fu!xXJvFy*FeiDf=(QvJa)}WO zWmBqO5VC3rbhQ{W0R`gFI_TMH#U+JC+iVp6RdleW@00IeR3HBp61QT2?@O+d=mM;| z^-U*i!gvwop{lk%mCGKYhULtLA{Q7dW=V|d=qFzotMyxg6{J$yN1sC z>0Y-1mr7o8I*_4^P9=fTrt9}o2m;~@F6H(IDKNF85@4F@)-)82sNPWYz7!!D5P2Fzuz=xLKu#2@Q#<~L(8P#|q^jpvb|0GVFe%wpsd0RiKLWM+h&rcPX z!%Qc&;H&S(W_47IJ-1K8x~+aCfwYxNk>!ho-R;O3CwlH!WOL#$=!UnFce{lN;yc+E zPMJ`_iYU_YGfft*lU28%vo%3p&xh-S0k>Vymeb!MhWd8XF>}RyE1*t2Lk)qQcFBMI z?BlP4^pn2{C6{0N!N%U*v5+X;m#h>^uV5ZtyQxj&Azmzds`Ctlx0%_ z_GYZuE}gIO873G<(1;P4Qy7>R%wYpGQ0j*J67yAfP}pG=BnB!oNZ6P16)}z5k}9@Rn8&k%B!g^|@k~?zSb4LKblZ98 zgl^mFq8#xVZC606eU1X#&o%CAnA}P!D+E)UD_Bt5Lxax*$>|d3uU4(zt@vK8h^If| zfqIb3`GN|rjX}^5O}(o!T9Bs~%mTBLroD7-QcX3FZdznR5#x}7S7&JnbkzkfxLqu@ z+mg_8x+Gc!gaZ;-c(*6!9sbmhA*{&eZuK1Pt{H1li!^LN!Z|AMMG-QiC?O3;DPei?IyDBFMQ_jj@) z;{rv6!?^ig0HS@!77zhX1j5P#XXJ#Il%P`|9opox(L_$u$P5@Km8m@62d zYW8Uf=&P4rNtz(y>CEvi`q;iqakGe$nRbdgSmGL1DX{7El=eH$bxXyms1Rtf_#zIAZ77c6(Y0#OE~$MQ$p2eN%i;Xq2_VUQjg35W z*wr>mKNk99Cx;qKKd%z*r|Fl*A{WR)5^p%M2O1NGt(=EH0N152XK}V<+2$5*-oQ~! z{ozEj-YfY3YM1$p$`2eNPc!?^a5(bCZv%uAGMmjs)pdwK+_e0;rB3lS(EfZ z@Lw|t=Kxl3I=brYl5r1ilEop^#XAniwPRbd3GfqidDC05WNr2JgfsG-Eg-H~FtLfC zxkT{^K(Brexv1IhS)JX-Af~NlDt*8cxcjr-pwH}C%0){^f)I37p7Rd8pwJnm z#PJ4E?dm1*u%y2oUfpO_23`oe!nb-BI~m~9mayc%1fah9__?RVVDYVb`qvH!fH2j9 zt>-c8?x8e#<4uF6MSsgd%EikAoNq;9p9PFjph*Y>J_9lA>0!xWIf<+(B&+t4djVW4 zpYHTC@7E;W;XsE8vYzMq=y3&#B|YH((7lKd=QYElx?^QFR}s)=jZ3yV>aN=@bSeIS z9T`$k$`*y}l*g|^;zWnOjGib167Wf|$77%jT;2e8zzxwPOGG>}EpV%!c$Dj-KfSTE z`uJ6P^-n8xoT2;=j#q!{^Zq(($^fb`T8WV4Lu*TfN~#B>8ujB(Dt(cJX#Md}aGD&R zAkIz_Dw;2_zWb&rK{Cy=TqkIAXlbEEG||Kksd6NHS#9oU4=b@xJ@4Tmkv;|Z4#^$L zn>f0xHSCkEI6oe3A&|~nK>5FdQ=6?^SmQm_h9{v(C=A*Iqzl{6Fq8EFqH+yI(MVt6 zqrJ<$11tC`EEAM?k{*#K4oOfl(DKoIrsUSWJDg~1N>isU9F8E;IuxV9B_^1w)+Xy2 zyN^yh^TB>&`5OJySN+fu=M9wLR+qS;;0#MHHO3xr9BmS@l`;im2|@Tui~lQM^bcAm zqBGwO^}8z1Gr}}w;%M$FaL6L6#|yJpVG-XVcO9Fk#{8NLN$h9@EypW7ugedmNzSCa zALV}a@z?1l6DI_@FzHNUuk9Iciz8LUsX7B9U5-0j8m^FVw!6}Xz7r|3k{Qn(pnFd7 zKuRcFE+8_x2A!o3o)RDjv=Q?D+si!FDLp;E8SM2u2Ive02?AR&kl%=Yg7EohStNP5Zzzf4_SFo20k3LRuw#7$DulnaH!y+H$U4b|0D*6ON3tP6-!zOq|5sa#Sr#MXYKH9>#ClxfA-A&~fx!LnofHE5+))lBFN-+&PEz9q_XF&XG8 z7_1a556Z@4=_3yzaJLhY76X@@4=rlCa%SYo4U$dfYqM4(I^(nUFcYLMq9CThj%jKs zO&PKk+g|4LR3A+n5O_Z;cW&&XUNVH=LMix`Z=pdZZs-z!G}exv(QUFUKZJywY8{K`qAmbqZVtz)&4!U~I_?j&~RD*wT?uYJ81a zkptAJ&QKn7uB`k?uE@N}(-Zl0$9Pw2f1ndjl#}H5(1ktae}=Q8_uLQrY5`&tj$lU@ z2?F;G$zlt6UvFfa8FhW-@7XpG{LZu>W?>2+NmwvyDFQ7r*FWde8o*d=^WY4{5=Fyv z?g=(QR!OFwfYUfC_Lo|XFZuzQNH}&L;DH|PVee61tNH+%(FAIz^7+CFBILWnZLe~4 zX9I|veAMM%e@)8T;J%-+2lA_DBb-rBwftitM(f%9vBl~)WDT4BR%ab7Y+ zc&0kBuXdn$)(aW}({%W@GXamt)6h7GL7db*oJ1;aGJ}z=S#kgl5yi2wg zuIFRQU%bU?(Lcs=DYgGXx&9Zi!Fr`7D7`|Usy@|HJE1xZ-MVb`taxKJE4n94paage z2sEuQ_oYas80Od^uofL1NOi-XN`x5rCuN0z9S%vg{Cs-(t;OQsT{7sw$C_RsBS>#E z-HF2wGxRIx8wD%-H_fI(ha8PS%k<#=1}ui2(Xn8a9}99Vw*08M^+eAl`xIwi%#UOv zdM58BgOM9LdaYMheQ(wHe^veQf5#}ORx=J02Nj-~K^xQJQAsJdTe?>7K3`PYyLW|> z99zh8#Y0$_6}}qH`)Qb<=(?o&(+VT^=89P`R8aitL7utbDDwW+FwgnJIf{19;xYhV z$=EG19!YR`_hYdz~D& z!`)3zDdz#MxS1{jSFTGBh*iWk$&hA=akQI*>jR7=O_V$=tFKXkw&(FQv&-Qa7}Cvw z2CLUKM5KIQ{y=|L-~0>xnQoxncE7RE69C{&ZRB>gUrIj07cp1P z$W7}|=5bx~m<1yDwhCfDyzDH1wUPm`(K%=9!cyTwZ5JZfU{d~+O5+QpD?ZTvta|?i z7TXjVnq?>8DRseg-X4``%~3`lL&CqIH_|ilXQJ|YVhT>>!^w9#2noadj3hNQU}yzo zH&5Ms7PQ40%L=`g_qf^{CV%rnD?!h)>SgPlh(^xbhM~zd@tge2!7$c~W{MHv1N^pn z|7#t{h;eyGo%UGk@{dYSw9dgM73gYxra}_%=6qJQU56G1QH0(S3kUkC4!O#L31R2f ztHKUPYo+ShmIyMq6o0ir;8);2wU?j=xxO7zqccDzr4D^Nzp5-G_{6Vt?_g0Wsf>Sk z|3l@I=+1n)&xgyUx?C*Sw{#{~AQ&`aLF;Mlv9H~5)K;?N!%Exty?PC2BdIM8UG}>; zM}r&aE|z*hEHntK!u%NBiUuaWLy3pbTH)NSmMy3gtmY=ng@ITS$8 z!gkhIO*@~zsrcLn&m2=qUmzRw>9WY}L+aiKO0;>sha8_uq5%AD-3Yz3RfbXa;a+tt zSfNS9#Et zHQ)zoo4vjuRKA1*kK8M_sH~VBXw57$OfxjySf8tKkSB!4-zdTW+H6arAkbV}s>fCw zW9YckP^@c7sdq{cW}Z{;I^Rp~TNR=LV-HovV-Hf-426lgn6l2){8MiH`Nw~)-hbcc zDMLRN_&Zx|a4O3P3S?QKIDVXW^dCeOBS$h7KJ>%6Xm~pG$F9Tzp4k6PHBIk*#8D+| z4|2jH_4nI1B(B$u?j*6SlPV#+0b06TPx-J!IR{2qhrVE^VjnFnmskPs10Q;7U|93b|`IA zNHAli02v}tRxs-fMZQ|?9@ISopdb-zT_C=X3$=Z7OYN%!Uyv(3F*f%B z0Dl0_KY?-b8L;Ehzz2~@#?W{7jG~1Z(yqjzTVrR~0;&to!5~CfVG9v(aC6aRzxUl% z**Q;&RHLdE#;Q86scErD&FFVhGx{Bya{vLv`s{O76NCSmod=;)tZKJox7EW3;9CRZ zF|g?PeZkT>#nD-Fi2>h=wp_4K2)58K_fUVC?mc)Zd9^}1Opo$qZwnUxgD2*iQSRUf z2$o99Pkt3v{vqGwsBPa45IYR*z3K@2&Zn<;lz4ek0orYU=qs16ygbk7-ze)%LuE-B zTT%cZ*ed>@MWS0xIk?bH=_gpkOCxz*;Vg^l?Rdm2Cc#-BV4DgHS8X1C`ysM;mRWl? zbdYo!|44Uyg3`GcBQxCBvu6WmR7i-U^H8cpjOo#B0T#H4*F zptj)zs7A9Npi$b)XM5q-cyJbb0FI4O&Lyw$?ww^Mxp4}gA12V$ct4G~S*Y^?#Bd4RMi-w%i5Gh9p$(%@V z8)jQBQIvkC`rowFs@u-V%wC{RVk)a4`=@poh~0*4JcMxJT5|wy@#j_?cVW8tLZ6<`)V^|8Jveo?iOyU1sct5Z) zG&k3Ib*wJ4t0`o*ezM;}Z*D1jk&3B8C~fSH0j>&x+4;d7RAcZ)sJI9H(~m*aB+lb?R3E)yDAWcF`=@A5|9LI6<~1>*|!kdtXZa zg!o=RMlhJy*y0(~7$$)Ioh382?z0M*$Z3GcEw*;rfpQ20`!!!iKQQ3MLNxGlLfBZ~;R^R*!yFlQ8 zJG@CF5!KgyJJ1v{n|c`?n@SQ+=G`3Pv5~CHcCY+C8C&vUM%Om)Xylu zo0*wZ?m!-`77=qNg|wiSYBKtG z%%Lwk!d7%cTU1uyU7_#5nY>p+5ifSt|ut9kb*1Fxicf zdaS+Qj3!ZQ*>#AdD2cGUe0pdZ_DcZp)Z{|WRwml z2psfEE>yxBA;zA-wl5w5u)V(oBfBa*i%0D-8anuzg!0hrX~L}M*$l~SOpZ7=I+%ag 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