Data Forge & Quality Moat (v0.47.0)

soup data forge — synthetic data pipeline

Chunk → judge → active-prune → JSONL with provenance.

bash
# Smoke test of the plumbing only: no model runs, every answer is a canned placeholder line.
soup data forge --docs ./docs --output ./synth.jsonl --task sft --target-rows 100

# Real synthesis needs a live judge backend.
soup data forge --docs ./docs --output ./synth.jsonl --task sft --target-rows 5000 \
  --judge-provider ollama --judge-model llama3.1 --provenance ./provenance.json

Without --judge-provider nothing is generated. The default judge is a deterministic offline stub that writes Synthesised answer (offline): ... as every assistant turn and exits 0. --teacher is only a label recorded in the provenance manifest (as judge_id); it never loads or calls a model, so a stub run still names whatever you passed. --judge-provider takes ollama (localhost only), anthropic (key from ANTHROPIC_API_KEY) or vllm. --hub modelscope|modelers pre-fetches --teacher only when it is an owner/name repo id.

--task picks the shape of what comes out: sft, preference or tool. --provenance writes a separate manifest, a single JSON document (not JSONL) of {version, row_count, records} where each record is {row_id, source_doc, judge_id, chunk_id, filter_score}, so a generated row can be traced back to the document it came from. The rest tune the pipeline: --uncertainty-threshold for the active-prune step, --max-chunk-chars for chunking, --judge-model / --judge-base-url for the judge, and --hub hf|modelscope|modelers for where the teacher is pulled from.

Each row carries provenance (source doc, chunk id, judge id, filter score).

soup data score — composite quality scorecard

PII + toxicity + langdetect + educational value, plus a Decontaminated cell that is always 0.

bash
soup data score --input ./train.jsonl

The scorecard reports PII-flagged and toxic-flagged counts, the language mix and mean educational value. --benchmarks (mmlu, gsm8k, humaneval, truthfulqa, arc, hellaswag) is checked against that list and nothing else: no benchmark text is bundled or supplied to score, so nothing is compared and Decontaminated stays 0. Use soup data decontaminate --benchmark-file for real overlap removal. Like the individual filters, score reads only text, content and messages[].content; an Alpaca row with instruction and output scores as empty.

Each filter is also addressable individually:

  • soup data decontaminate --input ./train.jsonl --benchmark-file ./benchmarks/eval_sets.jsonl — drop rows whose n-grams overlap a benchmark file you supply (rows with text, prompt or content). Soup bundles no benchmark corpora: --benchmarks gsm8k alone only records a label and removes nothing, and with neither option the command exits 1. The kept rows go to clean.jsonl by default.
  • soup data toxicity — keyword baseline today; a Llama-Guard backend is named in the source but is still unshipped as of v0.75.2
  • soup data langdetect — 2-letter language code per row
  • soup data pii — flag email / phone / SSN / credit-card patterns
  • soup data educational — educational-value score per row [0, 1]

Soup is free and Apache-2.0. If it saved you a training run, starring the repo costs nothing and helps most. You can also fund the GPU time behind the work a 4 GB laptop cannot reach.