Spaces:
Running on L40S
Running on L40S
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | |
| # SPDX-License-Identifier: OpenMDW-1.1 | |
| from pathlib import Path | |
| from typing import Annotated | |
| import pydantic | |
| import requests | |
| import tyro | |
| from cosmos_framework.inference.args import OmniSampleOverrides | |
| from cosmos_framework.inference.common.args import ResolvedPath, SampleOutputs, tyro_cli | |
| from cosmos_framework.utils import log | |
| class Args(pydantic.BaseModel): | |
| output_dir: Annotated[ResolvedPath, tyro.conf.arg(aliases=("-o",))] | |
| """Output directory.""" | |
| input_files: Annotated[list[ResolvedPath], tyro.conf.arg(aliases=("-i",))] | |
| """Path to the inference parameter file(s). | |
| If multiple files are provided, the model will be loaded once and all the samples will be run sequentially. | |
| Accepts glob patterns (e.g. `inputs/*.json`). | |
| """ | |
| overrides: OmniSampleOverrides = pydantic.Field(default_factory=OmniSampleOverrides) | |
| """Overrides for the inference parameters.""" | |
| host: str = "localhost" | |
| """The hostname of the Ray Serve endpoint.""" | |
| port: int = 8000 | |
| """The port of the Ray Serve endpoint.""" | |
| timeout: int = 600 | |
| """The timeout for the request in seconds.""" | |
| def server(self) -> str: | |
| return f"http://{self.host}:{self.port}" | |
| def handle_response(response: requests.Response) -> None: | |
| try: | |
| response.raise_for_status() | |
| except requests.exceptions.HTTPError as e: | |
| try: | |
| detail = response.json().get("detail") | |
| except Exception: | |
| detail = None | |
| if detail: | |
| raise ValueError(f"{detail}") from e | |
| raise e | |
| def submit(args: Args): | |
| args.output_dir.mkdir(parents=True, exist_ok=True) | |
| sample_args_list = OmniSampleOverrides.from_files(args.input_files, overrides=args.overrides) | |
| for i_sample, sample_args in enumerate(sample_args_list): | |
| assert sample_args.name | |
| log.info(f"[{i_sample + 1}/{len(sample_args_list)}] Submitting sample '{sample_args.name}'") | |
| log.debug(f"{sample_args.__class__.__name__}({sample_args})") | |
| sample_dir = args.output_dir / sample_args.name | |
| sample_dir.mkdir(parents=True, exist_ok=True) | |
| sample_args_file = sample_dir / "sample_args.json" | |
| sample_args_file.write_text(sample_args.model_dump_json()) | |
| log.info(f"Saved sample args to '{sample_args_file}'") | |
| response = requests.post( | |
| f"{args.server}/generate", json=sample_args.model_dump(mode="json"), timeout=args.timeout | |
| ) | |
| handle_response(response) | |
| response_dict = response.json() | |
| sample_outputs = SampleOutputs.model_validate(response_dict) | |
| # Download files | |
| def download_file(remote_file: Path) -> Path: | |
| response = requests.get(f"{args.server}/outputs/{remote_file}", timeout=args.timeout) | |
| handle_response(response) | |
| local_file = sample_dir.joinpath(*remote_file.parts[1:]) | |
| local_file.write_bytes(response.content) | |
| return local_file | |
| sample_outputs = sample_outputs.map_files(download_file) | |
| sample_outputs_file = sample_dir / "sample_outputs.json" | |
| sample_outputs_file.write_text(sample_outputs.model_dump_json()) | |
| log.info(f"Saved sample outputs to '{sample_outputs_file}'") | |
| def main(): | |
| args = tyro_cli(Args, description=__doc__, config=(tyro.conf.OmitArgPrefixes,)) | |
| submit(args) | |
| if __name__ == "__main__": | |
| main() | |