← 返回博客

Zed 现在利用我们新的开源模型 Zeta 预测您的下一次编辑

Zed 生来为速度而生。我们一直致力于提供一种感觉“即时”的编辑体验。但有什么比即时更快呢?一个能预测您下一步动作的工具。这就是为什么我们在 Zed 中引入了编辑预测,由我们新的开源模型 Zeta 提供支持。

这是一个快速演练

编辑预测正在进行中。

在您工作时,Zed 现在可以预测您的下一次编辑,因此您只需按 tab 即可应用它。一旦您接受了一个预测,您可以通过反复按 tab 来执行多个后续编辑,从而节省时间和按键次数。我们收到了“大量”关于此功能的需求,我们倾尽全力使其感觉像是 Zed 体验的自然延伸。

在此公开测试版期间,您可以通过下载 Zed 并使用您的 GitHub 帐户登录来免费使用 Zeta。编辑预测不会永远免费,但目前我们很高兴能分享并学习。

周全的集成

编辑预测将 tab 转换成一个神奇的通用键。但是 tab 的现有用途,比如缩进,该怎么办?当同时存在编辑预测“和”语言服务器建议时,又会发生什么?我们不希望强大的新功能以牺牲 Zed 现有编辑体验为代价。

Zeta 预测与语言服务器补全。

当语言服务器补全可见时,Zed 不会预览预测的编辑,直到您按下 optionalt。一旦您按下修饰符,Zed 就会预览编辑并隐藏菜单,以实现无障碍查看。在 macOS 上,您只需按 tab 即可确认,或通过释放 option 来恢复语言服务器补全菜单。

在 Linux 上,alt-tab 通常被窗口管理器占用,因此我们提供了 alt-l 作为替代默认值。我们选择 l 是因为它在 QWERTY 主行上,并且在 Vim 中代表向右移动。如果您的 Linux 窗口管理器不占用 alt-tab,您也可以自由使用该绑定。

介绍 Zeta:Zed 的开源编辑预测模型

Zeta 源自 Qwen2.5-Coder-7B,并且完全开源,包括一个开放数据集。如果您正在使用开源仓库,我们希望您能通过为 Zeta 的数据集做出贡献来帮助我们改进它。请大家在初期耐心等待,因为我们将在发布前审查提交的数据,以确保每个人的安全和隐私。我们很高兴能解决这个问题,并看到社区共同努力,让编辑预测在所有地方都变得更好,尤其是在 Zed 中!

伴随视频

Zed 的开源编辑预测如何工作

Richard Feldman 和 Antonio Scandurra 讨论了 Zed 新的编辑预测功能是如何在幕后工作的。这包括 Zed 团队如何开发和开源了支持微调 Zeta 语言模型的代码和数据集!

在此观看视频 →

How Zed's Open-Source Edit Predictions Work

通过重写进行编辑

大多数编码模型都是在“填补中间”任务上训练的。您给它们一个前缀和一个后缀,它们生成中间的内容。

<|fim_prefix|>fn quicksort(array: &mut [T]) {
    if array.len() <= 1 {
        return;
    }
    let pivot = partition(array);
    <|fim_suffix|>
    quicksort(&mut array[pivot + 1..]);
}<|fim_middle|>

这适用于在光标处补全文本,但我们希望 Zeta 能够在任意位置预测编辑,这不符合这种结构。

根据我们的经验,模型在生成细粒度编辑方面表现不佳,但它们擅长重写更大的代码块。因此,我们从这里开始:给定最近编辑的列表和光标位置,我们要求模型重写光标周围的一段文本,并在重写文本中包含一个或多个编辑预测。

评估预测

在编写任何一行代码之前,我们创建了一组测试来检查我们的想法是否有效。测试大型语言模型的输出很棘手,因为每次运行,即使输入完全相同,您也可能会得到略有不同的结果。这可以通过使用 0 的温度,以及对于支持的提供商,为 RNG 提供种子来缓解。

话虽如此,代码通常可以用许多不同但同样有效的方式编写。因此,即使 Zeta 的输出与我们预期的答案不同,它仍然可能完全符合我们的要求——只是采取了不同的路径来实现。这使得在处理 LLM 时,传统的单元测试方法特别具有挑战性。

这使我们采取了一种不同的方法——Instead of strict assertions, we used a larger LLM to evaluate Zeta's edits. By writing our test assertions in plain English and having Claude check if the results matched our intent, we could validate that Zeta was making sensible edits, even when its exact output differed between runs. This ended up being much more practical than trying to make brittle assertions about specific tokens.

这是我们评估套件中的一个示例

// Input:
pub fn quicksort<T: Ord>(arr: &mut [T]) {
    let len = arr.len();
    if len <= 1 {
        return;
    }
 
    let pivot_index = partition(arr);
    <|user_cursor_is_here|>
}
 
// Assertion: Ensure that the quicksort function recurses to the left and to the right of the pivot.

Prompt 工程

我们首次尝试通过使用 Qwen2.5-Coder-32B 并为其提供明确的指示来使其通过这些测试,说明我们希望它预测哪些类型的编辑。这是我们使用的初始系统提示,您可以查看历史记录,了解我们如何不断更改它以使其通过评估套件。

这在最初的 4-5 次评估中出人意料地顺利。然而,一旦我们引入更多,我们开始注意到始终如一地通过所有评估变得越来越困难。更改提示导致新的评估通过,但旧的评估失败。总的来说,这感觉像是一个不稳定的过程,我们不相信这会导致系统足够健壮以用于生产。

此外,使用 32b 模型并不真正符合我们严格的延迟要求(稍后会详细介绍)。

有监督微调

在尝试了不同的方法后,我们决定使用 Unsloth 和 LoRA 进行监督微调。其思想是教 Zeta 两件关键事情:根据开发人员最近的编辑找出他们接下来可能想要进行的更改,然后将这些更改干净地应用到代码中,而不会引入奇怪的副作用。

但我们遇到了经典的鸡生蛋、蛋生鸡的问题——我们需要数据来训练模型,但我们还没有任何实际示例。因此,我们首先让 Claude 生成大约 50 个合成示例,并将其添加到我们的数据集中。然后,我们使用最初的微调通过功能标志发布了 Zeta 的早期版本,并开始从我们团队自己的使用中收集示例。

这种方法让我们快速建立了一个大约 400 个高质量示例的可靠数据集,这大大改善了模型!然而,我们不断遇到模型会出错的边缘情况。最令人恼火的是当 Zeta 在一个更大的文件中处理一小段代码时——它有时会感到困惑,并进行一些与用户意图无关的随机删除或插入,而且似乎添加更多示例也无法阻止模型犯这些错误。

直接偏好优化

为了处理这些边缘情况,我们使用直接偏好优化(DPO)进行了另一次尝试。这种技术让我们不仅仅是向模型展示好的编辑是什么样子的,我们还可以教它“避免”哪些编辑。通过 DPO,我们可以通过提供正例和负例来微调 Zeta,帮助它学习有用和有问题的编辑之间的细微差别。

我们发现,仅仅 ~150 个精心挑选的示例就足以显著改善 Zeta 在棘手情况下的行为。当然,我们认为通过扩展我们的训练数据并提供更多样化的示例,我们可以使其变得更好,我们很高兴能在这里继续突破界限。

最小化延迟:推测解码

与 Zed 的所有功能一样,延迟是编辑预测的关键因素。当我们开始时,我们设定了激进的性能目标:中位情况 (p50) 下预测应在 200 毫秒内交付,90% 百分位 (p90) 下应在 500 毫秒内交付。挑战在于,重写完整的摘录,同时启用多位置编辑,需要生成比简单的“填补中间”方法更多的标记。最初,这大大超出了我们的延迟预算。

然而,关于编辑预测的工作方式有一个引人入胜的见解。当我们重写文本片段时,输出通常与输入非常相似,变化集中在特定位置。这种模式使我们能够通过将输入作为参考来并行化令牌生成——这种技术称为推测解码。我们使用 n-gram 搜索来识别输入中有希望的起点,我们可以在那里开始并行令牌生成,从而在不牺牲质量的情况下显著提高速度。

最小化延迟:模型服务

为了让编辑预测响应迅速,我们需要并行解决多个延迟挑战。如上所述,我们通过推测解码解决了模型执行时间问题,但大规模服务模型带来了自身的一系列障碍。这是我们团队迄今为止遇到的计算最密集的问题。

在发布前几周,我们进行了一次简短的竞争性流程,结果我们对 Baseten 印象深刻。他们的性能工程师迅速优化了我们的开源模型,使其在他们灵活的基础设施上运行,达到了我们的目标延迟,同时让我们保留了对部署细节的完全可见性,无论是对于 Zed 团队还是整个 Zed 社区。我们计划发布一篇客座文章,介绍他们优化我们的模型所学到的经验。

延迟不仅仅是计算的功能;网络传输时间是感知速度的关键驱动因素。为了符合物理定律,我们将在北美和欧洲同时推出 GPU,并希望尽快增加更多区域。我们还在使用 Cloudflare Workers,在离您最近的数据中心处理您的请求。

结论

为了让编辑预测功能更强大,还有很多可以探索的地方。我们将快速跟进更多实验。我们计划向模型发送更多类型的上下文,并继续进行微调实验,我们将在 Zeta 数据集增长和演变时分享更新。

自去年秋天推出 Zed AI 以来,我们学到了很多。世界变化飞快,我们很高兴能探索和学习如何构建开发者喜爱的功能。我们也热衷于以 Zed 的方式构建 AI。从早期开始,我们就是开放软件构建方法的倡导者,即使这很困难,我们认为在处理 AI 时也没有理由改变这种方法。我们希望您能作为用户、贡献者或员工加入我们,共同努力,创造一个黄金未来。


正在寻找更好的编辑器吗?

您今天就可以在 macOS、Windows 或 Linux 上试用 Zed。立即下载


我们正在招聘!

如果您对我们博客中涵盖的主题充满热情,请考虑加入我们的团队,帮助我们实现软件开发的未来。