cortexgrid-train
Training loops for models you train on the cortexgrid infrastructure.
What this library is
cortexgrid-train is an add-on to cortexgrid. It does not offer better training
algorithms or custom optimizations. The loops are standard: train_sft is AdamW with a
cosine warmup schedule and gradient clipping, the same loop you would write by hand.
It exists so you don't have to hand-write the same cortexgrid instrumentation into each project's training loop. Every loop in this library:
- logs metrics to the cortexgrid experiment run (MLflow): per-step loss and learning rate, and per-epoch loss;
- logs a heartbeat at the start of every epoch, so a stalled run is visible;
- checkpoints model, optimizer, and scheduler state through
cortexgrid.checkpoint()after every epoch; - resumes from the latest checkpoint through
cortexgrid.resume(), so a retried job continues after its last completed epoch instead of starting over.
It is not limited to LLMs. The library covers training any PyTorch model on
cortexgrid: language models, diffusion models, vision models, and so on. The algorithm
it ships today, train_sft, is supervised fine-tuning for HuggingFace causal LMs.
Loops for other model types and objectives belong here as well (see
Adding a training algorithm).
Install
pip install cortexgrid-train
Using it in your project
1. Get a model to train
The training loops take any torch.nn.Module, so the model can come from anywhere:
the HuggingFace Hub (from_pretrained("org/name")), a module you define, or weights
already stored in the cortexgrid model registry.
To train on the cluster, stage the weights in the registry with cortexgrid-infer. The download runs on the cluster, so the weights never pass through your machine:
import time
import cortexgrid
import cortexgrid_infer
cortexgrid.Experiment.init("qwen-sft")
MODEL_ID = "hf:Qwen/Qwen2.5-0.5B-Instruct"
cortexgrid_infer.upload_model(MODEL_ID)
status = cortexgrid_infer.deployment_status(MODEL_ID)
while status is None or status.phase != "ready":
time.sleep(10)
status = cortexgrid_infer.deployment_status(MODEL_ID)
cortexgrid-infer registers hf:<org>/<name> in the current run. The family is the
part of <name> before its last -, and the suffix is the part after it. For example,
Qwen2.5-0.5B-Instruct becomes family Qwen2.5-0.5B and suffix Instruct. A job
submitted from the same run gets the weights as a local directory with
cortexgrid.load_model(family, suffix, run_name).
2. Write the training job
A training job is a plain function. It loads the model, builds a dataset, calls a training loop, and saves the result. Saving is up to you: the loop only returns the trained model.
import cortexgrid
from peft import LoraConfig, get_peft_model
from transformers import AutoModelForCausalLM
from cortexgrid_train import train_sft
def train_job():
run_name = cortexgrid.Experiment.get_instance().run_name()
weights_dir = cortexgrid.load_model("Qwen2.5-0.5B", "Instruct", run_name)
model = AutoModelForCausalLM.from_pretrained(weights_dir).to("cuda")
model = get_peft_model(
model,
LoraConfig(r=16, target_modules=["q_proj", "v_proj"], task_type="CAUSAL_LM"),
)
dataset = build_dataset(weights_dir) # your code, see below
model = train_sft(model, dataset, epochs=3, batch_size=4, lr=2e-4)
model.save_pretrained("adapter")
cortexgrid.upload_dir("adapter", f"adapters/{run_name}")
train_sft expects a torch.utils.data.Dataset whose items are dicts of tensors with
input_ids and attention_mask, plus optionally labels. When labels is missing,
the loop copies input_ids and masks out padding positions. To use something other
than the model's built-in causal-LM loss, pass loss_fn=lambda outputs, batch: ....
3. Run it on the cluster
Submit the job from the same experiment run that holds the weights:
job_id = cortexgrid.remote(train_job, num_gpus=1, retry=True)
Metrics appear in the run while the job trains. If the job is retried, the loop picks up from the last checkpoint. See the cortexgrid docs for job status, retries, and logs.
Adding a training algorithm
To add a new objective or model type (DPO, reward modeling, diffusion fine-tuning, a vision classifier, ...), add it as a new loop next to SFT:
- Create a module, e.g.
cortexgrid_train/dpo.py, with atrain_dpo(...)function, and export it fromcortexgrid_train/__init__.py. - Write the algorithm however it needs to work: its own dataset format, loss, optimizer, and schedule. Nothing here assumes a language model.
- Keep the cortexgrid contract. It is what makes the loop belong in this library.
cortexgrid_train/sft.pyis the reference implementation.- Before training, call
cortexgrid.resume(). If it returns a checkpoint, restore the training state and skip the epochs that already completed. - At the start of each epoch, call
cortexgrid.log_metric("heartbeat", time.time(), step=global_step). - After each step, call
cortexgrid.log_metrics({"train/...": ...}, step=global_step). - After each epoch, open
with cortexgrid.checkpoint() as ckpt:, setckpt.epochandckpt.global_step, and callckpt.save_training_state(model, optimizer, scheduler). To store any other state the algorithm needs to resume, assign it as an attribute onckpt. - Return the trained model and let the caller save it.
- Before training, call
- Add unit tests that patch
cortexgrid_train.<module>.cortexgridand check the metric and checkpoint calls, as intests/test_sft_mlflow.py. Run them withuv run python -m unittest discover -s tests -v.
License
Apache-2.0
Metadata
Release files for cortexgrid-train 0.1.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cortexgrid_train-0.1.8.tar.gz | 8.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cortexgrid_train-0.1.8-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.9 kB
Release files / cortexgrid_train-0.1.8.tar.gz
| Download URL | cortexgrid_train-0.1.8.tar.gz |
|---|---|
| Size | 8.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bf56760e654c931a7bea9ec8f31bb764d1313cfe9d134e089dc846a2ecae78df
|
|
BLAKE2b-256 checksum How to use checksums |
78b11be0bb94d5a4ea7322a7ff72cba2ec4759687b0f2fbd2febaf0b274e2f59
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency logRelease files / cortexgrid_train-0.1.8-py3-none-any.whl
| Download URL | cortexgrid_train-0.1.8-py3-none-any.whl |
|---|---|
| Size | 9.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
98a474772d72605c5aaee5b06cbc7c34098c87956b9759199f5d926522f7f7e4
|
|
BLAKE2b-256 checksum How to use checksums |
6ee62298994cd9bd49b0c0e9fafdeb7f39db627f907652fb5b432379b89915ce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency log