FAQ

Formats

ShareGPT, Alpaca and ChatML: three ways to store a conversation

Which instruction-tuning format to use, how each one maps onto a chat template, and the loss-masking decision that quietly determines whether your fine-tune works.

Every fine-tuning framework accepts a handful of conversation formats and converts them into one tokenised string before training. Understanding that conversion is the difference between a fine-tune that behaves and one that rambles.

Alpaca: single turn, three fields

The Alpaca format came out of Stanford's 2023 instruction-tuning work and is the simplest of the three. One JSON object per example, with instruction, an optional input, and output.

It suits single-turn tasks exactly and multi-turn conversation not at all. If your data is 'given this document, produce this summary' or 'classify this ticket', Alpaca is a clean fit and the lack of structure is an advantage. The input field exists so that the instruction can stay constant across many examples while the content varies — useful, and frequently ignored in favour of concatenating everything into instruction.

alpaca.json
[
  {
    "instruction": "Summarise the clinical note in two sentences.",
    "input": "Patient presented with a three-day history of ...",
    "output": "A 54-year-old patient reported three days of ..."
  },
  {
    "instruction": "List the three risk factors mentioned.",
    "input": "...",
    "output": "1. Hypertension\n2. Family history\n3. Smoking"
  }
]
Four boxes of instruction, input and output: a zip-code lookup for 123 Main Street, San Francisco; filling in a job application form; Python code to convert Fahrenheit to Celsius with a null input; and a letter written from a cat's perspective with a null input.
Four machine-generated tasks from Self-Instruct, each stored as an instruction, an optional input and an output; two have no input at all ('Null'). Alpaca's three-field records follow exactly this single-turn layout, which is why an empty input field is normal in the format. Image: Figure 1 of the paper (ACL 2023) · CC BY 4.0 · from Wang et al. 2023, “Self-Instruct: Aligning Language Models with Self-Generated Instructions”, doi:10.18653/v1/2023.acl-long.754 · image rendered from the arXiv version, arXiv:2212.10560

ShareGPT: a list of turns

ShareGPT stores each example as a list of alternating turns, which is what you need the moment a conversation has more than one exchange or a system prompt. The field names are the thing people trip over: the list is conventionally called conversations, each turn has from and value, and the roles are system, human and gpt.

Those role names are historical — they come from the scraped-conversation dataset the format is named after, not from any standard. Some tools expect role and content with user and assistant instead, which is really the OpenAI messages shape wearing ShareGPT's clothes. Check which naming your framework wants; most will convert between them if you tell them which you have.

sharegpt.jsonl — one object per line (wrapped here for reading)
{"conversations": [
  {"from": "system", "value": "You are a careful clinical summarising assistant."},
  {"from": "human",  "value": "Summarise this note: Patient presented with ..."},
  {"from": "gpt",    "value": "A 54-year-old patient reported three days of ..."},
  {"from": "human",  "value": "Now list the risk factors."},
  {"from": "gpt",    "value": "1. Hypertension\n2. Family history\n3. Smoking"}
]}
A conversation annotation view. On the left, a chat is rendered as an alternating list of turns, each tagged with its role - user, assistant, user, assistant - and holding the message text. On the right, a panel headed 'Turn 1' repeats the first user and assistant messages and asks for a per-turn label, with intent options offered as checkboxes.
A conversation as an ordered list of role-tagged turns, annotated per turn. That per-turn structure is what maps onto a loss mask once the conversation is rendered into a training sequence. Image: HumanSignal/label-studio · Apache-2.0 repository

ChatML is a template, not a storage format

This is the distinction that clears up most of the confusion. Alpaca and ShareGPT describe how conversations sit in a file. ChatML describes how they are rendered into the single token sequence the model sees.

A chat template wraps each turn in special tokens that mark role boundaries. The widely used ChatML convention uses <|im_start|>role and <|im_end|>, but it is not universal: many model families have their own — Llama, Mistral and Gemma each differ — and using the wrong one is one of the most common causes of a fine-tune that echoes role markers as text or never stops talking.

You almost never want to write these tokens by hand. The tokenizer that ships with a model carries its own template, and applying it is one call. Let the tokenizer do it and the boundaries are correct by construction.

let the tokenizer render it
from transformers import AutoTokenizer

tok = AutoTokenizer.from_pretrained("<model-id>")

msgs = [
    {"role": "system",    "content": "You are a careful assistant."},
    {"role": "user",      "content": "Summarise this note: ..."},
    {"role": "assistant", "content": "A 54-year-old patient ..."},
]

# training: render the full conversation including the final answer
text = tok.apply_chat_template(msgs, tokenize=False)

# inference: stop after the assistant header so the model continues it
prompt = tok.apply_chat_template(
    msgs[:-1], tokenize=False, add_generation_prompt=True)

print(repr(text[-120:]))   # inspect the actual boundary tokens once

The decision that actually matters: loss masking

Having rendered the conversation, you must decide which tokens contribute to the loss. Train on every token and the model learns to produce user turns as well as assistant turns — it will happily continue your conversation on both sides. Train only on assistant tokens and it learns to respond.

For most instruction tuning, masking everything except assistant responses is what you want, and it is what the response-only and assistant-only loss options in the major frameworks do — Unsloth's train_on_responses_only, for example. The exception is continued pretraining, where you genuinely do want loss on all tokens because you are teaching the model a domain rather than a behaviour.

In a multi-turn ShareGPT example this means masking every human turn and computing loss on every gpt turn — not just the last one. Getting that wrong wastes most of a multi-turn dataset's signal, and it fails silently: the loss curve looks fine.

Mask everything except the assistant turn, and include the stop token. Train on every token and the model learns to produce user turns too; mask everything and there is no training signal at all, which the trainer reports as 0.0 or NaN.

Which to choose

If your data is single-turn and task-shaped, Alpaca is the least ceremony. If it has system prompts, multiple turns, or you expect it to grow into those, use a messages list — ShareGPT's from/value or the role/content variant, whichever your framework prefers. Store conversations in whichever one you pick, and let the tokenizer apply the model's own template at training time.

The one combination to avoid is baking rendered special tokens into your stored dataset. It welds your data to one model family, and the next time you fine-tune something else you will be stripping template tokens out with regular expressions.

Questions people ask

Can I convert Alpaca data to ShareGPT?

Yes, and it is lossless in that direction. Each example becomes a two-turn conversation: the instruction and input joined into a human turn, the output as the gpt turn. Going the other way loses anything beyond the first exchange, so multi-turn data cannot be flattened into Alpaca without discarding most of it.

Do I need a system prompt in my training data?

Only if you want the model to condition on one at inference. If every training example carries the same system prompt, the model partly folds it into its weights and behaves that way without it. If you want robustness to varied system prompts, vary them in training — including leaving them out of some examples.

What happens if I use the wrong chat template?

Typically the model trains without error and then behaves oddly: it may not stop generating, may echo role markers as literal text, or may ignore the system prompt. Because there is no error, this is usually diagnosed late. Rendering one example and reading it is the cheap preventative.

Is there a standard for tool and function calls?

Not a single one. Tool calls are generally stored as an extra turn with a structured payload, and each model family's template serialises them differently. If you are fine-tuning for tool use, follow the target model's documented format exactly rather than inventing a shape — this is the area where templates diverge most.

Stop hunting. Start searching.

Tens of thousands of curated datasets, searchable in plain language — with the licence and size checked before you download anything.

Search Dataset Finder →