[feat] update bucketed weights from distributed (#13824)

Co-authored-by: Stefan He <hebiaobuaa@gmail.com>
This commit is contained in:
ShawnY112358
2025-11-27 07:30:45 +08:00
committed by GitHub
parent 082b54c689
commit 5155016b56
5 changed files with 124 additions and 15 deletions

View File

@@ -466,6 +466,7 @@ class Engine(EngineBase):
shapes: list[list[int]],
group_name: str = "weight_update_group",
flush_cache: bool = True,
load_format: Optional[str] = None,
):
"""Update weights from distributed source."""
obj = UpdateWeightsFromDistributedReqInput(
@@ -474,6 +475,7 @@ class Engine(EngineBase):
shapes=shapes,
group_name=group_name,
flush_cache=flush_cache,
load_format=load_format,
)
return self.loop.run_until_complete(
self.tokenizer_manager.update_weights_from_distributed(obj, None)

View File

@@ -1144,6 +1144,8 @@ class UpdateWeightsFromDistributedReqInput(BaseReq):
abort_all_requests: bool = False
# Optional: Update weight version along with weights
weight_version: Optional[str] = None
# Optional format specification for loading
load_format: Optional[str] = None
@dataclass

View File

@@ -153,7 +153,11 @@ class BaseTpWorker(ABC):
self, recv_req: UpdateWeightsFromDistributedReqInput
):
success, message = self.model_runner.update_weights_from_distributed(
recv_req.names, recv_req.dtypes, recv_req.shapes, recv_req.group_name
recv_req.names,
recv_req.dtypes,
recv_req.shapes,
recv_req.group_name,
recv_req.load_format,
)
return success, message

View File

@@ -1153,7 +1153,14 @@ class ModelRunner:
logger.error(message)
return False, message
def update_weights_from_distributed(self, names, dtypes, shapes, group_name):
def update_weights_from_distributed(
self,
names,
dtypes,
shapes,
group_name,
load_format: Optional[str] = None,
):
"""
Update specific parameter in the model weights online
through `_model_update_group` process group.
@@ -1169,6 +1176,10 @@ class ModelRunner:
"Please call `init_weights_update_group` first."
)
if load_format == "flattened_bucket":
return self._update_bucketed_weights_from_distributed(
names, dtypes, shapes, group_name
)
try:
weights = []
handles = []
@@ -1201,6 +1212,37 @@ class ModelRunner:
logger.error(error_msg)
return False, error_msg
def _update_bucketed_weights_from_distributed(
self, names, dtypes, shapes, group_name
):
try:
named_tensors = []
for name, dtype, shape in zip(names, dtypes, shapes):
target_dtype = (
dtype if isinstance(dtype, torch.dtype) else getattr(torch, dtype)
)
named_tensors.append(
(name, torch.empty(shape, dtype=target_dtype, device=self.device))
)
bucket = FlattenedTensorBucket(named_tensors=named_tensors)
flattened_tensor = bucket.get_flattened_tensor()
torch.distributed.broadcast(
flattened_tensor,
src=0,
group=self._model_update_group[group_name],
)
reconstructed_tensors = bucket.reconstruct_tensors()
self.model.load_weights(reconstructed_tensors)
return True, f"Succeeded to update parameter online."
except Exception as e:
error_msg = (
f"Failed to update parameter online: {e}. "
f"The full weights of the ModelRunner are partially updated. "
f"Please discard the whole weights."
)
logger.error(error_msg)
return False, error_msg
def update_weights_from_tensor(
self,
named_tensors: List[Tuple[str, Union[torch.Tensor, "LocalSerializedTensor"]]],