PrintGuard 2.0 — ShuffleNetV2 + few-shot prototypical network, LiteRT를 통한
요약
ShuffleNetV2 기반의 few-shot 결함 탐지기인 PrintGuard 2.0을 소개합니다. LiteRT를 활용해 모델을 경량화하였으며, CPython과 브라우저(Pyodide) 환경 모두에서 동일한 코드로 실행 가능한 단일 Python 엔진 아키텍처를 구현했습니다.
핵심 포인트
- LiteRT를 통한 5MB 규모의 TFLite 모델 최적화
- CPython과 Pyodide 환경을 모두 지원하는 단일 엔진 아키텍처
- 카메라 및 조명 환경에 맞춘 실시간 민감도/임계값 조정 기능
- 지연 시간 기반의 동적 추론 스케줄링 및 Max-Min Fairness 적용
안녕하세요 여러분,
약 1년 전 이곳에 ShuffleNetV2 백본을 기반으로 prototypical network에 의해 분류되는 few-shot FDM 결함 탐지기인 PrintGuard를 공유했습니다. 이는 제 학위 논문의 모델로, hub 및 웹 UI와 함께 패키징되었습니다. 오늘 v2.0을 출시하며, 이는 모델 주변의 모든 것을 완전히 새로 작성한 버전이기에 무엇이 바뀌었고 무엇이 바뀌지 않았는지 설명해 드리고자 합니다.
바뀌지 않은 것은 모델입니다. 여전히 가장 가까운 프로토타입(nearest prototype)에 의해 분류되는 ShuffleNetV2 인코더이며, Edge-FDM-Fault-Detection(저장소에 기술 문서 포함)을 위한 few-shot FDM 결함 탐지를 위해 학습되었습니다. 바뀐 것은 런타임(runtime)입니다. 이제 모델은 LiteRT를 통해 내보낸 약 5 MB의 TFLite 파일이며, 가장 가까운 프로토타입에 의해 분류됩니다. 또한 프린터별 민감도 및 임계값 슬라이더가 프로토타입 거리(prototype distances)에 직접 매핑되어 있어, 재학습 없이도 카메라와 조명 환경에 맞춰 조정할 수 있습니다.
이 서브레딧(sub)에서 흥미로울 부분은 모델 주변의 아키텍처입니다. v2.0은 CPython(hub 모드)과 브라우저의 Pyodide(local 모드)에서 수정 없이 실행되는 단일 Python 엔진입니다. 모델별 모든 사항은 런타임당 하나의 Platform 구현으로 제한됩니다. 두 모드는 동일한 파일을 실행하므로 서로 달라질 수 없습니다. Platform 컨트랙트(contract)의 메서드들은 이식되지 않는(not portable) 기능들입니다: infer(rgb), discover_cameras(), open_camera(id, source), http(...), encode_jpeg(rgb), load_state / save_state. CPython 측에서 infer는 CPU 스레드 상의 ai-edge-litert이며, discover_cameras는 MediaMTX 경로 목록을 탐색하고, open_camera는 RTSP 스트림당 하나의 PyAV 리더 스레드입니다. 브라우저 측에서 infer는 JS 브릿지를 통한 WASM 상의 LiteRT.js이며, discover_cameras는 enumerateDevices()이고, open_camera는 getUserMedia + canvas grabs입니다.
UI는 프레젠테이션 전용이며 단일 JSON 명령/이벤트 프로토콜을 사용합니다. hub 모드에서는 WebSocket을 통해, local 모드에서는 페이지 내 Pyodide 브릿지를 통해 통신합니다. 엔진은 자신이 어떤 전송 방식(transport)을 사용 중인지 알 수 없습니다.
모드별 로직은 다른 어디에도 존재하지 않습니다. 특정 기능에 런타임 서비스 (runtime service)가 필요한 경우, 양측 모두에서 플랫폼 (Platform) 계약을 확장합니다.
추론 스케줄링 (Inference scheduling)은 완전히 동적이며 공정성 (fairness)을 고려합니다:
관찰된 추론 지연 시간 (inference latency)의 평활화된 추정치를 통해 지속 가능한 총 처리량 (workers / latency)을 지속적으로 산출합니다.
해당 용량은 사용 중인 카메라들에 걸쳐 수위 조절 (water-filled) 방식으로 배분됩니다 (max-min fairness): 어떤 카메라도 고유의 fps를 초과하여 할당되지 않으며, 남는 용량은 이를 사용할 수 있는 카메라로 흐릅니다.
유휴 상태인 워커 (worker)는 가장 오래된 작업이 밀려 있는 카메라를 선택하여, 디스패치 (dispatch) 시점에 해당 카메라의 가장 최신 프레임을 가져옵니다. 프레임은 시퀀스 식별자 (sequence identity)를 가지고 있으므로, 동일한 프레임이 두 번 추론되지 않으며 결과는 항상 백로그 (backlog)가 아닌 현재 상태를 나타냅니다.
RTSP의 경우, MediaMTX는 연결 시 버퍼링된 GOP를 버스트 (burst) 전송합니다. 따라서 스트림 fps는 가능한 경우 SDP의 average_rate를 신뢰하며, 그렇지 않은 경우 워밍업 (warm-up) 이후에만 측정합니다.
결함 파이프라인 (defect pipeline)은 프린터별 점수 스트림 (score stream) 상단의 모니터입니다. N개의 연속된 프레임에서 score ≥ threshold 조건이 충족되면, 연결된 OctoPrint 또는 Moonraker 서비스에 대해 구성된 작업(알림만 수행, 일시 정지, 또는 취소)을 트리거하며, 실패 시 재시도합니다. 알림 이벤트는 해당 작업과 그 결과를 포함하며, UI 에러 피드 (error feed)에 복사본이 전달되고, 스냅샷은 활성화된 모든 알림 채널 (ntfy, Telegram, Discord)로 전송됩니다.
페일 세이프 (fail-safe) 동작은 제가 가장 피드백을 받고 싶은 부분인데, 이에 대해 확고한 견해를 가지고 있기 때문입니다. 프린터의 감시 상태 (watching state)가 추론을 제어합니다:
연결된 서비스가 '감시 중(Watched)?'이라고 보고할 때:
- 연결된 서비스 없음: 아니요 $\rightarrow$ 제어할 대상 없음
- 출력 중: 예 $\rightarrow$ 작업에 감시가 필요함
- 아직 상태 미정 / 알 수 없음: 예 $\rightarrow$ 판단 불가 $\rightarrow$ 감시 수행
- 오프라인 (연결 불가): 예 $\rightarrow$ 신호를 놓치고 있음 $\rightarrow$ 모니터링을 중단해서는 안 됨
- 유휴 / 일시 정지 / 에러: 아니요 (대기 상태) $\rightarrow$ 확실히 출력 중이 아님
오직 긍정적인 '출력 중 아님(not printing)' 상태만이 추론을 중단시킵니다. 워치독 (watchdog)은 카메라 연결이 끊기거나, 피드가 멈추거나, 프린터 서비스가 응답을 중단할 때 대시보드와 알림 채널을 통해 경고를 보내며, 실패한 일시 정지 명령은 절대 무시되지 않고 공지됩니다.
이러한 입장이 프린터 서비스의 신뢰도가 제각각인 여러 대의 프린터를 운영하는 사람들에게 어떻게 작용할지 매우 궁금합니다.
실시간 브라우저 데모(Pyodide + LiteRT.js WASM 기반의 전체 엔진)가 준비되어 있으며, Docker 이미지는 멀티 아키텍처(multi-arch)를 지원합니다. 또한 아키텍처 문서를 통해 엔진 레이아웃과 결함 파이프라인(defect pipeline)의 다이어그램과 함께 위 내용들을 더 자세히 다루고 있습니다.
이번 버전은 메이저 버전입니다. 1.x 버전의 어떤 것도 마이그레이션되지 않으며, 2.0 허브는 새로운 설정에서 시작됩니다. 공정성 스케줄러(fairness scheduler), CORS / mixed-content / host.docker.internal 관련 에지 케이스(edge cases), 그리고 LiteRT ↔ Pyodide 브리지(bridge)와 관련된 이슈들을 적극적으로 환영합니다. 결함 탐지(failure detection) 기술이 오픈 소스로 유지되어, 모두에게 로컬에서 접근 가능하도록 합시다.
/u/oliverbravery 가 r/MachineLearning 에 제출함
[link] [comments]
AI 자동 생성 콘텐츠
본 콘텐츠는 r/OpenAI Codex (search)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기