vllm-project/vllm · error · FileNotFoundError

Parent directory for FP8 scale save path not found: {save_pa

Error message

Parent directory for FP8 scale save path not found: {save_parent}

What it means

The final check in MultiModalConfig's validator confirms the parent directory of mm_encoder_fp8_scale_save_path exists (Path(...).parent.is_dir()). Because the save step only creates the file, not its directory, a missing parent directory is rejected up front with FileNotFoundError.

Source

Thrown at vllm/config/multimodal.py:345

            )
        if (
            self.mm_encoder_fp8_scale_path is not None
            and self.mm_encoder_fp8_scale_save_path is not None
        ):
            raise ValueError(
                "'mm_encoder_fp8_scale_save_path' cannot be used with "
                "'mm_encoder_fp8_scale_path' (saving requires dynamic scaling)."
            )

        # Validate file paths exist.
        if self.mm_encoder_fp8_scale_path is not None:
            scale_path = Path(self.mm_encoder_fp8_scale_path)
            if not scale_path.is_file():
                raise FileNotFoundError(f"FP8 scale file not found: {scale_path}")
        if self.mm_encoder_fp8_scale_save_path is not None:
            save_parent = Path(self.mm_encoder_fp8_scale_save_path).parent
            if not save_parent.is_dir():
                raise FileNotFoundError(
                    f"Parent directory for FP8 scale save path not found: {save_parent}"
                )
        return self

    @staticmethod
    def fold_mm_processor_device(
        mm_processor_kwargs: dict[str, Any] | None,
        mm_processor_device: MMProcessorDevice | None,
    ) -> dict[str, Any] | None:
        """Fold the `mm_processor_device` convenience flag into the kwargs.

        The flag keeps no state of its own: `mm_processor_kwargs["device"]` is
        the only representation of where the processor runs, so an explicit
        `device` there always wins and `"auto"` stays unresolved for
        `VllmConfig`, which is where the EC role needed to resolve it lives.

        Args:
            mm_processor_kwargs: The kwargs as given, or None.

View on GitHub (pinned to c794754062)

Solutions

  1. Create the parent directory before launching: mkdir -p $(dirname <save-path>).
  2. Point the save path at a directory that already exists (e.g. under /tmp or your mounted output volume).
  3. Add a mkdir -p step to your launch script or container entrypoint.

Example fix

# before
vllm serve model --mm-encoder-attn-dtype fp8 --mm-encoder-fp8-scale-save-path runs/exp1/scales.pt

# after
mkdir -p runs/exp1
vllm serve model --mm-encoder-attn-dtype fp8 --mm-encoder-fp8-scale-save-path runs/exp1/scales.pt
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

def check_save_dir(p: str | None) -> None:
    if p is not None and not Path(p).parent.is_dir():
        Path(p).parent.mkdir(parents=True, exist_ok=True)  # or fail early with a clear message

Prevention

When it happens

Trigger: Passing --mm-encoder-fp8-scale-save-path /tmp/does-not-exist/out.pt when /tmp/does-not-exist does not exist; nested output dirs like runs/exp1/ never created; save path on an unmounted volume.

Common situations: Calibration output directories that the user expected vLLM to create (mkdir -p behavior); Kubernetes pods where the output PVC is mounted at a different path.

Related errors


AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14). Data as JSON: /api/errors/661f3b42bf65d6cd. Report an issue: GitHub.