code: def elbo(model, guide, *args, **kwargs):
      # Run the guide with the arguments passed to SVI.step() and trace the execution,
      # i.e. record all the calls to Pyro primitives like sample() and param().
      guide_trace = trace(guide).get_trace(*args, **kwargs)
      # Now run the model with the same arguments and trace the execution. Because
      # model is being run with replay, whenever we encounter a sample site in the
      # model, instead of sampling from the corresponding distribution in the model,
      # we instead reuse the corresponding sample from the guide. In probabilistic
      # terms, this means our loss is constructed as an expectation w.r.t. the joint
      # distribution defined by the guide.
      model_trace = trace(replay(model, guide_trace)).get_trace(
          *args, **kwargs
      )
      # We will accumulate the various terms of the ELBO in `elbo`.
      elbo = 0.0
      # Loop over all the sample sites in the model and add the corresponding
      # log p(z) term to the ELBO. Note that this will also include any observed
      # data, i.e. sample sites with the keyword `obs=...`.
      for site in model_trace.values():
          if site["type"] == "sample":
              elbo = elbo + site["fn"].log_prob(site["value"]).sum()
      # Loop over all the sample sites in the guide and add the corresponding
      # -log q(z) term to the ELBO.
      for site in guide_trace.values():
          if site["type"] == "sample":
              elbo = elbo - site["fn"].log_prob(site["value"]).sum()
      # Return (-elbo) since by convention we do gradient descent on a loss and
      # the ELBO is a lower bound that needs to be maximized.
      return -elbo
  
imports: import random
  import warnings
  import weakref
  from collections import OrderedDict
  import numpy
  import torch
  from pyro.distributions import validation_enabled
label_desc: Use image node_id 6 for calling a global function with example usage: elbo(model, guide) and returns: unknown