生成式 AI 模型通常基于公开源代码和自然语言文本进行训练。虽然庞大的训练语料库使模型能生成常用功能的代码,但这些模型无法理解私有代码库中的代码及其编码风格。因此,生成的建议在纳入内部代码库之前,通常需要进行重写。
为了填补这方面的空白并减少手动编辑工作,需在基于公共代码训练的语言模型的基础上,嵌入来自私有代码库的知识。这也是我们开发 Amazon CodeWhisperer 定制功能的原因。在本文中,我们将展示两种使用检索增强生成和微调的方法来定制编码助手。
CodeWhisperer 的定制功能旨在让组织能够利用其私有代码库和库来调整模型,从而生成特定于组织的代码建议,提升效率、遵循组织风格和规范,并避免潜在的错误或安全漏洞。这将惠及企业软件开发,并帮助克服以下挑战:
内部库和 API 文档稀少,开发者需花费时间分析先前的代码以复制用法。实施企业特定编码实践、风格和模式时缺乏认识与一致性。开发者可能无意中使用已弃用的代码和 API。使用经过代码审查的内部代码库进行额外训练,语言模型可以识别内部 API 和代码块,从而解决上述问题。因为参考代码已通过审查并达到客户的高标准,因此引入错误或安全漏洞的可能性也得到降低。通过审慎选择用于定制的源文件,组织还可以减少对已弃用代码的使用。
基于组织私有库定制代码建议面临诸多有趣的设计挑战。部署大型语言模型LLM以获取代码建议需支付固定可用性成本,而因生成的令牌数量而产生的推理成本则是可变的。因此,为每个客户进行单独定制并单独托管它们,从而产生额外的固定成本,可能过于昂贵。另一方面,在同一系统上同时进行多次定制则需要多租户架构,以便为每个客户隔离专有代码。此外,定制能力应具备接口,以便使用不同指标选择适当的训练子集例如,拥有较少 bug 的文件或最近提交到仓库的代码。通过根据这些指标选择代码,定制化可以基于更高质量的代码进行训练,从而提高代码建议的质量。最后,即使在不断发展的代码库中,定制相关的成本也应保持在最低限度,以帮助企业通过增加开发者的生产力来节省成本。
构建定制的基本方法可以是在一个单一的训练语料库上预训练模型,该语料库由现有的公共预训练数据集和私有的企业代码组成。尽管该方法在实践中可行,但它需要为每个企业各自进行冗余的单独预训练。它还需要与每个客户相关的托管定制模型的冗余部署成本。通过将公共和私有代码的训练解耦,并在多租户系统上部署定制化,可以避免这些冗余成本。
大体上,有两种可能的定制技术:检索增强生成RAG和微调FT。
检索增强生成RAG: RAG 在仓库中查找与给定代码片段例如,IDE 中光标前的代码相似的代码片段,并将这些匹配的代码片段增加到用于查询 LLM 的提示中。这丰富了提示,帮助模型生成更相关的代码。相关技术的文献中有几种方案可供参考,包括检索增强生成用于知识密集型 NLP 任务、REALM、kNNLM和RETRO。微调FT: 微调是指在特定更小的代码库与预训练数据集相比上进一步训练一个预训练的 LLM,以适应相应的代码仓库。微调根据该训练调整 LLM 的权重,使其更符合组织的独特需求。RAG 和微调两种技巧都能有效提升基于 LLM 的定制表现。RAG 能快速适应私有库或 API,且训练复杂度和成本较低。然而,在运行时搜索和增强检索的代码片段会增加延迟。相反,微调不需要对上下文进行增强,因为模型已经在私有库和 API 上进行过训练。但是,支持多个企业客户的多种定制模型会导致更高的训练成本和复杂性。接下来,我们将讨论如何进一步优化这些问题。
RAG 包含多个步骤:
管理员提供私有代码库作为输入,通过将源代码文件拆分为代码块创建索引。简言之,分块将代码片段转化为易于获取的信息小块。分块的大小和提取方式是影响最终结果的设计选择。例如,代码块可以根据代码行或语法块等进行拆分。
管理员工作流程根据光标上方的几行代码,搜索一组索引的代码片段并提取相关代码片段。这种检索可以使用不同的算法进行选择,包括:
使用词袋模型例如 BM25根据查询词频和代码片段长度,对代码片段进行排名。如上图所示,BM25 的工作原理是首先构建反向索引。这是一个数据结构,用于将不同术语映射到出现这些术语的代码片段。在检索阶段,我们根据查询中存在的术语查找代码片段,并根据其频率进行评分。
使用语义检索例如 Contriever、UniXcoder将查询和索引代码片段转换为高维向量,并根据语义相似性对代码片段进行排名。通常使用最近邻KNN或近似最近邻ANN搜索以查找其他具有相似语义的代码片段。BM25 侧重于词汇匹配,因此将“add”替换为“delete”可能不会改变 BM25 的得分,而检索出的功能可能与需求正好相反。相比之下,语义检索则专注于代码片段的功能性,尽管变量和 API 名称可能不同。通常,结合 BM25 和语义检索可以更好地提供结果。
当开发者编写代码时,现有程序将用于形成发送到检索索引的查询。使用上述某种技术检索多个代码片段后,将其预附加到原始提示中。这里有许多设计选择,包括要检索的代码片段数量、代码片段在提示中的相对位置,以及片段的大小。最终的设计选择主要受到经验观察的影响,通过在底层语言模型上探索各种方法,关系到方法的准确性。返回的代码块内容与原始代码组合,并发送给模型以获取定制的代码建议。
开发者工作流程微调 是针对 迁移学习 的一种做法,即在新数据上训练预训练模型的权重。目的在于保留来自已经在大型语料库上训练的模型的知识,并通过新语料库中的知识进行改进、替换或添加在我们这个案例中是新的代码库。简单地在新代码库上训练可能导致 灾难性遗忘。例如,该语言模型可能会 “忘记”安全知识或在企业代码库中稀少使用的 API。为了解决这个挑战,采用了多种技术,如经验重放、GEM 和 PPTF。
微调有两种方式。一种方法是使用附加数据对模型进行微调,而不增强提示。另一种方法是通过检索相关的代码建议来增强微调过程中的提示。这有助于提高模型在检索到代码片段时提供更好建议的能力。训练后,再在保留的示例集上评估模型。随后,部署定制模型用于生成代码建议。
尽管为私有代码库生成代码使用专用 LLM 的优势显而易见,但对于中小企业而言,成本可能过高。这是因为尽管团队规模较小,但仍需使用专用的计算资源。实现成本效益的一种方法是在相同计算资源上服务多个模型例如,SageMaker 多租户。然而,语言模型需要一个或多个专用 GPU 来满足延迟和吞吐量的要求。因此,完全在每个 GPU 上托管多租户模型的计划并不可行。
免费加速器试用一小时我们可以通过在 LLM 中使用小型的 适配器 来解决此问题。在微调过程中使用诸如 提示调优、前缀调优 和低秩适配 (LoRA) 等参数高效微调PEFT技术,可以降低训练成本,而不会影响模型的准确性。 LoRA 特别有效,在实现与完整模型微调相似或更好的准确度方面表现出色。基本思想是设计一个低秩矩阵,然后将其添加到为目标模型的特定层设置的原始矩阵权重中。通常,这些适配器随后与原始模型权重结合用于部署。这使得适配器的大小和结构与原始神经网络相同。通过保持适配器分开,我们可以用多种模型适配器提供相同的基础模型。这使得我们能够为中小型客户带回规模经济。
我们需要评估指标来评估定制解决方案的有效性。离线评估指标充当了确保未交付不合格的定制模型的护栏。通过从提供的代码库中构建持出数据集,可以应用定制方法来测量效果。比较现有源代码和定制代码建议之间的相似性可以量化定制的有效性。用于这种量化的常见衡量标准包括编辑相似度、完全匹配和 CodeBLEU。
也可以通过量化定制过程中调用内部 API 的频率来评估其有效性,并将其与现有源代码中的调用频率进行比较。显然,要完全满足这两个方面是成功完成的关键。对于我们的定制方法,我们设计了一个专用指标,称为定制质量指数CQI,这是一个在1到10之间的用户友好型度量。CQI 指标反映了定制模型建议与通用公共模型建议的有效性。
我们基于本文中讨论的先进技术,构建了 Amazon CodeWhisperer 的定制能力,并通过 Persistent Systems 进行的用户研究来评估其效用。在这两项研究中,AWS 委托开发者开发需要使用其内部库的 Java 医疗软件应用。在第一项研究中,没有访问 CodeWhisperer 的开发人员完成任务的平均时间约为 82 小时,而使用 CodeWhisperer未定制的开发人员完成任务的时间则减少了 62,平均为 31 小时。
在第二项研究中的其他开发者组中,使用经过其私有代码库定制的 CodeWhisperer 的开发人员,平均完成任务时间为 25 小时,比未定制版本的 CodeWhisperer 的开发者节省了 28的时间后者平均完成时间为 35 小时。我们坚信,像 CodeWhisperer 这样的工具,能够根据您的代码库进行定制,对提高开发者的生产力至关重要,强烈建议您进行尝试。有兴趣的人可以访问 Amazon CodeWhisperer 页面 获取更多信息并开始使用。
Qing Sun 是 AWS AI Labs 的高级应用科学家,负责 AWS CodeWhisperer,该项目为生成式 AI 驱动的编码助手。她的研究兴趣包括自然语言处理、AI4Code 和生成式 AI。在此之前,她曾在多个基于 NLP 的服务中工作,如 Amazon Health AI 的医疗诊断系统 Comprehend Medical 和 Meta AI 的机器翻译系统。她于 2017 年获得弗吉尼亚理工大学博士学位。
Arash Farahani 是 Amazon CodeWhisperer 的应用科学家。他目前的研究兴趣集中在生成式 AI、搜索和个性化。他热衷于构建解决开发者痛点的方案,曾在 CodeWhisperer 中开发多项功能,并将 NLP 解决方案引入到亚马逊所有开发者接触的多个内部工作流中。他于 2017 年获得伊利诺伊大学香槟分校博士学位。

Xiaofei Ma 是 AWS AI Labs 的应用科学经理,2016 年以应用科学家的身份加入亚马逊,隶属于 SCOT 组织,后于 2018 年转入 AWS AI Labs,参与 Amazon Kendra 项目。Xiaofei 担任多个服务的科学经理,包括 Kendra、Contact Lens,以及最近的 CodeWhisperer 和 CodeGuru Security。他的研究兴趣涵盖 AI4