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

飞桨首创 FlashMask :加速大模型灵活注意力掩码计算,长序列训练的利器

在 Transformer 类大模型训练任务中,注意力掩码(Attention Mask)一方面带来了大量的冗余计算,另一方面因其 O ( N 2 ) O(N^2) O(N2)巨大的存储占用导致难以实现长序列场景的高效训练(其中 N N N为序列长度)。虽然业界已有 FlashAttention 等针对特定注意力掩码的计算加速方法,但其支持的注意力掩码模式有限,难以满足大模型训练任务对灵活注意力掩码的需求。为了解决上述问题,飞桨独创 FlashMask 技术,提出了列式稀疏的注意力掩码表示方法,支持灵活多样的注意力掩码模式,使得存储复杂度从 O ( N 2 ) O(N^2) O(N2)降低至 O ( N ) O(N) O(N),并在此基础上实现了高效的算子 Kernel,极致加速大模型训练效率,尤其是长序列场景下的训练效率。

我们在NVIDIA A100 (80G) GPU上对 FlashMask 在大语言模型微调和对齐训练中的表现进行了评估,包括 SFT、LoRA、DPO 和 RM。与现有的 FlashAttention 稠密掩码方法相比,FlashMask 在端到端训练速度上实现了显著提升,速度提高幅度在 1.65 倍到 3.22 倍之间。此外,我们还评估了其 Kernel 层次上的性能。FlashMask 在理论最大浮点运算次数上达到了37.8%到62.3%,在 Kernel 每秒浮点运算次数(TFLOPs/s)方面,其性能超过 FlexAttention,提升幅度为 12.1% 到 60.7%。

arXiv 论文: https://arxiv.org/abs/2410.01359

PaddlePaddle 官方文档: https://www.paddlepaddle.org.cn/documentation/docs/en/develop/api/paddle/nn/functional/flashmask_attention_en.html

PaddleNLP 开源集成:https://github.com/PaddlePaddle/PaddleNLP/tree/develop/llm/docs/flashmask.md

星河社区快速体验:https://aistudio.baidu.com/projectdetail/8459413

一、大语言模型的挑战

随着人工智能技术的迅猛发展,以 Transformer 为代表的大模型在自然语言处理、计算机视觉和多模态应用中展现出了非凡的能力。在这些大模型中,注意力(Attention)机制是一个关键环节。为了在大模型训练任务中确定哪些 Query-Key token 之间需要进行有效的 Attention 计算,业界通常使用注意力掩码(Attention Mask)。然而,目前的注意力掩码通常采用二维稠密矩阵表示,这导致了一些问题。一方面,这种表示方法引入了大量冗余计算,因为许多无效 token 的 Attention 仍需计算;另一方面,这种掩码的空间复杂度为 O ( N 2 ) O(N^2) O(N2)(其中 N N N为序列长度),在长序列的训练场景中会造成巨大的存储压力,难以进行高效训练。为了解决这些问题,业界已经提出了一些方案,如 Memory Efficient Attention (MEA) [1] 和 FlashAttention [2]。然而,这些方案支持的注意力掩码类型较为有限。正如图 1 所示,FlashAttention 只能支持如纯因果掩码(Causal)、滑动窗口掩码(Sliding Window)、因果文档掩码(Causal Document Mask)和文档掩码(Document Mask)等几种固定形式的掩码。然而,实际训练任务中使用的注意力掩码形式往往丰富多变,当前技术难以满足大模型不同训练任务对注意力掩码灵活性的要求。
图1 常见的注意力掩码类型
图1 常见的注意力掩码类型

二、FlashMask 的创新:列式稀疏掩码表示方法与高效计算

1. 关键洞察

FlashMask 的核心发现是,在大模型常见的注意力掩码模式中,Query-Key token 的掩码模式具有一定的连续性。具体而言,对于每一个 Key token,无效注意力计算的 Query token 是相邻排列的。也就是说,在图 1 中二维掩码矩阵中,Query token 作用在每一列的 Key token 的灰色部分沿列方向连续分布。基于这一洞察,FlashMask 巧妙地将二维稠密掩码矩阵转换为一维的行索引区间,从而实现更为紧凑的表示形式,并显著降低了存储需求。我们可以公式化表示为:

M j = [ s t a r t j , e n d j ) , ∀ j ∈ { 1 , … , N } M_{j} = [start_j, end_j), \quad \forall j \in \{1, \ldots, N\} Mj=[startj,endj),j{1,,N}

其中 N N N为 Key 的序列长度, M j M_j Mj为二维的稠密掩码矩阵的第 j j j列, [ s t a r t j , e n d j ) [start_j, end_j) [startj,endj)为连续的行索引区间,表示 s t a r t j start_j startj e n d j − 1 end_{j} - 1 endj1的连续 Query token 是被 mask 掉,置为无效 Attention 计算。

2. 注意力掩码的列式稀疏掩码表示方法

为了高效处理因果和双向注意力场景中的复杂掩码模式,FlashMask 提出了一种新颖的列式稀疏表示方法。以对角线为区分,它使用四个一维向量来表示掩码:

  • 下三角起始行索引(Lower Triangular Start,简称 L T S LTS LTS
  • 下三角结束行索引(Lower Triangular End,简称 L T E LTE LTE
  • 上三角起始行索引(Upper Triangular Start,简称 U T S UTS UTS
  • 上三角结束行索引(Upper Triangular End,简称 U T E UTE UTE
    其中下三角被 mask 掉的行索引区间使用 [ 𝐿 𝑇 𝑆 , 𝐿 𝑇 𝐸 ) [𝐿𝑇𝑆, 𝐿𝑇𝐸) [LTS,LTE)表示,上三角被 mask 掉的行索引区间使用 [ 𝑈 𝑇 𝑆 , 𝑈 𝑇 𝐸 ) [𝑈𝑇𝑆, 𝑈𝑇𝐸) [UTS,UTE) 表示。 如图2所示,我们展示了16个Query token 和16个Key token 做 Attention 计算时较为复杂的二维稠密因果注意力的掩码矩阵,灰色单元格是 mask 区域。
    图2 较为复杂的二维稠密因果注意力的掩码矩阵示意图
    图2 较为复杂的二维稠密因果注意力的掩码矩阵示意图

可以通过 [ 𝐿 𝑇 𝑆 , 𝐿 𝑇 𝐸 ) [𝐿𝑇𝑆, 𝐿𝑇𝐸) [LTS,LTE)两个向量进行表达,如下所示:
在这里插入图片描述

以第 0 列为例,开始 mask 的行为 13,结束 mask 的行为 15(开区间),表示位置为 13 和 14 的 Query token 不与位置为 0 的 Key token 做有效 Attention 计算。

更多的例子参考图 3,FlashMask 使用列式稀疏掩码表示方法,表达了图 1 中所有的注意力掩码模式。其中 - 的空缺表示在不同的场景下有不同的默认值, L T S LTS LTS U T S UTS UTS中的默认值是 0,表示 mask 区域默认从第 0 行开始, L T E LTE LTE U T E UTE UTE中的默认值是 Query 的序列长度,表示 mask 区域默认结束于最后一行。
图3 使用 FlashMask 的列式稀疏掩码表示方法表示图1的注意力掩码模式
图3 使用 FlashMask 的列式稀疏掩码表示方法表示图1的注意力掩码模式

3. 扩展 FlashAttention 支持复杂掩码

FlashMask 将列式掩码表示方法集成到 FlashAttention-2 算法中,增强了其对注意力掩码的支持能力。在 FlashAttention Kernel 的分块计算基础上,FlashMask 利用上述的 L T S LTS LTS L T E LTE LTE U T S UTS UTS U T E UTE UTE 等掩码向量,来判断当前分块的掩码类型:

  • 完全掩码块:此类块的所有元素均被掩码,计算时可直接跳过。
  • 部分掩码块:此类块仅部分元素被掩码,因此需要对该块进行逐元素的掩码处理。
  • 未掩码块:此类块中的所有元素均未被掩码,可以简化计算过程,无需额外的掩码操作。
    通过这种分类处理,FlashMask 显著提升了计算效率:完全掩码块的计算被直接跳过,未掩码块的计算得到简化,仅对部分掩码块执行必要的掩码操作,如图4所示。
    图4 FlashMask 计算过程示意图图4 FlashMask 计算过程示意图

算法1详细描述了 FlashMask 扩展 FlashAttention-2 的前向计算过程,其中浅蓝色阴影部分表示 FlashMask 新增的计算步骤 [3]。
算法1 FlashMask 的前向计算伪代码
算法1 FlashMask 的前向计算伪代码

4. 效率提升与精度保证

FlashMask 充分利用了注意力掩码中的稀疏性,通过跳过完全掩码块的计算,减少了计算开销,同时不改变算法的精度。与使用稠密掩码矩阵的注意力计算保持比特级别的数值等效性,确保了精度无损。

三、FlashMask 的优势:速度与存储的双重提升

1. 端到端训练吞吐量提升

在 Llama-2 7B、13B、70B 等模型规模下,针对 SFT、LoRA、DPO、RM 四种下游训练场景和不同序列长度的实验表明,FlashMask 在各个模型规模和序列长度下均实现了端到端的加速和存储效率的提升。相比现有的基于稠密掩码矩阵的计算方法,FlashMask 实现了 1.65 倍至 3.22 倍的吞吐量提升,并支持更长的序列长度。
图5 在四个下游训练任务(SFT、LoRA、DPO 和 RM)中,3 个 Llama2 模型规模,在不同序列长度下的端到端训练吞吐量
图5 在四个下游训练任务(SFT、LoRA、DPO 和 RM)中,3 个 Llama2 模型规模,在不同序列长度下的端到端训练吞吐量
图6 在四个下游训练任务(SFT、LoRA、DPO 和 RM)中,3 个 Llama2 模型规模,不同序列长度下的端到端训练峰值显存消耗
图6 在四个下游训练任务(SFT、LoRA、DPO 和 RM)中,3 个 Llama2 模型规模,不同序列长度下的端到端训练峰值显存消耗
表2 在 Llama2 7B 模型上 FlashMask 对比 FlashAttention (Causal=True) 的显存消耗,单位(GB)
表2 在 Llama2 7B 模型上 FlashMask 对比 FlashAttention (Causal=True) 的显存消耗,单位(GB)

2. 端到端训练收敛验证

在 Llama 3.1 模型上的实验验证了 FlashMask 对收敛精度没有影响。作为一种精确的算法,通过控制计算过程的随机性(如 FlashAttention 反向 Query 梯度计算使用 atomicAdd 操作),FlashMask 可以与使用稠密掩码的 FlashAttention 在比特级别精确对齐。
图7 在四个下游训练任务(SFT、LoRA、DPO 和 RM)中,Llama3.1 8B 模型端到端训练 Loss 对比
图7 在四个下游训练任务(SFT、LoRA、DPO 和 RM)中,Llama3.1 8B 模型端到端训练 Loss 对比

3. 稀疏度与 Kernel 计算时延的线性关系

FlashMask 利用注意力掩码的块稀疏性,跳过完全掩码块的计算,将计算复杂度降低到 O ( ( 1 − ρ ) T r T c ) O((1 - ρ)T_rT_c) O((1ρ)TrTc),其中 ρ ρ ρ 表示块稀疏性。为了验证这一关系,FlashMask 进行了多组实验,测试了三种不同的掩码类型(因果文档掩码、共享问题掩码和文档掩码),并使用不同稀疏度的数据。实验结果(如图 5 所示)表明,Kernel 执行延迟与稀疏性之间呈线性关系,意味着随着稀疏性的增加,FlashMask 的计算速度进一步提升。
图8 不同块稀疏度下的 Kernel 计算时延
图8 不同块稀疏度下的 Kernel 计算时延

4. Kernel 性能对比

关注到近期 PyTorch 推出了 FlexAttention [4](使用编译器技术支持 Attention Mask),FlashMask 与之在 Kernel 级别进行了对比。在各种常见的注意力掩码模式下,FlashMask 展现了更高的计算效率。在 TFLOPs/s 指标上,FlashMask 比 FlexAttention 高出 12.1% 至 60.7%,在 A100 GPU 上实现了 37.8% 至 62.3% 的理论峰值计算性能。
 图9 在 A100-SXM 80G GPU 上的 Kernel 前向和反向速度对比。FlexAttention 使用 PyTorch 2.6.0.dev20240920+cu124
图9 在 A100-SXM 80G GPU 上的 Kernel 前向和反向速度对比。FlexAttention 使用 PyTorch 2.6.0.dev20240920+cu124

四、FlashMask 的应用:赋能大语言模型

FlashMask 的创新和优势为 Transformer 类大模型的注意力机制训练加速开辟了新的可能,可广泛应用于各种任务,并支持超长序列高效训练。

1. 可广泛应用于大语言模型的下游训练加速

FlashMask 可以应用于大语言模型的下游任务训练,例如 SFT、LoRA、DPO、RM 等。特别是在 DPO 和 RM 的训练中,其数据由问题和回答对组成,训练时多个答案可以共享一个问题,从而大幅减少对问题 token 的冗余计算。

2. 支持单向/双向混合注意力掩码模式训练

FlashMask 支持多种注意力模式,包括因果掩码(单向注意力)和文档掩码(双向注意力),因此能够灵活地应用于需要混合注意力的场景。例如:

  • 全局 + 滑动窗口掩码:这种掩码结合了全局注意力和滑动窗口注意力,既能捕捉全局上下文信息,又能关注局部细节。FlashMask 能高效处理这种混合掩码,提升模型性能。
  • 前缀语言模型:在生成文本时,前缀部分需要关注所有的 token,而其他部分使用因果掩码(如 T5 模型的预训练)。FlashMask 可以同时支持这两种注意力模式,提高前缀语言模型的训练和推理效率。

3. 支持多模态图文数据的混合多分辨率训练

在多模态数据处理中,不同模态的数据可能具有不同的分辨率。虽然文中未明确提及 FlashMask 在多模态和多分辨率训练中的应用,但 FlashMask 可以通过不同的注意力模式和掩码策略,有效处理这些具有不同分辨率的数据。针对长序列处理能力的优化,使得FlashMask能够帮助模型更好地学习不同模态数据之间的关联。例如,在图文匹配任务中,FlashMask 可以帮助模型更有效地对齐图像和文本中的关键信息。

FlashMask 的开源代码已在 PaddlePaddle 和 PaddleNLP 平台发布,支持超过千亿参数的模型以及超过 128K tokens 的上下文长度。我们相信,FlashMask 将成为推动大语言模型发展的重要力量,为算法研究人员提供更广阔的注意力掩码创新与研究空间。

结语

飞桨首创 FlashMask 技术,通过创新的列式稀疏掩码表示方法和高效的Kernel实现方式,解决了传统注意力掩码方法冗余计算和存储占用过高等难题,助力大模型训练加速,尤其是基于长文场景的训练加速。未来,飞桨将持续研发高效的大模型训练加速技术,不断推进大模型技术更新迭代。

参考文献

[1] Self-attention Does Not Need O(n^2) Memory. https://arxiv.org/abs/2112.05682

[2] FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning. https://arxiv.org/abs/2307.08691

[3] FlashMask: Efficient and Rich Mask Extension of FlashAttention. https://arxiv.org/abs/2410.01359

[4] FlexAttention: The Flexibility of PyTorch with the Performance of FlashAttention. https://pytorch.org/blog/flexattention/

相关文章:

飞桨首创 FlashMask :加速大模型灵活注意力掩码计算,长序列训练的利器

在 Transformer 类大模型训练任务中,注意力掩码(Attention Mask)一方面带来了大量的冗余计算,另一方面因其 O ( N 2 ) O(N^2) O(N2)巨大的存储占用导致难以实现长序列场景的高效训练(其中 N N N为序列长度)…...

【含文档+源码】基于SpringBoot+Vue的新型吃住玩一体化旅游管理系统的设计与实现

开题报告 本文旨在探讨新型吃住玩一体化旅游管理系统的设计与实现。该系统融合了用户注册与登录、旅游景点管理、旅游攻略发帖、特色旅游路线推荐、附近美食推荐以及酒店客房推荐与预定等多项功能,旨在为游客提供全方位、一体化的旅游服务体验。在系统设计中&#…...

【网络安全】揭示 Web 缓存污染与欺骗漏洞

未经许可,不得转载。 文章目录 前言污染与欺骗Web 缓存污染 DoS1、HTTP 头部超大 (HHO)2、HTTP 元字符 (HMC)3、HTTP 方法覆盖攻击 (HMO)4、未键入端口5、重定向 DoS6、未键入头部7、Host 头部大小写规范化8、路径规范化9、无效头部 CP-DoS10、HTTP 请求拆分Web 缓存污染与有害…...

PHP如何防止防止源代码的暴露

在PHP开发中,防止源代码暴露是确保应用程序安全性的重要一环。源代码暴露可能会让攻击者发现敏感信息,如数据库凭据、业务逻辑漏洞等,从而进行恶意攻击。以下是一些防止PHP源代码暴露的方法: 禁用PHP短标签: 在php.in…...

C++智能指针的实现

本篇文章详细探讨下如何使用裸指针实现智能指针。 补充内容 由于本篇文章主要是探讨怎么实现三种智能指针,但是在编码过程中,博主可能会使用些有些同学不了解的特性,为了保证大家思绪不被打断,博主先把这些小特性介绍出来,大家选择性参考。 1、什么是RAII? RAII(Reso…...

硅谷(12)菜单管理

菜单管理模块 11.1 模块初始界面 11.1.1 API&&type API: import request from /utils/request import type { PermisstionResponseData, MenuParams } from ./type //枚举地址 enum API {//获取全部菜单与按钮的标识数据ALLPERMISSTION_URL /admin/acl/permission…...

定子调压调速系统

定子调压调速系统是一种用于控制三相交流绕线电机的调速系统,它通过改变电动机定子电压和转子电阻来实现对电机转速的控制。以下是关于定子调压调速系统的详细介绍: 工作原理 定子电压调控:在1~3档时,系统通过控制定子…...

从APP小游戏到Web漏洞的发现

一、前因: 在对一次公司的一个麻将游戏APP进行渗透测试的时候发现,抓到HTTP请求的接口,但是反编译APK后发现没有在本身发现任何一个关于接口或者域名相关的关键字,对此感到了好奇。 于是直接解压后everything搜索了一下&#xff…...

设计模式07-结构型模式(装饰模式/外观模式/代理模式/Java)

4.4 装饰模式 4.4.1 装饰模式的定义 1.动机:在不改变一个对象本身功能的基础上给对象增加额外的新行为 2.定义:动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活 4.4.2 装饰模式的结构…...

C# 广播技术——发现局域网设备技术——

一广播技术应用 客户端发现与管理:软件可以通过广播消息来发现网络中的客户端,从而方便对客户端进行集中管理和监控。服务通知:向所有客户端广播重要的通知、更新或警告信息,确保客户端及时了解相关情况。资源共享与分配&#xf…...

【QA】windows和linux陷入系统调用后有什么区别?

最近被某面试官的这个问题拷打,当场脸烧起来… 首先讲讲系统调用: 系统调用是操作系统为调用者提供服务的接口,以便程序员聚焦于业务问题。分为文件操作,内存分配,进程管理等等。用户使用系统调用后会触发软中断&…...

Github 2024-11-01 开源项目月报 Top19

根据Github Trendings的统计,本月(2024-11-01统计)共有19个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目9TypeScript项目3JavaScript项目3Svelte项目1Jupyter Notebook项目1Ruby项目1HTML项目1Rust项目1Java项目1C++项目1Go项目1Python中的…...

Python实现深度学习模型预测控制(tensorflow)DL-MPC(Deep Learning Model Predictive Control

链接:深度学习模型预测控制 (如果认为有用,动动小手为我点亮github小星星哦),持续更新中…… 链接:WangXiaoMingo/TensorDL-MPC:DL-MPC(深度学习模型预测控制)是基于 P…...

Anki插件Export deck to html的改造

在Anki中进行复习时,每次只能打开一条笔记。如果积累了很多笔记,有时候会有将它们集中输出成一个pdf进行阅读的想法。Anki插件Export deck to html(安装ID:1897277426)就有这个功能。但是,这个插件目前存在…...

csdn 记载文章十分缓慢

现象:其它网站能够正常访问,但只要点击某个 csdn 页面就会等很久 (本文只针对 csdn 网页,其他网页出现类似情况可以同样处理) 产生这种现象的原因: 这种情况很有可能是在访问 CSDN 主页时,需要向…...

python通过pyperclip库操作剪贴板

pyperclip介绍 pyperclip是一个python库用于操作剪贴板,可以非常方便地将文本复制到剪贴板或从剪贴板获取文本。 通过pip进行安装:pip install pyperclip pyperclip的github地址 pyperclip使用 复制到剪贴板 import pypercliptext "Hello, Wo…...

LSTM——长短期记忆神经网络

目录 1.LSTM 工作原理 2.LSTM的代码实现 3.代码详解 LSTM(Long Short-Term Memory)是一种特殊的循环神经网络(RNN),用于解决长序列中的长期依赖问题。它通过引入门机制,控制信息的流入、保留和输出&…...

10进阶篇:运用第一性原理解答“是什么”类型题目

在667分析题题型中,关于“如何做”和“好处是什么”的题目,许多同学都能较好地运用前述的667作答地图开展答题,但是唯独在“是什么”类型题目(也可以叫做认识型题目),不知从何下手。这种题目通常要求我们理解、分析,并展望未来的发展方向,而结构化、逻辑清晰的答案往往…...

【elkb】索引生命周期管理

索引生命周期管理 Index lifecycle management(索引生命周期管理)是elasticsearch提供的一种用于自动管理索引的生命周期的功能。允许使用者定义索引的各个阶段,从创建至删除。并允许使用者在每个阶段定义索引需要执行的特定动作。这些动作包含索引创建&#xff0c…...

江协科技STM32学习- P25 UART串口协议

🚀write in front🚀 🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝​…...

15分钟学 Go 第 22 天:包的使用

第22天:包的使用 欢迎来到Go语言的第22天!今天,我们将深入探讨如何创建和使用包。通过学习包的使用,你将能够更好组织你的代码,提高复用性和可维护性。 1. 包的概念 在Go语言中,包是代码的基本组织单位。…...

【Leecode】Leecode刷题之路第35天之搜索插入位置

题目出处 35-搜索插入位置-题目出处 题目描述 个人解法 思路: 1.依次遍历数组,看目标值是否在数组中 2.如果不在,将目标值插入数组(涉及到数组移动、扩容),返回下标代码示例:(Java…...

速盾:海外cdn高防

随着互联网的快速发展,网站的安全性和稳定性变得越来越重要。尤其是对于大型企业和电商平台来说,保护用户数据和维护网站稳定运行是至关重要的。为了应对日益增长的网络攻击和恶意访问,海外CDN高防服务成为了一种非常受欢迎的解决方案。 首先…...

图书管理系统(JDBC)

AdminUser是管理员类 NormalUser是用户类 AddOperation是增加图书类 BorrowOperation是借书类 DelOperation是删除图书类 ExitOperation是退出类 FindOperation是查找图书类 IOPeration是接口 ReturnOperation是还书类 ShowOperation是显示所有图书类 注意&#xff1a…...

模板初阶及STL简介

目录 一.模板初阶 1.泛型函数 2.函数模板 1.函数模板概念 2.函数模板使用格式 3.函数模板的原理 4.函数模板的实例化 5.模板参数的匹配原则 3.类模板 1.类模板的定义格式 2.类模板的实例化 二.STL简介 1.什么是STL 2.STL的版本 3.STL的六大组件 4.如何学习STL …...

UE5 不同的编译模式下,module的组织形式

由于最近在琢磨UE5.4这个引擎,在学习过程中,碰到了一些非常有意思的事情,我在尝试把之前写的一些底层库搬到UE里面,比如底层库,网络库等等,我通过建立module,将这些库用源代码的方式整合进了UE5…...

【ms-swift 大模型微调实战】

安装环境 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simplepip install modelscope vllm ‘ms-swift[llm]’ -U 下载模型 modelscope download --model Qwen/Qwen2.5-7B-Instruct --local_dir ./Qwen2.5-7B-Instruct 微调 实验环境:…...

Linux:网络基础

计算机是人的工具,人需要协作,于是有了网络 专用服务器->专用计算机 局域网:随着计算机的数量增加,通过交换机和路由器连接计算机 广域网:将远隔千里的计算机都连在一起 协议 协议就是约定俗成 计算机之间用光信号…...

mysql 的内连接、左连接、右连接有什么区别?

在MySQL中,内连接、左连接和右连接是三种常见的连接类型,它们用于通过共享一个或多个字段的值,将两个或多个表组合在一起进行查询。以下是这三种连接类型的详细区别: 一、内连接(INNER JOIN) 定义&#x…...

update-alternatives(选择工具)

0 Preface/foreword 1 update-alternatives介绍 1.1 选项和用法 1.2 install用法 update-alternatives --install <link> <name> <path> <priority> [--slave <link> <name> <path>] link&#xff1a;符号链接&#xff08;软链…...