Secured / training /modal_train.py
gowtham0992's picture
Ship MiniCPM LoRA v3
cc862d5
Raw
History Blame Contribute Delete
3.99 kB
from __future__ import annotations
from pathlib import Path
import modal
APP_NAME = "jawbreaker-minicpm-lora"
REMOTE_ROOT = Path("/workspace")
REMOTE_OUTPUT = Path("/outputs")
LOCAL_ROOT = Path(__file__).resolve().parents[1]
image = (
modal.Image.debian_slim(python_version="3.12")
.pip_install(
"accelerate==1.12.0",
"datasets>=4.4.0,<5.0",
"huggingface-hub>=0.34.0,<1.0",
"peft>=0.18.0,<1.0",
"sentencepiece>=0.2.0,<1.0",
"torch==2.9.1",
"transformers==4.57.3",
)
.add_local_dir(LOCAL_ROOT / "jawbreaker", remote_path=REMOTE_ROOT / "jawbreaker")
.add_local_dir(LOCAL_ROOT / "training", remote_path=REMOTE_ROOT / "training")
.add_local_dir(LOCAL_ROOT / "eval", remote_path=REMOTE_ROOT / "eval")
)
app = modal.App(APP_NAME, image=image)
volume = modal.Volume.from_name("jawbreaker-training", create_if_missing=True)
@app.function(
gpu="A100",
timeout=6 * 60 * 60,
volumes={REMOTE_OUTPUT: volume},
secrets=[modal.Secret.from_name("huggingface-secret", required_keys=["HF_TOKEN"])],
)
def train_lora(
model_id: str = "openbmb/MiniCPM4.1-8B",
output_name: str = "jawbreaker-minicpm-lora",
epochs: float = 1.0,
train_file: str = "training/data/train.jsonl",
dev_file: str = "training/data/dev.jsonl",
max_length: int = 768,
batch_size: int = 1,
grad_accum: int = 16,
learning_rate: float = 2e-4,
warmup_ratio: float = 0.0,
weight_decay: float = 0.0,
lr_scheduler_type: str = "linear",
lora_r: int = 16,
lora_alpha: int = 32,
lora_dropout: float = 0.05,
push_to_hub: bool = False,
hub_model_id: str | None = None,
) -> None:
import os
import subprocess
os.chdir(REMOTE_ROOT)
output_dir = REMOTE_OUTPUT / output_name
cmd = [
"python",
"training/train_lora.py",
"--model-id",
model_id,
"--train-file",
train_file,
"--dev-file",
dev_file,
"--output-dir",
str(output_dir),
"--epochs",
str(epochs),
"--max-length",
str(max_length),
"--batch-size",
str(batch_size),
"--grad-accum",
str(grad_accum),
"--learning-rate",
str(learning_rate),
"--warmup-ratio",
str(warmup_ratio),
"--weight-decay",
str(weight_decay),
"--lr-scheduler-type",
lr_scheduler_type,
"--lora-r",
str(lora_r),
"--lora-alpha",
str(lora_alpha),
"--lora-dropout",
str(lora_dropout),
]
if push_to_hub:
cmd.append("--push-to-hub")
if hub_model_id:
cmd.extend(["--hub-model-id", hub_model_id])
subprocess.run(cmd, check=True)
volume.commit()
@app.local_entrypoint()
def main(
model_id: str = "openbmb/MiniCPM4.1-8B",
output_name: str = "jawbreaker-minicpm-lora",
epochs: float = 1.0,
train_file: str = "training/data/train.jsonl",
dev_file: str = "training/data/dev.jsonl",
max_length: int = 768,
batch_size: int = 1,
grad_accum: int = 16,
learning_rate: float = 2e-4,
warmup_ratio: float = 0.0,
weight_decay: float = 0.0,
lr_scheduler_type: str = "linear",
lora_r: int = 16,
lora_alpha: int = 32,
lora_dropout: float = 0.05,
push_to_hub: bool = False,
hub_model_id: str | None = None,
) -> None:
train_lora.remote(
model_id=model_id,
output_name=output_name,
epochs=epochs,
train_file=train_file,
dev_file=dev_file,
max_length=max_length,
batch_size=batch_size,
grad_accum=grad_accum,
learning_rate=learning_rate,
warmup_ratio=warmup_ratio,
weight_decay=weight_decay,
lr_scheduler_type=lr_scheduler_type,
lora_r=lora_r,
lora_alpha=lora_alpha,
lora_dropout=lora_dropout,
push_to_hub=push_to_hub,
hub_model_id=hub_model_id,
)