Skip to content

Commit a5ff146

Browse files
committed
feat(data): report family side channels in smoke
1 parent 296274b commit a5ff146

2 files changed

Lines changed: 96 additions & 0 deletions

File tree

scripts/data_smoke.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ def run_smoke(args: argparse.Namespace) -> dict[str, Any]:
188188
batches = _read_batches(dataset, max_batches=int(args.batches))
189189
first_batch = batches[0]
190190
side_channels = _side_channel_presence(first_batch)
191+
family_side_channels = _family_side_channel_presence(first_batch)
191192
structure_channels = [
192193
key for key in STRUCTURE_SIDE_CHANNELS if side_channels.get(key, False)
193194
]
@@ -211,6 +212,10 @@ def run_smoke(args: argparse.Namespace) -> dict[str, Any]:
211212
"seq_len": batch_shape[1],
212213
"side_channel_presence": side_channels,
213214
"side_channels": [key for key, present in side_channels.items() if present],
215+
"family_side_channel_presence": family_side_channels,
216+
"family_side_channels": [
217+
family for family, columns in family_side_channels.items() if columns
218+
],
214219
"structure_side_channel_presence": {
215220
key: side_channels[key] for key in STRUCTURE_SIDE_CHANNELS
216221
},
@@ -299,6 +304,18 @@ def _side_channel_presence(batch: LMTokenBatch) -> dict[str, bool]:
299304
return dict(sorted(presence.items()))
300305

301306

307+
def _family_side_channel_presence(batch: LMTokenBatch) -> dict[str, dict[str, bool]]:
308+
if not batch.side_channels:
309+
return {}
310+
return {
311+
family: {
312+
column: value is not None
313+
for column, value in sorted(columns.items())
314+
}
315+
for family, columns in sorted(batch.side_channels.items())
316+
}
317+
318+
302319
def _dataset_receipt(dataset: TokenBatchDataset) -> dict[str, Any]:
303320
receipt: dict[str, Any] = {
304321
"batch_size": int(dataset.batch_size),

tests/test_data_smoke_script.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,43 @@ def write_parquet(path: Path) -> None:
5858
pq.write_table(table, path)
5959

6060

61+
def write_parquet_with_family_side_channels(path: Path) -> None:
62+
pa = pytest.importorskip("pyarrow")
63+
pq = pytest.importorskip("pyarrow.parquet")
64+
table = pa.table(
65+
{
66+
"token_ids": pa.array(
67+
[
68+
[1, 2, 3, 4],
69+
[5, 6, 7, 8],
70+
[9, 10, 11, 12],
71+
[13, 14, 15, 16],
72+
],
73+
type=pa.large_list(pa.uint32()),
74+
),
75+
"token_symbol_ids": pa.array(
76+
[
77+
[10, 11, 12, 13],
78+
[14, 15, 16, 17],
79+
[18, 19, 20, 21],
80+
[22, 23, 24, 25],
81+
],
82+
type=pa.large_list(pa.int32()),
83+
),
84+
"edit_op_per_token": pa.array(
85+
[
86+
[0, 0, 2, 2],
87+
[0, 3, 0, 3],
88+
[1, 1, 0, 0],
89+
[4, 0, 4, 0],
90+
],
91+
type=pa.large_list(pa.int32()),
92+
),
93+
}
94+
)
95+
pq.write_table(table, path)
96+
97+
6198
def run_script(*args: str) -> subprocess.CompletedProcess[str]:
6299
return subprocess.run(
63100
[sys.executable, str(SCRIPT), *args],
@@ -209,6 +246,8 @@ def test_parquet_smoke_reports_local_ingress_contract(tmp_path: Path) -> None:
209246
}
210247
]
211248
assert payload["side_channels"] == []
249+
assert payload["family_side_channels"] == []
250+
assert payload["family_side_channel_presence"] == {}
212251
assert payload["structure_side_channels"] == []
213252
assert payload["structure_side_channels_present"] is False
214253
assert payload["local_only"] is True
@@ -218,6 +257,46 @@ def test_parquet_smoke_reports_local_ingress_contract(tmp_path: Path) -> None:
218257
assert payload["training_wired"] is False
219258

220259

260+
def test_parquet_smoke_reports_generic_family_side_channels(tmp_path: Path) -> None:
261+
dataset_path = tmp_path / "family_side_channels.parquet"
262+
write_parquet_with_family_side_channels(dataset_path)
263+
264+
result = run_script(
265+
str(dataset_path),
266+
"--token-key",
267+
"token_ids",
268+
"--batch-size",
269+
"2",
270+
"--seq-len",
271+
"4",
272+
"--forward-smoke",
273+
)
274+
275+
assert result.returncode == 0, result.stderr
276+
payload = load_json(result)
277+
assert payload["side_channels"] == []
278+
assert payload["family_side_channels"] == ["semantic_graph", "temporal_diff"]
279+
assert payload["family_side_channel_presence"] == {
280+
"semantic_graph": {"token_symbol_ids": True},
281+
"temporal_diff": {"edit_op_per_token": True},
282+
}
283+
assert payload["dataset"]["parquet_receipt"]["family_side_channel_sources"] == {
284+
"semantic_graph": {
285+
"token_symbol_ids": {
286+
"column": "token_symbol_ids",
287+
"type": "large_list<element: int32>",
288+
}
289+
},
290+
"temporal_diff": {
291+
"edit_op_per_token": {
292+
"column": "edit_op_per_token",
293+
"type": "large_list<element: int32>",
294+
}
295+
},
296+
}
297+
assert payload["forward"]["side_channel_model_kwargs"] == []
298+
299+
221300
def test_megatron_multishard_smoke_reports_side_channels(tmp_path: Path) -> None:
222301
_write_structured_multishard_fixture(
223302
tmp_path,

0 commit comments

Comments
 (0)