Ruvadev commited on
Commit
8e38bde
·
verified ·
1 Parent(s): 4934421

Delete raven/foundation_runtime.py

Browse files
Files changed (1) hide show
  1. raven/foundation_runtime.py +0 -179
raven/foundation_runtime.py DELETED
@@ -1,179 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import gc
4
- from pathlib import Path
5
- from typing import Any
6
-
7
- import numpy as np
8
- import torch
9
- import torch.nn as nn
10
-
11
- from .foundation import FoundationEncoder
12
-
13
-
14
- class _FoundationWrapper(nn.Module):
15
- def __init__(self, enc: FoundationEncoder):
16
- super().__init__()
17
- self.enc = enc
18
-
19
- def forward(self, x):
20
- return self.enc(x)
21
-
22
-
23
- class FoundationRuntime:
24
-
25
-
26
- def __init__(self, cfg: dict, encoder: FoundationEncoder):
27
- self.cfg = cfg
28
- self.encoder = encoder
29
- self.backend = "torch"
30
- self.batch_size = max(1, int(cfg.get("torch_batch_size", 8)))
31
- self.runtime_cache = Path(cfg.get("runtime_cache_dir", "cache/foundation_runtime"))
32
- self.runtime_cache.mkdir(parents=True, exist_ok=True)
33
- self._session: Any = None
34
- self._compiled: Any = None
35
-
36
- requested = str(cfg.get("accelerator", "auto")).strip().lower()
37
- order = [requested] if requested not in {"auto", ""} else ["directml", "openvino", "torch"]
38
-
39
- errors = []
40
- for candidate in order:
41
- try:
42
- if candidate == "directml":
43
- self._init_directml()
44
- elif candidate == "openvino":
45
- self._init_openvino()
46
- elif candidate == "torch":
47
- self._init_torch()
48
- else:
49
- raise ValueError(f"Unknown foundation accelerator: {candidate}")
50
- print(f"[foundation-runtime] {self.backend}, batch={self.batch_size}")
51
- break
52
- except Exception as exc:
53
- errors.append(f"{candidate}: {exc}")
54
- self._session = None
55
- self._compiled = None
56
- else:
57
- raise RuntimeError("No foundation runtime could be initialized: " + " | ".join(errors))
58
-
59
- @property
60
- def model_backend(self) -> str:
61
- return self.encoder.backend
62
-
63
- @property
64
- def dim(self) -> int:
65
- return int(self.encoder.dim)
66
-
67
- def _fixed_batch_onnx_path(self, batch: int) -> Path:
68
- safe = self.encoder.backend.replace("/", "_")
69
- return self.runtime_cache / f"{safe}_b{batch}_fixed.onnx"
70
-
71
- def _init_directml(self):
72
- import onnxruntime as ort
73
-
74
- available = ort.get_available_providers()
75
- if "DmlExecutionProvider" not in available:
76
- raise RuntimeError(f"DmlExecutionProvider unavailable; providers={available}")
77
-
78
- batch = max(1, int(self.cfg.get("directml_batch_size", 4)))
79
- onnx_path = self._fixed_batch_onnx_path(batch)
80
- if not onnx_path.exists():
81
- print(f"[foundation-runtime] exporting fixed-batch ONNX once -> {onnx_path}")
82
- wrapper = _FoundationWrapper(self.encoder).eval()
83
- dummy = torch.randn(batch, 3, 224, 224, dtype=torch.float32)
84
- torch.onnx.export(
85
- wrapper,
86
- dummy,
87
- str(onnx_path),
88
- input_names=["image"],
89
- output_names=["embedding"],
90
- opset_version=18,
91
- do_constant_folding=True,
92
- )
93
-
94
- opts = ort.SessionOptions()
95
-
96
- opts.execution_mode = ort.ExecutionMode.ORT_SEQUENTIAL
97
- opts.enable_mem_pattern = False
98
- opts.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
99
- self._session = ort.InferenceSession(
100
- str(onnx_path),
101
- sess_options=opts,
102
- providers=["DmlExecutionProvider", "CPUExecutionProvider"],
103
- )
104
- self.backend = "directml"
105
- self.batch_size = batch
106
-
107
- def _init_openvino(self):
108
- import openvino as ov
109
-
110
- batch = max(1, int(self.cfg.get("openvino_batch_size", 16)))
111
- safe = self.encoder.backend.replace("/", "_")
112
- xml = self.runtime_cache / f"{safe}_b{batch}.xml"
113
-
114
- if not xml.exists():
115
- print(f"[foundation-runtime] converting to OpenVINO IR once -> {xml}")
116
- wrapper = _FoundationWrapper(self.encoder).eval()
117
- dummy = torch.randn(batch, 3, 224, 224, dtype=torch.float32)
118
- ov_model = ov.convert_model(wrapper, example_input=dummy)
119
- ov.save_model(
120
- ov_model,
121
- str(xml),
122
- compress_to_fp16=bool(self.cfg.get("openvino_compress_fp16", True)),
123
- )
124
-
125
- core = ov.Core()
126
- config = {}
127
-
128
- config["PERFORMANCE_HINT"] = "THROUGHPUT"
129
- try:
130
- config["INFERENCE_NUM_THREADS"] = int(self.cfg.get("openvino_threads", 6))
131
- except Exception:
132
- pass
133
- try:
134
- self._compiled = core.compile_model(str(xml), "CPU", config)
135
- except Exception:
136
-
137
- self._compiled = core.compile_model(str(xml), "CPU", {"PERFORMANCE_HINT": "THROUGHPUT"})
138
- self.backend = "openvino"
139
- self.batch_size = batch
140
-
141
- def _init_torch(self):
142
- self.encoder.eval().to("cpu")
143
- self.backend = "torch"
144
- self.batch_size = max(1, int(self.cfg.get("torch_batch_size", 8)))
145
-
146
- def _pad(self, x: np.ndarray | torch.Tensor) -> tuple[np.ndarray, int]:
147
- if isinstance(x, torch.Tensor):
148
- a = x.detach().cpu().numpy().astype(np.float32, copy=False)
149
- else:
150
- a = np.asarray(x, dtype=np.float32)
151
- n = int(a.shape[0])
152
- if n == self.batch_size:
153
- return a, n
154
- if n > self.batch_size:
155
- raise ValueError(f"Runtime batch {n} exceeds configured fixed batch {self.batch_size}")
156
- pad = np.zeros((self.batch_size,) + tuple(a.shape[1:]), dtype=np.float32)
157
- pad[:n] = a
158
- return pad, n
159
-
160
- @torch.inference_mode()
161
- def infer(self, x: torch.Tensor) -> np.ndarray:
162
- if self.backend == "torch":
163
- return self.encoder(x.float()).cpu().numpy().astype(np.float32)
164
-
165
- a, n = self._pad(x)
166
- if self.backend == "directml":
167
- y = self._session.run(["embedding"], {"image": a})[0]
168
- elif self.backend == "openvino":
169
- result = self._compiled([a])
170
- y = result[self._compiled.output(0)]
171
- else:
172
- raise RuntimeError(self.backend)
173
- return np.asarray(y[:n], dtype=np.float32)
174
-
175
- def release_accelerator_memory(self):
176
-
177
- self._session = None
178
- self._compiled = None
179
- gc.collect()