sklearn-onnx: ValueError: Unable to create node 'LabelEncoder' with name='LabelEncoder3' and attributes={'keys_floats': array([False, True]), 'values_int64s': array([0, 1])}.

Hi there!

I’m trying to convert the sklearn’s Pipeline to the ONNX format, but I get a strange error. The Pipeline is the following:

        preprocessor = ColumnTransformer(
            transformers=[
                ("cat", OrdinalEncoder(dtype=np.int64), categorical_features),
                ("num", "passthrough", numerical_features),
            ],
            sparse_threshold=1,
            verbose_feature_names_out=False,
        ).set_output(transform="pandas")
        model = make_pipeline(
            self.preprocessor, RandomForestRegressor(**cfg.model.hyperparams)
        )

The dataset is obtained via fetch_openml("Bike_Sharing_Demand", version=2, as_frame=True, parser="pandas") and little preprocessing (e.g. the “heavy_rain” category is merged with the “rain” category). The result of print(X_train.iloc[:1]) is

   season  month  hour  holiday  weekday  workingday weather  temp  feel_temp  humidity  windspeed
0  spring      1     0    False        6       False   clear  9.84     14.395      0.81        0.0

When I run model_onnx = to_onnx(model, X=X_train.iloc[:1], verbose=1), I get an error in the title. The type guessing seems to work fine:

[to_onnx] initial_types=[('season', StringTensorType(shape=[None, 1])), ('month', Int64TensorType(shape=[None, 1])), ('hour', Int64TensorType(shape=[None, 1])), ('holiday', BooleanTensorType(shape=[None, 1])), ('weekday', Int64TensorType(shape=[None, 1])), ('workingday', BooleanTensorType(shape=[None, 1])), ('weather', StringTensorType(shape=[None, 1])), ('temp', DoubleTensorType(shape=[None, 1])), ('feel_temp', DoubleTensorType(shape=[None, 1])), ('humidity', DoubleTensorType(shape=[None, 1])), ('windspeed', DoubleTensorType(shape=[None, 1]))]

The remaining part of the output is:

[convert_sklearn] parse_sklearn_model
[convert_sklearn] convert_topology
[convert_operators] begin
[convert_operators] iteration 1 - n_vars=0 n_ops=5
[call_converter] call converter for 'SklearnConcat'.
[call_converter] call converter for 'SklearnOrdinalEncoder'.
Traceback (most recent call last):
  File "/home/topcoder2k/.cache/pypoetry/virtualenvs/mlopscourse-4vHWhyzM-py3.9/lib/python3.9/site-packages/skl2onnx/common/_container.py", line 707, in add_node
    node = make_node(op_type, inputs, outputs, name=name, **new_attrs)
  File "/home/topcoder2k/.cache/pypoetry/virtualenvs/mlopscourse-4vHWhyzM-py3.9/lib/python3.9/site-packages/onnx/helper.py", line 164, in make_node
    node.attribute.extend(
  File "/home/topcoder2k/.cache/pypoetry/virtualenvs/mlopscourse-4vHWhyzM-py3.9/lib/python3.9/site-packages/onnx/helper.py", line 165, in <genexpr>
    make_attribute(key, value)
  File "/home/topcoder2k/.cache/pypoetry/virtualenvs/mlopscourse-4vHWhyzM-py3.9/lib/python3.9/site-packages/onnx/helper.py", line 894, in make_attribute
    raise ValueError(
ValueError: Could not infer the attribute type from the elements of the passed Iterable value.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/topcoder2k/CodeProjects/MLOps/mlops-course/commands.py", line 59, in <module>
    fire.Fire()
  File "/home/topcoder2k/.cache/pypoetry/virtualenvs/mlopscourse-4vHWhyzM-py3.9/lib/python3.9/site-packages/fire/core.py", line 141, in Fire
    component_trace = _Fire(component, args, parsed_flag_args, context, name)
  File "/home/topcoder2k/.cache/pypoetry/virtualenvs/mlopscourse-4vHWhyzM-py3.9/lib/python3.9/site-packages/fire/core.py", line 475, in _Fire
    component, remaining_args = _CallAndUpdateTrace(
  File "/home/topcoder2k/.cache/pypoetry/virtualenvs/mlopscourse-4vHWhyzM-py3.9/lib/python3.9/site-packages/fire/core.py", line 691, in _CallAndUpdateTrace
    component = fn(*varargs, **kwargs)
  File "/home/topcoder2k/CodeProjects/MLOps/mlops-course/commands.py", line 30, in train
    Trainer(config_name, **kwargs).train()
  File "/home/topcoder2k/CodeProjects/MLOps/mlops-course/mlopscourse/train.py", line 69, in train
    model_onnx = to_onnx(model.model, X=X_train.iloc[:1], verbose=1)
  File "/home/topcoder2k/.cache/pypoetry/virtualenvs/mlopscourse-4vHWhyzM-py3.9/lib/python3.9/site-packages/skl2onnx/convert.py", line 306, in to_onnx
    return convert_sklearn(
  File "/home/topcoder2k/.cache/pypoetry/virtualenvs/mlopscourse-4vHWhyzM-py3.9/lib/python3.9/site-packages/skl2onnx/convert.py", line 208, in convert_sklearn
    onnx_model = convert_topology(
  File "/home/topcoder2k/.cache/pypoetry/virtualenvs/mlopscourse-4vHWhyzM-py3.9/lib/python3.9/site-packages/skl2onnx/common/_topology.py", line 1532, in convert_topology
    topology.convert_operators(container=container, verbose=verbose)
  File "/home/topcoder2k/.cache/pypoetry/virtualenvs/mlopscourse-4vHWhyzM-py3.9/lib/python3.9/site-packages/skl2onnx/common/_topology.py", line 1349, in convert_operators
    self.call_converter(operator, container, verbose=verbose)
  File "/home/topcoder2k/.cache/pypoetry/virtualenvs/mlopscourse-4vHWhyzM-py3.9/lib/python3.9/site-packages/skl2onnx/common/_topology.py", line 1132, in call_converter
    conv(self.scopes[0], operator, container)
  File "/home/topcoder2k/.cache/pypoetry/virtualenvs/mlopscourse-4vHWhyzM-py3.9/lib/python3.9/site-packages/skl2onnx/common/_registration.py", line 27, in __call__
    return self._fct(*args)
  File "/home/topcoder2k/.cache/pypoetry/virtualenvs/mlopscourse-4vHWhyzM-py3.9/lib/python3.9/site-packages/skl2onnx/operator_converters/ordinal_encoder.py", line 89, in convert_sklearn_ordinal_encoder
    container.add_node(
  File "/home/topcoder2k/.cache/pypoetry/virtualenvs/mlopscourse-4vHWhyzM-py3.9/lib/python3.9/site-packages/skl2onnx/common/_container.py", line 709, in add_node
    raise ValueError(
ValueError: Unable to create node 'LabelEncoder' with name='LabelEncoder3' and attributes={'keys_floats': array([False,  True]), 'values_int64s': array([0, 1])}.

The skl2onnx version from the poetry.lock is:

[[package]]
name = "skl2onnx"
version = "1.15.0"
description = "Convert scikit-learn models to ONNX"
optional = false
python-versions = "*"
files = [
    {file = "skl2onnx-1.15.0-py2.py3-none-any.whl", hash = "sha256:13a9ea5d50619ce42381c67001db8c87ce574a459a8f0738b45d2f4b93f465f6"},
    {file = "skl2onnx-1.15.0.tar.gz", hash = "sha256:05b2c2643ad0357ec1ea684d138438a2df657df828e57d07cb78c2e76be20e37"},
]

UPD:

I’ve also decided to leave here the python and scikit-learn versions:

python --- 3.9.13
scikit-learn --- 1.3.1

About this issue

  • Original URL
  • State: open
  • Created 7 months ago
  • Comments: 24

Most upvoted comments

Could you use a tool like netron to look at your model and search for node LabelEncoder5? It should show you the data it processes and lead you to the input it is connected to.

I created PR #1049 to look into your issue but I can’t replicate it. I assume the test I used is different from yours. Could you let me know what is different?