- 2026년 10월 12일에 공개된 MiniCPM-V 4.7의 소형 버전(1B, Apache-2.0)을 Apple M3 Mac의 transformers를 사용하여 구동했습니다. 메모리는 약 4.4GB이며 API 키가 필요하지 않습니다.
- 직접 만든 일본어 영수증 1종류에 각 모드별로 한 번씩 읽게 했습니다. 선명한 이미지의 경우 단 하나의 오류도 없이 작성할 수 있었습니다. 절반으로 축소하고 흐리게 처리한 이미지에서는 16x 모드에서 오류가 발생했지만(문자 오류율 5.4%), 4x 모드로 변경하니 0%였습니다.
- 반대로, 선명한 이미지의 경우 4x 모드가 1글자를 더 틀리고 느렸습니다. 시도 횟수가 적으므로, 어느 모드를 사용할지는 자신의 이미지로 확인해야 합니다.
MiniCPM-V는 OpenBMB가 공개한 이미지 이해 모델 시리즈입니다. 스마트폰 등의 단말기에서 구동하는 것을 중시하고 있습니다. 2026년 10월 12일에 MiniCPM-V 4.7이 공개되었으며, 35B-A3B(MoE)와 1B의 두 가지 사이즈가 나왔습니다(GitHub 뉴스).
이번에 시도한 것은 작은 MiniCPM-V-4.7-1B입니다. 모델 카드에 따르면 다음 특징들이 있습니다.
| 항목 | 내용 |
|---|
| 구성 | 이미지 인코더 (SigLIP2 기반) + 언어 모델 (Qwen3.5 / Qwen3.6 기반) |
| ... | downsample_mode에서 16x(기본값)와 4x(세밀한 부분용)를 선택 가능 |
이미지 토큰은 이미지를 모델이 읽을 수 있는 단위로 나눈 것입니다. 16x는 이미지를 강하게 압축하여 토큰 수를 줄이고, 4x는 압축을 약화시켜 세부 정보를 남깁니다. 모델 카드에서는 4x를 '세밀한 부분용'이라고 명시하고 있습니다.
'글자가 작은 이미지에서 4x가 정말로 읽을 수 있는지'를 정답이 알려진 일본어 영수증으로 확인했습니다.
- 사진(금문교)에 대해 일본어로 설명시키기
- 일본어 영수증 OCR 수행 및 16x와 4x 비교. 영수증은 다음 2장입니다.
- [IMG:N]
receipt.png: 선명한 버전 (560×540)
- [IMG:N]
receipt_small.jpg: 절반으로 축소하고 약간 흐리게 처리하여 화질을 낮춘 JPEG (280×270)
- 영수증 내용에 대해 질문하기
영수증은 정답 문자열을 알 수 있도록 PIL(Python의 이미지 라이브러리)로 제작했습니다. 정확도는 문자 오류율(CER: 정답으로 만들기 위해 필요한 문자의 추가/삭제/대체 횟수 ÷ 정답 문자 수)로 측정합니다. 공백과 개행은 제외하고 비교했습니다.
- OS: macOS 26.6.2 (Apple M3, 메모리 24GB)
- Python: 3.12.15
- 주요 라이브러리: transformers==5.20.1, torch==2.14.1, torchvision==0.29.1, av==19.0.1, accelerate==1.15.0 (간접 의존 포함하여
requirements.txt로 고정) - 실행 장치: MPS (Apple GPU), bfloat16
- 실행일: 2026-10-18
cd code
uv venv --python 3.12 .venv
uv pip install --python .venv -r requirements.txt
...
API 키는 필요하지 않습니다. 모델은 gated(이용 신청이 필요한 모델)가 아닙니다.
모델 카드 설치 절차에서는 torchcodec (동영상 등의 읽기 라이브러리)를 설치합니다. torchcodec이 원활하게 설치되지 않는 환경을 위해, 대신 PyAV (av)를 사용하는 방법도 안내되어 있습니다(모델 카드). 이번에는 이미지만 다루었으므로, PyAV를 사용하는 구성으로 했습니다.
영수증 이미지를 만드는 코드입니다.
"""OCR 검증용으로 정답 텍스트가 알려진 일본어 영수증 이미지를 생성합니다 (macOS의 히라기노 각고딕 사용).
receipt.png(선명한 버전)과 receipt_small.jpg(축소/흐림/저화질 버전) 두 장을 만듭니다.
"""
...
추론 코드입니다. 모델 카드의 'Inference with Transformers' 예시를 기반으로 했습니다. 차이점은 재현하기 쉽도록 탐욕법(매번 가장 확률 높은 토큰을 선택하는 방법. do_sample=False)으로 변경한 점입니다. 모델 카드 권장 방식은 temperature=0.7 등의 샘플링 방식입니다.
MiniCPM-V-4.7-1B를 Mac(Apple Silicon / MPS)에서 구동하여 이미지 설명과 일본어 OCR을 시도했습니다.
이미지는 prepare_media.sh로 media/에 준비합니다.
추론 코드는 모델 카드의 'Inference with Transformers' 예시를 기반으로 작성되었습니다:
...
outputs/run.log에서 내용을 가져왔습니다. 라이브러리 경고(예: [transformers]로 시작하는 줄)는 생략했습니다. 주요 경고 내용은 추후 설명하겠습니다.
Python 3.12.15 / Darwin arm64
transformers==5.20.1
torch==2.14.1
...
| 이미지 | 모드 | 입력 토큰 | 문자 오류율 | 생성 시간 |
|---|
| receipt.png (560×540) | 16x | 236 | 0.0% | 3.4초 |
| receipt.png (560×540) | 4x | 824 | 0.9% | 4.9초 |
| receipt_small.jpg (280×270) | 16x | 100 | 5.4% | 3.2초 |
| receipt_small.jpg (280×270) | 4x | 292 | 0.0% | 3.3초 |
선명한 영수증의 경우, 16x 모드에서 상점 이름, 날짜, 금액까지 모두 정확하게 읽을 수 있었습니다. 이번 한 장만으로는 1B라는 작은 모델임에도 불구하고 깨끗한 일본어 인쇄물을 올바르게 읽었습니다. 실제 문서나 영수증 사진에서도 동일하게 읽을 수 있는지는 확인이 필요합니다.
축소되거나 흐릿한 영수증의 경우, 16x 모드에서 '抹茶チーズケーキ'가 '抹茶チーサーキ'로, '季節のフルーツサンド'가 '季節の Fruルサンド'로 변형되었습니다. 4x 모드로 설정하자 둘 다 정확하게 읽혔고 오류율은 0%였습니다. 입력 토큰은 100개에서 292개로 증가했지만, 생성 시간은 거의 동일했습니다(3.2초와 3.3초).
이미지가 작으면 16x 모드에서는 한 글자당 사용할 수 있는 정보가 부족한 것 같습니다. 4x는 압축이 약해서 세밀한 자형이 남아있습니다.
반면, 선명한 영수증을 4x로 읽게 하니 '珈琲'가 '珈班'으로 변했습니다. 게다가 금액이 상품명과 다른 줄에 분리되어 출력되었습니다(문자 오류율은 공백과 개행을 제외하고 측정하므로, 이러한 분리는 숫자에 포함되지 않습니다). 입력 토큰이 3.5배(236 → 824) 증가했고, 생성 시간도 약 1.5초 늘어났습니다.
한 번씩, 한 종류의 영수증으로만 시도했기 때문에 일반화할 수는 없습니다. 이번 결과로는 '우선 16x로 읽고, 글자가 작은 이미지에 대해서만 4x를 사용한다'는 활용 방안이 생각해 볼 수 있지만, 실제로 사용할 때는 자신의 이미지로 두 가지 모드를 비교하여 확인해야 합니다.
진먼교(金門橋) 사진의 경우 '붉은 다리가 만을 가로지른다'와 같이 세 문장으로 설명할 수 있었습니다. 다만, '진먼교'나 '샌프란시스코' 같은 고유명사는 언급되지 않았습니다.
영수증에 대한 질문(가장 비싼 상품과 거스름돈)에는 '季節のフルーツサンド', '¥650', '¥218'로 정확하게 답했습니다.
이번 한 번의 실행에서는 M3 Mac에서 1초당 약 14~32 토큰이 생성되었습니다. 속도는 환경이나 입력에 따라 달라지므로, 실제로 사용하기 전에 자신의 환경에서 측정해야 합니다. MPS의 확보 메모리는 4.4GB입니다. 모델 로딩은 2.9초가 걸렸습니다(다운로드된 모델을 읽었을 때의 값입니다).
로그에는 causal_conv1d나 flash-linear-attention이 없다는 경고가 있어, 느린 참조 구현(PyTorch만으로 작성한 버전)을 사용한다는 내용이 있었습니다. 이러한 고속 버전이 포함되면 더 빨라질 가능성이 있습니다(이번에는 시도하지 않았습니다). 또한, 이미지 로딩에 torchvision을 사용하는 것은 비권장이며, torchcodec을 넣도록 하는 경고도 있었습니다.
참고로 파라미터 수를 세어보니 1.55B였습니다. 이름은 '1B'이지만, Hugging Face 페이지의 표시에는 '2B params'입니다.
downsample_mode 등을 apply_chat_template에 전달하면, 'processor_kwargs에 넣도록'이라는 경고가 발생합니다. 하지만 값은 적용되었습니다. max_slice_nums
1과 36으로 설정하니, 금문교 사진의 입력 토큰이 각각 83과 348로 바뀌었습니다(code/check_kwargs.py
로그는 outputs/check_kwargs.log입니다).
이번에는 모델 카드 작성 방식을 그대로 유지했습니다.
downsample_mode=16x max_slice_nums=1 -> 입력 83 tok
downsample_mode=16x max_slice_nums=36 -> 입력 348 tok
downsample_mode=4x max_slice_nums=1 -> 입력 275 tok
...
-
MiniCPM-V-4.7-1B는 M3 Mac에서도 메모리 약 4.4GB로 구동되었습니다. API 키도 필요 없습니다.
-
이번 선명한 일본어 영수증은 16x 모드에서 전체 내용을 정확하게 읽었습니다.
-
작고 흐릿한 이미지에서는 16x에서 오류가 발생했지만, 4x로 설정하니 수정되었습니다. 다만, 선명한 이미지에서는 4x가 역효과였습니다.
-
모두 영수증 종류별/각 1회 결과입니다. 실제로 사용할 때는 자신의 이미지로 정확도와 속도를 확인해야 합니다.
-
openbmb/MiniCPM-V-4.7-1B (모델 카드) — OpenBMB / Hugging Face
-
OpenBMB/MiniCPM-V (GitHub) — OpenBMB (News에 2026-10-12 공개로 기재)
-
MiniCPM-V 4.7 — OpenBMB
-
google-gemma/cookbook — Google (금문교 사진 apps/sample-data/GoldenGate.png 출처. Apache-2.0)
-
없음