Skip to content
Back to skills

2688 Inference 1a48ad07

ASecurity

- [Method Selection Guide](#method-selection-guide) - [MCMC Samplers](#mcmc-samplers) - [nutpie (Default)](#nutpie-default) - [NumPyro/JAX Backend](#numpyrojax-backend) - [PyMC NUTS](#pymc-nuts) - [Approximate Inference](#approximate-inference) - [Variational Inference (ADVI, DADVI)](#variational-inference) - [Pathfinder](#pathfinder) - [Combining Methods](#combining-methods)

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 11, 2026
developmentpythonrustgoawsdebuggingbackend

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2688-inference_1a48ad07 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2688 Inference 1a48ad07?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2688 Inference 1a48ad07
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2688-inference-1a48ad07/badge)](https://www.skillsdirectory.com/skills/tools-only-2688-inference-1a48ad07)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Inference Methods

## Table of Contents
- [Method Selection Guide](#method-selection-guide)
- [MCMC Samplers](#mcmc-samplers)
  - [nutpie (Default)](#nutpie-default)
  - [NumPyro/JAX Backend](#numpyrojax-backend)
  - [PyMC NUTS](#pymc-nuts)
- [Approximate Inference](#approximate-inference)
  - [Variational Inference (ADVI, DADVI)](#variational-inference)
  - [Pathfinder](#pathfinder)
- [Combining Methods](#combining-methods)

## Method Selection Guide

### MCMC Samplers (Exact Inference)

| Method | Best For | Speed | GPU | Notes |
|--------|----------|-------|-----|-------|
| **nutpie** | Default choice | 2-5x faster than PyMC | No | Rust-based, excellent adaptation |
| **NumPyro** | Large models, GPU | Fast | Yes | JAX-based, vectorized chains |
| **PyMC NUTS** | Compatibility | Baseline | No | Most tested, fallback option |

### Approximate Inference (Fast but Inexact)

| Method | Best For | Speed | GPU | Notes |
|--------|----------|-------|-----|-------|
| **ADVI** | Quick approximations | Fast | No | Mean-field or full-rank Gaussian |
| **DADVI** | Stable VI | Very fast | Yes | Deterministic gradients |
| **Pathfinder** | Initialization, screening | Very fast | Yes | Quasi-Newton optimization paths |

**When to use approximate inference:**
- Model screening before committing to full MCMC
- Very large datasets where MCMC is prohibitively slow
- Finding good initial values for MCMC
- Posteriors that are approximately Gaussian

**Caution**: Approximate methods underestimate posterior uncertainty and may miss multimodality. Always validate with MCMC when possible.

---

## Initialization and Common Failures

### "Initial evaluation of model at starting point failed"

This error occurs when the log-probability is `-inf` or `NaN` at initial parameter values.

**Common causes and fixes**:

| Cause | Fix |
|-------|-----|
| Data outside distribution support | Verify observed data matches likelihood bounds |
| Jitter pushes parameters outside constraints | Use `init="adapt_diag"` (no jitter) |
| Invalid default starting values | Specify `initvals={"param": value}` |
| Constant response variable | Ensure target variable has variance |

```python
# Fix 1: Reduce/eliminate initialization jitter
idata = pm.sample(init="adapt_diag")

# Fix 2: Specify valid starting values
idata = pm.sample(initvals={"sigma": 1.0, "beta": np.zeros(p)})

# Fix 3: Use ADVI for more robust initialization
idata = pm.sample(init="advi+adapt_diag")

# Debugging: check which variables have invalid log-probabilities
model.point_logps()
model.debug()
```

### The MCMC Prior Sampling Fallacy

**Common mistake**: Using `pm.sample()` to sample from the prior distribution.

```python
# BAD: pm.sample() uses MCMC even without observations
with prior_model:
    prior = pm.sample(draws=1000)  # slow, poor convergence for discrete vars

# GOOD: Use ancestral sampling for priors
with prior_model:
    prior = pm.sample_prior_predictive(draws=1000)  # instant, exact
```

`pm.sample_prior_predictive()` performs ancestral sampling (drawing directly from distributions in dependency order), which is instant and avoids all MCMC convergence issues.

---

## MCMC Samplers

### nutpie (Default)

Rust-based sampler with excellent mass matrix adaptation. Use as default.

#### Basic Usage

```python
import pymc as pm

with pm.Model() as model:
    # ... model specification ...
    pass

# Sample with nutpie backend
with model:
    idata = pm.sample(
        draws=1000,
        tune=1000,
        chains=4,
        nuts_sampler="nutpie",
        random_seed=42,
    )

    # IMPORTANT: nutpie doesn't store log_likelihood automatically
    # Compute it explicitly if you need LOO-CV or LOO-PIT
    pm.compute_log_likelihood(idata)
```

#### Configuration Options

```python
with model:
    idata = pm.sample(
        draws=1000,
        tune=1000,
        chains=4,
        nuts_sampler="nutpie",
        random_seed=42,
        progressbar=True,
        target_accept=0.8,  # increase for difficult posteriors
        cores=4,            # number of parallel chains
    )
```

#### When to Use PyMC NUTS Instead

- Debugging model specification issues (temporary only — switch back to nutpie after debugging)
- Model requires compound step methods mixing NUTS with discrete samplers

**Note**: nutpie supports all standard PyMC distributions and operations including `pytensor.scan`, `GaussianRandomWalk`, `AR`, `GARCH11`, `HSGP`, `Mixture`, `NormalMixture`, and `DensityDist`. "Complex model" is never a reason to avoid nutpie.

### NumPyro/JAX Backend

JAX-based sampling with GPU support and vectorized chains.

#### Setup

```python
import pymc as pm

# Optional: configure JAX for GPU
import jax
jax.config.update("jax_platform_name", "gpu")  # or "cpu"
```

#### Basic Usage

```python
with pm.Model() as model:
    # ... model specification ...
    pass

# Sample with NumPyro NUTS
with model:
    idata = pm.sample(
        draws=1000,
        tune=1000,
        chains=4,
        nuts_sampler="numpyro",
        random_seed=42,
    )
```

#### Vectorized Chains (GPU Efficient)

```python
# Run all chains in parallel on GPU
with model:
    idata = pm.sample(
        draws=1000,
        tune=1000,
        chains=4,
        nuts_sampler="numpyro",
        nuts_sampler_kwargs={"chain_method": "vectorized"},
    )
```

#### Configuration

```python
with model:
    idata = pm.sample(
        draws=1000,
        tune=1000,
        chains=4,
        nuts_sampler="numpyro",
        target_accept=0.9,
        nuts_sampler_kwargs={"max_tree_depth": 12},
        progressbar=True,
    )
```

#### When to Use NumPyro

- Large models that benefit from GPU
- Many chains needed (vectorization efficient)
- Already in JAX ecosystem

### PyMC NUTS

Legacy sampler. Only use for debugging or when nutpie and numpyro cannot be installed.

```python
with model:
    idata = pm.sample(
        draws=1000,
        tune=1000,
        chains=4,
        random_seed=42,
        target_accept=0.8,
    )
```

---

## Approximate Inference

### Variational Inference

#### ADVI (Automatic Differentiation Variational Inference)

Approximates the posterior with a Gaussian distribution.

```python
with model:
    approx = pm.fit(
        n=30000,
        method="advi",
        callbacks=[pm.callbacks.CheckParametersConvergence()],
    )

# Draw samples from the approximation
idata = approx.sample(1000)
```

#### Full-Rank ADVI

Better posterior approximation (captures correlations) at higher cost:

```python
with model:
    approx = pm.fit(
        n=50000,
        method="fullrank_advi",
    )
```

#### DADVI (Deterministic ADVI)

More stable variational inference from pymc-extras:

```python
import pymc_extras as pmx

with model:
    idata = pmx.fit(
        method="dadvi",
        num_steps=10000,
        random_seed=42,
    )
```

DADVI advantages:
- Deterministic gradients (no Monte Carlo noise)
- Faster convergence
- More stable optimization

### Pathfinder

Quasi-Newton variational method that follows optimization paths. Very fast for quick approximations or initialization.

```python
with model:
    idata = pm.fit(method="pathfinder")
```

#### Multi-Path Pathfinder

```python
with model:
    idata = pm.fit(
        method="pathfinder",
        num_paths=8,  # multiple optimization paths
        maxcor=10,    # L-BFGS history
    )
```

#### When to Use Pathfinder

- Quick posterior approximation (seconds vs minutes)
- Finding good initial values for MCMC
- Model screening before full inference
- When posterior is approximately Gaussian

---

## Combining Methods

### Pathfinder Initialization + MCMC

Use Pathfinder to find good starting points, then run MCMC for accurate inference:

```python
with model:
    # Quick pathfinder approximation
    pathfinder_idata = pm.fit(method="pathfinder")

    # Extract initial values
    init_vals = {
        var.name: pathfinder_idata.posterior[var.name].mean(dim=["chain", "draw"]).values
        for var in model.free_RVs
    }

    # Run MCMC with good initialization
    idata = pm.sample(initvals=init_vals)
```

### VI for Screening, MCMC for Final Inference

```python
# Screen model with VI (fast)
with model:
    vi_approx = pm.fit(n=30000)

# If model looks reasonable, run full MCMC
with model:
    idata = pm.sample()
```

### VI for Large Data, MCMC for Validation

```python
# Full data: use VI for speed
with full_model:
    vi_approx = pm.fit(n=30000)

# Validation subset: use MCMC for accurate uncertainty
with subset_model:
    idata = pm.sample()
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.