def apply_model(
    samples,
    model,
    label_field="predictions",
    confidence_thresh=None,
    store_logits=False,
    batch_size=None,
    num_workers=None,
    skip_failures=True,
    output_dir=None,
    rel_dir=None,
    progress=None,
    **kwargs,
):
    """Applies the model to the samples in the collection.

    This method supports all of the following cases:

    -   Applying an image model to an image collection
    -   Applying an image model to the frames of a video collection
    -   Applying a video model to a video collection

    Args:
        samples: a :class:`fiftyone.core.collections.SampleCollection`
        model: a :class:`Model`, Hugging Face Transformers model, Ultralytics
            model, SuperGradients model, or Lightning Flash model
        label_field ("predictions"): the name of the field in which to store
            the model predictions. When performing inference on video frames,
            the "frames." prefix is optional
        confidence_thresh (None): an optional confidence threshold to apply to
            any applicable labels generated by the model
        store_logits (False): whether to store logits for the model
            predictions. This is only supported when the provided ``model`` has
            logits, ``model.has_logits == True``
        batch_size (None): an optional batch size to use, if the model supports
            batching
        num_workers (None): the number of workers to use when loading images.
            Only applicable for Torch-based models
        skip_failures (True): whether to gracefully continue without raising an
            error if predictions cannot be generated for a sample. Only
            applicable to :class:`Model` instances
        output_dir (None): an optional output directory in which to write
            segmentation images. Only applicable if the model generates
            segmentations. If none is provided, the segmentations are stored in
            the database
        rel_dir (None): an optional relative directory to strip from each input
            filepath to generate a unique identifier that is joined with
            ``output_dir`` to generate an output path for each segmentation
            image. This argument allows for populating nested subdirectories in
            ``output_dir`` that match the shape of the input paths. The path is
            converted to an absolute path (if necessary) via
            :func:`fiftyone.core.storage.normalize_path`
        progress (None): whether to render a progress bar (True/False), use the
            default value ``fiftyone.config.show_progress_bars`` (None), or a
            progress callback function to invoke instead
        **kwargs: optional model-specific keyword arguments passed through
            to the underlying inference implementation
    """
    if _is_flash_model(model):
        return fouf.apply_flash_model(
            samples,
            model,
            label_field=label_field,
            confidence_thresh=confidence_thresh,
            store_logits=store_logits,
            batch_size=batch_size,
            num_workers=num_workers,
            output_dir=output_dir,
            rel_dir=rel_dir,
            **kwargs,
        )

    model = _convert_model_if_necessary(model)

    if not isinstance(model, Model):
        raise ValueError("Unsupported model type: %s" % type(model))

    if samples.media_type == fom.IMAGE:
        fov.validate_image_collection(samples)
    elif samples.media_type == fom.GROUP:
        raise fom.SelectGroupSlicesError((fom.IMAGE, fom.VIDEO))
    elif samples.media_type != fom.VIDEO:
        raise fom.MediaTypeError(
            "Unsupported media type '%s'" % samples.media_type
        )

    if model.media_type == "video" and samples.media_type != fom.VIDEO:
        raise ValueError(
            "Video models can only be applied to video collections"
        )

    if model.media_type not in ("image", "video"):
        raise ValueError(
            "Unsupported model `media_type=%s`. Supported values are "
            "('image', 'video')" % model.media_type
        )

    if store_logits and not model.has_logits:
        raise ValueError(
            "The provided model does not expose logits "
            "(model.has_logits = %s)" % model.has_logits
        )

    supports_get_item = isinstance(model, SupportsGetItem)
    needs_samples = isinstance(model, SamplesMixin)

    if supports_get_item and needs_samples:
        field_mapping = kwargs.pop("field_mapping", {})
        needs_fields = kwargs.pop("needs_fields", {})
        needs_fields.update(kwargs)
    elif supports_get_item:
        field_mapping = kwargs.pop("field_mapping", {})
        field_mapping.update(kwargs)
        needs_fields = None
    elif needs_samples:
        field_mapping = None
        needs_fields = kwargs.pop("needs_fields", {})
        needs_fields.update(kwargs)
    else:
        field_mapping = None
        needs_fields = None

    process_video_frames = (
        samples.media_type == fom.VIDEO and model.media_type == "image"
    )

    use_data_loader = (
        isinstance(model, (SupportsGetItem, TorchModelMixin))
        and not process_video_frames
    )

    if num_workers is not None and not use_data_loader:
        logger.warning("Ignoring unsupported `num_workers` parameter")

    if output_dir is not None:
        filename_maker = fou.UniqueFilenameMaker(
            output_dir=output_dir, rel_dir=rel_dir, idempotent=False
        )
    else:
        filename_maker = None

    with contextlib.ExitStack() as context:
        try:
            if confidence_thresh is not None:
                cthresh = confidence_thresh
            else:
                cthresh = model.config.confidence_thresh

            context.enter_context(
                fou.SetAttributes(model.config, confidence_thresh=cthresh)
            )
        except:
            pass

        if store_logits:
            context.enter_context(fou.SetAttributes(model, store_logits=True))

        if use_data_loader:
            context.enter_context(fou.SetAttributes(model, preprocess=False))

        if needs_samples:
            context.enter_context(
                fou.SetAttributes(model, needs_fields=needs_fields)
            )

        context.enter_context(model)

        if model.media_type == "video":
            return _apply_video_model(
                samples,
                model,
                label_field,
                confidence_thresh,
                skip_failures,
                filename_maker,
                progress,
            )

        batch_size = _parse_batch_size(batch_size, model, use_data_loader)

        if process_video_frames:
            label_field, _ = samples._handle_frame_field(label_field)

            if batch_size is not None:
                return _apply_image_model_to_frames_batch(
                    samples,
                    model,
                    label_field,
                    confidence_thresh,
                    batch_size,
                    skip_failures,
                    filename_maker,
                    progress,
                )

            return _apply_image_model_to_frames_single(
                samples,
                model,
                label_field,
                confidence_thresh,
                skip_failures,
                filename_maker,
                progress,
            )

        if use_data_loader:
            return _apply_image_model_data_loader(
                samples,
                model,
                label_field,
                confidence_thresh,
                batch_size,
                num_workers,
                skip_failures,
                filename_maker,
                progress,
                field_mapping,
            )

        if batch_size is not None:
            return _apply_image_model_batch(
                samples,
                model,
                label_field,
                confidence_thresh,
                batch_size,
                skip_failures,
                filename_maker,
                progress,
            )

        return _apply_image_model_single(
            samples,
            model,
            label_field,
            confidence_thresh,
            skip_failures,
            filename_maker,
            progress,
        )
Applies the model to the samples in the collection.

    This method supports all of the following cases:

    -   Applying an image model to an image collection
    -   Applying an image model to the frames of a video collection
    -   Applying a video model to a video collection

    Args:
        samples: a :class:`fiftyone.core.collections.SampleCollection`
        model: a :class:`Model`, Hugging Face Transformers model, Ultralytics
            model, SuperGradients model, or Lightning Flash model
        label_field ("predictions"): the name of the field in which to store
            the model predictions. When performing inference on video frames,
            the "frames." prefix is optional
        confidence_thresh (None): an optional confidence threshold to apply to
            any applicable labels generated by the model
        store_logits (False): whether to store logits for the model
            predictions. This is only supported when the provided ``model`` has
            logits, ``model.has_logits == True``
        batch_size (None): an optional batch size to use, if the model supports
            batching
        num_workers (None): the number of workers to use when loading images.
            Only applicable for Torch-based models
        skip_failures (True): whether to gracefully continue without raising an
            error if predictions cannot be generated for a sample. Only
            applicable to :class:`Model` instances
        output_dir (None): an optional output directory in which to write
            segmentation images. Only applicable if the model generates
            segmentations. If none is provided, the segmentations are stored in
            the database
        rel_dir (None): an optional relative directory to strip from each input
            filepath to generate a unique identifier that is joined with
            ``output_dir`` to generate an output path for each segmentation
            image. This argument allows for populating nested subdirectories in
            ``output_dir`` that match the shape of the input paths. The path is
            converted to an absolute path (if necessary) via
            :func:`fiftyone.core.storage.normalize_path`
        progress (None): whether to render a progress bar (True/False), use the
            default value ``fiftyone.config.show_progress_bars`` (None), or a
            progress callback function to invoke instead
        **kwargs: optional model-specific keyword arguments passed through
            to the underlying inference implementation
    
fiftyone/core/models.py