Three steps
1
Preprocess locally
common/data/prepare_*.py and produce a local directory (parquet / jsonl).2
Versioned upload
3
Reference in training
Prefer writing it into the experiment config:Or override temporarily at submission:At job startup, the platform pulls the dataset to the cluster shared cache (with integrity verification; corruption triggers an automatic re-pull) and injects the
<NAME>_DATA_DIR environment variable; --train-data takes just the relative filename within the dataset.Writing a dataset card
A dataset with nothing but a name is a black box to everyone except whoever uploaded it — and picking the wrong data costs hundreds of GPU hours. Put the description in aREADME.md inside
the data directory and sf dataset push publishes it along with the data:
Management
/data) carries the description, latest version,
file count, size, formats and update time — no need to open datasets one by one to compare them.
Opening one gives you four tabs:
Parquet
Parquet is the most common training-data format here, and its preview works out of the box (pyarrow ships with the control plane; it is not an optional extra). It gives you two things
jsonl and csv cannot:
- The total row count, read from the footer at the end of the file — a few KB. jsonl and csv would need a full scan, so those formats show ”—” here rather than a guessed number.
- Declared column types (
int64/string/timestamp[us]…). More reliable than types inferred from the first few rows: a sample that happens to be all integers does not make the column an integer column, and an all-null sample does not mean the column has no type.
Column lengths in the preview are measured before truncation. Sample cells are cut to 160
characters on their way to the browser, so an average computed from the samples would always
equal the truncation cap — a number you cannot size
max_seq_len with.“Referenced by N jobs” is platform-wide; the job list below it still only shows jobs you can
already see.The dataset manifest (with presigned URLs) is generated at submission and written into the job package — the job side needs no object storage credentials and no access to the console; one fewer runtime dependency means one fewer failure point.
Scanning for sensitive values
After a version is published, the reconcile pass scans it once and the result appears on the dataset page. It produces a report and never rewrites what you uploaded. Every comparable tool draws this line — Cloud DLP’sinspect and deidentify are two calls you
make separately, Macie reports and does not touch the object — and the reason is
sharper here. A reflow buffer is something the platform produced, so rewriting
one is its business. A training set is your material: rewriting it silently
changes what a model learns, cannot be undone, and leaves nobody able to explain
a result afterwards.
To clean it, use a Processing Run: read the material, run your own
treatment, publish a new version. Your code, in the platform, with provenance.
It samples, and says how much
A hundred-gigabyte dataset cannot be read on the way to a submission. The scan reads bounded windows and reports how many rows it read. A sampled scan can never say “clean” — only “nothing in what I looked at” — and a report that omits its sample size is one somebody will eventually quote as proof. Windows are spread across each file rather than taken from the head. A bad export is appended and a test fixture sits at the top, so a head-only sample systematically misses the case most worth catching.Confidence, not a boolean
Every rule carries a severity.api_key, private_key and a checksum-valid
identity number are high; email and phone are medium; the generic
long-token rule is low — it hits every base64 blob and git SHA in a code
corpus.
So the blocking policy (FORGE_DATA_SCAN_POLICY=block) only fires on high.
A gate that refuses work over low-confidence heuristics is one somebody turns off
within a week, taking the useful half with it.
Your own terms
FORGE_DATA_SCAN_DENY_TERMS adds terms this deployment treats as sensitive (a
customer number, a case id); FORGE_DATA_SCAN_ALLOW_TERMS suppresses known
false positives.
Terms, never patterns. Pasting a regex into a settings box is how a config
change becomes a catastrophic backtrack that hangs a worker — Python’s re has
no timeout. The platform escapes and compiles them. Presidio’s deny lists work
the same way, for the same reason.
Volumes (not train/val)
Material a job reads but does not train on — internal documents, reference PDFs, anything a script should see — lives in a Volume: a directory you create in the console and drop files into. It has no versions; its current contents are its contents.$VOLUMES_DIR/<name>, read-only.
Nobody can download its files unless the owner turns that on, and there is no
preview at any setting. The console’s Volumes page is the reference.
Relationship to HuggingFace datasets
Writing an HF dataset id directly in the config (e.g.nvidia/OpenMathInstruct-2) also works: the platform runs an HF preflight at submission (gated datasets verify your authorization). Platform datasets suit internal data and preprocessed derived data — no need to push to HF, and permissions stay on the internal network.