开源 BERTc:从零训练的字级中文 Modern BERT,一张 4090 可以复现
最近把自己做的中文 BERT 项目整理了一下,叫 **BERTc**:
- GitHub: [https://github.com/Ismantic/BERTc](https://github.com/Ismantic/BERTc)
- Hugging Face: [https://huggingface.co/Ismantic/BERTc-315M](https://huggingface.co/Ismantic/BERTc-315M)
它不是在现有中文 BERT 上继续训练,而是从随机初始化开始做了一遍完整流程:
语料下载和加工、词表、预编码、预训练、下游微调、评测、导出 HF 发布包。
165M 和 315M 两个规格,以及对应的多任务分析和拼写纠错模型都已经发布。
我做这个项目,主要是想回答一个问题:个人开发者能不能用一张消费级显卡,把一个中文基础模型从数据一路做到可验证的下游结果,而不是只留下训练脚本和一条 Loss 曲线?
目前的答案是可以。单张 RTX 4090 上,从零预训练大约需要 3 ~ 5 天,数据准备另需约 8 小时;从已经发布的 backbone 开始微调,则是几个小时。仓库没有多卡路径,模型和训练代码的 `src/` 只依赖 PyTorch 。
## 为什么是字级
BERTc 的词表大小是 12,536 ,中文一字一 piece ,英文使用 BPE 子词。
我比较看重它在中文序列标注任务上的简单性:分词、词性、实体识别和拼写纠错本来就是按字标注,token 与标签可以直接对齐,不需要处理一个 token 跨越多个标注单元的问题。
架构上采用了 24 层 / 315M 和 12 层 / 165M 两种规格,使用 GeGLU 、Pre-Norm 、无 bias 的 Linear 、输入输出嵌入绑权重,以及只在嵌入层计算一次的 Scaled Sinusoidal 位置编码。预训练是固定 15% 整词掩码,有效 batch 4096 ,共约 17.4B token 。
这里所谓“Modern”并不是照搬某个现成实现,而是把近几年已经比较成熟、且对 512 长度 encoder 合适的设计组合起来,同时尽量保持代码短和依赖少。
## 下游结果
做了两组完整微调和公开基准评测。
第一组是人民日报 PD-1998 上的中文分词( CWS )、词性标注( POS )和命名实体识别( NER )联合训练。315M + FGM 在 dev 前 2,000 句上的结果是:
```
CWS F1 0.9840
POS accuracy 0.9800
NER F1 0.9660
joint 1.4712
```
其中 `joint = CWS F1 + 0.3 × POS accuracy + 0.2 × NER F1`。同一口径下,MacBERT-Large 是 1.4677 。BERTc 的 CWS 单项并没有超过 MacBERT-Large ,综合提升主要来自 POS 。
第二组是中文拼写纠错,在 SIGHAN-15 官方 707 条测试集上按 PyCorrector 口径评测:
```
F1 0.8388
P 0.9461
R 0.7534
```
同一口径下,MacBERT4CSC 是 0.8314 ,MacBERT-Large 是 0.8309 。这个测试集很小,单条样本就足以明显改变数字,所以我不认为千分之几的差距能说明模型存在本质优势;这些结果更重要的作用,是证明仓库公开的训练链路确实能落到实际任务上。
仓库里有一个基准复现脚本,会加载真实 checkpoint 和真实数据,而不是用 mock 做形状测试:
```bash
python test/test_reproduce_sota.py
```
## 可以直接试
多任务分析模型:
```bash
huggingface-cli download Ismantic/BERTc-315M-MT --local-dir BERTc-MT
pip install git+https://github.com/Ismantic/PieceTokenizer
cd BERTc-MT
python example_decode.py
```
输入:
```
中国科学院计算技术研究所在北京
```
输出类似:
```
words: 中国 / 科学院 / 计算技术 / 研究所 / 在 / 北京
pos: ns n n n p ns
ner: [机构名] 中国科学院计算技术研究所 [地名] 北京
```
拼写纠错模型:
```python
from csc_model import BERTcForCSC
model = BERTcForCSC.from_pretrained(".")
model.correct("他平时喜欢锻练身体")
# 他平时喜欢锻炼身体
```
六个已发布模型都在这里:
- Backbone: [https://huggingface.co/Ismantic/BERTc-315M](https://huggingface.co/Ismantic/BERTc-315M)
- CWS + POS + NER: [https://huggingface.co/Ismantic/BERTc-315M-MT](https://huggingface.co/Ismantic/BERTc-315M-MT)
- 拼写纠错: [https://huggingface.co/Ismantic/BERTc-315M-CSC](https://huggingface.co/Ismantic/BERTc-315M-CSC)
- 165M 版本: [https://huggingface.co/Ismantic/BERTc-165M](https://huggingface.co/Ismantic/BERTc-165M)
如果有人愿意试跑、复现数字,或者对字级词表、预训练配方和评测口径有意见,都很欢迎直接提 issue 或在这里交流。
---
原文链接:[点击查看](https://www.v2ex.com/t/1231201)
- GitHub: [https://github.com/Ismantic/BERTc](https://github.com/Ismantic/BERTc)
- Hugging Face: [https://huggingface.co/Ismantic/BERTc-315M](https://huggingface.co/Ismantic/BERTc-315M)
它不是在现有中文 BERT 上继续训练,而是从随机初始化开始做了一遍完整流程:
语料下载和加工、词表、预编码、预训练、下游微调、评测、导出 HF 发布包。
165M 和 315M 两个规格,以及对应的多任务分析和拼写纠错模型都已经发布。
我做这个项目,主要是想回答一个问题:个人开发者能不能用一张消费级显卡,把一个中文基础模型从数据一路做到可验证的下游结果,而不是只留下训练脚本和一条 Loss 曲线?
目前的答案是可以。单张 RTX 4090 上,从零预训练大约需要 3 ~ 5 天,数据准备另需约 8 小时;从已经发布的 backbone 开始微调,则是几个小时。仓库没有多卡路径,模型和训练代码的 `src/` 只依赖 PyTorch 。
## 为什么是字级
BERTc 的词表大小是 12,536 ,中文一字一 piece ,英文使用 BPE 子词。
我比较看重它在中文序列标注任务上的简单性:分词、词性、实体识别和拼写纠错本来就是按字标注,token 与标签可以直接对齐,不需要处理一个 token 跨越多个标注单元的问题。
架构上采用了 24 层 / 315M 和 12 层 / 165M 两种规格,使用 GeGLU 、Pre-Norm 、无 bias 的 Linear 、输入输出嵌入绑权重,以及只在嵌入层计算一次的 Scaled Sinusoidal 位置编码。预训练是固定 15% 整词掩码,有效 batch 4096 ,共约 17.4B token 。
这里所谓“Modern”并不是照搬某个现成实现,而是把近几年已经比较成熟、且对 512 长度 encoder 合适的设计组合起来,同时尽量保持代码短和依赖少。
## 下游结果
做了两组完整微调和公开基准评测。
第一组是人民日报 PD-1998 上的中文分词( CWS )、词性标注( POS )和命名实体识别( NER )联合训练。315M + FGM 在 dev 前 2,000 句上的结果是:
```
CWS F1 0.9840
POS accuracy 0.9800
NER F1 0.9660
joint 1.4712
```
其中 `joint = CWS F1 + 0.3 × POS accuracy + 0.2 × NER F1`。同一口径下,MacBERT-Large 是 1.4677 。BERTc 的 CWS 单项并没有超过 MacBERT-Large ,综合提升主要来自 POS 。
第二组是中文拼写纠错,在 SIGHAN-15 官方 707 条测试集上按 PyCorrector 口径评测:
```
F1 0.8388
P 0.9461
R 0.7534
```
同一口径下,MacBERT4CSC 是 0.8314 ,MacBERT-Large 是 0.8309 。这个测试集很小,单条样本就足以明显改变数字,所以我不认为千分之几的差距能说明模型存在本质优势;这些结果更重要的作用,是证明仓库公开的训练链路确实能落到实际任务上。
仓库里有一个基准复现脚本,会加载真实 checkpoint 和真实数据,而不是用 mock 做形状测试:
```bash
python test/test_reproduce_sota.py
```
## 可以直接试
多任务分析模型:
```bash
huggingface-cli download Ismantic/BERTc-315M-MT --local-dir BERTc-MT
pip install git+https://github.com/Ismantic/PieceTokenizer
cd BERTc-MT
python example_decode.py
```
输入:
```
中国科学院计算技术研究所在北京
```
输出类似:
```
words: 中国 / 科学院 / 计算技术 / 研究所 / 在 / 北京
pos: ns n n n p ns
ner: [机构名] 中国科学院计算技术研究所 [地名] 北京
```
拼写纠错模型:
```python
from csc_model import BERTcForCSC
model = BERTcForCSC.from_pretrained(".")
model.correct("他平时喜欢锻练身体")
# 他平时喜欢锻炼身体
```
六个已发布模型都在这里:
- Backbone: [https://huggingface.co/Ismantic/BERTc-315M](https://huggingface.co/Ismantic/BERTc-315M)
- CWS + POS + NER: [https://huggingface.co/Ismantic/BERTc-315M-MT](https://huggingface.co/Ismantic/BERTc-315M-MT)
- 拼写纠错: [https://huggingface.co/Ismantic/BERTc-315M-CSC](https://huggingface.co/Ismantic/BERTc-315M-CSC)
- 165M 版本: [https://huggingface.co/Ismantic/BERTc-165M](https://huggingface.co/Ismantic/BERTc-165M)
如果有人愿意试跑、复现数字,或者对字级词表、预训练配方和评测口径有意见,都很欢迎直接提 issue 或在这里交流。
---
原文链接:[点击查看](https://www.v2ex.com/t/1231201)
· 0 个赞