高级用法¶
TorchX 为您定义了插件点,以便您配置 TorchX 以最佳支持您的基础设施设置。大多数配置是通过 Python 的 入口点 完成的。
注意
入口点需要安装包含它们的 Python 包。 如果你没有 Python 包,我们建议你创建一个,以便在团队和组织内共享你的资源定义、调度程序和组件。
下面描述的入口点可以在你的项目的setup.py 文件中指定为
from setuptools import setup
setup(
name="project foobar",
entry_points={
"torchx.schedulers": [
"my_scheduler = my.custom.scheduler:create_scheduler",
],
"torchx.named_resources": [
"gpu_x2 = my_module.resources:gpu_x2",
],
}
)
注册自定义调度器¶
您可以通过实现 .. py::class torchx.schedulers.Scheduler 接口来实现自定义调度器。
函数 create_scheduler 应该具有以下函数签名:
from torchx.schedulers import Scheduler
def create_scheduler(session_name: str, **kwargs: object) -> Scheduler:
return MyScheduler(session_name, **kwargs)
您可以通过在您的 Python 项目中添加一个 entry_points 定义来注册这个自定义调度器。
# setup.py
...
entry_points={
"torchx.schedulers": [
"my_scheduler = my.custom.scheduler:create_schedule",
],
}
注册命名资源¶
命名资源是一组预定义的资源规格,并被赋予一个字符串名称。这在你的集群拥有一组固定的实例类型时特别有用。例如,如果你在 AWS 上的深度学习训练 Kubernetes 集群仅由 p3.16xlarge(64 个虚拟 CPU、8 张 GPU、488GB)组成,那么你可能希望为容器枚举以下 T 恤尺码的资源规格:
from torchx.specs import Resource
def gpu_x1() -> Resource:
return Resource(cpu=8, gpu=1, memMB=61_000)
def gpu_x2() -> Resource:
return Resource(cpu=16, gpu=2, memMB=122_000)
def gpu_x3() -> Resource:
return Resource(cpu=32, gpu=4, memMB=244_000)
def gpu_x4() -> Resource:
return Resource(cpu=64, gpu=8, memMB=488_000)
要使这些资源定义可用,您需要通过 entry_points 进行注册:
# setup.py
...
entry_points={
"torchx.named_resources": [
"gpu_x2 = my_module.resources:gpu_x2",
],
}
一旦您安装了带有入口点定义的软件包,该命名资源即可按如下方式使用:
>>> from torchx.specs import get_named_resources
>>> get_named_resources("gpu_x2")
Resource(cpu=16, gpu=2, memMB=122000, ...)
# my_module.component
from torchx.specs import AppDef, Role, get_named_resources
def test_app(resource: str) -> AppDef:
return AppDef(name="test_app", roles=[
Role(
name="...",
image="...",
resource=get_named_resources(resource),
)
])
test_app("gpu_x2")
注册自定义组件¶
你可以使用
torchx CLI编写并注册自定义组件集,将其作为内置组件添加到CLI中。这使得你可以为团队或组织定制一组最相关的组件,并通过CLI支持它们。
builtin。这样,当用户运行时,他们将看到你的自定义组件
$ torchx builtins
可以通过[torchx.components]个入口注册自定义组件。
如果my_project.bar具有以下目录结构:
$PROJECT_ROOT/my_project/bar/
|- baz.py
并且 baz.py 包含一个名为 trainer 的单个组件(函数):
# baz.py
import torchx.specs as specs
def trainer(...) -> specs.AppDef: ...
入口函数被添加为:
# setup.py
...
entry_points={
"torchx.components": [
"foo = my_project.bar",
],
}
TorchX 将在模块 my_project.bar 中搜索所有已定义的组件,并将找到的组件按 foo.* 前缀分组。在这种情况下,组件 my_project.bar.baz.trainer 将以名称 foo.baz.trainer 注册。
注意
仅搜索包含__init__.py文件的Python包(即那些目录)。
TorchX不会尝试递归进入命名空间包(没有__init__.py文件的目录)。
但是,您可以注册顶级命名空间包。
torchx CLI 将通过以下方式显示已注册的组件:
$ torchx builtins
Found 1 builtin components:
1. foo.baz.trainer
自定义组件可以如下使用:
$ torchx run foo.baz.trainer -- --name "test app"
当您注册自己的组件时,TorchX 将不会包含其自身的内置组件。要添加 TorchX 的内置组件,您必须指定另一个条目为:
# setup.py
...
entry_points={
"torchx.components": [
"foo = my_project.bar",
"torchx = torchx.components",
],
}
这将重新添加TorchX内置组件,但带有torchx.*组件名称前缀(例如torchx.dist.ddp,
相对于默认的dist.ddp)。
如果有两个注册表项指向同一个组件,例如
# setup.py
...
entry_points={
"torchx.components": [
"foo = my_project.bar",
"test = my_project",
],
}
对于在my_project.bar中具有不同前缀别名的那些组件,将会有两组重叠的组件:foo.*和test.bar.*。具体来说,
$ torchx builtins
Found 2 builtin components:
1. foo.baz.trainer
2. test.bar.baz.trainer
为了省略分组并使组件名称更短,请使用下划线(例如 _ 或 _0,_1 等)。
例如:
# setup.py
...
entry_points={
"torchx.components": [
"_0 = my_project.bar",
"_1 = torchx.components",
],
}
这使得训练器组件以baz.trainer的形式暴露(而不是foo.baz.trainer)
并重新添加了内置组件,就像在torchx的纯净安装中一样,没有torchx.*前缀。
$ torchx builtins
Found 11 builtin components:
1. baz.trainer
2. dist.ddp
3. utils.python
4. ... <more builtins from torchx.components.* ...>