ManmohanSharma commited on
Commit
468b3a9
·
verified ·
1 Parent(s): 2c3f055

Upload NativeSpecZ-296M.ipynb

Browse files
Files changed (1) hide show
  1. NativeSpecZ-296M.ipynb +126 -0
NativeSpecZ-296M.ipynb ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# NativeSpecZ-296M — Demo Notebook (scale-up ablation)\n",
8
+ "\n",
9
+ "A 296M-parameter unimodal foundation model for DESI spectra, trained from scratch (no AION pretrained weights) with wavelength-grid jitter augmentation. Hits the spec's ~300M target and is competitive with AION-base on DESI in-distribution, but does NOT beat AION on out-of-distribution data — the smaller NativeSpecZ-FM-76M is the recommended headline.\n",
10
+ "\n",
11
+ "**Approach A**: z head trained jointly with the encoder. \n",
12
+ "**Approach B**: `[Z_MASK]` token always masked.\n",
13
+ "\n",
14
+ "NOTE: load with `strict=False` — the current `hybrid_redshift.py` has `z_rerank_head` / `z_calib_head` modules added after this checkpoint was trained; they are unused in the `bin_residual` prediction path."
15
+ ]
16
+ },
17
+ {
18
+ "cell_type": "code",
19
+ "execution_count": null,
20
+ "metadata": {},
21
+ "outputs": [],
22
+ "source": [
23
+ "import os, sys, json\n",
24
+ "import numpy as np\n",
25
+ "import torch\n",
26
+ "from torch.utils.data import DataLoader\n",
27
+ "sys.path.append(\"code\")\n",
28
+ "from hybrid_redshift import HybridSpecZ, RawCollatorConfig, RawSpectraCollator, move_to_device\n",
29
+ "from data import SpectraListDataset, parse_mmu_example\n",
30
+ "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
31
+ "print(f\"Device: {device}\")\n",
32
+ "torch.manual_seed(42); np.random.seed(42)"
33
+ ]
34
+ },
35
+ {
36
+ "cell_type": "markdown",
37
+ "metadata": {},
38
+ "source": [
39
+ "## Load the 296M model (strict=False)"
40
+ ]
41
+ },
42
+ {
43
+ "cell_type": "code",
44
+ "execution_count": null,
45
+ "metadata": {},
46
+ "outputs": [],
47
+ "source": [
48
+ "ckpt = torch.load(\"weights/best.pt\", map_location=device, weights_only=False)\n",
49
+ "a = ckpt[\"args\"]\n",
50
+ "model = HybridSpecZ(\n",
51
+ " d_model=a[\"d_model\"], conv_width=a[\"conv_width\"], layers=a[\"layers\"],\n",
52
+ " heads=a[\"heads\"], dropout=a[\"dropout\"], z_bins=a[\"z_bins\"],\n",
53
+ " stem_stride=a[\"stem_stride\"], rec_hidden_mult=a[\"rec_hidden_mult\"],\n",
54
+ " rec_refine_width=a[\"rec_refine_width\"], rec_refine_kernel=a[\"rec_refine_kernel\"],\n",
55
+ " layerscale_init=a[\"layerscale_init\"], prediction_mode=a[\"prediction_mode\"],\n",
56
+ " bin_temperature=a[\"bin_temperature\"], residual_scale=a[\"residual_scale\"],\n",
57
+ " candidate_topk=a[\"candidate_topk\"],\n",
58
+ ").to(device)\n",
59
+ "missing, unexpected = model.load_state_dict(ckpt[\"model\"], strict=False)\n",
60
+ "model.eval()\n",
61
+ "print(f\"Params: {sum(p.numel() for p in model.parameters()):,}\")\n",
62
+ "print(f\"Missing keys (unused rerank/calib heads): {len(missing)}; unexpected: {len(unexpected)}\")"
63
+ ]
64
+ },
65
+ {
66
+ "cell_type": "markdown",
67
+ "metadata": {},
68
+ "source": [
69
+ "## Load DESI test data + run inference"
70
+ ]
71
+ },
72
+ {
73
+ "cell_type": "code",
74
+ "execution_count": null,
75
+ "metadata": {},
76
+ "outputs": [],
77
+ "source": [
78
+ "from datasets import load_dataset\n",
79
+ "from tqdm.auto import tqdm\n",
80
+ "import torch.nn.functional as F\n",
81
+ "\n",
82
+ "ds = load_dataset(\"MultimodalUniverse/desi\", split=\"train\", streaming=True).shuffle(seed=4242, buffer_size=5000)\n",
83
+ "samples = []\n",
84
+ "for ex in ds:\n",
85
+ " p = parse_mmu_example(ex)\n",
86
+ " if p is not None: samples.append(p)\n",
87
+ " if len(samples) >= 500: break\n",
88
+ "print(f\"Loaded {len(samples)} DESI spectra\")\n",
89
+ "\n",
90
+ "cfg = RawCollatorConfig(target_length=a[\"target_length\"], eval_mask_ratio=0.30, mask_mode=\"mixed_span\", mask_span_min=a[\"mask_span_min\"], mask_span_max=a[\"mask_span_max\"])\n",
91
+ "loader = DataLoader(SpectraListDataset(samples, np.arange(len(samples))), batch_size=8, shuffle=False, num_workers=2, collate_fn=RawSpectraCollator(cfg, train=False, seed=31415))\n",
92
+ "z_true_all, y_pred_all = [], []\n",
93
+ "with torch.no_grad():\n",
94
+ " for batch in tqdm(loader):\n",
95
+ " batch = move_to_device(batch, device)\n",
96
+ " with torch.autocast(device_type=device.type, dtype=torch.bfloat16, enabled=device.type==\"cuda\"):\n",
97
+ " out = model(batch[\"x\"], batch[\"valid\"], batch[\"loglam\"])\n",
98
+ " z_true_all.append(batch[\"z\"].cpu().numpy())\n",
99
+ " y_pred_all.append(out.get(\"y_pred\", out[\"y_mu\"]).float().cpu().numpy())\n",
100
+ "z_true = np.concatenate(z_true_all)\n",
101
+ "z_pred = np.clip(np.expm1(np.concatenate(y_pred_all)), 0, 6)\n",
102
+ "mae = float(np.mean(np.abs(z_pred - z_true)))\n",
103
+ "r = float(np.corrcoef(z_true, z_pred)[0,1])\n",
104
+ "print(f\"DESI MAE={mae:.4f} Pearson r={r:.4f}\")"
105
+ ]
106
+ },
107
+ {
108
+ "cell_type": "markdown",
109
+ "metadata": {},
110
+ "source": [
111
+ "## Held-out results (precomputed, n=2500/2000/2000) + comparison\n",
112
+ "\n",
113
+ "| Dataset | NativeSpecZ-296M | NativeSpecZ-76M (headline) | AION-base |\n",
114
+ "|---|---:|---:|---:|\n",
115
+ "| **DESI** | **0.067** | 0.069 | 0.074 |\n",
116
+ "| SDSS (real non-DESI) | 0.314 | 0.382 | **0.127** |\n",
117
+ "| VIPERS (real non-DESI) | 0.316 | **0.172** | 0.274 |\n",
118
+ "\n",
119
+ "The 296M ties the 76M on DESI (both beat AION) and improves SDSS over the 76M, but loses the 76M's strong VIPERS result. It beats AION-base on no OOD dataset, so the 76M remains the recommended headline; the 296M is the scale-up ablation that hits the ~300M target."
120
+ ]
121
+ }
122
+ ],
123
+ "metadata": {"kernelspec": {"display_name": "Python 3", "language": "python", "name": "python3"}, "language_info": {"name": "python", "version": "3.11"}},
124
+ "nbformat": 4,
125
+ "nbformat_minor": 4
126
+ }