본문으로 건너뛰기

Python과 C++에서 NVIDIA TensorRT 엔진 빌드를 가시화하고 취소 가능하게 만드는 개발자 도구와 기법

TensorRT의 IProgressMonitor를 이용해 빌드 진행을 실시간으로 스트리밍하고 step 경계에서 안전하게 취소할 수 있으며 Python·C++ 샘플과 통합 경로가 제공된다.

이 요약은 AI가 원문을 분석해 생성했습니다. 정확한 내용은 원문 기준으로 확인하세요.

TL;DR

TensorRT의 IProgressMonitor는 엔진 빌드 중에 phase_start·step_complete·phase_finish 세 콜백으로 중첩된 진행 상태를 보고하고 step_complete의 반환값으로 빌드 취소를 요청하는 단일 경계 역할을 하며 Python과 C++ 샘플을 통해 즉시 적용 가능한 구현 패턴을 제공한다. 구현은 멀티스레드 호출을 고려한 Lock 또는 mutex로 상태를 보호하고 atomic 플래그로 취소 요청을 전달하며 터미널에서는 ANSI 시퀀스로 중첩 진행 막대를 갱신하고 비상호작용형 전송에서는 구조화된 이벤트를 내보내야 한다. 통합은 IBuilderConfig에 모니터를 설정한 뒤 LSP 알림, Server-Sent Events, 에이전트 툴콜 청크 같은 기존 전송으로 렌더 출력을 보내고 monitor.requestCancel()을 통해 Ctrl-C·IDE 중지·HTTP cancel 등 외부 소스로부터 일관된 취소 처리를 실현한다. 취소는 step 경계에서만 적용되므로 긴 전술 탐색 단계에서는 응답 지연이 수초에서 수십 초가 될 수 있고 phase_finish가 예상보다 먼저 호출될 수 있으므로 이를 운영상 고려해야 한다.

빠른 이해

새로운 점

IProgressMonitor를 단일 경계로 삼아 터미널·IDE·HTTP·에이전트로 진행과 취소를 일관되게 연결한 실용적 통합 패턴

핵심 메커니즘

빌더가 phase_start로 단계 트리를 열고 각 step에서 step_complete를 호출하면 모니터가 현재 스텝을 갱신하고 Boolean을 반환해 계속할지 취소할지를 결정하며 phase_finish가 단계 종료를 정리하는 입력→처리→출력 흐름이다.

섹션별 상세

문제와 목적

TensorRT 엔진 빌드는 수초에서 수분까지 걸릴 수 있고 빌드 중 진행 정보가 없으면 개발자와 에이전트가 기다릴지 중단할지 판단할 수 없어 GPU 시간이 낭비된다. IProgressMonitor는 이러한 블랙박스 빌드 과정에 세부 진행 정보와 취소 경로를 제공하기 위해 NvInfer.h에 포함된 추상 인터페이스이다. 이 튜토리얼은 Python과 C++에서 IProgressMonitor를 구현해 실시간 보고와 외부 취소를 연결하는 방법을 보여주며 실제 샘플을 통해 재현 가능한 워크플로를 제공한다.

IProgressMonitor 인터페이스와 동작 원리

IProgressMonitor는 phase_start, step_complete, phase_finish 세 메서드를 통해 빌더가 진행 상황을 통지하는 구조로 설계되어 있고 step_complete의 반환값만이 빌더 동작에 취소 신호를 전달한다. 중첩된 phase는 parent_phase 인자를 통해 트리 형태로 표현되며 모니터는 이 트리를 기반으로 계층적 진행 상태를 유지해야 한다. TensorRT는 내부 스레드에서 동일한 모니터 인스턴스를 호출할 수 있으므로 구현은 스레드 안전을 보장해야 하고 빌더는 step 경계에서 취소 요청을 확인해 현재 스텝을 마친 뒤 빌드를 정리한다.
근거
  • step_complete는 빌더의 동작을 변경하는 유일한 콜백으로, 반환값이 False이면 빌드 취소가 요청된다. Table 1 및 관련 문단(인터페이스 설명)에서 메서드 의미와 취소 경로를 기술한 부분

Python 구현 핵심

Python 샘플은 trt.IProgressMonitor를 상속해 phase 상태를 기록하는 간단한 데이터 구조와 Lock을 사용한 동기화로 상태 갱신과 렌더를 보호한다. phase_start에서 단계 수를 기록하고 phase_finish에서 상태를 제거하며 step_complete는 current_step을 갱신하고 내부 취소 플래그를 확인해 False를 반환하면 빌드가 취소된다. 빌더에 모니터를 연결할 때는 IBuilderConfig의 config.progress_monitor 속성에 인스턴스를 할당하면 되며 이 연결은 언어별로 단일 호출로 이루어진다.
python
import tensorrt as trt
from dataclasses import dataclass, field
from threading import Lock

@dataclass
class _PhaseState:
    num_steps: int
    current_step: int = 0
    parent: str | None = None

class RichProgressMonitor(trt.IProgressMonitor):
    def __init__(self):
        super().__init__()
        self._lock = Lock()
        self._phases: dict[str, _PhaseState] = {}
        self._cancelled = False
        self._rendered_lines = 0

    def phase_start(self, phase_name, parent_phase, num_steps):
        with self._lock:
            self._phases[phase_name] = _PhaseState(
                num_steps=num_steps,
                parent=parent_phase
            )
            self._render()

    def step_complete(self, phase_name, step) -> bool:
        with self._lock:
            if phase_name in self._phases:
                self._phases[phase_name].current_step = step
            self._render()
            return not self._cancelled

    def phase_finish(self, phase_name):
        with self._lock:
            self._phases.pop(phase_name, None)
            self._render()

TensorRT의 IProgressMonitor를 상속해 phase별 상태를 잠금으로 보호하며 추적하고 step_complete에서 취소 플래그를 검사하는 Python 구현 예시이다.

터미널 렌더링과 출력 처리

터미널 렌더러는 중첩 깊이에 따라 phase를 정렬하고 이전 렌더에서 출력한 행 수를 기억한 뒤 ANSI 시퀀스로 커서를 위로 이동해 기존 출력을 덮어쓰는 방식으로 실시간 막대를 갱신한다. 진행률 계산은 완료된 항목 수(done)를 num_steps로 나누어 백분율을 구하고 고정 폭 문자로 바(예: 40칸)를 그려 시각적 피드백을 제공한다. 터미널 렌더러는 stdout 리다이렉션 시 제어문자가 로그를 오염시킬 수 있으므로 비상호작용형 전송에서는 구조화된 이벤트(예: JSON 청크 혹은 SSE)를 내보내는 별도 렌더러를 사용해야 한다.
python
def _render(self):
    # Order phases by nesting depth so children draw under parents.
    rows = sorted(
        self._phases.items(), key=lambda kv: (kv[1].parent or "", kv[0]),
    )
    # Move the cursor up by the number of lines the PREVIOUS render printed,
    # not the current row count — phases are added on nesting and removed on
    # phase_finish, so the two differ exactly when the tree changes shape.
    if self._rendered_lines:
        print(f"\x1b[{self._rendered_lines}A", end="")
    for name, st in rows:
        # step is a 0-based index in [0, num_steps); +1 turns it into a
        # completed count so the bar can actually reach 100%.
        done = min(st.current_step + 1, st.num_steps)
        pct = done / max(st.num_steps, 1)
        bar = "█" * int(40 * pct) + "·" * (40 - int(40 * pct))
        indent = " " if st.parent else ""
        print(f"\x1b[2K{indent}{name}", end="")

터미널에 중첩 진행 막대를 출력하기 위한 렌더러의 핵심 로직으로 행 정렬, 커서 이동, 진행률 바 계산을 포함한다.

C++ 구현 핵심

C++ 예시는 mutex로 phases 맵을 보호하고 std::atomic<bool> cancelled_ 플래그를 통해 requestCancel 호출을 안전하게 전달하는 구조를 사용한다. phaseStart·stepComplete·phaseFinish가 각각 상태 삽입·갱신·삭제를 수행하고 render()가 출력 갱신을 담당하며 stepComplete의 반환값(false)이 빌더에게 취소를 요청한다. C++에서는 signal handler나 다른 스레드에서 requestCancel을 호출할 수 있으므로 atomic 플래그 사용이 중요하며 빌드 구성 시 config->setProgressMonitor(&monitor)로 연결한다.
cpp
#include <unordered_map>
#include <mutex>
#include <atomic>

class RichProgressMonitor : public nvinfer1::IProgressMonitor {
public:
  void phaseStart(char const* phaseName, char const* parentPhase, int32_t nbSteps) noexcept override {
    std::lock_guard g(mu_);
    phases_[phaseName] = {nbSteps, 0, parentPhase ? parentPhase : ""};
    render();
  }
  bool stepComplete(char const* phaseName, int32_t step) noexcept override {
    std::lock_guard g(mu_);
    auto it = phases_.find(phaseName);
    if (it != phases_.end()) it->second.current = step;
    render();
    return !cancelled_.load();
  }
  void phaseFinish(char const* phaseName) noexcept override {
    std::lock_guard g(mu_);
    phases_.erase(phaseName);
    render();
  }
  void requestCancel() noexcept { cancelled_.store(true); }

private:
  struct Phase { int32_t nbSteps; int32_t current; std::string parent; };
  std::mutex mu_;
  std::unordered_map<std::string, Phase> phases_;
  std::atomic<bool> cancelled_{false};
  void render() noexcept;
};

// Attach with:
// auto config = std::unique_ptr( builder->createBuilderConfig());
// RichProgressMonitor monitor; config->setProgressMonitor(&monitor);

C++에서 IProgressMonitor를 구현한 예시로, mutex로 상태를 보호하고 atomic 플래그로 취소 요청을 처리하는 구조이다.

외부 통합 경로

IProgressMonitor를 애플리케이션의 단일 통합점으로 삼아 터미널 출력 외에 IDE, HTTP 서비스, 에이전트 런타임으로 진행 정보를 라우팅할 수 있다. IDE 통합은 render에서 LSP의 $/progress 알림을 발송하거나 window/showProgress 메시지로 변환하고 HTTP 통합은 백그라운드 스레드에서 Server-Sent Events로 스트리밍하며 취소 엔드포인트가 monitor.requestCancel()을 호출하는 방식으로 구현된다. 에이전트 통합은 각 phase 전환을 구조화된 툴콜 청크로 내보내고 타임아웃이나 정책에 따라 동일한 requestCancel 경로로 빌드를 중지하게 만든다.

엣지 케이스와 운영상 주의점

phase_start 자체는 취소를 거부할 수 없으므로 긴 phase_start 단계가 있을 경우 사용자가 취소해도 첫 번째 step_complete까지 빌드가 계속될 수 있다. phase_finish는 내부 오류 복구나 빌더 최적화에 의해 num_steps가 모두 보고되기 전에 호출될 수 있으므로 phase_finish를 종결 신호로 간주해야 하고 current_step == num_steps를 가정해서는 안 된다. 취소 지연은 현재 스텝이 완료될 때까지 발생하므로 긴 전술 탐색 단계에서는 응답 시간이 수초에서 수십 초까지 늘어나며 stdout 리다이렉션과 동시성 문제를 방지하기 위해 상태 접근을 반드시 동기화해야 한다.

시작 방법과 샘플 실행

가장 빠른 실행 경로는 TensorRT GitHub 리포지토리를 클론한 뒤 samples/python/simple_progress_monitor의 스크립트를 실행해 ResNet-50 엔진 빌드를 실시간으로 관찰하는 것이다. 제공된 샘플의 모니터 클래스를 교체하거나 기존 클래스 주위에 취소 핸들러를 추가하면 즉시 종료 및 스트리밍 동작을 시험해볼 수 있다. 대규모 시스템에서는 터미널 렌더러를 애플리케이션이 이미 사용하는 전송으로 대체해 LSP·SSE·툴콜 청크 같은 기존 인프라와 통합하는 것이 권장된다.

용어 해설

IProgressMonitor API(IProgressMonitor)
TensorRT 빌더가 엔진 빌드 진행 중에 호출하는 추상 콜백 인터페이스로, phase_start·step_complete·phase_finish 세 메서드를 오버라이드해 중첩된 진행 상태를 추적하고 step 경계에서 취소 신호를 전달하는 역할을 한다. 구현은 멀티스레드 호출을 고려한 동기화와 취소 플래그 처리, 렌더링 혹은 구조화된 이벤트 방출로의 변환을 포함한다. 이 인터페이스가 있으면 터미널·IDE·HTTP·에이전트 런타임으로 빌드 진행을 스트리밍하고 외부에서 안전하게 취소할 수 있다.
전략(타틱) 선택(Tactic Selection)
TensorRT 빌더가 엔진 최적화 과정에서 모델 연산을 실행할 하드웨어·커널·전략을 탐색하는 단계로, 개별 탐색 단계가 길어 취소 지연이 발생할 수 있다. 이 단계는 빌드 시간 변동의 주요 원인 중 하나이므로 진행 표시 및 단계별 취소 처리에서 핵심적으로 고려된다. 긴 단일 스텝은 취소 응답 시간에 수초에서 수십 초의 지연을 유발할 수 있다.
ANSI 가상 터미널 제어문자(Virtual Terminal Escapes)
터미널 커서를 이동하고 행을 지우는 제어 시퀀스로, 중첩 진행 막대를 실시간으로 갱신하기 위해 커서 이동([{n}A)과 행 삭제([2K)를 사용해 이전 렌더 출력 위치로 되돌리는 방식이 핵심이다. 렌더링 로직은 이전에 출력한 행 수를 기억해 커서를 올바르게 이동시켜야 하며, stdout 리다이렉션 시 제어문자가 로그를 오염시킬 수 있다. 상호작용형 터미널과 비상호작용형 전송(예: SSE)은 서로 다른 출력 전략이 필요하다.
Language Server Protocol
IDE와 편집기 간의 표준화된 통신 규격으로, IProgressMonitor의 렌더 결과를 $/progress 알림과 같은 프로토콜 메시지로 변환해 IDE의 진행 표시창에 실시간으로 노출할 수 있다. 각 빌드 phase를 개별 토큰으로 취급하고 step_complete를 보고로 변환하면 IDE의 Stop 버튼이 모니터.requestCancel()을 호출해 빌드를 중단하게 만들 수 있다. LSP 전송은 상호작용형 클라이언트에 적합한 통합 경로다.

기술

  • Python
  • C++
  • TensorRT
  • Server-Sent Events
  • Language Server Protocol
AI 분석 전체 내용 보기

AI 요약 · 북마크 · 개인 피드 설정 — 무료

출처 · 인용 안내

수집 2026. 07. 23.출처 타입 WEB

인용 시 "요약 출처: AI Trends (aitrends.kr)"를 표기하고, 사실 확인은 원문 보기 기준으로 진행해 주세요. 자세한 기준은 운영 정책을 참고해 주세요.