Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions backends/apple/coreml/compiler/coreml_preprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,18 @@ def model_compute_precision_from_compile_specs(

@staticmethod
def generate_minimum_deployment_target_compile_spec(
min_deployment_target: ct.target,
min_deployment_target: Optional[ct.target],
) -> CompileSpec:
"""
Returns the compile spec representing the minimum deployment target on which the model can run,
for additional details please refer to the documentation for ``coremltools.target``.
"""
value = str("").encode("utf-8")
if min_deployment_target is not None:
value = str(min_deployment_target.value).encode("utf-8")
return CompileSpec(
COMPILE_SPEC_KEYS.MIN_DEPLOYMENT_TARGET.value,
str(min_deployment_target.value).encode("utf-8"),
value,
)

@staticmethod
Expand All @@ -146,10 +149,13 @@ def min_deployment_target_from_compile_specs(
"""
for compile_spec in compile_specs:
if compile_spec.key == COMPILE_SPEC_KEYS.MIN_DEPLOYMENT_TARGET.value:
compile_spec_value: int = int(compile_spec.value.decode("utf-8"))
value = compile_spec.value.decode("utf-8")
if value == "":
return None
compile_spec_value: int = int(value)
return ct.target(compile_spec_value)

return ct.target.iOS15
return None

@staticmethod
def compute_unit_from_compile_specs(
Expand Down Expand Up @@ -211,7 +217,7 @@ def op_linear_quantizer_config_from_compile_specs(
@staticmethod
def generate_compile_specs(
compute_unit: ct.ComputeUnit = ct.ComputeUnit.ALL,
minimum_deployment_target: ct.target = ct.target.iOS15,
minimum_deployment_target: Optional[ct.target] = None,
compute_precision: ct.precision = ct.precision.FLOAT16,
model_type: MODEL_TYPE = MODEL_TYPE.MODEL,
op_linear_quantizer_config: Optional[Dict] = None,
Expand Down Expand Up @@ -248,6 +254,13 @@ def model_metadata_from_spec(
input_names: List[str] = [input.name for input in model_spec.description.input]
output_names = [output.name for output in model_spec.description.output]

if len(output_names) == 0:
raise ValueError("Cannot lower a model with no outputs in CoreML.")
if len(input_names) == 0:
assert (
model_spec.specificationVersion >= 9
), "Deploying a model with no inputs in CoreML requires you set minimum_deployment_target to iOS18 or later in the CoreMLPartitioner."

return ModelMetadata(
inputNames=input_names, outputNames=output_names, identifier=identifier
)
Expand Down Expand Up @@ -352,6 +365,12 @@ def preprocess_model(
dir_path: Path = Path("tmp") / identifier
model_dir_path: Path = dir_path / "lowered_module"
model_spec: ct.proto.Model_pb2 = mlmodel.get_spec()
logger.warning(
f"The model with identifier {identifier} was exported with CoreML specification version {model_spec.specificationVersion}, and it will not run on all version of iOS/macOS."
" See https://apple.github.io/coremltools/mlmodel/Format/Model.html#model for information on what OS versions are compatible with this specifcation version."
" If you want to control the deployment target, please set the minimum_deployment_target compile spec in the CoreMLPartitioner."
)

model_metadata: ModelMetadata = CoreMLBackend.model_metadata_from_spec(
model_spec=model_spec,
identifier=identifier,
Expand Down Expand Up @@ -418,7 +437,7 @@ def preprocess(
model_compute_precision: ct.precision = (
CoreMLBackend.model_compute_precision_from_compile_specs(compile_specs)
)
minimum_deployment_target: ct.target = (
minimum_deployment_target: Optional[ct.target] = (
CoreMLBackend.min_deployment_target_from_compile_specs(compile_specs)
)
compute_units: ct.ComputeUnit = CoreMLBackend.compute_unit_from_compile_specs(
Expand Down
4 changes: 1 addition & 3 deletions backends/apple/coreml/runtime/delegate/model_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ struct ModelMetadata {
inline ModelMetadata() noexcept { }

/// Returns `true` if the metadata is valid otherwise `false`.
inline bool is_valid() const noexcept {
return !identifier.empty() && !input_names.empty() && !output_names.empty();
}
inline bool is_valid() const noexcept { return !identifier.empty() && !output_names.empty(); }

inline std::string to_json_string() const noexcept { return executorchcoreml::serde::json::to_json_string(*this); }

Expand Down
Loading