diff --git a/.github/workflows/request-nvskills-ci.yml b/.github/workflows/request-nvskills-ci.yml new file mode 100644 index 0000000..a88a057 --- /dev/null +++ b/.github/workflows/request-nvskills-ci.yml @@ -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 }} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 6ce6974..9c9bcad 100644 --- a/requirements.txt +++ b/requirements.txt @@ -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 @@ -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 diff --git a/skills/codonfm-embed/SKILL.md b/skills/codonfm-embed/SKILL.md new file mode 100644 index 0000000..2e72c40 --- /dev/null +++ b/skills/codonfm-embed/SKILL.md @@ -0,0 +1,101 @@ +--- +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 " +--- + +# 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. + +## Instructions + +Resolve the sequence CSV, checkpoint, and output directory from the request and +available files. Validate inputs before extraction. Execution requires the +project's ML dependencies and a compatible NVIDIA GPU. If a required resource +is unavailable, complete the available preparation and return the command with +that prerequisite identified. When extraction is requested and resources are +ready, execute and verify the embedding arrays. A request for preparation ends +with the inputs and command. If no sequences were supplied, report the required +inputs. For Decodon, inspect the [public parser](../../src/runner.py) and +[model configuration](../../src/config.py), explain the missing implementation, +and finish without attempting installation or model development. + +For a demonstration use `nvidia/NV-CodonFM-Encodon-80M-v1`, revision +`399ca9fe17b57941a7bebc6788033919b417413c`, file +`NV-CodonFM-Encodon-80M-v1.safetensors` with sibling `config.json`. +Reuse an existing checkpoint or download it when needed for the requested work. +Preserve a user's explicit checkpoint choice. + +## 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. For execution require a `.ckpt`, or `.safetensors` with sibling `config.json`; + input preparation can use a planned path. +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. + +## Examples + +Set `CODONFM_DATA_PATH` to the sequence CSV, `CODONFM_CHECKPOINT_PATH` to the +checkpoint, and `CODONFM_RUN_DIR` to your chosen output directory: + +```bash +python -m src.runner eval \ + --exp_name embed_extract \ + --model_name encodon_80m \ + --checkpoint_path "$CODONFM_CHECKPOINT_PATH" \ + --data_path "$CODONFM_DATA_PATH" \ + --process_item codon_sequence \ + --dataset_name CodonBertDataset \ + --task_type embedding_prediction \ + --num_nodes 1 \ + --num_gpus 1 \ + --num_workers 0 \ + --val_batch_size 2 \ + --out_dir "$CODONFM_RUN_DIR" \ + --predictions_output_dir "$CODONFM_RUN_DIR/predictions" +``` + +For preparation requests, inspect the CSV directly against the input schema +above and report the test-row count and sequence checks. Extra columns are +allowed; extraction does not require a measured target. This does not require +the ML runtime. The command above performs extraction when resources are ready. + +The existing `--dryrun` optionally builds runtime configuration and skips +execution. It requires the ML dependencies, can create the prediction directory, +and does not read the CSV or load weights. Do not use it as evidence that inputs, +checkpoint compatibility, or embedding quality have been validated. + +## 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. diff --git a/skills/codonfm-embed/agents/openai.yaml b/skills/codonfm-embed/agents/openai.yaml new file mode 100644 index 0000000..d3cb6e8 --- /dev/null +++ b/skills/codonfm-embed/agents/openai.yaml @@ -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." diff --git a/skills/codonfm-embed/evals/evals.json b/skills/codonfm-embed/evals/evals.json new file mode 100644 index 0000000..e155005 --- /dev/null +++ b/skills/codonfm-embed/evals/evals.json @@ -0,0 +1,38 @@ +{ + "skill_name": "codonfm-embed", + "evals": [ + { + "id": "codonfm-embed-001", + "prompt": "Validate the supplied sequences.csv and prepare a public Encodon embedding-extraction command. Explain which rows will be processed and how to associate the output embeddings with sequence IDs. Use the supplied public source and checkpoint metadata.", + "files": [ + "files/codonfm_source.zip", + "files/encodon_checkpoint.json", + "files/sequences.csv" + ], + "expected_output": "Two validated test rows and a public embedding_prediction command with the correct embedding/ID output contract.", + "assertions": [ + "The command uses embedding_prediction, codon_sequence, and CodonBertDataset", + "The command specifies --checkpoint_path and output/prediction paths appropriate to the chosen working directory", + "The agent validates both sequence rows, including value and split=test, and explains that evaluation processes the test split", + "The response identifies embeddings_merged.npy and ids_merged.npy and explains their row alignment without fabricating embeddings" + ], + "expected_skill": "codonfm-embed", + "expected_script": null + }, + { + "id": "codonfm-embed-002", + "prompt": "Does the public CodonFM implementation support extracting Decodon embeddings? Check the supplied source and explain the limitation, if any.", + "files": [ + "files/codonfm_source.zip", + "files/encodon_checkpoint.json" + ], + "expected_output": "The agent identifies the absence of a public Decodon model and inference implementation.", + "assertions": [ + "The agent explains that the supplied public source has no Decodon model/inference implementation and cites inspected files", + "The agent does not invent a Decodon command or attempt to implement the missing model" + ], + "expected_skill": "codonfm-embed", + "expected_script": null + } + ] +} diff --git a/skills/codonfm-embed/evals/files/codonfm_source.zip b/skills/codonfm-embed/evals/files/codonfm_source.zip new file mode 100644 index 0000000..eb76611 Binary files /dev/null and b/skills/codonfm-embed/evals/files/codonfm_source.zip differ diff --git a/skills/codonfm-embed/evals/files/encodon_checkpoint.json b/skills/codonfm-embed/evals/files/encodon_checkpoint.json new file mode 100644 index 0000000..6c6230d --- /dev/null +++ b/skills/codonfm-embed/evals/files/encodon_checkpoint.json @@ -0,0 +1,33 @@ +{ + "repo_id": "nvidia/NV-CodonFM-Encodon-80M-v1", + "revision": "399ca9fe17b57941a7bebc6788033919b417413c", + "model_name": "encodon_80m", + "filename": "NV-CodonFM-Encodon-80M-v1.safetensors", + "size_bytes": 307351588, + "config_filename": "config.json", + "config": { + "vocab_size": 69, + "hidden_size": 1024, + "num_hidden_layers": 6, + "num_attention_heads": 8, + "intermediate_size": 4096, + "hidden_act": "gelu", + "hidden_dropout_prob": 0.1, + "attention_probs_dropout_prob": 0.1, + "initializer_range": 0.02, + "layer_norm_eps": 1e-12, + "pad_token_id": 3, + "position_embedding_type": "rotary", + "classifier_dropout": 0.1, + "rotary_theta": 10000.0, + "ignore_index": -100, + "loss_type": "cross_entropy", + "lora": false, + "lora_alpha": 32.0, + "lora_r": 16, + "lora_dropout": 0.1, + "finetune_strategy": "full" + }, + "source_url": "https://huggingface.co/nvidia/NV-CodonFM-Encodon-80M-v1/tree/399ca9fe17b57941a7bebc6788033919b417413c", + "weights_included": false +} diff --git a/skills/codonfm-embed/evals/files/sequences.csv b/skills/codonfm-embed/evals/files/sequences.csv new file mode 100644 index 0000000..42af3f8 --- /dev/null +++ b/skills/codonfm-embed/evals/files/sequences.csv @@ -0,0 +1,3 @@ +id,ref_seq,value,split +example_1,ATGGCTGAATTTCCGTAA,0.0,test +example_2,ATGGCAGAATTTCCGTAA,0.0,test diff --git a/skills/codonfm-finetune/SKILL.md b/skills/codonfm-finetune/SKILL.md new file mode 100644 index 0000000..1474499 --- /dev/null +++ b/skills/codonfm-finetune/SKILL.md @@ -0,0 +1,200 @@ +--- +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 " +--- + +# 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. + +## Instructions + +Resolve the target label, dataset, checkpoint, and output directory from the +request and available files. Reuse existing data and weights. For training, +check the project's ML dependencies and a compatible NVIDIA GPU before launch. +If a required resource is unavailable, complete the available data preparation +and return the command with the missing prerequisite clearly identified. +When training is requested and the prerequisites are met, execute it and check +the resulting checkpoints and metrics. A request for preparation ends with the +validated inputs and command. + +Use the user's labeled dataset when provided. For a demonstration of sequence +regression without a dataset, use the public human RiboNN translation-efficiency +data below and state that choice. This is not a substitute for a user's intended +assay or for labeled coding variants. If variant labels are missing, return the +required schema and a command template promptly; do not search for labels or +invent measured effects. + +Default demonstration checkpoint: `nvidia/NV-CodonFM-Encodon-80M-v1`, revision +`399ca9fe17b57941a7bebc6788033919b417413c`, file +`NV-CodonFM-Encodon-80M-v1.safetensors` with sibling `config.json`. +The [public weights](https://huggingface.co/nvidia/NV-CodonFM-Encodon-80M-v1) +are about 307 MB. Download them when needed for the requested work; input +preparation can record an intended checkpoint path. These are the original Encodon weights; the `-TE-` +checkpoints use the separate TransformerEngine implementation. + +For an unsupported Decodon or missense-aggregation request, inspect the public +parser/model configuration, explain the missing feature, and finish. Do not +implement the missing model or search private repositories. + +## Examples + +Prepare a small public-data example with the standard-library helper +[prepare_ribonn.py](scripts/prepare_ribonn.py), running from the repository root. +Set `CODONFM_DATA_PATH` to the CSV you want to create: + +```bash +python skills/codonfm-finetune/scripts/prepare_ribonn.py \ + --output "$CODONFM_DATA_PATH" +``` + +With an existing raw file, add `--input "$RIBONN_DATA_PATH"`. The default reads +at most eight accepted rows per split; `--max-rows-per-split 0` processes the full +input. Remote streaming has a time budget and no automatic retries; use a local +file if it fails. The helper follows the CDS slicing in the +[RiboNN notebook](../../notebooks/4-EnCodon-Downstream-Task-riboNN.ipynb): + +- Read the upstream `.csv` with a **tab** delimiter. +- Set `ref_seq = tx_sequence[utr5_size:utr5_size + cds_size]`, `id = transcript_id`, + and `value = mean_te` unchanged. Do not take another logarithm. +- Preserve source fold groups: 0–7 become `train`, 8 becomes `val`, 9 becomes + `test`. This is a demonstration holdout, not the notebook's cross-validation. +- Exclude invalid/non-finite rows and CDSs exceeding 2046 codons instead of + silently truncating labeled examples. Record counts and source in the adjacent + `.metadata.json`. A small subset does not establish predictive performance. + +The pinned dataset URL is in the helper; its source is +[CenikLab/TE_classic_ML](https://github.com/CenikLab/TE_classic_ML/tree/main/data). +The notebook extracts frozen Encodon embeddings and trains a random-forest +regressor with fold-based cross-validation. This skill reuses its data source, +CDS extraction, and target for a separate fine-tuning example; it does not +reproduce the notebook's training procedure or results. + +## 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. Extra columns are allowed. +Map the user's columns to this loader schema; the RiboNN helper is only for +RiboNN source data. Training needs `train` rows and, when validation is enabled, +`val` rows. A `test` split is needed only for later evaluation. Labels in unused +splits need not be populated. Regression targets must be finite numbers; +classification targets must be integer class indices from zero through +`num_classes - 1`. Use a downstream head for scalar targets. + +Check sequence preparation with the user’s assay in mind. The loader converts +uppercase RNA `U` to `T`, and the tokenizer uppercases bases. Ambiguous bases and +incomplete codons can produce unknown tokens; overlength sequences are truncated. +Review these cases rather than silently dropping user records. Choose batches +and a training budget appropriate to the dataset; small training sets may be +resampled by the loader. + +Set `CODONFM_CHECKPOINT_PATH` to the checkpoint file and `CODONFM_RUN_DIR` to +your chosen output directory. This example runs ten steps to check the workflow; +choose the training budget for the actual dataset and task: + +```bash +python -m src.runner finetune \ + --exp_name property_finetune \ + --model_name encodon_80m \ + --pretrained_ckpt_path "$CODONFM_CHECKPOINT_PATH" \ + --data_path "$CODONFM_DATA_PATH" \ + --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 10 \ + --warmup_iterations 1 \ + --check_val_every_n_epoch 1 \ + --train_batch_size 4 \ + --val_batch_size 4 \ + --num_workers 0 \ + --num_nodes 1 \ + --num_gpus 1 \ + --out_dir "$CODONFM_RUN_DIR" \ + --checkpoints_dir "$CODONFM_RUN_DIR/checkpoints" +``` + +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`, the reference-sequence column +(`ref_seq` by default), `ref_codon`, `alt_codon`, `codon_position`, and the chosen +label column. Select existing sequence/label columns with `--ref_seq_col` and +`--label_col`; these overrides apply to `MutationDataset` only. 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. +Use `--extract-seq` to construct the context around a variant in a full CDS; +already prepared contexts can omit it. Choose split ratios for the dataset; +a held-out test split is optional for training. Public v1 reuses existing +`train_idx.npy`, `val_idx.npy`, and `test_idx.npy` files without checking that +they belong to the current CSV. Verify their provenance before reusing them. + +## Execute and outputs + +Check prepared data directly against the selected loader's schema above using +ordinary CSV inspection. Verify required columns, finite labels in the splits +used for training, class indices when applicable, sequence preparation, and +variant reference positions. The RiboNN helper checks its output during +preparation. These checks do not require installing CodonFM's ML dependencies. +For preparation requests, report what was checked and provide the training +command. For execution requests, run it once data, weights, and compute are ready. + +The existing [runner](../../src/runner.py) has an optional `--dryrun` flag that +builds runtime configuration and skips execution. It requires the ML dependencies +and does not read the dataset or load weights. It is not a data-validation step +or a prerequisite for preparing inputs and commands. + +Set validation frequency for the planned training length: for a small example, +`--check_val_every_n_epoch 1` or a smaller `--val_check_interval` avoids public +v1's default interval of 1,000 batches exceeding an epoch. + +- Checkpoints are written under the explicitly supplied `--checkpoints_dir`, + including `last.ckpt` and configured best checkpoints. +- CSV metrics are written below `--out_dir//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. diff --git a/skills/codonfm-finetune/agents/openai.yaml b/skills/codonfm-finetune/agents/openai.yaml new file mode 100644 index 0000000..0dafc77 --- /dev/null +++ b/skills/codonfm-finetune/agents/openai.yaml @@ -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." diff --git a/skills/codonfm-finetune/evals/evals.json b/skills/codonfm-finetune/evals/evals.json new file mode 100644 index 0000000..cbbe9fe --- /dev/null +++ b/skills/codonfm-finetune/evals/evals.json @@ -0,0 +1,60 @@ +{ + "skill_name": "codonfm-finetune", + "evals": [ + { + "id": "codonfm-finetune-001", + "prompt": "Prepare a LoRA fine-tuning run for public Encodon 80M using the supplied RiboNN sample. Use mean_te as the translation-efficiency label. Create a labeled coding-sequence CSV, validate it, and provide the training command. Preserve the source fold groups when choosing train, validation, and test splits. The public source and checkpoint metadata are supplied.", + "files": [ + "files/codonfm_source.zip", + "files/encodon_checkpoint.json", + "files/ribonn_smoke.tsv", + "files/ribonn_smoke.provenance.json" + ], + "expected_output": "A validated 12-row coding-sequence dataset with original mean_te labels and non-empty splits that preserve source fold groups, plus a public Encodon LoRA regression command. The response distinguishes input checks from training results.", + "assertions": [ + "The agent reads the tab-separated RiboNN sample and extracts CDS using utr5_size and cds_size instead of using the entire transcript", + "The output has id/ref_seq/value/split, preserves all 12 valid rows and the original mean_te labels, and reports non-empty splits without dividing a source fold across splits", + "The training command uses --pretrained_ckpt_path, lora, regression, --use_downstream_head, an explicit --lr, and a validation frequency compatible with the planned training run", + "Batch sizes fit the prepared splits, warmup is shorter than the training budget, and checkpoint/output paths are clearly specified", + "The agent validates the prepared CSV and accurately reports what was checked; it does not present preparation as completed training" + ], + "expected_skill": "codonfm-finetune", + "expected_script": "prepare_ribonn.py" + }, + { + "id": "codonfm-finetune-002", + "prompt": "Validate the supplied variants_labeled.csv and prepare a public Encodon fine-tuning command using a standard binary classification head. These are synthetic examples for checking the workflow; their label values are not measured biological effects. Explain the required preprocessing and data splits. Use the supplied public source and checkpoint metadata.", + "files": [ + "files/codonfm_source.zip", + "files/encodon_checkpoint.json", + "files/variants_labeled.csv", + "files/variants_labeled.provenance.json" + ], + "expected_output": "A validated labeled-variant dataset and a public MutationDataset classification command with viable splits. The response identifies the synthetic nature of the labels and does not claim a trained model.", + "assertions": [ + "The command uses MutationDataset, mutation_pred_mlm, --label_col label, --mask_mutation, and --extract-seq", + "The command uses --pretrained_ckpt_path, classification, --num_classes 2, --use_downstream_head, an explicit --lr, and a validation frequency compatible with the planned training run", + "The agent validates reference codons against zero-based CDS positions and binary labels, and checks that the selected training and validation splits are non-empty; a held-out test split is optional for this preparation task", + "The agent avoids reusing unrelated train_idx.npy, val_idx.npy, or test_idx.npy files when preparing the variant CSV", + "The agent does not use MissenseDataset or missense_synom_agg, claim training occurred, or interpret the synthetic labels as biological observations" + ], + "expected_skill": "codonfm-finetune", + "expected_script": null + }, + { + "id": "codonfm-finetune-003", + "prompt": "Does public CodonFM support fine-tuning Decodon with missense_synom_agg? Check the supplied source and explain whether this workflow is available.", + "files": [ + "files/codonfm_source.zip", + "files/encodon_checkpoint.json" + ], + "expected_output": "The agent identifies both features as unavailable in the supplied public implementation and explains the compatibility limitation.", + "assertions": [ + "The agent identifies Decodon and missense_synom_agg as unavailable in the supplied public source and cites the inspected files", + "The agent answers the compatibility question without inventing an executable command, downloading an undocumented model, or implementing the missing features" + ], + "expected_skill": "codonfm-finetune", + "expected_script": null + } + ] +} diff --git a/skills/codonfm-finetune/evals/files/codonfm_source.zip b/skills/codonfm-finetune/evals/files/codonfm_source.zip new file mode 100644 index 0000000..eb76611 Binary files /dev/null and b/skills/codonfm-finetune/evals/files/codonfm_source.zip differ diff --git a/skills/codonfm-finetune/evals/files/encodon_checkpoint.json b/skills/codonfm-finetune/evals/files/encodon_checkpoint.json new file mode 100644 index 0000000..6c6230d --- /dev/null +++ b/skills/codonfm-finetune/evals/files/encodon_checkpoint.json @@ -0,0 +1,33 @@ +{ + "repo_id": "nvidia/NV-CodonFM-Encodon-80M-v1", + "revision": "399ca9fe17b57941a7bebc6788033919b417413c", + "model_name": "encodon_80m", + "filename": "NV-CodonFM-Encodon-80M-v1.safetensors", + "size_bytes": 307351588, + "config_filename": "config.json", + "config": { + "vocab_size": 69, + "hidden_size": 1024, + "num_hidden_layers": 6, + "num_attention_heads": 8, + "intermediate_size": 4096, + "hidden_act": "gelu", + "hidden_dropout_prob": 0.1, + "attention_probs_dropout_prob": 0.1, + "initializer_range": 0.02, + "layer_norm_eps": 1e-12, + "pad_token_id": 3, + "position_embedding_type": "rotary", + "classifier_dropout": 0.1, + "rotary_theta": 10000.0, + "ignore_index": -100, + "loss_type": "cross_entropy", + "lora": false, + "lora_alpha": 32.0, + "lora_r": 16, + "lora_dropout": 0.1, + "finetune_strategy": "full" + }, + "source_url": "https://huggingface.co/nvidia/NV-CodonFM-Encodon-80M-v1/tree/399ca9fe17b57941a7bebc6788033919b417413c", + "weights_included": false +} diff --git a/skills/codonfm-finetune/evals/files/ribonn_smoke.provenance.json b/skills/codonfm-finetune/evals/files/ribonn_smoke.provenance.json new file mode 100644 index 0000000..6832940 --- /dev/null +++ b/skills/codonfm-finetune/evals/files/ribonn_smoke.provenance.json @@ -0,0 +1,12 @@ +{ + "source_url": "https://raw.githubusercontent.com/CenikLab/TE_classic_ML/512fca642b6b7b61ae494ad83cfc2b72831636d2/data/data_with_human_TE_cellline_all_NA_plain.csv", + "upstream_revision": "512fca642b6b7b61ae494ad83cfc2b72831636d2", + "selection": "First valid rows per split: 8 train (folds 0-7), 2 val (fold 8), 2 test (fold 9); CDS <= 2046 codons. Only columns required for preprocessing retained; sequences and mean_te values unchanged.", + "purpose": "Real public-data input preparation fixture, not a benchmark", + "split_counts": { + "train": 8, + "val": 2, + "test": 2 + }, + "rows": 12 +} diff --git a/skills/codonfm-finetune/evals/files/ribonn_smoke.tsv b/skills/codonfm-finetune/evals/files/ribonn_smoke.tsv new file mode 100644 index 0000000..67c7336 --- /dev/null +++ b/skills/codonfm-finetune/evals/files/ribonn_smoke.tsv @@ -0,0 +1,13 @@ +transcript_id tx_sequence utr5_size cds_size mean_te fold +ENST00000342066.8 GCAGAGCCCAGCAGATCCCTGCGGCGTTCGCGAGGGTGGGACGGGAAGCGGGCTGGGAAGTCGGGCCGAGGGAAAAGTCTGAAGACGCTTATGTCCAAGGGGATCCTGCAGGTGCATCCTCCGATCTGCGACTGCCCGGGCTGCCGAATATCCTCCCCGGTGAACCGGGGGCGGCTGGCAGACAAGAGGACAGTCGCCCTGCCTGCCGCCCGGAACCTGAAGAAGGAGCGAACTCCCAGCTTCTCTGCCAGCGATGGTGACAGCGACGGGAGTGGCCCCACCTGTGGGCGGCGGCCAGGCTTGAAGCAGGAGGATGGTCCGCACATCCGTATCATGAAGAGAAGAGTCCACACCCACTGGGACGTGAACATCTCTTTCCGAGAGGCGTCCTGCAGCCAGGACGGCAACCTTCCCACCCTCATATCCAGCGTCCACCGCAGCCGCCACCTCGTTATGCCCGAGCATCAGAGCCGCTGTGAATTCCAGAGAGGCAGCCTGGAGATTGGCCTGCGACCCGCCGGTGACCTGTTGGGCAAGAGGCTGGGCCGCTCCCCCCGTATCAGCAGCGACTGCTTTTCAGAGAAGAGGGCACGAAGCGAATCGCCTCAAGAGGCGCTGCTGCTGCCGCGGGAGCTGGGGCCCAGCATGGCCCCGGAGGACCATTACCGCCGGCTTGTGTCAGCACTGAGCGAGGCCAGCACCTTTGAGGACCCTCAGCGCCTCTACCACCTGGGCCTCCCCAGCCACGGTGAGGACCCACCCTGGCATGATCCCCCTCATCACCTCCCCAGCCACGATCTCCTGAGGGTCCGGCAGGAGGTGGCGGCTGCAGCTCTGAGGGGCCCCAGTGGCCTGGAAGCCCACCTGCCCTCCTCCACGGCAGGTCAGCGTCGGAAGCAGGGCCTGGCTCAGCACCGGGAGGGCGCCGCCCCAGCTGCCGCCCCGTCCTTCTCGGAGAGGGAGCTGCCTCAGCCGCCCCCCTTGCTGTCGCCGCAGAATGCCCCTCACGTCGCCCTGGGCCCCCATCTCAGGCCCCCCTTCCTGGGGGTGCCCTCGGCTCTGTGCCAGACCCCAGGCTACGGCTTCCTGCCCCCCGCGCAGGCGGAGATGTTCGCCTGGCAGCAGGAGCTCCTGCGGAAGCAGAACCTGGCCCGGCTGGAGCTGCCCGCCGACCTCCTGCGGCAGAAGGAGCTGGAGAGCGCGCGCCCACAGCTGCTGGCGCCCGAGACCGCCCTGCGCCCCAACGACGGCGCCGAGGAGCTGCAGCGGCGCGGGGCCCTGCTGGTGCTGAACCACGGCGCGGCGCCACTGCTGGCCCTGCCCCCCCAGGGGCCCCCGGGCTCCGGACCCCCCACCCCGTCCCGGGACTCTGCCCGGCGAGCCCCCCGGAAGGGGGGTCCCGGCCCTGCCTCAGCGCGGCCCAGCGAGTCCAAGGAGATGACGGGGGCTAGGCTCTGGGCACAAGATGGCTCGGAAGACGAGCCCCCCAAAGACTCGGACGGAGAGGACCCCGAGACGGCAGCTGTTGGGTGCAGGGGGCCCACTCCGGGCCAAGCTCCAGCTGGAGGGGCCGGCGCCGAGGGGAAGGGGCTTTTCCCAGGGTCCACACTGCCCCTGGGCTTCCCTTATGCCGTCAGCCCCTACTTCCACACAGGCGCGGTAGGGGGACTCTCCATGGATGGGGAGGAGGCCCCAGCCCCTGAGGACGTCACCAAGTGGACCGTGGATGACGTCTGCAGCTTCGTGGGGGGCCTGTCTGGCTGTGGAGAGTACACTCGGGTCTTCAGGGAGCAGGGGATCGACGGGGAGACCCTGCCACTGCTGACGGAGGAGCACCTGCTGACCAACATGGGGCTGAAGCTGGGGCCCGCCCTCAAGATCCGGGCCCAGGTGGCCAGGCGCCTGGGCCGAGTTTTCTACGTGGCCAGCTTCCCCGTGGCTCTGCCACTGCAGCCACCAACCCTGCGGGCCCCGGAGCGAGAACTCGGCACAGGAGAGCAGCCCTTGTCCCCCACGACGGCCACGTCCCCCTATGGAGGGGGCCACGCCCTTGCCGGTCAAACTTCACCCAAGCAGGAGAATGGGACCTTGGCTCTACTTCCAGGGGCCCCCGACCCTTCCCAGCCTCTGTGTTGAGGTTGCCGGGGGTAGGGGTGGGGCCACACAAATCTCCAGGAGCCACCACTCAACACAATGGCCCTGCCTCCCACCGCTTTATTTCTTTCGGTTTCGGATGCAAAACAAAAAATTTTAAAAGAAAATGTGACTTCAAAGGAAAGGAACAAATTTTCAAAGACTTGGGGGAGTGAAGGCAGAGCCTGGTGCAGATGGACGAGGTCTGCAGACGGAGGGCAGAGGTGGTGGAAGGGGCCAGGGGCCTGCAGGCCTCCCCCTGGAACTGGGACTGGTCTCGGTCTGCTGACGTCAGGGTCAGCTCCCCCGCGGAGCTGACTTCAGCAGCCCACAGCTGTGGGGCTTCAGCAGCCACACCAGCCCAGCCCAGCCCAGCTCTCGATACGTTTGGTCTTTCATGCTGAAAAATAAATAATAAAGCCTG 90 2046 -0.6890823386857142 4 +ENST00000327044.7 GCTTCGGGTTGGTGTCATGGCAGCTGCGGGGAGCCGCAAGAGGCGCCTGGCGGAGCTGACGGTGGACGAGTTCCTAGCTTCGGGCTTTGACTCCGAGTCCGAATCCGAGTCCGAAAATTCTCCACAAGCGGAGACACGGGAAGCACGCGAGGCTGCCCGGAGTCCGGATAAGCCGGGCGGGAGCCCCTCGGCCAGCCGGCGTAAAGGCCGTGCCTCTGAGCACAAAGACCAGCTCTCTCGGCTGAAGGACAGAGACCCCGAGTTCTACAAGTTCCTGCAGGAGAATGACCAGAGCCTGCTAAACTTCAGCGACTCGGACAGCTCTGAGGAGGAAGAGGGGCCGTTCCACTCCCTGCCAGATGTGCTGGAGGAAGCCAGTGAGGAGGAGGATGGAGCGGAGGAAGGAGAAGATGGGGACAGAGTCCCCAGAGGGCTGAAGGGGAAGAAGAATTCTGTTCCTGTGACCGTCGCCATGGTTGAGAGATGGAAGCAGGCAGCAAAGCAACGCCTCACTCCAAAGCTGTTCCATGAAGTGGTACAGGCGTTCCGAGCAGCTGTGGCCACCACCCGAGGGGACCAGGAAAGTGCTGAGGCCAACAAATTCCAGGTCACGGACAGTGCTGCATTCAATGCTCTGGTTACCTTCTGCATCAGAGACCTCATTGGCTGTCTCCAGAAGCTGCTGTTTGGAAAGGTGGCAAAGGATAGCAGCAGGATGCTGCAGCCGTCCAGCAGCCCGCTCTGGGGGAAGCTTCGTGTGGACATCAAGGCTTACCTGGGCTCGGCCATACAGCTGGTGTCCTGTCTGTCGGAGACGACGGTGTTGGCGGCCGTGCTGCGGCACATCAGCGTGCTGGTGCCCTGCTTCCTGACCTTCCCCAAGCAGTGCCGCATGCTGCTCAAGAGAATGGTGATCGTATGGAGCACTGGGGAAGAGTCTCTGCGGGTGCTGGCTTTCCTGGTCCTCAGCAGAGTCTGCCGGCACAAGAAGGACACTTTCCTTGGCCCCGTCCTCAAGCAAATGTACATCACGTATGTGAGGAACTGCAAGTTCACCTCGCCTGGTGCCCTCCCCTTCATCAGTTTCATGCAGTGGACCTTGACGGAGCTGCTGGCCCTGGAGCCGGGTGTGGCCTACCAGCACGCCTTCCTCTACATCCGCCAGCTCGCCATACACCTGCGCAACGCCATGACCACTCGCAAGAAGGAAACATACCAGTCTGTGTACAACTGGCAGTATGTGCACTGCCTCTTCCTGTGGTGCCGGGTCCTGAGCACTGCGGGCCCCAGCGAAGCCCTCCAGCCCTTGGTCTACCCCCTTGCCCAAGTCATCATTGGCTGTATCAAGCTCATCCCCACTGCCCGCTTCTACCCGCTGCGAATGCACTGCATCCGTGCCCTGACGCTGCTCTCGGGGAGCTCGGGGGCCTTCATCCCGGTGCTGCCTTTCATCCTGGAGATGTTCCAGCAGGTCGACTTCAACAGGAAGCCAGGGCGCATGAGCTCCAAGCCCATCAACTTCTCCGTGATCCTGAAGCTGTCCAATGTCAACCTGCAGGAGAAGGCGTACCGGGACGGCCTGGTGGAGCAGCTGTACGACCTCACCCTGGAGTACCTGCACAGCCAGGCACACTGCATCGGCTTCCCGGAGCTGGTGCTGCCTGTGGTCCTGCAGCTGAAGTCGTTCCTCCGGGAGTGCAAGGTGGCCAACTACTGCCGGCAGGTGCAGCAGCTGCTTGGGAAGGTTCAGGAGAACTCGGCATACATCTGCAGCCGCCGCCAGAGGGTTTCCTTCGGCGTCTCTGAGCAGCAGGCAGTGGAAGCCTGGGAGAAGCTGACCCGGGAAGAGGGGACACCCCTGACCTTGTACTACAGCCACTGGCGCAAGCTGCGTGACCGGGAGATCCAGCTGGAGATCAGTGGCAAAGAGCGGCTGGAAGACCTGAACTTCCCTGAGATCAAACGAAGGAAGATGGCTGACAGGAAGGATGAGGACAGGAAGCAATTTAAAGACCTCTTTGACCTGAACAGCTCTGAAGAGGACGACACCGAGGGATTCTCGGAGAGAGGGATACTGAGGCCCCTGAGCACTCGGCATGGGGTGGAAGACGATGAAGAGGACGAGGAGGAGGGCGAGGAGGACAGCAGCAACTCGGAGGATGGAGACCCAGACGCAGAGGCGGGGCTGGCCCCTGGGGAGCTGCAGCAGCTGGCCCAGGGGCCGGAGGACGAGCTGGAGGATCTGCAGCTCTCAGAGGACGACTGAGGCAGCCCATCTGGGGGGCCTGTAGGGGCTGCCGGGCTGGTGGCCAGTGTTTCCACCTCCCTGGCAGTCAGGCCTAGAGGCTGGCGTCTGTGCAGTTGGGGGAGGCAGTAGACACGGGACAGGCTTTATTATTTATTTTTCAGCATGAAAGACCAAACGTATCGAGAGCTGGGCTGGGCTGGGCTGGTGTGGCTGCTGAAGCCCCACAGCTGTGGGCTGCTGAAGTCAGCTCCGCGGGGGAGCTGACCCTGACGTCAGCAGACCGAGACCAGTCCCAGTTCCAGGGGGAGGCCTGCAGGCCCCTGGCCCCTTCCACCACCTCTGCCCTCCGTCTGCAGACCTCGTCCATCTGCACCAGGCTCTGCCTTCACTCCCCCAAGTCTTTGAAAATTTGTTCCTTTCCTTTGAAGTCACATTTTCTTTTAAAATTTTTTGTTTTGCATCCGAAACCGAAAGAAATAAAGCGGTGGGAGGCAGGGCCATTGTGTTGA 16 2250 0.6394872221025641 8 +ENST00000338591.8 GGGAGTGAGCGACACAGAGCGGGCCGCCACCGCCGAGCAGCCCTCCGGCAGTCTCCGCGTCCGTTAAGCCCGCGGGTCCTCCGCGAATCGGCGGTGGGTCCGGCAGCCGAATGCAGCCCCGCAGCGAGCGCCCGGCCGGCAGGACGCAGAGCCCGGAGCACGGCAGCCCGGGGCCCGGGCCCGAGGCGCCGCCGCCTCCACCGCCGCAGCCGCCGGCCCCCGAGGCAGAGCGCACGCGGCCCCGGCAGGCTCGGCCCGCAGCCCCCATGGAGGGAGCCGTGCAGCTGCTGAGCCGCGAGGGCCACAGCGTGGCCCACAACTCCAAGCGGCACTACCACGATGCCTTCGTGGCCATGAGCCGCATGCGCCAGCGCGGCCTCCTGTGCGACATCGTCCTGCACGTGGCTGCCAAGGAGATCCGTGCGCACAAAGTGGTGCTGGCCTCCTGCAGCCCCTACTTCCACGCCATGTTCACAAATGAGATGAGCGAGAGCCGCCAGACCCACGTGACGCTGCACGACATCGACCCTCAGGCCTTGGACCAGCTGGTGCAGTTTGCCTACACGGCTGAGATTGTGGTGGGCGAGGGCAATGTGCAGACTCTGCTCCCAGCCGCCAGTCTCCTGCAGCTGAATGGCGTCCGAGACGCTTGCTGCAAGTTTCTACTGAGTCAGCTCGACCCCTCCAACTGCCTGGGTATCCGGGGCTTTGCCGATGCGCACTCCTGCAGCGACCTGCTCAAGGCCGCCCACAGGTACGTGCTGCAGCACTTCGTGGACGTGGCCAAGACCGAGGAGTTTATGCTGCTGCCCCTGAAACAGGTTCTGGAACTGGTCTCTAGCGACAGCCTGAACGTGCCTTCAGAGGAGGAGGTCTACCGAGCCGTCCTGAGCTGGGTGAAACACGACGTGGACGCCCGCAGGCAGCATGTCCCACGGCTCATGAAGTGTGTGCGGCTGCCCTTGCTGAGCCGCGACTTCCTGCTGGGCCACGTGGATGCCGAGAGCCTGGTGAGGCACCACCCTGACTGCAAGGACCTCCTCATCGAGGCCCTGAAGTTCCACCTGCTGCCTGAGCAGAGGGGCGTCCTAGGCACCAGCCGCACACGTCCCCGGCGCTGCGAGGGGGCCGGGCCTGTGCTTTTTGCTGTGGGCGGCGGGAGCCTGTTTGCCATCCACGGAGACTGTGAGGCCTACGACACGCGCACCGACCGCTGGCACGTGGTGGCCTCCATGTCCACGCGCCGGGCCCGGGTGGGAGTGGCTGCGGTGGGGAACCGGCTCTATGCTGTGGGCGGCTATGATGGGACCTCAGACCTGGCTACCGTGGAGTCCTACGACCCCGTGACTAACACGTGGCAGCCGGAGGTGTCCATGGGCACAAGGCGAAGCTGCCTGGGTGTGGCCGCCTTGCATGGACTCCTGTACTCGGCCGGCGGCTATGACGGGGCCTCCTGCCTGAACAGTGCTGAACGCTACGACCCCCTGACCGGAACGTGGACGTCCGTCGCTGCCATGAGCACCCGGAGGCGCTATGTGCGAGTGGCCACGCTTGATGGGAACCTGTATGCTGTGGGCGGCTACGACAGCTCCTCACACCTGGCCACTGTGGAGAAGTATGAGCCCCAGGTGAACGTGTGGTCGCCCGTGGCGTCCATGCTGAGCCGACGCAGCTCAGCGGGCGTGGCCGTGCTGGAGGGTGCCCTGTACGTGGCAGGGGGCAACGACGGCACCAGCTGCCTCAACTCGGTAGAGAGATACAGTCCAAAGGCTGGAGCCTGGGAAAGCGTGGCGCCCATGAATATCCGCAGGAGCACGCATGACCTGGTGGCCATGGACGGATGGTTGTACGCCGTGGGGGGTAACGACGGTAGCTCCAGCCTCAACTCCATCGAGAAGTACAACCCGAGGACCAACAAGTGGGTGGCCGCATCCTGCATGTTCACCCGGCGCAGCAGTGTGGGTGTGGCGGTGCTGGAGCTGCTCAATTTCCCGCCGCCATCCTCCCCGACGCTGTCCGTGTCCTCCACCAGCCTCTGACCCACCTACCACCAGAGGCCTGCAGCCTCCCACATGCCTTAAGGGGACCGTGGCCCCCACCAGGGACGTCCTGCGCCATCCGTTCACGTCTCTGCATCCATTCCTTCATGTCTTTATTTAGTTGTTTATTTATTTAGTTATTTATCTTATTTATTGAGGGGTGAGGAGTGCCACGGCTGCCCGTTTACACCTTTAGCGTCTGGTCCTCCTGCGTGTCCTCCCCTCCACTGCCTGCATGGGGGGCGCGGGGAGTGACCAGGCGGGGGCCTCACCGCCCCAGGGCCGTTGCCTGCTCAGACCTTGCAGGCTGTGGAGCAAGAGGCCCTGGGTCTCTCCAAGCAGCTGCAGACCCCAGCTCGAATTTTGCACATGGCGGGGTCCCGGGAAGGGTGGGGAGCAGTTGTCCTTCCTGTCGTCGTCTGCCGTGTGCCATCTTTCCTGGATCTTGTAGTGGGTGCACACGCGTGCACTGGGACCCCACACAGCAATACGAGTCCAACTTAATAAACACATTTCTGGGGTTCCTCA 110 1929 -0.7954436229032259 9 +ENST00000304952.11 GCGGGCCTGGAGCCGGGATCCGCCCTAGGGGCTCGGATCGCCGCGCGCTCGCCGCTCGCCCGCCAGCCCGCCCGTGGTCCGTGGCGGCGCGCTCCACCCGGCACGGGGAGGCGCGGGGCGCACCATGGCCGCAGACACGCCGGGGAAACCGAGCGCCTCGCCGATGGCAGGAGCGCCGGCCAGCGCCAGCCGGACCCCAGACAAGCCCCGGAGCGCGGCCGAGCACCGCAAGTCCTCCAAGCCGGTCATGGAGAAGCGGCGCCGAGCGCGTATTAACGAGAGCCTCGCTCAGCTCAAAACCCTCATCCTGGACGCCCTCAGAAAAGAGAGCTCCCGCCACTCGAAGCTGGAGAAGGCGGACATCCTGGAGATGACCGTGAGACACCTGCGGAGCCTGCGTCGCGTGCAGGTGACGGCCGCGCTCAGCGCCGACCCCGCCGTTCTGGGCAAGTACCGCGCCGGCTTCCACGAGTGTCTGGCGGAGGTGAACCGCTTCCTGGCCGGCTGCGAGGGCGTCCCGGCCGACGTGCGCTCCCGCCTGCTGGGCCACCTGGCAGCCTGCCTGCGCCAGCTGGGACCCTCCCGCCGCCCGGCCTCGCTGTCCCCGGCTGCCCCCGCAGAGGCCCCAGCGCCCGAGGTCTACGCGGGCCGCCCGCTGCTGCCATCGCTCGGCGGCCCCTTCCCTCTGCTCGCGCCGCCGCTGCTGCCGGGTCTGACCCGGGCGCTGCCCGCCGCCCCCAGGGCGGGGCCGCAGGGCCCGGGTGGGCCCTGGAGGCCGTGGCTGCGCTGAGGCTGTGGCCCTGAGACTGCATCGGAGGCGGCGCCCCGTTCTAGGGCCGTGGCCTTTGCCGAGACTGTAGCAGAGAAAACGTATTTATTATTCCA 124 666 -0.08823092367164176 7 +ENST00000649529.1 GGCGGCTGAGAGGCAGCGAACTCATCTTTGCCAGTACAGGAGCTTGTGCCGTGGCCCACAGCCCACAGCCCACAGCCATGGGCTGGGACCTGACGGTGAAGATGCTGGCGGGCAACGAATTCCAGGTGTCCCTGAGCAGCTCCATGTCGGTGTCAGAGCTGAAGGCGCAGATCACCCAGAAGATCGGCGTGCACGCCTTCCAGCAGCGTCTGGCTGTCCACCCGAGCGGTGTGGCGCTGCAGGACAGGGTCCCCCTTGCCAGCCAGGGCCTGGGCCCCGGCAGCACGGTCCTGCTGGTGGTGGACAAATGCGACGAACCTCTGAGCATCCTGGTGAGGAATAACAAGGGCCGCAGCAGCACCTACGAGGTACGGCTGACGCAGACCGTGGCCCACCTGAAGCAGCAAGTGAGCGGGCTGGAGGGTGTGCAGGACGACCTGTTCTGGCTGACCTTCGAGGGGAAGCCCCTGGAGGACCAGCTCCCGCTGGGGGAGTACGGCCTCAAGCCCCTGAGCACCGTGTTCATGAATCTGCGCCTGCGGGGAGGCGGCACAGAGCCTGGCGGGCGGAGCTAAGGGCCTCCACCAGCATCCGAGCAGGATCAAGGGCCGGAAATAAAGGCTGTTGTAAAGAGAAA 77 498 0.7913875147051284 2 +ENST00000379370.7 AGTCCCGTCCCCGGCGCGGCCCGCGCGCTCCTCCGCCGCCTCTCGCCTGCGCCATGGCCGGCCGGTCCCACCCGGGCCCGCTGCGGCCGCTGCTGCCGCTCCTTGTGGTGGCCGCGTGCGTCCTGCCCGGAGCCGGCGGGACATGCCCGGAGCGCGCGCTGGAGCGGCGCGAGGAGGAGGCGAACGTGGTGCTCACCGGGACGGTGGAGGAGATCCTCAACGTGGACCCGGTGCAGCACACGTACTCCTGCAAGGTTCGGGTCTGGCGGTACTTGAAGGGCAAAGACCTGGTGGCCCGGGAGAGCCTGCTGGACGGCGGCAACAAGGTGGTGATCAGCGGCTTTGGAGACCCCCTCATCTGTGACAACCAGGTGTCCACTGGGGACACCAGGATCTTCTTTGTGAACCCTGCACCCCCATACCTGTGGCCAGCCCACAAGAACGAGCTGATGCTCAACTCCAGCCTCATGCGGATCACCCTGCGGAACCTGGAGGAGGTGGAGTTCTGTGTGGAAGATAAACCCGGGACCCACTTCACTCCAGTGCCTCCGACGCCTCCTGATGCGTGCCGGGGAATGCTGTGCGGCTTCGGCGCCGTGTGCGAGCCCAACGCGGAGGGGCCGGGCCGGGCGTCCTGCGTCTGCAAGAAGAGCCCGTGCCCCAGCGTGGTGGCGCCTGTGTGTGGGTCGGACGCCTCCACCTACAGCAACGAATGCGAGCTGCAGCGGGCGCAGTGCAGCCAGCAGCGCCGCATCCGCCTGCTCAGCCGCGGGCCGTGCGGCTCGCGGGACCCCTGCTCCAACGTGACCTGCAGCTTCGGCAGCACCTGTGCGCGCTCGGCCGACGGGCTGACGGCCTCGTGCCTGTGCCCCGCGACCTGCCGTGGCGCCCCCGAGGGGACCGTCTGCGGCAGCGACGGCGCCGACTACCCCGGCGAGTGCCAGCTCCTGCGCCGCGCCTGCGCCCGCCAGGAGAATGTCTTCAAGAAGTTCGACGGCCCTTGTGACCCCTGTCAGGGCGCCCTCCCTGACCCGAGCCGCAGCTGCCGTGTGAACCCGCGCACGCGGCGCCCTGAGATGCTCCTACGGCCCGAGAGCTGCCCTGCCCGGCAGGCGCCAGTGTGTGGGGACGACGGAGTCACCTACGAAAACGACTGTGTCATGGGCCGATCGGGGGCCGCCCGGGGTCTCCTCCTGCAGAAAGTGCGCTCCGGCCAGTGCCAGGGTCGAGACCAGTGCCCGGAGCCCTGCCGGTTCAATGCCGTGTGCCTGTCCCGCCGTGGCCGTCCCCGCTGCTCCTGCGACCGCGTCACCTGTGACGGGGCCTACAGGCCCGTGTGTGCCCAGGACGGGCGCACGTATGACAGTGATTGCTGGCGGCAGCAGGCTGAGTGCCGGCAGCAGCGTGCCATCCCCAGCAAGCACCAGGGCCCGTGTGACCAGGCCCCGTCCCCATGCCTCGGGGTGCAGTGTGCATTTGGGGCGACGTGTGCTGTGAAGAACGGGCAGGCAGCGTGTGAATGCCTGCAGGCGTGCTCGAGCCTCTACGATCCTGTGTGCGGCAGCGACGGCGTCACATACGGCAGCGCGTGCGAGCTGGAGGCCACGGCCTGTACCCTCGGGCGGGAGATCCAGGTGGCGCGCAAAGGACCCTGTGACCGCTGCGGGCAGTGCCGCTTTGGAGCCCTGTGCGAGGCCGAGACCGGGCGCTGCGTGTGCCCCTCTGAATGCGTGGCTTTGGCCCAGCCCGTGTGTGGCTCCGACGGGCACACGTACCCCAGCGAGTGCATGCTGCACGTGCACGCCTGCACACACCAGATCAGCCTGCACGTGGCCTCAGCTGGACCCTGTGAGACCTGTGGAGATGCCGTGTGTGCTTTTGGGGCTGTGTGCTCCGCAGGGCAGTGTGTGTGTCCCCGGTGTGAGCACCCCCCGCCCGGCCCCGTGTGTGGCAGCGACGGTGTCACCTACGGCAGTGCCTGCGAGCTACGGGAAGCCGCCTGCCTCCAGCAGACACAGATCGAGGAGGCCCGGGCAGGGCCGTGCGAGCAGGCCGAGTGCGGTTCCGGAGGCTCTGGCTCTGGGGAGGACGGTGACTGTGAGCAGGAGCTGTGCCGGCAGCGCGGTGGCATCTGGGACGAGGACTCGGAGGACGGGCCGTGTGTCTGTGACTTCAGCTGCCAGAGTGTCCCAGGCAGCCCGGTGTGCGGCTCAGATGGGGTCACCTACAGCACCGAGTGTGAGCTGAAGAAGGCCAGGTGTGAGTCACAGCGAGGGCTCTACGTAGCGGCCCAGGGAGCCTGCCGAGGCCCCACCTTCGCCCCGCTGCCGCCTGTGGCCCCCTTACACTGTGCCCAGACGCCCTACGGCTGCTGCCAGGACAATATCACCGCAGCCCGGGGCGTGGGCCTGGCTGGCTGCCCCAGTGCCTGCCAGTGCAACCCCCATGGCTCTTACGGCGGCACCTGTGACCCAGCCACAGGCCAGTGCTCCTGCCGCCCAGGTGTGGGGGGCCTCAGGTGTGACCGCTGTGAGCCTGGCTTCTGGAACTTTCGAGGCATCGTCACCGATGGCCGGAGTGGCTGTACACCCTGCAGCTGTGATCCCCAAGGCGCCGTGCGGGATGACTGTGAGCAGATGACGGGGCTGTGCTCGTGTAAGCCCGGGGTGGCTGGACCCAAGTGTGGGCAGTGTCCAGACGGCCGTGCCCTGGGCCCCGCGGGCTGTGAAGCTGACGCTTCTGCGCCTGCGACCTGTGCGGAGATGCGCTGTGAGTTCGGTGCGCGGTGCGTGGAGGAGTCTGGCTCAGCCCACTGTGTCTGCCCGATGCTCACCTGTCCAGAGGCCAACGCTACCAAGGTCTGTGGGTCAGATGGAGTCACATACGGCAACGAGTGTCAGCTGAAGACCATCGCCTGCCGCCAGGGCCTGCAAATCTCTATCCAGAGCCTGGGCCCGTGCCAGGAGGCTGTTGCTCCCAGCACTCACCCGACATCTGCCTCCGTGACTGTGACCACCCCAGGGCTCCTCCTGAGCCAGGCACTGCCGGCCCCCCCCGGCGCCCTCCCCCTGGCTCCCAGCAGTACCGCACACAGCCAGACCACCCCTCCGCCCTCATCACGACCTCGGACCACTGCCAGCGTCCCCAGGACCACCGTGTGGCCCGTGCTGACGGTGCCCCCCACGGCACCCTCCCCTGCACCCAGCCTGGTGGCGTCCGCCTTTGGTGAATCTGGCAGCACTGATGGAAGCAGCGATGAGGAACTGAGCGGGGACCAGGAGGCCAGTGGGGGTGGCTCTGGGGGGCTCGAGCCCTTGGAGGGCAGCAGCGTGGCCACCCCTGGGCCACCTGTCGAGAGGGCTTCCTGCTACAACTCCGCGTTGGGCTGCTGCTCTGATGGGAAGACGCCCTCGCTGGACGCAGAGGGCTCCAACTGCCCCGCCACCAAGGTGTTCCAGGGCGTCCTGGAGCTGGAGGGCGTCGAGGGCCAGGAGCTGTTCTACACGCCCGAGATGGCTGACCCCAAGTCAGAACTGTTCGGGGAGACAGCCAGGAGCATTGAGAGCACCCTGGACGACCTCTTCCGGAATTCAGACGTCAAGAAGGATTTTCGGAGTGTCCGCTTGCGGGACCTGGGGCCCGGCAAATCCGTCCGCGCCATTGTGGATGTGCACTTTGACCCCACCACAGCCTTCAGGGCACCCGACGTGGCCCGGGCCCTGCTCCGGCAGATCCAGGTGTCCAGGCGCCGGTCCTTGGGGGTGAGGCGGCCGCTGCAGGAGCACGTGCGATTTATGGACTTTGACTGGTTTCCTGCGTTTATCACGGGGGCCACGTCAGGAGCCATTGCTGCGGGAGCCACGGCCAGAGCCACCACTGCATCGCGCCTGCCGTCCTCTGCTGTGACCCCTCGGGCCCCGCACCCCAGTCACACAAGCCAGCCCGTTGCCAAGACCACGGCAGCCCCCACCACACGTCGGCCCCCCACCACTGCCCCCAGCCGTGTGCCCGGACGTCGGCCCCCGGCCCCCCAGCAGCCTCCAAAGCCCTGTGACTCACAGCCCTGCTTCCACGGGGGGACCTGCCAGGACTGGGCATTGGGCGGGGGCTTCACCTGCAGCTGCCCGGCAGGCAGGGGAGGCGCCGTCTGTGAGAAGGTGCTTGGCGCCCCTGTGCCGGCCTTCGAGGGCCGCTCCTTCCTGGCCTTCCCCACTCTCCGCGCCTACCACACGCTGCGCCTGGCACTGGAATTCCGGGCGCTGGAGCCTCAGGGGCTGCTGCTGTACAATGGCAACGCCCGGGGCAAGGACTTCCTGGCATTGGCGCTGCTAGATGGCCGCGTGCAGCTCAGGTTTGACACAGGTTCGGGGCCGGCGGTGCTGACCAGTGCCGTGCCGGTAGAGCCGGGCCAGTGGCACCGCCTGGAGCTGTCCCGGCACTGGCGCCGGGGCACCCTCTCGGTGGATGGTGAGACCCCTGTTCTGGGCGAGAGTCCCAGTGGCACCGACGGCCTCAACCTGGACACAGACCTCTTTGTGGGCGGCGTACCCGAGGACCAGGCTGCCGTGGCGCTGGAGCGGACCTTCGTGGGCGCCGGCCTGAGGGGGTGCATCCGTTTGCTGGACGTCAACAACCAGCGCCTGGAGCTTGGCATTGGGCCGGGGGCTGCCACCCGAGGCTCTGGCGTGGGCGAGTGCGGGGACCACCCCTGCCTGCCCAACCCCTGCCATGGCGGGGCCCCATGCCAGAACCTGGAGGCTGGAAGGTTCCATTGCCAGTGCCCGCCCGGCCGCGTCGGACCAACCTGTGCCGATGAGAAGAGCCCCTGCCAGCCCAACCCCTGCCATGGGGCGGCGCCCTGCCGTGTGCTGCCCGAGGGTGGTGCTCAGTGCGAGTGCCCCCTGGGGCGTGAGGGCACCTTCTGCCAGACAGCCTCGGGGCAGGACGGCTCTGGGCCCTTCCTGGCTGACTTCAACGGCTTCTCCCACCTGGAGCTGAGAGGCCTGCACACCTTTGCACGGGACCTGGGGGAGAAGATGGCGCTGGAGGTCGTGTTCCTGGCACGAGGCCCCAGCGGCCTCCTGCTCTACAACGGGCAGAAGACGGACGGCAAGGGGGACTTCGTGTCGCTGGCACTGCGGGACCGCCGCCTGGAGTTCCGCTACGACCTGGGCAAGGGGGCAGCGGTCATCAGGAGCAGGGAGCCAGTCACCCTGGGAGCCTGGACCAGGGTCTCACTGGAGCGAAACGGCCGCAAGGGTGCCCTGCGTGTGGGCGACGGCCCCCGTGTGTTGGGGGAGTCCCCGGTTCCGCACACCGTCCTCAACCTGAAGGAGCCGCTCTACGTAGGGGGCGCTCCCGACTTCAGCAAGCTGGCCCGTGCTGCTGCCGTGTCCTCTGGCTTCGACGGTGCCATCCAGCTGGTCTCCCTCGGAGGCCGCCAGCTGCTGACCCCGGAGCACGTGCTGCGGCAGGTGGACGTCACGTCCTTTGCAGGTCACCCCTGCACCCGGGCCTCAGGCCACCCCTGCCTCAATGGGGCCTCCTGCGTCCCGAGGGAGGCTGCCTATGTGTGCCTGTGTCCCGGGGGATTCTCAGGACCGCACTGCGAGAAGGGGCTGGTGGAGAAGTCAGCGGGGGACGTGGATACCTTGGCCTTTGACGGGCGGACCTTTGTCGAGTACCTCAACGCTGTGACCGAGAGCGAGAAGGCACTGCAGAGCAACCACTTTGAACTGAGCCTGCGCACTGAGGCCACGCAGGGGCTGGTGCTCTGGAGTGGCAAGGCCACGGAGCGGGCAGACTATGTGGCACTGGCCATTGTGGACGGGCACCTGCAACTGAGCTACAACCTGGGCTCCCAGCCCGTGGTGCTGCGTTCCACCGTGCCCGTCAACACCAACCGCTGGTTGCGGGTCGTGGCACATAGGGAGCAGAGGGAAGGTTCCCTGCAGGTGGGCAATGAGGCCCCTGTGACCGGCTCCTCCCCGCTGGGCGCCACGCAGCTGGACACTGATGGAGCCCTGTGGCTTGGGGGCCTGCCGGAGCTGCCCGTGGGCCCAGCACTGCCCAAGGCCTACGGCACAGGCTTTGTGGGCTGCTTGCGGGACGTGGTGGTGGGCCGGCACCCGCTGCACCTGCTGGAGGACGCCGTCACCAAGCCAGAGCTGCGGCCCTGCCCCACCCCATGAGCTGGCACCAGAGCCCCGCGCCCGCTGTAATTATTTTCTATTTTTGTAAACTTGTTGCTTTTTGATATGATTTTCTTGCCTGAGTGTTGGCCGGAGGGACTGCTGGCCCGGCCTCCCTTCCGTCCAGGCAGCCGTGCTGCAGACAGACCTAGTGCCGAGGGATGGACAGGCGAGGTGGCAGCGTGGAGGGCTCGGCGTGGATGGCAGCCTCAGGACACACACCCCTGCCTCAAGGTGCTGAGCCCCCGCCTTGCACTGCGCCTGCCCCACGGTGTCCCCGCCGGGAAGCAGCCCCGGCTCCTGAATCACCCTCGCTCCGTCAGGCGGGACTCGTGTCCCAGAGAGGAAGGGGCTGCTGAGGTCTGATGGGGCCCTTCCTCCGGGTGACCCCACAGGGCCTTTCCAAGCCCCCATTTGAGCTGCTCCTTCCTGTGTGTGCTCTGGGCCCTGCCTCGGCCTCCTGCGCCAATACTGTGACTTCCAAACAATGTTACTGCTGGGCACAGCTCTGCGTTGCTCCCGTGCTGCCTGCGCCAGCCCCAGGCTGCTGAGGAGCAGAGGCCAGACCAGGGCCGATCTGGGTGTCCTGACCCTCAGCTGGCCCTGCCCAGCCACCCTGGACGTGACCGTATCCCTCTGCCACACCCCAGGCCCTGCGAGGGGCTATCGAGAGGAGCTCACTGTGGGATGGGGTTGACCTCTGCCGCCTGCCTGGGTATCTGGGCCTGGCCATGGCTGTGTTCTTCATGTGTTGATTTTATTTGACCCCTGGAGTGGTGGGTCTCATCTTTCCCATCTCGCCTGAGAGCGGCTGAGGGCTGCCTCACTGCAAATCCTCCCCACAGCGTCAGTGAAAGTCGTCCTTGTCTCAGAATGACCAGGGGCCAGCCAGTGTCTGACCAAGGTCAAGGGGCAGGTGCAGAGGTGGCAGGGATGGCTCCGAAGCCAGAAATGCCTTAAACTGCAACGTCCCGTCCCTTCCCCACCCCCATCCCATCCCCACCCCCAGCCCCAGCCCAGTCCTCCTAGGAGCAGGACCCGATGAAGCGGGCGGCGGTGGGGCTGGGTGCCGTGTTACTAACTCTAGTATGTTTCTGTGTCAATCGCTGTGAAATAAAGTCTGAAAACTTTAAAA 53 6138 0.09680575867567566 4 +ENST00000421241.6 GGGCGGGGTGTACGAAAGAGAAACCCGGAGGGCGCCGGGGACTGGGCCGGGGTCTGCAGGGCTCAGCTGAGCCCATGAGCTCCCAGAGCTAACCCCTGAACACCCAGGCGGGCAAAGGGCTGATGTCGGTAGTCCCCATCCTGGAGGGGCAGGCTCTGCGCATCTGCTCCTGGCATGGCGCTGCGGCACCTCGCCCTCCTGGCTGGCCTTCTCGTGGGAGTCGCCAGCAAGTCCATGGAGAACACGGCCCAGCTGCCCGAGTGCTGTGTGGATGTGGTGGGCGTCAACGCCAGCTGCCCAGGCGCAAGTCTGTGTGGTCCAGGCTGTTACAGGCGCTGGAACGCGGACGGGAGCGCCAGCTGCGTCCGCTGTGGGAACGGAACCCTCCCAGCCTACAACGGCTCCGAGTGTAGAAGCTTTGCTGGCCCGGGTGCGCCATTCCCCATGAACAGAAGCTCAGGGACCCCCGGGCGGCCACATCCTGGGGCTCCGCGCGTGGCCGCCTCCCTCTTCCTGGGCACGTTCTTCATTAGCTCCGGCCTCATCCTCTCCGTAGCTGGGTTCTTCTACCTCAAGCGCTCCAGTAAACTCCCCAGGGCCTGCTACAGAAGAAACAAAGCTCCGGCCCTGCAGCCTGGCGAAGCCGCTGCAATGATCCCCCCGCCACAGTCCTCAGTACGGAAGCCGCGCTACGTCAGGCGGGAGCGGCCCCTGGACAGGGCCACGGATCCCGCTGCCTTCCCGGGGGAGGCCCGTATCAGCAATGTCTGACCTGGAGGCCGAGACCACGCCACGCACTTGGCGGCAGGGACCCGGAGGCCGACCCCTTGGCGGGAACCAGCACAAAGTGTTGGCATCGCCCGGCGCCCGGGACAGTCCTGGGCACAGCCTCGGCTCTGAGTCCCTCCGCCTCCCAGCGACGGACGCCAAAGGGTCCCGGGCCGCCTGAGGCTCCTCCCCACCACAGCCATCTCGTTTATCGGACCAGGAGCAGGCATCCATGAGACCTCAGAGCTTCAGATCGAGGCCTTGGGGGGTCCGGGCCCCCCCAGGAAACACGGTGAGGCCCCAGCGCCTGCAGCCAAAGCTGGCACGATCTATGGGGCAGGTGCCGCTCTGCCTAGAAAAGCCAGGGGCTCTGCTGCCGTGCCCTCCAGAGCCCACAGCGGGCAGGACTCCTCCAGCACCACCACACCCAGTGGCCCGAGACCCCTCTGAGAACAGTGAGGCTGGTCCTCGTGCCGTTCCAGCCGGTGCCCGGCCAGTGGGGAGGACACAGCCTAGGAACCAGCTGCCTGAGACCAGGGTGCCTCTGGGCTGTCCTCCCGCGTGGCGGAGACCCCAAGCACGCAGCCACCCATTTCCGGAGCTGCAGGATAGAGCTTCCTCTTGATCTCTGTTTTTAAGCAGAAATTCATTGTGCAGAAAAGTCCTCCAGAGCTCTGTGGCCCCGCTCGGATCCGCTGGACCCCCATGCCTGGCTGATCCCTGCCCACGTGGGGCAGGCCCACATCTAACCCCCACAAGTCACTGCCTCACTGCACCTGCCAAGGCTGCCCTGGCGCTGAGTCCTGGGGTCCCTCCCGGAGTTCCTGGGAGAAAGGCGCCGTCGTGGCCGCCTCCCGCACGCCAGGCCCGGGCTCCACCGTGGGTCTCAGACGCCCTGCGGCACCGGCACCGTCTGCTTTAGCATGGGACCCCCCTCTGAGGGGTGGCCTGGCCTTCGGGGTCCCCACGCTCCTTTGCGAAGTCCACTGTGGGTGCCATCATGGTCTCCGGGACCTGGGCCAGCGGGAACGTGGGGGCACTGGGTGTGCTGATATAAAGTCGGCATTACTCAA 174 597 -0.1919400409857143 0 +ENST00000360001.11 GCACCGCCCCCGCCCGCAAGAAAGATGGCAGTGGCCTGATCCGGGCCCGTTGGCGGCGTCACTGACGCTTCGCTCCGGTCCTCGGATCCCGAGCGCGGGGAGGCAGACCGACTGTGAGCTGCTTGTCCCCATCCTGCGGCCGTCCTGGGGACACAGAGCCCTCCGTGGTGCCCGGGGATTGGATTGGAGCCAGGACCTCACTTCCTCCTCTGCCCCTGCCCCTGCCCCTCCCAGCACCTGGCCCACACCCTGCAGCCCGCCCCATGGTCTGGCCCTGGGTGGCGATGGCGTCCAGGTGGGGTCCCCTCATTGGCCTGGCTCCGTGCTGCCTCTGGCTCCTGGGGGCAGTCCTTCTGATGGACGCGTCTGCACGGCCTGCCAACCACTCGTCCACTCGAGAGAGAGTAGCCAACAGGGAGGAGAATGAGATCCTGCCCCCAGACCACCTGAACGGGGTGAAGCTGGAGATGGACGGGCACCTCAATCGCGGCTTCCACCAGGAGGTCTTCCTAGGCAAGGACCTGGGTGGCTTTGATGAGGACGCGGAGCCGCGGCGGAGCCGGAGGAAGCTGATGGTCATCTTTTCCAAGGTGGATGTGAACACTGACCGGAAGATCAGTGCCAAGGAGATGCAGCGCTGGATCATGGAGAAGACGGCCGAGCACTTCCAGGAGGCCATGGAGGAGAGCAAGACACACTTCCGCGCCGTGGACCCTGACGGGGACGGTCACGTGTCTTGGGACGAGTATAAGGTGAAGTTTTTGGCGAGTAAAGGCCATAGCGAGAAGGAGGTTGCCGACGCCATCAGGCTCAACGAGGAACTCAAAGTGGATGAGGAAACACAGGAAGTCCTGGAGAACCTGAAGGACCGCTGGTACCAGGCGGACAGCCCCCCTGCAGACCTGCTGCTGACGGAGGAGGAGTTCCTGTCGTTCCTCCACCCCGAGCACAGCCGGGGAATGCTCAGGTTCATGGTGAAGGAGATCGTCCGGGACCTGGACCAGGACGGTGACAAGCAGCTCTCTGTGCCCGAGTTCATCTCCCTGCCCGTGGGCACCGTGGAGAACCAGCAGGGCCAGGACATTGACGACAACTGGGTGAAAGACAGAAAAAAGGAGTTTGAGGAGCTCATTGACTCCAACCACGACGGCATCGTGACCGCCGAGGAGCTGGAGAGCTACATGGACCCCATGAACGAGTACAACGCGCTGAACGAGGCCAAGCAGATGATCGCCGTCGCCGACGAGAACCAGAACCACCACCTGGAGCCCGAGGAGGTGCTCAAGTACAGCGAGTTCTTCACGGGCAGCAAGCTGGTGGACTACGCGCGCAGCGTGCACGAGGAGTTTTGAGCGCCCGGCCGCGCCCCGCGCCGCCCCCCACGCACCACCGGGGCGGCCTCGCGGGTGACTCCGGGCTCCGTGGCTGTCCCGGACCCCACCTCTTCCCTGCCGCCCGCCACCGGCCGACCGACCGCGGCTGCCCCAGTTGATGAGCGGCGTGTCCCCTCTGCAGCGCGCACCCCGGCGGGGCTTTGGCTGTGACGCGGTCGGGGCGCGGGGCTGGGCTGTGGCCCCGCGGCGCCGCCTCCTCCCTGGTCCCTCGAAATCGTGGCATCTCACTTCTGAGAACGAAATCTCGCTTCAGTCACTCTGCCGAAGGCGCTGACGGCATCGCGGCCGGAACCTCTGGGCCCGGCCCCTCCCAGGGCCGCCGCTCCGTGGGAAAAAACAGCTCCTCCATTTCCTTGAAAACTGAACGATTATTAAAAATAGATTAAACTTCGCTGGAAATGAGTAGCCAGGAAGTTCAGGGGAGGGTGCCGGGTCCTTCCCGGGCCTGGCGTGTCGGAGCCACCCAGGTCCCGCAGCTGCCGCTGAGAAAATGCAAATATTTGTTGTGACAAGAATCACATACATTTACTTTAAATATAGTTGCCTTTTTTGGTCAGCTTCA 284 1068 0.734010135871795 4 +ENST00000379198.5 ACTCGCGAGTCCGGCCTGGGCCGCCGGCCCGGCGCGGGCGCCATGAAGCTGCTGCGGCGGGCGTGGCGGCGGCGGGCGGCGCTAGGCCTGGGCACGCTGGCGCTGTGCGGGGCGGCGCTGCTCTACCTGGCGCGCTGCGCGGCCGAGCCCGGGGACCCCAGGGCGATGTCGGGCCGCAGCCCGCCTCCCCCCGCGCCCGCGCGCGCCGCCGCCTTCCTGGCAGTGCTGGTGGCCAGCGCGCCCCGCGCCGCCGAGCGCCGCAGCGTGATCCGCAGCACGTGGCTTGCGCGGCGCGGGGCCCCGGGCGACGTGTGGGCGCGCTTTGCCGTGGGCACGGCCGGCCTGGGCGCCGAGGAGCGGCGCGCCCTGGAGCGGGAGCAGGCGCGGCACGGGGACCTGCTGCTGCTGCCCGCGCTGCGCGACGCCTACGAAAACCTCACGGCCAAGGTGCTGGCCATGCTGGCCTGGCTGGACGAGCACGTGGCCTTCGAGTTCGTGCTCAAGGCGGACGACGACTCCTTCGCGCGGCTGGACGCGCTGCTGGCCGAGCTGCGCGCCCGCGAGCCCGCGCGCCGCCGCCGCCTCTACTGGGGCTTCTTCTCGGGCCGCGGCCGCGTCAAGCCGGGGGGGCGCTGGCGCGAGGCCGCCTGGCAACTCTGCGACTACTACCTGCCCTACGCGCTGGGCGGCGGCTACGTGCTCTCGGCCGACCTGGTGCACTACCTGCGCCTCAGCCGCGACTACCTGCGCGCCTGGCACAGCGAGGACGTGTCTCTGGGCGCCTGGCTGGCGCCGGTGGACGTCCAGCGGGAGCACGACCCGCGCTTCGACACCGAATACCGGTCCCGCGGCTGCAGCAACCAGTACCTGGTGACGCACAAGCAGAGCCTGGAGGACATGCTGGAGAAGCACGCGACGCTGGCGCGCGAGGGCCGCCTGTGCAAGCGCGAGGTGCAGCTGCGCCTGTCCTACGTGTACGACTGGTCCGCGCCGCCCTCGCAGTGCTGCCAGAGAAGGGAGGGCATCCCCTGAGCCGCCGCGGCCCGGCCCTCCGGGACACCTGCTTCACCCGGCGGCGCCTTGGGGCAGGTGCCGAGCGGGCGCACTACGCCCGGGCCCCAAGGCCCCCGTCCCGCAGCCACGCTTGTGGTCGCTGCGTCCCGGTCTGCGTTTGGGAGACCCCTGGGGGTTGCCGGGGCAGCGCGCCGTGTCCAGGTGGAGGTGCCCGTTCCTGGACCTCAGCGAGCCTGAGCCGGGCCCGGCCGCACGCTGACCCCCGTGCTGTCCCCGACCGGCTCACGGGGCTGGGCTCCGATCTTCCGTGTCTCTTATCAGTGGCGTTTCTCACGTCTGCGTCTCAGATCTAACGTGGTTTCACATCAATCCGCTTTCATGGGATTTTGGTCTCTGTCCAGTGACTTCGTGGTAAATGTAACTCAGTGTTTGCTTGCGACTTATTTATAAATATTGTAAGTTTGTGTCGATGAGTGTAAGTTGGCAGTGCGCACGTCTCGGTTTTTTTACATGATTTAAGGAAAGACTTTTATGTCAGAACTTGGTGCCTGTACCGTCAACCCCGCTGCTGCCCGTGTTTAAACGCAGGAGAACTTTAAAACTGGCCATCTATCTTTTCAGTGTACAAGTCACTGAACCCATTGTTTCTTTCTGAAGAGACTTTCCTTTCAAGGCTTCCCATGGGTCCGCGCCACACAGGGCCGGTGCTGCTTTATTTCAGACTCTGCCCCAGGTTCCAGGAATCCGAACCCCGGAGTGCTGACGCGGTTCCCCAACTTCCGCCTTAAGAAAACAGGACCAGCCGGCACCAGGCCCGTCTCTCACGTACTTTAACACATCCTTGAAAGCCCCTCGTTTAATGAGAAAAGCGAACACTGCGGTCCTTGCCAAAGTAAAATGAAGCTGCCCCAGGACAAGGGGTTACCATGAGCTCCCTGGAGTCCGACGCGGGTTTTCTCTCTGGGGGACCTGGGTGGTCCCCGCTGTGGTCTTTGTTGTCCCACTTTGGGACCGGGTCCAGTCTGGGGTCTAGTCTCGAGCATCAGGGTCAGGCTCGGGGCAGGGCTGGGTTAGGCTCCGGGTCAGTCTTGCCATGGGTTTGGGAGCAGGTTTGGGTTACTTGCGTTTGAAGGCAGCAGTGGTCTCAGGAGGAAGAAACGGGGGCGGGAGAGAGTGGTGATCTGTGGTCAGTGGGTCAGTGACCTGCACGGTGATTCTCCCACCTCCAAAAGGTAGGGGTGGGACTGGAGGCGTCCCTAGGTCAGGCCGTTGAGTTCGAGCTCCGATGGGCCACCTTGAATCCAGGACTGACCGCCCGTGTGTGCACAGTTTGTTCTTGGACGAGGACTCGTGAGGATCGAGGGCTGGGGACCCCGGTGTGAGCAGGATGGGGCCCTGCCCTCCCGTGGGAGTTGTGGACTCGAGCCCAGGGGCTGCCCGTCACAGCGGTGTCCCAGGTCCCTGCCATCCGATTTTACCTGGGATGTCTTCTCTGGAGTTTGGAATTGCTTGAGGAACCCTGCGTGTGCTTGGAGAGGCCAGAGGGCTTGCTGAGAACCCCATGGACAGTGGAGAGCGGGATTCGAACCAAGGGCTGGACTCCCACACCTCTGGCCTGCGTCGCCCAGTTCTTTGTGGCTCTGAAGAATTGGCCGCTGTGGAAAAGAGCAAATGTCCGAGACCCCCAACAGGAAGAGTCTAAAAATCCAGTTTGCAACCACTTCTGACCTACAAAAAAATGGAAATTTAGTGTTTTTCAGCCTAAGACATTAAATTTCATATCAGAACAAA 42 990 0.06170675702777776 4 +ENST00000349431.11 GGTTCCGCCCCGCGAGCGGCCATCTTGGAGGCTGAGGCGGCGGCGGCGGCGCTGCGGCGGGTTCGGTGGGCCCAATCCCGGGGCGGTGCGGCTGTTTCGGGCGCGGGCCCCGCTTTTCCGCACCCTGCTCCGGCCTCGACTACGGCGAGCCTGAGCGCGGCGGCGGCCCACGCGCAGCGACAGGGAGAGATGAGCAGCACCAGCAGTAAGAGGGCTCCGACCACGGCAACCCAGAGGCTGAAGCAGGACTACCTTCGCATTAAGAAAGACCCGGTGCCTTACATCTGTGCCGAGCCCCTCCCTTCGAATATTCTCGAGTGGCACTATGTCGTCCGAGGCCCAGAGATGACCCCTTATGAAGGTGGCTATTATCATGGAAAACTAATTTTTCCCAGAGAATTTCCTTTCAAACCTCCCAGTATCTATATGATCACTCCCAACGGGAGGTTTAAGTGCAACACCAGGCTGTGTCTTTCTATCACGGATTTCCACCCGGACACGTGGAACCCGGCCTGGTCTGTCTCCACCATCCTGACTGGGCTCCTGAGCTTCATGGTGGAGAAGGGCCCCACCCTGGGCAGTATAGAGACGTCGGACTTCACGAAAAGACAACTGGCAGTGCAGAGTTTAGCATTTAATTTGAAAGATAAAGTCTTTTGTGAATTATTTCCTGAAGTCGTGGAGGAGATTAAACAAAAACAGAAAGCACAAGACGAACTCAGTAGCAGACCCCAGACTCTCCCCTTGCCAGACGTGGTTCCAGACGGGGAGACGCACCTCGTCCAGAACGGGATTCAGCTGCTCAACGGGCATGCGCCGGGGGCCGTCCCAAACCTCGCAGGGCTCCAGCAGGCCAACCGGCACCACGGACTCCTGGGTGGCGCCCTGGCGAACTTGTTTGTGATAGTTGGGTTTGCAGCCTTTGCTTACACGGTCAAGTACGTGCTGAGGAGCATCGCGCAGGAGTGAGGCCCAGGCGCCGAGACCCAAGGCGCCACTGAGGGCACCGCGCACCAGAGCGTGACCTCGGCAGGCTGGACACACTGCCCAGCACAGGCAGACCCACCAGGCTCCTAGGTTTAGCTTTTAAAAACCTGAAAGGGGAAGCAAAAACCAAAATGTGTGACTGGGCTTTGGAGGAGACTGGAGCCTCAGCCCTGTCCTGGCCACGGGCCGCTGGGGCTGGTGTGGGTGGGCCTTGTGTGCTGGATTTGTAGCTTATCTTCCGTGTTGTCTTTGGACCTGTTTTAGTAAACCCGTTTTTCATTTTATTAGATGTGGTCACTTAGAAATGCAAACTTGCTGCCGACCGCGGGCTGCTCCTGCGTTCTTGGAGCTCCTGGCGCGTTTCTCGGAGCTCCCGGCTCCTCAGCGGGTGGGAACCTCGGGGCCCAGGGGTGGAGCTGGCGTCCGCGGGTGCTGGTCTGGCCTGGCCGTGTGGTGATGAGGCTTAGCGGGGCCAGTGACGGCCGTGGCTCAGGATCCATAAGTCGGGGTTTGGTCTCAGCATTTACAAATGTGTTTACAGTCAGAATGAAACACATTCCTTCTAGAAAGTGCTTGGGGGTTTTTGCTGCCCTGGAAGCCAGGAGCCTGCTCACTCCAACCACAAGTCGCCCTTGACTGCGGCGGCCGCGAGCGGGGCGGGGGCTGCCGGTGCCCTCCGCAGGCCGGGCCTCCTGGGCGCCCCTCGGTGCTGCAGGCTGGGGGGCCTTGGGTACCTGCAGAGCCTTTTCTCTGAATTCCTTATGTCCGGTGGGCCAGAAGCCCGTCCTCCTATGCTGGTGGAAGGCGGAGGACCGGAGTCCCTGCAGAAGGCCCCGTGCACTCGGGGGCCTCCCTCACATCCCGTGCCCCCTGCGCTGGCCTTCACAGTAGGTAATGGCTCCGGCCCGGGTGTTCGCTGTCCACGGAACATGGCAGAGGGGCACCCCGGCCCGGAAAGACGCCAGAGCCAGCAGGGGCTGTTTCGGGCCGCGTGGCTCCCCGGGTCTCGGCCGTCTCCCCTCTTCTGCGTCTGTTCCGTGACTTCGCCTGGGTGGGATGTACCGCAGGTGCATCGCGTCGAGGTGGGGCACGGCCGCCGGCAAGAAACCCACCCTGTCCGGAGGCGGGCGTGAGACAAGCCCAGCCCGCACGCGCTCATCTTTCTTCGTTTTTTGATCAGTTTATTCAGAATTGCTCTATAATTTACCAATTGTATGTATTTAACCTATTCTTGTGGAAAAAAAAGGTCTTTCATTATATCTTTATTTCTGAA 189 780 0.5229675528311688 6 +ENST00000435064.6 GCAGTGCATCACCGCAGGCGGGCCTCGCGGGTCCGGGAGCGCGGCGGAGACGATGCCTGAGATCAGAGTCACGCCCTTGGGGGCCGGCCAGGACGTGGGCCGAAGCTGCATCCTGGTCTCCATTGCGGGCAAGAATGTCATGCTGGACTGTGGAATGCACATGGGCTTCAATGACGACCGACGCTTCCCTGACTTCTCCTACATCACCCAGAACGGCCGCCTAACAGACTTCCTGGACTGTGTGATCATTAGCCACTTCCACCTGGACCACTGCGGGGCACTCCCCTACTTCAGCGAGATGGTGGGCTACGACGGGCCCATCTACATGACTCACCCCACCCAGGCCATCTGCCCCATCTTGCTGGAGGACTACCGCAAGATCGCCGTAGACAAGAAGGGCGAGGCCAACTTCTTCACCTCCCAGATGATCAAAGACTGCATGAAGAAGGTGGTGGCTGTCCACCTCCACCAGACGGTCCAGGTAGATGATGAGCTGGAGATCAAGGCCTACTATGCAGGCCACGTGCTGGGGGCAGCCATGTTCCAGATTAAAGTGGGCTCAGAGTCTGTGGTCTACACGGGTGATTATAACATGACCCCAGACCGACACTTAGGAGCTGCCTGGATTGACAAGTGCCGCCCCAACCTGCTCATCACAGAGTCCACGTACGCCACGACCATCCGTGACTCCAAGCGCTGCCGGGAGCGAGACTTCCTGAAGAAAGTCCACGAGACCGTGGAGCGTGGTGGGAAGGTGCTGATACCTGTGTTCGCGCTGGGCCGCGCCCAGGAGCTCTGCATCCTCCTGGAGACCTTCTGGGAGCGCATGAACCTGAAGGTGCCCATCTACTTCTCCACGGGGCTGACCGAGAAGGCCAACCACTACTACAAGCTGTTCATCCCCTGGACCAACCAGAAGATCCGCAAGACTTTCGTGCAGAGGAACATGTTTGAGTTCAAGCACATCAAGGCCTTCGACCGGGCTTTTGCTGACAACCCAGGACCGATGGTTGTGTTTGCCACGCCAGGAATGCTGCACGCTGGGCAGTCCCTGCAGATCTTCCGGAAATGGGCCGGAAACGAAAAGAACATGGTCATCATGCCCGGCTACTGCGTGCAGGGCACCGTCGGCCACAAGATCCTCAGCGGGCAGCGGAAGCTCGAGATGGAGGGGCGGCAGGTGCTGGAGGTCAAGATGCAGGTGGAGTACATGTCATTCAGCGCACACGCGGACGCCAAGGGCATCATGCAGCTGGTGGGCCAGGCAGAGCCGGAGAGCGTGCTGCTGGTGCATGGCGAGGCCAAGAAGATGGAGTTCCTGAAGCAGAAGATCGAGCAGGAGCTCCGGGTCAACTGCTACATGCCGGCCAATGGCGAGACGGTGACGCTGCCCACAAGCCCCAGCATCCCCGTAGGCATCTCGCTGGGGCTGCTGAAGCGGGAGATGGCGCAGGGGCTGCTCCCTGAGGCCAAGAAGCCTCGGCTCCTGCACGGCACCCTGATCATGAAGGACAGCAACTTCCGGCTGGTGTCCTCAGAGCAAGCCCTCAAAGAGCTGGGTCTGGCTGAGCACCAGCTGCGCTTCACCTGCCGCGTGCACCTGCATGACACACGCAAGGAGCAGGAGACGGCATTGCGCGTCTACAGCCACCTCAAGAGCGTCCTGAAGGACCACTGTGTGCAGCACCTCCCAGACGGCTCTGTGACTGTGGAGTCCGTCCTCCTCCAGGCCGCCGCCCCTTCTGAGGACCCAGGCACCAAGGTGCTGCTGGTCTCCTGGACCTACCAGGACGAGGAGCTGGGGAGCTTCCTCACATCTCTGCTGAAGAAGGGCCTCCCCCAGGCCCCCAGCTGAGGCCGGCAACTCACCCAGCCGCCACCTCTGCCCTCTCCCAGCTGGACAGACCCTGGGCCTGCACTTCAGGACTGTGGGTGCCCTGGGTGAACAGACCCTGCAGGTCCCATCCCTGGGGACAGAGGCCTTGTGTCACCTGCCTGCCCAGGCAGCTGTTTGCAGCTGAAGAAACAAACTGGTCTCCAGGCTGTCTTGCCTTTATTCCTGGTTAGGGCAGGTGGTCCTAGACAGCAGTTTCCAGTAAAAGCTGAACAAAAGA 52 1803 0.3808095025384615 9 +ENST00000378609.9 AGGGGCCCGCCGCGCCCATCCCGATGGCTGGAGGCGTCTGAGGGGCGGACGGAGGCGGCGGCGGCGGCGGCGGGAGCGGGAGCGGGCGGCGAGTGGGGAGCGGGGCCGGGAGTGGAGCAGCCGCCGCGGCGGGACTGGACCGAGCCTCGCCGGCGCGCACCTGCCCGCAGCGCCCGCGGAGCGCGCAGCGCGGCCCGAGCGCGACGACCTGCCGAGCGGCGGCCGAGGCGGCGGTGTGGGCGCGTCAGGCCGCGACGAGGGCGCTGAGACAAATTTACATGTATTGGAGACCAGACCAGAAGCCCTTCTGAATTAAGATCTCACATTCTTGAAGGTGGCATTGAAGAGCACTAAGATCGGAAGATGAGTGAGCTTGACCAGTTACGGCAGGAGGCCGAGCAACTTAAGAACCAGATTCGAGACGCCAGGAAAGCATGTGCAGATGCAACTCTCTCTCAGATCACAAACAACATCGACCCAGTGGGAAGAATCCAAATGCGCACGAGGAGGACACTGCGGGGGCACCTGGCCAAGATCTACGCCATGCACTGGGGCACAGACTCCAGGCTTCTCGTCAGTGCCTCGCAGGATGGTAAACTTATCATCTGGGACAGCTACACCACCAACAAGGTCCACGCCATCCCTCTGCGCTCCTCCTGGGTCATGACCTGTGCATATGCCCCTTCTGGGAACTATGTGGCCTGCGGTGGCCTGGATAACATTTGCTCCATTTACAATCTGAAAACTCGTGAGGGGAACGTGCGCGTGAGTCGTGAGCTGGCAGGACACACAGGTTACCTGTCCTGCTGCCGATTCCTGGATGACAATCAGATCGTCACCAGCTCTGGAGACACCACGTGTGCCCTGTGGGACATCGAGACCGGCCAGCAGACGACCACGTTTACCGGACACACTGGAGATGTCATGAGCCTTTCTCTTGCTCCTGACACCAGACTGTTCGTCTCTGGTGCTTGTGATGCTTCAGCCAAACTCTGGGATGTGCGAGAAGGCATGTGCCGGCAGACCTTCACTGGCCACGAGTCTGACATCAATGCCATTTGCTTCTTTCCAAATGGCAATGCATTTGCCACTGGCTCAGACGACGCCACCTGCAGGCTGTTTGACCTTCGTGCTGACCAGGAGCTCATGACTTACTCCCATGACAACATCATCTGCGGGATCACCTCTGTCTCCTTCTCCAAGAGCGGGCGCCTCCTCCTTGCTGGGTACGACGACTTCAACTGCAACGTCTGGGATGCACTCAAAGCCGACCGGGCAGGTGTCTTGGCTGGGCATGACAACCGCGTCAGCTGCCTGGGCGTGACTGACGATGGCATGGCTGTGGCGACAGGGTCCTGGGATAGCTTCCTCAAGATCTGGAACTAACGCCAGTAGCATGTGGATGCCATGGAGACTGGAAGACCATTCCAACTTGGACGCGTTACCATGAGAGCATATCCTATCCAACCGTACTAACGTGGACACCCTACACCTCCCCTCAGAACTTCAAAAGGGCAAGATCTTTTTTCCTTCACTTATTGCTGAAACCAAGAGCACAATTCCCATTGAGAGAAAGATCTCTGTGCTGTAAACTAAAACAAATTGTGCATTCCTTCCGGGGCCATCGTCTTTGTTTTCTTTTTTGTCTTGAATGAATTTTAAAAGGAAATATATAATAAAAATGTTAACCAGAAGGTAAACTTGAGTGTAATTGTCAGACAGACACACTTTTCCACCAGTGTATTTGAATTTTAGACCAGTGACCCTGTTTTGTGGCATTCATGCAAAACATGCTGAGGGCTTTGTTCATCTGGTCATCGTGTCCAAATTTCAGTCATGTTTGTAGCAAGATTTTGGAAGCATTCATATTTCCTTTTTAAAATGTATTCCTTTGTGTTCAACAGTTAATCAAAACCAGAGAGTCTAGGGCAGCCTCTCTGATGTTGTCAATGATGTAAATTCAGTCCCTGGTTTTTAATTTTCTGTCTGATGTCACAGATCATTGTTGCACACAAACGTGGCATAGAAAAGAACATGTTCAGAAGCCATGGGGCCAAGCACATGCGGGGACGGTCTCAAATGCGTGATCAGAGAATCCTTCACCTTTGCTGAAAAGTGAGCTCAGATCCAGCACCATGTTCCTCCTGACCCATCCTGTCTATCTTCTCAGTTGAGTTTTTAATCTCACTTTGGGTTTCCTTGTGAAGTTGGAGGGAAGTTTATAATAGCCTAACACTACCCCACCCCCAACTAGGAGGAACCTCTGTTTTCAAGAGAGATGCCTGTCCTGTGCTTGGATAGTCAGTCAATTATTTGTGTATGAAACAATGTACAAATCAATGTTTTGAAAATAATGATCTCAGACTTTCTAAGTTAAATTTTAAAAATTTTGATTGTTTGCCATATTGGGTGGGTTTACTCTTAGAATCGCATGCTGTAGAAATGCTCAAAAGTGCATATGGGACTCAGTCCTTAGGTGTTCTTTTTCTTTTAAGAAATAACCTCTTACAGTTGTAACCATTGCGGCTCTGTCCACTTCTCGTTGCTGCTCTGTGGCACATATCGGAAGCAGTACAGCGCGCGGCTCTACACGCTTGGGTAGCGGGATAAGTCACTGTTTTCTTTATTTCTTTAAAAAAAAAAAAGTTCTGTTGCAAACGACTGCTGTTGGATTCTGAGGGTGGGGAGGGAGAGAGAGGGAGGGAGAGGGAGTGAAGAGCCTGCCCTCCTATATGGATTCTTCAGGGCCCTCCACATCTGAGGTGGCTCATTCCCATCACACACAGATTGTCCTGGTGTTCATTTCAAGGCCAGTGTTCAGCAGCAGCGTTTGGAAAGCAGGTTCTGTGGGACCCCCCGCCCCGCCCCCCGCACTCCTTCATAGCAGCAGTAGTGGCTTCTCCATCCTGTTTTCTGCAACATTCTATACAAAACTGTGCTGTGACCTTGCGGTAGGCCTGGATCTGGCAAAGAGAATACAAATGAAACCCCTTCTTTCTCTTTCCGTCCAACAACTCTGTAGAGCTCTCTGCACCCTTACCCCTTTCCACCTTTTGTATTTAATTTTAAAGTCAGTGTACTGCAAGGAAGCTGGATGCAAGATAGATACTATATTAAACTGTACTGTTATTTAAGATGTAATAAAGCAGTTTGACATGAGGGA 363 1023 1.0992302917051282 8 diff --git a/skills/codonfm-finetune/evals/files/variants_labeled.csv b/skills/codonfm-finetune/evals/files/variants_labeled.csv new file mode 100644 index 0000000..674222a --- /dev/null +++ b/skills/codonfm-finetune/evals/files/variants_labeled.csv @@ -0,0 +1,21 @@ +id,ref_seq,ref_codon,alt_codon,codon_position,label +variant_00,ATGGCTGAATTTCCGTAA,GCT,GCC,1,0 +variant_01,ATGGCTGAATTTCCGTAA,GAA,GAG,2,1 +variant_02,ATGGCTGAATTTCCGTAA,GCT,GTT,1,0 +variant_03,ATGGCTGAATTTCCGTAA,GAA,GAC,2,1 +variant_04,ATGGCTGAATTTCCGTAA,GCT,GCC,1,0 +variant_05,ATGGCTGAATTTCCGTAA,GAA,GAG,2,1 +variant_06,ATGGCTGAATTTCCGTAA,GCT,GTT,1,0 +variant_07,ATGGCTGAATTTCCGTAA,GAA,GAC,2,1 +variant_08,ATGGCTGAATTTCCGTAA,GCT,GCC,1,0 +variant_09,ATGGCTGAATTTCCGTAA,GAA,GAG,2,1 +variant_10,ATGGCTGAATTTCCGTAA,GCT,GTT,1,0 +variant_11,ATGGCTGAATTTCCGTAA,GAA,GAC,2,1 +variant_12,ATGGCTGAATTTCCGTAA,GCT,GCC,1,0 +variant_13,ATGGCTGAATTTCCGTAA,GAA,GAG,2,1 +variant_14,ATGGCTGAATTTCCGTAA,GCT,GTT,1,0 +variant_15,ATGGCTGAATTTCCGTAA,GAA,GAC,2,1 +variant_16,ATGGCTGAATTTCCGTAA,GCT,GCC,1,0 +variant_17,ATGGCTGAATTTCCGTAA,GAA,GAG,2,1 +variant_18,ATGGCTGAATTTCCGTAA,GCT,GTT,1,0 +variant_19,ATGGCTGAATTTCCGTAA,GAA,GAC,2,1 diff --git a/skills/codonfm-finetune/evals/files/variants_labeled.provenance.json b/skills/codonfm-finetune/evals/files/variants_labeled.provenance.json new file mode 100644 index 0000000..57b9e09 --- /dev/null +++ b/skills/codonfm-finetune/evals/files/variants_labeled.provenance.json @@ -0,0 +1,6 @@ +{ + "purpose": "Synthetic schema fixture for input validation only", + "rows": 20, + "labels": "Arbitrary binary labels; not measured variant effects, not a scientific training dataset", + "splitting": "0.8/0.1/0.1 yields 16/2/2 rows; repeated sequence contexts make this unsuitable for performance evaluation" +} diff --git a/skills/codonfm-finetune/scripts/prepare_ribonn.py b/skills/codonfm-finetune/scripts/prepare_ribonn.py new file mode 100644 index 0000000..ed6d76d --- /dev/null +++ b/skills/codonfm-finetune/scripts/prepare_ribonn.py @@ -0,0 +1,125 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +"""Prepare public human RiboNN TE data for CodonBertDataset, without ML deps.""" + +import argparse +import csv +import http.client +import io +import json +import math +import time +from collections import Counter +from contextlib import closing +from pathlib import Path + + +DATA_REVISION = "512fca642b6b7b61ae494ad83cfc2b72831636d2" +DATA_HOST = "raw.githubusercontent.com" +DATA_PATH = ( + f"/CenikLab/TE_classic_ML/{DATA_REVISION}" + "/data/data_with_human_TE_cellline_all_NA_plain.csv" +) +DATA_URL = f"https://{DATA_HOST}{DATA_PATH}" + + +def prepare(handle, max_rows_per_split=8, max_codons=2046, deadline=None): + """Slice CDSs and keep source folds: 0-7 train, 8 val, 9 test. + + The upstream file is TSV despite its .csv suffix. A capped subset is a + preparation/smoke example, not the notebook's full cross-validation study. + """ + if max_rows_per_split < 0 or max_codons < 1: + raise ValueError("Row cap must be non-negative and max_codons must be positive") + reader = csv.DictReader(handle, delimiter="\t") + required = {"transcript_id", "tx_sequence", "utr5_size", "cds_size", "mean_te", "fold"} + if not required <= set(reader.fieldnames or []): + raise ValueError("Expected RiboNN TSV columns: " + ", ".join(sorted(required))) + rows, seen_ids, sequence_splits = [], set(), {} + counts, skipped = Counter(), Counter() + examined = 0 + for raw in reader: + examined += 1 + if deadline is not None and time.monotonic() > deadline: + raise TimeoutError("Dataset preparation exceeded the network time budget; use --input for an offline file") + try: + start, length, fold = int(raw["utr5_size"]), int(raw["cds_size"]), int(raw["fold"]) + value = float(raw["mean_te"]) + transcript = raw["tx_sequence"].upper().replace("U", "T") + row_id = raw["transcript_id"].strip() + except (TypeError, ValueError, AttributeError): + skipped["invalid_metadata"] += 1 + continue + if not row_id or start < 0 or length <= 0 or start + length > len(transcript) or length % 3: + skipped["invalid_cds_bounds_or_id"] += 1 + continue + sequence = transcript[start:start + length] + if set(sequence) - set("ACGT") or not math.isfinite(value) or fold not in range(10): + skipped["invalid_sequence_label_or_fold"] += 1 + continue + if length // 3 > max_codons: + skipped["cds_exceeds_context"] += 1 + continue + split = "val" if fold == 8 else "test" if fold == 9 else "train" + if row_id in seen_ids: + skipped["duplicate_transcript"] += 1 + continue + if sequence in sequence_splits and sequence_splits[sequence] != split: + raise ValueError("Identical CDS appears in different source folds; resolve split leakage before training") + seen_ids.add(row_id) + sequence_splits[sequence] = split + if max_rows_per_split and counts[split] >= max_rows_per_split: + continue + rows.append({"id": row_id, "ref_seq": sequence, "value": value, "split": split}) + counts[split] += 1 + if max_rows_per_split and all(counts[s] >= max_rows_per_split for s in ("train", "val", "test")): + break + if not all(counts[s] for s in ("train", "val", "test")): + raise ValueError("Prepared data must have non-empty train, val, and test splits; check source folds 0-9") + return rows, { + "rows_examined": examined, "rows_written": len(rows), "split_counts": dict(counts), + "skipped": dict(skipped), "label": "mean_te (unchanged)", + "fold_mapping": {"train": list(range(8)), "val": [8], "test": [9]}, + "max_rows_per_split": max_rows_per_split, "max_codons": max_codons, + "purpose": "input preparation; a capped subset is not a scientific benchmark", + } + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--input", type=Path, help="Existing upstream-format TSV; omit to stream the pinned public data") + parser.add_argument("--output", type=Path, required=True) + parser.add_argument("--max-rows-per-split", type=int, default=8, help="Default 8 for a small example; 0 processes all rows") + parser.add_argument("--max-codons", type=int, default=2046) + args = parser.parse_args() + if args.input and args.input.resolve() == args.output.resolve(): + parser.error("Input and output must be different files") + try: + if args.input: + with args.input.open(encoding="utf-8-sig", newline="") as handle: + rows, report = prepare(handle, args.max_rows_per_split, args.max_codons) + else: + # Fixed HTTPS endpoint with default certificate verification; no redirects or retries. + deadline = time.monotonic() + 60 + with closing(http.client.HTTPSConnection(DATA_HOST, timeout=10)) as connection: + connection.request("GET", DATA_PATH) + with connection.getresponse() as response: + if response.status != 200: + raise ValueError(f"Dataset download returned HTTP {response.status}; expected 200 without redirects") + with io.TextIOWrapper(response, encoding="utf-8-sig", newline="") as handle: + rows, report = prepare(handle, args.max_rows_per_split, args.max_codons, deadline) + report.update({"source": str(args.input) if args.input else DATA_URL, "upstream_url": DATA_URL}) + args.output.parent.mkdir(parents=True, exist_ok=True) + with args.output.open("w", newline="", encoding="utf-8") as handle: + writer = csv.DictWriter(handle, fieldnames=["id", "ref_seq", "value", "split"]) + writer.writeheader() + writer.writerows(rows) + args.output.with_suffix(".metadata.json").write_text(json.dumps(report, indent=2) + "\n", encoding="utf-8") + except (ValueError, OSError, http.client.HTTPException) as exc: + parser.exit(1, f"Preparation failed: {exc}\n") + print(json.dumps(report, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/skills/codonfm-score/SKILL.md b/skills/codonfm-score/SKILL.md new file mode 100644 index 0000000..2bd51f6 --- /dev/null +++ b/skills/codonfm-score/SKILL.md @@ -0,0 +1,132 @@ +--- +name: codonfm-score +description: Score synonymous or missense coding variants with public CodonFM Encodon checkpoints using masked-codon reference-versus-alternate log-likelihood ratios. Use when a user explicitly asks for CodonFM or Encodon zero-shot variant scoring. Support the public mutation_prediction workflow only; reject Decodon and the newer synonymous-codon-aggregated missense_prediction workflow because they are not present in public CodonFM v1. +metadata: + author: "NVIDIA BioNeMo " +--- + +# Score variants with public Encodon + +Run general masked-codon `mutation_prediction` only. This produces a research +signal, not a clinical diagnosis or an expression-direction prediction. + +## Instructions + +Check whether the request is executable in public v1 before installing or +downloading anything. For synonymous-codon aggregation or Decodon, inspect the +[parser](../../src/runner.py) and [model configuration](../../src/config.py), +explain the missing feature, and finish. Do not implement the missing workflow, +search private code, or keep retrying unsupported commands. + +Resolve the variant CSV, checkpoint, and output directory from the request and +available files. Validate inputs before inference. Execution requires the +project's ML dependencies and a compatible NVIDIA GPU. If a required resource +is unavailable, return the validated inputs where possible and a command with +the missing prerequisite identified. When scoring is requested and resources +are ready, execute and verify the score arrays. A request for preparation ends +with the inputs and command. If variants are missing, report the required +schema; do not invent variants or silently switch to a public dataset. + +Default to the public 80M checkpoint for demonstrations: +`nvidia/NV-CodonFM-Encodon-80M-v1`, revision +`399ca9fe17b57941a7bebc6788033919b417413c`, file +`NV-CodonFM-Encodon-80M-v1.safetensors` and sibling `config.json`. +Reuse an existing checkpoint or download it when needed for the requested work. +Preserve an explicitly requested model size. + +## Preflight + +1. Confirm `src/runner.py`, `src/data/mutation_dataset.py`, and + `src/inference/encodon.py` exist. +2. Accept only `encodon_80m`, `encodon_600m`, or `encodon_1b` as + `--model_name`. The public parser lists larger names, but its model + configuration does not implement them. +3. For model execution, require a `.ckpt` file, or a `.safetensors` file with + sibling `config.json`. Input preparation can use a planned path. +4. Validate the CSV headers before starting a GPU job. + +## Inputs + +Require these CSV columns: + +- `id`: unique row identifier. +- `ref_seq`: reference coding sequence, not genomic DNA with introns, UTR-only + sequence, or protein sequence. +- `ref_codon` and `alt_codon`: three-nucleotide codons. +- `codon_position`: zero-based codon position relative to the CDS. + +With `--extract-seq`, `MutationDataset` extracts an appropriate sequence window +from `ref_seq`; it does not derive or require `alt_seq`. + +Before running, normalize sequences and codons to uppercase DNA (`A/C/G/T`), +require CDS lengths divisible by three, and check every row satisfies: + +```text +0 <= codon_position < len(ref_seq) / 3 +ref_seq[3 * codon_position : 3 * codon_position + 3] == ref_codon +``` + +The public extractor asserts the second condition and otherwise stops the job. + +## Examples + +Set `CODONFM_DATA_PATH` to the variant CSV, `CODONFM_CHECKPOINT_PATH` to the +checkpoint, and `CODONFM_RUN_DIR` to your chosen output directory: + +```bash +python -m src.runner eval \ + --exp_name variant_scoring \ + --model_name encodon_80m \ + --checkpoint_path "$CODONFM_CHECKPOINT_PATH" \ + --data_path "$CODONFM_DATA_PATH" \ + --process_item mutation_pred_mlm \ + --dataset_name MutationDataset \ + --task_type mutation_prediction \ + --extract-seq \ + --mask_mutation \ + --num_nodes 1 \ + --num_gpus 1 \ + --num_workers 0 \ + --val_batch_size 2 \ + --out_dir "$CODONFM_RUN_DIR" \ + --predictions_output_dir "$CODONFM_RUN_DIR/predictions" +``` + +Do not remove `--mask_mutation`: without it, the reference codon remains +visible at the scored position and invalidates masked-codon LLR scoring. +For preparation requests, inspect the CSV directly against the input schema +and reference-position checks above, then report the rows checked and provide +the scoring command. Extra columns are allowed; use `--ref_seq_col` if the +reference sequence has a different column name. These checks do not require +the ML runtime. The command above performs inference when resources are ready. + +The existing `--dryrun` optionally builds runtime configuration and skips +execution. It requires the ML dependencies, can create the prediction directory, +and does not read the CSV or load weights. Do not use it as evidence that inputs, +checkpoint compatibility, or prediction quality have been validated. + +## Outputs + +`--predictions_output_dir` receives: + +- `ref_likelihoods_merged.npy` +- `alt_likelihoods_merged.npy` +- `likelihood_ratios_merged.npy` +- `ids_merged.npy` + +Load the arrays with NumPy and align scores by `ids_merged.npy`. The reported +LLR is `log p(ref_codon) - log p(alt_codon)`; a larger positive value means the +alternate codon is less probable in context. It does not say whether +expression goes up or down. + +## Boundaries + +- General `mutation_prediction` handles both synonymous and missense changes. +- Do not use `missense_prediction`, `missense_inference`, `MissenseDataset`, + `mutation_pred_clm`, `--organism_token`, or `--causal`; those are newer + unavailable public-release features. +- If a user asks specifically for synonymous-codon-aggregated missense + scoring, explain that public v1 only provides the general ref/alt LLR. Do not + silently substitute the two methods. +- Do not invoke this skill for a bare “score this variant” request that does + not name CodonFM or Encodon. diff --git a/skills/codonfm-score/agents/openai.yaml b/skills/codonfm-score/agents/openai.yaml new file mode 100644 index 0000000..7dba4a4 --- /dev/null +++ b/skills/codonfm-score/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "CodonFM Variant Scoring" + short_description: "Score coding variants with public Encodon models" + default_prompt: "Use $codonfm-score to validate and score coding variants with a public Encodon checkpoint." diff --git a/skills/codonfm-score/evals/evals.json b/skills/codonfm-score/evals/evals.json new file mode 100644 index 0000000..d1584f0 --- /dev/null +++ b/skills/codonfm-score/evals/evals.json @@ -0,0 +1,51 @@ +{ + "skill_name": "codonfm-score", + "evals": [ + { + "id": "codonfm-score-001", + "prompt": "Validate the supplied variants.csv and prepare an Encodon masked-codon scoring command. Explain the output files and how to interpret the score sign. Use the supplied public source and checkpoint metadata; the two variants are synthetic examples.", + "files": [ + "files/codonfm_source.zip", + "files/encodon_checkpoint.json", + "files/variants.csv" + ], + "expected_output": "Two validated variant rows and a public mutation_prediction command, with the correct output contract and reference-versus-alternate score interpretation.", + "assertions": [ + "The command uses mutation_prediction, mutation_pred_mlm, and MutationDataset", + "The command includes --mask_mutation, --extract-seq, --checkpoint_path, and explicit prediction/output paths", + "The agent validates both variant rows, including reference codon agreement at the zero-based CDS position", + "The response identifies ref_likelihoods_merged.npy, alt_likelihoods_merged.npy, likelihood_ratios_merged.npy, and ids_merged.npy as expected inference outputs", + "The agent defines LLR as log p(ref_codon) minus log p(alt_codon), does not equate it with expression direction or clinical effect, and does not fabricate scores" + ], + "expected_skill": "codonfm-score", + "expected_script": null + }, + { + "id": "codonfm-score-002", + "prompt": "Can I run synonymous-codon-aggregated missense_prediction with public CodonFM? Check the supplied source and explain how this relates to the available variant-scoring method.", + "files": [ + "files/codonfm_source.zip", + "files/encodon_checkpoint.json" + ], + "expected_output": "The agent explains that the aggregation workflow is unavailable and distinguishes it from ordinary masked reference/alternate codon LLR scoring.", + "assertions": [ + "The agent identifies missense_prediction and missense_inference as unavailable in the supplied public implementation", + "The agent cites inspected source and distinguishes general mutation_prediction from synonymous-codon aggregation", + "The agent answers the compatibility question without implementing a missing feature or silently substituting the available method" + ], + "expected_skill": "codonfm-score", + "expected_script": null + }, + { + "id": "codonfm-score-003", + "prompt": "Score this variant.", + "expected_output": "The agent requests the missing variant and analysis context without assuming CodonFM.", + "assertions": [ + "The agent does not invoke a codonfm-* skill without CodonFM or Encodon context", + "The agent identifies missing inputs without inventing a variant or choosing a model" + ], + "expected_skill": null, + "expected_script": null + } + ] +} diff --git a/skills/codonfm-score/evals/files/codonfm_source.zip b/skills/codonfm-score/evals/files/codonfm_source.zip new file mode 100644 index 0000000..eb76611 Binary files /dev/null and b/skills/codonfm-score/evals/files/codonfm_source.zip differ diff --git a/skills/codonfm-score/evals/files/encodon_checkpoint.json b/skills/codonfm-score/evals/files/encodon_checkpoint.json new file mode 100644 index 0000000..6c6230d --- /dev/null +++ b/skills/codonfm-score/evals/files/encodon_checkpoint.json @@ -0,0 +1,33 @@ +{ + "repo_id": "nvidia/NV-CodonFM-Encodon-80M-v1", + "revision": "399ca9fe17b57941a7bebc6788033919b417413c", + "model_name": "encodon_80m", + "filename": "NV-CodonFM-Encodon-80M-v1.safetensors", + "size_bytes": 307351588, + "config_filename": "config.json", + "config": { + "vocab_size": 69, + "hidden_size": 1024, + "num_hidden_layers": 6, + "num_attention_heads": 8, + "intermediate_size": 4096, + "hidden_act": "gelu", + "hidden_dropout_prob": 0.1, + "attention_probs_dropout_prob": 0.1, + "initializer_range": 0.02, + "layer_norm_eps": 1e-12, + "pad_token_id": 3, + "position_embedding_type": "rotary", + "classifier_dropout": 0.1, + "rotary_theta": 10000.0, + "ignore_index": -100, + "loss_type": "cross_entropy", + "lora": false, + "lora_alpha": 32.0, + "lora_r": 16, + "lora_dropout": 0.1, + "finetune_strategy": "full" + }, + "source_url": "https://huggingface.co/nvidia/NV-CodonFM-Encodon-80M-v1/tree/399ca9fe17b57941a7bebc6788033919b417413c", + "weights_included": false +} diff --git a/skills/codonfm-score/evals/files/variants.csv b/skills/codonfm-score/evals/files/variants.csv new file mode 100644 index 0000000..18ce7b5 --- /dev/null +++ b/skills/codonfm-score/evals/files/variants.csv @@ -0,0 +1,3 @@ +id,ref_seq,ref_codon,alt_codon,codon_position +variant_00,ATGGCTGAATTTCCGTAA,GCT,GCC,1 +variant_01,ATGGCTGAATTTCCGTAA,GAA,GAG,2 diff --git a/skills/codonfm-setup/SKILL.md b/skills/codonfm-setup/SKILL.md new file mode 100644 index 0000000..5b343f9 --- /dev/null +++ b/skills/codonfm-setup/SKILL.md @@ -0,0 +1,153 @@ +--- +name: codonfm-setup +description: Set up the public CodonFM v1 repository and download public Encodon checkpoints. Use for requests to build or launch the CodonFM development container, configure local data/checkpoint mounts, verify GPU access, or download public Encodon 80M, 600M, 1B, or Cdwt-1B weights. Do not use for Decodon, Encodon 5B/10B, missense-aggregation, or codon-optimization setup because those implementations are not in the public repository. +metadata: + author: "NVIDIA BioNeMo " +--- + +# CodonFM public setup + +Operate from the public CodonFM repository root. Support only the checked-in +public v1 code and public Encodon checkpoints. + +## Instructions + +Determine whether the user wants instructions, a downloaded checkpoint, or a +working model environment. Inspect the [runner](../../src/runner.py), +[model configuration](../../src/config.py), [Dockerfile](../../Dockerfile), +[launcher](../../run_dev.sh), and [requirements](../../requirements.txt). +Reuse available environments and checkpoints, and choose paths from the user's +project. Follow the requested scope: instructions do not require installation; +checkpoint downloads do not require a GPU; actual model execution requires the +ML dependencies and a compatible NVIDIA GPU. + +Check hardware before installing the runtime: use `nvidia-smi` if available, or +check CUDA through an existing PyTorch installation. If a prerequisite cannot +be met, complete independent setup steps and report what is still missing. +Check supplied files and configuration directly when preparing setup instructions. +The existing runner's optional `--dryrun` builds runtime configuration with +the ML dependencies installed, then stops before execution. It does not validate +CSV data or load weights, and setup instructions do not require running it. +Public Decodon is unavailable: inspect local source and explain the boundary +without attempting an unsupported installation. + +## Preflight + +1. Confirm `Dockerfile`, `run_dev.sh`, and `src/runner.py` exist. +2. For container execution, confirm `docker info` succeeds and `nvidia-smi` + sees the intended GPU. Direct-host setup does not require Docker. +3. Run `bash -n run_dev.sh` before launching it. +4. Resolve explicit host paths for data and checkpoints. Do not rely on the + `/data/codonfm` defaults unless the user confirms they exist. +5. Check for an existing container before launch: + +```bash +docker ps -a --filter name='^/codon-fm-dev-container$' +``` + +If an exact-name container is running, `run_dev.sh` stops and removes it; tell +the user before replacement. If it is stopped, the script cannot reuse the +name, so obtain confirmation before removing it with +`docker rm codon-fm-dev-container`. The public script also uses host +networking/IPC and mounts the user's SSH directory read-only; disclose this +before execution. + +## Build and launch + +```bash +cd "$CODONFM_REPO_DIR" +bash run_dev.sh \ + --data-dir "$CODONFM_DATA_DIR" \ + --checkpoints-dir "$CODONFM_CHECKPOINT_DIR" +``` + +The host checkpoint directory is mounted at `/data/checkpoints` inside the +container. The image is `codon-fm-dev`; the container is +`codon-fm-dev-container`. + +Set `CODONFM_REPO_DIR`, `CODONFM_DATA_DIR`, and `CODONFM_CHECKPOINT_DIR` to +existing absolute paths chosen for the project. + +Use only the checked-in public code and the dependency versions declared in +its `Dockerfile` and `requirements.txt`. + +## Run directly without Docker + +Use this path when Docker is unavailable and the host has a compatible NVIDIA +driver. The example below uses Python 3.11, CUDA-capable PyTorch, and one GPU. +Operate from a writable checkout and use a dedicated virtual environment: + +```bash +cd "$CODONFM_REPO_DIR" +python3.11 -m venv .venv +. .venv/bin/activate +python -m pip install --upgrade pip +python -m pip install -r requirements.txt +mkdir -p "$CODONFM_CACHE_DIR/matplotlib" +export MPLCONFIGDIR="$CODONFM_CACHE_DIR/matplotlib" +python -c "import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))" +``` + +Set `CODONFM_CACHE_DIR` to a writable cache directory. Expect `True` and the +selected GPU name. The requirements file configures the +CUDA 12.4 PyTorch index for xFormers. Use explicit host paths in all subsequent +runner commands; unlike the container path, no `/data/checkpoints` mount is +created. + +## Examples + +For a small demonstration, prefer the original public Encodon 80M weights: + +```bash +hf download nvidia/NV-CodonFM-Encodon-80M-v1 \ + NV-CodonFM-Encodon-80M-v1.safetensors config.json \ + --revision 399ca9fe17b57941a7bebc6788033919b417413c \ + --local-dir "$CODONFM_CHECKPOINT_DIR/encodon-80m" +``` + +The [checkpoint](https://huggingface.co/nvidia/NV-CodonFM-Encodon-80M-v1/tree/main) +is publicly accessible without a gated-model approval, and the weight file is +307,351,588 bytes. It need not be mirrored to GitHub LFS. The `-TE-` model IDs +use TransformerEngine in `bionemo-recipes`; use the original model IDs with this +public CodonFM codebase. Download only the weights and `config.json`, and reuse +an existing local checkpoint. + +## Download a checkpoint + +Run inside the container, or in another environment with Hugging Face Hub: + +```bash +hf download nvidia/NV-CodonFM-Encodon-1B-v1 \ + --local-dir /data/checkpoints/encodon-1b +``` + +Other supported public model IDs are: + +- `nvidia/NV-CodonFM-Encodon-80M-v1` +- `nvidia/NV-CodonFM-Encodon-600M-v1` +- `nvidia/NV-CodonFM-Encodon-Cdwt-1B-v1` + +Use `--model_name encodon_80m`, `encodon_600m`, or `encodon_1b` according to +architecture size. Cdwt-1B uses `encodon_1b` because Cdwt is a checkpoint +training property, not a separate architecture. + +For `.safetensors`, keep `config.json` in the same directory as the model +file. Never invent a Decodon or undocumented checkpoint path. + +## Verify + +```bash +docker exec codon-fm-dev-container python -c \ + "import torch; print(torch.cuda.is_available())" +``` + +Expect `True` on a configured NVIDIA GPU host. If Docker or a GPU is +unavailable, report the missing prerequisite; do not claim setup succeeded. + +## Public-v1 boundaries + +- Supported: Encodon 80M, 600M, 1B, and Cdwt-1B. +- Not supported: Decodon, Encodon 5B/10B, sequence generation, specialized + missense aggregation/fine-tuning, and `scripts/codon_optimize.py`. +- CodonFM consumes coding sequences. It is not a variant caller, aligner, GTF + annotator, or general VCF analysis tool. diff --git a/skills/codonfm-setup/agents/openai.yaml b/skills/codonfm-setup/agents/openai.yaml new file mode 100644 index 0000000..4c7925b --- /dev/null +++ b/skills/codonfm-setup/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "CodonFM Setup" + short_description: "Set up public CodonFM and Encodon checkpoints" + default_prompt: "Use $codonfm-setup to configure the public CodonFM environment and download an Encodon checkpoint." diff --git a/skills/codonfm-setup/evals/evals.json b/skills/codonfm-setup/evals/evals.json new file mode 100644 index 0000000..e5ac568 --- /dev/null +++ b/skills/codonfm-setup/evals/evals.json @@ -0,0 +1,54 @@ +{ + "skill_name": "codonfm-setup", + "evals": [ + { + "id": "codonfm-setup-001", + "prompt": "Prepare instructions for setting up public CodonFM in its development container and downloading Encodon 80M. Use the supplied source and checkpoint metadata. Explain the prerequisites, host directories, and checkpoint location inside the container.", + "files": [ + "files/codonfm_source.zip", + "files/encodon_checkpoint.json" + ], + "expected_output": "Setup and download instructions using the original public Encodon 80M checkpoint, its configuration file, and the checked-in container launcher, with accurate prerequisites and mount paths.", + "assertions": [ + "The download command uses nvidia/NV-CodonFM-Encodon-80M-v1, the supplied revision, NV-CodonFM-Encodon-80M-v1.safetensors, and config.json", + "The launcher command uses run_dev.sh with explicit host data/checkpoint directories and explains the /data/checkpoints mount", + "The agent explains existing-container replacement behavior before any proposed launch", + "The response explains Docker and GPU requirements for model execution and does not claim that setup instructions prove a working environment" + ], + "expected_skill": "codonfm-setup", + "expected_script": null + }, + { + "id": "codonfm-setup-002", + "prompt": "Can I use the public CodonFM repository for Decodon sequence generation? Check the supplied source before recommending a setup procedure.", + "files": [ + "files/codonfm_source.zip", + "files/encodon_checkpoint.json" + ], + "expected_output": "The agent identifies Decodon generation as unavailable in the supplied public implementation and does not invent a checkpoint or setup procedure.", + "assertions": [ + "The agent identifies Decodon as unavailable in the provided public model configuration", + "The agent does not recommend an undocumented Decodon download or implement the missing feature" + ], + "expected_skill": "codonfm-setup", + "expected_script": null + }, + { + "id": "codonfm-setup-003", + "prompt": "Prepare instructions for installing public CodonFM directly on a CUDA host where Docker is unavailable. Use the supplied source and checkpoint metadata. Include environment setup, checkpoint paths, and checks to run before model execution.", + "files": [ + "files/codonfm_source.zip", + "files/encodon_checkpoint.json" + ], + "expected_output": "Direct-host setup instructions using the public dependencies, a Python 3.11 virtual environment, writable cache, and CUDA verification, with user-chosen checkpoint paths.", + "assertions": [ + "The instructions use python3.11 -m venv and python -m pip install -r requirements.txt", + "The instructions set MPLCONFIGDIR to a writable location and provide torch.cuda.is_available verification", + "The agent uses the direct-host path without requiring Docker", + "The response clearly identifies verification still needed before claiming the environment is ready for model execution" + ], + "expected_skill": "codonfm-setup", + "expected_script": null + } + ] +} diff --git a/skills/codonfm-setup/evals/files/codonfm_source.zip b/skills/codonfm-setup/evals/files/codonfm_source.zip new file mode 100644 index 0000000..eb76611 Binary files /dev/null and b/skills/codonfm-setup/evals/files/codonfm_source.zip differ diff --git a/skills/codonfm-setup/evals/files/encodon_checkpoint.json b/skills/codonfm-setup/evals/files/encodon_checkpoint.json new file mode 100644 index 0000000..6c6230d --- /dev/null +++ b/skills/codonfm-setup/evals/files/encodon_checkpoint.json @@ -0,0 +1,33 @@ +{ + "repo_id": "nvidia/NV-CodonFM-Encodon-80M-v1", + "revision": "399ca9fe17b57941a7bebc6788033919b417413c", + "model_name": "encodon_80m", + "filename": "NV-CodonFM-Encodon-80M-v1.safetensors", + "size_bytes": 307351588, + "config_filename": "config.json", + "config": { + "vocab_size": 69, + "hidden_size": 1024, + "num_hidden_layers": 6, + "num_attention_heads": 8, + "intermediate_size": 4096, + "hidden_act": "gelu", + "hidden_dropout_prob": 0.1, + "attention_probs_dropout_prob": 0.1, + "initializer_range": 0.02, + "layer_norm_eps": 1e-12, + "pad_token_id": 3, + "position_embedding_type": "rotary", + "classifier_dropout": 0.1, + "rotary_theta": 10000.0, + "ignore_index": -100, + "loss_type": "cross_entropy", + "lora": false, + "lora_alpha": 32.0, + "lora_r": 16, + "lora_dropout": 0.1, + "finetune_strategy": "full" + }, + "source_url": "https://huggingface.co/nvidia/NV-CodonFM-Encodon-80M-v1/tree/399ca9fe17b57941a7bebc6788033919b417413c", + "weights_included": false +} diff --git a/skills/stage_eval_context.py b/skills/stage_eval_context.py new file mode 100644 index 0000000..29707bc --- /dev/null +++ b/skills/stage_eval_context.py @@ -0,0 +1,49 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +"""Refresh the identical public source fixtures given to both Harbor conditions. + +Run after changing src/, Dockerfile, run_dev.sh, or requirements.txt. These +small deterministic ZIPs contain code, not skills, answers, weights, or deps. +""" + +import hashlib +import io +import json +import zipfile +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] + + +def build_context(): + paths = sorted((ROOT / "src").rglob("*.py")) + paths += [ROOT / name for name in ("Dockerfile", "run_dev.sh", "requirements.txt")] + contents = {path.relative_to(ROOT).as_posix(): path.read_bytes() for path in paths} + contents["source-manifest.json"] = (json.dumps({ + "repository": "https://github.com/NVIDIA-BioNeMo/CodonFM", + "purpose": "Public source snapshot for input preparation and API inspection; no weights or dependencies included", + "sha256": {name: hashlib.sha256(data).hexdigest() for name, data in sorted(contents.items())}, + }, indent=2) + "\n").encode() + buffer = io.BytesIO() + with zipfile.ZipFile(buffer, "w", compression=zipfile.ZIP_DEFLATED) as archive: + for name, data in sorted(contents.items()): + info = zipfile.ZipInfo(name, date_time=(2026, 1, 1, 0, 0, 0)) + info.compress_type = zipfile.ZIP_DEFLATED + info.external_attr = 0o644 << 16 + archive.writestr(info, data) + return buffer.getvalue() + + +def main(): + data = build_context() + for skill in sorted((ROOT / "skills").glob("codonfm-*")): + dest = skill / "evals/files/codonfm_source.zip" + dest.parent.mkdir(parents=True, exist_ok=True) + dest.write_bytes(data) + print(f"{dest.relative_to(ROOT)}: {len(data)} bytes") + + +if __name__ == "__main__": + main() diff --git a/src/tasks.py b/src/tasks.py index 0a8d48c..57c403f 100644 --- a/src/tasks.py +++ b/src/tasks.py @@ -157,10 +157,19 @@ def evaluate( model.configure_model() data.setup("test") - if os.path.exists(model_ckpt_path): + # Safetensors files contain model weights only. Loading one again through + # torch.load() raises an unpickling error, so only inspect Lightning + # checkpoints for an optional datamodule state. + if ( + os.path.exists(model_ckpt_path) + and Path(model_ckpt_path).suffix.lower() == ".ckpt" + ): logging.info(f"Loading dataset checkpoint from {model_ckpt_path}") - data.load_state_dict(torch.load(model_ckpt_path)) - model.prediction_counter = data.init_global_step + checkpoint = torch.load(model_ckpt_path, map_location="cpu") + datamodule_state = checkpoint.get(data.__class__.__qualname__) + if datamodule_state is not None: + data.load_state_dict(datamodule_state) + model.prediction_counter = data.init_global_step trainer.logger = logger trainer.callbacks = list(callbacks.values()) @@ -169,4 +178,4 @@ def evaluate( trainer.predict(model, datamodule=data, return_predictions=False) - return \ No newline at end of file + return diff --git a/tests/skills/test_public_skills.py b/tests/skills/test_public_skills.py new file mode 100644 index 0000000..d6585be --- /dev/null +++ b/tests/skills/test_public_skills.py @@ -0,0 +1,397 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +"""Static contract tests for the public CodonFM skills. + +These tests intentionally use only the Python standard library so command +usage can be checked before installing the GPU runtime. +""" + +import argparse +import ast +import csv +import hashlib +import importlib.util +import io +import json +import re +import shlex +import ssl +import subprocess +import sys +import tempfile +import unittest +import zipfile +from contextlib import redirect_stderr, redirect_stdout +from pathlib import Path +from unittest.mock import patch + + +REPO_ROOT = Path(__file__).resolve().parents[2] +SKILLS_ROOT = REPO_ROOT / "skills" +PUBLIC_SKILLS = { + "codonfm-setup", + "codonfm-score", + "codonfm-embed", + "codonfm-finetune", +} + + +def _frontmatter(skill_text: str) -> dict[str, str]: + match = re.match(r"\A---\n(.*?)\n---\n", skill_text, re.DOTALL) + if match is None: + raise AssertionError("SKILL.md is missing YAML frontmatter") + result = {} + for line in match.group(1).splitlines(): + if line.startswith(" "): + continue + key, separator, value = line.partition(":") + if not separator: + raise AssertionError(f"Invalid frontmatter line: {line}") + result[key.strip()] = value.strip() + return result + + +def _runner_commands(skill_text: str) -> list[list[str]]: + commands = [] + for block in re.findall(r"```bash\n(.*?)```", skill_text, re.DOTALL): + normalized = block.replace("\\\n", " ") + tokens = shlex.split(normalized, comments=True) + for index in range(len(tokens) - 3): + if tokens[index:index + 3] == ["python", "-m", "src.runner"]: + commands.append(tokens[index + 3:]) + break + return commands + + +def _public_runner_parser() -> argparse.ArgumentParser: + """Build the checked-in parser without importing the runner's GPU deps.""" + tree = ast.parse((REPO_ROOT / "src/runner.py").read_text()) + get_parser = next( + node + for node in tree.body + if isinstance(node, ast.FunctionDef) and node.name == "get_parser" + ) + parser_module = ast.Module(body=[get_parser], type_ignores=[]) + namespace = {"argparse": argparse} + exec(compile(parser_module, "src/runner.py", "exec"), namespace) + return namespace["get_parser"]() + + +def _evaluate_function(namespace): + """Load only tasks.evaluate so it can be tested without GPU packages.""" + tree = ast.parse((REPO_ROOT / "src/tasks.py").read_text()) + evaluate = next( + node + for node in tree.body + if isinstance(node, ast.FunctionDef) and node.name == "evaluate" + ) + module = ast.Module(body=[evaluate], type_ignores=[]) + exec(compile(module, "src/tasks.py", "exec"), namespace) + return namespace["evaluate"] + + +def _ribonn_helper(): + path = SKILLS_ROOT / "codonfm-finetune/scripts/prepare_ribonn.py" + spec = importlib.util.spec_from_file_location("prepare_ribonn", path) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +class PublicSkillContractTests(unittest.TestCase): + def test_expected_public_skill_set(self): + actual = { + path.name + for path in SKILLS_ROOT.iterdir() + if path.is_dir() and (path / "SKILL.md").exists() + } + self.assertTrue(PUBLIC_SKILLS.issubset(actual)) + self.assertFalse((SKILLS_ROOT / "codonfm-optimize").exists()) + + def test_frontmatter_and_ui_metadata(self): + for skill_name in PUBLIC_SKILLS: + with self.subTest(skill=skill_name): + skill_dir = SKILLS_ROOT / skill_name + text = (skill_dir / "SKILL.md").read_text() + metadata = _frontmatter(text) + self.assertEqual(set(metadata), {"name", "description", "metadata"}) + self.assertEqual(metadata["name"], skill_name) + self.assertNotIn("TODO", text) + + ui = (skill_dir / "agents/openai.yaml").read_text() + self.assertIn("display_name:", ui) + self.assertIn("short_description:", ui) + self.assertIn(f"${skill_name}", ui) + + def test_evals_are_valid_and_named(self): + for skill_name in PUBLIC_SKILLS: + with self.subTest(skill=skill_name): + eval_path = SKILLS_ROOT / skill_name / "evals/evals.json" + payload = json.loads(eval_path.read_text()) + self.assertEqual(payload["skill_name"], skill_name) + self.assertGreater(len(payload["evals"]), 0) + ids = [case["id"] for case in payload["evals"]] + self.assertEqual(len(ids), len(set(ids))) + + def test_eval_inputs_exist_and_source_fixtures_match_repository(self): + expected_archive = None + for skill_name in sorted(PUBLIC_SKILLS): + evals = SKILLS_ROOT / skill_name / "evals" + payload = json.loads((evals / "evals.json").read_text()) + for case in payload["evals"]: + for relative in case.get("files", []): + path = (evals / relative).resolve() + self.assertTrue(path.is_relative_to(evals.resolve())) + self.assertTrue(path.is_file(), str(path)) + archive_path = evals / "files/codonfm_source.zip" + data = archive_path.read_bytes() + if expected_archive is not None: + self.assertEqual(data, expected_archive, "Trials must receive identical public source") + expected_archive = data + with zipfile.ZipFile(archive_path) as archive: + manifest = json.loads(archive.read("source-manifest.json")) + for name, sha in manifest["sha256"].items(): + self.assertEqual(archive.read(name), (REPO_ROOT / name).read_bytes(), + "Refresh source fixtures with python skills/stage_eval_context.py") + self.assertEqual(hashlib.sha256(archive.read(name)).hexdigest(), sha) + self.assertFalse(any(name.startswith("skills/") or name.endswith(".safetensors") + for name in archive.namelist())) + + def test_ribonn_preparation_preserves_data_without_runtime_dependencies(self): + files = SKILLS_ROOT / "codonfm-finetune/evals/files" + helper = SKILLS_ROOT / "codonfm-finetune/scripts/prepare_ribonn.py" + with tempfile.TemporaryDirectory() as tmp: + output = Path(tmp) / "prepared.csv" + result = subprocess.run([sys.executable, "-S", str(helper), "--input", + str(files / "ribonn_smoke.tsv"), "--output", str(output)], + cwd=REPO_ROOT, capture_output=True, text=True, timeout=10) + self.assertEqual(result.returncode, 0, result.stderr) + report = json.loads(result.stdout) + self.assertEqual(report["split_counts"], {"train": 8, "val": 2, "test": 2}) + self.assertEqual(json.loads(output.with_suffix(".metadata.json").read_text()), report) + with (files / "ribonn_smoke.tsv").open() as handle: + raw = {row["transcript_id"]: row for row in csv.DictReader(handle, delimiter="\t")} + with output.open() as handle: + rows = list(csv.DictReader(handle)) + self.assertEqual(len(rows), 12) + for row in rows: + source = raw[row["id"]] + start, length = int(source["utr5_size"]), int(source["cds_size"]) + self.assertEqual(row["ref_seq"], source["tx_sequence"][start:start + length]) + self.assertEqual(float(row["value"]), float(source["mean_te"])) + fold = int(source["fold"]) + self.assertEqual(row["split"], "val" if fold == 8 else "test" if fold == 9 else "train") + + def test_ribonn_download_requires_direct_https_success(self): + helper = _ribonn_helper() + fixture = (SKILLS_ROOT / "codonfm-finetune/evals/files/ribonn_smoke.tsv").read_bytes() + for status in (200, 301, 302, 303, 307, 308, 404, 500): + with self.subTest(status=status), tempfile.TemporaryDirectory() as tmp: + output = Path(tmp) / "prepared.csv" + response = io.BytesIO(fixture) + response.status = status + with ( + patch.object(helper.http.client, "HTTPSConnection") as https, + patch.object(sys, "argv", ["prepare_ribonn.py", "--output", str(output)]), + redirect_stdout(io.StringIO()) as stdout, + redirect_stderr(io.StringIO()) as stderr, + ): + connection = https.return_value + connection.getresponse.return_value = response + if status == 200: + helper.main() + report = json.loads(stdout.getvalue()) + self.assertEqual(report["split_counts"], {"train": 8, "val": 2, "test": 2}) + self.assertEqual(report["source"], helper.DATA_URL) + self.assertTrue(output.is_file()) + else: + with self.assertRaises(SystemExit) as failure: + helper.main() + self.assertEqual(failure.exception.code, 1) + self.assertIn(f"HTTP {status}", stderr.getvalue()) + self.assertEqual(list(Path(tmp).iterdir()), []) + https.assert_called_once_with("raw.githubusercontent.com", timeout=10) + connection.request.assert_called_once_with("GET", helper.DATA_PATH) + connection.close.assert_called_once_with() + self.assertTrue(response.closed) + + def test_ribonn_download_handles_transport_errors_without_output(self): + helper = _ribonn_helper() + errors = (TimeoutError("read timed out"), ssl.SSLCertVerificationError("untrusted certificate"), + helper.http.client.BadStatusLine("invalid HTTP response")) + for error in errors: + with self.subTest(error=type(error).__name__), tempfile.TemporaryDirectory() as tmp: + output = Path(tmp) / "prepared.csv" + with ( + patch.object(helper.http.client, "HTTPSConnection") as https, + patch.object(sys, "argv", ["prepare_ribonn.py", "--output", str(output)]), + redirect_stderr(io.StringIO()) as stderr, + ): + https.return_value.getresponse.side_effect = error + with self.assertRaises(SystemExit) as failure: + helper.main() + self.assertEqual(failure.exception.code, 1) + self.assertIn("Preparation failed:", stderr.getvalue()) + self.assertEqual(list(Path(tmp).iterdir()), []) + https.assert_called_once() + https.return_value.close.assert_called_once_with() + + def test_documented_runner_commands_parse(self): + parser = _public_runner_parser() + commands = [] + for skill_name in PUBLIC_SKILLS: + text = (SKILLS_ROOT / skill_name / "SKILL.md").read_text() + commands.extend((skill_name, command) for command in _runner_commands(text)) + + self.assertEqual({name for name, _ in commands}, { + "codonfm-score", + "codonfm-embed", + "codonfm-finetune", + }) + for skill_name, command in commands: + with self.subTest(skill=skill_name): + parser.parse_args(command) + + def test_fragile_command_requirements(self): + score = _runner_commands( + (SKILLS_ROOT / "codonfm-score/SKILL.md").read_text() + )[0] + self.assertIn("--mask_mutation", score) + self.assertIn("--extract-seq", score) + self.assertEqual(score[score.index("--num_gpus") + 1], "1") + + embed = _runner_commands( + (SKILLS_ROOT / "codonfm-embed/SKILL.md").read_text() + )[0] + self.assertEqual(embed[embed.index("--num_gpus") + 1], "1") + + finetune = _runner_commands( + (SKILLS_ROOT / "codonfm-finetune/SKILL.md").read_text() + )[0] + self.assertIn("--pretrained_ckpt_path", finetune) + self.assertNotIn("--checkpoint_path", finetune) + for flag in ( + "--lr", + "--check_val_every_n_epoch", + "--checkpoints_dir", + "--use_downstream_head", + ): + self.assertIn(flag, finetune) + self.assertEqual( + finetune[finetune.index("--check_val_every_n_epoch") + 1], "1" + ) + + def test_no_unavailable_feature_in_runner_commands(self): + forbidden = { + "MissenseDataset", + "missense_prediction", + "missense_synom_agg", + "missense_inference", + "missense_seq", + "decodon_200m", + "decodon_1b", + "mutation_pred_clm", + } + for skill_name in PUBLIC_SKILLS: + text = (SKILLS_ROOT / skill_name / "SKILL.md").read_text() + for command in _runner_commands(text): + with self.subTest(skill=skill_name, command=command): + self.assertTrue(forbidden.isdisjoint(command)) + + def test_setup_usage_matches_public_script(self): + text = (SKILLS_ROOT / "codonfm-setup/SKILL.md").read_text() + self.assertIn("bash run_dev.sh", text) + self.assertIn("--data-dir", text) + self.assertIn("--checkpoints-dir", text) + self.assertIn("/data/checkpoints", text) + self.assertIn("hf download nvidia/NV-CodonFM-Encodon-1B-v1", text) + self.assertIn("python3.11 -m venv .venv", text) + self.assertIn("python -m pip install -r requirements.txt", text) + self.assertIn("export MPLCONFIGDIR=", text) + self.assertIn("Use only the checked-in public code", text) + + def test_safetensors_eval_is_not_loaded_as_a_lightning_checkpoint(self): + calls = {"torch_load": 0, "predict": 0} + + class FakeTorch: + @staticmethod + def load(*args, **kwargs): + calls["torch_load"] += 1 + raise AssertionError("torch.load must not read safetensors") + + class FakeLogger: + def log_hyperparams(self, config): + self.config = config + + class FakeData: + init_global_step = 0 + + def setup(self, stage): + self.stage = stage + + def load_state_dict(self, state): + self.state = state + + class FakeModel: + prediction_counter = 0 + + def configure_model(self): + self.configured = True + + class FakeTrainer: + def __init__(self, **kwargs): + self.kwargs = kwargs + + def predict(self, *args, **kwargs): + calls["predict"] += 1 + + namespace = { + "Any": object, + "Dict": dict, + "Path": Path, + "Trainer": FakeTrainer, + "logging": type("Logging", (), {"info": staticmethod(lambda message: None)}), + "os": __import__("os"), + "seed_everything": lambda *args, **kwargs: None, + "torch": FakeTorch, + } + evaluate = _evaluate_function(namespace) + + with tempfile.TemporaryDirectory() as temp_dir: + model_path = Path(temp_dir) / "model.safetensors" + model_path.touch() + data = FakeData() + model = FakeModel() + evaluate( + config={ + "log": FakeLogger(), + "data": data, + "trainer": {}, + "model": model, + "callbacks": {}, + }, + config_dict={}, + model_ckpt_path=str(model_path), + out_dir=temp_dir, + ) + + self.assertEqual(calls["torch_load"], 0) + self.assertEqual(calls["predict"], 1) + self.assertEqual(data.stage, "test") + self.assertTrue(model.configured) + + def test_checked_in_references_exist(self): + for relative_path in ( + "notebooks/4-EnCodon-Downstream-Task-riboNN.ipynb", + "notebooks/5-EnCodon-Downstream-Task-mRFP-expression.ipynb", + "notebooks/6-EnCodon-Downstream-Task-mRNA-stability.ipynb", + "src/data/codon_bert_dataset.py", + "src/data/mutation_dataset.py", + "src/inference/encodon.py", + ): + self.assertTrue((REPO_ROOT / relative_path).is_file(), relative_path) + + +if __name__ == "__main__": + unittest.main()