Repository: huggingface/diffusers

Issue:
Some methods mix the usage of numpy and torch
### Describe the bug

Here are what I find in `resnet.py` (not checking other files at this moment).

Goal: replace this with pure torch methods

- [FirUpsample2D._upsample_2d](https://github.com/huggingface/diffusers/blob/f4781a0b27ffb3ea61ecd25b0b87305e0960304e/src/diffusers/models/resnet.py#L137)
- [FirDownsample2D. _downsample_2d](https://github.com/huggingface/diffusers/blob/f4781a0b27ffb3ea61ecd25b0b87305e0960304e/src/diffusers/models/resnet.py#L222)
- [upsample_2d](https://github.com/huggingface/diffusers/blob/f4781a0b27ffb3ea61ecd25b0b87305e0960304e/src/diffusers/models/resnet.py#L394)
- [downsample_2d](https://github.com/huggingface/diffusers/blob/f4781a0b27ffb3ea61ecd25b0b87305e0960304e/src/diffusers/models/resnet.py#L428)



Discussion:
Thanks a lot for opening this, we should indeed make those pure PyTorch functions

Resolving patch:
diff --git a/src/diffusers/models/resnet.py b/src/diffusers/models/resnet.py
--- a/src/diffusers/models/resnet.py
+++ b/src/diffusers/models/resnet.py
@@ -1,6 +1,5 @@
 from functools import partial
 
-import numpy as np
 import torch
 import torch.nn as nn
 import torch.nn.functional as F
@@ -134,10 +133,10 @@ def _upsample_2d(self, x, weight=None, kernel=None, factor=2, gain=1):
             kernel = [1] * factor
 
         # setup kernel
-        kernel = np.asarray(kernel, dtype=np.float32)
+        kernel = torch.tensor(kernel, dtype=torch.float32)
         if kernel.ndim == 1:
-            kernel = np.outer(kernel, kernel)
-        kernel /= np.sum(kernel)
+            kernel = torch.outer(kernel, kernel)
+        kernel /= torch.sum(kernel)
 
         kernel = kernel * (gain * (factor**2))
 
@@ -219,10 +218,10 @@ def _downsample_2d(self, x, weight=None, kernel=None, factor=2, gain=1):
             kernel = [1] * factor
 
         # setup kernel
-        kernel = np.asarray(kernel, dtype=np.float32)
+        kernel = torch.tensor(kernel, dtype=torch.float32)
         if kernel.ndim == 1:
-            kernel = np.outer(kernel, kernel)
-        kernel /= np.sum(kernel)
+            kernel = torch.outer(kernel, kernel)
+        kernel /= torch.sum(kernel)
 
         kernel = kernel * gain
 
@@ -391,16 +390,14 @@ def upsample_2d(x, kernel=None, factor=2, gain=1):
     if kernel is None:
         kernel = [1] * factor
 
-    kernel = np.asarray(kernel, dtype=np.float32)
+    kernel = torch.tensor(kernel, dtype=torch.float32)
     if kernel.ndim == 1:
-        kernel = np.outer(kernel, kernel)
-    kernel /= np.sum(kernel)
+        kernel = torch.outer(kernel, kernel)
+    kernel /= torch.sum(kernel)
 
     kernel = kernel * (gain * (factor**2))
     p = kernel.shape[0] - factor
-    return upfirdn2d_native(
-        x, torch.tensor(kernel, device=x.device), up=factor, pad=((p + 1) // 2 + factor - 1, p // 2)
-    )
+    return upfirdn2d_native(x, kernel.to(device=x.device), up=factor, pad=((p + 1) // 2 + factor - 1, p // 2))
 
 
 def downsample_2d(x, kernel=None, factor=2, gain=1):
@@ -425,14 +422,14 @@ def downsample_2d(x, kernel=None, factor=2, gain=1):
     if kernel is None:
         kernel = [1] * factor
 
-    kernel = np.asarray(kernel, dtype=np.float32)
+    kernel = torch.tensor(kernel, dtype=torch.float32)
     if kernel.ndim == 1:
-        kernel = np.outer(kernel, kernel)
-    kernel /= np.sum(kernel)
+        kernel = torch.outer(kernel, kernel)
+    kernel /= torch.sum(kernel)
 
     kernel = kernel * gain
     p = kernel.shape[0] - factor
-    return upfirdn2d_native(x, torch.tensor(kernel, device=x.device), down=factor, pad=((p + 1) // 2, p // 2))
+    return upfirdn2d_native(x, kernel.to(device=x.device), down=factor, pad=((p + 1) // 2, p // 2))
 
 
 def upfirdn2d_native(input, kernel, up=1, down=1, pad=(0, 0)):


Test patch: