Skip to content

[BUG][stage3] using torch.utils.checkpoint in unet_3d_blocks causes weights size [0] error #4332

Description

@MetaBlues

Describe the bug
I want to use torch.utils.checkpoint() in diffusers.models.unet_3d_blocks to reduce VRAM occupied like this:

class DownBlock3D(DownBlock3D):
    def forward(self, hidden_states, temb=None, num_frames=1):
        output_states = ()

        for resnet, temp_conv in zip(self.resnets, self.temp_convs):
            if self.training and self.gradient_checkpointing:

                def create_custom_forward(module):
                    def custom_forward(*inputs):
                        return module(*inputs)

                    return custom_forward

                if is_torch_version(">=", "1.11.0"):
                    hidden_states = torch.utils.checkpoint.checkpoint(
                        create_custom_forward(resnet), hidden_states, temb, use_reentrant=False
                    )
                    hidden_states = torch.utils.checkpoint.checkpoint(
                        create_custom_forward(temp_conv), hidden_states, num_frames, use_reentrant=False
                    )
                else:
                    hidden_states = torch.utils.checkpoint.checkpoint(
                        create_custom_forward(resnet), hidden_states, temb
                    )
                    hidden_states = torch.utils.checkpoint.checkpoint(
                        create_custom_forward(temp_conv), hidden_states, num_frames
                    )
            else:
                hidden_states = resnet(hidden_states, temb)
                hidden_states = temp_conv(hidden_states, num_frames=num_frames)

            output_states += (hidden_states,)

        if self.downsamplers is not None:
            for downsampler in self.downsamplers:
                hidden_states = downsampler(hidden_states)

            output_states += (hidden_states,)

        return hidden_states, output_states

Yet when I used this new block in unet training I encountered an error said "RuntimeError: output with shape [0] doesn't match the broadcast shape [1280, 1280, 3, 1, 0]", and above error was gone when I set unet.disable_gradient_checkpointing().

To Reproduce
Steps to reproduce the behavior:

  1. Override DownBlock3D.forward() method with torch.utils.checkpoint like above
  2. use stage3 for training UNet3DConditionModel:
with ContextManagers(deepspeed_zero3_init_enabled_context_manager()):
    unet = UNet3DConditionModel.from_pretrained(ckpt_path, subfolder="unet") 
unet._supports_gradient_checkpointing = True
unet.enable_gradient_checkpointing()

deepspeed_zero3_init_enabled_context_manager() is a method inspired by here. I use huggingface.accelerate for deepspeed launch and set zero_init_flag to False, thus I only enable zero.init for unet.from_pretrained().

Expected behavior
Use stage3 for UNet3DConditionModel training with unet.enable_gradient_checkpointing().

ds_report output
Please run ds_report to give us details about your setup.

--------------------------------------------------
DeepSpeed C++/CUDA extension op report
--------------------------------------------------
NOTE: Ops not installed will be just-in-time (JIT) compiled at
      runtime if needed. Op compatibility means that your system
      meet the required dependencies to JIT install the op.
--------------------------------------------------
JIT compiled ops requires ninja
ninja .................. [OKAY]
--------------------------------------------------
op name ................ installed .. compatible
--------------------------------------------------
async_io ............... [NO] ....... [OKAY]
fused_adam ............. [NO] ....... [OKAY]
cpu_adam ............... [NO] ....... [OKAY]
cpu_adagrad ............ [NO] ....... [OKAY]
fused_lamb ............. [NO] ....... [OKAY]
quantizer .............. [NO] ....... [OKAY]
random_ltd ............. [NO] ....... [OKAY]
 [WARNING]  sparse_attn requires a torch version >= 1.5 and < 2.0 but detected 2.0
 [WARNING]  using untested triton version (2.0.0), only 1.0.0 is known to be compatible
sparse_attn ............ [NO] ....... [NO]
spatial_inference ...... [NO] ....... [OKAY]
transformer ............ [NO] ....... [OKAY]
stochastic_transformer . [NO] ....... [OKAY]
transformer_inference .. [NO] ....... [OKAY]
--------------------------------------------------
DeepSpeed general environment info:
torch install path ............... ['/root/miniconda3/envs/base/lib/python3.10/site-packages/torch']
torch version .................... 2.0.1+cu117
deepspeed install path ........... ['/root/miniconda3/envs/base/lib/python3.10/site-packages/deepspeed']
deepspeed info ................... 0.10.3
torch cuda version ............... 11.7
torch hip version ................ None
nvcc version ..................... 11.7
deepspeed wheel compiled w. ...... torch 2.0, cuda 11.7
shared memory (/dev/shm) size .... 251.52 GB

Screenshots
If applicable, add screenshots to help explain your problem.

Traceback (most recent call last):
  File "/unet3d_training/main.py", line 21, in <module>
    eval(cfg.common.mode)(cfg)
  File "/unet3d_training/main.py", line 7, in train
    trainer.train()
  File "/unet3d_training/src/trainers/base.py", line 360, in train
    self.accelerator.backward(loss["all"])
  File "/root/miniconda3/envs/base/lib/python3.10/site-packages/accelerate/accelerator.py", line 1847, in backward
    self.deepspeed_engine_wrapped.backward(loss, **kwargs)
  File "/root/miniconda3/envs/base/lib/python3.10/site-packages/accelerate/utils/deepspeed.py", line 167, in backward
    self.engine.backward(loss, **kwargs)
  File "/root/miniconda3/envs/base/lib/python3.10/site-packages/deepspeed/utils/nvtx.py", line 15, in wrapped_fn
    ret_val = func(*args, **kwargs)
  File "/root/miniconda3/envs/base/lib/python3.10/site-packages/deepspeed/runtime/engine.py", line 1923, in backward
    self.optimizer.backward(loss, retain_graph=retain_graph)
  File "/root/miniconda3/envs/base/lib/python3.10/site-packages/deepspeed/utils/nvtx.py", line 15, in wrapped_fn
    ret_val = func(*args, **kwargs)
  File "/root/miniconda3/envs/base/lib/python3.10/site-packages/deepspeed/runtime/zero/stage3.py", line 2080, in backward
    self.loss_scaler.backward(loss.float(), retain_graph=retain_graph)
  File "/root/miniconda3/envs/base/lib/python3.10/site-packages/deepspeed/runtime/fp16/loss_scaler.py", line 63, in backward
    scaled_loss.backward(retain_graph=retain_graph)
  File "/root/miniconda3/envs/base/lib/python3.10/site-packages/torch/_tensor.py", line 487, in backward
    torch.autograd.backward(
  File "/root/miniconda3/envs/base/lib/python3.10/site-packages/torch/autograd/__init__.py", line 200, in backward
    Variable._execution_engine.run_backward(  # Calls into the C++ engine to run the backward pass
RuntimeError: output with shape [0] doesn't match the broadcast shape [1280, 1280, 3, 1, 0]

System info (please complete the following information):

  • OS: Ubuntu 18.04
  • GPU count and types: 2 nodes with x2 V100s each
  • Python version: 3.10.11
  • diffusers: 0.19.3
  • accelerate: 0.21.0

Launcher context
Accelerate launcher

compute_environment: LOCAL_MACHINE
deepspeed_config:
  deepspeed_config_file: /path_to/zero_stage3_config.json
  deepspeed_multinode_launcher: standard
  zero3_init_flag: false
distributed_type: DEEPSPEED
downcast_bf16: 'no'
machine_rank: 0
main_process_ip: MASTER_IP
main_process_port: MASTER_PORT
main_training_function: main
num_machines: 2
num_processes: 4
rdzv_backend: static
same_network: true
tpu_env: []
tpu_use_cluster: false
tpu_use_sudo: false
use_cpu: false

Deepspeed config:

{
    "fp16": {
        "enabled": true
    },
    "zero_optimization": {
        "stage": 3,
        "overlap_comm": true,
        "reduce_bucket_size": 5e7,
        "contiguous_gradients": true,

        "stage3_prefetch_bucket_size" : 1e8,
        "stage3_max_live_parameters" : 1e9,
        "stage3_max_reuse_distance" : 1e9,
        "stage3_param_persistence_threshold" : 1e6,
        "sub_group_size" : 1e12,
        "ignore_unused_parameters": true,
        "stage3_gather_16bit_weights_on_model_save": true,

        "zero_hpz_partition_size": 2,
        "zero_quantized_weights": true,
        "zero_quantized_gradients": true
    },
    "steps_per_print": 100,
    "train_micro_batch_size_per_gpu": "8",
    "gradient_accumulation_steps": "1",
    "train_batch_size": "auto"
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtraining

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions