Knowledge Editing through Chain-of-Thought

题目

通过思路链进行知识编辑

在这里插入图片描述

论文地址:https://arxiv.org/abs/2412.17727

摘要

    大型语言模型 (LLM) 在广泛的自然语言处理 (NLP) 任务中表现出卓越的能力。然而,由于频繁重新训练的成本很高,让这些模型与不断发展的世界知识保持同步仍然是一项重大挑战。为了应对这一挑战,出现了知识编辑技术,可以用新信息更新 LLM,而无需从头开始重建模型。其中,上下文编辑范式因其在整合新知识的同时保留模型原有能力的有效性而脱颖而出。尽管具有潜力,但现有的上下文知识编辑方法通常是针对特定任务的,主要侧重于使用结构化知识三元组的多跳 QA 任务。此外,它们依赖于少量提示进行任务分解,这使得它们不稳定,并且在跨不同任务的泛化方面效率较低。为了应对这些限制,我们提出了 EditCoT,这是一种新颖的知识编辑框架,可以灵活高效地跨各种任务更新 LLM,而无需重新训练。 EditCoT 的工作原理是针对给定的输入生成思路链 (CoT),然后使用基于更新的知识的 CoT 编辑器迭代地改进该 CoT 过程。我们在多种基准上对 EditCoT 进行了评估,涵盖多种语言和任务。结果表明,与现有方法相比,我们的方法实现了最先进的性能,同时提供了卓越的泛化、有效性和稳定性,标志着知识更新领域的重大进步1 。

    ACM 参考格式:Changyue Wang、Weihang Su、Qingyao Ai 和 Yiqun Liu。2024. 通过思路编辑知识。在 WebConf 中。ACM,美国纽约,15 页。https://doi.org/000.000

简介

    近年来,大型语言模型 (LLM) 在众多 NLP 任务中表现出色。然而,一旦 LLM 经过完全训练,它的参数知识就会变得固定和受限。重新训练整个模型以纳入新信息既昂贵又耗时。为了解决为应对这一挑战,知识编辑领域应运而生,它提供了在保留原始模型大部分参数的同时有效修改或添加知识的技术。现有的知识编辑方法大致可分为两类:参数和非参数 [37]。参数方法直接修改模型的权重以整合新知识。虽然这种方法可以实现精确的编辑,但现有研究表明,这种变化可能会对模型的原始性能产生负面影响,并干扰原本应该保持不变的先前学习的知识 [12]。相比之下,非参数方法(例如上下文编辑)越来越受欢迎,因为它们利用 LLM 的上下文学习能力而不修改原始模型权重,从而保留了模型的基础能力和现有知识 [45]。

    大多数现有的上下文知识编辑框架都侧重于多跳问答 (MQA) 任务,这些任务依赖于知识三元组作为知识表示的基本单位。研究人员[6, 46]通过顺序链接多个三元组来构建多跳问题,以评估知识编辑方法的性能。例如,Mello [46] 和 PokeMQA [11] 指导 LLM 使用手工制作的示例分解任务,从而能够在解决子问题的同时更新知识。从另一个角度来看,RAE 框架 [23] 构建并编辑知识图谱,利用知识图谱的检索和修剪来获取上下文注入的知识。虽然这些方法在基于三元组的 MQA 任务上表现良好,但它们的设计过于专业化,限制了它们对其他任务和更复杂推理的适应性。例如,RAE 在处理 LeKUBE 法律数据集 [37] 中的任务时遇到困难,因为在特定领域的语料库上构建知识图谱是不切实际的。

    对于 PokeMQA,当它检测到子问题涉及新知识时,它会直接使用更新后的知识作为子问题的答案。这种方法通常适用于涉及知识三元组的任务,因为此类任务中的知识编辑通常对应于单跳问题,而多跳问题是由这种单跳问题形成的。然而,在其他数据集(如 DUNE[1] 和 LeKUBE[37])中,与新知识相关的问题通常更为复杂,需要推理。在这些情况下,仅凭新知识无法回答子问题,导致 PokeMQA 的性能较差。此外,对任务分解的依赖使 Mello 和 PokeMQA 不稳定,并且在各种任务中效率较低,如图 4 所示。

    为了解决现有上下文知识编辑方法的局限性,我们提出了 EditCoT,这是一个通过思路链 (CoT) 编辑 LLM 知识的知识更新框架。EditCoT 是一种非参数知识编辑方法,不会改变 LLM 的参数,这意味着它可以像其他上下文编辑方法一样保留主干 LLM 的原始容量。此外,与以前针对特定任务类型或严重依赖知识三元组的方法不同,EditCoT 采用迭代方法通过解决与更新知识的冲突来细化模型的推理过程。这种灵活性方法允许 EditCoT 动态调整其推理过程,而无需针对特定任务进行定制或预定义知识结构。具体而言,EditCoT 首先指示模型根据用户的输入及其直接答案生成初始 CoT。然后,CoT 编辑器迭代细化原始 CoT,从而整合新知识。通过提示 LLM 基于更新的 CoT 进行推理来生成最终答案。

    我们在各种基准上对 EditCoT 进行了评估,包括传统知识三重多跳问答数据集 MQuAKE-CF3k[46]、范围广泛且形式自由的编辑任务数据集 DUNE[1] 和领域特定的中文法律知识更新数据集 LeKUBE[37]。这些数据集涵盖了不同的编辑格式,并测试了中英文两种语言的任务。实验结果表明,我们提出的方法达到了最先进的性能,并且具有更好的效率和鲁棒性。总之,本文的贡献如下:

  • 我们提出了一个新颖的框架 EditCoT,用于编辑 LLM 的思路链,从而实现更有效且与任务无关的知识更新。
  • 我们证明我们的方法在具有不同编辑格式和任务类型的各种知识编辑基准上都表现良好,与其他基线相比,具有明显更好的有效性、鲁棒性和通用性。

相关工作

    知识编辑方法是指修改、更新或删除存储在 LLM 中的知识的技术。根据这些方法是否修改模型的参数,它们可以大致分为参数方法和非参数方法[37]。 参数策略直接更新模型的内部参数。一种值得注意的方法是 Meng 等人提出的 ROME[17],它将 LLM 中的前馈神经网络 (FFN) 层视为键值存储。通过对特定的 FFN 层执行低秩更新,ROME 能够精确修改模型内基于事实的关联。MEMIT[18] 通过在多个关键 FFN 层上应用权重更新来扩展这种方法,从而可以批量更新大量事实知识。相比之下,非参数方法主要利用上下文学习[2]进行知识编辑。IKE[45] 探索了通过上下文信息而不是更改模型参数来编辑知识的潜力。上下文编辑的优点是可以降低遗忘非目标知识的风险,特别适合黑盒模型。一些后续研究提出了这个想法。 Mello[46] 将任务分解为子任务,并使用提示引导模型将编辑后的知识与中间答案进行比较。PokeMQA[11]通过引入范围检测器和实体提取机制进一步改进了这项工作,使方法更加健壮。RAE[23]采用了不同的方法,为任务构建知识图谱,通过图谱修改进行知识编辑,并利用模型辅助修剪和细化搜索结果。

    思路链推理在自然语言处理中获得了广泛关注,因为它能够通过提供逐步的推理过程来提高LLM在复杂任务上的性能。最近的工作突出了这一领域的关键进展。Wei等人[40]引入了思路链(CoT)提示,其中手动提供的推理链鼓励LLM生成连贯的多步骤解决方案。在此基础上,Kojima 等人 [14] 表明,添加“让我们一步一步思考”之类的短语可以实现零样本 CoT 推理,使模型无需人工注释即可处理复杂任务。Gao 等人 [10] 提出了程序辅助语言模型,将问题翻译成 Python 代码,以便更好地进行数学推理。同样,Chen 等人 [4] 引入了思维程序,它使用编程语言来注释推理并为结构化任务生成可执行输出。

    除了增强推理能力外,最近的研究还探索了提高 CoT 推理的真实性和准确性。Wang 等人 [39] 提出了一种自洽解码方法,该方法对多条推理路径进行采样并选择一致性最高的路径,从而增强了 CoT 的可靠性。同样,Zhao 等人 [44] 引入了一个验证和编辑框架,从表面上看,它似乎与我们的方法类似,因为它还涉及编辑生成的 CoT。然而,有几个关键的区别:

  1. 它们的验证过程依赖于自洽性,这对于一般的 QA 任务很有效,但不太适用于知识编辑,因为模型通常对过时的信息表现出很高的信心,即使不正确也能保持很高的一致性。我们对 MQuAKE-CF-3k 进行了测试,只关注编辑的触发,忽略后续的编辑结果。使用自洽性,在知识编辑数据集上只有 37% 的情况触发了编辑,而我们的方法在 95% 的情况下触发了编辑。;
  2. 他们的编辑依赖于模型从上下文中学习的能力,而在小节 5.4.1 中,我们证明了我们提出的 CoT 编辑器在知识编辑任务中的表现明显优于这种自编辑方法;
  3. 他们的方法实际上类似于 Mello 等人 [46] 的分解任务策略,而我们的方法在每一轮编辑中都会修改整个 CoT,从而可以进行更全面的调整。

方法论

    在本节中,我们将详细介绍 EditCoT 框架的方法论。我们首先概述我们提出的方法,然后逐步描述框架的工作流程。然后,我们将深入解释 CoT 编辑器训练过程,最后讨论实施细节和数据集构建。

在这里插入图片描述
图 1:EditCoT 框架通过迭代编辑思路链 (CoT) 来更新 LLM,以整合新知识,同时保留模型的推理能力。它生成初始 CoT,检测与更新事实的冲突,并修改 CoT 直到实现对齐。

    方法概述,EditCoT 框架的主要目标是通过编辑思路链 (CoT) 来更新大型语言模型 (LLM),从而整合新的事实知识而不损害其固有的推理能力。传统的参数化知识编辑方法通常需要重新训练整个模型或进行微调,这可能会耗费大量资源,并可能导致先前获得的知识丢失。相比之下,EditCoT 引入了一种迭代编辑机制,通过仅关注 CoT 来有效地整合更新,确保模型保持准确性和逻辑一致性。该框架利用了两个组件:一个负责生成初始 CoT、检测冲突和生成最终答案的未编辑版本的 LLM,以及一个能够根据新知识编辑 CoT 的编辑器。以下小节将详细介绍 EditCoT 框架的每个步骤。

    EditCoT 的工作流程 图 1 说明了 EditCoT 框架的整体工作流程,附录 A 中也以伪代码描述了该工作流程。EditCoT 的核心步骤如下:3.2.1 由原始 LLM 生成初始 CoT。在流程开始时,未编辑的 LLM 会响应查询生成初始思路链。该思路链代表了导致模型最终答案的推理步骤序列。我们更关心推理路径的完整性而不是答案的准确性,因此我们让模型先直接给出答案,然后根据问题和答案给出 CoT。

    逐步检索并检测冲突。一旦生成初始的思路链 (CoT),我们将 CoT 的每个步骤视为查询,并从已编辑知识的内存中检索它。这种内存通常以两种方式组织:一种是将编辑前和编辑后的知识配对在一起(例如,MQuAKE [46]),另一种是仅提供编辑后知识(例如,DUNE [1])。对于前者,我们在知识库中搜索编辑前知识,然后根据对应关系匹配编辑后知识。对于后者,我们直接在编辑后知识中搜索。一旦找到更新的知识,我们就进入冲突检测阶段。

    EditCoT 使用原始 LLM 作为知识冲突检测器。具体来说,给定问题、初始 CoT 和检索到的知识,该模型的任务是完成三类分类任务:冲突、支持或不相关。我们用模型输出的对应词的前缀的概率来表示判断结果。这一步对于识别原始推理是否与新的、更准确的或更新的知识有分歧至关重要。

    编辑思路链。一旦检测到知识冲突,我们将问题、新知识和旧的思路链输入到思路链编辑器中。该编辑器根据输入生成新的思路链。然后,我们的迭代过程返回到步骤2,其中这个新的思路链被视为旧的思路链,用于检索和冲突检测。该过程持续到在思路链和记忆之间没有发现冲突,或者达到最大迭代次数。

    获得最终答案。一旦思路链被完全编辑并且没有检测到进一步的冲突,最终的思路链将用于生成最终答案。原始 LLM 负责此步骤,确保模型的答案符合其现有的推理能力,同时也融入了新的事实知识。我们指示原始 LLM 在上下文中更多地关注新的 CoT,因为新的 CoT 经常与模型的内在知识相冲突。

    CoT 编辑器训练我们设计了一种自动化方法来生成 CoT 编辑器所需的训练数据,其中不需要人工注释,除了使用一些人为提出的问题,从而使训练几乎无人监督。值得注意的是,我们的数据构建方法也不依赖于 GPT-4 等最先进的人工智能模型。此外,数据构建和训练过程不针对任何特定的数据集或任务进行定制。编辑器在训练过程中只是学习编辑 CoT 的能力。一旦经过训练,这个编辑器就可以应用于各种任务,而无需在接触新知识时重新训练。此外,CoT 编辑器是从原始 LLM 训练出来的,确保不会出现知识提炼问题。

    任务制定。编辑器的输入包括:一个问题、一个 CoT 和新知识(与 CoT 相冲突)。目标是根据新知识生成一个新的 CoT。从数学上讲,编辑器可以形式化为:编辑器(𝑄、CoT、𝐾new)→CoTnew,其中𝑄表示问题,CoT是原始的思路链,𝐾new表示相冲突的新知识,CoTnew是调和新知识的修订思路链。

    数据构建。为了构建训练数据,我们首先收集高质量的人工生成问题。在实践中,我们使用来自HotpotQA[42]数据集的验证集和测试集,该数据集包含各种多跳问题,这些问题通常需要多篇维基百科文章才能回答。选择HotpotQA是因为它的问题类型多样,而多跳推理任务通常会产生更复杂的CoT。获得这些问题后,我们使用以下构建步骤:

  1. 第一部分:检索,然后生成CoT和答案。对于每个问题,我们首先检索前5个相关的维基百科段落,然后使用检索增强生成(RAG)方法生成CoT和相应的答案。我们将这个初始 CoT 和答案视为基本版本,在以下部分中,为了清晰起见,它们将突出显示为 CoT 和答案。为了便于步骤级别分离,我们提示模型使用 [STEP] 标记指示每个步骤。
  2. 第二部分:前缀引导的 CoT 生成。给定第一部分中生成的具有 𝑁 个步骤的 CoT,我们将前 (𝑘 −1) 步 (𝑘 = 1, 2, . . . , 𝑁) 作为前缀,并提示模型生成剩余步骤和最终答案,分别标记为 CoT k 和​​答案 k。重要的是要注意,此步骤不使用 RAG,并且仅使用 CoT 的前 (𝑘 − 1) 步作为上下文来提示模型。我们最终在此部分获得 𝑁 个 CoT。
  3. 第三部分:冲突检测。然后,我们将第二部分中生成的每个 𝑁 CoT 与原始 CoT 进行比较,并指示模型检测任何知识冲突。只有在以下情况下,数据点才会被接受到最终数据集中:
  • 最终答案中存在冲突。
  • 两个 CoT 之间的第一个分歧步骤存在冲突。

    例如,考虑 CoT k 和​​ CoT ,第一个分歧步骤是步骤 k。如果原始步骤 k 和新步骤 k 相互冲突,并且答案和答案 k 之间也存在冲突,则它们有资格添加到最终数据集中。这确保可以在推理链中的特定步骤中精确定位冲突知识。在这里,我们假设在大多数情况下分歧只发生一次。

  1. 第四部分:重写以提取新知识。在此步骤中,我们重写从原始 CoT 中识别出的分歧步骤,以明确提取新知识。具体来说,对于上述示例,一个完整的训练数据条目形成一个元组: (𝑄, CoT, 𝐾new, CoTnew) = (Question, CoT k , rewrite( Step k ), CoT )。 我们还应用正则表达式来过滤掉低质量的示例,例如那些受 RAG 中检索到的文档过度影响的示例,从而确保构建的数据集的质量。图 2 说明了数据集构建的整体过程。

在这里插入图片描述
图 2:数据集构建流程图:我们的数据源完全是来自 HotpotQA 的问题,不需要人工标注的答案或相关文章。第二部分中,蓝色部分表示第一部分中已经生成的用于指导生成的前缀,红色部分表示本部分新生成的推理路径。

    在实践中,我们使用多项选择题格式实现冲突检测。我们设置 0.6 的概率阈值来确定冲突,这意味着如果模型分配 0.6 或更高的概率对于两个答案或推理步骤之间的冲突,我们将其视为不一致。此外,在前缀引导生成过程中,为了鼓励模型在发散步骤关注同一主题,我们在发散步骤中明确提供原始 CoT 的第一个单词作为输入提示的一部分。数据集构建的提示模板在 E.1 小节中详细说明。HotpotQA 的开发集和测试集中共有 14,810 个问题。在使用两个不同的 LLM:Meta-Llama-3-8B-Instruct[8] 和 Qwen2.5-14B-Instruct[35, 41] 创建训练数据后,我们分别从两个模型中获得了总共 459 个和 316 个示例。图 3 是构建的数据实例的示例。

实验设置 、

    数据集和指标,我们在以下三个数据集上评估了 EditCoT 和其他基线的性能:

  • MQuAKE-CF-3k[46]:此数据集设计用于使用基于维基百科的知识三元组进行知识编辑,查询形式为多跳问题。评估指标为多跳准确度,与原始论文相同。每个实例包含三个问题,如果任何一个问题回答正确,则被认为是准确的。我们遵循 MQuAKE 和 PokeMQA 的官方实现,使用精确匹配来评估正确性。
  • DUNE[1]:此数据集包括各种编辑任务,其中编辑是自然语言指令,要求模型遵循特定的事实、要求或偏好。每个编辑都与一个或多个查询相关联,以测试对更改的遵守情况。 DUNE 涵盖四个领域:纠正推理和算术错误、添加新信息和减少偏见。它由五个子数据集组成:算术推理、科学推理、新信息、去偏分割 I 和去偏分割 II。性能指标是准确度。在去偏分割 I 和去偏分割 II 中,答案包含偏见,目的是鼓励无偏见的回答;因此,准确度越低,偏差缓解效果越好。对于这些去偏任务,来自不太稳健的方法的无关内容也被认为是正确的,以避免奖励无意义的输出。
  • LeKUBE[36]:这是一个中文法律知识编辑数据集,涉及对中国民法和刑法文章的修改。我们专注于两个特别具有挑战性的任务,先前的基准表现不佳:法律情景的多项选择题和法规变更的判断题。这两项任务的评估指标都是准确率。三个基准的统计数据详见附录 B。

    模型我们评估了两个开源模型:Meta-Llama-3-8B-Instruct[8] 和 Qwen2.5-14B-Instruct[35, 41]。由于前者不支持中文,我们在 LeKUBE 上评估 Qwen2.5-14B-Instruct。按照 LeKUBE 的实验协议,我们首先在包含中国法律和司法解释的 STARD 语料库[28]上对模型进行微调,以确保模型在任何更新之前获取中国法律知识。我们还在 MQuAKE-3k-CF 上评估了 GPT-4o-2024-08-06[21]。由于其专有性质,我们仅在该模型上测试了一些非参数编辑方法。按照 RAE[23],我们随机抽取 300 个数据点以最小化成本。Meta-Llama-3-8B-Instruct 用作​​专有模型无法执行的任务的代理模型。在 RAE 中,此代理根据概率提取和修剪知识图谱,而在 EditCoT 中,它充当 CoT 编辑器。

    基线,我们将 EditCoT 与一系列模型编辑技术进行比较,包括基于知识神经元 (KN)[7]、秩一模型编辑 (ROME)[17] 和上下文方法,例如 Mello[46]、PokeMQA[11] 和 RAE[23]。我们还将全参数微调 (FT) 和检索增强生成 (RAG)[15] 作为基线。这提供了参数和非参数编辑方法的广泛比较。有关基线的详细信息,请参阅附录 C。值得注意的是,对于 DUNE 的 Debiasing 子集,由于无法构建知识三元组,我们无法应用 ROME 和 KN。RAE 不适用于 MQuAKE-CF-3k 以外的数据集,因为它需要构建知识图谱,而在这些数据集上构建知识图谱是不切实际的。

Q;在《艾内斯特拯救圣诞节》中饰演查克的演员与艾莉森·埃利奥特和艾伦·伯斯汀共同出演了 1996 年的一部电影,该电影由谁创作?
COT:在《Ernest Saves Christmas》中扮演 Chuck 的演员是 Gailard Sartain。Gailard Sartain 与 Alison Elliott 和 Ellen Burstyn 共同出演了 1996 年的电影《That Thing You Do!》。《That Thing You Do!》由汤姆·汉克斯编剧。
Knew:盖拉德·萨尔坦 (Gailard Sartain) 与艾莉森·艾略特 (Alison Elliott) 和艾伦·伯斯汀 (Ellen Burstyn) 共同主演了 1996 年的电影《美梦成真》。
COTnew:在《Ernest Saves Christmas》中扮演 Chuck 的演员是 Gailard Sartain。Gailard Sartain 与 Alison Elliott 和 Ellen Burstyn 共同出演了 1996 年的电影《What Dreams May Come》。《What Dreams May Come》的编剧是 Neil Jordan.

图 3:Meta-Llama-3-8BInstruct 构建的数据示例。两个 CoT 的黑色部分表示共享前缀。

    实施细节对于 CoT 编辑器,数据构建过程概述于第 3.4 小节。在训练期间,我们使用相应模型生成的 80% 的过滤数据并训练一个时期。为了生成初始答案、CoT 和最终答案并检测冲突,我们按照 Mello 和 PokeMQA 的风格构建了 5 次提示,并将此格式应用于所有任务,详情见第 E.2 节。对于冲突检测,我们指示模型将输出分为三类:“矛盾”、“支持”或“不相关”。我们将概率最高的标记作为最终分类结果。请注意,虽然我们在数据集构建过程中使用了 [STEP] 标记,但在实际推理中,我们允许模型自由生成思路链 (CoT),步骤以换行符分隔。

    对于 EditCoT 检索语料库,我们展示了第 3.2.2 节中的设置。具体而言,对于提供编辑前和编辑后知识的数据集(例如 MQuAKE-CF-3k 和 LeKUBE),我们从编辑前语料库中检索并尝试与相应的编辑后句子。对于仅提供编辑后知识的数据集(例如 DUNE),我们直接从编辑后语料库中检索。与 Mello 类似,我们使用在 MS MARCO[20] 上训练的 Contriever[13] 检索器,而对于中文数据集,我们使用 BM25[22],它在 LeKUBE 的任务中表现良好。

实验结果

    有效性 泛化性。与基线方法相比,EditCoT 表现出卓越的数据集泛化能力和模型鲁棒性。如表 1 所示,我们在 MQuAKE-3k-CF 和 DUNE 数据集上评估了 EditCoT,其中它在 12 个结果中的 7 个上取得了最佳性能,在 12 个结果中的 4 个上取得了第二好的性能,显着优于所有基线。此外,EditCoT 在 Meta-Llama-3-8B-Instruct 和 Qwen2.514B-Instruct 上的表现始终很好。相比之下,其他上下文编辑方法(如 Mello、PokeMQA 和 RAE)在 Meta-Llama-3-8B-Instruct 上表现出色,但在 Qwen2.5-14B-Instruct 上表现不佳。有趣的是,RAG 似乎更有效地提高了 Qwen2.5-14B-Instruct 的性能。对于 Mello 和 PokeMQA,缺乏稳健性和泛化能力源于它们严重依赖严格的指令遵循和手工制作的少量样本示例,这些示例在不同模型和任务中的有效性各不相同。此外,安全对齐模型倾向于拒绝外部编辑,如下面我们的案例分析进一步说明的那样。适用于垂直领域和黑盒模型。

    EditCoT 在专门的垂直领域和专有模型中也很有效。表 1 的最后两列展示了 LeKUBE 上的评估结果,其中 EditCoT 在两个任务中的表现优于所有基线,在法律场景的多项选择题中明显超过其他方法。此外,表 2 报告了 GPT-4o 在 MQuAKE-CF 上的表现,其中 EditCoT 也表现出了有竞争力的结果,总体排名第二。值得注意的是,此实验中的代理模型是 Meta-Llama3-8B-Instruct。当我们将代理模型本身的性能与 GPT-4o 进行比较时,我们发现,虽然 RAE 的准确率在 GPT-4o 上从 54.1% 提高到了 59.7%,但 EditCoT 实现了更大的相对改进,从 35.4% 上升到了 45.0%。这表明 EditCoT 的成功可能更多地取决于模型的内部推理能力,而 RAE 主要受益于利用外部知识。通用上下文编辑中的挑战。开发一个广泛适用的上下文编辑框架仍然是数据集和模型维度上的重大挑战。

    我们评估的三个数据集涵盖了多跳推理、广义编辑和领域特定知识。而且它们既包括英文任务,也包括中文任务,这对当前的编辑方法来说相当困难。在其他基准中,PokeMQA 在使用 Meta-Llama-3-8B-Instruct 的多跳问题上表现良好,而微调和 RAG 等更简单的方法在狭窄设置(例如 DUNE 去偏任务)中表现出色。然而,这些方法在其他数据集和模型上表现不佳。RAE 在 MQuAKE-3k-CF 数据集上表现出色,因为它构建了结构化知识图谱并访问了更广泛的外部知识(例如维基百科),但它很难在结构化之外进行推广数据集。相比之下,EditCoT 初步解决了这些限制,在大多数数据集和模型中取得了最佳或第二好的表现,尽管在某些情况下仍未达到最佳状态。

    案例研究:在图 4 中,我们在两个问题上将 EditCoT 与 Mello 和 PokeMQA 进行了比较。来自 DUNE 的科学推理子集的第一个问题表明,EditCoT 最初生成了一个错误的答案和 CoT。然而,在检索和冲突检测之后,它会修改 CoT 以得出正确的解决方案。相比之下,Mello 检索到了相关的编辑,但未能检测到与初始答案的任何冲突,错失了纠正的机会。这证明了 EditCoT 冲突检测机制的优势,该机制根据检索到的编辑评估整个推理链。PokeMQA 在这两个子问题上都遇到了困难,产生了重复的分解并且无法触发编辑。

    来自 MQuAKE-CF-3k 的第二个问题再次说明了 EditCoT 通过 CoT 编辑从错误推理过渡到正确答案的能力。尽管 PokeMQA 和 Mello 都成功检索并检测到相关编辑(将《哈利波特》的作者改为莫里斯·梅特林克),但它们并没有应用它。这表明,以安全为目的设计的模型可能会拒绝吸收外部知识而倾向于内部知识。EditCoT 通过将冲突检测与编辑过程分离并专门为 CoT 编辑训练模型来解决此问题,从而实现更有效的推理更新。

    稳健性在本节中,我们从多个角度评估 EditCoT 与其他上下文知识编辑方法。本节测试的模型是 Meta-Llama3-8B-Instruct。

    局部性。知识编辑的一个重要指标是局部性,它评估方法在不降低非目标信息性能的情况下更新特定知识的能力 [19]。

    我们使用 DUNE 的新信息(局部性)子集来评估局部性,其中检索范围仅限于编辑集(与主要实验设置一致),但测试任务涉及该集之外的知识。表 3 中显示的结果与未编辑的基础模型的性能进行了比较。虽然所有编辑方法相对于未编辑模型的性能都有所下降,但 EditCoT 表现出最好的局部性,其次是 Mello。RAG 表现最差,因为它缺乏文档和查询之间的冲突检测,导致在面对不相关信息时性能不佳。

    不同批次大小下的性能。知识编辑方法的性能会随着编辑批次的大小而变化。在这里,我们将编辑批次的大小视为一个批次中的问题数量,因为一个问题可能涉及多次编辑。在本节中,我们测试了 Mello、PokeMQA 和 EditCoT 对不同批量大小的敏感度。2 我们在来自 MQuAKE-CF-3k 的 300 个样本数据集上评估了 1、10、100 和 300 的批量大小。

    结果如图 6 所示。这三种方法在编辑单个样本时表现最佳,并且它们的性能随着批量大小增加。但是,EditCoT 在所有批量大小上的表现始终优于其他方法。从批量大小 1 到 300,EditCoT 的性能下降最小(约 20%),而其他两种方法的性能下降超过 30%。

在这里插入图片描述
表 1:MQuAKE-CF-3k、DUNE 和 LeKUBE 的测试结果,其中 MQuAKE-CF-3k 使用多跳准确度指标进行评估,其他使用准确度进行评估。每个数据集和模型上的最佳性能以粗体突出显示,而第二好的性能则用下划线表示。破折号(“-”)表示该方法不适用于给定的数据集。对于 Debiasing Split I 和 II,分数越低表示性能越好,而对于其他数据集,分数越高越好。

在这里插入图片描述
表 2:在 GPT-4o(黑盒 LLM)上的表现。使用 Meta-Llama-3-8B-Instruct 作为 RAE 和 EditCoT 的代理模型获得结果。

在这里插入图片描述
表 3:DUNE 的新信息(局部性)子集的局部性评估。EditCoT 的表现最接近编辑前的表现。

    效率,我们研究了从 MQuAKE-CF-3k 中抽取的 100 个问题的推理时间和性能之间的关系,比较了 Mello、PokeMQA、RAE 和 EditCoT。通过改变 Mello、PokeMQA 和 EditCoT 的最大迭代次数,我们记录了它们相应的推理时间和性能指标,所有实验都在单个 Nvidia A100 (40G) GPU 上进行。图 5 说明了这些结果,其中 x 轴表示每个问题的平均推理时间,y 轴表示性能。优越的方法位于左上角,表示推理时间更短,性能更高。

在这里插入图片描述
表 4:在 MQuAKE-CF 上评估的冲突检测和训练过的 CoT 编辑器的影响。

    RAE 的官方实现使用 Wikipedia API 调用;因此,我们从其报告的推理时间中排除了网络延迟(包括这将使 RAE 在 x 轴上约为 46 秒)。尽管如此,由于知识图谱检索和修剪的多次前向传播,尤其是在选择下一个关系时,RAE 的推理时间明显更长,这需要分别将所有候选输入模型。

    相比之下,EditCoT 以最短的推理时间实现了高性能,并且在相似的推理时间下优于 Mello 和 PokeMQA。EditCoT 的效率归因于所需的迭代次数更少:PokeMQA 平均需要 4.33 次迭代,而 EditCoT 只需要 3.65 次,这表明长文本生成步骤更少。这里将完整的检索生成周期定义为一次迭代。此外,EditCoT 在前两次迭代中表现出良好的性能,而其他方法则需要更多迭代才能获得相当的性能。附录 D 提供了有关迭代限制影响的更多详细信息。

    消融研究我们使用从 MQuAKE-CF(与上面提到的相同)中采样的 300 个示例数据集进行消融研究,模型为 Qwen2.5-14B-Instruct。

问题:眼镜有两个臂,称为镜腿,通过非常小的铰链连接到眼镜片上。 以下哪个功能类似于眼镜上的铰链? A. 膝盖 B. 手指 C. 颈椎 D. 拇指根部 基本事实:A. 膝盖 编辑: 原因是,就像眼镜上的铰链一样,膝盖也允许向两个方向(屈曲和伸展)移动,并通过铰链(膝关节)连接到两个部位(大腿骨和胫骨)。 手指、颈椎和拇指根部没有这种类型的移动或附着。

在这里插入图片描述
在这里插入图片描述
图 4:我们提出的 EditCoT 方法与其他基线方法的面对面比较。第一个例子来自 DUNE 的科学推理子集。第二个例子来自 MQuAKE-CF-3k。这里的模型是 Meta-Llama-3-8B-Instruct。

在这里插入图片描述
表 5:训练设置对 CoT 编辑器性能的影响,在 MQuAKE-CF 上进行评估。

    组件的影响。我们评估了两种替代设置:

  1. 在 EditCoT 中编辑 CoT 之前删除冲突检测;
  2. 使用原始模型作为 CoT 编辑器,无需进一步训练。结果如表 4 所示。与默认设置相比,这两种配置都会导致性能显著下降,尤其是在使用原始模型作为 CoT 编辑器的情况下。第一种设置表明,仅依靠没有冲突检测的检索器会引入不相关的信息,从而对 CoT 编辑器的性能产生负面影响。第二种设置强调了训练 CoT 编辑器的必要性;仅依靠提示不足以充分利用模型的编辑能力。

    训练配置的影响。表 5 说明了不同训练数据集大小和 epoch 对 CoT 编辑器的影响。虽然增加 epoch 的数量影响不大,但在将训练数据大小扩展到 200 个示例后,性能会稳定下来,这表明 CoT 编辑器需要足够数量的多样化数据才能有效学习。这也支持了我们的主要实验设置,其中使用 80% 的生成数据(252 个训练示例)进行一个时期的训练是一个合理的选择。

在这里插入图片描述在这里插入图片描述

图 5:平均推理时间与性能。更好的方法位于左上角,表明推理时间更短且性能更高。由于水平跨度太长,我们将其从中间截断。
图 6:MQuAKECF 上不同批次大小的性能。这里的指标是多跳准确率。

结论和未来工作

    在本文中,我们介绍了 EditCoT,这是一个旨在通过迭代 CoT 编辑有效更新大型语言模型的框架。EditCoT 增强了编辑在不同任务中的通用性和鲁棒性,而无需重新训练模型。我们在各种基准上进行的实验表明,EditCoT 优于现有方法,证明了其在通用和领域特定应用中的有效性。这种方法为大型语言模型中的持续知识更新提供了一种灵活的解决方案。然而,EditCoT 有局限性,特别是它依赖于两个不同的模型。虽然这种设计不会增加推理时间,但会导致更高的 GPU 资源消耗,这在硬件资源有限的环境中可能是一个挑战。未来的工作可以探索用更小的模型替换编辑器的可能性,旨在在不影响性能的情况下减轻计算负担。

附录

EditCoT 的伪代码描述EditCoT 的伪代码描述如算法 1 所示。
在这里插入图片描述
B 基准测试详情表 6 展示了三个基准测试的统计数据,包括编辑和查询的总数。
在这里插入图片描述
表 6:基准的编辑和问题数量统计

C 基线细节

我们专注于上下文编辑方法,并将 EditCoT 与几种传统模型编辑技术进行比较: 微调 (FT):一种全参数微调方法。由于我们评估的是 Instruct 模型,因此我们会在从每个数据集的编辑实例构建的问答对上训练模型。 RAG [5, 15, 26, 27, 29, 32, 43]:给定一个外部知识库和一个检索器 [9, 16, 24, 25, 30],检索增强生成 (RAG) 框架通过将检索到的文档连接到上下文中,将相关知识注入模型,从而有效地增强了语言模型的推理能力并减少了幻觉 [3, 31, 33, 34]。沿用LeKUBE和DUNE原论文的设置,我们使用BM25[22]作为检索器,基于词汇匹配的检索方法,分别连接3篇和1篇检索到的文档。对于MQuAKE-CF-3k的评估,由于原论文没有测试RAG,我们仍然使用RAG作为检索器,将其设置为连接5篇检索到的文档。

KN[7]:该方法通过识别和编辑模型中的“知识神经元”来更新知识。在我们的实验中,我们将神经元识别的提示数𝑛设置为10,知识归因阈值设置为0.2,保留共享神经元的概率设置为0.4。

ROME[17]:一种直接修改FFN层中键值对的Rank-One模型编辑方法。在我们的实验中,我们统一修改第五层,并在模型的最后一层计算损失。权重衰减设置为 1 × 10−3 。

KN 和 ROME 方法均使用 EasyEdit[38] 库实现,该库集成了多种模型编辑技术以方便使用。值得注意的是,这两种方法都依赖于知识三元组进行编辑。在 DUNE 的科学推理和新信息子集中,编辑由更长的自然语言序列组成。我们使用 GPT-4o 提取相关的知识三元组。

DUNE 中的两个 Debiasing 子集涉及基于观点的知识,因此无法提取知识三元组,因此未对它们进行这两种方法的测试。

Mello[46]:Mello 通过将问题分解为子问题并利用检索来执行上下文编辑。我们遵循官方设置,最多进行 4 轮检索,并将提示调整为指导模型。在英文数据集中,我们使用 Contriever[13] 作为检索器,遵循原始论文中的设置。对于中文 LeKUBE 数据集,我们将提示翻译成中文并使用 BM25 作为检索器。

PokeMQA[11]:PokeMQA 建立在 Mello 之上,增加了实体提取和范围确定,以细化问题理解。我们遵循官方设置,最多 5 轮,并使用其预先训练的 Scope-Detector。对于没有预提取实体的 DUNE 和 LeKUBE,我们指示模型以类似的格式提取实体。由于官方 ScopeDetector 仅支持英语,因此我们在应用检测器之前将 LeKUBE 任务的输入句子翻译成英语。在 GPT-4o 评估期间,我们发现严格遵循提示格式存在困难。为了缓解这个问题,我们添加了系统提示:“按照以下示例操作。”此外,对于 Mello、PokeMQA 和 EditCoT,由于 LeKUBE 评估法律条款的变化,而其他基线可以同时使用新旧法律,我们将更新前后的法律文本连接起来,并在检索后将它们提供给模型进行公平比较。

RAE[23]:RAE 构建知识图谱用于检索,并利用模型协助检索和修剪图谱。然而,对于 DUNE 和 LeKUBE,无法构建类似于维基百科的知识图谱,这使得 RAE 不太适合这些任务。

在这里插入图片描述
图 7:不同最大迭代次数下的性能。一个完整的检索生成周期定义为一次迭代。

D 不同最大迭代次数下的性能

我们探索不同最大迭代次数对其性能的影响。图 7 显示了结果。PokeMQA 和 Mello 需要更多迭代才能达到最佳性能,早期迭代的准确率相对较低。另一方面,EditCoT 在每次迭代中输出完整的思路链,在第一次迭代后实现不错的性能。

E 提示模板 由于我们使用的模型都是 Instruct 模型,因此以下提示模板使用“系统”、“用户”和“助手”来表示不同的角色。

E.1 数据集构建提示模板 首先,我们使用RAG生成CoT和答案。提示模板如下:

数据集构建-RAG提示 用户:{来自Wikipedia的前5个相关段落} 说明:您可以访问可能有助于回答问题的背景信息。专注于逐步推理问题,保持解释简洁。使用标记[STEP]开始每个思考步骤,使用标记[ANSWER]表示最终答案。 避免在推理中直接提及或引用背景信息。 模板:[STEP] ... 
[STEP] ... 
... 
[ANSWER] ... 
问题:{来自HotpotQA的问题} 

其次,我们进行前缀引导的CoT生成。提示模板如下:

数据集构建-前缀引导的CoT生成提示 
用户:请使用思路链回答以下问题。使用标记 [STEP] 开始每个思考步骤,使用标记 [ANSWER] 表示最终答案。保持每个步骤简短明了,并保持最终答案简洁。
模板:[STEP] ...
[STEP] ...
...
[ANSWER] ...
问题:{来自 HotpotQA 的问题}助手:[STEP] {来自 RAG 的 CoT 的前 (k-1)} {...} 

然后,我们检测最终答案是否存在冲突:

数据集构建 - 提示答案冲突检测用户:对于给定的问题 Q 和两个提供的答案(答案 1 和答案 2),确定答案在语义上是否一致。从以下选项中选择最合适的选项:A. 是的,它们传达了相似的想法或信息。
B. 不,它们是不同的或矛盾的。问题 Q:{来自 HotpotQA 的问题} 
答案 1{由 RAG 生成的答案} 
答案 2{由前缀引导的 CoT 生成生成的答案} 您的选择:

并检测两个 CoT 之间在第一个发散步骤中是否存在冲突:

数据集构建 - 提示 CoT 步骤冲突检测用户:根据事实内容评估以下两个句子之间的关系。从以下选项中选择最合适的选项:A. 这两个句子包含相互冲突的知识。
B. 这两个句子相互支持或补充。
C. 这两个句子毫无关联(没有冲突,但没有联系)。句子 1{CoT 步骤 k} 
句子 2{CoT 步骤 k*} 你的选择:

最后,我们让模型重写关键步骤:

数据集构建 - 重写提示用户:使用正式和客观的语言,以维基百科数据的风格重写以下句子。仅表达句子中存在的事实知识,不添加任何额外信息或虚构细节。你的输出必须是一个或多个句子,只需要包含直接结果而不需要额外的单词。
输入:
句子:{需要重写的 CoT 步骤} 输出:

E.2 EditCoT 提示模板 CoT 编辑器的提示模板如下。注意,在训练和推理阶段,模板是相同的。

EditCoT 框架 - CoT 编辑器提示系统:您可以根据新知识编辑以下思路。用户:问题:{用户问题} 旧想法:{旧 CoT} 新知识:{包含新知识的句子}请给我基于新知识的新思路。助手:新想法:

冲突检测的提示模板如下。我们使用 5-shot 示例并应用类似于 CoT 编辑器的场景。

EditCoT 框架 - 冲突检测提示系统:您可以根据新知识编辑以下思路。
用户:问题:¨Moneyballä 的作者是哪个国家的公民?
旧想法:Moneyball 的作者是 Michael Lewis。
Michael Lewis 是美国公民。
新知识:《我们共同的朋友》的作者是查尔斯·狄更斯 
请根据新知识给我新的思路。 助理:知识与思路的相关性:不相关。 
{另外4个例子...} 用户:问题:{用户问题} 旧想法:{旧的CoT} 新知识:{包含新知识的句子} 请根据新知识给我新的思路。 
助理:知识与思路的相关性:

获取最终答案的提示如下。我们指示原LLM多关注新的CoT。

EditCoT框架 - 获取最终答案系统的提示:假设世界知识已经更新。根据[新想法]而不是你自己的知识回答问题。不要分析[新想法]的推理是否正确。直接输出最简洁的答案。用户:问题:Android Jelly Bean开发者的总部位于哪里?
[新想法]:Android Jelly Bean由Google开发。
Google的总部位于Googleplex市。助手:来自[新想法]的回答:Googleplex {另外4个例子...}用户:问题:{一个问题} [新想法]{一个CoT}
助手:来自[新想法]的回答:

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

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

相关文章

运行.Net 7 Zr.Admin项目(后端)

1.下载Zr.Admin代码压缩包 https://codeload.github.com/izhaorui/Zr.Admin.NET/zip/refs/heads/main 2.打开项目 我这里装的是VS2022社区版 进入根目录,双击ZRAdmin.sln打开项目 3.安装.net7运行时 我当时下载的代码版本是.net7的 点击安装 点击安装&#xff0…

spark——RDD算子集合

目录 算子转换算子示例mapflatMapReduceByKeyfilterdistinctglomgroupBygroupByKeySortBysortByKeyunion交集intersection和差集subtractjoinpartitionBymapPartitionsample 行动算子示例ForeachPartitionForeachSaveAsTextFileCountByKeyReducefoldfirst、take、counttop、tak…

Taro+react 开发第一节创建 带有redux状态管理的项目

Taro 项目基于 node,请确保已具备较新的 node 环境(>16.20.0),推荐使用 node 版本管理工具 nvm 来管理 node,这样不仅可以很方便地切换 node 版本,而且全局安装时候也不用加 sudo 了。 1.安装 npm inf…

Qt C++读写NFC标签NDEF网址URI

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.1d292c1biFgjSs&ftt&id615391857885 #include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> #include "QLibrary" …

Js的回调函数

一、什么是回调函数&#xff08;Callback&#xff09;&#xff1f; 回调函数&#xff08;Callback Function&#xff09;是指一个函数被作为参数传递给另一个函数&#xff0c;并在特定事件发生或操作完成时执行。 可以通俗地理解为一种“委托”机制。 在JavaScript中&#xff0…

OSPF - 1类LSA(Router-LSA)

前篇博客有对常用LSA的总结 1类LSA是OSPF计算最原始的材料&#xff0c;他会泛洪发给所有的路由器 LSA是包含在LSU中的&#xff0c;一条LSU能够携带多条LSA options位所有LSA都会有&#xff0c;用于标记起源于什么类型的区域&#xff0c;具体查看文章【邻居建立】 flags位是一…

python学opencv|读取图像(三十一)缩放图像的三种方法

【1】引言 前序学习进程中&#xff0c;我们至少掌握了两种方法&#xff0c;可以实现对图像实现缩放。 第一种方法是调用cv2.resize()函数实现&#xff0c;相关学习链接为&#xff1a; python学opencv|读取图像&#xff08;三&#xff09;放大和缩小图像_python opencv 读取图…

实训云上搭建集群

文章目录 1. 登录实训云1.1 实训云网址1.2 登录实训云 2. 创建网络2.1 网络概述2.2 创建步骤 3. 创建路由器3.1 路由器名称3.1 创建路由器3.3 查看网络拓扑 4. 连接子网5. 创建虚拟网卡5.1 创建原因5.2 查看端口5.3 创建虚拟网卡 6. 管理安全组规则6.1 为什么要管理安全组规则6…

c++入门之 命名空间与输入输出

1、命名空间 1.1使用命名空间的原因 先看一个例子&#xff1a; #include <iostream>int round 0;int main() {printf("%d", round);return 0; }请问&#xff0c;这个程序能跑起来吗&#xff1f; 答案是否定的 原因是&#xff0c;当我们想创建一个全局变量 …

继承(7)

大家好&#xff0c;今天我们继续来学习一下继承的知识&#xff0c;这方面需要大家勤动脑才能理解&#xff0c;那么我们来看。 1.9 protected关键字 在类和对象章节中&#xff0c;为了实现封装特性,java中引入访向限定符,主要限定:类或者类中成员能否在类外和其他包中被访问. …

Unity中 Xlua使用整理(二)

1.Xlua的配置应用 xLua所有的配置都支持三种方式&#xff1a;打标签&#xff1b;静态列表&#xff1b;动态列表。配置要求&#xff1a; 列表方式均必须是static的字段/属性 列表方式均必须放到一个static类 建议不用标签方式 建议列表方式配置放Editor目录&#xff08;如果是H…

Flink三种集群部署模型

这里写自定义目录标题 Flink 集群剖析Flink 应用程序执行Flink Session 集群&#xff08;Session Mode&#xff09;Flink Job 集群&#xff08;以前称为per-job&#xff09;Flink Application 集群&#xff08;Application Mode&#xff09; 参考 Flink 集群剖析 Flink 运行时…

Windows10环境下安装RabbitMq折腾记

最近有个老项目需要迁移到windows10环境&#xff0c;用的是比较老的rabbitmq安装包&#xff0c;如下所示。经过一番折腾&#xff0c;死活服务起不来&#xff0c;最终果断放弃老版本启用新版本。现在把折腾过程记录下&#xff1a; 一、安装erlang 安装完成后的目录结构&#xff…

【深度学习】通俗理解偏差(Bias)与方差(Variance)

在统计学习中&#xff0c;我们通常使用方差与偏差来衡量一个模型 1. 方差与偏差的概念 偏差(Bais)&#xff1a; 预测值和真实值之间的误差 方差(Variance)&#xff1a; 预测值之间的离散程度 低偏差低方差、高偏差低方差&#xff1a; 图中每个点表示同一个模型每次采样出不同…

(五)ROS通信编程——参数服务器

前言 参数服务器在ROS中主要用于实现不同节点之间的数据共享&#xff08;P2P&#xff09;。参数服务器相当于是独立于所有节点的一个公共容器&#xff0c;可以将数据存储在该容器中&#xff0c;被不同的节点调用&#xff0c;当然不同的节点也可以往其中存储数据&#xff0c;关…

使用Keil创建FreeRTOS工程

之前记录了使用Keil创建Keil自带的RTX5的RTOS和使用CubeMX创建FreeRTOS。这次来记录下使用Keil创建FreeRTOS。使用CMSIS-RTOS2将FreeRTOS封装好 1.Pack增加CMSIS-FreeRTOS 2.CMSIS配置为FreeRTOS 点击Resolve后再点击OK即可 3.屏蔽相关文件 4.屏蔽3个中断 将void PendSV_Han…

LLM - Llama 3 的 Pre/Post Training 阶段 Loss 以及 logits 和 logps 概念

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/145056912 Llama 3 是 Meta 公司发布的开源大型语言模型&#xff0c;包括具有 80 亿和 700 亿参数的预训练和指令微调的语言模型&#xff0c;支持…

Unity + Firebase + GoogleSignIn 导入问题

我目前使用 Unity版本&#xff1a;2021.3.33f1 JDK版本为&#xff1a;1.8 Gradle 版本为&#xff1a;6.1.1 Firebase 版本: 9.6.0 Google Sign In 版本为&#xff1a; 1.0.1 问题1 &#xff1a;手机点击登录报错 apk转化成zip&#xff0c;解压&#xff0c;看到/lib/armeabi-v…

安卓投屏电脑最详细教程

安卓手机投屏到电脑的操作可以通过多种方式实现&#xff0c;最常见的方法有使用 Scrcpy、911投屏 或者 Windows 10/11 自带的投屏功能。下面是几个常用方法的详细教程&#xff1a; 方法 1&#xff1a;使用 Scrcpy &#xff08;推荐&#xff0c;免费的开源工具&#xff09; Sc…

VSCode配置php开发环境

我偷偷地告诉你&#xff0c; 有一个地方叫做稻城&#xff0c;我要和我最心爱的人一起去到那里... 2025.1.10 声明 仅作为个人学习使用&#xff0c;仅供参考 不知道如何配置php本地环境的&#xff0c;请翻阅 笔者的上一篇文章 正文 VSCode安装 官网&#xff1a;Download Vis…