Skip to content

Commit 461a10c

Browse files
JuliaEdomclaude
andcommitted
feat(autotune): serve-ready Kaggle notebook — flat-adapter self-homing, tunnel URL relay
Training v10 COMPLETE (500/500, train_loss 0.026, eval_loss 0.066); adapter verified (safetensors header == file size) and uploaded as dataset liovinajo/nlsql-adapter. Kaggle unpacks zips flat, so serve resolves the adapter dir by rglob and refuses to silently serve the base model. Live kernel logs are unreadable via API, so the serve cell publishes the cloudflared URL through a private nlsql-tunnel dataset (creds via nlsql-relay). Serve push itself is blocked until the weekly GPU quota resets. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 81c8b4b commit 461a10c

2 files changed

Lines changed: 64 additions & 5 deletions

File tree

‎scripts/autotune/kaggle/kaggle_autotune.ipynb‎

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,24 @@
2020
"id": "acae54e37e7d407bbb7b55eff062a284",
2121
"metadata": {},
2222
"outputs": [],
23-
"source": "MODE = \"train\" # \"train\" | \"serve\"\n\nBASE_MODEL = \"Qwen/Qwen2.5-Coder-7B-Instruct\"\nDATA_DIR = \"/kaggle/input/nlsql-autotune-data\" # train.jsonl, val.jsonl, train_qlora.py\nOUT = \"/kaggle/working/qlora_out\"\n\n# train mode\nEPOCHS = 1.0\nMAX_SEQ = 4096\nSMOKE_STEPS = 0 # >0: run this many steps end-to-end first, then the real run (0 = straight in)\nRESUME_INPUT = \"auto\" # non-empty: rglob /kaggle/input for checkpoint-* and resume; \"\" = fresh\n\n# serve mode\nADAPTER_DIR = \"/kaggle/input/nlsql-adapter/adapter\" # absent path => serve plain base model\nSERVE_HOURS = 5.0\nPORT = 8000"
23+
"source": [
24+
"MODE = \"serve\" # \"train\" | \"serve\"\n",
25+
"\n",
26+
"BASE_MODEL = \"Qwen/Qwen2.5-Coder-7B-Instruct\"\n",
27+
"DATA_DIR = \"/kaggle/input/nlsql-autotune-data\" # train.jsonl, val.jsonl, train_qlora.py\n",
28+
"OUT = \"/kaggle/working/qlora_out\"\n",
29+
"\n",
30+
"# train mode\n",
31+
"EPOCHS = 1.0\n",
32+
"MAX_SEQ = 4096\n",
33+
"SMOKE_STEPS = 0 # >0: run this many steps end-to-end first, then the real run (0 = straight in)\n",
34+
"RESUME_INPUT = \"auto\" # non-empty: rglob /kaggle/input for checkpoint-* and resume; \"\" = fresh\n",
35+
"\n",
36+
"# serve mode\n",
37+
"ADAPTER_DIR = \"/kaggle/input/nlsql-adapter/adapter\" # absent path => serve plain base model\n",
38+
"SERVE_HOURS = 8.0\n",
39+
"PORT = 8000"
40+
]
2441
},
2542
{
2643
"cell_type": "code",
@@ -37,6 +54,8 @@
3754
"metadata": {},
3855
"outputs": [],
3956
"source": [
57+
"import json\n",
58+
"import os\n",
4059
"import re\n",
4160
"import subprocess\n",
4261
"import sys\n",
@@ -56,7 +75,15 @@
5675
" import torch\n",
5776
"\n",
5877
" tp = 2 if torch.cuda.device_count() >= 2 else 1\n",
59-
" with_lora = Path(ADAPTER_DIR).is_dir()\n",
78+
" # Kaggle unpacks an uploaded zip FLAT (v9/v10 lesson) -- self-home on the config\n",
79+
" hits = sorted(Path(\"/kaggle/input/nlsql-adapter\").rglob(\"adapter_config.json\"))\n",
80+
" adapter_dir = str(hits[0].parent) if hits else ADAPTER_DIR\n",
81+
" with_lora = Path(adapter_dir, \"adapter_model.safetensors\").exists()\n",
82+
" if not with_lora:\n",
83+
" raise RuntimeError(\n",
84+
" \"no adapter under /kaggle/input/nlsql-adapter -- refusing to silently serve base\"\n",
85+
" )\n",
86+
" print(f\"adapter_dir resolved: {adapter_dir}\", flush=True)\n",
6087
" vllm_cmd = [\n",
6188
" \"vllm\",\n",
6289
" \"serve\",\n",
@@ -78,7 +105,7 @@
78105
" \"--max-lora-rank\",\n",
79106
" \"16\",\n",
80107
" \"--lora-modules\",\n",
81-
" f\"sqltuned={ADAPTER_DIR}\",\n",
108+
" f\"sqltuned={adapter_dir}\",\n",
82109
" ]\n",
83110
" print(\" \".join(vllm_cmd), flush=True)\n",
84111
" with open(\"/kaggle/working/vllm.log\", \"w\") as vllm_log:\n",
@@ -109,6 +136,35 @@
109136
" url = m.group(0)\n",
110137
" break\n",
111138
" Path(\"/kaggle/working/tunnel_url.txt\").write_text(url or \"NONE\")\n",
139+
" # Live kernel logs are unreadable via API, so push the URL out through a\n",
140+
" # private dataset the Windows side can poll. Creds ride in nlsql-relay.\n",
141+
" creds = json.loads(Path(\"/kaggle/input/nlsql-relay/kaggle.json\").read_text())\n",
142+
" relay_env = {**os.environ, \"KAGGLE_USERNAME\": creds[\"username\"], \"KAGGLE_KEY\": creds[\"key\"]}\n",
143+
" relay = Path(\"/kaggle/working/relay\")\n",
144+
" relay.mkdir(exist_ok=True)\n",
145+
" (relay / \"tunnel_url.txt\").write_text(url or \"NONE\")\n",
146+
" (relay / \"dataset-metadata.json\").write_text(\n",
147+
" json.dumps(\n",
148+
" {\n",
149+
" \"title\": \"nlsql-tunnel\",\n",
150+
" \"id\": \"liovinajo/nlsql-tunnel\",\n",
151+
" \"licenses\": [{\"name\": \"CC0-1.0\"}],\n",
152+
" }\n",
153+
" )\n",
154+
" )\n",
155+
" for verb in ([\"version\", \"-m\", \"tunnel-url\"], [\"create\"]):\n",
156+
" rr = subprocess.run(\n",
157+
" [\"kaggle\", \"datasets\", *verb, \"-p\", str(relay)],\n",
158+
" capture_output=True,\n",
159+
" text=True,\n",
160+
" env=relay_env,\n",
161+
" )\n",
162+
" print(f\"relay {verb[0]}: rc={rr.returncode}\", flush=True)\n",
163+
" if rr.returncode == 0:\n",
164+
" break\n",
165+
" else:\n",
166+
" print(\"relay FAILED; url only in log/output\", flush=True)\n",
167+
" print(rr.stdout[-400:], rr.stderr[-400:], flush=True)\n",
112168
" model_name = \"sqltuned\" if with_lora else BASE_MODEL\n",
113169
" print(\n",
114170
" f\"\\n{'=' * 60}\\nTUNNEL: {url}\\nbase_url for .env: {url}/v1\\n--sql-model {model_name}\\n{'=' * 60}\\n\",\n",

‎scripts/autotune/kaggle/kernel-metadata.json‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
"enable_gpu": true,
99
"machine_shape": "NvidiaTeslaT4",
1010
"enable_internet": true,
11-
"dataset_sources": ["liovinajo/nlsql-autotune-data", "liovinajo/nlsql-autotune-prev"],
11+
"dataset_sources": [
12+
"liovinajo/nlsql-adapter",
13+
"liovinajo/nlsql-relay"
14+
],
1215
"competition_sources": [],
1316
"kernel_sources": []
14-
}
17+
}

0 commit comments

Comments
 (0)