Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SEM Defect Inspection — TFLite GPU Inference Engine

실시간 SEM(주사전자현미경) 웨이퍼 결함 검사를 위한 멀티태스크 U-Net 추론 엔진입니다. 6종 결함 분류와 픽셀 단위 결함 분할을 하나의 네트워크로 동시에 수행하며, NextChip APACHE6 보드의 Mali GPU 위에서 TensorFlow Lite GPU 델리게이트로 구동됩니다.

카메라 프레임 하나가 들어가면 결함 종류 · 결함 면적 비율 · PASS/FAIL 판정이 한 번의 추론으로 나옵니다.

EN — A multi-task U-Net (6-class defect classification + binary defect segmentation) served through the TensorFlow Lite GPU delegate on a NextChip APACHE6 board (Mali GPU), with automatic CPU fallback. Exposed as a plain C API so it can be embedded in a C camera/render loop.

타깃 플랫폼 — NextChip APACHE6 (ARM64) · Mali GPU · MIPI CSI 카메라 · V4L2 캡처 · Wayland/OpenGL ES 표시


데모

카메라 입력 → 전처리 → GPU 추론 → 결과 오버레이가 보드 위에서 실시간으로 돕니다.

GPU 실시간 데모

이미지를 클릭하면 데모 영상이 재생됩니다. Class 3 / Confidence 84.47% / Defect Ratio 4.16% → PASS. GPU latency 171.9 ms.

결함 면적이 임계값을 넘으면 FAIL로 판정합니다. 아래는 같은 파이프라인의 FAIL 케이스 콘솔 로그입니다.

FAIL 판정 콘솔 로그

Class 1 / Defect pixels 49,465 / Defect area ratio 22.39% → FAIL. Probability sum: 1.00023 은 분류 출력이 이미 정규화된 확률임을 보여줍니다 — 왜 이걸 찍어보는가

위 스크린샷은 원본 온보드 애플리케이션의 출력입니다. 그 호스트 앱은 벤더 SDK 파생물이라 이 저장소에 포함되지 않습니다(NOTICE.md). 저장소의 inspect_image 예제가 같은 엔진을 데스크톱에서 실행합니다.


성능

동일 입력 기준으로 CPU와 GPU 델리게이트를 비교했습니다.

백엔드 Latency FPS 비고
CPU 1617.37 ms 0.62 델리게이트 없이
Mali GPU 델리게이트 171.57 ms 5.83 CPU 대비 9.4×
aiWare NPU (INT8) ≈ 8.03 ms ≈ 124.49 별도 확장, 아래 참고

CPU와 GPU 수치는 이 저장소의 엔진으로 측정한 end-to-end 추론 시간입니다.

NPU 확장 (이 저장소 범위 밖)

GPU 파이프라인 검증 후 동일 모델을 NPU로 옮겨 CPU/GPU/NPU 3자 비교를 만들었습니다.

PyTorch  →  ONNX  →  NNEF  →  aiwbin (INT8, minmax calibration)

카메라 · ISP · V4L2 · 표시 구조는 그대로 두고 추론부만 교체했습니다. 입력은 INT8 1×1×480×480, 후처리는 argmax + sigmoid로 동일합니다.

NPU 대시보드

▶ 클릭하면 NPU 데모 영상이 재생됩니다. NPU Time 7.73 ms / 129.36 FPS.

NPU 수치는 런타임 내부 측정값이라 CPU/GPU의 end-to-end latency와 측정 범위가 다릅니다. 직접 비교보다는 자릿수 참고용으로 보세요. NPU 변환에 쓴 벤더 툴체인과 런타임 코드는 이 저장소에 포함되지 않습니다.


왜 이 저장소인가

임베디드 보드에서 분류와 분할을 동시에 하는 네트워크를 실시간으로 돌리려면 모델 자체보다 그 주변이 더 까다롭습니다. 이 저장소는 그 주변부를 다룹니다.

  • 학습 시 전처리를 카메라 프레임에 정확히 동일하게 재현하는 문제
  • TFLite 변환 때마다 뒤바뀌는 출력 텐서 순서를 안정적으로 다루는 문제
  • GPU 델리게이트가 지원하지 않는 연산을 피해 모델을 설계하는 문제
  • GPU 델리게이트를 못 쓰는 환경에서 죽지 않고 degrade 하는 문제
  • 모델 출력이 확률인지 logit인지 확인하고 그 가정을 코드에 남기는 문제

→ 각각의 배경은 설계 노트에 정리되어 있습니다.


아키텍처

flowchart LR
    A["카메라 프레임<br/>RGB interleaved"] --> B["중앙 정사각 ROI"]
    B --> C["480×480 리사이즈"]
    C --> D["470×470 센터 크롭"]
    D --> E["그레이스케일<br/>+ 정규화"]
    E --> F["TFLite Interpreter<br/>GPU delegate"]
    F --> G["classification<br/>[1, 6]"]
    F --> H["segmentation<br/>[1, 470, 470, 1]"]
    G --> I["argmax<br/>결함 유형"]
    H --> J["threshold → 면적비<br/>PASS / FAIL"]
Loading

인코더를 공유하고 헤드 두 개가 갈라지는 U-Net입니다. 분류는 bottleneck에서 global average pooling 후 dense로, 분할은 디코더를 거쳐 원본 해상도로 복원합니다.

호스트 애플리케이션(카메라 캡처 + 화면 출력)은 C로 작성되어 있고 엔진은 C++이므로, 경계는 plain C ABI 4개 함수로 유지합니다.

sem_defect_init(model_path, config);   // 모델 로드 + 델리게이트 부착
sem_defect_run(rgb_frame, w, h);       // 프레임 1장 추론
sem_defect_get_latest_result(&result); // 최신 결과 복사
sem_defect_destroy();

sem_defect_run() 은 호출자의 버퍼를 복사하지 않고 cv::Mat 으로 감싸며, 반환 후에는 참조를 유지하지 않습니다. 카메라 버퍼를 즉시 큐에 반납할 수 있습니다.


전처리 파이프라인

단계 이유
ROI min(W, H) 중앙 정사각 시료가 화면 중앙에 고정된다는 촬영 조건
리사이즈 480 × 480 학습 파이프라인과 동일
크롭 (5, 5) 에서 470 × 470 리사이즈 경계의 보간 아티팩트 제거
색공간 RGB → GRAY 모델 입력이 1채널
정규화 (x - 98.0) / 12.0 데이터셋 통계값

정규화 상수 98 / 12 는 ImageNet 계열 값이 아니라 이 SEM 데이터셋의 실제 분포에서 나온 값입니다. 표준편차 12는 상당히 좁은데, SEM 이미지가 일반 사진보다 밝기가 균일하기 때문입니다. 다른 장비의 이미지를 넣으려면 SemDefectConfig 로 교체해야 합니다.


판정 로직

세그멘테이션 헤드는 마지막에 sigmoid가 붙어 있어 출력이 곧 확률입니다.

defect_pixels = count(segmentation >= 0.5)
defect_ratio  = defect_pixels / (470 × 470) × 100
verdict       = defect_ratio >= 20.0 ? FAIL : PASS

임계값 두 개(0.5, 20.0)는 모두 SemDefectConfig 로 조정할 수 있습니다.

분류 헤드는 그래프 안에 softmax를 포함하므로 출력이 곧 확률입니다. 엔진은 이를 그대로 전달하되, 합이 1에서 벗어나면 한 번 경고합니다.


데이터셋

Carinthia-S SEM 결함 데이터셋(이미지 + 라벨 + 이진 마스크)으로 학습했습니다.

항목
이미지 수 4,591
결함 클래스 6
마스크 binary region

클래스 분포가 크게 치우쳐 있습니다.

Class 1 2 3 4 5 6
샘플 수 55 8 4,008 289 4 227

Class 3이 전체의 87%를 차지하고 Class 5는 4장뿐입니다. 이 정도 불균형에서는 전체 정확도가 의미가 없으므로 클래스별 recall과 실제 카메라 입력에서의 분류 변화를 함께 봐야 합니다. 학습 코드와 데이터는 이 저장소에 포함되지 않습니다.


빌드 및 실행

TFLite는 CMake 패키지 config를 제공하지 않으므로 경로를 직접 지정합니다. 자세한 내용은 docs/building.md 를 참고하세요.

cmake -B build \
  -DTFLITE_INCLUDE_DIR=/path/to/tensorflow \
  -DTFLITE_LIB=/path/to/libtensorflow-lite.so \
  -DFLATBUFFERS_INCLUDE_DIR=/path/to/flatbuffers/include

cmake --build build -j

데스크톱에서 이미지 한 장으로 검증:

./build/inspect_image model.tflite sample.png --cpu
[sem-defect] initialised on GPU delegate
[sem-defect] input 470x470x1, classification [1,6], segmentation [1,470,470,1]

source      : sample.png (1280x720)
backend     : GPU delegate
latency     : 171.96 ms

class distribution
  class 1     8.875%
  class 2     0.387%
  class 3    79.932%   <-- predicted
  class 4     0.303%
  class 5     9.955%
  class 6     0.558%
  sum       1.00009  (expected ~1.0)

defect area : 9506 px  (4.303% of 470 x 470)
verdict     : PASS

출력 형식은 예시이고, 확률·픽셀·latency 수치는 위 데모 영상에서 실제로 관측된 프레임(frame=790)의 값입니다.


저장소에 포함되지 않은 것

이 저장소는 추론 엔진과 그 통합 방법만 다룹니다. 아래는 의도적으로 제외했습니다. 자세한 이유는 NOTICE.md 에 있습니다.

  • 학습된 모델 가중치 (.tflite) — 데이터 소유권 문제
  • 보드용 호스트 애플리케이션 — 벤더 SDK 파생물이며 재배포 불가
  • NPU 변환 툴체인 및 런타임 코드 — 벤더 독점
  • 런타임 공유 라이브러리 (.so) — 각 프로젝트 SDK에서 가져와야 합니다
  • 학습 코드 및 데이터셋

inspect_image 예제가 호스트 애플리케이션의 역할을 대신하므로, 보드 없이도 엔진의 동작을 그대로 확인할 수 있습니다.


문서

작성자

Jaehyeok Lee — dw7566@hanyang.ac.kr

라이선스

MIT

About

Real-time SEM wafer defect inspection on a NextChip APACHE6 board: multi-task U-Net (6-class classification + segmentation) via the TensorFlow Lite GPU delegate, exposed as a plain C API.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages