GNN Integration Layer: Python Framework Base:
pymdp(Python Package) Simulation Architecture: Online True POMDP Generative Model Documentation Version: 2.0.0
The Generalized Notation Notation (GNN) pipeline translates theoretical model specifications into executable Python code natively utilizing the pymdp framework. As the primary reference implementation within the Active Inference ecosystem, PyMDP operates as the mathematical ground truth for multi-framework correlation auditing.
This document details the exact mechanisms through which a GNN JSON specification is extracted, built into a PyMDP Agent node, evaluated continuously within an independent generative POMDP environment, and serialized into high-fidelity telemetry artifacts.
The PyMDP implementation relies on three interconnected architectures:
- Parameter Parsing:
pomdp_processor.py(Translating GNN variable states into multidimensional numpy matrices) - Generative Loop Generation:
pymdp_renderer.py(Building the target python script wrapping the agent inside a mathematical observation loop) - Execution Context:
pymdp_runner.py(Executing the generated python script and managing filesystem persistence)
Unlike strict typing systems, PyMDP initializes parameter matrices primarily using pure Numpy objects.
GNN maps structural definitions dynamically into pymdp.agent.Agent instantiation endpoints:
- State Space (
num_states): Inferred dynamically from the row dimensionality of theBtransition matrix (e.g.B_matrix.shape[1]) - Action Space (
num_actions): Inferred dynamically from the depth dimensionality of theBcontrol matrix (e.g.B_matrix.shape[2]) - Observation Space (
num_obs): Inferred dynamically from the row dimensionality of theAlikelihood matrix (e.g.A_matrix.shape[0])
# Extraction logic utilized by GNN to safely route specifications
agent = Agent(
A=A_matrix, # Likelihood mapping of Observation = f(State)
B=B_matrix, # Transition mapping of State(t+1) = f(State(t), Action)
C=C_vector, # Target Preference dist (Risk/Reward)
D=D_vector, # Prior initialization density
policy_len=1, # Depth 1 horizons by default in standard evaluation
inference_algo="MMP", # Marginal Message Passing
use_utility=True # Essential for Expected Free Energy activation
)A critical mandate of the cross-framework environment comparison is isolating the belief structure from the generative process entirely. PyMDP accomplishes this correctly by implementing a purely stochastic mathematical simulation that wraps around the agent instance itself.
The execution template builds the following sequence:
-
Initialize Environmental True State: The true environment begins by sampling the Prior definition
D.# Stochastic draw from Prior distribution true_state = utils.sample(D_vector)
-
Step-wise Environment Generation: The environment draws an observation exclusively from the true state using the Likelihood
Amatrix, shielding the agent from oracle knowledge.# Stochastic draw from A matrix conditioned on current True State observation = utils.sample(A_matrix[:, true_state])
-
Inference and Control Calculation (Agent): The PyMDP agent ingests the singular step observation to update its belief and calculate EFE.
qs = agent.infer_states([observation]) q_pi, efe = agent.infer_policies() action = agent.sample_action()
-
Environment Transition: The
true_statephysically shifts through spacetime based on the transition likelihood of theBmatrix, conditioned by the generated$Action$ .# Stochastic environment decay/shift true_state = utils.sample(B_matrix[:, true_state, int(action[0])])
PyMDP mathematically factors Expected Free Energy (EFE), stored internally as neg_efe, incorporating two principal components:
- Ambiguity (Expected Uncertainty): The entropy of the likelihood matrix
Aconditioned on predicted states. - Risk (Expected Divergence): The Kullback-Leibler (KL) divergence between the predicted observation distribution and the pre-defined target preference vector
C.
Important Tracking Detail: By mathematical convention within PyMDP, EFE is minimized as a negative quantity (neg_efe). Therefore, more optimal action selections natively resolve to higher (closer to 0) EFE values, conversely represented against frameworks that minimize positive EFE vectors.
At runtime, the PyMDP orchestrator records a full state continuum into memory and eventually dumps the structure out to the 12_execute block as simulation_results.json.
Logged Vectors:
-
beliefs: Array depth[num_timesteps, num_states]recording posterior$Q(S|O)$ . -
actions: Array length[num_timesteps]corresponding to index arrays of integer actions executed. -
observations: Array length[num_timesteps]logging the exact stochastic emission generated mathematically by the true environment. -
efe_history: 2-Dimensional Tensor[num_timesteps, num_policies]. While previously flattened dynamically, GNN extracts the comprehensive EFE vectors for all possible decisions evaluated at that timestep to allow high-fidelity plotting in downstream analysis engines.
"simulation_trace": {
"observations": [1, 1, 1, 0, 2],
"beliefs": [[0.05, 0.89, 0.05], [0.003, 0.99, 0.003], ...],
"actions": [0, 0, 0, 1, 2],
"efe_history": [
[-1.19, -1.19, -1.96],
[-0.68, -0.68, -1.45],
...
]
}The telemetry package operates with extremely high resilience, guaranteeing zero missing timesteps and zero floating-point NaN propagation across pipeline stages during standard tests.
| Pipeline Stage | Module | Key Function | Lines |
|---|---|---|---|
| Rendering | pymdp_renderer.py | render_gnn_to_pymdp() |
Entry point |
| Execution | pymdp_runner.py | execute_pymdp_script_with_outputs() |
L77-220 |
| Pre-validation | pymdp_runner.py | validate_and_clean_pymdp_script() |
L22-75 |
| Trace Generation | pymdp_runner.py | generate_simulation_trace() |
L264-304 |
| Analysis | analyzer.py | generate_analysis_from_logs() |
— |
| Cross-Framework | visualizations.py | generate_unified_comparison() |
— |
| ID | Area | Description | Impact |
|---|---|---|---|
| P-1 | Rendering | Matrix normalization is inlined — could be extracted into a shared utility | Low |
| P-2 | Execution | env = os.environ.copy() lines |
✅ FIXED |
| P-3 | Analysis | PyMDP analyzer imports PyMDPVisualizer which could fail silently |
Low |
| P-4 | Telemetry | simple_simulation.py could validate A/B/C/D shapes before simulation |
Medium |
- Cross-Framework Methodology: Details on the correlation methodology and benchmarking metrics.
- Architecture Reference: Deep dive into the pipeline orchestrator and module integration.
- GNN Implementations Index: Return to the master framework implementer manifest.
- Back to GNN START_HERE