最佳组件实践¶
这列出了你可能想要使用组件进行的常见事情以及它们的最佳实践。组件被设计为灵活的,因此你可以根据需要偏离这些最佳实践,但这是我们用于内置TorchX组件的最佳实践。
查看 应用最佳实践 以了解如何使用 TorchX 编写应用程序。
入口点¶
在可能的情况下,最好通过 python -m <module> 调用可重用组件,而不是指定主模块的路径。这使得它可以在多个不同的环境中使用,例如 docker 和 slurm,通过依赖 python 模块解析而不是目录结构。
如果你的应用不是基于 Python 的,你可以将你的应用放在一个文件夹中, PATH 以便无论目录结构如何,它都可以被访问。
def trainer(img_name: str, img_version: str) -> AppDef:
return AppDef(roles=[
Role(
entrypoint="python",
args=[
"-m",
"your.app",
],
)
])
简化¶
当你编写一个组件时,你希望每个组件尽可能简单,以便其他人更容易复用和理解。
参数处理¶
处理参数使得在其他环境中使用组件变得困难。特别是对于图像,我们希望直接将图像字段传递给AppDef,因为任何类型的操作都会使它在具有不同图像命名约定的其他环境中无法使用。
def trainer(image: str):
return AppDef(roles=[Role(image=image)...)
分支逻辑¶
你应该避免在组件中使用分支逻辑。如果你觉得需要在组件中使用 if 语句,你应该更喜欢创建多个具有共享逻辑的组件。复杂的参数使得其他人难以理解如何使用它。
def trainer_test():
return _trainer(num_replicas=1)
def trainer_prod() -> AppDef:
return _trainer(num_replicas=10)
# not a component just a function
def _trainer(num_replicas: int) -> AppDef:
return AppDef(roles=[Role(..., num_replicas=num_replicas)])
文档¶
文档是可选的,但最好保持组件功能的文档化,尤其是如果你想分享你的组件。请参阅 :ref:Component Authoring<components/overview:Authoring> 以获取更多详细信息。
命名资源¶
当编写组件时,最好使用TorchX的命名资源支持,而不是手动指定CPU和内存分配。命名资源允许你的组件独立于环境,并通过使用t-shirt大小来实现更好的调度行为。
参见 torchx.specs.get_named_resources() 以获取更多信息。
组合组件¶
对于常见的组件样式,我们提供基础组件定义。这些可以作为您自定义组件定义的调用,并且是创建一个完整的AppDef而不从头开始的一个替代方案。
See:
torchx.components.base用于简单的单节点组件。torchx.components.dist.ddp()用于分布式组件。
对于更复杂的组件,可以将多个现有组件合并成一个。例如,您可以使用指标UI组件,并将其角色从该组件合并到训练组件角色中,从而为您的主要训练任务创建一个侧车服务。
分布式组件¶
如果您正在编写用于分布式训练或其他类似分布式计算的组件,我们建议使用
torchx.components.dist.ddp() 组件,因为它提供了 torch.distributed.elastic 个任务的内置支持。
你可以通过编写一个自定义组件来扩展ddp组件,该组件简单地导入ddp组件并使用你的应用程序配置调用它。
定义所有参数¶
最好将所有组件参数定义为函数参数,而不是使用参数字典。这使得用户更容易了解选项,并且可以在使用pyre或mypy时提供静态类型。
单元测试¶
你可以像测试正常Python代码一样对组件定义进行单元测试,因为它们是有效的Python定义。
我们强烈建议使用 ComponentTestCase 以确保您的组件可以被 TorchX CLI 解析。CLI 需要比纯粹的 Python 更严格的格式化 doc string,因为 doc string 用于解析 CLI 参数。
- class torchx.components.component_test_base.ComponentTestCase(methodName='runTest')[source]¶
- run_component(component: Callable[[...], AppDef], args: Optional[Dict[str, Any]] = None, scheduler_params: Optional[Dict[str, Any]] = None, scheduler: str = 'local_cwd', interval: float = 0.1, timeout: float = 1) Optional[AppStatus][source]¶
隐藏设置跑者和检查结果复杂性的辅助函数。 注意:该方法是阻塞的,直到调度器退出或超时(对于非阻塞调度器)。
- Parameters
组件 – 组件函数,AppDef 的工厂
参数 – 可选组件工厂参数
调度器参数 – 可选的调度器工厂方法参数
调度器 – 调度器名称
间隔 – 调度器完成轮询间隔
超时 – 最大时间,用于调度器完成
集成测试¶
你可以通过使用程序化运行API或编写一个bash脚本来调用CLI来设置与组件的集成测试。
你可以在核心 TorchX 调度器集成测试中看到这两种风格的使用。