optm(checkpoint-engine): disable multi-thread loading when update weights (#12374)
Signed-off-by: Yang Kaiyong <yangkaiyong.yky@antgroup.com>
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
# Adapted from https://github.com/vllm-project/vllm/blob/v0.6.4.post1/vllm/model_executor/model_loader/utils.py
|
# Adapted from https://github.com/vllm-project/vllm/blob/v0.6.4.post1/vllm/model_executor/model_loader/utils.py
|
||||||
|
|
||||||
"""Utilities for selecting and loading models."""
|
"""Utilities for selecting and loading models."""
|
||||||
|
import concurrent.futures
|
||||||
import contextlib
|
import contextlib
|
||||||
import logging
|
import logging
|
||||||
from typing import Tuple, Type
|
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Type
|
||||||
|
|
||||||
import torch
|
import torch
|
||||||
import transformers
|
import transformers
|
||||||
@@ -116,3 +117,43 @@ def post_load_weights(model: nn.Module, model_config: ModelConfig):
|
|||||||
model.post_load_weights(is_nextn=True)
|
model.post_load_weights(is_nextn=True)
|
||||||
else:
|
else:
|
||||||
model.post_load_weights()
|
model.post_load_weights()
|
||||||
|
|
||||||
|
|
||||||
|
def should_async_load(weight: torch.Tensor) -> bool:
|
||||||
|
"""Return True if we should load the given weight asynchronously.
|
||||||
|
|
||||||
|
For host (CPU) tensors, using a threadpool can overlap H2D copies
|
||||||
|
and improve throughput. For device tensors, threading often adds overhead
|
||||||
|
(e.g., GIL contention) without benefit, so we do it synchronously.
|
||||||
|
"""
|
||||||
|
device = getattr(weight, "device", None)
|
||||||
|
if device is None:
|
||||||
|
return False
|
||||||
|
return device.type == "cpu"
|
||||||
|
|
||||||
|
|
||||||
|
def maybe_executor_submit(
|
||||||
|
*,
|
||||||
|
executor: concurrent.futures.ThreadPoolExecutor,
|
||||||
|
futures: List[concurrent.futures.Future],
|
||||||
|
use_async: bool,
|
||||||
|
func: Callable[..., Any],
|
||||||
|
func_args: Iterable[Any] = (),
|
||||||
|
func_kwargs: Optional[Dict[str, Any]] = None,
|
||||||
|
) -> None:
|
||||||
|
"""Submit a task to the executor if async loading is enabled.
|
||||||
|
|
||||||
|
Parameters (keyword-only):
|
||||||
|
- executor: ThreadPoolExecutor used to submit background tasks
|
||||||
|
- futures: a list collecting the submitted Future objects
|
||||||
|
- use_async: whether to submit to executor or run inline
|
||||||
|
- func: the callable to run
|
||||||
|
- func_args: positional args for the callable (defaults to empty tuple)
|
||||||
|
- func_kwargs: keyword args for the callable (defaults to empty dict)
|
||||||
|
"""
|
||||||
|
if func_kwargs is None:
|
||||||
|
func_kwargs = {}
|
||||||
|
if use_async:
|
||||||
|
futures.append(executor.submit(func, *func_args, **func_kwargs))
|
||||||
|
else:
|
||||||
|
func(*func_args, **func_kwargs)
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ from sglang.srt.layers.vocab_parallel_embedding import (
|
|||||||
VocabParallelEmbedding,
|
VocabParallelEmbedding,
|
||||||
)
|
)
|
||||||
from sglang.srt.model_executor.forward_batch_info import ForwardBatch, PPProxyTensors
|
from sglang.srt.model_executor.forward_batch_info import ForwardBatch, PPProxyTensors
|
||||||
|
from sglang.srt.model_loader.utils import maybe_executor_submit, should_async_load
|
||||||
from sglang.srt.model_loader.weight_utils import default_weight_loader
|
from sglang.srt.model_loader.weight_utils import default_weight_loader
|
||||||
from sglang.srt.server_args import get_global_server_args
|
from sglang.srt.server_args import get_global_server_args
|
||||||
from sglang.srt.single_batch_overlap import SboFlags
|
from sglang.srt.single_batch_overlap import SboFlags
|
||||||
@@ -3505,6 +3506,7 @@ class DeepseekV2ForCausalLM(nn.Module):
|
|||||||
params_dict = dict(self.named_parameters())
|
params_dict = dict(self.named_parameters())
|
||||||
weight_names = []
|
weight_names = []
|
||||||
for name, loaded_weight in weights:
|
for name, loaded_weight in weights:
|
||||||
|
use_async_loading = should_async_load(loaded_weight)
|
||||||
layer_id = get_layer_id(name)
|
layer_id = get_layer_id(name)
|
||||||
if (
|
if (
|
||||||
layer_id is not None
|
layer_id is not None
|
||||||
@@ -3572,8 +3574,12 @@ class DeepseekV2ForCausalLM(nn.Module):
|
|||||||
continue
|
continue
|
||||||
param = params_dict[name]
|
param = params_dict[name]
|
||||||
weight_loader = param.weight_loader
|
weight_loader = param.weight_loader
|
||||||
futures.append(
|
maybe_executor_submit(
|
||||||
executor.submit(weight_loader, param, loaded_weight, shard_id)
|
executor=executor,
|
||||||
|
futures=futures,
|
||||||
|
use_async=use_async_loading,
|
||||||
|
func=weight_loader,
|
||||||
|
func_args=(param, loaded_weight, shard_id),
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
@@ -3584,15 +3590,20 @@ class DeepseekV2ForCausalLM(nn.Module):
|
|||||||
name = name.replace(weight_name, param_name)
|
name = name.replace(weight_name, param_name)
|
||||||
param = params_dict[name]
|
param = params_dict[name]
|
||||||
weight_loader = param.weight_loader
|
weight_loader = param.weight_loader
|
||||||
futures.append(
|
maybe_executor_submit(
|
||||||
executor.submit(
|
executor=executor,
|
||||||
weight_loader,
|
futures=futures,
|
||||||
|
use_async=use_async_loading,
|
||||||
|
func=weight_loader,
|
||||||
|
func_args=(
|
||||||
param,
|
param,
|
||||||
loaded_weight,
|
loaded_weight,
|
||||||
name,
|
name,
|
||||||
shard_id=shard_id,
|
),
|
||||||
expert_id=expert_id,
|
func_kwargs={
|
||||||
)
|
"shard_id": shard_id,
|
||||||
|
"expert_id": expert_id,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
@@ -3652,8 +3663,12 @@ class DeepseekV2ForCausalLM(nn.Module):
|
|||||||
weight_loader = getattr(
|
weight_loader = getattr(
|
||||||
param, "weight_loader", default_weight_loader
|
param, "weight_loader", default_weight_loader
|
||||||
)
|
)
|
||||||
futures.append(
|
maybe_executor_submit(
|
||||||
executor.submit(weight_loader, param, fused_weight)
|
executor=executor,
|
||||||
|
futures=futures,
|
||||||
|
use_async=use_async_loading,
|
||||||
|
func=weight_loader,
|
||||||
|
func_args=(param, fused_weight),
|
||||||
)
|
)
|
||||||
cached_a_proj.pop(q_a_proj_name)
|
cached_a_proj.pop(q_a_proj_name)
|
||||||
cached_a_proj.pop(kv_a_proj_name)
|
cached_a_proj.pop(kv_a_proj_name)
|
||||||
@@ -3699,8 +3714,13 @@ class DeepseekV2ForCausalLM(nn.Module):
|
|||||||
weight_loader = getattr(
|
weight_loader = getattr(
|
||||||
param, "weight_loader", default_weight_loader
|
param, "weight_loader", default_weight_loader
|
||||||
)
|
)
|
||||||
futures.append(
|
maybe_executor_submit(
|
||||||
executor.submit(weight_loader, param, fused_weight)
|
executor,
|
||||||
|
futures,
|
||||||
|
use_async_loading,
|
||||||
|
weight_loader,
|
||||||
|
param,
|
||||||
|
fused_weight,
|
||||||
)
|
)
|
||||||
cached_wk_and_weights_proj.pop(wk_name)
|
cached_wk_and_weights_proj.pop(wk_name)
|
||||||
cached_wk_and_weights_proj.pop(weights_proj_name)
|
cached_wk_and_weights_proj.pop(weights_proj_name)
|
||||||
@@ -3725,8 +3745,12 @@ class DeepseekV2ForCausalLM(nn.Module):
|
|||||||
weight_loader = getattr(
|
weight_loader = getattr(
|
||||||
param, "weight_loader", default_weight_loader
|
param, "weight_loader", default_weight_loader
|
||||||
)
|
)
|
||||||
futures.append(
|
maybe_executor_submit(
|
||||||
executor.submit(weight_loader, param, loaded_weight)
|
executor=executor,
|
||||||
|
futures=futures,
|
||||||
|
use_async=use_async_loading,
|
||||||
|
func=weight_loader,
|
||||||
|
func_args=(param, loaded_weight),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Wait for all tasks to complete and raise any exceptions.
|
# Wait for all tasks to complete and raise any exceptions.
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ from sglang.srt.layers.vocab_parallel_embedding import (
|
|||||||
VocabParallelEmbedding,
|
VocabParallelEmbedding,
|
||||||
)
|
)
|
||||||
from sglang.srt.model_executor.forward_batch_info import ForwardBatch
|
from sglang.srt.model_executor.forward_batch_info import ForwardBatch
|
||||||
|
from sglang.srt.model_loader.utils import maybe_executor_submit, should_async_load
|
||||||
from sglang.srt.model_loader.weight_utils import default_weight_loader
|
from sglang.srt.model_loader.weight_utils import default_weight_loader
|
||||||
from sglang.srt.models.deepseek_v2 import DeepseekV2AttentionMLA
|
from sglang.srt.models.deepseek_v2 import DeepseekV2AttentionMLA
|
||||||
from sglang.srt.server_args import get_global_server_args
|
from sglang.srt.server_args import get_global_server_args
|
||||||
@@ -854,6 +855,7 @@ class LongcatFlashForCausalLM(nn.Module):
|
|||||||
params_dict = dict(self.named_parameters())
|
params_dict = dict(self.named_parameters())
|
||||||
weight_names = []
|
weight_names = []
|
||||||
for name, loaded_weight in weights:
|
for name, loaded_weight in weights:
|
||||||
|
use_async_loading = should_async_load(loaded_weight)
|
||||||
if "mtp" in name:
|
if "mtp" in name:
|
||||||
continue
|
continue
|
||||||
weight_names.append(name)
|
weight_names.append(name)
|
||||||
@@ -877,8 +879,12 @@ class LongcatFlashForCausalLM(nn.Module):
|
|||||||
continue
|
continue
|
||||||
param = params_dict[name]
|
param = params_dict[name]
|
||||||
weight_loader = param.weight_loader
|
weight_loader = param.weight_loader
|
||||||
futures.append(
|
maybe_executor_submit(
|
||||||
executor.submit(weight_loader, param, loaded_weight, shard_id)
|
executor=executor,
|
||||||
|
futures=futures,
|
||||||
|
use_async=use_async_loading,
|
||||||
|
func=weight_loader,
|
||||||
|
func_args=(param, loaded_weight, shard_id),
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
@@ -889,15 +895,16 @@ class LongcatFlashForCausalLM(nn.Module):
|
|||||||
name = name.replace(weight_name, param_name)
|
name = name.replace(weight_name, param_name)
|
||||||
param = params_dict[name]
|
param = params_dict[name]
|
||||||
weight_loader = param.weight_loader
|
weight_loader = param.weight_loader
|
||||||
futures.append(
|
maybe_executor_submit(
|
||||||
executor.submit(
|
executor=executor,
|
||||||
weight_loader,
|
futures=futures,
|
||||||
param,
|
use_async=use_async_loading,
|
||||||
loaded_weight,
|
func=weight_loader,
|
||||||
name,
|
func_args=(param, loaded_weight, name),
|
||||||
shard_id=shard_id,
|
func_kwargs={
|
||||||
expert_id=expert_id,
|
"shard_id": shard_id,
|
||||||
)
|
"expert_id": expert_id,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
@@ -951,8 +958,12 @@ class LongcatFlashForCausalLM(nn.Module):
|
|||||||
weight_loader = getattr(
|
weight_loader = getattr(
|
||||||
param, "weight_loader", default_weight_loader
|
param, "weight_loader", default_weight_loader
|
||||||
)
|
)
|
||||||
futures.append(
|
maybe_executor_submit(
|
||||||
executor.submit(weight_loader, param, fused_weight)
|
executor=executor,
|
||||||
|
futures=futures,
|
||||||
|
use_async=use_async_loading,
|
||||||
|
func=weight_loader,
|
||||||
|
func_args=(param, fused_weight),
|
||||||
)
|
)
|
||||||
cached_a_proj.pop(q_a_proj_name)
|
cached_a_proj.pop(q_a_proj_name)
|
||||||
cached_a_proj.pop(kv_a_proj_name)
|
cached_a_proj.pop(kv_a_proj_name)
|
||||||
@@ -977,8 +988,12 @@ class LongcatFlashForCausalLM(nn.Module):
|
|||||||
weight_loader = getattr(
|
weight_loader = getattr(
|
||||||
param, "weight_loader", default_weight_loader
|
param, "weight_loader", default_weight_loader
|
||||||
)
|
)
|
||||||
futures.append(
|
maybe_executor_submit(
|
||||||
executor.submit(weight_loader, param, loaded_weight)
|
executor=executor,
|
||||||
|
futures=futures,
|
||||||
|
use_async=use_async_loading,
|
||||||
|
func=weight_loader,
|
||||||
|
func_args=(param, loaded_weight),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Wait for all tasks to complete and raise any exceptions.
|
# Wait for all tasks to complete and raise any exceptions.
|
||||||
|
|||||||
Reference in New Issue
Block a user