Complexa Sweep
NVIDIAOfficialCreated by Ohad MosafiDistributed by NVIDIA
- Skill
- Workflow
- Science and research
- Apache-2.0
- Medium risk
- Has scripts
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The complexa-sweep skill provides a structured runbook for executing systematic parameter sweeps over Proteina-Complexa design pipelines. It automates the generation of multiple inference configurations based on a sweeper YAML, manages the execution loop across these configurations, and aggregates results into a ranked summary. This process enables users to perform ablations, tuning, and Pareto searches over quality and computational cost metrics, ensuring consistent evaluation across diverse parameter sets.
What it does
- Generates multiple inference configurations from a cartesian-product sweeper YAML.
- Executes the design pipeline across a generated grid of parameter combinations.
- Aggregates per-config success metrics into a ranked summary CSV.
- Identifies the best-performing configuration and Pareto frontiers.
- Provides a manifest for result tracking and experiment reproducibility.
- Includes pre-flight checks to estimate GPU budget and hardware readiness.
When to use it
- When performing hyperparameter tuning or ablations on design pipelines.
- When comparing multiple search algorithms or model configurations.
- When conducting Pareto searches to balance design quality against wall-clock time.
- When you need to rank configurations based on success rates and diversity metrics.
Advantages
- Systematic exploration of parameter space via cartesian-product enumeration.
- Automated aggregation of results simplifies complex multi-run analysis.
- Supports multi-GPU sharding for efficient execution of large sweeps.
- Provides clear visibility into cost and resource requirements before execution.
Usage examples
- “Run a sweep over beam_width and nsteps for the 22_DerF21 task.”
- The agent will generate the necessary inference configs using the specified sweeper YAML, execute the design pipeline for each combination, and produce a ranked sweep_summary.csv.
- “Estimate the GPU cost for a 4-axis sweep with 4 values each.”
- The agent will calculate the total number of configurations and estimate the total GPU-hours based on the per-run baseline, prompting for confirmation before proceeding.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/nvidia/complexa-sweep/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip complexa-sweep.zip -d .agents/skills
Documentation by Ohad Mosafi
complexa-sweep
Run cartesian-product parameter sweeps over Proteina-Complexa design pipelines. Pick or author a sweeper YAML in configs/sweeps/, expand it to N inference configs with script_utils/generate_inference_configs.py, loop complexa design over those configs, then aggregate per-config success metrics into a ranked summary CSV plus a manifest.
Important: The
complexa designCLI does NOT accept--sweeperdirectly. Sweeps are driven byscript_utils/generate_inference_configs.py, which writes oneconfigs/inference_configs/inf_{idx}_{run_name}.yamlper sweep combination. You then loopcomplexa designover those generated configs.
Instructions
Sweeper authoring, Cartesian enumeration, cost estimates, and analysis of supplied CSVs need only the relevant configs and data. Complete those artifacts without setting up inference. Read the relevant axis section in sweep_axes.md, then check the matching keys in the selected source config for current defaults. Summary CSVs with supplied counts and objective columns do not require the full inference or metric guides. For a partial snapshot, enumerate combinations locally and provide the future generator command; running that command requires the full project and its dependencies.
For a requested launch, check readiness and the budget below. A single existing job or a SLURM template does not require a parameter sweep.
Step 1: Pre-flight
Before GPU execution, or when the request conditions its workflow on hardware,
set SKILL_DIR to the directory containing this manifest and run preflight once.
Use a separate shell assignment; an inline environment assignment cannot set
$SKILL_DIR's expansion in the same command.
Reuse an existing probe from the same request if the environment is unchanged:
bash "$SKILL_DIR"/scripts/preflight.shRead ./complexa_setup/preflight.json. A sweep multiplies GPU time by the number
of configs and targets. Compute the budget before launch and obtain confirmation
if the user has not already authorized that scope and cost:
"This sweep produces N configs × ~M minutes per config ≈ TOTAL GPU-hours. OK to proceed? (y / reduce / cancel)"
If gpu.available=false, stop before GPU execution. Sweeper authoring,
Cartesian-product enumeration, cost estimates, and analysis of supplied CSVs
can run on CPU. For those requests, finish the requested artifacts and record
the launch prerequisites. Label synthetic input data as synthetic and keep
estimated GPU time separate from measured runtime.
For a hardware-conditional request, verify the allocated hardware before
selecting the CPU fallback. Missing weights, dependencies, or sufficient VRAM
for an allocated GPU are launch blockers, not evidence of a CPU-only environment.
Report probe or execution failures without reclassifying the selected branch.
The shared preflight's gpu.available=false also covers failed or missing
nvidia-smi; check device/allocation evidence before treating it as GPU absence.
In containers, /proc/driver/nvidia/gpus and loaded kernel modules may describe
the host, not this task's allocation. Check container device exposure and any
available scheduler allocation information together. A CPU allocation can share
a GPU host; an allocated GPU with inaccessible devices is blocked. If allocation
remains unclear, report it as undetermined.
Step 2: Pick the pipeline + target
Use the user's supplied pipeline, targets, and run name. Protein, ligand, and AME
runs use search_binder_local_pipeline, search_ligand_binder_local_pipeline,
and search_ame_local_pipeline, respectively. Ask only for missing values:
pipeline_config_name— e.g.search_binder_local_pipeline(default),search_ligand_binder_local_pipeline,search_ame_local_pipeline.task_name— e.g.02_PDL1,22_DerF21,39_7V11_LIGAND. Passed as--override generation.task_name=<task>.run_name— short tag for output dir naming.
Examples
Step 3: Pick or author the sweeper YAML
Sweeper YAMLs live in configs/sweeps/. Each key is a dot-notation Hydra path; each value is a list. The cartesian product becomes N configs.
Canned sweepers
| File | Axis | Values | Configs |
|---|---|---|---|
configs/sweeps/beam_width.yaml | generation.search.beam_search.beam_width | 1, 2, 4, 8 | 4 |
configs/sweeps/bb_ca_temperature.yaml | generation.model.bb_ca.simulation_step_params.sc_scale_noise | 0.1, 0.4 | 2 |
configs/sweeps/search_replicas.yaml | generation.search.best_of_n.replicas | 1, 4, 16, 64 | 4 |
configs/sweeps/example.yaml | beam_width × nsteps | (2,4) × (200,400) | 4 |
Use a matching sweeper, then check that its axes affect the selected algorithm.
The binder config defaults to best-of-n: a beam-width sweep must also pin
generation.search.algorithm: [beam-search]. A replicas sweep pins
generation.search.algorithm: [best-of-n]. For AME, reward-guided search also
requires a configured reward model; its default is null.
Authoring a new sweeper
Minimal multi-axis example (saved to configs/sweeps/my_sweep.yaml):
# 3 beam widths × 2 nsteps = 6 configs
generation.search.algorithm: [beam-search]
generation.search.beam_search.beam_width:
- 2
- 4
- 8
generation.args.nsteps:
- 200
- 400Rules (from script_utils/generate_inference_configs.py:load_sweeper_file):
Top-level mapping only. Keys are dot-notation Hydra paths.
Keep budgets, launch status, and other planning metadata in the launch plan, outside the sweeper. Every top-level entry becomes an override axis; a separate
targetslist would multiply the grid again.Values must be lists. A scalar is auto-wrapped into a single-element list (which pins a value without adding a dimension).
For a list-valued parameter, nest each candidate list:
metric.sequence_types: [[self, mpnn]]pins one list. The flat form sweeps two strings;--overrideparses scalars only.Cartesian product: total configs = product of list lengths. Multiply by the number of targets unless target names are already one of the axes; do not count them twice.
If a key appears in both the sweeper file and an
--override, the override wins and that axis collapses.Reject empty axes before launch: an axis of
[]produces zero configurations.
See references/sweep_axes.md for the full catalogue of swept keys (typical ranges, cost multipliers, what improves/regresses).
Dry-run preview before generating
With the full project available, confirm the config count first:
python script_utils/generate_inference_configs.py \
--config_name search_binder_local_pipeline \
--sweeper configs/sweeps/my_sweep.yaml \
--override generation.task_name=22_DerF21 \
--run_name my_sweep \
--dryrunThe output lists every axis + value list and prints DRY RUN — would generate N config pair(s).
This previews enumeration only; it returns before Hydra composition and does
not validate the pipeline, parameter types, or launch prerequisites.
When the full project is available, inspect the materialized inference configs before launching. Check the resolved target, selected search algorithm, and requested parameter values across the generated grid. The generator permits unknown keys during merging, so a successful write alone does not establish that a misspelled or misplaced axis changes the intended parameter. With only a partial snapshot, check each dot-path against its source config and report that materialization remains unverified.
Step 4: Generate configs + loop complexa design
Once the dry-run looks right, drop --dryrun to materialize inf_{idx}_{run_name}.yaml + eval_{idx}_{run_name}.yaml pairs under configs/inference_configs/ and configs/eval_configs/. Then loop complexa design over the inference configs.
For multiple targets, put generation.task_name in the sweeper as an axis, or
give each target's generator invocation a distinct --run_name. Indices restart
at zero on each invocation and filenames omit the target; reusing the same run
name and output directories overwrites earlier configs and reuses result paths.
# 1. Generate one inf_*.yaml + one eval_*.yaml per combination.
python script_utils/generate_inference_configs.py \
--config_name search_binder_local_pipeline \
--sweeper configs/sweeps/my_sweep.yaml \
--override generation.task_name=22_DerF21 \
--run_name my_sweep
# 2. Loop complexa design over each generated inference config.
for cfg in configs/inference_configs/inf_*_my_sweep.yaml; do
complexa design "$cfg" || echo "FAILED: $cfg"
doneThis serialises the sweep on a single GPU — be honest with the user that wall-clock = N × per-run.
Multi-GPU host (optional speed-up)
On a host with K GPUs, shard the config list K ways and launch one loop per GPU in parallel. Each complexa design call uses exactly one GPU at default gen_njobs=1 / eval_njobs=1, so pinning via CUDA_VISIBLE_DEVICES keeps them from colliding:
CONFIGS=(configs/inference_configs/inf_*_my_sweep.yaml)
N=${#CONFIGS[@]}; K=4 # 4 GPUs
for gpu in $(seq 0 $((K-1))); do
(
for i in $(seq $gpu $K $((N-1))); do
CUDA_VISIBLE_DEVICES=$gpu complexa design "${CONFIGS[$i]}" \
|| echo "FAILED on GPU $gpu: ${CONFIGS[$i]}"
done
) &
done
waitDrop gen_njobs / eval_njobs overrides into the loop only if you intentionally want each complexa design invocation to consume multiple GPUs (and you have a way to keep them out of each other's way).
Step 5: Collect results
Each swept config writes to its own ./inference/inf_{idx}_{run_name}/ directory; the analyze step writes ./evaluation_results/eval_{idx}_{run_name}/results_*.csv. After the sweep finishes:
ls -d ./inference/inf_*_my_sweep/
ls ./evaluation_results/eval_*_my_sweep/results_*.csvInspect the supplied CSV schema before aggregating. If it already contains one
row per configuration with n_passed and n_designs, compute
success_rate = n_passed / n_designs; flag zero denominators and invalid counts.
Do not treat those summary rows as individual designs. For per-design rows,
use existing pass flags, parsing string booleans explicitly. If flags are absent,
use the run's analysis thresholds, result_type, column names, and units from
EVALUATION_METRICS.md. PAE may be normalized
by 31 and pLDDT may use different scales; do not substitute generic thresholds.
Step 6: Rank configs
Emit sweep_summary.csv to the run directory. One row per config:
| Column | How to compute |
|---|---|
config_id | The {idx} from inf_{idx}_{run_name} |
<axis_1>, <axis_2>, ... | The swept value at this combination (read from the per-config inf_*.yaml) |
n_samples | n_designs for a supplied config summary, otherwise per-design row count |
success_rate | n_passed / n_designs for a config summary, otherwise mean of parsed per-design pass flags |
mean_i_pae | Preserve the supplied config mean, or average per-design values in consistent units (lower = better) |
mean_i_plddt | i_plddt.mean() (higher = better) |
diversity_score | Unique sequence count / n_samples (or use TM-score clustering if available) |
wall_clock_min | From the per-config log timestamps |
Populate only metrics present in the inputs or computable from them. Missing diversity or timing data stays unavailable.
Then report:
Best config = argmax of
success_rate. Tie-break onmean_i_pae(lower).Pareto frontier: choose the requested objectives and directions. For time versus success, minimize time and maximize success; for time versus iPAE, minimize both. A point is dominated when another is no worse on every objective and strictly better on at least one. Keep distinct config IDs at equal nondominated coordinates; report invalid/missing measurements separately.
Save the full table to sweep_summary.csv, then reopen the saved results and
print a compact summary: row count, best config and metric values, and frontier
IDs with their objective values. Report the CSV paths and keep the hardware
probe and configuration dumps separate from this result summary.
Step 7: Emit manifest
Capture the resolved invocation + outputs for replay. The shared helper takes a single --output-dir (it walks for CSVs and pulls the Hydra config from the run's .hydra/), so call it against the best-config's evaluation directory and pass the parent complexa design command for that run:
BEST_ID=4 # from Step 6 ranking
python3 "$SKILL_DIR"/scripts/write_manifest.py \
--output-dir ./evaluation_results/eval_${BEST_ID}_my_sweep \
--command "python script_utils/generate_inference_configs.py --config_name search_binder_local_pipeline --sweeper configs/sweeps/my_sweep.yaml --override generation.task_name=22_DerF21 --run_name my_sweep && for cfg in configs/inference_configs/inf_*_my_sweep.yaml; do complexa design \"\$cfg\"; done" \
--skill complexa-sweep \
--out ./sweep_runs/my_sweep/sweep_manifest.jsonAlongside the manifest, save the ranked sweep_summary.csv from Step 6 to ./sweep_runs/my_sweep/sweep_summary.csv and surface both paths to the user.
Recommended sweep recipes
| Symptom | Sweep this | Why |
|---|---|---|
| Quality not good enough | beam_width × nsteps (use example.yaml as a starting point) | Both raise compute → quality; find the cheapest combination that lands. |
| Too slow / want speed-up | nsteps downward (e.g. [100, 200, 400]) with fixed beam_width=4 | Find the smallest nsteps that retains success rate. |
| Mode collapse / low diversity | generation.model.bb_ca.simulation_step_params.sc_scale_noise (use bb_ca_temperature.yaml) | Higher noise → more diverse backbones. |
| Reward over-fitting (high reward, bad metrics) | generation.reward_model.reward_models.af2folding.reward_weights.{i_pae, plddt} ratio | Re-balance composite reward. |
| Broaden the best-of-N candidate pool | search_replicas.yaml (best_of_n.replicas) | More candidates per search; use separate seeds/runs to measure repeatability. |
| Algorithm shoot-out | generation.search.algorithm over [single-pass, best-of-n, beam-search, fk-steering] | Compare search regimes; pin everything else. |
Hardware
Total GPU-time for a sweep = N_configs × per_run_GPU_time. A single search_binder_local_pipeline run on one A100 is roughly 30–90 min (binder length + nsteps dependent). A 4-axis × 4-value sweep = 256 configs × ~60 min = ~256 GPU-hours — at that scale, plan on a multi-GPU host with the Step-4 sharding pattern.
Refer to references/hardware.md for the per-run baseline + VRAM minima.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
Sweeper file not found from generate_inference_configs.py | Path resolved from wrong CWD | Use a path relative to the repo root; or pass an absolute path. |
Sweeper YAML must be a mapping | Top-level YAML is a list or scalar | Rewrite as key: [v1, v2] mapping. |
| Dry-run reports zero config pairs | One of the value lists is empty [] | Supply at least one value before generating or launching; the generator does not reject an empty product. |
complexa design rejects --sweeper | Confusion between entrypoints | The CLI does not accept --sweeper. Use generate_inference_configs.py first, then loop complexa design over the generated configs. |
| Override silently collapses a sweep axis | --override key=v shadowed a sweep key | Drop either the override OR the matching key from the sweeper file. |
| One config in the loop fails, sweep keeps going | The || echo "FAILED…" in Step 4 swallows the error | Re-run the failed inf_*.yaml standalone; check the per-config log under ./logs/. Skip failed config_id when ranking. |
For per-axis reference (typical ranges, cost, what gets better/worse), see references/sweep_axes.md.
For the user-facing sweep system overview (config generation, output layout), see references/SWEEP.md.
Files
- ATTRIBUTION.mdAdded by AutoGineer955 B
- BENCHMARK.md7.9 KiB
- LICENSELicence file added by AutoGineer11.2 KiB
- SKILL.md16.5 KiB
- config/skillspector-baseline.yml1.2 KiB
- evals/evals.json34.9 KiB
- evals/files/launch_review/launch.shScript586 B
- evals/files/launch_review/sweeper.yaml89 B
- evals/files/pareto_results.csv84 B
- evals/files/project/SNAPSHOT.md1.0 KiB
- evals/files/project/configs/pipeline/binder/binder_generate.yaml9.0 KiB
- evals/files/project/configs/pipeline/model_sampling.yaml1.4 KiB
- evals/files/project/configs/search_binder_local_pipeline.yaml1.5 KiB
- evals/files/project/configs/sweeps/example.yaml1.1 KiB
- evals/files/project/script_utils/generate_inference_configs.pyScript15.1 KiB
- evals/files/project/source_manifest.json670 B
- evals/files/summary_review.csv297 B
- evals/files/sweep_results.csv322 B
- references/CONFIGURATION_GUIDE.md34.7 KiB
- references/EVALUATION_METRICS.md55.9 KiB
- references/INFERENCE.md14.9 KiB
- references/SEARCH_METADATA.md7.7 KiB
- references/SWEEP.md10.6 KiB
- references/hardware.md4.8 KiB
- references/sweep_axes.md11.7 KiB
- scripts/preflight.shScript8.4 KiB
- scripts/write_manifest.pyScript9.6 KiB
- skill-card.md4.6 KiB
- skill.oms.sig9.9 KiB
references/CONFIGURATION_GUIDE.md
Pipeline Configuration Guide
The single reference for all YAML configuration in the design pipeline: search/generation, reward models, evaluation, analysis, and training.
Documentation Map
Running a design? See Inference Guide.
Understanding metrics? See Evaluation Guide.
Parameter sweeps? See Sweep System.
Search metadata? See Search Metadata.
Table of Contents
Pipeline Overview
Common Overrides Cheat Sheet
Search & Generation Configs
Config Architecture
Protein Binder Pipeline
Ligand Binder Pipeline
Search Algorithms
Refinement
Reward Models
CompositeRewardModel
AF2 Reward (Protein Targets)
RF3 Reward (Ligand or Protein Targets)
Interface Reward Models
Model-Level Weights
Model Sampling Parameters
Running the Pipeline
Evaluation Configs
Evaluation Config Reference
External PDB Directory
Analysis Configs
Protein Binder Analysis
Ligand Binder Analysis
Monomer Analysis
Custom Success Thresholds
Custom Ranking Criteria
Training Configs
Common Patterns
Config Composition (Hydra Defaults)
Command-Line Overrides
Job Parallelism
Pipeline Overview
The design pipeline runs four stages sequentially:
generate → filter → evaluate → analyze| Stage | What it does | Config section |
|---|---|---|
| Generate | Sample binder structures via flow matching, optionally guided by search algorithms and reward models | generation.* |
| Filter | Rank and filter generated samples by reward scores | generation.search.* |
| Evaluate | Redesign sequences (ProteinMPNN) and validate with structure prediction (AF2/RF3) | metric.* |
| Analyze | Aggregate per-sample metrics into summary CSVs with success rates and diversity | aggregation.* |
A single pipeline config file composes all four stages via Hydra defaults.
Common Overrides Cheat Sheet
| What to change | CLI override | Example |
|---|---|---|
| Target | ++generation.task_name=... | 02_PDL1 |
| Search algorithm | ++generation.search.algorithm=... | beam-search |
| Beam width | ++generation.search.beam_search.beam_width=... | 8 |
| Sampling steps | ++generation.args.nsteps=... | 200 |
| Batch size | ++generation.dataloader.batch_size=... | 8 |
| Folding method | ++metric.binder_folding_method=... | rf3_latest |
| Filter limit | ++generation.filter.filter_samples_limit=... | 500 |
| Reward threshold | ++generation.filter.reward_threshold=... | 0.3 |
| Success threshold | ++aggregation.success_thresholds.i_pAE.threshold=... | 5.0 |
| Redesign count | ++metric.num_redesign_seqs=... | 16 |
Search & Generation Configs
Config Architecture
The pipeline uses a modular config system. A top-level pipeline config composes sub-configs for each stage:
configs/search_binder_local_pipeline.yaml # Protein binder pipeline
configs/search_ligand_binder_local_pipeline.yaml # Ligand binder pipeline
│
├── pipeline/binder/binder_generate.yaml → generation.*
│ ├── pipeline/binder/model_sampling.yaml → generation.args.*, generation.model.*
│ └── pipeline/binder/base_gen_data.yaml → generation.dataloader base
│
├── pipeline/binder/binder_evaluate.yaml → metric.*
└── pipeline/binder/binder_analyze.yaml → aggregation.*Protein Binder Pipeline
The main protein binder pipeline config. This is what you run for protein-protein binder design.
# configs/search_binder_local_pipeline.yaml
defaults:
- pipeline/binder/binder_generate@generation # Search, rewards, targets → generation.*
- pipeline/binder/binder_evaluate@_global_ # Evaluation metrics → metric.*
- pipeline/binder/binder_analyze@_global_ # Analysis thresholds → aggregation.*
- _self_
run_name: search_binder_local
ckpt_path: /path/to/checkpoints
ckpt_name: complexa.ckpt
autoencoder_ckpt_path: /path/to/checkpoints/complexa_ae.ckpt
ncpus_: 24
seed: 5
gen_njobs: 2
eval_njobs: 2Run the full pipeline:
complexa design configs/search_binder_local_pipeline.yaml \
++run_name=my_experiment \
++generation.task_name=02_PDL1Or run individual stages:
complexa generate configs/search_binder_local_pipeline.yaml
complexa filter configs/search_binder_local_pipeline.yaml
complexa evaluate configs/search_binder_local_pipeline.yaml
complexa analyze configs/search_binder_local_pipeline.yamlLigand Binder Pipeline
For small-molecule binder design. Uses a separate checkpoint (ligand model), RF3 as the folding reward, and LigandFeatures for conditional generation.
# configs/search_ligand_binder_local_pipeline.yaml
defaults:
- pipeline/ligand_binder/ligand_binder_generate@generation
- pipeline/ligand_binder/ligand_binder_evaluate@_global_
- pipeline/ligand_binder/ligand_binder_analyze@_global_
- _self_
run_name: search_ligand_binder_local
ckpt_path: /path/to/checkpoints
ckpt_name: complexa_ligand.ckpt
autoencoder_ckpt_path: /path/to/checkpoints/complexa_ligand_ae.ckpt
# LoRA is required for the paper ligand model checkpoint
lora:
r: 32
lora_alpha: 64.0
lora_dropout: 0.0
train_bias: none
ncpus_: 24
seed: 5
gen_njobs: 2
eval_njobs: 2Key differences from protein pipeline:
Uses
ligand_binder_generate(RF3 reward,LigandFeaturesconditioning)Uses
ligand_binder_evaluate(rf3_latestfolding,ligand_mpnninverse folding)Requires LoRA config matching the ligand checkpoint
Target definitions come from
configs/targets/ligand_targets_dict.yaml
Search Algorithms
Configured in pipeline/binder/binder_generate.yaml (or ligand_binder/ligand_binder_generate.yaml) under the search: key. CLI path: ++generation.search.*.
search:
algorithm: best-of-n # single-pass, best-of-n, beam-search, fk-steering, mcts
reward_threshold: null
step_checkpoints: [0, 100, 200, 300, 400] # Denoising steps where rewards are computed
best_of_n:
replicas: 2 # Number of independent generation runs per batch element
beam_search:
n_branch: 4 # Candidates to generate at each checkpoint
beam_width: 4 # Top candidates to keep at each checkpoint
keep_lookahead_samples: true
fk_steering:
n_branch: 4
beam_width: 4
temperature: 0.1 # Boltzmann temperature for selection
keep_lookahead_samples: true
mcts:
n_simulations: 20
exploration_prob: 0.5
exploration_constant: 1.0
keep_lookahead_samples: true| Algorithm | Description | When to use |
|---|---|---|
single-pass | Standard generation, no search | Baseline, fast sampling |
best-of-n | Generate N replicas, keep the best | Simple, embarrassingly parallel |
beam-search | Branch and prune at checkpoints | Highest quality, more compute |
fk-steering | Temperature-weighted selection | Balance exploration/exploitation |
mcts | Monte Carlo tree search | Exploration-heavy campaigns |
CLI examples:
# Switch to beam search with wider beam
++generation.search.algorithm=beam-search \
++generation.search.beam_search.beam_width=8 \
++generation.search.beam_search.n_branch=8
# Increase best-of-n replicas
++generation.search.algorithm=best-of-n \
++generation.search.best_of_n.replicas=10Post-Generation Filtering
Configured under the filter: key (CLI path: ++generation.filter.*). Runs after generation to rank and prune samples.
filter:
filter_samples_limit: 1000 # Max samples to keep (top-N by reward)
delete_non_top_n_samples: false # true = delete unselected dirs, false = move to filtered_out_samples/
dedup_sequence: true # Deduplicate identical sequences before ranking
reward_threshold: null # Drop samples below this reward before top-N selectionRefinement
Refinement is an optional post-search optimisation step that improves binder sequences using ColabDesign's AlphaFold2 design pipeline. It runs after the search algorithm on the final selected samples and before reward scoring.
search --> refinement (optional) --> reward scoring --> outputSet refinement.algorithm to null (default) to skip refinement, or sequence_hallucination to enable it.
# In pipeline/binder_generate.yaml (CLI path: ++generation.refinement.*)
refinement:
algorithm: null # null or sequence_hallucination
refine_targets: final # "final" (default) or "all" (final + lookahead)
save_pre_refinement: none # "none", "final", or "all" -- keep unrefined copies
# Stage toggles
enable_soft_optimization: false # Stages 2+3: softmax + one-hot optimisation
enable_greedy_optimization: true # Stage 4: PSSM semigreedy optimisation
# Iteration counts
n_temp_iters: 45 # Softmax temperature annealing iterations (stage 2)
n_hard_iters: 5 # One-hot optimisation iterations (stage 3)
n_greedy_iters: 15 # Semigreedy hard iterations (stage 4)
n_recycles: 3 # AF2 recycle count
greedy_percentage: 1 # % of residues to try per greedy step
# Loss weights for ColabDesign AF2 optimisation
loss_weights:
pae: 0.4
plddt: 0.1
i_pae: 0.1
con: 1.0
i_con: 1.0
dgram_cce: 0.0
rg: 0.3
i_ptm: 0.05
helix_binder: -0.3
nc_termini: 0.0
alignment_bb_ca: 0.0| Parameter | Description | Default |
|---|---|---|
algorithm | null (off) or sequence_hallucination | null |
refine_targets | Which samples are replaced with refined versions: final or all (final + lookahead). Non-targeted samples pass through unchanged. | final |
save_pre_refinement | Also output pre-refinement copies alongside the refined ones: none, final, or all | none |
enable_soft_optimization | Run softmax + one-hot stages (higher quality, slower) | false |
enable_greedy_optimization | Run PSSM semigreedy stage | true |
n_temp_iters | Softmax annealing iterations | 45 |
n_hard_iters | One-hot iterations | 5 |
n_greedy_iters | Semigreedy hard iterations | 15 |
n_recycles | AF2 recycle count | 3 |
greedy_percentage | % of binder residues to try per greedy step (higher = more aggressive) | 1 |
Loss weight reference:
| Weight | What it controls | Recommended range |
|---|---|---|
pae | Predicted aligned error | 0.1 - 1.0 |
plddt | Predicted LDDT confidence | 0.05 - 0.5 |
i_pae | Interface PAE | 0.05 - 0.5 |
con | Intra-chain contact loss | 0.5 - 2.0 |
i_con | Interface contact loss | 0.5 - 2.0 |
dgram_cce | Distogram cross-entropy | 0.0 (usually off) |
rg | Radius of gyration (binder compactness) | 0.1 - 0.5 |
i_ptm | Interface pTM score | 0.01 - 0.1 |
helix_binder | Helicity (negative = encourage helices) | -0.5 to 0.0 |
nc_termini | N-C termini distance penalty | 0.0 - 0.3 |
alignment_bb_ca | Backbone CA alignment to input | 0.0 - 0.3 |
When to use refinement:
Hard targets where search alone does not produce good binders: enable both soft and greedy with
greedy_percentage: 5Quick polish on easy targets: greedy-only (default) with
greedy_percentage: 1Maximum quality: enable soft + greedy, increase
n_temp_itersto 60-80
Controlling what gets refined and saved:
Only samples targeted by refine_targets are replaced with their refined versions. Everything else passes through unchanged -- for example, with refine_targets: final lookaheads are always kept as-is.
save_pre_refinement optionally saves copies of the structures before refinement so you can compare side-by-side. Rewards are computed for all saved samples.
refine_targets | save_pre_refinement | What happens |
|---|---|---|
final | none | Finals are refined and replace originals. Lookaheads pass through unchanged. |
final | final | Same, but also keeps the unrefined finals (final_unrefined). |
all | none | Finals and lookaheads are both refined, replacing originals. |
all | final | Both refined, plus unrefined finals kept for comparison. |
all | all | Both refined, plus unrefined copies of both kept. |
Error handling: If refinement fails for an individual sample (e.g. residue count mismatch from ColabDesign), the original unrefined structure is kept and processing continues for remaining samples.
CLI examples:
# Enable sequence hallucination with greedy-only (fast)
++generation.refinement.algorithm=sequence_hallucination
# Enable both stages for hard targets
++generation.refinement.algorithm=sequence_hallucination \
++generation.refinement.enable_soft_optimization=true \
++generation.refinement.greedy_percentage=5
# Tune loss weights
++generation.refinement.loss_weights.rg=0.5 \
++generation.refinement.loss_weights.nc_termini=0.2
# Refine all samples, keep unrefined copies for comparison
++generation.refinement.refine_targets=all \
++generation.refinement.save_pre_refinement=all
# Refine finals only, but keep unrefined finals to compare
++generation.refinement.save_pre_refinement=final
# Disable refinement
++generation.refinement.algorithm=nullReward Models
Reward models score generated structures during search. They are configured under the reward_model: key in the generation config.
CompositeRewardModel
All pipeline configs use CompositeRewardModel, which combines multiple reward sub-models. Each sub-model computes its own total_reward, and the composite sums them (optionally weighted).
reward_model:
_target_: "proteinfoundation.rewards.base_reward.CompositeRewardModel"
reward_models:
model_name_1:
_target_: "..."
# model-specific config
model_name_2:
_target_: "..."
# model-specific config
# Optional model-level weights (default 1.0 if omitted)
# weights:
# model_name_1: 1.0
# model_name_2: 0.5Execution order:
Folding models run first (AF2, RF3) and produce refolded structures
Interface models run second (TMOL, Bioinformatics) and can optionally use refolded structures via
structure_source
Final reward: total_reward = sum(weight_i * model_i.total_reward)
Component rewards are prefixed with the model name in output CSVs (e.g., af2folding_i_pae, tmol_hbond_count).
AF2 Reward (Protein Targets)
Primary reward for protein-protein binder design. Runs AlphaFold2 Multimer to predict the complex and scores binding confidence.
reward_model:
_target_: "proteinfoundation.rewards.base_reward.CompositeRewardModel"
reward_models:
af2folding:
_target_: "proteinfoundation.rewards.alphafold2_reward.AF2RewardModel"
protocol: "binder"
use_multimer: true
af_params_dir: ${oc.env:AF2_DIR}
num_recycles: 3
use_initial_guess: true
use_initial_atom_pos: false
seed: 0
device_id: null # Auto-detects current CUDA device
reward_weights:
i_pae: -1.0 # Interface PAE (primary, lower is better → negative weight)
con: 0.0 # Intra-binder confidence
dgram_cce: 0.0 # Distance gram cross-entropy
min_ipae: 0.0 # Minimum interface PAE
min_ipsae: 0.0 # ipSAE metrics
avg_ipsae: 0.0
max_ipsae: 0.0
min_ipsae_10: 0.0 # ipSAE with 10A cutoff
max_ipsae_10: 0.0
avg_ipsae_10: 0.0Reward weight convention: Set the weight to 0.0 to disable a metric. Use negative weights for metrics where lower is better (e.g., i_pae: -1.0), positive for metrics where higher is better.
CLI:
# Increase weight on i_pae
++generation.reward_model.reward_models.af2folding.reward_weights.i_pae=-2.0
# Also reward pLDDT
++generation.reward_model.reward_models.af2folding.reward_weights.plddt=0.5RF3 Reward (Ligand or Protein Targets)
Primary reward for ligand binder design. Runs RoseTTAFold3 via CLI to predict the complex. Can also be used for protein-protein targets.
reward_model:
_target_: "proteinfoundation.rewards.base_reward.CompositeRewardModel"
reward_models:
rf3folding:
_target_: "proteinfoundation.rewards.rf3_reward.RF3RewardRunner"
ckpt_path: ${oc.env:RF3_CKPT_PATH}
rf3_path: ${oc.env:RF3_EXEC_PATH}
normalize_pae: true # Divide PAE-family metrics by 31 for 0-1 scale
reward_weights:
min_ipAE: -1.0 # Minimum interface PAE (primary, lower → negative weight)
plddt: 0.0 # Structure confidence (higher is better)
ipAE: 0.0 # Mean interface PAE
mean_min_ipAE: 0.0
mean_ipAE: 0.0
min_mean_ipAE: 0.0
pAE: 0.0 # Overall PAE
ipTM: 0.0 # Interface pTM score
pTM: 0.0 # Overall pTM score
ranking_score: 0.0 # RF3 composite ranking
has_clash: 0.0 # 1.0 if clash, 0.0 if none; use negative weight to penalize
min_ipSAE: 0.0 # Interface pSAE metrics (higher is better)
max_ipSAE: 0.0
avg_ipSAE: 0.0normalize_pae: When true (default), PAE-family metrics (ipAE, min_ipAE, pAE, etc.) are divided by 31.0 before applying weights. This normalizes them to the 0-1 range so you can use simple weights like -1.0 instead of -1/31.
has_clash: Converted from boolean to numeric (1.0/0.0). To penalize clashes, set a negative weight (e.g., has_clash: -5.0).
Environment variables required: RF3_CKPT_PATH and RF3_EXEC_PATH must be set.
CLI:
# Use RF3 as reward in a protein binder pipeline
++generation.reward_model.reward_models.rf3folding._target_="proteinfoundation.rewards.rf3_reward.RF3RewardRunner" \
++generation.reward_model.reward_models.rf3folding.ckpt_path='${oc.env:RF3_CKPT_PATH}' \
++generation.reward_model.reward_models.rf3folding.rf3_path='${oc.env:RF3_EXEC_PATH}' \
++generation.reward_model.reward_models.rf3folding.normalize_pae=true \
++generation.reward_model.reward_models.rf3folding.reward_weights.min_ipAE=-1.0Interface Reward Models
These non-folding models score the interface quality of generated (or refolded) structures. They run after folding models and can optionally use refolded structures via structure_source.
TMOL (force field):
tmol:
_target_: "proteinfoundation.rewards.tmol_reward.TmolRewardModel"
enable_hbond: true
enable_elec: false
hbond_weight: 1.0
elec_weight: 1.0
reward_type: "interaction_count"
energy_threshold: -0.6Bioinformatics (shape complementarity, SASA, hydrophobicity):
bioinformatics:
_target_: "proteinfoundation.rewards.bioinformatics_reward.BioinformaticsRewardModel"
reward_weights:
surface_hydrophobicity: 0.0
interface_sc: 1.0
interface_dSASA: 0.0
interface_fraction: 0.0
interface_hydrophobicity: 1.0
interface_nres: 0.0
reward_thresholds:
interface_sc: 0.55
interface_nres: 7
structure_source: null # null = generated structure. Set to a folding model key (e.g. "af2folding") to use its refolded structure.Using refolded structures: structure_source must match the key name of a folding reward model defined in the same reward_models: block (e.g. af2folding or rf3folding). When set, this interface model scores the refolded structure produced by that folding model instead of the raw generated structure.
Model-Level Weights
Control the relative contribution of each sub-model to the composite reward. If omitted, all models default to weight 1.0.
reward_model:
_target_: "proteinfoundation.rewards.base_reward.CompositeRewardModel"
reward_models:
af2folding: { ... }
tmol: { ... }
bioinformatics: { ... }
weights:
af2folding: 1.0
tmol: 0.5
bioinformatics: 1.0Model Sampling Parameters
Configured in pipeline/model_sampling.yaml. Controls the diffusion sampling process.
args:
nsteps: 400 # Number of denoising steps
self_cond: true # Self-conditioning
guidance_w: 1.0 # Classifier-free guidance weight
save_trajectory_every: 0 # 0 = don't save intermediate structures
model:
bb_ca: # Backbone CA coordinates
schedule:
mode: log
p: 2.0
simulation_step_params:
sampling_mode: sc
sc_scale_noise: 0.1
sc_scale_score: 1.0
local_latents: # Local latent features (side chains, sequence)
schedule:
mode: power
p: 2.0
simulation_step_params:
sampling_mode: sc
sc_scale_noise: 0.1
sc_scale_score: 1.0CLI examples:
# Fewer denoising steps (faster, lower quality)
++generation.args.nsteps=200
# Increase guidance weight
++generation.args.guidance_w=2.0
# Reduce batch size to save memory
++generation.dataloader.batch_size=8Running the Pipeline
Full pipeline (all 4 stages):
complexa design configs/search_binder_local_pipeline.yaml
# With overrides
complexa design configs/search_binder_local_pipeline.yaml \
++run_name=pdl1_beam_v1 \
++generation.task_name=02_PDL1 \
++generation.search.algorithm=beam-search \
++generation.search.beam_search.beam_width=8Individual stages:
complexa generate configs/search_binder_local_pipeline.yaml
complexa filter configs/search_binder_local_pipeline.yaml
complexa evaluate configs/search_binder_local_pipeline.yaml
complexa analyze configs/search_binder_local_pipeline.yamlLigand binder pipeline:
complexa design configs/search_ligand_binder_local_pipeline.yaml \
++run_name=ligand_test \
++generation.task_name=39_7V11_LIGANDQuick local test (reduced samples):
complexa design configs/search_binder_local_pipeline.yaml \
++run_name=quick_test \
++generation.task_name=02_PDL1 \
++generation.args.nsteps=100 \
++generation.dataloader.dataset.nres.nsamples=2Verbose mode (output to terminal instead of log file):
complexa design configs/search_binder_local_pipeline.yaml --verboseEvaluation Configs
All evaluation configs are run with:
complexa evaluate configs/<config_name>.yaml
# or
python -m proteinfoundation.evaluate --config-name <config_name>Evaluation Config Reference
All evaluation configs share the same structure. The difference between binder-only, monomer-only, and combined evaluation is which boolean flags are enabled.
defaults:
- /generation/targets_dict@dataset
- _self_
run_name: my_eval
ckpt_path: Complexa
ckpt_name: Complexa_ckpt
protein_type: binder # binder, monomer, monomer_motif, or motif_binder
input_mode: generated # generated (from pipeline) or pdb_dir (flat directory)
sample_storage_path: ./inference/search_binder_TARGET
output_dir: ./evaluation_results/my_eval
ncpus_: 24
seed: 5
eval_njobs: 20 # Match to gen_njobs from generation
job_id: 0 # Set via SLURM array or loop
dataset:
task_name: 32_PDL1_ALPHA_REPACK
metric:
# -- Binder metrics (full complex refolding) --
compute_binder_metrics: true
binder_folding_method: colabdesign # colabdesign (AF2), rf3_latest, protenix_base_default_v0.5.0
sequence_types: [self, mpnn, mpnn_fixed]
num_redesign_seqs: 8
interface_cutoff: 8.0
inverse_folding_model: soluble_mpnn # soluble_mpnn, protein_mpnn, ligand_mpnn
# -- Pre/post refolding interface metrics --
compute_pre_refolding_metrics: true
pre_refolding:
bioinformatics: true # Shape complementarity, SASA, hydrophobicity
tmol: true # TMOL force field (H-bonds, electrostatics)
compute_refolded_structure_metrics: true
refolded:
bioinformatics: true
tmol: true
# -- Monomer metrics (binder chain designability) --
compute_monomer_metrics: true
monomer_folding_models: [esmfold] # esmfold, colabfold, chai1
compute_designability: true
designability_modes: [ca, bb3o] # ca, bb3o, all_atom
compute_codesignability: true
codesignability_modes: [ca, all_atom]
compute_co_sequence_recovery: true
compute_ss: true
# -- Novelty --
compute_novelty_pdb: true
compute_novelty_afdb: false # Requires AFDB index
keep_folding_outputs: falseEvaluation presets -- toggle these flags to get common evaluation modes:
| Preset | protein_type | compute_binder_metrics | compute_monomer_metrics | compute_pre_refolding_metrics | compute_refolded_structure_metrics |
|---|---|---|---|---|---|
| Binder-only | binder | true | false | false | false |
| Monomer-only | monomer | false | true | false | false |
| Binder + Monomer | binder | true | true | true | false |
| All benchmarks | binder | true | true | true | true |
When protein_type: binder and compute_monomer_metrics: true, monomer evaluation automatically extracts and evaluates only the binder chain.
Key options:
binder_folding_method:colabdesign(AF2, protein-protein),rf3_latest(protein-ligand or high accuracy)sequence_types:self(original sequence),mpnn(ProteinMPNN redesigned),mpnn_fixed(MPNN with fixed target)inverse_folding_model:soluble_mpnn,protein_mpnn,ligand_mpnnmonomer_folding_models:esmfold(fast),colabfold,chai1compute_novelty_afdb: requires AFDB index; set tofalsefor quick runs
ColabDesign does not support ligand targets. Use RF3 or Protenix for ligand binder evaluation.
External PDB Directory
For evaluating PDB files from external sources (BindCraft, AlphaProteo, etc.) that do not have the job_X_* directory structure.
defaults:
- /generation/targets_dict@dataset
- _self_
run_name: external_binder_eval
ckpt_path: external
ckpt_name: external_ckpt
protein_type: binder
input_mode: pdb_dir # Raw PDB files from any flat directory
sample_storage_path: ./pdb_samples/external_binders
output_dir: ./evaluation_results/external_binder_eval
ignore_generated_pdb_suffix: "_binder.pdb" # Skip PDB files matching this suffix
ncpus_: 24
seed: 5
eval_njobs: 1
job_id: 0
dataset:
task_name: 32_PDL1_ALPHA_REPACK
metric:
compute_binder_metrics: true
binder_folding_method: colabdesign
sequence_types: [self]
num_redesign_seqs: 8
interface_cutoff: 8.0
inverse_folding_model: soluble_mpnn
compute_pre_refolding_metrics: false
compute_refolded_structure_metrics: false
compute_monomer_metrics: false
compute_designability: false
compute_codesignability: false
compute_co_sequence_recovery: false
compute_novelty_pdb: false
compute_novelty_afdb: falseKey difference: input_mode: pdb_dir expects a flat directory of PDB files rather than the job_X_* directory structure from generate. Use ignore_generated_pdb_suffix to skip auxiliary PDB files.
Analysis Configs
All analysis configs are run with:
complexa analyze configs/<config_name>.yaml
# or
python -m proteinfoundation.analyze --config-name <config_name>The analysis step loads evaluation CSVs, computes aggregate metrics (success rates, diversity), and organizes output files.
Protein Binder Analysis
Uses default AlphaProteo-style success thresholds: i_pAE * 31 <= 7.0, pLDDT >= 0.9, binder_scRMSD < 1.5.
defaults:
- /analyze@_here_
- _self_
result_type: protein_binderRun with:
python -m proteinfoundation.analyze \
--config-name analyze \
results_dir=./evaluation_results/my_binder_run \
config_name=search_binderLigand Binder Analysis
Uses default ligand binder thresholds: min_ipAE * 31 < 2.0, binder_scRMSD_ca < 2.0, ligand_scRMSD_aligned_allatom < 5.0.
defaults:
- /analyze@_here_
- _self_
result_type: ligand_binderRun with:
python -m proteinfoundation.analyze \
--config-name analyze \
results_dir=./evaluation_results/my_ligand_run \
config_name=search_ligand_binderMonomer Analysis
Uses default designability/codesignability thresholds (2.0 A, auto-detected from result columns).
defaults:
- /analyze@_here_
- _self_
result_type: monomerRun with:
python -m proteinfoundation.analyze \
--config-name analyze \
results_dir=./evaluation_results/my_monomer_run \
config_name=evaluateCustom Success Thresholds
Override the default success thresholds for any result type. Each threshold specifies a column prefix, a scaling factor, a threshold value, and a comparison operator.
Custom binder thresholds:
defaults:
- /analyze@_here_
- _self_
result_type: protein_binder
aggregation:
success_thresholds:
i_pAE:
threshold: 8.0 # More relaxed than default 7.0
op: "<="
scale: 31.0 # Column stores normalized values; multiply back
column_prefix: complex
pLDDT:
threshold: 0.85 # More relaxed than default 0.9
op: ">="
scale: 1.0
column_prefix: complex
scRMSD:
threshold: 2.0 # More relaxed than default 1.5
op: "<"
scale: 1.0
column_prefix: binderCustom monomer thresholds (stricter):
defaults:
- /analyze@_here_
- _self_
result_type: monomer
aggregation:
require_all_thresholds: true
designability_thresholds:
ca:
esmfold:
threshold: 1.5 # Stricter than default 2.0
op: "<="
all_atom:
esmfold:
threshold: 2.5
op: "<="
codesignability_thresholds:
ca:
esmfold:
threshold: 2.0
op: "<="
all_atom:
esmfold:
threshold: 2.5
op: "<="Custom Ranking Criteria
During evaluation, the ranking_criteria config controls how the best refolded sample is selected from multiple inverse-folding sequences. The ranking system computes a composite score where lower is better.
The default ranking criteria are:
Protein binders:
i_pAE(minimize)Ligand binders:
min_ipAE(minimize)
To use custom ranking criteria (e.g., incorporating ipSAE or pLDDT), add them to the metric section of your evaluation config:
metric:
compute_binder_metrics: true
binder_folding_method: rf3_latest
# Custom ranking: pick the sample with the best combination of min_ipAE and ipSAE
ranking_criteria:
min_ipAE:
scale: 1.0
direction: minimize # Lower ipAE is better
min_ipSAE:
scale: 1.0
direction: maximize # Higher ipSAE is betterAny metric present in the refolding output can be used as a ranking criterion. For RF3, the available metrics include: pLDDT, i_pAE, min_ipAE, pAE, min_ipSAE, max_ipSAE, avg_ipSAE.
If ranking_criteria is not specified, the defaults above are used. If a metric name in the criteria is not found in the results, a warning is logged and that criterion is skipped.
Training Configs
Training configs use the same Hydra composition system. Three dataloader types are supported.
PyG Dataloader (default)
Standard PyG/foldcomp dataloader, matching the original training pipeline.
run_name: pyg_training
dataloader_type: pyg
defaults:
- nn: local_latents_score_nn_160M
- generation: validation_local_latents
- dataset: afdb_fromraw/genie2
- _self_
# ... (model, loss, optimizer, and training config)Atomworks Dataloader
Uses the atomworks dataloader pipeline for ligand-aware training.
run_name: atomworks_training
dataloader_type: atomworks
defaults:
- nn: local_latents_score_nn_160M_ligand_chainbreak
- generation: validation_local_latents
- dataset: atomworks/plinder
- _self_
dataloader:
train:
dataloader_params:
batch_size: 5
num_workers: 10
prefetch_factor: 2
# ... (model, loss, optimizer, and training config)Combined Dataloader
Mixes both atomworks and PyG dataloaders for multi-source training.
run_name: combined_training
dataloader_type: combined
defaults:
- nn: local_latents_score_nn_160M_ligand_chainbreak
- generation: validation_local_latents
- dataset: atomworks/plinder
- dataset/afdb_fromraw/genie2@dataset_pyg
- _self_
# ... (model, loss, optimizer, and training config)Common Patterns
Config Composition (Hydra Defaults)
Configs use Hydra's defaults list to compose from shared config fragments:
defaults:
- /generation/targets_dict@dataset # Load target definitions into 'dataset' key
- /analyze@_here_ # Load analyze defaults at the current level
- _self_ # Apply this file's values last (highest priority)/path@keyloads a config group and places it under the specified key@_here_places the loaded config at the root level_self_ensures the current file's values override any defaults
Command-Line Overrides
Use Hydra ++ syntax to override any config value from the command line:
# Override dataset target
complexa evaluate configs/evaluate.yaml ++dataset.task_name=02_PDL1
# Override multiple values
complexa evaluate configs/evaluate.yaml \
++run_name=my_run \
++metric.binder_folding_method=rf3_latest \
++metric.sequence_types="[self,mpnn]"
# Override nested values
complexa analyze configs/analyze.yaml \
++aggregation.success_thresholds.i_pAE.threshold=10.0Job Parallelism
Evaluation is designed for embarrassingly parallel execution across samples. Use eval_njobs and job_id to split work:
# Sequential (all samples in one job)
complexa evaluate configs/evaluate.yaml ++eval_njobs=1 ++job_id=0
# Parallel with SLURM array
# In your SLURM script:
complexa evaluate configs/evaluate.yaml \
++eval_njobs=20 \
++job_id=$SLURM_ARRAY_TASK_IDSet eval_njobs to match gen_njobs from generation so each eval job processes the outputs of one generation job.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Declares allowed tools, Needs Python
Security
What our scanner noticed· Medium risk
- Large base64-encoded blobs
- Scripts that your agent may run
This skill includes scripts that your agent may run. Read them before you use it.
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Ohad Mosafi
- Publisher
- NVIDIA (Official)
- Distributed by
- NVIDIA
- Source
- NVIDIA/skills · skills/bionemo-complexa-sweep · commit fce3cca
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE-APACHE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Ohad Mosafi or NVIDIA.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download complexa-sweep.zip