Repository: sbi-dev/sbi

Issue:
linearGaussian_snre_test fails
**Describe the bug**
The following tests fail (stochastically) since the training data produces one Inf for each of them.

```
test_api_snre_multiple_trials_and_rounds_map[SNRE_B-1]
test_api_snre_multiple_trials_and_rounds_map[SNRE_C-1]
```

**To Reproduce**
Please add a minimal code example that reproduces the problem:
1. Name Python version and SBI version: `Python 3.8.18` git commit `105008efbacf320758e43a5db5bee4e3a0f9de36`
1. Minimal code example `pytest tests/linearGaussian_snre_test.py -k test_api_snre_multiple_trials_and_rounds_map`
1. [Optional]: error message

**Expected behavior**
should not create an Inf

**Additional context**
I am working on #966 , but it shouldn't affect this test.



Discussion:
I just ran `pytest tests/linearGaussian_snre_test.py -k test_api_snre_multiple_trials_and_rounds_map` on the current main (commit b81420b096439e936b3c3b38e8ba3c757e0b0b92). The first 2 tries passed, on the 3rd one I got. This error seems to be non-deterministic. 
```
FAILED tests/linearGaussian_snre_test.py::test_api_snre_multiple_trials_and_rounds_map[SNRE_B-1] - ValueError: Found 0 NaN simulations and 2 Inf simulations.SNRE does not allow invalid simulations. Replace the invalid values with an unreasonably low or hig...
```

@michaeldeistler I think that this is related to what I approached you about, even though the tests in our PyMC PR have been successful afterward. However, now I think we just got lucky :sweat_smile: 

Resolving patch:
diff --git a/sbi/neural_nets/density_estimators/mixed_density_estimator.py b/sbi/neural_nets/density_estimators/mixed_density_estimator.py
--- a/sbi/neural_nets/density_estimators/mixed_density_estimator.py
+++ b/sbi/neural_nets/density_estimators/mixed_density_estimator.py
@@ -150,7 +150,8 @@ def log_prob_iid(self, x: Tensor, context: Tensor) -> Tensor:
         inference. The speed up is achieved by exploiting the fact that there are only
         finite number of possible categories in the discrete part of the dat: one can
         just calculate the log probs for each possible category (given the current batch
-        of context) and then copy those log probs into the entire batch of iid categories.
+        of context) and then copy those log probs into the entire batch of iid
+        categories.
         For example, for the drift-diffusion model, there are only two choices, but
         often 100s or 1000 trials. With this method a evaluation over trials then passes
         a batch of `2 (one per choice) * num_contexts` into the NN, whereas the normal
@@ -175,7 +176,8 @@ def log_prob_iid(self, x: Tensor, context: Tensor) -> Tensor:
         net_device = next(self.discrete_net.parameters()).device
         assert (
             net_device == x.device and x.device == context.device
-        ), f"device mismatch: net, x, context: {net_device}, {x.device}, {context.device}."
+        ), f"device mismatch: net, x, context: \
+            {net_device}, {x.device}, {context.device}."
 
         x_cont_repeated, x_disc_repeated = _separate_x(x_repeated)
         x_cont, x_disc = _separate_x(x)
diff --git a/sbi/utils/user_input_checks.py b/sbi/utils/user_input_checks.py
--- a/sbi/utils/user_input_checks.py
+++ b/sbi/utils/user_input_checks.py
@@ -610,8 +610,8 @@ def process_x(
 def prepare_for_sbi(simulator: Callable, prior) -> Tuple[Callable, Distribution]:
     """Prepare simulator and prior for usage in sbi.
 
-    NOTE: This method is deprecated as of sbi version v0.23.0. and will be removed in a future release.
-    Please use `process_prior` and `process_simulator` in the future.
+    NOTE: This method is deprecated as of sbi version v0.23.0. and will be removed in a
+    future release. Please use `process_prior` and `process_simulator` in the future.
     This is a wrapper around `process_prior` and `process_simulator` which can be
     used in isolation as well.
 
@@ -633,7 +633,8 @@ def prepare_for_sbi(simulator: Callable, prior) -> Tuple[Callable, Distribution]
     """
 
     warnings.warn(
-        "This method is deprecated as of sbi version v0.23.0. and will be removed in a future release."
+        "This method is deprecated as of sbi version v0.23.0. and will be removed in a \
+        future release."
         "Please use `process_prior` and `process_simulator` in the future.",
         DeprecationWarning,
         stacklevel=2,


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -29,3 +29,15 @@ def pytest_collection_modifyitems(config, items):
         for item in items:
             if "gpu" in item.keywords:
                 item.add_marker(skip_gpu)
+
+
+@pytest.fixture(scope="function")
+def mcmc_params_accurate() -> dict:
+    """Fixture for MCMC parameters for functional tests."""
+    return dict(num_chains=20, thin=2, warmup_steps=50)
+
+
+@pytest.fixture(scope="function")
+def mcmc_params_fast() -> dict:
+    """Fixture for MCMC parameters for fast tests."""
+    return dict(num_chains=1, thin=1, warmup_steps=10)
diff --git a/tests/embedding_net_test.py b/tests/embedding_net_test.py
--- a/tests/embedding_net_test.py
+++ b/tests/embedding_net_test.py
@@ -21,10 +21,13 @@
 from .test_utils import check_c2st
 
 
+@pytest.mark.mcmc
 @pytest.mark.parametrize("method", ["SNPE", "SNLE", "SNRE"])
 @pytest.mark.parametrize("num_dim", [1, 2])
 @pytest.mark.parametrize("embedding_net", ["mlp"])
-def test_embedding_net_api(method, num_dim: int, embedding_net: str):
+def test_embedding_net_api(
+    method, num_dim: int, embedding_net: str, mcmc_params_fast: dict
+):
     """Tests the API when using a preconfigured embedding net."""
 
     x_o = zeros(1, num_dim)
@@ -62,7 +65,7 @@ def test_embedding_net_api(method, num_dim: int, embedding_net: str):
     _ = inference.append_simulations(theta, x).train(max_num_epochs=2)
     posterior = inference.build_posterior(
         mcmc_method="slice_np_vectorized",
-        mcmc_parameters=dict(num_chains=2, warmup_steps=10, thin=5),
+        mcmc_parameters=mcmc_params_fast,
     ).set_default_x(x_o)
 
     s = posterior.sample((1,))
diff --git a/tests/ensemble_test.py b/tests/ensemble_test.py
--- a/tests/ensemble_test.py
+++ b/tests/ensemble_test.py
@@ -48,13 +48,15 @@ def simulator(theta):
     (
         (SNPE_C, 1),
         pytest.param(SNPE_C, 5, marks=pytest.mark.xfail),
-        (SNLE_A, 1),
-        (SNLE_A, 5),
-        (SNRE_A, 1),
-        (SNRE_A, 5),
+        pytest.param(SNLE_A, 1, marks=pytest.mark.mcmc),
+        pytest.param(SNLE_A, 5, marks=pytest.mark.mcmc),
+        pytest.param(SNRE_A, 1, marks=pytest.mark.mcmc),
+        pytest.param(SNRE_A, 5, marks=pytest.mark.mcmc),
     ),
 )
-def test_c2st_posterior_ensemble_on_linearGaussian(inference_method, num_trials):
+def test_c2st_posterior_ensemble_on_linearGaussian(
+    inference_method, num_trials, mcmc_params_accurate: dict
+):
     """Test whether EnsemblePosterior infers well a simple example with available
     ground truth.
     """
@@ -63,7 +65,7 @@ def test_c2st_posterior_ensemble_on_linearGaussian(inference_method, num_trials)
     ensemble_size = 2
     x_o = zeros(num_trials, num_dim)
     num_samples = 500
-    num_simulations = 2000 if inference_method == SNRE_A else 1500
+    num_simulations = 2000
 
     # likelihood_mean will be likelihood_shift+theta
     likelihood_shift = -1.0 * ones(num_dim)
@@ -100,10 +102,8 @@ def simulator(theta):
     if isinstance(inferer, (SNLE_A, SNRE_A)):
         samples = posterior.sample(
             (num_samples,),
-            num_chains=20,
             method="slice_np_vectorized",
-            thin=5,
-            warmup_steps=50,
+            **mcmc_params_accurate,
         )
     else:
         samples = posterior.sample((num_samples,))
diff --git a/tests/inference_on_device_test.py b/tests/inference_on_device_test.py
--- a/tests/inference_on_device_test.py
+++ b/tests/inference_on_device_test.py
@@ -45,20 +45,20 @@
     [
         (SNPE_C, "maf", "direct"),
         (SNPE_C, "mdn", "rejection"),
-        (SNPE_C, "maf", "slice_np_vectorized"),
-        (SNPE_C, "mdn", "slice"),
-        (SNLE, "nsf", "slice_np_vectorized"),
-        (SNLE, "mdn", "slice"),
+        pytest.param(SNPE_C, "maf", "slice_np_vectorized", marks=pytest.mark.mcmc),
+        pytest.param(SNPE_C, "mdn", "slice", marks=pytest.mark.mcmc),
+        pytest.param(SNLE, "nsf", "slice_np_vectorized", marks=pytest.mark.mcmc),
+        pytest.param(SNLE, "mdn", "slice", marks=pytest.mark.mcmc),
         (SNLE, "nsf", "rejection"),
         (SNLE, "maf", "importance"),
-        (SNRE_A, "mlp", "slice_np_vectorized"),
-        (SNRE_A, "mlp", "slice"),
+        pytest.param(SNRE_A, "mlp", "slice_np_vectorized", marks=pytest.mark.mcmc),
+        pytest.param(SNRE_A, "mlp", "slice", marks=pytest.mark.mcmc),
         (SNRE_B, "resnet", "rejection"),
         (SNRE_B, "resnet", "importance"),
-        (SNRE_B, "resnet", "slice"),
+        pytest.param(SNRE_B, "resnet", "slice", marks=pytest.mark.mcmc),
         (SNRE_C, "resnet", "rejection"),
         (SNRE_C, "resnet", "importance"),
-        (SNRE_C, "resnet", "nuts"),
+        pytest.param(SNRE_C, "resnet", "nuts", marks=pytest.mark.mcmc),
     ],
 )
 @pytest.mark.parametrize(
@@ -71,7 +71,13 @@
 )
 @pytest.mark.parametrize("prior_type", ["gaussian", "uniform"])
 def test_training_and_mcmc_on_device(
-    method, model, sampling_method, training_device, prior_device, prior_type
+    method,
+    model,
+    sampling_method,
+    training_device,
+    prior_device,
+    prior_type,
+    mcmc_params_fast: dict,
 ):
     """Test training on devices.
 
@@ -85,9 +91,11 @@ def test_training_and_mcmc_on_device(
 
     num_dim = 2
     num_samples = 10
-    num_simulations = 100
-    max_num_epochs = 2
+    max_num_epochs = 10
     num_rounds = 2  # test proposal sampling in round 2.
+    num_simulations_per_round = [200, num_samples]
+    # use more warmup steps to avoid Infs during MCMC in round two.
+    mcmc_params_fast["warmup_steps"] = 20
 
     x_o = zeros(1, num_dim).to(data_device)
     likelihood_shift = -1.0 * ones(num_dim).to(prior_device)
@@ -134,7 +142,7 @@ def simulator(theta):
     proposals = [prior]
 
     for _ in range(num_rounds):
-        theta = proposals[-1].sample((num_simulations,))
+        theta = proposals[-1].sample((num_simulations_per_round[_],))
         x = simulator(theta).to(data_device)
         theta = theta.to(data_device)
 
@@ -147,10 +155,7 @@ def simulator(theta):
             posterior = inferer.build_posterior(
                 sample_with="mcmc",
                 mcmc_method=sampling_method,
-                mcmc_parameters=dict(
-                    thin=10 if sampling_method == "slice_np_vectorized" else 1,
-                    num_chains=10 if sampling_method == "slice_np_vectorized" else 1,
-                ),
+                mcmc_parameters=mcmc_params_fast,
             )
         elif sampling_method in ["rejection", "direct"]:
             # all other cases: rejection, direct
@@ -331,6 +336,7 @@ def test_embedding_nets_integration_training_device(
     embedding_net_device: str,
     data_device: str,
     training_device: str,
+    mcmc_params_fast: dict,
 ) -> None:
     """Test embedding nets integration with different devices, priors and methods."""
     # add other methods
@@ -436,7 +442,7 @@ def test_embedding_nets_integration_training_device(
                 if inference_method == SNPE_A
                 else dict(
                     mcmc_method="slice_np_vectorized",
-                    mcmc_parameters=dict(thin=10, num_chains=20, warmup_steps=10),
+                    mcmc_parameters=mcmc_params_fast,
                 )
             ),
         )
diff --git a/tests/linearGaussian_mdn_test.py b/tests/linearGaussian_mdn_test.py
--- a/tests/linearGaussian_mdn_test.py
+++ b/tests/linearGaussian_mdn_test.py
@@ -23,16 +23,10 @@
 from tests.test_utils import check_c2st
 
 
-def test_mdn_with_snpe():
-    mdn_inference_with_different_methods(SNPE)
-
-
-@pytest.mark.slow
-def test_mdn_with_snle():
-    mdn_inference_with_different_methods(SNLE)
-
-
-def mdn_inference_with_different_methods(method):
+@pytest.mark.parametrize(
+    "method", (SNPE, pytest.param(SNLE, marks=[pytest.mark.slow, pytest.mark.mcmc]))
+)
+def test_mdn_inference_with_different_methods(method, mcmc_params_accurate: dict):
     num_dim = 2
     x_o = torch.tensor([[1.0, 0.0]])
     num_samples = 500
@@ -68,9 +62,7 @@ def simulator(theta: Tensor) -> Tensor:
             theta_transform=theta_transform,
             proposal=prior,
             method="slice_np_vectorized",
-            num_chains=20,
-            warmup_steps=50,
-            thin=5,
+            **mcmc_params_accurate,
         )
 
     samples = posterior.sample((num_samples,), x=x_o)
diff --git a/tests/linearGaussian_snle_test.py b/tests/linearGaussian_snle_test.py
--- a/tests/linearGaussian_snle_test.py
+++ b/tests/linearGaussian_snle_test.py
@@ -32,18 +32,12 @@
 
 from .test_utils import check_c2st, get_prob_outside_uniform_prior
 
-# mcmc params for fast testing.
-mcmc_parameters = {
-    "method": "slice_np_vectorized",
-    "num_chains": 20,
-    "thin": 5,
-    "warmup_steps": 50,
-}
-
 
 @pytest.mark.parametrize("num_dim", (1,))  # dim 3 is tested below.
 @pytest.mark.parametrize("prior_str", ("uniform", "gaussian"))
-def test_api_snle_multiple_trials_and_rounds_map(num_dim: int, prior_str: str):
+def test_api_snle_multiple_trials_and_rounds_map(
+    num_dim: int, prior_str: str, mcmc_params_fast: dict
+):
     """Test SNLE API with 2 rounds, different priors num trials and MAP."""
     num_rounds = 2
     num_samples = 1
@@ -74,14 +68,16 @@ def test_api_snle_multiple_trials_and_rounds_map(num_dim: int, prior_str: str):
             x_o = zeros((num_trials, num_dim))
             posterior = inference.build_posterior(
                 mcmc_method="slice_np_vectorized",
-                mcmc_parameters=dict(num_chains=10, thin=10, warmup_steps=10),
+                mcmc_parameters=mcmc_params_fast,
             ).set_default_x(x_o)
             posterior.sample(sample_shape=(num_samples,))
         proposals.append(posterior)
         posterior.map(num_iter=1)
 
 
-def test_c2st_snl_on_linear_gaussian_different_dims(model_str="maf"):
+def test_c2st_snl_on_linear_gaussian_different_dims(
+    mcmc_params_accurate: dict, model_str="maf"
+):
     """Test SNLE on linear Gaussian task with different theta and x dims."""
 
     theta_dim = 3
@@ -131,7 +127,8 @@ def simulator(theta):
         proposal=prior,
         potential_fn=potential_fn,
         theta_transform=theta_transform,
-        **mcmc_parameters,
+        method="slice_np_vectorized",
+        **mcmc_params_accurate,
     )
     samples = posterior.sample((num_samples,))
 
@@ -144,7 +141,7 @@ def simulator(theta):
 @pytest.mark.parametrize("prior_str", ("uniform", "gaussian"))
 @pytest.mark.parametrize("model_str", ("maf", "zuko_maf"))
 def test_c2st_and_map_snl_on_linearGaussian_different(
-    num_dim: int, prior_str: str, model_str: str
+    num_dim: int, prior_str: str, model_str: str, mcmc_params_accurate: dict
 ):
     """Test SNL on linear Gaussian, comparing to ground truth posterior via c2st.
 
@@ -206,7 +203,8 @@ def simulator(theta):
             proposal=prior,
             potential_fn=potential_fn,
             theta_transform=theta_transform,
-            **mcmc_parameters,
+            method="slice_np_vectorized",
+            **mcmc_params_accurate,
         )
 
         samples = posterior.sample(sample_shape=(num_samples,))
@@ -273,7 +271,9 @@ def simulator(theta):
 
 @pytest.mark.slow
 @pytest.mark.parametrize("num_trials", (1, 3))
-def test_c2st_multi_round_snl_on_linearGaussian(num_trials: int):
+def test_c2st_multi_round_snl_on_linearGaussian(
+    num_trials: int, mcmc_params_accurate: dict
+):
     """Test SNL on linear Gaussian, comparing to ground truth posterior via c2st."""
 
     num_dim = 2
@@ -309,7 +309,8 @@ def simulator(theta):
         proposal=prior,
         potential_fn=potential_fn,
         theta_transform=theta_transform,
-        **mcmc_parameters,
+        method="slice_np_vectorized",
+        **mcmc_params_accurate,
     )
 
     theta, x = simulate_for_sbi(
@@ -326,7 +327,8 @@ def simulator(theta):
         proposal=prior,
         potential_fn=potential_fn,
         theta_transform=theta_transform,
-        **mcmc_parameters,
+        method="slice_np_vectorized",
+        **mcmc_params_accurate,
     )
 
     samples = posterior.sample(sample_shape=(num_samples,))
@@ -400,15 +402,15 @@ def simulator(theta):
 @pytest.mark.parametrize(
     "sampling_method, prior_str",
     (
-        ("slice_np", "gaussian"),
-        ("slice_np", "uniform"),
-        ("slice_np_vectorized", "gaussian"),
-        ("slice_np_vectorized", "uniform"),
-        ("slice", "gaussian"),
-        ("slice", "uniform"),
-        ("nuts", "gaussian"),
-        ("nuts", "uniform"),
-        ("hmc", "gaussian"),
+        pytest.param("slice_np", "gaussian", marks=pytest.mark.mcmc),
+        pytest.param("slice_np", "uniform", marks=pytest.mark.mcmc),
+        pytest.param("slice_np_vectorized", "gaussian", marks=pytest.mark.mcmc),
+        pytest.param("slice_np_vectorized", "uniform", marks=pytest.mark.mcmc),
+        pytest.param("slice", "gaussian", marks=pytest.mark.mcmc),
+        pytest.param("slice", "uniform", marks=pytest.mark.mcmc),
+        pytest.param("nuts", "gaussian", marks=pytest.mark.mcmc),
+        pytest.param("nuts", "uniform", marks=pytest.mark.mcmc),
+        pytest.param("hmc", "gaussian", marks=pytest.mark.mcmc),
         ("rejection", "uniform"),
         ("rejection", "gaussian"),
         ("rKL", "uniform"),
@@ -425,7 +427,7 @@ def simulator(theta):
 )
 @pytest.mark.parametrize("init_strategy", ("proposal", "resample", "sir"))
 def test_api_snl_sampling_methods(
-    sampling_method: str, prior_str: str, init_strategy: str
+    sampling_method: str, prior_str: str, init_strategy: str, mcmc_params_fast: dict
 ):
     """Runs SNL on linear Gaussian and tests sampling from posterior via mcmc.
 
@@ -440,8 +442,6 @@ def test_api_snl_sampling_methods(
     num_trials = 2
     num_simulations = 1000
     x_o = zeros((num_trials, num_dim))
-    # Test for multiple chains is cheap when vectorized.
-    num_chains = 10 if sampling_method == "slice_np_vectorized" else 1
     if sampling_method == "rejection":
         sample_with = "rejection"
     elif (
@@ -489,9 +489,8 @@ def test_api_snl_sampling_methods(
                 proposal=prior,
                 theta_transform=theta_transform,
                 method=sampling_method,
-                thin=5,
-                num_chains=num_chains,
                 init_strategy=init_strategy,
+                **mcmc_params_fast,
             )
         elif sample_with == "importance":
             posterior = ImportanceSamplingPosterior(
diff --git a/tests/linearGaussian_snpe_test.py b/tests/linearGaussian_snpe_test.py
--- a/tests/linearGaussian_snpe_test.py
+++ b/tests/linearGaussian_snpe_test.py
@@ -388,13 +388,15 @@ def simulator(theta):
 @pytest.mark.parametrize(
     "sample_with, mcmc_method, prior_str",
     (
-        ("mcmc", "slice_np", "gaussian"),
-        ("mcmc", "slice", "gaussian"),
-        ("mcmc", "slice_np_vectorized", "gaussian"),
+        pytest.param("mcmc", "slice_np", "gaussian", marks=pytest.mark.mcmc),
+        pytest.param("mcmc", "slice", "gaussian", marks=pytest.mark.mcmc),
+        pytest.param("mcmc", "slice_np_vectorized", "gaussian", marks=pytest.mark.mcmc),
         ("rejection", "rejection", "uniform"),
     ),
 )
-def test_api_snpe_c_posterior_correction(sample_with, mcmc_method, prior_str):
+def test_api_snpe_c_posterior_correction(
+    sample_with, mcmc_method, prior_str, mcmc_params_fast: dict
+):
     """Test that leakage correction applied to sampling works, with both MCMC and
     rejection.
 
@@ -430,9 +432,7 @@ def simulator(theta):
             theta_transform=theta_transform,
             proposal=prior,
             method=mcmc_method,
-            num_chains=10 if mcmc_method == "slice_np_vectorized" else 1,
-            warmup_steps=10,
-            thin=1,
+            **mcmc_params_fast,
         )
     elif sample_with == "rejection":
         posterior = RejectionPosterior(
@@ -491,7 +491,8 @@ def simulator(theta):
 
 
 @pytest.mark.slow
-def test_sample_conditional():
+@pytest.mark.mcmc
+def test_sample_conditional(mcmc_params_accurate: dict):
     """
     Test whether sampling from the conditional gives the same results as evaluating.
 
@@ -508,10 +509,6 @@ def test_sample_conditional():
     num_simulations = 6000
     num_conditional_samples = 500
 
-    mcmc_parameters = dict(
-        method="slice_np_vectorized", num_chains=20, warmup_steps=50, thin=5
-    )
-
     x_o = zeros(1, num_dim)
 
     likelihood_shift = -1.0 * ones(num_dim)
@@ -563,7 +560,8 @@ def simulator(theta):
         potential_fn=conditioned_potential_fn,
         theta_transform=restricted_tf,
         proposal=restricted_prior,
-        **mcmc_parameters,
+        method="slice_np_vectorized",
+        **mcmc_params_accurate,
     )
     mcmc_posterior.set_default_x(x_o)  # TODO: This test has a bug? Needed to add this
     cond_samples = mcmc_posterior.sample((num_conditional_samples,))
diff --git a/tests/linearGaussian_snre_test.py b/tests/linearGaussian_snre_test.py
--- a/tests/linearGaussian_snre_test.py
+++ b/tests/linearGaussian_snre_test.py
@@ -35,25 +35,19 @@
     get_prob_outside_uniform_prior,
 )
 
-# mcmc params for fast testing.
-mcmc_parameters = {
-    "method": "slice_np_vectorized",
-    "num_chains": 20,
-    "thin": 5,
-    "warmup_steps": 50,
-}
-
 
+@pytest.mark.mcmc
 @pytest.mark.parametrize("num_dim", (1,))  # dim 3 is tested below.
 @pytest.mark.parametrize("snre_method", (SNRE_B, SNRE_C))
 def test_api_snre_multiple_trials_and_rounds_map(
-    num_dim: int, snre_method: RatioEstimator
+    num_dim: int,
+    snre_method: RatioEstimator,
+    mcmc_params_fast: dict,
+    num_rounds: int = 2,
+    num_samples: int = 12,
+    num_simulations: int = 100,
 ):
     """Test SNRE API with 2 rounds, different priors num trials and MAP."""
-
-    num_rounds = 2
-    num_samples = 1
-    num_simulations = 100
     prior = MultivariateNormal(loc=zeros(num_dim), covariance_matrix=eye(num_dim))
 
     simulator = diagonal_linear_gaussian
@@ -74,15 +68,18 @@ def test_api_snre_multiple_trials_and_rounds_map(
             x_o = zeros((num_trials, num_dim))
             posterior = inference.build_posterior(
                 mcmc_method="slice_np_vectorized",
-                mcmc_parameters=dict(num_chains=10, thin=5, warmup_steps=10),
+                mcmc_parameters=mcmc_params_fast,
             ).set_default_x(x_o)
             posterior.sample(sample_shape=(num_samples,))
         proposals.append(posterior)
         posterior.map(num_iter=1)
 
 
+@pytest.mark.mcmc
 @pytest.mark.parametrize("snre_method", (SNRE_B, SNRE_C))
-def test_c2st_sre_on_linearGaussian(snre_method: RatioEstimator):
+def test_c2st_sre_on_linearGaussian(
+    snre_method: RatioEstimator, mcmc_params_accurate: dict
+):
     """Test whether SRE infers well a simple example with available ground truth.
 
     This example has different number of parameters theta than number of x. This test
@@ -134,7 +131,8 @@ def simulator(theta):
         potential_fn=potential_fn,
         theta_transform=theta_transform,
         proposal=prior,
-        **mcmc_parameters,
+        method="slice_np_vectorized",
+        **mcmc_params_accurate,
     )
     samples = posterior.sample((num_samples,))
 
@@ -142,12 +140,16 @@ def simulator(theta):
     check_c2st(samples, target_samples, alg=f"{snre_method.__name__}")
 
 
+@pytest.mark.mcmc
 @pytest.mark.slow
 @pytest.mark.parametrize("snre_method", (SNRE_A, SNRE_B, SNRE_C, BNRE))
 @pytest.mark.parametrize("prior_str", ("gaussian", "uniform"))
 @pytest.mark.parametrize("num_trials", (3,))  # num_trials=1 is tested above.
 def test_c2st_snre_variants_on_linearGaussian_with_multiple_trials(
-    snre_method: RatioEstimator, prior_str: str, num_trials: int
+    snre_method: RatioEstimator,
+    prior_str: str,
+    num_trials: int,
+    mcmc_params_accurate: dict,
 ):
     """Test C2ST and MAP accuracy of SNRE variants on linear gaussian.
 
@@ -158,7 +160,7 @@ def test_c2st_snre_variants_on_linearGaussian_with_multiple_trials(
     """
 
     num_dim = 2
-    num_simulations = 1500
+    num_simulations = 1750
     num_samples = 500
     x_o = zeros(num_trials, num_dim)
 
@@ -199,7 +201,8 @@ def simulator(theta):
         potential_fn=potential_fn,
         theta_transform=theta_transform,
         proposal=prior,
-        **mcmc_parameters,
+        method="slice_np_vectorized",
+        **mcmc_params_accurate,
     )
     samples = posterior.sample(sample_shape=(num_samples,))
 
@@ -319,15 +322,15 @@ def simulator(theta):
 @pytest.mark.parametrize(
     "sampling_method, prior_str",
     (
-        ("slice_np", "gaussian"),
-        ("slice_np", "uniform"),
-        ("slice_np_vectorized", "gaussian"),
-        ("slice_np_vectorized", "uniform"),
-        ("slice", "gaussian"),
-        ("slice", "uniform"),
-        ("nuts", "gaussian"),
-        ("nuts", "uniform"),
-        ("hmc", "gaussian"),
+        pytest.param("slice_np", "gaussian", marks=pytest.mark.mcmc),
+        pytest.param("slice_np", "uniform", marks=pytest.mark.mcmc),
+        pytest.param("slice_np_vectorized", "gaussian", marks=pytest.mark.mcmc),
+        pytest.param("slice_np_vectorized", "uniform", marks=pytest.mark.mcmc),
+        pytest.param("slice", "gaussian", marks=pytest.mark.mcmc),
+        pytest.param("slice", "uniform", marks=pytest.mark.mcmc),
+        pytest.param("nuts", "gaussian", marks=pytest.mark.mcmc),
+        pytest.param("nuts", "uniform", marks=pytest.mark.mcmc),
+        pytest.param("hmc", "gaussian", marks=pytest.mark.mcmc),
         ("rejection", "uniform"),
         ("rejection", "gaussian"),
         ("rKL", "uniform"),
@@ -342,7 +345,9 @@ def simulator(theta):
         ("importance", "gaussian"),
     ),
 )
-def test_api_sre_sampling_methods(sampling_method: str, prior_str: str):
+def test_api_sre_sampling_methods(
+    sampling_method: str, prior_str: str, mcmc_params_fast: dict
+):
     """Test leakage correction both for MCMC and rejection sampling.
 
     Args:
@@ -356,7 +361,7 @@ def test_api_sre_sampling_methods(sampling_method: str, prior_str: str):
     num_simulations = 100
     x_o = zeros((num_trials, num_dim))
     # Test for multiple chains is cheap when vectorized.
-    num_chains = 5 if sampling_method == "slice_np_vectorized" else 1
+
     if sampling_method == "rejection":
         sample_with = "rejection"
     elif (
@@ -393,14 +398,12 @@ def test_api_sre_sampling_methods(sampling_method: str, prior_str: str):
         or "nuts" in sampling_method
         or "hmc" in sampling_method
     ):
-        mcmc_parameters.update({"num_chains": num_chains})
-        mcmc_parameters.update({"method": sampling_method})
-
         posterior = MCMCPosterior(
             potential_fn,
             proposal=prior,
             theta_transform=theta_transform,
-            **mcmc_parameters,
+            method=sampling_method,
+            **mcmc_params_fast,
         )
     elif sample_with == "importance":
         posterior = ImportanceSamplingPosterior(
diff --git a/tests/mcmc_slice_pyro/test_slice.py b/tests/mcmc_slice_pyro/test_slice.py
--- a/tests/mcmc_slice_pyro/test_slice.py
+++ b/tests/mcmc_slice_pyro/test_slice.py
@@ -137,6 +137,7 @@ def jit_idfn(param):
     return "JIT={}".format(param)
 
 
+@pytest.mark.mcmc
 @pytest.mark.parametrize(
     T._fields,
     TEST_CASES,
@@ -181,9 +182,10 @@ def test_slice_conjugate_gaussian(
         assert_equal(rmse(latent_std, expected_std).item(), 0.0, prec=std_tol)
 
 
+@pytest.mark.mcmc
 @pytest.mark.parametrize("jit", [False, mark_jit(True)], ids=jit_idfn)
 @pytest.mark.parametrize("num_chains", [1, 2])
-def test_logistic_regression(jit, num_chains):
+def test_logistic_regression(jit, num_chains, mcmc_params_fast: dict):
     dim = 3
     data = torch.randn(2000, dim)
     true_coefs = torch.arange(1.0, dim + 1.0)
@@ -196,20 +198,16 @@ def model(data):
         return y
 
     slice_kernel = Slice(model, jit_compile=jit, ignore_jit_warnings=True)
-    mcmc = MCMC(
-        slice_kernel,
-        num_samples=500,
-        warmup_steps=100,
-        num_chains=num_chains,
-        mp_context="fork",
-        available_cpu=1,
-    )
+    mcmc_params_fast["num_chains"] = num_chains
+    mcmc_params_fast.pop("thin")  # thinning is not supported
+    mcmc = MCMC(slice_kernel, num_samples=500, available_cpu=1, **mcmc_params_fast)
     mcmc.run(data)
     samples = mcmc.get_samples()
     assert_equal(rmse(true_coefs, samples["beta"].mean(0)).item(), 0.0, prec=0.1)
 
 
-def test_beta_bernoulli():
+@pytest.mark.mcmc
+def test_beta_bernoulli(mcmc_params_fast: dict):
     def model(data):
         alpha = torch.tensor([1.1, 1.1])
         beta = torch.tensor([1.1, 1.1])
@@ -220,14 +218,17 @@ def model(data):
     true_probs = torch.tensor([0.9, 0.1])
     data = dist.Bernoulli(true_probs).sample(sample_shape=(torch.Size((1200,))))
     slice_kernel = Slice(model)
-    mcmc = MCMC(slice_kernel, num_samples=400, warmup_steps=200)
+    mcmc = MCMC(
+        slice_kernel, num_samples=400, warmup_steps=mcmc_params_fast["warmup_steps"]
+    )
     mcmc.run(data)
     samples = mcmc.get_samples()
     assert_equal(samples["p_latent"].mean(0), true_probs, prec=0.02)
 
 
+@pytest.mark.mcmc
 @pytest.mark.parametrize("jit", [False, mark_jit(True)], ids=jit_idfn)
-def test_gamma_normal(jit):
+def test_gamma_normal(jit, mcmc_params_fast: dict):
     def model(data):
         rate = torch.tensor([1.0, 1.0])
         concentration = torch.tensor([1.0, 1.0])
@@ -238,14 +239,17 @@ def model(data):
     true_std = torch.tensor([0.5, 2])
     data = dist.Normal(3, true_std).sample(sample_shape=(torch.Size((2000,))))
     slice_kernel = Slice(model, jit_compile=jit, ignore_jit_warnings=True)
-    mcmc = MCMC(slice_kernel, num_samples=200, warmup_steps=100)
+    mcmc = MCMC(
+        slice_kernel, num_samples=200, warmup_steps=mcmc_params_fast["warmup_steps"]
+    )
     mcmc.run(data)
     samples = mcmc.get_samples()
     assert_equal(samples["p_latent"].mean(0), true_std, prec=0.05)
 
 
+@pytest.mark.mcmc
 @pytest.mark.parametrize("jit", [False, mark_jit(True)], ids=jit_idfn)
-def test_dirichlet_categorical(jit):
+def test_dirichlet_categorical(jit, mcmc_params_fast: dict):
     def model(data):
         concentration = torch.tensor([1.0, 1.0, 1.0])
         p_latent = pyro.sample("p_latent", dist.Dirichlet(concentration))
@@ -255,16 +259,19 @@ def model(data):
     true_probs = torch.tensor([0.1, 0.6, 0.3])
     data = dist.Categorical(true_probs).sample(sample_shape=(torch.Size((2000,))))
     slice_kernel = Slice(model, jit_compile=jit, ignore_jit_warnings=True)
-    mcmc = MCMC(slice_kernel, num_samples=200, warmup_steps=100)
+    mcmc = MCMC(
+        slice_kernel, num_samples=200, warmup_steps=mcmc_params_fast["warmup_steps"]
+    )
     mcmc.run(data)
     samples = mcmc.get_samples()
     posterior = samples["p_latent"]
     assert_equal(posterior.mean(0), true_probs, prec=0.02)
 
 
+@pytest.mark.mcmc
 @pytest.mark.parametrize("jit", [False, mark_jit(True)], ids=jit_idfn)
 @pytest.mark.skip(reason="Slice sampling not implemented for multiple sites yet.")
-def test_gamma_beta(jit):
+def test_gamma_beta(jit, mcmc_params_fast: dict):
     def model(data):
         alpha_prior = pyro.sample("alpha", dist.Gamma(concentration=1.0, rate=1.0))
         beta_prior = pyro.sample("beta", dist.Gamma(concentration=1.0, rate=1.0))
@@ -280,16 +287,19 @@ def model(data):
         torch.Size((5000,))
     )
     slice_kernel = Slice(model, jit_compile=jit, ignore_jit_warnings=True)
-    mcmc = MCMC(slice_kernel, num_samples=500, warmup_steps=200)
+    mcmc = MCMC(
+        slice_kernel, num_samples=500, warmup_steps=mcmc_params_fast["warmup_steps"]
+    )
     mcmc.run(data)
     samples = mcmc.get_samples()
     assert_equal(samples["alpha"].mean(0), true_alpha, prec=0.08)
     assert_equal(samples["beta"].mean(0), true_beta, prec=0.05)
 
 
+@pytest.mark.mcmc
 @pytest.mark.parametrize("jit", [False, mark_jit(True)], ids=jit_idfn)
 @pytest.mark.skip(reason="Slice sampling not implemented for multiple sites yet.")
-def test_gaussian_mixture_model(jit):
+def test_gaussian_mixture_model(jit, mcmc_params_fast: dict):
     K, N = 3, 1000
 
     def gmm(data):
@@ -312,7 +322,9 @@ def gmm(data):
     slice_kernel = Slice(
         gmm, max_plate_nesting=1, jit_compile=jit, ignore_jit_warnings=True
     )
-    mcmc = MCMC(slice_kernel, num_samples=300, warmup_steps=100)
+    mcmc = MCMC(
+        slice_kernel, num_samples=300, warmup_steps=mcmc_params_fast["warmup_steps"]
+    )
     mcmc.run(data)
     samples = mcmc.get_samples()
     assert_equal(samples["phi"].mean(0).sort()[0], true_mix_proportions, prec=0.05)
@@ -321,9 +333,10 @@ def gmm(data):
     )
 
 
+@pytest.mark.mcmc
 @pytest.mark.parametrize("jit", [False, mark_jit(True)], ids=jit_idfn)
 @pytest.mark.skip(reason="Slice sampling not implemented for multiple sites yet.")
-def test_bernoulli_latent_model(jit):
+def test_bernoulli_latent_model(jit, mcmc_params_fast: dict):
     @poutine.broadcast
     def model(data):
         y_prob = pyro.sample("y_prob", dist.Beta(1.0, 1.0))
@@ -340,15 +353,21 @@ def model(data):
     slice_kernel = Slice(
         model, max_plate_nesting=1, jit_compile=jit, ignore_jit_warnings=True
     )
-    mcmc = MCMC(slice_kernel, num_samples=600, warmup_steps=200)
+    mcmc = MCMC(
+        slice_kernel,
+        num_samples=600,
+        warmup_steps=mcmc_params_fast["warmup_steps"],
+        num_chains=1,
+    )
     mcmc.run(data)
     samples = mcmc.get_samples()
     assert_equal(samples["y_prob"].mean(0), y_prob, prec=0.05)
 
 
+@pytest.mark.mcmc
 @pytest.mark.parametrize("num_steps", [2, 3, 30])
 @pytest.mark.skip(reason="Slice sampling not implemented for multiple sites yet.")
-def test_gaussian_hmm(num_steps):
+def test_gaussian_hmm(num_steps, mcmc_params_fast: dict):
     dim = 4
 
     def model(data):
@@ -406,13 +425,16 @@ def _generate_data():
     )
     if num_steps == 30:
         slice_kernel.initial_trace = _get_initial_trace()
-    mcmc = MCMC(slice_kernel, num_samples=5, warmup_steps=5)
+    mcmc = MCMC(
+        slice_kernel, num_samples=5, warmup_steps=mcmc_params_fast["warmup_steps"]
+    )
     mcmc.run(data)
 
 
+@pytest.mark.mcmc
 @pytest.mark.parametrize("hyperpriors", [False, True])
 @pytest.mark.skip(reason="Slice sampling not implemented for multiple sites yet.")
-def test_beta_binomial(hyperpriors):
+def test_beta_binomial(hyperpriors, mcmc_params_fast: dict):
     def model(data):
         with pyro.plate("plate_0", data.shape[-1]):
             alpha = (
@@ -444,16 +466,21 @@ def model(data):
     hmc_kernel = Slice(
         collapse_conjugate(model), jit_compile=True, ignore_jit_warnings=True
     )
-    mcmc = MCMC(hmc_kernel, num_samples=num_samples, warmup_steps=50)
+    mcmc = MCMC(
+        hmc_kernel,
+        num_samples=num_samples,
+        warmup_steps=mcmc_params_fast["warmup_steps"],
+    )
     mcmc.run(data)
     samples = mcmc.get_samples()
     posterior = posterior_replay(model, samples, data, num_samples=num_samples)
     assert_equal(posterior["probs"].mean(0), true_probs, prec=0.05)
 
 
+@pytest.mark.mcmc
 @pytest.mark.parametrize("hyperpriors", [False, True])
 @pytest.mark.skip(reason="Slice sampling not implemented for multiple sites yet.")
-def test_gamma_poisson(hyperpriors):
+def test_gamma_poisson(hyperpriors, mcmc_params_fast: dict):
     def model(data):
         with pyro.plate("latent_dim", data.shape[1]):
             alpha = (
@@ -477,7 +504,11 @@ def model(data):
     slice_kernel = Slice(
         collapse_conjugate(model), jit_compile=True, ignore_jit_warnings=True
     )
-    mcmc = MCMC(slice_kernel, num_samples=num_samples, warmup_steps=50)
+    mcmc = MCMC(
+        slice_kernel,
+        num_samples=num_samples,
+        warmup_steps=mcmc_params_fast["warmup_steps"],
+    )
     mcmc.run(data)
     samples = mcmc.get_samples()
     posterior = posterior_replay(model, samples, data, num_samples=num_samples)
diff --git a/tests/mcmc_test.py b/tests/mcmc_test.py
--- a/tests/mcmc_test.py
+++ b/tests/mcmc_test.py
@@ -32,6 +32,7 @@
 from tests.test_utils import check_c2st
 
 
+@pytest.mark.mcmc
 @pytest.mark.parametrize("num_dim", (1, 2))
 def test_c2st_slice_np_on_Gaussian(num_dim: int):
     """Test MCMC on Gaussian, comparing to ground truth target via c2st.
@@ -72,11 +73,12 @@ def lp_f(x):
     check_c2st(samples, target_samples, alg="slice_np")
 
 
+@pytest.mark.mcmc
 @pytest.mark.parametrize("num_dim", (1, 2))
 @pytest.mark.parametrize("slice_sampler", (SliceSamplerVectorized, SliceSamplerSerial))
 @pytest.mark.parametrize("num_workers", (1, 2))
 def test_c2st_slice_np_vectorized_parallelized_on_Gaussian(
-    num_dim: int, slice_sampler, num_workers: int
+    num_dim: int, slice_sampler, num_workers: int, mcmc_params_accurate: dict
 ):
     """Test MCMC on Gaussian, comparing to ground truth target via c2st.
 
@@ -85,9 +87,13 @@ def test_c2st_slice_np_vectorized_parallelized_on_Gaussian(
 
     """
     num_samples = 500
-    warmup = 50
-    num_chains = 10 if slice_sampler is SliceSamplerVectorized else 1
-    thin = 2
+    warmup = mcmc_params_accurate["warmup_steps"]
+    num_chains = (
+        mcmc_params_accurate["num_chains"]
+        if slice_sampler is SliceSamplerVectorized
+        else 1
+    )
+    thin = mcmc_params_accurate["thin"]
 
     likelihood_shift = -1.0 * ones(num_dim)
     likelihood_cov = 0.3 * eye(num_dim)
@@ -129,6 +135,7 @@ def lp_f(x):
     check_c2st(samples, target_samples, alg=alg)
 
 
+@pytest.mark.mcmc
 @pytest.mark.parametrize(
     "method",
     (
@@ -139,7 +146,7 @@ def lp_f(x):
         "slice_np_vectorized",
     ),
 )
-def test_getting_inference_diagnostics(method):
+def test_getting_inference_diagnostics(method, mcmc_params_fast: dict):
     num_simulations = 100
     num_samples = 10
     num_dim = 2
@@ -170,9 +177,7 @@ def test_getting_inference_diagnostics(method):
         proposal=prior,
         potential_fn=potential_fn,
         theta_transform=theta_transform,
-        thin=2,
-        warmup_steps=10,
-        num_chains=1,
+        **mcmc_params_fast,
     )
     posterior.sample(
         sample_shape=(num_samples,),
diff --git a/tests/mnle_test.py b/tests/mnle_test.py
--- a/tests/mnle_test.py
+++ b/tests/mnle_test.py
@@ -36,25 +36,20 @@ def mixed_simulator(theta, stimulus_condition=2.0):
     return torch.cat((rts, choices), dim=1)
 
 
-# MCMC kwargs for faster testing
-mcmc_kwargs = dict(
-    num_chains=20,
-    warmup_steps=50,
-    method="slice_np_vectorized",
-    init_strategy="proposal",
-    thin=5,
-)
-
-
+@pytest.mark.mcmc
 @pytest.mark.gpu
 @pytest.mark.parametrize("device", ("cpu", "gpu"))
-def test_mnle_on_device(device):
+def test_mnle_on_device(
+    device,
+    mcmc_params_fast: dict,
+    num_simulations: int = 100,
+    mcmc_method: str = "slice",
+):
     """Test MNLE API on device."""
 
     device = process_device(device)
+
     # Generate mixed data.
-    num_simulations = 100
-    mcmc_method = "slice"
     theta = torch.rand(num_simulations, 2)
     x = torch.cat(
         (
@@ -76,13 +71,14 @@ def test_mnle_on_device(device):
         x=x[0],
         show_progress_bars=False,
         mcmc_method=mcmc_method,
-        thin=1,
-        warmup_steps=1,
+        **mcmc_params_fast,
     )
 
 
-@pytest.mark.parametrize("sampler", ("mcmc", "rejection", "vi"))
-def test_mnle_api(sampler):
+@pytest.mark.parametrize(
+    "sampler", (pytest.param("mcmc", marks=pytest.mark.mcmc), "rejection", "vi")
+)
+def test_mnle_api(sampler, mcmc_params_fast: dict):
     """Test MNLE API."""
     # Generate mixed data.
     num_simulations = 100
@@ -113,18 +109,20 @@ def test_mnle_api(sampler):
     else:
         posterior.sample(
             (1,),
-            num_chains=2,
-            warmup_steps=1,
-            method="slice_np_vectorized",
             init_strategy="proposal",
-            thin=1,
+            method="slice_np_vectorized",
+            **mcmc_params_fast,
         )
 
 
 @pytest.mark.slow
-@pytest.mark.parametrize("sampler", ("mcmc", "rejection", "vi"))
+@pytest.mark.parametrize(
+    "sampler", (pytest.param("mcmc", marks=pytest.mark.mcmc), "rejection", "vi")
+)
 @pytest.mark.parametrize("num_trials", [5, 10])
-def test_mnle_accuracy_with_different_samplers_and_trials(sampler, num_trials: int):
+def test_mnle_accuracy_with_different_samplers_and_trials(
+    sampler, num_trials: int, mcmc_params_accurate: dict
+):
     """Test MNLE c2st accuracy for different samplers and number of trials."""
 
     num_simulations = 2000
@@ -149,6 +147,10 @@ def test_mnle_accuracy_with_different_samplers_and_trials(sampler, num_trials: i
     theta_o = prior.sample((1,))
     x_o = mixed_simulator(theta_o.repeat(num_trials, 1))
 
+    mcmc_kwargs = dict(
+        method="slice_np_vectorized", init_strategy="proposal", **mcmc_params_accurate
+    )
+
     # True posterior samples
     transform = mcmc_transform(prior)
     true_posterior_samples = MCMCPosterior(
@@ -224,7 +226,8 @@ def iid_likelihood(self, theta: torch.Tensor) -> torch.Tensor:
 
 
 @pytest.mark.slow
-def test_mnle_with_experimental_conditions():
+@pytest.mark.mcmc
+def test_mnle_with_experimental_conditions(mcmc_params_accurate: dict):
     """Test MNLE c2st accuracy when conditioned on a subset of the parameters, e.g.,
     experimental conditions.
 
@@ -257,9 +260,13 @@ def sim_wrapper(theta):
     theta_o[0, 2] = 2.0  # set condition to 2 as in original simulator.
     x_o = sim_wrapper(theta_o.repeat(num_trials, 1))
 
+    mcmc_kwargs = dict(
+        method="slice_np_vectorized", init_strategy="proposal", **mcmc_params_accurate
+    )
+
     # MNLE
     trainer = MNLE(proposal)
-    estimator = trainer.append_simulations(theta, x).train(training_batch_size=100)
+    estimator = trainer.append_simulations(theta, x).train(training_batch_size=1000)
 
     potential_fn = MixedLikelihoodBasedPotential(estimator, proposal, x_o)
 
diff --git a/tests/posterior_sampler_test.py b/tests/posterior_sampler_test.py
--- a/tests/posterior_sampler_test.py
+++ b/tests/posterior_sampler_test.py
@@ -19,17 +19,14 @@
 from sbi.simulators.linear_gaussian import diagonal_linear_gaussian
 
 
+@pytest.mark.mcmc
 @pytest.mark.parametrize(
     "sampling_method",
-    (
-        "slice_np",
-        "slice_np_vectorized",
-        "slice",
-        "nuts",
-        "hmc",
-    ),
+    ("slice_np", "slice_np_vectorized", "slice", "nuts", "hmc"),
 )
-def test_api_posterior_sampler_set(sampling_method: str, set_seed):
+def test_api_posterior_sampler_set(
+    sampling_method: str, set_seed, mcmc_params_fast: dict
+):
     """Runs SNL and checks that posterior_sampler is correctly set.
 
     Args:
@@ -43,7 +40,6 @@ def test_api_posterior_sampler_set(sampling_method: str, set_seed):
     num_simulations = 10
     x_o = zeros((num_trials, num_dim))
     # Test for multiple chains is cheap when vectorized.
-    num_chains = 3 if sampling_method in "slice_np_vectorized" else 1
 
     prior = MultivariateNormal(loc=zeros(num_dim), covariance_matrix=eye(num_dim))
     simulator = diagonal_linear_gaussian
@@ -63,13 +59,11 @@ def test_api_posterior_sampler_set(sampling_method: str, set_seed):
 
     assert posterior.posterior_sampler is None
     posterior.sample(
-        sample_shape=(num_samples, num_chains),
+        sample_shape=(num_samples, mcmc_params_fast["num_chains"]),
         x=x_o,
         mcmc_parameters={
-            "thin": 2,
-            "num_chains": num_chains,
             "init_strategy": "prior",
-            "warmup_steps": 10,
+            **mcmc_params_fast,
         },
     )
 
diff --git a/tests/potential_test.py b/tests/potential_test.py
--- a/tests/potential_test.py
+++ b/tests/potential_test.py
@@ -18,9 +18,14 @@
 
 @pytest.mark.parametrize(
     "sampling_method",
-    [ImportanceSamplingPosterior, MCMCPosterior, RejectionPosterior, VIPosterior],
+    [
+        ImportanceSamplingPosterior,
+        pytest.param(MCMCPosterior, marks=pytest.mark.mcmc),
+        RejectionPosterior,
+        VIPosterior,
+    ],
 )
-def test_callable_potential(sampling_method):
+def test_callable_potential(sampling_method, mcmc_params_accurate: dict):
     """Test whether callable potentials can be used to sample from a Gaussian."""
     dim = 2
     mean = 2.5
@@ -41,7 +46,7 @@ def potential(theta, x_o):
     elif sampling_method == MCMCPosterior:
         approx_density = sampling_method(potential_fn=potential, proposal=proposal)
         approx_samples = approx_density.sample(
-            (1024,), x=x_o, num_chains=100, method="slice_np_vectorized"
+            (1024,), x=x_o, method="slice_np_vectorized", **mcmc_params_accurate
         )
     elif sampling_method == VIPosterior:
         approx_density = sampling_method(
diff --git a/tests/save_and_load_test.py b/tests/save_and_load_test.py
--- a/tests/save_and_load_test.py
+++ b/tests/save_and_load_test.py
@@ -11,8 +11,8 @@
     "inference_method, sampling_method",
     (
         (SNPE, "direct"),
-        (SNLE, "mcmc"),
-        (SNRE, "mcmc"),
+        pytest.param(SNLE, "mcmc", marks=pytest.mark.mcmc),
+        pytest.param(SNRE, "mcmc", marks=pytest.mark.mcmc),
         pytest.param(SNRE, "vi", marks=pytest.mark.xfail),  # bug: see #684
         (SNRE, "rejection"),
     ),
diff --git a/tests/sbc_test.py b/tests/sbc_test.py
--- a/tests/sbc_test.py
+++ b/tests/sbc_test.py
@@ -18,9 +18,16 @@
 @pytest.mark.parametrize("reduce_fn_str", ("marginals", "posterior_log_prob"))
 @pytest.mark.parametrize("prior", ("boxuniform", "independent"))
 @pytest.mark.parametrize(
-    "method, sampler", ((SNPE, None), (SNLE, "mcmc"), (SNLE, "vi"))
+    "method, sampler",
+    (
+        (SNPE, None),
+        pytest.param(SNLE, "mcmc", marks=pytest.mark.mcmc),
+        pytest.param(SNLE, "vi", marks=pytest.mark.mcmc),
+    ),
 )
-def test_running_sbc(method, prior, reduce_fn_str, sampler, model="mdn"):
+def test_running_sbc(
+    method, prior, reduce_fn_str, sampler, mcmc_params_accurate: dict, model="mdn"
+):
     """Tests running inference and then SBC and obtaining nltp."""
 
     num_dim = 2
@@ -52,7 +59,7 @@ def simulator(theta):
         posterior_kwargs = {
             "sample_with": "mcmc" if sampler == "mcmc" else "vi",
             "mcmc_method": "slice_np_vectorized",
-            "mcmc_parameters": {"num_chains": 10, "thin": 5, "warmup_steps": 10},
+            "mcmc_parameters": mcmc_params_accurate,
         }
     else:
         posterior_kwargs = {}