From 5c6b37a83a795eec87dcb159b7ac5cc0db2a631e Mon Sep 17 00:00:00 2001 From: ixlmar <206748156+ixlmar@users.noreply.github.com> Date: Fri, 8 May 2026 14:42:20 +0000 Subject: [PATCH] fix: only configure gc thresholds once Signed-off-by: ixlmar <206748156+ixlmar@users.noreply.github.com> --- tensorrt_llm/executor/proxy.py | 10 +++--- tensorrt_llm/llmapi/utils.py | 56 ++++++++++++++-------------------- 2 files changed, 29 insertions(+), 37 deletions(-) diff --git a/tensorrt_llm/executor/proxy.py b/tensorrt_llm/executor/proxy.py index 38b1fb466153..2dd033df6561 100644 --- a/tensorrt_llm/executor/proxy.py +++ b/tensorrt_llm/executor/proxy.py @@ -281,9 +281,8 @@ def abort_request(self, request_id: int) -> None: def dispatch_result_task(self) -> bool: # TODO[chunweiy]: convert the dispatch_result_task to async, that should # benefit from zmq.asyncio.Context - with customized_gc_thresholds(self.garbage_collection_gen0_threshold): - if (res := self.result_queue.get()) is None: - return False # shutdown the thread + if (res := self.result_queue.get()) is None: + return False # shutdown the thread async_queues = [] event_loop = None @@ -337,7 +336,10 @@ def _start_dispatch_threads(self): self.dispatch_result_thread = ManagedThread( weakref.WeakMethod(self.dispatch_result_task), error_queue=self._error_queue, - name="proxy_dispatch_result_thread") + name="proxy_dispatch_result_thread", + context=customized_gc_thresholds( + self.garbage_collection_gen0_threshold), + ) self.dispatch_result_thread.start() diff --git a/tensorrt_llm/llmapi/utils.py b/tensorrt_llm/llmapi/utils.py index 6765617a1804..ef501cd0894f 100644 --- a/tensorrt_llm/llmapi/utils.py +++ b/tensorrt_llm/llmapi/utils.py @@ -15,11 +15,12 @@ import traceback import warnings import weakref +from contextlib import nullcontext from functools import wraps from pathlib import Path from queue import Queue -from typing import (Any, Callable, Iterable, List, Optional, Tuple, Type, - get_type_hints) +from typing import (Any, Callable, ContextManager, Iterable, List, Optional, + Tuple, Type, get_type_hints) import filelock import huggingface_hub @@ -171,19 +172,6 @@ def get_gpu_arch(device: int = 0) -> int: return torch.cuda.get_device_properties(device).major -class ContextManager: - ''' A helper to create a context manager for a resource. ''' - - def __init__(self, resource): - self.resource = resource - - def __enter__(self): - return self.resource.__enter__() - - def __exit__(self, exc_type, exc_value, traceback): - return self.resource.__exit__(exc_type, exc_value, traceback) - - def is_directory_empty(directory: Path) -> bool: return not any(directory.iterdir()) @@ -328,6 +316,7 @@ def __init__(self, error_queue: Queue, name: Optional[str] = None, stop_event: Optional[threading.Event] = None, + context: Optional[ContextManager[Any]] = None, **kwargs): super().__init__(name=name) self.task = task @@ -335,26 +324,27 @@ def __init__(self, self.kwargs = kwargs self.daemon = True self.stop_event = stop_event or threading.Event() + self.context = context or nullcontext() def run(self): - - while not self.stop_event.is_set(): - task = self.task - if isinstance(task, weakref.WeakMethod): - task = task() - if task is None: - # Normally, this should not happen. - logger.warning("WeakMethod is expired.") - break - - try: - if not task(**self.kwargs): - break - except Exception as e: - logger.error( - f"Error in thread {self.name}: {e}\n{traceback.format_exc()}" - ) - self.error_queue.put(e) + with self.context: + while not self.stop_event.is_set(): + task = self.task + if isinstance(task, weakref.WeakMethod): + task = task() + if task is None: + # Normally, this should not happen. + logger.warning("WeakMethod is expired.") + break + + try: + if not task(**self.kwargs): + break + except Exception as e: + logger.error( + f"Error in thread {self.name}: {e}\n{traceback.format_exc()}" + ) + self.error_queue.put(e) logger.info(f"Thread {self.name} stopped.")