注意
「Mistral-Small-3.1-24B-Instruct-2503」と「gemma-3-27b-it」は自身のPC環境の制限のため4bit量子化して使用しています。本来はもう少し性能が高いと思いますので今回の結果は参考程度に見て下さい。パラメーターの設定も詰め切れてないと思います。お題①

Mistral-Small-3.1-24B-Instruct-2503
この画像から抽出されたテキストは以下の通りです: --- **警察が捜査しました。** 当院は、安心・信頼の医療の提供を指針としております。 暴力・脅迫・迷惑行為はお断りします!! これからは厳正に対処します。 --- このテキストは、医療機関が暴力や脅迫、迷惑行為に対して厳正に対処する旨を伝えるポスターのようです。
gemma-3-27b-it
画像から以下のテキストを抽出しました。 **警察OBが 巡回しています** 当院は、安全・安心な医療の提供を目指しております **暴力・暴言・迷惑行為は お断りします!!** これらの行為は 厳正に対処します
EasyOCR
警察のが 巡回しでいます 当院は 安全・安心な医療の 提供を目指しております 暴力 ・ 暴言 ・ 迷惑行為は お断りします ! ! これらの行為は 厳正に対処します
お題②

Mistral-Small-3.1-24B-Instruct-2503
以下は画像から抽出されたテキストです。 --- **条項6** ドライバーがネジを締めて、M.2 SSDカードを所定の位置に固定します。M.2 SSDカードを損傷する可能性があるため、ネジを締めすぎないようにしてください。M.2 SSDカードがタイプ2280の場合、手順6をスキップしてください。
gemma-3-27b-it
画像からテキストを抽出しました。以下に示します。 **手順6** ドライバーでネジを締め、M.2 SSDカードを所定の位置に固定します。 M.2 SSDカードを損傷する可能性があるため、ネジを締めすぎないようにしてください。 M.2 SSDカードがタイプ2280の場合は、手順6をスキップしてください。
EasyOCR
手順6 ドライバーでネジを締めて MZSSD カードを所定の位置に固定します ML2SSDカードを損傷する可能性が あるため ネジを締めすぎないように してください。 M.2 SSD カードがタイプ2280 の場合 は 手順6をスキップしてください。
お題③

Mistral-Small-3.1-24B-Instruct-2503
この画像は、書籍の表紙です。以下にテキストを抽出します。 --- **ChatGPT/LangChainによるチャットシステム構築実践入門** **吉田真吾、大嶋秀樹** --- **大規模言語モデルを本番システムで活用するための基礎知識と実践ハンド** --- **OpenAI API(ChatCompletions API)の利用** **LLMのプロンプトエンジニアリングを理解し、LangChainの機能、詳細な説明** **ソースコードをデプロイするためのSlackChatアプリ** **本書の著者が実際に経験した課題と解決策** --- **エンタープライズ** --- この書籍は、ChatGPTやLangChainを用いたチャットシステムの構築に関する実践的なガイドです。大規模言語モデルを本番システムで活用するための基礎知識や実践的なハンドブックを提供しています。
gemma-3-27b-it
画像から以下のテキストを抽出しました。 **表紙のタイトル:** * ChatGPT / LangChain による チャットシステム構築[実践]入門 **著者:** * 吉田英吾、大嶋勇樹 (著) **キャッチコピー:** * 本規模言語モデルを本番システムで活用するための基礎知識と実践的ハンズオン **内容:** * OpenAI API (Chat Completions API) の活用 * LLMを 待ったアプリ開発を支える LangChain の基本と実践的解説 * ソースコードで学んで今日から使える Slack チャットアプリ * すべてクラウドに役立つ実例
EasyOCR
ChatGPTI Langchain による チャットシステム構築[実銭 入門 吉田や 大.田樹衛 ChatGPT 大規模言語モデルを本番システムで活用する ための基礁知識と実銭的ハンズオン ・r『nal nttnhnon'nlsmn 山ド川= 川itっr ・つリy… iblonochiinniさと 4e 「いこrーピ ー・フー‥こ・う-川 == …り- トバー川 一沼言 aリ川ー -こりう …川 ーーエ・ーウト川 にl川 だにン江
結果
今回の結果は「gemma-3-27b-it」の圧勝です。Pythonスクリプト
Mistral-Small-3.1-24B-Instruct-2503
from transformers import BitsAndBytesConfig, AutoProcessor, AutoModelForImageTextToText, TextIteratorStreamer import torch import gradio as gr from threading import Thread model_checkpoint = "mistralai/Mistral-Small-3.1-24B-Instruct-2503" quantization_config = BitsAndBytesConfig(load_in_4bit=True) model = AutoModelForImageTextToText.from_pretrained( model_checkpoint, torch_dtype=torch.bfloat16, device_map="cuda", quantization_config=quantization_config ) processor = AutoProcessor.from_pretrained(model_checkpoint) streamer = TextIteratorStreamer( processor, skip_prompt=True, skip_special_tokens=True ) def extract_text(filepath: str): messages = [ { "role": "user", "content": [ {"type": "image", "url": filepath}, {"type": "text", "text": "この画像からテキストを抽出して下さい"}, ], } ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt" ).to(model.device, dtype=torch.bfloat16) generation_kwargs = dict( **inputs, streamer=streamer, max_new_tokens=1024, do_sample=True, temperature=0.15, pad_token_id=2 ) thread = Thread(target=model.generate, kwargs=generation_kwargs) thread.start() result = "" for new_text in streamer: result += new_text yield result with gr.Blocks() as demo: gr.Interface( fn=extract_text, inputs=gr.Image(type="filepath"), outputs=gr.Textbox(lines=10, max_lines=40, show_copy_button=True), flagging_mode="never" ) demo.launch()
gemma-3-27b-it
from transformers import BitsAndBytesConfig, AutoProcessor, Gemma3ForConditionalGeneration, TextIteratorStreamer import torch import gradio as gr from threading import Thread model_checkpoint = "google/gemma-3-27b-it" quantization_config = BitsAndBytesConfig(load_in_4bit=True) model = Gemma3ForConditionalGeneration.from_pretrained( model_checkpoint, torch_dtype=torch.bfloat16, device_map="cuda", quantization_config=quantization_config ) processor = AutoProcessor.from_pretrained(model_checkpoint, use_fast=True) streamer = TextIteratorStreamer( processor, skip_prompt=True, skip_special_tokens=True ) def extract_text(filepath: str): messages = [ { "role": "system", "content": [{"type": "text", "text": "あなたは優秀で誠実なAIアシスタントです。"}] }, { "role": "user", "content": [ {"type": "image", "image": filepath}, {"type": "text", "text": "この画像からテキストを抽出して下さい"}, ], } ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt" ).to(model.device, dtype=torch.bfloat16) generation_kwargs = dict( **inputs, streamer=streamer, max_new_tokens=1024, do_sample=True, top_k=64, top_p=0.95, temperature=0.15 ) thread = Thread(target=model.generate, kwargs=generation_kwargs) thread.start() result = "" for new_text in streamer: result += new_text yield result with gr.Blocks() as demo: gr.Interface( fn=extract_text, inputs=gr.Image(type="filepath"), outputs=gr.Textbox(lines=10, max_lines=40, show_copy_button=True), flagging_mode="never" ) demo.launch()
EasyOCR
from PIL import ImageDraw import easyocr import numpy as np import gradio as gr reader = easyocr.Reader(['ja','en']) def ocr(img): result = reader.readtext(np.array(img)) draw = ImageDraw.Draw(img) result_text = [] for each_result in result: draw.rectangle(tuple(each_result[0][0] + each_result[0][2]), outline=(0, 0, 255), width=3) result_text.append(each_result[1]) return [img, "\n".join(result_text)] with gr.Blocks() as demo: gr.Interface( fn=ocr, inputs=gr.Image(type="pil"), outputs=["image", gr.Textbox(lines=10, max_lines=40, show_copy_button=True)], flagging_mode="never" ) demo.launch()