본문 바로가기
조명·카메라·인터페이스·리사이즈·INT8 모델·엣지 장치·결과 출력으로 이어지는 엣지 AI 검사 체인에 일곱 가지 현장 실패 증상의 발생 지점을 표시한 도식
비전 알고리즘,  엣지 AI

엣지 AI 비전이 현장에서 안 돌아가는 이유

EDGE AI

20 MP 영상을 640 px 입력으로 줄이면 60 μm 흠집은 0.35칸이 되니, 엣지 AI 검사가 흔들릴 때는 재학습에 앞서 증상별 숫자 하나를 봅니다.

서버에서 검증한 모델이 라인에서 흔들리는 증상을 입력 크기, 양자화, 열, 지연, 대역폭, 입력 열화로 나눠 각각 먼저 잴 숫자를 계산했습니다.

읽는 시간 약 12분

서버에서 검증을 마친 검사 모델을 엣지 장치에 올리면, 처음 한동안은 대개 잘 돌아갑니다. 문제는 몇 주 뒤나 오후 시간대, 혹은 카메라를 한 대 늘린 날부터 시작돼요. 정확도가 조금 떨어지거나 판정이 가끔 늦는 식으로 나타나서, 원인을 모델 안에서만 찾게 됩니다.

증상과 원인을 잇지 않은 채 재학습부터 시작하면, 몇 주를 들여 모델을 바꾼 뒤에도 같은 증상이 돌아옵니다. 원인이 입력 크기나 열, 지연, 대역폭, 조명 변화처럼 모델 바깥에 있으면 재학습은 아무것도 고치지 못하고, 그동안 가장 작은 결함부터 조용히 빠져나갑니다.

예로 들 라인은 무광 사출 하우징과 광택 금속 단자가 섞인 부품에서 60 μm 흠집을 찾습니다. 카메라는 20 MP(5,472 × 3,648 px), 화소 분해능1은 20 μm/px라 흠집은 원본 영상에서 세 칸을 덮습니다. 제가 권하는 순서는 증상 하나에 숫자 하나입니다. 그 숫자를 보기 전에는 재학습을 시작하지 않습니다.

가는 결함만 사라지면 입력에서 칸 수를 잰다

전체 정확도는 1~2%p만 떨어졌는데 특정 결함 클래스만 사라진다면, 첫 의심은 입력 크기와 양자화입니다. 둘 다 평균 지표에는 거의 드러나지 않거든요. 그래서 저는 클래스별 재현율2과 모델 입력 기준 결함 칸 수를 첫 줄에 둡니다. 두 경우 모두 서버 쪽 검증 지표는 거의 그대로라서, 라인에서 놓친 결함 샘플을 클래스별로 다시 세어 봐야 드러납니다.

20 MP 영상을 640 × 640 px 입력에 통째로 줄여 넣으면 가로가 8.55분의 1이 되고, 화소 하나가 맡는 길이는 20 μm에서 171 μm로 늘어납니다. 원본에서 세 칸이던 60 μm 흠집은 0.35칸으로 줄어, 줄이는 과정에서 주변 화소와 섞여 사라집니다. 점 하나도 못 됩니다. 원본 해상도 그대로 640 px 조각으로 잘라 넣는 타일링3이라면 한 장이 가로 9개, 세로 6개, 54조각이 되고, 그 대가로 추론 횟수가 54배로 늡니다. 경량 모델의 출력 stride4가 결함을 한 칸 아래로 떨어뜨리는 구조는 지식 증류 글에, 조각 겹침과 지연은 타일링 추론 글에 계산해 두었습니다.

0.35칸

20 MP를 640 px로 줄였을 때 60 μm 흠집이 남는 폭

54조각

원본 해상도로 640 px씩 자를 때 한 장의 조각 수

0.8단계

양자화 범위가 4배로 넓어질 때 배경과 0.8만큼 다른 신호가 차지하는 단계 수

세 번째 카드는 양자화 이야기입니다. INT8 양자화5는 텐서의 값 범위를 256단계로 나누고, 비대칭 방식이라면 한 단계의 폭은 범위 ÷ 255예요. 어떤 특징 맵의 범위가 0~64이고 흠집과 배경의 차이가 0.8이라면 한 단계는 0.25, 차이는 3.2단계로 살아남습니다. 여기까지는 괜찮습니다. 그런데 캘리브레이션6 영상에 금속 단자의 하얗게 날아간 반사점이 섞여 범위가 0~256으로 넓어지면 한 단계가 1.0이 되고, 0.8의 차이는 한 단계도 못 채워 배경과 같은 코드로 묶일 수 있습니다. 두 숫자는 계산을 위한 가정이지만, 저대비 클래스만 재현율이 떨어지는 모양은 이 구조로 설명됩니다.

그래서 이 증상에서 볼 숫자는 양자화 전과 후의 클래스별 재현율입니다. 캘리브레이션 영상에 포화된 반사점이 얼마나 들어 있는지도 함께 봐야 하고요. 양자화 설정을 바꿔야 하는지는 INT8 양자화 글과 서버와 엣지의 정확도 차이를 다룬 글에 이어 적어 두었습니다.

느려지는 시간대가 원인을 가리킨다

속도 문제는 언제 느려지는지가 원인을 가리킵니다. 시간표가 단서예요. 오후에만 느려지면 열, 평균은 빠른데 가끔 늦으면 지연 꼬리, 카메라를 늘린 뒤 프레임이 빠지면 인터페이스부터 봅니다. 팬 없는 엣지 장치는 온도가 한계에 가까워지면 클록을 낮춰 추론 시간이 흔들리는데, 그 원인은 모델 파일 어디에도 보이지 않습니다. 모듈 온도와 추론 시간을 같은 시간축에 기록해야 보이고, 열 설계는 열 설계 글에 따로 계산해 두었습니다.

판정 지연은 트리거에서 출력까지 여러 구간의 합이고, 평균 대신 p99 지연7으로 봐야 합니다. 부품이 1초에 둘씩 지나가는 라인에서 1,000개 중 1개가 마감을 넘기면, 8시간에 57.6개가 마감 안에 판정을 받지 못합니다. 평균 추론 시간이 마감의 절반이어도 이 숫자는 줄지 않아요. 구간별로 쪼개는 방법은 p99 지연 예산 글에 있습니다.

카메라를 늘린 날부터 프레임이 빠진다면 링크부터 계산합니다. 20 MP 8비트 영상을 초당 2장 받으면 카메라 한 대에 39.9 MB/s, 두 대면 79.8 MB/s라 1GigE의 실효 대역폭8으로 가정한 약 115 MB/s 안에 듭니다. 세 번째 카메라를 같은 링크에 걸면 119.8 MB/s로 넘쳐요. 저라면 이때 모델은 그대로 두고 카메라별 실제 수신 MB/s를 찍어 봅니다. 링크를 넓히거나 나누는 선택지는 인터페이스 대역폭 글과 GigE Vision RDMA 글에 있습니다.

이상 탐지 모델이 정상 특징을 메모리 뱅크9에 쌓아 두고 비교하는 구조라면, 메모리 부족이나 탐색 지연이 따로 나타납니다. 이때 볼 숫자는 코어셋 비율에 따른 지연과 과검출이고, 그 교환은 메모리 뱅크 이상탐지 글에서 계산합니다. 메모리 뱅크를 줄이면 탐색은 빨라지지만 정상 변동을 덜 담아 과검출이 늘 수 있어서, 두 숫자를 같은 표에 놓고 고릅니다.

몇 주 뒤의 오검출은 입력이 변했다는 신호다

모델을 바꾸지 않았는데 성능이 서서히 변하면 입력이 변한 것입니다. 렌즈 오염, 조명 열화, 초점 이탈은 정확도에 드러나기에 앞서 평균 밝기와 선명도 같은 입력 통계에 흔적을 남깁니다. 매 프레임 두 숫자를 계산해 추이를 그리면, 재현율이 떨어지기에 앞서 원인 쪽이 움직이는 모습이 보입니다(입력 드리프트 감시 글).

LED 광출력이 떨어지는 경우는 경보 없이 미검출 쪽으로 먼저 진행합니다. 배경 계조 120 위에 계조 200으로 빛나는 결함을 절대 임계 170으로 잡는 검사라면, 광출력이 15% 떨어지는 순간 결함이 170으로 내려와 임계에 닿고 그 아래로는 놓칩니다. 15%면 충분합니다. 배경 대비 비율로 판정하면 결함은 200 ÷ 120 = 1.67배로, 임계 비율 1.42배 위에 그대로 남습니다. 빛이 고르게 줄어드는 한 비율은 흔들리지 않으니까요. 열화 속도와 재보정 주기는 LED 열화 글에 있습니다.

조명 브래킷을 다시 조인 뒤 무너지는 모델은 밝기 증강으로는 흉내 낼 수 없는 조명 각도 변화를 배우지 못한 경우입니다. 이때 볼 숫자는 조명 조건별 재현율이고, 방위각 하나를 떼어 처음 보는 조명에서 재현율이 얼마나 떨어지는지 재는 촬영 표는 조명 증강의 한계 글에 있습니다. 재학습은 이 두 숫자가 원인을 모델로 지목할 때 시작합니다.

증상 아홉 줄을 한 장에

앞의 숫자를 증상 순서로 늘어놓으면 한 장의 점검 지도가 됩니다. 그림은 증상과 먼저 볼 숫자, 원인 후보를 세 칸으로 이은 것이고, 아래 표는 같은 지도를 광학 쪽 WD와 분해능 확인까지 넓힌 것입니다.

정확도·드리프트·속도 증상별로 먼저 확인할 숫자와 원인 후보를 한 줄씩 연결한 엣지 AI 점검 지도
왼쪽 증상에서 가운데 숫자로 건너가는 화살표 하나가 재학습 전에 할 일의 전부입니다.

그림은 위에서부터 정확도, 드리프트, 속도 증상을 색으로 나눠 두었습니다. 숫자를 하나 재면 오른쪽 원인 후보가 하나나 둘로 좁혀지고, 남은 후보만 상세 글로 따라가면 됩니다. 제 눈에는 가운데 열이 이 지도의 몸통이에요.

구분 · 증상먼저 볼 숫자원인 후보 · 근거풀어 쓰면
① 최소 불량 사이즈 · 가는 결함만 놓친다모델 입력 기준 결함 칸 수(3칸 이상인가)리사이즈. 60 μm가 20 μm/px에서 3칸, 640 px로 줄이면 0.35칸줄인 영상에서 결함이 점 하나도 못 된다
① 최소 불량 사이즈 · 저대비 클래스만 재현율 저하양자화 전후 클래스별 재현율INT8 범위가 반사점에 끌려 넓어지면 0.8 차이가 0.8단계눈금이 굵어져 작은 차이가 묻힌다
② 광학 셋업 · 재설치나 조명 교체 뒤 변화WD와 화소 분해능 실측(20 μm/px 유지)WD가 바뀌면 모델 입력 기준 칸 수도 바뀜카메라 거리부터 다시 잰다
② 광학 셋업 · 몇 주 뒤 오검출·미검출 증가평균 밝기·선명도 추이LED 열화, 오염, 초점 이탈. 15% 저하면 절대 임계 170에 닿음입력이 먼저 변한다
② 광학 셋업 · 조명을 만진 뒤 붕괴조명 각도별 재현율학습에 없던 각도처음 보는 빛
③ 알고리즘 · 카메라 증설 뒤 프레임 누락카메라별 수신 MB/s20 MP 2 fps 세 대면 119.8 MB/s, 1GigE 실효 약 115 MB/s 초과길이 좁다
③ 알고리즘 · 오후에 느려짐모듈 온도와 추론 시간 시계열열로 인한 클록 저하더워지면 느려진다
③ 알고리즘 · 가끔 마감 초과구간별 p99 지연지연 꼬리, 대기열. 1,000개 중 1개면 8시간에 57.6개평균 뒤에 숨은 꼬리
③ 알고리즘 · 메모리·탐색 지연코어셋 비율별 지연과 과검출메모리 뱅크 크기비교할 사진첩이 너무 두껍다

아홉 줄 가운데 재학습이 바로 처방인 것은 조명 각도 일반화와 경량 모델 설계 정도입니다. 나머지는 입력 크기, 양자화 설정, 열, 지연, 대역폭, 입력 열화처럼 학습 밖의 설정과 물리량에서 시작합니다. 증상마다 숫자 하나를 먼저 재는 것만으로 재학습 루프의 상당 부분을 피할 수 있다는 것이 이 지도에서 제가 가장 아끼는 결론입니다. 숫자 하나가 재학습보다 쌉니다.

이 지도가 맞지 않는 라인도 있습니다. 제품과 결함 유형이 자주 바뀌는 다품종 라인이라면 적은 샘플로 빨리 다시 학습하는 체계가 원인 점검에 앞설 수 있습니다(Few-shot 이상탐지 글). 처리 시간 여유가 큰 오프라인 샘플 검사라면 지연과 열 항목의 순위가 내려가고, 서버 추론이 가능한 환경이라면 양자화와 열 제약 자체가 사라집니다. 금속 단자의 광택처럼 반사가 섞인 표면에서는 원인의 비중이 달라져, 어느 원인이 먼저인지는 샘플 테스트 전 확언 불가입니다.

증상에서 숫자로 건너가는 습관은 엣지 AI 일을 시작하는 사람에게 모델 구조보다 먼저 익힐 만한 기술입니다. 장비를 운영하는 쪽에서 보면, 온도와 지연, 밝기 로그를 처음부터 남기는 장비가 문제 하나를 푸는 데 드는 시간을 줄여 줍니다. 이 글은 기술 설명이며 투자 권유가 아닙니다. 자세한 내용은 면책조항을 참고하세요.

현장 노트

현장 문의가 온다면 저는 모델 파일보다 로그 세 줄을 먼저 요청합니다. 모듈 온도, 구간별 지연, 프레임 평균 밝기를 같은 시간축에 놓으면, 오후에만 늦어지는 열 문제와 몇 주에 걸친 조명 열화가 서로 다른 모양으로 갈라지기 때문입니다. 재설치를 거친 라인이라면 WD와 화소 분해능을 다시 재서, 60 μm 흠집이 모델 입력에서 여전히 세 칸 이상인지도 확인합니다. 그 세 숫자가 모델을 가리킬 때만 재학습 일정을 잡습니다.

현장 체크포인트

현장 노트의 로그 세 줄을 점검 항목으로 펼치면 아래와 같습니다.

  • WD와 화소 분해능이 설계값을 유지하는가? (재설치나 조명 교체 뒤 바뀌면 모델 입력 기준 칸 수도 바뀐다)
  • 모델 입력 기준으로 최소 결함이 세 칸 이상인가? (20 MP를 640 px로 줄이면 60 μm가 0.35칸)
  • 클래스별 재현율을 양자화 전후로 비교하고, 캘리브레이션 영상의 포화 반사점을 확인했는가? (범위가 넓어지면 저대비 신호가 묶인다)
  • 구간별 p99 지연과 모듈 온도를 같은 시간축으로 기록하는가? (평균만 보면 꼬리가 숨는다)
  • 카메라별 수신 대역폭이 링크의 실효 한계 안에 있는가? (20 MP 2 fps 세 대면 119.8 MB/s)
  • 입력 통계(밝기, 선명도)를 매 프레임 계산하고, 밝은 결함을 배경 대비 비율로 판정하는가? (광출력이 15% 줄어도 비율은 유지된다)

자주 묻는 질문

재학습은 언제 시작하나요?

입력 크기, 양자화, 열, 지연, 대역폭, 입력 통계를 확인해도 원인이 남을 때입니다. 특히 조명 조건별 재현율이 처음 보는 조명에서만 떨어진다면, 그 조명을 담은 영상을 모아 다시 학습하는 것이 맞는 처방입니다.

INT8 대신 FP16을 쓰면 문제가 사라지나요?

16비트 부동소수점은 표현할 수 있는 간격이 훨씬 촘촘해서 저대비 신호가 묶일 위험이 크게 줄지만, 메모리와 추론 시간이 늘어납니다. 엣지 장치가 FP16을 얼마나 빠르게 처리하는지는 장치마다 달라서, 같은 영상으로 재현율과 지연을 함께 재 보고 고릅니다.

타일링을 하면 추론 시간이 너무 길어지지 않나요?

54조각을 하나씩 돌리면 추론 횟수가 54배가 됩니다. 조각을 묶어 한 번에 처리하거나, 결함이 생길 수 있는 영역의 조각만 넣어 횟수를 줄이는 방법이 있고, 그 교환은 타일링 추론 글에 계산해 두었습니다.

용어 풀이

  • [1] 화소 분해능 pixel resolution, μm/px
    화소 한 칸이 검사 면에서 덮는 길이입니다. 영상을 줄이면 한 칸이 맡는 길이가 그만큼 늘어납니다. ↩
  • [2] 재현율 recall
    실제 결함 가운데 모델이 결함으로 잡아낸 비율입니다. 전체 평균보다 결함 종류별로 따로 봐야 작은 결함의 손실이 보입니다. ↩
  • [3] 타일링 tiling
    큰 영상을 모델 입력 크기의 조각으로 원래 해상도 그대로 잘라 넣는 방법입니다. 작은 결함을 지키는 대신 추론 횟수가 늘어납니다. ↩
  • [4] 출력 stride output stride
    모델 출력의 한 칸이 입력 영상에서 몇 화소를 대표하는지 나타내는 값입니다. stride 4면 출력 한 칸이 입력 4 × 4 화소를 맡습니다. ↩
  • [5] INT8 양자화 INT8 quantization
    모델의 실수 값을 8비트 정수 256단계로 바꿔 계산을 가볍게 하는 방법입니다. 자의 눈금을 굵게 바꾸는 것과 같아서 작은 차이가 같은 눈금에 묶일 수 있습니다. ↩
  • [6] 캘리브레이션 calibration
    양자화할 때 값의 범위를 정하려고 대표 영상을 모델에 흘려 보는 단계입니다. 이 영상에 극단적인 밝기가 섞이면 범위가 넓어집니다. ↩
  • [7] p99 지연 99th percentile latency
    지연 시간을 짧은 순서로 늘어놓았을 때 99%째에 해당하는 값입니다. 평균은 괜찮아도 100번 중 1번 늦는 꼬리를 드러냅니다. ↩
  • [8] 대역폭 bandwidth, MB/s
    링크가 1초에 실어 나를 수 있는 데이터 양입니다. 카메라 여러 대가 한 링크를 나눠 쓰면 합계가 이 안에 들어야 합니다. ↩
  • [9] 메모리 뱅크 memory bank
    정상품 영상에서 뽑은 특징을 쌓아 두고 새 영상과 비교하는 저장소입니다. 클수록 정확해지지만 메모리와 탐색 시간이 늘어납니다. ↩

참고 자료

  • Jacob et al., Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference (2017): 실수 r과 정수 q의 관계 r = S(q − Z), 8비트 정수 연산 추론
  • 계산식: 리사이즈 뒤 화소 분해능 = 원래 분해능 × (원본 폭 ÷ 입력 폭), 조각 수 = ⌈폭 ÷ 640⌉ × ⌈높이 ÷ 640⌉, 비대칭 INT8 한 단계 = 범위 ÷ 255, 대역폭 = 가로 × 세로 × 바이트/화소 × 프레임 속도, 마감 초과 수 = 부품 수 × 초과 비율. 계산 가정: 20 MP(5,472 × 3,648 px), 20 μm/px, 1GigE 실효 115 MB/s, 특징 맵 범위 0~64와 0~256, 결함 계조 200·배경 120·임계 170

함께 읽으면 좋은 글 — 서버에선 잘 됐는데 엣지에선 왜 정확도가 떨어지나 · 640×640으로 줄이면 미세 결함은 어디로 갈까 · 평균 지연이 마감 안에 있어도 안전하지 않은 이유

2005년부터 생산설비의 기계설계와 프로젝트 관리를 맡아 온 엔지니어입니다. 설비에 들어가는 카메라·렌즈·조명을 수식과 공개 자료로 계산하고, 가정과 출처를 함께 밝혀 기록합니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다