비전·음성·추천

DOMAIN / 44번째 글

현대 OCR — 찾는 모델과 읽는 모델, 그리고 그 경계가 사라진 자리

텍스트 검출과 문자 인식으로 나뉘던 OCR이 VLM 한 번으로 끝나기까지의 지형을 정리합니다. 두 방식이 각각 무엇을 잘하고 무엇을 못 하는지, 한글에서 특히 어려운 것, CER과 필드 완전 일치율의 차이, 그리고 둘을 겹쳐 쓰는 실무 구성입니다.

PALDYN Team15 MIN READ

지난 글까지는 그림을 만드는 쪽이었고, 이번에는 다시 읽는 쪽이다. OCR은 컴퓨터 비전에서 가장 오래된 과제 중 하나이고 "이미 다 풀린 문제"로 취급받는데, 실제로 붙여 보면 그렇지 않다. 인쇄된 A4 문서는 정말 다 풀렸다. 간판, 손글씨, 구겨진 영수증, 화면을 찍은 사진, 세로쓰기, 도장 위에 겹친 글자는 여전히 어렵다.

이 글은 지금 OCR의 지형을 정리한다. 오래 쓰인 두 단계 구조가 무엇이었는지, 왜 그게 여전히 필요한지, 그리고 시각-언어 모델이 그 경계를 어떻게 지웠는지다.

찾는 일과 읽는 일은 원래 다른 문제였다

OCR을 한 문장으로 정의하면 "이미지에서 글자를 텍스트로 바꾸는 일"이지만, 그 안에는 성격이 아주 다른 두 문제가 들어 있다.

텍스트 검출은 "글자가 어디 있는가"를 찾는 일이다. 무엇이라고 쓰였는지는 몰라도 된다. 사진 한 장에서 글자 영역 스물세 개를 찾아 내는 것이 목표다.

문자 인식은 "이 조각에 무엇이라고 쓰였는가"를 읽는 일이다. 이미 잘린 한 줄짜리 이미지를 받아 문자열을 낸다.

텍스트 검출과 문자 인식으로 나뉜 단계형 파이프라인, 그리고 한 모델이 끝까지 처리하는 방식

둘을 나눈 이유는 실용적이다. 검출은 위치를 다루므로 객체 검출과 뼈대가 같고, 인식은 순서 있는 문자열을 만드는 문제라 오히려 언어 모델에 가깝다. 각각 다른 모델로 푸는 편이 자연스러웠다.

검출 — 글자는 사각형에 안 담긴다

일반 객체 검출과 텍스트 검출의 가장 큰 차이는 모양이다. 사람이나 자동차는 축에 나란한 사각형에 대체로 담기지만, 글자는 그렇지 않다. 간판은 기울어져 있고, 컵에 인쇄된 글자는 휘어 있고, 한 줄이 아주 길쭉하다.

그래서 텍스트 검출은 사각형 대신 다각형을 낸다. DBNet 계열은 픽셀마다 "여기가 글자인가"를 확률로 예측한 뒤 그 확률 지도를 이진화해 덩어리의 외곽선을 다각형으로 뽑는다. 이진화 임계값 자체를 학습으로 정하게 만든 것이 이 방식의 요점이다 — 고정 임계값을 쓰면 밝은 간판과 어두운 문서에서 동시에 잘 되기가 어렵다. CRAFT는 조금 다르게, 글자 하나하나의 중심과 글자 사이의 이음새를 각각 예측한 뒤 이어 붙여 줄을 만든다. 붙여 나가는 방식이라 휘어진 줄에 강하다.

검출 단계에서 실무적으로 중요한 것은 줄을 어떻게 묶느냐다. 같은 문장이 두 줄로 나뉘어 검출되면 뒤의 인식과 후처리가 전부 어긋난다. 반대로 표의 인접한 두 칸이 한 줄로 묶여도 마찬가지다. 이 부분은 모델보다 임계값과 병합 규칙을 데이터에 맞춰 손보는 일이 대부분이다.

인식 — 글자 수를 미리 모른다는 문제

잘라 낸 한 줄 이미지에서 문자열을 만들 때의 어려움은, 글자가 몇 개인지 미리 모른다는 것이다. 이미지 가로 폭은 정해져 있지만 거기 글자가 세 개일 수도 열두 개일 수도 있다.

오랫동안 표준이었던 해법이 CTC(connectionist temporal classification)다. 이미지를 세로로 잘게 썰어 조각마다 문자를 하나씩 예측하게 하되, "빈칸" 기호를 두어 같은 글자가 연속으로 나오면 하나로 합치는 규칙을 둔다. ㅅㅅ_ㅓㅓ_ㅇㅇ 같은 예측이 서울로 정리되는 식이다. 정렬 정보를 학습 데이터에 안 넣어도 되는 것이 이 방식의 큰 이점이었다.

지금은 여기에 인코더-디코더 방식이 더해졌다. TrOCR처럼 Vision Transformer로 이미지를 인코딩하고 언어 모델 디코더로 문자열을 뽑는 구조다. 디코더가 언어 지식을 갖고 있으므로 흐릿한 글자를 문맥으로 메운다. 다만 이 이점이 그대로 약점이기도 하다 — 문맥으로 메운다는 것은 안 보이는 글자를 그럴듯하게 지어낼 수 있다는 뜻이다. 계좌번호나 일련번호처럼 문맥이 도움이 안 되는 필드에서는 CTC 계열이 더 정직하게 틀린다.

한글에서 더 어려운 것

한글 OCR에는 다른 언어에 없는 어려움이 몇 가지 있다.

글자 종류가 많다. 현대 한글 음절은 11,172자이고, 실제로 쓰이는 것만 추려도 2,500자 안팎이다. 알파벳 26자에 비하면 출력 클래스가 두 자릿수 배로 많고, 그만큼 학습 데이터도 더 필요하다.

모아쓰기라서 부분이 비슷하다. 왼과 외, 밝과 밖, 쁘와 쁨처럼 획 하나로 갈리는 쌍이 많다. 해상도가 조금만 떨어지면 받침이 사라진다. 이 때문에 한글은 다른 언어보다 입력 해상도에 민감하다 — 줄 높이가 20픽셀 아래로 내려가면 정확도가 급격히 떨어진다.

한글·영문·숫자가 한 줄에 섞인다. 주소 한 줄에 서울특별시 강남구 테헤란로 137, 5F처럼 세 문자 체계가 섞이는 것이 보통이다. 글자 폭도 서로 다르다. 여기서 특히 자주 나는 오류가 숫자와 알파벳의 혼동이다 — 0과 O, 1과 l, 5와 S.

마지막 항목은 모델로 푸는 것보다 후처리로 푸는 것이 확실하다. 그 필드가 숫자만 들어가는 자리라면 인식 결과의 O를 0으로 바꾸는 규칙 한 줄이 모델 교체보다 낫다. 사업자등록번호처럼 검증 규칙이 있는 값은 체크섬으로 걸러 낼 수도 있다.

VLM이 경계를 지웠다

시각-언어 모델이 좋아지면서 흐름이 하나 더 생겼다. 검출도 인식도 후처리도 따로 두지 않고 이미지와 지시를 함께 넣고 결과를 바로 받는 것이다.

이 영수증 이미지에서 다음을 JSON으로 뽑아 주세요.
{ "상호": ..., "사업자번호": ..., "합계금액": 정수, "품목": [{"이름":..., "금액": 정수}] }
읽을 수 없는 항목은 null로 두고, 추측하지 마세요.

파이프라인이 통째로 사라지므로 붙이는 비용이 압도적으로 싸다. 그리고 "글자를 다 뽑는 일"이 아니라 "필요한 값을 뽑는 일"을 바로 시킬 수 있다 — 앞의 문서 이해에서 다룬 그 차이다. 세로쓰기, 회전된 글자, 표 구조 같은 것도 모델이 알아서 다룬다.

대신 잃는 것이 둘이다.

좌표가 안 남는다. 값이 문서의 어디에서 왔는지 모르니 사람이 검수할 화면을 만들 수 없고, 틀렸을 때 어디를 봐야 하는지도 모른다.

조용히 지어낸다. 안 보이는 글자를 그럴듯한 것으로 채우는 것이 언어 모델의 기본 성질이다. 흐릿한 137을 137이라고 자신 있게 답하는데 실제로는 187인 경우가 생기고, 확률값이 없으니 걸러 낼 방법도 마땅치 않다.

그래서 둘을 겹쳐 쓴다

실무에서 가장 자주 보는 구성은 둘 중 하나를 고르는 게 아니라 겹쳐 쓰는 것이다.

검출기로 글자 영역과 좌표를 먼저 잡고, 그 조각들만 VLM에 넘겨 값을 뽑는다. 이러면 좌표는 검출기에서 얻고 읽기 정확도와 구조 이해는 VLM에서 얻는다. 검수 화면도 만들 수 있다.

고르는 기준을 정리하면 이렇다.

필요한 것 맞는 방식
값이 문서의 어디에서 왔는지 (검수·감사) 단계형 (검출 좌표가 남는다)
글자 단위 신뢰도 점수 단계형 (인식 확률이 나온다)
표·다단·세로쓰기 같은 복잡한 배치 VLM
형식 있는 값을 바로 JSON으로 VLM
같은 양식 수만 장을 값싸게 단계형 (호출 비용이 훨씬 싸다)
양식이 매번 다른 소량 문서 VLM
둘 다 검출로 좌표 → 조각만 VLM

평가 — CER이 높다고 쓸 수 있는 것이 아니다

OCR의 표준 지표는 CER(character error rate)이다. 정답 문자열로 바꾸는 데 필요한 편집 연산(치환·삽입·삭제) 수를 정답 길이로 나눈다.

CER=S+I+DN\text{CER} = \frac{S + I + D}{N}

문제는 이 값이 필드 단위 쓸모와 어긋난다는 것이다.

한 글자가 틀렸을 때 CER과 필드 완전 일치율이 갈리는 모습

주소 한 줄에서 번지수 한 글자가 틀리면 CER은 6.3%로 매우 좋아 보이지만 그 주소는 못 쓴다. 계좌번호도, 금액도, 사업자등록번호도 마찬가지다. 한 글자가 곧 값인 필드에서는 부분 점수가 의미가 없다.

그래서 실무 평가는 둘을 함께 본다. CER은 모델을 고를 때 쓴다 — 후보 모델 셋을 같은 데이터에 돌려 어느 쪽이 나은지 볼 때는 연속적인 값이 편하다. 필드 완전 일치율은 자동화 비율을 정할 때 쓴다. 이 값이 92%라면 여덟 건 중 하나는 사람이 손을 대야 한다는 뜻이고, 그게 실제로 아낄 수 있는 인건비의 상한이다.

여기에 하나 더 붙이면 좋은 것이 신뢰도와 실제 정확도의 대응이다. 단계형 파이프라인은 인식 확률이 나오므로, 확률 구간별로 실제 정확도를 재 보면 "확률 0.95 이상은 자동 통과, 그 아래는 검수"라는 선을 근거를 갖고 그을 수 있다. VLM 쪽에서 이걸 흉내 내려면 같은 이미지를 두세 번 물어 답이 일치하는지 보는 방법이 있는데, 호출이 두세 배 드는 만큼 값이 중요한 필드에만 쓴다.

정리

  • OCR은 글자를 찾는 일과 읽는 일 두 문제이고, 오래 그렇게 나뉘어 풀렸다
  • 검출은 글자가 사각형에 안 담기므로 다각형을 낸다. 실무의 대부분은 줄 묶기 규칙 조정이다
  • 인식은 글자 수를 모른다는 문제를 CTC로 풀었고, 지금은 언어 모델 디코더가 문맥을 메운다 — 그 이점이 곧 지어내기 위험이다
  • 한글은 글자 종류가 많고 받침 하나로 갈리므로 해상도에 특히 민감하다. 문자 체계 혼동은 후처리 규칙이 확실하다
  • VLM은 파이프라인을 통째로 지우지만 좌표와 신뢰도를 함께 지운다
  • 실무 구성은 겹쳐 쓰는 것이다 — 검출로 좌표를 잡고 그 조각만 VLM에 넘긴다
  • CER은 모델을 고를 때, 필드 완전 일치율은 자동화 비율을 정할 때 쓴다. 둘은 크게 어긋날 수 있다

읽어주셔서 감사합니다. 😊

LATEST

비전·음성·추천의 최신 글

비전·음성·추천2026.09.07

오프라인 강화학습 — 쌓인 로그만으로 정책을 배우기

실제 서비스에서 탐색은 곧 사용자에게 나쁜 행동을 해 보는 일입니다. 이미 쌓인 로그만으로 정책을 배우려 할 때 왜 Q값이 혼자 부풀어 오르는지, 그 부풀음을 누르는 세 갈래 대응, 행동 복제라는 기준선의 무게, 그리고 배포 전에 성능을 재는 일이 왜 가장 어려운지를 정리합니다.

18 MIN
비전·음성·추천2026.09.07

다국어 전이 — 라벨 없는 언어에서 모델이 동작하는 이유

영어 라벨만으로 학습한 분류기가 한국어 문장을 그대로 처리하는 일이 실제로 일어납니다. 여러 언어가 한 표현 공간에 겹쳐 놓이는 원리, 그 겹침이 무너지는 조건, 번역해서 학습할지 번역해서 추론할지 고르는 기준, 그리고 언어별로 나눠 재야 하는 이유를 정리합니다.

16 MIN
비전·음성·추천2026.09.07

정보 추출 — 글 한 덩이를 표 한 줄로 바꾸는 일

계약서와 이메일을 데이터베이스에 넣으려면 글에서 값을 뽑아 칸에 채워야 합니다. 개체명·관계·사건의 세 층위, 값을 정규화하는 일이 왜 절반인지, 근거 위치를 함께 남겨야 하는 이유, 규칙·전용 모델·언어 모델의 갈림길, 그리고 필드별로 재는 평가법을 정리합니다.

17 MIN