PaddleNLP SqueezeBERT 模型汇总与实战指南:预训练权重、分组卷积架构与下游任务使用
2026/9/23 16:38:22 网站建设 项目流程

PaddleNLP SqueezeBERT 模型汇总与实战指南:预训练权重、分组卷积架构与下游任务使用

【免费下载链接】PaddleNLPEasy-to-use and powerful LLM and SLM library with awesome model zoo.项目地址: https://gitcode.com/gh_mirrors/pa/PaddleNLP

本文以 PaddleNLP 官方模型汇总文档(docs/zh/model_zoo/transformers/SqueezeBert/contents.rst)为核心骨架,系统梳理 PaddleNLP 支持的 SqueezeBERT 预训练权重、模型架构原理与加载使用方式。读完本文,你将掌握如何在 PaddleNLP 中一键加载squeezebert-uncased等权重完成文本分类、命名实体识别与抽取式问答,并理解 SqueezeBERT 以分组卷积压缩参数量的核心设计。

一、SqueezeBERT 是什么

SqueezeBERT 是面向高效推理设计的 BERT 变体。它与标准 BERT 一样采用 12 层 Transformer 编码器结构,但核心区别在于:将传统 Transformer 中占用参数最多的全连接层(Q/K/V 投影、前馈网络)替换为 1×1 分组卷积(grouped convolution),从而在保持模型能力的同时显著减少参数总量、降低计算开销。

在 PaddleNLP 中,SqueezeBERT 以独立子模块形式实现,完整代码位于 paddlenlp/transformers/squeezebert,包含三个文件:

文件职责
configuration.pySqueezeBertConfig配置类与预训练权重清单
modeling.py模型主体:Embeddings、Encoder、SelfAttention 及三个下游任务头
tokenizer.pySqueezeBertTokenizer分词器

二、PaddleNLP 支持的 SqueezeBERT 预训练权重汇总

根据官方汇总文档,PaddleNLP 目前提供以下 3 个 SqueezeBERT 预训练权重,均为英文(English)语料训练:

预训练权重名称语言模型细节
squeezebert-uncasedEnglish12 层、768 维隐藏层、12 注意力头、约 51M 参数。SqueezeBERT Uncased 基础模型
squeezebert-mnliEnglish12 层、768 维隐藏层、12 注意力头、约 51M 参数。在 MNLI(自然语言推断)任务上微调后的模型
squeezebert-mnli-headlessEnglish12 层、768 维隐藏层、12 注意力头、约 51M 参数。去掉 MNLI 分类头的模型,适合作为下游任务微调起点

这三份权重在源码中的完整注册信息(含默认配置与权重下载地址)定义于 configuration.py 的SQUEEZEBERT_PRETRAINED_INIT_CONFIGURATIONSQUEEZEBERT_PRETRAINED_RESOURCE_FILES_MAP中。三者的基础架构配置完全一致(hidden_size=768num_hidden_layers=12num_attention_heads=12intermediate_size=3072),区别仅在于:

  • squeezebert-mnli额外设置了num_labels=3(对应 MNLI 蕴含/矛盾/中立三分类);
  • squeezebert-mnli-headless与基础版配置相同,但对应权重不包含分类头参数,专为继续微调设计。

与权重配套的分词器词表(vocab.txt)同样提供三个版本,见 tokenizer.py 的pretrained_resource_files_map

三、SqueezeBertConfig 核心配置参数

SqueezeBertConfig继承自PretrainedConfig,用于实例化SqueezeBertModel并控制模型输出。除了 BERT 常见的标准参数(vocab_sizehidden_sizenum_hidden_layersnum_attention_headsintermediate_sizehidden_acthidden_dropout_probattention_probs_dropout_probmax_position_embeddingstype_vocab_sizeinitializer_rangelayer_norm_epspad_token_id等),SqueezeBERT 特有的核心参数是六个分组数(groups)参数,它们直接决定了各层分组卷积的分组规模,是压缩参数量的关键:

参数默认值作用
embedding_size768词嵌入向量维度
q_groups4Q 投影层的分组数
k_groups4K 投影层的分组数
v_groups4V 投影层的分组数
post_attention_groups1注意力后第一个前馈层(post-attention)的分组数
intermediate_groups4第二个前馈层(intermediate)的分组数
output_groups4第三个前馈层(output)的分组数

分组卷积的参数压缩原理:当输入输出通道数均为 768 时,普通卷积层参数量为768 × 768,而分组数g=4的分组卷积参数量降为768 × 768 / 4。注意post_attention_groups默认值为 1,即该层退化为标准全连接(不分组),因为此层的输入输出通道数相等,分组压缩收益有限。

在 configuration.py 中,SqueezeBertConfig还通过attribute_mapnum_classes映射为num_labels,便于不同框架权重的统一加载。

四、源码级架构解析:分组卷积如何落地

阅读 modeling.py 可以清晰看到分组卷积的实现细节:

4.1 卷积基础构件

  • ConvActivation:封装 1×1 卷积 + 激活函数,用于 FFN 的 intermediate 层;
  • ConvDropoutLayerNorm:封装 1×1 卷积 + Dropout + 残差连接 + LayerNorm,用于 post-attention 与 output 层;
  • SqueezeBertLayerNorm:由于卷积在[N, C, W](通道在中间)布局上计算,LayerNorm 前先做维度转置,归一化后再转置回原布局。

4.2 Self-Attention 的卷积化

SqueezeBertSelfAttention 将标准 BERT 的 Q/K/V 线性投影全部替换为分组卷积:

self.query = nn.Conv1D(in_channels=cin, out_channels=cin, kernel_size=1, groups=q_groups) self.key = nn.Conv1D(in_channels=cin, out_channels=cin, kernel_size=1, groups=k_groups) self.value = nn.Conv1D(in_channels=cin, out_channels=cin, kernel_size=1, groups=v_groups)

随后通过transpose_for_scores/transpose_key_for_scores[N, C, W]布局的卷积输出重排为多头注意力所需的[N, heads, W, head_size]结构,再进行标准的缩放点积注意力(除以sqrt(attention_head_size))、softmax、Dropout 与加权求和。

4.3 单层结构与整体编码器

SqueezeBertLayer 的通道流转为:hidden_size → (attention) → hidden_size → (post_attention) → intermediate_size → (output) → hidden_size,即c0 = c1 = c3 = hidden_sizec2 = intermediate_size,对应上文的三个前馈分组层。

SqueezeBertEncoder 堆叠num_hidden_layersSqueezeBertLayer,并在首层前断言embedding_size == hidden_size——若两者不等,源码注释提示需要在第一个 SqueezeBertLayer 前插入 Conv1D 层调整通道数。

4.4 可用的模型类

PaddleNLP 为 SqueezeBERT 提供了 4 个可直接使用的模型类(定义于 modeling.py):

模型类用途输出
SqueezeBertModel基础编码器(@register_base_model(sequence_output, pooled_output),可选各层 hidden states 与注意力分数
SqueezeBertForSequenceClassification句级分类(如 GLUE)[batch_size, num_classes]的 logits
SqueezeBertForTokenClassification词级分类(如 NER)[batch_size, sequence_length, num_classes]的 logits
SqueezeBertForQuestionAnswering抽取式问答(如 SQuAD)(start_logits, end_logits)

这些类均已注册进 Auto 体系:AutoConfig通过"squeezebert"映射到SqueezeBertConfig(见 paddlenlp/transformers/auto/configuration.py),AutoModel映射到SqueezeBertModel(见 paddlenlp/transformers/auto/modeling.py),AutoTokenizer映射到SqueezeBertTokenizer(见 paddlenlp/transformers/auto/tokenizer.py)。

五、快速上手:加载模型与分词器

5.1 加载预训练模型

使用from_pretrained即可自动下载并加载上述任一权重:

import paddle from paddlenlp.transformers import SqueezeBertModel, SqueezeBertTokenizer # 加载模型与配套分词器 model = SqueezeBertModel.from_pretrained("squeezebert-uncased") tokenizer = SqueezeBertTokenizer.from_pretrained("squeezebert-uncased") # 构造输入 inputs = tokenizer("He was a puppeteer", return_tensors="pd") # 前向推理 sequence_output, pooled_output = model(**inputs) print(sequence_output.shape) # [batch_size, seq_len, hidden_size] print(pooled_output.shape) # [batch_size, hidden_size]

5.2 分词器行为

SqueezeBertTokenizer 采用与 BERT 一致的「BasicTokenizer + WordPieceTokenizer」两段式流程:先做标点切分与小写化(do_lower_case默认为True),再做 WordPiece 子词切分。文档示例:

from paddlenlp.transformers import SqueezeBertTokenizer tokenizer = SqueezeBertTokenizer.from_pretrained("squeezebert-uncased") tokens = tokenizer("He was a puppeteer") # 结果为 ['he', 'was', 'a', 'puppet', '##eer'] tokenizer.convert_tokens_to_string(tokens) # 结果为 'he was a puppeteer'

特殊 token 格式与 BERT 一致:单句为[CLS] X [SEP],句对为[CLS] A [SEP] B [SEP](见 build_inputs_with_special_tokens),并实现了create_token_type_ids_from_sequencesget_special_tokens_maskbuild_offset_mapping_with_special_tokens等完整接口,可直接对接 PaddleNLP 的 Trainer 训练流程。

六、下游任务实战示例

6.1 序列分类(基于 MNLI 权重)

squeezebert-mnli已带 3 分类头,可直接用于 MNLI 推理;也可以加载基础权重后接自定义分类器微调:

from paddlenlp.transformers import SqueezeBertForSequenceClassification # 加载 MNLI 微调权重(num_labels=3) model = SqueezeBertForSequenceClassification.from_pretrained("squeezebert-mnli") # 或在基础权重上微调自己的分类任务 model = SqueezeBertForSequenceClassification.from_pretrained( "squeezebert-uncased", num_labels=2 )

前向时模型内部取[CLS]位置的池化输出,经 Dropout 后送入nn.Linear(hidden_size, num_classes)得到[batch_size, num_classes]的 logits(见 SqueezeBertForSequenceClassification)。

6.2 抽取式问答

SqueezeBertForQuestionAnswering 在序列输出上接线性层,输出被拆分为start_logitsend_logits,对应答案区间的起止位置:

from paddlenlp.transformers import SqueezeBertForQuestionAnswering model = SqueezeBertForQuestionAnswering.from_pretrained("squeezebert-uncased") start_logits, end_logits = model(input_ids, token_type_ids) # start_logits / end_logits 形状均为 [batch_size, sequence_length]

6.3 词级分类(NER)

SqueezeBertForTokenClassification 在每个 token 的隐状态上接分类器,输出[batch_size, sequence_length, num_classes]的 logits,适用于命名实体识别等序列标注任务。

七、测试与验证

仓库提供了完整的单元测试,可用于验证模型与分词器行为:

  • tests/transformers/squeezebert/test_modeling.py:通过SqueezeBertModelTester构造小规模配置(如hidden_size=32num_hidden_layers=5num_attention_heads=4),覆盖SqueezeBertModelSqueezeBertForSequenceClassificationSqueezeBertForTokenClassificationSqueezeBertForQuestionAnswering四个模型类的前向与输出形状验证;
  • tests/transformers/squeezebert/test_tokenizer.py:验证分词器的切分、特殊 token 与还原逻辑。

此外,PaddleNLP 还通过 Sphinx 为 SqueezeBERT 生成了 API 文档(见 docs/zh/source/paddlenlp.transformers.squeezebert.rst 及其 modeling/tokenizer 子页面),其中以 automodule 方式索引了全部公开类与方法,可作为查阅 API 详情的入口。

八、总结

PaddleNLP 以 3 个官方预训练权重完整支持 SqueezeBERT 模型:squeezebert-uncased适合作为通用微调起点,squeezebert-mnli可直接用于自然语言推断,squeezebert-mnli-headless则适合追求灵活性的微调场景。三者均基于 12 层、768 维、12 头、约 51M 参数的统一架构。从源码看,SqueezeBERT 通过将 Q/K/V 与 FFN 中的线性层替换为 1×1 分组卷积,在保证 Transformer 表达能力的框架内显著压缩了参数量。配合 PaddleNLP 统一的from_pretrained接口与 Auto 体系,开发者可以用极少的代码完成加载、推理与下游任务微调。

【免费下载链接】PaddleNLPEasy-to-use and powerful LLM and SLM library with awesome model zoo.项目地址: https://gitcode.com/gh_mirrors/pa/PaddleNLP

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询