LLM 大语言模型显存消耗估计与计算

LLM 大语言模型显存消耗估计与计算

1. LLM 大语言模型开发流程

在大模型(如 LLaMA-7B、GPT-3 等)的开发、训练、微调、推理和部署过程中,各个阶段的流程都涉及多个复杂的步骤。以下是详细的流程描述,涵盖训练和微调的区别,以及训练、推理和部署的具体过程。

1.1 预训练(Pre-training)

目标:使用大规模的数据集训练模型,使其能够理解和生成自然语言。

流程

  1. 数据准备

    • 收集大规模文本数据(如维基百科、新闻、书籍等)。
    • 数据清洗和预处理,包括分词、去除停用词等。
  2. 模型定义

    • 选择模型架构(如 Transformer)。
    • 定义模型的层数、隐藏单元数、注意力头数等超参数。
  3. 训练过程

    • 初始化:随机初始化模型权重。
    • 前向传播:计算每个输入的输出。
    • 计算损失:使用目标数据计算模型的损失(如交叉熵损失)。
    • 反向传播:计算梯度并更新模型权重。
    • 优化:使用优化器(如 Adam、AdamW)调整学习率和其他超参数。
  4. 评估

    • 使用验证集评估模型的性能(如准确率、损失值)。
  5. 保存模型

    • 保存训练后的模型权重和配置,以便后续使用或微调。

1.2 微调(Fine-tuning)

目标:在特定任务或数据集上对预训练模型进行调整,以提高任务性能。

流程

  1. 准备特定任务的数据集

    • 收集并处理特定任务的数据集(如文本分类、问答等)。
  2. 加载预训练模型

    • 从预训练模型中加载权重。
  3. 任务适配

    • 修改模型架构(如添加分类层)以适应特定任务。
  4. 微调过程

    • 前向传播:在特定任务数据上计算输出。
    • 计算损失:使用特定任务的标签计算损失。
    • 反向传播:计算梯度并更新模型权重。
    • 优化:调整学习率和其他超参数。
  5. 评估

    • 在验证集上评估模型的性能。
  6. 保存微调后的模型

    • 保存微调后的模型权重和配置,以便部署或进一步优化。

1.3 推理(Inference)

目标:使用训练好的模型进行实际应用(如文本生成、翻译等)。

流程

  1. 加载模型

    • 从磁盘加载预训练或微调后的模型权重。
  2. 预处理输入

    • 对输入数据进行预处理(如分词、编码)。
  3. 前向传播

    • 使用模型计算输入数据的输出。
  4. 后处理

    • 对模型输出进行解码和后处理(如将生成的文本转换为可读的形式)。
  5. 输出结果

    • 返回或展示模型的输出结果。

1.4 部署(Deployment)

目标:将模型部署到生产环境中,使其能够为用户提供服务。

流程

  1. 环境准备

    • 配置运行环境(如服务器、云平台)。
    • 安装必要的软件和库。
  2. 模型导出

    • 导出模型为适合部署的格式(如 ONNX、TensorFlow SavedModel)。
  3. 创建服务

    • 构建 API 或用户接口来与模型进行交互(如 REST API、gRPC)。
  4. 集成

    • 将模型集成到应用程序或服务中。
  5. 监控和维护

    • 监控模型的性能和响应时间。
    • 定期维护和更新模型,处理任何出现的问题。
  6. 优化

    • 进行模型压缩(如量化、剪枝)以减少部署成本。
    • 使用缓存和负载均衡来提高服务的可扩展性。

2. 模型GPU显存占用(accelerate 工具)

2.1 开发环境

  • Transformers 4.38.1
  • Accelerate 0.27.2

2.2 使用方法

这个工具 accelerate estimate-memory 是 huggingface 的 accelerate 开发库中提供的一个工具。使用这个工具,并不会真正的下载或者加载模型到内存中,它只是根据meta数据来对大模型所需要的内存进行模拟计算。所以,运行此工具并不需要您有GPU机器。

2.2.1 网页在线访问

截止 2024/7/23 (无法打开)

https://huggingface.co/spaces/hf-accelerate/model-memory-usage

2.2.2 本地运行
  • 安装 accelerate, transformers
pip install accelerate
pip install transformers
  • 使用方法举例
# 基本使用方法
accelerate estimate-memory mistralai/Mistral-7B-v0.1
accelerate estimate-memory meta-llama/Llama-2-13b-hf# 只显示指定的数据类型
accelerate estimate-memory mistralai/Mistral-7B-v0.1 --dtypes float16# 指定开发库(针对本地模型,Hub上存储的模型不需要指定)
accelerate estimate-memory mistralai/Mistral-7B-v0.1 --dtypes float32 float16 --library_name transformers# 设置 trust_remote_code=True
accelerate estimate-memory Qwen/Qwen1.5-7B #正常
accelerate estimate-memory Qwen/Qwen-7B #报错
accelerate estimate-memory Qwen/Qwen-7B --trust_remote_code #可以运行# 其他模型
accelerate estimate-memory google/gemma-7b
accelerate estimate-memory baichuan-inc/Baichuan2-7B-Base --trust_remote_code

2.3 实验结果

2.3.1 meta-llama/Llama-2-7b-hf
accelerate estimate-memory meta-llama/Llama-2-7b-hf
┌──────────────────────────────────────────────────────────┐
│   Memory Usage for loading `meta-llama/Llama-2-7b-hf`    │
├───────┬─────────────┬──────────┬─────────────────────────┤
│ dtype │Largest Layer│Total Size│   Training using Adam   │
├───────┼─────────────┼──────────┼─────────────────────────┤
│float32│  776.03 MB  │ 24.74 GB │         98.96 GB        │
│float16│  388.02 MB  │ 12.37 GB │         49.48 GB        │
│  int8 │  194.01 MB  │ 6.18 GB  │           N/A           │
│  int4 │   97.0 MB   │ 3.09 GB  │           N/A           │
└───────┴─────────────┴──────────┴─────────────────────────┘
2.3.2 手动测试代码

测试使用的代码:

代码使用mistralai/Mistral-7B-Instruct-v0.2模型,原教程直接复制过来,未修改,如需需要自己修改

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch, pdbmodel = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-Instruct-v0.2", torch_dtype=torch.float32, device_map="auto")
#model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-Instruct-v0.2", torch_dtype=torch.float16, device_map="auto")
#model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-Instruct-v0.2", load_in_8bit=True, device_map="auto")
#model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-Instruct-v0.2", load_in_4bit=True, device_map="auto")tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-Instruct-v0.2")
#pdb.set_trace()input_text = "Write me a poem about Machine Learning."
input_ids = tokenizer(input_text, return_tensors="pt").to("cuda")outputs = model.generate(**input_ids, max_new_tokens=1000)
print(tokenizer.decode(outputs[0]))

2.4 总结

这个工具的计算的结果,针对代码加入到Transformers中的模型,计算结果有参考价值。
针对本地模型,计算可能会不准确。

作为总结,可以试着回答下面的问题:

  1. 这个工具可以做什么? 如何使用?
  2. 此工具如何设置 trust_remote_code=True ? 什么情况下需要设置?
    处理来自第三方的自定义配置
  3. Timm是什么?: https://huggingface.co/timm
    是huggingface的开发库,主要面向图像处理模型
  4. 此工具的计算值与实际运行时的差异有多大? 造成差异的原因有那些?

3. 模型GPU显存占用(手动计算—推理过程)

前提条件: 模型参数量为 $ \Phi$

推理过程

推理过程包括模型的一次前向传播,显存主要存储模型的参数。当模型通过 Float 16 数据类型存储时,每个元素占据 2 个 bytes,因此显存占用量为 2 Φ 2\Phi 。当模型通过 Float 32 数据类型存储时,每个元素占据 4 个 bytes,因此显存占用量为 4 Φ 4\Phi

例子

以 ChatGLM-6B 为例,FP16 存储时 (6*2=12G):

量化等级最低 GPU 显存(推理)
FP16(无量化)13 GB
INT88 GB
INT46 GB

总结

推理过程中,模型参数的存储占据显存的主要部分。不同的数据类型(FP16、INT8、INT4)对显存的需求不同,选择适当的量化等级可以有效地减少显存占用。

4. 模型GPU显存占用(手动计算—训练过程)

模型训练过程中,显存占用主要包括下面四个部分:

  1. 模型参数
  2. 模型梯度
  3. 优化器状态
  4. 中间激活值

4.1 基础知识

  • 1GB = 1024 MB
  • 1MB = 1024KB
  • 1KB = 1024B
  • 1B = 8bit
  • FP32 32bit 单精度 4B
  • FP16 16bit 半精度 2B

4.2 模型参数

4.2.1 前置说明:
符号说明
  • n layer n_{\text{layer}} nlayer: 模型层数;

  • d model d_{\text{model}} dmodel: 模型残差输出维度大小;

  • d ff d_{\text{ff}} dff: 前馈神经网络输出维度大小;

  • d attn d_{\text{attn}} dattn: 注意力网络输出维度大小;

  • n heads n_{\text{heads}} nheads: 每一层的多头注意力的数量;

  • n ctx n_{\text{ctx}} nctx: 输入的上下文长度大小;

前置知识
  1. 参数量定义
    参数量是指神经网络或机器学习模型中可以进行学习和调整的参数的数量。包括权重(weights)和偏量(biases),它们在训练过程中不断地更新以优化模型的性能。

  2. FLOPS定义
    FLOPS(floating point operations)表示浮点数运算次数,衡量计算量的大小。

  3. 如何计算矩阵乘法的FLOPs

    • 对于 A ∈ R l × n , B ∈ R n × k A \in \mathbb{R}^{l \times n}, B \in \mathbb{R}^{n \times k} ARl×n,BRn×k,计算 A B AB AB需要进行 n n n次乘法运算和 n n n次加法运算,共计 2 n k 2nk 2nk次浮点数运算,需 2 n k 2nk 2nk次FLOPs。
    • 对于 A ∈ R m × n , B ∈ R n × p A \in \mathbb{R}^{m \times n}, B \in \mathbb{R}^{n \times p} ARm×n,BRn×p,计算 A B AB AB需要的浮点数运算次数为 2 m n p 2mnp 2mnp
4.2.2 Transformer各层参数及计算量如下表所示
OperationParametersFLOPs per Token
Embed ( n vocab + n ctx ) d model (n_{\text{vocab}} + n_{\text{ctx}}) d_{\text{model}} (nvocab+nctx)dmodel 4 d model 4d_{\text{model}} 4dmodel
Attention: QKV n layer d model 3 d attn n_{\text{layer}} d_{\text{model}} 3d_{\text{attn}} nlayerdmodel3dattn 2 n layer d model 3 d attn 2n_{\text{layer}} d_{\text{model}} 3d_{\text{attn}} 2nlayerdmodel3dattn
Attention: Mask- 2 n layer n ctx d attn 2n_{\text{layer}} n_{\text{ctx}} d_{\text{attn}} 2nlayernctxdattn
Attention: Project n layer d attn d model n_{\text{layer}} d_{\text{attn}} d_{\text{model}} nlayerdattndmodel 2 n layer d attn d embd 2n_{\text{layer}} d_{\text{attn}} d_{\text{embd}} 2nlayerdattndembd
Feedforward n layer 2 d model d ff n_{\text{layer}} 2d_{\text{model}} d_{\text{ff}} nlayer2dmodeldff 2 n layer 2 d model d ff 2n_{\text{layer}} 2d_{\text{model}} d_{\text{ff}} 2nlayer2dmodeldff
De-embed- 2 d model n vocab 2d_{\text{model}} n_{\text{vocab}} 2dmodelnvocab
Total (Non-Embedding) N = 2 d model n layer ( 2 d attn + d ff ) N = 2d_{\text{model}} n_{\text{layer}} (2d_{\text{attn}} + d_{\text{ff}}) N=2dmodelnlayer(2dattn+dff) C forward = 2 N + 2 n layer n ctx d attn C_{\text{forward}} = 2N + 2n_{\text{layer}} n_{\text{ctx}} d_{\text{attn}} Cforward=2N+2nlayernctxdattn
4.2.3 Embedding层
  • 功能
    Embedding层完成输入ID到向量的映射,将词表大小的ID映射到 d model d_{\text{model}} dmodel维度的向量。

  • 计算转换
    [ batch , n ctx ] × [ vocab , d model ] → [ batch , n ctx , d model ] [ \text{batch}, n_{\text{ctx}} ] \times [ \text{vocab}, d_{\text{model}} ] \rightarrow [ \text{batch}, n_{\text{ctx}}, d_{\text{model}} ] [batch,nctx]×[vocab,dmodel][batch,nctx,dmodel]

  • 操作
    这里的“ × \times ×”代表lookup操作。

  • 参数量

    • 词嵌入矩阵参数量大小为: n vocab × d model n_{\text{vocab}} \times d_{\text{model}} nvocab×dmodel
    • 上下文输入向量大小为: n ctx × d model n_{\text{ctx}} \times d_{\text{model}} nctx×dmodel
4.2.4 Attention QKV 层

功能
Attention QKV层完成输入向量到注意力层的映射,将隐层大小 d model d_{\text{model}} dmodel映射到多头注意力 3 d attn 3d_{\text{attn}} 3dattn维度的向量。

计算转换
[ batch , n ctx , d model ] × [ d model , 3 d attn ] [\text{batch}, n_{\text{ctx}}, d_{\text{model}}] \times [d_{\text{model}}, 3d_{\text{attn}}] [batch,nctx,dmodel]×[dmodel,3dattn]

参数量
每一层的变换如上所示,Attention QKV层参数量大小为: n layer d model 3 d attn n_{\text{layer}} d_{\text{model}} 3d_{\text{attn}} nlayerdmodel3dattn

计算量
计算量包括矩阵的乘法运算和加法运算两个操作,每个Token计算量大小为:
2 × batch × n ctx × n layer d model 3 d attn / ( batch × n ctx ) = 2 n layer d model 3 d attn 2 \times \text{batch} \times n_{\text{ctx}} \times n_{\text{layer}} d_{\text{model}} 3d_{\text{attn}} / (\text{batch} \times n_{\text{ctx}}) = 2n_{\text{layer}} d_{\text{model}} 3d_{\text{attn}} 2×batch×nctx×nlayerdmodel3dattn/(batch×nctx)=2nlayerdmodel3dattn

4.2.5 Attention Mask层

功能
Attention Mask层完成以下计算操作:

Softmax ( Q K T d model ) V \text{Softmax}\left( \frac{QK^T}{\sqrt{d_{\text{model}}}} \right) V Softmax(dmodel QKT)V

计算维度转换
[ batch , n ctx , d attn ] × [ batch , d attn , n ctx ] → [ batch , n ctx , n ctx ] [\text{batch}, n_{\text{ctx}}, d_{\text{attn}}] \times [\text{batch}, d_{\text{attn}}, n_{\text{ctx}}] \rightarrow [\text{batch}, n_{\text{ctx}}, n_{\text{ctx}}] [batch,nctx,dattn]×[batch,dattn,nctx][batch,nctx,nctx]

[ batch , n ctx , n ctx ] × [ batch , n ctx , d attn ] → [ batch , n ctx , d attn ] [\text{batch}, n_{\text{ctx}}, n_{\text{ctx}}] \times [\text{batch}, n_{\text{ctx}}, d_{\text{attn}}] \rightarrow [\text{batch}, n_{\text{ctx}}, d_{\text{attn}}] [batch,nctx,nctx]×[batch,nctx,dattn][batch,nctx,dattn]

未引入新的变量,因为无参数量。

计算量
Attention Mask层计算量包括矩阵的乘法运算和加法运算两个操作,每个Token计算量大小为:

2 × n layer × ( batch × n ctx × d attn × n ctx + batch × n ctx × n ctx × d attn ) / ( batch × n ctx ) = 2 n layer n ctx d attn 2 \times n_{\text{layer}} \times (\text{batch} \times n_{\text{ctx}} \times d_{\text{attn}} \times n_{\text{ctx}} + \text{batch} \times n_{\text{ctx}} \times n_{\text{ctx}} \times d_{\text{attn}}) / (\text{batch} \times n_{\text{ctx}}) = 2n_{\text{layer}} n_{\text{ctx}} d_{\text{attn}} 2×nlayer×(batch×nctx×dattn×nctx+batch×nctx×nctx×dattn)/(batch×nctx)=2nlayernctxdattn

4.2.6 Attention Project层总结

功能
Attention Project层完成从Attention输出维度 d attn d_{\text{attn}} dattn到隐层大小 d model d_{\text{model}} dmodel的映射。

计算维度转换
[ batch , n ctx , d attn ] × [ d attn , d model ] → [ batch , n ctx , d model ] [\text{batch}, n_{\text{ctx}}, d_{\text{attn}}] \times [d_{\text{attn}}, d_{\text{model}}] \rightarrow [\text{batch}, n_{\text{ctx}}, d_{\text{model}}] [batch,nctx,dattn]×[dattn,dmodel][batch,nctx,dmodel]

参数量
每一层的变化均如上所示,Attention Project层参数量大小为: n layer d attn d model n_{\text{layer}} d_{\text{attn}} d_{\text{model}} nlayerdattndmodel

计算量
Attention Project层计算量包括矩阵的乘法运算和加法运算两个操作,每个Token计算量大小为:

2 × n layer × batch × n ctx × d attn × d model / ( batch × n ctx ) = 2 n layer d attn d model 2 \times n_{\text{layer}} \times \text{batch} \times n_{\text{ctx}} \times d_{\text{attn}} \times d_{\text{model}} / (\text{batch} \times n_{\text{ctx}}) = 2n_{\text{layer}} d_{\text{attn}} d_{\text{model}} 2×nlayer×batch×nctx×dattn×dmodel/(batch×nctx)=2nlayerdattndmodel

4.2.7 Feedforward层总结

功能
Feedforward层完成从隐层大小 d model d_{\text{model}} dmodel到前馈隐层大小 d ff d_{\text{ff}} dff再到隐层大小 d model d_{\text{model}} dmodel的映射。

计算维度转换
[ batch , n ctx , d model ] × [ d model , d ff ] → [ batch , n ctx , d ff ] [\text{batch}, n_{\text{ctx}}, d_{\text{model}}] \times [d_{\text{model}}, d_{\text{ff}}] \rightarrow [\text{batch}, n_{\text{ctx}}, d_{\text{ff}}] [batch,nctx,dmodel]×[dmodel,dff][batch,nctx,dff]

[ batch , n ctx , d ff ] × [ d ff , d model ] → [ batch , n ctx , d model ] [\text{batch}, n_{\text{ctx}}, d_{\text{ff}}] \times [d_{\text{ff}}, d_{\text{model}}] \rightarrow [\text{batch}, n_{\text{ctx}}, d_{\text{model}}] [batch,nctx,dff]×[dff,dmodel][batch,nctx,dmodel]

参数量
每一层的变化均如上所示,Feedforward层参数量大小为: n layer 2 d model d ff n_{\text{layer}} 2d_{\text{model}} d_{\text{ff}} nlayer2dmodeldff

计算量
Feedforward层计算量包括矩阵的乘法运算和加法运算两个操作,每个Token计算量大小为:

2 × n layer × ( batch × n ctx × d model × d ff + batch × n ctx × d ff × d model ) / ( batch × n ctx ) = 2 n layer 2 d model d ff 2 \times n_{\text{layer}} \times (\text{batch} \times n_{\text{ctx}} \times d_{\text{model}} \times d_{\text{ff}} + \text{batch} \times n_{\text{ctx}} \times d_{\text{ff}} \times d_{\text{model}}) / (\text{batch} \times n_{\text{ctx}}) = 2n_{\text{layer}} 2d_{\text{model}} d_{\text{ff}} 2×nlayer×(batch×nctx×dmodel×dff+batch×nctx×dff×dmodel)/(batch×nctx)=2nlayer2dmodeldff

4.2.8 De-emb层总结

功能
De-emb层完成从隐层大小 d model d_{\text{model}} dmodel到输出 n vocab n_{\text{vocab}} nvocab的映射。

计算维度转换
[ batch , n ctx , d model ] × [ d model , n vocab ] → [ batch , n ctx , n vocab ] [\text{batch}, n_{\text{ctx}}, d_{\text{model}}] \times [d_{\text{model}}, n_{\text{vocab}}] \rightarrow [\text{batch}, n_{\text{ctx}}, n_{\text{vocab}}] [batch,nctx,dmodel]×[dmodel,nvocab][batch,nctx,nvocab]

操作方式
De-embedding层通常使用与输入嵌入层(Embedding层)相同的权重矩阵来进行线性转换。这种权重共享的策略有助于减少模型参数量,从而降低过拟合的风险。因此,不需要为De-embedding层单独分配参数量。

计算量
计算量包括矩阵的乘法运算和加法运算两个操作,每个Token计算量大小为:
2 × batch × n ctx × d model × n vocab / ( batch × n ctx ) = 2 d model n vocab 2 \times \text{batch} \times n_{\text{ctx}} \times d_{\text{model}} \times n_{\text{vocab}} / (\text{batch} \times n_{\text{ctx}}) = 2d_{\text{model}} n_{\text{vocab}} 2×batch×nctx×dmodel×nvocab/(batch×nctx)=2dmodelnvocab

4.2.9 总结

模型总参数量(不包括Embedding参数):
N = n layer ( d model 3 d attn + d attn d model + 2 d model d ff ) = 2 d model n layer ( 2 d attn + d ff ) N = n_{\text{layer}} (d_{\text{model}} 3d_{\text{attn}} + d_{\text{attn}} d_{\text{model}} + 2d_{\text{model}} d_{\text{ff}}) = 2d_{\text{model}} n_{\text{layer}} (2d_{\text{attn}} + d_{\text{ff}}) N=nlayer(dmodel3dattn+dattndmodel+2dmodeldff)=2dmodelnlayer(2dattn+dff)

每个Token计算量
C forward = 2 n layer ( d model 3 d attn + n ctx d model + d attn d model + 2 d model d ff ) C_{\text{forward}} = 2n_{\text{layer}} (d_{\text{model}} 3d_{\text{attn}} + n_{\text{ctx}} d_{\text{model}} + d_{\text{attn}} d_{\text{model}} + 2d_{\text{model}} d_{\text{ff}}) Cforward=2nlayer(dmodel3dattn+nctxdmodel+dattndmodel+2dmodeldff)
= 4 d model n layer ( 2 d attn + d ff ) + 2 n layer n ctx d attn = 4d_{\text{model}} n_{\text{layer}} (2d_{\text{attn}} + d_{\text{ff}}) + 2n_{\text{layer}} n_{\text{ctx}} d_{\text{attn}} =4dmodelnlayer(2dattn+dff)+2nlayernctxdattn
= 2 N + 2 n layer n ctx d attn = 2N + 2n_{\text{layer}} n_{\text{ctx}} d_{\text{attn}} =2N+2nlayernctxdattn

4.2.10 实例分析

以下是两个具体实例的分析及总结:

ChatGLM-6B
  • 参数

    • 层数:28层
    • 隐藏层大小:4096
    • 中间隐藏层大小:16384
    • 注意力头数:32
    • 词表大小:130528
    • 上下文长度:2048
  • 参数量计算
    N = 2 × 4096 × 28 × ( 2 × 4096 + 16386 ) + ( 130528 + 2048 ) × 4096 = 6 , 180 , 634 , 624 N = 2 \times 4096 \times 28 \times (2 \times 4096 + 16386) + (130528 + 2048) \times 4096 = 6,180,634,624 N=2×4096×28×(2×4096+16386)+(130528+2048)×4096=6,180,634,624

LLAMA-7B
  • 参数

    • 层数:32层
    • 隐藏层大小:4096
    • 中间隐藏层大小:11008
    • 注意力头数:32
    • 词表大小:32000
    • 上下文长度:2048
  • 参数量计算
    N = 2 × 4096 × 32 × ( 2 × 4096 + 11008 ) + ( 32000 + 2048 ) × 4096 = 5 , 172 , 625 , 408 N = 2 \times 4096 \times 32 \times (2 \times 4096 + 11008) + (32000 + 2048) \times 4096 = 5,172,625,408 N=2×4096×32×(2×4096+11008)+(32000+2048)×4096=5,172,625,408

计算结果与模型参数不符原因

发现上述计算结果与实际模型参数不符的原因在于LLAMA的前馈神经网络层采用了SwiGLU激活函数,使得FFN层的计算方式发生变化:

F F N SwiGLU ( x , W , V , W 2 ) = ( Swish ( x W ) ∘ x V ) W 2 FFN_{\text{SwiGLU}}(x, W, V, W_2) = (\text{Swish}(xW) \circ xV) W_2 FFNSwiGLU(x,W,V,W2)=(Swish(xW)xV)W2

因此,FFN相比原计算方式参数矩阵从2个变成了3个。

修正后的LLAMA-7B计算
  • 修正参数量计算
    N = 2 × 4096 × 32 × ( 2 × 4096 + 11008 × 3 / 2 ) + ( 32000 + 2048 ) × 4096 = 6 , 615 , 465 , 984 N = 2 \times 4096 \times 32 \times (2 \times 4096 + 11008 \times 3 / 2) + (32000 + 2048) \times 4096 = 6,615,465,984 N=2×4096×32×(2×4096+11008×3/2)+(32000+2048)×4096=6,615,465,984
LLAMA-13B
  • 参数

    • 层数:40层
    • 隐藏层大小:5120
    • 中间隐藏层大小:13824
    • 注意力头数:40
    • 词表大小:32000
    • 上下文长度:2048
  • 参数量计算
    N = 2 × 5120 × 40 × ( 2 × 5120 + 13824 × 3 / 2 ) + ( 32000 + 2048 ) × 5120 = 12 , 862 , 095 , 360 N = 2 \times 5120 \times 40 \times (2 \times 5120 + 13824 \times 3 / 2) + (32000 + 2048) \times 5120 = 12,862,095,360 N=2×5120×40×(2×5120+13824×3/2)+(32000+2048)×5120=12,862,095,360

4.3 优化器

4.3.1 Adam优化器的显存计算公式
  1. 模型参数显存
    模型参数显存 = 参数数量 × 每个参数的字节数 \text{模型参数显存} = \text{参数数量} \times \text{每个参数的字节数} 模型参数显存=参数数量×每个参数的字节数

  2. 动量(m)显存 (梯度指数平滑值):
    动量显存 = 参数数量 × 每个动量变量的字节数 \text{动量显存} = \text{参数数量} \times \text{每个动量变量的字节数} 动量显存=参数数量×每个动量变量的字节数

  3. 平方梯度(v)显存 (梯度平方指数平滑值):
    平方梯度显存 = 参数数量 × 每个平方梯度变量的字节数 \text{平方梯度显存} = \text{参数数量} \times \text{每个平方梯度变量的字节数} 平方梯度显存=参数数量×每个平方梯度变量的字节数

  4. Adam优化器总显存

Adam优化器总显存 = 动量显存 + 平方梯度显存 \text{Adam优化器总显存} = \text{动量显存} + \text{平方梯度显存} Adam优化器总显存=动量显存+平方梯度显存

LLama13B 有130亿(13B)个参数,每个参数为32位浮点数(4字节)(因为梯度值很小,需要用FP32保存,以避免精度损失)

4.3.2 LLama 13B Adam优化器的显存计算实例
  1. 模型参数显存

    模型参数显存 = 13 × 1 0 9 × 4 字节 = 52 GB \text{模型参数显存} = 13 \times 10^9 \times 4 \text{字节} = 52 \text{GB} 模型参数显存=13×109×4字节=52GB

  2. 动量显存
    动量显存 = 13 × 1 0 9 × 4 字节 = 52 GB \text{动量显存} = 13 \times 10^9 \times 4 \text{字节} = 52 \text{GB} 动量显存=13×109×4字节=52GB

  3. 平方梯度显存
    平方梯度显存 = 13 × 1 0 9 × 4 字节 = 52 GB \text{平方梯度显存} = 13 \times 10^9 \times 4 \text{字节} = 52 \text{GB} 平方梯度显存=13×109×4字节=52GB

  4. Adam优化器总显存
    Adam优化器总显存 = 2 × 动量显存 = 2 × 52 GB = 104 GB \text{Adam优化器总显存} = 2 \times \text{动量显存} = 2 \times 52 \text{GB} = 104 \text{GB} Adam优化器总显存=2×动量显存=2×52GB=104GB

  5. 总计 : 156GB

4.4 激活值

对于激活值的估计,采用了Reducing Activation Recomputation in Large Transformer Models 这篇论文的激活值估算方法。

激活内存需求的计算分为三部分:注意力块、MLP块和层规范化(Layer Norm)。每个部分的内存需求如下:

  • s:序列长度(Sequence Length),表示输入序列的长度。例如,在自然语言处理中,s表示输入句子的单词数。
  • b:微批次大小(Microbatch Size),表示一次计算中处理的样本数量。这个值通常是一个较小的批次大小,以便在计算资源受限时更高效地进行训练。
  • h:隐藏层维度(Hidden Dimension Size),表示Transformer模型中每一层的隐藏状态的维度。h通常是一个较大的值,以提供足够的表示能力。

在这里插入图片描述

  1. 注意力块(Attention Block)

    • 线性投影输入激活值:2sbh
    • 注意力dropout所需的掩码:sbh
    • 自注意力(Self-Attention)
      • Q, K, V矩阵乘法的输入激活值:2sbh
      • QKT矩阵乘法:4sbh
      • Softmax输出:2as^2b
      • Softmax dropout的掩码:as^2b
      • 注意力值(Values)和其dropout输出:2as^2b + 2sbh
    • 总计:11sbh + 5as^2b
  2. MLP块

    • 两个线性层的输入激活值:2sbh和8sbh
    • GeLU非线性激活:8sbh
    • Dropout的掩码:sbh
    • 总计:19sbh
  3. 层规范化(Layer Norm)

    • 每个层规范化的输入激活值:2sbh
    • 总计:4sbh

综合以上计算,一个Transformer层的激活内存需求为:
Activations memory per layer = s b h ( 34 + 5 a s h ) \text{Activations memory per layer} = sbh \left(34 + \frac{5as}{h}\right) Activations memory per layer=sbh(34+h5as)

4.4.1 总激活内存需求

对于包含L层的Transformer网络,总激活内存需求为:
Total activations memory = s b h L ( 34 + 5 a s h ) \text{Total activations memory} = sbhL \left(34 + \frac{5as}{h}\right) Total activations memory=sbhL(34+h5as)
这种公式计算方法考虑了主要的激活内存贡献者,忽略了较小的缓冲区,提供了一个较为准确的激活内存需求估算。

4.4.2 LLama 13B 激活内存计算实例

激活值的内存消耗计算公式为:

Memory (GB) = s × b × h × ( 34 + 5 × a × s h ) × L 1024 × 1024 × 1024 \text{Memory (GB)} = \frac{s \times b \times h \times (34 + 5 \times a \times \frac{s}{h}) \times L}{1024 \times 1024 \times 1024} Memory (GB)=1024×1024×1024s×b×h×(34+5×a×hs)×L
LLama 13B

  • s 序列长度:1024
  • b batch size:1
  • h 隐藏层大小:5120
  • a Attention 头:40
  • L 层数 :40

FP16:

s * b * h * (34 + 5 * a * s/h ) * L /1024 /1024/1024 GB = 14.5GB

4.5 梯度值

与推理相比,我们只需要在传递给下一层之前存储单个层的激活,微调需要存储前向传播过程中创建的所有激活。这对于计算梯度是必要的,然后用于反向传播误差并更新模型的权重。

为了估计计算梯度所需的内存,我们可以使用用于推理的相同公式,然后将结果乘以层数。

在反向传播过程中,需要存储每一层的梯度,这些梯度包括参数的梯度和激活值的梯度。

一个Transformer层的梯度内存需求为:
Gradients memory per layer = s b h ( 34 + 5 a s h ) \text{Gradients memory per layer} = sbh \left(34 + \frac{5as}{h}\right) Gradients memory per layer=sbh(34+h5as)
如果L是层数,那么计算梯度所消耗的内存为
Total memory per layer = s b h L ( 34 + 5 a s h ) \text{Total memory per layer} = sbhL \left(34 + \frac{5as}{h}\right) Total memory per layer=sbhL(34+h5as)
FP16:

s * b * h * (34 + 5 * a * s/h ) * L /1024 /1024/1024 GB = 14.5GB

4.6 总计

Batch Size = 1 , Seq_Len = 1024, FP16

  • 模型参数:26GB
  • 优化器:156GB
  • 激活值:14.5GB
  • 梯度值:26GB
  • 合计:222.5GB

5. 模型GPU显存占用(实验代码计算)

5.1 简介

本文使用Wanda方法,已在Github上开源

论文:A Simple and Effective Pruning Approach for Large Language Models

**源码:**https://github.com/locuslab/wanda

环境配置

  • 操作系统:Windows11
  • GPU :Nvidia RTX 3090
  • Python : 3.9
  • pytorch==1.10.1
  • cudatoolkit==11.3
  • transformers==4.28.0
  • datasets==2.11.0
  • accelerate==0.18.0

详细环境配置以及使用手册请查看 Github 中的 README 文件

5.2定义显存监控函数

定义一个显存监控函数 print_memory_usage,以便在代码中调用:

import torchdef print_memory_usage(stage=''):"""打印当前显存使用情况"""allocated = torch.cuda.memory_allocated() / 1024**3  # 转换为GBreserved = torch.cuda.memory_reserved() / 1024**3    # 转换为GBprint(f"{stage} - Allocated memory: {allocated:.2f} GB")print(f"{stage} - Reserved memory: {reserved:.2f} GB")

5.3 Magnitude 方法实例

5.3.1 代码实例

prune.pyprune_magnitude函数中添加print_memory_usage查看显存函数

def prune_magnitude(args, model, tokenizer, device=torch.device("cuda:0"), prune_n=0, prune_m=0):layers = model.model.layers# 在开始修剪之前,打印当前显存使用情况。这样可以了解开始修剪之前的显存状态。print_memory_usage("剪枝之前")for i in range(len(layers)):layer = layers[i]subset = find_layers(layer)# 在处理每一层之前打印显存使用情况。这有助于监控每一层处理对显存的影响。print_memory_usage(f"处理第 {i} 层之前")for name in subset:W = subset[name].weight.dataW_metric = torch.abs(W)if prune_n != 0:W_mask = (torch.zeros_like(W)==1)for ii in range(W_metric.shape[1]):if ii % prune_m == 0:tmp = W_metric[:,ii:(ii+prune_m)].float()W_mask.scatter_(1,ii+torch.topk(tmp, prune_n,dim=1, largest=False)[1], True)else:thresh = torch.sort(W_metric.flatten().cuda())[0][int(W.numel()*args.sparsity_ratio)].cpu()W_mask = (W_metric<=thresh)W[W_mask] = 0# 在每一层的权重修剪之后打印显存使用情况。这样可以了解修剪操作对显存的影响。print_memory_usage(f"剪枝第 {i} 的权重 {name} 之后")# 在所有层修剪完成之后打印显存使用情况,获取整体的显存使用情况print_memory_usage("剪枝所有层之后")
5.3.2 实验运行
python main.py --model meta-llama/Llama-2-7b-hf --prune_method magnitude --sparsity_ratio 0.5 --sparsity_type unstructured --save out/llama2_7b/unstructured/magnitude/

详细解释:

  1. 加载 meta-llama/Llama-2-7b-hf 模型。
  2. 使用 magnitude 剪枝方法对模型进行剪枝。
  3. 剪枝的稀疏率设为50%,即模型的50%参数会被剪掉。
  4. 剪枝类型是不结构化的稀疏(unstructured),参数可以任意位置剪枝。
  5. 最后,将剪枝后的模型保存到指定的目录 out/llama2_7b/unstructured/magnitude/
5.3.3 实验结果
use device  cuda:0
pruning starts
剪枝之前 - 分配内存: 12.68 GB
剪枝之前 - 保留内存: 12.69 GB
处理第 0 层之前 - 分配内存: 12.68 GB
处理第 0 层之前 - 保留内存: 12.69 GB
剪枝第 0 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 0 的权重 self_attn.q_proj 之后 - 保留内存: 13.35 GB
剪枝第 0 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 0 的权重 self_attn.k_proj 之后 - 保留内存: 13.35 GB
剪枝第 0 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 0 的权重 self_attn.v_proj 之后 - 保留内存: 13.35 GB
剪枝第 0 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 0 的权重 self_attn.o_proj 之后 - 保留内存: 13.35 GB
剪枝第 0 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 0 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 0 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 0 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 0 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 0 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 1 层之前 - 分配内存: 12.80 GB
处理第 1 层之前 - 保留内存: 14.95 GB
剪枝第 1 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 1 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 1 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 1 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 1 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 1 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 1 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 1 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 1 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 1 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 1 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 1 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 1 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 1 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 2 层之前 - 分配内存: 12.80 GB
处理第 2 层之前 - 保留内存: 14.95 GB
剪枝第 2 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 2 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 2 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 2 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 2 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 2 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 2 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 2 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 2 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 2 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 2 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 2 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 2 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 2 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 3 层之前 - 分配内存: 12.80 GB
处理第 3 层之前 - 保留内存: 14.95 GB
剪枝第 3 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 3 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 3 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 3 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 3 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 3 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 3 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 3 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 3 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 3 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 3 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 3 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 3 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 3 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 4 层之前 - 分配内存: 12.80 GB
处理第 4 层之前 - 保留内存: 14.95 GB
剪枝第 4 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 4 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 4 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 4 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 4 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 4 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 4 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 4 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 4 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 4 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 4 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 4 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 4 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 4 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 5 层之前 - 分配内存: 12.80 GB
处理第 5 层之前 - 保留内存: 14.95 GB
剪枝第 5 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 5 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 5 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 5 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 5 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 5 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 5 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 5 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 5 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 5 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 5 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 5 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 5 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 5 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 6 层之前 - 分配内存: 12.80 GB
处理第 6 层之前 - 保留内存: 14.95 GB
剪枝第 6 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 6 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 6 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 6 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 6 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 6 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 6 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 6 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 6 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 6 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 6 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 6 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 6 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 6 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 7 层之前 - 分配内存: 12.80 GB
处理第 7 层之前 - 保留内存: 14.95 GB
剪枝第 7 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 7 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 7 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 7 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 7 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 7 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 7 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 7 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 7 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 7 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 7 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 7 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 7 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 7 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 8 层之前 - 分配内存: 12.80 GB
处理第 8 层之前 - 保留内存: 14.95 GB
剪枝第 8 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 8 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 8 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 8 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 8 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 8 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 8 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 8 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 8 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 8 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 8 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 8 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 8 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 8 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 9 层之前 - 分配内存: 12.80 GB
处理第 9 层之前 - 保留内存: 14.95 GB
剪枝第 9 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 9 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 9 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 9 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 9 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 9 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 9 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 9 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 9 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 9 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 9 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 9 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 9 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 9 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 10 层之前 - 分配内存: 12.80 GB
处理第 10 层之前 - 保留内存: 14.95 GB
剪枝第 10 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 10 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 10 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 10 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 10 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 10 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 10 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 10 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 10 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 10 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 10 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 10 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 10 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 10 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 11 层之前 - 分配内存: 12.80 GB
处理第 11 层之前 - 保留内存: 14.95 GB
剪枝第 11 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 11 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 11 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 11 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 11 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 11 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 11 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 11 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 11 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 11 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 11 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 11 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 11 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 11 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 12 层之前 - 分配内存: 12.80 GB
处理第 12 层之前 - 保留内存: 14.95 GB
剪枝第 12 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 12 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 12 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 12 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 12 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 12 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 12 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 12 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 12 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 12 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 12 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 12 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 12 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 12 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 13 层之前 - 分配内存: 12.80 GB
处理第 13 层之前 - 保留内存: 14.95 GB
剪枝第 13 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 13 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 13 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 13 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 13 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 13 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 13 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 13 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 13 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 13 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 13 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 13 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 13 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 13 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 14 层之前 - 分配内存: 12.80 GB
处理第 14 层之前 - 保留内存: 14.95 GB
剪枝第 14 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 14 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 14 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 14 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 14 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 14 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 14 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 14 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 14 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 14 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 14 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 14 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 14 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 14 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 15 层之前 - 分配内存: 12.80 GB
处理第 15 层之前 - 保留内存: 14.95 GB
剪枝第 15 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 15 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 15 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 15 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 15 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 15 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 15 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 15 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 15 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 15 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 15 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 15 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 15 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 15 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 16 层之前 - 分配内存: 12.80 GB
处理第 16 层之前 - 保留内存: 14.95 GB
剪枝第 16 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 16 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 16 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 16 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 16 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 16 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 16 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 16 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 16 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 16 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 16 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 16 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 16 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 16 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 17 层之前 - 分配内存: 12.80 GB
处理第 17 层之前 - 保留内存: 14.95 GB
剪枝第 17 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 17 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 17 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 17 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 17 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 17 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 17 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 17 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 17 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 17 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 17 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 17 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 17 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 17 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 18 层之前 - 分配内存: 12.80 GB
处理第 18 层之前 - 保留内存: 14.95 GB
剪枝第 18 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 18 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 18 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 18 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 18 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 18 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 18 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 18 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 18 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 18 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 18 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 18 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 18 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 18 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 19 层之前 - 分配内存: 12.80 GB
处理第 19 层之前 - 保留内存: 14.95 GB
剪枝第 19 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 19 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 19 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 19 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 19 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 19 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 19 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 19 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 19 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 19 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 19 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 19 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 19 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 19 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 20 层之前 - 分配内存: 12.80 GB
处理第 20 层之前 - 保留内存: 14.95 GB
剪枝第 20 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 20 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 20 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 20 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 20 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 20 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 20 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 20 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 20 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 20 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 20 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 20 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 20 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 20 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 21 层之前 - 分配内存: 12.80 GB
处理第 21 层之前 - 保留内存: 14.95 GB
剪枝第 21 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 21 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 21 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 21 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 21 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 21 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 21 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 21 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 21 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 21 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 21 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 21 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 21 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 21 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 22 层之前 - 分配内存: 12.80 GB
处理第 22 层之前 - 保留内存: 14.95 GB
剪枝第 22 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 22 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 22 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 22 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 22 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 22 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 22 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 22 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 22 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 22 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 22 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 22 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 22 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 22 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 23 层之前 - 分配内存: 12.80 GB
处理第 23 层之前 - 保留内存: 14.95 GB
剪枝第 23 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 23 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 23 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 23 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 23 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 23 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 23 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 23 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 23 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 23 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 23 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 23 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 23 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 23 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 24 层之前 - 分配内存: 12.80 GB
处理第 24 层之前 - 保留内存: 14.95 GB
剪枝第 24 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 24 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 24 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 24 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 24 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 24 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 24 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 24 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 24 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 24 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 24 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 24 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 24 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 24 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 25 层之前 - 分配内存: 12.80 GB
处理第 25 层之前 - 保留内存: 14.95 GB
剪枝第 25 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 25 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 25 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 25 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 25 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 25 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 25 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 25 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 25 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 25 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 25 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 25 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 25 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 25 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 26 层之前 - 分配内存: 12.80 GB
处理第 26 层之前 - 保留内存: 14.95 GB
剪枝第 26 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 26 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 26 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 26 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 26 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 26 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 26 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 26 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 26 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 26 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 26 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 26 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 26 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 26 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 27 层之前 - 分配内存: 12.80 GB
处理第 27 层之前 - 保留内存: 14.95 GB
剪枝第 27 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 27 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 27 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 27 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 27 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 27 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 27 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 27 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 27 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 27 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 27 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 27 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 27 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 27 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 28 层之前 - 分配内存: 12.80 GB
处理第 28 层之前 - 保留内存: 14.95 GB
剪枝第 28 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 28 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 28 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 28 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 28 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 28 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 28 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 28 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 28 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 28 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 28 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 28 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 28 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 28 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 29 层之前 - 分配内存: 12.80 GB
处理第 29 层之前 - 保留内存: 14.95 GB
剪枝第 29 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 29 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 29 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 29 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 29 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 29 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 29 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 29 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 29 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 29 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 29 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 29 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 29 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 29 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 30 层之前 - 分配内存: 12.80 GB
处理第 30 层之前 - 保留内存: 14.95 GB
剪枝第 30 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 30 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 30 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 30 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 30 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 30 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 30 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 30 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 30 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 30 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 30 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 30 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 30 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 30 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
处理第 31 层之前 - 分配内存: 12.80 GB
处理第 31 层之前 - 保留内存: 14.95 GB
剪枝第 31 的权重 self_attn.q_proj 之后 - 分配内存: 12.72 GB
剪枝第 31 的权重 self_attn.q_proj 之后 - 保留内存: 14.95 GB
剪枝第 31 的权重 self_attn.k_proj 之后 - 分配内存: 12.72 GB
剪枝第 31 的权重 self_attn.k_proj 之后 - 保留内存: 14.95 GB
剪枝第 31 的权重 self_attn.v_proj 之后 - 分配内存: 12.72 GB
剪枝第 31 的权重 self_attn.v_proj 之后 - 保留内存: 14.95 GB
剪枝第 31 的权重 self_attn.o_proj 之后 - 分配内存: 12.72 GB
剪枝第 31 的权重 self_attn.o_proj 之后 - 保留内存: 14.95 GB
剪枝第 31 的权重 mlp.gate_proj 之后 - 分配内存: 12.80 GB
剪枝第 31 的权重 mlp.gate_proj 之后 - 保留内存: 14.95 GB
剪枝第 31 的权重 mlp.down_proj 之后 - 分配内存: 12.80 GB
剪枝第 31 的权重 mlp.down_proj 之后 - 保留内存: 14.95 GB
剪枝第 31 的权重 mlp.up_proj 之后 - 分配内存: 12.80 GB
剪枝第 31 的权重 mlp.up_proj 之后 - 保留内存: 14.95 GB
剪枝所有层之后 - 分配内存: 12.80 GB
剪枝所有层之后 - 保留内存: 14.95 GB
******************************
layer 0 sparsity 0.500654
layer 1 sparsity 0.500707
layer 2 sparsity 0.500744
layer 3 sparsity 0.501227
layer 4 sparsity 0.501123
layer 5 sparsity 0.501560
layer 6 sparsity 0.500812
layer 7 sparsity 0.501593
layer 8 sparsity 0.500865
layer 9 sparsity 0.501034
layer 10 sparsity 0.500843
layer 11 sparsity 0.501353
layer 12 sparsity 0.501236
layer 13 sparsity 0.501154
layer 14 sparsity 0.501012
layer 15 sparsity 0.501432
layer 16 sparsity 0.501073
layer 17 sparsity 0.500963
layer 18 sparsity 0.501161
layer 19 sparsity 0.500545
layer 20 sparsity 0.500673
layer 21 sparsity 0.501270
layer 22 sparsity 0.500906
layer 23 sparsity 0.500999
layer 24 sparsity 0.500991
layer 25 sparsity 0.501228
layer 26 sparsity 0.500776
layer 27 sparsity 0.500648
layer 28 sparsity 0.501165
layer 29 sparsity 0.501206
layer 30 sparsity 0.501136
layer 31 sparsity 0.500962
sparsity sanity check 0.5010
******************************
evaluating on wikitext2
nsamples 83
sample 0
sample 50
wikitext perplexity 14.89717960357666
5.3.4 输出文件结果
method	actual_sparsity	ppl_test
magnitude	0.5010	14.8972

5.4 Wanda 方法实例

5.4.1 代码实例

prune.pyprune_wanda函数中添加print_memory_usage查看显存函数

def prune_wanda(args, model, tokenizer, device=torch.device("cuda:0"), prune_n=0, prune_m=0):use_cache = model.config.use_cache  # 保存模型的use_cache配置model.config.use_cache = False  # 关闭缓存以节省显存print("loading calibration data")print_memory_usage("加载数据前的显存使用情况")  # 打印加载数据前的显存使用情况dataloader, _ = get_loaders("c4", nsamples=args.nsamples, seed=args.seed, seqlen=model.seqlen,tokenizer=tokenizer)  # 获取数据加载器print_memory_usage("加载数据后的显存使用情况")  # 打印加载数据后的显存使用情况with torch.no_grad():  # 禁用梯度计算print_memory_usage("准备校准输入前的显存使用情况")  # 打印准备校准输入前的显存使用情况inps, outs, attention_mask, position_ids = prepare_calibration_input(model, dataloader, device)  # 准备校准数据print_memory_usage("准备校准输入后的显存使用情况")  # 打印准备校准输入后的显存使用情况layers = model.model.layers  # 获取模型的所有层for i in range(len(layers)):  # 遍历所有层layer = layers[i]  # 获取第i层subset = find_layers(layer)  # 获取该层的子层if f"model.layers.{i}" in model.hf_device_map:  # 如果层i在设备映射中dev = model.hf_device_map[f"model.layers.{i}"]  # 获取该层所在设备print(f"layer {i} device {dev}")inps, outs, attention_mask, position_ids = inps.to(dev), outs.to(dev), attention_mask.to(dev), position_ids.to(dev)  # 将数据移动到正确的设备wrapped_layers = {}  # 创建一个空字典来存储包装的层for name in subset:  # 遍历每个子层wrapped_layers[name] = WrappedGPT(subset[name])  # 包装子层def add_batch(name):def tmp(_, inp, out):wrapped_layers[name].add_batch(inp[0].data, out.data)  # 收集数据return tmphandles = []for name in wrapped_layers:  # 为每个包装的层注册前向钩子handles.append(subset[name].register_forward_hook(add_batch(name)))print_memory_usage(f"第 {i} 层前向传播前")  # 打印前向传播前的显存使用情况for j in range(args.nsamples):  # 对每个样本执行前向传播with torch.no_grad():  # 禁用梯度计算outs[j] = layer(inps[j].unsqueeze(0), attention_mask=attention_mask, position_ids=position_ids)[0]print_memory_usage(f"第 {i} 层前向传播后")  # 打印前向传播后的显存使用情况for h in handles:  # 移除前向钩子h.remove()for name in subset:  # 对每个子层进行剪枝print(f"pruning layer {i} name {name}")W_metric = torch.abs(subset[name].weight.data) * torch.sqrt(wrapped_layers[name].scaler_row.reshape((1, -1)))  # 计算权重度量W_mask = (torch.zeros_like(W_metric) == 1)  ## 初始化一个全False的掩码if prune_n != 0:# structured n:m sparsity  # 结构化的n:m稀疏性for ii in range(W_metric.shape[1]):  # 遍历每个权重列if ii % prune_m == 0:  # 对于每m列的开始位置tmp = W_metric[:, ii:(ii + prune_m)].float()  # 计算当前列的度量W_mask.scatter_(1, ii + torch.topk(tmp, prune_n, dim=1, largest=False)[1], True)  # 更新掩码else:sort_res = torch.sort(W_metric, dim=-1, stable=True)  # 对度量进行排序if args.use_variant:# wanda variant  # Wanda变体tmp_metric = torch.cumsum(sort_res[0], dim=1)  # 计算累积度量sum_before = W_metric.sum(dim=1)  # 计算剪枝前的总和alpha = 0.4alpha_hist = [0., 0.8]W_mask, cur_sparsity = return_given_alpha(alpha, sort_res, W_metric, tmp_metric,sum_before)  # 根据alpha计算掩码和稀疏度while (torch.abs(cur_sparsity - args.sparsity_ratio) > 0.001) and (alpha_hist[1] - alpha_hist[0] >= 0.001):if cur_sparsity > args.sparsity_ratio:  # 如果当前稀疏度大于目标稀疏度alpha_new = (alpha + alpha_hist[0]) / 2.0alpha_hist[1] = alphaelse:alpha_new = (alpha + alpha_hist[1]) / 2.0alpha_hist[0] = alphaalpha = alpha_newW_mask, cur_sparsity = return_given_alpha(alpha, sort_res, W_metric, tmp_metric,sum_before)  # 重新计算掩码和稀疏度print(f"alpha found {alpha} sparsity {cur_sparsity:.6f}")  # 打印找到的alpha值和稀疏度else:# unstructured pruning  # 无结构剪枝indices = sort_res[1][:, :int(W_metric.shape[1] * args.sparsity_ratio)]  # 计算需要剪枝的权重索引W_mask.scatter_(1, indices, True)  # 更新掩码subset[name].weight.data[W_mask] = 0  ## 将权重设为零print_memory_usage(f"第 {i} 层剪枝后显存使用情况")  # 打印剪枝后的显存使用情况for j in range(args.nsamples):  # 对每个样本执行前向传播以验证剪枝效果with torch.no_grad():  # 禁用梯度计算outs[j] = layer(inps[j].unsqueeze(0), attention_mask=attention_mask, position_ids=position_ids)[0]inps, outs = outs, inps  # 交换输入和输出以进行下一轮处理model.config.use_cache = use_cache  # 恢复模型的use_cache配置torch.cuda.empty_cache()  # 清空显存缓存print_memory_usage("清理缓存后的显存使用情况")  # 打印清理缓存后的显存使用情况
5.4.2 实验运行
python main.py --model meta-llama/Llama-2-7b-hf --prune_method wanda --sparsity_ratio 0.5 --sparsity_type unstructured --save out/llama2_7b/unstructured/wanda/

详细解释:

  1. 加载 meta-llama/Llama-2-7b-hf 模型。
  2. 使用 wanda 剪枝方法对模型进行剪枝。
  3. 剪枝的稀疏率设为50%,即模型的50%参数会被剪掉。
  4. 剪枝类型是不结构化的稀疏(unstructured),参数可以任意位置剪枝。
  5. 最后,将剪枝后的模型保存到指定的目录 out/llama2_7b/unstructured/wanda/
5.4.3 实验结果
use device  cuda:0
pruning starts
loading calibration data
Before data loading - Allocated memory: 12.68 GB
Before data loading - Reserved memory: 12.69 GB
After data loading - Allocated memory: 12.68 GB
After data loading - Reserved memory: 12.69 GB
Before calibration input preparation - Allocated memory: 12.68 GB
Before calibration input preparation - Reserved memory: 12.69 GB
After calibration input preparation - Allocated memory: 20.71 GB
After calibration input preparation - Reserved memory: 20.92 GB
Before forward pass of layer 0 - Allocated memory: 20.71 GB
Before forward pass of layer 0 - Reserved memory: 20.92 GB
After forward pass of layer 0 - Allocated memory: 20.71 GB
After forward pass of layer 0 - Reserved memory: 25.02 GB
pruning layer 0 name self_attn.q_proj
pruning layer 0 name self_attn.k_proj
pruning layer 0 name self_attn.v_proj
pruning layer 0 name self_attn.o_proj
pruning layer 0 name mlp.gate_proj
pruning layer 0 name mlp.down_proj
pruning layer 0 name mlp.up_proj
After pruning layer 0 - Allocated memory: 21.42 GB
After pruning layer 0 - Reserved memory: 25.02 GB
Before forward pass of layer 1 - Allocated memory: 21.42 GB
Before forward pass of layer 1 - Reserved memory: 27.02 GB
After forward pass of layer 1 - Allocated memory: 21.42 GB
After forward pass of layer 1 - Reserved memory: 27.02 GB
pruning layer 1 name self_attn.q_proj
pruning layer 1 name self_attn.k_proj
pruning layer 1 name self_attn.v_proj
pruning layer 1 name self_attn.o_proj
pruning layer 1 name mlp.gate_proj
pruning layer 1 name mlp.down_proj
pruning layer 1 name mlp.up_proj
After pruning layer 1 - Allocated memory: 21.42 GB
After pruning layer 1 - Reserved memory: 27.02 GB
Before forward pass of layer 2 - Allocated memory: 21.42 GB
Before forward pass of layer 2 - Reserved memory: 27.02 GB
After forward pass of layer 2 - Allocated memory: 21.42 GB
After forward pass of layer 2 - Reserved memory: 27.02 GB
pruning layer 2 name self_attn.q_proj
pruning layer 2 name self_attn.k_proj
pruning layer 2 name self_attn.v_proj
pruning layer 2 name self_attn.o_proj
pruning layer 2 name mlp.gate_proj
pruning layer 2 name mlp.down_proj
pruning layer 2 name mlp.up_proj
After pruning layer 2 - Allocated memory: 21.42 GB
After pruning layer 2 - Reserved memory: 27.02 GB
Before forward pass of layer 3 - Allocated memory: 21.42 GB
Before forward pass of layer 3 - Reserved memory: 27.02 GB
After forward pass of layer 3 - Allocated memory: 21.42 GB
After forward pass of layer 3 - Reserved memory: 27.02 GB
pruning layer 3 name self_attn.q_proj
pruning layer 3 name self_attn.k_proj
pruning layer 3 name self_attn.v_proj
pruning layer 3 name self_attn.o_proj
pruning layer 3 name mlp.gate_proj
pruning layer 3 name mlp.down_proj
pruning layer 3 name mlp.up_proj
After pruning layer 3 - Allocated memory: 21.42 GB
After pruning layer 3 - Reserved memory: 27.02 GB
Before forward pass of layer 4 - Allocated memory: 21.42 GB
Before forward pass of layer 4 - Reserved memory: 27.02 GB
After forward pass of layer 4 - Allocated memory: 21.42 GB
After forward pass of layer 4 - Reserved memory: 27.02 GB
pruning layer 4 name self_attn.q_proj
pruning layer 4 name self_attn.k_proj
pruning layer 4 name self_attn.v_proj
pruning layer 4 name self_attn.o_proj
pruning layer 4 name mlp.gate_proj
pruning layer 4 name mlp.down_proj
pruning layer 4 name mlp.up_proj
After pruning layer 4 - Allocated memory: 21.42 GB
After pruning layer 4 - Reserved memory: 27.02 GB
Before forward pass of layer 5 - Allocated memory: 21.42 GB
Before forward pass of layer 5 - Reserved memory: 27.02 GB
After forward pass of layer 5 - Allocated memory: 21.42 GB
After forward pass of layer 5 - Reserved memory: 27.02 GB
pruning layer 5 name self_attn.q_proj
pruning layer 5 name self_attn.k_proj
pruning layer 5 name self_attn.v_proj
pruning layer 5 name self_attn.o_proj
pruning layer 5 name mlp.gate_proj
pruning layer 5 name mlp.down_proj
pruning layer 5 name mlp.up_proj
After pruning layer 5 - Allocated memory: 21.42 GB
After pruning layer 5 - Reserved memory: 27.02 GB
Before forward pass of layer 6 - Allocated memory: 21.42 GB
Before forward pass of layer 6 - Reserved memory: 27.02 GB
After forward pass of layer 6 - Allocated memory: 21.42 GB
After forward pass of layer 6 - Reserved memory: 27.02 GB
pruning layer 6 name self_attn.q_proj
pruning layer 6 name self_attn.k_proj
pruning layer 6 name self_attn.v_proj
pruning layer 6 name self_attn.o_proj
pruning layer 6 name mlp.gate_proj
pruning layer 6 name mlp.down_proj
pruning layer 6 name mlp.up_proj
After pruning layer 6 - Allocated memory: 21.42 GB
After pruning layer 6 - Reserved memory: 27.02 GB
Before forward pass of layer 7 - Allocated memory: 21.42 GB
Before forward pass of layer 7 - Reserved memory: 27.02 GB
After forward pass of layer 7 - Allocated memory: 21.42 GB
After forward pass of layer 7 - Reserved memory: 27.02 GB
pruning layer 7 name self_attn.q_proj
pruning layer 7 name self_attn.k_proj
pruning layer 7 name self_attn.v_proj
pruning layer 7 name self_attn.o_proj
pruning layer 7 name mlp.gate_proj
pruning layer 7 name mlp.down_proj
pruning layer 7 name mlp.up_proj
After pruning layer 7 - Allocated memory: 21.42 GB
After pruning layer 7 - Reserved memory: 27.02 GB
Before forward pass of layer 8 - Allocated memory: 21.42 GB
Before forward pass of layer 8 - Reserved memory: 27.02 GB
After forward pass of layer 8 - Allocated memory: 21.42 GB
After forward pass of layer 8 - Reserved memory: 27.02 GB
pruning layer 8 name self_attn.q_proj
pruning layer 8 name self_attn.k_proj
pruning layer 8 name self_attn.v_proj
pruning layer 8 name self_attn.o_proj
pruning layer 8 name mlp.gate_proj
pruning layer 8 name mlp.down_proj
pruning layer 8 name mlp.up_proj
After pruning layer 8 - Allocated memory: 21.42 GB
After pruning layer 8 - Reserved memory: 27.02 GB
Before forward pass of layer 9 - Allocated memory: 21.42 GB
Before forward pass of layer 9 - Reserved memory: 27.02 GB
After forward pass of layer 9 - Allocated memory: 21.42 GB
After forward pass of layer 9 - Reserved memory: 27.02 GB
pruning layer 9 name self_attn.q_proj
pruning layer 9 name self_attn.k_proj
pruning layer 9 name self_attn.v_proj
pruning layer 9 name self_attn.o_proj
pruning layer 9 name mlp.gate_proj
pruning layer 9 name mlp.down_proj
pruning layer 9 name mlp.up_proj
After pruning layer 9 - Allocated memory: 21.42 GB
After pruning layer 9 - Reserved memory: 27.02 GB
Before forward pass of layer 10 - Allocated memory: 21.42 GB
Before forward pass of layer 10 - Reserved memory: 27.02 GB
After forward pass of layer 10 - Allocated memory: 21.42 GB
After forward pass of layer 10 - Reserved memory: 27.02 GB
pruning layer 10 name self_attn.q_proj
pruning layer 10 name self_attn.k_proj
pruning layer 10 name self_attn.v_proj
pruning layer 10 name self_attn.o_proj
pruning layer 10 name mlp.gate_proj
pruning layer 10 name mlp.down_proj
pruning layer 10 name mlp.up_proj
After pruning layer 10 - Allocated memory: 21.42 GB
After pruning layer 10 - Reserved memory: 27.02 GB
Before forward pass of layer 11 - Allocated memory: 21.42 GB
Before forward pass of layer 11 - Reserved memory: 27.02 GB
After forward pass of layer 11 - Allocated memory: 21.42 GB
After forward pass of layer 11 - Reserved memory: 27.02 GB
pruning layer 11 name self_attn.q_proj
pruning layer 11 name self_attn.k_proj
pruning layer 11 name self_attn.v_proj
pruning layer 11 name self_attn.o_proj
pruning layer 11 name mlp.gate_proj
pruning layer 11 name mlp.down_proj
pruning layer 11 name mlp.up_proj
After pruning layer 11 - Allocated memory: 21.42 GB
After pruning layer 11 - Reserved memory: 27.02 GB
Before forward pass of layer 12 - Allocated memory: 21.42 GB
Before forward pass of layer 12 - Reserved memory: 27.02 GB
After forward pass of layer 12 - Allocated memory: 21.42 GB
After forward pass of layer 12 - Reserved memory: 27.02 GB
pruning layer 12 name self_attn.q_proj
pruning layer 12 name self_attn.k_proj
pruning layer 12 name self_attn.v_proj
pruning layer 12 name self_attn.o_proj
pruning layer 12 name mlp.gate_proj
pruning layer 12 name mlp.down_proj
pruning layer 12 name mlp.up_proj
After pruning layer 12 - Allocated memory: 21.42 GB
After pruning layer 12 - Reserved memory: 27.02 GB
Before forward pass of layer 13 - Allocated memory: 21.42 GB
Before forward pass of layer 13 - Reserved memory: 27.02 GB
After forward pass of layer 13 - Allocated memory: 21.42 GB
After forward pass of layer 13 - Reserved memory: 27.02 GB
pruning layer 13 name self_attn.q_proj
pruning layer 13 name self_attn.k_proj
pruning layer 13 name self_attn.v_proj
pruning layer 13 name self_attn.o_proj
pruning layer 13 name mlp.gate_proj
pruning layer 13 name mlp.down_proj
pruning layer 13 name mlp.up_proj
After pruning layer 13 - Allocated memory: 21.42 GB
After pruning layer 13 - Reserved memory: 27.02 GB
Before forward pass of layer 14 - Allocated memory: 21.42 GB
Before forward pass of layer 14 - Reserved memory: 27.02 GB
After forward pass of layer 14 - Allocated memory: 21.42 GB
After forward pass of layer 14 - Reserved memory: 27.02 GB
pruning layer 14 name self_attn.q_proj
pruning layer 14 name self_attn.k_proj
pruning layer 14 name self_attn.v_proj
pruning layer 14 name self_attn.o_proj
pruning layer 14 name mlp.gate_proj
pruning layer 14 name mlp.down_proj
pruning layer 14 name mlp.up_proj
After pruning layer 14 - Allocated memory: 21.42 GB
After pruning layer 14 - Reserved memory: 27.02 GB
Before forward pass of layer 15 - Allocated memory: 21.42 GB
Before forward pass of layer 15 - Reserved memory: 27.02 GB
After forward pass of layer 15 - Allocated memory: 21.42 GB
After forward pass of layer 15 - Reserved memory: 27.02 GB
pruning layer 15 name self_attn.q_proj
pruning layer 15 name self_attn.k_proj
pruning layer 15 name self_attn.v_proj
pruning layer 15 name self_attn.o_proj
pruning layer 15 name mlp.gate_proj
pruning layer 15 name mlp.down_proj
pruning layer 15 name mlp.up_proj
After pruning layer 15 - Allocated memory: 21.42 GB
After pruning layer 15 - Reserved memory: 27.02 GB
Before forward pass of layer 16 - Allocated memory: 21.42 GB
Before forward pass of layer 16 - Reserved memory: 27.02 GB
After forward pass of layer 16 - Allocated memory: 21.42 GB
After forward pass of layer 16 - Reserved memory: 27.02 GB
pruning layer 16 name self_attn.q_proj
pruning layer 16 name self_attn.k_proj
pruning layer 16 name self_attn.v_proj
pruning layer 16 name self_attn.o_proj
pruning layer 16 name mlp.gate_proj
pruning layer 16 name mlp.down_proj
pruning layer 16 name mlp.up_proj
After pruning layer 16 - Allocated memory: 21.42 GB
After pruning layer 16 - Reserved memory: 27.02 GB
Before forward pass of layer 17 - Allocated memory: 21.42 GB
Before forward pass of layer 17 - Reserved memory: 27.02 GB
After forward pass of layer 17 - Allocated memory: 21.42 GB
After forward pass of layer 17 - Reserved memory: 27.02 GB
pruning layer 17 name self_attn.q_proj
pruning layer 17 name self_attn.k_proj
pruning layer 17 name self_attn.v_proj
pruning layer 17 name self_attn.o_proj
pruning layer 17 name mlp.gate_proj
pruning layer 17 name mlp.down_proj
pruning layer 17 name mlp.up_proj
After pruning layer 17 - Allocated memory: 21.42 GB
After pruning layer 17 - Reserved memory: 27.02 GB
Before forward pass of layer 18 - Allocated memory: 21.42 GB
Before forward pass of layer 18 - Reserved memory: 27.02 GB
After forward pass of layer 18 - Allocated memory: 21.42 GB
After forward pass of layer 18 - Reserved memory: 27.02 GB
pruning layer 18 name self_attn.q_proj
pruning layer 18 name self_attn.k_proj
pruning layer 18 name self_attn.v_proj
pruning layer 18 name self_attn.o_proj
pruning layer 18 name mlp.gate_proj
pruning layer 18 name mlp.down_proj
pruning layer 18 name mlp.up_proj
After pruning layer 18 - Allocated memory: 21.42 GB
After pruning layer 18 - Reserved memory: 27.02 GB
Before forward pass of layer 19 - Allocated memory: 21.42 GB
Before forward pass of layer 19 - Reserved memory: 27.02 GB
After forward pass of layer 19 - Allocated memory: 21.42 GB
After forward pass of layer 19 - Reserved memory: 27.02 GB
pruning layer 19 name self_attn.q_proj
pruning layer 19 name self_attn.k_proj
pruning layer 19 name self_attn.v_proj
pruning layer 19 name self_attn.o_proj
pruning layer 19 name mlp.gate_proj
pruning layer 19 name mlp.down_proj
pruning layer 19 name mlp.up_proj
After pruning layer 19 - Allocated memory: 21.42 GB
After pruning layer 19 - Reserved memory: 27.02 GB
Before forward pass of layer 20 - Allocated memory: 21.42 GB
Before forward pass of layer 20 - Reserved memory: 27.02 GB
After forward pass of layer 20 - Allocated memory: 21.42 GB
After forward pass of layer 20 - Reserved memory: 27.02 GB
pruning layer 20 name self_attn.q_proj
pruning layer 20 name self_attn.k_proj
pruning layer 20 name self_attn.v_proj
pruning layer 20 name self_attn.o_proj
pruning layer 20 name mlp.gate_proj
pruning layer 20 name mlp.down_proj
pruning layer 20 name mlp.up_proj
After pruning layer 20 - Allocated memory: 21.42 GB
After pruning layer 20 - Reserved memory: 27.02 GB
Before forward pass of layer 21 - Allocated memory: 21.42 GB
Before forward pass of layer 21 - Reserved memory: 27.02 GB
After forward pass of layer 21 - Allocated memory: 21.42 GB
After forward pass of layer 21 - Reserved memory: 27.02 GB
pruning layer 21 name self_attn.q_proj
pruning layer 21 name self_attn.k_proj
pruning layer 21 name self_attn.v_proj
pruning layer 21 name self_attn.o_proj
pruning layer 21 name mlp.gate_proj
pruning layer 21 name mlp.down_proj
pruning layer 21 name mlp.up_proj
After pruning layer 21 - Allocated memory: 21.42 GB
After pruning layer 21 - Reserved memory: 27.02 GB
Before forward pass of layer 22 - Allocated memory: 21.42 GB
Before forward pass of layer 22 - Reserved memory: 27.02 GB
After forward pass of layer 22 - Allocated memory: 21.42 GB
After forward pass of layer 22 - Reserved memory: 27.02 GB
pruning layer 22 name self_attn.q_proj
pruning layer 22 name self_attn.k_proj
pruning layer 22 name self_attn.v_proj
pruning layer 22 name self_attn.o_proj
pruning layer 22 name mlp.gate_proj
pruning layer 22 name mlp.down_proj
pruning layer 22 name mlp.up_proj
After pruning layer 22 - Allocated memory: 21.42 GB
After pruning layer 22 - Reserved memory: 27.02 GB
Before forward pass of layer 23 - Allocated memory: 21.42 GB
Before forward pass of layer 23 - Reserved memory: 27.02 GB
After forward pass of layer 23 - Allocated memory: 21.42 GB
After forward pass of layer 23 - Reserved memory: 27.02 GB
pruning layer 23 name self_attn.q_proj
pruning layer 23 name self_attn.k_proj
pruning layer 23 name self_attn.v_proj
pruning layer 23 name self_attn.o_proj
pruning layer 23 name mlp.gate_proj
pruning layer 23 name mlp.down_proj
pruning layer 23 name mlp.up_proj
After pruning layer 23 - Allocated memory: 21.42 GB
After pruning layer 23 - Reserved memory: 27.02 GB
Before forward pass of layer 24 - Allocated memory: 21.42 GB
Before forward pass of layer 24 - Reserved memory: 27.02 GB
After forward pass of layer 24 - Allocated memory: 21.42 GB
After forward pass of layer 24 - Reserved memory: 27.02 GB
pruning layer 24 name self_attn.q_proj
pruning layer 24 name self_attn.k_proj
pruning layer 24 name self_attn.v_proj
pruning layer 24 name self_attn.o_proj
pruning layer 24 name mlp.gate_proj
pruning layer 24 name mlp.down_proj
pruning layer 24 name mlp.up_proj
After pruning layer 24 - Allocated memory: 21.42 GB
After pruning layer 24 - Reserved memory: 27.02 GB
Before forward pass of layer 25 - Allocated memory: 21.42 GB
Before forward pass of layer 25 - Reserved memory: 27.02 GB
After forward pass of layer 25 - Allocated memory: 21.42 GB
After forward pass of layer 25 - Reserved memory: 27.02 GB
pruning layer 25 name self_attn.q_proj
pruning layer 25 name self_attn.k_proj
pruning layer 25 name self_attn.v_proj
pruning layer 25 name self_attn.o_proj
pruning layer 25 name mlp.gate_proj
pruning layer 25 name mlp.down_proj
pruning layer 25 name mlp.up_proj
After pruning layer 25 - Allocated memory: 21.42 GB
After pruning layer 25 - Reserved memory: 27.02 GB
Before forward pass of layer 26 - Allocated memory: 21.42 GB
Before forward pass of layer 26 - Reserved memory: 27.02 GB
After forward pass of layer 26 - Allocated memory: 21.42 GB
After forward pass of layer 26 - Reserved memory: 27.02 GB
pruning layer 26 name self_attn.q_proj
pruning layer 26 name self_attn.k_proj
pruning layer 26 name self_attn.v_proj
pruning layer 26 name self_attn.o_proj
pruning layer 26 name mlp.gate_proj
pruning layer 26 name mlp.down_proj
pruning layer 26 name mlp.up_proj
After pruning layer 26 - Allocated memory: 21.42 GB
After pruning layer 26 - Reserved memory: 27.02 GB
Before forward pass of layer 27 - Allocated memory: 21.42 GB
Before forward pass of layer 27 - Reserved memory: 27.02 GB
After forward pass of layer 27 - Allocated memory: 21.42 GB
After forward pass of layer 27 - Reserved memory: 27.02 GB
pruning layer 27 name self_attn.q_proj
pruning layer 27 name self_attn.k_proj
pruning layer 27 name self_attn.v_proj
pruning layer 27 name self_attn.o_proj
pruning layer 27 name mlp.gate_proj
pruning layer 27 name mlp.down_proj
pruning layer 27 name mlp.up_proj
After pruning layer 27 - Allocated memory: 21.42 GB
After pruning layer 27 - Reserved memory: 27.02 GB
Before forward pass of layer 28 - Allocated memory: 21.42 GB
Before forward pass of layer 28 - Reserved memory: 27.02 GB
After forward pass of layer 28 - Allocated memory: 21.42 GB
After forward pass of layer 28 - Reserved memory: 27.02 GB
pruning layer 28 name self_attn.q_proj
pruning layer 28 name self_attn.k_proj
pruning layer 28 name self_attn.v_proj
pruning layer 28 name self_attn.o_proj
pruning layer 28 name mlp.gate_proj
pruning layer 28 name mlp.down_proj
pruning layer 28 name mlp.up_proj
After pruning layer 28 - Allocated memory: 21.42 GB
After pruning layer 28 - Reserved memory: 27.02 GB
Before forward pass of layer 29 - Allocated memory: 21.42 GB
Before forward pass of layer 29 - Reserved memory: 27.02 GB
After forward pass of layer 29 - Allocated memory: 21.42 GB
After forward pass of layer 29 - Reserved memory: 27.02 GB
pruning layer 29 name self_attn.q_proj
pruning layer 29 name self_attn.k_proj
pruning layer 29 name self_attn.v_proj
pruning layer 29 name self_attn.o_proj
pruning layer 29 name mlp.gate_proj
pruning layer 29 name mlp.down_proj
pruning layer 29 name mlp.up_proj
After pruning layer 29 - Allocated memory: 21.42 GB
After pruning layer 29 - Reserved memory: 27.02 GB
Before forward pass of layer 30 - Allocated memory: 21.42 GB
Before forward pass of layer 30 - Reserved memory: 27.02 GB
After forward pass of layer 30 - Allocated memory: 21.42 GB
After forward pass of layer 30 - Reserved memory: 27.02 GB
pruning layer 30 name self_attn.q_proj
pruning layer 30 name self_attn.k_proj
pruning layer 30 name self_attn.v_proj
pruning layer 30 name self_attn.o_proj
pruning layer 30 name mlp.gate_proj
pruning layer 30 name mlp.down_proj
pruning layer 30 name mlp.up_proj
After pruning layer 30 - Allocated memory: 21.42 GB
After pruning layer 30 - Reserved memory: 27.02 GB
Before forward pass of layer 31 - Allocated memory: 21.42 GB
Before forward pass of layer 31 - Reserved memory: 27.02 GB
After forward pass of layer 31 - Allocated memory: 21.42 GB
After forward pass of layer 31 - Reserved memory: 27.02 GB
pruning layer 31 name self_attn.q_proj
pruning layer 31 name self_attn.k_proj
pruning layer 31 name self_attn.v_proj
pruning layer 31 name self_attn.o_proj
pruning layer 31 name mlp.gate_proj
pruning layer 31 name mlp.down_proj
pruning layer 31 name mlp.up_proj
After pruning layer 31 - Allocated memory: 21.42 GB
After pruning layer 31 - Reserved memory: 27.02 GB
After cleaning cache - Allocated memory: 21.42 GB
After cleaning cache - Reserved memory: 21.78 GB
******************************
layer 0 sparsity 0.500000
layer 1 sparsity 0.500000
layer 2 sparsity 0.500000
layer 3 sparsity 0.500000
layer 4 sparsity 0.500000
layer 5 sparsity 0.500000
layer 6 sparsity 0.500000
layer 7 sparsity 0.500000
layer 8 sparsity 0.500000
layer 9 sparsity 0.500000
layer 10 sparsity 0.500000
layer 11 sparsity 0.500000
layer 12 sparsity 0.500000
layer 13 sparsity 0.500000
layer 14 sparsity 0.500000
layer 15 sparsity 0.500000
layer 16 sparsity 0.500000
layer 17 sparsity 0.500000
layer 18 sparsity 0.500000
layer 19 sparsity 0.500000
layer 20 sparsity 0.500000
layer 21 sparsity 0.500000
layer 22 sparsity 0.500000
layer 23 sparsity 0.500000
layer 24 sparsity 0.500000
layer 25 sparsity 0.500000
layer 26 sparsity 0.500000
layer 27 sparsity 0.500000
layer 28 sparsity 0.500000
layer 29 sparsity 0.500000
layer 30 sparsity 0.500000
layer 31 sparsity 0.500000
sparsity sanity check 0.5000
******************************
evaluating on wikitext2
Downloading readme: 10.5kB [00:00, 10.3MB/s]
Downloading data: 100%|██████████████████████████████████████████████████████████████| 733k/733k [00:02<00:00, 353kB/s]
Downloading data: 100%|███████████████████████████████████████████████████████████| 6.36M/6.36M [00:01<00:00, 3.31MB/s]
Downloading data: 100%|██████████████████████████████████████████████████████████████| 657k/657k [00:01<00:00, 553kB/s]
Generating test split: 100%|████████████████████████████████████████████| 4358/4358 [00:00<00:00, 182353.77 examples/s]
Generating train split: 100%|█████████████████████████████████████████| 36718/36718 [00:00<00:00, 534412.48 examples/s]
Generating validation split: 100%|██████████████████████████████████████| 3760/3760 [00:00<00:00, 472031.82 examples/s]
nsamples 83
sample 0
sample 50
wikitext perplexity 6.461933135986328
5.4.4 输出文件结果
method	actual_sparsity	ppl_test
wanda	0.5000	6.4619

5.5 论文实验结果

在这里插入图片描述

6.模型训练时间估计

在训练Transformer模型时,模型参数量和训练总tokens数决定了所需的计算量。

6.1 训练时间估算方法

使用公式:
训练时间 ≈ 8 × token训练数 × 模型参数量 GPU数量 × GPU峰值flops × GPU利用率 \text{训练时间} \approx \frac{8 \times \text{token训练数} \times \text{模型参数量}}{\text{GPU数量} \times \text{GPU峰值flops} \times \text{GPU利用率}} 训练时间GPU数量×GPU峰值flops×GPU利用率8×token训练数×模型参数量

  1. 确定模型参数量和训练总tokens数

    • 模型参数量(例如:GPT-3 175B, LLaMA-65B, GLM-130B)。
    • 训练总tokens数(例如:300B tokens, 1.4TB tokens, 400B tokens)。
  2. 计算训练所需的总浮点运算次数(FLOPS)

    • 前向传递 + 后向传递 + 激活重计算的系数=1+2+1=4。
    • 使用激活重计算的一次训练迭代中,对于每个token,每个模型参数,需要进行2∗4=8次浮点数运算
  3. 计算训练时间

    • 训练时间与GPU的峰值浮点运算能力和实际GPU利用率有关。
  4. 考虑端到端训练的GPU利用率

    • 训练时间不仅包括前向传递和后向传递的计算时间,还包括数据加载、优化器更新、多卡通信和记录日志的时间。
    • 一般情况下,GPU利用率在30%到50%之间。

6.2 Nvidia A100算力情况

在这里插入图片描述

6.3 实例分析

  1. GPT-3 175B

    • 硬件配置:1024张40GB显存的A100

    • 训练数据:300B tokens

    • A100峰值性能:312TFLOPS

    • GPU利用率:45%

    • 训练时间:34天

    • 计算:
      训练时间 ≈ 8 × 300 × 175 × 1 0 18 1024 × 312 × 0.45 × 1 0 12 \text{训练时间} \approx \frac{8 \times 300 \times 175 \times 10^{18}}{1024 \times 312 \times 0.45 \times 10^{12}} 训练时间1024×312×0.45×10128×300×175×1018

      训练时间 ≈ 420000 × 1 0 18 143769.6 × 1 0 12 \text{训练时间} \approx \frac{420000 \times 10^{18}}{143769.6 \times 10^{12}} 训练时间143769.6×1012420000×1018

      训练时间 ≈ 2921340 seconds \text{训练时间} \approx 2921340 \text{ seconds} 训练时间2921340 seconds

      将秒数转换为天:
      2921340 seconds ≈ 34 days 2921340 \text{ seconds} \approx 34 \text{ days} 2921340 seconds34 days

  2. LLaMA-65B

    • 硬件配置:2048张80GB显存的A100
    • 训练数据:1.4TB tokens
    • A100峰值性能:624TFLOPS
    • GPU利用率:30%
    • 训练时间:21天
  3. GLM-130B

    • 硬件配置:768张40GB显存的A100
    • 训练数据:400B tokens
    • A100峰值性能:312TFLOPS
    • GPU利用率:35%
    • 训练时间:57天

7. 小工具—LLM 3D 可视化工具

**网站:**https://bbycroft.net/llm

效果图:

在这里插入图片描述

​ 这个网站是一个3D可视化的工具,它可以让你直观地看到一个GPT-风格的语言模型(LLM)的内部结构和运行过程,它展示了一个基于Transformer的语言模型的主要组成部分

​ 你可以通过鼠标和键盘来控制视角,放大缩小,旋转,拖动,查看每个部分的细节和功能。你还可以输入自己的文本,看看模型是如何处理和生成的。

8. 参考资料

  1. 官方说明
  2. 技术文档
  3. 爱鼓捣 – AI开发者de频道
  4. 如何准确的估计llm推理和微调的内存消耗
  5. Reducing Activation Recomputation in Large Transformer Models
  6. A Simple and Effective Pruning Approach for Large Language Models
  7. LLM训练指南(二):模型参数、计算量、显存、计算时间计算

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/385160.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloud+Vue3多对多,多表联查

♥️作者&#xff1a;小宋1021 &#x1f935;‍♂️个人主页&#xff1a;小宋1021主页 ♥️坚持分析平时学习到的项目以及学习到的软件开发知识&#xff0c;和大家一起努力呀&#xff01;&#xff01;&#xff01; &#x1f388;&#x1f388;加油&#xff01; 加油&#xff01…

学习日记:数据类型2

目录 1.转义字符 2.隐式类型转换 2.1 强制类型转换 2.2 不同类型间赋值 3.运算符 表达式 3.1 算术运算符 3.2 算术运算优先级 3.3 赋值运算 3.3.1 不同类型间混合赋值 3.4 逗号运算 4.生成随机数 5. 每日一练 1.转义字符 \n 表示换行 \t …

前端渲染模式

渲染的概念 在Web开发中&#xff0c;渲染&#xff08;Rendering&#xff09;是一个核心概念&#xff0c;指的是将应用程序的数据&#xff08;data&#xff09;与模板&#xff08;template&#xff09;结合&#xff0c;生成最终的HTML页面&#xff0c;这个页面随后会被浏览器解析…

RedHat9 | Ansible 角色

环境版本说明 RedHat9 [Red Hat Enterprise Linux release 9.0]Ansible [core 2.13.3]Python [3.9.10]jinja [3.1.2] 描述角色结构 Playbook可能比较冗长且负载&#xff0c;也可能存在大量的重复代码。而角色&#xff08;roles&#xff09;可以用于层次性结构化的组织playbo…

55. 跳跃游戏【 力扣(LeetCode) 】

一、题目描述 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 二、测试用…

在vue中优雅地异步引入(懒加载)腾讯地图API

背景 接到一个需求需要在网站首页显示使用腾讯地图展示公司所在地。一开始我直接全局引入了腾讯地图js&#xff0c;结果发现在用户打开登陆页面的时候首页比较缓慢&#xff0c;为了提高用户登陆的加载效率&#xff0c;需要优化为异步引入。 思路 根据官网的示例&#xff0c;…

SQL 注入漏洞详解 - Union 注入

1)漏洞简介 SQL 注入简介 SQL 注入 即是指 Web 应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在 Web 应用程序中事先定义好的查询语句的结尾上添加额外的 SQL 语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,…

【前端 02】新浪新闻项目-初步使用CSS来排版

在今天的博文中&#xff0c;我们将围绕“新浪新闻”项目&#xff0c;深入探讨HTML和CSS在网页制作中的基础应用。通过具体实例&#xff0c;我们将学习如何设置图片、标题、超链接以及文本排版&#xff0c;同时了解CSS的引入方式和选择器优先级&#xff0c;以及视频和音频标签的…

分布式光伏并网AM5SE-IS防孤岛保护装置介绍——安科瑞 叶西平

产品简介 功能&#xff1a; AM5SE-IS防孤岛保护装置主要适用于35kV、10kV及低压380V光伏发电、燃气发电等新能源并网供电系统。当发生孤岛现象时&#xff0c;可以快速切除并网点&#xff0c;使本站与电网侧快速脱离&#xff0c;保证整个电站和相关维护人员的生命安全。 应用…

Hello 算法:动画图解、一键运行的数据结构与算法教程

Hello 算法 《Hello 算法》是一份开源、免费的数据结构与算法入门教程&#xff0c;特别适合新手。全书采用动画图解&#xff0c;内容清晰易懂&#xff0c;学习曲线平滑&#xff0c;引导初学者探索数据结构与算法的知识地图。源代码可以一键运行&#xff0c;帮助读者通过练习提…

WEB攻防-通用漏洞-SQL 读写注入-MYSQLMSSQLPostgreSQL

什么是高权限注入 高权限注入指的是攻击者通过SQL注入漏洞&#xff0c;利用具有高级权限的数据库账户&#xff08;如MYSQL的root用户、MSSQL的sa用户、PostgreSQL的dba用户&#xff09;执行恶意SQL语句。这些高级权限账户能够访问和修改数据库中的所有数据&#xff0c;甚至执行…

springboot中使用knife4j访问接口文档的一系列问题

springboot中使用knife4j访问接口文档的一系列问题 1.个人介绍 &#x1f389;&#x1f389;&#x1f389;欢迎来到我的博客,我是一名自学了2年半前端的大一学生,熟悉的技术是JavaScript与Vue.目前正在往全栈方向前进, 如果我的博客给您带来了帮助欢迎您关注我,我将会持续不断的…

用Java手写jvm之实现查找class

写在前面 完成类加载器加载class的三阶段&#xff0c;加载&#xff0c;解析&#xff0c;初始化中的加载&#x1f600;&#x1f600;&#x1f600; 源码 。 jvm想要运行class&#xff0c;是根据类全限定名称来从特定的位置基于类加载器来查找的&#xff0c;分别如下&#xff1a;…

解决R语言找不到系统库导致的报错

1、基本需知 1.1、系统库 系统库&#xff08;System library&#xff09;是一组预先编写和编译好的软件模块集合&#xff0c;用于支持操作系统的基本功能和提供一些常见的服务。这些库通常由操作系统或第三方开发者提供&#xff0c;并且在系统安装过程中被预装或者用户可以额…

崖山异构数据库迁移利器YMP初体验-Oracle迁移YashanDB

前言 首届YashanDB「迁移体验官」开放后&#xff0c;陆续收到「体验官」们的投稿&#xff0c;小崖在此把优秀的投稿文章分享给大家~今天分享的用户文章是《崖山异构数据库迁移利器YMP初体验-Oracle迁移YashanDB》&#xff08;作者&#xff1a;小草&#xff09;&#xff0c;满满…

【vue前端项目实战案例】之Vue仿饿了么App

本文将介绍一款仿“饿了么”商家页面的App。该案例是基于 Vue2.0 Vue Router webpack ES6 等技术栈实现的一款外卖类App&#xff0c;适合初学者进行学习。 项目源码下载链接在文章末尾 1 项目概述 该项目是一款仿“饿了么”商家页面的外卖类App&#xff0c;主要有以下功能…

51单片机嵌入式开发:17、STC89C52的嵌入式 遥控器 控制步进电机 转速 和 转向 操作并 printf打印信息

51单片机嵌入式开发 STC89C52的嵌入式 遥控器 控制步进电机 转速 和 转向 操作并 printf打印信息 51单片机嵌入式开发STC89C52的嵌入式 遥控器 控制步进电机 转速 和 转向 操作并 printf打印信息1 概述2 硬件电路2.1 遥控器2.2 红外接收器电路2.3 STC89C52单片机电路2.4 数码管…

SpringBoot集成Sharding-JDBC实现分库分表

本文已收录于专栏 《中间件合集》 目录 版本介绍背景介绍拆分方式集成并测试1.引入依赖2.创建库和表3.pom文件配置4.编写测试类Entity层Mapper接口MapperXML文件测试类 5.运行结果 自定义分片规则定义分片类编写pom文件 总结提升 版本介绍 SpringBoot的版本是&#xff1a; 2.3.…

IDEA Maven使用HTTP代理,解决Could not transfer artifact org.xxx问题

文章目录 一、前言二、遇到问题三、分析问题四、HTTP代理五、重新编译验证 一、前言 遇到这个问题&#xff0c;有两种解决办法 IDEA Maven使用HTTP代理&#xff0c;解决Could not transfer artifact org.xxx问题IDEA Maven使用国内镜像&#xff0c;解决Could not transfer arti…

C语言分支语句之if的一些用法

目录 引言C语言结构 1. if 语句1.1 if1.2 else 2. 分支中包含多条语句3. 多重选择 else if4. 嵌套if5. 悬空else / else与if配对问题 引言 C语言作为一种非常常用的编程语言&#xff0c;具有灵活强大的循环和分支结构。循环结构允许我们重复执行一段代码&#xff0c;而分支结构…