File size: 1,255 Bytes
309b968
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
"""The Task interface — bring your own model + data.

A DaisyChain task is any object with three methods:

    build_model() -> torch.nn.Module          # the model to train (identical on every node)
    sample(n)     -> (X, y)                    # draw n training samples (this node's shard)
    loss(model, X, y) -> scalar tensor         # mean loss over the batch

Point DaisyChain at your task with  DAISY_TASK="my_module:MyTask"  (or --task).
An example lives in examples/example_task.py. Keep build_model deterministic
(seed it) so every node starts from the same weights.
"""
from __future__ import annotations

import importlib
from typing import Protocol, Tuple

import torch


class Task(Protocol):
    def build_model(self) -> torch.nn.Module: ...
    def sample(self, n: int) -> Tuple[torch.Tensor, torch.Tensor]: ...
    def loss(self, model: torch.nn.Module, X: torch.Tensor, y: torch.Tensor) -> torch.Tensor: ...


def load_task(spec: str):
    """spec = 'package.module:ClassName' -> instantiated task object."""
    if ":" not in spec:
        raise ValueError(f"task spec must be 'module:Class', got {spec!r}")
    mod_name, cls_name = spec.split(":", 1)
    mod = importlib.import_module(mod_name)
    return getattr(mod, cls_name)()