当前位置: 首页 > news >正文

大语言模型的训练、微调及压缩技术

The rock can talk — not interesting. The rock can read — that’s interesting.

(石头能说话,不稀奇。稀奇的是石头能读懂。)
----硅谷知名创业孵化器 YC 的总裁 Gar Tan

目录

1. 什么是大语言模型?

2. 语言建模(LM):

3. 基础模型和大语言模型:

4. 大语言模型的架构:

5. 预训练:

6. 数据并行训练技术:

6.1 分布式数据并行(DDP)

6.2 全分片数据并行(FSDP)

7. 微调:

7.1 PEFT

7.2 迁移学习

7.3 Adapters 适配器

7.4 LoRA——低秩自适应

7.5 QLoRA

7.6 IA3

7.7 P-Tuning

7.8 Prefix Tuning

7.9 Prompt Tuning(并非提示工程)

7.10 LoRA与Prompt Tuning对比

7.11 LoRA和PEFT与全量微调对比

8. 大语言模型推理:

9. 提示工程:

9.1 思维链(CoT)提示

9.2 PAL(程序辅助语言模型)

9.3 ReAct提示

10. 模型优化技术:

10.1 量化

10.2 蒸馏

10.3 剪枝

结论:

References:


1. 什么是大语言模型?

大语言模型(LLM)是非常庞大的深度学习模型,它们在大量数据上进行预训练。其底层的Transformer是一组神经网络,由具有自注意力能力的编码器和解码器组成。编码器和解码器从文本序列中提取含义,并理解其中单词和短语之间的关系。

Transformer神经网络架构允许使用非常大的模型,这些模型通常包含数千亿个参数。如此大规模的模型可以摄取大量数据,这些数据通常来自互联网,也可以来自如包含超过500亿个网页的Common Crawl,以及约有5700万页面的维基百科等来源。

2. 语言建模(LM):

语言和交流的过程可以简化为计算吗?

语言模型通过从一个或多个文本语料库中学习来生成概率。文本语料库是一种语言资源,由一种或多种语言的大量结构化文本组成。文本语料库可以包含一种或多种语言的文本,并且通常带有注释。

语言模型可以根据其在训练过程中学习到的统计模式,预测最可能跟随某个短语的单词(或多个单词)。在图中,语言模型可能会估计“天空的颜色是”这个短语后面跟着“蓝色”一词的概率为91%。

构建语言模型的最早方法之一是基于n - gram。n - gram是从给定文本样本中连续的n个项目组成的序列。在这里,模型假设序列中下一个单词的概率仅取决于前面固定数量的单词:

其中,wi表示单词,k是窗口大小。

然而,n - gram语言模型在很大程度上已被神经语言模型所取代。神经语言模型基于神经网络,这是一种受生物神经网络启发的计算系统。这些模型利用单词的连续表示或嵌入来进行预测:

神经网络将单词表示为权重的非线性组合。因此,它可以避免语言建模中的维度灾难问题。已经有几种神经网络架构被提出用于语言建模。

3. 基础模型和大语言模型:

这与自然语言处理(NLP)应用程序早期的方法有很大不同,早期是训练专门的语言模型来执行特定任务。相反,研究人员在大语言模型中观察到了许多涌现能力,这些能力是模型从未接受过训练的。

例如,大语言模型已被证明能够执行多步算术运算、解乱序单词的字母,以及识别口语中的冒犯性内容。最近,基于OpenAPI的GPT系列大语言模型构建的流行聊天机器人ChatGPT,通过了美国医学执照考试等专业考试。

基础模型通常是指在广泛数据上进行训练的任何模型,它可以适应各种下游任务。这些模型通常使用深度神经网络创建,并使用自监督学习在大量未标记数据上进行训练。

在训练过程中,从语料库中提取文本序列并进行截断。语言模型计算缺失单词的概率,然后通过基于梯度下降的优化机制对这些概率进行微调,并反馈给模型以匹配真实情况。这个过程在整个文本语料库上重复进行。

尽管如此,大语言模型通常在与语言相关的数据(如文本)上进行训练。而基础模型通常在多模态数据(文本、图像、音频等的混合)上进行训练。更重要的是,基础模型旨在作为更特定任务的基础或基石:

基础模型通常通过进一步训练进行微调,以完成各种下游认知任务。微调是指采用预训练的语言模型,并使用特定数据针对不同但相关的任务进行训练的过程。这个过程也被称为迁移学习。

4. 大语言模型的架构:

早期的大语言模型大多是使用带有长短期记忆网络(LSTM)和门控循环单元(GRU)的循环神经网络(RNN)模型创建的。然而,它们面临挑战,主要是在大规模执行NLP任务方面。但这正是大语言模型预期要发挥作用的领域。这就促使了Transformer的诞生!

一开始,大语言模型主要是使用自监督学习算法创建的。自监督学习是指处理未标记数据以获得有用的表示,这些表示可以帮助下游的学习任务。

通常,自监督学习算法使用基于人工神经网络(ANN)的模型。我们可以使用几种架构来创建人工神经网络,但大语言模型中使用最广泛的架构是循环神经网络(RNN)。

RNN可以利用其内部状态来处理可变长度的输入序列。RNN具有长期记忆和短期记忆。RNN有一些变体,如长短期记忆网络(LSTM)和门控循环单元(GRU)。

使用LSTM单元的RNN训练速度非常慢。此外,对于这样的架构,我们需要按顺序或串行地输入数据。这就无法进行并行化处理,也无法利用可用的处理器核心。

或者,使用GRU的RNN模型训练速度更快,但在更大的数据集上表现较差。尽管如此,在很长一段时间里,LSTM和GRU仍然是构建复杂NLP系统的首选。然而,这样的模型也存在梯度消失问题:

当反向传播多层时,梯度可能会变得非常小,导致训练困难。

RNN的一些问题通过在其架构中添加注意力机制得到了部分解决。在像LSTM这样的循环架构中,可以传播的信息量是有限的,并且保留信息的窗口较短。

然而,有了注意力机制,这个信息窗口可以显著增加。注意力是一种增强输入数据某些部分,同时削弱其他部分的技术。其背后的动机是网络应该更多地关注数据的重要部分:

其中,ai是注意力权重,表示对每个输入部分的关注程度。

注意力和自注意力之间有一个微妙的区别,但它们的动机是相同的。注意力机制是指关注另一个序列不同部分的能力,而自注意力是指关注当前序列不同部分的能力。

自注意力允许模型访问来自任何输入序列元素的信息。在NLP应用中,这提供了关于远距离标记的相关信息。因此,模型可以捕获整个序列中的依赖关系,而无需固定或滑动窗口。

带有注意力机制的RNN模型在性能上有了显著提升。然而,循环模型本质上很难扩展。但是,自注意力机制很快被证明非常强大,以至于它甚至不需要循环顺序处理。

2017年,谷歌大脑团队推出的Transformer可能是大语言模型历史上最重要的转折点之一。Transformer是一种深度学习模型,它采用自注意力机制,并一次性处理整个输入:

与早期基于RNN的模型相比,Transformer有一个重大变化,即它没有循环结构。在有足够训练数据的情况下,Transformer架构中的注意力机制本身就可以与带有注意力机制的RNN模型相媲美。

使用Transformer模型的另一个显著优势是它们具有更高的并行化程度,并且需要的训练时间大大减少。这正是我们利用可用资源在大量基于文本的数据上构建大语言模型所需要的优势。

许多基于人工神经网络的自然语言处理模型都是使用编码器 - 解码器架构构建的。例如,seq2seq是谷歌最初开发的一系列算法。它通过使用带有LSTM或GRU的RNN将一个序列转换为另一个序列。

最初的Transformer模型也使用了编码器 - 解码器架构。编码器由编码层组成,这些层逐层迭代处理输入。解码器由解码层组成,对编码器的输出进行同样的处理:

每个编码器层的功能是生成编码,其中包含关于输入中哪些部分相互相关的信息。输出编码随后作为输入传递给下一个编码器。每个编码器由一个自注意力机制和一个前馈神经网络组成。

此外,每个解码器层获取所有编码,并利用其中包含的上下文信息生成输出序列。与编码器一样,每个解码器由一个自注意力机制、一个对编码的注意力机制和一个前馈神经网络组成。

5. 预训练:

在这个阶段,模型以自监督的方式在大量非结构化文本数据集上进行预训练。预训练的主要挑战是计算成本。

存储10亿参数模型所需的GPU内存:

  • 1个参数 -> 4字节(32位浮点数)
  • 10亿参数 -> 4×10^9 字节 = 4GB
  • 存储10亿参数模型所需的GPU内存 = 4GB(32位全精度)

让我们计算训练10亿参数模型所需的内存:

  • 模型参数
  • 梯度
  • ADAM优化器(2个状态)
  • 激活值和临时内存(大小可变)

-> 4字节参数 + 每个参数额外20字节

所以,训练所需的内存大约是存储模型所需内存的20倍。

存储10亿参数模型所需内存 = 4GB(32位全精度)

训练10亿参数模型所需内存 = 80GB(32位全精度)

6. 数据并行训练技术:

6.1 分布式数据并行(DDP)

分布式数据并行(DDP)要求模型权重以及训练所需的所有其他额外参数、梯度和优化器状态都能在单个GPU中容纳。如果模型太大,则应使用模型分片。

6.2 全分片数据并行(FSDP)

全分片数据并行(FSDP)通过在多个GPU之间分布(分片)模型参数、梯度和优化器状态来减少内存使用。

7. 微调:

微调有助于我们通过调整预训练的大语言模型(LLM)的权重,使其更好地适应特定任务或领域,从而充分发挥这些模型的潜力。这意味着与单纯的提示工程相比,你可以用更低的成本和延迟获得更高质量的结果。

与提示相比,微调通常在引导大语言模型的行为方面要有效得多。通过在一组示例上训练模型,你可以缩短精心设计的提示,节省宝贵的输入令牌,同时不牺牲质量。你通常还可以使用小得多的模型,这反过来又可以减少延迟和推理成本。

例如,经过微调的Llama 7B模型在每个令牌的基础上,成本效益比现成的模型(如GPT-3.5)高得多(大约50倍),且性能相当。

如前所述,微调是针对其他任务对已经训练好的模型进行调整。其工作方式是获取原始模型的权重,并对其进行调整以适应新任务。

模型在训练时会学习完成特定任务,例如,GPT-3在大量数据集上进行了训练,因此它学会了生成故事、诗歌、歌曲、信件等。人们可以利用GPT-3的这种能力,并针对特定任务(如以特定方式生成客户查询的答案)对其进行微调。

有多种方法和技术可以对模型进行微调,其中最流行的是迁移学习。迁移学习源自计算机视觉领域,它是指冻结网络初始层的权重,只更新后面层的权重的过程。这是因为较底层(更接近输入的层)负责学习训练数据集的通用特征,而较上层(更接近输出的层)学习更具体的信息,这些信息直接与生成正确的输出相关。

7.1 PEFT

PEFT,即参数高效微调(Parameter Efficient Fine-Tuning),是一组以最节省计算资源和时间的方式微调大型模型的技术或方法,同时不会出现我们可能在全量微调中看到的性能损失。之所以采用这些技术,是因为随着模型越来越大,例如拥有1760亿参数的BLOOM模型,在不花费数万美元的情况下对其进行微调几乎是不可能的。但有时为了获得更好的性能,使用这样的大型模型又几乎是必要的。这就是PEFT发挥作用的地方,它可以帮助解决在处理这类大型模型时遇到的问题。

以下是一些PEFT技术:

7.2 迁移学习

迁移学习是指我们获取模型的一些已学习参数,并将其用于其他任务。这听起来与微调相似,但实际上有所不同。在微调中,我们重新调整模型的所有参数,或者冻结一些权重并调整其余参数。但在迁移学习中,我们从一个模型中获取一些已学习参数,并将其用于其他网络。这在我们的操作上给予了更大的灵活性。例如,在微调时我们无法改变模型的架构,这在很多方面限制了我们。但在使用迁移学习时,我们只使用训练好的模型的一部分,然后可以将其附加到任何具有不同架构的其他模型上。

迁移学习在使用大语言模型的NLP任务中经常出现,人们会使用像T5这样的预训练模型中Transformer网络的编码器部分,并训练后面的层。

7.3 Adapters 适配器

适配器是最早发布的参数高效微调技术之一。相关论文Parameter-Efficient Transfer Learning for NLP表明,我们可以在现有的Transformer架构上添加更多层,并且只对这些层进行微调,而不是对整个模型进行微调。他们发现,与完全微调相比,这种技术可以产生相似的性能。

在左边,是添加了适配器层的修改后的Transformer架构。我们可以看到适配器层添加在注意力堆栈和前馈堆栈之后。在右边,是适配器层本身的架构。适配器层采用瓶颈架构,它将输入缩小到较小维度的表示,然后通过非线性激活函数,再将其放大到输入的维度。这确保了Transformer堆栈中的下一层能够接收适配器层生成的输出。

论文作者表明,这种微调方法在消耗更少计算资源和训练时间的同时,性能可与完全微调相媲美。他们在GLUE基准测试中,仅增加3.6%的参数,就能达到全量微调0.4%的效果。

7.4 LoRA——低秩自适应

LoRA是一种与适配器层类似的策略,但它旨在进一步减少可训练参数的数量。它采用了更严谨的数学方法。LoRA通过修改神经网络中可更新参数的训练和更新方式来工作。

从数学角度解释,我们知道预训练神经网络的权重矩阵是满秩的,这意味着每个权重都是唯一的,不能通过组合其他权重得到。但在这篇论文Intrinsic Dimensionality Explains the Effectiveness of Language Model Fine-Tuning中,作者表明,当预训练语言模型针对新任务进行调整时,权重具有较低的“内在维度”。这意味着权重可以用更小的矩阵表示,即它具有较低的秩。反过来,这意味着在反向传播过程中,权重更新矩阵的秩较低,因为大部分必要信息已经在预训练过程中被捕获,在微调过程中只进行特定任务的调整。

更简单的解释是,在微调过程中,只有极少数权重会有较大的更新,因为神经网络的大部分学习是在预训练阶段完成的。LoRA利用这一信息来减少可训练参数的数量。

以GPT-3 175B为例,LoRA研究团队证明,即使全秩(即d)高达12288,非常低的秩(即图1中的r可以是1或2)也足够了,这使得LoRA在存储和计算上都非常高效。

图2展示了矩阵  和  的维度为  ,而我们可以改变 r 的值。 r 值越小,需要调整的参数就越少。虽然这会缩短训练时间,但r值过小时也可能导致信息丢失并降低模型性能。然而,使用LoRA时,即使秩较低,性能也能与完全训练的模型相当甚至更好。

用HuggingFace实现LoRA微调

要使用HuggingFace实现LoRA微调,你需要使用PEFT库将LoRA适配器注入模型,并将它们用作更新矩阵。

from transformers import AutoModelForCausalLM
from peft import get_peft_config, get_peft_model, LoraConfig, TaskType
model = AutoModelForCausalLM.from_pretrained(model_name_or_path, device_map="auto", trust_remote_code=True)
peft_config = LoraConfig(task_type=TaskType.CAUSAL_LM, inference_mode=False, r=32, lora_alpha=16, lora_dropout=0.1,target_modules=['query_key_value']
)
model = get_peft_model(model, peft_config)
model.print_trainable_parameters()

完成这些后,你就可以像平常一样训练模型了。但这一次,它将比平常花费更少的时间和计算资源。

LoRA的效率

论文的作者表明,LoRA仅用总可训练参数的2%就能超越全量微调的效果。

至于它训练的参数数量,我们可以通过秩r参数在很大程度上进行控制。例如,假设权重更新矩阵有100,000个参数,A为200,B为500。权重更新矩阵可以分解为较低维度的较小矩阵,A为200×3,B为3×500。这样我们就只有200×3 + 3×500 = 2100个可训练参数,仅占总参数数量的2.1%。如果我们决定只将LoRA应用于特定层,这个数量还可以进一步减少。

由于训练和应用的参数数量比实际模型少得多,文件大小可以小至8MB。这使得加载、应用和传输学习到的模型变得更加容易和快速。

7.5 QLoRA

QLoRA如何与LoRA不同?它是一种4位Transformer。

QLoRA是一种微调技术,它将高精度计算技术与低精度存储方法相结合。这有助于在保持模型高性能和准确性的同时,使模型大小保持较小。

QLoRA使用LoRA作为辅助手段来修复量化过程中引入的误差。

QLoRA的工作原理

QLoRA通过引入3个新概念来帮助减少内存使用,同时保持相同的性能质量。它们是4位Normal Float、双重量化和分页优化器。

4位Normal Float(NF4)

4位NormalFloat是一种新的数据类型,是保持16位性能水平的关键因素。它的主要特性是:数据类型中的任何位组合,例如0011或0101,都会从输入张量中分配到数量相等的元素。

QLoRA对权重进行4位量化,并以32位精度训练注入的适配器权重(LORA)。

QLoRA有一种存储数据类型(NF4)和一种计算数据类型(16位BrainFloat)。

我们将存储数据类型反量化为计算数据类型以进行前向和反向传递,但我们只对使用16位BrainFloat的LORA参数计算权重梯度。

1.归一化:首先对模型的权重进行归一化,使其具有零均值和单位方差。这确保了权重分布在零附近,并落在一定范围内。

2.量化:然后将归一化后的权重量化为4位。这涉及将原始的高精度权重映射到一组较小的低精度值。对于NF4,量化级别被选择为在归一化权重的范围内均匀分布。

3.反量化:在前向传递和反向传播过程中,量化后的权重被反量化回全精度。这是通过将4位量化值映射回其原始范围来完成的。反量化后的权重用于计算,但它们以4位量化形式存储在内存中。

数据会被量化到“桶”或“箱”中。数字2和3都落入相同的量化区间2。这种量化过程通过“四舍五入”到最接近的量化区间,让你可以使用更少的数字。

双重量化

双重量化是指对4位NF量化过程中使用的量化常数进行量化的独特做法。虽然这看起来不太起眼,但相关研究论文指出,这种方法有可能平均每个参数节省0.5位。这种优化在采用块wise k位量化的QLoRA中特别有用。与对所有权重一起进行量化不同,这种方法将权重分成不同的块或片段,分别进行量化。

块wise量化方法会生成多个量化常数。有趣的是,这些常数可以进行第二轮量化,从而提供了额外的节省空间的机会。由于量化常数的数量有限,这种策略仍然有效,减轻了与该过程相关的计算和存储需求。

分页优化器

如前所述,分位数量化涉及创建桶或箱来涵盖广泛的数值范围。这个过程会导致多个不同的数字被映射到同一个桶中,例如在量化过程中,2和3都被转换为值3。因此,权重的反量化会引入1的误差。

在神经网络中更广泛的权重分布上可视化这些误差,就可以看出分位数量化的固有挑战。这种差异凸显了为什么QLoRA更像是一种微调机制,而不是一种独立的量化策略,尽管它适用于4位推理。在使用QLoRA进行微调时,LoRA调整机制就会发挥作用,包括创建两个较小的权重更新矩阵。这些矩阵以更高精度的格式(如脑浮点16或浮点16)维护,然后用于更新神经网络的权重。

值得注意的是,在反向传播和前向传递过程中,网络的权重会进行反量化,以确保实际训练是以更高精度格式进行的。虽然存储仍然采用较低精度,但这种有意的选择会引入量化误差。然而,模型训练过程本身具有适应和减轻量化过程中这些低效性的能力。从本质上讲,采用更高精度的LoRA训练方法有助于模型学习并积极减少量化误差。

用HuggingFace进行QLoRA微调

要使用HuggingFace进行QLoRA微调,你需要同时安装BitsandBytes库和PEFT库。BitsandBytes库负责4位量化以及整个低精度存储和高精度计算部分。PEFT库将用于LoRA微调部分。

import torch
from peft import prepare_model_for_kbit_training, LoraConfig, get_peft_model
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
model_id = "EleutherAI/gpt-neox-20b"
bnb_config = BitsAndBytesConfig(load_in_4bit=True,lbnb_4bit_use_double_quant=True,bnb_4bit_quant_type="nf4",bnb_4bit_compute_dtype=torch.bfloat16
)
model = AutoModelForCausalLM.from_pretrained(model_id, quantization_config=bnb_config, device_map={"":0})
model.gradient_checkpointing_enable()
model = prepare_model_for_kbit_training(model)
config = LoraConfig(r=8,lora_alpha=32,target_modules=["query_key_value"],lora_dropout=0.05,bias="none",task_type="CAUSAL_LM"
)
model = get_peft_model(model, config)

7.6 IA3

IA3(通过抑制和放大内部激活注入适配器,Infused Adapter by Inhibiting and Amplifying Inner Activations)是一种基于适配器的技术,与LoRA有些相似。作者的目标是在避免上下文学习(ICL,in context learning或Few-Shot prompting)相关问题的同时,复制其优势。ICL在成本和推理方面可能会变得复杂,因为它需要用示例来提示模型。更长的提示需要更多的时间和计算资源来处理。但ICL可能是开始使用模型的最简单方法。

IA3通过引入针对模型激活的缩放向量来工作。总共引入了3个向量,lv、ik和lff。这些向量分别针对注意力层中的值、键以及密集层中的非线性层。这些向量与模型中的默认值进行逐元素相乘。一旦注入,这些参数在训练过程中就会被学习,而模型的其余部分保持冻结。这些学习到的向量本质上是针对手头的任务对预训练模型的权重进行缩放或优化。

到目前为止,这似乎是一种基本的基于适配器的参数高效微调(PEFT)方法。但不止如此。作者还使用了3个损失项来增强学习过程。这3个损失项是LLM、LUL和LLN。LLM是标准的交叉熵损失,它增加了生成正确响应的可能性。然后是LUL,即非似然损失(Unlikelihood Loss)。这个损失项通过等级分类(Rank Classification)来降低错误输出的概率。最后是LLN,它是一种长度归一化损失,对所有输出选择的长度归一化对数概率应用软max交叉熵损失。这里使用多个损失项是为了确保模型更快、更好地学习。因为我们试图通过少样本示例进行学习,这些损失是必要的。

现在让我们谈谈IA3中的两个非常重要的概念:等级分类和长度归一化。

在等级分类中,模型被要求根据正确性对一组响应进行排序。这是通过计算潜在响应的概率得分来完成的。然后使用LUL来降低错误响应的概率,从而增加正确响应的概率。但是在等级分类中,我们面临一个关键问题,即由于概率的计算方式,令牌较少的响应会排名更高。生成的令牌数量越少,概率就越高,因为每个生成令牌的概率都小于1。为了解决这个问题,作者提出将响应的得分除以响应中的令牌数量。这样做将对得分进行归一化。这里需要非常注意的一点是,归一化是在对数概率上进行的,而不是原始概率。对数概率是负数,且在0到1之间。

示例用法对于序列分类任务,可以按如下方式为Llama模型初始化IA3配置:

peft_config = IA3Config(task_type=TaskType.SEQ_CLS, target_modules=["k_proj", "v_proj", "down_proj"], feedforward_modules=["down_proj"]
)

7.7 P-Tuning

P-Tuning方法旨在优化传递给模型的提示的表示。在P-Tuning论文中,作者强调了提示工程在使用大语言模型时是一种非常强大的技术。P-Tuning方法建立在提示工程的基础上,并试图进一步提高优质提示的有效性。

P-Tuning通过为你的提示创建一个小型编码器网络来工作,该网络为传入的提示创建一个软提示。要使用P-Tuning调整你的大语言模型,你应该创建一个表示你的提示的提示模板。还有一个上下文x,用于模板中以获得标签y。这是论文中提到的方法。提示模板中使用的令牌是可训练和可学习的参数,这些被称为伪令牌。我们还添加了一个提示编码器,它帮助我们针对手头的特定任务更新伪令牌。提示编码器通常是一个双向LSTM网络,它为模型学习提示的最佳表示,然后将该表示传递给模型。LSTM网络连接到原始模型。这里只有编码器网络和伪令牌被训练,原始网络的权重不受影响。训练完成后,LSTM头部被丢弃,因为我们有可以直接使用的hi。

简而言之,提示编码器只改变传入提示的嵌入,以更好地表示任务,其他一切都保持不变。

7.8 Prefix Tuning

Prefix Tuning可以被视为P-Tuning的下一个版本。P-Tuning的作者发表了一篇关于P-Tuning V-2的论文,解决了P-Tuning的问题。在这篇论文中,他们实现了本文中介绍的Prefix Tuning。Prefix Tuning和P-Tuning没有太大区别,但仍然可能导致不同的结果。让我们深入解释一下。

在P-Tuning中,我们只在输入嵌入中添加可学习参数,而在Prefix Tuning中,我们在网络的所有层中添加这些参数。这确保了模型本身更多地了解它正在被微调的任务。我们在提示以及Transformer层的每一层激活中附加可学习参数。与P-Tuning的不同之处在于,我们不是完全修改提示嵌入,而是只在每一层提示的开头添加很少的可学习参数。

在Transformer的每一层,我们将一个带有可学习参数的软提示与输入连接起来。这些可学习参数通过一个非常小的MLP(只有2个全连接层)进行调整。这样做是因为论文的作者指出,直接更新这些提示令牌对学习率和初始化非常敏感。软提示增加了可训练参数的数量,但也大大提高了模型的学习能力。MLP或全连接层稍后可以去掉,因为我们只关心软提示,在推理时,软提示将被附加到输入序列中,引导模型。

7.9 Prompt Tuning(并非提示工程)

Prompt Tuning是最早基于仅使用软提示进行微调这一想法的论文之一。Prompt Tuning是一个非常简单且易于实现的想法。它包括在输入前添加一个特定的提示,并为该特定提示使用虚拟令牌或新的可训练令牌。在这个过程中,可以对这些新的虚拟令牌进行微调,以更好地表示提示。这意味着模型被调整为更好地理解提示。以下是论文中Prompt Tuning与全量微调的比较:

从图中可以看到,如果我们想将模型用于多个任务,全模型微调需要存在多个模型副本。但使用Prompt Tuning,你只需要存储学习到的提示令牌的虚拟令牌。例如,如果你使用“对这条推文进行分类:{tweet}”这样的提示,目标将是为该提示学习新的更好的嵌入。在推理时,只有这些新的嵌入将用于生成输出。这使得模型能够调整提示,以帮助自己在推理时生成更好的输出。

Prompt Tuning的效率

使用Prompt Tuning的最大优点是学习到的参数规模很小。文件大小可能只有KB级别。由于我们可以确定新令牌的维度大小和使用的参数数量,因此可以极大地控制要学习的参数数量。论文作者展示了,即使可训练令牌的数量非常少,该方法的表现也相当出色。并且随着使用更大的模型,性能只会进一步提升。

另一个很大的优点是,我们可以在不做任何修改的情况下,将同一个模型用于多个任务,因为唯一被更新的只是提示令牌的嵌入。这意味着,只要模型足够大且足够复杂,能够执行这些任务,你就可以将同一个模型用于推文分类任务和语言生成任务,而无需对模型本身进行任何修改。但一个很大的限制是,模型本身不会学到任何新东西。这纯粹是一个提示优化任务。这意味着,如果模型从未在情感分类数据集上进行过训练,Prompt Tuning可能不会有任何帮助。需要特别注意的是,这种方法优化的是提示,而不是模型。所以,如果你无法手工制作一个能较好完成任务的硬提示,那么尝试使用提示优化技术来优化软提示就没有任何意义。

硬提示与软提示:

硬提示可以被看作是一个定义明确的提示,它是静态的,或者充其量是一个模板。一个生成式人工智能应用程序也可以使用多个提示模板。

提示模板允许提示被存储、重复使用、共享和编程。生成式提示可以被整合到程序中,用于编程、存储和重复使用。

软提示是在Prompt Tuning过程中创建的。

与硬提示不同,软提示无法在文本中查看和编辑。提示由嵌入(一串数字)组成,它从更大的模型中获取知识。

可以肯定的是,软提示的一个缺点是缺乏可解释性。人工智能发现了与特定任务相关的提示,但无法解释为什么选择这些嵌入。就像深度学习模型本身一样,软提示是不透明的。

软提示可作为额外训练数据的替代品。

7.10 LoRA与Prompt Tuning对比

现在我们已经探索了各种参数高效微调(PEFT)技术。那么问题来了,是使用像适配器(Adapter )和LoRA这样的添加式技术,还是使用像P-Tuning和Prefix Tuning这样基于提示的技术呢?

在比较LoRA与P-Tuning和Prefix Tuning时,可以肯定地说,就充分发挥模型性能而言,LoRA是最佳策略。但根据你的需求,它可能不是最有效的。如果你想在与模型预训练任务差异很大的任务上训练模型,毫无疑问,LoRA是有效调整模型的最佳策略。但如果你的任务或多或少是模型已经理解的,只是挑战在于如何正确地向模型提供提示,那么你应该使用Prompt Tuning技术。Prompt Tuning不会修改模型中的许多参数,主要侧重于传入的提示。

需要注意的一个重要点是,LoRA将权重更新矩阵分解为较小的低秩矩阵,并使用它们来更新模型的权重。即使可训练参数较少,LoRA也会更新神经网络目标部分中的所有参数。而在Prompt Tuning技术中,只是向模型添加了一些可训练参数,这通常有助于模型更好地适应和理解任务,但并不能帮助模型很好地学习新特性。

7.11 LoRA和PEFT与全量微调对比

参数高效微调(PEFT)是作为全量微调的替代方案被提出的。在大多数任务中,已有论文表明,像LoRA这样的PEFT技术即使不比全量微调更好,也与之相当。但是,如果你希望模型适应的新任务与模型预训练的任务完全不同,PEFT可能并不够。在这种情况下,有限数量的可训练参数可能会导致严重问题。

如果我们试图使用像LLaMA或Alpaca这样基于文本的模型构建一个代码生成模型,我们可能应该考虑对整个模型进行微调,而不是使用LoRA来调整模型。这是因为这个任务与模型已知和预训练的内容差异太大。另一个典型的例子是训练一个只懂英语的模型来生成尼泊尔语的文本。

8. 大语言模型推理:

在使用大语言模型(LLM)进行推理时,我们通常可以配置各种参数来微调其输出和性能。以下是一些关键参数的详细介绍:

  1. Top-k采样:在每一步只对可能性最高的k个词元进行采样,这样可以增加多样性并避免重复。k值越高,输出的多样性越强,但可能连贯性会变差。
  2. 温度参数:影响下一个可能词元的概率分布,用于控制随机性和 “创造性”。较低的温度会生成更可能出现但可能重复的文本,而较高的温度则会鼓励多样性,产生更不可预测的输出。
  3. Top-P(核)采样:Top-P或核采样将词元的选择限制在累计概率达到某个阈值的词汇子集内,有助于控制生成输出的多样性。
  4. 最大长度:设置大语言模型生成的最大词元数,防止输出过长。
  5. 上下文提示:通过提供特定的上下文提示或输入,可以引导模型生成与该上下文一致的文本,确保生成的输出在给定的上下文中相关且连贯。
  6. 重复惩罚:对出现重复n - gram的序列进行惩罚,鼓励多样性和新颖性。
  7. 采样方式:在确定性(贪心)和基于随机采样的生成方式中选择。贪心模式在每一步选择最可能的词元,而随机采样则引入随机性。贪心模式优先考虑准确性,而随机采样鼓励多样性和创造性。
  8. 束搜索:保留多个潜在序列,在每一步扩展最有希望的序列,与Top-k采样相比,旨在生成更连贯、更准确的输出。

9. 提示工程:

提示工程,也称为上下文提示,是指在不更新模型权重的情况下,与大语言模型进行沟通,引导其行为以获得期望结果的方法。这是一门实证科学,提示工程方法的效果在不同模型之间可能差异很大,因此需要大量的实验和探索。

什么是提示?

我们与大语言模型交互时使用的自然语言指令被称为提示。构建提示的过程称为提示工程。

提示的作用

大语言模型根据提示中的指令进行推理并完成任务的过程被称为上下文学习。

少样本提示

大语言模型在没有任何示例的情况下响应提示指令的能力称为零样本学习。

当提供单个示例时,称为单样本学习。

如果提供多个示例,则称为少样本学习。

上下文窗口,即大语言模型可以提供和推理的最大词元数,在零样本/单样本/少样本学习中至关重要。

9.1 思维链(CoT)提示

思维链(CoT)提示(Wei等人,2022)会生成一系列短句子,逐步描述推理逻辑,即推理链或推理依据,最终得出答案。在使用大型模型(例如参数超过500亿的模型)处理复杂推理任务时,CoT的优势更为明显。而简单任务使用CoT提示的受益则相对较小。

9.2 PAL(程序辅助语言模型)

Gao等人(2022)PAL: Program-aided Language Models提出了一种方法,使用大语言模型读取自然语言问题,并生成程序作为中间推理步骤。这种方法被称为程序辅助语言模型(PAL),它与思维链提示的不同之处在于,它不是使用自由形式的文本获取解决方案,而是将解决方案步骤交给诸如Python解释器这样的程序运行时处理。

9.3 ReAct提示

ReAct的灵感来自于 “行动” 和 “推理” 之间的协同作用,这种协同作用使人类能够学习新任务并做出决策或进行推理。

CoT由于无法访问外部世界或更新自身知识,可能会导致事实幻觉和错误传播等问题。

ReAct是一种将推理和行动与大语言模型相结合的通用范式。ReAct促使大语言模型为任务生成语言推理轨迹和行动。这使系统能够进行动态推理,创建、维护和调整行动方案,同时还能与外部环境(例如维基百科)进行交互,将更多信息纳入推理过程。下图展示了ReAct的一个示例以及执行问答任务所涉及的不同步骤。

10. 模型优化技术:

模型压缩方法包括:(a)剪枝、(b)量化和(c)知识蒸馏。

10.1 量化

模型量化是一种用于减小大型神经网络(包括大语言模型LLM)大小的技术,通过修改其权重的精度来实现。大语言模型的量化之所以可行,是因为实证结果表明,虽然神经网络训练和推理的某些操作必须使用高精度,但在某些情况下,可以使用低得多的精度(例如float16),这可以减小模型的整体大小,使其能够在性能和准确性可接受的情况下,在性能较弱的硬件上运行。

一般来说,在神经网络中使用高精度与更高的准确性和更稳定的训练相关。使用高精度在计算上也更为昂贵,因为它需要更多且更昂贵的硬件。谷歌和英伟达的相关研究表明,神经网络的某些训练和推理操作可以使用较低的精度。

除了研究之外,这两家公司还开发了支持低精度操作的硬件和框架。例如,英伟达的T4加速器是低精度GPU,其张量核心技术比K80的效率要高得多。谷歌的TPU引入了bfloat16的概念,这是一种为神经网络优化的特殊基本数据类型。低精度的基本思想是,神经网络并不总是需要使用64位浮点数的全部范围才能表现良好。

随着神经网络越来越大,利用低精度的重要性对使用它们的能力产生了重大影响。对于大语言模型来说,这一点更为关键。

英伟达的A100 GPU最先进的版本有80GB内存。在下面的表格中可以看到,LLama2 - 70B模型大约需要138GB内存,这意味着要部署它,我们需要多个A100 GPU。在多个GPU上分布模型不仅意味着要购买更多的GPU,还需要额外的基础设施开销。另一方面,量化版本大约需要40GB内存,因此可以轻松地在一个A100上运行,显著降低了推理成本。这个例子甚至还没有提到在单个A100中,使用量化模型会使大多数单个计算操作执行得更快。

使用llama.cpp进行4位量化的示例,大小可能会因方法略有不同。

1.量化如何缩小模型?:量化通过减少每个模型权重所需的比特数来显著减小模型的大小。一个典型的场景是将权重从FP16(16位浮点数)减少到INT4(4位整数)。这使得模型可以在更便宜的硬件上运行,并且 / 或者运行速度更快。然而,降低权重的精度也会对大语言模型的整体质量产生一定影响。研究表明,这种影响因使用的技术而异,并且较大的模型对精度变化的影响较小。较大的模型(超过约700亿参数)即使转换为4位,也能保持其性能,像NF4这样的一些技术表明对其性能没有影响。因此,对于这些较大的模型,4位似乎是在性能与大小 / 速度之间的最佳折衷,而6位或8位可能更适合较小的模型。

2.大语言模型量化的类型:获得量化模型的技术可以分为两类。

  • 训练后量化(PTQ):将已经训练好的模型的权重转换为较低精度,而无需任何重新训练。虽然这种方法简单直接且易于实现,但由于权重值精度的损失,可能会使模型性能略有下降。
  • 量化感知训练(QAT):与PTQ不同,QAT在训练阶段就整合了权重转换过程。这通常会带来更好的模型性能,但计算要求更高。一种常用的QAT技术是QLoRA。

本文将只关注PTQ策略及其关键区别。

  1. 更大的量化模型与更小的未量化模型:我们知道降低精度会降低模型的准确性,那么你会选择较小的全精度模型,还是选择推理成本相当的更大的量化模型呢?尽管理想的选择可能因多种因素而异,但Meta的最新研究提供了一些有见地的指导。虽然我们预期降低精度会导致准确性下降,但Meta的研究人员已经证明,在某些情况下,量化模型不仅表现更优,而且还能减少延迟并提高吞吐量。在比较8位的130亿参数模型和16位的70亿参数模型时,也可以观察到相同的趋势。本质上,在比较推理成本相似的模型时,更大的量化模型可以超越更小的未量化模型。随着网络规模的增大,这种优势更加明显,因为大型网络在量化时质量损失较小。
  2. 在哪里可以找到已经量化的模型?:幸运的是,在Hugging Face Hub上可以找到许多已经使用GPTQ(有些与ExLLama兼容)、NF4或GGML进行量化的模型版本。快速浏览一下就会发现,这些模型中有很大一部分是由大语言模型社区中一位有影响力且备受尊敬的人物TheBloke量化的。该用户发布了多个使用不同量化方法的模型,因此人们可以根据具体的用例选择最合适的模型。要轻松试用这些模型,可以打开一个Google Colab,并确保将运行时更改为GPU(有免费的GPU可供使用)。首先安装Hugging Face维护的transformers库以及所有必要的库。由于我们将使用由Auto - GPTQ量化的模型,因此还需要安装相应的库:
  3. 你可能需要重新启动运行时,以便安装的库可用。然后,只需加载已经量化的模型,这里我们加载一个之前使用Auto - GPTQ量化的Llama - 2 - 7B - Chat模型,如下所示:
#pip install transformers
#pip install accelerate
#pip install optimum
#pip install auto - gptqfrom transformers import AutoModelForCausalLM, AutoTokenizer
import torchmodel_id = "TheBloke/Llama-2-7b-Chat-GPTQ"
tokenizer = AutoTokenizer.from_pretrained(model_id, torch_dtype=torch.float16, device_map="auto")
model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype=torch.float16, device_map="auto")

量化大语言模型:如前所述,Hugging Face Hub上已经有大量量化模型,在许多情况下,无需自己压缩模型。然而,在某些情况下,你可能希望使用尚未量化的模型,或者你可能希望自己压缩模型。这可以通过使用适合你特定领域的数据集来实现。为了演示如何使用AutoGPTQ和Transformers库轻松量化模型,我们采用了Optimum(Hugging Face用于优化训练和推理的解决方案)中简化版的AutoGPTQ接口:

from transformers import AutoModelForCausalLM, AutoTokenizer, GPTQConfigmodel_id = "facebook/opt-125m"
tokenizer = AutoTokenizer.from_pretrained(model_id)
quantization_config = GPTQConfig(bits=4, dataset = "c4", tokenizer=tokenizer)
model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto", quantization_config=quantization_config)

模型压缩可能很耗时。例如,一个1750亿参数的模型至少需要4个GPU小时,尤其是使用像 “c4” 这样的大型数据集时。值得注意的是,量化过程中的比特数或数据集可以通过GPTQConfig的参数轻松修改。更改数据集会影响量化的方式,因此,如果可能的话,使用与推理时看到的数据相似的数据集,以最大化性能。

  1. 量化技术:在模型量化领域已经出现了几种最先进的方法。让我们深入了解一些突出的方法:

  • GPTQ:有一些实现选项,如AutoGPTQ、ExLlama和GPTQ - for - LLaMa,这种方法主要侧重于GPU执行。
  • NF4:在bitsandbytes库中实现,它与Hugging Face的transformers库紧密合作。它主要被QLoRA方法使用,以4位精度加载模型进行微调。
  • GGML:这个C库与llama.cpp库紧密合作。它为大语言模型提供了一种独特的二进制格式,允许快速加载和易于读取。值得注意的是,它最近转换为GGUF格式,以确保未来的可扩展性和兼容性。

许多量化库支持多种不同的量化策略(例如4位、5位和8位量化),每种策略在效率和性能之间都提供了不同的权衡。

10.2 蒸馏

知识蒸馏(KD; Hinton等人,2015年;Gou等人,2020年)Distilling the Knowledge in a Neural Network是一种构建更小、成本更低模型(“学生模型”)的直接方法,通过将预训练的高成本模型(“教师模型”)的能力转移到学生模型中,来加快推理速度。除了要求学生模型的输出空间与教师模型匹配,以便构建合适的学习目标之外,对学生模型的架构构建方式并没有太多限制。

教师模型已经在训练数据上进行了微调,因此,其概率分布可能与真实数据非常接近,并且在生成的token上不会有太多变化。

当温度>1时,概率分布会变得更宽泛。

  • T > 1时 => 教师模型的输出 -> 软标签 学生模型的输出 -> 软预测
  • T = 1时 => 教师模型的输出 -> 硬标签 学生模型的输出 -> 硬预测

蒸馏对于生成式解码器模型的效果并不显著,它对仅编码器模型(如BERT)更为有效,因为这类模型存在大量的表示冗余。

10.3 剪枝

网络剪枝是指在保持模型能力的同时,通过修剪不重要的模型权重或连接来减小模型大小。这一过程可能需要也可能不需要重新训练。剪枝可分为非结构化剪枝和结构化剪枝。

非结构化剪枝允许删除任何权重或连接,因此不会保留原始网络架构。非结构化剪枝通常与现代硬件的适配性不佳,并且无法真正加快推理速度。

结构化剪枝旨在保持矩阵乘法中部分元素为零的密集形式。为了适配硬件内核的支持,它们可能需要遵循特定的模式限制。这里我们主要关注结构化剪枝,以在Transformer模型中实现高稀疏性。

构建剪枝网络的常规工作流程包含三个步骤:

  1. 训练一个密集网络直至收敛;
  2. 对网络进行剪枝,去除不需要的结构;
  3. 可选步骤,重新训练网络,通过新的权重恢复模型性能 。

通过网络剪枝在密集模型中发现稀疏结构,同时使稀疏网络仍能保持相似性能,这一想法的灵感来源于彩票假设(LTH):一个随机初始化的、密集的前馈网络包含多个子网络,其中只有一部分(稀疏网络)是 “中奖彩票”,当单独训练时,这些子网络能够达到最佳性能。

结论:

在本篇文章中,我们探索了检索增强生成(RAG)应用中的文本生成部分,重点介绍了大语言模型(LLM)的使用。内容涵盖了语言建模、预训练面临的挑战、量化技术、分布式训练方法,以及大语言模型的微调。此外,还讨论了参数高效微调(PEFT)技术,包括适配器、LoRA和QLoRA;介绍了提示策略、模型压缩方法(如剪枝和量化),以及各种量化技术(GPTQ、NF4、GGML)。最后,对用于减小模型大小的蒸馏和剪枝技术进行了讲解。

References:

[1]Transformer: https://arxiv.org/abs/1706.03762

[2]BLOOM: https://huggingface.co/docs/transformers/model_doc/bloom

[3]Parameter-Efficient Transfer Learning for NLP: https://arxiv.org/abs/1902.00751

[4]Intrinsic Dimensionality Explains the Effectiveness of Language Model Fine-Tuning: https://arxiv.org/abs/2012.13255

[5]Infused Adapter by Inhibiting and Amplifying Inner Activations: https://arxiv.org/abs/2205.05638

[6]P-Tuning论文: https://arxiv.org/abs/2103.10385

[7]P-Tuning V-2: https://arxiv.org/abs/2110.07602

[8]思维链(CoT)提示: https://arxiv.org/abs/2201.11903

[9]PAL: Program-aided Language Models: https://arxiv.org/abs/2211.10435

[10]Distilling the Knowledge in a Neural Network: https://arxiv.org/abs/1503.02531

相关文章:

大语言模型的训练、微调及压缩技术

The rock can talk — not interesting. The rock can read — that’s interesting. (石头能说话,不稀奇。稀奇的是石头能读懂。) ----硅谷知名创业孵化器 YC 的总裁 Gar Tan 目录 1. 什么是大语言模型? 2. 语言建模&#xff…...

制作一个简单的操作系统2

Linux 一般都提供了需要的标准工具。使用nasm汇编器,gcc编写自己的os 开发环境截图: 创建一个文件,让 BIOS 将文件识别为一个可引导的磁盘 理论基础 计算机上电启动后,首先运行主板 BIOS 程序, BIOS 并不知道如何加载操作系统,所以 BIOS 把加载操作系统的任务交给引导…...

day31和day32图像处理OpenCV

文章目录 一、图像预处理10 图像添加水印11 图像噪点消除11.1 均值滤波11.2 方框滤波11.3 高斯滤波11.4 中值滤波11.5 双边滤波11.6 小结 12 图像梯度处理12.1 图像梯度12.2 垂直或水平边缘提取 一、图像预处理 10 图像添加水印 本实验中添加水印的概念其实可以理解为将一张图…...

火山引擎的生态怎么样

“火山引擎”是字节跳动旗下的**云计算服务平台**,主要为企业提供智能化的技术解决方案,涵盖云计算、大数据、人工智能、音视频处理等多个领域。其“生态”指的是火山引擎通过技术开放、合作伙伴计划、行业解决方案等构建的商业与技术协作网络。以下从多…...

AI 数字短视频系统AI数字人源码开发:开启短视频行业发展新维度​

在短视频行业蓬勃发展的背后,创作效率瓶颈、内容同质化等问题逐渐凸显。AI 数字短视频数字人源码开发的出现,以创新性的解决方案,为行业发展带来了全新机遇与多元价值。​ 打破创作壁垒,释放全民创作潜力​ 对于普通创作者而言&…...

FreeFileSync:文件同步对比工具

FreeFileSync 是一款开源、跨平台的文件同步与备份工具,支持 Windows、Linux 和 macOS 系统‌。其核心功能是通过智能对比源文件夹与目标文件夹的内容差异,仅同步修改部分,提升效率并节省存储空间‌。软件体积小巧(约20MB&#xf…...

SimBody安装

SimBody安装 Simbody 是一个用于创建生物力学和机械系统仿真的多体动力学库。 SimBody安装 Windows安装: 下载地址:GitHub - simbody/simbody: High-performance C multibody dynamics/physics library for simulating articulated biomechanical and…...

刀片服务器的散热构造方式

刀片服务器的散热构造是其高密度、高性能设计的核心挑战之一。其散热系统需在有限空间内高效处理多个刀片模块产生的集中热量,同时兼顾能耗、噪音和可靠性。以下从模块化架构、核心散热技术、典型方案对比、厂商差异及未来趋势等方面展开分析: 一、模块化散热架构 刀片服务器…...

从数字化到智能化,百度 SRE 数智免疫系统的演进和实践

1. 为什么 SRE 需要数智免疫系统? 2022 年 10 月,在 Gartner 公布的 2023 年十大战略技术趋势中提到了「数字免疫系统」的概念,旨在通过结合数据驱动的一系列手段来提高系统的弹性和稳定性。 在过去 2 年的时间里,百度基于该…...

STM32F7安全库各版本发布内容的表格化中文总结

以下是STM32F7安全库各版本发布内容的中文总结: 英文原文: version V2.0.0 This document describes the STM32F7 Safety release V2.0.0 Main changes: Maintenance release with new STL lib Contents: the SW expansion package, delivery itse…...

使用dompurify修复XSS跨站脚本缺陷

1. 问题描述 漏洞扫描说有一个低危漏洞,容易被跨站脚本攻击XSS。 2. 使用dompurify修复 DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. 简单来说,我们可以使用 dompurify 处理xss跨站脚本攻击。 2.…...

下载electron 22.3.27 源码错误集锦

下载步骤同 electron源码下载及编译_electron源码编译-CSDN博客 问题1 从github 下载 dugite超时,原因没有找到 Validation failed. Expected 8ea2d0d3c9d9e4615069913207371ffe892dc10fb93975972f2f6e668f2e3b3a but got e3b0c44298fc1c149afbf4c8996fb92427ae41e…...

Java漏洞原理与实战

一、基本概念 1、序列化与反序列化 (1)序列化:将对象写入IO流中,ObjectOutputStream类的writeobject()方法可以实现序列化 (2)反序列化:从IO流中恢复对象,ObjectinputStream类的readObject()方法用于反序列化 (3)意义:序列化机制允许将实现序列化的J…...

查看matlab函数帮助文档的方法

方法一:在命令行窗口中使用help命令 方法二:在命令行窗口中使用doc命令 方法三:在帮助文档中搜索关键字...

string函数具体事例

输出所有字串出现的位置 输入两个字符串A和B&#xff0c;输出B在A中出现的位置 输入 两行 第一行是一个含有空格的字符串 第二行是要查询的字串 输出 字串的位置 样例输入 I love c c python 样例输出 -1 样例输入 I love c c c 样例输出 8 12 #include<iostream> #inclu…...

OpenCV 中的分水岭算法的原理及其应用---图像分割的利器

图像分割作为计算机视觉的基石领域&#xff0c;历经数十年的演进与革新&#xff0c;从传统的图像处理方法到如今蓬勃发展的深度学习技术&#xff0c;始终推动着计算机视觉应用的边界拓展。本系列文章将通过三篇深度技术博客&#xff0c;分别对三种极具代表性的图像分割技术展开…...

Python项目--基于机器学习的股票预测分析系统

1. 项目介绍 在当今数字化时代&#xff0c;金融市场的数据分析和预测已经成为投资决策的重要依据。本文将详细介绍一个基于Python的股票预测分析系统&#xff0c;该系统利用机器学习算法对历史股票数据进行分析&#xff0c;并预测未来股票价格走势&#xff0c;为投资者提供决策…...

第三阶段面试题

Nginx nginx常用模块以及其功能 proxy模块&#xff0c;进行代理功能 ssl模块&#xff0c;进行HTTPS协议的使用 gzip模块&#xff0c;进行传输数据的压缩 upstream模块&#xff0c;进行反向代理时使用 static模块&#xff0c;静态资源进行访问的模块 cache模块&#xff0…...

spring响应式编程系列:总体流程

目录 示例 程序流程 just subscribe new LambdaMonoSubscriber ​​​​​​​MonoJust.subscribe ​​​​​​​new Operators.ScalarSubscription ​​​​​​​onSubscribe ​​​​​​​request ​​​​​​​onNext 时序图 类图 数据发布者 MonoJust …...

基于PySide6与pyCATIA的圆柱体特征生成工具开发实战——NX建模之圆柱命令的参考与移植

引言 在机械设计领域&#xff0c;特征建模的自动化是提升设计效率的关键。本文基于PySide6与pycatia技术栈&#xff0c;深度解析圆柱特征自动化生成系统的开发实践&#xff0c;涵盖参数化建模、交互式元素选择、异常处理等核心模块&#xff0c;实现比传统手动操作提升3倍效率的…...

kafka jdbc connector适配kadb数据实时同步

测试结论 源端增量获取方式包括&#xff1a;bulk、incrementing、timestamp、incrementingtimestamp&#xff08;混合&#xff09;&#xff0c;各种方式说明如下&#xff1a; bulk: 一次同步整个表的数据 incrementing: 使用严格的自增列标识增量数据。不支持对旧数据的更新…...

pgsql中使用jsonb的mybatis-plus和jps的配置

在pgsql中使用jsonb类型的数据时&#xff0c;实体对象要对其进行一些相关的配置&#xff0c;而mybatis和jpa中使用各不相同。 在项目中经常会结合 MyBatis-Plus 和 JPA 进行开发&#xff0c;MyBatis_plus对于操作数据更灵活&#xff0c;jpa可以自动建表&#xff0c;两者各取其…...

4.17-4.18学习总结 多线程

并发与并行&#xff1a; 并发和并行是有可能都在发生的。 多线程的实现方式&#xff1a; 第一种&#xff1a;创建子类对象&#xff0c;调用start方法启动线程。 第二种&#xff1a; 第三种&#xff1a; 第一种和第二种不可以获取到多线程结果&#xff0c;但第三章种可以。 多…...

无人机在农业中的应用与挑战!

一、无人机在农业中的作用 1. 提升作业效率与降低成本 无人机在喷洒农药、播种、施肥、吊运等环节显著提升效率。例如&#xff0c;湖北秭归县使用大疆T100无人机吊运脐橙&#xff0c;单次85公斤的运输任务仅需2分钟&#xff0c;而人工需1小时&#xff0c;综合成本降低250元…...

无刷电机槽数相同、转子极数不同的核心区别

一、基础原理差异 无刷电机的核心参数: 槽数(定子槽数,记为 ( Z )):定子铁芯上的绕组槽数量,决定绕组布局。极数(转子磁极数,记为 ( 2p )):转子上的永磁体磁极对数(总极数为 ( 2p ),如 ( p=4 ) 表示 8 极)。核心关系:槽极配合(( Z/2p ))决定电机电磁结构,相同…...

为您的照片提供本地 AI 视觉:使用 Llama Vision 和 ChromaDB 构建 AI 图像标记器

有没有花 20 分钟浏览您的文件夹以找到心中的特定图像或屏幕截图&#xff1f;您并不孤单。 作为工作中的产品经理&#xff0c;我总是淹没在竞争对手产品的屏幕截图、UI 灵感以及白板会议或草图的照片的海洋中。在我的个人生活中&#xff0c;我总是捕捉我在生活中遇到的事物&am…...

OpenAI 34页最佳构建Agent实践

penAI发布O4&#xff0c;也发布34页最佳构建Agent实践&#xff0c;值得阅读。 什么是Agent&#xff1f; 传统软件使用户能够简化和自动化工作流程&#xff0c;而代理能够以高度独立的方式代表用户执行相同的工作流程。 代理是能够独立地代表您完成任务的系统。 工作流程是必…...

第 5 期(进阶版):训练第一个 DDPM 模型(使用 CIFAR-10 数据集)

—— 用 DDPM 模型生成彩色图像&#xff0c;感受扩散魔法在 CIFAR-10 上的威力&#xff01; 本期目标 将 MNIST 替换为 CIFAR-10&#xff1b; 模型结构适配 RGB 三通道输入&#xff1b; 保持原始扩散与采样流程&#xff1b; 增加图像可视化对比&#xff01; 数据准备&…...

进程间通信(IPC)----共享内存

进程间通信&#xff08;IPC&#xff09;的共享内存机制允许不同进程直接访问同一块物理内存区域&#xff0c;是速度最快的IPC方式&#xff08;无需数据拷贝&#xff09;。 一、共享内存核心概念 1. 基本原理 共享内存区域&#xff1a;由内核管理的特殊内存段&#xff0c;可被…...

Xcode16 调整 Provisioning Profiles 目录导致证书查不到

cronet demo 使用的 ninja 打包&#xff0c;查找 Provisioning Profiles 路径是 ~/Library/MobileDevice/Provisioning Profiles&#xff0c;但 Xcode16 把该路径改为了 ~/Library/Developer/Xcode/UserData/Provisioning Profiles&#xff0c;导致在编译 cronet 的demo 时找不…...

Debian服务器环境下env变量丢失怎么办

在 Debian服务器环境下&#xff0c;如果出现了 env 环境变量丢失的问题&#xff0c;比如常见的 PATH、JAVA_HOME、PYTHONPATH 等系统变量或自定义变量不起作用&#xff0c;可能会导致一些命令无法执行、服务无法启动、脚本报错等。 这个问题常见于&#xff1a; 使用 cron、sy…...

搜广推校招面经七十八

字节推荐算法 一、实习项目&#xff1a;多任务模型中的每个任务都是做什么&#xff1f;怎么确定每个loss的权重 这个根据实际情况来吧。如果实习时候用了moe&#xff0c;就可能被问到。 loss权重的话&#xff0c;直接根据任务的重要性吧。。。 二、特征重要性怎么判断的&…...

ctf.show—Web(1-10)详细通关教程

Web1-签到题 1、按F12查看元素&#xff0c;发现有一段被注释的字符串 2、看起来并不像flag&#xff0c;格式类似于Base64编码 扔到Base64在线编码平台&#xff1a;Base64 编码/解码 - 锤子在线工具此工具是一个 Base64 编码或解码在线工具&#xff0c;实现把字符串转成 Base6…...

双层Key缓存

双层 Key 缓存是一种针对 缓存击穿 和 雪崩问题 的优化方案&#xff0c;其核心思想是通过 主备双缓存 的机制&#xff0c;确保在热点数据过期时仍能提供可用服务&#xff0c;同时降低对数据库的瞬时压力。以下是其核心原理、实现细节及适用场景的深度解析&#xff1a; 一、核心…...

android编译使用共享缓存

注意 服务器端与客户端系统的版本号需为Ubuntu20.04ccache版本不能低于4.4执行用户需要为sudo权限服务器端nfs目录权限必须为nobody:nogroup 一、服务端配置&#xff1a; 在服务器192.168.60.142上配置 NFS 共享 1.安装 NFS 服务器&#xff1a; 1 sudo apt-get install nfs…...

如何使用Labelimg查看已经标注好的YOLO数据集标注情况

文章目录 1、 安装并运行Labelimg1.1、安装Labelimg1.2、运行Labelimg 2、查看数据集标注情况2.1、创建类别名称文件classes.txt2.2、使用Labelimg打开查看标注文件2.3、正式标注 3、目标检测系列文章 本文主要介绍一下如何使用LabelImg查看已经标注好的YOLO数据集标注情况&…...

Web3架构下的数据隐私与保护

在这个信息爆炸的时代&#xff0c;Web3的概念如同一股清流&#xff0c;以其去中心化的特性&#xff0c;为数据隐私与保护带来了新的希望。Web3&#xff0c;也被称作下一代互联网&#xff0c;它通过区块链技术实现数据的去中心化存储和处理&#xff0c;旨在提高数据的安全性和隐…...

PCM 参数深度解析:采样率、帧、缓存大小与多通道关系

将下面的 PCM 配置作为例子&#xff1a; config.channels 2; // 立体声&#xff08;2 个通道&#xff09; config.rate 48000; // 采样率 48000 Hz&#xff0c;即每秒 48000 帧 config.period_size 1024; // 每个周…...

Kafka消费者端重平衡流程

重平衡的完整流程需要消费者 端和协调者组件共同参与才能完成。我们先从消费者的视角来审视一下重平衡的流程。在消费者端&#xff0c;重平衡分为两个步骤&#xff1a;分别是加入组和等待领导者消费者&#xff08;Leader Consumer&#xff09;分配方案。这两个步骤分别对应两类…...

【字节跳动AI论文】海姆达尔:生成验证的测试时间扩展

摘要&#xff1a;人工智能系统只能在能够验证知识本身的范围内创建和维护知识。 最近关于长链推理的研究表明&#xff0c;LLM在解决竞争问题方面具有巨大的潜力&#xff0c;但它们的验证能力仍然很弱&#xff0c;而且没有得到充分的研究。 在本文中&#xff0c;我们提出了Heimd…...

【Datawhale Al春训营】气象预测(AI+航空安全)竞赛笔记

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…...

大模型应用开发实战:AI Agent与智能体开发技术解析

更多AI大模型应用开发学习内容&#xff0c;尽在聚客AI学院 一、AI Agent的核心概念 AI Agent&#xff08;智能体&#xff09;是基于大模型构建的自主任务执行系统&#xff0c;能够根据用户指令拆解目标、调用工具、完成复杂任务&#xff08;如数据分析、自动化办公&#xff09…...

《Learning Langchain》阅读笔记3-基于 Gemini 的 Langchain如何从LLMs中获取特定格式

纯文本输出是有用的&#xff0c;但在某些情况下&#xff0c;我们需要 LLM 生成结构化输出&#xff0c;即以机器可读格式&#xff08;如 JSON、XML 或 CSV&#xff09;或甚至以编程语言&#xff08;如 Python 或 JavaScript&#xff09;生成的输出。当我们打算将该输出传递给其他…...

Mac mini 安装mysql数据库以及出现的一些问题的解决方案

首先先去官网安装一下mysql数据库&#xff0c;基本上都是傻瓜式安装的流程&#xff0c;我也就不详细说了。 接下来就是最新版的mysql安装的时候&#xff0c;他就会直接让你设置一个新的密码。 打开设置&#xff0c;拉到最下面就会看到一个mysql的图标&#xff1a; 我设置的就是…...

智能体时代的产业范式确立,中国企业以探索者姿态走出自己的路

作者 | 曾响铃 文 | 响铃说 当前&#xff0c;一个新的20年的产业升级期已经开启&#xff0c;系统性的发展路径也正在形成。 前不久&#xff0c;以“共建智能体时代“为主题的超聚变探索者大会2025在河南郑州举办。超聚变变数字技术有限公司&#xff08;以下简称&#xff1a;…...

电路安全智控系统与主机安全防护系统主要功能是什么

电路安全智控系统被称为电路安全用电控制系统。电路安全智控系统具备一系列强大且实用的功能。电路安全智控系统能够对总电压、总电流、总功率、总电能&#xff0c;以及各分路的电压、电流、功率、电能和功率因素等进行全方位的监控。在大型工厂的电力分配中&#xff0c;通过对…...

MCP Server驱动传统SaaS智能化转型:从工具堆叠到AI Agent生态重构,基于2025年技术演进与产业实践

MCP Server驱动传统SaaS智能化转型&#xff1a;从工具堆叠到AI Agent生态重构 &#xff08;基于2025年技术演进与产业实践&#xff09; MCP模型上下文协议 一、技术底座革新&#xff1a;MCP协议重构AI时代的"数字接口" 传统SaaS软件向大模型AI应用转型的核心矛盾…...

【工具变量】地市农业播种面积及粮食产量等21个相关指标(2013-2022年)

粮食产量、粮食播种面积及农作物播种面积等&#xff0c;是衡量农业发展水平和粮食安全的重要指标。随着全球粮食需求的持续增长&#xff0c;准确掌握这些数据对制定农业政策、优化生产结构和提高农业生产效率至关重要。因此&#xff0c;缤本次分享数据包括《中国统计NJ》、《中…...

使用 PySpark 批量清理 Hive 表历史分区

使用 PySpark 批量清理 Hive 表历史分区 在大数据平台中&#xff0c;Hive 表通常采用分区方式存储数据&#xff0c;以提升查询效率和数据管理的灵活性。随着数据的不断积累&#xff0c;历史分区会越来越多&#xff0c;既占用存储空间&#xff0c;也影响元数据管理性能。因此&a…...

A. k-th equality(1700)

Problem - 1835A - Codeforces Daily_CF_Problems/daily_problems/2025/04/0417/solution/cf1835a.md at main Yawn-Sean/Daily_CF_Problems 考虑所有形式为 abc 的等式&#xff0c;其中 a有 A 位数&#xff0c; b 有 B 位数&#xff0c; c 有 C 位数。所有数字都是正整数,求…...