Spaces:
Running on Zero
Running on Zero
Work around bnb-4bit shape check on ZeroGPU's fake CUDA device
Browse files- app.py +1 -0
- zerogpu_patch.py +29 -0
app.py
CHANGED
|
@@ -5,6 +5,7 @@ import numpy as np
|
|
| 5 |
import spaces
|
| 6 |
import torch
|
| 7 |
|
|
|
|
| 8 |
from diffusers import ModularPipeline
|
| 9 |
from diffusers.modular_pipelines import SequentialPipelineBlocks
|
| 10 |
from diffusers.modular_pipelines.flux2.decoders import Flux2UnpackLatentsStep
|
|
|
|
| 5 |
import spaces
|
| 6 |
import torch
|
| 7 |
|
| 8 |
+
import zerogpu_patch # noqa: F401 — bnb-4bit loading on ZeroGPU, see the module docstring
|
| 9 |
from diffusers import ModularPipeline
|
| 10 |
from diffusers.modular_pipelines import SequentialPipelineBlocks
|
| 11 |
from diffusers.modular_pipelines.flux2.decoders import Flux2UnpackLatentsStep
|
zerogpu_patch.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Workaround for loading a bnb-4bit diffusers model on ZeroGPU.
|
| 2 |
+
#
|
| 3 |
+
# On ZeroGPU the main process has no real GPU: the `spaces` package fakes the CUDA device, and its
|
| 4 |
+
# proxy tensors expose `.shape` as a plain tuple. diffusers' bnb shape check calls
|
| 5 |
+
# `current_param.shape.numel()`, which only exists on `torch.Size`, so loading the quantized
|
| 6 |
+
# transformer crashes with `'tuple' object has no attribute 'numel'`
|
| 7 |
+
# (src/diffusers/quantizers/bitsandbytes/bnb_quantizer.py:206). Everything else in the bnb path works
|
| 8 |
+
# under the ZeroGPU shim — the bnb-4bit text encoder loads fine through transformers, whose
|
| 9 |
+
# equivalent check doesn't assume `torch.Size`.
|
| 10 |
+
#
|
| 11 |
+
# TODO: remove once the duck-typed check (`math.prod(shape)`) lands in diffusers.
|
| 12 |
+
|
| 13 |
+
import math
|
| 14 |
+
|
| 15 |
+
from diffusers.quantizers.bitsandbytes.bnb_quantizer import BnB4BitDiffusersQuantizer
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def check_quantized_param_shape(self, param_name, current_param, loaded_param):
|
| 19 |
+
n = math.prod(current_param.shape)
|
| 20 |
+
inferred_shape = (n,) if "bias" in param_name else ((n + 1) // 2, 1)
|
| 21 |
+
if tuple(loaded_param.shape) != inferred_shape:
|
| 22 |
+
raise ValueError(
|
| 23 |
+
f"Expected the flattened shape of the current param ({param_name}) to be {tuple(loaded_param.shape)} "
|
| 24 |
+
f"but is {inferred_shape}."
|
| 25 |
+
)
|
| 26 |
+
return True
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
BnB4BitDiffusersQuantizer.check_quantized_param_shape = check_quantized_param_shape
|