CodeWisdom
“智能化软件开发沙龙是由CodeWisdom团队组织的围绕智能化软件开发、数据驱动的软件开发质量与效能分析、云原生与智能化运维等相关话题开展的线上沙龙,通过微信群访谈交流等线上交流方式将学术界与工业界专家学者汇聚起来,共同分享前沿研究进展与业界实践,共同探讨未来技术发展方向。”
代码大模型训练、微调与增强
智能化软件开发微访谈·第三十一期
背景介绍
当前,基于大模型的软件智能化开发已经成为学术界和产业界共同关注的热点话题。商业及开源大模型本身已经将代码生成作为一个重要的基本能力,同时还有大量在通用大模型基础上通过代码数据强化训练获得的代码大模型。另一方面,大量软件企业也在积极探索如何在开源代码大模型基础上加入特定领域的私有代码及文档数据,从而得到更加适应特定企业和领域特点的代码大模型。在此基础上,一些企业还在探索如何将代码大模型与提示工程(Prompt Engineering)、上下文学习(In-Context Learning)、多Agent、检索增强生成(RAG)以及一些后处理技术相结合,从而实现面向自身开发者的定制化编程助手(如IDE插件形式)。那么当前代码大模型训练与微调都采用了哪些技术,各自有什么优缺点?企业在开展面向特定领域的代码大模型微调与定制时需要考虑哪些关键问题,有哪些成功经验?提示工程、上下文学习、多Agent、检索增强以及各种后处理技术与模型微调如何有机结合从而提高代码推荐和生成的成功率?
围绕这些问题,本次微访谈邀请了来自学术界和工业界的多位专家,围绕代码大模型训练、微调与增强这一主题展开讨论,总结学术界研究及工业界实践现状、分析相关技术问题、展望未来的发展方向。
主持人
彭鑫
复旦大学计算机科学技术学院副院长、教授,教育部长江学者
嘉宾
李戈
北京大学计算机学院长聘教授,博士生导师,教育部长江学者
张令明
美国伊利诺伊大学香槟分校计算机系副教授
王焱林
中山大学软件工程学院助理教授,2022年入选中山大学百人计划
刘名威
中山大学软件工程学院副教授,“逸仙学者计划”新锐学者,博士生导师
王翀
新加坡南洋理工大学博士后研究员
彭超
字节跳动软件工程实验室技术专家
李钟麒
华为云 LLM研发垂域方向研究员,主任工程师,HUAWEI CodeArts Snap代码生成工具模型负责人,pangu-coder核心研究成员
曹荣禹
阿里巴巴通义实验室算法工程师
薛增奎
科大讯飞效能平台首席技术专家,iFlyCode产品总架构师,研发总监
徐晓强
百度资深工程师、百度Comate架构师
王思维
腾讯高级算法研究员,大模型代码方向负责人
访谈主题
代码大模型训练、微调与增强
01
当前代码大模型主要是在通用大模型基础上继续训练得到的还是完全重新训练的?代码大模型的训练和微调有哪些常用方法,其有效性如何?
02
企业在开展面向特定领域的代码大模型微调与定制时可以采取哪些技术手段(例如微调方式和任务)?在数据准备和清洗以及其他关键问题上有哪些需要特别注意的问题?
03
企业在代码大模型落地应用时,如何将提示工程、上下文学习、多Agent、检索增强以及各种后处理技术与模型微调有机结合,从而提高代码推荐和生成的准确性?
04
企业在代码大模型落地应用时有哪些比较成功的应用场景(例如代码补全/生成/重构以及软件开发问答等)?为了实现软件开发质量和效率提升,需要如何度量代码推荐和生成的质量(例如采纳率或其他指标)?还需要考虑哪些人机交互(例如如何掌握代码补全和推荐的时机)及其他方面的问题?
05
当前企业应用代码大模型主要是完成一些简单任务(例如局部的代码补全与生成),那么代码大模型是否有可能支持更加复杂的开发任务(例如更大范围内的生成式软件开发以及大规模软件的维护型任务等)?为此需要解决哪些关键问题,有哪些初步的思路和方向?
Q&A记录
Question 1
主持人:当前代码大模型主要是在通用大模型基础上继续训练得到的还是完全重新训练的?代码大模型的训练和微调有哪些常用方法,其有效性如何?
李戈:
当前代码大模型主要是在通用大模型基础上继续训练得到的还是完全重新训练的?
两种方式都有。以代码数据为主训练的,比如StarCoder、DeepSeek-Coder、CodeQwen,还有我们的aiXcoder等等;也有在通用模型的基础上构建的,比如CodeLlama等。无论那种方式,都离不可大量的代码数据,这是代码大模型构建的基础。
代码大模型的训练和微调有哪些常用方法,其有效性如何?
这个不能一概而言,需要看训练和微调的目的是什么。一般而言,一些对LLM都适用的技术在代码大模型场景中也同样可以适用。如果带有目的的训练和微调,则需要使用不同的手段或方法。比如,如果要增长上下文感知范围,可以用一些对位置编码进行处理的办法,也可以同时考虑增强代码的结构信息;如果要解决多文件关联的问题,则需要利用一些特殊构造的数据来进行CT或FT;如果需要解决领域知识或特殊语言的问题,则需要使用特别准备的数据来进行训练。
观点讨论
@彭鑫:@李戈 不依赖基础大模型,直接以代码数据为主训练的代码大模型在用户意图理解和文本交互能力上会不会差一些?
@李戈:@彭鑫 目前没有看到这方面的明确结论。
@王焱林:@李戈 (补充一下:认同李老师的观点,因为DeepSeekCoder是以代码数据为主训练出来的(87%),它在多个代码任务上表现都很好,所以推论应该不会在用户意图理解和文本交互能力上很差)。
@彭鑫:@王焱林 看起来有点反直觉,原因在哪里呢?
@王焱林:@彭鑫 可能是因为它还有13%的非代码数据(10%英文语料+3中文预料),而且评测任务大多数是代码相关的任务,不清楚到通用任务上是否在用户意图理解和文本交互能力上变差。
@王思维:@王焱林 这个我们有评测过 nlp理解确实会变差的。
@张令明:@彭鑫 这个问题其实deepseekcoder论文里最后有个小的study大家可以看看。、
@彭鑫:@张令明 直觉上是否有什么简洁的解释?
@张令明:@彭鑫 不同的模型结果估计不太一样,但deepseek的发现是在通用大模型基础上继续训练会有更好的NLP和Math能力,但代码能力比代码数据为主的重新训练稍弱。我猜还是nlp和代码数据分布的影响。
@王翀:@彭鑫 这是DeepSeek-Coder文章中对其中10%英文语料的介绍:“The English corpus consists of materials from GitHub’s Markdown and StackExchange, which are used to enhance the model’s understanding of code-related concepts and improve its ability to handle tasks like library usage and bug fixing.”
@彭鑫:@王翀 嗯,这样显然它在对话型语料上的训练是不够的。
@王翀:@彭鑫 是的,所以还有一个instruction-tuning版本的deepseek-coder-instruct,专门做了这方面的微调。
张令明:
其实这两种方案都有。直接从0开始训练的开源代码大模型有CodeGen系列,StarCoder系列和DeepSeek Coder初始版本等等,其它大部分模型(例如Code Llama,Llama3,CodeQwen等等)是在通用大模型基础上继续训练得到的。这两种方式各有利弊,比如DeepSeek Coder的实验发现在通用大模型基础上继续训练会有更好的NLP和Math能力,但代码能力比完全重新训练稍弱。
代码大模型的预训练常见的方法是next token prediction和fill in the middle任务。常见的微调方式是利用大模型来直接生成微调数据,比如Self-Instruct和Evol-Instruct。而两种方式生成的微调数据容易受到模型偏见的影响(比如模型只会生成比较常见的指令数据)。我们去年底提出的OSS-Instruct可以利用开源代码来引导大模型生成更加多样、真实和可控的微调数据。OSS-Instruct以及我们基于此微调的Magicoder模型在GitHub上已经有1900多star。OSS-Instruct也已经被许多其它代码大模型采用,比如最近的Google CodeGemma、IBM Granite Code Models、StarCoder2-Instruct等等。Snowflake Arctic、Meta Llama3以及Amazon Q等团队也在尝试使用OSS-Instruct进行代码模型的微调。
王焱林:
基于通用大模型继续训练或完全重新训练这两种情况都有,例如CodeLlama是基于Llama2通用大模型基础继续训练得到的;StarCoder2系列(3B to 15B)和DeepSeekCoder系列(1.3B to 33B)是完全重新训练的。而且我觉得很有趣的是,DeepSeek选择先训练代码大模型,再训练通用大模型,某种程度上反映了代码大模型的重要性。
代码大模型的预训练方法目前和通用大模型一样,在海量无标签corpus上进行自监督学习,通常是NTP和FIM任务,以前在小一些的预训练模型上,前人尝试过不同的训练任务(如GraphCodeBERT考虑数据流、UniXcoder考虑语法树的任务等),但目前(貌似)还没有adapt到大模型里,训练效率可能是主要原因。另外有些代码大模型在训练时对代码仓库进行拓扑排序解析文件之间的依赖,被证明可以增强长距离跨文件的代码理解能力。
主要的微调方法和通用大模型的微调在技术上并无区别,包括全量微调、Adapter tuning、LORA、QLORA、Prefix tuning、Prompt tuning、P-tuning等,不考虑资源限制的话,全量微调效果好,但大多情况下,资源都很受限,因此现在各种PEFT(参数高效微调)方法非常流行。
刘名威:
根据我的观察,目前性能较好的代码大模型基本上都是从头开始利用代码语料训练的,比如StarCoder和DeepSeekCoder。相比之下,CodeLLama是通过在LLama模型基础上继续训练得到的,效果看起来不算特别好。增量预训练很可能会出现灾难性遗忘问题,导致新模型忘记基础模型已经学习到的能力,反而效果更差,这个度很难把握。
另一个问题可能是分词器和词汇表的问题。基于通用大模型可能需要复用其分词器和词汇表,但这可能与代码领域的需求不匹配。一些代码领域的专业词汇使用通用模型的分词器可能需要拆分成多个token,这会极大影响推理效率。
在训练和微调方面。由于资源限制,我们对预训练涉及不多,主要涉及微调。微调又分为全参数微调和高效微调方法。我们主要使用高效微调,其中LORA算是效果比较好且稳定的,在性能和效果上达到了比较好的平衡。
王翀:
1)两者都有,像CodeLlama是基于Llama2在代码预料上基于训练得到的,而StarCoder和aiXcoder是直接利用代码及相关文本从头开始训练的。
2)目前**生成式**大模型本质上都是在做下一个Token预测,重点在于收集不同类型的数据以及构建不同形式的输入,来实现不同的训练目标和策略。在此基础上,有以下常见的训练和微调方式:
从输入形式上:常见的有自回归训练(Autoregressive)和填空(Fill-in-Middle)。前者主要是训练模型根据前文来预测下文(NL-Code生成、代码续写等场景);后者通过插入、、等特殊Token来让模型根据前文和后文来预测缺失的中间部分(某些补全、修复场景)。
从训练数据类型上:指令微调(Instruction Fine-tuning)通过在指令数据集上对模型进行微调来显著增强模型遵循指令的能力(如张老师团队的OSS-instruct数据集和Magicoder模型);长上下文微调(Long-context Fine-tuning)通过在长序列数据上进行训练并对结合位置编码改进(例如Position Interpolation)来提升模型在长下文代码生成上的能力。上述是为了增强代码大模型自身的能力,当然还可以通过收集其它类型的数据来提升在更多下游任务上的表现,例如测试用例生成、代码摘要等。
李钟麒:
之前老师们也谈到了,其实两种模式都存在,有类似DeepSeekCoder的方式以代码数据为主的预训练模型,也有比如codellama在llama基础模型上进行Continue Pretrain得到的模型;两种方式都可以达到一个可用的状态,关键是算力的投入要足够。
代码模型通常在混合代码+垂域数据的SFT,同时会在一些下游任务上进行对齐;尤其是对于常用开发场景,需要进行进一步的语料扩充与训练;同时类似PPO/DPO的方式进行进一步的偏好对齐能够使得模型快速拟合实际偏好。
曹荣禹:
1、当前代码大模型主要是在通用大模型基础上继续训练得到的还是完全重新训练的?代码大模型的训练和微调有哪些常用方法,其有效性如何?
当前代码大模型大多是在通用大模型的技术上继续训练得到的,例如code-llama、codeqwen等;
代码大模型的训练和微调主要包括如下:
1. 代码数据预训练(Pretrain),一般收集大量的包含代码的数据,让模型做next-token-prediction,让模型学习代码数据的特性、代码数据和自然语言的对应等;
2. 代码数据持续预训练(Continue Pretrain),一般是fill-in-middle的形式,让模型学习给定代码上文、代码下文的前提下,如何预测需要补全的代码;
3. 代码数据监督微调(Supervised Fine Tuning),主要分为两种:
a. 一般是fill-in-middle的形式,主要用于IDE的补全模型,一般称为completion模型,只不过相比于持续预训练,需要对数据进行AST解析,并且针对具体的代码上下文场景构造训练数据;
b. 一般是question-answering的形式,主要用于IDE的代码问答,一版称为chat、instruct模型,针对代码生成注释、代码解释、生成单测、生成缺陷修复等不同任务构造训练数据;
4. 企业数据微调(Privatized SFT),主要用于企业私有化部署的客户,客户提供企业专属的训练数据,并且基于completion模型、chat模型进行进一步的微调,该步骤针对客户的资源情况而定,可以使用全参SFT或者lora SFT。
观点讨论
@彭鑫:嗯,可能也看应用场景,如果是续写和简单的文本到代码生成可能还能应付。但如果用户有反复的交互式迭代精化调整的诉求,那意图理解和文本交互能力可能就会比较重要了。
徐晓强:
编码过程中我们主要使用到两个主要的场景,一个是实时代码续写,一个是chat。
续写场景指的是在给定的上下文,根据用户当前输入的不完整的代码片段,实现对后续内容的补全,以便加速开发者的开发效率。
Chat场景,根据用户对一个技术问题的提问,模型给出解答的过程。包括对熟悉、不熟悉的知识以及通过描述一个需求来生成一个完整的代码片段等场景。开发者可以用自己更熟悉的自然语言方式来实现学习新知识、咨询和生成代码。
这两个场景对于模型的要求是不同的。在续写场景中,保证准确性的前提下,尽可能快地将推理结果展示给开发者,才能有效帮助开发者提升效率。即使推理的结果再准确,但在开发者写完后才推荐出来,也是没有用的。因此速度是除了准确度之外的一个非常重要的指标。
反观Chat的场景,在开发者描述一个问题后,如何准确地理解开发者的真实意图,当前workspace中的哪些上下文更有助于回答和提升生成质量,则是这个场景更关注的,推荐速度就变得没有那么重要了。此外在该场景中,对于自然语言的理解能力的要求要远高于续写场景。
因此基于上面不同的业务特性,模型的训练基座也会有所不同。续写模型通常规模更小、数据更加专一、指令更加单一,因此适合使用一个完全重新训练的模型实现;Chat场景下的模型为了尽可能提升自然语言理解和指令遵从等能力,可以考虑使用一个已有的通用大模型上精调而来。不同场景的模型组成一个MoE架构,从成本和效率上达到最优效果。
在训练过程中我认为有必要重点关注训练的数据。百度Comate在第一版训练时,希望尽可能获取到更多的数据,但数据质量参差不齐,在部分场景下的推荐效果并不理想。在第二版训练时,主要做了按照语言、框架、知识点等多层级的知识整理,同时将低质的数据移除出训练集。经过提升数据质量,在数据规模更小的情况下,模型的效果反而有了明显的提升。
观点讨论
@彭鑫:@徐晓强 嗯,看来要针对不同场景(续写还是交互式问答)训练不同的代码大模型。
王思维:
1)、热启动和冷启动都有,例如CodeLlama是基于Llama2增训得到的;DeepSeekCoder系列从头训练的。openai的codex结论是两者最终效果差异不大;但热启收敛更快
2)、代码大模型的预训练方法和通用大模型基本一致,但是在补全场景会增加fim的训练方式。从代码上文和下文预测中间部分。这种情况在ide补全场景尤为重要。
3)、代码SFT方式主要也都是使用target loss在内的方法进行训练,使用的方式包括全量微调、Adapter tuning、LORA、QLORA、Prefix tuning、Prompt tuning、P-tuning等。和通用场景并无太大差别。
观点讨论
@郭圆平:我对于问题1还有一些疑问,想要请教各位专家老师,就是前面讨论的内容和结论,是否同样适用于训练一个好的文本代码嵌入模型?
@李戈:@郭圆平 是的。
@刘名威:@郭圆平 这方面我们在做一些探索,目前一个有意思的初步发现,似乎用基于通用大模型得到的文本代码嵌入模型,比专门基于代码大模型的文本嵌入模型要好。可能源于通用大模型的文本理解能力在这方面更有优势。
Question 2
主持人:企业在开展面向特定领域的代码大模型微调与定制时可以采取哪些技术手段(例如微调方式和任务)?在数据准备和清洗以及其他关键问题上有哪些需要特别注意的问题?
李戈:
领域数据CT/EPFT/RAG等都是可以用的办法,一些其他的Superalignment的技术也可以起到辅助作用。但这里最重要的,还是数据问题。仅仅使用企业代码数据来进行简单微调的办法通常不能获得足够满意的效果。这里要分情况来处理,如果领域知识的缺失只是表现在缺少相关信息的层面,或许RAG或类似技术会获得不错的效果,但如果领域知识的缺失表现在推理能力不足,也就是说领域知识的缺失已经影响到了模型的推理能力,那就需要更多的领域数据进行训练。
在数据准备方面,理想做法是以全链条开发数据作为原料,但通常企业难以提供这样的数据,也就是说,很多企业在以往的开发中没有对相关的开发数据进行有效的管理,软件制品之间的关系也没有理顺,这是数据治理阶段要解决的任务。在数据治理过程中应该针对不同任务设计不同的数据治理方案,而不应该在不管下游任务的情况下,盲目收集数据,这将直接关系到后续任务的进行。
张令明:
我们这边主要做的是针对常见代码生成问题的指令微调,我们关注的是指令数据的真实性、多样性和可控性,以及数据污染问题。长上下文处理和多样下游任务的微调等在企业真实的软件开发过程中应该都比较重要。
王焱林:
如上个问题讨论的,如果资源有限,可采用LORA等PEFT方法来微调。对于面向特定领域的代码大模型微调,数据准备和清洗尤为重要,因为企业的特定需求可能与模型预训练阶段的数据分布差异很大,例如某企业用一些小众的函数式编程语言、或自研的编程语言,这在预训练阶段受训练不足,需要额外收集足量数据(真实数据或合成数据)来微调模型,在微调数据量要求不是特别大的情况下,大模型+人工共同构建也是可行的。同时,采用多种清洗方法,如去重、去除低质量代码等。
观点讨论
@曹荣禹:@王焱林 您提到的领域性较强的语言,我也在思考这个问题,个人实践感觉输出方不太好处理,因为还需要对语言知识本身有理解,但客户可能了解该语言,但并不太了解应该准备什么样的训练数据,请问这种有什么好的解决办法吗?
@王焱林:@曹荣禹 对于自研语言,要准备的数据和常规语言可能区别不大(代码数据、文档、问答数据等),只是模型预训练阶段可能见不到这样的数据,或者量非常少。所以我认为控制比例,调高目标场景的语言的比例很重要。
刘名威:
企业在开展面向特定领域的代码大模型微调与定制时,可以采取以下技术手段:使用特定领域的代码语料库进行继续预训练,让模型更好地学习到特定领域的知识。在此基础上,可以针对最终应用场景的特定任务设计相应的指令微调数据,对模型进行指令微调,使模型能更好地理解特定领域的指令和输入上下文,并产生符合任务格式要求的输出。
值得注意,其中继续预训练和微调的作用是不一样的。最近有一篇关于LLM微调和幻觉关系的研究,结论大致是大模型主要通过预训练获得事实知识,而微调则教会它们更有效地使用这些知识。如果在微调过程中引入新的事实知识,可能会增加大模型产生幻觉的风险。不过,仍需要注意灾难性遗忘问题。我们之前的实验表明,虽然使用特定领域的代码语料进行了继续预训练,然后再进行微调,最终效果不如直接基于基础模型进行微调。
数据质量可能是目前大模型落地最重要的部分,现在的训练方式可能都差不多。在高质量数据上训练出来的模型,可能比在质量不高的数据上训练出来的大参数模型效果更好,毕竟“garbage in, garbage out”。一些典型的问题包括数据去重、选取高星项目的代码、选择可读性更高的代码(如含有较高比例注释的代码)。
在这方面,我们做了一些探索和实验。我们对大模型生成的代码进行了审查,发现生成的代码存在的质量问题很多可能可以归到训练数据质量问题上。例如,我们发现模型在生成代码时,会生成一段注释,然后是一段代码,其中注释和后面的代码非常相似。我们猜想,可能是因为训练数据中混有低质量的代码。例如,有些人修改代码时,为了保险起见,把旧代码注释掉,然后在下面复制一份并进行修改,最后没有删除注释掉的旧代码。这样的低质量数据被模型学习到了,影响了最终效果。所以应该从代码质量尽可能做一些清洗,把一些低质量不正常的代码一定要去掉。
王翀:
在资源受限的情况下,可以使用一些参数高效的微调(PEFT)方法,但个人觉得重点还是落在微调数据的收集和构造上。
在通用代码大模型的训练和微调中,已经有一些被证实有效的数据清洗实践,例如启发式规则、代码去重、依赖解析、静态缺陷扫描等。在面向特定领域微调的场景下,我们需要重点考虑如何筛选出那些未被开源项目和Foundation模型覆盖到的数据和知识。这块我认为可能涉及到很多特定领域软件知识的收集和挖掘的问题,需要在已有数据清洗实践的基础上结合相关领域背景知识(例如相关概念知识)来收集和筛选出高质量的、高多样性训练和微调数据。关于领域知识挖掘方面彭老师团队已经有很多积累,我目前也在NTU刘杨老师团队做一些上述的数据收集和清洗的相关探索。
李钟麒:
对于数据量不是很大的企业,可以考虑走lora模式,在一个较好的L0上进行轻量级微调,如果数据量偏大,可以考虑全参SFT/二阶段预训练+SFT的方式进行;通常情况下任务主要集中在下游应用场景如实际的代码生成补全/UT/研发问答等常用的任务上;对于一些有特殊诉求的场景,可能需要独立任务演进;RAG在分布有偏的情况下可以在一定程度上缓解生成相关性问题。
在数据上要对质量进行一定程度的把控,避免junk in junk out,同时避免大量新数据带来的灾难性遗忘问题;如果私有数据与L0分布偏差较大,可能需要考虑混合通用数据进行微调以保障模型收敛。
曹荣禹:
企业数据微调(Privatized SFT),主要用于企业私有化部署的客户,客户提供企业专属的训练数据,并且基于completion模型、chat模型进行进一步的微调,该步骤针对客户的资源情况而定,可以使用全参SFT或者lora SFT;当前通义灵码在这个方向经过打磨,已经开始向企业用户进行输出了。
数据准备和清洗上需要注意的点:
1. 企业用户准备的数据尽量多样,需要企业自己针对性地提供一些质量筛选策略,例如通过python的PEP8,并且最好能有类似github提供的点赞、收藏等metadata用于评估代码的质量;
2. 用户准备的数据需要进行一些文本级别的清洗,例如对行数较多的文件、某些行长度很大、注释比例较低的文件等进行筛除;从而留下较为优质的代码文件;
3. 数据准备阶段需要对用户的代码进行AST解析,从而针对具体的代码上下文场景构造训练数据;
4. 在我们的实践过程中,我们会在Privatized SFT过程中加入一定比例的Supervised Fine Tuning的数据,从而使模型既能学习企业客户的代码数据,也保证通用能力不丢失。
薛增奎:
企业在开展面向特定领域的代码大模型微调与定制时可以采取LORA微调和全参微调;在代码领域的数据主要考虑代码数据的质量和数量;一般单个应用场景数据量至少达到1W条以上,才会取得比较好的微调效果。
徐晓强:
我们认为相较于sft,通过RAG等技术增加输入更相关的上下文,更有助于提升推理结果。
在百度内部,我们也有过一次对比。基于同一个版本加入一定比例百度私有的代码,在实际场景中这部分模型的效果较纯开源的数据集没有明显的提升,甚至有部分退化的现象发生。究其原因就如同上面一个问题中提到的,部分代码片段的质量还是较差的。我们也在其他场景中使用相同的微调方式验证过,结果与百度内部类似,都没有明显的效果提升。
反而在RAG技术逐渐成熟后,我们也验证了提供更多相关上下文的实践,效果提升还是非常明显的,百度Comate当前Autowork的能力就是基于RAG技术实现。一方面对于模型本身的侵入性基本为0,在后续模型迭代的时候这部分定制的成本为0,也没有引发针对一个场景sft后导致其它场景退化的现象发生。相比较下RAG在检索速度上确实有一定的损耗,但尤其在chat场景下的耗时占比较小,同时也有各种工程化的手段来优化检索速度。
在准备RAG的文档时,理想的情况是针对一个框架、api、需求,能够有总览的介绍、领域知识的介绍、每个api的说明以及对应的示例代码,内容越完善,质量越高,则推荐的效果越好。
观点讨论
@彭鑫:@徐晓强 但是特定领域的API和概念等不经过微调仅靠RAG是不是无法让大模型有所理解?
@徐晓强:@彭鑫 那倒没有,我们也试过将一个框架的api和调用样例文档作为索引知识输入,让模型去推理调用这个api的代码,效果还不错。目前有些内部的框架也在用类似的方式生成代码。
@朱少民:@徐晓强 把私有代码库可以作为文档,可以采用RAG技术引入吗?
@徐晓强:@朱少民 私有代码库可以作为RAG引入。需要对代码库做一次向量化的索引,之后在生成和问答时候都可以得到更贴合这个私有代码库的推理结果。
王思维:
特定领域的模型可以尝试在通用代码sft上继续精调;这样一般能有更大的收益。
数据的构造需要保证以下几点:
1.数据质量:确保训练数据的质量,包括数据的准确性、完整性和一致性。
2.数据代表性:最好能涵盖领域内的各种用户情况和场景。避免数据偏差和过拟合。
3.数据平衡:确保各类别的数据分布平衡,避免类别不平衡问题,这个需要对数据有一个完整的类目体系建设。
4.数据清洗:去除训练数据中的噪声、重复数据和无关信息,可以通过一些工具或者reward model进行打分。
5.数据隐私:在处理敏感数据时,确保遵守相关法规和政策,对数据进行脱敏处理。
6.模型泛化能力:通过数据增强等方法提高模型的泛化能力,避免过拟合。
7.模型评估:选择合适的评估指标和体系模型进行全面评估,例如实际场景中humaneval往往是不够用的。
观点讨论
@袁志强:@王思维 当微调方式选用SFT时,它和哪种微调任务(例如 fill-in-middle, next-token-prediction, instruction tuning)搭配是能够最大限度的提升模型在下游任务上的效果的,有这方面的尝试吗?
Question 3
主持人:企业在代码大模型落地应用时,如何将提示工程、上下文学习、多Agent、检索增强以及各种后处理技术与模型微调有机结合,从而提高代码推荐和生成的准确性?
李戈:
今年5月,在华为的“智能化软件开发”讨论会上,我曾经分享过:基于大模型的辅助编程的1.0阶段已经过去了,在这个1.0阶段中,大模型以单一的交互模式服务于单一的开发任务;而现在已经进入了基于大模型的软件开发的2.0阶段,就是要借助多Agent等技术将开发过程链接起来,通过与大模型的多环节多方式的交互完成开发任务。例如,在提升代码推荐和生成准确性方面,可以参考我们组最近的一些工作,例如Self-collaboration Code Generation [TOSEM,2024] ,CodeAgent [ACL 2024], Prompt with Actor-Critic Editing[ACL 2024]等。
这不仅仅体现在代码推荐和生成的准确性方面,在其他软件开发任务上,如测试案例生成、Bug修复、Code Review等场景中,也需要利用类似的机制来提升效率。
张令明:
我期待企业界朋友们的回答。我的感觉是模型微调和模型与预训练的界限越来越模糊了。会有越来越多的下游任务出现在大规模的微调甚至是预训练过程中。
王焱林:
目前多数提高代码生成准确性的论文只研究某个单点技术的改进对效果的提升(如提出一种更好的RAG方法等),但落地的时候,往往需要多点技术合力加持,比如在训练阶段先进行任务特定的微调,在推理阶段利用提示工程技术、multiagent、RAG等,在推理阶段后进行后处理,每个部分都需要。目前我们在探索一个方法,在RAG代码生成的过程中,通过强化学习来微调检索模型,改进以前只检索相似代码带来的问题,如检索器依赖有标签数据、候选代码块语义不完整、不加选择地检索等问题。虽然不是多点技术全部考虑,也初步得到了不错的代码生成效果提升。
刘名威:
赞同李戈老师的观点,提示工程、上下文学习、多Agent、检索增强以及各种后处理技术这些技术现在都被广泛使用来提升特定场景、任务的效果了。微调可能不再是唯一的提升效果的手段,成本也比较高昂。接下来应该会更多转向Agent类型的技术,利用大模型强大的能力完成各项任务,具体的方式可能就需要针对场景来综合设计了。
可能需要进一步发挥软件工程工具的作用,比如静态分析工具。我们最近的一项工作探索了如何利用静态分析工具提升大模型在仓库级别代码补全任务上的效果,减少幻觉问题(例如使用不存在的变量和方法)。一种方法是将静态分析工具的结果结合到大模型生成的各个阶段。例如上下文选择,解码,后处理等等。需要更加精细的设计来达到更好的效果。但是底座模型其实不需要变。
观点讨论
@彭鑫:@刘名威 那你是否同意特定领域微调完全不需要,转而主要依靠提示工程、上下文学习、多Agent、检索增强以及各种后处理技术?
@刘名威:@彭鑫 嗯,我觉得目前试下来,如果基座模型足够强,领域微调可能带来的收益不是特别明显。反而不如rag,传统工具结合的方法。
@薛增奎:@刘名威 我认同刘老师这个观点,我们现在也在进行这方面的尝试,就是传统的一些方法,比如已有的静态分析工具,与大模型联合输出解决方案,效果可能是1+1>2的。
@彭鑫:@薛增奎 静态分析工具与大模型联合输出解决方案是指将来静态分析用于RAG和多Agent等处理环节中?
@薛增奎:@彭鑫 不是简单的先后的关系,而是深度的融合,静态分析有他的成熟优势,模型有模型的优势,可以尝试静态分析的过程进行拆解,小的阶段步骤中融入模型能力。同时将静态分析的过程数据和能力融入到RAG和multi-agent中。
@彭鑫:@薛增奎 嗯,说的不是顺序,而是说RAG、多Agent等技术中融入静态分析。例如在RAG的检索过程中使用静态分析。
@王翀:@薛增奎 这方面我们也有一些探索,在大模型生成过程中在恰当的位置调用静态分析工具提供合法的候选项。
@薛增奎:@彭鑫 是的,彭老师。
王翀:
在实际应用中,大模型会遇到很多挑战,背后的因素有很多,我主要从大模型学到的知识的角度来回答。一方面,代码大模型应用在实际开发中时存在知识缺失问题,由于没有见过项目内自定义的类和函数,会产生很多错误依赖(如调用不存在的方法)和幻觉问题。针对这类问题,可以使用RAG、工具集成、多Agent等方式来为大模型提供相关后验知识(例如合法的方法调用候选),提升大模型代码生成的正确性。这块李戈老师团队已经有很多进展。另一方面,代码大模型也可能学到了很多错误或者过时的知识。例如,在库的持续演化过程中,某些已经被弃用的API仍然被包含在了大模型的训练数据中,导致训练后的模型会预测出这些弃用甚至是包含安全问题的API。我们最近的一项study对这一问题进行了证实。针对这一问题,可以探索使用一些模型修复的方法来修复这些有问题的先验知识,或者使用RAG以及多Agent等方式在生成过程中增加后验知识(例如相关API弃用说明)来避免相关问题。
彭超:
以代码补全为例,检索增强和后处理技术都可以提高推荐代码的质量和准确性。检索增强的实践包括在prompt中包含最近打开或编辑的文件内容、当前文件所在路径,以及通过静态分析或embedding检索的方式对当前代码仓进行相似和关联代码检索,以提供给模型更多的上下文信息。
后处理的实践包括过滤或修复有明显语法错误的代码、对缩进和代码格式进行修正等。
随着SWE-Bench的提出和Devin的爆火,各类LLM-based agent和这些技术结合的工具在更复杂场景的代码生成和代码编辑也取得了惊艳的效果,如完整实现一个feature或修复一个issue。
李钟麒:
首先模型需要具有较强的能力;对于指令的遵从性以及泛化性需要较强,才能结合ICL/RAG的方式进行生成,另外结合上下文/前端IDE的能力对解码进行干预,减少模型生成幻觉,也是一个可以考虑的方向;多agent目前也是一个比较有意思的方向,大家最近刷得比较多的swe-bench就是一个利用多agent来解决实际问题的很好的例子。
曹荣禹:
1. 可以通过对代码数据进行AST解析,并且针对不同语言、不同补全场景的上下文情况下,收集对应的SFT数据,从而让模型学习在各种上下文场景下生成精确的推荐;
2. 多家企业现在已经支持了类github workspace的功能,如baidu comate autowork、alibaba lingma workspace等,主要利用multi-agents、rag等技术针对仓库代码问题、仓库级别根据用户需求生成修改建议、仓库级别debug的能力;具体地,用户询问“如何增加删除按钮”、“密码验证逻辑在哪个函数中”等类似的问题时,模型会判断需要使用的agent,并且同时对用户仓库内的代码进行切片、计算embedding等方式,召回可能需要参考/修改的代码片段,最终生成回复或者修改建议。
徐晓强:
这是一个系统的问题,在百度内部落地时确实有各种不同的方式来实现不同的业务需求。有些业务团队更希望能够按照自己的要求来实现代码,因此在prompt上有与其他团队不同的定义,有些团队或产品使用agent的能力来连通编码现场与对应平台的能力,有些团队也需要使用RAG来增强自己研发的框架代码。这些场景都需要在工具层面有足够的开放性和灵活性,能够实现工具的对接和生成效果的提升。
百度Comate有个开放平台的功能,建立起三方插件和开发者之间的桥梁。总体从能力扩展(更多研发场景智能插件),知识扩展(对接私域知识),模型扩展(模型精调)打造组织自有的研发助手。
具体举例来说,百度Comate集成了PaddlePaddle知识扩展的插件,能够基于PaddlePaddle的官方文档,提供更贴切和准确的知识问答能力,同时内部也有类似多个插件,来实现不同框架生成准确性的增强;部分部署平台也结合自己的智能体能力,通过百度Comate作为入口,实现特定的CICD流程,减少常见动作的操作步长。
王思维:
问题3这个其实看具体场景,例如对一些需要模型遵从特定指令输出的场景,需要比较好的提升工程和上下文学习;对于一些需要外部知识的场景,如特定领域的问答或者业务代码补全,通过检索的方式能给模型一个很好的提示。Agent这块其实对模型综合能力要求很高,包括代码长文理解,多轮理解,以及代码修复能力,这些都需要sft进行加强。
在模型微调上,其实要注重sft数据中的icl数据和复杂指令数据,这部分数据能提高模型的指令遵从能力。sft之后模型的icl能力一般会弱化,这块可以通过数据补充进行加强,更好支持提示工程/上下文学习等。
Question 4
主持人:企业在代码大模型落地应用时有哪些比较成功的应用场景(例如代码补全/生成/重构以及软件开发问答等)?为了实现软件开发质量和效率提升,需要如何度量代码推荐和生成的质量(例如采纳率或其他指标)?还需要考虑哪些人机交互(例如如何掌握代码补全和推荐的时机)及其他方面的问题?
李戈:
(1)企业在代码大模型落地应用时有哪些比较成功的应用场景(例如代码补全/生成/重构以及软件开发问答等)?
从当前应用情况看,“代码自动补全”的确是应用最广、使用量最大的场景;其次,代码生成、代码缺陷自动检测 或 代码检视、测试案例自动生成等都是常见的应用场景。
(2)为了实现软件开发质量和效率提升,需要如何度量代码推荐和生成的质量(例如采纳率或其他指标)?
关于代码推荐和生成的度量指标,的确有很多指标,如EM、BLEU、CodeBLEU、采纳率、自动生成占比等,但在实际应用过程中,不同的指标有不同的实际应用问题。
经过我们的探索和实践,“自动生成占比”(或 采纳代码占比)可能是大家最易接受,且比较直观反映代码大模型实际能力的指标,这也是被很多开发者接受和采纳的一个评估指标。究其原因,一方面这个指标是一个“实测指标”,而不是一个“基于已知结果”计算而来的指标;另一方面,这个指标融合了很多权衡的结果,例如代码生成长度、代码推荐速度等多方面。
(3)还需要考虑哪些人机交互(例如如何掌握代码补全和推荐的时机)及其他方面的问题?
仅就代码补全而言,通常需要考虑的相关问题包括:推荐反馈速度、推荐长度、多推荐结果的处理等。除此之外还需要考虑如何多GPU处理并发,如何收集错误反馈等问题。
张令明:
根据我的了解,代码补全和开发问答等在许多公司都有成功的案例,相信很多企业界的朋友会提到。代码重构,特别是大规模系统的重构需要大模型对代码有深刻的理解能力,目前的大模型可能效果还不是特别明显。非常期待企业界朋友的补充。
在我们研究小组我们最先关注的是软件测试和程序修复问题。在这两个问题上大模型在很多场景下都可以超越过去十几年甚至是几十年来的传统研究成果。大家可能会问为什么我们主要关注这两个问题。首先这两个是非常经典和重要的软工问题,也是我们小组过去十几年的主要研究方向。其次,这两个问题基本都主要用到了大模型强大的生成能力,而对大模型的效果也都有很好的自动评判机制,比如软件测试我们可以用传统系统测试的断言而程序修复我们可以用测试集合来自动过滤补丁。除此之外,和传统的技术相比大模型有更好的实用性(实现开销非常低)和适用性(直接适用于不同的软件系统和语言)。有趣的是即使是大模型的主要缺点(hallucination)也在这两个问题上变成了优点:可以帮我们生成更有趣的测试和更多样的补丁。
王焱林:
在落地应用方面,华为云盘古研发大模型,在通用代码能力、专用场景、应用成熟度等方面表现突出。DeepSeekCoder以小而精取胜,33B的模型大小,超越了闭源模型GPT-3.5-Turbo,是最接近GPT-4-Turbo能力的开源代码模型,虽然DeepSeek没有直接做应用,但有不少企业都在使用。
在度量指标方面,目前代码生成的metric包括EM,ES,Pass@k,采纳率等偏单点的指标,可能未来需要一些综合性指标,如 “开发时间”可能当做一个新指标,因为单点指标高(如函数级代码生成的采纳率高),不一定意味着总开发时间会降低,可能采纳了某段代码后,程序员还需要额外的时间去理解和调试模型生成的代码。另外,盘古研发大模型的推文中,有一个3大能力域、16个能力项的多维度指标,也有参考借鉴意义。
刘名威:
1)在小规模的代码补全和单元测试生成方面,以及一些小规模的原子功能的函数实现生成上,大模型的效果还是很好的。然而,在复杂业务场景中的表现就不尽如人意。使用的时候补全粒度和上下文依赖不能特别大。例如我们的一个工作就评估发现,LLM在类级别的代码生成任务上表现很差。
在一些维护类型任务中,大模型的表现也还不理想,比如添加特性和修复复杂的BUG等任务。由于这些任务的上下文特别复杂,目前即使是号称最先进的基于Agent的技术,效果也只有20%左右,并且还依赖于很多理想化的假设。特别是大模型目前输入窗口的限制和长上下文理解能力不强的现状,制约了其大模型的效果。
2)如何度量代码推荐和生成的质量这个没有比较好的方案,可能可以从采纳率、编译通过率、代码留存度这些方面进行一些衡量。
3)人机交互方面,感觉除了适时的代码补全和推荐以外,一些面向用户的个性化可能是需要考虑,比如推荐结果考虑用户的编码习惯、命名风格、习语使用、三方库偏好等等,这个可能可以提高人员对于解决的可理解性和接受度。另外一个方面,生成结果的可读性可能是需要考虑,如果开发者看不懂推荐结果,可能就完全不会采纳了。
王翀:
这些问题我觉得各位企业专家非常有发言权。
针对第三个小问题,总体来说我觉得需要让大模型对整个开发环境和当前上下文态势有一个更全面的感知(例如使用一个专门的Agent来实现环境感知和任务调度),才能实现更好的人机结合。
彭超:
较为成功和使用频率最高的场景应该还是代码补全和研发问答。对于代码补全而言,除了采纳率还有一种更为全面的名为CPO(Character per Opportunity)的指标,CPO是通过计算每个机会中平均字符数来衡量的代码补全工具的表现的。机会指的是用户在IDE中进行操作的每个动作,例如输入或删除一段代码。
CPO的计算公式是CPO = 尝试率 * 反馈率 * 采纳率 * 每次采纳平均token数 * 每token的平均字符数。
尝试率是指在每次可能给用户补全代码的机会中,工具实际为用户提供建议的频率,弥补了“不推荐就没有拒绝”的问题。
反馈率是指有多少工具生成的补全建议最终被展示给了用户,当网络延迟过高、用户持续键入时,会导致较低的反馈率。
采纳率即为用户实际采纳了多少工具推荐的代码。
每次采纳平均token数反映了每条被采纳建议所传递出的实际价值,而每token的平均字符数可以平衡不同模型的分词器导致的tokne可以代表过长或者过短字符串的问题。另外,工具补全的代码实际被合入代码仓的比例也是值得关注的一个指标。
李钟麒:
目前来看对于一些片段型的生成,如UT/debug等任务,能够相对独立的完成,研发问答类场景也能结合RAG得到较好的回复,对于一些复杂性较强的工程化生成,还需要进一步的提升;
最好的评价其实是基于testcase的正确性反馈/人工的评估反馈,但是实际很难做到,目前主要以接受率为主;另外产品的体验会在很大程度上影响用户的接受率,正确的触发时机也会影响推理成本以及用户体验,产品侧可以结合如意图识别/生成请求判别等简单模型来优化体验,这些都是可以考虑的。
曹荣禹:
通过通义灵码的使用情况来看,代码补全场景是用户使用最频繁的场景,在开发问答场景中,通用领域的开发问答是用户使用最频繁的场景,单元测试生成则是用户非常关注和具有很大需求量的场景,特别是针对企业用户。代码重构、代码缺陷修复、代码注释生成、代码故障分析也是用户非常关注的问题。
为了实现软件开发的质量和效率的提升,衡量代码推荐的质量中常用到的指标有在线用户采纳率、代码生成占比、平均采纳代码行数;
1. 采纳率体现了用户对模型推荐的满意度,质量更高的推荐、不打扰用户的推荐更可能会被采纳;
2. 代码生成占比则体现了代码助手对用户开发效率的提升,代码生成占比越高,说明越能帮助用户提升效率,因为这样用户更多的tab就ok了;
3. 平均采纳代码行数业界提的较少,但是通义灵码发现,往往推荐出来的多行且高质量的内容,能大大提升效率,并且使得用户更加信任代码助手,例如当模型能正确地推荐一个函数、一个for循环的时候,用户会觉得代码助手更加智能;
代码补全和推荐的时机也是另一个非常重要的问题,主要体现在不打扰用户编码过程中的思考,通义灵码针对性地分析了一些日常使用场景中遇到的不良触发时机,在这些时机不触发补全模型,并且在模型侧也增加模型对一些场景判断补全为空的能力,从而减少对用户的打扰;这一方面灵码也在持续地优化中。
薛增奎:
目前企业在代码大模型落地应用时比较成功的应用场景有:智能问答(技术知识答疑、技术知识搜索、疑难问题解决、技术方案输出等等),代码补全和生成,单元测试生成,代码解释和代码调试。
为了实现软件开发质量和效率的提升,我认为比较好的度量代码推荐和生成质量的指标是代码采纳率、AI代码生成占比和CPO。
人机交互层面我认为掌握代码补全和推进的时机不应该是人机交互考虑的,而是代码服务(工程层及模型层)考虑的,对用户行为的识别与判断的考验,同时考虑千人千面,每个用户的行为习惯/思维习惯、组织规范要求等等。
徐晓强:
先看一些客观数据,百度内部去年80%+的工程师在使用百度Comate完成自己日常的工作,27%入库的代码由百度Comate辅助生成,整体采纳率达到46%+、头部用户采纳率达到60%+。无论从用得多不多、推荐准不准等多角度看,可以说数据上相当亮眼。我们综合了多种结果,测算得出有了百度Comate的辅助,一年的研发效率提升了10%+(无论从完成需求的数量上,还是单个需求完成的时间上都有提升)。
从推荐的体验上来说,有不少需要衡量和权衡的场景,需要单独处理。什么场景下优先推荐多行、多行推荐多少行体感最舒服、如果遇到重载方法如何推荐、如何和已有的代码片段融合等都是需要不同的策略和思考的,每个产品应该都有自己不同的主张和特点。
观点讨论
@赵俊民:@徐晓强 这个数据很牛,目前我们在测试阶段,不到10%。
@徐晓强:@赵俊民 确实,在落地过程中也有不少和业务线同学一起发现让大家更好用起来的技巧。整个指标也都是逐步提升起来的。
@王思维:@徐晓强 这块采纳率是按采纳行数/总行数 还是按采纳字符/总字符呀?
@徐晓强:@王思维 行数。字符数我们还有留存率一个二级指标来观测,比如x分钟后采纳且未被修改的字符比例,1分钟的留存率也在90%+。
@王思维:@徐晓强 这块想问下当时没有考虑用字符数统计的主要原因是什么呀?是因为模型每次推荐的字符数量差别比较大吗?
@朱少民:@王思维 这样度量是不是有问题?理想情况是功能点、对象点、故事点?
@徐晓强:@王思维 也不是,我们最初的想法是想尽可能让采纳这个动作能够是一个完整的人类行为,观察字符的结果不具备实际的应用效应。我记得曾经有个文章说用奖励模型优化llm,最终它会倾向于输出高更少的内容,这种优化在实际应用中属于负优化了。
@朱少民:@徐晓强 采纳率和入库率为何相差那么大? 另外,采纳或入库里面可能包含了不同的尝试次数以及人工review的时间,这些因素是不是也要度量?
@徐晓强:@朱少民 一些是代码是用其他工具生成的,如按照模板生成代码,不一定全是人工编写的代码。另外也有一些代码内容是工具还不支持推荐的。您提到的第二个问题,我们也考虑过,通过编写一行代码的时间和理解+采纳决策的时间来衡量效果的差异,能够得出研发效率的提升。另外就是pair code review,百度一直有代码评审的要求,因此在这里基本没有额外的时间和人力投入。
@乔梁:@徐晓强 入库中 27%是生成的,那么,入库总量提升了多少,也是27%吗?
@乔梁:比如,原来没有ai助手,百度月人均入库6000行,现在有了ai助手,总入库量是不是月人均就到了 7800行。
@徐晓强:@乔梁 入库总量的变化斜率没有27%高。
王思维:
1、从应用场景来看代码补全和text2sql之类的bi分析都有比较大的需求量;另外chat场景下的代码生成和代码修复也都使用比较多;其他比如代码cr等在代码提交中也非常有帮助;
2、评估指标上不同业务有不同的参照,例如采纳率和生成率在代码补全下非常重要;可执行率和准确率在bi场景下是衡量标准;代码修复目前我们没有发现特别公用的评测集。这个也欢迎各位专家补充,代码生成可以参考humaneval和live bench的pass@1,这个还是比较能反映模型效果的。
观点讨论
@薛增奎:@王思维 我认为humaneval和live bench的pass@1对于一些复杂业务场景下对于代码生成的评测就比较局限了。目前行业内还没有一套完善的评测集,导致各个厂商都在积极建立自己的评测体系,会在humaneval和MBPP等基础上考虑更多的业务场景,就是希望能够缩短基于评测集的评测结论与人工实际体验的结论的差距。
@王思维:@薛增奎 是的,这块其实也需要结合业务场景进行评测 目前这两个可能只是评测模型的基础能力。
@刘名威:@薛增奎 是的,我认为更加真实的评测大模型在复杂场景下的能力,也是一个非常必要的工作。我们也一直做些相关尝试,构建对应的benchmark。这样才能知道未来改进方向。humaneval这种还是太简单了,都是不到10行的原子代码。
Question 5
主持人:当前企业应用代码大模型主要是完成一些简单任务(例如局部的代码补全与生成),那么代码大模型是否有可能支持更加复杂的开发任务(例如更大范围内的生成式软件开发以及大规模软件的维护型任务等)?为此需要解决哪些关键问题,有哪些初步的思路和方向?
李戈:
正如前文所述,大模型辅助编程的1.0阶段已经过去了,已经进入了基于大模型的软件开发的2.0阶段,就是要借助多Agent等技术将开发过程链接起来,通过与大模型的多环节多方式的交互完成开发任务。在这个阶段,很多企业已经在考虑“如何利用大模型完成更加复杂的开发任务”,例如需求如何处理、如何辅助进行软件设计等问题。
这些问题的讨论已经涉及到了企业软件开发流程、开发方式的问题,预计在未来一段时间,会在一些企业的某些环节先建立一些探索性应用案例。但正如软工领域的很多其他问题一样,对于其中包含的技术问题的探讨,可能会跟随应用的探索而逐步展开。
观点讨论
@乔梁:@李戈 现在就进入2.0时代啦?
@李戈:@乔梁 借用一个说法而已,不用太认真。
张令明:
当然大模型在业界已经得到了广泛的部署和应用,比如现在已经有超过一百万的程序员在使用GitHub Copilot而Copilot也号称可以帮助程序员提效50%。但正如Copilot的命名,目前来说大模型主要是作为副驾驶这么个角色来辅助程序员完成一些简单的任务。在不久的将来,我相信大模型可以支持更加复杂的开发任务,并在某些任务上取代人类作为主驾。在这个方向上,强大的基座模型支持和更好的模型编排和微调都很重要。相信企业界的朋友们已经有很多有趣的大模型和Agent系统的案例分享。最后我想加一句我个人的看法,单纯靠现有的大模型设计和scaling law去完全取代人类程序员是不太现实的,因为现有模型基本只能模拟人脑中非常小的一部分语言处理和生成区域。未来我会期待更多的人机交互的工作或者是颠覆性的代码大模型设计。
王焱林:
当前模型在处理更为复杂的仓库级代码任务时仍面临挑战,例如仓库级问题修复、代码生成方面。在问题修复数据集SWE-bench的leaderboard上,榜一Amazon Q Developer Agent也只有13.82%的通过率。利用RAG的GPT-4模型也仅取得了1.31%的通过率。需要提升代码大模型的大代码仓理解能力、任务规划和分解能力,以及继续提升局部的代码生成能力对仓库级能力的提升应当也有帮助。目前主流的思路是采用多智能体技术来解决仓库级别问题修复任务中的上述问题,并可以针对性的提升long context理解能力、相关代码检索能力、错误定位能力等。
刘名威:
我觉得是有可能支撑更加复杂的开发任务的。比较大的可能也是现在大家在尝试的就是基于Agent的思路。但是这方面应该还有不少难点,例如大模型如何更好地使用工具,理解各种工具反馈,遵循复杂指令的能力。长上下文理解能力,多轮对话后的历史遗忘问题等等都是需要解决的。这些都需要模型的基础能力有更大的提升。
针对一些小点,目前一个可能的思路是通过针对性的微调来对应增强能力,比如收集各种工具的反馈构造指令微调数据,加强大模型对于这些反馈的理解能力。以及基于工具反馈去让大模型能力与工具反馈对齐等等。
王翀:
个人认为支持大范围软件生成和软件维护是可能的。实现的途径包括利用多Agent对复杂任务进行拆解和规划,结合RAG和一些成熟的分析工具,来协同完成最终目标。
除了相关算法的设计之外,其中还有很重要的一点是对相关软件制品的数字化和知识化。例如,在对复杂软件进行维护型任务时需要对相关代码及所涉及到的业务知识进行全面的理解,这些知识经常分散在整个软件制品的各个部分(代码、文档、配置文件等)之中,大模型或Agent需要获取和整合这些信息来进行更好地决策和答案生成。因此,我们需要构建一套能够对复杂软件制品进行细粒度语义标注、建立知识之间的追溯关系、且支持知识同步演化的 “代码数字孪生”平台,这也是彭老师一直倡导的。
观点讨论
@彭鑫:目前围绕SWE-bench做的全自动开发问题解决的路子是否具有长期价值,这个大家怎么看?光是其中的修改位置定位就非常难,因为高层问题到底层代码之间经常还有很多层的设计拆解,而目前的方法基本都是用各种信息检索方法确定大致相关的代码内容然后再求助大模型。有些简单的问题确实可能能这样解决(目前有些工具可以刷到20%左右的成绩),但更多的问题还是要靠人机协作来解决。
彭超:
如在第三个问题中所说,当前学术界和工业界也在积极探索将agent技术和代码检索、静态分析等结合,来实现完整的feature开发和issue解决,我们也预期基于大模型的技术可以实现整个工程的重构或者语言迁移。为了实现这些目标,有一些问题需要解决,包括任务的拆解和规划能力、复杂上下文的理解能力、生成代码的正确性和一致性等。
任务的拆解和规划能力是指将复杂的大任务分解成一系列可管理的小任务,并为每个小任务制定详细的执行计划,或者在已有的计划中选择最优的计划去执行。这种能力对于软件开发尤其重要,因为开发过程通常包含多个相互关联的步骤和任务。优化的方向可以包括针对任务分解的模型训练、构建包含软件开发领域知识的知识图谱等。
复杂上下文的理解能力是指在复杂的软件开发和维护中,对代码和文档的理解能力,需要通过改进注意力机制、层级模型等方式来优化。
为了提升生成代码的正确性和一致性,我们可以考虑通过开发更适合大模型的轻量级代码分析工具、形式化验证等方式最模型生成的代码进行验证,并通过反馈和迭代的形式让模型生成更高质量的代码。
李钟麒:
目前强模型+多agent协同的方式在当前的情况下有一定解决问题的能力,但是在更复杂的任务上,表现尚未达到预期;在代码模型上目前还停留在纯语言模型的阶段, 大胆设想一下多Agent协同 +(代码)多模态 + 执行沙箱 的模型可能会是一个解决的问题的方向,难点在于可能需要用test driven的方式出发,并且如何一步一步的引导智能体向目标逼近。
曹荣禹:
复杂的开发任务一般是开发者日常开发过程中的项目级别的开发任务,包括分析用户/产品提出的需求、组织搭建或者修改项目树结构、特定文件中增加/删除/修改对应的代码片段、寻找项目中的bug和异常等任务,这些任务需要模型能力进一步提升,不仅仅理解单个代码文件,而是理解项目结构、理解项目架构和逻辑、将用户需求对应到需要修改的代码片段上、对异常错误能知道如何定位和修复,这些能力需要rag、multi-agents、模型self-evolution、execution feedback等技术的支持,通义灵码在这些方面正在探索中,并且会将最新的成果集成到IDE中。如最近上线的库内问答和lingma workspace功能,针对用户需求在项目中查找和修改代码。
薛增奎:
未来是完全有可能完成更加复杂的开发任务的。想要达成这种效果我认为还需要解决如何把更多的项目相关的需求、代码、issue等等知识给到大模型,并且让大模型理解这些知识并进行任务拆解、完成具体的设计生成、代码生成、用例生成等子任务。
观点讨论
@朱少民:@薛增奎 但人的参与是少不了的,毕竟需求是不断澄清的,而且软件是为人服务的。
@薛增奎:@朱少民 我认可朱老师的观点,人的参与是必不可少的,但我相信随着技术的发展,人工参与的事情会逐渐减少并达到一个平衡,比如现在人工参与80%AI参与20%,不远的未来可能是55开,再未来80%AI完成,20%人工完成。软件是为人服务的。
@彭鑫:@薛增奎 按照Brooks关于软件开发的本质性困难和偶然性困难的说法,是不是目前大模型代码生成只是在偶然性困难的层面上提供支持,这些问题解决完之后接下来AI参与占比提升的曲线可能会越来越难以上涨了。
@彭鑫:另外,代码生成比例的提升与开发效率的提升可能并不是同步的。比如有专家谈到当代码生成比例达到70%之后,再继续提高到90%甚至更高也不是不可能的,但这样做不一定是合算的。这也很好理解,我们很多时候也感觉交代别人办事的时候到了一定程度之后让别人做可能要花10分钟(为了把事情交代清楚)而自己做可能只要1分钟。
@薛增奎:@彭鑫 我认为是的。
@赵俊民:@彭鑫 应该在本质困难提升才是大模型价值。
@朱少民:@赵俊民 LLM其实是可以,在知识量、读取代码量、代码理解能力等可以超过大部分开发人员,即使现在没有,未来1-2年就可以。
@彭鑫:@朱少民 可能没那么乐观。目前大模型的进展主要来自AI领域,而软件开发还是有一些自身的门槛和特有的困难的。
@彭鑫:大模型是一个能力的放大器,在高手手里能发挥更大的作用,而在普通程序员手里则效果一般。当然从软件工程领域开展一些研究帮助普通程序员获得更高的基于大模型的软件开发能力提升可能有一定希望。
@朱少民:@彭鑫 这个同意,人机交互,人的能力越强,相互启发、取长补短等更显著。
@刘名威:@彭鑫 同意彭老师观点,不同水平的人用大模型效果也不一样。我们目前其实是希望把高手使用大模型的技巧经验,做成工具来帮助初级程序员。
徐晓强:
我的看法是目前主要的局限是大模型对于一个系统的认知还不足够。为什么当前阶段大众普遍不认为它能够独立完成一个复杂的开发任务,一是因为它本身对于业务和跨领域知识的理解还不足够,二是对于整个工程、需求的理解还不足够深入,但有希望的是我们确实可以在需求明确的简单任务上相信大模型的生成结果。基于单个Agent,甚至多个Agent联合的智能体,我们可以把agent当做积木,发挥多个agent结合的效果。
观点讨论
@彭鑫:@徐晓强 如果不做任务拆解或者拆解粒度和顺序不合适,那么即使用多Agent机制估计也难以实现两三百行或更大规模的完整应用开发?
@徐晓强:@彭鑫 恐怕是的。
王思维:
我理解这个还是要看模型的各环节的基础能力需要足够强,比如代码长文理解,项目级代码生成和代码缺陷定位:修复等;这些能力足够强了再结合agent相关的方法,比如规划 思考 执行 观察 反思等等,可用性才能够进一步加强。
访谈结束
CodeWisdom
一个有知识的软工公众号
发现智能化编程之道