Skip to content

Commit 95c6c8d

Browse files
committed
feat(npu): colocate TMS env and CANN path for Ascend
Add TMS torch mode, training region, colocate-only PYTORCH_NPU_ALLOC_CONF override, CANN PYTHONPATH for Ray workers, and safe NPU empty_cache. Complements IPC weight sync for bridge colocate on 8x910B. Signed-off-by: kaiyuan <kyxiezju@163.com>
1 parent 105a2c3 commit 95c6c8d

8 files changed

Lines changed: 100 additions & 10 deletions

File tree

vime/backends/megatron_utils/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import logging
22

33
import torch
4+
5+
try:
6+
import torch_npu # noqa: F401
7+
except ImportError:
8+
pass
9+
410
from vime.utils.common import is_npu
511

612
if is_npu():

vime/backends/megatron_utils/actor.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,18 @@ def init(
8484
logger.info(f"Set torch_memory_saver.memory_margin_bytes to {x}")
8585
torch_memory_saver.memory_margin_bytes = x
8686

87+
tms_region_ctx = None
88+
if args.offload_train and is_npu():
89+
tms_region_ctx = torch_memory_saver.region(tag="training", enable_cpu_backup=True)
90+
tms_region_ctx.__enter__()
91+
8792
self.model, self.optimizer, self.opt_param_scheduler, loaded_rollout_id = initialize_model_and_optimizer(
8893
args, role
8994
)
9095

96+
if tms_region_ctx is not None:
97+
tms_region_ctx.__exit__(None, None, None)
98+
9199
vpp_size = mpu.get_virtual_pipeline_model_parallel_world_size() or 1
92100
if vpp_size > 1:
93101
from megatron.core.utils import get_model_config
@@ -621,7 +629,7 @@ def update_weights(self) -> None:
621629
if dist.get_rank() == 0:
622630
ray.get(self.rollout_manager.clear_updatable_num_new_engines.remote())
623631

624-
with torch_memory_saver.disable() if self.args.offload_train else nullcontext():
632+
with torch_memory_saver.disable() if (self.args.offload_train and not is_npu()) else nullcontext():
625633
print_memory("before update_weights")
626634
self.weight_updater.update_weights()
627635
print_memory("after update_weights")

vime/backends/vllm_utils/vllm_engine.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
from vime.backends.vllm_utils.arguments import SKIPPED_DESTS, get_vllm_cli_action_table
2626
from vime.ray.ray_actor import RayActor
27-
from vime.utils.common import is_npu
27+
from vime.utils.common import get_cann_python_site_packages, is_npu, prepend_pythonpath
2828
from vime.utils.http_utils import get_host_info
2929

3030
logger = logging.getLogger(__name__)
@@ -361,6 +361,12 @@ def build_vllm_subprocess_env(server_args: dict[str, Any]) -> dict[str, str]:
361361
env.setdefault("NCCL_CUMEM_ENABLE", "0")
362362
if is_npu():
363363
env["ASCEND_RT_VISIBLE_DEVICES"] = server_args["visible_devices"]
364+
env["VLLM_USE_AOT_COMPILE"] = "0"
365+
cann_python_path = get_cann_python_site_packages()
366+
if cann_python_path is not None:
367+
prepend_pythonpath(env, cann_python_path)
368+
if getattr(args, "colocate", False):
369+
env.pop("PYTORCH_NPU_ALLOC_CONF", None)
364370
else:
365371
env["CUDA_VISIBLE_DEVICES"] = server_args["visible_devices"]
366372
env.setdefault("VLLM_SERVER_DEV_MODE", "1")

vime/ray/actor_group.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from ray.util.scheduling_strategies import PlacementGroupSchedulingStrategy
66

77
from vime.ray.utils import NOSET_VISIBLE_DEVICES_ENV_VARS_LIST
8-
from vime.utils.common import is_npu
8+
from vime.utils.common import get_cann_python_site_packages, is_npu, prepend_pythonpath
99

1010

1111
class RayTrainGroup:
@@ -82,6 +82,16 @@ def _allocate_gpus_for_actor(self, pg, num_gpus_per_actor):
8282
env_vars["TMS_INIT_ENABLE"] = "1"
8383
env_vars["TMS_INIT_ENABLE_CPU_BACKUP"] = "1"
8484

85+
if is_npu():
86+
env_vars["TMS_HOOK_MODE"] = "torch"
87+
env_vars["TMS_REGION_TAG"] = "training"
88+
env_vars["TMS_ENABLE_CPU_BACKUP"] = "1"
89+
if self.args.colocate:
90+
env_vars.pop("PYTORCH_NPU_ALLOC_CONF", None)
91+
cann_python_path = get_cann_python_site_packages()
92+
if cann_python_path is not None:
93+
prepend_pythonpath(env_vars, cann_python_path)
94+
8595
# We cannot do routing replay for critic.
8696
if self.args.use_routing_replay and self.role == "actor":
8797
env_vars["ENABLE_ROUTING_REPLAY"] = "1"

vime/ray/placement_group.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,26 @@
1818
@ray.remote
1919
class InfoActor:
2020
def get_ip_and_gpu_id(self):
21-
if is_npu():
22-
return ray.util.get_node_ip_address(), ray.get_runtime_context().get_accelerator_ids()["NPU"][0]
23-
else:
24-
return ray.util.get_node_ip_address(), ray.get_gpu_ids()[0]
21+
try:
22+
import torch_npu # noqa: F401
23+
24+
has_npu = True
25+
except ImportError:
26+
has_npu = False
27+
28+
if has_npu or is_npu():
29+
npu_ids = ray.get_runtime_context().get_accelerator_ids().get("NPU", [])
30+
if npu_ids:
31+
return ray.util.get_node_ip_address(), npu_ids[0]
32+
33+
gpu_ids = ray.get_gpu_ids()
34+
if gpu_ids:
35+
return ray.util.get_node_ip_address(), gpu_ids[0]
36+
37+
raise RuntimeError(
38+
"No GPU/NPU IDs found. "
39+
f"Accelerator IDs: {ray.get_runtime_context().get_accelerator_ids()}, GPU IDs: {gpu_ids}"
40+
)
2541

2642

2743
def sort_key(x):

vime/ray/rollout.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
GPU_MEMORY_TYPE_CUDA_GRAPH = "cuda_graph"
2222
from vime.rollout.base_types import call_rollout_fn
2323
from vime.utils import logging_utils
24-
from vime.utils.common import is_npu
24+
from vime.utils.common import get_cann_python_site_packages, is_npu, prepend_pythonpath
2525
from vime.utils.dp_schedule import build_dp_schedule
2626
from vime.utils.health_monitor import RolloutHealthMonitor
2727
from vime.utils.http_utils import _wrap_ipv6, find_available_port, get_host_info, init_http_client
@@ -126,6 +126,13 @@ def start_engines(self, port_cursors: dict[int, int] | None = None) -> tuple[lis
126126
)
127127

128128
env_vars = {name: "1" for name in NOSET_VISIBLE_DEVICES_ENV_VARS_LIST}
129+
if is_npu():
130+
cann_python_path = get_cann_python_site_packages()
131+
if cann_python_path is not None:
132+
prepend_pythonpath(env_vars, cann_python_path)
133+
if self.args.colocate:
134+
env_vars["PYTORCH_NPU_ALLOC_CONF"] = ""
135+
env_vars["VLLM_USE_AOT_COMPILE"] = "0"
129136
rollout_engine = RolloutRayActor.options(
130137
num_cpus=num_cpus,
131138
scheduling_strategy=scheduling_strategy,

vime/utils/common.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,37 @@
1+
import os
2+
13
import torch
24

35

6+
def get_cann_python_site_packages() -> str | None:
7+
"""Return CANN Python site-packages if ``acl`` is importable from there."""
8+
candidates: list[str] = []
9+
for env_key in ("ASCEND_TOOLKIT_HOME", "ASCEND_HOME_PATH"):
10+
base = os.environ.get(env_key)
11+
if not base:
12+
continue
13+
candidates.extend(
14+
[
15+
os.path.join(base, "python", "site-packages"),
16+
os.path.normpath(os.path.join(base, "..", "python", "site-packages")),
17+
]
18+
)
19+
candidates.append("/usr/local/Ascend/ascend-toolkit/latest/python/site-packages")
20+
21+
for path in candidates:
22+
if os.path.isdir(os.path.join(path, "acl")):
23+
return path
24+
return None
25+
26+
27+
def prepend_pythonpath(env: dict[str, str], *paths: str) -> None:
28+
existing = env.get("PYTHONPATH", os.environ.get("PYTHONPATH", ""))
29+
existing_parts = {part for part in existing.split(os.pathsep) if part}
30+
prefix_parts = [path for path in paths if path and path not in existing_parts]
31+
if prefix_parts:
32+
env["PYTHONPATH"] = os.pathsep.join([*prefix_parts, existing] if existing else prefix_parts)
33+
34+
435
def is_npu() -> bool:
536
if not hasattr(torch, "npu"):
637
return False

vime/utils/memory_utils.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,16 @@ def clear_memory(clear_host_memory: bool = False):
1717
gc.collect()
1818
torch.cuda.empty_cache()
1919
if is_npu():
20-
torch.npu.empty_cache()
20+
try:
21+
torch.npu.empty_cache()
22+
except RuntimeError:
23+
pass
2124
if clear_host_memory:
2225
if is_npu():
23-
torch.npu.empty_cache()
26+
try:
27+
torch.npu.empty_cache()
28+
except RuntimeError:
29+
pass
2430
else:
2531
torch._C._host_emptyCache()
2632

0 commit comments

Comments
 (0)