LLM之长度外推(一)| 基于位置编码的长度外推研究综述

图片

论文:Length Extrapolation of Transformers: A Survey from the Perspective of Position Encoding
地址:https://arxiv.org/abs/2312.17044

        Transformer自诞生以来就席卷了NLP领域,因为它具有对序列中复杂依赖关系进行建模的优越能力。尽管基于Transformer的预训练语言模型(PLM)在几乎所有NLP任务中都取得了巨大成功,但它们都有预设的长度限制,因此很难将这种成功扩展到见过数据以外的更长的序列,即长度外推问题。为了增强Transformer的长度外推,人们提出了大量的可外推的位置编码。

一、介绍

        在有限的学习资源下,人类可以通过理解它们的组成部分和结构来理解潜在无限长度的话语。在NLP中,这种能力称为模型的长度外推,即在较短的上下文窗口上进行训练,在较长的上下文窗口上进行推理。尽管神经网络在各种任务上取得了惊人的进展,但长度外推对它们来说仍然是一个重大挑战。Transformer被用来环节这一问题。

       然而,Transformer的优势容量是以相对于输入序列长度的二次计算和内存复杂度为代价的,这导致了基于Transformer的模型的预定义上下文长度限制,通常是512或1024个token。因此,利用Transformer处理长序列是极其困难的。此外,人们普遍认为,用更长的上下文窗口对现有模型进行微调要么是有害的,要么是昂贵的。更糟糕的是,由于高质量长文本数据的稀缺和不可负担的二次成本,通过直接在长序列上训练Transformer来扩展上下文窗口是不可行的。因此,长度外推似乎是减少训练开销、同时放松Transformer上下文长度限制的最合适的方法。

       最近,基于Transformer的LLMs,如Llama和GPT-4,在工业界和研究界引起了极大的兴趣。但即使这些能力很强的LLMs仍然对上下文长度有强制限制,并且在长度推断上失败,这极大地阻碍了它们的广泛采用。尽管GPT-4的上下文窗口达到了惊人的32k,但实际上,这个上下文长度远远不够。一方面,随着LLM能力的增长,我们对它们的期望也在增长。另一方面,现有有效利用LLM的技术也对上下文窗口的长度提出了更高的要求。

二、预备知识

        Transformer最初是作为一个编码器-解码器架构引入的,其中编码器和解码器都由N个相同的层组成。每个编码器层由两个子层组成,self-attention层和位置全连接前馈网络。而对于每个解码器层,还有第三个子层执行交叉注意力,即对编码器输出的注意力。我们在这里给出了编码器层的形式化描述。给定输入矩阵X\in \mathbb{R}^{n\times d}n个维度为d的嵌入序列,f(X)=:Z的编码器层f: \mathbb{R}^{n\times d}\rightarrow \mathbb{R}^{n\times d}定义为:

图片

       其中Q=XW_q,K=XW_k,V=XW_v是所谓的query、key和value,其中W_q,W_k,W_v\in \mathbb{R}^{d\times d}是投影矩阵。首先,兼容性分数C被计算为具有缩放因子的query和key之间的点积。然后,利用逐行softmax函数将兼容性分数转换为权重,值的加权和正是注意力子层的输出。全连接的前馈网络由两个线性变换组成,中间由ReLU激活。为了提供可伸缩性,在每个子层周围利用残差连接,然后进行层归一化。

       为了使模型能够共同关注来自不同表示子空间不同位置的信息,通常使用多头注意力。简而言之,h个头意味着用不同的投影矩阵W_{q}^{(h)}W_{k}^{(h)},W_{v}^{(h)}\in \mathbb{R}^{d\times d_h}计算自注意力h次,其中d=hd_h。然后将输出矩阵A^{(h)}\in \mathbb{R}^{n\times d_h}沿着第二个维度连接起来以获得最终的A。从上面的描述中,不难看出整个编码器层是置换等价或顺序不变的,考虑到注意力子层和前馈子层都是置换等价的。即,给定任意置换矩阵P_\pi \in \mathbb{R}^{n\times n},得到P_\pi f(X)=f(P_\pi X)。这种置换等价性质与人类语言的顺序性质不一致,可以通过向Transformer中注入位置信息来减少。

三、位置编码实现长度外推

       直观地说,长度外推与长度和位置有很强的相关性。另一方面,在介绍Transformer时,研究人员也提出了正弦位置嵌入,并声称它可以外推到训练之外的更长的序列。这一说法背后的想法,即只需改变位置表示方法就可以实现长度外推,已得到广泛支持和证明。因此,开发更好的位置编码方法已经成为增强Transformer长度外推的主要途径。

       有各种各样的方法将位置信息集成到Transformer中,统称为位置编码(PEs)。表1给出了不同外推PE的特征。我们根据PE是绝对的还是相对的来划分表格。使用绝对位置编码(APE),每个位置都被映射到一个唯一的表示,而相对位置编码(RPE)基于两个token之间的相对距离来表示位置。

图片

3.1 绝对位置编码

       考虑到Transformer的置换等价性质,提出了将位置信息融入其中的APE。具体来说,对于位置为pos的token,位置嵌入定义为:

图片

       其中2i,2i+1是位置嵌入的维数,d表示模型维数。然后,将每个位置嵌入与对应的token嵌入相加,并将之和输入到Transformer中,从而将查询q_i与键k_j之间的兼容性得分形式化为:

图片

        这是许多不同PE的基础和重点。此外,比较了所提出的正弦APE和完全可学习的位置嵌入的性能,其中位置嵌入是在训练期间随机初始化和更新的。尽管具有类似的性能,但研究人员声称正弦位置嵌入可能能够推断出比所看到的更长的序列。然而,研究人员随后发现,正弦APE很难外推。因此,人们提出了各种APEs和RPEs,以增强正弦位置编码,从而增强Transformer的外推。

       研究人员推测优异的外推性能来自PE的平移不变性,即即使输入发生移动,函数也不会改变其输出的特性。为了结合正弦APE中移位不变性的优点,他们只是对每个序列和训练期间的每次迭代,通过从离散均匀分布U(0,K)中提取的随机偏移量k移动每个位置索引,其中K\in N是最大偏移量。也就是说,他们只是用P_{pos+k}代替了P_{pos},这阻止了模型使用绝对位置,而是鼓励使用相对位置。

       遵循类似的想法,进一步利用连续信号来增强正弦APE。除了用相同的随机偏移量移动APE的每个位置索引(为全局偏移)外,还引入了局部偏移和全局缩放。这三种增广方法的形式如下:

图片

       其中pos\in \mathbb{R}^n为位置索引向量,X\in \mathbb{R}^{n\times d}Y\in \mathbb{R}^{​{n}'\times d}分别为源序列和目标序列的嵌入向量。全局位移将每个嵌入转换为一个从\Delta \sim U(-\Delta _{max},\Delta _{max})的全局随机位移序列。

       除了这些基于正弦APE的相对简单的方法外,还有一些APE采取了完全不同的理论途径。例如将每个词嵌入扩展为自变量上的连续函数,即位置,以便词表示随着位置的增加而平滑移动。通过数学上合理的推导,将单词w_jpos位置上的一般复数嵌入f(j,pos)定义为:

图片

        注意,振幅向量r=[r_{j,1},...,r_{j,d}],频率矢量权值\omega =[\omega _{j,1},...,\omega _{j,d}]和初始相位向量\theta =[\theta _{j,1},...,\theta _{j,d}]都是可训练的参数。振幅只取决于单词wj和向量[e^{i(\omega _j,1pos+\theta _j,1)},...,e^{i(\omega _j,dpos+\theta _j,d)}]可以被视为“purely”的位置嵌入。

       研究人员也试图直接捕捉位置表示之间的依赖关系或动态关系。引入了一个动态系统来对这些位置表示进行建模,其特征可以表示为:

图片

       正弦APE作为Transformer的第一个PE,对以后的PE有重要影响。然而,发现它的外推性很差。为了增强Transformer的外推性,研究人员要么利用随机移位将移位不变性纳入正弦APE中,要么生成随位置平滑变化的位置嵌入。这些方法确实比正弦APE具有更好的外推性能,但只能勉强赶上RPEs的外推能力。

3.2 相对位置编码

       已经提出了许多新的RPE加强Transformer的外推。在我们深入讨论之前,我们重新制定兼容性得分,如下所示,以帮助阐明RPEs的视角:

图片

       其中p(j-i)是编码j-i相对位置信息的术语。RPEs倾向于直接修改注意力机制来融合相对位置信息。因此,这种位置信息通常在每一层都重复出现,而不是像APE那样只在第一层之前出现。此外,这种修改独立于值向量,使它们不与位置信息纠缠。这些差异如图1所示。

图片

       研究人员在此公式的基础上引入了RPE的思想。具体来说,他们将公式具体化为:

图片

       其中p_r\in \mathbb{R}^d是可训练的相对位置嵌入,r=clip(j-i,r_{min},r_{max})表示关系位置关系。通过在确定的范围内裁剪相对位置,减少了要学习的位置嵌入数量,增强了长度外推。同样,在计算V值时,他们还引入了p_r^v\in \mathbb{R}^d,将其添加到词嵌入中。再此基础上,研究人员又增加了一个项来同时建模键嵌入和相对位置嵌入的交互:

图片

       然而,一些研究人员采取了完全相反的方法,将其简化为极其简单的形式。利用可学习的标量来表示相对位置信息:

图片

       为了使Transformer能够有效利用真实的token距离信息,研究人员提出了一种更复杂的方法:

图片

       其中ReLU被用于确保兼容性分数的非负性,\hat{\mathbb{R}}_{i,j}是通过可学习的sigmoid函数从加权相对距离\mathbb{R}_{i,j}映射而来的重新缩放系数:

图片

       同样为了利用真实距离信息来增强上下文建模,另一种更简单的方法来表示相对位置信息:

图片

       其中标量m是训练前固定的特定头部斜率。值得注意的是,该方法不需要额外的可学习参数,因此效率更高,也有助于更好地推断不在场证明。另一种方法建议按照以下方式计算兼容性:

图片

       类似地,研究人员认为位置嵌入和词嵌入对不同的概念进行编码,因此应该对不同的信息应用不同的投影。因此,他们建议用:

图片

        其中p_ip_j为正弦位置嵌入。他们发现他们的方法结合T5偏差可以有效地降低预训练成本,并提高GLUE基准上的性能。

        同样受到正弦APE的启发,研究人员提出通过正弦嵌入将键和查询相乘,而不是将它们相加。他们将相容性分数重新表述为:

图片

        这种方法称为旋转位置嵌入(RoPE),因为直观地说,它根据位置索引旋转键和值嵌入,该索引形式化为f_{\{q,k\}}{(x_i,i)}=R_{\Theta ,i^{\omega_{\{q,k\}^{x_i}}}}^{d}。值得注意的是,尽管这是一个绝对的旋转过程,但兼容性分数以及注意力机制仅依赖于查询与键之间的相对距离,这有助于长度外推。

       尽管之前提出了大量的PEs,但在最近的LLMs中,只有ALiBi和RoPE被广泛采用。因此,LLM时代提出的PEs大多衍生自这两种方法,试图使ALiBi更具表现力或使RoPE更具外推性。

       研究人员意识到正弦APE的过拟合问题,提出通过将正弦APE简化为一种新的RPE Sandwich来克服它。具体来说,他们删除了交叉项,但保留了两个位置嵌入的内积:

图片

       值得注意的是,在这种形式化中,p_i^Tp_j成为与ALiBi具有相同衰减与距离模式的时间偏差项。此外,由于这里的位置嵌入只需要与自己交互,作者将它们的维度作为超参数,以进一步改善推断。

       FIRE采用与T5 bias完全相同的形式,将位置信息与Transformer集成:

图片

       其中,它们的偏差b(i,j)使用可学习的连续函数f_\theta :\mathbb{R}\rightarrow \mathbb{R},例如MLP。为了避免输入在函数训练域之外时的泛化问题,提出了通过查询位置索引对距离进行归一化的渐进式插值方法。请注意,在因果注意中,相对距离总是在[0,1]之间有界,对于任何序列长度,这将使推理域与训练域对齐,从而带来更好的长度泛化。

       由于RoPE在流行的LLM中被广泛使用,也有人提出一些变体来改进它。研究人员首先定义了两个特定距离上的token之间的注意力得分期望和进一步的注意力分辨率,作为Transformer编码位置能力的指标。他们将绳子外推性能较差的原因归结为注意期望的剧烈振荡,并提出引入平衡项来惩罚不稳定维度的振荡,保持稳定维度的分布。他们的方法可以简化为:

图片

四、LLMs时代的长度外推

       LLM彻底改变了NLP领域,并对长度外推提出了很大的要求,以更好地理解长文档,利用更多的演示,处理多轮对话,增强智能体的长期记忆等。因此,在LLM的长度推断方面付出了大量努力,导致了许多新的和新颖的PE的出现。除了这些方法,也有一些研究尝试分析LLM的外推,并试图揭示PE对长度外推的影响。

4.1 位置插值

       尽管有大量具有更好外推性的PE,但RoPE由于其优越的分布性能,在最近的LLM中得到了最广泛的采用。因此,人们提出了许多方法来增强现有的用RoPE进行预训练的LLM的外推,其中最流行的是位置插值方法。基于将LLM外推到更长的序列的简单想法,引入了RoPE的位置插值,这是将线性缩放降低该位置索引的比例,以便在预训练期间最大位置索引匹配之前的长度限制。形式上,这个方法将RoPE f替换为{f}',定义如下:

图片

       其中L是预训练期间的长度限制,{L}'是推理时较长的上下文窗口。注意,这里的比例是\kappa ={L}'/L,将位置n转换为位置n/\kappa。该方法将绝对位置索引从[0,{L}')减少到[0,{L})以匹配原始范围,这也减少了从{L}'L的最大相对距离。因此,位置插值通过对齐位置索引的范围和扩展前后的相对距离,减轻了由于上下文窗口扩展对注意力分数计算的影响。

       然而,从神经切线核(Neural Tangent Kernel, NTK)理论的角度来看,简单地线性插值RoPE的傅里叶空间会造成高频信息的丢失,会阻止模型区分附近的位置。为了解决这个问题,提出了NTK-Aware Scaling RoPE算法,通过修改基底来代替RoPE的尺度:

图片

       其中b是原始基底,κ仍然是比例,两者都可以看作是超参数。这里的核心思想是减少高频的缩放,增加低频的缩放,以减少高频的信息损失。由于NTK-Aware插值不直接对傅里叶特征进行缩放,因此所有位置都是可以区分的。此外,该方法不需要对上下文窗口进行任何微调。

       已经提出了几种改进NTK-Aware插值的变体。Dynamic-NTK插值在预训练的上下文窗口中为token使用精确的位置值,以防止性能下降,并随着当前序列长度的增加动态增加缩放比,以适应预训练的上下文窗口以外的位置:

图片

       其中{L}'是当前序列的长度,每一步都会增加。

       无论是缩放位置索引还是修改基地,所有token都变得彼此更接近,这将损害LLM区分相近token的位置顺序的能力。结合他们对RoPE的波长的观察,存在一些波长比预训练的上下文窗口长的维度,NTK-by-parts插值的作者建议完全不插值较高的频率维度,而总是插值较低的频率维度。除了这种方法之外,在Softmax之前引入一个兼容性分数的温度t可以持续降低困惑度,他们将其称为注意力缩放。具体来说:

图片

        请注意,该方法与上面的插值方法是正交的,这促使作者将YaRN作为注意力扩展和NTK-by-parts插值的组合,以进一步提高性能,并在微调和非微调场景中超越所有基于NTK-Aware插值的方法。

       研究人员在此基础上提出了一种更简单的方法。不难看出,在训练过程中,模型已经看到了全范围的高频分量,而低频分量则没有。这种不平衡使得模型对低频进行外推是一项特别困难的任务。因此,他们建议使用apply给出的截断基:

图片

       其中ρ是一个相对较小的固定值,ab是选定的截断值。这样,模型将通过选择适当的截断值,在微调期间使用的上下文长度中体验所有基值,并被认为在推理过程中进行更好的推断。

4.2 随机化位置编码

       对于没有clipping机制的APE和RPE,长度外推意味着位置表示超出了训练期间观察到的位置表示,导致分布外位置表示,从而性能下降。为了解决这个问题,最直观的方法之一是使模型在训练期间观察所有可能的位置表示,这正是随机PEs背后的核心思想。

       作为这一想法的具体化,研究人员提出模拟更长的序列的位置,并随机选择一个有序子集来适应训练上下文窗口。具体来说,M的长度远大于训练和评估过程中的最大长度。对于每个训练步骤,长度为n的序列的随机位置是较大范围位置的升序子样本,该范围大小为n,且不包含重复。因此,通过充分的训练,可以确保模型遇到足够的唯一位置,并且在推理之前已经充分训练了从1到M的所有位置,从而在Etoken中的任何序列上实现一致的性能。

       基于相同的想法,PoSE也试图通过在固定的预训练上下文窗口内操纵位置索引来模拟更长的输入。然而,PoSE是将原始序列划分为几个块,并通过添加不同的skip偏差项来调整每个块的位置索引。这样,PoSE保持了每个块中的连续位置,这与预训练非常相似,同时允许模型适应更长的上下文窗口中的所有位置。

       本质上,随机PE只是通过在训练过程中引入随机位置,将预训练的上下文窗口与较长的推理长度解耦,从而提高了较长的上下文窗口中所有位置的暴露。

五、讨论

5.1 评估和基准

       在早期阶段,研究人员通过有意在具有长度限制的序列上训练模型并在稍长的序列上测试来评估长度外推。在此期间,训练和测试的长度限制都只有几十个token和样本,指标通常来自各种不同的下游任务,如机器翻译,文本分类和问答。然后,由于PLM已经被证明是通用的,并且其他NLP任务可以很容易地转换为语言建模,语言建模和困惑度成为测试和评估长度外推的标准做法。然而,人们越来越认识到,作为唯一的指标,复杂度不能说明下游任务的性能,而且非常不充分。

5.2 理论基础

       早期的方法大多是经验的,并声称通过下游性能进行外推。最近,有一种量化外推能力的趋势,如累积归一化梯度和注意力分辨率。对数衰减时间偏差模式被认为是成功的长度外推的秘密,而没有PE的仅解码器模型在小规模合成任务中有更好的长度外推。尽管取得了这些进展,但仍然需要建立一个坚实的理论基础,什么真正导致更好的长度外推仍然是一个开放的问题。

5.3 其他方法

       除了上述方法外,还有几种采取不同思维方式的方法来提高长度外推性能,如暂存器或思维链,Λ-shaped注意力掩码和streamingLLM。此外,长度外推还适用于更大的任务,即上下文窗口扩展或长上下文LLM。

六、总结

       本文对从Transformer诞生到LLM时代关于Transformer长度外推的研究工作进行了全面和有组织的概述,重点是外推PE和相关方法,包括位置插值和随机PE。

参考文献:

 [1] https://arxiv.org/abs/2312.17044

[2] 综述:利用位置编码实现长度外推

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

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

相关文章

001 Golang-channel-practice

最近在练习并发编程。加上最近也在用Golang写代码,所以记录一下练习的题目。 第一道题目是用10个协程打印100条信息,创建10个协程。每个协程都会有自己的编号。每个协程都会被打印10次。 package mainimport ("fmt""strconv" )func …

1-07基本数据类型

一、概述 C语言的基本数据类型(也叫内置数据类型)在日常编程中被频繁使用,本章我们主要简单地介绍下 C 语言的基本数据类型。 基本数据类型主要包括:整数类型,浮点数类型和字符类型,其中字符类型也可以看…

gradient_checkpointing

点评:本质是减少内存消耗的一种方式,以时间或者计算换内存 gradient_checkpointing(梯度检查点)是一种用于减少深度学习模型中内存消耗的技术。在训练深度神经网络时,反向传播算法需要在前向传播和反向传播之间存储中…

前端系列:正则表达式RegExp详解

文章目录 正则创建匹配方法元字符字符集合边界分组数量词汇匹配模式RegExp 方法特性 正则创建 字面量创建 const str asdf123sds3234 const regexp /\d/g const res str.match(regexp) console.log(res) //[123, 3234]构造函数 const str asdf123asad23121 const regexp n…

[②C++ Boost]: Boost库编译,arm交叉编译方法

前言 Boost是十分实用的C库,如果想在arm环境下使用,就需要自己下载源码编译,本篇博客就记录下Boost库的编译方法。 下载Boost源码 Boost源码的下载路径可以使用:https://sourceforge.net/projects/boost/files/boost/ 编译 …

408重要数据结构+算法汇总——C语言手搓版(全)

该套代码,大学期间跟着网课一遍一遍打下来的,408大概就这些了,别的杂七杂八其实还有很多,遗憾的是,一直没有整理和归纳。导致一遍遍地学一遍遍地忘记。大四就快毕业了,研也考了。这里做个整理,算…

JavaScript小案例

烟花 html <body><div id"box"></div><script src"./move.js"></script><script src"./fire.js"></script> </body>js代码 fire.js function Fire(){// 获取box盒子this.box document.que…

虚幻UE 材质-材质编辑器节点2

上一篇&#xff1a;虚幻UE 材质-材质编辑器节点 1 上一篇文章对材质编辑器的部分节点做了讲解和对比较常用的功能做了展示 这篇文章继续对上一篇的文章进行补充 文章目录 前言一、ReflectionVector反射向量二、Material Parameter Collection材质参数集三、TwoSideSign和Vertex…

使用 Process Explorer 和 Windbg 排查软件线程堵塞问题

目录 1、问题说明 2、线程堵塞的可能原因分析 3、使用Windbg和Process Explorer确定线程中发生了死循环 4、根据Windbg中显示的函数调用堆栈去查看源码&#xff0c;找到问题 4.1、在Windbg定位发生死循环的函数的方法 4.2、在Windbg中查看变量的值去辅助分析 4.3、是循环…

uniapp(vue2)+VoerkaI18n多语言

今天我学习了VoerkaI18n国际化插件&#xff0c;它是一个适用于Javascript/Vue/React/Solid/ReactNative的国际化全流程解决方案。VoerkaI18n可以帮助我们轻松地实现应用程序的多语言支持&#xff0c;使得应用程序可以适应不同的语言环境。 比较吸引我的是集成自动翻译,t(“中华…

基于net6的asp.net core webapi项目打包为docker镜像,并推送至私有镜像仓库harbor中

基于net6的asp.net core webapi项目打包为docker镜像&#xff0c;并推送至私有镜像仓库harbor中 0、环境说明1、打包步骤1.1 创建Asp.net core WebApi项目1.2 在Asp.net core WebApi项目根目录下创建Dockerfile文件1.3 在子系统Ubuntu20.04.4中通过docker build生成docker镜像1…

【angular教程240105】02绑定属性 绑定数据、条件判断、加载图片、【ngClass】 【ngStyle】、Angular管道

【angular】02绑定属性 绑定数据、条件判断、加载图片、【ngClass】 【ngStyle】、Angular管道 0 一些基础的概念 标记为可注入的服务 在Angular中&#xff0c;一个服务是一个通常提供特定功能的类&#xff0c;比如获取数据、日志记录或者业务逻辑等。标记为可注入的服务意味着…

PTA——查验身份证

一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下&#xff1a; 首先对前17位数字加权求和&#xff0c;权重分配为&#xff1a;{7&#xff0c;9&#xff0c;10&#xff0c;5&#xff0c;8&#xff0c;4&#xff0c;2&#xff0c;1&am…

判断一个数是NaN和Infinity的方法

1. isNaN()、 Number.isNaN()的区别 isNaN()只要不是数字都会返回true&#xff0c; Number.isNaN()只有NaN才 返回 true 所以&#xff0c;想严格检查一个值是否是 NaN&#xff0c;就选择 Number.isNaN() isNaN() isNaN() 函数会尝试将传入的值转换为数字&#xff0c;然后检查…

PCL 计算异面直线的距离

目录 一、算法原理二、代码实现三、结果展示四、相关链接本文由CSDN点云侠原创,PCL 计算异面直线的距离,爬虫自重。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 设置直线 A B AB A

在vue3上挂载方法,以及在页面中使用setup语法糖 该怎么使用原型(公共)上的方法

//新建的项目的main.js文件是这样的 //main.js 文件 //befor import { createApp } from vue; import App from ./App.vue;const app createApp(App); app.mount(#app);以下例子用于解释在vue3.0的main.js中挂载公共的方法&#xff08;foo&#xff09; //main.js 文件 //afte…

【JVM 基础】 Java 类加载机制

JVM 基础 - Java 类加载机制 类的生命周期类的加载: 查找并加载类的二进制数据连接验证: 确保被加载的类的正确性准备: 为类的静态变量分配内存&#xff0c;并将其初始化为默认值解析: 把类中的符号引用转换为直接引用 初始化使用卸载 类加载器&#xff0c; JVM类加载机制类加载…

nuxt 不解析HTML结构bug

记录一个本人Vue3迁移Nuxt3的报错 报错信息 [Vue warn]: Failed to resolve directive: top [nitro] [unhandledRejection] TypeError: Cannot read properties of undefined (reading ‘getSSRProps’) 原因是Vue3在迁移到nuxt3的时候有一个自定义指令没有搬过来&#xff0…

flutter 打包安卓apk 常用配置

打包之前需要先不配置不然会报错 Execution failed for task ‘:app:mergeReleaseResources’. APP目录下的build.gradleaaptOptions.cruncherEnabled falseaaptOptions.useNewCruncher false如图 配置targetSdkVersion 、minSdkVersion 在android/app/src目录下的build.…

自承载 Self-Host ASP.NET Web API 1 (C#)

本教程介绍如何在控制台应用程序中托管 Web API。 ASP.NET Web API不需要 IIS。 可以在自己的主机进程中自托管 Web API。 创建控制台应用程序项目 启动 Visual Studio&#xff0c;然后从“开始”页中选择“新建项目”。 或者&#xff0c;从“ 文件 ”菜单中选择“ 新建 ”&a…