sgl-project/sglang · error · FileNotFoundError

Action normalization stats not found at {stats_path}.

Error message

Action normalization stats not found at {stats_path}.

What it means

load_action_stats reads a JSON file of per-channel action normalization statistics (mean/std/min/max/q01/q99) required to normalize/denormalize actions. If the path does not exist it raises FileNotFoundError — the stats artifact was not shipped, mounted, or its path misconfigured.

Source

Thrown at python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/cosmos3_action.py:170

            "duration": f"{int(duration_seconds)}s",
            "fps": float(fps),
            "resolution": {"H": int(height), "W": int(width)},
            "aspect_ratio": canonical_aspect_ratio(int(width), int(height)),
        }
        prompts.append(json.dumps(prompt))

    if isinstance(description, (list, tuple)):
        return prompts
    return prompts[0]


def load_action_stats(
    stats_path: str, stats_key: str = "global"
) -> dict[str, torch.Tensor]:
    """Load per-channel action normalization stats from a JSON file."""
    path = Path(stats_path)
    if not path.exists():
        raise FileNotFoundError(
            f"Action normalization stats not found at {stats_path}."
        )
    raw = json.loads(path.read_text())
    if stats_key in raw:
        raw = raw[stats_key]
    return {
        k: torch.as_tensor(np.array(v, dtype=np.float32))
        for k, v in raw.items()
        if k in _STAT_KEYS
    }


def normalize_action(
    action: torch.Tensor, method: str, stats: dict[str, torch.Tensor]
) -> torch.Tensor:
    if method == "quantile":
        q01, q99 = stats["q01"].to(action), stats["q99"].to(action)
        return (2.0 * (action - q01) / (q99 - q01).clamp(min=1e-8) - 1.0).clamp(

View on GitHub (pinned to 0132848349)

Solutions

  1. Verify the stats JSON exists at the configured path (ls the exact path from the error)
  2. Point the config/server arg at the correct location of the model's action stats file
  3. If the file was never generated, create it from your training data (per-channel mean/std/min/max/q01/q99) or export it from the model release
  4. In containers, ensure the volume containing the stats file is mounted

Example fix

# before
--action-stats-path /models/cosmos3/stats.json  # missing
# after
--action-stats-path /models/cosmos3/action_stats.json  # actual filename in checkpoint
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
assert Path(stats_path).is_file(), f"action stats file missing: {stats_path}"

Type guard

def action_stats_available(stats_path: str) -> bool:
    return Path(stats_path).is_file()

Try / catch

try:
    stats = load_action_stats(stats_path)
except FileNotFoundError:
    raise RuntimeError(f"deploy blocked: mount or download action stats at {stats_path}") from None

Prevention

When it happens

Trigger: Any action-conditioned Cosmos3 request: _prepare_action_latents/forward calls load_action_stats(stats_path) with a path (from pipeline config / server args) that doesn't exist on the scheduler's filesystem.

Common situations: Stats JSON not downloaded with the model checkpoint; wrong path after moving the model directory; container missing a volume mount that hosts the stats file; typo in the config key.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/8a2b850b955fb843. Report an issue: GitHub.