Introduction to LLM Adaptation
Large Language Models (LLMs) have transformed the way developers build applications, but getting them to perform specific tasks reliably requires adaptation. The two primary methods for adapting an LLM to your use case are prompt engineering and fine-tuning. Understanding the distinction between these two approaches—and knowing when to apply each—is critical for balancing performance, cost, and development time. This tutorial explores both methods, provides practical code examples, and outlines best practices for integrating them into your workflow.
Prompt Engineering
What is Prompt Engineering?
Prompt engineering is the practice of designing and optimizing the inputs given to an LLM to elicit the desired output. Instead of changing the underlying model, you change the instructions, context, and examples provided in the prompt. This approach is highly flexible, requires no specialized machine learning knowledge, and allows for rapid iteration.
How to Use Prompt Engineering
Effective prompt engineering often involves using system messages to set the persona, providing clear instructions, and utilizing few-shot learning (giving the model a few examples of the desired input-output pair). Below is an example using the OpenAI Python SDK to classify customer support tickets.
import openai
openai.api_key = "your-api-key"
response = openai.chat.completions.create(
model="gpt-4",
messages=[
{
"role": "system",
"content": "You are a customer support ticket classifier. Classify the user's message into one of the following categories: 'Billing', 'Technical', 'General'."
},
{
"role": "user",
"content": "Example: I cannot log into my account. -> Technical"
},
{
"role": "user",
"content": "Example: How do I update my credit card? -> Billing"
},
{
"role": "user",
"content": "Classify this: My screen goes black when I click save."
}
],
temperature=0.0
)
print(response.choices[0].message.content)
Fine-Tuning
What is Fine-Tuning?
Fine-tuning is the process of taking a pre-trained model and further training it on a smaller, task-specific dataset. This updates the actual weights of the neural network. Fine-tuning is ideal when you need the model to adopt a specific tone, learn a proprietary domain language, or consistently format outputs in a way that prompt engineering cannot reliably achieve. It can also reduce token usage at inference time, as you no longer need to include long system prompts or few-shot examples.
How to Use Fine-Tuning
To fine-tune a model, you must first prepare a dataset in JSONL format, containing hundreds or thousands of examples. Once prepared, you upload the file and create a fine-tuning job. Below is an example of how to initiate a fine-tuning job using the OpenAI Python SDK.
import openai
openai.api_key = "your-api-key"
# Step 1: Upload the training data file
file_response = openai.files.create(
file=open("training_data.jsonl", "rb"),
purpose="fine-tune"
)
# Step 2: Create the fine-tuning job
job_response = openai.fine_tuning.jobs.create(
training_file=file_response.id,
model="gpt-3.5-turbo",
hyperparameters={
"n_epochs": 3
}
)
print(f"Fine-tuning job created with ID: {job_response.id}")
When to Use Each Approach
Choosing between prompt engineering and fine-tuning depends on your specific constraints and goals. Here is a breakdown of when to use each:
- Use Prompt Engineering when:
- You are prototyping or in the early stages of development.
- The task requires dynamic context, such as Retrieval-Augmented Generation (RAG) where documents change frequently.
- You have limited data and cannot compile hundreds of high-quality examples.
- You need to update the model's behavior instantly without waiting for a training job to complete.
- Use Fine-Tuning when:
- You have a stable, well-defined task and hundreds of high-quality examples.
- You need to reduce latency and token costs by removing long system prompts and few-shot examples.
- The model needs to learn a specific style, tone, or proprietary jargon that it has not seen in its base training.
- Prompt engineering has hit a performance ceiling, and the model still makes consistent errors.
Best Practices
To maximize the effectiveness of your LLM applications, consider the following best practices:
- Start with Prompting: Always exhaust prompt engineering techniques first. It is cheaper, faster, and often solves the problem without the overhead of training.
- Collect Real Data: If you decide to fine-tune, use real-world data gathered from your prompt engineering prototypes. Log the inputs and the ideal corrected outputs to build your training dataset.
- Evaluate Rigorously: Before deploying a fine-tuned model, test it against a holdout validation set to ensure it actually performs better than the prompted version.
- Combine Both Methods: Fine-tuning and prompt engineering are not mutually exclusive. You can fine-tune a model to understand your domain, and then use prompt engineering at inference time to provide dynamic, real-time context.
Conclusion
Prompt engineering and fine-tuning are complementary tools in a developer's AI toolkit. Prompt engineering offers a fast, flexible, and cost-effective way to guide LLM behavior through carefully crafted instructions and context. Fine-tuning, on the other hand, provides a deeper level of customization by altering the model's weights, making it indispensable for highly specialized tasks and cost optimization at scale. By starting with prompt engineering and transitioning to fine-tuning only when data and performance requirements demand it, developers can build robust, efficient, and highly capable AI applications.