Nirnay v3.1 is the new default: request routing 0.40 -> 0.88, SMS spam, emotion, toxicity, RAG up; previous default moved to v2/
61ffaac verified Download code/kaggle/nirnay_gpu_train.py from nandukmelath/nirnay: direct link, hf CLI and curl.
- Browser
- Download file 4.68 kB
-
https://huggingface.co/nandukmelath/nirnay/resolve/main/code/kaggle/nirnay_gpu_train.py
- Command line
-
hf download hf://nandukmelath/nirnay/code/kaggle/nirnay_gpu_train.py
-
curl -L -o nirnay_gpu_train.py https://huggingface.co/nandukmelath/nirnay/resolve/main/code/kaggle/nirnay_gpu_train.py
4.68 kB
| """Kaggle GPU job (GPU T4 x2): trains two Nirnay models at once, one per GPU, with train/train_gpu.py. | |
| Input: the private dataset <user>/nirnay-train-data made by jobs/kaggle_gpu.py (code/, records_v31.jsonl, | |
| records_ml.jsonl, v2_model_best.pt). Output in /kaggle/working: nirnay-v31-gpu/, nirnay-multilingual/, one log per | |
| model and the training run logs. With a single GPU the two models train one after the other. | |
| """ | |
| import glob | |
| import os | |
| import shutil | |
| import subprocess | |
| import sys | |
| import time | |
| import zipfile | |
| W = "/kaggle/working" | |
| SRC = os.path.join(W, "src") | |
| def find(name): | |
| hits = sorted(glob.glob("/kaggle/input/**/" + name, recursive=True)) | |
| return hits[0] if hits else None | |
| def stage_code(): | |
| script = find("train_gpu.py") | |
| if script is None: # code uploaded as an archive that was not unpacked | |
| for z in glob.glob("/kaggle/input/**/*.zip", recursive=True): | |
| zipfile.ZipFile(z).extractall(os.path.join(W, "unzipped")) | |
| script = (sorted(glob.glob(W + "/unzipped/**/train_gpu.py", recursive=True)) or [None])[0] | |
| assert script, "train_gpu.py not found in the attached dataset" | |
| root = os.path.dirname(os.path.dirname(script)) # .../code (holds nirnay/ and train/) | |
| shutil.copytree(root, SRC, dirs_exist_ok=True) | |
| return os.path.join(SRC, "train", "train_gpu.py") | |
| COMMON = {"NIRNAY_FUSION": "deep", "NIRNAY_SPLIT": "8", "NIRNAY_BATCH": "64", "NIRNAY_WARMUP": "300", | |
| "NIRNAY_EVAL_EVERY": "1000", "NIRNAY_MAX_STATE": "256", "NIRNAY_TRAIN_STATE_TOKENS": "256", | |
| "NIRNAY_THREADS": "2", "HF_HUB_DISABLE_TELEMETRY": "1", "PYTORCH_CUDA_ALLOC_CONF": "expandable_segments:True"} | |
| JOBS = [ | |
| {"name": "multilingual", "NIRNAY_RECORDS": "records_ml.jsonl", "NIRNAY_BACKBONE": "intfloat/multilingual-e5-base", | |
| "NIRNAY_POOL": "mean", "NIRNAY_PREFIX": "query: ", "NIRNAY_EPOCHS": "2.5", "NIRNAY_LR": "2e-4", | |
| "NIRNAY_ADAPTER_LR": "5e-5", "NIRNAY_RUN": "multilingual", "NIRNAY_EXPORT": W + "/nirnay-multilingual"}, | |
| {"name": "v31-gpu", "NIRNAY_RECORDS": "records_v31.jsonl", "NIRNAY_BACKBONE": "BAAI/bge-base-en-v1.5", | |
| "NIRNAY_POOL": "cls", "NIRNAY_PREFIX": "none", "NIRNAY_EPOCHS": "2.0", "NIRNAY_LR": "1e-4", | |
| "NIRNAY_ADAPTER_LR": "3e-5", "NIRNAY_INIT": "v2_model_best.pt", "NIRNAY_RUN": "v31-gpu", | |
| "NIRNAY_EXPORT": W + "/nirnay-v31-gpu"}, | |
| ] | |
| def launch(job, gpu, script): | |
| env = dict(os.environ, **COMMON) | |
| for k, v in job.items(): | |
| if k.startswith("NIRNAY_"): | |
| env[k] = (find(v) or v) if k in ("NIRNAY_RECORDS", "NIRNAY_INIT") else v | |
| env["CUDA_VISIBLE_DEVICES"] = str(gpu) | |
| log = open(os.path.join(W, job["name"] + ".log"), "w") | |
| print("launch %s on GPU %s: records %s" % (job["name"], gpu, env["NIRNAY_RECORDS"]), flush=True) | |
| return subprocess.Popen([sys.executable, "-u", script], env=env, stdout=log, stderr=subprocess.STDOUT, cwd=SRC), log | |
| def last_line(name): | |
| try: | |
| lines = [l for l in open(os.path.join(W, name + ".log"), encoding="utf-8", errors="replace").read().splitlines() if l.strip()] | |
| return lines[-1][:160] if lines else "" | |
| except OSError: | |
| return "" | |
| def main(): | |
| print(subprocess.run(["nvidia-smi", "-L"], capture_output=True, text=True).stdout, flush=True) | |
| import torch | |
| ngpu = torch.cuda.device_count() | |
| script = stage_code() | |
| t0 = time.time() | |
| queue = list(JOBS) | |
| running = [] | |
| while queue or running: | |
| while queue and len(running) < max(1, ngpu): | |
| free = sorted(set(range(max(1, ngpu))) - {g for _, _, _, g in running})[0] | |
| job = queue.pop(0) | |
| p, log = launch(job, free, script) | |
| running.append((job, p, log, free)) | |
| time.sleep(120) | |
| for job, p, log, g in list(running): | |
| state = "running" if p.poll() is None else "exit %s" % p.returncode | |
| print("[%6.1f min] %-12s %-9s %s" % ((time.time() - t0) / 60, job["name"], state, last_line(job["name"])), flush=True) | |
| if p.poll() is not None: | |
| log.close() | |
| running.remove((job, p, log, g)) | |
| for job in JOBS: | |
| print("=" * 30, job["name"], "-> exported:", os.path.isdir(job["NIRNAY_EXPORT"]), flush=True) | |
| print(open(os.path.join(W, job["name"] + ".log"), encoding="utf-8", errors="replace").read()[-4000:], flush=True) | |
| for run in glob.glob(SRC + "/train/runs/*"): # keep the run logs and best checkpoints next to the models | |
| shutil.copytree(run, os.path.join(W, "runs", os.path.basename(run)), dirs_exist_ok=True) | |
| shutil.rmtree(SRC, ignore_errors=True) | |
| shutil.rmtree(os.path.join(W, "unzipped"), ignore_errors=True) | |
| if __name__ == "__main__": | |
| main() | |