DC Former代码框架思路解析
1 DCFormer
1.1 config.json
本文件是DCFormer 模型的配置文件,定义了模型的各种超参数和设定。
-字段说明
**architectures:**模型架构的名称,这里是 “DCFormer”。
**auto_map:**自动映射模型和配置类,指定了 AutoConfig 和 AutoModelForCausalLM 对应的配置类和模型类路径。
AutoConfig: 指定 DCFormerConfig,这是模型的配置类。
**AutoModelForCausalLM:**指定 DCFormer 模型类,这是实际的推理模型。
**block_size:**输入序列的最大长度(2048),影响模型在训练或推理时处理的上下文窗口大小。
**bos_token_id 和 eos_token_id:**这是模型的特殊标记(begin-of-sequence 和 end-of-sequence),分别对应词汇表中的 1 和 2。
**dim:**模型的隐藏层维度,设置为 2560。
**head_dim:**每个注意力头的维度,设置为 80。
**intermediate_size:**前馈网络的中间层维度,设置为 6912。
**n_head:**注意力头的数量,这里设置为 32。
**n_layer:**Transformer 层数,设置为 32。
**norm_eps:**归一化中的 epsilon 值,设置为 1e-6。
**q_chunk_size:**查询(query)的分块大小,这个参数用于控制大规模模型训练中的内存使用。
**use_dcmha:**是否启用动态可组合多头注意力(DCMHA),设为 true,意味着使用了 DCFormer 改进的注意力机制。
**use_qk_norm:**是否启用查询和键的归一化(QK Norm),设为 true,这有助于避免在训练过程中出现不稳定。
**vocab_size:**词汇表大小,这里设置为 50257,符合大规模模型(如 GPT 系列)的标准大小。
1.2 configuration_dcformer.py
DCFormerConfig 类继承自 PretrainedConfig,用于初始化和管理 DCFormer模型.
-DCFormerConfig 类初始化了模型的核心超参数,很多参数与 config.json 中的字段相对应。
-构造函数中的一些值会根据给定的参数进行自动推断,比如 intermediate_size(默认情况下为 None,会根据模型维度自动计算)。
-该类继承自 PretrainedConfig,使得模型可以无缝与 Huggingface Transformers 框架集成。
1.3 generation_demo.py
本文件展示了如何使用 DCFormer 模型进行推理生成。
-加载预训练的 DCFormer-2.8B 模型和分词器。
-使用 CUDA 加速模型推理,确保计算效率。
-模型生成 100 个 token,并使用分词器解码生成的 ID 到文本格式。
-示例代码简单直观,演示了如何利用 Huggingface AutoModelForCausalLM 和 AutoTokenizer 接口快速加载并推理生成文本。
1.4 maxtext2torch.py
maxtext2torch.py 文件的作用是将 MaxText 格式的模型权重转换为 PyTorch 支持的格式,通常用于加载预训练模型或进行模型迁移。MaxText 是一种特殊的模型保存格式,可能用于一些特定框架或定制模型存储。
将其转换为 PyTorch 格式后,可以直接使用 transformers 库加载并进行推理或微调。
-加载 MaxText 权重:假设 MaxText 权重是以某种特定的格式存储的,首先需要通过某种方式将其解析出来。通常这种格式会涉及到二进制文件或者自定义格式,需要根据模型开发者提供的解析规则来加载。
-加载 PyTorch 模型:在转换过程中,我们使用 AutoModelForCausalLM 来加载一个预训练的 PyTorch 模型,这里假设已经有一个对应的 DCFormer 模型。
-权重加载:将从 MaxText 格式读取的权重加载到 PyTorch 模型中,并且调用 model.load_state_dict() 方法。
-保存转换后的模型:将最终加载了 MaxText 权重的模型保存在 .pt 格式的文件中,以便后续使用。
1.5 modeling_dcformer.py
代码实现了 DCFormer 模型,基于 Transformer 的自注意力机制,进行了动态加权、窗口优化和分组注意力等改进,目的是优化训练和推理性能。
以下是核心代码解析:
1.5.1 KVKWCache
1 | class KVKWCache(nn.Module): |
这部分是缓存模块,用于高效存储和更新注意力层的 Key-Value(KV)对。
作用:
-支持推理时的序列缓存和动态窗口机制。
提供可选的权重缓存 (kw_cache),允许动态加权的注意力机制。
主要方法:
-update: 更新缓存,支持单 token(在线生成)或批量(填充模式)更新。
关键逻辑:
窗口限制 (window_size) 允许模型仅关注局部上下文。
支持动态生成的权重(kw_cache)。
1.5.2 DCFormer
1 | class DCFormer(PreTrainedModel): |
这是模型的核心类,继承自 PreTrainedModel,具备加载和保存模型的能力。
结构:
-词嵌入层(tok_embeddings)。
-多个 Transformer 块(DCFormerBlock)。
-RMSNorm 归一化和输出层。
方法解析:
-setup_caches:
初始化 KV 缓存。
预计算频率编码(freqs_cis)用于旋转位置编码。
-generate:
循环生成文本,支持快速解码(compiled_decode_one_token)。
-forward:
依次通过各层 Transformer 块。
支持梯度检查点(节省显存)。
根据窗口类型和训练模式切换掩码。
特点:
使用 RMSNorm 替代 LayerNorm。
通过 KV 缓存和窗口机制优化推理。
1.5.3 DCFormerBlock
1 | class DCFormerBlock(nn.Module): |
单个 Transformer 块,包含以下模块:
-动态加权多头注意力(DCMHAttention)。
-前馈网络(FeedForward)。
-两个归一化层(RMSNorm)。
实现:
注意力和前馈网络均通过残差连接(h = x + …)相加。
1.5.4 DCMHAttention
1 | class DCMHAttention(nn.Module): |
本部分为动态加权多头注意力模块,是模型的核心改进。
功能:
计算 Query、Key 和 Value(通过 wqkv 投影)。
支持 Query 和 Key 的归一化。
根据窗口类型和位置掩码调整计算范围。
使用 DynamicWeightProjection 动态调整注意力权重。
推理优化:
_generate_fast 用于快速单步解码。
支持按块分组(q_chunk_size)计算,减少内存开销。
动态权重投影的关键逻辑:
通过动态权重投影(DynamicWeightProjection)生成权重。
fast_infer 模式下,利用缓存加速计算。
1.5.5 DynamicWeightProjection
1 | class DynamicWeightProjection(nn.Module): |
实现动态权重投影,为 Query 和 Key 生成自适应权重。
特点:
动态生成投影权重 (dw_hidden, qkw)。
支持分组权重(num_groups)。
提供预投影(pre_proj)和后投影(post_proj)的支持。
关键方法:
merge_weights: 将预定义权重合并,用于优化推理。
forward: 根据输入动态生成权重,并选择是否缓存。
1.5.6 FeedForward
1 | class FeedForward(nn.Module): |
这部分是前馈网络模块,典型的 Transformer 组件:
-两个全连接层。
-使用 SILU 激活函数。
1.5.7 RMSNorm
1 | class RMSNorm(nn.Module): |
RMSNorm 是一种替代 LayerNorm 的归一化技术,具有更好的训练稳定性。
公式:
$$
\text{output} = \frac{x}{\sqrt{\text{mean}(x^2) + \epsilon}} \cdot \text{scale}
$$
1.5.8 辅助函数
precompute_freqs_cis
-用于预计算旋转位置编码(RoPE)。
-将频率参数以极坐标形式表示,支持快速计算旋转编码。
make_window_mask
生成窗口掩码,仅允许模型关注特定上下文范围。
apply_rotary_emb
应用旋转位置编码,增强 Transformer 在长序列上的建模能力。
slice_dw
切片动态权重,用于按窗口分割输入。
2 DCpythia
config.json
本文件定义了模型的各种配置参数,包括架构、token的id、模型的维度等。该配置文件是用来加载模型时给定的超参数和设置。
主要配置项:
architectures: 定义模型的架构类型,这里指定为 “DCPythia”,即模型是基于DCPythia架构。
auto_map: 映射自动配置类和模型类,AutoConfig指向 configuration_dcpythia.DCPythiaConfig,而 AutoModelForCausalLM 指向 modeling_dcpythia.DCPythia。
block_size: 定义块的大小,通常影响模型处理的最大序列长度。
vocab_size: 模型词汇表的大小,通常影响模型的输入和输出维度。
dim: 模型的隐藏层维度,也就是每个token的表示向量的大小。
n_layer: 模型的层数,也就是Transformer的堆叠层数。
n_head: 每个自注意力层的头数。
intermediate_size: Transformer中FeedForward层的维度,影响每层的宽度。
bos_token_id, eos_token_id: 序列的起始token和结束token的ID。
torch_dtype: 定义使用的PyTorch数据类型,这里使用float16,表示使用半精度浮点数,通常用于节省内存和加速计算。
use_dcmha: 是否使用DCMHA(Dynamic Chunked Multi-Head Attention)。
use_parallel_residual: 是否启用并行残差连接。
use_linear_bias: 是否使用线性偏置。
use_qk_norm: 是否在自注意力计算中使用查询(Q)和键(K)的归一化。
transformers_version: 定义所使用的Transformers库版本。
configuration_dcythia.py
1 | from transformers.configuration_utils import PretrainedConfig |
DCPythiaConfig 继承了 PretrainedConfig,这使得它能够作为 Hugging Face transformers 库中的配置类来使用。配置类用于管理模型的参数和设置。
model_type 定义了模型类型为 “dcpythia”,这表明该配置是为 DCPythia 模型定制的。
注释表明该配置类来自某个 GitHub 项目链接,表明 DCPythia 是从 GPT-fast 模型中改编的。
初始化方法 (init):
这是 DCPythiaConfig 类的初始化方法,定义了很多用于 DCPythia 模型的超参数。
常见的超参数包括:
block_size:序列的最大长度,通常决定输入的最大 token 数量。
vocab_size:词汇表的大小。
n_layer:Transformer 网络的层数。
n_head:多头注意力机制中的头数。
dim:模型的隐层维度。
intermediate_size:中间层的维度,通常是 dim 的倍数。
head_dim:每个头的维度,通常 dim / n_head。
use_gradient_checkpointing:是否启用梯度检查点,以节省内存。
use_dcmha:是否使用 DC-MHA(假设是某种改进的多头注意力机制)。
use_qk_norm:是否对查询-键(Q和K)做归一化。
window_size 和 window_type:窗口大小和类型,可能用于局部注意力机制。
rotary_pct:用于旋转位置编码的百分比。
接着是后处理部分:
1 | if self.n_local_heads == -1: |
如果 n_local_heads 没有被指定(即为 -1),则将其设置为 n_head。
如果没有指定 intermediate_size,则将其设置为 dim 的四倍。
head_dim 被计算为 dim // n_head。
然后调用父类的构造方法:
1 | super().__init__( |
这里调用了父类 PretrainedConfig 的构造方法,并传递了额外的 token ID 和其他参数。
generation_demo.py
1 | import torch |
导入 torch 和 transformers 库,用于加载模型和执行推理。
关闭 TOKENIZERS_PARALLELISM 环境变量,通常用于避免多线程令牌化过程中的问题。
加载模型和分词器:
1 | tokenizer = AutoTokenizer.from_pretrained("Caiyun-AI/DCPythia-6.9B") |
使用 AutoTokenizer 和 AutoModelForCausalLM 从指定的模型库 “Caiyun-AI/DCPythia-6.9B” 加载模型和分词器。
trust_remote_code=True 表示信任并加载远程代码,可能包含自定义实现。
设置设备:
1 | device = torch.device('cuda') |
将模型和推理过程设置为在 GPU 上运行。
配置模型:
1 | MAX_BATCH_SIZE = 1 |
设置批量大小、最大序列长度和生成的 token 数量。
COMPILE = True 表示是否启用编译功能(即是否使用 torch.compile)。
将模型转移到 GPU 上,并设置数据类型为 float16 以减少内存使用。
设置缓存:
1 | with torch.device(device): |
在指定的设备上配置模型的缓存。这里指定了批处理大小、最大序列长度,并启用了键值缓存。
定义 decode_one_token 函数:
1 | def decode_one_token(model, cur_token, input_pos): |
定义了一个函数 decode_one_token,它根据当前 token 和位置生成下一个 token。模型输出的 logits 被用来选择概率最大的 token。
生成文本:
1 | prompt = "Beijing is the capital of China. London is the capital of" |
使用给定的 prompt 编码为 token ids。
torch.compile 对 decode_one_token 函数进行优化,减少计算开销。
推理生成:
1 | with torch.no_grad(): |
使用 model.generate 方法生成文本。
使用 tokenizer.decode 将生成的 token 转换为文本并打印出来。
modeling_dcpythia.py
1 | class KVKWCache(nn.Module): |
用于管理模型的键值缓存,适配不同的序列长度、窗口大小和头部配置。
支持常规键值缓存 (k_cache 和 v_cache) 和额外的 kw_cache。
方法 update 用于更新缓存,是模型的核心之一,处理序列窗口截断和序列填充。
1 | class DCPythia(PreTrainedModel): |
基于 HuggingFace 的 PreTrainedModel,是该模型的主干结构。
包括以下子模块:
-tok_embeddings:词嵌入层。
-多层 DCPythiaBlock。
-LayerNorm 和输出线性层。
-支持训练和推理两种模式,拥有灵活的缓存管理功能。
方法 setup_caches 初始化模型缓存,确保性能优化。
方法 generate 实现逐步生成,支持动态调整输入序列。
1 | class DCPythiaBlock(nn.Module): |
表示模型的一层,包含注意力机制和前馈网络。
使用并行残差结构(use_parallel_residual)来优化计算。
1 | class DynamicWeightProjection(nn.Module): |
一个动态权重投影模块,用于生成自适应的权重矩阵。
通过输入序列特征动态调整注意力计算的权重。
提供高效的权重生成和缓存机制。
1 | class DCMHAttention(nn.Module): |
多头注意力实现,支持动态权重投影和窗口化机制。
结合旋转位置嵌入(Rotary Embedding)进行位置编码。
提供快速推理模式,通过 _generate_fast 优化生成速度。
支持复杂的多阶段窗口机制(如 LG 和 LGLL)。
1 | class FeedForward(nn.Module): |
两层前馈网络,激活函数使用 GELU。
处理非线性变换和特征映射。
辅助函数:
1 | def _atten_context(query, key, value, atten_mask, pre_proj_dw_args, post_proj_dw_args): |
提供位置编码 (precompute_freqs_cis)、窗口掩码生成 (make_window_mask)、嵌入旋转 (apply_rotary_emb) 和张量拆分 (unbind) 等工具函数。