메모리뱅크 이상탐지는 정상 패치를 전부 기억해야 할까
EDGE AI
정상 패치를 모두 저장하면 6.29 GB, 코어셋 1 %면 62.9 MB입니다. 그래도 탐색은 이미지당 2.58 × 1012 곱셈-누산이라 비율을 정하는 쪽은 메모리보다 탐색 시간입니다.
사출 커넥터 하우징을 20 μm/px로 찍는 엣지 장치에서 입력 타일링, 패치 셀 크기, 메모리뱅크 크기, 코어셋 비율, 탐색 연산량과 판정 임계를 차례로 계산했습니다.
읽는 시간 약 12분
사출 성형 커넥터 하우징처럼 불량 샘플을 모으기 어려운 공정에서는 정상품만으로 학습하는 메모리뱅크 이상탐지(PatchCore1 계열)가 자주 쓰입니다. 사전학습된 백본에서 정상 영상의 패치 특징을 뽑아 저장해 두고, 검사 영상의 각 패치가 가장 가까운 정상 패치와 얼마나 떨어져 있는지로 이상 점수를 매기는 방식이죠. 서버에서 잘 돌던 이 구조를 엣지 장치로 옮기면 메모리와 탐색 지연이라는 두 문제가 한꺼번에 드러납니다. 메모리뱅크를 근거 없이 줄이면 정상 변동이 기억에서 빠져 과검출이 늘고, 줄이지 않으면 탐색 지연이 택트를 넘어 전수 검사가 샘플링 검사로 물러납니다.
표면부터 확인합니다. 커넥터 하우징의 PBT 수지는 대부분 무광이라 돔 확산 조명 아래에서 고른 밝기로 찍히지만, 금형 게이트 자국 주변은 광택이 달라 같은 조명에서도 밝기와 질감이 바뀝니다. 이 광택 차이가 그대로 정상 변동의 폭이 되고, 메모리뱅크가 기억해야 할 패치의 종류를 늘립니다. 그래서 아래 크기와 비율은 무광 영역 기준이며, 광택 게이트부나 투명 수지에서 필요한 뱅크 크기는 샘플 테스트 전 확언 불가입니다.
가정은 이렇습니다. 2,448 × 2,048 px, 화소 3.45 μm 카메라에 25 mm 렌즈를 달아 렌즈 주점에서 약 170 mm 떨어진 곳(WD2 150 mm 이상 확보)에서 FOV 49 mm × 41 mm를 20 μm/px로 찍습니다. 가장 작은 결함은 직경 80 μm 흑점이고, 백본 특징은 stride 8 층에서 뽑아 3 × 3 이웃을 모은 384차원 FP163 벡터, 정상 학습 영상은 100장입니다. 엣지 장치의 실효 거리 계산 성능은 초당 5 × 1012 곱셈-누산4, 라인 택트는 500 ms로 둡니다.
통째 축소에서 80 μm 흑점은 0.84 px가 된다
메모리뱅크 방식의 검출 하한은 학습 데이터의 양보다 입력 해상도와 백본의 특징 stride로 먼저 정해집니다. 가장 결정적인 단계는 카메라 원본을 백본 입력 크기로 줄이는 전처리입니다. 2,448 × 2,048 px 영상을 통째로 512 × 512 px로 줄이면 가로 95.7 μm/px, 세로 80.1 μm/px가 되어 직경 80 μm 흑점은 가로 기준 0.84 px로 한 화소에도 못 미칩니다. 축소가 가로세로 비율까지 바꿔 버리는 것도 문제예요.
그래서 원본 해상도를 지킨 채 512 px 타일로 자릅니다. 가로 2,448 px는 타일 5장(이음마다 28 px 겹침), 세로 2,048 px는 정확히 4장이라 이미지당 20장이 되고, 같은 흑점이 4 px로 살아납니다. 타일 20장이 해상도의 대가이고, 이 20이라는 숫자가 뒤에 이어지는 메모리와 탐색 연산에 그대로 곱해집니다.
패치 셀 160 μm 안에서 흑점은 절반을 차지한다
이상 점수는 패치5 특징 단위로 매겨집니다. 백본 중간 층의 stride가 8이면 특징맵 한 칸은 입력 8 × 8 px를 요약하고, 3 × 3 이웃까지 모으면 실제로 반영되는 영역은 그보다 넓습니다. 결함이 이 영역에서 차지하는 비율이 작을수록 패치 특징은 정상 질감 쪽으로 끌려가 이상 점수가 낮아집니다.

20 μm/px에 stride 8을 곱하면 패치 셀 한 칸은 160 μm입니다. 80 μm 흑점은 4 px로 셀 폭의 절반을 차지하고, 폭 60 μm 흐름 자국은 3 px, 미성형 결손 200 μm는 10 px로 셀 1.25칸입니다. 제 기준으로는 최소 결함이 셀 폭의 절반 안팎을 차지하도록 타일링과 FOV를 정한 뒤에야 메모리뱅크 크기를 논할 수 있고, 80 μm 흑점은 그 기준에 겨우 걸려 있습니다. 여유가 없는 셈이죠.
정상 패치를 모두 저장하면 6.29 GB다
메모리뱅크6 크기는 정상 영상 수 × 영상당 타일 수 × 타일당 패치 수 × 특징 차원 × 자료형 크기입니다. 곱셈 구조라서 해상도를 지키려고 타일을 늘리는 순간 메모리도 그대로 비례해 커집니다. 정상 100장, 타일 20장, 타일당 64 × 64 = 4,096 패치, 384차원, FP16 2바이트를 넣으면 8,192,000 패치 × 768바이트 ≈ 6.29 GB입니다. 엣지 장치에는 들어가지 않습니다.
코어셋 서브샘플링7은 특징 공간을 고르게 덮는 대표 패치만 남기는 탐욕적 선택 절차입니다. 이미 고른 패치에서 가장 먼 패치를 차례로 더하는 방식이라 무작위 추출과 달리 드물게 나타나는 정상 변동을 먼저 챙기는 성질이 있어요. 1 %로 줄이면 81,920 패치, 약 62.9 MB가 되어 엣지 장치의 메모리에 들어오고, 0.1 %면 약 6.3 MB까지 내려갑니다. 비율을 낮출수록 게이트 자국 주변의 광택 변화나 파팅 라인, 로트별 색조 차이 같은 드문 정상 변동이 뱅크에서 빠질 위험도 커집니다.
코어셋 비율의 상한은 탐색 시간이 정한다
엣지 배포에서 먼저 한계에 닿는 곳은 대개 메모리가 아닌 최근접 탐색8 연산입니다. 검사 영상의 모든 패치가 뱅크 전체와 거리를 계산하면 연산량은 쿼리 패치 수 × 뱅크 크기 × 특징 차원에 비례하고, 이 셋업의 쿼리는 이미지당 20 × 4,096 = 81,920개입니다. 코어셋 1 % 뱅크와 전수 탐색하면 81,920 × 81,920 × 384 ≈ 2.58 × 1012 곱셈-누산이에요.
가정한 실효 성능 초당 5 × 1012 곱셈-누산으로 나누면 1 %는 515 ms로 택트 500 ms를 혼자 다 씁니다. 0.3 %면 24,576 패치, 18.9 MB, 155 ms이고, 0.1 %면 52 ms까지 내려갑니다. 그래서 저는 코어셋 비율의 상한을 탐색 시간으로, 하한을 정상 검증 세트의 과검출로 정하고, 이 셋업이라면 0.3 %에서 출발해 과검출이 생기는 위치를 지도로 확인합니다.
근사 최근접 탐색9은 이 연산을 크게 줄여 주지만, 근사 오차가 이상 점수에 그대로 섞입니다. 이상 점수가 가장 가까운 정상 패치와의 거리라서, 근사 탐색이 조금 먼 이웃을 고르면 정상 패치의 점수가 체계적으로 올라가 과검출 쪽으로 기웁니다. 그래서 코어셋 비율을 검증이 허락하는 만큼 낮춘 뒤 남은 부족분만 근사 탐색으로 메우고, 적용 전후 정상 검증 세트의 점수 분포가 얼마나 옮겨 갔는지 비교합니다.
임계 99.9 백분위에는 정상 이미지 1,000장이 필요하다
판정은 영상마다 가장 큰 패치 점수를 이상 점수로 두고, 정상 검증 세트에서 이 점수의 99.9 백분위를 임계로 잡는 방식이 흔합니다. 그런데 정상 검증 이미지가 200장이면 99.9 백분위 위에 놓이는 표본은 0.2장이라, 그 임계는 사실상 가장 높은 한 장의 점수가 정하게 됩니다. 한 장짜리 임계는 다음 로트에서 쉽게 흔들립니다.
그래서 99.9 백분위를 쓰려면 저는 정상 검증 이미지를 최소 1,000장 모읍니다. 정상품은 모으기 쉬우니 이 조건은 비용이 크지 않고, 그래도 모으기 어렵다면 99 백분위에 여유를 더하는 쪽으로 기준을 바꿉니다. 근사 탐색으로 바꾸거나 코어셋 비율을 바꾼 뒤에는 임계를 처음부터 다시 추정합니다.
80 μm 흑점을 잡는 조건을 한 표에 놓으면
결함 크기와 광학 셋업, 메모리뱅크 파라미터를 한 표에 모았습니다. 셀 크기와 메모리, 연산량은 모두 위의 가정에서 계산했습니다.
| 구분 | ① 최소 불량 크기 | ② 광학 셋업 · WD | ③ 알고리즘 파라미터 |
|---|---|---|---|
| 흑점 · 이물 | 직경 80 μm = 4 px (20 μm/px), 패치 셀 160 μm의 1/2 | 2,448 × 2,048 px, 화소 3.45 μm, 25 mm 렌즈, FOV 49 × 41 mm, 돔 확산 조명, WD 150 mm 이상(주점 기준 물체 거리 약 170 mm) | 512 × 512 px 타일 20장(5 × 4), 축소 없음. 통째 축소 시 95.7 μm/px로 0.84 px |
| 흐름 자국 · 스크래치 | 폭 60 μm, 길이 400 μm = 3 × 20 px | 무광 PBT 기준, 광택 게이트부는 따로 확인 | stride 8 층, 3 × 3 이웃, 384차원 FP16 |
| 미성형 결손 | 폭 200 μm = 10 px, 셀 1.25칸 | WD는 돔 조명 높이까지 포함해 실측 | 메모리뱅크 원본 8,192,000 패치 ≈ 6.29 GB, 코어셋 0.3 % 24,576 패치 ≈ 18.9 MB |
| 탐색 · 판정 | 이미지당 쿼리 81,920 패치 | 실효 성능 초당 5 × 1012 곱셈-누산 가정 | 탐색 155 ms(0.3 %) / 515 ms(1 %), k = 1 최근접 거리, 임계 = 정상 검증 1,000장 이상의 99.9 백분위 |
이 표의 실질적인 병목은 메모리가 아니라 탐색입니다. 80 μm 흑점을 셀 절반으로 지키려고 택한 타일 20장이 쿼리 수와 뱅크 원본에 동시에 곱해져, 코어셋 1 %에서도 이미지당 2.58 × 1012 곱셈-누산이 남고 탐색만으로 택트를 넘깁니다. 0.3 %는 탐색을 155 ms로 묶는 대신 드문 정상 변동을 덜 기억하니, 그 대가는 과검출 위치 지도로 확인해야 합니다.
메모리뱅크 대신 다른 방식이 맞는 경우
불량 샘플을 충분히 모을 수 있고 결함 유형이 정해져 있다면 지도 학습 세그멘테이션이나 분류 모델이 경계 정밀도와 추론 비용 모두에서 유리하고, 최근접 탐색 자체가 필요 없습니다. 색상 다품종이나 로트별 질감 차이 같은, 정상 외관 변동이 아주 큰 제품은 뱅크가 급격히 커지거나 과검출이 늘어나므로 품종별 뱅크 분리부터 검토합니다. 검사 영역이 몇 mm 수준으로 작다면 뱅크 원본이 작아 코어셋 없이 전수 탐색해도 택트 안에 들어오고, 이때는 서브샘플링이 오히려 불필요한 정보 손실입니다.
사출품 가운데 광택 표면이나 투명 수지는 정반사와 난반사가 패치 특징을 크게 흔들어 정상 변동의 폭 자체가 달라집니다. 그래서 위의 뱅크 크기와 코어셋 비율이 그런 표면에도 맞을지는 샘플 테스트 전 확언 불가이고, 저는 금형이 바뀌면 정상 검증 세트부터 다시 모읍니다.
현장 노트
코어셋 비율을 더 낮춰야 하는 상황이라면 저는 전체 과검출률보다 과검출이 어느 타일, 어느 좌표에 몰리는지를 지도로 먼저 그립니다. 메모리와 탐색 시간은 계산대로 비율에 비례해 줄지만, 드물게 나타나는 정상 패치가 뱅크에서 빠지면 그 위치에서만 과검출이 생길 수 있기 때문입니다. 금형 게이트 주변처럼 광택이 다른 영역이 있다면 그 타일만 비율을 높게 두는 배분을 검토하고, 다른 금형에서는 샘플로 다시 확인합니다.
현장 체크포인트
메모리뱅크 모델을 엣지에 올리기 전에 아래 숫자를 채웁니다. 하나라도 비어 있으면 코어셋 비율은 근거 없는 값이 됩니다.
- WD 150 mm 이상이 돔 조명의 높이와 카메라 관측창 위치까지 포함해 실측으로 확보되는가? (주점 기준 물체 거리 약 170 mm)
- 무광 영역과 광택 게이트부를 나눠 정상 변동의 폭을 따로 봤는가?
- μm/px × stride로 패치 셀 크기를 계산했고, 최소 결함이 셀 폭의 절반 안팎을 차지하는가? (20 μm/px × 8 = 160 μm)
- 메모리뱅크 원본 크기(장수 × 타일 × 패치 × 차원 × 바이트)와 코어셋 뒤 크기가 장치 메모리 여유 안에 드는가?
- 이미지당 탐색 연산량(쿼리 수 × 뱅크 크기 × 차원)을 실효 성능으로 나눈 시간이 택트 안에 드는가?
- 임계를 정상 검증 이미지 1,000장 이상에서 추정했고, 코어셋이나 근사 탐색을 바꾼 뒤 다시 추정했는가?
자주 묻는 질문
뱅크를 GPU 메모리에 다 올릴 수 있으면 코어셋이 필요 없나요?
메모리에 들어가도 탐색 연산은 뱅크 크기에 비례해 늘어납니다. 원본 8,192,000 패치를 그대로 두면 이미지당 곱셈-누산이 코어셋 1 %의 100배인 2.58 × 1014로 늘어나, 가정한 성능으로는 52초가 걸립니다. 메모리 여유와 별개로 탐색 시간이 비율을 정합니다.
코어셋을 타일 위치별로 나눠 만들어도 되나요?
광택이 다른 게이트 주변처럼 위치에 따라 정상 외관이 확연히 다르다면, 위치별로 뱅크를 나누고 비율을 다르게 주는 방법이 있습니다. 쿼리는 자기 위치의 뱅크하고만 비교하니 탐색 연산도 줄어듭니다. 다만 부품 위치가 흔들리면 엉뚱한 뱅크와 비교하게 되므로, 저는 위치 정렬 오차를 먼저 재고 그 오차 안에 드는 이웃 위치의 패치도 각 뱅크에 함께 넣습니다.
용어 풀이
- [1] PatchCore PatchCore
정상 영상의 패치 특징을 메모리뱅크에 저장해 두고, 검사 패치와 가장 가까운 정상 패치의 거리로 이상을 판정하는 방식입니다. ↩ - [2] WD working distance, 작동 거리
렌즈 앞면에서 검사할 면까지의 거리입니다. 본문의 약 170 mm는 얇은 렌즈 근사로 렌즈 주점을 기준으로 계산한 물체 거리이고, 렌즈 앞면 기준 거리는 렌즈 도면으로 확인합니다. ↩ - [3] FP16 half-precision floating point
숫자 하나를 16비트, 2바이트로 저장하는 부동소수점 형식입니다. 32비트보다 메모리가 절반으로 줄어듭니다. ↩ - [4] 곱셈-누산 multiply-accumulate, MAC
곱셈 한 번과 덧셈 한 번을 묶은 연산 단위입니다. 거리 계산의 연산량을 셀 때 씁니다. ↩ - [5] 패치 patch
특징맵의 한 칸이 대표하는 입력 영상의 작은 영역입니다. stride 8이면 8 × 8 px에 이웃 정보가 더해집니다. ↩ - [6] 메모리뱅크 memory bank
정상 패치 특징을 모아 둔 저장소입니다. 검사할 때 이 안에서 가장 가까운 정상 패치를 찾습니다. ↩ - [7] 코어셋 서브샘플링 coreset subsampling
전체 특징 공간을 고르게 덮는 대표 패치만 골라 뱅크를 줄이는 절차입니다. 이미 고른 패치에서 가장 먼 패치를 차례로 더합니다. ↩ - [8] 최근접 탐색 nearest neighbor search
뱅크 안에서 쿼리 패치와 거리가 가장 가까운 패치를 찾는 계산입니다. ↩ - [9] 근사 최근접 탐색 approximate nearest neighbor search
모든 패치와 거리를 재지 않고 인덱스나 양자화로 후보를 줄여 빠르게 찾는 방법입니다. 가장 가까운 이웃을 놓칠 수 있습니다. ↩
참고 자료
- Roth, Pemula, Zepeda, Schölkopf, Brox, Gehler, Towards Total Recall in Industrial Anomaly Detection, arXiv:2106.08265 (2021). 정상 패치 특징의 메모리뱅크로 이상을 찾는 PatchCore를 제안한 논문입니다.
- 계산식: 화소 분해능 = FOV ÷ 픽셀 수, 패치 셀 크기 = 화소 분해능 × stride, 메모리뱅크 크기 = 영상 수 × 타일 수 × 타일당 패치 수 × 차원 × 바이트, 코어셋 뒤 크기 = 원본 × 비율, 탐색 연산량 = 쿼리 패치 수 × 뱅크 패치 수 × 차원, 탐색 시간 = 연산량 ÷ 실효 성능, 백분위 위 표본 수 = 표본 수 × (1 − 백분위), 배율 m = 센서 폭 ÷ FOV 폭, 물체 거리 = f × (1 + 1/m)
- 계산 가정: 2,448 × 2,048 px 카메라(화소 3.45 μm), 25 mm 렌즈, FOV 49 × 41 mm, 최소 결함 80 μm, 512 × 512 px 타일 20장, stride 8, 384차원 FP16, 정상 학습 100장, 실효 성능 초당 5 × 1012 곱셈-누산, 택트 500 ms, 정상 검증 1,000장
함께 읽으면 좋은 글 — 결함 샘플 5장으로 Few-Shot 이상탐지 라인을 세울 수 있을까 · 조명이 5 % 어두워지면 정상 화소 몇 개가 불량이 될까 · 엣지 검사의 입력 드리프트는 정확도보다 먼저 보인다


