nexaai 1.0.4rc15__cp310-cp310-win_amd64.whl → 1.0.5__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.
- nexaai/__init__.py +6 -1
- nexaai/_stub.cp310-win_amd64.pyd +0 -0
- nexaai/_version.py +1 -1
- nexaai/asr.py +7 -3
- nexaai/asr_impl/mlx_asr_impl.py +3 -2
- nexaai/asr_impl/pybind_asr_impl.py +3 -2
- nexaai/binds/common_bind.cp310-win_amd64.pyd +0 -0
- nexaai/binds/embedder_bind.cp310-win_amd64.pyd +0 -0
- nexaai/binds/libcrypto-3-x64.dll +0 -0
- nexaai/binds/libssl-3-x64.dll +0 -0
- nexaai/binds/llm_bind.cp310-win_amd64.pyd +0 -0
- nexaai/binds/nexa_bridge.dll +0 -0
- nexaai/binds/nexa_llama_cpp/ggml-base.dll +0 -0
- nexaai/binds/nexa_llama_cpp/ggml-cpu.dll +0 -0
- nexaai/binds/nexa_llama_cpp/ggml-cuda.dll +0 -0
- nexaai/binds/nexa_llama_cpp/ggml-vulkan.dll +0 -0
- nexaai/binds/nexa_llama_cpp/ggml.dll +0 -0
- nexaai/binds/nexa_llama_cpp/llama.dll +0 -0
- nexaai/binds/nexa_llama_cpp/mtmd.dll +0 -0
- nexaai/binds/nexa_llama_cpp/nexa_plugin.dll +0 -0
- nexaai/common.py +49 -7
- nexaai/cv.py +7 -3
- nexaai/cv_impl/mlx_cv_impl.py +3 -2
- nexaai/cv_impl/pybind_cv_impl.py +3 -2
- nexaai/embedder.py +7 -3
- nexaai/embedder_impl/mlx_embedder_impl.py +3 -2
- nexaai/embedder_impl/pybind_embedder_impl.py +6 -3
- nexaai/image_gen.py +6 -2
- nexaai/image_gen_impl/mlx_image_gen_impl.py +3 -2
- nexaai/image_gen_impl/pybind_image_gen_impl.py +3 -2
- nexaai/llm.py +13 -6
- nexaai/llm_impl/mlx_llm_impl.py +26 -6
- nexaai/llm_impl/pybind_llm_impl.py +17 -6
- nexaai/rerank.py +7 -3
- nexaai/rerank_impl/mlx_rerank_impl.py +3 -2
- nexaai/rerank_impl/pybind_rerank_impl.py +3 -2
- nexaai/tts.py +7 -3
- nexaai/tts_impl/mlx_tts_impl.py +3 -2
- nexaai/tts_impl/pybind_tts_impl.py +3 -2
- nexaai/vlm.py +11 -4
- nexaai/vlm_impl/mlx_vlm_impl.py +10 -3
- nexaai/vlm_impl/pybind_vlm_impl.py +15 -4
- {nexaai-1.0.4rc15.dist-info → nexaai-1.0.5.dist-info}/METADATA +13 -9
- nexaai-1.0.5.dist-info/RECORD +61 -0
- nexaai-1.0.4rc15.dist-info/RECORD +0 -59
- {nexaai-1.0.4rc15.dist-info → nexaai-1.0.5.dist-info}/WHEEL +0 -0
- {nexaai-1.0.4rc15.dist-info → nexaai-1.0.5.dist-info}/top_level.txt +0 -0
nexaai/__init__.py
CHANGED
|
@@ -19,7 +19,10 @@ except ImportError:
|
|
|
19
19
|
__version__ = "0.0.1"
|
|
20
20
|
|
|
21
21
|
# Import common configuration classes first (no external dependencies)
|
|
22
|
-
from .common import ModelConfig, GenerationConfig, ChatMessage, SamplerConfig
|
|
22
|
+
from .common import ModelConfig, GenerationConfig, ChatMessage, SamplerConfig, PluginID
|
|
23
|
+
|
|
24
|
+
# Create alias for PluginID to be accessible as plugin_id
|
|
25
|
+
plugin_id = PluginID
|
|
23
26
|
|
|
24
27
|
# Import new feature classes (no external dependencies in base classes)
|
|
25
28
|
from .llm import LLM
|
|
@@ -40,6 +43,8 @@ __all__ = [
|
|
|
40
43
|
"ChatMessage",
|
|
41
44
|
"SamplerConfig",
|
|
42
45
|
"EmbeddingConfig",
|
|
46
|
+
"PluginID",
|
|
47
|
+
"plugin_id",
|
|
43
48
|
|
|
44
49
|
"LLM",
|
|
45
50
|
"Embedder",
|
nexaai/_stub.cp310-win_amd64.pyd
CHANGED
|
Binary file
|
nexaai/_version.py
CHANGED
nexaai/asr.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
from typing import List, Optional, Sequence, Tuple
|
|
1
|
+
from typing import List, Optional, Sequence, Tuple, Union
|
|
2
2
|
from abc import abstractmethod
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
|
|
5
5
|
from nexaai.base import BaseModel
|
|
6
|
+
from nexaai.common import PluginID
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
@dataclass
|
|
@@ -33,11 +34,14 @@ class ASR(BaseModel):
|
|
|
33
34
|
model_path: str,
|
|
34
35
|
tokenizer_path: Optional[str] = None,
|
|
35
36
|
language: Optional[str] = None,
|
|
36
|
-
plugin_id: str =
|
|
37
|
+
plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
|
|
37
38
|
device_id: Optional[str] = None
|
|
38
39
|
) -> 'ASR':
|
|
39
40
|
"""Load ASR model from local path, routing to appropriate implementation."""
|
|
40
|
-
|
|
41
|
+
# Check plugin_id value for routing - handle both enum and string
|
|
42
|
+
plugin_value = plugin_id.value if isinstance(plugin_id, PluginID) else plugin_id
|
|
43
|
+
|
|
44
|
+
if plugin_value == "mlx":
|
|
41
45
|
from nexaai.asr_impl.mlx_asr_impl import MLXASRImpl
|
|
42
46
|
return MLXASRImpl._load_from(model_path, tokenizer_path, language, plugin_id, device_id)
|
|
43
47
|
else:
|
nexaai/asr_impl/mlx_asr_impl.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Note: This code is generated by Cursor, not tested yet.
|
|
2
2
|
|
|
3
|
-
from typing import List, Optional
|
|
3
|
+
from typing import List, Optional, Union
|
|
4
4
|
|
|
5
|
+
from nexaai.common import PluginID
|
|
5
6
|
from nexaai.asr import ASR, ASRConfig, ASRResult
|
|
6
7
|
from nexaai.mlx_backend.asr.interface import MlxAsr as MLXASRInterface
|
|
7
8
|
from nexaai.mlx_backend.ml import ModelConfig as MLXModelConfig, SamplerConfig as MLXSamplerConfig, GenerationConfig as MLXGenerationConfig, EmbeddingConfig
|
|
@@ -18,7 +19,7 @@ class MLXASRImpl(ASR):
|
|
|
18
19
|
model_path: str,
|
|
19
20
|
tokenizer_path: Optional[str] = None,
|
|
20
21
|
language: Optional[str] = None,
|
|
21
|
-
plugin_id: str =
|
|
22
|
+
plugin_id: Union[PluginID, str] = PluginID.MLX,
|
|
22
23
|
device_id: Optional[str] = None
|
|
23
24
|
) -> 'MLXASRImpl':
|
|
24
25
|
"""Load ASR model from local path using MLX backend."""
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
from typing import List, Optional
|
|
1
|
+
from typing import List, Optional, Union
|
|
2
2
|
|
|
3
|
+
from nexaai.common import PluginID
|
|
3
4
|
from nexaai.asr import ASR, ASRConfig, ASRResult
|
|
4
5
|
|
|
5
6
|
|
|
@@ -14,7 +15,7 @@ class PyBindASRImpl(ASR):
|
|
|
14
15
|
model_path: str,
|
|
15
16
|
tokenizer_path: Optional[str] = None,
|
|
16
17
|
language: Optional[str] = None,
|
|
17
|
-
plugin_id: str =
|
|
18
|
+
plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
|
|
18
19
|
device_id: Optional[str] = None
|
|
19
20
|
) -> 'PyBindASRImpl':
|
|
20
21
|
"""Load ASR model from local path using PyBind backend."""
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
nexaai/binds/nexa_bridge.dll
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
nexaai/common.py
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from typing import TypedDict, Literal, Optional, List
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class PluginID(str, Enum):
|
|
7
|
+
"""Enum for plugin identifiers."""
|
|
8
|
+
MLX = "mlx"
|
|
9
|
+
LLAMA_CPP = "llama_cpp"
|
|
3
10
|
|
|
4
11
|
|
|
5
12
|
class ChatMessage(TypedDict):
|
|
@@ -52,10 +59,45 @@ class ModelConfig:
|
|
|
52
59
|
|
|
53
60
|
@dataclass(frozen=True) # Read-only
|
|
54
61
|
class ProfilingData:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
"""Profiling data structure for LLM/VLM performance metrics."""
|
|
63
|
+
ttft: int = 0 # Time to first token (us)
|
|
64
|
+
prompt_time: int = 0 # Prompt processing time (us)
|
|
65
|
+
decode_time: int = 0 # Token generation time (us)
|
|
66
|
+
prompt_tokens: int = 0 # Number of prompt tokens
|
|
67
|
+
generated_tokens: int = 0 # Number of generated tokens
|
|
68
|
+
audio_duration: int = 0 # Audio duration (us)
|
|
69
|
+
prefill_speed: float = 0.0 # Prefill speed (tokens/sec)
|
|
70
|
+
decoding_speed: float = 0.0 # Decoding speed (tokens/sec)
|
|
71
|
+
real_time_factor: float = 0.0 # Real-Time Factor (RTF)
|
|
72
|
+
stop_reason: str = "" # Stop reason: "eos", "length", "user", "stop_sequence"
|
|
73
|
+
|
|
74
|
+
@classmethod
|
|
75
|
+
def from_dict(cls, data: dict) -> "ProfilingData":
|
|
76
|
+
"""Create ProfilingData from dictionary."""
|
|
77
|
+
return cls(
|
|
78
|
+
ttft=data.get("ttft", 0),
|
|
79
|
+
prompt_time=data.get("prompt_time", 0),
|
|
80
|
+
decode_time=data.get("decode_time", 0),
|
|
81
|
+
prompt_tokens=data.get("prompt_tokens", 0),
|
|
82
|
+
generated_tokens=data.get("generated_tokens", 0),
|
|
83
|
+
audio_duration=data.get("audio_duration", 0),
|
|
84
|
+
prefill_speed=data.get("prefill_speed", 0.0),
|
|
85
|
+
decoding_speed=data.get("decoding_speed", 0.0),
|
|
86
|
+
real_time_factor=data.get("real_time_factor", 0.0),
|
|
87
|
+
stop_reason=data.get("stop_reason", "")
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
def to_dict(self) -> dict:
|
|
91
|
+
"""Convert to dictionary."""
|
|
92
|
+
return {
|
|
93
|
+
"ttft": self.ttft,
|
|
94
|
+
"prompt_time": self.prompt_time,
|
|
95
|
+
"decode_time": self.decode_time,
|
|
96
|
+
"prompt_tokens": self.prompt_tokens,
|
|
97
|
+
"generated_tokens": self.generated_tokens,
|
|
98
|
+
"audio_duration": self.audio_duration,
|
|
99
|
+
"prefill_speed": self.prefill_speed,
|
|
100
|
+
"decoding_speed": self.decoding_speed,
|
|
101
|
+
"real_time_factor": self.real_time_factor,
|
|
102
|
+
"stop_reason": self.stop_reason
|
|
103
|
+
}
|
nexaai/cv.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
from typing import List, Optional
|
|
1
|
+
from typing import List, Optional, Union
|
|
2
2
|
from abc import abstractmethod
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
|
|
5
5
|
from nexaai.base import BaseModel
|
|
6
|
+
from nexaai.common import PluginID
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
@dataclass
|
|
@@ -71,11 +72,14 @@ class CVModel(BaseModel):
|
|
|
71
72
|
def _load_from(cls,
|
|
72
73
|
_: str, # TODO: remove this argument, this is a hack to make api design happy
|
|
73
74
|
config: CVModelConfig,
|
|
74
|
-
plugin_id: str =
|
|
75
|
+
plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
|
|
75
76
|
device_id: Optional[str] = None
|
|
76
77
|
) -> 'CVModel':
|
|
77
78
|
"""Load CV model from configuration, routing to appropriate implementation."""
|
|
78
|
-
|
|
79
|
+
# Check plugin_id value for routing - handle both enum and string
|
|
80
|
+
plugin_value = plugin_id.value if isinstance(plugin_id, PluginID) else plugin_id
|
|
81
|
+
|
|
82
|
+
if plugin_value == "mlx":
|
|
79
83
|
from nexaai.cv_impl.mlx_cv_impl import MLXCVImpl
|
|
80
84
|
return MLXCVImpl._load_from(config, plugin_id, device_id)
|
|
81
85
|
else:
|
nexaai/cv_impl/mlx_cv_impl.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Note: This code is generated by Cursor, not tested yet.
|
|
2
2
|
|
|
3
|
-
from typing import Optional
|
|
3
|
+
from typing import Optional, Union
|
|
4
4
|
import os
|
|
5
5
|
|
|
6
|
+
from nexaai.common import PluginID
|
|
6
7
|
from nexaai.cv import CVModel, CVModelConfig, CVResults
|
|
7
8
|
from nexaai.mlx_backend.cv.interface import CVModel as MLXCVInterface, create_cv_model
|
|
8
9
|
|
|
@@ -16,7 +17,7 @@ class MLXCVImpl(CVModel):
|
|
|
16
17
|
@classmethod
|
|
17
18
|
def _load_from(cls,
|
|
18
19
|
config: CVModelConfig,
|
|
19
|
-
plugin_id: str =
|
|
20
|
+
plugin_id: Union[PluginID, str] = PluginID.MLX,
|
|
20
21
|
device_id: Optional[str] = None
|
|
21
22
|
) -> 'MLXCVImpl':
|
|
22
23
|
"""Load CV model from configuration using MLX backend."""
|
nexaai/cv_impl/pybind_cv_impl.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
from typing import Optional
|
|
1
|
+
from typing import Optional, Union
|
|
2
2
|
|
|
3
|
+
from nexaai.common import PluginID
|
|
3
4
|
from nexaai.cv import CVModel, CVModelConfig, CVResults
|
|
4
5
|
|
|
5
6
|
|
|
@@ -12,7 +13,7 @@ class PyBindCVImpl(CVModel):
|
|
|
12
13
|
@classmethod
|
|
13
14
|
def _load_from(cls,
|
|
14
15
|
config: CVModelConfig,
|
|
15
|
-
plugin_id: str =
|
|
16
|
+
plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
|
|
16
17
|
device_id: Optional[str] = None
|
|
17
18
|
) -> 'PyBindCVImpl':
|
|
18
19
|
"""Load CV model from configuration using PyBind backend."""
|
nexaai/embedder.py
CHANGED
|
@@ -4,6 +4,7 @@ from abc import abstractmethod
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
|
|
6
6
|
from nexaai.base import BaseModel
|
|
7
|
+
from nexaai.common import PluginID
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
@dataclass
|
|
@@ -21,19 +22,22 @@ class Embedder(BaseModel):
|
|
|
21
22
|
pass
|
|
22
23
|
|
|
23
24
|
@classmethod
|
|
24
|
-
def _load_from(cls, model_path: str, tokenizer_file: str = "tokenizer.json", plugin_id: str =
|
|
25
|
+
def _load_from(cls, model_path: str, tokenizer_file: str = "tokenizer.json", plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP):
|
|
25
26
|
"""
|
|
26
27
|
Load an embedder from model files, routing to appropriate implementation.
|
|
27
28
|
|
|
28
29
|
Args:
|
|
29
30
|
model_path: Path to the model file
|
|
30
31
|
tokenizer_file: Path to the tokenizer file (default: "tokenizer.json")
|
|
31
|
-
plugin_id: Plugin ID to use for the model (default:
|
|
32
|
+
plugin_id: Plugin ID to use for the model (default: PluginID.LLAMA_CPP)
|
|
32
33
|
|
|
33
34
|
Returns:
|
|
34
35
|
Embedder instance
|
|
35
36
|
"""
|
|
36
|
-
|
|
37
|
+
# Check plugin_id value for routing - handle both enum and string
|
|
38
|
+
plugin_value = plugin_id.value if isinstance(plugin_id, PluginID) else plugin_id
|
|
39
|
+
|
|
40
|
+
if plugin_value == "mlx":
|
|
37
41
|
from nexaai.embedder_impl.mlx_embedder_impl import MLXEmbedderImpl
|
|
38
42
|
return MLXEmbedderImpl._load_from(model_path, tokenizer_file, plugin_id)
|
|
39
43
|
else:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import List, Union
|
|
2
2
|
import numpy as np
|
|
3
3
|
|
|
4
|
+
from nexaai.common import PluginID
|
|
4
5
|
from nexaai.embedder import Embedder, EmbeddingConfig
|
|
5
6
|
from nexaai.mlx_backend.embedding.interface import Embedder as MLXEmbedderInterface
|
|
6
7
|
from nexaai.mlx_backend.ml import ModelConfig as MLXModelConfig, SamplerConfig as MLXSamplerConfig, GenerationConfig as MLXGenerationConfig, EmbeddingConfig
|
|
@@ -13,14 +14,14 @@ class MLXEmbedderImpl(Embedder):
|
|
|
13
14
|
self._mlx_embedder = None
|
|
14
15
|
|
|
15
16
|
@classmethod
|
|
16
|
-
def _load_from(cls, model_path: str, tokenizer_file: str = "tokenizer.json", plugin_id: str =
|
|
17
|
+
def _load_from(cls, model_path: str, tokenizer_file: str = "tokenizer.json", plugin_id: Union[PluginID, str] = PluginID.MLX):
|
|
17
18
|
"""
|
|
18
19
|
Load an embedder from model files using MLX backend.
|
|
19
20
|
|
|
20
21
|
Args:
|
|
21
22
|
model_path: Path to the model file
|
|
22
23
|
tokenizer_file: Path to the tokenizer file (default: "tokenizer.json")
|
|
23
|
-
plugin_id: Plugin ID to use for the model (default:
|
|
24
|
+
plugin_id: Plugin ID to use for the model (default: PluginID.MLX)
|
|
24
25
|
|
|
25
26
|
Returns:
|
|
26
27
|
MLXEmbedderImpl instance
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import List, Union
|
|
2
2
|
import numpy as np
|
|
3
3
|
|
|
4
|
+
from nexaai.common import PluginID
|
|
4
5
|
from nexaai.embedder import Embedder, EmbeddingConfig
|
|
5
6
|
from nexaai.binds import embedder_bind
|
|
6
7
|
from nexaai.runtime import _ensure_runtime
|
|
@@ -15,20 +16,22 @@ class PyBindEmbedderImpl(Embedder):
|
|
|
15
16
|
self._handle = _handle_ptr
|
|
16
17
|
|
|
17
18
|
@classmethod
|
|
18
|
-
def _load_from(cls, model_path: str, tokenizer_file: str = "tokenizer.json", plugin_id: str =
|
|
19
|
+
def _load_from(cls, model_path: str, tokenizer_file: str = "tokenizer.json", plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP):
|
|
19
20
|
"""
|
|
20
21
|
Load an embedder from model files
|
|
21
22
|
|
|
22
23
|
Args:
|
|
23
24
|
model_path: Path to the model file
|
|
24
25
|
tokenizer_file: Path to the tokenizer file (default: "tokenizer.json")
|
|
25
|
-
plugin_id: Plugin ID to use for the model (default:
|
|
26
|
+
plugin_id: Plugin ID to use for the model (default: PluginID.LLAMA_CPP)
|
|
26
27
|
|
|
27
28
|
Returns:
|
|
28
29
|
PyBindEmbedderImpl instance
|
|
29
30
|
"""
|
|
30
31
|
_ensure_runtime()
|
|
31
|
-
|
|
32
|
+
# Convert enum to string for C++ binding
|
|
33
|
+
plugin_id_str = plugin_id.value if isinstance(plugin_id, PluginID) else plugin_id
|
|
34
|
+
handle = embedder_bind.ml_embedder_create(model_path, tokenizer_file, plugin_id_str)
|
|
32
35
|
return cls(handle)
|
|
33
36
|
|
|
34
37
|
def eject(self):
|
nexaai/image_gen.py
CHANGED
|
@@ -3,6 +3,7 @@ from abc import abstractmethod
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
|
|
5
5
|
from nexaai.base import BaseModel
|
|
6
|
+
from nexaai.common import PluginID
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
@dataclass
|
|
@@ -67,13 +68,16 @@ class ImageGen(BaseModel):
|
|
|
67
68
|
def _load_from(cls,
|
|
68
69
|
model_path: str,
|
|
69
70
|
scheduler_config_path: str = "",
|
|
70
|
-
plugin_id: str =
|
|
71
|
+
plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
|
|
71
72
|
device_id: Optional[str] = None,
|
|
72
73
|
float16: bool = True,
|
|
73
74
|
quantize: bool = False
|
|
74
75
|
) -> 'ImageGen':
|
|
75
76
|
"""Load image generation model from local path, routing to appropriate implementation."""
|
|
76
|
-
|
|
77
|
+
# Check plugin_id value for routing - handle both enum and string
|
|
78
|
+
plugin_value = plugin_id.value if isinstance(plugin_id, PluginID) else plugin_id
|
|
79
|
+
|
|
80
|
+
if plugin_value == "mlx":
|
|
77
81
|
from nexaai.image_gen_impl.mlx_image_gen_impl import MLXImageGenImpl
|
|
78
82
|
return MLXImageGenImpl._load_from(model_path, scheduler_config_path, plugin_id, device_id, float16, quantize)
|
|
79
83
|
else:
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Note: This code is generated by Cursor, not tested yet.
|
|
2
2
|
|
|
3
|
-
from typing import List, Optional
|
|
3
|
+
from typing import List, Optional, Union
|
|
4
4
|
import os
|
|
5
5
|
|
|
6
|
+
from nexaai.common import PluginID
|
|
6
7
|
from nexaai.image_gen import ImageGen, ImageGenerationConfig, ImageSamplerConfig, SchedulerConfig, Image
|
|
7
8
|
from nexaai.mlx_backend.sd.interface import ImageGen as MLXImageGenInterface
|
|
8
9
|
|
|
@@ -17,7 +18,7 @@ class MLXImageGenImpl(ImageGen):
|
|
|
17
18
|
def _load_from(cls,
|
|
18
19
|
model_path: str,
|
|
19
20
|
scheduler_config_path: str = "",
|
|
20
|
-
plugin_id: str =
|
|
21
|
+
plugin_id: Union[PluginID, str] = PluginID.MLX,
|
|
21
22
|
device_id: Optional[str] = None,
|
|
22
23
|
float16: bool = True,
|
|
23
24
|
quantize: bool = False
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
from typing import List, Optional
|
|
1
|
+
from typing import List, Optional, Union
|
|
2
2
|
|
|
3
|
+
from nexaai.common import PluginID
|
|
3
4
|
from nexaai.image_gen import ImageGen, ImageGenerationConfig, ImageSamplerConfig, SchedulerConfig, Image
|
|
4
5
|
|
|
5
6
|
|
|
@@ -13,7 +14,7 @@ class PyBindImageGenImpl(ImageGen):
|
|
|
13
14
|
def _load_from(cls,
|
|
14
15
|
model_path: str,
|
|
15
16
|
scheduler_config_path: str = "",
|
|
16
|
-
plugin_id: str =
|
|
17
|
+
plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
|
|
17
18
|
device_id: Optional[str] = None,
|
|
18
19
|
float16: bool = True,
|
|
19
20
|
quantize: bool = False
|
nexaai/llm.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
from typing import Generator, Optional
|
|
1
|
+
from typing import Generator, Optional, Union
|
|
2
2
|
from abc import abstractmethod
|
|
3
3
|
import queue
|
|
4
4
|
import threading
|
|
5
5
|
|
|
6
|
-
from nexaai.common import ModelConfig, GenerationConfig, ChatMessage
|
|
7
|
-
from nexaai.base import BaseModel
|
|
6
|
+
from nexaai.common import ModelConfig, GenerationConfig, ChatMessage, PluginID
|
|
7
|
+
from nexaai.base import BaseModel, ProfilingData
|
|
8
8
|
|
|
9
9
|
class LLM(BaseModel):
|
|
10
10
|
def __init__(self, m_cfg: ModelConfig = ModelConfig()):
|
|
@@ -17,11 +17,14 @@ class LLM(BaseModel):
|
|
|
17
17
|
local_path: str,
|
|
18
18
|
tokenizer_path: Optional[str] = None,
|
|
19
19
|
m_cfg: ModelConfig = ModelConfig(),
|
|
20
|
-
plugin_id: str =
|
|
20
|
+
plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
|
|
21
21
|
device_id: Optional[str] = None
|
|
22
22
|
) -> 'LLM':
|
|
23
23
|
"""Load model from local path, routing to appropriate implementation."""
|
|
24
|
-
|
|
24
|
+
# Check plugin_id value for routing - handle both enum and string
|
|
25
|
+
plugin_value = plugin_id.value if isinstance(plugin_id, PluginID) else plugin_id
|
|
26
|
+
|
|
27
|
+
if plugin_value == "mlx":
|
|
25
28
|
from nexaai.llm_impl.mlx_llm_impl import MLXLLMImpl
|
|
26
29
|
return MLXLLMImpl._load_from(local_path, tokenizer_path, m_cfg, plugin_id, device_id)
|
|
27
30
|
else:
|
|
@@ -37,7 +40,7 @@ class LLM(BaseModel):
|
|
|
37
40
|
self._cancel_event.clear()
|
|
38
41
|
|
|
39
42
|
@abstractmethod
|
|
40
|
-
def apply_chat_template(self, messages: list[ChatMessage]) -> str:
|
|
43
|
+
def apply_chat_template(self, messages: list[ChatMessage], tools: Optional[str] = None, enable_thinking: bool = True, add_generation_prompt: bool = True) -> str:
|
|
41
44
|
"""Apply the chat template to messages."""
|
|
42
45
|
pass
|
|
43
46
|
|
|
@@ -60,6 +63,10 @@ class LLM(BaseModel):
|
|
|
60
63
|
"""
|
|
61
64
|
pass
|
|
62
65
|
|
|
66
|
+
def get_profiling_data(self) -> Optional[ProfilingData]:
|
|
67
|
+
"""Get profiling data from the last generation."""
|
|
68
|
+
pass
|
|
69
|
+
|
|
63
70
|
@abstractmethod
|
|
64
71
|
def save_kv_cache(self, path: str):
|
|
65
72
|
"""
|
nexaai/llm_impl/mlx_llm_impl.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
from typing import Generator, Optional, Any
|
|
1
|
+
from typing import Generator, Optional, Any, Sequence, Union
|
|
2
2
|
|
|
3
|
-
from nexaai.
|
|
3
|
+
from nexaai.base import ProfilingData
|
|
4
|
+
from nexaai.common import ModelConfig, GenerationConfig, ChatMessage, PluginID
|
|
4
5
|
from nexaai.llm import LLM
|
|
5
6
|
from nexaai.mlx_backend.llm.interface import LLM as MLXLLMInterface
|
|
6
7
|
from nexaai.mlx_backend.ml import ModelConfig as MLXModelConfig, SamplerConfig as MLXSamplerConfig, GenerationConfig as MLXGenerationConfig, EmbeddingConfig
|
|
@@ -17,7 +18,7 @@ class MLXLLMImpl(LLM):
|
|
|
17
18
|
local_path: str,
|
|
18
19
|
tokenizer_path: Optional[str] = None,
|
|
19
20
|
m_cfg: ModelConfig = ModelConfig(),
|
|
20
|
-
plugin_id: str =
|
|
21
|
+
plugin_id: Union[PluginID, str] = PluginID.MLX,
|
|
21
22
|
device_id: Optional[str] = None
|
|
22
23
|
) -> 'MLXLLMImpl':
|
|
23
24
|
"""Load model from local path using MLX backend."""
|
|
@@ -54,7 +55,13 @@ class MLXLLMImpl(LLM):
|
|
|
54
55
|
self._mlx_llm.destroy()
|
|
55
56
|
self._mlx_llm = None
|
|
56
57
|
|
|
57
|
-
def apply_chat_template(
|
|
58
|
+
def apply_chat_template(
|
|
59
|
+
self,
|
|
60
|
+
messages: Sequence[ChatMessage],
|
|
61
|
+
tools: Optional[str] = None,
|
|
62
|
+
enable_thinking: bool = True,
|
|
63
|
+
add_generation_prompt: bool = True
|
|
64
|
+
) -> str:
|
|
58
65
|
"""Apply the chat template to messages."""
|
|
59
66
|
if not self._mlx_llm:
|
|
60
67
|
raise RuntimeError("MLX LLM not loaded")
|
|
@@ -68,9 +75,16 @@ class MLXLLMImpl(LLM):
|
|
|
68
75
|
def __init__(self, role, content):
|
|
69
76
|
self.role = role
|
|
70
77
|
self.content = content
|
|
71
|
-
|
|
78
|
+
|
|
79
|
+
# Handle both dict-style and attribute-style access
|
|
80
|
+
if hasattr(msg, 'role') and hasattr(msg, 'content'):
|
|
81
|
+
# Message is already an object with attributes
|
|
82
|
+
mlx_messages.append(MLXChatMessage(msg.role, msg.content))
|
|
83
|
+
else:
|
|
84
|
+
# Message is a dict
|
|
85
|
+
mlx_messages.append(MLXChatMessage(msg["role"], msg["content"]))
|
|
72
86
|
|
|
73
|
-
return self._mlx_llm.apply_chat_template(mlx_messages)
|
|
87
|
+
return self._mlx_llm.apply_chat_template(mlx_messages, tools=tools, enable_thinking=enable_thinking, add_generation_prompt=add_generation_prompt)
|
|
74
88
|
except Exception as e:
|
|
75
89
|
raise RuntimeError(f"Failed to apply chat template: {str(e)}")
|
|
76
90
|
|
|
@@ -202,6 +216,12 @@ class MLXLLMImpl(LLM):
|
|
|
202
216
|
except Exception as e:
|
|
203
217
|
raise RuntimeError(f"Failed to generate text: {str(e)}")
|
|
204
218
|
|
|
219
|
+
def get_profiling_data(self) -> Optional[ProfilingData]:
|
|
220
|
+
"""Get profiling data from the last generation."""
|
|
221
|
+
if not self._mlx_llm:
|
|
222
|
+
raise RuntimeError("MLX LLM not loaded")
|
|
223
|
+
return self._mlx_llm.get_profiling_data()
|
|
224
|
+
|
|
205
225
|
def save_kv_cache(self, path: str):
|
|
206
226
|
"""
|
|
207
227
|
Save the key-value cache to the file.
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
from typing import Generator, Optional
|
|
1
|
+
from typing import Generator, Optional, Union
|
|
2
2
|
import queue
|
|
3
3
|
import threading
|
|
4
4
|
|
|
5
|
-
from nexaai.
|
|
5
|
+
from nexaai.base import ProfilingData
|
|
6
|
+
from nexaai.common import ModelConfig, GenerationConfig, ChatMessage, PluginID
|
|
6
7
|
from nexaai.binds import llm_bind, common_bind
|
|
7
8
|
from nexaai.runtime import _ensure_runtime
|
|
8
9
|
from nexaai.llm import LLM
|
|
@@ -13,13 +14,14 @@ class PyBindLLMImpl(LLM):
|
|
|
13
14
|
"""Private constructor, should not be called directly."""
|
|
14
15
|
super().__init__(m_cfg)
|
|
15
16
|
self._handle = handle # This is a py::capsule
|
|
17
|
+
self._profiling_data = None
|
|
16
18
|
|
|
17
19
|
@classmethod
|
|
18
20
|
def _load_from(cls,
|
|
19
21
|
local_path: str,
|
|
20
22
|
tokenizer_path: Optional[str] = None,
|
|
21
23
|
m_cfg: ModelConfig = ModelConfig(),
|
|
22
|
-
plugin_id: str =
|
|
24
|
+
plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
|
|
23
25
|
device_id: Optional[str] = None
|
|
24
26
|
) -> 'PyBindLLMImpl':
|
|
25
27
|
"""Load model from local path."""
|
|
@@ -49,11 +51,13 @@ class PyBindLLMImpl(LLM):
|
|
|
49
51
|
config.chat_template_content = m_cfg.chat_template_content
|
|
50
52
|
|
|
51
53
|
# Create handle : returns py::capsule with automatic cleanup
|
|
54
|
+
# Convert enum to string for C++ binding
|
|
55
|
+
plugin_id_str = plugin_id.value if isinstance(plugin_id, PluginID) else plugin_id
|
|
52
56
|
handle = llm_bind.ml_llm_create(
|
|
53
57
|
model_path=local_path,
|
|
54
58
|
tokenizer_path=tokenizer_path,
|
|
55
59
|
model_config=config,
|
|
56
|
-
plugin_id=
|
|
60
|
+
plugin_id=plugin_id_str,
|
|
57
61
|
device_id=device_id
|
|
58
62
|
)
|
|
59
63
|
return cls(handle, m_cfg)
|
|
@@ -64,7 +68,7 @@ class PyBindLLMImpl(LLM):
|
|
|
64
68
|
del self._handle
|
|
65
69
|
self._handle = None
|
|
66
70
|
|
|
67
|
-
def apply_chat_template(self, messages: list[ChatMessage]) -> str:
|
|
71
|
+
def apply_chat_template(self, messages: list[ChatMessage], tools: Optional[str] = None, enable_thinking: bool = True, add_generation_prompt: bool = True) -> str:
|
|
68
72
|
"""Apply the chat template to messages."""
|
|
69
73
|
# Convert TypedDict to list of dicts for binding
|
|
70
74
|
message_dicts = [
|
|
@@ -95,13 +99,14 @@ class PyBindLLMImpl(LLM):
|
|
|
95
99
|
# Run generation in thread
|
|
96
100
|
def generate():
|
|
97
101
|
try:
|
|
98
|
-
llm_bind.ml_llm_generate(
|
|
102
|
+
result = llm_bind.ml_llm_generate(
|
|
99
103
|
handle=self._handle,
|
|
100
104
|
prompt=prompt,
|
|
101
105
|
config=config,
|
|
102
106
|
on_token=on_token,
|
|
103
107
|
user_data=None
|
|
104
108
|
)
|
|
109
|
+
self._profiling_data = ProfilingData.from_dict(result.get("profile_data", {}))
|
|
105
110
|
except Exception as e:
|
|
106
111
|
exception_container[0] = e
|
|
107
112
|
finally:
|
|
@@ -143,8 +148,14 @@ class PyBindLLMImpl(LLM):
|
|
|
143
148
|
on_token=None, # No callback for non-streaming
|
|
144
149
|
user_data=None
|
|
145
150
|
)
|
|
151
|
+
|
|
152
|
+
self._profiling_data = ProfilingData.from_dict(result.get("profile_data", {}))
|
|
146
153
|
return result.get("text", "")
|
|
147
154
|
|
|
155
|
+
def get_profiling_data(self) -> Optional[ProfilingData]:
|
|
156
|
+
"""Get profiling data."""
|
|
157
|
+
return self._profiling_data
|
|
158
|
+
|
|
148
159
|
def save_kv_cache(self, path: str):
|
|
149
160
|
"""
|
|
150
161
|
Save the key-value cache to the file.
|
nexaai/rerank.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
from typing import List, Optional, Sequence
|
|
1
|
+
from typing import List, Optional, Sequence, Union
|
|
2
2
|
from abc import abstractmethod
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
|
|
5
5
|
from nexaai.base import BaseModel
|
|
6
|
+
from nexaai.common import PluginID
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
@dataclass
|
|
@@ -24,11 +25,14 @@ class Reranker(BaseModel):
|
|
|
24
25
|
def _load_from(cls,
|
|
25
26
|
model_path: str,
|
|
26
27
|
tokenizer_file: str = "tokenizer.json",
|
|
27
|
-
plugin_id: str =
|
|
28
|
+
plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
|
|
28
29
|
device_id: Optional[str] = None
|
|
29
30
|
) -> 'Reranker':
|
|
30
31
|
"""Load reranker model from local path, routing to appropriate implementation."""
|
|
31
|
-
|
|
32
|
+
# Check plugin_id value for routing - handle both enum and string
|
|
33
|
+
plugin_value = plugin_id.value if isinstance(plugin_id, PluginID) else plugin_id
|
|
34
|
+
|
|
35
|
+
if plugin_value == "mlx":
|
|
32
36
|
from nexaai.rerank_impl.mlx_rerank_impl import MLXRerankImpl
|
|
33
37
|
return MLXRerankImpl._load_from(model_path, tokenizer_file, plugin_id, device_id)
|
|
34
38
|
else:
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Note: This code is generated by Cursor, not tested yet.
|
|
2
2
|
|
|
3
|
-
from typing import List, Optional, Sequence
|
|
3
|
+
from typing import List, Optional, Sequence, Union
|
|
4
4
|
import os
|
|
5
5
|
|
|
6
|
+
from nexaai.common import PluginID
|
|
6
7
|
from nexaai.rerank import Reranker, RerankConfig
|
|
7
8
|
from nexaai.mlx_backend.rerank.interface import Reranker as MLXRerankInterface, create_reranker
|
|
8
9
|
|
|
@@ -17,7 +18,7 @@ class MLXRerankImpl(Reranker):
|
|
|
17
18
|
def _load_from(cls,
|
|
18
19
|
model_path: str,
|
|
19
20
|
tokenizer_file: str = "tokenizer.json",
|
|
20
|
-
plugin_id: str =
|
|
21
|
+
plugin_id: Union[PluginID, str] = PluginID.MLX,
|
|
21
22
|
device_id: Optional[str] = None
|
|
22
23
|
) -> 'MLXRerankImpl':
|
|
23
24
|
"""Load reranker model from local path using MLX backend."""
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
from typing import List, Optional, Sequence
|
|
1
|
+
from typing import List, Optional, Sequence, Union
|
|
2
2
|
|
|
3
|
+
from nexaai.common import PluginID
|
|
3
4
|
from nexaai.rerank import Reranker, RerankConfig
|
|
4
5
|
|
|
5
6
|
|
|
@@ -13,7 +14,7 @@ class PyBindRerankImpl(Reranker):
|
|
|
13
14
|
def _load_from(cls,
|
|
14
15
|
model_path: str,
|
|
15
16
|
tokenizer_file: str = "tokenizer.json",
|
|
16
|
-
plugin_id: str =
|
|
17
|
+
plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
|
|
17
18
|
device_id: Optional[str] = None
|
|
18
19
|
) -> 'PyBindRerankImpl':
|
|
19
20
|
"""Load reranker model from local path using PyBind backend."""
|
nexaai/tts.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
from typing import List, Optional
|
|
1
|
+
from typing import List, Optional, Union
|
|
2
2
|
from abc import abstractmethod
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
|
|
5
5
|
from nexaai.base import BaseModel
|
|
6
|
+
from nexaai.common import PluginID
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
@dataclass
|
|
@@ -43,11 +44,14 @@ class TTS(BaseModel):
|
|
|
43
44
|
def _load_from(cls,
|
|
44
45
|
model_path: str,
|
|
45
46
|
vocoder_path: str,
|
|
46
|
-
plugin_id: str =
|
|
47
|
+
plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
|
|
47
48
|
device_id: Optional[str] = None
|
|
48
49
|
) -> 'TTS':
|
|
49
50
|
"""Load TTS model from local path, routing to appropriate implementation."""
|
|
50
|
-
|
|
51
|
+
# Check plugin_id value for routing - handle both enum and string
|
|
52
|
+
plugin_value = plugin_id.value if isinstance(plugin_id, PluginID) else plugin_id
|
|
53
|
+
|
|
54
|
+
if plugin_value == "mlx":
|
|
51
55
|
from nexaai.tts_impl.mlx_tts_impl import MLXTTSImpl
|
|
52
56
|
return MLXTTSImpl._load_from(model_path, vocoder_path, plugin_id, device_id)
|
|
53
57
|
else:
|
nexaai/tts_impl/mlx_tts_impl.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Note: This code is generated by Cursor, not tested yet.
|
|
2
2
|
|
|
3
|
-
from typing import List, Optional
|
|
3
|
+
from typing import List, Optional, Union
|
|
4
4
|
import os
|
|
5
5
|
|
|
6
|
+
from nexaai.common import PluginID
|
|
6
7
|
from nexaai.tts import TTS, TTSConfig, TTSResult
|
|
7
8
|
from nexaai.mlx_backend.tts.interface import MlxTts as MLXTTSInterface
|
|
8
9
|
|
|
@@ -17,7 +18,7 @@ class MLXTTSImpl(TTS):
|
|
|
17
18
|
def _load_from(cls,
|
|
18
19
|
model_path: str,
|
|
19
20
|
vocoder_path: str,
|
|
20
|
-
plugin_id: str =
|
|
21
|
+
plugin_id: Union[PluginID, str] = PluginID.MLX,
|
|
21
22
|
device_id: Optional[str] = None
|
|
22
23
|
) -> 'MLXTTSImpl':
|
|
23
24
|
"""Load TTS model from local path using MLX backend."""
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
from typing import List, Optional
|
|
1
|
+
from typing import List, Optional, Union
|
|
2
2
|
|
|
3
|
+
from nexaai.common import PluginID
|
|
3
4
|
from nexaai.tts import TTS, TTSConfig, TTSResult
|
|
4
5
|
|
|
5
6
|
|
|
@@ -13,7 +14,7 @@ class PyBindTTSImpl(TTS):
|
|
|
13
14
|
def _load_from(cls,
|
|
14
15
|
model_path: str,
|
|
15
16
|
vocoder_path: str,
|
|
16
|
-
plugin_id: str =
|
|
17
|
+
plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
|
|
17
18
|
device_id: Optional[str] = None
|
|
18
19
|
) -> 'PyBindTTSImpl':
|
|
19
20
|
"""Load TTS model from local path using PyBind backend."""
|
nexaai/vlm.py
CHANGED
|
@@ -5,8 +5,8 @@ import threading
|
|
|
5
5
|
import base64
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
|
|
8
|
-
from nexaai.common import ModelConfig, GenerationConfig, MultiModalMessage
|
|
9
|
-
from nexaai.base import BaseModel
|
|
8
|
+
from nexaai.common import ModelConfig, GenerationConfig, MultiModalMessage, PluginID
|
|
9
|
+
from nexaai.base import BaseModel, ProfilingData
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class VLM(BaseModel):
|
|
@@ -20,7 +20,7 @@ class VLM(BaseModel):
|
|
|
20
20
|
local_path: str,
|
|
21
21
|
mmproj_path: str,
|
|
22
22
|
m_cfg: ModelConfig = ModelConfig(),
|
|
23
|
-
plugin_id: str =
|
|
23
|
+
plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
|
|
24
24
|
device_id: Optional[str] = None
|
|
25
25
|
) -> 'VLM':
|
|
26
26
|
"""Load VLM model from local path, routing to appropriate implementation.
|
|
@@ -35,7 +35,10 @@ class VLM(BaseModel):
|
|
|
35
35
|
Returns:
|
|
36
36
|
VLM instance
|
|
37
37
|
"""
|
|
38
|
-
|
|
38
|
+
# Check plugin_id value for routing - handle both enum and string
|
|
39
|
+
plugin_value = plugin_id.value if isinstance(plugin_id, PluginID) else plugin_id
|
|
40
|
+
|
|
41
|
+
if plugin_value == "mlx":
|
|
39
42
|
from nexaai.vlm_impl.mlx_vlm_impl import MlxVlmImpl
|
|
40
43
|
return MlxVlmImpl._load_from(local_path, mmproj_path, m_cfg, plugin_id, device_id)
|
|
41
44
|
else:
|
|
@@ -117,4 +120,8 @@ class VLM(BaseModel):
|
|
|
117
120
|
Returns:
|
|
118
121
|
str: The generated text.
|
|
119
122
|
"""
|
|
123
|
+
pass
|
|
124
|
+
|
|
125
|
+
def get_profiling_data(self) -> Optional[ProfilingData]:
|
|
126
|
+
"""Get profiling data from the last generation."""
|
|
120
127
|
pass
|
nexaai/vlm_impl/mlx_vlm_impl.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
from typing import Generator, Optional, List, Dict, Any
|
|
1
|
+
from typing import Generator, Optional, List, Dict, Any, Union
|
|
2
2
|
|
|
3
|
-
from nexaai.
|
|
3
|
+
from nexaai.base import ProfilingData
|
|
4
|
+
from nexaai.common import ModelConfig, GenerationConfig, MultiModalMessage, PluginID
|
|
4
5
|
from nexaai.vlm import VLM
|
|
5
6
|
from nexaai.mlx_backend.vlm.interface import VLM as MLXVLMInterface
|
|
6
7
|
from nexaai.mlx_backend.ml import ModelConfig as MLXModelConfig, SamplerConfig as MLXSamplerConfig, GenerationConfig as MLXGenerationConfig, EmbeddingConfig
|
|
@@ -17,7 +18,7 @@ class MlxVlmImpl(VLM):
|
|
|
17
18
|
local_path: str,
|
|
18
19
|
mmproj_path: str,
|
|
19
20
|
m_cfg: ModelConfig = ModelConfig(),
|
|
20
|
-
plugin_id: str =
|
|
21
|
+
plugin_id: Union[PluginID, str] = PluginID.MLX,
|
|
21
22
|
device_id: Optional[str] = None
|
|
22
23
|
) -> 'MlxVlmImpl':
|
|
23
24
|
"""Load VLM model from local path using MLX backend.
|
|
@@ -247,3 +248,9 @@ class MlxVlmImpl(VLM):
|
|
|
247
248
|
|
|
248
249
|
except Exception as e:
|
|
249
250
|
raise RuntimeError(f"Failed to generate text: {str(e)}")
|
|
251
|
+
|
|
252
|
+
def get_profiling_data(self) -> Optional[ProfilingData]:
|
|
253
|
+
"""Get profiling data from the last generation."""
|
|
254
|
+
if not self._mlx_vlm:
|
|
255
|
+
raise RuntimeError("MLX VLM not loaded")
|
|
256
|
+
return self._mlx_vlm.get_profiling_data()
|
|
@@ -4,10 +4,11 @@ import threading
|
|
|
4
4
|
import base64
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
|
-
from nexaai.common import ModelConfig, GenerationConfig, MultiModalMessage
|
|
7
|
+
from nexaai.common import ModelConfig, GenerationConfig, MultiModalMessage, PluginID
|
|
8
8
|
from nexaai.binds import vlm_bind, common_bind
|
|
9
9
|
from nexaai.runtime import _ensure_runtime
|
|
10
10
|
from nexaai.vlm import VLM
|
|
11
|
+
from nexaai.base import ProfilingData
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
class PyBindVLMImpl(VLM):
|
|
@@ -15,13 +16,14 @@ class PyBindVLMImpl(VLM):
|
|
|
15
16
|
"""Private constructor, should not be called directly."""
|
|
16
17
|
super().__init__(m_cfg)
|
|
17
18
|
self._handle = handle # This is a py::capsule
|
|
19
|
+
self._profiling_data = None
|
|
18
20
|
|
|
19
21
|
@classmethod
|
|
20
22
|
def _load_from(cls,
|
|
21
23
|
local_path: str,
|
|
22
24
|
mmproj_path: str,
|
|
23
25
|
m_cfg: ModelConfig = ModelConfig(),
|
|
24
|
-
plugin_id: str =
|
|
26
|
+
plugin_id: Union[PluginID, str] = PluginID.LLAMA_CPP,
|
|
25
27
|
device_id: Optional[str] = None
|
|
26
28
|
) -> 'PyBindVLMImpl':
|
|
27
29
|
"""Load VLM model from local path.
|
|
@@ -61,11 +63,13 @@ class PyBindVLMImpl(VLM):
|
|
|
61
63
|
config.chat_template_content = m_cfg.chat_template_content
|
|
62
64
|
|
|
63
65
|
# Create handle : returns py::capsule with automatic cleanup
|
|
66
|
+
# Convert enum to string for C++ binding
|
|
67
|
+
plugin_id_str = plugin_id.value if isinstance(plugin_id, PluginID) else plugin_id
|
|
64
68
|
handle = vlm_bind.create_vlm(
|
|
65
69
|
model_path=local_path,
|
|
66
70
|
mmproj_path=mmproj_path,
|
|
67
71
|
model_config=config,
|
|
68
|
-
plugin_id=
|
|
72
|
+
plugin_id=plugin_id_str,
|
|
69
73
|
device_id=device_id
|
|
70
74
|
)
|
|
71
75
|
return cls(handle, m_cfg)
|
|
@@ -141,13 +145,14 @@ class PyBindVLMImpl(VLM):
|
|
|
141
145
|
# Run generation in thread
|
|
142
146
|
def generate():
|
|
143
147
|
try:
|
|
144
|
-
vlm_bind.ml_vlm_generate(
|
|
148
|
+
result = vlm_bind.ml_vlm_generate(
|
|
145
149
|
handle=self._handle,
|
|
146
150
|
prompt=prompt,
|
|
147
151
|
config=config,
|
|
148
152
|
on_token=on_token,
|
|
149
153
|
user_data=None
|
|
150
154
|
)
|
|
155
|
+
self._profiling_data = ProfilingData.from_dict(result.get("profile_data", {}))
|
|
151
156
|
except Exception as e:
|
|
152
157
|
exception_container[0] = e
|
|
153
158
|
finally:
|
|
@@ -189,8 +194,14 @@ class PyBindVLMImpl(VLM):
|
|
|
189
194
|
on_token=None, # No callback for non-streaming
|
|
190
195
|
user_data=None
|
|
191
196
|
)
|
|
197
|
+
|
|
198
|
+
self._profiling_data = ProfilingData.from_dict(result.get("profile_data", {}))
|
|
192
199
|
return result.get("text", "")
|
|
193
200
|
|
|
201
|
+
def get_profiling_data(self) -> Optional[ProfilingData]:
|
|
202
|
+
"""Get profiling data."""
|
|
203
|
+
return self._profiling_data
|
|
204
|
+
|
|
194
205
|
def _convert_generation_config(self, g_cfg: GenerationConfig):
|
|
195
206
|
"""Convert GenerationConfig to binding format."""
|
|
196
207
|
config = common_bind.GenerationConfig()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nexaai
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.5
|
|
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
|
|
@@ -17,11 +17,15 @@ Requires-Dist: tqdm
|
|
|
17
17
|
Requires-Dist: hf_xet
|
|
18
18
|
Requires-Dist: numpy
|
|
19
19
|
Requires-Dist: httpx
|
|
20
|
-
|
|
21
|
-
Requires-Dist: mlx
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist:
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist:
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Requires-Dist:
|
|
20
|
+
Provides-Extra: mlx
|
|
21
|
+
Requires-Dist: mlx; extra == "mlx"
|
|
22
|
+
Requires-Dist: mlx-lm; extra == "mlx"
|
|
23
|
+
Requires-Dist: mlx-vlm; extra == "mlx"
|
|
24
|
+
Requires-Dist: tokenizers; extra == "mlx"
|
|
25
|
+
Requires-Dist: safetensors; extra == "mlx"
|
|
26
|
+
Requires-Dist: Pillow; extra == "mlx"
|
|
27
|
+
Requires-Dist: scipy; extra == "mlx"
|
|
28
|
+
Requires-Dist: soundfile; extra == "mlx"
|
|
29
|
+
Requires-Dist: opencv-python; extra == "mlx"
|
|
30
|
+
Requires-Dist: shapely; extra == "mlx"
|
|
31
|
+
Requires-Dist: pyclipper; extra == "mlx"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
nexaai/__init__.py,sha256=Lt8NU57eTMtWrDYzpFeYR9XtGAPXqizynP83TPU0UW0,2105
|
|
2
|
+
nexaai/_stub.cp310-win_amd64.pyd,sha256=p44ZGmcsoolJ5aI2Oqu053_P9hSscKzoTQfDG6Lk4S0,10752
|
|
3
|
+
nexaai/_version.py,sha256=gMJqvRn_xrvChdUIgn-DExgBJixnRda2-paThBgt3s0,142
|
|
4
|
+
nexaai/asr.py,sha256=_fsGaxpiU137bUtO5ujtFSYCI1RLsyeEm3Gf4GhHVRk,2118
|
|
5
|
+
nexaai/base.py,sha256=qQBCiQVNzgpkQjZX9aiFDEdbAAe56TROKC3WnWra2Zg,1021
|
|
6
|
+
nexaai/common.py,sha256=6keIpdX5XS5us4z79EMoa6RSkVze9SbbXax13IJ9yvs,3525
|
|
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/rerank.py,sha256=_zGWmX6eDigY2kViMKCtNssp4JMEeVycZZfJH9eAZOY,1927
|
|
12
|
+
nexaai/runtime.py,sha256=LxAUejH9uaci8IGz9_h0l-MMeYcwTlBjVKN_0u4Q4Qo,2021
|
|
13
|
+
nexaai/tts.py,sha256=afs6sx0w0Tvs_aJlyZRPm62qQpTrs-fW_jDHrMkc4AA,2241
|
|
14
|
+
nexaai/vlm.py,sha256=STjXCw67ABrHrEll8A2NGiwmfo7MotfYgBh1k1aNxkk,4775
|
|
15
|
+
nexaai/asr_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
+
nexaai/asr_impl/mlx_asr_impl.py,sha256=XwMX3LYMeulp8cDS0TCCYcjvttFHAyDWQ_oMvABwQmI,3349
|
|
17
|
+
nexaai/asr_impl/pybind_asr_impl.py,sha256=20o5SOPzhF9x41ra8L_qIM7YxCkYeLb5csSrNde-dds,1560
|
|
18
|
+
nexaai/binds/__init__.py,sha256=tYvy0pFhoY29GstDT5r-oRiPRarPLECvJAkcamJItOg,83
|
|
19
|
+
nexaai/binds/common_bind.cp310-win_amd64.pyd,sha256=wXqQGKiddXq8rQA2SluwuCmfvKlLK9bNt3IyhP-Q2t8,201216
|
|
20
|
+
nexaai/binds/embedder_bind.cp310-win_amd64.pyd,sha256=jhCkw3xHYir2zJBnSwbLH6dsWuD4loaU2F44cvlShD4,182784
|
|
21
|
+
nexaai/binds/libcrypto-3-x64.dll,sha256=-Lau6pL5DpDXzpg9MED63gCeL8oRrSLI_e2LeaxIHqk,7314432
|
|
22
|
+
nexaai/binds/libssl-3-x64.dll,sha256=Tzzyu5jRpUugFxr_65hbFlAtFpjxIDpOYMU1E0ijkJw,1313792
|
|
23
|
+
nexaai/binds/llm_bind.cp310-win_amd64.pyd,sha256=mbtjTaQ_Cc90HYs76QCs_T5DY_fZ7VpfzoTYGPSX2Vg,162816
|
|
24
|
+
nexaai/binds/nexa_bridge.dll,sha256=taCRtuNWJQVvEv_2d2K1o0FAmHPDPD5Uez2npNkT700,178688
|
|
25
|
+
nexaai/binds/nexa_llama_cpp/ggml-base.dll,sha256=b1Ei-roaQLUBPNd4PxCUAMAR4jyv-GIwbA144xttdXY,514560
|
|
26
|
+
nexaai/binds/nexa_llama_cpp/ggml-cpu.dll,sha256=PNt0gYfIfuywKVYr4DyTTeVv8QN2-9nDKA6pI08TtkQ,663552
|
|
27
|
+
nexaai/binds/nexa_llama_cpp/ggml-cuda.dll,sha256=4dJy4K4ZCCYMkL-9zcMsn10By_sMK_pfiqL7X3EOJSI,315100160
|
|
28
|
+
nexaai/binds/nexa_llama_cpp/ggml-vulkan.dll,sha256=yJrka26Udhgzu3ZJKEldeHP1G0yw6Jo6830CD0mFifE,26204160
|
|
29
|
+
nexaai/binds/nexa_llama_cpp/ggml.dll,sha256=WaVwGkJbgg2Cq6lJTKEZop0Av74YUh8M_-oovSdhtJ0,66560
|
|
30
|
+
nexaai/binds/nexa_llama_cpp/llama.dll,sha256=oWDzqoNqkx4Klli2ZNEtBVIZuQ9ri1IyuK8mQNB7wlw,1587712
|
|
31
|
+
nexaai/binds/nexa_llama_cpp/mtmd.dll,sha256=0UfR_8qiJMnIOCdHT9i9lZjBs2mKazhCm-1exSFCbVY,560128
|
|
32
|
+
nexaai/binds/nexa_llama_cpp/nexa_plugin.dll,sha256=HcqcbJbEDPVTphVdqTt3CxQjFeQtQZAMSW1omX0JcKM,1384448
|
|
33
|
+
nexaai/cv_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
|
+
nexaai/cv_impl/mlx_cv_impl.py,sha256=QLd_8w90gtxH8kmssaDYatCTRvQNIJuUGKZNnYrmx6E,3317
|
|
35
|
+
nexaai/cv_impl/pybind_cv_impl.py,sha256=aSOCAxmHrwJbEkSN6VX3Cykqlj_9RIpVrZXILul04GA,1096
|
|
36
|
+
nexaai/embedder_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
|
+
nexaai/embedder_impl/mlx_embedder_impl.py,sha256=MN5vAGohgyEreLn3H7dg2JeWp2v8emLhrfIDGndk-us,4498
|
|
38
|
+
nexaai/embedder_impl/pybind_embedder_impl.py,sha256=FoLsUrzF5cNtEsSFchPlapkdqLGFOUGNPx0Kc8hdCvA,3589
|
|
39
|
+
nexaai/image_gen_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
40
|
+
nexaai/image_gen_impl/mlx_image_gen_impl.py,sha256=peUE9ue9ApaPlZVOICBWiHtd13sY40OWQbE8EjfIUMU,11511
|
|
41
|
+
nexaai/image_gen_impl/pybind_image_gen_impl.py,sha256=514RFQMSO0Rhacq0IYzlEhEr6QfaprnGew0Rjz8HZI4,3777
|
|
42
|
+
nexaai/llm_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
|
+
nexaai/llm_impl/mlx_llm_impl.py,sha256=r9Qa1ZuduRAcRjmqo2J_zlqhprVPe3ioZtUbi7yIvYY,11426
|
|
44
|
+
nexaai/llm_impl/pybind_llm_impl.py,sha256=s2Cb035xDbh1ZhGNys0LRtAR6b6n4-YVKSC5voD4_Tk,8269
|
|
45
|
+
nexaai/rerank_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
|
+
nexaai/rerank_impl/mlx_rerank_impl.py,sha256=x8L6zCccV2I4bq4V5zAOcrWFe5Ckle7z5J_00tao8bI,3335
|
|
47
|
+
nexaai/rerank_impl/pybind_rerank_impl.py,sha256=1IW925bYv4FRwZDNzf9epEzdDqR6T3OONgTLBd-cOn8,1556
|
|
48
|
+
nexaai/tts_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
49
|
+
nexaai/tts_impl/mlx_tts_impl.py,sha256=LcH9bVdIl3Q6lOzSUB_X2s-_nWFmlCl1yL7XSUK0fYI,3195
|
|
50
|
+
nexaai/tts_impl/pybind_tts_impl.py,sha256=n3z4zmPQayQJgAwcvETw0IBUCp8IYROuYFSg0tAy_8Y,1487
|
|
51
|
+
nexaai/utils/avatar_fetcher.py,sha256=D01f8je-37Nd68zGw8MYK2m7y3fvGlC6h0KR-aN9kdU,3925
|
|
52
|
+
nexaai/utils/decode.py,sha256=0Z9jDH4ICzw4YXj8nD4L-sMouDaev-TISGRQ4KzidWE,421
|
|
53
|
+
nexaai/utils/model_manager.py,sha256=Ksl-tKq-a3miTUxEn6-SSOC_KVdn6RPjcUdkWmDDwCk,49767
|
|
54
|
+
nexaai/utils/progress_tracker.py,sha256=FmJBoOlzfQdc-TmccEav0cBR_iSNrrcskG3Fm1OrEJA,15482
|
|
55
|
+
nexaai/vlm_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
56
|
+
nexaai/vlm_impl/mlx_vlm_impl.py,sha256=oY_qb9z_iF0zArBuY5CCYIvZcA3R0i_NKXrr_r-QSgg,10989
|
|
57
|
+
nexaai/vlm_impl/pybind_vlm_impl.py,sha256=Hu8g8OXyPn8OzLQOpRSE5lfGmhjChiKj7fMRB8mC_cI,9147
|
|
58
|
+
nexaai-1.0.5.dist-info/METADATA,sha256=JhdQmzKpw_EKjD-jcgZHKzn-KRMIoQEKbRGPlTwxrm8,1182
|
|
59
|
+
nexaai-1.0.5.dist-info/WHEEL,sha256=KUuBC6lxAbHCKilKua8R9W_TM71_-9Sg5uEP3uDWcoU,101
|
|
60
|
+
nexaai-1.0.5.dist-info/top_level.txt,sha256=LRE2YERlrZk2vfuygnSzsEeqSknnZbz3Z1MHyNmBU4w,7
|
|
61
|
+
nexaai-1.0.5.dist-info/RECORD,,
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
nexaai/__init__.py,sha256=d1bC_PUNduXYYPLrzKLyS0RapvcrKzLQGJREsoBZvXM,1977
|
|
2
|
-
nexaai/_stub.cp310-win_amd64.pyd,sha256=C8_5OyVPadKYiSnRiPWYNr6Y7TJCu76TAZV3lBhcqjI,10752
|
|
3
|
-
nexaai/_version.py,sha256=65huyjVsErx2svghMx8d4OaeLV72OhoKTE2Wt_RlEgk,147
|
|
4
|
-
nexaai/asr.py,sha256=1XnwbrSoweBfIVAH6LbILv0DMStTQe_Uq5U_f-EyArY,1873
|
|
5
|
-
nexaai/base.py,sha256=qQBCiQVNzgpkQjZX9aiFDEdbAAe56TROKC3WnWra2Zg,1021
|
|
6
|
-
nexaai/common.py,sha256=00cP8uT9NdldBI3dRNHrQFx-uhdgtOGGxRAx4p96nw4,1586
|
|
7
|
-
nexaai/cv.py,sha256=90lrW6o77E6uNMk5MYWsLp2f-fhLacjWTT1ENDhVYEg,3120
|
|
8
|
-
nexaai/embedder.py,sha256=FtJtMKrniejTCi8_-ePLOymfkH8j1VzUqteOqGy5cO4,2279
|
|
9
|
-
nexaai/image_gen.py,sha256=oliLxFN7Bd_3wzP4F6frMJ7GPvRn-1kn_8kAtdcy_pY,4258
|
|
10
|
-
nexaai/llm.py,sha256=7V60E1cI1tt6CZ1ti2-tPqkYS56TcJE_kIhvyRyIBeQ,3194
|
|
11
|
-
nexaai/rerank.py,sha256=l6KtNX9TMGjrtighTQrpXpG_XUlSoZ21AMDDFwR1acI,1682
|
|
12
|
-
nexaai/runtime.py,sha256=LxAUejH9uaci8IGz9_h0l-MMeYcwTlBjVKN_0u4Q4Qo,2021
|
|
13
|
-
nexaai/tts.py,sha256=1tJ3dSwphqPIAQmhMvigcyVFMki6_CC3yofCmaV_H9I,1996
|
|
14
|
-
nexaai/vlm.py,sha256=Cnnw9gy9PaC46WvrCoF5MwFA_iUPaBQGGQ98THSn1jA,4410
|
|
15
|
-
nexaai/asr_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
-
nexaai/asr_impl/mlx_asr_impl.py,sha256=UpGOtl4JZmcmDRa56z5OyIozFVjfsYpKw_vYU_7HoWk,3282
|
|
17
|
-
nexaai/asr_impl/pybind_asr_impl.py,sha256=C0Qnx-WDNmyC72dxuZVfUwuAoUSMvpo8IfOOkEbqsFA,1493
|
|
18
|
-
nexaai/binds/__init__.py,sha256=tYvy0pFhoY29GstDT5r-oRiPRarPLECvJAkcamJItOg,83
|
|
19
|
-
nexaai/binds/common_bind.cp310-win_amd64.pyd,sha256=tsCwzARi5fu-66q24KKLnWnBhNOt4UEbXbssgv4MPTw,201216
|
|
20
|
-
nexaai/binds/embedder_bind.cp310-win_amd64.pyd,sha256=-JroOPxqlTEIU1BirfvjE0vqF__WCvsJaiuE3toWoyI,182784
|
|
21
|
-
nexaai/binds/llm_bind.cp310-win_amd64.pyd,sha256=e7BWEt6TzJocCe_Qb3dB1c-73n6ETL9uPOMuTEsT0Ew,160256
|
|
22
|
-
nexaai/binds/nexa_bridge.dll,sha256=HPGaSjp3uuNGWXKhxvNbyiwxuyLFWr6TzIBxTlaweqQ,176640
|
|
23
|
-
nexaai/binds/nexa_llama_cpp/ggml-base.dll,sha256=WiLohLZ6F5t9Vc0o65CjOMijPjuSH6-G586FOwOJLFE,514560
|
|
24
|
-
nexaai/binds/nexa_llama_cpp/ggml-cpu.dll,sha256=vUHtE3B6dAuJu-WCmXCD7GKayM5HBcoYHw7DVXMvG-4,663552
|
|
25
|
-
nexaai/binds/nexa_llama_cpp/ggml-cuda.dll,sha256=2O7SF6N6VUYPq2yf3l-KFvEpee2X6Yh_7vSbfgWVi2o,315100160
|
|
26
|
-
nexaai/binds/nexa_llama_cpp/ggml-vulkan.dll,sha256=vhNQXlF9_0f5WQkzckQ4lGzmI0ccTPWDODhWlej1ebs,26204160
|
|
27
|
-
nexaai/binds/nexa_llama_cpp/ggml.dll,sha256=VYw6ZxxvlZf4Gi2jkTaOeWSB_pZCIuex4hBd6cWwSWI,66560
|
|
28
|
-
nexaai/binds/nexa_llama_cpp/llama.dll,sha256=Zp6IS6RSJ72vDulABng_9Q59tKvi3znbm13pJwazzNY,1587712
|
|
29
|
-
nexaai/binds/nexa_llama_cpp/mtmd.dll,sha256=9350YqtbNICY1eV1gLB7flBu6NpRUoMf3ESIyH3uoiI,560128
|
|
30
|
-
nexaai/binds/nexa_llama_cpp/nexa_plugin.dll,sha256=DeKJPc4fgbgC14iBPghfjGID9vuT3FEkvx9FT6BDk1s,1086464
|
|
31
|
-
nexaai/cv_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
|
-
nexaai/cv_impl/mlx_cv_impl.py,sha256=vYN8ASbDr-VlQcia0ydpE3tUfnRcRIoRVQDAOhlZB_4,3250
|
|
33
|
-
nexaai/cv_impl/pybind_cv_impl.py,sha256=oXT7Hcurg2YH_qgvwpGtgeQcIFxt6uzT9xN-cLvRHcU,1029
|
|
34
|
-
nexaai/embedder_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
|
-
nexaai/embedder_impl/mlx_embedder_impl.py,sha256=9tQ2-t31r7oo0WcvN3yWIYsk6VQgqSgcILEg0iz3x2I,4431
|
|
36
|
-
nexaai/embedder_impl/pybind_embedder_impl.py,sha256=-sQkWxtwU_SpcSW6OcddmTn4YVTTRBTNlZRDdktKagk,3377
|
|
37
|
-
nexaai/image_gen_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
|
-
nexaai/image_gen_impl/mlx_image_gen_impl.py,sha256=q-kXDj7Pg0xTuI1XKCbCigU5HtXV2HNJOXWx85YznLI,11444
|
|
39
|
-
nexaai/image_gen_impl/pybind_image_gen_impl.py,sha256=M3l9cgQStbStmJ2mtS2NRBZcjp0FJjDlHOhh8xhoaGI,3710
|
|
40
|
-
nexaai/llm_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
|
-
nexaai/llm_impl/mlx_llm_impl.py,sha256=oJePBkpvQijIxTNgF6sj_lmWKbV9Egh0wJIkGrTHzFc,10459
|
|
42
|
-
nexaai/llm_impl/pybind_llm_impl.py,sha256=ecDlzQ_4WE_xBE2pA98nkHdDdJgctpzK9IcpFINCdPc,7581
|
|
43
|
-
nexaai/rerank_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
44
|
-
nexaai/rerank_impl/mlx_rerank_impl.py,sha256=litO0iDf7KUrl8hE3ADETIvLkZcosroSgMpa3HEVFvQ,3268
|
|
45
|
-
nexaai/rerank_impl/pybind_rerank_impl.py,sha256=F-bsWJAS5ZBr4ZOwecZJwiZeB4uEGg0u3bSJV035NDA,1489
|
|
46
|
-
nexaai/tts_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
|
-
nexaai/tts_impl/mlx_tts_impl.py,sha256=I7_ladKIhzn3C7zcx5_dN8EcGlgmRjWSFfwQeqTza9s,3128
|
|
48
|
-
nexaai/tts_impl/pybind_tts_impl.py,sha256=JmWWoluN6I8325IwPL_Np8RLUq_yMENPoyszQ9G3B3M,1420
|
|
49
|
-
nexaai/utils/avatar_fetcher.py,sha256=D01f8je-37Nd68zGw8MYK2m7y3fvGlC6h0KR-aN9kdU,3925
|
|
50
|
-
nexaai/utils/decode.py,sha256=0Z9jDH4ICzw4YXj8nD4L-sMouDaev-TISGRQ4KzidWE,421
|
|
51
|
-
nexaai/utils/model_manager.py,sha256=Ksl-tKq-a3miTUxEn6-SSOC_KVdn6RPjcUdkWmDDwCk,49767
|
|
52
|
-
nexaai/utils/progress_tracker.py,sha256=FmJBoOlzfQdc-TmccEav0cBR_iSNrrcskG3Fm1OrEJA,15482
|
|
53
|
-
nexaai/vlm_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
54
|
-
nexaai/vlm_impl/mlx_vlm_impl.py,sha256=O0NA0zkJ4mhv5lT4EBSVineGe_F0Rsz4ITQvaX_VgIk,10651
|
|
55
|
-
nexaai/vlm_impl/pybind_vlm_impl.py,sha256=WGC21LaQnr4LEiytXX8wVBMLJDG75GIweW3kEMxJGXE,8561
|
|
56
|
-
nexaai-1.0.4rc15.dist-info/METADATA,sha256=eHwHTGzl4PN_GfTApdOqE5dQTesECMWRo6r6CYZe7rY,910
|
|
57
|
-
nexaai-1.0.4rc15.dist-info/WHEEL,sha256=KUuBC6lxAbHCKilKua8R9W_TM71_-9Sg5uEP3uDWcoU,101
|
|
58
|
-
nexaai-1.0.4rc15.dist-info/top_level.txt,sha256=LRE2YERlrZk2vfuygnSzsEeqSknnZbz3Z1MHyNmBU4w,7
|
|
59
|
-
nexaai-1.0.4rc15.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|