nexaai 1.0.4rc14__cp310-cp310-win_amd64.whl → 1.0.4rc15__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.

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.4-rc14"
4
+ __version__ = "1.0.4-rc15"
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
nexaai/cv.py CHANGED
@@ -69,6 +69,7 @@ class CVModel(BaseModel):
69
69
 
70
70
  @classmethod
71
71
  def _load_from(cls,
72
+ _: str, # TODO: remove this argument, this is a hack to make api design happy
72
73
  config: CVModelConfig,
73
74
  plugin_id: str = "llama_cpp",
74
75
  device_id: Optional[str] = None
@@ -76,8 +76,10 @@ class MlxVlmImpl(VLM):
76
76
  raise RuntimeError("MLX VLM not loaded")
77
77
 
78
78
  try:
79
- # Convert MultiModalMessage to MLX format
80
79
  mlx_messages = []
80
+ total_images = 0
81
+ total_audios = 0
82
+
81
83
  for msg in messages:
82
84
  # Create a simple object with role and content attributes
83
85
  class MLXChatMessage:
@@ -85,19 +87,38 @@ class MlxVlmImpl(VLM):
85
87
  self.role = role
86
88
  self.content = content
87
89
 
88
- # For MLX VLM, we need to extract text content from multimodal messages
89
- # This is a simplified approach - the actual implementation may need
90
- # more sophisticated handling of different content types
90
+ # Extract text content and count media files
91
91
  text_content = ""
92
+ first_content = True
93
+
92
94
  for content_item in msg["content"]:
93
- if content_item["type"] == "text":
95
+ content_type = content_item.get("type", "")
96
+
97
+ if content_type == "text":
98
+ if not first_content:
99
+ text_content += " "
94
100
  text_content += content_item.get("text", "")
95
- # Note: image/audio/video content is typically handled separately
96
- # in the generation phase, not in the chat template
101
+ first_content = False
102
+ elif content_type == "image":
103
+ total_images += 1
104
+ elif content_type == "audio":
105
+ total_audios += 1
97
106
 
98
107
  mlx_messages.append(MLXChatMessage(msg["role"], text_content))
99
108
 
100
- return self._mlx_vlm.apply_chat_template(mlx_messages)
109
+ if total_images > 0 or total_audios > 0:
110
+ # Use apply_chat_template_with_media when media is present
111
+ return self._mlx_vlm.apply_chat_template_with_media(
112
+ mlx_messages,
113
+ num_images=total_images,
114
+ num_audios=total_audios,
115
+ tools=tools,
116
+ enable_thinking=False # Default to False, could be made configurable
117
+ )
118
+ else:
119
+ # Use regular apply_chat_template for text-only messages
120
+ return self._mlx_vlm.apply_chat_template(mlx_messages)
121
+
101
122
  except Exception as e:
102
123
  raise RuntimeError(f"Failed to apply chat template: {str(e)}")
103
124
 
@@ -107,9 +128,6 @@ class MlxVlmImpl(VLM):
107
128
  raise RuntimeError("MLX VLM not loaded")
108
129
 
109
130
  try:
110
- # Get MLX config classes
111
- _, MLXSamplerConfig, MLXGenerationConfig, _ = get_mlx_configs()
112
-
113
131
  # Convert GenerationConfig to MLX format
114
132
  mlx_gen_config = MLXGenerationConfig()
115
133
  mlx_gen_config.max_tokens = g_cfg.max_tokens
@@ -130,25 +148,57 @@ class MlxVlmImpl(VLM):
130
148
  mlx_sampler_config.grammar_string = g_cfg.sampler_config.grammar_string
131
149
  mlx_gen_config.sampler_config = mlx_sampler_config
132
150
 
133
- # Create a token callback for streaming
134
- def token_callback(token: str) -> bool:
135
- # Check if generation should be cancelled
136
- return not self._cancel_event.is_set()
151
+ import queue
152
+ import threading
153
+
154
+ # Create a queue for streaming tokens
155
+ token_queue = queue.Queue()
156
+ exception_container = [None]
157
+ self.reset_cancel() # Reset cancel flag before generation
137
158
 
138
- # Use MLX VLM streaming generation
139
- result = self._mlx_vlm.generate_stream(prompt, mlx_gen_config, token_callback)
159
+ def token_callback(token: str, user_data: Any = None) -> bool:
160
+ if self._cancel_event.is_set():
161
+ token_queue.put(('end', None))
162
+ return False
163
+ try:
164
+ token_queue.put(('token', token))
165
+ return True
166
+ except Exception as e:
167
+ exception_container[0] = e
168
+ return False
140
169
 
141
- # MLX VLM interface returns a GenerationResult, extract the text
142
- if hasattr(result, 'text') and result.text:
143
- # Split the result into words and yield them
144
- words = result.text.split()
145
- for i, word in enumerate(words):
146
- if self._cancel_event.is_set():
170
+ # Run generation in a separate thread
171
+ def generate():
172
+ try:
173
+ self._mlx_vlm.generate_stream(prompt, mlx_gen_config, token_callback)
174
+ except Exception as e:
175
+ exception_container[0] = e
176
+ finally:
177
+ token_queue.put(('end', None))
178
+
179
+ thread = threading.Thread(target=generate)
180
+ thread.start()
181
+
182
+ # Yield tokens as they come from the queue
183
+ while True:
184
+ if exception_container[0]:
185
+ raise exception_container[0]
186
+
187
+ try:
188
+ msg_type, token = token_queue.get(timeout=0.1)
189
+ if msg_type == 'end':
147
190
  break
148
- if i == 0:
149
- yield word
150
- else:
151
- yield " " + word
191
+ elif msg_type == 'token':
192
+ yield token
193
+ except queue.Empty:
194
+ if not thread.is_alive():
195
+ break
196
+ continue
197
+
198
+ thread.join()
199
+
200
+ if exception_container[0]:
201
+ raise exception_container[0]
152
202
 
153
203
  except Exception as e:
154
204
  raise RuntimeError(f"Failed to generate streaming text: {str(e)}")
@@ -168,9 +218,6 @@ class MlxVlmImpl(VLM):
168
218
  raise RuntimeError("MLX VLM not loaded")
169
219
 
170
220
  try:
171
- # Get MLX config classes
172
- _, MLXSamplerConfig, MLXGenerationConfig, _ = get_mlx_configs()
173
-
174
221
  # Convert GenerationConfig to MLX format
175
222
  mlx_gen_config = MLXGenerationConfig()
176
223
  mlx_gen_config.max_tokens = g_cfg.max_tokens
@@ -191,15 +238,12 @@ class MlxVlmImpl(VLM):
191
238
  mlx_sampler_config.grammar_string = g_cfg.sampler_config.grammar_string
192
239
  mlx_gen_config.sampler_config = mlx_sampler_config
193
240
 
194
- # Use MLX VLM generation
195
- result = self._mlx_vlm.generate(prompt, mlx_gen_config)
241
+ # Simple token callback that just continues
242
+ def token_callback(token: str, user_data: Any = None) -> bool:
243
+ return not self._cancel_event.is_set()
196
244
 
197
- # MLX VLM interface returns a GenerationResult, extract the text
198
- if hasattr(result, 'text'):
199
- return result.text
200
- else:
201
- # Fallback if result is just a string
202
- return str(result)
245
+ # Use MLX streaming generation and return the full result
246
+ return self._mlx_vlm.generate_stream(prompt, mlx_gen_config, token_callback)
203
247
 
204
248
  except Exception as e:
205
249
  raise RuntimeError(f"Failed to generate text: {str(e)}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nexaai
3
- Version: 1.0.4rc14
3
+ Version: 1.0.4rc15
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,10 +17,11 @@ Requires-Dist: tqdm
17
17
  Requires-Dist: hf_xet
18
18
  Requires-Dist: numpy
19
19
  Requires-Dist: httpx
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"
20
+ Requires-Dist: mlx
21
+ Requires-Dist: mlx-lm
22
+ Requires-Dist: scipy
23
+ Requires-Dist: soundfile
24
+ Requires-Dist: Pillow
25
+ Requires-Dist: opencv-python
26
+ Requires-Dist: shapely
27
+ Requires-Dist: pyclipper
@@ -1,10 +1,10 @@
1
1
  nexaai/__init__.py,sha256=d1bC_PUNduXYYPLrzKLyS0RapvcrKzLQGJREsoBZvXM,1977
2
- nexaai/_stub.cp310-win_amd64.pyd,sha256=AqYjxocL8y9D6PVMpNfrK8bjWlkh5QKtCE2nIG1ALJw,10752
3
- nexaai/_version.py,sha256=uRRQiVCCiR6jdFwtfQT2hqN_HwM1guhUpuxR4tuqrL8,147
2
+ nexaai/_stub.cp310-win_amd64.pyd,sha256=C8_5OyVPadKYiSnRiPWYNr6Y7TJCu76TAZV3lBhcqjI,10752
3
+ nexaai/_version.py,sha256=65huyjVsErx2svghMx8d4OaeLV72OhoKTE2Wt_RlEgk,147
4
4
  nexaai/asr.py,sha256=1XnwbrSoweBfIVAH6LbILv0DMStTQe_Uq5U_f-EyArY,1873
5
5
  nexaai/base.py,sha256=qQBCiQVNzgpkQjZX9aiFDEdbAAe56TROKC3WnWra2Zg,1021
6
6
  nexaai/common.py,sha256=00cP8uT9NdldBI3dRNHrQFx-uhdgtOGGxRAx4p96nw4,1586
7
- nexaai/cv.py,sha256=qGDVK0pKAEx0DrSi2rpSVLV4Kf53UAVIst9GdCMAGN0,3021
7
+ nexaai/cv.py,sha256=90lrW6o77E6uNMk5MYWsLp2f-fhLacjWTT1ENDhVYEg,3120
8
8
  nexaai/embedder.py,sha256=FtJtMKrniejTCi8_-ePLOymfkH8j1VzUqteOqGy5cO4,2279
9
9
  nexaai/image_gen.py,sha256=oliLxFN7Bd_3wzP4F6frMJ7GPvRn-1kn_8kAtdcy_pY,4258
10
10
  nexaai/llm.py,sha256=7V60E1cI1tt6CZ1ti2-tPqkYS56TcJE_kIhvyRyIBeQ,3194
@@ -16,18 +16,18 @@ nexaai/asr_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  nexaai/asr_impl/mlx_asr_impl.py,sha256=UpGOtl4JZmcmDRa56z5OyIozFVjfsYpKw_vYU_7HoWk,3282
17
17
  nexaai/asr_impl/pybind_asr_impl.py,sha256=C0Qnx-WDNmyC72dxuZVfUwuAoUSMvpo8IfOOkEbqsFA,1493
18
18
  nexaai/binds/__init__.py,sha256=tYvy0pFhoY29GstDT5r-oRiPRarPLECvJAkcamJItOg,83
19
- nexaai/binds/common_bind.cp310-win_amd64.pyd,sha256=dkXWLzyqnwbjD8X-R2EgXVisNQ0m8dp4vPDUk9lTFtk,201216
20
- nexaai/binds/embedder_bind.cp310-win_amd64.pyd,sha256=rIpVBezf-CnRLOXp-UUm1QzMyo6jfVv45gmYcjazGbw,182784
21
- nexaai/binds/llm_bind.cp310-win_amd64.pyd,sha256=ZYJ3LPPoCJ71I_-fzWBIP1CAH2074Gp6nOofnAcOYdc,160256
22
- nexaai/binds/nexa_bridge.dll,sha256=5s3i1ipX6gy0PsTN6NwpdI3sHb1GWThWuDR6V_IpHZY,176640
23
- nexaai/binds/nexa_llama_cpp/ggml-base.dll,sha256=gbrUPK8zgkj9bBR5xUDGD0D7nvNGUq92AN3WQn8MQko,514560
24
- nexaai/binds/nexa_llama_cpp/ggml-cpu.dll,sha256=35M4StfLC6dabERz-lsIMN-0cqZ-5TuzBiMxNJfavDk,663552
25
- nexaai/binds/nexa_llama_cpp/ggml-cuda.dll,sha256=ArpiDq4u5H69gMvTNLI4n6KVvEAW9kX0W47bkoGte18,315100160
26
- nexaai/binds/nexa_llama_cpp/ggml-vulkan.dll,sha256=SKtwhTRMZ5NjAd-tfOwRSh5YClFPOs4rW8RVuMTHaPs,26204160
27
- nexaai/binds/nexa_llama_cpp/ggml.dll,sha256=pvoyxBM3WRq_RkivDQlYi5V5zLKAtZ_onLoZBf68OmA,66560
28
- nexaai/binds/nexa_llama_cpp/llama.dll,sha256=zOiAWXJivXJCPRMPLEXC9Ct1jWXNl8NyknEEy8whfDA,1587712
29
- nexaai/binds/nexa_llama_cpp/mtmd.dll,sha256=fiSHNh1iDND5aqBwhE0Bki-up2olfoLDIKTsWmjQip0,560128
30
- nexaai/binds/nexa_llama_cpp/nexa_plugin.dll,sha256=G6LAMb8NNRUTiVIyTBF-6CZ3OzdeHJ5ZliHJDDPkUWk,1086464
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
31
  nexaai/cv_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  nexaai/cv_impl/mlx_cv_impl.py,sha256=vYN8ASbDr-VlQcia0ydpE3tUfnRcRIoRVQDAOhlZB_4,3250
33
33
  nexaai/cv_impl/pybind_cv_impl.py,sha256=oXT7Hcurg2YH_qgvwpGtgeQcIFxt6uzT9xN-cLvRHcU,1029
@@ -51,9 +51,9 @@ nexaai/utils/decode.py,sha256=0Z9jDH4ICzw4YXj8nD4L-sMouDaev-TISGRQ4KzidWE,421
51
51
  nexaai/utils/model_manager.py,sha256=Ksl-tKq-a3miTUxEn6-SSOC_KVdn6RPjcUdkWmDDwCk,49767
52
52
  nexaai/utils/progress_tracker.py,sha256=FmJBoOlzfQdc-TmccEav0cBR_iSNrrcskG3Fm1OrEJA,15482
53
53
  nexaai/vlm_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
- nexaai/vlm_impl/mlx_vlm_impl.py,sha256=DobOLnbf1v2uQrcB0TByTzJDp2Vhrjyjk3DvW4feahQ,9152
54
+ nexaai/vlm_impl/mlx_vlm_impl.py,sha256=O0NA0zkJ4mhv5lT4EBSVineGe_F0Rsz4ITQvaX_VgIk,10651
55
55
  nexaai/vlm_impl/pybind_vlm_impl.py,sha256=WGC21LaQnr4LEiytXX8wVBMLJDG75GIweW3kEMxJGXE,8561
56
- nexaai-1.0.4rc14.dist-info/METADATA,sha256=AHPVkJq7Csbteh1-yBdVtZFIp0UKq6QWyVPTMJmQbCc,978
57
- nexaai-1.0.4rc14.dist-info/WHEEL,sha256=KUuBC6lxAbHCKilKua8R9W_TM71_-9Sg5uEP3uDWcoU,101
58
- nexaai-1.0.4rc14.dist-info/top_level.txt,sha256=LRE2YERlrZk2vfuygnSzsEeqSknnZbz3Z1MHyNmBU4w,7
59
- nexaai-1.0.4rc14.dist-info/RECORD,,
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,,