← Back to DevBytes

Comparing SLMs: Qwen2 vs Mistral 7B vs Phi-3

Introduction to Small Language Models (SLMs)

Large Language Models (LLMs) like GPT-4 and Claude have dominated the AI landscape, but they come with significant costs, latency, and infrastructure requirements. Small Language Models (SLMs) — typically ranging from 2B to 8B parameters — have emerged as powerful alternatives for developers who need capable AI without the overhead. In this tutorial, we'll compare three of the most popular SLMs available today: Qwen2, Mistral 7B, and Phi-3.

What Are SLMs and Why They Matter

Small Language Models are compact neural networks trained on high-quality data to perform language tasks at a fraction of the cost of their larger counterparts. They are designed to run on consumer hardware, edge devices, or cost-effective cloud instances while still delivering impressive performance on many tasks.

Why SLMs Matter for Developers

Model Overview

Qwen2 (Alibaba)

Qwen2 is the second generation of Alibaba's Tongyi Qianwen model family. Released in multiple sizes (0.5B, 1.5B, 7B, and 72B), the 7B variant is the most comparable to its peers. Qwen2 supports a 128K context window in its extended version and was trained on a massive multilingual corpus covering 29+ languages. It excels in coding, mathematics, and multilingual tasks.

Key specs:

Mistral 7B (Mistral AI)

Mistral 7B was released by Mistral AI in late 2023 and quickly became a community favorite. It introduced Grouped-Query Attention (GQA) and Sliding Window Attention (SWA) for efficient inference. Mistral 7B outperformed Llama 2 13B on many benchmarks despite being nearly half the size, making it a landmark release for the SLM category.

Key specs:

Phi-3 (Microsoft)

Phi-3 is Microsoft's family of small models, with the Phi-3 Mini (3.8B) being the flagship SLM. It was trained on "textbook quality" synthetic data, which allows it to punch well above its weight class. Despite being smaller than both Qwen2 7B and Mistral 7B, Phi-3 Mini competes with them on many reasoning and knowledge benchmarks.

Key specs:

Head-to-Head Comparison

Let's compare these three models across key dimensions that matter to developers:

Performance on Common Benchmarks

Note: Benchmark numbers vary by quantization, prompt format, and evaluation methodology. Always run your own evaluation on your specific use case.

Resource Requirements

Phi-3 Mini's smaller parameter count gives it a clear advantage in memory-constrained environments, while Qwen2 and Mistral require similar resources.

When to Choose Each Model

How to Use These Models

All three models are available through the Hugging Face Hub and can be loaded using the transformers library. Let's look at practical examples for each.

Prerequisites

First, install the required packages:

pip install transformers torch accelerate bitsandbytes

Loading and Running Qwen2 7B

from transformers import AutoModelForCausalLM, AutoTokenizer

model_name = "Qwen/Qwen2-7B-Instruct"

tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype="auto",
    device_map="auto"
)

messages = [
    {"role": "system", "content": "You are a helpful programming assistant."},
    {"role": "user", "content": "Write a Python function to check if a string is a palindrome."}
]

text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True
)

inputs = tokenizer([text], return_tensors="pt").to(model.device)
outputs = model.generate(
    **inputs,
    max_new_tokens=512,
    temperature=0.7,
    do_sample=True
)

response = tokenizer.decode(
    outputs[0][len(inputs.input_ids[0]):],
    skip_special_tokens=True
)
print(response)

Loading and Running Mistral 7B

from transformers import AutoModelForCausalLM, AutoTokenizer

model_name = "mistralai/Mistral-7B-Instruct-v0.3"

tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype="auto",
    device_map="auto"
)

messages = [
    {"role": "user", "content": "Explain the difference between supervised and unsupervised learning in simple terms."}
]

text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True
)

inputs = tokenizer([text], return_tensors="pt").to(model.device)
outputs = model.generate(
    **inputs,
    max_new_tokens=400,
    temperature=0.7,
    do_sample=True
)

response = tokenizer.decode(
    outputs[0][len(inputs.input_ids[0]):],
    skip_special_tokens=True
)
print(response)

Loading and Running Phi-3 Mini with 4-bit Quantization

Phi-3 Mini is small enough to run on consumer GPUs. Here's how to load it with 4-bit quantization to save even more memory:

from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
import torch

model_name = "microsoft/Phi-3-mini-4k-instruct"

quantization_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_compute_dtype=torch.float16,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_use_double_quant=True
)

tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    quantization_config=quantization_config,
    device_map="auto"
)

messages = [
    {"role": "system", "content": "You are a concise AI assistant."},
    {"role": "user", "content": "What are three best practices for writing clean code?"}
]

text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True
)

inputs = tokenizer([text], return_tensors="pt").to(model.device)

with torch.no_grad():
    outputs = model.generate(
        **inputs,
        max_new_tokens=300,
        temperature=0.5,
        do_sample=True,
        pad_token_id=tokenizer.eos_token_id
    )

response = tokenizer.decode(
    outputs[0][len(inputs.input_ids[0]):],
    skip_special_tokens=True
)
print(response)

Using Ollama for Local Deployment

For the simplest local deployment experience, Ollama supports all three models. After installing Ollama, you can run any of them with a single command:

# Pull and run Qwen2 7B
ollama run qwen2:7b

# Pull and run Mistral 7B
ollama run mistral

# Pull and run Phi-3 Mini
ollama run phi3

You can then interact with the models via the Ollama Python SDK:

import requests

def query_ollama(model, prompt):
    response = requests.post(
        "http://localhost:11434/api/generate",
        json={
            "model": model,
            "prompt": prompt,
            "stream": False
        }
    )
    return response.json()["response"]

# Example usage with all three models
models = ["qwen2:7b", "mistral", "phi3"]
prompt = "Summarize the concept of recursion in programming in two sentences."

for model in models:
    print(f"\n=== {model} ===")
    print(query_ollama(model, prompt))

Using vLLM for High-Throughput Inference

If you need to serve these models in production with high throughput, vLLM is an excellent choice:

# Install vLLM
pip install vllm
from vllm import LLM, SamplingParams

# Load any of the three models
llm = LLM(model="Qwen/Qwen2-7B-Instruct")

sampling_params = SamplingParams(
    temperature=0.7,
    max_tokens=512
)

prompts = [
    "Write a haiku about debugging.",
    "Explain what a REST API is.",
    "List three Python best practices."
]

outputs = llm.generate(prompts, sampling_params)

for output in outputs:
    prompt = output.prompt
    generated_text = output.outputs[0].text
    print(f"Prompt: {prompt}")
    print(f"Output: {generated_text}\n")

Fine-Tuning with LoRA

All three models can be fine-tuned efficiently using LoRA (Low-Rank Adaptation). Here's a minimal example using PEFT:

from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments
from peft import LoraConfig, get_peft_model
from datasets import Dataset
from trl import SFTTrainer

model_name = "mistralai/Mistral-7B-Instruct-v0.3"

tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token

model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype="auto",
    device_map="auto"
)

# Apply LoRA
lora_config = LoraConfig(
    r=16,
    lora_alpha=32,
    target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM"
)

model = get_peft_model(model, lora_config)
model.print_trainable_parameters()

# Prepare a sample dataset
training_data = [
    {"text": "### Human: What is Python?\n### Assistant: Python is a high-level programming language."},
    {"text": "### Human: What is a variable?\n### Assistant: A variable is a named storage location in memory."}
]

dataset = Dataset.from_list(training_data)

training_args = TrainingArguments(
    output_dir="./fine-tuned-mistral",
    num_train_epochs=3,
    per_device_train_batch_size=2,
    save_steps=100,
    logging_steps=10,
    learning_rate=2e-4
)

trainer = SFTTrainer(
    model=model,
    train_dataset=dataset,
    args=training_args,
)

trainer.train()

# Save the fine-tuned adapter
model.save_pretrained("./fine-tuned-mistral-adapter")

Best Practices

Model Selection

Prompt Engineering

Deployment

Fine-Tuning

Conclusion

Qwen2, Mistral 7B, and Phi-3 represent the state of the art in small language models, each with distinct strengths. Qwen2 7B leads in multilingual tasks, coding, and long-context scenarios. Mistral 7B offers a mature, well-supported general-purpose model with an efficient architecture. Phi-3 Mini stands out for its remarkable reasoning ability in an ultra-compact footprint, making it ideal for edge deployment. The right choice depends on your specific constraints around latency, memory, language support, and task complexity. By starting with a clear evaluation strategy, leveraging quantization, and following deployment best practices, you can harness these SLMs to build cost-effective, performant AI applications that rival solutions built on much larger models.

— Ad —

Google AdSense will appear here after approval

← Back to all articles