手書き伝票のOCRで、DeepSeek V4.1 Flash と Gemini 3 Flash を同じプロンプトで比べた

未分類

手書き伝票のOCRで、DeepSeek V4.1 Flash と Gemini 3 Flash を同じプロンプトで比べた

記帳の仕事で、美容室の手書き売上伝票を Gemini に読ませて仕訳にしている。 1枚ごとに日付、施術の内容、技術売上、店販売上を取り出し、画面で直して確定する流れだ。

DeepSeek が 2026年9月に出した V4.1 Flash は画像を読める。 重みが公開されているので、NVIDIA の DGX Spark で手元に置く道もある。 顧問先の伝票を外に出さずに済むなら、それは大きい。

そこで、いま使っているプロンプトとスキーマを一切変えずに、同じ伝票を DeepSeek にも読ませて Gemini と並べた。

結論

  • 金額3項目(技術売上、店販売上、特定商品の売上)がすべて合った伝票は、78枚中 Gemini が 75枚、DeepSeek が 70枚だった
  • 日付は逆で、DeepSeek が 66枚、Gemini が 55枚
  • 日付と金額の両方が合った伝票は、DeepSeek の最良が 59枚、Gemini の最良が 55枚。総合ではほぼ互角
  • thinking(推論モード)はどちらも精度を上げなかった。所要は4倍、費用は4倍から7倍になる
  • 間違え方は書き手の癖に集中している。DeepSeek は細い「1」と「7」で、Gemini は年と月で落ちる
  • 費用は 78枚で DeepSeek が7円、Gemini が10円ほど。全量963枚でも、DeepSeek は100円弱、Gemini は130円ほど(1ドル150円で換算)

何を、どう比べたか

対象は、美容室を営む個人事業主の顧問先の伝票だ。 市販の複写式の「お客様伝票」に、オーナーが日付、来店客の名前、施術ごとの金額、技術売上の合計、店販の内訳を手書きしている。 スキャン画像は幅 767px、高さ 2,224px の縦長で、1枚 200KB 前後になる。

正解は、私が画面で1枚ずつ直して確定した値を使った。 2025年12月分の78枚を対象にした。 最新の月で、項目の定義が今のアプリと同じだからだ。

条件は次のとおり。

  • プロンプトとスキーマ:アプリが Gemini に投げているものをそのまま使う。伝票の構造の説明、特定商品を別に抜き出す指示、注意事項7つ、出力6項目のスキーマからなる。DeepSeek は厳密なスキーマ指定に対応していないので、プロンプト末尾にスキーマと出力例を貼り、JSON モードで出させた
  • 顧客名のマスク:来店客の名前の行だけを白で塗ってから送った。位置が定型なので、画像の高さに対する比率で機械的に塗れる。名前は正解データに入っていないので、評価には影響しない
  • thinking:DeepSeek は既定(有効)と無効の両方。Gemini 3 Flash は完全には切れないので、既定(high)と最小(minimal)の両方
  • temperature:既定の 1.0 と 0 の両方
  • 画像の渡し方:1枚そのまま、上下2分割、日付欄と技術欄と商品欄の3部位に切り出し、の3通り

採点は、日付を yyyy-mm-dd に正規化して完全一致、金額3項目は整数の完全一致、施術内容は空白と全角半角を揃えたうえで品目の集合一致とした。

結果

一致した枚数を並べる(78枚中)。 「金額3項目」は技術売上、店販売上、特定商品の売上がすべて合った枚数、「日付+金額」はそれに日付も合った枚数だ。

モデル画像thinkingtemp日付金額3項目日付+金額施術内容秒/枚78枚の費用
DeepSeek1枚無効1.0606549541.9$0.046
DeepSeek上下2分割無効1.0546947591.9$0.051
DeepSeek1枚有効1.0656656597.5$0.168
DeepSeek1枚無効0617054581.8$0.046
DeepSeek3部位無効0666959581.8$0.044
Gemini1枚(アプリと同一)既定1.0557454716.4$0.299
Gemini1枚最小0557555672.6$0.068
Gemini3部位最小0527551663.1$0.159

項目別に見ると、Gemini の最小設定は技術売上 76、店販売上 77、特定商品 78 で、DeepSeek の1枚・temp 0 はそれぞれ 72、76、78 だった。

費用は各社の公式単価で計算した(DeepSeek はピーク時間帯の単価、Gemini は Standard)。 実際には同じ画像の再送がキャッシュに乗るので、これより下がる。 Gemini の3部位は、画像3枚が別々にトークン化されて入力が 2.3倍になった。

間違え方が違う

数字だけ見ると互角だが、外し方はまったく違った。 誤読した伝票は実物を切り出して確かめている。

DeepSeek は、細く書かれた「1」を落とす。 13160 を 3160、12月を 2月、19日を 09日と読む。 もう1つは「7」を「2」と読む癖で、7700 を 2200 と読んだ伝票が2枚、11700 を 11200 と読んだ伝票が1枚あった。 この書き手の 7 は上の横線が長く、小さくなると 2 に見える。 最初は縮小のせいだと思ったが、違った。 画像トークン数を見ると、1枚渡しでも上下に割っても面積あたりの密度は同じで、縮小は5%ほどしかない。 細い 1 は原寸でも落ちている。

Gemini は数字の読みそのものは正確で、7 も先頭の 1 も拾う。 落ちるのは年と月だ。 日付の誤り23件のうち、年(2025 を 2015、2023、2026)か月(12 を 11、01、02)の誤りが19件で、日だけの誤りは4件しかない。 書き手の 2025 は「2」が「1」に見える形で、12 は「1」と「2」が離れて書かれている。 人間は「12月の伝票の束だから」と文脈で読むが、モデルには1枚ずつしか渡していない。

施術内容の欄は Gemini が強い。 DeepSeek は、チェックも金額も無いシャンプーやスタイリングまで列挙する。

どちらにも共通の癖があった。 特定商品の売上を、明細に無いのに作ることがある。 Gemini の既定設定で1枚、DeepSeek の thinking 有効で3枚あった。

thinking と temperature

thinking は、どちらのモデルでも金額の一致を増やさなかった。 DeepSeek は無効の 65〜70 に対して有効で 66、Gemini は最小の 75 に対して既定で 74 だった。 DeepSeek の thinking は1枚あたり 1,300 トークン前後の推論を吐き、明細の足し上げで合計を検算していた。 その割に、特定商品の売上を勝手に作る、足し間違える、JSON の前にスキーマを復唱して出力が崩れる、という副作用が出た。 Gemini の既定設定は施術内容の一致だけ上がった(71 対 67)。

temperature は 0 に固定したほうがよい。 既定の 1.0 では、同じ画像でも回すたびに結果が動き、条件の差より揺れのほうが大きかった。 1枚渡しと上下2分割の差(金額 65 と 69、日付 60 と 54)は、この揺れの範囲に見える。

DGX Spark で回すなら

DeepSeek V4.1 Flash は 重みが公開されている(MIT ライセンス)。 ただし 552B のモデルで、公式チェックポイントは 511GB ある。 DGX Spark 1台の 128GB には載らず、コミュニティの実装は 3台か4台を束ねる構成になっている。 1台で動くのは旧 V4 Flash で、こちらは画像を読めない。

そこで効くのが、thinking が要らないという今回の結果だ。 2台構成で旧 V4 Flash を動かした実測は 35〜55 tok/s で、この速度だと thinking 有効では1枚 30秒前後かかる。 無効なら数秒で終わり、963枚の全量でも1時間かからない計算になる。 3台以上なら API と同じ公式の重みが動くので、精度もそのまま持ち越せるはずだ。

注意点

  • 78枚、1か月分、書き手1人の結果である。別の月や別の書き手で同じ傾向かは確かめていない
  • Gemini はプレビュー版の名前で呼んでいる。裏のモデルが更新されても名前は変わらないので、この結果は 2026年9月18日時点のものだ
  • 費用は公式単価の机上計算で、キャッシュの効き方で変わる
  • どちらのモデルも、実務でそのまま仕訳にできる水準ではない。日付と金額の両方が合う伝票は4枚に3枚で、残りは人が直す前提になる

次にやること

年と月の誤りは、伝票の束の年月をプロンプトに渡せば大半が消えるはずだ。 Gemini の日付誤りの19件と、DeepSeek の5件がそれに当たる。 「この書き手の 7 は 2 に見える」のような癖の注記も効く可能性がある。 ただ、これは既存アプリと同じプロンプトという今回の前提から外れるので、別の回に分ける。

ベンチのスクリプトは、画像の加工、2社への送信、採点、条件の横並びまでを1本にした。 同じ形で別の月を回せば、傾向の再現を確かめられる。

#AI#OCR#DeepSeek#Gemini#記帳#DGX Spark