Model finetuning

Adapting BioLMs to your own data.

The catalog models get you a long way, but sometimes the right model is one trained on your sequences and your labels. The SDK exposes BioLM’s managed finetuning service through biolm.finetune.Finetune, a small Python-only client that launches training runs on BioLM infrastructure and tracks them to completion. There is no CLI for finetuning — it lives entirely in Python — and it covers two families of job: XGBoost models trained on BioLM embeddings, and DSM language-model finetuning across three stages.

Finetuning is a gated feature. Every call authenticates exactly like the rest of the SDK (BIOLM_TOKEN or api_key=; see Authentication), and if your account is not enabled for finetuning the service returns HTTP 402 and the client raises a PermissionError telling you to contact BioLM. A missing or invalid token raises the same error for 401.

How the client is shaped

Finetune is a collection of classmethods that each return a plain dict — the JSON the service sends back, typically including a run_id you use to track progress. Every launch method is keyword-only, and every training argument that accepts data (train_data, paired_data, seed_sequences, …) takes one of two shapes:

  • a list of row dicts[{"sequence": "MK...", "label": 1}, ...], or

  • a raw CSV string — the full contents of a CSV file, sent inline.

Both are transmitted as JSON in the request body, so there is no file upload step: build your table in memory (or read a CSV off disk into a string) and pass it straight in. Because the whole client is Python, the natural workflow is to prepare data with pandas or plain lists, launch a run, capture the returned run_id, and poll it — all in the same script or notebook. An optional run_name labels the job for later, and environment_id pins it to a specific compute environment when your account has more than one.

Training XGBoost on embeddings

xgboost() trains a gradient-boosted model on embeddings drawn from one or more catalog models. You supply labeled data, name the embedding model(s) to featurize with, and pick a task type:

python
from biolm.finetune import Finetune

run = Finetune.xgboost(
    train_data=[
        {"sequence": "MSILVTRPSPAGEEL", "label": 1},
        {"sequence": "MKTAYIAKQRQISFV", "label": 0},
        # ...
    ],
    embedding_models=["esm2-8m"],
    task_type="classification",
    target_column="label",
    text_column="sequence",
)
run_id = run["run_id"]

target_column and text_column name the label and sequence fields in your rows (defaulting to "label" and "sequence"). task_type is "classification" or "regression". Beyond that you can tune the booster directly — n_estimators, max_depth, learning_rate, n_splits for cross-validation, and seed — or turn on Ray Tune hyperparameter search with hyperopt=True and hyperopt_n_trials. Optional test_data and validation_data follow the same row/CSV shape as train_data. For antibody workflows set antibody_mode=True and name the heavy_column and light_column.

DSM finetuning: stage 1, stage 2, and RL

DSM (diffusion sequence model) finetuning runs in stages that build on one another: stage 1 adapts the base language model to your sequence distribution, stage 2 specializes it on paired data, and the RL stage steers generation toward a measurable objective. You can stop after any stage — a stage-1 checkpoint is useful on its own — but stage 2 and RL expect the artifacts the earlier stages produce.

Stage 1dsm_stage1() — is a single-chain masked-LM finetune over your sequences:

python
run = Finetune.dsm_stage1(
    train_data=my_sequences_csv,      # list of dicts or CSV string
    sequence_col="sequence",
    max_steps=50000,
)

Stage 2dsm_stage2() — continues from a stage-1 checkpoint to learn paired, multichain structure (for example antibody heavy/light pairs). Pass the checkpoint identifier the stage-1 run produced:

python
run = Finetune.dsm_stage2(
    stage1_checkpoint="",
    paired_data=my_pairs,             # rows with heavy_col / light_col
    heavy_col="heavy",
    light_col="light",
)

RLdsm_rl() — optimizes sequences against an oracle using reinforcement learning, seeded with sequences you provide:

python
run = Finetune.dsm_rl(
    seed_sequences=["MSILVTRPSPAGEEL", "MKTAYIAKQRQISFV"],
    oracle_type="esmc",
    stability_objective="thermostability",
    algorithm="ppo",
    num_episodes=100,
)

Each stage exposes its own training knobs — learning rate, batch size, gradient accumulation, step counts, fp16, and so on — with sensible defaults, so you only override what you need.

Tracking a run to completion

Launches return immediately; training happens asynchronously on BioLM’s side. The simplest way to wait is wait(), which polls until the run reaches a terminal state and then returns its full detail:

python
result = Finetune.wait(run_id, poll_interval=15, timeout=3600)

The terminal states are held in TERMINAL_STATUSESsucceeded, failed, cancelled, and error. For finer control, progress() returns lightweight status, get_run() returns full detail and results, list_runs() paginates your history (filter by dag or status), and cancel() stops an in-flight run.

Async variants

Every launch and tracking method has an _async twin — xgboost_async, dsm_stage1_async, get_run_async, and so on — that you await inside an event loop. The synchronous methods are thin wrappers that run the coroutine for you, so use the plain names in scripts and notebooks and the _async names when you are already in async code (see Client interfaces).

Where to go next

We speak the language of bio-AI

© 2022 - 2026 BioLM. All Rights Reserved.