[Triton] 모듈 언로드 테스트 비결정적 실패 수정 — GC 비활성화로 안정성 확보
PR 링크: triton-lang/triton#9520 상태: Merged | 변경: +7 / -1
들어가며
Triton의 런타임은 커널 모듈의 생명주기를 관리하며, 모듈이 언로드될 때 사용자 정의 hook을 호출할 수 있다. test_module_load_unload 테스트는 이 메커니즘이 올바르게 동작하는지 검증하는데, 간헐적으로 실패하는 비결정적(non-deterministic) 버그가 있었다.
원인은 Python의 garbage collector다. GC가 테스트 도중 예기치 않은 시점에 객체를 수거하면서 module_unload callback이 추가로 호출되어 counter 값이 기대와 달라지는 문제였다.
핵심 코드 분석
Before: GC 간섭 가능
def test_module_load_unload():
@triton.jit
def kernel(out_ptr, val) -> None:
tl.store(out_ptr, val)
counter = 0
def module_unload(*args, **kwargs):
nonlocal counter
counter -= 1
triton.knobs.runtime.module_unload_hook.add(module_unload)
# ... 테스트 실행
assert counter == 0
After: GC 비활성화로 결정적 실행 보장
def test_module_load_unload(fresh_knobs):
@triton.jit
def kernel(out_ptr, val) -> None:
tl.store(out_ptr, val)
counter = 0
def module_unload(*args, **kwargs):
nonlocal counter
counter -= 1
# turn off python garbage collector, so the callback is not called
# in the garbage collector
gc.disable()
triton.knobs.runtime.module_unload_hook.add(module_unload)
# ... 테스트 실행
assert counter == 0
assert pre_compile.module is None
# turn on garbage collector
gc.enable()
변경 사항은 세 가지다:
fresh_knobsfixture 추가: 테스트 간 knob 상태 격리를 보장한다.gc.disable(): hook 등록 전에 GC를 꺼서 테스트 도중 예기치 않은 객체 수거를 방지한다.gc.enable(): 테스트 완료 후 GC를 다시 활성화한다.
왜 이게 좋은가
- 비결정적 실패 해소: GC 타이밍에 의존하던 테스트가 이제 결정적으로 동작한다. CI에서 간헐적으로 빨간불이 들어오는 문제가 사라진다.
- 최소한의 변경: 테스트 로직 자체를 바꾸지 않고, GC 제어만 추가하여 근본 원인을 해결했다.
- fixture 기반 격리:
fresh_knobs를 통해 다른 테스트와의 상태 간섭도 차단했다.
정리
Python GC는 예측 불가능한 시점에 객체를 수거하므로, callback 기반 테스트에서 비결정적 실패의 원인이 될 수 있다. 이 PR은 테스트 구간에서 GC를 명시적으로 비활성화하는 간단한 방법으로 문제를 해결한다.
참고 자료
이 글은 AI(Claude)의 도움을 받아 작성되었습니다. 핵심 코드와 explaination은 실제 PR diff를 기반으로 합니다.
관련 포스트
PR Analysis 의 다른글
- 이전글 [Open WebUI] 공유 채팅 목록에서 불필요한 JSON 역직렬화를 제거하여 응답 속도 개선
- 현재글 : [Triton] 모듈 언로드 테스트 비결정적 실패 수정 — GC 비활성화로 안정성 확보
- 다음글 [Open WebUI] O(n²) 시간 복잡도 메시지 리스트 생성 버그 수정
댓글