forked from xxz-888/PylaAi-XXZ
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgpu_support.py
More file actions
315 lines (250 loc) · 8.97 KB
/
Copy pathgpu_support.py
File metadata and controls
315 lines (250 loc) · 8.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
import platform
import subprocess
VIRTUAL_GPU_TOKENS = (
"microsoft basic",
"virtual",
"parsec",
"remote",
"iddcx",
"mirror",
"display only",
)
def _normalize_name(name):
return str(name or "").strip()
def _is_virtual_gpu(name):
lower = _normalize_name(name).lower()
return not lower or any(token in lower for token in VIRTUAL_GPU_TOKENS)
def _classify_vendor(name):
lower = _normalize_name(name).lower()
if "nvidia" in lower or "geforce" in lower or "quadro" in lower:
return "nvidia"
if "amd" in lower or "radeon" in lower:
return "amd"
if "intel" in lower or "arc" in lower:
return "intel"
return None
def _wmic_video_controllers():
try:
output = subprocess.check_output(
["wmic", "path", "win32_VideoController", "get", "name"],
encoding="utf-8",
stderr=subprocess.DEVNULL,
)
except Exception:
return []
names = []
for line in output.splitlines():
name = _normalize_name(line)
if not name or name.lower() == "name":
continue
names.append(name)
return names
def detect_graphics_cards():
cards = []
seen = set()
try:
output = subprocess.check_output(
["nvidia-smi", "--query-gpu=name", "--format=csv,noheader,nounits"],
encoding="utf-8",
stderr=subprocess.DEVNULL,
).strip()
for line in output.splitlines():
name = _normalize_name(line)
if name and name not in seen:
cards.append(("nvidia", name))
seen.add(name)
except Exception:
pass
for name in _wmic_video_controllers():
if name in seen or _is_virtual_gpu(name):
continue
vendor = _classify_vendor(name)
if vendor:
cards.append((vendor, name))
seen.add(name)
return cards
def primary_vendor(cards=None):
cards = cards if cards is not None else detect_graphics_cards()
vendors = [vendor for vendor, _name in cards]
for preferred in ("nvidia", "amd", "intel"):
if preferred in vendors:
return preferred
return "cpu"
def primary_gpu_name(cards=None):
cards = cards if cards is not None else detect_graphics_cards()
vendor = primary_vendor(cards)
for card_vendor, name in cards:
if card_vendor == vendor:
return name
return "Generic CPU"
def get_gpu_data():
"""Legacy setup helper: (target_key, version, display_name)."""
cards = detect_graphics_cards()
vendor = primary_vendor(cards)
name = primary_gpu_name(cards)
if vendor == "nvidia":
try:
output = subprocess.check_output(
["nvidia-smi", "--query-gpu=name,compute_cap", "--format=csv,noheader,nounits"],
encoding="utf-8",
stderr=subprocess.DEVNULL,
).strip()
nvidia_name, compute_cap = output.split(", ")
return "nvidia", float(compute_cap), nvidia_name
except Exception:
return "nvidia", 0.0, name
if vendor == "amd":
return "amd_windows", 0.0, name
if vendor == "intel":
return "intel", 0.0, name
return "cpu", 0.0, name
def normalize_preferred_device(preferred_device):
preferred_device = str(preferred_device or "auto").strip().lower()
if preferred_device in ("amd", "dml"):
return "directml"
return preferred_device
def recommended_onnx_variant(vendor=None):
vendor = vendor or primary_vendor()
if vendor == "nvidia":
return "directml"
if vendor in ("amd", "intel"):
return "directml"
return "cpu"
def list_directml_adapters(cards=None):
adapters = []
for index, name in enumerate(_wmic_video_controllers()):
if _is_virtual_gpu(name):
continue
adapters.append({"index": index, "name": name, "vendor": _classify_vendor(name)})
if not adapters:
cards = cards if cards is not None else detect_graphics_cards()
for vendor, name in cards:
adapters.append({"index": len(adapters), "name": name, "vendor": vendor})
return adapters
def recommended_directml_device_id(cards=None):
adapters = list_directml_adapters(cards)
physical = [adapter for adapter in adapters if adapter["vendor"] is not None]
if len(physical) <= 1:
return "auto"
cards = cards if cards is not None else detect_graphics_cards()
vendor = primary_vendor(cards)
if vendor == "amd":
for adapter in adapters:
if adapter["vendor"] == "amd":
return str(adapter["index"])
if vendor == "nvidia":
for adapter in adapters:
if adapter["vendor"] == "nvidia":
return str(adapter["index"])
if vendor == "intel":
for adapter in adapters:
if adapter["vendor"] == "intel":
return str(adapter["index"])
return "auto"
def auto_candidate_variants(cards=None):
return ["directml", "cpu"]
def detect_runtime_variant():
return auto_candidate_variants()[0]
def normalize_runtime_variant(variant):
variant = str(variant or "auto").strip().lower()
if variant == "amd":
return "directml"
if variant == "openvino":
return "openvino"
return variant
def gpu_help_message(context, vendor=None, provider=None):
vendor = vendor or primary_vendor()
provider = provider or ""
if context == "missing_gpu_provider":
if vendor == "amd":
return (
"WARNING: GPU inference was requested but no usable GPU ONNX provider is installed. "
"AMD users run: py -3.11-64 tools\\fix_gpu_runtime.py directml"
)
if vendor == "intel":
return (
"WARNING: GPU inference was requested but no usable GPU ONNX provider is installed. "
"Intel users run: py -3.11-64 tools\\fix_gpu_runtime.py directml"
)
return (
"WARNING: GPU inference was requested but no usable GPU ONNX provider is installed. "
"NVIDIA users run: py -3.11-64 tools\\fix_gpu_runtime.py directml"
)
if context == "session_cpu_fallback":
if vendor == "amd":
return (
"AMD users repair DirectML with: py -3.11-64 tools\\fix_gpu_runtime.py directml"
)
if vendor == "intel":
return (
"Intel users repair DirectML with: py -3.11-64 tools\\fix_gpu_runtime.py directml"
)
return (
"NVIDIA users repair DirectML with: py -3.11-64 tools\\fix_gpu_runtime.py directml"
)
if context == "runtime_provider_failure":
if provider == "CUDAExecutionProvider":
if vendor == "amd":
return (
"CUDA is not supported on AMD Radeon. Use DirectML instead: "
"py -3.11-64 tools\\fix_gpu_runtime.py directml"
)
return (
"CUDA/cuDNN runtime failed. NVIDIA users can repair it with: "
"py -3.11-64 tools\\fix_gpu_runtime.py cuda"
)
if provider == "DmlExecutionProvider" and vendor == "amd":
return (
"DirectML failed on AMD. Reinstall with: "
"py -3.11-64 tools\\fix_gpu_runtime.py directml"
)
return ""
def has_cuda_torch():
try:
import torch
return torch.cuda.is_available()
except Exception:
return False
def has_torch_directml():
try:
import torch_directml # noqa: F401
return True
except Exception:
return False
def resolve_easyocr_gpu():
if has_cuda_torch():
return True
if primary_vendor() == "amd" and has_torch_directml():
return True
return False
def resolve_ultralytics_device(requested_device="0"):
requested = str(requested_device).strip().lower()
if requested not in ("", "0", "auto", "gpu"):
return requested_device
if has_cuda_torch():
return "0"
if has_torch_directml():
try:
import torch_directml
device = torch_directml.device()
return str(device)
except Exception:
pass
return "cpu"
def apply_gpu_config(config, variant, cards=None):
cards = cards if cards is not None else detect_graphics_cards()
variant = normalize_runtime_variant(variant)
config["cpu_or_gpu"] = variant
config["onnx_cpu_threads"] = 4
config["used_threads"] = 4
if variant == "directml":
device_id = recommended_directml_device_id(cards)
if device_id != "auto":
config["directml_device_id"] = device_id
return config
def describe_detected_gpus(cards=None):
cards = cards if cards is not None else detect_graphics_cards()
if not cards:
return "No dedicated GPU detected."
lines = [f"{vendor}: {name}" for vendor, name in cards]
return f"Detected graphics: {', '.join(lines)} (primary={primary_vendor(cards)})"