Skip to content

base

Type Aliases:

Classes:

Attributes:

logger module-attribute

logger = getLogger(__name__)

Shape

Shape = tuple[int, int]

Backend dataclass

Backend()

Base wrapper for a MLRT VapourSynth backend plugin.

Methods:

  • autoselect

    Try to select the best backend for the current system.

  • get_args

    Return backend plugin arguments derived from this configuration.

  • inference

    Run inference with this backend.

Attributes:

flexible_output_prop class-attribute

flexible_output_prop: str = 'MlrtFlexible'

plugin class-attribute

plugin: Plugin

autoselect staticmethod

autoselect(device_id: int = 0, **kwargs: Any) -> Backend

Try to select the best backend for the current system.

Parameters:

  • device_id

    (int, default: 0 ) –

    The GPU device id.

  • **kwargs

    (Any, default: {} ) –

    Additional arguments to pass to the backend.

Returns:

  • Backend

    The selected backend.

Source code in vsscale/mlrt/backend/base.py
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
@staticmethod
def autoselect(device_id: int = 0, **kwargs: Any) -> Backend:
    """
    Try to select the best backend for the current system.

    Args:
        device_id: The GPU device id.
        **kwargs: Additional arguments to pass to the backend.

    Returns:
        The selected backend.
    """

    gpu = get_gpu(device_id)
    vendor = None if not gpu else str(gpu.vendor).strip()

    match vendor:
        # Windows & Linux
        case "NVIDIA Corporation":
            if hasattr(core, "trt"):
                backend = UserBackend.TRT
            elif hasattr(core, "trt_rtx"):
                backend = UserBackend.TRT_RTX
            elif platform.system().lower() == "windows" and hasattr(core, "ort"):
                backend = UserBackend.ORT_DML
            elif hasattr(core, "ort"):
                backend = UserBackend.ORT_CUDA
            elif hasattr(core, "ncnn"):
                backend = UserBackend.NCNN
            else:
                backend = UserBackend.OV_CPU
        # Windows & Linux
        case "Advanced Micro Devices, Inc.":
            if platform.system().lower() == "windows" and hasattr(core, "ort"):
                backend = UserBackend.ORT_DML
            elif hasattr(core, "migx"):
                backend = UserBackend.MIGX
            elif hasattr(core, "ncnn"):
                backend = UserBackend.NCNN_VK
            else:
                backend = UserBackend.OV_CPU
        # Windows & Linux
        case "Intel(R) Corporation":
            if hasattr(core, "ov"):
                backend = UserBackend.OV_GPU
            elif platform.system().lower() == "windows" and hasattr(core, "ort"):
                backend = UserBackend.ORT_DML
            elif hasattr(core, "ncnn"):
                backend = UserBackend.NCNN_VK
            else:
                backend = UserBackend.OV_CPU
        # macOS ARM64 & x86_64
        case "Apple":
            if hasattr(core, "ncnn"):
                backend = UserBackend.NCNN_VK
            elif hasattr(core, "ort"):
                backend = UserBackend.ORT_COREML
            else:
                backend = UserBackend.OV_CPU
        case _:
            backend = UserBackend.OV_CPU

    del gpu

    if hasattr(backend, "device_id"):
        kwargs["device_id"] = device_id

    return backend(**kwargs)

get_args

get_args(clips: VideoNode | Sequence[VideoNode]) -> dict[str, Any]

Return backend plugin arguments derived from this configuration.

Source code in vsscale/mlrt/backend/base.py
117
118
119
def get_args(self, clips: vs.VideoNode | Sequence[vs.VideoNode]) -> dict[str, Any]:
    """Return backend plugin arguments derived from this configuration."""
    return {}

inference

inference(
    clips: VideoNode | Sequence[VideoNode],
    network_path: str | PathLike[str],
    /,
    overlap: tuple[int, int],
    tilesize: tuple[int, int],
    *,
    flexible: Literal[False] = ...,
    **kwargs: Any,
) -> VideoNode
inference(
    clips: VideoNode | Sequence[VideoNode],
    network_path: str | PathLike[str],
    /,
    overlap: tuple[int, int],
    tilesize: tuple[int, int],
    *,
    flexible: Literal[True],
    **kwargs: Any,
) -> list[VideoNode]
inference(
    clips: VideoNode | Sequence[VideoNode],
    network_path: str | PathLike[str],
    /,
    overlap: tuple[int, int],
    tilesize: tuple[int, int],
    *,
    flexible: bool = ...,
    **kwargs: Any,
) -> VideoNode | list[VideoNode]
inference(
    clips: VideoNode | Sequence[VideoNode],
    network_path: str | PathLike[str],
    /,
    overlap: tuple[int, int],
    tilesize: tuple[int, int],
    *,
    flexible: bool = False,
    **kwargs: Any,
) -> VideoNode | list[VideoNode]

Run inference with this backend.

Parameters:

  • clips

    (VideoNode | Sequence[VideoNode]) –

    Input clip or clips passed to the backend model.

  • network_path

    (str | PathLike[str]) –

    Path to the model file or backend artifact.

  • overlap

    (tuple[int, int]) –

    Horizontal and vertical tile overlap in pixels.

  • tilesize

    (tuple[int, int]) –

    Horizontal and vertical tile size in pixels.

  • flexible

    (bool, default: False ) –

    Return each flexible output plane as a separate clip.

  • **kwargs

    (Any, default: {} ) –

    Additional backend plugin arguments forwarded unchanged.

Returns:

  • VideoNode | list[VideoNode]

    A single output clip, or a list of output clips when flexible is enabled.

Source code in vsscale/mlrt/backend/base.py
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
def inference(
    self,
    clips: vs.VideoNode | Sequence[vs.VideoNode],
    network_path: str | os.PathLike[str],
    /,
    overlap: tuple[int, int],
    tilesize: tuple[int, int],
    *,
    flexible: bool = False,
    **kwargs: Any,
) -> vs.VideoNode | list[vs.VideoNode]:
    """
    Run inference with this backend.

    Args:
        clips: Input clip or clips passed to the backend model.
        network_path: Path to the model file or backend artifact.
        overlap: Horizontal and vertical tile overlap in pixels.
        tilesize: Horizontal and vertical tile size in pixels.
        flexible: Return each flexible output plane as a separate clip.
        **kwargs: Additional backend plugin arguments forwarded unchanged.

    Returns:
        A single output clip, or a list of output clips when `flexible` is enabled.
    """
    UnsupportedSampleTypeError.check(clips, vs.FLOAT, self.__class__)

    args = self.get_args(clips)

    if flexible:
        args = args.copy()
        args["flexible_output_prop"] = self.flexible_output_prop

    logger.info("Calling %s.Model", self.plugin.namespace)
    logger.info("Clips: %r", clips)
    logger.info("Network Path: %s", network_path)
    logger.info("overlap=%s, tilesize=%s, %s", overlap, tilesize, args | kwargs)
    output = self.plugin.Model(clips, network_path, overlap, tilesize, **args | kwargs)

    if flexible:
        clip = output["clip"]
        num_planes = output["num_planes"]

        output = [clip.std.PropToClip(prop=f"{self.flexible_output_prop}{i}") for i in range(num_planes)]

    return output

BackendAutoConvertFloat dataclass

BackendAutoConvertFloat()

Bases: Backend

Methods:

  • autoselect

    Try to select the best backend for the current system.

  • get_args

    Return backend plugin arguments derived from this configuration.

  • inference

    Run inference with this backend.

Attributes:

flexible_output_prop class-attribute

flexible_output_prop: str = 'MlrtFlexible'

plugin class-attribute

plugin: Plugin

autoselect staticmethod

autoselect(device_id: int = 0, **kwargs: Any) -> Backend

Try to select the best backend for the current system.

Parameters:

  • device_id

    (int, default: 0 ) –

    The GPU device id.

  • **kwargs

    (Any, default: {} ) –

    Additional arguments to pass to the backend.

Returns:

  • Backend

    The selected backend.

Source code in vsscale/mlrt/backend/base.py
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
@staticmethod
def autoselect(device_id: int = 0, **kwargs: Any) -> Backend:
    """
    Try to select the best backend for the current system.

    Args:
        device_id: The GPU device id.
        **kwargs: Additional arguments to pass to the backend.

    Returns:
        The selected backend.
    """

    gpu = get_gpu(device_id)
    vendor = None if not gpu else str(gpu.vendor).strip()

    match vendor:
        # Windows & Linux
        case "NVIDIA Corporation":
            if hasattr(core, "trt"):
                backend = UserBackend.TRT
            elif hasattr(core, "trt_rtx"):
                backend = UserBackend.TRT_RTX
            elif platform.system().lower() == "windows" and hasattr(core, "ort"):
                backend = UserBackend.ORT_DML
            elif hasattr(core, "ort"):
                backend = UserBackend.ORT_CUDA
            elif hasattr(core, "ncnn"):
                backend = UserBackend.NCNN
            else:
                backend = UserBackend.OV_CPU
        # Windows & Linux
        case "Advanced Micro Devices, Inc.":
            if platform.system().lower() == "windows" and hasattr(core, "ort"):
                backend = UserBackend.ORT_DML
            elif hasattr(core, "migx"):
                backend = UserBackend.MIGX
            elif hasattr(core, "ncnn"):
                backend = UserBackend.NCNN_VK
            else:
                backend = UserBackend.OV_CPU
        # Windows & Linux
        case "Intel(R) Corporation":
            if hasattr(core, "ov"):
                backend = UserBackend.OV_GPU
            elif platform.system().lower() == "windows" and hasattr(core, "ort"):
                backend = UserBackend.ORT_DML
            elif hasattr(core, "ncnn"):
                backend = UserBackend.NCNN_VK
            else:
                backend = UserBackend.OV_CPU
        # macOS ARM64 & x86_64
        case "Apple":
            if hasattr(core, "ncnn"):
                backend = UserBackend.NCNN_VK
            elif hasattr(core, "ort"):
                backend = UserBackend.ORT_COREML
            else:
                backend = UserBackend.OV_CPU
        case _:
            backend = UserBackend.OV_CPU

    del gpu

    if hasattr(backend, "device_id"):
        kwargs["device_id"] = device_id

    return backend(**kwargs)

get_args

get_args(clips: VideoNode | Sequence[VideoNode]) -> dict[str, Any]

Return backend plugin arguments derived from this configuration.

Source code in vsscale/mlrt/backend/base.py
192
193
def get_args(self, clips: vs.VideoNode | Sequence[vs.VideoNode]) -> dict[str, Any]:
    return {"output_format": max(c.format.bits_per_sample for c in to_arr(clips)) == 16}

inference

inference(
    clips: VideoNode | Sequence[VideoNode],
    network_path: str | PathLike[str],
    /,
    overlap: tuple[int, int],
    tilesize: tuple[int, int],
    *,
    flexible: Literal[False] = ...,
    **kwargs: Any,
) -> VideoNode
inference(
    clips: VideoNode | Sequence[VideoNode],
    network_path: str | PathLike[str],
    /,
    overlap: tuple[int, int],
    tilesize: tuple[int, int],
    *,
    flexible: Literal[True],
    **kwargs: Any,
) -> list[VideoNode]
inference(
    clips: VideoNode | Sequence[VideoNode],
    network_path: str | PathLike[str],
    /,
    overlap: tuple[int, int],
    tilesize: tuple[int, int],
    *,
    flexible: bool = ...,
    **kwargs: Any,
) -> VideoNode | list[VideoNode]
inference(
    clips: VideoNode | Sequence[VideoNode],
    network_path: str | PathLike[str],
    /,
    overlap: tuple[int, int],
    tilesize: tuple[int, int],
    *,
    flexible: bool = False,
    **kwargs: Any,
) -> VideoNode | list[VideoNode]

Run inference with this backend.

Parameters:

  • clips

    (VideoNode | Sequence[VideoNode]) –

    Input clip or clips passed to the backend model.

  • network_path

    (str | PathLike[str]) –

    Path to the model file or backend artifact.

  • overlap

    (tuple[int, int]) –

    Horizontal and vertical tile overlap in pixels.

  • tilesize

    (tuple[int, int]) –

    Horizontal and vertical tile size in pixels.

  • flexible

    (bool, default: False ) –

    Return each flexible output plane as a separate clip.

  • **kwargs

    (Any, default: {} ) –

    Additional backend plugin arguments forwarded unchanged.

Returns:

  • VideoNode | list[VideoNode]

    A single output clip, or a list of output clips when flexible is enabled.

Source code in vsscale/mlrt/backend/base.py
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
def inference(
    self,
    clips: vs.VideoNode | Sequence[vs.VideoNode],
    network_path: str | os.PathLike[str],
    /,
    overlap: tuple[int, int],
    tilesize: tuple[int, int],
    *,
    flexible: bool = False,
    **kwargs: Any,
) -> vs.VideoNode | list[vs.VideoNode]:
    """
    Run inference with this backend.

    Args:
        clips: Input clip or clips passed to the backend model.
        network_path: Path to the model file or backend artifact.
        overlap: Horizontal and vertical tile overlap in pixels.
        tilesize: Horizontal and vertical tile size in pixels.
        flexible: Return each flexible output plane as a separate clip.
        **kwargs: Additional backend plugin arguments forwarded unchanged.

    Returns:
        A single output clip, or a list of output clips when `flexible` is enabled.
    """
    UnsupportedSampleTypeError.check(clips, vs.FLOAT, self.__class__)

    args = self.get_args(clips)

    if flexible:
        args = args.copy()
        args["flexible_output_prop"] = self.flexible_output_prop

    logger.info("Calling %s.Model", self.plugin.namespace)
    logger.info("Clips: %r", clips)
    logger.info("Network Path: %s", network_path)
    logger.info("overlap=%s, tilesize=%s, %s", overlap, tilesize, args | kwargs)
    output = self.plugin.Model(clips, network_path, overlap, tilesize, **args | kwargs)

    if flexible:
        clip = output["clip"]
        num_planes = output["num_planes"]

        output = [clip.std.PropToClip(prop=f"{self.flexible_output_prop}{i}") for i in range(num_planes)]

    return output

UserBackend dataclass

UserBackend()

Bases: ABC

Backend namespace for user interaction.

Attributes:

MIGX class-attribute instance-attribute

MIGX = migx.MIGX

NCNN class-attribute instance-attribute

NCNN = ncnn.NCNN

NCNN_VK class-attribute instance-attribute

NCNN_VK = ncnn.NCNN

ORT class-attribute instance-attribute

ORT = ort.ORT

ORT_COREML class-attribute instance-attribute

ORT_COREML = ort.ORT_COREML

ORT_CPU class-attribute instance-attribute

ORT_CPU = ort.ORT_CPU

ORT_CUDA class-attribute instance-attribute

ORT_CUDA = ort.ORT_CUDA

ORT_DML class-attribute instance-attribute

ORT_DML = ort.ORT_DML

OV class-attribute instance-attribute

OV = ov.OV

OV_CPU class-attribute instance-attribute

OV_CPU = ov.OV_CPU

OV_GPU class-attribute instance-attribute

OV_GPU = ov.OV_GPU

OV_NPU class-attribute instance-attribute

OV_NPU = ov.OV_NPU

TRT class-attribute instance-attribute

TRT = trt.TRT

TRT_RTX class-attribute instance-attribute

TRT_RTX = trt.TRT_RTX

autoselect class-attribute instance-attribute

autoselect = Backend.autoselect