Run Synthesis on Your Data
Upload owned CSV, Parquet, JSON, JSONL, or relational JSON data, authorize an exact quote, and generate new rows with RadMah Synthesis. The delivered artifacts are accompanied by quality, privacy, provenance, and integrity evidence.
✦What you'll build
You will upload a source dataset, choose one of the three operating modes of the same learned Synthesis engine, review the maximum charge, run the job, download its primary CSV, inspect its quality and privacy reports, and verify the evidence bundle offline.
Before you start
| Requirement | Details |
|---|---|
| Source dataset | CSV, Parquet, JSON, JSONL, or relational JSON with at least 1,000 source rows in every table that the learned model must fit. Upload size is governed by your current plan and is shown by the upload flow. |
| Credits | Enough available credit or an enabled pay-as-you-go policy for the quote. The server refuses execution above your authorized maximum. |
| API key | Required only for SDK, CLI, or REST use. Create one under Settings → API Keys. |
One engine, three operating modes
Quality, Automatic, and Fast are control profiles of one learned Synthesis engine. They never select a hidden statistical fallback or route by industry, dataset name, column name, or category value.
| Mode | Intent | Control authority |
|---|---|---|
| Quality | Highest supported learned quality | You may set the epoch ceiling, seed, batch size, and learning rate. Held-out convergence may stop training earlier. |
| Automatic | Governed defaults | The server owns training controls and reports the exact epoch and charge ceilings in the quote. |
| Fast | Lower-latency iteration | The same learned engine runs with a bounded server-owned training ceiling. Quality and privacy are still measured. |
Upload and inspect the source dataset
In the customer application, open Datasets, upload the source, and check the detected row and column counts. Then use Run Synthesis on the dataset page, or open /synthesizeand select it there.
import os
from radmah_sdk import RadMahClient
client = RadMahClient(
api_key=os.environ["RADMAH_API_KEY"],
base_url=os.environ.get("RADMAH_BASE_URL", "https://api.radmah.ai"),
)
dataset = client.upload_dataset(
"customers_2026.csv",
description="Owned training dataset for Synthesis",
)
print(dataset.id, dataset.rows, dataset.columns_json)Configure the run
The Synthesis setup page exposes only controls that the API and worker consume. Choose Generate synthetic data for a customer artifact or Train a reusable model to preserve a versioned model for later runs. Both operations use the same source dataset, governed compute, exact quote, and maximum-charge authorization. Generation adds mode, output rows, the mandatory quality/privacy evidence contract, an explicit release policy, optional numeric output ranges, and an owned saved model. The reproducibility seed is explicit in every mode. Only Quality exposes the training ceiling, batch size, and learning rate; Automatic and Fast keep those training controls server-owned.
Dataset
Owned CSV, Parquet, JSON, JSONL, or relational JSON with 1,000+ source rows in every fitted table
Rows
1 to 10,000,000 primary-table rows per run; the quote includes the exact admitted allocation across every related table
Evidence
Mandatory measured quality, privacy, provenance, integrity, and release evidence; there is no reduced evidence tier
Compute
Automatic, eligible CPU, or eligible GPU capacity
Release policy
Minimum aggregate, per-column, and relationship source-normalized fidelity plus maximum membership advantage / excess linkage indicators; untouched privacy and raw-source comparisons remain in evidence
Output constraints
Optional numeric ranges bound to measured source support; fidelity uses the same bounded source reference while retaining the untouched comparison
Saved model
Optional verified checkpoint trained from this exact dataset
Seed
Exact reproducibility input in Quality, Automatic, and Fast modes
Training ceiling
Quoted maximum; held-out convergence may stop earlier
ℹRelational JSON keeps tables separate
Upload one JSON object whose keys are table names and whose values are row arrays. The setup page shows every table and binds numeric constraints to an exact table and column. Synthesis emits one primary CSV plus supporting CSVs for related entities, then validates generated foreign keys against generated parent keys before release.
train_quote = client.estimate_cost(
kind="train",
dataset_id=str(dataset.id),
mode="quality",
compute="auto",
epochs=2_400,
batch_size=512,
learning_rate=0.001,
)
training_job = client.submit_job_with_budget(
kind="train",
dataset_id=str(dataset.id),
seed=42,
mode="quality",
compute="auto",
options={
"epochs": 2_400,
"batch_size": 512,
"learning_rate": 0.001,
},
max_credits=int(train_quote["credits_required"]),
).wait(timeout=1_800)
model_sha256 = (training_job.result_summary or {}).get(
"checkpoint_artifact_sha256"
)
if training_job.status != "succeeded" or not model_sha256:
raise RuntimeError("Reusable Synthesis model was not produced")Review and authorize the quote
The setup page requests a server quote before enabling submission. It shows training and generation credits, the compute assignment, the training and runtime ceilings, available credits, and any pay-as-you-go ceiling. Submission binds that quote as the maximum authorized charge.
from radmah_sdk import (
SynthesisNumericConstraint,
SynthesisReleasePolicy,
)
release_policy = SynthesisReleasePolicy(
minimum_overall_fidelity=0.75,
minimum_column_fidelity=0.75,
minimum_bivariate_fidelity=0.60,
maximum_membership_advantage=0.20,
maximum_linkage_risk=0.05,
require_zero_exact_copies=True,
)
quote = client.estimate_cost(
kind="synthesize",
dataset_id=str(dataset.id),
rows=10_000,
mode="quality",
compute="auto",
epochs=2_400,
)
job = client.submit_job_with_budget(
kind="synthesize",
dataset_id=str(dataset.id),
rows=10_000,
seed=42,
mode="quality",
compute="auto",
options={
"epochs": 2_400,
"batch_size": 512,
"learning_rate": 0.001,
},
numeric_constraints=[
SynthesisNumericConstraint(
column="customer_age",
minimum=18.0,
maximum=90.0,
),
],
release_policy=release_policy,
# Optional: a successful owned training-job id from the exact dataset.
# checkpoint_source_job_id=str(training_job.id),
max_credits=int(quote["credits_required"]),
)
print(job.id, job.status, job.mode)⚠A quote is an authorization boundary
Do not submit a different mode, dataset, row count, compute class, or training ceiling under an earlier quote. The server recomputes the request and fails closed if the accepted authority no longer matches.
Monitor, cancel, or replay
The job page shows the public mode, progress, timestamps, typed failure details, and artifacts. Running jobs can be cancelled. Terminal jobs can be replayed with the same seed or rerun as a changed-seed variation.
# Quote, submit, wait, and download the primary customer artifact
rady synthesize \
--dataset "$DATASET_ID" \
--rows 10000 \
--mode quality \
--epochs 2400 \
--batch-size 512 \
--learning-rate 0.001 \
--seed 42 \
--compute auto \
--minimum-overall-fidelity 75 \
--minimum-relationship-fidelity 60 \
--maximum-membership-advantage 20 \
--maximum-linkage-indicator 5 \
--output synthesis.csv
# Operational lifecycle
rady jobs get "$JOB_ID"
rady jobs cancel "$JOB_ID"
rady jobs rerun "$JOB_ID"Download data and inspect evidence
A successful Synthesis run has exactly one primary customer CSV. Relational runs also expose one supporting CSV per related entity. The job and evidence pages expose the same artifact authority, plus a native quality report, privacy explanation, provenance, and the complete evidence download. Parquet is download-only; readable CSV artifacts are previewed.
import json
from pathlib import Path
from radmah_sdk.verify import verify_evidence_bundle
artifacts = client.list_artifacts(job.id)
primary = [a for a in artifacts if a.artifact_type == "primary"]
if len(primary) != 1:
raise RuntimeError(f"expected one primary artifact, received {len(primary)}")
csv_bytes = client.download_artifact_bytes(job.id, primary[0].id)
Path("synthesis.csv").write_bytes(csv_bytes)
quality = client.get_utility_report(job.id)
privacy = client.get_privacy_report(job.id)
bundle_bytes = client.download_evidence_bundle(job.id)
Path("evidence_bundle.json").write_bytes(bundle_bytes)
verification = verify_evidence_bundle(json.loads(bundle_bytes))
if not verification.ok:
raise RuntimeError(verification.reason)
print(quality)
print(privacy)
print(verification.kind.value, verification.integrity)How to read the reports
| Evidence | What it tells you |
|---|---|
| Distribution similarity | How closely delivered synthetic columns match source marginals. |
| Relationship similarity | How well measured cross-column structure is preserved. |
| Downstream utility | Whether models trained on synthetic data transfer to held-out real data. |
| Privacy indicators | Exact-row overlap, distance, distinguishability, and empirical disclosure evidence. |
| Run authority | Dataset, mode, seed, workload, compute, pricing, code, artifact, and evidence hashes. |
ℹMeasured evidence is not a blanket guarantee
Interpret fidelity and privacy together and against your use case. Empirical privacy indicators are not described as formal differential privacy, and a sealed bundle proves integrity—not fitness for an untested downstream decision.
Optional: plan through ADS
The Agentic Data Scientist can plan the same Synthesis workflow when a larger analytical goal needs multiple steps. ADS must still identify the owned dataset, use the same public mode and sole learned engine, show the exact plan digest and maximum credit quote, and wait for explicit approval. It is an orchestrator—not an alternate synthesis engine.