Adding _tie_weights() to prediction heads to support low_cpu_mem_usage=True (#29024)
* Adding _tie_weights() to prediction heads to support low_cpu_mem_usage=True * Testing for the non-safe-tensors case, since the default is safe-tensors already * Running fixup/fix-copies * Adding accelerate annotations to tests
This commit is contained in:
@@ -578,6 +578,18 @@ class DeformableDetrModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineT
|
||||
msg=f"Parameter {name} of model {model_class} seems not properly initialized",
|
||||
)
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_checkpoints(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_no_safetensors(self):
|
||||
pass
|
||||
|
||||
def test_two_stage_training(self):
|
||||
model_class = DeformableDetrForObjectDetection
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
|
||||
@@ -528,6 +528,18 @@ class DetaModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin
|
||||
msg=f"Parameter {name} of model {model_class} seems not properly initialized",
|
||||
)
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_checkpoints(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_no_safetensors(self):
|
||||
pass
|
||||
|
||||
# Inspired by tests.test_modeling_common.ModelTesterMixin.test_tied_weights_keys
|
||||
def test_tied_weights_keys(self):
|
||||
for model_class in self.all_model_classes:
|
||||
|
||||
@@ -325,6 +325,18 @@ class EncodecModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase)
|
||||
def test_hidden_states_output(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_checkpoints(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_no_safetensors(self):
|
||||
pass
|
||||
|
||||
def test_determinism(self):
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
|
||||
|
||||
@@ -766,6 +766,18 @@ class LxmertModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase):
|
||||
|
||||
return tf_inputs_dict
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_checkpoints(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_no_safetensors(self):
|
||||
pass
|
||||
|
||||
|
||||
@require_torch
|
||||
class LxmertModelIntegrationTest(unittest.TestCase):
|
||||
|
||||
@@ -372,6 +372,18 @@ class MarianModelTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMix
|
||||
def test_training_gradient_checkpointing_use_reentrant_false(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_checkpoints(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_no_safetensors(self):
|
||||
pass
|
||||
|
||||
|
||||
def assert_tensors_close(a, b, atol=1e-12, prefix=""):
|
||||
"""If tensors have different shapes, different values or a and b are not both tensors, raise a nice Assertion error."""
|
||||
|
||||
@@ -1273,6 +1273,18 @@ class MusicgenTest(ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin,
|
||||
def test_tied_weights_keys(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_checkpoints(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_no_safetensors(self):
|
||||
pass
|
||||
|
||||
# override since changing `output_hidden_states` / `output_attentions` from the top-level model config won't work
|
||||
def test_retain_grad_hidden_states_attentions(self):
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
|
||||
@@ -1258,6 +1258,18 @@ class MusicgenMelodyTest(ModelTesterMixin, GenerationTesterMixin, PipelineTester
|
||||
def test_tied_weights_keys(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_checkpoints(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_no_safetensors(self):
|
||||
pass
|
||||
|
||||
# override since changing `output_hidden_states` / `output_attentions` from the top-level model config won't work
|
||||
# Ignore copy
|
||||
def test_retain_grad_hidden_states_attentions(self):
|
||||
|
||||
@@ -356,6 +356,18 @@ class SEWModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase):
|
||||
def test_model_common_attributes(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_checkpoints(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_no_safetensors(self):
|
||||
pass
|
||||
|
||||
def test_retain_grad_hidden_states_attentions(self):
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
config.output_hidden_states = True
|
||||
|
||||
@@ -460,6 +460,18 @@ class SEWDModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase):
|
||||
def test_feed_forward_chunking(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_checkpoints(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_no_safetensors(self):
|
||||
pass
|
||||
|
||||
@slow
|
||||
def test_model_from_pretrained(self):
|
||||
model = SEWDModel.from_pretrained("asapp/sew-d-tiny-100k")
|
||||
|
||||
@@ -169,6 +169,18 @@ class TimmBackboneModelTest(ModelTesterMixin, BackboneTesterMixin, PipelineTeste
|
||||
def test_save_load(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_checkpoints(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("No support for low_cpu_mem_usage=True.")
|
||||
def test_save_load_low_cpu_mem_usage_no_safetensors(self):
|
||||
pass
|
||||
|
||||
@unittest.skip("model weights aren't tied in TimmBackbone.")
|
||||
def test_tie_model_weights(self):
|
||||
pass
|
||||
|
||||
@@ -437,6 +437,88 @@ class ModelTesterMixin:
|
||||
max_diff = (model_slow_init.state_dict()[key] - model_fast_init.state_dict()[key]).sum().item()
|
||||
self.assertLessEqual(max_diff, 1e-3, msg=f"{key} not identical")
|
||||
|
||||
@slow
|
||||
@require_accelerate
|
||||
@mark.accelerate_tests
|
||||
def test_save_load_low_cpu_mem_usage(self):
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
with tempfile.TemporaryDirectory() as saved_model_path:
|
||||
for model_class in self.all_model_classes:
|
||||
model_to_save = model_class(config)
|
||||
model_to_save.save_pretrained(saved_model_path)
|
||||
|
||||
self._check_save_load_low_cpu_mem_usage(model_class, saved_model_path)
|
||||
|
||||
@slow
|
||||
@require_accelerate
|
||||
@mark.accelerate_tests
|
||||
def test_save_load_low_cpu_mem_usage_checkpoints(self):
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
with tempfile.TemporaryDirectory() as saved_model_path:
|
||||
for model_class in self.all_model_classes:
|
||||
model_to_save = model_class(config)
|
||||
model_to_save.config.save_pretrained(saved_model_path)
|
||||
torch.save(model_to_save.state_dict(), os.path.join(saved_model_path, "pytorch_model.bin"))
|
||||
|
||||
self._check_save_load_low_cpu_mem_usage(model_class, saved_model_path)
|
||||
|
||||
@slow
|
||||
@require_accelerate
|
||||
@mark.accelerate_tests
|
||||
def test_save_load_low_cpu_mem_usage_no_safetensors(self):
|
||||
with tempfile.TemporaryDirectory() as saved_model_path:
|
||||
for model_class in self.all_model_classes:
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
model_to_save = model_class(config)
|
||||
|
||||
model_to_save.save_pretrained(saved_model_path, safe_serialization=False)
|
||||
self._check_save_load_low_cpu_mem_usage(model_class, saved_model_path)
|
||||
|
||||
def _check_save_load_low_cpu_mem_usage(self, model_class, saved_model_path):
|
||||
# Load the low usage and the normal models.
|
||||
model_low_usage, loading_info = model_class.from_pretrained(
|
||||
saved_model_path,
|
||||
low_cpu_mem_usage=True,
|
||||
output_loading_info=True,
|
||||
)
|
||||
model_non_low_usage = model_class.from_pretrained(saved_model_path)
|
||||
|
||||
# Check that there were no missing keys.
|
||||
self.assertEqual(loading_info["missing_keys"], [])
|
||||
|
||||
# The low_cpu_mem_usage=True causes the model params to be initialized with device=meta, and then
|
||||
# subsequently loaded with the correct values and onto the correct device. We check if there are any
|
||||
# remaining params that were not properly loaded.
|
||||
for name, param in model_low_usage.named_parameters():
|
||||
self.assertNotEqual(
|
||||
param.device,
|
||||
torch.device("meta"),
|
||||
"Parameter '" + name + "' has not been properly loaded and has device=meta.",
|
||||
)
|
||||
|
||||
# Tests moving the model to a device other than meta.
|
||||
model_low_usage.to(torch_device)
|
||||
|
||||
# Check that the parameters are equal.
|
||||
for p1, p2 in zip(model_low_usage.parameters(), model_non_low_usage.parameters()):
|
||||
self.assertEquals(p1.data.ne(p2.data).sum(), 0)
|
||||
|
||||
# Check that the state dict keys are equal.
|
||||
self.assertEqual(set(model_low_usage.state_dict().keys()), set(model_non_low_usage.state_dict().keys()))
|
||||
|
||||
# Check that the shared tensors are equal.
|
||||
tensor_ptrs1 = collections.defaultdict(list)
|
||||
for name, tensor in model_low_usage.state_dict().items():
|
||||
tensor_ptrs1[id_tensor_storage(tensor)].append(name)
|
||||
tied_params1 = [names for _, names in tensor_ptrs1.items() if len(names) > 1]
|
||||
|
||||
tensor_ptrs2 = collections.defaultdict(list)
|
||||
for name, tensor in model_non_low_usage.state_dict().items():
|
||||
tensor_ptrs2[id_tensor_storage(tensor)].append(name)
|
||||
tied_params2 = [names for _, names in tensor_ptrs2.items() if len(names) > 1]
|
||||
|
||||
self.assertEqual(tied_params1, tied_params2)
|
||||
|
||||
def test_fast_init_context_manager(self):
|
||||
# 1. Create a dummy class. Should have buffers as well? To make sure we test __init__
|
||||
class MyClass(PreTrainedModel):
|
||||
|
||||
Reference in New Issue
Block a user