大模型微调技术 --> 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而不是FP4
    bnb_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",
    }
)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vert.x,应用监控 - 基于Micrometer / Prometheus

对于企业级的应用程序来说,我们需要通过运行指标(metrics)的监控,来了解(监控)程序的运行状态。Vert.x的核心组件内置了大量的运行指标,并支持通过Micrometer来管理这些运行指标并向后端报告。 目前Vertx内置运行指标的核心组件包括: TCP/HTT…

如何用PPT画箭头?用这2个ppt软件快速完成绘图!

ppt怎么画箭头? 有时在ppt中绘制流程图或传达承上启下的含义时,会用到箭头形状,运用到箭头元素来增强表达的清晰度和逻辑性。那可能有人会问,ppt怎么画箭头? 这似乎是一个小问题,但如果你对ppt工具不够熟…

java: 无法访问org.springframework.web.bind.annotation.RequestMapping

一、报错问题 java: 无法访问org.springframework.web.bind.annotation.RequestMapping 二、原因分析 SpringBoot使用了3.0或者3.0以上,因为Spring官方发布从Spring6以及SprinBoot3.0开始最低支持JDK17。所以仅需要将SpringBoot版本降低为3.0以下即可(或…

[ DOS 命令基础 3 ] DOS 命令详解-文件操作相关命令

🍬 博主介绍 👨‍🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…

【TS】九天学会TS语法——3.TypeScript 函数

今天学习 TypeScript 的函数,包括函数类型、可选参数、默认参数、剩余参数。 函数声明和表达式函数类型可选参数和默认参数剩余参数 在 TypeScript 中,函数是编程的核心概念之一。它们允许我们将代码组织成可重用的块,并提供了强大的抽象能力…

Kafka 源码 KRaft 模式本地运行

KRaft(Kafka Raft Metadata mode),从版本 2.8.0 开始作为测试特性引入,并在后续版本中持续得到改进和增强。 KRaft 模式是指 Kafka 使用 Raft 协议来管理集群元数据的一种运行模式,这标志着 Kafka 向去除对 ZooKeeper …

day05(单片机)SPI+数码管

目录 SPI数码管 SPI通信 SPI总线介绍 字节交换原理 时序单元 ​​​​​​​SPI模式 模式0 模式1 模式2 模式3 数码管 介绍 74HC595芯片分析 ​​​​​​​原理图分析 ​​​​​​​cubeMX配置​​​​​​​ 程序编写 硬件SPI ​​​​​​​软件SPI 作业: SPI数…

数据结构和算法-贪心算法01- 认识贪心

贪心算法 什么是贪心算法 一个贪心算法总是做出当前最好的选择,也就是说,它期望通过局部最优选择从而得到全局最优的解决方案。 ​ ----《算法导论》 贪心算法(Greedy Method): 所谓贪心算法就是重复地(或贪婪地)根据一个法则挑选解的一部分。当挑选完毕…

创新实践:基于边缘智能+扣子的智慧婴儿监控解决方案

在2024年全国大学生物联网设计竞赛中,火山引擎作为支持企业,不仅参与了赛道的命题设计,还为参赛队伍提供了相关的硬件和软件支持。以边缘智能和扣子的联合应用为核心,参赛者们在这场竞赛中的方案展现出了卓越的创新性和实用性&…

6款IntelliJ IDEA插件,让Spring和Java开发如虎添翼

文章目录 1、SonarLint2、JRebel for IntelliJ3、SwaggerHub插件4、Lombok插件5、RestfulTool插件6、 Json2Pojo插件7、结论 对于任何Spring Boot开发者来说,两个首要的目标是最大限度地提高工作效率和确保高质量代码。IntelliJ IDEA 是目前最广泛使用的集成开发环境…

CSS弹性布局:灵活布局的终极指南

在网页设计中,CSS 弹性布局(Flexbox)是一个不可或缺的工具。它能帮助你轻松地排列和对齐元素,尤其是在响应式设计中表现出色。今天,我们就来深入探讨一下 Flexbox 的各个属性,让你彻底掌握这个强大的布局工…

论文阅读:Computational Long Exposure Mobile Photography (一)

这篇文章是谷歌发表在 2023 ACM transaction on Graphic 上的一篇文章,介绍如何在手机摄影中实现长曝光的一些拍摄效果。 Abstract 长曝光摄影能拍出令人惊叹的影像,用运动模糊来呈现场景中的移动元素。它通常有两种模式,分别产生前景模糊或…

CTF入门教程(非常详细)从零基础入门到竞赛,看这一篇就够了!

目录 一、CTF简介 二、CTF竞赛模式 三、CTF各大题型简介 四、CTF学习路线 4.1、初期 1、htmlcssjs(2-3天) 2、apachephp (4-5天) 3、mysql (2-3天) 4、python (2-3天) 5、burpsuite (…

linux 进程调度学习笔记

https://zhuanlan.zhihu.com/p/1248579228 吐血整理 | 肝翻 Linux 进程调度所有知识点 执行调度 Kernel 判断当前进程标记是否为 TIF_NEED_RESCHED,是的话调用 schedule 函数,执行调度,切换上下文,这也是上面抢占(preempt)机制的…

django图书管理系统-计算机毕业设计源码00648

摘要 图书管理系统在数字化阅读趋势、图书馆自动化管理、用户体验需求和信息技术应用等方面具有重要的研究意义。图书馆自动化管理系统的引入和应用提高了图书借阅过程的效率和准确性,减少了对手工操作和纸质记录的需求。用户对系统的易用性、查询速度、借还流程有更…

SQL实战训练之,力扣:2020. 无流量的帐户数(递归)

目录 一、力扣原题链接 二、题目描述 三、建表语句 四、题目分析 五、SQL解答 六、最终答案 七、验证 八、知识点 一、力扣原题链接 2020. 无流量的帐户数 二、题目描述 表: Subscriptions ------------------- | Column Name | Type | ------------------- | accoun…

ARM base instruction -- ccmp (immediate)

Conditional Compare (immediate) sets the value of the condition flags to the result of the comparison of a register value and an immediate value if the condition is TRUE, and an immediate value otherwise. 此指令一般出现在 cmp 指令之后,表示双重比…

【支付行业-支付系统架构及总结】

记得第一次看埃隆马斯克(Elon Musk)讲第一性原理的视频时,深受震撼,原来还可以这样处理复杂的事务。这篇文章也尝试化繁为简,探寻支付系统的本质,讲清楚在线支付系统最核心的一些概念和设计理念。 虽然支付…

【系统面试篇】进程和线程类(1)(笔记)——区别、通讯方式、同步、互斥、锁分类

目录 一、问题综述 1. 进程和线程的区别? 2. 进程的状态有哪些? 3. 进程之间的通信方式? (1)管道 (2)消息队列 (3)共享内存 (4)信号量 &#xff08…

Java算法OJ(6)归并分治

目录 1.前言 2.正文 2.1归并分治的概念 2.2计算数组的小和 2.2.1题目 2.2.2示例 2.2.3代码 2.3翻转对 2.3.1题目 2.3.2示例 2.3.3代码 3.小结 1.前言 哈喽大家好吖,今天继续来给大家带来Java算法——归并分治的讲解,学习这篇的前提可以先把…