Skip to content

Latest commit

 

History

History
945 lines (873 loc) · 29.7 KB

minicpm_v2dot6.md

File metadata and controls

945 lines (873 loc) · 29.7 KB

MiniCPM-V 2.6

Archieve at: 2025-01-13

MiniCPM-V 2.6 is the latest and most capable model in the MiniCPM-V series. The model is built on SigLip-400M and Qwen2-7B with a total of 8B parameters. It exhibits a significant performance improvement over MiniCPM-Llama3-V 2.5, and introduces new features for multi-image and video understanding. Notable features of MiniCPM-V 2.6 include:

  • 🔥 Leading Performance. MiniCPM-V 2.6 achieves an average score of 65.2 on the latest version of OpenCompass, a comprehensive evaluation over 8 popular benchmarks. With only 8B parameters, it surpasses widely used proprietary models like GPT-4o mini, GPT-4V, Gemini 1.5 Pro, and Claude 3.5 Sonnet for single image understanding.

  • 🖼️ Multi Image Understanding and In-context Learning. MiniCPM-V 2.6 can also perform conversation and reasoning over multiple images. It achieves state-of-the-art performance on popular multi-image benchmarks such as Mantis-Eval, BLINK, Mathverse mv and Sciverse mv, and also shows promising in-context learning capability.

  • 🎬 Video Understanding. MiniCPM-V 2.6 can also accept video inputs, performing conversation and providing dense captions for spatial-temporal information. It outperforms GPT-4V, Claude 3.5 Sonnet and LLaVA-NeXT-Video-34B on Video-MME with/without subtitles.

  • 💪 Strong OCR Capability and Others. MiniCPM-V 2.6 can process images with any aspect ratio and up to 1.8 million pixels (e.g., 1344x1344). It achieves state-of-the-art performance on OCRBench, surpassing proprietary models such as GPT-4o, GPT-4V, and Gemini 1.5 Pro. Based on the the latest RLAIF-V and VisCPM techniques, it features trustworthy behaviors, with significantly lower hallucination rates than GPT-4o and GPT-4V on Object HalBench, and supports multilingual capabilities on English, Chinese, German, French, Italian, Korean, etc.

  • 🚀 Superior Efficiency. In addition to its friendly size, MiniCPM-V 2.6 also shows state-of-the-art token density (i.e., number of pixels encoded into each visual token). It produces only 640 tokens when processing a 1.8M pixel image, which is 75% fewer than most models. This directly improves the inference speed, first-token latency, memory usage, and power consumption. As a result, MiniCPM-V 2.6 can efficiently support real-time video understanding on end-side devices such as iPad.

  • 💫 Easy Usage. MiniCPM-V 2.6 can be easily used in various ways: (1) llama.cpp and ollama support for efficient CPU inference on local devices, (2) int4 and GGUF format quantized models in 16 sizes, (3) vLLM support for high-throughput and memory-efficient inference, (4) fine-tuning on new domains and tasks, (5) quick local WebUI demo setup with Gradio, and (6) online web demo.

Evaluation

Click to view single image results on OpenCompass, MME, MMVet, OCRBench, MMMU, MathVista, MMB, AI2D, TextVQA, DocVQA, HallusionBench, Object HalBench.
Model Size Token Density+ OpenCompass MME MMVet OCRBench MMMU val MathVista mini MMB1.1 test AI2D TextVQA val DocVQA test HallusionBench Object HalBench
Proprietary
GPT-4o - 1088 69.9 2328.7 69.1 736 69.2 61.3 82.2 84.6 - 92.8 55.0 17.6
Claude 3.5 Sonnet - 750 67.9 1920.0 66.0 788 65.9 61.6 78.5 80.2 - 95.2 49.9 13.8
Gemini 1.5 Pro - - 64.4 2110.6 64.0 754 60.6 57.7 73.9 79.1 73.5 86.5 45.6 -
GPT-4o mini - 1088 64.1 2003.4 66.9 785 60.0 52.4 76.0 77.8 - - 46.1 12.4
GPT-4V - 1088 63.5 2070.2 67.5 656 61.7 54.7 79.8 78.6 78.0 87.2 43.9 14.2
Step-1V - - 59.5 2206.4 63.3 625 49.9 44.8 78.0 79.2 71.6 - 48.4 -
Qwen-VL-Max - 784 58.3 2281.7 61.8 684 52.0 43.4 74.6 75.7 79.5 93.1 41.2 13.4
Open-source
LLaVA-NeXT-Yi-34B 34B 157 55.0 2006.5 50.7 574 48.8 40.4 77.8 78.9 69.3 - 34.8 12.6
Mini-Gemini-HD-34B 34B 157 - 2141.0 59.3 518 48.0 43.3 - 80.5 74.1 78.9 - -
Cambrian-34B 34B 1820 58.3 2049.9 53.2 591 50.4 50.3 77.8 79.5 76.7 75.5 41.6 14.7
GLM-4V-9B 13B 784 59.1 2018.8 58.0 776 46.9 51.1 67.9 71.2 - - 45.0 -
InternVL2-8B 8B 706 64.1 2215.1 54.3 794 51.2 58.3 79.4 83.6 77.4 91.6 45.0 21.3
MiniCPM-Llama-V 2.5 8B 1882 58.8 2024.6 52.8 725 45.8 54.3 72.0 78.4 76.6 84.8 42.4 10.3
MiniCPM-V 2.6 8B 2822 65.2 2348.4* 60.0 852* 49.8* 60.6 78.0 82.1 80.1 90.8 48.1* 8.2
* We evaluate this benchmark using chain-of-thought prompting. Specifically, for MME, we used this technique only for the Cognition set.

+ Token Density: number of pixels encoded into each visual token at maximum resolution, i.e., # pixels at maximum resolution / # visual tokens.

Note: For proprietary models, we calculate token density based on the image encoding charging strategy defined in the official API documentation, which provides an upper-bound estimation.

Click to view multi-image results on Mantis Eval, BLINK, Mathverse mv, Sciverse mv, MIRB.
Model Size Mantis Eval BLINK val Mathverse mv Sciverse mv MIRB
Proprietary
GPT-4V - 62.7 54.6 60.3 66.9 53.1
LLaVA-NeXT-Interleave-14B 14B 66.4 52.6 32.7 30.2 -
Open-source
Emu2-Chat 37B 37.8 36.2 - 27.2 -
CogVLM 17B 45.2 41.1 - - -
VPG-C 7B 52.4 43.1 24.3 23.1 -
VILA 8B 8B 51.2 39.3 - 36.5 -
InternLM-XComposer-2.5 8B 53.1* 48.9 32.1* - 42.5
InternVL2-8B 8B 59.0* 50.9 30.5* 34.4* 56.9*
MiniCPM-V 2.6 8B 69.1 53.0 84.9 74.9 53.8
* We evaluate the officially released checkpoint by ourselves.
Click to view video results on Video-MME and Video-ChatGPT.
Model Size Video-MME Video-ChatGPT
w/o subs w subs Correctness Detail Context Temporal Consistency
Proprietary
Claude 3.5 Sonnet - 60.0 62.9 - - - - -
GPT-4V - 59.9 63.3 - - - - -
Open-source
LLaVA-NeXT-7B 7B - - 3.39 3.29 3.92 2.60 3.12
LLaVA-NeXT-34B 34B - - 3.29 3.23 3.83 2.51 3.47
CogVLM2-Video 12B - - 3.49 3.46 3.23 2.98 3.64
LongVA 7B 52.4 54.3 3.05 3.09 3.77 2.44 3.64
InternVL2-8B 8B 54.0 56.9 - - - - -
InternLM-XComposer-2.5 8B 55.8 - - - - - -
LLaVA-NeXT-Video 32B 60.2 63.0 3.48 3.37 3.95 2.64 3.28
MiniCPM-V 2.6 8B 60.9 63.6 3.59 3.28 3.93 2.73 3.62
Click to view few-shot results on TextVQA, VizWiz, VQAv2, OK-VQA.
Model Size Shot TextVQA val VizWiz test-dev VQAv2 test-dev OK-VQA val
Flamingo 80B 0* 35.0 31.6 56.3 40.6
4 36.5 39.6 63.1 57.4
8 37.3 44.8 65.6 57.5
IDEFICS 80B 0* 30.9 36.0 60.0 45.2
4 34.3 40.4 63.6 52.4
8 35.7 46.1 64.8 55.1
OmniCorpus 7B 0* 43.0 49.8 63.2 45.5
4 45.4 51.3 64.5 46.5
8 45.6 52.2 64.7 46.6
Emu2 37B 0 26.4 40.4 33.5 26.7
4 48.2 54.6 67.0 53.2
8 49.3 54.7 67.8 54.1
MM1 30B 0 26.2 40.4 48.9 26.7
8 49.3 54.7 70.9 54.1
MiniCPM-V 2.6+ 8B 0 43.9 33.8 45.4 23.9
4 63.6 60.5 65.5 50.1
8 64.6 63.4 68.2 51.4
* denotes zero image shot and two additional text shots following Flamingo.

+ We evaluate the pretraining ckpt without SFT.

Examples

Bike Menu Code Mem medal
Click to view more cases.
elec Menu

We deploy MiniCPM-V 2.6 on end devices. The demo video is the raw screen recording on a iPad Pro without edition.

    

    

rabbit.mp4

Multi-turn Conversation

import torch
from PIL import Image
from transformers import AutoModel, AutoTokenizer

torch.manual_seed(0)

model = AutoModel.from_pretrained('openbmb/MiniCPM-V-2_6', trust_remote_code=True,
    attn_implementation='sdpa', torch_dtype=torch.bfloat16) # sdpa or flash_attention_2, no eager
model = model.eval().cuda()
tokenizer = AutoTokenizer.from_pretrained('openbmb/MiniCPM-V-2_6', trust_remote_code=True)

image = Image.open('./assets/airplane.jpeg').convert('RGB')

# First round chat 
question = "Tell me the model of this aircraft."
msgs = [{'role': 'user', 'content': [image, question]}]

answer = model.chat(
    image=None,
    msgs=msgs,
    tokenizer=tokenizer
)
print(answer)

# Second round chat 
# pass history context of multi-turn conversation
msgs.append({"role": "assistant", "content": [answer]})
msgs.append({"role": "user", "content": ["Introduce something about Airbus A380."]})

answer = model.chat(
    image=None,
    msgs=msgs,
    tokenizer=tokenizer
)
print(answer)

You could get the following output:

"The aircraft in the image is an Airbus A380, which can be identified by its large size, double-deck structure, and the distinctive shape of its wings and engines. The A380 is a wide-body aircraft known for being the world's largest passenger airliner, designed for long-haul flights. It has four engines, which are characteristic of large commercial aircraft. The registration number on the aircraft can also provide specific information about the model if looked up in an aviation database."

"The Airbus A380 is a double-deck, wide-body, four-engine jet airliner made by Airbus. It is the world's largest passenger airliner and is known for its long-haul capabilities. The aircraft was developed to improve efficiency and comfort for passengers traveling over long distances. It has two full-length passenger decks, which can accommodate more passengers than a typical single-aisle airplane. The A380 has been operated by airlines such as Lufthansa, Singapore Airlines, and Emirates, among others. It is widely recognized for its unique design and significant impact on the aviation industry."

Multi-image Understanding

Click to view Python example of MiniCPM-V 2.6 multi-image understanding
import torch
from PIL import Image
from transformers import AutoModel, AutoTokenizer

model = AutoModel.from_pretrained('openbmb/MiniCPM-V-2_6', trust_remote_code=True,
    attn_implementation='sdpa', torch_dtype=torch.bfloat16) # sdpa or flash_attention_2, no eager
model = model.eval().cuda()
tokenizer = AutoTokenizer.from_pretrained('openbmb/MiniCPM-V-2_6', trust_remote_code=True)

image1 = Image.open('image1.jpg').convert('RGB')
image2 = Image.open('image2.jpg').convert('RGB')
question = 'Compare image 1 and image 2, tell me about the differences between image 1 and image 2.'

msgs = [{'role': 'user', 'content': [image1, image2, question]}]

answer = model.chat(
    image=None,
    msgs=msgs,
    tokenizer=tokenizer
)
print(answer)

Few-shot In-Context-Learning

Click to view Python example of MiniCPM-V 2.6 few-shot in-context-learning example
import torch
from PIL import Image
from transformers import AutoModel, AutoTokenizer

model = AutoModel.from_pretrained('openbmb/MiniCPM-V-2_6', trust_remote_code=True,
    attn_implementation='sdpa', torch_dtype=torch.bfloat16) # sdpa or flash_attention_2, no eager
model = model.eval().cuda()
tokenizer = AutoTokenizer.from_pretrained('openbmb/MiniCPM-V-2_6', trust_remote_code=True)

question = "production date" 
image1 = Image.open('example1.jpg').convert('RGB')
answer1 = "2023.08.04"
image2 = Image.open('example2.jpg').convert('RGB')
answer2 = "2007.04.24"
image_test = Image.open('test.jpg').convert('RGB')

msgs = [
    {'role': 'user', 'content': [image1, question]}, {'role': 'assistant', 'content': [answer1]},
    {'role': 'user', 'content': [image2, question]}, {'role': 'assistant', 'content': [answer2]},
    {'role': 'user', 'content': [image_test, question]}
]

answer = model.chat(
    image=None,
    msgs=msgs,
    tokenizer=tokenizer
)
print(answer)

Video understanding

Click to view Python example of MiniCPM-V 2.6 video understanding
import torch
from PIL import Image
from transformers import AutoModel, AutoTokenizer
from decord import VideoReader, cpu    # pip install decord

model = AutoModel.from_pretrained('openbmb/MiniCPM-V-2_6', trust_remote_code=True,
    attn_implementation='sdpa', torch_dtype=torch.bfloat16) # sdpa or flash_attention_2, no eager
model = model.eval().cuda()
tokenizer = AutoTokenizer.from_pretrained('openbmb/MiniCPM-V-2_6', trust_remote_code=True)

MAX_NUM_FRAMES=64 # if cuda OOM set a smaller number

def encode_video(video_path):
    def uniform_sample(l, n):
        gap = len(l) / n
        idxs = [int(i * gap + gap / 2) for i in range(n)]
        return [l[i] for i in idxs]

    vr = VideoReader(video_path, ctx=cpu(0))
    sample_fps = round(vr.get_avg_fps() / 1)  # FPS
    frame_idx = [i for i in range(0, len(vr), sample_fps)]
    if len(frame_idx) > MAX_NUM_FRAMES:
        frame_idx = uniform_sample(frame_idx, MAX_NUM_FRAMES)
    frames = vr.get_batch(frame_idx).asnumpy()
    frames = [Image.fromarray(v.astype('uint8')) for v in frames]
    print('num frames:', len(frames))
    return frames

video_path="video_test.mp4"
frames = encode_video(video_path)
question = "Describe the video"
msgs = [
    {'role': 'user', 'content': frames + [question]}, 
]

# Set decode params for video
params = {}
params["use_image_id"] = False
params["max_slice_nums"] = 2 # 如果cuda OOM且视频分辨率大于448*448可设为1

answer = model.chat(
    image=None,
    msgs=msgs,
    tokenizer=tokenizer,
    **params
)
print(answer)