main
py 94 lines 3.12 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """FlashInfer autotune cache helpers."""
4
5 import hashlib
6 import os
7 import tempfile
8 from contextlib import suppress
9 from pathlib import Path
10 from typing import TYPE_CHECKING
11
12 import vllm.envs as envs
13
14 if TYPE_CHECKING:
15 from vllm.distributed.parallel_state import GroupCoordinator
16 from vllm.v1.worker.gpu_model_runner import GPUModelRunner
17
18
19 def flashinfer_autotune_cache_hash(runner: "GPUModelRunner") -> str:
20 config_hash = runner.vllm_config.compute_hash(include_version=False)
21 return hashlib.sha256(config_hash.encode()).hexdigest()
22
23
24 def resolve_flashinfer_autotune_file(runner: "GPUModelRunner") -> Path:
25 override_dir = envs.VLLM_FLASHINFER_AUTOTUNE_CACHE_DIR
26 if override_dir:
27 root = Path(override_dir).expanduser()
28 else:
29 from flashinfer.jit import env as flashinfer_jit_env
30
31 flashinfer_workspace = flashinfer_jit_env.FLASHINFER_WORKSPACE_DIR
32 root = (
33 Path(envs.VLLM_CACHE_ROOT)
34 / "flashinfer_autotune_cache"
35 / flashinfer_workspace.parent.name
36 / flashinfer_workspace.name
37 )
38
39 output_dir = root / flashinfer_autotune_cache_hash(runner)
40 output_dir.mkdir(parents=True, exist_ok=True)
41 return output_dir / "autotune_configs.json"
42
43
44 def sync_flashinfer_autotune_cache(
45 runner: "GPUModelRunner",
46 group: "GroupCoordinator",
47 ) -> None:
48 cache: bytes | str | None = None
49 if (
50 group.rank_in_group == 0
51 and runner.vllm_config.kernel_config.enable_flashinfer_autotune
52 ):
53 try:
54 from vllm.platforms import current_platform
55 from vllm.utils.flashinfer import has_flashinfer
56
57 if has_flashinfer() and current_platform.has_device_capability(90):
58 from flashinfer.autotuner import AutoTuner
59
60 with tempfile.TemporaryDirectory() as temp_dir:
61 path = Path(temp_dir) / "autotune_configs.json"
62 AutoTuner.get().save_configs(str(path))
63 cache = path.read_bytes()
64 except Exception as exc:
65 cache = f"{type(exc).__name__}: {exc}"
66
67 cache = group.broadcast_object(cache)
68 if isinstance(cache, str):
69 raise RuntimeError(f"Failed to serialize FlashInfer autotune state: {cache}")
70 if cache is None or group.rank_in_group == 0:
71 return
72
73 from flashinfer.autotuner import AutoTuner
74
75 with tempfile.NamedTemporaryFile() as f:
76 f.write(cache)
77 f.flush()
78 if not AutoTuner.get().load_configs(f.name):
79 raise RuntimeError("FlashInfer autotune cache is incompatible")
80
81
82 def write_flashinfer_autotune_cache(cache_path: Path, contents: bytes) -> None:
83 cache_path.parent.mkdir(parents=True, exist_ok=True)
84 fd, tmp_path = tempfile.mkstemp(
85 dir=cache_path.parent, suffix=".tmp", prefix=f".{cache_path.name}."
86 )
87 try:
88 with os.fdopen(fd, "wb") as f:
89 f.write(contents)
90 os.replace(tmp_path, cache_path)
91 except BaseException:
92 with suppress(OSError):
93 os.unlink(tmp_path)
94 raise