"""SpikeWhale training control panel (CLI: python -m daisychain.spikewhale_panel). A web page with sliders for the SpikeWhale config. Pick a size your hardware can handle, hit Start, and it launches the real DaisyChain training (SpikeWhale + FineWeb-Edu) and streams the live loss. The exact env is shown so you can run the same command on other machines to train distributed. """ import json import os import subprocess import sys import threading from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer PORT = int(os.environ.get("SW_PANEL_PORT", "8899")) _proc = None _log = [] # rolling training log _lock = threading.Lock() def _pump(proc): for line in iter(proc.stdout.readline, ""): with _lock: _log.append(line.rstrip("\n")) if len(_log) > 400: del _log[:200] proc.stdout.close() def start_training(cfg): global _proc if _proc and _proc.poll() is None: return False, "already running" env = dict(os.environ) env.update({ "MASTER_ADDR": "127.0.0.1", "MASTER_PORT": "29610", "WORLD_SIZE": "1", "RANK": "0", "USE_LIBUV": "0", "PYTHONUNBUFFERED": "1", "DAISY_TASK": "daisychain.spikewhale_task:SpikeWhaleTask", "DAISY_SW_HIDDEN": str(cfg["hidden"]), "DAISY_SW_LAYERS": str(cfg["layers"]), "DAISY_SW_HEADS": str(cfg["heads"]), "DAISY_SW_EXPERTS": str(cfg["experts"]), "DAISY_SW_SEQLEN": str(cfg["seqlen"]), "DAISY_STEPS": str(cfg["steps"]), "DAISY_LR": str(cfg["lr"]), "DAISY_OPTIMIZER": "adam", "DAISY_BASE_BATCH": str(cfg["batch"]), }) if cfg.get("dataset"): env["DAISY_SW_DATASET"] = cfg["dataset"] # blank subset means the dataset's default config; unset any inherited one if cfg.get("subset"): env["DAISY_SW_SUBSET"] = cfg["subset"] else: env.pop("DAISY_SW_SUBSET", None) with _lock: _log.clear() _log.append(f"launching training: hidden={cfg['hidden']} layers={cfg['layers']} " f"experts={cfg['experts']} seqlen={cfg['seqlen']} steps={cfg['steps']} " f"dataset={env.get('DAISY_SW_DATASET', 'HuggingFaceFW/fineweb-edu')}" + (f":{env['DAISY_SW_SUBSET']}" if env.get("DAISY_SW_SUBSET") else "")) _proc = subprocess.Popen([sys.executable, "-u", "-m", "daisychain.train"], env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1) threading.Thread(target=_pump, args=(_proc,), daemon=True).start() return True, "started" PAGE = """
Pick a size your hardware can train, then start. Trains the real SpikeWhale on streamed FineWeb-Edu, distributed by DaisyChain. Smaller = faster on old hardware.
Any streamable text dataset with a text column works. For gated/private datasets, log in first with huggingface-cli login on this machine — the trainer inherits your token.
idle