点击⬇️图标关注 抓住你的灵感💡瞬间
你可能跟我一样,会好奇Cursor这样一个初创团队,
如何能够单挑微软的Github Copilot,并保持持续领先?这篇Lex Fridman与Cursor团队的创始成员Michael Truell、Sualeh Asif、Arvid Lunnemark和Aman Sanger的对话,长达2个多小时。可以为你解答!
编程是一门特殊的语言,“Fast is Fun” 是他们领悟到的真谛,这一次他们要用AI完成这个使命。
(全文2万+字,建议先收藏!加关注,后台回复cusor获取英文原版。)
Cursor是一款基于VS Code的代码编辑器,加入了许多强大的AI辅助编程功能。它引起了编程和AI社区的广泛关注和激动。这是一次深入探讨AI在编程中作用的绝佳机会。这次对话非常技术化,讨论的范围远远超出一个代码编辑器,涉及编程的未来,以及人类与AI在设计和工程复杂系统中的协作未来。
Cursor团队的创始成员在MIT麻省理工学院相识,2022年决定创建 Cursor。
姓名 | 工作/实习经验 | 竞赛与研究荣誉 |
Michael Truell | - Google: 大语言模型在新闻推荐的应用 - Octant: 计算化学工作 - Two Sigma: 创建Halite编程竞赛 | 麻省理工学院研究工作 |
Sualeh Asif | - 麻省理工学院多门课程助教 - IBM Watson ML实习: 翻译相关工作 | - 代表巴基斯坦参加2016-2018年国际数学奥林匹克 - 在数论、算法等领域发表学术论文 |
Arvid Lunnemark | - Jane Street实习: 量化交易工作 - Stripe实习: 软件工程师 | - 国际信息学奥林匹克银牌 - 国际数学奥林匹克金牌 |
Aman Sanger | - Google、Bridgewater Associates实习 - 麻省理工哈佛布罗德研究所本科研究员 | - 麻省理工学院壁球队队长 |
福布斯8月报道配图
OpenAI、Midjourney、Perplexity 和 Scale AI 等领先人工智能初创公司以及 Shopify 和 Instacart 等科技公司的工程师都是 30,000 名客户之一,他们每月支付 20 美元或 40 美元使用 Cursor 的人工智能工具编写和编辑整段代码。
Cursor 由四位在麻省理工学院相识的朋友于 2022 年共同创立,周四,该公司宣布已在由 Andreessen Horowitz 领投的 A 轮融资中筹集了 6000 万美元,Thrive Capital、OpenAI Startup Fund 和谷歌首席科学家 Jeff Dean 也参与其中。据一位知情人士透露,在获得新投资后,这家初创公司的估值现已达到 4 亿美元。该公司每年的经常性收入超过 1000 万美元。
代码编辑器的基础【Code editor basics】
代码编辑器是软件开发的核心工具。Cursor团队成员Michael解释道:“代码编辑器主要是构建软件的场所,长期以来,这意味着对形式化编程语言进行文本编辑的地方。“对于非程序员来说,可以将代码编辑器理解为程序员专用的增强版文字处理器。
Michael进一步阐述了代码编辑器的特点:“代码具有大量结构,所以这个’文字处理器’——代码编辑器实际上可以为你做很多普通文字处理器在文本编辑领域无法做到的事情。“这包括为代码中的不同元素提供视觉区分,以便快速浏览;允许在代码库中导航,类似于在互联网上使用超链接;以及进行错误检查以捕获基本错误。
团队认为,未来10年内,代码编辑器的定义将发生重大变化,因为软件构建的方式可能会有所不同。Arvid补充说,一个好的代码编辑器应该是有趣的,这是他们决定开发哪些功能时考虑的一个重要方面。他强调:“快速就是有趣。“
Arvid:
Yes, that is very important. That is very important. And it’s actually sort of an underrated aspect of how we decide what to build. A lot of the things that we build and then we try them out, we do an experiment and then we actually throw them out because they’re not fun. And so a big part of being fun is being fast a lot of the time. Fast is fun.
GitHub Copilot
团队成员分享了他们使用GitHub Copilot的经历。Aman回忆道:“我们最初都是纯Vim用户(Vim是高度可配置的文本编辑器,广泛用于编程和文本编辑。它最初是为 Unix 系统开发的,具有强大的功能和灵活性,支持多种编程语言。)。对我来说,是在Copilot推出时,也就是2021年左右,我真的想尝试一下。所以我进入了VS Code,这是当时唯一可用Copilot的代码编辑器。尽管我非常喜欢使用Vim,但Copilot与VS Code的体验足以说服我切换过来。“
Lex Fridman将使用Copilot的体验比作与密友交谈时对方能够接上你的话:“当它做得好时,会有一种亲密的感觉。可能‘亲密’不是最恰当的词,但确实有一种很酷的感觉,就像‘天哪,它懂我’。“
Arvid指出了Copilot的一个被低估的方面:“即使它错了,也不会太糟糕,因为你只需要再输入一个字符,也许它就能理解你了,或者再输入一个字符,它就能理解你了。所以即使它错了,也不会太糟糕。“
Sualeh补充说:“对我来说,Copilot被低估的另一个方面是,它是第一个真正的AI产品,第一个面向消费者的语言模型产品。“
Cusor
Michael解释了Cursor的诞生背景:“在2020年左右,OpenAI发布了scaling laws论文,这是一个关键时刻。即使我们没有任何新想法,看起来只要有更多的计算能力和数据,就可以让这些模型变得更好。“
他继续说道:“在那之后,我们经历了几个重要时刻,使得理论上的进展变得非常具体,感觉现在真的可以去构建有用的AI系统,而不需要去读博士。第一个重要时刻是玩转Copilot的早期测试版,那感觉很棒,很神奇。“
“第二个重大时刻是在2022年底获得GPT-4的早期访问权。能力的提升感觉巨大。在此之前,我们一直在研究一些不同的项目,比如为金融专业人士开发Jupyter Notebook工具,或者尝试用这些模型进行静态分析。“
“GPT-4的能力提升让我们感觉,现在可以立即构建更多东西。如果我们保持一致性,感觉这不仅仅是一个点解决方案,而是所有的编程都将通过这些模型进行。这需要一种不同类型的编程环境,一种不同类型的编程。所以我们开始着手构建这个更大的愿景。“
Lex 询问 Cursor 团队,为什么决定 fork VS Code,而不是像 Copilot 那样开发一个插件?
Michael 解释说,他们希望能够完全掌控代码编辑器,以便构建最强大的功能。如果仅仅是一个插件,就会受到现有编辑器的限制。他们相信,随着 AI 模型的能力不断提升,软件开发方式将会发生根本性的变化,程序员的效率将会大幅提高,软件开发的过程也会发生巨大的改变。为了适应这些变化,他们需要一个能够完全掌控的编辑器。
Lex 询问,既然 VS Code 和 Copilot 已经成为竞争对手,Cursor 如何才能胜出?
Aman 认为,AI 编程领域非常特殊,每年甚至每几个月,AI 模型的能力都会有显著提升,这会带来一波又一波新的功能和可能性。因此,即使只领先几个月,也会让产品更有优势。他相信,一年后的 Cursor 必须让今天的 Cursor 看起来过时。微软虽然做出了很多很棒的工作,但他们无法像初创公司那样快速创新和迭代。
Lex 指出,快速实现新功能是关键。Aman 补充说,还需要进行大量的研究和实验,才能真正突破技术上限。
Sualeh 认为,重要的不是功能,而是程序员的能力。随着新的模型(例如 O1)不断涌现,例如更长的上下文窗口和更快的推理速度,我们可以尝试各种 crazy 的想法,希望其中 10% 能够转化为真正有用和酷炫的功能。他们希望用户能够尽早体验到这些新功能。
Sualeh 强调,Cursor 的开发初衷是为了满足他们自己的需求。当他们开始开发 Cursor 时,他们感到非常沮丧,因为虽然 AI 模型的能力越来越强,但 Copilot 的体验却没有改变。他们认为,Copilot 应该开发更多的新功能和 Alpha 版本,让用户能够体验到最新的技术。
Lex 表示,虽然很难用语言表达,但他确实感觉到 Copilot 很快就变得过时了。
Arvid 认为,Cursor 的优势在于他们将用户体验、模型交互方式和模型性能优化整合在一起。负责用户界面、prompt 设计、上下文选择和模型训练的人员紧密合作,甚至可能是同一个人,这使得他们能够创造出其他公司无法实现的功能。
Arvid 确认Cursor 团队使用 Cursor 来开发 Cursor。
Cursor Tab
Lex 提出了 Cursor 的 Tab 功能,这是一个超级强大的自动补全功能。他询问 Tab 功能是如何工作的?
Michael介绍了Cursor的两个主要优势:“Cursor现在做得很好的两件事是:一是这种在你肩膀上看着你的想法,像一个非常快速的同事,可以跳到你前面,输入并弄清楚你接下来要做什么。这是好的自动完成背后的核心想法,不仅预测光标后的字符,还预测你接下来要做的整个更改,下一个差异,下一个你要跳转的地方。“
“第二件Cursor现在做得很好的事是帮助你有时跳到AI前面,告诉它要做什么,从指令到代码。在这两方面,我们都做了很多工作,使编辑体验符合人体工程学,同时也使这些功能变得聪明和快速。“
Sualeh补充道:“我们真正想要的是让模型能够为我们编辑代码。这是一种愿望,在我们有一个好的模型可以为你编辑代码之前,我们尝试了多次。然后在我们有了一个好的模型之后,我认为为了获得良好的体验,我们付出了很多努力使推理变得快速。Tab 功能的目标是消除所有低熵的操作。当程序员的意图已经确定后,模型应该能够自动完成后续的步骤,就像“读心术”一样。“
Aman 指出,代码的熵比自然语言低,这意味着代码中有许多 token 是可以预测的。当我们不仅试图自动补全代码,还试图预测程序员下一步的编辑操作时,这种可预测性会更加明显。Cursor Tab 的目标是消除所有低熵的操作,当意图已经确定时,就自动跳转到下一步。
Lex 询问,如何预测程序员的下一步行动?
Aman解释了一些技术细节:“为了使这些功能工作得非常低延迟,你需要在这个任务上训练小模型。这些模型需要处理非常长的输入,但输出却很小。这意味着它们有这些非常长的提示,可以看到你的大量代码,但实际上并不生成那么多token。所以完美的解决方案是使用稀疏模型,也就是MOE模型。这是我们取得的一个突破,大大改善了它在更长上下文中的性能。另一个是我们开发的一种推测性解码变体,称为推测性编辑。这两个是使其具有很高质量和非常快速的重要部分。“
此外,他们还开发了一种称为“推测性编辑”(speculative edits)的技术,这是一种改进版的推测性解码。这两项技术是 Cursor Tab 高效运行的关键。
Lex 询问缓存是否发挥了作用?Aman 回答说,缓存非常重要。由于模型需要处理大量的输入 token,如果每次按键都重新运行模型,将会导致延迟增加和 GPU 负载过高。因此,他们设计了一种缓存感知的 prompt,并在多个请求之间共享 KV 缓存,以减少计算量。
Lex 总结了 Tab 功能的近期目标:生成代码、填充空白、编辑多行代码、在同一文件中跳转到不同位置,以及在不同文件之间跳转。
Arvid 补充说,最终目标是预测程序员的下一步行动,这可能包括在终端中运行命令、跳转到代码定义,或者提供其他必要的信息,帮助程序员理解和接受模型的建议。
Lex 指出,这相当于为程序员提供知识。
Lex 提到了 Primeagen 开发的一个可以通过 SSH 订购咖啡的功能,询问 Cursor 是否也能做到这一点。
Michael 认为,编程的特殊之处在于,有时程序员接下来的五分钟操作是可预测的。未来的目标是让程序员能够通过简单地按下 Tab 键,或者快速浏览模型的建议,就能完成这些可预测的操作。
代码差异(Diff)界面
Lex谈到Cursor的Diff界面是 Cursor 真正酷且引人注目的事情之一,模型用红色和绿色建议我们如何修改代码,在聊天窗口中您可以应用它,它会向您显示差异,您可以接受差异。
Sualeh解释说:“我们可能会有四到五种不同类型的差异。我们已经优化了自动完成的差异,所以它有一个不同于审查大块代码时的Diff界面。然后我们正在尝试为处理多个不同文件时优化另一个差异界面。实际上,在所有情况下阅读都应该很快,但是在自动完成中,你的眼睛集中在一个区域,你不能关注太多……人类不能看太多不同的地方。总的来说,差异视图的设计目标是让用户能够快速、轻松地阅读和理解代码修改。“
Arvid表示他对这个领域的改进感到兴奋:“我们经常把它称为验证问题。这些差异对小编辑很好。对于大编辑或涉及多个文件的情况,实际上有点难以审查这些差异。所以我们有几个不同的想法。一个想法是,差异的某些部分很重要,包含大量信息。而差异的其他部分只是非常低熵的,一遍又一遍地重复相同的东西。所以也许你可以突出显示重要的部分,然后将不那么重要的部分变灰。或者也许你可以有一个模型查看差异,看到,‘哦,这里可能有一个bug。‘我会用一个小红色波浪线标记它,说你应该审查差异的这一部分。这类想法我认为很令人兴奋。“
Lex 认为,这是一个非常有趣的用户体验设计领域,目标是引导程序员只阅读必要的信息。
Arvid 补充说,他们希望使用智能模型来实现这一点。目前的差异算法都是普通的算法,没有智能。他们希望模型能够理解代码的语义,并根据重要性进行高亮显示。
Sualeh 指出,随着模型变得越来越智能,它们能够提出的修改也会越来越大,这将增加代码审查的工作量。我们需要帮助程序员更高效地进行代码审查。
Lex 询问,如何处理跨多个文件的代码修改?
Aman 回答说,GitHub 尝试使用代码审查来解决这个问题,但代码审查的体验并不好,因为审查者需要花费大量时间来理解不熟悉的代码,而且经常 无法发现很多 bug。他认为,可以使用语言模型来改进代码审查体验,例如引导审查者关注重要的代码区域。此外,由于代码是由语言模型生成的,而不是由其他程序员编写的,因此我们可以围绕审查者的体验来设计整个流程,使其更加轻松、高效和有趣。
Arvid 补充说,审查代码的顺序也很重要。通常情况下,我们按照文件列表的顺序从上到下进行审查,但实际上,我们可能需要先理解某些逻辑上更重要的部分。模型应该能够引导我们按照正确的顺序进行审查。
关于未来的编程方向,Arvid认为:“我不认为所有的编程都会是自然语言,原因是这样的:如果我和Sualeh结对编程,Sualeh在电脑和键盘前,有时如果我在驾驶,我想对Sualeh说,‘嘿,实现这个函数,‘这是可行的。但有时向Sualeh解释我想让他做什么是如此烦人,所以我实际上接管了键盘,向他展示。我写了部分例子,然后它就有意义了,这是最简单的交流方式。“
“我认为对AI来说也是如此。有时与AI交流的最简单方式是展示一个例子,然后它会在其他地方做同样的事情。或者有时如果你在制作一个网站,向AI展示你想要什么的最简单方式不是告诉它做什么,而是拖动东西或画东西,也许最终我们会进入脑机接口或其他方式,你可以理解你在想什么。所以我认为自然语言会有一席之地。我认为它肯定不会成为大多数人大多数时候编程的方式。“
ML细节【ML details】
Cursor 是一款创新的代码编辑器,结合了自定义模型与尖端模型的优势,展现出其强大的功能。这种组合使得 Cursor 在多个任务中表现出色,尤其是在一些专门模型能够超越先进通用模型的领域。
Cursor 的一个显著特点是“Tab”功能,它展示了专用模型的强大之处。这些经过专门训练的模型在特定任务上的表现优于尖端模型,评估结果也证实了这一点。另一个专用模型发挥关键作用的功能是“应用(Apply )”功能,负责处理代码更改。
Aman 认为,其他工具中简单的 Apply 功能经常会失败,因为它试图进行确定性匹配,但至少有 40% 的情况下会失败,导致糟糕的用户体验。他认为,随着模型变得越来越智能,我们可以使用更少的 token 来表达意图,然后让模型完成具体的实现细节。这种方式既可以节省成本,也可以降低延迟。例如,我们可以使用 o1 模型生成高级计划,然后使用 Sonnet 和 Apply 模型递归地实现这些计划。
虽然尖端模型擅长规划代码并生成粗略的更改框架,但它们在生成精确的差异(diffs)时,尤其是在处理大文件时,表现不佳。为了解决这一问题,Cursor 采用了一个两步流程。首先,尖端模型生成一个粗略的代码块,指示所需的更改。然后,专用模型将该更改应用到文件中,避免了常见的问题,比如处理行号错误。
Aman 解释道:“如果你试图用 Sonnet 或 o1 这样的前沿模型来做这件事,它真的会搞砸一些愚蠢的东西,比如计数行号,特别是在处理超大文件时。”这种方法不仅提高了准确性,还能更高效地利用最智能的模型。通过在高级规划中使用更少的 token,结合较不智能的模型处理实施细节,Cursor 实现了性能和效率的平衡。
提高速度:推测性编辑(speculative edits)
速度是 Cursor 性能的一个关键因素,而实现这一目标的核心技术之一是推测性编辑,这是一种推测性解码的变体。Aman 描述了这个过程:“通过推测性解码,你可以利用语言模型生成时在内存受限的情况下处理多个 token 的优势,这比一次生成一个 token 要快。”
在代码编辑的上下文中,Cursor 利用现有代码的强先验知识。系统将原始代码块反馈给模型,模型通常会同意输出相同的代码。这一过程并行进行,直到出现分歧点,即模型预测的文本与原始代码不同。此时,系统生成那些 token,然后重新开始使用新的代码块进行推测。
其结果是一个比普通代码编辑快得多的版本,允许快速流式传输更改。Sualeh 补充道:“而且它的优势在于,在流式传输的同时,你可以在代码未完全加载完之前就开始审查它,因此没有冗长的加载屏幕。”
Sualeh 认为,"推测"(speculation)是一个普遍的概念,不仅应用于语言模型,还应用于 CPU、数据库等领域。
GPT 与 Claude 在编程中的对比【GPT vs Claude】
在“哪个大型语言模型更擅长编程?GPT、Claude 还是其他模型?”的问题上,
Aman 认为,没有任何一个模型在所有方面都占据绝对优势。他们评估模型的指标包括速度、代码编辑能力、代码处理能力、上下文长度和编程能力。目前综合表现最佳的模型是 Sonnet。o1 模型虽然擅长推理,在编程面试和 LeetCode 问题上表现出色,但它对用户意图的理解不如 Sonnet。其他一些尖端模型在基准测试中表现出色,但在实际应用中,当遇到超出基准测试范围的任务时,Sonnet 的表现更为稳定。
Lex 询问,实际编程体验与基准测试之间有什么区别?基准测试有哪些不足之处?
Sualeh 指出,基准测试中的代码通常是面试风格的代码,问题定义明确。而实际编程中,用户的表达可能不够清晰,任务的上下文也更加复杂。程序员需要理解用户的意图,并满足他们的需求。
Michael 补充说,基准测试很难准确反映真实的编程体验,因为实际编程环境非常复杂,任务目标往往不够明确。此外,公开的基准测试还会带来数据污染问题。例如,SWE-Bench 是一个流行的代理基准测试,但其数据已经被大型语言模型的训练数据污染。如果让这些模型解决 SWE-Bench 问题,即使不提供代码库上下文,它们也能凭空捏造出正确的文件路径和函数名。
Aman 指出,模型可能在训练过程中接触过 SWE-Bench 使用的代码库,例如 SimPy。为了获得准确的评估结果,实验室不太可能从训练数据中剔除这些流行的代码库。
Michael 认为,鉴于基准测试的局限性,一些机构采用人工评估的方式来判断模型的改进方向。一些大型语言模型公司会雇佣人员专门进行模型评估。Cursor 团队也会进行内部的定性评估,并参考用户的反馈意见。
Arvid 用“氛围”(vibe)来形容这种评估方式。
Lex 表示赞同,并将其称为“氛围基准测试”(vibe benchmark)。
Lex 提到,他也会通过阅读在线论坛、Reddit 和 X 来了解用户的评价。但他发现,用户的评价往往比较主观,例如“我觉得 Claude 或 GPT 变笨了”。他想知道,这到底是模型的问题还是用户的问题。
Aman 提到一个关于 Claude 性能下降的有趣说法:AWS 使用的芯片与 Nvidia GPU 的数值精度略有不同,Claude 在 AWS Bedrock 上运行的量化版本可能导致性能下降。
Lex 开玩笑说,他采访过很多有阴谋论的人,很高兴 Aman 也提到了这个阴谋论。
Sualeh 认为,这不是阴谋论,而是现实问题。人类的表达存在差异,芯片的精度也存在差异,这些因素都可能导致 bug。我们很难完全避免 bug 的出现。
提示工程与设计【Prompt engineering】
有效提示在最大化语言模型性能中的作用至关重要,特别是不同模型对不同提示的响应不同。Arvid 描述了 Cursor 的提示设计方法,借鉴了网页设计的原则:
“我们内部有一个叫 Preempt 的系统,帮助我们做这件事。我认为它是为 8000-token 上下文窗口之前的时代构建的。这有点类似于你在创建网站时的做法。你希望它在移动设备上运行良好,也希望它在桌面屏幕上运行良好,并且你拥有的是动态信息,而不是静态的。”
Cursor 的提示设计系统使用类似 React 的声明式方法,在 JavaScript 中使用 JSX 来指定提示中的优先级和结构。此方法使调试更容易,并且可以更灵活地呈现提示,适应不同的上下文窗口大小和模型要求。
虽然这种复杂的提示工程是在幕后进行的,但团队的目标是使用户体验尽可能自然和轻松。正如 Arvid 所言:“我认为我们的目标是让用户做最自然的事情,然后我们的工作是找出如何检索相关事件,使你的思路真正有意义。”
然而,讨论也涉及了允许用户在提示中“懒惰”和鼓励他们提供更清晰详细的指令之间的紧张关系。Aman 提出了潜在的解决方案,以解决用户查询中的歧义,例如让模型请求澄清或呈现多个可能的生成结果供用户选择。
Sualeh 描述了 Cursor 最近增加的一个旨在减少不确定性的功能:“我们做的一件事,最近增加的,是尝试建议你可以添加的文件。当你输入时,它可以猜测出不确定性,并可能建议你正在编写 API,我们可以利用你之前在同一文件中的提交记录来猜测客户端和服务器的关系,这非常有用。”
这一功能展示了 Cursor 为平衡用户便利性与与 AI 模型的清晰有效沟通所做的持续努力,最终旨在提升用户的编码体验和生产力。
人工智能代理(AI Agents)
在人工智能领域,代理(agents)是一个引人注目的概念。它模仿人类行为,让人感觉更接近通用人工智能(AGI)。然而,目前代理在许多方面还未达到实用水平,但我们正在接近这个阶段。
对于某些特定任务,代理可能会非常有用。例如,在处理软件bug时,能够简单地描述问题并让代理自主完成修复会非常方便。Arvid提到:“如果我们的聊天输入框偶尔无法使用Command+C和Command+V,我希望能有一个代理,我只需用两句话说‘这不工作,请修复它‘。然后代理就会去执行,一天后我回来审查结果。“
这种代理需要能够找到正确的文件、重现bug、修复问题并验证修复是否正确。这可能是一个耗时的过程,但对于程序员来说会很有价值。
然而,Arvid认为代理不太可能完全取代编程工作:“很多人认为代理会接管所有编程工作。我们不这么认为,因为编程的大部分价值在于迭代。你通常不想一开始就完全指定所有内容,因为直到看到初始版本之前,你可能并不真正知道自己想要什么。然后你会想要在此基础上进行迭代并提供更多信息。“
对于大多数编程任务,更理想的系统是能够立即给出初始版本,然后允许程序员快速迭代。不过,对于某些特定类型的编程任务,比如设置开发环境、解决软件包问题、配置数据库和部署应用程序等,使用代理可能会很有帮助。
Arvid表示,虽然Cursor目前没有积极开发这类功能,但它们确实在公司的考虑范围内:“我们希望让程序员的生活更轻松、更有趣。有些任务非常繁琐,需要经过很多步骤,你会想把这些任务委托给代理。“
此外,在后台使用代理也可能带来好处。例如,当程序员在处理同时涉及前端和后端的PR(Pull Request)时,可以在后台运行一个代理。当程序员专注于前端工作时,代理可以为后端部分准备一些初始代码,等程序员转向后端工作时就有了一个可以迭代的基础。
速度优化
Cursor的一个显著特点是其快速响应能力。为了实现这种高速性能,团队采用了多种技术策略。
Aman解释了一种称为“缓存预热“的技术:“当用户在输入时,你可以预测可能会用到的上下文信息。因为重用KV(Key-Value)缓存可以降低延迟、减少成本,所以当用户开始输入时,你可以立即用当前文件内容预热缓存。这样当用户按下回车键时,实际需要预填充和计算的token就很少了,这会大大降低首个token的生成时间(TTFT)。“
KV缓存是Transformer模型实现高效处理的关键机制。Aman详细解释道:“Transformer的工作原理之一是使用注意力机制中的键(keys)和值(values)来查看之前的token。通常情况下,对于每个token,模型都需要对整个提示进行完整的前向传递,这涉及大量矩阵乘法,速度非常慢。但如果你已经计算并存储了键和值,并将它们保存在GPU中,那么在处理后续token时,就不需要再对之前的token进行全模型的前向传递了。你只需要对最新的token进行前向传递,然后在进行注意力计算时重用之前计算好的键和值。这大大提高了处理速度。“
除了KV缓存,还有其他类型的缓存策略可以提高性能。Aman提到了一种有趣的技术:“对于Cursor的Tab补全功能,你可以预测用户接受建议后的情况,并触发另一个请求。这是投机执行和缓存的结合。当用户按下Tab键时,下一个建议就已经准备好了,给人一种非常快速的感觉。“
Sualeh补充道:“如果你能让KV缓存变小,一个好处是可以进行更多的投机预测。也许你可以猜测10个可能有用的东西并预测接下来的10个。用户击中这10个中的一个的概率要比击中你只显示的那一个高得多。这里的一般现象是,模型的单个样本可能不太好,但如果你预测10个不同的东西,其中一个是正确的概率就高多了。“
为了进一步提高速度,研究人员还开发了更高效的注意力机制。Aman解释道:“以前人们主要使用多头注意力(multi-head attention),但现在已经转向更高效的方案,比如组查询(group query)或多查询注意力(multi-query attention)。这对于使用更大的批处理大小来更快地生成token非常有帮助。“
这些技术的主要目标是减少KV缓存的大小。Aman继续解释:“多查询注意力是最激进的方法,它只保留查询头,去掉了所有的键值头。组查询则保留了所有查询头,但减少了键和值的头数。这些方法的目的都是减小KV缓存的大小。“
Arvid和Aman还提到了一种名为MLA(multi-latent attention)的新技术,这是由DeepSeek公司开发的。Sualeh解释道:“MLA的关键思想是,你保留一个大的共享向量来存储所有的键和值,然后为每个token存储更小的向量。这是一种低秩减少的方法,在最终计算时,你可以将潜在向量展开回来。这种方法更有效,因为你减少了需要保存的向量大小。“
这些优化技术对用户体验有直接影响。Aman总结道:“这主要带来两个好处:首先,你可以使缓存更大,因为分配给KV缓存的空间更少。这意味着你可以更激进地缓存更多内容,从而获得更多缓存命中,这有助于减少首个token的生成时间。其次,当你开始处理更多请求和更大的批处理大小时,token生成速度不会明显降低。“
Sualeh补充说,这些优化还允许在某些情况下使用更大的提示,因为KV缓存的大小是所有提示的大小乘以并行处理的提示数量。这意味着可以在不降低token生成延迟的情况下增加批处理大小或提示大小。
这些技术共同作用,使得Cursor能够提供快速、流畅的用户体验,即使在处理复杂的编程任务时也能保持高效性能。
代码后台运行【Running code in background】
Arvid 在一篇名为《影子工作区:在后台迭代代码》的博文中探讨了代码后台运行的机制。他指出,Cursor 团队希望在后台进行大量操作,并正在进行多项实验。目前,除了缓存预热和确定命令键提示的正确上下文之外,后台操作并不多。但他们的目标是,如果能够在后台进行计算,就能在比仅仅预测用户接下来的几行代码更长的时间范围内为用户提供帮助,例如预测用户在接下来的 10 分钟内会编写什么代码。通过在后台运行,可以投入更多计算资源来实现这一点。
Arvid 提出的“影子工作区”概念,Cursor 团队正在内部用于实验,其核心思想是,为了充分利用后台操作的优势,需要向模型提供某种反馈信号。否则 ,仅仅让模型思考更长时间就能获得更高的性能,例如 o1 就是一个很好的例子。
提高性能的另一种方法是让模型迭代并获取反馈。对于程序员来说,一个非常重要的反馈来源是语言服务器。大多数编程语言都有自己的语言服务器,它们可以通过语言服务器协议与 VS Code 等编辑器进行交互。语言服务器可以告知程序员代码中的错误,例如“此处使用了错误的类型”,还可以允许程序员跳转到定义并理解代码结构。例如,TypeScript 语言服务器由 TypeScript 团队开发,Rust 语言服务器由 Rust 团队开发,它们都通过语言服务器协议与 VS Code 进行交互。这样,VS Code 不需要内置所有不同的语言,而是可以使用现有的编译器基础设施。
Lex 进一步询问了语言服务器在 Cursor 中的使用方式,Arvid 解释说,Cursor 使用语言服务器向程序员展示与 VS Code 中相同的信息,但他们的目标是将这些信息也展示给 AI 模型,并且希望以一种不影响用户的方式在后台进行。影子工作区的思路是,生成一个隐藏的 Cursor 窗口,在这个窗口中,AI 代理可以随意修改代码,只要不保存即可,因为它仍然指向相同的文件夹,并且可以从代码检查器获取反馈,跳转到定义并迭代代码。
Lex 认为,最终的目标是在后台运行所有内容,甚至运行代码。Arvid 表示,这确实是最终版本的目标,并且他的博文很大一部分内容是关于如何实现这一点,因为这有一定的技术难度。为了精确地反映用户的环境,需要在用户的机器上运行代码。在 Linux 上,可以通过镜像文件系统的方式,让 AI 对文件进行更改,它会认为自己是在操作文件级别,但实际上这些更改存储在内存中,并且可以通过创建类似内核的扩展来实现这一点。而在 Mac 和 Windows 上,实现起来则更加困难,但这同时也是一个有趣的技术挑战。
Aman 提出了一种可能比较“hacky”但很有趣的想法:对保存操作加锁。语言模型可以持有保存到磁盘的锁,用户操作的实际上是之前影子工作区中的内容和那些只存在于内存中的未保存内容,用户仍然可以获得代码检查器的错误提示并在其中编写代码。当用户尝试运行代码时,会显示一个警告,提示存在一个锁,如果用户尝试同时进行操作,则可以从语言服务器或影子工作区收回锁。
关于代码调试的探讨【Debugging】
Lex 认为允许模型修改文件是一个令人兴奋的未来方向,尽管这听起来有些吓人。他设想人工智能代理可以自动执行一系列任务,让用户第二天只需审查结果,就像与同事合作一样。
Aman回复,模型的可运行性存在不同版本。对于用户在几分钟内完成的简单任务,在本地机器上运行是合理的。而对于需要更长时间和更大改动的任务,则需要在远程沙盒环境中进行。如何精准复制用户环境到远程沙盒,以确保代码运行结果一致,是一个极具挑战性的问题。
Sualeh 提问,大家希望 AI 代理在编码方面扮演什么角色?例如查找 bug 或实现新功能。
Lex 回应说,他认为 AI 代理的应用不仅限于编码,还包括视频编辑等领域。例如,Adobe Premiere 等软件背后存在大量代码,尽管文档匮乏,但可以通过代码与其交互。Lex 自己在 YouTube 上的所有操作,包括上传、翻译、配音等,都是通过代码完成的。他设想人工智能代理可以自动化许多与编辑无直接关系的任务。 至于编码方面,Lex 主要关注 bug 查找,包括各种级别的 bug,尤其是逻辑错误,以及实现方向上的错误。
Sualeh 补充说,他希望 AI 代理能够发现一些“神奇”的 bug。
Aman 指出,尽管大型语言模型在代码生成和问答方面表现出色,但在 bug 查找方面却非常糟糕,即使是最先进的模型(如 o1)也是如此。
Lex 询问了这种现象的原因。Aman 解释说,模型的性能很大程度上取决于预训练数据。虽然随着损失函数的降低,模型的泛化能力会增强,但目前的损失函数和规模还不足以使模型在代码理解上完全泛化。代码生成和问答在预训练数据中大量存在(例如 GitHub 代码和 Stack Overflow 问答),而 bug 检测的例子相对较少,导致模型在这一方面的能力不足。类似于预训练模型在代码生成到 Cursor Tab 目标上的迁移,未来也会出现从通用代码模型到 bug 检测的迁移,但需要一些额外的引导。
Sualeh 补充说,模型在预训练过程中已经建立了对代码的理解,并且可能已经察觉到代码中存在问题,但如何有效地识别和表达这些问题是关键所在。人类程序员能够区分 bug 的重要性,例如哪些 bug 只是小问题,哪些 bug 会导致服务器宕机。这部分取决于经验,例如资深工程师知道哪些代码曾经导致过严重问题。模型需要根据用户的“偏执程度”进行调整,例如在实验性代码中不必过于严格,而在生产环境代码中则需要更高的警惕性。即使将模型的“偏执程度”设置为最高,其 bug 检测能力仍然不足。
关于危险代码和调试未来的探讨【Dangerous code】
Lex 提及,判断代码的重要性对人类来说也是一项挑战。他引用 Arvid 网站上的一个原则:如果某行代码可能造成严重后果,应该添加注释,并多次重复“危险”字样。Lex 认为这反映了人性的特点:即使是同一个人,也可能忘记某段代码的潜在风险,尤其是在代码量很大的情况下。
Arvid 补充道,这种做法也有助于当前的 AI 模型识别危险代码,提高 bug 查找的效率。Lex 认为,明确标注代码的潜在危害程度是一种良好的实践。Arvid 表示,这种做法存在争议,例如 Sualeh 就不太喜欢。Sualeh 承认,虽然从美学角度来看他不喜欢这种做法,但它确实对模型和容易遗忘的人类很有帮助,可以避免一些小的错误导致严重的 consequences,例如服务器宕机。Aman 补充说,即使是普通的文档字符串,人们在修改代码时也经常会忽略,因此需要明确指出潜在风险。Lex 总结道,人们在修改代码时往往只考虑如何改进功能,而忽略了潜在的风险。
Arvid 认为,如果能够对所有代码进行形式化验证,就可以确保不会引入 bug。Aman 询问了这种未来的具体形态。Arvid 设想,人们不再需要编写测试,模型会根据代码自动生成规范,用户只需审查规范即可。同时,智能推理模型会验证代码是否符合规范。他认为,这种方式适用于大多数函数。Michael 质疑,规范的生成是否真的容易?对于某些难以用规范语言描述的需求,形式化验证是否可行?Arvid 确认,他设想的规范是形式化的,而不是自然语言描述的。Michael 认为,对于难以用规范语言描述的需求,形式化验证可能不是万能的。Aman 担心这会导致大量的规范文档。Michael 认为,规范可以取代单元测试。Arvid 认为,规范语言可以不断发展,以涵盖更多需求。
Lex 询问,Arvid 的设想是否适用于整个代码库,而不仅仅是单个函数。Arvid 承认,对整个代码库进行形式化验证更难,但他认为这是值得追求的目标,并且从理论上是可行的。例如,最近有一些研究可以对硬件进行形式化验证,包括 C 代码、GCC 编译器和 Verilog 硬件描述语言。他认为大型代码库也类似于多层系统,如果可以分解并分别验证每个部分,那么形式化验证整个代码库应该是可能的。但他承认,规范问题是一个真正的挑战。
Aman 询问,如何处理副作用和外部依赖,例如调用 Stripe API。Sualeh 建议 Stripe 为其 API 编写规范。Aman 质疑,是否所有外部依赖都可以提供规范?例如,如果程序中使用了语言模型作为原语,如何将其纳入形式化验证?Arvid 认为,这仍然是可能的。Aman 询问,如何证明语言模型的性质?Arvid 认为,可以证明语言模型的对齐性,或者证明它能够给出正确的答案。Sualeh 表示,这是最终的梦想。Lex 认为,如果这能够实现,将有助于确保代码的正确性和 AI 的安全性。
Lex 提问,既然模型在 bug 查找方面存在困难,那么未来的希望在哪里?
Sualeh 表示,他希望模型首先能够帮助发现一些简单的 bug,例如 off-by-one 错误或注释与代码不一致的情况。最终,模型应该能够发现更复杂的 bug。Michael 补充说,强大的 bug 查找模型对于实现 AI 编程至关重要。如果 AI 能够自动生成代码,那么也需要能够验证代码的正确性。这不仅是为了帮助人类程序员,也是为了验证 AI 生成的代码。Arvid 介绍了一种训练 bug 查找模型的方法:首先训练一个模型在现有代码中引入 bug,然后训练另一个模型利用这些合成数据查找 bug。
Michael 补充说,还可以利用大型模型和代码之外的信息来辅助 bug 查找,例如代码执行轨迹和调试器信息。他认为,bug 查找工具可能会有两种不同的产品形态:一种是在后台运行的快速模型,用于发现常见的 bug;另一种是用于解决特定 bug 的高计算量模型,用户可以付费使用。
Lex 提议,可以将付费机制整合到 bug 查找和代码生成中。他表示,如果模型能够找到 bug 或生成高质量的代码,他愿意付费。他举了一个例子,Cursor 生成了完美的 YouTube API 交互代码,帮助他实现了多语言字幕更新功能。他希望能有一个“打赏”按钮,既可以支持公司发展,也可以向模型发送积极反馈信号。对于 bug 查找,也可以引入类似 bug 赏金的机制。
Arvid 表示,公司内部对此存在争议。他认为,理想情况下,用户应该免费使用 bug 查找功能,只有在接受模型找到的 bug 时才需要付费。但他担心用户可能会复制粘贴代码,或者付费机制会影响用户体验。他认为,可以考虑将付费机制与产品分离,例如用户每月支付一定的费用,然后可以免费使用所有功能。
Lex 建议可以添加一个“打赏”功能,而不是强制收费。Arvid 认为,即使是打赏也涉及到金钱,可能会影响用户体验。Aman 认为,用户在分享模型生成的优秀代码时,就已经在表达对模型的认可了。Michael 认为,如果能够开发出一种技术手段来验证 bug 是否已被修复,那么就可以避免依赖荣誉制度的赏金机制。
关于终端交互、数据库分支和基础设施的探讨【Branching file systems】
Lex 询问,终端和代码之间有多少交互?从终端运行代码可以获得多少信息?是否可以实现一个循环,让模型运行代码、根据错误提示 改代码建议?目前代码和运行时是完全分离的吗?他知道可以在终端中使用 Ctrl+K 来辅助编写代码。
Aman 回答说,可以在 Check 命令和 Ctrl+K 中使用终端上下文信息。他们目前还没有实现循环功能,但认为这很有意义。问题在于,这个循环是在前台进行还是像之前讨论的那样在后台进行。
Lex 认为后台运行很酷,因为它可以支持以不同的方式运行代码。此外,还需要考虑数据库方面的问题,例如如何防止模型修改数据库。
Sualeh 介绍了一种新的数据库分支 API,例如 PlanetScale 和 Turbopuffer 数据库都支持这种功能。当开发者需要测试新功能时,可以使用数据库分支,避免直接修改主数据库。这种技术的实现方式是为数据库的预写日志添加分支。数据库公司需要不断开发新功能,而分支功能可能成为未来的一个趋势,AI 代理也可以利用数据库分支进行测试。
Aman 提出了一个有趣的想法:如果可以对文件系统进行分支会怎么样?Sualeh 表示赞同,他认为所有东西都需要分支功能。Lex 指出,这就像多重宇宙问题,如果对所有东西都进行分支,将会非常复杂。Sualeh 解释说,有一些巧妙的算法可以确保分支操作不会占用太多空间或 CPU 资源。
Lex 将话题转向基础设施,询问 Cursor 团队主要使用 AWS 的原因,以及使用 AWS 过程中遇到的挑战。Arvid 表示,AWS 非常出色,它的产品总是能够正常工作,虽然设置过程可能很麻烦。Lex 吐槽 AWS 的界面很糟糕。Arvid 认为,AWS 强大到不需要友好的界面。Sualeh 认为,这是 AWS 占据主导地位的结果。Arvid 总结道,AWS 值得信赖,如果出现问题,那很可能是用户自己的问题。
关于扩展挑战、本地模型和隐私问题的探讨【Scaling challenges】
Lex 询问 Cursor 作为一家初创公司,在用户规模快速增长过程中遇到了哪些挑战。Michael 回答说,随着请求量级的不断提升,缓存和数据库等通用组件都会遇到瓶颈。例如,他们遇到了数据表溢出等问题。此外,他们构建的一些定制系统,例如用于代码语义索引和问答的检索系统,也面临着扩展的挑战。
Sualeh 提到,即使是经验丰富的工程师也很难预测系统在扩展过程中会出现哪些问题。他以 Cursor 的代码检索系统为例,详细介绍了他们在扩展过程中遇到的挑战和解决方案。为了避免引入客户端错误,Cursor 团队将大部分代码信息存储在服务器端,并进行加密。一个关键的挑战是如何确保本地代码库状态与服务器端状态保持一致。一种简单的方案是定期下载服务器端的哈希值,并与本地哈希值进行比较,但这种方案会带来巨大的网络和数据库开销。为了解决这个问题,他们采用了 Merkle 树结构,只在根节点哈希值不匹配时才进行递归比较,大大降低了开销。
Sualeh 指出,随着用户数量和代码库规模的增长,系统扩展变得越来越困难。他们最初的方案在 Dark 代码库上运行良好,但对于一些拥有庞大代码库的公司来说,就不够用了。他们正在开发新的解决方案来应对这些挑战。
Aman 补充说,代码嵌入是索引系统的主要成本瓶颈。为了避免重复嵌入相同的代码块,他们采用了一种缓存机制,将代码块的哈希值与对应的向量缓存起来。这样,当同一公司的新用户使用 Cursor 时,代码嵌入速度会大大加快。此外,Cursor 服务器端不存储任何代码数据,只存储向量数据。
Lex 询问,代码库索引目前带来的最大好处是什么?Arvid 回答说,最明显的用途是在大型代码库中查找特定功能的实现位置。用户可以通过模糊的描述来提问,例如“我想找到实现 X 功能的地方”,模型通常能够找到正确的位置。Aman 补充说,未来代码库索引的功能会越来越强大,他们正在努力提高检索质量。
Lex 提问,为什么 Cursor 不考虑在本地进行代码嵌入等操作?Arvid 解释说,他们考虑过这种方案,但实现起来很困难。首先,许多用户的电脑性能不足,例如 80% 以上的用户使用 Windows 系统,其中很多电脑的性能并不强。其次,本地模型需要额外的开发工作量。随着模型规模的不断增大,在本地运行模型将会变得更加困难。Sualeh 补充说,即使是性能强大的 MacBook Pro,也很难处理大型公司的代码库。如果所有操作都在本地进行,用户体验会很糟糕。
Aman 指出,近似最近邻搜索在大规模代码库上会消耗大量内存和 CPU 资源。此外,未来的模型可能会采用 MOE 架构,虽然 MOE 模型对内存带宽的要求更高,有利于在本地运行,但模型的整体规模也会更大,甚至需要多台机器才能运行,这在本地几乎是不可能的。对于代码生成等任务,用户总是希望使用最强大、最智能的模型,这在本地很难实现。
Arvid 介绍了一种替代本地模型的方案:同态加密。用户可以在本地加密输入数据,然后发送到服务器端进行推理。服务器端可以使用强大的模型对加密数据进行处理,但无法看到数据的明文内容。推理结果会被加密后返回给用户,只有用户才能解密查看结果。目前同态加密的开销还很大,但如果能够降低开销,将会是一项非常有价值的技术。
Arvid 指出,随着模型变得越来越强大,它们将会处理越来越多的数据,这会导致数据集中在少数几个公司手中,带来安全和隐私风险。例如,为了防止 AI 模型被滥用,可能会引入监控机制,但这也有可能被滥用,导致对用户数据的监控。他希望同态加密能够解决这个问题。
Lex 认为,这是所有软件都面临的挑战。云服务提供了许多便利的功能,但同时也带来了隐私风险。我们需要依靠强大的安全措施来抵御攻击,但也需要警惕数据集中带来的潜在风险。
Sualeh 担心,未来强大的 AI 模型可能会被用于监控用户输入的 prompt。例如,Anthropic 公司的“负责任的扩展政策”要求对模型的 prompt 进行监控,以确保模型的安全。但他认为,如果所有信息都被监控,将会导致过度集中化,这是一个需要权衡的问题。
Aman 询问,为什么 AI 模型的监控比云服务提供商的监控更令人担忧?Arvid 解释说,用户可能会向 AI 模型提供一些他们从未上传到云端的个人数据。此外,AI 模型的监控更加集中化,云服务提供商通常允许用户使用自己的加密密钥,而 AI 模型的提供商则可以直接看到数据的明文内容。
关于上下文和模型训练的探讨【Context】
Lex 提出了他在使用 Cursor 时遇到的一个问题:如何为 Python 代码自动选择合适的上下文。例如,代码中导入的模块信息是否应该包含在上下文中。Michael 回答说,自动选择上下文是一个 tricky 的问题,未来还有很大的改进空间。增加上下文会降低模型的速度和增加请求的成本,从而限制模型调用次数和后台操作。此外,过多的上下文信息可能会让模型感到困惑,因此需要确保上下文的准确性和相关性。Cursor 目前在某些情况下会自动添加上下文,他们希望在这方面做得更好。
Michael 介绍了两种改进上下文选择的方法:一是改进检索系统,例如使用更好的嵌入模型和排序算法;二是让语言模型能够理解新的语料库,例如将上下文窗口扩展到无限大,并让模型能够有效地利用无限上下文。此外,还可以将语料库信息直接编码到模型权重中,类似于微调。目前还不清楚哪种方法最终会胜出,但 Cursor 团队目前更关注改进检索系统,选择与当前任务最相关的代码片段作为上下文。
Aman 以 VS Code 为例,说明了将知识直接编码到模型权重中的可能性。VS Code 的代码是开源的,大型语言模型在预训练过程中已经见过这些代码,并且经过微调和 RLHF 训练,能够回答与代码相关的问题。因此,当用户询问关于 VS Code 的问题时,模型有时能够给出正确的答案,尽管有时也会出现幻觉。如果能够专门针对某个代码库进行训练,模型的理解能力可能会进一步提高。
Aman 提出了一个开放性问题:模型应该端到端地完成所有任务(包括检索和代码生成),还是应该将检索和代码生成分离?未来几个月可能会出现比现有开源模型更强大的模型,届时可以单独训练一个优秀的开源模型作为检索器,为这些大型模型提供上下文。
Lex 询问,如何针对特定代码库进行模型训练?Aman 回答说,有很多方法可以尝试,例如可以模仿 VS Code 的训练方式,在继续预训练阶段加入特定代码库的数据,并在指令微调阶段加入关于该代码库的问题。这些问题可以是人工标注的,也可以是模型生成的。例如,可以利用模型生成关于代码片段的问题,并将这些问题作为指令微调的数据点。理论上,这种方法可以提高模型理解特定代码库的能力。
关于 OpenAI o1 模型、上下文隐藏、模型训练策略和竞争格局的探讨【OpenAI o1】
Lex 询问了 OpenAI o1 模型在编程领域的意义。Aman 认为,测试时计算(test time compute)是一个非常有趣的方向。随着数据规模和模型规模的增长,预训练模型在损失函数和下游任务上的表现都会越来越好。但是,我们现在开始遇到数据瓶颈,继续扩大数据规模变得越来越困难。因此,扩大测试时计算规模成为一个有潜力的方向。通过增加推理时的计算量,可以在不改变模型规模的情况下提高模型性能。例如,我们可以使用相同规模的模型,但延长推理时间,以获得与更大规模模型相当的性能。
Aman 认为,测试时计算的优势在于可以针对不同类型的查询采用不同的计算策略。例如,某些查询可能需要 100 万亿参数规模的模型才能处理,但这类查询可能只占所有查询的 0.1%。在这种情况下,专门训练一个如此庞大的模型是不划算的。我们可以训练一个能够处理 99.9% 查询的模型,然后针对少数需要更高智能的查询延长推理时间。
Lex 询问,如何判断哪些问题需要更高水平的智能?是否可以动态地选择使用 GPT-4、小型模型还是 o1 模型?Aman 承认,这是一个开放的研究问题,目前还没有人能够很好地解决模型路由问题。Cursor 团队在 Cursor Tab 功能中实现了简单的模型路由,但在 4o sonnet 和 o1 之间的切换还比较困难。此外,还需要考虑如何判断某个问题对 4o sonnet 来说是否过难,这可能需要 o1 级别的模型才能判断。
Lex 总结了模型训练的三个阶段:预训练、后训练和测试时计算。他询问,哪个阶段的收益最大?Aman 回答说,测试时计算比较特殊,因为它需要一套专门的训练策略才能发挥作用。此外,除了大型实验室(可能只有 OpenAI),没有人真正了解 o1 模型的内部机制。一些研究论文暗示了 o1 模型可能使用树搜索和过程奖励模型(process reward model),但具体细节尚不清楚。Aman 认为,测试时计算可以归类为后训练阶段,但未来用于训练支持测试时计算的模型的算力可能会超过预训练阶段。
Lex 询问,我们是否了解 o1 模型是否使用了思维链(chain of thought)以及其他技术?
Aman 表示,目前只能进行猜测。Lex 询问,如果要构建一个与 o1 竞争的模型,应该怎么做?Aman 认为,需要训练一个过程奖励模型。传统的奖励模型(也称为结果奖励模型,outcome reward model)只关注最终结果,例如对数学问题的最终答案进行评分。而过程奖励模型则尝试对思维链的每个步骤进行评分。OpenAI 去年发表了一篇关于过程奖励模型的论文,他们使用人工标注的数据集训练了一个过程奖励模型。目前,过程奖励模型主要用于从多个模型输出中选择最佳答案。未来,过程奖励模型可能会与树搜索结合,用于探索思维链的不同分支,并评估每个分支的质量。
Lex 提出了一个关于 AI 安全和哲学的问题:OpenAI 决定隐藏思维链,只向用户展示思维链的总结。OpenAI 表示,这是一个艰难的决定,他们会在后台监控思维链,以确保模型不会试图操控用户。Lex 询问,大家如何看待隐藏思维链的做法?Michael 认为,OpenAI 可能是为了防止他人窃取其技术。如果能够看到思维链的每个步骤,就更容易复制这项技术。
Lex 认为,也可以利用思维链数据来训练模型。Michael 举了一个类似的例子:一些大型语言模型 API 曾经提供访问日志概率的功能,但后来取消了这项功能。一种猜测是,日志概率信息可以帮助他人窃取模型的能力。
Michael 补充说,Cursor 团队仍在学习如何使用 o1 模型。他们将 o1 集成到 Cursor 中,是因为他们对这个模型很感兴趣,并且认为很多程序员也会感兴趣。但 o1 并不是 Cursor 默认体验的一部分,他们还没有找到一种将其无缝集成到编辑器中的方法。目前还不清楚如何最好地利用 o1 模型,也没有看到 o1 模型的杀手级应用。o1 模型可能有助于实现后台循环和代理模型,但还需要进一步探索。
Sualeh 补充说,他们有一些想法,但在发布之前需要找到真正有用的应用场景。Aman 指出,o1 模型存在一些 限制,例如不支持流式输出,这使得用户难以监控输出过程。此外,测试时计算和搜索技术还处于早期阶段,o1 模型可以看作是一个 v0 版本,还有很多需要改进的地方。他认为,未来测试时计算和搜索技术会得到快速发展,与预训练技术并驾齐驱。
Lex 询问,GitHub Copilot 似乎正在以某种方式集成 o1 模型,有人认为这意味着 Cursor 的末日到了。Arvid 和 Lex 开玩笑说,是时候关闭 Cursor 了。Lex 询问,Cursor 真的要完蛋了吗?Michael 认为,与 2010 年代的软件行业不同,AI 编程领域的潜力非常巨大,未来三到四年的最佳产品将会比现在的最佳产品强大得多。即使拥有大量的用户和品牌优势,如果停止创新,最终也会失败。这对初创公司和新进入者来说是一个好消息,这意味着他们有机会通过构建更好的产品来击败现有巨头。未来几年,关键在于构建最好的产品和系统,包括建模引擎和编辑器体验。
Aman 认为,Cursor 的优势在于其深度定制的模型和精心设计的用户体验,而不仅仅是快速集成新模型(如 o1)。
关于合成数据的探讨【Synthetic data】
Lex 引用 Aman 之前提到的“合成数据分类法”,请他详细解释。Aman 首先解释了合成数据的定义:与自然产生的数据(通常由人类活动产生)不同,合成数据是由模型或算法生成的。他将合成数据分为三类:
第一类:蒸馏
这类合成数据是由语言模型生成的 token 或 token 的概率分布,可以用来训练能力较弱的模型。这种方法无法生成比原始模型更强大的模型,但可以将昂贵的高延迟模型的能力提取到更小、更 specific 的模型中。
第二类:利用问题的不对称性
这类合成数据利用了某些问题中一个方向比另一个方向更容易的特点。例如,在 bug 检测问题中,引入 bug 比检测 bug 更容易。我们可以使用一个能力较弱的模型在代码中引入一些看似合理的 bug,然后用这些合成数据训练一个更强大的 bug 检测模型。
第三类:易于验证的文本
这类合成数据是由语言模型生成的易于验证的文本。例如,如果我们有一个可以检测文本是否达到莎士比亚水平的验证系统,那么我们可以让一群猴子随机敲打打字机,最终会得到足够的训练数据来训练一个莎士比亚水平的语言模型。这种方法在数学领域特别有效,因为形式语言的验证非常容易。我们可以使用一个还可以的模型生成大量的推导过程,然后选择那些能够证明真实定理的推导过程,用这些数据进一步训练模型。类似地,在代码领域,如果我们有一组测试用例,可以通过测试结果判断代码是否解决了问题,那么我们可以使用模型生成代码,并选择那些通过测试的代码来训练模型。
Aman 认为,这种方法在某些领域可能难以奏效,因为很难找到完美的验证器,尤其是在开放式任务或长 horizon 任务中。
Lex 指出,第三类合成数据需要一个验证器。Aman 确认了这一点,并补充说,理想情况下,验证器应该能够确定结果的正确性,例如使用测试用例或形式化系统,而不是使用语言模型进行验证。
Michael 补充说,也可以使用人工验证,例如手动进行质量控制。或者,可以使用语言模型来运行代码并理解输出结果,但这需要模型具备很强的理解能力。
Aman 认为,第三类合成数据最有可能带来巨大的收益。
关于 RLHF 和 RLAIF 的探讨【RLHF vs RLAIF】
Lex 询问了基于人类反馈的强化学习(RLHF)和基于 AI 反馈的强化学习(RLAIF)在提升模型性能方面的作用。
Aman 解释说,RLHF 使用的是从人类反馈中训练得到的奖励模型。如果能够获得大量针对特定任务的人类反馈,那么 RLHF 就能取得很好的效果。
RLAIF 则比较有趣,因为它依赖于验证比生成更容易的约束条件。也就是说,如果语言模型更容易验证某个解决方案的正确性,而不是生成这个解决方案,那么 RLAIF 就有可能实现一种递归循环,从而提升模型性能。
Aman 认为,RLAIF 不太可能以这种简单的递归循环的形式出现。另一种可能的方式是将 RLAIF 和 RLHF 结合起来。例如,在 Cursor Tab 功能中,模型通常能够生成比较正确的代码,只需要少量的人类反馈(例如 50 到 100 个例子)就能将模型的先验知识与用户的期望对齐。
Aman 指出,这种方法与传统的 RLHF 不同,传统的 RLHF 通常需要大量的训练数据来训练奖励模型。
关于生成与验证、AI 获得菲尔兹奖的可能性以及时间预测的探讨【Fields Medal for AI】
Lex 询问 Aman 对生成和验证或生成和排序的直觉比较。他认为排序比生成更容易吗?Aman 回答说,他的直觉认为确实如此。这可以追溯到 P 与 NP 问题,如果 P 不等于 NP,那么存在一大类问题,在给定证明的情况下更容易验证,而不是找到证明。
Lex wondered if AI could be used to prove or disprove P 等于 NP。Arvid 认为这将会非常棒。Lex 认为,如果 AI 能够做到这一点,它应该获得菲尔兹奖。但这引发了一个开放的哲学问题:谁应该获得荣誉?Michael 开玩笑说,应该是谁提出这个问题的人获得荣誉。
Sualeh 表示,他很好奇 AI 获得菲尔兹奖的可能性有多大,以及何时会发生。Michael 认为 Aman 是这方面的专家,应该问问他的预测。Lex 询问,是诺贝尔奖还是菲尔兹奖更容易先被 AI 获得?Sualeh 和 Arvid 都认为菲尔兹奖更容易先被 AI 获得。Lex 开玩笑说,Arvid 作为程序员当然会这样说。Arvid 解释说,菲尔兹奖通常颁发给在特定领域(例如数学)做出重大突破的研究,这类似于一个孤立的系统,更容易设计良好的奖励系统,因此更容易训练 AI 来解决这类问题。
Aman 认为,获得菲尔兹奖的路径还不太清晰。虽然 AI 已经能够解决一些奥数问题,并且在当时已有的研究基础上,还有一些容易实现的目标。但他对定理证明领域不太了解,也不确定 AI 距离解决那些真正困难的开放性问题还有多远。
Lex 询问,Aman 认为 AI 会先获得菲尔兹奖,而不是物理学或其他领域的奖项吗?Sualeh 认为 100% 会先获得菲尔兹奖,并且可能性很大。他认为,像 BSD 猜想或霍奇猜想这样的难题对 AI 来说仍然非常困难,目前还不清楚解决这些问题的路径是什么,更不用说训练 AI 来解决它们了。
Arvid 质疑 Aman 的观点,他认为数学问题可以看作是一个孤立的系统,可以设计良好的奖励系统,因此更容易训练 AI 来解决。Aman 认为,AI 可能会在实现通用人工智能(AGI)之前就获得菲尔兹奖。Sualeh 表示,如果 AI 能够获得菲尔兹奖,他会非常高兴。他预测 AI 获得菲尔兹奖的时间是 2028 年或 2030 年。Lex 认为,考虑到 AI 发展的速度,这段时间感觉像是永远。
关于缩放规律、蒸馏、计算资源分配和创新理念的探讨【Scaling laws】
Lex 提出了关于缩放规律(scaling laws)的话题,希望大家探讨一下这个概念的含义、现状和未来发展方向。
Aman 回顾了缩放规律的研究历程。最初 OpenAI 的缩放规律论文存在一些错误,例如学习率调整方面的问题。后来 Chinchilla 论文提出了更准确的版本。但现在人们又开始偏离计算最优的路线,转而更加关注在有限的推理预算下获得最佳性能。
Aman 认为,缩放规律的曲线维度比最初设想的更多,不仅仅是计算量、参数数量和数据规模。例如,推理计算量和上下文长度也是重要的维度。如果我们关注推理计算量和上下文长度,那么可能更倾向于训练某种状态空间模型(SSM),因为 SSM 在超长上下文中更高效。即使训练 SSM 需要 10 倍的计算量才能达到相同的能力水平,也是值得的,因为我们更关注在长上下文窗口下的推理预算。未来,人们将探索更多维度下的缩放规律。
Lex 指出,最初的缩放规律概念只关注模型规模(以参数数量衡量)和数据规模(以 token 数量衡量),以及两者的比例关系。Aman 表示赞同。Lex 询问,大家是否仍然相信“越大越好”(bigger is better)的理念?Aman 认为,对于原始性能和原始智能来说,更大的模型肯定更好。
Sualeh 补充说,他尤其看好蒸馏技术。如果我们投入大量资金进行训练,那么可以通过调整各种参数,获得能力最强、成本最低的模型。例如,Llama 模型就是通过在远超必要规模的数据集上过度训练 7B 参数的模型,来优化推理时计算量的。Gamma 模型则更进一步,它不是直接在 token 上训练,而是通过最小化与 Gamma 27B 模型输出分布的 KL 散度来训练,这是一种知识蒸馏的方法。
Lex 指出,蒸馏可以得到更快、更小的模型。Aman 解释说,蒸馏的目的是从训练数据中提取更多信号,这有助于克服数据瓶颈。我们可以使用更大的模型在所有 token 上进行训练,然后将知识蒸馏到更小的模型中,这样可以使更小的模型从每个 token 中获得更多信息。
Lex 询问,如果给他们 10 万亿美元的预算,他们会如何使用?Aman 认为,大型模型训练过程中存在很多秘密和细节,只有大型实验室才了解,如果贸然尝试,可能会浪费很多钱。
Lex 假设他们可以获得所有信息,包括训练模型的所有参数和启发式方法。在这种情况下,未来五年应该如何投资,才能最大化原始智能?Sualeh 认为,答案很简单,就是尽可能多地购买计算资源(例如 GPU)。然后研究人员可以根据需要选择训练大型模型还是小型模型。
Aman 质疑,我们真的是受限于计算资源和资金,还是受限于其他因素?Sualeh 认为,我们更可能是受限于想法,但也存在其他限制因素。Arvid 补充说,如果拥有大量的计算资源,就可以进行大量的实验。
Lex 询问,他们会选择进行大量的实验,还是使用这些计算资源来训练一个巨大的模型?Arvid 表示他会选择进行实验,因为他相信我们目前受限于想法。
Aman 认为,即使拥有无限的计算资源和数据,我们最终还是会受限于工程能力,甚至不仅仅是想法。世界上能够真正推动 AI 发展的人才并不多,而研究工作需要大量的工程努力。例如,最初的 Transformer 论文,除了将现有的概念整合在一起之外,还需要大量的编码工作,例如编写 CUDA 内核,并进行优化,以充分利用 GPU 的性能。这需要像 Noam Shazeer 这样顶尖的工程师才能完成。
Aman 举了另一个例子:下一代模型的模型并行化,需要在数千甚至数万个 GPU 上进行扩展,这需要大量的工程工作。如果能够将工程成本降低 10 倍,让那些拥有优秀想法的人能够轻松地实现他们的新架构,并在 GPU 上获得 50% 或 40% 的利用率,那么研究速度将会大大加快。
Sualeh 认为,如果看到一条清晰的改进路径,就应该先抓住唾手可得的成果。OpenAI 和其他实验室的做法是正确的,他们抓住了缩放模型带来的红利,例如 GPT-4.25。只要现有的方法有效,就没有必要尝试新的想法。只有当现有方法遇到瓶颈时,才需要新的想法。如果拥有 10 万亿美元的预算,那么可以先尝试扩大规模,然后重新评估想法。
Aman 认为,我们都需要新的想法才能最终实现 AGI。我们也相信,可以通过在较小的规模上测试新想法,并对其效果充满信心。但对于目前的实验室来说,将有限的研究和工程人才投入到探索新想法上是比较困难的,因为现有的方法在一段时间内仍然有效。
关于编程的未来、编程技能的演变以及 Cursor 理念的探讨【The future of programming】
Lex 询问 Cursor 团队,作为编程领域的中心人物,他们如何看待未来几年编程的本质变化?
Michael 认为,Cursor 团队致力于打造一个程序员长期处于主导地位的未来,强调程序员的速度、agency 和控制力。程序员能够修改任何想要修改的内容,并快速迭代构建的内容。这与一些人所追求的“与计算机对话式编程”不同。后者试图将编程简化为与工程师通过 Slack 沟通一样,将需求输入到一个孤立的文本框中,让 AI 自动完成所有工作。
Michael 指出,这种“对话式编程”存在一些问题。首先,它存在延迟问题,其次,它会导致程序员失去控制力。在文本框中进行沟通很难做到非常具体,程序员不得不将许多重要的决策委托给 AI。这与真正的工程实践相悖。一些不了解工程的人可能会认为,工程就是将完整的需求规格说明书交给工程师,然后工程师按照说明书进行编码实现。但实际上,最好的工程实践需要工程师做出大量的微观决策,并在速度、成本和其他系统因素之间进行权衡。只要人类仍然是软件的设计者和需求的制定者,我们就需要将控制权交给人类。
Michael 认为,未来编程的一种可能形式是,程序员可以控制代码库的抽象级别,并以伪代码的形式查看和编辑代码库,然后将更改反映到正式的编程语言级别。这种方式既保留了文本编辑的优势,又提供了更高的抽象级别,可以大幅提高生产力。
Lex 认为,能够在抽象层次之间自由切换将会非常棒。Michael 表示赞同,但这只是一个模糊的想法,还需要很多细节需要解决,最终能否实现还有待观察。但他相信,控制力、速度和以人为中心的理念非常重要。对于某些特定类型的编程任务,例如修复一个明确定义的 bug,可以采用“对话式编程”的方式。但大多数编程任务,尤其是那些程序员真正重视的任务,都需要程序员的深度参与。
Lex 询问,编程的基本技能是否会发生根本性的变化?许多热爱编程的年轻人担心,未来 AI 会取代程序员的工作。Michael 认为,现在是一个非常激动人心的软件开发时代。与 2012 年或 2013 年相比,现在的编程环境已经有了很大的改善,很多繁琐的样板代码和查找工作都被自动化了。现在的编程更加有趣,也更加专注于创造性。那些吸引人们学习编程的因素,例如快速构建、速度和个人控制,都得到了极大的增强。
Michael 认为,未来软件开发将会更加有趣,编程技能也会发生变化。程序员的品味和创造力将会得到放大,而样板代码编写和谨慎性(这对现在的程序员来说非常重要)的重要性将会降低。
Arvid 举了一个例子来说明未来编程的效率提升。最近他们需要对代码库进行一次比较大的迁移,将 Node.js 中的 AsyncLocalStorage(性能较差)替换为 Context 对象。即使使用现有的 AI 工具,这项工作也花费了他和另一位工程师五天的时间。他 envisions that 在未来,他只需展示几个例子,AI 就能自动应用到所有位置,并高亮显示新的情况,询问他应该如何处理。这样,整个迁移过程可以在 10 分钟内完成。程序员可以更快地迭代,而不需要预先进行大量的思考和设计,因为尝试新方案的成本很低。
Aman 补充说,现在的编程通常有两种方式:一种是预先仔细思考最佳方案,然后花费大量时间进行编码实现;另一种是直接上手编写代码,然后快速迭代。后一种方式更加有趣。
Lex 认为,AI 自动生成样板代码非常棒,这样程序员就可以专注于更细致、更困难的设计决策。他认为代码迁移是一个很好的例子,大型语言模型已经能够将代码从一种编程语言翻译到另一种编程语言,或者进行更广义的代码迁移。但他也担心,随着模型的能力越来越强,程序员需要做出的创造性决策会越来越少,最终可能会演变成使用自然语言作为主要的编程语言。
Lex 询问 Cursor 团队,对于现在想要学习编程的人,他们有什么建议?他们应该学习哪些编程语言?他回顾了 Cursor 团队成员早年学习的编程语言,例如 Java、PHP 和 Objective-C,并开玩笑说最终 JavaScript(而不是 TypeScript)将会胜出,统治世界,甚至可能与 PHP 共存。他还提到了 Donald Knuth 的观点,认为只有一部分人具备编程所需的心理素质,但他认为未来能够进行优秀编程的人群可能会扩大。
Aman 认为,不同的人学习编程的原因不同,但最好的程序员是那些真正热爱编程的人。例如,Cursor 团队中的一些成员下班后会继续使用 Cursor 编写自己的项目,甚至熬夜到凌晨 3 点。当他们感到沮丧时,他们会说:“我真的需要写代码。”这种对编程的热爱和痴迷造就了最好的程序员。他们会深入研究事物的运作方式。
Lex 询问,对于那些真正热爱编程的人,当超级 Tab 功能(例如 Cursor Tab)发展到极致时,他们会做什么?Sualeh 开玩笑说,他们会比任何人都更喜欢使用 Cursor Tab。Arvid 补充说,按下 Tab 键不仅仅是按下 Tab 键,而是在不断地注入意图。程序员有时会拒绝建议,有时会输入更多的字符,从而塑造最终的代码。他认为,未来的编程将会更多地关注“你想要创造什么”。
Sualeh 认为,与简单的打字相比,与计算机的沟通带宽将会越来越高,程序员可以通过更丰富的方式表达自己的意图。
Lex 引用了 Cursor 的宣言“工程天才”(Engineering Genius):“我们是一个应用研究实验室,致力于构建极其高效的人机协作系统。”这体现了 Cursor 对人机混合智能的重视。宣言中写道:“首先,我们正在打造未来的工程师,一个比任何单个工程师效率高出一个数量级的人机协作程序员。这位混合工程师将能够轻松地控制他们的代码库,无需进行任何低熵的按键操作。他们将能够以判断的速度进行迭代,即使在最复杂的系统中也是如此。通过结合 AI 和人类的创造力,他们将能够超越最优秀的纯 AI 系统。我们是一个由研究人员和工程师组成的团队。我们开发软件和模型,在实用性和可能性之间进行探索。我们的工作已经改善了数十万程序员的生活。”
Lex 最后总结道:“在实现这一目标的过程中,我们至少会让编程变得更加有趣。”
本文使用 Notion Nice 排版一键生成
以上,既然看到这里了,如果觉得不错,随手点个赞、在看、转发三连吧,如果想第一时间收到推送,也可以给我个星标⭐~谢谢你看我的文章,我们,下次再见。
点击关注和转发公众号 保持你对AI优质内容的敏感