A2D2 / a2d2_mol /scripts /run_mol_finetune.slurm
Sophia
initial commit
8019be0
Raw
History Blame Contribute Delete
7.01 kB
#!/bin/bash
# NOTE: --partition and --qos below are specific to our cluster. Change them
# (or remove them and pass `--partition` on the `sbatch` command line) to match
# the partitions/QOS available on yours.
#SBATCH --job-name=mol-finetune
#SBATCH --partition=dgx-b200
#SBATCH --nodes=1
#SBATCH --gpus-per-node=1
#SBATCH --cpus-per-task=8
#SBATCH --ntasks-per-node=1
#SBATCH --mem=80GB
#SBATCH --time=02-00:00:00
#SBATCH --output=logs/slurm-%A.%x.log
# =====================================================================
# run_mol_finetune.slurm
#
# Single-mode job (1 MIG GPU) running ONE finetune_mol experiment.
# Select which mode to run via the MODE_ID variable below (or override
# at submit time with `sbatch --export=ALL,MODE_ID=2 ...`):
# 0) A2D2 (Ours) – with full planner (alternating)
# 1) A2D2 w/o quality – --disable_planner
# 2) A2D2 w/o insertion planner – --disable_insertion_planner
# 3) A2D2 w/o unmasking planner – --disable_unmasking_planner
#
# The job trains the selected mode then evaluates the resulting
# checkpoint on the same GPU.
# =====================================================================
set -e
# --- Mode selection ---------------------------------------------------
# Which experiment to run (0-3). Override with `--export=ALL,MODE_ID=N`.
MODE_ID="${MODE_ID:-0}"
# Run prefix
PREFIX=${SLURM_JOB_ID:-$(date +%Y%m%d_%H%M%S)}
# --- Paths ------------------------------------------------------------
# Repo root is resolved at submit time so the job runs from any clone:
# - set A2D2_ROOT explicitly, OR
# - submit with `sbatch` from the repo root (SLURM sets SLURM_SUBMIT_DIR;
# note sbatch copies the script to a spool dir, so we can't rely on the
# script's own path here), OR
# - run the script directly, falling back to its location on disk.
if [ -n "${A2D2_ROOT:-}" ]; then
HOME_LOC="$A2D2_ROOT"
elif [ -n "${SLURM_SUBMIT_DIR:-}" ]; then
HOME_LOC="$SLURM_SUBMIT_DIR"
else
# This script lives in a2d2_mol/scripts/, so the repo root is two levels up.
HOME_LOC="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
fi
SCRIPT_LOC="$HOME_LOC/a2d2_mol"
LOG_LOC=$HOME_LOC/logs
SAVE_DIR=$HOME_LOC/checkpoints/finetune_mol
RESULTS_DIR=$HOME_LOC/results/mol_ablation
mkdir -p "$LOG_LOC" "$SAVE_DIR" "$RESULTS_DIR"
# --- Environment setup ------------------------------------------------
# Set WANDB_API_KEY in your shell/secret store before submitting (do NOT commit it):
# export WANDB_API_KEY=... or `wandb login`
export WANDB_DIR=$HOME_LOC/.wandb
export WANDB_CONFIG_DIR=$HOME_LOC/.config/wandb
export WANDB_CACHE_DIR=$HOME_LOC/.cache/wandb
mkdir -p "$WANDB_DIR" "$WANDB_CONFIG_DIR" "$WANDB_CACHE_DIR"
export TRITON_CACHE_DIR=$HOME_LOC/.triton/cache
mkdir -p "$TRITON_CACHE_DIR"
export TORCHINDUCTOR_CACHE_DIR=$HOME_LOC/.torchinductor/cache
mkdir -p "$TORCHINDUCTOR_CACHE_DIR"
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
# Force unbuffered stdout/stderr so live training output is flushed to the
# redirected RUN_LOG (Python block-buffers stdout when it's a file, not a TTY).
export PYTHONUNBUFFERED=1
# Activate conda env. Override CONDA_ROOT to point at your conda/miniconda
# install, or just have `conda` on PATH; override CONDA_ENV if your env name
# differs from the one created by environment.yml.
CONDA_ENV="${CONDA_ENV:-a2d2}"
if [ -n "${CONDA_ROOT:-}" ]; then
source "$CONDA_ROOT/bin/activate" "$CONDA_ENV"
elif command -v conda >/dev/null 2>&1; then
source "$(conda info --base)/bin/activate" "$CONDA_ENV"
else
echo "ERROR: conda not found; set CONDA_ROOT to your miniconda install." >&2
exit 1
fi
PYTHON_EXECUTABLE=$(which python)
cd "$SCRIPT_LOC"
# Pretrained base checkpoint
PRETRAINED_CKPT="$HOME_LOC/pretrained/anylength_mol.ckpt"
# --- Shared training hyperparameters ----------------------------------
COMMON_ARGS=(
--base_path "$HOME_LOC"
--use_quality_filter
--noise_removal
--wdce_num_replicates 16
--pool_size 1000
--pool_refresh_fraction 0.3
--buffer_size 100
--batch_size 200
--training_mini_batch_size 20
--max_length 256
--total_num_steps 256
--num_iter 20
--resample_every_n_step 10
--num_epochs 1000
--save_every_n_epochs 100
--reset_every_n_step 1
--alpha 0.01
--no_mcts
--schedule_warmup_epochs 20
--alternation_frequency 5
--num_remasking 3
--quality_threshold 0.3
--checkpoint_path "$PRETRAINED_CKPT"
--grad_clip
--qed_only
--seed 42
--num_training_steps_per_epoch 25
)
# --- Shared evaluation hyperparameters --------------------------------
EVAL_COMMON_ARGS=(
--pretrained_ckpt "$PRETRAINED_CKPT"
--num_samples 1000
--batch_size 50
--max_length 256
--total_num_steps 256
--num_remasking 2
--quality_threshold 0.3
--seed 42
)
# =====================================================================
# Pick experiment from $MODE_ID
# =====================================================================
case "$MODE_ID" in
0) MODE="with_planner"; EXTRA_ARGS=() ;;
1) MODE="no_planner"; EXTRA_ARGS=(--disable_planner) ;;
2) MODE="no_insertion_planner"; EXTRA_ARGS=(--disable_insertion_planner) ;;
3) MODE="no_unmasking_planner"; EXTRA_ARGS=(--disable_unmasking_planner) ;;
*) echo "Unknown MODE_ID=$MODE_ID (expected 0-3)"; exit 1 ;;
esac
RUN_NAME="${PREFIX}_mol_${MODE}"
RUN_LOG="$LOG_LOC/${RUN_NAME}.log"
RUN_SAVE_DIR="$SAVE_DIR/${RUN_NAME}"
RESULTS_SUBDIR="$RESULTS_DIR/${MODE}"
mkdir -p "$RUN_SAVE_DIR" "$RESULTS_SUBDIR"
echo "=== Mol finetune (MODE_ID=$MODE_ID) ==="
echo "Job: ${SLURM_JOB_ID} Node: $SLURM_NODELIST"
echo "Mode: $MODE"
echo "Save dir: $RUN_SAVE_DIR"
echo "Results dir: $RESULTS_SUBDIR"
echo "Python: $PYTHON_EXECUTABLE"
echo "CUDA_VISIBLE_DEVICES: ${CUDA_VISIBLE_DEVICES:-(unset)}"
# =====================================================================
# Train
# =====================================================================
$PYTHON_EXECUTABLE $SCRIPT_LOC/finetune_mol.py \
"${COMMON_ARGS[@]}" \
--devices 1 \
"${EXTRA_ARGS[@]}" \
--save_path_dir "$RUN_SAVE_DIR" \
>> "$RUN_LOG" 2>&1
echo "Training finished for $MODE. Log: $RUN_LOG"
# =====================================================================
# Evaluate
# =====================================================================
RUN_CKPT=$(ls -t "$RUN_SAVE_DIR"/*/last.ckpt "$RUN_SAVE_DIR"/last.ckpt 2>/dev/null | head -1)
if [ -z "$RUN_CKPT" ]; then
echo "No checkpoint found in $RUN_SAVE_DIR — skipping eval."
exit 1
fi
echo "Evaluating checkpoint: $RUN_CKPT"
$PYTHON_EXECUTABLE $SCRIPT_LOC/evaluate_mol_table.py \
--checkpoint_path "$RUN_CKPT" \
"${EVAL_COMMON_ARGS[@]}" \
"${EXTRA_ARGS[@]}" \
--output_dir "$RESULTS_SUBDIR" \
--device cuda:0 \
>> "$RESULTS_SUBDIR/eval.log" 2>&1
echo "Eval finished for $MODE. CSV: $RESULTS_SUBDIR/eval_metrics_${MODE}.csv"
conda deactivate