lumen-resources 0.4.1__tar.gz → 0.4.2__tar.gz
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-0.4.1 → lumen_resources-0.4.2}/PKG-INFO +1 -1
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/cli.py +1 -1
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/downloader.py +42 -104
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/lumen_config.py +2 -2
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/lumen_config_validator.py +3 -3
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/model_info_validator.py +3 -3
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/schemas/config-schema.yaml +1 -1
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources.egg-info/PKG-INFO +1 -1
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/.gitignore +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/README.md +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/docs/examples/clip_torch_cn.yaml +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/docs/examples/hub-service.yaml +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/docs/examples/model_info_template.json +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/docs/examples/single-service.yaml +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/pyproject.toml +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/setup.cfg +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/__init__.py +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/exceptions.py +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/model_info.py +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/platform.py +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/result_schemas/README.md +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/result_schemas/__init__.py +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/result_schemas/embedding_v1.py +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/result_schemas/face_v1.py +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/result_schemas/labels_v1.py +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/result_schemas/ocr_v1.py +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/result_schemas/text_generation_v1.py +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/schemas/model_info-schema.json +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/schemas/result_schemas/embedding_v1.json +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/schemas/result_schemas/face_v1.json +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/schemas/result_schemas/labels_v1.json +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/schemas/result_schemas/ocr_v1.json +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/schemas/result_schemas/text_generation_v1.json +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources.egg-info/SOURCES.txt +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources.egg-info/dependency_links.txt +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources.egg-info/entry_points.txt +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources.egg-info/requires.txt +0 -0
- {lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources.egg-info/top_level.txt +0 -0
|
@@ -291,7 +291,7 @@ def cmd_list(args: argparse.Namespace) -> None:
|
|
|
291
291
|
import json
|
|
292
292
|
|
|
293
293
|
try:
|
|
294
|
-
with open(info_file
|
|
294
|
+
with open(info_file) as f:
|
|
295
295
|
info = json.load(f)
|
|
296
296
|
print(f" Version: {info.get('version', 'unknown')}")
|
|
297
297
|
runtimes = info.get("runtimes", {})
|
|
@@ -139,18 +139,15 @@ 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
|
|
145
142
|
|
|
146
143
|
if self.verbose:
|
|
147
144
|
print(f"\n📦 Processing {model_type.upper()}")
|
|
148
145
|
print(f" Model: {model_config.model}")
|
|
149
146
|
print(f" Runtime: {model_config.runtime.value}")
|
|
147
|
+
if model_config.precision:
|
|
148
|
+
print(f" Precision: {model_config.precision}")
|
|
150
149
|
|
|
151
|
-
result = self._download_model(
|
|
152
|
-
model_type, model_config, force, prefer_fp16
|
|
153
|
-
)
|
|
150
|
+
result = self._download_model(model_type, model_config, force)
|
|
154
151
|
results[model_type] = result
|
|
155
152
|
|
|
156
153
|
# Print result
|
|
@@ -168,22 +165,25 @@ class Downloader:
|
|
|
168
165
|
|
|
169
166
|
return results
|
|
170
167
|
|
|
171
|
-
def _get_runtime_patterns(
|
|
172
|
-
|
|
168
|
+
def _get_runtime_patterns(
|
|
169
|
+
self, runtime: Runtime, precision: str | None
|
|
170
|
+
) -> list[str]:
|
|
171
|
+
"""Get file patterns to download based on runtime and precision.
|
|
173
172
|
|
|
174
173
|
Determines which file patterns to include in downloads based on the
|
|
175
|
-
model runtime. Always includes model_info.json
|
|
174
|
+
model runtime and precision configuration. Always includes model_info.json
|
|
175
|
+
and config files.
|
|
176
176
|
|
|
177
177
|
Args:
|
|
178
178
|
runtime: The model runtime (torch, onnx, rknn).
|
|
179
|
-
|
|
179
|
+
precision: The precision variant (fp32, fp16, int8, q4fp16, etc.).
|
|
180
180
|
|
|
181
181
|
Returns:
|
|
182
182
|
List of file glob patterns for the download.
|
|
183
183
|
|
|
184
184
|
Example:
|
|
185
|
-
>>> patterns = downloader._get_runtime_patterns(Runtime.
|
|
186
|
-
>>> print("
|
|
185
|
+
>>> patterns = downloader._get_runtime_patterns(Runtime.onnx, "fp16")
|
|
186
|
+
>>> print("*.fp16.onnx" in patterns)
|
|
187
187
|
True
|
|
188
188
|
"""
|
|
189
189
|
patterns = [
|
|
@@ -215,11 +215,12 @@ class Downloader:
|
|
|
215
215
|
"preprocessor_config.json",
|
|
216
216
|
]
|
|
217
217
|
)
|
|
218
|
-
#
|
|
219
|
-
if
|
|
220
|
-
patterns.extend(["*.
|
|
218
|
+
# Add precision-specific ONNX model files if precision is specified
|
|
219
|
+
if precision:
|
|
220
|
+
patterns.extend([f"*.{precision}.onnx"])
|
|
221
221
|
else:
|
|
222
|
-
|
|
222
|
+
# If no precision specified, include all common precisions
|
|
223
|
+
patterns.extend(["*.fp32.onnx", "*.fp16.onnx", "*.int8.onnx"])
|
|
223
224
|
elif runtime == Runtime.rknn:
|
|
224
225
|
patterns.extend(
|
|
225
226
|
[
|
|
@@ -230,79 +231,45 @@ class Downloader:
|
|
|
230
231
|
"preprocessor_config.json",
|
|
231
232
|
]
|
|
232
233
|
)
|
|
234
|
+
# RKNN files are already quantized, precision field may indicate variant
|
|
235
|
+
if precision:
|
|
236
|
+
patterns.extend([f"*.{precision}.rknn"])
|
|
237
|
+
else:
|
|
238
|
+
patterns.extend(["*.rknn"])
|
|
233
239
|
|
|
234
240
|
return patterns
|
|
235
241
|
|
|
236
242
|
def _download_model(
|
|
237
|
-
self, model_type: str, model_config: ModelConfig, force: bool
|
|
243
|
+
self, model_type: str, model_config: ModelConfig, force: bool
|
|
238
244
|
) -> DownloadResult:
|
|
239
|
-
"""Download a single model with its runtime files
|
|
245
|
+
"""Download a single model with its runtime files.
|
|
240
246
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
247
|
+
Uses the precision specified in model_config to download the appropriate
|
|
248
|
+
model variant. If no precision is specified for ONNX/RKNN runtimes, will
|
|
249
|
+
download all available precision variants.
|
|
244
250
|
|
|
245
251
|
Args:
|
|
246
252
|
model_type: Identifier for the model (e.g., "clip:default").
|
|
247
253
|
model_config: Model configuration from LumenConfig.
|
|
248
254
|
force: Whether to force re-download even if already cached.
|
|
249
|
-
pref_fp16: Whether to prefer FP16 models over FP32.
|
|
250
255
|
|
|
251
256
|
Returns:
|
|
252
257
|
DownloadResult with success status, file paths, and error details.
|
|
253
258
|
|
|
254
259
|
Raises:
|
|
255
|
-
DownloadError: If platform download fails
|
|
260
|
+
DownloadError: If platform download fails.
|
|
256
261
|
ModelInfoError: If model_info.json is missing or invalid.
|
|
257
262
|
ValidationError: If model configuration is not supported.
|
|
258
263
|
"""
|
|
259
|
-
#
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
model_config.runtime, not pref_fp16
|
|
264
|
+
# Get file patterns based on runtime and precision from ModelConfig
|
|
265
|
+
patterns = self._get_runtime_patterns(
|
|
266
|
+
model_config.runtime, model_config.precision
|
|
263
267
|
)
|
|
264
268
|
|
|
265
|
-
#
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
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
|
|
269
|
+
# Download with the determined patterns
|
|
270
|
+
return self._download_model_with_patterns(
|
|
271
|
+
model_type, model_config, force, patterns
|
|
272
|
+
)
|
|
306
273
|
|
|
307
274
|
def _download_model_with_patterns(
|
|
308
275
|
self,
|
|
@@ -310,7 +277,6 @@ class Downloader:
|
|
|
310
277
|
model_config: ModelConfig,
|
|
311
278
|
force: bool,
|
|
312
279
|
patterns: list[str],
|
|
313
|
-
is_fp16: bool | None = None,
|
|
314
280
|
) -> DownloadResult:
|
|
315
281
|
"""Download a model with specific file patterns.
|
|
316
282
|
|
|
@@ -381,9 +347,7 @@ class Downloader:
|
|
|
381
347
|
)
|
|
382
348
|
|
|
383
349
|
# Final: File integrity validation
|
|
384
|
-
missing = self._validate_files(
|
|
385
|
-
model_path, model_info, model_config, is_fp16
|
|
386
|
-
)
|
|
350
|
+
missing = self._validate_files(model_path, model_info, model_config)
|
|
387
351
|
result.missing_files = missing
|
|
388
352
|
|
|
389
353
|
if missing:
|
|
@@ -406,29 +370,6 @@ class Downloader:
|
|
|
406
370
|
|
|
407
371
|
return result
|
|
408
372
|
|
|
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
|
-
|
|
432
373
|
def _load_model_info(self, model_path: Path) -> ModelInfo:
|
|
433
374
|
"""Load and parse model_info.json using validator.
|
|
434
375
|
|
|
@@ -499,20 +440,16 @@ class Downloader:
|
|
|
499
440
|
model_path: Path,
|
|
500
441
|
model_info: ModelInfo,
|
|
501
442
|
model_config: ModelConfig,
|
|
502
|
-
is_fp16: bool | None = None,
|
|
503
443
|
) -> list[str]:
|
|
504
444
|
"""Validate that all required files are present after download.
|
|
505
445
|
|
|
506
446
|
Checks model files, tokenizer files, and dataset files against
|
|
507
|
-
the model_info.json metadata based on the
|
|
508
|
-
downloaded.
|
|
447
|
+
the model_info.json metadata based on the runtime configuration.
|
|
509
448
|
|
|
510
449
|
Args:
|
|
511
450
|
model_path: Local path where model files are located.
|
|
512
451
|
model_info: Parsed model information.
|
|
513
452
|
model_config: Model configuration to validate.
|
|
514
|
-
is_fp16: Whether FP16 files were downloaded (None for non-ONNX
|
|
515
|
-
runtimes).
|
|
516
453
|
|
|
517
454
|
Returns:
|
|
518
455
|
List of missing file paths. Empty list if all files present.
|
|
@@ -534,13 +471,14 @@ class Downloader:
|
|
|
534
471
|
runtime_files = runtime_config.files
|
|
535
472
|
|
|
536
473
|
# For ONNX runtime, filter by precision if specified
|
|
537
|
-
if runtime_str == "onnx" and
|
|
538
|
-
precision_str = "fp16" if is_fp16 else "fp32"
|
|
474
|
+
if runtime_str == "onnx" and model_config.precision:
|
|
539
475
|
runtime_files = [
|
|
540
476
|
f
|
|
541
477
|
for f in runtime_files
|
|
542
|
-
if not f.endswith(
|
|
543
|
-
|
|
478
|
+
if not f.endswith(
|
|
479
|
+
(".fp16.onnx", ".fp32.onnx", ".int8.onnx", ".q4fp16.onnx")
|
|
480
|
+
)
|
|
481
|
+
or f.endswith(f".{model_config.precision}.onnx")
|
|
544
482
|
]
|
|
545
483
|
elif isinstance(runtime_config.files, dict) and model_config.rknn_device:
|
|
546
484
|
# RKNN files are organized by device
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# generated by datamodel-codegen:
|
|
2
2
|
# filename: config-schema.yaml
|
|
3
|
-
# timestamp: 2025-12-
|
|
3
|
+
# timestamp: 2025-12-30T14:26:42+00:00
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -225,7 +225,7 @@ class Services(BaseModel):
|
|
|
225
225
|
"""
|
|
226
226
|
Python package name
|
|
227
227
|
"""
|
|
228
|
-
import_info: ImportInfo
|
|
228
|
+
import_info: ImportInfo
|
|
229
229
|
backend_settings: BackendSettings | None = None
|
|
230
230
|
models: dict[str, ModelConfig]
|
|
231
231
|
"""
|
{lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/lumen_config_validator.py
RENAMED
|
@@ -57,7 +57,7 @@ class ConfigValidator:
|
|
|
57
57
|
if not schema_path.exists():
|
|
58
58
|
raise FileNotFoundError(f"Schema file not found: {schema_path}")
|
|
59
59
|
|
|
60
|
-
with open(schema_path,
|
|
60
|
+
with open(schema_path, encoding="utf-8") as f:
|
|
61
61
|
self.schema = yaml.safe_load(f)
|
|
62
62
|
|
|
63
63
|
self.validator = Draft7Validator(self.schema)
|
|
@@ -93,7 +93,7 @@ class ConfigValidator:
|
|
|
93
93
|
return False, [f"Configuration file not found: {config_path}"]
|
|
94
94
|
|
|
95
95
|
try:
|
|
96
|
-
with open(config_path,
|
|
96
|
+
with open(config_path, encoding="utf-8") as f:
|
|
97
97
|
config_data = yaml.safe_load(f)
|
|
98
98
|
except yaml.YAMLError as e:
|
|
99
99
|
return False, [f"Invalid YAML syntax: {e}"]
|
|
@@ -207,7 +207,7 @@ class ConfigValidator:
|
|
|
207
207
|
raise ConfigError(error_msg)
|
|
208
208
|
|
|
209
209
|
# Load and construct the validated configuration
|
|
210
|
-
with open(config_path,
|
|
210
|
+
with open(config_path, encoding="utf-8") as f:
|
|
211
211
|
config_data = yaml.safe_load(f)
|
|
212
212
|
|
|
213
213
|
return LumenConfig(**config_data)
|
|
@@ -54,7 +54,7 @@ class ModelInfoValidator:
|
|
|
54
54
|
if not schema_path.exists():
|
|
55
55
|
raise FileNotFoundError(f"Schema file not found: {schema_path}")
|
|
56
56
|
|
|
57
|
-
with open(schema_path,
|
|
57
|
+
with open(schema_path, encoding="utf-8") as f:
|
|
58
58
|
self.schema: dict[str, Any] = json.load(f)
|
|
59
59
|
|
|
60
60
|
self.validator = Draft7Validator(self.schema)
|
|
@@ -89,7 +89,7 @@ class ModelInfoValidator:
|
|
|
89
89
|
return False, [f"File not found: {path}"]
|
|
90
90
|
|
|
91
91
|
try:
|
|
92
|
-
with open(path,
|
|
92
|
+
with open(path, encoding="utf-8") as f:
|
|
93
93
|
data = json.load(f)
|
|
94
94
|
except json.JSONDecodeError as e:
|
|
95
95
|
return False, [f"Invalid JSON: {e}"]
|
|
@@ -196,7 +196,7 @@ class ModelInfoValidator:
|
|
|
196
196
|
)
|
|
197
197
|
raise ValueError(error_msg)
|
|
198
198
|
|
|
199
|
-
with open(path,
|
|
199
|
+
with open(path, encoding="utf-8") as f:
|
|
200
200
|
data = json.load(f)
|
|
201
201
|
|
|
202
202
|
return ModelInfo.model_validate(data)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/result_schemas/README.md
RENAMED
|
File without changes
|
{lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/result_schemas/__init__.py
RENAMED
|
File without changes
|
{lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/result_schemas/embedding_v1.py
RENAMED
|
File without changes
|
{lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/result_schemas/face_v1.py
RENAMED
|
File without changes
|
{lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/result_schemas/labels_v1.py
RENAMED
|
File without changes
|
{lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/result_schemas/ocr_v1.py
RENAMED
|
File without changes
|
|
File without changes
|
{lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources/schemas/model_info-schema.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{lumen_resources-0.4.1 → lumen_resources-0.4.2}/src/lumen_resources.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|