File size: 6,989 Bytes
4516781
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# Copyright 2026 Google LLC.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""AlphaGenome finetuning example script.

This script demonstrates how to finetune the AlphaGenome model on custom genomic data, suitable for the following scenarios:
  - ATAC-seq/ChIP-seq signal prediction for new cell types or tissues
  - Adaptation to specific experimental data
  - Transfer learning to new species

Data requirements:
  - Reference genome FASTA file
  - BigWig signal track files pointed to by file_path in metadata
  - Training regions CSV file (columns: chromosome, start, end)

Usage:
    python run_finetuning.py \
        --fasta_path /path/to/GRCh38.fa \
        --regions_csv /path/to/regions.csv \
        --output_dir ./finetuned_model \
        --num_steps 1000 \
        --batch_size 2
"""

import pathlib
import sys

_PROJECT_ROOT = pathlib.Path(__file__).resolve().parents[1]
_SRC_DIR = _PROJECT_ROOT / "src"
if str(_SRC_DIR) not in sys.path:
    sys.path.insert(0, str(_SRC_DIR))

from absl import app
from absl import flags
from absl import logging

from alphagenome._sdk.data import fold_intervals
from alphagenome._sdk.models import dna_model as dna_model_types
import jax
import optax
import orbax.checkpoint as ocp

from alphagenome.finetuning.finetune import (
    get_dataset_iterator,
    get_forward_fn,
    get_train_step,
)
from alphagenome.evals.track_prediction import load_model as load_model_from_kaggle
from alphagenome.model.metadata import metadata as metadata_lib

FLAGS = flags.FLAGS

flags.DEFINE_string(
    'fasta_path',
    None,
    'Reference genome FASTA path.',
    required=True,
)
flags.DEFINE_string(
    'regions_csv',
    None,
    'Training regions CSV path with chromosome,start,end columns.',
    required=True,
)
flags.DEFINE_list(
    'bigwig_paths',
    None,
    'Deprecated compatibility flag. BigWig paths are read from metadata '
    'file_path columns.',
)
flags.DEFINE_string(
    'model_dir',
    None,
    'Pretrained checkpoint directory. If unset, Kaggle Hub is used.',
)
flags.DEFINE_string(
    'output_dir',
    './finetuned_model',
    'Directory to save finetuned checkpoints.',
)
flags.DEFINE_integer('num_steps', 1000, 'Number of training steps.')
flags.DEFINE_integer('batch_size', 2, 'Training batch size.')
flags.DEFINE_float('learning_rate', 1e-5, 'Initial learning rate.')
flags.DEFINE_integer('log_every', 50, 'Log interval in steps.')
flags.DEFINE_integer('save_every', 200, 'Checkpoint interval in steps.')
flags.DEFINE_enum(
    'model_version', 'FOLD_0',
    ['FOLD_0', 'FOLD_1', 'FOLD_2', 'FOLD_3', 'FOLD_4'],
    'Pretrained model version.',
)
flags.DEFINE_enum(
    'organism', 'HOMO_SAPIENS',
    ['HOMO_SAPIENS', 'MUS_MUSCULUS'],
    'Target organism.',
)


def _resolve_local_model_dir(path: str) -> pathlib.Path:
    model_dir = pathlib.Path(path).expanduser()
    if not model_dir.is_dir():
        raise FileNotFoundError(
            f'Pretrained checkpoint directory does not exist: {model_dir}'
        )
    return model_dir


def _load_pretrained_state(model_version: dna_model_types.ModelVersion):
    if FLAGS.model_dir:
        checkpoint_path = _resolve_local_model_dir(FLAGS.model_dir)
        logging.info('Loading pretrained model from local checkpoint: %s',
                     checkpoint_path)
        return ocp.StandardCheckpointer().restore(str(checkpoint_path))

    logging.info('Loading pretrained model from Kaggle Hub: %s',
                 model_version.name)
    params, state, _ = load_model_from_kaggle(model_version)
    return params, state


def main(_):
    output_dir = pathlib.Path(FLAGS.output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)

    model_version = dna_model_types.ModelVersion[FLAGS.model_version]
    organism = dna_model_types.Organism[FLAGS.organism]

    logging.info('JAX devices: %s', jax.devices())
    logging.info('Finetuning config: lr=%.2e, steps=%d, batch_size=%d',
                 FLAGS.learning_rate, FLAGS.num_steps, FLAGS.batch_size)

    # Load pretrained model parameters, the training forward function reconstructs the loss from the finetuning module.
    params, state = _load_pretrained_state(model_version)

    # Load output metadata.
    output_metadata = metadata_lib.load(organism)

    # Build the optimizer, using warmup + cosine decay to balance stability and convergence.
    schedule = optax.warmup_cosine_decay_schedule(
        init_value=0.0,
        peak_value=FLAGS.learning_rate,
        warmup_steps=100,
        decay_steps=FLAGS.num_steps,
    )
    optimizer = optax.chain(
        optax.clip_by_global_norm(1.0),
        optax.adam(learning_rate=schedule),
    )
    opt_state = optimizer.init(params)

    # Build finetuning training steps.
    forward = get_forward_fn({organism: output_metadata})
    train_step = get_train_step(
        predict_fn=forward.apply,
        optimizer=optimizer,
    )

    # Build dataset iterator.
    logging.info('Building finetuning dataset iterator...')
    dataset_iter = get_dataset_iterator(
        batch_size=FLAGS.batch_size,
        sequence_length=1_048_576,
        output_metadata=output_metadata,
        model_version=model_version,
        subset=fold_intervals.Subset.TRAIN,
        organism=organism,
        fasta_path=FLAGS.fasta_path,
        example_regions_path=FLAGS.regions_csv,
    )

    # Configure checkpoint manager.
    checkpointer = ocp.CheckpointManager(
        output_dir / 'checkpoints',
        options=ocp.CheckpointManagerOptions(max_to_keep=3),
    )

    # Training loop.
    logging.info('Starting finetuning training...')
    for step, batch in enumerate(dataset_iter):
        if step >= FLAGS.num_steps:
            break

        params, state, opt_state, metrics = train_step(
            params, state, opt_state, batch
        )

        if step % FLAGS.log_every == 0:
            loss = float(metrics.get('loss', float('nan')))
            logging.info('Step %d/%d | loss=%.4f', step, FLAGS.num_steps, loss)

        if step % FLAGS.save_every == 0 and step > 0:
            checkpointer.save(step, args=ocp.args.StandardSave({'params': params, 'state': state}))
            logging.info('Checkpoint saved (step=%d)', step)

    # Save final model.
    checkpointer.save(
        FLAGS.num_steps,
        args=ocp.args.StandardSave({'params': params, 'state': state}),
    )
    logging.info('Finetuning complete, final model saved to %s', output_dir / 'checkpoints')


if __name__ == '__main__':
    app.run(main)