Skip to content

BUG: model_to_graphviz fails with Flat variables #8024

@rrebane

Description

@rrebane

Describe the issue:

The call to pm.model_to_graphviz or model.to_graphviz fails if the model contains a pm.Flat variable. According to the error message, it tries to sample from the flat variable.

Reproduceable code example:

import numpy as np
import pandas as pd
import pymc as pm

RANDOM_SEED = 8927
rng = np.random.default_rng(RANDOM_SEED)

size = 200
true_intercept = 1
true_slope = 2

x = np.linspace(0, 1, size)
true_regression_line = true_intercept + true_slope * x
y = true_regression_line + rng.normal(scale=0.5, size=size)

data = pd.DataFrame({"x": x, "y": y})

with pm.Model() as model:
    intercept = pm.Flat("intercept") # <--- Flat prior here causes model.to_graphviz() to fail
    sigma = pm.HalfCauchy("sigma", beta=10)
    slope = pm.Normal("slope", 0, sigma=20)
    likelihood = pm.Normal("y", mu=intercept + slope * x, sigma=sigma, observed=y)
    idata = pm.sample(3000)

pm.model_to_graphviz(model)

Error message:

Traceback (most recent call last):
  File "/Users/rebane/miniconda3/envs/test/lib/python3.12/site-packages/pytensor/link/utils.py", line 197, in streamline_default_f
    thunk()
  File "/Users/rebane/miniconda3/envs/test/lib/python3.12/site-packages/pytensor/graph/op.py", line 545, in rval
    r = p(n, [x[0] for x in i], o)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/rebane/miniconda3/envs/test/lib/python3.12/site-packages/pytensor/tensor/random/op.py", line 430, in perform
    self.rng_fn(rng, *args, None if size is None else tuple(size)),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/rebane/miniconda3/envs/test/lib/python3.12/site-packages/pymc/distributions/continuous.py", line 357, in rng_fn
    raise NotImplementedError("Cannot sample from flat variable")
NotImplementedError: Cannot sample from flat variable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/rebane/dev/salk/turnout-model/model_test/tmp.py", line 25, in <module>
    pm.model_to_graphviz(model)
  File "/Users/rebane/miniconda3/envs/test/lib/python3.12/site-packages/pymc/model_graph.py", line 763, in model_to_graphviz
    plates=graph.get_plates(var_names=var_names),
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/rebane/miniconda3/envs/test/lib/python3.12/site-packages/pymc/model_graph.py", line 349, in get_plates
    var_name: tuple(map(int, fast_eval(self.model[var_name].shape)))
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/rebane/miniconda3/envs/test/lib/python3.12/site-packages/pymc/model_graph.py", line 77, in fast_eval
    return function([], var, mode=_cheap_eval_mode)()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/rebane/miniconda3/envs/test/lib/python3.12/site-packages/pytensor/compile/function/types.py", line 1038, in __call__
    outputs = vm() if output_subset is None else vm(output_subset=output_subset)
              ^^^^
  File "/Users/rebane/miniconda3/envs/test/lib/python3.12/site-packages/pytensor/link/utils.py", line 201, in streamline_default_f
    raise_with_op(fgraph, node, thunk)
  File "/Users/rebane/miniconda3/envs/test/lib/python3.12/site-packages/pytensor/link/utils.py", line 526, in raise_with_op
    raise exc_value.with_traceback(exc_trace)
  File "/Users/rebane/miniconda3/envs/test/lib/python3.12/site-packages/pytensor/link/utils.py", line 197, in streamline_default_f
    thunk()
  File "/Users/rebane/miniconda3/envs/test/lib/python3.12/site-packages/pytensor/graph/op.py", line 545, in rval
    r = p(n, [x[0] for x in i], o)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/rebane/miniconda3/envs/test/lib/python3.12/site-packages/pytensor/tensor/random/op.py", line 430, in perform
    self.rng_fn(rng, *args, None if size is None else tuple(size)),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/rebane/miniconda3/envs/test/lib/python3.12/site-packages/pymc/distributions/continuous.py", line 357, in rng_fn
    raise NotImplementedError("Cannot sample from flat variable")
NotImplementedError: Cannot sample from flat variable
Apply node that caused the error: flat_rv{"->()"}(RNG(<Generator(PCG64) at 0x13B388900>), NoneConst{None})
Toposort index: 0
Inputs types: [RandomGeneratorType, <pytensor.tensor.type_other.NoneTypeT object at 0x1105da480>]
Inputs shapes: ['No shapes', 'No shapes']
Inputs strides: ['No strides', 'No strides']
Inputs values: [Generator(PCG64) at 0x13B388900, None]
Outputs clients: [[], [Shape(intercept)]]

Backtrace when the node is created (use PyTensor flag traceback__limit=N to make it longer):
  File "/Users/rebane/dev/salk/turnout-model/model_test/tmp.py", line 19, in <module>
    intercept = pm.Flat("intercept") # <--- Flat prior here causes model.to_graphviz() to fail
  File "/Users/rebane/miniconda3/envs/test/lib/python3.12/site-packages/pymc/distributions/distribution.py", line 529, in __new__
    rv_out = cls.dist(*args, **kwargs)
  File "/Users/rebane/miniconda3/envs/test/lib/python3.12/site-packages/pymc/distributions/continuous.py", line 370, in dist
    res = super().dist([], **kwargs)
  File "/Users/rebane/miniconda3/envs/test/lib/python3.12/site-packages/pymc/distributions/distribution.py", line 598, in dist
    return cls.rv_op(*dist_params, size=create_size, **kwargs)

HINT: Use the PyTensor flag `exception_verbosity=high` for a debug print-out and storage map footprint of this Apply node.

PyMC version information:

  • PyMC: 5.27.0
  • PyTensor: 2.36.1
  • Python: 3.12.0
  • Operating system: macOS Sequoia 15.6.1
  • How did you install PyMC: pip

Context for the issue:

Visualizing the model fails. Does not block my work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions