@@ -213,7 +213,8 @@ def _get_or_create_generator(self, temperature: float, top_p: float):
213213
214214 def _ensure_background_worker (self , gen_dict ):
215215 """Ensure background worker is running for this generator."""
216- if gen_dict ["task" ] is None :
216+ task = gen_dict ["task" ]
217+ if task is None or task .done ():
217218 loop = asyncio .get_event_loop ()
218219 gen_dict ["task" ] = loop .create_task (self ._background_worker (gen_dict ))
219220
@@ -226,6 +227,13 @@ async def _background_worker(self, gen_dict):
226227
227228 while True :
228229 try :
230+ async with self ._get_lock ():
231+ has_active_requests = bool (gen_dict ["active" ])
232+
233+ if not has_active_requests :
234+ await asyncio .sleep (0.001 )
235+ continue
236+
229237 self ._reset_mlx_lm_generation_stream ()
230238 # Get next batch of results for ALL active requests
231239 # Use different API based on mlx-lm version
@@ -268,6 +276,11 @@ async def _background_worker(self, gen_dict):
268276 f"Request { result .uid } finished, removed from active set"
269277 )
270278
279+ has_active_requests = bool (gen_dict ["active" ])
280+
281+ if not has_active_requests :
282+ self ._synchronize_mlx ()
283+
271284 # Small delay to prevent busy waiting
272285 await asyncio .sleep (0.0001 )
273286
@@ -305,6 +318,19 @@ def _new_mlx_thread_local_stream():
305318 return mx .new_thread_local_stream (device )
306319 return mx .new_stream (device )
307320
321+ @staticmethod
322+ def _synchronize_mlx ():
323+ try :
324+ import mlx .core as mx
325+
326+ synchronize = getattr (mx , "synchronize" , None )
327+ if synchronize is not None :
328+ synchronize ()
329+ else :
330+ mx .eval (mx .array ([0 ]))
331+ except Exception :
332+ logger .debug ("Failed to synchronize MLX" , exc_info = True )
333+
308334 @staticmethod
309335 def _reset_generation_stream (module_name : str ):
310336 try :
@@ -372,9 +398,6 @@ async def generate_stream(
372398 gen_dict = self ._get_or_create_generator (temperature , top_p )
373399 batch_generator = gen_dict ["generator" ]
374400
375- # Ensure background worker is running for this generator
376- self ._ensure_background_worker (gen_dict )
377-
378401 # Prepare request
379402 assert self ._tokenizer_ref is not None
380403 prompt_tokens = self ._tokenizer_ref .encode (prompt )
@@ -419,6 +442,9 @@ async def generate_stream(
419442 )
420443 del gen_dict ["pending" ][inserted_uid ]
421444
445+ # Ensure background worker is running after the request is visible.
446+ self ._ensure_background_worker (gen_dict )
447+
422448 try :
423449 # Track generated text
424450 generated_tokens = []
0 commit comments