Skip to content

EnumeratedShapes converts with ClassifierConfig #2764

Open

Description

@DLumi

🐞Describing the bug

Apparently, ClassifierConfig only supports batch size of 1, and the conversion will fail if you supply any other batch explicitly. However, is not the case with EnumeratedShapes - the converter passes just fine, but you will get an error when trying to run the model on a mac device.
I'd appreciate if the conversion script failed whenever the single-sample (B=1) native models encounter symbolic shapes.

Stack Trace

input shape spec: EnumeratedShapes([(1, 32, 32, 3), (4, 32, 32, 3), (8, 32, 32, 3)], default=[4, 32, 32, 3])
Converting PyTorch Frontend ==> MIL Ops:  98%|█████████▊| 41/42 [00:00<00:00, 1658.45 ops/s]
Running MIL frontend_pytorch pipeline:   0%|          | 0/5 [00:00<?, ? passes/s]WARNING:coremltools:Saving value type of int64 into a builtin type of int32, might lose precision!
Running MIL frontend_pytorch pipeline: 100%|██████████| 5/5 [00:00<00:00, 289.08 passes/s]
Running MIL default pipeline: 100%|██████████| 95/95 [00:00<00:00, 885.01 passes/s]
Running MIL backend_mlprogram pipeline: 100%|██████████| 12/12 [00:00<00:00, 2594.28 passes/s]
CONVERT OK

To Reproduce

https://colab.research.google.com/drive/1bfrzzButElmpYzvvMV7ElnPGXkU1CpMl

System environment:

  • coremltools version: 9.0
  • OS: Linux a23a7a51d265 6.6.122+
  • Any other relevant version information: torch version 2.7.0+cu126

Activity

  1. added
    bugUnexpected behaviour that should be corrected (type)
    on Jul 29, 2026
  2. TobyRoseman commented on Jul 29, 2026

    @TobyRoseman
    Collaborator

    Sounds like you're bring up several possible issues. It's not clear to me which issues the Notebook Code is demonstrating.

    Please provide standalone code here (in the GitHub issue) with a clear explanation of the problem it demonstrates. Feel free to create separate issues for each distinct possible problem.

    I'd appreciate if the conversion script failed whenever the single-sample (B=1) native models encounter symbolic shapes.

    Why?

  3. DLumi commented on Jul 30, 2026

    @DLumi
    Author

    Thanks for taking a look. This is one issue, not several.
    The Colab notebook is a step-by-step copy of the standalone script - same three cases, each verified individually.
    What it demonstrates

    Case Input shape Convert Predict (macOS)
    1 Fixed batch=1 (control) OK OK
    2 Fixed batch=4 FAIL - number of classes must match the size of the tensor -
    3 EnumeratedShapes batches {1, 4, 8} OK FAIL - Classifier probabilities must have a fully known shape

    Cases 1 and 2 behave correctly. Case 3 is the bug.

    Root cause
    In classify type inference, the len(classes) == prod(probabilities.shape) check is skipped when the probability tensor has any symbolic dimension (if not any_symbolic(...)). Concrete batch > 1 hits that check and fails at convert time. EnumeratedShapes makes batch symbolic, skips the check, and conversion succeeds - but the runtime requires classifier probabilities to have a fully known shape, so the saved .mlpackage won't compile/run.

    Requested fix
    Fail at ct.convert(..., classifier_config=...) whenever probabilities fed to classify would be symbolic - same fail-fast behavior as concrete batch > 1, applied consistently.

    Why
    A successful conversion should mean a deployable artifact. Case 3 breaks that: export looks fine (on Linux you only see CONVERT OK), then it fails at compile/predict on macOS. Rejecting this up front avoids silently shipping broken models and matches the error users already get for the concrete batch > 1 case.

  4. TobyRoseman commented on Jul 30, 2026

    @TobyRoseman
    Collaborator

    So for case 3, the model converts without error but you cannot get predictions from it, is that correct? If so, what error do you get at prediction time?

  5. DLumi commented on Jul 30, 2026

    @DLumi
    Author

    When you try to run this successfully compiled model, you get this error:

    RuntimeWarning: You will not be able to run predict() on this Core ML model. Underlying exception message was: Error compiling model: "Failed to parse the model specification. Error: Unable to parse ML Program: in operation classify_0: Classifier probabilities must have a fully known shape.".
      _warnings.warn(
    Traceback (most recent call last):
      File "/Users/user/dev/a.k/product-cls-train/product-cls-train/coreml_validate.py", line 63, in <module>
        passed = validate(args.ckpt_path, args.mlpackage_path, args.model_type, args.atol, image_size=args.image_size)
      File "/Users/user/dev/a.k/product-cls-train/product-cls-train/coreml_validate.py", line 44, in validate
        prediction = mlmodel.predict({"input": example_input.numpy()})
      File "/Users/user/dev/a.k/product-cls-train/.venv/lib/python3.10/site-packages/coremltools/models/model.py", line 872, in predict
        raise self._framework_error
      File "/Users/user/dev/a.k/product-cls-train/.venv/lib/python3.10/site-packages/coremltools/models/model.py", line 617, in _get_proxy_and_spec
        _MLModelProxy(
    RuntimeError: Error compiling model: "Failed to parse the model specification. Error: Unable to parse ML Program: in operation classify_0: Classifier probabilities must have a fully known shape.".
    

    As far as I understand, this is by design, as ClassifierConfig (like many other non-generic mlprograms) only supports the batch_size of 1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugUnexpected behaviour that should be corrected (type)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions