(EMNLP-2023)预训练语言模型的稀疏低秩自适应

server/2025/1/15 15:24:14/

预训练语言模型的稀疏低秩自适应

paper是清华大学发表在EMNLP 2023的工作

paper title:Sparse Low-rank Adaptation of Pre-trained Language Models

Code:https://github.com/tsinghuac3i/sora

Abstract

以参数高效的方式对预训练的大型语言模型进行微调因其有效性和效率而受到广泛研究。 流行的低秩自适应 (LoRA) 方法提供了一种值得注意的方法,假设自适应过程本质上是低维的。尽管 LoRA 表现出了令人称赞的性能,但它是以固定且不可改变的内在秩来实现的,这可能并不总是理想的选择。认识到需要更灵活的自适应,我们将 LoRA 方法扩展到一种创新方法,我们称之为稀疏低秩自适应 (SoRA),该方法可以在自适应过程中动态调整内在秩。我们通过在训练阶段加入使用近端梯度法优化的门单元来实现这一点,在门的稀疏性下控制秩的基数。在随后的推理阶段,我们消除与清零秩相对应的参数块,以将每个 SoRA 模块简化为简洁但秩最优的 LoRA。我们的方法通过以更高的秩初始化 LoRA 来增强其表示能力,同时通过稀疏方式更新有效地控制暂时增加的参数数量。我们进一步为 SoRA 引入了稀疏化调度程序,旨在检查非零参数数量对模型记忆和泛化的影响。我们的实验结果表明,即使保留 70% 的参数和 70% 的训练时间,SoRA 也能胜过其他基线。

1 Introduction

以参数高效 (He et al, 2022; Ding et al, 2023; Hu et al, 2023) 的方式调整大规模预训练语言模型 (Devlin et al, 2019; Brown et al, 2020; He et al, 2020; Bommasani et al, 2021; Han et al, 2021; Touvron et al, 2023) 在研究界越来越受到关注。该范式的方法通常保持底层模型的大部分参数不变,要么在模型中插入额外的可训练参数(Houlsby 等人,2019;Li 和 Liang,2021),要么指定少量参数(Zaken 等人,2021;Liu 等人,2021;Su 等人,2023)可训练,要么将适应过程重新参数化为更有效的形式(Hu 等人,2021;Qin 等人,2021)。它们已被证实在各种模型和任务中都是有效的,通常产生与全参数微调相当甚至更好的结果。

参数高效微调的发展潜力在经过广泛的性能验证后变得显而易见。这些方法提供了调整基础模型以适应任何数据的机会,从而允许针对特定任务和个性化用户特征定制语言模型。由于优化参数的轻量级特性,它们可以无缝插入模型中,从而实现有针对性的增强。在这些方法中,低秩自适应(LORA(Hu et al,2021))被认为是目前最有效的方法之一。它假设模型参数在自适应后的变化是“内在低维的”,并通过优化从低秩分解获得的矩阵来执行自适应。LoRA 避免了插入额外神经模块导致的前向传播延迟,同时表现出稳定的性能。 虽然有效,但内在秩(通常作为超参数)的设置仍不清楚。直观地说,更大的秩带来更大的优化空间,并创造了处理更具挑战性的任务的能力。然而,在实践中,最佳内在排名会根据主干模型和任务等多种因素而变化。

考虑到在大规模模型(例如具有 1750 亿个参数的 GPT-3(Brown 等人,2020 年)和具有 7 亿至 650 亿个参数的 LLaMA(Touvron 等人,2023 年))上搜索超参数的巨大计算成本,开发一种基于自适应秩的方法是一种自然的方法。现有的一些工作试图探索这个方向(Valipour 等人,2022 年;Zhang 等人,2023 年),但它们大多是启发式的或引入了额外的成本。在本文中,我们提出了 SoRA,一种简单、有效且自动化的自适应参数高效微调方法。我们引入了一个在 L1 正则化下具有近端梯度下降更新的门控模块来控制更新矩阵的稀疏性。训练后,门控向量的零条目记录下投影矩阵的列和上投影矩阵的行,可以简单地将其删除并以更参数高效的方式存储。与其他自适应方法相比,近端梯度法具有明确的数学含义,并且不必涉及其他计算和启发式方法。例如,AdaLoRA(Zhang 等人,2023 年)引入了一个额外的正则化器,以确保下部和上部投影矩阵严格遵守奇异值分解 (SVD) 的定义,每个矩阵都是正交的。然而,由于梯度计算,这个正则化项会产生大量的计算开销。相反,我们消除了这一要求,而是通过控制中间对角矩阵来选择性地过滤低秩分量。我们在第 3 节中详细比较了 SoRA 和相关方法。

SoRA 的机制还允许我们暂时控制稀疏性,并研究非零可训练参数的数量与记忆和泛化能力之间的关系。我们提出了一个稀疏化调度程序,并发现模型自适应过程表现出强大的“压缩能力”,即使一小部分参数(低于 LoRA 秩 1)也可以保持相当好的性能。进行了大量的实验来证明我们方法的有效性。特别是,我们的模型可以在广泛的下游任务上以更少的参数和缩短 30% 的训练时间持续优于参数高效的基线。

2 A Closer Look to Adaptive Rank

相关工作。在介绍我们的方法之前,我们首先简要回顾一下参数高效调优和我们的骨干低秩自适应 (LoRA)。 参数高效调优是一组仅优化一小部分参数并保持主模型不受影响以进行自适应的方法。 一些参数高效方法会将额外的神经模块或参数插入主干模型,例如适配器 (Houlsby 等人,2019)、前缀和提示调优 (Li and Liang,2021;Lester 等人,2021)。另一类此类方法试图将特定参数指定为可训练或可修剪 (Guo 等人,2021;Zhao 等人,2020;Zaken 等人,2021)。研究人员推导出一系列参数高效方法的变体来提高有效性或效率 (Karimi Mahabadi et al, 2021; Hu et al, 2022; Sung et al, 2022; He et al, 2022)。最近,参数高效微调的应用扩展到多模态和指令调整场景 (Gao et al, 2023; Dettmers et al, 2023)。在本文中,我们更多地关注 LoRA (Hu et al, 2021),它使用低秩矩阵来近似权重的变化。

在 LoRA 中,预训练权重(记为 W 0 ∈ R p × q \mathbf{W}_0 \in \mathbb{R}^{p \times q} W0Rp×q)是冻结的,而可训练的 LoRA 模块是每个权重矩阵变化 Δ \boldsymbol{\Delta} Δ 的低秩分解矩阵 W d ∈ R r × q \mathbf{W}_d \in \mathbb{R}^{r \times q} WdRr×q W u ∈ R p × r \mathbf{W}_u \in \mathbb{R}^{p \times r} WuRp×r,其中 Δ = W u W d ∈ R p × q \boldsymbol{\Delta}=\mathbf{W}_u \mathbf{W}_d \in \mathbb{R}^{p \times q} Δ=WuWdRp×q。这样,当前层的输出 h \mathbf{h} h 可以表示为:

y ← W 0 x + W u W d x \mathbf{y} \leftarrow \mathbf{W}_0 \mathbf{x}+\mathbf{W}_u \mathbf{W}_d \mathbf{x} yW0x+WuWdx

其中 r ≪ min ⁡ { p , q } r \ll \min \{p, q\} rmin{p,q} 是一个控制低秩矩阵大小和可训练参数数量的超参数,称为“内在维度”。在本节中,我们主要关注最后一项,记为 z ← W u W d x \mathbf{z} \leftarrow \mathbf{W}_u \mathbf{W}_d \mathbf{x} zWuWdx

LoRA 上的自适应排序。尽管在可处理性和效率方面取得了很大进步,但 LoRA 仍然受到其在选择最佳排序 r 方面的不灵活性的限制。与可以在训练过程中自适应地在线调整的连续超参数(例如学习率和权重衰减)不同,LoRA 排序 r 采用离散值 - 其变化将直接改变模型结构。排序的最佳选择可能因不同的主干模型和下游任务而异。保守地选择较大的排序 r 会浪费训练时间和计算资源,而逐渐将 r 设置为很小可能会降低模型性能并导致从头开始重新训练。这些限制凸显了使用自适应排序选择插件升级 LoRA 的重要性。

近年来,提出了多种方法以实现 LoRA 秩的灵活调整。例如,与固定秩不同,Valipour 等人(Valipour et al., 2022)提出了 DyLoRA,其中在一系列秩选择上引入了一个预定义的离散分布 p B ( ⋅ ) p_B(\cdot) pB()。这种方法与嵌套 Dropout(Rippel et al., 2014)相关但有所不同,可被视为一种对不同秩的 LoRA 模块的混合模型进行优化的方式。

然而,直接且确定性地调整 LoRA 秩似乎是一种更具吸引力的方法。为设计这种方法,我们首先从矩阵的秩与奇异值分解(SVD)之间的关系中获得了重要的启示。将 LoRA 中可调整的增量权重矩阵记为 Δ : = W u W d \Delta:=\mathbf{W}_u \mathbf{W}_d Δ:=WuWd,我们可以将其 SVD 表示为:

Δ p × q = U p × p Σ p × q V q × q ⊤ \boldsymbol{\Delta}_{p \times q} = \mathbf{U}_{p \times p} \boldsymbol{\Sigma}_{p \times q} \mathbf{V}_{q \times q}^{\top} Δp×q=Up×pΣp×qVq×q

其中 U \mathbf{U} U V \mathbf{V} V 分别是正交矩阵, Σ \boldsymbol{\Sigma} Σ 是一个(矩形)对角矩阵,其对角元素为 Δ \Delta Δ 的奇异值: σ ( Δ ) = { σ 1 ≥ σ 2 ≥ ⋯ ≥ σ min ⁡ { p , q } ≥ 0 } \sigma(\Delta) = \left\{\sigma_1 \geq \sigma_2 \geq \cdots \geq \sigma_{\min \{p, q\}} \geq 0\right\} σ(Δ)={σ1σ2σmin{p,q}0}。为了方便表示,我们将 Σ \Sigma Σ 的对角线元素重塑为一个列向量:

g : = ( σ 1 , σ 2 , ⋯ , σ min ⁡ { p , q } ) ⊤ \mathbf{g} := \left(\sigma_1, \sigma_2, \cdots, \sigma_{\min \{p, q\}}\right)^{\top} g:=(σ1,σ2,,σmin{p,q})

d = min ⁡ { p , q } d=\min \{p, q\} d=min{p,q},我们可以将 LoRA 的前向传播公式重新表述为:

z ← Δ x = U ⋅ , 1 : d ( g ⊙ V ⋅ , 1 : d ⊤ x ) \mathbf{z} \leftarrow \mathbf{\Delta} \mathbf{x}=\mathbf{U}_{\cdot, 1: d}\left(\mathbf{g} \odot \mathbf{V}_{\cdot, 1: d}^{\top} \mathbf{x}\right) zΔx=U,1:d(gV,1:dx)

其中, ⊙ \odot 表示逐元素点积(Hadamard 乘积)。注意, rank ⁡ ( Δ ) = ∥ g ∥ 0 \operatorname{rank}(\boldsymbol{\Delta})=\|\mathbf{g}\|_0 rank(Δ)=g0,即 g \mathbf{g} g ℓ 0 \ell_0 0 范数。因此,调整 LoRA 的秩足以控制向量 g \mathbf{g} g 的稀疏性。

Zhang 等人基于这一 SVD 方法提出了 AdaLoRA 方法(Zhang et al., 2023)。在 AdaLoRA 中,向量 g \mathbf{g} g 中的元素经过调整,使得非零项的数量小于预定义的预算 b b b。具体来说,他们仅保留重要性评分(由权重-梯度乘积启发性地构造的一种新度量)排名前 b b b 的条目。由于负值 g i \mathbf{g}_i gi 可以通过翻转 u i \mathbf{u}_i ui v i \mathbf{v}_i vi 的符号转换为正值,因此合理地去掉了 g \mathbf{g} g 条目非负性的限制。

此外,他们将约束优化问题转化为其无约束版本,通过将正交性条件 U ⊤ U = I p \mathbf{U}^{\top} \mathbf{U}=\mathbf{I}_p UU=Ip V ⊤ V = I q \mathbf{V}^{\top} \mathbf{V}=\mathbf{I}_q VV=Iq 替换为以下正则化项:

R ( U , V ) = ∥ U ⊤ U − I p ∥ F 2 + ∥ V ⊤ V − I q ∥ F 2 R(\mathbf{U}, \mathbf{V})=\left\|\mathbf{U}^{\top} \mathbf{U}-\mathbf{I}_p\right\|_F^2+\left\|\mathbf{V}^{\top} \mathbf{V}-\mathbf{I}_q\right\|_F^2 R(U,V)= UUIp F2+ VVIq F2

尽管实验证明了其有效性,但 AdaLoRA 中仍然存在两个问题,需要重新思考方法论并等待进一步改进。首先,AdaLoRA 中的稀疏性选择标准基于他们新提出的重要性得分,该得分依赖于权重梯度乘积的移动平均值。尽管它在实证研究中是有效的,但该标准在很大程度上是启发式的,缺乏理论动机。其次,重要性得分的移动平均运算和正交正则化的梯度 (5) 都会增加额外的计算成本。与具有上述局限性的 AdaLoRA 相比,我们的方法 SoRA 是一种改进,具有高度简化的更新规则,并以稀疏正则化和近端梯度方法的理论为后盾。SoRA 的详细方法将在下一节中详细阐述。

3 Our Approach

我们的方法的核心思想是稀疏低秩自适应 (SoRA),即使用近端梯度法训练的稀疏门控单元在训练过程中动态调整固有秩。SoRA 采用之前介绍的低秩分解框架,因为它的有效性和参数效率已得到广泛验证。

3.1 Sparse Low-rank Adaptation


模块结构

在构建 SoRA 模块时,我们首先根据实际需求或研究考虑预定义一个最大可接受秩 r max r_{\text{max}} rmax。然后,每个 SoRA 模块会从 LoRA 继承两个矩阵 W d ∈ R r max × q \mathbf{W}_d \in \mathbb{R}^{r_{\text{max}} \times q} WdRrmax×q W u ∈ R p × r max \mathbf{W}_u \in \mathbb{R}^{p \times r_{\text{max}}} WuRp×rmax,分别用于降维投影和升维投影。最大秩 r max r_{\text{max}} rmax 被设定为相对较大的值,但我们将在接下来的段落中展示如何通过稀疏化机制高效控制它。实际上,这通过在投影矩阵之间引入一个门控单元 g ∈ R r max g \in \mathbb{R}^{r_{\text{max}}} gRrmax 实现,其公式类似于 SVD 的形式。SoRA 模块的前向传播过程如下:

h ← 降维投影 W d x h ′ ⇐ 门控操作 g ⊙ h z ← 升维投影 W u h ′ \begin{aligned} & \mathbf{h} \stackrel{\text{降维投影}}{\leftarrow} \mathbf{W}_d \mathbf{x} \\ & \mathbf{h}^{\prime} \stackrel{\text{门控操作}}{\Leftarrow} \mathbf{g} \odot \mathbf{h} \\ & \mathbf{z} \stackrel{\text{升维投影}}{\leftarrow} \mathbf{W}_u \mathbf{h}^{\prime} \end{aligned} h降维投影Wdxh门控操作ghz升维投影Wuh

更简洁地表示为:

z ← W u ( g ⊙ ( W d x ) ) \mathbf{z} \leftarrow \mathbf{W}_u\left(\mathbf{g} \odot\left(\mathbf{W}_d \mathbf{x}\right)\right) zWu(g(Wdx))


优化

我们使用与 LoRA 相同的随机梯度方法优化降维投影和升维投影矩阵,而门控单元 g \mathbf{g} g 采用一种促进稀疏性的不同优化方式:

g t + 1 ← T η t ⋅ λ ( g t − η t ∇ g L 0 ( Δ t ) ) \mathbf{g}_{t+1} \leftarrow \mathcal{T}_{\eta_t \cdot \lambda}\left(\mathbf{g}_t-\eta_t \nabla_{\mathbf{g}} \mathcal{L}_0\left(\boldsymbol{\Delta}_t\right)\right) gt+1Tηtλ(gtηtgL0(Δt))

其中:

  • L 0 ( ⋅ ) \mathcal{L}_0(\cdot) L0()语言模型的原始损失函数,
  • Δ \Delta Δ 表示完整的可调参数(包括门控单元),
  • η t > 0 \eta_t > 0 ηt>0 是第 t t t 次迭代的步长,
  • λ > 0 \lambda > 0 λ>0 是促进稀疏性的正则化强度超参数。

此外,表达式中的 T η t ⋅ λ ( ⋅ ) \mathcal{T}_{\eta_t \cdot \lambda}(\cdot) Tηtλ() 表示以下软阈值函数的逐元素广播:

T ξ ( x ) : = { x − ξ , x > ξ 0 , − ξ ≤ x ≤ ξ x + ξ , x < − ξ \mathcal{T}_{\xi}(x):=\left\{ \begin{array}{l} x-\xi, \quad x > \xi \\ 0, \quad -\xi \leq x \leq \xi \\ x+\xi, \quad x < -\xi \end{array} \right. Tξ(x):= xξ,x>ξ0,ξxξx+ξ,x<ξ

其中 ξ = η t ⋅ λ \xi = \eta_t \cdot \lambda ξ=ηtλ 是阈值。在实际操作中,(10) 中的真实梯度 ∇ g L 0 \nabla_{\mathbf{g}} \mathcal{L}_0 gL0 被其小批量随机近似所代替。

后剪枝 (Post-pruning)

当训练完成后,我们对 SoRA 权重进行进一步剪枝,以删除为零的秩并将模块还原为 LoRA 形式。具体来说,对于第 k k k 个 SoRA 模块,令:

I ( k ) = { i ∈ [ 1 : r max ⁡ ] ∣ g i ( k ) = 0 } \mathcal{I}^{(k)}=\left\{i \in\left[1: r_{\max }\right] \mid \mathbf{g}_i^{(k)}=0\right\} I(k)={i[1:rmax]gi(k)=0}

表示第 k k k 个门控向量 g ( k ) \mathbf{g}^{(k)} g(k) 中零条目的索引。我们对第 k k k 个模块进行以下处理:

  1. 删除降维投影矩阵 W d ( k ) \mathbf{W}_d^{(k)} Wd(k) 中索引为 I ( k ) \mathcal{I}^{(k)} I(k) 的行,得到 W ~ d ( k ) \widetilde{\mathbf{W}}_d^{(k)} W d(k)
  2. 删除升维投影矩阵 W u ( k ) \mathbf{W}_u^{(k)} Wu(k) 中索引为 I ( k ) \mathcal{I}^{(k)} I(k) 的列,得到 W ~ u ( k ) \widetilde{\mathbf{W}}_u^{(k)} W u(k)
  3. 删除门控向量 g ( k ) \mathbf{g}^{(k)} g(k) 中索引为 I ( k ) \mathcal{I}^{(k)} I(k) 的条目,得到 g ~ ( k ) \widetilde{\mathbf{g}}^{(k)} g (k)

通过上述步骤,在推理阶段,第 k k k 个 SoRA 模块将作为一个通常的 LoRA 模块运行,其秩为 r max − ∣ I ( k ) ∣ r_{\text{max}} - \left|\mathcal{I}^{(k)}\right| rmax I(k) 。此时,降维投影矩阵为 W ~ d ( k ) \widetilde{\mathbf{W}}_d^{(k)} W d(k),升维投影矩阵为 W ~ u ( k ) ⋅ diag ⁡ ( g ~ ( k ) ) \widetilde{\mathbf{W}}_u^{(k)} \cdot \operatorname{diag}\left(\widetilde{\mathbf{g}}^{(k)}\right) W u(k)diag(g (k))

3.2 Interpretation and Comparison


理论解释

更新规则 (10) 实际上是 ℓ 1 \ell_1 1 损失的 近端梯度方法 的应用(Chambolle et al., 1998; Beck and Teboulle, 2009)。这一点可以通过将 (10) 等价地重写为以下公式直接得出:

g t + 1 ← arg ⁡ min ⁡ g η t ⋅ λ ∥ g ∥ 1 + 1 2 ∥ g − ( g t − η t ∇ L 0 ( g t ) ) ∥ 2 2 \begin{aligned} \mathbf{g}_{t+1} & \leftarrow \underset{\mathbf{g}}{\arg \min } \eta_t \cdot \lambda\|\mathbf{g}\|_1 \\ & +\frac{1}{2}\left\|\mathbf{g}-\left(\mathbf{g}_t-\eta_t \nabla \mathcal{L}_0\left(\mathbf{g}_t\right)\right)\right\|_2^2 \end{aligned} gt+1gargminηtλg1+21g(gtηtL0(gt))22

上式 (13) 正是以下 ℓ 1 \ell_1 1 正则化损失函数 的近端梯度更新:

L ( Δ ) : = L 0 ( Δ ) + λ ∑ k = 1 K ∥ g ( k ) ∥ 1 \mathcal{L}(\boldsymbol{\Delta}):=\mathcal{L}_0(\boldsymbol{\Delta})+\lambda \sum_{k=1}^K\left\|\mathbf{g}^{(k)}\right\|_1 L(Δ):=L0(Δ)+λk=1K g(k) 1

其中, g ( k ) \mathbf{g}^{(k)} g(k) 表示第 k k k 个 SoRA 模块的门控向量。该促进稀疏性的策略可以追溯到 LASSO 回归估计器(Tibshirani, 1996)和 压缩感知(Candes et al., 2006),并已被许多深度学习领域的工作所采用(Wen et al., 2016; Scardapane et al., 2017)。

与 AdaLoRA 进行比较。我们的方法 SoRA 受到 SVD 分解的启发,与之前的 AdaLoRA (Zhang et al, 2023) 有以下不同之处。首先,我们不应用 AdaLoRA 中使用的正交性正则化 (5)。原因是,对于秩选择目的,稀疏门 g 就足够了。 坚持 SVD 的原始要求可能会导致额外的计算开销。其次,AdaLoRA 中的移动平均重要性得分可作为相应条目归零时损失变化的近似值,这被视为参数“敏感性”的启发式测量。然而,模型对某个参数的时间敏感性并不意味着应该保留该参数,因为没有严格的理论来做到这一点。相比之下,我们基于软阈值操作 (10) 的秩选择以更清晰的形式进行,并且由近端梯度迭代理论充分证明。如本节前面所述,SoRA 模块的更新规则通过最小化正则化损失目标 (14),完全遵循插值-复杂性权衡的第一原则。 除了形式简单性和理论清晰性之外,SoRA 还以更少的参数和更短的时钟时间实现了卓越的实验性能,这将在第 4 节中介绍。

图1

图 1:稀疏低秩自适应 (SoRA) 的示意图。 训练阶段:门控单元 g g g 控制 W d \mathbf{W}_d Wd W u \mathbf{W}_u Wu 的稀疏性。 推理阶段:根据 g g g 中零条目的索引,将 W d \mathbf{W}_d Wd W u \mathbf{W}_u Wu 中的零向量移除。


http://www.ppmy.cn/server/158591.html

相关文章

(三)c#中const、static、readonly的区别

在 C# 中&#xff0c;const、static 和 readonly 都是用来定义不可变的值&#xff0c;但它们有一些关键的区别。让我们详细比较一下这三者的用途和特点&#xff1a; 1. const&#xff08;常量&#xff09; 编译时常量&#xff1a;const 用于声明常量&#xff0c;其值必须在编…

基于YOLOv8的高空无人机小目标检测系统(python+pyside6界面+系统源码+可训练的数据集+也完成的训练模型

目标检测系统【环境搭建过程】&#xff08;GPU版本&#xff09;-CSDN博客 摘要 本文提出了一种基于YOLOv8算法的高空无人机小目标检测系统&#xff0c;利用VisDrone数据集中的7765张图片&#xff08;6903张训练集&#xff0c;862张验证集&#xff09;进行模型训练&#xff0c;…

1.14寒假作业

web&#xff1a;nssctf mydoor 打开环境&#xff0c;只有一片空白&#xff0c;源代码也什么都没有&#xff0c;题目的分类是涉及到php伪协议&#xff0c;之前写过一题也是为协议&#xff0c;当时是用base64的方式将源码给加密显现出来了&#xff0c;看一下当时得到命令试试看&…

vue3项目大屏适配方案(scale)及vue-tv-focusable库使用

一. 适配方案代码(scale) 公共代码 export const useAdjustScale () > {// * 指向最外层容器const pageRef ref();// * 默认缩放值const scale {width: 1,height: 1,};// * 需保持的比例&#xff08;默认1.77778&#xff09; const designWidth 1920 const designHeig…

python检测gitlab中某个标签在一个月内添加和移除了多少次

可以通过 Python 脚本和 GitLab API 检测一个标签在一个月内被添加和移除的次数。以下是实现的步骤和示例代码&#xff1a; 步骤 获取 GitLab API 访问令牌&#xff1a;在 GitLab 中生成一个 Personal Access Token。设置时间范围&#xff1a;确定一个月的时间范围。调用 Git…

Pyinstaller打包部署在Win2008上的Bug排查之路

1.前言 python项目的部署工作基本是属于算法的最后阶段&#xff0c;同样也是最容易出现问题的阶段&#xff0c;毕竟IDE中的运行甚至debug都是可以直接给出问题&#xff0c;再加上开发机器的版本较新&#xff0c;也很少会出现各种各样的dll系统问题。win和linux部署相比&#x…

【maptalks】加载SVG和GIF

加载SVG和GIF 一、加载SVG方法一&#xff1a;直接载入SVG文件&#xff0c;类似载入图片方法二&#xff1a;载入SVG路径 二、加载GIFVUEmaptalks实现GIF可拖拽点VUEmaptalks实现GIF跟随线条动画 一、加载SVG 方法一&#xff1a;直接载入SVG文件&#xff0c;类似载入图片 缺点&…

Redisson和可重入锁初认

文章目录 Redisson 简介Redisson 的主要特点Redisson 的核心模块Redisson的优势使用示例Maven 引入依赖配置 Redisson 客户端分布式锁使用示例 Redisson 使用场景总结 可重入锁关键特性为什么需要可重入锁可重入锁的实现方式可重入锁的实现原理可重入锁的优缺点优点缺点 可重入…