GPU 비전 파이프라인
8대 카메라 실시간 GPU 추론 파이프라인과 품목별 머신 비전 라이브러리
배경
컨베이어 위를 고속으로 지나가는 농산물을 산업용 카메라 최대 8대로 촬영하고, GPU 기반 YOLOv8 추론과 머신 비전 분석을 실시간으로 수행하는 시스템이다. 1년간 기능이 누적되면서 메인 프로세스에 초기화·프로세스 빌드·CPU 할당·설정 관리가 혼재되었고, 프로세스 간 자원 경쟁으로 레이턴시가 불안정해졌다. 현장마다 설비 제조사가 달라 프로토콜을 매번 개별 대응해야 했고, 8종 이상의 농산물에 대한 머신 비전 알고리즘도 확장 가능한 구조가 필요했다.
시스템 구조
- 실행 파이프라인:
libs/{camera, inference, socket, sync, transfer, db}로 나뉜 실시간 파이프라인.main.py가torch.multiprocessing.set_start_method('spawn')으로 프로세스를 띄우고,Queue기반 Producer-Consumer로 10여 개 프로세스를 디커플링한다. - 비전 알고리즘 라이브러리:
pyproject.toml을 가진 독립 Python 패키지.BaseProcessor(abc.ABC) 추상화 위에 6개 품목 runner,mv/8 품목 처리기,grading·inference·io_schemas서브패키지. - 설비 프로토콜 플러그인: 9개 업체 Sender(
aiofarm·aiofarm_weight·gj_prusen·multi_tp_rail·prusen_wandong·snp·tp·tp_rail·wh)가 공통 베이스를 상속해 업체별 차이만 구현한다. - Arduino 트리거: Mega 2560 펌웨어가 광전 센서 신호를 받아 다중 카메라 트리거를 밀리초 정밀도로 생성한다. 품목별 변형 펌웨어 7종.
해결 과정
파이프라인 모듈화. 메인 프로세스에 얽혀 있던 캡처·추론·MV·전송을 libs/ 하위 서브패키지로 나눠 각 단계가 자기 책임만 지도록 했다. FlowControls로 데이터 흐름 라우팅을 집중시키고, Queue 경계에 Backpressure와 Timeout을 걸어 한 프로세스 정체가 전체 파이프라인을 데드락시키지 않게 한다.
CPU Affinity 최적화. psutil로 물리 코어를 탐지해 프로세스별 전용 코어를 할당한다. 추론·MV·전송·캡처 프로세스가 같은 코어에서 경쟁하지 않게 분리해 레이턴시 분산을 줄였다.
설비 Sender 플러그인. 현장별 설비 제조사 프로토콜이 달라 동적 로딩이 필요했다. 베이스 Sender 한 개를 두고, 업체별 파일은 전송 포맷·시퀀스 차이만 오버라이드한다. 신규 업체가 들어오면 Sender 파일 한 개만 추가하면 된다.
품목 프레임워크. 품목별 머신 비전 알고리즘이 섞여 있어 신규 품목 진입 장벽이 컸다. BaseProcessor(abc.ABC)를 정의하고 PredictYoloV8·MVCalculators·MVInput/MVOutput을 표준 인터페이스로 고정했다. 품목 개발자는 {품목}_run.py에서 BaseProcessor를 상속해 process_single_image()만 구현한다. 본인은 라이브러리 아키텍처를 설계했고, 개별 품목의 머신 비전 알고리즘은 팀원들이 독립적으로 개발했다.
독립 패키지화. 비전 알고리즘 라이브러리는 pyproject.toml을 갖춘 독립 패키지로 분리했다. 실행 파이프라인은 pip install로 당겨 쓰기 때문에, 품목 알고리즘 변경이 파이프라인 레포에 섞이지 않는다.
Arduino 품목별 펌웨어. 컨베이어 광전 센서 신호를 받아 카메라 트리거 신호를 보내는 Mega 2560 펌웨어를 7개 품목 변형으로 관리한다. 현장별 브랜치로 펌웨어를 배포.
성과
libs/서브패키지 6개(camera / inference / socket / sync / transfer / db)로 실시간 파이프라인 모듈화.- 9개 설비 업체 프로토콜을 Sender 플러그인으로 통합, 신규 업체는 파일 1개 추가로 확장.
- 비전 알고리즘 라이브러리 독립 패키지로 분리, BaseProcessor 추상화 위에서 6 품목 runner + 8 품목 mv 처리기를 팀원들이 독립 개발.
- libjpeg-turbo JPEG 인코딩으로 네트워크 대역폭 90% 절감, 다중 GPU 설정으로 추론 처리량 선형 확장.
- Arduino Mega 2560 기반 카메라 트리거 7 품목 변형, 밀리초 정밀도.
torch.multiprocessing(spawn)+ Queue Backpressure로 프로세스 간 완전 디커플링, 데드락 방지.