LLM 能提高开发人员的生产力吗

2024-06-17 17:17:22 浏览数 (2)

作者 | Glenn Engstrand

译者 | 平川

策划 | Tina

本文要点

  • 为了帮助理解当前的 LLM 工具是否可以帮助程序员提高生产力,我们进行了一个实验,并使用经过改进的单元测试代码覆盖率作为一个客观度量指标。
  • 我们在这个实验中选择了多种免费的 LLM:ChatGPT、CodeWhisperer、codellama:34b、codellama:70b 和 Gemini。它们都是免费的,这也是 Github Copilot 不在这个列表上的原因。
  • 我们设计了一个实验,用于测试上述几种 LLM 为已经完成编码的重要 Web 服务生成单元测试的能力。对于上面提到的每一种 LLM,我们都提供同样的问题和提示。然后,我们将输出与现有的开源项目结合起来,编译并运行单元测试。为了再次构建的时候能够通过,我们需要保存所有的修改记录。
  • 如果没有人类监督和干预,则没有一个 LLM 能够成功地执行任务。不过,许多 LLM 都能够在一定程度上加速单元测试的编码过程。

从 OpenAI 发布 ChatGPT 至今尚不足两年。这是第一个公开发布的基于生成式预训练转换器的主流大语言模型,而且简单易用。

从华尔街到白宫,人们都为它的发布感到兴奋不已。几乎每一家财富 500 强公司和科技初创公司都在设法弄清楚如何利用 LLM。开发生态系统中涌现了很多支持工具和基础设施,如 Lang Chain,加快了现有应用程序与 LLM 的集成速度。

在最近于丹佛举行的一次技术会议上,Eric Evans(领域驱动设计的创建者)“鼓励大家现在就开始学习 LLM 并进行实验,然后与社区分享实验的结果和经验。”

本文记录了我个人在这方面的贡献。这项研究不是基于我前雇主或现雇主的任何要求或指示。

实 验

我决定做一个实验,在每个比较流行的 LLM 上进行实验,然后对它们进行比较,探索 LLM 的能力界限(至少短期内如此)。我对 LLM 将如何取代程序员并不感兴趣,也不担心。在使用 LLM 时,我们仍然需要有经验的开发人员,因为需要特别慎重地审查它提供的建议。我更感兴趣的是 LLM 如何通过自动化编写代码中比较耗时、琐碎但仍然非常重要的部分,来帮助编码人员提高生产力。当然,我指的是单元测试。

许多人会说,单元测试不是使用 LLM 的好地方,因为理论上,在测试驱动开发中,首先编写的是测试,然后才是代码。不过,我在很多公司都有过这样的经历,单元测试几乎总是到最后才考虑,测试所覆盖的代码量与冲刺剩余的时间成正比。如果编码人员可以用 LLM 更快地编写更多的单元测试,那么就会有更高的代码覆盖率和代码质量。我仿佛听到 TDD 的死忠分子已在怒火中烧。很抱歉,但这就是冷酷无情的事实。此外,如果不首先了解实现的内部细节,又如何在测试中模拟外部依赖关系呢?

我有一个开源存储库,其中我用各种编程语言和技术栈实现了相同的微服务。每个实现都包括对 MySql 前端 Redis 的访问。为了进行比较,我对每个微服务做了同样的负载测试,并收集、分析了性能数据。我借用了 Java on Spring Boot 实现中的一个服务类,只保留其中三个可路由的 public 方法。然后,我取出单元测试代码并删除了所有单元测试,只保留了其中一个。我保留了导入、设置和基于注解的依赖注入。在提示中,我要求另外生成两个单元测试。整个提示的长度为 250 行(约 1300 个单词)。我为什么使用 Java on Spring Boot 呢?因为网上有很多现成的代码,而且没有许可限制,可以作为 LLM 的部分训练数据。在很大程度上,Spring Boot 所采用的方法是基于注解的,与简单地研究代码本身相比,这需要更深入的理解。

我把这个问题当作一个科学实验来处理,但这并不是一个很好的实验。实验只有在可复现的情况下才有价值,但我所评估的所有这些技术都在不断发展,拥有这些技术的组织在这些产品上花了很多钱进行创新,希望可以改进它们。如果你今天做同样的实验,大概率得不到相同的结果。尽管如此,我还是保留了一份我在这个过程中使用的提示,如果你感兴趣,可以试一下。

OpenAI ChatGPT

2022 年底,ChatGPT 将基于转换器的大语言模型和 OpenAI 带到了媒体的聚光灯下。因此,我的这个实验中必须包含 ChatGPT。最初,ChatGPT 有许多问题:上下文窗口小,输出质量低,忘记提示,产生自信的幻觉。它现在已经好很多了。像这里评估的所有其他技术一样,我使用的是免费版本。在使用这些商业化的 LLM 时,人们担心提示会泄露专有信息。这就是为什么我基于开源版本进行实验。不会泄露什么专有的东西。提示泄漏是不可避免的,因为你提供的提示是用于对 LLM 进行调优,随着时间的推移,LLM 的答案质量将越来越高。

ChatGPT 的表现如何?它做得不错。对结果的解释简明准确。输出是有用的,但它确实有 Bug,特别是在依赖注入和模拟(mocking)方面。测试覆盖率也还可以。单元测试代码有针对单个属性的断言、未找到及不为空。即使有 Bug,我仍然认为它的输出是有用的,因为我觉得自己输入代码比修复生成代码中的错误花费的时间更多。

Amazon CodeWhisperer

我用这种方式评估的下一项技术是 Amazon CodeWhisperer。这是一个 Visual Studio Code 插件。总的来说,它的语句补全功能更好。你开始输入,它就会帮你补全这一行。有时,它可以完成一个代码块。然后,你可以选择接受或拒绝更改建议。大多数时候,我都接受更改,然后进行必要的修改,消除它生成的代码中的任何错误。我觉得使用 CodeWhisperer 生产力最高。

我认为,CodeWhisperer 在方法上与 Github Copilot 类似。因为 Github Copilot 需要付费,所以我没有评估。CodeWhisperer 是免费的。对于 CodeWhisperer 的内部机制,亚马逊守口如瓶。它可能不仅仅是一个 LLM,但它确实给人 LLM 的感觉。我怀疑 CodeWhisperer 一直在和服务器通信,因为 IDE 经常会卡住。禁用 CodeWhisperer,IDE 就又可以正常响应了。

Code Llama

Ollama 是一个开源平台,允许你构建和运行 LLM。它提供了大量经过预训练的开源模型,其中包括 Meta 的 Code Llama 模型。人们对这些开源 LLM 很感兴趣。去年,在加州大学洛杉矶分校的一次峰会上,著名风险投资家 Bill Gurley 指出,Llama 2(包含在 Ollama 的模型库中)是 OpenAI 最大的威胁。还记得我之前提到的提示泄漏问题吗?因为你将 Ollama 托管在直接由你控制的 VM 上,所以提示泄漏的可能性很小。

虽然不是必需的,但你肯定希望在 GPU 还算说得过去的系统上运行它。我的个人笔记本电脑上没有 GPU,所以我使用了谷歌云平台提供的 a2-highgpu-1g VM,并在上面配置了一个带有 CUDA 系统的机器学习 Linux 来运行测试。更具体地说,我使用了 codellama:34b 模型。根据 Meta 介绍该模型的博文,“Code Llama 是 Llama 2 的代码专用版本,它是通过在专门的代码数据集上做进一步训练而创建的,从同一数据集中做了更多的数据采样,而且时间更长。本质上讲,Code Llama 是在 Llama 2 的基础上增强了编码能力。”我在 NVIDIA A100 40GB 上使用 codelama:70b 运行了相同的测试,并且确实看到,所生成代码的代码覆盖率略有提高。在撰写本文时,该实例的成本为每小时 3.67 美元。

结果比 ChatGPT 稍微差一点,但不算太坏。它会报编译错误,缺少包和导入,存在 mocking 和依赖注入 Bug。在 34b 模型中,唯一的代码覆盖是不为空断言。在 70b 模型中,这被一个新的断言所取代。新断言会匹配从服务调用返回的内容与在底层 DAO 调用模拟中注入的内容。Code Llama 提供的结果中没有任何说明性文字或在线参考资料。它生成的输出确实包含没有多少价值的代码注释。

Google Gemini

我在实验中使用的最后一个 LLM 是 Gemini(之前的 Bard)。与 Code Llama 一样,它生成的输出忽略了包声明或输入中可用的导入。这很容易解决。我不确定这是一个错误,还是仅仅针对我提的问题给出的不同解释。与所有基于聊天的技术一样,其输出在依赖注入和模拟代码方面也存在类似的 Bug。它的代码覆盖率稍微好一点,因为它还有针对缓存命中和缓存未命中的测试。它的说明性文字比 ChatGPT 稍微好一点,它引用了自己使用最多的源,而不是作为实验中所有代码来源的开源存储库。这很有用,和 ChatGPT 的方法一样有用。与从头开始编写这两个方法相比,修复 Bug 花费的时间会少一些。

小 结

对于像软件质量这样主观的东西,要进行准确可靠的数值度量是相当具有挑战性的。在下表中,我尝试用数值这种便于比较的方式来汇总我的发现。对于生成的单元测试,我使用 Myers Diff 算法来度量修复代码(你肯定要修复生成的代码)所需添加和删除的代码行数(修改一个代码行视为添加一行和删除一行)。Jacoco 代码覆盖率是由单元测试覆盖的指令(比如 Java 字节码)除以指令总数(覆盖的和未覆盖的)得出的百分比。

基于 LLM 生成单元测试的实验结果汇总:

显然,从这些实验中可以看出,在任何单元测试代码的生成过程中都没有通用人工智能的参与。它们对基于注解的依赖注入和 mock 没有任何专业级的理解。这让我清楚地认识到,其背后并没有什么非常智能的东西。很简单,LLM 对大量文档进行编码,对输入做词法分析,并根据其结构以基于转换器的有大量权重的神经网络的形式(即模型)捕获该输入的上下文。

当我们提出问题(比如编码任务)时,该模型通过预测输入最可能的下文或补全输入来生成响应。它考虑输入提供的上下文,并生成连贯、有意义且符合上下文但不一定正确的响应。这样来看的话,你可以将 LLM 视为一种复杂的上下文搜索形式(尽管比 Web 搜索引擎或 Lucene circa 2020 的搜索机制更复杂)。

在这个实验中,我发现 LLM 具有非常好的代码搜索功能,对于经验丰富的开发人员来说,这非常有用。对于 ChatGPT、Ollama 和 Gemini,令我失望的是,我希望聊天窗口的另一端有人类智慧的期望落空了。但是,对于语句补全,我没有这样的期待。CodeWhisperer 没有让人失望,不是因为这个 AI 更好,而是因为其用户体验在管理用户期望方面做得更好。

未来展望

单元测试代码补全类的生成式人工智能在退出实验阶段进入生产应用之前,可能还需要解决一些企业关注的问题。

我已经讨论过提示泄漏。对于企业来说,这是一个大问题,因为公司的许多代码需要包含在提示中,而通常,大多数公司认为他们的代码是专有的。如果提示没有返回到与其他公司共享的模型实例中,那么就不必担心提示会泄露给其他公司。一种选择是在本地运行 LLM(如 Ollama),这就要求为每个开发人员配备的机器都具有足够强大的 GPU。另一种选择是订阅 ChatGPT 或 Gemini 的单租户非共享版本。还有一种选择是完全关闭提示驱动的模型微调。第三种选择目前已可以选用,但第二种还不可以。

另一个担忧是成本。我怀疑,如今的生成式人工智能定价侧重于增加市场份额,尚未涵盖所有成本。为了从增长转向盈利,价格将不得不上涨。我在上文 Code Llama 一节中提到的 NVIDIA A100 40GB 现如今的价格约为 10000 美元左右。还有电力消耗的问题。这一领域还在不断创新,但通常情况下,GPU 的功耗大约是 CPU 的三倍。单租户的方法更安全,但也更昂贵,因为供应商无法从构建基础模型之外的规模经济中获益。生产力的提高微乎其微。成本将成为长期使用的一个考量因素。

正如我之前提到的,这个领域发展迅速。大部分实验我都是在 2024 年初做的。从那以后,Amazon CodeWhisperer 又升级了他们的产品。ChatGPT 和 Gemini 的一些早期版本都支持 IntelliJ 和 VS Code 插件。Meta 发布了 Llama 3,是的,它已经在 Ollama 中提供。明年这个时候这个领域会有怎样的发展呢?在产品植入、战略定位、政府监管、员工干扰、供应商输赢方面,谁又能说得清呢?会有 AGI 吗?不会。

原文链接

https://www.infoq.com/articles/llm-productivity-experiment/

声明:本文由 InfoQ 翻译,未经许可禁止转载。

0 人点赞