Skip to content

Commit 6bafea7

Browse files
authored
Merge branch 'main' into integrations/framepack
2 parents 6c86a3d + 0e3f271 commit 6bafea7

7 files changed

Lines changed: 125 additions & 23 deletions

File tree

.github/workflows/nightly_tests.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,55 @@ jobs:
180180
pip install slack_sdk tabulate
181181
python utils/log_reports.py >> $GITHUB_STEP_SUMMARY
182182
183+
run_torch_compile_tests:
184+
name: PyTorch Compile CUDA tests
185+
186+
runs-on:
187+
group: aws-g4dn-2xlarge
188+
189+
container:
190+
image: diffusers/diffusers-pytorch-compile-cuda
191+
options: --gpus 0 --shm-size "16gb" --ipc host
192+
193+
steps:
194+
- name: Checkout diffusers
195+
uses: actions/checkout@v3
196+
with:
197+
fetch-depth: 2
198+
199+
- name: NVIDIA-SMI
200+
run: |
201+
nvidia-smi
202+
- name: Install dependencies
203+
run: |
204+
python -m venv /opt/venv && export PATH="/opt/venv/bin:$PATH"
205+
python -m uv pip install -e [quality,test,training]
206+
- name: Environment
207+
run: |
208+
python utils/print_env.py
209+
- name: Run torch compile tests on GPU
210+
env:
211+
HF_TOKEN: ${{ secrets.DIFFUSERS_HF_HUB_READ_TOKEN }}
212+
RUN_COMPILE: yes
213+
run: |
214+
python -m pytest -n 1 --max-worker-restart=0 --dist=loadfile -s -v -k "compile" --make-reports=tests_torch_compile_cuda tests/
215+
- name: Failure short reports
216+
if: ${{ failure() }}
217+
run: cat reports/tests_torch_compile_cuda_failures_short.txt
218+
219+
- name: Test suite reports artifacts
220+
if: ${{ always() }}
221+
uses: actions/upload-artifact@v4
222+
with:
223+
name: torch_compile_test_reports
224+
path: reports
225+
226+
- name: Generate Report and Notify Channel
227+
if: always()
228+
run: |
229+
pip install slack_sdk tabulate
230+
python utils/log_reports.py >> $GITHUB_STEP_SUMMARY
231+
183232
run_big_gpu_torch_tests:
184233
name: Torch tests on big GPU
185234
strategy:

.github/workflows/release_tests_fast.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ jobs:
335335
- name: Environment
336336
run: |
337337
python utils/print_env.py
338-
- name: Run example tests on GPU
338+
- name: Run torch compile tests on GPU
339339
env:
340340
HF_TOKEN: ${{ secrets.DIFFUSERS_HF_HUB_READ_TOKEN }}
341341
RUN_COMPILE: yes

src/diffusers/utils/testing_utils.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,13 @@ def _is_torch_fp64_available(device):
11861186
"mps": 0,
11871187
"default": 0,
11881188
}
1189+
BACKEND_SYNCHRONIZE = {
1190+
"cuda": torch.cuda.synchronize,
1191+
"xpu": getattr(torch.xpu, "synchronize", None),
1192+
"cpu": None,
1193+
"mps": None,
1194+
"default": None,
1195+
}
11891196

11901197

11911198
# This dispatches a defined function according to the accelerator from the function definitions.
@@ -1208,6 +1215,10 @@ def backend_manual_seed(device: str, seed: int):
12081215
return _device_agnostic_dispatch(device, BACKEND_MANUAL_SEED, seed)
12091216

12101217

1218+
def backend_synchronize(device: str):
1219+
return _device_agnostic_dispatch(device, BACKEND_SYNCHRONIZE)
1220+
1221+
12111222
def backend_empty_cache(device: str):
12121223
return _device_agnostic_dispatch(device, BACKEND_EMPTY_CACHE)
12131224

tests/models/test_modeling_common.py

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@
5959
from diffusers.utils.testing_utils import (
6060
CaptureLogger,
6161
backend_empty_cache,
62+
backend_max_memory_allocated,
63+
backend_reset_peak_memory_stats,
64+
backend_synchronize,
6265
floats_tensor,
6366
get_python_version,
6467
is_torch_compile,
@@ -341,7 +344,7 @@ def test_weight_overwrite(self):
341344

342345
assert model.config.in_channels == 9
343346

344-
@require_torch_gpu
347+
@require_torch_accelerator
345348
def test_keep_modules_in_fp32(self):
346349
r"""
347350
A simple tests to check if the modules under `_keep_in_fp32_modules` are kept in fp32 when we load the model in fp16/bf16
@@ -1480,16 +1483,16 @@ def test_layerwise_casting(storage_dtype, compute_dtype):
14801483
test_layerwise_casting(torch.float8_e5m2, torch.float32)
14811484
test_layerwise_casting(torch.float8_e4m3fn, torch.bfloat16)
14821485

1483-
@require_torch_gpu
1486+
@require_torch_accelerator
14841487
def test_layerwise_casting_memory(self):
14851488
MB_TOLERANCE = 0.2
14861489
LEAST_COMPUTE_CAPABILITY = 8.0
14871490

14881491
def reset_memory_stats():
14891492
gc.collect()
1490-
torch.cuda.synchronize()
1491-
torch.cuda.empty_cache()
1492-
torch.cuda.reset_peak_memory_stats()
1493+
backend_synchronize(torch_device)
1494+
backend_empty_cache(torch_device)
1495+
backend_reset_peak_memory_stats(torch_device)
14931496

14941497
def get_memory_usage(storage_dtype, compute_dtype):
14951498
torch.manual_seed(0)
@@ -1502,7 +1505,7 @@ def get_memory_usage(storage_dtype, compute_dtype):
15021505
reset_memory_stats()
15031506
model(**inputs_dict)
15041507
model_memory_footprint = model.get_memory_footprint()
1505-
peak_inference_memory_allocated_mb = torch.cuda.max_memory_allocated() / 1024**2
1508+
peak_inference_memory_allocated_mb = backend_max_memory_allocated(torch_device) / 1024**2
15061509

15071510
return model_memory_footprint, peak_inference_memory_allocated_mb
15081511

@@ -1512,7 +1515,7 @@ def get_memory_usage(storage_dtype, compute_dtype):
15121515
torch.float8_e4m3fn, torch.bfloat16
15131516
)
15141517

1515-
compute_capability = get_torch_cuda_device_capability()
1518+
compute_capability = get_torch_cuda_device_capability() if torch_device == "cuda" else None
15161519
self.assertTrue(fp8_e4m3_bf16_memory_footprint < fp8_e4m3_fp32_memory_footprint < fp32_memory_footprint)
15171520
# NOTE: the following assertion would fail on our CI (running Tesla T4) due to bf16 using more memory than fp32.
15181521
# On other devices, such as DGX (Ampere) and Audace (Ada), the test passes. So, we conditionally check it.
@@ -1527,7 +1530,7 @@ def get_memory_usage(storage_dtype, compute_dtype):
15271530
)
15281531

15291532
@parameterized.expand([False, True])
1530-
@require_torch_gpu
1533+
@require_torch_accelerator
15311534
def test_group_offloading(self, record_stream):
15321535
init_dict, inputs_dict = self.prepare_init_args_and_inputs_for_common()
15331536
torch.manual_seed(0)
@@ -1714,6 +1717,37 @@ def test_push_to_hub_library_name(self):
17141717
delete_repo(self.repo_id, token=TOKEN)
17151718

17161719

1720+
class TorchCompileTesterMixin:
1721+
def setUp(self):
1722+
# clean up the VRAM before each test
1723+
super().setUp()
1724+
torch._dynamo.reset()
1725+
gc.collect()
1726+
backend_empty_cache(torch_device)
1727+
1728+
def tearDown(self):
1729+
# clean up the VRAM after each test in case of CUDA runtime errors
1730+
super().tearDown()
1731+
torch._dynamo.reset()
1732+
gc.collect()
1733+
backend_empty_cache(torch_device)
1734+
1735+
@require_torch_gpu
1736+
@require_torch_2
1737+
@is_torch_compile
1738+
@slow
1739+
def test_torch_compile_recompilation_and_graph_break(self):
1740+
torch._dynamo.reset()
1741+
init_dict, inputs_dict = self.prepare_init_args_and_inputs_for_common()
1742+
1743+
model = self.model_class(**init_dict).to(torch_device)
1744+
model = torch.compile(model, fullgraph=True)
1745+
1746+
with torch._dynamo.config.patch(error_on_recompile=True), torch.no_grad():
1747+
_ = model(**inputs_dict)
1748+
_ = model(**inputs_dict)
1749+
1750+
17171751
@slow
17181752
@require_torch_2
17191753
@require_torch_accelerator

tests/models/transformers/test_models_transformer_flux.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from diffusers.models.embeddings import ImageProjection
2323
from diffusers.utils.testing_utils import enable_full_determinism, torch_device
2424

25-
from ..test_modeling_common import ModelTesterMixin
25+
from ..test_modeling_common import ModelTesterMixin, TorchCompileTesterMixin
2626

2727

2828
enable_full_determinism()
@@ -78,7 +78,7 @@ def create_flux_ip_adapter_state_dict(model):
7878
return ip_state_dict
7979

8080

81-
class FluxTransformerTests(ModelTesterMixin, unittest.TestCase):
81+
class FluxTransformerTests(ModelTesterMixin, TorchCompileTesterMixin, unittest.TestCase):
8282
model_class = FluxTransformer2DModel
8383
main_input_name = "hidden_states"
8484
# We override the items here because the transformer under consideration is small.

tests/pipelines/test_pipelines_common.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
require_accelerator,
5454
require_hf_hub_version_greater,
5555
require_torch,
56-
require_torch_gpu,
56+
require_torch_accelerator,
5757
require_transformers_version_greater,
5858
skip_mps,
5959
torch_device,
@@ -1111,12 +1111,14 @@ def callback_cfg_params(self) -> frozenset:
11111111
def setUp(self):
11121112
# clean up the VRAM before each test
11131113
super().setUp()
1114+
torch._dynamo.reset()
11141115
gc.collect()
11151116
backend_empty_cache(torch_device)
11161117

11171118
def tearDown(self):
11181119
# clean up the VRAM after each test in case of CUDA runtime errors
11191120
super().tearDown()
1121+
torch._dynamo.reset()
11201122
gc.collect()
11211123
backend_empty_cache(torch_device)
11221124

@@ -2210,7 +2212,7 @@ def test_layerwise_casting_inference(self):
22102212
inputs = self.get_dummy_inputs(torch_device)
22112213
_ = pipe(**inputs)[0]
22122214

2213-
@require_torch_gpu
2215+
@require_torch_accelerator
22142216
def test_group_offloading_inference(self):
22152217
if not self.test_group_offloading:
22162218
return

tests/quantization/quanto/test_quanto.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66
from diffusers.models.attention_processor import Attention
77
from diffusers.utils import is_optimum_quanto_available, is_torch_available
88
from diffusers.utils.testing_utils import (
9+
backend_empty_cache,
10+
backend_reset_peak_memory_stats,
11+
enable_full_determinism,
912
nightly,
1013
numpy_cosine_similarity_distance,
1114
require_accelerate,
12-
require_big_gpu_with_torch_cuda,
15+
require_big_accelerator,
1316
require_torch_cuda_compatibility,
1417
torch_device,
1518
)
@@ -23,9 +26,11 @@
2326

2427
from ..utils import LoRALayer, get_memory_consumption_stat
2528

29+
enable_full_determinism()
30+
2631

2732
@nightly
28-
@require_big_gpu_with_torch_cuda
33+
@require_big_accelerator
2934
@require_accelerate
3035
class QuantoBaseTesterMixin:
3136
model_id = None
@@ -39,13 +44,13 @@ class QuantoBaseTesterMixin:
3944
_test_torch_compile = False
4045

4146
def setUp(self):
42-
torch.cuda.reset_peak_memory_stats()
43-
torch.cuda.empty_cache()
47+
backend_reset_peak_memory_stats(torch_device)
48+
backend_empty_cache(torch_device)
4449
gc.collect()
4550

4651
def tearDown(self):
47-
torch.cuda.reset_peak_memory_stats()
48-
torch.cuda.empty_cache()
52+
backend_reset_peak_memory_stats(torch_device)
53+
backend_empty_cache(torch_device)
4954
gc.collect()
5055

5156
def get_dummy_init_kwargs(self):
@@ -89,7 +94,7 @@ def test_keep_modules_in_fp32(self):
8994
self.model_cls._keep_in_fp32_modules = self.keep_in_fp32_module
9095

9196
model = self.model_cls.from_pretrained(**self.get_dummy_model_init_kwargs())
92-
model.to("cuda")
97+
model.to(torch_device)
9398

9499
for name, module in model.named_modules():
95100
if isinstance(module, torch.nn.Linear):
@@ -107,7 +112,7 @@ def test_modules_to_not_convert(self):
107112
init_kwargs.update({"quantization_config": quantization_config})
108113

109114
model = self.model_cls.from_pretrained(**init_kwargs)
110-
model.to("cuda")
115+
model.to(torch_device)
111116

112117
for name, module in model.named_modules():
113118
if name in self.modules_to_not_convert:
@@ -122,7 +127,8 @@ def test_dtype_assignment(self):
122127

123128
with self.assertRaises(ValueError):
124129
# Tries with a `device` and `dtype`
125-
model.to(device="cuda:0", dtype=torch.float16)
130+
device_0 = f"{torch_device}:0"
131+
model.to(device=device_0, dtype=torch.float16)
126132

127133
with self.assertRaises(ValueError):
128134
# Tries with a cast
@@ -133,7 +139,7 @@ def test_dtype_assignment(self):
133139
model.half()
134140

135141
# This should work
136-
model.to("cuda")
142+
model.to(torch_device)
137143

138144
def test_serialization(self):
139145
model = self.model_cls.from_pretrained(**self.get_dummy_model_init_kwargs())

0 commit comments

Comments
 (0)