Skip to content
AI Dev Toolkit.
Esc
  • AI Token CounterCount tokens for GPT, Claude, Gemini, DeepSeek, Qwen and more.Tool
  • LLM API Cost CalculatorEstimate per-request, daily and monthly API costs.Tool
  • AI Model ComparisonCompare prices, context windows and features across models.Tool
  • AI Model Pricing PagesSpecs, real costs and cheaper alternatives for popular models.Tool
  • Context Window CheckerSee whether your text fits each model’s context window.Tool
  • Subscription vs API CalculatorFind out whether a chat plan or the API is cheaper for you.Tool
  • GPU / VRAM CalculatorCheck how much VRAM a local model needs and which GPUs fit.Tool
  • Prompt Caching CalculatorEstimate savings from prompt caching.Tool

Utilities

JSONL validator and CSV to JSONL converter

Check a fine-tuning JSONL file line by line against the OpenAI or Gemini format, with token estimates and each provider’s limits, or turn a CSV into JSONL. It’s free, handles files of tens of megabytes, and runs in your browser, so your data never leaves your device.

or drop it here. Files up to 200 MB are read in your browser and never uploaded.
Try:

Checked in your browser. Nothing you paste or open is sent anywhere.

Open or paste a JSONL file to check it.

Steps

How to validate JSONL and convert CSV to JSONL

  1. To validate, choose or drop a .jsonl file, or paste a few lines into the box.
  2. Leave the format on “Detect automatically”, or pick OpenAI, Gemini or generic JSONL.
  3. Read the summary and the limits table, then work through the problems by line number.
  4. To convert, open “CSV to JSONL”, choose your CSV and map the columns to user, assistant and an optional system message.
  5. Download train.jsonl, or press “Validate this file” to check the result straight away.

Method

How it works

A fine-tuning file is JSON Lines: every line is one complete JSON object, and each object is one training example. Providers check the file only after you upload it, and some problems never fail at all: an example with no answer or one that is too long just wastes training. This tool runs the checks first, on your own device.

What it checks

Every line is parsed on its own. If a line isn’t valid JSON, you get the line and column and, where it can tell, the likely cause: a trailing comma, single quotes, Python’s True or None, or an object pretty-printed over several lines. Blank lines, a byte order mark and a file saved as a JSON array are flagged too. Windows line endings are fine: JSON Lines allows them.

For the OpenAI chat format each line needs a messages list with the roles system, user, assistant and tool. The validator reports a missing assistant answer, empty content, a system message after the conversation has started, two user turns in a row, a conversation that ends after the last answer, weight values other than 0 or 1, and tool calls whose arguments aren’t a JSON string. OpenAI’s DPO lines (input, preferred_output, non_preferred_output) are recognised as well. Mistral and most open-source trainers read the same shape, so this check covers their files too.

For Gemini on Google Cloud each line needs a contents list with user and model turns, text inside parts, and an optional systemInstruction that holds only text. The most common mistakes are OpenAI habits: the role assistant instead of model, a system turn inside contents, and content instead of parts.

Generic JSONL checks only that every line is valid JSON and that the lines share the same keys, which catches a renamed column or a stray record in any dataset.

Tokens and limits

With “Estimate tokens” on, each example is counted with OpenAI’s o200k_base tokenizer. For OpenAI files the count follows the formula in OpenAI’s cookbook: 3 tokens of framing per message plus the role and content, and 3 more per example. You see the total, the median and the largest examples by line. Training tokens are that total times the number of epochs, so a training cost estimate is one multiplication away. Gemini counts its tokens differently, so treat its numbers as a guide.

The limits table compares your file with each provider’s documented limits, checked on 2026-10-12. OpenAI needs at least 10 examples, suggests starting with 50, and truncates examples over 65,536 tokens from the end, which is where the answer is. Google recommends starting with 100 examples and allows 131,072 tokens per example.

CSV to JSONL

The converter reads CSV the way spreadsheet programs write it: quoted cells, doubled quotes, commas and line breaks inside cells, comma, semicolon or tab separators, and the byte order mark Excel adds. Each row becomes one example. Line breaks inside a cell are kept as \n in the JSON, spaces around a cell are trimmed, and rows with an empty prompt or answer are skipped and listed so you can fix them.

Large files and privacy

Files are read and checked in a Web Worker, a background thread in your browser, so a file of tens of megabytes doesn’t freeze the page, and a progress bar shows how far it has got. Nothing is uploaded: there is no server step, and the tool works the same offline once the page has loaded.

Examples

Worked examples

What the validator reports for common mistakes (generated by the tool itself)
ProblemLineWhat the tool says
Trailing commaOpenAI format{"messages": [{"role": "user", "content": "Hi"}, {"role": "assistant", "content": "Hello"},]}Invalid JSON at column 92: expected another value (remove the trailing comma), found “]”. Likely cause: a trailing comma before a closing bracket.
Pretty-printed objectOpenAI format{Invalid JSON at column 2: expected a property name in double quotes, found the end of the line. This looks like one JSON object spread over several lines; JSONL needs each example on a single line.
Gemini role in an OpenAI fileOpenAI format{"messages": [{"role": "user", "content": "Hi"}, {"role": "model", "content": "Hello"}]}message 2: unknown role "model"; “model” is Gemini’s name; the OpenAI format uses “assistant”.
No answer to learnOpenAI format{"messages": [{"role": "system", "content": "Be brief."}, {"role": "user", "content": "Hi"}]}No assistant message, so there is no answer to learn.
Arguments as an objectOpenAI format{"messages": [{"role": "user", "content": "Weather in Paris?"}, {"role": "assistant", "tool_calls": [{"id": "call_1", "type": "function", "function": {"name": "get_weather", "arguments": {"city": "Paris"}}}]}]}message 2, tool call 1: function.arguments must be a JSON string, not object.
OpenAI role in a Gemini fileGemini format{"contents": [{"role": "user", "parts": [{"text": "Hi"}]}, {"role": "assistant", "parts": [{"text": "Hello"}]}]}contents 2: unknown role "assistant"; Gemini calls the model’s turn “model”, not “assistant”.
Text outside partsGemini format{"contents": [{"role": "user", "content": "Hi"}, {"role": "model", "parts": [{"text": "Hello"}]}]}contents 1 needs a “parts” list. Gemini puts text inside parts: [{"text": "…"}].
Fine-tuning formats and limits, checked 2026-10-12
ProviderFormatExamplesPer exampleFile sizeStatus
OpenAImessages: system, user, assistant, toolAt least 10; start with 5065,536 tokens (GPT-4.1 family)512 MBWinding down: closed since 7 May 2026 to organisations that had never fine-tuned, and since 2 July 2026 to those with no fine-tuned model inference in the past 60 days; active customers can create jobs until 6 January 2027
Google Cloud (Gemini)systemInstruction + contents: user, model, partsStart with 100; up to 10,000,000 text (300,000 multimodal)131,072 input and output tokens1 GBAvailable on Gemini Enterprise Agent Platform for Gemini 3.5 Flash, 3.1 Flash-Lite, 2.5 Pro, 2.5 Flash and 2.5 Flash-Lite. Not in the Gemini API or AI Studio
MistralSame as OpenAI (accepts OpenAI-format files)No documented minimumNot documented512 MB per training file; validation data up to 1 MBDeprecated and “no longer actively supported”

FAQ

Frequently asked questions

What is a JSONL file?

JSONL (JSON Lines) is a text file with one complete JSON value on every line, encoded as UTF-8. For fine-tuning, each line is one training example: a short conversation that ends with the answer you want the model to learn. Blank lines are not allowed, and a pretty-printed object spread over several lines is valid JSON but broken JSONL. To turn a JSON array into JSONL, run jq -c '.[]' data.json > data.jsonl.

How do I validate a fine-tuning JSONL file?

Open the file in the validator above, or paste a few lines. Every line is parsed as JSON and checked against the OpenAI chat format or Google Cloud’s Gemini format, which is detected for you. You get errors and warnings with line numbers, an estimate of tokens per example, and a check against the provider’s documented limits.

How do I convert a CSV file to JSONL for fine-tuning?

Open the CSV to JSONL tab, choose or paste your CSV, then map one column to the user message and one to the assistant answer. Add an optional system message, either the same text for every row or a column. Pick OpenAI or Gemini output and download train.jsonl. Quoted cells, commas and line breaks inside cells are handled.

Is my training data uploaded?

No. The file is read by your own browser, and the checks and conversion run in a background Web Worker on your device. Nothing you open or paste is sent to our server or to any provider, so the tool is safe for private or customer data. Strip secrets and personal data before you upload the file to a provider, though.

How accurate are the token counts?

They are estimates. For the OpenAI format the tool uses OpenAI’s o200k_base tokenizer with the formula from OpenAI’s cookbook (3 tokens per message, plus the role and content, plus 3 per example). Gemini uses its own tokenizer, so counts for Gemini files are a guide only. Images and other files in an example aren’t counted.

Can I still fine-tune OpenAI or Gemini models?

As of 2026-10-12: OpenAI is winding fine-tuning down. Organisations that had never fine-tuned lost access on 7 May 2026, and from 2 July 2026 so did those with no fine-tuned model inference in the past 60 days. Remaining customers can create jobs until 6 January 2027. The Gemini API and AI Studio have no tunable model, but Google Cloud offers supervised tuning of Gemini 2.5 and later. Mistral marks its fine-tuning API as deprecated.

How big can a fine-tuning file be?

OpenAI accepts files up to 512 MB and at least 10 examples, with up to 65,536 tokens per example on the GPT-4.1 family. Google Cloud accepts a 1 GB JSONL file, up to 10,000,000 text examples and 131,072 tokens per example. Mistral allows 512 MB per training file.