大模型从零开始——模型参数量计算

文章目录

一、LLaMA2参数量计算

二、大模型参数解析

模型下载并加载

打印模型的所有参数

打印参数的形状和名称

打印模型的配置信息

打印模型总参数量和大小

三、Transformer模型参数量估算



本篇我们将介绍如何计算基于Transformer架构的大语言模型的参数数量。由于当前主流的大模型普遍采用因果解码器(CausalDecoder)架构,因此下面以LLaMA2模型为范例,深入剖析其参数数量计算方式。对于其他模型,其参数量计算算法可参照此方法计算。

一、LLaMA2**参数量计算**

大模型一般都会将参数量命名进模型中,如 llama2:7b、glm4:9b、qwen2.5:32B。参数的7B、9B是指模型中可训练参数的数量。这里的"B"表示10亿(Billion),即10^9。因此,7B表示70亿个可训练参数,9B表示90亿个可训练参数。

首先,假设词表大小为 V,模型包含 L 层解码器,中间状态的维度大小为 H,前馈网络层的中间状态维度大小为 H′。

  • 输入嵌入层。首先,输入嵌入层( )将词表中的每个单词映射到一个 H 维的向量,因此输入编码层有 V × H 个参数。

  • 多头注意力层。传统的注意力机制部分包含查询( )、键( )和值( )的线性变换矩阵,每个变换矩阵都包含 个参数,所以这部分需要 3 × 个参数。同时还需要一个额外的线性变换来将多头注意力机制的输出拼接后映射成最终输出( ),这又需要 个参数。因此,多头注意力层总共需要 4 × 个参数。

  • 前馈网络层。LLaMA 的前馈网络层由三个线性变换组成,中间有一个非线性激活函数。前两个线性变换( )将输入从 H 维映射到 H′ 维,需要 2 × HH′ 个参数;最后一个线性变换()将输出从H′维映射回 H维,需要 H′ 个参数。因此,前馈网络层总共需要 3 × HH′ 个参数。

  • 归一化层。每一层解码器还包含两个 RMSNorm 操作,分别用于对多头注意力层和前馈网络层的输入进行归一化处理,共需要 2 × H个参数。此外,最后一层的输出也需要进行归一化处理,这又需要额外的 H 个参数。

  • 输出层。最后,LLaMA 的输出层包含一个线性变换(),将解码器的输出映射到词表大小 V 的维度上,使用 softmax 归一化后预测下一个单词的概率分布。这个线性变换需要 V × H 个参数。

综上所述,累积输入嵌入层、输出层和 L 层解码器每层的多头注意力层、前馈网络层和归一化层,LLaMA 模型的参数量计算公式为:

以 LLaMA2 (7B) 为例计算其参数:

共32个Block,一个Block的参数情况:

词表Token数为32K。即给定 V = 32000, L= 32, H= 4096, H′ = 11008,将这些值代入上述公式中:

参数量 = 2 × 32000 × 4096 + 4096 + 32 × (4 × 4096^2 + 3 × 4096 × 11008 + 2 × 4096)= 6,738,415,616。

计算得到的参数量与 LLaMA2 (7B) 模型的实际参数量完全一致。详见:https://ollama.com/library/llama2/blobs/8934d96d3f08

二、大模型参数解析

下面我们以Llama-2-7b-chat-hf为例,来实际打印模型的参数量看看。

模型下载并加载

git clone https://www.modelscope.cn/shakechen/Llama-2-7b-chat-hf.git
python 复制代码
pip install transformers
python 复制代码
from transformers import AutoModelForCausalLM
 
# 指定模型路径
model_path = "./Llama-2-7b-chat-hf"
 
# 加载模型
hf_model = AutoModelForCausalLM.from_pretrained(model_path)
 
# 打印模型信息
print(hf_model)

从提供的输出中,我们可以看到Llama2模型的结构细节。这个模型是使用transformers库加载的。

模型结构的关键点:

  • 嵌入层(Embedding) :使用一个嵌入层将输入的词标(tokens)转换为固定大小的向量,这里的维度是4096,词汇表大小为32000,则参数数量为32,000 * 4,096
  • 解码器层(LlamaDecoderLayer) :包含32个解码器层,每个层都具有以下组件:
    • 自注意力(LlamaSdpaAttention) :一个自注意力机制,包括四个线性变换(q_proj, k_proj, v_proj, o_proj)以及一个旋转位置编码(rotary_emb)。
    • 多层感知机(LlamaMLP) :包括一个门控投影(gate_proj),上升投影(up_proj),下降投影(down_proj),以及激活函数(act_fn),这里使用了SiLU(Sigmoid线性单元)。
    • 层归一化(LlamaRMSNorm):在输入和自注意力后使用RMS归一化,有利于模型训练的稳定性。
  • 输出层(Linear):最后,一个线性层将解码器的输出转换回词汇表空间,用于生成最终的输出词标,这里输出层的大小也是32000,与词汇表大小相同。

打印模型的所有参数

python 复制代码
from transformers import AutoModelForCausalLM
 
# 指定模型路径
model_path = "./Llama-2-7b-chat-hf"
 
# 加载模型
hf_model = AutoModelForCausalLM.from_pretrained(model_path)
 
for param_tensor in hf_model.parameters():
    print(param_tensor)

打印参数的形状和名称

python 复制代码
from transformers import AutoModelForCausalLM
 # 指定模型路径
model_path = "./Llama-2-7b-chat-hf"
 
# 加载模型
hf_model = AutoModelForCausalLM.from_pretrained(model_path)
 
for name, param in hf_model.named_parameters():
    print(f"{name}: {param.size()}")
python 复制代码
Loading checkpoint shards: 100%|██████████████████████████████████████████████████| 2/2 [00:03<00:00,  1.79s/it]
model.embed_tokens.weight: torch.Size([32000, 4096])
model.layers.0.self_attn.q_proj.weight: torch.Size([4096, 4096])
model.layers.0.self_attn.k_proj.weight: torch.Size([4096, 4096])
model.layers.0.self_attn.v_proj.weight: torch.Size([4096, 4096])
model.layers.0.self_attn.o_proj.weight: torch.Size([4096, 4096])
model.layers.0.mlp.gate_proj.weight: torch.Size([11008, 4096])
model.layers.0.mlp.up_proj.weight: torch.Size([11008, 4096])
model.layers.0.mlp.down_proj.weight: torch.Size([4096, 11008])
model.layers.0.input_layernorm.weight: torch.Size([4096])
model.layers.0.post_attention_layernorm.weight: torch.Size([4096])
...
model.layers.31.self_attn.q_proj.weight: torch.Size([4096, 4096])
model.layers.31.self_attn.k_proj.weight: torch.Size([4096, 4096])
model.layers.31.self_attn.v_proj.weight: torch.Size([4096, 4096])
model.layers.31.self_attn.o_proj.weight: torch.Size([4096, 4096])
model.layers.31.mlp.gate_proj.weight: torch.Size([11008, 4096])
model.layers.31.mlp.up_proj.weight: torch.Size([11008, 4096])
model.layers.31.mlp.down_proj.weight: torch.Size([4096, 11008])
model.layers.31.input_layernorm.weight: torch.Size([4096])
model.layers.31.post_attention_layernorm.weight: torch.Size([4096])
model.norm.weight: torch.Size([4096])
lm_head.weight: torch.Size([32000, 4096])

打印模型的配置信息

python 复制代码
from transformers import AutoModelForCausalLM
# 指定模型路径
model_path = "./Llama-2-7b-chat-hf"
 
# 加载模型
hf_model = AutoModelForCausalLM.from_pretrained(model_path)
 
print(hf_model.config)

从提供的LlamaConfig配置输出中,我们可以看到Llama2模型的关键配置参数。这些参数提供了模型架构的深入了解,下面是其中一些重要参数的解释:

  • _name_or_path : 指定了模型加载的路径或名称,这里是"./Llama-2-7b-chat-hf"
  • architectures : 包含了模型使用的架构类型,这里是"LlamaForCausalLM",表明这是一个因果语言模型。
  • attention_dropout: 注意力层中使用的dropout比率,这里设置为0.0,意味着没有应用dropout。
  • bos_token_ideos_token_id: 分别表示文本序列开始(BOS)和结束(EOS)的特殊标记的ID。
  • hidden_act : 隐藏层使用的激活函数,这里是"silu"(Sigmoid线性单元,也称为Swish激活函数)。
  • hidden_size: 隐藏层的大小,这里是4096,表明每个隐藏层的输出维度。
  • intermediate_size: 前馈网络(feed-forward network)层中间层的大小,这里是11008。
  • max_position_embeddings: 最大的位置嵌入维度,这里是4096,限定了模型能处理的最大序列长度。
  • model_type : 模型的类型,这里是"llama"
  • num_attention_heads: 注意力机制中使用的头数,这里是32。
  • num_hidden_layers: 隐藏层的数量,这里是32。
  • vocab_size: 词汇表的大小,这里是32000。
  • torch_dtype : 模型中使用的数据类型,这里是"float16",表明模型参数使用的是半精度浮点数,这有助于减少模型的内存占用,加快计算速度。

这个配置概览揭示了Llama2模型的一些关键特性,包括其深度、宽度和操作的技术细节。例如,32层的深度与4096的隐藏大小和32的注意力头数共同决定了模型的能力和复杂性,使其适合处理复杂的语言理解和生成任务。使用半精度浮点数(float16)是为了优化性能和资源使用,特别是在支持半精度计算的硬件上。

打印模型总参数量和大小

python 复制代码
from transformers import AutoModelForCausalLM

# 指定模型路径
model_path = "./Llama-2-7b-chat-hf"

# 加载模型
hf_model = AutoModelForCausalLM.from_pretrained(model_path)

# 计算参数数量
total_params = sum(p.numel() for p in hf_model.parameters())

# 计算模型大小(以字节为单位),假设每个参数为16位浮点数, 半精度浮点数(float16)
model_size_bytes = total_params * 2  # 2字节/参数

# 转换为更易于理解的单位:MB
model_size_mb = model_size_bytes / (1024 ** 2)

print(f"Total Parameters: {total_params}")
print(f"Model Size: {model_size_mb:.2f} MB")

总参数量为 6,738,415,616,模型大小以半精度浮点数(float16)计算,约为12.55GB,和实际模型文件大小基本一致。

三、Transformer模型参数量估算

下面我们来介绍一种Transformer模型通用的近似估算方法,假设词汇表大小为v,隐藏层维度为h

嵌入层:

多头自注意力层:含三个权重矩阵Q、K、V,加一个输出投影矩阵W,整个自注意力层的参数量为 ,存在偏置参数加

前馈神经网络层:两个线性变换,第一个从h扩展到4h,第二个再压缩回h,参数量为 ,存在偏置参数加

归一化层:分别用于对多头自注意力层和前馈神经网络层的输入进行归一化处理,同时包含缩放参数和平移参数,参数量为

RMSNorm只有一个可训练的缩放参数,与传统的层归一化不同,不包含偏置(平移)参数,它主要通过对输入的标准差进行归一化来稳定训练过程。

输出层:

综上,l 层模型可训练模型参数量为 ,当隐藏层维度 h 较大时,可忽略一次项,参数量可以近似为

例如:估算GPT-3模型参数量,模型层数为96,隐藏层维度为12,288,代入公式可得 ,与模型给定参数基本一致。

相关推荐
AIzealot无8 小时前
论文解读之learning to summarize with human feedback
人工智能·深度学习·语言模型·大模型·强化学习·人类偏好
耿子6661 天前
大模型 LangChain 开发框架-初探
langchain·大模型·embedding
视觉&物联智能1 天前
【杂谈】-DeepSeek如何以560万美元突破成本障碍
人工智能·深度学习·机器学习·ai·大模型·llm·deepseek
Luke Ewin2 天前
解决安装pynini和WeTextProcessing报错问题
python·大模型·llm·语音识别·语音合成·tts·asr
山顶夕景2 天前
【LLM综述】29种大模型Prompt Engineering技术
大模型·llm·prompt
Nicolas8933 天前
【大模型实战篇】GLM-Zero模型初代版本的尝鲜
大模型·大模型推理·o1·强化推理·多步推理·glm强化推理
Nicolas8933 天前
【大模型实战篇】LLaMA Factory微调ChatGLM-4-9B模型
大模型·全参微调·大模型微调·glm4·llamafactory·chatglm9b
林泽毅3 天前
SwanLab x LLaMA Factory:国产开源AI训练工具组合拳(含教程)
人工智能·python·机器学习·开源·大模型·llama·swanlab
Nicolas8933 天前
【大模型实战篇】Mac本地部署RAGFlow的踩坑史
大模型·rag·检索增强生成·文档解析·ragflow·大模型垂直应用