상태: 실측 (2026-10-29 부터 10-30, 24GB 소비자용 GPU 한 장). 숫자는 모두 직접 잰 원자료(쪽마다 출력 원문, 측정 로그, 채점 스크립트)에서 가져왔습니다. 논문 수치는 원문을 열어 확인한 표·절 번호와 함께 적었고, 재지 못한 것은 「미실측」, 원문에서 찾지 못한 것은 「미확인」으로 표시합니다. 설치하며 겪은 일과 보안 메모는 2편에 따로 모았습니다.
목차
- 1. 무엇을 왜 쟀나
- 2. 세 엔진은 어떻게 다르게 읽나
- 3. 시험 문서와 채점
- 4. 결과: 정확도, 속도, 메모리
- 5. 실제 출력 비교
- 6. 왜 이렇게 느린가, 그리고 이 숫자로 말하면 안 되는 것
- 7. 무엇을 고를까
- 8. 한계
- 참고
1. 무엇을 왜 쟀나
OCR(광학 문자 인식)은 사진이나 스캔한 쪽에서 글자를 뽑아내는 일입니다. 오래된 방식은 두 단계입니다. 먼저 쪽에서 글줄이 있는 자리를 찾고(검출), 찾은 줄을 하나씩 잘라 글자로 읽습니다(인식). 요즘은 이미지를 통째로 보고 마크다운을 바로 써 내는 비전 언어 모델 (VLM, 그림을 입력으로 받는 언어 모델)이 문서 OCR 의 순위표 위쪽을 차지합니다.
이번에 고른 엔진은 셋입니다. 셋 다 같은 회사(Baidu) 계열에서 나왔지만 쪽을 읽는 방식이 서로 다릅니다.
| 엔진 | 한 줄 | 우리가 쓴 판 |
|---|---|---|
| PP-OCRv5 한국어 | 고전 검출+인식 파이프라인. 작은 전용 모델 둘 | PaddleOCR 3.7.0, 검출 PP-OCRv5_server_det, 인식 korean_PP-OCRv5_mobile_rec |
| PaddleOCR-VL-1.6 | 레이아웃 모델이 쪽을 요소로 자르고, 0.9B VLM 이 요소마다 읽는다 | PaddleOCR 3.7.0, PaddleOCR-VL-1.6 |
| Unlimited-OCR-2 | 이미지를 시각 토큰으로 압축하고, 3B MoE 디코더가 여러 쪽을 한 번에 읽는다 | baidu/Unlimited-OCR-2(2026-10-27 공개), Transformers 4.52.1 |
왜 직접 재야 했는가. 문서 OCR 의 대표 벤치마크에 한국어가 없기 때문입니다.
- OmniDocBench(CVPR 2025, arXiv 2412.07626)의 v1.0 은 981쪽인데 영어 290, 간체 중국어 612, 혼합 79쪽입니다(표 S3). 한국어 쪽은 없습니다. 저자도 「거의 모든 알고리즘이 영어에서 중국어보다 점수가 높다」고 적습니다(§5.1). 언어에 따라 순위가 달라질 수 있다는 뜻입니다.
- 여러 쪽 문서용인 MPDocBench(arXiv 2605.22100, 433개 문서 3,246쪽)와 MarathonDocBench(100개 문서, 103쪽에서 300쪽)도 영어와 중국어뿐입니다.
- 엔진 쪽 근거도 얇습니다. PaddleOCR-VL 1.0 논문은 잘린 한 줄 단위의 사내 시험에서 한국어 편집거리 0.052를 보고했고(표 6a), 1.5·1.6판 논문에는 한국어 평가가 없습니다. PP-OCRv5 한국어 인식 모델은 공식 문서에 「한국어 글자 이미지 5,007장에서 정확도 88.0%」가 있을 뿐 논문 수치는 없습니다. Unlimited-OCR 1·2편 보고서에는 「Korean」이라는 낱말이 한 번도 나오지 않습니다.
그래서 질문은 셋입니다. 한국어 문서에서 셋 중 무엇이 가장 정확한가. 얼마나 빠르고 메모리는 얼마나 드는가. 그리고 틀릴 때는 어떻게 틀리는가.
2. 세 엔진은 어떻게 다르게 읽나
PP-OCRv5 한국어는 쪽 구조를 모릅니다. 검출기가 글줄 상자를 찾고, 인식기가 줄마다 글자를 냅니다. 출력은 줄 글자를 위에서 아래로 이은 것입니다. PaddleOCR 3.0 기술 보고서(arXiv 2507.05595, §2.1)에 따르면 이 계열은 전체 0.07B, 100MB 미만입니다(보고서의 기본 모델 기준이고, 한국어 인식 모델의 크기는 미확인입니다).
PaddleOCR-VL 은 일을 둘로 나눕니다(1.0 논문 arXiv 2510.14528, §2.1). 레이아웃 모델(1.5판부터 PP-DocLayoutV3)이 「어디에 무엇이 어떤 순서로 있는가」를 정하면, 0.9B VLM(NaViT 방식 동적 해상도 인코더 + ERNIE-4.5-0.3B)이 잘린 요소 하나의 내용만 읽습니다. VLM 이 쪽 전체를 한 번에 보지는 않습니다. 1.6판(arXiv 2606.03264)은 구조를 그대로 두고 데이터와 후학습만 바꿨습니다. 모델이 잘 틀리던 표본(체크포인트 8개와 왜곡 16종에서 예측이 갈리는 것, 고서·희귀 글자)을 골라 보강하고 CPT, SFT, GRPO 강화학습을 차례로 거쳤습니다(§3, §4).
Unlimited-OCR-2 의 뼈대는 DeepSeek-OCR(arXiv 2510.18234)의 「광학 압축」입니다. 인코더(DeepEncoder)가 1024×1024 이미지를 256개 안팎의 시각 토큰으로 16배 줄이고, 3B MoE(전문가 혼합, 토큰마다 일부 전문가만 쓴다) 디코더가 글을 씁니다. 2편 보고서(HF 공개 PDF, p.5-7)가 더한 것이 SR-SWA(희소 참조 슬라이딩 창 어텐션)입니다. 디코더가 다음 토큰을 낼 때마다 모든 쪽의 시각 토큰을 다 보지 않고, 그 쪽의 블록 몇 개와 직전 출력만 봅니다. 우리가 받은 설정값으로 계산하면 원격 12블록×32 + 로컬 128 = 512토큰이고, 모델 카드의 「512 tokens」와 맞습니다. 쪽이 늘어도 한 걸음의 계산량이 늘지 않게 하려는 장치입니다.
두 VLM 의 학습 데이터에도 흥미로운 고리가 있습니다. Unlimited-OCR-2 의 의사 정답(사람 대신 다른 모델이 만든 정답)은 MinerU2.5-Pro 와 PaddleOCR-VL-1.6 에서 뽑았습니다(2편 보고서 p.8). 이번 비교의 두 VLM 은 선생과 학생 관계이기도 합니다.
3. 시험 문서와 채점
정답을 아는 문서를 만들었다
실제 스캔 문서는 정답 글자를 사람이 일일이 쳐야 합니다. 그래서 반대로 했습니다. 정답 글자를 먼저 정하고 그 글자로 쪽을 그렸습니다. 본문은 TT Lab 의 기술 공부 노트에서 한글 비중이 40% 넘는 문단을 뽑았고, A4 크기(150dpi, 1240×1754 화소)에 Apple SD Gothic Neo 글꼴 하나로 그렸습니다. 60쪽은 이렇게 나눴습니다.
| 묶음 | 쪽 | 만든 방법 | 정답 글자 수(정규화 뒤) |
|---|---|---|---|
| 일반 본문 | 8 | 한 단 본문, 26px 글자 | 9,833 |
| 흐린 사본 | 8 | 일반 본문 8쪽을 가우스 흐림 → 1.5도 회전 → 0.6배 축소 → JPEG 품질 35 | 9,833 |
| 한국어 표 | 4 | 머리글이 한국어인 6열 23행 격자 표 | 2,285 |
| 긴 문서 | 40 | 서로 다른 문단 40쪽, 24px 글자 | 48,878 |
흐린 사본은 일반 본문과 글자가 똑같습니다. 그래서 같은 엔진의 두 묶음 차이가 곧 「화질이 나빠져서 생긴 오류」입니다.
채점: 글자 오류율(CER) 두 가지
CER(Character Error Rate)은 정답을 출력으로 바꾸는 데 필요한 최소 편집(글자 넣기·빼기·바꾸기) 수를 정답 글자 수로 나눈 값입니다. 1%면 100글자에 하나꼴로 틀렸다는 뜻입니다. 편집거리는 Myers(1999)의 비트 병렬 알고리즘으로 구했습니다.
엔진마다 출력 꼴이 다르므로 먼저 정규화합니다. 유니코드 NFKC 로 맞추고, 마크다운 기호(#, *, | 등)와 HTML 태그, 모델이 붙이는
좌표 표식을 지우고, 공백과 줄바꿈을 모두 뺍니다. 띄어쓰기와 줄 나눔은 레이아웃에 따라 달라지므로 글자 순서만 비교합니다.
그리고 CER 을 두 번 냅니다.
- 전체 CER: 정규화한 글자 전부. 낫표 「」, 가운뎃점 ·, 마침표, 쉼표 같은 문장 부호가 들어갑니다.
- 글자만 CER: 한글·영문·숫자만 남기고 잰 값.
둘을 따로 둔 이유는 엔진마다 문장 부호를 다루는 습관이 크게 달라서입니다. 한 숫자로 묶으면 「문장 부호를 자주 빼먹는 엔진」과 「한글을 잘못 읽는 엔진」이 같은 점수로 보입니다. 검색 색인처럼 글자만 맞으면 되는 용도와, 사람이 그대로 읽을 문서를 만드는 용도는 서로 다른 숫자를 봐야 합니다.
채점 함정: 좌표를 지우지 않으면 CER 이 16%
Unlimited-OCR-2 의 출력에는 블록마다 좌표가 붙습니다. 예를 들면 이런 꼴입니다.
<BLOCK>text[71, 96, 900, 160]<FORK>우리에게 의미는 「언젠가 휴대폰 안에서 …
처음 채점기는 <…> 태그만 지우고 text[71, 96, 900, 160] 는 남겼습니다. 그 결과 일반 본문 CER 중앙값이 16.3%(쪽마다 13.9%에서
17.5%)로 나왔습니다. 좌표 정규식 한 줄을 더하자 0.80% 가 됐습니다. 흐린 사본은 16.95% → 1.99%, 표는 8.38% → 0.17%입니다(같은
출력, 같은 정답으로 다시 계산). 20배 차이가 출력 꼴 하나에서 나온 셈입니다. VLM 출력을 채점할 때는 먼저 출력 원문 몇 쪽을 눈으로
읽고 정규화 규칙을 맞추는 것이 순서입니다.
4. 결과: 정확도, 속도, 메모리
| 엔진 | 묶음 | 쪽 | 전체 CER(중앙) | 전체 CER(최대) | 글자만 CER(중앙) | 초/쪽 | 최대 GPU 메모리 |
|---|---|---|---|---|---|---|---|
| PP-OCRv5 한국어 | 일반 본문 | 8 | 1.52% | 2.37% | 0.33% | 0.36 | 2.27 GiB |
| 흐린 사본 | 8 | 4.47% | 4.89% | 1.23% | 0.20 | 2.27 GiB | |
| 한국어 표 | 4 | 0.00% | 0.00% | 0.00% | 0.30 | 2.27 GiB | |
| 긴 문서(쪽마다, 40쪽) | 40 | 1.41% | 0.49% | 0.34 | 2.27 GiB | ||
| PaddleOCR-VL-1.6 | 일반 본문 | 8 | 0.48% | 1.71% | 0.28% | 13.81 | 5.80 GiB |
| 흐린 사본 | 8 | 1.51% | 2.68% | 0.83% | 14.04 | 5.80 GiB | |
| 한국어 표 | 4 | 0.00% | 0.00% | 0.00% | 8.59 | 5.90 GiB | |
| 긴 문서(쪽마다, 40쪽) | 40 | 0.53% | 0.37% | 14.39 | 5.80 GiB | ||
| Unlimited-OCR-2 | 일반 본문 | 8 | 0.80% | 0.98% | 0.75% | 31.07 | 6.85 GiB |
| 흐린 사본 | 8 | 1.99% | 3.25% | 1.76% | 30.91 | 6.85 GiB | |
| 한국어 표 | 4 | 0.17% | 0.71% | 0.19% | 21.52 | 6.85 GiB | |
| 긴 문서(10쪽 한 번에) | 10 | 2.72% | 2.01% | 38.07 | 7.59 GiB | ||
| 긴 문서(20쪽 한 번에) | 20 | 2.59% | 2.00% | 41.21 | 8.81 GiB |
읽는 법. 중앙값은 쪽마다 낸 CER 을 늘어놓은 가운데 값이고, 8쪽처럼 짝수면 위쪽 값(다섯 번째)을 썼습니다. 긴 문서는 한 덩어리로 채점해
값이 하나뿐입니다. 시간은 예열 한 쪽을 빼고 잰 평균이고, 긴 문서는 전체 시간을 쪽 수로 나눴습니다. 메모리는 각 프레임워크의 할당기가
기록한 최대값(PyTorch·Paddle 의 max_memory_allocated)이라 nvidia-smi 에 보이는 값보다 작습니다. 13개 묶음 모두 실패한 쪽은 없었습니다.
그림에서 짚을 곳은 셋입니다.
PaddleOCR-VL-1.6 이 네 묶음 모두에서 가장 정확했습니다. 일반 본문 전체 CER 0.48%는 1,230글자쯤인 쪽에서 여섯 글자 안팎을 틀린 정도입니다. 표는 PP-OCRv5 와 함께 4쪽 모두 0%였습니다.
문장 부호를 빼면 순위가 바뀝니다. 전체 CER 로는 Unlimited-OCR-2(0.80%)가 PP-OCRv5(1.52%)보다 낫습니다. 그런데 글자만 세면 PP-OCRv5 가 0.33%, Unlimited-OCR-2 가 0.75%로 뒤집힙니다. 흐린 사본에서는 더 뚜렷합니다. 전체 CER 은 PP-OCRv5 가 4.47%로 셋 중 가장 나쁘지만 글자만 CER 은 1.23%로 Unlimited-OCR-2(1.76%)보다 좋습니다. PP-OCRv5 의 오류는 대부분 문장 부호이고, Unlimited-OCR-2 의 오류는 대부분 글자입니다. 그림에서 두 점 사이 막대가 길면 문장 부호 오류가 많다는 뜻입니다. Unlimited-OCR-2 는 막대가 거의 없습니다.
여러 쪽을 한 번에 읽으면 Unlimited-OCR-2 의 오류가 세 배쯤 늘었습니다. 같은 긴 문서 앞 10쪽을 놓고 비교하면 PaddleOCR-VL-1.6 은 0.58%, PP-OCRv5 는 1.53%인데 Unlimited-OCR-2 는 2.72%입니다(앞 10쪽 값은 40쪽 출력을 정답 10쪽 끝에 맞춰 잘라 다시 계산했고, 40쪽 전체로 같은 방법을 쓰면 표의 0.53%·1.41%가 그대로 나옵니다). 한 쪽씩 읽을 때(일반 본문 0.80%)와의 차이는 해상도 모드에서 옵니다. 한 쪽은 타일을 나눠 자세히 보는 Gundam 모드로, 여러 쪽은 쪽마다 시각 토큰 273개인 Base 모드로 읽습니다. 5절에서 실제 예를 봅니다.
속도는 자릿수가 다릅니다. 일반 본문 한 쪽에 PP-OCRv5 는 0.36초, PaddleOCR-VL-1.6 은 13.81초(약 38배), Unlimited-OCR-2 는 31.07초(약 86배)가 걸렸습니다. 한 시간으로 단순 환산하면 1만 쪽, 약 260쪽, 약 116쪽입니다. 흐린 사본에서 PP-OCRv5 가 더 빠른 것(0.20초)은 이미지가 0.6배로 작아서입니다. 메모리는 PP-OCRv5 2.27 GiB, PaddleOCR-VL-1.6 5.80 GiB, Unlimited-OCR-2 는 가중치만 6.32 GiB 이고 한 쪽 6.85 GiB, 10쪽 7.59 GiB, 20쪽 8.81 GiB 로 쪽 수에 따라 늘었습니다. 24GB 카드라면 셋 모두 여유가 있습니다.
다만 VLM 둘의 시간은 우리 실행 방식의 시간이지 모델의 한계가 아닙니다. 6절에서 이유를 봅니다.
5. 실제 출력 비교
숫자 뒤에 있는 실제 출력을 봅니다. 아래 두 그림은 같은 2쪽의 같은 자리입니다. 위는 엔진이 받은 이미지를 화소 그대로 옮긴 조각이고, 아래는 세 엔진의 출력을 정답 위치에 맞춰 놓은 것입니다. 이 쪽은 오류 유형이 고루 모여 있어서 골랐습니다(일반 본문 2쪽의 CER 은 PaddleOCR-VL-1.6 0.09%, Unlimited-OCR-2 0.26%, PP-OCRv5 1.57%로 묶음 중앙값보다 조금 좋은 쪽입니다).
드문 받침: 「쟀」은 셋 다 한 번도 못 읽었다
「쟀습니다」(쟀다, 재다의 과거형)는 일반 본문 8쪽에 7번 나옵니다. 세 엔진 모두 7번 다 틀렸습니다. 깨끗한 일반 본문에서도 그렇습니다.
| 「쟀」을 무엇으로 읽었나 | 일반 본문(7번) | 흐린 사본(7번) |
|---|---|---|
| PP-OCRv5 한국어 | 졌 7 | 괜 4, 겠 3 |
| PaddleOCR-VL-1.6 | 잤 6, 챙 1 | 졌 2, 채 2, 잤 1, 짧 1, 챗 1 |
| Unlimited-OCR-2 | 잤 2, 잿 2, 썼 1, 겠 1, 잦 1 | 겠 3, 쪼 2, 켜 1, 챙 1 |
PP-OCRv5 는 깨끗한 쪽에서 언제나 「졌」으로 읽었습니다. 인식기는 정해진 글자 사전 안에서만 답을 고르는데, 「쟀」이 그 사전에 없으면 이렇게 가장 닮은 글자로 일관되게 바뀝니다(사전에 실제로 없는지는 미확인입니다). VLM 둘은 답이 흩어집니다. 비슷한 모양의 글자 가운데 언어 모델이 더 자주 본 쪽으로 기우는 것으로 보입니다. 일상 문서에 드물게 나오는 받침이라 세 엔진의 학습 데이터에 적었을 가능성이 큽니다.
비슷한 글자가 더 있습니다. 「힙」(읽힙니다, 밝힙니다, 힙 메모리)은 일반 본문에 5번 나오는데 Unlimited-OCR-2 는 5번 모두 「힘」이나 「립」으로 읽었고, PaddleOCR-VL-1.6 은 다 맞혔으며, PP-OCRv5 는 한 번 틀렸습니다. 「씁니다」의 「씁」은 Unlimited-OCR-2 만 「씽」으로 읽었습니다 (일반 본문 3번 중 2번, 흐린 사본 3번 모두). 반대로 「랠리」의 「랠」은 PP-OCRv5(앨)와 PaddleOCR-VL-1.6(램, 랄)이 틀리고 Unlimited-OCR-2 가 깨끗한 쪽에서 맞혔습니다. 드문 글자에서는 어느 엔진도 안전하지 않고, 엔진마다 약한 글자가 다릅니다.
뜻이 뒤집히는 오류: 「없습니다 → 있습니다」
Unlimited-OCR-2 는 「없」을 「있」으로 읽었습니다. 일반 본문에 「없」이 14번 나오는데 그중 2번이고, 흐린 사본에서도 같은 2번입니다. 그림의 예는 「왜 그런지 알려 주는 메시지도 없습니다」가 「메시지도 있습니다」가 된 것입니다. CER 로는 1,150글자 중 한 글자, 0.09%포인트에 불과하지만 문장의 뜻은 정반대가 됩니다. 두 Paddle 엔진은 14번 모두 맞혔습니다.
이 오류는 글자 모양만으로는 설명이 어렵습니다. 「없」과 「있」은 받침 모양이 꽤 다릅니다. 시각 근거가 약할 때 디코더의 언어 지식이 더 흔한 쪽을 채우는 오류로 보입니다. PP-OCRv6 논문(arXiv 2606.13108)도 VLM 계열 OCR 의 이런 「환각」을 문제로 듭니다. 계약서·검사 결과처럼 부정어 하나가 중요한 문서라면 VLM 출력은 사람이 검수하는 흐름을 전제로 해야 합니다.
문장 부호: PP-OCRv5 는 낫표를 바꾸고, 흐리면 지운다
PP-OCRv5 의 전체 CER 을 끌어올린 것은 거의 모두 문장 부호입니다. 오류 유형을 세어 보면(정규화 글자를 정렬해 다른 곳을 센 것) 일반 본문에서 「 를 ' 로 바꾼 것이 46번, 」 를 ] 로 바꾼 것이 42번이었습니다. 흐린 사본에서는 바꾸는 대신 지웠습니다. 마침표 삭제 60번, 「 삭제 39번, 쉼표 삭제 38번, 쉼표를 마침표로 바꾼 것 36번, 」 삭제 30번, 가운뎃점 · 삭제 28번입니다. 작고 흐린 점은 검출 단계에서 글자로 잡히지 않는 것으로 보입니다.
VLM 둘도 문장 부호를 틀리지만 횟수가 훨씬 적습니다. PaddleOCR-VL-1.6 은 흐린 사본에서 「 를 ‘ 나 ' 로 바꾼 것이 18번, Unlimited-OCR-2 는 흐린 사본에서 가운뎃점 삭제 18번, 「 를 ' 로 바꾼 것 11번이 가장 많았습니다.
채점기 쪽의 작은 흠도 하나 밝혀 둡니다. 정답의 줄표 – 를 세 엔진 모두 하이픈 - 으로 읽었는데, 정규화가 하이픈을 마크다운 기호로 보고 지우므로 「줄표 삭제」로 묶음마다 4번씩 세었습니다. 엄밀히는 줄표를 하이픈으로 바꾼 것이고, 세 엔진에 똑같이 들어가므로 순위는 바뀌지 않습니다.
여러 쪽 모드의 해상도 저하
Unlimited-OCR-2 가 긴 문서 10쪽을 한 번에 읽은 출력에는 한 쪽씩 읽을 때 보기 어려운 오류가 섞입니다. 「늘어납니다 → 놀아납니다」, 「체감 → 채갑」, 「멘션 → 댄선」, 「가벼운 → 바뀌온」, 「댓글 → 덧글」(3번), 「랠리 → 뭘리」 같은 것들입니다. 한 글자가 아니라 두세 글자가 함께 무너지고, 모양이 닮은 다른 낱말로 바뀝니다. 같은 쪽을 쪽마다 읽은 PaddleOCR-VL-1.6 의 앞 10쪽 CER 은 0.58%였습니다.
원인은 논문이 이미 짚었습니다. DeepSeek-OCR 표 3에서 획이 빽빽한 중국어는 같은 Base 모드에서 편집거리가 영어의 약 4배(0.205 대 0.054)이고, 토큰을 늘린 Gundam 모드에서 0.097로 좋아집니다. Unlimited-OCR 1편 보고서(arXiv 2606.23050, §5.4)도 40쪽이 넘는 문서의 오류 대부분이 Base 모드에서 작은 글자를 못 읽어서 생겼다고 적습니다. 한글도 받침이 있는 네모꼴 글자라 중국어 쪽에 가깝습니다. 우리 결과는 그 설명과 맞습니다. 쪽당 시각 토큰이 273개로 줄면 24px 한글의 받침이 뭉개집니다.
6. 왜 이렇게 느린가, 그리고 이 숫자로 말하면 안 되는 것
Unlimited-OCR-2 의 한 쪽 30초는 논문의 속도와 거리가 멉니다. 하지만 두 숫자는 종류가 다릅니다.
논문 숫자는 동시 처리량입니다. Unlimited-OCR 1편의 5,580 TPS(초당 토큰, §5.2)는 동시 요청 512개의 합계이고, 2편 표 4의 1,315 TPS 는 배치 16입니다. 요청 하나로 나누면 각각 약 11, 약 82 토큰/초입니다. 2편 그림 6(b)의 단계당 약 3.8ms 는 배치 3에서 잰 값입니다. 세 수치 모두 하드웨어가 밝혀져 있지 않습니다(미확인). 우리는 배치 1에서 초당 37.9토큰, 한 걸음 26.4ms 였습니다(일반 본문 8쪽의 출력 9,426토큰을 248.6초로 나눈 값).
하드웨어 몫은 크지 않습니다. 배치 1 디코딩은 매 걸음 가중치를 메모리에서 읽어야 하므로 메모리 대역폭에 묶입니다. 모델 카드가 시험한 A800 80GB 의 대역폭은 1,935 GB/s(공식 사양)이고 우리 GPU 는 약 936 GB/s 로, 차이는 2.1배쯤입니다. 활성 파라미터 약 0.57B 를 bf16(2바이트)으로 읽으면 한 걸음에 약 1.14 GB 이니, 우리 GPU 로도 이론상 한 걸음 약 1.2ms 가 하한입니다(추정). 실측 26ms 는 그 20배가 넘습니다. 병목은 하드웨어가 아니라 실행 경로입니다.
Transformers 경로는 「빠른 시험용」입니다. 모델 카드가 그렇게 부르고, 서빙에는 SGLang 을 권합니다. 우리가 받은 원격 코드(revision 5632329a)를
읽어 보면 이유가 보입니다. 토큰을 하나씩 내는 파이썬 반복문이고 CUDA graph 가 없습니다. MoE 층마다 tokens_per_expert.cpu() 로 GPU 와 CPU 가
동기화하고, 디코딩 어텐션은 고른 블록만 계산하지 않고 캐시 전체를 fp32 로 복사해 밀집 행렬곱을 한 뒤 마스크로 가립니다. 결과는 희소
어텐션과 같지만 계산은 밀집입니다. 그래서 20쪽 묶음이 10쪽 묶음의 2.16배 걸렸습니다(출력 토큰은 1.96배). 한 걸음이 27.7ms 에서 30.6ms 로
약 10% 길어진 몫입니다.
SR-SWA 가 약속하는 것은 「한 걸음이 일정하다」입니다. 총시간은 출력 토큰 수에 비례하므로 쪽 수에 선형으로 늘어나는 것이 정상입니다. SR-SWA 가 막는 것은 전체 어텐션의 제곱 증가이고, 2편 그림 6(b)에서 그 차이가 크게 벌어지는 곳은 50쪽에서 100쪽 이상입니다(100쪽에서 전체 어텐션 약 26.7ms 대 SR-SWA 약 3.9ms, 그림을 눈으로 읽은 값). 우리 10·20쪽 측정으로는 SR-SWA 의 이득을 검증할 수 없습니다.
PaddleOCR-VL 도 같은 사정입니다. 우리는 vLLM 이나 FastDeploy 서버 없이 Paddle 동적 그래프로 한 쪽씩 순서대로 읽었습니다. 1.0 논문 표 13은 A100 한 장에 512개 PDF 를 몰아 넣어 FastDeploy 1.62 쪽/초, vLLM 1.35 쪽/초를 보고합니다. 부록 표 A2·1.5판 표 A8에는 보급형 소비자 GPU 의 0.36에서 0.54 쪽/초도 있습니다. 우리 0.07 쪽/초(13.81초)와는 열 배 넘게 차이가 납니다. 이것도 묶음 처리량이라 바로 견줄 수는 없습니다.
그래서 이 결과로 말하면 안 되는 것들이 있습니다.
- 「Unlimited-OCR-2 는 PaddleOCR-VL-1.6 보다 두 배 느리다」: 두 VLM 모두 권장 서빙 경로를 쓰지 않았습니다. 서빙 엔진에서의 속도 차이는 미실측입니다.
- 「PP-OCRv5 가 VLM 보다 90배 빠르다」: 고전 파이프라인의 속도는 우리 조건에서 맞지만, VLM 쪽 숫자는 배치 1과 서빙 엔진 없는 경로의 값입니다.
- 「Unlimited-OCR-2 가 가장 부정확하다」: 우리 시험은 한 단 본문의 글자만 봤습니다. 이 모델이 내세우는 것은 쪽을 넘는 표와 문단, 제목 계층입니다. 자기 보고 MPDocBench 84.59(2편 p.10 표 1)는 같은 벤치마크에서 제3자가 잰 PaddleOCR-VL-1.5 의 80.80(MPDocBench 논문 표 2)보다 높습니다 (측정한 사람이 다르고, 입력 방식이 같은지는 미확인입니다). 구조 지표는 우리가 재지 않았습니다.
- 「반복 오류가 없었다」: 저자의 평가 설정은 n-gram 반복 차단(크기 35)을 켜지만 우리는 껐습니다. 이번 60쪽에서 반복 루프는 보지 못했지만, 설정이 다릅니다.
7. 무엇을 고를까
우리 실측이 닿는 범위 안에서만 권합니다. 한국어 한 단 본문, 격자 표, 24GB GPU 한 장, 배치 1 기준입니다.
| 하려는 일 | 고를 것 | 근거와 주의 |
|---|---|---|
| 많은 쪽을 빨리, 검색 색인용 | PP-OCRv5 한국어 | 쪽당 0.36초, 2.27 GiB. 글자만 CER 0.33%(흐린 사본 1.23%). 낫표·마침표는 바뀌거나 사라진다 |
| 사람이 읽을 결과, 흐린 스캔 | PaddleOCR-VL-1.6 | 네 묶음 모두 가장 정확(일반 0.48%, 흐린 1.51%). 우리 경로로 쪽당 14초, 대량이면 vLLM·FastDeploy 서빙을 따로 재 볼 것 |
| 쪽을 넘는 표·문단, 긴 책 | 우리 실측으로는 판단 보류 | Unlimited-OCR-2 는 글자 정확도에서 셋 중 가장 약했고(여러 쪽 모드 2.6%대), 구조 장점은 재지 않았다. SGLang 경로로 따로 잴 것 |
| 부정어·숫자가 중요한 문서 | 어느 엔진이든 검수 전제 | 「쟀」은 셋 다 7번 모두 틀렸고, VLM 은 「없 → 있」처럼 뜻을 뒤집을 수 있다 |
고전 파이프라인과 VLM 을 섞는 길도 있습니다. 먼저 PP-OCRv5 로 전부 읽어 색인을 만들고, 사람이 읽을 쪽이나 낮은 신뢰도의 쪽만 PaddleOCR-VL-1.6 으로 다시 읽는 식입니다. 이 조합의 효과는 미실측입니다.
8. 한계
- 합성 문서입니다. 정답을 알기 위해 글자를 글꼴 하나로 그렸고, 흐림·회전·축소·JPEG 도 합성입니다. 종이 질감, 휘어짐, 그림자, 손글씨, 다단 편집, 도장 같은 실제 스캔의 어려움은 없습니다. 실제 스캔에서의 결과는 미실측입니다.
- 표가 단순합니다. 병합 칸이 없는 격자 표 4쪽이고, 표 구조(TEDS)는 재지 않고 칸 글자만 이어 비교했습니다.
- 표본이 작습니다. 묶음마다 4쪽에서 8쪽이고, 중앙값은 8쪽 중 다섯 번째 값입니다. 0.1%포인트 단위의 차이는 쪽 하나로 뒤집힐 수 있습니다.
- 장비 한 대, 시분할입니다. 24GB GPU 한 장을 다른 작업과 나눠 썼고, 그 영향은 따로 재지 않았습니다.
- 서빙 엔진을 쓰지 않았습니다. Unlimited-OCR-2 는 Transformers 경로(bf16, torch 2.14), PaddleOCR 계열은 PaddleOCR 3.7.0 과 paddlepaddle-gpu 3.4.0(cu129) 자체 추론입니다.
- n-gram 반복 차단을 껐습니다(Unlimited-OCR-2,
no_repeat_ngram_size=0). - Unlimited-OCR-2 의 40쪽 묶음은 측정이 중간에 끊겨 10쪽과 20쪽만 있습니다. 다른 두 엔진의 긴 문서는 40쪽을 쪽마다 읽었습니다.
- 본문 출처. 시험 문단은 우리 공부 노트에서 왔고, 그중에는 이 블로그에 공개된 글도 있습니다. 엔진들의 학습 데이터에 같은 글이 들어갔는지는 미확인입니다.
- 메모리 숫자는 할당기 기준입니다. 프레임워크가 미리 잡아 두는 몫과 CUDA 문맥은 빠져 있어 실제 카드 점유는 더 큽니다.
티티 한마디. 「쟀습니다」를 세 엔진이 스물한 번 읽어서 스물한 번 다 틀렸어요. 탁구공 속도를 쟀다고 쓰려다 잤다고 쓰면 곤란하잖아요! 그래서 OCR 결과는 숫자 하나로 고르지 않고, 무엇을 어떻게 틀리는지까지 보고 골라요.
참고
원문은 모두 2026-10-30 에 열어 확인했습니다. arXiv 는 HTML 판이라 쪽 번호 대신 절·표 번호를 적었습니다.
- Unlimited OCR Works, arXiv 2606.23050: https://arxiv.org/abs/2606.23050
- Unlimited OCR Works 2(보고서 PDF, arXiv 번호 없음): https://huggingface.co/baidu/Unlimited-OCR-2/blob/main/Unlimited-OCR-2.pdf
- Unlimited-OCR-2 모델 카드: https://huggingface.co/baidu/Unlimited-OCR-2
- DeepSeek-OCR, arXiv 2510.18234: https://arxiv.org/abs/2510.18234
- DeepSeek-OCR 2, arXiv 2601.20552: https://arxiv.org/abs/2601.20552
- PaddleOCR-VL, arXiv 2510.14528: https://arxiv.org/abs/2510.14528
- PaddleOCR-VL-1.5, arXiv 2601.21957: https://arxiv.org/abs/2601.21957
- PaddleOCR-VL-1.6, arXiv 2606.03264: https://arxiv.org/abs/2606.03264
- PaddleOCR 3.0 Technical Report, arXiv 2507.05595: https://arxiv.org/abs/2507.05595
- PP-OCRv6, arXiv 2606.13108: https://arxiv.org/abs/2606.13108
- PP-OCRv5 다국어 인식 모델(공식 문서): https://www.paddleocr.ai/latest/en/version3.x/algorithm/PP-OCRv5/PP-OCRv5_multi_languages.html
- OmniDocBench, arXiv 2412.07626, 저장소와 순위표: https://github.com/opendatalab/OmniDocBench
- MPDocBench-Parse, arXiv 2605.22100: https://arxiv.org/abs/2605.22100
- MarathonDocBench: https://huggingface.co/datasets/baidu/MarathonDocBench
- A800 80GB PCIe 사양(Lenovo Press): https://lenovopress.lenovo.com/lp1813-thinksystem-nvidia-a800-80gb-pcie-gen4-gpu
- Myers, 「A fast bit-vector algorithm for approximate string matching based on dynamic programming」, Journal of the ACM, 1999