当前位置: 首页 > 产品展示 > 数码模块

火博sports

PRODUCTS
×

火博sports字节跳动代码生成 Copilot 产品的应用和演进

发布时间:2024-06-12 09:22:53 来源:火博体育首页 作者:HB火博APP官网

  大语言模型在代码生成领域取得了令人瞩目的进展。本文整理自字节跳动产品研发和工程架构部的代码智能助手架构师刘夏在 AICon 2024 北京 的演讲《代码生成 Copilot 产品的应用和演进》,聚焦基于大语言模型的代码生成技术,深入探讨了代码补全和代码编辑这两种典型的应用形态。同时,还分析了当前代码补全面临的挑战和局限性,阐述了代码编辑是如何在交互和构建方法上实现创新。内容经 InfoQ 进行不改变原意的编辑。

  在 6 月 14-15 日即将举办的 ArchSummit 深圳上,来自字节跳动各个不同部门的技术专家还将进一步介绍字节跳动在高可用云边通信、观测诊断的智能化演进、数据驱动业务成本优化等方面的实践经验。此外,大会还进一步策划了《低代码与 AI 结合》专题,来自腾讯、网易、蚂蚁集团的技术专家,将在现场深度探讨在低代码环境中集成智能决策、自动化流程,以及构建灵活、高效的应用系统。目前,大会议程已全部上线,感兴趣的同学请锁定大会官网: 。

  首先,回顾一下代码生成 Copilot 这种产品形式。当我们谈论代码生成 Copilot 或者 Copilot 这个词时,不得不提到 GitHub 在 2021 年 6 月推出的 GitHub Copilot。这个产品不仅拥有一个响亮的名字,而且定义了一种新的 AI 产品的范式。GitHub Copilot 在 2021 年 6 月推出了技术预览版,随着不断的迭代,其效果令人印象深刻,使人们意识到将大语言模型应用于代码生成领域具有巨大的潜力。业界也开始迅速构建类似的产品,无论是在模型还是产品上都取得了快速的迭代。

  这里有一个关键问题:为什么是 GitHub Copilot 引爆了这个热点?实际上,将自然语言处理(NLP)技术应用于代码生成并不是一个新概念,例如 TabNine 这样的产品在 GPT-2 时代就已经将其应用于代码补全。那么,GitHub Copilot 究竟有何特别之处呢?我们想要从几个方面和维度来探讨这个问题。

  首先,我想提到团队,GitHub Next 是这个产品的孵化团队。GitHub Next 是一个具有研究属性的团队,他们的任务是探索未来软件开发的新方式。如果访问他们的官网,你会发现许多有趣的项目,其中就包括 Copilot。团队主要由程序分析师、软件工程师以及研究员组成,他们持续关注的一个重要话题是如何实现通用的代码生成。

  接下来,我想谈谈一个重要的契机,那就是 2020 年 6 月 GPT-3 的问世。由于 GitHub 现在是微软的子公司,而微软与 OpenAI 有着深入的合作,GitHub 团队很早就获得了 GPT-3 的预览版,并对其能力感到非常兴奋。他们认为必须利用 GPT-3 在代码生成领域做出一些创新,因此与 OpenAI 紧密合作,基于 GPT-3 迭发出了专门用于代码的大型语言模型 Codex。随后,他们对 Codex 进行了持续的微调训练,打造了专属的模型。一个强大且优秀的基础模型实际上决定了产品的上限,因此 GPT-3 的出现对这款产品的贡献是巨大的。

  有了模型之后,团队开始思考应该开发什么样的产品形态。根据 GitHub 的分享,他们最初的想法是开发一款 Chatbot,即一款能够解答编码过程中遇到的任何问题并提供代码的对话聊天产品。但他们很快发现,尽管知识库中大部分问题都能得到回答,但只有大约 20% 的回答是正确且被接受的。尤其是在 GPT-3 时期,ChatGPT 还要两年后才出现,他们意识到这种 Chatbot 产品的效果并不理想。如果大部分时候给出的答案都不是用户想要的,用户对产品的信任度会很低。于是他们决定先采用代码补全这种容错率更高的产品形态,一方面代码补全是个开发者使用频率非常高的功能,也有很强的依赖性,更重要的是开发者对于这个功能的预期是给出建议而不是 100% 准确的答案。

  选择好产品形态后的一个要素是交互方式。GitHub Copilot 放弃了传统 IDE 中从下拉列表选择补全建议的交互,而是选择了用 Ghost Text 进行展示,用 Tab 键进行采纳,继续输入则取消推荐。这种交互方式发挥了模型在多行补全上的优势,推荐代码和已有代码融为一体,方便开发者快速基于上下文判断是否采纳。

  代码补全产品的一个技术挑战是实现低延迟,Jetbrains 在开发传统的补全功能时甚至要求在 150ms 内出现推荐列表以达到最佳的开发者体验。因为专业开发者的输入速度通常较快,过高的延迟会失去很多推荐的机会或者迫使用户停顿等待。GitHub Copilot 在大语言模型的推理速度和工程链路上进行了优化,让一个基于云端推理的 LLM 应用做到 500ms 左右的平均延迟。

  如果说基座模型决定了产品能力的上限,那么提示工程所做的努力就是去逼近这个上限。通过研究开发者日常开发中会关注的上下文,在 prompt 中加入文件路径、相似代码、浏览记录等信息,让模型在代码补全方面的表现大幅提升,如今这些提示工程上的实践也被大家广泛应用。

  字节跳动在内部探索代码生成的过程中,面临多种优化选择:可以在模型层面进行优化,也可以选择在工程链路上优化,或在交互体验上进行改进。团队需要灵活地做出决策。

  随着大语言模型的发展,特别是从 2023 年开始,这个领域开始受到广泛关注,新的模型和产品层出不穷。为了迭代和优化模型,字节跳动首先建立了自己的评测方法和自动化评测系统。这涉及到模型选型的决策,快速评估训练过程中的 checkpoint 效果,以及产品上线后如何收集线上反馈,包括用户编辑过程中的正反馈和负反馈。字节跳动还建立了一个完整的数据链路,以决定哪些数据被采纳,哪些被丢弃,并实施 A/B 测试系统来验证不同的 prompt 策略、参数配置,甚至是新模型的上线效果。字节跳动的自研大语言模型也已经发布,团队逐渐切换到这个自研模型上。基于此,字节跳动引入了对话方式,使代理模型能够理解整个工程结构,并根据实际情况生成代码。此外,还引入了多点代码编辑推荐功能,这是一个较新的功能。今天的分享将围绕三个重点进行详细分析:

  构建自研评测体系的重要性在于,它可以帮助我们避免使用不恰当的评测指标,如 HumanEval,它可能无法准确反映模型在实际应用中的表现。HumanEval 通过完工编写的算法题并运行单元测试来评估模型,虽然模型在测试的分数可能很高,但这并不意味着模型在代码补全产品中的表现就一定好。例如,GitHub Copilot 在 HumanEval 上的得分可能不高,但其用户体验仍然出色。

  自建评测集可以避免数据泄露问题,确保题目和答案不会被模型提前接触到。同时,自建评测集可以引入真实项目中的跨文件上下文,这对于评估模型能否合理利用上下文信息至关重要。此外,自建评测集还可以引入大量公司内部代码,因为开源代码与内部代码的使用场景和分布可能存在显著差异。评测体系还需要包括基于单元测试的验证方式,因为同一功能可能有多种不同的代码实现方式,而单元测试可以更准确地验证生成代码的正确性。

  最后,安全的自动化评测系统对于模型迭代至关重要。它不仅可以通过执行结果来验证代码的正确性,还可以防止模型生成有害代码,如删除根目录或造成大量内存分配等问题。高效的沙箱测试环境和高并发支持对于大规模的评测也是必不可少的。通过这样的评测系统,我们可以在训练过程中对不同 checkpoint 的模型效果进行评估,从而为模型选型和迭代提供有力支持。

  在科学地定义指标时,我们需要考虑代码补全流程中的各个环节,并确保所选指标能够准确反映产品优化的需要。一个有效的指标应该能够指导整个链路的优化,帮助我们识别瓶颈并进行相应的调整。采纳率是一个常被提到的指标,它通常定义为采纳次数除以推荐次数。虽然这个定义简单,但它并不是一个好的指标。首先,采纳率容易被操纵。例如,如果减少推荐次数,只在非常确定的时候去帮你补一个分号,采纳率就会提高,但这并不意味着产品的实际效果有所提升。其次,采纳率没有很好地拆解推荐和采纳过程中的具体因素,无法明确指出是推荐更快了,还是其他因素导致采纳次数增多。

  体验指标是另一个需要考虑的方面。当用户在使用代码补全产品时,如果一个 Tab 操作就能接受推荐的代码并完成工作,这自然会带来良好的用户体验。体验指标可以反映用户对产品的满意度,但它并不直接指导产品优化的方向。在定义指标时,我们需要更细致地考虑如何反映产品的实际性能和用户体验,同时避免指标被操纵,并确保指标能够指导我们进行有效的产品迭代和优化。

  在探讨如何科学地定义指标时,引入了 CPO(Character per opportunity)这一指标,它是由一家专门从事代码补全产品的公司提出的。CPO 的计算公式由五个因子相乘得到:尝试率、反馈率、采纳率、每次采纳平均的token数以及token的平均字符长度。

  尝试率指的是用户在编辑器中进行操作时,AI 提供建议的频率。例如,如果用户敲击键盘 10 次,但只有 6 次触发了对模型的请求,尝试率就是 6/10。这个指标反映了 AI 实际为用户提供建议的次数。

  反馈率考虑了 AI 给出补全建议时存在的延迟问题。如果因为延迟太高,开发者已经进行了其他操作,那么即使推荐返回了也没有意义。如果发起 6 次请求,最终只有 3 次被展示,反馈率就是 3/6。

  采纳率是大家熟悉的指标,即用户接受推荐的次数与推荐次数的比值。例如,三次推荐中只有一次被采纳,采纳率就是 1/3。

  引入每次采纳平均的 token 数和 token 的平均字符长度这两个参数,是为了衡量不同长度代码带来的价值。不同的语言模型有不同的分词器,因此需要计算每个 token 平均的字符长度。例如,ChatGPT 的词表较大,平均一个 token 可以生成的字符数可能大于其他模型。

  CPO 指标的计算公式是这几个因子的乘积,它衡量的是在每次有机会向用户推荐时,推荐了多少字符给用户。这个指标不仅可以衡量产品给开发者带来的价值,还可以拆解到整个链路的各个部分进行优化。例如,可以通过优化模型推理性能,提高反馈率,或者在代码注释中提供推荐来优化尝试率。此外,当线上出现问题时,CPO 指标也可以用来分析可能存在的问题所在。

  A/B 测试在产品开发过程中扮演着至关重要的角色。尽管离线评测可以帮助我们进行模型选型,但一个模型是否真正有效,还需要通过线上测试来验证。有时候,一个模型在评测中得分很高,但这并不代表它在线上的实际表现同样出色。例如,一个非常强大的模型如 GPT-4,可能会因为高延迟而影响用户体验。

  A/B 测试还可以帮助我们确定各种参数配置的合适值。比如,如果一个模型支持 16K 的上下文长度,是否就应该使用完整的 16K 呢?实际上,如果上下文过长,可能会导致整体延迟增加,影响用户体验。因此,需要通过 A/B 测试来找到最合适的上下文长度。

  此外,A/B 测试还可以验证新的提示工程策略的效果。例如,如果我们在模型中加入了函数签名或其他包结构信息,是否真的能提升效果?模型是否能够有效利用这些上下文?以及为了采集这些上下文信息而引入的额外延迟,是否值得?这些问题都需要通过 A/B 测试来验证。

  最后,A/B 测试还可以帮助我们发现并改进产品指标。假设我们最初使用的是采纳率作为指标,但在进行 A/B 测试后,我们发现延迟提高后,采纳率反而增加了。这种情况可能表明我们的指标存在问题,需要重新考虑和调整。

  代码补全的进化形式可以被视为代码编辑推荐。大语言模型擅长生成下一个 toke。


火博sports