TrotVote
[IT 심층 분석]

딥러닝 기반 실시간 노이즈 감소(NR) 연산의 NPU 메모리 누수 원인 파악 및 타파

김민준 · IT 시스템 엔지니어|
야간 투시경에 버금가는 극한의 저조도 환경에서도 노이즈가 없는 깨끗한 영상 결과물을 얻기 위해 우리는 최근 텐서 연산을 전담하는 하드웨어 즉 NPU(Neural Processing Unit)에 자체 학습시킨 이미지 디노이징 딥러닝 모델을 얹어 실시간으로 처리하는 파이프라인을 구축했습니다. 하지만 이 혁신적인 아키텍처는 스트리밍이 20분을 넘어가면 급작스럽게 프레임이 깨진다거나 화면 전체가 픽셀화되어 녹색 노이즈 스크린으로 변해버리는 치명적 결함을 동반했습니다. 리눅스의 시스템 감시 도구 top이나 htop 상에서 추적할 수 있는 일반적인 프로세스의 램 점유율 지표는 지극히 정상이어서 개발 초창기에는 센서 발열 문제나 이미지 ISP 파이프라인의 하드웨어 타이밍 클럭 엇갈림으로 인한 데이터 손상으로 헛발질을 계속했습니다. 수 주간의 막막한 원인 규명 끝에 실마리는 운영체제 밖의 폐쇄된 세계인 NPU의 전용 SRAM 영역에서 찾아냈습니다. 디버그 브리지를 통해 NPU 펌웨어 내부의 레지스터 덤프를 주기적으로 끄집어내어 파이썬 스크립트로 상태 천이 다이어그램을 그리며 분석한 결과 NPU 내부의 텐서 연산 버퍼 큐에서 명백한 메모리 리크가 누적되고 있었습니다. 커스텀 텐서플로우 라이트 빌드의 딜리게이트(Delegate) 코드가 매 프레임마다 결과 텐서를 할당받아 처리한 뒤 이를 ISP로 반환하는데 그 연결 고리에서 해제 명령 즉 Deallocate 콜백이 커널 드라이버를 통해 NPU로 제때 도달하지 않고 허공으로 증발해버리는 끔찍한 버그가 암약하고 있었던 것입니다. 한 장의 프레임이 수 밀리초만에 스쳐 지나가는 동안 해제되지 않은 메모리 블록이 첩첩산중으로 쌓이자 방어력이 붕괴한 NPU가 엉뚱한 주소의 찌꺼기 메모리를 새로운 비디오 데이터인 줄 알고 인코딩해버렸기 때문에 화면이 초록색 쓰레기 픽셀로 변했던 것입니다. 이 원인은 결국 C++ 바인딩 브릿지 계층에서의 스마트 포인터 복사 오류 임을 파악해냈고 저는 텐서 메모리의 생명 주기를 완전히 개조하기 시작했습니다. 매 회차마다 새로 할당하고 해제하는 번거롭고 위험한 동적 방식 대신 처음부터 고정된 3개의 대형 텐서 버퍼 풀(Buffer Pool)을 마련해놓고 라운드 로빈 방식으로 번갈아가며 포인터만 재활용하는 오브젝트 풀링 아키텍처를 도입했습니다. 호스트 프로세스는 더 이상 NPU에 해제 요청을 보낼 필요 없이 이미 존재하는 버퍼에 다음 프레임 데이터를 덮어씌운 뒤 동기화 장막인 메모리 배리어만 호출해주면 그만인 매우 단순하고 견고한 루틴을 적용한 것입니다. 이렇게 구조를 변혁하자 누수의 근본적인 경로가 물리적으로 차단되어 오프젝트 자체의 불멸성이 확보되었습니다. 안정성 확보는 물론이거니와 객체 생성과 소멸에 동원되던 시스템콜 부하가 사라짐과 동시에 딥러닝 디노이징 모델의 추론 속도 지표마저 15퍼센트나 수직 상승하는 예기치 못한 부산물을 얻어냈습니다. 메모리가 한정적이고 연산 빈도가 극에 달하는 실시간 엣지 지능형 카메라 디바이스의 아키텍처에서 메모리의 생성과 소명 사이클은 극단의 악이라 할 수 있으며 하드웨어 가속기 내부의 불투명한 메모리 누수는 개발자에게 지옥을 선사한다는 교훈을 강렬히 남겼죠. 이는 임베디드 AI 시대의 시스템 엔지니어가 단순히 모델의 정확도뿐만 아니라 밑바닥 네이티브 메모리의 잔여물 한 톨까지 설계도를 장악하고 통제해야 한다는 것을 적나라하게 증명하는 사건이었습니다.