Skip to content
Published on

Vision LLM の学習法 — 入力と出力をどう教えるか

Authors

はじめに: 学習とは入力と出力を定義すること

ビジョン言語モデル(VLM)を学習するとは、結局のところモデルにどんな入力を与え、どんな出力を期待するかを定義することです。同じアーキテクチャでも、何を入力として見せ、何を正解とするかで全く異なる能力が育ちます。画像キャプションだけを学習すれば説明は得意でも指示に従えず、座標を学習すれば物体を指し示し、文書を学習すれば表やフォームを読みます。

本記事は VLM がどう学習されるかを入力と出力の観点で解きほぐします。段階的な学習パイプライン、ビジョンエンコーダの凍結戦略、データの種類、入力フォーマットと出力形式、損失計算、そして整列段階までを扱います。アーキテクチャ自体は別記事で扱ったので、ここではその構造をどう教えるかに集中します。

学習を始める前に持っているもの

最初からすべてを無から学習するわけではありません。通常は二つのよく学習された部品から出発します。一つは大規模な画像で事前学習されたビジョンエンコーダ、もう一つは大規模なテキストで事前学習された LLM です。二つはそれぞれ自分の領域で強いですが、互いに会話する方法を知りません。

出発点
  ビジョンエンコーダ(事前学習)  画像はよく見るが言語と整列していない
  LLM(事前学習)               言語はよく扱うが画像を見たことがない
  プロジェクタ(ランダム初期化)  まだ何も知らない

目標
  三つの部品が協力して画像を見て言語で答えるようにする

だから VLM 学習の最初の課題は二つの強い部品をつなぐ橋(プロジェクタ)を架け、その橋の上を情報が流れるよう整列することです。この出発条件を覚えておくと、なぜ学習が整列段階から始まるのか、なぜプロジェクタを先に学習するのかが自然に理解できます。

核心原理: 段階的な学習パイプライン

多くの VLM は一度に学習せず、段階を分けて徐々に能力を積み上げます。典型的な流れは 3 段階です。

段階 1: ビジョン言語整列事前学習
   目標: ビジュアルトークンを LLM 言語空間へ整列
   データ: 大規模な画像-キャプションペア
   学習対象: 主にプロジェクタ (ビジョンエンコーダ/LLM は凍結傾向)

段階 2: マルチタスク事前学習
   目標: 多様な視覚能力(キャプション・VQA・OCR・grounding)を広く習得
   データ: 混合マルチタスクコーパス
   学習対象: プロジェクタ + LLM (+ ビジョンエンコーダ一部解除も可)

段階 3: インストラクションファインチューニング
   目標: 指示追従, 対話, 形式遵守
   データ: 高品質なインストラクション-応答 (画像含む)
   学習対象: 主に LLM (+ プロジェクタ)

段階 1 はビジョンと言語を同じ意味空間に載せる整列段階です。ここではモデルが画像を見ておおよそ何かを言えるようにするだけでよいです。段階 2 で能力の幅を広げ、段階 3 で人の指示に合わせて行動するよう仕上げます。後段ほどデータ量は減り品質は上がる傾向があります。

深掘り 1: ビジョンエンコーダの凍結と解除

学習で最も重要な決定の一つは、どの構成要素をいつ学習させるかです。特にビジョンエンコーダを凍結するか解除するかが核心です。

凍結戦略の直観

  • 初期はビジョンエンコーダを凍結: 事前学習済みのビジョンエンコーダはすでに良い視覚特徴を出します。整列初期にこれを一緒に揺らすと壊れやすいため、通常はプロジェクタだけを学習します。
  • 中後半で段階的に解除: 能力を引き上げる段階でビジョンエンコーダを一部または全部解除し、ドメイン(文書・チャートなど)に合わせて微調整します。ただし学習率を低く取り、既存の表現が崩れないようにします。
  • LLM も段階的に: LLM バックボーンも整列初期は凍結または低い学習率で、インストラクション段階で本格的に学習する形で扱います。
        段階 1       段階 2          段階 3
ビジョンエンコーダ 凍結  一部/全解除     凍結 または 低 lr
プロジェクタ      学習    学習           学習
LLM             凍結    学習(低 lr)     学習

この表は絶対規則ではなくよくあるパターンです。モデルとデータ規模によって組み合わせは変わります。核心の直観は、うまく動く部品はむやみに揺らさず、整列が必要な部品(プロジェクタ)から学習するということです。

学習率と安定性

異なる構成要素は異なる学習率を使うことが多いです。よく事前学習されたビジョンエンコーダと LLM には小さな学習率を、ゼロから学ぶプロジェクタには相対的に大きな学習率を与えます。こうすると良い表現を保ちつつ整列だけを速く学習できます。

深掘り 2: データ — 何を見せるか

VLM の能力は学習データが決めます。主なデータ型は次のとおりです。

  • 画像-キャプション: 画像とその説明。整列事前学習の主力。大規模なウェブ収集データが一般的です。
  • 文書/OCR: テキストを含む画像とそのテキスト。小さな文字、表、レシート、フォームを読む能力を育てます。
  • VQA(視覚質問応答): 画像に対する質問と回答。推論と指示追従を一緒に学習します。
  • grounding/座標: 画像内の物体位置(ボックス座標)とその名称。物体を指し示す能力を与えます。
  • チャート/表理解: チャートや表の画像とその構造化された解釈。数値推論を育てます。

データの比率と品質が結果を左右します。OCR データを増やせば文書をよく読みますが、偏りすぎると一般対話能力が落ちることがあります。段階ごとにデータ混合比率を調整するのが実務の核心技術です。

深掘り 3: 入力フォーマット — どう見せるか

学習入力は画像トークンとテキストトークンをインターリーブした系列であり、通常チャットテンプレートで包みます。

チャットテンプレートと画像プレースホルダ

入力はシステム/ユーザ/アシスタントの役割で構成され、画像が入る位置にプレースホルダトークンを置きます。前処理段階でその位置が実際のビジュアルトークンに置換されます。

system: あなたは役立つビジョンアシスタントです。
user: [IMAGE] このレシートの合計はいくらですか?
assistant: 合計は 32,500 ウォンです。

IMAGE の位置は学習直前にビジュアルトークンブロックへ置換されます。複数画像なら各画像の位置に該当ブロックが入ります。

多様な出力形式

VLM の出力はテキストだけではありません。学習データの正解形式がそのままモデルが学ぶ出力形式になります。

  • 自然言語テキスト: キャプション, 回答, 説明。
  • 座標: grounding タスクでボックス座標をテキストトークンとして表現(例: 正規化された数値列)。モデルが座標を文字のように生成します。
  • 構造化出力: JSON, マークダウン表など。文書パースでキーバリューや表構造をそのまま生成するよう教えます。

出力を構造化するには学習データの正解も同じ構造である必要があります。モデルは正解形式を模倣するため、一貫したフォーマットでデータを作ることが重要です。

深掘り 4: 損失 — 何を基準に学ぶか

VLM の学習目標は LLM と同じく次トークン予測です。すなわち系列の各位置で次トークンの確率を高めるよう学習します。

loss = - sum over target positions of log P(token_t | tokens_<t)

核心はどの位置で損失を計算するかです。通常は画像トークンとユーザプロンプト部分を損失計算から除外(マスキング)し、アシスタントの応答トークンだけで損失を計算します。

[system] [user テキスト] [IMAGE トークン群] [assistant 応答]
   X          X              X(マスキング)        O(損失計算)

理由は明確です。私たちはモデルに画像を生成させたりユーザの質問を覚えさせたいのではなく、良い応答を生成させたいのです。だから正解であるアシスタント応答だけで学習信号を与えます。画像トークンは通常生成対象ではないため損失から外れます。

損失マスキングの擬似コード

def compute_loss(logits, labels, loss_mask):
    # logits: B x T x V, labels: B x T, loss_mask: B x T (1=学習, 0=無視)
    shift_logits = logits[:, :-1, :]
    shift_labels = labels[:, 1:]
    shift_mask = loss_mask[:, 1:]

    token_loss = cross_entropy(
        shift_logits.reshape(-1, shift_logits.size(-1)),
        shift_labels.reshape(-1),
        reduction="none",
    )
    token_loss = token_loss.reshape(shift_labels.shape)

    # マスキング: 画像/ユーザトークン位置は 0, アシスタント応答だけ 1
    masked = token_loss * shift_mask
    return masked.sum() / shift_mask.sum().clamp(min=1)

loss_mask をどう作るかが学習品質を左右します。アシスタント応答だけを 1 にし、画像トークンとプロンプトを 0 で塞ぐのが一般的な出発点です。

全体の学習ステップ擬似コード

def training_step(batch, model):
    # batch: 画像テンソル + トークン化されたインターリーブ系列 + loss_mask
    visual_tokens = model.vision_encoder(batch["images"])      # B x N_v x D_vis
    visual_tokens = model.projector(visual_tokens)             # B x N_v x D_llm

    # プレースホルダ位置にビジュアルトークンを挿入
    inputs_embeds = model.embed_and_inject(
        batch["input_ids"], visual_tokens, batch["image_positions"]
    )

    logits = model.llm(inputs_embeds=inputs_embeds,
                       attention_mask=batch["attention_mask"])

    loss = compute_loss(logits, batch["labels"], batch["loss_mask"])
    return loss

深掘り 5: grounding と座標をテキストで教える

VLM が物体を指し示す grounding 能力はどう学習されるのでしょうか。核心は座標を特別なモジュールなしにテキストトークンで表現することです。ボックス座標を 0 から 999 のような整数範囲へ正規化したのち、その数字を文字列のように出力するよう教えます。

入力:  [IMAGE] 犬をボックスで示してください。
正解:  犬の位置は (x1=120, y1=340, x2=410, y2=720) です。

モデルにとって座標はただの別のトークン系列です。次トークン予測で数字を生成すれば、それがそのまま位置になります。こうすると別途の検出ヘッドなしに同じ言語モデリング損失で grounding を学習できます。

  • 座標正規化: 画像サイズに無関係な一定範囲へ正規化すると、様々な解像度で一貫して学習されます。
  • 双方向タスク: 座標を出力するタスク(物体を示す)と座標を入力として受けるタスク(この領域に何があるか)を一緒に学習すると空間理解が固まります。
  • 形式の一貫性: 座標表記の形式をデータ全体で統一すると、モデルが安定して数字を生成します。

深掘り 6: データ混合とカリキュラム

段階ごとにどのデータをどれだけ混ぜるかが最終能力を左右します。これをデータミックスまたはカリキュラムと呼びます。

整列段階のミックス(例)
  画像-キャプション   大部分
  簡単な VQA         少量

マルチタスク段階のミックス(例)
  画像-キャプション   一部
  VQA               相当量
  OCR/文書          相当量
  grounding         一部
  チャート/表        一部

インストラクション段階のミックス(例)
  対話型インストラクション  大部分
  形式遵守の例             一部
  拒否/安全の例           少量

核心の直観は段階が進むほどデータの多様性と品質を引き上げることです。初期は量で整列を取り、後期は質で行動を仕上げます。特定の能力が弱ければそのデータ比重を増やしますが、一方を過度に増やすと別の能力が退化する均衡問題を常に念頭に置くべきです。

能力間の干渉

OCR データを大きく増やすと文書はよく読みますが自由な対話が硬くなることがあります。逆に対話データばかり多いと精密な座標や表抽出が弱くなります。こうした能力間の干渉は VLM 学習でよくある現象であり、評価セットを能力別に分けて追跡しながらミックスを調整するのが実務の核心です。

深掘り 7: 効率的ファインチューニングとパラメータ戦略

全モデルを毎回学習するのは高価です。そこで一部だけを学習する効率的ファインチューニング戦略が広く使われます。

  • プロジェクタのみ学習: 最も軽い適応。新しいビジョンエンコーダやドメインに素早く合わせるのに有用です。
  • LoRA 系の低ランクアダプタ: LLM やビジョンエンコーダの重みを直接変えず、小さな低ランク行列だけを追加学習します。メモリと保存コストが大きく減り、同じベースモデルに複数のアダプタを差し替えられます。
  • 部分凍結: ビジョンエンコーダを凍結し LLM とプロジェクタだけを学習する形で、安定性とコストの均衡を取ります。
ファインチューニングコスト比較(直観)
  全学習           高価,   最大の柔軟性
  部分学習         中間,   均衡
  LoRA 系アダプタ   安価,   速いドメイン適応
  プロジェクタのみ  非常に安価, 限定的な適応

ドメイン特化の文書抽出のような狭いタスクには LoRA 系で十分な場合が多く、モデルの根本能力を変えるならより多くのパラメータを解除する必要があります。タスクの性質と予算に合わせて戦略を選ぶことが重要です。

深掘り 7.5: チャットテンプレートと特殊トークン

入力を構成するとき、チャットテンプレートは単なる形式ではなく学習信号の一部です。モデルはテンプレートの特殊トークンを境界に役割を区別します。

一般的なチャットテンプレートの構造
  <役割:system> システム指示 <役割終了>
  <役割:user> [画像の位置] ユーザ質問 <役割終了>
  <役割:assistant> モデル応答 <役割終了>
  • 役割境界トークン: システム・ユーザ・アシスタントを区切る特殊トークン。この境界があってこそ損失マスクを正確に塗れます。
  • 画像プレースホルダ: 画像が入る位置を示すトークン。前処理でビジュアルトークンへ置換されます。
  • 応答終了トークン: モデルがいつ止まるかを学ばせるトークン。これがないと生成が終わりません。

ここでよくある誤りは学習と推論でチャットテンプレートが微妙に異なることです。空白一つ、トークン一つがずれてもモデルは学習時と異なる入力と認識し性能が落ちます。学習と推論は必ず同じテンプレート関数を共有すべきです。

深掘り 7.6: 学習の安定性とよくある失敗

VLM 学習はテキスト学習より不安定になりやすいです。二種類のデータと三種類の部品が絡むためです。よく見る失敗の様相を整理します。

  • 損失の発散: ビジョンエンコーダを大きすぎる学習率で解除すると損失が跳ね上がります。エンコーダは低い学習率で慎重に扱ってください。
  • モダリティ崩壊: モデルが画像を無視してテキストだけ見て答える現象。画像が答えに必須なデータを十分に混ぜる必要があります。
  • 反復生成: 応答が同じ句を無限に繰り返す。データ品質と終了トークン学習を点検してください。
  • 形式無視: 構造化出力を求めても自由テキストを出す。形式遵守の例を増やし一貫性を確保してください。
失敗 -> 点検項目
  損失の発散      学習率, 特にビジョンエンコーダ lr
  モダリティ崩壊   画像必須データの比重
  反復生成        終了トークン, データ品質
  形式無視        形式例の数, スキーマの一貫性

これらの失敗は大半がデータミックスや学習率、あるいはマスク設定に由来します。モデル構造を変える前にこの三つを先に点検するのが効率的です。

整列段階: RLHF と DPO を簡単に

インストラクションファインチューニングまで終えるとモデルは指示に従います。そこに人の選好を反映する整列段階を加えると応答の有用性と安全性が上がります。

  • RLHF: 人がより好む応答に高い報酬を与える報酬モデルを学習したのち、強化学習でポリシー(モデル)をその報酬に合わせて最適化します。強力ですがパイプラインが複雑です。
  • DPO: 選好ペア(良い応答, 悪い応答)から別途の報酬モデルなしに直接ポリシーを最適化します。実装が単純で安定しており、広く使われます。

VLM でも同じ原理が適用されます。ただし選好データに画像が含まれ、ハルシネーション(画像にないものを言う現象)を減らす方向で選好を集めることが多いです。

比較テーブル: 学習段階を一目で

段階主目標データ主学習対象データ量/品質
整列事前学習ビジョン言語整列画像-キャプションプロジェクタ量多い, 品質普通
マルチタスク能力の幅拡大混合マルチタスクプロジェクタ+LLM中間
インストラクションチューニング指示追従インストラクション-応答LLM量少ない, 品質高い
整列(RLHF/DPO)選好反映選好ペアLLM少ない, 非常に高い
損失位置マスキング理由
画像トークンマスキング(除外)生成対象でない
システム/ユーザテキストマスキング(除外)質問を覚えさせない
アシスタント応答学習(含む)良い応答生成が目標

深掘り 8: 評価と学習モニタリング

学習がうまくいっているかは損失曲線だけでは分かりません。VLM は能力が複数の系統に分かれるため、能力別の評価セットで多角的に追跡する必要があります。

モニタリングダッシュボード(例)
  キャプション品質   検証セットスコアの推移
  VQA 精度          質問応答の正答率
  OCR/文書精度       フィールド抽出精度
  grounding 精度     座標の整合度
  対話品質          インストラクション遵守の評価
  ハルシネーション率  根拠のない応答の頻度

ここでよくある落とし穴は一つの指標だけを見て学習を進めることです。OCR 精度だけを上げていくとある瞬間に対話品質が崩れていることがあります。複数の指標を一緒に見て、一方が良くなるとき別の方が悪くならないか監視することが重要です。

  • 早期シグナル: 学習序盤に特定の能力のスコアが急落したら、データミックスや損失マスクに問題があるかもしれません。
  • 過学習: 検証スコアが停滞または下がり始めたら、データの多様性を増やすか学習を止める時点です。
  • 分布の点検: 評価セットが実際の利用分布を代表するか定期的に点検すべきです。

深掘り 9: マルチモーダルなバッチ構成と学習効率

VLM 学習はテキスト専用学習よりバッチ構成が難しいです。画像ごとにビジュアルトークン数が異なり(任意解像度)、テキスト長もまちまちなので系列長が不揃いです。

バッチ構成の難しさ
  サンプル1: 短いテキスト + 小さい画像(256 トークン)   -> 合計 300 トークン
  サンプル2: 長いテキスト + 大きい画像(6000 トークン)   -> 合計 6500 トークン
  サンプル3: テキストのみ                            -> 合計 200 トークン

  単純パディング時: 最長サンプルに合わせてパディング -> 無駄が大きい

この非効率を減らす手法があります。

  • 長さベースのまとめ: 似た長さのサンプルを一つのバッチに集めてパディングの無駄を減らします。
  • シーケンスパッキング: 複数の短いサンプルを一つの系列に連結しつつ、アテンションマスクでサンプル間の境界を塞いで混ざらないようにします。
  • 画像トークン上限: 任意解像度で画像あたりのトークン上限を置き、極端に長いサンプルがバッチを支配しないようにします。

学習効率はそのままコストです。同じ GPU 時間でより多くの有効トークンを学習するほどコスト対性能が良くなるため、バッチ構成は単なるエンジニアリングのディテールではなく学習経済性の核心です。

深掘り 10: 分散学習とメモリ

大きな VLM は単一 GPU に載りません。そこで分散学習戦略が必要です。

  • データ並列: 同じモデルの複製を複数 GPU に置き、異なるデータを学習したのち勾配を合わせます。最も単純です。
  • シャーディング(パラメータ分割): モデルパラメータ・オプティマイザ状態・勾配を GPU 群に分割してメモリ負担を分散します。大きなモデル学習の標準です。
  • 活性値チェックポインティング: 順伝播の中間活性値を保存せず逆伝播時に再計算してメモリを節約します。計算を多く使う代わりにメモリを節約する折衷です。
メモリを占める主な要素
  モデルパラメータ    固定
  オプティマイザ状態  パラメータの数倍(オプティマイザによる)
  勾配               パラメータと同じ大きさ
  活性値             バッチ/系列長に比例 (ビジュアルトークン含む)

VLM で特に注意すべきは活性値です。ビジュアルトークンが系列を長くすると活性値メモリが急増します。だから画像トークン上限と活性値チェックポインティングが大きな画像の学習で重要になります。

深掘り 11: 合成データとデータ拡張

高品質なラベルデータは高価です。そこで合成データで学習データを補強する手法が広く使われます。

  • テンプレートベース生成: 表やフォームをプログラムで生成し正解も一緒に作ります。構造が明確なタスクに効果的です。
  • 既存モデルでの再キャプショニング: 強いモデルで画像により正確なキャプションを付け直しノイズを減らします。
  • レンダリング合成: 多様なフォント・背景・解像度でテキストをレンダリングして OCR データを無限に作れます。ドメインギャップに注意が必要です。
合成データ活用の流れ
  実データ(少量, 高品質)  +  合成データ(大量, 制御可能)
   |
   v
  混合学習  ->  実分布で検証  ->  ドメインギャップを点検

合成データの落とし穴はドメインギャップです。きれいすぎる合成画像だけ学習すると実際のノイズある文書で崩れます。合成と実を適切に混ぜ、評価は必ず実データで行うのが安全です。

データキュレーションと落とし穴

  • ノイズキャプション: ウェブ収集の画像-キャプションは不正確または無関係な場合が多いです。フィルタリングと再キャプショニングで品質を上げると効果が大きいです。
  • データ不均衡: 特定タスク(例: OCR)に偏りすぎると他の能力が退化します。段階ごとの混合比率を監視してください。
  • ハルシネーション誘発データ: 画像にない内容を断定するキャプションを多く学習するとモデルがハルシネーションを起こします。根拠ある応答中心にキュレーションするのが重要です。
  • フォーマット不一致: 学習正解の出力形式がばらつくとモデルが一貫した構造を出せません。JSON/表出力はスキーマを固定してください。
  • 前処理の不一致: 学習と推論の画像前処理(パッチサイズ, 正規化)が異なると性能が落ちます。同じパイプラインを両側で共有してください。
  • 損失マスクのバグ: loss_mask が誤ってプロンプトや画像トークンで損失が漏れると学習が誤った方向へ進みます。マスクを必ず検証してください。

おわりに

VLM 学習の本質は段階的に入力と出力を定義することです。整列事前学習でビジョンと言語を同じ空間に載せ、マルチタスクで能力の幅を広げ、インストラクションチューニングで指示に従わせ、整列で人の選好を反映します。その合間にビジョンエンコーダの凍結と解除、データ混合比率、損失マスキングというつまみを回して望む能力を育てます。

覚えておくべき核心は一つです。モデルは見せた入力と正解とした出力を模倣します。座標を教えれば座標を、表を教えれば表を出します。だからどの能力を望むかをまず決め、その能力を正確に反映する入力フォーマットと出力形式でデータを設計するのが学習の出発点です。

参考資料