Download cloud/lightning_launch.py from abuz8studios/FAIE: direct link, hf CLI and curl.
- Browser
- Download file 4.62 kB
-
https://huggingface.co/abuz8studios/FAIE/resolve/main/cloud/lightning_launch.py
- Command line
-
hf download hf://abuz8studios/FAIE/cloud/lightning_launch.py
-
curl -L -o lightning_launch.py https://huggingface.co/abuz8studios/FAIE/resolve/main/cloud/lightning_launch.py
4.62 kB
| """Drive a Lightning Studio from here: upload the lane, run a job, pull results back. | |
| WHAT THIS DOES AND DOES NOT DO | |
| It does NOT create an account, accept terms, or authorise any spend — those are | |
| owner actions by design (see README). It assumes you have already run `lightning login` | |
| or set LIGHTNING_USER_ID / LIGHTNING_API_KEY, and it fails with a plain message if not. | |
| WHY A STUDIO AND NOT A ONE-SHOT JOB | |
| The lane is iterative: generate traces, train, judge, adjust the mix, train again. | |
| A Studio is a persistent machine you attach a GPU to and detach when idle, so the | |
| corpus and checkpoints survive between rounds instead of being re-uploaded each time. | |
| WHAT GETS UPLOADED (small — deliberately) | |
| cloud/*.py, requirements.txt, cloud/traces/*.jsonl, corpus/calib_*.txt | |
| NOT the 129 GB GGUF. The oracle stays home; the student is pulled from HF on the | |
| remote machine, which is faster than any upload from here. | |
| Usage: | |
| python lightning_launch.py --status | |
| python lightning_launch.py --start --machine A100 | |
| python lightning_launch.py --run "python distill_qlora.py --model <id> --dry-run" | |
| python lightning_launch.py --stop | |
| """ | |
| import argparse | |
| import os | |
| import sys | |
| NAME = os.environ.get("LIGHTNING_STUDIO", "abuz8-tajwid") | |
| TEAMSPACE = os.environ.get("LIGHTNING_TEAMSPACE") # optional | |
| UPLOAD = [ | |
| ("cloud/teacher_client.py", "teacher_client.py"), | |
| ("cloud/make_traces.py", "make_traces.py"), | |
| ("cloud/distill_qlora.py", "distill_qlora.py"), | |
| ("cloud/requirements.txt", "requirements.txt"), | |
| ] | |
| ROOT = r"E:\ABU\NEOCORTEX" | |
| def need_auth(): | |
| have_env = bool(os.environ.get("LIGHTNING_USER_ID") and os.environ.get("LIGHTNING_API_KEY")) | |
| have_file = os.path.exists(os.path.expanduser("~/.lightning/credentials.json")) | |
| return not (have_env or have_file) | |
| def get_studio(create=False): | |
| from lightning_sdk import Studio | |
| kw = {"name": NAME} | |
| if TEAMSPACE: | |
| kw["teamspace"] = TEAMSPACE | |
| if create: | |
| kw["create_ok"] = True | |
| return Studio(**kw) | |
| def main(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--status", action="store_true") | |
| ap.add_argument("--start", action="store_true") | |
| ap.add_argument("--stop", action="store_true") | |
| ap.add_argument("--upload", action="store_true") | |
| ap.add_argument("--run", type=str) | |
| ap.add_argument("--machine", default="A100", | |
| help="Lightning machine type, e.g. CPU / T4 / A10G / A100 / H100") | |
| a = ap.parse_args() | |
| if need_auth(): | |
| print("NOT AUTHENTICATED — Lightning needs one owner action first:\n" | |
| " lightning login (opens a browser)\n" | |
| "or set LIGHTNING_USER_ID and LIGHTNING_API_KEY in the environment.\n" | |
| "I do not create accounts or accept terms on your behalf.") | |
| return 2 | |
| try: | |
| from lightning_sdk import Machine | |
| except Exception as e: | |
| print(f"lightning_sdk import failed: {e}") | |
| return 1 | |
| s = get_studio(create=a.start) | |
| if a.status: | |
| print(f"studio : {NAME}") | |
| print(f"status : {getattr(s, 'status', '?')}") | |
| print(f"machine : {getattr(s, 'machine', '?')}") | |
| return 0 | |
| if a.start: | |
| mt = getattr(Machine, a.machine.upper(), None) | |
| if mt is None: | |
| print(f"unknown machine '{a.machine}'. Available: " | |
| f"{[x for x in dir(Machine) if x.isupper()]}") | |
| return 1 | |
| print(f"starting {NAME} on {a.machine} …") | |
| s.start(machine=mt) | |
| print(f"started. status={getattr(s, 'status', '?')}") | |
| if a.upload or a.start: | |
| for local, remote in UPLOAD: | |
| p = os.path.join(ROOT, local.replace("cloud/", "cloud\\")) | |
| if os.path.exists(p): | |
| print(f" upload {local} -> {remote}") | |
| s.upload_file(p, remote) | |
| tdir = os.path.join(ROOT, "cloud", "traces") | |
| if os.path.isdir(tdir): | |
| for f in os.listdir(tdir): | |
| if f.endswith(".jsonl"): | |
| print(f" upload traces/{f}") | |
| s.upload_file(os.path.join(tdir, f), f"traces/{f}") | |
| for f in ("calib_holdout.txt", "calib_arabic_holdout.txt"): | |
| p = os.path.join(ROOT, "corpus", f) | |
| if os.path.exists(p): | |
| print(f" upload corpus/{f}") | |
| s.upload_file(p, f"corpus/{f}") | |
| if a.run: | |
| print(f"run: {a.run}") | |
| print(s.run(a.run)) | |
| if a.stop: | |
| print(f"stopping {NAME} (this is what stops the meter) …") | |
| s.stop() | |
| print("stopped.") | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main()) | |