def METHOD_NAME(
    model: Union[lbann.Model, List[lbann.Layer]],
    inputs: npt.NDArray,
    outputs: Optional[List[str]] = None,
    extra_callbacks: Optional[List[lbann.Callback]] = None,
    training: bool = False,
    **kwargs,
) -> Union[npt.NDArray, Tuple[npt.NDArray]]:
    """
    Runs a given LBANN model once on the given inputs and returns its forward
    propagation outputs. All tensors are numpy arrays.
    :param model: The LBANN model or layer graph to evaluate.
    :param inputs: A tensor with the inputs to the model. It will be mapped
                   to the ``lbann.Input`` with the ``samples`` data field.
    :param outputs: An optional list of layer names to output as the return
                    value. If not given, returns all layers without children.
    :param extra_callbacks: If given, uses additional callbacks in the evaluated
                            model.
    :param training: If True, evaluates in training mode. Otherwise, evaluates
                     in testing mode.
    :param kwargs: Additional keyword arguments to pass onto ``lbann.run``
    :return: Output tensor or tensors of the LBANN model.
    """
    ########################
    # Canonicalize arguments
    # Set model to always be an lbann.Model
    if isinstance(model, (list, tuple, set, lbann.Layer)):
        if isinstance(model, lbann.Layer):
            model = [model]
        model = lbann.Model(0, model)
    # Obtain outputs if not given
    if not outputs:
        outputs = [l.name for l in model.layers if not l.children]
    extra_callbacks = extra_callbacks or []
    #####################
    if 'job_name' not in kwargs:
        kwargs['job_name'] = 'lbann_evaluate'
    workdir = make_timestamped_work_dir(**kwargs)
    fmt = 'npy' if lbann.has_feature('CNPY') else 'csv'
    # Reset fields for evaluation
    old_epochs = model.epochs
    old_callbacks = model.callbacks
    old_metrics = model.metrics
    try:
        model.epochs = 1 if training else 0
        model.callbacks = [
            lbann.CallbackDumpOutputs(
                batch_interval=1,
                execution_modes='train' if training else 'test',
                directory=workdir,
                format=fmt,
                layers=' '.join(outputs))
        ] + extra_callbacks
        model.metrics = []
        data_reader = _setup_data_reader(inputs, workdir, training)
        trainer = lbann.Trainer(inputs.shape[0])
        ########################
        # Run model
        lbann.run(trainer, model, data_reader, lbann.NoOptimizer(), workdir,
                  **kwargs)
        #######################
        # Collect outputs
        output_tensors = _collect_outputs(outputs, workdir, inputs.dtype, fmt,
                                          training)
    finally:
        # Set fields back to original state
        model.epochs = old_epochs
        model.callbacks = old_callbacks
        model.metrics = old_metrics
    # Unpack tuple if single-element
    if len(output_tensors) == 1:
        output_tensors = output_tensors[0]
    return output_tensors