FAQ

LLM training

Continued pretraining: teaching a model a domain

When instruction tuning cannot help because the model lacks the knowledge — how much domain text you need, how to avoid forgetting, and the embedding learning rate people miss.

If your model does not know your domain's vocabulary, entities or conventions, no amount of instruction data will supply them. Continued pretraining is the stage that does, and it needs a different kind of dataset entirely.

When you actually need it

Continued pretraining is the right tool in a narrower set of cases than people assume. The test is whether the base model is confidently wrong about facts in your domain, as opposed to knowing the answer and presenting it badly.

Cases where it genuinely helps: a low-resource language the base model barely saw; a technical vocabulary with its own abbreviations and conventions, like clinical notes or a specific legal jurisdiction; an internal corpus of entities and product names that do not exist on the public web; a modality of text the model is weak at, such as heavily tabular or structured documents.

Cases where it does not: the model is too verbose, will not produce valid JSON, ignores your format, refuses too much. All behaviour, all cheaper to fix with supervised fine-tuning.

Each stage consumes a different shape of data, usually less of it than the stage before, so the stage your goal belongs to decides what you collect and how much of it.

The data shape, and the mix

Same shape as pretraining — raw documents, one text field, loss on every token. What changes is curation: you are deliberately upsampling a domain rather than sampling the web broadly.

A line chart of average F1 score (45 to 65) against the percentage of the pre-training corpus used (1 to 20%), for DACP, ETS-DACP, ETA-DACP-entropy, ETA-DACP-perplexity and a flat Pythia 1B baseline near 53; ETS-DACP rises to about 60 at 5 to 10% and falls to 56 at 20%.
Average F1 on financial tasks as a 1B Pythia model continues pretraining on growing shares of a financial corpus. Picking the documents most similar to the target tasks (ETS-DACP) peaks at 5 to 10% of the corpus, near 60 F1, above plain continued pretraining (DACP), which reaches only about 55 F1 even on the whole corpus; a perplexity-based pick falls below the base model. Selection matters as much as volume. Image: Figure 2 of the paper · CC BY 4.0 · from Xie et al. 2023, “Efficient Continual Pre-training for Building Domain Specific Large Language Models”, arXiv:2311.08545

Crucially you do not train on domain text alone. Doing so degrades general capability, and the standard mitigation is to mix a proportion of general-purpose data back in. OLMo 2 illustrates the structure: it anneals its 7B model “three separate times for 50B tokens each” on a curated high-quality mix, with the learning rate decayed linearly to zero over each run.

Order of magnitude for the domain stage: OLMo 2's mid-training runs used 50B to 300B tokens, which it frames as 5–10% of training FLOPs — a small fraction of a stage-one budget, cheap by comparison, and the reason this stage is practical for organisations that could never pretrain.

Three small line charts, for biomedicine, finance and law from left to right, each joining three points labelled General LLM, DAPT and Adapt LLM. Biomedicine reads 44.2, 41.7, 47.3; finance 58.6, 57.6, 63.4; law 34.2, 35.0, 38.5. Dashed reference lines are labelled MedAlpaca, BloombergGPT and LexGPT.
Average domain-task scores before and after continued pretraining, for biomedicine, finance and law. Plain continued pretraining on raw domain text (DAPT) lowers the biomedicine and finance scores; the same corpora rewritten as reading-comprehension exercises raise all three. The paper's reading is that raw text adds domain knowledge but 'drastically hurts its prompting ability', so the form of your domain data matters as much as its subject. Image (cropped): microsoft/LMOps · MIT repository · from “Adapting Large Language Models via Reading Comprehension”, arXiv:2309.09530

What annealing buys, quantified

Llama 3 publishes the clearest numbers on this. Annealing on upsampled high-quality code and maths data improved a pretrained 8B model by 24.0% on the GSM8K validation set and 6.4% on MATH.

The same paper describes using annealing as a data-evaluation protocol, which is a useful trick in its own right: take a half-trained 8B model, anneal the learning rate linearly to zero over 40B tokens with 30% weight on the candidate dataset, and see what moves. That is a far cheaper way to assess whether a corpus is worth including than a full training run.

OLMo 2’s totals show how the stages compose: its 7B model is trained on 4.05 trillion tokens of which 3.90 trillion is stage-one pretraining, leaving roughly 150B for mid-training across the three annealing runs.

The embedding learning rate

Here is the detail that trips up people doing this with an adapter rather than a full fine-tune, and it is worth stating plainly because it fails quietly.

Continued pretraining on new domain text often means new vocabulary, so the embedding and output layers need to move — which means including them in the target modules rather than only the attention and MLP projections. Unsloth's documentation for this case adds lm_head and embed_tokens.

But embeddings want a gentler rate than the rest of the network. Unsloth's continued pretraining guidance uses a learning rate of 5e-5 with a separate embedding_learning_rate of 5e-6 — ten times smaller, the top of its advised two-to-ten range — and the separate rate only takes effect through UnslothTrainer with UnslothTrainingArguments; TRL's SFTConfig has no such field. Train the embeddings at the main rate and you can destabilise representations the model already had, producing a model that is worse at everything including your domain.

the continued-pretraining configuration that differs
model = FastLanguageModel.get_peft_model(
    model,
    r = 32,
    target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
                      "gate_proj", "up_proj", "down_proj",
                      "lm_head", "embed_tokens"],   # <- the embeddings, for new vocabulary
    lora_alpha = 32,
    use_gradient_checkpointing = "unsloth",
)

from unsloth import UnslothTrainer, UnslothTrainingArguments

args = UnslothTrainingArguments(      # not SFTConfig: it has no embedding rate
    learning_rate = 5e-5,             # lower than the 2e-4 typical of instruction SFT
    embedding_learning_rate = 5e-6,   # 2-10x smaller again
    ...
)
trainer = UnslothTrainer(model = model, args = args, train_dataset = dataset, ...)

# the dataset is raw text, not instructions:
#   {"text": "<a whole document>"}

Finding domain text at the right scale

The practical obstacle is rarely method and usually supply. Ten billion tokens of a specific domain is a lot of text — far more than most organisations have internally, and the public sources are uneven by field.

A table with columns Math Corpus, Size and five English benchmarks (GSM8K, MATH, OCW, SAT, MMLU-STEM). No Math Training scores 2.9%, 3.0%, 2.9%, 15.6% and 19.5%; MathPile (8.9B) 2.7%, 3.3%, 2.2%, 12.5%, 15.7%; OpenWebMath (13.6B) 11.5%, 8.9%, 3.7%, 31.3%, 29.6%; Proof-Pile-2 (51.9B) 14.3%, 11.2%, 3.7%, 43.8%, 29.2%; DeepSeekMath Corpus (120.2B), in bold, 23.8%, 13.6%, 4.8%, 56.3%, 33.1%.
The same 1.3B general model trained for 150B tokens on each of four maths corpora. MathPile's 8.9B tokens leave it no better than the no-maths baseline, while the 120.2B-token DeepSeekMath Corpus scores best on every English test. Which domain corpus you continue on matters as much as whether you continue at all. Image (cropped): deepseek-ai/DeepSeek-Math · MIT (repository code and documentation licence) · from “DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models”, arXiv:2402.03300

Some domains are well served: biomedical literature, legal opinions and filings, patents, code, and the major scientific archives all have substantial open corpora. Others barely exist in public form, and for those the realistic options are your own archives, licensed commercial sources, or synthetic expansion from a smaller real seed.

This is worth scoping before committing to the approach. If you can only assemble a few hundred million tokens of genuine domain text, you are in a different regime — closer to a light domain nudge than to teaching a field — and the honest expectation should be set accordingly.

A circular flow diagram. A 'Math Seed' feeds '1. Train a FastText Model', then '2. Recall Math-Related Webpages From Common Crawl', drawing on a central 'Deduplicated Common Crawl, 40B HTML pages', which produces a 'Math Corpus'. From there '3. Discover Math-Related Domains' leads to '4. Annotate Math-Related URL Path From Labelers', which loops back to the seed. Seed and corpus are drawn as illustrated trees.
How DeepSeekMath gathered its maths corpus from Common Crawl: a fastText classifier trained on a seed set recalls candidate pages, maths-heavy domains are found statistically, people annotate the relevant URL paths, and the new pages join the seed for the next round. Four rounds gave 35.5M pages and 120B tokens, which is what finding domain text at scale looks like for a domain the web covers well. Image: deepseek-ai/DeepSeek-Math · MIT (repository code and documentation licence) · from “DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models”, arXiv:2402.03300

Questions people ask

How much general data should I mix back in?

There is no single published figure, and the right proportion depends on how far your domain sits from the base distribution. Llama 3's data-evaluation protocol weights a candidate dataset at 30% against the existing mix, which is a reasonable starting point for the domain share. Measure general capability as well as domain capability before and after — regression on the former is the thing you are guarding against.

Can I do continued pretraining with LoRA, or do I need a full fine-tune?

LoRA works, provided you include the embedding and output layers in the target modules for new vocabulary and use a lower embedding learning rate. A full fine-tune gives the model more freedom to move and costs proportionally more memory. For a domain nudge an adapter is usually enough; for a genuinely distant domain or a new language, full fine-tuning is the stronger option.

Should I do continued pretraining before or after instruction tuning?

Before. The conventional order is pretraining, then domain adaptation, then instruction tuning, then preference tuning — knowledge before behaviour. Running continued pretraining on an already instruction-tuned model on raw text tends to erode the instruction-following you paid for, since raw-text training has no notion of turns or roles.

Will the model forget what it knew?

It can, and that is the main risk of the stage. The mitigations are mixing general data back in, keeping the learning rate low, decaying it to zero, and keeping the run short relative to pretraining. Evaluate on general benchmarks as well as your domain so that a regression shows up as a number rather than as a surprise later.

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 →