技術 約14分で読めます

ローカルVision LLMでキャラ画像からRPGパラメータを抽出できるか試した

いけさん目次

写真をドット絵に変換して、RPGの戦闘シーン風の画像を自動合成するパイプラインを組みたくなった。最終的にはカメラ撮影→ドット絵化→パラメータ生成→戦闘シーン合成→プリントまで一気通貫で回す構想だが、まずは中間処理から固める。

ドット絵への変換はQwen Image Editでできることがわかっている。問題は「画像を見てRPGのステータスを返す」ステップで、ここはVision LLM(VLM)の仕事になる。どのモデルがローカルで実用的に使えるか、実際に試して決める。

やること

キャラクター画像をローカルのVision LLMに渡して、以下のようなJSON形式でRPGパラメータを返せるかテストする。

{
  "name": "キャラ名",
  "class": "職業",
  "level": 23,
  "hp": 180,
  "mp": 45,
  "attack": 72,
  "defense": 58,
  "speed": 41,
  "special": ["とくぎ1", "とくぎ2"],
  "description": "短い説明"
}

画像の見た目(服装、表情、ポーズ、雰囲気)からそれっぽいパラメータを「でっちあげて」もらう。正解はないので、出力の面白さ・一貫性・JSON形式の安定性を比較する。

テスト環境

  • M1 Max 64GB
  • Ollama 0.17.7(Gemma 4テスト時に0.20.6へアップデート)
  • macOS

テスト画像

4種類の画像を使う。同じキャラクターだが、画風と等身が異なる。

画像1: 全身イラスト画像2: ドット絵・等身高め画像3: ドット絵・等身低め画像4: ドット絵・2等身
全身イラストドット絵・等身高めドット絵・等身低めドット絵・2等身
制服+悪魔の翼、月背景透過背景透過背景ベージュ背景

VLMが画風の違いをどう解釈するか、ドット絵からでもパラメータを生成できるかが見どころ。

共通プロンプト

各モデルに同じプロンプトを渡す。OllamaのAPIに画像をbase64で添付し、stream: falseで一括レスポンスを取得する。

この画像のキャラクターを見て、ドラクエ風のRPGステータスをJSON形式で生成してください。
画像の見た目から想像して、それっぽいパラメータをでっちあげてください。
JSON以外のテキストは不要です。
{"name": "キャラ名", "class": "職業", "level": 数値, "hp": 数値,
 "mp": 数値, "attack": 数値, "defense": 数値, "speed": 数値,
 "special": ["とくぎ1", "とくぎ2", "とくぎ3"],
 "description": "短い説明"}

呼び出しはPythonスクリプトで統一した。

import json, base64, urllib.request

def generate_rpg_params(model, image_path):
    with open(image_path, 'rb') as f:
        img = base64.b64encode(f.read()).decode()
    payload = json.dumps({
        'model': model,
        'prompt': PROMPT,  # 上記のプロンプト
        'images': [img],
        'stream': False
    }).encode()
    req = urllib.request.Request(
        'http://localhost:11434/api/generate',
        data=payload,
        headers={'Content-Type': 'application/json'}
    )
    with urllib.request.urlopen(req, timeout=300) as resp:
        return json.loads(resp.read())

テスト結果

Gemma 3 4B

モデル: gemma3:4b(3.3GB)

画像1: 全身イラスト(8.2秒)

{
  "name": "ルナ",
  "class": "妖精戦士",
  "level": 5,
  "hp": 120,
  "mp": 150,
  "attack": 30,
  "defense": 25,
  "speed": 60,
  "special": ["星光魔法", "月影舞", "妖精の囁き"],
  "description": "夜空を舞う妖精。素早い動きと魔法で敵を翻弄する。"
}

画像2: ドット絵・等身高め(5.5秒)

{
  "name": "ユイ",
  "class": "学園娘",
  "level": 5,
  "hp": 80,
  "mp": 120,
  "attack": 15,
  "defense": 10,
  "speed": 20,
  "special": ["バブル", "イタズラ", "癒し"],
  "description": "学校帰りの元気な少女。友達を大切にする優しい性格。"
}

画像3: ドット絵・等身低め(5.2秒)

{
  "name": "アリス",
  "class": "プリキュア",
  "level": 5,
  "hp": 120,
  "mp": 80,
  "attack": 45,
  "defense": 30,
  "speed": 60,
  "special": ["ホイッスル", "フレッシュ", "スター"],
  "description": "元気いっぱいの少女。仲間を守るためなら、どんな困難にも立ち向かう。"
}

画像4: ドット絵・2等身(5.3秒)

{
  "name": "ルナ",
  "class": "魔法使い",
  "level": 5,
  "hp": 80,
  "mp": 150,
  "attack": 30,
  "defense": 20,
  "speed": 60,
  "special": ["メラファイア", "メラアイス", "メラホオオ"],
  "description": "クールで少し大人びた魔法使い。普段は落ち着いているが、戦闘では強力な魔法を繰り出す。"
}

所見

  • JSON形式は4枚とも安定して正しい形式で返ってきた
  • 全画像でlevel 5固定。数値の振れ幅が小さい
  • 翼と月の背景を認識して「妖精戦士」「月影舞」を出したのは良い
  • 「プリキュア」が職業として出てくるのはドラクエ感がない
  • 「メラホオオ」など実在しない呪文を捏造する傾向あり(ドラクエを知らないわけではなさそうだが、再現精度は低い)
  • ドット絵でも画像認識自体は問題なく動作する
  • 推論速度は5〜8秒と高速

Qwen2.5-VL 7B

モデル: qwen2.5vl:7b(6.0GB)

画像1: 全身イラスト(24.1秒)

{
  "name": "ルイーゼ",
  "class": "戦士",
  "level": 10,
  "hp": 150,
  "mp": 50,
  "attack": 80,
  "defense": 70,
  "speed": 60,
  "special": ["剣の舞", "魔法防具", "回復薬"],
  "description": "青い翼を持つ少女。夜空の下で静かに立つ、神秘的な戦士。"
}

画像2: ドット絵・等身高め(4.2秒)

{
  "name": "リリィ",
  "class": "戦士",
  "level": 15,
  "hp": 120,
  "mp": 10,
  "attack": 30,
  "defense": 25,
  "speed": 20,
  "special": ["剣の舞", "防御の盾", "高速移動"],
  "description": "青いリボンをつけて、元気な印象の少女。戦闘では防御と攻撃のバランスが取れた戦士として活躍する。"
}

画像3: ドット絵・等身低め(3.7秒)

{
  "name": "ルイーゼ",
  "class": "戦士",
  "level": 10,
  "hp": 150,
  "mp": 50,
  "attack": 80,
  "defense": 70,
  "speed": 60,
  "special": ["剣の舞", "防御の盾", "高速移動"],
  "description": "赤い髪の少女。元気で明るい性格の戦士。"
}

画像4: ドット絵・2等身(3.9秒)

{
  "name": "リリィ",
  "class": "戦士",
  "level": 10,
  "hp": 150,
  "mp": 50,
  "attack": 80,
  "defense": 70,
  "speed": 60,
  "special": ["剣の舞", "防御の盾", "高速移動"],
  "description": "青いリボンとリボンの髪飾りが特徴的な、元気な少女戦士。"
}

所見

  • JSON形式は全画像で安定
  • 全画像で職業が「戦士」固定。画像の特徴(翼、魔法的な雰囲気)を職業に反映しない
  • 画像3・4はステータスがHP150/MP50/攻撃80/防御70/速さ60で完全に同一。テンプレ感が強い
  • 特技も「剣の舞」「防御の盾」「高速移動」がほぼ共通。画像ごとの差分が少ない
  • 翼の存在を認識はしている(descriptionに「青い翼を持つ少女」)が、ステータスに反映されない
  • ドット絵の認識は問題なし。リボンなどの細かいパーツも拾えている
  • 推論速度は全身イラストで24秒と遅め。ドット絵は3〜4秒と高速

Gemma 3 12B

モデル: gemma3:12b(8.1GB)

画像1: 全身イラスト(12.2秒)

{
  "name": "シエル・ヴァルキュリア",
  "class": "堕天使騎士",
  "level": 27,
  "hp": 185,
  "mp": 112,
  "attack": 78,
  "defense": 55,
  "speed": 93,
  "special": ["堕天光線", "聖域剥奪", "魅了の歌"],
  "description": "冷静沈着な堕天使。その美貌と力で人々を惑わせ、時には破滅へと導く。"
}

画像2: ドット絵・等身高め(9.2秒)

{
  "name": "春日 杏 (はるひ あん)",
  "class": "スクールアイドル",
  "level": 7,
  "hp": 68,
  "mp": 42,
  "attack": 25,
  "defense": 18,
  "speed": 35,
  "special": ["応援歌", "閃光ダンス", "キュートアタック"],
  "description": "ステージを照らす、希望の光。アイドルとしての輝きと、秘めた健闘心を持つ少女。"
}

画像3: ドット絵・等身低め(8.2秒)

{
  "name": "花音",
  "class": "魔法使い",
  "level": 7,
  "hp": 65,
  "mp": 120,
  "attack": 30,
  "defense": 25,
  "speed": 70,
  "special": ["ファイア", "アイス", "ライトニング"],
  "description": "明るく元気な魔法使い。意外と正義感が強い。"
}

画像4: ドット絵・2等身(9.3秒)

{
  "name": "憂鬱な花子",
  "class": "理系魔法使い",
  "level": 5,
  "hp": 85,
  "mp": 120,
  "attack": 30,
  "defense": 25,
  "speed": 60,
  "special": ["しかめっ面ブレス", "溜め読みマナ", "ツッコミ判定"],
  "description": "いつも何かと不満げな表情をしている理系魔法使い。天才的な頭脳で強力な魔法を操る。"
}

所見

  • JSON形式は全画像で安定
  • 3モデル中、最もクリエイティブな出力。画像の特徴を職業や特技に反映する能力が高い
  • 翼+制服+月の組み合わせから「堕天使騎士」を導き出し、特技も「堕天光線」「聖域剥奪」と世界観が一貫している
  • 2等身ドット絵のちょっとムスッとした表情を読み取って「憂鬱な花子」「理系魔法使い」「しかめっ面ブレス」を生成。表情認識の精度が高い
  • レベルが画像の雰囲気で変わる(全身絵は27、ドット絵は5〜7)。単調にならない
  • ステータスの配分にも個性がある。堕天使騎士は速さ93が突出、魔法使いはMP120が高い
  • 推論速度は8〜12秒。4Bより遅いが十分実用的

Llama 3.2 Vision 11B

モデル: llama3.2-vision:11b(7.8GB)

画像1: 全身イラスト(19.2秒)

{"name": "Hana", "class": "Vampire", "level": 10, "hp": 100, "mp": 50,
 "attack": 20, "defense": 15, "speed": 30,
 "special": ["Blood Drain", "Shadow Bite", "Darkness"],
 "description": "A young vampire with a mysterious past..."}

画像2: ドット絵・等身高め(17.5秒)

JSONではなくMarkdown形式で出力された。特技が「まほう1」「まほう2」「まほう3」というプレースホルダ。

画像3: ドット絵・等身低め(15.8秒)

{"name": "エリザ", "class": "マジック少女", "level": 10, "hp": 100, "mp": 80,
 "attack": 15, "defense": 10, "speed": 12,
 "special": ["火の炎", "水の波", "風の旋", "電の光", "土の壁"],
 "description": "天才少女、エリザはマジックを操り、世界を救い、天下を取る"}

画像4: ドット絵・2等身(14.2秒)

{"name": "さや", "class": "魔女", "level": 10, "hp": 100, "mp": 50,
 "attack": 20, "defense": 15, "speed": 30,
 "special": ["火の玉", "氷の壁", "電気の鞭"],
 "description": "とりあえず魔女のとりあえず"}

所見

  • 日本語プロンプトに対して英語で返すことがある(画像1)。日本語の指示追従が弱い
  • JSON形式が不安定。画像2はMarkdownで返ってきた。画像3はMarkdown見出し+JSONの混合
  • level 10固定、HP100固定と、パラメータがテンプレ的
  • descriptionが投げやり(「とりあえず魔女のとりあえず」)
  • FF風テストでは「ティル・ド・ジント」「マルス・エクス・デュス」のようなフランス語風ハルシネーションが発生
  • カードダス風テストでは英語で返す(“Vampirina”, “The Moonlight”)うえに、JSONとMarkdownの両方を出力する
  • 日本語コンテンツ生成タスクには不向き

Gemma 4 E4B

モデル: gemma4:e4b(9.6GB)

Ollama 0.17.7ではpull時に412エラーが出た。0.19以降が必要で、今回は0.20.6にアップデートして実行。

画像1: 全身イラスト(28.9秒)

{
  "name": "リリー",
  "class": "翼使(ヨコシ)",
  "level": 25,
  "hp": 2800,
  "mp": 6500,
  "attack": 1200,
  "defense": 1500,
  "speed": 3500,
  "special": [
    "天癒の舞(てんゆのまい): 味方全体のHPを大きく回復する光の魔法。",
    "蒼空の翼撃(そうくうのよくげき): 巨大な翼から強力な光の波動を放つ広範囲攻撃。",
    "羽音の急襲(はおとのきゅうしゅう): 自身のスピードとMPを大幅に回復しながら敵を拘束する支援魔法。"
  ],
  "description": "学園の制服を身に纏いながらも、背後からは巨大な翼を広げる神秘的な少女。優雅な動きからは高い魔法の才能が滲み出ており、回復と攻撃を兼ね備えた万能のエレメンタリスト。その力は、天使と魔族の境界に存在する謎めいたものである。"
}

画像2: ドット絵・等身高め(19.4秒)

{
  "name": "夢見の少女",
  "class": "癒しの魔法使い",
  "level": 17,
  "hp": 240,
  "mp": 380,
  "attack": 10,
  "defense": 18,
  "speed": 28,
  "special": [
    "聖なる癒し (Heal)",
    "精神安定 (Mind's Calm)",
    "結界展開 (Barrier)"
  ],
  "description": "繊細で優雅な雰囲気を持つ魔法使い。直接的な戦闘よりも、仲間の心を癒し、支えることに長けている。"
}

画像3: ドット絵・等身低め(14.4秒)

{
  "name": "リナ",
  "class": "賢者",
  "level": 15,
  "hp": 250,
  "mp": 400,
  "attack": 30,
  "defense": 15,
  "speed": 35,
  "special": ["マジックカーン", "シールド", "弱点看破"],
  "description": "学園に所属する、知識と癒やしの力を持つ少女。戦場ではサポートに徹し、仲間を支える魔導使い。"
}

画像4: ドット絵・2等身(14.1秒)

{
  "name": "ライラ",
  "class": "学園魔術師",
  "level": 18,
  "hp": 280,
  "mp": 550,
  "attack": 15,
  "defense": 10,
  "speed": 30,
  "special": [
    "ルーンの結界 (防御)",
    "記憶の回復 (回復)",
    "ステータス解析 (支援)"
  ],
  "description": "知識を武器とする、冷静な魔術の使い手。友情の魔法を信じ、仲間を支える。"
}

所見

  • JSON形式自体は正しいが、指定した数値範囲を守らない。画像1はHP2800・速さ3500で、プロンプトのHP1-999・speed1-255を大幅に逸脱
  • 特技にフレーバーテキスト(説明文や英訳)を勝手に追加する傾向がある。パース時に邪魔になる
  • 「翼使(ヨコシ)」のように独自のルビを振るのはクリエイティブだが、ドラクエ感からは外れる
  • 学園要素を全画像で強く拾っている(制服を認識して「学園魔術師」「学園に所属する」等)
  • descriptionが長い。画像1は3文に及ぶ
  • 推論速度は14〜29秒で、テストした中で最も遅い
  • Gemma 3 12Bと比べると、認識精度は同等だがフォーマット遵守の面で劣る

プロンプト変更テスト

ドラクエ風以外のフォーマットでも全モデルで試した。最終的にDQ風・FF風・カードダス風のどれで合成するかはまだ決めていないので、プロンプトを変えたときの出力の質をモデルごとに確認する。

全身イラストと2等身ドット絵の2枚で比較。

FF風

Gemma 3 12B

// 全身イラスト(15.1秒)
{"name": "白咲 凛華 (Shirasaki Rinka)", "job": "魔導剣士 (Magick Knight)", "level": 55,
 "hp": 8200, "mp": 6500, "strength": 75, "magic": 120, "vitality": 90, "speed": 110,
 "abilities": ["魔力障壁", "迅雷剣舞", "星詠み", "治癒の光"],
 "limit_break": "星影の奔流 (Starlight Torrent)"}

// ドット絵・2等身(9.1秒)
{"name": "早苗 (Sanae)", "job": "白魔道士 (White Mage)", "level": 12,
 "hp": 680, "mp": 420, "strength": 35, "magic": 85, "vitality": 60, "speed": 48,
 "abilities": ["白魔法習得", "祈祷", "アエテロヘイスト", "ライフ"],
 "limit_break": "聖なる光"}

「魔導剣士」「白魔道士」とFFの語彙で出てくる。リミットブレイクも自然。英語名を勝手に括弧で添えるのはGemma 3の癖だが、パースで除去すればいい。

Gemma 3 4B

// 全身イラスト(9.0秒)
{"name": "ルナ", "job": "スターライト・ナイト", "level": 10,
 "hp": 750, "mp": 1200, "strength": 80, "magic": 150, "vitality": 110, "speed": 130,
 "abilities": ["スターダスト・ショット", "ミラーイメージ", "ライトニング・ガンス"],
 "limit_break": "コスミック・ディヴァイン"}

// ドット絵・2等身(5.8秒)
{"name": "ミユ", "job": "学園の守護者", "level": 5,
 "hp": 120, "mp": 80, "strength": 10, "magic": 15, "vitality": 12, "speed": 14,
 "abilities": ["学園の力", "精神感応", "静寂の防壁"],
 "limit_break": "聖なるバリア"}

「スターライト・ナイト」「コスミック・ディヴァイン」と中二感が強め。FFというよりオリジナルRPGの雰囲気。

Qwen2.5-VL 7B

// 全身イラスト(39.0秒)
{"name": "ルイーゼ", "job": "魔法使い", "level": 15,
 "hp": 1200, "mp": 1500, "strength": 80, "magic": 120, "vitality": 90, "speed": 70,
 "abilities": ["魔法の盾", "炎の魔法", "風の魔法"],
 "limit_break": "天界の魔法"}

// ドット絵・2等身(4.6秒)
{"name": "リリィ", "job": "魔法使い", "level": 15,
 "hp": 120, "mp": 180, "strength": 70, "magic": 100, "vitality": 80, "speed": 60,
 "abilities": ["魔法の盾", "炎の矢", "風の舞"],
 "limit_break": "光の結晶"}

DQ風と同じくジョブが「魔法使い」固定。FF感がない。全身イラストで39秒と極端に遅い。

Gemma 4 E4B

// 全身イラスト(30.7秒)
{"name": "ルナリス", "job": "神秘の舞踊家", "level": 40,
 "hp": 750, "mp": 1800, "strength": 65, "magic": 150, "vitality": 110, "speed": 145,
 "abilities": ["魅惑の舞(エンチャント): 敵全体に魅了状態を付与...",
               "翼影斬(ウィング・シャドウ): 自身の翼を媒介とした...",
               "月詠の導き(ルナー・ガイド): 味方全体のMPを回復..."],
 "limit_break": "アビス・フォール:聖夜の羽翼"}

// ドット絵・2等身(20.3秒)
{"name": "ルナリア", "job": "魔導学園の生徒", "level": 18,
 "hp": 850, "mp": 1500, "strength": 110, "magic": 145, "vitality": 650, "speed": 1300,
 "abilities": ["光の護符(サポート)", "元素弾(魔法攻撃)", "時間停止の詠唱(妨害)"],
 "limit_break": "星詠みのアルカナ"}

DQ風と同じ傾向で、特技に説明文を混ぜる。vitality 650、speed 1300と数値範囲も守らない。

カードダス風

Gemma 3 12B

// 全身イラスト(8.1秒)
{"name": "藍川 栞", "title": "放課後ノ魔女", "type": "魔法", "rarity": "★3",
 "power": 780, "technique": 920, "speed": 850,
 "special_move": "禁書召喚:星詠みの呪印",
 "flavor_text": "放課後には古書に囲まれて魔法の研究に励む。その瞳には、禁断の知識が宿っている。"}

// ドット絵・2等身(7.7秒)
{"name": "憂鬱な小鳥遊", "title": "陰鬱プリンセス", "type": "メンタル", "rarity": "3",
 "power": 350, "technique": 800, "speed": 600,
 "special_move": "絶望の囁き",
 "flavor_text": "俯き加減の彼女に語りかけると、心の奥底にある暗い秘密が漏れ出すかも?"}

「放課後ノ魔女」「陰鬱プリンセス」のような二つ名が印刷映えする。パラメータ3つに集約されるのでカードレイアウトとの相性も良い。

Gemma 3 4B

// 全身イラスト(4.6秒)
{"name": "ルナ", "title": "星影の乙女", "type": "夜空の魔女", "rarity": "3",
 "power": 1500, "technique": 1200, "speed": 1800,
 "special_move": "星詠みの呪文",
 "flavor_text": "夜空に浮かぶ星の囁きに従い、真実を見抜く。"}

// ドット絵・2等身(4.4秒)
{"name": "ミオ", "title": "静寂の生徒", "type": "幻影", "rarity": "3",
 "power": 1500, "technique": 1800, "speed": 1200,
 "special_move": "虚像の嘲笑",
 "flavor_text": "沈黙は、時に最大の反証となる。"}

4Bでもカードダス風は安定している。フレーバーテキストが短くキレがある。

Qwen2.5-VL 7B

// 全身イラスト(14.9秒)
{"name": "ルーニー", "title": "月の妖精", "type": "水", "rarity": 5,
 "power": 8500, "technique": 9000, "speed": 8000,
 "special_move": "月光の舞",
 "flavor_text": "夜空に浮かぶ月の下で、彼女の歌声は星々を誘う。"}

// ドット絵・2等身(3.2秒)
{"name": "リリ", "title": "青い瞳の少女", "type": "風", "rarity": 3,
 "power": 1200, "technique": 1300, "speed": 1100,
 "special_move": "風の歌",
 "flavor_text": "青い瞳に風が吹き抜ける。"}

rarityを数値で返す(★表記でない)。全身イラストでpower 8500〜9000と極端に高いが、ドット絵は妥当な範囲。

Gemma 4 E4B

// 全身イラスト(18.6秒)
{"name": "リリア・ナイトウォーカー", "title": "月夜の翼人", "type": "闇", "rarity": "星5",
 "power": 8500, "technique": 9200, "speed": 7500,
 "special_move": "宵闇飛翔術",
 "flavor_text": "満月が照らす夜の帳の下、彼女の背中に宿る黒き翼は、失われた記憶を羽ばたかせていく。"}

// ドット絵・2等身(20.3秒)
{"name": "橘 結衣", "title": "秘めた決意の学徒", "type": "光", "rarity": "★★★★",
 "power": 2850, "technique": 4500, "speed": 1900,
 "special_move": "学園の約束",
 "flavor_text": "表向きは穏やかだが、仲間を想う強い意志が彼女の真の力を引き出す。"}

rarityの表記が「星5」「★★★★」と揺れる。カードダス風でもフレーバーテキストが長め。

プロンプト変更テストの傾向

モデルFF風の質カードダス風の質速度傾向
Gemma 3 12BFFの語彙で自然に出る二つ名が秀逸8〜15秒
Gemma 3 4B中二感が強いフレーバーが短くキレあり4〜9秒
Qwen2.5-VL 7Bジョブが「魔法使い」固定数値が極端3〜39秒
Llama 3.2 Visionフランス語風ハルシネーション英語で返す14〜19秒
Gemma 4 E4B特技に説明文混入rarityが揺れる18〜31秒

プロンプトを変えてもモデルの癖は変わらない。Gemma 3 12Bはどのフォーマットでも安定。Llama 3.2 Visionは日本語タスクに向かないことがFF風・カードダス風でも裏付けられた。カードダス風はフィールドが少ないぶん全モデルでJSON形式が安定する傾向がある(llamaを除く)。


比較

観点Gemma 3 4BQwen2.5-VL 7BGemma 3 12BLlama 3.2 VisionGemma 4 E4B
JSON形式の安定性安定安定安定不安定(Markdown混入)形式OK、数値範囲逸脱
画像認識の精度翼・月を認識翼・リボンを認識翼・表情・雰囲気まで認識翼を認識(Vampire)翼・制服・学園を強く認識
パラメータの面白さ中(メラホオオなど迷走あり)低(全部「戦士」固定)高(堕天使騎士、理系魔法使い)低(テンプレ的、投げやり)高(翼使、独自ルビ)だが冗長
ドット絵への対応力問題なし問題なし問題なし、表情まで読む認識するがJSON崩壊問題なし
日本語対応良好良好良好英語混入が頻発良好
推論速度5〜8秒3〜24秒8〜12秒14〜19秒14〜29秒
モデルサイズ3.3GB6.0GB8.1GB7.8GB9.6GB
フォーマット遵守良好良好良好不良数値範囲・特技形式が崩れる

Gemma 3 12Bが総合的に最も使いやすい。JSON出力の安定性と面白さのバランスが良く、指定したフォーマットを忠実に守る。

Gemma 4 E4Bは認識精度と面白さでは負けていないが、数値範囲を無視したり特技に説明文を混ぜたりと、構造化データとしての扱いやすさで劣る。パイプラインに組み込むにはパース処理の追加が必要になる。

Llama 3.2 Visionは日本語の指示追従とJSON出力の安定性が致命的に低く、このタスクでは使い物にならなかった。Qwen2.5-VLは画像認識自体はできているものの、出力のバリエーションが乏しい。Gemma 3 4Bはサイズの割に健闘しているが、12Bにすると画像の読み取りと出力の質が一段上がる。

パイプラインに組み込むVLMとしてはGemma 3 12Bを採用する方向で進める。M1 Max 64GBなら8.1GBのモデルは余裕で載る。Gemma 4 E4Bはプロンプトの改良で制御できる可能性があるが、速度面でも不利なので今回は見送り。