1.导读
优秀的端侧模型系列面壁 MiniCPM 上新!一口气带来:
- 端侧多模态模型 MiniCPM-V 2.0:OCR 能力显著增强、甚至部分能力比肩 Gemini Pro;
- 适配更多端侧场景的基座模型 MiniCPM-1.2B:性能超越 Llama2-13B、推理速度达到人类语速近 25 倍;
- 最小的 128K 长文本模型 MiniCPM-2B-128K ;
- 性能进一步增强的 MoE 架构模型 MiniCPM-MoE-8x2B
开源地址(内含技术报告)如下:
端侧多模态模型 MiniCPM-V 2.0
多模态能力已成为当前大模型的核心竞争力之一,智能终端设备由于其影像视觉处理的高频需求,对在端侧部署的人工智能模型提出了更高的多模态识别与推理能力要求。
这一次,MiniCPM-V 2.0 不仅带来优秀端侧多模态通用能力,更带来惊艳的 OCR 表现。通过自研的高清图像解码技术,可以突破传统困境,让更为精准地识别充满纷繁细节的街景、长图在端侧成为可能。
甚至,还能识读 2300 多年前的清华简上一些难以辨别的古老字迹,以卓越的 OCR 能力,为我们叩响识读老文字的大门。譬如,它不仅可以在三根竹简中准确找到最短的竹简,也能精准地识别出上面的字迹。甚至,连无从辨别的复杂楚文字都被正确解读。
作为多模态识别与推理能力的硬核指标,新一代 MiniCPM-V 2.0 在 OCR(光学字符识别)方面的成绩,已被一项项权威榜单验证。
在 权威 OCR 综合能⼒榜单 OCRBench 中,MiniCPM-V 2.0 秉承面壁「小钢炮」系列「以小博大」传统,刷新了开源模型 SOTA。在 场景图片文字识别榜单 TextVQA 中,越级超越 13B 量级通用模型。
这一次,新一代 MiniCPM-V 2.0 还加速解锁了过去难以识别的高清图像信息识别,譬如街景、长图这类典型场景。
为什么我们在手机上随手可得的影像,用于 OCR 识别却如此困难?这是由于传统处理方法,只能处理固定尺寸图片,会将大像素或不规则图片强制压缩,导致原始图片中丢失大量信息、难以识别,这对充满了细节文字信息、又大量零散分布的街景类画面提出了极大挑战。
得益于自研高清图片解码技术,新一代 MiniCPM-V 2.0 带来清晰大图识别体验的大幅提升。可以处理最大 180 万像素高清大图,甚至 1:9 极限宽高比的高清图片(譬如要翻阅好几屏的长图),对它们进行高效编码和无损识别。
具体效果如下:
在 中文OCR 能力方面,识别同一张街景图,MiniCPM-V 2.0 可以准确地叫出大厦的名字。
目前,MiniCPM-V 2.0 已经可部署于智能手机,在图像理解和推理效率方面取得了卓越的表现:
2.小钢炮四连发
2.1更适配端侧场景的1.2B尺寸,以及长文本、MoE版本
在「高效大模型」的路径下,把大模型变得更小!更强!推动大模型落地应用!
我们再次追求极致,制造了一颗小小钢炮—— MiniCPM-1.2B。参数减少一半,速度提升 38%,成本下降 60%(1元= 4150000 tokens) 。在手机上的 推理速度 达到 25 token / s,甚至相当于 人的语速的 15 ~25 倍。
25 token / s, 则是将 MiniCPM-1.2B 离线部署于 iPhone 15 的实测成绩。
同时而来的,还有当前 最小的“128K长文本”模型,将原先4K上下文窗口一口气扩增至 128K(20万字)。
MiniCPM在多维度综合性能评测中表现卓越。此评测集针对大模型在长文本方面的五项能力(检索、数学、代码、问答和摘要)而设计,相较于当前主流的仅关注检索能力的大海捞针测试更加全面。
此外,MiniCPM通过 MoE 的性能增强,让 2B 小钢炮(MiniCPM 1.0)在其原来的基础之上性能平均提高 4.5 个百分点。从榜单成绩上来看,MiniCPM-MoE-8x2B 模型做到了在性能上的越级超越,并且推理成本仅为 Gemma-7B 的 69.7%。
模型链接和下载
MiniCPM系列模型现已在ModelScope社区开源:
社区支持直接下载模型的repo:
from modelscope import snapshot_download model_dir = snapshot_download("OpenBMB/MiniCPM-MoE-8x2B")
模型推理
本文使用的模型为 MiniCPM-MoE-8x2B 模型,在PAI-DSW运行(单卡A100) 。
MoE模型推理
from modelscope import AutoModelForCausalLM, AutoTokenizer import torch torch.manual_seed(0) path = 'openbmb/MiniCPM-MoE-8x2B' tokenizer = AutoTokenizer.from_pretrained(path) model = AutoModelForCausalLM.from_pretrained(path, torch_dtype=torch.bfloat16, device_map='cuda', trust_remote_code=True) responds, history = model.chat(tokenizer, "山东省最高的山是哪座山, 它比黄山高还是矮?差距多少?", temperature=0.8, top_p=0.8) print(responds)
资源消耗:
多模态模型推理:
# test.py import torch from PIL import Image from modelscope import AutoModel, AutoTokenizer model = AutoModel.from_pretrained('openbmb/MiniCPM-V-2.0', trust_remote_code=True, torch_dtype=torch.bfloat16) # For Nvidia GPUs support BF16 (like A100, H100, RTX3090) model = model.to(device='cuda', dtype=torch.bfloat16) # For Nvidia GPUs do NOT support BF16 (like V100, T4, RTX2080) #model = model.to(device='cuda', dtype=torch.float16) # For Mac with MPS (Apple silicon or AMD GPUs). # Run with `PYTORCH_ENABLE_MPS_FALLBACK=1 python test.py` #model = model.to(device='mps', dtype=torch.float16) tokenizer = AutoTokenizer.from_pretrained('openbmb/MiniCPM-V-2.0', trust_remote_code=True) model.eval() image = Image.open('xx.jpeg').convert('RGB') question = 'What is in the image?' msgs = [{'role': 'user', 'content': question}] answer, context, _ = model.chat( image=image, msgs=msgs, context=None, tokenizer=tokenizer, sampling=True, temperature=0.7 ) print(answer)
3.模型微调和微调后推理
我们使用SWIFT来对模型进行微调, SWIFT是魔搭社区官方提供的LLM&AIGC模型微调推理框架.
环境准备:
git clone https://github.com/modelscope/swift.git cd swift pip install -e .[all]
3.1MiniCPM-MoE-8x2B
我们使用数据集 blossom-math-zh 微调 MiniCPM-MoE-8x2B 模型. 任务是: 解数学题
微调脚本: LoRA+ddp
# Experimental environment: 4 * A100 # 4 * 41GB GPU memory nproc_per_node=4 CUDA_VISIBLE_DEVICES=0,1,2,3 \ NPROC_PER_NODE=$nproc_per_node \ MASTER_PORT=29500 \ swift sft \ --model_id_or_path OpenBMB/MiniCPM-MoE-8x2B \ --model_revision master \ --sft_type lora \ --tuner_backend peft \ --dtype bf16 \ --output_dir output \ --dataset blossom-math-zh \ --train_dataset_sample -1 \ --num_train_epochs 1 \ --max_length 2048 \ --check_dataset_strategy warning \ --lora_rank 8 \ --lora_alpha 32 \ --lora_dropout_p 0.05 \ --lora_target_modules DEFAULT \ --gradient_checkpointing false \ --batch_size 1 \ --weight_decay 0.1 \ --learning_rate 1e-4 \ --gradient_accumulation_steps $(expr 16 / $nproc_per_node) \ --max_grad_norm 0.5 \ --warmup_ratio 0.03 \ --eval_steps 100 \ --save_steps 100 \ --save_total_limit 2 \ --logging_steps 10 \ --use_flash_attn false \
对于消费级显卡,可以用模型并行来支持训练
LoRA+mp
# Experimental environment: 2 * A100 # 2 * 17GB GPU memory CUDA_VISIBLE_DEVICES=0,1 \ swift sft \ --model_id_or_path OpenBMB/MiniCPM-MoE-8x2B \ --model_revision master \ --sft_type lora \ --tuner_backend peft \ --dtype bf16 \ --output_dir output \ --dataset blossom-math-zh \ --train_dataset_sample -1 \ --num_train_epochs 1 \ --max_length 2048 \ --check_dataset_strategy warning \ --lora_rank 8 \ --lora_alpha 32 \ --lora_dropout_p 0.05 \ --lora_target_modules DEFAULT \ --gradient_checkpointing false \ --batch_size 1 \ --weight_decay 0.1 \ --learning_rate 1e-4 \ --gradient_accumulation_steps 16 \ --max_grad_norm 0.5 \ --warmup_ratio 0.03 \ --eval_steps 100 \ --save_steps 100 \ --save_total_limit 2 \ --logging_steps 10 \ --use_flash_attn false \
训练过程支持本地数据集,需要指定如下参数:
--custom_train_dataset_path xxx.jsonl \ --custom_val_dataset_path yyy.jsonl \
微调后推理脚本: (这里的ckpt_dir需要修改为训练生成的checkpoint文件夹)
对于消费级显卡,可以设置CUDA_VISIBLE_DEVICES来支持推理
# Experimental environment: A100 # 30GB GPU memory CUDA_VISIBLE_DEVICES=0 \ swift infer \ --ckpt_dir "output/minicpm-moe-8x2b/vx-xxx/checkpoint-xxx" \ --load_dataset_config true \ --max_new_tokens 2048 \ --temperature 0.1 \ --top_p 0.7 \ --repetition_penalty 1. \ --do_sample true \ --merge_lora false
训练loss图:
资源占用
训练
lora+ddp
lora+mp
推理
[PROMPT]<s> <用户>新华书店运到2车图书,每辆车装125包,每包有80本.新华书店运到图书多少本?<AI>[OUTPUT]新华书店运到2车图书,每辆车装125包,每包有80本。所以,每辆车装的总包数为125 * 80 = 10000本。 因此,新华书店运到图书的总数为10000 * 2 = 20000本。 Answer: 20000</s> [LABELS]新华书店运到的图书总数为2车图书的数量之和。每辆车装125包,每包有80本,所以每辆车的图书数量为125包 x 80本/包 = 10000本。两辆车的图书数量之和为2辆 x 10000本/辆 = 20000本。新华书店运到的图书总数为20000本。 Answer: 20000 -------------------------------------------------- [PROMPT]<s> <用户>Jacob的水箱能容纳50升水。Jacob从河里和雨水中收集水来填满他的水箱。他每天可以从雨水中收集800毫升的水,从河里收集1700毫升的水。Jacob需要多少天才能填满他的水箱?<AI>[OUTPUT]Jacob每天收集的水量为800毫升 + 1700毫升 = 2500毫升。 每天填满水箱需要的量为50升 * 1000毫升/升 = 50000毫升。 所以,Jacob需要50000毫升 / 2500毫升/天 = 20天才能填满他的水箱。 Answer: 20</s> [LABELS]每天从雨水和河水中收集到的水总量为800毫升+1700毫升=2500毫升=2.5升。 所以,填满50升水箱需要的天数为50升/2.5升=20天。 Answer: 20 -------------------------------------------------- [PROMPT]<s> <用户>一种小家电,打0.8后的价格是160元,这种小家电原价多少元.<AI>[OUTPUT]设小家电原价为x元,则打0.8后的价格为0.8x元。根据题意,打0.8后的价格是160元,所以0.8x = 160。 解方程得:x = 160 / 0.8 = 200元。 所以小家电原价为200元。 Answer: 200</s> [LABELS]设小家电的原价为x元。 根据题意,打0.8折扣后的价格为0.8x元。 根据题意,0.8x = 160。 解这个方程可以得到x = 200。 所以,这种小家电的原价为200元。 Answer: 200
3.2MiniCPM-V 2.0
我们使用数据集coco-mini-en-2 微调MiniCPM-V 2.0模型. 任务是: 图像描述
微调脚本: LoRA
# Experimental environment: A10 # 9GB GPU memory CUDA_VISIBLE_DEVICES=0 swift sft \ --model_type minicpm_v_v2 \ --dataset coco-mini-en-2
训练过程支持本地数据集,需要指定如下参数:
--custom_train_dataset_path xxx.jsonl \ --custom_val_dataset_path yyy.jsonl \
微调后推理脚本: (这里的ckpt_dir需要修改为训练生成的checkpoint文件夹)
CUDA_VISIBLE_DEVICES=0 swift infer \ --ckpt_dir output/minicpm-v-v2/vx-xxx/checkpoint-xxx \ --load_dataset_config true \
训练loss图:
训练后生成样例:
<AI>[OUTPUT]A large airplane that is hanging from the ceiling.</s> [LABELS]People walking in a museum with a airplane hanging from the celing.
<AI>[OUTPUT]A bowl of fruit and a cup of coffee.</s> [LABELS]a bowl of fruit and pastry on a table
资源占用
微调
推理