人工智能大语言模型微调技术:SFT 监督微调、LoRA 微调方法、P-tuning v2 微调方法、Freeze 监督微调方法

人工智能大语言模型微调技术:SFT 监督微调、LoRA 微调方法、P-tuning v2 微调方法、Freeze 监督微调方法

1.SFT 监督微调

1.1 SFT 监督微调基本概念

SFT(Supervised Fine-Tuning)监督微调是指在源数据集上预训练一个神经网络模型,即源模型。然后创建一个新的神经网络模型,即目标模型。目标模型复制了源模型上除了输出层外的所有模型设计及其参数。这些模型参数包含了源数据集上学习到的知识,且这些知识同样适用于目标数据集。源模型的输出层与源数据集的标签紧密相关,因此在目标模型中不予采用。微调时,为目标模型添加一个输出大小为目标数据集类别个数的输出层,并随机初始化该层的模型参数。在目标数据集上训练目标模型时,将从头训练到输出层,其余层的参数都基于源模型的参数微调得到。

1.2 监督微调的步骤

具体来说,监督式微调包括以下几个步骤:

  • 预训练 首先在一个大规模的数据集上训练一个深度学习模型,例如使用自监督学习或者无监督学习算法进行预训练;
  • 微调 使用目标任务的训练集对预训练模型进行微调。通常,只有预训练模型中的一部分层被微调,例如只微调模型的最后几层或者某些中间层。在微调过程中,通过反向传播算法对模型进行优化,使得模型在目标任务上表现更好;
  • 评估 使用目标任务的测试集对微调后的模型进行评估,得到模型在目标任务上的性能指标。

1.3 监督微调的特点

监督式微调能够利用预训练模型的参数和结构,避免从头开始训练模型,从而加速模型的训练过程,并且能够提高模型在目标任务上的表现。监督式微调在计算机视觉、自然语言处理等领域中得到了广泛应用。然而监督也存在一些缺点。首先,需要大量的标注数据用于目标任务的微调,如果标注数据不足,可能会导致微调后的模型表现不佳。其次,由于预训练模型的参数和结构对微调后的模型性能有很大影响,因此选择合适的预训练模型也很重要。

1.4 常见案例

  • 样例 1

在计算机视觉中,低层的网络主要学习图像的边缘或色斑,中层的网络主要学习物体的局部和纹理,高层的网络识别抽象的语义,如下图所示。因此,可以把一个神经网络分成两块:

  • 低层的网络进行特征抽取,将原始信息变成容易被后面任务使用的特征;

  • 输出层的网络进行具体任务的预测。输出层因为涉及到具体任务没办法在不同任务中复用,但是低层的网络是具有通用型的,可以应用到其他任务上。

    下图表示的是将预训练模型的前 L-1 层的参数复制到微调模型,而微调模型的输出层参数随机初始化。在训练过程中,通过设置很小的学习率,从而达到微调的目的。

  • 样例 2

BERT 模型是 Google AI 研究院提出的一种预训练模型,通过预训练 + 微调的方式于多个 NLP 下游任务达到当时最先进水平,如实体识别、文本匹配、阅读理解等。与样例 1 一样,BERT 模型微调时,将预训练好的模型参数复制到微调模型,而输出层参数随机初始化。

1.5 SFT 监督微调的主流方法

随着技术的发展,涌现出越来越多的大语言模型,且模型参数越来越多,比如 GPT3 已经达到 1750 亿的参数量,传统的监督微调方法已经不再能适用现阶段的大语言模型。为了解决微调参数量太多的问题,同时也要保证微调效果,急需研发出参数高效的微调方法(Parameter Efficient Fine Tuning, PEFT)。目前,已经涌现出不少参数高效的微调方法,其中主流的方法包括:

  • LoRA
  • P-tuning v2
  • Freeze

2. LoRA 微调方法

2.1 LoRA 微调方法的基本概念

LoRA(Low-Rank Adaptation of Large Language Models),直译为大语言模型的低阶自适应。LoRA 的基本原理是冻结预训练好的模型权重参数,在冻结原模型参数的情况下,通过往模型中加入额外的网络层,并只训练这些新增的网络层参数。由于这些新增参数数量较少,这样不仅 finetune 的成本显著下降,还能获得和全模型参数参与微调类似的效果。

随着大语言模型的发展,模型的参数量越来越大,比如 GPT-3 参数量已经高达 1750 亿,因此,微调所有模型参数变得不可行。LoRA 微调方法由微软提出,通过只微调新增参数的方式,大大减少了下游任务的可训练参数数量。

2.2 LoRA 微调方法的基本原理

神经网络的每一层都包含矩阵的乘法。这些层中的权重矩阵通常具有满秩。当适应特定任务时,预训练语言模型具有低的 “内在维度”,将它们随机投影到更小的子空间时,它们仍然可以有效地学习。

在大语言模型微调的过程中,LoRA 冻结了预先训练好的模型权重,并将可训练的秩的分解矩阵注入到 Transformer 体系结构的每一层。例如,对于预训练的权重矩阵W0​,可以让其更新受到用低秩分解表示后者的约束:

W 0 ​ + △ W = W 0 ​ + B A W0​+△W=W0​+BA W0​+W=W0​+BA

其中:

W 0 ​ ∈ R d × k , B ∈ R d × r , A ∈ R r × k W0​∈Rd×k,B∈Rd×r,A∈Rr×k W0​Rd×k,BRd×r,ARr×k

而且,秩r≪min(d,k),
此时,修正后的正向传播计算公式就变成:

h = W 0 ​ x + △ W x = W 0 ​ x + B A x h=W0​x+△Wx=W0​x+BAx h=W0​x+Wx=W0​x+BAx

在模型微调时,W0​被冻结,不接受梯度更新,只微调参数AB。与所有参数参与模型微调相比,此时该步骤模型微调的参数量由d×k变成d×r+r×k,而r≪min(d,k),因此微调参数量大量减少了。

如下图所示,LoRA 微调时,对A使用随机高斯初始化,对B使用零初始化,因此ΔW=BA在训练开始时为零。

对 Transformer 的每一层结构都采用 LoRA 微调的方式,最终可以使得模型微调参数量大大减少。当部署到生产环境中时,只需要计算和存储W=W0​+BA,并像往常一样执行推理。与其它方法相比,没有额外的延迟,因为不需要附加更多的层。

在 Transformer 体系结构中,自注意力机制模块中有四个权重矩阵 (Wq​Wk​Wv​Wo​), MLP 模块中有两个权重矩阵。LoRA 在下游任务微调时,只调整自注意力机制模块的权重,并冻结 MLP 模块。所以对于大型 Transformer,使用 LoRA 可减少高达 2/3 的显存(VRAM)使用量。比如在 GPT-3 175B 上,使用 LoRA 可以将训练期间的 VRAM 消耗从 1.2TB 减少到 350GB。

2.3 LoRA 微调方法的主要优势

  1. 预训练模型参数可以被共享,用于为不同的任务构建许多小的 LoRA 模块。冻结共享模型,并通过替换矩阵 A 和 B 可以有效地切换任务,从而显著降低存储需求和多个任务切换的成本。

  2. 当使用自适应优化器时,由于不需要计算梯度以及保存太多模型参数,LoRA 使得微调效果更好,并将微调的硬件门槛降低了 3 倍。

  3. 低秩分解采用线性设计的方式使得在部署时能够将可训练的参数矩阵与冻结的参数矩阵合并,与完全微调的方法相比,不引入推理延迟。

  4. LoRA 与其它多种微调方法不冲突,可以与其它微调方法相结合,比如下节实训将要介绍的前缀调优方法等。

3. P-tuning v2 微调方法

3.1 P-tuning v2 微调方法的相关技术

传统的微调方法需要微调整个预训练语言模型,对于大语言模型的微调需要大量的资源和时间,急需更加高效的微调方法。理解 P-tuning v2 微调方法,首先需要了解 prefix-tuning 微调方法和 P-tuning v1 微调方法。

3.1.1 Prefix-tuning 微调方法

Prefix-tuning 微调方法在模型中加入 prefix,即连续的特定任务向量,微调时只优化这一小段参数。对于条件生成任务,如下图所示,其输入是文本x,输出是序列y

在上图中,z=[x;y]xy的拼接,Xidx​Yidx​表示序列的索引,hi​∈Rd表示每个时刻i下的激活值,hi​=[hi​(1);...;hi​(n)]表示当前时刻所有层输出向量的拼接,hi​(j)是时刻i的第j层 Transformer 的输出,于是自回归语言模型计算每一时刻的输出hi​即:

h i ​ = L M ϕ ​ ( z i ​ , h < i ​ ) hi​=LMϕ​(zi​,h<i​) hi=L(zi,h<i)

hi​的最后一层用来计算下一个词的分布:

p ϕ ​ ( z i + 1 ​ ∣ h ≤ i ​ ) = s o f t m a x ( W ϕ ​ h i ​ ( n ) ) pϕ​(zi+1​∣h≤i​)=softmax(Wϕ​hi​(n)) (zi+1​hi)=softmax(Wϕhi(n))

其中ϕ是语言模型的参数。在自回归语言模型前添加 prefix 后,z=[PREFIX;x;y]或者z=[PREFIX;x;PREFIX;y]Pidx​表示 prefix 的索引,|Pidx​|表示 prefix 的长度。Prefix-tuning 通过初始化可训练矩阵Pθ​(维度为∣Pidx​×dim(hi​)∣) 来存储 prefix 参数:

KaTeX parse error: Expected '}', got 'EOF' at end of input: …<i​),otherwise​

训练对象与 Fine-tuning 相同,但语言模型的参数ϕ固定,仅 prefix 参数θ是可训练的参数。因此hi​是可训练的Pθ​的函数。

3.1.2 P-tuning v1 微调方法

P-tuning v1 微调方法是将 Prompt 加入到微调过程中,只对 Prompt 部分的参数进行训练,而语言模型的参数固定不变。如下图所示:

P-tuning v1 设计一个自动的生成连续 prompt 的方法来提升模型的微调效果。由上图,P-tuning v1 的模版可以用下面公式表示:

h 0 ​ , . . . , h i ​ , e ( x ) , h i + 1 ​ , . . . , h m ​ , e ( y ) {h0​,...,hi​,e(x),hi+1​,...,hm​,e(y)} h0​,...,hi,e(x),hi+1​,...,hm,e(y)

其中h代表 P-tuning v1 的连续 prompt 表征,e代表一个预训练的语言模型,x代表数据的原始输入,y代表数据的标签。在面对下游任务微调是,通过优化h的参数来进行模型微调:

h 0 : m ​ = a r g h m i n ​ L ( M ( x , y ) ) h^0:m​=arghmin​L(M(x,y)) h0:m=arghminL(M(x,y))

3.1.3 存在不足

P-tuning v1 微调方法缺少普遍性。实验表明,当模型规模超过 100 亿个参数时,P-tuning v1 可以与全参数微调方法相媲美,但对于那些较小的模型,P-tuning v1 方法和全参数微调方法的表现有很大差异,效果很差。同时,P-tuning v1 缺少跨任务的通用性,在序列标注任务中的有效性没有得到验证。序列标注需要预测一连串的标签,而且大都是无实际意义的标签,对于 P-tuning v1 微调方法极具挑战。此外,当模型层数很深时,微调时模型的稳定性难以保证。模型层数越深,第一层输入的 prompt 对后面的影响难以预估。

3.2 P-tuning v2 微调方法的原理

P-tuning v2 微调方法是 P-tuning v1 微调方法的改进版,同时借鉴了 prefix-tuning 微调的方法。如下图所示:

与 P-tuning v1 微调方法相比,P-tuning v2 微调方法采用了 prefix-tuning 的做法,在输入前面的每一层都加入可微调的参数。在 prefix 部分,每一层的 transformer 的 embedding 输入都需要被微调,而 P-tuning v1 只在第一层进行微调。同时,对于 prefix 部分,每一层 transformer 的输入不是从上一层输出,而是随机初始化的 embedding 作为输入。

此外,P-Tuning v2 还包括以下改进:

  • 移除 Reparamerization 加速训练方式;
  • 采用多任务学习优化:基于多任务数据集的 Prompt 进行预训练,然后再适配的下游任务。
  • 舍弃词汇 Mapping 的 Verbalizer 的使用,重新利用 [CLS] 和字符标签,跟传统微调方法一样利用 cls 或者 token 的输出做自然语言理解,以增强通用性,可以适配到序列标注任务。

3.3 P-tuning v2 微调方法优点

P-tuning v2 微调方法解决了 P-tuning v1 方法的缺陷,是一种参数高效的大语言模型微调方法。

  • P-tuning v2 微调方法仅精调 0.1% 参数量(固定 LM 参数),在各个参数规模语言模型上,均取得和 Fine-tuning 相比肩的性能,解决了 P-tuning v1 在参数量不够多的模型中微调效果很差的问题。如下图所示(横坐标表示模型参数量,纵坐标表示微调效果):

  • 将 Prompt tuning 技术首次拓展至序列标注等复杂的 NLU 任务上,而 P-tuning v1 在此任务上无法运作。

4. Freeze 监督微调方法

4.1 Freeze 微调方法的概念

Freeze 方法,即参数冻结,对原始模型部分参数进行冻结操作,仅训练部分参数,以达到在单卡或不进行 TP 或 PP 操作,就可以对大模型进行训练。在语言模型模型微调中,Freeze 微调方法仅微调 Transformer 后几层的全连接层参数,而冻结其它所有参数。

4.2 Freeze 微调方法的原理

Freeze 微调方法为什么只微调 Transformer 后几层的全连接层参数呢?下面对其原因进行展开讲述。

Transformer 模型主要由自注意力层和全连接层(FF 层)构成。对于 Transformer 的每一层结构,自注意力层的参数量为4⋅d2,即WQWQWQWQ ∈Rd×d;FF 层的参数量为8⋅d2,即W1​∈Rd×4d,W2​∈Rd×4d。因此 FF 层占据了模型的32​的参数,具有重要的研究价值。Transformer 的全连接层网络结构图如下图所示:

Transformer 的 FF 层可以视为一个 key-value memory,其中每一层的 key 用于捕获输入序列的特征,value 可以基于 key 捕获的特征,给出下一个 token 的词表分布。Transformer 每一层的 FF 层是由多个 key-value 组合而成,然后结合残差连接对每层结果细化,最终产生模型的预测结果。FF 层的公式可以表示为:

F F ( x ) = f ( x ⋅ K T ) ⋅ V FF(x)=f(x⋅KT)⋅V FF(x)=f(xKT)V

其中K,V∈Rdm​×d是可训练的参数矩阵,f是非线性激活函数,如 ReLU。

此外,实验表明,Transformer 的浅层倾向于提取出浅层特征,深层倾向于提取语义特征,如下图所示。层数越深提取的语义特征所占的比例越重。

对于各类不同的 NLP 任务,浅层特征往往是具有 “共性”,而主要区别在于各自深层次的语义特征。因此,通过仅微调 Transformer 后几层的全连接层参数,在保证参数高效微调的前提下,可以最大程度的发挥大语言模型的微调作用。

4.3 Freeze 微调方法的优势

  • 大量减少了大语言模型的微调参数,是一种参数高效的微调方法;
  • 由于只需微调高层特征,加快了模型的收敛,节约了微调的时间;
  • 最大程度地保留了大语言模型预训练所学习到的语言的 “共性”,可解释性较强。

5.关键知识点总结

  1. SFT监督微调时监督微调时,学习率通常会设置得很小

常见误区:1.监督微调需要大量的训练时间和数据 2.监督微调将复制源模型的所有参数至目标模型 3.监督微调只需要几十条监督数据即可

  1. 监督微调常见任务:1.用中文预训练BERT模型完成中文实体识别任务 2.训练语言模型GPT3 3.UIE模型在垂直领域的数据集上微调

常见误区:在ImageNet上的预训练的模型再来训练目标检测任务 (则不是)

  1. 目前,主流的SFT监督方法包括:LoRA、P-tuning v2、Freeze

  2. LoRA微调方法预训练的模型参数不参与微调,LoRA微调方法一般会在各层新增参数,LoRA微调方法的核心思想是利用高阶矩阵秩的分解来减少微调参数量

  3. LoRA微调方法的优势:减少大语言预训练模型微调的参数量、节省成本、能取得与全模型微调类似的效果

  4. LoRA微调方法不会 对Transformer的每个权重矩阵采用秩分解。

  5. P-tuning v2微调方法是在P-tuning v1的基础上引入了prefix-tuning的思想

常见误区:1.P-tuning v1微调方法能微调实体识别的任务、2.P-tuning v1微调方法在效果上可以媲美全参数微调的方式 3.P-tuning v2微调方法在自然语言理解任务上表现不佳

  1. P-tuning v2微调方法原理方面:1.P-tuning v2微调方法在transformer的每一层都加入了prefix、2.P-tuning v2微调方法采用了多任务学习、3.P-tuning v2微调方法prefix部分的参数不是由上一层的prefix输出来输入

常见误区:P-tuning v2微调方法微调的参数对象是每一层离散表示的prefix

  1. P-tuning v2微调方法解决了P-tuning v1微调方法中序列标注任务不佳、普遍性很差等问题。

  2. Freeze微调优点:1.Freeze微调方法是一种参数高效的微调方法 2.大语言模型的后几层网络主要提取的是语义特征,前几层主要提取的是文本的表层特征 3.Transformer的全连接层参数量多于自注意力层参数量

refix输出来输入

常见误区:P-tuning v2微调方法微调的参数对象是每一层离散表示的prefix

  1. P-tuning v2微调方法解决了P-tuning v1微调方法中序列标注任务不佳、普遍性很差等问题。

  2. Freeze微调优点:1.Freeze微调方法是一种参数高效的微调方法 2.大语言模型的后几层网络主要提取的是语义特征,前几层主要提取的是文本的表层特征 3.Transformer的全连接层参数量多于自注意力层参数量

在这里插入图片描述

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

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

相关文章

听GPT 讲K8s源代码--pkg(六)

pkg/kubelet/cm 目录是 Kubernetes 源代码中的一个目录&#xff0c;包含了 kubelet 组件中的 ConfigMap 相关代码。 在 Kubernetes 中&#xff0c;ConfigMap 是一种用于存储非机密数据的 API 对象类型&#xff0c;它可以用来存储配置信息、环境变量、命令行参数等等。 kubelet …

Twisted Circuit

题目描述 输入格式 The input consists of four lines, each line containing a single digit 0 or 1. 输出格式 Output a single digit, 0 or 1. 题意翻译 读入四个整数 00 或者 11&#xff0c;作为如图所示的电路图的输入。请输出按照电路图运算后的结果。 感谢PC_DOS …

时序预测 | MATLAB实现Hamilton滤波AR时间序列预测

时序预测 | MATLAB实现Hamilton滤波AR时间序列预测 目录 时序预测 | MATLAB实现Hamilton滤波AR时间序列预测预测效果基本介绍程序设计参考资料预测效果 基本介绍 预测在很大程度上取决于适合周期的模型和所采用的预测方法,就像它们依赖于过滤器提取的周期一样。标准 Hodrick-P…

Python教程(4)——Python开发工具PyCharm的下载与安装

PyCharm是一种专业的Python集成开发环境&#xff08;IDE&#xff09;&#xff0c;由JetBrains公司开发和维护。它提供了丰富的功能和工具&#xff0c;帮助开发人员更高效地编写、调试和测试Python代码。如果是一些大型Python项目强烈推荐用这个来开发。今天我们来介绍一下PyCha…

nginx系列第八篇:Ubuntu下验证nginx各请求处理阶段

Nginx处理请求的过程一共划分为11个阶段&#xff0c;按照执行顺序依次是 post-read、server-rewrite、find-config、rewrite、post-rewrite、preaccess、access、post-access、try-files、content 以及 log。 准备工作&#xff1a;host文件加入测试域名 sudo vi /etc/hosts 加入…

C语言--程序环境和预处理

翻译环境 C语言的代码是文本信息&#xff0c;对于计算机来说无法直接理解&#xff0c;需要通过翻译环境进行翻译成二进制信息&#xff1b; 我们在写代码的时候&#xff0c;一般都会写在一个源文件中&#xff0c;这时候我们就使用我们的编译器(VS)将其转换为机器代码&#xff0…

Android应用启动全流程分析(源码深度剖析)

作者&#xff1a;努比亚技术团队 源码来源&#xff1a;努比亚技术团队 1.前言 从用户手指点击桌面上的应用图标到屏幕上显示出应用主Activity界面而完成应用启动&#xff0c;快的话往往都不需要一秒钟&#xff0c;但是这整个过程却是十分复杂的&#xff0c;其中涉及了Android系…

TortoiseGit 入门指南13:拣选

对于多分支的代码库&#xff0c;将代码从一个分支转移到另一个分支是常见需求。 这时分两种情况。一种情况是&#xff0c;你需要另一个分支的所有代码变动&#xff0c;那么就采用 合并&#xff08;merge&#xff09;。另一种情况是&#xff0c;你只需要部分代码变动&#xff0…

[JVM] 2. 类加载子系统(1)-- 内存结构、类加载子系统概述

一、内存结构 类加载子系统的职责是&#xff1a;加载class文件到内存中。 完整的内存结构如下&#xff1a; 二、类加载过程 类加载过程总体分为Loading&#xff08;加载&#xff09;、Linking&#xff08;链接&#xff09;、Initialization&#xff08;初始化&#xff09;三…

Mars3d采用ellipsoid球实现模拟地球旋转效果

1.Mars3d采用ellipsoid球实现模拟地球旋转效果 2.开始自选装之后&#xff0c;模型一直闪烁 http://mars3d.cn/editor-vue.html?idgraphic/entity/ellipsoid 3.相关代码&#xff1a; import * as mars3d from "mars3d"export let map // mars3d.Map三维地图对象 …

深入浅出如何通过API瞬间搭建亿万商品外贸代购系统PHP系统

什么是淘宝代购 淘宝代购是近年兴起的一种购物模式&#xff0c;是帮国外客户购买中国商品。主要是通过万邦 科技的外贸代购系统&#xff0c;把淘宝、天猫等电商平台的全站商品通过API 接入到你的网站 上&#xff0c;瞬间就可以架设一个有数亿产品的大型网上商城&#xff0c;而…

2023年测试之路,从功能测试进阶测试开发工程师,突破内卷...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 测试开发工程师到…

Redis可视化工具(Redis Desktop Manager)

redis是我们平时开发工作中经常用到的非关系型数据库&#xff0c;常用于做数据缓存&#xff0c;分布式锁等。 为了更方便的使用redi&#xff0c;这里给大家推荐一款可视化工具&#xff1a;Redis Desktop Manager。 1.下载与安装 直接到gihub下载&#xff0c;地址 Release 0.…

uni-app的H5版本下载跨域问题

前端能正常访问图片&#xff0c;但无法下载 因为路径不经过业务代码&#xff0c;所以需要在nginx配置跨域 代码&#xff1a; add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods GET, POST, OPTIONS; add_header Access-Control-Allow-H…

基于simulink的DPLL仿真笔记

该笔记主要用于本人思路整理与记录 本设计运用的是电荷泵一阶环路滤波器&#xff0c;二阶三阶则在此基础上举一反三&#xff0c;以后如有机会会慢慢补全 文章目录 一.仿真模型PS&#xff08;题外话&#xff09; 二.仿真结果三.环路滤波器分析1. 环路滤波器对比LPF2. 环路滤波器…

Shikra:新一代多模态大语言模型,理解指向,说出坐标

“ Shikra&#xff1a;解锁多模态语言模型参考对话的魔法” Shikra和用户的对话案例 在人类的日常交流中&#xff0c;经常会关注场景中的不同区域或物体&#xff0c;双方都可以通过说话并指向这些区域来进行高效的信息交换。我们将这种对话模式称为参考对话&#xff08;Referen…

uniapp自定义头部,计算状态栏和导航栏高度超简单三步

效果图 1.pages.json 页面给要自定义头部的页面加入一行代码 "navigationStyle":"custom" {"path": "pages/index/index","style": {"navigationBarTitleText": "","navigationStyle":"…

Gin+Gorm练手小项目bubble清单企业级结构剖析

概述 本项目来源于Qimi老师的小清单项目——基于gingorm开发的练手小项目&#xff0c;通过该项目可初识go web开发该有的姿势。笔者对代码有些许修改&#xff0c;以下是项目成功运行的截图&#xff0c;主要功能有添加&#xff0c;删除&#xff0c;确认&#xff0c;查看待办事项…

有哪些记事本app可以用来整理个人笔记?

我总是在思考一个问题&#xff0c;为什么现在越来越多的人选择使用记事本app&#xff1f;它们相比传统笔记本&#xff0c;又有什么吸引人的地方呢&#xff1f;这其实并不难理解。因为&#xff0c;记事本app不仅可以让我们及时记录重要信息&#xff0c;还能对这些信息进行系统、…

Django实现接口自动化平台(九)环境envs序列化器及视图【持续更新中】

相关文章&#xff1a; Django实现接口自动化平台&#xff08;八&#xff09;测试报告reports序列化器及视图【持续更新中】_做测试的喵酱的博客-CSDN博客 本章是项目的一个分解&#xff0c;查看本章内容时&#xff0c;要结合整体项目代码来看&#xff1a; python django vue …