envd
是BuildKit的前端。就像Dockerfile一样。自从我开始从事这个项目以来已经过去了一年多。由于功能相对稳定,因此我想写一个有关我使用envd
的旅程的博客。
为什么我们需要这个工具
机器学习开发环境已经是一个痛苦点了一段时间。 “您现在正在使用哪个Python?”绝对是新手杀手。如果您需要使用CUDA,情况甚至更糟。 “它在我的机器上起作用!”发生了很多。
envd
的创建是为了解决机器学习开发环境的问题。但是,它远远超出了。
基础架构作为代码(IAC)
真是个名字!在这里,这意味着通过使用envd
配置文件,您将能够在不同的机器上获得相同的环境,无论是本地计算机,远程服务器还是Kubernetes群集。
纳米
一开始它被命名为MIDI
。但这对SEO不友好。
envd
中的d
没有官方含义(据我所知)。它可以是“ docker”,“深度学习”,“开发”等
有关更多信息,请检查此issue。
标识
我们有一个由Lily设计的可爱徽标。这是带有envd
字符的猫脸。
实际上,当我们创建GIF时,猫只眨了眨眼。 MacOS上的录制工具很难使用。这就是为什么它最终眨眼两次。顺便说一句,我们用SVG代替了它,以使动画清晰清晰。从头开始编写SVG动画并不难。
您可以找到草稿here。
安装
显然,envd
是一个Golang项目。但是,我们的目标受众主要使用Python。这就是为什么我们花费大量精力通过pip
支持安装。
我们知道,Python从未在分发预编译的二进制文件方面做得很好。我没有找到有关如何创建Python预编译的二进制发行版的好文件。人们只需复制并粘贴其他项目的代码即可。 envd
也是如此。该代码主要从koude11复制。
我确实从他人的贡献中学到新知识:
- 如今,cibuildwheel已经成熟。这是在CI中设置多平台分配管道的好工具。
- You can package a binary file without any Python code. (by frostming)
- 您可以创建Python ABI-agnostic wheel。 (由frostming)
当然,您可以使用conda-forge
。我试图创建a recipe for koude11。它具有完全不同的包装逻辑。
无根
作为开发人员,除非我必须使用,否则我不喜欢使用sudo
运行命令。当我试图与buildkit
守护程序进行调试时,我发现我们可以运行in rootless mode。
Starlark
Starlark是Python的方言,它使其易于用于机器学习工程师和数据科学家。
我知道很多配置文件都是用yaml编写的。我个人不喜欢它。您可能还会听到很多有关YAML格式的抱怨。我认为配置文件应该能够验证自己。
您可以在Starlark中使用if-条件,for-loop等。以下代码有效:
def build(libs, gpu=True):
base = "ubuntu:20.04"
if gpu:
base = "nvidia/cuda:11.2.2-cudnn8-runtime-ubuntu20.04"
for lib in sorted(libs):
install.python_packages(name=[lib])
有关更多信息,请检查Starlark spec。
尽管Starlark有解释顺序,但我们不依赖它。我们将把文件解析到内部图,并在其顶部构建BuildKit低级构建(LLB)图。这种权衡使得可以轻松缓存层。
Starlark也很容易扩展。我们添加了许多envd
特定功能,以使其更强大。您可以在reference中找到它们。它具有load
功能,类似于Python中的import
,可以加载另一个文件。我们创建了一个名为koude19的新的(因为保留import
)从GIT存储库中导入功能。人们可以创建自己的envd
构建功能并与他人共享。
VSCODE支持
为了使其更加用户友好,我们有一个用于envd
的Vscode extension,该功能提供以下功能:
- LSP:这使Starlark自动完成。
- 管理
envd
环境
BuildKit
这是envd
的后端。与之集成是麻烦的。主要是因为它没有任何文档。学习它的唯一方法是阅读examples。由于源代码以功能风格编写,因此很难理解。一旦您习惯了,事情就会更容易。
BuildKit中有一些不错的功能:
- 并行构建
- 可分配工人
- 更好的缓存
- 高级操作员
我们将逐一遍历它们。
平行构建
主要思想是将构建图拆分为多个子图,并在可能的情况下并行运行。当某些步骤需要很长时间完成而它们之间没有重叠时,这是一个很棒的功能。例如,我们可以并行安装系统软件包和CONDA环境。
相关的操作员是diff
和merge
。在merge
列表中,如果更改相同的目录,则后来的状态将覆盖先前的统计数据。有时,可能需要比您预期的更长的差异并将它们合并在一起。当您确定并行性节省时间时,应使用此方法。
可分发工人
基本上,前端将构建构建图并以协议缓冲区格式序列化,然后通过TCP或UNIX域插座将其发送到后端工人。
建议设置一个长期运行的buildkit守护程序并将其用作远程工人,因为这样它可以从缓存中受益。
默认情况下,我们将为envd
创建一个buildkitd
容器来构建图像。
更好的缓存
buildKit可以从/向本地/内联/注册表导入/导出缓存。您可以选择是否导出中间层。
默认情况下,缓存限制是磁盘空间的10%。您可以通过buildkit config进行配置。
envd
V0将下载包含基本开发工具和Python环境的前构建基础图像。如果依赖项都没有变化,则此图像可以用作缓存层。这是加快构建过程的好方法。您可以检查夜间构建benchmark。
Moby
目前,最好的用户体验是将envd
V1与moby
Worker一起使用。这需要Docker Engine版本> = 22。要启用它,您可以创建一个新的envd
上下文:
envd context create --name moby --builder moby-worker --use
需要提及moby
工人仍在实验中。由于issue,我们必须在使用moby
工人时在envd
中使用的disable the koude26 operator。因此,构建步骤可能会较慢,但是导出步骤会更快。总体而言,它仍然更快,尤其是当您拥有大图像时,这是机器学习的常见情况。
缓存
Docker层缓存是图像构建的常见优化。此外,我们还启用了APT软件包,Python Wheels,Vscode Extensions和oh-my-zsh
插件的缓存。这是通过在构建时间安装缓存目录来完成的。机器学习相关的PIP车轮可能很大,这使得高速缓存非常有用。
霍斯特
我完全同意,对于在线环境,一个容器应该只做一件事,通常意味着只运行一项服务。但是,对于开发环境,只要不相互冲突,就可以按照自己的意愿运行尽可能多的过程。
这就是为什么我们需要一个过程管理工具来控制所有这些过程的原因。我们探索了几种选择,例如systemd,s6 overlay,Supervisor。最后,我们决定使用简单而强大的Horust。您可以检查discussion。
外壳提示
我亲自将fish
与starship
一起使用,它提供了很好的盒外壳体验。 starship
可以与最常见的外壳(如bash
,zsh
,fish
等)配合正常。这很容易配置和扩展。您可以检查starship documentation。
当您拥有Nerd font时,它可以更好地工作,但是我们无法控制用户的终端配置,我们必须禁用一些花式图标。
jupyter笔记本和VSCODE中的编码
这些是机器学习工程师和数据科学家的最常见的编码工具。
是Jupyter笔记本电脑还是Jupyter实验室,可以作为普通Web服务暴露。
vscode在远程开发方面确实做得很好。您可以使用本地计算机上的VSCODE连接到远程服务器,甚至可以在远程服务器上运行的容器。
受许可证的限制,我们必须使用Open VSX Registry。有时,相关的CI测试由于其稳定性而失败。
在Kubernetes群集中发展
我们希望通过此功能能够通过envd
获利。但是,没有多少人对此感兴趣。该代码作为koude46开源。也许我们可以将此功能带入新的openmodelz项目。尽管您可以运行mdz exec {name} -ti bash
进入容器,但现在不支持vscode-remote。
使用指针接收器
这是使用envd
开发过程中最常见的错误。我们有一个内部构建图,该图具有许多构建LLB图的方法。并非所有这些方法都使用指针接收器,从而导致内部图的不一致状态。我希望将指针接收器用于所有方法。
您可能会很好奇棉绒不会抓住这一点。那是因为它可以以嵌套方式使用,而外部函数则使用值接收器时使用指针接收器。
这也是显示语言设计(个人选项)的一个很好的例子。您不会在Rust中看到这种错误。但是Rust没有一个良好的容器生态系统。 :(
进度条
默认的Docker进度栏确实很复杂。当我实施koude32 push功能时,我选择重复使用另一个进度栏,以使生活更轻松。尽管缺少多行日志支持。
SSH代理转发
实际上,我们可以将主机SSH凭据转发到容器中。因此,我们可以在主机机器中使用git
命令。
咀嚼0 v1
创建此新版本是为了解决envd
V0的不适当设计。主要的想法是envd
文件应该是BuildKit的更一般的前端。它应该能够构建任何图像,而不仅仅是机器学习开发环境。
这是一个比较:
功能 | v0 | v1 |
---|---|---|
是envd<v1.0 的默认值
|
||
支持开发 | ||
支持CUDA | ||
支持服务 | ||
支持自定义基础图像 | ||
支持安装多种语言 | ||
支持moby 建造者 |
使其更快
koude56功能应该能够更快地运行。如果您对envd
开发感兴趣,则可以尝试。
遗憾
此功能将使其更强大,但也具有复杂性。
用户可以使用低级操作员来构建图形。我们可以按用户定义的顺序从envd
文件执行命令。
许多开发环境并非一镜头。该建议希望跟踪运行环境中的更改并相应地更新envd
文件。
概括
这是我第一次可以作为我的日常工作进行开源项目。我从社区中学到了很多东西。我希望更多的人可以从envd
中受益。