Steel-LLM_a1373794422999859.../README.md

95 lines
4.7 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.

---
license: apache-2.0
---
<div align="center">
# 开源中文预训练语言模型Steel-LLM
由zhanshijin和lishu14创建
</div>
## 👋 介绍
Steel-LLM是个人发起的利用业余时间从零开始预训练中文大模型的项目。我们使用了1T+的数据预训练一个1B左右参数量的中文LLM耗时8个月。我们分享了数据收集、数据处理、预训练框架修改、模型设计、模型微调等全过程并开源全部代码。让每个人在有8~几十张卡的情况下都能复现我们的工作。得益于开源中文数据Steel LLM在中文benchmark上表现优于一些大几倍的机构发布的LLM最终在ceval达到了38分cmmlu达到了33分。
<p align="center">
🐱 <a href="https://github.com/zhanshijinwat/Steel-LLM">Github</a>&nbsp&nbsp
&nbsp&nbsp 📑 <a href="https://www.zhihu.com/people/zhan-shi-jin-27">Blog</a> &nbsp&nbsp🌐公众号炼钢AI
"Steel(钢)"取名灵感来源于华北平原一只优秀的乐队“万能青年旅店万青”。乐队在做一专的时候条件有限自称是在“土法炼钢”但却是一张神专。我们训练LLM的条件同样有限但也希望能炼出好“钢”来。
## 📖 预训练数据
预训练数据方面Steel-LLM主要使用了wanjuan1.0、Skywork/Skypile-150B数据集、starcoder的python/java/c++数据。另外也加入了中文维基百科、百度百科、知乎问答等数据转换为token id后占用1.7T硬盘空间。Steel-LLM也对问答数据以及代码数据使用data-juicer进行了数据清洗数据收集及数据处理的具体细节见我的博客
https://mp.weixin.qq.com/s/yqmtHLuuNV9075qHgzhcPw
## 🎰 训练框架
训练框架方面我们修改了TinyLlama训练程序兼容Hugginface格式模型、支持了数据断点续训、支持了追加新的数据等能力。训练前20k checkpoint使用8 * A100之后使用的是8 * H800
具体的技术细节见我的博客https://mp.weixin.qq.com/s/KPRir6bK3MZZ-vMFTfhUQQ
## 🤖模型结构
tokenizer方面使用了Qwen/Qwen1.5-MoE-A2.7B-Chat的tokenizer。模型结构方面基于Qwen1.5模型进行了以下的新结构的尝试:
- FFN层使用softmax moe相同参数量下有更高的训练速度
- 使用双层的SwiGLU
具体的技术细节见我的博客https://mp.weixin.qq.com/s/JaZyf1jOEOtNDCcFqSj8TQ
## 💡 微调
微调阶段主要使用了BAAI/Infinity-Instruct、预训练数据中的wanjuan中文选择题部分回炉重造、ruozhiba等数据。尝试了COT/非COT微调、刷榜测试。
具体的实验细节见我的博客https://mp.weixin.qq.com/s/KK0G0spNw0D9rPUESkHMew
## 🏅 评估
Steel-LLM在CEVAL和CMMLU上进行了测试。Steel-LLM旨在训练一个中文LLM80%的训练数据都是中文因此并没有在英文benchmark上进行评测。
其他模型的指标来自于CEVAL论文、MiniCPM技术报告、MAP-Neo技术报告等途径。更多模型的指标可查看之前的<a href=https://mp.weixin.qq.com/s/KK0G0spNw0D9rPUESkHMew>博客</a>
| | CEVAL | CMMLU |
|------------------------------|--------|-------|
| Steel-LLM | 38.57 | 33.48 |
| Tiny-Llama-1.1B | 25.02 | 24.03 |
| Gemma-2b-it | 32.3 | 33.07 |
| Phi2(2B) | 23.37 | 24.18 |
| Deepseek-coder-1.3B-instruct | 28.33 | 27.75 |
| CT-LLM-SFT-2B | 41.54 | 41.48 |
| MiniCPM-2B-sft-fp32 | 49.14 | 51.0 |
| Qwen1.5-1.8B-Chat | 56.84 | 54.11 |
| ChatGLM-6B | 38.9 | - |
| Moss | 33.1 | - |
| LLAMA-65B | 34.7 | - |
| Qwen-7B | 58.96 | 60.35 |
| Gemma-7B | 42.57 | 44.20 |
| OLMo-7B | 35.18 | 35.55 |
| MAP-NEO-7B | 56.97 | 55.01 |
## ⛏️ 快速使用
```python
from modelscope import AutoModelForCausalLM, AutoTokenizer
model_name = "zhanshijin/Steel-LLM"
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype="auto",
device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)
prompt = "你是谁开发的"
messages = [
{"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)
generated_ids = model.generate(
**model_inputs,
max_new_tokens=512
)
generated_ids = [
output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
print(response)
```