AbstractPhil commited on
Commit
02253aa
·
verified ·
1 Parent(s): 8039dec

Caption key corrected per the campaign record: qwen-deepfashion-fused stays THE dataset (r2 exp011-013 design of record); caption = caption_joycaption with prompt_fused fallback (dexp011:154), materialized as a derived column; exp011 audit gate + id dedup in the split. The earlier ft1 retarget was wrong — the fix was the key, not the dataset.

Browse files
Files changed (1) hide show
  1. colab/anima_closeout.ipynb +96 -52
colab/anima_closeout.ipynb CHANGED
@@ -138,30 +138,30 @@
138
  "print(\"Anima split_files present \u2014 NC weights; derived ckpts inherit NC\")\n",
139
  "\n",
140
  "# -- 5. dataset columns, verified BEFORE anything spends ------------------\n",
141
- "# exp004's actual source: diffusion-pretrain-set-ft1, deepfashion config \u2014\n",
142
- "# the dataset whose shards were the pod's ft1_shards and which carries\n",
143
- "# caption_vlm_json. (qwen-deepfashion-fused does NOT have that column; the\n",
144
- "# first campaign run caught this exactly here, at zero cost.) The repo\n",
145
- "# holds 582 parquet files across many configs \u2014 filter to deepfashion or\n",
146
- "# the split cell would download all of them.\n",
147
- "DATASET = \"AbstractPhil/diffusion-pretrain-set-ft1\"\n",
148
- "DATASET_SUBDIR = \"data/deepfashion/\"\n",
149
  "from huggingface_hub import HfApi\n",
150
  "SHARDS = sorted(f for f in HfApi().list_repo_files(\n",
151
- " DATASET, repo_type=\"dataset\")\n",
152
- " if f.endswith(\".parquet\") and f.startswith(DATASET_SUBDIR))\n",
153
- "assert SHARDS, f\"no parquet shards under {DATASET_SUBDIR} in {DATASET}\"\n",
154
- "print(f\"deepfashion shards: {len(SHARDS)}\")\n",
155
  "import pyarrow.parquet as pq\n",
156
  "_p0 = hf_hub_download(DATASET, SHARDS[0], repo_type=\"dataset\")\n",
157
  "_cols = set(pq.read_schema(_p0).names)\n",
158
- "_missing = {\"image\", \"caption_vlm_json\"} - _cols\n",
159
  "assert not _missing, f\"dataset lacks {_missing}; has {sorted(_cols)[:24]}\"\n",
160
  "ANIMA.update(DATASET=DATASET, SHARDS=SHARDS,\n",
161
  " HAS_WH={\"image_width\", \"image_height\"} <= _cols,\n",
162
- " ID_COL=\"id\" if \"id\" in _cols else None)\n",
163
- "print(f\"dataset OK: {len(SHARDS)} shard(s); wh cols {ANIMA['HAS_WH']}; \"\n",
164
- " f\"id col {ANIMA['ID_COL']}\")\n",
 
 
165
  "print(\"\\n=== READY ===\")\n"
166
  ]
167
  },
@@ -171,11 +171,16 @@
171
  "execution_count": null,
172
  "outputs": [],
173
  "source": [
174
- "# \u2550\u2550\u2550 CELL 1 \u2014 materialize the held-out split + write all TOMLs \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n",
175
- "# Deterministic row-hash split: 512 eval rows, disjoint by construction,\n",
176
- "# recorded in split_manifest.json (the reproducibility anchor). Both sides\n",
177
- "# read the SAME materialized parquet. caption_type='text' = exp004's\n",
178
- "# verbatim-JSON recipe (flattened-'json' is the recorded alternative).\n",
 
 
 
 
 
179
  "import hashlib, json\n",
180
  "import pyarrow as pa\n",
181
  "import pyarrow.parquet as pq\n",
@@ -186,40 +191,72 @@
186
  "EVAL_PARQUET = DATA / \"eval.parquet\"\n",
187
  "MANIFEST = DATA / \"split_manifest.json\"\n",
188
  "\n",
 
 
 
 
 
 
189
  "if not MANIFEST.exists():\n",
190
- " _paths = [hf_hub_download(ANIMA[\"DATASET\"], s, repo_type=\"dataset\")\n",
191
- " for s in ANIMA[\"SHARDS\"]]\n",
192
- "\n",
193
- " def _row_key(si, ri, batch, j):\n",
194
- " if ANIMA[\"ID_COL\"]:\n",
195
- " return str(batch.column(ANIMA[\"ID_COL\"])[j].as_py())\n",
196
- " cap = str(batch.column(\"caption_vlm_json\")[j].as_py())[:256]\n",
197
- " return f\"{si}:{ri}:{hashlib.sha1(cap.encode()).hexdigest()[:12]}\"\n",
198
- "\n",
199
- " _key_cols = [c for c in (ANIMA[\"ID_COL\"], \"caption_vlm_json\") if c]\n",
200
- " ranked = []\n",
201
- " for si, p in enumerate(_paths):\n",
202
  " ri = 0\n",
203
- " for batch in pq.ParquetFile(p).iter_batches(batch_size=256,\n",
204
- " columns=_key_cols):\n",
205
  " for j in range(batch.num_rows):\n",
206
- " k = _row_key(si, ri, batch, j)\n",
207
- " ranked.append(\n",
208
- " (hashlib.sha256(k.encode()).hexdigest(), si, ri, k))\n",
 
 
 
 
 
 
 
 
209
  " ri += 1\n",
210
  " ranked.sort()\n",
 
 
 
 
211
  " eval_set = {(si, ri) for _h, si, ri, _k in ranked[:EVAL_N]}\n",
212
- " total = len(ranked)\n",
213
  "\n",
 
214
  " ew = tw = None\n",
215
- " for si, p in enumerate(_paths):\n",
 
 
216
  " ri = 0\n",
217
- " for batch in pq.ParquetFile(p).iter_batches(batch_size=64):\n",
218
  " tbl = pa.Table.from_batches([batch])\n",
219
- " emask = [(si, ri + j) in eval_set for j in range(batch.num_rows)]\n",
220
- " ri += batch.num_rows\n",
 
 
 
 
 
 
 
 
 
 
221
  " esub = tbl.filter(pa.array(emask))\n",
222
- " tsub = tbl.filter(pa.array([not m for m in emask]))\n",
 
223
  " if esub.num_rows:\n",
224
  " if ew is None:\n",
225
  " ew = pq.ParquetWriter(EVAL_PARQUET, esub.schema)\n",
@@ -233,16 +270,24 @@
233
  " if w:\n",
234
  " w.close()\n",
235
  " MANIFEST.write_text(json.dumps(\n",
236
- " {\"dataset\": ANIMA[\"DATASET\"], \"total_rows\": total, \"eval_n\": EVAL_N,\n",
 
 
237
  " \"eval_ids\": [k for _h, _s, _r, k in ranked[:EVAL_N]],\n",
238
- " \"rule\": \"sha256(row_key) ascending; first EVAL_N rows are eval\"},\n",
 
 
 
 
239
  " indent=1))\n",
240
- " print(f\"split: {total} rows -> {total - EVAL_N} train + {EVAL_N} eval\")\n",
 
241
  "else:\n",
242
- " print(\"split already materialized:\",\n",
243
- " json.loads(MANIFEST.read_text())[\"total_rows\"], \"rows\")\n",
 
244
  "\n",
245
- "# -- dataset TOMLs (the exp004 recipe) ------------------------------------\n",
246
  "_wh = (\"image_width_column = 'image_width'\\n\"\n",
247
  " \"image_height_column = 'image_height'\\n\") if ANIMA[\"HAS_WH\"] else \"\"\n",
248
  "\n",
@@ -260,7 +305,7 @@
260
  "type = 'parquet'\n",
261
  "parquet_files = '{files}'\n",
262
  "image_column = 'image'\n",
263
- "{_wh}caption_column = 'caption_vlm_json'\n",
264
  "caption_type = 'text'\n",
265
  "num_repeats = 1\n",
266
  "skip_empty_caption = true\n",
@@ -269,7 +314,6 @@
269
  "(TOMLS / \"dataset_train.toml\").write_text(\n",
270
  " _dataset_toml(f\"{TRAIN_DIR}/*.parquet\"))\n",
271
  "(TOMLS / \"dataset_eval.toml\").write_text(_dataset_toml(str(EVAL_PARQUET)))\n",
272
- "\n",
273
  "# -- training TOMLs per arm -----------------------------------------------\n",
274
  "_AP = WORK / \"models\" / \"anima\" / \"split_files\"\n",
275
  "\n",
 
138
  "print(\"Anima split_files present \u2014 NC weights; derived ckpts inherit NC\")\n",
139
  "\n",
140
  "# -- 5. dataset columns, verified BEFORE anything spends ------------------\n",
141
+ "# THE DATASET IS qwen-deepfashion-fused (the fused line's design of record:\n",
142
+ "# r2 exp011/012/013 all trained on it). The CAPTION KEY per the record is\n",
143
+ "# caption_joycaption with prompt_fused fallback (pod2/dexp011:154; results\n",
144
+ "# cond = \"caption_joycaption nl77\"). caption_vlm_json belongs to the older\n",
145
+ "# ft1 shards and does NOT exist here \u2014 the first campaign run's pre-spend\n",
146
+ "# column check caught exactly that; the fix was the key, not the dataset.\n",
147
+ "DATASET = \"AbstractPhil/qwen-deepfashion-fused\"\n",
 
148
  "from huggingface_hub import HfApi\n",
149
  "SHARDS = sorted(f for f in HfApi().list_repo_files(\n",
150
+ " DATASET, repo_type=\"dataset\") if f.endswith(\".parquet\"))\n",
151
+ "assert SHARDS, f\"no parquet shards in {DATASET}\"\n",
152
+ "print(f\"shards: {len(SHARDS)} (incl. the shard_r0_* series)\")\n",
 
153
  "import pyarrow.parquet as pq\n",
154
  "_p0 = hf_hub_download(DATASET, SHARDS[0], repo_type=\"dataset\")\n",
155
  "_cols = set(pq.read_schema(_p0).names)\n",
156
+ "_missing = {\"image\", \"caption_joycaption\", \"id\"} - _cols\n",
157
  "assert not _missing, f\"dataset lacks {_missing}; has {sorted(_cols)[:24]}\"\n",
158
  "ANIMA.update(DATASET=DATASET, SHARDS=SHARDS,\n",
159
  " HAS_WH={\"image_width\", \"image_height\"} <= _cols,\n",
160
+ " HAS_FUSED_JSON=\"fused_json\" in _cols,\n",
161
+ " HAS_PROMPT_FUSED=\"prompt_fused\" in _cols,\n",
162
+ " ID_COL=\"id\")\n",
163
+ "print(f\"dataset OK: wh cols {ANIMA['HAS_WH']}; fused_json \"\n",
164
+ " f\"{ANIMA['HAS_FUSED_JSON']}; prompt_fused {ANIMA['HAS_PROMPT_FUSED']}\")\n",
165
  "print(\"\\n=== READY ===\")\n"
166
  ]
167
  },
 
171
  "execution_count": null,
172
  "outputs": [],
173
  "source": [
174
+ "# \u2550\u2550\u2550 CELL 1 \u2014 materialize the gated held-out split + write TOMLs \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n",
175
+ "# Row pipeline, exactly the campaign record:\n",
176
+ "# AUDIT GATE (pod2/dexp011:98-105): a row passes when its age_audit/audit\n",
177
+ "# value contains \"approved\" or \"pass\" (case-insensitive); gated rows are\n",
178
+ "# counted and reported loudly.\n",
179
+ "# DEDUP by id (first occurrence wins) \u2014 guards the stray rank0.part00\n",
180
+ "# shard alongside the shard_r0_* series.\n",
181
+ "# CAPTION = caption_joycaption or prompt_fused fallback (dexp011:154),\n",
182
+ "# materialized as a `caption` column so the fork reads one key.\n",
183
+ "# SPLIT: sha256(id) ascending; first EVAL_N surviving rows are eval.\n",
184
  "import hashlib, json\n",
185
  "import pyarrow as pa\n",
186
  "import pyarrow.parquet as pq\n",
 
191
  "EVAL_PARQUET = DATA / \"eval.parquet\"\n",
192
  "MANIFEST = DATA / \"split_manifest.json\"\n",
193
  "\n",
194
+ "def _passes_gate(row_get):\n",
195
+ " vals = [str(row_get(c)) for c in (\"age_audit\", \"audit\")\n",
196
+ " if row_get(c) is not None]\n",
197
+ " return (not vals) or any((\"approved\" in v.lower() or \"pass\" in v.lower())\n",
198
+ " for v in vals)\n",
199
+ "\n",
200
  "if not MANIFEST.exists():\n",
201
+ " _paths = [hf_hub_download(ANIMA[\"DATASET\"], sh, repo_type=\"dataset\")\n",
202
+ " for sh in ANIMA[\"SHARDS\"]]\n",
203
+ "\n",
204
+ " # pass 1: gate + dedup + rank survivors by sha256(id)\n",
205
+ " _key_cols = [c for c in (\"id\", \"caption_joycaption\", \"prompt_fused\",\n",
206
+ " \"age_audit\", \"audit\")\n",
207
+ " if True]\n",
208
+ " seen_ids, ranked = set(), []\n",
209
+ " n_seen = n_gated = n_dup = 0\n",
210
+ " for si, pth in enumerate(_paths):\n",
211
+ " pf = pq.ParquetFile(pth)\n",
212
+ " avail = [c for c in _key_cols if c in pf.schema_arrow.names]\n",
213
  " ri = 0\n",
214
+ " for batch in pf.iter_batches(batch_size=256, columns=avail):\n",
215
+ " cols = {c: batch.column(c) for c in avail}\n",
216
  " for j in range(batch.num_rows):\n",
217
+ " n_seen += 1\n",
218
+ " get = lambda c: (cols[c][j].as_py() if c in cols else None)\n",
219
+ " rid = str(get(\"id\"))\n",
220
+ " if not _passes_gate(get):\n",
221
+ " n_gated += 1\n",
222
+ " elif rid in seen_ids:\n",
223
+ " n_dup += 1\n",
224
+ " else:\n",
225
+ " seen_ids.add(rid)\n",
226
+ " ranked.append((hashlib.sha256(rid.encode()).hexdigest(),\n",
227
+ " si, ri, rid))\n",
228
  " ri += 1\n",
229
  " ranked.sort()\n",
230
+ " assert len(ranked) > 4 * EVAL_N, (\n",
231
+ " f\"only {len(ranked)} rows survive the audit gate \"\n",
232
+ " f\"(saw {n_seen}, gated {n_gated}, dup {n_dup}) \u2014 inspect before \"\n",
233
+ " \"training on so little\")\n",
234
  " eval_set = {(si, ri) for _h, si, ri, _k in ranked[:EVAL_N]}\n",
235
+ " keep_set = {(si, ri) for _h, si, ri, _k in ranked}\n",
236
  "\n",
237
+ " # pass 2: route rows, appending the derived caption column\n",
238
  " ew = tw = None\n",
239
+ " for si, pth in enumerate(_paths):\n",
240
+ " pf = pq.ParquetFile(pth)\n",
241
+ " names = pf.schema_arrow.names\n",
242
  " ri = 0\n",
243
+ " for batch in pf.iter_batches(batch_size=64):\n",
244
  " tbl = pa.Table.from_batches([batch])\n",
245
+ " jc = tbl.column(\"caption_joycaption\")\n",
246
+ " pfu = (tbl.column(\"prompt_fused\")\n",
247
+ " if \"prompt_fused\" in names else None)\n",
248
+ " caps, kmask, emask = [], [], []\n",
249
+ " for j in range(tbl.num_rows):\n",
250
+ " c = jc[j].as_py() or (pfu[j].as_py() if pfu is not None\n",
251
+ " else None) or \"\"\n",
252
+ " caps.append(str(c))\n",
253
+ " kmask.append((si, ri + j) in keep_set)\n",
254
+ " emask.append((si, ri + j) in eval_set)\n",
255
+ " ri += tbl.num_rows\n",
256
+ " tbl = tbl.append_column(\"caption\", pa.array(caps))\n",
257
  " esub = tbl.filter(pa.array(emask))\n",
258
+ " tsub = tbl.filter(pa.array([k and not e for k, e\n",
259
+ " in zip(kmask, emask)]))\n",
260
  " if esub.num_rows:\n",
261
  " if ew is None:\n",
262
  " ew = pq.ParquetWriter(EVAL_PARQUET, esub.schema)\n",
 
270
  " if w:\n",
271
  " w.close()\n",
272
  " MANIFEST.write_text(json.dumps(\n",
273
+ " {\"dataset\": ANIMA[\"DATASET\"], \"rows_seen\": n_seen,\n",
274
+ " \"gated_out\": n_gated, \"duplicate_ids\": n_dup,\n",
275
+ " \"rows_kept\": len(ranked), \"eval_n\": EVAL_N,\n",
276
  " \"eval_ids\": [k for _h, _s, _r, k in ranked[:EVAL_N]],\n",
277
+ " \"caption_rule\": \"caption_joycaption or prompt_fused fallback \"\n",
278
+ " \"(dexp011:154; cond = caption_joycaption nl77)\",\n",
279
+ " \"gate_rule\": \"age_audit/audit must contain approved|pass \"\n",
280
+ " \"(dexp011:98-105)\",\n",
281
+ " \"split_rule\": \"sha256(id) ascending; first EVAL_N are eval\"},\n",
282
  " indent=1))\n",
283
+ " print(f\"split: seen {n_seen} -> gated {n_gated}, dup {n_dup}, kept \"\n",
284
+ " f\"{len(ranked)} = {len(ranked) - EVAL_N} train + {EVAL_N} eval\")\n",
285
  "else:\n",
286
+ " _m = json.loads(MANIFEST.read_text())\n",
287
+ " print(f\"split already materialized: kept {_m['rows_kept']} \"\n",
288
+ " f\"(gated {_m['gated_out']}, dup {_m['duplicate_ids']})\")\n",
289
  "\n",
290
+ "# -- dataset TOMLs (fused recipe: derived caption column) -----------------\n",
291
  "_wh = (\"image_width_column = 'image_width'\\n\"\n",
292
  " \"image_height_column = 'image_height'\\n\") if ANIMA[\"HAS_WH\"] else \"\"\n",
293
  "\n",
 
305
  "type = 'parquet'\n",
306
  "parquet_files = '{files}'\n",
307
  "image_column = 'image'\n",
308
+ "{_wh}caption_column = 'caption'\n",
309
  "caption_type = 'text'\n",
310
  "num_repeats = 1\n",
311
  "skip_empty_caption = true\n",
 
314
  "(TOMLS / \"dataset_train.toml\").write_text(\n",
315
  " _dataset_toml(f\"{TRAIN_DIR}/*.parquet\"))\n",
316
  "(TOMLS / \"dataset_eval.toml\").write_text(_dataset_toml(str(EVAL_PARQUET)))\n",
 
317
  "# -- training TOMLs per arm -----------------------------------------------\n",
318
  "_AP = WORK / \"models\" / \"anima\" / \"split_files\"\n",
319
  "\n",