大模型微调技术 --> LoRA 系列之 QLoRA (省资源能手)

QLoRA

1.摘要

作者提出了QLoRA,一种有效的微调方法,可以减少内存使用,足以在单个48 GB GPU上微调 65B 参数模型,同时保留完整的 16位 微调任务性能。

QLoRA 通过冻结的4位量化预训练语言模型将梯度反向传播到低秩适配器(LoRA)中。

QLORA引入了许多创新来节省内存而不牺牲性能:

(a)4位 NormalFloat(NF4),一种对于正态分布权重理论上最优的新数据类型

(B)双重量化,通过量化 量化常数 来减少平均内存占用,以及

(c)分页优化器来管理内存尖峰。

我们使用 QLoRA 对 1,000 多个模型进行微调,我们的研究结果表明,QLoRA 在一个小的高质量数据集上进行微调,即使使用比以前的 SoTA 更小的模型,也会产生最先进的结果。此外,我们发现,目前的聊天机器人基准是不值得信赖的准确评估聊天机器人的性能水平。

2.引言

QLoRA 使用高精度的计算把模型量化到 4bit ,然后增加一小部分可训练 LoRA 参数。

QLORA将65B参数模型的微调平均内存需求从超过 780GB 的 GPU 内存减少到不到 48GB而与 16位 完全微调的基准相比,运行时或预测性能没有降低(很震撼!)。这标志着LLM微调可访问性的重大转变:现在最大的公开可用模型可以在单个 GPU 上进行微调。

在这里插入图片描述

1.量化微调后的 Guanaco 13B 性能超越了 Bard;
2.33B/65B 的版本超越了 ChatGPT
3.同样是 13B ,Guranaco 比 Vicuna 小很多

Elo Rating (不仅考虑输赢,还会考虑你对手的水平):ELO评级是一种测量棋手或其他竞技游戏玩家相对技能水平的系统。最初为国际象棋设计,如今ELO评级广泛应用于各种竞技游戏和体育赛事。用于评估大模型:将ELO评级应用于大型模型(如AI或机器学习模型)时,可以按照类似的原则进行:- 设定基准:确定一个基线模型作为参照点,给予一个初始ELO分数。- 比较性能:在特定任务或挑战中,将新模型与基线模型进行比较。- 调整评分:根据新模型相对于基线模型的表现,上调或下调其ELO分数。- 持续更新:随着模型的不断迭代和优化,持续更新其ELO评分,以反映其在特定任务上的相对能力。

除了展示QLORA恢复了16位性能,并训练了最先进的聊天机器人Guanaco,论文还分析了训练模型的趋势。

首先,结果发现数据质量比数据集大小更重要,例如,一个 9k 样本数据集(OASST1)在聊天机器人性能上超过了一个450k样本数据集(FLAN v2,抽样子集)即使两者都旨在支持指令遵循泛化。

其次,论文展示了在 Massive Multitask Language Understanding (MMLU)基准测试上的强劲表现并不意味着在 Vicuna 聊天机器人基准测试上同样表现强劲,反之亦然——换句话说,对于给定任务,数据集的适用性比大小更重要

在这里插入图片描述

图1:不同的调优方法及其对内存的要求。QLORA比LoRA提高了将Transformer模型量化到4位精度,并使用分页优化器来处理内存峰值

3.背景

1.块状 k-bit 量化

在这里插入图片描述

**块状 k-bit 量化(**Block-wise k-bit Quantization):这是一种数据压缩技术,通过减少表示数据的比特数(如从32位浮点数到8位整数)来减少模型大小。

为了有效使用低比特数据类型的整个范围,通常会通过最大绝对值归一化输入数据。

然而,这种方法存在一个问题:如果输入数据中有极大或极小的异常值,一些量化区间将不会被充分利用

为了解决这个问题,可以将输入数据划分为块,每个块独立进行量化

当输入张量中存在较大幅度的值时,传统的量化方法可能会导致某些量化区间未被充分利用。为了解决这个问题,提出了一种将输入张量分块处理的方法,每个块都有自己的量化常数 c。具体如下:将输入张量 X ∈ R b × h X∈R^{b×h} XRb×h 分成大小为 B B B n n n 个连续块,然后将线性段切分为 n = ( b × h ) / B n=(b×h)/B n=(b×h)/B个块,独立地对这些块进行量化,即使用上面的 等式(1) 创建一个量化张量和 n n n 个量化常数 c i c_i ci 。这种方法的目的是通过独立地处理每个块,避免了异常值的影响,并确保了所有量化区间都能够被充分利用。

2.LoRA

讲过了

3.参数高效微调的内存需求

LoRA内存需求的讨论涉及到适配器数量和大小,因为LoRA的内存占用较小,因此可以使用更多的适配器来提高性能。

尽管LoRA被设计为参数高效微调(PEFT)方法,但LLM微调的大部分内存占用来自激活梯度,而不是学习到的LoRA参数。梯度检查点技术能够减少输入梯度的内存占用,但过度减少 LoRA 参数数量只会带来微小的内存优势。因此,可以使用更多的适配器,而不会显著增加整体训练内存占用量,这对于恢复完整的 16 位精度性能至关重要。

4.QLoRA 微调

技术概述:通过提出的两种技术实现了高保真度的4位微调——4-bit NormalFloat(NF4)量化双重量化。此外,论文引入了分页优化器,以防止在梯度检查点期间内存峰值导致内存不足错误,这种错误传统上使得在单台机器上对大型模型进行微调变得困难。

存储与计算数据类型:QLORA有一个低精度的存储数据类型,通常是4比特,和一个通常为BFloat16的计算数据类型。在实践中,这意味着每当使用QLORA的权重张量时,将张量反量化到BFloat16,然后执行16位的矩阵乘法。

1.4bit NormalFloat 量化

量化基础 - 正态浮点(NF)数据类型: 正态浮点(NormalFloat, NF)数据类型是建立在分位数量化的基础上。分位数量化是一种信息论上的最优数据类型,它确保每个量化区间有相同数量的输入张量值。通过经验累积分布函数估算输入张量的分位数来实现。

分位数量化的局限性与近似算法: 分位数量化的主要局限在于估算过程的高成本。因此,采用了如 SRAM 分位数这样的 快速近似算法 来估算分位数。由于这些算法的近似性质,对于异常值(通常是最重要的值)会有较大的量化误差

利用固定分布避免高成本估算和近似误差: 当输入张量来自于一个固定分布(仅在量化常数上有所不同)时,可以避免昂贵的分位数估算和近似误差。在这种情况下,输入张量有相同的分位数,使得精确的分位数估算在计算上可行。

预训练神经网络权重的分布转换: 预训练神经网络权重通常呈零中心正态分布,标准差为 σ σ σ。通过缩放 σ σ σ,可以将所有权重转换为单一固定分布,使分布完全符合数据类型的范围。对于该数据类型,设定了任意范围 [−1, 1]。因此,数据类型的分位数和神经网络权重都需要规范化到这个范围内。

针对正态分布的量化数据类型计算: 对于范围在 [−1, 1] 内的零均值正态分布,其标准差为任意 σ 的信息论上最优数据类型的计算方式如下:

  1. 估算理论上的 N ( 0 , 1 ) N(0,1) N(0,1) 分布的 2 k + 1 2^k+1 2k+1 个分位数,以获得 k k k 位的正态分布量化数据类型;
  2. 将此数据类型的值规范化到 [−1, 1] 范围内;
  3. 通过绝对最大值重缩放将输入权重张量规范化到 [−1,1] 范围内进行量化。
  4. 步骤 (3) 相当于重新缩放权重张量的标准差,以匹配 k k k 位数据类型的标准差。更具体地,数据类型的 2 k 2^k 2k 个值 q i q_i qi 的估算方式为: q i = 1 2 ( Q X ( i 2 k + 1 ) + Q X ( i + 1 2 k + 1 ) ) q_i=\frac12(Q_X(\frac i{2^k+1})+Q_X(\frac{i+1}{2^k+1})) qi=21(QX(2k+1i)+QX(2k+1i+1)) ,其中 Q X ( ⋅ ) Q_X(·) QX() 是标准正态分布 N ( 0 , 1 ) N(0,1) N(0,1) 的分位数函数。

对称量化的问题与非对称数据类型的创建: 对于对称的 k k k 位量化,上述方法无法精确表示零,而零的精确表示对于量化填充和其他零值元素而无误差是重要的。为了确保一个离散的零点为 0,并使用所有的 2 k 2^k 2k 位表示 k k k 位数据类型,通过估算两个范围的分位数 q i : 2 ( k − 1 ) q_i:2^{(k−1)} qi2(k1) 用于负部分和 2 ( k − 1 ) + 1 2^{(k−1)}+1 2(k1)+1 用于正部分,然后将这些 q i q_i qi 集合统一并移除两个集合中都出现的一个零。所得到的数据类型被称为 k k k 位正态浮点(NFk),因为该数据类型对于零中心的正态分布数据是信息论上最优的。这种数据类型的具体值可以在附录E中找到。

2.双重量化

双重量化(DQ)的引入: 引入了双重量化(Double Quantization, DQ)的概念,这是一种对量化常数进行二次量化的过程,目的是为了进一步节省内存。尽管精确的4位量化需要小的块大小,但这也带来了相当大的内存开销。例如,使用32位的量化常数和64的块大小对于权重 W W W ,平均每个参数的量化常数增加了 32 / 64 = 0.5 32/64=0.5 32/64=0.5 位。

双重量化的具体过程: 具体来说,双重量化将第一次量化的量化常数 c 2 F P 32 c_2^{FP32} c2FP32

作为第二次量化的输入。这一第二步产生了量化的量化常数 c 2 F P 8 c_2^{FP8} c2FP8 和第二层量化常数 c 1 F P 32 c_1^{FP32} c1FP32 。研究者使用 256 块大小的 8 位浮点数进行第二次量化,根据Dettmers和Zettlemoyer的研究,8位量化并没有观察到性能下降。由于 c 2 F P 32 c_2^{FP32} c2FP32 是正数,在量化之前从 c 2 c_2 c2 中减去均值以使值围绕零中心,并利用对称量化。

内存占用的减少 :平均来说,对于 64 的块大小,这种量化方法将每个参数的内存占用从 32 / 64 = 0.5 32/64=0.5 32/64=0.5 位降低到 8 / 64 + 32 / ( 64 ⋅ 256 ) = 0.127 8/64+32/(64·256)=0.127 8/64+32/(64256)=0.127 位,每个参数减少了 0.373 位的内存占用。

3.优化器状态分配分页内存

使用NVIDIA统一内存特性: 论文中提到了使用NVIDIA的统一内存(Unified Memory)特性,这个特性可以在 GPU 偶尔内存不足的情况下,自动在 CPU 和 GPU 之间进行页到页的传输,以保证 GPU 处理过程中无误差。这个特性类似于 CPU RAM 和硬盘之间的常规内存分页。

优化器状态的内存分配: 作者使用这个特性来为优化器状态分配分页内存。当 GPU 内存不足时,这些状态会自动被逐出到 CPU RAM,然后在优化器更新步骤中需要内存时,再分页回 GPU 内存。

4.QLoRA

QLORA定义与线性层的量化实现: 在量化基础模型中,对于单个线性层和单个LoRA适配器,QLORA被定义为:

在这里插入图片描述

其中 doubleDequant(·) 被定义为:

在这里插入图片描述

双重解量化及其内存优化: 使用 N F 4 NF4 NF4 作为 W W W 的数据类型和 FP8 作为 c 2 c_2 c2 的数据类型。为了获得更高的量化精度, W 使用 64 的块大小;而为了节省内存, c 2 c_2 c2 使用 256 的块大小。 doubleDequant 函数通过两次解量化过程,将存储数据类型转换为计算数据类型。

参数更新与梯度计算: 对于参数更新,只需要计算适配器权重的误差梯度 ∂ E / ∂ L i ∂E/∂L_i E/Li ,而不是4位权重的梯度 ∂ E / ∂ W ∂E/∂W E/W 。然而,计算 ∂ E / ∂ L i ∂E/∂L_i E/Li 需要通过方程式(5)进行,其中包括从存储数据类型 W N F 4 W_{NF4} WNF4 到计算数据类型 W B F 16 W_{BF16} WBF16 的反量化,以计算 ∂ X / ∂ W ∂X/∂W X/W 的 BFloat16 精度导数。

QLORA的数据类型总结: QLORA使用两种数据类型:一种是存储数据类型(通常是 4 位的 NormalFloat),另一种是计算数据类型(16 位的 BrainFloat )。在正向和反向传播过程中,将存储数据类型反量化为计算数据类型,但只为 LoRA 参数(使用 16 位 BrainFloat )计算权重梯度。

5.QLoRA vs Standard Finetuning

论文结果一致表明,配备 NF4 数据类型的 4 位 QLORA 在学术基准测试中的表现可与 16 位完全微调和 16 位 LoRA 微调相媲美,这些基准测试都有成熟的评估设置。

在这里插入图片描述

论文还展示了 NF4 比 FP4 更有效,以及双重量化并不会降低性能。综合来看,这为 4 位 QLORA 调整可靠地达到与 16 位方法相匹配的结果提供了有力证据。

在这里插入图片描述

1. QLoRA 的超参数

作者对 LoRA 进行了下面的超参数搜索

LoRA dropout { 0.0,0.05,0.1},

LoRA r { 8,16,32,64,128,256},

LoRA layer {key+query,all attention layers,all FFN layers,all layers,attention + FFN output layers}。

我们保持 LoRA α 固定并搜索学习率,因为LoRA α始终与学习率成正比。

我们发现 LoRA dropout 0.05 对于小模型(7B,13B)有用但对于较大的模型(33B,65B)无效

我们发现,如果在所有层上使用 LoRA,则 LoRA r 与最终性能无关,如图所示

在这里插入图片描述

我们使用与 Wang 等人相同的 Super-Natural Instruction 数据集预处理。然而,我们将训练数据分割为训练和验证数据集,从而使我们能够执行更严格的超参数调整和早期停止。

我们使用本文中描述的相同超参数来训练 Super-Natural Instruction 数据上的各种 T5 模型大小。

对于小型、中型和大型T5型号,我们使用 LoRA r = 16

对于T5 xl和xxl型号,我们使用LoRA r = 64

我们还在所有实验中使用LoRA α = 64,并且没有LoRA dropout

6.训练最先进的聊天机器人实验设置详情

1.数据集

We include datasets obtained through crowd-sourcing (OASST1 [31],
HH-RLHF [4]), distillation from instruction-tuned models (Alpaca [55], self-instruct [59], unnatural instructions [26]), corpora aggregations (FLAN v2 [12]), as well as hybrids (Chip2 [32], Longform [30]). These datasets cover different languages, data sizes, and licenses.

2.超参数

在 QLoRA 微调实验中,发现超参数在数据集上具有很大的鲁棒性。

我们使用MMLU 5-shot dev set进行验证和超参数调优。在我们所有的实验中,我们使用具有双重量化和 bf16 数据类型的 NF4。

设置 LoRA r=64, \alpha = 16 ,把 LoRA module 附加在基础模型的所有线性层。

Adam 的 beta2 = 0.999

最大梯度范数 = 0.3

LoRA 的 dropout =0.1(13B中),dropout=0.05(33B 和 65B 中)

根据之前关于指令微调的工作,在对其他线性和余弦调度器进行基准测试之后,我们使用 constant 学习率调度器。

我们使用 group-by-length 将相同批次中相似长度的示例分组(注意这将产生振荡损失曲线)

在这里插入图片描述

QLoRA微调的训练超参数,在不同的数据集和不同的模型大小

3.哪个更重要:指令微调数据集大小还是数据集质量?

数据集的适用性 比 数据集的大小 更重要

为了了解数据集质量与数据集大小的影响,我们对至少有150,000个样本的大型数据集(Chip 2,FLAN v2,Unnatural Instructions)进行了实验,将其分为50,000,100,000和150,000大小的数据集,并检查了结果趋势,如表11所示。

我们发现,增加数据集大小 和 增加epoch数量 只能略微提高MMLU(0.0 - 0.5 MMLU),而数据集之间的差异高达40倍(1.5 - 8.0 MMLU)。

这清楚地表明,数据集质量而不是数据集大小对平均MMLU准确性至关重要。我们对聊天机器人的性能获得了类似的发现,如中所讨论的。

在这里插入图片描述

7.超参数微调

1.超参数

  1. 量化相关参数

    1. 量化位宽(bits)
      • 建议:
        • 4-bit 量化
        • 3-bit 可能导致显著性能下降
        • 5-bit 以上可能导致失去量化优势
    2. 量化类型(quantization_type)
      1. NormalFloat4(默认):大多数场景适用
      2. Float4:对特殊值处理更好,但是开销大
      3. 建议从 NormalFLoat4 开始
  2. 分组大小(group_size)

    1. 决定多少参数共享一个缩放因子
    2. 建议
      • 默认是 128
      • 较小的值(64)可能提高精度但是增加内存
      • 较大的值(256)节省内存但可能影响性能
  3. 双重量化(double_quantization)

    • 是否对量化器本身进行二次量化
    • 建议
      • 默认开启
      • 可以节省 2-3% 的内存
      • 对性能影响极小
  4. LoRA 相关参数

    • rank:通常设置为 64-256
    • alpha:与 rank 相同
    • target_modules:比传统的 LoRA 可以设置更多的层
  5. 典型配置示例

    qlora_config = {# 量化参数"bits": 4,"group_size": 128,"double_quant": True,"quant_type": "nf4",# LoRA参数"lora_r": 64,"lora_alpha": 64,"target_modules": ["q_proj", "v_proj", "k_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],# 分页参数"window_size": 256,  # 页面大小"page_size": "2GB"   # 单页大小
    }
    

2.最佳实践建议

  1. 不同规模模型的参数配置
    • 7B 模型:
      • rank=64
      • target_modules=所有线性层(也包括了q, k, v)
      • group_size=128
    • 13B-70B模型:
      • rank: 32-64
      • 重点关注attention相关层
      • group_size: 128-256
    • 70B以上模型:
      • rank: 16-32
      • 仅关注关键层
      • group_size: 256
  2. 内存优化策略
    • 开启梯度检查点(gradient checkpointing)
    • 是用分页系统(paged optimizer)
    • 适当的调整 batch size 和 gradient accumulation
  3. 稳定性优化
    • 使用 BF16 而不是 FP16
    • 适当增加预热步数
    • 考虑使用 gradient clipping

3.关键注意事项

  1. 显存管理:
    • 合理设置 batch size
    • 利用梯度累积
    • 注意监控显存使用
  2. 训练稳定性
    • 确保学习率较小(1e-4 ~ 5e-4)
    • 使用足够的预热步骤
    • 监控训练损失波动
  3. 常见问题解决
    • 如果出现 OOM:
      • 减小batch size
      • 增加 group_size
      • 减少 target modules
    • 如果性能不够好
      • 增加 rank
      • 添加更多的 target modules
      • 调整量化参数
  4. 与传统 LoRA 相比的优势
    1. 显著降低显存需求
    2. 支持更大的 rank 和 更多的 target modules
    3. 保持接近全参数微调的性能
  5. 特别建议
    1. 起步配置

      starter_config = {"bits": 4,"group_size": 128,"double_quant": True,"lora_r": 64,"target_modules": ["q_proj", "v_proj"]
      }
      
    2. 进阶配置

      1. 逐步增加 target modules
      2. 根据显存情况调整 rank
      3. 实验不同的量化参数

4.Hugging Face 中

  1. 核心参数配置

    from peft import LoraConfig
    from transformers import BitsAndBytesConfig# 量化配置
    quant_config = BitsAndBytesConfig(load_in_4bit=True,bnb_4bit_quant_type="nf4",bnb_4bit_compute_dtype=torch.float16,bnb_4bit_use_double_quant=True,
    )# LoRA配置
    qlora_config = LoraConfig(r=64,lora_alpha=128,target_modules=["q_proj", "v_proj"],lora_dropout=0.1,
    )
    
  2. 量化参数

    # 基础配置
    basic_quant_config = BitsAndBytesConfig(load_in_4bit=True,bnb_4bit_quant_type="nf4",bnb_4bit_use_double_quant=True,
    )# 高性能配置
    advanced_quant_config = BitsAndBytesConfig(load_in_4bit=True,bnb_4bit_quant_type="nf4",bnb_4bit_compute_dtype=torch.bfloat16,bnb_4bit_use_double_quant=True,
    )
    
  3. LoRA 参数

    • 小模型:r=64, lora_alpha=128
    • 中模型:r=32, lora_alpha=64
    • 大模型:r=16, lora_alpha=32

5.Hugging Face 共同最佳实践

from transformers import (AutoModelForCausalLM,AutoTokenizer,BitsAndBytesConfig,TrainingArguments
)
from peft import LoraConfig, get_peft_model
import torch# 1. 更详细的量化配置
bnb_config = BitsAndBytesConfig(load_in_4bit=True,bnb_4bit_use_double_quant=True,bnb_4bit_quant_type="nf4",           # 使用NF4而不是FP4bnb_4bit_compute_dtype=torch.float16,# 以下是一些额外的优化配置llm_int8_enable_fp32_cpu_offload=True,   # 启用CPU卸载llm_int8_skip_modules=None,              # 跳过某些模块的量化llm_int8_threshold=6.0,                  # 量化阈值llm_int8_has_fp16_weight=False          # 是否保持fp16权重
)# 2. 更详细的LoRA配置
lora_config = LoraConfig(r=64,                    # 论文中使用了较大的秩lora_alpha=16,           # alpha值调整target_modules=["query_key_value"],lora_dropout=0.1,bias="none",task_type="CAUSAL_LM",# 以下是一些额外的LoRA配置inference_mode=False,    # 训练模式init_lora_weights=True,  # 初始化LoRA权重modules_to_save=None     # 额外保存的模块
)# 3. 加载模型
model = AutoModelForCausalLM.from_pretrained("your-model-name",quantization_config=bnb_config,device_map="auto",torch_dtype=torch.float16,# 以下配置有助于内存管理max_memory={0: "24GB"},  # 为每个GPU分配内存offload_folder="offload", # 设置权重卸载目录offload_state_dict=True  # 启用状态字典卸载
)# 4. 应用LoRA
model = get_peft_model(model, lora_config)# 5. 训练配置
training_args = TrainingArguments(output_dir="./qlora_output",per_device_train_batch_size=2,gradient_accumulation_steps=4,gradient_checkpointing=True,    # 启用梯度检查点max_grad_norm=0.3,             # 梯度裁剪num_train_epochs=3,learning_rate=2e-4,lr_scheduler_type="cosine",    # 使用余弦学习率调度warmup_ratio=0.03,             # 预热比例fp16=True,                     # 使用混合精度logging_steps=10,save_strategy="epoch",# 以下是一些内存优化配置gradient_checkpointing_kwargs={"use_reentrant": False},fsdp_config={"fsdp_offload_params": True,"fsdp_state_dict_type": "FULL_STATE_DICT",}
)

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

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

相关文章

一种ESB的设计

系统架构 ESB包括: ESB总控服务、业务应用集群、业务消息WEB服务、业务消息日志服务、运维管理平台、业务设计器。如下图所示 ESB总控服务 ESB总控服务承载了各项业务的运维和管理。主要包括: 业务流程的管理ESB内部不同模块间的通讯ESB系统设置和管理…

06 网络编程基础

目录 1.通信三要素 1. IP地址(Internet Protocol Address) 2. 端口号(Port Number) 3. 协议(Protocol) 2.TCP与UDP协议 三次握手(Three-Way Handshake) 四次挥手(…

使用sealos部署的集群在部署metrics-server时日志x509

1、下载文件并进行部署 wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml2、进行部署 kubectl apply -f components.yaml3、发现问题 pod容器已经启动但是健康检查没有通过 kubectl get pod -n kube-system metrics-server…

定海 - 利用Coraza引擎开发一个防火墙

1. 介绍: Coraza有大量的内置安全规则,包括 OWASP Top 10,同时将错误警报降至最低。CRS保护免受许多常见攻击类别的攻击,包括SQL注入(SQLi)、跨站点脚本(XSS)、PHP和Java代码注入、HTTPoxy、Shellshock、脚…

【Linux】冯诺依曼体系、再谈操作系统

目录 一、冯诺依曼体系结构: 1、产生: 2、介绍: 二、再谈操作系统: 1、为什么要管理软硬件资源: 2、操作系统如何进行管理: 3、库函数: 4、学习操作系统的意义: 一、冯诺依曼…

bat批量处理脚本细节研究

文章目录 bat批处理脚本(框架)set变量设置基本语法显示环境变量 自定义环境变量临时环境变量和永久环境变量特殊环境变量和系统默认环境变量set命令利用选项的其他应用 !与%解析变量的区别/为什么使用setlocal enabledelayedexpansion区别%的规则!使用 %…

ReactPress系列—Next.js 的动态路由使用介绍

ReactPress Github项目地址:https://github.com/fecommunity/reactpress 欢迎提出宝贵的建议,感谢Star。 Next.js 的动态路由使用介绍 Next.js 是一个流行的 React 框架,支持服务端渲染、静态站点生成和动态路由等功能,极大地简化…

计算机的发展史

计算机的发展史是一个跨越多个世纪的过程,从最早的机械计算设备到如今的高性能、智能化计算机。以下是计算机发展史的简要概述,按重要的技术进步和里程碑进行归类: 1. 早期的计算工具(公元前3000年—17世纪) 计算机的…

基于STM32的实时时钟(RTC)教学

引言 实时时钟(RTC)是微控制器中的一种重要功能,能够持续跟踪当前时间和日期。在许多应用中,RTC用于记录时间戳、定时操作等。本文将指导您如何使用STM32开发板实现RTC功能,通过示例代码实现当前时间的读取和显示。 环…

Python | Leetcode Python题解之第537题复数乘法

题目: 题解: class Solution:def complexNumberMultiply(self, num1: str, num2: str) -> str:real1, imag1 map(int, num1[:-1].split())real2, imag2 map(int, num2[:-1].split())return f{real1 * real2 - imag1 * imag2}{real1 * imag2 imag1…

CoD-MIL: 基于诊断链提示的多实例学习用于全切片图像分类|文献速递-基于深度学习的病灶分割与数据超分辨率

Title 题目 CoD-MIL: Chain-of-Diagnosis Prompting Multiple Instance Learning for Whole Slide Image Classification CoD-MIL: 基于诊断链提示的多实例学习用于全切片图像分类 01 文献速递介绍 病理检查被广泛视为肿瘤诊断的金标准,因为它为治疗决策和患者…

232转485模块测试

概述 常用的PLC一般会有两个左右的232口,以及两个左右的485口,CAN口等,但是PLC一般控制的设备可能会有很多,会超出通讯口的数量,此时我们一般会采用一个口接多个设备,这种情况下要注意干扰等因素&#xff0…

网络编程——TCP通信练习

目录 一、多发多收 二、接收和反馈 三、上传文件 四、解决上传文件名重复问题 五、上传文件多线程版 六、上传文件线程池版 七、B/S(接收浏览器的消息并打印) 一、多发多收 客户端:多次发送数据 服务器:接收多次数据,并打印 public cl…

【stm32】RTC时钟的介绍与使用

RTC时钟的介绍与使用 一、时间戳1、Unix时间戳2、UTC/GMT3、时间戳转换 二、BKP简介及代码编写1、BKP简介2、BKP基本结构3、BKP库函数介绍:4、程序编写: 三、RTC简介及代码编写1、RTC简介2、RTC框图2、RTC基本结构3、RTC相关库函数介绍:4、程…

在docker中搭建redis哨兵环境

文章目录 一、引言二、环境准备前提条件目录结构 三、配置文件1. 主节点配置文件 sentinel-master.conf2. 从节点配置文件3. 哨兵配置文件 sentinel.conf4. Docker Compose 文件 四、启动 Docker Compose五、验证哨兵机制1. 检查主节点状态2. 检查从节点状态3. 检查哨兵状态4. …

职场高手揭秘,细节如何左右你的成败与升迁之路

身在职场,每一个人都想得到老板的器重,能不断地加薪、升职,从而获得职场的成功。但你知道,影响一个人职场成功,或者说影响升职加薪的最重要因素是什么吗? 许多人会说那要靠运气,也有人认为工作…

微信小程序 高校教材征订系统

文章目录 项目介绍具体实现截图技术介绍mvc设计模式小程序框架以及目录结构介绍错误处理和异常处理java类核心代码部分展示详细视频演示源码获取 项目介绍 系统分为三个角色,分别是教材科、系教学秘书、教研室主任。系统主要完成功能是教材科要发布教材征订信息&am…

RNN中的梯度消失与梯度爆炸问题

梯度消失与梯度爆炸问题 循环神经网络(Recurrent Neural Network,RNN)是一类具有短期记忆能力的神经网络.在循环神经网络中,神经元不但可以接受其他神经元的信息,也可以接受自身的信息,形成具有…

Unity网络开发基础(part5.网络协议)

目录 前言 网络协议概述 OSI模型 OSI模型的规则 第一部分 物理层 数据链路层 网络层 传输层 第二部分 ​编辑 应用层 表示层 会话层 每层的职能 TCP/IP协议 TCP/IP协议的规则 TCP/IP协议每层的职能 TCP/IP协议中的重要协议 TCP协议 三次握手 四次挥手 U…

ENSP GVRP动态学习VLAN

手工配置的VLAN称为静态VLAN,通过GVRP协议创建的VLAN称为动态VLAN。 GVRP有三种注册模式,不同的模式对静态VLAN和动态VLAN的处理方式也不同。 GVRP的三种注册模式分别定义如下: Normal模式:允许动态VLAN在端口上进行注册…