Generator Error On Simple Model

Hello. I’m trying to develop a hierarchical negative binomial regression model on count data. I’m getting a weird error that has something to with a generator(?). I haven’t seen this before so I wanted to see if anyone has seen this and can help me. Below is the error:

error

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File /opt/conda/lib/python3.10/site-packages/pytensor/compile/function/types.py:970, in Function.__call__(self, *args, **kwargs)
    968 try:
    969     outputs = (
--> 970         self.vm()
    971         if output_subset is None
    972         else self.vm(output_subset=output_subset)
    973     )
    974 except Exception:

File /opt/conda/lib/python3.10/site-packages/pytensor/graph/op.py:552, in Op.make_py_thunk.<locals>.rval(p, i, o, n, params)
    548 @is_thunk_type
    549 def rval(
    550     p=p, i=node_input_storage, o=node_output_storage, n=node, params=None
    551 ):
--> 552     r = p(n, [x[0] for x in i], o)
    553     for o in node.outputs:

File /opt/conda/lib/python3.10/site-packages/pytensor/tensor/random/op.py:339, in RandomVariable.perform(self, node, inputs, outputs)
    337 rng_var_out[0] = rng
--> 339 smpl_val = self.rng_fn(rng, *(args + [size]))
    341 if (
    342     not isinstance(smpl_val, np.ndarray)
    343     or str(smpl_val.dtype) != out_var.type.dtype
...
Inputs values: [Generator(PCG64) at 0x7FC6D9992880, array([5619]), array(4), array(3.73399624), 'not shown']
Outputs clients: [['output'], ['output']]

Here is the model code.

def make_next_level_hierarchy_variable(name, mu, alpha, beta, dims=None):
    with modelcontext(None):
        sigma_ = pm.Gamma(f'{name}_sigma', alpha=alpha, beta=beta)
        offset = pm.Normal(f'{name}_offset', dims=dims)
        return pm.Deterministic(f'{name}', mu + sigma_ * offset, dims=dims)


coords = {'business_line':business_lines,
            'category':categories}
#TRAINING THE MODEL STARTS HERE
print("fitting model...")
with pm.Model(coords=coords) as npi_model:    
    #Data that does not change
    cat_to_bl_map = pm.Data('cat_to_bl_map', cat_to_bl_idx, mutable=False)

    #Mutable Data
    observed_eaches = pm.Data('observed_eaches', df_train.ord_qty.values, mutable=True)
    pm_cat_idx = pm.Data('pm_cat', cat_idx, mutable = True)
    pm_month_0 = pm.Data('pm_month_0', offset_0,  mutable = True)
    pm_month_1 = pm.Data('pm_month_1', offset_1,  mutable = True)
    pm_month_2 = pm.Data('pm_month_2', offset_2,  mutable = True)
    pm_month_3 = pm.Data('pm_month_3', offset_3,  mutable = True)

    bl_intercept = utility_functions.make_next_level_hierarchy_variable(name='bl_intercept', mu=intercept, alpha=2, beta=1, dims=['business_line'])
    cat_intercept = utility_functions.make_next_level_hierarchy_variable(name='cat_intercept', mu=bl_intercept[cat_to_bl_map], alpha=2, beta=1, dims=['category'])

    month_0 = pm.Normal('month_0', mu = 0, sigma = 1)
    bl_month_0 = utility_functions.make_next_level_hierarchy_variable(name='bl_month_0', mu=month_0, alpha=2, beta=1, dims=['business_line'])
    cat_month_0 = utility_functions.make_next_level_hierarchy_variable(name='cat_month_0', mu=bl_month_0[cat_to_bl_map], alpha=2, beta=1, dims=['category'])

    month_1 = pm.Normal('month_1', mu = 0, sigma = 1)
    bl_month_1 = utility_functions.make_next_level_hierarchy_variable(name='bl_month_1', mu=month_1, alpha=2, beta=1, dims=['business_line'])
    cat_month_1 = utility_functions.make_next_level_hierarchy_variable(name='cat_month_1', mu=bl_month_1[cat_to_bl_map], alpha=2, beta=1, dims=['category'])

    month_2 = pm.Normal('month_2', mu = 0, sigma = 1)
    bl_month_2 = utility_functions.make_next_level_hierarchy_variable(name='bl_month_2', mu=month_2, alpha=2, beta=1, dims=['business_line'])
    cat_month_2 = utility_functions.make_next_level_hierarchy_variable(name='cat_month_2', mu=bl_month_2[cat_to_bl_map], alpha=2, beta=1, dims=['category'])

    month_3 = pm.Normal('month_3', mu = 0, sigma = 1)
    bl_month_3 = utility_functions.make_next_level_hierarchy_variable(name='bl_month_3', mu=month_3, alpha=2, beta=1, dims=['business_line'])
    cat_month_3 = utility_functions.make_next_level_hierarchy_variable(name='cat_month_3', mu=bl_month_3[cat_to_bl_map], alpha=2, beta=1, dims=['category'])

    mu = (cat_intercept[pm_cat_idx] + cat_month_0[pm_cat_idx]*pm_month_0 + cat_month_1[pm_cat_idx]*pm_month_1 + cat_month_2[pm_cat_idx]*pm_month_2 + cat_month_3[pm_cat_idx]*pm_month_3)

    n = np.log(mu)
    alpha_ = pm.HalfNormal('alpha', 2.5)

    likelihood = pm.NegativeBinomial('actuals', mu = n, alpha = alpha_, observed=observed_eaches)

idata = pm.sampling_jax.sample_numpyro_nuts(model = npi_model, draws = 1000, tune=1000, target_accept = .95, idata_kwargs={"log_likelihood": False})

I’ve also tried this just using one intercept term for the model and got the same error.

Has anyone see this before?

I think I figured it out.

This line:

bl_intercept = utility_functions.make_next_level_hierarchy_variable(name='bl_intercept', mu=intercept, alpha=2, beta=1, dims=['business_line'])

Should be preceded by the following line after it samples without error:

intercept = pm.Normal('intercept', mu = 0, sigma = 1)

I thought this was good. However, when I try to sample the posterior by running the following line:

ppc = pm.sample_posterior_predictive(trace = idata, model = npi_model)

But now I’m getting the same error when running that line:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File /opt/conda/lib/python3.10/site-packages/pytensor/compile/function/types.py:970, in Function.__call__(self, *args, **kwargs)
    968 try:
    969     outputs = (
--> 970         self.vm()
    971         if output_subset is None
    972         else self.vm(output_subset=output_subset)
    973     )
    974 except Exception:

File /opt/conda/lib/python3.10/site-packages/pytensor/graph/op.py:552, in Op.make_py_thunk.<locals>.rval(p, i, o, n, params)
    548 @is_thunk_type
    549 def rval(
    550     p=p, i=node_input_storage, o=node_output_storage, n=node, params=None
    551 ):
--> 552     r = p(n, [x[0] for x in i], o)
    553     for o in node.outputs:

File /opt/conda/lib/python3.10/site-packages/pytensor/tensor/random/op.py:339, in RandomVariable.perform(self, node, inputs, outputs)
    337 rng_var_out[0] = rng
--> 339 smpl_val = self.rng_fn(rng, *(args + [size]))
    341 if (
    342     not isinstance(smpl_val, np.ndarray)
    343     or str(smpl_val.dtype) != out_var.type.dtype
...
Inputs values: [Generator(PCG64) at 0x7F46F195D620, array([5619]), array(4), array(4.06224807), 'not shown']
Outputs clients: [['output'], ['output']]

HINT: Re-running with most PyTensor optimizations disabled could provide a back-trace showing when this node was created. This can be done by setting the PyTensor flag 'optimizer=fast_compile'. If that does not work, PyTensor optimizations can be disabled with 'optimizer=None'.
HINT: Use the PyTensor flag `exception_verbosity=high` for a debug print-out and storage map footprint of this Apply node.

EDIT 2:

I think it’s an issue with the negative binomial likelihood. When I change that likelihood to normal, I no longer get an error even though my data is over dispersed in a major way.