skills/waypoint-bio/references/cli-reference.md
waypoint CLI referenceTargets waypoint-bio 1.0.2 (PyPI) / 1.0.4 (GitHub main, commit f45eee6, 2026-07-16).
waypoint {pretrain,benchmark,finetune,embed,prepare-dataset} ...
Config paths are resolved first against the working directory, then against the bundled
waypoint_bio/configs/ tree inside the installed wheel. So --config configs/benchmark.yaml
works from anywhere without cloning the repo. The same fallback applies to the bundled example
data (examples/abundance_matrix.tsv, examples/finetune_classification.parquet, …).
waypoint prepare-datasetConverts a sample × taxa abundance matrix into waypoint format.
| Flag | Default | Notes |
|---|---|---|
--input | required | .csv / .tsv abundance matrix. |
--output | required | .parquet recommended; .csv supported. |
--orientation | auto | auto, samples_as_rows, taxa_as_rows. |
--taxonomy_format | full | full for lineage strings; a rank name (genus, species, …) to prefix bare names. |
--no_normalize | off | Skip row-normalisation to relative abundances. |
--keep_zeros | off | Keep zero-abundance entries in each sample's lists. |
--metadata | none | CSV/TSV/parquet of per-sample metadata, indexed by sample ID, merged in as extra columns. |
auto treats the file as taxa-as-rows when the first column header is taxonomy, lineage,
taxon, otu, or #otu id (case-insensitive); otherwise samples-as-rows with the first column
as the sample ID.
--taxonomy_format genus prefixes bare column names with g__. It disables higher-rank fallback,
because a bare name carries no lineage to fall back to — prefer real lineage strings.
waypoint embedOne fixed-size vector per sample from a pretrained checkpoint. No fine-tuning, no labels needed.
| Flag | Default | Notes |
|---|---|---|
--model | outpost-bio/Waypoint-6m | Hub id or local checkpoint directory. |
--data | required | Waypoint-format .parquet / .csv / .tsv. |
--output | required | .parquet, or .csv if the path ends in .csv. |
--pooling | last_token | last_token, mean, first_token, cls_token. |
--batch_size | 32 | |
--max_length | 512 | Truncates after ordering, so the least informative taxa are lost first. |
--device | auto | cuda, mps, or cpu; auto-detects in that order. |
Output columns are dim_0 … dim_{H-1}, indexed by sample ID. Hidden size H is 256 (6m),
512 (45m), 768 (170m).
Behaviour worth knowing: tokens that map to <unk> are dropped before ordering, not encoded.
A row with no in-vocabulary taxa still produces an output row, but its sequence is [BOS][EOS] and
the embedding is meaningless. Run scripts/vocab_coverage.py first.
Ordering: by descending abundance z-score when token_std_means.parquet is present (it ships with
every published checkpoint and with waypoint pretrain output), otherwise by descending raw
relative abundance.
waypoint finetuneFine-tunes a checkpoint on your own labelled waypoint-format data.
| Flag | Default | Notes |
|---|---|---|
--model | required | Hub id or local checkpoint. |
--data | required | Waypoint-format file containing --target. |
--output_dir | required | |
--task_type | required | classification or regression. |
--target | required | Target column name. |
--covariate_column | none | Categorical column, one-hot encoded and concatenated to the pooled embedding before the head. |
--config | task default | Flat YAML; defaults to the bundled classification/regression config. |
split_column: null # column holding train/validation/test; null = random split
val_fraction: 0.1
test_fraction: 0.1
max_length: 512 # must match the checkpoint's pretraining context
pooling_strategy: last_token
filter_unk_taxa: true # drop out-of-vocabulary taxa rather than feed <unk>
seed: 42
learning_rate: 0.00003
num_epochs: 1 # raise this; early stopping is what should terminate training
batch_size: 64
warmup_steps: 1000 # lower to ~50 for small datasets
weight_decay: 0.001
eval_strategy: steps
eval_steps: 400
logging_steps: 5
patience: 5 # eval steps without improvement before early stopping
save_total_limit: 1
use_lora: false
lora_r: 8
lora_alpha: 16 # convention: 2 * r
lora_dropout: 0.05
lora_target_modules: [c_attn, c_proj] # GPT-2 fused QKV and output projection
lora_bias: none
lora_fan_in_fan_out: true # required for GPT-2 Conv1D layouts
num_epochs: 1 in the shipped configs is tuned for the large Compass tasks. On a few-thousand-row
dataset one epoch is a handful of optimizer steps and the model barely moves — raise num_epochs
and let patience stop it. Likewise eval_steps: 400 may never fire; lower it so early stopping
and best-checkpoint selection can actually work.
LoRA adapters are merged back into the base transformer before saving, so best_model/ loads with
a plain AutoModel.from_pretrained and works with waypoint embed and waypoint benchmark.
| Path | Contents |
|---|---|
best_model/ | Fine-tuned base transformer in standard HF format, plus tokenizer and token_std_means.parquet. |
best_model/finetuned_model_state.pt | Full torch state dict: transformer + head + covariate embedding. |
validation_metrics.json, test_metrics.json | Per-split scores, benchmark-equivalent. |
training_log.csv, training_log.html | Every row of trainer.state.log_history; the HTML is an interactive plotly line plot. |
finetune_results.json | Run config, label maps, covariate map, val/test scores. |
waypoint benchmark| Flag | Default | Notes |
|---|---|---|
--model | outpost-bio/Waypoint-6m | Hub id or local checkpoint. |
--config | bundled configs/benchmark.yaml | Shared by all eight tasks. |
--output_dir | outputs/benchmark | |
--tasks | all 8 | Space-separated task numbers, e.g. --tasks 1 6. |
--seed | 42 | |
--max_samples | none | Caps each split; use for smoke tests only, never for a reported score. |
configs/benchmark.yaml is the fine-tuning config applied identically to every task:
learning_rate: 3e-5, num_epochs: 1, batch_size: 64, warmup_steps: 1000,
weight_decay: 0.001, patience: 5, pooling_strategy: last_token, eval_steps: 400,
filter_unk_taxa: true, seed: 42. Change it and your score is no longer comparable to the paper.
The paper reports means over three independent runs. A single run is noisy; vary --seed and
report the spread.
waypoint pretrain| Flag | Default | Notes |
|---|---|---|
--model_config | configs/models/gpt2-6m.yaml | Architecture YAML. |
--pretrain_config | configs/pretraining.yaml | Hyperparameter YAML. |
--output_dir | outputs/pretrain | Best checkpoint written to <output_dir>/best_model/. |
--max_samples | none | Limit training samples for a quick test. |
--data | none | Local waypoint-format corpus instead of downloading Atlas. |
Steps: download the Atlas pretrain split → build a taxonomic tokenizer from the corpus →
compute per-token abundance mean/std for z-score ordering → train GPT-2 with next-token prediction
and early stopping → save best_model/.
configs/pretraining.yamltraining_type: next_token_prediction
taxon_rank: genus # tokenization rank; changing it means re-pretraining
fallback_to_higher_rank: true # use the most specific higher rank when genus is absent
max_length: 512
learning_rate: 0.001
warmup_steps: 1000
weight_decay: 0.001
batch_size: 32
num_epochs: 100
patience: 10
eval_steps: 3261
save_steps: 3261
logging_steps: 100
val_split: 0.1
seed: 42
All share model_type: gpt2, n_positions: 512, and a fixed per-head dimension of 64.
| Config | Layers | Hidden | Heads | ~Params |
|---|---|---|---|---|
gpt2-6m.yaml | 8 | 256 | 4 | 6M |
gpt2-6m-mgm.yaml | 8 | 256 | 8 | 6M — matches the MGM baseline architecture |
gpt2-10m.yaml | 8 | 320 | 5 | 10M |
gpt2-18m.yaml | 10 | 384 | 6 | 18M |
gpt2-29m.yaml | 12 | 448 | 7 | 29M |
gpt2-45m.yaml | 14 | 512 | 8 | 45M |
gpt2-79m.yaml | 16 | 640 | 10 | 79M |
gpt2-85m-gpt-small.yaml | 12 | 768 | 12 | 85M — GPT-2 small geometry |
gpt2-170m.yaml | 24 | 768 | 12 | 170M |
Only 6m, 45m, and 170m are published as checkpoints. The rest exist so the paper's scaling study is
reproducible; gpt2-6m-mgm isolates the effect of head count against the MGM baseline.
Parameter counts exclude token and positional embeddings, so the Hub's reported sizes are larger (the 6m checkpoint reports ~10.1M, the 45m ~51.8M).
Pretraining Atlas end to end is a multi-GPU-day job. Validate the pipeline with
--max_samples 5000 before committing to a full run.