← 返回博客

Zed 现在通过我们的全新开放模型 Zeta 预测您的下一次编辑

2025 年 2 月 13 日


Zed 专为速度而生。我们一直致力于提供一种感觉即时的编辑体验。但是,有什么比即时更快?一种预测您的下一步操作的工具。这就是为什么我们推出 Zed 中的 编辑预测,由我们的全新开源模型 Zeta 提供支持。

这是一个快速演练

编辑预测的实际应用。

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

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

周到的集成

编辑预测将 tab 转换为神奇的通用键。但是,tab 的现有用途(例如缩进行)又该如何处理?当同时存在编辑预测来自您的语言服务器的建议时会发生什么?我们不希望强大的新功能以牺牲 Zed 中现有的编辑体验为代价。

Zeta 预测与语言服务器完成一起使用。

当语言服务器完成可见时,在您按下 optionalt 之前,Zed 不会预览预测的编辑。按下修饰键后,Zed 会立即预览编辑并隐藏菜单,以便进行无障碍审查。在 macOS 上,您只需点击 tab 确认,或释放 option 以恢复语言服务器完成菜单。

在 Linux 上,alt-tab 通常由窗口管理器保留,因此我们提供 alt-l 作为替代默认值。我们选择 l 是因为它位于 QWERTY 主行上,并在 Vim 中表示向右移动。如果您的 Linux 窗口管理器没有声明 alt-tab,您可以随意使用该绑定。

隆重推出 Zeta:Zed 的开源编辑预测模型

Zeta 衍生自 Qwen2.5-Coder-7B,并且是完全开源的,包括一个开放数据集。如果您正在开源存储库中工作,我们很乐意您通过为 Zeta 的数据集做出贡献来帮助改进 Zeta。请一开始耐心等待,因为我们将在发布之前审查提交的数据,以确保每个人的安全和隐私。我们很高兴能弄清楚这一点,并看到社区共同努力,使编辑预测在任何地方都变得更好,尤其是在 Zed 中!

配套视频

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

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

在此处观看视频 →

通过重写进行编辑

大多数编码模型都经过“填充中间”任务的训练。您给他们一个前缀和一个后缀,他们会生成两者之间的内容。

<|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 时特别具有挑战性。

这促使我们采取不同的方法——我们没有使用严格的断言,而是使用更大的 LLM 来评估 Zeta 的编辑。通过用简单的英语编写我们的测试断言,并让 Claude 检查结果是否符合我们的意图,我们可以验证 Zeta 是否正在进行合理的编辑,即使它的确切输出在运行之间有所不同。最终,这比尝试对特定令牌进行脆弱的断言要实际得多。

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

// 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.

提示词工程

我们首先尝试使用 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 毫秒内交付。挑战在于,重写完整的摘录,同时启用多位置编辑,需要生成比简单的中间填充方法多得多的 tokens。最初,这使我们远远超出了我们的延迟预算。

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

最小化延迟:服务模型

为了使编辑预测感觉灵敏,我们需要并行解决多个延迟挑战。如上所述,我们通过推测性解码解决了模型执行时间问题,但大规模服务模型提出了其自身的一系列障碍。这是我们团队迄今为止解决的最计算密集型的问题。

在发布前几周,我们进行了一个简短的竞争过程,最终我们对 Baseten 印象深刻。他们的性能工程师迅速优化了我们的开源模型,使其能够在他们灵活的基础设施上运行,在实现我们的目标延迟的同时,让我们能够完全了解部署的细节,这对 Zed 团队和整个 Zed 社区都是如此。我们计划跟进一篇关于他们优化 我们的模型 的经验的客座文章。

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

结论

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

自从去年秋天我们推出 Zed AI 以来,我们学到了很多东西。世界变化很快,我们正在享受探索和学习构建开发者喜欢的功能的乐趣。我们也很高兴以 Zed 的方式使用 AI 进行构建。从早期开始,我们就一直是构建开放式软件的支持者,即使这很困难,而且我们认为在处理 AI 时没有理由改变这种方法。我们希望您能以用户、贡献者或员工的身份加入我们,因为我们努力实现一个美好的未来。