Files
ray-project--ray/python/ray/air/_internal/torch_utils.py
T
2026-07-13 13:17:40 +08:00

106 lines
3.5 KiB
Python

from typing import Any, Dict, List, Optional, Union
import torch
from ray.air._internal.device_manager import get_torch_device_manager_by_context
def get_devices() -> List[torch.device]:
"""Gets the correct torch device list configured for this process.
Returns a list of torch accelerator (GPU, HPU, NPU...) devices allocated for
the current worker.
If no accelerators are assigned, then it returns a list with a single CPU device.
"""
return get_torch_device_manager_by_context().get_devices()
def load_torch_model(
saved_model: Union[torch.nn.Module, Dict],
model_definition: Optional[torch.nn.Module] = None,
) -> torch.nn.Module:
"""Loads a PyTorch model from the provided ``saved_model``.
``model_definition`` is only used when ``saved_model`` is
a torch state dict, which will be loaded into ``model_definition``.
Otherwise, ``model_definition`` is discarded.
"""
if isinstance(saved_model, torch.nn.Module):
return saved_model
elif isinstance(saved_model, dict):
if not model_definition:
raise ValueError(
"Attempting to load torch model from a "
"state_dict, but no `model_definition` was "
"provided."
)
model_definition.load_state_dict(saved_model)
return model_definition
else:
raise ValueError(
f"Saved model is of type {type(saved_model)}. "
f"The model saved in the checkpoint is expected "
f"to be of type `torch.nn.Module`, or a model "
f"state dict of type dict."
)
def contains_tensor(obj):
if isinstance(obj, torch.Tensor):
return True
elif isinstance(obj, dict):
for k, v in obj.items():
if contains_tensor(k):
return True
if contains_tensor(v):
return True
elif isinstance(obj, (list, tuple)):
for v in obj:
if contains_tensor(v):
return True
return False
# Not present in torch<=1.7.0
# Adapted from https://github.com/pytorch/pytorch/blob/\
# c18da597e0bb1c1aecc97c77a73fed1849057fa4/torch/nn/modules/utils.py
def consume_prefix_in_state_dict_if_present_not_in_place(
state_dict: Dict[str, Any], prefix: str
) -> Dict[str, Any]:
"""Strip the prefix in state_dict, if any and return a new dict.
Adapted from https://github.com/pytorch/pytorch/blob/\
c18da597e0bb1c1aecc97c77a73fed1849057fa4/torch/nn/modules/utils.py
The original method modified the dict in-place.
Args:
state_dict: a state-dict to be loaded to the model.
prefix: prefix.
Returns:
A new state-dict with the prefix stripped from the keys.
"""
copied = False
for key in state_dict:
if key.startswith(prefix):
newkey = key[len(prefix) :]
if not copied:
# We are doing shallow copies here, so the performance
# impact should be negligible anyway, but this is
# a simple optimization.
state_dict = state_dict.copy()
copied = True
state_dict[newkey] = state_dict.pop(key)
if "_metadata" in state_dict:
state_dict["_metadata"] = state_dict["_metadata"].copy()
metadata = state_dict["_metadata"]
for key in metadata:
if len(key) == 0:
continue
newkey = key[len(prefix) :]
metadata[newkey] = metadata.pop(key)
return state_dict