OCR vs VLM 底層原理與報支管線:LLM 怎麼看圖、為何贏 OCR

一句話心法
OCR 是「CNN 眼睛 + CTC 近視解碼器」的接力管線;VLM 是「ViT 眼睛 + 會推理的 LLM 大腦」的單一模型。VLM 贏過 OCR 不是因為眼睛更好,而是眼睛後面接了一顆會「用語言常識補視覺缺口」的腦——這也正是它會幻覺的原因。實戰上報支這種「多種票據混在一起」的場景,答案是兩階段混合管線:VLM 當第一層分類定位,電子發票 QR 直接解碼(零幻覺),其餘走 grounded OCR。

這篇把「OCR 跟 VLM 到底差在哪」從底層 encode/decode 機制一路講到怎麼設計一條報支(費用核銷)辨識管線。內容是我一連串追問逐步逼出來的:LLM 明明是語言模型,它到底怎麼「看」圖?圖被切成 token 的單位是什麼?為什麼它會比專用 OCR 強?邊界又在哪?最後收斂到一個具體、正確的混合式架構,並附上 grounded OCR 的正式論文出處與兩張 UML/架構圖。

🧭 本文導覽
Part 一 — 兩者是不同「類別」的東西
Part 二 — LLM 到底怎麼「看」圖
Part 三 — 為什麼 VLM 會贏過 OCR
Part 四 — 能力邊界與 QR code 死穴
Part 五 — 實戰:報支管線與 grounded OCR
Part 六 — 附錄
Part 一 — 兩者是不同「類別」的東西

1. 不是「誰比較準」,是兩個不同類別

傳統 OCR 是「多個獨立小模型接力」的管線,最後只吐字串;現代 VLM 是「一顆模型從頭到尾」,把版面、文字、結構、語意一次生成出來。差異不是「誰比較準」,而是架構類別根本不同——一個是分類/序列辨識問題,一個是「看圖說話(自回歸生成)」問題。理解了這個分水嶺,後面所有能力差異、失效模式都能推導出來。

2. 傳統 OCR 的 encode/decode:CNN + CTC 接力管線

傳統 OCR(學術上叫 OCR-1.0)的資料流是一條接力線:

  • 編碼(encode):CNN 把字元影像抽成特徵序列。
  • 解碼(decode):用 CTC decoder(Connectionist Temporal Classification)。CTC 是「逐格對齊字元」的機制,它只認局部視覺 pattern → 字元的對應,完全不理解語意
  • 致命結構問題:偵測、辨識、版面各自是獨立模型,前段錯誤會往下游累積放大(error compound)。偵測框歪了,辨識再強也沒用。

例如 Tesseract 4/5 用的就是 CNN + BiLSTM(CRNN) → CTC decoder。它便宜、快、座標精準,但它「只會認,不懂讀」。

3. 現代 VLM 的 encode/decode:ViT → 投影 → LLM 自回歸

現代 VLM(對應 OCR-2.0)的路徑完全不同:

  • 編碼:圖片切成不重疊的 patch(通常 14×14 像素),每塊過 ViT 視覺編碼器變成一個 visual token。
  • 橋接(關鍵一步):visual token 不是直接餵進 LLM,中間有個投影模組把它「翻譯」成 LLM 聽得懂的 embedding。Qwen 系 / InternVL 用 MLP 把相鄰 2×2 patch 壓成一個 token;較早的 BLIP-2 系用 Q-Former 壓成固定數量。
  • 解碼:visual token 與文字 token 串接成一串,由 LLM decoder 自回歸生成——就是「一個 token 一個 token 地說出來」,跟 ChatGPT 產文字同一個機制。所以它能吐 HTML、Markdown、LaTeX、座標,因為對它來說這些都只是「要生成的文字」。
⭐ 架構分水嶺:解析度處理
VLM 能讀文件細字的關鍵是 Naive Dynamic Resolution(原生動態解析度):用原生解析度處理任意大小圖片、動態產生可變數量 token。Qwen2.5-VL 還用 window attention 把成本從 patch 數的平方降到線性。相對地,早期 Q-Former 把圖壓成固定 token 數——Jina 的視覺編碼器 survey 明講這「會丟棄文件理解與視覺 grounding 所需的細節」。這就是為什麼現代主流都改用 MLP + 原生解析度,放棄 Q-Former。

下面這張圖把兩條管線並排:左邊紅色是 OCR 的接力線(前錯後崩),右邊綠色是 VLM 的單一模型端到端。注意兩者的「眼睛」(CNN vs ViT)其實半斤八兩,真正的差別在眼睛後面接了什麼。

OCR 與 VLM 的 encode/decode 管線對照圖:左為傳統 OCR 的 CNN+CTC 接力管線,右為現代 VLM 的 ViT patch → 投影 → LLM 自回歸端到端流程
傳統 OCR(左)vs 現代 VLM(右)的 encode/decode 拆解。眼睛一樣,大腦不同。
Part 二 — LLM 到底怎麼「看」圖

4. 誤解一:LLM 是把像素直接吃進去嗎?

不是。這是關鍵。LLM 從頭到尾沒有看過一個 RGB 像素。它收到的不是圖,是一串「已經被翻譯成它聽得懂的外語單字」的向量

打個精準的比喻:ViT 是一個翻譯官。它看著圖片,把每一小塊 patch 翻成一個「詞」,這些詞跟真正的文字單字活在同一個座標系(embedding space)裡。所以對 LLM 來說,一張發票圖 = 一句用「視覺語」寫的話。LLM 讀這句話,跟它讀中文英文,是同一個動作。它分不出、也不在乎哪些 token 來自鍵盤、哪些來自圖——反正都是同一個空間裡的向量。

5. 誤解二:VLM 訓練資料裡沒有圖片?

這個要直接更正:VLM 的訓練裡有大量圖片,而且訓練的目標函數跟純文字 LLM 一模一樣——「預測下一個 token」。差別只在輸入序列的組成:圖片被 ViT 翻成 visual token 塞進序列後,模型照樣做「看前文、猜下一個」。

階段 餵什麼 訓練誰 學到什麼
① LLM 預訓練 純文字(幾兆 token) LLM 骨幹 語言、常識、推理
② 多模態對齊 大量「圖片–文字」配對 ViT + 投影層 讓「視覺語」對齊到「文字語」

所以「圖片沒被訓練」是錯的——圖片全部集中在第②階段被訓練。這階段就是在教翻譯官:「這塊像素長這樣 → 對應到『2』這個字的向量」。而你觀察到的「它會像 CNN 一樣咬住字」——那個 CNN 的動作沒有消失,它搬到 ViT 裡面去了。ViT 用 self-attention 取代卷積,但功能一樣:學出來的視覺特徵抽取器。

6. 圖 token 的單位是什麼?區塊,不是逐字預測

先拆掉一個誤解:圖 token 從來不會被「預測下一個」。自回歸(預測下一個)只發生在「輸出的文字」那一側。圖片是「一次全部塞進去」的。

一個圖 token 的單位是:一個固定大小的方形區塊(patch),被壓成一個向量。以 Qwen 系為例,patch 是 14×14 像素,再把相鄰 2×2 合併,所以一個圖 token 大約是一塊 28×28 像素的方形區域 → 一個向量(比如 3584 維)。它不是一個字、不是一個像素。一張圖被切成一整片 patch 網格(例如 24×24 = 576 個 token)。

那「圖是 2D 的,一個區塊要連同上下左右」怎麼辦?這件事靠兩個機制解決,不靠排列順序:

  1. 位置編碼(positional embedding):每個圖 token 身上都貼了標籤說「我是第 3 排第 5 格」。就算被攤平成一串,模型還是知道每塊在 2D 的原始座標。
  2. 全對全 self-attention:ViT 裡每一個 patch 都能同時看到所有其他 patch——上下左右一次全看。所以「這格跟上下排的關係」是靠 attention 算出來的,不是靠排隊順序。

換句話說:文字 token 是「一條線」,圖 token 是「一張攤平但保留了座標的網格」。攤平只是為了塞進序列,2D 關係完全沒丟。這就是為什麼 ViT 能理解「表格的這一格屬於哪一欄哪一列」。

Part 三 — 為什麼 VLM 會贏過 OCR

7. 眼睛一樣、大腦不同:VLM 會「連猜帶讀」

現在有了前面的鋪陳,這題就有答案了。差別在眼睛後面接了什麼:OCR 的 CNN 眼睛後面接 CTC(一個近視、只認單字、不懂語意的機器);VLM 的 ViT 眼睛後面接 LLM(一個懂語言、懂上下文、會推理的大腦)。

同一雙眼睛看到一個糊掉的字,兩者反應天差地別:

  • OCR 的 CTC:孤立地看那一格像素,「這團 pattern 最像哪個字?」→ 糊了就猜錯,而且它不知道自己錯,因為它根本沒有「這句話該是什麼」的概念。
  • VLM 的 LLM:看到糊字,但它同時知道「這是一張發票、這個位置是日期欄、旁邊寫著 2026 年 8 月」→ 它用語言先驗把糊掉的字推回來。

這就是質變:OCR 做的是「辨識」,VLM 做的是「辨識 + 理解 + 推理」融在一起。它不只在「看」,它在「讀懂」。加上端到端、沒有接力斷點,VLM 因此能一次吐出帶座標的結構化輸出(Qwen2.5-VL 直接產出每個元素都帶 data-bbox='x1 y1 x2 y2' 的 HTML,涵蓋段落、表格、公式、樂譜、化學式)。這在傳統 OCR 需要版面分析、文字抽取、圖表解讀三個獨立模型。

OCR-2.0 專用模型正是這種統一 VLM。以 dots.ocr 為例,它靠改 prompt(不是換模型)就能在版面偵測、閱讀順序、文字/表格/公式辨識之間切換:

# 同一顆 dots.ocr 模型,換 prompt 就換任務 —— 不用重訓、不用換模型
prompt_layout_only     # 只做版面偵測(輸出各區塊 bbox)
prompt_ocr             # 讀出全文
prompt_grounding_ocr   # 讀出文字 + 每個元素的座標框(grounded OCR)

# 對照:傳統 OCR 要「偵測模型 + 辨識模型 + 版面模型」三個各自跑,前錯後崩

8. 雙面刃:幻覺與失效模式

但「連猜帶讀」是雙面刃。NeurIPS 2025《Seeing is Believing?》確認:當視覺輸入退化(模糊/遮擋/低對比)時,VLM 會「退回語言先驗」、不再錨定實際看到的像素,產生圖中根本不存在的值或誤讀。它是「說話」機制,寧可掰一個通順的也不留白。

看不清楚一個字時 傳統 OCR VLM
失敗的樣子 吐錯字 / 空白 / 亂碼 → 你一眼看得出它掛了 腦補一個通順但錯誤的答案 → 你看不出它在唬爛
內部信心 有 per-char confidence,相對可信 對幻覺輸出照樣給高信心,不可靠
結構化內容(圖表/表格) 擾動下最脆弱(保留率 0.826→0.676)

還有一個反直覺的發現(OCR-Robust benchmark):乾淨影像上準確率越高,不代表抗擾動越強——thinking-mode 模型 clean 準確率最高,但結構化內容 WCR 低到 0.579。結論:在報稅、報支這種審計敏感場景,abstention(不確定就拒答/轉人工)常常優於硬吐一個轉錄結果

Part 四 — 能力邊界與 QR code 死穴

9. VLM 也有「圖片解析」問題:解析度天花板

OCR 有一堆低階視覺前處理的坑(去斜、二值化、去噪、對比增強),VLM 大幅吃掉這些問題——因為 ViT 在幾億張真實照片上練過,天生見過歪的、暗的、有陰影的。你不用前處理,它照樣讀。這是 VLM 體感「比較神」的一大來源。

但 VLM 有它自己的圖片解析問題,而且比 OCR 更陰險——解析度天花板:

  • 字太小(相對於輸入解析度),一個字可能不到一個 patch、或跨在 patch 邊界 → ViT 物理上「看不到」細節,翻出來的 token 就是糊的。
  • 文件太大太密(整頁報表、A3 圖紙)→ patch 數暴增 → token 太多 → 系統自動 downscale 縮圖 → 小字直接糊掉。
  • 動態解析度拉高了天花板,但天花板還是存在。

實務對應:VLM 讀不好時,第一個動作是「提高輸入解析度、別讓它 downscale」,而不是換模型。很多人以為模型爛,其實是圖被縮掉了。密集小字報表,有時切塊分次餵比整張塞更準。

10. QR code / 條碼:VLM 認得出、但別讓它解碼

這是本節最該帶走的一條:VLM 認得出「這是一個 QR code」,但它幾乎無法「正確解碼」QR code。

原因是機制上的死穴:QR code 不是「視覺語意」,它是一個精密的二進位矩陣,解碼需要逐 bit 讀取 + Reed–Solomon 錯誤更正演算法。而 ViT 會 downsample、會壓 patch,那些細密黑白格的精確 bit 早就糊掉了;LLM 腦子裡也沒有 Reed–Solomon 可以跑。結果就是最危險的失效——它不會說「我解不出來」,它會腦補一個「看起來很合理的網址」給你。條碼、極密的數字矩陣也一樣。

內容 交給誰 為什麼
QR code / 條碼 專用解碼器(zxing / pyzbar) 要跑精確演算法,VLM 會腦補
車牌 / 手寫 / 印刷文字 VLM(或專用 OCR) 需要「理解 + 容錯」,VLM 強
一張圖混了以上全部 VLM 先分類定位 → 各自派給對的工具 這就是混合式管線的價值
Part 五 — 實戰:報支管線與 grounded OCR

11. 正名:什麼是 grounded OCR / visual grounding

先做一個誠實的正名。口語常說的「grounding OCR」不是最精準的用語,正規的學術詞是:

  • Visual Grounding:把自然語言描述對應到視覺輸入裡的特定區域(給出 bounding box)。
  • Grounded OCR / Visual Text Grounding:系統不只讀出文字,還告訴你這些字在圖上的哪裡(座標框)。也就是「reading + detection + grounding 統一在一個 prompt 介面」。

最貼近「報支第一層」設計的論文是 GutenOCR: A Grounded Vision-Language Front-End for Documents(arXiv 2601.14490)。它基於 Qwen2.5-VL 微調,論文原話是把「reading, detection, and grounding 透過單一 prompt 介面暴露出來」,支援 line/paragraph 級 bounding box,並能回答「where is x?」這種定位查詢——這就是你要的「第一層告訴我這是什麼、在哪」

兩個相關但不同的概念,別混:
Grounded OCR / visual grounding = 單模型能力(VLM 一次吐出文字 + 座標)。
② 而「VLM 當前端分類定位 → crop → 派給專用工具」的整套路由架構,更精準的名字是 hybrid / coarse-to-fine 兩階段文件解析管線(MinerU2.5、PaddleOCR-VL、GutenOCR 都屬此型)。你設計的報支流程 = ① 當前端 + ② 當骨架。

12. 報支:第一層分類器決定成敗

報支的圖是異質的:電子發票、三聯式發票、收銀機發票、手開收據、計程車收據、停車費、高鐵/台鐵票、國外 receipt 混在一起。所以架構是清楚的兩層:第一層分類 + 定位(VLM),第二層分型抽取(各派各的工具)。

⚠️ 命脈:第一層分類錯 → 整條全錯(error compound 又出現,只是搬到管線第一關)。如果把「三聯式發票」誤判成「收據」,後面全部走錯路。所以第一層必須能「不確定就標人工」——這就是前面講的 abstention。報支牽涉金額與報稅,寧可讓它舉手,不要它自信地分錯類。

建議的第一步(花不到一天):先證明第一層分類到底準不準,這是整個架構唯一的地基。

  1. 撈 20–30 張真實票據,涵蓋你會遇到的各種類型。
  2. 每張只問 VLM 一個問題:「這是哪一類票據?」(先只做分類,不做抽取)。
  3. 算分類正確率,看它分錯時哪幾類容易混(例如收銀機發票 vs 手開收據)。
  4. 測它「不確定時會不會舉手」,還是硬分。

13. 台灣電子發票的隱藏王牌:QR 本身就是結構化資料

這是台灣報支場景最該帶走的一點,很多人不知道:台灣「電子發票證明聯」上的兩個 QR code,裡面直接編碼了發票的結構化資料——發票號碼、開立日期、隨機碼、銷售額、稅額、總金額、買賣方統一編號,甚至品項。

意思是:對電子發票,你根本不需要「讀」上面的字。直接解碼那兩個 QR,就拿到 ground-truth 的金額/統編/發票號碼。這是零幻覺的——因為你不是用 VLM「看」金額(會腦補),你是把 QR 裡編碼好的精確數字解碼出來,比讀印刷字可靠一個檔次。前面說「QR 交給專用解碼器」在這裡不是限制,反而是你最強的資料來源。

# 第二層:電子發票分支 —— 讀 QR 而不是「看」字
from pyzbar.pyzbar import decode
from PIL import Image

def extract_einvoice(img, qr_bbox):
    x1, y1, x2, y2 = qr_bbox                 # VLM 第一層給的座標
    pad = int((x2 - x1) * 0.12)              # 留 padding:VLM 座標不 pixel-perfect
    crop = img.crop((x1-pad, y1-pad, x2+pad, y2+pad))
    codes = decode(crop)                     # Reed-Solomon 精確解碼,零幻覺
    if not codes:
        return {"status": "abstain", "reason": "QR 讀不到 → 轉人工"}
    # 財政部規格:發票號碼/日期/隨機碼/金額/統編… 直接在字串裡
    return parse_mof_einvoice(codes[0].data.decode())

(QR 裡確切的欄位順序/格式是財政部規格,實作時去對一份最新的「電子發票證明聯 QR code 規格」文件確認欄位排列。)

14. 兩階段混合管線(UML 循序圖)

把整套組起來就是下面這張 UML 循序圖:VLM 前端(grounded OCR)當第一層分類定位 → Router 依類型分派 → 電子發票走 QR 解碼(零幻覺)、文字/表格走 VLM/OCR 抽取(附信心分數)→ 低信心欄位進人工複核閘 → 高信心直接寫入結構化結果。VLM 在這裡當的是「看懂整張圖、分派工作的大腦」,而不是每件事都自己硬幹。

報支辨識管線的 UML 循序圖:VLM 前端 grounded OCR 分類定位 → Router 分派器 → QR 解碼器 / VLM-OCR 抽取器 → 人工複核閘 → 結構化結果
報支兩階段混合管線的 UML 循序圖。第一層分類定位、第二層依類型分派,低信心走人工複核。
Part 六 — 附錄

15. Benchmark、延伸閱讀與論文出處

2025–2026 的評測趨勢是分項能力對照:OmniDocBench(CVPR 2025)把文件解析拆成文字辨識、表格結構(TEDS)、公式(CDM)、版面偵測、閱讀順序五個子任務,可逐能力比較 OCR vs VLM。OCRBench v2(NeurIPS 2025)雙語、任務數是舊版 4 倍。融合方向是「輕量偵測 + VLM 辨識」的混合架構,加上幾何探針 / abstention 控制幻覺。

時效性提醒:VLM 領域迭代極快,文中 Qwen2-VL 的 DocVQA 96.5 / OCRBench 877 是 2024/9 的歷史 SoTA,已被後續版本超越,只能當里程碑不能當現況。部分引用的 preprint 尚未同儕審查(NeurIPS 2025《Seeing is Believing?》與 OmniDocBench CVPR 2025 為 peer-reviewed 例外)。PP-OCRv6「小模型超越十億級 VLM」的結果來自供應商 in-house benchmark,數字正確但「碾壓感」需打折,限縮於純 OCR 任務。
  • 架構:Qwen2.5-VL(arXiv 2502.13923)、Qwen2-VL(2409.12191)、GOT-OCR2.0(2409.01704)、dots.ocr(HF: rednote-hilab/dots.ocr)、Jina Vision Encoder Survey。
  • Grounded OCR / grounding:GutenOCR(2601.14490)、TextHawk2(2410.05261)、Towards Visual Text Grounding of MLLM(2504.04974)、MMDocBench(2410.21311)、Survey on MLLM-based Visually Rich Document Understanding(2507.09861)。
  • Benchmark:OmniDocBench(CVPR 2025)、OCRBench v2(NeurIPS 2025)。
  • 失效模式 / 邊界:Seeing is Believing?(NeurIPS 2025)、OCR-Robust(2606.26041)、PP-OCRv6 技術報告(2606.13108)。

留言

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *