def predict_intermediate_outputs(
        self, inputs, intermediate_output_names, compute_units=ct.ComputeUnit.CPU_ONLY
    ):
        """Append all intermediate_output_names to model's output, and then use model.predict to get those outputs."""
        model_key = frozenset(intermediate_output_names)

        cloned_spec = self.__class__.clone_spec(self.model_info.spec)
        if self.model_info.spec.specificationVersion < _SPECIFICATION_VERSION_IOS_16:
            logger.warning(
                f"The model has spec version {self.model_info.spec.specificationVersion}, but the minimum "
                f"version to do activation quantization is {_SPECIFICATION_VERSION_IOS_16}. Forcely updated the spec to {_SPECIFICATION_VERSION_IOS_16} during calibration."
            )
            cloned_spec.specificationVersion = max(self.model_info.spec.specificationVersion, 7)
        cloned_model_info = ModelInfo(
            ModelDebugger.get_program_info(cloned_spec.mlProgram), cloned_spec
        )
        cloned_block_info = self.__class__.get_any_block(cloned_model_info)

        for output_name in intermediate_output_names:
            cloned_output_type = self.__class__.get_output_feature_type(
                output_name, self.block_info.operations
            )

            # Some intermediate tensors cannot be appended to outputs since their data type is not valid as an output data type.
            # For example, an intermediate tensor with bool type cannot be appended to outputs (which will cause compilation error).
            if cloned_output_type is None:
                continue

            cloned_block_info.spec.outputs.append(output_name)
            cloned_output = ct.proto.Model_pb2.FeatureDescription()
            cloned_output.name = output_name
            cloned_output.type.multiArrayType.dataType = cloned_output_type
            cloned_model_info.spec.description.output.append(cloned_output)

        model = ct.models.MLModel(
            cloned_spec,
            weights_dir=self.weights_dir,
            compute_units=compute_units,
            skip_model_load=False,  # Don't skip model load as we need model prediction to get activations range.
        )
        return model.predict(inputs)
Append all intermediate_output_names to model's output, and then use model.predict to get those outputs.
coremltools/optimize/coreml/experimental/_model_debugger.py