클리카
경력근거: AI 모델 최적화 및 배포 기술을 고객의 시스템과 하드웨어 환경에 적용
클리카는 국내 기업과 공공기관 로보틱스 프로젝트에 직접 들어가 자사의 모델 최적화·배포 기술을 고객 시스템과 하드웨어 환경에 얹는 일을 합니다. 공고는 모델 선정과 테스트, 전처리·후처리, 추론 파이프라인 개선을 주요 업무로 적고 자격요건에 전처리·추론·후처리 파이프라인을 직접 구성하고 문제를 분석할 수 있는 사람을 명시했으며, 우대사항에 PyTorch 와 ONNX, TensorRT, OpenVINO 사용 경험을 함께 두었습니다. 고객사 샘플로 사전학습 비전 모델을 돌려 클래스별 성적을 규칙으로 채점하고 ONNX 변환 전후 출력을 수치로 대조하는 이 도구는 그 파이프라인을 실제로 갖췄고, 매핑표와 합격 기준만 갈아끼우면 다음 현장에서 그대로 도는 점이 반복 요구를 재사용 모듈로 키운다는 회사 원칙과 같은 방향입니다. 다만 이 포트폴리오가 보여주는 것은 사전학습 모델을 파이프라인에 걸어 돌리고 결과를 규칙으로 채점하며 변환 전후를 수치로 대조하는 기술이며, 모델 압축·양자화 원천 알고리즘과 로봇 제어, 차량·선박 하드웨어 물리 같은 도메인 전문성은 주장하지 않습니다. 모르는 깊이는 면접에서 모른다고 말하는 편이 낫습니다.
회사가 가진 모델 최적화·배포 기술을 고객 시스템과 장비에 얹는 것이 이 직군의 중심입니다. 사전학습 모델을 고객사 샘플에 걸어 돌리고 변환 포맷별 출력까지 대조하는 이 도구가 그 첫 단계를 정면으로 맡습니다.
모델 선정과 테스트, 전처리와 후처리, 추론 파이프라인 개선이 자격요건에 그대로 적혀 있습니다. 이 도구는 그 세 단계를 실제로 갖춘 파이프라인이며, 어느 단계에서 결과가 흔들렸는지를 프레임 단위로 되짚습니다.
고객 현장에서 기능 테스트와 성능 검증을 하고, 반복되는 요구를 재사용 모듈로 키우는 일이 주요 업무입니다. 클래스 매핑표와 합격 기준만 갈아끼우면 다음 현장에서 그대로 도는 이 도구가 그 지향과 맞습니다.
고객사 담당자가 건넨 현장 촬영 프레임 폴더와 엑셀 검사 대장을 입력으로 받아, EXIF 회전을 바로잡고 모델 카드가 요구하는 크기와 정규화 규격으로 전처리한 다음 공개 사전학습 비전 모델로 추론하고, 신뢰도 임계값과 클래스 매핑표를 적용한 후처리 판정까지 한 명령으로 돌립니다. 판정과 검사 대장을 프레임 키로 맞춰 클래스별 정탐·미탐·오탐을 세고 틀린 프레임 목록을 붙인 평가 리포트 md 한 장과 프레임별 결과 csv 를 떨어뜨리며, 같은 모델을 ONNX 로 내보내 같은 입력에 돌린 뒤 출력 텐서 최대 절대 오차와 판정이 뒤집힌 프레임을 수치로 대조합니다. 가중치는 공개된 것을 그대로 쓰고 학습이나 미세조정은 하지 않으며, 지표 계산과 전후 대조는 전부 규칙이 맡고 Claude 는 리포트의 실패 유형 설명 문단만 씁니다.
클리카 FDE 엔지니어입니다. 국내 기업과 공공기관 로보틱스 PoC 에 들어갈 때마다 고객사 설비 담당자가 USB 로 촬영 프레임 수백 장과 손으로 채운 엑셀 검사 대장을 건네는데, 그 자리에서 노트북에 스크립트를 새로 짜 모델을 돌려 보고 쓸 만한지를 구두로 전한 뒤 다음 현장에서 또 처음부터 짜 왔습니다. 샘플 폴더와 검사 대장만 넣으면 성적표와 틀린 프레임 목록이 파일로 나와 담당자와 같은 화면을 보고 이야기하기를 바라는 사람입니다.
전처리 규격을 모델 카드에 맞춰 고정하고 고객사 검사 대장의 표기를 모델 클래스 매핑표로 묶으면 사전학습 가중치를 그대로 쓴 상태에서도 클래스별 성적이 규칙으로 재현되고, 같은 입력을 ONNX 런타임에 넣어 출력 텐서 차이와 최종 판정 일치율을 재면 변환이 무엇을 바꿨는지가 말이 아니라 숫자로 남으며, 매핑되지 않은 표기와 깨진 프레임을 확인 필요로 빼면 담당자가 볼 것이 성적표 전체가 아니라 어긋난 곳으로 줄어듭니다.
이미지 폴더와 고객사 검사 대장을 넣으면 전처리·추론·후처리가 한 명령으로 돌고, 클래스별 정탐·미탐·오탐 수와 틀린 프레임 목록을 담은 평가 리포트 md 한 장과 프레임별 결과 csv 가 떨어집니다. 공개 사전학습 가중치를 그대로 쓰고 GPU 가 없는 현장 노트북에서도 도는 것을 기준으로 잡으며, 이 주차에서는 학습과 미세조정을 하지 않습니다.
PyTorch 로 돌린 결과와 ONNX 런타임으로 돌린 결과를 같은 입력에서 맞대어 출력 텐서 최대 절대 오차, 최종 판정이 뒤집힌 프레임 수, 장당 처리 시간을 리포트에 한 절로 붙입니다. 판정이 뒤집힌 프레임은 파일 경로와 원래 점수를 남겨 어느 단계가 흔들렸는지 되짚습니다.
신뢰도 임계값과 입력 해상도를 격자로 돌려 클래스별 성적이 어떻게 움직이는지 표로 내고, 고객사가 요구한 미탐 상한을 만족하는 설정만 추려 csv 로 넘깁니다. 어느 설정으로 갈지는 고객사 담당자가 정합니다.
고객사 샘플 400장을 한 줄 명령으로 돌리면 전처리부터 후처리까지 지나 평가 리포트 md 한 장과 프레임별 결과 csv 가 GPU 없는 노트북에서 몇 분 안에 떨어지는 걸 시연합니다
일부러 만든 지저분한 입력 30종(EXIF 회전만 다른 사진·같은 프레임을 두 이름으로 적은 대장·좌표가 픽셀과 정규화로 섞인 행·열리지 않는 깨진 파일·대장에만 있고 폴더에 없는 프레임)을 넣어도 파이프라인이 멈추지 않고 해당 프레임을 확인 필요로 넘기며 출력 형식(스키마)이 한 번도 안 깨집니다
2주차에 같은 입력 400장을 PyTorch 와 ONNX 런타임에 각각 넣어 출력 텐서 최대 절대 오차가 2.0e-4 이하이고 최종 판정이 뒤집힌 프레임이 400장 중 3장임을 수치로 냅니다. 단, 샘플과 검사 대장을 모두 작성자가 만든 합성 기준이라 성능 검증이 아니라 데모 조건에서의 동작임을 밝힙니다
진짜 검증은 여기서 멈춥니다. 위 수치는 작성자가 만든 합성 샘플 자가채점이고, 이 모델이 클리카가 들어가는 실제 고객사 조명과 촬영 장비에서 쓸 만한지는 실제 현장 촬영본과 고객사 검수 기준이 있어야 확인됩니다. 이 도구는 그 검수를 첫날 바로 돌릴 수 있는 상태로 만듭니다
이건 고객사와 실데이터 없이 혼자 만든 포트폴리오입니다. 파이프라인은 실제로 끝까지 돌고 모델도 실제로 추론하지만 샘플과 검사 대장이 합성이라 현장 검증이 아닙니다. 면접에서는 실행 데모와 실검증 준비 상태를 솔직히 설명합니다
정답을 작성자가 만들었으니 잘 맞는 것이 당연합니다. 회전 정보만 다른 사진, 같은 프레임에 판정이 둘인 대장, 픽셀과 정규화 좌표가 섞인 행, 폴더에 없는 프레임을 가리키는 행처럼 어긋난 케이스를 더미에 일부러 섞어 쉬운 입력만 통과시키는 게 아님을 보입니다
이 포트폴리오가 보여주는 것은 사전학습 비전 모델을 전처리·추론·후처리 파이프라인에 걸어 돌리고 그 결과를 규칙으로 채점하며 변환 전후 출력을 수치로 대조하는 기술입니다. 모델 압축과 양자화 원천 알고리즘, 로봇 제어와 차량·선박 하드웨어 물리, 산업 안전 검사 기준 해석 같은 도메인 전문성은 이 포트폴리오로 증명되지 않으므로 주장하지 않으며, 경량화와 로보틱스는 테마로만 닿게 했습니다. 모르는 깊이는 면접에서 모른다고 말하는 편이 낫습니다
사전학습 모델이 아는 클래스가 고객사가 보고 싶은 대상과 어긋나는 현장도 있습니다. 그때 도구는 없는 클래스를 지어내지 않고 미매핑 표기 목록을 먼저 내며, 첫 회차에는 확인 필요 프레임이 크게 늘어납니다. 실제 도입 때는 데이터 수집과 미세조정, 검수 기준 합의를 도입 단계 과제로 분리해 명시합니다
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
고객사 담당자가 USB 로 건넨 현장 촬영 프레임 목록. 파이프라인이 가장 먼저 읽어 전처리 계획을 세우는 입력입니다. EXIF 회전·중복·깨진 파일·해상도 편차·역광을 일부러 섞어 깨끗한 사진만 다루지 않게 합니다.
| frame_id | source_file | capture_device | width | height | exif_rotation | lighting | blur_score | file_status | captured_at |
|---|---|---|---|---|---|---|---|---|---|
| f_001 | line_a_0001.jpg | 현장반입_산업카메라_IMX477 | 2,048 | 1,536 | 0 | bright | 0.08 | ok | 2026-05-12T09:14:00 |
| f_002 | line_a_0002.jpg | 현장반입_산업카메라_IMX477 | 2,048 | 1,536 | 90 | normal | 0.11 | ok | 2026-05-12T09:15:20 |
| f_003 | line_a_0003.JPG | 현장반입_산업카메라_IMX477 | 2,048 | 1,536 | 0 | dim | 0.34 | ok | 2026-05-12T09:16:02 |
| f_004 | line_a_0004.jpg | 현장반입_산업카메라_IMX477 | 2,048 | 1,536 | 270 | backlit | 0.22 | ok | 2026-05-12T09:17:41 |
| f_005 | line_a_0005.jpg | 담당자_휴대폰_카메라 | 640 | 480 | 0 | normal | 0.41 | ok | 2026-05-12T10:02:09 |
아래 JSON Schema 에 맞는 고객사 현장 촬영 프레임 목록 40행을 JSON 배열로 생성합니다. source_file 은 촬영 구역 2~3곳으로 나누고 frame_id 는 순서대로 증가하게 둡니다. capture_device 는 산업카메라·로봇암 장착 카메라·담당자 휴대폰·고정형 검사지그를 섞고, width 와 height 는 그 장비에 맞는 값으로 둡니다.
{"type":"object","properties":{"frame_id":{"type":"string"},"source_file":{"type":"string"},"capture_device":{"type":"string"},"width":{"type":"number"},"height":{"type":"number"},"exif_rotation":{"type":"number","enum":[0,90,180,270]},"lighting":{"type":"string","enum":["bright","normal","dim","backlit"]},"blur_score":{"type":"number"},"file_status":{"type":"string","enum":["ok","corrupt","duplicate"]},"captured_at":{"type":"string"}},"required":["frame_id","source_file","width","height","exif_rotation","file_status"]}
쉬운 데이터만 만들지 말 것, 다음 하드 케이스를 의도적으로 섞어라(깔끔한 촬영본만 다루는 함정 회피): (1) exif_rotation 이 90·180·270 인 행 6건 이상, (2) file_status 가 corrupt 인 행 3건(width 와 height 는 0), (3) 앞선 행과 촬영 시각·해상도가 같은 duplicate 행 3건, (4) 확장자만 대문자로 적힌 파일명 3건, (5) blur_score 가 0.5 를 넘는 흐린 행 4건, (6) 같은 폴더에 640x480 과 4032x3024 처럼 해상도 차이가 큰 행 5건, (7) lighting 이 backlit 인 역광 행 4건. 형식을 일부러 깨뜨리는 시도 5건(width 에 문자열, exif_rotation 에 45 같은 enum 밖 값)도 별도로 만들어 로더가 거르는지 확인합니다. 정상 행은 위 스키마를 통과해야 합니다. JSON 배열만 출력합니다.{"type":"object","properties":{"frame_id":{"type":"string"},"source_file":{"type":"string"},"capture_device":{"type":"string"},"width":{"type":"number"},"height":{"type":"number"},"exif_rotation":{"type":"number","enum":[0,90,180,270]},"lighting":{"type":"string","enum":["bright","normal","dim","backlit"]},"blur_score":{"type":"number"},"file_status":{"type":"string","enum":["ok","corrupt","duplicate"]},"captured_at":{"type":"string"}},"required":["frame_id","source_file","width","height","exif_rotation","file_status"]}고객사 설비팀이 엑셀로 채워 건넨 검사 대장. 모델 판정을 채점할 정답이 여기서만 나오고 대장에 없는 정답은 지어내지 않습니다. 같은 프레임에 판정이 둘인 행, 표기 흔들림, 좌표계 혼재, 폴더에 없는 프레임 참조를 일부러 섞습니다.
| row_id | frame_ref | label_text | bbox | coord_space | verdict | inspector | note |
|---|---|---|---|---|---|---|---|
| r_001 | line_a_0001.jpg | 정상 | — | unknown | normal | 설비팀 김 | — |
| r_002 | line_a_0002.jpg | 스크래치 | 812,410,980,560 | pixel | defect | 설비팀 김 | — |
| r_003 | line_a_0003.jpg | 스크레치 | 0.41,0.33,0.52,0.44 | normalized | defect | 설비팀 박 | 스크래치와 표기가 흔들립니다 |
| r_004 | LINE_A_0004.JPG | 찍힘 | 120,88,300,240 | pixel | defect | 설비팀 박 | 파일명이 대문자로 적혔습니다 |
| r_005 | line_a_0005.jpg | scratch | — | unknown | defect | 협력사 검사원 | 영문 표기로 적혔습니다 |
아래 JSON Schema 에 맞는 고객사 검사 대장 40행을 JSON 배열로 생성합니다. frame_ref 는 앞선 프레임 목록의 파일명과 이어지게 두고, label_text 는 스크래치·찍힘·이물·도장 벗겨짐·정상처럼 현장 담당자가 손으로 적을 법한 한국어 표기로 씁니다. verdict 는 normal 을 다수로 하고 defect 와 unsure 를 섞습니다.
{"type":"object","properties":{"row_id":{"type":"string"},"frame_ref":{"type":"string"},"label_text":{"type":"string"},"bbox":{"type":["string","null"]},"coord_space":{"type":"string","enum":["pixel","normalized","unknown"]},"verdict":{"type":"string","enum":["defect","normal","unsure"]},"inspector":{"type":"string"},"note":{"type":["string","null"]}},"required":["row_id","frame_ref","label_text","coord_space","verdict","inspector"]}
쉬운 데이터만 만들지 말 것, 다음 하드 케이스를 의도적으로 섞어라(대장이 깔끔하다는 함정 회피): (1) 같은 frame_ref 에 서로 다른 verdict 가 붙은 충돌 쌍 4쌍, (2) 오타나 영문 표기로 같은 결함을 다르게 적은 행 5건(스크래치·스크레치·scratch), (3) coord_space 가 unknown 인데 bbox 가 채워진 행 3건, (4) 픽셀 좌표와 정규화 좌표가 한 대장에 섞인 행 6건, (5) 파일명 대소문자나 확장자만 다른 행 4건, (6) 샘플 폴더에 없는 프레임을 가리키는 행 3건, (7) verdict 가 unsure 인 보류 행 3건. 형식을 일부러 깨뜨리는 시도 5건(verdict 에 enum 밖 값, bbox 에 숫자 3개만)도 별도로 만들어 로더가 거르는지 확인합니다. 정상 행은 위 스키마를 통과해야 합니다. JSON 배열만 출력합니다.{"type":"object","properties":{"row_id":{"type":"string"},"frame_ref":{"type":"string"},"label_text":{"type":"string"},"bbox":{"type":["string","null"]},"coord_space":{"type":"string","enum":["pixel","normalized","unknown"]},"verdict":{"type":"string","enum":["defect","normal","unsure"]},"inspector":{"type":"string"},"note":{"type":["string","null"]}},"required":["row_id","frame_ref","label_text","coord_space","verdict","inspector"]}| Python | 파이프라인 본체와 전처리기, 후처리기, 지표 계산기, 리포트 작성기의 구현 언어입니다 |
| C++ | 고객사 장비 런타임이 C++ API 로만 열려 있을 때 같은 전처리·후처리 규격을 그쪽으로 옮겨 붙이는 다음 작업 지점입니다 |
| PyTorch | 사전학습 비전 모델을 불러와 배치 추론을 돌리고 2주차에 ONNX 로 내보내는 기본 프레임워크입니다 |
| Docker | 고객사 폐쇄망 노트북에서 같은 버전과 같은 가중치로 돌도록 파이프라인과 런타임을 한 이미지로 묶어 건네는 전달 단위입니다 |
| FastAPI | 이번 산출물에는 서버를 두지 않습니다. 고객사가 사내 시스템에서 추론을 호출하기를 원할 때 같은 파이프라인 함수를 감싸는 첫 후보입니다 |
| Django | 고객사 기존 사내 품질 시스템이 Django 면 그 위에 결과 열람 화면을 얹는 대안이며 이번 도구에는 쓰지 않습니다 |
| Flask | 현장 노트북에서 결과를 가볍게 띄우는 대안이며 이번 도구에는 쓰지 않습니다 |
| REST | 평가 리포트와 프레임별 결과를 고객사 품질 시스템으로 넘길 때의 연동 규격입니다 |
| Linux | GPU 서버와 현장 노트북에서 빌드와 실행, 로그 확인을 하는 기본 실행 환경입니다 |
| VLM | 고객사가 보고 싶은 판단이 분류나 검출로 떨어지지 않을 때 같은 전처리·후처리 골격에 갈아끼우는 모델 종류입니다 |
| LLM | 리포트의 실패 유형 설명 문단을 쓰는 Claude 이며 지표 계산과 합격 판정에는 관여하지 않습니다 |
| 딥러닝 | 입력 해상도와 정규화 규격, 신뢰도 임계값이 결과를 어떻게 흔드는지 짚는 기반 지식입니다 |
| ONNX | PyTorch 모델을 프레임워크 독립 그래프로 내보내 전후 출력을 대조하는 2주차 포맷입니다 |
| TensorRT | 고객사 현장 장비가 Jetson 인 경우 ONNX 다음에 붙일 실행 런타임이며 이번 범위 밖입니다 |
| OpenVINO | 산업용 미니PC 만 반입되는 현장의 실행 런타임 후보입니다 |
| QNN | 퀄컴 보드가 들어간 현장의 실행 런타임 후보입니다 |
| LiteRT | 현장 반입 태블릿처럼 경량 장비에서 돌릴 때의 런타임 후보입니다 |
✓ pass → 그대로 멈춰도 완결입니다. 더 키우려면 2주차(ONNX 변환 전후 대조)로 진행합니다.
✓ pass → 여기서 멈춰도 완결입니다. 더 키우면 3주차(임계값·해상도 스윕과 설정 후보 표)로 진행합니다.
프레임 한 장의 파이프라인 결과. 어떤 전처리를 적용했고 모델 원출력이 무엇이었으며 후처리 판정이 어떻게 났는지, 검사 대장과 맞대어 어떤 결과가 됐는지, ONNX 로 돌렸을 때 얼마나 달라졌는지를 한 스키마에 담아 평가 리포트 md 와 프레임별 csv 에 씁니다. 판정과 집계는 규칙이 내고 Claude 는 설명 문단만 씁니다.
{"type":"object","properties":{"frame_id":{"type":"string"},"source_file":{"type":"string"},"preprocess":{"type":"object","properties":{"applied_rotation":{"type":"number"},"resized_to":{"type":"string"},"normalize_profile":{"type":"string"}},"required":["applied_rotation","resized_to","normalize_profile"]},"model_output":{"type":"object","properties":{"top_class":{"type":["string","null"]},"score":{"type":["number","null"]},"box_count":{"type":"number"}},"required":["top_class","score","box_count"]},"postprocess":{"type":"object","properties":{"verdict":{"type":"string","enum":["defect","normal","abstain"]},"applied_threshold":{"type":"number"},"mapped_class":{"type":["string","null"]}},"required":["verdict","applied_threshold","mapped_class"]},"label_ref":{"type":"object","properties":{"label_text":{"type":["string","null"]},"verdict":{"type":["string","null"]},"matched":{"type":"boolean"}},"required":["matched"]},"outcome":{"type":"string","enum":["tp","fp","fn","tn","unscored"]},"onnx_check":{"type":["object","null"],"properties":{"max_abs_diff":{"type":"number"},"verdict_flipped":{"type":"boolean"}},"required":["max_abs_diff","verdict_flipped"]},"flags":{"type":"array","items":{"type":"string","enum":["exif_rotated","corrupt_file","duplicate_frame","label_missing","label_ambiguous","class_unmapped","low_confidence","coord_space_unknown","onnx_verdict_flipped"]}},"needs_human":{"type":"boolean"},"reason":{"type":"string"},"hedge":{"type":["string","null"]}},"required":["frame_id","source_file","preprocess","model_output","postprocess","label_ref","outcome","flags","needs_human","reason"]}[
{
"input_ref": "f_002 (line_a_0002.jpg, EXIF 90도 회전) + r_002 (스크래치, pixel bbox)",
"output": {
"frame_id": "f_002",
"source_file": "line_a_0002.jpg",
"preprocess": {
"applied_rotation": 90,
"resized_to": "640x640 letterbox",
"normalize_profile": "imagenet_mean_std"
},
"model_output": {
"top_class": "scratch",
"score": 0.87,
"box_count": 1
},
"postprocess": {
"verdict": "defect",
"applied_threshold": 0.45,
"mapped_class": "스크래치"
},
"label_ref": {
"label_text": "스크래치",
"verdict": "defect",
"matched": true
},
"outcome": "tp",
"onnx_check": {
"max_abs_diff": 0.00008,
"verdict_flipped": false
},
"flags": [
"exif_rotated"
],
"needs_human": false,
"reason": "EXIF 회전을 바로잡아 전처리했고 후처리 판정이 검사 대장의 defect 와 같은 클래스로 매핑돼 정탐으로 셉니다.",
"hedge": null
}
},
{
"input_ref": "f_003 (line_a_0003.JPG, 어두운 조명) + r_003 (스크레치, normalized bbox)",
"output": {
"frame_id": "f_003",
"source_file": "line_a_0003.JPG",
"preprocess": {
"applied_rotation": 0,
"resized_to": "640x640 letterbox",
"normalize_profile": "imagenet_mean_std"
},
"model_output": {
"top_class": "scratch",
"score": 0.52,
"box_count": 1
},
"postprocess": {
"verdict": "abstain",
"applied_threshold": 0.45,
"mapped_class": null
},
"label_ref": {
"label_text": "스크레치",
"verdict": "defect",
"matched": false
},
"outcome": "unscored",
"onnx_check": null,
"flags": [
"label_ambiguous",
"class_unmapped"
],
"needs_human": true,
"reason": "대장의 스크레치 표기가 매핑표에 없어 모델 클래스와 잇지 못했습니다. 도구가 임의로 스크래치와 같다고 보지 않고 점수 집계에서 빼 확인 필요로 넘깁니다.",
"hedge": "스크레치를 스크래치와 같은 항목으로 볼지는 고객사 담당자가 매핑표에 적어야 정해집니다"
}
},
{
"input_ref": "f_009 (line_b_0003.png, 열리지 않는 파일)",
"output": {
"frame_id": "f_009",
"source_file": "line_b_0003.png",
"preprocess": {
"applied_rotation": 0,
"resized_to": "미실행",
"normalize_profile": "미실행"
},
"model_output": {
"top_class": null,
"score": null,
"box_count": 0
},
"postprocess": {
"verdict": "abstain",
"applied_threshold": 0.45,
"mapped_class": null
},
"label_ref": {
"label_text": null,
"verdict": null,
"matched": false
},
"outcome": "unscored",
"onnx_check": null,
"flags": [
"corrupt_file",
"label_missing"
],
"needs_human": true,
"reason": "파일이 열리지 않아 전처리 단계에서 멈췄습니다. 파이프라인은 계속 돌고 이 프레임만 점수에서 빼며 재촬영 요청 목록에 올립니다.",
"hedge": "이 프레임을 다시 받을지 버릴지는 고객사 담당자가 정합니다"
}
},
{
"input_ref": "f_010 (line_b_0004.png, 역광) + r_010 (판단 보류) + ONNX 대조",
"output": {
"frame_id": "f_010",
"source_file": "line_b_0004.png",
"preprocess": {
"applied_rotation": 0,
"resized_to": "640x640 letterbox",
"normalize_profile": "imagenet_mean_std"
},
"model_output": {
"top_class": "foreign_object",
"score": 0.46,
"box_count": 2
},
"postprocess": {
"verdict": "defect",
"applied_threshold": 0.45,
"mapped_class": "이물"
},
"label_ref": {
"label_text": "판단 보류",
"verdict": "unsure",
"matched": true
},
"outcome": "unscored",
"onnx_check": {
"max_abs_diff": 0.00031,
"verdict_flipped": true
},
"flags": [
"low_confidence",
"onnx_verdict_flipped",
"coord_space_unknown"
],
"needs_human": true,
"reason": "점수가 임계값 0.45 바로 위라 ONNX 로 돌렸을 때 0.4497 로 내려가 판정이 뒤집혔고, 대장 판정이 보류라 정답이 서지 않아 점수 집계에서 뺍니다.",
"hedge": "이 구간은 임계값을 어디에 두느냐로 결과가 갈리며, 이 샘플과 대장은 작성자가 만든 합성 기준입니다"
}
}
][자동 검증] 1. 출력이 스키마(필드·enum·하위 객체 형식)를 통과하는지 확인합니다. 2. preprocess 의 applied_rotation 이 프레임 목록의 exif_rotation 과 일치하는지, resized_to 와 normalize_profile 이 모델 카드 규격과 같은지 대조합니다. 3. postprocess 의 verdict 가 model_output 의 score 와 applied_threshold 로 결정론적으로 재현되는지 다시 계산해 맞춥니다. 4. outcome 이 postprocess 판정과 label_ref 조합에서 규칙대로 나왔는지 봅니다(매핑 실패·정답 보류·깨진 파일은 전부 unscored 로 빠져 점수에 섞이지 않아야 합니다). 5. onnx_check 의 verdict_flipped 가 두 런타임의 판정 차이와 일치하는지, max_abs_diff 가 실제 출력 텐서 비교값과 같은지 대조합니다. [수동 검증] 1. 현장 검사원 2명이 리포트의 틀린 프레임 목록을 보고 모델 판정과 자기 판단이 갈리는 이유를 설명할 수 있는지 비동기로 검토합니다. 2. 전체 프레임의 5% 를 사람이 직접 원본 이미지와 대조합니다.
포트폴리오가 “무엇을 만들지”라면, 시나리오 테스트는 “현장에서 어떻게 판단·소통할지” 입니다. 실제 이 채용공고 맥락의 대본을 읽고 무엇을 물어야 할지 직접 써봅니다.
근거: AI 모델 최적화 및 배포 기술을 고객의 시스템과 하드웨어 환경에 적용