Error "AttributeError: 'Scratchpad' object has no attribute 'ufunc'" in Docker container

Hi,

I have trained a Bayesian model using pymc 5.16.0 in vertex AI notebook (GCP). Then serializing it with cloudpickle and storing it in GCS bucket. Finally, in another notebook I am loading the model and doing predictions using the function sample_posterior_predictive(predictions=True) and everything works fine.

But when I run the same code for predictions using the same versions of dependencies within a docker container, it throws this error while running sample_posterior_predictive():

File "/code_master/application_pipeline/application_functions.py", line 80, in predict_posterior
    posterior = pm.sample_posterior_predictive(trace=trace, predictions=True, random_seed=29)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pymc/sampling/forward.py", line 870, in sample_posterior_predictive
    values = sampler_fn(**param)
             ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pymc/util.py", line 395, in wrapped
    return core_function(**input_point)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pytensor/compile/function/types.py", line 970, in __call__
    self.vm()
  File "/usr/local/lib/python3.12/site-packages/pytensor/link/vm.py", line 411, in __call__
    raise_with_op(self.fgraph, node, thunk)
  File "/usr/local/lib/python3.12/site-packages/pytensor/link/utils.py", line 528, in raise_with_op
    raise exc_value.with_traceback(exc_trace)
  File "/usr/local/lib/python3.12/site-packages/pytensor/link/vm.py", line 407, in __call__
    thunk()
  File "/usr/local/lib/python3.12/site-packages/pytensor/graph/op.py", line 524, in rval
    r = p(n, [x[0] for x in i], o)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pytensor/tensor/elemwise.py", line 747, in perform
    ufunc = node.tag.ufunc
            ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pytensor/graph/utils.py", line 286, in __getattribute__
    return super().__getattribute__(name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Scratchpad' object has no attribute 'ufunc'

Dockerfile:

FROM continuumio/miniconda3

COPY code_master_docker/modeling/utils code_master/modeling/utils
COPY code_master_docker/application_pipeline/application_pipeline_test.py code_master/application_pipeline/application_pipeline_test.py
COPY code_master_docker/application_pipeline/application_functions.py code_master/application_pipeline/application_functions.py

WORKDIR /code_master

COPY requirements_pip_only_new_packages.txt requirements.txt

RUN conda create -n docker_pymc -y python=3.12.3
RUN echo "source activate docker_pymc" > ~/.bashrc
RUN conda install pip

RUN conda config --set ssl_verify False
RUN conda config --add channels conda-forge
RUN conda install --force-reinstall pymc -y
RUN pip install --force-reinstall pillow
RUN pip install -r requirements.txt
RUN conda install numpyro -y

ENTRYPOINT ["python", "application_pipeline/application_pipeline_test.py"]

requirements.txt file:

‘pandas==2.2.2’,
‘numpy==1.26.4’,
‘google-cloud-storage==2.18.2’,
‘plotly==5.24.1’,
‘google-cloud-bigquery==3.25.0’,
‘db-dtypes==1.2.0’,
‘logging==0.4.9.6’,
‘argparse==1.4.0’,
‘google-cloud-aiplatform==1.68.0’,
‘pandas-gbq==0.23.0’,
‘pytrends==4.9.0’,
‘scikit-learn==1.3.0’,
‘pytensor==2.23.0’,
‘seaborn==0.13.2’,
‘matplotlib==3.9.2’,
‘arviz==0.18.0’,
‘pymc==5.16.0’,
‘jax==0.4.26’,
‘jaxlib==0.4.23’,
‘cloudpickle==3.0.0’

and python version is 3.12.3

Can anyone help me understand the root cause and its resolution?

Thanks a lot

Do you see a warning about fusion before the error?

I am getting this error before “AttributeError: ‘Scratchpad’ object has no attribute ‘ufunc’”:

ERROR (pytensor.graph.rewriting.basic): Traceback (most recent call last):
  File "/opt/conda/envs/docker_pymc/lib/python3.12/site-packages/pytensor/graph/rewriting/basic.py", line 1920, in process_node
    replacements = node_rewriter.transform(fgraph, node)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/envs/docker_pymc/lib/python3.12/site-packages/pytensor/graph/rewriting/basic.py", line 1081, in transform
    return self.fn(fgraph, node)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/envs/docker_pymc/lib/python3.12/site-packages/pytensor/tensor/rewriting/basic.py", line 1121, in constant_folding
    thunk = node.op.make_thunk(node, storage_map, compute_map, no_recycling=[])
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/envs/docker_pymc/lib/python3.12/site-packages/pytensor/link/c/op.py", line 119, in make_thunk
    return self.make_c_thunk(node, storage_map, compute_map, no_recycling)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/envs/docker_pymc/lib/python3.12/site-packages/pytensor/link/c/op.py", line 84, in make_c_thunk
    outputs = cl.make_thunk(
              ^^^^^^^^^^^^^^
  File "/opt/conda/envs/docker_pymc/lib/python3.12/site-packages/pytensor/link/c/basic.py", line 1190, in make_thunk
    cthunk, module, in_storage, out_storage, error_storage = self.__compile__(
                                                             ^^^^^^^^^^^^^^^^^
  File "/opt/conda/envs/docker_pymc/lib/python3.12/site-packages/pytensor/link/c/basic.py", line 1110, in __compile__
    thunk, module = self.cthunk_factory(
                    ^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/envs/docker_pymc/lib/python3.12/site-packages/pytensor/link/c/basic.py", line 1632, in cthunk_factory
    module = cache.module_from_key(key=key, lnk=self)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/envs/docker_pymc/lib/python3.12/site-packages/pytensor/link/c/cmodule.py", line 1250, in module_from_key
    module = lnk.compile_cmodule(location)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/envs/docker_pymc/lib/python3.12/site-packages/pytensor/link/c/basic.py", line 1533, in compile_cmodule
    module = c_compiler.compile_str(
             ^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/envs/docker_pymc/lib/python3.12/site-packages/pytensor/link/c/cmodule.py", line 2601, in compile_str
    p_out = output_subprocess_Popen(cmd)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/envs/docker_pymc/lib/python3.12/site-packages/pytensor/utils.py", line 209, in output_subprocess_Popen
    p = subprocess_Popen(command, **params)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/envs/docker_pymc/lib/python3.12/site-packages/pytensor/utils.py", line 175, in subprocess_Popen
    proc = subprocess.Popen(command, startupinfo=startupinfo, **params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/envs/docker_pymc/lib/python3.12/subprocess.py", line 1026, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/opt/conda/envs/docker_pymc/lib/python3.12/subprocess.py", line 1953, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'g++'

It’s trying to access g++ to execute a certain Op, but failing. Can you find which node.op it is?