openai / point-e

Point cloud diffusion for 3D model synthesis
MIT License
6.53k stars 760 forks source link

Type Error with MPS #78

Open hyperswine opened 1 year ago

hyperswine commented 1 year ago

Im on an M2 apple system version 12.3.1 and Im getting the following error when I try to run texttopointcloud.ipynb with device = torch.device("mps"). Ive tried changing some of the float64 (mostly in gaussian it seems) to float32 but to no effect. Im guessing its probably one of the dependencies

Output exceeds the [size limit](command:workbench.action.openSettings?%5B%22notebook.output.textLineLimit%22%5D). Open the full output data [in a text editor](command:workbench.action.openLargeOutput?be55e8a7-0d71-42c1-837e-be8f9347d533)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[11], line 6
      4 # Produce a sample from the model.
      5 samples = None
----> 6 for x in tqdm(sampler.sample_batch_progressive(batch_size=1, model_kwargs=dict(texts=[prompt]))):
      7     samples = x

File [~/.pyenv/versions/mambaforge-22.9.0-3/lib/python3.10/site-packages/tqdm/std.py:1178](https://file+.vscode-resource.vscode-cdn.net/Users/jasonqin/Documents/GitHub/point-e/point_e/examples/~/.pyenv/versions/mambaforge-22.9.0-3/lib/python3.10/site-packages/tqdm/std.py:1178), in tqdm.__iter__(self)
   1175 time = self._time
   1177 try:
-> 1178     for obj in iterable:
   1179         yield obj
   1180         # Update and possibly print the progressbar.
   1181         # Note: does not call self.update(1) for speed optimisation.

File [~/.pyenv/versions/mambaforge-22.9.0-3/lib/python3.10/site-packages/point_e/diffusion/sampler.py:163](https://file+.vscode-resource.vscode-cdn.net/Users/jasonqin/Documents/GitHub/point-e/point_e/examples/~/.pyenv/versions/mambaforge-22.9.0-3/lib/python3.10/site-packages/point_e/diffusion/sampler.py:163), in PointCloudSampler.sample_batch_progressive(self, batch_size, model_kwargs)
    155         internal_batch_size *= 2
    156     samples_it = diffusion.p_sample_loop_progressive(
    157         model,
    158         shape=(internal_batch_size, *sample_shape[1:]),
   (...)
    161         clip_denoised=self.clip_denoised,
    162     )
--> 163 for x in samples_it:
...
-> 1016     res = th.from_numpy(arr).to(device=timesteps.device)[timesteps].float()
   1017     while len(res.shape) < len(broadcast_shape):
   1018         res = res[..., None]

TypeError: Cannot convert a MPS Tensor to float64 dtype as the MPS framework doesn't support float64. Please use float32 instead.
objectkuan commented 9 months ago

The issue is np.append() quietly converts the float32 array to float64...

Here's how I managed to run with MPS.

diff --git a/point_e/diffusion/gaussian_diffusion.py b/point_e/diffusion/gaussian_diffusion.py
index 8dc4dc3..15ebfed 100644
--- a/point_e/diffusion/gaussian_diffusion.py
+++ b/point_e/diffusion/gaussian_diffusion.py
@@ -16,7 +16,7 @@ def get_beta_schedule(beta_schedule, *, beta_start, beta_end, num_diffusion_time
     See get_named_beta_schedule() for the new library of schedules.
     """
     if beta_schedule == "linear":
-        betas = np.linspace(beta_start, beta_end, num_diffusion_timesteps, dtype=np.float64)
+        betas = np.linspace(beta_start, beta_end, num_diffusion_timesteps, dtype=np.float32)
     else:
         raise NotImplementedError(beta_schedule)
     assert betas.shape == (num_diffusion_timesteps,)
@@ -68,7 +68,7 @@ def betas_for_alpha_bar(num_diffusion_timesteps, alpha_bar, max_beta=0.999):
         t1 = i / num_diffusion_timesteps
         t2 = (i + 1) / num_diffusion_timesteps
         betas.append(min(1 - alpha_bar(t2) / alpha_bar(t1), max_beta))
-    return np.array(betas)
+    return np.array(betas, dtype=np.float32)

 def space_timesteps(num_timesteps, section_counts):
@@ -159,8 +159,8 @@ class GaussianDiffusion:
         self.channel_scales = channel_scales
         self.channel_biases = channel_biases

-        # Use float64 for accuracy.
-        betas = np.array(betas, dtype=np.float64)
+        # Use float32 for accuracy.
+        betas = np.array(betas, dtype=np.float32)
         self.betas = betas
         assert len(betas.shape) == 1, "betas must be 1-D"
         assert (betas > 0).all() and (betas <= 1).all()
@@ -169,8 +169,8 @@ class GaussianDiffusion:

         alphas = 1.0 - betas
         self.alphas_cumprod = np.cumprod(alphas, axis=0)
-        self.alphas_cumprod_prev = np.append(1.0, self.alphas_cumprod[:-1])
-        self.alphas_cumprod_next = np.append(self.alphas_cumprod[1:], 0.0)
+        self.alphas_cumprod_prev = np.append(np.float32(1.0), self.alphas_cumprod[:-1])
+        self.alphas_cumprod_next = np.append(self.alphas_cumprod[1:], np.float32(0.0))
         assert self.alphas_cumprod_prev.shape == (self.num_timesteps,)

         # calculations for diffusion q(x_t | x_{t-1}) and others
valfonsoardila commented 7 months ago

Hello