nexaai 1.0.17rc9__cp310-cp310-win_amd64.whl → 1.0.19__cp310-cp310-win_amd64.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.

Potentially problematic release.


This version of nexaai might be problematic. Click here for more details.

Files changed (49) hide show
  1. nexaai/_stub.cp310-win_amd64.pyd +0 -0
  2. nexaai/_version.py +1 -1
  3. nexaai/asr.py +2 -1
  4. nexaai/binds/common_bind.cp310-win_amd64.pyd +0 -0
  5. nexaai/binds/{nexa_llama_cpp → cpu_gpu}/ggml-base.dll +0 -0
  6. nexaai/binds/{nexa_nexaml → cpu_gpu}/ggml-cpu.dll +0 -0
  7. nexaai/binds/{nexa_llama_cpp → cpu_gpu}/ggml-cuda.dll +0 -0
  8. nexaai/binds/{nexa_llama_cpp → cpu_gpu}/ggml-vulkan.dll +0 -0
  9. nexaai/binds/{nexa_llama_cpp → cpu_gpu}/ggml.dll +0 -0
  10. nexaai/binds/{nexa_llama_cpp → cpu_gpu}/mtmd.dll +0 -0
  11. nexaai/binds/{nexa_llama_cpp/llama.dll → cpu_gpu/nexa_cpu_gpu.dll} +0 -0
  12. nexaai/binds/cpu_gpu/nexa_plugin.dll +0 -0
  13. nexaai/binds/embedder_bind.cp310-win_amd64.pyd +0 -0
  14. nexaai/binds/libcrypto-3-x64.dll +0 -0
  15. nexaai/binds/libssl-3-x64.dll +0 -0
  16. nexaai/binds/llm_bind.cp310-win_amd64.pyd +0 -0
  17. nexaai/binds/nexa_bridge.dll +0 -0
  18. nexaai/binds/{nexa_nexaml → nexaml}/ggml-base.dll +0 -0
  19. nexaai/binds/{nexa_llama_cpp → nexaml}/ggml-cpu.dll +0 -0
  20. nexaai/binds/{nexa_nexaml → nexaml}/ggml-cuda.dll +0 -0
  21. nexaai/binds/{nexa_nexaml → nexaml}/ggml-vulkan.dll +0 -0
  22. nexaai/binds/{nexa_nexaml → nexaml}/ggml.dll +0 -0
  23. nexaai/binds/{nexa_nexaml → nexaml}/nexa-mm-process.dll +0 -0
  24. nexaai/binds/{nexa_nexaml → nexaml}/nexa-sampling.dll +0 -0
  25. nexaai/binds/nexaml/nexa_plugin.dll +0 -0
  26. nexaai/binds/{nexa_nexaml → nexaml}/nexaproc.dll +0 -0
  27. nexaai/binds/{nexa_nexaml → nexaml}/qwen3-vl.dll +0 -0
  28. nexaai/binds/nexaml/qwen3vl-vision.dll +0 -0
  29. nexaai/binds/vlm_bind.cp310-win_amd64.pyd +0 -0
  30. nexaai/cv.py +2 -1
  31. nexaai/embedder.py +1 -1
  32. nexaai/image_gen.py +2 -1
  33. nexaai/llm.py +5 -3
  34. nexaai/llm_impl/mlx_llm_impl.py +2 -0
  35. nexaai/llm_impl/pybind_llm_impl.py +2 -0
  36. nexaai/rerank.py +2 -1
  37. nexaai/tts.py +2 -1
  38. nexaai/utils/manifest_utils.py +222 -15
  39. nexaai/utils/model_manager.py +120 -14
  40. nexaai/utils/model_types.py +2 -0
  41. nexaai/vlm.py +2 -1
  42. {nexaai-1.0.17rc9.dist-info → nexaai-1.0.19.dist-info}/METADATA +1 -2
  43. nexaai-1.0.19.dist-info/RECORD +76 -0
  44. nexaai/binds/nexa_llama_cpp/nexa_plugin.dll +0 -0
  45. nexaai/binds/nexa_nexaml/nexa_plugin.dll +0 -0
  46. nexaai/binds/nexa_nexaml/qwen3vl-vision.dll +0 -0
  47. nexaai-1.0.17rc9.dist-info/RECORD +0 -76
  48. {nexaai-1.0.17rc9.dist-info → nexaai-1.0.19.dist-info}/WHEEL +0 -0
  49. {nexaai-1.0.17rc9.dist-info → nexaai-1.0.19.dist-info}/top_level.txt +0 -0
Binary file
nexaai/_version.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # This file is generated by CMake from _version.py.in
2
2
  # Do not modify this file manually - it will be overwritten
3
3
 
4
- __version__ = "1.0.17-rc9"
4
+ __version__ = "1.0.19"
nexaai/asr.py CHANGED
@@ -35,7 +35,8 @@ class ASR(BaseModel):
35
35
  tokenizer_path: Optional[str] = None,
36
36
  language: Optional[str] = None,
37
37
  plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
38
- device_id: Optional[str] = None
38
+ device_id: Optional[str] = None,
39
+ **kwargs
39
40
  ) -> 'ASR':
40
41
  """Load ASR model from local path, routing to appropriate implementation."""
41
42
  # Check plugin_id value for routing - handle both enum and string
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
nexaai/cv.py CHANGED
@@ -73,7 +73,8 @@ class CVModel(BaseModel):
73
73
  _: str, # TODO: remove this argument, this is a hack to make api design happy
74
74
  config: CVModelConfig,
75
75
  plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
76
- device_id: Optional[str] = None
76
+ device_id: Optional[str] = None,
77
+ **kwargs
77
78
  ) -> 'CVModel':
78
79
  """Load CV model from configuration, routing to appropriate implementation."""
79
80
  # Check plugin_id value for routing - handle both enum and string
nexaai/embedder.py CHANGED
@@ -22,7 +22,7 @@ class Embedder(BaseModel):
22
22
  pass
23
23
 
24
24
  @classmethod
25
- def _load_from(cls, model_path: str, tokenizer_file: str = "tokenizer.json", plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP):
25
+ def _load_from(cls, model_path: str, tokenizer_file: str = "tokenizer.json", plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP, **kwargs):
26
26
  """
27
27
  Load an embedder from model files, routing to appropriate implementation.
28
28
 
nexaai/image_gen.py CHANGED
@@ -71,7 +71,8 @@ class ImageGen(BaseModel):
71
71
  plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
72
72
  device_id: Optional[str] = None,
73
73
  float16: bool = True,
74
- quantize: bool = False
74
+ quantize: bool = False,
75
+ **kwargs
75
76
  ) -> 'ImageGen':
76
77
  """Load image generation model from local path, routing to appropriate implementation."""
77
78
  # Check plugin_id value for routing - handle both enum and string
nexaai/llm.py CHANGED
@@ -15,10 +15,12 @@ class LLM(BaseModel):
15
15
  @classmethod
16
16
  def _load_from(cls,
17
17
  local_path: str,
18
+ model_name: Optional[str] = None,
18
19
  tokenizer_path: Optional[str] = None,
19
20
  m_cfg: ModelConfig = ModelConfig(),
20
21
  plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
21
- device_id: Optional[str] = None
22
+ device_id: Optional[str] = None,
23
+ **kwargs
22
24
  ) -> 'LLM':
23
25
  """Load model from local path, routing to appropriate implementation."""
24
26
  # Check plugin_id value for routing - handle both enum and string
@@ -26,10 +28,10 @@ class LLM(BaseModel):
26
28
 
27
29
  if plugin_value == "mlx":
28
30
  from nexaai.llm_impl.mlx_llm_impl import MLXLLMImpl
29
- return MLXLLMImpl._load_from(local_path, tokenizer_path, m_cfg, plugin_id, device_id)
31
+ return MLXLLMImpl._load_from(local_path, model_name, tokenizer_path, m_cfg, plugin_id, device_id)
30
32
  else:
31
33
  from nexaai.llm_impl.pybind_llm_impl import PyBindLLMImpl
32
- return PyBindLLMImpl._load_from(local_path, tokenizer_path, m_cfg, plugin_id, device_id)
34
+ return PyBindLLMImpl._load_from(local_path, model_name, tokenizer_path, m_cfg, plugin_id, device_id)
33
35
 
34
36
  def cancel_generation(self):
35
37
  """Signal to cancel any ongoing stream generation."""
@@ -16,6 +16,7 @@ class MLXLLMImpl(LLM):
16
16
  @classmethod
17
17
  def _load_from(cls,
18
18
  local_path: str,
19
+ model_name: Optional[str] = None,
19
20
  tokenizer_path: Optional[str] = None,
20
21
  m_cfg: ModelConfig = ModelConfig(),
21
22
  plugin_id: Union[PluginID, str] = PluginID.MLX,
@@ -40,6 +41,7 @@ class MLXLLMImpl(LLM):
40
41
  instance = cls(m_cfg)
41
42
  instance._mlx_llm = MLXLLMInterface(
42
43
  model_path=local_path,
44
+ # model_name=model_name, # FIXME: For MLX LLM, model_name is not used
43
45
  tokenizer_path=tokenizer_path or local_path,
44
46
  config=mlx_config,
45
47
  device=device_id
@@ -19,6 +19,7 @@ class PyBindLLMImpl(LLM):
19
19
  @classmethod
20
20
  def _load_from(cls,
21
21
  local_path: str,
22
+ model_name: Optional[str] = None,
22
23
  tokenizer_path: Optional[str] = None,
23
24
  m_cfg: ModelConfig = ModelConfig(),
24
25
  plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
@@ -55,6 +56,7 @@ class PyBindLLMImpl(LLM):
55
56
  plugin_id_str = plugin_id.value if isinstance(plugin_id, PluginID) else plugin_id
56
57
  handle = llm_bind.ml_llm_create(
57
58
  model_path=local_path,
59
+ model_name=model_name,
58
60
  tokenizer_path=tokenizer_path,
59
61
  model_config=config,
60
62
  plugin_id=plugin_id_str,
nexaai/rerank.py CHANGED
@@ -26,7 +26,8 @@ class Reranker(BaseModel):
26
26
  model_path: str,
27
27
  tokenizer_file: str = "tokenizer.json",
28
28
  plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
29
- device_id: Optional[str] = None
29
+ device_id: Optional[str] = None,
30
+ **kwargs
30
31
  ) -> 'Reranker':
31
32
  """Load reranker model from local path, routing to appropriate implementation."""
32
33
  # Check plugin_id value for routing - handle both enum and string
nexaai/tts.py CHANGED
@@ -45,7 +45,8 @@ class TTS(BaseModel):
45
45
  model_path: str,
46
46
  vocoder_path: str,
47
47
  plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
48
- device_id: Optional[str] = None
48
+ device_id: Optional[str] = None,
49
+ **kwargs
49
50
  ) -> 'TTS':
50
51
  """Load TTS model from local path, routing to appropriate implementation."""
51
52
  # Check plugin_id value for routing - handle both enum and string
@@ -22,6 +22,11 @@ from .model_types import (
22
22
  MODEL_TYPE_TO_PIPELINE
23
23
  )
24
24
 
25
+ MODEL_FILE_TYPE_TO_PLUGIN_ID_MAPPING = {
26
+ 'npu': 'npu',
27
+ 'mlx': 'mlx',
28
+ 'gguf': 'llama_cpp'
29
+ }
25
30
 
26
31
  def process_manifest_metadata(manifest: Dict[str, Any], repo_id: str) -> Dict[str, Any]:
27
32
  """Process manifest metadata to handle null/missing fields."""
@@ -94,12 +99,20 @@ def save_download_metadata(directory_path: str, metadata: Dict[str, Any]) -> Non
94
99
  pass
95
100
 
96
101
 
97
- def create_gguf_manifest(repo_id: str, files: List[str], directory_path: str, old_metadata: Dict[str, Any], is_mmproj: bool = False, file_name: Optional[Union[str, List[str]]] = None) -> Dict[str, Any]:
102
+ def _get_plugin_id_from_model_file_type(model_file_type: Optional[str], default: str = "llama_cpp") -> str:
103
+ """Map model file type to PluginId."""
104
+ return MODEL_FILE_TYPE_TO_PLUGIN_ID_MAPPING.get(model_file_type, default)
105
+
106
+
107
+ def create_gguf_manifest(repo_id: str, files: List[str], directory_path: str, old_metadata: Dict[str, Any], is_mmproj: bool = False, file_name: Optional[Union[str, List[str]]] = None, **kwargs) -> Dict[str, Any]:
98
108
  """Create GGUF format manifest."""
99
109
 
100
110
  # Load existing manifest to merge GGUF files if it exists
101
111
  existing_manifest = load_nexa_manifest(directory_path)
102
112
 
113
+ # Check if there's a downloaded nexa.manifest from the repo
114
+ downloaded_manifest = old_metadata.get('downloaded_manifest', {})
115
+
103
116
  model_files = {}
104
117
  if existing_manifest and "ModelFile" in existing_manifest:
105
118
  model_files = existing_manifest["ModelFile"].copy()
@@ -151,10 +164,41 @@ def create_gguf_manifest(repo_id: str, files: List[str], directory_path: str, ol
151
164
  "Size": file_size
152
165
  }
153
166
 
167
+ # Determine PluginId with priority: kwargs > downloaded_manifest > model_file_type > default
168
+ plugin_id = kwargs.get('plugin_id')
169
+ if not plugin_id:
170
+ model_file_type = old_metadata.get('model_file_type')
171
+ if downloaded_manifest.get('PluginId'):
172
+ plugin_id = downloaded_manifest.get('PluginId')
173
+ elif model_file_type:
174
+ plugin_id = _get_plugin_id_from_model_file_type(model_file_type)
175
+ else:
176
+ plugin_id = "llama_cpp"
177
+
178
+ # Determine ModelType with priority: kwargs > downloaded_manifest > pipeline_tag mapping
179
+ model_type = kwargs.get('model_type')
180
+ if not model_type:
181
+ if downloaded_manifest.get('ModelType'):
182
+ model_type = downloaded_manifest.get('ModelType')
183
+ else:
184
+ model_type = PIPELINE_TO_MODEL_TYPE.get(old_metadata.get('pipeline_tag'), "other")
185
+
186
+ # Determine ModelName with priority: kwargs > downloaded_manifest > empty string
187
+ model_name = kwargs.get('model_name')
188
+ if not model_name:
189
+ model_name = downloaded_manifest.get('ModelName', '')
190
+
191
+ # Get DeviceId and MinSDKVersion from kwargs or default to empty string
192
+ device_id = kwargs.get('device_id', '')
193
+ min_sdk_version = kwargs.get('min_sdk_version', '')
194
+
154
195
  manifest = {
155
196
  "Name": repo_id,
156
- "ModelType": PIPELINE_TO_MODEL_TYPE.get(old_metadata.get('pipeline_tag'), "other"),
157
- "PluginId": "llama_cpp",
197
+ "ModelName": model_name,
198
+ "ModelType": model_type,
199
+ "PluginId": plugin_id,
200
+ "DeviceId": device_id,
201
+ "MinSDKVersion": min_sdk_version,
158
202
  "ModelFile": model_files,
159
203
  "MMProjFile": mmproj_file,
160
204
  "TokenizerFile": {
@@ -172,12 +216,15 @@ def create_gguf_manifest(repo_id: str, files: List[str], directory_path: str, ol
172
216
  return manifest
173
217
 
174
218
 
175
- def create_mlx_manifest(repo_id: str, files: List[str], directory_path: str, old_metadata: Dict[str, Any], is_mmproj: bool = False, file_name: Optional[Union[str, List[str]]] = None) -> Dict[str, Any]:
219
+ def create_mlx_manifest(repo_id: str, files: List[str], directory_path: str, old_metadata: Dict[str, Any], is_mmproj: bool = False, file_name: Optional[Union[str, List[str]]] = None, **kwargs) -> Dict[str, Any]:
176
220
  """Create MLX format manifest."""
177
221
 
178
222
  # Load existing manifest to merge MLX files if it exists
179
223
  existing_manifest = load_nexa_manifest(directory_path)
180
224
 
225
+ # Check if there's a downloaded nexa.manifest from the repo
226
+ downloaded_manifest = old_metadata.get('downloaded_manifest', {})
227
+
181
228
  model_files = {}
182
229
  extra_files = []
183
230
 
@@ -233,10 +280,153 @@ def create_mlx_manifest(repo_id: str, files: List[str], directory_path: str, old
233
280
  "Size": file_size
234
281
  })
235
282
 
283
+ # Determine PluginId with priority: kwargs > downloaded_manifest > model_file_type > default
284
+ plugin_id = kwargs.get('plugin_id')
285
+ if not plugin_id:
286
+ model_file_type = old_metadata.get('model_file_type')
287
+ if downloaded_manifest.get('PluginId'):
288
+ plugin_id = downloaded_manifest.get('PluginId')
289
+ elif model_file_type:
290
+ plugin_id = _get_plugin_id_from_model_file_type(model_file_type)
291
+ else:
292
+ plugin_id = "mlx"
293
+
294
+ # Determine ModelType with priority: kwargs > downloaded_manifest > pipeline_tag mapping
295
+ model_type = kwargs.get('model_type')
296
+ if not model_type:
297
+ if downloaded_manifest.get('ModelType'):
298
+ model_type = downloaded_manifest.get('ModelType')
299
+ else:
300
+ model_type = PIPELINE_TO_MODEL_TYPE.get(old_metadata.get('pipeline_tag'), "other")
301
+
302
+ # Determine ModelName with priority: kwargs > downloaded_manifest > empty string
303
+ model_name = kwargs.get('model_name')
304
+ if not model_name:
305
+ model_name = downloaded_manifest.get('ModelName', '')
306
+
307
+ # Get DeviceId and MinSDKVersion from kwargs or default to empty string
308
+ device_id = kwargs.get('device_id', '')
309
+ min_sdk_version = kwargs.get('min_sdk_version', '')
310
+
311
+ manifest = {
312
+ "Name": repo_id,
313
+ "ModelName": model_name,
314
+ "ModelType": model_type,
315
+ "PluginId": plugin_id,
316
+ "DeviceId": device_id,
317
+ "MinSDKVersion": min_sdk_version,
318
+ "ModelFile": model_files,
319
+ "MMProjFile": mmproj_file,
320
+ "TokenizerFile": {
321
+ "Name": "",
322
+ "Downloaded": False,
323
+ "Size": 0
324
+ },
325
+ "ExtraFiles": extra_files if extra_files else None,
326
+ # Preserve old metadata fields
327
+ "pipeline_tag": old_metadata.get('pipeline_tag') if old_metadata.get('pipeline_tag') else existing_manifest.get('pipeline_tag'),
328
+ "download_time": old_metadata.get('download_time') if old_metadata.get('download_time') else existing_manifest.get('download_time'),
329
+ "avatar_url": old_metadata.get('avatar_url') if old_metadata.get('avatar_url') else existing_manifest.get('avatar_url')
330
+ }
331
+
332
+ return manifest
333
+
334
+
335
+ def create_npu_manifest(repo_id: str, files: List[str], directory_path: str, old_metadata: Dict[str, Any], is_mmproj: bool = False, file_name: Optional[Union[str, List[str]]] = None, **kwargs) -> Dict[str, Any]:
336
+ """Create NPU format manifest."""
337
+
338
+ # Load existing manifest to merge NPU files if it exists
339
+ existing_manifest = load_nexa_manifest(directory_path)
340
+
341
+ # Check if there's a downloaded nexa.manifest from the repo
342
+ downloaded_manifest = old_metadata.get('downloaded_manifest', {})
343
+
344
+ model_files = {}
345
+ extra_files = []
346
+
347
+ # Initialize MMProjFile
348
+ mmproj_file = {
349
+ "Name": "",
350
+ "Downloaded": False,
351
+ "Size": 0
352
+ }
353
+
354
+ for current_file_name in files:
355
+ file_path = os.path.join(directory_path, current_file_name)
356
+ file_size = 0
357
+ if os.path.exists(file_path):
358
+ try:
359
+ file_size = os.path.getsize(file_path)
360
+ except (OSError, IOError):
361
+ pass
362
+
363
+ # Check if this file is an mmproj file
364
+ is_current_mmproj = 'mmproj' in current_file_name.lower()
365
+
366
+ # If we're downloading specific files and this is marked as mmproj, respect that
367
+ if is_mmproj and file_name is not None:
368
+ filenames_to_check = file_name if isinstance(file_name, list) else [file_name]
369
+ is_current_mmproj = current_file_name in filenames_to_check
370
+
371
+ if is_current_mmproj:
372
+ # This is an mmproj file, put it in MMProjFile
373
+ mmproj_file = {
374
+ "Name": current_file_name,
375
+ "Downloaded": True,
376
+ "Size": file_size
377
+ }
378
+ else:
379
+ # For NPU, all non-mmproj files go to extra_files
380
+ extra_files.append({
381
+ "Name": current_file_name,
382
+ "Downloaded": True,
383
+ "Size": file_size
384
+ })
385
+
386
+ # Pick the first file from extra_files and add it to ModelFile with key "N/A"
387
+ if extra_files:
388
+ first_file = extra_files[0]
389
+ model_files["N/A"] = {
390
+ "Name": first_file["Name"],
391
+ "Downloaded": first_file["Downloaded"],
392
+ "Size": first_file["Size"]
393
+ }
394
+
395
+ # Determine PluginId with priority: kwargs > downloaded_manifest > model_file_type > default
396
+ plugin_id = kwargs.get('plugin_id')
397
+ if not plugin_id:
398
+ model_file_type = old_metadata.get('model_file_type')
399
+ if downloaded_manifest.get('PluginId'):
400
+ plugin_id = downloaded_manifest.get('PluginId')
401
+ elif model_file_type:
402
+ plugin_id = _get_plugin_id_from_model_file_type(model_file_type)
403
+ else:
404
+ plugin_id = "npu"
405
+
406
+ # Determine ModelType with priority: kwargs > downloaded_manifest > pipeline_tag mapping
407
+ model_type = kwargs.get('model_type')
408
+ if not model_type:
409
+ if downloaded_manifest.get('ModelType'):
410
+ model_type = downloaded_manifest.get('ModelType')
411
+ else:
412
+ model_type = PIPELINE_TO_MODEL_TYPE.get(old_metadata.get('pipeline_tag'), "other")
413
+
414
+ # Determine ModelName with priority: kwargs > downloaded_manifest > empty string
415
+ model_name = kwargs.get('model_name')
416
+ if not model_name:
417
+ model_name = downloaded_manifest.get('ModelName', '')
418
+
419
+ # Get DeviceId and MinSDKVersion from kwargs or default to empty string
420
+ device_id = kwargs.get('device_id', '')
421
+ min_sdk_version = kwargs.get('min_sdk_version', '')
422
+
236
423
  manifest = {
237
424
  "Name": repo_id,
238
- "ModelType": PIPELINE_TO_MODEL_TYPE.get(old_metadata.get('pipeline_tag'), "other"),
239
- "PluginId": "mlx",
425
+ "ModelName": model_name,
426
+ "ModelType": model_type,
427
+ "PluginId": plugin_id,
428
+ "DeviceId": device_id,
429
+ "MinSDKVersion": min_sdk_version,
240
430
  "ModelFile": model_files,
241
431
  "MMProjFile": mmproj_file,
242
432
  "TokenizerFile": {
@@ -254,8 +444,21 @@ def create_mlx_manifest(repo_id: str, files: List[str], directory_path: str, old
254
444
  return manifest
255
445
 
256
446
 
257
- def detect_model_type(files: List[str]) -> str:
258
- """Detect if this is a GGUF or MLX model based on file extensions."""
447
+ def detect_model_type(files: List[str], old_metadata: Dict[str, Any] = None) -> str:
448
+ """Detect if this is a GGUF, MLX, or NPU model based on file extensions and metadata.
449
+
450
+ Args:
451
+ files: List of files in the model directory
452
+ old_metadata: Metadata dict that may contain 'model_file_type'
453
+
454
+ Returns:
455
+ Model type string: 'gguf', 'mlx', or 'npu'
456
+ """
457
+ # Check if model_file_type is explicitly set to NPU
458
+ if old_metadata and old_metadata.get('model_file_type') == 'npu':
459
+ return "npu"
460
+
461
+ # Otherwise, detect based on file extensions
259
462
  has_gguf = any(f.endswith('.gguf') for f in files)
260
463
  has_safetensors = any(f.endswith('.safetensors') or 'safetensors' in f for f in files)
261
464
 
@@ -268,7 +471,7 @@ def detect_model_type(files: List[str]) -> str:
268
471
  return "mlx"
269
472
 
270
473
 
271
- def create_manifest_from_files(repo_id: str, files: List[str], directory_path: str, old_metadata: Dict[str, Any], is_mmproj: bool = False, file_name: Optional[Union[str, List[str]]] = None) -> Dict[str, Any]:
474
+ def create_manifest_from_files(repo_id: str, files: List[str], directory_path: str, old_metadata: Dict[str, Any], is_mmproj: bool = False, file_name: Optional[Union[str, List[str]]] = None, **kwargs) -> Dict[str, Any]:
272
475
  """
273
476
  Create appropriate manifest format based on detected model type.
274
477
 
@@ -276,22 +479,25 @@ def create_manifest_from_files(repo_id: str, files: List[str], directory_path: s
276
479
  repo_id: Repository ID
277
480
  files: List of files in the model directory
278
481
  directory_path: Path to the model directory
279
- old_metadata: Existing metadata (pipeline_tag, download_time, avatar_url)
482
+ old_metadata: Existing metadata (pipeline_tag, download_time, avatar_url, model_file_type)
280
483
  is_mmproj: Whether the downloaded file is an mmproj file
281
484
  file_name: The specific file(s) that were downloaded (None if entire repo was downloaded)
485
+ **kwargs: Additional metadata including plugin_id, model_name, model_type, device_id, min_sdk_version
282
486
 
283
487
  Returns:
284
488
  Dict containing the appropriate manifest format
285
489
  """
286
- model_type = detect_model_type(files)
490
+ model_type = detect_model_type(files, old_metadata)
287
491
 
288
492
  if model_type == "gguf":
289
- return create_gguf_manifest(repo_id, files, directory_path, old_metadata, is_mmproj, file_name)
493
+ return create_gguf_manifest(repo_id, files, directory_path, old_metadata, is_mmproj, file_name, **kwargs)
494
+ elif model_type == "npu":
495
+ return create_npu_manifest(repo_id, files, directory_path, old_metadata, is_mmproj, file_name, **kwargs)
290
496
  else: # mlx or other
291
- return create_mlx_manifest(repo_id, files, directory_path, old_metadata, is_mmproj, file_name)
497
+ return create_mlx_manifest(repo_id, files, directory_path, old_metadata, is_mmproj, file_name, **kwargs)
292
498
 
293
499
 
294
- def save_manifest_with_files_metadata(repo_id: str, local_dir: str, old_metadata: Dict[str, Any], is_mmproj: bool = False, file_name: Optional[Union[str, List[str]]] = None) -> None:
500
+ def save_manifest_with_files_metadata(repo_id: str, local_dir: str, old_metadata: Dict[str, Any], is_mmproj: bool = False, file_name: Optional[Union[str, List[str]]] = None, **kwargs) -> None:
295
501
  """
296
502
  Create and save manifest based on files found in the directory.
297
503
 
@@ -301,6 +507,7 @@ def save_manifest_with_files_metadata(repo_id: str, local_dir: str, old_metadata
301
507
  old_metadata: Existing metadata to preserve
302
508
  is_mmproj: Whether the downloaded file is an mmproj file
303
509
  file_name: The specific file(s) that were downloaded (None if entire repo was downloaded)
510
+ **kwargs: Additional metadata including plugin_id, model_name, model_type, device_id, min_sdk_version
304
511
  """
305
512
  # Get list of files in the directory
306
513
  files = []
@@ -314,7 +521,7 @@ def save_manifest_with_files_metadata(repo_id: str, local_dir: str, old_metadata
314
521
  pass
315
522
 
316
523
  # Create appropriate manifest
317
- manifest = create_manifest_from_files(repo_id, files, local_dir, old_metadata, is_mmproj, file_name)
524
+ manifest = create_manifest_from_files(repo_id, files, local_dir, old_metadata, is_mmproj, file_name, **kwargs)
318
525
 
319
526
  # Save manifest
320
527
  save_download_metadata(local_dir, manifest)
@@ -595,6 +595,7 @@ class HuggingFaceDownloader:
595
595
  self.enable_transfer = enable_transfer
596
596
  self.original_hf_transfer = None
597
597
  self.endpoint = endpoint # Store endpoint for avatar fetching
598
+ self._model_info_cache: Dict[str, Any] = {} # Cache for model_info results
598
599
 
599
600
  def _create_repo_directory(self, local_dir: str, repo_id: str) -> str:
600
601
  """Create a directory structure for the repository following HF convention."""
@@ -618,6 +619,32 @@ class HuggingFaceDownloader:
618
619
  os.makedirs(local_dir, exist_ok=True)
619
620
  return local_dir
620
621
 
622
+ def _get_model_info_cached(self, repo_id: str, files_metadata: bool = False):
623
+ """Get model info with caching to avoid rate limiting.
624
+
625
+ Args:
626
+ repo_id: Repository ID
627
+ files_metadata: Whether to include files metadata
628
+
629
+ Returns:
630
+ Model info object from HuggingFace API
631
+ """
632
+ # Create cache key based on repo_id and files_metadata flag
633
+ cache_key = f"{repo_id}:files={files_metadata}"
634
+
635
+ # Return cached result if available
636
+ if cache_key in self._model_info_cache:
637
+ return self._model_info_cache[cache_key]
638
+
639
+ # Fetch from API and cache the result
640
+ try:
641
+ info = self.api.model_info(repo_id, files_metadata=files_metadata, token=self.token)
642
+ self._model_info_cache[cache_key] = info
643
+ return info
644
+ except Exception:
645
+ # Don't cache errors, re-raise
646
+ raise
647
+
621
648
  def _get_repo_info_for_progress(
622
649
  self,
623
650
  repo_id: str,
@@ -625,7 +652,7 @@ class HuggingFaceDownloader:
625
652
  ) -> tuple[int, int]:
626
653
  """Get total repository size and file count for progress tracking."""
627
654
  try:
628
- info = self.api.model_info(repo_id, files_metadata=True, token=self.token)
655
+ info = self._get_model_info_cached(repo_id, files_metadata=True)
629
656
 
630
657
  total_size = 0
631
658
  file_count = 0
@@ -720,7 +747,7 @@ class HuggingFaceDownloader:
720
747
  ):
721
748
  """Validate repository exists and get info."""
722
749
  try:
723
- info = self.api.model_info(repo_id, token=self.token)
750
+ info = self._get_model_info_cached(repo_id, files_metadata=False)
724
751
  return info
725
752
  except RepositoryNotFoundError:
726
753
  error_msg = f"Repository '{repo_id}' not found. Please check the repository ID."
@@ -789,6 +816,36 @@ class HuggingFaceDownloader:
789
816
  # If no expected size, just check that file is not empty
790
817
  return os.path.getsize(file_path) > 0
791
818
 
819
+ def _extract_model_file_type_from_tags(self, repo_id: str) -> Optional[str]:
820
+ """Extract model file type from repo tags with priority: NPU > MLX > GGUF."""
821
+ try:
822
+ info = self._get_model_info_cached(repo_id, files_metadata=False)
823
+ if hasattr(info, 'tags') and info.tags:
824
+ # Convert tags to lowercase for case-insensitive matching
825
+ tags_lower = [tag.lower() for tag in info.tags]
826
+
827
+ # Check with priority: NPU > MLX > GGUF
828
+ if 'npu' in tags_lower:
829
+ return 'npu'
830
+ elif 'mlx' in tags_lower:
831
+ return 'mlx'
832
+ elif 'gguf' in tags_lower:
833
+ return 'gguf'
834
+ except Exception:
835
+ pass
836
+ return None
837
+
838
+ def _load_downloaded_manifest(self, local_dir: str) -> Dict[str, Any]:
839
+ """Load nexa.manifest from the downloaded repository if it exists."""
840
+ manifest_path = os.path.join(local_dir, 'nexa.manifest')
841
+ if os.path.exists(manifest_path):
842
+ try:
843
+ with open(manifest_path, 'r', encoding='utf-8') as f:
844
+ return json.load(f)
845
+ except (json.JSONDecodeError, IOError):
846
+ pass
847
+ return {}
848
+
792
849
  def _fetch_and_save_metadata(self, repo_id: str, local_dir: str, is_mmproj: bool = False, file_name: Optional[Union[str, List[str]]] = None, **kwargs) -> None:
793
850
  """Fetch model info and save metadata after successful download."""
794
851
  # Initialize metadata with defaults to ensure manifest is always created
@@ -800,8 +857,8 @@ class HuggingFaceDownloader:
800
857
 
801
858
  # Try to fetch additional metadata, but don't let failures prevent manifest creation
802
859
  try:
803
- # Fetch model info to get pipeline_tag
804
- info = self.api.model_info(repo_id, token=self.token)
860
+ # Fetch model info to get pipeline_tag (using cache)
861
+ info = self._get_model_info_cached(repo_id, files_metadata=False)
805
862
  if hasattr(info, 'pipeline_tag') and info.pipeline_tag:
806
863
  old_metadata['pipeline_tag'] = info.pipeline_tag
807
864
  except Exception as e:
@@ -810,11 +867,21 @@ class HuggingFaceDownloader:
810
867
 
811
868
  # Use input avater url if provided
812
869
  old_metadata['avatar_url'] = kwargs.get('avatar_url')
870
+
871
+ # Extract model file type from tags
872
+ model_file_type = self._extract_model_file_type_from_tags(repo_id)
873
+ if model_file_type:
874
+ old_metadata['model_file_type'] = model_file_type
875
+
876
+ # Load existing nexa.manifest from downloaded repo (if exists)
877
+ downloaded_manifest = self._load_downloaded_manifest(local_dir)
878
+ if downloaded_manifest:
879
+ old_metadata['downloaded_manifest'] = downloaded_manifest
813
880
 
814
881
 
815
882
  # CRITICAL: Always create the manifest file, regardless of metadata fetch failures
816
883
  try:
817
- save_manifest_with_files_metadata(repo_id, local_dir, old_metadata, is_mmproj, file_name)
884
+ save_manifest_with_files_metadata(repo_id, local_dir, old_metadata, is_mmproj, file_name, **kwargs)
818
885
  print(f"[OK] Successfully created nexa.manifest for {repo_id}")
819
886
  except Exception as e:
820
887
  # This is critical - if manifest creation fails, we should know about it
@@ -823,8 +890,11 @@ class HuggingFaceDownloader:
823
890
  try:
824
891
  minimal_manifest = {
825
892
  "Name": repo_id,
826
- "ModelType": "other",
827
- "PluginId": "unknown",
893
+ "ModelName": kwargs.get('model_name', ''),
894
+ "ModelType": kwargs.get('model_type', 'other'),
895
+ "PluginId": kwargs.get('plugin_id', 'unknown'),
896
+ "DeviceId": kwargs.get('device_id', ''),
897
+ "MinSDKVersion": kwargs.get('min_sdk_version', ''),
828
898
  "ModelFile": {},
829
899
  "MMProjFile": {"Name": "", "Downloaded": False, "Size": 0},
830
900
  "TokenizerFile": {"Name": "", "Downloaded": False, "Size": 0},
@@ -1136,6 +1206,12 @@ def download_from_huggingface(
1136
1206
  is_mmproj (bool, optional): Whether the file being downloaded is an mmproj file. Only used when
1137
1207
  file_name is not None. If None, defaults to True if 'mmproj' is in
1138
1208
  the filename, False otherwise.
1209
+ **kwargs: Additional parameters including:
1210
+ - plugin_id (str): Override PluginId in nexa.manifest (highest priority)
1211
+ - model_name (str): Override ModelName in nexa.manifest (highest priority)
1212
+ - model_type (str): Override ModelType in nexa.manifest (highest priority)
1213
+ - device_id (str): Set DeviceId in nexa.manifest (highest priority)
1214
+ - min_sdk_version (str): Set MinSDKVersion in nexa.manifest (highest priority)
1139
1215
 
1140
1216
  Returns:
1141
1217
  str: Path to the downloaded file or directory
@@ -1213,7 +1289,7 @@ def _download_model_if_needed(
1213
1289
  token: Union[bool, str, None] = None,
1214
1290
  is_mmproj: bool = False,
1215
1291
  **kwargs
1216
- ) -> str:
1292
+ ) -> tuple[str, Optional[str]]:
1217
1293
  """
1218
1294
  Helper function to download a model from HuggingFace if it doesn't exist locally.
1219
1295
 
@@ -1224,15 +1300,38 @@ def _download_model_if_needed(
1224
1300
  token: HuggingFace authentication token for private repositories
1225
1301
 
1226
1302
  Returns:
1227
- str: Local path to the model (either existing or downloaded)
1303
+ tuple[str, Optional[str]]: Tuple of (local_path, model_name)
1304
+ - local_path: Local path to the model (either existing or downloaded)
1305
+ - model_name: ModelName from nexa.manifest if available, None otherwise
1228
1306
 
1229
1307
  Raises:
1230
1308
  RuntimeError: If download fails
1231
1309
  """
1310
+ # Helper function to extract model_name from manifest
1311
+ def _extract_model_name_from_manifest(path: str) -> Optional[str]:
1312
+ """Extract ModelName from nexa.manifest if it exists."""
1313
+ # If path is a file, check its parent directory for manifest
1314
+ if os.path.isfile(path):
1315
+ manifest_dir = os.path.dirname(path)
1316
+ else:
1317
+ manifest_dir = path
1318
+
1319
+ manifest_path = os.path.join(manifest_dir, 'nexa.manifest')
1320
+ if not os.path.exists(manifest_path):
1321
+ return None
1322
+
1323
+ try:
1324
+ with open(manifest_path, 'r', encoding='utf-8') as f:
1325
+ manifest = json.load(f)
1326
+ return manifest.get('ModelName')
1327
+ except (json.JSONDecodeError, IOError):
1328
+ return None
1329
+
1232
1330
  # Check if model_path exists locally (file or directory)
1233
1331
  if os.path.exists(model_path):
1234
- # Local path exists, return as-is
1235
- return model_path
1332
+ # Local path exists, try to extract model_name
1333
+ model_name = _extract_model_name_from_manifest(model_path)
1334
+ return model_path, model_name
1236
1335
 
1237
1336
  # Model path doesn't exist locally, try to download from HuggingFace
1238
1337
  try:
@@ -1252,7 +1351,10 @@ def _download_model_if_needed(
1252
1351
  **kwargs
1253
1352
  )
1254
1353
 
1255
- return downloaded_path
1354
+ # Extract model_name from the downloaded manifest
1355
+ model_name = _extract_model_name_from_manifest(downloaded_path)
1356
+
1357
+ return downloaded_path, model_name
1256
1358
 
1257
1359
  except Exception as e:
1258
1360
  # Only handle download-related errors
@@ -1321,7 +1423,7 @@ def auto_download_model(func: Callable) -> Callable:
1321
1423
  # Download name_or_path if needed
1322
1424
  if name_or_path is not None:
1323
1425
  try:
1324
- downloaded_name_path = _download_model_if_needed(
1426
+ downloaded_name_path, model_name = _download_model_if_needed(
1325
1427
  name_or_path, 'name_or_path', progress_callback, token, **kwargs
1326
1428
  )
1327
1429
 
@@ -1332,6 +1434,10 @@ def auto_download_model(func: Callable) -> Callable:
1332
1434
  args = tuple(args_list)
1333
1435
  else:
1334
1436
  kwargs['name_or_path'] = downloaded_name_path
1437
+
1438
+ # Add model_name to kwargs if it exists and not already set
1439
+ if model_name is not None and 'model_name' not in kwargs:
1440
+ kwargs['model_name'] = model_name
1335
1441
 
1336
1442
  except Exception as e:
1337
1443
  raise e # Re-raise the error from _download_model_if_needed
@@ -1339,7 +1445,7 @@ def auto_download_model(func: Callable) -> Callable:
1339
1445
  # Download mmproj_path if needed
1340
1446
  if mmproj_path is not None:
1341
1447
  try:
1342
- downloaded_mmproj_path = _download_model_if_needed(
1448
+ downloaded_mmproj_path, _ = _download_model_if_needed(
1343
1449
  mmproj_path, 'mmproj_path', progress_callback, token, is_mmproj=True, **kwargs
1344
1450
  )
1345
1451
 
@@ -13,6 +13,8 @@ class ModelTypeMapping(Enum):
13
13
  """Enum for mapping HuggingFace pipeline_tag to our ModelType."""
14
14
  TEXT_GENERATION = ("text-generation", "llm")
15
15
  IMAGE_TEXT_TO_TEXT = ("image-text-to-text", "vlm")
16
+ ANY_TO_ANY = ("any-to-any", "ata")
17
+ AUTOMATIC_SPEECH_RECOGNITION = ("automatic-speech-recognition", "asr")
16
18
 
17
19
  def __init__(self, pipeline_tag: str, model_type: str):
18
20
  self.pipeline_tag = pipeline_tag
nexaai/vlm.py CHANGED
@@ -22,7 +22,8 @@ class VLM(BaseModel):
22
22
  model_name: Optional[str] = None,
23
23
  m_cfg: ModelConfig = ModelConfig(),
24
24
  plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
25
- device_id: Optional[str] = None
25
+ device_id: Optional[str] = None,
26
+ **kwargs
26
27
  ) -> 'VLM':
27
28
  """Load VLM model from local path, routing to appropriate implementation.
28
29
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nexaai
3
- Version: 1.0.17rc9
3
+ Version: 1.0.19
4
4
  Summary: Python bindings for NexaSDK C-lib backend
5
5
  Author-email: "Nexa AI, Inc." <dev@nexa.ai>
6
6
  Project-URL: Homepage, https://github.com/NexaAI/nexasdk-bridge
@@ -14,7 +14,6 @@ Requires-Python: >=3.7
14
14
  Description-Content-Type: text/markdown
15
15
  Requires-Dist: huggingface_hub
16
16
  Requires-Dist: tqdm
17
- Requires-Dist: hf_xet
18
17
  Requires-Dist: numpy
19
18
  Requires-Dist: httpx
20
19
  Provides-Extra: mlx
@@ -0,0 +1,76 @@
1
+ nexaai/__init__.py,sha256=mbzzeXrEHHI_E3BQ0_OukD9wNajKJJVk0ykxT0rz8uM,2267
2
+ nexaai/_stub.cp310-win_amd64.pyd,sha256=5dzEltIGjiUo03HnBGj-H8Im7YjeWrrpl8vUyj7gEQ4,10752
3
+ nexaai/_version.py,sha256=1EqJuyxDoSkEvRoBL8vxC0Ww_e-0l8BLCs6fquyOolY,143
4
+ nexaai/asr.py,sha256=eeFMFKsaEKiJ2PCGmgedRR4fTfrhaDcnZBuhCChMAio,2148
5
+ nexaai/base.py,sha256=qQBCiQVNzgpkQjZX9aiFDEdbAAe56TROKC3WnWra2Zg,1021
6
+ nexaai/common.py,sha256=muQqFY-WllwL5IO83tImexbuUcoEQsKg73u4gWL2lNs,3548
7
+ nexaai/cv.py,sha256=PhgqK5hO8FlXLR6QxE_pHtXjdtzLSEPzkCda-qrNpOs,3395
8
+ nexaai/embedder.py,sha256=NdYsmq--KGlLah11OJhhJe8rwAqO3mb-SxKEoRR9vXs,2534
9
+ nexaai/image_gen.py,sha256=_kLLCbvhc30a-YGidkB13ZXYoPOS-sKMo8bKVRkUado,4526
10
+ nexaai/llm.py,sha256=woB98NQmaNf3_BH0Ogig3niU1rcD8YtHPiSpzyrbVmo,3771
11
+ nexaai/log.py,sha256=F_Qe169kLbnFV25WJmS_ZtmBfOdcGic8BYFIsYVoD_o,2720
12
+ nexaai/rerank.py,sha256=26Fizy3YLoJmEswCU4IgG7Ka-NHcu79YZr4IBz1XDQ0,1957
13
+ nexaai/runtime.py,sha256=_BoAtTUv5ZR7wtOlJL5TldR3AZTP0OnMWjB9p71k-8E,2135
14
+ nexaai/tts.py,sha256=5lEzv50Q5iLTNHLg3kX-4J_mi1T_t-rVdZzOwd6sALY,2271
15
+ nexaai/vlm.py,sha256=bmdl215iIFhpFi3zloRkdym4j_z5BDbU6c981I80k-0,4890
16
+ nexaai/asr_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ nexaai/asr_impl/mlx_asr_impl.py,sha256=XwMX3LYMeulp8cDS0TCCYcjvttFHAyDWQ_oMvABwQmI,3349
18
+ nexaai/asr_impl/pybind_asr_impl.py,sha256=20o5SOPzhF9x41ra8L_qIM7YxCkYeLb5csSrNde-dds,1560
19
+ nexaai/binds/__init__.py,sha256=ENl-uoIF9-3XGIXitVgZ2QmJ6p7Yet4h1-X7nUDZ0Hk,108
20
+ nexaai/binds/common_bind.cp310-win_amd64.pyd,sha256=N7qfVNi48wmqhKJf1TIMhY0W6GZT14Fo97bQh7OFG40,205824
21
+ nexaai/binds/embedder_bind.cp310-win_amd64.pyd,sha256=mkx4LibQEUY_OP0cc333_Qv_JWHhn4vJc3z7mLGHD0o,182784
22
+ nexaai/binds/libcrypto-3-x64.dll,sha256=X7hDuQPMn6eRe58dTGJxTmRPKFWgd5i6Gjoy9QPLmPg,7315968
23
+ nexaai/binds/libssl-3-x64.dll,sha256=GRw0cOaGUaR2QHRvBFuU_9S9iNgkyVgm0NIpZMnReAw,1313792
24
+ nexaai/binds/llm_bind.cp310-win_amd64.pyd,sha256=lOusUjV5teUtAk-lq62Y8ha-IZQ__3cb7yA1Tx0BvbA,163840
25
+ nexaai/binds/nexa_bridge.dll,sha256=4x7QWF0PdfvUxf_DBsgac3Z2jZqPKvsNCHHDu0A79pg,187904
26
+ nexaai/binds/vlm_bind.cp310-win_amd64.pyd,sha256=ziwINHPBAwC2WkFOoU5EJOQfKEw3JUJeUZ-jDkkLQho,168960
27
+ nexaai/binds/cpu_gpu/ggml-base.dll,sha256=JBjHN894qYk8Izk0Lsl_aK5OrtU6s6pkVf-mNbE3dSY,532480
28
+ nexaai/binds/cpu_gpu/ggml-cpu.dll,sha256=ZoIgujpu9WwK0CJLnz4dlVuEuSKphj3wrR_w9AuCIp8,672768
29
+ nexaai/binds/cpu_gpu/ggml-cuda.dll,sha256=EDQMReypE0cQKj_mVT8UQ0kWRlf5mJ7S5duOuJLQ98w,313528832
30
+ nexaai/binds/cpu_gpu/ggml-vulkan.dll,sha256=UQSw_60Z-d3NtnQgJVORlm5BofWKafXKOT-L19Ayc78,36627968
31
+ nexaai/binds/cpu_gpu/ggml.dll,sha256=hvS-ukn4PDTZhc09MZ7r9mZuIu9q6fYS-rXQXH9ZiXw,66560
32
+ nexaai/binds/cpu_gpu/mtmd.dll,sha256=rLo4waw9B9UawaJUMhiDao-zH12m4QqIAxfW0gW9wC8,561152
33
+ nexaai/binds/cpu_gpu/nexa_cpu_gpu.dll,sha256=vFFvQp0pqV5blDrPs18ZgpCQ-owSwT1p8HTtf4pGa4M,1611776
34
+ nexaai/binds/cpu_gpu/nexa_plugin.dll,sha256=O_06Z508L4Ia0Cd-OCcrMJvfFWtn8zhrUv_hzOLp9qw,1411072
35
+ nexaai/binds/nexaml/ggml-base.dll,sha256=JBjHN894qYk8Izk0Lsl_aK5OrtU6s6pkVf-mNbE3dSY,532480
36
+ nexaai/binds/nexaml/ggml-cpu.dll,sha256=ZoIgujpu9WwK0CJLnz4dlVuEuSKphj3wrR_w9AuCIp8,672768
37
+ nexaai/binds/nexaml/ggml-cuda.dll,sha256=EDQMReypE0cQKj_mVT8UQ0kWRlf5mJ7S5duOuJLQ98w,313528832
38
+ nexaai/binds/nexaml/ggml-vulkan.dll,sha256=UQSw_60Z-d3NtnQgJVORlm5BofWKafXKOT-L19Ayc78,36627968
39
+ nexaai/binds/nexaml/ggml.dll,sha256=hvS-ukn4PDTZhc09MZ7r9mZuIu9q6fYS-rXQXH9ZiXw,66560
40
+ nexaai/binds/nexaml/nexa-mm-process.dll,sha256=DDD5qPbelZAIrRWGggOd3Pg9U_fh_ZEYIplwqiyD5LY,4643328
41
+ nexaai/binds/nexaml/nexa-sampling.dll,sha256=Notkz287laSUG2_ED3oFXWVLJM3t7x_USkvX6wKVOLA,4265984
42
+ nexaai/binds/nexaml/nexa_plugin.dll,sha256=DcIOfUjhXaOfB9SXIEJZMXdZWa12_VCswP3hWch7lVE,600576
43
+ nexaai/binds/nexaml/nexaproc.dll,sha256=cVU4ngSdsQ0MttqOv5IUZhmUE8lZLq-OjC8ueaAsx1s,2668544
44
+ nexaai/binds/nexaml/qwen3-vl.dll,sha256=say_RLwLsIq_svPlgqPl12gfrOCQtcCiwa_q91Ql7YM,5873152
45
+ nexaai/binds/nexaml/qwen3vl-vision.dll,sha256=5AX4MtAOWTcXSAkS2qqvl2pFti4HR55dtkCaOO03Evc,1063424
46
+ nexaai/cv_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
+ nexaai/cv_impl/mlx_cv_impl.py,sha256=QLd_8w90gtxH8kmssaDYatCTRvQNIJuUGKZNnYrmx6E,3317
48
+ nexaai/cv_impl/pybind_cv_impl.py,sha256=aSOCAxmHrwJbEkSN6VX3Cykqlj_9RIpVrZXILul04GA,1096
49
+ nexaai/embedder_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
+ nexaai/embedder_impl/mlx_embedder_impl.py,sha256=Kzd-veLNl95FbI2oEJMtr6qKbjtPDDajzsGUVjJfTRA,4598
51
+ nexaai/embedder_impl/pybind_embedder_impl.py,sha256=eH2L--L6BAl-46UOzm84pfjIkJtQKVd63-r62eb0Vg0,3670
52
+ nexaai/image_gen_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
+ nexaai/image_gen_impl/mlx_image_gen_impl.py,sha256=peUE9ue9ApaPlZVOICBWiHtd13sY40OWQbE8EjfIUMU,11511
54
+ nexaai/image_gen_impl/pybind_image_gen_impl.py,sha256=514RFQMSO0Rhacq0IYzlEhEr6QfaprnGew0Rjz8HZI4,3777
55
+ nexaai/llm_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
+ nexaai/llm_impl/mlx_llm_impl.py,sha256=qJY0zwb6jfVFQnTsp1W7BDnIMdgcJlqnU5UJgSoU-Vs,11567
57
+ nexaai/llm_impl/pybind_llm_impl.py,sha256=zzZZ2FovnNn9EJxjovNhLI_SDjt3MAXMi8jsR6N57Ng,8359
58
+ nexaai/rerank_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
+ nexaai/rerank_impl/mlx_rerank_impl.py,sha256=x8L6zCccV2I4bq4V5zAOcrWFe5Ckle7z5J_00tao8bI,3335
60
+ nexaai/rerank_impl/pybind_rerank_impl.py,sha256=1IW925bYv4FRwZDNzf9epEzdDqR6T3OONgTLBd-cOn8,1556
61
+ nexaai/tts_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
+ nexaai/tts_impl/mlx_tts_impl.py,sha256=LcH9bVdIl3Q6lOzSUB_X2s-_nWFmlCl1yL7XSUK0fYI,3195
63
+ nexaai/tts_impl/pybind_tts_impl.py,sha256=n3z4zmPQayQJgAwcvETw0IBUCp8IYROuYFSg0tAy_8Y,1487
64
+ nexaai/utils/decode.py,sha256=0Z9jDH4ICzw4YXj8nD4L-sMouDaev-TISGRQ4KzidWE,421
65
+ nexaai/utils/manifest_utils.py,sha256=E07t_bNq-EDrqVYZW7uyX8zsKsFklvqqwSvic0in0tQ,21800
66
+ nexaai/utils/model_manager.py,sha256=BBtScKRPXSSJDhoeHePB_bucjC4dXHjxnYHSR4EPyx4,62488
67
+ nexaai/utils/model_types.py,sha256=q2m7diYLOpLvRl1ixL2eMq5_kdTj8KqPBGWX4p6Ob08,1532
68
+ nexaai/utils/progress_tracker.py,sha256=BztrFqtjwNUmeREwZ5m7H6ZcrVzQEbpZfsxndWh4z0A,15778
69
+ nexaai/utils/quantization_utils.py,sha256=FxnZ6-uAE_bl_vQ5jsRXlpU0NBn-U4Y8iN9_O6aCdPA,8070
70
+ nexaai/vlm_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
+ nexaai/vlm_impl/mlx_vlm_impl.py,sha256=MgqJO7OzuPd79gOZZKhSXXMNSP2eBuhhrdCX8XHn6aQ,11090
72
+ nexaai/vlm_impl/pybind_vlm_impl.py,sha256=NuQ_Ep1TnjmGAkjJuUS0Lb6z7iPu3wroLVOx7kiAwlE,8827
73
+ nexaai-1.0.19.dist-info/METADATA,sha256=0IRxAP_axX6ofVihQYA_qWLx8vF0zON-0OdoVbePPy4,1207
74
+ nexaai-1.0.19.dist-info/WHEEL,sha256=KUuBC6lxAbHCKilKua8R9W_TM71_-9Sg5uEP3uDWcoU,101
75
+ nexaai-1.0.19.dist-info/top_level.txt,sha256=LRE2YERlrZk2vfuygnSzsEeqSknnZbz3Z1MHyNmBU4w,7
76
+ nexaai-1.0.19.dist-info/RECORD,,
Binary file
Binary file
Binary file
@@ -1,76 +0,0 @@
1
- nexaai/__init__.py,sha256=mbzzeXrEHHI_E3BQ0_OukD9wNajKJJVk0ykxT0rz8uM,2267
2
- nexaai/_stub.cp310-win_amd64.pyd,sha256=ceSj-sc3ptDA4NQBrP0EkcvUmCoqnyARwOxjyZdlVt0,10752
3
- nexaai/_version.py,sha256=WXmF66x0dmzVLa6Qm6qe9msuViXrfu6n7ujttHcRaQg,147
4
- nexaai/asr.py,sha256=_fsGaxpiU137bUtO5ujtFSYCI1RLsyeEm3Gf4GhHVRk,2118
5
- nexaai/base.py,sha256=qQBCiQVNzgpkQjZX9aiFDEdbAAe56TROKC3WnWra2Zg,1021
6
- nexaai/common.py,sha256=muQqFY-WllwL5IO83tImexbuUcoEQsKg73u4gWL2lNs,3548
7
- nexaai/cv.py,sha256=a6-csgYNDzPziJ0EojE9-BeM_xCny4UvWWbpnJ7GL-A,3365
8
- nexaai/embedder.py,sha256=3a81s7JapvYxCRbWPFKp_9EWBKW7WYqF03gk87YuGKU,2524
9
- nexaai/image_gen.py,sha256=4iASOKxJosMznLarTvOxJQDNaas251O81bfUWJTUBfE,4496
10
- nexaai/llm.py,sha256=Qwm1q_NStLfD-JYZQIvxniWnAmwNl1V6LUON3Me7w_I,3663
11
- nexaai/log.py,sha256=F_Qe169kLbnFV25WJmS_ZtmBfOdcGic8BYFIsYVoD_o,2720
12
- nexaai/rerank.py,sha256=_zGWmX6eDigY2kViMKCtNssp4JMEeVycZZfJH9eAZOY,1927
13
- nexaai/runtime.py,sha256=_BoAtTUv5ZR7wtOlJL5TldR3AZTP0OnMWjB9p71k-8E,2135
14
- nexaai/tts.py,sha256=afs6sx0w0Tvs_aJlyZRPm62qQpTrs-fW_jDHrMkc4AA,2241
15
- nexaai/vlm.py,sha256=wUMbRURluxvULbS7vgyHsWdEPgLGrrC_S79bhdEN7Vg,4860
16
- nexaai/asr_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- nexaai/asr_impl/mlx_asr_impl.py,sha256=XwMX3LYMeulp8cDS0TCCYcjvttFHAyDWQ_oMvABwQmI,3349
18
- nexaai/asr_impl/pybind_asr_impl.py,sha256=20o5SOPzhF9x41ra8L_qIM7YxCkYeLb5csSrNde-dds,1560
19
- nexaai/binds/__init__.py,sha256=ENl-uoIF9-3XGIXitVgZ2QmJ6p7Yet4h1-X7nUDZ0Hk,108
20
- nexaai/binds/common_bind.cp310-win_amd64.pyd,sha256=5Tix3pQanZtjtpKkP61ffawmNWewXcBYCjhFFhAqoCU,205824
21
- nexaai/binds/embedder_bind.cp310-win_amd64.pyd,sha256=BK-floyPQQuCg3Ixbi6Dl54iEWk6-R2RX5nfMJSfCdk,182784
22
- nexaai/binds/libcrypto-3-x64.dll,sha256=TAWcTdJrWviUingNyWaraOfz0ILUy7ybpI4VaiVHURg,7315968
23
- nexaai/binds/libssl-3-x64.dll,sha256=ZxawOWlONNM0Neg47w4JbU8kZJldj046H1zV3LiETa0,1313792
24
- nexaai/binds/llm_bind.cp310-win_amd64.pyd,sha256=q_rFOC-8d2LWic4SCCkJtNOfOQVdMI3Q0Flj9zLSEeQ,162816
25
- nexaai/binds/nexa_bridge.dll,sha256=VDz1HILMgloBFa-C5S2JmLbNZL7O1buLvNpSTWyCFAo,171008
26
- nexaai/binds/vlm_bind.cp310-win_amd64.pyd,sha256=VDaTHpuV2S97XMFHmTqPlEI0Flq6u5s3g0bSwZ5ViPE,168960
27
- nexaai/binds/nexa_llama_cpp/ggml-base.dll,sha256=itL13J0fh7MIzE9ZTcR4UmDAS018r12PVYpop6i7PlA,532480
28
- nexaai/binds/nexa_llama_cpp/ggml-cpu.dll,sha256=3t1tCZad7gAvyKYaW9cbQ4CJb7P2U0_Kab1Smtd0P9s,672768
29
- nexaai/binds/nexa_llama_cpp/ggml-cuda.dll,sha256=-LHsflgA9GRIkbBinD8Kmlux7DeGpuhjitSLX1R2E9c,313528832
30
- nexaai/binds/nexa_llama_cpp/ggml-vulkan.dll,sha256=vlZ0b6LV8ZqE6CGPNBWk_XqkgqIZN4ch4OL5SRld0D8,36627456
31
- nexaai/binds/nexa_llama_cpp/ggml.dll,sha256=8cdUzL8ppC6iz0nkESnxoIMX6Mtu4jfdTU3cGjacfF8,66560
32
- nexaai/binds/nexa_llama_cpp/llama.dll,sha256=yqq5h0w26rTVIdhpeduB0F9mfJDl6uibFcFKKu_DIyo,1611776
33
- nexaai/binds/nexa_llama_cpp/mtmd.dll,sha256=dAs6RQwSYxWuQQW_a1dG7ugUC9kLWeP--_t-Dj3oe6o,561152
34
- nexaai/binds/nexa_llama_cpp/nexa_plugin.dll,sha256=HuKy-Z-rNbcxHgBK8jSELWTVDiXW0CIUZTjQ4BDy-nE,1413120
35
- nexaai/binds/nexa_nexaml/ggml-base.dll,sha256=itL13J0fh7MIzE9ZTcR4UmDAS018r12PVYpop6i7PlA,532480
36
- nexaai/binds/nexa_nexaml/ggml-cpu.dll,sha256=3t1tCZad7gAvyKYaW9cbQ4CJb7P2U0_Kab1Smtd0P9s,672768
37
- nexaai/binds/nexa_nexaml/ggml-cuda.dll,sha256=-LHsflgA9GRIkbBinD8Kmlux7DeGpuhjitSLX1R2E9c,313528832
38
- nexaai/binds/nexa_nexaml/ggml-vulkan.dll,sha256=vlZ0b6LV8ZqE6CGPNBWk_XqkgqIZN4ch4OL5SRld0D8,36627456
39
- nexaai/binds/nexa_nexaml/ggml.dll,sha256=8cdUzL8ppC6iz0nkESnxoIMX6Mtu4jfdTU3cGjacfF8,66560
40
- nexaai/binds/nexa_nexaml/nexa-mm-process.dll,sha256=oDnqTaAUeZrWJePQEDuIYKEOMP-ndu221mMFHht4bSY,4642816
41
- nexaai/binds/nexa_nexaml/nexa-sampling.dll,sha256=PNtidsRbGO8dTfbf7-VMdhQRbF328yvLnmDjMy2Tb7Y,4265984
42
- nexaai/binds/nexa_nexaml/nexa_plugin.dll,sha256=j0VR1s0Pz25CeK_XjbQc8FaUS994eNeigqmqryakis8,602112
43
- nexaai/binds/nexa_nexaml/nexaproc.dll,sha256=9X4TF6p7wOiIXi_SA7uHLoEmrvcTlH2WpfijK7HxZgY,2668544
44
- nexaai/binds/nexa_nexaml/qwen3-vl.dll,sha256=Es-etUDiMmK_BwOki8V79Nja-NY4kBbrkhtnesXfMMU,5870592
45
- nexaai/binds/nexa_nexaml/qwen3vl-vision.dll,sha256=HFAk0FxWlf_lko3AQL6uBXTIhm6AzDFi5PjxI0lxONI,1184256
46
- nexaai/cv_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
- nexaai/cv_impl/mlx_cv_impl.py,sha256=QLd_8w90gtxH8kmssaDYatCTRvQNIJuUGKZNnYrmx6E,3317
48
- nexaai/cv_impl/pybind_cv_impl.py,sha256=aSOCAxmHrwJbEkSN6VX3Cykqlj_9RIpVrZXILul04GA,1096
49
- nexaai/embedder_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
- nexaai/embedder_impl/mlx_embedder_impl.py,sha256=Kzd-veLNl95FbI2oEJMtr6qKbjtPDDajzsGUVjJfTRA,4598
51
- nexaai/embedder_impl/pybind_embedder_impl.py,sha256=eH2L--L6BAl-46UOzm84pfjIkJtQKVd63-r62eb0Vg0,3670
52
- nexaai/image_gen_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
- nexaai/image_gen_impl/mlx_image_gen_impl.py,sha256=peUE9ue9ApaPlZVOICBWiHtd13sY40OWQbE8EjfIUMU,11511
54
- nexaai/image_gen_impl/pybind_image_gen_impl.py,sha256=514RFQMSO0Rhacq0IYzlEhEr6QfaprnGew0Rjz8HZI4,3777
55
- nexaai/llm_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
- nexaai/llm_impl/mlx_llm_impl.py,sha256=r9Qa1ZuduRAcRjmqo2J_zlqhprVPe3ioZtUbi7yIvYY,11426
57
- nexaai/llm_impl/pybind_llm_impl.py,sha256=s2Cb035xDbh1ZhGNys0LRtAR6b6n4-YVKSC5voD4_Tk,8269
58
- nexaai/rerank_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
- nexaai/rerank_impl/mlx_rerank_impl.py,sha256=x8L6zCccV2I4bq4V5zAOcrWFe5Ckle7z5J_00tao8bI,3335
60
- nexaai/rerank_impl/pybind_rerank_impl.py,sha256=1IW925bYv4FRwZDNzf9epEzdDqR6T3OONgTLBd-cOn8,1556
61
- nexaai/tts_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
- nexaai/tts_impl/mlx_tts_impl.py,sha256=LcH9bVdIl3Q6lOzSUB_X2s-_nWFmlCl1yL7XSUK0fYI,3195
63
- nexaai/tts_impl/pybind_tts_impl.py,sha256=n3z4zmPQayQJgAwcvETw0IBUCp8IYROuYFSg0tAy_8Y,1487
64
- nexaai/utils/decode.py,sha256=0Z9jDH4ICzw4YXj8nD4L-sMouDaev-TISGRQ4KzidWE,421
65
- nexaai/utils/manifest_utils.py,sha256=OyLi9e4JrOBunswf4FG2KoVvkbv2FulkOf5LqRDVf50,12979
66
- nexaai/utils/model_manager.py,sha256=bWMVvcBu5dC3YmWtsJK4C3IaXfaDSByAYcH7GVLtoEg,57334
67
- nexaai/utils/model_types.py,sha256=arIyb9q-1uG0nyUGdWZaxxDJAxv0cfnJEpjCzyELL5Q,1416
68
- nexaai/utils/progress_tracker.py,sha256=BztrFqtjwNUmeREwZ5m7H6ZcrVzQEbpZfsxndWh4z0A,15778
69
- nexaai/utils/quantization_utils.py,sha256=FxnZ6-uAE_bl_vQ5jsRXlpU0NBn-U4Y8iN9_O6aCdPA,8070
70
- nexaai/vlm_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
- nexaai/vlm_impl/mlx_vlm_impl.py,sha256=MgqJO7OzuPd79gOZZKhSXXMNSP2eBuhhrdCX8XHn6aQ,11090
72
- nexaai/vlm_impl/pybind_vlm_impl.py,sha256=NuQ_Ep1TnjmGAkjJuUS0Lb6z7iPu3wroLVOx7kiAwlE,8827
73
- nexaai-1.0.17rc9.dist-info/METADATA,sha256=UDHEOOf9isWWOBY3kBn-K4D0mlx9Dilhm-5PWM2D1Jw,1233
74
- nexaai-1.0.17rc9.dist-info/WHEEL,sha256=KUuBC6lxAbHCKilKua8R9W_TM71_-9Sg5uEP3uDWcoU,101
75
- nexaai-1.0.17rc9.dist-info/top_level.txt,sha256=LRE2YERlrZk2vfuygnSzsEeqSknnZbz3Z1MHyNmBU4w,7
76
- nexaai-1.0.17rc9.dist-info/RECORD,,