language: zh
thumbnail:
license: mit
tags:
datasets:
- 第2版SQuAD数据集
metrics:
- 第2版SQuAD
widget:
- text: "埃菲尔铁塔位于何处?"
context: "埃菲尔铁塔是一座位于法国巴黎战神广场的锻铁格子塔,以工程师古斯塔夫·埃菲尔的名字命名,其公司设计并建造了该塔。"
- text: "弗雷德里克·肖邦是谁?"
context: "弗雷德里克·弗朗索瓦·肖邦(1810年3月1日-1849年10月17日),原名弗里德里克·弗朗齐歇克·肖邦,是浪漫主义时期的波兰作曲家和钢琴演奏大师,主要创作独奏钢琴作品。"
基于SQuAD v2微调的bert-large-uncased-whole-word-masking模型
此模型通过nn_pruning Python库创建:线性层保留了原有权重的25.0%。
总体而言,该模型保留了**32.0%**的原始权重(嵌入层占模型重要部分且未通过此方法修剪)。
通过简单调整线性矩阵尺寸,其在评估任务上的运行速度达到bert-large-uncased-whole-word-masking的2.15倍。这得益于修剪方法生成的结构化矩阵:将鼠标悬停在下方图表上可观察各矩阵的非零/零部分分布。
准确率方面,其F1值为83.22,相较原版bert-large-uncased-whole-word-masking的85.85,下降2.63个点。
精细修剪细节
本模型基于HuggingFace的预训练模型在SQuAD2.0上微调,并蒸馏自madlag/bert-large-uncased-whole-word-masking-finetuned-squadv2。该模型不区分大小写:如english和English视为相同。
块修剪的副作用是部分注意力头被完全移除:384个头中有155个被修剪(占比40.4%)。下图展示了修剪后剩余注意力头在网络中的分布情况。
SQuAD1.1数据集详情
数据集 |
划分 |
样本数 |
SQuAD 2.0 |
训练集 |
13.0万 |
SQuAD 2.0 |
评估集 |
1.19万 |
微调环境
CPU: 英特尔(R) 酷睿(TM) i7-6700K
内存: 64GB
GPU: 1块GeForce GTX 3090,24GB显存
驱动版本: 455.23.05, CUDA: 11.1
性能指标
PyTorch模型文件大小:1119MB
(原始BERT:1228.0MB
)
指标 |
当前值 |
原始值(参见论文表2) |
差异 |
EM |
80.19 |
82.83 |
-3.64 |
F1 |
83.22 |
85.85 |
-2.63 |
完整评估结果:
{
"HasAns_exact": 76.48448043184885,
"HasAns_f1": 82.55514100819374,
"HasAns_total": 5928,
"NoAns_exact": 83.8856181665265,
"NoAns_f1": 83.8856181665265,
"NoAns_total": 5945,
"best_exact": 80.19034784805862,
"best_exact_thresh": 0.0,
"best_f1": 83.22133208932635,
"best_f1_thresh": 0.0,
"exact": 80.19034784805862,
"f1": 83.22133208932645,
"total": 11873
}
使用示例
首先安装nn_pruning库(包含优化脚本,可通过移除空行/列来压缩线性层):
pip install nn_pruning
然后几乎可以像常规使用transformers库一样调用,只需在加载管道后调用optimize_model
函数:
from transformers import pipeline
from nn_pruning.inference_model_patcher import optimize_model
qa_pipeline = pipeline(
"question-answering",
model="madlag/bert-large-uncased-wwm-squadv2-x2.15-f83.2-d25-hybrid-v1",
tokenizer="madlag/bert-large-uncased-wwm-squadv2-x2.15-f83.2-d25-hybrid-v1"
)
print("原始bert-large-uncased-whole-word-masking参数量:497.0M")
print(f"当前参数量(仅含注意力头修剪)={int(qa_pipeline.model.num_parameters() / 1E6)}M")
qa_pipeline.model = optimize_model(qa_pipeline.model, "dense")
print(f"完全优化后参数量={int(qa_pipeline.model.num_parameters() / 1E6)}M")
predictions = qa_pipeline({
'context': "弗雷德里克·弗朗索瓦·肖邦(1810年3月1日-1849年10月17日),原名弗里德里克·弗朗齐歇克·肖邦,是浪漫主义时期的波兰作曲家和钢琴演奏大师,主要创作独奏钢琴作品。",
'question': "弗雷德里克·肖邦是谁?",
})
print("预测结果", predictions)