マルチモーダル大規模言語モデルの一般的なフレームワークと、各モジュールにおける実装方法について解説します。画像や動画などの視覚情報は、ViT (Vision Transformer) や CLIP などの異なるビジョンエンコーダーでエンコードされ、テキスト情報はエンコーダーでエンコードされます。その後、視覚モーダル情報はマッピング層 (Q-Former や MLP など) を通して次元が揃えられ、LLM に入力されて結果が出力されます。ここでは、一般的に使用されるマルチモーダルモデルについて概説します。
QwenVLシリーズ
QwenVLシリーズは、QwenVL、QwenVL2、QwenVL2.5 の3つのモデルがあり、特に視覚情報の処理に大きな改善が見られます。
QwenVL
QwenVLでは、学習済みのクエリ (learned-query) を使用してモーダル情報をアライメントします。
- 言語モデル: Qwen-7B
- ビジョンエンコーダー: ViT-bigG (OpenCLIP で事前学習済み)
- フュージョンモジュール: 学習可能なクエリ (Learnable Query)
ViT は、3x448x448 の入力画像を処理し、特徴マップを生成します。この特徴マップは、畳み込み処理と次元の入れ替えを経て、1024 個の 1664 次元ベクトルに変換されます。QwenVL は、このシーケンス長を圧縮するために、アダプターとして単層のクロスアテンションモジュールを導入しています。このモジュールは、学習可能なクエリベクトルを使用し、ViT からの画像特徴量をキーとして、クロスアテンション操作により視覚特徴シーケンスを固定長 256 に圧縮します。位置情報の重要性を考慮し、2 次元絶対位置エンコーディング (三角関数位置エンコーディング) がクロスアテンションのクエリとキーに組み込まれ、位置情報の損失を低減します。
QwenVL-2
QwenVL-2 では、以下の改善点があります。
- 動的解像度: 入力画像の解像度を固定値にリサイズする必要がなく、アスペクト比を維持したまま、指定された範囲 `[mix_pixels, max_pixels]` に収まるように縮小します。これにより、視覚トークン数を削減します。
- 時間次元の追加: 画像 (CHW) に時間次元を追加し (TCHW、T=2)、動画処理との互換性を高めます。
- パッチ化とマージ: 追加された時間次元と空間次元の隣接する 2x2 のトークンをマージし、MLP 層で処理します。これにより、特徴表現が圧縮されます。
- マルチモーダル回転位置エンコーディング (M-RoPE): 位置エンコーディングに時間、高さ、幅の情報を含めることで、よりリッチな位置情報を付与します。
def _preprocess():
# ...
channel = patches.shape[1]
grid_t = patches.shape[0] // self.temporal_patch_size
grid_h, grid_w = resized_height // self.patch_size, resized_width // self.patch_size
# パッチの再形成とマージ
patches = patches.reshape(
grid_t,
self.temporal_patch_size, channel,
grid_h // self.merge_size,
self.merge_size, self.patch_size,
grid_w // self.merge_size,
self.merge_size, self.patch_size,
) # self.merge_size=2, self.patch_size=14, self.temporal_patch_size=2
# 2x2 の隣接パッチをマージ
patches = patches.transpose(0, 3, 6, 4, 7, 2, 1, 5, 8)
# パッチのシーケンス化(時間、高さ、幅の位置情報を保持)
flatten_patches = patches.reshape(
grid_t * grid_h * grid_w, channel * self.temporal_patch_size * self.patch_size * self.patch_size
)
# ...
最終的に、3D-RoPE を適用し、線形層を通して最終的な視覚トークンを得ます。
QwenVL-2.5
QwenVL-2.5 は QwenVL-2 のフレームワークを基盤としつつ、以下の変更が加えられています。
- RMSNorm の採用: LayerNorm を RMSNorm に置き換えました。
- SwiGLU MLP: VisionBlock 内の MLP を SwiGLU 構造に変更しました。
- Window Attention: 計算効率を向上させるために、Window Attention を導入しました。これにより、計算対象となるパッチの範囲を限定します。
- 2D-RoPE: 位置エンコーディングに 2D-RoPE を使用します。
Window Attention では、入力画像のサイズに基づいてウィンドウのインデックスと累積シーケンス長が計算されます。これにより、アテンション計算が局所化され、計算量が削減されます。
# 例: Window Attention のマスク計算
for i in range(1, len(cu_seqlens)):
attention_mask[..., cu_seqlens[i - 1] : cu_seqlens[i], cu_seqlens[i - 1] : cu_seqlens[i]] = 0
q = q.transpose(0, 1)
k = k.transpose(0, 1)
v = v.transpose(0, 1)
# アテンション計算
attn_weights = torch.matmul(q, k.transpose(1, 2)) / math.sqrt(self.head_dim)
attn_weights = attn_weights + attention_mask
attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(q.dtype)
まとめ
- QwenVL: 固定解像度で画像を処理し、ViT で特徴を抽出し、クロスアテンションにより特徴を固定長 (256 トークン) に圧縮して LLM に入力します。
- QwenVL2: 動的解像度、時間次元の追加、隣接トークンのマージ、M-RoPE を採用し、視覚特徴の表現力を向上させています。
- QwenVL2.5: QwenVL2 のフレームワークをベースに、RMSNorm、SwiGLU MLP、Window Attention、2D-RoPE を導入し、効率と性能をさらに向上させています。
KimiVLシリーズ
KimiVLシリーズの詳細は、参照資料をご参照ください。
参照:
- 1. https://arxiv.org/abs/2504.07491
- 2. https://arxiv.org/pdf/2308.12966
- 3. http://arxiv.org/abs/2409.12191
- 4. https://arxiv.org/abs/2502.13923
- 5. https://www.big-yellow-j.top/posts/2025/08/29/QwenVLCode.html