Skip to content

Commit b2d9a3d

Browse files
Reduce final model loading memory
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
1 parent dc89f9a commit b2d9a3d

2 files changed

Lines changed: 37 additions & 5 deletions

File tree

src/scancode_required_phrases/training.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,15 +1125,17 @@ def validate_state_structure(expected, actual, expected_name="expected", actual_
11251125
f"missing={missing}, unexpected={unexpected}"
11261126
)
11271127
for name in expected_keys:
1128-
left = expected[name].detach().cpu()
1128+
left = expected[name].detach()
11291129
right = actual[name].detach().cpu()
11301130
if left.shape != right.shape:
11311131
raise ValueError(
11321132
f"Tensor {name!r} shape mismatch: {tuple(left.shape)} != {tuple(right.shape)}"
11331133
)
11341134
if left.dtype != right.dtype:
11351135
raise ValueError(f"Tensor {name!r} dtype mismatch: {left.dtype} != {right.dtype}")
1136-
if not torch.isfinite(left).all() or not torch.isfinite(right).all():
1136+
if left.device.type != "meta" and not torch.isfinite(left.cpu()).all():
1137+
raise ValueError(f"Tensor {name!r} contains non-finite values")
1138+
if not torch.isfinite(right).all():
11371139
raise ValueError(f"Tensor {name!r} contains non-finite values")
11381140

11391141

@@ -1248,7 +1250,11 @@ def _load_local_model(model_dir, offline=True):
12481250
except (OSError, json.JSONDecodeError) as error:
12491251
raise ValueError(f"Cannot read supported artifact configuration: {error}") from error
12501252
local_config = AutoConfig.from_pretrained(str(model_dir), local_files_only=True)
1251-
backbone = AutoModel.from_config(local_config)
1253+
# Construct the large backbone without allocating random parameters. The
1254+
# saved tensors are assigned below, avoiding a second full FP32 model during
1255+
# inference startup on memory-constrained hosts.
1256+
with torch.device("meta"):
1257+
backbone = AutoModel.from_config(local_config)
12521258
tagger_config = SimpleNamespace(**values)
12531259
model = PhraseTagger(tagger_config, backbone=backbone)
12541260
state_path = model_dir / "model.safetensors"
@@ -1261,7 +1267,22 @@ def _load_local_model(model_dir, offline=True):
12611267
"constructed",
12621268
"saved",
12631269
)
1264-
model.load_state_dict(state, strict=True)
1270+
model.load_state_dict(state, strict=True, assign=True)
1271+
for module in model.modules():
1272+
position_ids = getattr(module, "position_ids", None)
1273+
if position_ids is not None and position_ids.device.type == "meta":
1274+
module.register_buffer(
1275+
"position_ids",
1276+
torch.arange(position_ids.shape[-1]).expand(position_ids.shape),
1277+
persistent=False,
1278+
)
1279+
meta_tensors = [
1280+
name
1281+
for name, tensor in (*model.named_parameters(), *model.named_buffers())
1282+
if tensor.device.type == "meta"
1283+
]
1284+
if meta_tensors:
1285+
raise ValueError(f"Final_Model did not materialize tensors: {meta_tensors}")
12651286
validate_state_dicts(
12661287
_canonical_state_dict(state),
12671288
_canonical_state_dict(model.state_dict()),

tests/test_training.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -907,9 +907,19 @@ def test_local_loader_loads_saved_values_after_structural_validation(
907907
str(model_dir / "model.safetensors"),
908908
)
909909

910+
class LocalBackbone(torch.nn.Module):
911+
def __init__(self):
912+
super().__init__()
913+
self.register_buffer(
914+
"position_ids",
915+
torch.arange(4).expand((1, 4)),
916+
persistent=False,
917+
)
918+
910919
class LocalTagger(torch.nn.Module):
911920
def __init__(self, config, backbone=None):
912921
super().__init__()
922+
self.backbone = backbone
913923
self.weight = torch.nn.Parameter(torch.tensor([0.0]))
914924

915925
class LocalTokenizer:
@@ -924,7 +934,7 @@ class LocalTokenizer:
924934
monkeypatch.setattr(
925935
transformers.AutoModel,
926936
"from_config",
927-
lambda config: object(),
937+
lambda config: LocalBackbone(),
928938
)
929939
monkeypatch.setattr(
930940
transformers.AutoTokenizer,
@@ -935,6 +945,7 @@ class LocalTokenizer:
935945
loaded, tokenizer = training._load_local_model(model_dir)
936946

937947
assert loaded.weight.item() == 3.0
948+
assert loaded.backbone.position_ids.device.type == "cpu"
938949
assert tokenizer.is_fast
939950

940951

0 commit comments

Comments
 (0)