プロジェクトの背景
VAONは、製品ラベルの撮影画像からテキストと識別番号(シリアル番号、IMEI、部品番号、型番)を抽出するOCRマイクロサービスを構築しました。最も難しい要件は、きれいなスキャン画像での精度ではなく、実際のカメラ画像をCPUのみで処理することでした。検証結果は、英語で信頼度0.997、日本語で0.999、いずれも完全一致。GPUを使わない132MBのモデル構成で達成しています。
課題
入力はきれいなスキャンではなく、実際の撮影画像である
ラベルは実運用の条件下でカメラ撮影されます。傾き、ぼけ、不均一な照明、雑然とした背景を伴います。印刷物で高いスコアを出すエンジンでも、この種の画像では機能しないことがあります。したがって評価用データは、レンダリングされた文字列ではなく撮影画像である必要がありました。
既定エンジンはベトナム語の声調記号を完全に脱落させる
ản phẩm Việt Nam に対し、既定エンジンは Sn phm Vit Nam を返します。精度の低下ではなく、記号が完全に失われる状態です。英語・中国語・日本語では同様の問題は発生しません。これは特定言語に限定された不具合であり、全体のパラメータ調整では解決できません。
インフラ費用を抑えるため、CPU専用で動作させる必要がある
GPUに依存しないことは、当初からの制約条件でした。この制約により大半の大規模OCRモデルが選択肢から外れ、精度だけでなくモデルサイズを軸にした選定が必要になります。すべての候補は同一のCPU条件下で測定しました。
識別番号はラベル上に散在しており、文字を読めるだけでは不十分
1枚のラベルには複数の数値群が含まれます。文字を正しく認識するだけでは課題は解決しません。どの数値群がシリアル番号で、どれが部品番号かを判別し、ラベルと隣接する値を正しく結びつける必要があります。これは文字認識ではなく、構造の問題です。
VAONのソリューション
1つのパイプラインに統合するのではなく、完全に独立した2つのOCRエンドポイントに分離しました。クライアントは単一の処理系に縛られず、言語要件に応じてエンジンを選択できます。
既定エンジンにはPP-OCRv6_mediumを採用しました。中国語・英語・日本語・ラテン文字を単一の132MBモデル内でカバーでき、追加学習なしで実機テストにより検証済みであるためです。
ベトナム語の声調記号用にVietOCRを副エンジンとして追加し、VIETOCR_ENABLED フラグで切り替える構成とし、既定は無効としました。既定エンジン自体を置き換えなかった理由は、VietOCRが約623MBと主エンジンの約5倍の容量を要するためです。この費用は、ベトナム語の実需がある場合にのみ支払うべきと判断しました。
識別番号の抽出層は両系統で共通化し、ルールベースで実装しました。正規表現によるラベル照合、空間的な最近傍による関連付け、IMEI向けのLuhnチェックサムを組み合わせています。専用モデルではなくルールを選んだのは、結果が透明で、手順ごとに監査可能だからです。
エンジンごとに独立した同時実行制御(asyncio.Semaphore と threading.Lock)を設け、負荷時に2つのエンジンが互いのリソースを奪い合わない構成としました。
ミドルウェア層で入力を制限しました。アップロード容量の上限、解凍爆弾対策としての25メガピクセル上限、CVE-2023-4863に対応するための pillow==12.3.0 の固定、ダウンロードした重みファイルのSHA256検証を実施しています。
提供価値
英語・日本語で完全一致、信頼度0.997〜0.999
文字列 S/N: ABC123456 は信頼度0.997を記録しました。日本語の文字列 日本語のテスト製品番号123 は0.999です。いずれも既定エンジンにより、言語ごとの設定なしで完全に正しく読み取れました。
ベトナム語の声調記号:完全な誤りから完全一致へ
既定エンジンが Sn phm Vit Nam と返した同一の文字列を、VietOCRは信頼度0.913で正しく読み取ります。問題を1言語に切り分け、必要時のみ有効化するエンジンで解決しました。システム全体で精度を引き換えにする方法は取っていません。
132MB、GPU不要
既定のモデル構成は検出59MBと認識73MBで、すべてCPU上で動作します。録画したデモでは、識別番号の読み取り1回が1,800msで完了しました。したがってインフラはGPUインスタンスではなく、汎用マシンで構成できます。
監査可能な識別番号抽出
抽出をモデルではなくルールで実装しているため、各識別番号は一致したルールまで遡れます。どのラベルか、どの位置か、Luhnチェックサムを通過したか、が特定できます。結果が誤っていた場合も、再学習を要さず原因を即座に特定できます。
54件の自動テストと、公開された制約事項
本サービスは42件のユニットテストと、実モデルに対する12件の結合テストを備え、2つの実行系統に分離しています。開発中、新規ルートにアップロード容量制限が適用されていないことが判明し、リリース前に修正しました。現在、11MBのアップロードは設計どおり413を返します。