
深入解读 PLBARTTransformers 中面向程序理解与生成的统一预训练模型【免费下载链接】transformers Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformersPLBARTProgram and Language BART是一个基于 BART 架构的多语言 encoder-decoder 序列到序列模型专门面向代码摘要code summarization、代码生成code generation与代码翻译code translation等编程语言PL与自然语言NL互转任务。本文以 docs/source/en/model_doc/plbart.md 为主线结合本仓库中 configuration_plbart.py、tokenization_plbart.py、modeling_plbart.py 及对应测试全面讲解 PLBART 的模型原理、语言 ID 特殊 token 的构造与编码格式、有监督微调与生成推理的完整用法以及四类模型 Head 的实现细节。读完本文你将能够在 Transformers 生态中用uclanlp/plbart-*系列 checkpoint 完成 Python/Java 等代码与英文之间的翻译、摘要、补全任务并理解其输入输出格式为何与其他 BART 类模型不同。一、模型背景与定位PLBART 来自论文Unified Pre-training for Program Understanding and GenerationWasi Uddin Ahmad 等UCLA。它是一个类 BART 的序列到序列模型可用于代码摘要code summarization代码 → 自然语言描述代码生成code generation自然语言 → 代码代码翻译code translation一种编程语言 → 另一种编程语言或代码 ↔ 英文。预训练 checkpointplbart-base使用多语言去噪任务在 Java、Python 与英文文本上训练。模型通过去噪自编码denoising autoencoding学习大规模 Java/Python 函数及其关联 NL 文本论文实验表明除了生成类任务PLBART 在程序修复program repair、克隆检测clone detection、漏洞代码检测等判别式任务上也展现出程序理解能力。PLBART 由社区成员 gchhablani 贡献至 Transformers于 2022-02-18 合入仓库。从实现上看PLBART 完全复用 Transformers 的 BART 式分层结构encoder decoder 共享词嵌入但保留了一些与 fairseq 原版实现对齐的特殊设计这正是它和其他 BART 模型最不一样的地方。模型代码位于 src/transformers/models/plbart/由 modular_plbart.py 自动生成文件头声明该文件不得手工编辑。二、区别于一般 BART 模型的两个核心设计2.1 语言 ID token 与输入输出格式约定PLBART 是多语言模型期望输入带有特殊语言 ID tokenlanguage id token简称 以区分 Java、Python、英文等。与 MBart 等在序列最前面加语言 token 的做法不同PLBART 的 采用缀在末尾的方式组织源端格式X [eos, src_lang_code]其中X为源文本目标端格式[tgt_lang_code] X [eos]即解码器真正消费的序列以目标语言 ID 开头boss从不使用。在 tokenizer 内部这一约定通过special_tokens_patternprefix_suffix与空的prefix_tokens实现tokenization_plbart.py 中set_src_lang_special_tokens/set_tgt_lang_special_tokens都只设置suffix_tokens [eos_token_id, cur_lang_code]前缀为空。也就是说 tokenizer 物理输出均为X [eos][LID]而模型侧通过特殊的shift_tokens_right见下文 3.3 节在右移时将末尾的 挪到序列首部从而在解码器输入中得到[tgt_lang_code] X [eos]这一目标端形态保证教师强制teacher forcing与自回归生成视角下解码总是以目标语言 ID 起头。文档同时提醒微调时若只涉及单一语言可以不附加语言 token详见原论文。2.2 fairseq 词汇表对齐与 token 映射PLBART tokenizer 基于 SentencePiece模型文件为sentencepiece.bpe.model。为了与 fairseq 原版词汇表对齐PLBartTokenizer特意处理了 fairseq vocab 与 spm vocab 错位 的问题tokenization_plbart.py 的注释给出对齐示意——fairseq 前 4 个 tokens0, pad1, /s2, unk3spm 中unk却占第 0 位。因此 tokenizer 定义fairseq_tokens_to_ids {s: 0, pad: 1, /s: 2, unk: 3}并设置fairseq_offset 1SentencePiece 的真实子词从 spm ID 偏移后spm_id fairseq_offset映射为 fairseq 侧 ID_convert_token_to_id语言代码等保留 token 也会从 added-token 表中移除改为按 fairseq 语义统一管理从而保证权重能够正确加载、vocab_size与模型 lm_head 尺寸一致。注意 tokenizer 需要一个额外的特殊mask偏移base模式下vocab_size计算多1因为 PLBART 预训练时使用掩码去噪推理端lang_code_to_id与id_to_lang_code两表则用来在生成时定位目标语言 ID。三、PLBartTokenizer 用法详解加载 tokenizer 与设置源/目标语言from transformers import PLBartTokenizer tokenizer PLBartTokenizer.from_pretrained( uclanlp/plbart-base, src_langen_XX, tgt_langpython )src_lang与tgt_lang均会经FAIRSEQ_LANGUAGE_CODES_MAP归一化为特殊格式如python→__python__支持的语言与对应代码在源码中显式列出tokenization_plbart.py。language_codes 取值可用语言base__java__、__python__、__en_XX__multi在 base 之上增加__javascript__、__php__、__ruby__、__go__传入language_codesbase默认使用 base 版词汇表额外包含mask传入language_codesmulti则额外注册四个语言代码词汇表中不保留mask多语言下游任务不做掩码测试见 tests/models/plbart/test_tokenization_plbart.py。编码约定当把源文本作为第一个参数或以关键字text传入__call__时tokenizer 编码源端格式以text_target关键字传入目标文本时编码目标端格式。src_lang/tgt_lang还可用 setter 在运行时切换见src_langproperty 与prepare_seq2seq_batch。构造PLBartTokenizer的其他参数vocab_fileSentencePiece 词表路径bos_tokens、eos_token/s、sep_token/s、cls_tokens、unk_tokenunk、pad_tokenpad、mask_tokenmasklanguage_codesbase或multisp_model_kwargs透传给SentencePieceProcessor.__init__可用于启用 subword regularizationenable_sampling、nbest_size、alpha实现细节与 BART 一致。四、架构与配置PLBartConfig 全参数PLBartConfig的核心默认值定义在 configuration_plbart.py对应uclanlp/plbart-basecheckpoint配置项默认值说明vocab_size50005词表大小含 4 个基础 token、语言代码与 maskmax_position_embeddings1024最大位置编码长度d_model/hidden_size768隐藏层维度encoder_layers/decoder_layers6 / 6编码器/解码器层数encoder_ffn_dim/decoder_ffn_dim3072 / 3072FFN 中间维度encoder_attention_heads/decoder_attention_heads12 / 12注意力头数activation_functiongeluFFN 激活函数dropout/attention_dropout0.1 / 0.1全连接/注意力 dropoutactivation_dropout0.0FFN 激活后 dropoutencoder_layerdrop/decoder_layerdrop0.0 / 0.0LayerDrop 比例init_std0.02权重初始化标准差scale_embeddingTrue是否按 √d_model 缩放词嵌入classifier_dropout0.0分类头 dropoutpad_token_id/bos_token_id/eos_token_id1 / 0 / 2特殊 token IDforced_eos_token_id2强制结束符 ID生成必带/sis_encoder_decoder/is_decoderTrue / Falseseq2seq 架构标记tie_word_embeddingsTruelm_head 与输入嵌入权重共享use_cacheTrue生成时启用 KV 缓存此外attribute_map将num_attention_heads → encoder_attention_heads、hidden_size → d_model等通用命名映射到 PLBART 命名兼容其他 BART 类模型的加载约定。直接以默认配置初始化模型from transformers import PLBartConfig, PLBartModel configuration PLBartConfig() model PLBartModel(configuration) # 随机权重模型内部实现要点从 modeling_plbart.py 的结构看PLBART 保留了 BART 家族特有的几个机制缩放词嵌入PLBartScaledWordEmbedding在nn.Embedding输出上乘以embed_scale当config.scale_embeddingTrue时embed_scale sqrt(d_model)见 modeling_plbart.py 与 modeling_plbart.py这一点需与 fairseq 训练保持一致可学习位置嵌入PLBartLearnedPositionalEmbedding固定加offset2再查表modeling_plbart.py保证 pad 占位与 BART 一致注意力后端可插拔PLBartPreTrainedModel声明了_supports_flash_attn True、_supports_sdpa True、_supports_flex_attn Truemodeling_plbart.py并在PLBartAttention.forward中通过ALL_ATTENTION_FUNCTIONS.get_interface(...)按config._attn_implementation分发到 eager / FlashAttention / SDPA / FlexAttention 实现——这也解释了官方模型页上的 FlashAttention 与 SDPA 徽章梯度检查点Encoder/Decoder 层继承GradientCheckpointingLayer_no_split_modules为[PLBartDecoderLayer, PLBartEncoderLayer]便于超大模型分布式切分。五、监督训练text-to-code 与 code-to-text有监督微调直接把源文本与目标文本交给 tokenizer 即可模型需预先加载到 devicefrom transformers import PLBartTokenizer, PLBartForConditionalGeneration import torch model PLBartForConditionalGeneration.from_pretrained( uclanlp/plbart-base ).to(cuda) tokenizer PLBartTokenizer.from_pretrained( uclanlp/plbart-base, src_langen_XX, tgt_langpython ) example_python_phrase def maximum(a,b,c):NEW_LINE_INDENTreturn max([a,b,c]) expected_translation_english Returns the maximum value of a b c. inputs tokenizer( example_python_phrase, text_targetexpected_translation_english, return_tensorspt, ).to(model.device) model(**inputs)要点示例中 Python 代码里出现的NEW_LINE_INDENT是预训练数据处理阶段使用的换行/缩进占位符源码文本中直接原样包含它们即可传入text_target后 tokenizer 会切换到目标端模式构建目标序列的 token 与labels若需要计算 loss可额外传labelsshape(batch_size, seq_len)-100的位置被忽略。当labels给出且未提供decoder_input_ids时PLBartForConditionalGeneration.forward会用shift_tokens_right(labels, pad_token_id)自动构造解码器输入见 modeling_plbart.py。3.x 附录shift_tokens_right的特殊性PLBART 没有像其他 BART 类模型那样使用统一decoder_start_token_id。其辅助函数 shift_tokens_right 的逻辑是克隆标签序列 → 把-100替换成pad_token_id→ 取每行最后一个非 pad token正是被缀在序列末尾的 放到首位其余 token 整体右移一位。因此解码器的第一个 token 天然就是目标语言 ID这一点与文档所述目标格式[tgt_lang_code] X [eos]一致也是推理时必须用decoder_start_token_id语言ID的原因。六、生成推理Python → English 翻译实战PLBartForConditionalGeneration继承GenerationMixin可直接用generate解码。生成目标文本时必须把decoder_start_token_id设为目标语言 ID官方示例使用uclanlp/plbart-python-en_XX在 Python 与英文上微调过的翻译模型from transformers import PLBartForConditionalGeneration, PLBartTokenizer tokenizer PLBartTokenizer.from_pretrained( uclanlp/plbart-python-en_XX, src_langpython, tgt_langen_XX ) example_python_phrase def maximum(a,b,c):NEW_LINE_INDENTreturn max([a,b,c]) inputs tokenizer(example_python_phrase, return_tensorspt).to(model.device) model PLBartForConditionalGeneration.from_pretrained( uclanlp/plbart-python-en_XX, device_mapauto ) translated_tokens model.generate( **inputs, decoder_start_token_idtokenizer.lang_code_to_id[en_XX] ) tokenizer.batch_decode(translated_tokens, skip_special_tokensTrue)[0] # Returns the maximum value of a b c.代码解读src_langpython、tgt_langen_XX指定源/目标语言tokenizer 据此把__python__/__en_XX__附加到对应序列tokenizer.lang_code_to_id[en_XX]返回英文语言 ID该字典在 tokenizer 构造时按sp_model 大小 fairseq_offset 语言下标生成如 docstring 所注对plbart-base大约对应 50003 等高位 ID作为decoder_start_token_id使解码从英文 LID 起头目标语言有单语言场景下也可不附加 LIDmodel.generate(**inputs)同样可用test_base_generate等测试正是用decoder_start_token_idself.tokenizer.lang_code_to_id[src_lan]验证的。仓库对应测试集中在 tests/models/plbart/test_modeling_plbart.py如test_java_cs_generate_one、test_java_cs_generate_batch、test_base_generate、test_sample_generate与 tests/models/plbart/test_tokenization_plbart.py可作为理解与验证格式约定的第一手资料。七、四种模型 Head从 seq2seq 到分类与纯解码Transformers 仓库按用途提供了多套 PLBART 入口均可通过from transformers import ...直接使用PLBartModel无 Head 的裸 encoder-decoder 模型输出Seq2SeqModelOutput含last_hidden_state、past_key_values、decoder_attentions、cross_attentions与编码器侧各字段。值得注意的是它的 forward 会在未提供decoder_input_ids时自动用shift_tokens_right从input_ids生成modeling_plbart.py因此可直接跑 denoising 预训练式的前向。PLBartForConditionalGenerationseq2seq 主模型PLBartModel之上叠加lm_head线性层与输入嵌入共享权重与final_logits_biasnn.Buffer。若labels未提供而decoder_input_ids未给会默认按shift_tokens_right生成解码器输入以支持去噪提供了labels则计算交叉熵损失并返回Seq2SeqLMOutput。若扩展词表需调用resize_token_embeddings它会同步_resize_final_logits_bias以维持偏置形状。PLBartForSequenceClassification用于程序理解类判别任务。在PLBartModel之上挂PLBartClassificationHeadDense → tanh → dropout → 分类线性层分类特征取自输入序列最后一个eos对应的隐状态modeling_plbart.py因此要求每个样本至少包含一个/stoken。labels支持回归num_labels1走 MSE、单标签分类与多标签分类自动推断problem_type对应可复现论文中 clone detection、vulnerable code detection 这类理解型任务。PLBartForCausalLM纯解码器版语言模型。构造时会改写config.is_decoderTrue、config.is_encoder_decoderFalse内部使用PLBartDecoderWrapper包装 decoder并叠加与解码器词嵌入共享权重的lm_headmodeling_plbart.py。它也可以在EncoderDecoderModel框架中作为解码器使用。例如从uclanlp/plbart-base直接加载后对一段文本做条件语言建模docstring 内给出PLBartForCausalLM的完整示例。八、可迁移参考的任务指南PLBART 覆盖的几类典型任务在仓库中均有对应的端到端任务指南与本模型正交、按AutoModel*通用接口组织可直接迁移文本分类任务指南因果语言建模任务指南翻译任务指南摘要任务指南九、使用注意事项小结语言 ID 必须正确src_lang/tgt_lang只接受java、python、en_XXbase或扩展的javascript、php、ruby、gomulti大小写与映射见FAIRSEQ_LANGUAGE_CODES_MAP推理显式给解码起点跨语言生成务必设置decoder_start_token_idtokenizer.lang_code_to_id[tgt]单语言微调场景可省略bos不参与序列构建不要手动拼接stokenizer 的prefix_suffix模式会自动只追加[eos][LID]数据集预处理占位符代码文本中的换行/缩进占位符如NEW_LINE_INDENT需要与训练语料一致地保留注意力后端默认支持 eager 与 SDPA开启 FlashAttention 时需满足模型页面标注的能力约束与硬件前提以上 checkpoint、参数取值与调用方式均以本仓库实现为准实际使用以from_pretrained拉取到的 Hub 配置为准。【免费下载链接】transformers Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考