torchlens.dataset_extraction¶
Batched dataset extraction with a self-describing, resumable disk artifact.
This module is the public face of the extraction v2 runtime (extract memo
items 4-19; the engine lives in :mod:torchlens._extraction). In disk mode
(path=) the artifact directory is the v2 layout: a
BOUNDED manifest.json (written at creation, once when batch zero freezes
the plan, and at terminal status — never per shard), an APPEND-ONLY fsynced
ledger.jsonl with one line per committed shard, a write-once ordered
stimulus_ids.json sidecar, and immutable batch-major shards
(safetensors by default; .pt stays readable forever and writable via
shard_format="pt"). The commit protocol is validate -> temp shard ->
flush/fsync -> atomic rename -> append/fsync ledger row.
Every batch travels the ONE manifested store pipeline::
collate -> position/mask validation -> model call -> selected output
-> pool (captured dtype, raw axes, mask) -> postprocess
-> row + logical-shape validation -> per-key save-dtype cast
-> CPU-contiguous snapshot -> writer
The run signature carries MODEL IDENTITY, the collate policy, callable identity, pool/dtype/ragged policies, and the selector request — all compared FIELD BY FIELD on resume.
Read artifacts back through :func:open_extraction (the documented lazy
path) or :func:load_extraction (the eager compatibility wrapper behind an
exact byte guard); export with :func:export_extraction.
Every spelling introduced here is DOCUMENTED-UNSTABLE pending the naming/UI sprint.
BatchEnvelope
dataclass
¶
One collated batch, typed.
Attributes:
| Name | Type | Description |
|---|---|---|
args |
tuple[Any, ...]
|
Positional arguments for |
kwargs |
dict[str, Any]
|
Keyword arguments for |
num_rows |
int
|
INPUT-derived number of stimulus rows in this batch — the row-truth every selected output is validated against. |
mask |
Tensor | None
|
The batch's two-dimensional attention mask when the collator
supplied one (nonzero = token present); |
disclosure |
dict[str, Any]
|
JSON-portable collate disclosure recorded in the manifest and the resume signature (collate kind, tokenizer identity, pad-token source, ...). |
Examples:
>>> envelope = BatchEnvelope(args=(x,), kwargs={}, num_rows=1, mask=None, disclosure={})
>>> envelope.num_rows
1
>>> envelope.first_input() is x
True
first_input ¶
Return the batch's primary input container for legacy paths.
Returns:
| Type | Description |
|---|---|
Any
|
The single positional arg when there is exactly one and no kwargs, else the kwargs mapping when purely keyword-shaped, else the args tuple. |
RaggedBatch
dataclass
¶
One shard's trimmed carrier for one output key (the Arrow triplet).
Attributes:
| Name | Type | Description |
|---|---|---|
values |
Tensor
|
Packed per-row slices concatenated along axis 0:
|
offsets |
Tensor
|
|
row_shapes |
tuple[tuple[int, ...], ...]
|
Per-row logical shapes (each row's true |
Examples:
>>> batch = RaggedBatch(
... values=torch.zeros(5, 4), offsets=torch.tensor([0, 2, 5]), row_shapes=((2, 4), (3, 4))
... )
>>> batch.num_rows
2
>>> tuple(batch.row(1).shape)
(3, 4)
TokenRows
dataclass
¶
Stored keys flattened to one row per token (DOCUMENTED-UNSTABLE).
Attributes:
| Name | Type | Description |
|---|---|---|
values |
dict[str, Tensor]
|
|
stimulus_row |
Tensor
|
|
position |
Tensor
|
|
Examples:
>>> import tempfile
>>> def collate(texts):
... ids = torch.tensor([[int(word) for word in text.split()] for text in texts])
... return {"input_ids": ids, "attention_mask": torch.ones_like(ids)}
>>> class Embed(nn.Module):
... def __init__(self):
... super().__init__()
... self.emb = nn.Embedding(10, 4)
... def forward(self, input_ids, attention_mask=None):
... return self.emb(input_ids)
>>> with tempfile.TemporaryDirectory() as folder:
... _ = tl.dataset_extraction.extract_dataset(
... Embed().eval(), ["1 2", "3 4 5"], {"h": "emb"}, batch_size=1, path=folder,
... collate=collate, ragged="trim", progress=False,
... )
... tokens = tl.dataset_extraction.open_extraction(folder).token_rows()
>>> tokens.num_tokens, tokens.position.tolist()
(5, [0, 1, 0, 1, 2])
num_tokens
property
¶
Return the number of token rows.
Returns:
| Type | Description |
|---|---|
int
|
|
LoadedExtraction
dataclass
¶
A dataset-extraction artifact read back with its self-description.
Attributes:
| Name | Type | Description |
|---|---|---|
manifest |
dict[str, Any]
|
Parsed |
activations |
dict[str, Any]
|
Materialized payloads keyed by output key: concatenated tensors
for dense keys, one merged
:class: |
batch_paths |
list[Path]
|
Shard files in ledger consumption order. |
Examples:
>>> import tempfile
>>> with tempfile.TemporaryDirectory() as tmp:
... stimuli = torch.randn(4, 3, 8, 8)
... _ = tl.extract_dataset(model, stimuli, ["1"], path=tmp, progress=False)
... loaded = tl.dataset_extraction.load_extraction(tmp)
... shape = tuple(loaded.activations["1"].shape)
>>> isinstance(loaded, LoadedExtraction), shape
(True, (4, 4, 8, 8))
input_preprocessing
property
¶
The manifest's input-preprocessing block (legacy reads as unknown).
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
See :func: |
export_extraction ¶
export_extraction(path: str | Path, dest: str | Path, *, file_format: str = 'npy', keys: list[str] | None = None, widen_unsupported: bool = True) -> Path
Export one COMPLETE extraction artifact (read-only, streaming).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Source artifact directory. |
required |
dest
|
str | Path
|
Destination directory (created; published atomically by rename). |
required |
file_format
|
str
|
|
'npy'
|
keys
|
list[str] | None
|
Optional output-key subset. |
None
|
widen_unsupported
|
bool
|
Widen bf16/fp8 members to fp32 with disclosure (default) or refuse typed. |
True
|
Returns:
| Type | Description |
|---|---|
Path
|
The published destination directory. |
Raises:
| Type | Description |
|---|---|
InvalidArgumentError
|
|
Examples:
>>> import tempfile
>>> from pathlib import Path
>>> stimuli = [torch.randn(3, 8, 8) for _ in range(2)]
>>> with tempfile.TemporaryDirectory() as src, tempfile.TemporaryDirectory() as out:
... _ = tl.dataset_extraction.extract_dataset(
... model, stimuli, {"relu": "1"}, batch_size=2, path=src, progress=False
... )
... dest = export_extraction(src, Path(out) / "npy", file_format="npy")
... print(dest.name, dest.is_dir())
npy True
hf_collate ¶
hf_collate(tokenizer: Any = None, *, pad_token: str | None = None, **tokenizer_kwargs: Any) -> Callable[[list[Any], nn.Module, dict[str, Any]], BatchEnvelope]
Build the HF text collate helper (DOCUMENTED-UNSTABLE).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tokenizer
|
Any
|
Caller-supplied tokenizer (first in the resolution order); |
None
|
pad_token
|
str | None
|
|
None
|
**tokenizer_kwargs
|
Any
|
Extra tokenizer call kwargs ( |
{}
|
Returns:
| Type | Description |
|---|---|
Callable
|
An engine collate callable: |
Examples:
open_extraction ¶
open_extraction(path: str | Path, *, verify: str = 'structural', in_progress: bool = False) -> ExtractionReader
Open one extraction artifact lazily (the documented read path).
Opening reads bounded manifest/ledger metadata only; payload bytes move on demand through the reader.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Artifact directory written by disk-mode |
required |
verify
|
str
|
|
'structural'
|
in_progress
|
bool
|
Open a still-writing artifact's trusted committed prefix;
|
False
|
Returns:
| Type | Description |
|---|---|
ExtractionReader
|
The lazy reader. |
Raises:
| Type | Description |
|---|---|
DatasetExtractionResumeError
|
On a missing/invalid manifest or an incomplete artifact opened
without |
InvalidArgumentError
|
|
Examples:
>>> import tempfile
>>> stimuli = [torch.randn(3, 8, 8) for _ in range(4)]
>>> with tempfile.TemporaryDirectory() as folder:
... _ = tl.dataset_extraction.extract_dataset(
... model, stimuli, {"relu": "1"}, batch_size=2, path=folder, progress=False
... )
... reader = open_extraction(folder)
... print(reader.keys, reader.n_stimuli, tuple(reader.row(0)["relu"].shape))
['relu'] 4 (4, 8, 8)
register_pure_module ¶
Register a module namespace as pure for callable classification.
Registration is an AUDITED ASSERTION, not an invisible trust grant: the module name and its installed version are recorded in every classification record that folds it, and those records ride the extraction manifest.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Top-level module name (e.g. |
required |
Raises:
| Type | Description |
|---|---|
InvalidArgumentError
|
|
Examples:
extract_dataset ¶
extract_dataset(model: Module, stimuli: Any, layers: Any, batch_size: int = 32, device: device | str | None = None, path: str | Path | None = None, output_transform: Any = None, progress: bool = True, *, resume: bool = False, stimulus_ids: Iterable[str] | None = None, model_identity: Any = 'measured', input_transform: Any = None, input_provenance: Any = None, collate: Any = None, pool: Any = None, dtype: Any = None, ragged: str = 'refuse', shard_format: str | None = None, checksums: str = 'fast', pipeline_id: str | None = None, intervene: Any = None, store_input_ids: bool = False) -> dict[str, torch.Tensor] | list[Path]
Extract outputs from an iterable dataset in batches.
Row i of every stored tensor corresponds to stimulus i in
iteration order; shards are consumed in ledger order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Module
|
PyTorch model to run. |
required |
stimuli
|
Any
|
Tensor with a leading batch dimension, or an iterable of stimulus items (tensors, containers, or TEXT strings — text routes through the once-per-run tokenizer with padding and the full mapping forwarded). |
required |
layers
|
Any
|
List or mapping of layer lookups (:func: |
required |
batch_size
|
int
|
Number of stimuli per forward pass. |
32
|
device
|
device | str | None
|
Optional device for model and stimuli. |
None
|
path
|
str | Path | None
|
Optional directory. When supplied, each batch is committed as an immutable shard under the v2 protocol and paths are returned. |
None
|
output_transform
|
Any
|
Transform slot, through the ONE :func: |
None
|
progress
|
bool
|
Whether to wrap batch iteration with |
True
|
resume
|
bool
|
Disk mode only (DOCUMENTED-UNSTABLE): continue an interrupted run
from its trusted ledger prefix. Every semantic signature field is
compared individually; the skipped prefix is
replayed at zero forward cost and verified against the ledgered
per-shard |
False
|
stimulus_ids
|
Iterable[str] | None
|
Optional per-stimulus identifiers (DOCUMENTED-UNSTABLE): non-empty
strings, duplicates legal (recorded as |
None
|
model_identity
|
Any
|
Disk mode (DOCUMENTED-UNSTABLE): |
'measured'
|
input_transform
|
Any
|
The unambiguous INPUT-preprocessing path (tvscope B5,
DOCUMENTED-UNSTABLE spelling), distinct from |
None
|
input_provenance
|
Any
|
Provenance-only stamp (tvscope B4, DOCUMENTED-UNSTABLE spelling) for
stimuli preprocessed OUTSIDE this run: a
:class: |
None
|
collate
|
Any
|
Optional collate (DOCUMENTED-UNSTABLE): a callable receiving the
batch's item list and returning a
:class: |
None
|
pool
|
Any
|
Optional pool preset (DOCUMENTED-UNSTABLE): one of
|
None
|
dtype
|
Any
|
Optional save dtype (DOCUMENTED-UNSTABLE): a
|
None
|
ragged
|
str
|
|
'refuse'
|
shard_format
|
str | None
|
|
None
|
checksums
|
str
|
The integrity level: |
'fast'
|
pipeline_id
|
str | None
|
Caller-asserted pipeline identity: permits resuming past a PARTIAL callable classification or a deliberate complete-class refactor, with strict continuity — the id must already be recorded in the artifact's prefix. |
None
|
intervene
|
Any
|
Optional :class: |
None
|
store_input_ids
|
bool
|
Store each batch's token ids as the ordinary |
False
|
Returns:
| Type | Description |
|---|---|
dict[str, Tensor] | list[Path]
|
In-memory outputs on the model's device (no host copy), or shard paths. |
Raises:
| Type | Description |
|---|---|
InvalidArgumentError
|
On closed-vocabulary violations, in-memory false affordances, left-padding that cannot be corrected, row-count drift, ragged refusals, pool/dtype geometry refusals, and id validation. |
DatasetExtractionResumeError
|
When the artifact in |
TransformContractError
|
When the transform slot cannot be coerced or violates its plan. |
Notes
Every forward runs under torch.no_grad() with the model in eval
mode, and every submodule's exact training flag is restored
afterward (exception paths included).
Examples:
>>> stimuli = torch.randn(4, 3, 8, 8)
>>> out = tl.extract_dataset(model, stimuli, ["1"], batch_size=2, progress=False)
>>> tuple(out["1"].shape)
(4, 4, 8, 8)
>>> import tempfile
>>> with tempfile.TemporaryDirectory() as tmp:
... shards = tl.extract_dataset(
... model, stimuli, ["1"], batch_size=2, path=tmp, progress=False
... )
... len(shards)
2
load_extraction ¶
load_extraction(path: str | Path, layers: Iterable[str] | None = None, *, max_bytes: int | None = None) -> LoadedExtraction
Eagerly load a disk-mode extraction artifact (the guarded wrapper).
This is a thin materialization over :func:open_extraction — the
documented lazy path — behind an EXACT byte guard computed from ledger
facts before any allocation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Directory previously written by disk-mode :func: |
required |
layers
|
Iterable[str] | None
|
Optional subset of output keys to load; defaults to every key. |
None
|
max_bytes
|
int | None
|
Optional explicit byte-budget override for the guard ( |
None
|
Returns:
| Type | Description |
|---|---|
LoadedExtraction
|
Manifest, materialized activations, and shard paths. |
Raises:
| Type | Description |
|---|---|
DatasetExtractionResumeError
|
If the manifest is missing/invalid or the artifact is incomplete. |
InvalidArgumentError
|
|
relabel_extraction ¶
Relabel a COMPLETE artifact's stimulus ids (the audited verb).
Relabeling is deliberately OUT of resume — the sidecar is write-once
there — and produces a NEW artifact identity: the manifest's id digest
changes, the prior digest is recorded, and an audit line rides the
manifest permanently. Per-shard ledger ids_range_digest facts keep
describing the WRITE-TIME labeling (the ledger is append-only); the
audit trail is the pointer between the two.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Artifact directory. |
required |
new_ids
|
Iterable[str]
|
Replacement identifiers, one per stimulus row, in row order. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
The appended audit record. |
Raises:
| Type | Description |
|---|---|
InvalidArgumentError
|
|
Examples:
>>> import tempfile
>>> with tempfile.TemporaryDirectory() as tmp:
... stimuli = torch.randn(2, 3, 8, 8)
... _ = tl.extract_dataset(
... model, stimuli, ["1"], path=tmp, progress=False, stimulus_ids=["a", "b"]
... )
... audit = relabel_extraction(tmp, ["first", "second"])
... ids = tl.dataset_extraction.open_extraction(tmp).stimulus_ids()
>>> audit["kind"], ids
('relabel', ['first', 'second'])