AlgoMaster Logo

Adapting Models

Medium Priority20 min readUpdated October 18, 2026
Listen to this chapter
Unlock Audio

A base model rarely meets all your application's needs out of the box. It might use the wrong tone, occasionally ignore your required output format, lack knowledge about your company, or be too expensive to run at scale.

There are several ways to address these problems. You can improve the instructions, provide better context, or fine-tune the model on your own data. Each approach solves different problems and comes with its own trade-offs in cost, complexity, and maintenance.

In this chapter, we'll cover how to choose the right approach, how fine-tuning works, how to prepare training data, how to serve fine-tuned models at scale, and the common mistakes to avoid.

Ways to Adapt a Model

There are several ways to adapt a model to your application's needs. These approaches form a ladder, from simple prompt changes to training your own model. As you move up, the effort, cost, and complexity generally increase.

A good rule is to start with the simplest approach that could meet your requirements and introduce more complexity only when you have evidence that it's needed. Let's look at what each approach offers and when to use it.

Prompting is the simplest starting point. You write clear instructions, provide a few examples, and specify the expected output format. Changes are quick to make, and you can measure their impact against an evaluation dataset. Before trying more complex approaches, make sure you've tested and improved your prompts.

RAG retrieves relevant information and adds it to the prompt at request time. It's useful when the model lacks the knowledge needed to answer correctly, such as your product catalog, internal policies, or recent support tickets. You can keep this information up to date by updating your document index without retraining the model.

Fine-tuning updates the model's weights using examples of the behavior you want. It's useful when prompting alone isn't reliable enough, such as when the model struggles to follow a specific format, maintain a consistent tone, or perform a specialized task. Fine-tuning can also help a smaller model perform a narrow task well, reducing inference costs at scale.

Pretraining involves training a model from scratch on a large dataset. Building a competitive large model can cost millions of dollars and requires substantial compute, data, and engineering expertise. It's rarely practical for product teams. One example is BloombergGPT, a 50-billion-parameter model trained on a mixture of financial and general-purpose text for financial language tasks.

Between fine-tuning and training from scratch, there's another option called continued pretraining. Instead of starting from scratch, you continue training an existing model on large amounts of domain-specific text, such as medical literature or legal documents. This can improve the model's understanding of specialized language and concepts before fine-tuning it for specific tasks.

These approaches aren't mutually exclusive. A production system might use a fine-tuned model to follow a consistent response format, RAG to provide current information, and prompting to define the task. The ladder is a guide to choosing the right level of investment, not a sequence you must follow.

In practice, the decision that comes up more often is whether fine-tuning is worth the additional effort. Let's look at when it makes sense.

When Fine-Tuning Fits and When It Doesn't

Fine-tuning is most useful for changing how a model behaves, rather than teaching it facts. It works well when you want the model to learn consistent patterns from examples, but it's less reliable for information that needs to stay accurate and up to date.

Where Fine-Tuning Works Well

  • Style and tone. A customer support assistant that follows your brand's voice, or a writing tool that matches a company's editorial style. Prompting can establish the tone, but fine-tuning can make it more consistent across different inputs.
  • Output format. Complex JSON structures, specific report layouts, or domain-specific markup. Native structured output features handle many formatting requirements, but fine-tuning can help when the model also needs to learn how to organize and populate the content.
  • Narrow, well-defined tasks. Classifying support tickets into 40 categories, extracting fields from insurance claims, or routing requests to the right team. These tasks have clear expected outputs and can benefit from training on representative examples.
  • Replacing a large model with a smaller one. This is a common reason to fine-tune. A large model might perform your task well, but a fine-tuned 8B model could achieve comparable quality on that specific task at much lower cost and latency.
  • Shorter prompts. If your prompt contains 3,000 tokens of instructions and examples, fine-tuning may let you remove much of that content. At millions of requests per day, fewer input tokens can significantly reduce inference costs and latency.

Where Fine-Tuning Falls Short

Fine-tuning is a poor fit for teaching a model factual knowledge. Suppose you fine-tune a model on your product documentation so it can answer customer questions. Several problems can arise:

  1. Facts become outdated. When a price or policy changes, the model may continue giving the old answer. Updating that knowledge could require another training run, while RAG only needs the relevant documents updated and re-indexed.
  2. Source attribution is difficult. Fine-tuning stores learned information in the model's weights, not as retrievable documents. The model can't reliably identify which source supports a particular claim. RAG provides the source passages directly, making it easier to generate verifiable citations.
  3. Factual recall is unreliable. Fine-tuning doesn't turn a model into a database. It may learn some facts while confusing or misremembering others, sometimes producing confident but incorrect answers. For factual questions, retrieving the relevant information is generally more reliable than depending on what the model memorized during training.

Access control is another concern. RAG can restrict retrieval to documents each user is authorized to access. Fine-tuning offers no equivalent way to enforce document-level permissions on information learned in the weights. Sensitive training data may also be memorized and exposed.

Here's a quick guide to choosing the right approach:

ProblemLikely solution
Model doesn't follow instructions it was never givenBetter prompting
Model lacks company-specific or recent informationRAG
Information changes frequently or requires citationsRAG
Users must only access information they're authorized to seeRAG with permission filtering
Model knows what to do but struggles with tone, format, or consistencyFine-tuning
A large model works well, but inference costs or latency are too highFine-tune or distill a smaller model
Existing models struggle with specialized domain language or conceptsContinued pretraining, followed by fine-tuning

Once you've decided that fine-tuning is worth the effort, there are two important choices to make: how much of the model to update and what training method to use.

Fine-Tuning Methods

Full Fine-Tuning vs. Parameter-Efficient Fine-Tuning

Full fine-tuning updates all the model's weights during training. This gives the model the most flexibility to learn new behavior, but requires substantial GPU memory.

During training, the GPU must store more than just the model weights. With mixed-precision training and the Adam optimizer, a common estimate is 16 bytes per parameter: 2 bytes for the weights, 2 for gradients, 4 for a full-precision copy of the weights, and 8 for optimizer states.

For an 8B model, that's:

That's already more than a single 80 GB GPU can hold. A 70B model requires roughly 1.12 TB before activations. Each fine-tuned 8B model also produces a separate checkpoint of around 16 GB in FP16, which must be stored and deployed.

Parameter-efficient fine-tuning (PEFT) reduces this cost by freezing the original weights and training a small number of additional parameters. The most widely used approach is LoRA (Low-Rank Adaptation).

LoRA is based on the idea that the changes needed to adapt a model can often be represented using much smaller matrices. Instead of updating a large weight matrix W, LoRA keeps it frozen and learns two smaller matrices, A and B, whose product represents the weight update.

The input passes through the frozen weights and the two trainable matrices in parallel. Their outputs are added together. In this example, 16 is the rank, which controls the adapter's capacity. Common ranks range from 8 to 64.

The parameter savings are significant. A 4096 × 4096 weight matrix contains about 16.8 million parameters. With rank 16, matrices A and B contain just 131,072 parameters combined, less than 1% of the original.

For a typical 8B model, applying rank-16 LoRA to all major linear layers adds roughly 40 million trainable parameters, depending on the architecture. That's around 80 MB in FP16, compared with 16 GB for the full model.

Training memory also drops because gradients and optimizer states are only needed for the adapter. An 8B model can be fine-tuned with LoRA on a single 80 GB GPU, often with room to spare.

QLoRA reduces memory usage further by storing the frozen base model in 4-bit precision while training the adapters at higher precision. An 8B model's quantized weights take roughly 4 to 5 GB, making fine-tuning possible on a single 24 GB GPU with appropriate batch sizes, sequence lengths, and memory optimizations.

Here's how the three approaches compare:

Scroll
FactorFull fine-tuningLoRAQLoRA
Weights updatedAll model weightsSmall adapter, often under 1%Small adapter, often under 1%
Training memory for 8B~128 GB + activationsFits on one 80 GB GPUCan fit on one 24 GB GPU
Output size for 8B~16 GB full modelTens of MB per adapterTens of MB per adapter
QualityMost flexibility for substantial model changesOften comparable to full fine-tuning on targeted tasksOften comparable to LoRA, with possible quantization trade-offs
ServingSeparate model weights for each versionMultiple adapters can share one base modelMultiple adapters can share one base model

For most product use cases that need fine-tuning, LoRA is a good starting point. It's cheaper to train, easier to experiment with, and produces small adapters that can share the same base model during serving.

Full fine-tuning is worth considering when you need substantial changes to the model's behavior, have enough training data and compute, and evaluations show that LoRA isn't meeting your requirements.

Supervised Fine-Tuning vs. Preference Tuning

The second decision is how to train the model. There are two common approaches, depending on the type of training data you have.

Supervised fine-tuning (SFT) trains the model on examples of inputs and desired outputs. For instance, you provide a customer support ticket along with a response written by an experienced support agent. The model learns to produce similar responses for new tickets.

SFT works well when you can provide clear examples of what a good answer should look like.

But for some tasks, it's easier to compare two responses than to write an ideal one from scratch. You might know that one summary is clearer than another, or that one support response is more helpful.

Preference tuning learns from these comparisons. Each training example contains a prompt, a preferred response, and a rejected response. The goal is to make the model more likely to produce responses that match the preferred behavior.

Two common approaches are:

  • RLHF (Reinforcement Learning from Human Feedback). In the classic approach, a separate reward model learns to predict human preferences. Reinforcement learning, often using PPO, then updates the language model to produce responses that receive higher reward scores. This approach was used in early instruction-following models such as InstructGPT. It's powerful but operationally complex, requiring multiple models and careful training to maintain stability.
  • DPO (Direct Preference Optimization). DPO learns directly from preferred and rejected response pairs, without training a separate reward model or running a reinforcement learning loop. Its objective increases the relative preference for chosen responses compared with rejected ones, using a reference model. It's generally simpler and less expensive to train, making it a practical choice in many cases.

These methods are often used in sequence:

SFT teaches the model how to perform the task. Preference tuning then refines its behavior, such as favoring concise, helpful responses over unnecessarily long or vague ones.

SFT is usually the simpler place to start. Preference tuning becomes useful when SFT alone isn't producing the desired behavior and you have reliable comparison data, such as users choosing between two generated drafts.

Another common reason to fine-tune is to replace an expensive model with a smaller, faster one. This approach is called model distillation, and it has its own techniques and trade-offs.

Distillation

Distillation trains a smaller student model to learn from a larger teacher model. The goal is to achieve comparable quality on a specific task while reducing inference cost and latency.

In production, the process is often straightforward. You run the teacher model on a representative set of inputs, filter its responses for quality, and use the resulting input-output pairs to fine-tune the student.

Filtering is important because even strong teacher models make mistakes. If you train the student on incorrect responses, it can learn those mistakes too. You can filter outputs using schema validation, rule-based checks, LLM judges, and human review for cases that are difficult to evaluate automatically.

The main benefit of distillation is lower inference cost at scale.

Suppose you're building a support ticket classifier that handles 5 million requests per day. Each request contains around 1,000 input tokens and produces 50 output tokens.

Here's an illustrative cost comparison:

Scroll
OptionAssumed priceDaily cost
Frontier model$3 per 1M input tokens, $15 per 1M output tokens~$18,750
Distilled 8B model, self-hosted~$0.15 per 1M tokens, blended serving cost~$790

The actual savings depend on the models, hardware, throughput, and GPU utilization. The self-hosted estimate assumes efficient serving and doesn't include training costs. Still, for narrow, high-volume tasks, distillation can reduce inference costs by 10x or more while improving latency.

There are two important considerations:

  • Provider restrictions. Some model providers restrict using their outputs to train competing models. Check the provider's terms before using a hosted model as your teacher.
  • Training data coverage. The student is most reliable on inputs similar to those it was trained on. If your dataset misses rare cases or important variations in production traffic, the student may perform poorly on them. Evaluate it on representative, held-out data, including difficult and uncommon cases.

If you host the teacher yourself, you can also use logit distillation, where the student learns from the teacher's probability distribution over tokens rather than just its generated text. This provides a richer training signal, but typically requires access to model internals that most hosted APIs don't expose.

Whether you're distilling a larger model or fine-tuning on human-written examples, the quality of the training data is one of the biggest factors in the final result.

Training Data

Training data is often the biggest factor in whether fine-tuning succeeds. A few hundred to a few thousand high-quality examples can be enough to teach a model a specific format, tone, or narrow task. A thousand clean, representative examples can outperform ten thousand noisy ones.

There are three main sources of training data.

Production traces. If your application already uses an LLM, its logs contain real user inputs and model responses. User feedback can help identify good responses, such as a thumbs up, an accepted draft, or a support ticket resolved without escalation. These are useful signals, though they don't always guarantee correctness.

When users edit generated content, the corrected version can become a supervised training example. The original and corrected responses may also serve as preference data if the correction represents a clear improvement.

However, production data requires careful handling. Remove or mask personal information, follow data retention policies, and verify that your agreements permit using customer data for training. Some enterprise customers explicitly prohibit it.

Synthetic data. You can use a stronger model to generate training examples, including cases that rarely appear in production logs, such as uncommon languages, unusual document formats, or difficult edge cases.

Synthetic data helps expand coverage quickly, but it can contain errors and reflect the generating model's biases. It may also lack the diversity of real user inputs. Validate generated examples and combine them with real data rather than relying entirely on synthetic outputs.

Human labeling. Domain experts can write responses, correct model outputs, or rank multiple answers. This is usually the most expensive approach, but it's particularly valuable in specialized fields such as medicine and law, where evaluating correctness requires domain expertise.

Provide clear labeling guidelines and measure agreement between reviewers. If experts frequently disagree about the correct answer, you need to resolve those inconsistencies before using the examples for training.

These sources feed into a data preparation pipeline:

The train/evaluation split is especially important. Ideally, create a representative evaluation set before training and keep it isolated from training and synthetic data generation. Otherwise, near-duplicate examples or leaked answers can make your model appear better than it actually is.

Split data carefully, grouping related conversations, users, or documents where necessary to prevent leakage. Time-based splits are also useful for measuring performance on newer inputs.

Finally, pay attention to dataset balance. If 90% of your production logs involve password resets, training directly on that distribution may leave the model poorly prepared for other support requests. Include enough examples of less common but important cases, and evaluate performance across categories rather than relying only on overall accuracy.

Once you've trained a model, the next challenge is serving it efficiently, especially when you need to support multiple fine-tuned versions.

Serving Fine-Tuned Models

Serving one fine-tuned model is similar to serving any other LLM. The challenge comes when you need to serve many of them.

For example, a B2B writing assistant might have a separate fine-tuned model for each enterprise customer to match their writing style. Another platform might use different fine-tuned models for summarization, classification, and data extraction.

There are two main approaches to serving these models.

One Deployment per Model

With full fine-tuning, each model has its own complete set of weights. An 8B model in 16-bit precision requires roughly 16 GB just for its weights. If you have 100 customer models, that's 1.6 TB of model weights.

Each model also needs GPU capacity when serving requests. Since most customers don't generate traffic continuously, maintaining dedicated GPU instances can leave a lot of compute capacity idle.

This approach works when you have a small number of high-traffic models, customers that require strict isolation, or models that need full fine-tuning. However, it becomes expensive when you have hundreds of models serving relatively little traffic.

Many LoRA Adapters on One Base Model

LoRA offers a more efficient alternative. Instead of maintaining a full model for every customer, you load the base model once and serve multiple small adapters alongside it.

Serving engines such as vLLM support multi-LoRA inference, allowing requests using different adapters to share the same base model. Systems like S-LoRA have also demonstrated how to serve thousands of adapters by managing them across GPU and CPU memory.

Each request includes an adapter ID, typically assigned by the gateway based on the tenant or task. The serving engine selects the corresponding adapter and can batch requests using different adapters together.

Because the expensive base model weights are shared, only the adapter-specific computation differs between requests. Frequently used adapters can remain in GPU memory, while less frequently used ones are loaded from CPU memory or storage when needed.

For 100 customer models, the difference in weight memory is substantial:

That's a reduction from 1.6 TB to roughly 24 GB of model and adapter weights. Actual GPU memory requirements will be higher because inference also needs KV cache, temporary buffers, and other runtime resources. Not all adapters need to remain in GPU memory simultaneously.

However, shared adapter serving introduces a few trade-offs:

  • Additional latency. Batching requests with different adapters can introduce some computation overhead. Loading an adapter that isn't already in GPU memory also adds latency to the first request.
  • Base model compatibility. LoRA adapters are tied to the base model they were trained on. Upgrading the base model generally requires retraining or adapting the adapters and re-evaluating their quality. This makes it important to preserve training datasets and version the base model alongside its adapters.
  • Noisy neighbors. Tenants share GPU resources, so a traffic spike from one customer can affect latency for others. Per-tenant quotas, concurrency limits, and request scheduling help maintain predictable performance.

Another option is managed fine-tuning from hosted model providers. You upload your training dataset, run a fine-tuning job, and receive a model ID to use for inference. The provider handles deployment and scaling, but you have less control over model selection, training methods, and serving costs.

For multi-tenant applications with many low-traffic adapters, shared LoRA serving is a good starting point. It reduces memory requirements and improves GPU utilization, while dedicated deployments remain useful for high-traffic customers or workloads that require stronger isolation.

Efficient serving addresses the infrastructure side of fine-tuning. The next challenge is making sure your adapted model actually performs better than the original.

Failure Modes

Fine-tuning doesn't always improve a model. It can introduce problems that aren't obvious from training metrics alone. Watch for three failure modes.

Overfitting to the Training Set

When you train for too many epochs on a small dataset, the model may memorize examples instead of learning patterns that generalize to new inputs.

A common sign is that training loss keeps decreasing while validation loss starts increasing. The model performs well on familiar inputs but struggles with slightly different ones. It may even reproduce phrases from the training data word for word.

Monitor validation loss and task-specific metrics during training, and use early stopping or select the checkpoint that performs best on held-out data. For LoRA with small datasets, one to three epochs is often a reasonable starting point, though the right number depends on the task and dataset.

Most importantly, evaluate on representative inputs the model hasn't seen, including cases that differ from the training examples.

Losing General Ability

Fine-tuning a model on a narrow task can weaken capabilities it already had. This is known as catastrophic forgetting.

For example, a model heavily fine-tuned for JSON extraction might become worse at following general instructions or answering questions in natural language.

Safety behavior can also degrade. A 2023 study by Qi et al. found that fine-tuning an aligned model, even on seemingly harmless data, can weaken its ability to refuse harmful requests. If users interact directly with your fine-tuned model, include safety evaluations rather than assuming the base model's behavior will remain unchanged.

LoRA preserves the original weights, but the adapted model can still lose capabilities when the adapter is active. Mixing some general instruction-following examples into the training data can help preserve broader behavior.

Run general capability and safety evaluations alongside task-specific tests to catch regressions before deployment.

Evaluation Data Leaking Into Training

Evaluation leakage is hard to spot because it can make a poorly performing model look successful.

If evaluation examples, or near-duplicates of them, appear in the training data, the model may score well simply because it has already seen similar answers. The results look promising during development, but performance drops when the model encounters real production traffic.

Leakage can happen in several ways:

  • The same customer email appears multiple times in production logs, with copies ending up in both training and evaluation sets.
  • Synthetic training examples are generated using questions or answers from the evaluation set.
  • A random split puts different versions of the same question into both sets.

Preventing leakage requires a disciplined data preparation process.

Create and freeze your evaluation set before training. Check for duplicates across datasets using exact matching and semantic similarity. Where appropriate, split by time so evaluation data comes from a later period, and group related records by customer, conversation, or document so they don't appear in both sets.

Also avoid repeatedly tuning your model against the same evaluation examples. Over time, this can lead to overfitting to the evaluation set itself. Keep a separate test set for the final assessment.

Here's a summary of the three failure modes:

Scroll
Failure modeSymptomMitigation
OverfittingStrong training performance but poor results on unseen inputsTrack validation metrics, use early stopping, evaluate on representative held-out data
Losing general abilityRegressions on other tasks or weaker safety behaviorLoRA, mixing general instruction data, general capability and safety evaluations
Evaluation leakageHigh evaluation scores that don't match production performanceFreeze evaluation data, remove near-duplicates, split by time and source, maintain a separate test set

Putting It Together

Suppose you're designing an email drafting feature for a B2B customer support platform with 300 enterprise customers. Each customer wants replies that match its brand voice and follow its own policies. The platform generates 2 million drafts per day.

Here's how you could apply the adaptation ladder:

  1. Start with prompting. Use a frontier model with instructions describing each customer's tone and a few examples of good replies. This gives you a working product and a baseline for evaluating quality. However, each request includes around 3,000 tokens of style instructions and examples, and the model still struggles to maintain a consistent tone in longer responses.
  2. Add RAG for company policies. Refund policies, shipping times, and product details change frequently. Retrieve the relevant information from each customer's knowledge base at request time, with tenant-level access controls. Keep this information outside the model's weights so updates don't require retraining.
  3. Fine-tune for tone and format. After a few months, you've collected thousands of agent-approved drafts per customer. For customers who permit training on their data, remove personal information and use these examples to train a separate LoRA adapter on an open-weight 8B model. Reserve recent, representative examples as a held-out evaluation set for each customer before training.
  4. Serve adapters on a shared base model. Deploy replicas of the 8B base model across a GPU pool, with each replica supporting multiple customer adapters. Keep frequently used adapters in GPU memory and load less common ones on demand. The gateway selects the correct adapter using the tenant ID.
  5. Keep a fallback. Customers without enough training data, or whose adapters fail quality evaluations, continue using the prompted frontier model. You can also route requests to the fallback when an adapter is unavailable or fails at runtime.

The resulting architecture looks like this:

Each component has a clear responsibility. Fine-tuning helps maintain a consistent brand voice and output format. RAG supplies current policies and product information. Shared LoRA serving keeps the cost of supporting 300 customer-specific models manageable, while the fallback ensures customers can still use the feature without a fine-tuned adapter.

One important maintenance cost is upgrading the base model. LoRA adapters are tied to the model they were trained on, so moving to a new base model generally means retraining or adapting the customer adapters and evaluating them again. For 300 customers, that requires a versioned training pipeline and a gradual rollout rather than a simple model replacement.

Summary

Here are the key decisions when adapting models for a GenAI application:

Scroll
DecisionChoose one whenChoose the other when
RAG vs. fine-tuningRAG: The model needs external knowledge, facts change frequently, citations are required, or access depends on user permissionsFine-tuning: The model has the necessary information but struggles with tone, format, or task-specific behavior
Full fine-tuning vs. LoRAFull: You need substantial changes to model behavior, have sufficient training data, and LoRA doesn't meet quality targetsLoRA: You're adapting style, format, or narrow tasks and want lower training costs and efficient serving
SFT vs. preference tuningSFT: You have examples of the desired outputsPreference tuning: You can reliably compare responses, but defining an ideal output is difficult
Large prompted model vs. distilled small modelLarge: Tasks are broad, traffic is low, or requirements are still changingDistilled: Tasks are narrow and stable, volume is high, and reducing cost or latency matters
Dedicated deployments vs. shared LoRA servingDedicated: You have a few high-traffic models or need strict isolationShared: You serve many low-traffic adapters built on the same base model

Regardless of the approach, invest in training data quality and representative evaluations. Keep a separate, deduplicated evaluation set to measure whether the adapted model actually improves on the baseline, including any regressions in general capabilities or safety.

Start with prompting or RAG, measure where they fall short on your evaluation set, and move to fine-tuning, preference tuning, or distillation only when the results show a clear improvement.