How many epochs? Setting epochs from your data and your model

· 6 min read · kvrun team

Epochs is the one training setting kvrun asks you to choose, and the default is three. Three is a reasonable guess and a poor answer, because the right number depends on two things the field cannot see: how many examples you uploaded, and which base model you picked. The useful way to think about it is that you are not really choosing epochs — you are choosing how many optimiser steps the adapter gets, and epochs is just the dial that reaches them.

Epochs are a proxy for the thing that matters

An epoch is one complete pass over your dataset. But a model does not learn from passes, it learns from weight updates, and the number of updates depends on how your examples are batched:

steps = (examples x epochs) / effective batch size

# On kvrun: batch size 1, gradient accumulation 8
effective batch size = 8

That division is where most fine-tunes go wrong. A 200-example dataset at the default three epochs gives 600 examples seen and 75 optimiser steps — nowhere near enough for a LoRA adapter to converge on anything. The same three epochs on 20,000 examples gives 7,500 steps, which is comfortably into overfitting territory. Identical setting, opposite mistakes.

As a rule of thumb, a LoRA or QLoRA adapter wants roughly 200 to 1,000 optimiser steps. Below about 100 it has barely moved off the base model; far above 1,000 on a small dataset it is memorising rather than generalising.

Start from your dataset size

Work backwards from the step count. These are starting points, not laws — the loss curve decides in the end.

ExamplesStart withSteps you getWhat to expect
Under 2008–10 epochs200–250Format and style only. Do not expect new knowledge; consider gathering more data first.
200–1,0004–6 epochs100–750Reliable format, tone and task adherence. The sweet spot for most adapters.
1,000–5,0003 epochs375–1,875The default earns its keep here. Watch the held-out loss on the third epoch.
5,000–20,0002 epochs1,250–5,000One pass is often nearly as good as two. Compare before paying for the second.
Over 20,0001 epoch2,500+A single pass is usually enough. More epochs mostly buy memorisation.

Note the inversion people find counterintuitive: small datasets need more epochs, not fewer. The instinct is to train briefly on little data to avoid overfitting, but at 75 steps there is no fit to over — the adapter has not learned the task yet. Raise the epochs and let the held-out loss tell you when to stop.

kvrun truncates training examples at 1,024 tokens. If your examples are long documents, each one contributes less signal than its file size suggests, so the example count — not the megabytes — is what should drive this decision.

Then adjust for the model you picked

A bigger base model arrives knowing more, so it needs fewer passes to pick up your task, and it overfits faster when given too many. Adjust the figure from the table above by roughly one epoch in each direction:

Base modelAdjustmentWhy
0.8B–4BAdd 1–2 epochsLess capacity and weaker instruction following, so the task takes longer to land.
7B–14BUse the table as-isThe range the defaults were set for.
27B and aboveSubtract 1 epochStrong priors. It adapts in fewer steps and memorises small datasets quickly.

Method matters less than people expect. QLoRA trains against a 4-bit base, which adds a little gradient noise and makes it marginally more tolerant of an extra epoch than LoRA on 16-bit weights — but not by more than one. If you are still choosing between the two, see LoRA vs QLoRA on private data.

And for what you are teaching it

  • Output format — a JSON shape, a fixed template, a classification label. Fast to learn: stay at the low end, 1–3 epochs, even on small data.
  • Tone and style — house voice, register, how to refuse. The middle of the range, and the most forgiving of the three.
  • Domain vocabulary and knowledge — internal product names, codes, procedures. The high end, and the case where more data beats more epochs by a wide margin. If 10 epochs on 300 examples is not working, the answer is 3,000 examples, not 20 epochs.

Read the loss curve rather than guessing twice

Every kvrun run holds back 10% of your dataset (up to 64 examples) before training and never trains on it, then reports the loss and perplexity on that held-out slice when the job finishes. That number, not the training loss, is what tells you whether the epoch count was right:

Training lossHeld-out lossVerdict
FallingFallingUnder-trained. Add epochs — there is still signal left.
FallingFlatAbout right. You are at the useful limit for this dataset.
FallingRisingOverfitting. Cut the epochs, roughly back to where the held-out loss bottomed out.
FlatFlatNot an epoch problem. Check the data formatting and whether the examples really contain the pattern.

The last row catches more real failures than overfitting does. If the training loss will not move, no number of epochs will help: the usual cause is a dataset whose fields are not being read the way you intended, so the model is learning something other than the task you meant to teach it.

What epochs cost

Training time and cost rise roughly linearly with epochs — the estimate on the kvrun training page moves as you change the number, because the GPU is rented by the minute for the duration of the run. That has a practical consequence: it is cheaper to run two epochs, read the held-out loss and re-run longer than to run ten speculatively. Adapters are small and quick to retrain, so treat the first run as a measurement.

Epochs are also a privacy dial

More epochs on a small dataset increase the chance the adapter memorises individual examples verbatim, which matters if the training set contained personal data. An adapter that can be prompted into reproducing a customer record is a disclosure risk, and the risk grows with every extra pass over the same few hundred examples.

So the epoch count is a data protection decision as well as a quality one. Keep it as low as the held-out loss allows, minimise the data before training rather than after, and test the finished adapter by prompting it with the openings of training examples to check it does not complete them from memory. Fine-tuning open models on private data covers the surrounding controls, and GDPR Article 17 and LLMs covers what erasure means once data has reached the weights.

A worked example

  1. Count the examples, not the bytes. 850 support tickets, each labelled with a department.
  2. Read the table. 200–1,000 examples, so 4–6 epochs. Start at 5, which is 530 optimiser steps.
  3. Adjust for the model. Fine-tuning qwen3.5-27b, so subtract one: 4 epochs, 425 steps.
  4. Adjust for the task. This is classification into a fixed label set — an output-format task, the fastest kind. Come down to 3.
  5. Run it and read the held-out loss. Still falling at the end of epoch 3 means there was more to learn: re-run at 5. Rising means cut to 2.
  6. Test before deploying. Check accuracy on the held-out slice, then prompt the adapter with training openings to confirm it is not reciting them.

Questions

What is a safe default if I only get one run?
Three epochs for 1,000 to 5,000 examples, five for a few hundred, one for tens of thousands. Then read the held-out loss, because one run is rarely all you get: retraining an adapter is cheap.
Can I set a fraction of an epoch?
Not on kvrun — epochs are whole numbers from 1 to 10. On a very large dataset one epoch is the floor, and you would reduce the dataset rather than the epochs.
Does a higher LoRA rank change the epoch count?
A larger rank has more capacity to fit, so it reaches the same training loss in fewer passes and overfits sooner. kvrun trains at rank 16, which the figures here assume.
My held-out loss went up but the model seems better. Which do I trust?
Your own evaluation on real examples. Held-out loss measures next-token prediction, which is a proxy for quality and not the same thing — especially on classification and format tasks, where the score you care about is accuracy.