モデル概要
モデル特徴
モデル能力
使用事例
🚀 InternVL3-8B
InternVL3-8Bは、高度な多モーダル大規模言語モデルで、卓越した多モーダル感知と推論能力を備えており、ツール使用、GUIエージェント、産業画像分析などの多くの分野で優れた性能を発揮します。
- GitHub
- InternVL 1.0
- InternVL 1.5
- InternVL 2.5
- InternVL2.5-MPO
- InternVL3
- Blog
- Chat Demo
- HF Demo
- Quick Start
- Documents

✨ 主な機能
- InternVL 2.5と比較して、InternVL3はより卓越した多モーダル感知と推論能力を示し、その多モーダル能力はツール使用、GUIエージェント、産業画像分析、3D視覚感知などの分野にさらに拡張されています。
- ネイティブ多モーダル事前学習のおかげで、InternVL3シリーズは全体的なテキスト性能においてQwen2.5シリーズを上回っています。
- 可変視覚位置符号化(V2PE)を統合しているため、InternVL3は長文脈理解能力において前代のモデルよりも優れています。
📚 ドキュメント
InternVL3ファミリー
以下の表は、InternVL3シリーズを要約しています。
モデル名 | 視覚部分 | 言語部分 | HFリンク |
---|---|---|---|
InternVL3-1B | InternViT-300M-448px-V2_5 | Qwen2.5-0.5B | リンク |
InternVL3-2B | InternViT-300M-448px-V2_5 | Qwen2.5-1.5B | リンク |
InternVL3-8B | InternViT-300M-448px-V2_5 | Qwen2.5-7B | リンク |
InternVL3-9B | InternViT-300M-448px-V2_5 | internlm3-8b-instruct | リンク |
InternVL3-14B | InternViT-300M-448px-V2_5 | Qwen2.5-14B | リンク |
InternVL3-38B | InternViT-6B-448px-V2_5 | Qwen2.5-32B | リンク |
InternVL3-78B | InternViT-6B-448px-V2_5 | Qwen2.5-72B | リンク |
モデルアーキテクチャ
下の図に示すように、InternVL3は、InternVL 2.5およびその前代のモデルであるInternVL 1.5と2.0と同じモデルアーキテクチャを採用しており、「ViT - MLP - LLM」パラダイムに従っています。この新しいバージョンでは、ランダムに初期化されたMLPプロジェクターを使用して、新しい増分事前学習のInternViTをInternLM 3やQwen 2.5などのさまざまな事前学習された大規模言語モデル(LLM)と統合しています。
以前のバージョンと同様に、ピクセル再配置操作を適用して、視覚トークンの数を元の四分の一に減らしています。さらに、InternVL 1.5と同様の動的解像度戦略を採用して、画像を448×448ピクセルのタイルに分割しています。InternVL 2.0以降の主な違いは、多画像およびビデオデータのサポートも導入されたことです。
特に、InternVL3では、可変視覚位置符号化(V2PE)を統合しており、視覚トークンに対してより小さく、より柔軟な位置増分を使用しています。V2PEのおかげで、InternVL3は長文脈理解能力において前代のモデルよりも優れています。
学習戦略
ネイティブ多モーダル事前学習
我々は、ネイティブ多モーダル事前学習方法を提案しており、言語と視覚学習を1つの事前学習段階に統合しています。言語のみのモデルを最初に学習させ、それを他のモーダルを処理するように適合させる標準的なパラダイムとは異なり、我々の方法は多モーダルデータ(画像テキスト、ビデオテキスト、または画像テキスト交差シーケンスなど)を大規模なテキストコーパスと交織させています。この統一された学習スキームにより、モデルは言語と多モーダル表現を同時に学習することができ、最終的には個別のアライメントまたはブリッジモジュールを必要とせずに、視覚言語タスクを処理する能力が向上します。詳細については、我々の論文を参照してください。
教師付き微調整
この段階では、InternVL2.5で提案されたランダムJPEG圧縮、二乗損失再重み付け、および多モーダルデータパッキング技術もInternVL3シリーズに適用されています。InternVL2.5と比較して、InternVL3の教師付き微調整段階の主な進歩は、より高品質で多様な学習データを使用したことです。具体的には、ツール使用、3Dシーン理解、GUI操作、長文脈タスク、ビデオ理解、科学図表、創造的な執筆、および多モーダル推論の学習サンプルをさらに拡張しています。
混合嗜好最適化
事前学習と教師付き微調整の間、モデルは以前の真のトークンに基づいて次のトークンを予測するように学習されます。しかし、推論時には、モデルは自分自身の以前の出力に基づいて各トークンを予測します。この真のトークンとモデルの予測トークンの間の差異は、分布のズレを引き起こし、モデルの思考連鎖(CoT)推論能力を損なう可能性があります。この問題を緩和するために、我々はMPOを採用しており、正のサンプルと負のサンプルからの追加の監督を導入して、モデルの応答分布を真の分布に合わせ、推論性能を向上させています。具体的には、MPOの学習目標は、嗜好損失 \(\mathcal{L}{\text{p}}\)、品質損失 \(\mathcal{L}{\text{q}}\)、および生成損失 \(\mathcal{L}{\text{g}}\) の組み合わせであり、以下のように表されます。 $$ \mathcal{L}=w{p}\cdot\mathcal{L}{\text{p}} + w{q}\cdot\mathcal{L}{\text{q}} + w{g}\cdot\mathcal{L}{\text{g}}, $$ ここで、\(w{*}\) は各損失コンポーネントの重みを表します。MPOの詳細については、我々の論文を参照してください。
テスト時スケーリング
テスト時スケーリングは、大規模言語モデルと多モーダル大規模言語モデルの推論能力を強化する効果的な方法であることが証明されています。この研究では、N選択ベスト評価戦略を使用し、VisualPRM-8Bを評価モデルとして使用して、推論と数学評価のための最適な応答を選択しています。
多モーダル能力評価
多モーダル推論と数学
OCR、グラフ、および文書理解
多画像と現実世界の理解
総合多モーダルと幻覚評価
視覚位置特定
多モーダル多言語理解
ビデオ理解
GUI位置特定
空間推論
言語能力評価
我々は、InternVL3をQwen2.5チャットモデルと比較しました。Qwen2.5チャットモデルの対応する事前学習ベースモデルは、InternVL3の言語コンポーネントの初期化に使用されています。ネイティブ多モーダル事前学習のおかげで、InternVL3シリーズは全体的なテキスト性能においてQwen2.5シリーズを上回っています。なお、Qwen2.5シリーズの評価スコアは、すべてのデータセットで表に提供されたプロンプトバージョンを使用してOpenCompass評価を行ったため、公式に報告されたスコアと異なる場合があります。
アブレーション研究
ネイティブ多モーダル事前学習
我々は、InternVL2-8Bモデルで実験を行い、そのアーキテクチャ、初期化パラメータ、および学習データを完全に変更せずに維持しました。従来、InternVL2-8Bは、特徴アライメントのためのMLPウォームアップ段階を行った後、命令微調整段階を行う学習パイプラインを採用していました。我々の実験では、従来のMLPウォームアップ段階をネイティブ多モーダル事前学習プロセスに置き換えました。この変更により、ネイティブ多モーダル事前学習がモデルの全体的な多モーダル能力に与える影響を分離することができました。
下の図の評価結果は、ネイティブ多モーダル事前学習を採用したモデルが、ほとんどのベンチマークテストにおいて、完全な多段階学習を行ったInternVL2-8Bベースラインと同等の性能を示していることを示しています。さらに、より高品質のデータで命令微調整を行った後、このモデルは評価された多モーダルタスクにおいてさらなる性能向上を示しました。これらの結果は、ネイティブ多モーダル事前学習が多モーダル大規模言語モデルに強力な多モーダル能力を与える効率性を強調しています。
混合嗜好最適化
下の表に示すように、MPOを使用して微調整されたモデルは、MPOを使用していないモデルと比較して、7つの多モーダル推論ベンチマークにおいてより優れた推論性能を示しています。具体的には、InternVL3-78BとInternVL3-38Bは、それぞれ対応するモデルよりも4.1と4.5ポイント高いスコアを記録しています。特に、MPOに使用される学習データは、教師付き微調整に使用される学習データのサブセットであり、これは性能向上が主に学習アルゴリズムに起因するものであり、学習データに起因するものではないことを示しています。
可変視覚位置符号化
下の表に示すように、V2PEの導入により、ほとんどの評価指標において顕著な性能向上が見られました。さらに、位置増分 \( \delta \) を変更して行ったアブレーション研究により、通常の文脈を主に扱うタスクでも、比較的小さい \( \delta \) 値が最適な性能を実現することが示されました。これらの結果は、将来の多モーダル大規模言語モデルにおける視覚トークンの位置符号化戦略の改善に重要な洞察を提供しています。
🔧 技術詳細
ネイティブ多モーダル事前学習
言語と視覚学習を1つの事前学習段階に統合し、多モーダルデータを大規模なテキストコーパスと交織させることで、モデルが言語と多モーダル表現を同時に学習し、視覚言語タスクを処理する能力を向上させます。
教師付き微調整
ランダムJPEG圧縮、二乗損失再重み付け、および多モーダルデータパッキング技術を採用し、より高品質で多様な学習データを使用して、さまざまなタスクの学習サンプルを拡張しています。
混合嗜好最適化
追加の監督を導入して、モデルの応答分布を真の分布に合わせ、推論時の分布のズレの問題を緩和し、推論性能を向上させます。
可変視覚位置符号化(V2PE)
視覚トークンに対してより小さく、より柔軟な位置増分を使用し、モデルの長文脈理解能力を向上させます。
💻 使用例
基本的な使用法
我々は、transformers
を使用してInternVL3-8B
を実行するサンプルコードを提供しています。
⚠️ 重要提示
モデルが正常に動作するように、transformers>=4.37.2を使用してください。
16ビット(bf16 / fp16)
import torch
from transformers import AutoTokenizer, AutoModel
path = "OpenGVLab/InternVL3-8B"
model = AutoModel.from_pretrained(
path,
torch_dtype=torch.bfloat16,
low_cpu_mem_usage=True,
use_flash_attn=True,
trust_remote_code=True).eval().cuda()
BNB 8ビット量子化
import torch
from transformers import AutoTokenizer, AutoModel
path = "OpenGVLab/InternVL3-8B"
model = AutoModel.from_pretrained(
path,
torch_dtype=torch.bfloat16,
load_in_8bit=True,
low_cpu_mem_usage=True,
use_flash_attn=True,
trust_remote_code=True).eval()
マルチGPU
以下のコードは、マルチGPU推論中にテンソルが同じデバイス上にないことによるエラーを回避するために記述されています。大規模言語モデル(LLM)の最初の層と最後の層を同じデバイス上に配置することで、このようなエラーを防止することができます。
import math
import torch
from transformers import AutoTokenizer, AutoModel
def split_model(model_name):
device_map = {}
world_size = torch.cuda.device_count()
config = AutoConfig.from_pretrained(model_path, trust_remote_code=True)
num_layers = config.llm_config.num_hidden_layers
# Since the first GPU will be used for ViT, treat it as half a GPU.
num_layers_per_gpu = math.ceil(num_layers / (world_size - 0.5))
num_layers_per_gpu = [num_layers_per_gpu] * world_size
num_layers_per_gpu[0] = math.ceil(num_layers_per_gpu[0] * 0.5)
layer_cnt = 0
for i, num_layer in enumerate(num_layers_per_gpu):
for j in range(num_layer):
device_map[f'language_model.model.layers.{layer_cnt}'] = i
layer_cnt += 1
device_map['vision_model'] = 0
device_map['mlp1'] = 0
device_map['language_model.model.tok_embeddings'] = 0
device_map['language_model.model.embed_tokens'] = 0
device_map['language_model.output'] = 0
device_map['language_model.model.norm'] = 0
device_map['language_model.model.rotary_emb'] = 0
device_map['language_model.lm_head'] = 0
device_map[f'language_model.model.layers.{num_layers - 1}'] = 0
return device_map
path = "OpenGVLab/InternVL3-8B"
device_map = split_model('InternVL3-8B')
model = AutoModel.from_pretrained(
path,
torch_dtype=torch.bfloat16,
low_cpu_mem_usage=True,
use_flash_attn=True,
trust_remote_code=True,
device_map=device_map).eval()
高度な使用法
import math
import numpy as np
import torch
import torchvision.transforms as T
from decord import VideoReader, cpu
from PIL import Image
from torchvision.transforms.functional import InterpolationMode
from transformers import AutoModel, AutoTokenizer
IMAGENET_MEAN = (0.485, 0.456, 0.406)
IMAGENET_STD = (0.229, 0.224, 0.225)
def build_transform(input_size):
MEAN, STD = IMAGENET_MEAN, IMAGENET_STD
transform = T.Compose([
T.Lambda(lambda img: img.convert('RGB') if img.mode != 'RGB' else img),
T.Resize((input_size, input_size), interpolation=InterpolationMode.BICUBIC),
T.ToTensor(),
T.Normalize(mean=MEAN, std=STD)
])
return transform
def find_closest_aspect_ratio(aspect_ratio, target_ratios, width, height, image_size):
best_ratio_diff = float('inf')
best_ratio = (1, 1)
area = width * height
for ratio in target_ratios:
target_aspect_ratio = ratio[0] / ratio[1]
ratio_diff = abs(aspect_ratio - target_aspect_ratio)
if ratio_diff < best_ratio_diff:
best_ratio_diff = ratio_diff
best_ratio = ratio
elif ratio_diff == best_ratio_diff:
if area > 0.5 * image_size * image_size * ratio[0] * ratio[1]:
best_ratio = ratio
return best_ratio
def dynamic_preprocess(image, min_num=1, max_num=12, image_size=448, use_thumbnail=False):
orig_width, orig_height = image.size
aspect_ratio = orig_width / orig_height
# calculate the existing image aspect ratio
target_ratios = set(
(i, j) for n in range(min_num, max_num + 1) for i in range(1, n + 1) for j in range(1, n + 1) if
i * j <= max_num and i * j >= min_num)
target_ratios = sorted(target_ratios, key=lambda x: x[0] * x[1])
# find the closest aspect ratio to the target
target_aspect_ratio = find_closest_aspect_ratio(
aspect_ratio, target_ratios, orig_width, orig_height, image_size)
# calculate the target width and height
target_width = image_size * target_aspect_ratio[0]
target_height = image_size * target_aspect_ratio[1]
blocks = target_aspect_ratio[0] * target_aspect_ratio[1]
# resize the image
resized_img = image.resize((target_width, target_height))
processed_images = []
for i in range(blocks):
box = (
(i % (target_width // image_size)) * image_size,
(i // (target_width // image_size)) * image_size,
((i % (target_width // image_size)) + 1) * image_size,
((i // (target_width // image_size)) + 1) * image_size
)
# split the image
split_img = resized_img.crop(box)
processed_images.append(split_img)
assert len(processed_images) == blocks
if use_thumbnail and len(processed_images) != 1:
thumbnail_img = image.resize((image_size, image_size))
processed_images.append(thumbnail_img)
return processed_images
def load_image(image_file, input_size=448, max_num=12):
image = Image.open(image_file).convert('RGB')
transform = build_transform(input_size=input_size)
images = dynamic_preprocess(image, image_size=input_size, use_thumbnail=True, max_num=max_num)
pixel_values = [transform(image) for image in images]
pixel_values = torch.stack(pixel_values)
return pixel_values
def split_model(model_name):
device_map = {}
world_size = torch.cuda.device_count()
config = AutoConfig.from_pretrained(model_path, trust_remote_code=True)
num_layers = config.llm_config.num_hidden_layers
# Since the first GPU will be used for ViT, treat it as half a GPU.
num_layers_per_gpu = math.ceil(num_layers / (world_size - 0.5))
num_layers_per_gpu = [num_layers_per_gpu] * world_size
num_layers_per_gpu[0] = math.ceil(num_layers_per_gpu[0] * 0.5)
layer_cnt = 0
for i, num_layer in enumerate(num_layers_per_gpu):
for j in range(num_layer):
📄 ライセンス
このプロジェクトは、Qwenライセンスを採用しています。









