PaddleNLP ERNIE-CTM 模型详解:基于 content summary 的多任务中文预训练模型实现与使用指南
2026/9/24 14:15:44 网站建设 项目流程

PaddleNLP ERNIE-CTM 模型详解:基于 content summary 的多任务中文预训练模型实现与使用指南

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

ERNIE-CTM(ERNIE for Chinese Token-level Modeling)是 PaddleNLP 中针对中文词级/字级细粒度语言建模设计的预训练模型系列,通过引入多个[CLS]摘要占位符(content summary token)机制,让模型在序列标注类任务(如命名实体识别 NER、词边界标注 wordtag、命名短语标注 nptag)上同时兼顾全局语义与局部词法信息。本文以 docs/zh/source/paddlenlp.transformers.ernie_ctm.rst 所定义的 API 文档结构为骨架,结合 paddlenlp/transformers/ernie_ctm 模块的完整源码与 tests/transformers/ernie_ctm/test_modeling.py 测试用例,系统讲解其配置类、基础模型、三类下游任务模型与专用分词器的实现原理和调用方式,读完即可在 PaddleNLP 中完成 ERNIE-CTM 的加载、推理与微调。

一、ERNIE-CTM 模块总览与文件布局

该 RST 文档是 PaddleNLP 中文 API 文档体系中的标准 autodoc 页面,它定义了paddlenlp.transformers.ernie_ctm这一顶层模块的公开文档结构,并通过toctree将内容划分为两个子页面:

  • paddlenlp.transformers.ernie_ctm.modeling:模型结构(modeling)
  • paddlenlp.transformers.ernie_ctm.tokenizer:分词器(tokenizer)

对应的实际源码位于 paddlenlp/transformers/ernie_ctm 目录,包含四个文件:

文件职责
configuration.py定义ErnieCtmConfig配置类、默认超参与预训练模型资源映射
modeling.py实现ErnieCtmEmbeddingsErnieCtmPoolerErnieCtmModel以及三类任务模型
tokenizer.py实现ErnieCtmTokenizer,支持多个[CLS]占位符的输入构造
init.py模块包声明

modeling.py__all__导出五个公开类(modeling.py 第 43-49 行):

ErnieCtmPretrainedModel ErnieCtmModel ErnieCtmWordtagModel ErnieCtmNptagModel ErnieCtmForTokenClassification

tokenizer.py仅导出ErnieCtmTokenizer(tokenizer.py 第 20 行)。整个模块同时被 paddlenlp/transformers/auto 的自动加载机制登记,可通过模型名直接from_pretrained加载。

二、ErnieCtmConfig:架构配置与预训练资源

ErnieCtmConfig继承自PretrainedConfig(位于 paddlenlp/transformers/configuration_utils.py),model_type"ernie-ctm"。其默认配置定义在模块级常量ERNIE_CTM_CONFIG(configuration.py 第 27-44 行):

配置项默认值说明
vocab_size23000词表大小,决定 token embedding 矩阵规模
embedding_size128词嵌入维度(区别于hidden_size,后续通过线性映射升维)
hidden_size768Encoder 层与 Pooler 层维度
num_hidden_layers12Transformer Encoder 层数
num_attention_heads12每层注意力头数
intermediate_size3072FFN 中间层维度
hidden_dropout_prob0.1Embedding 与 Encoder 全连接层 dropout
attention_probs_dropout_prob0.1注意力概率 dropout
max_position_embeddings512最大序列长度
type_vocab_size2segment id 词表大小
layer_norm_eps1e-12LayerNorm 的 epsilon
initializer_range0.02权重初始化标准差
pad_token_id0padding token 的 id
use_content_summaryTrue是否启用 content summary token 机制
content_summary_index1content summary token 在序列中的位置(即第二个[CLS],索引 1)
cls_num2模型使用的[CLS]占位符数量
num_prompt_placeholders5解码阶段 prompt 答案的最大长度
prompt_vocab_idsNone解码过程的 prompt 词表集合

其中embedding_sizehidden_size分离是 ERNIE-CTM 的显著特点:Embedding 层只有 128 维,送入 Encoder 前先经embedding_hidden_mapping_in线性层映射到 768 维,从而在不牺牲模型容量的前提下显著压缩嵌入参数量。

此外配置类还提供了attribute_mapnum_tag → num_labelsdropout → classifier_dropout等),保证与 PaddleNLP 通用任务头接口的兼容性(configuration.py 第 109 行)。

预训练资源映射ERNIE_CTM_PRETRAINED_RESOURCE_FILES_MAP(configuration.py 第 53-59 行)与分词器侧(tokenizer.py 第 76-88 行)共同定义了三个可加载的预训练模型名:

  • ernie-ctm:通用基础模型(ernie_ctm_v3.pdparams
  • wordtag:词边界/词性标注任务模型(wordtag_v3.pdparams
  • nptag:命名短语标注任务模型(nptag_v3.pdparams

三者共享同一份ERNIE_CTM_CONFIG默认架构与同一个vocab.txt词表,最大输入长度均为 512(PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES)。

三、ErnieCtmModel:带 content summary 的基础编码器

3.1 类继承与初始化

ErnieCtmModel继承自ErnieCtmPretrainedModel,后者通过类属性声明了资源文件命名与预训练配置(modeling.py 第 146-162 行):

  • model_config_file = "model_config.json"resource_files_names = {"model_state": "model_state.pdparams"}
  • base_model_prefix = "ernie_ctm"
  • 权重初始化_init_weights对 Linear/Embedding 使用initializer_range标准差的高斯初始化,对 LayerNorm 将 epsilon 设为 1e-12

模型内部结构(modeling.py 第 245-275 行)由四部分组成:

  1. ErnieCtmEmbeddings:word / position / token_type 三类 embedding 相加后过 LayerNorm 与 Dropout;
  2. embedding_hidden_mapping_in:把 128 维嵌入映射到 768 维隐藏层;
  3. nn.TransformerEncoder:12 层标准 Transformer,激活函数为GELU(approximate=True)
  4. ErnieCtmPooler:取序列第一个 token([CLS0])的隐藏状态,经 Linear + Tanh 得到句级表示。

3.2 特殊的 position ids 构造

ErnieCtmEmbeddings.forward(modeling.py 第 100-126 行)体现了多个[CLS]占位符的定位策略:当未显式传入position_ids时,前cls_num个位置(即所有[CLS]占位符)位置编码为 0,正文 token 则从 1 开始用linspace连续编号,保证摘要位与正文位的相对距离明确。

3.3 content summary 机制与输出

这是 ERNIE-CTM 的核心设计。在forward中(modeling.py 第 428-452 行):

  1. content_output = sequence_output[:, self.content_summary_index],即取content_summary_index=1位置(第二个[CLS],对应[CLS1])的隐藏状态作为全局内容摘要;
  2. content_output沿序列维扩展,与原sequence_output在最后一维拼接,得到hidden_size * 2维;
  3. 依次通过feature_fuse(Linear:hidden_size*2 → intermediate_size)与feature_output(Linear:intermediate_size → hidden_size)完成特征融合,把全局摘要信息逐 token 地注入序列表示。

该机制同时支持content_clone参数:置为 True 时直接用序列表示克隆内容摘要,用于避免分类任务对序列标注任务产生干扰。返回值(return_dict=True时)为ErnieCtmModelOutput(modeling.py 第 52-83 行):

  • last_hidden_state:融合了 content summary 的最后一层序列输出,形状[batch, seq_len, hidden_size]
  • pooler_output[CLS0]经 Pooler 的句级表示,形状[batch, hidden_size]
  • content_output[CLS1]的内容摘要表示,形状[batch, hidden_size]
  • 可选hidden_statesattentions

attention_mask缺省时自动以pad_token_id位置填充-1e4构建掩码(modeling.py 第 397-400 行),2D 掩码也会被自动扩展为 4D。

四、三类下游任务模型

基于ErnieCtmModel,模块提供了三种任务头,分别面向词法级与序列标注场景。

4.1 ErnieCtmWordtagModel:CRF 词边界/词性标注

ErnieCtmWordtagModel(modeling.py 第 470-600 行)在基础模型之上叠加:

  • tag_classifierLinear(hidden_size, num_tag)生成逐 token 标签 logits;
  • LinearChainCrfLinearChainCrfLoss:来自 paddlenlp/layers/crf.py 的线性链 CRF,with_start_stop_tag=False
  • ViterbiDecoder:Paddle 2.2.0 及以上使用paddle.text.ViterbiDecoder,否则回退到paddlenlp.layers.crf.ViterbiDecoder(modeling.py 第 35-39 行)。

训练与推理路径(forward,modeling.py 第 583-593 行):

  • 训练:传入tag_labels时,loss = CRF loss + token 级交叉熵之和;
  • 推理:不传标签时,使用viterbi_decoder输出全局最优标签序列,返回seq_logits
  • lengths缺省时按input_ids != pad_token_id自动统计各样本有效长度,供 CRF 处理变长序列。

4.2 ErnieCtmNptagModel:MLM 头命名短语标注

ErnieCtmNptagModel(modeling.py 第 626-723 行)由基础模型加ErnieCtmMLMHead构成,用于命名短语标注(nptag)任务。ErnieCtmMLMHead(modeling.py 第 603-623 行)的结构为:

Linear(hidden_size → embedding_size) → GELU → LayerNorm → Linear(embedding_size → vocab_size)

即先降回 128 维嵌入空间再映射到 23000 维词表,输出形状[batch, seq_len, vocab_size],等价于对每个 token 做掩码词预测(MLM),从而支持在[MASK]位“填空”式地预测命名短语。传入labels时返回交叉熵 loss。

4.3 ErnieCtmForTokenClassification:通用 token 分类

ErnieCtmForTokenClassification(modeling.py 第 726-830 行)提供了与 HuggingFace 风格一致的通用 token 分类接口:基础模型输出先过Dropout(默认复用hidden_dropout_prob,支持classifier_dropout覆盖),再经Linear(hidden_size, num_labels)分类器,返回TokenClassifierOutput。适用于 NER 等需要逐 token 多分类、但不依赖 CRF 约束的场景。

五、ErnieCtmTokenizer:多 [CLS] 占位符分词器

ErnieCtmTokenizer继承自PretrainedTokenizer(paddlenlp/transformers/tokenizer_utils.py),构造函数的关键参数(tokenizer.py 第 90-112 行):

参数默认值说明
vocab_file必填词表文件路径
do_lower_caseTrue是否小写化输入
do_basic_tokenizeTrue是否先做基础分词再做 WordPiece
cls_token_template"[CLS{}]"多摘要占位符的 token 模板
cls_num1[CLS]占位符数量(预训练配置中为 2)
unk_token/sep_token/pad_token/mask_token[UNK]/[SEP]/[PAD]/[MASK]标准特殊 token

其分词逻辑_tokenize(tokenizer.py 第 266-282 行)面向中文按单字切分(字符级),可配置小写化——这与中文词法任务的字级建模方式一致。

5.1 多 [CLS] 的输入构造

build_inputs_with_special_tokens(tokenizer.py 第 150-174 行)定义了 ERNIE-CTM 的序列格式:

单句: [CLS0][CLS1]... X [SEP] 句对: [CLS0][CLS1]... X [SEP] X [SEP]

其中cls_token_ids通过cls_token_template.format(sid)(即[CLS0][CLS1]…)逐个生成,数量等于cls_num。相应地,num_special_tokens_to_add在单句时为cls_num + 1、句对时为cls_num + 2(tokenizer.py 第 245-264 行)。

create_token_type_ids_from_sequences(tokenizer.py 第 206-243 行)把前cls_num[CLS]与第一段都标记为 segment 0,第二段标记为 segment 1。由于ErnieCtmEmbeddings的默认position_ids将前cls_num位置编码为 0,分词器与模型在占位符数量上必须保持cls_num一致,加载ernie-ctm/wordtag/nptag时默认即为 2。

5.2 反序列化与转换

convert_tokens_to_string(tokenizer.py 第 124-148 行)在拼接字符串时移除 WordPiece 的##前缀(中文场景主要用于处理词表内可能出现的子词),get_special_tokens_mask则为[CLS][SEP]返回 1、正文 token 返回 0。

六、端到端使用示例

6.1 加载基础模型并获取三路输出

import paddle from paddlenlp.transformers import ErnieCtmModel, ErnieCtmTokenizer tokenizer = ErnieCtmTokenizer.from_pretrained("ernie-ctm") model = ErnieCtmModel.from_pretrained("ernie-ctm") inputs = tokenizer("Welcome to use PaddlePaddle and PaddleNLP!") inputs = {k: paddle.to_tensor([v]) for k, v in inputs.items()} sequence_output, pooled_output, content_output = model(**inputs) # sequence_output: [1, seq_len, 768] # pooled_output: [1, 768] (来自 [CLS0]) # content_output: [1, 768] (来自 [CLS1])

6.2 词边界标注(wordtag)

from paddlenlp.transformers import ErnieCtmWordtagModel, ErnieCtmTokenizer tokenizer = ErnieCtmTokenizer.from_pretrained("wordtag") model = ErnieCtmWordtagModel.from_pretrained("wordtag", num_tag=2) inputs = tokenizer("Welcome to use PaddlePaddle and PaddleNLP!") inputs = {k: paddle.to_tensor([v]) for k, v in inputs.items()} logits = model(**inputs) # 推理时内部走 Viterbi 解码,返回标签序列

6.3 命名短语标注(nptag)

from paddlenlp.transformers import ErnieCtmNptagModel, ErnieCtmTokenizer tokenizer = ErnieCtmTokenizer.from_pretrained("nptag") model = ErnieCtmNptagModel.from_pretrained("nptag") inputs = tokenizer("Welcome to use PaddlePaddle and PaddleNLP!") inputs = {k: paddle.to_tensor([v]) for k, v in inputs.items()} logits = model(**inputs) print(logits.shape) # [1, seq_len, 23000],逐 token 在词表上打分

6.4 通用 token 分类微调接口

from paddlenlp.transformers import ErnieCtmForTokenClassification, ErnieCtmTokenizer tokenizer = ErnieCtmTokenizer.from_pretrained("ernie-ctm") model = ErnieCtmForTokenClassification.from_pretrained("ernie-ctm", num_labels=7) inputs = tokenizer("Welcome to use PaddlePaddle and PaddleNLP!") inputs = {k: paddle.to_tensor([v]) for k, v in inputs.items()} logits = model(**inputs) # [1, seq_len, 7]

七、测试验证与工程细节

仓库为 ERNIE-CTM 提供了完整的单元测试 tests/transformers/ernie_ctm/test_modeling.py(共 385 行)。ErnieCtmModelTester使用小规模配置(vocab_size=100hidden_size=16num_hidden_layers=2等)覆盖ErnieCtmConfig的全部超参,并通过ModelTesterMixin验证ErnieCtmModelErnieCtmWordtagModelErnieCtmNptagModelErnieCtmForTokenClassification四个模型的前向、反向与输出形状;同时通过ConfigTester校验配置对象的序列化、属性映射与默认值。

工程实现上还有两点值得注意:

  1. Paddle 版本兼容paddle.text.ViterbiDecoder需要 Paddle 2.2.0 及以上,旧版本自动回退到paddlenlp.layers.crf.ViterbiDecoder(modeling.py 第 35-39 行);
  2. 标签参数兼容ErnieCtmWordtagModel.forward同时接受tag_labelslabels两种命名(modeling.py 第 560-561 行),便于与 Trainer 等高层 API 对齐。

八、总结

ERNIE-CTM 在 PaddleNLP 中的实现围绕"多[CLS]摘要占位符 + content summary 特征融合"这一核心机制展开:ErnieCtmTokenizer负责构造[CLS0][CLS1]... X [SEP]形式的输入,ErnieCtmModel将第二个[CLS]的全局表示逐 token 注入序列输出,而ErnieCtmWordtagModel(CRF 词边界)、ErnieCtmNptagModel(MLM 短语填空)、ErnieCtmForTokenClassification(通用序列标注)三个任务头则把该表示应用于具体的中文词法任务。开发者可通过ernie-ctmwordtagnptag三个预训练模型名直接体验,或基于ErnieCtmForTokenClassification在自有数据集上微调,实现词级细粒度语义建模。

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

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

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

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

立即咨询