lumen-resources 0.2.2__py3-none-any.whl → 0.3.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lumen_resources/__init__.py +7 -10
- lumen_resources/downloader.py +201 -103
- lumen_resources/lumen_config.py +115 -351
- lumen_resources/lumen_config_validator.py +1 -1
- lumen_resources/model_info.py +41 -173
- lumen_resources/result_schemas/__init__.py +4 -7
- lumen_resources/result_schemas/embedding_v1.py +1 -1
- lumen_resources/result_schemas/face_v1.py +1 -1
- lumen_resources/result_schemas/labels_v1.py +1 -1
- lumen_resources/result_schemas/ocr_v1.py +54 -0
- lumen_resources/result_schemas/text_generation_v1.py +89 -0
- lumen_resources/schemas/config-schema.yaml +4 -0
- lumen_resources/schemas/model_info-schema.json +5 -1
- lumen_resources/schemas/result_schemas/ocr_v1.json +55 -0
- lumen_resources/schemas/result_schemas/text_generation_v1.json +94 -0
- {lumen_resources-0.2.2.dist-info → lumen_resources-0.3.2.dist-info}/METADATA +1 -1
- lumen_resources-0.3.2.dist-info/RECORD +28 -0
- lumen_resources-0.2.2.dist-info/RECORD +0 -24
- {lumen_resources-0.2.2.dist-info → lumen_resources-0.3.2.dist-info}/WHEEL +0 -0
- {lumen_resources-0.2.2.dist-info → lumen_resources-0.3.2.dist-info}/entry_points.txt +0 -0
- {lumen_resources-0.2.2.dist-info → lumen_resources-0.3.2.dist-info}/top_level.txt +0 -0
lumen_resources/__init__.py
CHANGED
|
@@ -38,25 +38,20 @@ The package follows a layered architecture:
|
|
|
38
38
|
- CLI layer: User-friendly command-line interface
|
|
39
39
|
"""
|
|
40
40
|
|
|
41
|
-
from .lumen_config import LumenConfig, Runtime, Region
|
|
42
41
|
from .downloader import Downloader, DownloadResult
|
|
43
42
|
from .exceptions import (
|
|
44
|
-
ResourceError,
|
|
45
43
|
ConfigError,
|
|
46
44
|
DownloadError,
|
|
45
|
+
ModelInfoError,
|
|
47
46
|
PlatformUnavailableError,
|
|
47
|
+
ResourceError,
|
|
48
48
|
ValidationError,
|
|
49
|
-
ModelInfoError,
|
|
50
49
|
)
|
|
50
|
+
from .lumen_config import LumenConfig, Region, Runtime
|
|
51
51
|
from .lumen_config_validator import load_and_validate_config
|
|
52
|
-
|
|
53
|
-
from .model_info import ModelInfo, Source, Runtimes, Metadata
|
|
52
|
+
from .model_info import Metadata, ModelInfo, Runtimes, Source
|
|
54
53
|
from .model_info_validator import load_and_validate_model_info
|
|
55
|
-
from .result_schemas import
|
|
56
|
-
EmbeddingV1,
|
|
57
|
-
FaceV1,
|
|
58
|
-
LabelsV1
|
|
59
|
-
)
|
|
54
|
+
from .result_schemas import OCRV1, EmbeddingV1, FaceV1, LabelsV1, TextGenerationV1
|
|
60
55
|
|
|
61
56
|
__version__ = "0.1.0"
|
|
62
57
|
|
|
@@ -76,6 +71,8 @@ __all__ = [
|
|
|
76
71
|
"FaceV1",
|
|
77
72
|
"EmbeddingV1",
|
|
78
73
|
"LabelsV1",
|
|
74
|
+
"OCRV1",
|
|
75
|
+
"TextGenerationV1",
|
|
79
76
|
# Downloader
|
|
80
77
|
"Downloader",
|
|
81
78
|
"DownloadResult",
|
lumen_resources/downloader.py
CHANGED
|
@@ -139,13 +139,18 @@ class Downloader:
|
|
|
139
139
|
|
|
140
140
|
for alias, model_config in service_config.models.items():
|
|
141
141
|
model_type = f"{service_name}:{alias}"
|
|
142
|
+
prefer_fp16 = False
|
|
143
|
+
if service_config.backend_settings:
|
|
144
|
+
prefer_fp16 = service_config.backend_settings.prefer_fp16 or False
|
|
142
145
|
|
|
143
146
|
if self.verbose:
|
|
144
147
|
print(f"\n📦 Processing {model_type.upper()}")
|
|
145
148
|
print(f" Model: {model_config.model}")
|
|
146
149
|
print(f" Runtime: {model_config.runtime.value}")
|
|
147
150
|
|
|
148
|
-
result = self._download_model(
|
|
151
|
+
result = self._download_model(
|
|
152
|
+
model_type, model_config, force, prefer_fp16
|
|
153
|
+
)
|
|
149
154
|
results[model_type] = result
|
|
150
155
|
|
|
151
156
|
# Print result
|
|
@@ -163,7 +168,7 @@ class Downloader:
|
|
|
163
168
|
|
|
164
169
|
return results
|
|
165
170
|
|
|
166
|
-
def _get_runtime_patterns(self, runtime: Runtime) -> list[str]:
|
|
171
|
+
def _get_runtime_patterns(self, runtime: Runtime, pref_fp16: bool) -> list[str]:
|
|
167
172
|
"""Get file patterns to download based on runtime.
|
|
168
173
|
|
|
169
174
|
Determines which file patterns to include in downloads based on the
|
|
@@ -171,18 +176,20 @@ class Downloader:
|
|
|
171
176
|
|
|
172
177
|
Args:
|
|
173
178
|
runtime: The model runtime (torch, onnx, rknn).
|
|
179
|
+
pref_fp16: Whether to prefer FP16 models over FP32.
|
|
174
180
|
|
|
175
181
|
Returns:
|
|
176
182
|
List of file glob patterns for the download.
|
|
177
183
|
|
|
178
184
|
Example:
|
|
179
|
-
>>> patterns = downloader._get_runtime_patterns(Runtime.torch)
|
|
185
|
+
>>> patterns = downloader._get_runtime_patterns(Runtime.torch, False)
|
|
180
186
|
>>> print("model_info.json" in patterns)
|
|
181
187
|
True
|
|
182
188
|
"""
|
|
183
189
|
patterns = [
|
|
184
190
|
"model_info.json",
|
|
185
191
|
"*config*",
|
|
192
|
+
"*.txt",
|
|
186
193
|
] # Always include model_info.json and config files.
|
|
187
194
|
|
|
188
195
|
if runtime == Runtime.torch:
|
|
@@ -202,14 +209,17 @@ class Downloader:
|
|
|
202
209
|
elif runtime == Runtime.onnx:
|
|
203
210
|
patterns.extend(
|
|
204
211
|
[
|
|
205
|
-
"*.onnx",
|
|
206
|
-
"*.ort",
|
|
207
212
|
"*vocab*",
|
|
208
213
|
"*tokenizer*",
|
|
209
214
|
"special_tokens_map.json",
|
|
210
215
|
"preprocessor_config.json",
|
|
211
216
|
]
|
|
212
217
|
)
|
|
218
|
+
# Only add one precision based on preference to save space
|
|
219
|
+
if pref_fp16:
|
|
220
|
+
patterns.extend(["*.fp16.onnx"])
|
|
221
|
+
else:
|
|
222
|
+
patterns.extend(["*.fp32.onnx"])
|
|
213
223
|
elif runtime == Runtime.rknn:
|
|
214
224
|
patterns.extend(
|
|
215
225
|
[
|
|
@@ -224,18 +234,94 @@ class Downloader:
|
|
|
224
234
|
return patterns
|
|
225
235
|
|
|
226
236
|
def _download_model(
|
|
227
|
-
self, model_type: str, model_config: ModelConfig, force: bool
|
|
237
|
+
self, model_type: str, model_config: ModelConfig, force: bool, pref_fp16: bool
|
|
238
|
+
) -> DownloadResult:
|
|
239
|
+
"""Download a single model with its runtime files using fallback strategy.
|
|
240
|
+
|
|
241
|
+
First attempts to download with the preferred precision (FP16/FP32),
|
|
242
|
+
and if that fails due to file mismatch, falls back to the other precision.
|
|
243
|
+
This ensures model availability while minimizing storage usage.
|
|
244
|
+
|
|
245
|
+
Args:
|
|
246
|
+
model_type: Identifier for the model (e.g., "clip:default").
|
|
247
|
+
model_config: Model configuration from LumenConfig.
|
|
248
|
+
force: Whether to force re-download even if already cached.
|
|
249
|
+
pref_fp16: Whether to prefer FP16 models over FP32.
|
|
250
|
+
|
|
251
|
+
Returns:
|
|
252
|
+
DownloadResult with success status, file paths, and error details.
|
|
253
|
+
|
|
254
|
+
Raises:
|
|
255
|
+
DownloadError: If platform download fails for both precisions.
|
|
256
|
+
ModelInfoError: If model_info.json is missing or invalid.
|
|
257
|
+
ValidationError: If model configuration is not supported.
|
|
258
|
+
"""
|
|
259
|
+
# First attempt with preferred precision
|
|
260
|
+
preferred_patterns = self._get_runtime_patterns(model_config.runtime, pref_fp16)
|
|
261
|
+
fallback_patterns = self._get_runtime_patterns(
|
|
262
|
+
model_config.runtime, not pref_fp16
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
# Try preferred precision first
|
|
266
|
+
try:
|
|
267
|
+
return self._download_model_with_patterns(
|
|
268
|
+
model_type, model_config, force, preferred_patterns, pref_fp16
|
|
269
|
+
)
|
|
270
|
+
except DownloadError as e:
|
|
271
|
+
# Check if this is a "no matching files" error that warrants fallback
|
|
272
|
+
if (
|
|
273
|
+
self._should_fallback_download(str(e))
|
|
274
|
+
and model_config.runtime == Runtime.onnx
|
|
275
|
+
):
|
|
276
|
+
precision = "FP16" if pref_fp16 else "FP32"
|
|
277
|
+
fallback_precision = "FP32" if pref_fp16 else "FP16"
|
|
278
|
+
if self.verbose:
|
|
279
|
+
print(
|
|
280
|
+
f" ⚠️ {precision} model not found, trying {fallback_precision}"
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
try:
|
|
284
|
+
return self._download_model_with_patterns(
|
|
285
|
+
model_type,
|
|
286
|
+
model_config,
|
|
287
|
+
force,
|
|
288
|
+
fallback_patterns,
|
|
289
|
+
not pref_fp16,
|
|
290
|
+
)
|
|
291
|
+
except DownloadError as fallback_error:
|
|
292
|
+
# If fallback also fails, report both errors
|
|
293
|
+
return DownloadResult(
|
|
294
|
+
model_type=model_type,
|
|
295
|
+
model_name=model_config.model,
|
|
296
|
+
runtime=model_config.runtime.value
|
|
297
|
+
if hasattr(model_config.runtime, "value")
|
|
298
|
+
else str(model_config.runtime),
|
|
299
|
+
success=False,
|
|
300
|
+
error=f"Failed to download with {precision}: {e}. "
|
|
301
|
+
f"Fallback with {fallback_precision} also failed: {fallback_error}",
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
# Non-fallbackable error or non-ONNX runtime, just report original error
|
|
305
|
+
raise
|
|
306
|
+
|
|
307
|
+
def _download_model_with_patterns(
|
|
308
|
+
self,
|
|
309
|
+
model_type: str,
|
|
310
|
+
model_config: ModelConfig,
|
|
311
|
+
force: bool,
|
|
312
|
+
patterns: list[str],
|
|
313
|
+
is_fp16: bool | None = None,
|
|
228
314
|
) -> DownloadResult:
|
|
229
|
-
"""Download a
|
|
315
|
+
"""Download a model with specific file patterns.
|
|
230
316
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
rollback on failure by cleaning up downloaded files.
|
|
317
|
+
This is the core download method that handles the actual downloading
|
|
318
|
+
with a given set of file patterns.
|
|
234
319
|
|
|
235
320
|
Args:
|
|
236
321
|
model_type: Identifier for the model (e.g., "clip:default").
|
|
237
322
|
model_config: Model configuration from LumenConfig.
|
|
238
323
|
force: Whether to force re-download even if already cached.
|
|
324
|
+
patterns: File patterns to include in the download.
|
|
239
325
|
|
|
240
326
|
Returns:
|
|
241
327
|
DownloadResult with success status, file paths, and error details.
|
|
@@ -254,8 +340,6 @@ class Downloader:
|
|
|
254
340
|
)
|
|
255
341
|
|
|
256
342
|
try:
|
|
257
|
-
# Phase 1: Prepare and download runtime + JSON only
|
|
258
|
-
patterns = self._get_runtime_patterns(model_config.runtime)
|
|
259
343
|
cache_dir = Path(self.config.metadata.cache_dir).expanduser()
|
|
260
344
|
|
|
261
345
|
model_path = self.platform.download_model(
|
|
@@ -277,7 +361,10 @@ class Downloader:
|
|
|
277
361
|
if model_config.dataset and model_info.datasets:
|
|
278
362
|
dataset_files = model_info.datasets.get(model_config.dataset)
|
|
279
363
|
if dataset_files:
|
|
280
|
-
for file_rel in [
|
|
364
|
+
for file_rel in [
|
|
365
|
+
dataset_files.labels,
|
|
366
|
+
dataset_files.embeddings,
|
|
367
|
+
]:
|
|
281
368
|
dataset_path = model_path / file_rel
|
|
282
369
|
if not dataset_path.exists():
|
|
283
370
|
# Download only the dataset file by its relative path
|
|
@@ -294,7 +381,9 @@ class Downloader:
|
|
|
294
381
|
)
|
|
295
382
|
|
|
296
383
|
# Final: File integrity validation
|
|
297
|
-
missing = self._validate_files(
|
|
384
|
+
missing = self._validate_files(
|
|
385
|
+
model_path, model_info, model_config, is_fp16
|
|
386
|
+
)
|
|
298
387
|
result.missing_files = missing
|
|
299
388
|
|
|
300
389
|
if missing:
|
|
@@ -317,142 +406,151 @@ class Downloader:
|
|
|
317
406
|
|
|
318
407
|
return result
|
|
319
408
|
|
|
409
|
+
def _should_fallback_download(self, error_message: str) -> bool:
|
|
410
|
+
"""Determine if a download error should trigger fallback to another precision.
|
|
411
|
+
|
|
412
|
+
Args:
|
|
413
|
+
error_message: The error message from the download attempt.
|
|
414
|
+
|
|
415
|
+
Returns:
|
|
416
|
+
True if the error suggests we should try the other precision, False otherwise.
|
|
417
|
+
"""
|
|
418
|
+
# Common patterns that indicate file matching issues
|
|
419
|
+
fallback_indicators = [
|
|
420
|
+
"No matching files found",
|
|
421
|
+
"No files matched the pattern",
|
|
422
|
+
"Cannot find any files matching",
|
|
423
|
+
"File pattern matched no files",
|
|
424
|
+
"No such file or directory", # Sometimes used for remote files
|
|
425
|
+
]
|
|
426
|
+
|
|
427
|
+
error_lower = error_message.lower()
|
|
428
|
+
return any(
|
|
429
|
+
indicator.lower() in error_lower for indicator in fallback_indicators
|
|
430
|
+
)
|
|
431
|
+
|
|
320
432
|
def _load_model_info(self, model_path: Path) -> ModelInfo:
|
|
321
433
|
"""Load and parse model_info.json using validator.
|
|
322
434
|
|
|
323
|
-
Loads the model_info.json file from the model directory and validates
|
|
324
|
-
it against the ModelInfo schema to ensure metadata integrity.
|
|
325
|
-
|
|
326
435
|
Args:
|
|
327
|
-
model_path:
|
|
436
|
+
model_path: Local path where model files are located.
|
|
328
437
|
|
|
329
438
|
Returns:
|
|
330
|
-
|
|
439
|
+
Parsed ModelInfo object.
|
|
331
440
|
|
|
332
441
|
Raises:
|
|
333
|
-
ModelInfoError: If model_info.json is missing or
|
|
334
|
-
|
|
335
|
-
Example:
|
|
336
|
-
>>> model_info = downloader._load_model_info(Path("/models/clip_vit_b32"))
|
|
337
|
-
>>> print(model_info.name)
|
|
338
|
-
'ViT-B-32'
|
|
442
|
+
ModelInfoError: If model_info.json is missing or invalid.
|
|
339
443
|
"""
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
msg = (
|
|
344
|
-
f"model_info.json not found in {model_path}. "
|
|
345
|
-
"Repository must contain model metadata."
|
|
346
|
-
)
|
|
347
|
-
raise ModelInfoError(msg)
|
|
444
|
+
info_path = model_path / "model_info.json"
|
|
445
|
+
if not info_path.exists():
|
|
446
|
+
raise ModelInfoError(f"Missing model_info.json in {model_path}")
|
|
348
447
|
|
|
349
448
|
try:
|
|
350
|
-
return load_and_validate_model_info(
|
|
449
|
+
return load_and_validate_model_info(info_path)
|
|
351
450
|
except Exception as e:
|
|
352
|
-
raise ModelInfoError(f"Failed to load
|
|
451
|
+
raise ModelInfoError(f"Failed to load model_info.json: {e}")
|
|
353
452
|
|
|
354
453
|
def _validate_model_config(
|
|
355
454
|
self, model_info: ModelInfo, model_config: ModelConfig
|
|
356
455
|
) -> None:
|
|
357
|
-
"""Validate
|
|
456
|
+
"""Validate model configuration against model_info.json.
|
|
358
457
|
|
|
359
|
-
Checks
|
|
360
|
-
|
|
458
|
+
Checks that the requested runtime and dataset are supported
|
|
459
|
+
by the model metadata.
|
|
361
460
|
|
|
362
461
|
Args:
|
|
363
|
-
model_info:
|
|
364
|
-
model_config:
|
|
462
|
+
model_info: Parsed model information.
|
|
463
|
+
model_config: Model configuration to validate.
|
|
365
464
|
|
|
366
465
|
Raises:
|
|
367
|
-
ValidationError: If
|
|
368
|
-
by the model according to its metadata.
|
|
369
|
-
|
|
370
|
-
Example:
|
|
371
|
-
>>> downloader._validate_model_config(model_info, model_config) # No exception
|
|
372
|
-
>>> # If runtime is not supported, raises ValidationError
|
|
466
|
+
ValidationError: If configuration is not supported by the model.
|
|
373
467
|
"""
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
468
|
+
# Validate runtime support
|
|
469
|
+
runtime_str = (
|
|
470
|
+
model_config.runtime.value
|
|
471
|
+
if hasattr(model_config.runtime, "value")
|
|
472
|
+
else str(model_config.runtime)
|
|
473
|
+
)
|
|
474
|
+
if runtime_str not in model_info.runtimes:
|
|
380
475
|
raise ValidationError(
|
|
381
|
-
f"
|
|
476
|
+
f"Runtime {runtime_str} not supported by model {model_config.model}. "
|
|
477
|
+
f"Supported runtimes: {', '.join(model_info.runtimes)}"
|
|
382
478
|
)
|
|
383
479
|
|
|
384
|
-
# Special check for RKNN device support
|
|
385
|
-
if runtime == Runtime.rknn and rknn_device:
|
|
386
|
-
if not runtime_config.devices or rknn_device not in runtime_config.devices:
|
|
387
|
-
msg = (
|
|
388
|
-
f"Model {model_config.model} does not support "
|
|
389
|
-
f"runtime '{runtime.value}' with device '{rknn_device}'"
|
|
390
|
-
)
|
|
391
|
-
raise ValidationError(msg)
|
|
392
|
-
|
|
393
480
|
# Validate dataset if specified
|
|
394
481
|
if model_config.dataset:
|
|
395
482
|
if (
|
|
396
483
|
not model_info.datasets
|
|
397
484
|
or model_config.dataset not in model_info.datasets
|
|
398
485
|
):
|
|
399
|
-
|
|
400
|
-
f"Dataset
|
|
401
|
-
f"
|
|
486
|
+
raise ValidationError(
|
|
487
|
+
f"Dataset {model_config.dataset} not supported by model {model_config.model}. "
|
|
488
|
+
f"Available datasets: {', '.join(model_info.datasets.keys() if model_info.datasets else [])}"
|
|
402
489
|
)
|
|
403
|
-
|
|
490
|
+
|
|
491
|
+
# Validate RKNN device if RKNN runtime
|
|
492
|
+
if model_config.runtime == Runtime.rknn and not model_config.rknn_device:
|
|
493
|
+
raise ValidationError(
|
|
494
|
+
f"RKNN runtime requires rknn_device specification for model {model_config.model}"
|
|
495
|
+
)
|
|
404
496
|
|
|
405
497
|
def _validate_files(
|
|
406
|
-
self,
|
|
498
|
+
self,
|
|
499
|
+
model_path: Path,
|
|
500
|
+
model_info: ModelInfo,
|
|
501
|
+
model_config: ModelConfig,
|
|
502
|
+
is_fp16: bool | None = None,
|
|
407
503
|
) -> list[str]:
|
|
408
|
-
"""Validate that required
|
|
504
|
+
"""Validate that all required files are present after download.
|
|
409
505
|
|
|
410
|
-
Checks
|
|
411
|
-
|
|
412
|
-
|
|
506
|
+
Checks model files, tokenizer files, and dataset files against
|
|
507
|
+
the model_info.json metadata based on the actual precision
|
|
508
|
+
downloaded.
|
|
413
509
|
|
|
414
510
|
Args:
|
|
415
|
-
model_path:
|
|
416
|
-
model_info:
|
|
417
|
-
model_config: Model configuration
|
|
511
|
+
model_path: Local path where model files are located.
|
|
512
|
+
model_info: Parsed model information.
|
|
513
|
+
model_config: Model configuration to validate.
|
|
514
|
+
is_fp16: Whether FP16 files were downloaded (None for non-ONNX
|
|
515
|
+
runtimes).
|
|
418
516
|
|
|
419
517
|
Returns:
|
|
420
|
-
List of missing file paths
|
|
421
|
-
Empty list if all required files are present.
|
|
518
|
+
List of missing file paths. Empty list if all files present.
|
|
422
519
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
>>> if not missing:
|
|
426
|
-
... print("All required files are present")
|
|
427
|
-
... else:
|
|
428
|
-
... print(f"Missing files: {missing}")
|
|
520
|
+
Raises:
|
|
521
|
+
ValidationError: If critical files are missing.
|
|
429
522
|
"""
|
|
430
523
|
missing: list[str] = []
|
|
524
|
+
runtime_str = (
|
|
525
|
+
model_config.runtime.value
|
|
526
|
+
if hasattr(model_config.runtime, "value")
|
|
527
|
+
else str(model_config.runtime)
|
|
528
|
+
)
|
|
431
529
|
|
|
432
|
-
#
|
|
433
|
-
runtime_config = model_info.runtimes.get(
|
|
434
|
-
if
|
|
435
|
-
return missing
|
|
436
|
-
|
|
437
|
-
# Get required files based on runtime type
|
|
438
|
-
if model_config.runtime == Runtime.rknn and model_config.rknn_device:
|
|
439
|
-
# RKNN files are organized by device
|
|
440
|
-
if isinstance(runtime_config.files, dict):
|
|
441
|
-
required_files = runtime_config.files.get(model_config.rknn_device, [])
|
|
442
|
-
else:
|
|
443
|
-
required_files = []
|
|
444
|
-
else:
|
|
445
|
-
# Other runtimes have simple list
|
|
530
|
+
# Check runtime files
|
|
531
|
+
runtime_config = model_info.runtimes.get(runtime_str)
|
|
532
|
+
if runtime_config and runtime_config.files:
|
|
446
533
|
if isinstance(runtime_config.files, list):
|
|
447
|
-
|
|
534
|
+
runtime_files = runtime_config.files
|
|
535
|
+
|
|
536
|
+
# For ONNX runtime, filter by precision if specified
|
|
537
|
+
if runtime_str == "onnx" and is_fp16 is not None:
|
|
538
|
+
precision_str = "fp16" if is_fp16 else "fp32"
|
|
539
|
+
runtime_files = [
|
|
540
|
+
f
|
|
541
|
+
for f in runtime_files
|
|
542
|
+
if not f.endswith((".fp16.onnx", ".fp32.onnx"))
|
|
543
|
+
or f.endswith(f".{precision_str}.onnx")
|
|
544
|
+
]
|
|
545
|
+
elif isinstance(runtime_config.files, dict) and model_config.rknn_device:
|
|
546
|
+
# RKNN files are organized by device
|
|
547
|
+
runtime_files = runtime_config.files.get(model_config.rknn_device, [])
|
|
448
548
|
else:
|
|
449
|
-
|
|
549
|
+
runtime_files = []
|
|
450
550
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
if not full_path.exists():
|
|
455
|
-
missing.append(file_path)
|
|
551
|
+
for file_name in runtime_files:
|
|
552
|
+
if not (model_path / file_name).exists():
|
|
553
|
+
missing.append(file_name)
|
|
456
554
|
|
|
457
555
|
# Check dataset files if specified
|
|
458
556
|
if model_config.dataset and model_info.datasets:
|