Skip to content

Quick Example

An end-to-end federated run on the Antibodies benchmark.

0. Prerequisites

uv sync
cli data download --type maxfuse
cli preprocess data cite_seq_and_pbmc --out ./data/preprocessed
cli preprocess labels cite_seq_and_pbmc

1. Pick a configuration

Default configurations ship with the package, one per run type and dataset:

src/fed_maxfuse/models/federated/default_federated_cite_seq_pbmc_params.json
src/fed_maxfuse/models/federated/default_federated_tonsils_params.json
src/fed_maxfuse/models/regular/default_regular_cite_seq_pbmc_params.json
src/fed_maxfuse/models/regular/default_regular_tonsils_params.json
src/fed_maxfuse/models/original/default_original_*_params.json

Copy one and edit it rather than modifying the defaults in place.

cp src/fed_maxfuse/models/federated/default_federated_cite_seq_pbmc_params.json my_run.json

2. Understand the configuration

The structure mirrors MaxFuse's dual-modality design: global settings, then separate blocks for the meta and non-meta modalities.

{
  "dataset_id": "cite_seq_and_pbmc",
  "training": {
    "global_parameters": {
      "svd": { "is_randomized": false, "runs": 1 },
      "graph_construction": {
        "leiden_algorithm": { "resolution": 2.0, "resolution_tol": 0.1, "runs": 1 },
        "randomness_seeds": { "leiden_seed": null, "nn_graph_seed": null },
        "fuzzy_smoothing": "centroid_shrinkage"
      },
      "refinement_loop": {
        "cca": {
          "randomness": 0.0,
          "components": 20,
          "max_loop_iterations": 2000,
          "bad_filter_wt": 0.0
        },
        "loop_iterations": 3
      },
      "filtering": { "pivot_wt": 0.3, "propagation_wt": 0.0 }
    },
    "meta_data_parameters": {
      "graph_construction": { "nearest_neighbors": 15, "svd_components": 30 },
      "initial_correlation": { "svd_components": 25, "shrink_wt": 0.7 },
      "refinement_loop": { "svd_components": 30, "smoothing_weight": 0.7 },
      "propagation": { "smoothing_wt": 0.7, "svd_components": 30 }
    },
    "non_meta_data_parameters": { "...": "same structure" }
  }
}

Every symbol from the papers maps to a key here:

Paper symbol Config key
\(T\) (refinement iterations) refinement_loop.loop_iterations
\(C\) (CCA components) refinement_loop.cca.components
\(K\) (SVPM iterations) refinement_loop.cca.max_loop_iterations
\(w\) (CCA noise interpolation) refinement_loop.cca.randomness
\(\alpha\) (pivot filter) filtering.pivot_wt
\(\beta\) (propagation filter) filtering.propagation_wt
\(\omega\) (fuzzy smoothing) *.shrink_wt / *.smoothing_weight

3. Run

cli run train federated my_run.json \
    --id my-first-run \
    --out ./out \
    --preprocessed-dir ./data/preprocessed \
    --evaluate \
    --verbose

Four run types are available:

Run type Meaning
original Upstream MaxFuse reference implementation
regular This project's centralized re-implementation
distributed Distributed (non-privacy-preserving) variant
federated The federated algorithm

The --evaluate flag runs evaluation immediately after training. For large datasets, prefer running it separately; see the memory note in Installation.

4. Inspect the output

out/
└── federated_cite_seq_pbmc_params_{ID}/
    β”œβ”€β”€ meta_embedding.npy
    β”œβ”€β”€ non_meta_embedding.npy
    β”œβ”€β”€ matching.csv
    β”œβ”€β”€ supervised_evaluation_metrics.json
    β”œβ”€β”€ unsupervised_evaluation_metrics.json
    └── local_evaluation_metrics.json
cli analysis matching ./out/federated_cite_seq_pbmc_params_my-first-run --summary
cli analysis embeddings ./out/federated_cite_seq_pbmc_params_my-first-run --summary
cli run evaluation cite_seq_and_pbmc ./out/federated_cite_seq_pbmc_params_my-first-run \
    --preprocessed-dir ./data/preprocessed \
    --algorithm-type federated \
    --verbose

cli run mrre cite_seq_and_pbmc ./out/federated_cite_seq_pbmc_params_my-first-run \
    --preprocessed-dir ./data/preprocessed \
    --algorithm-type federated

Running a parameter sweep

MaxFuse is stochastic: Leiden clustering, k-NN construction, and the CCA noise initialisation all vary between runs. Single runs are therefore not informative. Generate a sweep:

# How many configurations will this produce?
cli generate count master_config.json --reps 25

# Generate them
cli generate new master_config.json ./configs --reps 25

# Split into batches for cluster submission
cli generate batch ./configs ./batches 50

The master configuration holds lists of values; the generator expands the combinations. This is what produced the thesis's 2,600 runs.

One knob at a time

Vary exactly one parameter and freeze the rest. That discipline is what makes a Mann–Whitney U comparison meaningful and the conclusion attributable; see Evaluation Framework.

Set seeds if you need reproducibility

leiden_seed and nn_graph_seed default to null. Leiden labels are the smoothing targets, so clustering variation propagates into every distance computation. Leave them unset when you are measuring stochasticity; set them when you need a run to be repeatable.