MiniCPM/README.md
2024-01-31 15:24:21 +08:00

437 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div align="center">
<h1>
MiniCPM
</h1>
</div>
<p align="center">
<a href="XXXX" target="_blank">Hugging Face</a> |
<a href="XXXX" target="_blank">ModelScope</a> |
<a href="XXXX" target="_blank">Hugging Face</a> |
<a href="XXXX" target="_blank">技术报告</a>
</p>
<div align="center">
XXXXXX
XXXXXX
在[面壁露卡](https://luca.cn/)体验更大规模的模型。
<h4 align="center">
<p>
<b>中文</b> |
<a href="XXXX">English</a>
<p>
</h4>
</div>
## 目录
- [模型介绍]()
- [模型下载]()
- [评测结果]()
- [中文]()
- [英文]()
- [代码]()
- [逻辑]()
- [多模态]()
- [手机部署]()
- [Demo & API]()
- [高效参数微调]()
- [开源协议]()
- [工作引用]()
- [典型示例]()
# 模型介绍
# 模型下载
[HuggingFace仓库]()
[ModelScope仓库]()
[XX仓库]()
## 评测结果
## 多模态
|Models|MME(P)|MMB-dev(en)|MMB-dev(zh)|MMMU-val|CMMMU-val|
|-|-|-|-|-|-|
|LLaVA-Phi|1335.1|59.8|/|/|/|
|MobileVLM|1288.9|59.6|/|/|/|
|Imp-v1|1434.0|66.5|/|/|/|
|Qwen-VL-Chat|**1487**|60.6|56.7|**35.9**|30.7
|**MiniCPM-V**|1446|**67.3**|**61.9**|34.7|**32.1**|
## DPO
|Models|MT-bench|
|---|---|
|GPT-4-turbo|9.32|
|GPT-3.5-turbo|8.39|
|Mistral-8*7b-Instruct-v0.1|8.30|
|Claude-2.1|8.18|
|Zephyr-7B-beta|7.34|
|**MiniCPM-2B**|**7.25**|
|Vicuna-33B|7.12|
|Zephyr-7B-alpha|6.88|
|LLaMA-2-70B-chat|6.86|
|Mistral-7B-Instruct-v0.1|6.84|
|LLaMA-2-13B-chat|6.65|
|Vicuna-13B|6.57|
|MPT-34B-instruct|6.39|
|LLaMA-2-7B-chat|6.27|
|Vicuna-7B|6.17|
|MPT-7B-chat|5.42|
## 端侧部署
进行Int4量化后MiniCPM只占2GB空间具备在端侧手机进行模型部署的条件。
对此我们针对Android和Harmony系统使用开源框架MLC-LLM进行模型适配针对iPhone系统使用开源框架LLMFarm进行模型适配并分别选取了部分端侧手机设备进行了测试。
### 部署步骤
#### 安卓
#### IOS
[ios编译安装MiniCPM指南](https://github.com/zkh2016/LLMFarm/blob/main/CPM.md)
#### 多模态
### 部署性能
我们并为针对手机部署进行深度优化仅验证MiniCPM使用手机芯片进行推理的可行性。
**我们也欢迎更多开发者进一步调优并更新下面的测试列表,不断提升端侧大模型在手机上的推理性能。**
|手机型号|操作系统|处理器|MemoryGB|推理吞吐token/s|
|-|-|-|-|-|
|OPPO Find N3|Android 13|snapdragon 8 Gen2|12|6.5|
|Samsung S23 Ultra|Android 14|snapdragon 8 Gen2|12|6.4|
|Meizu M182Q|Android 11|snapdragon 888Plus|8|3.7|
|Xiaomi 12 Pro|Android 13|snapdragon 8 Gen1|8+3|3.7|
|Xiaomi Redmi K40|Android 11|snapdragon 870|8|3.5|
|Oneplus LE 2100|Android 13|snapdragon 870|12|3.5|
|Oneplus HD1900|Android 11|snapdragon 865|8|3.2|
|Oneplus HD1900|Android 11|snapdragon 855|8|3.0|
|Oneplus HD1905|Android 10|snapdragon 855|8|3.0|
|Oneplus HD1900|Android 11|snapdragon 855|8|3.0|
|Xiaomi MI 8|Android 9|snapdragon 845|6|2.3|
|Huawei Nova 11SE|Harmony 4.0.0|snapdragon 778|12|1.9|
|Xiaomi MIX 2|Android 9|snapdragon 835|6|1.3|
|iPhone 15 Pro|iOS 17.2.1|A16|8|18.0|
|iPhone 15|iOS 17.2.1|A16|6|15.0|
|iPhone 12 Pro|iOS 16.5.1|A14|6|5.8|
|iPhone 12|iOS 17.2.1|A14|4|5.8|
|iPhone 11|iOS 16.6|A13|4|4.6|
## Demo & API
#### 基于Gradio的网页版Demo
使用如下命令启动基于Gradio的网页版demo
```shell
python demo/gradio_based_demo.py
```
## 高效参数微调
## 开源协议
#### 模型协议
本仓库中代码依照 [Apache-2.0](https://github.com/OpenBMB/MiniCPM/blob/main/LICENSE) 协议开源MiniCPM 模型权重的使用则需要遵循 [“通用模型许可协议-来源说明-宣传限制-商业授权”](https://github.com/OpenBMB/General-Model-License/blob/main/%E9%80%9A%E7%94%A8%E6%A8%A1%E5%9E%8B%E8%AE%B8%E5%8F%AF%E5%8D%8F%E8%AE%AE-%E6%9D%A5%E6%BA%90%E8%AF%B4%E6%98%8E-%E5%AE%A3%E4%BC%A0%E9%99%90%E5%88%B6-%E5%95%86%E4%B8%9A%E6%8E%88%E6%9D%83.md)。
MiniCPM 模型权重对学术研究完全开放。如需将模型用于商业用途请联系cpm@modelbest.cn来获取书面授权在登记后亦允许免费商业使用。
#### 声明
作为一个语言模型MiniCPM 通过学习大量的文本来生成内容,但它无法理解、表达个人观点或价值判断,它所输出的任何内容都不代表模型开发者的观点和立场。
因此用户在使用 MiniCPM 生成的内容时,应自行负责对其进行评估和验证。
## 工作引用
如果觉得MiniCPM有助于您的工作请考虑引用下列[技术报告]()
```
@inproceedings{han2022bminf,
title={MiniCPM: todo},
booktitle={OpenBMB Blog},
year={2024}
}
```
## 典型示例
#### 代码生成
Case 1:
```
<用户>: 给这段代码逐行加上注释\n#include <stdio.h>\nint rabbit(int n) {\nif (n == 1 || n == 2) {\nreturn 1;\n} else {\nreturn rabbit(n - 1) + rabbit(n - 2);\n}\n}\nint main() {\nint n;\nfor(n=1;n<41;n++){\n printf(\"第%d个月时有%d对兔子\\n\", n, rabbit(n));\n}\nreturn 0;\n}
<AI>:
以下是包含详细注释的代码:
```c
// 引入标准输入输出库
#include <stdio.h>
// 定义一个递归函数计算第n个月有多少对兔子
int rabbit(int n) {
// 如果n等于1或2说明是第一个月或第二个月此时有1对兔子
if (n == 1 || n == 2) {
return 1;
}
// 否则,递归调用自身,计算前一个月和上个月兔子数量之和
else {
return rabbit(n - 1) + rabbit(n - 2);
}
}
// 主函数
int main() {
int n;
// 从1开始循环到第40个月
for(n=1; n<41; n++) {
// 输出当前月的编号和对应的兔子对数
printf("第%d个月时有%d对兔子\n", n, rabbit(n));
}
return 0;
}
```
这段代码首先定义了一个名为`rabbit`的递归函数用于计算第n个月有多少对兔子。在主函数中我们使用一个for循环从1遍历到第40个月并调用`rabbit`函数来计算每个月的兔子对数,并使用`printf`函数输出结果。
```
Case 2:
```
<用户>: 编写一个Python程序来实现一个MiniCPM模型Transformer结构, 40层每层维度为2304, 词表大小为122753
<AI>:
Mini-CPMMini-Contrastive Pretraining模型是一种基于Transformer结构的自然语言处理模型。它使用自注意力机制和多层编码器-解码器结构来学习序列到序列的转换任务。在实现Mini-CPM模型时我们需要遵循以下步骤
1. 导入所需库
2. 定义模型结构
3. 训练模型
4. 测试模型
以下是实现Mini-CPM模型的Python代码
```python
import torch
import torch.nn as nn
from torch.autograd import Variable
class MiniCpmModel(nn.Module):
def __init__(self, vocab_size, d_model, num_layers, dropout=0.1):
super(MiniCpmModel, self).__init__()
self.vocab_size = vocab_size
self.d_model = d_model
self.num_layers = num_layers
self.dropout = dropout
# 自注意力层
self.self_attn = nn.SelfAttention(d_model, dropout=dropout)
self.attn_layer = nn.TransformerEncoderLayer(d_model, num_layers, dropout=dropout)
self.transformer_encoder = nn.TransformerEncoder(self.attn_layer, num_layers)
# 全连接层
self.fc = nn.Linear(d_model * 8, vocab_size)
def forward(self, x):
x = self.self_attn(x)
x = x.view(x.size(0), -1)
x = self.transformer_encoder(x)
x = self.fc(x)
return x
def train_mini_cpm(model, device, train_loader, optimizer, epochs):
model.train()
for epoch in range(epochs):
for i, (text, target) in enumerate(train_loader):
text = text.to(device)
target = target.to(device)
optimizer.zero_grad()
output = model(text)
loss = nn.CrossEntropyLoss()(output, target)
loss.backward()
optimizer.step()
def test_mini_cpm(model, device, test_loader):
model.eval()
correct = 0
total = 0
with torch.no_grad():
for text, target in test_loader:
text = text.to(device)
target = target.to(device)
output = model(text)
_, predicted = torch.max(output, 1)
total += target.size(0)
correct += (predicted == target).sum().item()
print(f'Test Accuracy: {100 * correct / total}%')
if __name__ == "__main__":
# 参数设置
vocab_size = 122753
d_model = 2304
num_layers = 40
dropout = 0.1
# 初始化模型
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = MiniCpmModel(vocab_size, d_model, num_layers, dropout).to(device)
# 训练模型
optimizer = torch.optim.Adam(model.parameters(), lr=1e-5)
epochs = 10
train_mini_cpm(model, device, train_data, optimizer, epochs)
# 测试模型
test_mini_cpm(model, device, test_data)
```
请注意,您需要将`train_data`和`test_data`替换为您的训练和测试数据。同时,您需要准备包含文本和目标标签的数据集。
```
#### 数理逻辑
Case 1:
```
<用户>: 直接给出以下算式的计算结果15 + 25 + 33 + 22 + 9=
<AI>:
15 + 25 + 33 + 22 + 9 = 104
结果是104。
```
Case 2:
```
<用户>: 如果以下算式中减号均表示加号而加号实际上是减号给出算式的计算结果15 - 25 - 12 + 34=
<AI>:
如果在算式中将减号表示为加号,并且加号实际上表示减号,那么算式将变为:
15 + 25 + 12 - 34
按照数学运算的优先级(先乘除后加减),我们首先计算括号内的加法:
15 + 25 = 40
40 + 12 = 52
然后,我们进行减法操作:
52 - 34 = 18
所以,原算式的计算结果仍然是 18。
```
#### 知识推理
Case 1:
```
<用户>: 山东省最高的山是哪座山, 它比黄山高还是矮?差距多少?
<AI>:
山东省最高的山是泰山海拔1545米。黄山位于中国安徽省海拔1864米。从海拔上来看黄山比泰山高。两者之间的差距为
黄山 - 泰山 = 319米
请注意,这个数据可能随着气候变化和测量方法的变化而有所变化。
```
Case 2:
#### 内容创作
Case 1:
```
<用户>: 晚上睡不着,可以写哪些简短高级的朋友圈文案?
<AI>:
1. "夜深人静,思绪万千。愿此刻的宁静,能驱散心中的纷扰。"
2. "夜幕降临,星光闪烁。在这宁静的时刻,愿我的心灵得到片刻的慰藉。"
3. "月光如水,洒满窗台。此刻的我,只想静静聆听内心的声音。"
4. "繁星点点,照亮了黑暗。今晚的星空,让我感受到无尽的希望与力量。"
5. "夜深人静,独享这宁静的时光。愿所有的烦恼都能随风而逝,留下美好的回忆。"
6. "夜色渐浓,思念渐深。愿这份思念,能温暖我孤独的心房。"
7. "月光如水,洒满心间。在这宁静的夜晚,愿我能找到内心的安宁与平静。"
8. "夜深人静,独自品味生活的酸甜苦辣。愿每一个经历,都能成为成长的养分。"
9. "月光如诗,诗意如画。在这宁静的夜晚,愿我能感受到生活的美好与温馨。"
10. "夜深人静,倾听内心的呼唤。愿我能在这宁静的时刻,找到心灵的归宿。"
```
Case 2:
```
```
#### 文本翻译
Case 1:
```
<用户>: Translate this sentence into Russian: '如何用Python创建一个简单的网页爬虫'.
<AI>:
'Как создать простый скрипт для собирания страниц в скрипте Python?'
```
Case 2:
```
<用户>: Translate this sentence into French: "I am a fresh man on Chinese, do you know how this sentence is translated: 如何用Python创建一个简单的网页爬虫"
<AI>:
Je suis un nouveau-né en chinois, sais-tu comment on crée un simple web scraper en Python ?
Note : Voici la traduction en français de la phrase originale : "How to create a simple web crawler in Python".
```
#### 指令跟随
Case 1:
```
<用户>: 请帮小明写一份东京旅游的游记,要求每一句话以“哇太好玩了!”开头。
<AI>:
哇太好玩了!第一天,我们抵达了东京的成田国际机场。哇太壮观了!机场内的设施和服务都让我惊叹不已。
哇太兴奋了!我们搭乘高速列车前往东京站,准备开始我们的旅程。哇太刺激了!列车穿行在城市的上空,让我们感受到了日本的现代科技。
哇太兴奋了!我们抵达了东京塔,这座标志性的建筑给我们留下了深刻的印象。哇太壮观了!从塔顶俯瞰整个城市,景色美不胜收。
哇太好玩了!我们在浅草寺参观,感受到了日本传统文化的魅力。哇太神奇了!寺庙内的神像和佛像让我们感受到了宗教的力量。
哇太好玩了!我们去了东京迪士尼乐园,这里充满了欢声笑语和快乐。哇太梦幻了!我们乘坐了各种游乐设施,体验了不同的游戏和表演。
哇太好玩了!我们还去了东京迪士尼海洋,这里有更多的海洋主题景点和表演。哇太精彩了!我们欣赏了精彩的烟花表演,结束了这个美好的夜晚。
哇太好玩了!我们的东京之旅结束了,但留下了许多美好的回忆。我们学到了很多关于日本文化和历史的知识,也体验了日本的美食和娱乐。这次旅行真是太棒了!
```
Case 2:
```
<用户>: 给我一个藏头(“雪碧”)的春联, 分别按顺序给出上联(七个字),下联(七个字),横批。
<AI>:
以下是符合要求的藏头春联:
上联:雪消冰释瑞气来
下联:碧海青天春意浓
横批:瑞雪兆丰年
```
#### 特殊字符
Case 1:
```
<用户>: 请给以下句子加上emoji让它更生动: 亲爱的妻子:今天是你的生日,请收下我的蛋糕和玫瑰。
<AI>:
亲爱的妻子:🎉今天是你的生日,💖请收下我的蛋糕🎂和玫瑰花🌹。
emoji需要根据具体语言环境进行替换以下仅作示例展示
```
Case 2:
```
<用户>: 请给我一个json, 每个key是一个emoji每个value是这个emoji对应的意思给出10个左右
<AI>:
以下是一个包含10个emoji及其对应意义的JSON对象
```json
{
"😊": "表示满意和喜悦",
"😡": "表示愤怒或不满",
"🤣": "表示搞笑的跌倒动作,代表轻松和幽默",
"🚀": "表示兴奋和期待,通常与太空探索相关",
"💡": "表示光亮和智慧,代表新想法或创意",
"💤": "表示休息和放松,通常用于结束对话",
"🌟": "表示成就和优秀,代表成功和激励",
"🌱": "表示成长和发展,代表进步和积极变化",
"🦋": "表示自然和生命的循环,代表希望和重生",
"👥": "表示人与人之间的联系和团结,代表友谊和支持"
}
```
```