跳转至

配置文件

Geyser 依靠遵循Geyser JSON Schema的配置文件来编排执行各类任务。

基本概念

以下仅简要介绍对应概念,详细概念请点击标题。

Task

Task是任务流模型的基本单元,定义了基本的任务行为。你可以继承Task来定义你的任务,并通过Geyser.task来注册你的任务。

如果只需要通过某个函数定义任务行为, Geyser 会通过FunctorTask来将你的函数封装为Task

Flow

Flow是任务流模型的编排规则,定义了任务的执行流程。

目前支持以下类型的Flow

类型 行为
linear 所有任务线性执行。
unordered 所有任务乱序执行。
graph 所有任务按 DAG 编排执行。
targeted_graph 所有任务按 DAG 编排执行,但不被目标任务依赖的任务不被执行。

Warning

targeted_graph类型尚未完全支持,可能存在问题,会在后续版本完善。

Engine

Flow定义了任务的编排流程,而实际Engine依照Flow的规则驱动任务执行。

目前支持一下类型的Engine

类型 行为
serial 所有任务在一个线程中执行。
parallel 所有任务在不同线程(或进程)并行执行,具体执行方式见Executor
worker-basedworkers 所有任务在不同机器分布式执行,具体执行方式见Workers

Warning

worker-basedworkers类型尚未完全支持,可能存在问题,可能会在后续版本完善。

当“engine”字段为parallel时,需要额外定义“executor”的类型,支持的启动器类型如下:

类型 行为
processprocesses 所有任务在不同进程中执行。
threadthreadedthreads 所有任务在不同线程中执行。
greenthreadgreedthreadedgreenthreads 所有任务在不同协程(或绿色线程)中执行。

Warning

由于 CPython 的 GIL (全局解释器锁)限制,使用除线程启动器(即选择processprocesses)以外的启动器启动任务,可能由于解释器本身的原因并行执行难以生效。

编写配置文件

使用 Geyser 编辑

您可以使用 Geyser 调用编辑器来编写配置文件,例如:

geyser -e [配置文件路径]

Geyser 会按以下优先级选择编辑器:

  • 环境变量中定义EDITOR变量时, Geyser 优先执行EDITOR定义的编辑器。
  • 当用户在~/.geyser/EDITOR文件中定义编辑器时,会在环境变量EDITOR不存在的情况下执行该文件定义的编辑器。
  • Geyser 默认会使用 vim 作为编辑器

“tasks”字段

“tasks”字段定义了所有任务的列表,对于每个任务需要的配置项如下:

名称 内容 必填
reference 任务路径 ✅
name 任务名称 ✅
type 任务类型 ✅
inject 输入任务参数 ❎
rebind 输入参数名称映射 ❎
rename 输出参数名称映射 ❎
revert_rebind 回滚时输入参数名称映射 ❎

任务真实路径,可以通过reference函数从类或函数获得。

任务名称,注意不能与其他任务重名,在“flow”字段中按照该名称调用任务。

任务类型,取决于注册时使用的装饰器。

如果使用Geyser.functor,依照对参数的处理方式,可以使用functormapper或者reducer

如果使用Geyser.task,使用task

输入参数,直接注入到该任务参数注入的作用域中,但不会存在于后续任务的作用域中,不在provides中声明的参数依旧不会被传入任务中。

重新绑定输入参数,按照目标名称原始名称的方式进行映射。

重新命名输出参数,按照原始名称目标名称的方式进行映射。

rebind行为类似,但定义的是显式定义revert函数即任务回滚时需要的输入参数。

“flow”字段

“flow”字段定义的是任务流的逻辑结构,对于任务流需要的配置项如下:

名称 内容 必填
name 任务流名称 ✅
type 任务流类型 ✅
include 任务流包含列表 ✅

任务流名称,建议不与其他任务流重名,同时将根任务流命名为“root”。

任务流类型,可以使用的任务流类型参见Flow

任务流包含列表,列表元素为字符串时将对应名称任务加入该任务流。当列表元素为与“flow”字段相同结构的对象时,会构建子任务流加入该任务流。

“engine”字段

“engine”字段定义执行任务流过程中使用的引擎类型,对应Engine中对应的类型。

“inject”字段

“inject”字段(可选)定义整个任务流执行过程中初始的输入参数,直接注入到全局作用域中。

“backend”字段

“backend”字段(可选)定义任务引擎存储参数使用的后端,支持的后端有memorydirfilemysqlpostgressqlite以及zookeeper,默认为memory

Warning

目前只支持memory后端进行存储,其他后端尚未经过测试。

“executor”字段

如果“engine”字段为parallel,“executor”字段定义执行任务的基本单元,详见Engine

完整示例

以下是torch/train_resnet_cifar10.[format]配置文件的完整示例。

JSON

{
  "$schema": "https://geyser.waterch.cn/zh_CN/latest/schema.json",
  "tasks": [
    {
      "reference": "geyser_lava.task.utility.IdProvider",
      "name": "id",
      "type": "task",
      "inject": {
        "title": "cifar10_resnet50"
      }
    },
    {
      "reference": "geyser_lava.task.utility.PathProvider",
      "name": "path",
      "type": "task",
      "rename": {
        "path_provider": "path"
      }
    },
    {
      "reference": "geyser_lava.task.utility.PathBuilder",
      "name": "dataset_root",
      "type": "functor",
      "inject": {
        "typename": "current",
        "subpaths": [
          "dataset",
          "cifar10"
        ]
      },
      "rename": {
        "path": "dataset_root"
      }
    },
    {
      "reference": "geyser_lava.profile._support.operator.ToTensor",
      "name": "vision_transform",
      "type": "functor"
    },
    {
      "reference": "geyser_lava.profile._support.operator.CifarUnflatten",
      "name": "train_dataset_params",
      "type": "functor",
      "inject": {
        "reference": "torchvision.datasets.cifar.CIFAR10",
        "train": true,
        "download": true
      },
      "rebind": {
        "root": "dataset_root"
      },
      "rename": {
        "obj": "train_dataset_params"
      }
    },
    {
      "reference": "geyser_lava.profile._support.operator.CifarUnflatten",
      "name": "validate_dataset_params",
      "type": "functor",
      "inject": {
        "reference": "torchvision.datasets.cifar.CIFAR10",
        "train": false,
        "download": true
      },
      "rebind": {
        "root": "dataset_root"
      },
      "rename": {
        "obj": "validate_dataset_params"
      }
    },
    {
      "reference": "geyser_lava.task.torch.common.DataLoaderProvider",
      "name": "train_loader",
      "type": "task",
      "rebind": {
        "dataset_params": "train_dataset_params"
      },
      "inject": {
        "loader_params": {
          "batch_size": 32,
          "shuffle": true
        }
      },
      "rename": {
        "loader": "train_loader"
      }
    },
    {
      "reference": "geyser_lava.task.torch.common.DataLoaderProvider",
      "name": "validate_loader",
      "type": "task",
      "rebind": {
        "dataset_params": "validate_dataset_params"
      },
      "inject": {
        "loader_params": {
          "batch_size": 32,
          "shuffle": true
        }
      },
      "rename": {
        "loader": "validate_loader"
      }
    },
    {
      "reference": "geyser_lava.task.torch.common.ModelProvider",
      "name": "model",
      "type": "task",
      "inject": {
        "model_params": {
          "reference": "torchvision.models.resnet.resnet50",
          "pretrained": false,
          "progress": false,
          "num_classes": 10
        }
      }
    },
    {
      "reference": "geyser_lava.task.torch.common.OptimizerProvider",
      "name": "optimizer",
      "type": "task",
      "inject": {
        "optimizer_params": {
          "reference": "torch.optim.adamw.AdamW"
        }
      }
    },
    {
      "reference": "geyser_lava.task.torch.common.LossProvider",
      "name": "loss",
      "type": "task",
      "inject": {
        "loss_params": {
          "reference": "torch.nn.modules.loss.CrossEntropyLoss"
        }
      }
    },
    {
      "reference": "geyser_lava.task.torch.trainer.SupervisedTrainer",
      "name": "trainer",
      "type": "task",
      "inject": {
        "max_epochs": 100,
        "device": "cuda:0",
        "metrics_params": [
          {
            "reference": "ignite.metrics.accuracy.Accuracy",
            "name": "accuracy",
            "params": {
              "device": "cuda:0"
            }
          },
          {
            "reference": "ignite.metrics.fbeta.Fbeta",
            "name": "f1macro",
            "params": {
              "beta": 1
            }
          }
        ],
        "non_blocking": true
      }
    }
  ],
  "flow": {
    "name": "root",
    "type": "graph",
    "include": [
      "id",
      "path",
      "dataset_root",
      "vision_transform",
      "train_dataset_params",
      "validate_dataset_params",
      "train_loader",
      "validate_loader",
      "model",
      "optimizer",
      "loss",
      "trainer"
    ]
  },
  "engine": "serial"
}

YAML

$schema: https://geyser.waterch.cn/zh_CN/latest/schema.json
tasks:
  - reference: geyser_lava.task.utility.IdProvider
    name: id
    type: task
    inject:
      title: cifar10_resnet50
  - reference: geyser_lava.task.utility.PathProvider
    name: path
    type: task
    rename:
      path_provider: path
  - reference: geyser_lava.task.utility.PathBuilder
    name: dataset_root
    type: functor
    inject:
      typename: current
      subpaths:
        - dataset
        - cifar10
    rename:
      path: dataset_root
  - reference: geyser_lava.profile._support.operator.ToTensor
    name: vision_transform
    type: functor
  - reference: geyser_lava.profile._support.operator.CifarUnflatten
    name: train_dataset_params
    type: functor
    inject:
      reference: torchvision.datasets.cifar.CIFAR10
      train: true
      download: true
    rebind:
      root: dataset_root
    rename:
      obj: train_dataset_params
  - reference: geyser_lava.profile._support.operator.CifarUnflatten
    name: validate_dataset_params
    type: functor
    inject:
      reference: torchvision.datasets.cifar.CIFAR10
      train: false
      download: true
    rebind:
      root: dataset_root
    rename:
      obj: validate_dataset_params
  - reference: geyser_lava.task.torch.common.DataLoaderProvider
    name: train_loader
    type: task
    rebind:
      dataset_params: train_dataset_params
    inject:
      loader_params:
        batch_size: 32
        shuffle: true
    rename:
      loader: train_loader
  - reference: geyser_lava.task.torch.common.DataLoaderProvider
    name: validate_loader
    type: task
    rebind:
      dataset_params: validate_dataset_params
    inject:
      loader_params:
        batch_size: 32
        shuffle: true
    rename:
      loader: validate_loader
  - reference: geyser_lava.task.torch.common.ModelProvider
    name: model
    type: task
    inject:
      model_params:
        reference: torchvision.models.resnet.resnet50
        pretrained: false
        progress: false
        num_classes: 10
  - reference: geyser_lava.task.torch.common.OptimizerProvider
    name: optimizer
    type: task
    inject:
      optimizer_params:
        reference: torch.optim.adamw.AdamW
  - reference: geyser_lava.task.torch.common.LossProvider
    name: loss
    type: task
    inject:
      loss_params:
        reference: torch.nn.modules.loss.CrossEntropyLoss
  - reference: geyser_lava.task.torch.trainer.SupervisedTrainer
    name: trainer
    type: task
    inject:
      max_epochs: 100
      device: cuda:0
      metrics_params:
        - reference: ignite.metrics.accuracy.Accuracy
          name: accuracy
          params:
            device: cuda:0
        - reference: ignite.metrics.fbeta.Fbeta
          name: f1macro
          params:
            beta: 1
      non_blocking: true
flow:
  name: root
  type: graph
  include:
    - id
    - path
    - dataset_root
    - vision_transform
    - train_dataset_params
    - validate_dataset_params
    - train_loader
    - validate_loader
    - model
    - optimizer
    - loss
    - trainer
engine: serial

TOML

"$schema" = "https://geyser.waterch.cn/zh_CN/latest/schema.json"
engine = "serial"

[[tasks]]
reference = "geyser_lava.task.utility.IdProvider"
name = "id"
type = "task"
[tasks.inject]
title = "cifar10_resnet50"

[[tasks]]
reference = "geyser_lava.task.utility.PathProvider"
name = "path"
type = "task"
[tasks.rename]
path_provider = "path"

[[tasks]]
reference = "geyser_lava.task.utility.PathBuilder"
name = "dataset_root"
type = "functor"
[tasks.inject]
typename = "current"
subpaths = [ "dataset", "cifar10",]
[tasks.rename]
path = "dataset_root"

[[tasks]]
reference = "geyser_lava.profile._support.operator.ToTensor"
name = "vision_transform"
type = "functor"

[[tasks]]
reference = "geyser_lava.profile._support.operator.CifarUnflatten"
name = "train_dataset_params"
type = "functor"
[tasks.inject]
reference = "torchvision.datasets.cifar.CIFAR10"
train = true
download = true
[tasks.rebind]
root = "dataset_root"
[tasks.rename]
obj = "train_dataset_params"

[[tasks]]
reference = "geyser_lava.profile._support.operator.CifarUnflatten"
name = "validate_dataset_params"
type = "functor"
[tasks.inject]
reference = "torchvision.datasets.cifar.CIFAR10"
train = false
download = true
[tasks.rebind]
root = "dataset_root"
[tasks.rename]
obj = "validate_dataset_params"

[[tasks]]
reference = "geyser_lava.task.torch.common.DataLoaderProvider"
name = "train_loader"
type = "task"
[tasks.rebind]
dataset_params = "train_dataset_params"
[tasks.rename]
loader = "train_loader"
[tasks.inject.loader_params]
batch_size = 32
shuffle = true

[[tasks]]
reference = "geyser_lava.task.torch.common.DataLoaderProvider"
name = "validate_loader"
type = "task"
[tasks.rebind]
dataset_params = "validate_dataset_params"
[tasks.rename]
loader = "validate_loader"
[tasks.inject.loader_params]
batch_size = 32
shuffle = true

[[tasks]]
reference = "geyser_lava.task.torch.common.ModelProvider"
name = "model"
type = "task"
[tasks.inject.model_params]
reference = "torchvision.models.resnet.resnet50"
pretrained = false
progress = false
num_classes = 10

[[tasks]]
reference = "geyser_lava.task.torch.common.OptimizerProvider"
name = "optimizer"
type = "task"
[tasks.inject.optimizer_params]
reference = "torch.optim.adamw.AdamW"

[[tasks]]
reference = "geyser_lava.task.torch.common.LossProvider"
name = "loss"
type = "task"
[tasks.inject.loss_params]
reference = "torch.nn.modules.loss.CrossEntropyLoss"

[[tasks]]
reference = "geyser_lava.task.torch.trainer.SupervisedTrainer"
name = "trainer"
type = "task"
[tasks.inject]
max_epochs = 100
device = "cuda:0"
non_blocking = true
[[tasks.inject.metrics_params]]
reference = "ignite.metrics.accuracy.Accuracy"
name = "accuracy"
[tasks.inject.metrics_params.params]
device = "cuda:0"
[[tasks.inject.metrics_params]]
reference = "ignite.metrics.fbeta.Fbeta"
name = "f1macro"
[tasks.inject.metrics_params.params]
beta = 1

[flow]
name = "root"
type = "graph"
include = [ "id", "path", "dataset_root", "vision_transform", "train_dataset_params", "validate_dataset_params", "train_loader", "validate_loader", "model", "optimizer", "loss", "trainer",]

HOCON

"$schema" = "https://geyser.waterch.cn/zh_CN/latest/schema.json"
tasks = [
  {
    reference = "geyser_lava.task.utility.IdProvider"
    name = "id"
    type = "task"
    inject {
      title = "cifar10_resnet50"
    }
  }
  {
    reference = "geyser_lava.task.utility.PathProvider"
    name = "path"
    type = "task"
    rename {
      path_provider = "path"
    }
  }
  {
    reference = "geyser_lava.task.utility.PathBuilder"
    name = "dataset_root"
    type = "functor"
    inject {
      typename = "current"
      subpaths = [
        "dataset"
        "cifar10"
      ]
    }
    rename {
      path = "dataset_root"
    }
  }
  {
    reference = "geyser_lava.profile._support.operator.ToTensor"
    name = "vision_transform"
    type = "functor"
  }
  {
    reference = "geyser_lava.profile._support.operator.CifarUnflatten"
    name = "train_dataset_params"
    type = "functor"
    inject {
      reference = "torchvision.datasets.cifar.CIFAR10"
      train = true
      download = true
    }
    rebind {
      root = "dataset_root"
    }
    rename {
      obj = "train_dataset_params"
    }
  }
  {
    reference = "geyser_lava.profile._support.operator.CifarUnflatten"
    name = "validate_dataset_params"
    type = "functor"
    inject {
      reference = "torchvision.datasets.cifar.CIFAR10"
      train = false
      download = true
    }
    rebind {
      root = "dataset_root"
    }
    rename {
      obj = "validate_dataset_params"
    }
  }
  {
    reference = "geyser_lava.task.torch.common.DataLoaderProvider"
    name = "train_loader"
    type = "task"
    rebind {
      dataset_params = "train_dataset_params"
    }
    inject {
      loader_params {
        batch_size = 32
        shuffle = true
      }
    }
    rename {
      loader = "train_loader"
    }
  }
  {
    reference = "geyser_lava.task.torch.common.DataLoaderProvider"
    name = "validate_loader"
    type = "task"
    rebind {
      dataset_params = "validate_dataset_params"
    }
    inject {
      loader_params {
        batch_size = 32
        shuffle = true
      }
    }
    rename {
      loader = "validate_loader"
    }
  }
  {
    reference = "geyser_lava.task.torch.common.ModelProvider"
    name = "model"
    type = "task"
    inject {
      model_params {
        reference = "torchvision.models.resnet.resnet50"
        pretrained = false
        progress = false
        num_classes = 10
      }
    }
  }
  {
    reference = "geyser_lava.task.torch.common.OptimizerProvider"
    name = "optimizer"
    type = "task"
    inject {
      optimizer_params {
        reference = "torch.optim.adamw.AdamW"
      }
    }
  }
  {
    reference = "geyser_lava.task.torch.common.LossProvider"
    name = "loss"
    type = "task"
    inject {
      loss_params {
        reference = "torch.nn.modules.loss.CrossEntropyLoss"
      }
    }
  }
  {
    reference = "geyser_lava.task.torch.trainer.SupervisedTrainer"
    name = "trainer"
    type = "task"
    inject {
      max_epochs = 100
      device = "cuda:0"
      metrics_params = [
        {
          reference = "ignite.metrics.accuracy.Accuracy"
          name = "accuracy"
          params {
            device = "cuda:0"
          }
        }
        {
          reference = "ignite.metrics.fbeta.Fbeta"
          name = "f1macro"
          params {
            beta = 1
          }
        }
      ]
      non_blocking = true
    }
  }
]
flow {
  name = "root"
  type = "graph"
  include = [
    "id"
    "path"
    "dataset_root"
    "vision_transform"
    "train_dataset_params"
    "validate_dataset_params"
    "train_loader"
    "validate_loader"
    "model"
    "optimizer"
    "loss"
    "trainer"
  ]
}
engine = "serial"

Apple pList

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>$schema</key>
    <string>https://geyser.waterch.cn/zh_CN/latest/schema.json</string>
    <key>engine</key>
    <string>serial</string>
    <key>flow</key>
    <dict>
        <key>include</key>
        <array>
            <string>id</string>
            <string>path</string>
            <string>dataset_root</string>
            <string>vision_transform</string>
            <string>train_dataset_params</string>
            <string>validate_dataset_params</string>
            <string>train_loader</string>
            <string>validate_loader</string>
            <string>model</string>
            <string>optimizer</string>
            <string>loss</string>
            <string>trainer</string>
        </array>
        <key>name</key>
        <string>root</string>
        <key>type</key>
        <string>graph</string>
    </dict>
    <key>tasks</key>
    <array>
        <dict>
            <key>inject</key>
            <dict>
                <key>title</key>
                <string>cifar10_resnet50</string>
            </dict>
            <key>name</key>
            <string>id</string>
            <key>reference</key>
            <string>geyser_lava.task.utility.IdProvider</string>
            <key>type</key>
            <string>task</string>
        </dict>
        <dict>
            <key>name</key>
            <string>path</string>
            <key>reference</key>
            <string>geyser_lava.task.utility.PathProvider</string>
            <key>rename</key>
            <dict>
                <key>path_provider</key>
                <string>path</string>
            </dict>
            <key>type</key>
            <string>task</string>
        </dict>
        <dict>
            <key>inject</key>
            <dict>
                <key>subpaths</key>
                <array>
                    <string>dataset</string>
                    <string>cifar10</string>
                </array>
                <key>typename</key>
                <string>current</string>
            </dict>
            <key>name</key>
            <string>dataset_root</string>
            <key>reference</key>
            <string>geyser_lava.task.utility.PathBuilder</string>
            <key>rename</key>
            <dict>
                <key>path</key>
                <string>dataset_root</string>
            </dict>
            <key>type</key>
            <string>functor</string>
        </dict>
        <dict>
            <key>name</key>
            <string>vision_transform</string>
            <key>reference</key>
            <string>geyser_lava.profile._support.operator.ToTensor</string>
            <key>type</key>
            <string>functor</string>
        </dict>
        <dict>
            <key>inject</key>
            <dict>
                <key>download</key>
                <true/>
                <key>reference</key>
                <string>torchvision.datasets.cifar.CIFAR10</string>
                <key>train</key>
                <true/>
            </dict>
            <key>name</key>
            <string>train_dataset_params</string>
            <key>rebind</key>
            <dict>
                <key>root</key>
                <string>dataset_root</string>
            </dict>
            <key>reference</key>
            <string>geyser_lava.profile._support.operator.CifarUnflatten</string>
            <key>rename</key>
            <dict>
                <key>obj</key>
                <string>train_dataset_params</string>
            </dict>
            <key>type</key>
            <string>functor</string>
        </dict>
        <dict>
            <key>inject</key>
            <dict>
                <key>download</key>
                <true/>
                <key>reference</key>
                <string>torchvision.datasets.cifar.CIFAR10</string>
                <key>train</key>
                <false/>
            </dict>
            <key>name</key>
            <string>validate_dataset_params</string>
            <key>rebind</key>
            <dict>
                <key>root</key>
                <string>dataset_root</string>
            </dict>
            <key>reference</key>
            <string>geyser_lava.profile._support.operator.CifarUnflatten</string>
            <key>rename</key>
            <dict>
                <key>obj</key>
                <string>validate_dataset_params</string>
            </dict>
            <key>type</key>
            <string>functor</string>
        </dict>
        <dict>
            <key>inject</key>
            <dict>
                <key>loader_params</key>
                <dict>
                    <key>batch_size</key>
                    <integer>32</integer>
                    <key>shuffle</key>
                    <true/>
                </dict>
            </dict>
            <key>name</key>
            <string>train_loader</string>
            <key>rebind</key>
            <dict>
                <key>dataset_params</key>
                <string>train_dataset_params</string>
            </dict>
            <key>reference</key>
            <string>geyser_lava.task.torch.common.DataLoaderProvider</string>
            <key>rename</key>
            <dict>
                <key>loader</key>
                <string>train_loader</string>
            </dict>
            <key>type</key>
            <string>task</string>
        </dict>
        <dict>
            <key>inject</key>
            <dict>
                <key>loader_params</key>
                <dict>
                    <key>batch_size</key>
                    <integer>32</integer>
                    <key>shuffle</key>
                    <true/>
                </dict>
            </dict>
            <key>name</key>
            <string>validate_loader</string>
            <key>rebind</key>
            <dict>
                <key>dataset_params</key>
                <string>validate_dataset_params</string>
            </dict>
            <key>reference</key>
            <string>geyser_lava.task.torch.common.DataLoaderProvider</string>
            <key>rename</key>
            <dict>
                <key>loader</key>
                <string>validate_loader</string>
            </dict>
            <key>type</key>
            <string>task</string>
        </dict>
        <dict>
            <key>inject</key>
            <dict>
                <key>model_params</key>
                <dict>
                    <key>num_classes</key>
                    <integer>10</integer>
                    <key>pretrained</key>
                    <false/>
                    <key>progress</key>
                    <false/>
                    <key>reference</key>
                    <string>torchvision.models.resnet.resnet50</string>
                </dict>
            </dict>
            <key>name</key>
            <string>model</string>
            <key>reference</key>
            <string>geyser_lava.task.torch.common.ModelProvider</string>
            <key>type</key>
            <string>task</string>
        </dict>
        <dict>
            <key>inject</key>
            <dict>
                <key>optimizer_params</key>
                <dict>
                    <key>reference</key>
                    <string>torch.optim.adamw.AdamW</string>
                </dict>
            </dict>
            <key>name</key>
            <string>optimizer</string>
            <key>reference</key>
            <string>geyser_lava.task.torch.common.OptimizerProvider</string>
            <key>type</key>
            <string>task</string>
        </dict>
        <dict>
            <key>inject</key>
            <dict>
                <key>loss_params</key>
                <dict>
                    <key>reference</key>
                    <string>torch.nn.modules.loss.CrossEntropyLoss</string>
                </dict>
            </dict>
            <key>name</key>
            <string>loss</string>
            <key>reference</key>
            <string>geyser_lava.task.torch.common.LossProvider</string>
            <key>type</key>
            <string>task</string>
        </dict>
        <dict>
            <key>inject</key>
            <dict>
                <key>device</key>
                <string>cuda:0</string>
                <key>max_epochs</key>
                <integer>100</integer>
                <key>metrics_params</key>
                <array>
                    <dict>
                        <key>name</key>
                        <string>accuracy</string>
                        <key>params</key>
                        <dict>
                            <key>device</key>
                            <string>cuda:0</string>
                        </dict>
                        <key>reference</key>
                        <string>ignite.metrics.accuracy.Accuracy</string>
                    </dict>
                    <dict>
                        <key>name</key>
                        <string>f1macro</string>
                        <key>params</key>
                        <dict>
                            <key>beta</key>
                            <integer>1</integer>
                        </dict>
                        <key>reference</key>
                        <string>ignite.metrics.fbeta.Fbeta</string>
                    </dict>
                </array>
                <key>non_blocking</key>
                <true/>
            </dict>
            <key>name</key>
            <string>trainer</string>
            <key>reference</key>
            <string>geyser_lava.task.torch.trainer.SupervisedTrainer</string>
            <key>type</key>
            <string>task</string>
        </dict>
    </array>
</dict>
</plist>