本文为邹德清教授的《网络安全专题》课堂笔记系列的文章,本次专题主题为大模型。
黄邕灵同学@potato&&tomato:分享了Keeping Pace with Ever-Increasing Data:Towards Continual Learning of Code Intelligence Models《跟上不断增长的数据:迈向代码智能模型的持续学习》
软工顶会ICSE ‘23: Proceedings of the 45th International Conference on Software Engineering
论文主题:大模型在代码智能领域的应用,特别是它们如何持续学习并适应新数据。
将论文阐述得深入浅出,受益匪浅
这门课中最细节的PPT,对公式的每个符号都进行了解释,观感特别友好
论文:https://arxiv.org/pdf/2303.16749.pdf
以往的代码智能研究通常以离线方式在固定数据集上训练深度学习模型。然而,在实际场景中,新的代码仓库不断涌现,所携带的新知识有利于向开发者提供最新的代码智能服务。
在本文中,我们针对以下问题:如何使代码智能模型能够从不断增长的数据中不断学习?
这里的一个主要挑战是灾难性的遗忘,这意味着模型在从新数据集学习时很容易忘记从以前的数据集中学习的知识。
代表性示例重放、自适应参数正则化
来解决灾难性遗忘问题。为了应对这一挑战,我们提出了REPEAT,这是一种持续学习代码智能模型的新方法。具体来说,REPEAT通过
代表性示例重放、自适应参数正则化
解决了灾难性的遗忘问题。
代表性示例重放
组件在每个数据集中选择信息丰富且多样化的示例,并使用它们定期重新训练模型。
自适应参数正则化
组件可识别模型中的重要参数,并自适应地惩罚其更改,以保留之前学习的知识。
我们在三个代码智能任务上评估了所提出的方法,包括代码摘要、软件漏洞检测和代码克隆检测。大量实验表明,REPEAT在所有任务上的表现始终优于基线方法。例如,REPEAT在代码汇总、漏洞检测和克隆检测方面分别将传统的微调方法提高了1.22、5.61和1.72。
REPEAT方法提供了一系列值得借鉴的概念和技术,这些可以应用于NLP中的NER和关系抽取任务,以改进模型的持续学习能力、泛化能力和准确性。
持续学习
灾难性遗忘的处理
保持重要信息的、同时学习新信息的策略
提供了思路。自适应参数正则化
可以被用于调整模型中参数的更新,以维持对旧知识的记忆。代表性样本的重要性
代表性示例重放
的概念,可用于优化NER和关系抽取任务的数据选择,即选择那些能够提供最大信息量的样本
进行训练。多样化且信息丰富的样本
可以帮助模型更好地泛化,减少对特定数据集的过拟合。多任务的应用与评估
噪声数据,训练损失比较大
选择训练损失更小的样本
三个不同任务,用到了三个数据集
数据集划分成了五个子数据集
特征差别不大
旧模型训练好的参数,新模型上再次训练
重要参数尽可能小的改变:计算每个参数的变化值,限制参数变化
大模型结构不太一样,
codebert基于编码器,在第一个任务上更擅长
T5的摘要更合适
REPEAT方法在漏洞检测和代码克隆任务上准确率较低可能是由几个因素造成的,了解这些因素有助于进一步优化REPEAT方法,或开发更适合这些特定任务的新方法:
任务本身的难度:漏洞检测和代码克隆是代码智能领域中比较复杂的任务。它们需要模型对代码的深层结构和潜在的安全漏洞有很高的理解能力。这些任务往往涉及对细微差别的识别,比如在代码克隆检测中区分微妙的代码差异、或者在漏洞检测中识别潜在的安全风险。
数据集的质量和多样性:如果用于训练和测试模型的数据集不够丰富或者质量不高,模型的性能可能会受到影响。在漏洞检测和代码克隆任务中,高质量、多样化的数据集对于训练有效的模型至关重要。
模型的泛化能力:这些任务可能要求模型在不同的编程语言和代码库中具有较好的泛化能力。如果模型在训练过程中未能充分学习到可以泛化到新情况的特征,其性能可能会降低。
灾难性遗忘的挑战:尽管REPEAT方法旨在减轻灾难性遗忘问题,但在实际应用中,完全避免模型在学习新任务时忘记旧任务的知识仍然是一个挑战。特别是在复杂任务如漏洞检测和代码克隆中,保持之前学习成果的难度可能更大。
特定任务的特性:每个代码智能任务都有其独特的特性和挑战。REPEAT方法虽然是一个通用的持续学习方法,但它可能不完全适用于某些特定任务的特定需求。
大模型是一种复杂的计算机程序,它可以学习和适应新信息。在软件开发领域,这些模型帮助自动化许多任务,比如:
◆ 文本生成代码
根据自然语言描述生成代码
◆ 代码摘要
以自然语言描述生成源代码摘要
◆ 代码翻译
将一种编程语言编写的代码转换为另一种同功能编程语言的过程
◆ 代码漏洞检测
要求 LLM 检测提示中提供的源代码中的缺陷
◆ 代码克隆检测
检测存在于代码库中两个及以上的相同或者相似的源代码片段
◆ 代码重构、代码补全、代码修复、代码搜索…
如何维护代码智能模型,使模型能够持续学习,随时间变化的知识,不断更新迭代?
灾难性遗忘问题
:模型会忘记从以前的数据中学习到的知识、计算开销大
,缺乏可行性基于持续学习
的方法
当新的代码不断出现时,模型需要不断学习这些新信息。但这里有一个挑战:当模型学习新信息时,它可能会“忘记”以前学到的内容。这就像我们在学习新语言时可能会忘记之前学过的语言。
记忆回放
来缓解灾难性遗忘,这些样本/伪样本既可用于联合训练,也可用于约束新任务损失的优化,以避免干扰先前任务。为损失增添额外损失项,对权重进行约束
,保护巩固已学习的知识,但这样可能会制衡新任务的学习性能,无法很好的权衡新旧任务。该类方法不需要保存任何以前的数据,只需要对每个任务进行一次训练。但是,随着任务数量的不断增加,可能导致特征漂移现象。动态的对网络结构进行调整
,使其适应新的任务,也可以扩展网络结构来学习新的任务,使用更多的神经元或网络层。然而随着任务数量的不断增多,模型结构会不断变大,因此这样的方法无法应用到大规模数据中,影响其在实际场景中的使用。为了解决上述挑战,研究人员提出了一个称为“REPEAT”的新方法。这个方法通过两个关键步骤来帮助模型更好地学习:
针对代码智能数据集中存在各种数据模式和噪声数据的问题,提出一种新的代表性样本重放方法
,保留数据集中更具信息量的多样性样本。
考虑到软件开发中存在较多的代码重用,提出了一种基于数据集之间共享知识的自适应参数正则化
机制来控制参数更新的程度。
在三个代码智能任务
上与两个先进的模型
进行了对比,实验结果证明该方法对于缓解灾难性问题具有较好效果。
针对样本大小有限,如何缓解模型对保存的样本过拟合并忘记其他样本的问题
TF-IDF(词频-逆文档频率)
算法向量化代码样本K-means算法
将样本划分为K类,从每个类中分别选取样本滤除高损失样本
,保留具有高信息量的样本数据
利用重要度矩阵,即: Fisher信息矩阵,度量网络参数对旧任务的重要程度;
L2正则化用于在训练新任务B时对完成任务A重要的网络
计算两个数据集之间的相似度,相似度越大,新知识权重越小。
因为旧模型中已经学习到了很多相似的知识
通过控制优化方向,使得其能够处于两个区域的交集部分,在旧任务与新任务上都有良好的性能
。通过一系列实验,研究人员发现REPEAT方法比旧方法更有效。它不仅帮助模型更好地记住旧信息,还提高了在新任务上的表现。
◼ FT严重患有灾难性遗忘问题
◼ 样本重放和参数正则化有利于缓解灾难性遗忘
◼ REPEAT在不同代码智能任务都有由于其他基线系统的性能
◼ 在前四个数据集上训练所有基线模型和REPEAT,在第五个数据集上评估模型性能
◼ REPEAT-1、 REPEAT-2和REPEAT-3,分别表示在第一、第二和第三个数据集上的训练REPEAT
◼ 使用CodeBERT作为基本模型,并选择Java作为代码汇总的评估数据集。
◼ 用新数据持续训练模型有利于模型在未知项目上的泛化。
为什么漏洞检测和代码克隆任务上的准确率这么低
?REPEAT方法在漏洞检测和代码克隆任务上准确率较低可能是由几个因素造成的,了解这些因素有助于进一步优化REPEAT方法,或开发更适合这些特定任务的新方法:
任务本身的难度:漏洞检测和代码克隆是代码智能领域中比较复杂的任务。它们需要模型对代码的深层结构和潜在的安全漏洞有很高的理解能力。这些任务往往涉及对细微差别的识别,比如在代码克隆检测中区分微妙的代码差异、或者在漏洞检测中识别潜在的安全风险。
数据集的质量和多样性:如果用于训练和测试模型的数据集不够丰富或者质量不高,模型的性能可能会受到影响。在漏洞检测和代码克隆任务中,高质量、多样化的数据集对于训练有效的模型至关重要。
模型的泛化能力:这些任务可能要求模型在不同的编程语言和代码库中具有较好的泛化能力。如果模型在训练过程中未能充分学习到可以泛化到新情况的特征,其性能可能会降低。
灾难性遗忘的挑战:尽管REPEAT方法旨在减轻灾难性遗忘问题,但在实际应用中,完全避免模型在学习新任务时忘记旧任务的知识仍然是一个挑战。特别是在复杂任务如漏洞检测和代码克隆中,保持之前学习成果的难度可能更大。
特定任务的特性:每个代码智能任务都有其独特的特性和挑战。REPEAT方法虽然是一个通用的持续学习方法,但它可能不完全适用于某些特定任务的特定需求。
◼ 使用CodeBERT和CodeT5作为我们的基本模型,并选择Java和Python作为代码总结的评估数据集。
◼ REPEAT-C、 REPEAT-L和REPEAT-A,分别表示移除了基于聚类的样本选择,基于损失的样本选择和自适应参数正则化模块后的模型性能。
◼ 删除基于聚类的样本选择会显著降低各类任务的性能。例如,在CodeBERT预训练模型漏洞检测方面的表现在F1、 Precision和Recall方面分别下降了1.99、 1.37和2.16分, 表明了样本多样性的重要性。
◼ 删除基于损失的样本选择会显著降低各类任务的性能。例如,在CodeBERT预训练模型代码摘要方面的表现在BLEU-4、 METEOR和ROUGE-L方面分别下降了0.64%、 0.39%和0.48%, 表明了去除样本噪声数据的重要性。
◼ 删除自适应参数正则化会显著降低各类任务的性能。 在持续学习环境中,自适应惩罚重要参数变化是有效的。
◼ 第一个在持续学习场景下探索代码智能模型性能的工作。
◼ 为了防止代码智能模型灾难性地遗忘所学知识,提出了一种新的基于持续学习的方法REPEAT,该方法采用了代表性示例重放和自适应参数正则化技术。
◼ 使用两个最先进的模型对三个代码智能任务进行了广泛的实验。实验结果证明了重复记忆的有效性及其减轻灾难性遗忘问题的能力。