Repository: huggingface/diffusers

Issue:
Make LoRACompatibleConv padding_mode work
**Is your feature request related to a problem? Please describe.**
Due to #4315 ,the forward method is implemented in https://github.com/huggingface/diffusers/blob/50a749e90990932d49556ee54a333278559722f3/src/diffusers/models/lora.py#L354-L365
If you modify the padding mode of LoRACompatibleConv to achieve some other effects, such as padding_mode="circular" to generate a seamless panorama, the existing implementation method will not work.

**Describe the solution you'd like.**
I recommend following the forward implementation of pytorch Conv2d, so that users can modify the padding mode and it will be reflected.https://github.com/pytorch/pytorch/blob/00412e6dfacdec5a8508c841b3ea0846388dc872/torch/nn/modules/conv.py#L452-L457


**Describe alternatives you've considered.**
The existing implementation also calls the function of F.conv2d, so the modification cost is low.



Discussion:
Feel free open a PR :) More than happy to help out. 

Resolving patch:
diff --git a/src/diffusers/models/lora.py b/src/diffusers/models/lora.py
--- a/src/diffusers/models/lora.py
+++ b/src/diffusers/models/lora.py
@@ -361,16 +361,19 @@ def _unfuse_lora(self):
         self.w_down = None
 
     def forward(self, hidden_states: torch.Tensor, scale: float = 1.0) -> torch.Tensor:
+        if self.padding_mode != "zeros":
+            hidden_states = F.pad(hidden_states, self._reversed_padding_repeated_twice, mode=self.padding_mode)
+            padding = (0, 0)
+        else:
+            padding = self.padding
+
+        original_outputs = F.conv2d(
+            hidden_states, self.weight, self.bias, self.stride, padding, self.dilation, self.groups
+        )
+
         if self.lora_layer is None:
-            # make sure to the functional Conv2D function as otherwise torch.compile's graph will break
-            # see: https://github.com/huggingface/diffusers/pull/4315
-            return F.conv2d(
-                hidden_states, self.weight, self.bias, self.stride, self.padding, self.dilation, self.groups
-            )
+            return original_outputs
         else:
-            original_outputs = F.conv2d(
-                hidden_states, self.weight, self.bias, self.stride, self.padding, self.dilation, self.groups
-            )
             return original_outputs + (scale * self.lora_layer(hidden_states))
 
 


Test patch:
diff --git a/tests/lora/test_lora_layers_peft.py b/tests/lora/test_lora_layers_peft.py
--- a/tests/lora/test_lora_layers_peft.py
+++ b/tests/lora/test_lora_layers_peft.py
@@ -1177,6 +1177,24 @@ def test_simple_inference_with_text_unet_lora_unfused_torch_compile(self):
             # Just makes sure it works..
             _ = pipe(**inputs, generator=torch.manual_seed(0)).images
 
+    def test_modify_padding_mode(self):
+        def set_pad_mode(network, mode="circular"):
+            for _, module in network.named_modules():
+                if isinstance(module, torch.nn.Conv2d):
+                    module.padding_mode = mode
+
+        for scheduler_cls in [DDIMScheduler, LCMScheduler]:
+            components, _, _ = self.get_dummy_components(scheduler_cls)
+            pipe = self.pipeline_class(**components)
+            pipe = pipe.to(self.torch_device)
+            pipe.set_progress_bar_config(disable=None)
+            _pad_mode = "circular"
+            set_pad_mode(pipe.vae, _pad_mode)
+            set_pad_mode(pipe.unet, _pad_mode)
+
+            _, _, inputs = self.get_dummy_inputs()
+            _ = pipe(**inputs).images
+
 
 class StableDiffusionLoRATests(PeftLoraLoaderMixinTests, unittest.TestCase):
     pipeline_class = StableDiffusionPipeline