def mil_convert_to_proto(
    model, convert_from, convert_to, converter_registry, main_pipeline=None, **kwargs
) -> Tuple[Optional["ct.models.MLModel"], Program]:
    """
    Convert model to proto object.

    Parameters
    ----------
    model: See `mil_convert`

    convert_from: See `mil_convert`

    convert_to: See `mil_convert`

    converter_registry: `ConverterRegistry`
      Available frontend and backend converters

    main_pipeline: `PassPipeline`
      The main pipeline with options set by users.
    """
    frontend_converter_type = converter_registry.frontends.get(convert_from.lower())
    if not frontend_converter_type:
        raise NotImplementedError(
            f'Frontend converter "{convert_from}" not implemented, must be '
            f"one of: {list(converter_registry.frontends.keys())}"
        )

    kwargs.setdefault("convert_from", convert_from)
    kwargs.setdefault("convert_to", convert_to)

    if main_pipeline is None:
        # If the client calls `mil_convert` directly, the `pass_pipeline` is None. To keep the
        # behaviour same as before, the quantization pass is removed in this situation.
        # TODO: rdar://106111553 ([Infra] Quantization Pass is skipped when `mil_convert` is called directly.)
        main_pipeline = kwargs.get("pass_pipeline", PassPipeline())
        main_pipeline.remove_passes({"common::add_fp16_cast", "common::add_int16_cast"})
    frontend_pipeline, backend_pipeline = _construct_other_pipelines(
        main_pipeline, convert_from, convert_to
    )

    frontend_converter = frontend_converter_type()
    prog = frontend_converter(model, **kwargs)
    PassPipelineManager.apply_pipeline(prog, frontend_pipeline)

    PassPipelineManager.apply_pipeline(prog, main_pipeline)

    if convert_to == 'milinternal':
        return None, prog

    PassPipelineManager.apply_pipeline(prog, backend_pipeline)

    prog._check_early_error_out_for_invalid_program()

    backend_converter_type = converter_registry.backends.get(convert_to.lower())
    if not backend_converter_type:
        raise NotImplementedError(
            f'Backend converter "{convert_to}" not implemented, must be '
            f"one of: {list(converter_registry.backends.keys())}"
        )
    backend_converter = backend_converter_type()
    out = backend_converter(prog, **kwargs)

    return out, prog

    Convert model to proto object.

    Parameters
    ----------
    model: See `mil_convert`

    convert_from: See `mil_convert`

    convert_to: See `mil_convert`

    converter_registry: `ConverterRegistry`
      Available frontend and backend converters

    main_pipeline: `PassPipeline`
      The main pipeline with options set by users.
    
coremltools/converters/mil/converter.py