- 人工智能
- 大模型
- NLP
- 深度学习
- 预训练
- 微调
- RLHF
- 模型量化
【免费下载链接】PaddleNLP
Easy-to-use and powerful LLM and SLM library with awesome model zoo.
RoFormer 是苏剑林提出的一种将**旋转位置编码(Rotary Position Embedding, RoPE)**引入 Transformer 的预训练语言模型,在 PaddleNLP 中提供了中英文多规格的预训练权重与完整的建模实现。本文基于docs/en/model_zoo/transformers/RoFormer/contents.rst的模型清单展开,并结合 configuration.py、modeling.py、tokenizer.py 及 tests/transformers/roformer 测试用例,逐项讲解每个预训练权重的结构参数、RoFormer-S 生成模型的训练配置,以及旋转位置编码在多头注意力中的底层实现,帮助你完成从模型选型到直接调用的全流程。
一、RoFormer 预训练权重总览
PaddleNLP 当前共支持 10 个 RoFormer 预训练权重,覆盖中文(词级 / 字级 / 相似度微调变体)与英文(判别器 / 生成器)两类场景。下表汇总了每个权重对应的预训练权重名称、语言以及模型结构细节:
| 预训练权重 | 语言 | 模型详情 |
|---|---|---|
roformer-chinese-small | 中文 | 6 层、384 隐藏维、6 头注意力,约 30M 参数,RoFormer 中文 Small 模型 |
roformer-chinese-base | 中文 | 12 层、768 隐藏维、12 头注意力,约 124M 参数,RoFormer 中文 Base 模型 |
roformer-chinese-char-small | 中文 | 6 层、384 隐藏维、6 头注意力,约 15M 参数,RoFormer 中文 Char(字级)Small 模型 |
roformer-chinese-char-base | 中文 | 12 层、768 隐藏维、12 头注意力,约 95M 参数,RoFormer 中文 Char(字级)Base 模型 |
roformer-chinese-sim-char-ft-small | 中文 | 12 层、768 隐藏维、12 头注意力,约 95M 参数,RoFormer 中文相似度微调字级 Ft Small 模型 |
roformer-chinese-sim-char-ft-base | 中文 | 12 层、768 隐藏维、12 头注意力,约 95M 参数,RoFormer 中文相似度微调字级 Ft Base 模型 |
roformer-chinese-sim-char-small | 中文 | 12 层、768 隐藏维、12 头注意力,约 95M 参数,RoFormer 中文相似度字级 Small 模型 |
roformer-chinese-sim-char-base | 中文 | 12 层、768 隐藏维、12 头注意力,约 95M 参数,RoFormer 中文相似度字级 Base 模型 |
roformer-english-small-discriminator | 英文 | 12 层、256 隐藏维、4 头注意力,约 13M 参数,RoFormer 英文 Small 判别器 |
roformer-english-small-generator | 英文 | 12 层、256 隐藏维、4 头注意力,约 13M 参数,RoFormer 英文 Small 生成器 |
注:
roformer-chinese-sim-char-*系列为在相似度任务上进一步微调(fine-tuned)的字级模型,pool_act被设置为linear,并定义了eos_token_id(见下文源码解析)。
这些权重的加载入口统一通过RoFormerModel.from_pretrained(...)自动完成,其对应的初始化配置与权重下载映射定义在 configuration.py 的ROFORMER_PRETRAINED_INIT_CONFIGURATION与ROFORMER_PRETRAINED_RESOURCE_FILES_MAP中;词表文件(vocab.txt)的下载映射则定义在 tokenizer.py。
二、各预训练权重的精确配置参数(源码级)
原文档的模型详情表是"层数/隐藏维/头数/参数量"级别的概览,而每个权重在仓库中都有精确到每个超参数的初始化配置。以下内容直接来源于 configuration.py 的ROFORMER_PRETRAINED_INIT_CONFIGURATION,可在from_pretrained时自动生效:
| 配置项 | chinese-small | chinese-base | char-small | char-base | sim-char-ft-base | sim-char-base | english-small-discriminator | english-small-generator |
|---|---|---|---|---|---|---|---|---|
vocab_size | 50000 | 50000 | 12000 | 12000 | 12000 | 12000 | 30522 | 30522 |
embedding_size | 384 | 768 | 384 | 768 | 768 | 768 | 128 | 128 |
hidden_size | 384 | 768 | 384 | 768 | 768 | 768 | 256 | 64 |
num_hidden_layers | 6 | 12 | 6 | 12 | 12 | 12 | 12 | 12 |
num_attention_heads | 6 | 12 | 6 | 12 | 12 | 12 | 4 | 1 |
intermediate_size | 1536 | 3072 | 1536 | 3072 | 3072 | 3072 | 1024 | 256 |
hidden_act | gelu | gelu | gelu | gelu | gelu | gelu | gelu | gelu |
max_position_embeddings | 512 | 1536 | 512 | 512 | 512 | 512 | 128 | 128 |
type_vocab_size | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
initializer_range | 0.02 | 0.02 | 0.02 | 0.02 | 0.02 | 0.02 | 0.02 | 0.02 |
pad_token_id | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
rotary_value | False | False | False | False | False | False | True | True |
eos_token_id | - | - | - | - | 102 | 102 | - | - |
pool_act | tanh | tanh | tanh | tanh | linear | linear | tanh | tanh |
从表中可以读出几个关键差异:
- 词级 vs 字级:
roformer-chinese-small/base的vocab_size为 50000(词级,配合 jieba 分词);char系列vocab_size为 12000(字级,无需 jieba)。 - 英文小模型:
roformer-english-small-discriminator的hidden_size=256、4 头;roformer-english-small-generator的hidden_size=64、1 头,两者rotary_value=True,即对 Value 也施加旋转位置编码;其max_position_embeddings仅为 128,对应原文档"上下文窗口 512/128"的限制。 roformer-chinese-base是唯一支持 1536 长上下文的模型(max_position_embeddings=1536),其余中文模型为 512。- 相似度微调系列(
sim-char-*)设置了eos_token_id=102与pool_act="linear",这与它们作为生成/相似度模型的特殊用途有关。
RoFormerConfig 参数说明
RoFormerConfig继承自PretrainedConfig,在 configuration.py 中定义,核心构造参数及默认值如下:
| 参数 | 默认值 | 说明 |
|---|---|---|
vocab_size | 30522 | 词表大小,决定input_ids可表示的 token 数 |
embedding_size | 768 | 词嵌入维度(默认与hidden_size一致,若不同则自动插入embeddings_project投影层) |
hidden_size | 768 | 编码器层与池化层的维度 |
num_hidden_layers | 12 | Transformer 编码器层数 |
num_attention_heads | 12 | 每层注意力头数 |
intermediate_size | 3072 | FFN 中间层维度 |
hidden_act | "gelu" | 编码器与池化层激活函数,支持"gelu"、"relu"、"silu"、"gelu_new" |
hidden_dropout_prob | 0.1 | 全连接层 dropout 概率 |
attention_probs_dropout_prob | 0.1 | 注意力权重 dropout 概率 |
max_position_embeddings | 1536 | 最大序列长度 |
type_vocab_size | 2 | token_type_ids的段 ID 词表大小 |
initializer_range | 0.02 | 权重初始化截断正态分布标准差 |
layer_norm_eps | 1e-12 | LayerNorm 的 epsilon |
pad_token_id | 0 | padding token 的 id |
eos_token_id | 102 | eos token 的 id |
pool_act | "tanh" | 池化层激活函数 |
rotary_value | False | 是否对 Value 施加旋转位置编码 |
model_type = "roformer",并通过attribute_map将dropout映射到classifier_dropout、num_classes映射到num_labels,便于与通用训练框架对接。
三、RoFormer-S 英文小型生成模型:完整训练配置
原文档针对英文场景的 RoFormer-S(即roformer-english-small-generator所对应的开源配置)给出了一张完整的训练配置表,现完整保留并整理如下:
| 配置项 | 参数 | 说明 |
|---|---|---|
| Layers / Hidden / Heads | 12 / 64 / 1 | 12 层 Transformer、64 维隐藏层、1 个注意力头 |
| Parameters | 5M | 总参数量约 5 百万 |
| Architecture | RoFormer-S | 基于旋转位置编码的小型生成式架构,适用于英文场景 |
| Training Data | OpenWebText | 基于公开网络文本(约 40GB)进行预训练 |
| Training Steps | 100k | 在 8xV100 GPU 上训练约 10 万步 |
| Batch Size | 128 | 每步处理 128 个样本 |
| Context Window | 512 | 支持最大 512 个 token 的上下文窗口 |
| Optimizer | AdamW | 使用 AdamW 优化器,学习率 5e-5,权重衰减 0.01 |
| License | Apache 2.0 | 模型权重遵循 Apache 2.0 协议 |
| Recommended Use | Text Generation | 适用于开放域文本生成、问答、摘要等任务 |
| Limitations | 512 tokens | 受限于上下文长度,可能无法处理超长文本 |
| Ethical Considerations | - | 可能生成存在偏见或不准确内容,需谨慎使用 |
该表中的大部分超参数可以在仓库配置中找到对应实现:roformer-english-small-generator的hidden_size=64、num_attention_heads=1与"12/64/1"完全一致(见 configuration.py);在 modeling.py 中,RoFormerForCausalLM提供了从左到右的语言建模(next token prediction)头,配合prepare_inputs_for_generation与update_model_kwargs_for_generation方法(modeling.py),即构成"文本生成"推荐用途的推理链路。
四、架构与源码级原理:旋转位置编码如何融入多头注意力
RoFormer 的核心创新在于用**旋转位置编码(RoPE)**替代传统 Transformer 的绝对位置嵌入。在 PaddleNLP 的 modeling.py 中,这条链路由三个组件构成:
1.RotaryPositionEmbedding(旋转位置编码层)
定义于 modeling.py:
class RotaryPositionEmbedding(nn.Layer): def __init__(self, dim, max_position_embeddings=512): super().__init__() inv_freq = 1.0 / (10000 ** (paddle.arange(0, dim, 2, dtype=paddle.get_default_dtype()) / dim)) t = paddle.arange(max_position_embeddings, dtype=paddle.get_default_dtype()) freqs = paddle.matmul(t.unsqueeze(1), inv_freq.unsqueeze(0)) self.register_buffer("sin", freqs.sin(), persistable=False) self.register_buffer("cos", freqs.cos(), persistable=False)实现要点:
- 频率计算:
inv_freq = 1 / (10000^(2i/dim)),与原始 RoPE 论文一致,即沿维度方向从高频到低频递减的旋转角频率; - 预计算 sin/cos 表:对位置
t与频率做外积后一次性预计算sin、cos缓冲,max_position_embeddings决定了位置表长度; - 旋转操作(
forward):输入形状为[batch_size, num_heads, seqlen, head_dim],将最后一维按奇偶下标拆分为x1, x2,执行二维旋转:
x1, x2 = x[..., 0::2], x[..., 1::2] return paddle.stack([x1 * cos - x2 * sin, x1 * sin + x2 * cos], axis=-1).flatten(-2, -1)这对应矩阵形式[cos_nθ, -sin_nθ; sin_nθ, cos_nθ] · [x1, x2]ᵀ,即对每个位置施加与位置 n 相关的旋转,使得相对位置信息被内嵌进点积注意力中,这也是 RoFormer 无需可学习位置嵌入表的原因。
2.MultiHeadAttentionWithRotary(带旋转的注意力)
定义于 modeling.py,继承nn.MultiHeadAttention并注入旋转位置编码:
class MultiHeadAttentionWithRotary(nn.MultiHeadAttention): def __init__(self, embed_dim, num_heads, dropout=0.0, kdim=None, vdim=None, need_weights=False, rotary_value=False, max_position_embeddings=512): super().__init__(embed_dim, num_heads, dropout, kdim, vdim, need_weights) self.rotary_value = rotary_value self.rotary = RotaryPositionEmbedding(self.head_dim, max_position_embeddings) def _prepare_qkv(self, query, key, value, cache=None): q = self.q_proj(query) q = paddle.reshape(x=q, shape=[0, 0, self.num_heads, self.head_dim]) q = paddle.transpose(x=q, perm=[0, 2, 1, 3]) k, v = self.compute_kv(key, value) offset = 0 if cache is None else cache.k.shape[2] # rotary q,k,v q = self.rotary(q, offset=offset) k = self.rotary(k, offset=offset) if self.rotary_value: v = self.rotary(v, offset=offset) ...关键设计:
- 旋转作用于 Q、K(可选 V):
rotary_value=True时对 V 也施加旋转,这正是英文 small 系列(discriminator/generator)的配置; - 推理缓存偏移
offset:解码时通过offset = cache.k.shape[2]从预计算表中切片,保证增量解码时新 token 的旋转角度与历史位置正确衔接; - Cache 拼接:解码自注意力场景下将新 K/V 与历史
cache.k/cache.v沿序列维拼接,实现 KV-Cache 加速。
3.TransformerEncoderLayerWithRotary与RoFormerModel
TransformerEncoderLayerWithRotary(modeling.py)将上述旋转注意力替换进标准nn.TransformerEncoderLayer,并把rotary_value、max_position_embeddings记录到_config。RoFormerModel(modeling.py)进一步组装:
RoFormerEmbeddings:词嵌入 + token_type 段嵌入 + LayerNorm + Dropout(modeling.py),没有可学习的位置嵌入表;- 当
embedding_size != hidden_size时自动插入embeddings_project线性投影层; - 编码器为多层
TransformerEncoderLayerWithRotary堆叠; RoFormerPooler(modeling.py)取首 token([CLS])的隐藏状态经线性层 +pool_act激活得到池化输出;- 默认
attention_mask生成逻辑:当未显式传入 mask 时,自动把pad_token_id位置置为-1e4(modeling.py)。
五、面向任务的下游模型家族
RoFormerPretrainedModel(modeling.py)是下载与权重映射的抽象基类,base_model_prefix = "roformer",并通过_get_name_mappings定义了从 HuggingFace 权重名到 Paddle 权重名的完整映射(含transpose转置规则,兼容 HF 权重直接转换)。在此基础上,PaddleNLP 提供了 7 个可直接使用的模型类:
| 模型类 | 任务场景 | 输出结构 | 关键实现位置 |
|---|---|---|---|
RoFormerModel | 基础编码器,输出 raw hidden-states | BaseModelOutputWithPoolingAndCrossAttentions | modeling.py |
RoFormerForSequenceClassification | GLUE 等分类/回归任务 | SequenceClassifierOutput,支持单标签/多标签分类与回归三种 loss | modeling.py |
RoFormerForTokenClassification | NER 等序列标注任务 | TokenClassifierOutput | modeling.py |
RoFormerForQuestionAnswering | SQuAD 等抽取式问答 | QuestionAnsweringModelOutput(start/end logits,平均 span loss) | modeling.py |
RoFormerForMultipleChoice | RocStories/SWAG 等多项选择 | MultipleChoiceModelOutput(logits 重塑为[batch, num_choices]) | modeling.py |
RoFormerForMaskedLM | 掩码语言建模(BERT 式预训练) | MaskedLMOutput,LM 头与词嵌入权重共享 | modeling.py |
RoFormerForCausalLM | 自回归文本生成 | CausalLMOutputWithCrossAttentions,含生成专用输入预处理 | modeling.py |
其中RoFormerForMaskedLM与RoFormerForCausalLM共用RoFormerOnlyMLMHead/RoFormerLMPredictionHead(modeling.py),并通过embedding_weights=self.roformer.embeddings.word_embeddings.weight实现LM 头与词嵌入权重共享(tied embeddings)。
六、分词器:jieba 词级与字级两种模式
RoFormer 中文模型分为词级与字级两种,对应的分词策略也不同,均由RoFormerTokenizer(tokenizer.py)统一提供:
- 词级模型(
roformer-chinese-small/base):use_jieba=True,使用JiebaBasicTokenizer先经 jieba 预分词(HMM=False),词表中已有的整词保留、否则按单字拆分(tokenizer.py); - 字级模型(
roformer-chinese-char-*、sim-char-*)与英文模型:use_jieba=False,直接使用BasicTokenizer+WordpieceTokenizer的经典 BERT 式流水线; - 特殊 token:
[UNK]、[SEP]、[PAD]、[CLS]、[MASK];输入格式为单句[CLS] X [SEP]、句对[CLS] A [SEP] B [SEP](tokenizer.py); - 各权重的最大输入长度记录在
max_model_input_sizes/PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES(tokenizer.py)中:中文模型 512(roformer-chinese-base为 1536),英文模型 128。
七、快速上手:加载权重并推理
以下示例均来自仓库源码 docstring,可直接复制运行(首次执行会通过from_pretrained自动下载权重与词表)。
基础编码器
import paddle from paddlenlp.transformers import RoFormerModel, RoFormerTokenizer tokenizer = RoFormerTokenizer.from_pretrained('roformer-chinese-char-base') model = RoFormerModel.from_pretrained('roformer-chinese-char-base') tokenized_inputs = tokenizer("欢迎使用百度飞桨!", return_tensors="pd") output = model(**tokenized_inputs)掩码语言建模
from paddlenlp.transformers import RoFormerForMaskedLM, RoFormerTokenizer tokenizer = RoFormerTokenizer.from_pretrained('roformer-chinese-char-base') model = RoFormerForMaskedLM.from_pretrained('roformer-chinese-char-base') tokenized_inputs = tokenizer("欢迎使用百度飞桨!", return_tensors="pd") logits = model(**tokenized_inputs)自回归文本生成(CausalLM)
from paddlenlp.transformers import RoFormerForCausalLM, RoFormerTokenizer tokenizer = RoFormerTokenizer.from_pretrained('roformer-chinese-sim-char-ft-base') model = RoFormerForCausalLM.from_pretrained('roformer-chinese-sim-char-ft-base') tokenized_inputs = tokenizer("欢迎使用百度飞桨!", return_tensors="pd") logits = model(**tokenized_inputs) print(logits.shape) # [1, 11, 12000]RoFormerForCausalLM的输出形状为[batch_size, seq_len, vocab_size],其中 vocab 维度为 12000(字级词表),验证了前文配置表中vocab_size=12000的设定。
多项选择
from paddlenlp.transformers import RoFormerForMultipleChoice, RoFormerTokenizer tokenizer = RoFormerTokenizer.from_pretrained('roformer-chinese-char-base') model = RoFormerForMultipleChoice.from_pretrained('roformer-chinese-char-base') data = [ {"question": "如何打开ipad屏幕?", "answer1": "按音量按钮。", "answer2": "按下锁定按钮。", "label": 1}, {"question": "如何缩进一些文本?", "answer1": "在开始写之前留一些空格。", "answer2": "按空格键。", "label": 0}, ] text, text_pair = [], [] for d in data: text.append(d["question"]); text_pair.append(d["answer1"]) text.append(d["question"]); text_pair.append(d["answer2"]) tokenized_inputs = tokenizer(text, text_pair, padding=True, return_tensors="pd") reshaped_logits = model(**tokenized_inputs) print(reshaped_logits.shape) # [2, 2]同理,序列分类、Token 分类、抽取式问答分别使用RoFormerForSequenceClassification、RoFormerForTokenClassification、RoFormerForQuestionAnswering,传入labels(或start_positions/end_positions)即可自动计算相应损失,可直接接入 PaddleNLP 训练器 进行下游微调。
八、测试与验证
仓库为 RoFormer 提供了完整的单元测试,可作为"模型可复现性"的验证依据:
- tests/transformers/roformer/test_modeling.py:基于
ModelTesterMixin+ConfigTester覆盖RoFormerModel及全部 6 个下游任务模型的输入输出形状、loss 计算与参数初始化,其RoFormerModelTester的默认参数(batch_size=2, seq_length=7, hidden_size=36, num_hidden_layers=6, num_attention_heads=6等)可用于小规模快速回归; - tests/transformers/roformer/test_tokenizer.py:验证 jieba 词级与字级分词、特殊 token 拼接、offset mapping 等行为。
结语
本文以 RoFormer 模型清单 为主线,完整整理了 PaddleNLP 中 10 个 RoFormer 预训练权重的结构与配置、RoFormer-S 英文生成模型的训练规格,并结合源码剖析了旋转位置编码的数学实现、其在多头注意力与 KV-Cache 解码中的衔接方式,以及 7 个任务模型与双模式分词器的用法。无论你是要做中文语义相似度、抽取式问答、序列标注,还是轻量级英文文本生成,都可以依据文中参数表快速选定权重,并借助from_pretrained一键加载直接使用。
- 人工智能
- 大模型
- NLP
- 深度学习
- 预训练
- 微调
- RLHF
- 模型量化
【免费下载链接】PaddleNLP
Easy-to-use and powerful LLM and SLM library with awesome model zoo.
相关推荐
PaddleNLP 中的 NeZha 模型:预训练权重清单与相对位置编码实现解析
PaddleNLP 中的 NeZha 模型:预训练权重清单与相对位置编码实现解析 NeZha(哪吒)是华为诺亚方舟实验室提出的中文预训练语言模型,其核心创新在于
人工智能大模型NLP深度学习预训练微调RLHF模型量化模型推理服务本地部署模型压缩强化学习模型评测Obsidian:英雄联盟WAD文件编辑的终极免费解决方案
Obsidian:英雄联盟WAD文件编辑的终极免费解决方案 如果你是《英雄联盟》的模组开发者、游戏资源研究者,或是想要深入了解游戏内部结构的玩家,那么你一定会遇
人工智能大模型NLP深度学习预训练微调RLHF模型量化模型推理服务本地部署模型压缩强化学习模型评测番茄小说下载器完整指南:免费开源工具实现小说离线阅读自由
番茄小说下载器完整指南:免费开源工具实现小说离线阅读自由 你是否曾经因为网络信号不佳而无法继续阅读番茄小说?或者厌倦了阅读过程中频繁弹出的广告干扰?番茄小说下载
人工智能大模型NLP深度学习预训练微调RLHF模型量化模型推理服务本地部署模型压缩强化学习模型评测
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考