greenwam / cosmos_framework /scripts /action_policy_server_utils.py
multimodalart's picture
multimodalart HF Staff
Initial GreenWAM demo
a1833c8 verified
Raw History Blame Contribute Delete
3.56 kB
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: OpenMDW-1.1
"""Shared helpers for the standalone Action policy serving scripts.
Both ``cosmos_framework.scripts.action_policy_server_libero`` (HTTP) and
``cosmos_framework.scripts.action_policy_server_robolab`` (WebSocket) reuse the
helpers defined here:
- single-rank distributed init for FSDP-aware model loading;
- local IP / free-port discovery for log messages and PG bring-up;
- the default output directory shared across both servers;
- the ``OmniSetupArgs`` subclass that disables runtime EMA for frozen configs.
Keeping these in one module avoids ``action_policy_server_robolab`` importing
from ``action_policy_server_libero`` purely to share runtime utilities.
"""
import os
import socket
from pathlib import Path
import torch
from torch import distributed as dist
from cosmos_framework.inference.args import OmniSetupArgs
from cosmos_framework.inference.common.args import ConfigFileType
from cosmos_framework.utils import log
DEFAULT_FALLBACK_OUTPUT_DIR = Path("/tmp/cosmos3_action_server")
def _get_free_local_port() -> int:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(("127.0.0.1", 0))
return int(s.getsockname()[1])
def get_local_ip() -> str:
"""Get the local IP address of this machine."""
try:
# Connect to an external address to determine the local IP
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.connect(("8.8.8.8", 80))
return str(s.getsockname()[0])
except Exception:
return socket.gethostbyname(socket.gethostname())
def maybe_init_distributed() -> None:
"""
Initialize a one-rank process group when launched outside torchrun so FSDP
and distributed utilities have the process-group state they expect.
``init_script()`` already inits the PG when ``WORLD_SIZE>1`` (under
torchrun); this function fills in the single-process case used by the
standalone server.
"""
if not dist.is_available() or dist.is_initialized():
return
world_size_env = os.getenv("WORLD_SIZE")
rank_env = os.getenv("RANK")
local_rank = int(os.getenv("LOCAL_RANK", "0"))
backend = "nccl" if torch.cuda.is_available() else "gloo"
if world_size_env is not None and rank_env is not None:
if torch.cuda.is_available():
torch.cuda.set_device(local_rank)
dist.init_process_group(backend=backend, init_method="env://")
return
if torch.cuda.is_available():
torch.cuda.set_device(0)
port = _get_free_local_port()
dist.init_process_group(backend=backend, init_method=f"tcp://127.0.0.1:{port}", rank=0, world_size=1)
class _ActionPolicyServerSetupArgs(OmniSetupArgs):
"""Server-local setup args that avoid instantiating runtime EMA for frozen configs."""
def load_model_config_dict(self) -> dict:
model_dict = super().load_model_config_dict()
model_dict.setdefault("config", {}).setdefault("ema", {})["enabled"] = False
return model_dict
def disable_runtime_ema_for_frozen_config(setup_args: OmniSetupArgs) -> OmniSetupArgs:
"""Use server-local setup args to instantiate frozen configs without runtime EMA."""
if setup_args.config_file_type == ConfigFileType.MODULE:
return setup_args
log.info("[action-server] disabled runtime EMA for frozen config model load")
return _ActionPolicyServerSetupArgs.model_validate(setup_args.model_dump())