The Linter For
Fine-Tuning Data

Parallelogram validates your dataset before you spend GPU hours on it. If it exits 0, your training run won't fail because of data.

Read Docs

Works with

  • Claude Code
  • Codex
  • Cursor
  • Windsurf
  • Cline
  • GitHub Copilot
  • Gemini CLI
  • Zed
  • JetBrains
  • Warp
  • TRAE
  • Hugging Face
  • GitHub Actions

Catch It Before The GPU Does

Find the bad examples. Fix what you can. Check the clean file.
Here’s what that looks like in a real workflow.

Three examples. Two issues. One clean file.

Parallelogram finds a duplicate record and a private email in train.jsonl. The fix writes two records to clean.jsonl: the duplicate is removed and the email becomes [REDACTED_EMAIL]. The original file stays untouched. A second check passes with no errors or warnings.

❯ parallelogram check train.jsonl
  i (global) [context-window] Context-window counts are approximate
      → no tokenizer specified — pass --tokenizer <model> (e.g. gpt-4o, 
Qwen/Qwen2.5-7B) for an exact count
  ✗ train.jsonl:2 [duplicates] Duplicate of line 1
      → 2 copies total at lines: [1, 2]
  ! train.jsonl:3 [pii] Message 1 contains an email address: 
m***@***.com
      → The model can learn and repeat it; --fix replaces it with a 
placeholder

╭───────────── parallelogram ──────────────╮
│ 3 records  2 clean  1 errors  1 warnings │
╰──────────────────────────────────────────╯
❯ parallelogram check train.jsonl --fix --output clean.jsonl

  ✓ duplicates · 1 fix
  ✓ pii · 1 fix

  ✗ dropped:
      train.jsonl:2 → duplicates (dropped as fix)

╭─────────────────── parallelogram --fix ───────────────────╮
│ 3 records  1 unchanged  1 fixed  1 dropped  0 unparseable │
╰───────────────────────────────────────────────────────────╯
  → Wrote 2 records to clean.jsonl
❯ parallelogram check clean.jsonl
  i (global) [context-window] Context-window counts are approximate
      → no tokenizer specified — pass --tokenizer <model> (e.g. gpt-4o, 
Qwen/Qwen2.5-7B) for an exact count

╭───────────── parallelogram ──────────────╮
│ 2 records  2 clean  0 errors  0 warnings │
╰──────────────────────────────────────────╯

THE CASE FOR CHECKING FIRST.

Your advantage starts before training.

A fine-tuned model learns your data—including its mistakes.
Catch checkable defects before you spend GPU hours.

Same model. Different data. Different result.

Exact-match accuracy · higher is better · controlled small-model test

MEASURED, NOT PROJECTED
100%
Clean dataBaseline
77.6%
Empty answersDetectable by validation
68.3%
Wrong labelsNeeds semantic review
30% injection setting; systematic label errors affected 31.9% of rows. 383K parameters · 5 seeds · greedy decoding.
01 · VALIDATEStop broken records.

Flag empty turns, malformed examples and invalid roles before training.

02 · PROTECTKeep eval data separate.

Catch train/eval overlap and redact secrets before they reach model weights.

03 · VERIFYRe-check what you fix.

In a separate test: 18 of 23 defect types flagged at 98–100% recall.

Test setup & limits

Accuracy: locally built 383K-parameter GPT-style model, 2,000 fine-tuning examples, 600 held-out extraction examples, five seeds. At 30% injection, empty answers reduced mean accuracy by 22.4 percentage points (95% paired t-interval: 18.8–26.0); systematic errors by 31.7 (30.3–33.1). At 10% the reductions were 4.6 (3.3–5.9) and 12.2 (10.6–13.8). Systematic errors actually affected 12.1% and 31.9% of rows.

Detection: separate test of Parallelogram 1.6.1, 100 injected rows per defect type, all rules, approximate token counts with a 2,048-token limit. The 98–100% range includes warnings. The base was filtered by all detectors, so false positives on natural data are not estimated. Both tests were conducted by Parallelogram’s author; these results do not measure accuracy recovered by the linter, production-model quality, or performance against frontier APIs.

Download experiment results ↗

One workload. Four ways to run it.

Estimated monthly spend · USD · lower is cheaper

MONTHLY WORKLOAD1 million tasks

Change the volume.
Watch the economics shift.

Published API ratesYour deployment estimate12 NOV 2026 SNAPSHOT
$25K
OpenAIGPT-6 AstraAPI · standard rate
$20K
AnthropicClaude Fable 5.2API · standard rate
$5K
GoogleGemini 4 CarbonAPI · standard rate
$6K
Self-hostedYour fine-tuneLlama-based · scenario
1,500 input + 200 billed output tokens per task. Cost comparison, not a quality ranking.
Pricing & assumptions

Snapshot: 12 November 2026. API cost = tasks × (1,500 × input rate + 200 × output rate) ÷ 1,000,000. The 200 output tokens include any billed reasoning tokens; more reasoning increases cost. Tokenization varies by provider. Standard uncached text rates; no batch discounts, tools, taxes, retries or application-operation costs. Selected models are examples, not a complete market survey.

USD per million input/output tokens: GPT-6 Astra 10/50; Claude Fable 5.2 8/40; Gemini 4 Carbon 2/10. Efficient alternatives: GPT-6 Luna 0.10/0.50; Claude Haiku 5.5 0.10/0.50; Gemini 3.1 Flash-Lite 0.25/1.50. Gemini 4 Carbon’s promotional rates end 30 November 2026; this is a dated snapshot.

The self-hosted bar is an editable budget, not a measured Llama deployment or a vendor quote. The default assumes $2,800 hosting, $2,500 maintenance and $700 amortized training per month. It stays fixed as volume changes: increase it if extra GPUs or staffing are needed. Matching the APIs’ task quality and meeting throughput targets require your own evaluation. No Parallelogram savings or model-quality uplift is assumed.

OpenAI pricing ↗Anthropic pricing ↗Google pricing ↗

Buy capability. Build specialization.

Different approaches to the same job—not a universal winner.

WORKFLOW COMPARISON
What matters
OpenAIAnthropicGoogle
Frontier APIsGPT · Claude · Gemini
MetaYour fine-tuneFor example, a self-hosted Llama adapter
Where to startBroad reasoning & unfamiliar tasksStable, repeated tasks with examples
BehaviorPrompts, tools & retrievalTraining examples + your adapter
Model weightsManaged by the providerYou hold the adapter and licensed base
Serving locationAvailable provider regionsYou choose the infrastructure
OperationsProvider runs the modelYour team serves, monitors & updates
Proof of usefulnessEvaluate on your actual workloadEvaluate on the same held-out tasks

They can work together. Route familiar work to your specialized model and escalate the harder cases to a frontier API.

“In-house” here means a self-hosted, fine-tuned open-weight model—not training a foundation model from scratch. Capability depends on the base, data and task.

Whichever model you choose, start with better data.Check structure, duplicates, leakage and secrets before you train.

See how Parallelogram fits

Eleven Checks Your Trainer Won't Run

Each one crashes the run, quietly trains the wrong thing, or leaks something it shouldn't.

All rules

Check. Fix. Gate.

Every issue gets a line and a rule. Mechanical problems are repaired, the rest are dropped with a reason, and the re-check decides.

  1. 01 · checkparallelogram check data.jsonl

    Every issue with its line number and rule. Exits 0, 1 or 2.

  2. 02 · fixparallelogram check data.jsonl --fix --output clean.jsonl

    Mechanical repairs, then a re-check. Anything still broken is dropped, with the reason.

  3. 03 · gateuses: Thatayotlhe04/Parallelogram@v1

    The GitHub Action fails the pull request when dataset quality regresses.

Changelog

Shipped in the open, versioned on PyPI.

Full changelog
  1. 1.6.0

    Tool-calling datasets, parallelogram integrate for eight agents, and a pre-commit hook

  2. 1.5.1

    Every field scanned for keys and personal data, and a CI gate that can't be crashed open

  3. 1.5.0

    For coding agents: an MCP server, a Python API and --json --limit

  4. 1.1.1

    Fixes from an independent review, including secrets quoted in diagnostics

  5. 1.1.0

    Alpaca and DPO formats, secrets and PII checks, train/eval leakage with --eval

Frequently Asked Questions

Questions? We've got answers.

or read the docs
What does "exits 0" actually guarantee?

With all rules on: every record parses, has a valid role order ending on the assistant, has no empty turns or exact duplicates, and fits your token budget (counted exactly with --tokenizer, estimated otherwise). It checks that your data will train, not that it's good data.

Does my data leave my machine?

No. Nothing is uploaded and there is no telemetry. The only network request is opt-in: --tokenizer may download a tokenizer vocabulary once, then caches it.

Which formats are supported?

OpenAI/Qwen chat, ShareGPT, prompt/completion, Alpaca and preference (DPO) pairs, detected per line and mixable in one file. --fix writes each record back in the shape it came in.

Will it catch a leaked API key?

Yes. The secrets check finds keys and tokens for OpenAI, Anthropic, AWS, GitHub, Hugging Face, Slack, Google and Stripe, plus private key blocks. It never prints them in full, and --fix redacts them.

Are token counts exact?

With pip install 'parallelogram[tokenizer]' and --tokenizer, yes (tiktoken or Hugging Face). Without, counts are estimated and overflows are warnings, never errors.

How do I use it in CI?

Add uses: Thatayotlhe04/Parallelogram@v1 to a workflow. It writes a report to the job summary and fails on errors, or on regressions against a --baseline.

Can my coding agent run it?

Yes. parallelogram mcp gives Claude Code, Codex and Cursor three tools: check, fix and list rules. Agents using the shell can run check --json --limit 50, which keeps every count exact but lists only the most important issues. Setup is in the agent guide.

Is it free?

Yes. Apache-2.0, on PyPI and GitHub.

Run It Before You Train

Star on GitHub