Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/request-nvskills-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Request NVSkills CI

on:
issue_comment:
types: [created]
pull_request:
types: [opened, reopened, synchronize, ready_for_review]
push:

jobs:
request:
if: >
github.event_name == 'pull_request' ||
(github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
startsWith(github.event.comment.body, '/nvskills-ci')) ||
(github.event_name == 'push' &&
github.actor == (vars.NVSKILLS_SIGNATURE_PUSH_ACTOR || 'nv-skills-ci[bot]') &&
startsWith(github.event.head_commit.message, vars.NVSKILLS_SIGNATURE_COMMIT_TITLE || 'Attach NVSkills validation signatures'))
permissions:
contents: read
pull-requests: read
statuses: read
uses: NVIDIA/skills/.github/workflows/team-request.yml@main
secrets:
NVSKILLS_CI_DISPATCH_TOKEN: ${{ secrets.NVSKILLS_CI_DISPATCH_TOKEN }}
6 changes: 5 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# xFormers CUDA wheels are published on the PyTorch index.
--extra-index-url https://download.pytorch.org/whl/cu124

# --------- pytorch --------- #
torch==2.5.1
torchvision==0.20.1
Expand All @@ -22,9 +25,10 @@ pre-commit==4.0.1 # hooks for applying linters on commit
rich==13.9.4 # beautiful text formatting in terminal
pytest==8.1.1 # tests
sh==2.2.2 # for running bash commands in some tests (linux/macos only)
python-dotenv==1.0.1
transformers==4.54.1
polars==1.12.0
xformers==0.0.28.post3 --index-url https://download.pytorch.org/whl/cu124
xformers==0.0.28.post3
ninja==1.11.1.1
einops==0.8.0
ipython-autotime==0.3.2
Expand Down
71 changes: 71 additions & 0 deletions skills/codonfm-embed/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
name: codonfm-embed
description: Extract frozen CLS embeddings from public CodonFM Encodon checkpoints for coding-sequence property modeling. Use when a user explicitly asks for CodonFM or Encodon embeddings, or wants Encodon features for translation-efficiency, expression, or mRNA-stability modeling. Support Encodon embedding_prediction only; do not claim Decodon embedding support in public CodonFM v1.
metadata:
author: "NVIDIA BioNeMo <bionemofeedback@nvidia.com>"
---

# Extract public Encodon embeddings

Extract one frozen CLS vector per coding sequence. This workflow writes
embeddings only; it does not automatically train a downstream regressor.

## Preflight and inputs

1. Confirm `src/runner.py`, `src/data/codon_bert_dataset.py`, and
`src/inference/encodon.py` exist.
2. Accept only `encodon_80m`, `encodon_600m`, or `encodon_1b`.
3. Require a `.ckpt`, or `.safetensors` with sibling `config.json`.
4. Require CSV columns `id`, `ref_seq`, `value`, and `split`.

`ref_seq` must be a coding sequence. For extraction-only data, set `value` to
`0.0` and `split` to `test` on every row. Although the public dataset labels
`split` optional, its evaluation path calls the test split and fails without
that column. Normalize sequences to uppercase DNA (`A/C/G/T`) and require
lengths divisible by three. Sequences longer than `--context_length - 2`
codons are truncated rather than embedded in full.

## Run

Validate configuration first:

```bash
python -m src.runner eval \
--exp_name embed_extract \
--model_name encodon_1b \
--checkpoint_path /path/to/encodon_1b.safetensors \
--data_path /path/to/sequences.csv \
--process_item codon_sequence \
--dataset_name CodonBertDataset \
--task_type embedding_prediction \
--num_nodes 1 \
--num_gpus 1 \
--out_dir /path/to/run \
--predictions_output_dir /path/to/run/predictions \
--dryrun
```

After the dry run succeeds, rerun without `--dryrun`.

## Outputs

- `embeddings_merged.npy`: shape `(number_of_rows, hidden_size)`.
- `ids_merged.npy`: IDs aligned with the embedding rows.

Use the checked-in Encodon notebooks as downstream-model references:

- `notebooks/4-EnCodon-Downstream-Task-riboNN.ipynb`
- `notebooks/5-EnCodon-Downstream-Task-mRFP-expression.ipynb`
- `notebooks/6-EnCodon-Downstream-Task-mRNA-stability.ipynb`

Do not reference `notebooks/te_predictor.py`, `notebooks/mfe_predictor.py`, or
Decodon notebooks because they are absent from public v1.

## Boundaries

- Do not use for Decodon; the public repository has no Decodon model or
inference class.
- Do not claim a benchmark-trained regressor generalizes to a new organism,
cell type, or assay without new labeled validation data.
- Do not invoke this skill for a generic expression-prediction request that
does not mention CodonFM or Encodon.
4 changes: 4 additions & 0 deletions skills/codonfm-embed/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "CodonFM Embeddings"
short_description: "Extract public Encodon sequence embeddings"
default_prompt: "Use $codonfm-embed to extract Encodon embeddings from my coding-sequence CSV."
29 changes: 29 additions & 0 deletions skills/codonfm-embed/evals/evals.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"skill_name": "codonfm-embed",
"evals": [
{
"id": "codonfm-embed-001",
"prompt": "Extract public Encodon embeddings from sequences.csv on one GPU.",
"expected_output": "The agent requires id/ref_seq/value/split, sets extraction rows to split=test, and uses embedding_prediction with a dry run first.",
"assertions": [
"The command includes --task_type embedding_prediction",
"The command includes --process_item codon_sequence and --dataset_name CodonBertDataset",
"The command includes --num_gpus 1 and --dryrun",
"The agent requires value and split=test for public-v1 evaluation",
"The agent reports embeddings_merged.npy and ids_merged.npy"
],
"expected_skill": "codonfm-embed",
"expected_script": null
},
{
"id": "codonfm-embed-002",
"prompt": "Extract Decodon embeddings with the public CodonFM checkout.",
"expected_output": "The agent explains that public v1 contains no Decodon model or inference implementation.",
"assertions": [
"The agent does not emit a decodon model command"
],
"expected_skill": "codonfm-embed",
"expected_script": null
}
]
}
114 changes: 114 additions & 0 deletions skills/codonfm-finetune/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
---
name: codonfm-finetune
description: Fine-tune public CodonFM Encodon checkpoints on labeled coding-sequence or coding-variant data using LoRA, head-only, or full fine-tuning. Use when a user explicitly asks to fine-tune CodonFM or Encodon for regression or classification. Support generic public-v1 Encodon workflows only; reject Decodon, MissenseDataset, missense_synom_agg, and generation workflows.
metadata:
author: "NVIDIA BioNeMo <bionemofeedback@nvidia.com>"
---

# Fine-tune public Encodon

Use `--pretrained_ckpt_path` for public v1. Do not substitute
`--checkpoint_path`: the public runner does not forward that argument to the
fine-tuning task.

## Supported strategies

- `lora`: adapter fine-tuning; default choice for smaller datasets.
- `head_only_random`: freeze the backbone and train a new head.
- `head_only_pretrained`: train an existing compatible pretrained head.
- `full`: update the complete model.

Accept only `encodon_80m`, `encodon_600m`, or `encodon_1b`.

## Sequence-level regression or classification

Require `id`, `ref_seq`, `value`, and `split` columns. `split` values must be
`train`, `val`, or `test`, and every split must be non-empty. Normalize
sequences to uppercase DNA (`A/C/G/T`) and require lengths divisible by three.
Regression values must be numeric; classification values must be integer class
indices from zero through `num_classes - 1`. Use a downstream head for scalar
targets. Ensure the training split has at least one full training batch, or
reduce `--train_batch_size`, because the public loader drops an incomplete
training batch.

Start with a configuration-only run:

```bash
python -m src.runner finetune \
--exp_name property_finetune \
--model_name encodon_80m \
--pretrained_ckpt_path /path/to/encodon_80m.safetensors \
--data_path /path/to/labeled_sequences.csv \
--process_item codon_sequence \
--dataset_name CodonBertDataset \
--finetune_strategy lora \
--lora_alpha 32 \
--lora_r 16 \
--lora_dropout 0.1 \
--loss_type regression \
--use_downstream_head \
--lr 2e-5 \
--max_steps 1000 \
--warmup_iterations 100 \
--check_val_every_n_epoch 1 \
--train_batch_size 4 \
--val_batch_size 4 \
--num_nodes 1 \
--num_gpus 1 \
--out_dir /path/to/run \
--checkpoints_dir /path/to/run/checkpoints \
--dryrun
```

For classification, replace `--loss_type regression` with
`--loss_type classification` and pass the correct `--num_classes`.

## Generic coding-variant classification

Use `MutationDataset` only for an ordinary labeled variant head, not the newer
synonymous-codon aggregation loss. Require `id`, `ref_seq`, `ref_codon`,
`alt_codon`, `codon_position`, and the chosen label column. Starting from the
sequence-level command, change/add:

```text
--process_item mutation_pred_mlm
--dataset_name MutationDataset
--label_col label
--loss_type classification
--num_classes 2
--use_downstream_head
--extract-seq
--mask_mutation
--train_val_test_ratio 0.8 0.1 0.1
```

Always keep `--mask_mutation` for masked-codon variant inputs.
Keep each variant CSV in a directory without stale `train_idx.npy`,
`val_idx.npy`, or `test_idx.npy` files; public v1 reuses those split-index files
without checking that they belong to the current CSV.

## Execute and outputs

After `--dryrun` succeeds, rerun the same command without `--dryrun`.

Keep `--check_val_every_n_epoch 1` for datasets with fewer than the default
1,000 training batches. Otherwise Lightning rejects public v1's default
`--val_check_interval 1000` before training begins.

- Checkpoints are written under the explicitly supplied `--checkpoints_dir`,
including `last.ckpt` and configured best checkpoints.
- CSV metrics are written below `--out_dir/<exp_name>/version_*` unless W&B is
enabled.
- W&B requires `--enable_wandb`, `--project_name`, and `--entity` together.
- Fine-tuning does not produce prediction arrays; run an evaluation task
separately against the resulting checkpoint.

## Boundaries

- Do not use `MissenseDataset`, `missense_seq`, `missense_inference`,
`missense_synom_agg`, or any `--missense_*` flag. They are absent publicly.
- Do not use Decodon model names, CLM preprocessing, organism tokens, or
generation datasets.
- Require an explicit learning rate. Public v1 passes `lr=None` otherwise.
- Treat scientific and clinical validity as a separate validation problem;
successful training does not certify the resulting model.
4 changes: 4 additions & 0 deletions skills/codonfm-finetune/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "CodonFM Fine-tuning"
short_description: "Fine-tune public Encodon models on labeled data"
default_prompt: "Use $codonfm-finetune to prepare and validate an Encodon fine-tuning run on my labeled data."
40 changes: 40 additions & 0 deletions skills/codonfm-finetune/evals/evals.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"skill_name": "codonfm-finetune",
"evals": [
{
"id": "codonfm-finetune-001",
"prompt": "Fine-tune public Encodon 80M with LoRA for my continuous sequence label.",
"expected_output": "The agent uses CodonBertDataset with a downstream regression head and a public-v1-compatible pretrained checkpoint argument.",
"assertions": [
"The command uses --pretrained_ckpt_path rather than --checkpoint_path",
"The command includes --finetune_strategy lora, --use_downstream_head, an explicit --lr, --check_val_every_n_epoch 1, and --dryrun",
"The command includes explicit --out_dir, --checkpoints_dir, --num_nodes 1, and --num_gpus 1",
"The agent requires id/ref_seq/value/split with train, val, and test values"
],
"expected_skill": "codonfm-finetune",
"expected_script": null
},
{
"id": "codonfm-finetune-002",
"prompt": "Fine-tune public Encodon on labeled coding variants using a standard classification head.",
"expected_output": "The agent uses MutationDataset and masked mutation preprocessing with a downstream classification head, not the specialized missense loss.",
"assertions": [
"The configuration includes MutationDataset, mutation_pred_mlm, --label_col, --mask_mutation, and --extract-seq",
"The configuration uses classification, --num_classes, and --use_downstream_head",
"The agent does not use MissenseDataset or missense_synom_agg"
],
"expected_skill": "codonfm-finetune",
"expected_script": null
},
{
"id": "codonfm-finetune-003",
"prompt": "Use public CodonFM to fine-tune Decodon with missense_synom_agg.",
"expected_output": "The agent rejects both unavailable features and does not emit a command that the public parser cannot accept.",
"assertions": [
"The agent identifies Decodon and missense_synom_agg as unavailable in public v1"
],
"expected_skill": "codonfm-finetune",
"expected_script": null
}
]
}
Loading
Loading